/** * localizeContextBug — the contextual-bug LOCALIZER, "git bisect for * context" (RFC-003 Part B, block D8). * * The five-stage pipeline (each stage is a shipped piece — this file only * ASSEMBLES): * * 1. TRIGGER — an explicit `atStep`, a custom trigger strategy, or * the QualityRecorder's lowest-scoring step. * 2. SLICE — footprintjs `causalChain` over the commit log, WITH * control-dependence edges (D3) and honesty markers * (A2/A4) when the artifacts carry them. * 3. WEIGH — D7's `llmEdgeWeigher` stamps influence weights on * every LLM-call parent edge (two-pass: prime, re-slice). * 4. RANK — suspects = slice nodes classified into ablatable * context sources (tool / injection / memory / arg), * scored by max-product path weight × per-item semantic * refinement. CORRELATIONAL tier — and marked so. * 5. ABLATE — optional: the consumer's `AblationRunner` re-runs the * scenario without each top suspect, N seeded times. * Verdicts (the ONLY causal claims, §B2) + variance. * * Without a runner the report stops at stage 4 with * `mode: 'correlational'` — explicitly a ranking of proxies, no causal * claim anywhere. * * Every `source` / `step` id in the report is a plain runtimeStageId — * drill any of them with the trace-toolpack tools (`trace_node`, * `trace_slice`, `get_value`) over the same artifacts bag. */ import type { CausalNode } from 'footprintjs/trace'; import { type Embedder, type InfluenceScorer, type InfluenceStrategy } from '../influence-core/index.js'; import type { LoopRecallShortlist } from './loop-recall.js'; import { type ContextUnit } from './missingContext.js'; import { type RestorationRerun } from './restoration.js'; import type { AblationRerun, ContextBugArtifacts, ContextBugReport, Suspect, SuspectDetail, SuspectKind } from './types.js'; /** * Extract LLM-call step ids from captured typed events: the * `meta.runtimeStageId` of every `agentfootprint.stream.llm_start` * envelope, deduplicated in event order. Collect events with * `agent.on('*', (e) => events.push(e))`. */ export declare function llmCallIdsFromEvents(events: readonly { readonly type: string; readonly meta: { readonly runtimeStageId: string; }; }[]): string[]; /** A classified-but-unscored suspect produced by a classifier. */ export interface SuspectSeed { readonly kind: SuspectKind; readonly detail?: SuspectDetail; } /** What a classifier sees for one slice node. */ export interface ClassifyContext { readonly node: CausalNode; /** Keys this node committed. */ readonly keysWritten: readonly string[]; /** Verb-aware value of a key as of this node's last commit. */ readonly valueOf: (key: string) => unknown; } /** * Pluggable classifier: map one slice node to its ablatable context * sources. Return `undefined` to fall through to the default (which * understands the agent chart's committed shapes); return `[]` to * suppress the node entirely. */ export type SuspectClassifier = (ctx: ClassifyContext) => readonly SuspectSeed[] | undefined; /** * The default classifier — reads the node's COMMITTED values (already * redaction-scrubbed) and recognizes the agent chart's shapes: * * - `systemPromptInjections` / `messagesInjections` / `toolsInjections` * records with an engineered source → one suspect per `Injection.id` * (kind `'memory'` for source `'memory'`, else `'injection'`). * - `lastToolResult` → a `'tool'` suspect for the tool that ran. * - footprintjs A2 honesty marker `args` → an `'arg'` suspect (the * consumer's runner must override the input — nothing to filter). * - anything else → the honest `'stage'` fallback (no ablation spec). */ export declare function defaultSuspectClassifier(ctx: ClassifyContext): readonly SuspectSeed[]; export interface LocalizeContextBugOptions { readonly artifacts: ContextBugArtifacts; /** Injected embedder (D6) — wrap in `embeddingCache(...)`. */ readonly embedder: Embedder; /** Explicit trigger step (runtimeStageId). Wins over everything. */ readonly atStep?: string; /** Custom trigger strategy — consulted when `atStep` is absent. */ readonly trigger?: (artifacts: ContextBugArtifacts) => string | undefined; /** * The counterfactual tier: supply a runner (+ the original output) and * top suspects get ablation verdicts. Absent → the report stops at the * ranking, marked `mode: 'correlational'`. */ readonly rerun?: AblationRerun; /** * Interface #3 — the MISSING-context tier. Supply what was `available` for * the turn and what was `sent` to the model; the report's `dropped` lists the * units that never reached the model (`available − sent`). Add a `rerun` and * each dropped candidate gets a RESTORATION verdict (the mirror of ablation: * restoring it flips the outcome → causal). Absent → no `dropped` section. */ readonly missingContext?: { readonly available: readonly ContextUnit[]; readonly sent: readonly ContextUnit[]; readonly rerun?: RestorationRerun; }; /** Slice depth budget. Default 12. */ readonly maxDepth?: number; /** Slice node budget. Default 80. */ readonly maxNodes?: number; /** Ranked suspects kept on the report. Default 12. */ readonly maxSuspects?: number; /** Override / extend the suspect classifier. */ readonly classify?: SuspectClassifier; /** * The RANK stage's pluggable influence scorer (the suspect-ordering * extension point). Default `scoreInfluence` — the FDL four-signal * composite. Bring your own `InfluenceScorer` — e.g. * `scoreContrastiveInfluence` wrapped with a `referenceText`, or a * scorer of your own — to change the ranking ORDER, never causality: * a scorer only changes how FAST §B2 ablation confirms a culprit; * ablation alone makes the causal claim. * * Or pass a named `InfluenceStrategy` (`semanticAlignmentStrategy` / * `lexicalOverlapStrategy` / your own) — the report's `rankedBy` echoes * its name. */ readonly scorer?: InfluenceScorer | InfluenceStrategy; /** * L3 narrowing (proposal 006): a per-loop recall shortlist from `shortlistEarlyCulprits`. * When supplied, suspects are REORDERED (never filtered) so high-recall candidates float to the * top and survive the `maxSuspects` slice → ablation targets them first. Joined on the suspect * identity (`detail.injectionId`/`detail.toolName`). Default off (back-compat). */ readonly shortlist?: LoopRecallShortlist; } /** * Localize a contextual bug: trigger → causal slice → influence-weighted * ranking → (optional) counterfactual ablation. See module docs for the * pipeline and the §B2 claim tiers. * * @beta Beta feature — the API may change before GA. * * @throws when no trigger can be resolved (no `atStep`, no custom * strategy hit, no `artifacts.quality`), or when the trigger step * is not in the commit log. */ export declare function localizeContextBug(options: LocalizeContextBugOptions): Promise; export declare function suspectLabel(suspect: Suspect): string; /** * Human-readable report. The claim tiers are spelled out in the output * itself (§B2): scores are proxies; verdict lines are the only causal * claims; every ⚠ honesty flag prints. */ export declare function formatContextBugReport(report: ContextBugReport): string; //# sourceMappingURL=localize.d.ts.map