feat(audit): M5.6 SourceNode sentinel backfill (purge-role) + CLI + runbook note (T5)
This commit is contained in:
@@ -386,6 +386,44 @@ component (Options pattern):
|
||||
Notification List / Database Connection name. `RetentionDays` is a single
|
||||
global value in v1; per-channel overrides are deferred to v1.x.
|
||||
|
||||
## Ops Notes — Historical Null Columns
|
||||
|
||||
### `SourceNode` backfill (M5.6 T5)
|
||||
|
||||
`SourceNode` (`varchar(64)` NULL) is a physical column stamped on every row at
|
||||
write time. Rows ingested before M5.6 shipped have `SourceNode IS NULL` because
|
||||
the value was not populated until the feature landed. A one-time CLI command sets
|
||||
these to a configurable sentinel:
|
||||
|
||||
```
|
||||
scadabridge audit backfill-source-node --before <ISO-8601-UTC> [--sentinel unknown] [--batch 5000]
|
||||
```
|
||||
|
||||
The default sentinel is `"unknown"`. The true node-of-origin for pre-feature rows
|
||||
is **unknowable** retroactively — the emitting node is long gone from the telemetry
|
||||
pipeline. The sentinel makes that explicit rather than leaving the column NULL
|
||||
(which the Audit Log UI's Node filter already treats as "unresolved", but which
|
||||
an operator might mistake for a data-quality bug).
|
||||
|
||||
The backfill runs via `POST /api/audit/backfill-source-node` (Admin role required)
|
||||
on the maintenance/purge path, NOT the append-only `scadabridge_audit_writer` role.
|
||||
It is idempotent and can be re-run safely.
|
||||
|
||||
### `ExecutionId` and `ParentExecutionId` — cannot be backfilled
|
||||
|
||||
`ExecutionId` and `ParentExecutionId` are **PERSISTED COMPUTED columns** derived
|
||||
from `DetailsJson`. They were introduced in the same feature window as the column
|
||||
itself but their value comes from the JSON payload that was written at ingest time.
|
||||
|
||||
The AuditLog append-only invariant **forbids mutating `DetailsJson`** — rows may
|
||||
only be inserted, never updated. Because backfilling the computed values would
|
||||
require rewriting the underlying `DetailsJson`, it is impossible under the
|
||||
append-only contract. Pre-feature rows carry `NULL` in both columns permanently.
|
||||
|
||||
This is a documented limitation, not a defect. The NULL values are visible in the
|
||||
Audit Log UI's execution-tree drilldown (rows with no `ExecutionId` appear as
|
||||
orphaned entries) and in the CLI's `audit tree` output.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **[Commons (#16)](Component-Commons.md)** — `AuditEvent`, `IAuditWriter` /
|
||||
|
||||
Reference in New Issue
Block a user