@agenticprimitives/fabric 0.0.0-alpha.1 → 0.0.0-alpha.11

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 (167) hide show
  1. package/CLAUDE.md +26 -30
  2. package/README.md +16 -16
  3. package/dist/case-emissions.d.ts +95 -0
  4. package/dist/case-emissions.d.ts.map +1 -0
  5. package/dist/case-emissions.js +208 -0
  6. package/dist/case-emissions.js.map +1 -0
  7. package/dist/case-machine.d.ts +28 -2
  8. package/dist/case-machine.d.ts.map +1 -1
  9. package/dist/case-machine.js +34 -7
  10. package/dist/case-machine.js.map +1 -1
  11. package/dist/cloudflare/authority-verdict-cache.d.ts +28 -1
  12. package/dist/cloudflare/authority-verdict-cache.d.ts.map +1 -1
  13. package/dist/cloudflare/authority-verdict-cache.js +32 -1
  14. package/dist/cloudflare/authority-verdict-cache.js.map +1 -1
  15. package/dist/cloudflare/index.d.ts +4 -1
  16. package/dist/cloudflare/index.d.ts.map +1 -1
  17. package/dist/cloudflare/index.js +7 -1
  18. package/dist/cloudflare/index.js.map +1 -1
  19. package/dist/cloudflare/interaction-store.d.ts +55 -0
  20. package/dist/cloudflare/interaction-store.d.ts.map +1 -0
  21. package/dist/cloudflare/interaction-store.js +230 -0
  22. package/dist/cloudflare/interaction-store.js.map +1 -0
  23. package/dist/cloudflare/principal-gateway-do.d.ts +136 -2
  24. package/dist/cloudflare/principal-gateway-do.d.ts.map +1 -1
  25. package/dist/cloudflare/principal-gateway-do.js +190 -8
  26. package/dist/cloudflare/principal-gateway-do.js.map +1 -1
  27. package/dist/cloudflare/vault-exchange-store.d.ts +47 -0
  28. package/dist/cloudflare/vault-exchange-store.d.ts.map +1 -0
  29. package/dist/cloudflare/vault-exchange-store.js +118 -0
  30. package/dist/cloudflare/vault-exchange-store.js.map +1 -0
  31. package/dist/cloudflare/vault-interaction-store.d.ts +44 -0
  32. package/dist/cloudflare/vault-interaction-store.d.ts.map +1 -0
  33. package/dist/cloudflare/vault-interaction-store.js +245 -0
  34. package/dist/cloudflare/vault-interaction-store.js.map +1 -0
  35. package/dist/communicative-act.d.ts +24 -1
  36. package/dist/communicative-act.d.ts.map +1 -1
  37. package/dist/communicative-act.js +28 -0
  38. package/dist/communicative-act.js.map +1 -1
  39. package/dist/delivery-envelope.d.ts.map +1 -1
  40. package/dist/delivery-envelope.js +0 -1
  41. package/dist/delivery-envelope.js.map +1 -1
  42. package/dist/enum-retirement.d.ts +43 -0
  43. package/dist/enum-retirement.d.ts.map +1 -0
  44. package/dist/enum-retirement.js +93 -0
  45. package/dist/enum-retirement.js.map +1 -0
  46. package/dist/exchange-record.d.ts +35 -4
  47. package/dist/exchange-record.d.ts.map +1 -1
  48. package/dist/exchange-record.js.map +1 -1
  49. package/dist/exchange-reducer.d.ts +32 -4
  50. package/dist/exchange-reducer.d.ts.map +1 -1
  51. package/dist/exchange-reducer.js +75 -1
  52. package/dist/exchange-reducer.js.map +1 -1
  53. package/dist/exchange-state.d.ts +30 -8
  54. package/dist/exchange-state.d.ts.map +1 -1
  55. package/dist/exchange-state.js +12 -10
  56. package/dist/exchange-state.js.map +1 -1
  57. package/dist/inbox-doc.d.ts +2 -2
  58. package/dist/inbox-doc.d.ts.map +1 -1
  59. package/dist/inbox-doc.js.map +1 -1
  60. package/dist/inbox-projection.d.ts +2 -2
  61. package/dist/inbox-projection.d.ts.map +1 -1
  62. package/dist/inbox-projection.js.map +1 -1
  63. package/dist/inbox-revision.d.ts +42 -0
  64. package/dist/inbox-revision.d.ts.map +1 -0
  65. package/dist/inbox-revision.js +57 -0
  66. package/dist/inbox-revision.js.map +1 -0
  67. package/dist/index.d.ts +24 -3
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +37 -2
  70. package/dist/index.js.map +1 -1
  71. package/dist/interaction-machines.d.ts +136 -0
  72. package/dist/interaction-machines.d.ts.map +1 -0
  73. package/dist/interaction-machines.js +174 -0
  74. package/dist/interaction-machines.js.map +1 -0
  75. package/dist/interaction-profile.d.ts +126 -0
  76. package/dist/interaction-profile.d.ts.map +1 -0
  77. package/dist/interaction-profile.js +192 -0
  78. package/dist/interaction-profile.js.map +1 -0
  79. package/dist/interaction-record.d.ts +168 -0
  80. package/dist/interaction-record.d.ts.map +1 -0
  81. package/dist/interaction-record.js +108 -0
  82. package/dist/interaction-record.js.map +1 -0
  83. package/dist/interactions/machine.d.ts +2 -2
  84. package/dist/interactions/machine.d.ts.map +1 -1
  85. package/dist/interactions/machine.js +2 -2
  86. package/dist/interactions/machine.js.map +1 -1
  87. package/dist/interactions/open-case.d.ts +60 -0
  88. package/dist/interactions/open-case.d.ts.map +1 -0
  89. package/dist/interactions/open-case.js +83 -0
  90. package/dist/interactions/open-case.js.map +1 -0
  91. package/dist/interactions/store.d.ts +9 -0
  92. package/dist/interactions/store.d.ts.map +1 -1
  93. package/dist/interactions/store.js +57 -2
  94. package/dist/interactions/store.js.map +1 -1
  95. package/dist/messaging/board.d.ts +86 -6
  96. package/dist/messaging/board.d.ts.map +1 -1
  97. package/dist/messaging/board.js +100 -9
  98. package/dist/messaging/board.js.map +1 -1
  99. package/dist/messaging/consult-routing.d.ts +289 -0
  100. package/dist/messaging/consult-routing.d.ts.map +1 -0
  101. package/dist/messaging/consult-routing.js +455 -0
  102. package/dist/messaging/consult-routing.js.map +1 -0
  103. package/dist/messaging/consult.d.ts +158 -0
  104. package/dist/messaging/consult.d.ts.map +1 -0
  105. package/dist/messaging/consult.js +141 -0
  106. package/dist/messaging/consult.js.map +1 -0
  107. package/dist/messaging/conversation-interaction.d.ts +66 -0
  108. package/dist/messaging/conversation-interaction.d.ts.map +1 -0
  109. package/dist/messaging/conversation-interaction.js +139 -0
  110. package/dist/messaging/conversation-interaction.js.map +1 -0
  111. package/dist/messaging/delivery.d.ts +2 -2
  112. package/dist/messaging/delivery.d.ts.map +1 -1
  113. package/dist/messaging/delivery.js +8 -1
  114. package/dist/messaging/delivery.js.map +1 -1
  115. package/dist/messaging/directory.d.ts +16 -0
  116. package/dist/messaging/directory.d.ts.map +1 -1
  117. package/dist/messaging/directory.js.map +1 -1
  118. package/dist/messaging/envelope.d.ts +7 -3
  119. package/dist/messaging/envelope.d.ts.map +1 -1
  120. package/dist/messaging/envelope.js +18 -1
  121. package/dist/messaging/envelope.js.map +1 -1
  122. package/dist/messaging/hash.d.ts +8 -2
  123. package/dist/messaging/hash.d.ts.map +1 -1
  124. package/dist/messaging/hash.js +6 -0
  125. package/dist/messaging/hash.js.map +1 -1
  126. package/dist/messaging/inbox-assistant.d.ts +80 -0
  127. package/dist/messaging/inbox-assistant.d.ts.map +1 -0
  128. package/dist/messaging/inbox-assistant.js +125 -0
  129. package/dist/messaging/inbox-assistant.js.map +1 -0
  130. package/dist/messaging/index.d.ts +10 -3
  131. package/dist/messaging/index.d.ts.map +1 -1
  132. package/dist/messaging/index.js +20 -2
  133. package/dist/messaging/index.js.map +1 -1
  134. package/dist/messaging/outbound-message.d.ts +42 -0
  135. package/dist/messaging/outbound-message.d.ts.map +1 -0
  136. package/dist/messaging/outbound-message.js +64 -0
  137. package/dist/messaging/outbound-message.js.map +1 -0
  138. package/dist/messaging/projector.d.ts +3 -3
  139. package/dist/messaging/projector.d.ts.map +1 -1
  140. package/dist/messaging/projector.js.map +1 -1
  141. package/dist/messaging/receipts.d.ts +3 -3
  142. package/dist/messaging/receipts.d.ts.map +1 -1
  143. package/dist/messaging/receipts.js.map +1 -1
  144. package/dist/messaging/rules.d.ts +10 -3
  145. package/dist/messaging/rules.d.ts.map +1 -1
  146. package/dist/messaging/rules.js +8 -1
  147. package/dist/messaging/rules.js.map +1 -1
  148. package/dist/messaging/store.d.ts +4 -4
  149. package/dist/messaging/store.d.ts.map +1 -1
  150. package/dist/messaging/store.js +5 -3
  151. package/dist/messaging/store.js.map +1 -1
  152. package/dist/messaging/types.d.ts +52 -0
  153. package/dist/messaging/types.d.ts.map +1 -1
  154. package/dist/messaging/types.js +18 -1
  155. package/dist/messaging/types.js.map +1 -1
  156. package/dist/messaging/vault-store.d.ts +35 -2
  157. package/dist/messaging/vault-store.d.ts.map +1 -1
  158. package/dist/messaging/vault-store.js +53 -5
  159. package/dist/messaging/vault-store.js.map +1 -1
  160. package/dist/protocol-binding.d.ts +71 -0
  161. package/dist/protocol-binding.d.ts.map +1 -0
  162. package/dist/protocol-binding.js +0 -0
  163. package/dist/protocol-binding.js.map +1 -0
  164. package/dist/record-catalog.d.ts.map +1 -1
  165. package/dist/record-catalog.js +24 -0
  166. package/dist/record-catalog.js.map +1 -1
  167. package/package.json +7 -7
