@serfab/cadre-core 0.13.0 → 1.0.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 (131) hide show
  1. package/README.md +20 -6
  2. package/dist/bootstrap-peer-store-file.js +2 -2
  3. package/dist/bootstrap-peer-store.d.ts +32 -12
  4. package/dist/bootstrap-peer-store.js +41 -15
  5. package/dist/bootstrap-peer-store.js.map +1 -1
  6. package/dist/cadre-node.d.ts +558 -80
  7. package/dist/cadre-node.js +1060 -170
  8. package/dist/cadre-node.js.map +1 -1
  9. package/dist/control-authorization.d.ts +2 -2
  10. package/dist/control-authorization.js +1 -0
  11. package/dist/control-authorization.js.map +1 -1
  12. package/dist/control-cohort.d.ts +13 -26
  13. package/dist/control-cohort.js +0 -26
  14. package/dist/control-cohort.js.map +1 -1
  15. package/dist/control-database.d.ts +299 -44
  16. package/dist/control-database.js +469 -69
  17. package/dist/control-database.js.map +1 -1
  18. package/dist/control-read-retry.d.ts +40 -11
  19. package/dist/control-read-retry.js +48 -15
  20. package/dist/control-read-retry.js.map +1 -1
  21. package/dist/control-retry.d.ts +58 -3
  22. package/dist/control-retry.js +58 -3
  23. package/dist/control-retry.js.map +1 -1
  24. package/dist/control-schema.d.ts +1 -1
  25. package/dist/control-schema.js +103 -19
  26. package/dist/control-schema.js.map +1 -1
  27. package/dist/control-write-retry.d.ts +80 -11
  28. package/dist/control-write-retry.js +168 -29
  29. package/dist/control-write-retry.js.map +1 -1
  30. package/dist/enrolled-machine-store.js +2 -2
  31. package/dist/index.d.ts +14 -7
  32. package/dist/index.js +33 -6
  33. package/dist/index.js.map +1 -1
  34. package/dist/node-local-snapshot.d.ts +15 -7
  35. package/dist/node-local-snapshot.js +23 -8
  36. package/dist/node-local-snapshot.js.map +1 -1
  37. package/dist/peer-dial.d.ts +143 -0
  38. package/dist/peer-dial.js +176 -0
  39. package/dist/peer-dial.js.map +1 -0
  40. package/dist/relay-addrs.d.ts +90 -52
  41. package/dist/relay-addrs.js +91 -59
  42. package/dist/relay-addrs.js.map +1 -1
  43. package/dist/relay-reservation.d.ts +71 -3
  44. package/dist/relay-reservation.js +116 -8
  45. package/dist/relay-reservation.js.map +1 -1
  46. package/dist/seed-bootstrap.d.ts +30 -1
  47. package/dist/seed-bootstrap.js +62 -17
  48. package/dist/seed-bootstrap.js.map +1 -1
  49. package/dist/storage-scope.d.ts +62 -0
  50. package/dist/storage-scope.js +75 -0
  51. package/dist/storage-scope.js.map +1 -0
  52. package/dist/strand-database.d.ts +34 -16
  53. package/dist/strand-database.js +38 -24
  54. package/dist/strand-database.js.map +1 -1
  55. package/dist/strand-first-sync-gate.d.ts +152 -0
  56. package/dist/strand-first-sync-gate.js +208 -0
  57. package/dist/strand-first-sync-gate.js.map +1 -0
  58. package/dist/strand-formation-manager.d.ts +87 -5
  59. package/dist/strand-formation-manager.js +109 -5
  60. package/dist/strand-formation-manager.js.map +1 -1
  61. package/dist/strand-formation-protocol.d.ts +21 -1
  62. package/dist/strand-formation-protocol.js +30 -0
  63. package/dist/strand-formation-protocol.js.map +1 -1
  64. package/dist/strand-instance-manager.d.ts +243 -6
  65. package/dist/strand-instance-manager.js +470 -37
  66. package/dist/strand-instance-manager.js.map +1 -1
  67. package/dist/strand-member-key.d.ts +20 -12
  68. package/dist/strand-member-key.js +20 -12
  69. package/dist/strand-member-key.js.map +1 -1
  70. package/dist/strand-member-registry.js +3 -0
  71. package/dist/strand-member-registry.js.map +1 -1
  72. package/dist/strand-membership-reconciler.d.ts +361 -0
  73. package/dist/strand-membership-reconciler.js +548 -0
  74. package/dist/strand-membership-reconciler.js.map +1 -0
  75. package/dist/strand-membership-writer.d.ts +131 -11
  76. package/dist/strand-membership-writer.js +396 -134
  77. package/dist/strand-membership-writer.js.map +1 -1
  78. package/dist/strand-network-config.d.ts +46 -14
  79. package/dist/strand-network-config.js +79 -23
  80. package/dist/strand-network-config.js.map +1 -1
  81. package/dist/strand-solicitation.d.ts +10 -1
  82. package/dist/strand-solicitation.js +5 -0
  83. package/dist/strand-solicitation.js.map +1 -1
  84. package/dist/strand-wake-protocol.d.ts +11 -7
  85. package/dist/strand-wake-protocol.js +20 -52
  86. package/dist/strand-wake-protocol.js.map +1 -1
  87. package/dist/strand-watcher.js +6 -0
  88. package/dist/strand-watcher.js.map +1 -1
  89. package/dist/timed-step.d.ts +12 -0
  90. package/dist/timed-step.js +28 -0
  91. package/dist/timed-step.js.map +1 -0
  92. package/dist/timeout-scheduler.d.ts +19 -0
  93. package/dist/timeout-scheduler.js +22 -0
  94. package/dist/timeout-scheduler.js.map +1 -0
  95. package/dist/types.d.ts +262 -30
  96. package/dist/types.js.map +1 -1
  97. package/package.json +8 -8
  98. package/src/bootstrap-peer-store-file.ts +2 -2
  99. package/src/bootstrap-peer-store.ts +69 -27
  100. package/src/cadre-node.ts +7301 -6353
  101. package/src/control-authorization.ts +2 -1
  102. package/src/control-cohort.ts +122 -130
  103. package/src/control-database.ts +537 -69
  104. package/src/control-read-retry.ts +202 -167
  105. package/src/control-retry.ts +297 -190
  106. package/src/control-schema.ts +103 -19
  107. package/src/control-write-retry.ts +525 -383
  108. package/src/enrolled-machine-store.ts +2 -2
  109. package/src/index.ts +83 -6
  110. package/src/node-local-snapshot.ts +25 -8
  111. package/src/peer-dial.ts +215 -0
  112. package/src/relay-addrs.ts +458 -436
  113. package/src/relay-reservation.ts +951 -828
  114. package/src/seed-bootstrap.ts +76 -18
  115. package/src/storage-scope.ts +78 -0
  116. package/src/strand-database.ts +50 -27
  117. package/src/strand-first-sync-gate.ts +258 -0
  118. package/src/strand-formation-manager.ts +140 -5
  119. package/src/strand-formation-protocol.ts +43 -1
  120. package/src/strand-instance-manager.ts +577 -37
  121. package/src/strand-member-key.ts +20 -12
  122. package/src/strand-member-registry.ts +3 -0
  123. package/src/strand-membership-reconciler.ts +680 -0
  124. package/src/strand-membership-writer.ts +527 -189
  125. package/src/strand-network-config.ts +102 -24
  126. package/src/strand-solicitation.ts +16 -1
  127. package/src/strand-wake-protocol.ts +21 -66
  128. package/src/strand-watcher.ts +6 -0
  129. package/src/timed-step.ts +28 -0
  130. package/src/timeout-scheduler.ts +28 -0
  131. package/src/types.ts +1789 -1554
