Repository navigation
Open
Description
Summary
These are the follow-ups from Osher's review of #861 (tool deferral in ultrahigh). #861 fixes the blocking and high items (B1–B4, H1–H4), plus N11 and the signal.sh match from N12. The items below are not blocking. Each has a fix.
What we found
| # | Problem | Fix |
|---|---|---|
| N1 | The history flush clears dirty before the write. On any SQLite error it returns, so those sessions are not written until they change again. |
Set dirty back on a failed write. |
| N2 | Every request moves a session's last time and marks it dirty. Each 5 s flush then rewrites every tool row of every active session. |
Mark a session dirty only when its tool sets change. Write last_ts on a set change or at close. |
| N3 | The project veto reads at most 10 project sessions out of the newest 64 per account. A user in 4 or more projects, or with scripted claude -p runs, pushes a project's older sessions out. |
Also keep the newest 10 sessions per account and project. |
| N4 | Rebuild can drift. Observe adds a session at its first request, so a session that only started in between changes UserSessions. After #861 this runs only when a record was evicted at the pin cap. |
When Rebuild gives a set other than what the transcript proves, send the original and do not save. Or keep it, and say so in the code. |
| N5 | sniffer.bytes() is head plus tail. For a response of 64–128 KiB the two windows overlap, so SearchesInSSE can count one search twice. |
Scan the tail only past the head. |
| N6 | The 200-token minimum counts o200k tokens, about 337 Claude tokens. The ledger scales by BilledDeltaFactor; the rule does not. |
Scale the rule the same way, or write "200 o200k tokens" in the docs. |
| N7 | The net saving leaves out the cache write of a loaded definition on the next request. | Add the loaded tokens at the write price, once per load. |
| N8 | The metrics that #485 lists are missing: per-account counters, the wrong-guess count (a deferred tool that was then used), dropped parallel searches, and the keep-alive ledger credit. | Add wrong_guesses and dropped_searches to the tool_defer block, per account. |
| N9 | The seeded history misses the tools this feature targets. tool_declarations lacks the built-ins Claude Code defers, and tool_uses lacks search loads. |
Fix it with the dashboard follow-up from #485. |
| N10 | Running sessions count as history. On the hosted database, 94% of decisions had a running session among the last 3. A replay gave 24 wrong guesses with running sessions counted and 22 with ended sessions only, at the same deferred volume. So the current rule is fine. | Write this in a code comment, so nobody "fixes" it. |
| N12a | The probe sends no OAuth beta header. Direct Anthropic with a subscription token may answer 401. #861 now makes a 401 "no verdict", so deferral stays off and the probe retries. Inferred, not tested. | Send the header the client sent, or probe with the client's own headers. |
| N12b | false, 0, no and off all turn deferral off. The design says only a literal false. |
The owner decides. |
Also found while fixing B3: an account purge removes tool deferral's rows from session_state, but not the tenant's other session-state keys (cg:sum:, cg:bin: and so on). That is older than #861, and it is not part of it.
Open questions
- N12b: keep
false/0/no/off, or go back to a literalfalse?
🤖 Generated with Claude Code
Metadata
Metadata
Assignees
Labels
No labels
Type
Projects
- StatusShow more project fieldsNew/ToDo
Activity
amiddavid commentedon Nov 2, 2026
Answer to the open question (N12b): keep
false,0,noandoffas off values. The owner decided this on 2026-11-02. Only these four count as a deliberate opt-out;auto,trueand an unset value do not. No change needed.🤖 Generated with Claude Code
amiddavid commentedon Nov 2, 2026
One more from the #861 round-4 review: the 400 turn-off map (
Gate.broken,tooldefer/gate.go) is one global map capped at 20,000 across tenants. One tenant's 400s can push out another tenant's turn-offs. Each entry expires in 24 h. Fix: key and cap it per tenant, like the pending opt-outs.feat(tooldefer): defer unused tools in the new ultrahigh preset (#485) (