@agenticprimitives/fabric 0.0.0-alpha.3 → 0.0.0-alpha.30

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 (185) hide show
  1. package/CLAUDE.md +30 -29
  2. package/README.md +18 -16
  3. package/dist/adoption.d.ts +79 -0
  4. package/dist/adoption.d.ts.map +1 -0
  5. package/dist/adoption.js +95 -0
  6. package/dist/adoption.js.map +1 -0
  7. package/dist/case-emissions.d.ts +95 -0
  8. package/dist/case-emissions.d.ts.map +1 -0
  9. package/dist/case-emissions.js +208 -0
  10. package/dist/case-emissions.js.map +1 -0
  11. package/dist/case-machine.d.ts +28 -2
  12. package/dist/case-machine.d.ts.map +1 -1
  13. package/dist/case-machine.js +34 -7
  14. package/dist/case-machine.js.map +1 -1
  15. package/dist/cloudflare/authority-verdict-cache.d.ts +28 -1
  16. package/dist/cloudflare/authority-verdict-cache.d.ts.map +1 -1
  17. package/dist/cloudflare/authority-verdict-cache.js +32 -1
  18. package/dist/cloudflare/authority-verdict-cache.js.map +1 -1
  19. package/dist/cloudflare/index.d.ts +4 -1
  20. package/dist/cloudflare/index.d.ts.map +1 -1
  21. package/dist/cloudflare/index.js +7 -1
  22. package/dist/cloudflare/index.js.map +1 -1
  23. package/dist/cloudflare/interaction-store.d.ts +55 -0
  24. package/dist/cloudflare/interaction-store.d.ts.map +1 -0
  25. package/dist/cloudflare/interaction-store.js +230 -0
  26. package/dist/cloudflare/interaction-store.js.map +1 -0
  27. package/dist/cloudflare/principal-gateway-do.d.ts +136 -2
  28. package/dist/cloudflare/principal-gateway-do.d.ts.map +1 -1
  29. package/dist/cloudflare/principal-gateway-do.js +190 -8
  30. package/dist/cloudflare/principal-gateway-do.js.map +1 -1
  31. package/dist/cloudflare/sql-vault.d.ts.map +1 -1
  32. package/dist/cloudflare/sql-vault.js +56 -0
  33. package/dist/cloudflare/sql-vault.js.map +1 -1
  34. package/dist/cloudflare/vault-exchange-store.d.ts +47 -0
  35. package/dist/cloudflare/vault-exchange-store.d.ts.map +1 -0
  36. package/dist/cloudflare/vault-exchange-store.js +118 -0
  37. package/dist/cloudflare/vault-exchange-store.js.map +1 -0
  38. package/dist/cloudflare/vault-interaction-store.d.ts +44 -0
  39. package/dist/cloudflare/vault-interaction-store.d.ts.map +1 -0
  40. package/dist/cloudflare/vault-interaction-store.js +245 -0
  41. package/dist/cloudflare/vault-interaction-store.js.map +1 -0
  42. package/dist/communicative-act.d.ts +24 -1
  43. package/dist/communicative-act.d.ts.map +1 -1
  44. package/dist/communicative-act.js +28 -0
  45. package/dist/communicative-act.js.map +1 -1
  46. package/dist/delivery-envelope.d.ts.map +1 -1
  47. package/dist/delivery-envelope.js +0 -1
  48. package/dist/delivery-envelope.js.map +1 -1
  49. package/dist/email/index.d.ts +75 -0
  50. package/dist/email/index.d.ts.map +1 -0
  51. package/dist/email/index.js +77 -0
  52. package/dist/email/index.js.map +1 -0
  53. package/dist/enum-retirement.d.ts +43 -0
  54. package/dist/enum-retirement.d.ts.map +1 -0
  55. package/dist/enum-retirement.js +93 -0
  56. package/dist/enum-retirement.js.map +1 -0
  57. package/dist/exchange-record.d.ts +35 -4
  58. package/dist/exchange-record.d.ts.map +1 -1
  59. package/dist/exchange-record.js.map +1 -1
  60. package/dist/exchange-reducer.d.ts +32 -4
  61. package/dist/exchange-reducer.d.ts.map +1 -1
  62. package/dist/exchange-reducer.js +75 -1
  63. package/dist/exchange-reducer.js.map +1 -1
  64. package/dist/exchange-state.d.ts +30 -8
  65. package/dist/exchange-state.d.ts.map +1 -1
  66. package/dist/exchange-state.js +12 -10
  67. package/dist/exchange-state.js.map +1 -1
  68. package/dist/inbox-doc.d.ts +2 -2
  69. package/dist/inbox-doc.d.ts.map +1 -1
  70. package/dist/inbox-doc.js.map +1 -1
  71. package/dist/inbox-projection.d.ts +2 -2
  72. package/dist/inbox-projection.d.ts.map +1 -1
  73. package/dist/inbox-projection.js.map +1 -1
  74. package/dist/inbox-revision.d.ts +42 -0
  75. package/dist/inbox-revision.d.ts.map +1 -0
  76. package/dist/inbox-revision.js +57 -0
  77. package/dist/inbox-revision.js.map +1 -0
  78. package/dist/index.d.ts +26 -3
  79. package/dist/index.d.ts.map +1 -1
  80. package/dist/index.js +40 -2
  81. package/dist/index.js.map +1 -1
  82. package/dist/interaction-machines.d.ts +136 -0
  83. package/dist/interaction-machines.d.ts.map +1 -0
  84. package/dist/interaction-machines.js +174 -0
  85. package/dist/interaction-machines.js.map +1 -0
  86. package/dist/interaction-profile.d.ts +136 -0
  87. package/dist/interaction-profile.d.ts.map +1 -0
  88. package/dist/interaction-profile.js +212 -0
  89. package/dist/interaction-profile.js.map +1 -0
  90. package/dist/interaction-record.d.ts +168 -0
  91. package/dist/interaction-record.d.ts.map +1 -0
  92. package/dist/interaction-record.js +108 -0
  93. package/dist/interaction-record.js.map +1 -0
  94. package/dist/interactions/grant-scopes.d.ts +21 -0
  95. package/dist/interactions/grant-scopes.d.ts.map +1 -0
  96. package/dist/interactions/grant-scopes.js +88 -0
  97. package/dist/interactions/grant-scopes.js.map +1 -0
  98. package/dist/interactions/index.d.ts +1 -0
  99. package/dist/interactions/index.d.ts.map +1 -1
  100. package/dist/interactions/index.js +3 -0
  101. package/dist/interactions/index.js.map +1 -1
  102. package/dist/interactions/machine.d.ts +2 -2
  103. package/dist/interactions/machine.d.ts.map +1 -1
  104. package/dist/interactions/machine.js +2 -2
  105. package/dist/interactions/machine.js.map +1 -1
  106. package/dist/interactions/open-case.d.ts +60 -0
  107. package/dist/interactions/open-case.d.ts.map +1 -0
  108. package/dist/interactions/open-case.js +83 -0
  109. package/dist/interactions/open-case.js.map +1 -0
  110. package/dist/interactions/store.d.ts +9 -0
  111. package/dist/interactions/store.d.ts.map +1 -1
  112. package/dist/interactions/store.js +57 -2
  113. package/dist/interactions/store.js.map +1 -1
  114. package/dist/messaging/board.d.ts +3 -3
  115. package/dist/messaging/board.d.ts.map +1 -1
  116. package/dist/messaging/board.js +2 -2
  117. package/dist/messaging/board.js.map +1 -1
  118. package/dist/messaging/consult-routing.d.ts +21 -14
  119. package/dist/messaging/consult-routing.d.ts.map +1 -1
  120. package/dist/messaging/consult-routing.js +34 -25
  121. package/dist/messaging/consult-routing.js.map +1 -1
  122. package/dist/messaging/consult.d.ts +4 -0
  123. package/dist/messaging/consult.d.ts.map +1 -1
  124. package/dist/messaging/consult.js +3 -1
  125. package/dist/messaging/consult.js.map +1 -1
  126. package/dist/messaging/conversation-interaction.d.ts +66 -0
  127. package/dist/messaging/conversation-interaction.d.ts.map +1 -0
  128. package/dist/messaging/conversation-interaction.js +139 -0
  129. package/dist/messaging/conversation-interaction.js.map +1 -0
  130. package/dist/messaging/conversation.d.ts +69 -1
  131. package/dist/messaging/conversation.d.ts.map +1 -1
  132. package/dist/messaging/conversation.js +131 -0
  133. package/dist/messaging/conversation.js.map +1 -1
  134. package/dist/messaging/delivery.d.ts +2 -2
  135. package/dist/messaging/delivery.d.ts.map +1 -1
  136. package/dist/messaging/delivery.js +8 -1
  137. package/dist/messaging/delivery.js.map +1 -1
  138. package/dist/messaging/envelope.d.ts +7 -3
  139. package/dist/messaging/envelope.d.ts.map +1 -1
  140. package/dist/messaging/envelope.js +18 -1
  141. package/dist/messaging/envelope.js.map +1 -1
  142. package/dist/messaging/hash.d.ts +8 -2
  143. package/dist/messaging/hash.d.ts.map +1 -1
  144. package/dist/messaging/hash.js +6 -0
  145. package/dist/messaging/hash.js.map +1 -1
  146. package/dist/messaging/inbox-assistant.d.ts +16 -4
  147. package/dist/messaging/inbox-assistant.d.ts.map +1 -1
  148. package/dist/messaging/inbox-assistant.js +27 -4
  149. package/dist/messaging/inbox-assistant.js.map +1 -1
  150. package/dist/messaging/index.d.ts +6 -2
  151. package/dist/messaging/index.d.ts.map +1 -1
  152. package/dist/messaging/index.js +10 -1
  153. package/dist/messaging/index.js.map +1 -1
  154. package/dist/messaging/outbound-message.d.ts +42 -0
  155. package/dist/messaging/outbound-message.d.ts.map +1 -0
  156. package/dist/messaging/outbound-message.js +64 -0
  157. package/dist/messaging/outbound-message.js.map +1 -0
  158. package/dist/messaging/projector.d.ts +3 -3
  159. package/dist/messaging/projector.d.ts.map +1 -1
  160. package/dist/messaging/projector.js.map +1 -1
  161. package/dist/messaging/receipts.d.ts +3 -3
  162. package/dist/messaging/receipts.d.ts.map +1 -1
  163. package/dist/messaging/receipts.js.map +1 -1
  164. package/dist/messaging/rules.d.ts +10 -3
  165. package/dist/messaging/rules.d.ts.map +1 -1
  166. package/dist/messaging/rules.js +8 -1
  167. package/dist/messaging/rules.js.map +1 -1
  168. package/dist/messaging/store.d.ts +4 -4
  169. package/dist/messaging/store.d.ts.map +1 -1
  170. package/dist/messaging/store.js +5 -3
  171. package/dist/messaging/store.js.map +1 -1
  172. package/dist/messaging/types.d.ts +30 -0
  173. package/dist/messaging/types.d.ts.map +1 -1
  174. package/dist/messaging/types.js +3 -0
  175. package/dist/messaging/types.js.map +1 -1
  176. package/dist/messaging/vault-store.d.ts +2 -2
  177. package/dist/messaging/vault-store.d.ts.map +1 -1
  178. package/dist/protocol-binding.d.ts +71 -0
  179. package/dist/protocol-binding.d.ts.map +1 -0
  180. package/dist/protocol-binding.js +0 -0
  181. package/dist/protocol-binding.js.map +1 -0
  182. package/dist/record-catalog.d.ts.map +1 -1
  183. package/dist/record-catalog.js +12 -0
  184. package/dist/record-catalog.js.map +1 -1
  185. package/package.json +28 -15
