Commit graph

180 commits

Author SHA1 Message Date
0e612c88ac
fix: round 3 of the release review of 6.3.0
Round 3 (v6.2.0..96cb977, BLOCK: 1 BLOCKER, 8 MAJOR, 2 MINOR), each fixed
behind a test that failed first.

- Every allowlisted runner, not only git, takes plain words and a short list
  of options that only read: an option that writes a file or loads code
  (--test-reporter-destination, --outputFile, --junitxml, --basetemp,
  --import, --config, -p, -o, -exec, a reporter path) is on no list; after
  `npm test --` only paths follow; `make test` takes no VAR=value. A built-in
  node test reporter (tap, spec, dot, junit, lcov) stays allowed.
- /trekexecute: a restore the guard refuses (destructive git, in the mode
  that shows no prompts) or the operator declines is never recorded as
  reverted: simplify = "revert-refused" and the run stops before review; a
  refused step revert is reported with its paths.
- stepTestsOnly: a fixture document under tests/ is a test file, "e.g." is
  not a path, ./ is dropped; the plan-file sweep reads Files: with the same
  reader (fieldPaths); the validator hands its parsed fields over.
- plan-validator --steps-from asks for Verify: on a 1.8 plan too.
- skill frontmatter: a value starting with # is a hazard; a quote after an
  escaped backslash closes the value. Routing reads kind tags with hasOwn.
- release-check reads scope_sha_end as written (an all-digit sha keeps its
  leading zero), and Voyage's own artifacts under .claude/projects/ and
  .claude/voyage/ committed after the review do not count as unreviewed.

