@agenticprimitives/fabric 0.0.0-alpha.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.
Files changed (201) hide show
  1. package/CLAUDE.md +67 -0
  2. package/LICENSE +21 -0
  3. package/README.md +21 -0
  4. package/dist/case-machine.d.ts +76 -0
  5. package/dist/case-machine.d.ts.map +1 -0
  6. package/dist/case-machine.js +83 -0
  7. package/dist/case-machine.js.map +1 -0
  8. package/dist/client/index.d.ts +114 -0
  9. package/dist/client/index.d.ts.map +1 -0
  10. package/dist/client/index.js +76 -0
  11. package/dist/client/index.js.map +1 -0
  12. package/dist/cloudflare/authority-verdict-cache.d.ts +27 -0
  13. package/dist/cloudflare/authority-verdict-cache.d.ts.map +1 -0
  14. package/dist/cloudflare/authority-verdict-cache.js +66 -0
  15. package/dist/cloudflare/authority-verdict-cache.js.map +1 -0
  16. package/dist/cloudflare/channel-store.d.ts +61 -0
  17. package/dist/cloudflare/channel-store.d.ts.map +1 -0
  18. package/dist/cloudflare/channel-store.js +124 -0
  19. package/dist/cloudflare/channel-store.js.map +1 -0
  20. package/dist/cloudflare/exchange-store.d.ts +16 -0
  21. package/dist/cloudflare/exchange-store.d.ts.map +1 -0
  22. package/dist/cloudflare/exchange-store.js +45 -0
  23. package/dist/cloudflare/exchange-store.js.map +1 -0
  24. package/dist/cloudflare/gateway-tools.d.ts +28 -0
  25. package/dist/cloudflare/gateway-tools.d.ts.map +1 -0
  26. package/dist/cloudflare/gateway-tools.js +45 -0
  27. package/dist/cloudflare/gateway-tools.js.map +1 -0
  28. package/dist/cloudflare/index.d.ts +13 -0
  29. package/dist/cloudflare/index.d.ts.map +1 -0
  30. package/dist/cloudflare/index.js +20 -0
  31. package/dist/cloudflare/index.js.map +1 -0
  32. package/dist/cloudflare/orchestration-runtime.d.ts +28 -0
  33. package/dist/cloudflare/orchestration-runtime.d.ts.map +1 -0
  34. package/dist/cloudflare/orchestration-runtime.js +35 -0
  35. package/dist/cloudflare/orchestration-runtime.js.map +1 -0
  36. package/dist/cloudflare/outbox-store.d.ts +24 -0
  37. package/dist/cloudflare/outbox-store.d.ts.map +1 -0
  38. package/dist/cloudflare/outbox-store.js +42 -0
  39. package/dist/cloudflare/outbox-store.js.map +1 -0
  40. package/dist/cloudflare/principal-gateway-do.d.ts +234 -0
  41. package/dist/cloudflare/principal-gateway-do.d.ts.map +1 -0
  42. package/dist/cloudflare/principal-gateway-do.js +369 -0
  43. package/dist/cloudflare/principal-gateway-do.js.map +1 -0
  44. package/dist/cloudflare/provenance-store.d.ts +9 -0
  45. package/dist/cloudflare/provenance-store.d.ts.map +1 -0
  46. package/dist/cloudflare/provenance-store.js +36 -0
  47. package/dist/cloudflare/provenance-store.js.map +1 -0
  48. package/dist/cloudflare/receipt-signer.d.ts +26 -0
  49. package/dist/cloudflare/receipt-signer.d.ts.map +1 -0
  50. package/dist/cloudflare/receipt-signer.js +69 -0
  51. package/dist/cloudflare/receipt-signer.js.map +1 -0
  52. package/dist/cloudflare/request-id-ledger.d.ts +13 -0
  53. package/dist/cloudflare/request-id-ledger.d.ts.map +1 -0
  54. package/dist/cloudflare/request-id-ledger.js +38 -0
  55. package/dist/cloudflare/request-id-ledger.js.map +1 -0
  56. package/dist/cloudflare/sql-vault.d.ts +10 -0
  57. package/dist/cloudflare/sql-vault.d.ts.map +1 -0
  58. package/dist/cloudflare/sql-vault.js +98 -0
  59. package/dist/cloudflare/sql-vault.js.map +1 -0
  60. package/dist/communicative-act.d.ts +47 -0
  61. package/dist/communicative-act.d.ts.map +1 -0
  62. package/dist/communicative-act.js +36 -0
  63. package/dist/communicative-act.js.map +1 -0
  64. package/dist/delivery-envelope.d.ts +38 -0
  65. package/dist/delivery-envelope.d.ts.map +1 -0
  66. package/dist/delivery-envelope.js +43 -0
  67. package/dist/delivery-envelope.js.map +1 -0
  68. package/dist/exchange-record.d.ts +131 -0
  69. package/dist/exchange-record.d.ts.map +1 -0
  70. package/dist/exchange-record.js +25 -0
  71. package/dist/exchange-record.js.map +1 -0
  72. package/dist/exchange-reducer.d.ts +25 -0
  73. package/dist/exchange-reducer.d.ts.map +1 -0
  74. package/dist/exchange-reducer.js +108 -0
  75. package/dist/exchange-reducer.js.map +1 -0
  76. package/dist/exchange-state.d.ts +56 -0
  77. package/dist/exchange-state.d.ts.map +1 -0
  78. package/dist/exchange-state.js +81 -0
  79. package/dist/exchange-state.js.map +1 -0
  80. package/dist/gateway-surface.d.ts +24 -0
  81. package/dist/gateway-surface.d.ts.map +1 -0
  82. package/dist/gateway-surface.js +33 -0
  83. package/dist/gateway-surface.js.map +1 -0
  84. package/dist/inbox-doc.d.ts +32 -0
  85. package/dist/inbox-doc.d.ts.map +1 -0
  86. package/dist/inbox-doc.js +57 -0
  87. package/dist/inbox-doc.js.map +1 -0
  88. package/dist/inbox-projection.d.ts +15 -0
  89. package/dist/inbox-projection.d.ts.map +1 -0
  90. package/dist/inbox-projection.js +28 -0
  91. package/dist/inbox-projection.js.map +1 -0
  92. package/dist/index.d.ts +19 -0
  93. package/dist/index.d.ts.map +1 -0
  94. package/dist/index.js +30 -0
  95. package/dist/index.js.map +1 -0
  96. package/dist/interactions/audited.d.ts +12 -0
  97. package/dist/interactions/audited.d.ts.map +1 -0
  98. package/dist/interactions/audited.js +67 -0
  99. package/dist/interactions/audited.js.map +1 -0
  100. package/dist/interactions/builders.d.ts +24 -0
  101. package/dist/interactions/builders.d.ts.map +1 -0
  102. package/dist/interactions/builders.js +48 -0
  103. package/dist/interactions/builders.js.map +1 -0
  104. package/dist/interactions/cards.d.ts +32 -0
  105. package/dist/interactions/cards.d.ts.map +1 -0
  106. package/dist/interactions/cards.js +20 -0
  107. package/dist/interactions/cards.js.map +1 -0
  108. package/dist/interactions/index.d.ts +15 -0
  109. package/dist/interactions/index.d.ts.map +1 -0
  110. package/dist/interactions/index.js +23 -0
  111. package/dist/interactions/index.js.map +1 -0
  112. package/dist/interactions/machine.d.ts +19 -0
  113. package/dist/interactions/machine.d.ts.map +1 -0
  114. package/dist/interactions/machine.js +31 -0
  115. package/dist/interactions/machine.js.map +1 -0
  116. package/dist/interactions/mandates.d.ts +64 -0
  117. package/dist/interactions/mandates.d.ts.map +1 -0
  118. package/dist/interactions/mandates.js +62 -0
  119. package/dist/interactions/mandates.js.map +1 -0
  120. package/dist/interactions/relationship.d.ts +29 -0
  121. package/dist/interactions/relationship.d.ts.map +1 -0
  122. package/dist/interactions/relationship.js +31 -0
  123. package/dist/interactions/relationship.js.map +1 -0
  124. package/dist/interactions/risk.d.ts +39 -0
  125. package/dist/interactions/risk.d.ts.map +1 -0
  126. package/dist/interactions/risk.js +49 -0
  127. package/dist/interactions/risk.js.map +1 -0
  128. package/dist/interactions/runs.d.ts +26 -0
  129. package/dist/interactions/runs.d.ts.map +1 -0
  130. package/dist/interactions/runs.js +80 -0
  131. package/dist/interactions/runs.js.map +1 -0
  132. package/dist/interactions/store.d.ts +20 -0
  133. package/dist/interactions/store.d.ts.map +1 -0
  134. package/dist/interactions/store.js +68 -0
  135. package/dist/interactions/store.js.map +1 -0
  136. package/dist/interactions/tickets.d.ts +68 -0
  137. package/dist/interactions/tickets.d.ts.map +1 -0
  138. package/dist/interactions/tickets.js +49 -0
  139. package/dist/interactions/tickets.js.map +1 -0
  140. package/dist/interactions/types.d.ts +160 -0
  141. package/dist/interactions/types.d.ts.map +1 -0
  142. package/dist/interactions/types.js +7 -0
  143. package/dist/interactions/types.js.map +1 -0
  144. package/dist/messaging/board.d.ts +54 -0
  145. package/dist/messaging/board.d.ts.map +1 -0
  146. package/dist/messaging/board.js +90 -0
  147. package/dist/messaging/board.js.map +1 -0
  148. package/dist/messaging/conversation.d.ts +35 -0
  149. package/dist/messaging/conversation.d.ts.map +1 -0
  150. package/dist/messaging/conversation.js +72 -0
  151. package/dist/messaging/conversation.js.map +1 -0
  152. package/dist/messaging/delivery.d.ts +19 -0
  153. package/dist/messaging/delivery.d.ts.map +1 -0
  154. package/dist/messaging/delivery.js +56 -0
  155. package/dist/messaging/delivery.js.map +1 -0
  156. package/dist/messaging/directory.d.ts +32 -0
  157. package/dist/messaging/directory.d.ts.map +1 -0
  158. package/dist/messaging/directory.js +35 -0
  159. package/dist/messaging/directory.js.map +1 -0
  160. package/dist/messaging/envelope.d.ts +14 -0
  161. package/dist/messaging/envelope.d.ts.map +1 -0
  162. package/dist/messaging/envelope.js +71 -0
  163. package/dist/messaging/envelope.js.map +1 -0
  164. package/dist/messaging/hash.d.ts +19 -0
  165. package/dist/messaging/hash.d.ts.map +1 -0
  166. package/dist/messaging/hash.js +36 -0
  167. package/dist/messaging/hash.js.map +1 -0
  168. package/dist/messaging/index.d.ts +16 -0
  169. package/dist/messaging/index.d.ts.map +1 -0
  170. package/dist/messaging/index.js +29 -0
  171. package/dist/messaging/index.js.map +1 -0
  172. package/dist/messaging/projector.d.ts +58 -0
  173. package/dist/messaging/projector.d.ts.map +1 -0
  174. package/dist/messaging/projector.js +103 -0
  175. package/dist/messaging/projector.js.map +1 -0
  176. package/dist/messaging/receipts.d.ts +5 -0
  177. package/dist/messaging/receipts.d.ts.map +1 -0
  178. package/dist/messaging/receipts.js +19 -0
  179. package/dist/messaging/receipts.js.map +1 -0
  180. package/dist/messaging/rules.d.ts +84 -0
  181. package/dist/messaging/rules.d.ts.map +1 -0
  182. package/dist/messaging/rules.js +109 -0
  183. package/dist/messaging/rules.js.map +1 -0
  184. package/dist/messaging/store.d.ts +24 -0
  185. package/dist/messaging/store.d.ts.map +1 -0
  186. package/dist/messaging/store.js +120 -0
  187. package/dist/messaging/store.js.map +1 -0
  188. package/dist/messaging/types.d.ts +166 -0
  189. package/dist/messaging/types.d.ts.map +1 -0
  190. package/dist/messaging/types.js +7 -0
  191. package/dist/messaging/types.js.map +1 -0
  192. package/dist/messaging/vault-store.d.ts +37 -0
  193. package/dist/messaging/vault-store.d.ts.map +1 -0
  194. package/dist/messaging/vault-store.js +62 -0
  195. package/dist/messaging/vault-store.js.map +1 -0
  196. package/dist/record-catalog.d.ts +22 -0
  197. package/dist/record-catalog.d.ts.map +1 -0
  198. package/dist/record-catalog.js +35 -0
  199. package/dist/record-catalog.js.map +1 -0
  200. package/package.json +82 -0
  201. package/spec.md +15 -0
