diff --git a/plugins/voyage/commands/trekbrief.md b/plugins/voyage/commands/trekbrief.md index 0036747..edafd94 100644 --- a/plugins/voyage/commands/trekbrief.md +++ b/plugins/voyage/commands/trekbrief.md @@ -288,6 +288,118 @@ Phase 3 complete: {N} questions asked across {M} sections. Proceeding to draft and review. ``` +## Phase 3.5 — Per-phase effort dialog + +Phase 3.5 is the v5.1 entry-point for **adaptive-depth execution**. After +Phase 3 has gathered intent / goal / success criteria / research plan, the +operator commits an effort level and (optional) model per downstream phase +(`research`, `plan`, `execute`, `review`). The committed signals are written +to brief frontmatter as a `phase_signals:` list that the four downstream +commands read via their `## Composition rule (v5.1)` section. + +### State requirements + +Before entering Phase 3.5 the following must be populated: + +- `state.intent` — the Phase 3 Intent answer (1+ paragraph) +- `state.goal` — the Phase 3 Goal answer +- `state.success_criteria` — at least one falsifiable SC +- `state.research_plan.topics` — list (may be empty) + +If any are absent: skip Phase 3.5 entirely and write `phase_signals_partial: +true` to the draft frontmatter. Do not block. + +### --quick mode + +If the operator launched with `--quick`: skip Phase 3.5 entirely and +auto-write `phase_signals_partial: true` to draft frontmatter. The brief +will satisfy the v5.1 sequencing gate without going through the dialog. + +### Default-derivation heuristic (LLM judgment, not algorithmic) + +Before each phase question, propose a default tier marked `(default)`. Use +these signals — they are weak heuristics, not rules: + +- `research_topics_count` → high (`high`), low (`low`), absent (`low`) +- `sc_count` (count of falsifiable SCs) → high (≥6 ⇒ `high`), low (≤2 ⇒ `low`) +- Goal complexity: keywords like "rewrite", "migration", "refactor across", + "new platform" ⇒ `high`; "typo", "small bugfix", "docs touch-up" ⇒ `low` +- Otherwise: `standard` + +Mix these into one proposed default per phase. Document the proposed tier +in the question body so the operator sees why it was picked. + +### The loop — 4 tier-coupled AskUserQuestion calls + +Loop over `[research, plan, execute, review]` in order. For each phase, +issue one `AskUserQuestion` with 3 options: + +| Option | Maps to phase_signals entry | +|--------|----------------------------| +| **Low effort** | `{phase: , effort: low, model: sonnet}` | +| **Standard (default)** | `{phase: , effort: standard}` *(model omitted — composition falls through to profile)* | +| **High effort** | `{phase: , effort: high, model: opus}` | + +The proposed tier per phase (from the default-derivation heuristic) MUST be +labelled `(default)` in the option list so the operator can one-click +accept. Commit the chosen tier immediately to an in-memory `effort_state` +dict — no bulk summary-before-commit. The loop is interruptible. + +The mapping table is canonical: +- `low → {effort: low, model: sonnet}` (force sonnet for the low-cost path) +- `standard → {effort: standard}` (model omitted; composition rule resolves via profile) +- `high → {effort: high, model: opus}` (force opus for the high-confidence path) + +### Force-stop handling + +If during any of the four `AskUserQuestion` calls the operator says "stop", +"skip", "enough", "just write it", or similar, do NOT exit silently — apply +the Phase 4f force-stop pattern verbatim: + +``` +You stopped before committing per-phase signals. Remaining phases: + - {list of phases not yet answered} + +The brief will still be valid (v5.1 supports `phase_signals_partial: true` +as a force-stop record). Downstream commands will fall back to the profile +resolver for the un-committed phases. + +Continue anyway? +``` + +Then `AskUserQuestion`: + +| Option | Action | +|--------|--------| +| **Answer one more phase** | Return to the next un-answered phase question. | +| **Stop now (record partial)** | Drop any in-progress `effort_state` and set `phase_signals_partial: true` in draft frontmatter. Mutually exclusive with `phase_signals`. Break Phase 3.5. | + +This pattern matches Step 4f (line 436-458) so the force-stop UX is +identical across both surfaces. + +### Hand-off to Phase 4a + +If `effort_state` is fully populated (4 commits, no force-stop): write a +`phase_signals:` block to draft frontmatter — one entry per phase, +preserving the canonical-mapping form above. Omit `model:` for standard +tier (composition falls through to profile). + +If `phase_signals_partial: true` was set: write that single line to draft +frontmatter and skip the `phase_signals:` block (mutually exclusive per +validator). + +Phase 4a (Step 4a — Draft in memory) reads from `effort_state` / +`phase_signals_partial` and incorporates the appropriate frontmatter block +into the draft brief. + +### Sequencing gate (downstream) + +`brief_version: 2.1` activates the validator's sequencing gate. If the +final brief reaches `/trekplan`, `/trekresearch`, `/trekexecute`, or +`/trekreview` WITHOUT `phase_signals` and WITHOUT `phase_signals_partial: +true`, the validator emits `BRIEF_V51_MISSING_SIGNALS` and the command +halts with a friendly hint pointing back to `/trekbrief`. + ## Phase 4 — Draft, review, and revise Phase 4 runs a **draft → brief-reviewer → revise** loop. The draft is