test+docs(m5): M5.7 — de-date 2 EndToEnd purge tests (closes #52); document T3-T8 in Component-AuditLog/-CLI/README/CLAUDE

Tests: anchor SeedOccurredAt() to a fixed thresholdAnchor (2026-01-20) and compute
RetentionDays dynamically (UtcNow - anchor + 1d) so the threshold always sits near
Jan 20 2026, between the Jan-15 "old" seed (purged) and Apr-15/Jun-15 "kept" seeds.
Seed dates stay within the explicit pf_AuditLog_Month boundary range (Jan 2026 –
Dec 2027) — relative-from-now offsets landed before 2026-01-01 (the catch-all
partition, invisible to GetPartitionBoundariesOlderThanAsync). Both tests confirmed
passing; all 284 AuditLog tests green.

Docs:
- Component-AuditLog.md: per-channel retention overrides (T3, PerChannelRetentionDays
  + bounded DELETE + AuditLogPurge:ChannelPurgeBatchSize); ParentExecutionId tag-cascade
  now spans alarm-triggered + nested CallScript/CallShared + inbound→routed (T4, "no
  further spawn points deferred"); per-node stuck KPIs for Notification Outbox +
  Site Call Audit (T6); T7 structured response-capture increments (request headers in
  Extra.requestHeaders, AuditInboundCeilingHits counter, per-method SkipBodyCapture);
  T8 CLI audit tree; T1 hash-chain + T2 Parquet explicitly marked deferred to v1.x.
- Component-CLI.md + README.md: document audit tree --execution-id <guid> and
  audit backfill-source-node --sentinel/--before/--batch with exact options verified
  against AuditCommands.cs; update Interactions to list new endpoints.
- CLAUDE.md: update audit-log design-decision bullets for T3 per-channel retention,
  T4 tag-cascade complete, T6 per-node KPIs, T7 inbound capture increments, T8 tree
  command; clarify T1/T2 remain deferred to v1.x.
This commit is contained in:
Joseph Doherty
2026-06-16 22:26:09 -04:00
parent 1b63d6751f
commit 639e331db1
6 changed files with 320 additions and 127 deletions
+56 -13
View File
@@ -1269,15 +1269,18 @@ script-trust-boundary action: outbound API calls (sync + cached), outbound DB
operations (sync + cached), notifications, and inbound API calls. This is distinct
from the configuration-change audit trail exposed by [`audit-config`](#audit-config--configuration-change-audit-log).
The subcommands map directly onto the `GET /api/audit/query` and
`GET /api/audit/export` management endpoints. Filters and the result columns mirror
the Central UI **Audit** page, so a CLI query and a UI query with the same filters
return the same rows — CLI ↔ UI filter parity is intentional.
The subcommands map directly onto the `GET /api/audit/query`,
`GET /api/audit/export`, `GET /api/audit/tree`, and
`POST /api/audit/backfill-source-node` management endpoints. Filters and the
result columns mirror the Central UI **Audit** page, so a CLI query and a UI
query with the same filters return the same rows — CLI ↔ UI filter parity is
intentional.
**Permissions.** Querying requires the `OperationalAudit` permission (roles `Admin`,
`Audit`, or `AuditReadOnly`). Exporting requires the stricter `AuditExport` permission
(roles `Admin` or `Audit`) — read access does *not* imply export access. A request
without the required role returns exit code `2`.
**Permissions.** Querying and tree traversal require the `OperationalAudit`
permission (roles `Admin`, `Audit`, or `AuditReadOnly`). Exporting requires the
stricter `AuditExport` permission (roles `Admin` or `Audit`) — read access does
*not* imply export access. The `backfill-source-node` maintenance command requires
the `Admin` role. A request without the required role returns exit code `2`.
#### `audit query`
@@ -1342,6 +1345,46 @@ scadabridge --url <url> audit export --since <time> --until <time> --format <fmt
> Implemented` — Parquet archival is deferred to v1.x (see `Component-AuditLog.md`).
> Use `csv` or `jsonl`.
#### `audit tree` (M5.3 T8)
Display the full execution-chain tree for a given execution ID. The server walks
`ParentExecutionId` to find the root, then traverses downward to collect all
reachable executions in the chain.
```sh
scadabridge --url <url> audit tree --execution-id <guid> [--format table|json]
```
| Option | Required | Default | Description |
|--------|----------|---------|-------------|
| `--execution-id` | yes | — | Any `ExecutionId` in the chain (root or child) |
| `--format` | no | `json` | Output format: `json` (structured tree) or `table` (indented tree) |
The `--execution-id` can be any node in the chain — the server resolves the root
automatically. With `--format table` the tree is printed as an indented text
representation. With `--format json` (the default) a structured JSON tree is
returned, suitable for scripting. Backed by `GET /api/audit/tree?executionId=<guid>`.
Requires `OperationalAudit` permission.
#### `audit backfill-source-node` (M5.6 T5)
Set `SourceNode` to a sentinel value on pre-feature rows where `SourceNode IS NULL`
and `OccurredAtUtc` is older than `--before`. Admin-only maintenance command.
```sh
scadabridge --url <url> audit backfill-source-node --before <ISO-8601-UTC> [--sentinel <value>] [--batch <n>]
```
| Option | Required | Default | Description |
|--------|----------|---------|-------------|
| `--before` | yes | — | ISO-8601 UTC datetime; only rows older than this date are eligible |
| `--sentinel` | no | `unknown` | Value to write (must be non-empty) |
| `--batch` | no | `5000` | Max rows updated per batch; controls transaction size |
The command is idempotent — running it multiple times converges (only rows where
`SourceNode IS NULL` are eligible; already-set rows are untouched). Backed by
`POST /api/audit/backfill-source-node`. Requires `Admin` role.
#### `audit verify-chain`
Verify the audit log hash chain for a given month.
@@ -1354,11 +1397,11 @@ scadabridge --url <url> audit verify-chain --month <YYYY-MM>
|--------|----------|---------|-------------|
| `--month` | yes | — | Month to verify, `YYYY-MM` (e.g. `2026-05`) |
> **v1 no-op.** Hash-chain tamper-evidence is not enabled in this release. The
> subcommand validates the `--month` argument and prints a notice pointing at the
> v1.x roadmap in `Component-AuditLog.md`; it exits `0` without contacting the server.
> The command exists now so scripts and operator habits do not need to change when
> tamper-evidence ships.
> **v1 no-op.** Hash-chain tamper-evidence is not enabled in this release (T1
> deferred to v1.x). The subcommand validates the `--month` argument and prints a
> notice pointing at the v1.x roadmap in `Component-AuditLog.md`; it exits `0`
> without contacting the server. The command exists now so scripts and operator
> habits do not need to change when tamper-evidence ships.
---