UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

721 lines (720 loc) • 48.8 kB
import { strict as assert } from "node:assert"; import { createHash } from "node:crypto"; import { chmod, mkdtemp, mkdir, rm, stat, symlink, writeFile, readFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { NodeExecutionEnv } from "../../internal/harness.js"; import { beginContract } from "./contract-harness.js"; function probeOver(inner) { const calls = new Map(); const paths = new Map(); const proxied = new Proxy(inner, { get(target, prop, receiver) { const v = Reflect.get(target, prop, receiver); if (typeof v !== "function") return v; return (...args) => { calls.set(String(prop), (calls.get(String(prop)) ?? 0) + 1); if (typeof args[0] === "string") paths.set(args[0], (paths.get(args[0]) ?? 0) + 1); return v.apply(inner, args); }; }, }); return { env: proxied, calls, touched: (p) => paths.get(p) ?? 0 }; } const wireEnvelope = (raw) => raw; function envWithFailingRead(inner, fail) { return new Proxy(inner, { get(target, prop, receiver) { const v = Reflect.get(target, prop, receiver); if (prop !== "readBinaryFile" || typeof v !== "function") return v; return async (...args) => fail(String(args[0])); }, }); } async function withTree(fn) { const dir = await mkdtemp(join(tmpdir(), "fh-kit-")); try { await fn(dir, new NodeExecutionEnv({ cwd: dir })); } finally { await rm(dir, { recursive: true, force: true }); } } export async function fileHistoryStoreContract(make, runAssertion) { const { run, settle } = beginContract(runAssertion); run("absent everything: canRestore=false, restore=failed/not_found with an empty ledger, reap=0 — and none of it throws", async () => { await withTree(async (dir, env) => { const store = make(); assert.equal(await store.canRestore("sc", "e1"), false); const r = await store.restore("sc", "e1", env, dir); assert.equal(r.outcome, "failed"); assert.equal(r.error?.code, "not_found"); assert.deepEqual(r.filesChanged, []); assert.deepEqual(r.refused, []); assert.equal(await store.reap("sc", []), 0); }); }); run("first-touch idempotence: a second trackEdit for the same path is a cheap no-op (ZERO env reads)", async () => { await withTree(async (dir, env) => { const store = make(); await writeFile(join(dir, "f.txt"), "v1"); assert.deepEqual(await store.trackEdit("sc", join(dir, "f.txt"), env, dir), { ok: true, minted: true }, "the FIRST touch reports minted:true — the caller's annul handle (#491)"); const probe = probeOver(env); assert.deepEqual(await store.trackEdit("sc", join(dir, "f.txt"), probe.env, dir), { ok: true, minted: false }, "a repeat must report minted:false — annulling it would discard the FIRST edit's baseline"); assert.equal(probe.calls.get("readBinaryFile") ?? 0, 0); }); }); run("boundary commit visibility + idempotence: canRestore flips only on commit; a repeat snapshot over a COMMITTED boundary is ok with zero env reads", async () => { await withTree(async (dir, env) => { const store = make(); await writeFile(join(dir, "f.txt"), "v1"); assert.deepEqual(await store.trackEdit("sc", join(dir, "f.txt"), env, dir), { ok: true, minted: true }); assert.equal(await store.canRestore("sc", "b1"), false); assert.deepEqual(await store.snapshot("sc", "b1", env, dir), { ok: true }); assert.equal(await store.canRestore("sc", "b1"), true); const probe = probeOver(env); assert.deepEqual(await store.snapshot("sc", "b1", probe.env, dir), { ok: true }); assert.equal(probe.calls.get("readBinaryFile") ?? 0, 0); }); }); run("fencing: an attempt whose signal fired NEVER publishes (canRestore stays false) — including a signal that fires DURING the capture while the env completes its read anyway", async () => { await withTree(async (dir, env) => { const store = make(); await writeFile(join(dir, "f.txt"), "v1"); assert.deepEqual(await store.trackEdit("sc", join(dir, "f.txt"), env, dir), { ok: true, minted: true }); const pre = new AbortController(); pre.abort(); const r = await store.snapshot("sc", "bX", env, dir, pre.signal); assert.equal(r.ok, false); assert.equal(await store.canRestore("sc", "bX"), false); const mid = new AbortController(); const abortDuringRead = new Proxy(env, { get(target, prop, receiver) { const v = Reflect.get(target, prop, receiver); if (prop !== "readBinaryFile" || typeof v !== "function") return v; return async (...args) => { mid.abort(); return v.apply(target, [args[0], undefined]); }; }, }); const r2 = await store.snapshot("sc", "bY", abortDuringRead, dir, mid.signal); assert.equal(r2.ok, false); assert.equal(await store.canRestore("sc", "bY"), false); }); }); run("capture lease (§10 S-6): a MID-SET failure (second file's read) spends the lease — no boundary appears (catches per-file publishers), and the retry performs ZERO env calls of ANY kind", async () => { await withTree(async (dir, env) => { const store = make(); await writeFile(join(dir, "a.txt"), "a1"); await writeFile(join(dir, "b.txt"), "b1"); assert.deepEqual(await store.trackEdit("sc", join(dir, "a.txt"), env, dir), { ok: true, minted: true }); assert.deepEqual(await store.trackEdit("sc", join(dir, "b.txt"), env, dir), { ok: true, minted: true }); let reads = 0; const brokenSecond = new Proxy(env, { get(target, prop, receiver) { const v = Reflect.get(target, prop, receiver); if (prop !== "readBinaryFile" || typeof v !== "function") return v; return async (...args) => { if (reads++ >= 1) return { ok: false, error: { code: "unknown", message: "injected IO fault" } }; return v.apply(target, args); }; }, }); assert.equal((await store.snapshot("sc", "bL", brokenSecond, dir)).ok, false); assert.equal(await store.canRestore("sc", "bL"), false); const probe = probeOver(env); const retry = await store.snapshot("sc", "bL", probe.env, dir); assert.equal(retry.ok, false); const totalCalls = [...probe.calls.values()].reduce((a, b) => a + b, 0); assert.equal(totalCalls, 0, `retry must not touch the env AT ALL (saw: ${[...probe.calls.keys()].join(", ")})`); assert.equal(await store.canRestore("sc", "bL"), false); }); }); run("v1 permanence across reap: the pristine fallback outlives every boundary (b0-before-track ⇒ restore b0 walks back to pristine after later boundaries were reaped)", async () => { await withTree(async (dir, env) => { const store = make(); assert.deepEqual(await store.snapshot("sc", "b0", env, dir), { ok: true }); await writeFile(join(dir, "f.txt"), "pristine"); assert.deepEqual(await store.trackEdit("sc", join(dir, "f.txt"), env, dir), { ok: true, minted: true }); await writeFile(join(dir, "f.txt"), "edited"); assert.deepEqual(await store.snapshot("sc", "b1", env, dir), { ok: true }); assert.equal(await store.reap("sc", ["b0"]), 1); assert.equal(await store.canRestore("sc", "b1"), false); const r = await store.restore("sc", "b0", env, dir); assert.equal(r.outcome, "complete"); assert.equal(await readFile(join(dir, "f.txt"), "utf8"), "pristine"); }); }); run("deletion-marker round trip: a deleted tracked file revives at an earlier boundary; an agent-created file dies at a pre-creation boundary", async () => { await withTree(async (dir, env) => { const store = make(); await writeFile(join(dir, "keep.txt"), "keep-v1"); assert.deepEqual(await store.trackEdit("sc", join(dir, "keep.txt"), env, dir), { ok: true, minted: true }); assert.deepEqual(await store.trackEdit("sc", join(dir, "born.txt"), env, dir), { ok: true, minted: true }); assert.deepEqual(await store.snapshot("sc", "b1", env, dir), { ok: true }); await writeFile(join(dir, "born.txt"), "created"); await rm(join(dir, "keep.txt")); assert.deepEqual(await store.snapshot("sc", "b2", env, dir), { ok: true }); let r = await store.restore("sc", "b1", env, dir); assert.equal(r.outcome, "complete"); assert.equal(await readFile(join(dir, "keep.txt"), "utf8"), "keep-v1"); assert.equal(await readFile(join(dir, "born.txt"), "utf8").then(() => true, () => false), false); r = await store.restore("sc", "b2", env, dir); assert.equal(r.outcome, "complete"); assert.equal(await readFile(join(dir, "keep.txt"), "utf8").then(() => true, () => false), false); assert.equal(await readFile(join(dir, "born.txt"), "utf8"), "created"); }); }); run("adoptScope: same-scope no-op; adoption copies the graph; EMPTY-TARGET ONLY (typed conflict refusal, target intact)", async () => { await withTree(async (dir, env) => { const store = make(); await writeFile(join(dir, "f.txt"), "v1"); assert.deepEqual(await store.trackEdit("old", join(dir, "f.txt"), env, dir), { ok: true, minted: true }); await writeFile(join(dir, "f.txt"), "v2"); assert.deepEqual(await store.snapshot("old", "b", env, dir), { ok: true }); assert.deepEqual(await store.adoptScope("old", "old"), { ok: true }); assert.deepEqual(await store.adoptScope("old", "fresh"), { ok: true }); assert.equal(await store.canRestore("fresh", "b"), true); const busy = await store.adoptScope("old", "fresh"); assert.equal(busy.ok, false); if (!busy.ok) assert.equal(busy.error.code, "conflict"); assert.equal(await store.canRestore("fresh", "b"), true); }); }); run("structural out-of-scope (cowork guarantee) + T-1 positive control + G4 zero listDir: restore IO lands ONLY on tracked files, and no verb enumerates directories", async () => { await withTree(async (dir, env) => { const store = make(); await writeFile(join(dir, "tracked.txt"), "v1"); await writeFile(join(dir, "user-parallel.txt"), "user-work"); const probe = probeOver(env); assert.deepEqual(await store.trackEdit("sc", join(dir, "tracked.txt"), probe.env, dir), { ok: true, minted: true }); await writeFile(join(dir, "tracked.txt"), "v2"); assert.deepEqual(await store.snapshot("sc", "b", probe.env, dir), { ok: true }); await writeFile(join(dir, "tracked.txt"), "diverged"); await writeFile(join(dir, "user-new.txt"), "created-after-boundary"); const r = await store.restore("sc", "b", probe.env, dir); assert.equal(r.outcome, "complete"); assert.ok(probe.touched(join(dir, "tracked.txt")) > 0, "T-1 positive control: the tracked target must show IO in the SAME probe"); assert.equal(probe.touched(join(dir, "user-parallel.txt")), 0, "a user's parallel file must be structurally invisible"); assert.equal(probe.touched(join(dir, "user-new.txt")), 0, "a post-boundary user file must be structurally invisible"); assert.equal(probe.calls.get("listDir") ?? 0, 0, "G4: zero directory enumeration across every verb"); assert.equal(await readFile(join(dir, "tracked.txt"), "utf8"), "v2"); assert.equal(await readFile(join(dir, "user-parallel.txt"), "utf8"), "user-work"); }); }); run("annulTrack (#491): the caller's own mint is retractable with ZERO env IO and the path goes structurally invisible again; an absent record is idempotent-ok", async () => { await withTree(async (dir, env) => { const store = make(); await writeFile(join(dir, "anchor.txt"), "anchor-v1"); assert.deepEqual(await store.trackEdit("sc", join(dir, "anchor.txt"), env, dir), { ok: true, minted: true }); assert.deepEqual(await store.snapshot("sc", "b1", env, dir), { ok: true }); assert.deepEqual(await store.trackEdit("sc", join(dir, "never-written.txt"), env, dir), { ok: true, minted: true }); const probe = probeOver(env); assert.deepEqual(await store.annulTrack("sc", join(dir, "never-written.txt"), dir), { ok: true }); assert.equal([...probe.calls.values()].reduce((a, b) => a + b, 0), 0, "annulTrack without a verify env is a pure record discard — it must perform NO env IO"); assert.deepEqual(await store.annulTrack("sc", join(dir, "never-written.txt"), dir), { ok: true }, "annulling an absent record is idempotent-ok (the retry arm)"); await writeFile(join(dir, "never-written.txt"), "USER BYTES"); await writeFile(join(dir, "anchor.txt"), "anchor-edited"); const r = await store.restore("sc", "b1", env, dir); assert.equal(r.outcome, "complete"); assert.deepEqual(r.refused, []); assert.equal(await readFile(join(dir, "never-written.txt"), "utf8"), "USER BYTES", "the annulled path is structurally out of scope again — restore must not delete it"); assert.equal(r.filesChanged.some((p) => p.includes("never-written")), false, "an annulled path must not even appear in the ledger"); assert.equal(await readFile(join(dir, "anchor.txt"), "utf8"), "anchor-v1", "positive control: the genuinely tracked file DID converge in the same restore"); }); }); run("annulTrack EVIDENCE arm: with an env supplied, a path whose bytes moved since the mint keeps its record (deleting a modified file's only baseline is worse than a stale record); an unchanged path still retracts", async () => { await withTree(async (dir, env) => { const store = make(); await writeFile(join(dir, "moved.txt"), "pristine"); await writeFile(join(dir, "still.txt"), "pristine"); assert.deepEqual(await store.trackEdit("sc", join(dir, "moved.txt"), env, dir), { ok: true, minted: true }); assert.deepEqual(await store.trackEdit("sc", join(dir, "still.txt"), env, dir), { ok: true, minted: true }); await writeFile(join(dir, "moved.txt"), "half-written by the failing write"); const refused = await store.annulTrack("sc", join(dir, "moved.txt"), dir, { env }); assert.equal(refused.ok, false, "a changed file keeps its baseline"); if (!refused.ok) assert.equal(refused.error.code, "conflict"); assert.deepEqual(await store.annulTrack("sc", join(dir, "still.txt"), dir, { env }), { ok: true }); assert.deepEqual(await store.snapshot("sc", "b1", env, dir), { ok: true }); await writeFile(join(dir, "moved.txt"), "diverged"); await writeFile(join(dir, "still.txt"), "USER BYTES"); const r = await store.restore("sc", "b1", env, dir); assert.equal(await readFile(join(dir, "moved.txt"), "utf8"), "half-written by the failing write", "the kept record still protects the modified file"); assert.equal(await readFile(join(dir, "still.txt"), "utf8"), "USER BYTES", "the retracted one is structurally out of scope again"); assert.equal(r.outcome, "complete"); }); }); run("annulTrack EVIDENCE arm, base-unavailable case: the DV-14 marker is the refusal state itself, so an ambiguous retraction may not erase it (the PROVEN path still may)", async () => { await withTree(async (dir, env) => { const store = make(); assert.deepEqual(await store.snapshot("sc", "b0", env, dir), { ok: true }); await writeFile(join(dir, "opaque.txt"), "true-pristine"); await writeFile(join(dir, "opaque2.txt"), "true-pristine"); const hostile = envWithFailingRead(env, async () => ({ ok: false, error: { code: "unknown", message: "pristine unreadable" } })); const t = await store.trackEdit("sc", join(dir, "opaque.txt"), hostile, dir); if (t.ok === false) return; const refused = await store.annulTrack("sc", join(dir, "opaque.txt"), dir, { env }); assert.equal(refused.ok, false, "an ambiguous retraction must not erase a base-unavailable marker"); if (!refused.ok) assert.equal(refused.error.code, "conflict"); const t2 = await store.trackEdit("sc", join(dir, "opaque2.txt"), hostile, dir); if (t2.ok) assert.deepEqual(await store.annulTrack("sc", join(dir, "opaque2.txt"), dir), { ok: true }); await writeFile(join(dir, "opaque.txt"), "agent-edited"); const r = await store.restore("sc", "b0", env, dir); assert.equal(r.refused.some((f) => f.reason.includes("base_unavailable")), true, `the kept marker must still refuse a below-base restore: ${JSON.stringify(r)}`); assert.equal(await readFile(join(dir, "opaque.txt"), "utf8"), "agent-edited", "never overwritten with a fake baseline"); }); }); run("annulTrack refuses what is no longer a mint: a boundary-referenced record is history (typed conflict, record intact)", async () => { await withTree(async (dir, env) => { const store = make(); await writeFile(join(dir, "f.txt"), "pristine"); assert.deepEqual(await store.trackEdit("sc", join(dir, "f.txt"), env, dir), { ok: true, minted: true }); assert.deepEqual(await store.snapshot("sc", "b1", env, dir), { ok: true }); const busy = await store.annulTrack("sc", join(dir, "f.txt"), dir); assert.equal(busy.ok, false, "a record a committed boundary references is not the caller's to withdraw"); if (!busy.ok) assert.equal(busy.error.code, "conflict"); await writeFile(join(dir, "f.txt"), "diverged"); const r = await store.restore("sc", "b1", env, dir); assert.equal(r.outcome, "complete"); assert.equal(await readFile(join(dir, "f.txt"), "utf8"), "pristine", "the refusal left the record fully intact"); }); }); run("never-throw against a hostile env: a rejecting readBinaryFile yields typed results on every verb, never an exception", async () => { await withTree(async (dir, env) => { const store = make(); await writeFile(join(dir, "f.txt"), "v1"); const hostile = envWithFailingRead(env, async () => { throw new Error("hostile env rejection"); }); const t = await store.trackEdit("sc", join(dir, "f.txt"), hostile, dir); assert.equal(typeof t.ok, "boolean"); const sHealthy = await store.trackEdit("sc2", join(dir, "f.txt"), env, dir); assert.deepEqual(sHealthy, { ok: true, minted: true }); const snap = await store.snapshot("sc2", "b", hostile, dir); assert.equal(snap.ok, false); const r = await store.restore("sc2", "nope", hostile, dir); assert.equal(r.outcome, "failed"); }); }); run("DV-14 marker honesty: a backend that TOLERATES an uncapturable pristine (trackEdit ok despite a hostile read) must REFUSE a below-base restore for that path — never silently omit it, never overwrite with a fake baseline", async () => { await withTree(async (dir, env) => { const store = make(); assert.deepEqual(await store.snapshot("sc", "b0", env, dir), { ok: true }); await writeFile(join(dir, "f.txt"), "true-pristine"); const hostile = envWithFailingRead(env, async () => ({ ok: false, error: { code: "unknown", message: "pristine unreadable" } })); const t = await store.trackEdit("sc", join(dir, "f.txt"), hostile, dir); if (t.ok === false) return; await writeFile(join(dir, "f.txt"), "agent-edited"); const r = await store.restore("sc", "b0", env, dir); assert.equal(r.outcome, "partial", "a below-base path must surface as a REFUSAL, not fold into complete"); assert.equal(r.refused.some((f) => f.reason.includes("base_unavailable")), true, "the refusal must name base_unavailable"); assert.equal(await readFile(join(dir, "f.txt"), "utf8"), "agent-edited"); }); }); run("track-key COORDINATE (A-082 idx5): an under-root capture re-joins against the CURRENT root (a legal whole-root move still restores, and the OLD root is not written), while an outside-root path is recorded verbatim-absolute and restores in place", async () => { await withTree(async (dirA, envA) => { await withTree(async (dirB) => { await withTree(async (outside, _envOut) => { void _envOut; const store = make(); const outsideFile = join(outside, "o.txt"); await mkdir(join(dirA, "sub"), { recursive: true }); await writeFile(join(dirA, "sub", "f.txt"), "P-under-root"); await writeFile(outsideFile, "P-outside-root"); assert.deepEqual(await store.trackEdit("sc", join(dirA, "sub", "f.txt"), envA, dirA), { ok: true, minted: true }); assert.deepEqual(await store.trackEdit("sc", outsideFile, envA, dirA), { ok: true, minted: true }); assert.deepEqual(await store.snapshot("sc", "b1", envA, dirA), { ok: true }); await writeFile(join(dirA, "sub", "f.txt"), "EDITED"); await writeFile(outsideFile, "EDITED"); await mkdir(join(dirB, "sub"), { recursive: true }); await writeFile(join(dirB, "sub", "f.txt"), "EDITED"); const envB = new NodeExecutionEnv({ cwd: dirB }); const r = await store.restore("sc", "b1", envB, dirB); assert.equal(r.outcome, "complete", `moved-root restore must converge, got ${JSON.stringify(r)}`); assert.equal(await readFile(join(dirB, "sub", "f.txt"), "utf8"), "P-under-root", "the under-root key must re-join against the CURRENT root"); assert.equal(await readFile(join(dirA, "sub", "f.txt"), "utf8"), "EDITED", "the OLD root must not be written (the key was rel, not absolute)"); assert.equal(await readFile(outsideFile, "utf8"), "P-outside-root", "an outside-root key is verbatim-absolute — it restores where it was captured, root move or not"); }); }); }); }); run("export/import round trip AFTER a reap: the complete retained state travels (v1 fallbacks, parent guards, key self-description) and the importing scope serves BOTH a boundary restore and the pristine fallback", async () => { await withTree(async (dir, env) => { const src = make(); if (src.exportHistory === undefined || src.importHistory === undefined) return; const shed = contentShed(); await shed.write(join(dir, "keep.txt"), "pristine"); assert.deepEqual(await src.snapshot("sc", "b0", env, dir), { ok: true }); assert.deepEqual(await src.trackEdit("sc", join(dir, "keep.txt"), env, dir), { ok: true, minted: true }); await shed.write(join(dir, "keep.txt"), "turn-1"); assert.deepEqual(await src.snapshot("sc", "b1", env, dir), { ok: true }); assert.equal(await src.reap("sc", ["b0", "b1"]), 0); const envelope = await src.exportHistory("sc"); assert.ok(envelope !== null, "a scope with history must export an envelope"); assert.equal(envelope.formatVersion, "file-history/1"); assert.ok(envelope.tracked.every((t) => (t.keyKind === "root-relative" || t.keyKind === "absolute") && (t.keyFamily === "posix" || t.keyFamily === "win")), "every tracked row must carry its key's self-description (kind + family) — a bare key cannot be judged after it crosses machines"); const dst = make(); const carried = await dst.importHistory("carried", envelope, shed.fetch); assert.deepEqual(carried, { ok: true }); assert.equal(await dst.canRestore("carried", "b1"), true); await writeFile(join(dir, "keep.txt"), "diverged"); const r1 = await dst.restore("carried", "b1", env, dir); assert.equal(r1.outcome, "complete", `imported boundary restore: ${JSON.stringify(r1)}`); assert.equal(await readFile(join(dir, "keep.txt"), "utf8"), "turn-1"); const r0 = await dst.restore("carried", "b0", env, dir); assert.equal(r0.outcome, "complete"); assert.equal(await readFile(join(dir, "keep.txt"), "utf8"), "pristine", "the v1 fallback travelled: a boundary that predates the track still restores pristine"); }); }); run("import door refuses, never coerces: a foreign formatVersion and an unknown key self-description are typed unsupported_format with NOTHING published", async () => { await withTree(async (_dir, env) => { void _dir; const store = make(); if (store.importHistory === undefined) return; const foreignEpoch = wireEnvelope({ formatVersion: "file-snapshot/1", tracked: [], boundaries: [] }); const v = await store.importHistory("sc", foreignEpoch, async () => undefined); assert.equal(v.ok, false); if (!v.ok) assert.equal(v.error.code, "unsupported_format"); const unknownFamily = wireEnvelope({ formatVersion: "file-history/1", tracked: [{ relOrAbsPath: "a.txt", keyKind: "root-relative", keyFamily: "vms", baseAvailable: true, versions: [{ version: 1, blobHash: null, backupTime: "t" }] }], boundaries: [{ entryId: "b1", files: [{ relOrAbsPath: "a.txt", version: 1 }] }], }); const f = await store.importHistory("sc", unknownFamily, async () => undefined); assert.equal(f.ok, false); if (!f.ok) assert.equal(f.error.code, "unsupported_format"); assert.equal(await store.canRestore("sc", "b1"), false, "a refused import must publish nothing at all"); const missingBlob = wireEnvelope({ formatVersion: "file-history/1", tracked: [{ relOrAbsPath: "a.txt", keyKind: "root-relative", keyFamily: "posix", baseAvailable: true, versions: [{ version: 1, blobHash: "a".repeat(64), backupTime: "t" }] }], boundaries: [{ entryId: "b2", files: [{ relOrAbsPath: "a.txt", version: 1 }] }], }); const m = await store.importHistory("sc", missingBlob, async () => undefined); assert.equal(m.ok, false); assert.equal(await store.canRestore("sc", "b2"), false); const duplicated = wireEnvelope({ formatVersion: "file-history/1", tracked: [ { relOrAbsPath: "dup.txt", keyKind: "root-relative", keyFamily: "posix", baseAvailable: true, versions: [{ version: 1, blobHash: null, backupTime: "t" }] }, { relOrAbsPath: "dup.txt", keyKind: "root-relative", keyFamily: "posix", baseAvailable: true, versions: [{ version: 1, blobHash: null, backupTime: "t" }, { version: 2, blobHash: null, backupTime: "t" }] }, ], boundaries: [{ entryId: "b3", files: [{ relOrAbsPath: "dup.txt", version: 1 }] }], }); const outOfOrder = wireEnvelope({ formatVersion: "file-history/1", tracked: [ { relOrAbsPath: "ooo.txt", keyKind: "root-relative", keyFamily: "posix", baseAvailable: true, versions: [ { version: 1, blobHash: null, backupTime: "t" }, { version: 3, blobHash: null, backupTime: "t" }, { version: 2, blobHash: null, backupTime: "t" }, ], }, ], boundaries: [{ entryId: "b4", files: [{ relOrAbsPath: "ooo.txt", version: 1 }] }], }); const o = await store.importHistory("sc", outOfOrder, async () => undefined); assert.equal(o.ok, false, "an out-of-order version chain must be refused — a later local boundary would reference an ambiguous version"); if (!o.ok) assert.match(o.error.message, /strictly increasing/); assert.equal(await store.canRestore("sc", "b4"), false); const d = await store.importHistory("sc", duplicated, async () => undefined); assert.equal(d.ok, false, "duplicate tracked rows must be refused — the published graph would differ from the validated one"); if (!d.ok) assert.match(d.error.message, /twice/); assert.equal(await store.canRestore("sc", "b3"), false); void env; }); }); run("import AUTHORITY BOUND: an envelope may not carry an absolute key or an escaping relative one — a graph that would grant restore authority over a path outside the importing root publishes NOTHING", async () => { await withTree(async (dir, env) => { const store = make(); if (store.importHistory === undefined) return; const outsideVictim = join(dir, "victim-outside.txt"); await writeFile(outsideVictim, "not the agent's file"); const absolutePayload = wireEnvelope({ formatVersion: "file-history/1", tracked: [{ relOrAbsPath: outsideVictim, keyKind: "absolute", keyFamily: "posix", baseAvailable: true, versions: [{ version: 1, blobHash: null, backupTime: "t" }] }], boundaries: [{ entryId: "bA", files: [{ relOrAbsPath: outsideVictim, version: 1 }] }], }); const a = await store.importHistory("hostile", absolutePayload, async () => undefined); assert.equal(a.ok, false, "an absolute imported key must be refused at the door"); if (!a.ok) { assert.equal(a.error.code, "unsupported_format"); assert.match(a.error.message, /ABSOLUTE key/, `the refusal must name the authority bound: ${a.error.message}`); } const escaping = wireEnvelope({ formatVersion: "file-history/1", tracked: [{ relOrAbsPath: "../escape.txt", keyKind: "root-relative", keyFamily: "posix", baseAvailable: true, versions: [{ version: 1, blobHash: null, backupTime: "t" }] }], boundaries: [{ entryId: "bB", files: [{ relOrAbsPath: "../escape.txt", version: 1 }] }], }); const b = await store.importHistory("hostile", escaping, async () => undefined); assert.equal(b.ok, false, "a '..' relative key must be refused at the door, not per-file at restore"); assert.equal(await store.canRestore("hostile", "bA"), false); assert.equal(await store.canRestore("hostile", "bB"), false); const r = await store.restore("hostile", "bA", env, dir); assert.equal(r.outcome, "failed"); assert.equal(await readFile(outsideVictim, "utf8"), "not the agent's file", "the victim path was never in reach"); }); }); run("annulTrack refuses a mint ANOTHER lane is already relying on: two edits race one path, the first fails its write, and the second's baseline survives", async () => { await withTree(async (dir, env) => { const store = make(); await writeFile(join(dir, "contended.txt"), "pristine"); assert.deepEqual(await store.trackEdit("sc", join(dir, "contended.txt"), env, dir), { ok: true, minted: true }); assert.deepEqual(await store.trackEdit("sc", join(dir, "contended.txt"), env, dir), { ok: true, minted: false }); await writeFile(join(dir, "contended.txt"), "B's edit landed"); const annul = await store.annulTrack("sc", join(dir, "contended.txt"), dir); assert.equal(annul.ok, false, "a record another lane was served is no longer the minter's to retract"); if (!annul.ok) assert.equal(annul.error.code, "conflict"); assert.deepEqual(await store.snapshot("sc", "b1", env, dir), { ok: true }); assert.deepEqual(await store.trackEdit("sc", join(dir, "contended.txt"), env, dir), { ok: true, minted: false }); const r = await store.restore("sc", "b1", env, dir); assert.equal(r.outcome, "complete"); assert.equal(await readFile(join(dir, "contended.txt"), "utf8"), "B's edit landed"); }); }); run("import NON-DESTRUCTIVE target law: the identical envelope re-imports idempotently, while a DIFFERENT graph over locally-grown history is refused typed and the target survives intact", async () => { await withTree(async (dir, env) => { const src = make(); if (src.exportHistory === undefined || src.importHistory === undefined) return; const shed = contentShed(); await shed.write(join(dir, "f.txt"), "source-pristine"); assert.deepEqual(await src.trackEdit("sc", join(dir, "f.txt"), env, dir), { ok: true, minted: true }); assert.deepEqual(await src.snapshot("sc", "b1", env, dir), { ok: true }); const envelope = (await src.exportHistory("sc")); const dst = make(); assert.deepEqual(await dst.importHistory("target", envelope, shed.fetch), { ok: true }); assert.deepEqual(await dst.importHistory("target", envelope, shed.fetch), { ok: true }, "the same envelope arriving twice is a re-publish, not a conflict"); await shed.write(join(dir, "local.txt"), "local-work"); assert.deepEqual(await dst.trackEdit("target", join(dir, "local.txt"), env, dir), { ok: true, minted: true }); assert.deepEqual(await dst.snapshot("target", "b-local", env, dir), { ok: true }); const other = await src.exportHistory("sc"); const conflict = await dst.importHistory("target", other, shed.fetch); assert.equal(conflict.ok, false); if (!conflict.ok) assert.equal(conflict.error.code, "conflict"); assert.equal(await dst.canRestore("target", "b-local"), true, "the refusal left the target's own history intact"); assert.equal(await dst.canRestore("target", "b1"), true); }); }); run("FOREIGN-FAMILY keys are refused at restore, not re-pointed at this machine's tree (the self-describing key's whole purpose)", async () => { await withTree(async (dir, env) => { const store = make(); if (store.importHistory === undefined) return; const foreign = wireEnvelope({ formatVersion: "file-history/1", tracked: [ { relOrAbsPath: "D:\\other\\machine\\x.txt", keyKind: "absolute", keyFamily: "win", baseAvailable: true, versions: [{ version: 1, blobHash: null, backupTime: "t" }] }, { relOrAbsPath: "sub\\deep.txt", keyKind: "root-relative", keyFamily: "win", baseAvailable: true, versions: [{ version: 1, blobHash: null, backupTime: "t" }] }, ], boundaries: [ { entryId: "bw", files: [ { relOrAbsPath: "D:\\other\\machine\\x.txt", version: 1 }, { relOrAbsPath: "sub\\deep.txt", version: 1 }, ], }, ], }); const imported = await store.importHistory("foreign", foreign, async () => undefined); if (!imported.ok) return; const r = await store.restore("foreign", "bw", env, dir); assert.equal(r.outcome, "partial", `foreign-family rows must surface as refusals: ${JSON.stringify(r)}`); assert.equal(r.refused.length, 2, "each foreign-family key is refused by name"); assert.ok(r.refused.every((f) => /foreign-family/.test(f.reason)), `the refusal must name the provenance mismatch: ${JSON.stringify(r.refused)}`); assert.deepEqual(r.filesChanged, [], "nothing under this root may be touched on behalf of a foreign-family record"); }); }); run("mode (DV-8): a recorded POSIX mode is restored with the bytes — including on a file the restore has to RE-CREATE", async () => { await withTree(async (dir, env) => { const store = make(); const script = join(dir, "run.sh"); await writeFile(script, "#!/bin/sh\necho v1\n"); await chmod(script, 0o755); assert.deepEqual(await store.trackEdit("sc", script, env, dir), { ok: true, minted: true }); assert.deepEqual(await store.snapshot("sc", "b1", env, dir), { ok: true }); const recorded = (await stat(script)).mode & 0o7777; if (recorded !== 0o755) return; await writeFile(script, "#!/bin/sh\necho edited\n"); await chmod(script, 0o644); const back = await store.restore("sc", "b1", env, dir); assert.equal(back.outcome, "complete", JSON.stringify(back)); assert.equal((await stat(script)).mode & 0o7777, 0o755, "the boundary's mode travels with its bytes"); await rm(script); const revived = await store.restore("sc", "b1", env, dir); assert.equal(revived.outcome, "complete", JSON.stringify(revived)); assert.equal((await stat(script)).mode & 0o7777, 0o755, "a re-created file gets the recorded mode, not the umask default"); assert.equal(revived.modeNotPreserved ?? 0, 0, "an env WITH the mode face reports nothing unpreserved"); }); }); run("mode (DV-8) honest degradation: an env without the optional setFileMode face restores the BYTES and DISCLOSES the unpreserved mode (never silently, never fatally)", async () => { await withTree(async (dir, env) => { const store = make(); const script = join(dir, "run.sh"); await writeFile(script, "v1"); await chmod(script, 0o755); assert.deepEqual(await store.trackEdit("sc", script, env, dir), { ok: true, minted: true }); assert.deepEqual(await store.snapshot("sc", "b1", env, dir), { ok: true }); if (((await stat(script)).mode & 0o7777) !== 0o755) return; await rm(script); const modeless = new Proxy(env, { get(target, prop, receiver) { if (prop === "setFileMode") return undefined; return Reflect.get(target, prop, receiver); }, }); const r = await store.restore("sc", "b1", modeless, dir); assert.equal(r.outcome, "complete", "a mode that cannot be applied is a disclosure, not a failure"); assert.deepEqual(r.filesChanged, [key(dir, script)], "the BYTES still converge"); assert.equal(r.modeNotPreserved, 1, "…and the count says so — the honest-absence law, in the ledger"); }); }); run("restore preflight (§7 E5/E4, slice 3): an in-root ancestor swapped for a link OUT of the root is REFUSED per file, a legal whole-root move still restores, and the rest of the set converges either way", async () => { await withTree(async (dir, env) => { const store = make(); const outside = await mkdtemp(join(tmpdir(), "fh-kit-outside-")); try { await mkdir(join(dir, "d"), { recursive: true }); await writeFile(join(dir, "d", "f.txt"), "pristine"); await writeFile(join(dir, "sibling.txt"), "sibling-pristine"); assert.deepEqual(await store.trackEdit("sc", join(dir, "d", "f.txt"), env, dir), { ok: true, minted: true }); assert.deepEqual(await store.trackEdit("sc", join(dir, "sibling.txt"), env, dir), { ok: true, minted: true }); assert.deepEqual(await store.snapshot("sc", "b1", env, dir), { ok: true }); await writeFile(join(dir, "d", "f.txt"), "agent-edited"); await writeFile(join(dir, "sibling.txt"), "agent-edited"); await writeFile(join(outside, "f.txt"), "OUTSIDE-UNTOUCHED"); await rm(join(dir, "d"), { recursive: true, force: true }); await symlink(outside, join(dir, "d"), "dir"); const r = await store.restore("sc", "b1", env, dir); assert.equal(r.outcome, "partial", JSON.stringify(r)); assert.deepEqual(r.refused.map((x) => x.path), [key(dir, join(dir, "d", "f.txt"))], "the swapped path — and ONLY it — is refused"); assert.equal(await readFile(join(outside, "f.txt"), "utf8"), "OUTSIDE-UNTOUCHED", "E5: zero writes outside the root"); assert.deepEqual(r.filesChanged, [key(dir, join(dir, "sibling.txt"))], "a security refusal never fails the whole restore"); } finally { await rm(outside, { recursive: true, force: true }); } }); await withTree(async (oldRoot, env) => { const store = make(); await mkdir(join(oldRoot, "d"), { recursive: true }); await writeFile(join(oldRoot, "d", "f.txt"), "pristine"); assert.deepEqual(await store.trackEdit("sc", join(oldRoot, "d", "f.txt"), env, oldRoot), { ok: true, minted: true }); assert.deepEqual(await store.snapshot("sc", "b1", env, oldRoot), { ok: true }); await withTree(async (newRoot, newEnv) => { await mkdir(join(newRoot, "d"), { recursive: true }); await writeFile(join(newRoot, "d", "f.txt"), "agent-edited"); const r = await store.restore("sc", "b1", newEnv, newRoot); assert.equal(r.outcome, "complete", `E4 must be green in the same breath as E5: ${JSON.stringify(r)}`); assert.equal(await readFile(join(newRoot, "d", "f.txt"), "utf8"), "pristine"); }); }); }); run("restore preflight (kind arm, G11): a target replaced by a LEAF SYMLINK or a DIRECTORY is refused by name and the link's own target is untouched", async () => { await withTree(async (dir, env) => { const store = make(); const outside = await mkdtemp(join(tmpdir(), "fh-kit-kind-")); try { await writeFile(join(dir, "leaf.txt"), "pristine-leaf"); await writeFile(join(dir, "dir.txt"), "pristine-dir"); assert.deepEqual(await store.trackEdit("sc", join(dir, "leaf.txt"), env, dir), { ok: true, minted: true }); assert.deepEqual(await store.trackEdit("sc", join(dir, "dir.txt"), env, dir), { ok: true, minted: true }); assert.deepEqual(await store.snapshot("sc", "b1", env, dir), { ok: true }); await writeFile(join(outside, "victim.txt"), "OUTSIDE-UNTOUCHED"); await rm(join(dir, "leaf.txt")); await symlink(join(outside, "victim.txt"), join(dir, "leaf.txt"), "file"); await rm(join(dir, "dir.txt")); await mkdir(join(dir, "dir.txt")); const r = await store.restore("sc", "b1", env, dir); assert.equal(r.outcome, "partial", JSON.stringify(r)); assert.equal(r.refused.length, 2, "both kind mismatches are refused, each by name"); assert.equal(await readFile(join(outside, "victim.txt"), "utf8"), "OUTSIDE-UNTOUCHED", "a leaf link is never written THROUGH"); assert.deepEqual(r.filesChanged, []); } finally { await rm(outside, { recursive: true, force: true }); } }); }); run("diffStats (A-2 two-state law): a real preview lists exactly the files a restore WOULD change with their line arithmetic, an already-converged tracked set is an EMPTY answer, and no boundary at all is NULL — never an empty object", async () => { await withTree(async (dir, env) => { const store = make(); if (store.diffStats === undefined) return; await writeFile(join(dir, "edited.txt"), "one\ntwo\nthree\n"); await writeFile(join(dir, "untouched.txt"), "same\n"); assert.deepEqual(await store.trackEdit("sc", join(dir, "edited.txt"), env, dir), { ok: true, minted: true }); assert.deepEqual(await store.trackEdit("sc", join(dir, "untouched.txt"), env, dir), { ok: true, minted: true }); assert.deepEqual(await store.snapshot("sc", "b1", env, dir), { ok: true }); assert.equal(await store.diffStats("sc", "no-such-boundary", env, dir), null); const quiet = await store.diffStats("sc", "b1", env, dir); assert.notEqual(quiet, null, "a boundary that exists must produce an answer, not an absence"); assert.deepEqual(quiet, { filesChanged: [], insertions: 0, deletions: 0 }); await writeFile(join(dir, "edited.txt"), "one\nTWO\nthree\nfour\n"); const preview = await store.diffStats("sc", "b1", env, dir); assert.notEqual(preview, null); assert.deepEqual(preview.filesChanged, [key(dir, join(dir, "edited.txt"))], "an unchanged tracked file is not a change"); assert.deepEqual({ insertions: preview.insertions, deletions: preview.deletions }, { insertions: 1, deletions: 2 }); const restored = await store.restore("sc", "b1", env, dir); assert.deepEqual(restored.filesChanged, preview.filesChanged); await chmod(join(dir, "edited.txt"), 0o600); if (((await stat(join(dir, "edited.txt"))).mode & 0o7777) !== 0o600) return; const modePreview = await store.diffStats("sc", "b1", env, dir); assert.notEqual(modePreview, null); assert.deepEqual(modePreview.filesChanged, [key(dir, join(dir, "edited.txt"))], "a mode-only restoration is a change the preview must list"); assert.deepEqual({ insertions: modePreview.insertions, deletions: modePreview.deletions }, { insertions: 0, deletions: 0 }, "…and it moves no lines"); const modeRestored = await store.restore("sc", "b1", env, dir); assert.deepEqual(modeRestored.filesChanged, modePreview.filesChanged, "preview and operation agree on the mode-only arm too"); }); }); await settle(); } function key(root, absPath) { return absPath.slice(root.length + 1).replace(/\\/g, "/"); } function contentShed() { const bytesOf = new Map(); return { async write(path, text) { const bytes = Buffer.from(text, "utf8"); bytesOf.set(createHash("sha256").update(bytes).digest("hex"), bytes); await writeFile(path, bytes); }, async fetch(hash) { return bytesOf.get(hash); }, }; }