Generated design docs and implementation plans via Codex for: - Batch 37: Stream Messages - Batch 38: Consumer Lifecycle - Batch 39: Consumer Dispatch - Batch 40: MQTT Server/JSA - Batch 41: MQTT Client/IO All plans include mandatory verification protocol and anti-stub guardrails. Updated batches.md with file paths and planned status. All 42 batches (0-41) now have design docs and implementation plans.
16 KiB
Batch 37 Stream Messages Implementation Plan
For Codex: REQUIRED SUB-SKILL: Use
executeplanto implement this plan task-by-task.
Goal: Port and verify Batch 37 (Stream Messages) from server/stream.go so all 86 mapped features and 13 mapped tests are either genuinely implemented/verified or explicitly deferred with concrete blockers.
Architecture: Implement Batch 37 in five feature groups (18/16/16/17/19) using NatsStream partials plus message carrier helpers (InMsg, CMsg, JsPubMsg, JsOutQ) and account restore support. Execute three test waves with strict per-feature/per-test evidence loops and mandatory anti-stub gates 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-37-stream-messages-design.md
Batch 37 Scope
- Batch ID:
37 - Name:
Stream Messages - Dependency:
36 - Go source:
golang/nats-server/server/stream.go - Features:
86(3294-3387mapped IDs) - Tests:
13
If dotnet is not on PATH, use:
DOTNET=/usr/local/share/dotnet/dotnet
Expected production files:
- Modify:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.cs - Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.MessageHeaders.cs - Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.DirectGet.cs - Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.MessagePipeline.cs - Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.Consumers.cs - Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.SnapshotMonitor.cs - Modify:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StreamTypes.cs - Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StreamTypes.MessageCarriers.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/Accounts/Account.StreamRestore.cs
Expected test files:
- Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs - Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamClusterTests2.Impltests.cs - Create:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamClusterTests1.Impltests.cs - Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamFileStoreTests.Impltests.cs - Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/GatewayHandlerTests.Impltests.cs - Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JwtProcessorTests.Impltests.cs - Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/LeafNodeHandlerTests.Impltests.cs - Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests1.Impltests.cs - Create:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RaftNodeTests.Impltests.cs
MANDATORY VERIFICATION PROTOCOL
NON-NEGOTIABLE: Every Batch 37 feature and test must pass this loop. No shortcut status updates.
Dependency Preflight (before any status change)
$DOTNET run --project tools/NatsNet.PortTracker -- batch show 36 --db porting.db
$DOTNET run --project tools/NatsNet.PortTracker -- batch show 37 --db porting.db
$DOTNET run --project tools/NatsNet.PortTracker -- batch ready --db porting.db
Start only when Batch 37 is ready:
$DOTNET run --project tools/NatsNet.PortTracker -- batch start 37 --db porting.db
Capture baseline:
$DOTNET build dotnet/
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/
What Counts as a Real Port
A feature is real only if all are true:
- Mapped method/type exists with non-placeholder behavior.
- Logic uses actual state/inputs (not hardcoded defaults).
- At least one behavioral test exercises that code path.
- No forbidden stub patterns are present.
A test is real only if all are true:
- Arrange/Act/Assert is present.
- It calls production code in
ZB.MOM.NatsNet.Server.*. - Assertions validate behavior from Act output/effects.
- It is not a template/literal stub.
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
- Claim work:
$DOTNET run --project tools/NatsNet.PortTracker -- feature update <feature_id> --status stub --db porting.db
- Add or update focused behavioral test(s) for that feature.
- Implement minimal real logic for the mapped method/type.
- Run Stub Detection Check on changed files.
- Run Build Gate.
- Run targeted Test Gate (specific class/filter for touched area).
- Promote only proven feature IDs to
complete(orverifiedonly after checkpoint evidence).
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
- Claim work:
$DOTNET run --project tools/NatsNet.PortTracker -- test update <test_id> --status stub --db porting.db
- Port full behavior (no template assertions).
- Run single test method:
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~<ClassName>.<MethodName>" --verbosity normal
- Confirm
Passed: 1, Failed: 0(neverPassed: 0). - Run touched class filter.
- Run Stub Detection Check + Build Gate.
- Promote only proven test IDs to
complete(orverifiedonly after checkpoint evidence).
Stub Detection Check (REQUIRED after every feature/test loop)
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|Assert\\.True\\(true\\)|Assert\\.Pass\\(\\)|// TODO|// PLACEHOLDER|var goFile = \"server/|\\.ShouldContain\\(\"Should\"\\)|GetRequiredApiLevel\\(new Dictionary<string, string>\\)\\.ShouldBe\\(string\\.Empty\\)|=>\\s*default;|return\\s+default;|return\\s+null;\\s*$)"
fi
Any match blocks status promotion until fixed or deferred with reason.
Build Gate (REQUIRED)
$DOTNET build dotnet/
Run this:
- after each feature loop
- after each test loop
- before every
batch-update - at every task checkpoint
Test Gate (REQUIRED)
Minimum targeted gates by touched domain:
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~JetStreamEngineTests"
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~JetStreamClusterTests1|FullyQualifiedName~JetStreamClusterTests2"
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~JetStreamFileStoreTests|FullyQualifiedName~RaftNodeTests"
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~GatewayHandlerTests|FullyQualifiedName~JwtProcessorTests|FullyQualifiedName~LeafNodeHandlerTests|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-update. - Never update IDs outside current task scope.
- Never promote to
verifiedwithout checkpoint evidence. - For blocked items, keep
deferredwith explicit reason.
Use:
$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 targeted class test filters for touched classes.
- Run full unit test gate.
- Apply status updates in
<=15ID chunks only. - Commit checkpoint before next task.
ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)
Forbidden Patterns
Forbidden in mapped Batch 37 feature/test work:
throw new NotImplementedException()- Empty mapped method bodies or no-op method shims
- Placeholder comments (
TODO,PLACEHOLDER,later) - Fake-pass assertions (
Assert.True(true),Assert.Pass()) - Template assertions that do not validate behavior:
var goFile = "server/...""<MethodName>".ShouldContain("Should")GetRequiredApiLevel(new Dictionary<string, string>()).ShouldBe(string.Empty)as core assertion
- Constant-return shortcuts in mapped methods without behavioral justification:
=> default;return default;return null;
- Catch-and-ignore patterns that hide failures
Hard Limits
- Max feature group size:
~20IDs. - Max IDs per
feature batch-update:15. - Max IDs per
test batch-update:15. - One active feature loop at a time.
- One active test loop at a time.
- Mandatory checkpoint between every task.
- No
verifiedpromotion without full checkpoint evidence.
If You Get Stuck (REQUIRED)
- Stop on the current ID immediately.
- Do not write placeholder logic or fake assertions.
- Mark item
deferredwith concrete blocker. - Continue with next unblocked item.
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 explicit reason is correct. Stubbed progress is not.
Feature Groups (max ~20 each)
Group A (18): Dedupe and header extraction foundation
IDs:
3294,3295,3296,3297,3298,3299,3300,3301,3302,3303,3304,3305,3306,3307,3308,3310,3311,3312
Group B (16): Scheduling/batch headers and direct-get ingress path
IDs:
3314,3315,3316,3318,3319,3320,3321,3322,3323,3324,3325,3326,3327,3328,3329,3330
Group C (16): Message carriers, publish out queue, and internal loop hooks
IDs:
3331,3332,3333,3334,3335,3336,3337,3338,3339,3340,3341,3342,3343,3345,3346,3347
Group D (17): Consumer registry and interest-state operations
IDs:
3350,3351,3352,3353,3354,3355,3356,3357,3358,3359,3360,3361,3362,3364,3366,3367,3368
Group E (19): Pre-ack, snapshot/restore, monitor/replication checks
IDs:
3369,3370,3371,3372,3373,3374,3375,3376,3377,3378,3379,3380,3381,3382,3383,3384,3385,3386,3387
Test Waves
Wave T1 (5): direct-get and rollup/mirror semantics
IDs:
828,954,987,1642,1643
Wave T2 (4): snapshot/restore and raft recovery paths
IDs:
383,2617,2672,2695
Wave T3 (4): gateway/jwt/leaf/perf regression coverage
IDs:
635,1892,1961,2426
Task 1: Preflight, Baseline, and Batch Start
Files:
- Read:
docs/plans/2026-02-27-batch-37-stream-messages-design.md - Read:
golang/nats-server/server/stream.go
Steps:
- Run dependency preflight and verify Batch 36 completion.
- Start Batch 37.
- Capture baseline build/test evidence.
- Do not change any status without baseline logs.
Task 2: Implement Feature Group A (18 IDs)
Files:
- Modify:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.cs - Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.MessageHeaders.cs
Steps:
- Move Group A IDs to
stubin15 + 3chunks. - Run Per-Feature Verification Loop for each ID.
- Run required stub/build/test gates per ID.
- Promote proven IDs in
<=15chunks. - Run checkpoint protocol.
Task 3: Implement Feature Group B (16 IDs)
Files:
- Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.DirectGet.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.MessagePipeline.cs
Steps:
- Move Group B IDs to
stubin15 + 1chunks. - Execute Per-Feature Verification Loop per ID.
- Run mandatory gates.
- Promote proven IDs in
<=15chunks. - Run checkpoint protocol.
Task 4: Implement Feature Group C (16 IDs)
Files:
- Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.Consumers.cs - Modify:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StreamTypes.cs - Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StreamTypes.MessageCarriers.cs
Steps:
- Move Group C IDs to
stubin15 + 1chunks. - Execute Per-Feature Verification Loop per ID.
- Ensure
JsOutQexists with mapped methods. - Run mandatory gates.
- Promote proven IDs in
<=15chunks. - Run checkpoint protocol.
Task 5: Implement Feature Group D (17 IDs)
Files:
- Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.Consumers.cs
Steps:
- Move Group D IDs to
stubin15 + 2chunks. - Execute Per-Feature Verification Loop per ID.
- Run mandatory gates.
- Promote proven IDs in
<=15chunks. - Run checkpoint protocol.
Task 6: Implement Feature Group E (19 IDs)
Files:
- Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.SnapshotMonitor.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/Accounts/Account.StreamRestore.cs
Steps:
- Move Group E IDs to
stubin15 + 4chunks. - Execute Per-Feature Verification Loop per ID.
- Run mandatory gates.
- Promote proven IDs in
<=15chunks. - Run checkpoint protocol.
Task 7: Port Test Wave T1 (5 IDs)
Files:
- 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:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.cs
Steps:
- Move Wave T1 IDs to
stub. - Execute Per-Test Verification Loop per ID.
- Run mandatory stub/build/class/full test gates.
- Promote proven IDs in one
<=15batch. - Run checkpoint protocol.
Task 8: Port Test Wave T2 (4 IDs)
Files:
- Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamFileStoreTests.Impltests.cs - Create:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RaftNodeTests.Impltests.cs
Steps:
- Move Wave T2 IDs to
stub. - Execute Per-Test Verification Loop per ID.
- Run mandatory gates.
- Promote proven IDs in one
<=15batch. - Run checkpoint protocol.
Task 9: Port Test Wave T3 (4 IDs)
Files:
- Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/GatewayHandlerTests.Impltests.cs - Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JwtProcessorTests.Impltests.cs - Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/LeafNodeHandlerTests.Impltests.cs - Modify:
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests1.Impltests.cs
Steps:
- Move Wave T3 IDs to
stub. - Execute Per-Test Verification Loop per ID.
- Run mandatory gates.
- Promote proven IDs in one
<=15batch. - Run checkpoint protocol.
Task 10: Batch Closeout
Files:
- Modify:
porting.db - Modify:
reports/current.md(via report script output)
Steps:
- Run final stub detection on current diff.
- Run final build gate and full test gate.
- Run dry-run audits for features and tests:
$DOTNET run --project tools/NatsNet.PortTracker -- audit --type features --db porting.db
$DOTNET run --project tools/NatsNet.PortTracker -- audit --type tests --db porting.db
- Complete batch:
$DOTNET run --project tools/NatsNet.PortTracker -- batch complete 37 --db porting.db
- Regenerate summary report:
./reports/generate-report.sh
Plan complete and saved to docs/plans/2026-02-27-batch-37-stream-messages-implementation-plan.md. Two execution options:
- Subagent-Driven (this session) - I dispatch fresh subagent per task, review between tasks, fast iteration.
- Parallel Session (separate) - Open new session with
executeplan, batch execution with checkpoints.
Which approach?