#!/usr/bin/env node import { existsSync, readFileSync } from "node:fs"; const requiredFiles = [ "src/shared/lib/model.ts", "src/shared/lib/handoffReview.ts", "src/shared/lib/safeData.ts", "src/shared/contexts/ProjectContext.tsx", "src/features/handoffs/pages/CodexHandoffs.tsx", "src/features/execution-feedback/pages/ExecutionFeedback.tsx", "src/features/execution/pages/ExecutionCenter.tsx", "src/features/prompts/pages/PromptGenerator.tsx", "src/features/repo-builder/pages/RepoBuilder.tsx", "src/features/history/pages/ProjectHistory.tsx", "src/features/audit/pages/ProjectAuditCenter.tsx", "src/features/projects/pages/Workspace.tsx", "src/shared/lib/projectStartFlow.ts", "package.json", ]; const failures = []; for (const file of requiredFiles) { if (!existsSync(file)) failures.push(`Missing required file: ${file}`); } const read = (file) => readFileSync(file, "utf8"); const text = Object.fromEntries(requiredFiles.filter(existsSync).map((file) => [file, read(file)])); const model = text["src/shared/lib/model.ts"] ?? ""; const helper = text["src/shared/lib/handoffReview.ts"] ?? ""; const safeData = text["src/shared/lib/safeData.ts"] ?? ""; const context = text["src/shared/contexts/ProjectContext.tsx"] ?? ""; const handoffs = text["src/features/handoffs/pages/CodexHandoffs.tsx"] ?? ""; const feedbackPage = text["src/features/execution-feedback/pages/ExecutionFeedback.tsx"] ?? ""; const execution = text["src/features/execution/pages/ExecutionCenter.tsx"] ?? ""; const promptBuilder = text["src/features/prompts/pages/PromptGenerator.tsx"] ?? ""; const repoBuilder = text["src/features/repo-builder/pages/RepoBuilder.tsx"] ?? ""; const history = text["src/features/history/pages/ProjectHistory.tsx"] ?? ""; const audit = text["src/features/audit/pages/ProjectAuditCenter.tsx"] ?? ""; const workspace = text["src/features/projects/pages/Workspace.tsx"] ?? ""; const startFlow = text["src/shared/lib/projectStartFlow.ts"] ?? ""; const pkg = text["package.json"] ?? ""; const mustContain = [ [model, "export interface HandoffReview", "HandoffReview type missing."], [model, "export interface HandoffFileImpact", "HandoffFileImpact type missing."], [model, "export interface HandoffImpactRisk", "HandoffImpactRisk type missing."], [model, "export interface HandoffValidationCoverage", "HandoffValidationCoverage type missing."], [model, "export type HandoffReviewDecision", "HandoffReviewDecision type missing."], [model, "HandoffSimulationSource", "HandoffSimulationSource type missing."], [model, "handoffReviews?: HandoffReview[]", "Project model must persist handoff reviews."], [safeData, "handoffReviews: asArray(project.handoffReviews)", "Runtime normalization must preserve handoff reviews."], [helper, "generateHandoffReview", "handoffReview helper must generate reviews."], [helper, "simulateFileImpacts", "handoffReview helper must simulate file impacts."], [helper, "classifyHandoffFileAction", "handoffReview helper must classify file actions."], [helper, "scoreFileImpactRisk", "handoffReview helper must score file impact risk."], [helper, "buildValidationCoverage", "handoffReview helper must build validation coverage."], [helper, "buildRollbackCoverage", "handoffReview helper must build rollback coverage."], [helper, "getMissingSafeguards", "handoffReview helper must list missing safeguards."], [helper, "recommendHandoffReviewDecision", "handoffReview helper must recommend decisions."], [helper, "formatHandoffReviewMarkdown", "handoffReview helper must format markdown."], [helper, "not a live git diff", "Review helper must label simulation boundary."], [context, "generateHandoffReview", "ProjectContext must expose generateHandoffReview."], [context, "updateHandoffReviewDecision", "ProjectContext must update review decisions."], [context, "archiveHandoffReview", "ProjectContext must archive handoff reviews."], [context, "handoffReviewItems", "Project search must index handoff reviews."], [handoffs, "Generate impact review", "Codex Handoffs page must generate impact reviews."], [handoffs, "Create session pack", "Codex Handoffs page must create session packs after review."], [handoffs, "Refresh impact review", "Codex Handoffs page must refresh impact reviews."], [handoffs, "Copy review", "Codex Handoffs page must copy reviews."], [handoffs, "Download review", "Codex Handoffs page must download reviews."], [handoffs, "ProjectBrain-derived impact simulation, not a live git diff", "Codex Handoffs page must show simulation boundary."], [handoffs, "simulatedFileImpacts", "Codex Handoffs page must show simulated file impacts."], [handoffs, "missingSafeguards", "Codex Handoffs page must show missing safeguards."], [handoffs, "recommendedReviewDecision", "Codex Handoffs page must show recommended decision."], [feedbackPage, "Linked handoff", "Execution Feedback must link feedback to handoffs/reviews."], [execution, "Review impact", "Execution Center must show review impact action."], [execution, "Codex Session Pack", "Execution Center must show session pack handoff boundary."], [execution, "Recommended to approve the impact review before executing this prompt", "Execution Center must warn before unapproved execution."], [promptBuilder, "Pre-execution impact review", "Prompt Builder must include pre-execution review summary."], [promptBuilder, "missingSafeguards", "Prompt Builder must include missing safeguards."], [repoBuilder, "Handoff review status", "Repo Builder must show handoff review status."], [history, 'kind: "handoffReview"', "Project History must include handoff review records."], [history, 'kind: "sessionPack"', "Project History must include session pack records."], [audit, "Handoff review simulation", "Audit Center must show handoff review coverage."], [audit, "Codex session pack readiness", "Audit Center must show session pack readiness."], [workspace, "handoffsWithoutReview", "Workspace must detect handoffs without review."], [workspace, "fix safeguards", "Workspace must expose safeguard-fix next action."], [startFlow, "review-handoff-impact", "Project next actions must review handoff impact."], [startFlow, "fix-handoff-safeguards", "Project next actions must fix handoff safeguards."], [startFlow, "execute-approved-handoff", "Project next actions must execute approved handoffs."], [pkg, "audit:handoff-review", "package.json must expose audit:handoff-review."], [pkg, "check-handoff-review-readiness.mjs", "package.json must wire handoff review readiness script."], ]; for (const [haystack, needle, message] of mustContain) { if (!haystack.includes(needle)) failures.push(message); } if (!pkg.includes("audit:handoff-review") || !pkg.includes("audit:all")) { failures.push("audit:all must include the handoff review readiness check."); } if (failures.length) { console.error("ProjectBrain handoff review readiness: FAIL"); for (const failure of failures) console.error(`- ${failure}`); process.exit(1); } console.log("ProjectBrain handoff review readiness: PASS");