Skip to content

RFC: Add External State Attestation constraint type for autonomous ex…RFC: External State Attestation — Environmental Verification Constraint for Autonomous Execution#9

Open
LembaGang wants to merge 19 commits into
agent-intent:mainfrom
LembaGang:main
Open

Conversation

@LembaGang

@LembaGang LembaGang commented Mar 17, 2026

Copy link
Copy Markdown

Summary

Related: #22 proposes environment.wallet_state as a sibling constraint in the environment.* namespace.

This RFC proposes environment.market_state as a new constraint type in the Verifiable Intent specification for autonomous mode (L3) execution.

Problem

Mastercard's acquisition of BVNK creates the authorization (Verifiable Intent) + execution (BVNK Layer1) layers of autonomous commerce. However a critical vulnerability remains: autonomous agents executing financial transactions have no cryptographic awareness of external real-world conditions.

Without this constraint, an agent with a valid VI credential can execute BVNK stablecoin settlements during market halts, exchange closures, or circuit breaker events — race conditions that cause invalid execution at scale.

Proposed Constraint: environment.market_state

Requires the agent to obtain an Ed25519-signed attestation from a verified oracle confirming market state before L3 execution is permitted.

Key design decisions:

  • Fail-closed unconditionally — any verification failure blocks execution, no retry
  • UNKNOWN and HALTED always fail — oracle uncertainty is a hard stop
  • Execution order is normative — must be checked before all other constraint types
  • Verifiers re-verify independently — agents cannot self-assert constraint satisfaction
  • SSRF protections required — non-HTTPS and private IPs rejected

Reference Implementation

Headless Oracle (headlessoracle.com) implements this constraint live across 28 global exchanges with Ed25519-signed receipts, 60-second TTL, and fail-closed architecture.

Compliance endpoint: https://headlessoracle.com/v5/compliance

Files Changed

  • spec/external-state-attestation.md — full normative specification with test vectors, failure mode reference, and open questions for the working group

Open Question for Working Group

The spec identifies a gap in §8 Q2: VI needs a trusted_issuers policy layer to prevent malicious L2 issuers pointing attestation_url at attacker-controlled servers. Happy to discuss mitigations with the working group.

@douglasborthwick-crypto

Copy link
Copy Markdown

Strong RFC. I want to flag a generalization of environment.* and contribute a concrete answer to your §8 Q2 (trusted_issuers).

The environment.* pattern applies to payment sources, not just market sessions

§2.2 invites future environment.* extensions. One that's structurally identical to environment.market_state:

environment.wallet_state

The same fail-closed fetch-and-verify-at-L3 pattern you defined for exchange sessions, applied to an on-chain payment source:

{
  "type": "environment.wallet_state",
  "attestation_url": "https://api.insumermodel.com/v1/attest",
  "trusted_jwks": "https://api.insumermodel.com/.well-known/jwks.json",
  "expected_key_id": "insumer-attest-v1",
  "subject_wallet": "0xabc...",
  "condition_hashes": [
    "0xc938b71ac78df5843d6823dd78ee0a5b64dd56fa850984e954dd070285169444"
  ],
  "max_age_seconds": 300
}

Your §5.2 execution-order rationale applies 1:1. A TOCTOU race between amount validation and execution into an insolvent wallet is the same class of bug as executing into a halted market. Wallet state is environmental, not transactional.

With BVNK now in the Mastercard settlement path, L2 mandates on stablecoin rails need a way to gate on "does the source wallet still satisfy condition X at L3 verification time?" — the exact shape your RFC already defines for market state.

Concrete answer to §8 Q2: key binding, not URL binding

You flagged that a malicious L2 issuer could direct the agent at an attacker-controlled oracle. This is a real concern for any environment.* constraint with an embedded attestation_url.

One pattern that works today: move trust from the endpoint URL to the signing key, published via JWKS.

The verifier:

  1. Fetches the attestation (which is already an ES256 JWT per your algorithm requirement in design-rationale §5)
  2. Fetches the JWKS at the URL named in the constraint's trusted_jwks field
  3. Verifies the JWT signature against a key in that JWKS whose kid matches expected_key_id
  4. Fails closed if the JWKS URL isn't on a policy-layer allowlist (wallet, credential issuer, or payment network — wherever the policy root lives)

The attacker now has to substitute the attestation URL AND the JWKS URL AND get the resulting JWKS URL past the policy allowlist, instead of just swapping the attestation endpoint.

Two properties this pattern has that are worth flagging:

  • Reuses VI's existing algorithm stack. ES256 / P-256 is already the required VI signing algorithm. No second crypto stack, no new verification library — verifiers already have the JWT+JWKS code path for SD-JWT.
  • Subject binding via sub claim. If the attestation JWT's sub claim is the wallet address, then "this attestation is about this payment source" is a native JWT claim check rather than a new constraint field. Reference: https://api.insumermodel.com/v1/attest returns an ES256 JWT with iss: https://api.insumermodel.com, sub: <wallet>, kid: insumer-attest-v1, and a conditionHash array a verifier can match against the constraint.

Happy to turn environment.wallet_state into a sibling draft RFC if the generalization is welcome. Not trying to compete with the market-state draft — view it as a second species in the same family.

@LembaGang

Copy link
Copy Markdown
Author

Douglas — appreciate the depth here. This is exactly the kind of engagement I was hoping the §8 open questions would provoke.

Let me respond to the three threads:

The generalization is welcome and I think it's right. When I wrote §2.2 as an explicit extension point, the intuition was that market sessions couldn't be the only environmental state that matters at L3 verification time. Your environment.wallet_state example validates that intuition with a concrete use case I hadn't prioritized. The TOCTOU race between amount validation and execution into an insolvent wallet is structurally identical to executing into a halted market — you're right that wallet state is environmental, not transactional. I'd genuinely like to see a sibling draft RFC for this.

On §8 Q2 — key binding over URL binding is a stronger answer than what I had in mind. Moving trust to the signing key discoverable via JWKS, with the policy-layer allowlist gating the JWKS URL itself, raises the attack surface from "swap one endpoint" to "swap the endpoint AND the JWKS URL AND survive the allowlist." That's a meaningful improvement. The fact that it reuses VI's existing ES256/JWT verification path rather than introducing a second crypto stack makes it practically adoptable — verifiers already have this code path for SD-JWT. I'm inclined to adopt this as the baseline proposal for trusted_issuers in the next revision.

One question I want to put to the working group: algorithm negotiation for environment.* constraints. The current market_state draft specifies Ed25519 (which is what our reference implementation uses). Your wallet_state constraint naturally aligns with ES256/P-256 since it composes with the existing VI JWT stack. I think the right answer is that the environment.* family should be algorithm-agnostic at the constraint-type level — each constraint type declares its signing algorithm, and verifiers support a negotiated set. This avoids forcing every oracle into a single curve while keeping the verification path deterministic per constraint instance. Worth discussing.

Re: the sibling RFC — yes, please. Two independent implementations arriving at the same fail-closed, fetch-and-verify, signed-attestation pattern from different directions (market sessions vs. on-chain wallet state) is exactly the kind of convergence that makes a constraint family worth standardizing. Happy to coordinate on shared structure so the two specs are composable from the start.

One practical thought: your subject_wallet field and the sub claim binding you described could inform how we think about subject binding more generally across environment.* constraints. In market_state, the "subject" is the exchange/session. In wallet_state, it's the wallet address. A common subject claim pattern across the family would make verification libraries cleaner.

Looking forward to the draft.

douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request Apr 15, 2026
…t state

