fix(plan): a 1.9 Test first names its test only on a line that opens with File:

The step check read File: anywhere on the Test first lines, so a 1.9 plan whose only File: stood mid-line validated while the executor, K6 and the red proof read no test file. From 1.9 checkSteps reads the test the way testFirstFiles does; below 1.9 it reads as before (decision 16). Found by the step 5 controller in /trekexecute --session 2; fixed on the operator's decision.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-10-12 17:44:23 +02:00
commit 3009c5eddb
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
3 changed files with 61 additions and 8 deletions

View file

@ -273,7 +273,7 @@ prose form (relaxed in S26 so the template's prose emission parses).
8. **plan_version 1.9 only** (1.8 and 1.7 plans are read as before, with one warning, `PLAN_STEP_PATH_UNTICKED`, for a path their reader found outside backticks; decision 16, operator 2026-10-11) — the file first on every line:
- the entries of a step's `Files:` field are its first non-empty line and each list-item line (`-`, `*`, `+`, `1.`, `1)`); any other line continues the entry above it;
- each entry opens with its backticked path(s), separated only by commas or whitespace; everything from the first other text on is description and is never read (`` `a.test.mjs` - covers `src/parse.mjs` `` names one file), so every path stands before any annotation (`` `src/a.mjs`, `src/b.mjs` (new) ``, never `` `src/a.mjs` (new), `src/b.mjs` ``);
- each `Test first:` `File:` line is one entry under the same grammar (several test files share one line: `` File: `a.test.mjs`, `b.test.mjs` (new) ``);
- each `Test first:` `File:` line is one entry under the same grammar (several test files share one line: `` File: `a.test.mjs`, `b.test.mjs` (new) ``). A line counts only when `File:` opens it (after a list marker or `**`); a step whose `Test first:` has no such line with a backticked path names no test and is `PLAN_STEP_NO_TEST_FIRST` (`File:` mid-line is description, as the executor reads it);
- an entry that does not open with a backticked span, `none`, and an empty or absent `Files:` are `PLAN_STEP_PATH_NOT_FIRST` (a 1.9 step always names a file); a leading span that is no path (a call, an option, a URL) is `PLAN_STEP_PATH_NOT_A_PATH`. Both are errors under `--strict`, warnings under `--soft`;
- K6 (`lib/verification/plan-scope-sweep.mjs`) follows the grammar from 1.9: it reads a 1.9 plan's `Files:` and `Test first:` `File:` line by it (plan-schema `entryPaths` / `testFirstFiles`), and so does the red proof's `tests_only` reading (`lib/verification/red-proof.mjs`); below 1.9 both keep their earlier readers.
@ -293,7 +293,7 @@ The strongest validation in the entire pipeline. Phase 5.5 (planning-orchestrato
| `PLAN_VERSION_MISMATCH` | `plan_version` other than 1.7 / 1.8 / 1.9 | Warning only; planner should bump |
| `PLAN_NO_VERSION` | No `plan_version` found | Warning only; add the header line |
| `PLAN_NOT_FOUND` / `PLAN_READ_ERROR` | The plan file is missing or unreadable | Check the path |
| `PLAN_STEP_NO_TEST_FIRST` | 1.8: a step lacks `Test first:` with File + Verifies | Add the test the step makes pass |
| `PLAN_STEP_NO_TEST_FIRST` | 1.8: a step lacks `Test first:` with File + Verifies; 1.9: also when no line opens with `File:` and its backticked path | Add the test the step makes pass |
| `PLAN_NO_END_TO_END` | 1.8: no step carries `End-to-end:` with a command | Add the "run the thing" step |
| `PLAN_STEP_FIELD_EMPTY` | 1.8: `Interface in/out:` or `Review focus:` present but empty | Fill or remove it |
| `PLAN_VERIFICATION_NOT_RUNNABLE` | 1.8: a `## Verification` criterion has no command, or one the criteria runner's allowlist never runs | Name a test runner, or wrap the check as `bash tests/<script>.sh` |