feat(review): generate review/design-checklist.md from the catalog

review/design-checklist.md was hand-written and its own header admitted it
drifted from DESIGN_METHODOLOGY category 9. It is now rendered by
scripts/resolvers/design-checklist.ts from lib/design-catalog.ts: category 1
lists every grep-detectable slop entry plus the legacy blacklist lines,
sorted HIGH/MEDIUM/LOW, each with its heuristic and, where the detector knows
the rule, its bracketed id (27 items, up from 6). The font blacklist renders
from BANNED_FONTS. Categories 2-5, Instructions, Classification, Output
Format, and Suppressions keep their prose. Title and slop heading are
unchanged (test/skill-e2e-review.test.ts and hosts/opencode.ts key on them).

gen-skill-docs writes the file for the Claude host only (a Claude-side
runtime asset; other hosts copy or inline the render), honors --out-dir, and
reports STALE/FRESH under --dry-run like sections do.
test/design-checklist-sync.test.ts pins committed == generated, the
host/out-dir scoping, and the dry-run freshness line.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-09-08 15:34:24 +00:00
co-authored by Claude Fable 5.1
parent e34541c3bd
commit 11c2a33ae9
5 changed files with 373 additions and 11 deletions
+27
View File
@@ -11,6 +11,7 @@
import { discoverTemplates, discoverSectionTemplates } from './discover-skills';
import { writeLlmsTxt } from './gen-llms-txt';
import { generateDesignChecklistMd } from './resolvers/design-checklist';
import * as fs from 'fs';
import * as path from 'path';
import type { Host, TemplateContext } from './resolvers/types';
@@ -1103,6 +1104,32 @@ for (const currentHost of hostsToRun) {
});
}
// ─── review/design-checklist.md (generated from lib/design-catalog.ts) ───
// A Claude-side runtime asset: setup links it from review/ and the other
// hosts copy or inline the Claude render (hosts/opencode.ts), so it is
// written for the CLAUDE host only. Honors OUT_DIR (outputs-only rule) and
// takes part in the DRY_RUN freshness gate exactly like sections above.
if (currentHost === 'claude'
&& !(currentHostConfig.generation.includeSkills?.length && !currentHostConfig.generation.includeSkills.includes('review'))
&& !currentHostConfig.generation.skipSkills?.includes('review')) {
const outputPath = path.join(OUT_DIR ?? ROOT, 'review', 'design-checklist.md');
const relOutput = path.relative(OUT_DIR || ROOT, outputPath);
const content = generateDesignChecklistMd();
if (DRY_RUN) {
const existing = fs.existsSync(outputPath) ? fs.readFileSync(outputPath, 'utf-8') : '';
if (existing !== content) {
console.log(`STALE: ${relOutput}`);
hasChanges = true;
} else {
console.log(`FRESH: ${relOutput}`);
}
} else {
if (OUT_DIR) fs.mkdirSync(path.dirname(outputPath), { recursive: true });
fs.writeFileSync(outputPath, content);
console.log(`GENERATED: ${relOutput}`);
}
}
// Generate the OpenClaw orchestrator-injection docs (gstack-lite / gstack-full /
// gstack-plan CLAUDE.md snippets). Sources live in openclaw/templates/ —
// plain markdown, no placeholder resolution — and are copied byte-for-byte