Symptom
expand_unresolved_missing is non-zero, and it correlates with the pipeline doing more work:
| iteration |
arm |
unresolved missing |
| 024 (150 runs, 64k) |
B — +evidence, +econ_trigger |
209 |
| 024 |
A — baseline, sweep inert |
0 |
| 023 |
Cp1 (+coref) |
60 of that pass's 112 expand calls |
| 023 |
every other pass |
0 |
By this repo's own definition that is a defect, not a tuning artifact — expand/unresolved.go:
MISSING — the id is one this proxy could have minted, and nothing is behind it. That is a context-guru DEFECT: a cut was advertised as reversible and it was not. The stash expired, the store did not persist, or the key was written under a session id nothing reads.
209 times the agent asked for removed content back and got a placeholder instead.
Suspected cause: the pin list protects the decisions and evicts the payloads
store.DefaultPinPrefixes = {FrozenPrefix, ResultPrefix, LenPrefix, XResultPrefix, TTLPrefix, SeenPrefix}.
The stashed original payload — the content behind a <<cg:HASH>> marker — does not appear in that list. The default store holds 1000 entries (store.Options defaults; DefaultTTL is 10,000 s, far longer than these runs, so expiry is not the cause).
So under volume the store keeps "this output was dropped" (frozen + result entries, pinned) while evicting "here is what it was" (the stash, unpinned). A well-formed marker id with nothing behind it is exactly missing.
The volume fits the arm split. Arm B made 629 sweep calls, removed 2,407,680 tokens, and extract_llm logged 4,749 calls avoided — implying thousands of result-cache entries — against a 1000-entry store that the benchmark rig never configures. Arm A stashes nothing through the sweep and scores 0.
One assertion left to verify, and the diagnosis rests on it: that the stash payload key carries none of the pinned prefixes. Confirm that before fixing — if it is pinned, the cause is one of the other two in the comment above (non-persisting store, or a key written under a session id nothing reads) and the fix is different.
Why this is worse than a counter going up
The guarantee degrades precisely as the mechanism succeeds. Every additional drop both consumes a stash slot and adds a pinned decision entry, so the more content a configuration removes, the more of its own reversibility it destroys — and nothing warns. Fail open, always and "every lossy Offload must be reversible (a <<cg:HASH>> marker + the stashed original in the Store)" are stated as hard boundaries in CLAUDE.md; this silently converts a reversible removal into an irreversible one at exactly the load where reversibility matters most.
Adjacent to #47 (pin-budget exhaustion reopening the TailOnly fail-open on /compact), which suggests the pin budget is under-specified generally rather than only here.
How it affected iteration 024's published results
Recorded because the numbers are already written up in docs/experiments/loca/iter024/results.md, and this changes how two of them read:
- The reward result is CONSERVATIVE, not threatened. Arm B won 8 tasks to 0 (clustered p = 0.0078, harm bound 11.2%) while carrying 209 failed expands. A handicap the winning arm bore. With reversibility working it would plausibly do at least as well.
- The latency conclusion is WEAKENED and was stated too strongly. That write-up says arm B takes 13% more turns on pairs where both arms solved, and calls the latency hypothesis "refuted". But 209 failed expands over 75 runs is ~2.8 per run against ~33 turns/run — so failed-expand round-trips could account for a meaningful share of that 13%. "Refuted" should be "not supported, and partly confounded by this defect."
- Cost figures are mildly contaminated. A failed expand still costs the tokens and the turn spent asking, while delivering nothing.
- Most generally: iteration 024 measured "the mechanism plus a reversibility bug", not the mechanism. Re-running after the fix is the only way to separate them.
Suggested shape
Whichever cause verification confirms, the fix should make the failure loud rather than only fixed:
- pin the stash payload, or size the store to the stash volume a configuration will generate;
- and warn — or refuse the removal — when the budget is exhausted, rather than stamping a marker whose content cannot be produced. A removal that cannot be reversed should not be advertised as reversible.
expand_unresolved_missing exists and is documented as the alertable counter; the gap is that nothing acts on it, and the removal proceeds regardless.
Found while analysing iteration 024. Filed against main and kept off the co-reference branch (#186) because it is unrelated to evidence/econ_trigger and should reach production independently.
Symptom
expand_unresolved_missingis non-zero, and it correlates with the pipeline doing more work:missing+evidence, +econ_trigger+coref)By this repo's own definition that is a defect, not a tuning artifact —
expand/unresolved.go:209 times the agent asked for removed content back and got a placeholder instead.
Suspected cause: the pin list protects the decisions and evicts the payloads
store.DefaultPinPrefixes={FrozenPrefix, ResultPrefix, LenPrefix, XResultPrefix, TTLPrefix, SeenPrefix}.The stashed original payload — the content behind a
<<cg:HASH>>marker — does not appear in that list. The default store holds 1000 entries (store.Optionsdefaults;DefaultTTLis 10,000 s, far longer than these runs, so expiry is not the cause).So under volume the store keeps "this output was dropped" (frozen + result entries, pinned) while evicting "here is what it was" (the stash, unpinned). A well-formed marker id with nothing behind it is exactly
missing.The volume fits the arm split. Arm B made 629 sweep calls, removed 2,407,680 tokens, and
extract_llmlogged 4,749 calls avoided — implying thousands of result-cache entries — against a 1000-entry store that the benchmark rig never configures. Arm A stashes nothing through the sweep and scores 0.One assertion left to verify, and the diagnosis rests on it: that the stash payload key carries none of the pinned prefixes. Confirm that before fixing — if it is pinned, the cause is one of the other two in the comment above (non-persisting store, or a key written under a session id nothing reads) and the fix is different.
Why this is worse than a counter going up
The guarantee degrades precisely as the mechanism succeeds. Every additional drop both consumes a stash slot and adds a pinned decision entry, so the more content a configuration removes, the more of its own reversibility it destroys — and nothing warns.
Fail open, alwaysand "every lossy Offload must be reversible (a<<cg:HASH>>marker + the stashed original in the Store)" are stated as hard boundaries inCLAUDE.md; this silently converts a reversible removal into an irreversible one at exactly the load where reversibility matters most.Adjacent to #47 (pin-budget exhaustion reopening the
TailOnlyfail-open on/compact), which suggests the pin budget is under-specified generally rather than only here.How it affected iteration 024's published results
Recorded because the numbers are already written up in
docs/experiments/loca/iter024/results.md, and this changes how two of them read:Suggested shape
Whichever cause verification confirms, the fix should make the failure loud rather than only fixed:
expand_unresolved_missingexists and is documented as the alertable counter; the gap is that nothing acts on it, and the removal proceeds regardless.Found while analysing iteration 024. Filed against
mainand kept off the co-reference branch (#186) because it is unrelated toevidence/econ_triggerand should reach production independently.