feat(§8.12/§8.3): main-view Ask cuts an edit branch and runs the question there (v0.54.0)

The AI "Ask" affordance (selection tooltip + prompt bar) had no response
surface on an entry's canonical `main` view: RFCView renders the human-
discussion panel there, not the chat panel, so a chat turn posted from the
reading view had nowhere to render — asking-while-reading silently did
nothing. AI chat is an editing activity (a turn can emit <change> proposals)
and only runs on an edit branch.

Option B: when Ask is invoked from main, transparently cut an edit branch via
the same dispatch as Start Contributing (promote-to-branch for active,
start-edit-branch for super-draft; idempotent — reuse an existing edit
branch), navigate onto it so the chat panel mounts, and run the question
(text + selected quote) as the branch's first chat turn once its view and
main_thread_id resolve. The turn fires from the message-load effect's
continuation (not a parallel effect) so a late message load can't clobber the
optimistic turn; a live ref keeps the latest submitChatTurn closure in reach.

Degrades gracefully: signed-out → login; a viewer who can't contribute has the
cut rejected server-side and the error surfaced (no spurious branch); asking
from a branch already, and Flag on main (human discussion thread), unchanged.

Frontend-only; the branch chat endpoints already work on a branch. SPEC §8.3
records the behavior; new RFCView unit tests + an e2e spec cover the flow.
backend 677 / frontend 66 / e2e 5 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ben Stull
2026-06-09 04:19:20 -07:00
parent ff88be2e91
commit 24596842ea
7 changed files with 374 additions and 8 deletions
+29
View File
@@ -23,6 +23,35 @@ skip versions are the composition of each intervening adjacent
release's steps in order — no A-to-B path is pre-computed beyond
that.
## 0.54.0 — 2026-06-09
**Minor — the AI "Ask" affordance now works from an entry's canonical view
(§8.12); no operator action required.**
AI chat is an editing activity (a turn can emit proposed edits) and only runs
on an edit branch. On an entry's canonical `main` view the right column is the
human-discussion panel, not the chat panel — so invoking "Ask" (the selection
tooltip or the prompt bar) from the reading view pushed a chat turn that had
nowhere to render: it silently did nothing. Surfaced by dogfooding a non-default
project's spec entry on a live deployment.
- **Asking while reading "just works" (Option B).** When Ask is invoked from
the canonical view, the app transparently cuts an edit branch via the same
dispatch as Start Contributing (`start-edit-branch` for a super-draft,
`promote-to-branch` for an active RFC — idempotent, so it reuses an existing
edit branch rather than double-cutting), navigates onto that branch so the
chat panel mounts, and runs the question (text + the selected quote) there
once the branch's chat thread has resolved. The viewer lands in the chat with
the streaming answer, quote intact.
- **Graceful degradation.** A signed-out viewer keeps the read-only path
(sign-in prompt; Ask disabled) and a viewer who cannot contribute has the
branch cut rejected server-side and the error surfaced — no silent no-op and
no spurious branch. Asking from a branch already, and Flag on the canonical
view (which still opens a human discussion thread), are unchanged.
Frontend-only: the branch chat endpoints already worked on a branch. No
database migration and no configuration change.
## 0.53.0 — 2026-06-09
**Minor — the branch/edit/body subsystem is now three-tier (project /