INTERNET-DRAFT A. Jurkovikj Intended status: Best Current Practice 16 May 2026 Expires: 17 November 2026 HTTP Profile for Synchronized Resource State (Agentic State Transfer) draft-jurkovikj-httpapi-agentic-state-01 Abstract HTTP resources are frequently exposed in multiple representations (e.g., text/html for rendering and application/json for processing) via Content Negotiation. Standard HTTP validators such as ETags identify selected representations, while many applications need concurrency control over a shared logical resource state. This creates a synchronization gap where a client modifying one representation cannot guarantee consistency with the underlying state of another representation, leading to race conditions and "lost updates" in multi-client environments. This document specifies Agentic State Transfer (AST), an HTTP profile for managing Canonical Resource State (CRS) across multiple synchronized representations of the same resource. It defines a State-Bearing Representation (SBR) whose strong ETag acts as the AST semantic validator for the CRS. It further mandates the use of Optimistic Concurrency Control via If-Match headers for state-changing operations, ensuring that mutations applied by agents (whether automated clients, scripts, or human- driven applications) are atomic and consistent across all views. Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." Copyright Notice Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License. Table of Contents 1. Introduction 2. Terminology 3. The AST Profile 4. Discovery of Synchronized Representations 5. Integrity and Transport 6. Computing and Managing Semantic Validators 7. Conformance Requirements Summary 8. Security Considerations 9. IANA Considerations 1. Introduction The architecture of the World Wide Web allows a single logical resource (identified by a URI) to be represented in multiple formats. A common pattern in modern systems is to expose: * a *Rendered Representation* (e.g., text/html) for human agents, and * a *Structural Representation* (e.g., application/json) for automated agents. In AST terminology, rendered representations are typically Projected Representations, while a structural representation MAY serve as the State-Bearing Representation (SBR) when it exposes the full Canonical Resource State. HTTP provides mechanisms for content negotiation [RFC9110], and defines validators such as ETag for caching and conditional requests. However, in most deployments: * validators are derived from a particular representation's bytes, and * concurrency control, if present at all, is scoped to a single representation. This creates a synchronization gap: two clients interacting with different representations of the same logical resource can unwittingly overwrite each other's work. AST addresses this problem by treating the Canonical Resource State (CRS) as the primary object of synchronization, and by standardizing how the SBR ETag is used as the profile-specific semantic validator for that CRS. 1.1. The Synchronization Problem Consider a resource /article/123 exposed both as HTML and JSON. 1. Client A (Browser) retrieves the HTML representation. 2. Client B (Automated Agent) retrieves the JSON representation. 3. Client A submits an edit (e.g., via the JSON API or a form handler that writes to the CRS), updating the underlying database record. 4. Client B, unaware of the change, computes an update based on its stale JSON representation and submits a PUT or PATCH request. In typical HTTP APIs, at least one of the following is true: * there is no ETag at all; * the ETag is tied to the bytes of a specific representation (e.g., JSON only); or * the server does not enforce preconditions (If-Match). As a result, Client B's request may succeed, even though: * its view of the resource is stale, and * the update logically conflicts with Client A's change. This is the classic Lost Update problem, now exacerbated by the growing use of automated agents acting as first-class editors. 1.2. Canonical Resource State (CRS) To address this, AST introduces the concept of Canonical Resource State (CRS): CRS is the authoritative, logical state of the resource, independent of any particular representation or serialization. For example, the CRS might be: * a database row (or set of rows), * a document or abstract syntax tree, * a domain object in application memory, or * in a WordPress CMS, the post record in wp_posts with fields like post_content, post_title, post_status, and associated metadata. Representations such as HTML, JSON, or Markdown are derived from the CRS and are considered projections of that state. AST defines a profile where: 1. Shared Identity -- All HTTP representations of an AST resource are projections of the same CRS. 2. Semantic Validation -- Validators (ETag values) are derived from the CRS, not a specific representation's bytes, so that a change to the CRS invalidates all representations together. 3. Mandatory Concurrency -- State-changing operations on AST resources MUST provide a precondition (If-Match) based on the CRS validator. This enables safe interaction by automated agents and human clients, ensuring they participate in the same state transition model. 1.3. Deployment Models AST accommodates two common deployment patterns: Single-URI (Content Negotiation): The SBR and Projected Representations are served from the same URI based on Accept headers. The SBR ETag is returned when the structural media type (e.g., application/json) is selected; a different representation-specific ETag MAY be returned for other media types. Discovery of the SBR media type is implicit in the content negotiation. Multi-URI (Separate Endpoints): The SBR is served from a dedicated API endpoint (e.g., /api/article/123) while Projected Representations are served from other URIs (e.g., /article/123). The rel="state" link header connects Projected Representations to the SBR endpoint. In both models, the SBR ETag serves as the Semantic Validator for the shared CRS. Clients MUST use the SBR ETag (not any projection- specific ETag) for If-Match preconditions on state-changing operations. In multi-URI deployments, the SBR endpoint and Projected endpoints MAY reside on different authorities, base paths, or even different servers. The rel="state" link is the canonical connector that allows clients to discover the SBR regardless of deployment topology. AST is defined as a profile - a set of constraints and conventions layered on standard HTTP semantics. Conforming implementations remain fully interoperable with generic HTTP clients and servers; AST does not introduce breaking changes to HTTP. 1.4. Relationship to Dual-Native Pattern This specification defines an HTTP profile of the Dual-Native Pattern, an architectural approach where resources provide both human- optimized and machine-optimized representations with formal semantic equivalence guarantees. The Dual-Native Pattern is defined in the Core Architecture and Requirements specification and demonstrated across multiple domains (HTTP, databases, streaming systems, healthcare). AST specifically addresses the HTTP binding with focus on safe concurrency control for state-changing operations. 1.4.1. Terminology Mapping AST terminology aligns with Dual-Native Pattern concepts as follows: - AST Term / Dual-Native Term: Description - State-Bearing Representation (SBR) / Machine Representation (MR): Canonical, structured representation for programmatic access - Projected Representation / Human Representation (HR): Presentation-optimized interface (typically HTML) - Semantic Validator (SBR ETag) / Content Identity (CID): Version- specific strong validator for change detection - Canonical Resource State (CRS) / Underlying resource state: Authoritative logical state independent of serialization - Resource URI / Resource Identity (RID): Stable identifier shared across representations - If-Match preconditions / Safe writes: Optimistic concurrency control via validator preconditions - If-None-Match conditional requests / Zero-fetch reads: Bandwidth optimization via validator revalidation - Content-Digest / Integrity digest: Verification of exact byte- level payload parity - rel="state" discovery / Dual-Native Catalog (DNC) entry: Discovery mechanism connecting representations 1.4.2. Critical Properties Coverage AST implements the critical properties identified in the Dual- Native Pattern: 1. Canonical MR: The SBR serves as the deterministic, machine- readable representation (Section 3.1) 2. Strong CID: The SBR ETag is a strong validator that changes whenever the CRS changes (Section 3.2) 3. Safe writes: If-Match preconditions provide optimistic concurrency control with explicit conflict signals (Section 3.4) 4. Zero-fetch reads: If-None-Match conditional requests enable bandwidth optimization when content is unchanged (Section 3.3) 5. Integrity: Content-Digest provides byte-level verification independent of semantic validation (Section 5) 6. Discovery: rel="state" links enable clients to discover the SBR from Projected Representations (Section 6) 1.4.3. Scope: HTTP-Specific Binding AST is specifically an HTTP profile. It defines: - How to map Dual-Native concepts to HTTP headers (ETag, If-Match, Content-Digest, Link) - HTTP-specific status codes (412, 428, 304) - Content negotiation patterns (single-URI vs multi-URI) - HTTP caching semantics for SBR and Projected Representations AST does not address: - Database, streaming, or IoT bindings (see Dual-Native Implementation Guide) - Full catalog/registry specifications (DNC is out of scope; AST covers point-to-point discovery only) - Schema evolution or version migration strategies - Authentication/authorization mechanisms (domain-specific) For the broader architectural context, see the Dual-Native Pattern Whitepaper. For formal cross-domain requirements, see the Core Architecture and Requirements specification. 2. Terminology Note: AST terminology is consistent with the Dual-Native Pattern specification family. See Section 1.4.1 for detailed mapping. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals. Canonical Resource State (CRS) : The underlying, authoritative logical state of a resource (e.g., the database record or abstract syntax tree). The CRS is the atomic unit of concurrency. State-Bearing Representation (SBR) : A specific representation (e.g., application/json) that exposes the CRS in a lossless, deterministic format. The SBR serves as the Concurrency Token for the resource. Its ETag represents the version of the CRS. State-Bearing Endpoint : The HTTP endpoint (URI) that serves the State-Bearing Representation. This is the primary target for state-changing operations and the authoritative source of the Semantic Validator. Projected Representation : A representation derived from the CRS for a specific consumption pattern (e.g., text/html for rendering, text/csv for analysis). Projected Representations reflect the CRS but do not govern it. State-changing operations SHOULD be directed to the State-Bearing Endpoint; see Write Semantics for handling writes at other endpoints. Semantic Validator : The strong ETag associated with the SBR. It MUST change whenever the CRS changes. It SHOULD NOT change when the CRS has not changed, although implementation factors (for example, canonicalization or hashing algorithm changes, migrations, or salting strategies) may occasionally cause validator changes without CRS changes. In this document, "Semantic Validator" means the AST profile's SBR ETag. The separate Semantic-ETag field defined in [I-D.jurkovikj-http-semantic-validator] is a related HTTP extension but is not required by this profile. AST Resource : A logical Canonical Resource State (CRS) that may be exposed via one or more HTTP endpoints (URIs). Endpoints that share the same CRS share the same Semantic Validator (SBR ETag) for concurrency purposes. 3. The AST Profile This section defines the Agentic State Transfer (AST) profile. It specifies how clients synchronize state across multiple representations by pivoting on the State-Bearing Representation (SBR). 3.1. Representation Roles For a given AST Resource, the server MUST designate exactly one representation as the State-Bearing Representation (SBR). All other representations are considered Projected Representations. * The SBR acts as the source of truth for state synchronization. * Projected Representations are derivative views. While they MAY have their own caching validators (ETags) based on their specific byte sequences, they MUST NOT be used as the basis for state-changing preconditions on the CRS. Endpoints that expose distinct CRS values (i.e., different logical resources) MUST use distinct Semantic Validators. Conversely, endpoints that share the same CRS MUST be bound to the same Semantic Validator for concurrency control, meaning they MUST direct clients to the same SBR ETag for If-Match preconditions. Projected endpoints MAY emit their own representation-specific ETags for caching purposes, but these MUST NOT be used for CRS concurrency control. 3.2. Semantic Validators (The SBR ETag) The server MUST assign a Strong ETag to the SBR. This ETag serves as the AST Semantic Validator for the resource. Because If-Match uses the strong comparison function [RFC9110], weak entity-tags are not suitable for AST concurrency control; a weak ETag will never satisfy an If-Match precondition. * Determinism: The SBR ETag MUST change whenever the CRS changes. * Scope: The SBR ETag MUST NOT be reused as the ETag for Projected Representations, as this would confuse standard HTTP caches. Canonicalization: Implementations SHOULD compute the SBR ETag from a deterministic canonical serialization of the CRS. When the SBR uses JSON, servers MUST canonicalize using the JSON Canonicalization Scheme ([RFC8785]) or a profile-specified, equivalently deterministic canonicalization before computing the validator. This ensures that logically identical states produce identical validators, regardless of field ordering or formatting variations. See the Canonicalization subsection in Computing and Managing Semantic Validators for detailed guidance. 3.2.1. ETag Computation (Informative) The SBR ETag MUST be a strong validator as defined in [RFC9110]. Implementations MAY compute the SBR ETag using any method that satisfies both the determinism and strong validator requirements. Common approaches include: * Content Hash: SHA-256 or similar cryptographic hash over the canonicalized SBR bytes (e.g., "sha256-YWJjMTIz..."). This is RECOMMENDED for deployment predictability, as it supports reproducible validator generation and naturally produces strong validators. * Version Counter: Monotonic version number from the data store (e.g., "v42" or "rev-1234"). This is simple but requires centralized version tracking. The version must increment on every CRS change to maintain strong validator semantics. The content hash approach provides the strongest guarantee that identical CRS values produce identical ETags within the same canonicalization and validator-construction regime, which aids debugging and distributed deployments. 3.2.2. Relationship to Semantic-ETag This profile uses the standard ETag field on the SBR as the AST Semantic Validator because If-Match and If-None-Match already define strong validator behavior for state-changing and conditional requests. The separate Semantic-ETag extension [I-D.jurkovikj-http-semantic-validator] defines an HTTP field for carrying a server-defined semantic validator independently of the selected representation. Deployments that support both profiles can expose Semantic-ETag on Projected Representations as an additional signal for clients that understand it. Such use does not replace the AST requirement that CRS mutations use the SBR ETag, discovered through the SBR endpoint, as the If-Match precondition unless a later AST revision explicitly defines otherwise. A future revision of AST might define If-Semantic-Match as an alternative to SBR discovery for deployments that expose Semantic-ETag; this revision does not define that alternative. 3.2.3. Encodings and ETags SBR endpoints MUST NOT apply content-codings to SBR responses; the Content-Encoding header field MUST be absent. (The identity token is reserved in HTTP and MUST NOT appear in Content-Encoding [RFC9110].) This requirement ensures the SBR ETag remains a single, stable strong validator suitable for If-Match concurrency control. SBR endpoints SHOULD include Cache-Control: no-transform to prevent intermediaries from applying transformations in transit. Clients SHOULD indicate that no content-codings are acceptable when retrieving the SBR, for example by sending Accept-Encoding: identity or by omitting Accept-Encoding entirely if the client does not support any codings. Deployments that cannot avoid content-coding at a given URI (for example, due to platform or intermediary constraints) SHOULD NOT designate that URI as the SBR. Instead, they SHOULD expose a separate SBR endpoint that can be served without content-coding and link to it using rel="state". The content-coded URI MAY be treated as a Projected Representation. 3.3. Read Semantics 3.3.1. Reading the SBR Clients SHOULD use the SBR ETag for conditional requests (If-None-Match) on the SBR URI. The server MUST return 304 Not Modified if the CRS has not changed. On a 304 response, the server SHOULD include the current SBR ETag in the response headers. Clients SHOULD NOT use the SBR ETag as If-None-Match against Projected endpoints. Projected endpoints have their own byte-specific validators; using the SBR ETag would result in unnecessary cache misses and conflates semantic validation with byte-level caching. Example: HEAD Request to Fetch SBR Validator Clients MAY use HEAD to obtain the current SBR ETag without transferring the full representation body: HEAD /api/article/123 HTTP/1.1 Host: example.com Accept: application/json HTTP/1.1 200 OK Content-Type: application/json ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F" Content-Length: 4521 This allows clients to check for state changes with minimal bandwidth usage before deciding whether to fetch the full representation. 3.3.2. Reading Projections Clients MAY cache Projected Representations using their specific ETags. However, clients MUST recognize that a Projected Representation may be stale relative to the CRS if the SBR ETag has changed. 3.3.3. Low-Overhead Change Detection (Informative) Clients monitoring resources for changes (e.g., polling for updates) can minimize bandwidth by using conditional requests with HEAD or GET. Pattern 1: HEAD + If-None-Match (Minimal Overhead) HEAD /api/article/123 HTTP/1.1 Host: example.com Accept: application/json If-None-Match: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F" HTTP/1.1 304 Not Modified ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F" If the resource has changed: HEAD /api/article/123 HTTP/1.1 Host: example.com Accept: application/json If-None-Match: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F" HTTP/1.1 200 OK ETag: "sha256-NEWVALIDATOR456" Content-Length: 4721 The client detects the ETag change without transferring the body, then performs a GET to retrieve the updated representation only when needed. Pattern 2: GET + If-None-Match (Conditional Transfer) GET /api/article/123 HTTP/1.1 Host: example.com Accept: application/json If-None-Match: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F" HTTP/1.1 304 Not Modified ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F" This pattern combines checking and fetching in one request. If unchanged, the server returns 304 with no body. If changed, it returns 200 with the new representation, saving a round trip compared to HEAD-then- GET. Recommendation for Polling: Use Pattern 2 (GET + If-None-Match) when the client expects frequent changes and will fetch the body most of the time. Use Pattern 1 (HEAD + If-None-Match) when changes are infrequent and the client needs the ETag for other purposes (e.g., preparing an If-Match precondition for a future write). 3.4. Write Semantics (The Safe Write Protocol) To modify the Canonical Resource State, clients MUST perform the mutation against the SBR Endpoint (or an endpoint explicitly bound to the SBR's validator). Clients MUST NOT use a Projected Representation's ETag as an If-Match precondition for CRS mutations. Only the SBR's own ETag is valid for concurrency control. 1. Precondition: The client obtains the current SBR ETag (via GET or HEAD on the SBR URI). 2. Mutation: The client sends the state-changing request (PUT, POST, PATCH, DELETE) including the If-Match header set to the SBR ETag. 3. Verification: * If the If-Match header is missing, servers SHOULD respond with 428 Precondition Required [RFC6585]. Servers MAY respond with 400 Bad Request if 428 is not supported by the implementation environment, provided the error body clearly indicates the missing precondition requirement. * If the provided ETag does not match the current CRS version, the server MUST respond with 412 Precondition Failed. * If the provided ETag matches the current CRS version, the server MAY perform the write if the request is otherwise authorized and valid. If the server performs the write, it MUST update the CRS and ensure subsequent Projected Representation responses are derived from the updated state. Projected validators SHOULD change when the projection bytes change. Note: HTTP provides no general mechanism for servers to actively invalidate cached Projected Representations in shared caches or CDNs. Clients that perform CRS mutations SHOULD invalidate their own locally cached projections; intermediary caches will expire based on their Cache-Control directives. Note: For endpoints that do not implement AST semantics, servers MAY accept unconditional writes as in traditional HTTP APIs. See the "Non-AST Resources and Fallback Behavior" section for guidance on mixed deployments. 4. Response: Upon a successful write, the server SHOULD convey the new SBR ETag to allow the client to chain subsequent updates. The mechanism depends on the response type: * If the response body is the SBR representation (e.g., the server returns 200 OK with Content-Type: application/json containing the updated state): include ETag: in the response headers. * If the response body is a Projected Representation or empty: convey the updated SBR validator via the Link header's state-etag parameter, the 204 No Content with Content-Location pattern, or the 303 See Other redirect pattern (see "Returning the Updated Validator from Non-SBR Endpoints" below). The ETag header in a response MUST describe the selected representation in that response [RFC9110]; it MUST NOT be used to convey the SBR validator when the response body is not the SBR. 3.4.1. Normative Foundations The AST safe write protocol builds on standard HTTP conditional request semantics and status codes: * Entity Tags and Strong Comparison [RFC9110] Section 8.8.3 and Section 13.1.1: Define entity-tag syntax and the strong comparison function used by If-Match. AST requires strong validators because weak entity-tags never satisfy If-Match preconditions under strong comparison. * If-Match Precondition [RFC9110] Section 13.1.1: Defines precondition evaluation. The server MUST perform strong comparison between the provided entity-tag(s) and the current validator. If none match, the server MUST respond with 412 Precondition Failed. * 428 Precondition Required [RFC6585] Section 3: Defines the status code for requests that require a precondition but lack one. AST servers SHOULD use 428 when If-Match is missing on state-changing operations. * 412 Precondition Failed [RFC9110] Section 15.5.13: Indicates that precondition evaluation failed. AST servers MUST return 412 when If-Match does not match the current SBR ETag. * Problem Details [RFC9457]: Defines application/problem+json for machine-readable error responses. AST servers SHOULD return Problem Details bodies for 412, 428, and 400 (missing precondition) responses to assist automated conflict resolution. This normative alignment ensures AST concurrency control integrates cleanly with existing HTTP implementations and intermediaries. 3.4.2. Error Handling For 412, 428, and 400 (when used for missing preconditions) responses, servers SHOULD return a Problem Details body [RFC9457] to assist automated clients in resolving the conflict. When rejecting a request due to Digest Fields validation failures (unsupported algorithm, malformed digest value, or digest mismatch), servers MAY return 400 Bad Request with a Problem Details body using the problem types defined in [I-D.ietf-httpapi-digest-fields-problem-types]. Servers SHOULD NOT include the server-computed digest value in error responses to avoid potential oracle attacks. 3.4.3. Write Location State-changing operations SHOULD be performed against the State- Bearing Endpoint. Projected endpoints (e.g., HTML rendering URIs) SHOULD reject state-changing requests with 405 Method Not Allowed and include a Link header with rel="state" pointing to the SBR endpoint. A server MAY designate additional endpoints as accepting state- changing operations (e.g., for compatibility with existing form submissions or legacy APIs). Such endpoints MUST: * enforce If-Match against the same Semantic Validator as the SBR, * advertise the SBR via a Link header with rel="state", and * return the updated Semantic Validator in a manner consistent with HTTP semantics (see below). Returning the Updated Validator from Non-SBR Endpoints: In HTTP, the ETag header in a response describes the selected representation returned in that response [RFC9110]. If a non-SBR endpoint returns a Projected Representation (e.g., HTML) after a successful write, the ETag header MUST describe that projection, not the SBR. To provide the updated SBR validator without violating HTTP semantics, servers SHOULD use one of the following patterns: * 303 See Other Redirect (RECOMMENDED): Return 303 See Other with Location pointing to the SBR URI. The client obtains the updated ETag from the subsequent GET. This adds a round-trip but is unambiguous and widely understood. http HTTP/1.1 303 See Other Location: /api/article/123 Link: ; rel="state"; type="application/json" * 204 No Content with Content-Location: Return 204 No Content with Content-Location set to the SBR URI and the ETag header set to the updated Semantic Validator. Because Content-Location identifies the representation described by the response metadata, this approach is semantically defensible, though some implementations may find it unusual. http HTTP/1.1 204 No Content Content-Location: /api/article/123 ETag: "sha256-NEWVALIDATOR123" Link: ; rel="state"; type="application/json" * Projection Response with Link Metadata: Return the projection with its own ETag, and convey the updated SBR validator via the Link header using an extension parameter: http HTTP/1.1 200 OK Content-Type: text/html ETag: "html-v2" Link: ; rel="state"; type="application/json"; state-etag="\"sha256-NEWVALIDATOR123\"" In this pattern, the response ETag describes the HTML projection, while the Link header's state-etag parameter conveys the SBR validator. Clients MUST use the state-etag parameter value (not the response ETag) for subsequent If-Match preconditions. Definition of state-etag Link Extension Parameter: The state-etag parameter is an extension parameter as permitted by [RFC8288] Section 3.4.2. Its value is an RFC 8288 quoted-string whose decoded content is an HTTP entity-tag as defined in [RFC9110] Section 8.8.3 (including the surrounding DQUOTE characters). The backslash escaping is required because Link parameters use the quoted-string production. For example, if the SBR ETag is "sha256-ABC123", the Link parameter is serialized as state-etag="\"sha256-ABC123\"". Clients extracting the entity-tag MUST: 1. Parse the parameter value as an RFC 8288 quoted-string (removing outer quotes and unescaping backslashes), yielding "sha256-ABC123". 2. Use this value directly in If-Match or If-None-Match headers without additional quoting changes. This ensures that regardless of which endpoint processes the write, all clients can obtain the updated Semantic Validator while maintaining correct HTTP semantics. 3.4.4. Patch Formats (Informative) When using PATCH [RFC5789] for partial updates, servers SHOULD support one or more of the following standard patch formats: * JSON Merge Patch ([RFC7396]): application/merge-patch+json for simple field-level merging. Suitable for most partial updates. * JSON Patch ([RFC6902]): application/json-patch+json for operation-based updates (including array manipulation). Servers SHOULD document which patch formats they accept. Clients SHOULD use the Accept-Patch header (if provided) to discover supported formats. Example: 428 Response for Missing Precondition When a client attempts a state-changing operation without If- Match, the server SHOULD return a 428 response: PATCH /api/article/123 HTTP/1.1 Host: example.com Content-Type: application/json HTTP/1.1 428 Precondition Required Content-Type: application/problem+json { "type": "https://example.com/errors/precondition-required", "title": "Precondition Required", "status": 428, "detail": "If-Match header is required for CRS mutations" } Alternative: 400 Response When 428 Is Not Available If the server environment does not support 428, it MAY use 400 with a clear error message: PATCH /api/article/123 HTTP/1.1 Host: example.com Content-Type: application/json HTTP/1.1 400 Bad Request Content-Type: application/problem+json { "type": "https://example.com/errors/missing-precondition", "title": "Missing Required Precondition", "status": 400, "detail": "If-Match header is required for state-changing operations on AST resources" } Example: 412 Response with Problem Details When a client's If-Match precondition fails, the server SHOULD return a Problem Details response indicating the current state: PATCH /api/article/123 HTTP/1.1 Host: example.com Content-Type: application/json If-Match: "sha256-ABC123OLDVALUE456789STALE0123" HTTP/1.1 412 Precondition Failed Content-Type: application/problem+json Link: ; rel="state"; type="application/json"; state-etag="\"sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F\"" { "type": "https://example.com/errors/precondition-failed", "title": "Precondition Failed", "status": 412, "detail": "The resource state has changed since you last read it.", "current-etag": "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F", "provided-etag": "sha256-ABC123OLDVALUE456789STALE0123" } The current SBR validator is conveyed via both the state-etag Link parameter (for header-level access) and the current-etag member in the Problem Details body. This allows clients to immediately retry with the correct If-Match value or refetch the latest state. 3.4.5. Conflict Resolution (Informative) When a client receives a 412 Precondition Failed response, it SHOULD follow one of these resolution strategies: 1. Refetch and Retry: Fetch the current SBR to obtain the new ETag and state, then reapply the intended mutation and retry with the updated ETag. 2. Three-Way Merge: If the client maintains the original state it read, the changes it intended to make, and can obtain the current server state, it MAY attempt an automatic merge (similar to version control systems). This is only appropriate when changes affect non-overlapping fields or can be deterministically combined. 3. User Intervention: Present the conflict to the user (human or automated decision system) for manual resolution, showing both the client's intended changes and the server's current state. 4. Abort: Abandon the update if the conflict indicates the client's view is too stale or the changes are incompatible. Servers MAY assist conflict resolution by including the current state or a conflict diff in the 412 response body (see Problem Details example above). This reduces round trips and provides clients with immediate context for resolution. Retry Example: Client receives 412: HTTP/1.1 412 Precondition Failed Content-Type: application/problem+json Link: ; rel="state"; type="application/json"; state-etag="\"sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F\"" Client immediately refetches: GET /api/article/123 HTTP/1.1 If-None-Match: "sha256-ABC123OLDVALUE456789STALE0123" HTTP/1.1 200 OK ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F" { ...current state... } Client reapplies mutation with fresh ETag: PATCH /api/article/123 HTTP/1.1 If-Match: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F" 3.4.6. Idempotency Servers MAY support an Idempotency-Key header for POST and PATCH to allow safe retries by automated agents. When a duplicate request is received with the same idempotency key and identical semantics, servers SHOULD respond with the original status code, headers (including ETag), and, if applicable, response body. Example: Idempotency-Key Usage for Resource Creation POST /api/articles HTTP/1.1 Host: example.com Content-Type: application/json Idempotency-Key: client-txn-abc123 {"title": "New Article", "body": "..."} HTTP/1.1 201 Created Location: /api/articles/456 ETag: "sha256-NEWVALUE789XYZ" Note on Resource Creation: The If-Match requirement applies to mutations of existing resources. For creating new resources, clients typically cannot use If-Match on the target URI (which does not yet exist). Servers MAY support creation patterns such as: * POST to a collection endpoint, returning the new resource URI and SBR ETag in the response (as shown above), or * PUT with If-None-Match: * to create a resource only if it does not already exist at that URI. Once created, subsequent mutations to the resource follow the standard If-Match protocol. Note: Idempotency-Key is an opaque token. Per HTTP header grammar, both token and quoted-string forms are acceptable; the exact format is implementation-defined. Idempotency-Key behavior is intentionally profile-neutral. Deployments that support this header SHOULD document replay windows, storage scope, and duplicate-detection semantics. 3.4.7. Asynchronous Updates For mutations that cannot complete synchronously, servers MAY respond with 202 Accepted and a Location header pointing to a status resource. When the mutation completes: * The status resource SHOULD indicate completion and provide the URI of the updated resource. * A subsequent GET on the updated resource MUST return the new SBR ETag. * Clients SHOULD poll the status resource or use server-sent events / webhooks if available. The original If-Match precondition applies at the time the 202 is issued; the server MUST reject the operation with 412 Precondition Failed if the precondition fails at that point, even if processing is deferred. 3.5. SBR Endpoint Headers To ensure correct caching and transfer behavior, SBR endpoints SHOULD include the following headers: * Cache-Control: SBR responses SHOULD include Cache-Control: no-transform to prevent intermediaries from modifying the representation (which would invalidate the Semantic Validator). * Vary: For single-URI deployments serving multiple media types via content negotiation (e.g., JSON and HTML from the same URI), set Vary: Accept to ensure caches differentiate by requested media type. Since SBR endpoints MUST NOT apply content-coding (per Encodings and ETags), Vary: Accept-Encoding is not applicable to the SBR itself. Note on Content Codings: The Semantic Validator (SBR ETag) is computed from the canonical, uncompressed representation bytes. SBR endpoints MUST NOT apply content-coding; the Cache-Control: no- transform directive prevents intermediaries from introducing encoding in transit. * Accept-Ranges: SBR endpoints SHOULD include Accept-Ranges: none if range requests would break the semantic integrity of the representation (e.g., partial JSON structures). Example SBR Response Headers: HTTP/1.1 200 OK Content-Type: application/json ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F" Cache-Control: no-cache, no-transform Vary: Accept Accept-Ranges: none Content-Digest: sha-256=:RK63H5GH1GQJQM8A7LN7RP8VNR7FVXWH1TQKJM8QZH4=: 3.6. Caching Considerations 3.6.1. SBR Caching AST caching behavior follows HTTP caching semantics [RFC9111]. SBR endpoints SHOULD follow these caching practices: * Non-Negotiated SBR: Prefer a single canonical media type for the SBR to avoid cache fragmentation. * Strong ETag: The SBR MUST expose a strong ETag as the Semantic Validator. * Cache-Control: Use Cache-Control: no-cache, no-transform to require revalidation while allowing storage. If the SBR contains sensitive or user-specific data, use Cache-Control: private or no-store as appropriate. * Vary: For single-URI deployments serving multiple media types via content negotiation, set Vary: Accept to ensure caches differentiate by media type. Since SBR endpoints MUST NOT apply content-coding (per Encodings and ETags), Vary: Accept-Encoding is not applicable to the SBR. * Accept-Ranges: Consider Accept-Ranges: none to prevent partial-byte range requests that could create ambiguity in state validation. * 304 Revalidation: Support conditional requests with If-None- Match and respond with 304 Not Modified when the SBR ETag matches. * ETag Scope: Do NOT reuse the SBR ETag on Projected endpoints, as this would conflate semantic and byte-level validation. 3.6.2. Projected Representation Caching Projected Representations SHOULD be cached using standard HTTP caching mechanisms: * Representation-Specific ETags: Use their own ETags based on the byte content of each projection. * Standard Cache-Control: Apply appropriate Cache-Control directives (e.g., max-age, public, private) based on the projection's volatility and sensitivity. * Client-Side Invalidation: Clients that perform CRS mutations SHOULD invalidate their own cached Projected Representations after a successful write or upon receiving a 412 Precondition Failed response. Note that shared caches and intermediaries will not automatically invalidate projections based on SBR changes. 4. Discovery of Synchronized Representations To enable agents to discover different representations of the same AST resource, servers SHOULD expose relationships between representations using the HTTP Link header [RFC8288]. 4.1. The state Relation (SBR Discovery) Projected Representations SHOULD include a Link header with rel="state" pointing to the State-Bearing Representation (SBR). This allows clients consuming a Projected Representation to discover the SBR for synchronization or editing. The state relation identifies the authoritative SBR for concurrency control purposes. Clients MUST use the ETag from the state target (the SBR) for all If-Match and If-None-Match preconditions on state-changing operations. Example (Projected Representation response): HTTP/1.1 200 OK Content-Type: text/html ETag: "html-v1" Link: ; rel="state"; type="application/json" 4.2. The alternate Relation (General Cross-Representation Navigation) The alternate link relation type is RECOMMENDED for general navigation between synchronized representations of the same AST resource. When providing an alternate link: * the type attribute MUST be present to indicate the media type of the target representation (for example, application/json, text/html); and * the profile attribute MAY be used to indicate a specific schema or capability set of the target representation. Example (SBR response linking to Projected): HTTP/1.1 200 OK Content-Type: application/json ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F" Link: ; rel="alternate"; type="text/html" Note: The state relation specifically identifies the SBR for concurrency control purposes. In contrast, rel="alternate" is for general cross-representation navigation and does not imply concurrency semantics. Clients MUST NOT assume that a representation linked via alternate participates in the AST concurrency protocol. 4.3. Bidirectional Linking To ensure agents can navigate between representations regardless of their entry point, linking SHOULD be bidirectional. * If Representation A links to Representation B, then Representation B SHOULD link back to Representation A (or to a canonical URI that resolves to A). This ensures that an agent encountering a structural representation (for example, JSON) can identify the corresponding rendered representation (for example, HTML) for attribution, verification, or human inspection. 4.4. Profile Advertisement To enable clients to detect whether a resource implements AST semantics, servers SHOULD advertise this using the profile link relation [RFC6906] via one of the following mechanisms: Link Header with Profile Relation: HTTP/1.1 200 OK Content-Type: application/json Link: ; rel="profile" ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F" Content-Type Profile Parameter: HTTP/1.1 200 OK Content-Type: application/json; profile="https://datatracker.ietf.org/doc/draft-jurkovikj- httpapi-agentic-state/" ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F" This allows clients to detect AST resources and apply appropriate concurrency control workflows (If-Match preconditions, 412 handling, etc.) instead of assuming traditional HTTP semantics. Implementations MAY advertise either a versioned profile URI (e.g., .../draft-jurkovikj-httpapi-agentic-state-01) or the versionless profile URI (e.g., .../draft-jurkovikj-httpapi-agentic-state/). Clients SHOULD accept both as equivalent identifiers for the purposes of feature detection. 5. Integrity and Transport In standard HTTP usage, ETags often serve a dual purpose: validating the semantic state for caching/concurrency, and validating the integrity of the response bytes (to detect transport corruption). In the AST profile, the State-Bearing Representation (SBR) ETag serves as the Semantic Validator for the Canonical Resource State (CRS). Projected Representations MAY have their own representation- specific ETags for caching purposes, but these MUST NOT be used as Semantic Validators for concurrency control. 5.1. Separation of State and Integrity To allow clients to verify the integrity of the payload bytes independently of the semantic state, AST servers SHOULD use the Content-Digest header field defined in [RFC9530]. * ETag (SBR): validates the *Canonical Resource State* (logical truth) and is used with If-Match and If-None-Match for concurrency control. * ETag (Projected): MAY be used for caching individual representations, but MUST NOT be used for state-changing preconditions. * Content-Digest: validates HTTP content according to [RFC9530], independently of CRS validation. Clients MUST NOT send If-Match or If-None-Match preconditions using a Projected Representation's ETag when interacting with the SBR endpoint. Only the SBR's own ETag participates in concurrency control logic. Example Response (SBR): HTTP/1.1 200 OK Content-Type: application/json ETag: "sha256-RK63H5GH1GQJQM8A7LN7RP8VNR7F" Content-Digest: sha-256=:RK63H5GH1GQJQM8A7LN7RP8VNR7FVXWH1TQKJM8QZH4=: Example Response (Projected): HTTP/1.1 200 OK Content-Type: text/html ETag: "html-v1" Link: ; rel="state"; type="application/json" Content-Digest: sha-256=:X8Z9Y7W6V5U4T3S2R1Q0P9O8N7M6L5K4=: This separation allows intermediaries and clients to detect payload integrity failures without conflating them with state changes. In AST, the SBR ETag serves as a semantic validator for the Canonical Resource State. Clients SHOULD use Content-Digest for verifying HTTP content integrity. Outside of AST contexts, traditional ETag usage for caching and integrity remains unchanged. When content-coding is applied to non-SBR (Projected) representations, servers MAY include Content-Digest and/or Repr-Digest [RFC9530] according to the Digest Fields content-coding rules. Clients that need to verify the unencoded representation MAY use Unencoded-Digest and express preferences with Want-Unencoded-Digest [I-D.ietf-httpbis-unencoded-digest], if provided/supported by the server. 5.2. Request Integrity (Client-Sent Digests) Clients MAY include Content-Digest or Repr-Digest [RFC9530] on state-changing requests to allow servers to verify payload integrity before processing. Servers that choose to validate request digests: * SHOULD document which digest algorithms they accept; * MUST reject requests with unsupported algorithms or malformed digests with an appropriate error response; and * SHOULD NOT echo the server-computed digest in error responses to avoid potential oracle attacks. When returning errors for digest validation failures, servers MAY use the problem types defined in [I-D.ietf-httpapi-digest-fields- problem-types]. These problem types will be registered in the HTTP Problem Types registry upon publication of that specification; servers SHOULD use the type member of the Problem Details response to reference the appropriate URI as defined in that specification. Example digest validation error: HTTP/1.1 400 Bad Request Content-Type: application/problem+json { "type": "https://iana.org/assignments/http-problem- types#digest-invalid-values", "title": "Invalid Digest Values", "status": 400, "detail": "The sha-256 digest value has incorrect length" } Request digest validation is independent of AST concurrency control; If-Match remains the mechanism for preventing lost updates, while digests verify payload integrity. 6. Computing and Managing Semantic Validators AST does not mandate a single algorithm for computing Semantic Validators. However, deployment predictability benefits from consistent approaches. 6.1. Canonicalization A common pattern is to derive the Semantic Validator from a canonical serialization of the CRS. For example: 1. Serialize the CRS to a structured format (for example, JSON). 2. Canonicalize the serialization (for example, by sorting keys and controlling numeric formats). 3. Compute a hash over the canonical form (for example, SHA-256). 4. Encode and prefix the hash to produce the ETag value. Servers SHOULD ensure that: * fields that are purely operational or volatile (for example, last access timestamps) are excluded from the canonical form; and * the canonicalization process is deterministic across deployments. Servers MAY use [RFC8785] JSON Canonicalization Scheme (JCS) or an equivalent deterministic procedure. When the SBR is JSON, servers MUST use [RFC8785] or a profile-specified, equivalently deterministic canonicalization prior to computing the SBR validator. 6.2. Storage Models Servers MAY: * compute Semantic Validators on demand from the CRS; or * store precomputed Semantic Validators alongside the CRS. When validators are stored: * they SHOULD be updated atomically with the CRS; and * they MUST be invalidated or recomputed whenever the CRS changes. When validators are computed on demand, implementations SHOULD ensure that the cost of computing the validator is small relative to the cost of generating the representation. 6.3. Relationship to Application Backends AST is agnostic to how applications store and manage CRS. For example: * a SQL application might treat a row (or set of rows) as CRS, with the Semantic Validator derived from a version column and relevant fields; * a document store might treat a document body plus metadata as CRS; * a CMS might treat a block tree or content graph as CRS. The only requirement is that the Semantic Validator change whenever the logical CRS changes, regardless of how many representations exist. 6.4. Non-AST Resources and Fallback Behavior Servers MAY implement AST for some resources and not others. For resources that do not follow AST: * servers MAY continue to use representation-specific ETags as byte validators; * servers MAY accept unconditional writes (no If-Match required), as in traditional HTTP APIs; and * clients MUST NOT assume AST semantics. Servers SHOULD clearly document which resources implement AST. 7. Conformance Requirements Summary This section provides a checklist of normative requirements for AST conformance. Implementations MUST satisfy all items marked MUST/REQUIRED; items marked SHOULD/RECOMMENDED are strongly advised. 7.1. Server Requirements 7.1.1. State-Bearing Representation (SBR) - [ ] MUST designate exactly one representation as the SBR for each AST resource - [ ] MUST assign a strong ETag to the SBR that changes whenever the CRS changes - [ ] MUST NOT apply content-coding to SBR responses (Content- Encoding MUST be absent) - [ ] SHOULD compute SBR ETag from canonicalized CRS (using RFC 8785 for JSON) - [ ] SHOULD include Cache-Control: no-transform on SBR responses 7.1.2. Concurrency Control - [ ] MUST evaluate If-Match preconditions on state-changing operations using strong comparison [RFC9110] - [ ] MUST respond with 412 Precondition Failed when If-Match does not match current SBR ETag - [ ] SHOULD respond with 428 Precondition Required when If-Match is missing on state-changing operations - [ ] SHOULD return Problem Details [RFC9457] body for 412, 428, and 400 (missing precondition) responses 7.1.3. Discovery and Linking - [ ] SHOULD include Link: rel="state" header on Projected Representations pointing to the SBR endpoint - [ ] SHOULD advertise AST profile using Link: rel="profile" or Content-Type profile parameter - [ ] SHOULD include bidirectional rel="alternate" links between representations 7.1.4. Prohibited Actions - [ ] MUST NOT reuse the SBR ETag as the ETag for Projected Representations - [ ] MUST NOT use weak entity-tags for the SBR validator - [ ] MUST NOT use Content-Encoding on SBR responses 7.2. Client Requirements 7.2.1. Reading State - [ ] SHOULD use If-None-Match with SBR ETag for conditional requests to the SBR - [ ] SHOULD NOT use SBR ETag as If-None-Match against Projected endpoints 7.2.2. Writing State - [ ] MUST obtain current SBR ETag before performing state- changing operations - [ ] MUST include If-Match header with SBR ETag on all state- changing requests to AST resources - [ ] MUST NOT use Projected Representation ETags as If-Match preconditions for CRS mutations - [ ] SHOULD handle 412 responses by refetching current state and retrying or resolving conflicts 7.2.3. Discovery - [ ] SHOULD follow rel="state" links from Projected Representations to discover SBR endpoints - [ ] SHOULD check for rel="profile" links to detect AST resources 7.3. HTTP Status Codes AST-conforming implementations MUST use these status codes as specified: Code - Usage 200 OK - Successful read or write 204 No Content - Successful write with no body (when using Content-Location pattern) 303 See Other - Redirect to SBR after successful write (optional pattern) 304 Not Modified - Conditional request matched current ETag 400 Bad Request - Digest validation failure or missing precondition (if 428 unavailable) 412 Precondition Failed - If-Match precondition did not match current ETag 428 Precondition Required - If-Match missing on state-changing operation 7.4. Required Headers 7.4.1. SBR Response Headers - ETag: Strong validator (e.g., "sha256-ABC123...") - Cache-Control: Should include no-transform - Vary: Accept for single-URI negotiated deployments - Link: rel="alternate" to Projected Representations (recommended) 7.4.2. Projected Response Headers - ETag: Representation-specific validator (optional) - Link: rel="state" pointing to SBR endpoint (recommended) 7.4.3. Write Request Headers - If-Match: SBR ETag for precondition evaluation (required) - Content-Type: Appropriate media type for request body - Idempotency-Key: For idempotent POST/PATCH (optional) This checklist is informative; the normative requirements remain those specified in the body of this document using RFC 2119 keywords. 8. Security Considerations This profile relies on existing HTTP security mechanisms. However, the synchronization of multiple representations introduces specific security considerations. 8.1. Consistency and Race Conditions The primary security benefit of AST is the prevention of race conditions (Lost Updates). By enforcing If-Match checks against the CRS, the server ensures that an agent cannot overwrite state changes made by another client, even if those changes were made via a different representation. Applications SHOULD treat failed preconditions (412, 428) as an expected outcome in concurrent editing scenarios and provide appropriate conflict resolution mechanisms. 8.2. Information Leakage via Divergence If the access control policies for different representations diverge, there is a risk of information leakage. * Servers MUST ensure that the authorization requirements for accessing a structural representation (for example, JSON) are at least as strict as those for the rendered representation (for example, HTML). * Servers MUST ensure that a structural representation does not expose sensitive data that is redacted in the rendered representation, unless the client is explicitly authorized to see the raw state. If different audiences see different subsets of the CRS, the server SHOULD either: * maintain separate CRS domains with separate Semantic Validators; or * apply view-specific filtering consistently to all representations exposed to that audience. 8.3. Validator Guessing Because Semantic Validators are often derived from content (for example, a hash), they may be susceptible to offline guessing attacks if the content has low entropy. Implementations SHOULD ensure that: * validators have sufficient entropy; or * validators are combined with a secret salt; or * validators are derived from internal versioning mechanisms rather than directly from plaintext content, if the content version itself is sensitive. Validators MUST NOT be treated as authentication or authorization tokens. 9. IANA Considerations 9.1. Link Relation Type Registration This document requests registration of the "state" link relation type in the "Link Relation Types" registry maintained by IANA per [RFC8288]: * Relation Name: state * Description: Refers to the State-Bearing Representation (SBR) of the current resource for concurrency control. The target is the authoritative CRS view and exposes the strong ETag used for If- Match and If-None-Match on CRS-affecting operations. * Reference: This document (Sections 4.1 and 9.1) * Notes: The target's media type SHOULD be suitable for machine processing (e.g., application/json). Clients MUST use the target's strong ETag (not the source representation's ETag) as the validator for CRS preconditions. The type attribute SHOULD be present on the link to indicate the target's media type. Rationale for Name Selection: The name state was chosen over alternatives such as edit, canonical, or source because: * edit (defined in [RFC5023]) implies write capability, which may not apply to all clients; * canonical [RFC6596] identifies the preferred URI for a resource, not specifically its concurrency-control representation; * source suggests origin content rather than authoritative state. The term state directly conveys that the target exposes the resource's authoritative state for concurrency purposes, aligning with the "State-Bearing Representation" terminology used throughout this specification. Registration Process and Timing: This registration is requested upon adoption or publication of this specification in the IETF stream. Per IANA registration policy, Link Relation Type registrations typically occur after Working Group adoption or RFC publication, not from unadopted Internet-Drafts. Interim Usage: Implementations deploying this profile prior to IANA registration SHOULD use the extension relation type URI: https://datatracker.ietf.org/doc/draft-jurkovikj-httpapi-agentic- state/rels/state This URI-based extension relation is immediately usable without registry conflicts and follows [RFC8288] extensibility mechanisms. Once the state relation type is registered by IANA, implementations SHOULD migrate to the registered simple string form (rel="state"). Example using URI-based extension relation: Link: ; rel="https://datatracker.ietf.org/doc/draft-jurkovikj- httpapi-agentic-state/rels/state"; type="application/json" Appendix A. Implementation Status Note to RFC Editor: Please remove this section before publication. This section records the status of known implementations of the AST profile at the time of publication. Based on [RFC7942], reviewers are invited to report implementation experiences. WordPress Dual-Native Implementation Organization: Independent implementation Description: A WordPress plugin implementing the AST profile for content management and template synchronization. Implementation Details: * SBR Endpoint: Exposes WordPress posts and templates as application/json representations at /wp-json/dual- native/v1/posts/{id} and /wp-json/dual-native/v1/design/templates/... * Semantic Validators: Uses SHA-256 content hashes as strong ETags, formatted as "sha256-{base64}", computed from canonicalized JSON representation of the CRS. * Concurrency Control: Enforces If-Match preconditions on all state-changing operations (POST, PATCH). Returns 412 Precondition Failed on ETag mismatches and 428 Precondition Required when If- Match is missing. * Projected Representations: HTML rendering at canonical WordPress URLs with rel="state" Link headers pointing to the SBR endpoint. * Discovery: Implements rel="state" link relations on HTML responses and rel="alternate" on SBR responses. * Multi-Bot Testing: Demonstrated with multiple concurrent agents. Reported testing showed reduced monitoring bandwidth and no lost updates in the tested concurrent-agent workload. Maturity: Experimental implementation reported in active use. Coverage: Implements all normative requirements of this specification including SBR designation, strong ETag generation, If-Match enforcement, 412/428 error handling with Problem Details (RFC 9457), and Link header discovery. Licensing: Open source Contact: antunjurkovic@gmail.com Appendix B. Canonicalization Test Vectors (Informative) This appendix provides test vectors for implementers to verify canonicalization and ETag computation. B.1. JSON Canonicalization (RFC 8785) Input (arbitrary formatting): { "status": "published", "id": 123 } Canonical form (JCS per RFC 8785): {"id":123,"status":"published"} SHA-256 (hex): f8b47f69857655c0c84feb9427d443933d91891589f5eee6e51 Resulting ETag (base64-encoded, example): "sha256-+LR/aYV2VcDIT+uUJ9RD2Sx8DhtEOTPZGJFYn17ublE=" The ETag value shown above is the Base64-encoded SHA-256 digest of the canonical JSON form. B.2. Numeric Precision Input: {"value": 1.0} Canonical form (JCS normalizes 1.0 to 1): {"value":1} Implementers MUST ensure their JSON canonicalization produces JCS- compliant output before hashing. Appendix C. Single-URI Deployment Example (Informative) This appendix demonstrates a complete workflow using the Single- URI deployment model, where both the Projected Representation (HTML) and the State-Bearing Representation (JSON) are served from the same URI via content negotiation. Scenario: A blog article at https://example.com/article/123 serves both HTML (for browsers) and canonical JSON (for API clients). An agent wants to read the human-friendly HTML, extract the Semantic Validator, and perform a safe write operation. C.1. Reading the Projected Representation The agent first requests the HTML Projected Representation: GET /article/123 HTTP/1.1 Host: example.com Accept: text/html Server response: HTTP/1.1 200 OK Content-Type: text/html ETag: "html-abc123" Vary: Accept Link: ; rel="state"; type="application/json" Understanding HTTP Caching

