@interop/wallet-core 0.49.0 → 0.51.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 (163) hide show
  1. package/README.md +5 -2
  2. package/dist/clientAnnex/credentialAnchoredGenesis.d.ts +127 -0
  3. package/dist/clientAnnex/credentialAnchoredGenesis.d.ts.map +1 -0
  4. package/dist/clientAnnex/credentialAnchoredGenesis.js +195 -0
  5. package/dist/clientAnnex/credentialAnchoredGenesis.js.map +1 -0
  6. package/dist/clientAnnex/forget.d.ts +138 -0
  7. package/dist/clientAnnex/forget.d.ts.map +1 -0
  8. package/dist/clientAnnex/forget.js +133 -0
  9. package/dist/clientAnnex/forget.js.map +1 -0
  10. package/dist/clientAnnex/forgetLast.d.ts +291 -0
  11. package/dist/clientAnnex/forgetLast.d.ts.map +1 -0
  12. package/dist/clientAnnex/forgetLast.js +408 -0
  13. package/dist/clientAnnex/forgetLast.js.map +1 -0
  14. package/dist/{webvh/companionGc.d.ts → clientAnnex/gc.d.ts} +50 -16
  15. package/dist/clientAnnex/gc.d.ts.map +1 -0
  16. package/dist/{webvh/companionGc.js → clientAnnex/gc.js} +103 -71
  17. package/dist/clientAnnex/gc.js.map +1 -0
  18. package/dist/clientAnnex/index.d.ts +60 -0
  19. package/dist/clientAnnex/index.d.ts.map +1 -0
  20. package/dist/clientAnnex/index.js +60 -0
  21. package/dist/clientAnnex/index.js.map +1 -0
  22. package/dist/{unlock → clientAnnex}/ladder.d.ts +89 -15
  23. package/dist/clientAnnex/ladder.d.ts.map +1 -0
  24. package/dist/clientAnnex/ladder.js +474 -0
  25. package/dist/clientAnnex/ladder.js.map +1 -0
  26. package/dist/clientAnnex/ladderAnchored.d.ts +276 -0
  27. package/dist/clientAnnex/ladderAnchored.d.ts.map +1 -0
  28. package/dist/clientAnnex/ladderAnchored.js +631 -0
  29. package/dist/clientAnnex/ladderAnchored.js.map +1 -0
  30. package/dist/{webvh/companion.d.ts → clientAnnex/log.d.ts} +333 -119
  31. package/dist/clientAnnex/log.d.ts.map +1 -0
  32. package/dist/{webvh/companion.js → clientAnnex/log.js} +583 -199
  33. package/dist/clientAnnex/log.js.map +1 -0
  34. package/dist/clientAnnex/recoveryLadderAnchored.d.ts +103 -0
  35. package/dist/clientAnnex/recoveryLadderAnchored.d.ts.map +1 -0
  36. package/dist/clientAnnex/recoveryLadderAnchored.js +263 -0
  37. package/dist/clientAnnex/recoveryLadderAnchored.js.map +1 -0
  38. package/dist/{unlock → clientAnnex}/selfEnroll.d.ts +1 -1
  39. package/dist/clientAnnex/selfEnroll.d.ts.map +1 -0
  40. package/dist/{unlock → clientAnnex}/selfEnroll.js +1 -1
  41. package/dist/clientAnnex/selfEnroll.js.map +1 -0
  42. package/dist/clientAnnex/zcap.d.ts +49 -0
  43. package/dist/clientAnnex/zcap.d.ts.map +1 -0
  44. package/dist/clientAnnex/zcap.js +101 -0
  45. package/dist/clientAnnex/zcap.js.map +1 -0
  46. package/dist/clients/index.d.ts +9 -6
  47. package/dist/clients/index.d.ts.map +1 -1
  48. package/dist/clients/index.js +8 -5
  49. package/dist/clients/index.js.map +1 -1
  50. package/dist/clients/listing.d.ts +32 -0
  51. package/dist/clients/listing.d.ts.map +1 -1
  52. package/dist/clients/listing.js +47 -1
  53. package/dist/clients/listing.js.map +1 -1
  54. package/dist/clients/revocation.d.ts +33 -1
  55. package/dist/clients/revocation.d.ts.map +1 -1
  56. package/dist/clients/revocation.js +16 -4
  57. package/dist/clients/revocation.js.map +1 -1
  58. package/dist/enrollment/index.d.ts +6 -4
  59. package/dist/enrollment/index.d.ts.map +1 -1
  60. package/dist/enrollment/index.js +6 -4
  61. package/dist/enrollment/index.js.map +1 -1
  62. package/dist/enrollment/onboardingInvite.d.ts +5 -88
  63. package/dist/enrollment/onboardingInvite.d.ts.map +1 -1
  64. package/dist/enrollment/onboardingInvite.js +5 -168
  65. package/dist/enrollment/onboardingInvite.js.map +1 -1
  66. package/dist/genesis/accountGenesis.d.ts +12 -0
  67. package/dist/genesis/accountGenesis.d.ts.map +1 -1
  68. package/dist/genesis/accountGenesis.js.map +1 -1
  69. package/dist/genesis/index.d.ts +5 -0
  70. package/dist/genesis/index.d.ts.map +1 -1
  71. package/dist/genesis/index.js +5 -0
  72. package/dist/genesis/index.js.map +1 -1
  73. package/dist/keys/index.d.ts +1 -1
  74. package/dist/keys/index.d.ts.map +1 -1
  75. package/dist/keys/index.js +1 -1
  76. package/dist/keys/index.js.map +1 -1
  77. package/dist/keys/spaceEpochs.d.ts +7 -2
  78. package/dist/keys/spaceEpochs.d.ts.map +1 -1
  79. package/dist/keys/spaceEpochs.js +8 -2
  80. package/dist/keys/spaceEpochs.js.map +1 -1
  81. package/dist/keys/userKeyRoster.d.ts +39 -0
  82. package/dist/keys/userKeyRoster.d.ts.map +1 -1
  83. package/dist/keys/userKeyRoster.js +43 -1
  84. package/dist/keys/userKeyRoster.js.map +1 -1
  85. package/dist/recovery/index.d.ts +5 -3
  86. package/dist/recovery/index.d.ts.map +1 -1
  87. package/dist/recovery/index.js +4 -2
  88. package/dist/recovery/index.js.map +1 -1
  89. package/dist/recovery/recoveryDelegation.d.ts +35 -12
  90. package/dist/recovery/recoveryDelegation.d.ts.map +1 -1
  91. package/dist/recovery/recoveryDelegation.js +84 -86
  92. package/dist/recovery/recoveryDelegation.js.map +1 -1
  93. package/dist/recovery/recoveryWebvh.d.ts +32 -1
  94. package/dist/recovery/recoveryWebvh.d.ts.map +1 -1
  95. package/dist/recovery/recoveryWebvh.js +2 -2
  96. package/dist/recovery/recoveryWebvh.js.map +1 -1
  97. package/dist/request/capabilityRequest.d.ts +33 -0
  98. package/dist/request/capabilityRequest.d.ts.map +1 -0
  99. package/dist/request/capabilityRequest.js +35 -0
  100. package/dist/request/capabilityRequest.js.map +1 -0
  101. package/dist/request/ephemeralExchange.d.ts +118 -0
  102. package/dist/request/ephemeralExchange.d.ts.map +1 -0
  103. package/dist/request/ephemeralExchange.js +224 -0
  104. package/dist/request/ephemeralExchange.js.map +1 -0
  105. package/dist/request/index.d.ts +6 -0
  106. package/dist/request/index.d.ts.map +1 -1
  107. package/dist/request/index.js +6 -0
  108. package/dist/request/index.js.map +1 -1
  109. package/dist/space/activity.d.ts +2 -2
  110. package/dist/space/activity.js +3 -3
  111. package/dist/space/activity.js.map +1 -1
  112. package/dist/unlock/index.d.ts +11 -23
  113. package/dist/unlock/index.d.ts.map +1 -1
  114. package/dist/unlock/index.js +10 -21
  115. package/dist/unlock/index.js.map +1 -1
  116. package/dist/unlock/retire.d.ts +47 -3
  117. package/dist/unlock/retire.d.ts.map +1 -1
  118. package/dist/unlock/retire.js +21 -5
  119. package/dist/unlock/retire.js.map +1 -1
  120. package/dist/unlock/standingWebvh.d.ts +37 -82
  121. package/dist/unlock/standingWebvh.d.ts.map +1 -1
  122. package/dist/unlock/standingWebvh.js +64 -247
  123. package/dist/unlock/standingWebvh.js.map +1 -1
  124. package/dist/unlock/unlockRecord.d.ts +13 -6
  125. package/dist/unlock/unlockRecord.d.ts.map +1 -1
  126. package/dist/unlock/unlockRecord.js +14 -8
  127. package/dist/unlock/unlockRecord.js.map +1 -1
  128. package/dist/webvh/delegatedLogStore.d.ts +5 -5
  129. package/dist/webvh/delegatedLogStore.js +1 -1
  130. package/dist/webvh/didWebvh.d.ts +19 -9
  131. package/dist/webvh/didWebvh.d.ts.map +1 -1
  132. package/dist/webvh/didWebvh.js +16 -16
  133. package/dist/webvh/didWebvh.js.map +1 -1
  134. package/dist/webvh/index.d.ts +9 -25
  135. package/dist/webvh/index.d.ts.map +1 -1
  136. package/dist/webvh/index.js +9 -23
  137. package/dist/webvh/index.js.map +1 -1
  138. package/dist/webvh/revokeClient.d.ts +77 -5
  139. package/dist/webvh/revokeClient.d.ts.map +1 -1
  140. package/dist/webvh/revokeClient.js +154 -61
  141. package/dist/webvh/revokeClient.js.map +1 -1
  142. package/dist/webvh/standingZcap.d.ts +11 -1
  143. package/dist/webvh/standingZcap.d.ts.map +1 -1
  144. package/dist/webvh/standingZcap.js +13 -14
  145. package/dist/webvh/standingZcap.js.map +1 -1
  146. package/dist/webvh/wasIdStore.d.ts +13 -7
  147. package/dist/webvh/wasIdStore.d.ts.map +1 -1
  148. package/dist/webvh/wasIdStore.js +8 -4
  149. package/dist/webvh/wasIdStore.js.map +1 -1
  150. package/dist/webvh/zcap.d.ts +0 -24
  151. package/dist/webvh/zcap.d.ts.map +1 -1
  152. package/dist/webvh/zcap.js +0 -42
  153. package/dist/webvh/zcap.js.map +1 -1
  154. package/package.json +41 -35
  155. package/dist/unlock/ladder.d.ts.map +0 -1
  156. package/dist/unlock/ladder.js +0 -258
  157. package/dist/unlock/ladder.js.map +0 -1
  158. package/dist/unlock/selfEnroll.d.ts.map +0 -1
  159. package/dist/unlock/selfEnroll.js.map +0 -1
  160. package/dist/webvh/companion.d.ts.map +0 -1
  161. package/dist/webvh/companion.js.map +0 -1
  162. package/dist/webvh/companionGc.d.ts.map +0 -1
  163. package/dist/webvh/companionGc.js.map +0 -1