@@ -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,75 @@
1
+ /** What a provider needs to send one message. Deliberately small — no attachments, no templates. */
2
+ export interface OutboundEmailV1 {
3
+ to: string;
4
+ subject: string;
5
+ text: string;
6
+ /** Optional HTML alternative. Providers that cannot send it fall back to `text`. */
7
+ html?: string;
8
+ /** Set when this mail continues a conversation, so replies thread in the recipient's mail client. */
9
+ inReplyTo?: string;
10
+ }
11
+ export interface EmailSendResultV1 {
12
+ ok: boolean;
13
+ /** The provider's own id for the message, when it gives one — kept so a thread can cite it. */
14
+ messageId?: string;
15
+ error?: string;
16
+ /** Which provider actually sent it. Recorded, because "the email went" is a different fact per rail. */
17
+ via?: string;
18
+ }
19
+ /**
20
+ * THE PORT. One method, and the implementations are leaves.
21
+ *
22
+ * `available` is separate from `send` on purpose: a surface must be able to say "email is not set up
23
+ * here" BEFORE offering somebody an email invitation, rather than accepting the address and failing.
24
+ */
25
+ export interface EmailSenderPort {
26
+ readonly name: string;
27
+ available(): boolean;
28
+ send(msg: OutboundEmailV1): Promise<EmailSendResultV1>;
29
+ }
30
+ /**
31
+ * TWO INTEGRATIONS, ONE PORT — the first that is available sends.
32
+ *
33
+ * Not a fallback chain (ADR-0013): the order is a DEPLOYMENT PREFERENCE stated once, and a provider that
34
+ * is configured but fails returns an error rather than handing the message to the next one. Sending the
35
+ * same mail twice because the first attempt's response was slow is worse than not sending it.
36
+ */
37
+ export declare function firstAvailableSender(senders: readonly EmailSenderPort[]): EmailSenderPort | null;
38
+ /** An inbound message, already parsed. The adapter does the MIME; this is what the inbox needs. */
39
+ export interface InboundEmailV1 {
40
+ /** What the mail was sent TO — the only routable fact in it. */
41
+ to: string;
42
+ /** What it CLAIMS to be from. Unverified by construction; shown as a claim, never resolved as identity. */
43
+ from: string;
44
+ subject: string;
45
+ text: string;
46
+ /** Provider message id, for de-duplication and for citing the mail this message came from. */
47
+ messageId?: string;
48
+ /** Names only. An attachment is announced, never admitted (rule 4). */
49
+ attachments?: Array<{
50
+ name: string;
51
+ size?: number;
52
+ contentType?: string;
53
+ }>;
54
+ }
55
+ /** The handle an address routes to: `alice@faithnet.me` → `alice`. Empty when the zone is not ours. */
56
+ export declare function handleFromAddress(address: string, zones: readonly string[]): string;
57
+ /** Is this a well-formed address at all? Shape only — nothing here says a mailbox exists. */
58
+ export declare function isEmailAddress(v: string): boolean;
59
+ export declare const EMAIL_BODY_LIMIT = 16000;
60
+ /**
61
+ * An inbound email as the message a thread will hold.
62
+ *
63
+ * WHAT IT KEEPS: the words, who it says it is from, what it was about, and what came with it BY NAME.
64
+ * WHAT IT REFUSES: anything past the cap (truncated, and it says so — a body silently cut in half is a
65
+ * message that misleads), and every attachment's content.
66
+ *
67
+ * The result is deliberately plain text: a thread that renders remote HTML from an unverified sender is
68
+ * a phishing surface with a nice font.
69
+ */
70
+ export declare function inboundEmailToMessage(mail: InboundEmailV1): {
71
+ bodyText: string;
72
+ subject: string;
73
+ claimedFrom: string;
74
+ };
75
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/email/index.ts"],"names":[],"mappings":"AAwBA,oGAAoG;AACpG,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qGAAqG;IACrG,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,+FAA+F;IAC/F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wGAAwG;IACxG,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,SAAS,IAAI,OAAO,CAAC;IACrB,IAAI,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACxD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,GAAG,eAAe,GAAG,IAAI,CAEhG;AAED,mGAAmG;AACnG,MAAM,WAAW,cAAc;IAC7B,gEAAgE;IAChE,EAAE,EAAE,MAAM,CAAC;IACX,2GAA2G;IAC3G,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,8FAA8F;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5E;AAED,uGAAuG;AACvG,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAQnF;AAED,6FAA6F;AAC7F,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,eAAO,MAAM,gBAAgB,QAAS,CAAC;AAEvC;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,cAAc,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAetH"}
@@ -0,0 +1,77 @@
1
+ // EMAIL AS A CHANNEL INTO THE INBOX — spec 365.
2
+ //
3
+ // A person's agent should be reachable by the address they already have, and an email they send or
4
+ // receive should land in the SAME thread as everything else they say to that person. Two mailboxes for
5
+ // one relationship is how half a conversation goes missing.
6
+ //
7
+ // FOUR RULES, and the whole design is these:
8
+ //
9
+ // 1. AN EMAIL IS NOT AUTHORITY (spec 309 §4.2). Inbound mail creates a MESSAGE and can never trigger
10
+ // an act. Nobody sends an email that moves money; the acts a person can take from a thread are the
11
+ // ones their own surface offers them, under their own mandate.
12
+ // 2. THE SENDER IS AN UNVERIFIED CLAIM. `From:` is a header anyone can write, so routing is done by
13
+ // the address the mail was SENT TO (`<handle>@<zone>` → the naming service → an agent), never by
14
+ // who it says it is from. The claim travels with the message, labelled as a claim.
15
+ // 3. PARSE IN MEMORY, STORE IN THE VAULT (spec 362 §6.2). The raw message is read into a message body
16
+ // the owner's vault holds and is never written to a serving-plane store — a mailbox is exactly the
17
+ // kind of durable private record ADR-0055 keeps out of DO storage.
18
+ // 4. BOUNDED, ALWAYS. A body has a size cap and attachments are named, not admitted: an inbox that
19
+ // accepts whatever arrives is a way to fill somebody's vault from the outside.
20
+ //
21
+ // The SENDER PORT is here and the providers are not: a transport is a leaf binding that depends inward
22
+ // (ADR-0057), and this package must not know whether the deployment sends through an HTTP API or a
23
+ // platform binding.
24
+ /**
25
+ * TWO INTEGRATIONS, ONE PORT — the first that is available sends.
26
+ *
27
+ * Not a fallback chain (ADR-0013): the order is a DEPLOYMENT PREFERENCE stated once, and a provider that
28
+ * is configured but fails returns an error rather than handing the message to the next one. Sending the
29
+ * same mail twice because the first attempt's response was slow is worse than not sending it.
30
+ */
31
+ export function firstAvailableSender(senders) {
32
+ return senders.find((s) => s.available()) ?? null;
33
+ }
34
+ /** The handle an address routes to: `alice@faithnet.me` → `alice`. Empty when the zone is not ours. */
35
+ export function handleFromAddress(address, zones) {
36
+ const at = address.trim().toLowerCase();
37
+ const m = /^([^@\s]+)@([^@\s]+)$/.exec(at);
38
+ if (!m)
39
+ return '';
40
+ const [, local = '', domain = ''] = m;
41
+ if (!zones.some((z) => domain === z.toLowerCase() || domain.endsWith(`.${z.toLowerCase()}`)))
42
+ return '';
43
+ // Plus-addressing is the person's own tag, not part of who they are: `alice+bills@` is alice.
44
+ return (local.split('+')[0] ?? '').trim();
45
+ }
46
+ /** Is this a well-formed address at all? Shape only — nothing here says a mailbox exists. */
47
+ export function isEmailAddress(v) {
48
+ return /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(v.trim());
49
+ }
50
+ export const EMAIL_BODY_LIMIT = 16_000;
51
+ /**
52
+ * An inbound email as the message a thread will hold.
53
+ *
54
+ * WHAT IT KEEPS: the words, who it says it is from, what it was about, and what came with it BY NAME.
55
+ * WHAT IT REFUSES: anything past the cap (truncated, and it says so — a body silently cut in half is a
56
+ * message that misleads), and every attachment's content.
57
+ *
58
+ * The result is deliberately plain text: a thread that renders remote HTML from an unverified sender is
59
+ * a phishing surface with a nice font.
60
+ */
61
+ export function inboundEmailToMessage(mail) {
62
+ const body = (mail.text ?? '').trim();
63
+ const truncated = body.length > EMAIL_BODY_LIMIT;
64
+ const kept = truncated ? `${body.slice(0, EMAIL_BODY_LIMIT)}\n\n[…] this email was longer than ${EMAIL_BODY_LIMIT} characters and the rest was not kept.` : body;
65
+ const files = (mail.attachments ?? []).filter((a) => a.name);
66
+ const noted = files.length
67
+ ? `\n\n${files.length === 1 ? 'It came with a file' : `It came with ${files.length} files`}, which were not saved: ${files.map((f) => f.name).join(', ')}.`
68
+ : '';
69
+ return {
70
+ subject: (mail.subject ?? '').trim() || '(no subject)',
71
+ claimedFrom: (mail.from ?? '').trim(),
72
+ // WHO IT SAYS IT IS FROM, said as a claim. A person reading this must not be able to mistake an
73
+ // email address for a verified identity — that mistake is the whole of email fraud.
74
+ bodyText: `${kept}${noted}\n\n— sent by email from ${mail.from} (an email address, not a verified agent)`,
75
+ };
76
+ }
77
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/email/index.ts"],"names":[],"mappings":"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"}
@@ -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"}
@@ -0,0 +1,93 @@
1
+ // The `MessageKind` / `CaseState` retirement path (spec 340 W5).
2
+ //
3
+ // THIS FILE IS TRANSITIONAL. It is separate from everything else so that deleting it is a visible,
4
+ // one-file event rather than an archaeology exercise.
5
+ //
6
+ // The two enums are frozen taxonomies: a new interaction type is a new `MessageKind` member and a
7
+ // schema change, which is the problem versioned profiles solve (spec 340 §6).
8
+ //
9
+ // WHAT W8 ACTUALLY REMOVED, AND WHAT IT COULD NOT. W5 recorded these as one job — "26 files,
10
+ // mechanical once the mapping is total". Doing it showed that was wrong in a way worth writing down,
11
+ // because the next person will assume the same thing (spec 340 §R.1):
12
+ //
13
+ // · `ExchangeRecordV1.kind` — REMOVED. Zero readers, a second copy of `envelope.kind`, and its own
14
+ // doc comment said the authority tier is classified from the skill selector and never from it.
15
+ // `profileVersion` carries interaction type now.
16
+ //
17
+ // · `MessageEnvelopeV1.kind` — KEPT, and this is not deferral. It sits INSIDE the signed wire hash
18
+ // (`hashMessageEnvelope` excludes only `signature`), so removing it changes every envelope digest
19
+ // and invalidates every existing signature and delivery receipt. It also has live readers: the
20
+ // auto-reply gate, folder routing, the inbox rule predicate, and the delivery envelope. Removing
21
+ // it is an `ap.message.v2` migration with re-signing, not a cleanup.
22
+ //
23
+ // · `CaseState` — KEPT. `MACHINE_FOR_CASE_STATE` below proves it spans three machines, and that
24
+ // analysis stands. But the decision and commitment machines W3 built are not yet populated by the
25
+ // live case flow, so deleting `CaseState` today would remove working behaviour and replace it with
26
+ // machines nothing writes to. That is a regression wearing the costume of a cleanup. It goes when
27
+ // the case flow emits decision and commitment records — a behaviour change, not a rename.
28
+ //
29
+ // The maps below stay because both remaining removals still need them.
30
+ import { DIRECT_PROFILE, NEGOTIATION_PROFILE, CONSULTATION_PROFILE } from './interaction-profile.js';
31
+ /**
32
+ * Every `MessageKind` (still the ENVELOPE's, see the header), mapped to the profile that replaces it.
33
+ *
34
+ * `Record<MessageKind, …>` rather than a lookup function: adding a `MessageKind` without deciding its
35
+ * profile then fails the build, which is the only way a "total" mapping stays total.
36
+ *
37
+ * Three of the seven collapse onto `direct`, and that is the finding rather than laziness. `plain`,
38
+ * `system` and `tombstone` were never different KINDS of interaction — they are a message, a message
39
+ * from the substrate, and a deletion marker. They differed in rendering, not in what was permitted,
40
+ * which is exactly the kind of distinction an interaction-type enum should not have been carrying.
41
+ */
42
+ export const PROFILE_FOR_MESSAGE_KIND = {
43
+ plain: DIRECT_PROFILE.profileVersion,
44
+ system: DIRECT_PROFILE.profileVersion,
45
+ tombstone: DIRECT_PROFILE.profileVersion,
46
+ // A request and its response are one interaction with two moves, not two kinds. Under a profile the
47
+ // difference is the act (`QUERY` then `INFORM`), where it belongs.
48
+ request: CONSULTATION_PROFILE.profileVersion,
49
+ response: CONSULTATION_PROFILE.profileVersion,
50
+ // Issuing a credential discharges something someone agreed to; `negotiation` is the profile in the
51
+ // starter library whose ACCEPT can create that obligation. A dedicated `issuance` profile is the
52
+ // right long-term home — noted rather than invented here, because inventing a profile to make a
53
+ // migration table look tidy is how the library fills with profiles nothing uses.
54
+ 'credential-delivery': NEGOTIATION_PROFILE.profileVersion,
55
+ receipt: DIRECT_PROFILE.profileVersion,
56
+ };
57
+ /**
58
+ * Every `CaseState`, mapped to the machine that owns it.
59
+ *
60
+ * THE POINT OF THIS TABLE: the eleven states were never one machine's. `denied` is a DECISION,
61
+ * `completed` is an EXECUTION outcome, and `revoked` is what happens to a COMMITMENT — three
62
+ * different questions with three different signers, answered by one field. That is why a case could
63
+ * be `denied` and a commitment still outstanding with nowhere to say so.
64
+ *
65
+ * `issued` and `approved` are the two that look ambiguous and are not: approving is a decision,
66
+ * issuing is work performed under it. Reading `approved` as execution progress is precisely the
67
+ * "deciding is not doing" collapse.
68
+ */
69
+ export const MACHINE_FOR_CASE_STATE = {
70
+ draft: 'execution',
71
+ submitted: 'execution',
72
+ triaged: 'execution',
73
+ 'needs-info': 'execution',
74
+ issued: 'execution',
75
+ completed: 'execution',
76
+ closed: 'execution',
77
+ failed: 'execution',
78
+ };
79
+ /**
80
+ * How many distinct machines the single `CaseState` field stands in for.
81
+ *
82
+ * It was THREE, and that number was the whole argument for W10b-3. It is now ONE, and this function is
83
+ * kept — rather than deleted along with the states — precisely so that claim stays falsifiable: if
84
+ * anyone re-adds a decision-shaped or commitment-shaped member to `CaseState`, they must give it a home
85
+ * in the table above, and this count moves off 1 and the test fails.
86
+ *
87
+ * A cleanup is not finished when the code compiles; it is finished when re-introducing the thing you
88
+ * removed is caught automatically.
89
+ */
90
+ export function machinesSpannedByCaseState() {
91
+ return new Set(Object.values(MACHINE_FOR_CASE_STATE)).size;
92
+ }
93
+ //# sourceMappingURL=enum-retirement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enum-retirement.js","sourceRoot":"","sources":["../src/enum-retirement.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,EAAE;AACF,mGAAmG;AACnG,sDAAsD;AACtD,EAAE;AACF,kGAAkG;AAClG,8EAA8E;AAC9E,EAAE;AACF,6FAA6F;AAC7F,qGAAqG;AACrG,sEAAsE;AACtE,EAAE;AACF,qGAAqG;AACrG,mGAAmG;AACnG,qDAAqD;AACrD,EAAE;AACF,qGAAqG;AACrG,sGAAsG;AACtG,mGAAmG;AACnG,qGAAqG;AACrG,yEAAyE;AACzE,EAAE;AACF,kGAAkG;AAClG,sGAAsG;AACtG,uGAAuG;AACvG,sGAAsG;AACtG,8FAA8F;AAC9F,EAAE;AACF,uEAAuE;AAKvE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAErG;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAwC;IAC3E,KAAK,EAAE,cAAc,CAAC,cAAc;IACpC,MAAM,EAAE,cAAc,CAAC,cAAc;IACrC,SAAS,EAAE,cAAc,CAAC,cAAc;IACxC,oGAAoG;IACpG,mEAAmE;IACnE,OAAO,EAAE,oBAAoB,CAAC,cAAc;IAC5C,QAAQ,EAAE,oBAAoB,CAAC,cAAc;IAC7C,mGAAmG;IACnG,iGAAiG;IACjG,gGAAgG;IAChG,iFAAiF;IACjF,qBAAqB,EAAE,mBAAmB,CAAC,cAAc;IACzD,OAAO,EAAE,cAAc,CAAC,cAAc;CACvC,CAAC;AAKF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAqC;IACtE,KAAK,EAAE,WAAW;IAClB,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,WAAW;IACpB,YAAY,EAAE,WAAW;IACzB,MAAM,EAAE,WAAW;IACnB,SAAS,EAAE,WAAW;IACtB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,WAAW;CACpB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,0BAA0B;IACxC,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7D,CAAC"}
@@ -1,11 +1,13 @@
1
- import type { MessageEnvelopeV1, MessageKind, MessageEventType, MessageId, Hex32, ContextRefV1 } from './messaging/index.js';
1
+ import type { MessageEnvelopeV1, MessageEventType, MessageId, Hex32, ContextRefV1 } from './messaging/index.js';
2
2
  import { hashMessageEnvelope } from './messaging/index.js';