Understanding HTTP Caching

Status: published | Author: Jane Smith

HTTP caching is a fundamental optimization...

The Link: ; rel="state" header indicates the SBR is available at the same URI by requesting application/json. C.2. Obtaining the SBR Validator To obtain the Semantic Validator for safe writes, the agent requests the SBR: GET /article/123 HTTP/1.1 Host: example.com Accept: application/json Server response: HTTP/1.1 200 OK Content-Type: application/json ETag: "sha256-K8N9P3M2L5H7" Vary: Accept Link: ; rel="alternate"; type="text/html" Link: ; rel="profile" { "id": 123, "title": "Understanding HTTP Caching", "status": "published", "author": "Jane Smith", "body": "HTTP caching is a fundamental optimization..." } The SBR response uses rel="alternate" to link to the HTML projection, enabling bidirectional navigation. The rel="state" link is omitted because this response is the SBR, clients already have the authoritative validator in the ETag header. The agent now has the Semantic Validator "sha256-K8N9P3M2L5H7" which represents the current Canonical Resource State. C.3. Performing a Safe Write The agent wants to update the article status to "draft". It sends a conditional write using the Semantic Validator: PATCH /article/123 HTTP/1.1 Host: example.com Content-Type: application/merge-patch+json If-Match: "sha256-K8N9P3M2L5H7" { "status": "draft" } Success response (303 See Other pattern): HTTP/1.1 303 See Other Location: /article/123 Link: ; rel="state"; type="application/json"; state-etag="\"sha256-R9T4Q8P1N7M3\"" The agent can now follow the Location header to retrieve the updated SBR, or extract the new Semantic Validator "sha256-R9T4Q8P1N7M3" from the state-etag parameter for subsequent operations. Alternative success response (204 No Content pattern): HTTP/1.1 204 No Content Content-Location: /article/123 Link: ; rel="state"; type="application/json"; state-etag="\"sha256-R9T4Q8P1N7M3\"" Conflict response (state changed): If another agent modified the article between steps C.2 and C.3: HTTP/1.1 412 Precondition Failed Content-Type: application/problem+json Link: ; rel="state"; type="application/json"; state-etag="\"sha256-X2Y9Z4W1V8U5\"" { "type": "https://example.com/errors/precondition-failed", "title": "Precondition Failed", "status": 412, "detail": "The article has been modified by another agent.", "current-etag": "sha256-X2Y9Z4W1V8U5", "provided-etag": "sha256-K8N9P3M2L5H7" } The agent can extract the current Semantic Validator from the state-etag parameter and retry with the updated state. C.4. Optional: Zero-Fetch Optimization For monitoring scenarios, the agent can efficiently poll for changes without fetching the full representation: Pattern 1: HEAD request with If-None-Match HEAD /article/123 HTTP/1.1 Host: example.com Accept: application/json If-None-Match: "sha256-R9T4Q8P1N7M3" If unchanged: HTTP/1.1 304 Not Modified ETag: "sha256-R9T4Q8P1N7M3" Vary: Accept If changed: HTTP/1.1 200 OK ETag: "sha256-T5U8V1W4X7Y0" Vary: Accept Content-Type: application/json Content-Length: 234 Pattern 2: GET request with If-None-Match GET /article/123 HTTP/1.1 Host: example.com Accept: application/json If-None-Match: "sha256-R9T4Q8P1N7M3" Server returns 304 if unchanged, or 200 with updated content if changed. This zero-fetch pattern minimizes bandwidth while maintaining accurate change detection based on the Semantic Validator. 10. References 10.1. Normative References [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997. [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017. [RFC9110] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, DOI 10.17487/RFC9110, June 2022. [RFC8288] Nottingham, M., "Web Linking", RFC 8288, DOI 10.17487/RFC8288, October 2017. [RFC6585] Nottingham, M. and R. Fielding, "Additional HTTP Status Codes", RFC 6585, DOI 10.17487/RFC6585, April 2012. [RFC9530] Polli, R. and L. Pardue, "Digest Fields", RFC 9530, DOI 10.17487/RFC9530, February 2024. [RFC9457] Nottingham, M., Wilde, E., and S. Dalal, "Problem Details for HTTP APIs", RFC 9457, DOI 10.17487/RFC9457, July 2023. 10.2. Informative References [RFC9111] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Caching", STD 98, RFC 9111, DOI 10.17487/RFC9111, June 2022. [RFC6906] Wilde, E., "The 'profile' Link Relation Type", RFC 6906, DOI 10.17487/RFC6906, March 2013. [RFC5023] Gregorio, J., Ed., and B. de hOra, Ed., "The Atom Publishing Protocol", RFC 5023, DOI 10.17487/RFC5023, October 2007. [RFC5789] Dusseault, L. and J. Snell, "PATCH Method for HTTP", RFC 5789, DOI 10.17487/RFC5789, March 2010. [RFC6596] Ohye, M. and J. Kupke, "The Canonical Link Relation", RFC 6596, DOI 10.17487/RFC6596, April 2012. [RFC8785] Rundgren, A., Jordan, B., and S. Erdtman, "JSON Canonicalization Scheme (JCS)", RFC 8785, DOI 10.17487/RFC8785, June 2020. [I-D.jurkovikj-http-semantic-validator] Jurkovikj, A., "Semantic Validators for HTTP", Work in Progress, Internet-Draft, draft- jurkovikj-http-semantic-validator-00, May 2026. [RFC6902] Bryan, P., Ed. and M. Nottingham, Ed., "JavaScript Object Notation (JSON) Patch", RFC 6902, DOI 10.17487/RFC6902, April 2013. [RFC7396] Hoffman, P. and J. Snell, "JSON Merge Patch", RFC 7396, DOI 10.17487/RFC7396, October 2014. [RFC7942] Sheffer, Y. and A. Farrel, "Improving Awareness of Running Code: The Implementation Status Section", BCP 205, RFC 7942, DOI 10.17487/RFC7942, July 2016. [I-D.ietf-httpbis-unencoded-digest] Pardue, L. and M. West, "HTTP Unencoded Digest", Work in Progress, Internet-Draft, draft-ietf- httpbis-unencoded-digest-04, March 2026. [I-D.ietf-httpapi-digest-fields-problem-types] Kleidl, M., Pardue, L., and R. Polli, "HTTP Problem Types for Digest Fields", Work in Progress, Internet-Draft, draft-ietf-httpapi-digest-fields- problem-types-05, March 2026. Author's Address Antun Jurkovikj Email: antunjurkovic@gmail.com