@@ -0,0 +1,408 @@
1
+ import { readPublishedLog, relationIds } from '../webvh/didWebvh.js';
2
+ import { clientRemovalTarget } from '../webvh/revokeClient.js';
3
+ import { delegationProofKeyId } from '../webvh/standingZcap.js';
4
+ import { vmFragmentOf } from '../resourceLog/index.js';
5
+ import { cascadeCollectionsToUserKey, readUserKeyRoster, rosterRecipientKid, rotateUserKeyRoster } from '../keys/index.js';
6
+ import { readLogOrThrow } from '../unlock/standingWebvh.js';
7
+ import { recordSignerFromAgent } from '../keyring/record.js';
8
+ import { remintRecoveryDelegations } from '../recovery/recoveryDelegation.js';
9
+ import { ladderVmKeyMultibase } from './ladder.js';
10
+ import { ladderVmAgent, ladderVmZcapClient } from './zcap.js';
11
+ import { forgetLastWebvhClient, installLadderVmWebvh } from './ladderAnchored.js';
12
+ import { clientAnnexDidParts, clientAnnexLogPinId, delegatedClientsDelegationMinter, delegatedClientsPointer, ensureGenerationDelegationCurrent, generationDelegationHistory, mintGenerationDelegation, revokeTreatingAlreadyRevokedAsSuccess } from './log.js';
13
+ /**
14
+ * The record re-mint stage could not reach every other unlock method's
15
+ * record, so the removal entry was refused: `failed` names the entries whose
16
+ * re-mint threw (each carrying its cause), and `unlockMethods` is the whole
17
+ * stage report. The forgotten client is still enrolled and every stage
18
+ * before this one has landed, so a re-run resumes at the re-mint. Matched
19
+ * on `name` (the errors cross app-injected seams that may resolve to another
20
+ * copy of this package).
21
+ */
22
+ export class RecordRemintFailedError extends Error {
23
+ failed;
24
+ unlockMethods;
25
+ constructor({ unlockMethods }) {
26
+ const failed = unlockMethods.outcomes.filter(outcome => outcome.outcome === 'failed');
27
+ super('did:webvh: the last-client forget could not re-mint the record of ' +
28
+ `${failed.length} other unlock method(s) (` +
29
+ failed.map(outcome => `"${outcome.label}"`).join(', ') +
30
+ '); the removal entry was not published. The client stays enrolled; ' +
31
+ 'run the forget again.');
32
+ this.name = 'RecordRemintFailedError';
33
+ this.failed = failed;
34
+ this.unlockMethods = unlockMethods;
35
+ }
36
+ }
37
+ /**
38
+ * Forgets the account's LAST enrolled durable client -- this browser's own
39
+ * -- transitioning the account to the client-less, ladder-anchored state.
40
+ * See the module doc for the stage order and the torn-state map. The caller
41
+ * runs the local wipe only after this resolves. An account with another
42
+ * enrolled durable client refuses: that forget is the ordinary ceremony
43
+ * (`forgetDurableClient`), reached first, whose `LastDurableClientForgetError`
44
+ * is what routes callers here.
45
+ *
46
+ * @param options {object}
47
+ * @param options.logStore {UnlockLogStore} the credential's delegated
48
+ * `did.jsonl` bridge store; also serves the ceremony's public reads. The
49
+ * caller is expected to have verified the account log under its own
50
+ * chain-head pins in the same session (the ceremony re-reads through the
51
+ * seam and checks `expectedDid`, but carries no account-log pin store
52
+ * itself)
53
+ * @param options.ladderSeed {Uint8Array} the login credential's ladder seed
54
+ * @param options.forgottenClient {RevokedClientKeys} this client's public
55
+ * halves; an `updateKeyMultibase` the log does not authorize (stale, or the
56
+ * staged key) is re-derived from the log
57
+ * @param options.forgottenKeyAgreementKeyMultibase {string} this client's
58
+ * identity key-agreement key (the X25519 twin), naming its roster wrap
59
+ * @param [options.knownLatentHashes] {string[]} standing latent commitments
60
+ * the caller vouches for (the recovery registry's update-key hashes),
61
+ * excluded from the staged-hash attribution
62
+ * @param options.expectedDid {string} the account DID from the caller's
63
+ * stored account pointer
64
+ * @param options.rosterStoreFor {Function} `({ did, log }) => store` --
65
+ * builds the `key-map/user-key.jsonl` roster store whose appends are
66
+ * SIGNED BY THE LADDER VM and whose controller view resolves from the
67
+ * supplied post-install log (the posture-changing anchor the ceremony-tail
68
+ * license admits), while its HTTP requests invoke under the still-standing
69
+ * client
70
+ * @param options.credentialKeyAgreementKey {IKeyAgreementKey} the standing
71
+ * credential's key-agreement key -- the recipient whose wrap survives the
72
+ * rotation, reading the fresh key back and unwrapping the generations for
73
+ * the fan-out
74
+ * @param [options.userKey] {UserKey} this client's cached user key
75
+ * @param [options.pinnedEpochId] {string} the locally pinned latest-seen
76
+ * roster epoch
77
+ * @param [options.onUserKeyAdopted] {Function} persists a rotated key:
78
+ * called with `{ userKey, latestEpochId, descriptor }` after the roster
79
+ * read and BEFORE the fan-out
80
+ * @param options.collections {CascadeCollections} the fan-out's work
81
+ * @param options.annex {object} the generation stage's reach:
82
+ * @param options.annex.storeFor {Function}
83
+ * `({ spaceId, generationId }) => ClientAnnexWriteStore` -- the pointed
84
+ * generation's log store, reading and writing under the still-standing
85
+ * client's authority
86
+ * @param options.annex.revoke {Function} `(delegation) => Promise<void>`
87
+ * -- POSTs a revocation (was-client's `WasClient#revoke`, bound by the
88
+ * caller; the invocation signs as the still-standing client)
89
+ * @param options.annex.wasServerUrl {string} the ACCOUNT Space's storage
90
+ * server (the fresh generation delegation's target host)
91
+ * @param options.annex.accountSpaceId {string} the ACCOUNT Space's id (the
92
+ * fresh delegation's target subtree)
93
+ * @param [options.annex.pinStore] {ResourceLogPinStore} chain-head pins
94
+ * for the pointed generation's read
95
+ * @param [options.unlockMethods] {UnlockMethodsRemintReach} the other
96
+ * unlock methods' record re-mint reach (stage 5): the registry entries
97
+ * whose bridge (and sibling) the ladder VM re-signs and whose records it
98
+ * re-seals through their management zcaps, invoked as the still-standing
99
+ * client. Omitted, the stage is skipped and the result carries no
100
+ * `unlockMethods` report -- the residue decision 0004's amendment stated.
101
+ * Supplied, an entry the pass could not re-mint refuses the removal entry
102
+ * (`RecordRemintFailedError`)
103
+ * @param [options.onBeforeRemoval] {Function}
104
+ * `({ did, doc, log }) => Promise<void>` -- the record re-bind seam: runs
105
+ * after the record re-mint stage, immediately before the removal entry,
106
+ * with the post-install published state. The caller re-signs the login
107
+ * credential's bridge and `delegatedClients` sibling with the ladder VM
108
+ * and re-seals its unlock record here. Must be idempotent (a resumed run
109
+ * invokes it again)
110
+ * @param [options.now] {number} epoch milliseconds, for tests
111
+ * @returns {Promise<LastDurableClientForgetResult>}
112
+ */
113
+ export async function forgetLastDurableClient({ logStore, ladderSeed, forgottenClient, forgottenKeyAgreementKeyMultibase, knownLatentHashes, expectedDid, rosterStoreFor, credentialKeyAgreementKey, userKey, pinnedEpochId, onUserKeyAdopted, collections, annex, unlockMethods, onBeforeRemoval, now = Date.now() }) {
114
+ // The pre-install read and the two guards: a client with no remaining
115
+ // presence means the removal entry already landed (the finish-the-wipe
116
+ // state the app's next login maps -- nothing here can still invoke), and
117
+ // an account with another enrolled durable client belongs to the ordinary
118
+ // forget ceremony.
119
+ const before = await readLogOrThrow({ store: logStore, expectedDid });
120
+ const preTarget = await clientRemovalTarget({
121
+ published: before,
122
+ client: forgottenClient
123
+ });
124
+ if (!preTarget.present) {
125
+ return {
126
+ installed: false,
127
+ rotated: false,
128
+ collections: { outcomes: {}, failed: [] },
129
+ generation: { revoked: [], replaced: false, skipped: 'already-removed' },
130
+ did: before.did,
131
+ document: before.doc
132
+ };
133
+ }
134
+ const signingVmId = `${before.did}#${forgottenClient.signingKeyMultibase}`;
135
+ const invocationIds = relationIds(before.doc.capabilityInvocation);
136
+ if (invocationIds.some(id => id !== signingVmId)) {
137
+ throw new Error('did:webvh: another enrolled durable client remains; the last-client ' +
138
+ 'transition ceremony does not apply -- run the ordinary forget.');
139
+ }
140
+ // Stage 1: the install entry -- the ladder VM in, the client untouched.
141
+ const install = await installLadderVmWebvh({
142
+ store: logStore,
143
+ ladderSeed,
144
+ expectedDid
145
+ });
146
+ // Stage 2: the roster rotation off this client's wrap, ladder-signed and
147
+ // anchored at the install entry, then stage 3, the collection fan-out --
148
+ // both HTTP-invoked under this client's still-standing authority. An
149
+ // already-rotated roster skips the append entirely, so the one-shot
150
+ // license is never asked for a second append at the same anchor.
151
+ let rotated = false;
152
+ let read;
153
+ let cascade = { outcomes: {}, failed: [] };
154
+ const rosterStore = rosterStoreFor({ did: install.did, log: install.log });
155
+ const current = await rosterStore.read();
156
+ if (current !== null) {
157
+ const forgottenKid = rosterRecipientKid({
158
+ signingKeyMultibase: forgottenClient.signingKeyMultibase,
159
+ keyAgreementKeyMultibase: forgottenKeyAgreementKeyMultibase
160
+ });
161
+ let descriptor = current.descriptor;
162
+ const currentEpoch = (descriptor.epochs ?? []).find(epoch => epoch.id === descriptor.currentEpoch);
163
+ const wrapped = currentEpoch?.recipients.some(entry => entry.header.kid === forgottenKid);
164
+ if (wrapped) {
165
+ descriptor = await rotateUserKeyRoster({
166
+ store: rosterStore,
167
+ document: install.doc,
168
+ retireRecipientId: forgottenKid
169
+ });
170
+ rotated = true;
171
+ }
172
+ // The fresh key comes back through the credential's standing wrap -- this
173
+ // client's own is gone from the current epoch -- with the continuity and
174
+ // possession checks still running on the threaded descriptor.
175
+ const adopted = await readUserKeyRoster({
176
+ store: rosterStore,
177
+ descriptor,
178
+ ...(userKey ? { userKey } : {}),
179
+ clientKeyAgreementKey: credentialKeyAgreementKey,
180
+ pinnedEpochId
181
+ });
182
+ if (adopted.rotated) {
183
+ await onUserKeyAdopted?.({
184
+ userKey: adopted.userKey,
185
+ latestEpochId: adopted.latestEpochId,
186
+ descriptor: adopted.descriptor
187
+ });
188
+ }
189
+ read = { userKey: adopted.userKey, descriptor: adopted.descriptor };
190
+ cascade = await cascadeCollectionsToUserKey({
191
+ collectionIds: typeof collections.collectionIds === 'function'
192
+ ? await collections.collectionIds()
193
+ : collections.collectionIds,
194
+ storeFor: collections.storeFor,
195
+ ...(collections.isEncrypted
196
+ ? { isEncrypted: collections.isEncrypted }
197
+ : {}),
198
+ rosterDescriptor: adopted.descriptor,
199
+ clientKeyAgreementKey: credentialKeyAgreementKey,
200
+ userKey: adopted.userKey
201
+ });
202
+ }
203
+ // Stage 4: the generation-delegation replacement and revocations.
204
+ const generation = await retireLadderGenerationDelegations({
205
+ doc: install.doc,
206
+ accountDid: install.did,
207
+ ladderSeed,
208
+ annex,
209
+ now
210
+ });
211
+ // Stage 5: the other unlock methods' record re-mint, ladder-signed, with
212
+ // the forgotten client named as retiring -- the post-install document
213
+ // still lists it, so without that axis every bridge it signed would read
214
+ // as standing and be left to rot at the removal entry.
215
+ let remint;
216
+ if (unlockMethods !== undefined) {
217
+ remint = await remintUnlockMethodRecordsAsLadder({
218
+ doc: install.doc,
219
+ accountDid: install.did,
220
+ ladderSeed,
221
+ retiringSigningKeyMultibase: forgottenClient.signingKeyMultibase,
222
+ reach: unlockMethods,
223
+ now
224
+ });
225
+ // The one pass that will ever reach these records on a client-less
226
+ // account: a record it could not re-seal would be left with a bridge the
227
+ // removal entry rots for good, so the removal is refused instead. The
228
+ // stages already landed are idempotent and the client still stands, so
229
+ // the re-run resumes here.
230
+ if (remint.outcomes.some(outcome => outcome.outcome === 'failed')) {
231
+ throw new RecordRemintFailedError({ unlockMethods: remint });
232
+ }
233
+ }
234
+ // Stage 6: the record re-bind seam, while the removal has not landed (a
235
+ // ladder-VM-signed bridge verifies from the install entry on, and the old
236
+ // client-signed one keeps verifying until the removal -- so a tear on
237
+ // either side of this callback leaves a working login).
238
+ await onBeforeRemoval?.({
239
+ did: install.did,
240
+ doc: install.doc,
241
+ log: install.log
242
+ });
243
+ // Stage 7: the removal entry -- the client's whole footprint out, the
244
+ // installed ladder VM keeping the account anchored.
245
+ const removed = await forgetLastWebvhClient({
246
+ store: logStore,
247
+ ladderSeed,
248
+ forgottenClient,
249
+ ...(knownLatentHashes ? { knownLatentHashes } : {}),
250
+ expectedDid
251
+ });
252
+ return {
253
+ installed: install.installed,
254
+ rotated,
255
+ collections: cascade,
256
+ generation,
257
+ ...(remint ? { unlockMethods: remint } : {}),
258
+ did: removed.did,
259
+ document: removed.doc,
260
+ ...(read
261
+ ? { userKey: read.userKey, rosterDescriptor: read.descriptor }
262
+ : {})
263
+ };
264
+ }
265
+ /**
266
+ * The generation stage: reads the pointed generation's log, force-replaces
267
+ * the embedded delegation with a fresh ladder-signed one (so the account
268
+ * stays transient-login-reachable), then revokes every still-unexpired
269
+ * delegation the log's history embedded that this credential's ladder VM
270
+ * signed. Replace-before-revoke is the tear-safety order: the fresh
271
+ * delegation is never in the pre-replacement history, so the revocation loop
272
+ * cannot touch it, and a run torn between the two leaves the generation with
273
+ * a live delegation either way.
274
+ *
275
+ * @param options {object}
276
+ * @param options.doc {DIDDoc} the post-install account document
277
+ * @param options.accountDid {string}
278
+ * @param options.ladderSeed {Uint8Array}
279
+ * @param options.annex {object} see {@link forgetLastDurableClient}
280
+ * @param options.now {number}
281
+ * @returns {Promise<GenerationDelegationRetirement>}
282
+ */
283
+ async function retireLadderGenerationDelegations({ doc, accountDid, ladderSeed, annex, now }) {
284
+ const pointedDid = delegatedClientsPointer({ doc });
285
+ if (pointedDid === undefined) {
286
+ return { revoked: [], replaced: false, skipped: 'no-pointer' };
287
+ }
288
+ const parts = clientAnnexDidParts({ did: pointedDid });
289
+ const store = annex.storeFor(parts);
290
+ const logId = clientAnnexLogPinId(parts);
291
+ // readPublishedLog only calls getIdResourceRaw, so the narrow seam is safe.
292
+ const published = await readPublishedLog({
293
+ idStore: store,
294
+ expectedDid: pointedDid,
295
+ ...(annex.pinStore !== undefined ? { pinStore: annex.pinStore, logId } : {})
296
+ });
297
+ if (published === undefined) {
298
+ return { revoked: [], replaced: false, skipped: 'log-unreadable' };
299
+ }
300
+ // The doomed set, collected BEFORE the replacement so the fresh delegation
301
+ // can never join it: every delegation the history embedded whose proof key
302
+ // is this credential's ladder VM and whose expiry has not passed. An
303
+ // unparseable or absent expiry counts as unexpired -- fail-safe, since an
304
+ // unbounded delegation is the worst resurrection credential.
305
+ const ladderVmKey = await ladderVmKeyMultibase({ ladderSeed });
306
+ const doomed = generationDelegationHistory({ log: published.log }).filter(delegation => {
307
+ const proofKeyId = delegationProofKeyId(delegation);
308
+ const fragment = proofKeyId === undefined ? null : vmFragmentOf(proofKeyId);
309
+ if (fragment !== ladderVmKey) {
310
+ return false;
311
+ }
312
+ const expires = Date.parse(delegation.expires ?? '');
313
+ return Number.isNaN(expires) || expires > now;
314
+ });
315
+ // The forced replacement first: a ladder-signed fresh delegation under the
316
+ // reinstalled VM, the annex entry signed by this credential's committed
317
+ // annex rung. A credential the generation does not commit cannot write the
318
+ // entry -- the honest skip, leaving the generation delegation-less once
319
+ // the doomed set is revoked below.
320
+ let replaced = false;
321
+ const ladderClient = await ladderVmZcapClient({ accountDid, ladderSeed });
322
+ try {
323
+ await ensureGenerationDelegationCurrent({
324
+ store,
325
+ ladderSeed,
326
+ generationId: parts.generationId,
327
+ mintGenerationDelegation: async ({ clientAnnexDid }) => mintGenerationDelegation({
328
+ zcapClient: ladderClient,
329
+ wasServerUrl: annex.wasServerUrl,
330
+ spaceId: annex.accountSpaceId,
331
+ clientAnnexDid,
332
+ now
333
+ }),
334
+ expectedDid: pointedDid,
335
+ force: true,
336
+ ...(annex.pinStore !== undefined
337
+ ? { pinStore: annex.pinStore, logId }
338
+ : {}),
339
+ now
340
+ });
341
+ replaced = true;
342
+ }
343
+ catch (err) {
344
+ if (err.name !== 'ClientAnnexRungUncommittedError') {
345
+ throw err;
346
+ }
347
+ }
348
+ // The revocations, blind and resumable (400 already-revoked as success).
349
+ const revoked = [];
350
+ for (const delegation of doomed) {
351
+ await revokeTreatingAlreadyRevokedAsSuccess({
352
+ revoke: annex.revoke,
353
+ delegation
354
+ });
355
+ const id = delegation.id;
356
+ if (typeof id === 'string') {
357
+ revoked.push(id);
358
+ }
359
+ }
360
+ return replaced
361
+ ? { revoked, replaced }
362
+ : { revoked, replaced, skipped: 'rung-uncommitted' };
363
+ }
364
+ /**
365
+ * The record re-mint stage: the revocation cascade's re-mint pass over the
366
+ * other unlock methods' registry entries, with the ladder VM as both the
367
+ * delegating key (the fresh bridge and sibling) and the record-frame signer
368
+ * (`ladderVmAgent`'s did:key form, whose multibase the post-install document
369
+ * lists, so a reader settling the mixed-signer proof against the account
370
+ * document accepts it after the removal too -- `currentAccountRecordSigners`
371
+ * is that allowlist), and the forgotten client named as retiring. The sibling
372
+ * minter reads the annex pointer off the post-install document. The HTTP
373
+ * side rides the caller's management-zcap clients, still invocable here.
374
+ *
375
+ * @param options {object}
376
+ * @param options.doc {DIDDoc} the post-install account document
377
+ * @param options.accountDid {string}
378
+ * @param options.ladderSeed {Uint8Array}
379
+ * @param options.retiringSigningKeyMultibase {string} the forgotten
380
+ * client's signing key
381
+ * @param options.reach {UnlockMethodsRemintReach}
382
+ * @param options.now {number}
383
+ * @returns {Promise<object>} the pass's counts and per-entry outcomes
384
+ */
385
+ async function remintUnlockMethodRecordsAsLadder({ doc, accountDid, ladderSeed, retiringSigningKeyMultibase, reach, now }) {
386
+ const ladderClient = await ladderVmZcapClient({ accountDid, ladderSeed });
387
+ const recordSigner = recordSignerFromAgent({
388
+ keyAgent: await ladderVmAgent({ ladderSeed })
389
+ });
390
+ return remintRecoveryDelegations({
391
+ doc,
392
+ entries: reach.entries,
393
+ pointer: reach.pointer,
394
+ storageServerUrl: reach.storageServerUrl,
395
+ zcapClient: ladderClient,
396
+ recordSigner,
397
+ managementZcapClient: reach.managementZcapClient,
398
+ recordEntry: reach.recordEntry,
399
+ mintDelegatedClientsDelegation: delegatedClientsDelegationMinter({
400
+ doc,
401
+ zcapClient: ladderClient,
402
+ wasServerUrl: reach.pointer.host
403
+ }),
404
+ retiringKeyMultibases: [retiringSigningKeyMultibase],
405
+ now
406
+ });
407
+ }
408
+ //# sourceMappingURL=forgetLast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forgetLast.js","sourceRoot":"","sources":["../../src/clientAnnex/forgetLast.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
3
  */
