40 lines
2.4 KiB
Markdown
40 lines
2.4 KiB
Markdown
# 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.
|