3
3
  import type { AuthorityRef } from './interactions/index.js';
4
4
  import type { AuthorityTier } from '@agenticprimitives/tool-policy';
5
5
  import type { CanonicalAgentId } from '@agenticprimitives/types';
6
6
  import type { VaultRef } from '@agenticprimitives/vault';
7
7
  import type { ExecState, CaseState } from './exchange-state.js';
8
+ import type { DecisionState } from './interaction-machines.js';
8
9
  import type { CaseTransition } from './case-machine.js';
10
+ import type { InteractionId, ProfileVersion, ContextDigest } from './interaction-record.js';
9
11
  /** The exchange spine id — replaces today's `taskId` / `int_`+`run_` / `conv_`+`msg_` id families. */
10
12
  export type ExchangeId = `xch_${string}`;
11
13
  /**
@@ -82,12 +84,16 @@ export type ExchangeEventV1 = (ExchangeEventBase & {
82
84
  * The ONE canonical exchange record (spec §b). Two-level FSM: `exec` (transport, always present) + `case`
83
85
  * (business substate, execution-tier only). Authority is referenced, never satisfied here — approving a case
84
86
  * advances `case`, it never unlocks a resource (ADR-0041).
87
+ *
88
+ * `kind: MessageKind` was REMOVED in spec 340 W8. It was a frozen taxonomy on the aggregate, it was a second
89
+ * copy of `envelope.kind`, and it had ZERO readers — the authority tier is server-classified from the skill
90
+ * selector, never from `kind`, and that comment was the only thing the field was doing. `profileVersion` is
91
+ * what carries interaction type now. `MessageEnvelopeV1.kind` is a DIFFERENT field and stays: it is inside
92
+ * the signed wire hash and has live readers (spec 340 §R.1).
85
93
  */
