Generated design docs and implementation plans via Codex for: - Batch 23: Routes - Batch 24: Leaf Nodes - Batch 25: Gateways - Batch 26: WebSocket - Batch 27: JetStream Core - Batch 28: JetStream API - Batch 29: JetStream Batching - Batch 30: Raft Part 1 All plans include mandatory verification protocol and anti-stub guardrails. Updated batches.md with file paths and planned status.
505 lines
18 KiB
Markdown
505 lines
18 KiB
Markdown
# Batch 26 (WebSocket) Implementation Plan
|
|
|
|
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
|
|
|
**Goal:** Port and verify Batch 26 WebSocket behavior end-to-end (37 features, 86 tests) from `server/websocket.go` and mapped Go tests without introducing stubs or fake test passes.
|
|
|
|
**Architecture:** Implement websocket protocol logic in focused websocket components, wire runtime behavior through `ClientConnection` and `NatsServer` partials, and execute ID-driven feature/test verification loops with hard build/test/status gates. Do low-level frame primitives first, then HTTP upgrade/options/listener integration, then mapped tests (including explicit benchmark classification handling).
|
|
|
|
**Tech Stack:** .NET 10, C# latest, xUnit 3, Shouldly, NSubstitute, PortTracker CLI, SQLite (`porting.db`)
|
|
|
|
**Design doc:** `docs/plans/2026-02-27-batch-26-websocket-design.md`
|
|
|
|
---
|
|
|
|
## Batch Scope
|
|
|
|
- Batch: `26 - WebSocket`
|
|
- Dependencies: Batches `16`, `18` (must be complete before execution)
|
|
- Features: `37`
|
|
- Tests: `86`
|
|
|
|
### Feature Groups (max ~20 each)
|
|
|
|
1. **Group A (20 features):** `3506,3507,3509,3510,3511,3512,3513,3514,3515,3516,3517,3518,3519,3520,3521,3522,3523,3524,3525,3541`
|
|
2. **Group B (17 features):** `3526,3527,3528,3529,3530,3531,3532,3533,3534,3535,3536,3537,3538,3539,3540,3542,3543`
|
|
|
|
---
|
|
|
|
## MANDATORY VERIFICATION PROTOCOL
|
|
|
|
> **NON-NEGOTIABLE:** Every feature and test in this batch must follow this protocol. Skipping any step is a plan violation.
|
|
|
|
### What Counts as a Real Feature/Test
|
|
|
|
1. **Real feature**:
|
|
- Behavior implemented in runtime code (not placeholder return/no-op/throw stub).
|
|
- Mapped to the Go method intent for that feature ID.
|
|
- Covered by at least one related passing test.
|
|
2. **Real test**:
|
|
- Uses Arrange/Act/Assert.
|
|
- Calls relevant production code.
|
|
- Has meaningful Shouldly assertions.
|
|
- Is not a placeholder pattern.
|
|
|
|
### Per-Feature Verification Loop (REQUIRED for each feature ID)
|
|
|
|
1. Read mapped Go method location and surrounding logic:
|
|
- `dotnet run --project tools/NatsNet.PortTracker -- feature show <feature-id> --db porting.db`
|
|
- `sed -n '<start>,<end>p' golang/nats-server/server/websocket.go`
|
|
2. Write/adjust C# implementation for only that behavior slice.
|
|
3. Build immediately:
|
|
- `dotnet build dotnet/`
|
|
4. Run related targeted tests (single method/class filter first).
|
|
5. Record evidence (feature ID, Go line(s), test(s) run, pass summary) before status update.
|
|
|
|
### Stub Detection Check (REQUIRED after each feature/test mini-batch)
|
|
|
|
Run both scans and resolve all hits before continuing:
|
|
|
|
```bash
|
|
# Production code stub scan
|
|
rg -n --pcre2 "(NotImplementedException|TODO: session 23|TODO: websocket|// TODO|// PLACEHOLDER|=>\\s*throw\\s+new\\s+NotImplementedException)" \
|
|
dotnet/src/ZB.MOM.NatsNet.Server/WebSocket \
|
|
dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs \
|
|
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer*.cs
|
|
|
|
# Empty/trivial method body scan in touched websocket-related files
|
|
rg -n --pcre2 "^\\s*(public|private|internal|protected).*\\)\\s*\\{\\s*\\}\\s*$" \
|
|
dotnet/src/ZB.MOM.NatsNet.Server/WebSocket \
|
|
dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs \
|
|
dotnet/src/ZB.MOM.NatsNet.Server/NatsServer*.cs
|
|
|
|
# Test stub scan
|
|
rg -n --pcre2 "(Assert\\.True\\(true\\)|Assert\\.Pass\\(|NotImplementedException|// TODO|// PLACEHOLDER|ShouldBe\\(true\\);\\s*$)" \
|
|
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog
|
|
```
|
|
|
|
### Build Gate (REQUIRED after each feature group)
|
|
|
|
After Group A and Group B, full build must pass:
|
|
|
|
```bash
|
|
dotnet build dotnet/ --verbosity minimal
|
|
```
|
|
|
|
If build fails, no status updates are allowed.
|
|
|
|
### Test Gate (REQUIRED before marking features verified)
|
|
|
|
1. Run all related tests for the feature group.
|
|
2. Confirm `Failed: 0`.
|
|
3. Only after test gate passes can feature IDs move to `verified`.
|
|
|
|
Example:
|
|
|
|
```bash
|
|
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
|
|
--filter "FullyQualifiedName~WebSocketHandlerTests" --verbosity normal
|
|
```
|
|
|
|
### Status Update Protocol (REQUIRED)
|
|
|
|
1. Use max **15 IDs per `batch-update`** command.
|
|
2. Never update status without captured evidence for those exact IDs.
|
|
3. Keep feature and test updates separate.
|
|
4. If audit rejects update and behavior is truly implemented, use `--override "<reason>"` with explicit evidence note.
|
|
|
|
Examples:
|
|
|
|
```bash
|
|
dotnet run --project tools/NatsNet.PortTracker -- \
|
|
feature batch-update --ids "3506-3517,3518" --set-status complete --db porting.db --execute
|
|
|
|
dotnet run --project tools/NatsNet.PortTracker -- \
|
|
test batch-update --ids "3075,3076,3077,3078,3079,3080,3082,3083,3084,3085,3086,3087,3088,3089,3093" \
|
|
--set-status verified --db porting.db --execute
|
|
```
|
|
|
|
### Checkpoint Protocol Between Tasks (REQUIRED)
|
|
|
|
Between every task below:
|
|
|
|
1. Run full build:
|
|
- `dotnet build dotnet/ --verbosity minimal`
|
|
2. Run full unit tests:
|
|
- `dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal`
|
|
3. If regressions exist, fix before next task.
|
|
4. Commit checkpoint:
|
|
- `git add <changed-files>`
|
|
- `git commit -m "<task checkpoint message>"`
|
|
|
|
---
|
|
|
|
## ANTI-STUB GUARDRAILS (NON-NEGOTIABLE)
|
|
|
|
### Forbidden Patterns
|
|
|
|
Any appearance below in touched Batch 26 feature/test methods is disallowed:
|
|
|
|
1. `throw new NotImplementedException(...)`
|
|
2. Empty method body `{ }` for mapped feature methods
|
|
3. Trivial constant-return placeholder (`return true;`, `return null;`, `return default;`) where real behavior is required
|
|
4. `Assert.True(true)` or equivalent always-pass assertions
|
|
5. `// TODO`, `// PLACEHOLDER`, `TODO: session 23` in mapped code paths
|
|
6. Test methods that only assert non-null on unrelated constants without exercising websocket behavior
|
|
|
|
### Hard Limits
|
|
|
|
1. Max `~20` feature IDs per implementation group (already enforced by Group A/B).
|
|
2. Max `15` IDs per status batch update.
|
|
3. Max `1` feature group status finalization cycle at a time (finish Group A fully before Group B verification updates).
|
|
4. No marking `verified` for features until related tests pass.
|
|
5. No marking tests `verified` without direct pass evidence.
|
|
|
|
### If You Get Stuck (REQUIRED)
|
|
|
|
1. Do **not** leave stubs.
|
|
2. Mark blocked feature/test IDs as `deferred` with explicit reason.
|
|
3. Add a code comment near deferred code/test:
|
|
- `// DEFERRED(batch26): <specific dependency/runtime blocker>`
|
|
4. Continue with next unblocked ID.
|
|
5. Revisit deferred IDs only after blocker is resolved.
|
|
|
|
---
|
|
|
|
### Task 1: Dependency and Batch Readiness Gate
|
|
|
|
**Files:**
|
|
- Modify: none
|
|
- Validate context: `porting.db`, batch metadata
|
|
|
|
**Step 1: Verify dependencies are complete**
|
|
|
|
Run:
|
|
```bash
|
|
dotnet run --project tools/NatsNet.PortTracker -- batch show 16 --db porting.db
|
|
dotnet run --project tools/NatsNet.PortTracker -- batch show 18 --db porting.db
|
|
dotnet run --project tools/NatsNet.PortTracker -- batch ready --db porting.db
|
|
```
|
|
Expected: batch 26 is ready only after 16/18 are complete.
|
|
|
|
**Step 2: Start batch 26**
|
|
|
|
Run:
|
|
```bash
|
|
dotnet run --project tools/NatsNet.PortTracker -- batch start 26 --db porting.db
|
|
```
|
|
Expected: start succeeds; no dependency error.
|
|
|
|
**Step 3: Materialize execution manifest**
|
|
|
|
Run:
|
|
```bash
|
|
dotnet run --project tools/NatsNet.PortTracker -- batch show 26 --db porting.db
|
|
```
|
|
Expected: explicit list of 37 features + 86 tests used as task checklist.
|
|
|
|
**Step 4: Commit checkpoint**
|
|
|
|
```bash
|
|
git add porting.db
|
|
git commit -m "chore(batch26): start websocket batch after dependency gate"
|
|
```
|
|
|
|
---
|
|
|
|
### Task 2: Implement Feature Group A (20 features, frame/core path)
|
|
|
|
**Feature IDs:**
|
|
- `3506,3507,3509,3510,3511,3512,3513,3514,3515,3516,3517,3518,3519,3520,3521,3522,3523,3524,3525,3541`
|
|
|
|
**Files:**
|
|
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/WebSocket/WebSocketTypes.cs`
|
|
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/WebSocket/WebSocketConstants.cs`
|
|
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs`
|
|
- Add or modify focused websocket helper files under: `dotnet/src/ZB.MOM.NatsNet.Server/WebSocket/`
|
|
- Test: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/WebSocketHandlerTests.Impltests.cs`
|
|
|
|
**Step 1: Write/port failing tests for Group A behaviors**
|
|
|
|
Start with tests covering: control-frame detection, masking/unmasking, close message creation, frame header generation, read/decompression paths, close enqueue, outbound collapse.
|
|
|
|
Run:
|
|
```bash
|
|
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
|
|
--filter "FullyQualifiedName~WebSocketHandlerTests.WSIsControlFrame_ShouldSucceed|FullyQualifiedName~WebSocketHandlerTests.WSUnmask_ShouldSucceed"
|
|
```
|
|
Expected: initially fail until implementation lands.
|
|
|
|
**Step 2: Implement minimal code per feature using per-feature loop**
|
|
|
|
For each feature ID in Group A, execute the mandatory loop (Go source -> C# -> build -> related tests).
|
|
|
|
**Step 3: Run Group A build and focused tests**
|
|
|
|
Run:
|
|
```bash
|
|
dotnet build dotnet/ --verbosity minimal
|
|
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
|
|
--filter "FullyQualifiedName~WebSocketHandlerTests" --verbosity normal
|
|
```
|
|
Expected: no failures in mapped Group A coverage.
|
|
|
|
**Step 4: Run mandatory stub detection checks**
|
|
|
|
Run all scans from the MANDATORY VERIFICATION PROTOCOL section.
|
|
Expected: zero matches in touched methods/tests.
|
|
|
|
**Step 5: Update feature statuses (chunked <=15 IDs)**
|
|
|
|
Example chunks:
|
|
```bash
|
|
dotnet run --project tools/NatsNet.PortTracker -- \
|
|
feature batch-update --ids "3506,3507,3509,3510,3511,3512,3513,3514,3515,3516,3517,3518,3519,3520,3521" \
|
|
--set-status complete --db porting.db --execute
|
|
|
|
dotnet run --project tools/NatsNet.PortTracker -- \
|
|
feature batch-update --ids "3522,3523,3524,3525,3541" --set-status complete --db porting.db --execute
|
|
```
|
|
|
|
**Step 6: Commit checkpoint**
|
|
|
|
```bash
|
|
git add dotnet/src/ZB.MOM.NatsNet.Server/WebSocket dotnet/src/ZB.MOM.NatsNet.Server/ClientConnection.cs porting.db
|
|
git commit -m "feat(batch26): implement websocket frame/core feature group A"
|
|
```
|
|
|
|
---
|
|
|
|
### Task 3: Implement Feature Group B (17 features, upgrade/options/server integration)
|
|
|
|
**Feature IDs:**
|
|
- `3526,3527,3528,3529,3530,3531,3532,3533,3534,3535,3536,3537,3538,3539,3540,3542,3543`
|
|
|
|
**Files:**
|
|
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.cs`
|
|
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Init.cs`
|
|
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Listeners.cs`
|
|
- Modify: `dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Lifecycle.cs`
|
|
- Modify: websocket source files in `dotnet/src/ZB.MOM.NatsNet.Server/WebSocket/`
|
|
- Test: websocket/backlog test files listed in later tasks
|
|
|
|
**Step 1: Write failing tests for upgrade/origin/options behavior**
|
|
|
|
Focus on IDs mapped to:
|
|
- `TestWSUpgradeConnDeadline`, `TestWSCompressNegotiation`, `TestWSSetHeader`, `TestWSSetOriginOptions`.
|
|
|
|
**Step 2: Implement feature-by-feature with mandatory loop**
|
|
|
|
For each Group B feature:
|
|
- Read Go source section from `websocket.go`.
|
|
- Implement in .NET with lock/lifecycle parity.
|
|
- Build and run targeted tests before next feature.
|
|
|
|
**Step 3: Remove related integration stubs**
|
|
|
|
Eliminate websocket placeholder behavior in:
|
|
- readiness checks
|
|
- listener lists
|
|
- websocket server shutdown path
|
|
- websocket connect URL propagation
|
|
- websocket client creation path
|
|
|
|
**Step 4: Build + focused tests + stub scans**
|
|
|
|
Run:
|
|
```bash
|
|
dotnet build dotnet/ --verbosity minimal
|
|
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
|
|
--filter "FullyQualifiedName~WebSocketHandlerTests" --verbosity normal
|
|
```
|
|
|
|
**Step 5: Update feature statuses (chunked <=15 IDs)**
|
|
|
|
```bash
|
|
dotnet run --project tools/NatsNet.PortTracker -- \
|
|
feature batch-update --ids "3526,3527,3528,3529,3530,3531,3532,3533,3534,3535,3536,3537,3538,3539,3540" \
|
|
--set-status complete --db porting.db --execute
|
|
|
|
dotnet run --project tools/NatsNet.PortTracker -- \
|
|
feature batch-update --ids "3542,3543" --set-status complete --db porting.db --execute
|
|
```
|
|
|
|
**Step 6: Commit checkpoint**
|
|
|
|
```bash
|
|
git add dotnet/src/ZB.MOM.NatsNet.Server/NatsServer*.cs dotnet/src/ZB.MOM.NatsNet.Server/WebSocket porting.db
|
|
git commit -m "feat(batch26): implement websocket upgrade/options/server feature group B"
|
|
```
|
|
|
|
---
|
|
|
|
### Task 4: Port WebSocket Functional Tests (22 tests in `websocket_test.go`)
|
|
|
|
**Test IDs:**
|
|
- `3075,3076,3077,3078,3079,3080,3082,3083,3084,3085,3086,3087,3088,3089,3093,3097,3098,3099,3102,3113,3117,3132`
|
|
|
|
**Files:**
|
|
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/WebSocketHandlerTests.Impltests.cs`
|
|
|
|
**Step 1: Port test-by-test from Go source**
|
|
|
|
For each test ID:
|
|
1. `test show <id>`
|
|
2. Read Go body in `websocket_test.go`
|
|
3. Port behavior to Shouldly assertions
|
|
4. Run single test
|
|
|
|
Single-test command template:
|
|
```bash
|
|
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
|
|
--filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.ImplBacklog.WebSocketHandlerTests.<MethodName>" \
|
|
--verbosity normal
|
|
```
|
|
|
|
**Step 2: Run class-level gate**
|
|
|
|
```bash
|
|
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ \
|
|
--filter "FullyQualifiedName~WebSocketHandlerTests" --verbosity normal
|
|
```
|
|
|
|
**Step 3: Stub scan + assertion quality check**
|
|
|
|
```bash
|
|
rg -n "(Assert\\.True\\(true\\)|NotImplementedException|// TODO|// PLACEHOLDER)" \
|
|
dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/WebSocketHandlerTests.Impltests.cs
|
|
```
|
|
|
|
**Step 4: Update test statuses in chunks <=15**
|
|
|
|
Use chunks with pass evidence recorded for each chunk.
|
|
|
|
**Step 5: Commit checkpoint**
|
|
|
|
```bash
|
|
git add dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/WebSocketHandlerTests.Impltests.cs porting.db
|
|
git commit -m "test(batch26): port websocket functional tests"
|
|
```
|
|
|
|
---
|
|
|
|
### Task 5: Port Cross-Module Functional Tests Dependent on WebSocket (11 tests)
|
|
|
|
**Test IDs:**
|
|
- `409,465,466,1353,1902,1903,1975,1986,2371,2384,2488`
|
|
|
|
**Files:**
|
|
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/JetStreamFileStoreTests.Impltests.cs`
|
|
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsConsumerTests.Impltests.cs`
|
|
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/LeafNodeHandlerTests.Impltests.cs`
|
|
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests1.Impltests.cs`
|
|
- Modify: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/ConcurrencyTests2.Impltests.cs`
|
|
- Create if missing: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/LeafNodeProxyTests.Impltests.cs`
|
|
|
|
**Step 1: Ensure mapped class files exist**
|
|
|
|
Create missing files/classes before test-porting if absent (especially `LeafNodeProxyTests`).
|
|
|
|
**Step 2: Port tests ID-by-ID with single-test loop**
|
|
|
|
Use the same per-test loop and evidence policy as Task 4.
|
|
|
|
**Step 3: Run focused class gates**
|
|
|
|
Run each touched class with `dotnet test --filter "FullyQualifiedName~<ClassName>"`.
|
|
|
|
**Step 4: Update statuses in <=15 chunks**
|
|
|
|
Mark `verified` only with evidence.
|
|
If blocked by missing infra, mark `deferred` and add `// DEFERRED(batch26): <reason>`.
|
|
|
|
**Step 5: Commit checkpoint**
|
|
|
|
```bash
|
|
git add dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog porting.db
|
|
git commit -m "test(batch26): port cross-module websocket-dependent tests"
|
|
```
|
|
|
|
---
|
|
|
|
### Task 6: Resolve Benchmark-Mapped Test IDs (53 tests)
|
|
|
|
**Benchmark test IDs:**
|
|
- `154,274,275,276,277,3134,3135,3136,3137,3138,3139,3140,3141,3142,3143,3144,3145,3146,3147,3148,3149,3150,3151,3152,3153,3154,3155,3156,3157,3158,3159,3160,3161,3162,3163,3164,3165,3166,3167,3168,3169,3170,3171,3172,3173,3174,3175,3176,3177,3179,3180,3181,3182`
|
|
|
|
**Files:**
|
|
- Modify/create: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/WebSocketHandlerTests.Impltests.cs`
|
|
- Create if missing: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/CoreBenchmarks.Impltests.cs`
|
|
- Create if missing: `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/PublishBenchmarks.Impltests.cs`
|
|
|
|
**Step 1: Benchmark decision gate per ID**
|
|
|
|
For each benchmark ID choose exactly one:
|
|
1. Convert to deterministic functional test with real assertions and mark `verified`.
|
|
2. Mark `n_a` (benchmark-only/perf harness requirement) with explicit reason.
|
|
3. Mark `deferred` if runtime infra blocker exists.
|
|
|
|
**Step 2: Run tests for converted benchmark IDs**
|
|
|
|
Use class-level and method-level gates as in previous tasks.
|
|
|
|
**Step 3: Apply status updates in <=15 chunks**
|
|
|
|
Separate commands by status (`verified`, `n_a`, `deferred`).
|
|
|
|
**Step 4: Commit checkpoint**
|
|
|
|
```bash
|
|
git add dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog porting.db
|
|
git commit -m "test(batch26): resolve benchmark-mapped websocket test IDs"
|
|
```
|
|
|
|
---
|
|
|
|
### Task 7: Final Verification, Status Closure, and Batch Completion
|
|
|
|
**Files:**
|
|
- Modify: `porting.db`
|
|
- Optional report artifacts: `reports/current.md` (if generator updates it)
|
|
|
|
**Step 1: Full verification run**
|
|
|
|
```bash
|
|
dotnet build dotnet/ --verbosity minimal
|
|
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ --verbosity normal
|
|
dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ --verbosity normal
|
|
```
|
|
|
|
**Step 2: Promote complete feature IDs to verified**
|
|
|
|
Use chunked updates with evidence references.
|
|
|
|
**Step 3: Audit and reconcile**
|
|
|
|
```bash
|
|
dotnet run --project tools/NatsNet.PortTracker -- audit --type features --db porting.db
|
|
dotnet run --project tools/NatsNet.PortTracker -- audit --type tests --db porting.db
|
|
```
|
|
|
|
**Step 4: Complete batch**
|
|
|
|
```bash
|
|
dotnet run --project tools/NatsNet.PortTracker -- batch complete 26 --db porting.db
|
|
```
|
|
Expected: completion succeeds only when all batch items are in valid terminal statuses.
|
|
|
|
**Step 5: Generate report and commit**
|
|
|
|
```bash
|
|
./reports/generate-report.sh
|
|
git add porting.db reports/
|
|
git commit -m "feat(batch26): complete websocket batch with verified implementation and tests"
|
|
```
|
|
|
|
---
|
|
|
|
## Execution Notes
|
|
|
|
1. If `dotnet` is not on `PATH`, use absolute binary (for this machine): `/usr/local/share/dotnet/dotnet`.
|
|
2. Always keep evidence for each status update chunk (test output snippet + feature/test IDs).
|
|
3. Never move a feature to `verified` before its related tests are passing.
|
|
4. Never convert a blocked item into a stub just to make progress.
|
|
|