P4: writes via chat — Reginald proposes, you approve inline #43

Merged
christian merged 1 commits from p4/chat-writes into main 2026-07-09 02:17:46 +00:00

1 Commits

Author SHA1 Message Date
Croissant Le Doux
47c45ffa3e feat: writes via chat — Reginald proposes, you approve inline (P4)
Completes "chat is the write-path" (decisions.md D1). Ask Reginald to re-estimate
or reprioritize an issue; it formulates a proposal, you approve it inline, and the
write runs through the same guarded apply_changes engine the Issue screen uses.
The model never writes — it proposes; the app owns approval + execution.

core (@commitea/core):
- propose_change tool declaration + REGINALD_SYSTEM updated ("never claim a change
  is applied; you propose, the human approves").
- proposalsFor(args, currentLabels, title): pure — builds the concrete, non-noop
  ChangeProposal(s) (change + label diff) for a propose_change request, dropping
  invalid/unchanged axes. ChangeProposal / ProposeChangeArgs types.

app:
- model bridge executes propose_change by planning against the issue's current
  labels (no write) and returns the proposals with the turn.
- useChat surfaces pending proposals + approve/dismiss; approve calls onApplyChange
  (AppShell's guarded handler → PUT + board/forecast refetch), dismiss leaves it.
- ChatPanel renders each proposal as a propose-approve card (diff + Approve/Dismiss).

Verified: 101 core tests green (4 proposalsFor added), desktop typecheck clean,
14 fixture e2e green. Gated live e2e against gemma-4-26b: "Set the estimate on #3
to est/5d" → Reginald proposes "est/2d → est/5d" as an inline card, says it's
*proposed* not done; Dismiss leaves the repo untouched. The approve→write path is
the #41 engine (separately verified change→revert).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 21:38:25 -04:00