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.
This commit is contained in:
Joseph Doherty
2026-02-27 14:56:19 -05:00
parent b928be4f2f
commit f0455a1e45
19 changed files with 4977 additions and 9 deletions

View File

@@ -20,18 +20,18 @@
| 3 | SendQ, Service, Client ProxyProto | [design](plans/2026-02-27-batch-3-sendq-service-client-proxyproto-design.md) | [plan](plans/2026-02-27-batch-3-sendq-service-client-proxyproto-plan.md) | planned |
| 4 | Logging | [design](plans/2026-02-27-batch-4-logging-design.md) | [plan](plans/2026-02-27-batch-4-logging-plan.md) | planned |
| 5 | JetStream Errors | [design](plans/2026-02-27-batch-5-jetstream-errors-design.md) | [plan](plans/2026-02-27-batch-5-jetstream-errors-plan.md) | planned |
| 6 | Opts package-level functions | | | not_planned |
| 7 | Opts class methods + Reload | | | not_planned |
| 6 | Opts package-level functions | [design](plans/2026-02-27-batch-6-opts-package-level-functions-design.md) | [plan](plans/2026-02-27-batch-6-opts-package-level-functions-plan.md) | planned |
| 7 | Opts class methods + Reload | [design](plans/2026-02-27-batch-7-opts-class-methods-reload-design.md) | [plan](plans/2026-02-27-batch-7-opts-class-methods-reload-plan.md) | planned |
| 8 | Store Interfaces | [design](plans/2026-02-27-batch-8-store-interfaces-design.md) | [plan](plans/2026-02-27-batch-8-store-interfaces-plan.md) | planned |
| 9 | Auth, DirStore, OCSP foundations | | | not_planned |
| 10 | OCSP Cache + JS Events | | | not_planned |
| 11 | FileStore Init | | | not_planned |
| 12 | FileStore Recovery | | | not_planned |
| 9 | Auth, DirStore, OCSP foundations | [design](plans/2026-02-27-batch-9-auth-dirstore-ocsp-foundations-design.md) | [plan](plans/2026-02-27-batch-9-auth-dirstore-ocsp-foundations-plan.md) | planned |
| 10 | OCSP Cache + JS Events | [design](plans/2026-02-27-batch-10-ocsp-cache-js-events-design.md) | [plan](plans/2026-02-27-batch-10-ocsp-cache-js-events-plan.md) | planned |
| 11 | FileStore Init | [design](plans/2026-02-27-batch-11-filestore-init-design.md) | [plan](plans/2026-02-27-batch-11-filestore-init-implementation-plan.md) | planned |
| 12 | FileStore Recovery | [design](plans/2026-02-27-batch-12-filestore-recovery-design.md) | [plan](plans/2026-02-27-batch-12-filestore-recovery-plan.md) | planned |
| 13 | FileStore Read/Query | | | not_planned |
| 14 | FileStore Write/Lifecycle | | | not_planned |
| 15 | MsgBlock + ConsumerFileStore | | | not_planned |
| 16 | Client Core (first half) | | | not_planned |
| 17 | Client Core (second half) | | | not_planned |
| 16 | Client Core (first half) | [design](plans/2026-02-27-batch-16-client-core-first-half-design.md) | [plan](plans/2026-02-27-batch-16-client-core-first-half-plan.md) | planned |
| 17 | Client Core (second half) | [design](plans/2026-02-27-batch-17-client-core-second-half-design.md) | [plan](plans/2026-02-27-batch-17-client-core-second-half-plan.md) | planned |
| 18 | Server Core | | | not_planned |
| 19 | Accounts Core | | | not_planned |
| 20 | Accounts Resolvers | | | not_planned |

View File

@@ -0,0 +1,164 @@
# Batch 10 (OCSP Cache + JS Events) Design
**Date:** 2026-02-27
**Scope:** Design-only plan for Batch 10 (`20` features, `38` tests) covering Go files `server/ocsp_responsecache.go` and `server/jetstream_events.go`.
## Context Snapshot
PortTracker snapshot from:
- `/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 10 --db porting.db`
- `/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch list --db porting.db`
- `/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db`
Observed facts:
- Batch ID: `10`
- Name: `OCSP Cache + JS Events`
- Dependency: `Batch 9`
- Status: `pending`
- Features: `20` (all currently `deferred`)
- Tests: `38` (all currently `deferred`)
- Overall progress: `1924/6942 (27.7%)`
Feature mapping summary:
- JetStream advisory publish path: `1959 (Server.publishAdvisory)`
- OCSP cache config/parser: `2472`, `2501`
- Local cache behavior: `2484-2497`
- Server OCSP cache lifecycle wiring: `2498-2500`
Readiness reality from dependency analysis (`sqlite3` on `porting.db`):
- All Batch 10 features have `0` unresolved dependencies.
- Batch 10 tests are mixed:
- `8` tests become implementable once Batch 10 features are done.
- `30` tests still depend on external deferred features (not in Batch 10), so they cannot be honestly verified in this batch.
## Problem Statement
Batch 10 is a foundational OCSP cache batch with one JetStream advisory method. The main risk is false progress: implementing local cache APIs superficially or marking cross-module tests verified while upstream features remain deferred.
## Constraints and Success Criteria
Constraints:
- Execute after Batch 9 dependency.
- Follow .NET standards (`.NET 10`, nullable, xUnit 3 + Shouldly + NSubstitute).
- No fake-pass tests and no production stubs promoted to `verified`.
- Status updates must be evidence-backed and chunked (`<= 15` IDs per batch-update).
Success criteria:
- All 20 Batch 10 features implemented with Go-behavior parity and verification evidence.
- Batch 10 mapped tests split correctly into:
- truly verified tests (only when unblocked and passing), and
- deferred tests with concrete dependency/runtime reasons.
- Batch completion only attempted after gates pass.
## Approaches
### Approach A: Minimal API shims (fast status movement)
Implement signatures for local cache and parser methods with simplified behavior.
- Pros: quick throughput.
- Cons: high semantic drift from Go behavior (stats, revocation preservation, atomic save path, timer semantics).
### Approach B: Full-fidelity OCSP cache parity in one pass (all tests now)
Implement complete OCSP cache and attempt to force all 38 tests to pass in Batch 10.
- Pros: ambitious closure.
- Cons: invalid for this dependency graph because 30 tests still depend on external deferred features.
### Approach C (Recommended): Feature-complete cache + dependency-aware test closure
Port all Batch 10 features fully, then verify only tests that become unblocked; keep externally blocked tests deferred with explicit evidence.
- Pros: truthful status accounting, lower regression risk, auditable progress.
- Cons: leaves some Batch 10 tests deferred until upstream batches progress.
## Recommended Design
### 1. Production Code Architecture
Primary code paths:
- `dotnet/src/ZB.MOM.NatsNet.Server/Auth/Ocsp/OcspTypes.cs`
- `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Init.cs`
- `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Lifecycle.cs`
Expected new code files:
- `dotnet/src/ZB.MOM.NatsNet.Server/Auth/Ocsp/OcspHandler.cs`
- `NewOCSPResponseCacheConfig`
- `ParseOCSPResponseCache`
- `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.OcspResponseCache.cs`
- `InitOCSPResponseCache`
- `StartOCSPResponseCache`
- `StopOCSPResponseCache`
- `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.JetStreamEvents.cs`
- `PublishAdvisory`
Design intent:
- Replace simple disk `LocalDirCache` behavior with true Go-equivalent local cache semantics:
- in-memory cache map
- atomic stats (`hits/misses/goods/revokes/unknowns`)
- compression/decompression
- `PreserveRevoked` delete behavior
- load/save with dirty flag + periodic save timer
- Keep parser behavior strict and deterministic (invalid shape/type/cache kind => config error).
- Keep server lifecycle integration explicit in start/stop/init flows.
### 2. Test Design
Primary test files:
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/OcspResponseCacheTests.cs`
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/*.Impltests.cs` (mapped batch tests)
Expected new test files:
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/OcspResponseCacheParserTests.cs`
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/NatsServerOcspCacheTests.cs`
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/NatsServerJetStreamEventsTests.cs`
Test strategy:
- TDD at feature-group granularity:
- write failing tests for cache stats/timer/save-load/parser/server wiring/advisory publish
- implement minimal parity
- pass focused tests before status promotion
- For mapped Batch 10 tests:
- verify only those with no unresolved external dependencies after feature completion
- keep the rest deferred with explicit blocker IDs and reasons
### 3. Execution Slicing
Feature groups (`<=20` each):
- **F1 (1):** `1959`
- **F2 (13):** `2472,2484,2485,2486,2487,2488,2489,2490,2491,2492,2493,2494,2495`
- **F3 (6):** `2496,2497,2498,2499,2500,2501`
Test groups:
- **T1 Candidate Verify (8):** `1537,1538,1607,1625,1682,2442,2807,2894`
- **T2 Keep Deferred Unless Upstream Unblocks (30):** remaining Batch 10 test IDs
### 4. Risks and Mitigations
1. Timer/save behavior can introduce flaky tests.
Mitigation: deterministic timer intervals in tests, explicit waits with bounded timeouts, and repeated focused test runs.
2. Parser mismatch vs Go error semantics.
Mitigation: dedicated parser test matrix for accepted/rejected input shapes and type conversions.
3. Pressure to close all 38 tests inside this batch.
Mitigation: strict dependency evidence; external blockers stay deferred, never replaced by placeholders.
## Design Decision
Proceed with **Approach C**: full feature parity for Batch 10 plus dependency-aware test closure. This gives real progress on OCSP cache and JS advisory wiring while preventing incorrect verified statuses for externally blocked tests.

View File

@@ -0,0 +1,527 @@
# Batch 10 (OCSP Cache + JS Events) Implementation Plan
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
**Goal:** Implement and verify Batch 10 (`20` features + `38` tests) for OCSP response-cache behavior and JetStream advisory publishing, while keeping externally blocked tests deferred with explicit evidence.
**Architecture:** Implement Batch 10 in three feature groups (1/13/6 IDs) and two test-resolution groups (candidate-verify + blocked-defer). Use strict per-feature verification loops, stub detection, and chunked status updates so every transition to `complete`/`verified` is evidence-backed.
**Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`)
---
I'm using `writeplan` to create the implementation plan.
**Design doc:** `docs/plans/2026-02-27-batch-10-ocsp-cache-js-events-design.md`
## Batch 10 Working Set
Batch facts:
- Batch ID: `10`
- Depends on: `9`
- Features: `20`
- Tests: `38`
- Go files: `server/ocsp_responsecache.go`, `server/jetstream_events.go`
Environment note:
- In this workspace, use `/usr/local/share/dotnet/dotnet` (not `dotnet`) for CLI commands.
Feature groups (all <= 20 IDs):
- **F1 (1):** `1959`
- **F2 (13):** `2472,2484,2485,2486,2487,2488,2489,2490,2491,2492,2493,2494,2495`
- **F3 (6):** `2496,2497,2498,2499,2500,2501`
Test groups:
- **T1 candidate verify (8):** `1537,1538,1607,1625,1682,2442,2807,2894`
- **T2 dependency-blocked (30):** `641,684,1407,1837,1934,1946,1978,2002,2005,2042,2049,2050,2051,2052,2055,2058,2059,2060,2061,2062,2063,2177,2250,2487,2810,2812,2839,2862,3103,3112`
---
## MANDATORY VERIFICATION PROTOCOL
> NON-NEGOTIABLE: Every task in this plan must follow this protocol.
### Per-Feature Verification Loop (required for every feature ID)
1. Read mapping + Go source:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- feature show <feature_id> --db porting.db
```
2. Read exact Go implementation in `golang/nats-server/server/jetstream_events.go` or `golang/nats-server/server/ocsp_responsecache.go`.
3. Write/adjust C# implementation in mapped .NET file.
4. Build immediately:
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
5. Run related focused tests for that feature group.
6. Only after build + focused tests pass, add ID to promotion candidate list.
### Stub Detection Check (required after every feature/test group)
Run all checks before status updates:
```bash
# Placeholder/stub markers in touched code
rg -n "NotImplementedException|TODO|PLACEHOLDER|throw new NotSupportedException" \
dotnet/src/ZB.MOM.NatsNet.Server \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests
# Empty method bodies in touched C# files
for f in $(git diff --name-only -- '*.cs'); do
rg -n "^\s*(public|internal|private|protected).+\)\s*\{\s*\}$" "$f"
done
# Suspicious trivial returns in touched production files
for f in $(git diff --name-only dotnet/src/ZB.MOM.NatsNet.Server -- '*.cs'); do
rg -n "=>\s*(default|null|true|false);$" "$f"
done
```
Any hit blocks promotion to `complete` or `verified` until fixed or explicitly deferred.
### Build Gate (required after each feature group)
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
Required: `0` compile errors.
### Test Gate (required before marking features verified)
All tests related to current feature group must pass before moving feature IDs to `verified`.
Focused test commands are defined inside each task. If any test fails, do not promote.
### Status Update Protocol (required)
- Maximum `15` IDs per `feature batch-update` or `test batch-update` command.
- Required evidence per update command:
- latest build gate output
- latest focused test gate output
- latest stub detection output
- Required flow:
- Feature IDs: `deferred -> stub -> complete -> verified`
- Test IDs: `deferred -> stub -> verified` or remain `deferred` with blocker reason
Command templates:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<max15ids>" --set-status <stub|complete|verified> --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "<max15ids>" --set-status <stub|verified> --db porting.db --execute
```
### Checkpoint Protocol Between Tasks (required)
Between every task boundary (Task 1 -> Task 2 -> ...):
1. Full build:
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
2. Full unit test run:
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
3. Commit checkpoint:
```bash
git add <touched-files> porting.db
git commit -m "feat(batch10): <task checkpoint summary>"
```
---
## ANTI-STUB GUARDRAILS
### Forbidden Patterns
Do not mark as `verified` if any mapped method/test includes:
- `throw new NotImplementedException(...)`
- empty mapped method bodies (`{ }`)
- `TODO` or placeholder comments in method/test bodies
- fake pass assertions (`Assert.True(true)`, equivalent no-op assertions)
- tests that only assert non-behavioral values (for example, not-null only with no behavior)
### Hard Limits
- Max `20` feature IDs per implementation task group.
- Max `15` IDs per status update command.
- No cross-group bulk verification in one command cycle.
- Build gate is mandatory after each feature group.
- Test gate is mandatory before any feature moves to `verified`.
- Checkpoint commit is mandatory between tasks.
### If You Get Stuck
Do not stub and do not fake-pass.
1. Leave item as `deferred`.
2. Record specific blocker reason (dependency ID, missing runtime path, or infra need).
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 reason>"
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test update <id> --status deferred --db porting.db \
--override "blocked: <specific reason>"
```
---
### Task 1: Preflight and Batch Start
**Files:**
- Modify: `porting.db`
**Step 1: Verify dependency batch state**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 9 --db porting.db
```
Expected: Batch 9 is complete enough to start Batch 10.
**Step 2: Start Batch 10**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch start 10 --db porting.db
```
Expected: Batch 10 transitions to in-progress.
**Step 3: Baseline dependency evidence for Batch 10 tests**
```bash
cat <<'SQL' | sqlite3 -header -column porting.db
WITH t AS (
SELECT ut.id, ut.name
FROM unit_tests ut
JOIN batch_tests bt ON bt.test_id=ut.id
WHERE bt.batch_id=10
), unresolved AS (
SELECT d.source_id AS test_id,
SUM(CASE WHEN f.status NOT IN ('complete','verified','n_a') THEN 1 ELSE 0 END) AS unresolved_total,
SUM(CASE WHEN f.status NOT IN ('complete','verified','n_a')
AND f.id NOT IN (SELECT feature_id FROM batch_features WHERE batch_id=10)
THEN 1 ELSE 0 END) AS unresolved_outside_batch
FROM dependencies d
JOIN features f ON d.target_type='feature' AND d.target_id=f.id
WHERE d.source_type='unit_test' AND d.source_id IN (SELECT id FROM t)
GROUP BY d.source_id
)
SELECT * FROM unresolved ORDER BY test_id;
SQL
```
Expected: `T1` IDs have `unresolved_outside_batch=0`; `T2` IDs have `>0`.
**Step 4: Run checkpoint protocol and commit preflight evidence**
---
### Task 2: Implement Feature Group F1 (`1959`) JetStream Advisory Publish
**Files:**
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.JetStreamEvents.cs`
- Create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/NatsServerJetStreamEventsTests.cs`
- Modify: `porting.db`
**Step 1: Mark feature `1959` as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature update 1959 --status stub --db porting.db
```
**Step 2: Write failing tests for advisory decision tree**
Cover:
- null account falls back to `SystemAccount()`
- no interest returns false without send
- marshal/send errors return false
- successful send returns true
**Step 3: Run focused tests and confirm initial fail**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~NatsServerJetStreamEventsTests" --verbosity normal
```
**Step 4: Implement `PublishAdvisory` parity in new partial class**
**Step 5: Re-run focused tests and require pass**
Use same command as Step 3.
**Step 6: Run stub detection + build gate + test gate**
**Step 7: Promote feature `1959`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature update 1959 --status complete --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature update 1959 --status verified --db porting.db
```
**Step 8: Run checkpoint protocol and commit**
---
### Task 3: Implement Feature Group F2 (`2472,2484-2495`) Local Cache Core + Stats + Compression
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Auth/Ocsp/OcspTypes.cs`
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/Auth/Ocsp/OcspHandler.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/OcspResponseCacheTests.cs`
- Create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/OcspResponseCacheParserTests.cs`
- Modify: `porting.db`
**Step 1: Mark F2 IDs as `stub` (single command, 13 IDs <= 15)**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2472,2484,2485,2486,2487,2488,2489,2490,2491,2492,2493,2494,2495" \
--set-status stub --db porting.db --execute
```
**Step 2: Add failing tests for local cache behavior**
Cover:
- stats adjust on put/replace/delete
- hit->miss adjustment when preserving revoked entries
- `Online/Type/Config/Stats` semantics
- compress/decompress round-trip
- `NewOCSPResponseCacheConfig` defaults
**Step 3: Run focused tests and confirm initial fail**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~OcspResponseCacheTests|FullyQualifiedName~OcspResponseCacheParserTests" --verbosity normal
```
**Step 4: Implement F2 methods with per-feature verification loop**
**Step 5: Re-run focused tests and require pass**
Use same command as Step 3.
**Step 6: Run stub detection + build gate + test gate**
**Step 7: Promote F2 IDs in two transitions (`complete`, then `verified`)**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2472,2484,2485,2486,2487,2488,2489,2490,2491,2492,2493,2494,2495" \
--set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2472,2484,2485,2486,2487,2488,2489,2490,2491,2492,2493,2494,2495" \
--set-status verified --db porting.db --execute
```
**Step 8: Run checkpoint protocol and commit**
---
### Task 4: Implement Feature Group F3 (`2496,2497,2498,2499,2500,2501`) Load/Save + Server Wiring + Parser
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Auth/Ocsp/OcspTypes.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Auth/Ocsp/OcspHandler.cs`
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.OcspResponseCache.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Init.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Lifecycle.cs`
- Create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/NatsServerOcspCacheTests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/OcspResponseCacheParserTests.cs`
- Modify: `porting.db`
**Step 1: Mark F3 IDs as `stub` (6 IDs)**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2496,2497,2498,2499,2500,2501" --set-status stub --db porting.db --execute
```
**Step 2: Add failing tests for load/save lifecycle + parser + server init/start/stop**
Cover:
- load from absent/corrupt/valid cache file
- save no-op when clean + atomic write when dirty
- parser type conversion + minimum save interval clamp
- server init chooses no-op/local cache correctly
- start/stop wiring calls cache lifecycle
**Step 3: Run focused tests and confirm initial fail**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~OcspResponseCacheTests|FullyQualifiedName~OcspResponseCacheParserTests|FullyQualifiedName~NatsServerOcspCacheTests" --verbosity normal
```
**Step 4: Implement F3 methods with per-feature verification loop**
**Step 5: Re-run focused tests and require pass**
Use same command as Step 3.
**Step 6: Run stub detection + build gate + test gate**
**Step 7: Promote F3 IDs (`complete`, then `verified`)**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2496,2497,2498,2499,2500,2501" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2496,2497,2498,2499,2500,2501" --set-status verified --db porting.db --execute
```
**Step 8: Run checkpoint protocol and commit**
---
### Task 5: Resolve Batch 10 Tests (T1 verify, T2 defer with reason)
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests1.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.Impltests.cs`
- Modify: `porting.db`
**Step 1: Mark T1 + T2 IDs as `stub` in chunks <= 15**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "1537,1538,1607,1625,1682,2442,2807,2894" --set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "641,684,1407,1837,1934,1946,1978,2002,2005,2042,2049,2050,2051,2052,2055" \
--set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "2058,2059,2060,2061,2062,2063,2177,2250,2487,2810,2812,2839,2862,3103,3112" \
--set-status stub --db porting.db --execute
```
**Step 2: Port and verify T1 tests one-by-one using per-test loop**
For each T1 test ID:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- test show <test_id> --db porting.db
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~<ExactMethodName>" --verbosity normal
```
Expected: each verified method shows `Passed: 1`.
**Step 3: Promote T1 verified tests in one chunk (8 IDs <= 15)**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "1537,1538,1607,1625,1682,2442,2807,2894" --set-status verified --db porting.db --execute
```
**Step 4: For T2, prove unresolved external dependencies and keep deferred**
```bash
cat <<'SQL' | sqlite3 -header -column porting.db
WITH t AS (
SELECT ut.id, ut.name
FROM unit_tests ut
JOIN batch_tests bt ON bt.test_id=ut.id
WHERE bt.batch_id=10
AND ut.id IN (641,684,1407,1837,1934,1946,1978,2002,2005,2042,2049,2050,2051,2052,2055,
2058,2059,2060,2061,2062,2063,2177,2250,2487,2810,2812,2839,2862,3103,3112)
)
SELECT t.id, t.name, f.id AS blocked_feature_id, f.name AS blocked_feature_name, f.status
FROM t
JOIN dependencies d ON d.source_type='unit_test' AND d.source_id=t.id AND d.target_type='feature'
JOIN features f ON f.id=d.target_id
WHERE f.status NOT IN ('complete','verified','n_a')
AND f.id NOT IN (SELECT feature_id FROM batch_features WHERE batch_id=10)
ORDER BY t.id, f.id;
SQL
```
Then keep each blocked test deferred with reason:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test update <blocked_test_id> --status deferred --db porting.db \
--override "blocked: unresolved dependency feature <id> (<name>)"
```
**Step 5: Run stub detection + build gate + test gate + checkpoint commit**
---
### Task 6: Final Batch 10 Verification and Attempted Closure
**Files:**
- Modify: `porting.db`
- Generate: `reports/current.md`
**Step 1: Full verification gates**
```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 passes; no unexpected test regressions.
**Step 2: Global stub audit for touched scope**
```bash
rg -n "NotImplementedException|TODO|PLACEHOLDER|Assert\.True\(true\)" \
dotnet/src/ZB.MOM.NatsNet.Server \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests
```
Expected: no matches in Batch 10 touched code/tests.
**Step 3: Verify batch/test visibility**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 10 --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db
```
**Step 4: Try completing batch**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch complete 10 --db porting.db
```
If blocked by deferred T2 tests, keep batch in-progress with documented blockers (correct behavior).
**Step 5: Generate report and final commit**
```bash
./reports/generate-report.sh
git add dotnet/src/ZB.MOM.NatsNet.Server \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests \
porting.db reports/
git commit -m "feat(batch10): implement ocsp cache and js advisory with verified gates"
```

