Files
natsnet/AGENTS.md

7.4 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

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

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>