@integraledger/agent-guard 0.9.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,74 @@
1
1
  # @integraledger/agent-guard
2
2
 
3
+ ## 0.10.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 5154cfb: Install one copy of the protocol packages, not two.
8
+
9
+ `lcp-mcp-server` pinned its `@integraledger/lcp-*` dependencies to an exact version while `agent-guard`
10
+ — which it depends on — declares the same packages as peers at a caret range. Those two declarations
11
+ cannot be satisfied by a single copy, so installing both packages resolved the protocol line **twice**:
12
+ once hoisted to satisfy the caret, and once nested under `lcp-mcp-server` to satisfy the exact pin. The
13
+ two halves of one install then read different protocol code, with `instanceof` failing across the seam
14
+ between them.
15
+
16
+ `lcp-mcp-server` now declares those dependencies as a caret at the minor line's zero patch, matching its
17
+ sibling. A tree holding both resolves a single copy, and `npx lcp-mcp` still installs standalone.
18
+
19
+ Nothing about either package's API, behaviour or guarantees changes. Both were correct in isolation; only
20
+ a tree holding both was affected.
21
+
22
+ - ccf4bb4: The runtime table is measured now, not argued.
23
+
24
+ It used to assert that this package works on Bun and Deno because of what the import graph implies — the
25
+ one Node built-in that arrives, `node:crypto`, is polyfilled on both. That was a sound argument and it was
26
+ only ever an argument; nothing ran.
27
+
28
+ Every release now drives the guard's whole decision on Node, Bun and Deno, against the packed tarball
29
+ installed the way you would install it, with the protocol line resolved from npmjs. Both halves are
30
+ asserted on each runtime, because a runtime where the guard refused everything would pass a check that only
31
+ looked for the halt: tampered terms must halt with the signer never reached, and matching terms must sign
32
+ with the signer reached exactly once.
33
+
34
+ Measured on this release: Node 24.19.0, Bun 1.4.0, Deno 2.9.5.
35
+
36
+ The table now separates what is measured from what is reasoned. Workers with `nodejs_compat` and the
37
+ bundler row remain arguments from the import graph and say so, rather than sitting in the same column as
38
+ the rows that ran.
39
+
40
+ ## 0.10.0
41
+
42
+ ### Minor Changes
43
+
44
+ - 06a25ac: Read the whole advertisement, and move to protocol 0.12.0.
45
+
46
+ The peer range was `^0.10.1`, which on a `0.x` version admits only patches — so this guard declared it did
47
+ not support the line every seller now writes, and a tree holding both resolved a second copy of the protocol
48
+ packages to satisfy it. The peers are `^0.12.0` and the build pins 0.12.0 exactly.
49
+
50
+ **The terms URL is no longer read by hand.** `PlacementManifest.termsUrlField` was singular and named one
51
+ path; it is now `termsUrlFields`, plural, and a slot that rides a container the placement owns is declared on
52
+ that container. Reading that by hand here would have been a second implementation of a manifest rule, so the
53
+ locator now comes from the placement's own `extract`, which reconciles every declared slot and refuses two
54
+ that disagree. The reference walk stays this package's own: "integrity carriers only" is a BUYER rule — a
55
+ discovery link locates a standing page and attests nothing — and the placement's reader does not apply it.
56
+
57
+ **`AdvertisedTermsUrl` loses a state, and could not keep it.** `undeclared-at-answering-carrier` existed
58
+ because the singular member could not reach the carrier a §C.4 challenge actually used: the hash answered
59
+ from `accepts[].extra` while the one declared path sat empty inside `extensions`, and reporting that as "no
60
+ terms advertised" would have asserted a silence this reader could not see. With every slot declared and
61
+ reconciled there is no such carrier, so the state is unreachable rather than merely unused, and the §C.4
62
+ challenge now simply reads its URL. `declared-field-empty` becomes `declared-fields-empty` and carries every
63
+ slot it looked at.
64
+
65
+ `lcp_place_reference` takes an optional `termsUrl` — required where the protocol declares a slot and the
66
+ reference is a digest, refused where it declares none — and `lcp_extract_reference` reports the locator
67
+ beside the reference, with its two absences distinguished: a protocol with no slot is not a seller who left
68
+ one empty.
69
+
70
+ Wire identities are unchanged apart from the protocol line itself.
71
+
3
72
  ## 0.9.0
4
73
 
5
74
  **First public release** — Apache-2.0, free forever, no account and no token to install.
package/README.md CHANGED
@@ -59,12 +59,20 @@ no DNS module at all. That much is enforced by the code and is the part worth re
59
59
  ours: `@integraledger/lcp-evidence` re-exports its CAR support from its index, which pulls `multiformats`'
60
60
  Node SHA-2 build, which statically imports `node:crypto`. So:
61
61
 
62
- | Target | Works |
63
- |---|---|
64
- | Node | yes |
65
- | Deno, Bun, Workers with `nodejs_compat` | yes`node:crypto` is polyfilled |
66
- | A bundler honouring `multiformats`' `browser` export condition | yesit maps to the browser SHA-2 build |
67
- | A plain unbundled ESM import in a browser or service worker | **no** |
62
+ | Target | Works | How we know |
63
+ |---|---|---|
64
+ | Node | yes | **measured** — every release runs the guard's whole decision here |
65
+ | Bun | yes | **measured**same run, same assertions |
66
+ | Deno | yes | **measured**same run, same assertions |
67
+ | Workers with `nodejs_compat` | yes `node:crypto` is polyfilled | reasoned from the import graph, not measured |
68
+ | A bundler honouring `multiformats`' `browser` export condition | yes — it maps to the browser SHA-2 build | reasoned from the export conditions, not measured |
69
+ | A plain unbundled ESM import in a browser or service worker | **no** | reasoned — `node:crypto` has nothing to resolve to |
70
+
71
+ The measured rows run against **the packed tarball**, installed the way you would install it, with the
72
+ protocol line resolved from npmjs — not against this repository's own tree. Both halves of the guarantee are
73
+ asserted on each runtime, because a runtime where the guard refused everything would pass a check that only
74
+ looked for the halt: tampered terms must halt with the signer never reached, and matching terms must sign
75
+ with the signer reached exactly once.
68
76
 