View File

@@ -0,0 +1,114 @@
# Batch 11 FileStore Init Design
**Date:** 2026-02-27
**Batch:** 11 (`FileStore Init`)
**Dependency:** Batch 8 (`Store Interfaces`)
**Scope:** 39 features + 123 tests mapped to `server/filestore.go`
---
## 1. Context and Constraints
- Batch 11 is currently `pending` with all 39 features and all 123 tests in `deferred` status.
- Current .NET `JetStreamFileStore` implementation is mostly a delegation shell to `JetStreamMemStore`; most Batch 11 methods are not present yet.
- Existing backlog tests for this area include placeholder-style tests that must not be treated as verification evidence.
- Planning only in this session: produce design + implementation plan documents, no runtime code changes.
## 2. Success Criteria
- Implement all Batch 11 feature IDs with real C# behavior matching Go intent for `filestore.go` initialization-related scope.
- Port and verify all Batch 11 tests into real behavioral tests (no placeholder assertions).
- Enforce strict verification and anti-stub guardrails before any status updates.
- Preserve dependency order and use PortTracker updates with evidence-backed chunks.
## 3. Approach Options
### Option A (Recommended): Vertical feature groups with co-evolving tests
Implement features in 3 groups (17, 16, 6 features), each followed by targeted test waves and status updates.
- Pros: bounded risk, quick feedback, easier rollback and review, aligns with dependency and guardrail requirements.
- Cons: repeated build/test cycles increase total command count.
### Option B: Implement all 39 features first, then all 123 tests
- Pros: fewer context switches between prod/test files.
- Cons: very high integration risk; defects surface late; hard to attribute failures to specific changes.
### Option C: Utilities-first (helpers, codecs, file writers) then constructors/recovery
- Pros: helper APIs stabilize early.
- Cons: delayed validation of end-to-end init behavior; tends to accumulate partial implementations.
### Recommendation
Use **Option A**. This gives the strongest control over regressions and makes status updates defensible under audit.
## 4. Proposed Design
### 4.1 Feature Workstreams (max ~20 features/group)
- **Group 1: Store creation + encryption bootstrap + metadata + block recovery (17 features)**
IDs: `955, 956, 957, 958, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 972, 974`
- **Group 2: Lost-data/state rebuild + tracking/utilities (16 features)**
IDs: `975, 976, 978, 979, 980, 989, 990, 998, 1057, 1152, 1153, 1154, 1158, 1163, 1164, 1165`
- **Group 3: Init semaphore + consumer decode + atomic file writes (6 features)**
IDs: `1200, 1235, 1239, 1248, 1261, 1262`
### 4.2 File Boundaries
- Primary production files:
- `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/FileStore.cs`
- `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/MessageBlock.cs`
- `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/FileStoreTypes.cs`
- Primary test files:
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamFileStoreTests.Impltests.cs`
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests1.Impltests.cs`
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests2.Impltests.cs`
### 4.3 Data/Control Flow to Port
- `newFileStoreWithCreated` bootstrap flow:
- validate config and storage mode
- apply dynamic block sizing defaults
- verify/create directories and writable checks
- initialize hash/checksum state and encryption metadata
- recover persisted stream/message state
- enforce limits and age/timer setup
- start background flush/state loops
- Supporting flows:
- message block buffer pooling and recycling
- block encryption key generation/recovery
- lost data tracking and rebuild state accounting
- consumer state binary header/decode path
- atomic write helpers with optional sync and directory sync
### 4.4 Error Handling Design
- Preserve failure semantics from Go intent:
- reject invalid storage config early
- propagate IO/crypto errors with contextual messages
- fail closed for corrupt headers / decode failures
- avoid silent fallback to placeholder behavior
- Ensure lock discipline for shared mutable state and block-level operations.
### 4.5 Test Design
- Replace placeholder backlog tests with behavior-focused tests derived from Go cases.
- Keep benchmark-mapped tests as either:
- converted deterministic assertions where appropriate, or
- deferred with explicit infrastructure/perf rationale.
- Include focused regression tests for encryption key lifecycle, metadata integrity, state recovery, and consumer state decoding.
## 5. Risks and Mitigations
- **Risk:** large `filestore.go` surface can lead to stub creep.
**Mitigation:** mandatory stub scans for both src and tests, hard stop on matches.
- **Risk:** hidden behavior coupling across utility methods.
**Mitigation:** group-based checkpoints with full build + targeted suite each cycle.
- **Risk:** status drift (marking verified without evidence).
**Mitigation:** evidence logs required for every feature/test update, max 15 IDs per update.
## 6. Design Outcome
This design uses a strict vertical execution model with heavy verification gates. It is structured to be executed by a plan that enforces per-feature validation loops, anti-stub guardrails, and evidence-based PortTracker updates.

View File

@@ -0,0 +1,433 @@
# Batch 11 FileStore Init Implementation Plan
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
**Goal:** Implement and verify all Batch 11 FileStore Init features/tests with real behavior parity to `server/filestore.go`, then close the batch with evidence-backed status updates.
**Architecture:** Execute Batch 11 in three vertical feature groups (17, 16, 6 features), each followed by targeted test waves and strict gates. Keep implementation centered in `JetStream/FileStore` + `MessageBlock` + `FileStoreTypes`, and use backlog test classes as the only status evidence source. Every status change is chunked, logged, and tied to passing build/test output.
**Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`)
**Design doc:** `docs/plans/2026-02-27-batch-11-filestore-init-design.md`
---
I'm using `writeplan` to create the implementation plan.
## Batch Inputs
- Batch: `11` (`FileStore Init`)
- Dependency: Batch `8`
- Features: `39`
- Tests: `123`
- Go source focus: `golang/nats-server/server/filestore.go`
Feature groups (max ~20 each):
- Group 1 (17): `955,956,957,958,960,961,962,963,964,965,966,967,968,969,970,972,974`
- Group 2 (16): `975,976,978,979,980,989,990,998,1057,1152,1153,1154,1158,1163,1164,1165`
- Group 3 (6): `1200,1235,1239,1248,1261,1262`
Primary test classes:
- `JetStreamFileStoreTests` (116 mapped tests)
- `ConcurrencyTests1` (5 mapped tests)
- `ConcurrencyTests2` (2 mapped tests)
---
## MANDATORY VERIFICATION PROTOCOL
> **NON-NEGOTIABLE:** every task below must follow this protocol exactly.
### Per-Feature Verification Loop (REQUIRED for every feature ID)
1. Read source intent from Go:
- `dotnet run --project tools/NatsNet.PortTracker -- feature show <FEATURE_ID> --db porting.db`
- Read exact Go span in `golang/nats-server/server/filestore.go`.
2. Write minimal C# implementation in mapped target files.
3. Build immediately:
- `dotnet build dotnet/`
4. Run related tests (method/class filter) for that feature's behavior.
5. Only then include the feature in `complete/verified` candidate lists.
### Stub Detection Check (REQUIRED after each feature subgroup and test class)
Run all scans below; any hit is a blocker:
```bash
# Production stubs/placeholders
rg -n "NotImplementedException|TODO|PLACEHOLDER|throw new NotSupportedException" \
dotnet/src/ZB.MOM.NatsNet.Server/JetStream -g '*.cs'
# Empty method bodies in FileStore-related source
rg -n "^\s*(public|private|internal|protected).*\)\s*\{\s*\}$" \
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/FileStore.cs \
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/MessageBlock.cs
# Test stubs/placeholders
rg -n "NotImplementedException|Assert\.True\(true\)|Assert\.Pass|// TODO|// PLACEHOLDER|ShouldBe\(true\);" \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamFileStoreTests.Impltests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests1.Impltests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests2.Impltests.cs
```
### Build Gate (REQUIRED after each feature group)
`dotnet build dotnet/` must pass before moving to next group or updating status.
### Test Gate (REQUIRED before marking features `verified`)
All related tests for the changed feature group must pass:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ImplBacklog.JetStreamFileStoreTests" \
--verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ImplBacklog.ConcurrencyTests1" \
--verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ImplBacklog.ConcurrencyTests2" \
--verbosity normal
```
### Status Update Protocol (REQUIRED, evidence-backed)
- Max **15 IDs** per `feature batch-update` or `test batch-update` call.
- Status flow:
- Features: `deferred -> stub -> complete -> verified`
- Tests: `deferred -> stub -> verified` (or `deferred` with explicit reason)
- Save evidence output before each status update (recommended path: `/tmp/batch11-evidence/`).
- Never mark `verified` without matching passing output for the exact scope.
Example chunked update:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "955,956,957,958,960,961,962,963,964,965,966,967,968,969,970" \
--set-status complete --db porting.db --execute
```
### Checkpoint Protocol Between Tasks (REQUIRED)
After each major task (each group features+tests):
1. `dotnet build dotnet/`
2. Run the three backlog test-class gates above.
3. Commit checkpoint:
- `git add dotnet/src/ZB.MOM.NatsNet.Server/JetStream dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog porting.db`
- `git commit -m "feat(batch11): complete group <N> filestore init + tests"`
Do not start the next task until checkpoint passes.
---
## ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)
### Forbidden Patterns
Do not introduce or leave any of the following in feature or test code:
- `throw new NotImplementedException(...)`
- Empty method bodies `{ }` for mapped feature methods
- `// TODO` or `// PLACEHOLDER` in implemented Batch 11 methods/tests
- Tests that only assert constants/string literals unrelated to production behavior
- `Assert.True(true)`, `Assert.Pass()`, or equivalent always-pass constructs
### Hard Limits
- Max ~20 features per task group (already fixed as 17/16/6)
- Max 15 IDs per status update command
- Max one feature group per verification/update cycle
- Zero stub-scan hits allowed before any `complete`/`verified` updates
- No deferred item may be left without a concrete reason
### If You Get Stuck
1. Stop implementation for that item.
2. Mark it `deferred` with explicit reason (infra, missing dependency, non-portable behavior, etc.).
3. Do **not** add placeholder logic or fake tests.
4. Continue with next item in the same group.
Example:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature update <ID> --status deferred --db porting.db \
--override "blocked: requires <specific dependency/infra>"
```
Use the same pattern for tests.
---
### Task 1: Batch 11 Working Set and Evidence Scaffold
**Files:**
- Modify: `porting.db`
- Create: `/tmp/batch11-evidence/`
**Step 1: Confirm batch and dependency state**
Run:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 11 --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch list --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db
```
Expected: Batch 11 pending, depends on 8, 39 features, 123 tests.
**Step 2: Start batch**
Run:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch start 11 --db porting.db
```
Expected: batch marked in-progress (if dependency checks pass).
**Step 3: Mark Group 1 features/tests as stub (chunked <=15 IDs)**
Run chunked `feature batch-update ... --set-status stub` and `test batch-update ... --set-status stub` for Group 1 scope.
Expected: only scoped IDs moved to `stub`.
**Step 4: Commit scaffold checkpoint**
Run:
```bash
git add porting.db
git commit -m "chore(batch11): start batch and stage group1 ids"
```
### Task 2: Group 1 Feature Implementation (17 features)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/FileStore.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/MessageBlock.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/FileStoreTypes.cs`
**Step 1: Implement constructors/bootstrap methods**
Feature IDs: `955, 956, 960`
**Step 2: Implement block lock + buffer pool methods**
Feature IDs: `957, 958, 967, 968, 969, 970`
**Step 3: Implement encryption key lifecycle + metadata write**
Feature IDs: `961, 962, 963, 964, 965, 966, 972`
**Step 4: Implement message block recovery path**
Feature ID: `974`
**Step 5: Apply Mandatory Verification Protocol**
- Run per-feature loop for all 17 IDs.
- Run stub scans.
- Run `dotnet build dotnet/`.
**Step 6: Mark features complete in chunks (<=15 IDs)**
Use `feature batch-update` commands with evidence log references.
### Task 3: Group 1 Test Porting and Verification
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamFileStoreTests.Impltests.cs`
**Step 1: Port Group 1-related tests (wave A)**
Primary IDs:
`351,352,353,355,357,358,359,360,361,362,369,370,371,374,375,376,377,380,381,388,397,398,400,401,421,422,423,424,425,426,427,429,430,431,432,433,434,439,443,444,532`
**Step 2: Run class filter and verify pass count growth**
Run:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ImplBacklog.JetStreamFileStoreTests" \
--verbosity normal
```
Expected: no failures for newly ported tests.
**Step 3: Run stub scans + build gate**
Apply mandatory scans and `dotnet build dotnet/`.
**Step 4: Update test statuses to verified (<=15 IDs/chunk)**
Use `test batch-update` in chunks with evidence.
**Step 5: Verify Group 1 features to verified**
Only after test gate is green.
### Task 4: Group 1 Checkpoint
**Files:**
- Modify: `porting.db`
**Step 1: Full checkpoint gate**
- `dotnet build dotnet/`
- class test gates for `JetStreamFileStoreTests`, `ConcurrencyTests1`, `ConcurrencyTests2`
**Step 2: Commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/JetStream \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog \
porting.db
git commit -m "feat(batch11): complete group1 filestore init"
```
### Task 5: Group 2 Feature Implementation (16 features)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/FileStore.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/MessageBlock.cs`
**Step 1: Implement lost-data and rebuild-state logic**
Feature IDs: `975, 976, 978, 979, 980`
**Step 2: Implement tracking/copy/flusher helpers**
Feature IDs: `989, 990, 998, 1057`
**Step 3: Implement size/header/subject helper funcs**
Feature IDs: `1152, 1153, 1154, 1158, 1163, 1164, 1165`
**Step 4: Run mandatory protocol (per-feature loop + build gate + scans)**
**Step 5: Mark features complete (chunked <=15)**
### Task 6: Group 2 Test Porting and Verification
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamFileStoreTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests1.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests2.Impltests.cs`
**Step 1: Port Group 2-related tests (wave B)**
Primary IDs:
`364,366,367,406,408,410,414,415,417,419,420,436,441,446,447,450,453,454,456,467,468,469,471,480,481,484,487,488,489,504,505,506,507,508,509,510,511,512,513,514,515,516,517,520,521,522,524,525,526,536,537,538,539,540,541,542,543,556,558,560,563,564,565,576,585,592,2452,2453,2462,2491,2501`
**Step 2: Run test gate for JetStreamFileStoreTests + concurrency classes**
**Step 3: Run mandatory scans + build gate**
**Step 4: Mark tests verified in <=15 ID chunks**
**Step 5: Mark Group 2 features verified after gate passes**
### Task 7: Group 2 Checkpoint
**Files:**
- Modify: `porting.db`
**Step 1: Full build + three class test gates**
**Step 2: Commit checkpoint**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/JetStream \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog \
porting.db
git commit -m "feat(batch11): complete group2 filestore state and utility paths"
```
### Task 8: Group 3 Feature Implementation (6 features)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/FileStore.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/MessageBlock.cs`
**Step 1: Implement timestamp/init semaphore helpers**
Feature IDs: `1200, 1235`
**Step 2: Implement consumer header/state decode**
Feature IDs: `1239, 1248`
**Step 3: Implement atomic file-write helpers**
Feature IDs: `1261, 1262`
**Step 4: Run mandatory protocol and mark features complete (chunked <=15)**
### Task 9: Group 3 Test Porting and Verification
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamFileStoreTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests1.Impltests.cs`
**Step 1: Port Group 3-related tests (wave C)**
Primary IDs:
`385,386,387,393,395,396,402,440,2427,2447`
**Step 2: Run class gates and verify all wave C tests pass**
**Step 3: Run mandatory scans + build gate**
**Step 4: Mark tests verified (<=15 IDs/chunk)**
**Step 5: Mark Group 3 features verified (<=15 IDs/chunk)**
### Task 10: Batch 11 Final Closure
**Files:**
- Modify: `porting.db`
- Generate: `reports/current.md`
**Step 1: Final full verification**
Run:
```bash
dotnet build dotnet/
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ImplBacklog.JetStreamFileStoreTests" \
--verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ImplBacklog.ConcurrencyTests1" \
--verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ImplBacklog.ConcurrencyTests2" \
--verbosity normal
```
Expected: all relevant tests pass, zero failures.
**Step 2: Final stub audit (src + tests)**
Run mandatory stub scans again; expected zero matches.
**Step 3: Complete batch**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch complete 11 --db porting.db
```
Expected: success with no unverified blockers.
**Step 4: Regenerate report and final commit**
```bash
./reports/generate-report.sh
git add dotnet/src/ZB.MOM.NatsNet.Server/JetStream \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog \
porting.db reports/
git commit -m "feat(batch11): complete filestore init feature and test port"
```
---
## Execution Notes
- Always run status updates in explicit chunks and record matching evidence.
- If any test is infra-blocked, keep deferred with reason; never replace with placeholder assertions.
- If unexpected unrelated workspace changes appear during execution, stop and ask for direction before proceeding.