@@ -0,0 +1,118 @@
1
+ // The VAULT-BACKED `ExchangeStore` (spec 316 §0b, ADR-0055 amendment, audit G-2).
2
+ //
3
+ // This is what lets the exchange stream serve. ADR-0055's projection rule bars a DO-SQL store from being
4
+ // the home of exchanges; this store makes the owner's vault the home and the DO-SQL rows an index over it.
5
+ //
6
+ // RESIDENCY, DECIDED: **each party holds their own copy**. Sender and recipient each write one. There is no
7
+ // single system of record for an exchange and neither copy is authoritative over the other — the email
8
+ // model, not the shared-database model. It follows from portability: if a person can carry their history to
9
+ // another Home (spec 323), a message they sent cannot live only in the counterparty's vault, because
10
+ // leaving must not require the other party's cooperation or their continued existence.
11
+ //
12
+ // WHAT THAT BUYS: a rebuild is a SINGLE-VAULT READ. A wiped gateway reconstructs from its own principal's
13
+ // vault alone — no counterparty round-trip, no reconciliation, no recovery blocked because someone else is
14
+ // offline. Had we chosen one shared copy, rebuild would have been a distributed reconciliation, which is
15
+ // why the residency question had to be settled before write-through could be written rather than after.
16
+ //
17
+ // THE TWO COPIES ARE NOT EXPECTED TO MATCH BYTE-FOR-BYTE, and requiring it would invent a consensus problem
18
+ // where none exists. The signed core (exchangeId, envelope, bodyHash, signature) is identical because it is
19
+ // signed. Per-party lifecycle state legitimately differs: "I sent it" and "I read it" are different facts
20
+ // held by different people, and collapsing them into one row is how a system starts asserting that a
21
+ // recipient read something because the SENDER's copy says delivered. What makes a copy trustworthy is the
22
+ // signature, not the storage.
23
+ import { applyExchangeEvent } from '../exchange-reducer.js';
24
+ /** One party's copy of one exchange. */
25
+ export const exchangeResource = (exchangeId) => `exchange:${String(exchangeId)}`;
26
+ /** The ordered id list. It exists so `list()` and `rebuild()` are ONE read plus N, rather than an
27
+ * enumeration that must fetch every record just to order them — an index whose cost is the reason nobody
28
+ * runs the rebuild is not much of an index. */
29
+ export const EXCHANGE_INDEX_RESOURCE = 'exchange.index';
30
+ const EMPTY_INDEX = { version: 1, entries: [] };
31
+ /**
32
+ * @param vault the owner's MCP-backed vault — the home of the records.
33
+ * @param owner the principal whose copy this is. Each party passes their OWN.
34
+ * @param index DO-local index hooks. Optional: absent, the store is vault-only (correct, just slower),
35
+ * which is also what makes the rebuild testable without a SQL fake.
36
+ */
37
+ export function createVaultExchangeStore(vault, owner, index) {
38
+ const readIndex = async () => {
39
+ const obj = await vault.read({ owner, resource: EXCHANGE_INDEX_RESOURCE });
40
+ return obj?.data ?? EMPTY_INDEX;
41
+ };
42
+ const writeIndex = async (record) => {
43
+ const current = await readIndex();
44
+ const rest = current.entries.filter((e) => e.exchangeId !== String(record.exchangeId));
45
+ const entries = [{ exchangeId: String(record.exchangeId), updatedAt: record.updatedAt, rev: record.rev }, ...rest]
46
+ .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
47
+ await vault.write({ owner, resource: EXCHANGE_INDEX_RESOURCE, data: { version: 1, entries }, classification: 'internal' });
48
+ };
49
+ /**
50
+ * WRITE-THROUGH, AND THE ORDER IS NOT NEGOTIABLE.
51
+ *
52
+ * 1. the record lands in the vault — the durable fact now exists;
53
+ * 2. the index entry;
54
+ * 3. the DO-local row — ordering and fast reads.
55
+ *
56
+ * A crash after (1) leaves a DO missing a row it can re-derive: a performance problem. The reverse order
57
+ * would leave a row nobody can re-derive: a data-loss problem wearing a performance problem's clothes.
58
+ * The DO write is deliberately LAST and deliberately not awaited-for-correctness — it is a cache.
59
+ */
60
+ const save = async (record) => {
61
+ await vault.write({ owner, resource: exchangeResource(record.exchangeId), data: record, classification: 'internal' });
62
+ await writeIndex(record);
63
+ index?.put(record);
64
+ };
65
+ return {
66
+ async put(record) {
67
+ await save(record);
68
+ },
69
+ async get(exchangeId) {
70
+ const cached = index?.get(String(exchangeId));
71
+ // A cache hit is the SAME answer, not a different mechanism (ADR-0013) — the vault is where it came
72
+ // from and where a miss goes.
73
+ if (cached)
74
+ return cached;
75
+ const obj = await vault.read({ owner, resource: exchangeResource(exchangeId) });
76
+ return obj?.data ?? null;
77
+ },
78
+ async append(exchangeId, event) {
79
+ const current = await this.get(exchangeId);
80
+ if (!current)
81
+ return null;
82
+ const result = applyExchangeEvent(current, event);
83
+ // A REJECTED transition must not touch storage — fail-closed, exactly as the DO-SQL store behaves.
84
+ // Persisting a rejected state "for the audit trail" would make the reducer advisory.
85
+ if (result.ok)
86
+ await save(result.record);
87
+ return result;
88
+ },
89
+ async list() {
90
+ const cached = index?.list();
91
+ if (cached && cached.length > 0)
92
+ return cached;
93
+ const idx = await readIndex();
94
+ const records = await Promise.all(idx.entries.map((e) => this.get(e.exchangeId)));
95
+ return records.filter((r) => r !== null);
96
+ },
97
+ async rebuild() {
98
+ index?.clear();
99
+ const idx = await readIndex();
100
+ const missing = [];
101
+ let recovered = 0;
102
+ for (const entry of idx.entries) {
103
+ const obj = await vault.read({ owner, resource: exchangeResource(entry.exchangeId) });
104
+ // An id in the index with no record behind it is REPORTED, never skipped silently. It means the
105
+ // two vault writes fell apart mid-flight, and a rebuild that quietly dropped the id would erase
106
+ // the only evidence that anything was ever wrong.
107
+ if (!obj?.data) {
108
+ missing.push(entry.exchangeId);
109
+ continue;
110
+ }
111
+ index?.put(obj.data);
112
+ recovered++;
113
+ }
114
+ return { recovered, missing };
115
+ },
116
+ };
117
+ }
118
+ //# sourceMappingURL=vault-exchange-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vault-exchange-store.js","sourceRoot":"","sources":["../../src/cloudflare/vault-exchange-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type { Vault } from '@agenticprimitives/vault';
2
+ import type { InteractionId } from '../interaction-record.js';
3
+ import type { InteractionStore } from './interaction-store.js';
4
+ export declare const INTERACTION_INDEX_RESOURCE = "interaction.index";
5
+ export declare const interactionResource: (id: InteractionId | string) => string;
6
+ export declare const decisionResource: (id: string) => string;
7
+ export declare const commitmentResource: (id: string) => string;
8
+ export declare const snapshotResource: (digest: string) => string;
9
+ export declare const inboxEntryResource: (viewer: string, exchangeId: string) => string;
10
+ export interface InteractionIndexV1 {
11
+ version: 1;
12
+ interactions: string[];
13
+ decisions: string[];
14
+ /** Commitment ids only — state is re-derived from the records on read, never trusted from here.
15
+ * A cached state in an index is a second copy of a machine-owned fact, and the machine owns it. */
16
+ commitments: string[];
17
+ snapshots: string[];
18
+ inboxEntries: Array<{
19
+ viewer: string;
20
+ exchangeId: string;
21
+ }>;
22
+ /** Correlator → interaction ids. DUPLICATES ARE KEPT: two interactions under one correlator is the
23
+ * ambiguity `resolveByBinding` exists to report, and de-duplicating here would resolve it by deletion. */
24
+ bindings: Record<string, string[]>;
25
+ }
26
+ export interface VaultInteractionStore extends InteractionStore {
27
+ /**
28
+ * Reconstruct DO-local state from vault-held records (the ADR-0055 rebuild, in code).
29
+ *
30
+ * Returns per-family counts plus every id whose record is missing. An id in the index with nothing
31
+ * behind it means two vault writes fell apart mid-flight; reporting it is the only way that is ever
32
+ * discovered, since a rebuild that quietly skipped it would return a clean-looking count.
33
+ */
34
+ rebuild(): Promise<{
35
+ recovered: Record<string, number>;
36
+ missing: string[];
37
+ }>;
38
+ }
39
+ export declare function createVaultInteractionStore(vault: Vault, owner: string, cache?: {
40
+ put(resource: string, value: unknown): void;
41
+ get(resource: string): unknown | null;
42
+ clear(): void;
43
+ }): VaultInteractionStore;
44
+ //# sourceMappingURL=vault-interaction-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vault-interaction-store.d.ts","sourceRoot":"","sources":["../../src/cloudflare/vault-interaction-store.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAEtD,OAAO,KAAK,EAAuB,aAAa,EAAqB,MAAM,0BAA0B,CAAC;AAiBtG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,eAAO,MAAM,0BAA0B,sBAAsB,CAAC;AAE9D,eAAO,MAAM,mBAAmB,OAAQ,aAAa,GAAG,MAAM,KAAG,MAAqC,CAAC;AACvG,eAAO,MAAM,gBAAgB,OAAQ,MAAM,KAAG,MAAsC,CAAC;AACrF,eAAO,MAAM,kBAAkB,OAAQ,MAAM,KAAG,MAAwC,CAAC;AACzF,eAAO,MAAM,gBAAgB,WAAY,MAAM,KAAG,MAA0C,CAAC;AAC7F,eAAO,MAAM,kBAAkB,WAAY,MAAM,cAAc,MAAM,KAAG,MACb,CAAC;AAK5D,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,CAAC,CAAC;IACX,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB;wGACoG;IACpG,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D;+GAC2G;IAC3G,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACpC;AAMD,MAAM,WAAW,qBAAsB,SAAQ,gBAAgB;IAC7D;;;;;;OAMG;IACH,OAAO,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CAC9E;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE;IACN,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5C,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IACtC,KAAK,IAAI,IAAI,CAAC;CACf,GACA,qBAAqB,CAuMvB"}
@@ -0,0 +1,245 @@
1
+ // The VAULT-BACKED `InteractionStore` (spec 316 §0b, ADR-0055 amendment, audit G-2).
2
+ //
3
+ // Same residency decision as the exchange store, for the same reason: **each party holds their own copy**.
4
+ // An Interaction is a governed situation with participants, and each participant's vault holds their view
5
+ // of it. No single system of record; no copy authoritative over another. A rebuild is therefore a
6
+ // SINGLE-VAULT read — recovery never waits on a counterparty being reachable, willing, or still extant.
7
+ //
8
+ // SIX FAMILIES, ONE INDEX. Interactions, decisions, commitments, inbox entries, context snapshots and
9
+ // protocol bindings each get their own vault resource; one `interaction.index` document carries the ids.
10
+ // Six index documents would mean six writes to keep in step and six ways for them to drift.
11
+ //
12
+ // THE TWO INVARIANTS OF THE DO-LOCAL STORE ARE PRESERVED EXACTLY, because they are about immutability and
13
+ // they do not become negotiable when the backing store changes:
14
+ //
15
+ // 1. A ContextSnapshot is CONTENT-ADDRESSED and the digest is verified before storing. A forged snapshot
16
+ // is refused at the door rather than detected later. Re-putting a verified digest that is already
17
+ // present is a no-op — that is what content-addressing means.
18
+ // 2. Every transition goes THROUGH its machine. This store never assigns a state, so "the creditor
19
+ // discharges, not the debtor" cannot be bypassed by writing the row. A rejected transition writes
20
+ // NOTHING: persisting it "for the audit trail" would make the machine advisory.
21
+ //
22
+ // It confers nothing. Persisting a commitment does not make it owed; persisting a decision authorizes
23
+ // nothing (ADR-0041).
24
+ import { verifyContextSnapshot } from '../interaction-record.js';
25
+ import { applyInteractionTransition, applyDecisionTransition, applyCommitmentTransition, applyInboxTransition, } from '../interaction-machines.js';
26
+ import { bindingKey, resolveInteractionByBinding, } from '../protocol-binding.js';
27
+ export const INTERACTION_INDEX_RESOURCE = 'interaction.index';
28
+ export const interactionResource = (id) => `interaction:${String(id)}`;
29
+ export const decisionResource = (id) => `interaction.decision:${id}`;
30
+ export const commitmentResource = (id) => `interaction.commitment:${id}`;
31
+ export const snapshotResource = (digest) => `interaction.snapshot:${digest}`;
32
+ export const inboxEntryResource = (viewer, exchangeId) => `interaction.inbox:${viewer.toLowerCase()}:${exchangeId}`;
33
+ /** States an obligation is still live in. `discharged`/`breached`/`void` are ended, differently. */
34
+ const OPEN_COMMITMENT_STATES = new Set(['proposed', 'active', 'fulfilment-claimed']);
35
+ const EMPTY = {
36
+ version: 1, interactions: [], decisions: [], commitments: [], snapshots: [], inboxEntries: [], bindings: {},
37
+ };
38
+ export function createVaultInteractionStore(vault, owner, cache) {
39
+ const readIndex = async () => {
40
+ const obj = await vault.read({ owner, resource: INTERACTION_INDEX_RESOURCE });
41
+ return { ...EMPTY, ...(obj?.data ?? {}) };
42
+ };
43
+ const writeIndex = async (mutate) => {
44
+ const next = mutate(await readIndex());
45
+ await vault.write({ owner, resource: INTERACTION_INDEX_RESOURCE, data: next, classification: 'internal' });
46
+ };
47
+ /** WRITE-THROUGH. The vault first — the durable fact — then the index, then the DO-local cache. A crash
48
+ * after the first leaves a cache that can be re-derived; the reverse order leaves one that cannot. */
49
+ const save = async (resource, data, index) => {
50
+ await vault.write({ owner, resource, data, classification: 'internal' });
51
+ if (index)
52
+ await writeIndex(index);
53
+ cache?.put(resource, data);
54
+ };
55
+ const load = async (resource) => {
56
+ const hit = cache?.get(resource);
57
+ // A cache hit is the SAME answer the vault holds, not a second mechanism (ADR-0013).
58
+ if (hit)
59
+ return hit;
60
+ const obj = await vault.read({ owner, resource });
61
+ return obj?.data ?? null;
62
+ };
63
+ const addOnce = (list, id) => (list.includes(id) ? list : [...list, id]);
64
+ const store = {
65
+ // ── Interactions ────────────────────────────────────────────────────────────────────────────────
66
+ async putInteraction(record) {
67
+ await save(interactionResource(record.interactionId), record, (i) => ({
68
+ ...i, interactions: addOnce(i.interactions, String(record.interactionId)),
69
+ }));
70
+ },
71
+ async getInteraction(id) {
72
+ return load(interactionResource(id));
73
+ },
74
+ async listInteractions() {
75
+ const idx = await readIndex();
76
+ const all = await Promise.all(idx.interactions.map((id) => this.getInteraction(id)));
77
+ return all.filter((r) => r !== null);
78
+ },
79
+ async transitionInteraction(id, event) {
80
+ const record = await this.getInteraction(id);
81
+ if (!record)
82
+ return null;
83
+ const result = applyInteractionTransition(lifecycleOf(record), event);
84
+ // Fail-closed: a rejection leaves the record exactly as it was.
85
+ if (result.ok) {
86
+ await this.putInteraction({
87
+ ...record, lifecycleState: result.next.state, updatedAt: event.at, rev: record.rev + 1,
88
+ });
89
+ }
90
+ return result;
91
+ },
92
+ // ── Protocol bindings ───────────────────────────────────────────────────────────────────────────
93
+ async bindProtocolTo(id, binding) {
94
+ const key = bindingKey(binding.protocol, binding.field, binding.value);
95
+ await writeIndex((i) => ({
96
+ ...i,
97
+ // Appended, never de-duplicated across interactions: a correlator naming two interactions IS the
98
+ // ambiguity, and collapsing it here would answer an ambiguous question with a confident wrong one.
99
+ bindings: { ...i.bindings, [key]: [...(i.bindings[key] ?? []), String(id)] },
100
+ }));
101
+ },
102
+ async resolveByBinding(protocol, field, value) {
103
+ const idx = await readIndex();
104
+ const key = bindingKey(protocol, field, value);
105
+ // Reuses the in-memory resolver so every backing store agrees on what "ambiguous" means.
106
+ return resolveInteractionByBinding(new Map([[key, (idx.bindings[key] ?? [])]]), protocol, field, value);
107
+ },
108
+ // ── Context snapshots (content-addressed) ───────────────────────────────────────────────────────
109
+ async putContextSnapshot(snapshot) {
110
+ // Verified BEFORE storing. A snapshot whose digest does not match its bytes is not evidence, and
111
+ // storing it would make a later verification failure look like tampering rather than corruption.
112
+ if (!(await verifyContextSnapshot(snapshot)))
113
+ return { ok: false, reason: 'digest-mismatch' };
114
+ if (await load(snapshotResource(snapshot.digest))) {
115
+ // Digest verified and already present ⇒ the content is the same. Two parties observing one
116
+ // context legitimately store it twice; the stored bytes win.
117
+ return { ok: true, stored: 'identical' };
118
+ }
119
+ await save(snapshotResource(snapshot.digest), snapshot, (i) => ({
120
+ ...i, snapshots: addOnce(i.snapshots, snapshot.digest),
121
+ }));
122
+ return { ok: true, stored: 'new' };
123
+ },
124
+ async getContextSnapshot(digest) {
125
+ return load(snapshotResource(digest));
126
+ },
127
+ // ── Decisions ───────────────────────────────────────────────────────────────────────────────────
128
+ async putDecision(record) {
129
+ await save(decisionResource(record.decisionId), record, (i) => ({
130
+ ...i, decisions: addOnce(i.decisions, record.decisionId),
131
+ }));
132
+ },
133
+ async getDecision(id) {
134
+ return load(decisionResource(id));
135
+ },
136
+ async transitionDecision(id, event) {
137
+ const record = await this.getDecision(id);
138
+ if (!record)
139
+ return null;
140
+ const result = applyDecisionTransition(record, event);
141
+ if (result.ok)
142
+ await this.putDecision(result.next);
143
+ return result;
144
+ },
145
+ // ── Commitments ─────────────────────────────────────────────────────────────────────────────────
146
+ async putCommitment(record) {
147
+ await save(commitmentResource(record.commitmentId), record, (i) => ({
148
+ ...i, commitments: addOnce(i.commitments, record.commitmentId),
149
+ }));
150
+ },
151
+ async getCommitment(id) {
152
+ return load(commitmentResource(id));
153
+ },
154
+ async listOpenCommitments() {
155
+ const idx = await readIndex();
156
+ const all = await Promise.all(idx.commitments.map((id) => this.getCommitment(id)));
157
+ // Filtered on the RECORD's state, never on a state cached in the index. "What is still owed" is
158
+ // machine-owned, and an index that answered it from its own copy could report an obligation as open
159
+ // after the creditor discharged it — the exact confusion the six machines exist to prevent.
160
+ return all
161
+ .filter((r) => r !== null && OPEN_COMMITMENT_STATES.has(r.state))
162
+ .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
163
+ },
164
+ async transitionCommitment(id, event) {
165
+ const record = await this.getCommitment(id);
166
+ if (!record)
167
+ return null;
168
+ const result = applyCommitmentTransition(record, event);
169
+ if (result.ok)
170
+ await this.putCommitment(result.next);
171
+ return result;
172
+ },
173
+ // ── Inbox entries ───────────────────────────────────────────────────────────────────────────────
174
+ async putInboxEntry(entry) {
175
+ const viewer = String(entry.viewer).toLowerCase();
176
+ await save(inboxEntryResource(viewer, entry.exchangeId), entry, (i) => ({
177
+ ...i,
178
+ inboxEntries: i.inboxEntries.some((e) => e.viewer === viewer && e.exchangeId === entry.exchangeId)
179
+ ? i.inboxEntries
180
+ : [...i.inboxEntries, { viewer, exchangeId: entry.exchangeId }],
181
+ }));
182
+ },
183
+ async getInboxEntry(viewer, exchangeId) {
184
+ return load(inboxEntryResource(String(viewer), exchangeId));
185
+ },
186
+ async transitionInbox(viewer, exchangeId, event) {
187
+ const entry = await this.getInboxEntry(viewer, exchangeId);
188
+ if (!entry)
189
+ return null;
190
+ const result = applyInboxTransition(entry, event);
191
+ if (result.ok)
192
+ await this.putInboxEntry(result.next);
193
+ return result;
194
+ },
195
+ // ── Rebuild ─────────────────────────────────────────────────────────────────────────────────────
196
+ async rebuild() {
197
+ cache?.clear();
198
+ const idx = await readIndex();
199
+ const missing = [];
200
+ const recovered = {
201
+ interactions: 0, decisions: 0, commitments: 0, snapshots: 0, inboxEntries: 0,
202
+ };
203
+ const pull = async (family, resource) => {
204
+ const obj = await vault.read({ owner, resource });
205
+ if (!obj?.data) {
206
+ missing.push(resource);
207
+ return;
208
+ }
209
+ cache?.put(resource, obj.data);
210
+ recovered[family] = (recovered[family] ?? 0) + 1;
211
+ };
212
+ for (const id of idx.interactions)
213
+ await pull('interactions', interactionResource(id));
214
+ for (const id of idx.decisions)
215
+ await pull('decisions', decisionResource(id));
216
+ for (const id of idx.commitments)
217
+ await pull('commitments', commitmentResource(id));
218
+ for (const d of idx.snapshots)
219
+ await pull('snapshots', snapshotResource(d));
220
+ for (const e of idx.inboxEntries)
221
+ await pull('inboxEntries', inboxEntryResource(e.viewer, e.exchangeId));
222
+ return { recovered, missing };
223
+ },
224
+ };
225
+ return store;
226
+ }
227
+ /**
228
+ * The lifecycle facet of a stored interaction, for the machine to operate on.
229
+ *
230
+ * `principal` and `participations` are NOT optional decoration. The interaction machine decides who may
231
+ * drive a transition from them, so a facet that omitted them would hand the machine an interaction with
232
+ * no participants and no custodian — every transition rejected, for a reason that reads like a state-model
233
+ * problem. (Which is how this was found: the first version dropped both and the legal-transition test
234
+ * failed while the rejection tests still "passed".)
235
+ */
236
+ function lifecycleOf(record) {
237
+ return {
238
+ interactionId: record.interactionId,
239
+ state: record.lifecycleState,
240
+ principal: record.principal,
241
+ participations: record.participations,
242
+ updatedAt: record.updatedAt,
243
+ };
244
+ }
245
+ //# sourceMappingURL=vault-interaction-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vault-interaction-store.js","sourceRoot":"","sources":["../../src/cloudflare/vault-interaction-store.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,EAAE;AACF,2GAA2G;AAC3G,0GAA0G;AAC1G,kGAAkG;AAClG,wGAAwG;AACxG,EAAE;AACF,sGAAsG;AACtG,yGAAyG;AACzG,4FAA4F;AAC5F,EAAE;AACF,0GAA0G;AAC1G,gEAAgE;AAChE,EAAE;AACF,2GAA2G;AAC3G,uGAAuG;AACvG,mEAAmE;AACnE,qGAAqG;AACrG,uGAAuG;AACvG,qFAAqF;AACrF,EAAE;AACF,sGAAsG;AACtG,sBAAsB;AAKtB,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EACL,0BAA0B,EAC1B,uBAAuB,EACvB,yBAAyB,EACzB,oBAAoB,GAKrB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,UAAU,EACV,2BAA2B,GAE5B,MAAM,wBAAwB,CAAC;AAGhC,MAAM,CAAC,MAAM,0BAA0B,GAAG,mBAAmB,CAAC;AAE9D,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,EAA0B,EAAU,EAAE,CAAC,eAAe,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;AACvG,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAAU,EAAU,EAAE,CAAC,wBAAwB,EAAE,EAAE,CAAC;AACrF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,EAAU,EAAU,EAAE,CAAC,0BAA0B,EAAE,EAAE,CAAC;AACzF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,MAAc,EAAU,EAAE,CAAC,wBAAwB,MAAM,EAAE,CAAC;AAC7F,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAc,EAAE,UAAkB,EAAU,EAAE,CAC/E,qBAAqB,MAAM,CAAC,WAAW,EAAE,IAAI,UAAU,EAAE,CAAC;AAE5D,oGAAoG;AACpG,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAC;AAgBrF,MAAM,KAAK,GAAuB;IAChC,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;CAC5G,CAAC;AAaF,MAAM,UAAU,2BAA2B,CACzC,KAAY,EACZ,KAAa,EACb,KAIC;IAED,MAAM,SAAS,GAAG,KAAK,IAAiC,EAAE;QACxD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAqB,EAAE,KAAK,EAAE,QAAQ,EAAE,0BAA0B,EAAE,CAAC,CAAC;QAClG,OAAO,EAAE,GAAG,KAAK,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;IAC5C,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,KAAK,EAAE,MAAuD,EAAiB,EAAE;QAClG,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,SAAS,EAAE,CAAC,CAAC;QACvC,MAAM,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,0BAA0B,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC,CAAC;IAC7G,CAAC,CAAC;IAEF;2GACuG;IACvG,MAAM,IAAI,GAAG,KAAK,EAAE,QAAgB,EAAE,IAAa,EAAE,KAAqD,EAAiB,EAAE;QAC3H,MAAM,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC,CAAC;QACzE,IAAI,KAAK;YAAE,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;QACnC,KAAK,EAAE,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC7B,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,KAAK,EAAK,QAAgB,EAAqB,EAAE;QAC5D,MAAM,GAAG,GAAG,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjC,qFAAqF;QACrF,IAAI,GAAG;YAAE,OAAO,GAAQ,CAAC;QACzB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrD,OAAO,GAAG,EAAE,IAAI,IAAI,IAAI,CAAC;IAC3B,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,IAAc,EAAE,EAAU,EAAY,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IAErG,MAAM,KAAK,GAA0B;QACnC,mGAAmG;QACnG,KAAK,CAAC,cAAc,CAAC,MAAM;YACzB,MAAM,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACpE,GAAG,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;aAC1E,CAAC,CAAC,CAAC;QACN,CAAC;QAED,KAAK,CAAC,cAAc,CAAC,EAAE;YACrB,OAAO,IAAI,CAAsB,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5D,CAAC;QAED,KAAK,CAAC,gBAAgB;YACpB,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACrF,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAA4B,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QACjE,CAAC;QAED,KAAK,CAAC,qBAAqB,CAAC,EAAE,EAAE,KAAK;YACnC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;YAC7C,IAAI,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC;YACzB,MAAM,MAAM,GAAG,0BAA0B,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;YACtE,gEAAgE;YAChE,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;gBACd,MAAM,IAAI,CAAC,cAAc,CAAC;oBACxB,GAAG,MAAM,EAAE,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC;iBACvF,CAAC,CAAC;YACL,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,mGAAmG;QACnG,KAAK,CAAC,cAAc,CAAC,EAAE,EAAE,OAAO;YAC9B,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;YACvE,MAAM,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACvB,GAAG,CAAC;gBACJ,iGAAiG;gBACjG,mGAAmG;gBACnG,QAAQ,EAAE,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE;aAC7E,CAAC,CAAC,CAAC;QACN,CAAC;QAED,KAAK,CAAC,gBAAgB,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK;YAC3C,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YAC/C,yFAAyF;YACzF,OAAO,2BAA2B,CAChC,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAoB,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CACvF,CAAC;QACJ,CAAC;QAED,mGAAmG;QACnG,KAAK,CAAC,kBAAkB,CAAC,QAAQ;YAC/B,iGAAiG;YACjG,iGAAiG;YACjG,IAAI,CAAC,CAAC,MAAM,qBAAqB,CAAC,QAAQ,CAAC,CAAC;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;YAC9F,IAAI,MAAM,IAAI,CAAoB,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;gBACrE,2FAA2F;gBAC3F,6DAA6D;gBAC7D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;YAC3C,CAAC;YACD,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC9D,GAAG,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC;aACvD,CAAC,CAAC,CAAC;YACJ,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QACrC,CAAC;QAED,KAAK,CAAC,kBAAkB,CAAC,MAAM;YAC7B,OAAO,IAAI,CAAoB,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3D,CAAC;QAED,mGAAmG;QACnG,KAAK,CAAC,WAAW,CAAC,MAAM;YACtB,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC9D,GAAG,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC;aACzD,CAAC,CAAC,CAAC;QACN,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,EAAE;YAClB,OAAO,IAAI,CAAmB,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC;QACtD,CAAC;QAED,KAAK,CAAC,kBAAkB,CAAC,EAAE,EAAE,KAAK;YAChC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;YAC1C,IAAI,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC;YACzB,MAAM,MAAM,GAAG,uBAAuB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACtD,IAAI,MAAM,CAAC,EAAE;gBAAE,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACnD,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,mGAAmG;QACnG,KAAK,CAAC,aAAa,CAAC,MAAM;YACxB,MAAM,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAClE,GAAG,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,YAAY,CAAC;aAC/D,CAAC,CAAC,CAAC;QACN,CAAC;QAED,KAAK,CAAC,aAAa,CAAC,EAAE;YACpB,OAAO,IAAI,CAAqB,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1D,CAAC;QAED,KAAK,CAAC,mBAAmB;YACvB,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAC;YAC9B,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACnF,gGAAgG;YAChG,oGAAoG;YACpG,4FAA4F;YAC5F,OAAO,GAAG;iBACP,MAAM,CAAC,CAAC,CAAC,EAA2B,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,sBAAsB,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;iBACzF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QAC5D,CAAC;QAED,KAAK,CAAC,oBAAoB,CAAC,EAAE,EAAE,KAAK;YAClC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAC5C,IAAI,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC;YACzB,MAAM,MAAM,GAAG,yBAAyB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACxD,IAAI,MAAM,CAAC,EAAE;gBAAE,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACrD,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,mGAAmG;QACnG,KAAK,CAAC,aAAa,CAAC,KAAK;YACvB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;YAClD,MAAM,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACtE,GAAG,CAAC;gBACJ,YAAY,EAAE,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,UAAU,KAAK,KAAK,CAAC,UAAU,CAAC;oBAChG,CAAC,CAAC,CAAC,CAAC,YAAY;oBAChB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;aAClE,CAAC,CAAC,CAAC;QACN,CAAC;QAED,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,UAAU;YACpC,OAAO,IAAI,CAAe,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC;QAC5E,CAAC;QAED,KAAK,CAAC,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK;YAC7C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAC3D,IAAI,CAAC,KAAK;gBAAE,OAAO,IAAI,CAAC;YACxB,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAClD,IAAI,MAAM,CAAC,EAAE;gBAAE,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACrD,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,mGAAmG;QACnG,KAAK,CAAC,OAAO;YACX,KAAK,EAAE,KAAK,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAa,EAAE,CAAC;YAC7B,MAAM,SAAS,GAA2B;gBACxC,YAAY,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC;aAC7E,CAAC;YAEF,MAAM,IAAI,GAAG,KAAK,EAAE,MAAc,EAAE,QAAgB,EAAiB,EAAE;gBACrE,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAClD,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;oBAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAAC,OAAO;gBAAC,CAAC;gBACnD,KAAK,EAAE,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC/B,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACnD,CAAC,CAAC;YAEF,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,YAAY;gBAAE,MAAM,IAAI,CAAC,cAAc,EAAE,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC;YACvF,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,SAAS;gBAAE,MAAM,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC;YAC9E,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,WAAW;gBAAE,MAAM,IAAI,CAAC,aAAa,EAAE,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC;YACpF,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,SAAS;gBAAE,MAAM,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5E,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,YAAY;gBAAE,MAAM,IAAI,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;YAEzG,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;QAChC,CAAC;KACF,CAAC;IAEF,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,WAAW,CAAC,MAA2B;IAC9C,OAAO;QACL,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,KAAK,EAAE,MAAM,CAAC,cAAc;QAC5B,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC;AACJ,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { CanonicalAgentId } from '@agenticprimitives/types';
2
- import type { Hex32, MessageId, MessageKind } from './messaging/index.js';
2
+ import type { Hex32, MessageId, MessageKind, MessageEnvelopeV1, AnyMessageEnvelope } from './messaging/index.js';
3
3
  import type { VaultRef } from '@agenticprimitives/vault';
