RFC: environment.wallet_state — sibling constraint for on-chain wallet state#22
Conversation
|
Douglas — read through the whole thing. Structural mirroring of #9 is clean, the §6.3 JWKS solution is exactly what I was hoping to see drafted, and the §4.5 composition example with both constraints in a single mandate makes the family pattern visible in a way two isolated specs wouldn't have. Holding back on detailed technical notes until we agree on the shape — don't want either of us bogged down in line-level review before the scaffolding decisions are made. Three points worth putting on record now so they shape the next revision rather than surface at WG review: 1. TOCTOU freshness needs normative text, not an implementation default. The 30-minute TTL is a sensible InsumerAPI choice, but from the spec's perspective the freshness window is the entire exploitable surface. The DeFi oracle literature ($117M Mango, $116M Balancer, and most flash-loan exploits in that class) is effectively a catalogue of TOCTOU races at longer windows than this one. I'd like the spec to define 2. Attestation provider neutrality. Right now a reader can't cleanly separate "the 3. Algorithm agility framing across both specs. Your Q1 names the issue correctly. My view: the family should be algorithm-agnostic at the constraint-type level with explicit agility language (RFC 8725 §3.1 is the hook), each constraint type declares its MUST-implement alg and a SHOULD/MAY extension set, and verifiers negotiate per constraint instance. ES256 as MUST-implement for wallet_state is fine given it composes with the existing VI JWT stack; Ed25519 as MUST-implement for market_state is defensible for the same reason you made the ES256 call — matches the reference implementation's signing stack. What I want to avoid is the family inheriting a single-algorithm constraint by accident. Happy to put this in both specs' §8 open questions with identical wording so the WG sees one family-wide question, not two independent ones. Everything else I have — composition semantics when one constraint passes and another fails, JWKS caching and rotation expectations, cross-chain temporal consistency, the RFC 2119 pass — is technical-detail territory that reads better against a revision than against the current draft. Happy to go through it in a follow-up once these three are settled. The privacy-preserving boolean design, the block-anchored audit trail, the chain-agnostic abstraction, and the native On coordination: if you want to do shared-structure changes across both drafts before either merges, I'd rather align the freshness and provider-neutrality language in lockstep than have #9 and #22 diverge on the same questions. Either venue works for that — happy to coordinate here, on #9, or offline. |
|
@LembaGang — all three accepted. Here's what the revision looks like concretely: 1. The current draft already has
Happy to converge on field naming — 2. Provider neutrality — abstract interface in §3, InsumerAPI in §7. The restructure is clean because the validation algorithm (§4.2) already draws the line. Steps 1–10 only touch six JWT claims: Revision structure:
A second conformant implementation would need to emit the six core claims and publish a JWKS. That's the bar. You're right that this is the point Pablo and the Mastercard side will probe hardest — better to have the answer already in the text. 3. Algorithm agility — RFC 8725 §3.1, identical wording in both specs. Agreed on the shape: family-level agility language, per-type MUST-implement declaration, SHOULD/MAY extension set, verifiers negotiate per constraint instance. ES256 for On coordination: let's keep it here on #22. The revision will be a single commit addressing all three points. If any shared-structure changes need to land in #9 simultaneously, I'll flag them in the commit message so you can lift the pattern. The four items you held back — composition semantics on mixed pass/fail, JWKS caching and rotation expectations, cross-chain temporal consistency, RFC 2119 pass — all read better against the revision. Happy to take them in a follow-up round once the scaffolding is settled. |
|
Douglas — v0.2 lands all three. Read the full diff against v0.1 carefully; the restructure is more substantive than a line count suggests. Specific reactions worth putting on record: §4.6 is the right frame. The "attestation TTL is a provider-side default; §4.7 is handoff-ready. The standalone-block framing — adoptable verbatim with the table rows swapped — is the cleanest way to resolve a family-wide question across two specs. I'll lift it into #9 with Ed25519 as MUST-implement and the extension set widened to include ES256 / Ed448. The "fail-closed check, not a silent downgrade" line is worth keeping verbatim in both specs; it ties the agility model back to the family's fail-closed posture rather than leaving it as an isolated crypto concern. §4.1 restructure works. The split between seven REQUIRED claims and three OPTIONAL ones is the minimum surface a second conformant issuer needs, and the explicit sentence that the verification algorithm is defined solely over the REQUIRED claims closes the door on implementation leakage. §7 reading as "the reference implementation of a conformant wallet-state attestation issuer for this constraint type" rather than as de-facto normative text is the shift that makes the spec portable to a future second issuer without a revision. Coordination. Agree #22 stays the forward venue for shared-structure work. I'll open a commit on #9 this weekend that (a) adopts Next round. The four I held back — composition semantics on mixed pass/fail (what happens when The co-authorship attribution on the commit is noted and appreciated. The pace this is moving at wouldn't be possible without that kind of tooling on both sides. On family shape: two constraint types with matching freshness semantics, matching agility framing, matching fail-closed posture, and independently signed reference implementations starts to look less like two proposals and more like a registered namespace. Worth holding that framing in mind when the working group picks this up. |
…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.
|
@douglasborthwick-crypto — #9 v0.2 is live. Shared-structure changes landed in lockstep:
The four follow-up items now read against both v0.2 drafts. When you're ready for the next round — composition semantics on mixed pass/fail, JWKS caching and rotation expectations, cross-chain temporal consistency, RFC 2119 audit — either venue works for me. |
|
@LembaGang — picking up the first of the four: composition semantics on mixed pass/fail. Drafted as a new §5.5, same standalone-block pattern as §4.7 so #9 can lift verbatim with no changes. Pushed as 5.5 Family CompositionConjunction semantics. The Mixed pass/fail. When one L3 execution gate. A verifier or agent MUST NOT proceed to Layer 3 creation if the validation result contains any Per-member diagnostic output. Each failed Rationale. Each member of the family answers an independent question — is this market open? is this wallet still funded? Because the questions are independent, their answers compose as AND, not OR: a failure on any member removes the basis for execution. Collapsing per-member diagnostics would destroy the audit trail that makes the family load-bearing; preserving them makes every signed attestation recoverable from the validation output, and makes dispute resolution an application-layer concern with complete evidence rather than a debugging exercise.
The three remaining follow-ups (JWKS caching/rotation, cross-chain temporal consistency, RFC 2119 audit) still read against v0.2 + this block. Happy to take them in any order you prefer; either venue works. |
|
Caught up on 85cfaa0 this evening. The §5.5 core is right and I'd adopt it as drafted: conjunction semantics, no partial-fulfillment path, L3 gate, per-member diagnostic output. The passing-doesn't-rescue-failing framing is the load-bearing move and it lands cleanly. Your closing point on dispute resolution — that preserving per-member diagnostics makes disputes an application-layer concern with complete evidence rather than a debugging exercise — is the one I'd single out as quietly important: it's the clean separation between what the protocol owes (complete evidence) and what the application decides (what to do about it). Worth making that split explicit in normative text at some point, though not necessarily this revision. One thing I'd add alongside your rationale rather than in place of it. Your "independent questions compose as AND" captures the semantic argument. The architectural argument reinforces it: conjunction also falls out of fail-closed posture directly. Any Two gaps I'd flag for a v0.3.1 pass: Gap 1 — L3 gate timing vs. per-member diagnostic output. §5.5 mandates per-member diagnostic output for every failed Gap 2 — per-member disambiguation with same-type repeats. "Constraint type + §4.2 step" isn't sufficient to disambiguate when two constraints of the same type appear in the same mandate. My §4.5 multi-exchange example already has this case: two Happy to fold both into a v0.3.1 lift on PR #9 and have you mirror, or take them into your next commit on PR #22 — either venue works. Slight preference for mine since the §4.5 multi-exchange example is the concrete case Gap 2 resolves, but genuinely indifferent on mechanics. On the remaining three items — JWKS caching, cross-chain temporal consistency, RFC 2119 audit — pick whichever is easiest for you to land next and I'll stage against it. I'm leaning into the 2119 audit on my side this weekend regardless since it's symmetric work and doesn't block on either of us. |
|
Read your 20:40 carefully. Adopting both gaps as drafted, and the architectural argument as a co-equal rationale — the membership-criterion framing is load-bearing for future Gap 1 — L3 gate timing. Concur on the completeness rule. Proposed normative text, sitting above the per-member diagnostic paragraph:
Composes cleanly with §5.2's ordering rule — environment-before-transactional stays, completeness rule layers on top. Gap 2 — per-member disambiguation. Concur, wallet_state analog:
Making distinguishing-field selection a per-type obligation (same shape as §4.6 Venue. Your preference works. Take Gap 1 + Gap 2 into v0.3.1 on #9 — §4.5 multi-exchange is the clean driving case. I'll mirror on #22 once v0.3.1 lands, wallet_state examples in the same §5.5 slot. Dispute resolution. Agree the split is worth normative text eventually — not blocking v0.3.1. Next on #22. Picking JWKS caching and rotation next — wallet_state-specific, non-overlapping with your 2119 audit. Will stage the commit once v0.3.1 lands so we're not racing on §5.5 text. |
eed3105 to
f176515
Compare
|
Quick follow-up on sequencing. §6.8 JWKS Caching and Key Rotation staged as commit On "not racing on §5.5 text": §6.8 is a new section (between §6.7 and §7), doesn't touch §5.5, and doesn't cite the Gap 1 completeness rule. Its per-constraint-scope rule stands on JWKS-specific security grounds. When Gap 1 mirror lands on §5.5 after your v0.3.1, the general completeness rule reinforces §6.8 without edits. Sequencing holds:
The caching rules were drafted against live operational behaviour on the reference implementation side — |
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>
|
v0.3 of PR #9 landed — commit 7a8987c. §5.5 Family Composition sits between §5.4 and §6, five bold-label paragraphs: conjunction semantics, mixed pass/fail, L3 execution gate and completeness, per-member diagnostic output, rationale. Both gaps folded:
Rationale presents semantic ("independent questions compose as AND") and architectural ("failure mode must be gating, or the type isn't in the family") as co-equal. Membership-criterion framing is in. Coordination blockquote preserves the standalone-block-adoptable-verbatim pattern for your mirror onto §22 §5.5. Thanks for the co-drafting pace this week. Your next move — JWKS caching on §6.8 as you staged, and the §5.5 mirror whenever it fits. I'll read §6.8 against v0.2 this weekend and raise any family-wide concerns in a separate comment; RFC 2119 audit continues in parallel on my side. |
… 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>
|
§5.5 mirror shipped as Gap 1 lifted verbatim — completeness rule, short-circuit non-conforming, transactional post-failure implementation-defined, composes with §5.2. Gap 2 adopted with Handoff sequencing stays as you placed it — §6.8 on your weekend read, RFC 2119 audit on your side in parallel. |
|
Douglas, caught up on your §5.5 mirror and §6.8 JWKS commits this afternoon. The §5.5 mirror is clean. Subject_wallet as the wallet_state distinguishing-field with no fallback needed reads more cleanly than my MIC case precisely because the constraint-level field is always present. The settlement-wallet versus gas-wallet driving example is the right same-type analog to my §4.5 multi-exchange case. Family-wide §5.5 now lands identically across both specs. On §6.8, the core is correct and I would adopt it. The kid-mismatch cache bust is the load-bearing primitive; tying trust-root semantics back to §6.3 on the fail-closed fetch rule is the right move; keeping the jti cache and JWKS cache independent in §6.2 closes a class of confusion before it starts; the "payment execution SHOULD NOT enable stale-cache fallback" carve-out is exactly the right nod to the strict-freshness deployment class. One structural observation. Reading §6.8 against the family discipline we have established in §4.6, §4.7, and §5.5, each of those sections is family-wide by construction, adoptable verbatim in the sibling spec with per-type fields swapped. §6.8 reads the same way to me: every normative rule applies identically to any environment type that verifies via JWKS. The only wallet_state-specific mention is the example naming environment.wallet_state in the per-constraint-scope paragraph, which swaps cleanly to environment.market_state on my side. I do not have a §6.8 equivalent in the market_state spec yet, and market_state's JWKS pattern needs the same caching guidance or implementers will re-fetch per verification and create avoidable load. Happy to lift §6.8 verbatim into the market_state spec as a v0.4 addition, same standalone-block pattern we used for §5.5. The only per-type swap is the example constraint-type name in the per-constraint-scope paragraph. Alternatively, if you would rather extend your §6.8 to explicitly name family-wide scope in the opening paragraph and I just reference it from the market_state side without duplicating the text, that also works, though my instinct is that duplication matches what we have done for §4.6, §4.7, and §5.5 and the family reads more symmetrically if each spec carries a full §6.8. Three smaller items for a v0.3.2 pass or working-group review, none blocking. One. Stale-cache fallback policy mechanism. The "deployment's security policy explicitly permits" line is correct but leaves the policy mechanism unspecified, whether mandate-level field, verifier config, or deployment config. A one-line note ("mechanism is implementation-defined but SHOULD be explicit and auditable") would close the ambiguity. A mandate-level stale_cache_fallback_permitted field with default false is the stricter version, if we want to take that path. Two. Grace window discoverability. §6.8 correctly bounds the grace window by issuer-side quantities but does not specify how issuers communicate rotation start or grace-window end to downstream policy auditors. Could be a rotation_announcement JWKS metadata field, could be out-of-band. Polish-tier but worth raising before WG review. Three. JWKS URL migration. §6.8 handles key rotation within a single JWKS URL. Issuer migration where trusted_jwks itself changes is currently a new-mandate event because trusted_jwks is part of the signed constraint. That is a defensible design choice, it keeps the trust-root binding rigid, but it is undocumented. Worth naming explicitly, either here or in §6.3, so implementers understand the migration path is not free. Sequencing on my side. RFC 2119 audit continuing in parallel this weekend as flagged; any family-wide concerns from that on a separate comment. Cross-chain temporal consistency reads better against §6.8 plus the RFC 2119 pass than against v0.3.1 alone, so I would hold it for the round after v0.4. |
|
LembaGang — Concur on verbatim duplication. Family discipline is the right read: §6.8 is family-wide in substance, and the only wallet_state-specific surface is the per-constraint-scope example naming On the three v0.3.2 items — all three are adoptable as family-wide with per-type localization. Proposed resolutions: 1. Stale-cache fallback mechanism. Taking the stricter path — schema addition, same shape as
§6.8 companion paragraph (replaces the stale-cache sentences closing the "Fail-closed on fetch failure" paragraph, which are superseded by the field-level MUST NOT):
Field-level shape matches 2. Grace-window discoverability. SHOULD statement, no mandated mechanism. Proposed text, fitting between the issuer rotation responsibilities and fail-closed paragraphs of §6.8:
Keeps the polish-tier posture you flagged. Adoptable verbatim across specs — nothing wallet-specific. 3. JWKS URL migration. Single paragraph, §6.3 rather than §6.8 — the rigidity is a property of the trust-root binding, not the caching layer. Proposed text for §6.3:
Adoptable verbatim; trust-root rigidity applies to any Sequencing. Happy to fold all three into a single v0.3.2 commit on #22, with §6.8 duplication on your side landing as the market_state v0.4 addition. Cross-chain temporal consistency queued for the round after v0.4 as agreed — reads better against both specs once the stale-cache and migration text has stabilised. RFC 2119 audit continues on your side in parallel; I'll respond to family-wide findings when they land. |
|
Douglas — concur across the board on the three resolutions. Specific reactions:
Two things to raise before we pin v0.4 shape. First, version number sequencing. I pushed a v0.3.2-draft on PR #9 a few minutes ago — commit 67a5adb, an RFC 2119 audit pass. Two local fixes: max_attestation_age strictness (closes the v0.2 REQUIRED+default contradiction — strict REQUIRED, no default, missing field is malformed and verifiers MUST reject) and §6.5 Constraint Stripping normative hardening (previously zero normative keywords in a security-considerations section). Both HO-local; no family-wide surface touched. So v0.3.2 is taken on the market_state side for a P1 patch. My suggestion: let's converge your three resolutions plus the §6.8 duplication into v0.4 on both specs, landing identically. §6.8 verbatim + new stale_cache_fallback_permitted schema field + §6.8 grace-window SHOULD paragraph + §6.3 URL migration paragraph. That gives v0.4 substantive release shape rather than splitting across v0.3.2 and v0.4. Second, a family-wide finding from the v0.3.2 audit that I should flag rather than bury: the max_attestation_age REQUIRED+default-60 contradiction exists symmetrically on PR #22 — same elevation to REQUIRED in v0.2 with "normative default of 60 seconds" language, same silent-restoration of the TOCTOU surface that §4.6 is designed to close. I fixed it on PR #9 tonight. Your side has the same logical gap. Two paths forward: (a) you lift the strictness pass onto PR #22 as a separate v0.3.1.1 or similar patch before the v0.4 round, symmetric to what I just shipped; or (b) we fold the strictness pass into v0.4 alongside your three items, so v0.4 on both specs resolves max_attestation_age contradiction plus stale_cache_fallback_permitted plus grace window plus URL migration plus §6.8 in one coordinated release. My preference is (b) — cleaner versioning and the family charter in §2.3/§4.6 stays truthful without a temporary divergence window. Your call on venue mechanics. Sequencing on my side for v0.4: I will lift §6.8 onto PR #9 with the one-line per-type swap on the per-constraint-scope paragraph, plus whatever localization is needed on the stale_cache_fallback_permitted examples. Same lockstep pattern as §5.5. RFC 2119 full findings summary coming in a separate comment on PR #9 — preview: beyond the max_attestation_age P1 (fixed) and §6.5 gap (fixed), the third finding is SHALL/MUST normalization (both specs use SHALL a handful of times; MUST is more conventional — one-line find-and-replace). Everything else was market_state-local. |
|
LembaGang — Concur on (b). v0.3.1.1 would read as a procedural patch rather than a substantive release — landing audit-parity + family-wide additions together keeps the §2.3/§4.6 charter coherent on both sides. Audit-parity drafted locally against One thing to raise before v0.4 shape pins. The Two paths, your call: (i) OPTIONAL with default=false — matches the "missing = safe default" semantic. Stricter deployment rule ("payment execution MUST NOT set to (ii) REQUIRED, no default, missing=malformed — full parity with the My lean is (i) — the defaulted value is fail-secure, and forcing explicit declaration on every mandate doesn't buy security surface the way it does for Sequencing on my side:
Once your preference on (i)/(ii) is down and the SHALL→MUST findings are out, v0.4 on PR #22 goes up — single commit, parallel to whatever shape lands on PR #9. |
|
Douglas — (b) locked. Audit-parity + stale_cache_fallback_permitted + grace window + URL migration + §6.8 duplication as a single v0.4 release on both specs. The v0.3.1.1 route would read as a procedural patch where we want a substantive release; rolling it all into one keeps the §2.3/§4.6 charter coherent through the transition and gives v0.4 the shape a WG reviewer or acquirer engineer sees as a real milestone rather than a sequence of fix-ups. On the (i) vs (ii) question — I'm landing on (i), OPTIONAL with default=false, with reasoning you should stress-test before we bake it. The v0.3.2 audit closed a REQUIRED+default contradiction specifically — a field can't be both REQUIRED (missing = malformed) and carry deterministic absent-case behaviour. stale_cache_fallback_permitted doesn't have to inherit the REQUIRED framing; OPTIONAL with a fail-secure default of false is a different schema shape that doesn't recreate the contradiction. The security posture is independent of the REQUIRED/OPTIONAL choice — fail-secure-by-default covers the "implementer forgot the field" case whether the field is formally REQUIRED-rejecting-when-absent or OPTIONAL-applying-default-when-absent. Two consistency notes against the v0.3.2 audit pattern:
Open question back to you: is there a scenario where stale_cache_fallback_permitted default-false is actually fail-open that I'm missing? The case I can construct is "deployment wants strict-freshness behavior, mandate-level MUST NOT catches it" — which is already your 17:42 text. If you see a surface I haven't considered, now's the time to raise it before the v0.4 commit bakes. Sequencing on my side: SHALL/MUST normalization isn't a finding. Post-audit verification showed all SHALL references in the market_state spec are on line 66 inside the RFC 2119 Notational Conventions boilerplate — zero substantive usage elsewhere. Full findings summary on PR 9 landed with the correction. No normalization work to fold into v0.4. §6.8 duplication onto PR 9 with the per-type example swap reads clean. I'll lift it once your v0.4 commit lands, same lockstep pattern as §5.5. |
|
LembaGang — Concur on (b) + (i). The REQUIRED-vs-OPTIONAL distinction you drew — REQUIRED because no nontrivial default is safe across deployment classes ( On the stress-test question: I can't construct a fail-open scenario under (i) that you're missing. Three surfaces I walked:
Mandate-level MUST NOT for payment-execution is already in my 17:42 text and handles the explicit-true-with-strict-freshness case. Unless you see a different surface, I'll bake (i) with the boolean-type clause into the v0.4 schema row alongside the two JWKS paragraphs from my 17:42 and the audit-parity lifts from Sequencing confirmed: v0.4 commit on #22 next, §6.8 lift onto #9 after it lands. Same lockstep as §5.5. |
|
Douglas — (i) with the boolean-type clause confirmed. I walked surfaces 4-8 from your three baseline and can't construct an additional fail-open path: nested/malformed JSON, loose-typed coercion of boolean-like strings, and attacker-set-to-true are either caught by your proposed clause or outside the field's scope (covered by the payment-execution MUST NOT or the mandate-issuer trust model). Bake (i) + "If present, MUST be boolean; non-boolean values MUST be rejected as malformed per §4.2 Step 1" as proposed. The clause reads as a parallel-construction match to the max_attestation_age Field Constraints bullet from v0.3.2, which continues the family hygiene at the bullet level alongside the section-level lockstep we have on §4.6/§4.7/§5.5/§6.8. Sequencing confirmed: your v0.4 commit on #22 next, §6.8 lift onto #9 after it lands. One small thanks: the narrowing of the v0.3.2 rule to its specific cause (REQUIRED + deterministic absent-case behaviour) rather than "no defaults ever" is the framing I want going forward for future environment.* consumer-policy fields. Worth calling out that you landed on it cleanly. |
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 — v0.4 shipped on #22 as
Working-tree diff: +57 / -13 across Handoff: §6.8 lift onto #9 is yours next, same lockstep as §5.5. Ping me if anything on the new §6.8 Fail-closed wording or the |
…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>
|
Douglas — v0.4 on PR #9 shipped as 53ea1c6. Lifts §6.8 with RFC 8615 key registry terminology, stale_cache_fallback_permitted as OPTIONAL boolean with the boolean-type hygiene clause, grace-window SHOULD paragraph. Two items to flag from the lift. First, §6.3's JWKS URL migration paragraph does not port. PR #9's §6.3 already documents the asymmetry in its JWKS/RFC-8615 coexistence paragraph: 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 trust-root-rigidity property your paragraph asserts exists only in wallet_state's threat model. Not lifted, flagged in the v0.4 changelog. The coordination work this week treated §6.3 as family-symmetric; the spec body had already acknowledged it wasn't. Worth naming so the asymmetry doesn't resurface in v0.5. Second, surfaced during the v0.4 lift review: the scoping of stale_cache_fallback_permitted is provenance-only on both our specs. §4.6 says max_attestation_age is family-wide. stale_cache_fallback_permitted is per-type (trust-root-mechanism-bound, differs between JWKS and key registry). But neither of our specs' normative bodies expresses this distinction — only the v0.4 changelog entries do. An agent composing a mandate that mixes environment.market_state and environment.wallet_state has no machine-discoverable way to know which shared field names share semantics. This is the v0.5 work queued in the v0.4 changelog, and I want to flag it as time-sensitive. Once a third implementer arrives, they'll read §4.6's family-wide framing and reasonably bake in a family-wide assumption for every field named identically across both specs. That becomes hard to walk back. Proposal for v0.5 scope: formalize trust-root-binding as an explicit family-charter dimension in §4.6 (or a new §4.8). Each field declares its scope: family-wide-trust-root-agnostic, or per-type-trust-root-mechanism-bound. max_attestation_age is the first category; stale_cache_fallback_permitted is the second; future fields declare their category at introduction. Happy to draft §4.8 on PR #9 as a standalone block adoptable verbatim on PR #22 — same pattern we've used for every shared-structure section. Could land next weekend. Otherwise v0.4 is in lockstep on both sides. The boolean-type hygiene clause you proposed ended up being the most load-bearing precision in the family-wide work this week. |
|
Michael — Accepting the v0.5 scope and §4.8 drafting on PR #9. The §6.3 framing miss is on me; better to name it now than let it resurface in outside code. The One pin before you draft: §4.6 vs new §4.8. §4.6 is currently scoped to Otherwise lockstep. Will port verbatim when you land. And glad the boolean clause earned its keep. |
|
Douglas — v0.5-draft on PR #9 shipped as commit Summary of what §4.8 does: Declares two scope categories for
Forward rule: new §4.8 preserves §4.6 normative text unchanged — it formalises the scope distinction §4.6 and §4.7 already imply in their specific domains, rather than re-scoping §4.6's existing text. Cross-references §4.6 and §4.7 explicitly. One housekeeping note folded into the same commit: document header bumped from 0.3-draft to 0.5-draft. The v0.4 commit ( On the mirror onto PR #22 §4.8. Pre-walked your current schema fields against the two-category taxonomy. Three of them land cleanly, three land cleanly with a note, and two surface a taxonomy gap worth flagging before you commit. Clean
Clean
Clean
Two fields that surface a taxonomy gap:
The current §4.8 taxonomy has one "per-type" bucket labelled "trust-root-mechanism-bound." These two fields are clearly per-type but not because of trust-root mechanism; they're per-type because of evaluation semantics and wire protocol. Three options for handling:
My lean is (3) — lightest-touch commit for you today, gives the working group a named gap to discuss rather than pre-committing to a taxonomy fix. But the choice is yours since your side surfaces the gap. Happy to ship market_state's §4.8 taxonomy update in lockstep once you've committed to a direction. Cross-chain temporal consistency and RFC 2119 audit still queued for whichever of us picks them up next; v0.5 §4.8 doesn't touch either. |
… + 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>
…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.
…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>
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>
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.
… 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>
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>
…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>
…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>
…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>
…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>
…sub-second truncation asymmetry as intentional
…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>
First coordination commit following Mastercard's PR agent-intent#23 merge into upstream/main. Aligns environment.wallet_state RFC with the field-alignment-v2 normative changes from agent-intent#23 (Reda, Apr 20 2026). No semantic changes to `environment.wallet_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` (3 occurrences: §2.2 dual-mode prose, §4 Appears In, §4.5 composition example) - VCT version suffix: `mandate.payment.open` -> `mandate.payment.open.1` (2 occurrences: §2.2 dual-mode prose, §4 Appears In) - Constraint type pluralisation: `mandate.checkout.allowed_merchant` -> `mandate.checkout.allowed_merchants` (1 occurrence in §4.5 composition example) - Constraint field generalisation: `allowed_merchants` -> `allowed` (1 occurrence, 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: Douglas Borthwick <256362537+douglasborthwick-crypto@users.noreply.github.com>
…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.
…-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>
a14a801 to
d0c2e31
Compare
…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>
…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>
…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>
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>
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.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>
Summary
This RFC proposes
environment.wallet_stateas a second constraint type in theenvironment.*namespace introduced by #9, for autonomous mode (L3) execution.Problem
environment.market_state(#9) correctly identifies that autonomous agents need cryptographic awareness of external state before L3 execution, and uses market sessions as the first instance. The same TOCTOU class of harm applies to on-chain payment sources: an agent with a valid VI credential whose amount constraints were checked at L2 can still execute into a wallet that no longer holds the required balance at L3 verification time — the wallet may have been drained, the NFT transferred, or the position unwound between L2 issuance and L3 check.Wallet state is environmental, not transactional. Amount validation at L2 is not evidence that the source wallet will satisfy the same condition at L3. The gap is structurally identical to executing into a halted market.
Proposed Constraint:
environment.wallet_stateRequires the agent to obtain an ES256-signed JWT attestation from a verified wallet-state issuer, binding a boolean verdict to a specific
subwallet, a set ofconditionHashvalues, and aniat/expwindow — before L3 execution is permitted.Key design decisions:
pass: falsealways fails — a valid signed attestation confirming the wallet no longer satisfies the condition is a hard stopenvironment.*constraints checked before all transactional constraint types (shared rationale with RFC: Add External State Attestation constraint type for autonomous ex…RFC: External State Attestation — Environmental Verification Constraint for Autonomous Execution #9 §5.2)attestation_urlandtrusted_jwkssubclaim — "this attestation is about this payment source" is a standard JWT check, not a new constraint fieldRelationship to #9
This draft is intentionally structured as a sibling to #9:
trusted_issuers): trust is bound to the JWKS signing key host (trusted_jwks), not the endpoint URL, which moves the policy-layer allowlist from per-endpoint inventory to a one-line host checksubjectbinding generalisation raised in review of the proposalReference Implementation
InsumerAPI is the reference wallet-state attestation issuer consumed by this constraint. It evaluates boolean conditions against live on-chain state across 33 chains and returns ES256-signed JWTs directly verifiable with any standard JOSE library via JWKS key discovery.
POST /v1/attestGET /.well-known/jwks.jsonkid: insumer-attest-v1)"0x" + sha256(canonical_json(evaluated_condition)), sorted keysPOST /v1/keys/buy— no auth, wallet is identity, USDC/BTC on-chain paymentAgent lifecycle fit: the reference issuer supports fully autonomous key provisioning at
POST /v1/keys/buy— no email, no signup form, no human in the loop. An agent that has the authority to spend USDC on behalf of its principal already has everything it needs to self-provision the key required to fulfillenvironment.wallet_stateconstraints. No out-of-band credential issuance step.Live test vectors (fresh call 2026-04-15) are included in Appendix A of the spec. A working end-to-end verifier is published at
github.com/douglasborthwick-crypto/insumer-examples.Files Changed
spec/environment-wallet-state.md— full normative specification with validation algorithm, JavaScript and Python reference verifiers, failure mode quick reference, live test vectors, and six open questions for the working groupOpen Question for Working Group
§8 Q1 of the new spec raises the family-wide algorithm negotiation question:
environment.market_state(#9) uses Ed25519 with custom canonical JSON, this draft uses ES256 with standard JWS base64url. Both approaches are valid, but theenvironment.*family probably wants either a per-typealgdeclaration or a unified JWS-only requirement. Happy to discuss with the working group.Friendly-pinging @LembaGang since this draft is a direct response to the "yes, please" in #9 comment 4254720661.