A community based topic aggregation platform built on atproto

fix(cutover): task 8 re-review on Opus 5 — the migration tool was not safe to run master

Re-review of the cutover tool on a stronger model. It has never been run against production, so all of this is pre-flight. Seven blockers, two of which I verified by hand before assigning the work. FALSE-SUCCESS NO-OP: hostedCommunityDIDs filtered communities on PDSRefreshToken != "", but the List query never selects that column — only GetByDID decrypts it. Every community was filtered out, so a default all-communities run would have migrated NOTHING, reported Complete=true and exited 0. Now uses a dedicated DIDs-only query that never decrypts secrets into a listing path. TAUTOLOGICAL VERIFY: the acceptance guard compared SubjectRkey(X) to SubjectRkey(X) — a check that cannot fail — and the acceptance was never read back at all. On a clean run that is 100% of posts deleted having verified only one of the two records. Now reads the acceptance out of the community repo and asserts its subject uri and cid. UNGUARDED DELETE: the legacy body was snapshotted at t0 and deleted hours later with no swapRecord and no CID re-check, so any write that slipped past the maintenance window was destroyed silently. The delete is now interlocked three ways: a fresh source-CID re-read, a PDS-enforced swap guard, and fresh reads of the postv2, the acceptance and the blobs — on every path including resume, which previously treated a checkpoint as timeless authorization. TERMINAL-STATE TRAP: any ResumeSession failure — a network blip, or a session merely past its 7-day TTL — was classified as "no credentials" and written as a state with no way back. The Kagi aggregator authors most of prod, so one blip would have marked the whole corpus terminal and made every later run a no-op. Split into terminal vs retryable, credentials resolved once per author, plus -reopen-fallbacks and an abort-before-mutating default. Also: -community scope now enforced on the destructive paths (a staged run could delete another community's rows), completion gated on a final source re-scan, community blobs fetched from the community's host, truncated-blob overrun caught, and the operator surface built out — dry-run, target banner, confirmation, progress, advisory lock, signal handling, timeouts, rate limiting, and a census that prints on the error path. Tests: 14 mutations introduced, confirmed red, reverted. The suite previously asserted verify-before-delete more than it proved it — the re-run tests were structurally vacuous (early return on a done ledger row), the verify read-back's error branch was unexercised, rkey determinism was pinned only within one process (a per-process salt would have duplicated every post on the first restart), and the ledger's from-state guards could be stripped wholesale with a green suite. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QDvRJ45k6E5KrBARDHUtiM