- branch-manager: beforeEach→beforeAll (all 12 tests are read-only)
- worktree manager: clone template repo per test instead of full init
- signal-manager: reduce setTimeout delay from 100ms to 30ms
Bring buildErrandPrompt() and buildErrandRevisionPrompt() in line with
the codebase pattern used by execute, plan, detail, etc. Import shared
DEVIATION_RULES and GIT_WORKFLOW constants. Add session_startup (pwd,
git status, CLAUDE.md, expected-pwd.txt), execution_rules, and
anti_patterns sections. Keep signal format inline since errands use
result.message instead of the standard questions format.
Agents sometimes write signal.json before finishing output files,
causing work to be silently discarded. Replace weak "As your final
action" with explicit CRITICAL warning explaining the completion
trigger mechanism.
In YOLO mode, if mergePhaseIntoInitiative() threw (e.g., branch
doesn't exist, merge conflict), the error propagated and completePhase()
was never called — leaving the phase permanently stuck at in_progress.
Also wrap per-phase recovery in try-catch so one failing phase doesn't
abort the entire recoverDispatchQueues() loop.
Enriches the HQ inbox detail view so users can answer agent questions
without navigating away from the inbox:
- Replace raw task UUID in header with human-readable task name
(falls back to UUID, then em dash when both null)
- Add related context panel showing initiative link, task name,
truncated/HTML-stripped description, and phase name; shows skeleton
while loading, "No task context available" when agent has no task
- Add collapsible agent logs section using AgentOutputViewer;
hidden when no output exists, resets on agent change
- Wire new props (taskName, phaseName, initiativeName, initiativeId,
taskDescription, isLoadingContext) in hq.tsx from listWaitingAgents
- Add 11 tests covering all new behaviors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix vitest.config.ts React alias to point to local node_modules
instead of nonexistent ancestor path (../../../../node_modules/react)
- Remove stale HQWaitingForInputSection tests (component was deleted
in e8d332e0 but test cases were left behind)
When git worktree add fails with "branch already used by worktree at
<path>", parse the stale path, force-remove it, and retry once. Fixes
blocked task retries where the old agent-workdirs directory still exists
on disk and git worktree prune alone can't clear the reference.
Errands now create worktrees via ProcessManager.createWorktreesForProjects()
into agent-workdirs/<alias>/<project.name>/ instead of repos/<project>/.cw-worktrees/<errandId>.
This makes getAgentWorkdir + resolveAgentCwd work correctly for all agent types.
Key changes:
- Extract createWorktreesForProjects() from createProjectWorktrees() in ProcessManager
- Add resolveAgentCwd() to ProcessManager (probes for .cw/output in subdirs)
- Add projectId to SpawnAgentOptions for single-project agents (errands)
- Skip auto-cleanup for errand agents (worktrees persist for merge/abandon)
- Errand router uses agentManager.delete() for cleanup instead of SimpleGitWorktreeManager
- Remove cwd parameter from sendUserMessage (resolves via worktreeId)
- Add pruneProjectRepos() to CleanupManager for errand worktree refs
Replaces the in-memory filter (agentManager.list() + filter) with a direct
repository query that LEFT JOINs tasks, phases, and initiatives to return
taskName, phaseName, initiativeName, and taskDescription alongside agent fields.
- Adds AgentWithContext interface and findWaitingWithContext() to AgentRepository port
- Implements findWaitingWithContext() in DrizzleAgentRepository using getTableColumns
- Wires agentRepository into TRPCContext, CreateContextOptions, and TrpcAdapterOptions
- Adds requireAgentRepository() helper following existing pattern
- Updates listWaitingAgents to use repository query instead of agentManager
- Adds 5 unit tests for findWaitingWithContext() covering all FK join edge cases
- Updates existing AgentRepository mocks to satisfy updated interface
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Errand agents are spawned in the errand's git worktree (managed by
SimpleGitWorktreeManager), not in agent-workdirs/<alias>/.
sendUserMessage was deriving the cwd from worktreeId which pointed to
the non-existent agent-workdirs path. Now the errand.sendMessage
procedure resolves the actual worktree path and passes it through.
The "Detail Tasks" button was hidden when an idle detail agent from a
previous run was still associated with the phase. The frontend gate
blocked any re-detail while a detail agent existed, even if it was idle
(i.e. done). The backend already auto-dismisses stale idle agents, so
the frontend just needed to allow idle agents through the gate.
When spawn() receives an explicit cwd (errands), the manager was still
creating a standalone worktree at agent-workdirs/<alias>/ and injecting
its path into the workspace layout prompt. The agent then edited files
in the wrong directory — on a different branch than the errand's.
Now when cwd is provided, we skip worktree creation entirely and use
the caller's cwd for workspace layout, .cw/output/, and all paths.
Merge two useEffects in AgentOutputViewer into one to fix race where
agentId reset clears messages after data effect sets them on remount.
Add "commit before signaling" instruction to errand prompts so
Changes tab shows diff after completion.
- Register errandProcedures in appRouter (was defined but never spread)
- Fix nullable projectId guard in errand delete/abandon procedures
- Add sendUserMessage stub to MockAgentManager in headquarters and
radar-procedures tests (AgentManager interface gained this method)
- Add missing qualityReview field to Initiative fixture in file-io test
(schema gained this column from the quality-review phase)
- Cast conflictFiles access in CLI errand resolve command
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds the fourth test case from the spec: when shouldRunQualityReview
throws, the orchestrator must not crash, must log a warning (verified
implicitly by the catch block), and must still call scheduleDispatch()
so dispatch continuity is maintained.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add errand.requestChanges procedure that re-spawns an agent in the
existing worktree with user feedback. Replace raw <pre> diff blocks
with syntax-highlighted ErrandDiffView using FileCard components.
Add Output/Changes tabs to the active errand view.
When an agent stops, check whether a quality review should run before
auto-completing the task. If shouldRunQualityReview returns run:true,
delegate to runQualityReview (which transitions task to quality_review
and spawns a review agent) instead of calling completeTask directly.
Falls back to completeTask when agentRepository or agentManager are
not injected, or when the task lacks phaseId/initiativeId context.
- Add agentManager optional param to ExecutionOrchestrator constructor
- Extract tryQualityReview() private method to compute branch names and
repo path before delegating to the quality-review service
- Pass agentManager to ExecutionOrchestrator in container.ts
- Add orchestrator integration tests for the agent:stopped quality hook
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When an execute-mode agent stops with task_complete and the initiative has
qualityReview=true, the orchestrator now spawns a fresh execute-mode agent
to run /simplify on changed .ts/.tsx/.js files before marking the task
completed. The task transitions through quality_review status as a recursion
guard so the review agent's stop event is handled normally.
- Add apps/server/execution/quality-review.ts with three exported functions:
computeQualifyingFiles, shouldRunQualityReview, runQualityReview
- Add apps/server/execution/quality-review.test.ts (28 tests)
- Update ExecutionOrchestrator to accept agentManager, replace
handleAgentStopped with quality-review-aware logic, add getRepoPathForTask
- Update orchestrator.test.ts with 3 quality-review integration tests
- Update container.ts to pass agentManager to ExecutionOrchestrator
- Update docs/dispatch-events.md to reflect new agent:stopped behavior
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds apps/server/execution/quality-review.ts with three exported functions:
- computeQualifyingFiles: diffs task branch vs base, filters out *.gen.ts and dist/ paths
- shouldRunQualityReview: evaluates all six guard conditions (task_complete, execute mode,
in_progress status, initiative membership, qualityReview flag, non-empty changeset)
and returns { run, qualifyingFiles } to avoid recomputing the diff in the orchestrator
- runQualityReview: transitions task to quality_review, spawns execute-mode review agent
on the task branch, logs the review agent ID, and falls back to completed on spawn failure
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds qualityReview: z.boolean().optional() to the updateInitiativeConfig
input schema so the field passes through to the repository layer.
Includes integration tests verifying set-true, set-false, and
omit-preserves-existing round-trip behavior.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds two new fields to the database and propagates them through the
repository layer:
- Task status enum gains 'quality_review' (between in_progress and
completed), enabling a QA gate before tasks are marked complete.
- initiatives.quality_review (INTEGER DEFAULT 0) lets an initiative be
flagged for quality-review workflow without a data migration (existing
rows default to false).
Includes:
- Schema changes in schema.ts
- Migration 0037 (ALTER TABLE initiatives ADD quality_review)
- Snapshot chain repaired: deleted stale 0036 snapshot, fixed 0035
prevId to create a linear chain (0032 → 0034 → 0035), then generated
clean 0037 snapshot
- Repository adapter already uses SELECT * / spread-update pattern so
no adapter code changes were needed
- Initiative and task repository tests extended with qualityReview /
quality_review_status describe blocks (7 new tests)
- docs/database.md updated
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces HQWaitingForInputSection with a two-column inline panel that
lets users answer agent questions directly from HQ without navigating
to /inbox. Adds SSE invalidation for listWaitingAgents/listMessages,
useState for agent selection, and all required mutations.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Three fixes for phases getting stuck when a detail task crashes and is retried:
1. detailPhase mutation (architect.ts): clean up orphaned pending/in_progress
detail tasks before creating new ones, preventing duplicates at the source
2. orchestrator recovery: detect and complete stale duplicate planning tasks
(same category+phase, one completed, one pending)
3. ensureBranch: catch "already exists" TOCTOU race instead of blocking phase
tRPC without superjson serializes Date objects as plain strings/numbers
over the wire. The .toISOString() calls crashed because the values
aren't Date instances on the client. Matches the existing pattern used
elsewhere (e.g. agents page).
Populates the agent_metrics table from existing agent_log_chunks data after
the schema migration. Reads chunks in batches of 500, accumulates per-agent
counts in memory, then upserts with additive ON CONFLICT DO UPDATE to match
the ongoing insertChunk write-path behavior.
- apps/server/scripts/backfill-metrics.ts: core backfillMetrics(db) + CLI wrapper backfillMetricsFromPath(dbPath)
- apps/server/scripts/backfill-metrics.test.ts: 8 tests covering all chunk types, malformed JSON, isolation, empty DB, and re-run double-count behavior
- apps/server/cli/index.ts: new top-level `cw backfill-metrics [--db <path>]` command
- docs/database-migrations.md: Post-migration backfill scripts section documenting when and how to run the script
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
listForRadar previously called findByAgentIds() and JSON-parsed every chunk to
compute questionsCount, subagentsCount, and compactionsCount. Switch to
findMetricsByAgentIds() which reads the pre-computed agent_metrics table,
eliminating the chunk scan and per-row JSON.parse entirely.
Add two new test cases: agent with no metrics row returns zero counts, and
listForRadar response rows never carry chunk content.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wrap insertChunk in a synchronous better-sqlite3 transaction that upserts
agent_metrics counters atomically on every chunk insert. Malformed JSON
skips the upsert but always preserves the chunk row.
Add findMetricsByAgentIds to the interface and Drizzle adapter for
efficient bulk metric reads.
Add 8-test suite covering all write/read paths and edge cases.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When an initiative has multiple end phases (leaf nodes with no
dependents), queueAllPhases now auto-creates an Integration phase
that depends on all of them. This catches cross-phase incompatibilities
(type mismatches, conflicting exports, broken tests) before review.
Converts /inbox from a 270-line interactive page to a minimal
TanStack Router redirect route. Bookmarked or externally linked
/inbox URLs now redirect cleanly to /hq instead of 404-ing.
InboxList and InboxDetailPanel components are preserved for reuse
in the HQ page (Phase 569ZNKArI1OYRolaOZLhB).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Badge showing agents in waiting_for_input status now appears on HQ nav item.
Inbox link removed from the nav. Adds regression test for navItems structure.
Adds the agentMetrics table to SQLite schema for storing pre-computed
per-agent event counts (questions, subagents, compactions), enabling
listForRadar to fetch one row per agent instead of scanning log chunks.
Also fixes pre-existing Drizzle snapshot chain collision in meta/
(0035/0036 snapshots had wrong prevId due to parallel agent branches)
to unblock drizzle-kit generate.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ErrandRepository was instantiated in the container but never passed
from TrpcAdapterOptions into createContext(), causing all errand
procedures to throw "Errand repository not available" at runtime.