86
94
  export interface ExchangeRecordV1 {
87
95
  version: 'ap.exchange.v1';
88
96
  exchangeId: ExchangeId;
89
- /** Projection hint only — the authority TIER is server-classified from the skill selector, never `kind`. */
90
- kind: MessageKind;
91
97
  /** Server-classified ONCE at ingress (never client-asserted). */
92
98
  tier: AuthorityTier;
93
99
  /** The delegator / gateway owner SA — on whose behalf the exchange runs. Also the case RESPONDER by
@@ -108,8 +114,22 @@ export interface ExchangeRecordV1 {
108
114
  resourceOwner?: CanonicalAgentId;
109
115
  /** Transport envelope state (always present). */
110
116
  exec: ExecState;
111
- /** Business substate — execution-tier only; `undefined` for a T0 communication exchange. */
117
+ /** Execution substate — execution-tier only; `undefined` for a T0 communication exchange. */
112
118
  case?: CaseState;
119
+ /**
120
+ * spec 340 W10b-3 — the DECISION substate, projected onto this record.
121
+ *
122
+ * Until W10b-3 the ordering "you cannot issue before approving" was an FSM edge
123
+ * (`issue-credential` ran only `from: ['approved']`). With the determination out of `CaseState`,
124
+ * this reducer would otherwise have no way to know one was made, and issuance could skip it — a
125
+ * guarantee silently lost to a type change. So the reducer projects the decision state the same way
126
+ * it projects `exec` from `case`.
127
+ *
128
+ * A PROJECTION, not the record of record: the full `DecisionRecordV1` (with its decider and
129
+ * timestamps) lives in the interaction store's decision machine. This carries only what the
130
+ * precondition needs. It is never authority — a `granted` here permits nothing (ADR-0041).
131
+ */
132
+ decision?: DecisionState;
113
133
  /** The signed wire objects (deliveries, responses, decisions). */
114
134
  envelopes: ExchangeEnvelopeV1[];
115
135
  /** The single append-only event stream (single-writer in the DO). */
@@ -120,6 +140,17 @@ export interface ExchangeRecordV1 {
120
140
  artifacts?: ArtifactRef[];
121
141
  /** Entities this exchange is ABOUT (spec 312) — carried through from the envelope. */
122
142
  contextRefs?: ContextRefV1[];
143
+ /** The governed situation this exchange occurs in. An Exchange without one is a message — a
144
+ * legitimate state, not an error, and the reason this is optional rather than required. */
145
+ interactionId?: InteractionId;
146
+ /** The EXACT profile version this exchange was made under, recorded HERE rather than read off the
147
+ * live interaction. Reading it off the interaction is what makes a downgrade invisible: an
148
+ * adversary edits one field and a Negotiation is reinterpreted as a Conversation, taking its
149
+ * acceptance semantics with it (spec 340 §6). */
150
+ profileVersion?: ProfileVersion;
151
+ /** Digest of the `ContextSnapshotV1` this exchange was evaluated against — by hash, never a pointer
152
+ * at live state. Supersedes `contextRefs` for authority-bearing context (spec 340 §7). */
153
+ contextDigest?: ContextDigest;
123
154
  /** Monotonic revision for the inbox-projection cursor. */
124
155
  rev: number;
125
156
  updatedAt: string;
@@ -1 +1 @@
1
- {"version":3,"file":"exchange-record.d.ts","sourceRoot":"","sources":["../src/exchange-record.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"exchange-record.d.ts","sourceRoot":"","sources":["../src/exchange-record.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"exchange-record.js","sourceRoot":"","sources":["../src/exchange-record.ts"],"names":[],"mappings":"AAAA,yGAAyG;AACzG,6GAA6G;AAC7G,0GAA0G;AAC1G,EAAE;AACF,oGAAoG;AACpG,2GAA2G;AAC3G,6GAA6G;AAC7G,8GAA8G;AAC9G,+EAA+E;AAC/E,EAAE;AACF,4GAA4G;AAC5G,oGAAoG;AAGpG,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAiC3D;;kDAEkD;AAClD,MAAM,CAAC,MAAM,oBAAoB,GAAG,mBAAmB,CAAC;AACxD,uFAAuF;AACvF,MAAM,CAAC,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AA8EtD;uGACuG;AACvG,MAAM,UAAU,OAAO,CAAC,MAAqD;IAC3E,OAAO,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,SAAS,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"exchange-record.js","sourceRoot":"","sources":["../src/exchange-record.ts"],"names":[],"mappings":"AAAA,yGAAyG;AACzG,6GAA6G;AAC7G,0GAA0G;AAC1G,EAAE;AACF,oGAAoG;AACpG,2GAA2G;AAC3G,6GAA6G;AAC7G,8GAA8G;AAC9G,+EAA+E;AAC/E,EAAE;AACF,4GAA4G;AAC5G,oGAAoG;AAGpG,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAmC3D;;kDAEkD;AAClD,MAAM,CAAC,MAAM,oBAAoB,GAAG,mBAAmB,CAAC;AACxD,uFAAuF;AACvF,MAAM,CAAC,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AA+GtD;uGACuG;AACvG,MAAM,UAAU,OAAO,CAAC,MAAqD;IAC3E,OAAO,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,SAAS,CAAC;AAC1C,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { type CaseFsmFields } from './case-machine.js';
2
2
  import type { ExchangeRecordV1, ExchangeEventV1 } from './exchange-record.js';
3
+ import type { Hex32 } from './messaging/index.js';
3
4
  export type ExchangeApplyResult = {
4
5
  ok: true;
5
6
  record: ExchangeRecordV1;
@@ -16,10 +17,37 @@ export type ExchangeApplyResult = {
16
17
  * `null` for a case-less (T0) exchange.
17
18
  */
18
19
  export declare function caseViewFromRecord(record: ExchangeRecordV1): CaseFsmFields | null;
20
+ export declare function applyExchangeEvent(record: ExchangeRecordV1, event: ExchangeEventV1): ExchangeApplyResult;
21
+ /** Bumped ONLY when a fold changes an output for inputs it already accepted. Adding a rejection reason
22
+ * is not a bump; changing what an accepted event does to the record is. */
23
+ export declare const EXCHANGE_REDUCER_VERSION: "ap.exchange-reducer.v1";
24
+ export interface MaterializationProvenanceV1 {
25
+ reducerVersion: typeof EXCHANGE_REDUCER_VERSION;
26
+ /** sha256 over the canonical event array — order-sensitive, because the fold is. */
27
+ eventSetDigest: Hex32;
28
+ eventCount: number;
29
+ }
30
+ /** Digest of the exact event sequence a materialization consumed. Order-sensitive on purpose: the same
31
+ * events in a different order are a different history, and folding them yields a different record. */
32
+ export declare function eventSetDigest(events: readonly ExchangeEventV1[]): Promise<Hex32>;
33
+ export type ExchangeReplayResult = {
34
+ ok: true;
35
+ record: ExchangeRecordV1;
36
+ provenance: MaterializationProvenanceV1;
37
+ } | {
38
+ ok: false;
39
+ reason: string;
40
+ atSeq: number;
41
+ };
19
42
  /**
20
- * Apply one event to an exchange record. Single-writer semantics (the gateway DO): `event.seq` must be the
21
- * next slot (`record.events.length`). Returns the next record (`changed: true`), a no-op for an idempotent
22
- * replay (`changed: false`), or a typed rejection.
43
+ * Rebuild an exchange from its event stream, and return the state WITH the evidence of how it was
44
+ * built.
45
+ *
46
+ * `seed` is the record as it existed before any event — the identity fields only. Its `events` are
47
+ * ignored and replaced by the fold, so replaying an already-materialized record cannot double-apply.
48
+ *
49
+ * Failure carries `atSeq` rather than just a reason: on a stream of two hundred events, "illegal
50
+ * transition" without the position is not a diagnosis.
23
51
  */
24
- export declare function applyExchangeEvent(record: ExchangeRecordV1, event: ExchangeEventV1): ExchangeApplyResult;
52
+ export declare function replayExchange(seed: ExchangeRecordV1, events: readonly ExchangeEventV1[]): Promise<ExchangeReplayResult>;
25
53
  //# sourceMappingURL=exchange-reducer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"exchange-reducer.d.ts","sourceRoot":"","sources":["../src/exchange-reducer.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE9E,MAAM,MAAM,mBAAmB,GAC3B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GACxD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,GAAG,aAAa,GAAG,IAAI,CAajF;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,eAAe,GAAG,mBAAmB,CAiExG"}
1
+ {"version":3,"file":"exchange-reducer.d.ts","sourceRoot":"","sources":["../src/exchange-reducer.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAuB,KAAK,aAAa,EAAuB,MAAM,mBAAmB,CAAC;AAEjG,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAGlD,MAAM,MAAM,mBAAmB,GAC3B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GACxD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,GAAG,aAAa,GAAG,IAAI,CAajF;AAiCD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,eAAe,GAAG,mBAAmB,CAwExG;AAaD;4EAC4E;AAC5E,eAAO,MAAM,wBAAwB,EAAG,wBAAiC,CAAC;AAE1E,MAAM,WAAW,2BAA2B;IAC1C,cAAc,EAAE,OAAO,wBAAwB,CAAC;IAChD,oFAAoF;IACpF,cAAc,EAAE,KAAK,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;uGACuG;AACvG,wBAAsB,cAAc,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAEvF;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,UAAU,EAAE,2BAA2B,CAAA;CAAE,GAC/E;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjD;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,SAAS,eAAe,EAAE,GACjC,OAAO,CAAC,oBAAoB,CAAC,CAgB/B"}