Files
natsnet/docs/plans/2026-02-27-batch-7-opts-class-methods-reload-plan.md
Joseph Doherty f0455a1e45 Add batch plans for batches 6-7, 9-12, 16-17 (rounds 4-7)
Generated design docs and implementation plans via Codex for:
- Batch 6: Opts package-level functions
- Batch 7: Opts class methods + Reload
- Batch 9: Auth, DirStore, OCSP foundations
- Batch 10: OCSP Cache + JS Events
- Batch 11: FileStore Init
- Batch 12: FileStore Recovery
- Batch 16: Client Core (first half)
- Batch 17: Client Core (second half)

All plans include mandatory verification protocol and anti-stub guardrails.
Updated batches.md with file paths and planned status.
2026-02-27 14:56:19 -05:00

495 lines
17 KiB
Markdown

# Batch 7 (Opts Class Methods + Reload) Implementation Plan
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
**Goal:** Implement and verify Batch 7 config-receiver and reload orchestration behavior from `server/opts.go` and `server/reload.go` (`25` features, `63` tests) with evidence-backed status updates and zero stubs.
**Architecture:** Execute two feature groups (both <=20 features) in Go source order, then execute three test groups by mapped .NET class. Use strict per-feature and per-test verification loops, and promote statuses only when build and related tests prove behavior. Keep blocked items deferred with explicit reasons rather than stubbing.
**Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`)
**Design doc:** `docs/plans/2026-02-27-batch-7-opts-class-methods-reload-design.md`
---
## Batch 7 Working Set
Batch facts:
- Batch ID: `7`
- Features: `25`
- Tests: `63`
- Depends on: `Batch 6`
- Go files: `golang/nats-server/server/opts.go`, `golang/nats-server/server/reload.go`
Environment note:
- Use `/usr/local/share/dotnet/dotnet` for all dotnet commands in this workspace.
Feature groups (<=20 features each):
- **F1 Config receiver + reload helper primitives (14):** `2510,2511,2513,2514,2815,2816,2839,2873,2875,2877,2878,2886,2887,2888`
- **F2 Reload orchestration + server apply path (11):** `2869,2872,2874,2876,2879,2880,2881,2882,2883,2884,2885`
Test groups:
- **T1 ServerOptions mapping (`40`):** `2514,2517,2519,2520,2521,2522,2523,2525,2526,2527,2528,2529,2530,2531,2532,2533,2540,2541,2542,2544,2545,2546,2547,2549,2550,2553,2555,2556,2557,2560,2565,2566,2567,2569,2583,2588,2589,2590,2593,2597`
- **T2 Route/Leaf/Proxy mapping (`18`):** `1897,1898,1908,1909,1932,1939,1943,2796,2797,2799,2800,2801,2802,2803,2804,2805,2806,2813`
- **T3 Cross-cutting reload regressions (`5`):** `1893,2239,2372,2774,2904`
---
## MANDATORY VERIFICATION PROTOCOL
> **NON-NEGOTIABLE:** No feature or test can be promoted without this evidence loop.
### Per-Feature Verification Loop (REQUIRED)
For every feature ID:
1. Read mapping and exact Go location:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- feature show <feature-id> --db porting.db
```
2. Read referenced Go code in `opts.go` or `reload.go`.
3. Implement only that feature's behavior in C#.
4. Build immediately:
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
5. Run related mapped tests (at least class-filtered) for the behavior touched.
6. Add feature ID to promotion candidate list only if build + related tests are green.
### Stub Detection Check (REQUIRED)
Run after each feature sub-slice and each test class before status updates:
```bash
# Source and test stub markers
rg -n "NotImplementedException|TODO|PLACEHOLDER|throw new Exception\(\"not implemented\"\)" \
dotnet/src/ZB.MOM.NatsNet.Server/ServerOptions*.cs \
dotnet/src/ZB.MOM.NatsNet.Server/Config/*.cs \
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer*.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/*.cs
# Empty method bodies in touched C# files
rg -n "^\s*(public|private|internal|protected).+\)\s*\{\s*\}\s*$" \
dotnet/src/ZB.MOM.NatsNet.Server/ServerOptions*.cs \
dotnet/src/ZB.MOM.NatsNet.Server/Config/*.cs \
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer*.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/*.cs
```
If any match appears in code touched for Batch 7, do not promote status until fixed or explicitly deferred.
### Build Gate (REQUIRED)
After each feature group (`F1`, `F2`):
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
Gate condition: build must succeed with `0` errors.
### Test Gate (REQUIRED)
All related tests must pass before setting features to `verified`.
Suggested class gates:
```bash
# F1 related class gate
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ImplBacklog.ServerOptionsTests|FullyQualifiedName~ImplBacklog.RouteHandlerTests|FullyQualifiedName~ImplBacklog.LeafNodeHandlerTests|FullyQualifiedName~ImplBacklog.LeafNodeProxyTests" \
--verbosity normal
# F2 related class gate
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ImplBacklog.ConfigReloaderTests|FullyQualifiedName~ImplBacklog.NatsServerTests|FullyQualifiedName~ImplBacklog.JwtProcessorTests|FullyQualifiedName~ImplBacklog.MqttHandlerTests|FullyQualifiedName~ImplBacklog.ConcurrencyTests1|FullyQualifiedName~ImplBacklog.RouteHandlerTests|FullyQualifiedName~ImplBacklog.LeafNodeHandlerTests" \
--verbosity normal
```
Gate condition: `Failed: 0`.
### Status Update Protocol (REQUIRED)
Rules:
- Use `<=15` IDs per `feature batch-update` or `test batch-update` call.
- Evidence required for every promotion chunk:
- feature/test IDs being promoted
- latest build gate output
- relevant test gate output
- latest stub scan output
- Status progression:
- Features: `deferred/not_started -> stub -> complete -> verified`
- Tests: `deferred/not_started -> stub -> verified` (or stay `deferred` with reason)
Command templates:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<ids <=15>" --set-status <stub|complete|verified> --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "<ids <=15>" --set-status <stub|verified> --db porting.db --execute
```
If Roslyn audit blocks update:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status <status> --db porting.db --override "evidence: <short reason>"
```
### Checkpoint Protocol Between Tasks (REQUIRED)
After each task before moving to the next:
1. Full build:
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
2. Full unit test suite:
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
3. Record summary counts (`Passed`, `Failed`, `Skipped`).
4. Commit task slice before continuing.
---
## ANTI-STUB GUARDRAILS
### Forbidden Patterns
The following are forbidden for Batch 7 feature and test work:
- `throw new NotImplementedException(...)`
- Empty mapped feature methods (`{ }`) or empty lambda bodies
- `TODO` / `PLACEHOLDER` used as unresolved behavior for mapped IDs
- Fake-positive tests (`Assert.True(true)`, method-name string assertions, constant-only checks with no Act)
- Tests that do not invoke production code from `ZB.MOM.NatsNet.Server.*`
### Hard Limits
- Max `20` features per feature group (already enforced: `14` and `11`)
- Max `15` IDs per any batch status update command
- Max one feature-group promotion cycle at a time
- Mandatory build gate after each feature group
- Mandatory related-test gate before any `verified` feature promotion
- Mandatory checkpoint (full build + full test + commit) between tasks
### If You Get Stuck (REQUIRED)
Do not stub. Do not fake-pass tests.
1. Keep blocked item `deferred`.
2. Add explicit blocker reason.
3. Continue with next unblocked item.
Commands:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status deferred --db porting.db \
--override "blocked: <specific unported dependency/runtime requirement>"
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test update <id> --status deferred --db porting.db \
--override "blocked: <specific unported dependency/runtime requirement>"
```
---
### Task 1: Preflight and Batch Activation
**Files:**
- Modify: `porting.db`
**Step 1: Verify dependency state (`Batch 6`)**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 6 --db porting.db
```
Expected: Batch 6 complete before starting Batch 7 implementation.
**Step 2: Start Batch 7**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch start 7 --db porting.db
```
**Step 3: Mark F1 features as `stub` (single chunk <=15)**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2510,2511,2513,2514,2815,2816,2839,2873,2875,2877,2878,2886,2887,2888" \
--set-status stub --db porting.db --execute
```
**Step 4: Run checkpoint protocol and commit**
---
### Task 2: Implement Feature Group F1 (Config Receiver + Reload Helpers)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ServerOptions.Methods.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Config/ServerOptionsConfiguration.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Config/ReloadOptions.cs`
- Create (if needed): `dotnet/src/ZB.MOM.NatsNet.Server/Config/ReloadDiffHelpers.cs`
- Modify: `porting.db`
**Step 1: Execute per-feature verification loop for each F1 ID**
IDs: `2510,2511,2513,2514,2815,2816,2839,2873,2875,2877,2878,2886,2887,2888`
**Step 2: Run stub detection check on touched source and test files**
**Step 3: Run F1 build gate and F1 test gate**
**Step 4: Promote F1 features to `complete` (single chunk)**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2510,2511,2513,2514,2815,2816,2839,2873,2875,2877,2878,2886,2887,2888" \
--set-status complete --db porting.db --execute
```
**Step 5: Promote F1 features to `verified` only if F1 test gate is green**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2510,2511,2513,2514,2815,2816,2839,2873,2875,2877,2878,2886,2887,2888" \
--set-status verified --db porting.db --execute
```
**Step 6: Run checkpoint protocol and commit**
---
### Task 3: Implement Feature Group F2 (Server Reload Orchestration)
**Files:**
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Reload.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Config/ReloadOptions.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.cs` (only if field/property exposure is required)
- Modify: `porting.db`
**Step 1: Mark F2 as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2869,2872,2874,2876,2879,2880,2881,2882,2883,2884,2885" \
--set-status stub --db porting.db --execute
```
**Step 2: Execute per-feature verification loop for each F2 ID**
**Step 3: Run stub detection check**
**Step 4: Run build gate and F2 test gate**
**Step 5: Promote F2 to `complete`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2869,2872,2874,2876,2879,2880,2881,2882,2883,2884,2885" \
--set-status complete --db porting.db --execute
```
**Step 6: Promote F2 to `verified` only with green F2 test gate**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2869,2872,2874,2876,2879,2880,2881,2882,2883,2884,2885" \
--set-status verified --db porting.db --execute
```
**Step 7: Run checkpoint protocol and commit**
---
### Task 4: Implement Test Group T1 (ServerOptions Tests, 40 IDs)
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ServerOptionsTests.Impltests.cs`
- Modify: `porting.db`
**Step 1: Mark T1 IDs as `stub` in <=15 chunks**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "2514,2517,2519,2520,2521,2522,2523,2525,2526,2527,2528,2529,2530,2531,2532" \
--set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "2533,2540,2541,2542,2544,2545,2546,2547,2549,2550,2553,2555,2556,2557,2560" \
--set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "2565,2566,2567,2569,2583,2588,2589,2590,2593,2597" \
--set-status stub --db porting.db --execute
```
**Step 2: For each T1 ID, run per-test loop (read Go test, write real Arrange/Act/Assert, run single test)**
**Step 3: Run class-level gate for `ServerOptionsTests`**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ImplBacklog.ServerOptionsTests" --verbosity normal
```
**Step 4: Run stub scan and reject any placeholder patterns**
**Step 5: Promote T1 IDs to `verified` in the same <=15 chunks only after class gate is green**
**Step 6: Run checkpoint protocol and commit**
---
### Task 5: Implement Test Group T2 (Route/Leaf/Proxy, 18 IDs)
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/LeafNodeHandlerTests.Impltests.cs`
- Create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/LeafNodeProxyTests.Impltests.cs`
- Modify: `porting.db`
**Step 1: Mark T2 IDs as `stub` in <=15 chunks**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "1897,1898,1908,1909,1932,1939,1943,2796,2797,2799,2800,2801,2802,2803,2804" \
--set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "2805,2806,2813" \
--set-status stub --db porting.db --execute
```
**Step 2: Execute per-test verification loop for each ID**
**Step 3: Run class gates**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ImplBacklog.RouteHandlerTests|FullyQualifiedName~ImplBacklog.LeafNodeHandlerTests|FullyQualifiedName~ImplBacklog.LeafNodeProxyTests" \
--verbosity normal
```
**Step 4: Run stub scan on all three class files**
**Step 5: Promote T2 IDs to `verified` (same <=15 chunks) only when class gates pass**
**Step 6: Run checkpoint protocol and commit**
---
### Task 6: Implement Test Group T3 (Cross-Cutting, 5 IDs)
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConfigReloaderTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JwtProcessorTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MqttHandlerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests1.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.Impltests.cs`
- Modify: `porting.db`
**Step 1: Mark T3 IDs as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "1893,2239,2372,2774,2904" \
--set-status stub --db porting.db --execute
```
**Step 2: Execute per-test loop for each ID**
**Step 3: Run focused class gate**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ImplBacklog.ConfigReloaderTests|FullyQualifiedName~ImplBacklog.JwtProcessorTests|FullyQualifiedName~ImplBacklog.MqttHandlerTests|FullyQualifiedName~ImplBacklog.ConcurrencyTests1|FullyQualifiedName~ImplBacklog.NatsServerTests" \
--verbosity normal
```
**Step 4: Run stub scan on touched files**
**Step 5: Promote T3 IDs to `verified`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "1893,2239,2372,2774,2904" \
--set-status verified --db porting.db --execute
```
**Step 6: Run checkpoint protocol and commit**
---
### Task 7: Final Batch 7 Closure Verification
**Files:**
- Modify: `porting.db`
- Generate: `reports/current.md` (via script)
**Step 1: Full regression gate**
```bash
/usr/local/share/dotnet/dotnet build dotnet/
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
Expected: build success and `Failed: 0`.
**Step 2: Batch 7 global stub audit (source + test files touched in batch)**
```bash
rg -n "NotImplementedException|TODO|PLACEHOLDER|Assert\.True\(true\)" \
dotnet/src/ZB.MOM.NatsNet.Server/ServerOptions*.cs \
dotnet/src/ZB.MOM.NatsNet.Server/Config/*.cs \
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer*.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/*.cs
```
**Step 3: Confirm batch state and summary**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 7 --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db
```
**Step 4: Complete batch when all items are `verified`/`complete`/`n_a` or explicitly deferred with reasons**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch complete 7 --db porting.db
```
**Step 5: Generate report and commit**
```bash
./reports/generate-report.sh
git add dotnet/src/ZB.MOM.NatsNet.Server dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog porting.db reports/
git commit -m "feat(batch7): implement opts class methods and reload with verified tests"
```
---
## Notes for Execution
- Prefer behavior parity to Go intent over line-by-line translation.
- Keep reload behavior deterministic by preserving option application order.
- If any feature cannot be correctly completed because a required subsystem is unported, defer it with a concrete blocker reason instead of introducing a stub.