review: a cancelled turn keeps its trace, and a quiet box still expires (V-629)
Two defects found reviewing the PR. The insert ran on the turn's own context, so a caller that hung up or timed out cancelled it. That is exactly the turn worth having. It now runs detached, with a one-second bound of its own, because a write must not hold the reply. Retention was enforced on write alone, so a box that goes quiet for a month kept every row until the next sixty-fourth turn. pruneTracesOnStart closes that, and RoutingTraceRetention is exported so the daemon reads the same number the store enforces. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117tgnmbgZpHVV3XSNw8Qua
This commit is contained in:
@@ -311,7 +311,7 @@ ALTER TABLE reminders ADD COLUMN next_fire_ts INTEGER;`, // #2
|
||||
// sentence is substantially recoverable, so storing vectors instead would be a
|
||||
// privacy claim we cannot support. What makes it safe is the same thing that
|
||||
// makes the fact store safe: it never leaves the box, retention is bounded at
|
||||
// routingTraceRetention, and Wipe drops it with everything else.
|
||||
// store.RoutingTraceRetention, and Wipe drops it with everything else.
|
||||
//
|
||||
// correction is empty until the owner corrects a turn on /chat (V-630). A
|
||||
// corrected pair is promoted out of here into a seed-shaped row and kept, so
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// routingTraceRetention is how long a raw trace lives (owner's call,
|
||||
// RoutingTraceRetention is how long a raw trace lives (owner's call,
|
||||
// 06-08-2026). A trace is read within a day or two of the turn that produced it,
|
||||
// or never, so two weeks is diagnosis with room for a weekend. It is deliberately
|
||||
// an age and not a row count: the useful question is "what did she do this week",
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
// turn, the pair is promoted out of the trace into a seed-shaped row and kept
|
||||
// indefinitely, because a label is not a transcript. Keeping the transcript that
|
||||
// carried it would defeat the point of the bound.
|
||||
const routingTraceRetention = 14 * 24 * time.Hour
|
||||
const RoutingTraceRetention = 14 * 24 * time.Hour
|
||||
|
||||
// RoutingTrace is one turn's arbitration, persisted. It is internal/decision's
|
||||
// Record plus the four things the ring never had to carry: which reach the
|
||||
@@ -70,7 +70,7 @@ func (s *Store) WriteRoutingTrace(ctx context.Context, tr RoutingTrace) (int64,
|
||||
// Prune rarely. Turns arrive at human rate, so the bound is a ceiling and
|
||||
// paying for a delete on every one of them buys nothing. 64 turns is hours.
|
||||
if id%64 == 0 {
|
||||
if err := s.PruneRoutingTraces(ctx, tr.Ts.Add(-routingTraceRetention)); err != nil {
|
||||
if err := s.PruneRoutingTraces(ctx, tr.Ts.Add(-RoutingTraceRetention)); err != nil {
|
||||
return id, err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ func TestPruneRoutingTracesByAge(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err := s.PruneRoutingTraces(ctx, now.Add(-routingTraceRetention)); err != nil {
|
||||
if err := s.PruneRoutingTraces(ctx, now.Add(-RoutingTraceRetention)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := s.RecentRoutingTraces(ctx, 10)
|
||||
|
||||
Reference in New Issue
Block a user