Skip to content

Empty the corpus once, and keep everyone signed in - #216

Merged
Parshkov merged 1 commit into
mainfrom
claude/empty-the-corpus-once
Sep 7, 2026
Merged

Empty the corpus once, and keep everyone signed in#216
Parshkov merged 1 commit into
mainfrom
claude/empty-the-corpus-once

Conversation

@Parshkov

@Parshkov Parshkov commented Sep 7, 2026

Copy link
Copy Markdown
Owner

What this changes

Production holds eight thoughts, all of them written here to prove a path worked, plus the alerts they raised against each other and an accepted introduction whose own thought had already been deleted. The first person to arrive cannot tell a test from a stranger, and would have been introduced to one.

RESONANCE_PURGE_CORPUS=report|1 — one-shot, same shape as the two purges already in the runbook — removes every thought, every standing-search alert, every introduction, every conversation and every shared topic, and leaves accounts, sign-ins and OAuth client registrations alone. That distinction is the whole point: python3 -m src.persistence … reset also wipes both, so reaching the same empty corpus through it would sign everyone out and make every connected MCP client re-authorize.

It takes no exceptions, and refuses RESONANCE_PURGE_KEEP rather than ignoring it — an operator who sets it expects something to survive, and removing named thoughts is already RESONANCE_PURGE_SESSIONS.

Two defects found on the way, both leaving rows behind

  • RESONANCE_PURGE_SESSIONS never retracted standing-search alerts. It calls live.delete_session directly and so bypasses the product's _retract. Worse, retract_for_session only ever reached the owner's half of a pair: the alert recorded for the person on the other end kept naming a deleted thought until whenever they next looked. It now retracts both sides. This is what produced the ghost found in production — an accepted intro whose from_session_id no longer exists.
  • reset() and import_payload() forgot eight tables. Both cleared intros/channels/messages and left every workspace* table standing, so a "reset" store still held every shared topic. Both now name one list, CONNECTION_TABLES.

Evidence

python3 -m unittest discover -s tests

Ran 711 tests … OK (skipped=1) against PostgreSQL 16 (RESONANCE_TEST_POSTGRES_URL). Six of those are new, in tests/test_purge_corpus.py, covering: the variable being unset or unrecognised does nothing; report counts without moving anything; 1 empties sessions/alerts/intros/channels/messages while accounts and an OAuth client registration survive and the index stays current; a second run finds nothing left to do; KEEP is refused; and PURGE_SESSIONS retracts the counterpart's alert. One alert in the applied-case test is deliberately owned by an account that is not in users — that is what an alert looks like after its owner is revoked, and walking live accounts would never reach it, which is why the store gained delete_grants_of_kind.

Engine untouched — no scoring, alignment, extraction or index change — so the policy version does not move and the gates are unaffected.

Checklist

  • CI is green.
  • benchmark/ gold is unedited.
  • Engine behaviour unchanged; no policy version move and no ADR needed.
  • ROADMAP.md corrected: it opened on "Seven shared thoughts exist in the world" and now says none do, with why.
  • No credentials, tokens or private human context committed. The purge prints counts and ids only — never a topic, a label, a message or any thought content.

🤖 Generated with Claude Code

Production held eight thoughts, all written here to prove a path worked,
plus the alerts they raised against each other and an introduction whose
own thought had already been deleted. The first person to arrive cannot
tell a test from a stranger, and would have been introduced to one.

`RESONANCE_PURGE_CORPUS=report|1` removes every thought, every
standing-search alert, every introduction, every conversation and every
shared topic — and leaves accounts, sign-ins and OAuth client
registrations alone. That distinction is the whole point: `reset` also
wipes both, so it would sign everyone out and make every connected MCP
client re-authorize to achieve the same empty corpus. It takes no
exceptions, and refuses RESONANCE_PURGE_KEEP rather than ignoring it,
because removing named thoughts is already RESONANCE_PURGE_SESSIONS.

Two defects found on the way, both of which left rows behind:

`RESONANCE_PURGE_SESSIONS` never retracted standing-search alerts,
because it calls the corpus service directly and so bypasses the
product's retract. Now it retracts both sides — an alert is a pointer to
a pair of thoughts, and `retract_for_session` only ever reached the
owner's half, leaving the counterpart's copy naming a deleted thought
until whenever they next looked.

`reset()` and `import_payload()` cleared intros, channels and messages
and forgot all eight workspace tables, so a "reset" store still held
every shared topic. Both now name one list, CONNECTION_TABLES.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Parshkov
Parshkov merged commit 5c254ef into main Sep 7, 2026
3 checks passed
@Parshkov
Parshkov deleted the claude/empty-the-corpus-once branch September 7, 2026 05:49
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