from pathlib import Path ROOT = Path(__file__).resolve().parents[1] required = [ 'docs/40-build-launch/BUILD_SUCCESS_DEFINITION.md', 'docs/40-build-launch/SPRINT_1_SCOPE_FREEZE.md', 'docs/40-build-launch/DATA_ACQUISITION_PLAYBOOK.md', 'docs/40-build-launch/GOLDEN_DATASET_PACKAGE.md', 'docs/40-build-launch/BUILD_ORDER_GRAPH.md', 'docs/40-build-launch/MODULE_ACCEPTANCE_CRITERIA.md', 'docs/40-build-launch/CODEX_STOP_RULES.md', 'docs/40-build-launch/RELEASE_STRATEGY.md', 'docs/40-build-launch/RISK_REGISTER.md', 'docs/40-build-launch/BACKLOG_PRIORITIES_MOSCOW.md', 'docs/40-build-launch/FOLDER_OWNERSHIP.md', 'prompts/codex/m14/CODEX_FIRST_DAY_MASTER_PROMPT.md', 'checklists/SPRINT_1_OPERATOR_CHECKLIST.md', 'release/v0.1-foundation-target.md', ] missing = [p for p in required if not (ROOT / p).exists()] if missing: raise SystemExit('Missing M14 launch assets:\n' + '\n'.join(missing)) prompt = (ROOT / 'prompts/codex/m14/CODEX_FIRST_DAY_MASTER_PROMPT.md').read_text(encoding='utf-8') required_terms = [ 'Sprint 1 only', 'Do not build yet', 'YOLO live inference', 'CODEX_STOP_RULES', 'BUILD_SUCCESS_DEFINITION', ] missing_terms = [term for term in required_terms if term not in prompt] if missing_terms: raise SystemExit('M14 prompt missing expected control terms: ' + ', '.join(missing_terms)) start = (ROOT / 'CODEX_START.md').read_text(encoding='utf-8') if 'prompts/codex/m14/CODEX_FIRST_DAY_MASTER_PROMPT.md' not in start: raise SystemExit('CODEX_START.md does not point to M14 first-day prompt') readme = (ROOT / 'README.md').read_text(encoding='utf-8') if 'M14 — Build Launch Package' not in readme: raise SystemExit('README.md does not identify M14 as current milestone') print('M14 launch assets OK')