Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ export {
type VerifiedRejectedPayload,
} from "./preference-admission.js";

export {
orderCheckpointReceipts,
readPrivateCheckpoint,
writePrivateCheckpoint,
type PrivateCheckpointRecord,
type PublicCheckpointReceipt,
} from "./private-checkpoint-cas.js";

export { compileTraceFoundry, createTraceReplayPlan, importTraceReviews, runTraceReplays } from "./trace-foundry.js";
export { serveTraceFoundry } from "./trace-foundry-server.js";
export { buildRejectionGuidance, classifyRejection, computeRecoveryOverJournals, computeRecoveryRates, loadGuidanceFile, readRolloutJournals, synthesizeMinimalExample } from "./rejection-guidance.js";
Expand Down
66 changes: 66 additions & 0 deletions src/private-checkpoint-cas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { createHash } from "node:crypto";
import { chmodSync, closeSync, mkdirSync, openSync, readFileSync, writeFileSync } from "node:fs";
import { join } from "node:path";

export type PrivateCheckpointRecord = {
checkpointId: string;
restorePath: string;
step: number;
metadata?: Record<string, string | number | boolean>;
};

export type PublicCheckpointReceipt = {
checkpointId: string;
restorePathSha256: string;
step: number;
};

function digest(value: string): string {
return createHash("sha256").update(value).digest("hex");
}

function privatePath(root: string, checkpointId: string): string {
return join(root, `${checkpointId}.json`);
}

export function writePrivateCheckpoint(
root: string,
record: PrivateCheckpointRecord,
): PublicCheckpointReceipt {
mkdirSync(root, { recursive: true, mode: 0o700 });
chmodSync(root, 0o700);
const payload = JSON.stringify(record);
const path = privatePath(root, record.checkpointId);
const fd = openSync(path, "wx", 0o600);
try {
writeFileSync(fd, payload, "utf8");
} finally {
closeSync(fd);
}
chmodSync(path, 0o600);
return {
checkpointId: record.checkpointId,
restorePathSha256: digest(record.restorePath),
step: record.step,
};
}

export function readPrivateCheckpoint(
root: string,
receipt: PublicCheckpointReceipt,
): PrivateCheckpointRecord {
const record = JSON.parse(readFileSync(privatePath(root, receipt.checkpointId), "utf8")) as PrivateCheckpointRecord;
if (record.checkpointId !== receipt.checkpointId || record.step !== receipt.step) {
throw new Error("private checkpoint identity mismatch");
}
if (digest(record.restorePath) !== receipt.restorePathSha256) {
throw new Error("private checkpoint restore-path hash mismatch");
}
return record;
}

export function orderCheckpointReceipts(
receipts: readonly PublicCheckpointReceipt[],
): PublicCheckpointReceipt[] {
return [...receipts].sort((left, right) => left.step - right.step);
}
47 changes: 47 additions & 0 deletions tests/private-checkpoint-cas.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import assert from "node:assert/strict";
import { mkdtempSync, readFileSync, rmSync, statSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { describe, it } from "node:test";

import {
orderCheckpointReceipts,
readPrivateCheckpoint,
writePrivateCheckpoint,
} from "../dist/private-checkpoint-cas.js";

describe("private checkpoint CAS", () => {
it("stores restore preimages privately while receipts expose hashes only", () => {
const root = mkdtempSync(join(tmpdir(), "understudy-checkpoint-cas-"));
try {
const receipt = writePrivateCheckpoint(root, {
checkpointId: "step-14",
restorePath: "tinker://private/opaque/step-14",
step: 14,
});
assert.equal(Object.hasOwn(receipt, "restorePath"), false);
assert.equal(readPrivateCheckpoint(root, receipt).restorePath, "tinker://private/opaque/step-14");
assert.equal(statSync(root).mode & 0o777, 0o700);
assert.equal(statSync(join(root, "step-14.json")).mode & 0o777, 0o600);
assert.equal(readFileSync(join(root, "step-14.json"), "utf8").includes(receipt.restorePathSha256), false);
} finally {
rmSync(root, { recursive: true, force: true });
}
});

it("supports zero-network ordered ladder resume and detects tampering", () => {
const root = mkdtempSync(join(tmpdir(), "understudy-checkpoint-ladder-"));
try {
const receipts = [1, 14, 25, 41].map((step) => writePrivateCheckpoint(root, {
checkpointId: `step-${step}`,
restorePath: `tinker://private/opaque/step-${step}`,
step,
}));
assert.deepEqual(orderCheckpointReceipts([...receipts].reverse()).map((item) => item.step), [1, 14, 25, 41]);
const tampered = { ...receipts[0], restorePathSha256: "0".repeat(64) };
assert.throws(() => readPrivateCheckpoint(root, tampered), /hash mismatch/);
} finally {
rmSync(root, { recursive: true, force: true });
}
});
});