View File

@@ -0,0 +1,116 @@
# Batch 12 FileStore Recovery Design
**Date:** 2026-02-27
**Batch:** 12 (`FileStore Recovery`)
**Dependency:** Batch 11 (`FileStore Init`)
**Scope:** 8 features + 0 tests mapped to `golang/nats-server/server/filestore.go`
---
## 1. Context and Constraints
- PortTracker reports Batch 12 as `pending`, dependent on Batch 11, with 8 deferred features and no batch-owned tests.
- Batch 12 methods are all in the FileStore recovery path:
- `warn` (ID 987)
- `debug` (ID 988)
- `recoverFullState` (ID 991)
- `recoverTTLState` (ID 992)
- `recoverMsgSchedulingState` (ID 993)
- `cleanupOldMeta` (ID 995)
- `recoverMsgs` (ID 996)
- `expireMsgsOnRecover` (ID 997)
- Current .NET `JetStreamFileStore` is still a mostly delegated shell; these recovery methods are not implemented yet.
- Even though Batch 12 has 0 mapped tests, reverse dependencies exist for at least:
- test `#519` (`RecoverFullState` corruption detection)
- test `#545` (`RecoverTTLState` corrupt block resilience)
- Planning-only session: produce design and implementation plan documents; do not implement feature code.
## 2. Success Criteria
- Implement all 8 Batch 12 features with behavior parity to Go intent for recovery flows in `filestore.go`.
- Introduce recovery logic without stubs/placeholders in either production or related test files.
- Verify each feature using a strict per-feature loop: Go-source read, C# implementation, build, related tests.
- Use evidence-backed PortTracker status updates in small chunks and keep dependency/order integrity.
## 3. Brainstormed Approach Options
### Option A (Recommended): Two vertical recovery groups with strict gates
Group methods by lifecycle stage, then run full build/test/status gates between groups.
- Pros: low integration risk, easy isolation of regressions, aligns with mandatory checkpointing.
- Cons: more build/test cycles.
### Option B: Implement all 8 methods in one pass, verify once at the end
- Pros: fastest coding flow initially.
- Cons: high blast radius if behavior diverges; poor auditability for status updates.
### Option C: Logging + cleanup first, then all recovery methods together
- Pros: simple early wins on low-complexity methods.
- Cons: still delays hardest-state validation and can hide ordering bugs until late.
### Recommendation
Use **Option A**. Recovery behavior is stateful and failure-prone; bounded groups plus hard gates are the safest path.
## 4. Proposed Design
### 4.1 Feature Groups (max ~20 each)
- **Group 1 (5 features):** `987, 988, 991, 992, 993`
- Logging wrappers and persisted state/TTL/scheduling recovery.
- **Group 2 (3 features):** `995, 996, 997`
- Metadata cleanup, message block recovery sweep, startup age-expiration pass.
### 4.2 Primary Code Boundaries
- Production:
- `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/FileStore.cs` (main implementation surface)
- `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/MessageBlock.cs` (state and helper interactions used by recovery logic)
- `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/FileStoreTypes.cs` (supporting types/constants as needed)
- Related tests and verification targets:
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamFileStoreTests.cs`
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamFileStoreTests.Impltests.cs`
### 4.3 Recovery Flow to Port
1. **Observability wrappers** (`warn`, `debug`): no-op when server/logger is absent; prefix context consistently.
2. **Full state recovery** (`recoverFullState`):
- Read state file, validate minimum length and checksum, decrypt when configured.
- Decode stream + subject + block state, detect corruption/outdated state, and force rebuild fallback conditions.
3. **TTL and scheduling recovery** (`recoverTTLState`, `recoverMsgSchedulingState`):
- Decode persisted wheels/schedules.
- If stale, linear scan from recovered sequence through message blocks to rebuild runtime structures.
4. **Metadata cleanup** (`cleanupOldMeta`): remove stale `.idx`/`.fss` files in message directory.
5. **Message recovery** (`recoverMsgs`): enumerate blocks in order, recover each block, reconcile stream first/last/msgs/bytes, prune orphan key files.
6. **Startup age expiration** (`expireMsgsOnRecover`): expire max-age-out messages/blocks safely, preserve tombstone behavior, and recompute top-level state.
### 4.4 Error Handling and Safety
- Corrupt/full-state mismatch must fail closed and trigger rebuild path instead of continuing with partial state.
- IO permissions/corruption conditions should be surfaced with actionable context (not swallowed).
- Lock ordering must remain consistent with existing FileStore concurrency patterns to avoid recovery-time deadlocks.
### 4.5 Verification Design (Feature + Related Tests)
- Feature verification is not allowed on build-only evidence.
- Each feature needs:
- Go-source intent review
- build pass
- related test execution pass (or explicit deferred reason if test infra is unavailable)
- If related tests for a feature are still deferred/unported, feature can be moved to `complete` but not `verified` unless equivalent evidence exists and is documented.
## 5. Risks and Mitigations
- **Risk:** recovery logic complexity leads to placeholder shortcuts.
**Mitigation:** mandatory stub scans after every group for both source and tests.
- **Risk:** subtle state-accounting regressions (first/last/msgs/bytes).
**Mitigation:** group gates require targeted tests plus JetStream store regression filters.
- **Risk:** aggressive status updates without proof.
**Mitigation:** cap status update chunks to 15 IDs and require command-output evidence per chunk.
## 6. Design Outcome
Batch 12 should be executed as two recovery-focused feature groups with strict evidence gates between them. This design preserves dependency discipline, prevents stub creep, and keeps feature status updates auditable against build/test outputs.

View File

@@ -0,0 +1,360 @@
# Batch 12 FileStore Recovery Implementation Plan
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
**Goal:** Implement and verify all Batch 12 FileStore Recovery features from `server/filestore.go` with no stub logic and evidence-backed status transitions.
**Architecture:** Execute Batch 12 in two vertical feature groups (5 + 3). Implement recovery logic directly in `JetStream/FileStore.cs`, touching supporting JetStream types only when required. After each group, run strict stub scans, build, and related test gates before any status updates.
**Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`)
**Design doc:** `docs/plans/2026-02-27-batch-12-filestore-recovery-design.md`
---
I'm using `writeplan` to create the implementation plan.
## Batch Inputs
- Batch: `12` (`FileStore Recovery`)
- Depends on: Batch `11`
- Features: `8`
- Tests: `0` (batch-owned), with known related reverse dependencies:
- test `#519` (`FileStoreRecoverFullStateDetectCorruptState_ShouldSucceed`)
- test `#545` (`FileStoreNoPanicOnRecoverTTLWithCorruptBlocks_ShouldSucceed`)
- Go source scope: `golang/nats-server/server/filestore.go` lines ~1708-2580
Feature groups (max ~20 features each):
- **Group 1 (5):** `987,988,991,992,993`
- **Group 2 (3):** `995,996,997`
---
## MANDATORY VERIFICATION PROTOCOL
> **NON-NEGOTIABLE:** Every task and every status update in this plan must follow this protocol.
### Per-Feature Verification Loop (REQUIRED for every feature ID)
For each feature ID in the active group:
1. Read feature mapping and exact Go intent:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- feature show <FEATURE_ID> --db porting.db
```
2. Read corresponding Go method span in `golang/nats-server/server/filestore.go`.
3. Implement minimal real C# behavior (no placeholders).
4. Build immediately:
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
5. Run related tests for the touched behavior (see Test Gate below).
6. Record evidence (command + summary output) before adding the ID to status-update candidates.
### Stub Detection Check (REQUIRED after each feature group)
Run all scans below. Any match is a hard blocker:
```bash
# Production placeholder detection
rg -n "NotImplementedException|TODO|PLACEHOLDER" \
dotnet/src/ZB.MOM.NatsNet.Server/JetStream -g '*.cs'
# Empty method bodies (FileStore recovery surface)
rg -n "^\s*(public|private|internal|protected).*(Warn|Debug|RecoverFullState|RecoverTTLState|RecoverMsgSchedulingState|CleanupOldMeta|RecoverMsgs|ExpireMsgsOnRecover)\s*\([^)]*\)\s*\{\s*\}$" \
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/FileStore.cs
# Test placeholders in directly related classes
rg -n "NotImplementedException|Assert\.True\(true\)|Assert\.Pass|// TODO|// PLACEHOLDER" \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamFileStoreTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamFileStoreTests.Impltests.cs
```
### Build Gate (REQUIRED after each feature group)
This must pass before status updates and before moving to next group:
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
### Test Gate (REQUIRED before marking features `verified`)
All related tests must pass. Run at least:
```bash
# Existing JetStream FileStore coverage
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.JetStream.JetStreamFileStoreTests" \
--verbosity normal
# Backlog coverage for FileStore implementation
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ImplBacklog.JetStreamFileStoreTests" \
--verbosity normal
# Feature-linked methods from reverse dependencies
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~FileStoreRecoverFullStateDetectCorruptState|FullyQualifiedName~FileStoreNoPanicOnRecoverTTLWithCorruptBlocks" \
--verbosity normal
```
Gate rule:
- If related tests run and pass, eligible for `verified`.
- If related tests are unavailable/not yet implemented (0 discovered), feature may be set to `complete` only, with explicit note explaining why `verified` is deferred.
### Status Update Protocol (REQUIRED)
- Use max **15 IDs** per `feature batch-update` call.
- Required status progression: `deferred -> stub -> complete -> verified`.
- Do not mark `verified` without evidence from Build Gate + Test Gate.
- Keep an evidence log folder (example: `/tmp/batch12-evidence/`) with per-group command outputs.
Examples:
```bash
# Move active group to stub before editing
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "987,988,991,992,993" --set-status stub --db porting.db --execute
# Move group to complete after successful implementation + build/test evidence
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "987,988,991,992,993" --set-status complete --db porting.db --execute
```
### Checkpoint Protocol Between Tasks (REQUIRED)
At each group boundary:
1. Full build:
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
2. Full unit test sweep (not just filtered):
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
3. Commit checkpoint before next task:
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/JetStream \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests \
porting.db
git commit -m "feat(batch12): complete group <N> filestore recovery"
```
---
## ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)
### Forbidden Patterns
The following are forbidden in Batch 12 feature or related test code:
- `throw new NotImplementedException(...)`
- Empty recovery method bodies (`{ }`)
- `// TODO` or `// PLACEHOLDER` in implemented recovery methods
- Fake test pass patterns (`Assert.True(true)`, `Assert.Pass()`, assertion-only smoke checks that do not exercise production behavior)
- Swallowing corruption/IO errors silently instead of preserving Go intent
### Hard Limits
- Max ~20 features per implementation group (fixed here as 5 and 3)
- Max 15 feature IDs per status-update command
- One feature group per verification/update cycle
- Zero stub-scan matches before `complete` or `verified` transitions
- No `verified` transition without explicit Build Gate + Test Gate evidence
### If You Get Stuck (MANDATORY)
1. Do **not** add a stub, placeholder, or no-op workaround.
2. Mark only blocked feature IDs as `deferred` with a concrete reason.
3. Continue with remaining IDs in the group.
4. Record blocker details in evidence log and PortTracker override reason.
Example:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature update <ID> --status deferred --db porting.db \
--override "blocked: <specific technical reason>"
```
---
### Task 1: Batch Start and Group 1 Staging
**Files:**
- Modify: `porting.db`
- Create: `/tmp/batch12-evidence/` (evidence logs)
**Step 1: Confirm current batch state**
Run:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 12 --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch list --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db
```
Expected: Batch 12 pending, dependency 11, 8 features, 0 tests.
**Step 2: Start batch**
Run:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch start 12 --db porting.db
```
Expected: batch marked in-progress.
**Step 3: Stage Group 1 IDs to `stub`**
Run:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "987,988,991,992,993" --set-status stub --db porting.db --execute
```
Expected: only Group 1 IDs set to `stub`.
**Step 4: Commit checkpoint**
```bash
git add porting.db
git commit -m "chore(batch12): start batch and stage group1 recovery ids"
```
### Task 2: Implement Group 1 Recovery Features (5 IDs)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/FileStore.cs`
- Modify (if needed): `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/MessageBlock.cs`
- Modify (if needed): `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/FileStoreTypes.cs`
**Feature IDs:** `987,988,991,992,993`
**Step 1: Implement logging helpers**
- ID `987` (`Warn`) and ID `988` (`Debug`) with FileStore-context prefixing and no-op behavior when logger/server is unavailable.
**Step 2: Implement full-state recovery**
- ID `991` (`RecoverFullState`): stream state file load, length/checksum validation, decode, stale/corrupt fallback signaling.
**Step 3: Implement TTL and schedule recovery**
- ID `992` (`RecoverTTLState`)
- ID `993` (`RecoverMsgSchedulingState`)
- Include stale-state linear scan fallback over recovered message blocks.
**Step 4: Run mandatory verification protocol for Group 1**
- Per-feature loop for all 5 IDs.
- Stub Detection Check.
- Build Gate.
- Test Gate.
**Step 5: Status updates (chunk <=15)**
- Set Group 1 IDs to `complete` after successful evidence.
- Promote to `verified` only if Test Gate evidence is sufficient for each feature.
### Task 3: Group 1 Checkpoint
**Files:**
- Modify: `porting.db`
**Step 1: Run Checkpoint Protocol**
- Full build + full unit tests.
**Step 2: Commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/JetStream \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests \
porting.db
git commit -m "feat(batch12): complete group1 filestore recovery"
```
### Task 4: Implement Group 2 Recovery Features (3 IDs)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/FileStore.cs`
- Modify (if needed): `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/MessageBlock.cs`
- Modify (if needed): `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/FileStoreTypes.cs`
**Feature IDs:** `995,996,997`
**Step 1: Implement metadata cleanup**
- ID `995` (`CleanupOldMeta`): remove stale metadata file types in message directory safely.
**Step 2: Implement ordered message block recovery**
- ID `996` (`RecoverMsgs`): enumerate/sort blocks, recover block state, reconcile stream accounting, prune orphan keys.
**Step 3: Implement startup expiration path**
- ID `997` (`ExpireMsgsOnRecover`): max-age pass at startup, per-subject updates, empty-block cleanup, tombstone continuity.
**Step 4: Run mandatory verification protocol for Group 2**
- Per-feature loop for all 3 IDs.
- Stub Detection Check.
- Build Gate.
- Test Gate.
**Step 5: Status updates (chunk <=15)**
- Set Group 2 IDs to `complete`, then `verified` only when test evidence criteria are met.
### Task 5: Group 2 Checkpoint and Batch Closure
**Files:**
- Modify: `porting.db`
- Generate: `reports/current.md`
**Step 1: Final gates**
Run:
```bash
/usr/local/share/dotnet/dotnet build dotnet/
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ --verbosity normal
```
Expected: zero failures in executed suites.
**Step 2: Verify batch status and unblocked work**
Run:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 12 --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- dependency ready --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db
```
**Step 3: Complete batch**
Run:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch complete 12 --db porting.db
```
Expected: completion succeeds only if all items meet allowed terminal states.
**Step 4: Generate report + commit**
```bash
./reports/generate-report.sh
git add dotnet/src/ZB.MOM.NatsNet.Server/JetStream \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests \
porting.db reports/
git commit -m "feat(batch12): complete filestore recovery"
```
---
Plan complete and saved to `docs/plans/2026-02-27-batch-12-filestore-recovery-plan.md`. Two execution options:
**1. Subagent-Driven (this session)** - I dispatch fresh subagent per task, review between tasks, fast iteration
**2. Parallel Session (separate)** - Open new session with `executeplan`, batch execution with checkpoints
Which approach?

