@serfab/cadre-core 1.7.0 → 1.9.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 (188) hide show
  1. package/README.md +8 -6
  2. package/dist/cadre-node.d.ts +527 -206
  3. package/dist/cadre-node.js +1084 -528
  4. package/dist/cadre-node.js.map +1 -1
  5. package/dist/control-authorization.d.ts +2 -2
  6. package/dist/control-authorization.js +1 -0
  7. package/dist/control-authorization.js.map +1 -1
  8. package/dist/control-cohort.d.ts +6 -0
  9. package/dist/control-cohort.js +6 -0
  10. package/dist/control-cohort.js.map +1 -1
  11. package/dist/control-database.d.ts +46 -8
  12. package/dist/control-database.js +97 -18
  13. package/dist/control-database.js.map +1 -1
  14. package/dist/control-formation-recorder.d.ts +37 -14
  15. package/dist/control-formation-recorder.js +60 -10
  16. package/dist/control-formation-recorder.js.map +1 -1
  17. package/dist/control-read-retry.d.ts +13 -12
  18. package/dist/control-read-retry.js +14 -12
  19. package/dist/control-read-retry.js.map +1 -1
  20. package/dist/control-schema.d.ts +1 -1
  21. package/dist/control-schema.js +67 -5
  22. package/dist/control-schema.js.map +1 -1
  23. package/dist/control-stream.d.ts +9 -1
  24. package/dist/control-stream.js +24 -1
  25. package/dist/control-stream.js.map +1 -1
  26. package/dist/control-write-retry.d.ts +12 -2
  27. package/dist/control-write-retry.js +13 -2
  28. package/dist/control-write-retry.js.map +1 -1
  29. package/dist/delegate-admission.d.ts +11 -8
  30. package/dist/delegate-admission.js +19 -11
  31. package/dist/delegate-admission.js.map +1 -1
  32. package/dist/diagnostics/connection-path.d.ts +0 -7
  33. package/dist/diagnostics/connection-path.js +0 -7
  34. package/dist/diagnostics/connection-path.js.map +1 -1
  35. package/dist/formation-approval.d.ts +7 -0
  36. package/dist/formation-approval.js +9 -3
  37. package/dist/formation-approval.js.map +1 -1
  38. package/dist/fs-atomic.d.ts +11 -2
  39. package/dist/fs-atomic.js +13 -3
  40. package/dist/fs-atomic.js.map +1 -1
  41. package/dist/hibernation-manager.d.ts +111 -8
  42. package/dist/hibernation-manager.js +234 -49
  43. package/dist/hibernation-manager.js.map +1 -1
  44. package/dist/index.d.ts +10 -10
  45. package/dist/index.js +25 -20
  46. package/dist/index.js.map +1 -1
  47. package/dist/joined-strand-store.d.ts +90 -25
  48. package/dist/joined-strand-store.js +223 -55
  49. package/dist/joined-strand-store.js.map +1 -1
  50. package/dist/key-store-file.js +14 -5
  51. package/dist/key-store-file.js.map +1 -1
  52. package/dist/link-budget.d.ts +367 -69
  53. package/dist/link-budget.js +375 -72
  54. package/dist/link-budget.js.map +1 -1
  55. package/dist/membership-connection-gater.d.ts +30 -43
  56. package/dist/membership-connection-gater.js +31 -42
  57. package/dist/membership-connection-gater.js.map +1 -1
  58. package/dist/node-local-snapshot.d.ts +6 -4
  59. package/dist/node-local-snapshot.js +7 -3
  60. package/dist/node-local-snapshot.js.map +1 -1
  61. package/dist/peer-dial.d.ts +24 -4
  62. package/dist/peer-dial.js +74 -5
  63. package/dist/peer-dial.js.map +1 -1
  64. package/dist/peer-join-backfill.d.ts +2 -10
  65. package/dist/peer-join-backfill.js +8 -8
  66. package/dist/peer-join-backfill.js.map +1 -1
  67. package/dist/push-fanout.d.ts +6 -0
  68. package/dist/push-fanout.js +6 -0
  69. package/dist/push-fanout.js.map +1 -1
  70. package/dist/relay-reservation.d.ts +3 -1
  71. package/dist/relay-reservation.js +3 -1
  72. package/dist/relay-reservation.js.map +1 -1
  73. package/dist/relay-server.d.ts +79 -0
  74. package/dist/relay-server.js +74 -0
  75. package/dist/relay-server.js.map +1 -0
  76. package/dist/seed-bootstrap.d.ts +57 -4
  77. package/dist/seed-bootstrap.js +107 -83
  78. package/dist/seed-bootstrap.js.map +1 -1
  79. package/dist/storage-scope.d.ts +33 -17
  80. package/dist/storage-scope.js +44 -23
  81. package/dist/storage-scope.js.map +1 -1
  82. package/dist/strand-addr-protocol.d.ts +58 -21
  83. package/dist/strand-addr-protocol.js +133 -85
  84. package/dist/strand-addr-protocol.js.map +1 -1
  85. package/dist/strand-database.d.ts +20 -2
  86. package/dist/strand-database.js +42 -5
  87. package/dist/strand-database.js.map +1 -1
  88. package/dist/strand-first-sync-gate.d.ts +59 -21
  89. package/dist/strand-first-sync-gate.js +58 -19
  90. package/dist/strand-first-sync-gate.js.map +1 -1
  91. package/dist/strand-formation-deadlines.d.ts +151 -0
  92. package/dist/strand-formation-deadlines.js +171 -0
  93. package/dist/strand-formation-deadlines.js.map +1 -0
  94. package/dist/strand-formation-manager.d.ts +63 -30
  95. package/dist/strand-formation-manager.js +67 -41
  96. package/dist/strand-formation-manager.js.map +1 -1
  97. package/dist/strand-formation-protocol.d.ts +45 -46
  98. package/dist/strand-formation-protocol.js +62 -126
  99. package/dist/strand-formation-protocol.js.map +1 -1
  100. package/dist/strand-fret-addrs.d.ts +54 -0
  101. package/dist/strand-fret-addrs.js +108 -0
  102. package/dist/strand-fret-addrs.js.map +1 -0
  103. package/dist/strand-instance-manager.d.ts +122 -44
  104. package/dist/strand-instance-manager.js +270 -114
  105. package/dist/strand-instance-manager.js.map +1 -1
  106. package/dist/strand-membership-writer.d.ts +6 -0
  107. package/dist/strand-membership-writer.js +11 -0
  108. package/dist/strand-membership-writer.js.map +1 -1
  109. package/dist/strand-network-state-file.d.ts +12 -0
  110. package/dist/strand-network-state-file.js +38 -0
  111. package/dist/strand-network-state-file.js.map +1 -0
  112. package/dist/strand-network-state.d.ts +111 -0
  113. package/dist/strand-network-state.js +191 -0
  114. package/dist/strand-network-state.js.map +1 -0
  115. package/dist/strand-revocation-enforcer.js +2 -1
  116. package/dist/strand-revocation-enforcer.js.map +1 -1
  117. package/dist/strand-solicitation.d.ts +36 -20
  118. package/dist/strand-solicitation.js +4 -4
  119. package/dist/strand-solicitation.js.map +1 -1
  120. package/dist/strand-wake-protocol.d.ts +80 -23
  121. package/dist/strand-wake-protocol.js +89 -64
  122. package/dist/strand-wake-protocol.js.map +1 -1
  123. package/dist/types.d.ts +148 -61
  124. package/dist/types.js +4 -3
  125. package/dist/types.js.map +1 -1
  126. package/package.json +11 -10
  127. package/src/cadre-node.ts +8400 -7776
  128. package/src/control-authorization.ts +2 -1
  129. package/src/control-cohort.ts +6 -0
  130. package/src/control-database.ts +122 -18
  131. package/src/control-formation-recorder.ts +354 -305
  132. package/src/control-read-retry.ts +14 -12
  133. package/src/control-schema.ts +67 -5
  134. package/src/control-stream.ts +25 -1
  135. package/src/control-write-retry.ts +13 -2
  136. package/src/delegate-admission.ts +23 -13
  137. package/src/diagnostics/connection-path.ts +0 -7
  138. package/src/formation-approval.ts +610 -604
  139. package/src/fs-atomic.ts +14 -4
  140. package/src/hibernation-manager.ts +638 -437
  141. package/src/index.ts +43 -65
  142. package/src/joined-strand-store.ts +247 -57
  143. package/src/key-store-file.ts +14 -5
  144. package/src/link-budget.ts +393 -74
  145. package/src/membership-connection-gater.ts +31 -45
  146. package/src/node-local-snapshot.ts +12 -7
  147. package/src/peer-dial.ts +81 -7
  148. package/src/peer-join-backfill.ts +10 -9
  149. package/src/push-fanout.ts +6 -0
  150. package/src/relay-reservation.ts +3 -1
  151. package/src/relay-server.ts +98 -0
  152. package/src/seed-bootstrap.ts +133 -91
  153. package/src/storage-scope.ts +44 -23
  154. package/src/strand-addr-protocol.ts +547 -458
  155. package/src/strand-database.ts +287 -242
  156. package/src/strand-first-sync-gate.ts +58 -19
  157. package/src/strand-formation-deadlines.ts +227 -0
  158. package/src/strand-formation-manager.ts +700 -647
  159. package/src/strand-formation-protocol.ts +106 -154
  160. package/src/strand-fret-addrs.ts +145 -0
  161. package/src/strand-instance-manager.ts +307 -140
  162. package/src/strand-membership-writer.ts +12 -0
  163. package/src/strand-network-state-file.ts +40 -0
  164. package/src/strand-network-state.ts +243 -0
  165. package/src/strand-revocation-enforcer.ts +2 -1
  166. package/src/strand-solicitation.ts +519 -500
  167. package/src/strand-wake-protocol.ts +401 -355
  168. package/src/types.ts +150 -61
  169. package/dist/strand-peer-book-file.d.ts +0 -12
  170. package/dist/strand-peer-book-file.js +0 -37
  171. package/dist/strand-peer-book-file.js.map +0 -1
  172. package/dist/strand-peer-book-protocol.d.ts +0 -159
  173. package/dist/strand-peer-book-protocol.js +0 -360
  174. package/dist/strand-peer-book-protocol.js.map +0 -1
  175. package/dist/strand-peer-book-swap.d.ts +0 -104
  176. package/dist/strand-peer-book-swap.js +0 -284
  177. package/dist/strand-peer-book-swap.js.map +0 -1
  178. package/dist/strand-peer-book.d.ts +0 -159
  179. package/dist/strand-peer-book.js +0 -354
  180. package/dist/strand-peer-book.js.map +0 -1
  181. package/dist/strand-peer-observer.d.ts +0 -88
  182. package/dist/strand-peer-observer.js +0 -180
  183. package/dist/strand-peer-observer.js.map +0 -1
  184. package/src/strand-peer-book-file.ts +0 -39
  185. package/src/strand-peer-book-protocol.ts +0 -463
  186. package/src/strand-peer-book-swap.ts +0 -338
  187. package/src/strand-peer-book.ts +0 -468
  188. package/src/strand-peer-observer.ts +0 -235
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Strand-formation deadlines, derived from the declared link round trip.
3
+ *
4
+ * The wire protocol lives in `strand-formation-protocol.ts`; this module is only the
5
+ * arithmetic it runs on: the ladder of deadlines one declaration yields
6
+ * ({@link formationDeadlines}) and the clamping of a caller's configured provisioning budget
7
+ * under its session ({@link resolveProvisionTimeoutMs}, {@link splitProvisionBudget}). It
8
+ * reaches `link-budget.ts` for the counts and `formation-approval.ts` for the hook's flat
9
+ * timeout, and nothing in the protocol, so both roles and the manager can import it freely.
10
+ */
11
+ import debug from 'debug';
12
+ import { DEFAULT_APPROVAL_TIMEOUT_MS } from './formation-approval.js';
13
+ import { CIRCUIT_REQUEST_ROUND_TRIPS, cohortReadDeadlineMs, commitBudgetMs, relayedStreamOpenBudgetMs, resolveLinkRoundTripMs } from './link-budget.js';
14
+ const log = debug('sereus:cadre:formation-deadlines');
15
+ /**
16
+ * Derive every formation deadline from the declared link round trip
17
+ * (`NetworkConfig.linkRoundTripMs`; the default when none is declared is
18
+ * `DECLARED_LINK_ROUND_TRIP_MS` in `link-budget.ts`). With `L` the declaration, `R` one
19
+ * cohort read at that link (`cohortReadDeadlineMs`, 2L: one request and its answer over an
20
+ * open circuit) and `K` one commit (`commitBudgetMs`, 20L, measured):
21
+ *
22
+ * dialMs = a relayed dial plus one protocol negotiation (5L + 2 000)
23
+ * awaitContactMs = one request over the open stream (2L)
24
+ * validationMs = 2R (4L)
25
+ * provisionWorkMs = approval hook (10 000, flat) + 2R + K (10 000 + 24L)
26
+ * provisionGraceMs = R + K (22L)
27
+ * responseTravelMarginMs = L + validationMs (5L)
28
+ * initiatorAwaitResponseMs = work + grace + margin (10 000 + 51L)
29
+ * sessionMs = dialMs + initiatorAwaitResponseMs (12 000 + 56L)
30
+ *
31
+ * Why each term:
32
+ *
33
+ * - **awaitContact**: the listener's handler starts when it answers the protocol
34
+ * negotiation; the answer reaches the joiner and the contact frame comes back, one round
35
+ * trip, budgeted as a request over an open stream (2) for the same headroom as every other
36
+ * one-exchange read in `link-budget.ts`.
37
+ * - **validation** and the reads inside **provisionWork** are budgeted at two consulting
38
+ * reads each, not one per read the code issues. What actually runs: validation is three
39
+ * control reads (`isTokenValid` reads the invite; `isTokenUsed` reads it again and counts
40
+ * its usages) plus whatever the disclosure validator does; the bound provisioning path
41
+ * (`StrandFormationManager.provisionAsResponder`) reads the invite and the strand row to
42
+ * resolve the host strand, the invite again, the approver's `ValidationKey` and the seat
43
+ * count around the outside approval hook (an HTTP call, so its own
44
+ * `DEFAULT_APPROVAL_TIMEOUT_MS` is link-independent and added flat), the strand row and its
45
+ * `StrandPartyKey` to issue the joiner's membership invite, and the host strand's stamp
46
+ * before the `FormationUsage` write; then one strand-database commit issues the invite.
47
+ * Every one of those is a read of this party's own control database, which in steady state
48
+ * touches held blocks and consults nobody (`cadre-consistency.md` → "Deadlines Over
49
+ * Optimystic's Reads and Commits"), so `R` is charged as headroom for the ones that do
50
+ * consult, not per read. Waking a hibernating host strand inside the issue is NOT counted
51
+ * either: `wakeHostStrandForFormation` cuts it off by design with a retryable rejection
52
+ * and leaves the wake running, so the joiner's retry finds the strand live.
53
+ * NOTE: if formation is seen timing out while the responder's control reads are consulting
54
+ * the cohort (a cold responder, a control database not yet converged), charge one `R` per
55
+ * read here rather than raising the flat headroom; the joiner is told 'Formation
56
+ * provisioning timed out' with its invite unspent, so the cost is a retry, not a spent
57
+ * invite.
58
+ * - **provisionGrace**: the window it exists for opens when the `FormationUsage` insert
59
+ * attempt passes its abort check. `ControlDatabase.redeemInvitation` and
60
+ * `recordFormationUsage` check the signal once per attempt inside the write lock, then run
61
+ * the seat read (`assertSeatRemains`) and the transaction, so the grace contains one read
62
+ * plus one commit. A retry after a failed attempt re-checks the abort, so only one attempt
63
+ * needs containing.
64
+ * - **responseTravelMargin**: half a round trip out, half back, plus the validation reads,
65
+ * which run on the initiator's await-response clock but before the responder's
66
+ * provisioning clock starts.
67
+ * - **session**: the initiator's dial plus its await-response. The responder's whole path
68
+ * (awaitContact + validation + work + grace = 10 000 + 52L) is inside it at every L.
69
+ *
70
+ * Ordering, strict at every L > 0, and pinned by `strand-formation-deadlines.spec.ts`:
71
+ * approval hook < provisionWork < work + grace < initiatorAwaitResponse < session, and the
72
+ * responder's whole path < session. Each layer can therefore fail and report before the
73
+ * layer above it gives up, and the work budget always outlasts the hook's own timeout, so a
74
+ * dead hook reports 'Formation approval unavailable, retry' rather than racing a
75
+ * provisioning timeout.
76
+ *
77
+ * **What this costs.** At the default declaration (3 500 ms) a joiner whose responder
78
+ * accepts the contact and then hangs waits up to 188.5 s, about three minutes, before it is
79
+ * told, where the fixed ladder this replaced told it after 15 s; the whole session is
80
+ * bounded at 208 s. A responder that is unreachable still fails at the dial, 19.5 s. A host
81
+ * that knows its party is on a fast link lowers `linkRoundTripMs` and gets roughly the old
82
+ * numbers back (at L = 100: dial 2.5 s, provisioning 14.6 s, await-response 15.1 s, session
83
+ * 17.6 s). Before this derivation, the fixed 5 s dial could not open a relayed connection
84
+ * above a 1.25-second round trip, and the fixed 2 s grace could not contain one commit at the
85
+ * supported link, so a joiner could be told 'timed out' over an invite that was in fact
86
+ * spent.
87
+ */
88
+ export function formationDeadlines(linkRoundTripMs) {
89
+ const link = resolveLinkRoundTripMs(linkRoundTripMs);
90
+ const readMs = cohortReadDeadlineMs(link);
91
+ const commitMs = commitBudgetMs(link);
92
+ const dialMs = relayedStreamOpenBudgetMs(link);
93
+ const validationMs = 2 * readMs;
94
+ const provisionWorkMs = DEFAULT_APPROVAL_TIMEOUT_MS + 2 * readMs + commitMs;
95
+ const provisionGraceMs = readMs + commitMs;
96
+ const responseTravelMarginMs = link + validationMs;
97
+ const initiatorAwaitResponseMs = provisionWorkMs + provisionGraceMs + responseTravelMarginMs;
98
+ return {
99
+ dialMs,
100
+ awaitContactMs: CIRCUIT_REQUEST_ROUND_TRIPS * link,
101
+ validationMs,
102
+ provisionWorkMs,
103
+ provisionGraceMs,
104
+ responseTravelMarginMs,
105
+ initiatorAwaitResponseMs,
106
+ sessionMs: dialMs + initiatorAwaitResponseMs
107
+ };
108
+ }
109
+ /**
110
+ * Ceiling for a resolved provisioning budget.
111
+ *
112
+ * The session budget also has to cover what PRECEDES provisioning in the role
113
+ * (`precedingMs`: the initiator's dial; the responder's contact read plus its validation
114
+ * reads), so that whole span is held back rather than triggering only on a literal overrun.
115
+ *
116
+ * `reserveMs` is the EXTRA room only the responder holds back, so its own budget still
117
+ * lands strictly before the initiator's larger await-response budget even when both are
118
+ * clamped — without it, a configured budget large enough to clamp both roles puts the
119
+ * responder's reply on the wire at the moment the initiator's timeout fires. Capped at half
120
+ * the remaining room (like {@link splitProvisionBudget}) so a small session config still
121
+ * spends most of it working.
122
+ */
123
+ function provisionCeilingMs(sessionTimeoutMs, precedingMs, reserveMs) {
124
+ const roomMs = sessionTimeoutMs - precedingMs;
125
+ return Math.max(1, roomMs - Math.min(reserveMs, Math.floor(roomMs / 2)));
126
+ }
127
+ /**
128
+ * The extra room the responder's clamp holds back ({@link provisionCeilingMs}'s `reserveMs`).
129
+ *
130
+ * The initiator's clamped await-response is `session - dial`, and the responder's reply
131
+ * reaches it `responseTravelMarginMs` after provisioning ends, so provisioning must end by
132
+ * `session - dial - margin`. The responder's own room is `session - awaitContact -
133
+ * validation`; the difference between the two is what it must hold back on top. Computed
134
+ * from the responder's own derivation, since it cannot see the initiator's dial budget: the
135
+ * module doc of `link-budget.ts` says why both parties must declare the same link.
136
+ */
137
+ export function responderClampReserveMs(deadlines, awaitContactMs) {
138
+ return Math.max(0, deadlines.dialMs + deadlines.responseTravelMarginMs - awaitContactMs - deadlines.validationMs);
139
+ }
140
+ /**
141
+ * Resolve a caller-supplied provisioning budget: `0`/negative means "unset" (use
142
+ * `defaultMs`). If the result would let provisioning outlive the session — no result
143
+ * frame is ever sent, exactly the failure this budget exists to prevent — clamp it to
144
+ * {@link provisionCeilingMs} and log a warning. A budget that exactly meets the ceiling is
145
+ * not clamped: the derived defaults sit there by construction.
146
+ */
147
+ export function resolveProvisionTimeoutMs(configured, defaultMs, sessionTimeoutMs, precedingMs, role, reserveMs = 0) {
148
+ const requested = configured && configured > 0 ? configured : defaultMs;
149
+ const ceilingMs = provisionCeilingMs(sessionTimeoutMs, precedingMs, reserveMs);
150
+ if (requested > ceilingMs) {
151
+ log('%s provisionTimeoutMs %dms leaves no room under sessionTimeoutMs %dms (preceding %dms, reserve %dms); clamping to %dms', role, requested, sessionTimeoutMs, precedingMs, reserveMs, ceilingMs);
152
+ return ceilingMs;
153
+ }
154
+ return requested;
155
+ }
156
+ /**
157
+ * Split a resolved provisioning budget into the WORK budget and the trailing settle grace.
158
+ *
159
+ * The grace is carved OUT of the budget, never added on top, so the ladder in
160
+ * {@link formationDeadlines} is untouched: the listener aborts the provisioning hook when the
161
+ * work budget expires, then waits up to the grace for the work to settle anyway
162
+ * (`FormationListener.settleWithinGrace` in `strand-formation-protocol.ts`). `graceCeilingMs`
163
+ * is the derived grace, which contains one seat read plus one commit at the declared link; it
164
+ * is capped at half the budget so a small configured budget still spends at least half its
165
+ * time doing work.
166
+ */
167
+ export function splitProvisionBudget(provisionTimeoutMs, graceCeilingMs) {
168
+ const graceMs = Math.min(graceCeilingMs, Math.floor(provisionTimeoutMs / 2));
169
+ return { workMs: provisionTimeoutMs - graceMs, graceMs };
170
+ }
171
+ //# sourceMappingURL=strand-formation-deadlines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strand-formation-deadlines.js","sourceRoot":"","sources":["../src/strand-formation-deadlines.ts"],"names":[],"mappings":"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"}
@@ -14,12 +14,14 @@ export declare const MEMBERSHIP_INVITE_TTL_MS: number;
14
14
  /**
15
15
  * Rejection reason for a bound CLOSED-strand redemption whose responder could not issue
16
16
  * the joiner's membership invitation — the host strand runtime not live on this
17
- * responder, no party identity key yet, or the strand DB refusing the `Strand.Invite`
18
- * write. Retryable on purpose, and rejected BEFORE the consent row is recorded, so the
19
- * formation token stays unspent: approving without an invitation would admit a joiner
20
- * that looks joined but can never become a member, and a responder not running the
21
- * strand cannot serve the joiner's sync anyway. The one permanent failure,
22
- * a pre-split host strand, gets {@link HOST_STRAND_MUST_BE_RECREATED_REASON} instead.
17
+ * responder (never launched, mid-start, or a hibernating one that did not wake within the
18
+ * provisioning budget; a hibernating runtime is woken, not refused), no party identity key
19
+ * yet, or the strand DB refusing the `Strand.Invite` write. Retryable on purpose, and
20
+ * rejected BEFORE the consent row is recorded, so the formation token stays unspent:
21
+ * approving without an invitation would admit a joiner that looks joined but can never
22
+ * become a member, and a responder not running the strand cannot serve the joiner's sync
23
+ * anyway. The one permanent failure, a pre-split host strand, gets
24
+ * {@link HOST_STRAND_MUST_BE_RECREATED_REASON} instead.
23
25
  */