@@ -100,6 +100,29 @@ export declare function signStrandApproval(fields: ReadonlyArray<string | number
100
100
  * @returns A fresh base64url stamp (43 chars for 32 bytes).
101
101
  */
102
102
  export declare function generateStrandStampId(): string;
103
+ /**
104
+ * A membership writer that runs only in a transaction of its own found another
105
+ * transaction already open on the strand database, and wrote nothing. Raised only
106
+ * under `joinOpenTransaction: false` (see {@link StrandWriteOptions}) — the background
107
+ * callers, which treat it as "the app is mid-transaction; try again later".
108
+ */
109
+ export declare class StrandTransactionBusyError extends Error {
110
+ constructor(options?: ErrorOptions);
111
+ }
112
+ /** Options every transactional membership writer accepts. */
113
+ export interface StrandWriteOptions {
114
+ /**
115
+ * Default true: when a transaction is already open on the database, run the writer's
116
+ * statements inside it. The caller composes several writers in one transaction (e.g. a
117
+ * resign + revoke pair that must land together) and owns its commit and rollback, so
118
+ * the deferred constraints fire once, at the caller's commit.
119
+ *
120
+ * Background callers (the membership reconciler, the unpublish binding cleanup) pass
121
+ * false: they share the database with the app and must never join a transaction
122
+ * someone else opened, so the writer throws {@link StrandTransactionBusyError} instead.
123
+ */
124
+ joinOpenTransaction?: boolean;
125
+ }
103
126
  /** Parameters for {@link bootstrapFounderMembership}. */
104
127
  export interface FounderBootstrapParams {
105
128
  /** The strand id — written to `Header.Id`. */
@@ -114,7 +137,45 @@ export interface FounderBootstrapParams {
114
137
  * Required for a closed strand; ignored for an open strand.
115
138
  */
116
139
  founderKeyPair?: Ed25519KeyPair;
140
+ /**
141
+ * The public key derived from the strand row's SHARED `MemberPrivateKey` (the read
142
+ * secret every joining party holds). When supplied for a closed strand, a
143
+ * `Strand.Member` or `Strand.Manager` row holding it refuses the bootstrap with
144
+ * {@link PreSplitStrandIdentityError} (see {@link assertNotPreSplitStrand}): nothing
145
+ * seats that key since the per-party identity split, so its presence is exactly the
146
+ * fingerprint of a strand founded before it. Omitted, no such check runs (a caller that
147
+ * holds no shared key has nothing to compare against). Ignored for an open strand.
148
+ */
149
+ sharedMemberPublicKey?: string;
117
150
  }
151
+ /**
152
+ * A closed strand founded BEFORE the per-party identity split: its founding
153
+ * `Strand.Member` (and, unless handed on, `Strand.Manager`) is the key derived from the
154
+ * shared `MemberPrivateKey`, which every joining party holds, so any member can sign as
155
+ * the founder. There is no repair — rewriting the membership cannot be trusted, since any
156
+ * joiner could already have admitted or revoked anyone, or could race the rewrite — so
157
+ * the strand must be recreated. Thrown by {@link assertNotPreSplitStrand} (a founder
158
+ * bootstrap, or membership-invite issuance); the formation layer maps it to a
159
+ * non-retryable rejection.
160
+ */
161
+ export declare class PreSplitStrandIdentityError extends Error {
162
+ readonly strandId: string;
163
+ constructor(strandId: string);
164
+ }
165
+ /**
166
+ * Refuse a closed strand whose membership still holds the key derived from the shared
167
+ * `MemberPrivateKey` (see {@link FounderBootstrapParams.sharedMemberPublicKey}). `Member`
168
+ * is the primary probe — every manager is a member (`Manager.MemberExists`), so it also
169
+ * catches a pre-split founder who handed management to another key and resigned, or a
170
+ * sealed pre-split strand. `Manager` is probed too, for the partition case the schema
171
+ * notes on `MemberExists` (a Manager row converged without its Member row). Cannot
172
+ * misfire: nothing seats the shared-derived key since the split, and rows not yet loaded
173
+ * read as absent.
174
+ *
175
+ * @throws {PreSplitStrandIdentityError} when a `Strand.Member` or `Strand.Manager` row is
176
+ * the shared-derived key.
177
+ */
178
+ export declare function assertNotPreSplitStrand(db: Database, strandId: string, sharedMemberPublicKey: string): Promise<void>;
118
179
  /**
119
180
  * Founder-only one-time bootstrap of a strand's `Strand.*` membership/RBAC rows.
120
181
  *
@@ -136,10 +197,17 @@ export interface FounderBootstrapParams {
136
197
  * Manager could never admit anyone, so failing loudly here (which propagates out
137
198
  * of `StrandDatabase.initialize()` and triggers the runtime's rollback) is correct.
138
199
  *
200
+ * A closed strand whose membership holds `sharedMemberPublicKey` throws
201
+ * {@link PreSplitStrandIdentityError} before writing anything: the insert-if-absent
202
+ * guards would otherwise skip over its pre-split founding rows and leave the shared
203
+ * key seated.
204
+ *
139
205
  * @param db - The strand's Quereus database (schema already applied).
140
206
  * @param params - Strand id/type, the sApp config for the Header, and (closed only)
141
- * the derived founder keypair.
207
+ * the derived founder keypair and the shared-derived public key to refuse.
142
208
  * @throws If `type === 'c'` and no `founderKeyPair` is supplied.
209
+ * @throws {PreSplitStrandIdentityError} If `type === 'c'` and a `Strand.Member` or
210
+ * `Strand.Manager` row is `sharedMemberPublicKey`.
143
211
  */
144
212
  export declare function bootstrapFounderMembership(db: Database, params: FounderBootstrapParams): Promise<void>;
145
213
  /** Parameters for {@link issueInvite}. */
@@ -244,11 +312,41 @@ export interface ConsumeInviteParams {
244
312
  * @param db - The closed strand's database.
245
313
  * @param params - The invite key/secret, the joining member's public key, and an
246
314
  * optional `nowMs` instant for the expiry comparison (default `Date.now()`).
315
+ * @param options - Whether to join an already-open transaction (see {@link StrandWriteOptions}).
247
316
  * @throws If any constraint rejects (bad signature, missing invite, or an expired
248
317
  * invite); the whole transaction rolls back (neither the `Member` nor the
249
318
  * `ConsumedInvite` row survives).
319
+ * @throws {StrandTransactionBusyError} Under `joinOpenTransaction: false`, when another
320
+ * transaction is open; nothing was written.
321
+ */
322
+ export declare function consumeInvite(db: Database, params: ConsumeInviteParams, options?: StrandWriteOptions): Promise<void>;
323
+ /**
324
+ * Burn an invitation against an ALREADY-SEATED member: insert the
325
+ * `Strand.ConsumedInvite` row alone, naming the existing `Member.Key`, so the bearer
326
+ * credential can never be spent by anyone else.
327
+ *
328
+ * The already-member arm of the bring-up membership reconciler
329
+ * (`strand-membership-reconciler.ts`): a machine that finds its party's `Member` row
330
+ * already present (a sibling machine redeemed the invitation's twin first, or a
331
+ * manager admitted the party directly) may still hold an UNSPENT formation-delivered
332
+ * invitation — a bearer credential whoever presents can join with. Every
333
+ * `ConsumedInvite` constraint is satisfiable without a same-transaction `Member`
334
+ * insert (`MemberExists` reads the live table), so this is one statement whose
335
+ * deferred checks fire at its own commit. It seats nobody now or later:
336
+ * `Member.Authorized`'s invite branch requires a same-transaction FRESH consumption,
337
+ * so the row it leaves is exactly as inert as any other spent invitation's.
338
+ *
339
+ * @param db - The closed strand's database (the member already exists).
340
+ * @param params - The invite key/secret and the EXISTING member's public key, plus the
341
+ * optional `nowMs` instant for the expiry gate (default `Date.now()`).
342
+ * @param options - Whether to join an already-open transaction (see {@link StrandWriteOptions}).
343
+ * @throws If any constraint rejects — already consumed (the `InviteKey` primary key),
344
+ * cancelled, expired, or a sealed strand. Callers treat a burn failure as "already
345
+ * dead" and log rather than retry.
346
+ * @throws {StrandTransactionBusyError} Under `joinOpenTransaction: false`, when another
347
+ * transaction is open; nothing was tried, so the invitation is exactly as live as before.
250
348
  */
251
- export declare function consumeInvite(db: Database, params: ConsumeInviteParams): Promise<void>;
349
+ export declare function burnInvite(db: Database, params: ConsumeInviteParams, options?: StrandWriteOptions): Promise<void>;
252
350
  /** Parameters for {@link cancelInvite}. */
253
351
  export interface CancelInviteParams {
254
352
  /**
@@ -338,6 +436,15 @@ export interface OutstandingInvite {
338
436
  * matters); empty if none.
339
437
  */
340
438
  export declare function listOutstandingInvites(db: Database, nowMs?: number): Promise<OutstandingInvite[]>;
439
+ /**
440
+ * Whether `memberKey` holds a live `Strand.Member` row, as seen by THIS database
441
+ * instance — the membership probe behind the bring-up reconciler
442
+ * (`strand-membership-reconciler.ts`). Reads via {@link memberStampId}'s unfiltered
443
+ * scan + JavaScript compare (the {@link scanMemberPeers} argument for why a PK point
444
+ * lookup is not reliable on a networked strand). Local visibility only: `false` can
445
+ * mean "not replicated here yet", never a durable verdict about the strand.
446
+ */
447
+ export declare function isStrandMember(db: Database, memberKey: string): Promise<boolean>;
341
448
  /** Parameters for {@link addMemberByManager}. */
342
449
  export interface AddMemberByManagerParams {
343
450
  /**
@@ -364,10 +471,11 @@ export interface AddMemberByManagerParams {
364
471
  *
365
472
  * @param db - The closed strand's database.
366
473
  * @param params - The admitting manager keypair and the new member key.
474
+ * @param options - Whether to join an already-open transaction (see {@link StrandWriteOptions}).
367
475
  * @throws If `Member.Authorized` rejects (e.g. a non-manager key); the insert
368
476
  * rolls back, leaving no `Member` row.
369
477
  */
370
- export declare function addMemberByManager(db: Database, params: AddMemberByManagerParams): Promise<void>;
478
+ export declare function addMemberByManager(db: Database, params: AddMemberByManagerParams, options?: StrandWriteOptions): Promise<void>;
371
479
  /** Parameters for {@link revokeMember}. */
372
480
  export interface RevokeMemberParams {
373
481
  /**
@@ -426,12 +534,13 @@ export interface RevokeMemberParams {
426
534
  *
427
535
  * @param db - The closed strand's database.
428
536
  * @param params - The revoking manager keypair and the target member key.
537
+ * @param options - Whether to join an already-open transaction (see {@link StrandWriteOptions}).
429
538
  * @throws If `Member.Authorized` rejects (a non-manager or same-transaction
430
539
  * signer), `Member.NotAManager` rejects (the target still holds a Manager
431
540
  * row), or `Member.MinOneMember` rejects (the removal would empty the member
432
541
  * set); the whole delete+tombstone transaction rolls back.
433
542
  */
434
- export declare function revokeMember(db: Database, params: RevokeMemberParams): Promise<void>;
543
+ export declare function revokeMember(db: Database, params: RevokeMemberParams, options?: StrandWriteOptions): Promise<void>;
435
544
  /** Parameters for {@link leaveStrand}. */
436
545
  export interface LeaveStrandParams {
437
546
  /**
@@ -466,10 +575,11 @@ export interface LeaveStrandParams {
466
575
  *
467
576
  * @param db - The closed strand's database.
468
577
  * @param params - The departing member's own keypair.
578
+ * @param options - Whether to join an already-open transaction (see {@link StrandWriteOptions}).
469
579
  * @throws If `Member.Authorized`, `Member.NotAManager`, or `Member.MinOneMember`
470
580
  * rejects; the whole delete+tombstone transaction rolls back.
471
581
  */
472
- export declare function leaveStrand(db: Database, params: LeaveStrandParams): Promise<void>;
582
+ export declare function leaveStrand(db: Database, params: LeaveStrandParams, options?: StrandWriteOptions): Promise<void>;
473
583
  /** Parameters for {@link registerMemberPeer}. */
474
584
  export interface RegisterMemberPeerParams {
475
585
  /**
@@ -515,10 +625,13 @@ export interface RegisterMemberPeerParams {
515
625
  *
516
626
  * @param db - The closed strand's database (the member already exists).
517
627
  * @param params - The member's own keypair and the peer id to bind.
628
+ * @param options - Whether to join an already-open transaction (see {@link StrandWriteOptions}).
518
629
  * @throws If `MemberPeer.Authorized`/`MemberExists` rejects (wrong signer, or no
519
630
  * matching `Member` row); the insert rolls back, leaving no `MemberPeer` row.
631
+ * @throws {StrandTransactionBusyError} Under `joinOpenTransaction: false`, when another
632
+ * transaction is open; nothing was written.
520
633
  */
521
- export declare function registerMemberPeer(db: Database, params: RegisterMemberPeerParams): Promise<void>;
634
+ export declare function registerMemberPeer(db: Database, params: RegisterMemberPeerParams, options?: StrandWriteOptions): Promise<void>;
522
635
  /**
523
636
  * Every `PeerId` currently bound to `memberKey`, in storage order.
524
637
  *
@@ -601,10 +714,13 @@ export type RemoveMemberPeerParams = RemoveOwnPeerParams | RemoveMemberPeerByMan
601
714
  * @param db - The closed strand's database.
602
715
  * @param params - Either the owning member's keypair, or a manager's keypair plus the
603
716
  * target member key.
717
+ * @param options - Whether to join an already-open transaction (see {@link StrandWriteOptions}).
604
718
  * @throws If `MemberPeer.Authorized` rejects (neither branch satisfied), or if the row
605
719
  * is still present after the delete (see the point-lookup note below).
720
+ * @throws {StrandTransactionBusyError} Under `joinOpenTransaction: false`, when another
721
+ * transaction is open; nothing was written.
606
722
  */
607
- export declare function removeMemberPeer(db: Database, params: RemoveMemberPeerParams): Promise<void>;
723
+ export declare function removeMemberPeer(db: Database, params: RemoveMemberPeerParams, options?: StrandWriteOptions): Promise<void>;
608
724
  /** Parameters for {@link addManager}. */
609
725
  export interface AddManagerParams {
610
726
  /**
@@ -648,11 +764,12 @@ export interface AddManagerParams {
648
764
  *
649
765
  * @param db - The closed strand's database (founder manager already seated).
650
766
  * @param params - The authorizing manager's keypair and the new manager key.
767
+ * @param options - Whether to join an already-open transaction (see {@link StrandWriteOptions}).
651
768
  * @throws If `Manager.Authorized` rejects, or if `Manager.MemberExists` rejects because
652
769
  * `newManagerKey` holds no `Member` row (admit it first, or use
653
770
  * {@link admitManager}); the insert rolls back.
654
771
  */
655
- export declare function addManager(db: Database, params: AddManagerParams): Promise<void>;
772
+ export declare function addManager(db: Database, params: AddManagerParams, options?: StrandWriteOptions): Promise<void>;
656
773
  /** Parameters for {@link admitManager} — the same shape as {@link AddManagerParams}. */
657
774
  export type AdmitManagerParams = AddManagerParams;
658
775
  /**
@@ -682,10 +799,11 @@ export type AdmitManagerParams = AddManagerParams;
682
799
  *
683
800
  * @param db - The closed strand's database (founder manager already seated).
684
801
  * @param params - The authorizing manager's keypair and the key to admit + promote.
802
+ * @param options - Whether to join an already-open transaction (see {@link StrandWriteOptions}).
685
803
  * @throws If either half is rejected (`Member.Authorized`, `Manager.Authorized`, a
686
804
  * duplicate `Member` key, …); the whole transaction rolls back, leaving neither row.
687
805
  */
688
- export declare function admitManager(db: Database, params: AdmitManagerParams): Promise<void>;
806
+ export declare function admitManager(db: Database, params: AdmitManagerParams, options?: StrandWriteOptions): Promise<void>;
689
807
  /** Parameters for {@link removeManager}. */
690
808
  export interface RemoveManagerParams {
691
809
  /**
@@ -770,13 +888,14 @@ export interface RemoveManagerParams {
770
888
  *
771
889
  * @param db - The closed strand's database.
772
890
  * @param params - The authorizing keypair and the target manager key.
891
+ * @param options - Whether to join an already-open transaction (see {@link StrandWriteOptions}).
773
892
  * @throws If the signer IS the target and it is the sole manager (before writing —
774
893
  * the operation the caller wants is {@link sealStrand}), or if `Manager.Authorized`
775
894
  * rejects (a signer that is neither another existing manager nor the target
776
895
  * itself, or a raw sole-manager `'resign'` whose post-image count is zero); the
777
896
  * whole delete+tombstone transaction rolls back.
778
897
  */
779
- export declare function removeManager(db: Database, params: RemoveManagerParams): Promise<void>;
898
+ export declare function removeManager(db: Database, params: RemoveManagerParams, options?: StrandWriteOptions): Promise<void>;
780
899
  /** Parameters for {@link sealStrand}. */
781
900
  export interface SealStrandParams {
782
901
  /**
@@ -825,6 +944,7 @@ export interface SealStrandParams {
825
944
  *
826
945
  * @param db - The closed strand's database.
827
946
  * @param params - The sole manager's own keypair.
947
+ * @param options - Whether to join an already-open transaction (see {@link StrandWriteOptions}).
828
948
  * @throws If more than one manager exists (the caller wants {@link removeManager}),
829
949
  * or the supplied keypair holds no `Manager` row while one exists, or the strand
830
950
  * holds no `Manager` row and has never retired one (not founded yet — see
@@ -833,7 +953,7 @@ export interface SealStrandParams {
833
953
  * and returns quietly (restart-safe, matching {@link bootstrapFounderMembership}
834
954
  * and {@link removeManager}'s absent-row no-op).
835
955
  */
836
- export declare function sealStrand(db: Database, params: SealStrandParams): Promise<void>;
956
+ export declare function sealStrand(db: Database, params: SealStrandParams, options?: StrandWriteOptions): Promise<void>;
837
957
  /**
838
958
  * Whether the strand is sealed: a CLOSED strand that holds no `Manager` rows AND
839
959
  * has retired at least one `Manager` stamp into `Strand.Revocation`.