Files
projectbrain-Public/scripts/check-repo-builder-readiness.mjs

157 lines
12 KiB
JavaScript

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');