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.
7.5 KiB
Batch 36 Stream Lifecycle Design
Date: 2026-02-27
Batch: 36 (Stream Lifecycle)
Scope: 92 features + 53 unit tests
Dependencies: Batches 8, 11, 12, 13, 14, 15, 28
Go source: golang/nats-server/server/stream.go (focus through ~line 4600)
Problem
Batch 36 is the lifecycle/core control plane for JetStream streams: stream creation, assignment, config validation/update, purge/delete flows, mirror/source setup and message processing, and internal subscriptions. This batch is a gating dependency for Batch 37 (Stream Messages) and Batch 38 (Consumer Lifecycle), so fake progress here creates downstream breakage.
The current .NET surface is materially under-ported for this area:
- Batch 36 features are all
deferred. - Most mapped methods are missing from source classes.
- Existing
ImplBacklogtests for related classes are largely placeholder-style and need replacement with behavior checks.
Context Findings
Required command outputs
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch show 36 --db porting.db- Status:
pending - Features:
92(3196-3293with gaps) - Tests:
53 - Depends on:
8,11,12,13,14,15,28 - Go file:
server/stream.go
- Status:
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch list --db porting.db- Confirms chain:
36 -> 37,38
- Confirms chain:
/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db- Overall progress:
1924/6942 (27.7%)
- Overall progress:
Environment note: dotnet is not on PATH in this shell. Use /usr/local/share/dotnet/dotnet explicitly.
Feature ownership split (from porting.db)
NatsStream: 76Account: 4PersistModeType: 3StreamSourceInfo: 2StreamSource: 2JsAccount: 2NatsServer: 1InMsg: 1ExternalStream: 1
Test split (from porting.db)
JetStreamEngineTests: 35NatsConsumerTests: 4JetStreamClusterTests1: 3JetStreamClusterTests2: 4JetStreamClusterTests3: 3ConcurrencyTests1: 2JetStreamFileStoreTests: 1StorageEngineTests: 1
Additional finding: JetStreamClusterTests1.Impltests.cs and JetStreamClusterTests3.Impltests.cs do not currently exist and must be created.
Approaches
Approach A: Single-file port in existing files only
Port all methods directly into existing files (NatsStream.cs, Account.cs, JetStreamTypes.cs, etc.) without structural splits.
- Pros: minimal file churn.
- Cons: high merge risk, hard reviewability, and poor fault isolation for 76
NatsStreammethods.
Approach B (Recommended): Lifecycle-focused partial-file decomposition + staged verification
Keep mapped owning classes intact but split implementation by concern into new partial files for stream lifecycle/mirror/source/subscription paths. Execute in bounded feature groups and test waves with strict evidence gates.
- Pros: manageable review units, clearer ownership, better checkpointing and rollback, aligns with anti-stub guardrails.
- Cons: requires adding partial declarations where classes are currently non-partial.
Approach C: Test-first broad wave before feature completion
Attempt to port all 53 tests up front to drive implementation.
- Pros: fast behavior pressure.
- Cons: most tests depend on missing lifecycle internals and will churn heavily; expensive red-state noise.
Decision: Approach B.
Proposed Design
1. Code organization strategy
Use concern-oriented partial files while preserving mapped class ownership:
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.cs(retain core type; convert topartial)- Create
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.Lifecycle.cs - Create
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.Mirror.cs - Create
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.Source.cs - Create
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/NatsStream.Subscriptions.cs dotnet/src/ZB.MOM.NatsNet.Server/Accounts/Account.cs(convert topartial)- Create
dotnet/src/ZB.MOM.NatsNet.Server/Accounts/Account.StreamLifecycle.cs dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamTypes.cs(forJsAccount, convert class topartialif split)- Create
dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JsAccount.StreamLifecycle.cs dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.csorNatsServer.*.cspartial forCheckStreamCfgdotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreTypes.csandStreamTypes.csforPersistModeType,ExternalStream.Domain,StreamSource/StreamSourceInfo,InMsg
2. Functional decomposition
- Config and creation path:
PersistModeType,ExternalStream.Domain,Account.AddStream*,StreamSource.ComposeIName/SetIndexName,NatsServer.CheckStreamCfg,JsAccount.ConfigUpdateCheck,NatsStream.Update*. - State/advisory path: leader checks, sequence counters (
CLFS), created time, create/update/delete advisories, purge/delete/erase behavior. - Mirror path: mirror setup/retry/cancel, inbound mirror flow-control handling, lag tracking, retry backoff.
- Source path: source setup/retry/cancel, shared source message pump, source headers, start-sequence reconstruction.
- Subscription/internal path: stream/direct/mirror-direct subscriptions, source consumer stop/unsubscribe, batching cleanup, internal subscribe helpers.
3. Test design
Port test IDs in waves tied to implemented behavior:
- Wave 1: file store + cluster/meta + consumer API basics (15 tests)
- Wave 2-4:
JetStreamEngineTestsheavy stream lifecycle scenarios (12/12/14)
Test files:
- 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
4. Verification and risk controls (design-level)
- Per-feature and per-test loops are mandatory before status promotion.
- Stub scans are mandatory after each loop and at each checkpoint.
- Build and test gates are mandatory before every status batch update.
- Status updates are chunked to max 15 IDs.
- If blocked: remain
deferredwith explicit reason, never placeholder implementation.
Feature Grouping (for implementation plan)
- Group A (20): IDs
3196-3219(actual mapped IDs, 20 total) - Group B (20): IDs
3220-3240(actual mapped IDs, 20 total) - Group C (20): IDs
3241-3261(actual mapped IDs, 20 total) - Group D (20): IDs
3262-3281(actual mapped IDs, 20 total) - Group E (12): IDs
3282-3293(actual mapped IDs, 12 total)
Constraints
- Planning only in this session; no implementation execution.
- Must preserve .NET standards (
xUnit 3,Shouldly,NSubstitute, nullable, naming conventions). - Must avoid fake-pass tests and placeholder feature bodies.
Non-Goals
- Executing Batch 36 implementation in this session.
- Expanding scope beyond Batch 36 mapped features/tests.
- Building new integration infrastructure not required by mapped unit tests.