feat(audit): publish sequenced heartbeat and reconciliation evidence

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a06ec5-7e2b-7743-ac08-719e1b0f42e2
This commit is contained in:
tegwick 2026-09-05 01:39:48 +02:00
parent fce60099c4
commit b9349782f4
32 changed files with 839 additions and 111 deletions

View file

@ -0,0 +1,25 @@
---
id: ADHOC-2026-09-05
type: workplan
title: "Clear verification lint failures and stale scope status"
domain: infotech
repo: qonto-assistant
status: finished
owner: codex
created: "2026-09-05"
updated: "2026-09-05"
---
## Restore clean static checks
```task
id: ADHOC-2026-09-05-T01
status: done
priority: low
```
Applied Ruff import and formatting corrections to existing source/tests and
shortened one docstring to clear the 44 repository lint failures. Corrected
SCOPE.md's stale runtime-not-started entry. Full Ruff checks and the 88-test
suite pass using the existing venv directly. Make bootstrap remains dependent
on pip, which this workstation's existing venv does not contain.

View file

@ -0,0 +1,107 @@
---
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.