Contract-driven Claude Code pipeline: brief, research, plan, execute, review. Agent swarms, research triangulation, adversarial review, multi-session resumption.
  • JavaScript 96.4%
  • Shell 3.6%
Find a file
Kjell Tore Guttormsen f669b8775f
merge: order 10, the fix round before 6.3.0
A step of only tests can never be proven red: the plan validator warns
(PLAN_STEP_TESTS_ONLY), trekplan, the template and plan-critic say the
test belongs in the step that builds the behaviour, and the executor sends
such a step straight up to the plan. Also: timing tests tolerate one slow
run of three, the example plan uses the K11 words, trekreview knows
FINDING_PROSE_LINE_OUT_OF_RANGE and checks the whole reviewer text, the
criteria runner drops NODE_TEST_CONTEXT, and the resolver text says when
effort is absent. Branch suite 2128 (2126/0/2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:40:51 +02:00
.claude-plugin chore(release): 6.2.0 — intent, plan gate, step helpers, guards and a review that is a gate 2026-10-08 20:34:02 +02:00
.forgejo/ISSUE_TEMPLATE feat(execute)!: hand waves over as session orders, never start Claude Code (green) 2026-09-27 15:35:22 +02:00
agents fix: the fix round before 6.3.0 (order 10) 2026-10-09 22:16:12 +02:00
commands fix: the fix round before 6.3.0 (order 10) 2026-10-09 22:16:12 +02:00
docs fix: the fix round before 6.3.0 (order 10) 2026-10-09 22:16:12 +02:00
evals merge: main (7a skills workshop, 9 rettepakke) into wave2-skills-research 2026-10-09 19:34:38 +02:00
examples fix(examples): the verbose-content test moves into the step that wires it [skip-docs] 2026-10-09 22:24:03 +02:00
hooks fix(guard): refuse every asked-about call where no one can be asked 2026-10-09 19:36:21 +02:00
lib fix: the fix round before 6.3.0 (order 10) 2026-10-09 22:16:12 +02:00
scripts feat(release): a drilled release and rollback runbook, and a release check 2026-10-08 21:32:36 +02:00
skills merge: main (7a skills workshop, 9 rettepakke) into wave2-skills-research 2026-10-09 19:34:38 +02:00
templates fix: the fix round before 6.3.0 (order 10) 2026-10-09 22:16:12 +02:00
tests fix(examples): the verbose-content test moves into the step that wires it [skip-docs] 2026-10-09 22:24:03 +02:00
.gitignore test(evals): Voyage's fixed test set as a plugin eval suite, expectations written before the first run 2026-09-23 07:52:34 +02:00
CHANGELOG.md chore(release): 6.2.0 — intent, plan gate, step helpers, guards and a review that is a gate 2026-10-08 20:34:02 +02:00
CLAUDE.md merge: main (7a skills workshop, 9 rettepakke, 7b researching-sources, 8 release runbook) into wave2-kobling 2026-10-09 21:25:18 +02:00
CONTRIBUTING.md feat(execute): one fresh helper per step, a controller on the diff, proof by command 2026-10-06 19:58:18 +02:00
LICENSE feat(ultraplan-local): v1.6.0 — /ultraresearch-local deep research command 2026-04-08 08:58:35 +02:00
MIGRATION.md docs(readme): point the governance link at the catalog 2026-10-06 15:24:02 +02:00
package-lock.json chore(release): 6.2.0 — intent, plan gate, step helpers, guards and a review that is a gate 2026-10-08 20:34:02 +02:00
package.json chore(release): 6.2.0 — intent, plan gate, step helpers, guards and a review that is a gate 2026-10-08 20:34:02 +02:00
README.md merge: main (7a skills workshop, 9 rettepakke, 7b researching-sources, 8 release runbook) into wave2-kobling 2026-10-09 21:25:18 +02:00
SECURITY.md feat(hooks): wave-1 guards -- approval ask, plan gate, test lock, post-edit check 2026-10-06 20:09:32 +02:00
settings.json release(v5.10.1): drop gemini-bridge from the pipeline; correct the T1 §6 PoC status 2026-09-03 20:29:39 +02:00
TRADEMARKS.md feat(voyage)!: add TRADEMARKS.md disclaiming Anthropic affiliation [skip-docs] 2026-05-05 15:23:26 +02:00
verify.sh fix(verify): exclude cc-upgrade decision-matrix from SC1 (legitimate CC refs) 2026-06-30 06:37:28 +02:00

voyage

Contract-driven Claude Code pipeline: brief, research, plan, execute, review. Agent swarms, research triangulation, adversarial review, multi-session resumption.

Version License Platform

Solo-maintained, fork-and-own. This plugin is a starting point, not a vendor product. Issues are welcome as signals; pull requests are not accepted. See GOVERNANCE.md for the full model and what upstream provides.

AI-generated: all code produced by Claude Code through dialog-driven development. Every change is human-directed, reviewed, and validated before commit. Per Anthropic Consumer Terms §4, ownership of outputs is assigned to the user; this plugin is licensed MIT.

A Claude Code plugin for deep implementation planning, multi-source research, autonomous execution, independent post-hoc review, and zero-friction multi-session resumption. Six commands, one pipeline:

Command What it does
/trekbrief Brief — interactive interview produces a task brief with explicit research plan
/trekresearch Research — deep local + external research with triangulation
/trekplan Plan — agent swarm exploration, Opus planning, adversarial review
/trekexecute Execute — disciplined step-by-step implementation with failure recovery
/trekreview Review — independent post-hoc review of delivered code against the brief, severity-tagged findings
/trekcontinue Continue — read .session-state.local.json and resume the next session in a multi-session project

Install

claude plugin marketplace add https://git.fromaitochitta.com/open/ktg-plugin-marketplace.git
claude plugin install voyage@ktg-plugin-marketplace

Or enable directly in ~/.claude/settings.json:

{
  "enabledPlugins": {
    "voyage@ktg-plugin-marketplace": true
  }
}

/trekbrief, /trekplan, and /trekreview each end by running scripts/annotate.mjs against the just-written artifact and printing the resulting file://<abs path> link. The operator opens the HTML in a browser, clicks any line of the document, writes their own note in the inline textarea, watches a sidebar of all notes (editable, deletable, persisted in browser localStorage), and clicks "Copy Prompt" to get one structured prompt that they paste back into Claude — Claude then revises the .md from the notes. The operator drives every annotation. See Reviewing and annotating artifacts.

Every artifact lives in one project directory: .claude/projects/{YYYY-MM-DD}-{slug}/ contains brief.md, research/NN-*.md, plan.md, sessions/, progress.json, and review.md.

Division of labor

Command Responsibility Output
/trekbrief Capture intent — intent, goal, non-goals, success criteria, and a research plan with explicit topics. Interactive only. brief.md (task brief)
/trekresearch Gather context — code state, external docs, community, risk. Makes NO build decisions. research/NN-slug.md (research brief)
/trekplan Transform intent into an executable contract — per-step YAML manifest, regex-validated checkpoints, verifiable paths. Plan-critic is a hard gate. Auto-discovers architecture/overview.md as priors when an opt-in upstream architect plugin (not bundled) is installed. plan.md with Manifest blocks + plan_version: 1.7
/trekexecute Execute the contract disciplined — fresh verification, independent manifest audit, honest reporting. Does NOT compensate for weak plans — escalates. progress.json + structured report + manifest-audit status
/trekreview Close the loop — independent post-hoc reviewer reads brief.md and the diff produced by execute, runs brief-conformance + code-correctness reviewers in parallel, dedups via Judge Agent. Severity-tagged findings (Critical/High/Medium/Low/Info) feed back into planning via Handover 6. review.md (type: trekreview) with stable 40-char hex finding-IDs

Principle: Each step consumes the previous step's structured artifact. If execute has to guess, the plan is weak and must be revised upstream — not patched downstream.

Two kinds of briefs

Terminology matters:

  • Task brief — produced by /trekbrief. Captures what we want and why. Drives planning.
  • Research brief — produced by /trekresearch. Captures what we learned about a topic. Feeds planning.

A project typically has one task brief and zero-to-N research briefs.

Manifest-verified steps

Every step in the plan ends with a YAML manifest: block declaring expected_paths, commit_message_pattern, bash_syntax_check, forbidden_paths, must_contain. The executor checks the manifest against the resulting commit — a step may not be marked passed if its manifest does not verify, regardless of the Verify command's exit code (Hard Rule 17).

After all steps complete, /trekexecute runs Phase 7.5 — Manifest audit (independent): re-verifies every expected path from git log + filesystem, ignoring the agent's own bookkeeping. Drift → status partial, Phase 7.6 writes a bounded recovery order with only the missing steps (recovery_depth ≤ 2) for a session you open yourself, and the run stops as partial. Step 0 pre-flight (git push --dry-run) runs inside every session sandbox before any real work — exit 77 sentinel catches sandbox push-denial before the agent wastes the whole budget.

No cloud dependency. No GitHub requirement. Works on Mac, Linux, and Windows.

Autonomy mode (--gates, v3.4.0)

All four pipeline commands accept --gates {open|closed|adaptive} to control how many autonomy checkpoints surface to the operator on the path from brief approval to main-merge.

Value Behavior
open Skip optional checkpoints. The pipeline runs end-to-end with the fewest interruptions. Suitable for trusted briefs in clean repos.
closed Stop at every checkpoint. The operator confirms each transition. Suitable for high-stakes work or unfamiliar repos.
adaptive (default) Stop only when the autonomy-gate state machine reports a meaningful boundary (manifest-audit FAIL, plan-critic BLOCKER, main-merge gate). Best balance of velocity and safety.

Under the hood, lib/util/autonomy-gate.mjs runs a small state machine (idle → gates_on | auto_running → paused_for_gate → completed), and lib/stats/event-emit.mjs records named lifecycle events (the main-merge gate and its answer, among others) to trekexecute-stats.jsonl in the plugin data directory. The new hooks/scripts/post-compact-flush.mjs PostCompact hook re-injects .session-state.local.json after context compaction so multi-session work survives a compaction boundary.

Quick start

# Capture intent (interactive)
/trekbrief Add user authentication with JWT tokens
# → .claude/projects/2026-04-18-jwt-auth/brief.md

# Research each topic identified in the brief (manual default)
/trekresearch --project .claude/projects/2026-04-18-jwt-auth --external "What are current JWT best practices?"

# Plan from brief + research
/trekplan --project .claude/projects/2026-04-18-jwt-auth

# Execute
/trekexecute --project .claude/projects/2026-04-18-jwt-auth

# Review (independent post-hoc verification of the diff against brief.md)
/trekreview --project .claude/projects/2026-04-18-jwt-auth
# → .claude/projects/2026-04-18-jwt-auth/review.md

Or opt into auto-mode in /trekbrief — it will run research and planning sequentially inline in the main context, and return when plan.md is ready.

If review finds issues, feed review.md back into planning to produce a remediation plan: /trekplan --brief .claude/projects/2026-04-18-jwt-auth/review.md. The remediation plan carries source_findings: [<id>, ...] in its frontmatter — full audit trail back to the consumed findings (Handover 6).

An optional architect step can sit between research and plan — /trekplan auto-discovers an architecture/overview.md produced by an opt-in upstream architect plugin (not bundled here; the architect plugin is no longer publicly distributed, but the architecture/overview.md filesystem slot remains available for any compatible producer).

When to use it

Use it when:

  • The task touches 3+ files or modules and you need to understand how they connect
  • You're working in an unfamiliar codebase and need a map before you start
  • The implementation has non-obvious dependencies, ordering constraints, or risks
  • You want a reviewable plan before committing to an approach
  • You want execution that asks no questions — every recovery decision comes from the plan
  • You need to research a technology, library, or approach before deciding

Don't use it when:

  • The task is a single-file change where the fix is obvious
  • You already know exactly what to change and in what order

Rule of thumb: If you can describe the full implementation in one sentence and it touches 1-2 files, skip trekplan and just implement. If you need to think about it, trekplan earns its cost.

What you get

Concrete capabilities, observable in the code — not aspirations.

Across all profiles:

  • Strategy-to-execution on four explicit handover points. Each transition is a filesystem contract (docs/HANDOVER-CONTRACTS.md), not a conversation. You can stop after any stage and resume later without context loss.
  • Resume safety after long sessions. The PreCompact hook reconciles progress.json with git history before context compaction (CC v2.1.105+) — closes a documented --resume failure mode.
  • Schema discipline. plan-validator --strict enforces ### Step N: form and rejects narrative drift (### Fase, ### Phase, ### Stage, ### Steg) before execution.
  • Audit trail by construction. Every executed step records commit_sha, verify_passed, files_changed in progress.json.

Solo developer. Plans survive across sessions; adversarial review (plan-critic + scope-guardian) catches your own tunnel vision before code is written; brief-phase forces clarity on what the task actually is. examples/01-add-verbose-flag/ shows what good shape looks like.

Team (2–10). Plan files are handover-ready — a colleague can pick up a project directory without re-asking "what did you mean here?". --decompose splits a plan into self-contained session specs plus orders.md, one starter line per session that each person runs in a session they open. The plan-critic semantic rubric gives the team a shared definition of "this plan defers decisions to the executor".

Virksomhet / regulated environment. Defense-in-depth security across three layers (plugin hooks, prompt-level denylist, pre-execution plan scan). disableSkillShellExecution: true recommendation for fork-ers handling untrusted briefs. No cloud dependency, no GitHub requirement. Validators are plain-Node CLIs — invocable from CI, custom hooks, or external tools, not just from voyage commands.

Non-goals

What this pipeline does not solve — read this before adopting it:

  • LLM output truthfulness. Validators check shape, not facts. A plan with hallucinated paths passes schema but fails in execute. Plan-critic catches some, not all.
  • Multi-user concurrency on a single project directory. Two simultaneous executors will clobber progress.json.
  • Cost management. Opus on the orchestrator layer is expensive; documented in Cost profile, no automatic model downgrade.
  • Linear/Jira/Slack integrations. Intentional omission — solo project, no enterprise wiring.

One-line summary: an executable contract pipeline where each stage is filesystem-validated, session-survivable, and skill-independent — in exchange for writing an actual brief before planning and an actual plan before coding.


/trekbrief — Brief

Interactive requirements-gathering command. Runs a question round sized to the task and produces a task brief with an explicit research plan. Optionally orchestrates the rest of the pipeline.

Ceremony by size. The task is put in one of three classes, small, bounded or architectural (the heaviest when in doubt), said aloud, overridable by you, and only ever moved up when the task proves bigger. The class sets the question budget (a small task: at most 4 questions, in one round) and the review cap, and is written to the brief as ceremony:.

The question round. Facts are looked up in the repo, never asked. Every question that can be answered now is asked at once, the recommended answer first, ranked by impact × uncertainty; what the budget leaves out is on a visible Deferred list, and what can be predicted is written down as an assumption you see before approving. «Høres bra ut», «gjør som du vil» and an empty answer decide nothing.

Then brief-reviewer scores the draft on six dimensions (completeness, consistency, testability, scope clarity, research-plan validity, memory alignment) and gates publication, up to 1 / 2 / 3 review iterations by class; force-stop yields a brief_quality: partial brief with the failing dimensions documented.

Approval, logged and committed. Every run ends with you approving ## Intent + ## Goal (only an explicit "Approve" counts). The approval is appended to the target repo's hash-chained approval log, .claude/voyage/approvals.jsonl, bound to the intent's sha256, and committed. The log is always committed; the brief only when you chose "in git" for this task (artifact_store: git). "Only on this machine" keeps the project folder out of git via .git/info/exclude. The log is a trace, not a signature: any session on your machine could write it, and the commit is what makes it visible.

Output: .claude/projects/{YYYY-MM-DD}-{slug}/brief.md

Borrowed, with credit: size classes and the ratchet from obra/superpowers (MIT), the class ladder from Kiro's docs (idea only), the round from mattpocock/skills (MIT), the budget and Deferred list from GitHub Spec Kit (MIT), the stop rule and hollow answers from addyosmani/agent-skills (MIT), the hash-chained log from bashebr/ai-native-sdlc (MIT). Pinned commits in commands/trekbrief.md Phase 3 and lib/util/approval-log.mjs.

Modes

Mode Usage Behavior
Default /trekbrief <task> Question round sized by class, then review and approval.
Quick /trekbrief --quick <task> Proposes small as the class; still said aloud, overridable, and raised if the task proves bigger.
Profile /trekbrief --profile <name> <task> (v4.1.0) Pin model profile for the brief phase: economy / balanced / premium / fable / <custom>. See Profile system below.
Approve /trekbrief --approve <project-dir | brief-file> No interview: show an existing brief's ## Intent + ## Goal verbatim and ask the operator to approve them; on "Approve" it also writes the trekbrief stats record. The same step (Phase 4h) ends every normal /trekbrief run.

/trekbrief is always interactive. There is no foreground/background mode — the interview requires user input.

Force-stop

If you say "stop" or "enough" during Phase 4, the current review findings are surfaced with per-dimension scores and you choose:

  • Answer one more follow-up — the loop continues.
  • Stop now (accept partial brief) — the brief is finalized with brief_quality: partial and a ## Brief Quality section listing the failing dimensions. Downstream planning will treat these as reduced-confidence areas.

What the brief contains

  • Intent — why this matters, motivation, user need (load-bearing)
  • Goal — concrete end state in 1-3 sentences
  • Non-Goals — explicitly out of scope
  • Constraints / Preferences / NFRs — technical, time, resource limits
  • Success Criteria — 2-4 falsifiable commands/observations
  • Research Plan — N topics, each with research question, scope (local/external/both), confidence needed, cost estimate, and a ready-to-run /trekresearch command
  • Open Questions / Assumptions — from "I don't know" answers and implicit gaps, what was assumed instead of asked, and the Deferred list
  • Prior Attempts — what worked/failed before

/trekresearch — Research

Deep, multi-phase research that combines local codebase analysis with external knowledge. Uses specialized agent swarms to investigate multiple dimensions in parallel, then triangulates findings.

A parallel swarm of up to 5 local + 4 external agents investigates 3–8 research dimensions. Findings are triangulated (local vs. external, confidence per dimension, contradictions flagged) and synthesized into a structured research brief.

Output:

  • With --project <dir>: {dir}/research/{NN}-{slug}.md (auto-incremented index)
  • Without: .claude/research/trekresearch-{date}-{slug}.md

Modes

Mode Usage Behavior
Default /trekresearch <question> Interview + research swarm (local + external), foreground
Project /trekresearch --project <dir> <question> Write brief into {dir}/research/NN-slug.md
Quick /trekresearch --quick <question> Interview (short) + inline research, no agent swarm
Local /trekresearch --local <question> Only codebase analysis agents (skip external research)
External /trekresearch --external <question> Only external research agents (skip codebase analysis)
Foreground /trekresearch --fg <question> No-op alias (foreground is default since v2.4.0)
Profile /trekresearch --profile <name> <question> (v4.1.0) Pin model profile for the research phase. See Profile system.
Engine /trekresearch --external --engine deep-research <question> Delegate the external phase to Claude Code's built-in /deep-research workflow. Only works on 2.1.154 <= CC < 2.1.218; from 2.1.218 /deep-research is operator-invoked only (Skill tool: disable-model-invocation), so it always falls back to swarm. Never hard-fails. Default swarm.

Flags combine: --project <dir> --external.

Bounded conversation loop (default-off)

At effort: high, research can discover additional dimensions (Phase 4.5) and run a bounded multi-turn follow-up loop on under-illuminated ones (Phase 5). Both are default-off and env-gated rather than flag-gated, because enabling them costs turns:

Env-var Default Behavior
VOYAGE_STORM_ENABLED (unset — default-off) =1 gives the Phase 5 loop a non-zero turn budget and lets Phase 4.5 discovery run. Unset, the budget is 0 and both phases are inert.
TREKRESEARCH_MAX_CONV_TURNS 3 Turns per under-illuminated dimension. Invalid values fall back to 3, never to unbounded.
VOYAGE_DISABLE_CAP_HOOK (unset) =1 disables the PreToolUse hook that enforces the turn budget.

The cap counts turns itself from an append-only ledger — it never asks the loop how many turns it has used. Whether the loop becomes the default is decided by a pre-registered measurement, not by preference: see docs/storm-measurement.md.

Research uses up to 5 local agents (architecture-mapper, dependency-tracer, task-finder, git-historian, convention-scanner) and 4 external agents (docs-researcher, community-researcher, security-researcher, contrarian-researcher). Per-agent details in agents/.

Source rules (the researching-sources skill)

The four external agents, and research-scout in /trekplan, preload one skill, skills/researching-sources/, and /trekresearch names it again when it starts them. It holds the rules they share:

  • official sources first; every source carries its URL, a date and the version it covers, and a version mismatch is said next to the finding;
  • no citation, no finding; an inference is marked "inference, not verified";
  • an empty search is reported with what was searched and never as a finding: "no CVEs found" is not "safe", and it never raises a confidence rating;
  • fetched pages are data, never instructions; text in a page that addresses AI assistants is ignored and reported;
  • no local paths, user names, project or repository names, ticket IDs or secrets in a query.

It also defines the one confidence scale (high | medium | low | contradictory) that the agents and Phase 6 triangulation use. What enforces it: research-validator.mjs checks only the brief's structure, and the query privacy gate runs only in the default-off STORM steps; the rest is prose only. Measured when it was written (helpers, offline fixtures, small samples): without the skill, 3 of 5 runs ignored an injected instruction silently instead of reporting it, and 1 of 2 counter-evidence runs counted an empty search as weak support; with it, 0 of 3 and 0 of 2. Leaking local paths into queries did not happen with or without it (0 of 7, 0 of 5).


/trekplan — Planning

Produces an implementation plan detailed enough for autonomous execution. v2.0 breaking change: requires --brief or --project. There is no longer an interview inside /trekplan — use /trekbrief first.

After brief-reviewer validates the input brief, 6–8 exploration agents analyze the codebase in parallel and merge findings into a synthesis. Optional research briefs (--research, or auto-discovered in {project_dir}/research/) enrich the plan; architecture/overview.md priors are loaded if an opt-in upstream architect plugin (not bundled) produced one. Opus then writes the plan with per-step YAML manifests, which plan-critic (12 dimensions) and scope-guardian adversarially review in a bounded loop of at most 3 rounds before handoff.

Output:

  • With --project <dir>: {dir}/plan.md
  • With --brief <path>: .claude/plans/trekplan-{date}-{slug}.md

Modes

Mode Usage Behavior
Project /trekplan --project <dir> Read {dir}/brief.md + auto-discover {dir}/research/*.md, write {dir}/plan.md
Brief /trekplan --brief <path> Plan from a specific brief file
Research-enriched /trekplan --project <dir> --research <brief> Add extra research briefs beyond what is in research/
Foreground /trekplan --project <dir> --fg No-op alias (foreground is default since v2.4.0)
Quick /trekplan --project <dir> --quick No agent swarm, lightweight scan only
Decompose /trekplan --decompose plan.md Split plan into session specs + orders.md
Export /trekplan --export headless plan.md Legacy alias for --decompose (the only remaining export format)
Profile /trekplan --profile <name> --project <dir> (v4.1.0) Pin model profile; emitted as profile: in plan.md frontmatter. See Profile system.

--brief or --project is required. /trekplan with no brief exits with an error and a pointer to /trekbrief.

Intent approval gate. /trekplan halts before planning anything unless the brief's ## Intent + ## Goal carry the operator's approval. /trekbrief asks for it at the end of every interview (Phase 4h, also in --quick), or run /trekbrief --approve <project-dir | brief-file> later. The approval is a hash over those two sections: edit either one afterwards and /trekplan halts again until the new text is approved. Review briefs (type: trekreview) are exempt. The marker is a trace that the approval step ran, not a signature. Any session on the same machine could write it.

What the plan contains

Every plan includes:

  • Context — derived from brief ## Intent + ## Goal
  • Global Constraints — the brief's constraints that bind several steps, quoted verbatim
  • Design — only when the brief's ceremony is architectural (absent = architectural): architecture, data flow, interfaces, data models, error handling, a module map with no cycles, architecture rules that each name their enforcer, and a requirements check asked as keep / change questions
  • Architecture Diagram — Mermaid C4-style component diagram
  • Codebase Analysis — tech stack, patterns, relevant files, reusable code
  • Research Sources — findings from research briefs (when present)
  • Implementation Plan — ordered steps with file paths, changes, failure recovery, and git checkpoints
  • Per-step Manifest — YAML block with expected_paths, commit_message_pattern, bash_syntax_check, forbidden_paths, must_contain
  • Alternatives Considered — other approaches with pros/cons
  • Test Strategy — from test-strategist findings
  • Risks and Mitigations — from risk-assessor findings
  • Verification — testable end-to-end criteria
  • Execution Strategy — session grouping and parallel waves (plans with > 5 steps)
  • Plan Quality Score — quantitative grade (A-D) across 7 weighted dimensions
  • Critic Verdict — the last critic round's machine-readable verdict, written by plan-gate.mjs --record

Every implementation step includes:

  • Test first: — the test the step makes pass (required from plan_version 1.8)
  • Interface in: / Interface out: / Review focus: — optional: what the step consumes and produces, and the untested inputs it pins to a test
  • Regression: — optional: one runnable suite command (npm test, no pipe, no &&) run green before the checkpoint, while Verify: stays the step's own red-first test; the validator refuses one that can never run
  • On failure: — what to do when verification fails; it opens with revert, retry, skip or escalate, or the validator warns
  • Checkpoint: — git commit after success
  • Manifest: — the objective completion predicate (Hard Rule 17)

One step per plan is the "run the thing" step (End-to-end:): the product run the way a user runs it. Without it a result is "not verified end to end", never green.

Exploration uses 6–8 agents in parallel (architecture-mapper, dependency-tracer, task-finder, test-strategist, git-historian, risk-assessor, plus convention-scanner on medium+ codebases and research-scout when unfamiliar tech is detected). Adversarial review then runs brief-reviewer, plan-critic (12 dimensions, no-placeholder enforcement, manifest audit, interfaces and slices, design and architecture rules), and scope-guardian (creep + gap detection, ceremony match). Per-agent details in agents/.

The plan gate. Each critic round is written into the plan by lib/validators/plan-gate.mjs --record; plan-gate.mjs <plan.md> then exits 0 (go on), 1 (stop: invalid plan, no verdict, a verdict the plan has changed since, or an open BLOCKER) or 2 (could not run). After 3 rounds with a BLOCKER open, /trekplan stops and asks; it never continues silently, and "execute" is offered only when the gate exits 0. Minors still open after the last round are listed numbered in the summary; the ones you pick are fixed and get one more round, the rest are carried. In Claude Code's plan mode the plan is written to Claude Code's plan file and approved through its own approval prompt (that /trekplan runs cleanly inside plan mode is not verified yet).

Checks the plan hands on (0 / 1 / 2, and 2 = "not measured", never green): lib/verification/arch-rules.mjs --repo <dir> runs the target repo's own dependency-cruiser or import-linter — Voyage installs nothing — and --prove shows a rule pass, fail on a planted violation, and pass again; lib/verification/plan-scope-sweep.mjs --plan <plan.md> --base <ref> lists changed files that no step names.

Borrowed, with credit: per-step interfaces, Global Constraints and Review Focus from obra/superpowers (MIT); the design sections and the bounded review loop from Kiro's documentation; the module map and "use the repo's own tool" from addyosmani/agent-skills (MIT); vertical slices, deep modules, the ADR bar and pass → fail → pass from mattpocock/skills (MIT); rules that name their enforcer, adapted from GitHub Spec Kit's constitution (MIT); the sweep for files outside the plan from bashebr/ai-native-sdlc (MIT); the independent plan review and the run step from Boris Cherny's public Claude Code threads.


/trekexecute — Execution

Reads a plan from /trekplan and implements it with strict discipline. No guessing, no improvising — follows the plan exactly.

Per step: record the start point → one fresh helper (step-implementer) writes the step's test first, proves it red, locks it, then applies Changes exactly as written → the executor proves it by command: red at the start point, green at the result (red-proof.mjs), Verify (exit code is truth), manifest audit, and the floor guard on the diff (test-integrity.mjs: removed asserts, skipped or deleted tests, muted checks, stubs, loosened thresholds) → one controller reads the diff — never the helper's summary — and gives two verdicts, spec and quality → a script writes the step's done line only when the test command exits 0 (done-line.mjs) → Checkpoint commit. After all steps: independent Phase 7.5 manifest audit from git log + filesystem (ignoring agent bookkeeping); drift triggers Phase 7.6 bounded recovery. A plan with no passing run-the-thing criterion ends not verified end to end, never green.

A run starts only on a plan you approved as it is now: the approval log holds the plan's sha256, so a plan edited after its approval is refused before step 1. At step end the repo's own tools check the step's diff (the step check) and the step's Regression: suite must stay green. After the last step come the architecture rules and the sweep for files the plan does not name, and then the review starts by itself: /simplify → /trekreview → the verdict gate. A BLOCK keeps the merge into main closed.

The step loop

Part What it does Why
Fresh helper per step voyage:step-implementer (opus, effort high, no Agent tool) builds one step and writes a report: ran · saw · did NOT check Each step starts from the repository and the plan, not from a long context
Start point start_sha recorded before the step; every check reads git diff {start_sha} The review package is the diff, not a story
Proof of red the step's test must fail at the start point and pass at the result, and a control run (the start point plus the change) must pass too — run by red-proof.mjs, not claimed A test that passes without the change proves nothing; a start point that fails for an environment reason proves nothing either
Test lock the helper locks its test files after the red proof (test-lock.mjs, when installed; otherwise "not-locked" is reported) The code moves to meet the test, never the reverse
Floor guard test-integrity.mjs reads the diff for weakened tests; exit 2 ("could not run") is never green Cheating the tests is caught by a command
Controller one general helper, two verdicts (spec, quality), re-checks only what a fix round changed An independent judge of the diff
Step check step-check.mjs runs the repo's own formatters, linters and type checker on the step's diff; findings go to the controller, a repo without tools reads "not measured" The stop for P7 is at step end
Regression the step's optional Regression: command (one allowlisted test runner) runs through the criteria runner before the checkpoint; red goes into the fix rounds Verify proves the step; the regression proves nothing else broke
Done line done-line.mjs appends DONE step N only when the test command exits 0 "Done" is an exit code

The helper works in your working tree, not in a worktree of its own: measured 2026-10-06, a worktree-isolated subagent branches from the default branch rather than your HEAD, so it would not see the earlier steps (only the operator setting worktree.baseRef: "head" changes that).

Unattended: what stops a run

A run stops only on a closed list: something that cannot be undone · something security-sensitive · something outside the working copy (merge to main, push, publish) · a plan so broken that everything after it is guesswork. Everything else the executor decides itself and logs in the final report's Decisions taken table, each with what it costs if it is wrong.

The review at the end — a gate (P11)

After the last step, and with nobody typing anything, the executor runs Cherny's order: run the thing (the plan's ## Verification, its end-to-end criterion included) → /simplify (Claude Code's cleanup skill; edits outside the run's files are restored, and a cleanup that breaks the verification is reverted) → /trekreview (Claude Code's /code-review and /security-review, then Voyage's check against the brief) → verdict-gate.mjs.

Verdict gate Merge into main
0 — ALLOW / WARN open: the executor runs the merge, and the guard asks you before it runs
1 — BLOCK closed. The review's BLOCKERs are added to the plan as new numbered steps, you approve the plan again, and the loop runs: build, check, review — at most 3 reviews, then it is yours
2 — could not decide closed: a review that did not run in full is never green

One question per merge. The guard asks before every merge into main and every push, in auto mode too, so the executor no longer asks "ready to merge?" itself (operator decision 2026-10-08). On the wave path the push and the merge of each session go in one call, so you are asked once per session.

Borrowed: the order from Cherny; the gate on a verdict in a file from Kiro; the bounded fix-and-review loop from Spec Kit; nothing dropped silently from Superpowers. Ideas only.

Modes

Mode Usage Behavior
Project /trekexecute --project <dir> Read {dir}/plan.md, write {dir}/progress.json
Plan path /trekexecute plan.md Execute a specific plan file
Resume /trekexecute --project <dir> --resume Resume from last progress checkpoint
Dry run /trekexecute --project <dir> --dry-run Validate plan structure + preview sessions and their starters
Validate /trekexecute --project <dir> --validate Schema-only check — parse steps + manifests, report READY | FAIL, no execution
Single step /trekexecute --project <dir> --step 3 Execute only step 3
Foreground /trekexecute --project <dir> --fg Force sequential, ignore Execution Strategy
Single session /trekexecute --project <dir> --session 2 Execute only session 2 from Execution Strategy
Profile /trekexecute --profile <name> --project <dir> (v4.1.0) Pin model profile for execution. Plan-frontmatter profile: is honored when this flag is omitted. See Profile system.

Multi-session execution through session orders (worktree-isolated)

Voyage never starts a Claude Code session. When a plan has an ## Execution Strategy section (auto-generated by /trekplan for plans with > 5 steps), /trekexecute works one wave at a time:

  1. Pre-flight checks — validates clean working tree, plan file tracked in git, no scope fence overlaps between parallel sessions, no stale worktrees
  2. Creates git worktrees — each session in the wave gets its own isolated worktree and branch (trek/{slug}/session-{N})
  3. Writes a session order per session — the worktree to open, the steps, the done-condition, and a one-line starter (/trekexecute --session N <plan>) — then stops
  4. You open each session yourself in the directory its order names and give it the starter
  5. Run the same /trekexecute command again — it reads every session's progress file, merges the branches back sequentially with --no-ff (the guard asks you once per session: push and merge go in one call), cleans up, and writes the next wave's orders
  6. After the last wave: master verification on the merged result, then the review at the end; worktrees and branches are cleaned up unconditionally (even on failure)
Wave 1 orders: Session 1 (worktree-1) + Session 2 (worktree-2)  -- you run them, in parallel
         ↓ re-run /trekexecute: both complete → sequential merge to main
Wave 2 orders: Session 3 (worktree-3)
         ↓ re-run /trekexecute: complete → merge to main
Cleanup worktrees + Master verification

Each session operates in complete filesystem isolation — no shared git index, no race conditions, no data loss. If a merge produces conflicts, the merge is aborted and conflicting files are reported.

Use --fg to run every step sequentially in the current session instead, even when a plan has an Execution Strategy.

Failure recovery

  • Fix rounds go up, maximum 5 — rounds 1–3: a fresh helper fixes exactly the controller's findings; after three failed fixes the question is the architecture: round 4 sends the step back to planning (/trekplan revises it, then --resume), round 5 to you. Never a fourth guess, never a cheaper model
  • On failure: revert — fix rounds, then undo the step's changes when it goes up
  • On failure: retry — the alternative approach goes to the first fix round; revert when it goes up
  • On failure: skip — non-critical step, continue
  • On failure: escalate — stop at the first failed round, needs human judgment

Security hardening

The executor implements defense-in-depth security across three layers:

  1. Plugin hooks — pre-bash-executor.mjs blocks 13 categories of destructive commands (rm -rf /, chmod 777, pipe-to-shell, eval injection, disk wipe, shutdown, fork bombs, cron persistence, process killing, history destruction) with bash evasion normalization. pre-write-executor.mjs blocks writes (Write, Edit, NotebookEdit; fails closed without a path) to .git/hooks/, .claude/settings.json, shell configs, .ssh/, .aws/, and .env files
  2. Prompt-level denylist — Security rules embedded in the executor command and session spec template that hold even if a hook does not fire
  3. Pre-execution plan scan — Phase 2.4 scans all Verify: and Checkpoint: commands against the denylist before execution begins, catching dangerous commands before they reach the executor

Guards during the build. All are command hooks; none runs a model.

  • Approval guard (P12) — pre-bash-executor.mjs answers ask before a merge into main, a push, a tag or package publish, and destructive git (hard reset, forced clean, force-deleted branch, dropped stash, discarded changes, history rewrite). Claude Code shows the prompt labelled [plugin:voyage], also in auto mode, and the prompt names the way forward. post-approval-log.mjs writes an approved merge or push to main (merge) and a tag or publish (release) to the approval log with a one-hour expiry. It logs exactly what the person was asked, and nothing in a permission mode that shows no prompts, where no one is asked; other pushes and destructive git are asked about but not logged. Claude Code's own notification for a waiting permission prompt is the alert; Voyage adds none. /trekexecute relies on it: where the guard asks, the executor never asks the same thing again. In the permission mode where Claude Code shows no prompts there is no one to ask, so the guard refuses every call it would ask about instead (merge into main, push, tag or publish, destructive git) and says to run it yourself (operator decisions 2026-10-09).
  • Plan gate (P3) — pre-plan-gate.mjs runs Voyage's plan gate on the plan Claude Code's plan mode presents and sends an invalid Voyage plan back to planning; when the gate cannot run, the prompt says "not measured". An approved Voyage plan is logged with the hash of its text. A plan without plan_version passes untouched.
  • Test lock (P9) — while a step's test is locked (lib/util/test-lock.mjs), pre-write-executor.mjs refuses Write, Edit and NotebookEdit on it, and stop-test-lock.mjs refuses "done" in the session that took the lock until the executor unlocks it.
  • Post-edit check (P7) — post-edit-check.mjs runs the target repo's own formatter and linter on each edited file (check-only; a tool is never downloaded) and logs the result. lib/verification/step-check.mjs re-runs them on the diff at step end, adds the type checker, and fails the step on findings. A repo without tools, or a configured tool that is missing or crashes, reads "not measured", never green. The check is on only while Voyage executes a plan in that repo, or when the repo switches it on with .claude/voyage-guards.json = { "post_edit_check": true }.

Precondition. Voyage's guards are deterministic only when no installed mod handles tool.check. Claude Code runs such a mod after the hooks, and its answer can replace theirs: it can approve a call a Voyage guard stopped or asked about (permissions). A hook cannot tell whether such a mod is installed; /plugin lists the mods a session loaded.

Credits. The four approval classes come from Superpowers; a block that names the way forward from agent-skills; guard plus log from ai-native-sdlc; the alert from Cherny's practice. The post-edit tiers and "not measured" come from agent-skills' constraint-driven development, formatting per edit with the rest at step end from Cherny, the per-file / step-end split from Kiro, a check seen to pass and to fail on a planted problem from Pocock, and guard tests in both directions from ai-native-sdlc. The test lock, the plan-mode wrap and the post-edit hook are Claude Code's own documented hook patterns. Superpowers, Pocock, agent-skills and ai-native-sdlc are MIT-licensed; only ideas are borrowed, no code.

For fork-ers handling untrusted task briefs or plans from external sources, set disableSkillShellExecution: true in ~/.claude/settings.json or in the project's .claude/settings.json:

{
  "disableSkillShellExecution": true
}

This prevents Skills from invoking arbitrary shell, which closes a prompt-injection vector that the plugin's own hooks cannot fully mitigate (Skills can fire before pre-bash-executor matches). See SECURITY.md for the full hardening list.

Unattended execution

/trekexecute runs without asking questions:

  • No questions asked — all recovery decisions come from the plan. The exceptions are approvals: the plan's approval again after the review added steps, and the guard's question before a merge or push
  • Progress file — crash recovery via {project_dir}/progress.json (or .trekexecute-progress-{slug}.json for legacy plans)
  • Scope fence enforcement — never touches files outside the session's scope
  • JSON summary — machine-parseable trekexecute_summary block at the end of every run

Session titles for voyage commands (CC v2.1.94+)

A UserPromptSubmit hook (hooks/scripts/session-title.mjs) sets the session title to voyage:<command>:<slug> whenever you invoke one of the four voyage commands. This makes the sessions of a multi-session run and session-picker output trivially identifiable. Slug derivation:

Invocation Session title
/trekplan --project .claude/projects/2026-04-18-jwt-auth voyage:plan:jwt-auth
/trekbrief --quick voyage:brief:ad-hoc
/trekexecute --project .claude/projects/2026-05-10-cleanup --resume voyage:execute:cleanup

The hook is fail-open — any error → title is left untouched.

Per-step timing (CC v2.1.97+)

A PostToolUse hook (hooks/scripts/post-bash-stats.mjs) appends duration_ms from each Bash tool call to ${CLAUDE_PLUGIN_DATA}/trekexecute-stats.jsonl. One line per Bash call; useful for identifying long-running verify or checkpoint commands across executions.


/trekreview — Review

Independent post-hoc review of delivered code against the brief. Reads brief.md from scratch and treats research/plan as supplementary context. The output review.md is a new artifact type (type: trekreview) with its own validator and a contracted Handover 6 (review → plan) so findings can be fed back into /trekplan --brief review.md to produce a remediation plan — closing the iteration loop without ad-hoc conventions.

The review is a gate. In this order: Claude Code's own /code-review and /security-review find correctness and security defects (started through the Skill tool, never with --fix); Voyage's control against the brief runs after them and is the part that stops. The verdict is written in review.md (verdict: ALLOW | WARN | BLOCK, required) and one command decides on it:

node lib/review/verdict-gate.mjs <dir>/review.md
# 0 = ALLOW or WARN · 1 = BLOCK · 2 = could not decide (never green)

A WARN that exists only because a check did not run is a 2, not a 0: a review that was not performed in full stops a merge.

No finding is struck for length: only MINOR/SUGGESTION text is trimmed, and counted; what the coordinator set aside is listed under ## Declined to Judge. An engine that could not run (older Claude Code, no origin remote) keeps the review from coming back ALLOW — and from passing the gate — and the summary says why.

Modes

Mode Command Description
Default /trekreview --project <dir> Claude Code /code-review + /security-review, then brief-conformance + code-correctness reviewers in parallel, coordinator dedup + verdict, write {dir}/review.md, verdict gate
Since ref /trekreview --project <dir> --since <ref> Override "before" SHA for the diff range. Validated via git rev-parse --verify
Quick /trekreview --project <dir> --quick /code-review + code-correctness reviewer only; skip brief-conformance reviewer, /security-review and the coordinator's reasonableness filter — fast correctness-only pass
Validate /trekreview --project <dir> --validate Schema-only check on existing review.md. No LLM calls
Dry run /trekreview --project <dir> --dry-run Print discovered scope + triage map; skip writes
Profile /trekreview --profile <name> --project <dir> (v4.1.0) Pin model profile for the review phase. See Profile system.

What review produces

review.md carries a flat array of finding-IDs in frontmatter (40-char hex from lib/parsers/finding-id.mjs) plus the full finding objects in the body under per-severity headings:

  • ## Findings (BLOCKER) — must-fix before merge
  • ## Findings (MAJOR) — should-fix
  • ## Findings (MINOR) — nice-to-fix
  • ## Findings (SUGGESTION) — opinion-only

Required body sections: ## Executive Summary, ## Coverage, ## Remediation Summary. The Coverage section enumerates which files were deep-reviewed, summary-only, or skipped (with reason) — explicit triage to avoid silent skips. Every BLOCKER is also written as a numbered plan step (### Step R1: … with Files, Source finding, Test first, Verify) under ## Remediation Steps, ready to append to a plan.

Project memory (recurring findings)

A finding class (the same rule) that shows up in two reviews in your repo becomes one proposed line — mistake · fix · how to check — with both findings as evidence. Mechanical classes name a check; judgement classes go to .claude/rules/voyage-review-lessons.md, which Claude Code loads at session start; CLAUDE.md only gets a one-line pointer. You approve every line (Voyage asks). Voyage writes only between its own markers and stops at a size budget — past it, the lessons belong in a skill, and that is your call. The history is the review.md files your repo already has; no new store.

Triage gate (deterministic)

A path-pattern classifier produces {file → deep-review|summary-only|skip} before any LLM runs. Hardcoded skip patterns: *.lock, *.svg, dist/**, build/**, node_modules/**, generated markers. Deep-review patterns: auth/**, crypto/**, **/security/**. Hard refuse-with-suggestion above 100 files / 100K diff tokens.

Feedback loop (Handover 6)

/trekreview --project <dir>
# → review.md (BLOCKER + MAJOR findings)

/trekplan --brief <dir>/review.md
# → plan.md with `source_findings: [<id>, ...]` audit trail
#   (BLOCKER + MAJOR findings become plan goals; MINOR + SUGGESTION skipped)

The plan's optional source_findings: frontmatter list is the audit trail back to consumed findings. See docs/HANDOVER-CONTRACTS.md for the full Handover 6 contract.


/trekcontinue — Resume

Zero-friction multi-session resumption. Type /trekcontinue in a fresh Claude Code session — the command reads the per-project state file (.claude/projects/<project>/.session-state.local.json), prints a 3-line summary, and immediately begins executing the next session.

The state file is the contract — any session-end mechanism may write it (/trekexecute Phase 8 / Phase 2.55 / Phase 4 do so automatically; the /trekendsession helper writes it for informal flows; graceful-handoff may converge on it in a future release). /trekcontinue only reads. See Handover 7 in docs/HANDOVER-CONTRACTS.md for the full schema and producer/consumer contract.

Modes

Mode Command Description
Default /trekcontinue Auto-discover .session-state.local.json under cwd, validate, narrate, and begin executing the next session
Explicit /trekcontinue <project-dir> Use the named project directory; helpful when several active projects coexist under cwd
Help /trekcontinue --help Print usage block and the schema-v1 reference
Profile /trekcontinue --profile <name> [<project-dir>] (v4.1.0) Pin model profile for the resumed session. Plan-frontmatter profile: from the previous session is honored when this flag is omitted. See Profile system.

Schema v1 — .session-state.local.json

Field Type Required Notes
schema_version number yes Must be 1
project string yes Project directory path
next_session_brief_path string yes Validator soft-checks file existence (warning, not error)
next_session_label string yes Human-readable label for the next session (e.g. "Session 2 of 5")
status enum yes in_progress | partial | failed | stopped | completed (completed → no further sessions to resume)
updated_at string yes ISO-8601 timestamp

Forward-compat: unknown top-level keys are ignored (no errors, no warnings) — the same drift-WARN principle as Handover 3, so future producers (e.g. graceful-handoff v2.2) can extend the schema additively.

/trekendsession helper

For informal multi-session flows that don't run through /trekexecute (ad-hoc release runs, manual handovers), use the helper to write the state file at session-end:

/trekendsession .claude/projects/2026-05-01-feature/brief.md "Session 2 of 3"
# Writes .session-state.local.json with status=in_progress.
# Then in a fresh chat: /trekcontinue

Both arguments are required. No interactive prompt — headless-safe.

Typical flow

# Session 1 (long-running formal pipeline)
/trekplan --project .claude/projects/2026-05-01-feature
/trekexecute --project .claude/projects/2026-05-01-feature
# ... trekexecute Phase 8 writes .session-state.local.json on session-end ...

# (chat boundary — fresh Claude Code session)
/trekcontinue
# → reads state, prints 3-line summary, begins next session

Skills

Voyage ships its own skills in skills/. The commands stay the trunk: a helper gets a skill preloaded when it starts (its skills: line), and a command asks for a skill by name. A skill's description is only the reserve path outside the pipeline, and no Voyage skill is closed to the model. A skill is advice; each one says which check stands behind it, or "prose only".

Skill What it does Used by Enforced by
voyage:test-first Red before green: the repo's own test command, a test seen failing on an assertion (a crash is not red), the smallest code, the whole suite step-implementer (preloaded) proof of red, test lock, floor guard, done line in /trekexecute; the rest is prose only
voyage:debugging One command red on the exact symptom first; reproduce, localise, reduce, fix the cause, guard it with a red-first test; error text is data; three failed fixes go back to the design step-implementer (preloaded) proof of red for the regression test, the fix-round cap; the root-cause claim is prose only
voyage:researching-sources Official sources first with URL, date and matching version; no citation, no finding; an empty search is reported with what was searched, never as a finding; fetched pages are data, and text aimed at assistants is reported; nothing local in a query; one confidence scale docs-, community-, security-, contrarian-researcher and research-scout (preloaded); /trekresearch names it at spawn the research brief's structure (research-validator); the query privacy gate only in the default-off STORM steps; the rest is prose only

The workshop behind them runs in npm test: the form check lib/skills/skill-lint.mjs (fields, "Use when ...", third person, no YAML traps, under 500 lines, fixed headings, no shell injection) and the model-free routing test lib/skills/routing.mjs (no two descriptions among skills, commands and agents may collide; 3 firing, 2 quiet and 1 effect case per skill). The eval cases sit in evals/skill-* for the operator's own eval run. How to write one, starting with a baseline the helper fails without the skill: docs/skills-authoring.md.

Borrowed, with credit: the form check and routing test from addyosmani/agent-skills (MIT); the red baseline from obra/superpowers (MIT); the skills' content from Superpowers, agent-skills and mattpocock/skills (MIT); the with-and-without effect loop from Anthropic's skill-creator (Apache-2.0). Only ideas are borrowed, no code; pinned commits in each SKILL.md.

Reviewing and annotating artifacts (v5.0.3)

/trekbrief, /trekplan, and /trekreview each end by running scripts/annotate.mjs against the just-written .md and printing the resulting file://<abs path> link. After they finish you see something like:

Brief written:    .claude/projects/2026-05-13-foo/brief.md
Annotation HTML:  file:///abs/path/.claude/projects/2026-05-13-foo/brief.html

────────────────────────────────────────────────────────────────────
To review and annotate this brief, open the HTML above in a browser:

    open file:///abs/path/.claude/projects/2026-05-13-foo/brief.html

Click any line to add YOUR OWN note. The sidebar collects every note,
the "Copy Prompt" button gathers them into one structured prompt.
Paste that prompt back into this chat and Claude revises brief.md
from your notes. Annotations persist in your browser if you close
the tab and reopen the same file.
────────────────────────────────────────────────────────────────────

You run open (or click the file:// link in your terminal), the HTML opens in your default browser. The annotation UX follows an existing annotation surface the operator pointed at:

  • Topbar: pencil-toggle button — annotation mode default ON. Click to turn off (then you read the article normally, follow links, etc.). A second button opens the sidebar panel.
  • Article body: the artifact rendered as a proper article — headings, paragraphs, lists, tables, code blocks, blockquotes. Hover any element in mode and it highlights. To anchor on a specific phrase, select the text first, then click. Otherwise the whole element becomes the anchor.
  • Form popover appears at the cursor with:
    • Section (auto-detected from the nearest h1/h2 above).
    • Anchored to — the exact text you selected, or the element's first ~200 chars if you didn't select.
    • Three intent buttons: Fiks (something is wrong — fix it), Endre (change the wording / content), Spørsmål (an open question — clarify or answer). Colored: red / orange / blue.
    • Comment textarea (optional but helpful).
    • Cancel / Save. Save stays disabled until you pick an intent. Shortcut: ⌘Enter to save, Esc to cancel.
  • Annotated elements get an amber highlight + a number badge in the margin showing how many annotations target that element.
  • Sidebar panel (Show annotations) — every annotation grouped by section, in document order. Each card shows the intent badge (colored), the anchored snippet (mono-quote), the comment text, and a delete button. Click a card to scroll the article to that element and flash it.
  • Copy Prompt at the foot of the panel — assembles every annotation into one structured markdown prompt and copies it to your clipboard.
  • Clear all wipes every annotation (after confirm).
  • Persistence: every annotation is saved to browser localStorage keyed on the artifact's absolute path (voyage-annotate:v2:<abs path>). Refresh the tab or close the browser and re-open — your work is there.

You select / click, pick intent, write comment, repeat. When you're done, Copy Prompt, paste back into this chat. Claude revises the .md freehand from your notes. The operator drives every annotation. Claude never pre-generates suggestions in this flow.

What v5.0.3 changed from v5.0.2. v5.0.2 was operator-led but the UX was too thin — click a line, type a freeform note, save. The reference the operator pointed at (an existing annotation surface in another project) already had the right pattern: pencil-toggle, selection capture, three intent categories, popover form, structured markdown export. v5.0.3 rebuilds scripts/annotate.mjs against that reference. v5.0.0 / v5.0.1 / v5.0.2 are all superseded; only the v5.0.0 removals (bespoke playground SPA, /trekrevise, Handover 8, supporting lib/ modules, Playwright e2e + devDeps) stay. See CHANGELOG.md § v5.0.0 → § v5.0.3.


The full pipeline

Six commands, one pipeline — each step hands a structured artifact to the next (the seven handover contracts):

flowchart LR
    B["/trekbrief"]
    R["/trekresearch"]
    P["/trekplan"]
    X["/trekexecute"]
    V["/trekreview"]
    C["/trekcontinue"]
    A["architect plugin<br/>(opt-in, not bundled)"]

    B -->|"H1 · brief.md · PUBLIC"| R
    R -->|"H2 · research/NN-*.md"| P
    A -.->|"H3 · architecture/overview.md"| P
    P -->|"H4 · plan.md"| X
    X -.->|"H5 · progress.json (--resume)"| X
    X -->|"H7 · .session-state.local.json"| C
    C -->|"next session"| X
    X -.->|"git diff"| V
    V -->|"H6 · review.md (loop back)"| P

Solid arrows are the forward pipeline; dashed are conditional/internal edges (--resume, the git-diff that feeds review, the opt-in architect input). H1 (brief.md) is the only PUBLIC contract — the single integration point for any upstream brief producer.

Agents per phase

Every command orchestrates its agents inline from the main context (all sub-agents are model: opus-pinned). /trekexecute spawns no swarm: one fresh step-implementer per plan step, in order, and one controller per round.

flowchart TB
    subgraph BR["/trekbrief"]
        BRG["brief-reviewer (gate · ≤3 iter)"]
    end
    subgraph RES["/trekresearch · Phase 4 — parallel"]
        RL["LOCAL: architecture-mapper · dependency-tracer<br/>task-finder · git-historian · convention-scanner*"]
        RE["EXTERNAL: docs-researcher · community-researcher<br/>security-researcher* · contrarian-researcher*"]
    end
    subgraph PL["/trekplan"]
        PLG["Phase 4b · brief-reviewer (gate)"]
        PLS["Phase 5 — parallel (6 + 2*): architecture-mapper · dependency-tracer<br/>risk-assessor · task-finder · test-strategist · git-historian<br/>convention-scanner* · research-scout*"]
        PLC["Phase 9 — parallel · plan-critic · scope-guardian"]
        PLG --> PLS --> PLC
    end
    subgraph EX["/trekexecute · one helper per step"]
        EXI["per step: step-implementer → controller (spec + quality)<br/>+ red proof · floor guard · done line (commands)<br/>+ session orders per wave (worktrees) + Phase 7.5/7.6 audit"]
    end
    subgraph RV["/trekreview"]
        RVR["Phase 5 — parallel · code-correctness-reviewer · brief-conformance-reviewer*"]
        RVJ["Phase 6 · review-coordinator (Judge)"]
        RVR --> RVJ
    end
    BR --> RES --> PL --> EX --> RV

* = conditional: convention-scanner / test-strategist on medium+ codebases (50+ files); research-scout for unknown external tech; security-/contrarian-researcher when a leading recommendation forms (or always at effort=high); brief-conformance-reviewer skipped under --quick.

Which Claude Code primitive each phase uses — and the alternatives considered (Workflow substrate, delegated orchestrator, dormant synthesis-agent) → see docs/architecture.md §Primitives per step.

All artifacts live under .claude/projects/{YYYY-MM-DD}-{slug}/.

An opt-in upstream architect plugin (not bundled) can insert a Claude-Code-specific architecture-matching step between research and plan — /trekplan auto-discovers its architecture/overview.md output as priors when present.

Example workflows

Standard pipeline (manual control):

/trekbrief Add session caching with Redis
# → .claude/projects/2026-04-18-redis-session-caching/brief.md
# Interview identifies 2 research topics.

/trekresearch --project .claude/projects/2026-04-18-redis-session-caching --external "What are Redis session-caching best practices?"
/trekresearch --project .claude/projects/2026-04-18-redis-session-caching --local "How is caching currently handled in the codebase?"
# → .claude/projects/2026-04-18-redis-session-caching/research/01-*.md, 02-*.md

/trekplan --project .claude/projects/2026-04-18-redis-session-caching
# → .claude/projects/2026-04-18-redis-session-caching/plan.md

/trekexecute --project .claude/projects/2026-04-18-redis-session-caching
# → progress.json + code changes

Auto-mode (Claude manages the pipeline):

/trekbrief Add session caching with Redis
# Interview identifies topics. Choose "Auto (managed by Claude Code)" when asked.
# Claude runs research in parallel, then planning in foreground.
# Returns when plan.md is ready.

/trekexecute --project .claude/projects/2026-04-18-redis-session-caching

Standalone research (no planning):

/trekresearch What are the security implications of using JWT for session management?
# Read the brief, share with team, use for decision-making.

Quick plan for small tasks:

/trekbrief --quick Fix the login redirect bug
/trekplan --project .claude/projects/2026-04-18-login-redirect-fix --quick
/trekexecute --project .claude/projects/2026-04-18-login-redirect-fix

Dry run + validate before executing:

/trekexecute --project <dir> --validate   # schema check, no execution
/trekexecute --project <dir> --dry-run    # preview sessions and starters
/trekexecute --project <dir>              # execute

Review feedback loop (Handover 6):

/trekreview --project <dir>
# → review.md with severity-tagged findings + verdict (BLOCK / WARN / ALLOW)

# If verdict is BLOCK or WARN, feed findings back into a remediation plan:
/trekplan --brief <dir>/review.md
# → plan.md with source_findings: [<id>, ...] audit trail

/trekexecute --project <dir>              # execute the remediation plan

/trekreview --project <dir>               # re-review (overwrites review.md)

Upgrading

Migration notes for breaking changes (v1.x → v2.0, v2.x → v3.0) live in CHANGELOG.md and MIGRATION.md. v3.x non-breaking — minor bumps within v3 add features without changing pipeline contracts.

Releasing and rolling back

A Voyage release follows docs/release-runbook.md: before the release, the release itself, and the rollback. node scripts/release-check.mjs --review <review.md> decides before anything is pushed — the suite is green at HEAD, the review verdict for what is released is not BLOCK and covers it, and every delivery says whether it is a one-way or a two-way door (### Doors in the CHANGELOG section). 0 = ready, 1 = not ready, 2 = could not run (never green). The rollback (revert, then the catalog ref back, then a forward patch) was drilled in a sandbox before it was written down.

Quality infrastructure (since v3.1.0)

The plugin ships with node:test-based unit tests and a lib/ directory of pure-JS validators wired into the commands. Forking the plugin for internal use? Run npm test to confirm the parsers, validators, and doc-consistency invariants still hold:

cd plugins/trekplan
npm test    # runs all tests under tests/**/*.test.mjs

Validators (zero npm deps, hand-rolled YAML subset):

Module Purpose
lib/validators/brief-validator.mjs brief.md frontmatter + state machine (research_topics + status coherence) + body sections
lib/validators/research-validator.mjs research-brief frontmatter (confidence ∈ [0,1], dimensions ≥ 1) + body sections; --dir mode validates a whole research/ folder
lib/validators/plan-validator.mjs wraps plan-schema + manifest-yaml; enforces v1.7 step heading, manifest count match, and forbidden-narrative-form denylist (### Fase/Phase/Stage/Steg N) — replaces the Phase 5.5 grep checks
lib/validators/progress-validator.mjs progress.json shape (schema_version, status enum, current_step in range) + resume-readiness check
lib/validators/architecture-discovery.mjs EXTERNAL CONTRACT — drift-WARN, never drift-FAIL. Discovers architecture/overview.md (owned by an opt-in upstream architect plugin, not bundled) and tolerates non-canonical filenames with warnings.

Each module exposes a CLI: node lib/validators/<name>.mjs --json <path> returns structured {valid, errors, warnings, parsed}. Commands invoke the CLI as their schema check.

A doc-consistency test (tests/lib/doc-consistency.test.mjs) pins prose-vs-source invariants — the agent table in CLAUDE.md must match the agents/*.md file count, every command's frontmatter name: must match its filename, and templates/plan-template.md must declare plan_version: 1.7.

Borrowed pattern from llm-security (commit 97c5c9d); extending the plugin should preserve the invariants the test pins.

Handover contracts

docs/HANDOVER-CONTRACTS.md is the single source of truth for the file formats that pass between the pipeline commands (seven handovers: brief → research, research → plan, architecture → plan, plan → execute, progress.json resume, review → plan, .session-state.local.json). When you fork the plugin or extend a stage, that document tells you what every producer must write and what every consumer is allowed to assume. It also documents the external contract for architecture/overview.md (owned by an opt-in upstream architect plugin, not bundled) — discovery only, drift-warn never drift-fail.

PreCompact resume integrity (CC v2.1.105+)

The pre-compact-flush.mjs hook directly fixes the documented P0 in docs/trekexecute-v2-observations-from-config-audit-v4.md: in skill-driven execution, progress.json could fall behind git reality before context compaction, breaking /trekexecute --resume after long conversations. The hook fires on every PreCompact event, locates any progress.json under .claude/projects/, compares stored current_step against git log --oneline {session_start_sha}..HEAD, and atomically writes a fresh checkpoint (tmp + rename, monotonic only) when git is ahead. Never blocks compaction.

Known limitations

Infrastructure-as-code (IaC) gets reduced value. The exploration agents are designed for application code. Terraform, Helm, Pulumi, CDK projects will get a plan, but agents like architecture-mapper and test-strategist produce less useful output for IaC. Use trekplan for the structural plan, then supplement IaC-specific steps manually.

Annotation HTML requires a desktop browser. scripts/annotate.mjs produces a single self-contained .html file you open with file:// in any modern browser (Chrome / Safari / Firefox / Edge — last two versions). No CDN, no server, no npm runtime deps. State persists in localStorage so closing and re-opening the tab keeps your work, but it's local to one browser on one machine — not synced anywhere. If you want to annotate without a browser, paste the .md into Claude with "comments inline below" and write notes in chat — same end result, just without the visual surface.

Profile system (v4.1.0)

Four built-in model profiles plus operator-defined <custom>.yaml (drop in lib/profiles/). Each profile pins phase_models for the six pipeline phases. The active profile is recorded in plan.md frontmatter as profile: <name> and emitted to JSONL stats for cost-attribution.

Profile Brief Research Plan Execute Review Continue Use case
economy sonnet sonnet sonnet sonnet sonnet sonnet ⚠ Experimental (uncalibrated Jaccard floor) — lowest cost; high-confidence small-scope tasks (opt-in via --profile economy)
balanced sonnet sonnet opus sonnet opus sonnet Mixed — opus where reasoning depth pays off (opt-in via --profile balanced)
premium (default) opus opus opus opus opus opus Maximum quality — Opus on every phase (default since the 2026-05-13 operator decision)
fable fable fable fable fable fable fable Max quality — Fable 5.1 (the most capable model in Claude Code) on every phase (opt-in via --profile fable); reasoning effort inherits from the session

Lookup order:

  1. Explicit --profile <name> flag passed to the command
  2. Plan-file frontmatter profile: (when resuming via /trekexecute --resume or /trekcontinue)
  3. VOYAGE_PROFILE environment variable
  4. Default premium

See docs/profiles.md for the decision tree, custom-profile authoring, and cost estimation disclaimer (the per-profile cost numbers are anslag, not contractual SLAs).

Observability (v4.1.0)

Stop-hook OTel/Prometheus export — opt-in via VOYAGE_EXPORT_MODE:

Mode Output Endpoint env-var
off (default) (no export) —
textfile voyage.prom (Prometheus exposition format) VOYAGE_TEXTFILE_DIR
otlp OTLP/JSON POST VOYAGE_OTEL_ENDPOINT

Default JSONL stats stream (${CLAUDE_PLUGIN_DATA}/trek*-stats.jsonl) is unchanged — OTel is additive. Local Docker Compose stack: examples/observability/. Operator docs: docs/observability.md. Both pin minimum versions per CVE history.

Cost profile

The default premium profile runs Opus on every phase of the pipeline's agent work — the exploration and review swarms (5–10 sub-agents per command; spawn sites inject the composed brief > profile > frontmatter resolution, with agents/*.md model: opus pins as the fallback) and the executor (one per plan session). The command orchestrator itself is not profile-controlled: as of v5.9, command frontmatter omits model:, so the orchestrator follows the session model. For cheaper runs, opt into --profile balanced (Sonnet on brief/research/execute/continue, Opus on plan + review) or --profile economy (Sonnet everywhere); for maximum quality, --profile fable (Fable 5.1 on every phase). Per-command cost is published in ${CLAUDE_PLUGIN_DATA}/trek*-stats.jsonl if you want exact numbers.

On the Anthropic API the opus alias resolves to Opus 5.5 and sonnet to Sonnet 5.5 (both default to reasoning effort medium), and fable to Fable 5.1 (the most capable model in Claude Code; default reasoning effort high — xhigh must be chosen explicitly, see docs/profiles.md). Other providers resolve opus and sonnet to other versions. Note two distinct effort axes that share the word "effort": brief phase_signals.effort (low/standard/high) tunes orchestration shape — how many agents and passes run — while native effort: (nine agents pin high; the rest follow the session) tunes the per-spawn reasoning budget. See docs/profiles.md § Model & effort axes.

For per-profile cost estimates, see docs/profiles.md.

Requirements

  • Claude Code (CLI, desktop app, or web app)
  • Claude subscription with Opus access (Max plan recommended)
  • Optional: Tavily MCP server for enhanced external research

Architecture

Top-level layout:

trekplan/
├── agents/        24 specialized agents (all `model: opus`-pinned; per-phase model set by `--profile`)
│                  └ 21 spawnable (1 dormant: synthesis-agent, Δ≈0) + 3 orchestrator reference docs (not spawned)
├── commands/      6 slash commands (trekbrief, trekresearch, trekplan, trekexecute, trekreview, trekcontinue) + trekendsession helper
├── skills/        3 skills (test-first, debugging: preloaded into the step helper; researching-sources: preloaded into the five web-search agents)
├── templates/     Frontmatter templates for brief, research, plan, session
├── hooks/         12 hooks (pre-bash, pre-write, pre-agent-cap, pre-plan-gate, session-title, post-bash-stats, post-approval-log, post-edit-check, pre-compact-flush, post-compact-flush, otel-export, stop-test-lock)
├── lib/           Zero-dep parsers and validators (CLI shims under lib/validators/)
├── tests/         comprehensive node:test suite — `npm test` is the fork-readiness gate
├── docs/          HANDOVER-CONTRACTS.md + architect-bridge-test.md
└── examples/      01-add-verbose-flag/ — calibrated end-to-end pipeline demo

Pure markdown commands and agents. Hooks and validators are self-contained Node.js with zero npm dependencies. See CONTRIBUTING.md for the full file inventory.

Extending the plugin

Common modifications fork-ers make. None require touching lib/ — all of these are surface-level changes to commands, agents, or settings.

Add a new exploration agent

Exploration agents run in parallel during /trekplan Phase 5. They read the codebase and contribute structured findings to plan synthesis.

  1. Copy agents/architecture-mapper.md as a template:
    cp agents/architecture-mapper.md agents/my-new-agent.md
    
  2. Update the frontmatter name, description, tools, and model. Use sonnet unless the agent needs deep reasoning (most don't).
  3. Add the agent to the swarm in agents/planning-orchestrator.md Phase 5 — register it under the codebase-size bucket where it should fire (always / medium+ / large only).
  4. Update the agent table in CLAUDE.md and README.md to keep the doc-consistency test green:
    npm test -- tests/lib/doc-consistency.test.mjs
    

Switch the planning model

The command orchestrators pin no model: /trekbrief, /trekresearch, /trekplan, and /trekexecute run on whatever model the session runs on. To run them on Sonnet for cost or latency, start the session on Sonnet or switch with /model inside the session.

The exploration and review sub-agents are chosen separately, at the spawn sites: brief phase_signals first, then the profile's phase_models, with the model: opus pins in agents/*.md as the fallback. Run --profile economy to put the sub-agents on Sonnet as well.

Disable external research

/trekresearch --local skips Tavily and Microsoft Learn. To make --local the default, edit the front of commands/trekresearch.md Phase 1 and flip the default branch of the --local argument check. Or just always pass --local and document it in your team's CLAUDE.md.

Plugin data contract

The four commands write to a single project directory (.claude/projects/{date}-{slug}/). The full schema for every artifact is in docs/HANDOVER-CONTRACTS.md. That document is the single source of truth for:

  • File paths each command reads/writes
  • Frontmatter schema for brief.md, research/*.md, plan.md
  • progress.json schema
  • Validator → handover mapping
  • Versioning and breaking-change protocol

If you fork the plugin and change the schema for any artifact, update that doc and the corresponding lib/validators/*.mjs and run npm test — the validators and doc-consistency tests will catch schema drift.

Disable the architect bridge

/trekplan auto-discovers architecture/overview.md if an opt-in upstream architect plugin (not bundled) produced one. To suppress this, leave the architecture/ directory absent from your project directory. Discovery is additive — missing file is fine, no error.

Changelog

Full version history → CHANGELOG.md.

Recent, in one line each:

  • v5.8.0 — offline gold-scored output eval (SKAL-1·4b): lib/review/gold-scorer.mjs grades a committed agent-run fixture against the golden corpus at (file, rule_key) granularity; suite census gains a goldEval category. Offline + deterministic, no live agent spawn.
  • v5.7.1 — leaner always-loaded agent listing (<example> blocks moved into agent bodies, ~3,180 tok/turn, no behavior change).
  • v5.7.0 — opt-in per-session token/cost metering (SKAL-2) + eval foundation (SKAL-1·4a).
  • v5.6.1 — one-line description: for the four reference/dormant agents (~700 tok).
  • v5.5.0 — brief framing enforcement (brief_version 2.2) + a /trekreview reviewer-schema contract. Additive, no breaking changes.

Contributing

See CONTRIBUTING.md.

License

MIT