fix(ship-measure): report lists v1 measurements as an older format instead of crashing

This commit is contained in:
garrytan committed 2026-10-07 23:14:31 +00:00
1 parent 1912604284
commit 2a503b754e
3 files changed
+18

No files matched your search

+2
View File
@@ -70,6 +70,8 @@ Run `~/.claude/skills/gstack/bin/gstack-brain-sync --status`. Each held file is
- The outside-review classifier reported reviews with severity words and no `[Pn]` tags as clean.
- /context-restore picked an older checkpoint from a nested repo or a task worktree. (#3065)
- Browse cookbook: the script mistakes that look like page bugs (non-serializable `evaluate` results, a top-level `return`, `pg.press`, empty DOM reads). (#3063, #3064)
- `ship-measure report` no longer crashes on a measurement saved by v1.91.32.0; it lists that round as an older format to re-measure.
- The paid shared-code cases recognize Claude Code 2.1.292's own internal git probe, which now disables every git hook by name, instead of reading it as an unguarded git call from the skill.
- Credits in the v1.64.0.0 entry: the extension token fix (#1822) goes to @Mike-E-Log, and the polyfill `exited` promise (#1743) to @habassa5. (#3054)
#### For contributors
+4
View File
@@ -487,6 +487,10 @@ export function formatReport(outDir: string): string {
for (const round of ledger?.rounds ?? []) {
const m = readJson<Measurement>(path.join(dir, round, 'measurement.json'));
if (!m) continue;
if (m.schema !== 'gstack-ship-measure/2') {
rows.push(`| ${m.case} | ${m.kind ?? '—'} | ${round} | — | — | older measurement format (${String(m.schema).replace(/\|/g, '/')}); not read, re-measure on this release | — | — |`);
continue;
}
const bar = m.counted > m.plan.trials ? m.plan.pooledBar : m.plan.bar;
const what = m.fix ? `${m.round}: after fix at ${m.fix.replace(/\|/g, '/')}` : m.round;
const batches = m.sets.length > 1 ? ` (${m.sets.map(s => `${s.set} ${s.passes}/${s.trials}${s.void ? ' void' : ''}`).join(', ')})` : '';
+12
View File
@@ -210,6 +210,18 @@ describe('spend, approval, rounds and artifacts', () => {
expect(report).toContain('| browse-basic | — | — | — | — | unmeasured (provider outage before the first turn); not a pass | — | — |');
expect(report).toContain('never change a recorded verdict');
});
test('a measurement in the older v1 format is listed as not read instead of crashing the report', () => {
const outDir = tmp('ship-measure-report-v1-');
const dir = path.join(outDir, 'old-case');
fs.mkdirSync(path.join(dir, 'round-1'), { recursive: true });
fs.writeFileSync(path.join(dir, 'ledger.json'), JSON.stringify({ rounds: ['round-1'] }));
fs.writeFileSync(path.join(dir, 'round-1', 'measurement.json'), JSON.stringify({
schema: 'gstack-ship-measure/1', label: 'diagnostic', verdict: null, case: 'old-case', kind: 'rule', round: 'round-1',
status: 'measured', plan: { kind: 'rule', units: 10, trialsPerUnit: 1, trials: 10, unitTarget: 9, trialTarget: 9 }, trials: [],
}));
expect(formatReport(outDir)).toContain('| old-case | rule | round-1 | — | — | older measurement format (gstack-ship-measure/1); not read, re-measure on this release | — | — |');
});
});
describe('ship-measure CLI with a documented single-case command', () => {