import { existsSync, readFileSync } from 'node:fs'; import { join } from 'node:path'; const root = process.cwd(); type Check = { name: string; path: string; includes?: string[]; }; const checks: Check[] = [ { name: 'root Codex instructions', path: 'AGENTS.md', includes: [ '## Codex Harness', 'docs/_para/20_areas/codex-harness.md', 'docs/_para/20_areas/superpowers.md', 'docs/_para/20_areas/codex-prompts.md', 'bun run check:harness', ], }, { name: 'docs entrypoint', path: 'docs/README.md', includes: ['# Carboany Docs Entry', 'docs/expert_specs/'], }, { name: 'harness operating guide', path: 'docs/_para/20_areas/codex-harness.md', includes: ['## 적용 상태', '## 기본 루프', '## 필수 검증'], }, { name: 'superpowers routing', path: 'docs/_para/20_areas/superpowers.md', includes: ['# Superpowers Routing', 'citizen-mrv-engineer', 'methodology-campaign-architect'], }, { name: 'prompt set', path: 'docs/_para/20_areas/codex-prompts.md', includes: ['# Codex Prompt Set', '토큰 절약 모드', '브라우저 검증'], }, { name: 'graphify report', path: 'graphify-out/GRAPH_REPORT.md', includes: ['# Graph Report'], }, ]; const failures: string[] = []; for (const check of checks) { const fullPath = join(root, check.path); if (!existsSync(fullPath)) { failures.push(`${check.name}: missing ${check.path}`); continue; } if (!check.includes?.length) continue; const content = readFileSync(fullPath, 'utf8'); for (const expected of check.includes) { if (!content.includes(expected)) { failures.push(`${check.name}: ${check.path} does not include "${expected}"`); } } } if (failures.length > 0) { console.error('Codex Harness check failed:'); for (const failure of failures) { console.error(`- ${failure}`); } process.exit(1); } console.log('Codex Harness check passed.');