@@ -0,0 +1,9 @@
1
+ import type { ProvenanceRecordV1 } from '@agenticprimitives/provenance';
2
+ export interface ProvenanceStore {
3
+ /** Merge a projected record into the exchange's A-box (accretes activities/entities/agents/plans; de-dupes
4
+ * by id so a re-projection is idempotent). */
5
+ put(exchangeId: string, record: ProvenanceRecordV1, at: string): Promise<void>;
6
+ get(exchangeId: string): Promise<ProvenanceRecordV1 | null>;
7
+ }
8
+ export declare function createDurableObjectProvenanceStore(sql: SqlStorage): ProvenanceStore;
9
+ //# sourceMappingURL=provenance-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance-store.d.ts","sourceRoot":"","sources":["../../src/cloudflare/provenance-store.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAcxE,MAAM,WAAW,eAAe;IAC9B;mDAC+C;IAC/C,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;CAC7D;AAOD,wBAAgB,kCAAkC,CAAC,GAAG,EAAE,UAAU,GAAG,eAAe,CA8BnF"}
@@ -0,0 +1,36 @@
1
+ const CREATE_TABLE = `CREATE TABLE IF NOT EXISTS provenance_records (
2
+ exchange_id TEXT PRIMARY KEY,
3
+ record_json TEXT NOT NULL,
4
+ updated_at TEXT NOT NULL
5
+ )`;
6
+ function mergeById(a, b) {
7
+ const seen = new Set(a.map((x) => x.id));
8
+ return [...a, ...b.filter((x) => !seen.has(x.id))];
9
+ }
10
+ export function createDurableObjectProvenanceStore(sql) {
11
+ sql.exec(CREATE_TABLE);
12
+ const read = (exchangeId) => {
13
+ const rows = sql.exec('SELECT record_json FROM provenance_records WHERE exchange_id = ?', exchangeId).toArray();
14
+ return rows[0] ? JSON.parse(rows[0].record_json) : null;
15
+ };
16
+ return {
17
+ async put(exchangeId, record, at) {
18
+ const prev = read(exchangeId);
19
+ const merged = prev
20
+ ? {
21
+ version: 'ap.provenance.v1',
22
+ agents: mergeById(prev.agents, record.agents),
23
+ activities: mergeById(prev.activities, record.activities),
24
+ entities: mergeById(prev.entities, record.entities),
25
+ plans: mergeById(prev.plans, record.plans),
26
+ }
27
+ : record;
28
+ sql.exec(`INSERT INTO provenance_records (exchange_id, record_json, updated_at) VALUES (?, ?, ?)
29
+ ON CONFLICT(exchange_id) DO UPDATE SET record_json = excluded.record_json, updated_at = excluded.updated_at`, exchangeId, JSON.stringify(merged), at);
30
+ },
31
+ async get(exchangeId) {
32
+ return read(exchangeId);
33
+ },
34
+ };
35
+ }
36
+ //# sourceMappingURL=provenance-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance-store.js","sourceRoot":"","sources":["../../src/cloudflare/provenance-store.ts"],"names":[],"mappings":"AAUA,MAAM,YAAY,GAAG;;;;EAInB,CAAC;AAeH,SAAS,SAAS,CAA2B,CAAM,EAAE,CAAM;IACzD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,kCAAkC,CAAC,GAAe;IAChE,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvB,MAAM,IAAI,GAAG,CAAC,UAAkB,EAA6B,EAAE;QAC7D,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAU,kEAAkE,EAAE,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC;QACzH,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAwB,CAAC,CAAC,CAAC,IAAI,CAAC;IAClF,CAAC,CAAC;IACF,OAAO;QACL,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE;YAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;YAC9B,MAAM,MAAM,GAAuB,IAAI;gBACrC,CAAC,CAAC;oBACE,OAAO,EAAE,kBAAkB;oBAC3B,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;oBAC7C,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;oBACzD,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;oBACnD,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;iBAC3C;gBACH,CAAC,CAAC,MAAM,CAAC;YACX,GAAG,CAAC,IAAI,CACN;qHAC6G,EAC7G,UAAU,EACV,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EACtB,EAAE,CACH,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,UAAU;YAClB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC;QAC1B,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,26 @@
1
+ export interface DeliveryReceiptInput {
2
+ exchangeId: string;
3
+ /** The delivered message id the receipt attests. */
4
+ messageId: string;
5
+ /** The gateway principal (owner) that admitted the message. */
6
+ recipient: string;
7
+ /** Delivery time T (ISO) — the caller supplies it (a DO has no ambient wall-clock in tests). */
8
+ at: string;
9
+ }
10
+ export interface SignedDeliveryReceiptV1 extends DeliveryReceiptInput {
11
+ version: 'ap.delivery-receipt.v1';
12
+ /** The DO-local secp256k1 attestation pubkey (uncompressed hex). */
13
+ signerPubkey: string;
14
+ /** Compact secp256k1 signature (hex) over `sha256(canonical receipt bytes)`. */
15
+ signature: string;
16
+ }
17
+ export interface DeliveryReceiptSigner {
18
+ /** The DO-local attestation pubkey (uncompressed hex) — publish it so senders can verify receipts. */
19
+ pubkey(): Promise<string>;
20
+ /** Sign a delivery receipt with the DO-local key. */
21
+ sign(input: DeliveryReceiptInput): Promise<SignedDeliveryReceiptV1>;
22
+ }
23
+ export declare function createDurableObjectReceiptSigner(storage: DurableObjectStorage): DeliveryReceiptSigner;
24
+ /** Verify a signed delivery receipt against its embedded signer pubkey. Fail-closed on any error. */
25
+ export declare function verifyDeliveryReceipt(receipt: SignedDeliveryReceiptV1): boolean;
26
+ //# sourceMappingURL=receipt-signer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipt-signer.d.ts","sourceRoot":"","sources":["../../src/cloudflare/receipt-signer.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAC;IAClB,gGAAgG;IAChG,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,uBAAwB,SAAQ,oBAAoB;IACnE,OAAO,EAAE,wBAAwB,CAAC;IAClC,oEAAoE;IACpE,YAAY,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAC;CACnB;AAwBD,MAAM,WAAW,qBAAqB;IACpC,sGAAsG;IACtG,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1B,qDAAqD;IACrD,IAAI,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;CACrE;AAED,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,oBAAoB,GAAG,qBAAqB,CAqBrG;AAED,qGAAqG;AACrG,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAS/E"}
@@ -0,0 +1,69 @@
1
+ /// <reference types="@cloudflare/workers-types" />
2
+ // DO-local delivery-receipt signer (spec 316 W2 / §3a receipt + Blocker 4).
3
+ //
4
+ // When the gateway admits a message (T0 delivery), it signs a DeliveryReceipt attesting "this message was
5
+ // accepted under valid authority at time T" — the delivery-proof the sender gets (the review's "signed append
6
+ // receipt, decoupled from body storage"). The signing key is a DO-LOCAL software secp256k1 key, generated
7
+ // once + persisted in DO storage: it attests delivery (ADR-0011 delegated authority-to-attest), it is NOT the
8
+ // SA custody key, and it is NEVER a KMS round-trip on the hot warm path (Blocker 4). Verify with
9
+ // `verifyDeliveryReceipt` against the embedded signer pubkey.
10
+ import { secp256k1 } from '@noble/curves/secp256k1.js';
11
+ import { sha256 } from '@noble/hashes/sha2.js';
12
+ import { bytesToHex, hexToBytes } from '@noble/hashes/utils.js';
13
+ const STORAGE_KEY = 'fabric:receipt-signing-key';
14
+ /** The exact bytes the signature covers — a stable field order (the signer + verifier MUST agree). */
15
+ function digestOf(r) {
16
+ const canonical = JSON.stringify({
17
+ version: 'ap.delivery-receipt.v1',
18
+ exchangeId: r.exchangeId,
19
+ messageId: r.messageId,
20
+ recipient: r.recipient.toLowerCase(),
21
+ at: r.at,
22
+ });
23
+ return sha256(new TextEncoder().encode(canonical));
24
+ }
25
+ function genSecretKey() {
26
+ for (let i = 0; i < 8; i += 1) {
27
+ const k = globalThis.crypto.getRandomValues(new Uint8Array(32));
28
+ if (secp256k1.utils.isValidSecretKey(k))
29
+ return k;
30
+ }
31
+ throw new Error('receipt-signer: could not generate a valid secp256k1 secret key');
32
+ }
33
+ export function createDurableObjectReceiptSigner(storage) {
34
+ let priv = null;
35
+ let pub = null;
36
+ async function key() {
37
+ if (priv && pub)
38
+ return { priv, pub };
39
+ const stored = await storage.get(STORAGE_KEY);
40
+ priv = stored ? hexToBytes(stored) : genSecretKey();
41
+ if (!stored)
42
+ await storage.put(STORAGE_KEY, bytesToHex(priv));
43
+ pub = bytesToHex(secp256k1.getPublicKey(priv, false));
44
+ return { priv, pub };
45
+ }
46
+ return {
47
+ async pubkey() {
48
+ return (await key()).pub;
49
+ },
50
+ async sign(input) {
51
+ const k = await key();
52
+ const sig = secp256k1.sign(digestOf(input), k.priv, { lowS: true, prehash: false, format: 'compact' });
53
+ return { version: 'ap.delivery-receipt.v1', ...input, signerPubkey: k.pub, signature: bytesToHex(sig) };
54
+ },
55
+ };
56
+ }
57
+ /** Verify a signed delivery receipt against its embedded signer pubkey. Fail-closed on any error. */
58
+ export function verifyDeliveryReceipt(receipt) {
59
+ try {
60
+ return secp256k1.verify(hexToBytes(receipt.signature), digestOf(receipt), hexToBytes(receipt.signerPubkey), {
61
+ format: 'compact',
62
+ prehash: false,
63
+ });
64
+ }
65
+ catch {
66
+ return false;
67
+ }
68
+ }
69
+ //# sourceMappingURL=receipt-signer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receipt-signer.js","sourceRoot":"","sources":["../../src/cloudflare/receipt-signer.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,4EAA4E;AAC5E,EAAE;AACF,0GAA0G;AAC1G,8GAA8G;AAC9G,0GAA0G;AAC1G,8GAA8G;AAC9G,iGAAiG;AACjG,8DAA8D;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAoBhE,MAAM,WAAW,GAAG,4BAA4B,CAAC;AAEjD,sGAAsG;AACtG,SAAS,QAAQ,CAAC,CAAuB;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAC/B,OAAO,EAAE,wBAAwB;QACjC,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE;QACpC,EAAE,EAAE,CAAC,CAAC,EAAE;KACT,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,YAAY;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;QAChE,IAAI,SAAS,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IACpD,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;AACrF,CAAC;AASD,MAAM,UAAU,gCAAgC,CAAC,OAA6B;IAC5E,IAAI,IAAI,GAAsB,IAAI,CAAC;IACnC,IAAI,GAAG,GAAkB,IAAI,CAAC;IAC9B,KAAK,UAAU,GAAG;QAChB,IAAI,IAAI,IAAI,GAAG;YAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAS,WAAW,CAAC,CAAC;QACtD,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC;QACpD,IAAI,CAAC,MAAM;YAAE,MAAM,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9D,GAAG,GAAG,UAAU,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;QACtD,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IACvB,CAAC;IACD,OAAO;QACL,KAAK,CAAC,MAAM;YACV,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC;QAC3B,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,KAAK;YACd,MAAM,CAAC,GAAG,MAAM,GAAG,EAAE,CAAC;YACtB,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;YACvG,OAAO,EAAE,OAAO,EAAE,wBAAwB,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1G,CAAC;KACF,CAAC;AACJ,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,qBAAqB,CAAC,OAAgC;IACpE,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE;YAC1G,MAAM,EAAE,SAAS;YACjB,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ export interface RequestIdReservation {
2
+ /** Mark the request permanently consumed (the row already exists from reserve — this is a no-op marker). */
3
+ commit(): Promise<void>;
4
+ /** Release the reservation so a legitimate retry of the SAME requestId may re-reserve. */
5
+ release(): Promise<void>;
6
+ }
7
+ export interface RequestIdLedger {
8
+ /** Reserve `requestId` one-shot. Returns a reservation, or `null` if the id is already present (replay ⇒
9
+ * the caller denies). `now` is the caller-supplied timestamp (DOs have no ambient wall-clock in tests). */
10
+ reserve(requestId: string, now: string): Promise<RequestIdReservation | null>;
11
+ }
12
+ export declare function createDurableObjectRequestIdLedger(sql: SqlStorage): RequestIdLedger;
13
+ //# sourceMappingURL=request-id-ledger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-id-ledger.d.ts","sourceRoot":"","sources":["../../src/cloudflare/request-id-ledger.ts"],"names":[],"mappings":"AAwBA,MAAM,WAAW,oBAAoB;IACnC,4GAA4G;IAC5G,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,0FAA0F;IAC1F,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B;gHAC4G;IAC5G,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;CAC/E;AAED,wBAAgB,kCAAkC,CAAC,GAAG,EAAE,UAAU,GAAG,eAAe,CAmBnF"}
@@ -0,0 +1,38 @@
1
+ /// <reference types="@cloudflare/workers-types" />
2
+ // RequestIdLedger (spec 316 §3a — the T1 single-use replay guard, L2).
3
+ //
4
+ // Every T1 invoke binds its evaluated `argsHash` into a single-use `requestId` (the caller computes
5
+ // `requestId = H(sessionKey, delegationHash, toolSelector, argsHash, …)`); this ledger makes that id
6
+ // one-shot so a replayed (or concurrent-duplicate) invoke is denied. Two-phase (mirrors the a2a
7
+ // `reserveMessageId`, spec 290 §3): the row's PRESENCE is the durable guard — present ⇒ in-flight OR
8
+ // consumed ⇒ replay ⇒ deny. `reserve` writes it (in-flight); `commit` leaves it (permanently consumed);
9
+ // `release` deletes it so a legitimate retry of the SAME request may re-reserve. A crash between reserve and
10
+ // commit/release leaves the row present ⇒ that exact id can't retry (fail-closed; the caller mints a fresh
11
+ // requestId), the safe posture. Single-writer in the DO ⇒ the check-then-write is atomic (no CAS needed).
12
+ //
13
+ // Stored on the DO's `state.storage.sql` (co-located, one trust domain).
14
+ const CREATE_TABLE = `CREATE TABLE IF NOT EXISTS request_ids (
15
+ request_id TEXT PRIMARY KEY,
16
+ at TEXT NOT NULL
17
+ )`;
18
+ export function createDurableObjectRequestIdLedger(sql) {
19
+ sql.exec(CREATE_TABLE);
20
+ return {
21
+ async reserve(requestId, now) {
22
+ const id = requestId.toLowerCase();
23
+ const existing = sql.exec('SELECT request_id FROM request_ids WHERE request_id = ?', id).toArray();
24
+ if (existing.length > 0)
25
+ return null; // present ⇒ in-flight or consumed ⇒ replay
26
+ sql.exec('INSERT INTO request_ids (request_id, at) VALUES (?, ?)', id, now);
27
+ return {
28
+ async commit() {
29
+ /* the row was written on reserve — the id stays consumed */
30
+ },
31
+ async release() {
32
+ sql.exec('DELETE FROM request_ids WHERE request_id = ?', id);
33
+ },
34
+ };
35
+ },
36
+ };
37
+ }
38
+ //# sourceMappingURL=request-id-ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-id-ledger.js","sourceRoot":"","sources":["../../src/cloudflare/request-id-ledger.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,uEAAuE;AACvE,EAAE;AACF,oGAAoG;AACpG,qGAAqG;AACrG,gGAAgG;AAChG,qGAAqG;AACrG,wGAAwG;AACxG,6GAA6G;AAC7G,2GAA2G;AAC3G,0GAA0G;AAC1G,EAAE;AACF,yEAAyE;AAEzE,MAAM,YAAY,GAAG;;;EAGnB,CAAC;AAoBH,MAAM,UAAU,kCAAkC,CAAC,GAAe;IAChE,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAEvB,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG;YAC1B,MAAM,EAAE,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;YACnC,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAe,yDAAyD,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YACjH,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,IAAI,CAAC,CAAC,2CAA2C;YACjF,GAAG,CAAC,IAAI,CAAC,wDAAwD,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;YAC5E,OAAO;gBACL,KAAK,CAAC,MAAM;oBACV,4DAA4D;gBAC9D,CAAC;gBACD,KAAK,CAAC,OAAO;oBACX,GAAG,CAAC,IAAI,CAAC,8CAA8C,EAAE,EAAE,CAAC,CAAC;gBAC/D,CAAC;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Vault, DekWrapper } from '@agenticprimitives/vault';
2
+ /**
3
+ * Build a `Vault` over a Durable Object's `SqlStorage`, sealing/opening under the injected per-owner
4
+ * `DekWrapper` (the owner's KEK). Schema is created idempotently on construction. `data: null` on write
5
+ * tombstones (soft-delete); reads and lists skip tombstones. `owner` is lower-cased for case-insensitive
6
+ * keying (mirrors the D1 adapter + the in-memory reference). Generic: it stores arbitrary `resource`
7
+ * records (e.g. `message.body:<id>`) — no demo-mcp PII/profile seeding (that stays app-side).
8
+ */
9
+ export declare function createDurableObjectSqlVault(sql: SqlStorage, wrapper: DekWrapper): Vault;
10
+ //# sourceMappingURL=sql-vault.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-vault.d.ts","sourceRoot":"","sources":["../../src/cloudflare/sql-vault.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,KAAK,EAML,UAAU,EACX,MAAM,0BAA0B,CAAC;AA4ClC;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,KAAK,CAiFvF"}
@@ -0,0 +1,98 @@
1
+ import { sealEnvelope, openEnvelope, projectFields } from '@agenticprimitives/vault';
2
+ // One statement per `exec` (DO SQLite runs a single statement per call).
3
+ const CREATE_TABLE = `CREATE TABLE IF NOT EXISTS vault_objects (
4
+ owner_address TEXT NOT NULL,
5
+ resource TEXT NOT NULL,
6
+ classification TEXT NOT NULL,
7
+ ciphertext_b64 TEXT NOT NULL,
8
+ wrapped_dek_b64 TEXT NOT NULL,
9
+ crypto_meta TEXT NOT NULL,
10
+ created_at TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP),
11
+ updated_at TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP),
12
+ deleted_at TEXT,
13
+ PRIMARY KEY (owner_address, resource)
14
+ )`;
15
+ const CREATE_INDEX = `CREATE INDEX IF NOT EXISTS idx_vault_objects_owner ON vault_objects (owner_address) WHERE deleted_at IS NULL`;
16
+ function b64encode(bytes) {
17
+ let s = '';
18
+ for (let i = 0; i < bytes.length; i += 1)
19
+ s += String.fromCharCode(bytes[i]);
20
+ return btoa(s);
21
+ }
22
+ function b64decode(s) {
23
+ const bin = atob(s);
24
+ const out = new Uint8Array(bin.length);
25
+ for (let i = 0; i < bin.length; i += 1)
26
+ out[i] = bin.charCodeAt(i);
27
+ return out;
28
+ }
29
+ const DEFAULT_CLASSIFICATION = 'internal';
30
+ /**
31
+ * Build a `Vault` over a Durable Object's `SqlStorage`, sealing/opening under the injected per-owner
32
+ * `DekWrapper` (the owner's KEK). Schema is created idempotently on construction. `data: null` on write
33
+ * tombstones (soft-delete); reads and lists skip tombstones. `owner` is lower-cased for case-insensitive
34
+ * keying (mirrors the D1 adapter + the in-memory reference). Generic: it stores arbitrary `resource`
35
+ * records (e.g. `message.body:<id>`) — no demo-mcp PII/profile seeding (that stays app-side).
36
+ */
37
+ export function createDurableObjectSqlVault(sql, wrapper) {
38
+ sql.exec(CREATE_TABLE);
39
+ sql.exec(CREATE_INDEX);
40
+ return {
41
+ async read(req) {
42
+ const owner = req.owner.toLowerCase();
43
+ const rows = sql
44
+ .exec('SELECT * FROM vault_objects WHERE owner_address = ? AND resource = ? AND deleted_at IS NULL', owner, req.resource)
45
+ .toArray();
46
+ const row = rows[0];
47
+ if (!row)
48
+ return null;
49
+ const data = await openEnvelope({
50
+ envelope: {
51
+ owner: row.owner_address,
52
+ resource: row.resource,
53
+ classification: row.classification,
54
+ crypto: JSON.parse(row.crypto_meta),
55
+ },
56
+ ciphertext: b64decode(row.ciphertext_b64),
57
+ wrappedDek: b64decode(row.wrapped_dek_b64),
58
+ wrapper,
59
+ });
60
+ return {
61
+ owner: row.owner_address,
62
+ resource: row.resource,
63
+ classification: row.classification,
64
+ data: projectFields(data, req.fields),
65
+ updatedAt: row.updated_at,
66
+ };
67
+ },
68
+ async write(req) {
69
+ const owner = req.owner.toLowerCase();
70
+ if (req.data === null) {
71
+ sql.exec('UPDATE vault_objects SET deleted_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP WHERE owner_address = ? AND resource = ?', owner, req.resource);
72
+ return;
73
+ }
74
+ const classification = req.classification ?? DEFAULT_CLASSIFICATION;
75
+ const sealed = await sealEnvelope({ owner, resource: req.resource, classification, data: req.data, wrapper });
76
+ sql.exec(`INSERT INTO vault_objects (owner_address, resource, classification, ciphertext_b64, wrapped_dek_b64, crypto_meta)
77
+ VALUES (?, ?, ?, ?, ?, ?)
78
+ ON CONFLICT(owner_address, resource) DO UPDATE SET
79
+ classification = excluded.classification,
80
+ ciphertext_b64 = excluded.ciphertext_b64,
81
+ wrapped_dek_b64 = excluded.wrapped_dek_b64,
82
+ crypto_meta = excluded.crypto_meta,
83
+ updated_at = CURRENT_TIMESTAMP,
84
+ deleted_at = NULL`, owner, req.resource, classification, b64encode(sealed.ciphertext), b64encode(sealed.wrappedDek), JSON.stringify(sealed.envelope.crypto));
85
+ },
86
+ async list(owner) {
87
+ const rows = sql
88
+ .exec('SELECT resource, classification, updated_at FROM vault_objects WHERE owner_address = ? AND deleted_at IS NULL ORDER BY resource', owner.toLowerCase())
89
+ .toArray();
90
+ return rows.map((r) => ({
91
+ resource: r.resource,
92
+ classification: r.classification,
93
+ updatedAt: r.updated_at,
94
+ }));
95
+ },
96
+ };
97
+ }
98
+ //# sourceMappingURL=sql-vault.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-vault.js","sourceRoot":"","sources":["../../src/cloudflare/sql-vault.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { CanonicalAgentId } from '@agenticprimitives/types';
2
+ import type { Hex32, MessageId, MessageKind } from './messaging/index.js';
3
+ import type { VaultRef } from '@agenticprimitives/vault';
4
+ export type Performative = 'INFORM' | 'QUERY' | 'REQUEST' | 'PROPOSE' | 'COUNTER' | 'ACCEPT' | 'REJECT' | 'NOTIFY' | 'ACKNOWLEDGE' | 'ISSUE' | 'RETRACT' | 'SUBSCRIBE' | 'UNSUBSCRIBE';
5
+ /** A by-reference pointer at a piece of semantic content an act expresses or carries — a Situation, a
6
+ * credential, a delegation hash, an intent, an outcome. Display/provenance metadata, NEVER inline authority. */
7
+ export interface SemanticContentRef {
8
+ /** App/ontology kind, e.g. 'situation' | 'credential' | 'delegation' | 'intent' | 'outcome'. */
9
+ kind: string;
10
+ /** Stable id: a Situation id, CAIP-10, delegation hash, URI, content hash. */
11
+ id: string;
12
+ /** Optional content binding (situation hash, credential digest, delegation hash). */
13
+ hash?: Hex32;
14
+ }
15
+ /** A by-reference pointer at evidence backing an act (a vault-resident artifact, a receipt). */
16
+ export interface EvidenceRef {
17
+ ref: VaultRef;
18
+ hash?: Hex32;
19
+ contentType?: string;
20
+ }
21
+ /**
22
+ * A semantic act performed within an exchange (spec 324 §9). Body-adjacent in V1 (travels alongside the
23
+ * envelope, not inside the signed wire); native on `ap.exchange.v2`.
24
+ */
25
+ export interface CommunicativeActV1 {
26
+ version: 'ap.act.v1';
27
+ performative: Performative;
28
+ /** Who performed the act. */
29
+ actor: CanonicalAgentId;
30
+ /** On whose behalf (== actor unless delegated; the authorizing delegation lives in the record's authorityRefs). */
31
+ principal: CanonicalAgentId;
32
+ addressedTo: CanonicalAgentId[];
33
+ /** Zero, one, or many intents this act expresses. */
34
+ expressesIntentRefs?: SemanticContentRef[];
35
+ /** Situations, credentials, delegation hashes, outcomes this act carries or references. */
36
+ semanticContentRefs?: SemanticContentRef[];
37
+ evidenceRefs?: EvidenceRef[];
38
+ /** The message this act responds to, if any. */
39
+ inRespondsTo?: MessageId;
40
+ }
41
+ /**
42
+ * The TOTAL `MessageKind` → `Performative` derivation for V1 envelopes (spec 324 §9). Exhaustive: every
43
+ * `MessageKind` maps. A `response` refines to the act's performative when it is one of the response family
44
+ * (`INFORM`/`ACCEPT`/`REJECT`/`COUNTER`), defaulting to `INFORM`.
45
+ */
46
+ export declare function performativeForKind(kind: MessageKind, act?: CommunicativeActV1): Performative;
47
+ //# sourceMappingURL=communicative-act.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"communicative-act.d.ts","sourceRoot":"","sources":["../src/communicative-act.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEzD,MAAM,MAAM,YAAY,GACpB,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAC5E,QAAQ,GAAG,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,GAAG,aAAa,CAAC;AAEjF;iHACiH;AACjH,MAAM,WAAW,kBAAkB;IACjC,gGAAgG;IAChG,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,EAAE,EAAE,MAAM,CAAC;IACX,qFAAqF;IACrF,IAAI,CAAC,EAAE,KAAK,CAAC;CACd;AAED,gGAAgG;AAChG,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,QAAQ,CAAC;IACd,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,WAAW,CAAC;IACrB,YAAY,EAAE,YAAY,CAAC;IAC3B,6BAA6B;IAC7B,KAAK,EAAE,gBAAgB,CAAC;IACxB,mHAAmH;IACnH,SAAS,EAAE,gBAAgB,CAAC;IAC5B,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,qDAAqD;IACrD,mBAAmB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC3C,2FAA2F;IAC3F,mBAAmB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC3C,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAC7B,gDAAgD;IAChD,YAAY,CAAC,EAAE,SAAS,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC,EAAE,kBAAkB,GAAG,YAAY,CAmB7F"}
@@ -0,0 +1,36 @@
1
+ // Fabric semantic acts — spec 324 W5 (§9). A `CommunicativeActV1` names WHAT an exchange move DOES
2
+ // (inform / request / propose / accept / …) as an explicit speech act, distinct from the transport envelope
3
+ // that carries it. It NEVER grants authority: a message may ISSUE or reference a Delegation, but verification
4
+ // always re-evaluates the signed wire + caveats + session binding + revocation (ADR-0041/ADR-0047). The act
5
+ // carries `actor` (who performed it) AND `principal` (on whose behalf) — a service agent acting for an org is
6
+ // never erased from provenance and never pretends to BE the org.
7
+ //
8
+ // V1 envelopes carry no native performative, so for legacy/communication envelopes the performative is DERIVED
9
+ // from `MessageKind` via one TOTAL mapping (`performativeForKind`, golden-vectored). A future `ap.exchange.v2`
10
+ // envelope carries `performative`/`actor`/`principal` natively.
11
+ /**
12
+ * The TOTAL `MessageKind` → `Performative` derivation for V1 envelopes (spec 324 §9). Exhaustive: every
13
+ * `MessageKind` maps. A `response` refines to the act's performative when it is one of the response family
14
+ * (`INFORM`/`ACCEPT`/`REJECT`/`COUNTER`), defaulting to `INFORM`.
15
+ */
16
+ export function performativeForKind(kind, act) {
17
+ switch (kind) {
18
+ case 'plain':
19
+ return 'INFORM';
20
+ case 'request':
21
+ return 'REQUEST';
22
+ case 'response': {
23
+ const p = act?.performative;
24
+ return p === 'ACCEPT' || p === 'REJECT' || p === 'COUNTER' || p === 'INFORM' ? p : 'INFORM';
25
+ }
26
+ case 'credential-delivery':
27
+ return 'ISSUE';
28
+ case 'receipt':
29
+ return 'ACKNOWLEDGE';
30
+ case 'system':
31
+ return 'NOTIFY';
32
+ case 'tombstone':
33
+ return 'RETRACT';
34
+ }
35
+ }
36
+ //# sourceMappingURL=communicative-act.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"communicative-act.js","sourceRoot":"","sources":["../src/communicative-act.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,4GAA4G;AAC5G,8GAA8G;AAC9G,4GAA4G;AAC5G,8GAA8G;AAC9G,iEAAiE;AACjE,EAAE;AACF,+GAA+G;AAC/G,+GAA+G;AAC/G,gEAAgE;AAiDhE;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAiB,EAAE,GAAwB;IAC7E,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO;YACV,OAAO,QAAQ,CAAC;QAClB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;QACnB,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,CAAC,GAAG,GAAG,EAAE,YAAY,CAAC;YAC5B,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC9F,CAAC;QACD,KAAK,qBAAqB;YACxB,OAAO,OAAO,CAAC;QACjB,KAAK,SAAS;YACZ,OAAO,aAAa,CAAC;QACvB,KAAK,QAAQ;YACX,OAAO,QAAQ,CAAC;QAClB,KAAK,WAAW;YACd,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { CanonicalAgentId } from '@agenticprimitives/types';
2
+ import type { AuthorityTier } from '@agenticprimitives/tool-policy';
3
+ import type { IntentEnvelopeV1, ExchangeRecordV1, ExchangeId } from './exchange-record.js';
4
+ export interface DeliveryEnvelopeV1 {
5
+ version: 'ap.delivery-envelope.v1';
6
+ exchangeId: ExchangeId | string;
7
+ /** The signed message envelope being delivered — carries its own sender-proof + `bodyHash`. */
8
+ envelope: IntentEnvelopeV1;
9
+ /** Routing: the sending + receiving gateway principals (advisory; authority rides `envelope.signature`). */
10
+ fromGateway: CanonicalAgentId;
11
+ toGateway: CanonicalAgentId;
12
+ at: string;
13
+ /** Transport-level replay-dedup nonce (also the OutboxStore key). */
14
+ nonce: string;
15
+ }
16
+ export declare function buildDeliveryEnvelope(input: Omit<DeliveryEnvelopeV1, 'version'>): DeliveryEnvelopeV1;
17
+ export type DeliveryAdmission = {
18
+ ok: true;
19
+ } | {
20
+ ok: false;
21
+ reason: string;
22
+ };
23
+ /**
24
+ * TRANSPORT-level admission of a peer delivery at the recipient gateway (fail-closed): correct version, routed
25
+ * to THIS gateway, the envelope addressed to it, and structurally sound (`id` + `bodyHash`). It does NOT verify
26
+ * the sender's on-chain authority — that is the gateway's separate re-verification (ADR-0041). `recipient` is
27
+ * this gateway's principal.
28
+ */
29
+ export declare function admitDeliveryEnvelope(delivery: DeliveryEnvelopeV1, opts: {
30
+ recipient: CanonicalAgentId;
31
+ }): DeliveryAdmission;
32
+ /** Build the initial T0 `ExchangeRecordV1` the recipient gateway persists for an admitted delivery. The DO
33
+ * then applies the `delivered` message event + signs a receipt. */
34
+ export declare function deliveryToExchangeRecord(delivery: DeliveryEnvelopeV1, opts: {
35
+ tier: AuthorityTier;
36
+ at: string;
37
+ }): ExchangeRecordV1;
38
+ //# sourceMappingURL=delivery-envelope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-envelope.d.ts","sourceRoot":"","sources":["../src/delivery-envelope.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAE3F,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,yBAAyB,CAAC;IACnC,UAAU,EAAE,UAAU,GAAG,MAAM,CAAC;IAChC,+FAA+F;IAC/F,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,4GAA4G;IAC5G,WAAW,EAAE,gBAAgB,CAAC;IAC9B,SAAS,EAAE,gBAAgB,CAAC;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,SAAS,CAAC,GAAG,kBAAkB,CAGpG;AAED,MAAM,MAAM,iBAAiB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7E;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,kBAAkB,EAC5B,IAAI,EAAE;IAAE,SAAS,EAAE,gBAAgB,CAAA;CAAE,GACpC,iBAAiB,CAQnB;AAED;oEACoE;AACpE,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,kBAAkB,EAC5B,IAAI,EAAE;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GACxC,gBAAgB,CAelB"}
@@ -0,0 +1,43 @@
1
+ export function buildDeliveryEnvelope(input) {
2
+ if (!input.exchangeId || !input.nonce)
3
+ throw new Error('buildDeliveryEnvelope: exchangeId + nonce required');
4
+ return { version: 'ap.delivery-envelope.v1', ...input };
5
+ }
6
+ /**
7
+ * TRANSPORT-level admission of a peer delivery at the recipient gateway (fail-closed): correct version, routed
8
+ * to THIS gateway, the envelope addressed to it, and structurally sound (`id` + `bodyHash`). It does NOT verify
9
+ * the sender's on-chain authority — that is the gateway's separate re-verification (ADR-0041). `recipient` is
10
+ * this gateway's principal.
11
+ */
12
+ export function admitDeliveryEnvelope(delivery, opts) {
13
+ if (delivery.version !== 'ap.delivery-envelope.v1')
14
+ return { ok: false, reason: 'bad_version' };
15
+ const recip = opts.recipient.toLowerCase();
16
+ if (delivery.toGateway.toLowerCase() !== recip)
17
+ return { ok: false, reason: 'wrong_gateway' };
18
+ const e = delivery.envelope;
19
+ if (!e || !e.id || !e.bodyHash)
20
+ return { ok: false, reason: 'malformed_envelope' };
21
+ if (!e.to.some((t) => t.toLowerCase() === recip))
22
+ return { ok: false, reason: 'not_addressed' };
23
+ return { ok: true };
24
+ }
25
+ /** Build the initial T0 `ExchangeRecordV1` the recipient gateway persists for an admitted delivery. The DO
26
+ * then applies the `delivered` message event + signs a receipt. */
27
+ export function deliveryToExchangeRecord(delivery, opts) {
28
+ const e = delivery.envelope;
29
+ return {
30
+ version: 'ap.exchange.v1',
31
+ exchangeId: delivery.exchangeId,
32
+ kind: e.kind,
33
+ tier: opts.tier,
34
+ principal: delivery.toGateway,
35
+ parties: { from: e.from, to: e.to },
36
+ exec: 'submitted',
37
+ envelopes: [e],
38
+ events: [],
39
+ rev: 0,
40
+ updatedAt: opts.at,
41
+ };
42
+ }
43
+ //# sourceMappingURL=delivery-envelope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-envelope.js","sourceRoot":"","sources":["../src/delivery-envelope.ts"],"names":[],"mappings":"AA0BA,MAAM,UAAU,qBAAqB,CAAC,KAA0C;IAC9E,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IAC7G,OAAO,EAAE,OAAO,EAAE,yBAAyB,EAAE,GAAG,KAAK,EAAE,CAAC;AAC1D,CAAC;AAID;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAA4B,EAC5B,IAAqC;IAErC,IAAI,QAAQ,CAAC,OAAO,KAAK,yBAAyB;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IAChG,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;IAC3C,IAAI,QAAQ,CAAC,SAAS,CAAC,WAAW,EAAE,KAAK,KAAK;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAC9F,MAAM,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC;IAC5B,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC;IACnF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAChG,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC;AAED;oEACoE;AACpE,MAAM,UAAU,wBAAwB,CACtC,QAA4B,EAC5B,IAAyC;IAEzC,MAAM,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC;IAC5B,OAAO;QACL,OAAO,EAAE,gBAAgB;QACzB,UAAU,EAAE,QAAQ,CAAC,UAAwB;QAC7C,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE;QACnC,IAAI,EAAE,WAAW;QACjB,SAAS,EAAE,CAAC,CAAC,CAAC;QACd,MAAM,EAAE,EAAE;QACV,GAAG,EAAE,CAAC;QACN,SAAS,EAAE,IAAI,CAAC,EAAE;KACnB,CAAC;AACJ,CAAC"}