# Batch 35 JS Cluster Remaining Implementation Plan > **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task. **Goal:** Port and verify Batch 35 (`JS Cluster Remaining`) from `server/jetstream_cluster.go`, with auditable status transitions for all 57 features and 49 tests. **Architecture:** Execute three bounded feature groups (`20/20/17`) mapped to `JetStreamCluster`, `NatsStream`, `JetStreamEngine`, and `NatsServer`, then execute four test waves (`7/14/14/14`) with strict method-level verification evidence. Every promotion is gated by stub scans, build/test gates, and checkpoint protocol between tasks. **Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`) **Design doc:** `docs/plans/2026-02-27-batch-35-js-cluster-remaining-design.md` --- ## Batch 35 Scope - Batch ID: `35` - Name: `JS Cluster Remaining` - Dependency: `32` - Go source: `golang/nats-server/server/jetstream_cluster.go` - Features: `57` (`1694-1750`) - Tests: `49` (`730,846,847,848,890,891,893,2640,2641,2643,2644,2645,2646,2647,2648,2649,2653,2655,2656,2658,2659,2660,2661,2662,2665,2666,2668,2669,2673,2676,2677,2678,2679,2680,2681,2682,2683,2684,2685,2686,2688,2691,2696,2697,2703,2715,2716,2717,2719`) If `dotnet` is not on `PATH`, use: ```bash DOTNET=/usr/local/share/dotnet/dotnet ``` Primary production files (expected touch set): - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamClusterTypes.cs` - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.cs` - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamTypes.cs` - Modify or Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.JetStreamClusterRemaining.cs` - Modify (if not using partial file): `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.cs` Primary test files (expected touch set): - Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamBatchingTests.Impltests.cs` - Modify or Create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamClusterTests1.Impltests.cs` - Modify or Create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RaftNodeTests.Impltests.cs` --- ## MANDATORY VERIFICATION PROTOCOL > **NON-NEGOTIABLE:** Every Batch 35 feature/test ID must pass this protocol before promotion. ### Dependency Preflight Gate (before any status changes) ```bash $DOTNET run --project tools/NatsNet.PortTracker -- batch show 32 --db porting.db $DOTNET run --project tools/NatsNet.PortTracker -- batch show 35 --db porting.db $DOTNET run --project tools/NatsNet.PortTracker -- batch ready --db porting.db ``` Only if Batch 35 is ready: ```bash $DOTNET run --project tools/NatsNet.PortTracker -- batch start 35 --db porting.db ``` Capture baseline evidence: ```bash $DOTNET build dotnet/ $DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ ``` ### Per-Feature Verification Loop (REQUIRED per feature ID) 1. Inspect mapping and Go line span: ```bash $DOTNET run --project tools/NatsNet.PortTracker -- feature show --db porting.db ``` 2. Mark only that feature as in-progress: ```bash $DOTNET run --project tools/NatsNet.PortTracker -- feature update --status stub --db porting.db ``` 3. Add or update at least one focused test that fails for intended behavior. 4. Run focused test; verify failure reason matches target behavior. 5. Implement minimal feature logic (no placeholder code). 6. Run **Stub Detection Check**. 7. Run **Build Gate**. 8. Run **Test Gate** (method/class filters for impacted area). 9. If green, mark feature `complete`; defer `verified` promotion until task checkpoint. ### Per-Test Verification Loop (REQUIRED per test ID) 1. Inspect mapping and Go source: ```bash $DOTNET run --project tools/NatsNet.PortTracker -- test show --db porting.db ``` 2. Mark only that test as in-progress: ```bash $DOTNET run --project tools/NatsNet.PortTracker -- test update --status stub --db porting.db ``` 3. Port full Arrange/Act/Assert behavior. 4. Run single test method: ```bash $DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \ --filter "FullyQualifiedName~." --verbosity normal ``` 5. Confirm summary includes `Passed: 1, Failed: 0` (never `Passed: 0`). 6. Run class-level filter for touched class. 7. Run **Stub Detection Check** + **Build Gate**. 8. If green, mark test `complete`; defer `verified` promotion until task checkpoint. ### Stub Detection Check (REQUIRED after every feature/test loop) Run on changed C# files only: ```bash changed_files=$(git diff --name-only -- dotnet/src/ZB.MOM.NatsNet.Server dotnet/tests/ZB.MOM.NatsNet.Server.Tests | rg "\\.cs$" || true) if [ -n "$changed_files" ]; then echo "$changed_files" | xargs rg -n "(NotImplementedException|// TODO|// PLACEHOLDER|Assert\\.True\\(true\\)|Assert\\.Pass|ShouldBe\\(true\\)|=>\\s*default;|=>\\s*null;|return\\s+null;\\s*$|return\\s+0;\\s*$|return\\s+false;\\s*$)" fi ``` Any match in mapped methods/tests blocks promotion. ### Build Gate (REQUIRED) Run: ```bash $DOTNET build dotnet/ ``` Required timing: - after each feature loop - after each test loop - before every `batch-update` - at every checkpoint ### Test Gate (REQUIRED) Minimum gates: ```bash $DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~JetStream" $DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~RaftNodeTests" $DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ImplBacklog" ``` Per-item focused gates are mandatory: - Feature loop: nearest impacted class filters. - Test loop: method filter, then class filter. ### Status Update Protocol (HARD LIMIT: 15 IDs max per `batch-update`) - Never pass more than `15` IDs in one `feature batch-update` or `test batch-update` call. - Never promote `verified` without loop evidence and checkpoint evidence. - Never update IDs outside active task scope. - For blocked items, keep `deferred` and provide explicit `--override` reason. Templates: ```bash $DOTNET run --project tools/NatsNet.PortTracker -- \ feature batch-update --ids "" --set-status --db porting.db --execute $DOTNET run --project tools/NatsNet.PortTracker -- \ test batch-update --ids "" --set-status --db porting.db --execute ``` ### Checkpoint Protocol Between Tasks (REQUIRED) Before starting the next task: 1. Run **Stub Detection Check**. 2. Run **Build Gate**. 3. Run class filters for all touched classes. 4. Run full unit suite: ```bash $DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ ``` 5. Promote only proven IDs in `<=15` chunks. 6. Commit checkpoint before next task. --- ## ANTI-STUB GUARDRAILS (NON-NEGOTIABLE) These apply to features and tests. ### Forbidden Patterns - `throw new NotImplementedException()` in any mapped Batch 35 feature/test. - Empty method bodies for mapped features. - Placeholder comments in mapped paths (`TODO`, `PLACEHOLDER`, `later`). - Fake-pass assertions (`Assert.True(true)`, `Assert.Pass()`, tautological assertions). - Constant-return shortcuts in mapped features that ignore inputs/state (`return false;`, `return 0;`, `return null;`, `return string.Empty;`). - Catch-and-ignore blocks that suppress failures to force green results. ### Hard Limits - Feature task group size max: `~20` IDs. - `feature batch-update` max IDs: `15`. - `test batch-update` max IDs: `15`. - One active feature loop at a time. - One active test loop at a time. - Mandatory checkpoint between every task. - No `verified` promotion without checkpoint evidence. ### If You Get Stuck (REQUIRED) 1. Stop on the current ID immediately. 2. Do not add placeholder implementation or fake assertions. 3. Mark blocked item `deferred` with explicit reason. 4. Move to next unblocked ID. Feature deferral command: ```bash $DOTNET run --project tools/NatsNet.PortTracker -- \ feature update --status deferred --override "blocked: " --db porting.db ``` Test deferral command: ```bash $DOTNET run --project tools/NatsNet.PortTracker -- \ test update --status deferred --override "blocked: " --db porting.db ``` Deferred with reason is correct behavior. Stubbed/fake-pass progress is not. --- ## Feature Groups (max ~20 each) ### Group A (20): delete-range/assignment codecs + snapshot capability foundations IDs: `1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709,1710,1711,1712,1713` ### Group B (20): snapshot delete/catchup peer lifecycle + sync/catchup processing + cluster info base IDs: `1714,1715,1716,1717,1718,1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733` ### Group C (17): cluster stream info, gcb controls, runCatchup, and sync subject helpers IDs: `1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,1749,1750` ## Test Waves ### Wave T1 (7): batching + cluster-meta-recovery/offline strict decoding IDs: `730,846,847,848,890,891,893` ### Wave T2 (14): raft catchup/truncate/snapshot baseline IDs: `2640,2641,2643,2644,2645,2646,2647,2648,2649,2653,2655,2656,2658,2659` ### Wave T3 (14): raft health/quorum/leader-change/snapshot replay IDs: `2660,2661,2662,2665,2666,2668,2669,2673,2676,2677,2678,2679,2680,2681` ### Wave T4 (14): raft startup/rollback/install snapshot and peer replay IDs: `2682,2683,2684,2685,2686,2688,2691,2696,2697,2703,2715,2716,2717,2719` --- ### Task 1: Preflight and Baseline **Files:** - Read: `docs/plans/2026-02-27-batch-35-js-cluster-remaining-design.md` - Read: `golang/nats-server/server/jetstream_cluster.go` **Steps:** 1. Run dependency preflight commands. 2. Start Batch 35 only if dependency checks pass. 3. Capture baseline build/test evidence. 4. Do not promote any ID before baseline evidence exists. ### Task 2: Implement Feature Group A (20 IDs) **Files:** - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamClusterTypes.cs` - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.cs` - Modify/Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.JetStreamClusterRemaining.cs` **Steps:** 1. Move Group A IDs to `stub` in two `batch-update` calls (`15 + 5`). 2. Execute Per-Feature Verification Loop for each ID. 3. Run mandatory gates after each ID. 4. Apply checkpoint protocol. 5. Promote proven Group A IDs to `complete/verified` in `<=15` chunks. 6. Commit checkpoint. ### Task 3: Implement Feature Group B (20 IDs) **Files:** - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.cs` - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamTypes.cs` **Steps:** 1. Move Group B IDs to `stub` in two `batch-update` calls (`15 + 5`). 2. Execute Per-Feature Verification Loop for each ID. 3. Run mandatory gates after each ID. 4. Apply checkpoint protocol. 5. Promote proven Group B IDs to `complete/verified` in `<=15` chunks. 6. Commit checkpoint. ### Task 4: Implement Feature Group C (17 IDs) **Files:** - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.cs` - Modify/Create: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.JetStreamClusterRemaining.cs` - Modify: `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamClusterTypes.cs` **Steps:** 1. Move Group C IDs to `stub` in two `batch-update` calls (`15 + 2`). 2. Execute Per-Feature Verification Loop for each ID. 3. Run mandatory gates after each ID. 4. Apply checkpoint protocol. 5. Promote proven Group C IDs to `complete/verified` in `<=15` chunks. 6. Commit checkpoint. ### Task 5: Port Test Wave T1 (7 IDs) **Files:** - Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamBatchingTests.Impltests.cs` - Modify/Create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamClusterTests1.Impltests.cs` **Steps:** 1. Move T1 IDs to `stub` in one call. 2. Execute Per-Test Verification Loop for each ID. 3. Run class-level filters for touched classes. 4. Apply checkpoint protocol. 5. Promote proven T1 IDs to `complete/verified` in `<=15` chunks. 6. Commit checkpoint. ### Task 6: Port Test Wave T2 (14 IDs) **Files:** - Modify/Create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RaftNodeTests.Impltests.cs` **Steps:** 1. Move T2 IDs to `stub` in one call. 2. Execute Per-Test Verification Loop for each ID. 3. Run class-level `RaftNodeTests` filter. 4. Apply checkpoint protocol. 5. Promote proven T2 IDs to `complete/verified` in `<=15` chunks. 6. Commit checkpoint. ### Task 7: Port Test Wave T3 (14 IDs) **Files:** - Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RaftNodeTests.Impltests.cs` **Steps:** 1. Move T3 IDs to `stub` in one call. 2. Execute Per-Test Verification Loop for each ID. 3. Run class-level `RaftNodeTests` filter. 4. Apply checkpoint protocol. 5. Promote proven T3 IDs to `complete/verified` in `<=15` chunks. 6. Commit checkpoint. ### Task 8: Port Test Wave T4 (14 IDs) **Files:** - Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RaftNodeTests.Impltests.cs` **Steps:** 1. Move T4 IDs to `stub` in one call. 2. Execute Per-Test Verification Loop for each ID. 3. Run class-level `RaftNodeTests` filter. 4. Apply checkpoint protocol. 5. Promote proven T4 IDs to `complete/verified` in `<=15` chunks. 6. Commit checkpoint. ### Task 9: Final Batch 35 Closure **Files:** - Modify: `porting.db` - Modify: `reports/current.md` **Steps:** 1. Run final audit checks: ```bash $DOTNET run --project tools/NatsNet.PortTracker -- audit --type features --db porting.db $DOTNET run --project tools/NatsNet.PortTracker -- audit --type tests --db porting.db ``` 2. Resolve any audit mismatches (or explicit override reasons). 3. Complete batch: ```bash $DOTNET run --project tools/NatsNet.PortTracker -- batch complete 35 --db porting.db ``` 4. Generate updated report: ```bash ./reports/generate-report.sh ``` 5. Final regression gate: ```bash $DOTNET build dotnet/ $DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ ``` 6. Commit final Batch 35 closure.