# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## Unreleased — plan_version 1.9, the trial-4 findings, session-clean tests A new plan version, 1.9, in which every path in a step's `Files:` and on its `Test first:` `File:` line stands first, in backticks, so the reader no longer guesses paths from prose (decision 16). The same delivery closes the six findings from the test repo's trial 4 and stops `npm test` from pointing a live session's stop guard at a temp-repo lock. Every fix began with a test that failed on the code before it. Suite 2517 (2515 pass, 0 fail, 2 skipped), measured by `npm test` on the third remediation's Step 2 commit (`829da48`), the commit before this section. Nothing here asks anything of users. Older plans warn, they do not fail: a plan below 1.9 is read as in 6.3.1, apart from the fixes under Fixed, and gets one warning per step whose `Files:` names a path that is not backticked. ### Doors - two-way: plan_version 1.9 — a 1.9 plan read by 6.3.1 gets PLAN_VERSION_MISMATCH as a warning and the 6.3.1 reader, so a revert rewrites no plan. - two-way: Files reader (three 6.3.0 answers restored) — a revert brings back 6.3.1's answers; no file format changes. - two-way: the test files on the Test first File line are the backticked paths right after File: (operator decision 20) — a revert reads every path-shaped span again. - two-way: red proof checks --tests against the plan — a revert accepts any list again. - two-way: brief-conflict mark on review findings — an older verdict gate ignores the field. - two-way: review Pass 1 ranks by catalogue tier and a dropped duplicate never lowers its group — a revert restores the asserted-severity ranking. - two-way: the workflow review puts back every engine finding the coordinator did not return (operator decision 23) — opt-in path only; a revert restores the old floor. - two-way: approval commits require a Co-Authored-By trailer — only Voyage's own commands call the CLI, and they pass it. - two-way: explorer prompts, stamp order, test env — prose and test-side only. - two-way: a 1.9 wrapped line keeps its paths only after a comma (operator decision 29), and a File: line with nothing after it takes its first wrapped line — a revert joins every wrapped line again. - two-way: below 1.9 a test file after a note in brackets, and, plus or + is read when it is clearly a test (operator decision 28 and operator decision 31) — a revert reads only the run right after File: again. - two-way: red proof reads the step's test files from the plan, prints them, and refuses a plan it cannot read (operator decision 30) — the older prose that passes --tests still runs against it. - two-way: original_severity names what the kept finding asserted — only tests read the field. - two-way: the workflow review fails closed when its coordinator returns nothing, and names every reviewer that did not run in allow_blocked_by — opt-in path only. - two-way: below 1.8, when the plan names no test file, the helper and the executor give red proof the files the helper wrote (operator decision 41) — a revert leaves such a step unproven and unlocked. ### Added - **plan_version 1.9: the file first on every line.** Each entry of `Files:` and each `Test first:` `File:` line opens with its backticked path or paths; everything from the first other text on is description and is never read. A 1.9 plan that breaks this gets `PLAN_STEP_PATH_NOT_FIRST` or `PLAN_STEP_PATH_NOT_A_PATH` (errors under `--strict`, warnings without). The parser, the validator, the tests-only check, the plan-file sweep (K6) and red proof read a 1.9 plan by this grammar. 1.9 is the current target: Handover 4, the plan template, `/trekplan`, the planning orchestrator and CLAUDE.md say so, and the rules introduced at 1.8 say "1.8 or later". - **A warning for older plans.** Below 1.9, a path in `Files:` that is not backticked gets the warning `PLAN_STEP_PATH_UNTICKED`, under `--strict` too. - **The brief-conflict mark.** A `/code-review` finding at the MAJOR tier whose recommended action goes against a brief Non-Goal or another stated choice drops to MINOR, marked `contradicts_brief` and `brief_lowered_from: MAJOR`; any other engine finding only gets the mark, and a BLOCKER is never lowered. `/trekreview` passes the brief's choices to the coordinator, which writes the mark into `review.md`; the opt-in workflow review applies the same rule and floors an illegal lowering. On an ALLOW or WARN review the verdict gate answers exit 2 for a finding lowered or marked outside that one shape: `brief_lowered_from` on any other finding, a mark on a reviewer finding, a mark or an engine finding below its catalogue tier, or a mark with a missing or unknown rule key. ### Fixed - **The suite no longer hands the session id to the lock CLI.** `npm test` preloads a helper that removes `CLAUDE_CODE_SESSION_ID`, and every test that starts a child process passes an environment without it. A live session's stop guard is no longer pointed at a temp-repo lock. - **The three `Files:` regressions from 6.3.1's Known issues** give 6.3.0's answer again: a source file after a described test is kept, a path that a description only mentions is not read as a file, and a backticked bare name such as `LICENSE` alone on a following line is read as a file. - **The test files on the `Test first:` `File:` line** are the backticked paths that stand right after `File:`, separated only by commas or spaces, and below plan_version 1.9 also each further path after a note in brackets (`(new)`, `*(new)*`, `(existing …)`) or after `and`, `plus` or `+`, as long as it is clearly a test (operator decision 28, 13.10, and operator decision 31, 14.10; review `bd2520b0`). Every one of them is read, locked and copied for red proof, not only the first. A path in the description after them is no test file, at every plan_version (operator decision 20, 12.10; review `6c31212c`), so a step whose `File:` line names its source in the description is no longer read as tests-only. - **A 1.9 `Test first:` names its test only on a line that opens with `File:`**, the way the executor, K6 and red proof read it. Below 1.9 the check reads as before. - **Engine provenance in the review.** Ingest takes `engine` from the payload, never from a field a reviewer wrote on its own finding, and dedup ranks by catalogue tier, so a reviewer-agent finding is kept over an engine finding, and the kept finding carries the group's highest severity, in the coordinator's Pass 1 and in the workflow dedup. A brief-conflict mark can no longer lower a reviewer's MAJOR (operator decision 2026-10-12). On the workflow path, floor (b) and the put-back of every engine finding the coordinator did not return (both below) hold the same line after the coordinator answers. - **Explorers and reviewers stay in the repo.** `/trekplan` tells its brief-reviewer, the eight Phase 5 explorers, the Phase 6 deep-dives, the plan-critic and the scope-guardian to read local files only inside the repo under exploration plus the paths their prompt gives, and every explorer gets the brief. - **The brief review stamp covers only text the reviewer saw.** For a `small` brief, the reviewer's gaps are written after the stamp, so the stamp reads stale and `/trekplan` reviews the brief once more. - **Approval commits carry the caller's Co-Authored-By trailer.** `artifact-commit.mjs` takes `--trailer` and refuses (exit 1, before anything is staged or committed) a missing, multi-line or malformed trailer, an unfilled `{model}`, and one that names a session link. `/trekbrief`, `/trekplan` and `/trekexecute` pass it; `/trekexecute` prints the reason and goes on when the approval is logged but not committed. - **A list joiner no longer ends the read of a plain path below 1.9.** In `Files:`, a `+`, `&`, `and` or `or` between backticked paths is no word of description, so a plain path after them is read as a file again, as 6.3.1 read it, and a step of two tests joined by `+` and a plain source is not tests-only (review `182ceb93`). - **A 1.9 entry keeps the paths of a line wrapped after a comma, and a numbered `File:` line names its test.** A line that is no list item keeps its paths only after a comma, when the entry so far ends with one (operator decision 29, 14.10; reviews `d21ff81e`, `eaeb398e`), so a `Files:` list wrapped after a comma names every file: the step is not tests-only, and K6 plans the second file too. Otherwise that line, and every later wrapped line of the entry, is description and never read. A `File:` line with nothing after it takes its first wrapped line. The `Test first:` `File:` line may open with `-`, `*`, `+`, `1.` or `1)`, and any list item ends it (reviews `b4fa1927`, `4b6460e5`). - **A 1.9 plan refuses placeholders and mixed-case bare names as files** (operator decision 22, 13.10; review `33f37f53`). A leading backticked span that is a placeholder (`none`, `TBD`, `TODO`, `TBA`, `N/A`, `NA`, `...`, in any case) or a bare name that is neither in capitals nor a build file, such as the mixed-case `Parser`, is `PLAN_STEP_PATH_NOT_A_PATH`, and its hint says to write `./Name` for such a file. `LICENSE`, `README` and `Makefile` stay files; below 1.9 nothing changes. - **The engine of a payload is read from an own property.** Ingest no longer gives the findings of a payload whose reviewer is named `toString`, `constructor`, `__proto__` or another name `Object.prototype` carries an `engine` (it gave them a function or an object), and `toReviewerPayload` refuses an engine named `toString` with its "engine must be one of" error (review `3799ea6c`). - **Pass 1 ranks by catalogue tier, and a duplicate never lowers its group.** Of findings with the same `(file, line, rule_key)`, the coordinator's Pass 1 and `dedupByTriplet` keep the one with the higher catalogue tier, then a reviewer-agent finding over an engine finding, then the higher asserted severity, then the `brief-conformance-reviewer` finding, then the first seen, and write the kept finding at the highest severity its group asserted. Before, a marked code-review MAJOR beat a reviewer's MINOR on the same triplet and the review came out ALLOW; now it is WARN (review `bc7f4e23`; the coordinator's prose, operator decision 24). - **The workflow review puts back every engine finding the coordinator did not return** (operator decision 23, 13.10; reviews `ab1b5d9f`, `bc7f4e23`). On the opt-in workflow path, dedup ranks as Pass 1 does, and every engine finding with no returned finding at its exact `(file, line, rule_key)` is put back at its own severity, one per triplet (the higher-severity copy when two share it), so dropping, moving or relabelling an engine finding no longer lowers the verdict. Beside it, floor (b): a returned finding is never below the lower of its reviewer counterpart's severity and its catalogue tier (for a key outside the catalogue, the counterpart's severity). The workflow path is now stricter than the default path (see Known issues). - **An approval trailer with a blank or padded name is refused.** `artifact-commit.mjs` refuses a trailer whose name is empty or only spaces, or that holds two spaces in a row, so an empty `{model}` ("Claude" and two spaces) fails as the module header promises. A name with a parenthesis, such as "Claude Opus 5.5 (1M context)", is still accepted (review `8420915b`). - **The plan validator parses each step once.** `validatePlanContent` reads a step's fields once and every check, `--steps-from` included, reads them from there; its errors and warnings are unchanged (review `93382464`). - **Red proof reads the step's test files from the plan and prints them, and the executor defines them once** (review `cf241526`; operator decision 30, 14.10; reviews `793fc1aa`, `09ae46d8`, `d01df508`, `11ee78c5`). With `--plan` and `--step`, `red-proof.mjs` reads the step's test files from the plan as decision 20 and, below 1.9, decision 31 set them, and prints the list it ran as `tests` (a `tests:` line in text mode). The helper and the executor pass no `--tests`, and the lock's `--files` is that printed list. A `--tests` that names another set is exit 2 with a reason that starts `tests-mismatch` and the plan's list in `plan_tests`; a plan or step it cannot read is exit 2 with a reason that starts `plan-unreadable`, and the executor corrects its own call; a step whose plan names no test file reads as before. `commands/trekexecute.md` defines the step's test files in one sentence the other places point to. - **The `/trekbrief` pass branch names no `## Brief Quality`, and the stats rows span their blocks** (operator decision 21, 12.10). That section belongs to the exhausted and force-stopped branches only. In `tests/fixtures/jsonl-schemas.md` the `line_ref` of the trekbrief, trekplan and trekreview stats rows runs from the phase heading to the closing fence of its stats-append block, and a test pins all four command rows (trekexecute's too) by exact equality. - **`original_severity` names what the kept finding asserted** (review `08deae68`). When Pass 1 raises a finding to its duplicate group's severity, Pass 3 writes `original_severity` from the finding's own severity, and only when that differs from its catalogue tier; the carrier field `pass1_raised_from` never leaves the contract. - **The workflow review fails closed when its coordinator returns nothing** (review `edf2ec56`). A coordinator that returns no verdict and findings counts as a missing reviewer: the merged findings are read at their catalogue tier or higher (never lowered), the verdict starts at WARN (a BLOCK stays BLOCK), and every reviewer, engine and coordinator that did not deliver is named in `allow_blocked_by` as `missing-reviewer:`, so the verdict gate exits 2 on such a WARN. - **K6 keeps its own normaliser and `LIST_ITEM` is one literal again** (operator decision 27, 13.10; review `7961a700`). The two `/simplify` edits that crossed the first remediation's fence around K6 are reverted. - **The control-run test leaves headroom over a slow start** (review `703d87e1`). Under full-suite load the start-point run of red proof's control-run test was killed at its 2 s timeout. The test now gives red proof a 15 s timeout and starts every run but the control slowly on purpose, so a timeout without headroom fails on demand; the numbers live in `tests/helpers/timing.mjs`. - **Below 1.8 a plan that names no test file gets the files the helper wrote** (review `7b3b59ed`; operator decision 41, 14.10). A `File:` line below 1.8 may name its test without backticks, so red proof reads no test file from the plan and answers `no test files given`. The helper then runs the same red proof again with `--tests` naming the files it wrote, and the executor gives red proof that same list, so such a step is proven and locked. ### Known issues - The session split reads a 1.9 plan as an older plan (operator answer 3). - Marked MINOR findings still feed `recurrence` / project-memory proposals. - The default review path's verdict gate does not compare `review.md` with the engine payloads, so only the opt-in workflow path puts an engine finding the coordinator did not return back (operator decision 23). The operator made that check a separate delivery later (operator decision 25, 13.10). - Below 1.9 the plan-file sweep (K6) keeps its own wider reader of the `File:` line (operator 2026-10-11): it plans every backticked path on that line, also one in the description that decision 20 no longer counts as a test file. - Red proof accepts a `--tests` that matches the plan's list and prints it in the spelling it was given, not the plan's (review `2d624b54`; deferred by operator decision 42, 14.10). - `ingest` keeps a `pass1_raised_from` and an `original_severity` that a payload wrote on its own finding (reviews `c06d5385`, `e031a480`; deferred by operator decision 42, 14.10). - When its coordinator returns nothing, the workflow review raises the merged findings in place; this has no effect on its output today (review `6ff82e75`; deferred by operator decision 42, 14.10). - A whitespace-only line ends a 1.9 `Test first:` `File:` entry but not a `Files:` entry, to be skipped in both by operator decision 40 (review `4b6460e5`; deferred by operator decision 42, 14.10). The same id stands in a Fixed bullet above, which fixed the list-item case of that review; the whitespace-only case came back open. - A 1.9 wrapped line read as description is dropped without a warning, even when it opens with a backticked path, to be warned on by operator decision 39 (review `4e1607cb`; deferred by operator decision 42, 14.10). - Handover 4's `Files:` bullet words its empty-entry rule as for a `File:` line (review `4f22b101`; deferred by operator decision 42, 14.10). - Accepted deviation: the 1.9 `File:` selector repeats the list-marker set of `LIST_ITEM` (review `4dce7c74`; operator decision 38, 14.10, decision 27 stands). ## v6.3.1 — 2026-10-11 — Fixes from the release review of 6.3.0, and two verdict-gate holes closed Rounds 7 to 10 of the release review of 6.3.0. Round 7 is the WARN 6.3.0 was released with, round 8 was BLOCK (1 BLOCKER), rounds 9 and 10 were WARN. Every fix began with a test that failed on the code before it. Suite 2236 (2234 pass, 0 fail, 2 skipped). Nothing here asks anything of users. Measured against 6.3.0 over the marketplace and the test repo: the plan validator reports the same errors and warnings for all 233 plan files, the verdict gate gives the same exit for all 123 review files, and tests-only reads the same for all 1408 plan steps. ### Doors - two-way: tests-only is decided by the plan's `Files:` alone, and red proof no longer reads the step's diff (operator decision 2026-10-11) — a revert brings the diff check back; plans stay valid. - two-way: the `Files:` reader keeps a plain file beside a backticked path, reads numbered entries, and keeps a description together across commas and lines — it feeds only the `PLAN_STEP_TESTS_ONLY` warning and red proof's `tests_only`; a revert restores the 6.3.0 reading. - two-way: a trailing `# comment` is dropped from a backticked check too, so such a check now runs; one whose comment holds a double quote, `$`, a backtick or a backslash is refused out loud — 6.3.0 refused every backticked check with a comment, so nothing that ran stops running. - two-way: the verdict gate reads the last fenced block once and answers exit 2 unless its info string is exactly `json`, or when it is never closed; a `~~~` fence is a fence — a review written by `/trekreview` reads as before; a revert reopens the two holes under Fixed. - two-way: stops and timeouts, the release check's `--review`, `isMain` in every CLI, the test lock's command comparison, one fence reader, and cleanups — fixes; a revert restores the old behaviour. ### Fixed - **Two verdict-gate holes, present in 6.3.0.** A review that ended with a clean json block and then a block holding a BLOCK verdict, written as `~~~json` or opened with more text after `json` on its line, passed with exit 0: the gate did not see the second block. Both are exit 2 now. - **Tests-only steps.** The plan's `Files:` alone decides, and red proof, `/trekexecute`, `step-implementer` and the handover contract say so. A change already in the tree when the step began no longer counts against it, and a plan outside `.claude/` reads the same. - **The `Files:` reader** keeps a plain file beside a backticked path (", Dockerfile", "and Makefile"), reads a numbered entry (`1.` or `1)`) as an entry, keeps a description together past a comma and onto the next line, and starts a description at a plain file followed by a colon. Lowercase `makefile`, `rakefile` and `justfile` are build files. - **Checks with a comment.** A trailing `# comment` is dropped in a backticked check and in a command passed as written, so the words screened are the words run. A comment with a double quote, `$`, a backtick or a backslash is refused instead, because the executor hands the `Verify:` span to red proof, the test lock and the done line inside double quotes. Every reader refuses it out loud (`PLAN_VERIFICATION_NOT_RUNNABLE`, `BRIEF_SC_NOT_RUNNABLE`). A span that is only a comment is not-a-command. - **Stops.** Red proof reports a command killed by its timeout as killed after the timeout, not "could not start". The release check tells a timeout from output past its buffer and from another signal. One reading of a stop (`stoppedBy`) serves red proof, the criteria runner, the test lock, the done line and the release check. - **Release check.** A relative `--review` is read in `--repo`, or from the current directory when only that one exists. Two different files are exit 2, never guessed, and one file reached through a symlinked `--repo` is one file. - **Every CLI uses one `isMain` helper.** Before, some did nothing and exited 0 when run through a symlink or a path with a space. - **Test lock.** It compares `--cmd` by its words and without its trailing comment. - **One fence reader** for the gate and every reader of a trailing json block. A fence closes only on a run at least as long as its opener, as in Markdown, and CRLF and an indented fence read alike everywhere. A fence indented four spaces or more still counts, on purpose: Markdown's rule made a BLOCKER block inside a list item invisible. - **Cleanups.** The 15-minute timeout is defined once, the findings check reads each cited file once per validation, and the guard writes its no-one-to-ask refusal once. ### Known issues Round 11 of the release review (`0f400d3..10ac9c5`) is WARN: 0 BLOCKER, 10 MAJOR, 0 MINOR. All ten come from Claude Code's `/code-review`, which gives no category, so each enters as MAJOR. Voyage's two reviewers and `/security-review` found none. The operator chose to release 6.3.1 with it (2026-10-11). None of the ten lets a gate pass. The regressions below were checked by running them against 6.3.0. None of them occurs in the 1408 plan steps measured above. - The `Files:` reader still guesses paths from prose and misreads in both directions. Two misreads are regressions from 6.3.0: - A source file after a described test is dropped ("`tests/a.test.mjs` - new test, src/a.mjs - the fix"). The step that builds code then reads as tests-only and goes to the plan. - A path that a description only mentions is read as a file ("covers the parser in src/parse.mjs"). A step of only tests is then not caught and goes through fix rounds (at most five, then the operator). Red proof has no diff check behind the reader. The structural fix is to require every path in `Files:` to be backticked. It changes the plan contract and is left for a planned release. - A json block closed on the same line as its JSON is no longer read (a regression from 6.3.0). The gate answers exit 2, and a reviewer is asked again. An opener with a blank before `json` is not json either, as in 6.3.0. - A trailing comment with a double quote, `$`, a backtick or a backslash is refused in every backticked check. That includes checks that never reach a shell: a `## Verification` bullet, `Regression:`, `End-to-end:` and a brief criterion. 6.3.0 refused these too. - Cleanups: a dead branch for a span that is only a comment, the comment dropped up to four times per command, a re-export of the timeout that nothing imports, and a test helper that copies a PATH lookup. - An engine run that was stopped and not counted in the verdict reported three more, each checked by running: - A backticked bare name such as `LICENSE`, alone on a line after a description, is no longer read as a file. 6.3.0 read it. - One unclosed fence earlier in a review hides the review's own json block from the review validator. 6.3.0 found the block, and the gate answers exit 2 there. - An indented json example after a review's own block is read as the last block, as in 6.3.0. - The example plan's steps 1-2 keep their tests-only warning (operator decision 2026-10-09). ## v6.3.0 — 2026-10-11 — The executor is coupled to the review gate, three skills, and a drilled release runbook Wave 2 of the practice build (five orders, merged 2026-10-09) and the fix round after it, which closes finding 1 of the test repo's third trial: a step of only tests can never be proven red. Every fix began with a test that failed on the old code. Suite 2194 (2192 pass, 0 fail, 2 skipped). Two changes ask something of users (see Doors): `/trekexecute` now refuses a plan that has no logged approval for its current content, and a check in a brief or plan runs with no shell, as plain words with a runner's read-only options. Plan 1.7/1.8, brief 2.0–2.2 and review 1.0/1.1 files still validate; the new step fields are optional. ### Doors - one-way: `/trekexecute` refuses a plan whose logged approval does not cover its current sha256 (K2) — a plan written before 6.2.0, written by hand, or edited after its approval stops at Phase 1; run `/trekplan --project ` and answer "Approve" (from 6.3.0). - two-way: `/trekexecute` reviews by itself in the closing run (`/simplify` → `/trekreview` → verdict gate, K7) and keeps the main merge closed on BLOCK or an undecided verdict; step check (K9), `Regression:` (K10), architecture rules (K5) and plan-file sweep (K6) run at step end and after the last step — a revert restores the old executor; nothing to do for users. - two-way: the approval guard refuses a merge into main, a push, a tag or publish and destructive git in the permission mode that shows no prompts — a revert lets them through again; nothing to migrate. - two-way: `progress-validator` rejects the runner's `exitCode` in `plan_verification.failed_criteria` (C15) — the executor's own prose always wrote `exit_code`. - two-way: skills workshop — form check, model-free routing test, `test-first` and `debugging` preloaded into `step-implementer` — new files and one `skills:` line; a revert removes them. - two-way: `researching-sources` skill, preloaded by the five web-search agents and named by `/trekresearch` — the agents' copied rule text moved into the skill; a revert puts it back. - two-way: `Regression:` (K10) and `On failure:` action words (K11) — an optional field and a warning; plans without them validate as before. - two-way: trial 2's minor fixes (B8, B11, B12, C13, C14, C16, C17) — checks, prose and agent text; a revert restores the old behaviour. - two-way: release check and runbook — new files; a revert removes them, and nothing else reads them. - two-way: tests-only steps (`PLAN_STEP_TESTS_ONLY`, red-proof `--plan/--step` → `tests_only`, which also reads the step's own diff, executor routes them to the plan) — a warning and an optional flag; a revert removes them, plans stay valid. - two-way: timing tests under load (hook helper kill limit 30 s, SC #14 fastest of three against 800 ms) — test-only. - two-way: example plan `On failure:` lines open with a K11 word, and its verbose-content test moves into the step that wires the output (6 steps, progress.json follows) — text in an example. - two-way: `/trekreview` saves the reviewer's whole answer for the findings check and names `FINDING_PROSE_LINE_OUT_OF_RANGE` — command text. - two-way: the criteria runner's commands run without `NODE_TEST_CONTEXT` — a false green under `node --test` is now red; nothing to do for users. - two-way: the fixes from the release review of 6.3.0 (rounds 1-6) — checks and prose; `progress.json` may now say `simplify: "revert-refused"` (an optional value); a revert restores the old behaviour. - one-way: a check in a brief or plan (criteria, `Regression:`, proof of red, the done line, the test lock) runs with no shell: its words reach the runner as written, so only plain words run (no quote, backslash, `$`, brace, or `~`/`@` at a word's start; a glob only for `node --test` on Node 21 and later; no path that climbs out with `..` or starts at `/`, git included; a trailing `# comment` in a shell fence is dropped) with a short list of read-only options per runner — git without `--output` or `--no-index`, `node --test` with a built-in `--test-reporter` only, nothing after `make test`, only paths after `npm test --`; an option that writes a file or loads code is refused — a criterion that used one (`git log --grep="x"`, `pytest -k foo`, `pytest tests/test_*.py`, `jest --coverage`, `go test -timeout 30s`) is now NOT RUN at review and not runnable on a 1.8 plan; wrap it in `bash tests/