4
4
  /**
5
- * Companion GC: the quarterly wholesale replacement of the companion
5
+ * Client-annex GC: the quarterly wholesale replacement of the annex
6
6
  * generation, and the collection of everything it leaves behind.
7
7
  *
8
8
  * The ceremony has two halves with different rhythms:
@@ -54,7 +54,7 @@ import type { DIDLog } from '@interop/did-method-webvh';
54
54
  import type { ZcapClient } from '@interop/ezcap';
55
55
  import type { WasClient } from '@interop/was-client';
56
56
  import type { ResourceLogPinStore } from '../resourceLog/pin.js';
57
- import type { ClientWebvhUpdateKeys, PublishedWebvhLog, WebvhIdStore } from './didWebvh.js';
57
+ import type { ClientWebvhUpdateKeys, PublishedWebvhLog, WebvhIdStore } from '../webvh/didWebvh.js';
58
58
  /**
59
59
  * The fixed GC cadence: a generation is replaced at the first durable login
60
60
  * 90 days after the current pointer value was established. Wallet GC policy
@@ -82,7 +82,7 @@ export declare const GENERATION_QUIET_GRACE_MS: number;
82
82
  /**
83
83
  * The `versionTime` of the account-log entry that established the CURRENT
84
84
  * `#DelegatedClients` pointer value: the newest entry whose state names a
85
- * different companion DID than the entry before it (or the first entry, when
85
+ * different annex DID than the entry before it (or the first entry, when
86
86
  * the pointer has been there since genesis). This is the cadence's clock --
87
87
  * "the pointer-update entry is the record" -- and it is read off the log a
88
88
  * durable login has already verified, so the cadence costs no extra fetch
@@ -106,7 +106,7 @@ export declare function delegatedClientsPointerEstablishedAt({ log }: {
106
106
  * @param [options.now] {number} epoch milliseconds, for tests
107
107
  * @returns {boolean}
108
108
  */