69
77
  The guard needs `fetch` and Web Crypto and nothing else of its own. Removing the last hop is an upstream
70
78
  change — a subpath export on `lcp-evidence` so importing one predicate does not drag CAR and `multiformats`
@@ -132,12 +140,20 @@ Four answers are worth stating plainly, because each is a place a friendlier lib
132
140
  ACP/UCP one is contingent on the document, while `ap2`'s rule is a strict subset of `a2a`'s, so **every**
133
141
  AP2 envelope matches both and none is reachable through `parseProposalUniversal`. AP2 is a detect-and-name
134
142
  protocol here; `parseProposalFromAp2Envelope` exists and is called by name.
135
- - **An unlocatable terms URL is reported, not answered.** `legalContextUrl` is a union — `read`,
136
- `no-field-declared`, `declared-field-empty`, or `undeclared-at-answering-carrier` because
137
- `PlacementManifest.termsUrlField` is singular and x402's names a path inside one of its two carriers. A
138
- §C.4-illustrated challenge advertising in `accepts[].extra` really does carry a terms URL, and a bare
139
- `undefined` there would contradict `parseProposalFromChallenge` reading the same bytes. The fix is a
140
- per-alias declaration on the manifest; until it lands the shortfall is named.
143
+ - **An absent terms URL says WHICH absence it is.** `legalContextUrl` is a union — `read`,
144
+ `no-field-declared`, or `declared-fields-empty` because a bare `undefined` conflates two different
145
+ facts. `no-field-declared` is a fact about the PROTOCOL: it has nowhere to put a locator, and no document
146
+ of that protocol can be faulted for lacking one. `declared-fields-empty` is a fact about THIS DOCUMENT:
147
+ the protocol has room and this seller left every declared slot empty. Reporting the second as the first
148
+ would blame a protocol for a seller's silence.
149
+
150
+ It used to carry a fourth state, `undeclared-at-answering-carrier`, and that state is gone because the
151
+ defect requiring it is fixed. The manifest's terms-URL member was singular, so x402 could declare only one
152
+ of its two slots: a §C.4-illustrated challenge advertising in `accepts[].extra` really does carry a terms
153
+ URL, while the single declared path sat empty inside `extensions` — and calling that "no terms advertised"
154
+ would have asserted a silence this reader could not see. The member is plural now, every declared slot is
155
+ read and reconciled, and a slot riding a container the placement owns is declared on that container. There
156
+ is no carrier a declaration fails to reach, so the state is unreachable rather than merely unused.
141
157
  - **Carrier disagreement refuses.** Where a protocol declares more than one carrier, all of them are read
142
158
  and compared. Two different hashes on one document would let a seller advertise different terms to
143
159
  different readers of it, so this is deliberately stricter than the placement adapter's own `extract`,
