From 77eb27dcabc106a39d76b3bc15f17ec4af664d8c Mon Sep 17 00:00:00 2001 From: garrytan Date: Wed, 7 Oct 2026 01:28:10 +0000 Subject: [PATCH] fix(ship-measure): the selection preflight accepts name-mode cases A case registered beside others in its file lists its trial shard as #~t1, not (trial 1), so the preflight refused every name-mode case (for example ship-exploratory-late-input) before any paid trial. Accept both forms. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- scripts/ship-measure.ts | 4 +++- test/ship-measure.test.ts | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/ship-measure.ts b/scripts/ship-measure.ts index 31be5368d..6519ef36e 100644 --- a/scripts/ship-measure.ts +++ b/scripts/ship-measure.ts @@ -528,7 +528,9 @@ export function caseSelectionPreflight(caseId: string, rootDir = ROOT): { ok: bo const out = `${r.stdout ?? ''}${r.stderr ?? ''}`; if (r.status !== 0) return { ok: false, detail: `--list exited ${r.status}: ${out.trim().split('\n').slice(-1)[0] ?? ''}` }; const file = new RegExp(`--case ${caseId.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}: \\d+ trial\\(s\\) of (\\S+)`).exec(out)?.[1]; - const listed = file && new RegExp(`^\\s+${file.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')} \\(trial 1\\)`, 'm').test(out); + const esc = (text: string) => text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + // A file-mode case lists ` (trial 1)`; a name-mode case lists its trial shard `#~t1`. + const listed = file && new RegExp(`^\\s+${esc(file)}(?: \\(trial 1\\)|#${esc(caseId)}~t1)$`, 'm').test(out); if (!file || !listed || !fs.existsSync(path.join(rootDir, file))) return { ok: false, detail: `--list did not plan a trial of ${caseId}'s test file` }; return { ok: true, detail: `--case ${caseId} selects ${file}` }; } diff --git a/test/ship-measure.test.ts b/test/ship-measure.test.ts index e6305b196..b8f6cf6d4 100644 --- a/test/ship-measure.test.ts +++ b/test/ship-measure.test.ts @@ -350,9 +350,11 @@ describe('diagnostic trials prove they ran and never touch the judge cache', () }); describe('the measure CLI proves --case selection before any paid trial', () => { - test('a real case plans its own test file; an unknown case is refused', () => { + test('a real case plans its own test file, in file mode or name mode; an unknown case is refused', () => { const { caseSelectionPreflight } = require('../scripts/ship-measure'); expect(caseSelectionPreflight('ship-measure-seeded-flake')).toEqual({ ok: true, detail: '--case ship-measure-seeded-flake selects test/skill-e2e-ship-measure-loop.test.ts' }); expect(caseSelectionPreflight('no-such-case').ok).toBe(false); + // A name-mode case (one of several in its file) lists its trial shard as #~t1. + expect(caseSelectionPreflight('ship-exploratory-late-input')).toEqual({ ok: true, detail: '--case ship-exploratory-late-input selects test/skill-e2e-qa-callers.test.ts' }); }); });