diff --git a/docs/deployment/deploy-prep/2026-11-13-qa-vq03-vq04/README.md b/docs/deployment/deploy-prep/2026-11-13-qa-vq03-vq04/README.md index c03e943f..f56fcb3e 100644 --- a/docs/deployment/deploy-prep/2026-11-13-qa-vq03-vq04/README.md +++ b/docs/deployment/deploy-prep/2026-11-13-qa-vq03-vq04/README.md @@ -258,9 +258,18 @@ Run them from the Mac over HTTP, SQL, SMB and the CLI. No ad-hoc WinRM, except t - **In this window: the chain stays OFF on QA** (`AuditLog:HashChain:Enabled` is unset, so false). The migration only adds the columns, tables and roles. - **After the window, as a separate step:** - 1. SourceNode backfill first, because a chained row's `SourceNode` is frozen. Run `scadabridge audit backfill-source-node --before 2026-07-08T00:00:00Z --sentinel unknown`, which covers the 843 pre-M5.6 rows (Admin; idempotent). Then confirm that `preflight.sql` §6 shows 0 NULLs. - 2. Then set `AuditLog:HashChain:Enabled=true` on both centrals and restart them **together**. - 3. **"No backlog chaining" (only rows written after enablement): ⚠ BLOCKED, #139.** On `main` the chaining job links *every* unchained row, oldest first (`AuditLogHashChain.cs:102`), and has no cutoff option. Enabling it on QA as the code stands would chain all 3,441+ historical rows, which is the opposite of the decision. Wait for #139 (a cutoff option, or a revised decision) before step 2. + 0. **Build: needs the #139 cutoff.** "No backlog chaining" is implemented on `main` from `52da02a7` (#139): the first chaining pass records a chain-start anchor at the database's `SYSUTCDATETIME()` and only rows dated from then on are chained. **`3a59c3f6` does not have it**: enabling the chain on `3a59c3f6` would chain all 3,441+ historical rows. So either run this window at a tip that contains `52da02a7` (it adds **no migration**: the script in §2.2 is unchanged, re-check only the option delta), or ship such a build before step 2. Confirm with `Host.dll` ProductVersion. + 1. SourceNode backfill first, because a chained row's `SourceNode` is frozen. Run `scadabridge audit backfill-source-node --before 2026-07-08T00:00:00Z --sentinel unknown`, which covers the 843 pre-M5.6 rows (Admin; idempotent). Then confirm that `preflight.sql` §6 shows 0 NULLs. (With the cutoff the backlog is never chained, so its `SourceNode` is never frozen: the order no longer matters, but running it first keeps the documented #107 sequence.) + 2. Then set `AuditLog:HashChain:Enabled=true` on both centrals and restart them **together**. **Do not set `AuditLog:HashChain:ChainBacklog`** (default `false` = no backlog chaining, the owner decision). It is only read on the very first enablement; the first pass fixes the cutoff in the database and both nodes use it from then on. + 3. **Verify the cutoff** (direct SQL, read-only, a minute after start): + ```sql + SELECT ChainMonth, PurgedAtUtc AS ChainFromUtc FROM dbo.AuditLogChainTombstone WHERE ChainSeq = 0; -- exactly 1 row, at about the restart time + SELECT COUNT_BIG(*) FROM dbo.AuditLog WHERE ChainSeq IS NOT NULL + AND OccurredAtUtc < (SELECT PurgedAtUtc FROM dbo.AuditLogChainTombstone WHERE ChainSeq = 0); -- 0: no backlog row chained + SELECT COUNT_BIG(*) FROM dbo.AuditLog WHERE ChainSeq IS NULL; -- about the 3,441+ backlog, unchanged + ``` + Then `scadabridge audit verify-chain --month --format table`: `Intact`, `Chain from` = the anchor time, `Pre-cutoff rows` = this month's backlog, `Unchained rows` 0 (or a minute's worth). An earlier month shows `NotChained` with its rows as `Pre-cutoff rows`. Exit code 0 throughout. + 4. **Rollback of the enablement only:** unset `Enabled` and restart. The anchor and any chained rows stay (harmless; chaining resumes from them if re-enabled). Do not delete the anchor row: that is exactly what `verify-chain` reports as tampering. - **Head export: File sink to a UNC share** that the DB login cannot write. The service account gets create + append-data only. To add once the share is named, with `HashChain:Enabled`: ```jsonc "AuditLog": { "HashChain": { "HeadExport": { @@ -304,4 +313,4 @@ Run them from the Mac over HTTP, SQL, SMB and the CLI. No ad-hoc WinRM, except t - **#131:** QA has **nothing** to change (deploy-prep `2026-11-12-gates-52-131`). - **#52:** `CvdReactor.ProcessRecipeDownload` on QA still addresses `Children["DelmiaRecv"]`. The fix (`2026-11-12-gates-52-131/apply.sh apply 52`) is binary-independent, but it **redeploys Z28061–Z28069**, including **Z28061**. **Not bundled by default.** If the owner agrees a Z28061 slot in the same go, run it after G12, so there is still only one redeploy. -- **#139 (new):** hash-chain "no backlog" gate, §7. +- **#139:** hash-chain "no backlog" cutoff, fixed on `main` at `52da02a7` (no migration). The enablement steps in §7 need a build that contains it.