@@ -77,8 +77,8 @@ export function parseAckReceipt(credential) {
77
77
  const extracted = ackPlacement.extract(credential);
78
78
  if (!("ok" in extracted))
79
79
  throw new Error(`ACK receipt carries no readable LCP reference (${extracted.haltClass}/${extracted.code})`);
80
- if (extracted.value.type !== "sha256")
81
- throw new Error(`ACK legalContext must be a sha256 carrier, got "${extracted.value.type}" — a locator commits to nothing`);
80
+ if (extracted.value.ref.type !== "sha256")
81
+ throw new Error(`ACK legalContext must be a sha256 carrier, got "${extracted.value.ref.type}" — a locator commits to nothing`);
82
82
  const owned = lcpKeys();
83
83
  // `extract` above read the LCP key out of THIS map, so the map is an object and the narrowing cannot
84
84
  // fail. Asserted rather than branched: a defensive `typeof` ternary here would ship an else-arm no input
@@ -86,7 +86,7 @@ export function parseAckReceipt(credential) {
86
86
  const metadata = readAtPath(credential, "credentialSubject.metadata");
87
87
  const siblingRefKeys = Object.keys(metadata).filter((k) => !owned.includes(k));
88
88
  return {
89
- atrHash: extracted.value.value,
89
+ atrHash: extracted.value.ref.value,
90
90
  paymentRequestToken,
91
91
  paymentOptionId,
92
92
  payerDid,
@@ -1 +1 @@
1
- {"version":3,"file":"proposal-ack.js","sourceRoot":"","sources":["../src/proposal-ack.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proposal-ack.js","sourceRoot":"","sources":["../src/proposal-ack.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,7 @@ import type { GateProposal, ProposalContext } from "./proposal.js";
6
6
  * non-integer minor-unit amount.
7
7
  *
8
8
  * `legal_context_url` is required, and the ACP placement manifest DECLARES it as
9
- * `termsUrlField: "metadata.legal_context_url"` — the field this parser demands is a field the placement
9
+ * `termsUrlFields: ["metadata.legal_context_url"]` — the field this parser demands is a field the placement
10
10
  * names, which is what makes the round-trip compose. It is deliberately NOT read from ACP's native
11
11
  * `links[type=terms_of_use]`: that link is the merchant's standing policy page, while this names the ATR
12
12
  * terms document for this transaction, and falling back to it would substitute one for the other.
@@ -20,7 +20,7 @@ const AcpSessionSchema = z.object({
20
20
  * non-integer minor-unit amount.
21
21
  *
22
22
  * `legal_context_url` is required, and the ACP placement manifest DECLARES it as
23
- * `termsUrlField: "metadata.legal_context_url"` — the field this parser demands is a field the placement
23
+ * `termsUrlFields: ["metadata.legal_context_url"]` — the field this parser demands is a field the placement
24
24
  * names, which is what makes the round-trip compose. It is deliberately NOT read from ACP's native
25
25
  * `links[type=terms_of_use]`: that link is the merchant's standing policy page, while this names the ATR
26
26
  * terms document for this transaction, and falling back to it would substitute one for the other.
@@ -81,7 +81,7 @@ export interface Ap2ProposalContext extends ProposalContext {
81
81
  /**
82
82
  * The terms document's locator.
83
83
  *
84
- * AP2's placement is INTEGRITY-ONLY: `AP2_PLACEMENT` declares no `termsUrlField`, because the A2A
84
+ * AP2's placement is INTEGRITY-ONLY: `AP2_PLACEMENT` declares no `termsUrlFields`, because the A2A
85
85
  * `Message.metadata` map holds the reference and AP2 models no terms-URL field anywhere. So unlike ACP
86
86
  * (`metadata.legal_context_url`) and x402 (`extra.legalContextUrl`), the locator cannot come off the wire.
87
87
  * It comes from LCP §2 discovery — the seller's `/.well-known/legal-context.json` — resolved by the
@@ -1 +1 @@
1
- {"version":3,"file":"proposal-ap2.d.ts","sourceRoot":"","sources":["../src/proposal-ap2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEnE;;;;;;;;GAQG;AACH,MAAM,MAAM,OAAO,GACf,uBAAuB,GACvB,uBAAuB,GACvB,+BAA+B,GAC/B,mBAAmB,GACnB,0BAA0B,CAAC;AAE/B,iGAAiG;AACjG,MAAM,WAAW,YAAY;IAC3B,kGAAkG;IAClG,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,6FAA6F;IAC7F,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,4FAA4F;IAC5F,QAAQ,CAAC,YAAY,EAAE,SAAS,OAAO,EAAE,CAAC;IAC1C,oFAAoF;IACpF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,wGAAwG;IACxG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,cAAc,EAAE,YAY5B,CAAC;AAEF,uGAAuG;AACvG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAEvD;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAM5D;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACzD;;;;;;;;OAQG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,yFAAyF;IACzF,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAID;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,OAAO,EACjB,GAAG,EAAE,kBAAkB,GACtB,YAAY,CAoCd"}
1
+ {"version":3,"file":"proposal-ap2.d.ts","sourceRoot":"","sources":["../src/proposal-ap2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEnE;;;;;;;;GAQG;AACH,MAAM,MAAM,OAAO,GACf,uBAAuB,GACvB,uBAAuB,GACvB,+BAA+B,GAC/B,mBAAmB,GACnB,0BAA0B,CAAC;AAE/B,iGAAiG;AACjG,MAAM,WAAW,YAAY;IAC3B,kGAAkG;IAClG,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,6FAA6F;IAC7F,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,4FAA4F;IAC5F,QAAQ,CAAC,YAAY,EAAE,SAAS,OAAO,EAAE,CAAC;IAC1C,oFAAoF;IACpF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,wGAAwG;IACxG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,cAAc,EAAE,YAY5B,CAAC;AAEF,uGAAuG;AACvG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAEvD;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAM5D;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACzD;;;;;;;;OAQG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC;;;;;;;;OAQG;IACH,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,yFAAyF;IACzF,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAID;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,OAAO,EACjB,GAAG,EAAE,kBAAkB,GACtB,YAAY,CAqCd"}
@@ -87,7 +87,8 @@ export function parseProposalFromAp2Envelope(envelope, ctx) {
87
87
  const extracted = ap2Placement.extract(envelope);
88
88
  if (!("ok" in extracted))
89
89
  throw new Error(`AP2 envelope carries no readable LCP reference (${extracted.haltClass}/${extracted.code})`);
90
- const ref = extracted.value;
90
+ // AP2 declares no terms-URL slot, so the advertisement is the reference alone.
91
+ const ref = extracted.value.ref;
91
92
  if (ref.type !== "sha256")
92
93
  throw new Error(`AP2 legalContext must be a sha256 carrier, got "${ref.type}" — the gate compares the advertised ` +
93
94
  "hash against a recomputed one, and a locator commits to nothing");
@@ -1 +1 @@
1
- {"version":3,"file":"proposal-ap2.js","sourceRoot":"","sources":["../src/proposal-ap2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAiChE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC1C,YAAY,EAAE,uBAAuB;IACrC,UAAU,EAAE,+BAA+B;IAC3C,YAAY,EAAE;QACZ,+BAA+B;QAC/B,mBAAmB;QACnB,0BAA0B;KAC3B;IACD,SAAS,EACP,gaAAga;IACla,OAAO,EACL,gRAAgR;CACnR,CAAC;AAEF,uGAAuG;AACvG,MAAM,UAAU,gBAAgB,CAAC,IAAa;IAC5C,OAAO,cAAc,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAa;IACpD,IAAI,gBAAgB,CAAC,IAAI,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,wBAAwB,IAAI,0CAA0C,cAAc,CAAC,UAAU,KAAK;YAClG,kDAAkD,cAAc,CAAC,YAAY,MAAM,cAAc,CAAC,SAAS,EAAE,CAChH,CAAC;AACN,CAAC;AAkCD,MAAM,aAAa,GAAG,UAAU,CAAC,CAAC,mEAAmE;AAErG;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,4BAA4B,CAC1C,QAAiB,EACjB,GAAuB;IAEvB,yGAAyG;IACzG,oDAAoD;IACpD,wBAAwB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAEnC,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,mDAAmD,SAAS,CAAC,SAAS,IAAI,SAAS,CAAC,IAAI,GAAG,CAC5F,CAAC;IACJ,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC;IAC5B,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;QACvB,MAAM,IAAI,KAAK,CACb,mDAAmD,GAAG,CAAC,IAAI,uCAAuC;YAChG,iEAAiE,CACpE,CAAC;IACJ,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,UAAU,CAAC,UAAU,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC;IAC3E,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;QACvC,MAAM,IAAI,KAAK,CACb,qDAAqD,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CACzE,CAAC;IAEJ,0GAA0G;IAC1G,sGAAsG;IACtG,kEAAkE;IAClE,OAAO;QACL,iBAAiB,EAAE,GAAG,CAAC,KAAsB;QAC7C,eAAe,EAAE,GAAG,CAAC,eAAe;QACpC,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,KAAK,EAAE;YACL,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM;YACxB,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI;SACrB;QACD,eAAe,EAAE,GAAG,CAAC,eAAe;KACrC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"proposal-ap2.js","sourceRoot":"","sources":["../src/proposal-ap2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAiChE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAC,MAAM,cAAc,GAAiB;IAC1C,YAAY,EAAE,uBAAuB;IACrC,UAAU,EAAE,+BAA+B;IAC3C,YAAY,EAAE;QACZ,+BAA+B;QAC/B,mBAAmB;QACnB,0BAA0B;KAC3B;IACD,SAAS,EACP,gaAAga;IACla,OAAO,EACL,gRAAgR;CACnR,CAAC;AAEF,uGAAuG;AACvG,MAAM,UAAU,gBAAgB,CAAC,IAAa;IAC5C,OAAO,cAAc,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAa;IACpD,IAAI,gBAAgB,CAAC,IAAI,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,wBAAwB,IAAI,0CAA0C,cAAc,CAAC,UAAU,KAAK;YAClG,kDAAkD,cAAc,CAAC,YAAY,MAAM,cAAc,CAAC,SAAS,EAAE,CAChH,CAAC;AACN,CAAC;AAkCD,MAAM,aAAa,GAAG,UAAU,CAAC,CAAC,mEAAmE;AAErG;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,4BAA4B,CAC1C,QAAiB,EACjB,GAAuB;IAEvB,yGAAyG;IACzG,oDAAoD;IACpD,wBAAwB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAEnC,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,mDAAmD,SAAS,CAAC,SAAS,IAAI,SAAS,CAAC,IAAI,GAAG,CAC5F,CAAC;IACJ,+EAA+E;IAC/E,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC;IAChC,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;QACvB,MAAM,IAAI,KAAK,CACb,mDAAmD,GAAG,CAAC,IAAI,uCAAuC;YAChG,iEAAiE,CACpE,CAAC;IACJ,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,UAAU,CAAC,UAAU,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC;IAC3E,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC;QACvC,MAAM,IAAI,KAAK,CACb,qDAAqD,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CACzE,CAAC;IAEJ,0GAA0G;IAC1G,sGAAsG;IACtG,kEAAkE;IAClE,OAAO;QACL,iBAAiB,EAAE,GAAG,CAAC,KAAsB;QAC7C,eAAe,EAAE,GAAG,CAAC,eAAe;QACpC,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,KAAK,EAAE;YACL,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM;YACxB,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI;SACrB;QACD,eAAe,EAAE,GAAG,CAAC,eAAe;KACrC,CAAC;AACJ,CAAC"}
@@ -24,7 +24,7 @@ import type { GateProposal, ProposalContext } from "./proposal.js";
24
24
  * restating its regex keeps one definition of what an ATR hash is.
25
25
  *
26
26
  * **`legalContextUrl` is the field the placement names.** `placement-mpp` declares
27
- * `termsUrlField: "methodDetails.legalContextUrl"`, so the field this parser demands is the field the
27
+ * `termsUrlFields: ["methodDetails.legalContextUrl"]`, so the field this parser demands is the field the
28
28
  * manifest names — which is what makes the seller's write and this buyer's read compose. There is no
29
29
  * fallback to any other member: MPP defines none that means "these terms", and inventing one would gate the
30
30
  * buyer against a document nobody pointed at.
@@ -53,7 +53,7 @@ const BASE_UNIT_INT = /^[0-9]+$/;
53
53
  * restating its regex keeps one definition of what an ATR hash is.
54
54
  *
55
55
  * **`legalContextUrl` is the field the placement names.** `placement-mpp` declares
56
- * `termsUrlField: "methodDetails.legalContextUrl"`, so the field this parser demands is the field the
56
+ * `termsUrlFields: ["methodDetails.legalContextUrl"]`, so the field this parser demands is the field the
57
57
  * manifest names — which is what makes the seller's write and this buyer's read compose. There is no
58
58
  * fallback to any other member: MPP defines none that means "these terms", and inventing one would gate the
59
59
  * buyer against a document nobody pointed at.
@@ -105,46 +105,34 @@ export declare function matchProtocols(wire: unknown): readonly ProtocolId[];
105
105
  */
106
106
  export declare function detectProtocol(wire: unknown): ProtocolId | undefined;
107
107
  /**
108
- * The terms URL a document advertises at the path its manifest declares — or the reason there is no answer,
109
- * stated rather than folded into an `undefined`.
110
- *
111
- * A UNION, because `string | undefined` conflated three facts and only two of them are absences. The third is
112
- * x402 today: `PlacementManifest.termsUrlField` is SINGULAR, and x402's names a path INSIDE the
113
- * `extensions.legalContext.info` carrier while the challenge LCP v1.38 §C.4 illustrates carries both the
114
- * reference and the URL in `accepts[].extra` instead, which the manifest declares as a `readAlso` alias. Read
115
- * such a challenge and the hash answers from the alias while the declared terms path holds nothing. That is
116
- * not "this seller advertised no terms"; it is "the manifest says nothing about where a terms URL rides on the
117
- * carrier that answered". Returning `undefined` there would assert the seller's silence and
118
- * `parseProposalFromChallenge`, reading the same bytes in the same package, would contradict it.
119
- *
120
- * The gap is owed back to the manifest: a per-alias terms-URL declaration is the fix and it is a protocol-repo
121
- * change. Until it lands this type REPORTS the gap, because a reader that cannot tell two facts apart must say
122
- * which one it cannot tell.
108
+ * The terms URL a document advertises at the slots its manifest declares — or the reason there is no
109
+ * answer, stated rather than folded into an `undefined`.
110
+ *
111
+ * A UNION, because `string | undefined` conflated facts and only some of them are absences.
112
+ *
113
+ * IT USED TO CARRY A FOURTH STATE, and the state is gone because the defect that required it is fixed.
114
+ * `PlacementManifest.termsUrlField` was SINGULAR, so x402 could declare only one of its two slots: read a
115
+ * §C.4 challenge and the hash answered from `accepts[].extra` while the single declared path inside
116
+ * `extensions.legalContext.info` held nothing. Reporting that as "the seller advertised no terms" would
117
+ * have asserted a silence this reader could not see, so it reported `undeclared-at-answering-carrier`
118
+ * instead. `termsUrlFields` is now plural and every slot is read and reconciled, and a slot riding a
119
+ * container the placement owns is declared on the container — so there is no carrier a declaration fails
120
+ * to reach, and the state is unreachable rather than merely unused.
123
121
  */
124
122
  export type AdvertisedTermsUrl =
125
- /** Read from the field the manifest declares. */
123
+ /** Read from a slot the manifest declares. Where several are declared they agreed. */
126
124
  {
127
125
  readonly kind: "read";
128
126
  readonly url: string;
129
127
  }
130
- /** The manifest declares no terms-URL field at all: the protocol has no room for one. */
128
+ /** The manifest declares no terms-URL slot at all: the protocol has no room for one. */
131
129
  | {
132
130
  readonly kind: "no-field-declared";
133
131
  }
134
- /** The manifest declares one, its declaration reaches the answering carrier, and the document leaves it empty. */
132
+ /** Slots are declared and this document leaves every one of them empty. */
135
133
  | {
136
- readonly kind: "declared-field-empty";
137
- readonly field: string;
138
- }
139
- /**
140
- * The manifest's terms-URL path lies INSIDE the canonical carrier's own object, and the reference answered
141
- * from a declared alias instead — so the declaration never reached the carrier this document used. Whether
142
- * the document advertises a terms URL is UNKNOWN to this reader, not answered.
143
- */
144
- | {
145
- readonly kind: "undeclared-at-answering-carrier";
146
- readonly field: string;
147
- readonly answeredAt: string;
134
+ readonly kind: "declared-fields-empty";
135
+ readonly fields: readonly string[];
148
136
  };
149
137
  /** What a protocol document advertises about the terms governing it. */
150
138
  export type AdvertisedTerms = {
@@ -188,7 +176,6 @@ export type AdvertisedTerms = {
188
176
  * throws from the registry rather than answering about some invented namespace.
189
177
  */
190
178
  export declare function readAdvertisedTerms(protocol: ProtocolId, wire: unknown, deployment?: PlacementDeployment): AdvertisedTerms;
191
- /** A parser from one protocol's wire document to the one `GateProposal` every parser produces. */
192
179
  export type ProposalParser = (wire: unknown, ctx: ProposalContext) => GateProposal;
193
180
  /**
194
181
  * Every protocol this build can turn into a complete `GateProposal`, keyed by `ProtocolId`.
@@ -1 +1 @@
1
- {"version":3,"file":"proposal-universal.d.ts","sourceRoot":"","sources":["../src/proposal-universal.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proposal-universal.d.ts","sourceRoot":"","sources":["../src/proposal-universal.ts"],"names":[],"mappings":"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"}
@@ -363,48 +363,21 @@ export function readAdvertisedTerms(protocol, wire, deployment) {
363
363
  const ref = sole.ref;
364
364
  if (ref.type !== "sha256")
365
365
  throw new Error(`${protocol} advertises an lcp:${ref.type}: reference; the gate compares the advertised value against a recomputed record hash, which only a sha256 carrier can be`);
366
+ // The reference walk above is this package's own, because "integrity carriers only" is a BUYER rule:
367
+ // a discovery link locates a standing page and attests nothing, so it is never a candidate here even
368
+ // though the placement will happily read one. The TERMS URL is the placement's, because every rule about
369
+ // it — which slots a protocol declares, that a slot riding a container the placement owns is addressed
370
+ // through that container, that two slots disagreeing is a refusal rather than a preference — belongs to
371
+ // the manifest, and a second implementation here could only agree with it until the day it did not.
372
+ const advertised = placement.extract(wire);
373
+ if ("refused" in advertised)
374
+ throw new Error(`${protocol} document carries no readable advertisement (${advertised.code}): ${advertised.detail ?? ""}`);
366
375
  return {
367
376
  protocol,
368
377
  advertisedAtrHash: ref.value,
369
- legalContextUrl: readTermsUrl(protocol, wire, manifest, sole.path),
378
+ legalContextUrl: advertised.value.termsUrl,
370
379
  };
371
380
  }
372
- /**
373
- * The terms URL at the field the manifest DECLARES — or which of the three absences this is.
374
- *
375
- * `termsUrlField` is a plain dotted path on the manifest: it declares no container of its own, so it is read
376
- * with `readAtPath` rather than through the reference carrier's container. A manifest that omits it (A2A, ACK,
377
- * Visa TAP, Mastercard VI) is stating that its protocol has no room for one — a fact, not a gap.
378
- *
379
- * NOTHING AT THE DECLARED PATH IS TWO DIFFERENT FACTS, and which one it is turns on where the reference
380
- * answered from. `termsUrlField` is declared once, beside the canonical `field`; a `readAlso` alias carries no
381
- * terms-URL declaration of its own. So when the declared path is nested INSIDE the canonical field — x402's
382
- * `extensions.legalContext.info.legalContextUrl` inside `extensions.legalContext.info` — and the reference
383
- * answered from an alias instead, the manifest's declaration was scoped to a carrier this document did not
384
- * use, and its emptiness says nothing about the document. When the declared path is a SIBLING of the canonical
385
- * field (ACP's `metadata.legal_context_url`, MPP's `methodDetails.legalContextUrl`), it is reachable whichever
386
- * carrier answered, and empty means empty.
387
- *
388
- * `answeredAt` is the path the reconciled reference was read from. `carrierSlots` puts the canonical field
389
- * first and `integrityHits` preserves that order, so it differs from `manifest.field` exactly when the
390
- * canonical carrier did not answer.
391
- */
392
- function readTermsUrl(protocol, doc, manifest, answeredAt) {
393
- const field = manifest.termsUrlField;
394
- if (field === undefined)
395
- return { kind: "no-field-declared" };
396
- const raw = readAtPath(doc, field);
397
- if (raw === undefined)
398
- return answeredAt !== manifest.field &&
399
- field.startsWith(`${manifest.field}.`)
400
- ? { kind: "undeclared-at-answering-carrier", field, answeredAt }
401
- : { kind: "declared-field-empty", field };
402
- if (typeof raw !== "string")
403
- throw new Error(`${protocol} ${field} is not a string: ${JSON.stringify(raw)}`);
404
- if (!raw.startsWith("https://"))
405
- throw new Error(`legalContextUrl must be HTTPS: ${raw}`);
406
- return { kind: "read", url: raw };
407
- }
408
381
  /**
409
382
  * Every protocol this build can turn into a complete `GateProposal`, keyed by `ProtocolId`.
410
383
  *
@@ -1 +1 @@
1
- {"version":3,"file":"proposal-universal.js","sourceRoot":"","sources":["../src/proposal-universal.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proposal-universal.js","sourceRoot":"","sources":["../src/proposal-universal.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integraledger/agent-guard",
3
- "version": "0.9.0",
3
+ "version": "0.10.1",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -28,28 +28,29 @@
28
28
  "zod": "4.4.3"
29
29
  },
30
30
  "peerDependencies": {
31
- "@integraledger/lcp-authority": "^0.10.1",
32
- "@integraledger/lcp-binding-core": "^0.10.1",
33
- "@integraledger/lcp-discovery": "^0.10.1",
34
- "@integraledger/lcp-evidence": "^0.10.1",
35
- "@integraledger/lcp-kernel": "^0.10.1",
36
- "@integraledger/lcp-placement-ack": "^0.10.1",
37
- "@integraledger/lcp-placement-ap2": "^0.10.1",
38
- "@integraledger/lcp-placements": "^0.10.1",
39
- "@integraledger/lcp-verify": "^0.10.1"
31
+ "@integraledger/lcp-authority": "^0.12.0",
32
+ "@integraledger/lcp-binding-core": "^0.12.0",
33
+ "@integraledger/lcp-discovery": "^0.12.0",
34
+ "@integraledger/lcp-evidence": "^0.12.0",
35
+ "@integraledger/lcp-kernel": "^0.12.0",
36
+ "@integraledger/lcp-placement-ack": "^0.12.0",
37
+ "@integraledger/lcp-placement-ap2": "^0.12.0",
38
+ "@integraledger/lcp-placements": "^0.12.0",
39
+ "@integraledger/lcp-verify": "^0.12.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@integraledger/lcp-authority": "0.10.1",
43
- "@integraledger/lcp-binding-core": "0.10.1",
44
- "@integraledger/lcp-discovery": "0.10.1",
45
- "@integraledger/lcp-evidence": "0.10.1",
46
- "@integraledger/lcp-kernel": "0.10.1",
47
- "@integraledger/lcp-placement-ack": "0.10.1",
48
- "@integraledger/lcp-placement-acp": "0.10.1",
49
- "@integraledger/lcp-placement-ap2": "0.10.1",
50
- "@integraledger/lcp-placements": "0.10.1",
51
- "@integraledger/lcp-verify": "0.10.1",
42
+ "@integraledger/lcp-authority": "0.12.2",
43
+ "@integraledger/lcp-binding-core": "0.12.2",
44
+ "@integraledger/lcp-discovery": "0.12.2",
45
+ "@integraledger/lcp-evidence": "0.12.2",
46
+ "@integraledger/lcp-kernel": "0.12.2",
47
+ "@integraledger/lcp-placement-ack": "0.12.2",
48
+ "@integraledger/lcp-placement-acp": "0.12.2",
49
+ "@integraledger/lcp-placement-ap2": "0.12.2",
50
+ "@integraledger/lcp-placements": "0.12.2",
51
+ "@integraledger/lcp-verify": "0.12.2",
52
52
  "@types/node": "24.13.3",
53
+ "fast-check": "4.9.0",
53
54
  "vitest": "4.1.10"
54
55
  },
55
56
  "license": "Apache-2.0",
@@ -129,9 +129,9 @@ export function parseAckReceipt(credential: unknown): AckReceiptFacts {
129
129
  throw new Error(
130
130
  `ACK receipt carries no readable LCP reference (${extracted.haltClass}/${extracted.code})`,
131
131
  );
132
- if (extracted.value.type !== "sha256")
132
+ if (extracted.value.ref.type !== "sha256")
133
133
  throw new Error(
134
- `ACK legalContext must be a sha256 carrier, got "${extracted.value.type}" — a locator commits to nothing`,
134
+ `ACK legalContext must be a sha256 carrier, got "${extracted.value.ref.type}" — a locator commits to nothing`,
135
135
  );
136
136
 
137
137
  const owned = lcpKeys();
@@ -147,7 +147,7 @@ export function parseAckReceipt(credential: unknown): AckReceiptFacts {
147
147
  );
148
148
 
149
149
  return {
150
- atrHash: extracted.value.value as `0x${string}`,
150
+ atrHash: extracted.value.ref.value as `0x${string}`,
151
151
  paymentRequestToken,
152
152
  paymentOptionId,
153
153
  payerDid,
@@ -23,7 +23,7 @@ const AcpSessionSchema = z.object({
23
23
  * non-integer minor-unit amount.
24
24
  *
25
25
  * `legal_context_url` is required, and the ACP placement manifest DECLARES it as
26
- * `termsUrlField: "metadata.legal_context_url"` — the field this parser demands is a field the placement
26
+ * `termsUrlFields: ["metadata.legal_context_url"]` — the field this parser demands is a field the placement
27
27
  * names, which is what makes the round-trip compose. It is deliberately NOT read from ACP's native
28
28
  * `links[type=terms_of_use]`: that link is the merchant's standing policy page, while this names the ATR
29
29
  * terms document for this transaction, and falling back to it would substitute one for the other.
@@ -114,7 +114,7 @@ export interface Ap2ProposalContext extends ProposalContext {
114
114
  /**
115
115
  * The terms document's locator.
116
116
  *
117
- * AP2's placement is INTEGRITY-ONLY: `AP2_PLACEMENT` declares no `termsUrlField`, because the A2A
117
+ * AP2's placement is INTEGRITY-ONLY: `AP2_PLACEMENT` declares no `termsUrlFields`, because the A2A
118
118
  * `Message.metadata` map holds the reference and AP2 models no terms-URL field anywhere. So unlike ACP
119
119
  * (`metadata.legal_context_url`) and x402 (`extra.legalContextUrl`), the locator cannot come off the wire.
120
120
  * It comes from LCP §2 discovery — the seller's `/.well-known/legal-context.json` — resolved by the
@@ -166,7 +166,8 @@ export function parseProposalFromAp2Envelope(
166
166
  throw new Error(
167
167
  `AP2 envelope carries no readable LCP reference (${extracted.haltClass}/${extracted.code})`,
168
168
  );
169
- const ref = extracted.value;
169
+ // AP2 declares no terms-URL slot, so the advertisement is the reference alone.
170
+ const ref = extracted.value.ref;
170
171
  if (ref.type !== "sha256")
171
172
  throw new Error(
172
173
  `AP2 legalContext must be a sha256 carrier, got "${ref.type}" — the gate compares the advertised ` +
@@ -57,7 +57,7 @@ const BASE_UNIT_INT = /^[0-9]+$/;
57
57
  * restating its regex keeps one definition of what an ATR hash is.
58
58
  *
59
59
  * **`legalContextUrl` is the field the placement names.** `placement-mpp` declares
60
- * `termsUrlField: "methodDetails.legalContextUrl"`, so the field this parser demands is the field the
60
+ * `termsUrlFields: ["methodDetails.legalContextUrl"]`, so the field this parser demands is the field the
61
61
  * manifest names — which is what makes the seller's write and this buyer's read compose. There is no
62
62
  * fallback to any other member: MPP defines none that means "these terms", and inventing one would gate the
63
63
  * buyer against a document nobody pointed at.
@@ -332,38 +332,29 @@ export function detectProtocol(wire: unknown): ProtocolId | undefined {
332
332
  // ---------------------------------------------------------------------------------------------------------
333
333
 
334
334
  /**
335
- * The terms URL a document advertises at the path its manifest declares — or the reason there is no answer,
336
- * stated rather than folded into an `undefined`.
337
- *
338
- * A UNION, because `string | undefined` conflated three facts and only two of them are absences. The third is
339
- * x402 today: `PlacementManifest.termsUrlField` is SINGULAR, and x402's names a path INSIDE the
340
- * `extensions.legalContext.info` carrier while the challenge LCP v1.38 §C.4 illustrates carries both the
341
- * reference and the URL in `accepts[].extra` instead, which the manifest declares as a `readAlso` alias. Read
342
- * such a challenge and the hash answers from the alias while the declared terms path holds nothing. That is
343
- * not "this seller advertised no terms"; it is "the manifest says nothing about where a terms URL rides on the
344
- * carrier that answered". Returning `undefined` there would assert the seller's silence and
345
- * `parseProposalFromChallenge`, reading the same bytes in the same package, would contradict it.
346
- *
347
- * The gap is owed back to the manifest: a per-alias terms-URL declaration is the fix and it is a protocol-repo
348
- * change. Until it lands this type REPORTS the gap, because a reader that cannot tell two facts apart must say
349
- * which one it cannot tell.
335
+ * The terms URL a document advertises at the slots its manifest declares — or the reason there is no
336
+ * answer, stated rather than folded into an `undefined`.
337
+ *
338
+ * A UNION, because `string | undefined` conflated facts and only some of them are absences.
339
+ *
340
+ * IT USED TO CARRY A FOURTH STATE, and the state is gone because the defect that required it is fixed.
341
+ * `PlacementManifest.termsUrlField` was SINGULAR, so x402 could declare only one of its two slots: read a
342
+ * §C.4 challenge and the hash answered from `accepts[].extra` while the single declared path inside
343
+ * `extensions.legalContext.info` held nothing. Reporting that as "the seller advertised no terms" would
344
+ * have asserted a silence this reader could not see, so it reported `undeclared-at-answering-carrier`
345
+ * instead. `termsUrlFields` is now plural and every slot is read and reconciled, and a slot riding a
346
+ * container the placement owns is declared on the container — so there is no carrier a declaration fails
347
+ * to reach, and the state is unreachable rather than merely unused.
350
348
  */
351
349
  export type AdvertisedTermsUrl =
352
- /** Read from the field the manifest declares. */
350
+ /** Read from a slot the manifest declares. Where several are declared they agreed. */
353
351
  | { readonly kind: "read"; readonly url: string }
354
- /** The manifest declares no terms-URL field at all: the protocol has no room for one. */
352
+ /** The manifest declares no terms-URL slot at all: the protocol has no room for one. */
355
353
  | { readonly kind: "no-field-declared" }
356
- /** The manifest declares one, its declaration reaches the answering carrier, and the document leaves it empty. */
357
- | { readonly kind: "declared-field-empty"; readonly field: string }
358
- /**
359
- * The manifest's terms-URL path lies INSIDE the canonical carrier's own object, and the reference answered
360
- * from a declared alias instead — so the declaration never reached the carrier this document used. Whether
361
- * the document advertises a terms URL is UNKNOWN to this reader, not answered.
362
- */
354
+ /** Slots are declared and this document leaves every one of them empty. */
363
355
  | {
364
- readonly kind: "undeclared-at-answering-carrier";
365
- readonly field: string;
366
- readonly answeredAt: string;
356
+ readonly kind: "declared-fields-empty";
357
+ readonly fields: readonly string[];
367
358
  };
368
359
 
369
360
  /** What a protocol document advertises about the terms governing it. */
@@ -534,61 +525,25 @@ export function readAdvertisedTerms(
534
525
  `${protocol} advertises an lcp:${ref.type}: reference; the gate compares the advertised value against a recomputed record hash, which only a sha256 carrier can be`,
535
526
  );
536
527
 
528
+ // The reference walk above is this package's own, because "integrity carriers only" is a BUYER rule:
529
+ // a discovery link locates a standing page and attests nothing, so it is never a candidate here even
530
+ // though the placement will happily read one. The TERMS URL is the placement's, because every rule about
531
+ // it — which slots a protocol declares, that a slot riding a container the placement owns is addressed
532
+ // through that container, that two slots disagreeing is a refusal rather than a preference — belongs to
533
+ // the manifest, and a second implementation here could only agree with it until the day it did not.
534
+ const advertised = placement.extract(wire);
535
+ if ("refused" in advertised)
536
+ throw new Error(
537
+ `${protocol} document carries no readable advertisement (${advertised.code}): ${advertised.detail ?? ""}`,
538
+ );
539
+
537
540
  return {
538
541
  protocol,
539
542
  advertisedAtrHash: ref.value as `0x${string}`,
540
- legalContextUrl: readTermsUrl(protocol, wire, manifest, sole.path),
543
+ legalContextUrl: advertised.value.termsUrl,
541
544
  };
542
545
  }
543
546
 
544
- /**
545
- * The terms URL at the field the manifest DECLARES — or which of the three absences this is.
546
- *
547
- * `termsUrlField` is a plain dotted path on the manifest: it declares no container of its own, so it is read
548
- * with `readAtPath` rather than through the reference carrier's container. A manifest that omits it (A2A, ACK,
549
- * Visa TAP, Mastercard VI) is stating that its protocol has no room for one — a fact, not a gap.
550
- *
551
- * NOTHING AT THE DECLARED PATH IS TWO DIFFERENT FACTS, and which one it is turns on where the reference
552
- * answered from. `termsUrlField` is declared once, beside the canonical `field`; a `readAlso` alias carries no
553
- * terms-URL declaration of its own. So when the declared path is nested INSIDE the canonical field — x402's
554
- * `extensions.legalContext.info.legalContextUrl` inside `extensions.legalContext.info` — and the reference
555
- * answered from an alias instead, the manifest's declaration was scoped to a carrier this document did not
556
- * use, and its emptiness says nothing about the document. When the declared path is a SIBLING of the canonical
557
- * field (ACP's `metadata.legal_context_url`, MPP's `methodDetails.legalContextUrl`), it is reachable whichever
558
- * carrier answered, and empty means empty.
559
- *
560
- * `answeredAt` is the path the reconciled reference was read from. `carrierSlots` puts the canonical field
561
- * first and `integrityHits` preserves that order, so it differs from `manifest.field` exactly when the
562
- * canonical carrier did not answer.
563
- */
564
- function readTermsUrl(
565
- protocol: ProtocolId,
566
- doc: unknown,
567
- manifest: PlacementManifest,
568
- answeredAt: string,
569
- ): AdvertisedTermsUrl {
570
- const field = manifest.termsUrlField;
571
- if (field === undefined) return { kind: "no-field-declared" };
572
- const raw = readAtPath(doc, field);
573
- if (raw === undefined)
574
- return answeredAt !== manifest.field &&
575
- field.startsWith(`${manifest.field}.`)
576
- ? { kind: "undeclared-at-answering-carrier", field, answeredAt }
577
- : { kind: "declared-field-empty", field };
578
- if (typeof raw !== "string")
579
- throw new Error(
580
- `${protocol} ${field} is not a string: ${JSON.stringify(raw)}`,
581
- );
582
- if (!raw.startsWith("https://"))
583
- throw new Error(`legalContextUrl must be HTTPS: ${raw}`);
584
- return { kind: "read", url: raw };
585
- }
586
-
587
- // ---------------------------------------------------------------------------------------------------------
588
- // The universal gate parse
589
- // ---------------------------------------------------------------------------------------------------------
590
-
591
- /** A parser from one protocol's wire document to the one `GateProposal` every parser produces. */
592
547
  export type ProposalParser = (
593
548
  wire: unknown,
594
549
  ctx: ProposalContext,