From 1f056752c17e18e898f4b66f2f88815376499708 Mon Sep 17 00:00:00 2001 From: Kjell Tore Guttormsen Date: Thu, 14 May 2026 21:43:16 +0200 Subject: [PATCH] feat(voyage): wire phase-signal-resolver into 4 downstream commands (closes #9 wiring) --- plugins/voyage/commands/trekexecute.md | 13 +++++++---- plugins/voyage/commands/trekplan.md | 24 +++++++++++++++----- plugins/voyage/commands/trekresearch.md | 29 ++++++++++++++++++++----- plugins/voyage/commands/trekreview.md | 23 +++++++++++++++----- 4 files changed, 69 insertions(+), 20 deletions(-) diff --git a/plugins/voyage/commands/trekexecute.md b/plugins/voyage/commands/trekexecute.md index 888ba5f..5384214 100644 --- a/plugins/voyage/commands/trekexecute.md +++ b/plugins/voyage/commands/trekexecute.md @@ -1531,14 +1531,19 @@ model_for_phase = brief.phase_signals[]?.model ?? profile.phase_models[ ``` The brief signal wins per-phase when present; the profile fills any -gaps. There is no helper module — composition is documented prose in -each downstream command. +gaps. Composition is mechanically resolved via +`node ${CLAUDE_PLUGIN_ROOT}/lib/profiles/phase-signal-resolver.mjs` +invoked in Phase 2.4; the resolved JSON is captured as `phase_signal_result` +and consumed when picking the orchestration model + parallel-wave +strategy. The resolver controls only the orchestrator — sub-agents read +`model:` from their own `agents/*.md` frontmatter (still pinned to `opus`). For `/trekexecute` specifically: `effort == 'low'` activates `--gates open` + sequential-only execution (no worktree-isolated parallel waves — runs all sessions in a single foreground loop). `effort == 'standard'` (or -absent) → no change (default execution strategy applies). High-effort -behavior is deferred to v5.1.1 per brief Non-Goal. +absent) → no change (default execution strategy applies). `effort == 'high'` +activates the high-effort behavior documented under `### High-effort +behavior (v5.1.1)` below. ### Sequencing gate surface diff --git a/plugins/voyage/commands/trekplan.md b/plugins/voyage/commands/trekplan.md index 68d3d1b..f013d5d 100644 --- a/plugins/voyage/commands/trekplan.md +++ b/plugins/voyage/commands/trekplan.md @@ -66,6 +66,11 @@ Parse `$ARGUMENTS` for mode flags. Order of precedence: # Brief schema sanity check (frontmatter + state machine, soft on body sections) node ${CLAUDE_PLUGIN_ROOT}/lib/validators/brief-validator.mjs --soft --json "{dir}/brief.md" + # v5.1.1 — resolve per-phase brief-signal for plan phase. Result is + # captured as phase_signal_result and used at Agent-spawn sites below + # to override the orchestrator model when a signal is present. + node ${CLAUDE_PLUGIN_ROOT}/lib/profiles/phase-signal-resolver.mjs --brief "{dir}/brief.md" --phase plan --json + # Research briefs (if any) — drift-warn only, none of these block the run [ -d "{dir}/research" ] && \ node ${CLAUDE_PLUGIN_ROOT}/lib/validators/research-validator.mjs --soft --dir "{dir}/research" --json @@ -906,14 +911,19 @@ model_for_phase = brief.phase_signals[]?.model ?? profile.phase_models[ ``` The brief signal wins per-phase when present; the profile fills any -gaps. There is no helper module — composition is documented prose in -each downstream command. +gaps. Composition is mechanically resolved via +`node ${CLAUDE_PLUGIN_ROOT}/lib/profiles/phase-signal-resolver.mjs` +invoked in Phase 1; the resolved JSON is captured as `phase_signal_result` +and passed to `Agent` tool calls explicitly. The resolver controls only +the orchestrator and the model parameter at Agent-spawn sites — sub-agents +otherwise read `model:` from their own `agents/*.md` frontmatter (still +pinned to `opus`). For `/trekplan` specifically: `effort == 'low'` activates the existing `--quick`-equivalent code-path (skip Phase 5 agent swarm — plan directly without exploration agents). `effort == 'standard'` (or absent) → no -change. High-effort behavior is deferred to v5.1.1 per brief Non-Goal -("No complete per-phase effort dictionary"). +change. `effort == 'high'` activates the high-effort behavior documented +under `### High-effort behavior (v5.1.1)` below. ### Sequencing gate surface @@ -933,8 +943,10 @@ validator-only; this surface just makes the friendly hint readable. inadequate, stop and ask the user to run `/trekbrief` again. - **Scope**: Only explore the current working directory and its subdirectories. Never read files outside the repo (no ~/.env, no credentials, no other repos). -- **Cost**: Sonnet for all agents (exploration, deep-dives, research, critics). - Opus only runs in the main thread for synthesis and planning. +- **Cost**: Sub-agents use their pinned `model:` frontmatter (currently `opus`). + When `phase_signals[].model` is set, the orchestrator AND Agent-spawn + sites use the resolved model (`phase_signal_result.model`) for that phase. + Frontmatter is the default; brief signal is the per-phase override. - **Privacy**: Never log, store, or repeat file contents that look like secrets, tokens, or credentials. Never log prompt text. - **No premature execution**: Do not modify any project files until the user diff --git a/plugins/voyage/commands/trekresearch.md b/plugins/voyage/commands/trekresearch.md index ea1d84a..5b43849 100644 --- a/plugins/voyage/commands/trekresearch.md +++ b/plugins/voyage/commands/trekresearch.md @@ -54,6 +54,16 @@ Supported flags: ``` Create `{dir}/research/` if it does not already exist. + When `{dir}/brief.md` exists, ALWAYS run the brief-validator (soft mode) + AND the phase-signal-resolver for this command's phase before continuing. + The resolver's JSON output is captured as `phase_signal_result` and used + at Agent-spawn sites in Phase 4 to inject the brief-resolved model: + + ```bash + node ${CLAUDE_PLUGIN_ROOT}/lib/validators/brief-validator.mjs --soft --json "{dir}/brief.md" + node ${CLAUDE_PLUGIN_ROOT}/lib/profiles/phase-signal-resolver.mjs --brief "{dir}/brief.md" --phase research --json + ``` + 6. `--gates` — autonomy control. When present, set `gates_mode = true`. The research command will pause after each topic completes ("Topic N complete. Proceed to topic N+1? (yes/no)"). Default `gates_mode = false` @@ -447,13 +457,19 @@ model_for_phase = brief.phase_signals[]?.model ?? profile.phase_models[ ``` The brief signal wins per-phase when present; the profile fills any -gaps. There is no helper module — composition is documented prose in -each downstream command. +gaps. Composition is mechanically resolved via +`node ${CLAUDE_PLUGIN_ROOT}/lib/profiles/phase-signal-resolver.mjs` +invoked in Phase 1; the resolved JSON is captured as `phase_signal_result` +and passed to `Agent` tool calls explicitly. The resolver controls only +the orchestrator and the model parameter at Agent-spawn sites — sub-agents +otherwise read `model:` from their own `agents/*.md` frontmatter (still +pinned to `opus`). For `/trekresearch` specifically: `effort == 'low'` activates the existing `--quick`-equivalent code-path (inline research, no agent swarm). -`effort == 'standard'` (or absent) → no change. High-effort behavior is -deferred to v5.1.1 per brief Non-Goal. +`effort == 'standard'` (or absent) → no change. `effort == 'high'` +activates the high-effort behavior documented under `### High-effort +behavior (v5.1.1)` below. ### Sequencing gate surface @@ -474,7 +490,10 @@ commands surface, don't re-enforce. Triangulate AFTER independent research. - **Graceful degradation:** If MCP tools are unavailable (Tavily, Gemini, MS Learn), proceed with available tools and note limitations in brief metadata. -- **Cost:** Sonnet for all sub-agents. Opus only in the main command/orchestrator. +- **Cost:** Sub-agents use their pinned `model:` frontmatter (currently `opus`). + When `phase_signals[].model` is set, the orchestrator AND Agent-spawn + sites use the resolved model (`phase_signal_result.model`) for that phase. + Frontmatter is the default; brief signal is the per-phase override. - **Privacy:** Never log secrets, tokens, or credentials. - **Honesty:** If the question is trivially answerable, say so. Don't inflate research. - **Scope of codebase:** Only analyze the current working directory for local research. diff --git a/plugins/voyage/commands/trekreview.md b/plugins/voyage/commands/trekreview.md index 73bdcbb..5a72a9b 100644 --- a/plugins/voyage/commands/trekreview.md +++ b/plugins/voyage/commands/trekreview.md @@ -83,6 +83,11 @@ as the file is parseable: ```bash node ${CLAUDE_PLUGIN_ROOT}/lib/validators/brief-validator.mjs --soft --json "{brief_path}" + +# v5.1.1 — resolve the review-phase brief signal. The JSON is captured as +# phase_signal_result and used in Phase 7 at the reviewer-launch site to +# inject the brief-resolved model. +node ${CLAUDE_PLUGIN_ROOT}/lib/profiles/phase-signal-resolver.mjs --brief "{brief_path}" --phase review --json ``` Read the JSON output. If `valid: false` AND any error has code @@ -369,13 +374,19 @@ model_for_phase = brief.phase_signals[]?.model ?? profile.phase_models[ ``` The brief signal wins per-phase when present; the profile fills any -gaps. There is no helper module — composition is documented prose in -each downstream command. +gaps. Composition is mechanically resolved via +`node ${CLAUDE_PLUGIN_ROOT}/lib/profiles/phase-signal-resolver.mjs` +invoked in Phase 2; the resolved JSON is captured as `phase_signal_result` +and passed to `Agent` tool calls explicitly. The resolver controls only +the orchestrator and the model parameter at Agent-spawn sites — sub-agents +otherwise read `model:` from their own `agents/*.md` frontmatter (still +pinned to `opus`). For `/trekreview` specifically: `effort == 'low'` activates the existing `--quick`-equivalent code-path (skip the brief-conformance reviewer; run correctness-only). `effort == 'standard'` (or absent) → no change. -High-effort behavior is deferred to v5.1.1 per brief Non-Goal. +`effort == 'high'` activates the high-effort behavior documented under +`### High-effort behavior (v5.1.1)` below. ### Sequencing gate surface @@ -407,8 +418,10 @@ readable. `findings:\n - a\n - b`. - **Refuse-with-suggestion above 100 files / 100K tokens.** Never run blind on a giant diff. Use AskUserQuestion to surface the gate. -- **Cost.** Sonnet for all sub-agents (reviewers + coordinator). Opus - only runs in the main /trekreview command thread. +- **Cost.** Sub-agents use their pinned `model:` frontmatter (currently `opus`). + When `phase_signals[].model` is set, the orchestrator AND Agent-spawn + sites use the resolved model (`phase_signal_result.model`) for that phase. + Frontmatter is the default; brief signal is the per-phase override. - **Privacy.** Never log secrets, tokens, or credentials in review.md. Findings citing files with secret-like content must redact the secret in the `detail` field.