v5.1.0 shipped with an unquoted brief_version: 2.1 in trekbrief-template.md. parseScalar coerced it to Number 2.1, and the sequencing gate guarded on typeof === 'string', silently bypassing BRIEF_V51_MISSING_SIGNALS. Three-part atomic fix: - brief-validator.mjs:87+149 now accepts both string and number forms via String(fm.brief_version) coercion. - trekbrief-template.md quotes the value so new briefs parse as String. - doc-consistency.test.mjs pins the QUOTED form going forward. Three regression tests added in brief-validator.test.mjs.
This commit is contained in:
parent
a67b5717c9
commit
4c85a2c22b
4 changed files with 44 additions and 8 deletions
|
|
@ -218,3 +218,35 @@ test('validateBrief — phase_signals with unknown phase rejected', () => {
|
|||
assert.equal(r.valid, false);
|
||||
assert.ok(r.errors.find(e => e.code === 'BRIEF_INVALID_PHASE_SIGNAL_PHASE'));
|
||||
});
|
||||
|
||||
// --- v5.1.1 regression: YAML-number bypass closed ---
|
||||
// Findings 3c834097 + df1435a2: v5.1.0 shipped with an unquoted `brief_version: 2.1`
|
||||
// template. parseScalar coerces unquoted "2.1" to Number 2.1, and the original gate
|
||||
// guarded `typeof === 'string'`, silently bypassing the sequencing check. v5.1.1
|
||||
// coerces via String() so both shapes trigger the gate.
|
||||
|
||||
test('validateBrief — v5.1.1: UNQUOTED brief_version 2.1 without signals triggers gate', () => {
|
||||
const t = GOOD_BRIEF.replace('brief_version: "2.0"', 'brief_version: 2.1');
|
||||
const r = validateBriefContent(t, { strict: true });
|
||||
assert.equal(r.valid, false);
|
||||
assert.ok(
|
||||
r.errors.find(e => e.code === 'BRIEF_V51_MISSING_SIGNALS'),
|
||||
`gate must fire for unquoted brief_version: 2.1 (YAML Number); errors=${JSON.stringify(r.errors)}`,
|
||||
);
|
||||
});
|
||||
|
||||
test('validateBrief — v5.1.1: QUOTED brief_version "2.1" without signals triggers gate (regression guard)', () => {
|
||||
const t = GOOD_BRIEF.replace('brief_version: "2.0"', 'brief_version: "2.1"');
|
||||
const r = validateBriefContent(t, { strict: true });
|
||||
assert.equal(r.valid, false);
|
||||
assert.ok(r.errors.find(e => e.code === 'BRIEF_V51_MISSING_SIGNALS'));
|
||||
});
|
||||
|
||||
test('validateBrief — v5.1.1: UNQUOTED brief_version 2.1 WITH phase_signals is valid (positive case)', () => {
|
||||
const t = GOOD_BRIEF
|
||||
.replace('brief_version: "2.0"', 'brief_version: 2.1')
|
||||
.replace('source: interview\n', `source: interview\n${SIGNALS_BLOCK}`);
|
||||
const r = validateBriefContent(t, { strict: true });
|
||||
assert.equal(r.valid, true, JSON.stringify(r.errors));
|
||||
assert.ok(!r.errors.find(e => e.code === 'BRIEF_V51_MISSING_SIGNALS'));
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue