Files
natsnet/docs/plans/2026-02-27-batch-16-client-core-first-half-plan.md
Joseph Doherty f0455a1e45 Add batch plans for batches 6-7, 9-12, 16-17 (rounds 4-7)
Generated design docs and implementation plans via Codex for:
- Batch 6: Opts package-level functions
- Batch 7: Opts class methods + Reload
- Batch 9: Auth, DirStore, OCSP foundations
- Batch 10: OCSP Cache + JS Events
- Batch 11: FileStore Init
- Batch 12: FileStore Recovery
- Batch 16: Client Core (first half)
- Batch 17: Client Core (second half)

All plans include mandatory verification protocol and anti-stub guardrails.
Updated batches.md with file paths and planned status.
2026-02-27 14:56:19 -05:00

16 KiB

Batch 16 (Client Core first half) Implementation Plan

For Codex: REQUIRED SUB-SKILL: Use executeplan to implement this plan task-by-task.

Goal: Implement and verify Batch 16 (server/client.go first half) feature parity in two controlled feature groups (30 features total) and resolve the single tracked test (#2859) with real evidence or explicit deferral.

Architecture: Use a staged porting model: deterministic helper features first, then outbound/parser-state features. Keep ClientConnection as the primary host, reuse existing parser logic in ProtocolParser, and enforce strict per-feature verification loops to prevent stub regressions. Batch status updates happen only after group-level build and test gates.

Tech Stack: .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (porting.db)

Design doc: docs/plans/2026-02-27-batch-16-client-core-first-half-design.md


Batch 16 Working Set

  • Total features: 30
  • Total tests: 1
  • Dependencies: batches 2, 3, 4
  • Go source: golang/nats-server/server/client.go

Feature groups (max size <= 20):

  • Group A (19 features): 387,388,389,390,391,392,393,394,395,396,397,398,402,411,420,421,422,423,424
  • Group B (11 features): 429,430,431,432,456,471,472,473,474,475,476

Tracked test:

  • Test: 2859 (RouteHandlerTests.RouteSlowConsumerRecover_ShouldSucceed)

MANDATORY VERIFICATION PROTOCOL

NON-NEGOTIABLE: Every feature and test in this batch must pass these gates before any verified status update.

What Counts as Real Verification

A feature/test is eligible for verified only when all conditions hold:

  1. Mapped .NET method exists and contains real logic (no placeholder body).
  2. Behavior matches Go intent for the mapped function/test scenario.
  3. Focused related tests run and pass with non-zero executed tests.
  4. Stub scan returns zero hits in touched files.
  5. Group build and group test gates are green.

Per-Feature Verification Loop (REQUIRED for each feature ID)

  1. Read exact Go source range from tracker:
    dotnet run --project tools/NatsNet.PortTracker -- feature show <feature-id> --db porting.db
    
  2. Open Go function in golang/nats-server/server/client.go and capture intended behavior.
  3. Write or update C# implementation in mapped .NET target file.
  4. Run build and related focused tests:
    dotnet build dotnet/
    dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~<RelatedClassOrMethod>" --verbosity normal
    
  5. Verify summary reports at least one executed test and Failed: 0.
  6. Add feature ID to group-ready evidence list only after green build + green focused tests.

Stub Detection Check (REQUIRED after each feature group and test task)

Run on all touched source and test files:

grep -R -n -E "NotImplementedException|TODO|PLACEHOLDER" \
  dotnet/src/ZB.MOM.NatsNet.Server \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests

grep -R -n -E "^[[:space:]]*(public|internal|private|protected)[^;]*\\)\\s*\\{[[:space:]]*\\}$" \
  dotnet/src/ZB.MOM.NatsNet.Server \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests

Any hit in touched files blocks status promotion until fixed or explicitly deferred with reason.

Build Gate (REQUIRED after each feature group)

dotnet build dotnet/

Required: 0 errors.

Test Gate (REQUIRED before marking features verified)

Run all related classes for the group:

dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientConnectionStubFeaturesTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ProtocolParserTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~RouteHandlerTests" --verbosity normal

Required: all relevant runs show Failed: 0 and non-zero executed tests for newly touched scenarios.

Status Update Protocol (REQUIRED)

  1. Max 15 IDs per feature batch-update or test batch-update command.
  2. Status flow per item: deferred/not_started -> stub -> complete -> verified (or deferred with reason).
  3. Every update chunk must have evidence:
    • go source reviewed
    • build output
    • related test output
    • stub scan output
  4. If audit disagrees and logic is proven, use explicit override reason.

Template commands:

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "<<=15 ids>" --set-status stub --db porting.db --execute

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "<<=15 ids>" --set-status complete --db porting.db --execute

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "<<=15 ids>" --set-status verified --db porting.db --execute

Checkpoint Protocol Between Tasks (REQUIRED)

After each major task group (Group A, Group B, test task):

  1. Full build:
    dotnet build dotnet/
    
  2. Full unit tests:
    dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
    
  3. Confirm no new regressions.
  4. Commit before moving to next task.

ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)

Forbidden Patterns

The following are forbidden in touched feature/test code:

  • throw new NotImplementedException()
  • TODO / PLACEHOLDER markers left in executable paths
  • Empty method bodies used as placeholders ({ })
  • Trivial always-pass assertions (Assert.True(true), equivalent fake checks)
  • Wrapper methods that ignore Go behavior and return dummy values

Hard Limits

  • Max 15 IDs per status-update command.
  • Max 1 feature group promoted per verification cycle.
  • Mandatory stub scan + build gate + test gate before each promotion.
  • Mandatory checkpoint commit between task groups.
  • No "temporary stubs" allowed for batch completion.

If You Get Stuck

Do not stub. Use this exact path:

  1. Keep/return blocked feature or test to deferred.
  2. Add explicit reason via override (specific missing infra/dependency).
  3. Commit only proven items.
  4. Continue with next unblocked item in current group.

Examples:

dotnet run --project tools/NatsNet.PortTracker -- \
  feature update <id> --status deferred --db porting.db --override "blocked: requires <specific dependency>"

dotnet run --project tools/NatsNet.PortTracker -- \
  test update <id> --status deferred --db porting.db --override "blocked: requires <specific runtime/infra>"

Task 1: Preflight, Dependency Gate, and Mapping Hygiene

Files:

  • Modify (if needed): porting.db mappings for impossible enum-hosted method targets
  • Inspect: golang/nats-server/server/client.go

Step 1: Confirm batch readiness

dotnet run --project tools/NatsNet.PortTracker -- batch ready --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- batch show 16 --db porting.db

Expected: Batch 16 appears as ready. If not ready, stop execution and keep this batch pending.

Step 2: Start batch

dotnet run --project tools/NatsNet.PortTracker -- batch start 16 --db porting.db

Step 3: Reconcile method-host mappings where class type cannot host methods

Focus on enum-hosted mappings (ClientFlags, ReadCacheFlags, WriteTimeoutPolicy.String).
Use feature map / feature batch-map only if required for auditable method hosting.

Step 4: Commit mapping-only changes (if any)

git add porting.db
git commit -m "chore(batch16): reconcile feature mappings for verifiable method hosts"

Task 2: Group A Features (19) - Helpers, Flags, Permissions, Expiration

Feature IDs: 387,388,389,390,391,392,393,394,395,396,397,398,402,411,420,421,422,423,424

Files:

  • Modify: dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs
  • Modify: dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs
  • Modify: dotnet/src/ZB.MOM.NatsNet.Server/ServerOptionTypes.cs
  • Modify: dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientTests.cs
  • Modify: dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs

Step 1: Mark Group A as stub in chunks <= 15

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "387,388,389,390,391,392,393,394,395,396,397,398,402,411,420" --set-status stub --db porting.db --execute

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "421,422,423,424" --set-status stub --db porting.db --execute

Step 2: Write failing tests for Group A behavior

  • Add/extend tests for:
    • internal-client classification
    • flag set/clear/isSet/setIfNotSet semantics
    • timeout policy string value
    • nb pool get/put behavior
    • TLS state accessor and kind accessor
    • public/deny permissions merge behavior
    • expiration and deny-filter loading behavior

Step 3: Run focused tests and confirm failures

dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientConnectionStubFeaturesTests" --verbosity normal

Step 4: Implement minimal behavior-faithful Group A production code

Apply per-feature loop from protocol section for all 19 IDs.

Step 5: Run focused tests until green

Re-run the two related classes and verify Failed: 0.

Step 6: Mandatory stub scan + build gate

Run required stub and build commands from protocol section.

Step 7: Promote Group A statuses with evidence (<=15 IDs/chunk)

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "387,388,389,390,391,392,393,394,395,396,397,398,402,411,420" --set-status complete --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "421,422,423,424" --set-status complete --db porting.db --execute

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "387,388,389,390,391,392,393,394,395,396,397,398,402,411,420" --set-status verified --db porting.db --execute
dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "421,422,423,424" --set-status verified --db porting.db --execute

