tidaldb/.sdlc/features/p1-feedback-loop-ux/audit.md

63 lines
4.0 KiB
Markdown

# Audit: Feedback Loop UX
## Scope
Security, data integrity, and operational audit of the feedback loop UX feature (`p1-feedback-loop-ux`).
## Security
### Input Validation
- [x] **user_id and entity_id are opaque integers.** No string parsing, no injection vectors.
- [x] **creator_id in MuteCreator/UnmuteCreator is a u64.** No trust boundary crossed -- the caller provides the creator_id, and the method trusts it. This matches existing patterns (e.g., `signal_with_context` accepts user_id without validation).
- [x] **No new network endpoints.** This feature adds only in-process Rust API methods. No HTTP routes, no deserialization of external input.
- [x] **`require_writeable` guard** prevents writes on read-only follower nodes, maintaining the leader-follower invariant.
### Authorization
- [x] **No authorization model in scope.** The feedback API trusts the caller to pass the correct user_id. This is consistent with all other `TidalDb` methods (signal, retrieve, search). Authorization is an application-layer concern.
- [x] **No privilege escalation.** A user can only affect their own feedback state. The `user_id` parameter scopes all operations.
### Data Leakage
- [x] **`feedback_state` only returns boolean flags.** No signal values, no embeddings, no metadata leaked through this API.
- [x] **Skip counter is ephemeral.** Resets on restart. No durable record of how many times a user skipped an item (only the final hard-neg promotion is visible).
## Data Integrity
### Atomicity
- [x] **Each `submit_feedback` call performs all side effects synchronously** before returning `Ok(())`. There is no partial-apply failure mode where a signal is written but the bitmap is not updated.
- [x] **Exception: WAL write failure.** If `self.signal()` returns an error (e.g., backpressure), the method returns `Err` immediately. No bitmap updates have occurred yet because the signal write happens first in all action branches. This is correct: the method is fail-fast, and the caller can retry.
### Durability
- [x] **Signal-writing actions are WAL-durable.** Like, Hide, Dislike, MuteCreator, NotInterested all call `self.signal()` which writes to the WAL.
- [x] **Unhide writes a negative-weight signal** for durability (weight=-1.0 on "hide" signal type). This ensures the unhide survives restart via WAL replay.
- [x] **Undo-only actions (Unlike, UndoDislike, UnmuteCreator, Unsave) are ephemeral.** This is by design and documented in the spec. After restart, the undo state is lost unless the application replays it.
### Consistency
- [x] **DashMap provides sequential consistency** within a single process. A write on thread A followed by a read on thread B sees the write.
- [x] **No stale reads possible** within the same process, because there is no caching layer between the bitmap writes and the query pipeline reads.
- [x] **Cross-node replication is eventually consistent.** Signal writes propagate via WAL shipping. Bitmap state is rebuilt from WAL on followers. This is documented in the spec as a non-goal for immediate cross-node reflection.
## Operational Impact
### Memory
- [x] **skip_counter: DashMap<(u64, u32), u8>.** Each entry is ~17 bytes (key: 12 bytes, value: 1 byte, overhead: ~4 bytes). At 1M unique user-item skip pairs, this is ~17MB. Acceptable for a single-node database.
- [x] **No new background threads.** No new timers, no new channels, no new periodic tasks.
### Performance
- [x] **No regression on hot paths.** `submit_feedback` does not add any overhead to `signal()`, `retrieve()`, or `search()`. It is a new entry point, not a wrapper around existing hot paths.
- [x] **feedback_state is O(1).** 4 DashMap lookups, no iteration, no I/O.
### Monitoring
- [x] **No new metrics.** The existing signal write metrics (WAL append latency, signal count) already cover the signal-writing actions. Feedback-specific metrics (e.g., hide rate, mute rate) can be added as a future feature.
## Verdict
**APPROVED.** No security, data integrity, or operational concerns. The feature is safe for production use.