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.
16 KiB
Batch 36 Stream Lifecycle Implementation Plan
For Codex: REQUIRED SUB-SKILL: Use
executeplanto implement this plan task-by-task.
Goal: Port and verify Batch 36 (Stream Lifecycle) from server/stream.go so all 92 mapped features and 53 mapped tests are either genuinely implemented/verified or explicitly deferred with documented blockers.
Architecture: Implement in five bounded feature groups (20/20/20/20/12) aligned to NatsStream lifecycle domains (config/update, mirror, source, subscriptions) plus supporting Account, NatsServer, JsAccount, and stream type helpers. Execute four test waves with strict per-test evidence and anti-stub enforcement before any status promotion.
Tech Stack: .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (porting.db)
Design doc: docs/plans/2026-02-27-batch-36-stream-lifecycle-design.md
Batch 36 Scope
- Batch ID:
36 - Name:
Stream Lifecycle - Dependencies:
8,11,12,13,14,15,28 - Go source:
golang/nats-server/server/stream.go - Features:
92(3196-3293mapped IDs) - Tests:
53
If dotnet is not on PATH, use:
DOTNET=/usr/local/share/dotnet/dotnet
Primary production files (expected):
- Modify:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.Lifecycle.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.Mirror.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.Source.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.Subscriptions.cs - Modify:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreTypes.cs - Modify:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StreamTypes.cs - Modify:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamTypes.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JsAccount.StreamLifecycle.cs - Modify:
dotnet/src/ZB.MOM.NatsNet.Server/Accounts/Account.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/Accounts/Account.StreamLifecycle.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.StreamLifecycle.cs
Primary test files (expected):
- Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs - Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsConsumerTests.Impltests.cs - Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamClusterTests2.Impltests.cs - 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/StorageEngineTests.Impltests.cs - Create:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamClusterTests1.Impltests.cs - Create:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamClusterTests3.Impltests.cs
MANDATORY VERIFICATION PROTOCOL
NON-NEGOTIABLE: Every feature/test in Batch 36 must pass this loop. No shortcut status updates.
Dependency Preflight (before any status change)
$DOTNET run --project tools/NatsNet.PortTracker -- batch show 8 --db porting.db
$DOTNET run --project tools/NatsNet.PortTracker -- batch show 11 --db porting.db
$DOTNET run --project tools/NatsNet.PortTracker -- batch show 12 --db porting.db
$DOTNET run --project tools/NatsNet.PortTracker -- batch show 13 --db porting.db
$DOTNET run --project tools/NatsNet.PortTracker -- batch show 14 --db porting.db
$DOTNET run --project tools/NatsNet.PortTracker -- batch show 15 --db porting.db
$DOTNET run --project tools/NatsNet.PortTracker -- batch show 28 --db porting.db
$DOTNET run --project tools/NatsNet.PortTracker -- batch show 36 --db porting.db
$DOTNET run --project tools/NatsNet.PortTracker -- batch ready --db porting.db
Start only when ready:
$DOTNET run --project tools/NatsNet.PortTracker -- batch start 36 --db porting.db
Capture baseline:
$DOTNET build dotnet/
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/
Per-Feature Verification Loop (REQUIRED per feature ID)
- Inspect mapping and Go context:
$DOTNET run --project tools/NatsNet.PortTracker -- feature show <feature_id> --db porting.db
- Mark claim-in-progress:
$DOTNET run --project tools/NatsNet.PortTracker -- feature update <feature_id> --status stub --db porting.db
- Add/adjust focused test(s) for that feature behavior (red first when practical).
- Implement minimal real logic (no placeholder bodies).
- Run Stub Detection Check on touched files.
- Run Build Gate.
- Run targeted Test Gate for affected classes.
- If green, promote feature to
complete(orverifiedonly with checkpoint evidence). - Record evidence before touching next feature.
Per-Test Verification Loop (REQUIRED per test ID)
- Inspect mapping and Go test location:
$DOTNET run --project tools/NatsNet.PortTracker -- test show <test_id> --db porting.db
- Mark claim-in-progress:
$DOTNET run --project tools/NatsNet.PortTracker -- test update <test_id> --status stub --db porting.db
- Port full Arrange/Act/Assert behavior against production code.
- Run the single test method:
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~<ClassName>.<MethodName>" --verbosity normal
- Confirm output shows
Passed: 1, Failed: 0(neverPassed: 0). - Run class-level filter for touched test class.
- Run Stub Detection Check + Build Gate.
- Promote test to
complete(orverifiedonly with checkpoint evidence).
Stub Detection Check (REQUIRED after every loop)
Run on changed C# files in source + tests:
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|ShouldContain\\(\"Should\"\\)|var goFile = \"server/|JetStreamVersioning\\.GetRequiredApiLevel\\(new Dictionary<string, string>\\)\\.ShouldBe\\(string\\.Empty\\)|=>\\s*default;|return\\s+default;|return\\s+null;\\s*$)"
fi
Any match in mapped Batch 36 methods/tests blocks promotion until resolved.
Build Gate (REQUIRED)
$DOTNET build dotnet/
Run:
- after every feature loop
- after every test loop
- before any batch-update
- at every task checkpoint
Test Gate (REQUIRED)
Minimum class/domain gates per touched area:
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~JetStreamEngineTests"
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~JetStreamClusterTests"
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~NatsConsumerTests"
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~StorageEngineTests|FullyQualifiedName~JetStreamFileStoreTests|FullyQualifiedName~ConcurrencyTests1"
Checkpoint/full gate:
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/
Status Update Protocol (HARD LIMIT: max 15 IDs per batch-update)
- Never pass more than
15IDs perfeature batch-updateortest batch-updatecall. - Never promote
verifiedwithout loop evidence + checkpoint gate. - Never update IDs outside current task scope.
- For blocked work, keep
deferredwith explicit reason.
Templates:
$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:
- Run Stub Detection Check on current diff.
- Run Build Gate.
- Run class filters for all touched classes.
- Run full unit test gate.
- Promote only proven IDs in
<=15chunks. - Commit checkpoint before the next task.
ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)
Forbidden Patterns
These are forbidden in mapped Batch 36 features/tests:
throw new NotImplementedException()- Empty or no-op mapped method bodies
- Placeholder comments (
TODO,PLACEHOLDER,later) - Fake-pass assertions (
Assert.True(true),Assert.Pass(), tautological string checks) - Template test bodies that only assert literals, including patterns such as:
var goFile = "server/...""<MethodName>".ShouldContain("Should")JetStreamVersioning.GetRequiredApiLevel(new Dictionary<string, string>()).ShouldBe(string.Empty)as the core assertion
- Constant-return shortcuts in mapped feature methods that ignore state/input (
return default;,return null;, hardcoded primitives) unless directly required by Go behavior and covered by tests - Catch-and-ignore blocks used to force green tests
Hard Limits
- Feature groups must stay at
~20IDs max. feature batch-updatemaximum IDs per call:15.test batch-updatemaximum IDs per call:15.- One active feature loop at a time.
- One active test loop at a time.
- Mandatory checkpoint between every task.
- No
verifiedpromotion without checkpoint evidence.
If You Get Stuck (REQUIRED)
- Stop on the current ID immediately.
- Do not add placeholder code or fake assertions.
- Mark blocked item
deferredwith explicit reason. - Move to next unblocked ID.
Feature deferral:
$DOTNET run --project tools/NatsNet.PortTracker -- \
feature update <feature_id> --status deferred --override "blocked: <specific reason>" --db porting.db
Test deferral:
$DOTNET run --project tools/NatsNet.PortTracker -- \
test update <test_id> --status deferred --override "blocked: <specific reason>" --db porting.db
deferred with a concrete blocker is correct. Stubbed progress is not.
Feature Groups (max ~20 each)
Group A (20): Stream creation, assignment, leadership primitives
IDs:
3196,3197,3198,3200,3201,3202,3203,3204,3205,3206,3207,3208,3209,3210,3211,3213,3214,3216,3217,3219
Group B (20): Limits, dedupe, advisories, config validation/update entry points
IDs:
3220,3221,3222,3223,3224,3225,3226,3227,3228,3229,3230,3231,3232,3233,3234,3235,3237,3238,3239,3240
Group C (20): Update internals, purge/delete, mirror processing/retry foundation
IDs:
3241,3242,3244,3245,3246,3247,3248,3249,3250,3251,3252,3253,3254,3255,3256,3257,3258,3259,3260,3261
Group D (20): Source consumer setup, flow control, source header/sequence recovery
IDs:
3262,3263,3264,3265,3266,3267,3268,3269,3270,3271,3272,3273,3274,3275,3276,3277,3278,3279,3280,3281
Group E (12): Direct/mirror-direct subscriptions, internal subscribe/unsubscribe cleanup
IDs:
3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3293
Test Waves
Wave T1 (15): file-store + cluster + consumer API basics
IDs:
548,849,869,902,951,953,955,990,1032,1034,1125,1227,1262,1315,1317
Wave T2 (12): stream create/update/publish baseline
IDs:
1468,1470,1471,1474,1475,1478,1480,1481,1482,1483,1504,1512
Wave T3 (12): limits, perf-sensitive behavior, republish cases
IDs:
1532,1544,1554,1555,1564,1565,1614,1623,1635,1636,1637,1638
Wave T4 (14): republish tail, direct get, versioning, concurrency/storage
IDs:
1639,1640,1644,1645,1646,1653,1656,1657,1669,1741,1743,2387,2402,2952
Task 1: Preflight and Baseline
Files:
- Read:
docs/plans/2026-02-27-batch-36-stream-lifecycle-design.md - Read:
golang/nats-server/server/stream.go
Steps:
- Run dependency preflight commands.
- Start Batch 36 only if ready.
- Capture baseline build/test evidence.
- Do not promote any IDs before baseline evidence exists.
Task 2: Implement Feature Group A (20 IDs)
Files:
- Modify:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreTypes.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/Accounts/Account.StreamLifecycle.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.Lifecycle.cs
Steps:
- Move Group A IDs to
stubusing15 + 5update chunks. - Execute Per-Feature Verification Loop per ID.
- Run mandatory gates after each ID.
- Promote proven IDs (
complete/verified) in<=15chunks. - Run Checkpoint Protocol.
Task 3: Implement Feature Group B (20 IDs) + Test Wave T1 (15 IDs)
Files:
- Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.StreamLifecycle.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JsAccount.StreamLifecycle.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.Lifecycle.cs - Modify/Create:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamClusterTests1.Impltests.cs - Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamClusterTests2.Impltests.cs - Modify/Create:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamClusterTests3.Impltests.cs - Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsConsumerTests.Impltests.cs - Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamFileStoreTests.Impltests.cs
Steps:
- Implement Group B features with per-feature loop and gates.
- Port Wave T1 tests with per-test loop and gates.
- Apply status updates in max-15 chunks only.
- Run Checkpoint Protocol.
Task 4: Implement Feature Group C (20 IDs) + Test Wave T2 (12 IDs)
Files:
- Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.Lifecycle.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.Mirror.cs - Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs
Steps:
- Implement Group C feature IDs with per-feature loop.
- Port Wave T2 tests.
- Run stub/build/test gates and checkpoint.
- Promote only proven IDs in
<=15chunks.
Task 5: Implement Feature Group D (20 IDs) + Test Wave T3 (12 IDs)
Files:
- Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.Source.cs - Modify:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StreamTypes.cs - Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs
Steps:
- Implement Group D features with per-feature loop.
- Port Wave T3 tests.
- Run mandatory gates and checkpoint.
- Promote only proven IDs in
<=15chunks.
Task 6: Implement Feature Group E (12 IDs) + Test Wave T4 (14 IDs)
Files:
- Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.Subscriptions.cs - 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/StorageEngineTests.Impltests.cs
Steps:
- Implement Group E feature IDs.
- Port Wave T4 tests.
- Run mandatory gates and checkpoint.
- Promote proven IDs in
<=15chunks.
Task 7: Batch 36 Final Closure
Files:
- Modify:
porting.db - Generate:
reports/current.md(via report script)
Steps:
- Run final stub scan on all touched source/test files.
- Run full build and full unit suite.
- Validate batch state:
$DOTNET run --project tools/NatsNet.PortTracker -- batch show 36 --db porting.db
$DOTNET run --project tools/NatsNet.PortTracker -- report summary --db porting.db
- Ensure every Batch 36 ID is
complete/verified/n_aordeferredwith explicit blocker notes. - Generate report:
./reports/generate-report.sh
Execution note: Planning only. Do not execute this plan in this session.