feat(fixture): mirror the goal domain — /goal command, six verbs, projection unit

The keyless fixture now carries the goal chain end to end, mirroring the
host: /goal enters the command catalog and its execute path brackets a
goal/change create with the command lifecycle pair; the six mutation verbs
CAS-check the projected current goal and append whole-value changes (the
shared append path broadcasts the session event and the goal projection
frame); the tail-page projections block and the mux-open baseline always
carry the goal key (null before create / after clear). Connection specs
follow: the lifecycle round-trip replaces the not-implemented stubs, and
the mux baseline expects the third unit frame.

Also: GoalBar inline errors use ASCII parens around the code (review
feedback on #842).
This commit is contained in:
imccyu
2026-07-29 01:40:23 +08:00
parent b0fc3b971b
commit 0477f33079
5 changed files with 204 additions and 28 deletions
@@ -150,7 +150,7 @@ describe('GoalBar', () => {
fireEvent.change(box, { target: { value: 'retry this draft' } })
fireEvent.click(screen.getByRole('button', { name: 'Save goal' }))
expect((await screen.findByRole('alert')).textContent).toBe('stale revision(agent-busy)')
expect((await screen.findByRole('alert')).textContent).toBe('stale revision (agent-busy)')
expect(screen.getByRole('textbox', { name: 'Goal objective' })).toHaveProperty('value', 'retry this draft')
})
@@ -159,12 +159,12 @@ describe('GoalBar', () => {
actions.onResume.mockResolvedValue({ ok: false, error: { code: 'internal', message: 'resume failed' } })
const { rerender } = render(<GoalBar goal={makeGoal({ phase: 'paused' })} {...actions} />)
fireEvent.click(screen.getByRole('button', { name: 'Resume goal' }))
expect((await screen.findByRole('alert')).textContent).toBe('resume failed(internal)')
expect((await screen.findByRole('alert')).textContent).toBe('resume failed (internal)')
actions.onClear.mockResolvedValue({ ok: false, error: { code: 'agent-busy', message: 'clear failed' } })
rerender(<GoalBar goal={makeGoal()} {...actions} />)
fireEvent.click(screen.getByRole('button', { name: 'Clear goal' }))
expect((await screen.findByRole('alert')).textContent).toBe('clear failed(agent-busy)')
expect((await screen.findByRole('alert')).textContent).toBe('clear failed (agent-busy)')
expect(screen.getByText('Ship the redesign')).toBeTruthy()
})
})