recall.build_digest filters claims by status but not pages. an archived page's title is injected into the opening context of every new session, while its claims are correctly suppressed.
where — src/vouch/recall.py:57-61:
claims = [
c for c in store.list_claims()
if c.status not in _RETRACTED_CLAIM_STATUSES
]
pages = store.list_pages() # <- no status filter
Page.status exists (models.py:337) and synthesize.py:121,124 already filters page.status != PageStatus.ARCHIVED, so recall is the odd surface out.
why it matters — the rationale is already written down on _RETRACTED_CLAIM_STATUSES (context.py:35): "otherwise the archive/supersede/redact controls are decorative." that argument applies to pages. recall is also the one surface that runs unprompted on every SessionStart, so a retracted title reaches every future session's first turn.
repro — archiving a page means setting status: archived in its frontmatter (the plaintext / obsidian edit path; lifecycle.archive is claims-only). the status round-trips through get_page correctly:
s = KBStore.init(Path("kb"))
pr = propose_page(s, title="obsolete design", body="body", proposed_by="a")
pg = approve(s, pr.id, approved_by="u")
p = s._page_path(pg.id)
p.write_text(p.read_text().replace("status: draft", "status: archived"))
assert s.get_page(pg.id).status is PageStatus.ARCHIVED # passes
assert "obsolete design" not in recall.build_digest(s) # fails on test
scope — only ARCHIVED should be filtered. DRAFT and STALE stay live knowledge, mirroring the reasoning that keeps CONTESTED in the claim set.
happy to send the fix.
recall.build_digestfilters claims by status but not pages. an archived page's title is injected into the opening context of every new session, while its claims are correctly suppressed.where —
src/vouch/recall.py:57-61:Page.statusexists (models.py:337) andsynthesize.py:121,124already filterspage.status != PageStatus.ARCHIVED, so recall is the odd surface out.why it matters — the rationale is already written down on
_RETRACTED_CLAIM_STATUSES(context.py:35): "otherwise the archive/supersede/redact controls are decorative." that argument applies to pages. recall is also the one surface that runs unprompted on every SessionStart, so a retracted title reaches every future session's first turn.repro — archiving a page means setting
status: archivedin its frontmatter (the plaintext / obsidian edit path;lifecycle.archiveis claims-only). the status round-trips throughget_pagecorrectly:scope — only ARCHIVED should be filtered. DRAFT and STALE stay live knowledge, mirroring the reasoning that keeps CONTESTED in the claim set.
happy to send the fix.