Re-run without sources
One call: take a finished run, ignore some of its context sources, run it again, and see honestly what changed.
Beta
rerunWithoutSources is a beta feature. It works and ships with a tested example, but the API may still change before GA.
You've localized the bug — the ranking points at a source you suspect. A ranking is a guess. The only way to know is to remove the source and run it again.
rerunWithoutSourcesis that one call.
The loop
This is the product loop behind an "Influence Map" UI: the user sees an influence ranking, toggles a source off, hits re-run.
localizeContextBugproduces aContextBugReport— ranked suspects, each with the spec that would remove it.removableSources(report)turns that into the UI's toggle list — one row per removable source (id,label,score,spec), tools and injections and memory only. That's yourignorevocabulary.rerunWithoutSourcestakes the sources to ignore, re-runs the scenario without them, and returnswhatChanged— the re-run's answer, how often it flipped across seeded re-runs, and a plain-language summary.
One call
You supply the runner — the same AblationRunner the localizer's causal mode uses. Its body applies the specs at agent construction (the documented seam — see Localize a context bug), builds a fresh agent, and returns the answer:
// The runner applies the specs at CONSTRUCTION (the documented seam):
const = async (: readonly []) => {
const { , } = (, { : , : });
return (, ); // fresh agent + provider per call
};
const = await ({
,
: ['vip-override-fact'], // a plain id from removableSources(report)
,
: ,
: (()),
// domain comparator, recommended with mockEmbedder:
: (, ) => .('APPROVED') !== .('APPROVED'),
});
.; // the re-run's answer
..; // did a majority of seeded re-runs change?
..; // plain-language recap (presentation only — read the fields)ignore takes plain ids: an injection id, a tool name, or a step id (runtimeStageId). An unknown id throws and lists what's removable — a silent no-op re-run would lie.
Honesty tiers: observed vs causal
The default is honest about what it can and can't claim:
- Observed (default) —
whatChanged.answerFlippedis a majority over N ≥ 2 seeded re-runs (never a single-run diff), with the full similarity spread. It's an observation: these re-runs changed the answer. Noverdict. - Causal — pass
checkBaseline: true. The unchanged scenario is probed too, so an unstable scenario can't masquerade as a finding. Then the result carries averdict— the sameverdictForcausal-tier claim (CAUSAL/INCONCLUSIVE/NOT CONFIRMED) the localizer uses.
State it plainly: answerFlipped without a baseline check is an observation, not a conviction. Scores suggest; re-runs convict.
Works with any provider
Every seeded re-run is a real run of your runner:
- Mock —
$0, deterministic, instant. PairmockEmbedder()with a domainanswerChangedcomparator (its cosine compresses prose into a narrow band, so absolute thresholds don't discriminate). - Real — each sample costs a real run.
samplesdefaults to 3 (clamped to ≥ 2). Mind the cost when you turn oncheckBaseline(it doubles the runs).
The full runnable, tested example is 18-influence-strategies-and-rerun.ts — a stock-desk agent whose BUY flips to HOLD when the planted social-sentiment source is ignored.
Next steps
- Recorded chat — chatting?
recordedChatderives this runner for you, per turn, and keeps the recorded history byte-exact between the turn and its re-run - Localize a context bug — where the report and the removable specs come from
- Testing — the mocks-first
$0runs the re-runs are built on
Localize a context bug
Git bisect for context — point the debugging harness at a wrong answer and it walks the run back to the input that caused it, then proves it by removing it.
Variable recall
Ask about a VARIABLE, not a step — its whole recorded life, in agent vocabulary. And where the dataflow is exact, the backward walk stops guessing.
