@run402/sdk 4.39.1 → 4.41.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 (48) hide show
  1. package/README.md +4 -4
  2. package/dist/errors.d.ts +5 -2
  3. package/dist/errors.d.ts.map +1 -1
  4. package/dist/errors.js.map +1 -1
  5. package/dist/namespaces/gitvault.crypto.d.ts +10 -0
  6. package/dist/namespaces/gitvault.crypto.d.ts.map +1 -1
  7. package/dist/namespaces/gitvault.crypto.js +10 -0
  8. package/dist/namespaces/gitvault.crypto.js.map +1 -1
  9. package/dist/namespaces/gitvault.d.ts +285 -5
  10. package/dist/namespaces/gitvault.d.ts.map +1 -1
  11. package/dist/namespaces/gitvault.js +369 -8
  12. package/dist/namespaces/gitvault.js.map +1 -1
  13. package/dist/node/gitvault-apply.d.ts +1 -1
  14. package/dist/node/gitvault-apply.d.ts.map +1 -1
  15. package/dist/node/gitvault-apply.js +6 -6
  16. package/dist/node/gitvault-apply.js.map +1 -1
  17. package/dist/node/gitvault-creation-journal.js +1 -1
  18. package/dist/node/gitvault-creation-journal.js.map +1 -1
  19. package/dist/node/gitvault-deploy.js +2 -2
  20. package/dist/node/gitvault-deploy.js.map +1 -1
  21. package/dist/node/gitvault-keystore.d.ts +11 -1
  22. package/dist/node/gitvault-keystore.d.ts.map +1 -1
  23. package/dist/node/gitvault-keystore.js.map +1 -1
  24. package/dist/node/gitvault-mirror-backend.d.ts +88 -0
  25. package/dist/node/gitvault-mirror-backend.d.ts.map +1 -0
  26. package/dist/node/gitvault-mirror-backend.js +374 -0
  27. package/dist/node/gitvault-mirror-backend.js.map +1 -0
  28. package/dist/node/gitvault-mirror-config.d.ts +53 -0
  29. package/dist/node/gitvault-mirror-config.d.ts.map +1 -0
  30. package/dist/node/gitvault-mirror-config.js +112 -0
  31. package/dist/node/gitvault-mirror-config.js.map +1 -0
  32. package/dist/node/gitvault-mirror.d.ts +120 -0
  33. package/dist/node/gitvault-mirror.d.ts.map +1 -0
  34. package/dist/node/gitvault-mirror.js +464 -0
  35. package/dist/node/gitvault-mirror.js.map +1 -0
  36. package/dist/node/gitvault-publication.d.ts +153 -3
  37. package/dist/node/gitvault-publication.d.ts.map +1 -1
  38. package/dist/node/gitvault-publication.js +182 -13
  39. package/dist/node/gitvault-publication.js.map +1 -1
  40. package/dist/node/gitvault-recover.d.ts +136 -0
  41. package/dist/node/gitvault-recover.d.ts.map +1 -0
  42. package/dist/node/gitvault-recover.js +412 -0
  43. package/dist/node/gitvault-recover.js.map +1 -0
  44. package/dist/node/gitvault-snapshot.d.ts +8 -0
  45. package/dist/node/gitvault-snapshot.d.ts.map +1 -1
  46. package/dist/node/gitvault-snapshot.js +11 -0
  47. package/dist/node/gitvault-snapshot.js.map +1 -1
  48. package/package.json +1 -1
@@ -0,0 +1,412 @@
1
+ /**
2
+ * gitvault-mirror-and-recover — `r402s-recover`, the offline recovery engine
3
+ * (design D4/D5, tasks 3.1–3.5).
4
+ *
5
+ * Turns a mirrored `source/<repo_id>/` prefix (any {@link GitvaultMirrorBackend}
6
+ * — S3 or a local directory) plus a pin (the keystore's recovery receipt, or
7
+ * one supplied explicitly) into a working git repository, with NO SERVER
8
+ * INVOLVED: everything here reads from the {@link GitvaultMirrorBackend}
9
+ * alone. Only the decrypt/materialize step touches key material (design D5)
10
+ * — discovery, chain verification, and closure/absence adjudication run
11
+ * keylessly and are a first-class outcome on their own (`run402 gitvault
12
+ * mirror verify`), not a degraded mode of the keyed path.
13
+ *
14
+ * Reuses the SAME pure protocol functions the live SDK verifies pushes with
15
+ * ({@link checkChainLink}, {@link assertNoTransition}, {@link
16
+ * checkClaimSetEquality}, {@link gitvaultPaths}) — this file adds no new
17
+ * protocol semantics, exactly per the design doc's "recovery is the keyed
18
+ * offline subset of machinery that already exists."
19
+ */
20
+ import { createHash } from "node:crypto";
21
+ import { mkdirSync } from "node:fs";
22
+ import { LocalError } from "../errors.js";
23
+ import { GITVAULT_GENESIS_EPOCH, GITVAULT_GENESIS_GENERATION, GITVAULT_MIRROR_KEYSTORE_STILL_REQUIRED_STATEMENT, GITVAULT_MIRROR_VALIDITY_NOT_FRESHNESS_STATEMENT, checkGenesisKeyBindings, checkRecoveryReceipt, deriveDigestKey, deriveObjectKey, generateEncryptionKeypair, hexToBytes, keyedCommitment, objectsetContent, openFrame, openKeyEnvelope, parseGitvaultStrict, verifyGitvaultObject, } from "../namespaces/gitvault.crypto.js";
24
+ import { assertNoTransition, checkChainLink, checkClaimSetEquality, gitvaultPaths, nextGeneration } from "./gitvault-publication.js";
25
+ import { GitvaultKeystore } from "./gitvault-keystore.js";
26
+ import { hardenedGit, hasObject } from "./gitvault-snapshot.js";
27
+ function fail(code, message, context, details, nextActions) {
28
+ throw new LocalError(message, context, { code, details, ...(nextActions ? { next_actions: nextActions } : {}) });
29
+ }
30
+ function sha256Hex(bytes) {
31
+ return createHash("sha256").update(bytes).digest("hex");
32
+ }
33
+ /**
34
+ * List `head/`, pin-check the genesis, and walk `prev_sha256` from genesis to
35
+ * the newest generation this mirror both HOLDS and can VERIFY. A signature or
36
+ * chain-link failure at generation K stops the walk at K-1 (`chain_break`
37
+ * names why); a generation simply absent from the mirror also stops the walk
38
+ * there, with `chain_break: null` (nothing further was ever pushed here, or
39
+ * hasn't been synced yet — not evidence of corruption).
40
+ *
41
+ * A PIN MISMATCH is the one hard, no-fallback refusal (`VAULT_CREATION_CONFLICT`):
42
+ * a substituted vault must never be silently accepted at "whatever chain
43
+ * verifies", because a substituted vault's own chain verifies perfectly
44
+ * against ITS OWN (different) creator key.
45
+ */
46
+ export async function discoverAndVerifyChain(options) {
47
+ const { backend } = options;
48
+ const genesisBytes = await backend.get(gitvaultPaths.head(GITVAULT_GENESIS_GENERATION));
49
+ if (!genesisBytes)
50
+ fail("CHAIN_BROKEN", "the mirror holds no genesis (head/0000000000000000) — nothing to recover", "discovering gitvault vault from mirror", { destination: backend.describe() });
51
+ const genesis = parseGitvaultStrict(new TextDecoder().decode(genesisBytes));
52
+ if (genesis.object_kind !== "vault_genesis")
53
+ fail("CHAIN_BROKEN", "head/0000000000000000 is not a vault_genesis object", "discovering gitvault vault from mirror");
54
+ if (!verifyGitvaultObject(genesis, genesis.creator_signing_pubkey)) {
55
+ fail("GITVAULT_SIGNATURE_INVALID", "vault_genesis signature does not verify under its own claimed creator key", "discovering gitvault vault from mirror", { repo_id: genesis.repo_id });
56
+ }
57
+ const genesisSha = sha256Hex(genesisBytes);
58
+ const receipt = options.recovery_receipt ?? options.keystore?.readRecoveryReceipt(genesis.repo_id) ?? null;
59
+ let pinTrust = "unauthenticated_salvage";
60
+ if (receipt) {
61
+ const problems = checkRecoveryReceipt(receipt, genesis);
62
+ if (problems.length > 0) {
63
+ fail("VAULT_CREATION_CONFLICT", `the recovery receipt does not pin this mirror's genesis (${problems.join(", ")}) — this mirror may hold a SUBSTITUTED vault; refusing to recover from it`, "discovering gitvault vault from mirror", { repo_id: genesis.repo_id, problems, expected_genesis_sha256: receipt.genesis_sha256, observed_genesis_sha256: genesisSha }, [{ action: "verify the mirror destination and pin are the ones you intend — do not retry with a different receipt to make this pass" }]);
64
+ }
65
+ pinTrust = "receipt";
66
+ }
67
+ const chain = [];
68
+ let prevHash = genesisSha;
69
+ let prevGen = GITVAULT_GENESIS_GENERATION;
70
+ let chainBreak = null;
71
+ for (;;) {
72
+ const nextGen = nextGeneration(prevGen);
73
+ const bytes = await backend.get(gitvaultPaths.head(nextGen));
74
+ if (!bytes)
75
+ break; // natural end — the mirror holds nothing further at this generation
76
+ let head;
77
+ try {
78
+ head = parseGitvaultStrict(new TextDecoder().decode(bytes));
79
+ checkChainLink({
80
+ head, stored_bytes: bytes, listed_sha256: sha256Hex(bytes), expected_generation: nextGen, prev_sha256: prevHash,
81
+ repo_id: genesis.repo_id, writer_public_key: genesis.creator_signing_pubkey, writer_key_id: genesis.writer_key_id,
82
+ });
83
+ assertNoTransition(head);
84
+ }
85
+ catch (e) {
86
+ chainBreak = { generation: nextGen, reason: e instanceof Error ? e.message : String(e) };
87
+ break;
88
+ }
89
+ const headSha = sha256Hex(bytes);
90
+ chain.push({ generation: nextGen, head, head_sha256: headSha });
91
+ prevHash = headSha;
92
+ prevGen = nextGen;
93
+ }
94
+ return {
95
+ repo_id: genesis.repo_id, genesis, genesis_sha256: genesisSha, pin_trust: pinTrust, chain,
96
+ newest_generation: prevGen, newest_head_sha256: prevHash, chain_break: chainBreak,
97
+ };
98
+ }
99
+ /**
100
+ * The required object set for one generation, resolved KEYLESSLY:
101
+ * `checkpoint_claim_set` is plaintext-structured (never encrypted, protocol
102
+ * §4.7) precisely so ITS ordered pack receipts enumerate every checkpoint
103
+ * pack + manifest id without decryption — closure resolution never needs a
104
+ * key. Walks back from `head` to the nearest checkpoint-bearing ancestor (or
105
+ * genesis) collecting each head's own carriers + WAL entries along the way.
106
+ */
107
+ export async function closureForGeneration(backend, chain, targetGeneration) {
108
+ const byGen = new Map(chain.map((e) => [e.generation, e]));
109
+ const out = [];
110
+ let gen = targetGeneration;
111
+ for (;;) {
112
+ if (gen === GITVAULT_GENESIS_GENERATION)
113
+ break;
114
+ const entry = byGen.get(gen);
115
+ if (!entry)
116
+ fail("CHAIN_BROKEN", `generation ${gen} is not in the verified chain`, "resolving gitvault recovery closure", { generation: gen });
117
+ out.push({ key: gitvaultPaths.refState(entry.head.ref_state.object_id), object_id: entry.head.ref_state.object_id, kind: "ref_state" });
118
+ out.push({ key: gitvaultPaths.retentionRoots(entry.head.retention_roots.object_id), object_id: entry.head.retention_roots.object_id, kind: "retention_roots" });
119
+ if (entry.head.checkpoint) {
120
+ const claimSetId = entry.head.checkpoint.claim_set.object_id;
121
+ out.push({ key: gitvaultPaths.claimSet(claimSetId), object_id: claimSetId, kind: "checkpoint_claim_set" });
122
+ // The claim set's OWN content (plaintext-structured — no decryption)
123
+ // enumerates the manifest + every pack. Missing claim-set bytes stop
124
+ // enumeration here; the caller's adjudication loop reports it, and
125
+ // enumeration simply cannot go further without it (honest, not silent).
126
+ const claimBytes = await backend.get(gitvaultPaths.claimSet(claimSetId));
127
+ if (claimBytes) {
128
+ const claimSet = parseGitvaultStrict(new TextDecoder().decode(claimBytes));
129
+ out.push({ key: gitvaultPaths.checkpointManifest(claimSet.manifest_receipt.object_id), object_id: claimSet.manifest_receipt.object_id, kind: "checkpoint_manifest" });
130
+ for (const p of claimSet.ordered_pack_receipts)
131
+ out.push({ key: gitvaultPaths.checkpointPack(p.object_id), object_id: p.object_id, kind: "checkpoint_pack" });
132
+ }
133
+ break; // the checkpoint's recovery bundle is self-contained; no earlier WAL is needed
134
+ }
135
+ for (const w of entry.head.wal_entries)
136
+ out.push({ key: gitvaultPaths.wal(w.object_id), object_id: w.object_id, kind: "wal_pack" });
137
+ gen = generationMinusOne(gen);
138
+ }
139
+ return out;
140
+ }
141
+ function generationMinusOne(generation) {
142
+ return (BigInt(`0x${generation}`) - 1n).toString(16).padStart(16, "0");
143
+ }
144
+ /**
145
+ * Check presence of every required object; for each ABSENT one, check the
146
+ * mirror's OWN stored `prune_intent` objects (plaintext-structured, keyless)
147
+ * for a delete-set entry naming it. Never a silent skip: every absence is
148
+ * adjudicated one way or the other, and the caller decides what to do with an
149
+ * `unexplained_absence` (typically: fall back one generation, see {@link
150
+ * recoverWithFallback}).
151
+ */
152
+ export async function adjudicateAbsences(backend, required) {
153
+ const missing = [];
154
+ for (const r of required) {
155
+ const meta = await backend.head(r.key);
156
+ if (!meta)
157
+ missing.push(r);
158
+ }
159
+ if (missing.length === 0)
160
+ return [];
161
+ const pruneKeys = (await backend.list("prune/")).filter((k) => k.endsWith(".intent.json"));
162
+ const intents = [];
163
+ for (const key of pruneKeys) {
164
+ const bytes = await backend.get(key);
165
+ if (!bytes)
166
+ continue;
167
+ try {
168
+ const intent = parseGitvaultStrict(new TextDecoder().decode(bytes));
169
+ intents.push({ object_id: intent.object_id, delete_set: new Set((intent.core?.delete_set ?? []).map((d) => d.object_id)) });
170
+ }
171
+ catch {
172
+ /* an unreadable prune intent adjudicates nothing; the missing object stays unexplained */
173
+ }
174
+ }
175
+ return missing.map((m) => {
176
+ const covering = intents.find((i) => i.delete_set.has(m.object_id));
177
+ return {
178
+ object_id: m.object_id, key: m.key,
179
+ adjudication: covering ? "intentionally_pruned" : "unexplained_absence",
180
+ prune_intent_object_id: covering?.object_id ?? null,
181
+ };
182
+ });
183
+ }
184
+ /**
185
+ * Discovery + chain verification + closure/absence adjudication, WITHOUT
186
+ * touching any key material — `run402 gitvault mirror verify`. Reports the
187
+ * recoverable generation and an inventory; never decrypts, never
188
+ * materializes. A genuinely keyless integrity probe (design D5) — useful as a
189
+ * CI check that never needs a secret.
190
+ */
191
+ export async function verifyGitvaultMirror(backend, options = {}) {
192
+ const discovery = await discoverAndVerifyChain({ backend, ...options });
193
+ const { generation, absences } = await resolveWithFallback(backend, discovery, { requireMaterializable: false });
194
+ const inventory = {};
195
+ if (generation !== GITVAULT_GENESIS_GENERATION) {
196
+ const required = await closureForGeneration(backend, discovery.chain, generation);
197
+ for (const r of required)
198
+ inventory[r.kind] = (inventory[r.kind] ?? 0) + 1;
199
+ }
200
+ return {
201
+ repo_id: discovery.repo_id, genesis_sha256: discovery.genesis_sha256, pin_trust: discovery.pin_trust,
202
+ recovered_generation: generation, chain_break: discovery.chain_break, absences,
203
+ data_loss_detected: absences.some((a) => a.adjudication === "unexplained_absence"),
204
+ validity_not_freshness: GITVAULT_MIRROR_VALIDITY_NOT_FRESHNESS_STATEMENT,
205
+ keystore_still_required: GITVAULT_MIRROR_KEYSTORE_STILL_REQUIRED_STATEMENT,
206
+ mode: "keyless_verify", inventory,
207
+ };
208
+ }
209
+ /** Try `discovery.newest_generation`, then fall back one generation at a time on `unexplained_absence`, recording every adjudication along the way (never a silent skip — task 3.2). */
210
+ async function resolveWithFallback(backend, discovery, options) {
211
+ const allAbsences = [];
212
+ let gen = discovery.newest_generation;
213
+ for (;;) {
214
+ if (gen === GITVAULT_GENESIS_GENERATION)
215
+ return { generation: gen, absences: allAbsences };
216
+ const required = await closureForGeneration(backend, discovery.chain, gen);
217
+ const absences = await adjudicateAbsences(backend, required);
218
+ allAbsences.push(...absences);
219
+ const unexplained = absences.filter((a) => a.adjudication === "unexplained_absence");
220
+ if (unexplained.length === 0)
221
+ return { generation: gen, absences: allAbsences };
222
+ if (!options.requireMaterializable) {
223
+ // Keyless verify still names the generation it landed on as the OLDEST
224
+ // one with no unexplained gap, same fallback the keyed path takes.
225
+ gen = generationMinusOne(gen);
226
+ continue;
227
+ }
228
+ gen = generationMinusOne(gen);
229
+ }
230
+ }
231
+ /** Open the recipient's key envelope for this genesis and decrypt K_repo — the ONE step in this whole file that touches key material. */
232
+ async function resolveKRepo(backend, genesis, keystore) {
233
+ const identity = keystore.readIdentity();
234
+ if (!identity?.encryption_private_key_hex) {
235
+ fail("VAULT_UNRECOVERABLE", "no encryption key in this keystore — recovery can verify and adjudicate but cannot decrypt or materialize anything", "materializing gitvault recovery", undefined, [
236
+ { action: "restore the principal keystore (identity.json) from backup, then re-run recover" },
237
+ { action: "run with --keyless (or `mirror verify`) for the verify-only outcome" },
238
+ ]);
239
+ }
240
+ if (genesis.envelopes.length === 0)
241
+ fail("VAULT_CREATION_CONFLICT", "genesis carries no key envelope", "materializing gitvault recovery");
242
+ // Task 5.3 follow-up (gateway diagnosis confirmed 2026-08-26: a real vault
243
+ // can carry MORE than one key_envelope ledger row — a foreign recipient's
244
+ // envelope is the norm on a multi-recipient vault, never an anomaly). A
245
+ // genesis's own `envelopes[]` has always had exactly one entry so far (the
246
+ // creator's, minted at the six-stage creation — later reconcile-added
247
+ // envelopes are separate ledger rows, never appended to the SIGNED
248
+ // genesis), which is why blindly reading index 0 happened to be correct.
249
+ // SELECT BY FINGERPRINT EXPLICITLY instead of by position: this machine
250
+ // can only ever decrypt ITS OWN envelope (the recipient-only read gate
251
+ // means the mirror never even holds anyone else's — see
252
+ // `keyEnvelopeRecipientFingerprintFromKey`/`skipped_foreign_recipient` in
253
+ // `gitvault-mirror.ts`), so this function never looks for, and never fails
254
+ // on, a FOREIGN envelope being absent — that is silent-OK. A missing OWN
255
+ // envelope in genesis.envelopes (no entry matches our fingerprint at all)
256
+ // is its own distinct, honest refusal, separate from "the mirror never
257
+ // synced the bytes for an envelope genesis DOES name for us" below.
258
+ const envelopeReceipt = genesis.envelopes.find((e) => e.recipient_fingerprint === identity.encryption_fingerprint);
259
+ if (!envelopeReceipt) {
260
+ fail("GITVAULT_ENVELOPE_NOT_FOR_RECIPIENT", "genesis carries no key envelope for this machine's identity — this keystore is not a recipient of this vault", "materializing gitvault recovery", { own_fingerprint: identity.encryption_fingerprint });
261
+ }
262
+ // `key-envelopes/<epoch>/<recipient_fingerprint>.env` — the GATEWAY's real
263
+ // §3 wire key (`upload-sessions.ts` `UPLOADABLE_KINDS.key_envelope.key()`,
264
+ // mirrored by `storage-keys.ts` `objectKeyFor`), matching protocol §3
265
+ // exactly. The SDK's OWN `gitvault-creation-journal.ts` envelope `path`
266
+ // string (`envelopes/<epoch>/<fp>`) is a DIFFERENT, client-local label used
267
+ // only for the upload manifest ("never rides the wire") — the gateway
268
+ // derives its own key independently and never echoes that string back, so
269
+ // a mirror synced from the real objects listing never contains it.
270
+ const envelopeBytes = await backend.get(`key-envelopes/${envelopeReceipt.epoch}/${envelopeReceipt.recipient_fingerprint}.env`);
271
+ if (!envelopeBytes)
272
+ fail("VAULT_UNRECOVERABLE", "the mirror holds no key envelope for this genesis — cannot derive K_repo", "materializing gitvault recovery");
273
+ const envelope = parseGitvaultStrict(new TextDecoder().decode(envelopeBytes));
274
+ const bindingProblems = checkGenesisKeyBindings(genesis, envelope);
275
+ if (bindingProblems.length > 0)
276
+ fail("VAULT_CREATION_CONFLICT", `genesis key bindings do not hold for the stored envelope (${bindingProblems.join(", ")})`, "materializing gitvault recovery", { problems: bindingProblems });
277
+ if (envelope.recipient_fingerprint !== identity.encryption_fingerprint) {
278
+ fail("GITVAULT_ENVELOPE_NOT_FOR_RECIPIENT", "the stored envelope is addressed to another principal — this keystore cannot open it", "materializing gitvault recovery", { recipient_fingerprint: envelope.recipient_fingerprint });
279
+ }
280
+ const kp = generateEncryptionKeypair(hexToBytes(identity.encryption_private_key_hex));
281
+ return openKeyEnvelope({ envelope, recipient: kp, signer_public_key: genesis.creator_signing_pubkey });
282
+ }
283
+ async function openCarrier(backend, kRepo, repoId, kind, objectId, ciphertextSha256, key) {
284
+ const frame = await backend.get(key);
285
+ if (!frame)
286
+ fail("CHAIN_UNUSABLE", `${kind} ${objectId} is absent from the mirror`, "materializing gitvault recovery", { object_id: objectId });
287
+ const plaintext = openFrame({ k_obj: deriveObjectKey(kRepo, repoId, GITVAULT_GENESIS_EPOCH, kind, objectId), repo_id: repoId, object_kind: kind, object_id: objectId, epoch: GITVAULT_GENESIS_EPOCH, frame, expected_ciphertext_sha256: ciphertextSha256 });
288
+ return parseGitvaultStrict(new TextDecoder().decode(plaintext));
289
+ }
290
+ /**
291
+ * Materialize the resolved generation into `out_dir` and run §4.7 restorer
292
+ * acceptance: scratch restore, every covered ref at its EXACT oid, `git fsck`
293
+ * full connectivity, recompute the three keyed commitments against the
294
+ * checkpoint manifest when one covers this generation. Acceptance failure is
295
+ * a typed non-zero exit (throws) — never a partial, silently-accepted repo.
296
+ */
297
+ export async function recoverGitvaultMirror(options) {
298
+ // Task 5.3 follow-up (found via the live drill 2026-08-26): `out_dir` is
299
+ // "where to materialize the recovered repository" — the CLI's own
300
+ // documented example (`--out ./restored`) is a path that naturally does
301
+ // NOT already exist, same expectation as `git clone <url> restored-dir`.
302
+ // Every unit test happened to pass an already-`mkdtempSync`'d directory,
303
+ // which is exactly why nothing ever created it here. Create it FIRST,
304
+ // before any discovery/decrypt work, so a bad `out_dir` fails fast with a
305
+ // truthful, typed error instead of the misleading `GIT_UNAVAILABLE` the
306
+ // first `hardenedGit` call used to throw (see that function's own
307
+ // `GIT_CWD_MISSING` disambiguation in `gitvault-snapshot.ts` — this is the
308
+ // belt; that is the suspenders).
309
+ try {
310
+ mkdirSync(options.out_dir, { recursive: true });
311
+ }
312
+ catch (e) {
313
+ fail("GITVAULT_RECOVER_OUT_DIR_UNWRITABLE", `could not create the recovery output directory: ${options.out_dir}`, "materializing gitvault recovery", { out_dir: options.out_dir, cause: e instanceof Error ? e.message : String(e) });
314
+ }
315
+ const { backend } = options;
316
+ const keystore = options.keystore ?? GitvaultKeystore.open();
317
+ const discovery = await discoverAndVerifyChain({ backend, ...(options.recovery_receipt ? { recovery_receipt: options.recovery_receipt } : {}), keystore });
318
+ const { generation, absences } = await resolveWithFallback(backend, discovery, { requireMaterializable: true });
319
+ if (generation === GITVAULT_GENESIS_GENERATION) {
320
+ fail("CHECKPOINT_INCOMPLETE", "no generation could be fully materialized — every generation back to genesis has an unexplained missing object", "materializing gitvault recovery", { absences });
321
+ }
322
+ const kRepo = await resolveKRepo(backend, discovery.genesis, keystore);
323
+ const entry = discovery.chain.find((e) => e.generation === generation);
324
+ const repoId = discovery.repo_id;
325
+ const refState = await openCarrier(backend, kRepo, repoId, "ref_state", entry.head.ref_state.object_id, entry.head.ref_state.ciphertext_sha256, gitvaultPaths.refState(entry.head.ref_state.object_id));
326
+ const roots = await openCarrier(backend, kRepo, repoId, "retention_roots", entry.head.retention_roots.object_id, entry.head.retention_roots.ciphertext_sha256, gitvaultPaths.retentionRoots(entry.head.retention_roots.object_id));
327
+ // ── restore into scratch: newest checkpoint's packs, then every later WAL pack ──
328
+ const chainUpTo = discovery.chain.filter((e) => e.generation <= generation);
329
+ const heads = [];
330
+ for (let i = chainUpTo.length - 1; i >= 0; i--) {
331
+ heads.unshift(chainUpTo[i]);
332
+ if (chainUpTo[i].head.checkpoint)
333
+ break;
334
+ }
335
+ await hardenedGit(options.out_dir, ["init", "-q", "--bare", "--object-format=sha1", "."]);
336
+ let manifest = null;
337
+ const first = heads[0];
338
+ if (first.head.checkpoint) {
339
+ const claimBytes = await backend.get(gitvaultPaths.claimSet(first.head.checkpoint.claim_set.object_id));
340
+ if (!claimBytes)
341
+ fail("CHECKPOINT_INCOMPLETE", "checkpoint claim set absent from the mirror", "materializing gitvault recovery");
342
+ const claimSet = parseGitvaultStrict(new TextDecoder().decode(claimBytes));
343
+ if (!verifyGitvaultObject(claimSet, discovery.genesis.creator_signing_pubkey))
344
+ fail("CHECKPOINT_INCOMPLETE", "checkpoint claim set signature fails", "materializing gitvault recovery");
345
+ manifest = await openCarrier(backend, kRepo, repoId, "checkpoint_manifest", claimSet.manifest_receipt.object_id, claimSet.manifest_receipt.ciphertext_sha256, gitvaultPaths.checkpointManifest(claimSet.manifest_receipt.object_id));
346
+ checkClaimSetEquality(claimSet, manifest, first.head.checkpoint.covers_through_generation);
347
+ for (const p of manifest.packs) {
348
+ const frame = await backend.get(gitvaultPaths.checkpointPack(p.object_id));
349
+ if (!frame)
350
+ fail("CHECKPOINT_INCOMPLETE", `checkpoint pack ${p.object_id} absent`, "materializing gitvault recovery");
351
+ const plain = openFrame({ k_obj: deriveObjectKey(kRepo, repoId, GITVAULT_GENESIS_EPOCH, "checkpoint_pack", p.object_id), repo_id: repoId, object_kind: "checkpoint_pack", object_id: p.object_id, epoch: GITVAULT_GENESIS_EPOCH, frame, expected_ciphertext_sha256: p.ciphertext_sha256 });
352
+ if (sha256Hex(plain) !== p.plaintext_sha256 || String(plain.length) !== p.plaintext_size_bytes)
353
+ fail("CHECKPOINT_INCOMPLETE", `checkpoint pack ${p.object_id} plaintext mismatch`, "materializing gitvault recovery");
354
+ await hardenedGit(options.out_dir, ["index-pack", "--stdin", "--strict"], { input: plain });
355
+ }
356
+ }
357
+ for (const h of heads) {
358
+ for (const w of h.head.wal_entries) {
359
+ const frame = await backend.get(gitvaultPaths.wal(w.object_id));
360
+ if (!frame)
361
+ fail("CHAIN_UNUSABLE", `WAL pack ${w.object_id} absent`, "materializing gitvault recovery", { object_id: w.object_id });
362
+ const plain = openFrame({ k_obj: deriveObjectKey(kRepo, repoId, GITVAULT_GENESIS_EPOCH, "wal_pack", w.object_id), repo_id: repoId, object_kind: "wal_pack", object_id: w.object_id, epoch: GITVAULT_GENESIS_EPOCH, frame, expected_ciphertext_sha256: w.ciphertext_sha256 });
363
+ await hardenedGit(options.out_dir, ["index-pack", "--stdin", "--strict"], { input: plain });
364
+ }
365
+ }
366
+ // ── every covered ref at its EXACT oid + HEAD (task 3.4) ──
367
+ const coverageTips = new Set(Object.values(refState.refs));
368
+ for (const r of roots.roots)
369
+ coverageTips.add(r.oid);
370
+ if (refState.head_target.kind === "detached")
371
+ coverageTips.add(refState.head_target.oid);
372
+ for (const tip of coverageTips) {
373
+ if (!(await hasObject(options.out_dir, tip)))
374
+ fail("CHAIN_UNUSABLE", `covered tip ${tip} does not resolve after restore`, "materializing gitvault recovery", { oid: tip });
375
+ }
376
+ for (const [ref, oid] of Object.entries(refState.refs)) {
377
+ await hardenedGit(options.out_dir, ["update-ref", ref, oid]);
378
+ }
379
+ if (refState.head_target.kind === "symref")
380
+ await hardenedGit(options.out_dir, ["symbolic-ref", "HEAD", refState.head_target.ref]);
381
+ else
382
+ await hardenedGit(options.out_dir, ["update-ref", "--no-deref", "HEAD", refState.head_target.oid]);
383
+ // ── git fsck --no-dangling, full connectivity (task 3.4) ──
384
+ const fsck = await hardenedGit(options.out_dir, ["fsck", "--no-dangling", "--full", "--strict"], { okStatuses: [1, 2] });
385
+ if (fsck.status !== 0)
386
+ fail("CHECKPOINT_INCOMPLETE", `fsck reports missing connectivity after restore: ${fsck.stderr.slice(0, 500)}`, "materializing gitvault recovery");
387
+ // ── recompute the three keyed commitments against the covering manifest (§4.7) ──
388
+ if (manifest) {
389
+ const kDigestRefmap = deriveDigestKey(kRepo, repoId, GITVAULT_GENESIS_EPOCH, "refmap");
390
+ const kDigestRootset = deriveDigestKey(kRepo, repoId, GITVAULT_GENESIS_EPOCH, "rootset");
391
+ const kDigestObjectset = deriveDigestKey(kRepo, repoId, GITVAULT_GENESIS_EPOCH, "objectset");
392
+ const { signature: _s1, ...refStateContent } = refState;
393
+ const { signature: _s2, ...rootsContent } = roots;
394
+ const refmapOk = keyedCommitment(kDigestRefmap, refStateContent) === manifest.ref_state_hmac;
395
+ const rootsetOk = keyedCommitment(kDigestRootset, rootsContent) === manifest.retention_roots_hmac;
396
+ const sortedTips = [...coverageTips].sort();
397
+ const restoredOids = sortedTips.length === 0 ? [] : (await hardenedGit(options.out_dir, ["rev-list", "--objects", "--no-object-names", ...sortedTips])).lines().map((l) => l.trim());
398
+ const objectsetOk = keyedCommitment(kDigestObjectset, objectsetContent(restoredOids)) === manifest.object_set_hmac;
399
+ if (!refmapOk || !rootsetOk || !objectsetOk) {
400
+ fail("CHECKPOINT_INCOMPLETE", `restored state does not match the checkpoint's keyed commitments (refmap ${refmapOk ? "ok" : "MISMATCH"}, rootset ${rootsetOk ? "ok" : "MISMATCH"}, objectset ${objectsetOk ? "ok" : "MISMATCH"})`, "materializing gitvault recovery", { refmapOk, rootsetOk, objectsetOk });
401
+ }
402
+ }
403
+ return {
404
+ repo_id: repoId, genesis_sha256: discovery.genesis_sha256, pin_trust: discovery.pin_trust,
405
+ recovered_generation: generation, chain_break: discovery.chain_break, absences,
406
+ data_loss_detected: absences.some((a) => a.adjudication === "unexplained_absence"),
407
+ validity_not_freshness: GITVAULT_MIRROR_VALIDITY_NOT_FRESHNESS_STATEMENT,
408
+ keystore_still_required: GITVAULT_MIRROR_KEYSTORE_STILL_REQUIRED_STATEMENT,
409
+ mode: "recovered", out_dir: options.out_dir, refs: refState.refs, head_target: refState.head_target,
410
+ };
411
+ }
412
+ //# sourceMappingURL=gitvault-recover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitvault-recover.js","sourceRoot":"","sources":["../../src/node/gitvault-recover.ts"],"names":[],"mappings":"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"}
@@ -71,6 +71,14 @@ export declare const HARDENED_GIT_ARGV_PREFIX: () => string[];
71
71
  /**
72
72
  * Run git with explicit args (no shell) in `cwd` under the hardened env.
73
73
  * Throws `GIT_COMMAND_FAILED` on a non-ok exit.
74
+ *
75
+ * Task 5.3 follow-up (found via the live drill 2026-08-26): Node's
76
+ * `execFile` reports a MISSING `cwd` with the exact same `ENOENT` as a
77
+ * missing `git` binary, so a caller that forgot to create its working
78
+ * directory (e.g. `recover`'s `out_dir` before this fix) saw the misleading
79
+ * `GIT_UNAVAILABLE: git could not be executed` even though git itself was
80
+ * perfectly installed. Disambiguate BEFORE spawning: a missing `cwd` is its
81
+ * own distinct, honest refusal, never folded into "git is unavailable."
74
82
  */
75
83
  export declare function hardenedGit(cwd: string, args: string[], options?: HardenedGitOptions): Promise<HardenedGitResult>;
76
84
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"gitvault-snapshot.d.ts","sourceRoot":"","sources":["../../src/node/gitvault-snapshot.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gitvault-snapshot.d.ts","sourceRoot":"","sources":["../../src/node/gitvault-snapshot.ts"],"names":[],"mappings":"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"}
@@ -96,8 +96,19 @@ export const HARDENED_GIT_ARGV_PREFIX = () => [
96
96
  /**
97
97
  * Run git with explicit args (no shell) in `cwd` under the hardened env.
98
98
  * Throws `GIT_COMMAND_FAILED` on a non-ok exit.
99
+ *
100
+ * Task 5.3 follow-up (found via the live drill 2026-08-26): Node's
101
+ * `execFile` reports a MISSING `cwd` with the exact same `ENOENT` as a
102
+ * missing `git` binary, so a caller that forgot to create its working
103
+ * directory (e.g. `recover`'s `out_dir` before this fix) saw the misleading
104
+ * `GIT_UNAVAILABLE: git could not be executed` even though git itself was
105
+ * perfectly installed. Disambiguate BEFORE spawning: a missing `cwd` is its
106
+ * own distinct, honest refusal, never folded into "git is unavailable."
99
107
  */
100
108
  export function hardenedGit(cwd, args, options = {}) {
109
+ if (!existsSync(cwd)) {
110
+ return Promise.reject(new LocalError(`git working directory does not exist: ${cwd}`, "running hardened git", { code: "GIT_CWD_MISSING", details: { cwd, args } }));
111
+ }
101
112
  const argv = [...HARDENED_GIT_ARGV_PREFIX(), ...args];
102
113
  return new Promise((resolvePromise, reject) => {
103
114
  const child = execFile("git", argv, { cwd, env: hardenedGitEnv(options.env), encoding: "buffer", maxBuffer: options.maxBuffer ?? 1024 * 1024 * 1024, windowsHide: true }, (error, stdout, stderr) => {