@sema-agent/core
Version:
Stateless, task-oriented AI agent core
1,245 lines • 63.7 kB
JavaScript
import { createHash, randomBytes } from "node:crypto";
import { appendFileSync, closeSync, existsSync, fsyncSync, openSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { thrownText } from "../../core/thrown-value.js";
import { applyFileRestoreViaEnv, boundaryPublishVerdict, worldStillMatchesMint, captureFileBackupViaEnv, modeProvenDifferent, previewFileDelta, describeTrackKey, fileHistoryExportDigest, resolveTrackKey, trackKeyOf, validateFileHistoryExport, } from "../../core/file-history-store.js";
import { fileHistoryBoundariesToKeep, resolveFileHistoryRetention } from "../../core/file-history-retention.js";
import { atomicWriteFile, ensureDir, sanitizePathComponent, sanitizeScope, writeThenLink } from "./fs-atomic.js";
import { guardCorruptSink } from "./corrupt-read-sink.js";
import { isAbsoluteForFamily } from "../../tools/fs/safety.js";
import { assertAdoptionBootGate } from "./adoption/marker.js";
function trackedDigest(rows) {
const canonical = [...rows]
.sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))
.map(([key, rec]) => [
key,
{
baseAvailable: rec.baseAvailable,
mintId: rec.mintId ?? null,
keyKind: rec.keyKind ?? null,
keyFamily: rec.keyFamily ?? null,
observedByLaterTouch: rec.observedByLaterTouch === true,
versions: [...rec.versions]
.sort((x, y) => x.version - y.version)
.map((v) => ({ version: v.version, blobHash: v.blobHash, mode: v.mode ?? null, parentIdent: v.parentIdent ?? null, backupTime: v.backupTime })),
},
]);
return createHash("sha256").update(JSON.stringify(canonical)).digest("hex");
}
function boundaryDigest(files) {
const canonical = [...files].sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));
return createHash("sha256").update(JSON.stringify(canonical)).digest("hex");
}
const EMPTY_LEDGER = () => ({
filesChanged: [],
identicalSkipped: [],
refused: [],
failed: [],
});
const WINDOWS_DEVICE_NAMES = new Set(["con", "prn", "aux", "nul", ...Array.from({ length: 10 }, (_, i) => `com${i}`), ...Array.from({ length: 10 }, (_, i) => `lpt${i}`)]);
function historyPathComponent(raw) {
const safe = sanitizePathComponent(raw);
if (safe.length > 200)
throw new Error(`file history: path component is too long (${safe.length} > 200): ${JSON.stringify(raw.slice(0, 32))}…`);
if (WINDOWS_DEVICE_NAMES.has(safe.split(".")[0].toLowerCase()))
throw new Error(`file history: ${JSON.stringify(safe)} is a reserved device name — it would address a device, not a record`);
if (!/^[A-Za-z0-9_]/.test(safe))
throw new Error(`file history: path component must start with a letter, digit or underscore: ${JSON.stringify(safe)}`);
return safe;
}
function descriptorOf(rec) {
return rec.keyKind !== undefined && rec.keyFamily !== undefined ? { kind: rec.keyKind, family: rec.keyFamily } : undefined;
}
const STALE_JOURNAL_MS = 60 * 60 * 1000;
function pidIsAlive(pid) {
if (!Number.isInteger(pid) || pid <= 0)
return false;
try {
process.kill(pid, 0);
return true;
}
catch (err) {
return err.code === "EPERM";
}
}
function parseJsonRecord(raw) {
let parsed;
try {
parsed = JSON.parse(raw);
}
catch {
return null;
}
return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : null;
}
function leaseJournalBlob(line, live) {
const rec = parseJsonRecord(line);
if (rec !== null && typeof rec.blob === "string")
live.add(rec.blob);
}
function isTrackedPair(el) {
if (!Array.isArray(el) || el.length !== 2 || typeof el[0] !== "string")
return false;
const rec = el[1];
if (typeof rec !== "object" || rec === null || Array.isArray(rec))
return false;
const versions = rec.versions;
return Array.isArray(versions) && versions.every((v) => typeof v === "object" && v !== null && !Array.isArray(v));
}
function trackedRowsOf(parsed) {
if (parsed === null || !Array.isArray(parsed.tracked))
return null;
const rows = [];
for (const el of parsed.tracked) {
if (!isTrackedPair(el))
return null;
rows.push(el);
}
return rows;
}
function nestedSetAdd(map, scope, value) {
let inner = map.get(scope);
if (inner === undefined)
map.set(scope, (inner = new Set()));
inner.add(value);
}
function nestedMapSet(map, scope, key, value) {
let inner = map.get(scope);
if (inner === undefined)
map.set(scope, (inner = new Map()));
inner.set(key, value);
}
function safeRm(path) {
try {
rmSync(path, { force: true, recursive: true });
return true;
}
catch {
return false;
}
}
export class FileFileHistoryStore {
base;
blobsDir;
scopesDir;
onCorruptRead;
spentAttempts = new Map();
activeCaptures = new Map();
activeImports = new Map();
reapedCache = new Map();
boundaryKeep;
lastCommittedAt = 0;
seededScopes = new Set();
nextCommittedAt(scope) {
if (!this.seededScopes.has(scope)) {
this.seededScopes.add(scope);
const dir = this.boundaryDir(scope);
try {
for (const f of readdirSync(dir)) {
if (!f.endsWith(".json"))
continue;
const order = this.boundaryOrderOf(join(dir, f));
if (order !== undefined && order > this.lastCommittedAt)
this.lastCommittedAt = order;
}
}
catch {
}
}
this.lastCommittedAt = Math.max(Date.now(), this.lastCommittedAt + 1);
return this.lastCommittedAt;
}
constructor(root, opts) {
assertAdoptionBootGate(root, "FileFileHistoryStore");
this.boundaryKeep = resolveFileHistoryRetention("FileFileHistoryStore", opts?.retention);
this.base = join(root, "file-history");
this.blobsDir = join(this.base, "blobs");
this.scopesDir = join(this.base, "scopes");
ensureDir(this.blobsDir);
ensureDir(this.scopesDir);
this.onCorruptRead = guardCorruptSink(opts?.onCorruptRead);
}
applyBoundaryRetention(scope, justCommitted) {
if (this.boundaryKeep === null)
return;
try {
const dir = this.boundaryDir(scope);
let names;
try {
names = readdirSync(dir).filter((f) => f.endsWith(".json"));
}
catch (err) {
if (err.code !== "ENOENT") {
this.disclose(dir, `boundary directory unreadable (${err.code ?? "unknown"}) — the retention pass was skipped, so this scope is NOT bounded until it can be read`);
}
return;
}
if (names.length <= this.boundaryKeep)
return;
const readable = [];
for (const f of names) {
const path = join(dir, f);
if (this.readBoundary(path) === null) {
this.disclose(join(dir, f), "a boundary in this scope cannot be judged — the retention pass is disabled for the WHOLE scope until it is repaired or removed, so this scope is NOT bounded (trimming around a record whose references cannot be read destroys the versions only it points at)");
return;
}
readable.push({ id: f.slice(0, -".json".length), order: this.boundaryOrderOf(path) ?? 0 });
}
const ordered = readable.sort((a, b) => a.order - b.order || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)).map((e) => e.id);
const keepIds = fileHistoryBoundariesToKeep(ordered, justCommitted, this.boundaryKeep);
if (keepIds === null)
return;
this.reap(scope, keepIds).catch(() => { });
}
catch {
}
}
disclose(path, reason) {
this.onCorruptRead?.({ kind: "file", path, reason });
}
scopeDir(scope) {
return join(this.scopesDir, sanitizeScope(scope));
}
trackedPath(scope) {
return join(this.scopeDir(scope), "tracked.json");
}
boundaryDir(scope) {
return join(this.scopeDir(scope), "boundaries");
}
tryBoundaryPath(scope, entryId) {
try {
return join(this.boundaryDir(scope), `${historyPathComponent(entryId)}.json`);
}
catch {
return null;
}
}
blobPath(hash) {
return join(this.blobsDir, sanitizePathComponent(hash));
}
readTrackedState(scope) {
const path = this.trackedPath(scope);
let raw;
try {
raw = readFileSync(path, "utf8");
}
catch (err) {
if (err.code === "ENOENT")
return { corrupt: false, tracked: new Map() };
this.disclose(path, `tracked set unreadable (${err.code ?? "unknown"}) — this scope's history is UNUSABLE until it is repaired`);
return { corrupt: true, tracked: new Map() };
}
const parsed = parseJsonRecord(raw);
if (parsed === null) {
this.disclose(path, "unparseable tracked set (torn/zero-byte write?) — this scope's history is UNUSABLE until it is repaired");
return { corrupt: true, tracked: new Map() };
}
const rows = trackedRowsOf(parsed);
if (rows === null) {
this.disclose(path, "tracked set is not a pair array of [key, record] rows — this scope's history is UNUSABLE until it is repaired");
return { corrupt: true, tracked: new Map() };
}
if (parsed.digest !== undefined && (typeof parsed.digest !== "string" || parsed.digest !== trackedDigest(rows))) {
this.disclose(path, "tracked set fails its own integrity digest (edited in place, or written by something that is not this store) — this scope's history is UNUSABLE until it is repaired");
return { corrupt: true, tracked: new Map() };
}
return { corrupt: false, tracked: new Map(rows) };
}
readTracked(scope) {
return this.readTrackedState(scope).tracked;
}
writeTracked(scope, tracked) {
const dir = this.scopeDir(scope);
ensureDir(dir);
const rows = [...tracked];
const doc = { formatVersion: "file-history/1", scope, tracked: rows, digest: trackedDigest(rows) };
atomicWriteFile(join(this.base, "tmp"), this.trackedPath(scope), JSON.stringify(doc));
}
readBoundary(path) {
let raw;
try {
raw = readFileSync(path, "utf8");
}
catch (err) {
if (err.code === "ENOENT")
return null;
this.disclose(path, `boundary unreadable (${err.code ?? "unknown"}) — read as no boundary`);
return null;
}
{
const doc = parseJsonRecord(raw);
if (doc === null) {
this.disclose(path, "unparseable boundary (torn/zero-byte write?) — read as no boundary");
return null;
}
if (doc.formatVersion !== "file-history/1" || !Array.isArray(doc.files)) {
this.disclose(path, "boundary is not a file-history/1 pair array — read as no boundary");
return null;
}
const parsed = { formatVersion: doc.formatVersion, files: doc.files, digest: doc.digest };
for (const pair of parsed.files) {
if (!Array.isArray(pair) || pair.length !== 2 || typeof pair[0] !== "string" || !Number.isInteger(pair[1]) || pair[1] < 1) {
this.disclose(path, "boundary carries a malformed mapping row — read as no boundary");
return null;
}
}
if (new Set(parsed.files.map(([k]) => k)).size !== parsed.files.length) {
this.disclose(path, "boundary maps the same path twice — read as no boundary");
return null;
}
if (typeof parsed.digest !== "string" || parsed.digest !== boundaryDigest(parsed.files)) {
this.disclose(path, "boundary fails its own integrity digest (rows added or dropped?) — read as no boundary");
return null;
}
return new Map(parsed.files);
}
}
boundaryCommittedAt(path) {
try {
const doc = parseJsonRecord(readFileSync(path, "utf8"));
const at = doc?.committedAt;
return typeof at === "number" && Number.isFinite(at) ? at : undefined;
}
catch {
return undefined;
}
}
unjudgeableBoundaryIdsOf(scope) {
const dir = this.boundaryDir(scope);
let names;
try {
names = readdirSync(dir);
}
catch (err) {
return err.code === "ENOENT" ? null : [];
}
const bad = names.filter((f) => f.endsWith(".json") && this.readBoundary(join(dir, f)) === null).map((f) => f.slice(0, -".json".length));
return bad.length > 0 ? bad : null;
}
carryConsumedIds(fromScope, toScope) {
const spent = this.readReapedIds(fromScope);
if (spent === null) {
this.disclose(this.reapedLogPath(fromScope), "source consumed-id ledger unreadable — the adoption is refused rather than published without its lineage's tombstones");
return false;
}
if (spent.size === 0)
return true;
return this.markReaped(toScope, [...spent]);
}
reapedLogPath(scope) {
return `${this.scopeDir(scope)}.reaped.log`;
}
readReapedIds(scope) {
const path = this.reapedLogPath(scope);
let size;
try {
size = statSync(path).size;
}
catch (err) {
if (err.code === "ENOENT")
return new Set();
this.disclose(path, `consumed-id ledger unreadable (${err.code ?? "unknown"})`);
return null;
}
const cached = this.reapedCache.get(scope);
if (cached !== undefined && cached.size === size)
return cached.ids;
try {
const ids = new Set(readFileSync(path, "utf8")
.split("\n")
.map((l) => l.trim())
.filter((l) => l !== ""));
this.reapedCache.set(scope, { size, ids });
return ids;
}
catch (err) {
this.disclose(path, `consumed-id ledger unreadable (${err.code ?? "unknown"})`);
return null;
}
}
markReaped(scope, ids) {
if (ids.length === 0)
return true;
const path = this.reapedLogPath(scope);
try {
ensureDir(this.scopesDir);
const payload = ids.map((id) => `${id}\n`).join("");
const fd = openSync(path, "a");
try {
writeFileSync(fd, payload);
fsyncSync(fd);
}
finally {
closeSync(fd);
}
const cached = this.reapedCache.get(scope);
if (cached === undefined)
this.reapedCache.delete(scope);
else
this.reapedCache.set(scope, { size: cached.size + Buffer.byteLength(payload, "utf8"), ids: new Set([...cached.ids, ...ids]) });
return true;
}
catch (err) {
this.disclose(path, `consumed-id ledger could not be appended (${err.code ?? "unknown"}) — the boundaries it names are NOT being reaped, so this scope is not bounded until it can be written`);
return false;
}
}
boundaryOrderOf(path) {
const stamped = this.boundaryCommittedAt(path);
if (stamped !== undefined)
return stamped;
try {
return statSync(path).mtimeMs;
}
catch {
return undefined;
}
}
putBlob(hash, bytes) {
try {
writeThenLink(this.blobPath(hash), bytes);
}
catch (err) {
if (err.code !== "EEXIST")
throw err;
}
}
async trackEdit(scope, absPath, env, root, signal) {
try {
const { key, kind, family } = describeTrackKey(root, absPath);
const before = this.readTrackedState(scope);
if (before.corrupt)
return { ok: false, error: { code: "track_failed", message: `file history for scope "${scope}" is unreadable — refusing to mint a first-touch record over an unusable graph` } };
const existing = before.tracked.get(key);
if (existing !== undefined) {
if (existing.observedByLaterTouch !== true) {
existing.observedByLaterTouch = true;
this.writeTracked(scope, before.tracked);
}
return { ok: true, minted: false };
}
const cap = await captureFileBackupViaEnv(env, absPath, root, signal);
const after = this.readTrackedState(scope);
if (after.corrupt)
return { ok: false, error: { code: "track_failed", message: `file history for scope "${scope}" became unreadable during the first-touch capture — nothing was recorded` } };
const tracked = after.tracked;
const raced = tracked.get(key);
if (raced !== undefined) {
if (raced.observedByLaterTouch !== true) {
raced.observedByLaterTouch = true;
this.writeTracked(scope, tracked);
}
return { ok: true, minted: false };
}
if (cap.state === "aborted") {
return { ok: false, error: { code: "aborted", message: `first-touch backup of ${absPath} aborted` } };
}
const now = new Date().toISOString();
const mintId = randomBytes(8).toString("hex");
if (cap.state === "unreadable") {
tracked.set(key, { baseAvailable: false, mintId, keyKind: kind, keyFamily: family, versions: [] });
this.writeTracked(scope, tracked);
return { ok: true, minted: true };
}
if (cap.state === "file") {
this.putBlob(cap.hash, cap.bytes);
tracked.set(key, { baseAvailable: true, mintId, keyKind: kind, keyFamily: family, versions: [{ version: 1, blobHash: cap.hash, backupTime: now, ...(cap.mode !== undefined ? { mode: cap.mode } : {}), ...(cap.parentIdent !== undefined ? { parentIdent: cap.parentIdent } : {}) }] });
this.writeTracked(scope, tracked);
return { ok: true, minted: true };
}
tracked.set(key, { baseAvailable: true, mintId, keyKind: kind, keyFamily: family, versions: [{ version: 1, blobHash: null, backupTime: now, ...(cap.parentIdent !== undefined ? { parentIdent: cap.parentIdent } : {}) }] });
this.writeTracked(scope, tracked);
return { ok: true, minted: true };
}
catch (err) {
return { ok: false, error: { code: "track_failed", message: `first-touch record for ${absPath} could not be persisted: ${thrownText(err)}` } };
}
}
async annulTrack(scope, absPath, root, verify) {
try {
const key = trackKeyOf(root, absPath);
const state = this.readTrackedState(scope);
if (state.corrupt) {
return { ok: false, error: { code: "conflict", message: `file history for scope "${scope}" is unreadable — the first-touch record (if any) was left in place; repair the graph before retraction can be judged` } };
}
const tracked = state.tracked;
const rec = tracked.get(key);
if (rec === undefined)
return { ok: true };
for (const entryId of this.listBoundaryIds(scope)) {
const bp = this.tryBoundaryPath(scope, entryId);
const mapping = bp === null ? null : this.readBoundary(bp);
if (mapping?.has(key) === true) {
return { ok: false, error: { code: "conflict", message: `first-touch record for ${absPath} is referenced by a committed boundary — it is history now, not a retractable mint` } };
}
}
if (rec.versions.length > 1) {
return { ok: false, error: { code: "conflict", message: `first-touch record for ${absPath} has grown past its first version — only the mint itself is retractable` } };
}
if (rec.observedByLaterTouch === true) {
return { ok: false, error: { code: "conflict", message: `first-touch record for ${absPath} has since been served to another edit of the same path — it is that edit's baseline now, not a retractable mint` } };
}
const proof = verify === undefined ? undefined : await worldStillMatchesMint(verify.env, absPath, root, rec.baseAvailable, rec.versions[0]?.blobHash ?? null, verify.signal);
if (proof !== undefined && !proof.unchanged) {
return { ok: false, error: { code: "conflict", message: `first-touch record for ${absPath} is NOT retractable: ${proof.reason} — the write this retraction compensates for may have changed the file` } };
}
const fresh = this.readTrackedState(scope);
if (fresh.corrupt)
return { ok: false, error: { code: "conflict", message: `file history for scope "${scope}" became unreadable — the record was left in place` } };
const still = fresh.tracked.get(key);
if (still === undefined)
return { ok: true };
if (still.observedByLaterTouch === true || still.versions.length > 1) {
return { ok: false, error: { code: "conflict", message: `first-touch record for ${absPath} stopped being a retractable mint while this retraction was being proven` } };
}
if (still.mintId !== rec.mintId || still.baseAvailable !== rec.baseAvailable || still.versions.length !== rec.versions.length || still.versions[0]?.blobHash !== rec.versions[0]?.blobHash || still.versions[0]?.backupTime !== rec.versions[0]?.backupTime) {
return { ok: false, error: { code: "conflict", message: `first-touch record for ${absPath} was replaced while this retraction was being proven — the record now there belongs to a newer edit` } };
}
for (const entryId of this.listBoundaryIds(scope)) {
const bp2 = this.tryBoundaryPath(scope, entryId);
const mapping2 = bp2 === null ? null : this.readBoundary(bp2);
if (mapping2?.has(key) === true) {
return { ok: false, error: { code: "conflict", message: `first-touch record for ${absPath} was frozen by a boundary committed while this retraction was being proven — it is history now` } };
}
}
fresh.tracked.delete(key);
this.writeTracked(scope, fresh.tracked);
return { ok: true };
}
catch (err) {
return { ok: false, error: { code: "track_failed", message: `annulling the first-touch record for ${absPath} failed: ${thrownText(err)}` } };
}
}
scopeIsEmptySync(scope) {
const state = this.readTrackedState(scope);
if (state.corrupt)
return false;
return state.tracked.size === 0 && this.listBoundaryIds(scope).length === 0;
}
publishStagedScopeSync(scope, staging) {
if (!this.scopeIsEmptySync(scope))
return "not_empty";
const target = this.scopeDir(scope);
const destroyed = [];
for (const f of (() => {
try {
return readdirSync(this.boundaryDir(scope));
}
catch {
return [];
}
})()) {
if (f.endsWith(".json"))
destroyed.push(f.slice(0, -".json".length));
}
if (!this.markReaped(scope, destroyed))
return "ledger_failed";
safeRm(target);
renameSync(staging, target);
return "published";
}
listBoundaryIds(scope) {
const dir = this.boundaryDir(scope);
let entries;
try {
entries = readdirSync(dir);
}
catch (err) {
if (err.code !== "ENOENT") {
this.disclose(dir, `boundary directory unreadable (${err.code ?? "unknown"}) — listed as no boundaries`);
}
return [];
}
return entries
.filter((f) => f.endsWith(".json"))
.filter((f) => this.readBoundary(join(dir, f)) !== null)
.map((f) => f.slice(0, -".json".length));
}
async snapshot(scope, entryId, env, root, signal) {
const bpath = this.tryBoundaryPath(scope, entryId);
if (bpath === null)
return { ok: false, error: { code: "snapshot_failed", message: `unsafe boundary key ${JSON.stringify(entryId)}` } };
if (this.readBoundary(bpath) !== null)
return { ok: true };
const consumed = this.readReapedIds(scope);
if (consumed === null) {
return { ok: false, error: { code: "snapshot_failed", message: `the consumed-entry ledger for scope "${scope}" cannot be read — refusing to mint a boundary while it is impossible to tell a fresh entry id from one retention already reaped` } };
}
if (consumed.has(entryId)) {
return { ok: false, error: { code: "snapshot_failed", message: `entry "${entryId}" already had a boundary and it was reaped by retention — a fresh capture now would record post-turn bytes under a pre-turn key, so this entry has no boundary and cannot get one back` } };
}
if (this.spentAttempts.get(scope)?.has(entryId) === true) {
return { ok: false, error: { code: "snapshot_failed", message: `capture lease for entry "${entryId}" is closed (a prior attempt failed); no complete pre-close staging exists, so this turn has no boundary` } };
}
if (this.activeCaptures.get(scope)?.has(entryId) === true) {
return { ok: false, error: { code: "snapshot_failed", message: `a capture attempt for entry "${entryId}" is already in flight — concurrent same-key capture is refused (the in-flight attempt owns the lease)` } };
}
const journal = join(this.scopeDir(scope), "staging", `${Date.now().toString(36)}-${randomBytes(6).toString("hex")}.jsonl`);
nestedMapSet(this.activeCaptures, scope, entryId, journal);
try {
ensureDir(join(this.scopeDir(scope), "staging"));
appendFileSync(journal, `${JSON.stringify({ entryId, pid: process.pid, startedAt: new Date().toISOString() })}\n`);
const state = this.readTrackedState(scope);
if (state.corrupt) {
nestedSetAdd(this.spentAttempts, scope, entryId);
return { ok: false, error: { code: "snapshot_failed", message: `file history for scope "${scope}" is unreadable — a boundary minted over an unusable graph would claim to restore state that is not there` } };
}
const tracked = state.tracked;
const staged = new Map();
for (const [key, rec] of tracked) {
if (signal?.aborted) {
nestedSetAdd(this.spentAttempts, scope, entryId);
return { ok: false, error: { code: "aborted", message: `boundary capture for entry "${entryId}" aborted` } };
}
const resolved = resolveTrackKey(root, key, descriptorOf(rec));
if (!resolved.ok) {
nestedSetAdd(this.spentAttempts, scope, entryId);
return { ok: false, error: { code: "snapshot_failed", message: resolved.reason } };
}
const cap = await captureFileBackupViaEnv(env, resolved.abs, root, signal);
if (cap.state === "aborted") {
nestedSetAdd(this.spentAttempts, scope, entryId);
return { ok: false, error: { code: "aborted", message: `boundary capture for entry "${entryId}" aborted` } };
}
if (cap.state === "unreadable") {
nestedSetAdd(this.spentAttempts, scope, entryId);
return { ok: false, error: { code: "snapshot_failed", message: cap.cause } };
}
const last = rec.versions[rec.versions.length - 1];
if (cap.state === "absent") {
if (last !== undefined && last.blobHash === null)
staged.set(key, { kind: "unchanged", version: last.version });
else
staged.set(key, { kind: "changed", blobHash: null, ...(cap.parentIdent !== undefined ? { parentIdent: cap.parentIdent } : {}) });
continue;
}
if (last !== undefined && last.blobHash === cap.hash && !modeProvenDifferent(last.mode, cap.mode)) {
staged.set(key, { kind: "unchanged", version: last.version });
continue;
}
appendFileSync(journal, `${JSON.stringify({ blob: cap.hash })}\n`);
this.putBlob(cap.hash, cap.bytes);
staged.set(key, { kind: "changed", blobHash: cap.hash, ...(cap.mode !== undefined ? { mode: cap.mode } : {}), ...(cap.parentIdent !== undefined ? { parentIdent: cap.parentIdent } : {}) });
}
if (!boundaryPublishVerdict({ aborted: signal?.aborted === true }).publish) {
nestedSetAdd(this.spentAttempts, scope, entryId);
return { ok: false, error: { code: "aborted", message: `boundary capture for entry "${entryId}" aborted (fenced — never committed)` } };
}
const currentState = this.readTrackedState(scope);
if (currentState.corrupt) {
nestedSetAdd(this.spentAttempts, scope, entryId);
return { ok: false, error: { code: "snapshot_failed", message: `file history for scope "${scope}" became unreadable during the capture — no boundary was published` } };
}
const current = currentState.tracked;
for (const [key, cap] of staged) {
if (cap.kind !== "unchanged")
continue;
if (current.get(key)?.versions.some((v) => v.version === cap.version) !== true) {
nestedSetAdd(this.spentAttempts, scope, entryId);
return { ok: false, error: { code: "snapshot_failed", message: `staged reference ${key}@v${cap.version} no longer exists (reaped mid-capture)` } };
}
}
const mapping = [];
const now = new Date().toISOString();
for (const [key, cap] of staged) {
if (cap.kind === "unchanged") {
mapping.push([key, cap.version]);
continue;
}
const rec = current.get(key);
if (rec === undefined)
continue;
const last = rec.versions[rec.versions.length - 1];
const version = last !== undefined ? last.version + 1 : rec.baseAvailable ? 1 : 2;
rec.versions.push({ version, blobHash: cap.blobHash, backupTime: now, ...(cap.mode !== undefined ? { mode: cap.mode } : {}), ...(cap.parentIdent !== undefined ? { parentIdent: cap.parentIdent } : {}) });
mapping.push([key, version]);
}
this.writeTracked(scope, current);
ensureDir(this.boundaryDir(scope));
const doc = { formatVersion: "file-history/1", files: mapping, digest: boundaryDigest(mapping), committedAt: this.nextCommittedAt(scope) };
try {
writeThenLink(bpath, JSON.stringify(doc));
}
catch (err) {
if (err.code !== "EEXIST")
throw err;
if (this.readBoundary(bpath) === null) {
nestedSetAdd(this.spentAttempts, scope, entryId);
return { ok: false, error: { code: "snapshot_failed", message: `a boundary file for entry "${entryId}" already exists but cannot be read — this turn has no usable boundary (the unreadable file is left in place for an operator rather than silently replaced)` } };
}
}
this.applyBoundaryRetention(scope, entryId);
return { ok: true };
}
catch (err) {
nestedSetAdd(this.spentAttempts, scope, entryId);
return { ok: false, error: { code: "snapshot_failed", message: `boundary for entry "${entryId}" could not be committed: ${thrownText(err)}` } };
}
finally {
this.activeCaptures.get(scope)?.delete(entryId);
safeRm(journal);
}
}
async restore(scope, entryId, env, root, signal) {
const ledger = EMPTY_LEDGER();
let modeNotPreserved = 0;
try {
const bpath = this.tryBoundaryPath(scope, entryId);
const boundary = bpath === null ? null : this.readBoundary(bpath);
if (boundary === null) {
return { outcome: "failed", ...ledger, error: { code: "not_found", message: `no history boundary for entry "${entryId}"` } };
}
const state = this.readTrackedState(scope);
if (state.corrupt) {
return { outcome: "failed", ...ledger, error: { code: "restore_failed", message: `file history for scope "${scope}" is unreadable — the boundary exists but its version records cannot be read, so NOTHING was restored` } };
}
const tracked = state.tracked;
for (const key of [...tracked.keys()].sort()) {
const rec = tracked.get(key);
if (signal?.aborted) {
ledger.failed.push({ path: key, reason: "aborted before attempt" });
continue;
}
let targetVersion = boundary.get(key);
if (targetVersion === undefined) {
if (!rec.baseAvailable) {
ledger.refused.push({ path: key, reason: "base_unavailable" });
continue;
}
targetVersion = 1;
}
const version = rec.versions.find((v) => v.version === targetVersion);
if (version === undefined) {
ledger.failed.push({ path: key, reason: `version ${targetVersion} record missing (store integrity)` });
continue;
}
const resolved = resolveTrackKey(root, key, descriptorOf(rec));
if (!resolved.ok) {
ledger.refused.push({ path: key, reason: resolved.reason });
continue;
}
let target;
if (version.blobHash === null)
target = { absent: true };
else {
let bytes;
try {
bytes = readFileSync(this.blobPath(version.blobHash));
}
catch {
bytes = undefined;
}
if (bytes === undefined) {
ledger.failed.push({ path: key, reason: `blob ${version.blobHash} missing (store integrity)` });
continue;
}
if (createHash("sha256").update(bytes).digest("hex") !== version.blobHash) {
ledger.failed.push({ path: key, reason: `blob ${version.blobHash} fails content-address integrity (store corruption) — the file was left untouched` });
this.disclose(this.blobPath(version.blobHash), "blob bytes do not hash to their own name — the restore refused to apply them");
continue;
}
target = { bytes, hash: version.blobHash };
}
let applied;
try {
applied = await applyFileRestoreViaEnv(env, resolved.abs, target, {
root,
...(version.mode !== undefined ? { mode: version.mode } : {}),
...(version.parentIdent !== undefined ? { parentIdent: version.parentIdent } : {}),
...(signal !== undefined ? { signal } : {}),
});
}
catch (err) {
applied = { outcome: "failed", reason: thrownText(err) };
}
if (applied.outcome === "applied")
ledger.filesChanged.push(key);
else if (applied.outcome === "identical")
ledger.identicalSkipped.push(key);
else if (applied.outcome === "refused")
ledger.refused.push({ path: key, reason: applied.reason });
else
ledger.failed.push({ path: key, reason: applied.reason });
if ((applied.outcome === "applied" || applied.outcome === "identical") && applied.modeNotPreserved === true)
modeNotPreserved++;
}
return { outcome: ledger.refused.length > 0 || ledger.failed.length > 0 ? "partial" : "complete", ...ledger, ...(modeNotPreserved > 0 ? { modeNotPreserved } : {}) };
}
catch (err) {
const touched = ledger.filesChanged.length > 0 || ledger.identicalSkipped.length > 0 || ledger.refused.length > 0 || ledger.failed.length > 0;
return { outcome: touched ? "partial" : "failed", ...ledger, error: { code: "restore_failed", message: thrownText(err) } };
}
}
async canRestore(scope, entryId) {
const bpath = this.tryBoundaryPath(scope, entryId);
return bpath !== null && this.readBoundary(bpath) !== null;
}
async diffStats(scope, entryId, env, root) {
try {
const bpath = this.tryBoundaryPath(scope, entryId);
const boundary = bpath === null ? null : this.readBoundary(bpath);
if (boundary === null)
return null;
const state = this.readTrackedState(scope);
if (state.corrupt)
return null;
const filesChanged = [];
let insertions = 0;
let deletions = 0;
for (const key of [...state.tracked.keys()].sort()) {
const rec = state.tracked.get(key);
let targetVersion = boundary.get(key);
if (targetVersion === undefined) {
if (!rec.baseAvailable)
continue;
targetVersion = 1;
}
const version = rec.versions.find((v) => v.version === targetVersion);
const resolved = resolveTrackKey(root, key, descriptorOf(rec));
if (version === undefined || !resolved.ok)
continue;
let targetBytes;
if (version.blobHash !== null) {
try {
targetBytes = readFileSync(this.blobPath(version.blobHash));
}
catch {
continue;
}
if (createHash("sha256").update(targetBytes).digest("hex") !== version.blobHash)
continue;
}
const delta = await previewFileDelta(env, resolved.abs, version.blobHash, targetBytes, version.mode);
if (delta === undefined)
continue;
filesChanged.push(key);
insertions += delta.insertions;
deletions += delta.deletions;
}
return { filesChanged, insertions, deletions };
}
catch {
return null;
}
}
async reap(scope, keepEntryIds) {
const keep = new Set(keepEntryIds);
let removed = 0;
const dir = this.boundaryDir(scope);
let entries = [];
try {
entries = readdirSync(dir);
}
catch (err) {
if (err.code !== "ENOENT") {
this.disclose(dir, `boundary directory unreadable (${err.code ?? "unknown"}) — the WHOLE reap is refused (0 dropped, no version or blob collection) because an unlistable directory cannot distinguish "no boundaries" from "boundaries we cannot see"`);
return 0;
}
}
const mappings = new Map();
for (const file of entries) {
if (!file.endsWith(".json"))
continue;
const mapping = this.readBoundary(join(dir, file));
if (mapping === null) {
this.disclose(join(dir, file), "a boundary in this scope cannot be judged — the WHOLE reap is refused (0 dropped, nothing collected) until it is repaired or removed, because trimming around a record whose references cannot be read destroys the versions only it points at");
return 0;
}
mappings.set(file.slice(0, -".json".length), mapping);
}
const survivors = new Set(keep);
for (const file of entries) {
if (!file.endsWith(".json"))
continue;
const id = file.slice(0, -".json".length);
if (keep.has(id))
continue;
if (!this.markReaped(scope, [id])) {
survivors.add(id);
continue;
}
if (safeRm(join(dir, file))) {
removed++;
}
else {
survivors.add(id);
}
}
const referenced = new Map();
for (const [id, mapping] of mappings) {
if (!survivors.has(id))
continue;
for (const [key, v] of mapping) {
let s = referenced.get(key);
if (s === undefined)
referenced.set(key, (s = new Set()));
s.add(v);
}
}
const tracked = this.readTracked(scope);
if (tracked.size > 0) {
for (const [key, rec] of tracked) {
rec.versions = rec.versions.filter((v) => v.version === 1 || (referenced.get(key)?.has(v.version) ?? false));
}
try {
this.writeTracked(scope, tracked);
}
catch (err) {
this.disclose(this.trackedPath(scope), `version-chain trim could not be committed (${thrownText(err)}) — trim skipped this pass; untrimmed versions keep their blobs live`);
}
}
this.collectBlobs();
return removed;
}
collectBlobs() {
const live = new Set();
let complete = true;
let scopeDirs;
try {
scopeDirs = readdirSync(this.scopesDir);
}
catch (err) {
if (err.code === "ENOENT")
return;
this.disclose(this.scopesDir, `scope root unreadable (${err.code ?? "unknown"}) — blob GC aborted, every blob kept`);
return;
}
const liveJournals = new Set([...[...this.activeCaptures.values()].flatMap((m) => [...m.values()]), ...[...this.activeImports.values()].flatMap((set) => [...set])]);
for (const name of scopeDirs) {
const sdir = join(this.scopesDir, name);
try {
if (!statSync(sdir).isDirectory())
continue;
}
catch {
continue;
}
const tpath = join(sdir, "tracked.json");
if (existsSync(tpath)) {
let doc;
try {
doc = parseJsonRecord(readFileSync(tpath, "utf8"));
}
catch {
doc = null;
}
const rows = trackedRowsOf(doc);
if (rows === null) {
complete = false;
this.disclose(tpath, "tracked set unreadable during the live-set scan — blob GC aborted, every blob kept");
break;
}
if (doc?.digest !== undefined && (typeof doc.digest !== "string" || doc.digest !== trackedDigest(rows))) {
complete = false;
this.disclose(tpath, "tracked set fails its own integrity digest during the live-set scan — blob GC aborted, every blob kept (a live set built from damaged rows would delete the bytes a repair needs)");
break;
}
for (const [, rec] of rows)
for (const v of rec.versions)
if (v.blobHash !== null)
live.add(v.blobHash);
}
const stagingDir = join(sdir, "staging");
let journals = [];
try {
journals = readdirSync(stagingDir);
}
catch (err) {
if (err.code !== "ENOENT") {
complete = false;
this.disclose(stagingDir, `staging directory unreadable (${err.code ?? "unknown"}) — blob GC aborted, every blob kept`);
break;
}
}
for (const j of journals) {
const jpath = join(stagingDir, j);
let raw;
try {
raw = readFileSync(jpath, "utf8");
}
catch (err) {
if (err.code === "ENOENT")
continue;
complete = false;
this.disclose(jpath, "staging journal unreadable — blob GC aborted, every blob kept");
break;
}
const lines = raw.split("\n").filter((l) => l !== "");
const header = parseJsonRecord(lines[0] ?? "");
if (header === null || typeof header.pid !== "number" || typeof header.startedAt !== "string") {
this.disclose(jpath, "staging journal header is unreadable — the journal and its leased blobs are KEPT (an unknown owner is never proof of death)");
for (const line of lines)
leaseJournalBlob(line, live);
continue;
}
const ownedHere = liveJournals.has(jpath);
const ownerAlive = !ownedHere && typeof header.pid === "number" && pidIsAlive(header.pid);
const startedMs = Date.parse(header.startedAt ?? "");
const young = Number.isFinite(startedMs) && Date.now() - startedMs < STALE_JOURNAL_MS;
if (!ownedHere && !ownerAlive && !young) {
safeRm(jpath);
continue;
}
for (const line of lines)
leaseJournalBlob(line, live);
}
if (!complete)
break;
}
if (!complete)
return;
let blobs;
try {
blobs = readdirSync(this.blobsDir);
}
catch (err) {
if (err.code !== "ENOENT") {
this.disclose(this.blobsDir, `blob directory unreadable (${err.code ?? "unknown"}) — blob GC skipped, every blob kept`);
}
return;
}
for (const blob of blobs)
if (!live.has(blob))
safeRm(join(this.blobsDir, blob));
}
async adoptScope(fromScope, toScope) {
try {
if (fromScope === toScope)
return { ok: true };
const targetState = this.readTrackedState(toScope);
if (targetState.corrupt) {
return { ok: false, error: { code: "adopt_failed", message: `adoptScope target "${toScope}" has an unreadable tracked set — a scope whose bytes cannot be judged is not an empty target` } };
}
const targetTracked = targetState.tracked;
const targetBoundaries = this.listBoundaryIds(toScope);
if (targetTracked.size > 0 || targetBoundaries.length > 0) {
return { ok: false, error: { code: "conflict", message: `adoptScope target "${toScope}" already has history of its own — adoption is legal only onto an EMPTY scope (the fork/resume boundary before the new session's first turn)` } };
}
const sourceState = this.readTrackedState(fromScope);
if (sourceState.corrupt) {
return { ok: false, error: { code: "adopt_failed", message: `adoptScope source "${fromScope}" has an unreadable tracked set — adopting it would publish boundaries with no version records behind them` } };
}
const source = sourceState.tracked;
const unjudgeable = this.unjudgeableBoundaryIdsOf(fromScope);
if (unjudgeable !== null) {
return { ok: false, error: { code: "adopt_failed", message: `adoptScope source "${fromScope}" has ${unjudgeable.length > 0 ? `boundaries that cannot be judged (${unjudgeable.slice(0, 3).map((i) => JSON.stringify(i)).join(", ")}${unjudgeable.length > 3 ? ", …" : ""})` : "a boundary directory that cannot be listed"} — adopting it would publish a graph that silently drops those turns and hands their entry ids back to the fork; nothing was published` } };
}
const sourceBoundaries = this.listBoundaryIds(fromScope);
if (source.size === 0 && sourceBoundaries.length === 0) {
if (!this.carryConsumedIds(fromScope, toScope)) {
return { ok: false, error: { code: "adopt_failed", message: `adoptScope could not carry the consumed-entry ledger from "${fromScope}" to "${toScope}" — refusing rather than reporting a carry that would let an already-consumed entry id be minted again in the fork` } };
}
return { ok: true };
}
for (const [key, rec] of source) {
for (const v of rec.versions) {
if (v.blobHash === null)
continue;
let bytes;
try {
bytes = readFileSync(this.blobPath(v.blobHash));
}
catch {
bytes = undefined;
}
if (bytes === undefined || createHash("sha256").update(bytes).digest("hex") !== v.blobHash) {
return { ok: false, error: { code: "adopt_failed", message: `adoptScope source "${fromScope}" references blob ${v.blobHash} for ${key}@v${v.version}, which is missing or fails content-address integrity — nothing was published` } };
}
}
}
const staging = `${this.scopeDir(toScope)}.adopting-${process.pid}-${randomBytes(6).toString("hex")}`;
safeRm(staging);
try {
ensureDir(join(staging, "boundaries"));
const adoptedRows = [...source];
const doc = { formatVersion: "file-history/1", scope: toScope, tracked: adoptedRows, digest: trackedDigest(adoptedRows) };
atomicWriteFile(join(this.base, "tmp"), join(staging, "tracked.json"), JSON.stringify(doc));
for (const id of sourceBoundaries) {
const bp = this.tryBoundaryPath(fromScope, id);
const mapping = bp === null ? null : this.readBoundary(bp);
if (mapping === null)
continue;
for (const [key, version] of mapping) {
if (source.get(key)?.versions.some((v) => v.version === version) !== true) {
throw new Error(`source boundary ${id} references ${key}@v${version}, which the source's version chains do not carry`);
}
}
const sourceCommittedAt = bp === null ? undefined : this.boundaryOrderOf(bp);
const bdoc = { formatVersion: "file-history/1", files: [...mapping], digest: boundaryDigest([...mapping]), ...(sourceCommittedAt !== undefined ? { committedAt: sourceCommittedAt } : {}) };
atomicWriteFile(join(this.base, "tmp"), join(staging, "boundaries", `${historyPathComponent(id)}.json`), JSON.stringify(bdoc));
}
if (!this.carryConsumedIds(fromScope, toScope)) {
safeRm(staging);
return { ok: false, error: { code: "adopt_failed", message: `adoptScope could not carry the consumed-entry ledger from "${fromScope}" to "${toScope}" — nothing was published, because a fork missing its lineage's tombstones can mint an already-consumed entry id` } };
}
const published = this.publishStagedScopeSync(toScope, staging);
if (published !== "published") {
safeRm(staging);
return published === "not_empty"
? { ok: false, error: { code: "conflict", message: `adoptScope target "${toScope}" gained history of its own while this adoption was being staged — nothing was published` } }
: { ok: false, error: { code: "adopt_failed", message: `adoptScope could not record the consumed-entry tombstones for target "${toScope}"'s unreadable boundary residue — nothing was published, because replacing records nothing remembers would hand their already-consumed entry ids back to the fork` } };
}
}
catch (err) {
safeRm(staging);
throw err;
}
return { ok: true };
}
catch (err) {
return { ok: false, error: { code: "adopt_failed", message: `adoptScope failed: ${thrownText(err)}` } };
}
}
async exportHistory(scope) {
const state = this.readTrackedState(scope);
if (state.corrupt) {
return null;
}
const tracked = state.tracked;
const boundaryIds = this.listBoundaryIds(scope);
if (tracked.size === 0 && boundaryIds.length === 0)
return null;
const boundaries = [];
for (const entryId of [...boundaryIds].sort()) {
const bp = this.tryBoundaryPath(scope, entryId);
const mapping = bp === null ? null : this.readBoundary(bp);
if (mapping === null)
continue;
boundaries.push({ entryId, files: [...mapping.entries()].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)).map(([relOrAbsPath, version]) => ({ relOrAbsPath, version })) });
}
return {
formatVersion: "file-history/1",
tracked: [...tracked.entries()]
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
.map(([key, rec]) => ({
relOrAbsPath: key,
keyKind: rec.keyKind ?? (isAbsoluteForFamily(rec.keyFamily ?? "posix", key) ? "absolute" : "root-relative"),
keyFamily: rec.keyFamily ?? "posix",
baseAvailable: rec.baseAvailable,
versions: rec.versions.map((v) => ({ version: v.version, blobHash: v.blobHash, ...(v.mode !== undefined ? { mode: v.mode } : {}), ...(v.parentIdent !== undefined ? { parentIdent: v.parentIdent } : {}), backupTime: v.backupTime })),
})),
boundaries,
};
}
async importHistory(scope, data, srcGetBlob) {
try {
const shaped = validateFileHistoryExport(data);
if (!shaped.ok)
return shaped;
const existing = await this.exportHistory(scope);
let identicalRepublish = false;
if (existing !== null) {
if (fileHistoryExportDigest(existing) === fileHistoryExportDigest(data))
identicalRepublish = true;
else
return { ok: false, error: { code: "conflict", message: `importHistory target "${scope}" already holds a DIFFERENT history — a first import requires an empty target and a retry is legal only for the identical envelope (atomic visibility prevents half-graphs; this law prevents publishing the wrong complete graph over locally-grown history)` } };
}
const importJournal = join(this.scopeDir(scope), "staging", `import-${Date.now().toString(36)}-${randomBytes(6).toString("hex")}.jsonl`);
ensureDir(join(this.scopeDir(scope), "staging"));
appendFileSync(importJournal, `${JSON.stringify({ entryId: `import:${scope}`, pid: process.pid, startedAt: new Date().toISOString() })}\n`);
nestedSetAdd(this.activeImports, scope, importJournal);
for (const t of data.tracked) {
for (const v of t.versions) {
if (v.blobHash !== null)
appendFileSync(importJournal, `${JSON.stringify({ blob: v.blobHash })}\n`);
}
}
return await this.runImport(scope, data, srcGetBlob, importJournal, identicalRepublish);
}
catch (err) {
return { ok: false, error: { code: "unsupported_format", message: `importHistory failed: ${thrownText(err)}` } };
}
}
async runImport(scope, data, srcGetBlob, importJournal, identicalRepublish) {
try {
for (const t of data.tracked) {
for (const v of t.versions) {
if (v.blobHash === null)
continue;
if (existsSync(this.blobPath(v.blobHash))) {
let local;
try {
local = readFileSync(this.blobPath(v.blobHash));
}
catch {
local = undefined;
}
if (local !== undefined && createHash("sha256").update(local).digest("hex") === v.blobHash)
continue;
this.disclose(this.blobPath(v.blobHash), "locally stored blob does not hash to its own name — the import re-fetched it from the source");
safeRm(this.blobPath(v.blobHash));
}
let bytes;
try {
bytes = await srcGetBlob(v.blobHash);
}
catch (err) {
return { ok: false, error: { code: "unsupported_format", message: `source blob ${v.blobHash} fetch failed: ${thrownText(err)}` } };
}
if (bytes === undefined)
return { ok: false, error: { code: "not_found", message: `source blob ${v.blobHash} is missing — the envelope's graph cannot be completed, so nothing is published` } };
if (createHash("sha256").update(bytes).digest("hex") !== v.blobHash) {
return { ok: false, error: { code: "unsupported_format", message: `source blob ${v.blobHash} fails content-address integrity — refused, nothing published` } };
}
this.putBlob(v.blobHash, bytes);
}
}
if (identicalRepublish)
return { ok: true };
const now = await this.exportHistory(scope);
if (now !== null) {
if (fileHistoryExportDigest(now) === fileHistoryExportDigest(data))
return { ok: true };
return { ok: false, error: { code: "conflict", message: `importHistory target "${scope}" gained a DIFFERENT history while this import was fetching blobs — nothing was published` } };
}
const staging = `${this.scopeDir(scope)}.importing-${process.pid}-${randomBytes(6).toString("hex")}`;
safeRm(staging);
try {
ensureDir(join(staging, "boundaries"));
const tracked = data.tracked.map((t) => [
t.relOrAbsPath,
{
baseAvailable: t.baseAvailable,
keyKind: t.keyKind,
keyFamily: t.keyFamily,
versions: t.versions.map((v) => ({ version: v.version, blobHash: v.blobHash, ...(v.mode !== undefined ? { mode: v.mode } : {}), ...(v.parentIdent !== undefined ? { parentIdent: v.parentIdent } : {}), backupTime: v.backupTime })),
},
]);
const doc = { formatVersion: "file-history/1", scope, tracked, digest: trackedDigest(tracked) };
atomicWriteFile(join(this.base, "tmp"), join(staging, "tracked.json"), JSON.stringify(doc));
for (const b of data.boundaries) {
const bfiles = b.files.map((f) => [f.relOrAbsPath, f.version]);
const bdoc = { formatVersion: "file-history/1", files: bfiles, digest: boundaryDigest(bfiles) };
atomicWriteFile(join(this.base, "tmp"), join(staging, "boundaries", `${historyPathComponent(b.entryId)}.json`), JSON.stringify(bdoc));
}
let published;
try {
published = this.publishStagedScopeSync(scope, staging);
}
catch (err) {
safeRm(staging);
return { ok: false, error: { code: "adopt_failed", message: `importHistory could not publish the staged graph for "${scope}": ${thrownText(err)} — nothing was published (a local storage fault, not a malformed envelope)` } };
}
if (published !== "published") {
safeRm(staging);
return published === "not_empty"
? { ok: false, error: { code: "conflict", message: `importHistory target "${scope}" gained history of its own while this import was being staged — nothing was published` } }
: { ok: false, error: { code: "adopt_failed", message: `importHistory could not record the consumed-entry tombstones for target "${scope}"'s unreadable boundary residue — nothing was published, because replacing records nothing remembers would hand their already-consumed entry ids back to this scope` } };
}
}
catch (err) {
safeRm(staging);
throw err;
}
return { ok: true };
}
catch (err) {
return { ok: false, error: { code: "unsupported_format", message: `importHistory failed: ${thrownText(err)}` } };
}
finally {
safeRm(importJournal);
this.activeImports.get(scope)?.delete(importJournal);
}
}
}