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

@ -416,8 +416,13 @@ Suggested audit envelope:
```yaml
request_id: req-...
timestamp: ...
event_class: audit.allow | audit.deny
stream_id: qonto-assistant.audit
stream_instance_id: ...
stream_sequence: ...
actor: agt-... / workload id
tenant_id: binky
identity_binding: self_asserted | key_cape_jwt
capability: list_transactions
protocol: rest | mcp
decision: allow | deny
@ -426,9 +431,15 @@ policy_version: 1
latency_ms: ...
qonto_http_status: ...
result_count: ...
egress_destination: qonto-thirdparty-api
# never: Authorization header, API_KEY, OpenBao token, full IBAN by default
```
The load-bearing `audit.deny` class uses the source-owned cadence and
reconciliation contract in `specs/audit-emission-cadence.yaml`. Heartbeats
carry cumulative and per-window source transition counts; observers compare
those counts and per-instance sequence numbers with received records.
### 4.11 Operational guardrails (v1, not "later if we remember")
Basic safety and reliability controls belong in Phase 1 because one noisy

View file

@ -0,0 +1,66 @@
# Source-owned declaration for the qonto-assistant structured audit stream.
# The semantic shape follows the Taxonomy draft in
# kings-guard/specs/EmissionCadenceDeclaration.md. This repository owns the
# concrete emission claim even while the fleet-wide schema remains a draft.
audit_emission_cadence:
schema_version: "0.1"
source: qonto-assistant
stream_id: qonto-assistant.audit
transport: structured-stdout
instance_boundary: process
ordering:
instance_field: stream_instance_id
sequence_field: stream_sequence
sequence_starts_at: 1
gap: finding
reset: permitted-only-when-stream_instance_id-changes
event_classes:
audit.allow:
evidence_class: attributive
completeness_claimed: false
audit.deny:
evidence_class: load-bearing
form: heartbeat-or-reconciliation
rate_monitoring: forbidden
completeness_claimed: true
audit.heartbeat:
evidence_class: load-bearing
role: positive-liveness-and-reconciliation-claim
heartbeat:
event_class: audit.heartbeat
interval: PT24H
interval_config: QONTO_AUDIT_HEARTBEAT_INTERVAL_SECONDS
default_interval_seconds: 86400
lifecycle:
startup: required
periodic_while_process_active: required
shutdown: best-effort
quiet_assertion: nothing-to-report
active_instance_missing: finding
scale_to_zero_semantics: >
No periodic heartbeat is promised while no process instance exists.
Observers track each stream_instance_id from its startup heartbeat until
a shutdown heartbeat or expiry after a missing active-instance cadence.
reconciliation:
source_counts_field: source_transition_counts
window_counts_field: window_transition_counts
counted_classes:
- audit.allow
- audit.deny
snapshot_endpoint: /v1/audit/reconciliation
compare_observed: >
Count received request events by event_class and stream_instance_id, then
compare them with the heartbeat source counts and stream sequence.
divergence: finding
undrained_local: lag-not-divergence
persistence: process-local
event_context:
identity_binding_field: identity_binding
egress_destination_field: egress_destination
qonto_egress_destination: qonto-thirdparty-api

View file

@ -1,9 +1,9 @@
# Security Genome record for qonto-assistant.
#
# Schema per kings-guard/specs/NetKingdomImmuneArchitecture.md §9.1
# ("Minimum Genome Record"). Kings Guard does not exist as a running system
# yet — this record is written now so no rework is needed once an admission
# or posture-assessment consumer does exist. See docs/SecurityPractice.md.
# ("Minimum Genome Record"). King's Guard now consumes this source's structured
# audit events; the adjacent cadence declaration supplies stream-completeness
# semantics without making the consumer an authority for source intent.
security_genome_record:
id: kg:genome:qonto-assistant
@ -24,7 +24,7 @@ security_genome_record:
criticality: high
identities:
workload_identity: "TBD — pending key-cape/workload-identity integration (QONTO-WP-0004)"
workload_identity: "key-cape JWT verification supported; runtime enforcement is configuration-bound"
deployment_identity: "TBD — pending Railiance placement decision"
capabilities:
@ -84,3 +84,8 @@ security_genome_record:
bound to verified identity. Tolerated until key-cape/flex-auth
integration (QONTO-WP-0004) closes this.
expires_at: null
# Source emission claim for the load-bearing deny observation class. The full
# machine-readable declaration is kept separate so consumers can ingest it
# without interpreting the genome schema.
audit_emission_cadence: audit-emission-cadence.yaml