|
| 1 | +# ADR 0009 — Typed-reference schema for composition (Foxbook ↔ Concordia ↔ Sanctuary) |
| 2 | + |
| 3 | +**Number:** 0009 |
| 4 | +**Date:** 2026-05-04 |
| 5 | +**Status:** under-public-discussion |
| 6 | +**Supersedes:** — |
| 7 | +**Superseded by:** — |
| 8 | +**Related:** ADR 0004 (tl-leaf schema evolution), ADR 0005 (canonical bytes once), ADR 0006 (protocol-not-marketplace), ADR 0008 (stable-mode maintenance posture) |
| 9 | + |
| 10 | +## Context |
| 11 | + |
| 12 | +[A2A Discussion #1803](https://github.com/a2aproject/A2A/discussions/1803) crystallized a three-layer substrate stack with concrete cross-implementation reference candidates: |
| 13 | + |
| 14 | +- **Identity** — Foxbook (transparency log) |
| 15 | +- **Evidence** — Concordia v0.4.0 (attestation envelopes) |
| 16 | +- **Verdict** — Sanctuary Castle Architecture v1.2 (gateway policy) |
| 17 | + |
| 18 | +[@eriknewton's 2026-05-04 comment](https://github.com/a2aproject/A2A/discussions/1803#discussioncomment-13655678) proposed the natural integration: a Concordia envelope carries a **typed reference** to a Foxbook leaf, which Sanctuary's verdict-layer anchors on. This composition uses Foxbook's *existing* surface — no Foxbook protocol changes required — so it composes cleanly with [ADR 0008](0008-stable-mode-maintenance-posture.md)'s feature freeze. |
| 19 | + |
| 20 | +Specifying the typed-reference shape is a **composition decision** that affects multiple implementations. Per [ADR 0006](0006-protocol-not-marketplace.md)'s protocol-not-marketplace stance, the spec belongs in the open: reviewable, archival, multi-party. The active spec venue is: |
| 21 | + |
| 22 | +**`<DISCUSSION_URL>`** |
| 23 | + |
| 24 | +This ADR is the Foxbook-side ratification record. It is **`under-public-discussion`** until consensus lands in the thread; once schema v1.0 is agreed, this ADR is updated **in-place** with the ratified shape and `Status: accepted`. A new ADR (0010) is not opened for the ratification — the thread is the discussion record, this ADR is the decision record. |
| 25 | + |
| 26 | +## Decision |
| 27 | + |
| 28 | +### Schema (placeholder pending public consensus) |
| 29 | + |
| 30 | +The strawman from `<DISCUSSION_URL>` is reproduced here for traceability. The ratified schema lands in this section once the thread reaches consensus. |
| 31 | + |
| 32 | +```json |
| 33 | +{ |
| 34 | + "tl_url": "https://transparency.foxbook.dev", |
| 35 | + "leaf_index": 42, |
| 36 | + "tl_leaf_canonical_hash": "<64-char lowercase hex SHA-256>", |
| 37 | + "verified_signing_key_hex": "<64-char lowercase hex Ed25519 public key>", |
| 38 | + |
| 39 | + "sth_at_verify_time": { |
| 40 | + "tree_size": 100, |
| 41 | + "root_hash": "<64-char lowercase hex>", |
| 42 | + "timestamp": "<ISO-8601>" |
| 43 | + }, |
| 44 | + "sth_signature": "<compact-JWS EdDSA, three base64url segments>" |
| 45 | +} |
| 46 | +``` |
| 47 | + |
| 48 | +Required: `tl_url`, `leaf_index`, `tl_leaf_canonical_hash`, `verified_signing_key_hex`. Optional: `sth_at_verify_time`, `sth_signature`. Versioning + evolution rules per [ADR 0004](0004-tl-leaf-schema-evolution.md) precedent (additive within v1.x; breaking changes to v2.0). |
| 49 | + |
| 50 | +### Why these fields |
| 51 | + |
| 52 | +- **`tl_url`** — explicit log identifier. Forward-compat with multi-vendor federated logs. |
| 53 | +- **`leaf_index`** — log position. Combined with `tl_url`, uniquely identifies the leaf. |
| 54 | +- **`tl_leaf_canonical_hash`** — load-bearing for log-fork detection. The verdict layer recomputes the SHA-256 of the canonical-bytes leaf preimage and compares; any divergence is a log-integrity violation. Per [ADR 0005](0005-canonical-on-both-sides.md), canonicalization is via `canonical.ts` on the raw object — never on a storage round-trip. |
| 55 | +- **`verified_signing_key_hex`** — the active Ed25519 signing key surfaced by Foxbook SDK v0.2.0's `verifyAgentCard`. The verdict-layer uses this to verify the AgentCard's JWS signature directly without a second by-handle lookup. |
| 56 | +- **`sth_at_verify_time` / `sth_signature`** — temporal anchor + offline verification. Optional because verdict-layers that always re-fetch live can ignore them; mandatory-ish for verdict-layers wanting offline / point-in-time semantics. |
| 57 | + |
| 58 | +### What this ADR does NOT decide |
| 59 | + |
| 60 | +- **Verdict-layer policy**. How Sanctuary (or any verdict-layer impl) handles staleness, revocation between assert-time and consume-time, signing-key rotation between assert-time and consume-time — out of scope. The typed-reference is rich enough to support strict-freshness, point-in-time-anchor, and hybrid policies; the verdict-layer chooses based on its threat model. |
| 61 | +- **Concordia envelope shape**. How the typed reference embeds inside a Concordia attestation envelope (peer field vs nested vs CTEF-shape) is Concordia's call. |
| 62 | +- **AgentCard JWS verification**. The typed reference asserts "this signing key was active at verify-time per Foxbook"; whether the AgentCard was JWS-signed with that key is a Sanctuary-side check, not encoded in the typed reference. |
| 63 | + |
| 64 | +These deliberate omissions keep the typed reference minimal + composable. Adding them would couple it to specific verdict-layer or evidence-layer choices. |
| 65 | + |
| 66 | +## Enforcement |
| 67 | + |
| 68 | +- Schema-bump PRs to update this ADR's content (post-consensus) reference the discussion thread in the PR body and link the specific comment(s) where consensus crystallized. |
| 69 | +- This ADR moves from `under-public-discussion` → `accepted` only when: |
| 70 | + - The discussion thread has explicit consensus from at least the Foxbook side and the Concordia/Sanctuary side (eriknewton). |
| 71 | + - The schema is reproduced verbatim in the "Decision" section above (replacing the strawman). |
| 72 | + - At least one reference implementation (Concordia v0.5.x or equivalent) has demonstrated the typed reference round-trips cleanly against a live Foxbook leaf. |
| 73 | +- Schema evolution post-acceptance follows ADR 0004 precedent: additive within v1.x lands as inline updates here; breaking changes require a v2.0 schema and a new ADR (likely 0010+) explaining the migration. |
| 74 | + |
| 75 | +## Consequences |
| 76 | + |
| 77 | +- **Foxbook protocol surface is unchanged**. ADR 0008's feature freeze is preserved. Foxbook's existing tl-leaf v1.2 + SDK v0.2.0 expose everything the typed reference needs. |
| 78 | +- **Cross-implementation reference cycle is materially strengthened**. Per [ADR 0006](0006-protocol-not-marketplace.md) §4, named cross-impl references are the load-bearing co-option-defense indicator. Concordia + Sanctuary citing Foxbook by name + canonical-bytes shape is exactly that. |
| 79 | +- **The catalog at [`docs/INTEGRATIONS.md`](../INTEGRATIONS.md) tracks active compositions**. The Concordia + Sanctuary entry is the first; future compositions follow the same pattern. |
| 80 | +- **`docs/COMPOSE-WITH-FOXBOOK.md`** is the path-of-engagement for future integrators. Points at this ADR + the active discussion thread. |
| 81 | + |
| 82 | +## Alternatives considered |
| 83 | + |
| 84 | +- **Spec offline between Foxbook and Concordia/Sanctuary maintainers**. Considered briefly (per cloakmaster's 2026-05-04T17:47Z reply on #1803) but rejected in favor of public spec — reviewable, archival, multi-party, and consistent with ADR 0006's protocol-not-marketplace stance. |
| 85 | +- **Embed full leaf bytes in the typed reference**. Rejected: increases receipt size + couples consumers to leaf-shape changes. The hash-pointer pattern (citing `tl_leaf_canonical_hash` and resolving via `tl_url + leaf_index`) is more durable. |
| 86 | +- **Skip `tl_leaf_canonical_hash`; trust the live log**. Rejected: removes the ability to detect log forks at receipt-consumption time. The verdict-layer can re-fetch the live leaf; comparing its hash against the typed reference's hash is the integrity check. |
| 87 | +- **Make `sth_at_verify_time` + `sth_signature` required**. Rejected (for v1.0): pushes complexity onto integrators that don't need offline / temporal-anchor semantics. May be promoted in v2.0 if practice shows the optional path is rarely chosen. |
| 88 | + |
| 89 | +## When this rule can be violated |
| 90 | + |
| 91 | +ADR 0009 itself can be amended in-place pre-acceptance (the strawman evolves with the thread). Post-acceptance, schema evolution follows ADR 0004 precedent (additive within v1.x; breaking changes to v2.0 + a new ADR). |
| 92 | + |
| 93 | +The composition pattern itself (typed-reference, embedded inside a higher-layer envelope) can be superseded by a different composition pattern in a future ADR (0010+) if the cross-impl group decides a different shape is structurally better. ADR 0009 is silent on whether typed-reference is the only valid composition shape — see `docs/COMPOSE-WITH-FOXBOOK.md` for other shapes (wrapping, referencing-without-embedding, direct API integration). |
| 94 | + |
| 95 | +## Verified |
| 96 | + |
| 97 | +- The strawman schema in this ADR matches the strawman posted at `<DISCUSSION_URL>` first-comment as of `<DATE_POSTED>`. |
| 98 | +- Foxbook SDK v0.2.0 (`@foxbook/sdk-claim@0.2.0`) surfaces `verified_signing_key_hex` + `leaf_index` on the `verified` branch of `verifyAgentCard`. Verified by `npm view @foxbook/sdk-claim`. |
| 99 | +- tl-leaf v1.2's canonical-bytes shape (per [ADR 0004 addendum-3](0004-tl-leaf-schema-evolution.md)) is what `tl_leaf_canonical_hash` references. Cross-language byte-match validation in [`schemas/crypto-test-vectors.json`](../../schemas/crypto-test-vectors.json). |
| 100 | +- Concordia v0.4.0 and Sanctuary Castle Architecture v1.2 are the named cross-impl reference candidates per [@eriknewton's 2026-05-04 comment](https://github.com/a2aproject/A2A/discussions/1803#discussioncomment-13655678) on A2A Discussion #1803. |
0 commit comments