Proposes environment.wallet_state as a second constraint type in the
environment.* namespace (following environment.market_state, PR agent-intent#9).

Requires agents to obtain an ES256 JWT attestation binding a signed
boolean verdict to a specific source wallet and condition hash before
L3 execution. Fail-closed, structurally identical to market_state.

Also answers PR agent-intent#9 §8 Q2 (trusted_issuers) by binding trust to the
JWKS signing key rather than the attestation_url.

Reference implementation: InsumerAPI (https://api.insumermodel.com),
verified live 2026-04-15.
@douglasborthwick-crypto

Copy link
Copy Markdown

@LembaGang — opened #22 with spec/environment-wallet-state.md. Structure mirrors external-state-attestation.md 1:1 so the two are visibly siblings; §6.3 is the JWKS-key-binding answer to §8 Q2, §8 Q1 puts the algorithm-negotiation question on record (ES256/JWS here vs Ed25519 in #9), and §8 Q6 records the family-wide subject binding generalisation from your review. Live test vectors from a 2026-04-15 call to the reference issuer are in Appendix A. Happy to iterate on #22 — and if you want to coordinate any shared-structure changes across both drafts before either merges, either venue works.

@LembaGang

Copy link
Copy Markdown
Author

Review posted on #22 raising three structural points (TOCTOU freshness as normative text, attestation provider neutrality, and family-wide algorithm agility). Coordinating shared-structure changes across both drafts before either merges makes sense — happy to do that in either venue.

douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request Apr 16, 2026
…ithm agility

Addresses LembaGang review (comment 4259989585) with three structural changes:

1. Provider neutrality: §4.1 restructured as abstract attestation interface.
   7 REQUIRED JWT claims (iss, sub, jti, iat, exp, pass, conditionHash) define
   the normative contract. results/blockNumber/blockTimestamp moved to OPTIONAL.
   Condition hash canonicalization moved to §7.2 as issuer-specific detail.
   A second conformant implementation needs only the core claims and a JWKS.

2. Attestation freshness: max_age_seconds renamed to max_attestation_age,
   elevated to REQUIRED with normative default of 300. New §4.6 documents
   TOCTOU rationale (Mango/Balancer oracle exploit class) and family-wide
   semantics. PR agent-intent#9 invited to adopt identical field and semantics.

3. Algorithm agility: New §4.7 resolves former Q1. Family-level agility per
   RFC 8725 §3.1, per-type MUST-implement (ES256 for wallet_state, Ed25519
   for market_state), SHOULD/MAY extension sets. Drafted as standalone block
   for verbatim adoption in PR agent-intent#9.

§6.1 and §6.6 genericized (InsumerAPI-specific URLs and canonicalization
detail consolidated in §7). §7 restructured into subsections (7.1–7.7).

No changes to the verification algorithm logic or security model.
Zero InsumerAPI code changes required.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@LembaGang

Copy link
Copy Markdown
Author

v0.2 revision coordinating with #22

Filed v0.2 of spec/external-state-attestation.md. Three structural changes aligned with @douglasborthwick-crypto's v0.2 on #22, plus targeted spec-implementation alignment.

1. Namespace framing. New §2.3 documents the sibling relationship to environment.wallet_state. Abstract, §2.1, and §2.2 updated to reflect the environment.* family rather than a standalone constraint. §5.2 execution-order rationale generalized to the family.

2. max_attestation_age as family-wide normative field. Renamed from max_age_seconds for lockstep alignment with #22 §4.6. Elevated from OPTIONAL to REQUIRED with a normative default of 60 seconds. New §4.6 documents TOCTOU rationale — the freshness window is the exploitable surface, attestation TTL is a provider-side default while max_attestation_age is a consumer-side policy bound, the two serve different principals and MUST be independently configurable. Precedent class for this constraint is market-execution history: the 2010 Flash Crash, circuit breaker races at session boundaries, and the 2020 WTI crude oil futures negative-price event. Family-wide semantics paragraph confirms identical meaning across all environment.* types.

3. Algorithm agility. New §4.7 lifted from #22 §4.7 with table rows swapped — Ed25519 as MUST-implement for this constraint (matches the Headless Oracle signing stack, @noble/ed25519, RFC 8032), ES256 as SHOULD in the extension set, Ed448 / ES384 / ES512 as MAY. RFC 8725 §3.1 is the normative hook. Per-type MUST-implement plus SHOULD/MAY extension sets, verifiers negotiate per constraint instance, fail-closed rejection of unsupported algorithms (not silent downgrade). One family-wide question, one answer, two specs.

4. Spec-implementation alignment. Before committing v0.2 I conformance-tested the spec against the deployed Headless Oracle reference implementation (a verifier built strictly from §4.1 and §4.2, run against live /v5/demo and /.well-known/oracle-keys.json). Three pre-existing misalignments surfaced — all predated v0.2 but became visible under strict reading. Fixed in this revision:

  • §4.1 attestation field: key_idpublic_key_id, to match the deployed receipt shape (and the published canonical payload specification at {issuer}/v5/keys → canonical_payload_spec.receipt_fields). Appendix A test vector and Appendix B failure table updated accordingly.
  • §4.2 Step 4 and §7.2 registry lookup: find(keys, k => k.id == A.key_id)find(keys, k => k.key_id == A.public_key_id), to match the deployed /.well-known/oracle-keys.json shape.
  • §4.1 envelope clause: added a "Response envelope vs signed attestation" paragraph disambiguating unsigned wrapper fields (discovery_url, extensions, nested receipt) from the signed attestation subset. Verifiers MUST canonicalise only the signed fields as published by the oracle's canonical payload specification — not every top-level field of the response body. This was implicit before; now explicit.

Zero Worker changes. The deployed implementation was always correct; the spec is now the thing that changed.

Secondary updates:

What did not change: the core verification algorithm (§4.2 steps 1-8), the fail-closed semantics, the UNKNOWN/HALTED handling, the SSRF protections, the SMA receipt format on the wire, the Headless Oracle reference implementation, or the canonical payload construction. Zero HO code changes required. Existing v0.1 consumers continue to work — the max_attestation_age default of 60 seconds matches the v0.1 default for max_age_seconds.

Coordination: @douglasborthwick-crypto — the four items I held back in my #22 review (composition semantics on mixed pass/fail, JWKS caching and rotation expectations, cross-chain temporal consistency, RFC 2119 audit) now read against both v0.2 drafts. Happy to take them in a follow-up round on whichever venue you prefer.

@douglasborthwick-crypto

Copy link
Copy Markdown

@LembaGang — v0.2 lands in lockstep. Your §2.3 sibling framing, max_attestation_age as REQUIRED with family-wide semantics, §4.7 per-type MUST-implement table, and the joint composition example all compose with #22 v0.2 cleanly. The two drafts now read as siblings with no further structural changes on my side.

On the four held-back items: propose tackling all four on #22 (where you raised them in the #22 review). Two are wallet_state-specific (JWKS caching / rotation, cross-chain temporal consistency); the other two (composition semantics on mixed pass/fail, RFC 2119 audit) affect both specs symmetrically — will port matching language to #9 as they land.

Can pick them up one at a time over the next 48 hours — start wherever you'd like.

douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request Apr 17, 2026
Answers the first of the four held-back follow-ups from PR agent-intent#9 v0.2
review (composition semantics on mixed pass/fail). New §5.5 in
environment-wallet-state.md between §5.4 Output Fields and §6 Security
Considerations:

- Conjunction semantics (family gate = AND across all environment.*)
- Named answer for the mixed pass/fail case (market_state passes,
  wallet_state fails -> family fails; no partial-fulfillment path)
- L3 execution gate as explicit normative rule (MUST NOT proceed to
  L3 if any environment.* entry in violations, regardless of
  transactional constraint outcome)
- Per-member diagnostic output (each failed environment.* produces
  its own violations entry; verifiers MUST NOT collapse)

§5.2 and all other sections unchanged. Drafted as standalone block
adoptable verbatim in environment.market_state §5.5 with no changes —
same pattern as §4.7.

Co-Authored-By: LembaGang <127877551+LembaGang@users.noreply.github.com>
douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request Apr 17, 2026
Answers the second of the four held-back follow-ups from PR agent-intent#9 v0.2
review (JWKS caching/rotation — scoped as wallet_state-specific since
environment.market_state uses an RFC 8615 key registry rather than a
JWKS URI). New §6.8 in environment-wallet-state.md between §6.7 Time
Synchronisation and §7 Reference Implementation:

- Caching permissibility: verifiers MAY cache, SHOULD respect issuer
  HTTP cache directives (Cache-Control, ETag, Last-Modified); TTL is
  implementation-defined when directives absent
- Conditional revalidation via If-None-Match + If-Modified-Since,
  304 Not Modified refreshes cache window without body transfer
- Kid-mismatch as cache bust: unrecognised kid MUST trigger fresh
  JWKS fetch before rejection, so rotated keys are discoverable
  without waiting for TTL
- Issuer rotation: both old and new keys published simultaneously
  during a grace window exceeding both max attestation lifetime and
  verifier cache TTL
- Fail-closed on fetch failure: no fallback to hard-coded keys;
  stale-cache fallback permitted only when deployment policy allows
- Per-constraint scope: JWKS fetch failure on one wallet_state
  constraint MUST NOT short-circuit other environment.* constraints;
  each produces its own violation entry independently
- Interaction with §6.2 replay cache: independent, no cross-dependency

No changes to §5.5 text in this commit — Gap 1 (completeness rule) +
Gap 2 (array index + subject_wallet identifier) mirror lands in a
subsequent commit after PR agent-intent#9 v0.3.1 ships, per sibling-spec venue
agreement.

Drafted as standalone block; agent-intent#9 MAY adopt symmetric JWKS-style caching
as optional hardening per its §6.3 note.
douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request Apr 17, 2026
Answers the second of the four held-back follow-ups from PR agent-intent#9 v0.2
review (JWKS caching/rotation — scoped as wallet_state-specific since
environment.market_state uses an RFC 8615 key registry rather than a
JWKS URI). New §6.8 in environment-wallet-state.md between §6.7 Time
Synchronisation and §7 Reference Implementation:

- Caching permissibility: verifiers MAY cache, SHOULD respect the
  issuer's Cache-Control directive when present; TTL is
  implementation-defined when Cache-Control is absent
- Kid-mismatch as cache bust: unrecognised kid MUST trigger fresh
  JWKS fetch before rejection, so rotated keys are discoverable
  without waiting for TTL
- Issuer rotation: both old and new keys published simultaneously
  during a grace window exceeding both max attestation lifetime and
  verifier cache TTL
- Fail-closed on fetch failure: no fallback to hard-coded keys;
  stale-cache fallback permitted only when deployment policy allows
- Per-constraint scope: JWKS fetch failure on one wallet_state
  constraint MUST NOT short-circuit other environment.* constraints;
  each produces its own violation entry independently
- Interaction with §6.2 replay cache: independent, no cross-dependency

No changes to §5.5 text in this commit — Gap 1 (completeness rule) +
Gap 2 (array index + subject_wallet identifier) mirror lands in a
subsequent commit after PR agent-intent#9 v0.3.1 ships, per sibling-spec venue
agreement.

Drafted as standalone block; agent-intent#9 MAY adopt symmetric JWKS-style caching
as optional hardening per its §6.3 note.
LembaGang added a commit to LembaGang/verifiable-intent that referenced this pull request Apr 18, 2026
Adds §5.5 Family Composition in response to the held-back follow-ups
from PR agent-intent#22 v0.2 review (conjunction semantics, L3 gate, per-member
diagnostic output). Co-drafted with Douglas Borthwick (InsumerAPI) over
PRs agent-intent#9 and agent-intent#22; mirrors PR agent-intent#22 §5.5 (commit 85cfaa0) with two
refinements agreed in PR agent-intent#22 discussion:

- Gap 1 (L3 gate timing): verifiers MUST evaluate every environment.*
  constraint to completion before refusing Layer 3; short-circuit
  evaluation is non-conforming. Composes with §5.2 ordering.

- Gap 2 (per-member disambiguation): every violation entry carries
  both an array-index machine identifier and a per-type human-readable
  identifier (MIC for market_state, subject_wallet for wallet_state).
  The §4.5 multi-exchange example (XNYS + XLON) is the driving case.

Rationale presents semantic ("independent questions compose as AND")
and architectural ("failure mode must be gating, or the type isn't in
the family") arguments as co-equal — conjunction as a family
membership criterion, not a per-type design decision. Load-bearing for
future environment.* types (regulatory_status, counterparty_credit).

Drafted as standalone block adoptable verbatim in environment.wallet_state
§5.5 with the per-type distinguishing-field row swapped. Same pattern
as §4.7 — one family-wide question, one answer, two specs.

No changes elsewhere in the spec; no verification algorithm, fail-closed,
or security-model changes; no Headless Oracle code changes required.

Co-Authored-By: Douglas Borthwick <douglasborthwick-crypto@users.noreply.github.com>
douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request Apr 18, 2026
… disambiguation (v0.3.1)

Mirrors PR agent-intent#9 v0.3 §5.5 Family Composition (commit 7a8987c,
environment-market-state) into environment-wallet-state.md. Two
refinements surfaced in PR agent-intent#22 discussion folded into §5.5.

Gap 1 (completeness rule): verifiers MUST evaluate every environment.*
constraint in the mandate to completion before refusing Layer 3 — even
after the first failure has been observed. Short-circuit evaluation of
environment.* constraints is non-conforming. Transactional-constraint
evaluation (mandate.*, payment.*) after a confirmed environment.*
failure remains implementation-defined. Composes with §5.2 ordering —
environment-before-transactional stays; completeness layers on top.

Gap 2 (per-member disambiguation): every violation entry MUST carry two
identifiers — the array index of the constraint in constraints[] as the
primary machine id, and a human-readable id derived from the
constraint's distinguishing field. Selection of the distinguishing
field is a per-type obligation analogous to per-type algorithm
declaration in §4.7. For environment.wallet_state the distinguishing
field is subject_wallet (REQUIRED per §4 schema, always present, no
fallback needed). Driving case: multiple wallet-state constraints in a
single mandate with different subject_wallet values (e.g., settlement
wallet + gas wallet).

Rationale now presents semantic and architectural arguments as
co-equal — conjunction as a family membership criterion, not a per-type
design decision. Any environment.* type whose failure mode is
OR-tolerable is outside the family's design charter.

No changes elsewhere in the spec; §4.1, §4.5, §4.7, §5.2, §6.*, §7.*
untouched. No InsumerAPI-side code changes required.

Co-Authored-By: LembaGang <127877551+LembaGang@users.noreply.github.com>
@douglasborthwick-crypto

Copy link
Copy Markdown

LembaGang — caught a small thing while pulling 67a5adb across for the parity port. The Co-Authored-By there is douglas@insumerapi.com, but I don't own that domain and it doesn't link to my GitHub. Correct address is 256362537+douglasborthwick-crypto@users.noreply.github.com — same as 7a8987c, which got it right.

Not urgent at all, and no action needed from you if it's a hassle. If you'd rather amend, it's a quick rebase since it's a trailer rather than message body:

git rebase -i 67a5adb^   # mark 'reword', fix trailer
git push --force-with-lease origin <branch>

Flagging so you've got the right string next time we co-author, more than anything.

@LembaGang

Copy link
Copy Markdown
Author

RFC 2119 audit, PR 9 v0.3 → v0.3.2.

Scope. Full keyword audit of spec/external-state-attestation.md at commit 7a8987c. 139 RFC 2119 keyword occurrences across 85 lines. Distribution (for the record): MUST 82, SHOULD 16, MUST NOT 15, MAY 10, REQUIRED 6, RECOMMENDED 5, SHALL 2, SHALL NOT 1, SHOULD NOT 1, OPTIONAL 1.

Findings — two. Both fixed in commit 67a5adb.

P1. max_attestation_age REQUIRED+default-60 contradiction carried forward from the v0.1-to-v0.2 elevation. Appeared in the §4 schema row, §4 Field Constraints bullet, §4.2 pseudocode Step 1, and both reference implementations (§7.2 JS, §7.3 Python). Fixed by removing the absent-case default — strict REQUIRED, missing field is malformed, verifiers MUST reject per §4.2 Step 1. Rationale: freshness is the primary exploitable surface (§4.6); silent defaults leave it undefined. The family-wide implication (same gap on PR 22) is discussed in that thread.

P2. §6.5 Constraint Stripping had zero normative keywords in a security-considerations section. Described the security property but did not require it. Fixed by adding one sentence requiring verifiers to reject mandates whose L2 signature does not validate over the full constraint list, and prohibiting subset-signed mandates.

P3 withdrawn. Previewed as SHALL/MUST normalization in the PR 22 reply. Post-audit: all SHALL references are in the line-66 Notational Conventions boilerplate, zero substantive usage elsewhere. Spec is already consistent on MUST/SHOULD/MAY throughout. My apologies for the preview — should have verified the data before the claim.

Post-v0.3.2 state. No outstanding P1 or P2 findings on PR 9. Next substantive round is v0.4 consolidation with PR 22.

@LembaGang

Copy link
Copy Markdown
Author

Douglas — amended 67a5adb to use the correct noreply.github.com address. New HEAD is 57fd7b6, force-pushed with lease, signature intact, tree diff zero. Apologies for the noise — the email was a bad default I pulled from your company name rather than checking against the v0.3 commit where the address was already correct. Both commits now carry the same format. Thanks for catching it.

douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request Apr 18, 2026
Coordinated v0.4 release with PR agent-intent#9 environment.market_state as a
single-commit-on-both-specs bundle per LembaGang's (b) proposal
accepted in PR agent-intent#22 comment 4274334595 and locked at comment 4274435668.
LembaGang lifts §6.8 onto PR agent-intent#9 v0.4 after this lands, same lockstep
pattern as §5.5.

Audit-parity port from PR agent-intent#9 v0.3.2 (commit 57fd7b6, LembaGang):

(1) max_attestation_age strictness — removed absent-case default of 300
    seconds from:
    - §4 schema row: "default of 300" + "SHOULD always include"
      softener replaced with explicit MUST-include + MUST-reject-if-
      missing.
    - §4 Field Constraints bullet: "when absent... default of 300"
      replaced with malformed-rejection + no-default declaration +
      §4.6 security rationale.
    - §4.2 pseudocode Step 1: added absent-check before range check.
    - §7.6 JS reference: removed destructuring default; added
      undefined-check throw.
    - §7.7 Python reference: removed .get() default; added membership-
      check + ValueError.

    Missing max_attestation_age is now uniformly malformed; verifiers
    MUST reject per §4.2 Step 1. Closes the v0.2 REQUIRED-elevation-
    with-retained-default contradiction.

(2) §6.5 Constraint Stripping — added normative sentences requiring
    verifiers to reject mandates whose Layer 2 signature does not
    validate over the full constraint list, and prohibiting acceptance
    of subset-signed mandates. Closes the zero-normative-keyword gap
    identified by LembaGang's RFC 2119 audit.

Three consumer-policy additions (Doug's Apr 18 17:42 proposal comment
4274241447, LembaGang-approved in comment 4274435668):

(3) stale_cache_fallback_permitted OPTIONAL boolean field (default
    false):
    - §4 schema row added (OPTIONAL per LembaGang (i) at 4274435668;
      default-false; payment-execution MUST NOT set true).
    - §4 Field Constraints bullet with boolean-type hygiene clause:
      "if present, MUST be a strict boolean. Non-boolean values
      (including string "false", null, or numeric) MUST be rejected
      as malformed per §4.2 Step 1."
    - §4.2 pseudocode Step 1 type-check.
    - §6.8 "Fail-closed on fetch failure" paragraph: stale-cache
      sentences replaced with field-driven text (MAY use expired cache
      when true, MUST produce violation when false/absent, payment-
      execution MUST NOT set true).

    Shape follows the v0.3.2 rule-narrowing: REQUIRED remains the right
    pattern where no nontrivial default is safe across deployment
    classes (max_attestation_age); OPTIONAL-with-default is the right
    pattern where a single default is correct for almost all
    deployments (stale_cache_fallback_permitted). Parallel-construction
    Field Constraints bullet matches the max_attestation_age pattern.

(4) §6.8 grace-window discoverability: issuers SHOULD publish
    rotation-start and grace-window-end timestamps through an auditable
    channel. Channel MAY be out-of-band (release notes, status page,
    signed rotation announcement) or in-band via a JWKS top-level
    metadata field (e.g., rotation_announcement with
    rotation_started_at / previous_kid / new_kid / grace_window_end).
    SHOULD is on discoverability, not form. Future revision may elevate
    to REQUIRED if the WG converges on a canonical in-band mechanism.

(5) §6.3 JWKS URL migration paragraph: trusted_jwks URL change is a
    new-mandate event by design. Migration path: issuer publishes a
    new JWKS at the new URL; mandate issuers emit new mandates
    targeting the new URL; existing mandates expire naturally via
    exp. Deliberate cost/benefit: trust root cannot be silently
    relocated, at the cost of non-free URL migration.

(6) SHALL→MUST normalization NOT NEEDED: post-audit verification on
    both specs shows all SHALL references sit in the RFC 2119
    Notational Conventions boilerplate (line 67 on agent-intent#22, line 66 on
    agent-intent#9); zero substantive usage elsewhere. LembaGang's P3 finding
    withdrawn on PR agent-intent#9, symmetric on agent-intent#22.

§9 changelog: v0.4-draft row added above v0.3.1-draft.

No architectural changes. No family-wide changes. No InsumerAPI-side
code changes required. Co-drafted with LembaGang (Headless Oracle)
over PRs agent-intent#9 and agent-intent#22.

Co-Authored-By: LembaGang <127877551+LembaGang@users.noreply.github.com>
LembaGang added a commit to LembaGang/verifiable-intent that referenced this pull request Apr 19, 2026
…chanism-bound

Adds a third scope category to §4.8 in response to the taxonomy gap Douglas
Borthwick surfaced on PR agent-intent#22's v0.5 mirror: wallet_state fields
`required_condition_hashes` and `attestation_request_body` are per-type
scope but not bound by trust-root mechanism — their binding is to the
constraint type's evaluation mechanism (output shape or wire-protocol).

Three scope categories now recognised:

- family-wide-trust-root-agnostic (max_attestation_age)
- per-type-trust-root-mechanism-bound (stale_cache_fallback_permitted)
- per-type-evaluation-mechanism-bound (empty at v0.5.1; no market_state
  fields placed there; declaration only)

The new category preserves the -mechanism-bound suffix, keeping the
taxonomic level parallel to the existing per-type category (trust-root
mechanism vs. evaluation mechanism). Umbrella covers both the evaluator's
output shape (condition-hash sets vs. status enum) and the wire-protocol
binding to the evaluator (request body shape).

Preamble ("recognises three scope categories") and forward rule ("beyond
the three currently recognised") updated for consistency. The SHOULD
clause on placement under existing categories holds: the clause guards
against speculative proliferation, not evidence-based category addition
when two fields on a sibling spec clearly belong outside the two existing
categories.

Charter declaration is family-wide; field-table population for
environment.wallet_state sits with PR agent-intent#22's v0.5 mirror. Same standalone-
block pattern as §5.5 / §6.8 — one family-wide question, one answer, two
specs; PR agent-intent#9 leads the taxonomy, PR agent-intent#22 mirrors with populated field rows.

v0.5.1 is a patch-level refinement of v0.5. No header bump — the
document-level version marker stays at 0.5-draft; the v0.5.1 row in §9
records the taxonomy change. Forward rule holds: further scope categories
beyond these three are working-group revisions.

No algorithm changes; no security-model changes; no Headless Oracle code
changes required.

Co-Authored-By: Douglas Borthwick <256362537+douglasborthwick-crypto@users.noreply.github.com>
douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request Apr 19, 2026
…my with populated wallet_state field table

Mirrors PR agent-intent#9 v0.5.1-draft (commit 7b97827, LembaGang, Headless Oracle)
into environment.wallet_state §4.8. Closes the v0.5 round on this spec
per LembaGang's comment 4276111822: "You commit v0.5 §4.8 on PR agent-intent#22:
field table per the Note on family coordination, with
required_condition_hashes and attestation_request_body under
per-type-evaluation-mechanism-bound." Single v0.5-draft commit on the
wallet_state side; document header bumped 0.2-draft to 0.5-draft
(capturing v0.3 / v0.3.1 / v0.4 header omissions).

Three scope categories ported verbatim from 7b97827 as family-wide
prose:

- family-wide-trust-root-agnostic — identical semantics across every
  environment.* constraint type.
- per-type-trust-root-mechanism-bound — semantics bound to the specific
  trust-root mechanism (RFC 7517 JWKS here; RFC 8615 key registry on
  environment.market_state).
- per-type-evaluation-mechanism-bound — semantics bound to the type's
  evaluation-mechanism output shape or wire-protocol binding to the
  evaluator.

Field table populated for current environment.wallet_state fields:

- max_attestation_age               family-wide-trust-root-agnostic  (§4.6)
- trusted_jwks                      per-type-trust-root-mechanism-bound  (§6.3)
- stale_cache_fallback_permitted    per-type-trust-root-mechanism-bound  (§6.8)
- subject_wallet                    per-type-evaluation-mechanism-bound  (§5.5)
- required_condition_hashes         per-type-evaluation-mechanism-bound  (§4.1)
- attestation_request_body          per-type-evaluation-mechanism-bound  (§4.1)

Rationale for subject_wallet placement under
per-type-evaluation-mechanism-bound: the swap test is the load-bearing
argument. Replace ES256+JWKS with an Ed25519 scheme that binds wallets
through a different mechanism, and subject_wallet still does the §5.5
per-member disambiguation job against whatever the new format calls
the wallet identifier. The sub: <wallet> binding lives in the
attestation payload — the issuer's trust-root-specific claim that the
signed attestation is about this wallet — not in the constraint field.
subject_wallet as a constraint field is the verifier-side matching
slot: it names which wallet the attestation must prove pass for. That
matching function survives any trust-root mechanism swap. The
counter-case (trust-root-bound via JWT sub to wallet) collapses under
the swap test: the binding lives in the attestation, not in the
constraint's subject_wallet slot.

Rule for future fields and Relationship to §4.6/§4.7 ported verbatim
from 7b97827 as family-wide prose. Note on family coordination is
reciprocal, pointing at PR agent-intent#9 commit 7b97827 per the §5.5 precedent
(PR agent-intent#22 commit 7848bc2 points at PR agent-intent#9 commit 7a8987c).

No algorithm changes; no security-model changes; no §6.* changes; no
§7.* changes; no InsumerAPI-side code changes required.

Co-Authored-By: LembaGang <127877551+LembaGang@users.noreply.github.com>
douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request Apr 19, 2026
…nale entries

Closes the §4.8 field-table coverage asymmetry flagged by LembaGang in
comment 4276249269 (6/9 wallet_state constraint fields declared at v0.5;
missing attestation_url, expected_kid, expected_issuer). Path (1)
selected over narrowing the §4.8 preamble's universal quantifier per
Doug's comment 4276295574 and LembaGang's green-light in comment
4276315303.

Three table rows added to §4.8:

- attestation_url            family-wide-trust-root-agnostic     (§4.1)
- expected_kid               per-type-trust-root-mechanism-bound (§6.3)
- expected_issuer            per-type-trust-root-mechanism-bound (§6.3)

Three rationale entries integrated into the §4.8 post-table paragraph
in category order. The attestation_url entry is a three-sentence defense
block pre-empting the §4.8-internal question of why the URL is
family-wide when attestation_request_body (which targets the same URL)
is per-type-evaluation-mechanism-bound: the placement lands on the same
basis as max_attestation_age in §4.6 — identical semantic role across
types, with per-type variance localised at neighbouring fields (HTTP
verb, request-body shape). expected_kid and expected_issuer are
one-sentence entries semicolon-joined with their market_state sibling
notes, classified on JOSE-signing-stack specificity: both are JWT
header/claim bindings parallel-but-mechanism-specific on
environment.market_state, which uses an RFC 8615 key registry
(oracle_public_key_id) and derives issuer identity from the attestation
payload rather than from a constraint-level JOSE iss binding.

Document header stays at 0.5-draft — patch-level refinement, not a new
minor version (matches LembaGang's convention on commit 7b97827 where
PR agent-intent#9 shipped v0.5.1-draft with header unchanged).

No schema changes; no algorithm changes; no security-model changes; no
changes outside §4.8; no InsumerAPI-side code changes required.
LembaGang to mirror onto PR agent-intent#9 as v0.5.2-draft with attestation_url
(family-wide-trust-root-agnostic), oracle_public_key_id
(per-type-trust-root-mechanism-bound), and expected_status
(per-type-evaluation-mechanism-bound — status-enum analog to
required_condition_hashes) per comment 4276315303.

Co-Authored-By: LembaGang <127877551+LembaGang@users.noreply.github.com>
@LembaGang

Copy link
Copy Markdown
Author

Douglas —

v0.5.2 shipped on #9 as commit 6fb06b6. Single-file diff (+5/-1).

Three items per your 4effcb8 handoff:

Three table rows added to §4.8, grouped by scope category matching your v0.5 layout: attestation_url (family-wide-trust-root-agnostic, §4.1) placed under max_attestation_age in the family-wide bucket; oracle_public_key_id (per-type-trust-root-mechanism-bound, §6.3) grouped with stale_cache_fallback_permitted in the trust-root bucket; expected_status (per-type-evaluation-mechanism-bound, §4.1) as sole entry in the evaluation-mechanism bucket for now.

Three rationale entries integrated into the §4.8 post-table paragraph in category order, paralleling your v0.5.1 structure. attestation_url is the three-sentence defense block carrying the WG-reviewer pre-emption — semantic role identical across types, per-type variance localised at neighbouring wire-protocol fields (per-type §4.1 interface + attestation_request_body on environment.wallet_state), placement basis identical to max_attestation_age in §4.6. oracle_public_key_id is a one-sentence entry citing the RFC 8615 key registry mechanism and naming expected_kid as the parallel wallet_state field with JOSE-kid-specific semantics. expected_status is a one-sentence entry tying the market-session status vocabulary (per §4 schema: OPEN or CLOSED) to required_condition_hashes as the analogous evaluation-mechanism-bound field on environment.wallet_state — a different per-type evaluation primitive (status-enum equality vs. hash-set membership) for the same structural role.

Document header stays at 0.5-draft — patch-level refinement per your convention on 7b97827.

RFC 2119 audit findings summary landing in a separate comment shortly. Cross-chain temporal consistency still yours after that.

@LembaGang

Copy link
Copy Markdown
Author

Douglas —

RFC 2119 audit findings for PR #9 at 6fb06b6. Full keyword sweep against the v0.5.2 body, picking up where 67a5adb's audit pass left off. Findings below; nothing blocks v0.5.2.

Methodology

Word-boundary grep for every RFC 2119 + RFC 8174 keyword (MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, OPTIONAL) across the full spec body. 140 total occurrences. Excluded from analysis: the 9 hits in §1 Notational Conventions boilerplate (definitional, not normative) and 6 hits in §9 Changelog (descriptive commit notes). Remaining 125 analyzed against RFC 2119 §2-6 semantics, categorised by section (§2-§8 plus Appendices A/B), each checked for: keyword strength matches requirement strength, keyword usage matches action context, and no contradictions with other normative text in the spec.

Keyword distribution: MUST 67, MUST NOT 20, REQUIRED 11, SHALL 0 (post-v0.4 audit confirmation), SHALL NOT 0 substantive, SHOULD 19, SHOULD NOT 0 substantive, RECOMMENDED 5, MAY 14, OPTIONAL 2.

Findings

P1 (contradiction or missing normative force): 0.
The two P1s that existed at 67a5adbmax_attestation_age REQUIRED+default-60 contradiction and §6.5 Constraint Stripping normative gap — both closed in v0.3.2 and remain closed at v0.5.2. No new P1s introduced across v0.3, v0.3.1, v0.4, v0.5, v0.5.1, or v0.5.2.

P2 (misuse of keyword strength or action context): 0.
Every MUST / MUST NOT / REQUIRED / SHOULD / MAY / RECOMMENDED / OPTIONAL occurrence in the spec body matches RFC 2119 semantics at the correct strength for the requirement it imposes.

P3 (clarity, consistency, style): 3.

P3-1: §5.2 agent short-circuit vs. §5.5 verifier completeness — subject distinction implicit

§5.2 L686-688 says: "If any environment.* constraint fails, the agent MUST NOT evaluate remaining constraints and MUST NOT proceed to L3 creation."

§5.5 L719 says: "Verifiers MUST evaluate every environment.* constraint in the mandate to completion before refusing Layer 3, even after the first failure has been observed. Short-circuit evaluation of environment.* constraints is non-conforming..."

Reconciliation relies on a subject distinction (agent in §5.2, verifier in §5.5) and a phase distinction (L3 creation vs. L3 acceptance) that is load-bearing but not explicit on-page. A WG reviewer reading both clauses together can reasonably read surface tension where none exists — §5.5's own "This composes with §5.2's ordering requirement" asserts composition but only addresses §5.2's ordering clause, not §5.2's short-circuit clause.

The composition actually earned:

  • Agents (pre-L3-creation): stop at first environment.* failure per §5.2. Short-circuit is a self-gating optimization for the agent's own execution path.
  • Verifiers (L3-acceptance): evaluate every environment.* constraint to completion per §5.5. Completeness is required for the diagnostic audit trail the family depends on.

Proposed fix (single sentence, either §5.2 or §5.5): add a bridge sentence making the subject distinction explicit. Example for §5.2 after the short-circuit clause: "This short-circuit applies to the agent's pre-L3-creation self-gating path; verifier-side L3-acceptance evaluation is governed by §5.5's completeness rule, which requires every environment.* constraint in the mandate be evaluated for the diagnostic audit trail regardless of which member failed first."

Because §5.5 is family-wide prose shared verbatim between PR #9 and PR #22 at 7a8987c / 7848bc2, this P3 likely exists symmetrically on PR #22. Your §5.2's rationale says "inherited 1:1" from #9's §5.2 — if the short-circuit clause landed identically on your side, the clarity gap is symmetric and the bridge sentence should land in lockstep if we take that path.

Venue preference: your call. If you'd prefer the bridge land in §5.5 (so it's family-wide and ports verbatim), either of us can draft it. If you'd prefer per-spec §5.2 edits (market_state-local + wallet_state-local), I'll take #9 and you take #22.

P3-2: §2.3 Companion Documents table L142 — descriptive vs. normative register

The row describing design-rationale.md §3.1 reads: "§3.1, per-type MUST-implement algorithm, SHOULD/MAY extension sets"

The uppercase normative keywords here describe what §3.1 contains rather than imposing a requirement. A reader parsing §2.3 as a description of companion docs would not expect normative force on this row; a reader parsing every uppercase keyword as normative (the RFC 2119 convention) could read it as a redundant or misplaced requirement.

Proposed fix (trivial, market_state-local): lowercase the keywords or rephrase: "§3.1, a per-type mandatory signing algorithm with extension sets at recommended and optional levels." Non-blocking; polish.

P3-3: §2.4 L183 — RECOMMENDED/SHOULD redundancy

Current: "Layer 3 evidence field (RECOMMENDED): Agents SHOULD include a..."

RFC 2119 §3 treats SHOULD and RECOMMENDED as synonymous. Using both in the same sentence (label-level RECOMMENDED, body-level SHOULD) is stylistically redundant without adding semantic content. Not an error — both keywords are correctly applied — but a consistency pass could pick one.

Proposed fix (trivial, market_state-local): either drop the label RECOMMENDED (body SHOULD carries the weight) or drop the body SHOULD (label RECOMMENDED carries it). Marginal; polish.

Sequencing

  • P3-1 (§5.2/§5.5 clarity): family-wide shape likely; venue your call. Either v0.5.3 on both specs (parallel commits) or v0.6 scope. No rush.
  • P3-2 and P3-3: market_state-local, trivial, I can ship as a v0.5.3 patch whenever — or fold into v0.6 alongside any other polish that accrues.

Cross-chain temporal consistency still yours next; v0.5.2 mirror is landed on my side as 6fb06b6.

@douglasborthwick-crypto

Copy link
Copy Markdown

LembaGang —

Audit read. P1/P2 zero is clean. P3-2 and P3-3 are your-side polish, no input needed.

On P3-1:

Verified §5.5 Block 3 ("L3 execution gate and completeness") is verbatim between 6fb06b6 (#9) and 4effcb8 (#22). Option A — family-wide bridge in §5.5 — is the right venue.

§5.2 parity finding worth flagging. The short-circuit clause ("agent MUST NOT evaluate remaining... MUST NOT proceed to L3 creation") is on #9's §5.2 only. #22's §5.2 carries the ordering clause and rationale but not the short-circuit. The "inherited 1:1" note on #22's §5.2 is scoped to the rationale paragraph, not the body.

Consequence for Option A portability: the bridge is verbatim-portable only if phrased abstractly (agent-phase vs verifier-phase distinction, no §5.2 back-reference). If you prefer the referential phrasing you sketched ("This short-circuit applies to..."), #22's §5.2 short-circuit adoption becomes a prerequisite and folds into the bridge round rather than being a separate scope question. Your call on phrasing — and on whether #22's §5.2 should adopt short-circuit for family-wide symmetry either way.

Drafting: you surfaced it — take the bridge draft. I'll review and mirror on #22 in lockstep.

Cross-chain temporal consistency next on my side.

@LembaGang

Copy link
Copy Markdown
Author

Douglas —

Concur on Option A venue — family-wide bridge in §5.5 Block 3 since the block is verbatim across both specs. Your §5.2 parity catch is correct and I missed it in the audit — I said the short-circuit clause "likely exists symmetrically on PR #22" without verifying. It doesn't, and that asymmetry is worth resolving in the same round.

Referential phrasing is the sharper read. The abstract version would document the agent-phase/verifier-phase distinction as a general principle, but the referential version directly resolves the §5.2-short-circuit vs. §5.5-completeness tension that a WG reviewer would notice. The reader arriving at §5.5 with §5.2 in mind gets the answer on-page rather than having to reconstruct the relationship from abstract principle.

On #22 adopting §5.2 short-circuit for family-wide parity: my lean is yes, and to fold into the same v0.5.3 round. Three reasons:

  1. Behavioral consistency. An agent doing pre-L3 self-gating on environment.market_state failures should behave identically on environment.wallet_state failures — environment-state failure is environment-state failure regardless of type. The family's fail-closed posture argues for symmetric agent behaviour across types.

  2. Reconciles your "inherited 1:1" note on RFC: environment.wallet_state — sibling constraint for on-chain wallet state #22's §5.2. The rationale paragraph claims 1:1 inheritance from RFC: Add External State Attestation constraint type for autonomous ex…RFC: External State Attestation — Environmental Verification Constraint for Autonomous Execution #9; the body currently diverges on the short-circuit clause. Adding short-circuit to RFC: environment.wallet_state — sibling constraint for on-chain wallet state #22's §5.2 body makes the "inherited 1:1" note truthful rather than scoped-to-rationale-only.

  3. Single coordinated release. v0.5.3 becomes "§5.2 + §5.5 clarity pass" across both specs — matches the §4.7/§5.5/§6.8/§4.8 precedent for family-coordinated releases rather than splitting across v0.5.3 and v0.5.4.

Proposed v0.5.3 shape across both specs:

Draft bridge sentence — inserted after §5.5 Block 3's "even after the first failure has been observed" clause, before "The violations list MUST contain one entry...":

"The completeness requirement applies to the verifier-side L3-acceptance evaluation path; agent-side pre-L3-creation evaluation is governed by §5.2's short-circuit clause, which permits agents to stop at the first environment.* failure as a self-gating optimization distinct from the verifier's diagnostic-completeness obligation."

Eyeball before I commit? If the §5.2 cross-reference reads right and the verifier-side / agent-side distinction is phrased how you'd phrase it, I'll draft v0.5.3 on #9 (§5.5 bridge sentence only; #9 §5.2 already has short-circuit). You draft v0.5.3 on #22 (§5.2 short-circuit addition + §5.5 bridge sentence in lockstep).

Cross-chain temporal consistency — replying on #22 separately.

@douglasborthwick-crypto

Copy link
Copy Markdown

LembaGang —

Option A + v0.5.3 shape + §5.2 fold-in — concur on all three. The three reasons hold: behavioral-consistency is the load-bearing one for a WG reader, the "inherited 1:1" truthfulness point is the right tightening (the note on #22's §5.2 currently lives in the rationale paragraph only — body parity makes it honest about body content too), single coordinated release matches the §4.7/§5.5/§6.8/§4.8 precedent cleanly.

Bridge sentence — green on substance, one precision flag for your call.

The verifier-phase vs agent-phase distinction reads how I'd phrase it. The §5.2 cross-reference resolves the §5.2/§5.5 tension on-page for a WG reviewer — sharper than abstract phrasing would have been.

One wording flag, optional: the clause reads "permits agents to stop at the first environment.* failure as a self-gating optimization." Verified §5.2 at 6fb06b6 L687-688 carries two MUST NOTs ("agent MUST NOT evaluate remaining constraints and MUST NOT proceed to L3 creation") — fail-closed, not permissive. "Permits... optimization" reads MAY-register against §5.2's normative force. A careful reader chasing the cross-reference gets the MUST NOT downstream; a reader skimming the bridge could infer the agent has discretion to stop rather than an obligation to stop.

Minimal precision rewrite matching §5.2 register byte-for-byte:

"...agent-side pre-L3-creation evaluation is governed by §5.2's short-circuit clause, which requires agents to stop at the first environment.* failure as a fail-closed agent-side halt distinct from the verifier's diagnostic-completeness obligation."

Your call. The cross-reference does carry the normative weight downstream, so the original reads fine to a careful reader. Happy either way; flagging so you can weigh it on your own RFC-2119 audit register.

Work split confirmed.

Sequencing: you commit #9 bridge when you're ready; I'll commit #22's §5.2 + §5.5 pair in one v0.5.3 patch following your #9 commit.

Cross-chain temporal consistency — replying on #22.

LembaGang added a commit to LembaGang/verifiable-intent that referenced this pull request Apr 20, 2026
Inserts a single bridge sentence into §5.5 Block 3 ("L3 execution gate and completeness") that names the phase distinction explicitly: the §5.5 completeness requirement applies to the verifier-side L3-acceptance evaluation path; agent-side pre-L3-creation evaluation is governed by §5.2's short-circuit clause, which requires agents to stop at the first environment.* failure as a fail-closed agent-side halt distinct from the verifier's diagnostic-completeness obligation.

Resolves the §5.2/§5.5 register tension flagged in the RFC 2119 audit P3-1. §5.2 requires agents to short-circuit on the first environment.* failure (agent-phase, fail-closed). §5.5 Block 3 requires verifiers to evaluate every environment.* constraint to completion (verifier-phase, diagnostic-completeness). On their face these read as contradictory; the bridge sentence makes the phase distinction load-bearing and removes the apparent conflict without changing either rule.

Wording refined on PR agent-intent#9 with Douglas Borthwick:

- Option A venue: bridge sentence placed in §5.5 Block 3, immediately after the verifier-side completeness sentence, rather than in §5.2 or as a free-standing block. Keeps the disambiguation co-located with the rule it disambiguates.

- Precision rewrite: permits → requires (§5.2 short-circuit is normative agent obligation, not optional optimisation); self-gating optimization → fail-closed agent-side halt (correctly characterises the agent-phase halt as a safety property, not a performance choice). Douglas eyeball-acked the precision rewrite on PR agent-intent#9.

PR agent-intent#22 v0.5.3 mirror by Douglas will add the §5.2 short-circuit body sentence plus the same §5.5 Block 3 bridge in lockstep, so the family lands the resolution identically across both type specifications.

Document header stays at 0.5-draft; v0.5.3 is a patch-level refinement per the convention established in 7b97827. No algorithm changes; no security-model changes; no Headless Oracle code changes required.

Co-Authored-By: Douglas Borthwick <256362537+douglasborthwick-crypto@users.noreply.github.com>
@LembaGang

Copy link
Copy Markdown
Author

Douglas —

v0.5.3 shipped on #9 as commit 85c6594. +2/-1 on spec/external-state-attestation.md.

Precision rewrite adopted verbatim — "permits... self-gating optimization" → "requires... fail-closed agent-side halt." You were right that the MAY-register read would hit a skimmer even with the cross-reference carrying the normative weight downstream; better to match §5.2's register byte-for-byte in the bridge itself.

§5.5 Block 3 now reads: completeness obligation → bridge sentence naming the phase distinction → violations-list rule. The bridge sits co-located with the rule it disambiguates rather than free-standing, per Option A venue.

Ball to you for #22 v0.5.3 in lockstep — §5.2 body addition (short-circuit clause verbatim from #9's §5.2) + same §5.5 bridge. The "inherited 1:1" rationale note on #22's §5.2 stays in place, now truthful about body content rather than rationale-only.

Cross-chain temporal consistency still yours next after v0.5.3 mirror lands.

douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request May 12, 2026
… disambiguation (v0.3.1)

Mirrors PR agent-intent#9 v0.3 §5.5 Family Composition (commit 7a8987c,
environment-market-state) into environment-wallet-state.md. Two
refinements surfaced in PR agent-intent#22 discussion folded into §5.5.

Gap 1 (completeness rule): verifiers MUST evaluate every environment.*
constraint in the mandate to completion before refusing Layer 3 — even
after the first failure has been observed. Short-circuit evaluation of
environment.* constraints is non-conforming. Transactional-constraint
evaluation (mandate.*, payment.*) after a confirmed environment.*
failure remains implementation-defined. Composes with §5.2 ordering —
environment-before-transactional stays; completeness layers on top.

Gap 2 (per-member disambiguation): every violation entry MUST carry two
identifiers — the array index of the constraint in constraints[] as the
primary machine id, and a human-readable id derived from the
constraint's distinguishing field. Selection of the distinguishing
field is a per-type obligation analogous to per-type algorithm
declaration in §4.7. For environment.wallet_state the distinguishing
field is subject_wallet (REQUIRED per §4 schema, always present, no
fallback needed). Driving case: multiple wallet-state constraints in a
single mandate with different subject_wallet values (e.g., settlement
wallet + gas wallet).

Rationale now presents semantic and architectural arguments as
co-equal — conjunction as a family membership criterion, not a per-type
design decision. Any environment.* type whose failure mode is
OR-tolerable is outside the family's design charter.

No changes elsewhere in the spec; §4.1, §4.5, §4.7, §5.2, §6.*, §7.*
untouched. No InsumerAPI-side code changes required.

Co-Authored-By: LembaGang <127877551+LembaGang@users.noreply.github.com>
douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request May 12, 2026
Coordinated v0.4 release with PR agent-intent#9 environment.market_state as a
single-commit-on-both-specs bundle per LembaGang's (b) proposal
accepted in PR agent-intent#22 comment 4274334595 and locked at comment 4274435668.
LembaGang lifts §6.8 onto PR agent-intent#9 v0.4 after this lands, same lockstep
pattern as §5.5.

Audit-parity port from PR agent-intent#9 v0.3.2 (commit 57fd7b6, LembaGang):

(1) max_attestation_age strictness — removed absent-case default of 300
    seconds from:
    - §4 schema row: "default of 300" + "SHOULD always include"
      softener replaced with explicit MUST-include + MUST-reject-if-
      missing.
    - §4 Field Constraints bullet: "when absent... default of 300"
      replaced with malformed-rejection + no-default declaration +
      §4.6 security rationale.
    - §4.2 pseudocode Step 1: added absent-check before range check.
    - §7.6 JS reference: removed destructuring default; added
      undefined-check throw.
    - §7.7 Python reference: removed .get() default; added membership-
      check + ValueError.

    Missing max_attestation_age is now uniformly malformed; verifiers
    MUST reject per §4.2 Step 1. Closes the v0.2 REQUIRED-elevation-
    with-retained-default contradiction.

(2) §6.5 Constraint Stripping — added normative sentences requiring
    verifiers to reject mandates whose Layer 2 signature does not
    validate over the full constraint list, and prohibiting acceptance
    of subset-signed mandates. Closes the zero-normative-keyword gap
    identified by LembaGang's RFC 2119 audit.

Three consumer-policy additions (Doug's Apr 18 17:42 proposal comment
4274241447, LembaGang-approved in comment 4274435668):

(3) stale_cache_fallback_permitted OPTIONAL boolean field (default
    false):
    - §4 schema row added (OPTIONAL per LembaGang (i) at 4274435668;
      default-false; payment-execution MUST NOT set true).
    - §4 Field Constraints bullet with boolean-type hygiene clause:
      "if present, MUST be a strict boolean. Non-boolean values
      (including string "false", null, or numeric) MUST be rejected
      as malformed per §4.2 Step 1."
    - §4.2 pseudocode Step 1 type-check.
    - §6.8 "Fail-closed on fetch failure" paragraph: stale-cache
      sentences replaced with field-driven text (MAY use expired cache
      when true, MUST produce violation when false/absent, payment-
      execution MUST NOT set true).

    Shape follows the v0.3.2 rule-narrowing: REQUIRED remains the right
    pattern where no nontrivial default is safe across deployment
    classes (max_attestation_age); OPTIONAL-with-default is the right
    pattern where a single default is correct for almost all
    deployments (stale_cache_fallback_permitted). Parallel-construction
    Field Constraints bullet matches the max_attestation_age pattern.

(4) §6.8 grace-window discoverability: issuers SHOULD publish
    rotation-start and grace-window-end timestamps through an auditable
    channel. Channel MAY be out-of-band (release notes, status page,
    signed rotation announcement) or in-band via a JWKS top-level
    metadata field (e.g., rotation_announcement with
    rotation_started_at / previous_kid / new_kid / grace_window_end).
    SHOULD is on discoverability, not form. Future revision may elevate
    to REQUIRED if the WG converges on a canonical in-band mechanism.

(5) §6.3 JWKS URL migration paragraph: trusted_jwks URL change is a
    new-mandate event by design. Migration path: issuer publishes a
    new JWKS at the new URL; mandate issuers emit new mandates
    targeting the new URL; existing mandates expire naturally via
    exp. Deliberate cost/benefit: trust root cannot be silently
    relocated, at the cost of non-free URL migration.

(6) SHALL→MUST normalization NOT NEEDED: post-audit verification on
    both specs shows all SHALL references sit in the RFC 2119
    Notational Conventions boilerplate (line 67 on agent-intent#22, line 66 on
    agent-intent#9); zero substantive usage elsewhere. LembaGang's P3 finding
    withdrawn on PR agent-intent#9, symmetric on agent-intent#22.

§9 changelog: v0.4-draft row added above v0.3.1-draft.

No architectural changes. No family-wide changes. No InsumerAPI-side
code changes required. Co-drafted with LembaGang (Headless Oracle)
over PRs agent-intent#9 and agent-intent#22.

Co-Authored-By: LembaGang <127877551+LembaGang@users.noreply.github.com>
douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request May 12, 2026
…my with populated wallet_state field table

Mirrors PR agent-intent#9 v0.5.1-draft (commit 7b97827, LembaGang, Headless Oracle)
into environment.wallet_state §4.8. Closes the v0.5 round on this spec
per LembaGang's comment 4276111822: "You commit v0.5 §4.8 on PR agent-intent#22:
field table per the Note on family coordination, with
required_condition_hashes and attestation_request_body under
per-type-evaluation-mechanism-bound." Single v0.5-draft commit on the
wallet_state side; document header bumped 0.2-draft to 0.5-draft
(capturing v0.3 / v0.3.1 / v0.4 header omissions).

Three scope categories ported verbatim from 7b97827 as family-wide
prose:

- family-wide-trust-root-agnostic — identical semantics across every
  environment.* constraint type.
- per-type-trust-root-mechanism-bound — semantics bound to the specific
  trust-root mechanism (RFC 7517 JWKS here; RFC 8615 key registry on
  environment.market_state).
- per-type-evaluation-mechanism-bound — semantics bound to the type's
  evaluation-mechanism output shape or wire-protocol binding to the
  evaluator.

Field table populated for current environment.wallet_state fields:

- max_attestation_age               family-wide-trust-root-agnostic  (§4.6)
- trusted_jwks                      per-type-trust-root-mechanism-bound  (§6.3)
- stale_cache_fallback_permitted    per-type-trust-root-mechanism-bound  (§6.8)
- subject_wallet                    per-type-evaluation-mechanism-bound  (§5.5)
- required_condition_hashes         per-type-evaluation-mechanism-bound  (§4.1)
- attestation_request_body          per-type-evaluation-mechanism-bound  (§4.1)

Rationale for subject_wallet placement under
per-type-evaluation-mechanism-bound: the swap test is the load-bearing
argument. Replace ES256+JWKS with an Ed25519 scheme that binds wallets
through a different mechanism, and subject_wallet still does the §5.5
per-member disambiguation job against whatever the new format calls
the wallet identifier. The sub: <wallet> binding lives in the
attestation payload — the issuer's trust-root-specific claim that the
signed attestation is about this wallet — not in the constraint field.
subject_wallet as a constraint field is the verifier-side matching
slot: it names which wallet the attestation must prove pass for. That
matching function survives any trust-root mechanism swap. The
counter-case (trust-root-bound via JWT sub to wallet) collapses under
the swap test: the binding lives in the attestation, not in the
constraint's subject_wallet slot.

Rule for future fields and Relationship to §4.6/§4.7 ported verbatim
from 7b97827 as family-wide prose. Note on family coordination is
reciprocal, pointing at PR agent-intent#9 commit 7b97827 per the §5.5 precedent
(PR agent-intent#22 commit 7848bc2 points at PR agent-intent#9 commit 7a8987c).

No algorithm changes; no security-model changes; no §6.* changes; no
§7.* changes; no InsumerAPI-side code changes required.

Co-Authored-By: LembaGang <127877551+LembaGang@users.noreply.github.com>
douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request May 12, 2026
…nale entries

Closes the §4.8 field-table coverage asymmetry flagged by LembaGang in
comment 4276249269 (6/9 wallet_state constraint fields declared at v0.5;
missing attestation_url, expected_kid, expected_issuer). Path (1)
selected over narrowing the §4.8 preamble's universal quantifier per
Doug's comment 4276295574 and LembaGang's green-light in comment
4276315303.

Three table rows added to §4.8:

- attestation_url            family-wide-trust-root-agnostic     (§4.1)
- expected_kid               per-type-trust-root-mechanism-bound (§6.3)
- expected_issuer            per-type-trust-root-mechanism-bound (§6.3)

Three rationale entries integrated into the §4.8 post-table paragraph
in category order. The attestation_url entry is a three-sentence defense
block pre-empting the §4.8-internal question of why the URL is
family-wide when attestation_request_body (which targets the same URL)
is per-type-evaluation-mechanism-bound: the placement lands on the same
basis as max_attestation_age in §4.6 — identical semantic role across
types, with per-type variance localised at neighbouring fields (HTTP
verb, request-body shape). expected_kid and expected_issuer are
one-sentence entries semicolon-joined with their market_state sibling
notes, classified on JOSE-signing-stack specificity: both are JWT
header/claim bindings parallel-but-mechanism-specific on
environment.market_state, which uses an RFC 8615 key registry
(oracle_public_key_id) and derives issuer identity from the attestation
payload rather than from a constraint-level JOSE iss binding.

Document header stays at 0.5-draft — patch-level refinement, not a new
minor version (matches LembaGang's convention on commit 7b97827 where
PR agent-intent#9 shipped v0.5.1-draft with header unchanged).

No schema changes; no algorithm changes; no security-model changes; no
changes outside §4.8; no InsumerAPI-side code changes required.
LembaGang to mirror onto PR agent-intent#9 as v0.5.2-draft with attestation_url
(family-wide-trust-root-agnostic), oracle_public_key_id
(per-type-trust-root-mechanism-bound), and expected_status
(per-type-evaluation-mechanism-bound — status-enum analog to
required_condition_hashes) per comment 4276315303.

Co-Authored-By: LembaGang <127877551+LembaGang@users.noreply.github.com>
douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request May 12, 2026
…p mirror of PR agent-intent#9 v0.5.3

Mirrors PR agent-intent#9 v0.5.3 (commit 85c6594, LembaGang, Headless Oracle) onto
environment.wallet_state.

Two touch points:

- §5.2 body gains the short-circuit sentence verbatim from PR agent-intent#9 §5.2:
  "If any `environment.*` constraint fails, the agent MUST NOT evaluate
  remaining constraints and MUST NOT proceed to L3 creation."
  Brings §5.2 body to parity with agent-intent#9. The pre-existing "inherited 1:1
  from §5.2 of environment.market_state" rationale note is now truthful
  about body content, not only rationale.

- §5.5 Block 3 gains the family-wide bridge sentence verbatim from PR agent-intent#9
  §5.5 Block 3 at 85c6594:
  "The completeness requirement applies to the verifier-side L3-acceptance
  evaluation path; agent-side pre-L3-creation evaluation is governed by
  §5.2's short-circuit clause, which requires agents to stop at the first
  `environment.*` failure as a fail-closed agent-side halt distinct from
  the verifier's diagnostic-completeness obligation."

Resolves the §5.2/§5.5 register tension flagged in PR agent-intent#9's RFC 2119 audit
P3-1. §5.2 binds agents at pre-L3-creation (short-circuit, fail-closed).
§5.5 binds verifiers at L3-acceptance (completeness, diagnostic). Both
rules stand; the bridge sentence makes the phase distinction explicit so
neither reads as contradicting the other.

Venue Option A (§5.5 Block 3 placement). Precision rewrite adopted verbatim
per the precision flag posted on PR agent-intent#9 (permits → requires, self-gating
optimization → fail-closed agent-side halt).

Document header stays at 0.5-draft; v0.5.3 is a patch-level refinement per
the convention established in 7b97827. No algorithm changes; no security-
model changes; no InsumerAPI-side code changes required.

Queued for v0.5.4 per LembaGang's observation on comment 4279340548: §5.2
forward-pointer to §5.5 Block 3 for MCP/section-isolation retrieval paths;
plus PR agent-intent#9 P3-2 (§2.3 descriptive/normative register) and P3-3 (§2.4
RECOMMENDED/SHOULD redundancy) — both agent-intent#9-local.

Co-Authored-By: LembaGang <127877551+LembaGang@users.noreply.github.com>
douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request May 12, 2026
…preamble clarification + §4.8 rows + §6.9 new section

Closes the third and final held-back item from LembaGang's Apr 16 review
(first: §5.5 family composition, shipped v0.3/v0.3.1; second: §6.8 JWKS
caching + §6.5 constraint stripping + stale_cache, shipped v0.4; third:
cross-chain temporal consistency, this commit).

Scope locked with LembaGang on Apr 19 (comment 4276613295: three-scenario
walk-through of market_state's temporal surface confirmed no cross-venue
skew distinct from per-attestation freshness; Option 1 wallet_state-local
placement ratified). Apr 20 ratification (comment 4279340548) confirmed
boundary framing reads clean and §4.8 taxonomy extension to JWT claims
accepted.

Five touchpoints:

(1) §4 schema — two new OPTIONAL fields: finality_depth (positive
integer, minimum block confirmations past attested block; mandate-
issuer-declared) and max_cross_chain_skew_seconds (positive integer,
maximum tolerated wall-clock divergence across chain-tip timestamps for
multi-chain mandates). Companion Field Constraints bullets matching the
stale_cache_fallback_permitted malformedness pattern.

(2) §4.1 unchanged. The v0.2 provider-neutrality contract (7 REQUIRED
core claims + results/blockNumber/blockTimestamp OPTIONAL for second-
conformant-implementation portability across non-EVM chains) is
preserved; no elevation of blockTimestamp to REQUIRED.

(3) §4.8 preamble one-sentence inline clarification placed between the
three scope-category bullets and the "Scope declarations..." header:
"Within §4.8, 'field' encompasses both constraint schema fields declared
in §4 and, where operationally relevant, JWT claims declared in §4.1."
Preserves verbatim cross-spec byte-identity of the preamble sentence and
the three category bullets with PR agent-intent#9 §4.8 at 85c6594.

(4) §4.8 field table + rationale — three new rows under per-type-
evaluation-mechanism-bound: blockTimestamp (references existing §4.1
OPTIONAL JWT claim), finality_depth (references new §4 constraint
field), max_cross_chain_skew_seconds (references new §4 constraint
field). Rationale paragraph extended with three trailing semicolon-
joined sentences in category order paralleling the v0.5.1/v0.5.2
structure; blockTimestamp's rationale inlines a sibling-no-analog
clarification pre-empting the WG-reviewer question of why
environment.market_state has no corresponding entry.

(5) §6.9 Cross-Chain Temporal Consistency — new security-considerations
section between §6.8 JWKS caching/rotation and §7 Reference
Implementation. Six blocks:
  - §6.7 adjacency opening: verifier↔issuer wall-clock skew vs
    attested-block↔chain-tip skew — adjacent but distinct.
  - Orthogonal-axes boundary sentence: pre-acceptance×cross-chain via
    max_cross_chain_skew_seconds vs post-acceptance×within-chain via
    reorg advisory SHOULD.
  - Finality-depth measurement: confirmation depth is derived from the
    verifier's independent chain read at verification time; no
    additional JWT claim required from issuer, preserving the v0.2
    provider-neutrality contract on §4.1.
  - Reorg remediation (advisory): verifier-bound SHOULD on re-verification
    at settlement time; explicitly not a synchronous chain-finality
    mandate (would overconstrain verifier implementations).
  - Measurement basis for max_cross_chain_skew_seconds: verifier MUST
    measure skew across the mandate's environment.* attestations using
    blockTimestamp when present, falling back to iat; skew computed in
    Unix seconds with explicit canonicalization (ISO 8601 blockTimestamp
    values per §4.1 MUST be converted to integer Unix seconds, truncating
    sub-second precision, before comparison); issuer SHOULD include
    blockTimestamp on chains with a block-time anchor, MAY omit on chains
    without (non-EVM chains; iat governs cross-chain skew measurement
    and max_attestation_age bounds per-attestation freshness in that
    case).
  - Placement rationale: §4.8 forward rule against speculative family-
    wide §4.9 proliferation. market_state has no cross-venue temporal
    concern distinct from per-attestation freshness (three-scenario
    walk-through confirmed Apr 19). Future WG elevation path to §4.9
    preserved.

Document header bumps 0.5-draft → 0.6-draft; new-section-level surface
matches the v0.5 §4.8-addition precedent for minor-version release
discipline.

Queued for v0.5.4 (LembaGang's Apr 20 observation on comment 4279340548):
§5.2 forward-pointer to §5.5 Block 3 for MCP/section-isolation retrieval
paths; plus PR agent-intent#9 P3-2 (§2.3 descriptive/normative register) and P3-3
(§2.4 RECOMMENDED/SHOULD redundancy) — both agent-intent#9-local.

No algorithm changes; no security-model changes beyond §6.9 additions;
no InsumerAPI-side code changes required.

Co-Authored-By: LembaGang <127877551+LembaGang@users.noreply.github.com>
douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request May 12, 2026
…f PR agent-intent#9 01490df

Mirrors PR agent-intent#9 v0.5.5-draft Appendix C (commit 01490df, LembaGang, Headless
Oracle) per LembaGang's Apr 21 22:37 UTC converge signal on PR agent-intent#9 comment
4292298210. Six sections at C.1 through C.6:

- C.1 Purpose — anchors in v0.5.4 §2.3/§2.5 and v0.6.1 §6.9 as concrete drivers
- C.2 Normative vs. descriptive register — definitions + v0.5.4 §2.3 worked example
- C.3 Rules for the environment.* family (five rules: RFC 2119 keywords in
  normative register, lowercase synonyms in descriptive register, redundancy
  avoidance, application-layer vs. transport-layer scope, forward rule for
  new sections)
- C.4 Open questions for working group (Q1 informative-vs-normative
  classification, Q2 audit cadence, Q3 scope over time)
- C.5 Current instances — catalog deferred to a future revision
- C.6 Relationship to §1 Notational Conventions

Letter alignment C-to-C confirmed, no offset (Appendix A Attestation Test
Vectors + Appendix B Failure Mode Quick Reference + Appendix C Register
Discipline on both sides).

Two localisation surfaces; C.2 through C.6 byte-identical to PR agent-intent#9 01490df:

(1) C.1 prose flip — `environment.market_state` attached to (PR agent-intent#9) and
    `environment.wallet_state` attached to (this specification). Trailing
    "§2.3/§2.5 on agent-intent#9, §6.9 on agent-intent#22" PR-history refs verbatim.

(2) Coordination Note-block rewrite — resolves the "pending confirmation of
    current appendix count on PR agent-intent#22" caveat (confirmed in LembaGang's 22:37
    converge signal) and flips port direction from drafted-for to mirrored-from,
    naming commit 01490df as source.

Douglas's four dispositions on PR agent-intent#9 comment 4292173322 all landed as-drafted
per LembaGang's converge signal: (a) self-reference tension — MUSTs at
C.3.1/C.3.4/C.3.5 kept, preamble does the binding-scope work; Q1
informative-with-normative-cross-references; Q2 deferred to WG with mild
preference for continued ad-hoc cadence (forward-scoped if formalised, no
retroactive burden); Q3 kept open as drafted with four properties verbatim
(provider neutrality, peer-author coordination discipline, patch-level
versioning conventions, lockstep commit patterns).

Document header stays at 0.6-draft per patch-level convention established at
v0.5.1 and reaffirmed at v0.5.3 / v0.6.1; v0.6.2 is a patch-level refinement.

No algorithm changes; no security-model changes; no InsumerAPI-side code
changes required.

Co-Authored-By: LembaGang <127877551+LembaGang@users.noreply.github.com>
douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request May 12, 2026
…SDT alignment

Adds Appendix D listing the running-code implementations of the
environment.* family, per RFC 6982. Aligns §7.1 + §7.4 prose with
production /v1/keys/buy payment-method enumeration.

Scope of this revision:

- Appendix D.1 records InsumerAPI as the running implementation of
  environment.wallet_state. Lean RFC 6982 status table (License,
  endpoints, signing algorithm, kid, JWT TTL, coverage, agent-native
  key provisioning, reference verifiers); conformance pointer set
  for §4.1 / §4.2 / §4.6 / §4.7 / §4.8 / §5.5 / §6.5 / §6.8 / §6.9;
  pointer to §7 for full reference-implementation prose rather than
  duplicating.
- Appendix D.2 records Headless Oracle as the running implementation
  of the sibling environment.market_state constraint type per PR agent-intent#9.
  Listed for environment.* family completeness; canonical
  Implementation Status appendix for environment.market_state
  belongs in PR agent-intent#9 (editor's call on Michael Msebenzi / LembaGang's
  side).
- Appendix D.3 disclaimer states that listing is not endorsement and
  verifiers MUST independently verify per §4.2 regardless of
  Appendix D listing.
- §7.1 + §7.4 source-of-truth alignment: POST /v1/keys/buy payment
  methods updated from "USDC or BTC" / "USDC (or BTC)" to
  "USDC, USDT, or BTC" matching production behavior (openapi.yaml
  PaymentChainId enumeration). §7.4 prose around agent-key-bootstrap
  rationale generalised from "the authority to spend USDC" to
  "on-chain spending authority" — drops the canonical-token
  enumeration mismatch with §7.4 endpoint enumeration above it
  without losing the rhetorical argument.
- §9 Changelog: v0.6.4-draft row added at the top of the table.

Per RFC 6982 §2, Appendix D is intended to be removed by the RFC
Editor before any final standards-track publication; the GitHub
history of this Internet-Draft retains it permanently as evidence
of priority.

Document header stays at 0.6-draft; v0.6.4 is a patch-level
refinement adding an informative appendix and aligning §7 prose
with production. No algorithm changes, no security-model changes,
no §4 schema changes, no InsumerAPI-side code changes required.

Sibling-mirror coordination: independent of the parallel Appendix D
landing on the environment.market_state side per LembaGang's
LembaGang/verifiable-intent commit 21a156c anchor ("a parallel
Appendix D on PR agent-intent#22 is the editor's call on the
environment.wallet_state side and is expected to land independently
on Douglas Borthwick's timing"). Sole-authored, mirroring the v0.6.3
propagation discipline — no Co-Authored-By trailers.
douglasborthwick-crypto added a commit to douglasborthwick-crypto/verifiable-intent that referenced this pull request May 12, 2026
…-type)

Adds family-wide algorithm-deprecation prose mirroring
draft-borthwick-msebenzi-environment-state-00 v0.2-draft §4.3 family-wide
SHOULD ("Type specification authors SHOULD specify, in the type's
specification, a deprecation mechanism for the type's MUST-implement
algorithm before that algorithm is needed").

Adds per-type deprecation mechanism for environment.wallet_state:
conditions (NIST/IETF JOSE/RFC 8725 update or cryptographic break),
timeline (12-month verifier-migration window from minor-version revision
publication), backward-compatibility (parallel verification during window;
mandate issuer migration on JWKS readiness).

Updates §4.7 PR agent-intent#9 coordination Note to reflect PR agent-intent#9 §4.7 as the
verbatim-portable target (PR agent-intent#9's algorithm-agility section sits at §4.7);
family-wide prose remains verbatim-portable; deprecation mechanism block
joins table rows in the per-type-swap surface.

Co-Authored-By: LembaGang <127877551+LembaGang@users.noreply.github.com>
Michael Msebenzi and others added 18 commits May 31, 2026 15:40
…ecution

Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
…hm agility, impl alignment

Addresses coordination with PR agent-intent#22 (Douglas Borthwick, InsumerAPI).

Four structural changes:

1. Namespace framing: new §2.3 documents sibling relationship to
   environment.wallet_state. Abstract, §2.1, §2.2 updated to reflect
   environment.* family. §5.2 execution-order rationale generalized.

2. Attestation freshness: max_age_seconds renamed to max_attestation_age
   for lockstep alignment with agent-intent#22 §4.6. Elevated to REQUIRED with
   normative default of 60. New §4.6 documents TOCTOU rationale using
   market-execution precedents (2010 Flash Crash, circuit breaker races,
   2020 WTI crude oil futures) and family-wide semantics.

3. Algorithm agility: New §4.7 lifted from agent-intent#22 §4.7 with Ed25519 as
   MUST-implement, ES256/Ed448/ES384/ES512 as extension set. RFC 8725
   §3.1 hook. Per-type MUST-implement + SHOULD/MAY, fail-closed
   negotiation not silent downgrade.

4. Spec-implementation alignment: conformance-tested spec against
   deployed reference implementation before committing. Three
   pre-existing misalignments fixed: attestation field key_id ->
   public_key_id (matches deployed receipt shape), registry lookup
   k.id -> k.key_id (matches deployed /.well-known/oracle-keys.json),
   new envelope clause in §4.1 disambiguating unsigned wrapper fields
   (discovery_url, extensions, nested receipt) from the signed
   attestation subset. Zero Worker changes.

§4.5 expanded with joint environment.market_state +
environment.wallet_state composition example. §6.3 notes complementary
JWKS pattern from agent-intent#22 §6.3. §8 Q2 references agent-intent#22 §6.3; §8 Q6 added on
family-wide subject binding (mirrors agent-intent#22 §8 Q5). Lifecycle sections
renumbered (§2.3 -> §2.4, §2.4 -> §2.5).

Appendix A test vector and Appendix B failure table updated for field
name alignment. §7.2 and §7.3 reference implementations updated.

No changes to verification algorithm, fail-closed semantics, or security
model. Zero Headless Oracle code changes required.

Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
Adds §5.5 Family Composition in response to the held-back follow-ups
from PR agent-intent#22 v0.2 review (conjunction semantics, L3 gate, per-member
diagnostic output). Co-drafted with Douglas Borthwick (InsumerAPI) over
PRs agent-intent#9 and agent-intent#22; mirrors PR agent-intent#22 §5.5 (commit 85cfaa0) with two
refinements agreed in PR agent-intent#22 discussion:

- Gap 1 (L3 gate timing): verifiers MUST evaluate every environment.*
  constraint to completion before refusing Layer 3; short-circuit
  evaluation is non-conforming. Composes with §5.2 ordering.

- Gap 2 (per-member disambiguation): every violation entry carries
  both an array-index machine identifier and a per-type human-readable
  identifier (MIC for market_state, subject_wallet for wallet_state).
  The §4.5 multi-exchange example (XNYS + XLON) is the driving case.

Rationale presents semantic ("independent questions compose as AND")
and architectural ("failure mode must be gating, or the type isn't in
the family") arguments as co-equal — conjunction as a family
membership criterion, not a per-type design decision. Load-bearing for
future environment.* types (regulatory_status, counterparty_credit).

Drafted as standalone block adoptable verbatim in environment.wallet_state
§5.5 with the per-type distinguishing-field row swapped. Same pattern
as §4.7 — one family-wide question, one answer, two specs.

No changes elsewhere in the spec; no verification algorithm, fail-closed,
or security-model changes; no Headless Oracle code changes required.

Co-Authored-By: Douglas Borthwick <douglasborthwick-crypto@users.noreply.github.com>
Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
…§6.5 normative fix

Resolves P1 inconsistency from v0.2: the max_attestation_age field was
declared REQUIRED in the §4 schema row but retained an absent-case default
of 60 seconds from its OPTIONAL v0.1 origins. These are mutually exclusive
— a REQUIRED field cannot have deterministic absent-case behaviour. The
retained default silently restored the exploitable TOCTOU surface that
§4.6 was introduced to close.

Fix (Path b — strict REQUIRED):
- §4 schema row: removed the "backwards compatibility with v0.1 default
  of 60" clause and the "SHOULD always include" softener; replaced with
  explicit MUST-include + MUST-reject-if-missing.
- §4 Field Constraints bullet: replaced "when absent... default of 60
  seconds" with malformed-rejection + no-default declaration + §4.6
  security rationale.
- §4.2 pseudocode Step 1: added absent-check before value-range check.
- §7.2 JS reference: removed destructuring default; added undefined-
  check throw.
- §7.3 Python reference: removed .get() default; added membership-check
  + ValueError.

§6.5 Constraint Stripping: added normative sentence requiring verifiers
to reject mandates whose L2 signature does not validate over the full
constraint list, and prohibiting acceptance of subset-signed mandates.
Closes the zero-normative-keyword gap identified in RFC 2119 audit pass.

§9 changelog: v0.3.2-draft row added above v0.3-draft.

No architectural changes. No family-wide changes. No Headless Oracle
code changes required. No changes to §4.1, §4.6, §4.7, §5.5, or any
family-shared section.

Co-Authored-By: Douglas Borthwick <256362537+douglasborthwick-crypto@users.noreply.github.com>
Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
…back_permitted

Lifts the family-wide additions shipped by Douglas in PR agent-intent#22 bb7af90 with
terminology adaptation for market_state's key-discovery architecture.

Additions:
- New §6.8 Key Registry Caching and Key Rotation: lifted from bb7af90's
  §6.8 JWKS Caching and Key Rotation with systematic terminology swaps
  (JWKS → RFC 8615 key registry, kid → key_id, trusted_jwks → issuer-
  derived oracle key registry URL). All MUST/SHOULD/MAY keywords and
  paragraph ordering preserved verbatim. Includes grace-window SHOULD
  paragraph with rotation_announcement metadata example adapted to
  market_state's key registry shape.
- stale_cache_fallback_permitted OPTIONAL boolean field (§4 schema row,
  §4 Field Constraints bullet with "If present MUST be boolean" hygiene
  clause per Douglas's v0.4 addition, §4.2 Step 1 type-check, §6.8
  companion paragraph). Default false; payment-execution MUST NOT set
  true.

Intentional asymmetry — not lifted:
- §6.3 JWKS URL migration paragraph from bb7af90. wallet_state's
  trusted_jwks is a signed L2 constraint field (user-signed); market_
  state's registry URL is derived from the oracle's issuer field
  (oracle-signed). The underlying property Douglas's paragraph addresses
  — trust-root URL as rigid mandate binding — does not exist in
  market_state. This asymmetry is pre-existing and already documented
  in §6.3's JWKS/RFC-8615 coexistence paragraph. The coordination work
  this week treated §6.3 as family-symmetric; the spec itself says
  otherwise. Formalizing trust-root-binding as an explicit family-
  charter dimension queued for v0.5.

Scope of family-wide claims:
- §4.6 family-wide framing continues to cover max_attestation_age only.
- stale_cache_fallback_permitted is scoped per-type with parallel
  semantics to PR agent-intent#22's version. Field governs stale-cache fallback on
  the trust-root mechanism the constraint uses; the mechanism differs
  between types, so the field's operational scope is per-type.

Changelog: 0.4-draft row added above 0.3.2-draft.

Co-Authored-By: Douglas Borthwick <256362537+douglasborthwick-crypto@users.noreply.github.com>
Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
…isation

Adds §4.8 Field Scope Declaration between §4.7 and §5, formalising the
field-scope distinction already implicit in §4.6 (max_attestation_age as
family-wide) and §4.7 (per-type MUST-implement algorithms with family-wide
agility framework). Declares two scope categories for the environment.*
constraint family:

- family-wide-trust-root-agnostic: field semantics independent of trust-root
  mechanism. max_attestation_age is the current instance (§4.6).
- per-type-trust-root-mechanism-bound: field operational semantics depend on
  the type's trust-root mechanism (JWKS for wallet_state, RFC 8615 key
  registry for market_state). stale_cache_fallback_permitted is the current
  instance (§6.8).

Sets forward discipline: all new environment.* fields introduced in future
revisions MUST declare scope category at introduction. Additions of new
scope categories beyond the two currently recognised are working-group
revisions.

Preserves §4.6 normative text unchanged — §4.8 formalises the discipline
§4.6 already uses for max_attestation_age, rather than re-scoping §4.6's
existing text. Cross-references §4.6 and §4.7 explicitly.

Also retroactively bumps document header from 0.3-draft to 0.5-draft,
capturing the v0.4 commit's omission of the header update. The body of the
spec and the §9 changelog already carry correct v0.4 content as of 53ea1c6;
only the top-of-file version marker lagged. Fixing in this commit rather
than as a separate hotfix keeps the PR history clean.

Drafted as standalone block adoptable verbatim in environment.wallet_state
§4.8 with field-table rows swapped for per-type fields (trusted_jwks,
subject_wallet, and stale_cache_fallback_permitted under its JWKS-specific
mechanism). Same pattern as §4.6, §4.7, §5.5, §6.8.

Closes v0.5 scope queued in v0.4 changelog. No algorithm changes; no
security-model changes; no Headless Oracle code changes required.

Co-Authored-By: Douglas Borthwick <256362537+douglasborthwick-crypto@users.noreply.github.com>
Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
…chanism-bound

Adds a third scope category to §4.8 in response to the taxonomy gap Douglas
Borthwick surfaced on PR agent-intent#22's v0.5 mirror: wallet_state fields
`required_condition_hashes` and `attestation_request_body` are per-type
scope but not bound by trust-root mechanism — their binding is to the
constraint type's evaluation mechanism (output shape or wire-protocol).

Three scope categories now recognised:

- family-wide-trust-root-agnostic (max_attestation_age)
- per-type-trust-root-mechanism-bound (stale_cache_fallback_permitted)
- per-type-evaluation-mechanism-bound (empty at v0.5.1; no market_state
  fields placed there; declaration only)

The new category preserves the -mechanism-bound suffix, keeping the
taxonomic level parallel to the existing per-type category (trust-root
mechanism vs. evaluation mechanism). Umbrella covers both the evaluator's
output shape (condition-hash sets vs. status enum) and the wire-protocol
binding to the evaluator (request body shape).

Preamble ("recognises three scope categories") and forward rule ("beyond
the three currently recognised") updated for consistency. The SHOULD
clause on placement under existing categories holds: the clause guards
against speculative proliferation, not evidence-based category addition
when two fields on a sibling spec clearly belong outside the two existing
categories.

Charter declaration is family-wide; field-table population for
environment.wallet_state sits with PR agent-intent#22's v0.5 mirror. Same standalone-
block pattern as §5.5 / §6.8 — one family-wide question, one answer, two
specs; PR agent-intent#9 leads the taxonomy, PR agent-intent#22 mirrors with populated field rows.

v0.5.1 is a patch-level refinement of v0.5. No header bump — the
document-level version marker stays at 0.5-draft; the v0.5.1 row in §9
records the taxonomy change. Forward rule holds: further scope categories
beyond these three are working-group revisions.

No algorithm changes; no security-model changes; no Headless Oracle code
changes required.

Co-Authored-By: Douglas Borthwick <256362537+douglasborthwick-crypto@users.noreply.github.com>
Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
Adds three rows to the §4.8 field table covering remaining environment.market_state constraint fields, extends the post-table rationale paragraph with three new sentences, and reorganises the table to group by scope category matching PR agent-intent#22 v0.5 layout.

Field rows added:

- attestation_url (family-wide-trust-root-agnostic, §4.1)

- oracle_public_key_id (per-type-trust-root-mechanism-bound, §6.3)

- expected_status (per-type-evaluation-mechanism-bound, §4.1)

Rationale sentences added, one per new field, paralleling the existing max_attestation_age and stale_cache_fallback_permitted entries. The attestation_url rationale pre-empts the WG-reviewer question of why the URL field is family-wide while attestation_request_body on the sibling specification is per-type-evaluation-mechanism-bound: the semantic role of the URL field is identical across types, per-type variance is localised at neighbouring wire-protocol fields (per-type §4.1 interface + attestation_request_body on environment.wallet_state), placement basis identical to max_attestation_age in §4.6.

Responds to PR agent-intent#22 review thread flagging preamble-table asymmetry: §4.8's preamble requires every field in the family to declare its scope, but the v0.5 / v0.5.1 tables declared scope for a subset only. v0.5.2 closes the gap on the environment.market_state side. Parallel to PR agent-intent#22 v0.5.1 at commit 4effcb8.

Document header stays at 0.5-draft; v0.5.2 is a patch-level refinement. No algorithm changes; no security-model changes; no Headless Oracle code changes required.

Co-Authored-By: Douglas Borthwick <256362537+douglasborthwick-crypto@users.noreply.github.com>
Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
Inserts a single bridge sentence into §5.5 Block 3 ("L3 execution gate and completeness") that names the phase distinction explicitly: the §5.5 completeness requirement applies to the verifier-side L3-acceptance evaluation path; agent-side pre-L3-creation evaluation is governed by §5.2's short-circuit clause, which requires agents to stop at the first environment.* failure as a fail-closed agent-side halt distinct from the verifier's diagnostic-completeness obligation.

Resolves the §5.2/§5.5 register tension flagged in the RFC 2119 audit P3-1. §5.2 requires agents to short-circuit on the first environment.* failure (agent-phase, fail-closed). §5.5 Block 3 requires verifiers to evaluate every environment.* constraint to completion (verifier-phase, diagnostic-completeness). On their face these read as contradictory; the bridge sentence makes the phase distinction load-bearing and removes the apparent conflict without changing either rule.

Wording refined on PR agent-intent#9 with Douglas Borthwick:

- Option A venue: bridge sentence placed in §5.5 Block 3, immediately after the verifier-side completeness sentence, rather than in §5.2 or as a free-standing block. Keeps the disambiguation co-located with the rule it disambiguates.

- Precision rewrite: permits → requires (§5.2 short-circuit is normative agent obligation, not optional optimisation); self-gating optimization → fail-closed agent-side halt (correctly characterises the agent-phase halt as a safety property, not a performance choice). Douglas eyeball-acked the precision rewrite on PR agent-intent#9.

PR agent-intent#22 v0.5.3 mirror by Douglas will add the §5.2 short-circuit body sentence plus the same §5.5 Block 3 bridge in lockstep, so the family lands the resolution identically across both type specifications.

Document header stays at 0.5-draft; v0.5.3 is a patch-level refinement per the convention established in 7b97827. No algorithm changes; no security-model changes; no Headless Oracle code changes required.

Co-Authored-By: Douglas Borthwick <256362537+douglasborthwick-crypto@users.noreply.github.com>
Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
…2.5 register polish

Four touchpoints: §5.2 forward-pointer closing MCP/section-isolation discovery gap; §4.8 preamble port from PR agent-intent#22 v0.6 feb3292 by Douglas Borthwick; §2.3 register polish (P3-2); §2.5 register polish (P3-3). Document header stays at 0.5-draft. §9 Changelog row added.

Co-Authored-By: Douglas Borthwick <256362537+douglasborthwick-crypto@users.noreply.github.com>
Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
Formalises the normative-vs-descriptive register discipline applied across the environment.* family in multiple patch-level revisions (v0.5.4 §2.3/§2.5 on agent-intent#9, v0.6.1 §6.9 on agent-intent#22) as an explicit charter property.

Six sections at C.1 through C.6:

- C.1 Purpose — anchors in v0.5.4 §2.3/§2.5 and v0.6.1 §6.9 as concrete drivers
- C.2 Normative vs. descriptive register — definitions + worked example from v0.5.4 §2.3
- C.3 Rules for the environment.* family:
  * C.3.1 RFC 2119 keywords in normative register
  * C.3.2 Lowercase synonyms in descriptive register
  * C.3.3 Redundancy avoidance (v0.5.4 §2.5 as worked example)
  * C.3.4 Application-layer vs. transport-layer scope (v0.6.1 §6.9 as worked example)
  * C.3.5 Forward rule for new sections
- C.4 Open questions — three for WG input:
  * Q1 Informative vs. normative appendix classification
  * Q2 Register-discipline audit cadence
  * Q3 Scope of Appendix C over time (evolves with practice; WG input welcome)
- C.5 Catalog of current instances — deferred to a future revision
- C.6 Relationship to §1 Notational Conventions

Skeleton only — shape and rules stated, full prose and exhaustive catalog deferred to post-convergence revision. Adoptable verbatim on PR agent-intent#22 Appendix C following the (a) pattern established for §4.8.

Document header stays at 0.5-draft per patch-level convention.

No algorithm changes; no security-model changes; no Headless Oracle code changes required.

Co-Authored-By: Douglas Borthwick <256362537+douglasborthwick-crypto@users.noreply.github.com>
Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
First coordination commit following Mastercard's PR agent-intent#23 merge into upstream/main.
Aligns environment-state RFC with the field-alignment-v2 normative changes from
agent-intent#23 (Reda, Apr 20 2026).

No semantic changes to `environment.market_state` itself. Purely downstream
propagation of transactional-constraint renames that appear in examples and
prose cross-references within this RFC:

- VCT version suffix: `mandate.checkout.open` → `mandate.checkout.open.1`
  (4 occurrences: §3 dual-mode prose, §4 Appears In, §5.5 wallet example,
  §5.5 multi-exchange example)
- VCT version suffix: `mandate.payment.open` → `mandate.payment.open.1`
  (2 occurrences: §3 dual-mode prose, §4 Appears In)
- Constraint type pluralisation: `mandate.checkout.allowed_merchant` →
  `mandate.checkout.allowed_merchants` (2 occurrences in §5.5 examples)
- Constraint field generalisation: `allowed_merchants` → `allowed`
  (2 occurrences, paired with the pluralisation above)
- §5.5 Block 3 prose collapse: `(mandate.*, payment.*)` → `(mandate.*)`
  (reflects PR agent-intent#23's move of payment constraints under the mandate.* prefix)

Additive PR agent-intent#23 fields (match_mode, constraint_policy, risk_data) are out of
scope for this RFC — they belong to transactional constraint types, not the
environment.* family.

Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
Adds Appendix D listing the running-code implementations of the environment.*
family known to the editors at the time of writing, per RFC 6982.

Scope of this revision:

- Appendix D.1 records Headless Oracle as the reference implementation of
  environment.market_state. Endpoints, Ed25519 signing per §4.7, coverage of
  28 global exchanges (25 ISO 10383 MICs + 3 convention MICs for crypto-native
  venues), reference verifier at github.com/headlessoracle/demo-agent (~150
  lines, MIT), architectural rationale at github.com/headlessoracle/essays,
  and the conformance pointer set for §4.1, §4.2, §4.6, §4.7, §6.5, §6.8.
  Records the 2026-04-03 x402 settlement infrastructure validation tx on
  Base mainnet (payer wallet self-funded for end-to-end test, not commercial
  revenue; first external x402 transaction observed 2026-04-17).
- Appendix D.2 records InsumerAPI (Skye Meta Corp, PR agent-intent#22) as the running
  implementation of the sibling environment.wallet_state constraint type.
  Sourced from PR agent-intent#22's property table: ES256 / P-256, kid insumer-attest-v1,
  1800-second JWT TTL, 33-chain coverage. Listed for environment.* family
  completeness; the canonical Implementation Status appendix for
  environment.wallet_state belongs in that specification.
- Appendix D.3 disclaimer states that listing is not endorsement and verifiers
  MUST independently verify per §4.2 regardless of Appendix D listing.
- §9 Changelog: v0.5.7-draft row added at the top of the table.

Per RFC 6982 §2, Appendix D is intended to be removed by the RFC Editor before
any final standards-track publication; the GitHub history of this Internet-
Draft retains it permanently as evidence of priority.

Document header stays at 0.5-draft; v0.5.7 is a patch-level refinement adding
an informative appendix only. No algorithm changes, no security-model changes,
no §4 schema changes, no Headless Oracle code changes required, test count
unchanged (1031+ as of the Apr 24 telemetry hardening sprint baseline).

Sibling-mirror coordination: a parallel Appendix D on PR agent-intent#22 is the editor's
call on the environment.wallet_state side and is expected to land independently
on Douglas Borthwick's timing.

Co-Authored-By: Douglas Borthwick <256362537+douglasborthwick-crypto@users.noreply.github.com>
Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
Stacked on v0.5.7-draft-implementation-status (commit 21a156c). Catches the
spec text at §7.1 up to the live deployment state surfaced in Appendix D.1
shipped at v0.5.7, and backfills the previously omitted v0.5.6 changelog row.

Scope of this revision:

- §7.1 reference implementation table: "Supported exchanges" row updated
  from "23 global exchanges" to "28 global exchanges" — the §7.1 text was
  a stale residue from the v0.1-draft (Mar 17 2026) which described
  coverage of 23 exchanges before the XCBT, XNYM, XCBO, XCOI, and XBIN
  extensions landed in the live deployment. Spec text catches up; no
  semantic change.
- §7.1 prose MIC enumeration: replaced 23-MIC list with the verified
  28-MIC list (XNYS, XNAS, XLON, XJPX, XPAR, XHKG, XSES, XASX, XBOM,
  XNSE, XSHG, XSHE, XKRX, XJSE, XBSP, XSWX, XMIL, XIST, XSAU, XDFM,
  XNZE, XHEL, XSTO, XCBT, XNYM, XCBO, XCOI, XBIN) matching Appendix
  D.1 verbatim.
- §9 Changelog v0.5.6 row backfill: inserts the previously omitted
  v0.5.6-draft row between v0.5.7 and v0.5.5. Body summarises commit
  68f4db4 (PR agent-intent#23 field-alignment-v2 propagation: VCT version suffix
  .1 added to mandate.checkout.open and mandate.payment.open in
  examples; mandate.checkout.allowed_merchant pluralised; allowed_merchants
  generalised to allowed; §5.5 Block 3 prose collapsed for PR agent-intent#23's
  move of payment constraints under the mandate.* prefix). Date for
  v0.5.6 row derived from the commit author date (2026-04-23).
- §9 Changelog v0.5.8 row added at top of table.

Cross-section structural alignment between §7.1 and Appendix D.1 — adding
Reference verifier, Architectural rationale, or x402 settlement validation
rows to the §7.1 table mirroring D.1 — is intentionally out of scope for
this revision and left for a future v0.5.9+ patch. v0.5.8 is scoped strictly
to the count, MIC list, and changelog backfill.

Document header stays at 0.5-draft; v0.5.8 is a patch-level refinement
stacked on v0.5.7 (not independent). No algorithm changes, no security-model
changes, no §4 schema changes, no Headless Oracle code changes required,
test count unchanged (1031+ baseline).

Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
… breakdown

Stacked on v0.5.8-draft-section-7-1-update (commit f5daceb). Single-concern
edit: removes the parenthetical "(25 venues)" and "(3 venues)" count
breakdown from Appendix D.1's coverage row in favour of structurally-aligned
wording with §7.1 and a runtime-anchored pointer to GET /v5/exchanges.

Scope of this revision:

- Appendix D.1 coverage row: drops the parenthetical ISO/convention venue
  counts. Replacement wording aligns with §7.1's formulation and adds a
  pointer to the live mic_type categorisation at GET /v5/exchanges as the
  authoritative per-venue source. The explicit count breakdown was an
  editorial precision claim requiring external verification of each
  venue's ISO-registration status — the live mic_type field at
  /v5/exchanges reports a different split than the v0.5.7 D.1 wording
  asserted, so the cleanest move is to defer to runtime rather than fix
  the editorial claim with a count update.
- §9 Changelog: v0.5.9-draft row added at top of table.

The MIC list (XNYS, XNAS, ..., XBIN — 28 venues), the coverage count (28),
and every other D.1 row are unchanged.

Document header stays at 0.5-draft; v0.5.9 is a patch-level refinement
stacked on v0.5.8 (not independent). No algorithm changes, no security-
model changes, no §4 schema changes, no Headless Oracle code changes
required, test count unchanged (1031+ baseline).

Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
Stacked on v0.5.9-draft-d1-coverage-alignment (commit 486ae6d) which itself
stacks on v0.5.8 (0380ece) and v0.5.7 (21a156c). Applies six specific
corrections from Douglas's May 4 review of the v0.5.7-v0.5.9 stack and
his same-day follow-up tightening Fix agent-intent#5.

Scope of this revision:

- D.2 Organisation row corrected to "InsumerAPI (insumermodel.com)".
  InsumerAPI is the entity operating the environment.wallet_state issuer
  infrastructure (the RFC 6982 reference implementation D.2 documents),
  mirroring D.1's "Headless Oracle (headlessoracle.com)" pattern.
- §9 v0.5.7-draft row body updated correspondingly to reference
  "InsumerAPI (Douglas Borthwick)" rather than the prior wording that
  attributed the implementation to a different entity.
- D.2 Agent-native key provisioning row updated to "USDC/USDT/BTC
  on-chain payment". Production behaviour at POST /v1/keys/buy accepts
  USDC and USDT on EVM chains and Solana, plus BTC on Bitcoin, per
  Douglas's confirmation against PR agent-intent#22 v0.6.4 commit fc6d955 §7.4.
- §9 v0.5.8-draft and v0.5.9-draft row bodies updated to remove co-author
  attribution. Both patches were HO-side housekeeping with no Douglas
  input. The v0.5.8 and v0.5.9 commit message trailers were also
  dropped via amend+rebase in this sprint to align shipped state with
  what was committed to in correspondence. Only v0.5.7 (Appendix D
  listing both implementations as shared editorial work) warranted the
  co-author attribution and retains it.
- D.2 License row added between the existing Reference verifier row
  and the closing prose paragraph, mirroring D.1's License-row pattern,
  with final wording: "Proprietary. Copyright 2026 Douglas Borthwick."
  Two-sentence form is the cleaner default matching the posture across
  Douglas's other published surfaces; spec body does not carry patent-
  prosecution context where it would not serve standards-track readers.

Structural alignment between D.1 and D.2 (whether D.2 needs Operational
Since, Architectural rationale, or other rows mirroring D.1) is a
separate question and out of scope for v0.5.10.

This commit is the result of a stack rewrite that collapsed an earlier
v0.5.10 + v0.5.11 pair (where v0.5.11 added the License row tightening
on top of v0.5.10) into a single v0.5.10 commit with the License row
already at its final wording from the start. The collapse keeps
retracted-text quoting out of the changelog and commit-message prose
that working-group reviewers will read.

Document header stays at 0.5-draft; v0.5.10 is a patch-level refinement
stacked on v0.5.9 / v0.5.8 / v0.5.7 (not independent). No semantic
changes to spec body, no algorithm changes, no security-model changes,
no §4 schema changes, no Headless Oracle code changes required, test
count unchanged (1031+ baseline).

Co-Authored-By: Douglas Borthwick <256362537+douglasborthwick-crypto@users.noreply.github.com>
Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
… + per-type)

Mirrors PR agent-intent#22 v0.6.5-draft commit 66185a1 (Douglas Borthwick, InsumerAPI).

Adds family-wide algorithm-deprecation prose to §4.7 mirroring
draft-borthwick-msebenzi-environment-state-00 v0.2-draft §4.3 family-wide
SHOULD ("Type specification authors SHOULD specify, in the type's
specification, a deprecation mechanism for the type's MUST-implement
algorithm before that algorithm is needed").

Adds per-type deprecation mechanism for environment.market_state:
conditions (NIST / IRTF CFRG / RFC 8032 / RFC 8725 update or cryptographic
break), timeline (>=12-month verifier-migration window from minor-version
revision publication; parallel verification during window; rejection after
window end), backward compatibility (mandate-issuer migration on key-
registry readiness; verifier detection via RFC 8615 well-known key-set
inspection at {issuer}/.well-known/oracle-keys.json).

Updates §4.7 PR agent-intent#22 coordination Note to reflect the family-wide algorithm-
deprecation discipline as co-equal with the agility framework, extension-set
model, and fail-closed-negotiation requirement.

Family-wide prose (algorithm-agnostic policy paragraph, single-algorithm
lock-in paragraph, family-wide deprecation paragraph) byte-identical to
PR agent-intent#22 §4.7.

Co-Authored-By: douglasborthwick-crypto <256362537+douglasborthwick-crypto@users.noreply.github.com>
Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
Signed-off-by: Michael Msebenzi <127877551+LembaGang@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants