Files
natsnet/AGENTS.md
Joseph Doherty c5e0416793 Add batch commands to PortTracker CLI and migrate batch tables into porting.db
Implements batch list/show/ready/next/start/complete commands with dependency
validation, migrates 42 implementation batches (2377 features, 2087 tests) from
porting_batches.db into the live tracking database, and documents the batch
workflow in AGENTS.md.
2026-02-27 13:02:43 -05:00

8.9 KiB

AGENTS.md

Project Summary

This project ports the NATS messaging server from Go to .NET 10 C#. The Go source (~130K LOC) is the reference at golang/nats-server/. Porting progress is tracked in an SQLite database (porting.db) managed by the PortTracker CLI tool.

Folder Layout

natsnet/
├── golang/nats-server/                  # Go source (read-only reference)
├── dotnet/
│   ├── src/ZB.MOM.NatsNet.Server/       # Main server library
│   ├── src/ZB.MOM.NatsNet.Server.Host/  # Host entry point
│   └── tests/
│       ├── ZB.MOM.NatsNet.Server.Tests/              # Unit tests
│       └── ZB.MOM.NatsNet.Server.IntegrationTests/   # Integration tests
├── tools/NatsNet.PortTracker/           # CLI tracking tool
├── docs/standards/dotnet-standards.md   # .NET coding standards (MUST follow)
├── docs/plans/phases/                   # Phase instruction guides
├── reports/current.md                   # Latest porting status
├── porting.db                           # SQLite tracking database
└── porting-schema.sql                   # Database schema

Build and Test

# Build the solution
dotnet build dotnet/

# Run all unit tests
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/

# Run filtered tests (by namespace/class)
dotnet test --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.Protocol" \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests/

# Run integration tests
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/

# Generate porting report
./reports/generate-report.sh

.NET Coding Standards

MUST follow all rules in docs/standards/dotnet-standards.md.

Critical rules (non-negotiable):

  • .NET 10, C# latest, nullable enabled
  • xUnit 3 + Shouldly + NSubstitute for testing
  • NEVER use FluentAssertions or Moq — these are forbidden
  • PascalCase for public members, _camelCase for private fields
  • File-scoped namespaces: ZB.MOM.NatsNet.Server.[Module]
  • Use CancellationToken on all async signatures
  • Use ReadOnlySpan<byte> on hot paths
  • Test naming: [Method]_[Scenario]_[Expected]
  • Test class naming: [ClassName]Tests
  • Structured logging with ILogger<T> and LogContext.PushProperty

PortTracker CLI

All tracking commands use this base:

dotnet run --project tools/NatsNet.PortTracker -- <command> --db porting.db

Querying

Command Purpose
report summary Show overall porting progress
dependency ready List items ready to port (no unported deps)
dependency blocked List items blocked by unported deps
feature list --status <s> List features by status
feature list --module <id> List features in a module
feature show <id> Show feature details (Go source path, .NET target)
test list --status <s> List tests by status
test show <id> Show test details
module list List all modules
module show <id> Show module with its features and tests

Updating Status

Command Purpose
feature update <id> --status <s> Update one feature
feature batch-update --ids "1-10" --set-status <s> --execute Bulk update features
test update <id> --status <s> Update one test
test batch-update --ids "1-10" --set-status <s> --execute Bulk update tests
module update <id> --status <s> Update module status
batch start <id> Mark batch as in-progress (validates deps)
batch complete <id> Mark batch as complete (validates all items done)

Batch Querying

Command Purpose
batch list List all implementation batches
batch list --status <s> Filter batches by status
batch show <id> Show batch details with features and tests
batch ready List batches ready to start (deps met)
batch next Show next recommended batch

Audit Verification

Status updates are verified against Roslyn audit results. If the audit disagrees with your requested status, add --override "reason" to force it.

feature update 42 --status verified --override "manually verified logic"

Audit Commands

Command Purpose
audit --type features Dry-run audit of features against .NET source
audit --type tests Dry-run audit of tests against test project
audit --type features --execute Apply audit classifications to DB
audit --type tests --execute Apply test audit classifications to DB

