Scaffold for agent capability benchmark harness (skills-qng9):
- docs/specs/scenario-schema.md: YAML schema for test scenarios
- tests/scenarios/: Easy, medium, hard example scenarios
- tests/fixtures/: Python fixtures for testing
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- worktreePath() now returns absolute path using findMainRepoDir()
- Fixes 'cannot change to worktrees/...' error from inside worktree
- test-worker.sh now checks sqlite3 is available before running
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Extract renderStatusTable() from nested proc in status()
- Add column width constants (ColTask, ColState, etc.)
- Use parseEnum for heartbeat status instead of case statement
- Return bool from startGlobalHeartbeat() to indicate if started
- Remove unused getBranchStatus() function (dead code)
Closes: skills-y76g, skills-f8yd, skills-audh, skills-hx1n, skills-827e
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add StaleLevel enum (ok, WARN, STALE, DEAD) to types.nim
- Extract computeStaleLevel() as single source of truth
- Simplify isStale() and staleLevel() to use computeStaleLevel()
- Refactor transition() and transitionToFailed() to use withTransaction
- Add schema migration infrastructure:
- CurrentSchemaVersion constant
- Migrations sequence for incremental upgrades
- getSchemaVersion() and runMigrations() procs
- initSchema() now runs pending migrations
Closes: skills-dtk, skills-8fd, skills-9ny
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add try/except blocks in worker commands to catch WorkerNotFound,
InvalidTransition, and StaleState exceptions
- Return ExitInvalidTransition (3) for state transition errors
- Return ExitNotFound (7) for missing workers
- Fix double ROLLBACK bug in state.nim by removing inline ROLLBACKs
and letting the except block handle transaction cleanup
Closes: skills-lxb9
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Test infrastructure:
- Add comprehensive test-worker.sh with 59 tests
- Cover spawn, start, done, approve, reject, cancel, fail, heartbeat
- Test status filtering, context files, review-gate integration
- Test invalid state transitions and error cases
Bug fixes:
- Fix agent commands failing when run from worktrees (skills-y3f2)
- Add getMainRepoBusDbPath() to find DB in main repo
- Update start, done, fail, heartbeat to use correct path
- Fix review.nim crash when review-gate not installed (OSError)
- Gracefully return exitCode=-1 instead of crashing
Closes skills-y3f2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Documents rationale for using Nim with ORC for the worker coordination
CLI: fast startup, single binary, Python-like syntax, excellent SQLite
support via tiny_sqlite, CLI generation via cligen.
Closes skills-q40
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Nim's varargs doesn't consume the last positional argument when there's
a trailing parameter with a default value. This caused calls like
`runGit("fetch", "origin")` to be parsed as:
- args = ["fetch"]
- workDir = "origin"
Instead of the intended:
- args = ["fetch", "origin"]
- workDir = ""
Fixed by changing from varargs to openArray, which requires explicit
array syntax at call sites: `runGit(["fetch", "origin"])`.
Also includes P2 bug fixes:
- Start heartbeat before state transition (skills-qekj)
- Reject symlinks when reading context file (skills-16zf)
- Case-insensitive conflict detection (skills-n3qp)
Smoke tested: spawn, status, start, show, cancel all work.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
worker.nim:
- Start heartbeat before state transition in start command
(prevents WORKING state without heartbeat if startup fails)
context.nim:
- Reject symlinks when reading context file (security)
(prevents reading arbitrary files via symlinked .worker-ctx.json)
git.nim:
- Use case-insensitive conflict detection in rebase/merge
(toLowerAscii instead of checking "CONFLICT" and "conflict" separately)
Closes: skills-qekj, skills-16zf, skills-n3qp
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
types.nim:
- Remove unused constants: BusJsonlPath, BlobsDir, WorkersDir
worker.nim:
- Remove unused 'by' and 'comment' parameters from approve()
Note: skills-5ax (unused imports in db.nim) no longer applies -
strutils is used for toHex in genOid fallback path.
Closes: skills-t9ub, skills-5ax, skills-fdu, skills-ghlb
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add branchName() and worktreePath() helpers for consistent path generation
- Add msToTime() for epoch ms to Time conversion (8 occurrences consolidated)
- Add validateTaskId() for CLI input validation (prevents path traversal)
- Add optString/optInt64 helpers for nullable DB values
- Add withTransaction template for automatic rollback on error
Closes: skills-lzh2, skills-3d9o, skills-5x2o, skills-qiq0, skills-73yu, skills-vuj2
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- genOid: use std/sysrand for cryptographic randomness instead of rand()
- HeartbeatThread: change from ptr with manual alloc/dealloc to ref object
- Add error handling for DB open in heartbeat thread
- Remove unused globalChannel and times import
Closes: skills-0wk, skills-bk7x, skills-69sz, skills-ib9u, skills-kvdl, skills-n6zf
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>