From fd941c249e5802f77bb82e54a75f13d9647525b2 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Tue, 18 Aug 2026 06:36:47 -0400 Subject: [PATCH] =?UTF-8?q?docs(plan):=20followups-and-tickets=20=E2=80=94?= =?UTF-8?q?=2010=20tasks=20closing=20every=20recorded=20follow-up?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plans/2026-08-18-followups-and-tickets.md | 461 ++++++++++++++++++ ...-08-18-followups-and-tickets.md.tasks.json | 16 + 2 files changed, 477 insertions(+) create mode 100644 docs/plans/2026-08-18-followups-and-tickets.md create mode 100644 docs/plans/2026-08-18-followups-and-tickets.md.tasks.json diff --git a/docs/plans/2026-08-18-followups-and-tickets.md b/docs/plans/2026-08-18-followups-and-tickets.md new file mode 100644 index 0000000..76a8e8d --- /dev/null +++ b/docs/plans/2026-08-18-followups-and-tickets.md @@ -0,0 +1,461 @@ +# Follow-ups and Tickets Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers-extended-cc:subagent-driven-development +> to execute this plan task-by-task in this session. + +**Goal:** Close every follow-up recorded in `docs/plans/2026-08-17-followup-closeout.md` +(as-built notes, "Follow-ups recorded, not started") plus the two ticket-worthy windev +findings — leaving no recorded open item anywhere. + +**Architecture:** No new components. Ten independent closures: two toolchain/script fixes +(Check 4 Windows pin, Gradle 9 `checkGeneratedClean`), two dashboard display gaps +(Settings recent-limit rows, push-driven Alarms truncation banner), two documentation +audits (Server-0xx resolution regression sweep, `Authentication.md` runnable-examples +pass), one worker-test investigation (the deterministic `WorkerPipeSessionTests` failure +on windev), one bounded rig probe (ack-leg unblock paths), a windev verification pass +(including the `protoc-gen-go-grpc` 1.6.2 pin install), and bookkeeping. + +**Tech Stack:** PowerShell (codegen scripts), Gradle/Groovy (Java client), Blazor +server-side Razor + xUnit/bUnit-style render tests (dashboard), .NET Framework 4.8 x86 +xUnit (worker tests, windev-only), wnwrap probe harness (windev rig), Markdown. + +**Branch:** `feat/followups-tickets` off `main` (`45058d5`). + +--- + +## Ground rules for every implementer subagent + +- **Git discipline (Mac tree):** NEVER `git stash`, `git reset`, `git clean`, or + `git checkout `. Commit with **pathspecs on the commit**: + `git commit -m "..." -- `. If `index.lock` blocks you, wait 5 s and retry. +- **Build/test lock:** before any `dotnet build`/`dotnet test`/`cargo`/`gradle`/`go test` + on the Mac, acquire the lock: + `mkdir /private/tmp/claude-501/-Users-dohertj2-Desktop-MxAccessGateway/f36938ae-bbca-4245-b5c9-fac512d69e22/scratchpad/buildlock` + (retry with backoff until it succeeds); `rmdir` it on ALL exit paths, including failure. +- **Quality gates:** `TreatWarningsAsErrors=true`, `Nullable=enable`. Follow + `docs/style-guides/CSharpStyleGuide.md` (file-scoped namespaces, `sealed` by default, + `Async` suffix). Update affected docs in the same commit as source. +- **MXAccess parity:** never synthesize events; the dashboard/gateway forwards only what + the worker/monitor emits. The `snapshot_status` frame is a gateway-status frame (like + `provider_status`), NOT a synthesized MXAccess event. +- **Never log or echo secrets, API keys, credentials, or tag values.** +- **Scope contract:** the task's `Files:` block is the `files_to_edit` contract. If the + task needs other files, that is a plan defect — surface it in your report, don't + silently expand scope. (Exception: Tasks 7 and 8 are investigations; their Files list + is starting points, and they must report every file they end up touching.) +- **Windev access (Tasks 7, 8, 9 only):** `ssh windev` lands in PowerShell. The CI clone + is `C:\build\mxaccessgw-ci`. Quirks: the first `slnx` build after a pull often fails on + stale Contracts obj artifacts (CS2001/CS0016) — clear the Contracts `obj`/`bin` and + rebuild, it is not a regression; the gateway suite is load-sensitive — rerun a filtered + subset before believing a flake. To get branch code there: + `git -C C:\build\mxaccessgw-ci fetch origin && git -C C:\build\mxaccessgw-ci checkout feat/followups-tickets && git -C C:\build\mxaccessgw-ci pull` — + which requires the Mac side to have pushed the branch first (the controller pushes; + ask if the branch tip you need is not on origin). + +--- + +### Task 1: check-codegen Check 4 — tolerate the Windows `.exe` version banner + +**Classification:** small +**Estimated implement time:** ~4 min +**Parallelizable with:** Task 2, Task 3, Task 4, Task 5, Task 7 + +**Files:** +- Modify: `clients/go/generate-proto.ps1` (pin compare at `:52-67`, pin constants at `:10-11`) +- Modify: any doc that states Check 4 is unrunnable on Windows (grep `docs/` and + `code-reviews/` for "Check 4"; `docs/GatewayTesting.md` is the likely holder) + +**Problem.** On Windows the plugins report their invoked name with an `.exe` suffix +(`protoc-gen-go.exe v1.36.11`), so the exact-string compare against +`'protoc-gen-go v1.36.11'` throws and Check 4 (which shells this script) is unrunnable on +any Windows host — including windev, the box where regeneration actually happens. + +**Step 1: Normalize the banner before comparing.** Add a small helper and use it for both +plugin compares (protoc stays warn-only and gets the same normalization for a fair warn): + +```powershell +function Get-NormalizedToolVersion { + # On Windows a plugin reports its argv[0] name, so the banner carries an `.exe` + # suffix ("protoc-gen-go.exe v1.36.11"). Strip it so the pin compare is + # host-independent; the version part must still match exactly. + param([string]$RawBanner) + return ($RawBanner -replace '\.exe(?=\s)', '') +} +``` + +Apply to `$protocGenGoVersion`, `$protocGenGoGrpcVersion`, `$protocVersion` at the point +each is read (`:54`, `:59`, `:64`), keeping the pinned constants unchanged. Update the +comment block at `:4-9` to note the normalization. + +**Step 2: Verify on macOS.** Acquire the build lock, then run +`pwsh scripts/check-codegen.ps1` — all 4 checks must pass (banner has no `.exe` here, so +this proves no regression). Also assert the helper logic directly: +`pwsh -c "& { ; Get-NormalizedToolVersion 'protoc-gen-go.exe v1.36.11' }"` +must print `protoc-gen-go v1.36.11`, and a name-only match check for +`protoc-gen-go-grpc.exe 1.6.2` → `protoc-gen-go-grpc 1.6.2`. + +**Step 3: Fix the stale prose.** Wherever docs state Check 4 cannot run on Windows, +rewrite to: Check 4 runs on Windows; the plugin pins must be installed +(`go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.36.11`, +`go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.6.2`). +Do NOT edit `docs/plans/2026-08-17-followup-closeout.md` — Task 10 owns plan bookkeeping. + +**Step 4: Commit** with pathspecs on the touched files: +`fix(codegen): normalize .exe off plugin version banners so Check 4 runs on Windows`. + +Windows-side proof is deferred to Task 9 (windev runs check-codegen 1–4 after installing +the 1.6.2 pin). + +--- + +### Task 2: Gradle 9 — revive `checkGeneratedClean` without `Project.exec` + +**Classification:** small +**Estimated implement time:** ~4 min +**Parallelizable with:** Task 1, Task 3, Task 4, Task 5, Task 7 + +**Files:** +- Modify: `clients/java/zb-mom-ww-mxgateway-client/build.gradle` (`checkGeneratedClean`, `:71-92`) +- Modify: `docs/GatewayTesting.md` only if it describes the task's mechanism (grep + `checkGeneratedClean`) + +**Problem.** The task's `doLast` calls the script-level `exec {}` (i.e. `Project.exec`), +removed in Gradle 9 — the task is dead on any Gradle 9 host. + +**Step 1: Replace with `ProviderFactory.exec`** (available since Gradle 7.5, so it works +on both the current toolchain and Gradle 9, and is configuration-cache safe). Capture the +provider reference at configuration time, call `.get()` in `doLast` so the git status +runs at execution time: + +```groovy +tasks.register('checkGeneratedClean') { + group = 'verification' + description = 'Fails if the committed generated Java tree differs from a fresh regeneration.' + dependsOn 'generateProto' + def generatedDir = 'clients/java/src/main/generated' + def repoRoot = rootProject.projectDir.parentFile.parentFile + // Project.exec was removed in Gradle 9; ProviderFactory.exec runs the probe lazily + // at doLast time and works on Gradle 7.5+. + def gitStatus = providers.exec { + workingDir = repoRoot + commandLine 'git', 'status', '--porcelain', '--', generatedDir + ignoreExitValue = true + } + doLast { + def dirty = gitStatus.standardOutput.asText.get().trim() + if (!dirty.isEmpty()) { + throw new GradleException( + "Generated Java is stale:\n${dirty}\n" + + "Regenerate and commit the Java client after a .proto change " + + "(gradle :zb-mom-ww-mxgateway-client:generateProto).") + } + } +} +``` + +Preserve the explanatory comment block above the task (`:61-70`) — amend it, don't delete. + +**Step 2: Verify.** Acquire the build lock. From `clients/java`: +`gradle :zb-mom-ww-mxgateway-client:checkGeneratedClean` must pass (tree is clean), and +`gradle --version` must be recorded in your report. Then prove the failure path: touch a +scratch edit inside `clients/java/src/main/generated/` (append a comment line to one +generated file), rerun the task, confirm it fails with the stale message, then **revert +that file with `git checkout -- `** (this narrow file-level checkout is the +one permitted use; the file is committed generated output). + +**Step 3: Commit:** +`fix(java-client): checkGeneratedClean via ProviderFactory.exec — Project.exec is gone in Gradle 9`. + +--- + +### Task 3: SettingsPage — RecentFaultLimit / RecentSessionLimit rows + +**Classification:** small +**Estimated implement time:** ~4 min +**Parallelizable with:** Task 1, Task 2, Task 4, Task 5, Task 7 + +**Files:** +- Modify: `src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Pages/SettingsPage.razor` + (dashboard rows around `:98-102`) +- Test: `src/ZB.MOM.WW.MxGateway.Tests/` — extend the existing settings render coverage + (`SettingsPageTagVisibilityRenderTests` or its sibling settings render test class; find + with `grep -rl "SettingsPage" src/ZB.MOM.WW.MxGateway.Tests`) +- Modify: `docs/GatewayDashboardDesign.md` only if it enumerates settings rows (grep + `RecentFaultLimit` / "Snapshot interval" there first) + +**Problem.** `EffectiveDashboardConfiguration` carries `RecentFaultLimit` and +`RecentSessionLimit` (already projected by `GatewayConfigurationProvider.cs:62-63`), but +`SettingsPage` renders every member except these two. + +**Step 1: Write the failing test.** Extend the settings render test: rendered page +contains `Recent fault limit` with the configured value and `Recent session limit` with +the configured value (use non-default values in the arranged options so the assertion +proves plumbing, not defaults). + +**Step 2: Run it, expect FAIL** (`dotnet test --filter "FullyQualifiedName~SettingsPage"` +under the build lock). + +**Step 3: Add the two rows** next to the other Dashboard rows (after "Snapshot interval", +matching the existing `……` idiom): + +```razor +Recent fault limit@Snapshot.Configuration.Dashboard.RecentFaultLimit +Recent session limit@Snapshot.Configuration.Dashboard.RecentSessionLimit +``` + +**Step 4: Run the filtered test, expect PASS.** + +**Step 5: Commit:** +`feat(dashboard): settings page shows RecentFaultLimit and RecentSessionLimit`. + +--- + +### Task 4: Authentication.md — runnable-as-written examples pass + +**Classification:** small +**Estimated implement time:** ~5 min +**Parallelizable with:** Task 1, Task 2, Task 3, Task 5, Task 7 + +**Files:** +- Modify: `docs/Authentication.md` + +**Problem.** The doc's CLI/scope examples were flagged during the previous branch as not +runnable as written — notably samples that grant only invoke/event scopes with no +`session:open`, which since Server-004's validation would produce keys that cannot open a +session (or, for unknown scope strings, be rejected at create time). The canonical scope +catalog is: `session:open`, `session:close`, `invoke:read`, `invoke:write`, +`invoke:secure`, `events:read`, `metadata:read`, `admin`; the verb is `apikey create-key` +with `--key-id` required. + +**Step 1: Sweep every example** (` ```-fenced blocks and inline commands) in the doc. For +each, either (a) make it runnable as written — canonical verb, required flags, only +canonical scopes, scope sets that support what the surrounding prose says the key is for +(a key described as opening sessions needs `session:open`) — or (b) if it is deliberately +a fragment, mark it explicitly (e.g. "illustrative — not a complete command"). Prefer (a); +use (b) only where completeness would obscure the point being made. + +**Step 2: Cross-check** each corrected scope list against +`src/ZB.MOM.WW.MxGateway.Server/Security/Authentication/GatewayScopes.cs` (read-only) — +do not invent scope strings. + +**Step 3: Commit:** `docs(auth): make Authentication.md examples runnable as written`. + +--- + +### Task 5: AlarmsPage — push-driven truncation banner from the snapshot_status frame + +**Classification:** standard +**Estimated implement time:** ~5 min +**Parallelizable with:** Task 1, Task 2, Task 3, Task 4, Task 7 + +**Files:** +- Modify: `src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Pages/AlarmsPage.razor` + (in-process feed loop around `:199-230`, `_snapshotTruncated` at `:170`/`:401`) +- Test: `src/ZB.MOM.WW.MxGateway.Tests/` — the AlarmsPage/dashboard alarm test class + (find with `grep -rl "AlarmsPage" src/ZB.MOM.WW.MxGateway.Tests`); if no AlarmsPage + render/behavior test exists, add coverage at the level the existing dashboard tests use +- Modify: `docs/GatewayDashboardDesign.md` (truncation-banner description, if it says the + banner is poll-driven) + +**Problem.** The truncation banner (`_snapshotTruncated`, rendered at `:39`) updates only +from the 3-second poll (`:401`), even though the page already holds an in-process +subscription to the alarm feed (the loop at `:211-213` that feeds the provider-status +badge). The feed now carries an edge-triggered `snapshot_status` frame +(`AlarmFeedMessage.PayloadCase.SnapshotStatus`, shipped `fccf753`) — consume it so the +banner flips on the edge instead of up to 3 s late. + +**Spec:** +- In the existing in-process feed loop, add a case for + `AlarmFeedMessage.PayloadCase.SnapshotStatus`: set `_snapshotTruncated = + message.SnapshotStatus.Truncated` and re-render (same invoke/StateHasChanged pattern the + provider-status case uses). +- Keep the poll's assignment at `:401` — the poll is the reconcile baseline and both + sources derive from the same `GatewayAlarmMonitor` verdict, so they cannot disagree + except transiently. Do not remove or restructure the poll. +- Remember `StreamAsync` primes every subscriber with an unconditional `snapshot_status` + baseline frame after `provider_status` — so on attach the page gets the current verdict + push-side too. No extra priming logic needed in the page. +- Do NOT touch `GatewayAlarmMonitor` or the proto — gateway emission is done and shipped. + +**Steps:** failing test first (a `SnapshotStatus` frame delivered through the in-process +subscription flips the banner state without a poll tick; a `false` frame clears it), then +implement, then filtered dashboard/alarm tests green under the build lock, then commit: +`feat(dashboard): alarms page consumes snapshot_status feed frame for the truncation banner`. + +--- + +### Task 6: Server-0xx resolution audit — doc-only "Resolved" entries re-verified + +**Classification:** standard +**Estimated implement time:** ~5 min (audit) + fixes as found +**Parallelizable with:** none (runs after Task 4 lands — both may touch `docs/Authentication.md`) + +**Files:** +- Modify: `code-reviews/Server/findings.md` (annotations only — do not rewrite history) +- Modify: any file where a claimed correction is found absent (expected candidates: + `CLAUDE.md`, `docs/*.md`, XML doc comments named in findings — report each) + +**Problem.** Server-012 was recorded *Resolved 2026-05-18* claiming two scope-list +corrections that were absent from the tree when `feat/followup-closeout` looked — a +resolution that regressed or was never applied. Findings that read Resolved are never +re-examined, so every *documentation/comment-only* resolution needs the same spot-check. + +**Procedure:** +1. Enumerate every `Server-0xx` entry in `code-reviews/Server/findings.md` whose + Resolution describes documentation-only or comment-only changes (no test named, prose + like "Pure documentation change" — at minimum Server-011, Server-012, Server-013/014 + remarks rewrites; sweep all entries, don't assume). +2. For each, verify the specific claimed text exists in today's tree (grep the exact + phrases/identifiers the resolution names). +3. Where present: append one line to that finding's Resolution: + `Re-verified present 2026-08-18 (feat/followups-tickets).` +4. Where absent: re-apply the correction in the target file, and append: + `Regressed or never applied; re-fixed 2026-08-18 in (feat/followups-tickets).` + (Server-012 itself was already re-fixed on the previous branch — annotate it as such, + citing commits `a5f843c`/`f2a422b`, rather than re-fixing.) +5. Report a table: finding id → verified/regressed → action. + +**Commit:** `docs(reviews): re-verify doc-only Server-0xx resolutions; re-fix regressions`. + +--- + +### Task 7: WorkerPipeSessionTests deterministic failure — investigate and fix (windev) + +**Classification:** high-risk +**Estimated implement time:** investigation timeboxed ~10 min; fix ≤5 min +**Parallelizable with:** Task 1–5 (only windev user in wave 1) + +**Files (starting points — investigation task, report everything touched):** +- Test: `src/ZB.MOM.WW.MxGateway.Worker.Tests/Ipc/WorkerPipeSessionTests.cs` + (`RunAsync_LongInFlightCommandThatKeepsPumping_DoesNotFaultAndDeliversReply`) +- Suspect: `src/ZB.MOM.WW.MxGateway.Worker/` pipe-session / frame-protocol sources the + test exercises (follow the test's references) + +**Problem.** The test fails deterministically on windev, and reproduces on `main` — +pre-existing, not introduced by any recent branch. Everything else in the worker suite +passes (523/523 otherwise). + +**Procedure (all building/testing on windev over ssh; edits in the Mac tree, pushed by +the controller, pulled on the CI clone — coordinate via your report if you need a push):** +1. Repro on the CI clone at this branch: + `dotnet test src/ZB.MOM.WW.MxGateway.Worker.Tests/ZB.MOM.WW.MxGateway.Worker.Tests.csproj -p:Platform=x86 --filter "FullyQualifiedName~RunAsync_LongInFlightCommandThatKeepsPumping"`. + Capture the full failure output (assertion text, timeout, stack). +2. Read the test and the code under test. Classify: (a) test defect (bad timing + assumption, races in the harness), (b) product defect in the pipe session under a + long in-flight command, or (c) environment-specific (windev timing/load). + **Timebox: if the cause is not isolated after ~10 minutes of investigation, stop and + report your best hypothesis with evidence — do not churn.** +3. Fix minimally per the classification. A product fix in the frame/pipe layer is + high-risk territory: preserve the frame protocol (`docs/WorkerFrameProtocol.md`), the + STA pumping rules, and MXAccess parity. A test fix must keep the scenario's intent — + a long in-flight command that keeps pumping must not fault the session and must + deliver its reply; don't weaken it into a sleep-and-hope. +4. Verify: the fixed test passes 3 consecutive runs on windev; then the full worker suite + (`-p:Platform=x86`) is green. If you touched product code, also build the full `slnx` + on windev and run the gateway suite filtered to any shared-surface tests. +5. Docs in the same commit if behavior/rules changed. + +**Commit:** `fix(worker): — WorkerPipeSessionTests long-in-flight repro` (adjust +`fix(worker-tests)` if the defect is in the test). + +--- + +### Task 8: Ack-leg probe — bounded unblock attempt (windev rig) + +**Classification:** standard +**Estimated implement time:** timeboxed ~15 min of probing +**Parallelizable with:** Task 6 (runs after Task 7 — serialize windev use) + +**Files (starting points — investigation task):** +- Modify: `docs/AlarmProbeFindings.md` (append a third-attempt section, whatever the outcome) +- Reference (read-only): the probe harness locations named in that doc's earlier attempts; + the mxaccess analysis project at `C:\Users\dohertj2\Desktop\mxaccess` (windev) + +**Problem.** The acknowledge leg remains unobserved: every wnwrap ack surface is +accepted-but-inert (`rc=0`, state stays `UNACK_ALM`), and `.Acked` is write-rejected +(OperationalError 1007). Two recorded unblock paths remain +(`docs/AlarmProbeFindings.md`, "Remaining unblock paths for the acknowledge leg"). + +**Procedure — attempt path 2 first (it is inspectable), path 1 only if non-interactive:** +1. **Path 2 — ack-security configuration:** inspect whether the rig's galaxy/`alarmmgr` + is configured with an alarm-acknowledgement security requirement the wnwrap consumer + (operator *name* string, no authenticated identity) cannot meet. Look in galaxy + configuration (the `ZB` SQL Galaxy Repository — read-only queries only), area/object + security settings for the `TestMachine_00x` objects, and any alarm-security docs in + the mxaccess analysis project. **Read-only: do not change galaxy security config.** +2. **Path 1 — platform-side ack:** only if a *scriptable, non-interactive* path exists on + the rig as-installed (e.g. an existing harness or automation entry point). Do NOT + install software, do NOT drive GUI automation, do NOT change rig state beyond the + established raise/clear pattern on `TestMachine_001.TestAlarm001`. If only interactive + IDE/InTouch paths exist, record that and stop. +3. Whatever the outcome, append the third-attempt section: what was inspected, evidence, + and the leg's final status (observed / unavailable-by-configuration / still assumed + with the paths requiring a human). If the ack was actually observed, record whether + `STATE` reached `ACK_ALM` and whether the GUID survived — that answers the original + question and should update the findings table at the top of the doc. +4. **Stop condition:** at ~15 minutes of probing without a decisive result, write up what + was learned and conclude "still assumed" — the doc itself notes this is a + documentation gap, not a correctness one. + +**Commit:** `docs(probe): ack-leg third attempt — `. + +--- + +### Task 9: Windev toolchain pin + full verification + +**Classification:** verification (no review chain) +**Estimated implement time:** ~15 min wall (mostly build/test wait) +**Parallelizable with:** none (after all code tasks land and are pushed) + +**Files:** none in-repo except possibly `docs/ToolchainLinks.md` (update the windev +`protoc-gen-go-grpc` entry if it records 1.6.1). + +**Procedure (all over `ssh windev`, CI clone `C:\build\mxaccessgw-ci` at this branch tip):** +1. `go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.6.2` — then + `protoc-gen-go-grpc --version` must report 1.6.2. Update `docs/ToolchainLinks.md` if + it pins the old version (commit from the Mac tree). +2. Full `slnx` build — 0 warnings / 0 errors (clear Contracts obj/bin on CS2001/CS0016). +3. Worker tests `-p:Platform=x86` — expect the Task 7 outcome (fully green if fixed; + otherwise the documented known-failure only). +4. Gateway tests — full suite; rerun filtered on load flakes before believing a failure. +5. `powershell scripts/check-codegen.ps1` — **all 4 checks**, proving Task 1 on the + platform that had the bug. +6. `gradle --version` + `gradle :zb-mom-ww-mxgateway-client:checkGeneratedClean` from + `clients\java` if Gradle is installed there — record version and result either way. +7. Live MXAccess smoke: `MXGATEWAY_RUN_LIVE_MXACCESS_TESTS=1`, filter + `WorkerLiveMxAccessSmokeTests` — 8/8. +8. Report every result verbatim (counts, not "green"). + +--- + +### Task 10: Bookkeeping — close the follow-ups record + +**Classification:** trivial +**Estimated implement time:** ~3 min +**Parallelizable with:** none (last) + +**Files:** +- Modify: `docs/plans/2026-08-17-followup-closeout.md` (follow-ups block `:483-507`): + annotate each bullet closed with this branch's closing commit (or precisely narrowed, + e.g. ack leg if still assumed) +- Modify: `docs/plans/2026-08-18-followups-and-tickets.md` (this file): append as-built + notes — per-task commits, review outcomes, verification results, anything learned +- Modify: `docs/plans/2026-08-18-followups-and-tickets.md.tasks.json`: final statuses + +**Commit:** `chore(plan): followups-and-tickets as-built record; prior follow-ups closed`. + +--- + +## Execution notes for the controller + +- **Model/review chains** (subagent-driven-development skill): Tasks 1–4 small → Sonnet + implementer + Haiku code review (diffs <100 LOC). Task 5 standard → Opus implementer, + spec (Haiku) ∥ code (Sonnet). Task 6 standard → Opus implementer, spec ∥ code. Task 7 + high-risk → Opus implementer, serial spec (Haiku) → code (Sonnet). Task 8 standard → + Opus implementer, spec ∥ code. Task 9 verification → Opus, no review. Task 10 trivial → + Sonnet, no review. +- **Waves:** Wave 1 = Tasks 1, 2, 3, 4, 5, 7 (disjoint files; Task 7 alone on windev). + Wave 2 = Task 6 (after 4) and Task 8 (after 7). Wave 3 = push branch, Task 9. + Wave 4 = Task 10, final integration review, then hold for the user's merge decision. +- **Push cadence:** controller pushes the branch before any windev task needs its code + there (Task 7 investigates on-branch; Tasks 8–9 need the wave-1/2 tips). diff --git a/docs/plans/2026-08-18-followups-and-tickets.md.tasks.json b/docs/plans/2026-08-18-followups-and-tickets.md.tasks.json new file mode 100644 index 0000000..6a82449 --- /dev/null +++ b/docs/plans/2026-08-18-followups-and-tickets.md.tasks.json @@ -0,0 +1,16 @@ +{ + "planPath": "docs/plans/2026-08-18-followups-and-tickets.md", + "tasks": [ + {"id": 1, "subject": "Task 1: check-codegen Check 4 — Windows .exe banner normalization", "status": "pending"}, + {"id": 2, "subject": "Task 2: Gradle 9 checkGeneratedClean via ProviderFactory.exec", "status": "pending"}, + {"id": 3, "subject": "Task 3: SettingsPage RecentFaultLimit/RecentSessionLimit rows", "status": "pending"}, + {"id": 4, "subject": "Task 4: Authentication.md runnable-as-written examples pass", "status": "pending"}, + {"id": 5, "subject": "Task 5: AlarmsPage push-driven truncation banner (snapshot_status)", "status": "pending"}, + {"id": 6, "subject": "Task 6: Server-0xx doc-only resolution audit", "status": "pending", "blockedBy": [4]}, + {"id": 7, "subject": "Task 7: WorkerPipeSessionTests deterministic failure — investigate + fix (windev)", "status": "pending"}, + {"id": 8, "subject": "Task 8: Ack-leg probe bounded unblock attempt (windev rig)", "status": "pending", "blockedBy": [7]}, + {"id": 9, "subject": "Task 9: Windev toolchain pin + full verification", "status": "pending", "blockedBy": [1, 2, 3, 4, 5, 6, 7, 8]}, + {"id": 10, "subject": "Task 10: Bookkeeping — close the follow-ups record", "status": "pending", "blockedBy": [9]} + ], + "lastUpdated": "2026-08-18" +}