View File

@@ -0,0 +1,126 @@
# Batch 16 (Client Core first half) Design
**Date:** 2026-02-27
**Scope:** Design only for Batch 16 (`server/client.go` first-half mappings): 30 features and 1 tracked test.
## Context Snapshot
Batch metadata from PortTracker:
- Batch ID: `16`
- Name: `Client Core (first half)`
- Dependencies: batches `2`, `3`, `4`
- Go file: `server/client.go`
- Features: `30` (all currently `deferred`)
- Tests: `1` (`#2859`, currently `deferred`)
Tracker status snapshot (`report summary`):
- Features: `1271 verified`, `2377 deferred`, `24 n_a`, `1 stub`
- Unit tests: `430 verified`, `2640 deferred`, `187 n_a`
- Overall progress: `1924 / 6942 (27.7%)`
## Problem Statement
Batch 16 mixes:
1. Small deterministic helpers (flag operations, type helpers, permission shaping).
2. Mid-complexity outbound pipeline methods (buffer collapse, flush, timeout handling, close-path state).
3. Parser-adjacent methods (`processPub`, `processHeaderPub`, `splitArg`, `parseSub`, `processSub*`) that touch broader server/account state.
The key risk is fake progress via placeholder ports. The design must enforce behavior-faithful implementation with explicit defer decisions where later infrastructure is truly required.
## Working Set Breakdown
### Group A (19 features, deterministic/helper-focused, <= line 1300)
`387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 402, 411, 420, 421, 422, 423, 424`
### Group B (11 features, outbound + parser-facing, lines 1608-3046)
`429, 430, 431, 432, 456, 471, 472, 473, 474, 475, 476`
### Batch Test
- `2859` `TestRouteSlowConsumerRecover` -> mapped .NET target:
`RouteHandlerTests.RouteSlowConsumerRecover_ShouldSucceed`
## Current Code Findings
1. `ClientConnection.cs` already contains partial equivalents for some methods, but several mapped method names do not exist yet (`PublicPermissions`, `MergeDenyPermissions`, `FlushOutbound`, `HandleWriteTimeout`, `QueueOutbound`, `ProcessSubEx`, etc.).
2. `WriteTimeoutPolicy` is currently an enum; Go-style `String()` behavior exists via extension method (`ToVarzString`) rather than mapped name.
3. `clientFlag.*` / `readCacheFlag.*` features are mapped to `ClientFlags` and `ReadCacheFlags`, but those are enums in C#, which cannot host instance methods.
4. `ProtocolParser` already has high-quality static `ProcessPub` and `ProcessHeaderPub` parsing logic; Batch 16 should reuse this rather than duplicate parser internals.
5. Tracked test `#2859` depends on multiple non-Batch-16 features; at least one dependency (`#1207 fileStore.stop`) is still deferred, so test completion may remain blocked even after Batch 16 feature work.
## Approaches
### Approach A: Full in-place parity in one sweep
Port all 30 features directly in `ClientConnection.cs` before any status updates.
- Pros: Single execution wave, fewer intermediate commits.
- Cons: High regression risk, weak isolation, high chance of hidden stubs.
### Approach B: Thin wrappers + audit overrides
Add minimal wrappers, use status overrides for non-matching mappings, defer heavy logic.
- Pros: Fastest movement.
- Cons: Creates weak verification evidence and makes future maintenance harder.
### Approach C (Recommended): Two-group staged parity with explicit mapping hygiene and hard verification gates
Implement deterministic helper features first (Group A), then outbound/parser features (Group B), with strict per-feature evidence and chunked status updates. Treat test `#2859` as execute-or-defer based on runtime feasibility.
- Pros: Lowers risk, produces auditable evidence, prevents stub creep.
- Cons: Slightly more upfront discipline and tracker hygiene.
## Recommended Design
### 1. Surface and Mapping Alignment
- Keep `ClientConnection` as primary implementation location for Batch 16 methods.
- Reuse existing helper types where already idiomatic (`NbPool`, `ProtocolParser`) through `ClientConnection` wrappers.
- For enum-based mapped methods (`ClientFlags`, `ReadCacheFlags`, `WriteTimeoutPolicy.String`), perform explicit mapping reconciliation to method-hosting helper types when needed, rather than distorting core domain types.
### 2. Behavior Porting Strategy
- Port from Go source line ranges per feature ID, preserving observable behavior, lock expectations, and error paths.
- Prefer deterministic, unit-testable slices:
- Flag transitions and deny-permission merge semantics.
- Outbound queue accounting and timeout-close behavior.
- Pub/sub argument parsing wrappers around existing parser primitives.
### 3. Verification-First Execution Model
- Per-feature red/green loop with focused tests and build checks.
- Group-level gates (stub scan, full build, related test classes) before status promotions.
- Max 15 IDs per status update command, with evidence for every chunk.
### 4. Tracked Test Strategy (`#2859`)
- Attempt realistic port only if feature dependencies and harness capabilities are sufficient.
- If infrastructure dependencies remain unmet, keep `deferred` with explicit blocker reason; no placeholder pass test is allowed.
## Error Handling and Deferral Rules
1. If a feature requires unavailable infrastructure (for example full route/file-store interactions), mark it `deferred` with a concrete reason.
2. Never introduce fake success patterns (`NotImplementedException` stubs, TODO-only placeholders, trivial always-pass assertions).
3. Do not promote `verified` unless build and related tests are green with captured evidence.
## Success Criteria
1. Batch 16 features are either:
- behavior-faithfully implemented and verified, or
- explicitly deferred with specific blocker notes.
2. No stub patterns remain in touched source/test files.
3. Status transitions are evidence-backed and chunked (`<=15` IDs/update).
4. Batch test `#2859` is either genuinely verified or explicitly deferred with documented dependency blockers.
## Non-Goals
1. No execution in this design document.
2. No unrelated refactors outside Batch 16 scope.
3. No forced integration test completion through fragile or fake harnesses.

View File

@@ -0,0 +1,453 @@
# Batch 16 (Client Core first half) Implementation Plan
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
**Goal:** Implement and verify Batch 16 (`server/client.go` first half) feature parity in two controlled feature groups (30 features total) and resolve the single tracked test (`#2859`) with real evidence or explicit deferral.
**Architecture:** Use a staged porting model: deterministic helper features first, then outbound/parser-state features. Keep `ClientConnection` as the primary host, reuse existing parser logic in `ProtocolParser`, and enforce strict per-feature verification loops to prevent stub regressions. Batch status updates happen only after group-level build and test gates.
**Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`)
**Design doc:** `docs/plans/2026-02-27-batch-16-client-core-first-half-design.md`
---
## Batch 16 Working Set
- **Total features:** `30`
- **Total tests:** `1`
- **Dependencies:** batches `2`, `3`, `4`
- **Go source:** `golang/nats-server/server/client.go`
Feature groups (max size <= 20):
- **Group A (19 features):** `387,388,389,390,391,392,393,394,395,396,397,398,402,411,420,421,422,423,424`
- **Group B (11 features):** `429,430,431,432,456,471,472,473,474,475,476`
Tracked test:
- **Test:** `2859` (`RouteHandlerTests.RouteSlowConsumerRecover_ShouldSucceed`)
---
## MANDATORY VERIFICATION PROTOCOL
> **NON-NEGOTIABLE:** Every feature and test in this batch must pass these gates before any `verified` status update.
### What Counts as Real Verification
A feature/test is eligible for `verified` only when all conditions hold:
1. Mapped .NET method exists and contains real logic (no placeholder body).
2. Behavior matches Go intent for the mapped function/test scenario.
3. Focused related tests run and pass with non-zero executed tests.
4. Stub scan returns zero hits in touched files.
5. Group build and group test gates are green.
### Per-Feature Verification Loop (REQUIRED for each feature ID)
1. Read exact Go source range from tracker:
```bash
dotnet run --project tools/NatsNet.PortTracker -- feature show <feature-id> --db porting.db
```
2. Open Go function in `golang/nats-server/server/client.go` and capture intended behavior.
3. Write or update C# implementation in mapped .NET target file.
4. Run build and related focused tests:
```bash
dotnet build dotnet/
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~<RelatedClassOrMethod>" --verbosity normal
```
5. Verify summary reports at least one executed test and `Failed: 0`.
6. Add feature ID to group-ready evidence list only after green build + green focused tests.
### Stub Detection Check (REQUIRED after each feature group and test task)
Run on all touched source and test files:
```bash
grep -R -n -E "NotImplementedException|TODO|PLACEHOLDER" \
dotnet/src/ZB.MOM.NatsNet.Server \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests
grep -R -n -E "^[[:space:]]*(public|internal|private|protected)[^;]*\\)\\s*\\{[[:space:]]*\\}$" \
dotnet/src/ZB.MOM.NatsNet.Server \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests
```
Any hit in touched files blocks status promotion until fixed or explicitly deferred with reason.
### Build Gate (REQUIRED after each feature group)
```bash
dotnet build dotnet/
```
Required: `0` errors.
### Test Gate (REQUIRED before marking features `verified`)
Run all related classes for the group:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientConnectionStubFeaturesTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ProtocolParserTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~RouteHandlerTests" --verbosity normal
```
Required: all relevant runs show `Failed: 0` and non-zero executed tests for newly touched scenarios.
### Status Update Protocol (REQUIRED)
1. **Max 15 IDs per `feature batch-update` or `test batch-update` command.**
2. Status flow per item: `deferred/not_started -> stub -> complete -> verified` (or `deferred` with reason).
3. Every update chunk must have evidence:
- go source reviewed
- build output
- related test output
- stub scan output
4. If audit disagrees and logic is proven, use explicit override reason.
Template commands:
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<<=15 ids>" --set-status stub --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<<=15 ids>" --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<<=15 ids>" --set-status verified --db porting.db --execute
```
### Checkpoint Protocol Between Tasks (REQUIRED)
After each major task group (Group A, Group B, test task):
1. Full build:
```bash
dotnet build dotnet/
```
2. Full unit tests:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
3. Confirm no new regressions.
4. Commit before moving to next task.
---
## ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)
### Forbidden Patterns
The following are forbidden in touched feature/test code:
- `throw new NotImplementedException()`
- `TODO` / `PLACEHOLDER` markers left in executable paths
- Empty method bodies used as placeholders (`{ }`)
- Trivial always-pass assertions (`Assert.True(true)`, equivalent fake checks)
- Wrapper methods that ignore Go behavior and return dummy values
### Hard Limits
- Max `15` IDs per status-update command.
- Max `1` feature group promoted per verification cycle.
- Mandatory stub scan + build gate + test gate before each promotion.
- Mandatory checkpoint commit between task groups.
- No "temporary stubs" allowed for batch completion.
### If You Get Stuck
Do **not** stub. Use this exact path:
1. Keep/return blocked feature or test to `deferred`.
2. Add explicit reason via override (specific missing infra/dependency).
3. Commit only proven items.
4. Continue with next unblocked item in current group.
Examples:
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status deferred --db porting.db --override "blocked: requires <specific dependency>"
dotnet run --project tools/NatsNet.PortTracker -- \
test update <id> --status deferred --db porting.db --override "blocked: requires <specific runtime/infra>"
```
---
### Task 1: Preflight, Dependency Gate, and Mapping Hygiene
**Files:**
- Modify (if needed): `porting.db` mappings for impossible enum-hosted method targets
- Inspect: `golang/nats-server/server/client.go`
**Step 1: Confirm batch readiness**
```bash
dotnet run --project tools/NatsNet.PortTracker -- batch ready --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- batch show 16 --db porting.db
```
Expected: Batch 16 appears as ready. If not ready, stop execution and keep this batch pending.
**Step 2: Start batch**
```bash
dotnet run --project tools/NatsNet.PortTracker -- batch start 16 --db porting.db
```
**Step 3: Reconcile method-host mappings where class type cannot host methods**
Focus on enum-hosted mappings (`ClientFlags`, `ReadCacheFlags`, `WriteTimeoutPolicy.String`).
Use `feature map` / `feature batch-map` only if required for auditable method hosting.
**Step 4: Commit mapping-only changes (if any)**
```bash
git add porting.db
git commit -m "chore(batch16): reconcile feature mappings for verifiable method hosts"
```
---
### Task 2: Group A Features (19) - Helpers, Flags, Permissions, Expiration
**Feature IDs:** `387,388,389,390,391,392,393,394,395,396,397,398,402,411,420,421,422,423,424`
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ServerOptionTypes.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientTests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs`
**Step 1: Mark Group A as `stub` in chunks <= 15**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "387,388,389,390,391,392,393,394,395,396,397,398,402,411,420" --set-status stub --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "421,422,423,424" --set-status stub --db porting.db --execute
```
**Step 2: Write failing tests for Group A behavior**
- Add/extend tests for:
- internal-client classification
- flag set/clear/isSet/setIfNotSet semantics
- timeout policy string value
- nb pool get/put behavior
- TLS state accessor and kind accessor
- public/deny permissions merge behavior
- expiration and deny-filter loading behavior
**Step 3: Run focused tests and confirm failures**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientConnectionStubFeaturesTests" --verbosity normal
```
**Step 4: Implement minimal behavior-faithful Group A production code**
Apply per-feature loop from protocol section for all 19 IDs.
**Step 5: Run focused tests until green**
Re-run the two related classes and verify `Failed: 0`.
**Step 6: Mandatory stub scan + build gate**
Run required stub and build commands from protocol section.
**Step 7: Promote Group A statuses with evidence (<=15 IDs/chunk)**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "387,388,389,390,391,392,393,394,395,396,397,398,402,411,420" --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "421,422,423,424" --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "387,388,389,390,391,392,393,394,395,396,397,398,402,411,420" --set-status verified --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "421,422,423,424" --set-status verified --db porting.db --execute
```
**Step 8: Checkpoint protocol + commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs \
dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs \
dotnet/src/ZB.MOM.NatsNet.Server/ServerOptionTypes.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs \
porting.db
git commit -m "feat(batch16): port client helper and permission core features"
```
---
### Task 3: Group B Features (11) - Outbound Pipeline and Pub/Sub Parsing
**Feature IDs:** `429,430,431,432,456,471,472,473,474,475,476`
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProtocolParser.cs` (only if parser helper exposure is needed)
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Protocol/ProtocolParserTests.cs`
**Step 1: Mark Group B as `stub`**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "429,430,431,432,456,471,472,473,474,475,476" --set-status stub --db porting.db --execute
```
**Step 2: Write failing tests for outbound and parser wrappers**
- Outbound queue growth/chunking and pending-byte accounting.
- Flush behavior under partial writes and timeout error paths.
- `HandleWriteTimeout` and `MarkConnAsClosed` reason-specific transitions.
- `ProcessHeaderPub`, `ProcessPub`, `SplitArg`, `ParseSub`, `ProcessSub`, `ProcessSubEx` behavior.
**Step 3: Run focused tests and confirm failures**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientConnectionStubFeaturesTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ProtocolParserTests" --verbosity normal
```
**Step 4: Implement Group B features with per-feature verification loop**
Port from Go source ranges, reusing `ProtocolParser` behavior where valid.
**Step 5: Re-run focused tests until green**
Same two test runs, verify `Failed: 0`.
**Step 6: Stub scan + build gate + related test gate**
Run protocol-mandated commands.
**Step 7: Promote Group B statuses**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "429,430,431,432,456,471,472,473,474,475,476" --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "429,430,431,432,456,471,472,473,474,475,476" --set-status verified --db porting.db --execute
```
**Step 8: Checkpoint protocol + commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs \
dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProtocolParser.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Protocol/ProtocolParserTests.cs \
porting.db
git commit -m "feat(batch16): port outbound and parser-facing client core features"
```
---
### Task 4: Batch Test #2859 (`TestRouteSlowConsumerRecover`)
**Test ID:** `2859`
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs`
- Inspect dependencies via `porting.db` before status decision
**Step 1: Mark test as `stub` only if implementation attempt begins**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
test update 2859 --status stub --db porting.db
```
**Step 2: Port Go test intent to C# and run focused test**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~RouteHandlerTests.RouteSlowConsumerRecover_ShouldSucceed" \
--verbosity normal
```
**Step 3: Decision gate**
- If test is green with real assertions and real behavior coverage:
- set `complete`, then `verified`.
- If blocked by unmet runtime/dependency constraints:
- set back to `deferred` with explicit reason (for example unresolved dependency `#1207` or missing route/network harness behavior).
**Step 4: Apply status update with evidence**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
test update 2859 --status verified --db porting.db
```
or
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
test update 2859 --status deferred --db porting.db --override "blocked: <specific reason>"
```
**Step 5: Checkpoint protocol + commit**
```bash
git add dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs porting.db
git commit -m "test(batch16): resolve route slow-consumer recover status with evidence"
```
---
### Task 5: Batch 16 Final Verification and Closure
**Files:**
- Modify: `porting.db`
- Generate: `reports/current.md` (via report generation script)
**Step 1: Run full verification**
```bash
dotnet build dotnet/
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
dotnet run --project tools/NatsNet.PortTracker -- batch show 16 --db porting.db
```
**Step 2: Ensure all Batch 16 items are `verified`, `complete`, or explicit `deferred` with reason**
If anything is still `stub`, stop and resolve before completion.
**Step 3: Complete batch**
```bash
dotnet run --project tools/NatsNet.PortTracker -- batch complete 16 --db porting.db
```
**Step 4: Refresh report and final commit**
```bash
./reports/generate-report.sh
git add porting.db reports/current.md reports/
git commit -m "chore(batch16): complete client core first-half verification cycle"
```

View File

@@ -0,0 +1,130 @@
# Batch 17 (Client Core second half) Design
**Date:** 2026-02-27
**Scope:** Design only for Batch 17 (`server/client.go` second-half mappings): 60 features and 9 tracked tests.
## Context Snapshot
Batch metadata from PortTracker:
- Batch ID: `17`
- Name: `Client Core (second half)`
- Dependency: batch `16`
- Go file: `server/client.go`
- Features: `60` (all currently `deferred`)
- Tests: `9` (all currently `deferred`)
Tracker status snapshot (`report summary`):
- Features: `1271 verified`, `2377 deferred`, `24 n_a`, `1 stub`
- Unit tests: `430 verified`, `2640 deferred`, `187 n_a`
- Overall progress: `1924 / 6942 (27.7%)`
## Problem Statement
Batch 17 is the heaviest `client.go` section: subscription/unsubscribe paths, delivery fanout, inbound message processing, header mutation helpers, service import plumbing, ping/stale timers, account-reload handling, reconnect/TLS handshakes, and rate-limited logging.
The main execution risk is false progress through placeholder methods/tests because:
1. `ClientConnection.cs` still contains explicit second-half stubs/comments.
2. Batch 17 tests include JetStream/FileStore/MemStore/Server tests with many non-Batch-17 deferred dependencies.
3. Existing backlog tests include shallow placeholder patterns that can pass without validating behavior.
## Working Set Breakdown
Feature groups (max ~20 each):
- **Group A (20):** `477-496`
Subscription shadowing, unsubscribe flow, message header composition, `deliverMsg`, permission pruning, publish allow checks, reply classifiers.
- **Group B (20):** `497-515,520`
Inbound message pipeline, reply/service import handling, header get/set/remove helpers, `processServiceImport`, route-target accumulation, `processMsgResults`, ping timer processing.
- **Group C (20):** `521,522,534,535,537,540,541,542,543,544,545,546,547,548,553,565,566,567,568,569`
Ping interval adjustments, stale watcher, reload/reconnect/account cache helpers, `ClientInfo.serviceAccount`, client info enrichment, TLS handshake trio, allowed connection type conversion, rate-limit logging, first ping timer.
Tracked tests:
- File store scheduling/delete-marker cluster: `528,545,552,553,568,598`
- Memory store scheduling/delete-marker cluster: `2053,2057`
- Server rate-limit logging: `2901`
## Approaches
### Approach A: Monolithic `ClientConnection.cs` port wave
Implement all 60 features in the existing file, then patch tests.
- Pros: fewer files and simpler search path.
- Cons: high merge risk, hard reviewability, harder to isolate regressions.
### Approach B (Recommended): Three vertical feature groups with partial-class split and hard gates
Split second-half methods into focused `ClientConnection` partial files and execute three 20-feature groups with explicit build/test/stub gates between groups.
- Pros: reviewable increments, clearer ownership per concern, strong regression isolation.
- Cons: slightly more up-front file organization.
### Approach C: Wrapper-heavy defer-first strategy
Add shallow wrappers for signatures, defer behavior-heavy methods and most tests.
- Pros: fastest status movement.
- Cons: poor parity confidence, audit churn, high risk of anti-stub violations.
## Recommended Design
### 1. Architecture
- Keep `ClientConnection` as the primary host, but split second-half methods into dedicated partial files:
- `ClientConnection.SubscriptionsAndDelivery.cs` (Group A)
- `ClientConnection.InboundAndHeaders.cs` (Group B)
- `ClientConnection.LifecycleAndTls.cs` (Group C)
- Keep `ClientInfo.serviceAccount` logic in `ClientTypes.cs` (or a focused companion file if needed).
- Preserve existing first-half behavior in `ClientConnection.cs`; do not refactor unrelated code.
### 2. Data/Control Flow
- Inbound path: `processInboundMsg` -> subject mapping/service-import path -> `processMsgResults`.
- Delivery path: `deliverMsg` + header generation + permission/reply tracking.
- Timer/lifecycle path: ping interval decisions, stale detection, reconnect, and handshake transitions.
- Logging path: rate-limited wrappers funneling through existing server/client logging facilities.
### 3. Error Handling and Deferral
- Port behavior from Go line ranges, including close reasons and permission-deny behavior.
- If a feature/test requires missing infra (outside Batch 17 dependencies), keep it `deferred` with explicit reason and evidence.
- Never use placeholder success paths to force status transitions.
### 4. Test Strategy
- Add/expand focused client-core tests first (to make feature verification real).
- Attempt the 9 tracked tests only after dependency precheck and feature readiness.
- For blocked tests, keep `deferred` with concrete blocker notes rather than adding shallow assertions.
### 5. Verification Contract
- Per-feature read/implement/build/test loop.
- Group-level stub scan, build gate, and related test gate before status promotion.
- Chunked status updates (`<=15` IDs/update) with captured evidence.
## Risks and Mitigations
1. **Large method complexity (`deliverMsg`, `processMsgResults`)**
Mitigation: isolate in Group A/B, add targeted tests before and after each port.
2. **Cross-module test blockers (FileStore/MemStore/Server dependencies)**
Mitigation: dependency precheck before each test; defer with explicit reason when blocked.
3. **Stub regression under schedule pressure**
Mitigation: mandatory anti-stub scans and hard status gates.
## Success Criteria
1. All 60 Batch 17 features are either behavior-verified or explicitly deferred with reason.
2. All 9 Batch 17 tests are either genuinely verified or explicitly deferred with reason.
3. No forbidden stub patterns remain in touched feature/test files.
4. Status updates are evidence-backed, chunked, and auditable.
## Non-Goals
1. No implementation in this design document.
2. No unrelated refactors outside Batch 17 scope.
3. No synthetic "pass" tests or placeholder feature logic to satisfy tracker states.

View File

@@ -0,0 +1,498 @@
# Batch 17 (Client Core second half) Implementation Plan
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
**Goal:** Implement and verify Batch 17 (`server/client.go` second half) across 60 client-core features and 9 tracked tests using evidence-backed, anti-stub execution gates.
**Architecture:** Execute in three vertical feature groups (20 each) aligned to `client.go` functional seams: subscription/delivery, inbound/header/service import, and lifecycle/account/TLS/logging. Implement in `ClientConnection` partial files plus `ClientTypes` for `ClientInfo` behavior, then run tracked-test attempts with explicit dependency checks and defer reasoning where infra is still missing.
**Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`)
**Design doc:** `docs/plans/2026-02-27-batch-17-client-core-second-half-design.md`
---
I'm using `writeplan` to create the implementation plan.
## Batch Inputs
- Batch: `17` (`Client Core second half`)
- Depends on: `16`
- Features: `60`
- Tests: `9`
- Go source focus: `golang/nats-server/server/client.go` (line ~3057+)
Feature groups (max ~20 each):
- **Group A (20):** `477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496`
- **Group B (20):** `497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,520`
- **Group C (20):** `521,522,534,535,537,540,541,542,543,544,545,546,547,548,553,565,566,567,568,569`
Tracked tests:
- `528,545,552,553,568,598,2053,2057,2901`
---
## MANDATORY VERIFICATION PROTOCOL
> **NON-NEGOTIABLE:** Every feature/test update in this batch must pass this protocol before status promotion.
### Per-Feature Verification Loop (REQUIRED for every feature ID)
1. Read tracker mapping and Go location:
```bash
dotnet run --project tools/NatsNet.PortTracker -- feature show <FEATURE_ID> --db porting.db
```
2. Read the exact Go function in `golang/nats-server/server/client.go`.
3. Write minimal behavior-faithful C# implementation in mapped .NET file.
4. Build:
```bash
dotnet build dotnet/
```
5. Run focused related tests (class/method filter):
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~<RelatedClassOrMethod>" --verbosity normal
```
6. Confirm non-zero executed tests and `Failed: 0`.
7. Add feature ID to verified-candidate list only after green build + green related tests.
### Per-Test Verification Loop (REQUIRED for every tracked test ID)
1. Read mapping + dependencies:
```bash
dotnet run --project tools/NatsNet.PortTracker -- test show <TEST_ID> --db porting.db
```
2. Read referenced Go test in `server/filestore_test.go`, `server/memstore_test.go`, or `server/server_test.go`.
3. Port behavior intent with real Arrange/Act/Assert.
4. Run the single mapped test:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~<MappedClass>.<MappedMethod>" --verbosity normal
```
5. Only mark `verified` when test executes and passes (`Passed: 1`, `Failed: 0`).
### Stub Detection Check (REQUIRED after every feature group and test task)
Run stub scans before any `complete`/`verified` updates:
```bash
# Feature code stubs/placeholders
grep -R -n -E "NotImplementedException|TODO|PLACEHOLDER" \
dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection*.cs \
dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs
# Empty method bodies in touched feature files
grep -R -n -E "^[[:space:]]*(public|internal|private|protected)[^{;]*\\)[[:space:]]*\\{[[:space:]]*\\}$" \
dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection*.cs \
dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs
# Test stubs/placeholders
grep -R -n -E "NotImplementedException|Assert\\.True\\(true\\)|Assert\\.Pass|ShouldBe\\(true\\);|// TODO|// PLACEHOLDER" \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests
```
Any new hit in touched files blocks promotion until fixed or deferred with explicit reason.
### Build Gate (REQUIRED after each feature group)
After every feature group task:
```bash
dotnet build dotnet/
```
Required: `0` build errors.
### Test Gate (REQUIRED before marking features `verified`)
Before any feature IDs move to `verified`, run and pass all related suites:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientConnectionStubFeaturesTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ProtocolParserTests" --verbosity normal
```
If a group touches rate-limit logging or mapped server behaviors, also run:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~NatsServerTests" --verbosity normal
```
Required: `Failed: 0` and non-zero executed tests for changed scenarios.
### Status Update Protocol (REQUIRED, evidence-backed)
1. Maximum **15 IDs per `feature batch-update` / `test batch-update` call**.
2. Allowed flow:
- Features: `deferred -> stub -> complete -> verified` (or `deferred` with reason)
- Tests: `deferred -> stub -> verified` (or `deferred` with reason)
3. Evidence required for each update chunk:
- Go source review completed
- Build output green
- Related test output green
- Stub scan clean
4. If audit disagrees, use explicit override reason.
### Checkpoint Protocol Between Tasks (REQUIRED)
After each major task (Group A, Group B, Group C, tests):
1. Full build:
```bash
dotnet build dotnet/
```
2. Full unit test run:
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
3. Confirm no new regressions.
4. Commit checkpoint before starting the next task.
---
## ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)
### Forbidden Patterns
Do not introduce or keep these in Batch 17 feature/test code:
- `throw new NotImplementedException(...)`
- `// TODO` or `// PLACEHOLDER` in executable Batch 17 paths
- Empty method body placeholders (`{ }`)
- Trivial pass tests (`Assert.True(true)`, `Assert.Pass()`, literal-only assertions)
- Constant return placeholders for behavior-heavy methods (for example always `true`/`false` without Go-equivalent logic)
- Fake wrappers that ignore inputs and bypass Go behavior intent
### Hard Limits
- Max ~20 feature IDs per implementation task group (fixed at 20/20/20)
- Max 15 IDs per status-update command
- No status promotion without stub scan + build gate + test gate evidence
- No cross-group promotion; complete verification for one group before starting next
- Mandatory checkpoint commit between task groups
### If You Get Stuck
1. Stop work on the blocked item immediately.
2. Do **not** stub or fake-pass.
3. Set item back to `deferred` with exact blocker reason:
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature update <ID> --status deferred --db porting.db \
--override "blocked: <specific dependency/infra>"
```
or
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
test update <ID> --status deferred --db porting.db \
--override "blocked: <specific dependency/infra>"
```
4. Continue with the next unblocked ID in the same task.
---
### Task 1: Preflight and Batch Start
**Files:**
- Modify: `porting.db`
**Step 1: Confirm dependency readiness**
```bash
dotnet run --project tools/NatsNet.PortTracker -- batch show 17 --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- batch ready --db porting.db
```
Expected: Batch 17 is ready (Batch 16 complete).
**Step 2: Start batch**
```bash
dotnet run --project tools/NatsNet.PortTracker -- batch start 17 --db porting.db
```
**Step 3: Stage Group A to `stub` (<=15 IDs per command)**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "477,478,479,480,481,482,483,484,485,486,487,488,489,490,491" \
--set-status stub --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "492,493,494,495,496" \
--set-status stub --db porting.db --execute
```
**Step 4: Commit preflight**
```bash
git add porting.db
git commit -m "chore(batch17): start batch and stage group-a ids"
```
### Task 2: Group A Features (20) - Subscriptions, Delivery, Pub/Reply Permissions
**Feature IDs:** `477-496`
**Files:**
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.SubscriptionsAndDelivery.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientTests.cs`
**Step 1: Write/extend failing tests for Group A behavior**
Focus on:
- shadow subscription additions
- unsubscribe + deny-sub checks
- route/leaf header generation
- delivery/pruning/reply tracking behavior
- publish allow checks and reply classifiers
**Step 2: Run focused tests and confirm failures**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientConnectionStubFeaturesTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientTests" --verbosity normal
```
**Step 3: Implement Group A methods using per-feature verification loop**
**Step 4: Run mandatory stub detection + build gate + test gate**
Use protocol commands above.
**Step 5: Promote Group A feature statuses**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "477,478,479,480,481,482,483,484,485,486,487,488,489,490,491" \
--set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "492,493,494,495,496" \
--set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "477,478,479,480,481,482,483,484,485,486,487,488,489,490,491" \
--set-status verified --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "492,493,494,495,496" \
--set-status verified --db porting.db --execute
```
**Step 6: Checkpoint protocol + commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.SubscriptionsAndDelivery.cs \
dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientTests.cs \
porting.db
git commit -m "feat(batch17): port subscription and delivery client core features"
```
### Task 3: Group B Features (20) - Inbound Pipeline, Headers, Service Imports, Msg Results
**Feature IDs:** `497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,520`
**Files:**
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.InboundAndHeaders.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Protocol/ProtocolParserTests.cs`
**Step 1: Write/extend failing tests for Group B behavior**
Focus on:
- inbound client message processing and mapped subject selection
- gateway reply map + response service import setup
- header remove/set/get/slice helpers
- `processServiceImport`, route-target updates, and `processMsgResults`
- ping timer behavior (`processPingTimer`)
**Step 2: Run focused tests and confirm failures**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientConnectionStubFeaturesTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ProtocolParserTests" --verbosity normal
```
**Step 3: Implement Group B methods using per-feature verification loop**
**Step 4: Run mandatory stub detection + build gate + test gate**
**Step 5: Promote Group B feature statuses (<=15 IDs/chunk)**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "497,498,499,500,501,502,503,504,505,506,507,508,509,510,511" \
--set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "512,513,514,515,520" \
--set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "497,498,499,500,501,502,503,504,505,506,507,508,509,510,511" \
--set-status verified --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "512,513,514,515,520" \
--set-status verified --db porting.db --execute
```
**Step 6: Checkpoint protocol + commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.InboundAndHeaders.cs \
dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Protocol/ProtocolParserTests.cs \
porting.db
git commit -m "feat(batch17): port inbound, header, and service-import client features"
```
### Task 4: Group C Features (20) - Lifecycle, Account/Info, TLS, Rate-Limit Logging
**Feature IDs:** `521,522,534,535,537,540,541,542,543,544,545,546,547,548,553,565,566,567,568,569`
**Files:**
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.LifecycleAndTls.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.Impltests.cs`
**Step 1: Write/extend failing tests for Group C behavior**
Focus on:
- ping interval adjust + stale watcher + first ping timer
- account cache helpers and reload/reconnect paths
- client info account/service account enrichment
- TLS handshake wrappers and failure behavior
- rate-limited error/warn/debug logging wrappers
**Step 2: Run focused tests and confirm failures**
```bash
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientConnectionStubFeaturesTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~NatsServerTests" --verbosity normal
```
**Step 3: Implement Group C methods using per-feature verification loop**
**Step 4: Run mandatory stub detection + build gate + test gate**
**Step 5: Promote Group C feature statuses (<=15 IDs/chunk)**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "521,522,534,535,537,540,541,542,543,544,545,546,547,548,553" \
--set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "565,566,567,568,569" \
--set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "521,522,534,535,537,540,541,542,543,544,545,546,547,548,553" \
--set-status verified --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "565,566,567,568,569" \
--set-status verified --db porting.db --execute
```
**Step 6: Checkpoint protocol + commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.LifecycleAndTls.cs \
dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs \
dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.Impltests.cs \
porting.db
git commit -m "feat(batch17): port lifecycle, tls, and rate-limited logging features"
```
### Task 5: Tracked Tests (9) - Implement or Explicitly Defer With Reason
**Test IDs:** `528,545,552,553,568,598,2053,2057,2901`
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamFileStoreTests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamMemoryStoreTests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.Impltests.cs`
- Modify: `porting.db`
**Step 1: Stage all 9 tests to `stub` (single chunk <=15)**
```bash
dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "528,545,552,553,568,598,2053,2057,2901" \
--set-status stub --db porting.db --execute
```
**Step 2: For each test, run dependency readiness check**
If dependencies remain deferred outside Batch 17, do not force-port; defer with explicit blocker.
**Step 3: Port only implementable tests using per-test verification loop**
Run each mapped test individually and confirm it executes/passes.
**Step 4: Stub scan + build + targeted JetStream/Server test gates**
```bash
dotnet build dotnet/
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~JetStreamFileStoreTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~JetStreamMemoryStoreTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~NatsServerTests" --verbosity normal
```
**Step 5: Update statuses**
- Verified chunk (only those with direct pass evidence, <=15 IDs).
- Deferred updates for blocked tests with explicit `--override` reason.
**Step 6: Checkpoint protocol + commit**
```bash
git add dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamFileStoreTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamMemoryStoreTests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.Impltests.cs \
porting.db
git commit -m "test(batch17): resolve tracked tests with pass evidence or explicit deferrals"
```
### Task 6: Final Batch 17 Verification and Closure
**Files:**
- Modify: `porting.db`
- Generate: `reports/current.md`
**Step 1: Full verification sweep**
```bash
dotnet build dotnet/
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
dotnet run --project tools/NatsNet.PortTracker -- batch show 17 --db porting.db
```
**Step 2: Enforce no remaining Batch 17 stubs**
No Batch 17 feature/test should remain in `stub` status.
**Step 3: Complete batch**
```bash
dotnet run --project tools/NatsNet.PortTracker -- batch complete 17 --db porting.db
```
**Step 4: Update report + final commit**
```bash
./reports/generate-report.sh
git add porting.db reports/current.md reports/
git commit -m "chore(batch17): complete client core second-half verification cycle"
```

View File

@@ -0,0 +1,117 @@
# Batch 6 (Opts Package-Level Functions) Design
**Date:** 2026-02-27
**Scope:** Design for Batch 6 planning only (67 features, 18 tests). No implementation in this document.
## Context Snapshot
From `batch show 6`, `batch list`, and `report summary`:
- Batch ID: `6`
- Name: `Opts package-level functions`
- Features: `67` (all currently `deferred`)
- Tests: `18` (all currently `deferred`)
- Dependency: `Batch 4 (Logging)`
- Go file: `server/opts.go`
- Primary .NET target: `ServerOptions` methods in `dotnet/src/ZB.MOM.NatsNet.Server/`
- Environment note: use `/usr/local/share/dotnet/dotnet` because `dotnet` is not on PATH
Current .NET baseline findings:
- `ServerOptions.Methods.cs` contains foundational option/clone/merge/default logic.
- Batch 6 mappings target many missing parse/configuration methods (TLS, auth, account parsing, websocket, MQTT, `ConfigureOptions`).
- Batch 6 mapped tests currently sit in ImplBacklog placeholder-style methods and are not evidence-quality verification.
## Problem Statement
Batch 6 is a broad parser and option-bootstrap surface from `server/opts.go`. The risk is not only missing methods, but fake progress from placeholder tests or status updates without behavior evidence. The design must prioritize strict verification loops and explicit deferred handling instead of stubbing.
## Constraints and Success Criteria
Constraints:
- Follow `docs/standards/dotnet-standards.md` (.NET 10, nullable, xUnit 3 + Shouldly + NSubstitute).
- Keep feature work in groups of at most ~20 IDs.
- Preserve dependency order: Batch 6 starts only after Batch 4 is complete.
- No fake tests, empty method bodies, or `NotImplementedException` placeholders.
Success criteria:
- All unblocked Batch 6 features are implemented with Go parity and verified evidence.
- Mapped Batch 6 tests are either real/passing or explicitly deferred with concrete runtime/dependency reason.
- Status transitions in `porting.db` are evidence-backed and chunked (max 15 IDs per batch update).
## Approaches
### Approach A: Single-file monolithic port in `ServerOptions.Methods.cs`
- Pros: minimal file churn.
- Cons: very high merge/review risk, hard to validate per-feature intent, encourages large unverifiable commits.
### Approach B: Test-first by converting the 18 mapped tests only, then fill features
- Pros: quick visible test movement.
- Cons: mapped tests are mostly integration-heavy and do not cover all 67 feature methods; risks brittle or deferred-only progress.
### Approach C (Recommended): Capability-sliced feature waves + mapped-test waves with strict gates
- Pros: manageable slices (<=20 features), deterministic checkpoints, clear evidence trail for status updates.
- Cons: more orchestration overhead.
## Recommended Design
### 1. Feature Wave Decomposition (<=20 each)
Implement Batch 6 in four feature groups, ordered by `opts.go` flow:
- **F1 Core config entry + cluster/gateway parse (16):** `2502,2504,2505,2506,2507,2508,2509,2515,2516,2517,2519,2520,2521,2522,2523,2524`
- **F2 JetStream + leaf/gateway/TLS helpers (14):** `2525,2526,2527,2528,2529,2530,2531,2532,2533,2534,2535,2536,2537,2538`
- **F3 Account + authorization parsing (17):** `2539,2540,2541,2542,2543,2544,2545,2546,2547,2548,2549,2550,2551,2552,2553,2554,2555`
- **F4 Permission/TLS/websocket/MQTT/CLI configure (20):** `2556,2557,2558,2559,2560,2561,2562,2563,2564,2565,2566,2567,2568,2569,2570,2571,2572,2573,2574,2580`
### 2. Test Wave Decomposition (18 tests)
- **T1 Options + reload + resolver wiring (4):** `1832,2586,2587,2766`
- **T2 Leaf/route/websocket TLS behavior (8):** `1918,1919,1929,1942,1950,2817,2821,3109`
- **T3 Monitoring + MQTT TLS behavior (6):** `2108,2113,2114,2115,2166,2178`
### 3. File Strategy
- Primary implementation target: `dotnet/src/ZB.MOM.NatsNet.Server/ServerOptions.Methods.cs`.
- If method volume becomes unreviewable, split into additional `ServerOptions.*.cs` partials by area (auth/accounts, TLS, transport parsing) without changing external API names.
- Primary mapped test targets:
`dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ServerOptionsTests.Impltests.cs`,
`ConfigReloaderTests.Impltests.cs`, `JwtProcessorTests.Impltests.cs`,
`LeafNodeHandlerTests.Impltests.cs`, `RouteHandlerTests.Impltests.cs`,
`WebSocketHandlerTests.Impltests.cs`, `MonitoringHandlerTests.Impltests.cs`,
`MqttHandlerTests.Impltests.cs`.
### 4. Verification and Status Model
- Use per-feature loops (Go read -> C# implement -> build -> related tests).
- Use per-test loops for each mapped test ID.
- Promote statuses only after evidence gates; otherwise keep `deferred` with explicit reason.
- Prefer `complete` for implemented-but-not-fully-proven items; only set `verified` after all related tests pass.
### 5. Explicit Stuck Handling
- If blocked by missing infra/dependency (for example parser/token/runtime server harness), do not stub.
- Keep item `deferred` and attach concrete blocker note via `--override`.
## Risks and Mitigations
1. **Stub creep in ImplBacklog tests**
Mitigation: mandatory grep checks for placeholders and trivial assertion patterns.
2. **Large parser surface causes regressions**
Mitigation: four bounded feature groups + build gate after each group.
3. **Premature `verified` status updates**
Mitigation: max 15 IDs per update and required evidence log per chunk.
4. **Dependency/infra blockers**
Mitigation: formal deferred-with-reason protocol; continue with unblocked IDs.
## Approval-to-Plan Transition
This design selects **Approach C** and is ready for implementation planning with mandatory verification protocol and anti-stub guardrails for both features and tests.

View File

@@ -0,0 +1,594 @@
# Batch 6 (Opts Package-Level Functions) Implementation Plan
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
**Goal:** Implement and verify Batch 6 option/package-level behavior from `server/opts.go` (`67` features, `18` tests) with evidence-backed status updates and zero stubs.
**Architecture:** Execute four bounded feature groups (<=20 features each) in source-order, then port mapped tests in three class-based groups. Every feature follows a strict read-Go -> implement-C# -> build -> related-test loop. Promote to `verified` only when related mapped tests are green; otherwise keep `complete`/`deferred` with explicit evidence.
**Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`)
**Design doc:** `docs/plans/2026-02-27-batch-6-opts-package-level-functions-design.md`
---
## Batch 6 Working Set
Batch facts:
- Batch ID: `6`
- Features: `67`
- Tests: `18`
- Depends on: `Batch 4`
- Go file: `golang/nats-server/server/opts.go`
Feature groups (max <=20):
- **F1 Core config entry + cluster/gateway parse (16):** `2502,2504,2505,2506,2507,2508,2509,2515,2516,2517,2519,2520,2521,2522,2523,2524`
- **F2 JetStream + leaf/gateway/TLS helpers (14):** `2525,2526,2527,2528,2529,2530,2531,2532,2533,2534,2535,2536,2537,2538`
- **F3 Account + authorization parsing (17):** `2539,2540,2541,2542,2543,2544,2545,2546,2547,2548,2549,2550,2551,2552,2553,2554,2555`
- **F4 Permission/TLS/websocket/MQTT/CLI configure (20):** `2556,2557,2558,2559,2560,2561,2562,2563,2564,2565,2566,2567,2568,2569,2570,2571,2572,2573,2574,2580`
Test groups:
- **T1 Options/reload/JWT wiring (4):** `1832,2586,2587,2766`
- **T2 Leaf/route/websocket TLS behavior (8):** `1918,1919,1929,1942,1950,2817,2821,3109`
- **T3 Monitoring + MQTT TLS behavior (6):** `2108,2113,2114,2115,2166,2178`
Environment note:
- `dotnet` is not on PATH in this workspace; use `/usr/local/share/dotnet/dotnet`.
---
## MANDATORY VERIFICATION PROTOCOL
> **NON-NEGOTIABLE:** Every feature and test in Batch 6 must follow this protocol.
### Per-Feature Verification Loop (REQUIRED for each feature ID)
1. Read tracker mapping and Go location:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- feature show <id> --db porting.db
```
2. Read exact Go implementation lines in `golang/nats-server/server/opts.go`.
3. Write only that feature behavior in .NET (`ServerOptions`).
4. Build immediately:
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
5. Run related tests (focused filter for impacted classes).
6. Add feature ID to verified-candidate list only after build + related tests pass.
### Per-Test Verification Loop (REQUIRED for each test ID)
1. Read mapping + Go test lines:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- test show <id> --db porting.db
```
2. Replace placeholder ImplBacklog body with real Arrange/Act/Assert behavior.
3. Run exact test method and confirm discovery + pass:
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~<ExactTestMethod>" --verbosity normal
```
4. Add test ID to verified-candidate list only after focused pass.
### Stub Detection Check (REQUIRED after every feature group and test group)
Run all three checks before any status promotion:
```bash
# 1) Stub markers in touched source/test files
grep -n -E "(NotImplementedException|TODO|PLACEHOLDER|throw new Exception\\(\"not implemented\"\\))" \
dotnet/src/ZB.MOM.NatsNet.Server/ServerOptions*.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/*.cs
# 2) Empty method bodies in changed C# files
for f in $(git diff --name-only -- '*.cs'); do
grep -n -E "^\s*(public|private|internal|protected).*\)\s*\{\s*\}\s*$" "$f";
done
# 3) Placeholder impl-backlog anti-patterns
grep -n -E "\".*ShouldSucceed\"\.ShouldContain\(\"Should\"\)|goFile\.ShouldStartWith\(\"server/\"\)" \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ServerOptionsTests.Impltests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConfigReloaderTests.Impltests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JwtProcessorTests.Impltests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/LeafNodeHandlerTests.Impltests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/WebSocketHandlerTests.Impltests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MonitoringHandlerTests.Impltests.cs \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MqttHandlerTests.Impltests.cs
```
Any match blocks promotion until fixed or explicitly deferred with reason.
### Build Gate (REQUIRED after each feature group)
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
Rule: zero build errors required after each group.
### Test Gate (REQUIRED before marking features `verified`)
For the active feature group, all related mapped test classes must pass with `Failed: 0`.
Suggested related test commands:
```bash
# F1
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ServerOptionsTests|FullyQualifiedName~ConfigReloaderTests" --verbosity normal
# F2
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~LeafNodeHandlerTests|FullyQualifiedName~RouteHandlerTests|FullyQualifiedName~WebSocketHandlerTests|FullyQualifiedName~MonitoringHandlerTests|FullyQualifiedName~MqttHandlerTests|FullyQualifiedName~JwtProcessorTests" --verbosity normal
# F3
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~JwtProcessorTests|FullyQualifiedName~ServerOptionsTests|FullyQualifiedName~ConfigReloaderTests" --verbosity normal
# F4
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ServerOptionsTests|FullyQualifiedName~ConfigReloaderTests|FullyQualifiedName~JwtProcessorTests|FullyQualifiedName~LeafNodeHandlerTests|FullyQualifiedName~RouteHandlerTests|FullyQualifiedName~WebSocketHandlerTests|FullyQualifiedName~MonitoringHandlerTests|FullyQualifiedName~MqttHandlerTests" --verbosity normal
```
Rule: do not set features to `verified` until their related mapped tests pass.
### Status Update Protocol (REQUIRED)
- Max `15` IDs per `feature batch-update` or `test batch-update`.
- Required progression:
- Features: `deferred/not_started -> stub -> complete -> verified`
- Tests: `deferred/not_started -> stub -> verified` (or remain `deferred` with reason)
- Evidence required per update chunk:
- feature/test IDs covered
- build gate output
- related test output
- stub scan output
Command templates:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<max15ids>" --set-status <stub|complete|verified> --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "<max15ids>" --set-status <stub|verified> --db porting.db --execute
```
If audit disagrees:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status <status> --db porting.db --override "verification evidence: <reason>"
```
### Checkpoint Protocol Between Tasks (REQUIRED)
After each task, before starting the next:
1. Full build:
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
2. Full unit tests:
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
3. Record pass/fail totals.
4. Commit completed slice (including `porting.db`) before continuing.
---
## ANTI-STUB GUARDRAILS
### Forbidden Patterns
Do not introduce any of the following in Batch 6 scope:
- `throw new NotImplementedException(...)`
- Empty feature bodies (`{ }`) for mapped methods
- `TODO`, `PLACEHOLDER`, or fake "implement later" comments
- Placeholder test checks like method-name string assertions (`"...ShouldSucceed".ShouldContain("Should")`)
- Tests that only validate `goFile` string literals or constants unrelated to behavior
- Trivial pass assertions (`Assert.True(true)`, `Assert.Pass()`)
### Hard Limits
- Max `20` features per implementation group
- Max `15` IDs per status update command
- Max `1` feature-group promotion cycle at a time (no cross-group bulk verify)
- Mandatory build gate after every feature group
- Mandatory related test gate before `verified` feature status
- Mandatory checkpoint commit between tasks
### If You Get Stuck (REQUIRED BEHAVIOR)
Do not stub and do not fake-pass:
1. Keep blocked item as `deferred`.
2. Record concrete reason with `--override`.
3. Move to 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 dependency/runtime reason>"
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test update <id> --status deferred --db porting.db \
--override "blocked: <specific dependency/runtime reason>"
```
---
### Task 1: Preflight and Batch Start
**Files:**
- Modify: `porting.db`
**Step 1: Verify dependency batch is complete before starting Batch 6**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 4 --db porting.db
```
**Step 2: Start Batch 6**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch start 6 --db porting.db
```
**Step 3: Mark F1 as `stub` in <=15 ID chunks**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2502,2504,2505,2506,2507,2508,2509,2515,2516,2517,2519,2520,2521,2522,2523" \
--set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2524" --set-status stub --db porting.db --execute
```
**Step 4: Checkpoint protocol + commit**
---
### Task 2: Implement Feature Group F1 (Core Config + Cluster/Gateway Parse)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ServerOptions.Methods.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ServerOptions.cs` (if new fields/properties are required for parity)
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ServerOptionsTests.Impltests.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConfigReloaderTests.Impltests.cs`
- Modify: `porting.db`
**Step 1: For each F1 feature ID, run the Per-Feature Verification Loop**
**Step 2: Run F1 stub checks + build gate + F1 related test gate**
**Step 3: Promote F1 to `complete` in <=15 chunks**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2502,2504,2505,2506,2507,2508,2509,2515,2516,2517,2519,2520,2521,2522,2523" \
--set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2524" --set-status complete --db porting.db --execute
```
**Step 4: Promote F1 to `verified` only if F1 related tests are all passing**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2502,2504,2505,2506,2507,2508,2509,2515,2516,2517,2519,2520,2521,2522,2523" \
--set-status verified --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2524" --set-status verified --db porting.db --execute
```
**Step 5: Checkpoint protocol + commit**
---
### Task 3: Implement Feature Group F2 (JetStream + Leaf/TLS Helpers)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ServerOptions.Methods.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ServerOptionTypes.cs` (if parity requires shape updates)
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/LeafNodeHandlerTests.Impltests.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/WebSocketHandlerTests.Impltests.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MonitoringHandlerTests.Impltests.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MqttHandlerTests.Impltests.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JwtProcessorTests.Impltests.cs`
- Modify: `porting.db`
**Step 1: Mark F2 as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2525,2526,2527,2528,2529,2530,2531,2532,2533,2534,2535,2536,2537,2538" \
--set-status stub --db porting.db --execute
```
**Step 2: Execute Per-Feature Verification Loop for each F2 ID**
**Step 3: Run F2 stub checks + build gate + F2 related test gate**
**Step 4: Promote F2 to `complete` then `verified`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2525,2526,2527,2528,2529,2530,2531,2532,2533,2534,2535,2536,2537,2538" \
--set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2525,2526,2527,2528,2529,2530,2531,2532,2533,2534,2535,2536,2537,2538" \
--set-status verified --db porting.db --execute
```
**Step 5: Checkpoint protocol + commit**
---
### Task 4: Implement Feature Group F3 (Accounts + Authorization Parsing)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ServerOptions.Methods.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Accounts/Account.cs` (only if Batch 6 parser parity requires adjustments)
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JwtProcessorTests.Impltests.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ServerOptionsTests.Impltests.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConfigReloaderTests.Impltests.cs`
- Modify: `porting.db`
**Step 1: Mark F3 as `stub` (<=15 chunks)**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2539,2540,2541,2542,2543,2544,2545,2546,2547,2548,2549,2550,2551,2552,2553" \
--set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2554,2555" --set-status stub --db porting.db --execute
```
**Step 2: Execute Per-Feature Verification Loop for each F3 ID**
**Step 3: Run F3 stub checks + build gate + F3 related test gate**
**Step 4: Promote F3 to `complete` (<=15 chunks)**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2539,2540,2541,2542,2543,2544,2545,2546,2547,2548,2549,2550,2551,2552,2553" \
--set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2554,2555" --set-status complete --db porting.db --execute
```
**Step 5: Promote F3 to `verified` only if related tests are passing**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2539,2540,2541,2542,2543,2544,2545,2546,2547,2548,2549,2550,2551,2552,2553" \
--set-status verified --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2554,2555" --set-status verified --db porting.db --execute
```
**Step 6: Checkpoint protocol + commit**
---
### Task 5: Implement Feature Group F4 (Permissions/TLS/Websocket/MQTT/ConfigureOptions)
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ServerOptions.Methods.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ServerOptionTypes.cs` (if needed for TLS/permission parity)
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ServerOptionsTests.Impltests.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConfigReloaderTests.Impltests.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JwtProcessorTests.Impltests.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/LeafNodeHandlerTests.Impltests.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/WebSocketHandlerTests.Impltests.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MonitoringHandlerTests.Impltests.cs`
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MqttHandlerTests.Impltests.cs`
- Modify: `porting.db`
**Step 1: Mark F4 as `stub` (<=15 chunks)**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2556,2557,2558,2559,2560,2561,2562,2563,2564,2565,2566,2567,2568,2569,2570" \
--set-status stub --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2571,2572,2573,2574,2580" --set-status stub --db porting.db --execute
```
**Step 2: Execute Per-Feature Verification Loop for each F4 ID**
**Step 3: Run F4 stub checks + build gate + F4 related test gate**
**Step 4: Promote F4 to `complete` (<=15 chunks)**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2556,2557,2558,2559,2560,2561,2562,2563,2564,2565,2566,2567,2568,2569,2570" \
--set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2571,2572,2573,2574,2580" --set-status complete --db porting.db --execute
```
**Step 5: Promote F4 to `verified` only when related tests pass**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2556,2557,2558,2559,2560,2561,2562,2563,2564,2565,2566,2567,2568,2569,2570" \
--set-status verified --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2571,2572,2573,2574,2580" --set-status verified --db porting.db --execute
```
**Step 6: Checkpoint protocol + commit**
---
### Task 6: Port Test Group T1 (Options/Reload/JWT Wiring)
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ServerOptionsTests.Impltests.cs`
- 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: `porting.db`
**Step 1: Mark T1 tests as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "1832,2586,2587,2766" --set-status stub --db porting.db --execute
```
**Step 2: Execute Per-Test Verification Loop for each T1 ID**
**Step 3: Run class-level T1 gate**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ServerOptionsTests|FullyQualifiedName~ConfigReloaderTests|FullyQualifiedName~JwtProcessorTests" --verbosity normal
```
**Step 4: Promote T1 tests to `verified`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "1832,2586,2587,2766" --set-status verified --db porting.db --execute
```
**Step 5: Checkpoint protocol + commit**
---
### Task 7: Port Test Group T2 (Leaf/Route/WebSocket TLS Behavior)
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/LeafNodeHandlerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/WebSocketHandlerTests.Impltests.cs`
- Modify: `porting.db`
**Step 1: Mark T2 tests as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "1918,1919,1929,1942,1950,2817,2821,3109" --set-status stub --db porting.db --execute
```
**Step 2: Execute Per-Test Verification Loop for each T2 ID**
**Step 3: Run class-level T2 gate**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~LeafNodeHandlerTests|FullyQualifiedName~RouteHandlerTests|FullyQualifiedName~WebSocketHandlerTests" --verbosity normal
```
**Step 4: Promote T2 tests to `verified`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "1918,1919,1929,1942,1950,2817,2821,3109" --set-status verified --db porting.db --execute
```
**Step 5: Checkpoint protocol + commit**
---
### Task 8: Port Test Group T3 (Monitoring + MQTT TLS Behavior)
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MonitoringHandlerTests.Impltests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MqttHandlerTests.Impltests.cs`
- Modify: `porting.db`
**Step 1: Mark T3 tests as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "2108,2113,2114,2115,2166,2178" --set-status stub --db porting.db --execute
```
**Step 2: Execute Per-Test Verification Loop for each T3 ID**
**Step 3: Run class-level T3 gate**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~MonitoringHandlerTests|FullyQualifiedName~MqttHandlerTests" --verbosity normal
```
**Step 4: Promote T3 tests to `verified`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "2108,2113,2114,2115,2166,2178" --set-status verified --db porting.db --execute
```
**Step 5: Checkpoint protocol + commit**
---
### Task 9: Final Batch 6 Closure
**Files:**
- Modify: `porting.db`
- Optional: `reports/current.md`
**Step 1: Final verification gates**
```bash
/usr/local/share/dotnet/dotnet build dotnet/
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ --verbosity normal
```
**Step 2: Validate batch state and complete**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 6 --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch complete 6 --db porting.db
```
**Step 3: Generate report**
```bash
./reports/generate-report.sh
```
**Step 4: Final checkpoint commit**
```bash
git add dotnet/src/ZB.MOM.NatsNet.Server dotnet/tests/ZB.MOM.NatsNet.Server.Tests porting.db reports/current.md
git commit -m "feat(batch6): implement opts package-level functions and mapped tests with verification evidence"
```

View File

@@ -0,0 +1,141 @@
# Batch 7 (Opts Class Methods + Reload) Design
**Date:** 2026-02-27
**Scope:** Design for Batch 7 planning only (`25` features, `63` tests). No implementation in this document.
## Context Snapshot
From:
- `/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 -- batch list --db porting.db`
- `/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db`
Current state:
- Batch ID: `7`
- Name: `Opts class methods + Reload`
- Status: `pending`
- Dependency: `Batch 6`
- Go files: `server/opts.go`, `server/reload.go`
- Features: `25` (all currently `deferred`)
- Tests: `63` (all currently `deferred`)
- Environment note: use `/usr/local/share/dotnet/dotnet` (`dotnet` is not on PATH in this workspace)
Relevant .NET baseline:
- `dotnet/src/ZB.MOM.NatsNet.Server/Config/ReloadOptions.cs` contains many reload option types and a `ConfigReloader` stub, but the core reload pipeline methods mapped in Batch 7 are mostly missing.
- `dotnet/src/ZB.MOM.NatsNet.Server/Config/ServerOptionsConfiguration.cs` contains static config-string/file processing, while Batch 7 maps receiver-style `ServerOptions` methods from `opts.go`.
- Batch 7 mapped tests are concentrated in ImplBacklog classes and many are placeholder-style and not verification-grade.
- `LeafNodeProxyTests` mapped by Batch 7 does not currently exist in `ImplBacklog` and must be created.
## Problem Statement
Batch 7 is where config parsing receiver methods and live reload orchestration converge. The highest risk is not compilation failure; it is false progress from stubs, shallow tests, or status promotion without evidence. Design must enforce strict feature+test verification and allow explicit deferment for runtime-blocked behaviors instead of fake implementations.
## Constraints and Success Criteria
Constraints:
- Follow `docs/standards/dotnet-standards.md` (.NET 10, nullable, xUnit 3 + Shouldly + NSubstitute).
- Respect dependency ordering: Batch 7 starts only after Batch 6 is complete.
- Feature implementation groups must stay <= ~20 features each.
- No placeholder source or placeholder tests can be promoted.
Success criteria:
- Batch 7 features are implemented with Go parity (or explicitly deferred with concrete reasons).
- Batch 7 tests are real behavioral tests or explicitly deferred with blocker notes.
- `porting.db` status changes are evidence-backed and chunked (`<=15` IDs per update call).
## Candidate Approaches
### Approach A: Keep all work in existing monolith files
- Implementation primarily in `ReloadOptions.cs` and `ServerOptions.Methods.cs` without introducing new partial files.
- Pros: minimal file churn.
- Cons: very high review complexity and high risk of accidental stub retention in a large file.
### Approach B: Split by responsibility with focused partials (Recommended)
- Keep option-type classes in `ReloadOptions.cs`, but move core reload orchestration to `NatsServer.Reload.cs` and helper diff/order logic to dedicated config helper partial(s).
- Keep `ServerOptions` receiver-style config entry methods in `ServerOptions.Methods.cs` (or a dedicated `ServerOptions.ConfigProcessing.cs` partial).
- Pros: direct mapping to Go responsibilities, easier per-feature verification and smaller commits.
- Cons: introduces new files and requires careful type visibility.
### Approach C: Implement only thin wrappers and defer most reload internals
- Adds minimal API surface and marks most runtime methods deferred.
- Pros: fastest short-term movement.
- Cons: fails batch intent, leaves large reload behavior gap, and pushes risk forward.
## Recommended Design
Use **Approach B**.
### 1. Feature Decomposition (<=20 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 and server application path (11):** `2869,2872,2874,2876,2879,2880,2881,2882,2883,2884,2885`
### 2. Test Decomposition
- **T1 Options parsing surface (`40`):** `ServerOptionsTests` IDs from `2514..2597` subset in Batch 7
- **T2 Route/leaf/proxy reload behavior (`18`):** `RouteHandlerTests`, `LeafNodeHandlerTests`, `LeafNodeProxyTests`
- **T3 Cross-cutting regression (`5`):** `ConfigReloaderTests`, `JwtProcessorTests`, `MqttHandlerTests`, `ConcurrencyTests1`, `NatsServerTests`
### 3. File Strategy
Primary feature 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 (recommended): `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Reload.cs`
- Create (optional helper split if needed): `dotnet/src/ZB.MOM.NatsNet.Server/Config/ReloadDiffHelpers.cs`
Primary test files:
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ServerOptionsTests.Impltests.cs`
- 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: `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`
### 4. Data and Control Flow
- Config reload entry: `NatsServer.ReloadOptions()` normalizes config, merges flag snapshot/boolean overrides, applies baseline defaults, computes diff, applies ordered reload options, then performs post-apply actions (`recheckPinnedCerts`, timestamps, statsz/config metadata updates).
- Diff pipeline: `DiffOptions()` + helper functions (`ImposeOrder`, route/proxy diffs, copy-without-TLS helpers) produce an ordered option list for deterministic `ApplyOptions()` behavior.
- Authorization/cluster paths: `ReloadAuthorization()`, `ReloadClusterPermissions()`, `ReloadClusterPoolAndAccounts()` run after apply, with side effects explicitly validated by mapped tests or deferred with reason.
### 5. Error Handling and Deferment Model
- Unsupported runtime changes return explicit errors (mirroring Go behavior), not silent no-op.
- If a feature requires unported server internals, keep feature `deferred` with concrete reason.
- If a test requires live runtime topology or unsupported infra, keep test `deferred` with concrete reason.
- Stubbing is not an allowed fallback.
### 6. Verification Philosophy
- Feature verification is gated by build + related test evidence.
- Test verification requires real Arrange/Act/Assert on production behavior.
- Status promotion is evidence-driven and chunked.
## Key Risks and Mitigations
1. Reload behavior touches many server subsystems and may expose unported internals.
Mitigation: two bounded feature groups, explicit deferment protocol, and checkpoint gates.
2. Existing ImplBacklog placeholders can mask missing behavior.
Mitigation: mandatory anti-stub scans and class-level gates before status updates.
3. Batch dependency on Batch 6 may block execution sequencing.
Mitigation: preflight dependency gate in implementation plan before any Batch 7 status changes.
## Design Output
This design selects **Approach B** and is ready for execution planning with strict, mandatory verification guardrails for both features and tests.

View File

@@ -0,0 +1,494 @@
# 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.

View File

@@ -0,0 +1,144 @@
# Batch 9 (Auth, DirStore, OCSP Foundations) Design
**Date:** 2026-02-27
**Scope:** Design-only plan for Batch 9 (36 features, 10 tests) covering `server/auth.go`, `server/dirstore.go`, `server/ocsp.go`, and `server/ocsp_peer.go`.
## Context Snapshot
PortTracker snapshot:
- Batch ID: `9`
- Name: `Auth, DirStore, OCSP foundations`
- Dependencies: `Batch 4`, `Batch 6`
- Features: `36` (all currently `deferred`)
- Tests: `10` (all currently `deferred`)
- Current overall project progress (`report summary`): `1924/6942 (27.7%)`
Batch 9 feature clusters from tracker mapping:
- Auth: `361` (`client.matchesPinnedCert` -> `ClientConnection.MatchesPinnedCert`)
- DirStore: `793,794,817,818,819,820,821` (`validatePathExists`, `validateDirPath`, and `expirationTracker` heap methods)
- OCSP monitor/server wiring: `2443-2462`
- OCSP peer validation: `2463-2471`
Batch 9 test mappings:
- Tests `118,119,124,125,128,129,130,131,134,135` mapped to `AuthCalloutTests.*` in `ImplBacklog`
Current .NET baseline findings:
- `DirJwtStore` exists and implements equivalent behavior, but mapped names (`ValidatePathExists`, `ValidateDirPath`, `ExpirationTracker.Len/Less/Swap/Push/Pop`) are not exposed as mapped methods.
- OCSP code is partially ported in `Auth/Ocsp/OcspTypes.cs`, but many Batch 9 mapped methods (`NatsServer.*` OCSP lifecycle + `OcspHandler` helpers + OCSP peer wiring) are not present yet.
- Mapped Batch 9 `AuthCallout` tests are not implemented in `AuthCalloutTests.Impltests.cs` yet.
## Problem Statement
Batch 9 is a foundational bridge between TLS auth, directory-backed JWT storage, and OCSP lifecycle/peer validation. The largest risk is false progress through status updates without behavior-complete parity. A second risk is trying to force infra-heavy auth-callout tests into fake unit tests.
## Constraints and Success Criteria
Constraints:
- Must respect dependency order (`4`, `6`) before execution starts.
- Must follow project standards (`.NET 10`, nullable, xUnit + Shouldly + NSubstitute).
- No placeholders/stubs for production features or tests promoted to `verified`.
- Task slicing must keep feature groups <= ~20 IDs.
Success criteria:
- All implementable Batch 9 feature IDs are ported with direct Go-parity evidence.
- Batch 9 mapped tests are either real/passing or explicitly kept `deferred` with concrete blocker reasons.
- Status transitions are evidence-backed and chunked (<=15 IDs per update command).
## Approaches
### Approach A: Minimum mapping wrappers only
Create thin wrappers for missing mapped methods and mark complete quickly.
- Pros: fast status movement.
- Cons: high semantic risk for OCSP lifecycle and peer-verification behavior.
### Approach B: Full OCSP/auth-callout infrastructure first
Attempt full runtime-complete auth callout + OCSP networking + integration-heavy tests in one pass.
- Pros: closest to end-state behavior.
- Cons: oversized scope for one batch, high blocker probability, low iteration speed.
### Approach C (Recommended): Layered parity slices with strict defer rules
Implement Batch 9 in four bounded feature groups (auth/DirStore -> OCSP core -> OCSP server wiring -> OCSP peer), each with focused tests and hard verification gates. For mapped auth-callout tests, only verify real behaviors that are executable in current infrastructure; keep infra-blocked tests deferred with explicit reasons.
- Pros: controlled risk, auditable status evidence, resilient to infra blockers.
- Cons: requires disciplined status hygiene and explicit defer documentation.
## Recommended Design
### 1. Production Code Shape
Primary files:
- `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs`
- `dotnet/src/ZB.MOM.NatsNet.Server/Accounts/DirJwtStore.cs`
- `dotnet/src/ZB.MOM.NatsNet.Server/Auth/Ocsp/OcspTypes.cs`
- `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Init.cs`
- `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Lifecycle.cs`
Expected new files:
- `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Ocsp.cs`
- `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.OcspPeer.cs`
- `dotnet/src/ZB.MOM.NatsNet.Server/Auth/Ocsp/OcspHandler.cs`
Design intent:
- Add explicit mapped methods for path validation and expiration heap parity without regressing current `DirJwtStore` behavior.
- Separate OCSP responsibilities:
- monitor/cache/status helpers
- server TLS config wiring and lifecycle (enable/start/reload)
- peer verification and OCSP-peer config parsing
- Keep OCSP parsing/network behavior deterministic in unit tests by isolating pure helper paths and using controlled inputs.
### 2. Test Design
Primary/updated test files:
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Accounts/DirectoryStoreTests.cs`
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/OcspResponseCacheTests.cs`
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/CertificateIdentityProvider/CertificateIdentityProviderTests.cs`
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/AuthCalloutTests.Impltests.cs`
Expected new test files:
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/OcspFoundationTests.cs`
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/OcspPeerValidationTests.cs`
- `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/NatsServerOcspTests.cs`
Test strategy:
- Feature-first parity tests for each group before status promotion.
- Mapped `AuthCallout` tests use strict realism checks; if internal callout transport/JWT signing pipeline is still unavailable, keep deferred with explicit reason instead of synthetic pass tests.
### 3. Execution Slicing (Feature Groups <=20)
- **F1 (8 IDs):** `361,793,794,817,818,819,820,821`
- **F2 (12 IDs):** `2443,2444,2445,2446,2447,2448,2457,2458,2459,2460,2461,2462`
- **F3 (7 IDs):** `2450,2451,2452,2453,2454,2455,2456`
- **F4 (9 IDs):** `2463,2464,2465,2466,2467,2468,2469,2470,2471`
- **T1 (10 test IDs):** `118,119,124,125,128,129,130,131,134,135`
### 4. Risks and Mitigations
1. OCSP runtime/network complexity causes partial implementations.
Mitigation: isolate pure helper logic, gate status on focused tests, defer blocked runtime-only paths with evidence.
2. Existing OCSP/DirStore code already diverges from mapped method names.
Mitigation: add explicit mapped entry points/wrappers and prove they are exercised by tests.
3. Auth callout mapped tests require unavailable infrastructure.
Mitigation: enforce no-fake-pass policy; defer with concrete blocker notes and command evidence.
## Design Decision
Proceed with **Approach C**: bounded feature groups + strict verification/defer protocol, then mapped test pass/defer resolution with zero stub tolerance.

View File

@@ -0,0 +1,520 @@
# Batch 9 (Auth, DirStore, OCSP Foundations) Implementation Plan
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
**Goal:** Implement and verify Batch 9 (`36` features + `10` tests) across auth pinned-cert checks, directory-store parity helpers, and OCSP monitor/peer foundations, with evidence-backed status updates.
**Architecture:** Execute four bounded feature groups (8/12/7/9 IDs) and one mapped-test group. For every feature: read mapped Go source, implement minimal parity, build, run related tests, then promote status only after gates pass. For mapped auth-callout tests, enforce real behavioral verification; if infrastructure is missing, keep deferred with explicit blocker evidence.
**Tech Stack:** .NET 10, C# latest, xUnit + Shouldly + NSubstitute, PortTracker CLI, SQLite (`porting.db`)
**Design doc:** `docs/plans/2026-02-27-batch-9-auth-dirstore-ocsp-foundations-design.md`
---
I'm using `writeplan` to create the implementation plan.
## Batch 9 Working Set
Batch facts:
- Batch ID: `9`
- Dependencies: `4,6`
- Features: `36`
- Tests: `10`
- Go files: `server/auth.go`, `server/dirstore.go`, `server/ocsp.go`, `server/ocsp_peer.go`
Environment note:
- `dotnet` is not on PATH in this workspace. Use `/usr/local/share/dotnet/dotnet` for all commands.
Feature groups (max ~20 each):
- **F1 (8):** `361,793,794,817,818,819,820,821`
- **F2 (12):** `2443,2444,2445,2446,2447,2448,2457,2458,2459,2460,2461,2462`
- **F3 (7):** `2450,2451,2452,2453,2454,2455,2456`
- **F4 (9):** `2463,2464,2465,2466,2467,2468,2469,2470,2471`
Test group:
- **T1 (10):** `118,119,124,125,128,129,130,131,134,135`
---
## MANDATORY VERIFICATION PROTOCOL
> **NON-NEGOTIABLE:** No Batch 9 feature/test may be marked `verified` unless this exact protocol is followed.
### Per-Feature Verification Loop (REQUIRED for every feature ID)
1. Read mapping + Go location:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- feature show <id> --db porting.db
```
2. Read exact Go behavior in mapped file/line range.
3. Write C# parity in mapped .NET file/class.
4. Build immediately:
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
5. Run related tests for that feature slice (examples in each task).
6. Only after build + related tests pass, add feature ID to promotion candidates.
### Per-Test Verification Loop (REQUIRED for every test ID)
1. Read mapping + Go test location:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- test show <id> --db porting.db
```
2. Implement/port real Arrange/Act/Assert behavior in mapped test method.
3. Run single mapped test method:
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~<ExactMethodName>" --verbosity normal
```
4. Require discovery and pass (`Passed: 1`, `Failed: 0`) before candidate promotion.
### Stub Detection Check (REQUIRED after each feature/test group)
Run after each task, before any status promotion:
```bash
# Forbidden placeholder markers in touched source/tests
rg -n "NotImplementedException|TODO|PLACEHOLDER" \
dotnet/src/ZB.MOM.NatsNet.Server \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests
# Empty method bodies in touched C# files
for f in $(git diff --name-only -- '*.cs'); do
rg -n "^\s*(public|private|internal|protected).*\)\s*\{\s*\}\s*$" "$f"
done
```
Any match blocks status updates until fixed or explicitly deferred with reason.
### Build Gate (REQUIRED after each feature group)
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
Required: `0` build errors.
### Test Gate (REQUIRED before marking features verified)
All related tests for current group must pass before any `verified` promotion.
Baseline command template:
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "<group-specific-related-tests>" --verbosity normal
```
### Status Update Protocol (REQUIRED)
- Maximum `15` IDs per `feature batch-update` or `test batch-update` command.
- Required evidence for each update command:
- latest build gate output
- related test gate output
- stub detection output
- Status flow:
- Features: `deferred -> stub -> complete -> verified`
- Tests: `deferred -> stub -> verified` (or remain `deferred` with override reason)
Command templates:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "<max15ids>" --set-status <stub|complete|verified> --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "<max15ids>" --set-status <stub|verified> --db porting.db --execute
```
If audit disagrees:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status <status> --db porting.db \
--override "verification evidence: <short reason>"
```
### Checkpoint Protocol Between Tasks (REQUIRED)
After each task (F1/F2/F3/F4/T1), before moving on:
1. Full build:
```bash
/usr/local/share/dotnet/dotnet build dotnet/
```
2. Full unit tests:
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
3. Commit completed slice:
```bash
git add <touched-files> porting.db
git commit -m "feat(batch9): <task-slice-summary>"
```
---
## ANTI-STUB GUARDRAILS
### Forbidden Patterns
Production code must not include:
- `throw new NotImplementedException(...)` for Batch 9 mapped methods
- empty mapped method bodies (`{ }`)
- TODO placeholders in mapped method bodies
- fake default returns (`return null;`, `return default;`, `return true;`) where Go behavior is non-trivial
Test code must not include for `verified` status:
- `Assert.True(true)` / unconditional pass assertions
- tests that only assert method-name strings/constants
- empty test bodies
- single trivial assertion that does not exercise mapped behavior
### Hard Limits
- Max `20` features per implementation task group
- Max `15` IDs per status update command
- No cross-group bulk verification in one cycle
- Build gate required after each feature group
- Test gate required before `verified` promotion
- Mandatory checkpoint commit between task groups
### If You Get Stuck
Do not stub and do not fake-pass.
1. Keep blocked feature/test as `deferred`.
2. Record concrete blocker using `--override`.
3. Capture failing command output as evidence.
4. Continue with next unblocked ID.
Commands:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature update <id> --status deferred --db porting.db \
--override "blocked: <specific missing dependency/runtime/infrastructure>"
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test update <id> --status deferred --db porting.db \
--override "blocked: <specific missing dependency/runtime/infrastructure>"
```
---
### Task 1: Dependency Preflight and Batch Start
**Files:**
- Modify: `porting.db`
**Step 1: Verify dependency batches are complete**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 4 --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 6 --db porting.db
```
**Step 2: Start Batch 9 only if dependencies are complete**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch start 9 --db porting.db
```
**Step 3: Run checkpoint protocol and commit preflight evidence**
---
### Task 2: Implement Feature Group F1 (Auth + DirStore + Expiration Heap Primitives)
**IDs:** `361,793,794,817,818,819,820,821`
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Accounts/DirJwtStore.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Accounts/DirectoryStoreTests.cs`
- Modify/Create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ServerTests.cs`
- Modify: `porting.db`
**Step 1: Mark F1 as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "361,793,794,817,818,819,820,821" --set-status stub --db porting.db --execute
```
**Step 2: Write/adjust failing tests for pinned-cert and DirStore parity methods**
**Step 3: Run focused tests and confirm FAIL first**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~DirectoryStoreTests|FullyQualifiedName~ServerTests" --verbosity normal
```
**Step 4: Implement mapped F1 methods using Per-Feature Verification Loop**
**Step 5: Re-run focused tests and require PASS**
Use same command as Step 3, require `Failed: 0`.
**Step 6: Run Stub Detection + Build Gate + Test Gate**
**Step 7: Promote F1 to `complete` then `verified`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "361,793,794,817,818,819,820,821" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "361,793,794,817,818,819,820,821" --set-status verified --db porting.db --execute
```
**Step 8: Run checkpoint protocol and commit**
---
### Task 3: Implement Feature Group F2 (OCSP Monitor Core + Helper Functions)
**IDs:** `2443,2444,2445,2446,2447,2448,2457,2458,2459,2460,2461,2462`
**Files:**
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/Auth/Ocsp/OcspTypes.cs`
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/Auth/Ocsp/OcspHandler.cs`
- Modify/Create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/OcspResponseCacheTests.cs`
- Create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/OcspFoundationTests.cs`
- Modify: `porting.db`
**Step 1: Mark F2 as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2443,2444,2445,2446,2447,2448,2457,2458,2459,2460,2461,2462" --set-status stub --db porting.db --execute
```
**Step 2: Add failing OCSP foundation tests (status selection, cert parsing, issuer lookup, status-string, response validity)**
**Step 3: Run focused tests and confirm FAIL**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~OcspFoundationTests|FullyQualifiedName~OcspResponseCacheTests|FullyQualifiedName~CertificateIdentityProviderTests" --verbosity normal
```
**Step 4: Implement F2 methods with per-feature loop**
**Step 5: Re-run focused tests and require PASS**
Use same command as Step 3, require `Failed: 0`.
**Step 6: Run Stub Detection + Build Gate + Test Gate**
**Step 7: Promote F2 to `complete` then `verified`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2443,2444,2445,2446,2447,2448,2457,2458,2459,2460,2461,2462" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2443,2444,2445,2446,2447,2448,2457,2458,2459,2460,2461,2462" --set-status verified --db porting.db --execute
```
**Step 8: Run checkpoint protocol and commit**
---
### Task 4: Implement Feature Group F3 (NatsServer OCSP Wiring/Lifecycle)
**IDs:** `2450,2451,2452,2453,2454,2455,2456`
**Files:**
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Ocsp.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Init.cs`
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Lifecycle.cs`
- Create/Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/NatsServerOcspTests.cs`
- Modify: `porting.db`
**Step 1: Mark F3 as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2450,2451,2452,2453,2454,2455,2456" --set-status stub --db porting.db --execute
```
**Step 2: Add failing server OCSP wiring tests (config discovery, monitor creation, store dir, reload/start behavior)**
**Step 3: Run focused tests and confirm FAIL**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~NatsServerOcspTests|FullyQualifiedName~OcspFoundationTests" --verbosity normal
```
**Step 4: Implement F3 methods with per-feature loop**
**Step 5: Re-run focused tests and require PASS**
Use same command as Step 3, require `Failed: 0`.
**Step 6: Run Stub Detection + Build Gate + Test Gate**
**Step 7: Promote F3 to `complete` then `verified`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2450,2451,2452,2453,2454,2455,2456" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2450,2451,2452,2453,2454,2455,2456" --set-status verified --db porting.db --execute
```
**Step 8: Run checkpoint protocol and commit**
---
### Task 5: Implement Feature Group F4 (OCSP Peer Parsing + TLS Plug/Validation)
**IDs:** `2463,2464,2465,2466,2467,2468,2469,2470,2471`
**Files:**
- Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.OcspPeer.cs`
- Modify/Create: `dotnet/src/ZB.MOM.NatsNet.Server/Auth/CertificateIdentityProvider/OcspPeerConfig.cs`
- Create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/OcspPeerValidationTests.cs`
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Auth/CertificateIdentityProvider/CertificateIdentityProviderTests.cs`
- Modify: `porting.db`
**Step 1: Mark F4 as `stub`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2463,2464,2465,2466,2467,2468,2469,2470,2471" --set-status stub --db porting.db --execute
```
**Step 2: Add failing OCSP peer tests (config parse variants, peer chain selection, tls client/server validation hooks)**
**Step 3: Run focused tests and confirm FAIL**
```bash
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~OcspPeerValidationTests|FullyQualifiedName~CertificateIdentityProviderTests" --verbosity normal
```
**Step 4: Implement F4 methods with per-feature loop**
**Step 5: Re-run focused tests and require PASS**
Use same command as Step 3, require `Failed: 0`.
**Step 6: Run Stub Detection + Build Gate + Test Gate**
**Step 7: Promote F4 to `complete` then `verified`**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2463,2464,2465,2466,2467,2468,2469,2470,2471" --set-status complete --db porting.db --execute
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
feature batch-update --ids "2463,2464,2465,2466,2467,2468,2469,2470,2471" --set-status verified --db porting.db --execute
```
**Step 8: Run checkpoint protocol and commit**
---
### Task 6: Resolve Mapped Test Group T1 (AuthCalloutTests in ImplBacklog)
**IDs:** `118,119,124,125,128,129,130,131,134,135`
**Files:**
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/AuthCalloutTests.Impltests.cs`
- Modify (if needed): `dotnet/src/ZB.MOM.NatsNet.Server/Auth/AuthCallout.cs`
- Modify (if needed): `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Auth.cs`
- Modify: `porting.db`
**Step 1: Mark T1 as `stub` in one chunk (10 <= 15)**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "118,119,124,125,128,129,130,131,134,135" --set-status stub --db porting.db --execute
```
**Step 2: For each test ID, attempt real port with Per-Test Verification Loop**
**Step 3: If runtime dependencies are missing (internal callout pub/sub/JWT signing pipeline), keep test deferred with reason and no fake assertions**
Example defer command:
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test update <id> --status deferred --db porting.db \
--override "blocked: requires full auth-callout runtime path (internal request/reply + signed response validation)"
```
**Step 4: Promote only genuinely passing test IDs to `verified` (max 15 IDs/update)**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "<verified-ids-max15>" --set-status verified --db porting.db --execute
```
**Step 5: Run Stub Detection + Build/Test Gates + checkpoint commit**
---
### Task 7: Batch 9 Final Verification and Closure
**Files:**
- Modify: `porting.db`
- Generate: `reports/current.md`
**Step 1: Full build + full unit tests**
```bash
/usr/local/share/dotnet/dotnet build dotnet/
/usr/local/share/dotnet/dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
```
**Step 2: Run global Batch 9 stub scan on touched files**
```bash
rg -n "NotImplementedException|TODO|PLACEHOLDER|Assert\.True\(true\)" \
dotnet/src/ZB.MOM.NatsNet.Server \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests
```
**Step 3: Validate batch visibility and statuses**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 9 --db porting.db
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db
```
**Step 4: Attempt batch completion**
```bash
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch complete 9 --db porting.db
```
**Step 5: Generate report and final commit**
```bash
./reports/generate-report.sh
git add dotnet/src/ZB.MOM.NatsNet.Server \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests \
porting.db reports/
git commit -m "feat(batch9): implement auth/dirstore/ocsp foundations"
```