/** * contextLedger — the post-run bookkeeper (see types.ts for the WHY). * * DESIGN: a pure POST-RUN analyzer over the run's own commit log — no live * recorder lifecycle, no event-order coupling. Everything it counts is * already durably recorded by the engine (dogfooding: offers come from * `commitValueAt` folds, answer attribution from `sliceForKey` — the same * canonical queries every triage surface uses): * * offers — the context IN EFFECT at each LLM call. Call marker: a * commit that wrote `totalInputTokens` (monotonic — never * net-change-dropped) and did NOT write `userMessage` (which * only the seed writes). At each call index, fold * `activeInjections` + `dynamicToolSchemas`, and add the * STATIC tool registry (duck-read from the runner's public * `getUIGroup().extra.toolNames` — static registries live in a * closure, never in scope state). NOTE offers are deliberately * NOT "per context-key commit": the net-change filter drops * identical re-commits, so stable context appears once in the * log while still being offered (and paying tokens) per call. * Static-registry tools count offers with approxTokens 0 in L1 * (their schema JSON isn't in the log) — earnRate, the gate * signal, is unaffected; dynamicToolSchemas carries real sizes. * uses — tool: assistant messages' toolCalls in the final history; * skill: `activatedInjectionIds`; * injection: its SLOT's write sits on the final answer's * backward slice (slot-granular, labeled). * outcome — consumer label per run, credited to every offered piece. * * The slot→slice join needs NO id conventions: for each slot key * (INJECTION_KEYS.*), `findLastWriter` names the commit that fed the final * LLM call; membership of that writer in the answer slice IS the signal. */ import type { ContextLedger } from './types.js'; export declare function contextLedger(): ContextLedger; //# sourceMappingURL=contextLedger.d.ts.map