4
4
  export type Performative = 'INFORM' | 'QUERY' | 'REQUEST' | 'PROPOSE' | 'COUNTER' | 'ACCEPT' | 'REJECT' | 'NOTIFY' | 'ACKNOWLEDGE' | 'ISSUE' | 'RETRACT' | 'SUBSCRIBE' | 'UNSUBSCRIBE';
5
5
  /** A by-reference pointer at a piece of semantic content an act expresses or carries — a Situation, a
@@ -38,6 +38,29 @@ export interface CommunicativeActV1 {
38
38
  /** The message this act responds to, if any. */
39
39
  inRespondsTo?: MessageId;
40
40
  }
41
+ /**
42
+ * The performative of ANY envelope — the dual-read seam (spec 340 W9).
43
+ *
44
+ * V2 states it; V1 derives it. One mechanism per version, never a fallback chain: a V2 envelope is
45
+ * never re-derived from a kind it does not have, and a V1 envelope never invents a `performative`
46
+ * field (ADR-0013).
47
+ */
48
+ export declare function performativeOf(envelope: AnyMessageEnvelope, act?: CommunicativeActV1): Performative;
49
+ /**
50
+ * Is this an ORIGINAL message rather than a reply?
51
+ *
52
+ * THE READER THAT FOUND A LATENT BUG. The auto-reply gate was `kind !== 'plain'`, which excluded
53
+ * `response` — so the assistant never replied to a reply. Under V2 that exclusion evaporates, because
54
+ * `plain` and `response` BOTH map to `INFORM` and are indistinguishable by performative alone. A naive
55
+ * translation to `performative === 'INFORM'` would have made the assistant start answering replies,
56
+ * i.e. answering itself.
57
+ *
58
+ * The fix is not to keep the taxonomy. It is that `inReplyTo` — the causal edge — was always the thing
59
+ * that actually distinguished them, and the enum had been standing in for it. Expressing the rule as
60
+ * "an original message has no antecedent" is both correct under V1 and correct under V2, and it says
61
+ * what the rule means instead of naming a label that implied it.
62
+ */
63
+ export declare function isOriginalMessage(envelope: Pick<MessageEnvelopeV1, 'inReplyTo'>): boolean;
41
64
  /**
42
65
  * The TOTAL `MessageKind` → `Performative` derivation for V1 envelopes (spec 324 §9). Exhaustive: every
43
66
  * `MessageKind` maps. A `response` refines to the act's performative when it is one of the response family
@@ -1 +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"}
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,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAEjH,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;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,kBAAkB,EAAE,GAAG,CAAC,EAAE,kBAAkB,GAAG,YAAY,CAEnG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC,GAAG,OAAO,CAEzF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC,EAAE,kBAAkB,GAAG,YAAY,CAmB7F"}
@@ -8,6 +8,34 @@
8
8
  // V1 envelopes carry no native performative, so for legacy/communication envelopes the performative is DERIVED
9
9
  // from `MessageKind` via one TOTAL mapping (`performativeForKind`, golden-vectored). A future `ap.exchange.v2`
10
10
  // envelope carries `performative`/`actor`/`principal` natively.
11
+ import { isEnvelopeV2 } from './messaging/index.js';
12
+ /**
13
+ * The performative of ANY envelope — the dual-read seam (spec 340 W9).
14
+ *
15
+ * V2 states it; V1 derives it. One mechanism per version, never a fallback chain: a V2 envelope is
16
+ * never re-derived from a kind it does not have, and a V1 envelope never invents a `performative`
17
+ * field (ADR-0013).
18
+ */
19
+ export function performativeOf(envelope, act) {
20
+ return isEnvelopeV2(envelope) ? envelope.performative : performativeForKind(envelope.kind, act);
21
+ }
22
+ /**
23
+ * Is this an ORIGINAL message rather than a reply?
24
+ *
25
+ * THE READER THAT FOUND A LATENT BUG. The auto-reply gate was `kind !== 'plain'`, which excluded
26
+ * `response` — so the assistant never replied to a reply. Under V2 that exclusion evaporates, because
27
+ * `plain` and `response` BOTH map to `INFORM` and are indistinguishable by performative alone. A naive
28
+ * translation to `performative === 'INFORM'` would have made the assistant start answering replies,
29
+ * i.e. answering itself.
30
+ *
31
+ * The fix is not to keep the taxonomy. It is that `inReplyTo` — the causal edge — was always the thing
32
+ * that actually distinguished them, and the enum had been standing in for it. Expressing the rule as
33
+ * "an original message has no antecedent" is both correct under V1 and correct under V2, and it says
34
+ * what the rule means instead of naming a label that implied it.
35
+ */
36
+ export function isOriginalMessage(envelope) {
37
+ return envelope.inReplyTo === undefined;
38
+ }
11
39
  /**
12
40
  * The TOTAL `MessageKind` → `Performative` derivation for V1 envelopes (spec 324 §9). Exhaustive: every
13
41
  * `MessageKind` maps. A `response` refines to the act's performative when it is one of the response family
@@ -1 +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"}
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;AAIhE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AA8CpD;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,QAA4B,EAAE,GAAwB;IACnF,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAClG,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAA8C;IAC9E,OAAO,QAAQ,CAAC,SAAS,KAAK,SAAS,CAAC;AAC1C,CAAC;AAED;;;;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"}
@@ -1 +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"}
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,CAclB"}
@@ -29,7 +29,6 @@ export function deliveryToExchangeRecord(delivery, opts) {
29
29
  return {
30
30
  version: 'ap.exchange.v1',
31
31
  exchangeId: delivery.exchangeId,
32
- kind: e.kind,
33
32
  tier: opts.tier,
34
33
  principal: delivery.toGateway,
35
34
  parties: { from: e.from, to: e.to },
@@ -1 +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"}
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,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"}
@@ -0,0 +1,43 @@
1
+ import type { MessageKind } from './messaging/index.js';
2
+ import type { CaseState } from './exchange-state.js';
3
+ import type { ProfileVersion } from './interaction-record.js';
4
+ /**
5
+ * Every `MessageKind` (still the ENVELOPE's, see the header), mapped to the profile that replaces it.
6
+ *
7
+ * `Record<MessageKind, …>` rather than a lookup function: adding a `MessageKind` without deciding its
8
+ * profile then fails the build, which is the only way a "total" mapping stays total.
9
+ *
10
+ * Three of the seven collapse onto `direct`, and that is the finding rather than laziness. `plain`,
11
+ * `system` and `tombstone` were never different KINDS of interaction — they are a message, a message
12
+ * from the substrate, and a deletion marker. They differed in rendering, not in what was permitted,
13
+ * which is exactly the kind of distinction an interaction-type enum should not have been carrying.
14
+ */
15
+ export declare const PROFILE_FOR_MESSAGE_KIND: Record<MessageKind, ProfileVersion>;
16
+ /** Which of the six machines each `CaseState` actually belongs to. */
17
+ export type OwningMachine = 'execution' | 'decision' | 'commitment';
18
+ /**
19
+ * Every `CaseState`, mapped to the machine that owns it.
20
+ *
21
+ * THE POINT OF THIS TABLE: the eleven states were never one machine's. `denied` is a DECISION,
22
+ * `completed` is an EXECUTION outcome, and `revoked` is what happens to a COMMITMENT — three
23
+ * different questions with three different signers, answered by one field. That is why a case could
24
+ * be `denied` and a commitment still outstanding with nowhere to say so.
25
+ *
26
+ * `issued` and `approved` are the two that look ambiguous and are not: approving is a decision,
27
+ * issuing is work performed under it. Reading `approved` as execution progress is precisely the
28
+ * "deciding is not doing" collapse.
29
+ */
30
+ export declare const MACHINE_FOR_CASE_STATE: Record<CaseState, OwningMachine>;
31
+ /**
32
+ * How many distinct machines the single `CaseState` field stands in for.
33
+ *
34
+ * It was THREE, and that number was the whole argument for W10b-3. It is now ONE, and this function is
35
+ * kept — rather than deleted along with the states — precisely so that claim stays falsifiable: if
36
+ * anyone re-adds a decision-shaped or commitment-shaped member to `CaseState`, they must give it a home
37
+ * in the table above, and this count moves off 1 and the test fails.
38
+ *
39
+ * A cleanup is not finished when the code compiles; it is finished when re-introducing the thing you
40
+ * removed is caught automatically.
41
+ */
42
+ export declare function machinesSpannedByCaseState(): number;
43
+ //# sourceMappingURL=enum-retirement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enum-retirement.d.ts","sourceRoot":"","sources":["../src/enum-retirement.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAG9D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,WAAW,EAAE,cAAc,CAcxE,CAAC;AAEF,sEAAsE;AACtE,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,CAAC;AAEpE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,SAAS,EAAE,aAAa,CASnE,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAEnD"}