Files
Maven/docs/plans/21-persisting-the-routing-trace.md

3.2 KiB

Plan: persist the routing trace

Owner's call, 06-08-2026. V-629, umbrella V-628.

Verdict: the per-turn decision record now persists. That reverses a written decision, which is the point of this file. It is not an incidental telemetry feature. Do not read it as one.

Last verified: 06-08-2026 @ 799cf55

What the old decision said

internal/decision kept a 25-turn in-memory ring and persisted nothing. The argument was in CLAUDE.md and it was a good one. A turn record is read minutes after the turn or never, so a table that outlives the diagnosis buys nothing. His words did not belong in it.

Why it reversed

V-546 replaces the generative router with classification heads on e5-small. Fitting prototypes and calibrating a distance both need real utterances. V-631 measured how few there are. Nine of the 31 modes in internal/modes have no seed example at all, and they are exactly the nine with no deterministic matcher. The seed corpus cannot supply them. A seed row is a phrase someone wrote for a matcher, not a thing he said. The 202 generated contrast pairs were tried and cost four points of fixture accuracy.

So the choice was between no routing heads and a persisted trace. The owner chose the trace.

Retention, and why it is two answers

Raw trace: 14 days. store.RoutingTraceRetention in internal/store/routingtraces.go. That is the life of a diagnosis with room for a weekend. The bound is an age and not a row count. The useful question is what she did this week, and a busy Tuesday must not push last Friday out.

A correction: indefinite. The owner corrects a turn on /chat (V-630). The pair is then promoted out of the trace into a seed-shaped row and kept, because a label is not a transcript. What stays in routing_traces is the transcript. It expires on the same 14 days as every other row, corrected or not.

What keeps it safe

The utterance is stored in clear. A 384-dimension vector of a short sentence is substantially recoverable. Storing vectors instead would be a privacy claim we cannot support, and making it would be worse than staying silent.

  • Nothing here leaves the box. The rule that the owner's notes and facts are never search input covers this table too. No query source reads it, and no upstream engine can.
  • Retention is enforced on write and again at start. WriteRoutingTrace prunes every 64th row, which is hours at human rate. pruneTracesOnStart covers the case write alone cannot. A box that goes quiet keeps every row until the next sixty-fourth turn. Without the start-time prune, the bound would hold only for a box in daily use.
  • Deletion already exists. Store.Wipe drops every table the database reports, so mavend -wipe -confirm-wipe covers this one with no list to edit.
  • The ring did not move. It is still what /trace reads and still what a test with no store gets. The table is a second sink beside it. A failed insert is logged and swallowed, because a trace must never change what he hears.

What is not decided

Whether some utterances must never be promoted into a durable label, no matter how badly they routed. That is a content rule and it belongs beside the personal boundary, not in the trace writer. Recorded here, left to the owner.