Suite 2170 (2168/0/2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 23:25:24 +02:00
ed87cc668d
fix: round 2 of the release review of 6.3.0
Round 2 (v6.2.0..0d044f6, BLOCK: 2 BLOCKER, 11 MAJOR, 1 MINOR), each fixed
behind a test that failed first.

- The git runner checks only words /bin/sh passes through unchanged (no
  quote, backslash, $, glob or brace) and refuses --output and its
  abbreviations: round 1's --output refusal was bypassed by quoting.
- fieldPaths: backticked paths are kept as written, parentheses and all; in
  plain text every path-like word counts, and a parenthesised note does not.
- plan-validator --steps-from reads the plan's ## Verification for an
  appended End-to-end step, and warns instead of failing under --soft.
- regression-check prints progress_status, the value progress.json takes;
  /trekexecute copies it.
- release-check: a plugin in a subdirectory is checked in its own directory,
  the suite is not run when a cheaper check already makes the answer exit 2,
  and a bad argument or a crash is exit 2.
- Skill routing looks a skill up among skills only, and builds the corpus
  vectors once.
- /trekexecute Phase 7.2 says plainly that remediation steps in the review
  template's own form stop with a re-plan; making them runnable is a later
  order (operator 2026-10-10).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 22:43:38 +02:00
bef9c5b3ac
fix: the findings of the release review of 6.3.0
The review of v6.2.0..f669b87 (BLOCK: 1 BLOCKER, 12 MAJOR, 1 MINOR), each
fixed behind a test that failed first, or, for the two missing tests, a test
shown to fail on a stub of the branch it covers.

- Review steps appended by /trekexecute Phase 7.2 are held to the step rules
  on any plan version: plan-validator --steps-from <N> (on a plan below 1.8 a
  template review step validated and was executed).
- The guard refuses where no one can be asked also when its rules will not
  load; the wave merge path names that refusal instead of MERGE_REFUSED.
  Tests for the classifier-error refusal and post-approval-log's own check.
- release-check: the version files may change only in their version after
  the review (JSON compared without it), README diff lines are read inside
  hunks only, an unreadable diff is exit 2, and npm test runs without
  NODE_TEST_CONTEXT.
- What counts as a step of only tests: a note in parentheses is not a path,
  and a data file under specs/ is not a test. End-to-end: rides on the last
  step that builds behaviour (validator hint, trekplan, template).
- A removed line is cited as <rev>:<path>:<line> (findings-schema hint,
  trekreview re-ask).
- skill-lint counts a trailing newline as no line; regression-check takes
  commandEnv from lib/util/command-env.mjs; CLAUDE.md names four mode-read
  exemptions.
- /security-review, older than v6.2.0: the criteria runner refuses git
  --output, which writes a file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 22:12:12 +02:00
73262b6c84
fix(examples): the verbose-content test moves into the step that wires it [skip-docs]
Operator 2026-10-09: step 6 of examples/01-add-verbose-flag only added a
test for behaviour step 5 delivered - the pattern PLAN_STEP_TESTS_ONLY
warns on. It now lands in step 5 (Verify: the new test, red before the
wiring; Regression: the stability harness), the help-text step becomes
step 6, and progress.json follows (6 steps). Steps 1-2 (golden capture and
stability harness, tests of today's behaviour that cannot be red) keep
the warning; a step type for them is a wave 3 question.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:24:03 +02:00
33b58f460a
fix: the fix round before 6.3.0 (order 10)
1. A step of only tests can never be proven red. One reading,
   stepTestsOnly (lib/parsers/plan-schema.mjs, test paths from the new
   lib/util/test-path.mjs): the plan validator warns PLAN_STEP_TESTS_ONLY,
   red-proof --plan/--step adds tests_only to a not-red-at-base, and
   /trekexecute and the step helper send such a step straight up to the
   plan instead of into fix rounds that cannot succeed. /trekplan, the plan
   template and plan-critic (dimension 8, still 12) say the test belongs in
   the step that builds the behaviour.
2. Timing tests under load: the hook helper's kill limit is 30 s and per
   call overridable; SC #14 passes on the fastest of up to three runs
   against the same 800 ms limit (tests/helpers/timing.mjs).
3. The example plan's On failure lines open with a K11 word.
4. /trekreview saves the reviewer's whole answer for the findings check and
   names FINDING_PROSE_LINE_OUT_OF_RANGE (error: re-ask; warning: report).
5. The criteria runner's commands run without NODE_TEST_CONTEXT
   (commandEnv, moved to lib/util/command-env.mjs).
6. The resolver returns effort only when the brief's phase signal sets one;
   the four commands said it always did.

Also: the K2 hook tests used fixed session ids in a per-user temp dir, so
two suites running at once took each other's approval records; the ids are
now unique per run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 22:16:12 +02:00
3c18fdb5f7
merge: main (7a skills workshop, 9 rettepakke, 7b researching-sources, 8 release runbook) into wave2-kobling
Union lines resolved: CLAUDE.md command table keeps main's /trekresearch
and /trekplan rows and this branch's /trekexecute row. README's
architecture block now counts the three skills main ships (it said 2
after 7b added researching-sources).

Contracts run against the real ones on the merged tree: K10/K11 (plan
validator refuses a piped Regression:, warns on an unknown On failure:;
regression-check passes/fails/absent/unrunnable), S2 (skills/test-first
and skills/debugging exist, voyage:<name> form as 7a chose), K7 (real
review_version 1.1 WARN -> 0, a BLOCK copy -> 1, a 1.0 review with no
verdict -> 2). npm test: 2102 / 2100 pass / 0 fail / 2 skipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:25:18 +02:00
7ccdff4629
merge: main (7a skills workshop, 9 rettepakke, 7b researching-sources) into wave2-utgivelse
No conflicts. npm test on the merged tree: 2085 tests, 2083 pass, 0 fail,
2 skipped (main 2055 + this branch's 30). K2 and K7 tests green against
the real modules; the verdict gate and approval log CLIs run end to end.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 19:50:19 +02:00
bb0fb361a5
fix(guard): refuse every asked-about call where no one can be asked
In the permission mode that shows no prompts, pre-bash-executor refused only a
merge into main and a push. A tag, a package publish and destructive git still
went through unattended, which is what the approval guard exists to stop. Now
every call it would ask about, and a command it could not read, is refused
there with the way forward (operator decision 2026-10-09). No new exemption:
the mode is still read in one place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 19:36:21 +02:00
e226c33916
merge: main (7a skills workshop, 9 rettepakke) into wave2-skills-research
Conflict: CLAUDE.md command table. Kept both sides: this branch's
/trekresearch row (the external agents preload researching-sources) and
main's /trekplan row (open minors listed for the operator).

researching-sources adapted to contract S1, now that 7a's form check and
routing test run over it:
- SKILL.md takes the fixed headings (Overview, When to use, Process, Red
  flags, Enforced by, Credits); the five rules and the confidence scale move
  under Process unchanged; Red flags lists the thoughts the baseline runs
  showed; "text only" becomes "prose only" as the form check reads it.
- The description adds "official" documentation and "looking up online what
  an error message means or what causes it": the error-lookup case ranked
  #3 behind debugging. That prompt also said "our tests fail", which is
  debugging's job; it now asks only what the error means and where that is
  documented. No threshold changed.
- Eval cases carry the routing tags (skill-trigger / skill-no-trigger /
  skill-effect, skill=, owner= task-finder and trekplan, from=), 7a's
  Skill grader pattern, arm: both on the no-trigger graders, and the
  judge-model line on the effect case.
- The `## Skills` row in README and CLAUDE.md.
- tests/lib/skills-research-prose-pins.test.mjs drops its two form pins
  (skill-lint is the authority now): 14 -> 12.

npm test on the merged tree: 2055 = 2053 pass / 0 fail / 2 skipped
(main 2043 + 12).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 19:34:38 +02:00
920fbd3c47
feat(trekexecute): couple the executor to the review gate, the plan approval and the step checks
Wave 2, order 6. /trekexecute now:
- refuses a plan whose logged approval does not cover its current sha256
  (K2, approval-log verify --kind plan), before step 1;
- runs the step check (K9) and the step's optional Regression: (K10, new
  lib/verification/regression-check.mjs through the criteria runner) at step
  end, before the checkpoint; exit 2 is "not measured", never green;
- runs the architecture rules (K5) and the plan-file sweep (K6) after the last
  step; a violation or a file outside the plan turns completed into partial;
- reviews by itself in the closing run (Phase 7.2): run the thing, /simplify,
  /trekreview, verdict-gate; a BLOCK adds the review's remediation steps after
  the plan validator accepts them and the operator re-approves the plan, capped
  at TREKEXECUTE_MAX_REVIEW_ROUNDS (3);
- makes the main-merge gate a lock on the verdict: BLOCK or undecided keeps
  the merge closed; when open, the executor merges and the guard's question is
  the one question (operator decision 2026-10-08). The --gates pause before
  the wave merge-back is gone for the same reason.

The guard refuses a merge into main and a push in the permission mode that
shows no prompts, since no one can be asked (operator decision 2026-10-09; two
mode-read exemptions approved by the operator).

progress.json gains optional coupling fields (Handover 5); the validator
rejects the runner's exitCode in plan_verification.failed_criteria (C15).
Pointer lines name the skills test-first and debugging (S2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 19:22:00 +02:00
6c1bf40014
merge: main (7a skills workshop) into wave2-rettepakke
Wave 2 merge order 7a -> 9: brings e589a02 into order 9's branch.
No conflicts. Full suite on the merged tree: 2043 (2041 pass / 0 fail /
2 skipped) = main's 2014 + this branch's 29.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 19:12:45 +02:00
8e3946e687
feat(research): researching-sources skill, preloaded by the five web agents
The source rules the research agents shared by copy now live in one skill,
skills/researching-sources/: official sources first with URL, date and
matching version; no citation, no finding; an empty search is reported with
its denominator and never as a finding; fetched pages are data, and text in
them aimed at AI assistants is ignored and reported; nothing local in an
outbound query. It also holds the one confidence scale.

- docs-, community-, security-, contrarian-researcher and research-scout
  preload it (skills: ["voyage:researching-sources"]); the copied rule text
  leaves them, their own role stays.
- Two agent sentences that contradicted the rules are gone: an empty
  counter-evidence search "increases confidence", and "fall back silently".
- /trekresearch names the skill where it starts the external agents and in
  web follow-ups; Phase 6 rates on the skill's scale word for word; the
  deep-research adapter accepts `contradictory` like the template does.
- Enforced by: research-validator checks structure only, the query privacy
  gate runs only in the default-off STORM steps; the rest is text only.
  A guard on every web search is a separate later order (operator 08.10).
- Red baseline (helpers, offline fixtures): without the skill 3 of 5 runs
  ignored an injected instruction silently and 1 of 2 contrarian runs counted
  an empty search as weak support; with it 0 of 3 and 0 of 2. Path leaks:
  0 of 7 without, 0 of 5 with.
- Eval cases (3 should trigger, 2 should not, 1 effect), written, not run.
- tests/lib/skills-research-prose-pins.test.mjs: 14 pins, 13 red on 4ee711a.

Credits: Addy Osmani, agent-skills @9d0c60d,
skills/source-driven-development/SKILL.md:97-114 (MIT); Jesse Vincent,
obra/superpowers @8ca22db, skills/diagnosing-superpowers/ (MIT). Ideas only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 21:46:49 +02:00
255b6b4bf8
feat(trekplan): Regression and On failure step rules, and trial 2's minor fixes
The minor points (B8-B12, C13, C14, C16, C17) of the second voyage-lekerepo
trial (2026-10-08), each verified against the code and started with a test
that failed first.

- K10: optional step field `Regression:` - one command the criteria runner
  allows, unpiped; plan-validator refuses one that can never run
  (PLAN_STEP_REGRESSION_NOT_RUNNABLE). Any plan_version, no bump.
- K11: `On failure:` opens with revert | retry | skip | escalate, or the
  validator warns (PLAN_STEP_ON_FAILURE_UNKNOWN); onFailureAction in
  plan-schema.
- B8 (operator decision 2026-10-08): minors open after the last critic round
  are listed numbered in the Phase 10 summary; the ones the operator picks are
  fixed and get one more round (--extra-round when the 3 are spent).
- B11: plan-review dedup merges two reviewers' findings on the same file:line
  with the same content (trial pair: Jaccard 0.44, overlap 0.83); the Jaccard
  threshold for every other pair is unchanged.
- B12: /trekbrief Step 4c says the reviewer runs in the background and is
  waited for, not "foreground, blocking".
- C13: the Phase 4 size count includes .mjs, .cjs, .mts, .cts.
- C14: --evidence shows the first output line on PASS rows.
- C16: findings-schema checks path:line citations in finding prose (error) and
  in the prose around the block (warning) against the file.
- C17: git-historian gets the brief, never proposes changing a frozen file,
  and names the remote from `git remote -v`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 21:42:21 +02:00
cc832fd430
feat(skills): skill workshop, test-first and debugging preloaded into the step helper
The workshop (ordre 7a, contracts S1 and S2): a form check
(lib/skills/skill-lint.mjs) that follows Claude Code's own skill fields,
and a model-free routing test (lib/skills/routing.mjs) over every skill,
the 7 commands and the 21 spawnable agents, reading the eval cases
themselves (evals/skill-*, 3 fire / 2 quiet / 1 effect, tagged with the
event they came from). Thresholds pinned, never lowered.

The two skills were written against failures measured first in helpers
without them: red only as an import crash, the whole suite run from a
hand-made file list instead of the repo's own command, and an
unreproduced fix shipped under authority pressure. step-implementer
preloads both through its skills: line; no tool list change.

Credits: addyosmani/agent-skills @9d0c60d, obra/superpowers @8ca22db,
mattpocock/skills @c55ee46 (MIT), Anthropic skill-creator (Apache-2.0).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 21:38:58 +02:00
4807f6c458
feat(release): a drilled release and rollback runbook, and a release check
P13 (wave 2, order 8). docs/release-runbook.md has three parts: before the
release, the release, and the rollback. The rollback was drilled first, in a
sandbox with local bare repos as the remotes: a release 6.2.0 -> 6.2.1, then
path A (git revert, catalog ref back to v6.2.0) and path B (a forward patch
6.2.2 that carries the revert), with the catalog's check-versions green after
each. Nothing reached a real remote; the real catalog was byte-identical
before and after.

Measured: release-plugin.mjs refuses a ref backwards while plugin.json still
says the newer version, and accepts it once the release commit is reverted.

scripts/release-check.mjs decides before a release: clean tree, npm test
green at HEAD, review verdict not BLOCK (K7) and covering HEAD, and a door
type per delivery (### Doors in the CHANGELOG section). 0 ready, 1 not
ready, 2 could not run (never green). A ready run prints the K2 command that
logs the operator's yes.

tests/lib/release-prose-pins.test.mjs holds every command in the rollback
part to the commands the drill ran (tests/fixtures/release-drill/).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 21:32:36 +02:00
b0d96a2d53
fix: close what an independent review found in the trial 2 fixes
- The pre-compact hook read only a checkpoint that started with `git commit`,
  so every plan in the new `git add … && git commit` form rebuilt nothing, and
  an empty match also skipped the session-state refresh. It now finds the
  commit anywhere in the span and always refreshes; first test for the hook.
- A sub-bullet that carries its own command stays a criterion (folding it
  left the command unrun); the shallowest bullet sets the base indent.
- Only a MINOR/SUGGESTION /code-review finding outside the range is released
  from forbidding ALLOW: a MAJOR one may be a break cited at an unchanged
  caller.
- `reuse` is an improvement category; the session-spec template stages too;
  a negated bash 3.2 constraint, an env prefix and `bash -c` are handled.
- Stale comment, Declined-to-Judge wording and rule-key counts brought in line.

Tests fail on 7c11c2a first (9 of 24).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 15:21:56 +02:00
7c11c2aa9f
fix: the second lekerepo trial's faults that made a result wrong or misleading
voyage-lekerepo trial 2 (2026-10-08), report section A; the operator decided
they are fixed before the next release:
- A1: a /code-review finding whose category is simplification, efficiency,
  style or readability enters as CODE_REVIEW_IMPROVEMENT (MINOR), not MAJOR.
- A2: recommended_action is the engine's own fix when transcribed, otherwise
  a test-first step; never the failure scenario dressed as a remedy.
- A3: a /code-review finding outside the exact range it was given is declined
  and listed, but no longer holds ALLOW back; /security-review's still does.
- A4: the manifest must_contain recipe uses grep -E -e ... -- so a pattern
  like --sep is not read as an option.
- A5: indented sub-points belong to their criterion (counted), and a
  criterion with sub-points and no command warns BRIEF_SC_SUBPOINTS.
- A6: a brief requiring bash 3.2 whose criterion runs plain bash warns
  BRIEF_SC_BASH_NOT_PINNED; /trekbrief proposes /bin/bash.
- A7: the plan template's and /trekplan's checkpoints stage the step's files.

Tests fail on 5f9faee first (tests/lib/trial2-fixes.test.mjs, 11 of 14).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 15:12:07 +02:00
8094b00861
fix: brief template teaches runnable criteria; commands call validators through the plugin root
The skills reading (2026-10-06) found two defects the operator decided to fix
once wave 1 was merged:
- the brief template's Success Criteria examples used a pipe and npx, which
  the criteria runner refuses (and the brief validator now warns on);
- trekcontinue and trekexecute called lib/ scripts relative to the working
  directory, which is the user's repo, not the plugin.

Tests fail on the old text first (tests/lib/reading-defects.test.mjs).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 08:52:52 +02:00
5f9faeed4a
fix: close the six defects an independent review found in the trial fixes
Independent read-only review of c56f852..2d29966 (2026-10-08), each defect
reproduced by the reviewer; each new test fails on that code.

- test-lock green ran ANY allowlisted command: `green --cmd "git status"`
  marked a red step green and the stop guard let it stop. The lock now
  stores the step's test command (`lock --cmd`); `green` runs only that
  one (a different --cmd, or a lock without one, exits 2). trekexecute D1
  calls `green` with no command, which also removes the quoting hazard.
- plan-gate --accept-open worked at round 1 and passed the gate; it now
  refuses while rounds are left.
- findings-schema --repo-root swallowed a following flag, or took a root
  that does not exist, and silently skipped the line check: exit 2.
- brief-review-stamp hashed only the body, so a changed `framing` or
  `research_topics` stayed "current"; it now covers the reviewed
  frontmatter too (only the post-review stamps are left out).
- red-proof red_kind read an assertion message naming SyntaxError as a
  load error; the signatures are now specific.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 07:17:45 +02:00
81dc5af680
fix: the trial's mechanical faults -- approval label, import path, stats, annotate path, red kind
voyage-lekerepo end-to-end trial (2026-10-06), report points 8, 10, 12, 15, 16:

- approval-log: «Approve (Recommended)» / «Godkjenn (anbefalt)» is the
  approval it labels; the suffix never turns a hollow answer into a yes.
- trekexecute Phase 8: the state-file block imports atomic-write through
  ${CLAUDE_PLUGIN_ROOT}; a relative import only ran with cwd = plugin root
  (the test runs the block from another directory).
- trekreview, trekresearch, trekcontinue: stats go through stats-append like
  the other commands, and a failed write is reported, never skipped
  silently (closes the open STATE finding for all three). The schema
  fixture's stale line refs for these and trekplan are re-measured.
- annotate prints an absolute path, so file://{$ANNOT_HTML} is a live link.
- red-proof: `red_kind` = load-error | test-failure on a proven red.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 06:53:15 +02:00
609eb35015
fix(review): the review keeps the findings that are right
voyage-lekerepo end-to-end trial (2026-10-06), report points 1, 5, 11:

- engine-findings: recommended_action is "Fix <file:line> so this no longer
  happens: <failure scenario>", not "Resolve: <title>" (8 of 8 engine
  findings were set aside as actionability:empty); the coordinator never
  sets an engine finding aside for Actionability.
- findings-schema --repo-root: a cited line past the end of an existing
  file is FINDING_LINE_OUT_OF_RANGE, so Phase 5's bounded re-ask fixes it
  before the coordinator sees it. The reviewers' instruction said "the
  actual line number from the diff"; it now says the file's own line,
  never the patch's.
- fill-finding-ids.mjs: the coordinator (no shell) writes @@ID_<n>@@ and
  trekreview Phase 7 computes them over (file, line, rule_key); an
  unresolved placeholder or a wrong 40-hex id fails. The 4-field id with
  `title` the docs named is gone; the code always used three.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 06:48:13 +02:00
ca6ee8779a
merge: wave 1 order 1 (executor) into main
CLAUDE.md command table: each row from its owner (trekplan from order 3,
trekexecute from order 1, trekreview from order 5).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:42:47 +02:00
47864f91b4
merge: wave 1 order 4 (guards) into main
CLAUDE.md: the review paragraph (order 5) and the guards paragraph
(order 4) are both kept (planned union line).

The launch gate went red on the merged tree: post-approval-log reads
the session's permission_mode, and its regression test feeds that value.
Both were untracked when the branch ran its suite, so the gate never saw
them there. Operator decision 2026-10-06: a counted exemption in a new
class (mode-read: 3 + 1 hits), and the binding-rule sentence in CLAUDE.md
names it. An extra hit in either file turns the gate red again (checked).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:41:21 +02:00
21c28df3bc
merge: wave 1 order 2 (intent) into main
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:37:12 +02:00
885d515c3b
merge: wave 1 order 3 (plan and design) into main
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:36:31 +02:00
44dcc779a9
fix(execute): the step loop survives an adversarial review
An independent review of abc3083 found 15 defects, the two worst verified
in scratch repos. Each fix started with a test that failed.

- Proof of red could be "proven" by the environment: a start point
  unpacked with git archive had no node_modules and no .git, so any test
  failed there. The start point is now a git clone --shared checked out at
  start_sha, gitignored top-level entries are linked in, and a control run
  (start point + the change) must pass, or the result is not-run.
- The Test first file was never committed (the template lists it apart
  from Files:) and leaked into the next step's diff. The step's scope is
  now Files: + test files, staged at the checkpoint.
- New files outside Files: were invisible to every check. Every untracked
  file is registered with --intent-to-add; a revert unregisters them.
- The floor guard paired renames (foo.test.js -> .bak read as clean) and
  missed skipIf and node's t.skip/t.todo; prose files no longer count as
  stubs.
- Phase 7.5 audited from the last step's start_sha; it now uses the run's
  session_start_sha.
- The done line is written after the checkpoint and checked with --commit.
- fix_rounds never passes 5; attempts are never reset; re-control keeps
  the spec/quality verdicts and earlier floor-guard rulings; the closed
  stop list maps every existing stop; failed vs stopped made consistent;
  the controller's effort is said, not assumed.

Tests: 1470 (1468 pass, 0 fail, 2 skipped).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:17:39 +02:00
f5ca220bc0
feat(plan): plan 1.8, the plan gate, the design part and the plan-side checks
Wave 1, order 3 (P3 plan mode as the start, P2 design as its own part, P9
plan side). Contracts K3-K6 for the later merges.

- plan_version 1.8 (1.7 plans stay valid): Test first on every step, one
  End-to-end ("run the thing") step, optional Interface in / Interface out /
  Review focus fields, a ceremony class in the header (absent =
  architectural), and for architectural plans a ## Design part: module map
  without cycles, architecture rules that name their enforcer and the step
  that proves them, a requirements check asked as keep / change.
- K3 lib/validators/plan-gate.mjs: the critic verdict is recorded INSIDE the
  plan (Claude Code's plan approval hands a hook only the plan file's text),
  bound to the hash taken before the reviewers read it; 0 go / 1 stop / 2
  could not run; at most 3 critic rounds, then stop and ask.
- K5 lib/verification/arch-rules.mjs: runs the target repo's own
  dependency-cruiser or import-linter (installs nothing; 2 = not measured,
  never green); --prove --rule shows pass -> fail on a planted violation of
  that rule -> pass. Verified against dependency-cruiser 18.5.0 and
  import-linter 2.15; madge 8.0.0 left out (missed a planted .mjs cycle).
- K6 lib/verification/plan-scope-sweep.mjs: changed files no step names.
- /trekplan Phases 8-10: design part, bounded critic loop, the gate before
  "execute", a plan-mode path through ExitPlanMode (not yet run end to end
  inside plan mode). plan-critic 10 -> 12 dimensions; scope-guardian checks
  the ceremony.
- Fixed on the way: plan-validator and plan-review-dedup used the
  file://argv[1] main guard (no-op under a symlink or a space); CRLF plans
  failed every manifest; the dedup dropped finding severity.

Borrowed, credited in place: obra/superpowers, Kiro (docs), addyosmani/
agent-skills, mattpocock/skills, GitHub Spec Kit, bashebr/ai-native-sdlc,
Boris Cherny's public threads.

Suite 1497 (1495 / 0 / 2), 86 new tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:10:57 +02:00
2ee8137e7c
feat(hooks): wave-1 guards -- approval ask, plan gate, test lock, post-edit check
Wave-1 order 4 (P7, P12, the P9 test lock, the P3 plan-approval guard).
All command hooks; none runs a model.

- P12: pre-bash-executor answers permissionDecision "ask" before merge
  into main, push, tag/publish and destructive git (holds in auto mode).
  post-approval-log writes exactly what the person was asked to the K2
  approval log: merge/push to main as `merge`, tag/publish as `release`,
  with a one-hour expiry; nothing when no person was asked.
- P3: pre-plan-gate runs the K3 plan gate on a Voyage plan leaving plan
  mode and sends a refused plan back; "not measured" asks, never passes.
- P9: lib/util/test-lock.mjs (K8). pre-write-executor refuses edits to
  locked test files; stop-test-lock refuses "done" for the locking
  session (stop_hook_active guarded).
- P7: post-edit-check runs the target repo's own formatter/linter per
  edit, only during a Voyage plan run or after opt-in
  (.claude/voyage-guards.json); lib/verification/step-check.mjs (K9) fails
  the step on findings; no tool reads "not measured", never green.
- STORM cap matcher also names `Agent` (the tool's name since 2.1.63).
- Mod precondition stated in README, SECURITY.md and every PreToolUse stop
  guard: Voyage's guards are deterministic only when no installed mod
  handles `tool.check`.

K2, K3 and K5 are stubbed in tests until orders 2 and 3 are merged.
Two independent review rounds; every finding has a regression test.
Suite 1600 (1598 pass / 0 fail / 2 skipped).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:09:32 +02:00
22e792ce19
fix(review): a review with a control that did not run stops a merge
Operator decision 2026-10-06. Before, a WARN that existed only because a
reviewer or engine never reported (e.g. /security-review without an origin
remote) mapped to verdict-gate exit 0, so a review nobody performed in full
was green. Now `missing-reviewer:` / `unattributable-payload` in the JSON
block's allow_blocked_by is exit 2 (could not decide, never green); a WARN
for a MAJOR or a set-aside finding still passes with its reasons. A 1.1
review must carry allow_blocked_by.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:06:29 +02:00
40f6ae1177
fix(review): close the gate's fail-open paths an independent review found
An adversarial read of d88245c reproduced 15 problems; all fixed here, each
with a test that fails on the old code.

- verdict-gate: a greener verdict must be backed by the LAST fence being a
  `json` block of the right shape, with no BLOCKER in the JSON (any case),
  in `## Findings (BLOCKER)`, or a differing finding-id list; two verdict
  lines and more than one file argument are exit 2. ({}, null, lowercase
  "blocker", a trailing ```jsonc and a later json fence all gave exit 0.)
- engine-findings: a transcribed "narrower" key can no longer lower an
  engine tier; absolute paths under --repo-root match the scope; "12" lines
  parse; an empty scope is an error; out-of-scope engine findings are
  unverified (`engine:out-of-scope`) and forbid ALLOW.
- recurrence: the catch-all engine keys and keys normalised from unknown
  ones are never proposed; the same unfixed finding in two iterations is not
  a recurrence; proposals are validated before they are offered; \r/U+2028
  and damaged markers are refused; writes go through a symlinked CLAUDE.md.
  Prose points --repo at the session directory, not the git toplevel.
- Workflow substrate: engines are counted from what arrived, and the
  verdict's floor is recomputed from the coordinator's findings; now tested
  by running the script with stubbed Workflow globals. Two literal NUL bytes
  written as \u0000 (git saw the file as binary).
- Trimming keeps Pass 1's "Also flagged by" provenance; `## Declined to
  Judge` and remediation steps are required from review_version 1.1 only
  (N-1); the zero-diff review now carries the JSON block the gate needs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:03:16 +02:00
382d5ccba2
test(verification): the bare 02243c6 start point needs only the red run
The no-shim variant only shows the load error at the start point; its result run repeated the shimmed one. --red-only skips it: the test goes from 29 s to 14 s run alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:02:22 +02:00
abc3083c1e
feat(execute): one fresh helper per step, a controller on the diff, proof by command
/trekexecute no longer builds steps itself. Each plan step is built by one
fresh helper (new agent step-implementer: opus, effort high, no Agent tool)
and judged by one controller (a general helper on opus) that reads the
diff from a recorded start_sha and gives two verdicts, spec and quality.
Fix rounds go up, maximum 5: three fixes by a fresh helper, then back to
the plan, then to the operator. No cheaper-model ladder.

Proof is a command, never the model's word:
- lib/verification/red-proof.mjs: the step's test must fail at the start
  point and pass at the result (exit 0/1/2; 2 is never green). Reproduces
  the 02243c6 red-first measurement (6 of 55) through the shim fixture.
- lib/verification/test-integrity.mjs: the floor guard on the diff
  (removed asserts, skipped/deleted tests, muted checks, stubs, loosened
  thresholds). Over the last 150 commits: 149 clean, 1 real finding.
- lib/verification/done-line.mjs: DONE step N only when the test command
  exits 0.

Test first is required from plan_version 1.8. The test lock (K8) is used
through its CLI and reported as not-locked while it is missing. A run
stops only on a closed list of four classes; every other call goes into a
decision log with its cost if wrong. Without a passing run-the-thing
criterion the result is not verified end to end, never green.

Handover 5 gains optional per-step start_sha, report_path, red_proof,
test_lock, fix_rounds (0-5) and run-level decisions and end_to_end; old
progress files still validate and resume.

No isolation on the helper: measured, a worktree-isolated subagent
branches from the default branch (02f320f), not the executor's HEAD
(2c89a6b), so it would miss the earlier steps.

Borrowings credited in commands/trekexecute.md ## Credits (Superpowers,
ai-native-sdlc, Kiro, GitHub Spec Kit, agent-skills, Cherny).

Tests: 1411 -> 1457 (1455 pass, 0 fail, 2 skipped).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 19:58:18 +02:00
d88245c06e
feat(review): the review is a gate - verdict in the file, CC engine, project memory
Ordre 5 (wave 1, P11 + P5), review_version 1.1.

- K7: `verdict: ALLOW | WARN | BLOCK` is required in review.md (strict
  error, soft warning for 1.0 reviews). New CLI lib/review/verdict-gate.mjs:
  0 = ALLOW/WARN, 1 = BLOCK, 2 = could not decide (never green); a verdict
  greener than the file's own BLOCKERs or JSON block is exit 2. Realpath
  main guard (the old file:// guard exits 0 under a symlink - measured).
- No finding is struck for length: succinctness trims only MINOR/SUGGESTION
  text (catalogue tier), keeps BLOCKER/MAJOR whole, counts trims; the
  coordinator lists what it declined to judge.
- Claude Code's /code-review and /security-review run as the engine via the
  Skill tool (never --fix/--comment/--post/ultra); lib/review/engine-findings.mjs
  turns their findings into a reviewer payload; two catalogue keys
  (CODE_REVIEW_DEFECT, SECURITY_REVIEW_VULNERABILITY), catalogue 12 -> 14.
  An engine that did not run forbids ALLOW.
- Every BLOCKER is written as a numbered `### Step R<n>` with its source
  finding (strict error REVIEW_MISSING_REMEDIATION_STEP).
- P5: lib/review/recurrence.mjs - a finding class in two review.md files
  (current + git history, no new store) becomes one proposal, routed by the
  catalogue's memory_route; written only between Voyage markers in
  .claude/rules/voyage-review-lessons.md under a size budget, CLAUDE.md gets
  a pointer only; the operator approves every line (Phase 8.7).
- Workflow substrate: catalogue enum in step; a missing reviewer or engine
  forbids ALLOW there too (it returned ALLOW on zero findings before).
- Fixtures review-run-A/B said WARN over a BLOCKER; now BLOCK.

Borrowed and credited in code: Superpowers (declined-to-judge), ai-native-sdlc
(cap only nits; mistake/fix/check), Spec Kit (managed block; converge steps),
Pocock (retro routing), Kiro (verdict file + gate; evidence per lesson),
Cherny (engine -> brief control order; review -> memory; budget).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 19:45:52 +02:00
5244d2e8e8
feat(brief): ceremony by size, one question round, logged and committed approvals
P1 (order 2, wave 1). /trekbrief puts the task in a size class
(ceremony: small|bounded|architectural, K1; heaviest in doubt, said
aloud, overridable, only moved up) that sets the question budget and the
review cap, and asks one round of questions: facts looked up, never
asked; recommendation first; ranked by impact x uncertainty with a
visible Deferred list; stop when the next three answers can be predicted.
"høres bra ut", "gjør som du vil" and an empty answer are not approval.

K2: lib/util/approval-log.mjs, an append-only hash-chained log in the
target repo (.claude/voyage/approvals.jsonl) bound to the approved
content's sha256; append/verify (0/1/2), answer, digest. Committed by
lib/util/artifact-commit.mjs: the log always, the brief and plan only
with artifact_store: git (operator decision 2026-10-06). /trekplan
Phase 1 halts on a broken, diverged, missing or mismatched log entry;
Phase 11 logs and commits an explicit plan approval before any handoff.

Both new brief fields are optional: no brief_version bump. The
main-module guard in intent-approval.mjs and brief-validator.mjs now
compares real paths. Borrowings credited in the prose and module headers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 19:44:42 +02:00
cb68c4f125
fix(execute): the Phase 8 payload goes on stdin; /trekreview findings closed
/trekreview of 5680591..84a0621 (verdict WARN: 0 BLOCKER, 3 MAJOR, 1 MINOR,
1 MAJOR suppressed as unverified for length only). All closed red -> green:

- Suppressed MAJOR 1d0171a7 (verified live): Phase 8 spliced {plan-path}
  into a single-quoted --payload. A lone quote broke the shell parse (event
  lost, no written:false to report); a quoted pair ran a command
  substitution and still reported written:true. event-emit now reads
  `--payload -` from stdin and the three Phase 8 blocks pass the payload
  through a quoted heredoc. Checked under bash and zsh.
- 570ba19b: the SC5 set-step extractor read line by line and never saw the
  wrapped Step 0 sentinel (`blocked`); it now matches across the break and
  the test asserts `blocked` is read.
- c69a865a: the Phase 9 line_ref in jsonl-schemas.md was 9 lines off. Both
  trekexecute rows are now pinned to the exact span by a test.
- 0004fa23 (MINOR): the gates_mode_flag_override block says what to do on
  written:false (print the reason, continue).
- emit() docstring no longer says failures are swallowed silently.
- 7ffaede5: chosen to KEEP the prose-only legacy `passed` tolerance, because
  a public-plugin run started under the 6.1.0 prose would otherwise re-run
  every finished step on resume; recorded as an accepted deviation in the
  (local-only) brief. No code change.

Suite 1400 (1398/0/2), was 1393.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 18:16:46 +02:00
84a0621fcc
fix(agents): no agent is pinned below the high floor
Operator rule (2026-10-05): standard is Opus 5.5 at reasoning effort High. Four retrieval agents (architecture-mapper, dependency-tracer, git-historian, task-finder) pinned effort: medium in frontmatter, which overrides the session level, so every /trekplan exploration ran part of its swarm below the floor. They came from fdd3ad8 on the premise that unpinned agents inherit high; e4e37f9 corrected that (unpinned inherits the session; Opus 5.5 defaults to medium), so the reason for medium was already gone. All four now pin high; the other agents keep following the session (operator's choice). docs/profiles.md (one bullet for the eight pinned agents), CLAUDE.md and README.md updated; the model-default sentence stays. Dated decision records and CHANGELOG untouched.

Red: 4 of 5 new tests fail on the pre-fix files - effort floor over all agents (offenders: the four), the four pin exactly high, no live doc says retrieval runs at medium (hits docs/profiles.md:76, CLAUDE.md:85, README.md:806), profiles.md names the four as high. Known-positive control green on arrival.
Verify 153/153 (agent-frontmatter, doc-consistency). SC9 probe: npm test green under a scratch HOME with CLAUDE_PLUGIN_DATA empty, nothing under its plugin data dir. Suite 1393 (1391/0/2).

The change is repo-true, not installed-true, until a release.

Voyage order 20261005T104513Z-1250514346, plan step 5/5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 17:40:53 +02:00
d5d121150e
fix(execute): every /trekexecute telemetry write lands through a writer
Phase 9 said 'append to ${CLAUDE_PLUGIN_DATA}/trekexecute-stats.jsonl; if it is not set, skip silently' - the Bash tool env never carries it. It now runs stats-append.mjs trekexecute with the record on stdin, the /trekbrief Phase 7 shape, and reports a written:false. The gates_mode_flag_override record was prose with no writer; it now has an event-emit block (fixed literal payload: --gates is a boolean flag) and a documented shape {ts, event, known_event, payload:{flag, signal_effort}}. Phase 8's three event blocks spliced ${PLAN_PATH} (set in an earlier Bash call that does not survive) and ${WAVE_COUNT} (never assigned) into a double-quoted payload, so a literal run printed payload-not-json, and the decline reason was operator free text in a shell argument. Payloads are now single-quoted with {plan-path} / {wave-count} placeholders and the literal label hold-for-review; each call runs on its own and a written:false is printed and passed. docs/architecture.md and the jsonl-schemas rows (writer, measured line_refs) follow.

Red: 7 of 7 new tests fail on the pre-fix text (Phase 9 writer + no 'skip silently', Phase 9 record lands, no bare ${CLAUDE_PLUGIN_DATA}/...jsonl target, no shell expansion in --payload, the three Phase 8 blocks land known events when run as written in a fresh shell, the written:false sentence, the override writer and shape).
Verify 198/198 (stats-landing, main-merge-gate, gates-flag-coverage, profile-stats-fields, plugin-root-resolution, doc-consistency, no-claude-code-launch). Suite 1383 (1381/0/2).

Voyage order 20261005T104513Z-1250514346, plan step 3/5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 17:37:19 +02:00
27d586841a
fix(stats): event-emit lands without the env var and reports every failure
event-emit returned {written:false, reason:'CLAUDE_PLUGIN_DATA unset'} whenever the harness did not export the variable - the normal case for the Bash tool - so /trekexecute's Phase 8 events never landed. It now resolves the directory through stats-append's resolveStatsDir (one resolver; opts.path still wins, so intent-approval is unchanged). The CLI uses the realpath isMain() guard (the file:// guard was a silent no-op under a symlink or a path with a space) and exits 1 on every written:false - usage error, payload-not-json, failed write - instead of always 0. KNOWN_EVENTS gains main-merge-approved, main-merge-declined and gates_mode_flag_override, which /trekexecute emits by design. Header, intent-approval docstring (comment only), docs/operations.md and the README autonomy sentence (wrong state names, 'records each transition') updated.

Red: 10 of 20 tests fail on the pre-fix code - 7 new (CLI lands with CLAUDE_PLUGIN_DATA empty / absent, unwritable target exit 1, usage error exit 1, symlink, space path, known events) and 3 inverted contracts. Regression guards (green on arrival): never throws when unwritable; no second copy of the fallback directory name.

Inverted (the contract this changes, not deleted): emit with no CLAUDE_PLUGIN_DATA (silent skip) -> lands under a pinned HOME; never throws when unwritable -> a genuinely unwritable target (env {} now resolves to the real home); resolveStatsPath({}) === null -> the fallback path; malformed --payload exit 0 -> exit 1.

Readers checked: otel-export keys on 'event', yardstick counts only user_input, cache-analyzer and research-loop-cap name event-emit only in comments. Verify 268/268 (stats-event-emit, intent-approval, doc-consistency, otel-export-validators, yardstick). Suite 1376 (1374/0/2); non-hook lines in the real trekexecute-stats.jsonl 60 before and after.

Voyage order 20261005T104513Z-1250514346, plan step 2/5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 17:35:11 +02:00
5329355690
test(stats): a project_dir inside cwd finds the repo that holds it
/trekreview of e7ac34b..3f073b7 (WARN, 1 MAJOR, finding
986c939f93808a274b5e4ecd2c5318fd422a3be4): baseDir's accepting branch
was never exercised, though every production /trekbrief record carries
project_dir. One unit test (attributeOrder from a non-git parent with
projectDir inside it) and one end-to-end landing test (the Phase 7 line
with a record carrying project_dir).

Both pass on HEAD and both fail on the always-cwd mutant (measured,
then reverted). Suite 1364 (1362/0/2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 12:41:44 +02:00
598ef1b694
test(docs): the order fields stand on all five surfaces (red)
order_id / order_claimed_at / order_reason on the five surfaces: (1) record
format = the writer (pinned in stats-landing), (2) Phase 7 prose with "the
writer adds", (3) the field-allowlist header names them as dropped and
TREKBRIEF_ALLOWED leaves them out, (4) the trekbrief-stats fixture row's
`fields` column + EXPORT_DENYLIST, (5) docs/architecture.md Stats. Plus: the
row's line_ref must contain the Phase 7 stats-append line (it said 657-672,
the line is at 958); /trekbrief --approve reaches Phase 7 with mode "approve"
(PM 04.10, point 3) and CLAUDE.md, README.md, docs/command-modes.md say so.

Red: 7 doc pins fail. Green on arrival: the yardstick-header pin (Step 6
already rewrote the header) and the otel DROP guard (the fields were never
allowlisted).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 19:54:17 +02:00
1db116eda5
test(stats): a trekbrief record carries the order Voyage runs, written by the writer (red)
stats-landing gains a baseEnv() (process.env minus CLAUDE_COORD_DIR) at every
spawn - the real voyage mailbox holds a claimed order while the suite runs -
and runLine takes a cwd and extra env. New: Phase 7's own line, run in a temp
git repo against a temp coord dir, must land order_id / order_claimed_at /
order_reason (one claimed -> the id; zero -> keys present, null, none-claimed;
two -> several-claimed:2; model-supplied order_* keys replaced; no coord ->
coord-missing). The CLI must also write when run through a symlink or from a
path with a space.

Red on behaviour: 7 of 8 new tests fail against today's writer (no order keys;
the file:// guard is a silent no-op under a symlink and under a space -
measured in a scratch repro 04.10). Guard green on arrival: a trekplan record
gains no order keys.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 19:50:08 +02:00
e7ac34b93e
test(stats): the recorder finds the one claimed order Voyage runs (red)
20 tests for lib/stats/claimed-order.mjs (new): exactly one claimed order is
an attribution (stem id + the .claim sidecar's claimed-at); zero, several
(an unparseable file still counts), a to: naming another repo, a missing
coord dir or no git repo is null plus a reason - never a guess. Mailboxes
mirror coord-order-claim.sh (basename of the toplevel) plus the worktree's
main repo; _* is reserved; an inherited GIT_DIR and a project_dir outside
cwd cannot steer it.

Red: the module does not exist (20 of 20 fail, each on its own - the module
is loaded per test). Against a null stub in a scratch copy, 18 fail on
behaviour; 2 are guards green on arrival (13 _-prefixed mailbox never read,
14 the recorder only reads).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 19:48:21 +02:00
f555c281ea
test(docs): the alias targets on live surfaces must match the docs today (red)
Verified 2026-10-02 against code.claude.com/docs/en/model-config and
/sub-agents: opus -> Opus 5.5 and sonnet -> Sonnet 5.5 (both default
effort medium), fable -> Fable 5.1 (default high), and a subagent
without effort: inherits the session level. Seven tracked files still
say Opus 4.8 / Sonnet 4.6 / Fable 5. History keeps its names; a
known-positive control proves the query can find them there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:42:13 +02:00
a61cde2b38
test(execute): Check 4 and Step 5 must survive a first run under zsh (red)
The Bash tool runs the user's shell; on macOS that is zsh, whose NOMATCH
option fails an unmatched session-* glob with exit 1. A first run has no
worktrees yet, so Check 4 stops every first multi-session run and every
re-run after a declined main-merge gate. Red under /bin/zsh, green under
/bin/bash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 16:40:05 +02:00
d9e091c143
test(execute): pin the main-merge gate and the wave's branch on the wave path (red)
Round 3 of the review of the session-order flow:

- the orders dir is cleared only under the main-merge gate's confirm
  (wave path, next-wave none, Step 4 passed); Step 6 keeps it, and a
  declined gate keeps the merged-waves record
- the gate text is true on the wave path: the waves are already merged
  on the current branch, nothing is finalized, and re-running the same
  command (not --resume) returns to the gate; the single-session
  --resume statement stays
- the report footer names the multi-session way to continue
- wave.json stores the branch the wave was prepared on, and Step 3's
  status call (executed from the doc in a temp repo) refuses another
  branch, keeping wave.json

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 16:22:08 +02:00
a915b9d4b0
fix(execute): the multi-session path never force-deletes (green)
One invariant closes the data-loss class: Phase 2.55, 2.6 and 7.6 remove
worktrees only with `git worktree remove` without force and branches only
with `git branch -d`. Whatever git refuses (a worktree with changes, an
unmerged or checked-out branch) is kept, reported with what the user can
do, and never retried with force; every unmerged trek/{slug}/* branch
survives every failure path. Step 1 stops on a branch or worktree left
by an earlier attempt instead of deleting it. After a merged wave, a
progress file is dropped from its worktree only when untracked and
byte-identical to its archived copy, so the happy path still cleans up.

B1: Step 3 refuses to merge into a dirty main checkout, and tells a
refused merge (no MERGE_HEAD: stop, keep wave.json) from a real conflict
(abort, Step 5 keeps the branches).
B2: Phase 2.5, Check 4 and Step 0 take the main checkout from the first
`git worktree list` entry and refuse to run from a linked worktree.
B3: wave.json and merged-waves.json carry the plan's sha256 and refuse
another plan or version, naming the run that holds the orders dir and
the clear command; Step 0 stops on that. Step 6 clears the orders dir
when every wave is merged AND Step 4 passed, no longer keyed on the
Phase 8 label the wave path cannot reach.
Also: every session-orders.mjs call runs from the main checkout with a
main-relative plan path; Check 1 no longer counts .claude/trekplan-sessions/
as a dirty tree (it blocked every re-run after a failed wave); a stuck
wave has a documented non-force way out; Hard rule 12 states the
invariant. The test file only narrows one call-site filter that also
matched Step 0's plugin-root existence check.

npm test: 1273 tests, 1271 pass, 0 fail, 2 skipped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 16:18:33 +02:00
b4a0283c94
test(execute): pin a multi-session path that never force-deletes (red)
Round 2 of the review of the session-order flow. One invariant closes the
class: Phase 2.55, 2.6 and 7.6 remove worktrees only without force and
branches only with -d; a refusal keeps the work and is reported.

These tests execute the bash blocks of commands/trekexecute.md in
throwaway repos with linked worktrees:

- Check 4 and Step 5 remove a clean worktree and a merged branch, keep an
  unmerged branch and a worktree with untracked files, and list them
- Step 1 stops on a branch or worktree left by an earlier attempt
- Step 3 stops on a dirty main checkout (B1) and tells a refused merge
  (no MERGE_HEAD) from a real conflict; after a merged wave it records
  the wave and drops only identical, untracked, archived progress copies
- Phase 2.5, Check 4 and Step 0 resolve the main checkout and refuse a
  linked worktree (B2); Step 0 derives a main-relative plan path
- Check 1 does not count .claude/trekplan-sessions/ as a dirty tree
- wave.json and merged-waves.json carry the plan sha256 and refuse
  another plan or version, naming the run and the clear command (B3);
  Step 6, not Phase 8, clears on every wave merged + Step 4 passed

One test is a structural guard over the text (no force flag in those
phases); the executed blocks pin the behavior.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 16:13:42 +02:00
82fc507886
docs(rules): the fixed test set stays as the one operator-run exception
Operator decision 2026-10-02: keep the test set that a person runs
through Anthropic's plugin eval tool. Voyage starts nothing; the gate
counts that entry exactly, and the binding rule and the gate header now
say so instead of claiming historical mentions only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 15:48:36 +02:00
2c0ce8b9ab
test(execute): pin the wave collect side against destroying live or merged work (red)
An independent review of the 6.0 session-order flow found seven defects.
These tests pin the fixed behavior:

- status classifies each session as completed, running (no file, pending,
  in-progress, in_progress, or any unknown status) or ended-bad (failed,
  stopped, partial, blocked, unreadable), keeping the raw status; a failed
  session next to a running one reports running, and Step 3 must branch on
  running before any failure cleanup
- archive copies each progress file into orders/ before worktrees go
- a merged-waves record drives next-wave, survives Step 5, and clear
  resets it (refused while wave.json exists, and for another plan)
- the Phase 2.5 guard is anchored at the git toplevel; Check 4's guard is
  executed from a subdirectory and must refuse while wave.json exists
- Phase 7.6 names no deleted worktree and promises no unwired re-run
- Hard rule 12 carries the awaiting-sessions exception
- progress paths are asserted literally; the old self-referential check
  stayed green under a basename(planPath) mutation, the new one goes red

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 12:06:10 +02:00
93e51615f3
test(commands): every VOYAGE_ROOT block must resolve the installed plugin root (red)
The four blocks in trekexecute (x2), trekresearch and trekreview read
${CLAUDE_PLUGIN_ROOT:-}, which Claude Code never substitutes (it replaces
the literal ${CLAUDE_PLUGIN_ROOT}), and the fallback returns the
version-less cache/<marketplace>/voyage directory, so the guard after it
exits 2 every time. Red on both conditions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 11:57:58 +02:00