--- id: QONTO-WP-0005 type: workplan title: "Establish audit.deny stream completeness evidence" domain: infotech repo: qonto-assistant status: finished owner: codex topic_slug: qonto-audit-deny-stream-completeness created: "2026-09-04" updated: "2026-09-05" state_hub_workstream_id: "8a1bc02c-00fc-5400-af1f-10af562b9782" --- # Establish `audit.deny` stream completeness evidence Closes the qonto-assistant-owned remediation from `RISK-F-0011` and the King's Guard message received on 2026-09-01. A received deny event is already useful, but observers cannot currently distinguish a quiet stream from an incomplete one. The source therefore needs to publish its cadence, emit a positive heartbeat carrying source-side counts, and expose a reconciliation snapshot that makes missing events and sequence gaps visible. The implementation stays local to the structured audit stream. State Hub is not placed on the request hot path, and the existing in-process deny escalation loop remains independent from estate observation. ## Task: Declare cadence and reconciliation semantics ```task id: QONTO-WP-0005-T01 status: done priority: high state_hub_task_id: "e846d42b-d9e0-587e-874b-0ad8c1d5c471" ``` Publish the `audit.deny` load-bearing classification next to the security genome. Declare heartbeat behavior, active-instance lifecycle semantics, source-side counters, sequence-gap detection, and what an observer must compare. Done when the declaration is machine-readable and the operator documentation does not imply that a received event alone proves stream completeness. **Done 2026-09-04:** Added `specs/audit-emission-cadence.yaml` and linked it from the security genome. It declares the per-process sequence boundary, `audit.deny` as low-volume/load-bearing, the 24-hour active-process cadence, scale-to-zero lifecycle semantics, cumulative/window counters, and observer comparison rules. The architecture, security practice, and operator runbook now carry the same semantics. ## Task: Emit heartbeat and reconciliation evidence ```task id: QONTO-WP-0005-T02 status: done priority: high state_hub_task_id: "cdb6576a-f606-57c9-94b2-923f23c2044b" ``` Add process-instance identity, monotonic stream sequence, per-class transition counts, periodic/startup/shutdown heartbeat events, and a read-only local reconciliation view. Enrich request events with their identity binding and declared egress destination so observers no longer substitute genome constants. Done when the source emits enough information to detect a missing deny or heartbeat without introducing State Hub or another network dependency. **Done 2026-09-04:** `AuditLogger` now serializes publication under one lock, assigns a UUID process instance and monotonic sequence, counts allow/deny source transitions, and emits startup/periodic/best-effort-shutdown heartbeats with reconciliation counters. `GET /v1/audit/reconciliation` returns the same non-secret local state without incrementing it. REST/MCP request records carry `identity_binding` (`self_asserted` or `key_cape_jwt`) and `egress_destination: qonto-thirdparty-api`. The app rejects split injected audit loggers so request events and heartbeat evidence cannot silently land in different streams. ## Task: Verify and hand back the finding ```task id: QONTO-WP-0005-T03 status: done priority: high state_hub_task_id: "e5ed80bd-f0aa-5473-a185-ecb9f87ab21c" ``` Cover sequencing, counts, heartbeat windows, reconciliation output, REST/MCP parity, identity binding, and secret redaction in tests. Run the full local suite, sync the workplan to State Hub, and notify Risk Nexus and King's Guard with the source-owned evidence and any remaining deployment observation gate. **Done 2026-09-04:** Full suite passed (`85 passed`); changed-file Ruff checks, YAML parsing, `compileall`, `git diff --check`, REST smoke, and MCP smoke all passed. Both smoke runs visibly emitted startup/shutdown heartbeats with contiguous sequences and matching counts. Source implementation is complete; deployment and independent observer acceptance remain with the runtime owner, King's Guard, and Risk Nexus rather than as unfinished source work here. **Review 2026-09-05:** Reviewed the pending implementation against its cadence contract. Fixed client cleanup when shutdown audit publication fails, added regressions for cleanup and split stream rejection, and verified concurrent heartbeat/request publication ordering. Replaced timing-sensitive periodic test sleep with an explicit event. Final verification: 88 tests passed, full-source Ruff, compileall, YAML parsing, and REST/MCP fixture smoke checks passed. Runtime deployment and independent observer acceptance remain external gates. No new cross-repo messages were sent during this review.