QONTO-WP-0003-T05: pin REST/MCP audit-schema parity with a test
CapabilityService._emit_audit was already the single audit call site for both transports since T02, but nothing failed if a future change diverged one transport's shape. Add tests/test_audit_parity.py: same capability called through protocol="rest" and protocol="mcp" (allow path and deny path) must produce identical audit events except request_id/timestamp/ latency_ms (expected to vary) and protocol (expected to differ). Also pins down that no audit event ever contains a secret-shaped field name. Confirmed via grep: no State Hub coupling anywhere in src/qonto_assistant/ -- the only audit sink is AuditLogger, so there's no per-call hot-path write to accidentally wire up. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
0b268faf05
commit
c3e69373ca
2 changed files with 122 additions and 1 deletions
|
|
@ -218,7 +218,7 @@ its own scope note. `pytest` → `28 passed` (unchanged).
|
|||
|
||||
```task
|
||||
id: QONTO-WP-0003-T05
|
||||
status: todo
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "b7d70c3e-fe55-47d9-9180-cd4c0bedc31a"
|
||||
```
|
||||
|
|
@ -232,6 +232,26 @@ hot-path events — do not wire per-invocation State Hub writes.
|
|||
Done when: a test asserts REST and MCP audit records for the same capability
|
||||
call are schema-identical modulo protocol field.
|
||||
|
||||
**Done 2026-07-23:** This was already true structurally since T02
|
||||
(`CapabilityService._emit_audit` is the single audit call site for both
|
||||
transports), but it wasn't pinned down by a test — a future change could
|
||||
have special-cased one transport's shape without anything failing. Added
|
||||
`tests/test_audit_parity.py`: calls the same capability through
|
||||
`protocol="rest"` and `protocol="mcp"` for both an allow path
|
||||
(`org_summary`) and a deny path (`list_transactions` oversized `page_size`
|
||||
→ `arg_constraint`), then asserts the two events have identical key sets
|
||||
and identical values on every field except `request_id`/`timestamp`/
|
||||
`latency_ms` (expected to vary per call) and `protocol` (expected to
|
||||
differ by design). A third test asserts no audit event ever contains a
|
||||
secret-shaped field name (`api_key`, `authorization`, `token`, etc.) —
|
||||
belt-and-suspenders alongside `tests/test_audit.py`'s existing redaction
|
||||
test.
|
||||
|
||||
Confirmed (`grep`) there is no State Hub coupling anywhere in
|
||||
`src/qonto_assistant/`: the only audit sink is `AuditLogger` (structured
|
||||
stdout JSON, or a test-injected `sink` callable) — no per-call State Hub
|
||||
write exists to accidentally wire up. `pytest` → `31 passed`.
|
||||
|
||||
## Task: MCP smoke path + operator runbook update
|
||||
|
||||
```task
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue