fix(sleep): make epistemic promotion reachable — namespace spread never fired - #175
Merged
Merged
Conversation
…er fired Phase 5.12 required positive retrievals from >= 2 distinct namespaces to promote a memory to 'established'. That threshold is structurally unsatisfiable: every search path filters warm rows to the caller's namespace (memory-manager.ts:975/1015/1052/1092), retrieval_log records that same namespace, and namespace is immutable after insert. A row's retrieval evidence is therefore always single-namespace, so the count could never reach 2. Consequence: nothing was ever promoted to 'established' in production. That also silently starved bootstrapAgent(), which copies only 'established' rows — so cross-agent transfer moved zero memories. Two shipped features, both inert, both with passing tests: the suite hand-inserted retrieval_log rows carrying a namespace the system cannot produce for that row. Replaces the clause with a day-spread test: positive retrievals on >= 2 distinct calendar days. This preserves the documented intent (corroboration from independent sessions, not one burst) and is reachable. It is not redundant with evidence_count >= 3 — that counter increments once per sleep cycle that saw feedback in the trailing 24h, so several cycles in one busy day can reach 3 without independent confirmation. Tests: - New suite drives promotion through the real query() + feedback() paths and backdates only a timestamp, so it fails if promotion ever becomes unreachable again. Its poll is anchored to a pre-call id watermark because retrieval logging is fire-and-forget. - Pins the invariant that made the old rule dead (no retrieval row may carry a namespace differing from its memory), so reintroducing a namespace-spread requirement fails loudly. - Promotion tests now each run on their own agent. They all call engine.run(), which mutates every eligible row for the agent, so a shared agent let a later cycle retroactively promote an earlier test's fixture — a ~1-in-4 flake, reproduced and then absent across 8 runs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011xCqQo49d3CEbn6oEvb3Ru
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The defect
Phase 5.12 promotes a memory to
establishedonly when it has positive retrievals from ≥ 2 distinct namespaces. That can never happen:memory-manager.ts:975, 1015, 1052, 1092)retrieval_logrecords that same namespaceSET namespaceanywhere insrc/A row's retrieval evidence is therefore always single-namespace, so
COUNT(DISTINCT namespace)cannot reach 2.Nothing has ever been promoted to
establishedin production. That also silently starvedbootstrapAgent(), which copies onlyestablishedrows — so cross-agent transfer learning moves zero memories. Two shipped features, both inert.Both had passing tests, because the suite hand-inserted
retrieval_logrows carrying a namespace the system cannot produce for that row.The fix
Replace the namespace clause with a day-spread test: positive retrievals on ≥ 2 distinct calendar days. Preserves the documented intent (corroboration from independent sessions rather than one burst) and is reachable.
Not redundant with
evidence_count >= 3: that counter increments once per sleep cycle that saw feedback in the trailing 24h, so several cycles in one busy day can reach 3 without any independent confirmation. Both clauses now do distinct work.Tests
query()+feedback()paths, backdating only a timestamp. If promotion ever becomes unreachable again, this fails. (Its poll is anchored to a pre-call id watermark because retrieval logging is fire-and-forget —memory-manager.ts:942.)engine.run(), which mutates every eligible row for that agent, so the shared agent let a later cycle retroactively promote an earlier test's fixture. Reproduced at ~1-in-4, then absent across 8 consecutive runs.test:epistemic-confidencetest:bootstraptest:contested-conflictstest:integrationNote
This is step 1 of the profiles-over-namespaces direction: it unblocks
establishedstatus independent of which scoping model wins, and removes the last load-bearing use of namespace as a semantic signal.🤖 Generated with Claude Code
https://claude.ai/code/session_011xCqQo49d3CEbn6oEvb3Ru