docs(core): surface the config-relative recomposition caveat

Elision reads config/context.json at compose time, so the composed
payload is no longer a pure function of the durable log — inspecting an
old turn after a config edit can show different prefix bytes than were
transmitted. Document the exception against §8.3 and make the inspect
CLI print the policy in effect so divergence is visible instead of
silent. The gold fix (recording the applied policy on the turn) is
noted for when exact-bytes replay becomes a hard requirement.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Ramnique Singh 2026-07-07 20:26:22 +05:30
parent 8a952a4b7e
commit 4b4e6af2ea
2 changed files with 25 additions and 1 deletions

View file

@ -8,6 +8,10 @@
// messages (user-message context, attachments, tool-result envelopes) are
// visible; the file itself stores only structural facts and references.
//
// Caveat: historic-context elision reads config/context.json at compose
// time, so recomposition is exact only while that config matches what was
// live when the call ran. The header prints the policy in effect NOW.
//
// Session mode prints the session overview (title, turns, statuses, sizes);
// pass --turns to cascade full turn inspection for every turn.
//
@ -27,7 +31,7 @@ import { convertFromMessages } from "../agents/runtime.js";
import { WorkDir } from "../config/config.js";
import { FSSessionRepo } from "../sessions/fs-repo.js";
import { composeModelRequest } from "./compose-model-request.js";
import { createContextResolver } from "./context-elision.js";
import { createContextResolver, loadElisionPolicy } from "./context-elision.js";
import { FSTurnRepo } from "./fs-repo.js";
const turnRepo = new FSTurnRepo({
@ -81,6 +85,17 @@ async function inspectTurn(
console.log(
`agent ${agent.agentId} model ${agent.model.provider}/${agent.model.model} calls ${state.modelCalls.length}${inherited}`,
);
const policy = loadElisionPolicy();
console.log(
`context elision (per config/context.json NOW; transmitted bytes reflect the config live at call time): ` +
[
policy.toolResults
? `toolResults>${policy.toolResultThresholdChars}`
: "toolResults off",
policy.images ? "images" : "images off",
policy.middlePaneContent ? "notes" : "notes off",
].join(", "),
);
for (const call of state.modelCalls) {
if (onlyIndex !== undefined && call.index !== onlyIndex) continue;