24
26
  export declare const MEMBERSHIP_INVITE_UNAVAILABLE_REASON = "Strand membership invitation unavailable, retry";
25
27
  /**
@@ -31,20 +33,36 @@ export declare const MEMBERSHIP_INVITE_UNAVAILABLE_REASON = "Strand membership i
31
33
  * the formation token stays unspent.
32
34
  */
33
35
  export declare const HOST_STRAND_MUST_BE_RECREATED_REASON = "Host strand must be recreated";
36
+ /**
37
+ * Responder-side seam that issues a bound joiner's membership invitation — see
38
+ * {@link StrandFormationManagerOptions.issueMembershipInvite} for the contract. `signal`
39
+ * is the responder's provisioning budget: the issuer stops waiting (and throws) once it
40
+ * aborts.
41
+ */
42
+ export type MembershipInviteIssuer = (strandId: string, signal?: AbortSignal) => Promise<StrandMembershipInvite | null>;
34
43
  /**
35
44
  * Configuration for StrandFormationManager
36
45
  */
37
46
  export interface StrandFormationManagerConfig {
38
- /** Session timeout in milliseconds */
47
+ /**
48
+ * This machine's declared link round trip (`NetworkConfig.linkRoundTripMs`), from which
49
+ * every formation deadline is derived (`formationDeadlines` in
50
+ * `strand-formation-deadlines.ts`). `CadreNode` fills it from its network config; the
51
+ * fields below override single rungs of that ladder.
52
+ */
53
+ linkRoundTripMs?: number;
54
+ /** Whole-session budget, both roles, in milliseconds. */
39
55
  sessionTimeoutMs?: number;
40
- /** Step timeout in milliseconds */
56
+ /** The responder's contact-frame read, in milliseconds. */
41
57
  stepTimeoutMs?: number;
58
+ /** The initiator's dial-connect (open the connection, negotiate the protocol), in milliseconds. */
59
+ dialTimeoutMs?: number;
42
60
  /**
43
61
  * Provisioning budget in milliseconds for the RESPONDER's `provisionStrand` hook call.
44
- * The initiator's `await-response` wait is derived automatically from this value plus
45
- * `PROVISION_RESPONSE_TRAVEL_MARGIN_MS` (`strand-formation-protocol.ts`) — never set
46
- * directly — so the ordering documented there (approval hook < responder provisioning <
47
- * initiator await-response < session) cannot collapse when this is configured.
62
+ * The initiator's `await-response` wait is derived automatically from this value plus the
63
+ * travel margin of the derived ladder (`responseTravelMarginMs`) — never set directly — so
64
+ * the ordering documented there (approval hook < responder provisioning < initiator
65
+ * await-response < session) cannot collapse when this is configured.
48
66
  */
49
67
  provisionTimeoutMs?: number;
50
68
  /** Maximum concurrent sessions */
@@ -97,11 +115,15 @@ export interface StrandFormationManagerOptions {
97
115
  * `PreSplitStrandIdentityError` for a host strand that can never issue one; that maps
98
116
  * to the non-retryable {@link HOST_STRAND_MUST_BE_RECREATED_REASON}.
99
117
  *
118
+ * A hibernating host runtime is not a reason to throw: the issuer wakes it first,
119
+ * bounded by `signal` (the responder's provisioning budget), and throws only when the
120
+ * wake does not finish in time or fails.
121
+ *
100
122
  * Left unwired — mock/transport tests — the bound path approves with no invitation,
101
123
  * mirroring the unwired {@link resolveStrandAddrs} posture. Production
102
124
  * (`CadreNode.initializeStrandSolicitation`) always wires it.
103
125
  */
104
- issueMembershipInvite?: (strandId: string) => Promise<StrandMembershipInvite | null>;
126
+ issueMembershipInvite?: MembershipInviteIssuer;
105
127
  /** Configuration options */
106
128
  config?: StrandFormationManagerConfig;
107
129
  }
@@ -136,11 +158,11 @@ export declare class StrandFormationManager {
136
158
  * Register this manager as a protocol handler on a libp2p node.
137
159
  * Call this on the control network node to handle incoming formation requests.
138
160
  */
139
- registerResponder(node: Libp2p, protocolId?: string): void;
161
+ registerResponder(node: Libp2p, protocolId?: string): Promise<void>;
140
162
  /**
141
163
  * Unregister the protocol handler from a libp2p node.
142
164
  */
143
- unregisterResponder(node: Libp2p, protocolId?: string): void;
165
+ unregisterResponder(node: Libp2p, protocolId?: string): Promise<void>;
144
166
  /**
145
167
  * Form a strand with a responder via an open invitation (initiator side).
146
168
  *
@@ -171,12 +193,13 @@ export declare class StrandFormationManager {
171
193
  private membershipInviteFrom;
172
194
  /**
173
195
  * Derive the initiator's await-response budget from the configured RESPONDER budget —
174
- * never the same number (see `StrandFormationManagerConfig.provisionTimeoutMs`). Mirrors
175
- * `resolveProvisionTimeoutMs`'s own "`0`/negative means unset" rule so an unset config
176
- * still lets both sides fall back to their own independent defaults; must NOT hardcode
177
- * `DEFAULT_PROVISION_TIMEOUT_MS` here, or the per-role clamping downstream is defeated.
196
+ * never the same number (see `StrandFormationManagerConfig.provisionTimeoutMs`): the
197
+ * configured value plus the travel margin the ladder derives at this machine's link.
198
+ * Mirrors `resolveProvisionTimeoutMs`'s own "`0`/negative means unset" rule so an unset
199
+ * config still lets both sides fall back to their own derived defaults; must NOT
200
+ * reproduce the derived default here, or the per-role clamping downstream is defeated.
178
201
  * A value too large for the session is clamped per role, and the responder's ceiling holds
179
- * the same margin back, so the ordering survives there too.
202
+ * the margin back, so the ordering survives there too.
180
203
  */
181
204
  private initiatorProvisionTimeoutMs;
182
205
  private validateToken;
@@ -187,14 +210,16 @@ export declare class StrandFormationManager {
187
210
  * {@link ResponderProvisionOutcome} with `approved: false` — `runSession` turns that
188
211
  * into a clean, non-disclosing reply instead of a dropped result frame.
189
212
  *
190
- * - **bound** (host strand present): provision-then-record — first issue the joiner's
191
- * single-use strand membership invitation via the wired `issueMembershipInvite` seam
192
- * ({@link issueBoundMembershipInvite}; a closed strand whose invitation cannot be
193
- * issued rejects retryably HERE, before any consent row spends the token), then write
194
- * the single `FormationUsage` consent row against the pre-existing strand
195
- * (record-only) and return it + its membership key + the invitation (all read-gating
196
- * secrets disclosed only here, behind the token + disclosure validation `runSession`
197
- * already enforced).
213
+ * - **bound** (host strand present): provision-then-record, in three steps —
214
+ * (1) authorize ({@link authorizeBoundUsage}: the outside approval when the invite
215
+ * demands one, and a seat pre-check), so a refused join writes nothing into the host
216
+ * strand; (2) issue the joiner's single-use strand membership invitation via the wired
217
+ * `issueMembershipInvite` seam ({@link issueBoundMembershipInvite}; a closed strand whose
218
+ * invitation cannot be issued rejects retryably HERE, before any consent row spends the
219
+ * token); (3) write the single `FormationUsage` consent row against the pre-existing
220
+ * strand (record-only) and return it + its membership key + the invitation (all
221
+ * read-gating secrets disclosed only here, behind the token + disclosure validation
222
+ * `runSession` already enforced).
198
223
  * - **missing** (invite names a host strand absent on this responder, e.g. unconverged):
199
224
  * reject cleanly + retryably, writing NO usage row — recording usage here would fail the
200
225
  * deferred `StrandExists` CHECK at commit and drop the frame.
@@ -213,15 +238,23 @@ export declare class StrandFormationManager {
213
238
  * not control-flow-by-exception.
214
239
  */
215
240
  private provisionAsResponder;
241
+ /**
242
+ * Authorize a BOUND redemption without writing it, through the recorder's optional
243
+ * {@link FormationUsageRecorder.authorizeUsage}. A recorder without it has nothing to ask up
244
+ * front, so its handle defers everything to `recordUsage`.
245
+ */
246
+ private authorizeBoundUsage;
216
247
  /**
217
248
  * Issue the joiner's membership invitation for a BOUND redemption via the wired
218
- * {@link StrandFormationManagerOptions.issueMembershipInvite} seam.
249
+ * {@link StrandFormationManagerOptions.issueMembershipInvite} seam. Runs after the
250
+ * redemption is authorized ({@link authorizeBoundUsage}) and before consent is recorded.
219
251
  *
220
252
  * - Hook unwired (mock/transport tests): approve with no invitation, the same posture
221
253
  * as an unwired `resolveStrandAddrs`.
222
254
  * - Hook returns an invitation (closed host strand): carry it on the approval.
223
255
  * - Hook returns `null` (open host strand): approve with no invitation.
224
- * - Hook throws (runtime not live, no party key, strand-DB write rejected): report
256
+ * - Hook throws (runtime not live — including a hibernating one whose wake outran
257
+ * `signal` — no party key, strand-DB write rejected): report
225
258
  * `ok: false` with {@link MEMBERSHIP_INVITE_UNAVAILABLE_REASON} — the caller rejects
226
259
  * BEFORE any consent row is written, so the formation token stays unspent.
227
260
  * - Hook throws `PreSplitStrandIdentityError` (the host strand was founded before the
@@ -6,7 +6,8 @@ import { FormationAbortedError, InvitationExhaustedError } from './control-datab
6
6
  import { PreSplitStrandIdentityError } from './strand-membership-writer.js';
7
7
  import { mintPlaceholderStrandId } from './strand-id.js';
8
8
  import { canonicalJson } from './canonical-json.js';
9
- import { FormationListener, INVALID_TOKEN_REASON, PROVISION_RESPONSE_TRAVEL_MARGIN_MS, dialFormation, isValidResponderCreatesResult, isWellFormedMembershipInvite } from './strand-formation-protocol.js';
9
+ import { FormationListener, INVALID_TOKEN_REASON, dialFormation, isValidResponderCreatesResult, isWellFormedMembershipInvite } from './strand-formation-protocol.js';
10
+ import { formationDeadlines } from './strand-formation-deadlines.js';
10
11
  const log = debug('sereus:cadre:formation-manager');
11
12
  /**
12
13
  * Largest serialized disclosure a responder will accept (8 KiB). The disclosure is
@@ -28,12 +29,14 @@ export const MEMBERSHIP_INVITE_TTL_MS = 7 * 24 * 3600000;
28
29
  /**
29
30
  * Rejection reason for a bound CLOSED-strand redemption whose responder could not issue
30
31
  * the joiner's membership invitation — the host strand runtime not live on this
31
- * responder, no party identity key yet, or the strand DB refusing the `Strand.Invite`
32
- * write. Retryable on purpose, and rejected BEFORE the consent row is recorded, so the
33
- * formation token stays unspent: approving without an invitation would admit a joiner
34
- * that looks joined but can never become a member, and a responder not running the
35
- * strand cannot serve the joiner's sync anyway. The one permanent failure,
36
- * a pre-split host strand, gets {@link HOST_STRAND_MUST_BE_RECREATED_REASON} instead.
32
+ * responder (never launched, mid-start, or a hibernating one that did not wake within the
33
+ * provisioning budget; a hibernating runtime is woken, not refused), no party identity key
34
+ * yet, or the strand DB refusing the `Strand.Invite` write. Retryable on purpose, and
35
+ * rejected BEFORE the consent row is recorded, so the formation token stays unspent:
36
+ * approving without an invitation would admit a joiner that looks joined but can never
37
+ * become a member, and a responder not running the strand cannot serve the joiner's sync
38
+ * anyway. The one permanent failure, a pre-split host strand, gets
39
+ * {@link HOST_STRAND_MUST_BE_RECREATED_REASON} instead.
37
40
  */
38
41
  export const MEMBERSHIP_INVITE_UNAVAILABLE_REASON = 'Strand membership invitation unavailable, retry';
39
42
  /**
@@ -92,6 +95,7 @@ export class StrandFormationManager {
92
95
  // Forwarded only when wired, so `FormationListenerOptions.resolveStrandAddrs`
93
96
  // stays genuinely absent (and the listener short-circuits) for an unwired manager.
94
97
  ...(this.resolveStrandAddrs && { resolveStrandAddrs: this.resolveStrandAddrs }),
98
+ linkRoundTripMs: this.config.linkRoundTripMs,
95
99
  sessionTimeoutMs: this.config.sessionTimeoutMs,
96
100
  stepTimeoutMs: this.config.stepTimeoutMs,
97
101
  provisionTimeoutMs: this.config.provisionTimeoutMs,
@@ -103,23 +107,23 @@ export class StrandFormationManager {
103
107
  * Register this manager as a protocol handler on a libp2p node.
104
108
  * Call this on the control network node to handle incoming formation requests.
105
109
  */
106
- registerResponder(node, protocolId) {
110
+ async registerResponder(node, protocolId) {
107
111
  if (this.registeredNodes.has(node)) {
108
112
  log('Node already registered');
109
113
  return;
110
114
  }
111
- this.listener.register(node, protocolId ?? this.config.protocolId);
115
+ await this.listener.register(node, protocolId ?? this.config.protocolId);
112
116
  this.registeredNodes.add(node);
113
117
  log('Registered as responder on node');
114
118
  }
115
119
  /**
116
120
  * Unregister the protocol handler from a libp2p node.
117
121
  */
118
- unregisterResponder(node, protocolId) {
122
+ async unregisterResponder(node, protocolId) {
119
123
  if (!this.registeredNodes.has(node)) {
120
124
  return;
121
125
  }
122
- this.listener.unregister(node, protocolId ?? this.config.protocolId);
126
+ await this.listener.unregister(node, protocolId ?? this.config.protocolId);
123
127
  this.registeredNodes.delete(node);
124
128
  log('Unregistered from node');
125
129
  }
@@ -149,8 +153,9 @@ export class StrandFormationManager {
149
153
  contact,
150
154
  responderAddrs: invitation.bootstrap,
151
155
  validateResponse: (response) => this.validateResponse(invitation, disclosure, response),
156
+ linkRoundTripMs: this.config.linkRoundTripMs,
152
157
  sessionTimeoutMs: this.config.sessionTimeoutMs,
153
- stepTimeoutMs: this.config.stepTimeoutMs,
158
+ dialTimeoutMs: this.config.dialTimeoutMs,
154
159
  provisionTimeoutMs: this.initiatorProvisionTimeoutMs(),
155
160
  protocolId: this.config.protocolId
156
161
  });
@@ -200,16 +205,19 @@ export class StrandFormationManager {
200
205
  }
201
206
  /**
202
207
  * Derive the initiator's await-response budget from the configured RESPONDER budget —
203
- * never the same number (see `StrandFormationManagerConfig.provisionTimeoutMs`). Mirrors
204
- * `resolveProvisionTimeoutMs`'s own "`0`/negative means unset" rule so an unset config
205
- * still lets both sides fall back to their own independent defaults; must NOT hardcode
206
- * `DEFAULT_PROVISION_TIMEOUT_MS` here, or the per-role clamping downstream is defeated.
208
+ * never the same number (see `StrandFormationManagerConfig.provisionTimeoutMs`): the
209
+ * configured value plus the travel margin the ladder derives at this machine's link.
210
+ * Mirrors `resolveProvisionTimeoutMs`'s own "`0`/negative means unset" rule so an unset
211
+ * config still lets both sides fall back to their own derived defaults; must NOT
212
+ * reproduce the derived default here, or the per-role clamping downstream is defeated.
207
213
  * A value too large for the session is clamped per role, and the responder's ceiling holds
208
- * the same margin back, so the ordering survives there too.
214
+ * the margin back, so the ordering survives there too.
209
215
  */
210
216
  initiatorProvisionTimeoutMs() {
211
217
  const host = this.config.provisionTimeoutMs;
212
- return host && host > 0 ? host + PROVISION_RESPONSE_TRAVEL_MARGIN_MS : undefined;
218
+ return host && host > 0
219
+ ? host + formationDeadlines(this.config.linkRoundTripMs).responseTravelMarginMs
220
+ : undefined;
213
221
  }
214
222
  // ── Responder-side hooks ─────────────────────────────────────────────────────
215
223
  async validateToken(token) {
@@ -241,14 +249,16 @@ export class StrandFormationManager {
241
249
  * {@link ResponderProvisionOutcome} with `approved: false` — `runSession` turns that
242
250
  * into a clean, non-disclosing reply instead of a dropped result frame.
243
251
  *
244
- * - **bound** (host strand present): provision-then-record — first issue the joiner's
245
- * single-use strand membership invitation via the wired `issueMembershipInvite` seam
246
- * ({@link issueBoundMembershipInvite}; a closed strand whose invitation cannot be
247
- * issued rejects retryably HERE, before any consent row spends the token), then write
248
- * the single `FormationUsage` consent row against the pre-existing strand
249
- * (record-only) and return it + its membership key + the invitation (all read-gating
250
- * secrets disclosed only here, behind the token + disclosure validation `runSession`
251
- * already enforced).
252
+ * - **bound** (host strand present): provision-then-record, in three steps —
253
+ * (1) authorize ({@link authorizeBoundUsage}: the outside approval when the invite
254
+ * demands one, and a seat pre-check), so a refused join writes nothing into the host
255
+ * strand; (2) issue the joiner's single-use strand membership invitation via the wired
256
+ * `issueMembershipInvite` seam ({@link issueBoundMembershipInvite}; a closed strand whose
257
+ * invitation cannot be issued rejects retryably HERE, before any consent row spends the
258
+ * token); (3) write the single `FormationUsage` consent row against the pre-existing
259
+ * strand (record-only) and return it + its membership key + the invitation (all
260
+ * read-gating secrets disclosed only here, behind the token + disclosure validation
261
+ * `runSession` already enforced).
252
262
  * - **missing** (invite names a host strand absent on this responder, e.g. unconverged):
253
263
  * reject cleanly + retryably, writing NO usage row — recording usage here would fail the
254
264
  * deferred `StrandExists` CHECK at commit and drop the frame.
@@ -284,18 +294,8 @@ export class StrandFormationManager {
284
294
  try {
285
295
  switch (resolved.kind) {
286
296
  case 'bound': {
287
- // Issued BEFORE the consent row is recorded, so an issue failure rejects with
288
- // the formation token still unspent (retryable). The inverse window — invite
289
- // issued, then recordUsage fails/aborts — orphans a live `Strand.Invite` no
290
- // joiner ever received; bounded deliberately by its expiry
291
- // ({@link MEMBERSHIP_INVITE_TTL_MS}) rather than compensated, since nothing
292
- // here can atomically un-issue a strand-DB row.
293
- const issued = await this.issueBoundMembershipInvite(token, resolved.strandId);
294
- if (!issued.ok) {
295
- return { approved: false, reason: issued.reason };
296
- }
297
297
  // recorder is guaranteed non-null here: only resolveStrand can yield 'bound'.
298
- await recorder.recordUsage({
298
+ const authorized = await this.authorizeBoundUsage(recorder, {
299
299
  token,
300
300
  peerKey: contact.peerKey,
301
301
  peerSignature: contact.peerSignature,
@@ -304,6 +304,19 @@ export class StrandFormationManager {
304
304
  disclosure: disclosureText,
305
305
  signal
306
306
  });
307
+ // Issued only once authorized (a refused join writes nothing into the strand) and
308
+ // BEFORE consent is recorded (an issue failure leaves the token unspent, retryable).
309
+ // The remaining window — invite issued, then record() fails or aborts (a write that
310
+ // exhausted its retries, an abort, or the same-node seat race noted at
311
+ // `ControlFormationUsageRecorder.assertSeatFree`) — orphans a
312
+ // live `Strand.Invite` no joiner ever received; bounded deliberately by its expiry
313
+ // ({@link MEMBERSHIP_INVITE_TTL_MS}) rather than compensated, since nothing
314
+ // here can atomically un-issue a strand-DB row.
315
+ const issued = await this.issueBoundMembershipInvite(token, resolved.strandId, signal);
316
+ if (!issued.ok) {
317
+ return { approved: false, reason: issued.reason };
318
+ }
319
+ await authorized.record();
307
320
  return this.approve({
308
321
  strand: { strandId: resolved.strandId, createdBy: 'responder' },
309
322
  memberPrivateKey: resolved.memberPrivateKey ?? undefined,
@@ -349,15 +362,28 @@ export class StrandFormationManager {
349
362
  return { approved: false, reason: 'Formation conflict, retry' };
350
363
  }
351
364
  }
365
+ /**
366
+ * Authorize a BOUND redemption without writing it, through the recorder's optional
367
+ * {@link FormationUsageRecorder.authorizeUsage}. A recorder without it has nothing to ask up
368
+ * front, so its handle defers everything to `recordUsage`.
369
+ */
370
+ async authorizeBoundUsage(recorder, params) {
371
+ if (recorder.authorizeUsage) {
372
+ return await recorder.authorizeUsage(params);
373
+ }
374
+ return { record: () => recorder.recordUsage(params) };
375
+ }
352
376
  /**
353
377
  * Issue the joiner's membership invitation for a BOUND redemption via the wired
354
- * {@link StrandFormationManagerOptions.issueMembershipInvite} seam.
378
+ * {@link StrandFormationManagerOptions.issueMembershipInvite} seam. Runs after the
379
+ * redemption is authorized ({@link authorizeBoundUsage}) and before consent is recorded.
355
380
  *
356
381
  * - Hook unwired (mock/transport tests): approve with no invitation, the same posture
357
382
  * as an unwired `resolveStrandAddrs`.
358
383
  * - Hook returns an invitation (closed host strand): carry it on the approval.
359
384
  * - Hook returns `null` (open host strand): approve with no invitation.
360
- * - Hook throws (runtime not live, no party key, strand-DB write rejected): report
385
+ * - Hook throws (runtime not live — including a hibernating one whose wake outran
386
+ * `signal` — no party key, strand-DB write rejected): report
361
387
  * `ok: false` with {@link MEMBERSHIP_INVITE_UNAVAILABLE_REASON} — the caller rejects
362
388
  * BEFORE any consent row is written, so the formation token stays unspent.
363
389
  * - Hook throws `PreSplitStrandIdentityError` (the host strand was founded before the
@@ -367,12 +393,12 @@ export class StrandFormationManager {
367
393
  * The LOG-before-reject keeps both a deliberate internal-error→protocol-rejection
368
394
  * conversion, same as the catch-all in {@link provisionAsResponder}.
369
395
  */
370
- async issueBoundMembershipInvite(token, strandId) {
396
+ async issueBoundMembershipInvite(token, strandId, signal) {
371
397
  if (!this.issueMembershipInvite) {
372
398
  return { ok: true };
373
399
  }
374
400
  try {
375
- const invite = await this.issueMembershipInvite(strandId);
401
+ const invite = await this.issueMembershipInvite(strandId, signal);
376
402
  return { ok: true, invite: invite ?? undefined };
377
403
  }
378
404
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"strand-formation-manager.js","sourceRoot":"","sources":["../src/strand-formation-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"strand-formation-manager.js","sourceRoot":"","sources":["../src/strand-formation-manager.ts"],"names":[],"mappings":"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"}