Step 8: Checkpoint protocol + commit

git add dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs \
        dotnet/src/ZB.MOM.NatsNet.Server/ClientTypes.cs \
        dotnet/src/ZB.MOM.NatsNet.Server/ServerOptionTypes.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientTests.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs \
        porting.db

git commit -m "feat(batch16): port client helper and permission core features"

Task 3: Group B Features (11) - Outbound Pipeline and Pub/Sub Parsing

Feature IDs: 429,430,431,432,456,471,472,473,474,475,476

Files:

  • Modify: dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs
  • Modify: dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProtocolParser.cs (only if parser helper exposure is needed)
  • Modify: dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs
  • Modify: dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Protocol/ProtocolParserTests.cs

Step 1: Mark Group B as stub

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "429,430,431,432,456,471,472,473,474,475,476" --set-status stub --db porting.db --execute

Step 2: Write failing tests for outbound and parser wrappers

  • Outbound queue growth/chunking and pending-byte accounting.
  • Flush behavior under partial writes and timeout error paths.
  • HandleWriteTimeout and MarkConnAsClosed reason-specific transitions.
  • ProcessHeaderPub, ProcessPub, SplitArg, ParseSub, ProcessSub, ProcessSubEx behavior.

Step 3: Run focused tests and confirm failures

dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ClientConnectionStubFeaturesTests" --verbosity normal
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --filter "FullyQualifiedName~ProtocolParserTests" --verbosity normal

Step 4: Implement Group B features with per-feature verification loop

Port from Go source ranges, reusing ProtocolParser behavior where valid.

Step 5: Re-run focused tests until green

Same two test runs, verify Failed: 0.

Step 6: Stub scan + build gate + related test gate

Run protocol-mandated commands.

Step 7: Promote Group B statuses

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "429,430,431,432,456,471,472,473,474,475,476" --set-status complete --db porting.db --execute

dotnet run --project tools/NatsNet.PortTracker -- \
  feature batch-update --ids "429,430,431,432,456,471,472,473,474,475,476" --set-status verified --db porting.db --execute

Step 8: Checkpoint protocol + commit

git add dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs \
        dotnet/src/ZB.MOM.NatsNet.Server/Protocol/ProtocolParser.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ClientConnectionStubFeaturesTests.cs \
        dotnet/tests/ZB.MOM.NatsNet.Server.Tests/Protocol/ProtocolParserTests.cs \
        porting.db

git commit -m "feat(batch16): port outbound and parser-facing client core features"

Task 4: Batch Test #2859 (TestRouteSlowConsumerRecover)

Test ID: 2859

Files:

  • Modify: dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs
  • Inspect dependencies via porting.db before status decision

Step 1: Mark test as stub only if implementation attempt begins

dotnet run --project tools/NatsNet.PortTracker -- \
  test update 2859 --status stub --db porting.db

Step 2: Port Go test intent to C# and run focused test

dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
  --filter "FullyQualifiedName~RouteHandlerTests.RouteSlowConsumerRecover_ShouldSucceed" \
  --verbosity normal

Step 3: Decision gate

  • If test is green with real assertions and real behavior coverage:
    • set complete, then verified.
  • If blocked by unmet runtime/dependency constraints:
    • set back to deferred with explicit reason (for example unresolved dependency #1207 or missing route/network harness behavior).

Step 4: Apply status update with evidence

dotnet run --project tools/NatsNet.PortTracker -- \
  test update 2859 --status verified --db porting.db

or

dotnet run --project tools/NatsNet.PortTracker -- \
  test update 2859 --status deferred --db porting.db --override "blocked: <specific reason>"

Step 5: Checkpoint protocol + commit

git add dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/RouteHandlerTests.Impltests.cs porting.db
git commit -m "test(batch16): resolve route slow-consumer recover status with evidence"

Task 5: Batch 16 Final Verification and Closure

Files:

  • Modify: porting.db
  • Generate: reports/current.md (via report generation script)

Step 1: Run full verification

dotnet build dotnet/
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
dotnet run --project tools/NatsNet.PortTracker -- batch show 16 --db porting.db

Step 2: Ensure all Batch 16 items are verified, complete, or explicit deferred with reason

If anything is still stub, stop and resolve before completion.

Step 3: Complete batch

dotnet run --project tools/NatsNet.PortTracker -- batch complete 16 --db porting.db

Step 4: Refresh report and final commit

./reports/generate-report.sh
git add porting.db reports/current.md reports/
git commit -m "chore(batch16): complete client core first-half verification cycle"