tidaldb/.sdlc/features/m9-retroactive-purge/audit.md

2.4 KiB

Audit: Retroactive Signal Purge

Spec Compliance

Requirement Status Notes
FR-1: Contribution logging on signal write PASS try_cohort_attribution calls contribution_log.push() after each cohort_ledger.record()
FR-2: retract() on ledger with CAS floor at 0 PASS HotSignalState::subtract_contribution, BucketedCounter::subtract_bucket both implemented with 0 floor
FR-3: PurgeManifest persisted to Tag::PurgeManifest key PASS db/purge.rs writes to encode_key(user_id, PurgeManifest, purge_id.to_be_bytes())
FR-4: WAL event (original spec) DEFERRED Conscious design decision: storage manifest used instead; WAL replay covered by m9-purge-rematerialization
FR-5: request_community_purge() public API PASS Returns (PurgeId, PurgeManifest)
FR-6: Idempotency — second purge is no-op PASS Log is drained on first purge; second purge finds empty log
FR-7: Thread safety via Mutex<VecDeque> PASS All log access is mutex-guarded

Architecture Compliance

  • Single responsibility: PurgeCoordinator handles in-memory retraction only; db/purge.rs handles storage I/O. Clean separation.
  • No WAL dependency from purge path: purge writes to storage directly, avoids coupling to WAL format.
  • Lock-free hot path: signal writes only hold the contribution log mutex for push(), which is O(1). CAS loops in hot/warm tier are unblocked.
  • #[allow(dead_code)] on struct fields that are wired but not yet read by external code — appropriate for staged implementation.

Security / Correctness

  • subtract_contribution accounts for decay since contribution time — correctly removes the decayed portion of weight, not the full original weight.
  • Score floors at 0.0 throughout — no negative scores possible.
  • Multi-user isolation: drain_for(user_id, cohort) filters by both dimensions; other users' records untouched.
  • evicted_before_purge in manifest signals to m9-purge-rematerialization when a full WAL replay is needed for correctness.

Test Coverage

  • 5 unit tests in cohort::purge::tests
  • ~8 unit tests in cohort::contribution::tests
  • 8 integration tests in tests/m9_retroactive_purge.rs
  • 1299 lib tests passing
  • fmt clean, build clean

Verdict

APPROVED. Implementation correctly satisfies all in-scope requirements. The WAL-event deferral is a documented design decision consistent with the existing re-materialization architecture.