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

273 lines
8.9 KiB
Markdown

# 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
```bash
# 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:
```bash
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.
```bash
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:
```bash
dotnet run --project tools/NatsNet.PortTracker -- dependency ready --db porting.db
```
2. Or find deferred/stub features in a specific module:
```bash
dotnet run --project tools/NatsNet.PortTracker -- feature list --module <id> --status deferred --db porting.db
```
3. To find tests that need implementing:
```bash
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 batch**`batch next` returns the lowest-priority ready batch:
```bash
dotnet run --project tools/NatsNet.PortTracker -- batch next --db porting.db
```
2. **Start it** — marks the batch as in-progress (validates dependencies are met):
```bash
dotnet run --project tools/NatsNet.PortTracker -- batch start <id> --db porting.db
```
3. **See all items** — lists every feature and test in the batch:
```bash
dotnet run --project tools/NatsNet.PortTracker -- batch show <id> --db porting.db
```
4. **Implement features first**, then write/port the tests.
5. **Complete it** — validates all features and tests are verified/complete/n_a:
```bash
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:
```bash
dotnet run --project tools/NatsNet.PortTracker -- feature update <id> --status stub --db porting.db
```
2. **Read the Go source** — use `feature show <id>` to get the Go file path and line numbers, then read the Go implementation.
3. **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`
4. **Ensure it compiles** — run `dotnet build dotnet/`
5. **Mark complete**:
```bash
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**:
```bash
dotnet test --filter "FullyQualifiedName~TestClassName" \
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/
```
5. **Mark verified** (if passing):
```bash
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:
```bash
dotnet run --project tools/NatsNet.PortTracker -- dependency ready --db porting.db
```
4. Generate updated report:
```bash
./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>` |