Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a06ec5-7e2b-7743-ac08-719e1b0f42e2
107 lines
4.7 KiB
Markdown
107 lines
4.7 KiB
Markdown
---
|
|
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.
|