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 40 MQTT Server/JSA Implementation Plan
For Codex: REQUIRED SUB-SKILL: Use
executeplanto implement this plan task-by-task.
Goal: Port and verify Batch 40 (MQTT Server/JSA) from server/mqtt.go so all 78 mapped features and 323 mapped tests are either genuinely implemented/verified or explicitly deferred with concrete blocker reasons.
Architecture: Implement Batch 40 in four feature groups (20/20/20/18) aligned to MQTT bootstrap/parser, JSA adapter, account session manager, and session persistence/retained-message codec behavior. After each feature group, execute mapped test waves with strict evidence 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-40-mqtt-server-jsa-design.md
Batch 40 Scope
- Batch ID:
40 - Name:
MQTT Server/JSA - Dependencies:
19,27 - Go source:
golang/nats-server/server/mqtt.go - Features:
78 - Tests:
323
If dotnet is not on PATH, use:
DOTNET=/usr/local/share/dotnet/dotnet
Expected production files (create/modify as needed):
dotnet/src/ZB.MOM.NatsNet.Server/Mqtt/MqttHandler.csdotnet/src/ZB.MOM.NatsNet.Server/Mqtt/MqttTypes.csdotnet/src/ZB.MOM.NatsNet.Server/Mqtt/MqttConstants.csdotnet/src/ZB.MOM.NatsNet.Server/NatsServer*.cs(MQTT partials)dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs(or MQTT partial)dotnet/src/ZB.MOM.NatsNet.Server/Mqtt/MqttJetStreamAdapter*.cs(new if absent)dotnet/src/ZB.MOM.NatsNet.Server/Mqtt/MqttAccountSessionManager*.cs(new/partials)dotnet/src/ZB.MOM.NatsNet.Server/Mqtt/MqttSession*.cs(new/partials)
Expected test files (create/modify as needed):
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MqttHandlerTests.Impltests.csdotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsConsumerTests.Impltests.csdotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamBatchingTests.Impltests.csdotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamEngineTests.Impltests.csdotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamClusterTests2.Impltests.csdotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests1.Impltests.csdotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests2.Impltests.csdotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/MessageTracerTests.Impltests.csdotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConfigReloaderTests.Impltests.csdotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamJwtTests.Impltests.csdotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamFileStoreTests.Impltests.csdotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamLeafNodeTests.Impltests.cs- Create missing mapped backlog files as needed:
JetStreamClusterTests1.Impltests.csJetStreamClusterTests3.Impltests.csJetStreamClusterTests4.Impltests.csJetStreamSuperClusterTests.Impltests.csJetStreamClusterLongTests.Impltests.csJetStreamSourcingScalingTests.Impltests.csJetStreamBenchmarks.Impltests.cs
MANDATORY VERIFICATION PROTOCOL
NON-NEGOTIABLE: Every Batch 40 feature and test must pass this protocol. No shortcuts.
1. Dependency Preflight and Baseline
Run before any status changes:
$DOTNET run --project tools/NatsNet.PortTracker -- batch show 19 --db porting.db
$DOTNET run --project tools/NatsNet.PortTracker -- batch show 27 --db porting.db
$DOTNET run --project tools/NatsNet.PortTracker -- batch show 40 --db porting.db
$DOTNET run --project tools/NatsNet.PortTracker -- batch ready --db porting.db
Start batch only when ready:
$DOTNET run --project tools/NatsNet.PortTracker -- batch start 40 --db porting.db
Capture baseline:
$DOTNET build dotnet/
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/
2. Per-Feature Verification Loop (REQUIRED for each feature ID)
- Inspect mapping and Go source intent:
$DOTNET run --project tools/NatsNet.PortTracker -- feature show <feature_id> --db porting.db
- Claim the feature:
$DOTNET run --project tools/NatsNet.PortTracker -- feature update <feature_id> --status stub --db porting.db
- Add/adjust at least one behavioral test path for this feature.
- Implement minimal correct logic (no placeholders).
- Run Stub Detection Check.
- Run Build Gate.
- Run relevant Test Gate filters.
- Promote feature to
completeonly after evidence is captured. - Promote to
verifiedonly during task checkpoint after full gates pass.
3. Per-Test Verification Loop (REQUIRED for each test ID)
- Inspect mapped test:
$DOTNET run --project tools/NatsNet.PortTracker -- test show <test_id> --db porting.db
- Claim the test:
$DOTNET run --project tools/NatsNet.PortTracker -- test update <test_id> --status stub --db porting.db
- Port full Arrange/Act/Assert behavior.
- Run single-test filter and verify discovery:
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~<ClassName>.<MethodName>" --verbosity normal
- Confirm
Passed: 1, Failed: 0(never acceptPassed: 0). - Run class-level filter.
- Run Stub Detection Check and Build Gate.
- Promote test to
complete; deferverifiedto checkpoint.
4. Stub Detection Check (REQUIRED)
Run after each feature loop, each test loop, and before any status promotion:
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\(\)|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 explicitly deferred.
5. Build Gate (REQUIRED)
$DOTNET build dotnet/
Run after each feature loop, each test loop, before any batch-update, and at every task checkpoint.
6. Test Gate (REQUIRED)
Run smallest relevant filters continuously; run all sections at checkpoints.
MQTT-first filter:
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ImplBacklog.MqttHandlerTests|FullyQualifiedName~ImplBacklog.MessageTracerTests|FullyQualifiedName~ImplBacklog.ConfigReloaderTests"
Deterministic JS/consumer filter:
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ImplBacklog.NatsConsumerTests|FullyQualifiedName~ImplBacklog.JetStreamBatchingTests|FullyQualifiedName~ImplBacklog.JetStreamEngineTests|FullyQualifiedName~ImplBacklog.JetStreamJwtTests|FullyQualifiedName~ImplBacklog.JetStreamFileStoreTests|FullyQualifiedName~ImplBacklog.JetStreamLeafNodeTests"
Cluster/concurrency filter:
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
--filter "FullyQualifiedName~ImplBacklog.JetStreamClusterTests1|FullyQualifiedName~ImplBacklog.JetStreamClusterTests2|FullyQualifiedName~ImplBacklog.JetStreamClusterTests3|FullyQualifiedName~ImplBacklog.JetStreamClusterTests4|FullyQualifiedName~ImplBacklog.JetStreamSuperClusterTests|FullyQualifiedName~ImplBacklog.JetStreamClusterLongTests|FullyQualifiedName~ImplBacklog.JetStreamSourcingScalingTests|FullyQualifiedName~ImplBacklog.ConcurrencyTests1|FullyQualifiedName~ImplBacklog.ConcurrencyTests2|FullyQualifiedName~ImplBacklog.JetStreamBenchmarks"
Checkpoint/full gate:
$DOTNET test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/
7. Status Update Protocol (HARD LIMIT: 15 IDs per batch-update)
- Never send more than
15IDs perfeature batch-updatecommand. - Never send more than
15IDs pertest batch-updatecommand. - Never promote
verifiedwithout checkpoint evidence. - Never update IDs outside active task scope.
- Deferred items must include explicit blocker 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
8. Checkpoint Protocol Between Tasks (REQUIRED)
Before moving to the next task:
- Run Stub Detection Check.
- Run Build Gate.
- Run Test Gate (targeted filters + full unit suite).
- Apply status updates in <=15-ID chunks only.
- Run:
$DOTNET run --project tools/NatsNet.PortTracker -- batch show 40 --db porting.db
- Commit checkpoint before continuing.
ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)
Forbidden Patterns
The following patterns are forbidden for Batch 40 feature/test work:
throw new NotImplementedException(...)in mapped feature methods- Empty method bodies for mapped features
TODO/PLACEHOLDERmarkers left in mapped logicAssert.True(true)/Assert.Pass()- Placeholder template assertions disconnected from behavior:
var goFile = "server/...""<name>".ShouldContain("Should")GetRequiredApiLevel(new Dictionary<string, string>()).ShouldBe(string.Empty)as primary assertion
- Placeholder return shortcuts in mapped code:
=> default;return default;return null;
Hard Limits
- Max feature group size:
~20features. - 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 tasks.
- No
verifiedpromotion without checkpoint evidence.
If You Get Stuck (REQUIRED)
- Stop current item immediately.
- Do not stub or fake-pass.
- Mark item
deferredwith explicit blocker reason. - Continue with next unblocked feature/test.
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 concrete reason is correct. Stubs are not.
Feature Groups (max ~20 each)
Group A (20): bootstrap/parser/auth/JSA request foundations
IDs:
2252,2253,2254,2255,2257,2258,2259,2260,2261,2262,2263,2264,2265,2266,2267,2268,2269,2270,2271,2272
Group B (20): JSA operations + reply processing bridge
IDs:
2273,2274,2275,2276,2277,2278,2279,2280,2281,2282,2283,2284,2285,2286,2287,2288,2289,2290,2291,2292
Group C (20): account session manager retained/subscription core
IDs:
2293,2294,2295,2296,2297,2298,2299,2300,2301,2302,2303,2304,2305,2306,2307,2308,2309,2310,2311,2312
Group D (18): retained encode/decode + session lifecycle/publish tracking
IDs:
2313,2314,2315,2316,2317,2318,2319,2320,2321,2322,2323,2324,2325,2326,2327,2328,2329,2330
Test Waves (323 total)
- Wave T1 (51):
MqttHandlerTests,MessageTracerTests,ConfigReloaderTests - Wave T2 (89):
NatsConsumerTests,JetStreamBatchingTests,JetStreamEngineTests,JetStreamJwtTests,JetStreamFileStoreTests,JetStreamLeafNodeTests - Wave T3 (70):
JetStreamClusterTests1,JetStreamClusterTests2 - Wave T4 (77):
JetStreamClusterTests3,JetStreamClusterTests4,JetStreamSuperClusterTests,JetStreamClusterLongTests,JetStreamSourcingScalingTests - Wave T5 (36):
ConcurrencyTests1,ConcurrencyTests2,JetStreamBenchmarks
ID extraction helper:
sqlite3 -header -column porting.db "
SELECT bt.test_id AS id, t.dotnet_class, t.name
FROM batch_tests bt
JOIN unit_tests t ON t.id=bt.test_id
WHERE bt.batch_id=40
AND t.dotnet_class IN (<wave classes here>)
ORDER BY bt.test_id;"
Task 1: Preflight, Mapping Alignment, and Baseline
Files:
- Read:
docs/plans/2026-02-27-batch-40-mqtt-server-jsa-design.md - Read:
golang/nats-server/server/mqtt.go - Modify (if needed):
dotnet/src/ZB.MOM.NatsNet.Server/Mqtt/*for class/method mapping alignment
Steps:
- Run dependency preflight and start Batch 40.
- Confirm mapped class/method targets compile (notably
MqttJetStreamAdapter). - Capture baseline build + full unit test counts.
- Run checkpoint protocol.
Task 2: Implement Feature Group A + Test Wave T1
Files:
- Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer*.cs(MQTT methods) - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection*.cs(MQTT parse/trace helpers) - Modify:
dotnet/src/ZB.MOM.NatsNet.Server/Mqtt/MqttHandler.cs - Modify tests:
ImplBacklog/MqttHandlerTests.Impltests.cs,ImplBacklog/MessageTracerTests.Impltests.cs,ImplBacklog/ConfigReloaderTests.Impltests.cs
Steps:
- Process each Group A feature through per-feature loop.
- Port/verify Wave T1 tests through per-test loop.
- Apply status updates in <=15-ID chunks.
- Run checkpoint protocol and commit.
Task 3: Implement Feature Group B + Test Wave T2 (Part 1)
Files:
- Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/Mqtt/MqttJetStreamAdapter*.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/Mqtt/MqttAccountSessionManager*.cs - Modify tests:
ImplBacklog/JetStreamBatchingTests.Impltests.cs,ImplBacklog/JetStreamEngineTests.Impltests.cs,ImplBacklog/NatsConsumerTests.Impltests.cs,ImplBacklog/JetStreamJwtTests.Impltests.cs,ImplBacklog/JetStreamFileStoreTests.Impltests.cs,ImplBacklog/JetStreamLeafNodeTests.Impltests.cs
Steps:
- Process each Group B feature through per-feature loop.
- Port deterministic tests from Wave T2 first; defer runtime-blocked tests with reason.
- Apply status updates in <=15-ID chunks.
- Run checkpoint protocol and commit.
Task 4: Implement Feature Group C + Test Wave T3
Files:
- Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/Mqtt/MqttAccountSessionManager*.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/Mqtt/MqttSession*.cs - Modify/Create tests:
ImplBacklog/JetStreamClusterTests1.Impltests.cs,ImplBacklog/JetStreamClusterTests2.Impltests.cs
Steps:
- Process each Group C feature through per-feature loop.
- Execute Wave T3 with strict infra eligibility checks.
- Defer cluster-runtime blocked tests explicitly; do not stub.
- Apply status updates in <=15-ID chunks.
- Run checkpoint protocol and commit.
Task 5: Implement Feature Group D + Test Waves T4/T5
Files:
- Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/Mqtt/MqttHandler.cs - Modify/Create:
dotnet/src/ZB.MOM.NatsNet.Server/Mqtt/MqttSession*.cs - Modify/Create tests:
ImplBacklog/JetStreamClusterTests3.Impltests.csImplBacklog/JetStreamClusterTests4.Impltests.csImplBacklog/JetStreamSuperClusterTests.Impltests.csImplBacklog/JetStreamClusterLongTests.Impltests.csImplBacklog/JetStreamSourcingScalingTests.Impltests.csImplBacklog/ConcurrencyTests1.Impltests.csImplBacklog/ConcurrencyTests2.Impltests.csImplBacklog/JetStreamBenchmarks.Impltests.cs
Steps:
- Process each Group D feature through per-feature loop.
- Execute Waves T4/T5 with strict defer-with-reason handling.
- Apply status updates in <=15-ID chunks.
- Run checkpoint protocol and commit.
Task 6: Batch 40 Closure Verification
Files:
- Modify:
porting.db - Generate:
reports/current.md(via report script)
Steps:
- Run final stub detection across changed MQTT source/test files.
- Run
buildand full unit test suite. - Verify Batch 40 state:
$DOTNET run --project tools/NatsNet.PortTracker -- batch show 40 --db porting.db
$DOTNET run --project tools/NatsNet.PortTracker -- report summary --db porting.db
- Generate updated report:
./reports/generate-report.sh
- Final checkpoint commit.