Something went wrong. Try again.
Parametric learning in your code harness.
Something went wrong. Try again.
JavaScript
at letta-code
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450#!/usr/bin/env node// Unit tests for the pure helpers in lib/. These run without the pi binary,// so they catch regressions close to the source instead of only through the// end-to-end integration test.import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";import os from "node:os";import path from "node:path";import { countJsonlRows, flagOn, parseOptions, readJsonl, rel, shellSplit } from "../lib/cli.ts";import { buildForkPrompt, formatObservedListing, latestForkableRow, observedTurnText, redactSecrets, runMachineCli,} from "../lib/fork.ts";import { buildCorrectionPrompt, buildTaggedExampleRow, displayRowId, findRowById, newMachineRowId,} from "../lib/examples.ts";import { machineDataFile, machineProjectDataDir } from "../lib/storage.ts";import { isHarnessInjectedUserText, lastTaggedTurnFromLetta, lastUserTurnLettaMessages, recordsFromLettaMessages,} from "../lib/letta-trajectory.ts";import { applyAssistantRewrite, extractMessageText, isoTimestamp, lastTaggedTurn, lastUserTurnEntries, recordsFromSessionEntries, trajectoryToMessages,} from "../lib/trajectory.ts";import { formatMachineStatus, joinMachineStatusLine, resolveLastTurnStatus } from "../lib/statusline.ts";import { builtinTinkerChatModels, isTinkerNativeId, listTinkerChatModels } from "../lib/tinker-catalog.ts";
let checks = 0;function assert(condition, message) { if (!condition) throw new Error(message); checks++;}function eq(actual, expected, message) { const a = JSON.stringify(actual); const b = JSON.stringify(expected); assert(a === b, `${message}: expected ${b}, got ${a}`);}
// --- shellSplit ---eq(shellSplit(`--as "Go to Settings → Security."`), ["--as", "Go to Settings → Security."], "double-quoted value should keep spaces");eq(shellSplit("--note 'too terse'"), ["--note", "too terse"], "single-quoted value should keep spaces");eq(shellSplit("a\\ b c"), ["a b", "c"], "backslash should escape spaces");eq(shellSplit("it's 'fine'"), ["its fine"], "apostrophes open quoting, matching POSIX shell behavior");eq(shellSplit(""), [], "empty input should split to nothing");eq(shellSplit(" "), [], "whitespace-only input should split to nothing");
// --- parseOptions ---eq(parseOptions(["file.jsonl"]), { positional: ["file.jsonl"], options: {} }, "plain tokens are positional");eq(parseOptions(["--force"]), { positional: [], options: { force: true } }, "lone flag becomes true");eq(parseOptions(["--note", "too", "terse"]), { positional: ["terse"], options: { note: "too" } }, "flag consumes the next non-option token");eq(parseOptions(["--steps=20", "--next-flag"]), { positional: [], options: { steps: "20", "next-flag": true } }, "equals form and flag-followed-by-flag");eq(parseOptions(["--trace", "why", "--reasoning"]), { positional: [], options: { trace: "why", reasoning: true } }, "a flag consumes the next non-option token, even as a stray value");
// --- flagOn ---eq(flagOn({ trace: true }, "trace"), { on: true }, "true value is on");eq(flagOn({ trace: "false" }, "trace"), { on: false }, "string false is off");eq(flagOn({ trace: "why" }, "trace"), { on: true, leftover: "why" }, "stray value is returned as leftover");eq(flagOn({}, "trace"), { on: false }, "missing value is off");
// --- rel ---eq(rel("/a/b", "/a/b/c/train.jsonl"), "c/train.jsonl", "paths under cwd are relative");eq(rel("/a/b", "/elsewhere/train.jsonl"), "/elsewhere/train.jsonl", "paths outside cwd are absolute");
// --- readJsonl / countJsonlRows ---const tmp = mkdtempSync(path.join(os.tmpdir(), "machine-unit-"));const jsonl = path.join(tmp, "rows.jsonl");writeFileSync(jsonl, [ JSON.stringify({ n: 1 }), "", JSON.stringify({ n: 2 }), "not json {", JSON.stringify({ n: 3 }), "",].join("\n") + "\n");eq(readJsonl(jsonl).map((r) => r.n), [1, 2, 3], "corrupt lines are skipped, not fatal");eq(readJsonl(path.join(tmp, "missing.jsonl")), [], "missing files read as empty");assert(countJsonlRows(jsonl) === 4, "row counts should not require parseable JSON");
// --- extractMessageText ---eq(extractMessageText("plain"), "plain", "string content passes through");eq(extractMessageText([{ type: "text", text: "a" }, { type: "thinking", thinking: "b" }, { type: "text", text: "c" }]), "a\nc", "only text blocks are joined");eq(extractMessageText([{ type: "toolCall", name: "bash" }]), "", "non-text blocks contribute nothing");eq(extractMessageText(undefined), "", "missing content is empty");eq(extractMessageText({ text: "nested" }), "nested", "object text fields unwrap");
// --- isoTimestamp ---eq(isoTimestamp("2026-01-01T00:00:01.000Z"), "2026-01-01T00:00:01.000Z", "ISO strings normalize");eq(isoTimestamp(2), "1970-01-01T00:00:00.002Z", "numeric epochs (milliseconds) normalize");eq(isoTimestamp("garbage", "fallback"), "fallback", "unparseable values fall back");assert(isoTimestamp(undefined).endsWith("Z"), "missing timestamps default to now");
// --- session fixtures (same shape as real session JSONL) ---const session = [ { type: "session", id: "s", timestamp: "2026-01-01T00:00:00.000Z" }, { type: "message", id: "u1", timestamp: "2026-01-01T00:00:01.000Z", message: { role: "user", content: [{ type: "text", text: "How do I reset my password?" }], timestamp: 1 } }, { type: "message", id: "a1", timestamp: "2026-01-01T00:00:02.000Z", message: { role: "assistant", content: [{ type: "thinking", thinking: "Check docs." }, { type: "text", text: "Checking." }, { type: "toolCall", id: "call_1", name: "bash", arguments: { command: "which julia" } }], timestamp: 2 } }, { type: "message", id: "t1", timestamp: "2026-01-01T00:00:03.000Z", message: { role: "toolResult", toolCallId: "call_1", content: [{ type: "text", text: "/usr/bin/julia" }], isError: false, timestamp: 3 } }, { type: "message", id: "a2", timestamp: "2026-01-01T00:00:04.000Z", message: { role: "assistant", content: [{ type: "text", text: "Julia is installed." }], timestamp: 4 } },];
// --- lastTaggedTurn / lastUserTurnEntries ---eq(lastTaggedTurn(session), { userId: "u1", assistantId: "a2", user: "How do I reset my password?", assistant: "Julia is installed." }, "last user/assistant pair is found");eq(lastTaggedTurn([{ type: "message", id: "u1", message: { role: "user", content: "hi" } }]), undefined, "no pair without an assistant");eq(lastUserTurnEntries(session).map((e) => e.id), ["u1", "a1", "t1", "a2"], "the turn span starts at the last user message");
// --- recordsFromSessionEntries ---const records = recordsFromSessionEntries(session);eq(records.map((r) => [r.role, r.content === null ? "tool_calls" : typeof r.content === "string" ? "text" : "?"]), [ ["user", "text"], ["reasoning", "text"], ["assistant", "text"], ["assistant", "tool_calls"], ["tool", "text"], ["assistant", "text"],], "records preserve the full trajectory shape");const toolCallRecord = records.find((r) => r.role === "assistant" && r.content === null);eq(toolCallRecord.tool_calls, [{ id: "call_1", name: "bash", args: JSON.stringify({ command: "which julia" }) }], "tool call arguments are serialized to a JSON string");const toolRecord = records.find((r) => r.role === "tool");eq(toolRecord, { role: "tool", tool_call_id: "call_1", content: "/usr/bin/julia", timestamp: "2026-01-01T00:00:03.000Z" }, "tool results keep their call id and text");const failing = recordsFromSessionEntries([ { type: "message", id: "t2", timestamp: "2026-01-01T00:00:05.000Z", message: { role: "toolResult", toolCallId: "call_1", content: [{ type: "text", text: "boom" }], isError: true, timestamp: 5 } },]);assert(failing[0].content.startsWith("Error:"), "error tool results are prefixed");eq(recordsFromSessionEntries([{ type: "message", id: "u9", message: { role: "user", content: [{ type: "text", text: "/machine data" }], timestamp: 9 } }]).length, 1, "slash commands are still user records");
// --- applyAssistantRewrite ---const rewritten = applyAssistantRewrite(records, "Rewritten answer.");assert(rewritten.at(-1).content === "Rewritten answer.", "the last assistant text is replaced");assert(rewritten.length === records.length && records.at(-1).content === "Julia is installed.", "the input records are not mutated");eq(applyAssistantRewrite(records, ""), records, "empty rewrites are no-ops");
// --- trajectoryToMessages ---const messages = trajectoryToMessages(records);const toolCallMessage = messages.find((m) => Array.isArray(m.tool_calls));eq(toolCallMessage, { role: "assistant", content: "", tool_calls: [{ id: "call_1", type: "function", function: { name: "bash", arguments: JSON.stringify({ command: "which julia" }) } }],}, "OpenAI-style tool_calls are emitted");eq(messages.find((m) => m.role === "tool"), { role: "tool", content: "/usr/bin/julia", tool_call_id: "call_1" }, "tool results become role:tool messages");assert(!messages.some((m) => m.role === "reasoning"), "reasoning is dropped from chat messages");eq(messages[0], { role: "user", content: "How do I reset my password?" }, "the opening user message is preserved");
// --- Letta Code getHistory() reconstruction ---const lettaHistory = [ { id: "u1", date: "2026-01-01T00:00:01.000Z", message_type: "user_message", content: [{ type: "text", text: "list files" }] }, { id: "r1", date: "2026-01-01T00:00:02.000Z", message_type: "reasoning_message", reasoning: "I should inspect the directory." }, { id: "t1", date: "2026-01-01T00:00:03.000Z", message_type: "approval_request_message", tool_call: { tool_call_id: "call_1", name: "Bash", arguments: "{\"command\":\"ls\"}" } }, { id: "tr1", date: "2026-01-01T00:00:04.000Z", message_type: "tool_return_message", tool_call_id: "call_1", tool_return: "README.md", status: "success" }, { id: "a1", date: "2026-01-01T00:00:05.000Z", message_type: "assistant_message", content: [{ type: "text", text: "There is a README." }] },];eq(lastTaggedTurnFromLetta(lettaHistory), { userId: "u1", assistantId: "a1", user: "list files", assistant: "There is a README." }, "Letta history finds the last user/assistant pair");eq(lastUserTurnLettaMessages(lettaHistory).map((m) => m.id), ["u1", "r1", "t1", "tr1", "a1"], "Letta turn span starts at the last user message");const lettaRecords = recordsFromLettaMessages(lettaHistory);eq(lettaRecords.map((r) => r.role), ["user", "reasoning", "assistant", "tool", "assistant"], "Letta records preserve the full trajectory shape");eq(lettaRecords[2].tool_calls, [{ id: "call_1", name: "Bash", args: "{\"command\":\"ls\"}" }], "Letta approval_request_message becomes a tool-call record");eq(lettaRecords[3], { role: "tool", tool_call_id: "call_1", content: "README.md", timestamp: "2026-01-01T00:00:04.000Z" }, "Letta tool_return_message becomes a tool record");assert(isHarnessInjectedUserText("<task-notification>\n<task-id>task_5</task-id>"), "task notifications are harness-injected");assert(isHarnessInjectedUserText("<system-reminder>\nThis is an automated message"), "system reminders are harness-injected");assert(!isHarnessInjectedUserText("list files"), "ordinary user text is not harness-injected");const lettaHistoryWithNotification = [ { id: "u0", date: "2026-01-01T00:00:00.000Z", message_type: "user_message", content: "review the release" }, { id: "a0", date: "2026-01-01T00:00:00.500Z", message_type: "assistant_message", content: "I will review it." }, { id: "uN", date: "2026-01-01T00:00:06.000Z", message_type: "user_message", content: "<task-notification>\n<task-id>task_5</task-id>\n<summary>Agent completed</summary>" }, { id: "aN", date: "2026-01-01T00:00:07.000Z", message_type: "assistant_message", content: "The review is done." },];eq(lastTaggedTurnFromLetta(lettaHistoryWithNotification), { userId: "u0", assistantId: "aN", user: "review the release", assistant: "The review is done." }, "Letta last turn skips task-notification user rows");eq(lastUserTurnLettaMessages(lettaHistoryWithNotification).map((m) => m.id), ["u0", "a0", "uN", "aN"], "Letta turn span starts at the last real user message");
// --- SFT scaffold contract ---// The /train sft scaffold is rendered by string substitution: each host// (extensions/train.ts for Pi, mods/machine.ts for Letta) passes a fixed// replacement set to templates/train_sft.py. These checks pin the three// sides together so a new template placeholder cannot ship without both// hosts substituting it (the original num_epochs bug, inverted).import { readFileSync } from "node:fs";const repoRoot = path.resolve(import.meta.dirname, "..");const templatePath = path.join(repoRoot, "templates", "train_sft.py");const template = readFileSync(templatePath, "utf8");const templatePlaceholders = [...new Set([...template.matchAll(/__[A-Z_]+__/g)].map((m) => m[0]))].sort();
function renderKeysFor(hostFile) { const source = readFileSync(path.join(repoRoot, hostFile), "utf8"); const match = source.match(/renderTemplate\(\s*"train_sft\.py"\s*,\s*\{([\s\S]*?)\}\s*\)/); assert(match, `${hostFile} should call renderTemplate("train_sft.py", {...})`); return [...new Set([...match[1].matchAll(/__[A-Z_]+__/g)].map((m) => m[0]))].sort();}
eq(templatePlaceholders.length >= 8, true, "train_sft template should have its expected placeholders");eq(renderKeysFor("extensions/train.ts"), templatePlaceholders, "Pi /train sft substitutes exactly the template placeholders");eq(renderKeysFor("mods/machine.ts"), templatePlaceholders, "Letta /train sft substitutes exactly the template placeholders");assert(readFileSync(path.join(repoRoot, "extensions", "train.ts"), "utf8").includes("num_epochs: ${numEpochs}"), "Pi tinker.yaml should record num_epochs");assert(readFileSync(path.join(repoRoot, "mods", "machine.ts"), "utf8").includes("num_epochs: ${numEpochs}"), "Letta tinker.yaml should record num_epochs");
// Smoke-render the template the way both hosts do and require a clean result.const replacements = Object.fromEntries(templatePlaceholders.map((key) => [key, { __MODEL__: '"m"', __MAX_LENGTH__: "32768", __BATCH_SIZE__: "8", __DATA_FILE__: '"d.jsonl"', __TEST_SIZE__: "0", __LOG_PATH__: '"logs/x"', __LEARNING_RATE__: "2e-4", __NUM_EPOCHS__: "10", __MAX_STEPS__: "60" }[key]]));let smokeRendered = template;for (const [key, value] of Object.entries(replacements)) smokeRendered = smokeRendered.replaceAll(key, value);eq(/[A-Z]__[A-Z_]+__|__[A-Z_]+__/.test(smokeRendered), false, "rendered scaffold should contain no unsubstituted placeholders");assert(smokeRendered.includes('"num_epochs": 10,'), "rendered scaffold should carry the requested epoch count");
// --- statusline ---function statusText(input) { return joinMachineStatusLine(formatMachineStatus(input), (_tone, text) => text);}const noTurn = { state: "none" };eq(statusText({ autoTrace: false, student: false, lastTurn: noTurn, train: 0, observed: 0 }), undefined, "empty state hides the footer");eq(statusText({ autoTrace: false, student: false, lastTurn: noTurn, train: 3, observed: 0 }), "⚙ 3 train", "quiet train count when nothing else is pending");eq(statusText({ autoTrace: true, student: false, lastTurn: noTurn, train: 3, observed: 4 }), "⚙ auto · 3 train · 4 obs", "auto headline plus quiet counts");eq(statusText({ autoTrace: true, student: false, lastTurn: { state: "untagged" }, train: 3, observed: 0 }), "⚙ last turn untagged · 3 train", "untagged last turn wins over auto");eq(statusText({ autoTrace: false, student: false, lastTurn: { state: "good" }, train: 4, observed: 0 }), "⚙ last: good · 4 train", "just-tagged good example");eq(statusText({ autoTrace: false, student: false, lastTurn: { state: "good", trace: true }, train: 4, observed: 0 }), "⚙ last: good trace · 4 train", "just-tagged good trace");eq(statusText({ autoTrace: false, student: false, lastTurn: { state: "rejected" }, train: 3, observed: 0 }), "⚙ last: rejected · 3 train", "just-tagged rejected example");eq(statusText({ autoTrace: true, student: true, lastTurn: noTurn, train: 3, observed: 4 }), "⚙ student · 3 train · 4 obs", "student lane wins over auto");eq(statusText({ autoTrace: false, student: true, lastTurn: noTurn, train: 0, observed: 0 }), "⚙ student", "student lane alone is still worth showing");eq(statusText({ autoTrace: true, student: false, lastTurn: noTurn, train: 0, observed: 0 }), "⚙ auto", "auto alone is still worth showing");eq(statusText({ autoTrace: false, student: false, lastTurn: { state: "untagged" }, train: 0, observed: 4 }), "⚙ last turn untagged · 4 obs", "untagged with only observed rows");eq(resolveLastTurnStatus({ hasTurn: false }), { state: "none" }, "no turn means no last-turn headline");eq(resolveLastTurnStatus({ hasTurn: true }), { state: "untagged" }, "a live turn without a judgment is untagged");eq(resolveLastTurnStatus({ hasTurn: true, label: "good" }), { state: "none" }, "a historical good label is not a just-tagged headline");eq(resolveLastTurnStatus({ hasTurn: true, assistantId: "a2", lastSave: { assistantId: "a2", tag: "good", trace: true } }), { state: "good", trace: true }, "a matching save is a just-tagged good trace");eq(resolveLastTurnStatus({ hasTurn: true, assistantId: "a2", lastSave: { assistantId: "a2", tag: "bad", trace: false } }), { state: "rejected" }, "a matching save is a just-tagged rejection");eq(resolveLastTurnStatus({ hasTurn: true, assistantId: "a3", lastSave: { assistantId: "a2", tag: "good", trace: true } }), { state: "untagged" }, "a save for an older turn does not cover a new one");eq(resolveLastTurnStatus({ hasTurn: true, assistantId: "a3", label: "good", lastSave: { assistantId: "a2", tag: "good", trace: true } }), { state: "none" }, "a labeled historical turn stays quiet");
// --- tinker catalog ---assert(isTinkerNativeId("Qwen/Qwen3.8-27B:peft:262144"), "Qwen ids are Tinker-native");assert(isTinkerNativeId("thinkingmachines/Inkling-Small"), "Inkling ids are Tinker-native");assert(isTinkerNativeId("tinker://abc/sampler_weights/final"), "checkpoint paths are Tinker-native");assert(!isTinkerNativeId("zai/glm-5.3"), "non-Tinker providers stay prefixed");const builtinIds = builtinTinkerChatModels().map((model) => model.id);assert(builtinIds.includes("Qwen/Qwen3.8-27B"), "catalog includes Qwen3.8-27B");assert(builtinIds.includes("Qwen/Qwen3.8-27B:peft:262144"), "catalog includes Qwen3.8-27B 256K");assert(builtinIds.includes("thinkingmachines/Inkling-Small:peft:262144"), "catalog includes Inkling-Small 256K");const withCheckpoint = listTinkerChatModels([{ id: "tinker://ckpt", name: "my-sft", contextWindow: 32768, maxTokens: 4096 }]);assert(withCheckpoint.some((model) => model.id === "tinker://ckpt"), "registered checkpoints join the chat catalog");
// --- row ids ---const generatedIds = new Set(Array.from({ length: 40 }, () => newMachineRowId()));assert(generatedIds.size === 40, "new row ids should be unique");assert([...generatedIds].every((id) => /^[0-9a-f]{12}$/.test(id)), "row ids are 12-character hex");eq(displayRowId({}), "(no id)", "missing id displays as (no id)");eq(displayRowId({ id: "c0ffee123456" }), "c0ffee123456", "present id is shown");const built = buildTaggedExampleRow({ tag: "observed", messages: [{ role: "user", content: "hi" }, { role: "assistant", content: "hello" }] });assert(typeof built.id === "string" && /^[0-9a-f]{12}$/.test(built.id), "new tagged rows get a stable id");eq(buildCorrectionPrompt("Write the helper", "use Julia"), "Write the helper\n\nCorrection: use Julia", "correction prompt is original turn plus correction");
// --- machine CLI / fork helpers ---eq( latestForkableRow([ { kind: "auto-compact", tag: "observed", messages: [{ role: "user", content: "old compact" }] }, { kind: "auto-headless", tag: "observed", messages: [{ role: "user", content: "headless" }] }, { kind: "auto-compact", tag: "observed", messages: [{ role: "user", content: "later compact" }] }, ])?.kind, "auto-headless", "fork prefers the latest auto-headless row over a later compact observation",);eq( observedTurnText({ messages: [ { role: "user", content: "first" }, { role: "assistant", content: "draft" }, { role: "user", content: "real request" }, { role: "assistant", content: [{ type: "text", text: "final answer" }] }, ], }), { user: "real request", assistant: "final answer" }, "fork uses the last user turn and last spoken assistant answer",);const forkPrompt = buildForkPrompt({ user: "Write the helper", assistant: "I rewrote the file.", correction: "use the existing helper", kind: "auto-headless", note: "auto headless (print)",});assert(forkPrompt.includes("Write the helper"), "fork prompt includes the original user turn");assert(forkPrompt.includes("I rewrote the file."), "fork prompt includes the previous assistant answer");assert(forkPrompt.includes("use the existing helper"), "fork prompt includes the correction");assert(forkPrompt.includes("not a /good example"), "fork prompt must not treat observed rows as /good");eq(redactSecrets("token=sk-abcdefghijklmnopqrstuvwxyz and api_key=secret-value"), "token=[redacted] and api_key=[redacted]", "observed listings redact secret-shaped tokens");
const previousDataDir = process.env.MACHINE_DATA_DIR;const cliTmp = mkdtempSync(path.join(os.tmpdir(), "machine-cli-"));const cliCwd = path.join(cliTmp, "demo");const cliStore = path.join(cliTmp, "store");mkdirSync(cliCwd, { recursive: true });process.env.MACHINE_DATA_DIR = cliStore;try {mkdirSync(machineProjectDataDir(cliCwd), { recursive: true, mode: 0o700 });writeFileSync( machineDataFile(cliCwd, "observed"), [ JSON.stringify({ timestamp: "2026-01-01T00:00:01.000Z", kind: "auto-compact", tag: "observed", note: "auto compact", messages: [{ role: "user", content: "older compact" }, { role: "assistant", content: "compact answer" }], }), JSON.stringify({ timestamp: "2026-01-01T00:00:02.000Z", kind: "auto-headless", tag: "observed", note: "auto headless (print)", messages: [ { role: "user", content: "Write the helper. token=sk-abcdefghijklmnopqrstuvwxyz" }, { role: "assistant", content: "I rewrote everything." }, ], }), ].join("\n") + "\n", { mode: 0o600 },);
async function captureCli(argv, extra = {}) { let out = ""; let err = ""; const code = await runMachineCli(argv, { cwd: cliCwd, env: { ...process.env, PATH: "" }, stdout: { write(chunk) { out += chunk; return true; } }, stderr: { write(chunk) { err += chunk; return true; } }, spawnPi: false, ...extra, }); return { code, out, err };}
const help = await captureCli(["help"]);assert(help.code === 0 && help.out.includes("machine fork"), "machine help lists fork");assert(help.out.includes("machine correction --id"), "machine help lists correction --id");const data = await captureCli(["data"]);assert(data.code === 0 && data.out.includes(machineProjectDataDir(cliCwd)), "machine data prints the project store");assert(data.out.includes("observed") && data.out.includes("2 rows"), "machine data counts observed rows");const observed = await captureCli(["observed"]);assert(observed.code === 0, "machine observed succeeds");assert(observed.out.includes("auto-headless"), "machine observed shows kind");assert(observed.out.includes("Write the helper"), "machine observed shows truncated user text");assert(!observed.out.includes("sk-abcdefghijklmnopqrstuvwxyz"), "machine observed does not print secrets");assert(!observed.out.includes("I rewrote everything"), "machine observed does not dump the assistant answer");assert(observed.out.includes("(no id)"), "machine observed shows (no id) for legacy rows");const listing = formatObservedListing(cliCwd, 1);assert(listing.includes("auto-headless") && !listing.includes("older compact"), "observed listing honors n");
const missingPi = await captureCli(["fork", "use", "the", "existing", "helper"], { spawnPi: undefined });assert(missingPi.code === 1, "machine fork exits 1 when pi is not on PATH");assert(missingPi.err.includes("use the existing helper"), "fallback prompt includes the correction");assert(missingPi.err.includes("MACHINE_FORK=1 pi -p"), "fallback prints the pi -p command");assert(missingPi.err.includes("does not write train.jsonl"), "fork must not treat observed rows as /good");
let spawned;const fakeSpawn = await captureCli(["fork", "use Julia"], { env: { ...process.env, PATH: "/usr/bin" }, spawnPi: async (request) => { spawned = request; return { code: 0, stdout: "ok", stderr: "" }; },});assert(fakeSpawn.code === 0, "machine fork succeeds when pi spawn is injected");assert(spawned?.env.MACHINE_FORK === "1", "child env sets MACHINE_FORK=1");assert(spawned?.prompt.includes("use Julia"), "spawned pi -p prompt includes the correction");assert(spawned?.cwd === cliCwd, "spawned pi -p uses process cwd");assert(!fakeSpawn.out.includes('"tag":"good"'), "fork does not write a /good row");
writeFileSync(machineDataFile(cliCwd, "observed"), [ JSON.stringify({ id: "obsid0000001", timestamp: "2026-01-01T00:00:03.000Z", kind: "auto-headless", tag: "observed", messages: [{ role: "user", content: "from observed" }, { role: "assistant", content: "obs answer" }], }),].join("\n") + "\n", { mode: 0o600 });writeFileSync(machineDataFile(cliCwd, "traces"), [ JSON.stringify({ id: "traceid000001", kind: "trace", tag: "good", messages: [{ role: "user", content: "from traces" }, { role: "assistant", content: "trace answer" }], }), JSON.stringify({ id: "sharedid00001", kind: "trace", tag: "good", messages: [{ role: "user", content: "from traces shared" }, { role: "assistant", content: "trace shared" }], }),].join("\n") + "\n", { mode: 0o600 });writeFileSync(machineDataFile(cliCwd, "train"), [ JSON.stringify({ id: "sharedid00001", kind: "final", tag: "good", messages: [{ role: "user", content: "from train shared" }, { role: "assistant", content: "train shared" }], }),].join("\n") + "\n", { mode: 0o600 });
eq(findRowById(cliCwd, "obsid0000001")?.kind, "observed", "lookup prefers observed.jsonl");eq(findRowById(cliCwd, "traceid000001")?.kind, "traces", "lookup falls through to traces.jsonl");eq(findRowById(cliCwd, "sharedid00001")?.kind, "traces", "duplicate ids resolve in observed/traces/train order");eq(findRowById(cliCwd, "missing"), undefined, "unknown ids are not found");
const observedWithId = await captureCli(["observed"]);assert(observedWithId.out.includes("obsid0000001"), "machine observed shows row ids when present");
const usage = await captureCli(["correction", "fix it"]);assert(usage.code === 2 && usage.err.includes("--id"), "correction without --id is a usage error");
const missingId = await captureCli(["correct", "--id", "nope", "fix it"]);assert(missingId.code === 1 && missingId.err.includes("nope"), "correction reports unknown ids");
const printed = await captureCli(["correction", "--id", "obsid0000001", "use Julia"], { spawnPi: false });assert(printed.code === 0, "correction prints the prompt when pi is not spawned");assert(printed.out.includes("from observed"), "printed correction includes the original turn");assert(printed.out.includes("Correction: use Julia"), "printed correction includes the correction");
let corrected;const correctionSpawn = await captureCli(["correct", "--id", "traceid000001", "keep the helper"], { env: { ...process.env, PATH: "/usr/bin" }, spawnPi: async (request) => { corrected = request; return { code: 0, stdout: "ok", stderr: "" }; },});assert(correctionSpawn.code === 0, "machine correct --id succeeds when pi spawn is injected");assert(corrected?.env.MACHINE_FORK === "1", "correction sets MACHINE_FORK=1");assert(corrected?.env.MACHINE_ROW_ID === "traceid000001", "correction sets MACHINE_ROW_ID");assert(corrected?.prompt.includes("from traces"), "correction prompt includes the original turn");assert(corrected?.prompt.includes("keep the helper"), "correction prompt includes the correction text");} finally {if (previousDataDir === undefined) delete process.env.MACHINE_DATA_DIR;else process.env.MACHINE_DATA_DIR = previousDataDir;}
console.log(`unit tests passed (${checks} checks)`);