From 883557fc8ac0aa30286fa30ac3164530d74c96c8 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Mon, 15 Jun 2026 09:35:50 -0400 Subject: [PATCH] docs: implementation plan for stillpending.md completion 28 tasks across 5 workstreams (A worker control cmds, B worker COM cmds, C audit CorrelationId, D client CLI parity, E docs). Zero proto changes; worker net48/x86 + Java on windev, rest local. --- .../2026-06-15-stillpending-completion.md | 334 ++++++++++++++++++ ...6-15-stillpending-completion.md.tasks.json | 34 ++ 2 files changed, 368 insertions(+) create mode 100644 docs/plans/2026-06-15-stillpending-completion.md create mode 100644 docs/plans/2026-06-15-stillpending-completion.md.tasks.json diff --git a/docs/plans/2026-06-15-stillpending-completion.md b/docs/plans/2026-06-15-stillpending-completion.md new file mode 100644 index 0000000..e2abc26 --- /dev/null +++ b/docs/plans/2026-06-15-stillpending-completion.md @@ -0,0 +1,334 @@ +# Still-Pending Completion Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers-extended-cc:executing-plans (or subagent-driven-development) to implement this plan task-by-task. + +**Goal:** Close the actionable items in `stillpending.md` — 11 unimplemented worker command kinds (§1.1), audit CorrelationId threading (§1.2), client CLI/helper parity (§4), and doc hygiene (§7). + +**Architecture:** Two-process gateway/worker design is unchanged. All 11 worker commands already have proto request+reply messages, gateway validation, scope mapping, and generic pass-through routing — so the work is **worker executor arms + 6 new COM-wrapper methods + a gateway constraint-path CorrelationId thread + client CLI additions**. **Zero `.proto` changes**, therefore no codegen and no net48 regen risk. + +**Tech Stack:** .NET 10 (gateway, x64), .NET Framework 4.8 (worker, x86, MXAccess COM on STA), Go/Python/Rust/Java/.NET clients. Worker net48/x86 + Java client build/test on Windows host `windev` (10.100.0.48, passwordless ssh, PowerShell); everything else builds locally on macOS. + +**Design source:** `docs/plans/2026-06-15-stillpending-completion-design.md`. + +**Branch:** `feat/stillpending-completion` (already created). + +--- + +## Cross-platform build reference (read before any worker/Java task) + +- **Worker (net48/x86) + Worker.Tests + Java client** do NOT build on macOS. Build/test them on `windev`: + - Copy the working tree (or use the existing build worktree pattern) to `windev`, `git fetch && git reset --hard origin/` in the build worktree (NEVER trust a stale local `main` — see memory `project_deploy_mechanics`). + - Build: `dotnet build src/ZB.MOM.WW.MxGateway.Worker/MxGateway.Worker.csproj -p:Platform=x86` + - Test: `dotnet test src/ZB.MOM.WW.MxGateway.Worker.Tests/MxGateway.Worker.Tests.csproj -p:Platform=x86` + - Live MXAccess: set `$env:MXGATEWAY_RUN_LIVE_MXACCESS_TESTS = "1"` then run the IntegrationTests filter. + - Nested ssh→PowerShell mangles quotes; scp a `.ps1` and run `powershell -NoProfile -ExecutionPolicy Bypass -File`. Wrap git in `cmd /c "git ... 2>&1"`. +- **net48 worker C#:** no init-only props / positional records (no `IsExternalInit`); use `{ get; set; }` or ctors (memory `project_net48_worker_csharp`). +- **Gateway, .NET client, Go, Rust, Python** build+test locally on macOS. + +--- + +## Workstream A — Worker control/lifecycle commands (5) + +These add arms to `MxAccessCommandExecutor.Execute` (`src/ZB.MOM.WW.MxGateway.Worker/MxAccess/MxAccessCommandExecutor.cs:90-129`). They need runtime state the executor does not currently hold. **Task A0 establishes how the executor reaches that state; do it first.** + +### Task A0: Decide & wire control-command collaborators into the executor + +**Classification:** standard +**Estimated implement time:** ~5 min +**Parallelizable with:** none (A1–A5 depend on it) + +**Files:** +- Modify: `src/ZB.MOM.WW.MxGateway.Worker/MxAccess/MxAccessCommandExecutor.cs` (constructor + fields) +- Read first: `src/ZB.MOM.WW.MxGateway.Worker/MxAccess/MxAccessEventQueue.cs` (`Drain(uint)`:168, `Count`:58), `WorkerRuntimeHeartbeatSnapshot.cs`, `src/ZB.MOM.WW.MxGateway.Worker/Sta/StaRuntime.cs` (`IsRunning`:80, `Shutdown()`), `MxAccessInteropInfo.cs` (progid/clsid), the executor's existing construction site (grep `new MxAccessCommandExecutor(`) + +**What to do:** The 5 control commands need: the event queue (DrainEvents), a session-state source (GetSessionState), worker identity — pid/version/progid/clsid (GetWorkerInfo), and a shutdown signal (ShutdownWorker). Determine the cleanest seam: +- **Preferred:** inject the collaborators the executor lacks (event queue reference, a `Func` or the session object, `MxAccessInteropInfo`, and a shutdown delegate/`Action`) via the constructor, matching how its existing COM collaborator is passed. +- If the executor's construction site shows control commands are better intercepted one layer up (where `StaRuntime`/session context already lives), surface that to the controller before proceeding — do NOT silently relocate the dispatch. + +**Acceptance:** executor compiles on windev with new collaborators available to A1–A5; no behavior change yet (arms still fall through). Commit. + +> Note: A1–A5 are sequential edits to the same `Execute` switch + helper region of one file, so they are NOT parallelizable with each other. Bundle their review. + +### Task A1: Ping + +**Classification:** small +**Estimated implement time:** ~3 min +**Parallelizable with:** none (same file as A0/A2-A5) + +**Files:** +- Modify: `src/ZB.MOM.WW.MxGateway.Worker/MxAccess/MxAccessCommandExecutor.cs` (add `MxCommandKind.Ping` arm + `ExecutePing`) +- Test: `src/ZB.MOM.WW.MxGateway.Worker.Tests/MxAccess/MxAccessCommandExecutorTests.cs` (or the existing executor test file — grep to confirm name) + +**Step 1 — failing test:** assert `Execute` with a `Ping` command (`PingCommand { Message = "hi" }`) returns `ProtocolStatusCode.Ok`, `Hresult == 0`, and echoes the message (via reply diagnostic or base reply — `Ping` has no dedicated reply message, so assert OK status). Build/test on windev. + +**Step 2 — run, expect FAIL** (currently INVALID_REQUEST). + +**Step 3 — implement:** add `MxCommandKind.Ping => ExecutePing(command),` to the switch (`:99-126` region). `ExecutePing` returns `CreateOkReply(command)` (helper at `:784`). + +**Step 4 — run, expect PASS** on windev. + +**Step 5 — commit:** `feat(worker): implement Ping command` + +### Task A2: DrainEvents + +**Classification:** small +**Estimated implement time:** ~4 min +**Parallelizable with:** none + +**Files:** +- Modify: `MxAccessCommandExecutor.cs` (`DrainEvents` arm + `ExecuteDrainEvents`) +- Test: executor test file + +**Steps (TDD):** test that `DrainEvents { MaxEvents = N }` drains up to N from the injected `MxAccessEventQueue` and returns `DrainEventsReply { events = [...] }` (reply field 102). `MaxEvents == 0` drains all. Map each `WorkerEvent` → `MxEvent` using the existing event-mapping path (grep how the live event loop converts `WorkerEvent`→`MxEvent`; reuse, do not duplicate). Build/test windev. Commit `feat(worker): implement DrainEvents command`. + +### Task A3: GetSessionState + +**Classification:** small +**Estimated implement time:** ~3 min +**Parallelizable with:** none + +**Files:** `MxAccessCommandExecutor.cs` + executor test. + +**Steps:** test that `GetSessionState` returns `SessionStateReply { State = }` (reply field 100) mapping the worker's lifecycle to the proto `SessionState` enum (READY when the STA is running). Build/test windev. Commit `feat(worker): implement GetSessionState command`. + +### Task A4: GetWorkerInfo + +**Classification:** small +**Estimated implement time:** ~3 min +**Parallelizable with:** none + +**Files:** `MxAccessCommandExecutor.cs` + executor test. + +**Steps:** test that `GetWorkerInfo` returns `WorkerInfoReply { WorkerProcessId, WorkerVersion, MxaccessProgid, MxaccessClsid }` (reply field 101) sourced from `Process.GetCurrentProcess().Id`, the worker assembly version, and `MxAccessInteropInfo` (progid `LMXProxy.LMXProxyServer.1`, clsid `{C30B52F5-2CB5-4760-AF0A-3A344A7EB5DC}`). Build/test windev. Commit `feat(worker): implement GetWorkerInfo command`. + +### Task A5: ShutdownWorker + +**Classification:** standard +**Estimated implement time:** ~5 min +**Parallelizable with:** none + +**Files:** `MxAccessCommandExecutor.cs` + executor test. + +**Steps:** test that `ShutdownWorker { GracePeriod }` returns a base OK reply and triggers the injected shutdown signal **after** the reply is produced (must not deadlock the STA — signal shutdown, return reply, let the pump drain). Verify the grace period is honored (or documented as best-effort). Build/test windev. Commit `feat(worker): implement ShutdownWorker command`. + +### Task A6: Make FakeWorkerHarness respond to control commands + +**Classification:** standard +**Estimated implement time:** ~5 min +**Parallelizable with:** none (depends on A1–A5 reply shapes) + +**Files:** +- Modify: `src/ZB.MOM.WW.MxGateway.Tests/Gateway/Workers/Fakes/FakeWorkerHarness.cs` +- Test: a gateway-side test that invokes `Ping`/`GetWorkerInfo`/`DrainEvents` through the harness and asserts the reply (builds locally on macOS). + +**Why:** the audit (§1.1) flagged that control kinds were "exercised only through `FakeWorkerHarness`" but the harness is a passive relay that does not auto-respond — so gateway tests could not actually cover them. Add canned responses so the gateway↔worker round-trip for these commands is verified in the default (no-MXAccess) suite. Commit `test(gateway): fake worker responds to control commands`. + +--- + +## Workstream B — Worker MXAccess COM commands (6) + +`Suspend`, `Activate`, `AuthenticateUser`, `ArchestrAUserToId`, `AddBufferedItem`, `SetBufferedUpdateInterval`. **Task B0 (windev interop inspection) MUST run first** — the native interface exposing each method is unknown until inspected. + +### Task B0: Resolve native COM signatures on windev + +**Classification:** standard +**Estimated implement time:** ~5 min (investigation) +**Parallelizable with:** A-workstream tasks (different files/host activity) + +**Files:** +- Read on windev: the generated interop for `ArchestrA.MXAccess.dll` (the `ILMXProxyServer` / `ILMXProxyServer3` / `ILMXProxyServer4` RCW definitions), `C:\Users\dohertj2\Desktop\mxaccess\docs\MXAccess-Public-API.md` (method list/signatures). +- Output: a short note appended to this plan (or a comment block) recording, for each of the 6 methods, which interface version exposes it and its exact signature. + +**What to do:** Confirm the exact native signatures for `Suspend(int serverHandle, int itemHandle)`, `Activate(int serverHandle, int itemHandle)`, `AuthenticateUser(int serverHandle, string verifyUser, string verifyUserPassword)` → user id, `ArchestrAUserToId(int serverHandle, string userIdGuid)` → user id, `AddBufferedItem(int serverHandle, string itemDefinition, string itemContext)` → item handle, `SetBufferedUpdateInterval(int serverHandle, int intervalMs)`. If any method is **not** present on the installed interop (mirroring the §3.4/§3.5 vendor-stub pattern for alarms), STOP and surface it — implement only the available ones and record the rest as vendor-gated residuals. Commit the note. + +### Task B1: Add 6 wrapper methods to IMxAccessServer + MxAccessComServer + +**Classification:** high-risk +**Estimated implement time:** ~5 min +**Parallelizable with:** none (blocked by B0) + +**Files:** +- Modify: `src/ZB.MOM.WW.MxGateway.Worker/MxAccess/IMxAccessServer.cs` (add 6 method declarations) +- Modify: `src/ZB.MOM.WW.MxGateway.Worker/MxAccess/MxAccessComServer.cs` (dispatch to the interface version resolved in B0, mirroring existing methods like `Write2`:173, `AddItem2`:84) +- Modify: any fake/test `IMxAccessServer` implementation (grep `: IMxAccessServer`) to add the 6 methods (return canned values). +- Test: `src/ZB.MOM.WW.MxGateway.Worker.Tests/MxAccess/...` for `MxAccessComServer` if one exists. + +**Steps (TDD):** add the 6 declarations; implement dispatch following the existing version-selection pattern; update fakes so the solution compiles. Build on windev `-p:Platform=x86`. Commit `feat(worker): add MXAccess COM wrappers for suspend/activate/auth/buffered`. + +> B2–B7 are sequential edits to the same `Execute` switch; not parallelizable with each other. Bundle review. + +### Task B2: Suspend arm + +**Classification:** small · **~3 min** · **Parallelizable with:** none +**Files:** `MxAccessCommandExecutor.cs` + executor test. +TDD: `Suspend { ServerHandle, ItemHandle }` calls the wrapper and returns `SuspendReply { Status = MxStatusProxy }` (reply field 24). Use a fake `IMxAccessServer` asserting the call. Build/test windev. Commit `feat(worker): implement Suspend command`. + +### Task B3: Activate arm + +**Classification:** small · **~3 min** · **Parallelizable with:** none +**Files:** `MxAccessCommandExecutor.cs` + executor test. +TDD: `Activate { ServerHandle, ItemHandle }` → `ActivateReply { Status }` (field 25). Build/test windev. Commit `feat(worker): implement Activate command`. + +### Task B4: AuthenticateUser arm + +**Classification:** standard · **~4 min** · **Parallelizable with:** none +**Files:** `MxAccessCommandExecutor.cs` + executor test. +TDD: `AuthenticateUser { ServerHandle, VerifyUser, VerifyUserPassword }` → `AuthenticateUserReply { UserId }` (field 26). **Credentials must never be logged** (standing rule) — assert no log statement includes the password. AuthenticateUser is allowed to fail (surface the native HResult, do not throw). Build/test windev. Commit `feat(worker): implement AuthenticateUser command`. + +### Task B5: ArchestrAUserToId arm + +**Classification:** small · **~3 min** · **Parallelizable with:** none +**Files:** `MxAccessCommandExecutor.cs` + executor test. +TDD: `ArchestrAUserToId { ServerHandle, UserIdGuid }` → `ArchestrAUserToIdReply { UserId }` (field 27). Build/test windev. Commit `feat(worker): implement ArchestrAUserToId command`. + +### Task B6: AddBufferedItem arm + +**Classification:** standard · **~4 min** · **Parallelizable with:** none +**Files:** `MxAccessCommandExecutor.cs` + executor test. +TDD: `AddBufferedItem { ServerHandle, ItemDefinition, ItemContext }` → `AddBufferedItemReply { ItemHandle }` (field 23). Build/test windev. Commit `feat(worker): implement AddBufferedItem command`. + +### Task B7: SetBufferedUpdateInterval arm + +**Classification:** small · **~3 min** · **Parallelizable with:** none +**Files:** `MxAccessCommandExecutor.cs` + executor test. +TDD: `SetBufferedUpdateInterval { ServerHandle, UpdateIntervalMilliseconds }` → base OK reply (no dedicated reply message). Build/test windev. Commit `feat(worker): implement SetBufferedUpdateInterval command`. + +### Task B8: Live COM smoke + buffered capture on windev + +**Classification:** high-risk +**Estimated implement time:** ~5 min (authoring; live run is manual) +**Parallelizable with:** none (blocked by B1–B7) + +**Files:** +- Modify: `src/ZB.MOM.WW.MxGateway.IntegrationTests/WorkerLiveMxAccessSmokeTests.cs` (the existing AuthenticateUser send at ~line 919/931 should now get an OK/typed reply instead of INVALID_REQUEST; add Suspend/Activate/AddBufferedItem+SetBufferedUpdateInterval sends). +- Possibly: `src/ZB.MOM.WW.MxGateway.Worker.Tests/Probes/` for a buffered-capture probe. + +**Steps:** Under `MXGATEWAY_RUN_LIVE_MXACCESS_TESTS=1` on windev: verify the 4 unambiguous COM commands round-trip; then `AddBufferedItem` + `SetBufferedUpdateInterval` on a real tag and **capture a multi-sample `OnBufferedDataChange` batch** to validate the §3.2 `VariantConverter` path. If the buffered conversion proves correct, record it; if it surfaces a conversion bug, STOP and report (do not silently ship). If a live buffered sample cannot be elicited on the rig, record buffered round-trip as the documented residual (close the command gap, leave §3.2 open). Commit `test(integration): live COM command + buffered capture smoke`. + +--- + +## Workstream C — §1.2 gateway audit CorrelationId + +### Task C1: Thread ClientCorrelationId into constraint-denial audit records + +**Classification:** high-risk +**Estimated implement time:** ~5 min +**Parallelizable with:** all A/B/D tasks (gateway-only files, builds locally) + +**Files:** +- Modify: `src/ZB.MOM.WW.MxGateway.Server/Security/Authorization/IConstraintEnforcer.cs` (add `string? correlationId` param to `RecordDenialAsync`, signature at `:49-54`) +- Modify: `src/ZB.MOM.WW.MxGateway.Server/Security/Authorization/ConstraintEnforcer.cs` (`:124-158`): accept the param, `Guid.TryParse` it into the `Guid? CorrelationId` audit field (was hardcoded `null` at `:147`); remove `TODO(Task 2.3)` at `:134-136`. +- Modify: `src/ZB.MOM.WW.MxGateway.Server/Grpc/MxAccessGatewayService.cs`: thread `request.ClientCorrelationId` from `Invoke` (`:96`) → `ApplyConstraintsAsync` (`:279`) → the 6 filter helpers (`EnforceReadTagAsync`:427, `EnforceWriteHandleAsync`:448, `FilterTagBulkAsync`:474, `FilterReadBulkAsync`:529, `FilterWriteBulkAsync`:584, `FilterHandleBulkAsync`:656) → `RecordDenialAsync`. +- Test: `src/ZB.MOM.WW.MxGateway.Tests/...` constraint-enforcer / gateway-service test. + +**Step 1 — failing test:** a denied operation with `ClientCorrelationId = ""` persists an audit record whose `CorrelationId` equals that GUID; a non-GUID correlation id persists `null` (documented behavior). Run locally: `dotnet test src/ZB.MOM.WW.MxGateway.Tests/MxGateway.Tests.csproj --filter `. + +**Step 2 — FAIL** (currently always null). + +**Step 3 — implement** the threading + `Guid.TryParse`. + +**Step 4 — PASS** locally + full gateway suite green. + +**Step 5 — commit:** `feat(gateway): thread ClientCorrelationId into constraint-denial audit (§1.2)` + +--- + +## Workstream D — Client CLI/helper parity (5 clients) + +All D tasks touch disjoint client trees and are parallelizable across languages. Each builds/tests on its own toolchain (Java on windev; the rest local). + +### Task D1: Go single-shot Write2 helper + +**Classification:** small · **~3 min** · **Parallelizable with:** D2–D9 +**Files:** +- Modify: `clients/go/mxgateway/session.go` (add `Write2`/`Write2Raw` after `Write`:559, modeled on `Write` + the `Write2Bulk`:427 payload shape) +- Test: `clients/go/mxgateway/session_test.go` (or nearest) +TDD: `Write2(ctx, serverHandle, itemHandle, value, timestampValue *MxValue, userID int32) error` issues `MX_COMMAND_KIND_WRITE2` with `Write2Command{ServerHandle,ItemHandle,Value,TimestampValue,UserId}`. Verify: `gofmt`, `go build ./...`, `go test ./...` from `clients/go`. Commit `feat(go): add single-shot Write2 session helper (§4.1)`. + +### Task D2: Python galaxy-* CLI commands (4) + +**Classification:** standard · **~5 min** · **Parallelizable with:** D1,D3–D9 +**Files:** +- Modify: `clients/python/src/zb_mom_ww_mxgateway_cli/commands.py` (add `galaxy-test-connection`, `galaxy-last-deploy`, `galaxy-discover`, `galaxy-watch` Click commands wrapping `galaxy.py` `test_connection`/`get_last_deploy_time`/`discover_hierarchy`/`watch_deploy_events`; mirror the existing `ping` command structure at `:221`) +- Modify: `clients/python/README.md:217` (correct the understated galaxy CLI claim) +- Test: `clients/python/tests/` CLI test +TDD then `python -m pytest` from `clients/python`. Commit `feat(python): add galaxy-* CLI commands (§4.2)`. + +### Task D3: ping CLI in Go + +**Classification:** small · **~3 min** · **Parallelizable with:** others +**Files:** `clients/go/cmd/mxgw-go/main.go` (add `ping` case to the switch ~`:77-130`/`:1199`, modeled on an existing simple command) + test. +TDD; `gofmt`, `go build ./...`, `go test ./...`. Commit `feat(go): add ping CLI subcommand (§4.3)`. + +### Task D4: ping CLI in Java + +**Classification:** small · **~3 min** · **Parallelizable with:** others — **build on windev** +**Files:** `clients/java/zb-mom-ww-mxgateway-cli/src/main/java/com/zb/mom/ww/mxgateway/cli/MxGatewayCli.java` (register a `ping` subcommand ~`:126-149`) + test. +TDD; `gradle test` on windev. Commit `feat(java): add ping CLI subcommand (§4.3)`. + +### Task D5: browse CLI — Go + +**Classification:** standard · **~4 min** · **Parallelizable with:** others +**Files:** `clients/go/cmd/mxgw-go/main.go` (new `browse` command wrapping `GalaxyClient.Browse`:398 / `LazyBrowseNode.Expand`:337) + test. `go build/test`. Commit `feat(go): add browse CLI (§4.6)`. + +### Task D6: browse CLI — Python + +**Classification:** standard · **~4 min** · **Parallelizable with:** others +**Files:** `clients/python/src/zb_mom_ww_mxgateway_cli/commands.py` (new `browse` command wrapping `galaxy.py` `browse`:163) + test. `pytest`. Commit `feat(python): add browse CLI (§4.6)`. + +### Task D7: browse CLI — Rust + +**Classification:** standard · **~4 min** · **Parallelizable with:** others +**Files:** `clients/rust/crates/mxgw-cli/src/main.rs` (new `Browse` command variant wrapping the galaxy browse helper in `galaxy.rs`) + test. `cargo fmt`, `cargo test --workspace`, `cargo clippy --all-targets -- -D warnings`. Commit `feat(rust): add browse CLI (§4.6)`. + +### Task D8: browse CLI — Java + dotnet + +**Classification:** standard · **~5 min** · **Parallelizable with:** others — **Java builds on windev** +**Files:** `clients/java/.../MxGatewayCli.java` (browse subcommand wrapping `GalaxyRepositoryClient.browse`) + `clients/dotnet/ZB.MOM.WW.MxGateway.Client.Cli/MxGatewayClientCli.cs` (`browse` command wrapping `LazyBrowseNode.ExpandAsync`:63) + tests. `gradle test` (windev), `dotnet test` (local). Commit `feat(dotnet,java): add browse CLI (§4.6) — 5/5 parity`. + +### Task D9: Java galaxy-name aliases + verify dotnet version + +**Classification:** small · **~4 min** · **Parallelizable with:** others — **Java builds on windev** +**Files:** +- Modify: `clients/java/.../MxGatewayCli.java:145-146` — add canonical `galaxy-test-connection`/`galaxy-last-deploy` as the primary names; keep `galaxy-test`/`galaxy-deploy-time` as **deprecated aliases** (picocli `@Command(name=..., aliases={...})` or equivalent). +- Verify: `clients/dotnet/.../MxGatewayClientCli.cs` — the explorer found a `version` path at `:85` that conflicts with audit §4.4. **Read it**: if a `version` subcommand genuinely works, no change (note it in the §7 update); if it's only a `--version` flag and `IsKnownGatewayCommand` lacks `version`, add the subcommand. Do not add what already exists. +- Test: Java CLI test asserting both names resolve. +`gradle test` (windev), `dotnet build/test` (local). Commit `feat(java): galaxy command aliases; chore(dotnet): verify version subcommand (§4.4,§4.5)`. + +--- + +## Workstream E — Docs/hygiene + residual recording + +### Task E1: Doc hygiene + dead-code removal + +**Classification:** small · **~5 min** · **Parallelizable with:** all (mostly doc-only; one code deletion) +**Files:** +- `docs/plans/2026-06-14-deferred-followups.md:4` — change "Plan only — NOT yet executed" to reflect D1 done (`4af24b9`). +- `docs/AlarmClientDiscovery.md:765-774` — rewrite stale STA "production fix needed" prose (alarms now run through worker STA / `GatewayAlarmMonitor`). +- `src/ZB.MOM.WW.MxGateway.Server/Dashboard/Hubs/EventsHub.cs:9-17` — remove/update stale "publisher side is a follow-up" comment (broadcaster shipped). +- `CLAUDE.md` — fix project-name drift `src/MxGateway.*` → `src/ZB.MOM.WW.MxGateway.*` throughout. +- `src/ZB.MOM.WW.MxGateway.Server/Grpc/GalaxyRepositoryGrpcService.cs:350-360` — remove dead IDE0051-suppressed `MapSqlException`. +**Verify:** `dotnet build src/ZB.MOM.WW.MxGateway.Server` locally (the only code change is the deletion). Commit `docs+chore: fix stale prose, project names, remove dead MapSqlException (§7)`. + +### Task E2: Record §1.3 and §1.4 residuals + refresh stillpending.md + +**Classification:** trivial · **~3 min** · **Parallelizable with:** all (doc-only) +**Files:** +- `docs/plans/2026-06-14-deferred-followups.md` — record §1.3 (provider_switches counter live-exercise unproven; rig can't drive a real failover) as an explicit documented residual. +- Add a short note (in the worker alarm code's existing comment near `WnWrapAlarmConsumer.cs:261` or the design doc) that §1.4's 8-arg ack drops domain/full-name because the AVEVA `AlarmAckByName` v2 is a vendor stub (-55) — already partly noted; make it explicit and cross-referenced. +- `stillpending.md` — mark §1.1, §1.2, §4.1/§4.2/§4.3/§4.6 (and §4.4/§4.5 per outcome) as Resolved with commit refs; keep the documented residuals. +Commit `docs: record §1.3/§1.4 residuals and refresh stillpending.md (§7)`. + +--- + +## Final integration review + +After all workstreams: run the full local suite (`dotnet test` gateway + `.NET` client, `go test`, `pytest`, `cargo test`+clippy) and the windev suite (worker net48/x86 + Java + live MXAccess smoke). Then use **superpowers-extended-cc:finishing-a-development-branch**. + +## Dependency summary + +- A0 → A1..A5 → A6 +- B0 → B1 → B2..B7 → B8 +- C1 independent (gateway-only, local) +- D1..D9 independent of A/B/C and of each other (disjoint client trees) +- E1, E2 last (reflect what closed); E1 mostly independent diff --git a/docs/plans/2026-06-15-stillpending-completion.md.tasks.json b/docs/plans/2026-06-15-stillpending-completion.md.tasks.json new file mode 100644 index 0000000..5654d04 --- /dev/null +++ b/docs/plans/2026-06-15-stillpending-completion.md.tasks.json @@ -0,0 +1,34 @@ +{ + "planPath": "docs/plans/2026-06-15-stillpending-completion.md", + "tasks": [ + {"id": 80, "subject": "Task A0: Wire control-command collaborators into executor", "status": "pending"}, + {"id": 81, "subject": "Task A1: Implement Ping command", "status": "pending", "blockedBy": [80]}, + {"id": 82, "subject": "Task A2: Implement DrainEvents command", "status": "pending", "blockedBy": [80]}, + {"id": 83, "subject": "Task A3: Implement GetSessionState command", "status": "pending", "blockedBy": [80]}, + {"id": 84, "subject": "Task A4: Implement GetWorkerInfo command", "status": "pending", "blockedBy": [80]}, + {"id": 85, "subject": "Task A5: Implement ShutdownWorker command", "status": "pending", "blockedBy": [80]}, + {"id": 86, "subject": "Task A6: FakeWorkerHarness responds to control commands", "status": "pending", "blockedBy": [81, 82, 84]}, + {"id": 87, "subject": "Task B0: Resolve native COM signatures on windev", "status": "pending"}, + {"id": 88, "subject": "Task B1: Add 6 COM wrapper methods (IMxAccessServer + MxAccessComServer)", "status": "pending", "blockedBy": [87]}, + {"id": 89, "subject": "Task B2: Implement Suspend arm", "status": "pending", "blockedBy": [88]}, + {"id": 90, "subject": "Task B3: Implement Activate arm", "status": "pending", "blockedBy": [88]}, + {"id": 91, "subject": "Task B4: Implement AuthenticateUser arm", "status": "pending", "blockedBy": [88]}, + {"id": 92, "subject": "Task B5: Implement ArchestrAUserToId arm", "status": "pending", "blockedBy": [88]}, + {"id": 93, "subject": "Task B6: Implement AddBufferedItem arm", "status": "pending", "blockedBy": [88]}, + {"id": 94, "subject": "Task B7: Implement SetBufferedUpdateInterval arm", "status": "pending", "blockedBy": [88]}, + {"id": 95, "subject": "Task B8: Live COM smoke + buffered capture on windev", "status": "pending", "blockedBy": [89, 90, 91, 92, 93, 94]}, + {"id": 96, "subject": "Task C1: Thread ClientCorrelationId into denial audit (§1.2)", "status": "pending"}, + {"id": 97, "subject": "Task D1: Go single-shot Write2 helper (§4.1)", "status": "pending"}, + {"id": 98, "subject": "Task D2: Python galaxy-* CLI commands (§4.2)", "status": "pending"}, + {"id": 99, "subject": "Task D3: ping CLI in Go (§4.3)", "status": "pending"}, + {"id": 100, "subject": "Task D4: ping CLI in Java (§4.3)", "status": "pending"}, + {"id": 101, "subject": "Task D5: browse CLI — Go (§4.6)", "status": "pending"}, + {"id": 102, "subject": "Task D6: browse CLI — Python (§4.6)", "status": "pending"}, + {"id": 103, "subject": "Task D7: browse CLI — Rust (§4.6)", "status": "pending"}, + {"id": 104, "subject": "Task D8: browse CLI — Java + dotnet (§4.6)", "status": "pending"}, + {"id": 105, "subject": "Task D9: Java galaxy aliases + verify dotnet version (§4.4,§4.5)", "status": "pending"}, + {"id": 106, "subject": "Task E1: Doc hygiene + dead-code removal (§7)", "status": "pending"}, + {"id": 107, "subject": "Task E2: Record §1.3/§1.4 residuals + refresh stillpending.md (§7)", "status": "pending", "blockedBy": [81, 82, 83, 84, 85, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 105]} + ], + "lastUpdated": "2026-06-15" +}