From 027c4235024539c39d3ae368f57ece6849f48e13 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Thu, 20 Aug 2026 10:33:07 -0400 Subject: [PATCH] =?UTF-8?q?docs(plans):=20R3-04=20execution=20notes=20?= =?UTF-8?q?=E2=80=94=20T6-T12=20deviations=20recorded,=20T13=20marked=20pe?= =?UTF-8?q?nding=20(live=20gate=20deferred=20to=20orchestrator)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plans/R3-04-one-role-authority-plan.md | 50 +++++++++++++++++++ ...3-04-one-role-authority-plan.md.tasks.json | 3 +- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/archreview/plans/R3-04-one-role-authority-plan.md b/archreview/plans/R3-04-one-role-authority-plan.md index b809adcf..0b33665d 100644 --- a/archreview/plans/R3-04-one-role-authority-plan.md +++ b/archreview/plans/R3-04-one-role-authority-plan.md @@ -502,3 +502,53 @@ gossips 'Driver' and a Primary IS elected" — is **not achievable**. What shipp this test is actually about, without needing a second live node. No other T1–T5 deviations from the plan. + +**T6-T9 — no deviations.** Implemented as designed; `AkkaClusterOptionsValidator` gained an optional +(default-null) `EffectiveRoles?` constructor parameter rather than a required one specifically so the +pre-existing zero-arg test constructions in `AkkaClusterOptionsValidatorTests` did not all need +touching — the guard is simply inert when nothing is injected, which is also the correct behaviour +for any harness that builds this validator without the rest of the role authority. + +**T8 — two additional bare-role-literal offenders found and fixed, beyond the two the plan named.** +The census's row-by-row list did not claim to be exhaustive of every bare literal in the tree, only +of the *production predicate* sites; running the guard for real (rather than reasoning about it) +found two more before it could go green: + +- `DriverInstanceActor.ShouldStub`'s `roles.Contains("dev")` — a genuine Akka-cluster-role read + (`_localRoles`, threaded from `IClusterRoleInfo.LocalRoles`) gating dev-stub mode for + Windows-only drivers. Fixed to `RoleParser.GossipedRolesHave(roles, RoleParser.Dev)`. +- `ControlPlane/ServiceCollectionExtensions.AdminRole = "admin"` — a second constant duplicating the + literal `RoleParser.Admin` names, feeding Akka's own `ClusterSingletonOptions.Role` matching (the + same "not ours to change" ordinal match as `SelectOldestUpMemberOfRole`). The VALUE was already + correct (Akka's own matching is unaffected either way); fixed to alias `RoleParser.Admin` rather + than duplicate it, matching the sibling `Runtime/ServiceCollectionExtensions.DriverRole` pattern. + +The guard also required a small allow-list (six files) for bare `"admin"`/`"driver"`/`"dev"` literals +that name something OTHER than an Akka `Cluster:Roles` role — a raw-tree node-KIND discriminator, an +ACL-scope entity-type name, the Sql driver's own TagConfig JSON marker (×3 files), and an LDAP-derived +AdminUI RBAC role. Each carries its reason in `RoleAuthorityGuardTests.RoleLiteralAllowListWithReasons`, +per the plan's "add to the allow-list WITH A REASON" instruction; a companion test +(`Every_allow_list_entry_has_a_reason_and_still_applies`) fails if an entry goes stale. + +The falsification control (`The_scan_actually_detects_the_pre_R3_04_offenders`) could not literally +re-run the guard against the pre-T3/pre-T5 GIT COMMITS (T1–T8 landed sequentially in this same +worktree, so "the tree" is always post-fix by the time T8's test runs) — it instead feeds the scan +logic the exact pre-fix `Program.cs`/`Fleet.razor` snippets as string literals, captured verbatim +from this session's own earlier reads of those files before they were edited. Functionally +equivalent proof-of-falsifiability; recorded as a deviation because it is a different MECHANISM than +"run on the pre-T3 tree," not because the result differs. + +**T9 — scope note, not a deviation.** "The driver stack" is proven via two representative slices +(`ILocalDb` resolution + the `IOpcUaUserAuthenticator` selection block), not the ENTIRE +`WithOtOpcUaRuntimeActors` Akka actor graph — replicating that too would need a real `ActorSystem` +(the exact thing `DriverOnlyNoConfigDbBootTests`'s own doc comment explains this test family avoids). +The negative control uses an inline `PreFixDerivation` helper (reading `OTOPCUA_ROLES` only, matching +pre-T3 `Program.cs:61-63` verbatim) rather than a `git stash`, for the same "already sequential +commits in one worktree" reason as T8's falsification control — and it is run in the SAME test +process against the SAME configuration, which is a stronger control than a separate stash-and-revert +cycle would have been (both derivations are proven against literally identical input). + +**T11/T12 — combined into one commit.** The docker-compose.yml header comment documenting all six +nodes' role sources interleaves site-a-2 and site-b-2 on adjacent lines, so a clean git-level split +into the plan's two separate commits was not practical; both tasks' edits landed in one commit +(`985de0b6`). The rig was NOT brought up as part of either task, per the brief. diff --git a/archreview/plans/R3-04-one-role-authority-plan.md.tasks.json b/archreview/plans/R3-04-one-role-authority-plan.md.tasks.json index a29b3919..d901dc01 100644 --- a/archreview/plans/R3-04-one-role-authority-plan.md.tasks.json +++ b/archreview/plans/R3-04-one-role-authority-plan.md.tasks.json @@ -106,7 +106,8 @@ "T9", "T11", "T12" - ] + ], + "note": "Skipped by the executing agent per orchestrator instruction \u2014 the live gate runs separately, on the docker-dev rig, by the orchestrator/operator. T1-T12 are implemented, committed, and unit/integration-tested; T13 requires bringing the rig up (docker compose), which this task explicitly excluded." } ] }