diff --git a/codev/projects/bugfix-1199-afx-status-recommends-afx-towe/status.yaml b/codev/projects/bugfix-1199-afx-status-recommends-afx-towe/status.yaml new file mode 100644 index 000000000..e9f4a309f --- /dev/null +++ b/codev/projects/bugfix-1199-afx-status-recommends-afx-towe/status.yaml @@ -0,0 +1,22 @@ +id: bugfix-1199 +title: afx-status-recommends-afx-towe +protocol: bugfix +phase: verified +plan_phases: [] +current_plan_phase: null +gates: + pr: + status: approved + requested_at: '2026-07-18T21:12:37.974Z' + approved_at: '2026-07-18T21:16:42.226Z' +iteration: 1 +build_complete: false +history: [] +started_at: '2026-07-18T09:04:23.549Z' +updated_at: '2026-07-18T21:17:09.868Z' +pr_history: + - phase: pr + pr_number: 1200 + branch: builder/bugfix-1199 + created_at: '2026-07-18T09:16:31.778Z' +pr_ready_for_human: false diff --git a/codev/state/bugfix-1199_thread.md b/codev/state/bugfix-1199_thread.md new file mode 100644 index 000000000..b97c726fd --- /dev/null +++ b/codev/state/bugfix-1199_thread.md @@ -0,0 +1,21 @@ +# Bugfix #1199 Thread + +## Investigate + +- Confirmed no existing PR or prior implementation for issue #1199. +- Reproduced the bug against the running Tower from a temporary, unregistered Codev workspace: `status()` reported `Workspace: not active in tower` and recommended `afx tower start`. +- Root cause: the Tower-running/unregistered-workspace branch in `packages/codev/src/agent-farm/commands/status.ts` contains a stale hard-coded `afx tower start` recommendation. The separate Tower-down branch correctly uses `afx tower start` to start the daemon. +- Fix scope is BUGFIX-appropriate: one production string plus focused unit coverage for the Tower-running/unregistered and Tower-down branches. No architectural changes are needed. + +## Fix + +- Changed only the unregistered-workspace recommendation to `afx workspace start`. +- Added deterministic unit coverage for both required branches and their distinct recommendations in `spec-1057-status-owner.test.ts`. +- Focused regression suite passed: 17/17 tests. +- Porch build and full test checks passed. The shared environment's `/tmp/.git` marker and global `~/.codev/config.json` initially contaminated unrelated non-hermetic tests; isolating `TMPDIR` and `HOME` made the unchanged baseline tests pass without out-of-scope edits. + +## PR + +- Published the branch through the contributor fork and opened upstream PR #1200. +- CMAP completed with all three required verdicts: Gemini `APPROVE` (high confidence), Codex `APPROVE` (high confidence), and Claude `APPROVE` (high confidence). +- The Claude lane initially hit its CLI quota, then succeeded when retried after the quota window reset. No reviewer requested changes. diff --git a/packages/codev/src/agent-farm/__tests__/spec-1057-status-owner.test.ts b/packages/codev/src/agent-farm/__tests__/spec-1057-status-owner.test.ts index 14dccb75a..9295067d8 100644 --- a/packages/codev/src/agent-farm/__tests__/spec-1057-status-owner.test.ts +++ b/packages/codev/src/agent-farm/__tests__/spec-1057-status-owner.test.ts @@ -323,3 +323,46 @@ describe('afx status — Tower-running human path (Spec 1057)', () => { expect(rows.map((r) => r[0])).toEqual(['builder-feedback-1']); }); }); + +// ============================================================================ +// Startup recommendations (Bugfix #1199) +// ============================================================================ + +describe('afx status — startup recommendations', () => { + beforeEach(() => { + vi.clearAllMocks(); + mockLoadState.mockReturnValue({ + architect: null, + architects: [], + builders: [], + utils: [], + annotations: [], + }); + }); + + it('recommends workspace start when Tower is running but the workspace is unregistered', async () => { + mockIsRunning.mockResolvedValue(true); + mockGetHealth.mockResolvedValue({ + uptime: 100, + activeWorkspaces: 1, + memoryUsage: 1024 * 1024, + }); + mockGetWorkspaceStatus.mockResolvedValue(null); + + await status(); + + const info = mockLoggerInfo.mock.calls.map((c) => stripAnsi(String(c[0]))); + expect(info).toContain(`Run 'afx workspace start' to activate this workspace`); + expect(info).not.toContain(`Run 'afx tower start' to activate this workspace`); + }); + + it('continues to recommend tower start when Tower is not running', async () => { + mockIsRunning.mockResolvedValue(false); + + await status(); + + const info = mockLoggerInfo.mock.calls.map((c) => stripAnsi(String(c[0]))); + expect(info).toContain(`Run 'afx tower start' to start the tower daemon`); + expect(info).not.toContain(`Run 'afx workspace start' to start the tower daemon`); + }); +}); diff --git a/packages/codev/src/agent-farm/commands/status.ts b/packages/codev/src/agent-farm/commands/status.ts index 29309326f..ebb003fae 100644 --- a/packages/codev/src/agent-farm/commands/status.ts +++ b/packages/codev/src/agent-farm/commands/status.ts @@ -265,7 +265,7 @@ export async function status(options: StatusOptions = {}): Promise { // Workspace not found in tower, show "not active" logger.kv('Workspace', chalk.gray('not active in tower')); - logger.info(`Run 'afx tower start' to activate this workspace`); + logger.info(`Run 'afx workspace start' to activate this workspace`); return; }