@real-life/trust-protocol 0.3.2 → 0.4.0

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 (264) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +187 -78
  3. package/dist/ack.d.ts +84 -0
  4. package/dist/ack.d.ts.map +1 -0
  5. package/dist/ack.js +114 -0
  6. package/dist/ack.js.map +1 -0
  7. package/dist/adapters/vti-mediator.d.ts +154 -0
  8. package/dist/adapters/vti-mediator.d.ts.map +1 -0
  9. package/dist/adapters/vti-mediator.js +621 -0
  10. package/dist/adapters/vti-mediator.js.map +1 -0
  11. package/dist/anchor.d.ts +226 -0
  12. package/dist/anchor.d.ts.map +1 -0
  13. package/dist/anchor.js +347 -0
  14. package/dist/anchor.js.map +1 -0
  15. package/dist/{holder.d.ts → carrier-holder.d.ts} +1 -1
  16. package/dist/carrier-holder.d.ts.map +1 -0
  17. package/dist/{holder.js → carrier-holder.js} +5 -4
  18. package/dist/carrier-holder.js.map +1 -0
  19. package/dist/carrier-identity.js +4 -4
  20. package/dist/carrier-identity.js.map +1 -1
  21. package/dist/carrier.d.ts.map +1 -1
  22. package/dist/carrier.js +4 -3
  23. package/dist/carrier.js.map +1 -1
  24. package/dist/ceremony.d.ts +3 -2
  25. package/dist/ceremony.d.ts.map +1 -1
  26. package/dist/ceremony.js +16 -26
  27. package/dist/ceremony.js.map +1 -1
  28. package/dist/codec.d.ts +46 -0
  29. package/dist/codec.d.ts.map +1 -0
  30. package/dist/codec.js +410 -0
  31. package/dist/codec.js.map +1 -0
  32. package/dist/continuity.d.ts +67 -0
  33. package/dist/continuity.d.ts.map +1 -0
  34. package/dist/continuity.js +110 -0
  35. package/dist/continuity.js.map +1 -0
  36. package/dist/core.d.ts +4 -0
  37. package/dist/core.d.ts.map +1 -1
  38. package/dist/core.js.map +1 -1
  39. package/dist/crypto.d.ts +23 -7
  40. package/dist/crypto.d.ts.map +1 -1
  41. package/dist/crypto.js +54 -20
  42. package/dist/crypto.js.map +1 -1
  43. package/dist/delivery.d.ts +31 -3
  44. package/dist/delivery.d.ts.map +1 -1
  45. package/dist/delivery.js +75 -28
  46. package/dist/delivery.js.map +1 -1
  47. package/dist/encounter/ceremony.d.ts +37 -0
  48. package/dist/encounter/ceremony.d.ts.map +1 -0
  49. package/dist/encounter/ceremony.js +662 -0
  50. package/dist/encounter/ceremony.js.map +1 -0
  51. package/dist/encounter.d.ts +91 -1
  52. package/dist/encounter.d.ts.map +1 -1
  53. package/dist/encounter.js +191 -12
  54. package/dist/encounter.js.map +1 -1
  55. package/dist/engine.d.ts +291 -0
  56. package/dist/engine.d.ts.map +1 -0
  57. package/dist/engine.js +1395 -0
  58. package/dist/engine.js.map +1 -0
  59. package/dist/entropy.d.ts +28 -0
  60. package/dist/entropy.d.ts.map +1 -0
  61. package/dist/entropy.js +96 -0
  62. package/dist/entropy.js.map +1 -0
  63. package/dist/events.d.ts +177 -0
  64. package/dist/events.d.ts.map +1 -0
  65. package/dist/events.js +2 -0
  66. package/dist/events.js.map +1 -0
  67. package/dist/fixtures.d.ts +30 -0
  68. package/dist/fixtures.d.ts.map +1 -0
  69. package/dist/fixtures.js +155 -0
  70. package/dist/fixtures.js.map +1 -0
  71. package/dist/forge.d.ts +47 -0
  72. package/dist/forge.d.ts.map +1 -0
  73. package/dist/forge.js +20 -0
  74. package/dist/forge.js.map +1 -0
  75. package/dist/group-star.d.ts +251 -0
  76. package/dist/group-star.d.ts.map +1 -0
  77. package/dist/group-star.js +348 -0
  78. package/dist/group-star.js.map +1 -0
  79. package/dist/holder-api.d.ts +137 -0
  80. package/dist/holder-api.d.ts.map +1 -0
  81. package/dist/holder-api.js +132 -0
  82. package/dist/holder-api.js.map +1 -0
  83. package/dist/holder-state-v1.d.ts +801 -0
  84. package/dist/holder-state-v1.d.ts.map +1 -0
  85. package/dist/holder-state-v1.js +2 -0
  86. package/dist/holder-state-v1.js.map +1 -0
  87. package/dist/identity-state.d.ts +43 -0
  88. package/dist/identity-state.d.ts.map +1 -0
  89. package/dist/identity-state.js +345 -0
  90. package/dist/identity-state.js.map +1 -0
  91. package/dist/identity.d.ts +24 -2
  92. package/dist/identity.d.ts.map +1 -1
  93. package/dist/identity.js +70 -11
  94. package/dist/identity.js.map +1 -1
  95. package/dist/index.d.ts +26 -1
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +77 -29
  98. package/dist/index.js.map +1 -1
  99. package/dist/internal.d.ts +36 -0
  100. package/dist/internal.d.ts.map +1 -0
  101. package/dist/internal.js +22 -0
  102. package/dist/internal.js.map +1 -0
  103. package/dist/introduction/holder.d.ts +18 -0
  104. package/dist/introduction/holder.d.ts.map +1 -0
  105. package/dist/introduction/holder.js +757 -0
  106. package/dist/introduction/holder.js.map +1 -0
  107. package/dist/introduction.d.ts +101 -0
  108. package/dist/introduction.d.ts.map +1 -0
  109. package/dist/introduction.js +132 -0
  110. package/dist/introduction.js.map +1 -0
  111. package/dist/invariants.d.ts +43 -0
  112. package/dist/invariants.d.ts.map +1 -0
  113. package/dist/invariants.js +883 -0
  114. package/dist/invariants.js.map +1 -0
  115. package/dist/keys-seed.d.ts +7 -0
  116. package/dist/keys-seed.d.ts.map +1 -0
  117. package/dist/keys-seed.js +133 -0
  118. package/dist/keys-seed.js.map +1 -0
  119. package/dist/log-memory.d.ts +12 -0
  120. package/dist/log-memory.d.ts.map +1 -0
  121. package/dist/log-memory.js +101 -0
  122. package/dist/log-memory.js.map +1 -0
  123. package/dist/membership/holder.d.ts +35 -0
  124. package/dist/membership/holder.d.ts.map +1 -0
  125. package/dist/membership/holder.js +852 -0
  126. package/dist/membership/holder.js.map +1 -0
  127. package/dist/membership.d.ts +92 -0
  128. package/dist/membership.d.ts.map +1 -0
  129. package/dist/membership.js +157 -0
  130. package/dist/membership.js.map +1 -0
  131. package/dist/ports.d.ts +237 -0
  132. package/dist/ports.d.ts.map +1 -0
  133. package/dist/ports.js +2 -0
  134. package/dist/ports.js.map +1 -0
  135. package/dist/profile.d.ts +56 -0
  136. package/dist/profile.d.ts.map +1 -0
  137. package/dist/profile.js +193 -0
  138. package/dist/profile.js.map +1 -0
  139. package/dist/prompts.d.ts +14 -0
  140. package/dist/prompts.d.ts.map +1 -0
  141. package/dist/prompts.js +69 -0
  142. package/dist/prompts.js.map +1 -0
  143. package/dist/receive.d.ts +133 -0
  144. package/dist/receive.d.ts.map +1 -0
  145. package/dist/receive.js +298 -0
  146. package/dist/receive.js.map +1 -0
  147. package/dist/results.d.ts +158 -0
  148. package/dist/results.d.ts.map +1 -0
  149. package/dist/results.js +21 -0
  150. package/dist/results.js.map +1 -0
  151. package/dist/schemas.d.ts.map +1 -1
  152. package/dist/schemas.js +42 -38
  153. package/dist/schemas.js.map +1 -1
  154. package/dist/sha256.d.ts +3 -0
  155. package/dist/sha256.d.ts.map +1 -0
  156. package/dist/sha256.js +69 -0
  157. package/dist/sha256.js.map +1 -0
  158. package/dist/star.d.ts +31 -0
  159. package/dist/star.d.ts.map +1 -0
  160. package/dist/star.js +56 -0
  161. package/dist/star.js.map +1 -0
  162. package/dist/state-builder.d.ts +42 -0
  163. package/dist/state-builder.d.ts.map +1 -0
  164. package/dist/state-builder.js +100 -0
  165. package/dist/state-builder.js.map +1 -0
  166. package/dist/state.d.ts +853 -0
  167. package/dist/state.d.ts.map +1 -0
  168. package/dist/state.js +36 -0
  169. package/dist/state.js.map +1 -0
  170. package/dist/store-contract.d.ts +11 -0
  171. package/dist/store-contract.d.ts.map +1 -0
  172. package/dist/store-contract.js +189 -0
  173. package/dist/store-contract.js.map +1 -0
  174. package/dist/store-memory.d.ts +8 -0
  175. package/dist/store-memory.d.ts.map +1 -0
  176. package/dist/store-memory.js +17 -0
  177. package/dist/store-memory.js.map +1 -0
  178. package/dist/testing.d.ts +22 -0
  179. package/dist/testing.d.ts.map +1 -0
  180. package/dist/testing.js +21 -0
  181. package/dist/testing.js.map +1 -0
  182. package/dist/trust/continuity.d.ts +71 -0
  183. package/dist/trust/continuity.d.ts.map +1 -0
  184. package/dist/trust/continuity.js +1216 -0
  185. package/dist/trust/continuity.js.map +1 -0
  186. package/dist/trust/duties.d.ts +67 -0
  187. package/dist/trust/duties.d.ts.map +1 -0
  188. package/dist/trust/duties.js +179 -0
  189. package/dist/trust/duties.js.map +1 -0
  190. package/dist/trust/entries.d.ts +139 -0
  191. package/dist/trust/entries.d.ts.map +1 -0
  192. package/dist/trust/entries.js +694 -0
  193. package/dist/trust/entries.js.map +1 -0
  194. package/dist/trust/group-star.d.ts +43 -0
  195. package/dist/trust/group-star.d.ts.map +1 -0
  196. package/dist/trust/group-star.js +188 -0
  197. package/dist/trust/group-star.js.map +1 -0
  198. package/dist/trust/mapping.d.ts +56 -0
  199. package/dist/trust/mapping.d.ts.map +1 -0
  200. package/dist/trust/mapping.js +584 -0
  201. package/dist/trust/mapping.js.map +1 -0
  202. package/dist/trust/profile.d.ts +25 -0
  203. package/dist/trust/profile.d.ts.map +1 -0
  204. package/dist/trust/profile.js +249 -0
  205. package/dist/trust/profile.js.map +1 -0
  206. package/dist/trust/star.d.ts +208 -0
  207. package/dist/trust/star.d.ts.map +1 -0
  208. package/dist/trust/star.js +588 -0
  209. package/dist/trust/star.js.map +1 -0
  210. package/dist/trust/state.d.ts +83 -0
  211. package/dist/trust/state.d.ts.map +1 -0
  212. package/dist/trust/state.js +154 -0
  213. package/dist/trust/state.js.map +1 -0
  214. package/dist/util-freeze.d.ts +3 -0
  215. package/dist/util-freeze.d.ts.map +1 -0
  216. package/dist/util-freeze.js +11 -0
  217. package/dist/util-freeze.js.map +1 -0
  218. package/dist/views.d.ts +147 -0
  219. package/dist/views.d.ts.map +1 -0
  220. package/dist/views.js +268 -0
  221. package/dist/views.js.map +1 -0
  222. package/dist/visibility.d.ts +5 -5
  223. package/dist/visibility.d.ts.map +1 -1
  224. package/dist/visibility.js +22 -28
  225. package/dist/visibility.js.map +1 -1
  226. package/dist/wire.d.ts +178 -84
  227. package/dist/wire.d.ts.map +1 -1
  228. package/dist/wire.js.map +1 -1
  229. package/package.json +56 -10
  230. package/schemas/holder-state-v1.schema.json +3880 -0
  231. package/dist/holder.d.ts.map +0 -1
  232. package/dist/holder.js.map +0 -1
  233. package/dist/probe/acks.d.ts +0 -27
  234. package/dist/probe/acks.d.ts.map +0 -1
  235. package/dist/probe/acks.js +0 -152
  236. package/dist/probe/acks.js.map +0 -1
  237. package/dist/probe/continuity.d.ts +0 -20
  238. package/dist/probe/continuity.d.ts.map +0 -1
  239. package/dist/probe/continuity.js +0 -805
  240. package/dist/probe/continuity.js.map +0 -1
  241. package/dist/probe/deps.d.ts +0 -61
  242. package/dist/probe/deps.d.ts.map +0 -1
  243. package/dist/probe/deps.js +0 -54
  244. package/dist/probe/deps.js.map +0 -1
  245. package/dist/probe/encounter.d.ts +0 -26
  246. package/dist/probe/encounter.d.ts.map +0 -1
  247. package/dist/probe/encounter.js +0 -938
  248. package/dist/probe/encounter.js.map +0 -1
  249. package/dist/probe/introduce.d.ts +0 -62
  250. package/dist/probe/introduce.d.ts.map +0 -1
  251. package/dist/probe/introduce.js +0 -306
  252. package/dist/probe/introduce.js.map +0 -1
  253. package/dist/probe/membership.d.ts +0 -96
  254. package/dist/probe/membership.d.ts.map +0 -1
  255. package/dist/probe/membership.js +0 -467
  256. package/dist/probe/membership.js.map +0 -1
  257. package/dist/probe/trust.d.ts +0 -156
  258. package/dist/probe/trust.d.ts.map +0 -1
  259. package/dist/probe/trust.js +0 -1233
  260. package/dist/probe/trust.js.map +0 -1
  261. package/dist/probe.d.ts +0 -7
  262. package/dist/probe.d.ts.map +0 -1
  263. package/dist/probe.js +0 -42
  264. package/dist/probe.js.map +0 -1