109
- export declare function companionGcDue({ log, now }: {
109
+ export declare function clientAnnexGcDue({ log, now }: {
110
110
  log: DIDLog;
111
111
  now?: number;
112
112
  }): boolean;
@@ -119,7 +119,7 @@ export declare function companionGcDue({ log, now }: {
119
119
  * swap defers rather than abandoning a possibly-live visit.
120
120
  *
121
121
  * @param options {object}
122
- * @param options.log {DIDLog} the pointed generation's VERIFIED companion
122
+ * @param options.log {DIDLog} the pointed generation's VERIFIED annex
123
123
  * log
124
124
  * @param [options.now] {number} epoch milliseconds, for tests
125
125
  * @returns {boolean}
@@ -131,23 +131,23 @@ export declare function generationQuiet({ log, now }: {
131
131
  /**
132
132
  * What the swap half of one GC pass did. `replaced` is the successful swap;
133
133
  * `not-due` and `deferred-live` are the two healthy skips (cadence and quiet
134
- * bound); `no-pointer` means the account has no companion posture (the whole
134
+ * bound); `no-pointer` means the account has no annex posture (the whole
135
135
  * pass no-ops -- without a pointer there is no auxiliary Space to list);
136
136
  * `no-ladder-seed` means the swap was due but the login held no ladder seed
137
137
  * to mint with (a non-standing record); `failed` means a swap stage threw --
138
138
  * reported in `failed` under the pointed generation's id, with the collect
139
139
  * fan-out still run.
140
140
  */
141
- export type CompanionGcSwapOutcome = 'replaced' | 'not-due' | 'deferred-live' | 'no-pointer' | 'no-ladder-seed' | 'failed';
141
+ export type ClientAnnexGcSwapOutcome = 'replaced' | 'not-due' | 'deferred-live' | 'no-pointer' | 'no-ladder-seed' | 'failed';
142
142
  /**
143
- * One GC pass's report: the swap outcome, the companion DID the account
143
+ * One GC pass's report: the swap outcome, the annex DID the account
144
144
  * points at after the pass, the generation ids collected (revoked, digested,
145
145
  * deleted), and the per-generation failures. A report with `failed` entries
146
146
  * is a resumable success -- the next durable login's pass picks up exactly
147
147
  * the generations still listed.
148
148
  */
149
- export interface CompanionGcReport {
150
- swap: CompanionGcSwapOutcome;
149
+ export interface ClientAnnexGcReport {
150
+ swap: ClientAnnexGcSwapOutcome;
151
151
  pointedDid?: string;
152
152
  collected: string[];
153
153
  failed: Array<{
@@ -156,7 +156,7 @@ export interface CompanionGcReport {
156
156
  }>;
157
157
  }
158
158
  /**
159
- * One companion GC pass: the quarterly swap when due and quiet, then the
159
+ * One annex GC pass: the quarterly swap when due and quiet, then the
160
160
  * predicate-driven collect fan-out over every non-pointed `gen-` collection.
161
161
  * See the module header for the stage order and its load-bearing constraints.
162
162
  *
@@ -190,14 +190,14 @@ export interface CompanionGcReport {
190
190
  * delete, and a throw keeps the generation for the next pass
191
191
  * @param [options.onCollected] {Function}
192
192
  * `({ generationId }) => Promise<void>` -- local cleanup after a
193
- * generation's delete (the caller's companion pin-slot drop); a throw is
193
+ * generation's delete (the caller's annex pin-slot drop); a throw is
194
194
  * reported but cannot be retried (the collection is already gone)
195
195
  * @param [options.pinStore] {ResourceLogPinStore} chain-head pins for the
196
196
  * account-log re-point and the pointed generation's read
197
197
  * @param [options.now] {number} epoch milliseconds, for tests
198
- * @returns {Promise<CompanionGcReport>}
198
+ * @returns {Promise<ClientAnnexGcReport>}
199
199
  */
200
- export declare function runCompanionGc({ was, wasServerUrl, accountSpaceId, account, idStore, updateKeys, zcapClient, ladderSeed, recordDigest, onCollected, pinStore, now }: {
200
+ export declare function runClientAnnexGc({ was, wasServerUrl, accountSpaceId, account, idStore, updateKeys, zcapClient, ladderSeed, recordDigest, onCollected, pinStore, now }: {
201
201
  was: WasClient;
202
202
  wasServerUrl: string;
203
203
  accountSpaceId: string;
@@ -217,5 +217,39 @@ export declare function runCompanionGc({ was, wasServerUrl, accountSpaceId, acco
217
217
  }) => Promise<void>;
218
218
  pinStore?: ResourceLogPinStore;
219
219
  now?: number;
220
- }): Promise<CompanionGcReport>;
221
- //# sourceMappingURL=companionGc.d.ts.map
220
+ }): Promise<ClientAnnexGcReport>;
221
+ /**
222
+ * AN OFF-CADENCE GENERATION SWAP: replaces the pointed annex generation
223
+ * outside the quarterly rhythm -- the credential-rotation ceremony's
224
+ * fallback when no distinct committed rung can sign a strike entry
225
+ * (`retireClientAnnexRung`): a fresh generation minted from a SURVIVING
226
+ * credential's seed commits only that credential's rung-0 hash, so the
227
+ * retired credential's annex posture dies with the whole generation the
228
+ * moment the re-point lands. The abandoned generation is an ordinary
229
+ * non-pointed `gen-` collection the standing collect fan-out picks up at the
230
+ * next durable login.
231
+ *
232
+ * Same four swap stages and ordering as the quarterly GC swap, minus the
233
+ * cadence and quiet gates (the caller's reason for swapping is authority
234
+ * removal, not hygiene). The pointed generation's log is read for the revoke
235
+ * stage's delegation bytes; unreadable, the revoke is skipped and pointer
236
+ * equality retires the old delegation on a conforming server.
237
+ *
238
+ * @param options {object} see {@link runClientAnnexGc} for the shared
239
+ * members ({ was, wasServerUrl, accountSpaceId, account, idStore,
240
+ * updateKeys, zcapClient, pinStore }); `ladderSeed` here is the SURVIVING
241
+ * credential's seed the fresh generation is minted from
242
+ * @returns {Promise<string>} the fresh annex DID
243
+ */
244
+ export declare function swapClientAnnexGeneration({ was, wasServerUrl, accountSpaceId, account, idStore, updateKeys, zcapClient, ladderSeed, pinStore }: {
245
+ was: WasClient;
246
+ wasServerUrl: string;
247
+ accountSpaceId: string;
248
+ account: Pick<PublishedWebvhLog, 'did' | 'doc'>;
249
+ idStore: WebvhIdStore;
250
+ updateKeys: ClientWebvhUpdateKeys;
251
+ zcapClient: ZcapClient;
252
+ ladderSeed: Uint8Array;
253
+ pinStore?: ResourceLogPinStore;
254
+ }): Promise<string>;
255
+ //# sourceMappingURL=gc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gc.d.ts","sourceRoot":"","sources":["../../src/clientAnnex/gc.ts"],"names":[],"mappings":"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"}