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>
This commit is contained in:
Kjell Tore Guttormsen 2026-10-05 18:16:46 +02:00
commit cb68c4f125
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
7 changed files with 130 additions and 28 deletions

View file

@ -198,6 +198,42 @@ test('CLI shim with malformed --payload returns reason payload-not-json (exit 1)
}
});
// `--payload -` reads the payload from stdin, so the command prose can pass it
// through a quoted heredoc: the shell expands nothing, and a plan path with a
// quote character can no longer close a single-quoted argument.
test('CLI shim with --payload - reads the payload from stdin, quote characters and all', () => {
const home = tmp();
try {
const plan = ".claude/projects/it's a'$(touch PWNED)'b/plan.md";
const r = spawnSync(process.execPath, [SHIM, '--event', 'main-merge-gate', '--payload', '-'],
{ encoding: 'utf-8', env: isolatedEnv(home), input: JSON.stringify({ plan, wave_count: 1 }) });
assert.equal(r.status, 0, r.stdout + r.stderr);
const [rec] = records(join(home, DATA_REL, 'trekexecute-stats.jsonl'));
assert.deepEqual(rec.payload, { plan, wave_count: 1 });
} finally {
rmSync(home, { recursive: true, force: true });
}
});
test('CLI shim with --payload - and a stdin that is not JSON returns payload-not-json (exit 1)', () => {
const home = tmp();
try {
const r = spawnSync(process.execPath, [SHIM, '--event', 'main-merge-gate', '--payload', '-'],
{ encoding: 'utf-8', env: isolatedEnv(home), input: 'not-json{{' });
assert.equal(r.status, 1, r.stdout + r.stderr);
assert.equal(JSON.parse(r.stdout.trim()).reason, 'payload-not-json');
assert.ok(!existsSync(join(home, DATA_REL, 'trekexecute-stats.jsonl')));
} finally {
rmSync(home, { recursive: true, force: true });
}
});
// The emit() docstring said failures are "swallowed silently" after the contract
// became {written:false, reason}.
test('emit() is not documented as swallowing failures silently', () => {
assert.doesNotMatch(readFileSync(SHIM, 'utf-8'), /swallowed silently/);
});
test('CLI: with CLAUDE_PLUGIN_DATA empty the event lands under HOME', () => {
const home = tmp();
try {