Valid Statuses

not_started → stub → complete → verified
                 └→ n_a (not applicable)
                 └→ deferred (blocked, needs server infra)

Batch ID Syntax

--ids accepts: ranges "100-200", lists "1,5,10", or mixed "1-5,10,20-25".

All batch commands default to dry-run. Add --execute to apply.

Porting Workflow

Finding Work

  1. Query for features ready to port:
dotnet run --project tools/NatsNet.PortTracker -- dependency ready --db porting.db
  1. Or find deferred/stub features in a specific module:
dotnet run --project tools/NatsNet.PortTracker -- feature list --module <id> --status deferred --db porting.db
  1. To find tests that need implementing:
dotnet run --project tools/NatsNet.PortTracker -- test list --status stub --db porting.db
dotnet run --project tools/NatsNet.PortTracker -- test list --status deferred --db porting.db

Batch Workflow

Work is organized into 42 implementation batches with dependency ordering. Use batches to find and track work:

  1. Find the next batchbatch next returns the lowest-priority ready batch:
dotnet run --project tools/NatsNet.PortTracker -- batch next --db porting.db
  1. Start it — marks the batch as in-progress (validates dependencies are met):
dotnet run --project tools/NatsNet.PortTracker -- batch start <id> --db porting.db
  1. See all items — lists every feature and test in the batch:
dotnet run --project tools/NatsNet.PortTracker -- batch show <id> --db porting.db
  1. Implement features first, then write/port the tests.

  2. Complete it — validates all features and tests are verified/complete/n_a:

dotnet run --project tools/NatsNet.PortTracker -- batch complete <id> --db porting.db

The system enforces dependency ordering — you cannot start a batch until all batches it depends on are complete. Use batch ready to see all currently available batches.

Implementing a Feature

  1. Claim it — mark as stub before starting:
dotnet run --project tools/NatsNet.PortTracker -- feature update <id> --status stub --db porting.db
  1. Read the Go source — use feature show <id> to get the Go file path and line numbers, then read the Go implementation.

  2. Write idiomatic C# — translate intent, not lines:

    • Use async/await, not goroutine translations
    • Use Channel<T> for Go channels
    • Use CancellationToken for context.Context
    • Use ReadOnlySpan<byte> on hot paths
    • Use Lock (C# 13) for sync.Mutex
    • Use ReaderWriterLockSlim for sync.RWMutex
  3. Ensure it compiles — run dotnet build dotnet/

  4. Mark complete:

dotnet run --project tools/NatsNet.PortTracker -- feature update <id> --status complete --db porting.db

Implementing a Unit Test

  1. Read the Go test — use test show <id> to get Go source location.
  2. Read the corresponding .NET feature to understand the API surface.
  3. Write the test in dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ using xUnit 3 + Shouldly + NSubstitute.
  4. Run it:
dotnet test --filter "FullyQualifiedName~TestClassName" \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests/
  1. Mark verified (if passing):
dotnet run --project tools/NatsNet.PortTracker -- test update <id> --status verified --db porting.db

After Completing Work

  1. Run affected tests to verify nothing broke.
  2. Update DB status for all items you changed.
  3. Check what's newly unblocked:
dotnet run --project tools/NatsNet.PortTracker -- dependency ready --db porting.db
  1. Generate updated report:
./reports/generate-report.sh

Go to .NET Translation Reference

Go Pattern .NET Equivalent
goroutine Task.Run or async/await
chan T Channel<T>
select Task.WhenAny
sync.Mutex Lock (C# 13)
sync.RWMutex ReaderWriterLockSlim
sync.WaitGroup Task.WhenAll or CountdownEvent
atomic.Int64 Interlocked methods on long field
context.Context CancellationToken
defer try/finally or using
error return Exceptions or Result pattern
[]byte byte[], ReadOnlySpan<byte>, ReadOnlyMemory<byte>
map[K]V Dictionary<K,V> or ConcurrentDictionary<K,V>
interface{} object or generics
time.Duration TimeSpan
weak.Pointer[T] WeakReference<T>