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>
This commit is contained in:
Kjell Tore Guttormsen 2026-10-08 21:42:21 +02:00
commit 255b6b4bf8
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
15 changed files with 675 additions and 24 deletions

View file

@ -648,7 +648,7 @@ relevant to this task. This is best-effort and environment-dependent: if no memo
is available, pass nothing — the reviewer scores the memory-alignment dimension
`5` (N/A) when no context is supplied.
Launch the `brief-reviewer` agent (foreground, blocking) with the prompt:
Launch the `brief-reviewer` agent with the prompt below, then wait for its result before Step 4d: the Agent tool runs it in the background and tells this session when it is done (voyage-lekerepo trial 2, 2026-10-08), and no gate, revision or guess at the verdict comes before the reviewer's own output.
> **Never pass the Agent tool's `name` parameter — at this or any other spawn
> site in this command.** `name` does not label a subagent, it changes its kind:

View file

@ -414,7 +414,7 @@ Determine codebase scale to calibrate agent turns (not agent count).
Run via Bash:
```
find . -type f \( -name "*.ts" -o -name "*.tsx" -o -name "*.js" -o -name "*.jsx" -o -name "*.py" -o -name "*.go" -o -name "*.rs" -o -name "*.java" -o -name "*.rb" -o -name "*.c" -o -name "*.cpp" -o -name "*.h" -o -name "*.cs" -o -name "*.swift" -o -name "*.kt" -o -name "*.sh" -o -name "*.md" \) -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/vendor/*" -not -path "*/dist/*" -not -path "*/build/*" | wc -l
find . -type f \( -name "*.ts" -o -name "*.tsx" -o -name "*.mts" -o -name "*.cts" -o -name "*.js" -o -name "*.jsx" -o -name "*.mjs" -o -name "*.cjs" -o -name "*.py" -o -name "*.go" -o -name "*.rs" -o -name "*.java" -o -name "*.rb" -o -name "*.c" -o -name "*.cpp" -o -name "*.h" -o -name "*.cs" -o -name "*.swift" -o -name "*.kt" -o -name "*.sh" -o -name "*.md" \) -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/vendor/*" -not -path "*/dist/*" -not -path "*/build/*" | wc -l
```
Classify:
@ -523,8 +523,11 @@ Prompt: "Analyze the test infrastructure and design a test strategy for this tas
Discover existing patterns and identify coverage gaps."
**git-historian** — recent changes, code ownership, hot files, active branches.
Prompt: "Analyze git history relevant to this task: {task}. Report recent changes,
ownership, hot files, and active branches that may affect planning."
Prompt: "Analyze git history relevant to this task: {task}. Brief file:
{brief_path} — read its Constraints and Non-Goals for files it keeps unchanged,
and never recommend changing one. Report recent changes, ownership, hot files,
and active branches that may affect planning. Name the remote as `git remote -v`
shows it."
### Launch for medium+ codebases (50+ files):
@ -628,6 +631,7 @@ Do NOT write this synthesis to disk. It is internal working context only.
> - Verifies: valid token attaches user; invalid token returns 401; missing header returns 401
> - Pattern: `src/middleware/cors.test.ts` (follow this style)
> - **Verify:** `npm test -- jwt.test.ts` → expected: `3 passing`
> - **Regression:** `npm test` → expected: exit 0
> - **On failure:** revert — `git checkout -- src/middleware/jwt.ts src/middleware/jwt.test.ts`
> - **Checkpoint:** `git add src/middleware/jwt.ts src/middleware/jwt.test.ts && git commit -m "feat(auth): add JWT verification middleware"`
> - **Manifest:**
@ -650,7 +654,7 @@ Do NOT write this synthesis to disk. It is internal working context only.
> **plan_version 1.8 additions** (the validator enforces them; 1.7 plans stay
> valid): `Test first:` with `File:` and `Verifies:` on EVERY step; exactly the
> optional fields `Interface in:`, `Interface out:`, `Review focus:` (never
> empty when present); at least one step with `End-to-end:` and a backticked
> empty when present), plus `Regression:` below; at least one step with `End-to-end:` and a backticked
> command — the "run the thing" step; the header line carries
> `` `plan_version: 1.8` · `ceremony: <class>` ``; an architectural plan carries
> `## Design` (see "Design part" below); and every check the run executes can
@ -661,6 +665,19 @@ Do NOT write this synthesis to disk. It is internal working context only.
> `PLAN_STEP_VERIFY_NOT_RUNNABLE`, `PLAN_END_TO_END_NOT_RUNNABLE`,
> `PLAN_END_TO_END_NOT_VERIFIED`).
>
> **Two step rules at every plan_version** (no version bump; a plan without
> the field is unchanged): the optional `Regression:` field (K10) holds ONE
> backticked command the criteria runner allows, with no pipe and no `&&` —
> usually `npm test`, the suite the step must not break. `Verify:` stays the
> step's own test, the one that is red first; `Regression:` is what the
> executor runs green before the checkpoint, so a step whose red test is a
> script can still keep the frozen suite green. Write it on a step that can
> break existing tests; leave it out otherwise. A `Regression:` that can never
> run is `PLAN_STEP_REGRESSION_NOT_RUNNABLE`. And `On failure:` (K11) opens with
> one of `revert`, `retry`, `skip`, `escalate` — the words `/trekexecute`
> reads — then the specifics; any other opening is the warning
> `PLAN_STEP_ON_FAILURE_UNKNOWN`.
>
> **Validator self-check (mandatory after writing `plan.md`):** run
> `node ${CLAUDE_PLUGIN_ROOT}/lib/validators/plan-validator.mjs --strict --json {plan_path}`
> and re-revise the plan if it fails. The validator is the source of truth for
@ -703,7 +720,10 @@ Write the plan following the template structure. The plan MUST include:
- **Review focus:** — inputs the brief implies but no test exercises yet,
each pinned to a test; and any Global Constraint the step could break,
quoted verbatim.
- **On failure:** — recovery action (revert/retry/skip/escalate)
- **Regression:** (optional, K10) — the one suite command run green before
the checkpoint, on a step that can break existing tests
- **On failure:** — opens with the recovery action (`revert`, `retry`,
`skip` or `escalate`, K11), then the specifics
- **Checkpoint:** — `git add` of the step's Files and test files, then the git commit, after success
Steps are vertical slices: each cuts a narrow but complete path through the
@ -897,7 +917,8 @@ loudly instead of collapsing into a silently-empty merge (the historical Phase-9
defect, where the read-only reviewers never wrote the files and the dedup ran on
nothing). The merged array attributes each finding to `[plan-critic, scope-guardian]`
when both reviewers raised the same issue (exact match on `file:line:rule_key`,
or Jaccard ≥ 0.7 on text tokens), and keeps the more severe of the two
Jaccard ≥ 0.7 on text tokens, or — same file and same line — most of the
shorter text's content words in the longer one), and keeps the more severe of the two
severities. Revise the plan once for the merged set, not twice for the
duplicates. Source: research/05 R1 + R2.
@ -909,7 +930,11 @@ duplicates. Source: research/05 R1 + R2.
re-reviewed.
- **PASS** (minors only, or clean): fill in the quality header and
`## Plan Quality Score` from plan-critic's score. These and `## Revisions`
are the review log and do not stale the verdict. Go to Phase 10.
are the review log and do not stale the verdict. Do not edit a step for the
open minors now — that stales the verdict the round just earned. Go to
Phase 10, which lists the minors for the operator to pick from (operator
decision 2026-10-08: a real weakness among the minors after the last round
used to be carried with no way to a fix).
- **REVISE after the last round**: the gate reports
`PLAN_GATE_OPEN_MAJOR_FINAL`. Stop and ask the operator with
AskUserQuestion — each open major in plain words, recommendation first
@ -984,9 +1009,11 @@ Present a summary to the user:
**Plan critic:** {Summary — blockers/majors/minors found, how addressed}
**Scope guardian:** {Summary — creep/gaps found, how addressed}
**Open majors:** {list with "accepted by the operator" for each, or "none"}
**Open minors:** {numbered from the last recorded verdict — "1. {plain words} ({file}:{line})" — or "none"}
**Plan gate (K3):** {PASS | STOP — the reasons}
You can:
- Say which open minors to fix ("fix 1 and 3")
- Ask questions or request changes to refine the plan
- Say **"execute"** to start implementing ← only when the gate exited 0
- Say **"save"** to keep the plan for later
@ -1006,9 +1033,19 @@ If the user asks questions or requests changes:
- Update the plan file in-place
- Show what changed
- A change outside the review log makes the verdict stale: run one Phase 9
round on the changed plan (it counts toward the 3), then re-run the gate
round on the changed plan (it counts toward the 3), then re-run the gate.
When the 3 rounds are spent, record that round with `--extra-round`: the
operator's request for the change is their yes, for this one round.
- Re-present the summary
**Picking open minors.** The summary lists the open minors numbered. Nothing
is fixed unless the operator picks: minors they do not name are carried, as
before. When they pick some ("fix 1 and 3"), revise the plan for exactly those,
add rows to `## Revisions`, and run one Phase 9 round on the revised plan —
with `--extra-round` when the 3 rounds are spent; the operator's pick is their
yes for that one round. The new round's verdict decides as in Phase 9 (a new
major after the last round goes to the operator again).
### In plan mode
When this session is in Claude Code's plan mode, the plan sits in Claude
@ -1280,7 +1317,8 @@ Standard and low effort: do NOT emit the section at all.
- **Bounded critic loop**: at most 3 critic rounds (Phase 9). After the third
with a BLOCKER open, stop and ask the operator; never continue silently, and
never write or edit the `## Critic Verdict` block by hand — only
`plan-gate.mjs --record` writes it.
`plan-gate.mjs --record` writes it. Open minors are listed numbered in the
Phase 10 summary; only the ones the operator picks are fixed, with one round.
- **Plan stands alone**: The plan file must be understandable without access
to the exploration results. Include all necessary context.
- **Honesty**: If exploration reveals the task is trivial (single file, obvious