Skip to content

perf: debounce the @memory narrative read-rewrite (#445)#460

Merged
tcconnally merged 1 commit into
mainfrom
perf/445-narrative-touch-debounce
Jun 26, 2026
Merged

perf: debounce the @memory narrative read-rewrite (#445)#460
tcconnally merged 1 commit into
mainfrom
perf/445-narrative-touch-debounce

Conversation

@tcconnally

Copy link
Copy Markdown
Collaborator

Addresses #445 item 2 (the @memory narrative is fully rewritten on every fresh render just to bump updated). Owner-approved approach: debounce.

Problem

Feat #2 — reading a non-stale narrative resets its staleness clock — rewrote the entire narrative file (_save_narrative) on every render. Under bursty rendering (e.g. an agent loop) that's a file write per render.

Fix

Reuse the age already computed by the staleness check and only re-stamp updated when the recorded value is older than a window (default 60s, memory.narrative_touch_debounce_s) or unparseable. Staleness is measured in hours (ttl), so collapsing sub-window touches costs no meaningful precision while removing the repeated write.

Contract preserved

Both existing Feat #2 tests pass unchanged:

  • test_feat2_touch_updated_on_fresh_render uses a 30-min-old timestamp (≫ the 60s window) → still re-stamps.
  • test_feat2_no_touch_when_stale → stale narratives are never touched (unaffected).

Tests

  • test_feat2_touch_is_debounced_within_window — a render with updated 10s ago and a 5-min window does not rewrite the file.
  • 46 passed across the memory-feature + agora suites.

🤖 Generated with Claude Code

Addresses #445 item 2 (the @memory narrative is fully rewritten on every fresh
render just to bump `updated`).

Feat #2 — reading a *non-stale* narrative resets its staleness clock — rewrote
the entire narrative file (`_save_narrative`) on EVERY render. Under bursty
rendering (e.g. an agent loop) that's a file write per render.

Debounce it: reuse the age already computed by the staleness check and only
re-stamp `updated` when the recorded value is older than a window (default 60s,
`memory.narrative_touch_debounce_s`) or unparseable. Staleness is measured in
hours (ttl), so collapsing sub-window touches costs no meaningful precision
while removing the repeated write.

Contract preserved: both existing Feat #2 tests still pass unchanged —
test_feat2_touch_updated_on_fresh_render uses a 30-min-old timestamp (>> the
60s window, so it still re-stamps), and test_feat2_no_touch_when_stale is
unaffected (stale → never touched).

Tests: + test_feat2_touch_is_debounced_within_window (a render with `updated`
10s ago and a 5-min window does NOT rewrite the file). 46 passed across the
memory-feature + agora suites.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@tcconnally tcconnally merged commit e9c1973 into main Jun 26, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant