docs(localdb): record deviations D-6 and D-7 in the phase-2 recon

D-6 (payload-hash migrator ids over mig-{node}-{legacyId}) and D-7 (the
plan's Host.Tests project does not exist) were captured only in commit
messages and the tasks file. They belong with the other deviations, where
the next reader looks.

Claude-Session: https://claude.ai/code/session_01GASWkNEi68FSCtvr6rLoEW
This commit is contained in:
Joseph Doherty
2026-07-21 04:47:35 -04:00
parent f76d1f91e5
commit 4480a7d755
@@ -263,6 +263,30 @@ One genuine change: the drain's `ORDER BY` moves from `RowId ASC` to `enqueued_a
a hashed TEXT id carries no insertion order. Round-trip ("O") timestamps sort lexicographically in
chronological order, and `id` makes the ordering total; the index covers both.
### D-6 — The migrator keys on the payload hash, not `mig-{node}-{legacyId}`
**The plan says** deterministic ids of the form `mig-{NodeName}-{legacyId}`, mirroring ScadaBridge.
**Why that is not enough here.** Node-prefixing does solve the collision the legacy AUTOINCREMENT
key would otherwise cause — node A's `RowId 7` and node B's `RowId 7` are different alarms — but it
*preserves* a duplication that ought to be collapsed. A warm pair's two legacy files **overlap**:
`HistorianAdapterActor` default-writes while its redundancy role is unknown, so both nodes accepted
the same fanned transitions during every boot window they ever had. Prefixed ids would carry every
one of those duplicates into the merged buffer permanently, for the eventual Primary to deliver
twice.
**The decision.** Reuse D-1's `AlarmSfSchema.DeriveId` (lifted out of the sink so both call sites
share one identity rule). Distinct events cannot collide; identical ones converge. It also removes
the migrator's only need for node identity from configuration, and makes a crash between commit and
rename harmless under `INSERT OR IGNORE` — which the plan's own idempotency requirement wanted
anyway.
### D-7 — The migrator's tests live in `Host.IntegrationTests`
The plan names `tests/Server/ZB.MOM.WW.OtOpcUa.Host.Tests`. **That project does not exist.** The
tests sit beside `LocalDbSetupTests` in `Host.IntegrationTests`, which is where every other
LocalDb-facing test already lives. They are offline — a temp file and no external services.
### D-4 — The live gate needs `MaxAttempts` raised on the rig
Not actionable until Task 8, recorded now so it is not rediscovered there. The rig has no