# 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 `ImplBacklog` tests 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-3293` with gaps)
  - Tests: `53`
  - Depends on: `8,11,12,13,14,15,28`
  - Go file: `server/stream.go`
- `/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- batch list --db porting.db`
  - Confirms chain: `36 -> 37,38`
- `/usr/local/share/dotnet/dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db`
  - Overall progress: `1924/6942 (27.7%)`

Environment note: `dotnet` is not on `PATH` in this shell. Use `/usr/local/share/dotnet/dotnet` explicitly.

### Feature ownership split (from `porting.db`)

- `NatsStream`: 76
- `Account`: 4
- `PersistModeType`: 3
- `StreamSourceInfo`: 2
- `StreamSource`: 2
- `JsAccount`: 2
- `NatsServer`: 1
- `InMsg`: 1
- `ExternalStream`: 1

### Test split (from `porting.db`)

- `JetStreamEngineTests`: 35
- `NatsConsumerTests`: 4
- `JetStreamClusterTests1`: 3
- `JetStreamClusterTests2`: 4
- `JetStreamClusterTests3`: 3
- `ConcurrencyTests1`: 2
- `JetStreamFileStoreTests`: 1
- `StorageEngineTests`: 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 `NatsStream` methods.

### 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 to `partial`)
- 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 to `partial`)
- Create `dotnet/src/ZB.MOM.NatsNet.Server/Accounts/Account.StreamLifecycle.cs`
- `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JetStreamTypes.cs` (for `JsAccount`, convert class to `partial` if split)
- Create `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/JsAccount.StreamLifecycle.cs`
- `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.cs` or `NatsServer.*.cs` partial for `CheckStreamCfg`
- `dotnet/src/ZB.MOM.NatsNet.Server/JetStream/StoreTypes.cs` and `StreamTypes.cs` for `PersistModeType`, `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: `JetStreamEngineTests` heavy 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 `deferred` with 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.
