fix(gate): a differing README H1 is a WARN, not an ERROR
Measured against the live repos: okr opens `# OKR for Public Sector` and claude-design `# Claude Design Facilitator`. Neither breaks the thread the contract exists to protect - description == catalog == opening line - because the H1 is none of those three. Failing them would be the gate that stops a correct repo, which is what teaches people to switch gates off. A missing H1 stays an ERROR, and a differing one no longer short- circuits the description check. Validation against three cases the census measured by hand, all reproduced independently: okr (neither install line), claude-design (slash form, no marketplace add), repo-mailbox (install correct, first screen wrong). 34 tests. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WYJ3FHLtVgzFXMZ6UF598h
This commit is contained in:
parent
816ba97c63
commit
2357771587
2 changed files with 34 additions and 4 deletions
|
|
@ -120,15 +120,31 @@ export function checkFirstScreen({ readme, name, description }) {
|
|||
const lines = String(readme ?? '').split('\n');
|
||||
const firstIdx = lines.findIndex((l) => l.trim() !== '');
|
||||
|
||||
if (firstIdx === -1 || lines[firstIdx].trim() !== `# ${name}`) {
|
||||
const heading = firstIdx === -1 ? null : lines[firstIdx].trim();
|
||||
|
||||
// No heading at all is broken. A heading that merely differs from the repo
|
||||
// name is not: the thread that has to hold is description == catalog ==
|
||||
// opening line, and the H1 is none of those three. A human title like
|
||||
// `# OKR for Public Sector` is a naming choice the operator owns, so it is
|
||||
// surfaced and left to them — a gate that fails a correct repo is the
|
||||
// mechanism that gets gates switched off.
|
||||
if (heading === null || !heading.startsWith('# ')) {
|
||||
findings.push({
|
||||
level: 'ERROR',
|
||||
code: 'README-H1',
|
||||
msg: `README line 1 must be \`# ${name}\` (found: ${firstIdx === -1 ? '<empty file>' : `\`${lines[firstIdx].trim()}\``})`,
|
||||
msg: `README must open with an H1 (expected \`# ${name}\`, found: ${heading === null ? '<empty file>' : `\`${heading}\``})`,
|
||||
});
|
||||
return findings;
|
||||
}
|
||||
findings.push({ level: 'OK', code: 'README-H1', msg: `H1 is \`# ${name}\`` });
|
||||
if (heading !== `# ${name}`) {
|
||||
findings.push({
|
||||
level: 'WARN',
|
||||
code: 'README-H1',
|
||||
msg: `H1 is \`${heading}\`, not \`# ${name}\` — deliberate title, or drift? Operator's call.`,
|
||||
});
|
||||
} else {
|
||||
findings.push({ level: 'OK', code: 'README-H1', msg: `H1 is \`# ${name}\`` });
|
||||
}
|
||||
|
||||
if (description === null || description === undefined) {
|
||||
findings.push({ level: 'SKIP', code: 'README-DESC', msg: 'forge description not available — opening-line match not checked' });
|
||||
|
|
|
|||
|
|
@ -192,11 +192,25 @@ test('first-screen description match is SKIP when the forge text is unavailable'
|
|||
assert.equal(f.some((x) => x.code === 'README-DESC' && x.level === 'SKIP'), true);
|
||||
});
|
||||
|
||||
test('a wrong or missing H1 is an ERROR', () => {
|
||||
test('a missing H1 is an ERROR', () => {
|
||||
const f = checkFirstScreen({ readme: 'no heading here\n', name: 'x', description: null });
|
||||
assert.equal(f.some((x) => x.level === 'ERROR' && x.code === 'README-H1'), true);
|
||||
});
|
||||
|
||||
test('an H1 that differs from the repo name is a WARN, not a failure', () => {
|
||||
// `# OKR for Public Sector` is a naming choice, not a defect: the thread that
|
||||
// must hold is description == catalog == opening line, and the H1 is none of
|
||||
// those three. Surface it; let the operator decide.
|
||||
const f = checkFirstScreen({ readme: '# OKR for Public Sector\nbody\n', name: 'okr', description: null });
|
||||
assert.equal(f.some((x) => x.level === 'WARN' && x.code === 'README-H1'), true);
|
||||
assert.equal(f.some((x) => x.level === 'ERROR'), false);
|
||||
});
|
||||
|
||||
test('a differing H1 does not stop the description check from running', () => {
|
||||
const f = checkFirstScreen({ readme: '# Nice Title\nthe description\n', name: 'x', description: 'the description' });
|
||||
assert.equal(f.some((x) => x.code === 'README-DESC' && x.level === 'OK'), true);
|
||||
});
|
||||
|
||||
// ------------------------------------------------------------ install block
|
||||
|
||||
const MKT = REGISTER.marketplace;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue