Files
natsnet/docs/plans/2026-02-27-batch-35-js-cluster-remaining-implementation-plan.md
Joseph Doherty f8dce79ac0 Add batch plans for batches 31-36 (rounds 16-18)
Generated design docs and implementation plans via Codex for:
- Batch 31: Raft Part 2
- Batch 32: JS Cluster Meta
- Batch 33: JS Cluster Streams
- Batch 34: JS Cluster Consumers
- Batch 35: JS Cluster Remaining
- Batch 36: Stream Lifecycle

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

411 lines
14 KiB
Markdown

# 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 <feature_id> --db porting.db
```
2. Mark only that feature as in-progress:
```bash
$DOTNET run --project tools/NatsNet.PortTracker -- feature update <feature_id> --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 <test_id> --db porting.db
```
2. Mark only that test as in-progress:
```bash
$DOTNET run --project tools/NatsNet.PortTracker -- test update <test_id> --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~<ClassName>.<MethodName>" --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 "<max 15 ids>" --set-status <stub|complete|verified> --db porting.db --execute
$DOTNET run --project tools/NatsNet.PortTracker -- \
test batch-update --ids "<max 15 ids>" --set-status <stub|complete|verified> --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 <feature_id> --status deferred --override "blocked: <specific reason>" --db porting.db
```
Test deferral command:
```bash
$DOTNET run --project tools/NatsNet.PortTracker -- \
test update <test_id> --status deferred --override "blocked: <specific reason>" --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.