import { readFileSync, existsSync } from 'node:fs'; const requiredFiles = [ 'src/features/repo-builder/pages/RepoBuilder.tsx', 'src/app/routes.tsx', 'src/shared/lib/navigation.tsx', 'src/shared/components/ProjectFlowRail.tsx', 'src/shared/contexts/ProjectContext.tsx', 'src/shared/lib/model.ts', 'src/shared/lib/safeData.ts', 'src/shared/lib/codexSkills.ts', 'src/shared/lib/repositoryIntake.ts', 'src/shared/lib/projectSearch.ts', 'src/shared/lib/projectOperatingStep.ts', 'src/features/history/pages/ProjectHistory.tsx', 'src/features/execution-feedback/pages/ExecutionFeedback.tsx', 'src/shared/lib/buildLoop.ts', ]; const failures = []; for (const file of requiredFiles) { if (!existsSync(file)) failures.push(`Missing required file: ${file}`); } const read = (file) => readFileSync(file, 'utf8'); const repoPage = read('src/features/repo-builder/pages/RepoBuilder.tsx'); const routes = read('src/app/routes.tsx'); const navigation = read('src/shared/lib/navigation.tsx'); const flowRail = read('src/shared/components/ProjectFlowRail.tsx'); const context = read('src/shared/contexts/ProjectContext.tsx'); const model = read('src/shared/lib/model.ts'); const safeData = read('src/shared/lib/safeData.ts'); const skills = read('src/shared/lib/codexSkills.ts'); const repositoryIntake = read('src/shared/lib/repositoryIntake.ts'); const projectSearch = read('src/shared/lib/projectSearch.ts'); const operatingStep = read('src/shared/lib/projectOperatingStep.ts'); const history = read('src/features/history/pages/ProjectHistory.tsx'); const pkg = read('package.json'); const mustContain = [ [repoPage, 'Repositorybasis genereren', 'Repo Builder page must generate foundation blueprints.'], [repoPage, 'Uitbreiding uit selectie maken', 'Repo Builder must generate targeted expansion briefs.'], [repoPage, 'Ontwerpdocumentatie voor deze uitbreiding', 'Repo Builder must explicitly use design documentation as repo-expansion input.'], [repoPage, 'Actieve Codex-handoff', 'Repo Builder must expose an active Codex handoff.'], [repoPage, 'Repository changes', 'Repo Builder must show file-level repository changes.'], [repoPage, 'goedgekeurde ontwerpdocumentatie', 'Repo Builder must explain its place in the reviewed project flow.'], [routes, '/projects/:projectId/repo-builder', 'Repo Builder route missing.'], [navigation, 'label: "Repository"', 'Repository navigation item missing.'], [navigation, '`${base}/repo-builder`', 'Local repository navigation must route to Repo Builder.'], [flowRail, 'Repo Builder', 'Repo Builder flow rail step missing.'], [flowRail, 'shape the repo', 'Flow rail must place Repo Builder logically before delivery.'], [context, 'generateRepoBlueprint', 'Project context must expose generateRepoBlueprint.'], [context, 'archiveRepoBlueprint', 'Project context must expose archiveRepoBlueprint.'], [context, 'generateRepoExpansionBrief', 'Project context must expose generateRepoExpansionBrief.'], [context, 'archiveRepoExpansionBrief', 'Project context must expose archiveRepoExpansionBrief.'], [projectSearch, 'repoExpansionBriefItems', 'Search index must include repo expansion briefs.'], [model, 'export interface RepoBlueprint', 'RepoBlueprint model missing.'], [model, 'export interface RepoExpansionBrief', 'RepoExpansionBrief model missing.'], [model, 'repoBlueprints?: RepoBlueprint[]', 'Project model must persist repo blueprints.'], [model, 'repoExpansionBriefs?: RepoExpansionBrief[]', 'Project model must persist repo expansion briefs.'], [safeData, 'repoBlueprints: asArray(project.repoBlueprints)', 'Runtime normalization must preserve repo blueprints.'], [safeData, 'repoExpansionBriefs: asArray(project.repoExpansionBriefs)', 'Runtime normalization must preserve repo expansion briefs.'], [history, 'Repo Builder / foundation', 'History must surface foundation repo blueprint entries.'], [history, 'repoExpansionEntries', 'History must surface repo expansion brief entries.'], [read('src/shared/lib/buildLoop.ts'), 'getBuildLoopStatus', 'Repository shaping must retain technical build-loop guidance.'], [operatingStep, 'Nieuwe opdracht geven', 'Daily guidance must allow direct assignments.'], [operatingStep, 'activeWork', 'Daily guidance must account for active assignments.'], [operatingStep, 'attentionCount', 'Daily guidance must account for explicit human attention.'], [repoPage, 'Repository-deliverypakket', 'Repo Builder must expose delivery packages as the final repo handoff layer.'], [repoPage, 'Deliverypakket genereren', 'Repo Builder must generate Codex-ready delivery packages.'], [repoPage, 'File manifest', 'Repo delivery packages must show a file manifest.'], [repoPage, 'Validatieplan', 'Repo delivery packages must show a validation plan.'], [context, 'generateRepoDeliveryPackage', 'Project context must expose generateRepoDeliveryPackage.'], [context, 'archiveRepoDeliveryPackage', 'Project context must expose archiveRepoDeliveryPackage.'], [projectSearch, 'repoDeliveryPackageItems', 'Search index must include repo delivery packages.'], [model, 'export interface RepoDeliveryPackage', 'RepoDeliveryPackage model missing.'], [model, 'repoDeliveryPackages?: RepoDeliveryPackage[]', 'Project model must persist repo delivery packages.'], [safeData, 'repoDeliveryPackages: asArray(project.repoDeliveryPackages)', 'Runtime normalization must preserve repo delivery packages.'], [history, 'repoDeliveryPackageEntries', 'History must surface repo delivery package entries.'], [repoPage, 'Repositorywerkplan', 'Repo Builder must expose repo work plans as the sequencing layer.'], [repoPage, 'Werkplan genereren', 'Repo Builder must generate sequenced repo work plans.'], [repoPage, 'Aanbevolen volgende handoff', 'Repo work plans must show the next recommended handoff.'], [context, 'generateRepoWorkPlan', 'Project context must expose generateRepoWorkPlan.'], [context, 'archiveRepoWorkPlan', 'Project context must expose archiveRepoWorkPlan.'], [projectSearch, 'repoWorkPlanItems', 'Search index must include repo work plans.'], [model, 'export interface RepoWorkPlan', 'RepoWorkPlan model missing.'], [model, 'repoWorkPlans?: RepoWorkPlan[]', 'Project model must persist repo work plans.'], [safeData, 'repoWorkPlans: asArray(project.repoWorkPlans)', 'Runtime normalization must preserve repo work plans.'], [history, 'repoWorkPlanEntries', 'History must surface repo work plan entries.'], [repoPage, 'Repositorystatus', 'Repo Builder must expose repo state snapshots as the repository inventory layer.'], [repoPage, 'Repositorystatus vernieuwen', 'Repo Builder must let users refresh the repo state snapshot.'], [repoPage, 'Een afgeleide inventaris van bekende en geplande bestanden, geraakte gebieden, hiaten', 'Repo state snapshot must explain inventory, planned files, touched areas and gaps.'], [context, 'generateRepoStateSnapshot', 'Project context must expose generateRepoStateSnapshot.'], [context, 'archiveRepoStateSnapshot', 'Project context must expose archiveRepoStateSnapshot.'], [projectSearch, 'repoStateSnapshotItems', 'Search index must include repo state snapshots.'], [model, 'export interface RepoStateSnapshot', 'RepoStateSnapshot model missing.'], [model, 'repoStateSnapshots?: RepoStateSnapshot[]', 'Project model must persist repo state snapshots.'], [safeData, 'repoStateSnapshots: asArray(project.repoStateSnapshots)', 'Runtime normalization must preserve repo state snapshots.'], [history, 'repoStateSnapshotEntries', 'History must surface repo state snapshot entries.'], [repoPage, 'Skill set', 'Repo Builder must expose active project skills.'], [repoPage, 'formatSkillsForCodexHandoff', 'Repo Builder exports must include selected skill blocks.'], [context, 'skillIds', 'Repo generation must persist linked skill ids.'], [model, 'skillIds?: ID[]', 'Repo artifacts must support linked skill ids.'], [skills, 'getSkillGapsForRepoState', 'Repo state snapshots must be able to derive skill gaps.'], [repoPage, 'Bestaande repository inventariseren', 'Repo Builder must expose existing repository intake.'], [repoPage, 'ProjectBrain gebruikt dit als geïmporteerde informatie, niet als bewijs van de live-bestanden.', 'Repo Builder must separate imported repository evidence from live truth.'], [repoPage, 'Uitbreidingsbrief maken', 'Repo Builder must create expansion briefs from repository gaps.'], [repoPage, 'Deliverypakket maken', 'Repo Builder must create delivery packages from repository gaps.'], [repositoryIntake, 'deriveRepositoryGaps', 'Repository intake helper must derive repository gaps.'], [repositoryIntake, 'mapRepositoryEntriesToSkills', 'Repository intake helper must map imported files to Codex skills.'], [projectSearch, 'repositoryIntakeItems', 'Search index must include repository intakes.'], [context, 'linkedRepositoryIntakeIds', 'Repo artifacts must keep repository intake references.'], [model, 'export interface RepositoryIntake', 'RepositoryIntake model missing.'], [model, 'repositoryIntakes?: RepositoryIntake[]', 'Project model must persist repository intakes.'], [safeData, 'repositoryIntakes: asArray(project.repositoryIntakes)', 'Runtime normalization must preserve repository intakes.'], [history, 'repoIntakeEntries', 'History must surface repository intake entries.'], [pkg, 'audit:skills', 'package.json must expose audit:skills.'], [pkg, 'audit:repository-intake', 'package.json must expose audit:repository-intake.'], [repoPage, 'Codex-handoff maken', 'Repo Builder must create Codex handoffs from repo artifacts.'], [repoPage, 'Handoff vanuit werkplan maken', 'Repo Builder must create Codex handoffs from work plans.'], [repoPage, 'Handoff vanuit status maken', 'Repo Builder must create Codex handoffs from repo state snapshots.'], [repoPage, 'Controle van handoffs', 'Repo Builder must show handoff review status.'], [repoPage, 'impactcontroles', 'Repo Builder must show impact review count.'], [repoPage, 'feedbackitems', 'Repo Builder must show execution feedback count.'], [repoPage, 'Naar de buildloop', 'Repo Builder must link to Build Loop.'], [context, 'generateCodexHandoff', 'Project context must expose generateCodexHandoff.'], [context, 'generateHandoffReview', 'Project context must expose generateHandoffReview.'], [context, 'saveCodexExecutionFeedback', 'Project context must expose saveCodexExecutionFeedback.'], [model, 'export interface CodexHandoff', 'CodexHandoff model missing.'], [model, 'export interface HandoffReview', 'HandoffReview model missing.'], [model, 'export interface CodexExecutionFeedback', 'CodexExecutionFeedback model missing.'], [safeData, 'codexHandoffs: asArray(project.codexHandoffs)', 'Runtime normalization must preserve Codex handoffs.'], [safeData, 'handoffReviews: asArray(project.handoffReviews)', 'Runtime normalization must preserve handoff reviews.'], [safeData, 'codexExecutionFeedback: asArray(project.codexExecutionFeedback)', 'Runtime normalization must preserve execution feedback.'], [pkg, 'audit:handoffs', 'package.json must expose audit:handoffs.'], [pkg, 'audit:handoff-review', 'package.json must expose audit:handoff-review.'], [pkg, 'audit:execution-feedback', 'package.json must expose audit:execution-feedback.'], [pkg, 'audit:build-loop', 'package.json must expose audit:build-loop.'], [pkg, 'audit:repo-builder', 'package.json must expose audit:repo-builder.'], ]; for (const [haystack, needle, message] of mustContain) { if (!haystack.includes(needle)) failures.push(message); } if (!repoPage.includes('Open reviewitems blijven zichtbaar') || !repoPage.includes('alleen goedgekeurde invoer mag de uitvoering sturen') || !repoPage.includes('uiteindelijke overdrachtsgrens')) { failures.push('Repo Builder must communicate review-gated behavior, accepted input boundaries and the final delivery-package handoff boundary.'); } if (failures.length) { console.error('ProjectBrain repo builder readiness: FAIL'); for (const failure of failures) console.error(`- ${failure}`); process.exit(1); } console.log('ProjectBrain repo builder readiness: PASS');