Design: Feedback Review
Context
This is the heart of Stet: the editorial loop where a human reads AI-written code and directs changes without typing code. It realizes ADR-0006 (accumulate → submit → compile → one coherent PR), ADR-0005 (emoji/comment verbs as declarative workflows), ADR-0008 (Tour mode narration), and the viewer posture of ADR-0002. It sits on SPEC-0001's canvas/inbox/forge and produces the brief consumed by SPEC-0003's dispatch engine.
The design problem is capturing rich, multi-modal human intent (text, emoji, voice, gesture) as precisely-anchored structured data, then compiling it into a coherent agent brief — without ever letting the tool become an editor.
Goals / Non-Goals
Goals
- A pending-review model that accumulates anchored markup with zero side effects until Submit.
- Multi-modal capture: anchored comments/suggestions, emoji verbs, voice notes, scribble/strike-through gestures.
- Emoji/comment verbs resolved through data-driven verb packs (ADR-0005), never hardcoded.
- A Submit step that compiles markup into a structured brief and groups it into one coherent PR by default.
- A Tour rail that renders authored narration (and generates it on demand) and drives the canvas.
- A reply/iterate path against an existing PR.
Non-Goals
- Executing the brief (containers, harnesses, workflows) — SPEC-0003.
- Authoring/editing verb-pack workflow YAML in-app (a later capability); v1 ships a curated default pack loaded as data.
- Multiplayer markup, emoji voting, auto-approval thresholds — future (ADR mentions as down-the-road).
Decisions
Pending-review model
A PendingReview aggregates ReviewItems. Each ReviewItem has: an anchor
(file + line range, or a tour-stop reference), a verb (resolved from the active
verb pack, or comment/suggestion for plain items), and an intent payload
(text, transcribed voice, or captured gesture/suggestion span). Items are pure
data; adding them mutates only the pending model and the canvas overlay. A visible
pending indicator shows count and a Submit affordance, mirroring a GitHub draft
review.
Multi-modal capture
- Comment/suggestion: selection in the canvas → anchored text; suggestions capture intended replacement text.
- Emoji verb: a reaction palette; selecting an emoji records the verb id from the active pack.
- Voice: press-and-hold key starts capture; on-device transcription (Speech.framework) yields comment text anchored to the current selection.
- Scribble/strike-through: a gesture recognizer over the canvas captures a span and classifies it as a removal/replacement suggestion; the recognized span is the anchor.
Verb packs
A VerbPack is loaded as data (bundled default; user packs later). It maps an
emoji (or comment tag) → a workflow id and a human label. The pack only names the
workflow; the workflow definitions live in the dispatch layer (SPEC-0003,
ADR-0005). This keeps the review UI decoupled from execution.
Brief compilation
On Submit, a BriefCompiler transforms the PendingReview into a Brief: a
normalized, serializable structure listing each item's verb, anchor, and intent,
plus resolved workflow references. Grouping (one PR vs. several) is an
LLM-assisted step: the compiler proposes a grouping with rationale; the default is
one group. The Brief is the stable contract with SPEC-0003 — versioned, so the
dispatch engine and review UI can evolve independently.
Tour mode
A Narration is an ordered list of Stop { anchor, why, risk }. For Stet-dispatched
PRs, the narration arrives as an authored artifact from the harness (ADR-0004/0008).
For other PRs, a NarrationGenerator produces one on demand via the model, flagged
generated. The Tour rail renders stops; selecting one calls into SPEC-0001's
CanvasDocument to scroll + highlight. Each stop is a valid anchor, so markup at
a stop flows into the same PendingReview.
Iteration
A follow-up review on an existing PR compiles to a Brief tagged with the target
branch/PR; SPEC-0003 dispatches it against the same branch rather than opening a
new one.
Risks / Trade-offs
- Grouping correctness (ADR-0006's hard problem). One-vs-many is where bugs hide; we surface rationale and default to one group to stay predictable, and make it correctable before dispatch.
- Anchor stability across diffs. Anchors must survive when the underlying file changes between review and dispatch; anchors store enough context (path + range + surrounding hash) to re-locate.
- Transcription/gesture accuracy. Voice and scribble are delightful but fallible; both always produce editable text/intent the user can correct before Submit.
Migration / Rollout
Order: (1) pending-review model + anchored comments; (2) emoji verb palette + default
pack; (3) Submit → Brief (single-group) — enough to hand off to SPEC-0003;
(4) Tour rail rendering authored narration; (5) voice; (6) scribble; (7) grouping
rationale + splitting; (8) on-demand narration generation; (9) reply/iterate.
Open Questions
Briefschema versioning strategy shared with SPEC-0003.- How much grouping is deterministic vs. model-driven, and how to make it cheap.
- Anchor re-location algorithm when files drift between review and dispatch.