M2: durable audit events - #57
Conversation
Spec §14 audit log: every run records authorizer, source, packet version, permissions, access, requests, responses, artifacts, and final status. These tests pin the durable half M2 owns: a closed ten-kind taxonomy, a backend-stamped dense per-record sequence that clients cannot forge, bounded detail text, unknown_run splits, restart survival, and the single-item list-envelope admission probe. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Spec §14 audit log, S14-005, roadmap M2 audit store. Migration 12 adds audit_events: one recorded fact per row in a run's accountability trail, under a closed ten-kind taxonomy with a backend-stamped dense per-record sequence that clients cannot forge. record_audit_event admits bounded detail against the single-item list envelope at ceiling stamps; list_audit_events pages the trail in sequence order, keeping its start under the frame budget. Swift AuditEvent/AuditEventPage. Also stops four persistence tests from opening the user's real default store, which raced on the owner flock under parallel runs and left test residue in user data (recorded in the verification summary). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
| let mut events = | ||
| match store.list_audit_events(&record_id, LIST_AUDIT_EVENTS_LIMIT + 1) { | ||
| Ok(events) => events, | ||
| Err(error) => { | ||
| eprintln!("store read error: {error}"); | ||
| return write_protocol_error(&mut stream, "store_unavailable"); | ||
| } | ||
| }; | ||
| let mut truncated = events.len() > LIST_AUDIT_EVENTS_LIMIT; | ||
| events.truncate(LIST_AUDIT_EVENTS_LIMIT); |
There was a problem hiding this comment.
Truncated trails cannot continue
When a run has more than 50 audit events, or the response exceeds the byte budget, list_audit_events returns only the earliest bounded prefix with truncated set but accepts no cursor or offset. Clients therefore cannot retrieve later durable facts, including a final status, leaving the accountability trail incomplete through the protocol.
Prompt To Fix With AI
This is a comment left during a code review.
Path: backend/src/lib.rs
Line: 2322-2331
Comment:
**Truncated trails cannot continue**
When a run has more than 50 audit events, or the response exceeds the byte budget, `list_audit_events` returns only the earliest bounded prefix with `truncated` set but accepts no cursor or offset. Clients therefore cannot retrieve later durable facts, including a final status, leaving the accountability trail incomplete through the protocol.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Sol round 1: PASS, zero blockers, two MINOR test-coverage follow-ups recorded. Fresh merge-gate verify-m0 exit 0 archived. Merge withheld: user sent 'stop'; recurring job fa669dd2 cancelled, state persisted for resume (squash-merge PR #57 + closeout). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Status: paused by user, ready to merge on resume. Independent review (gpt-5.6-sol, xhigh): PASS, zero blockers — report at All ADR-007 merge conditions are green: fresh |
M2 slice 13: the audit store (spec §14 audit log; S14-005; roadmap M2 exit criterion "audit events survive restart").
audit_events: one recorded fact per row in a run's §14 accountability trail — closed case-sensitive ten-kind taxonomy (authorizer, source, packet_version, permission_granted, file_accessed, service_accessed, permission_requested, user_response, artifact, final_status), backend-stamped dense per-recordseqthat clients cannot forge (forgedseq/at_msignored, pinned by test + demo), bounded detail.record_audit_event: double-Option record_id, unknown_run split, single-item list-envelope admission probe at i64::MAX stamp ceilings before insert (mutant-proven binding);list_audit_events: seq-ordered, limit-51 truncation probe, end-popping byte budget keeping the trail's start.AuditEvent/AuditEventPage+ request builders/decoders/tests.TDD: red-first vs merged main 5c82fab (unknown_request_type ×3). Gates: 172 Rust + 62 Swift tests, fmt, clippy -D warnings, verify-m0.sh exit 0. Real-binary demo: self-contained hand-built v11 fixture migrated 11→12, legacy run gains a trail, all ten kinds recorded, restart survival, 0600. Evidence:
.loop/verification/m2-audit-events/.Traceability: S14-005 → in_progress with this PR (durable store + protocol; fact producers land M6/M9).
🤖 Generated with Claude Code
Greptile Summary
This PR adds durable, backend-sequenced audit events for runs, including migration, Rust protocol/store support, and Swift client models.
Confidence Score: 4/5
The PR should not merge until truncated audit trails provide a way to retrieve later events.
Runs exceeding the count or byte limit expose only their earliest audit events; the backend and Swift client still provide no cursor or offset for retrieving the omitted tail.
Files Needing Attention: backend/src/lib.rs, backend/src/store.rs, Sources/CaptureDelegateIPC/IPCClient.swift
Important Files Changed
Reviews (2): Last reviewed commit: "Record Sol PASS review and user-stop pau..." | Re-trigger Greptile