@@ -0,0 +1,584 @@
1
+ // trust/mapping — the Trust Layer's anchor mapping on the holder (lib
2
+ // Stage 2, PR 4a): the trust act and the class settings (Section 2a), the
3
+ // issuance of anchor-mapping@4 (6.1, 6300/6310, 6420), its verification
4
+ // (6.3) and the entry commit of the deliverable set (Section 2), on
5
+ // HolderState and the engine.
6
+ //
7
+ // Rule numbers: bare four-digit numbers are RLTP-TRU (trust-layer.md).
8
+ //
9
+ // What the module registers (createHolder builds it in):
10
+ // commands trust.set {contactId, on} the Trust button: the
11
+ // anchor mapping class `on` (2770) or `off` (2840); human
12
+ // trust.setClass {contactId, cls, setting} 2780/2810; human
13
+ // trust.setGroupClass {contactId, groupId, setting} 2830; human
14
+ // trust.pause {contactId, paused} the pause of 5.4: star
15
+ // and blinded group star `off`, or back to `default`; human
16
+ // trust.recover {} 2240: entries re-commit
17
+ // from verified mappings recovered without them; non-human
18
+ // task anchor-mapping/0.3 (proof absent): conditions 1–7 in the
19
+ // preparation (stage 8), condition 8 and the transition in
20
+ // apply (stage 9): mappingIn on the arrival tuple, links and
21
+ // bindings at chain level (6610), the counterpart head, the
22
+ // entry commit (2060) or its update in place (2070)
23
+ // duties class-on/1 (2850) and reissue-mapping/1 (6370, 6596): issue
24
+ // the current anchor-mapping@4 on one relationship; class-on of
25
+ // the star classes is discharged by the reconciliation (5.4);
26
+ // class-on of the profile and profile/1 (6455) issue profile@1
27
+ // (trust/profile.ts, PR 6)
28
+ // and, from trust/star.ts and trust/group-star.ts (PR 4b): the tasks
29
+ // star/0.2 and group-star/0.1, the sweeps trust.star and
30
+ // trust.groupStar run by resume, and their ack handlers
31
+ // and, from trust/profile.ts (PR 6): the command profile.set (human),
32
+ // the task profile/0.1 and the profile's duties
33
+ // and, from trust/entries.ts (PR 4c): the commands trust.merge and
34
+ // trust.depart and the duty merge/1; from trust/continuity.ts
35
+ // (PR 4c): the tasks continuity-probe/0.1 and
36
+ // continuity-mapping/0.1, the duty continuity/1, their ack and
37
+ // failure handlers
38
+ //
39
+ // Choices this file makes where note and spec leave them open:
40
+ // - a relationship's verifications go to the entry its active tuple's
41
+ // entryId names (2145), else the one its identity (contactId) names
42
+ // (trust/state.ts entryOf); it sends under that entry's settings
43
+ // (2146). An entry whose relationships hold incomparable anchor heads
44
+ // (a manual merge, 6640, before its split) keeps its anchor head where
45
+ // it is among the newest, else takes the verifying relationship's head
46
+ // - an accepted mapping runs, in order: the split of 2080 (the first
47
+ // mapping on a hand-merged relationship that shares no anchor with
48
+ // the entry), the entry commit, and the merge duties of the net and of
49
+ // 2145 (trust/entries.ts), which merge after this commit (2230)
50
+ // - mappingIn.body and mappingOut.body hold the mapping's body (the
51
+ // artifact without its MACs): the revision rule compares bodies (6270),
52
+ // 6310 compares the issued body
53
+ // - an equal revision with an identical body (6270 repeat, a resend under
54
+ // a new document id) is acknowledged and changes nothing, except that
55
+ // it re-commits an entry lost with state loss (2240); a lower revision,
56
+ // an equivocation and an unlinked change of self (6170) are
57
+ // failed(validation-failed) at stage 9 with the rule as ref
58
+ // - a document carrying ceremony.enactment is failed(validation-failed):
59
+ // a mapping has no material to recompute it against (Delivery §3)
60
+ // - trust.received is announced at the entry commit of a verification,
61
+ // contact.verified at every verification that changed the state; the
62
+ // re-commit of trust.recover (no verification) announces nothing
63
+ // - the admission bound is the constant 10¹⁸−1 (2050); trustModule takes
64
+ // another bound for tests only, as the probe's admissionBound did
65
+ // - an entry committed at a full set is deliverable-pending (2250);
66
+ // trust.recover, a merge and a departure admit pending entries in
67
+ // position order while the set has room (trust/entries.ts)
68
+ // - the entry commit of 2240 runs on trust.recover and on any accepted
69
+ // mapping of the relationship, the repeat included
70
+ // - issuance needs a community anchor (register.community): without one
71
+ // the Trust act is refused as no-community, a duty stays refused
72
+ // - the community key agrees through the KeyProvider under a release the
73
+ // module derives from the register (the current generation's label),
74
+ // not from `addresses`: it is no delivery address (Delivery §5)
75
+ // - the class duties (2850, 6410, 6595, 6596) open, drop and move by the
76
+ // one follow rule of trust/duties.ts, run after every settings change,
77
+ // verification, merge, split, departure and chaining. A class-on duty
78
+ // of the anchor mapping finding the class off, its relationship gone
79
+ // or lagging is fulfilled without sending; ceasing to lag opens a new
80
+ // one (2850). A re-issue duty sends whether or not the relationship
81
+ // lags now (6596) and is dropped while the class is off (6410)
82
+ // - every issuance on a relationship fulfils every open class-on duty of
83
+ // the anchor mapping and every re-issue owed on it (6596: one delivery
84
+ // meets every re-issue still owed)
85
+ // - the star, the blinded and the sealed group star are delivered by the
86
+ // reconciliation of 5.4 (trust/star.ts), which sees every settings
87
+ // change through its view, so changing their settings opens no class-on
88
+ // duty; a class-on duty of one of them (from elsewhere) is fulfilled
89
+ // without sending, since the sweep runs in the same resume after the
90
+ // duties. The profile's class-on and revision duties issue profile@1
91
+ // (trust/profile.ts)
92
+ // - trust.pause sets star and blinded group star `off`, unpausing back to
93
+ // `default`; it needs no trust (2780)
94
+ // - setGroupClass to `default` removes the per-group entry; turning the
95
+ // sealed group star class `off` resets every per-group `on` (5450), on
96
+ // that transition only: a group set `on` afterwards stays, and setting
97
+ // `off` while it is off resets nothing
98
+ import { jcs, iso, makeValidator, calOK } from '../core.js';
99
+ import { digestDoc, xRawOfMk } from '../crypto.js';
100
+ import { seal } from '../delivery.js';
101
+ import { communityLabel } from '../identity.js';
102
+ import { SCHEMAS } from '../schemas.js';
103
+ import { LINEAGE_MAX, MAPPING_CONDITION_RULE, assembleAnchorMapping, bindingOf, classifyMapping, lineageLinks, mappingBindings, rawProofValue, verifyAnchorMappingWith, } from '../anchor.js';
104
+ import { tupleByRkid } from '../receive.js';
105
+ import { ADMISSION_BOUND, CLASSES, activeTuple, classOnToward, entryOf, entryRelationships, findContact, lags, liveRel, unionBindings, } from './state.js';
106
+ import { admitPending, entryCommands, mergeDutiesAfter, mergeDuty, settleHead, splitIfUnlinked } from './entries.js';
107
+ import { classOnHandler, followClasses, owedOn } from './duties.js';
108
+ import { profileIssueDuty, profileParts } from './profile.js';
109
+ import { ASSEMBLY_LIMIT, STAR, STAR_TYPE, ackOf, rematchStars, retainInflight, starBlinds, sweepOf, taskOf } from './star.js';
110
+ import { GROUP_STAR, GROUP_STAR_TYPE } from './group-star.js';
111
+ import { continuityParts } from './continuity.js';
112
+ const te = new TextEncoder();
113
+ const V = makeValidator(SCHEMAS);
114
+ const mappingSchemaOk = (m) => V.validate(m, SCHEMAS['visibility-anchor-mapping.schema.json'], SCHEMAS['visibility-anchor-mapping.schema.json']).length === 0;
115
+ /** The registered task type that carries anchor-mapping@4 (Delivery §4.4). */
116
+ export const ANCHOR_MAPPING_TYPE = 'https://real-life.org/trust-tasks/anchor-mapping/0.3';
117
+ /** The trust module's command names. */
118
+ export const TRUST_COMMANDS = Object.freeze({
119
+ set: 'trust.set', setClass: 'trust.setClass', setGroupClass: 'trust.setGroupClass', pause: 'trust.pause', recover: 'trust.recover',
120
+ });
121
+ const SETTINGS = ['default', 'on', 'off'];
122
+ const inc = (d) => (BigInt(d) + 1n).toString();
123
+ /** The current generation's label and the next one's (Identity §5.4). */
124
+ function communityOf(state) {
125
+ const c = state.register.community;
126
+ if (c === null)
127
+ return null;
128
+ const gen = Number(c.head);
129
+ if (!Number.isSafeInteger(gen) || gen < 1 || gen + 1 > Number.MAX_SAFE_INTEGER)
130
+ throw new Error(`trust: community head ${c.head} outside [1, 2^53 − 2] (Identity §5.4)`);
131
+ return { genesis: c.genesis, gen, label: communityLabel(c.genesis, gen), nextLabel: communityLabel(c.genesis, gen + 1) };
132
+ }
133
+ /**
134
+ * The lineage a mapping on one relationship carries (6020, 6420): empty
135
+ * where nothing was issued there under an earlier anchor, otherwise the
136
+ * holder's lineage from the element that leaves the relationship's
137
+ * earliest anchor (2285) to `self`, at most the LINEAGE_MAX most recent.
138
+ */
139
+ export function lineageSegment(lineage, earliest, self) {
140
+ if (earliest === null || earliest === self)
141
+ return [];
142
+ const at = lineage.findIndex((r) => r?.body?.prev === earliest);
143
+ if (at < 0)
144
+ throw new Error('trust: a relationship\'s earliest anchor is not in the register lineage (2285, 6420)');
145
+ const seg = lineage.slice(at);
146
+ if (seg[seg.length - 1].body.next !== self)
147
+ throw new Error('trust: the register lineage does not end at the current community anchor');
148
+ return structuredClone(seg.slice(-LINEAGE_MAX));
149
+ }
150
+ /** Whether the anchor mapping can go out on `relId` toward `contactId` now. */
151
+ function issuable(state, contactId, relId, lagMatters) {
152
+ const contact = findContact(state, contactId);
153
+ const rel = Object.hasOwn(state.relationships, relId) ? state.relationships[relId] : undefined;
154
+ if (!contact || !rel || rel.chainedInto !== null || !contact.relIds.includes(rel.id))
155
+ return { ok: false, why: 'gone' };
156
+ if (entryOf(state, rel)?.id !== contact.id)
157
+ return { ok: false, why: 'gone' }; // 2146: it sends under the other entry
158
+ if (!classOnToward(contact, 'anchorMapping'))
159
+ return { ok: false, why: 'off' }; // 6410
160
+ const tuple = activeTuple(rel);
161
+ if (!tuple || tuple.deactivated)
162
+ return { ok: false, why: 'deactivated' }; // 6240
163
+ if (lagMatters && lags(rel, entryRelationships(state, contact)))
164
+ return { ok: false, why: 'lagging' }; // 6595
165
+ if (state.register.community === null)
166
+ return { ok: false, why: 'no-community' };
167
+ if (BigInt(tuple.mappingOut.rev) + 1n > ADMISSION_BOUND)
168
+ return { ok: false, why: 'scope-exhausted' }; // 2.1
169
+ return { ok: true, contact, rel, tuple };
170
+ }
171
+ /** Build and seal the current anchor-mapping@4 for one relationship. */
172
+ async function prepareIssue(ctx, contactId, relId, lagMatters) {
173
+ const st = ctx.snapshot;
174
+ const chk = issuable(st, contactId, relId, lagMatters);
175
+ if (!chk.ok)
176
+ return null;
177
+ const { contact, rel, tuple: t } = chk;
178
+ const S = ctx.crypto.subtle;
179
+ const com = communityOf(st);
180
+ const self = await ctx.keys.anchorOf(com.label);
181
+ const next = await ctx.keys.anchorOf(com.nextLabel);
182
+ const own = await ctx.keys.anchorOf(t.ownPairLabel);
183
+ // self-card@2 under the current generation, bound to the next (6.2)
184
+ const cardBody = { type: 'self-card@2', anchor: self.anchor, keyAgreement: self.keyAgreement, commit: await bindingOf(next.anchor, S) };
185
+ const card = { body: cardBody, proof: { proofValue: rawProofValue(await ctx.keys.sign(com.label, te.encode(jcs(cardBody)))) } };
186
+ const rev = inc(t.mappingOut.rev);
187
+ const body = {
188
+ type: 'anchor-mapping@4', pair: own.anchor, self: self.anchor, to: t.counterpartAnchor, card,
189
+ lineage: lineageSegment(st.register.lineage, rel.earliestAnchor, self.anchor), revision: rev, issuedAt: iso(ctx.when),
190
+ };
191
+ const theirX = xRawOfMk(t.counterpartKeyAgreement);
192
+ if (!theirX)
193
+ return null;
194
+ // mac1 under the tuple's own pair key, mac2 under the community key (6030)
195
+ const sh1 = await ctx.keys.agree(t.rkid, theirX, ctx.release);
196
+ const communityRelease = (rkid) => (rkid === self.keyAgreement ? { status: 'live', label: com.label } : { status: 'unknown' });
197
+ const sh2 = await ctx.keys.agree(self.keyAgreement, theirX, communityRelease);
198
+ if (sh1.status !== 'available' || sh2.status !== 'available')
199
+ return null;
200
+ const mapping = await assembleAnchorMapping(body, sh1.shared, sh2.shared, S);
201
+ const threadId = ctx.entropy.id('thread.id');
202
+ const doc = {
203
+ id: ctx.entropy.id('doc.id'), type: ANCHOR_MAPPING_TYPE, issuer: own.anchor, recipient: t.counterpartAnchor,
204
+ threadId, issuedAt: iso(ctx.when), payload: mapping,
205
+ };
206
+ const envelope = await seal(doc, t.counterpartKeyAgreement, { ephSeed: ctx.entropy.bytes('seal.eph', 32), nonce: ctx.entropy.bytes('seal.nonce', 12) }, S);
207
+ return {
208
+ relId: rel.id, tuple: t.ownPairLabel, baseRev: t.mappingOut.rev, rev, body, underAnchor: self.anchor,
209
+ outbound: {
210
+ digest: await digestDoc(doc, S), envelope, type: ANCHOR_MAPPING_TYPE, threadId,
211
+ recipient: { contactId: contact.id, rkid: t.rkid, keyAgreement: t.counterpartKeyAgreement },
212
+ },
213
+ };
214
+ }
215
+ /** The issuance's commit: revision and body persisted in one step (6300),
216
+ * the earliest anchor (2285), every duty the delivery meets (6596); null
217
+ * where the scope moved since the preparation. */
218
+ function commitIssue(state, p) {
219
+ const rel = state.relationships[p.relId];
220
+ const i = rel.tuples.findIndex((t) => t.ownPairLabel === p.tuple);
221
+ if (i < 0 || rel.tuples[i].mappingOut.rev !== p.baseRev)
222
+ return null;
223
+ const tuples = rel.tuples.map((t, j) => (j === i ? { ...t, mappingOut: { rev: p.rev, body: p.body, underAnchor: p.underAnchor } } : t));
224
+ const duties = {};
225
+ for (const [id, d] of Object.entries(state.duties))
226
+ if (!owedOn(d, p.relId, 'anchorMapping'))
227
+ duties[id] = d;
228
+ return {
229
+ state: {
230
+ ...state,
231
+ relationships: { ...state.relationships, [rel.id]: { ...rel, tuples, earliestAnchor: rel.earliestAnchor ?? p.underAnchor } },
232
+ duties,
233
+ },
234
+ outbound: [p.outbound],
235
+ };
236
+ }
237
+ // ── the entry commit (Section 2) ───────────────────────────────────────
238
+ /**
239
+ * After a verified mapping on `relId` (or on recovery): the entry commit
240
+ * where the entry has none (2060: next position, admitted, or pending at
241
+ * the bound, 2250) and the entry's anchor head (6560). The class duties
242
+ * that follow (a relationship that ceased to lag, 2850) are the caller's,
243
+ * by the follow rule (trust/duties.ts).
244
+ */
245
+ function commitEntry(state, relId, bound) {
246
+ const rel = state.relationships[relId];
247
+ const c0 = entryOf(state, rel);
248
+ if (!c0)
249
+ throw new Error(`trust: relationship ${relId} maps to no entry`);
250
+ let c = { ...c0 };
251
+ let entryOrder = state.entryOrder;
252
+ let committed = null;
253
+ if (c.pos === null) {
254
+ const admitted = BigInt(Object.values(state.contacts).filter((x) => x.status === 'admitted').length);
255
+ c = { ...c, pos: entryOrder.nextPos, status: admitted < bound ? 'admitted' : 'pending' };
256
+ entryOrder = { ...entryOrder, nextPos: inc(entryOrder.nextPos) };
257
+ committed = c;
258
+ }
259
+ const s1 = { ...state, contacts: { ...state.contacts, [c.id]: c }, entryOrder };
260
+ c = settleHead(s1, c, rel.heldCounterpartHead);
261
+ return { state: { ...s1, contacts: { ...s1.contacts, [c.id]: c } }, committed, contact: c };
262
+ }
263
+ /** First, pending entries are admitted in position order while the set
264
+ * has room (2250): they hold earlier positions than any re-commit. Then
265
+ * (2240) every relationship holding a verified mapping on a tuple whose
266
+ * entry holds no position re-commits that entry, in the order of
267
+ * entryOrder.heads (2180), then by relationship id, at the next position,
268
+ * admitted or pending by what room is left. */
269
+ export function recommitEntries(state, bound = ADMISSION_BOUND) {
270
+ const order = Object.keys(state.relationships).sort((a, b) => {
271
+ const ia = state.entryOrder.heads.indexOf(a), ib = state.entryOrder.heads.indexOf(b);
272
+ return ((ia < 0 ? Infinity : ia) - (ib < 0 ? Infinity : ib)) || (a < b ? -1 : a > b ? 1 : 0);
273
+ });
274
+ let cur = admitPending(state, bound);
275
+ for (const id of order) {
276
+ const rel = cur.relationships[id];
277
+ if (!rel.tuples.some((t) => t.mappingIn.body !== null) || entryOf(cur, rel)?.pos !== null)
278
+ continue;
279
+ cur = commitEntry(cur, id, bound).state;
280
+ }
281
+ const f = followClasses(state, cur);
282
+ return { state: f.state, ...(f.duties.length ? { duties: f.duties } : {}) };
283
+ }
284
+ // ── reception (6.3, Section 2) ─────────────────────────────────────────
285
+ const refuse = (reason, ref) => ({ ok: false, reason, ...(ref ? { ref } : {}) });
286
+ /** The arrival tuple, if it is the active head of a live relationship (6190, 6240). */
287
+ const arrivalTuple = (state, rkid) => {
288
+ const at = tupleByRkid(state, rkid);
289
+ if (!at || at.tuple.deactivated || at.rel.chainedInto !== null || at.rel.activeHead !== at.tuple.ownPairLabel)
290
+ return null;
291
+ return at;
292
+ };
293
+ function mappingTask(bound) {
294
+ return {
295
+ proof: 'absent',
296
+ // stage 7: the payload schema, calendar-valid issuedAt (6070)
297
+ decode(payload) {
298
+ if (!mappingSchemaOk(payload) || !calOK(payload.body.issuedAt))
299
+ return refuse('malformed', 'RLTP-TRU-6070');
300
+ return payload;
301
+ },
302
+ // stage 8: conditions 1–7 against the arrival tuple and the bindings
303
+ // its relationship holds (6118), then the bindings the mapping states
304
+ async prepare(ctx, doc, arrival) {
305
+ if (doc.ceremony?.enactment !== undefined)
306
+ return refuse('validation-failed');
307
+ const at = arrivalTuple(ctx.snapshot, arrival.rkid);
308
+ if (!at)
309
+ return refuse('validation-failed', 'RLTP-TRU-6240');
310
+ const S = ctx.crypto.subtle;
311
+ const own = await ctx.keys.anchorOf(at.tuple.ownPairLabel);
312
+ // 6118 against every binding held: an anchor the chain holds two
313
+ // bindings for (6610) admits no card and no successor, since none
314
+ // can meet both
315
+ const b0 = doc.payload.body;
316
+ const conflicted = new Set(Object.entries(at.rel.bindings).filter(([, v]) => v.length > 1).map(([k]) => k));
317
+ if (conflicted.has(b0.card.body.anchor) || b0.lineage.some((r) => conflicted.has(r.body.prev)))
318
+ return refuse('validation-failed', 'RLTP-TRU-6118');
319
+ let infra = null;
320
+ const v = await verifyAnchorMappingWith(doc.payload, {
321
+ ownAnchor: own.anchor, pair: at.tuple.counterpartAnchor, pairKeyAgreement: at.tuple.counterpartKeyAgreement,
322
+ held: new Map(Object.entries(at.rel.bindings).filter(([, x]) => x.length === 1).map(([k, x]) => [k, x[0]])),
323
+ agree: async (theirX) => {
324
+ try {
325
+ const a = await ctx.keys.agree(at.tuple.rkid, theirX, ctx.release);
326
+ return a.status === 'available' ? a.shared : null;
327
+ }
328
+ catch (e) {
329
+ infra = e;
330
+ throw e;
331
+ }
332
+ },
333
+ }, S);
334
+ if (infra !== null)
335
+ throw infra; // a provider failure is no verdict on the mapping
336
+ if (!v.ok)
337
+ return refuse('validation-failed', v.rule ?? MAPPING_CONDITION_RULE[v.step]);
338
+ // the anchors this mapping makes held (self, both ends of its links),
339
+ // blinded under every accepted star for the re-match of 6160
340
+ const anchors = [...new Set([doc.payload.body.self, ...lineageLinks(doc.payload.body.lineage).flat()])];
341
+ return { bindings: Object.fromEntries(await mappingBindings(doc.payload.body, S)), stars: await starBlinds(ctx, anchors) };
342
+ },
343
+ // stage 9: condition 8 (6150–6170) and the transition
344
+ apply(state, prepared, doc, arrival) {
345
+ const at = arrivalTuple(state, arrival.rkid);
346
+ if (!at)
347
+ return refuse('validation-failed', 'RLTP-TRU-6240');
348
+ const { rel, tuple: t } = at;
349
+ const b = doc.payload.body;
350
+ const rev = BigInt(b.revision);
351
+ const cur = BigInt(t.mappingIn.rev);
352
+ // the generic revision rule within the scope (pair, to) = this tuple (6270, 6280)
353
+ if (rev === cur) {
354
+ if (t.mappingIn.body === null || jcs(b) !== jcs(t.mappingIn.body))
355
+ return refuse('validation-failed', 'RLTP-TRU-6270');
356
+ // a repeat: ignored, except an entry lost with state loss re-commits (2240)
357
+ return entryOf(state, rel)?.pos === null ? { state: commitEntry(state, rel.id, bound).state } : { state: state };
358
+ }
359
+ if (rev < cur)
360
+ return refuse('validation-failed', 'RLTP-TRU-6270');
361
+ // condition 8 against the self this relationship holds (6150), never the entry's head
362
+ if (classifyMapping(rel.heldCounterpartHead ?? undefined, b) === 'rejected')
363
+ return refuse('validation-failed', 'RLTP-TRU-6170');
364
+ const tuples = rel.tuples.map((x) => (x.ownPairLabel === t.ownPairLabel
365
+ ? { ...x, mappingIn: { rev: b.revision, body: b, self: b.self, card: b.card } }
366
+ : x));
367
+ // links and bindings accumulate at chain level (6610)
368
+ const links = [...rel.links];
369
+ for (const [prev, next] of lineageLinks(b.lineage))
370
+ if (!links.some((l) => l.prev === prev && l.next === next))
371
+ links.push({ prev, next });
372
+ const nextRel = {
373
+ ...rel, tuples, links, bindings: unionBindings(rel.bindings, Object.fromEntries(Object.entries(prepared.value.bindings).map(([k, x]) => [k, [x]]))), heldCounterpartHead: b.self,
374
+ // 2190: the verification commit's place in the one total order
375
+ firstVerified: rel.firstVerified ?? inc(state.commitSeq),
376
+ };
377
+ let mid = { ...state, relationships: { ...state.relationships, [rel.id]: nextRel } };
378
+ const events = [];
379
+ // 2080: a manual merge the first mapping contradicts splits, atomically
380
+ const split = splitIfUnlinked(state, mid, rel.id);
381
+ if (split) {
382
+ mid = split.state;
383
+ events.push(split.event);
384
+ }
385
+ const e = commitEntry(mid, rel.id, bound);
386
+ if (e.committed)
387
+ events.push({ type: 'trust.received', contactId: e.contact.id });
388
+ events.push({ type: 'contact.verified', contactId: e.contact.id, relationshipId: rel.id });
389
+ // 6160: stars already accepted are tested against the anchors now held
390
+ // the net (6520–6605) and 2145: a merge this verification admits runs
391
+ // after its commit, as a persisted continuation (2230)
392
+ const m = mergeDutiesAfter(state, rematchStars(e.state, e.contact.id, prepared.value.stars), rel.id, { net: true });
393
+ // the class duties that follow (2850: a relationship that ceased to
394
+ // lag, a split's drop of 2115) — trust/duties.ts
395
+ const f = followClasses(state, m.state, m.duties);
396
+ const after = f.state;
397
+ const duties = f.duties;
398
+ return { state: after, events, ...(duties.length ? { duties } : {}), ...(split?.renames.length ? { renames: split.renames } : {}) };
399
+ },
400
+ };
401
+ }
402
+ // ── settings (Section 2a) ──────────────────────────────────────────────
403
+ const paused = (c) => c.settings.star === 'off' && c.settings.groupStar === 'off';
404
+ /** One change of a contact's settings: 2840 and 5450 follow from it, the
405
+ * class duties of 2850 and 6410 by the follow rule (trust/duties.ts), the
406
+ * events. */
407
+ function changeSettings(state, c, settings, groupSettings) {
408
+ // 5450: turning the sealed group star off resets every per-group on to
409
+ // default — on the transition only, so a group set on afterwards stays (2830)
410
+ let groups = groupSettings;
411
+ if (c.settings.sealedGroupStar !== 'off' && settings.sealedGroupStar === 'off')
412
+ groups = Object.fromEntries(Object.entries(groups).filter(([, s]) => s !== 'on'));
413
+ const next = { ...c, settings, groupSettings: groups };
414
+ const events = [];
415
+ if (!classOnToward(c, 'anchorMapping') && classOnToward(next, 'anchorMapping'))
416
+ events.push({ type: 'trust.given', contactId: next.id });
417
+ if (paused(c) !== paused(next))
418
+ events.push({ type: 'trust.paused', contactId: next.id, paused: paused(next) });
419
+ const f = followClasses(state, { ...state, contacts: { ...state.contacts, [c.id]: next } });
420
+ return { state: f.state, events, ...(f.duties.length ? { duties: f.duties } : {}) };
421
+ }
422
+ const needString = (x, what) => {
423
+ if (typeof x !== 'string' || x === '')
424
+ throw new TypeError(`${what} must be a non-empty string`);
425
+ return x;
426
+ };
427
+ const needSetting = (x) => {
428
+ if (!SETTINGS.includes(x))
429
+ throw new TypeError(`setting must be default, on or off, got ${String(x)}`);
430
+ return x;
431
+ };
432
+ const needInput = (x, name) => {
433
+ if (x === null || typeof x !== 'object' || Array.isArray(x))
434
+ throw new TypeError(`${name} needs an input object`);
435
+ return x;
436
+ };
437
+ /** A class setting through the one transition; `on` of the anchor mapping
438
+ * needs a community anchor to issue under. */
439
+ function setClass(state, contactId, cls, setting) {
440
+ const c = findContact(state, contactId);
441
+ if (!c)
442
+ return { ok: false, code: 'unknown-contact' };
443
+ const settings = { ...c.settings, [cls]: setting };
444
+ if (cls === 'anchorMapping' && setting === 'on' && state.register.community === null)
445
+ return { ok: false, code: 'no-community' };
446
+ return changeSettings(state, c, settings, c.groupSettings);
447
+ }
448
+ const commands = {
449
+ // the Trust button: on (2770), or withdrawn (2840)
450
+ [TRUST_COMMANDS.set]: {
451
+ human: true,
452
+ apply(state, _p, input) {
453
+ const i = needInput(input, TRUST_COMMANDS.set);
454
+ const contactId = needString(i.contactId, 'contactId');
455
+ if (typeof i.on !== 'boolean')
456
+ throw new TypeError('trust.set: on must be a boolean');
457
+ const c = findContact(state, contactId);
458
+ if (!c)
459
+ return { ok: false, code: 'unknown-contact' };
460
+ if (i.on && c.settings.anchorMapping === 'on')
461
+ return { ok: false, code: 'already-given' };
462
+ return setClass(state, contactId, 'anchorMapping', i.on ? 'on' : 'off');
463
+ },
464
+ },
465
+ [TRUST_COMMANDS.setClass]: {
466
+ human: true,
467
+ apply(state, _p, input) {
468
+ const i = needInput(input, TRUST_COMMANDS.setClass);
469
+ if (!CLASSES.includes(i.cls))
470
+ throw new TypeError(`trust.setClass: unknown class ${String(i.cls)}`);
471
+ return setClass(state, needString(i.contactId, 'contactId'), i.cls, needSetting(i.setting));
472
+ },
473
+ },
474
+ [TRUST_COMMANDS.setGroupClass]: {
475
+ human: true,
476
+ apply(state, _p, input) {
477
+ const i = needInput(input, TRUST_COMMANDS.setGroupClass);
478
+ const groupId = needString(i.groupId, 'groupId');
479
+ const setting = needSetting(i.setting);
480
+ const c = findContact(state, needString(i.contactId, 'contactId'));
481
+ if (!c)
482
+ return { ok: false, code: 'unknown-contact' };
483
+ const groups = { ...c.groupSettings };
484
+ if (setting === 'default')
485
+ delete groups[groupId];
486
+ else
487
+ groups[groupId] = setting;
488
+ return changeSettings(state, c, c.settings, groups);
489
+ },
490
+ },
491
+ // the pause of 5.4: star and blinded group star off (2780)
492
+ [TRUST_COMMANDS.pause]: {
493
+ human: true,
494
+ apply(state, _p, input) {
495
+ const i = needInput(input, TRUST_COMMANDS.pause);
496
+ if (typeof i.paused !== 'boolean')
497
+ throw new TypeError('trust.pause: paused must be a boolean');
498
+ const c = findContact(state, needString(i.contactId, 'contactId'));
499
+ if (!c)
500
+ return { ok: false, code: 'unknown-contact' };
501
+ const s = i.paused ? 'off' : 'default';
502
+ return changeSettings(state, c, { ...c.settings, star: s, groupStar: s }, c.groupSettings);
503
+ },
504
+ },
505
+ };
506
+ // ── duties ─────────────────────────────────────────────────────────────
507
+ /** What a blocked issuance means for a duty: fulfilled without sending
508
+ * (the class is off, the relationship gone or lagging), or kept. */
509
+ const blocked = (state, why) => why === 'no-community' ? { ok: false, code: 'no-community' }
510
+ : why === 'scope-exhausted' ? { ok: false, code: 'scope-exhausted', ref: 'RLTP-TRU-6310' }
511
+ : { state: state };
512
+ /** Issue the anchor mapping on a duty's relationship: class-on/1 of the
513
+ * anchor mapping (through classOnHandler) and reissue-mapping/1. */
514
+ const issueDuty = (lagMatters) => ({
515
+ v: 1,
516
+ prepare: (ctx, duty) => {
517
+ const d = duty;
518
+ return prepareIssue(ctx, d.contactId, d.relId, lagMatters);
519
+ },
520
+ apply(state, duty, ctx) {
521
+ const d = duty;
522
+ const chk = issuable(state, d.contactId, d.relId, lagMatters);
523
+ if (!chk.ok)
524
+ return blocked(state, chk.why);
525
+ const p = ctx.prepared.value;
526
+ if (p === null)
527
+ return { ok: false, code: 'no-own-channel', ref: 'RLTP-TRU-6140' }; // no usable key agreement
528
+ return commitIssue(state, p) ?? 'not-due';
529
+ },
530
+ });
531
+ /** 6596: an owed re-issue waits until its relationship presents the
532
+ * awaited head H as its anchor head, or a later anchor whose links carry
533
+ * H as a prev. A relationship gone releases the duty, which then drops. */
534
+ const reissueAwaits = (state, duty) => {
535
+ const d = duty;
536
+ if (!Object.hasOwn(state.relationships, d.relId))
537
+ return true;
538
+ const rel = state.relationships[d.relId];
539
+ return d.awaitHead === null || rel.heldCounterpartHead === d.awaitHead || rel.links.some((l) => l.prev === d.awaitHead);
540
+ };
541
+ /** The trust module createHolder builds in (see the header). */
542
+ export function trustModule(opts = {}) {
543
+ const bound = opts.admissionBound ?? ADMISSION_BOUND;
544
+ if (typeof bound !== 'bigint' || bound < 0n || bound > ADMISSION_BOUND)
545
+ throw new RangeError('admissionBound must be a bigint within [0, 10^18 − 1]');
546
+ const limit = opts.assemblyLimit;
547
+ if (limit !== undefined && (!Number.isSafeInteger(limit) || limit < 1))
548
+ throw new RangeError('assemblyLimit must be a positive integer');
549
+ const cont = continuityParts(bound, limit ?? ASSEMBLY_LIMIT.probe);
550
+ return Object.freeze({
551
+ name: 'trust',
552
+ commands: Object.freeze({
553
+ ...commands,
554
+ ...entryCommands(bound),
555
+ ...profileParts.commands,
556
+ [TRUST_COMMANDS.recover]: { human: false, apply: (state) => recommitEntries(state, bound) },
557
+ }),
558
+ tasks: Object.freeze({
559
+ [ANCHOR_MAPPING_TYPE]: mappingTask(bound),
560
+ [STAR_TYPE]: taskOf(STAR, limit ?? ASSEMBLY_LIMIT.star),
561
+ [GROUP_STAR_TYPE]: taskOf(GROUP_STAR, limit ?? ASSEMBLY_LIMIT.groupStar),
562
+ ...profileParts.tasks,
563
+ ...cont.tasks,
564
+ }),
565
+ duties: Object.freeze({
566
+ // 2850: per class — the anchor mapping and the profile issue, the
567
+ // reconciled classes go by their sweep (trust/duties.ts)
568
+ 'class-on': classOnHandler({ anchorMapping: issueDuty(true), profile: profileIssueDuty }),
569
+ 'reissue-mapping': { ...issueDuty(false), awaitHolds: reissueAwaits },
570
+ profile: profileIssueDuty,
571
+ merge: mergeDuty(bound),
572
+ ...cont.duties,
573
+ }),
574
+ // 5.4: the star first, then the group star, each its own scope (5730)
575
+ sweeps: Object.freeze({ 'trust.star': sweepOf(STAR), 'trust.groupStar': sweepOf(GROUP_STAR) }),
576
+ acks: Object.freeze({ [STAR_TYPE]: ackOf(STAR), [GROUP_STAR_TYPE]: ackOf(GROUP_STAR), ...cont.acks }),
577
+ failures: Object.freeze({ ...cont.failures }),
578
+ ownRetries: cont.ownRetries,
579
+ keepKeys: cont.keepKeys,
580
+ // in-flight deliveries whose outbox items are all gone leave on tick
581
+ retain: (state) => retainInflight(state),
582
+ });
583
+ }
584
+ //# sourceMappingURL=mapping.js.map