Something went wrong. Try again.
snapcompact for prime agent
Something went wrong. Try again.
31 kB · 647 lines
JavaScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648import { pathToFileURL, fileURLToPath } from "node:url";import { createHash } from "node:crypto";import { existsSync, mkdirSync, mkdtempSync, readFileSync, renameSync, rmSync, symlinkSync, unlinkSync, writeFileSync,} from "node:fs";import { dirname, join, resolve } from "node:path";import { tmpdir } from "node:os";import { resolvePrimeRoot } from "./prime-root.mjs";
const primeRoot = resolvePrimeRoot();const { loadExtensions } = await import(pathToFileURL(join(primeRoot, "dist/core/extensions/loader.js")));const extensionPath = fileURLToPath(new URL("./integration-extension.ts", import.meta.url));const root = mkdtempSync(join(tmpdir(), "prime-snapcompact-integration-"));const sessionDir = `${root}/sessions/project`;mkdirSync(sessionDir, { recursive: true });let activeSessionId = "11111111-1111-4111-8111-111111111111";let activeSessionFile = `${sessionDir}/${activeSessionId}.jsonl`;writeFileSync(activeSessionFile, `${JSON.stringify({ type: "session", version: 3, id: activeSessionId, timestamp: new Date().toISOString(), cwd: process.cwd(),})}\n`);const model = { id: "gpt-5.2", name: "test vision model", api: "openai-responses", provider: "openai", baseUrl: "https://example.invalid", reasoning: true, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 272000, maxTokens: 16384,};const longText = "日本語の履歴と解析結果です。ファイルを確認しました。\n".repeat(6000);const usage = { input: 100, output: 100, cacheRead: 0, cacheWrite: 0, totalTokens: 200, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } };const toolResult = (id, text, isError = false) => ({ role: "toolResult", toolCallId: id, toolName: "ipython", content: [{ type: "text", text }], isError, timestamp: 2,});const oldestMaskedOutput = `oldest tool output ${"MASKED-SECRET".repeat(10_000)}`;const recentExactOutput = `recent exact output ${"z".repeat(3000)}`;const oldMessages = [ { role: "user", content: [ { type: "text", text: "inspect the repository" }, { type: "image", data: "raw-source-image", mimeType: "image/png" }, ], timestamp: 1, }, { role: "assistant", content: [ { type: "thinking", thinking: "private stale reasoning" }, { type: "text", text: longText }, ...["t1", "t2", "t3", "t4"].map((id) => ({ type: "toolCall", id, name: "ipython", arguments: { id, payload: id === "t4" ? "q".repeat(1200) : id }, })), ], api: model.api, provider: model.provider, model: model.id, usage, stopReason: "toolUse", timestamp: 2, }, toolResult("t1", oldestMaskedOutput), toolResult("t2", "second exact output </out> injected suffix"), toolResult("t3", "third exact output"), toolResult("t4", recentExactOutput, true), toolResult("orphan", "orphan output"),];const prep = (messages, previousSummary) => ({ firstKeptEntryId: "kept-entry", messagesToSummarize: messages, turnPrefixMessages: [], isSplitTurn: false, tokensBefore: 100000, previousSummary, fileOps: { read: new Set(["src/file.ts"]), written: new Set(), edited: new Set() }, settings: { enabled: true, reserveTokens: 16384, keepRecentTokens: 20000 },});const controller = new AbortController();let branch = [];const ctx = { cwd: process.cwd(), hasUI: false, ui: { notify() {} }, model: { ...model }, modelRegistry: { async getApiKeyAndHeaders() { return { ok: true, apiKey: "test-key" }; } }, sessionManager: { getSessionFile: () => activeSessionFile, getSessionDir: () => sessionDir, getSessionId: () => activeSessionId, getBranch: () => branch, getEntries: () => branch, }, getSystemPrompt: () => "test system prompt", compact: () => { throw new Error("context hook must not compact reentrantly"); },};
const loaded = await loadExtensions([extensionPath], process.cwd());if (loaded.errors.length) throw new Error(JSON.stringify(loaded.errors));loaded.runtime.getThinkingLevel = () => "medium";const extension = loaded.extensions[0];const before = extension.handlers.get("session_before_compact")[0];const context = extension.handlers.get("context")[0];const sessionStart = extension.handlers.get("session_start")[0];const sessionCompact = extension.handlers.get("session_compact")[0];
ctx.model = { ...model, input: ["text"] };const initialText = await before({ type: "session_before_compact", preparation: prep(oldMessages), branchEntries: [], customInstructions: undefined, signal: controller.signal }, ctx);if (!initialText?.compaction) throw new Error("initial text-only compaction did not use projected native compaction");ctx.model = { ...model, id: "claude-sonnet-4-5", api: "anthropic-messages", provider: "anthropic", input: ["text"],};const initialClaudeText = await before({ type: "session_before_compact", preparation: prep(oldMessages), branchEntries: [], customInstructions: undefined, signal: controller.signal }, ctx);if (!initialClaudeText?.compaction) { throw new Error("Claude text compaction did not use its reasoning-safe projection");}ctx.model = { ...ctx.model, input: ["text", "image"] };const initialClaudeVisual = await before({ type: "session_before_compact", preparation: prep(oldMessages), branchEntries: [], customInstructions: undefined, signal: controller.signal }, ctx);if ( !initialClaudeVisual?.compaction?.details?.snapcompact?.artifact || initialClaudeVisual.compaction.details.snapcompact.thinkingIncluded !== false) { throw new Error("Claude visual compaction did not record reasoning exclusion");}const initialClaudeRef = initialClaudeVisual.compaction.details.snapcompact.artifact;const initialClaudeArchive = JSON.parse( readFileSync(join(root, "sessions", "session-artifacts", activeSessionId, "snapcompact", initialClaudeRef.file), "utf8"),).preserveData.snapcompact;const initialClaudeArchiveText = [ initialClaudeArchive.text, initialClaudeArchive.textHead, initialClaudeArchive.textTail,].filter((value) => typeof value === "string").join("");if (initialClaudeArchiveText.includes("private stale reasoning")) { throw new Error("Claude visual compaction archived replayed reasoning");}ctx.model = { ...model };const initialCustom = await before({ type: "session_before_compact", preparation: prep(oldMessages), branchEntries: [], customInstructions: "focus on tests", signal: controller.signal }, ctx);if (!initialCustom?.compaction) throw new Error("initial custom-instruction compaction did not use projected native compaction");const originalWarn = console.warn;console.warn = () => {};process.env.PRIME_SNAPCOMPACT_BUN = "/definitely/missing/bun";const initialFailure = await before({ type: "session_before_compact", preparation: prep(oldMessages), branchEntries: [], customInstructions: undefined, signal: controller.signal }, ctx);delete process.env.PRIME_SNAPCOMPACT_BUN;console.warn = originalWarn;if (!initialFailure?.compaction) throw new Error("first worker failure did not use projected native compaction");
const abortedController = new AbortController();abortedController.abort();const aborted = await before({ type: "session_before_compact", preparation: prep(oldMessages), branchEntries: [], customInstructions: undefined, signal: abortedController.signal }, ctx);if (aborted?.cancel !== true) throw new Error("aborted visual compaction did not cancel");
const splitPreparation = { ...prep([{ role: "user", content: "split history", timestamp: 1 }]), turnPrefixMessages: [{ role: "user", content: "split turn prefix", timestamp: 2 }], isSplitTurn: true,};const split = await before({ type: "session_before_compact", preparation: splitPreparation, branchEntries: [], customInstructions: undefined, signal: controller.signal }, ctx);if (!split?.compaction?.details?.snapcompact?.artifact) throw new Error("split visual compaction failed");const splitRef = split.compaction.details.snapcompact.artifact;const splitText = JSON.parse( readFileSync(join(root, "sessions", "session-artifacts", activeSessionId, "snapcompact", splitRef.file), "utf8"),).preserveData.snapcompact.text ?? "";if (!splitText.includes("split history") || !splitText.includes("split turn prefix")) { throw new Error("split visual compaction lost a message group");}
const rawProjectionInput = JSON.stringify(oldMessages);const first = await before({ type: "session_before_compact", preparation: prep(oldMessages), branchEntries: branch, customInstructions: undefined, signal: controller.signal }, ctx);if (!first?.compaction?.details?.snapcompact?.artifact) throw new Error("first SnapCompact compaction missing artifact reference");if (JSON.stringify(oldMessages) !== rawProjectionInput) throw new Error("visual projection mutated raw messages");const detailsJson = JSON.stringify(first.compaction.details);if (Buffer.byteLength(detailsJson) >= 1024 * 1024) throw new Error("compaction details exceed Prime line safety limit");if (detailsJson.includes("iVBORw0KGgo")) throw new Error("PNG data leaked into compaction details");const ref1 = first.compaction.details.snapcompact.artifact;if (first.compaction.details.snapcompact.projectionVersion !== 3) { throw new Error("visual compaction did not record its projection version");}const firstArtifactPath = join( root, "sessions", "session-artifacts", activeSessionId, "snapcompact", ref1.file,);const firstArtifactData = readFileSync(firstArtifactPath);const firstArtifactDocument = JSON.parse(firstArtifactData.toString("utf8"));const firstArchive = firstArtifactDocument.preserveData.snapcompact;const firstArchiveText = firstArchive.text ?? "";if (!firstArchiveText.includes("private stale reasoning")) { throw new Error("archive lost compatible reasoning");}if (first.compaction.details.snapcompact.thinkingIncluded !== true) { throw new Error("archive did not record compatible reasoning retention");}if (firstArchiveText.includes("raw-source-image") || !firstArchiveText.includes("[image]")) { throw new Error("archive did not replace source image bytes");}if ( firstArchiveText.includes("oldest tool output") || firstArchiveText.includes("MASKED-SECRET") || !firstArchiveText.includes("[tool result]")) { throw new Error("archive did not mask the oldest tool result");}for (const exact of ["second exact output", "third exact output", recentExactOutput]) { if (!firstArchiveText.includes(exact)) throw new Error(`archive lost ${exact.slice(0, 24)}`);}if (!firstArchiveText.includes("q".repeat(1200))) throw new Error("archive truncated recent tool arguments");if (!firstArchiveText.includes("[tool result ipython#t4 error=true]")) { throw new Error("archive lost tool result identity or error state");}if (firstArchiveText.includes("orphan output")) throw new Error("archive retained an orphan result");const compactionEntry = { type: "compaction", id: "compaction-1", parentId: null, timestamp: Date.now(), summary: first.compaction.summary, firstKeptEntryId: first.compaction.firstKeptEntryId, tokensBefore: first.compaction.tokensBefore, details: first.compaction.details, fromHook: true,};branch = [compactionEntry, { type: "message", id: "recent-1", parentId: "compaction-1", timestamp: Date.now(), message: { role: "user", content: "continue", timestamp: Date.now() } }];const hydrated = await context({ type: "context", messages: [ { role: "compactionSummary", summary: first.compaction.summary, tokensBefore: first.compaction.tokensBefore, timestamp: Date.now() }, { role: "user", content: "continue", timestamp: Date.now() },]}, ctx);const visual = hydrated.messages[0];const images = visual.content.filter((block) => block.type === "image");if (visual.role !== "custom" || images.length < 1 || images.length > first.compaction.details.snapcompact.frameBudget) { throw new Error("vision context did not rehydrate within frame budget");}if (images.some((image) => image.detail !== "original")) { throw new Error("vision context dropped SnapCompact frame detail");}ctx.model = { ...model, id: "claude-sonnet-4-5", api: "anthropic-messages", provider: "anthropic", contextWindow: 1_000_000,};const claudeHydrated = await context({ type: "context", messages: [ { role: "compactionSummary", summary: first.compaction.summary, tokensBefore: first.compaction.tokensBefore, timestamp: Date.now() }, { role: "user", content: "continue with Claude", timestamp: Date.now() },]}, ctx);const claudeArchiveContent = claudeHydrated.messages[0].content;if (claudeArchiveContent.some((block) => block.type === "image")) { throw new Error("Claude received reasoning-bearing archive frames");}const claudeArchiveText = claudeArchiveContent .filter((block) => block.type === "text") .map((block) => block.text) .join("");if (claudeArchiveText.includes("private stale reasoning")) { throw new Error("Claude received archived reasoning as text");}if (!claudeArchiveText.includes("inspect the repository")) { throw new Error("Claude reasoning sanitization discarded the archive");}ctx.model = { ...model };const cachedContextEvent = { type: "context", messages: [ { role: "compactionSummary", summary: first.compaction.summary, tokensBefore: first.compaction.tokensBefore, timestamp: Date.now() }, { role: "user", content: "verify artifact path", timestamp: Date.now() }, ],};const artifactFileBackup = `${firstArtifactPath}.verified`;renameSync(firstArtifactPath, artifactFileBackup);symlinkSync(artifactFileBackup, firstArtifactPath);console.warn = () => {};let symlinkedFileContext;try { symlinkedFileContext = await context(cachedContextEvent, ctx);} finally { console.warn = originalWarn; unlinkSync(firstArtifactPath); renameSync(artifactFileBackup, firstArtifactPath);}if ( symlinkedFileContext?.messages[0]?.role !== "custom" || symlinkedFileContext.messages[0].customType !== "snapcompact-context-error") { throw new Error("cached artifact bypassed a no-follow file check");}if (!readFileSync(firstArtifactPath).equals(firstArtifactData)) { throw new Error("artifact file changed during no-follow verification");}
const artifactDirectoryPath = dirname(firstArtifactPath);const artifactDirectoryBackup = `${artifactDirectoryPath}-verified`;renameSync(artifactDirectoryPath, artifactDirectoryBackup);symlinkSync(artifactDirectoryBackup, artifactDirectoryPath);console.warn = () => {};let symlinkedDirectoryContext;try { symlinkedDirectoryContext = await context(cachedContextEvent, ctx);} finally { console.warn = originalWarn; unlinkSync(artifactDirectoryPath); renameSync(artifactDirectoryBackup, artifactDirectoryPath);}if ( symlinkedDirectoryContext?.messages[0]?.role !== "custom" || symlinkedDirectoryContext.messages[0].customType !== "snapcompact-context-error") { throw new Error("cached artifact bypassed a canonical directory check");}const retainedImageCount = 3;const withRetainedImages = await context({ type: "context", messages: [ { role: "compactionSummary", summary: first.compaction.summary, tokensBefore: first.compaction.tokensBefore, timestamp: Date.now() }, { role: "user", content: Array.from({ length: retainedImageCount }, (_, index) => ({ type: "image", data: `retained-${index}`, mimeType: "image/png", })), timestamp: Date.now(), },]}, ctx);const budgetedArchiveImages = withRetainedImages.messages[0].content.filter( (block) => block.type === "image",).length;const frozenArchiveImages = visual.content.filter((block) => block.type === "image").length;if (budgetedArchiveImages !== frozenArchiveImages) { throw new Error("retained tail images rewrote the archive prefix and busted prompt caching");}const projectedBranch = branch;const legacyArtifact = structuredClone(firstArtifactDocument);legacyArtifact.preserveData.snapcompact.text = [ "¶think:legacy private reasoning", "¶call:one()<out>█\u000elegacy result 1\u000f█</out>", "¶call:two()<out>█\u000elegacy result 2\u000f█</out>", "¶call:three()<out>█\u000elegacy result 3\u000f█</out>", "¶call:four()<out>█\u000elegacy result 4\u000f█</out>",].join("█");delete legacyArtifact.preserveData.snapcompact.textHead;delete legacyArtifact.preserveData.snapcompact.textTail;legacyArtifact.preserveData.snapcompact.truncatedChars = 0;const legacyData = JSON.stringify(legacyArtifact);const legacyFile = "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa.json";writeFileSync(join(firstArtifactPath, "..", legacyFile), legacyData, { mode: 0o600 });const legacyDetails = structuredClone(first.compaction.details);delete legacyDetails.snapcompact.projectionVersion;legacyDetails.snapcompact.artifact = { file: legacyFile, bytes: Buffer.byteLength(legacyData), sha256: createHash("sha256").update(legacyData).digest("hex"),};branch = [ { ...compactionEntry, id: "legacy-compaction", details: legacyDetails }, { type: "message", id: "legacy-recent", parentId: "legacy-compaction", timestamp: Date.now(), message: { role: "user", content: "continue legacy", timestamp: Date.now() } },];const legacyHydrated = await context({ type: "context", messages: [ { role: "compactionSummary", summary: first.compaction.summary, tokensBefore: first.compaction.tokensBefore, timestamp: Date.now() }, { role: "user", content: "continue legacy", timestamp: Date.now() },]}, ctx);if (legacyHydrated.messages[0].content.some((block) => block.type === "image")) { throw new Error("legacy unprojected archive replayed image frames");}const legacyText = legacyHydrated.messages[0].content .filter((block) => block.type === "text") .map((block) => block.text) .join("");if (legacyText.includes("legacy private reasoning") || legacyText.includes("legacy result 1")) { throw new Error("legacy archive text was not destructively sanitized");}for (const exact of ["legacy result 2", "legacy result 3", "legacy result 4"]) { if (!legacyText.includes(exact)) throw new Error(`legacy archive lost ${exact}`);}const truncatedLegacyArtifact = structuredClone(firstArtifactDocument);truncatedLegacyArtifact.preserveData.snapcompact.textHead = "¶user:verified legacy prefix█¶call:cut()<out>█\u000eTRUNCATED-LEGACY-SECRET";truncatedLegacyArtifact.preserveData.snapcompact.text = `${truncatedLegacyArtifact.preserveData.snapcompact.textHead}untrusted omitted middle`;truncatedLegacyArtifact.preserveData.snapcompact.truncatedChars = 1000;const truncatedLegacyData = JSON.stringify(truncatedLegacyArtifact);const truncatedLegacyFile = "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb.json";writeFileSync(join(firstArtifactPath, "..", truncatedLegacyFile), truncatedLegacyData, { mode: 0o600 });const truncatedLegacyDetails = structuredClone(legacyDetails);truncatedLegacyDetails.snapcompact.artifact = { file: truncatedLegacyFile, bytes: Buffer.byteLength(truncatedLegacyData), sha256: createHash("sha256").update(truncatedLegacyData).digest("hex"),};branch = [ { ...compactionEntry, id: "truncated-legacy-compaction", details: truncatedLegacyDetails }, { type: "message", id: "truncated-legacy-recent", parentId: "truncated-legacy-compaction", timestamp: Date.now(), message: { role: "user", content: "continue safely", timestamp: Date.now() } },];const truncatedLegacyHydrated = await context({ type: "context", messages: [ { role: "compactionSummary", summary: first.compaction.summary, tokensBefore: first.compaction.tokensBefore, timestamp: Date.now() }, { role: "user", content: "continue safely", timestamp: Date.now() },]}, ctx);const truncatedLegacyText = truncatedLegacyHydrated.messages[0].content .filter((block) => block.type === "text") .map((block) => block.text) .join("");if ( truncatedLegacyHydrated.messages[0].content.some((block) => block.type === "image") || truncatedLegacyText.includes("TRUNCATED-LEGACY-SECRET") || !truncatedLegacyText.includes("verified legacy prefix") || !truncatedLegacyText.includes("[tool result]")) { throw new Error("truncated legacy archive did not degrade to its sanitized head");}branch = projectedBranch;ctx.model = { ...model, id: "different-model-same-provider" };const switched = await context({ type: "context", messages: [ { role: "compactionSummary", summary: first.compaction.summary, tokensBefore: first.compaction.tokensBefore, timestamp: Date.now() }, { role: "user", content: "continue after model switch", timestamp: Date.now() },]}, ctx);const switchedImages = switched.messages[0].content.filter((block) => block.type === "image").length;if (switchedImages > 5) throw new Error("same-provider model switch reused an unsafe producer frame budget");// Frozen epoch layout: block bytes must not depend on the live window or the// growing tail. Every rehydration of the same archive must be byte-identical,// otherwise each change busts the prompt cache back to the system prefix.const blockSignature = (content) => createHash("sha256").update(JSON.stringify(content)).digest("hex");let frozenSignature = blockSignature(visual.content);for (let turn = 0; turn < 20; turn++) { ctx.model = turn % 2 === 0 ? { ...model, contextWindow: 10_000, maxTokens: 8192 } : { ...model }; const turnHydrated = await context({ type: "context", messages: [ { role: "compactionSummary", summary: first.compaction.summary, tokensBefore: first.compaction.tokensBefore, timestamp: Date.now() }, ...Array.from({ length: turn }, (_, i) => ({ role: "user", content: [ { type: "text", text: `tail ${i} ${longText.slice(0, 400)}` }, { type: "image", data: `tail-image-${i}`, mimeType: "image/png" }, ], timestamp: Date.now() + i, })), ]}, ctx); const signature = blockSignature(turnHydrated.messages[0].content); if (signature !== frozenSignature) { throw new Error(`vision archive blocks changed at tail step ${turn}; prompt cache would bust`); }}ctx.model = { ...model };ctx.model = { ...model, input: ["text"], contextWindow: 10_000, maxTokens: 8192 };const exhaustedText = await context({ type: "context", messages: [ { role: "compactionSummary", summary: first.compaction.summary, tokensBefore: first.compaction.tokensBefore, timestamp: Date.now() }, { role: "user", content: "text context is already full", timestamp: Date.now() },]}, ctx);if (exhaustedText.messages[0].content.length !== 1) { throw new Error("exhausted text context forced archive text past zero budget");}ctx.model = { ...model };
const previousSessionFile = activeSessionFile;const mismatchedSessionId = "77777777-7777-4777-8777-777777777777";activeSessionId = mismatchedSessionId;activeSessionFile = `${sessionDir}/${activeSessionId}.jsonl`;writeFileSync(activeSessionFile, `${JSON.stringify({ type: "session", version: 3, id: "88888888-8888-4888-8888-888888888888", timestamp: new Date().toISOString(), cwd: process.cwd(), parentSession: previousSessionFile,})}\n`);console.warn = () => {};await sessionStart({ type: "session_start", reason: "startup" }, ctx);console.warn = originalWarn;if (existsSync(join(root, "sessions", "session-artifacts", mismatchedSessionId))) { throw new Error("mismatched current session header copied fork artifacts");}
const maliciousSessionId = "44444444-4444-4444-8444-444444444444";activeSessionId = maliciousSessionId;activeSessionFile = `${sessionDir}/${activeSessionId}.jsonl`;writeFileSync(activeSessionFile, `${JSON.stringify({ type: "session", version: 3, id: maliciousSessionId, timestamp: new Date().toISOString(), cwd: process.cwd(), parentSession: resolve(sessionDir, ".."),})}\n`);console.warn = () => {};await sessionStart({ type: "session_start", reason: "startup" }, ctx);console.warn = originalWarn;const maliciousArtifactDirectory = join( root, "sessions", "session-artifacts", maliciousSessionId, "snapcompact",);if (existsSync(maliciousArtifactDirectory)) { throw new Error("invalid CLI parent session escaped into an artifact copy");}
const forkSessionId = "22222222-2222-4222-8222-222222222222";activeSessionId = forkSessionId;activeSessionFile = `${sessionDir}/${activeSessionId}.jsonl`;writeFileSync(activeSessionFile, `${JSON.stringify({ type: "session", version: 3, id: forkSessionId, timestamp: new Date().toISOString(), cwd: process.cwd(), parentSession: previousSessionFile,})}\n`);await sessionStart({ type: "session_start", reason: "startup" }, ctx);const forkArtifact = join( root, "sessions", "session-artifacts", forkSessionId, "snapcompact", ref1.file,);if (!existsSync(forkArtifact)) throw new Error("CLI startup fork did not copy its inherited SnapCompact artifact");const forkHydrated = await context({ type: "context", messages: [ { role: "compactionSummary", summary: first.compaction.summary, tokensBefore: first.compaction.tokensBefore, timestamp: Date.now() }, { role: "user", content: "continue fork", timestamp: Date.now() },]}, ctx);if (!forkHydrated.messages[0].content.some((block) => block.type === "image")) { throw new Error("forked context did not rehydrate copied archive images");}const orphan = join(forkArtifact, "..", "33333333-3333-4333-8333-333333333333.json");writeFileSync(orphan, "orphan", { mode: 0o600 });await sessionCompact({ type: "session_compact", compactionEntry, fromExtension: true }, ctx);if (existsSync(orphan)) throw new Error("artifact cleanup did not remove an unreferenced artifact");if (!existsSync(forkArtifact)) throw new Error("artifact cleanup removed a referenced fork artifact");
const nextMessages = [ { role: "user", content: "implement and test the fix", timestamp: 3 }, { role: "assistant", content: [ { type: "text", text: "test passed\n".repeat(3000) }, { type: "toolCall", id: "current-1", name: "ipython", arguments: {} }, { type: "toolCall", id: "current-2", name: "ipython", arguments: {} }, { type: "toolCall", id: "empty", name: "ipython", arguments: {} }, { type: "toolCall", id: "useless", name: "ipython", arguments: {} }, ], api: model.api, provider: model.provider, model: model.id, usage, stopReason: "toolUse", timestamp: 4, }, toolResult("current-1", "current exact output 1"), toolResult("current-2", "current exact output 2"), { ...toolResult("empty", ""), content: [] }, { ...toolResult("useless", "no matches"), useless: true },];const second = await before({ type: "session_before_compact", preparation: prep(nextMessages, first.compaction.summary), branchEntries: branch, customInstructions: undefined, signal: controller.signal }, ctx);if (!second?.compaction?.details?.snapcompact?.artifact) throw new Error("repeat compaction missing artifact");if (second.compaction.details.snapcompact.artifact.sha256 === ref1.sha256) throw new Error("repeat compaction did not create a new archive");if (JSON.stringify(second.compaction.details).includes("iVBORw0KGgo")) throw new Error("repeat details inlined PNG data");const secondArtifactPath = join( root, "sessions", "session-artifacts", activeSessionId, "snapcompact", second.compaction.details.snapcompact.artifact.file,);const secondArchive = JSON.parse(readFileSync(secondArtifactPath, "utf8")).preserveData.snapcompact;if (secondArchive.frames.some((frame) => frame.font !== "silver")) { throw new Error("repeat compaction did not retain the prior non-Latin-safe render shape");}const secondArchiveText = secondArchive.text ?? "";for (const exact of [recentExactOutput, "current exact output 1", "current exact output 2"]) { if (!secondArchiveText.includes(exact)) { throw new Error(`empty or useless current result displaced ${exact.slice(0, 24)}`); }}for (const removed of ["second exact output", "third exact output", "injected suffix", "no matches"]) { if (secondArchiveText.includes(removed)) { throw new Error(`historical result masking retained ${removed}`); }}
ctx.model = { ...model, input: ["text"], contextWindow: 128000 };const textHydrated = await context({ type: "context", messages: [ { role: "compactionSummary", summary: first.compaction.summary, tokensBefore: first.compaction.tokensBefore, timestamp: Date.now() }, { role: "user", content: "continue in text", timestamp: Date.now() },]}, ctx);if (textHydrated.messages[0].content.some((block) => block.type === "image")) throw new Error("text-only context contains images");const textChars = textHydrated.messages[0].content.reduce((n, block) => n + (block.type === "text" ? block.text.length : 0), 0);if (textChars > 128000 * 3) throw new Error("text-only context was not bounded");const frozenTextSignature = blockSignature(textHydrated.messages[0].content);for (let turn = 0; turn < 20; turn++) { const turnHydrated = await context({ type: "context", messages: [ { role: "compactionSummary", summary: first.compaction.summary, tokensBefore: first.compaction.tokensBefore, timestamp: Date.now() }, ...Array.from({ length: turn }, (_, i) => ({ role: "user", content: `text tail ${i} ${longText.slice(0, 400)}`, timestamp: Date.now() + i })), ]}, ctx); if (blockSignature(turnHydrated.messages[0].content) !== frozenTextSignature) { throw new Error(`text archive blocks changed at tail step ${turn}; prompt cache would bust`); }}
ctx.model = { ...model, contextWindow: 20000, maxTokens: 4096 };console.warn = () => {};const workerFailureWithArchive = await before({ type: "session_before_compact", preparation: prep(nextMessages, first.compaction.summary), branchEntries: branch, customInstructions: undefined, signal: controller.signal }, ctx);console.warn = originalWarn;if (workerFailureWithArchive?.cancel !== true) throw new Error("worker failure with an existing archive did not cancel safely");ctx.model = { ...model, input: ["text"], contextWindow: 20000, maxTokens: 4096 };console.warn = () => {};const manual = await before({ type: "session_before_compact", preparation: prep(nextMessages, first.compaction.summary), branchEntries: branch, customInstructions: "focus on tests", signal: controller.signal }, ctx);console.warn = originalWarn;if (manual?.cancel !== true) throw new Error("oversize manual text migration did not cancel safely");
console.log(JSON.stringify({ firstDetailsBytes: Buffer.byteLength(detailsJson), firstFrames: images.length, switchedModelFrames: switchedImages, exhaustedBudgetArchiveBlocks: 0, forkArtifactCopied: true, orphanGc: true, repeatFont: "silver", firstArtifactBytes: ref1.bytes, repeatArtifactBytes: second.compaction.details.snapcompact.artifact.bytes, textContextChars: textChars, firstFailureNativeFallback: initialFailure?.compaction !== undefined, existingFailureCancelled: workerFailureWithArchive.cancel, manualOversizeCancelled: manual.cancel,}, null, 2));rmSync(root, { recursive: true, force: true });