# TODO.md -- go-agentic ## Phase 1: Test Coverage - [x] Verify all 5 test files pass standalone after split (`go test ./...`) - [x] Add integration test for full task lifecycle: claim -> process -> complete - [x] Add edge-case tests for allowance exhaustion mid-task - [x] Fill coverage gaps: embed, service types, git operations, config YAML/env paths, error store mock - [x] Target 85%+ coverage achieved: 85.6% (from 70.1%) — `23aa635` ## Phase 2: Allowance Persistence - [x] MemoryStore is in-memory only -- state lost on restart - [ ] Add Redis backend for `AllowanceStore` interface (multi-process safe) - [x] Add SQLite backend for `AllowanceStore` interface (single-node fallback) - [x] Config already supports YAML -- wire backend selection into config loader ## Phase 3: Multi-Agent Coordination — `646cc02` ### 3.1 Agent Registry - [x] **Create `registry.go`** — `AgentInfo` struct (ID, Name, Capabilities []string, Status enum, LastHeartbeat, CurrentLoad int, MaxLoad int), `AgentStatus` enum (Available/Busy/Offline) - [x] **`AgentRegistry` interface** — `Register(AgentInfo) error`, `Deregister(id string) error`, `Get(id string) (AgentInfo, error)`, `List() []AgentInfo`, `Heartbeat(id string) error`, `Reap(ttl time.Duration) []string` (returns IDs of reaped agents) - [x] **`MemoryRegistry` implementation** — `sync.RWMutex` guarded map, `Reap()` marks agents offline if heartbeat older than TTL - [x] **Tests** — registration, deregistration, heartbeat updates, reap stale agents, concurrent access ### 3.2 Task Router - [x] **Create `router.go`** — `TaskRouter` interface with `Route(task *Task, agents []AgentInfo) (string, error)` returning agent ID - [x] **`DefaultRouter` implementation** — capability matching (task.Labels ⊆ agent.Capabilities), then least-loaded agent (CurrentLoad / MaxLoad ratio), priority weighting (critical tasks skip load balancing) - [x] **`ErrNoEligibleAgent`** sentinel error when no agents match capabilities or all are at capacity - [x] **Tests** — capability matching, load distribution, critical priority bypass, no eligible agent error, tie-breaking by agent ID (deterministic) ### 3.3 Dispatcher - [x] **Create `dispatcher.go`** — `Dispatcher` struct wrapping `AgentRegistry`, `TaskRouter`, `AllowanceService`, and `Client` - [x] **`Dispatch(ctx, task) (string, error)`** — Route → allowance check → claim via client → record usage. Returns assigned agent ID - [x] **`DispatchLoop(ctx, interval)`** — polls client.ListTasks(pending) → dispatches each. Respects context cancellation - [x] **Tests** — full dispatch flow with mock client, allowance rejection path, no-agent-available path, loop cancellation ## Phase 4: CLI Backing Functions — `ef81db7` Phase 4 provides the data-fetching and formatting functions that `core agent` CLI commands will call. The CLI commands themselves live in `core/cli`. ### 4.1 Status Summary - [x] **Create `status.go`** — `StatusSummary` struct (Agents []AgentInfo, PendingTasks int, InProgressTasks int, AllowanceRemaining map[string]int64) - [x] **`GetStatus(ctx, registry, client, allowanceSvc) (*StatusSummary, error)`** — aggregates registry.List(), client.ListTasks counts, allowance remaining per agent - [x] **`FormatStatus(summary) string`** — tabular text output for CLI rendering - [x] **Tests** — with mock registry + nil client, full summary with mock client ### 4.2 Task Submission - [x] **`SubmitTask(ctx, client, title, description, labels, priority) (*Task, error)`** — creates a new task via client (requires new Client.CreateTask method) - [x] **Add `Client.CreateTask(ctx, task) (*Task, error)`** — POST /api/tasks - [x] **Tests** — creation with all fields, validation (empty title), httptest mock ### 4.3 Log Streaming - [x] **Create `logs.go`** — `StreamLogs(ctx, client, taskID, writer) error` — polls task updates and writes progress to io.Writer - [x] **Tests** — mock client with progress updates, context cancellation --- ## Workflow 1. Virgil in core/go writes tasks here after research 2. This repo's dedicated session picks up tasks in phase order 3. Mark `[x]` when done, note commit hash