#!/usr/bin/env node import { existsSync, readFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; const root = dirname(dirname(fileURLToPath(import.meta.url))); const failures = []; const warnings = []; const requiredFiles = [ 'src/features/projects/pages/RuntimeReadiness.tsx', 'src/shared/hooks/useAsyncResource.ts', 'src/shared/hooks/useProjectData.ts', 'src/shared/api/realClient.ts', 'docs/RUNTIME_ROUND_1_REAL_MODE_PILOT.md', 'docs/RUNTIME_ROUND_2_REAL_READ_PILOT.md', 'docs/RUNTIME_ROUND_3_REAL_READ_PILOT.md', 'backend/scripts/smoke-real-read-pilot.mjs', 'backend/scripts/smoke-vertical-slice.mjs', 'docs/RUNTIME_ROUND_4_VERTICAL_SLICE_SMOKE.md', 'docs/P2_LOCAL_RUNTIME_VERIFICATION.md', 'docs/RUNTIME_ROUND_5_BACKEND_HEALTH_AND_SUITE.md', 'backend/scripts/smoke-runtime-suite.mjs', 'src/features/operations/lib/operationRuntime.ts', 'src/features/operations/pages/RuntimeStateManager.tsx', 'docs/RUNTIME_ROUND_7_SHARED_LOCAL_OPERATING_STATE.md', 'docs/RUNTIME_ROUND_8_LOCAL_RUNTIME_PORTABILITY.md', 'docs/RUNTIME_ROUND_10_LOCAL_TRUTH_LEDGER.md', 'src/features/operations/pages/RuntimeTruthLedger.tsx', 'src/features/operations/pages/RuntimeHandoffBuilder.tsx', 'docs/RUNTIME_ROUND_11_HANDOFF_BUNDLES.md', 'src/features/operations/pages/RuntimeFlowProgress.tsx', 'docs/RUNTIME_ROUND_12_FLOW_PROGRESS_AND_CODEX_HANDOFF.md', 'docs/RUNTIME_ROUND_13_GUIDED_VERTICAL_SLICE_RUNNER.md', 'src/features/operations/pages/RuntimeMissionControl.tsx', 'docs/RUNTIME_ROUND_14_MISSION_CONTROL.md', 'src/features/operations/pages/RuntimeTraceInspector.tsx', 'docs/RUNTIME_ROUND_15_TRACE_INSPECTOR.md', 'src/features/operations/pages/RuntimeTodoBoard.tsx', 'docs/RUNTIME_ROUND_16_TODO_BOARD.md', 'src/features/operations/pages/RuntimeDeliveryPlan.tsx', 'docs/RUNTIME_ROUND_17_DELIVERY_PLAN.md', 'src/features/operations/pages/RuntimeExecutionQueue.tsx', 'docs/RUNTIME_ROUND_18_EXECUTION_QUEUE.md', 'src/features/operations/pages/RuntimeGateChecklist.tsx', 'src/features/operations/pages/RuntimeGateEvidence.tsx', 'docs/RUNTIME_ROUND_19_P2_GATE_CHECKLIST.md', 'docs/RUNTIME_ROUND_20_P2_SMOKE_EVIDENCE.md', 'src/features/operations/pages/RuntimeP3ReadinessAdvisor.tsx', 'docs/RUNTIME_ROUND_21_P3_READINESS_ADVISOR.md', 'src/features/operations/pages/RuntimeP3ImplementationPlanner.tsx', 'docs/RUNTIME_ROUND_22_P3_IMPLEMENTATION_PLANNER.md', 'src/features/operations/pages/RuntimeWorkSessionPanel.tsx', 'docs/RUNTIME_ROUND_23_WORK_SESSIONS.md', 'docs/RUNTIME_ROUND_24_REAL_MODE_FEATURE_DETAIL_PILOT.md', 'docs/STABILIZATION_PASS_V37.md', 'src/features/operations/pages/RuntimeContextPromptPilot.tsx', 'docs/RUNTIME_ROUND_25_CONTEXT_PROMPT_REAL_PILOT.md', 'docs/STABILIZATION_PASS_V38.md', 'src/features/operations/pages/RuntimeProjectUpdates.tsx', 'docs/RUNTIME_ROUND_26_PROJECT_UPDATE_MATERIALIZATION.md', 'docs/STABILIZATION_PASS_V39.md', 'src/features/operations/pages/RuntimeFeatureOverlay.tsx', 'docs/RUNTIME_ROUND_27_FEATURE_MAP_OVERLAY.md', 'docs/STABILIZATION_PASS_V40.md', 'docs/RUNTIME_ROUND_28_CAPTURE_REVIEW_REAL_PILOT.md', 'docs/STABILIZATION_PASS_V43.md', 'docs/PERSISTENCE_P6_TRUTH_UPDATES_OPERATING_LOG.md', 'docs/STABILIZATION_PASS_V44_P6_TRUTH_UPDATES_LOG.md', 'backend/scripts/smoke-p6.mjs', 'src/features/operations/pages/RuntimePersistencePilot.tsx', 'docs/RUNTIME_ROUND_29_P6_FRONTEND_PERSISTENCE_PILOT.md', 'docs/STABILIZATION_PASS_V45.md', 'src/features/operations/pages/RuntimeDeliveryPersistencePilot.tsx', 'docs/PERSISTENCE_P7_CURRENT_STATE_HANDOFF_CODEX.md', 'docs/RUNTIME_ROUND_30_P7_DELIVERY_PERSISTENCE_PILOT.md', 'docs/STABILIZATION_PASS_V46_P7_DELIVERY_PERSISTENCE.md', 'backend/scripts/smoke-p7.mjs', 'backend/scripts/smoke-p8.mjs', 'src/features/operations/pages/RuntimeKnowledgePersistencePilot.tsx', 'docs/PERSISTENCE_P8_DOCUMENTATION_KNOWLEDGE_MEMORY.md', 'docs/RUNTIME_ROUND_31_P8_KNOWLEDGE_PERSISTENCE_PILOT.md', 'docs/STABILIZATION_PASS_V47_P8_KNOWLEDGE_MEMORY_BRANDING.md', ]; for (const file of requiredFiles) { if (!existsSync(join(root, file))) failures.push(`Missing runtime-readiness file: ${file}`); } const routeFile = join(root, 'src/app/routes.tsx'); if (existsSync(routeFile)) { const routes = readFileSync(routeFile, 'utf8'); if (!routes.includes('/projects/:projectId/runtime')) failures.push('Runtime readiness route is not registered.'); } else { failures.push('Missing src/app/routes.tsx'); } const runtimeReadinessFile = join(root, 'src/features/projects/pages/RuntimeReadiness.tsx'); if (existsSync(runtimeReadinessFile)) { const runtimeReadiness = readFileSync(runtimeReadinessFile, 'utf8'); for (const marker of ['Tower deployment runbook', 'Deployment update path', 'git pull --ff-only', 'scripts/deploy-unraid-single.sh', 'Configurable public URL']) { if (!runtimeReadiness.includes(marker)) warnings.push(`RuntimeReadiness missing deployment runbook marker: ${marker}`); } } const sidebarFile = join(root, 'src/components/layout/Sidebar.tsx'); if (existsSync(sidebarFile)) { const sidebar = readFileSync(sidebarFile, 'utf8'); const navigationFile = join(root, 'src/shared/lib/navigation.tsx'); const navigation = existsSync(navigationFile) ? readFileSync(navigationFile, 'utf8') : ''; if (!sidebar.includes('/runtime') && !navigation.includes('/runtime')) warnings.push('Navigation does not expose Runtime Readiness.'); } else { failures.push('Missing Sidebar.tsx'); } const realClientFile = join(root, 'src/shared/api/realClient.ts'); if (existsSync(realClientFile)) { const realClient = readFileSync(realClientFile, 'utf8'); for (const marker of ['health: healthApi', 'unwrapPaginatedItems', 'unwrapWorkspaceState', 'mapBackendFeature', 'mapBackendEvidence', 'listFeatures', 'listEvidence', 'listEvidenceForFeature', 'listContextPacks', 'listChecks', 'listBuildRuns', 'listSnapshots', 'listKnowledge', 'listCaptureItems', 'createCaptureItem', 'classifyCaptureItem', 'sendCaptureToReview', 'listReviewItems', 'acceptReviewItem', 'convertReviewItem', 'listActions', 'runtimePersistence', 'listAcceptedTruth', 'materializeReviewItemAsTruth', 'listProjectUpdates', 'createProjectUpdateFromTruth', 'applyProjectUpdate', 'listOperatingLog', 'createOperatingLogEntry', 'runtimeV7', 'listCurrentStateReports', 'generateCurrentStateReport', 'listHandoffBundles', 'createHandoffBundle', 'listCodexTasks', 'createCodexTaskFromHandoff', 'importCodexOutput', 'createKnowledge', 'updateKnowledge', 'createMemoryRule', 'updateMemoryRule', 'listDocumentationItems', 'createDocumentationItem', 'updateDocumentationItem']) { if (!realClient.includes(marker)) warnings.push(`realClient missing expected marker: ${marker}`); } } const projectDataHooksFile = join(root, 'src/shared/hooks/useProjectData.ts'); if (existsSync(projectDataHooksFile)) { const hooks = readFileSync(projectDataHooksFile, 'utf8'); for (const marker of ['useBackendHealthData', 'useProjectFeatureGroupsData', 'useProjectFeaturesData', 'useProjectFeatureDetailData', 'useProjectEvidenceData', 'useFeatureEvidenceData', 'useProjectContextPacksData', 'useProjectChecksData', 'useProjectBuildRunsData', 'useProjectSnapshotsData', 'useProjectKnowledgeData', 'useProjectDocumentationItemsData', 'useProjectCaptureItemsData', 'useProjectReviewQueueData', 'useProjectAcceptedTruthData', 'useProjectProjectUpdatesData', 'useProjectOperatingLogData', 'useProjectCurrentStateReportsData', 'useProjectHandoffBundlesData', 'useProjectCodexTasksData', 'useProjectAIActionsData']) { if (!hooks.includes(marker)) warnings.push(`useProjectData missing expected runtime hook: ${marker}`); } } else { failures.push('Missing src/shared/hooks/useProjectData.ts'); } const featureMapFile = join(root, 'src/features/features/pages/FeatureMap.tsx'); if (existsSync(featureMapFile)) { const featureMap = readFileSync(featureMapFile, 'utf8'); for (const marker of ['Feature data source', 'useProjectFeatureGroupsData', 'Reload features', 'RuntimeFeatureOverlay']) { if (!featureMap.includes(marker)) warnings.push(`FeatureMap missing real-mode pilot marker: ${marker}`); } } const featureDetailFile = join(root, 'src/features/features/pages/FeatureDetail.tsx'); if (existsSync(featureDetailFile)) { const featureDetail = readFileSync(featureDetailFile, 'utf8'); for (const marker of ['Feature detail data source', 'useProjectFeatureDetailData', 'useFeatureEvidenceData', 'Reload detail']) { if (!featureDetail.includes(marker)) warnings.push(`FeatureDetail missing real-mode pilot marker: ${marker}`); } } const operationRuntimeFile = join(root, 'src/features/operations/lib/operationRuntime.ts'); if (existsSync(operationRuntimeFile)) { const runtime = readFileSync(operationRuntimeFile, 'utf8'); for (const marker of ['exportRuntime', 'exportRuntimeMarkdown', 'importRuntime', 'sendCaptureToReview', 'truthItems', 'RuntimeTruthItem', 'RuntimeHandoffBundle', 'createHandoffBundle', 'handoffBundles', 'runGuidedVerticalSlice', 'runtimeTraceRows', 'exportRuntimeTraceMarkdown', 'RuntimeTodoItem', 'todoItems', 'addTodo', 'toggleTodo', 'createTodosFromPendingReviews', 'exportTodoMarkdown', 'RuntimeDeliveryGate', 'runtimeDeliveryGates', 'createTodosFromTraceGaps', 'createTodosFromDeliveryGaps', 'completeDeliveryGate', 'exportDeliveryPlanMarkdown', 'RuntimeWorkSession', 'workSessions', 'startWorkSession', 'completeWorkSession', 'exportWorkSessionMarkdown', 'RuntimeProjectUpdate', 'projectUpdates', 'materializeAcceptedTruth', 'applyProjectUpdate', 'exportProjectUpdatesMarkdown']) { if (!runtime.includes(marker)) warnings.push(`operationRuntime missing expected portability marker: ${marker}`); } } const truthLedgerFile = join(root, 'src/features/operations/pages/RuntimeTruthLedger.tsx'); if (existsSync(truthLedgerFile)) { const ledger = readFileSync(truthLedgerFile, 'utf8'); for (const marker of ['Export truth markdown', 'Create context handoff', 'Create Codex handoff']) { if (!ledger.includes(marker)) warnings.push(`RuntimeTruthLedger missing expected control: ${marker}`); } } const codexPreviewFile = join(root, 'src/features/operations/pages/CodexTaskPreview.tsx'); if (existsSync(codexPreviewFile)) { const codex = readFileSync(codexPreviewFile, 'utf8'); for (const marker of ['Create runtime handoff', 'Runtime handoff attached', 'Runtime Handoff Context']) { if (!codex.includes(marker)) warnings.push(`CodexTaskPreview missing expected runtime-handoff marker: ${marker}`); } } const runtimeStateManagerFile = join(root, 'src/features/operations/pages/RuntimeStateManager.tsx'); if (existsSync(runtimeStateManagerFile)) { const manager = readFileSync(runtimeStateManagerFile, 'utf8'); for (const marker of ['Export JSON', 'Export Markdown', 'Import JSON', 'Reset local runtime', 'Handoffs']) { if (!manager.includes(marker)) warnings.push(`RuntimeStateManager missing expected control: ${marker}`); } } const missionControlFile = join(root, 'src/features/operations/pages/RuntimeMissionControl.tsx'); if (existsSync(missionControlFile)) { const mission = readFileSync(missionControlFile, 'utf8'); for (const marker of ['Runtime Mission Control', 'Run full local flow', 'Create Codex handoff', 'Copy mission markdown', 'Import Codex output preview']) { if (!mission.includes(marker)) warnings.push(`RuntimeMissionControl missing expected marker: ${marker}`); } } const traceInspectorFile = join(root, 'src/features/operations/pages/RuntimeTraceInspector.tsx'); if (existsSync(traceInspectorFile)) { const trace = readFileSync(traceInspectorFile, 'utf8'); for (const marker of ['Runtime Trace Inspector', 'Seed trace example', 'Copy trace markdown', 'Create trace handoff']) { if (!trace.includes(marker)) warnings.push(`RuntimeTraceInspector missing expected marker: ${marker}`); } } const todoBoardFile = join(root, 'src/features/operations/pages/RuntimeTodoBoard.tsx'); if (existsSync(todoBoardFile)) { const todoBoard = readFileSync(todoBoardFile, 'utf8'); for (const marker of ['Runtime Todo Board', 'Create todos from reviews', 'Export todo markdown', 'Add manual todo']) { if (!todoBoard.includes(marker)) warnings.push(`RuntimeTodoBoard missing expected marker: ${marker}`); } } const executionQueueFile = join(root, 'src/features/operations/pages/RuntimeExecutionQueue.tsx'); if (existsSync(executionQueueFile)) { const execution = readFileSync(executionQueueFile, 'utf8'); for (const marker of ['Runtime Execution Queue', 'Prepare execution burst', 'Mark top todo done', 'Export execution queue', 'Create execution handoff']) { if (!execution.includes(marker)) warnings.push(`RuntimeExecutionQueue missing expected marker: ${marker}`); } } const deliveryPlanFile = join(root, 'src/features/operations/pages/RuntimeDeliveryPlan.tsx'); if (existsSync(deliveryPlanFile)) { const delivery = readFileSync(deliveryPlanFile, 'utf8'); for (const marker of ['Runtime Delivery Plan', 'Create gate todos', 'Create trace-gap todos', 'Export delivery plan']) { if (!delivery.includes(marker)) warnings.push(`RuntimeDeliveryPlan missing expected marker: ${marker}`); } } const flowProgressFile = join(root, 'src/features/operations/pages/RuntimeFlowProgress.tsx'); if (existsSync(flowProgressFile)) { const flow = readFileSync(flowProgressFile, 'utf8'); for (const marker of ['Runtime Vertical Slice Progress', 'Create suggested handoff', 'Run guided local slice', 'Next best runtime step']) { if (!flow.includes(marker)) warnings.push(`RuntimeFlowProgress missing expected marker: ${marker}`); } } const handoffBuilderFile = join(root, 'src/features/operations/pages/RuntimeHandoffBuilder.tsx'); if (existsSync(handoffBuilderFile)) { const builder = readFileSync(handoffBuilderFile, 'utf8'); for (const marker of ['Create handoff bundle', 'Copy latest markdown', 'Send latest to Review Queue']) { if (!builder.includes(marker)) warnings.push(`RuntimeHandoffBuilder missing expected control: ${marker}`); } } const gateChecklistFile = join(root, 'src/features/operations/pages/RuntimeGateChecklist.tsx'); if (existsSync(gateChecklistFile)) { const gate = readFileSync(gateChecklistFile, 'utf8'); for (const marker of ['P2 Database Gate Checklist', 'Copy commands', 'Create todos for incomplete steps', 'Mark gate complete']) { if (!gate.includes(marker)) warnings.push(`RuntimeGateChecklist missing expected marker: ${marker}`); } } const gateEvidenceFile = join(root, 'src/features/operations/pages/RuntimeGateEvidence.tsx'); if (existsSync(gateEvidenceFile)) { const evidence = readFileSync(gateEvidenceFile, 'utf8'); for (const marker of ['P2 Smoke Evidence Recorder', 'Save evidence', 'Export evidence', 'Evidence history']) { if (!evidence.includes(marker)) warnings.push(`RuntimeGateEvidence missing expected marker: ${marker}`); } } const p3AdvisorFile = join(root, 'src/features/operations/pages/RuntimeP3ReadinessAdvisor.tsx'); if (existsSync(p3AdvisorFile)) { const p3 = readFileSync(p3AdvisorFile, 'utf8'); for (const marker of ['Feature/Evidence parity proof', 'Create parity proof todos', 'Create parity handoff', 'Export readiness', 'Mark P2 gate complete']) { if (!p3.includes(marker)) warnings.push(`RuntimeP3ReadinessAdvisor missing expected marker: ${marker}`); } } const workSessionFile = join(root, 'src/features/operations/pages/RuntimeWorkSessionPanel.tsx'); if (existsSync(workSessionFile)) { const sessions = readFileSync(workSessionFile, 'utf8'); for (const marker of ['Runtime Work Sessions', 'Start next work session', 'Complete active session', 'Export sessions']) { if (!sessions.includes(marker)) warnings.push(`RuntimeWorkSessionPanel missing expected marker: ${marker}`); } } const projectUpdatesFile = join(root, 'src/features/operations/pages/RuntimeProjectUpdates.tsx'); if (existsSync(projectUpdatesFile)) { const updates = readFileSync(projectUpdatesFile, 'utf8'); for (const marker of ['Runtime Project Updates', 'Prepare from truth', 'Apply ready', 'Export updates']) { if (!updates.includes(marker)) warnings.push(`RuntimeProjectUpdates missing expected marker: ${marker}`); } } const runtimePersistencePilotFile = join(root, 'src/features/operations/pages/RuntimePersistencePilot.tsx'); if (existsSync(runtimePersistencePilotFile)) { const pilot = readFileSync(runtimePersistencePilotFile, 'utf8'); for (const marker of ['Runtime Persistence Pilot', 'Materialize truth', 'Prepare updates', 'Apply ready', 'Add log note', 'realClient.runtimePersistence']) { if (!pilot.includes(marker)) warnings.push(`RuntimePersistencePilot missing expected marker: ${marker}`); } } else { warnings.push('Missing RuntimePersistencePilot component.'); } const runtimeDeliveryPersistencePilotFile = join(root, 'src/features/operations/pages/RuntimeDeliveryPersistencePilot.tsx'); if (existsSync(runtimeDeliveryPersistencePilotFile)) { const pilot = readFileSync(runtimeDeliveryPersistencePilotFile, 'utf8'); for (const marker of ['Runtime Delivery Persistence Pilot', 'Generate Current State', 'Create Handoff', 'Create Codex Task', 'Import Codex Output', 'realClient.runtimeV7']) { if (!pilot.includes(marker)) warnings.push(`RuntimeDeliveryPersistencePilot missing expected marker: ${marker}`); } } else { warnings.push('Missing RuntimeDeliveryPersistencePilot component.'); } const runtimeFeatureOverlayFile = join(root, 'src/features/operations/pages/RuntimeFeatureOverlay.tsx'); if (existsSync(runtimeFeatureOverlayFile)) { const overlay = readFileSync(runtimeFeatureOverlayFile, 'utf8'); for (const marker of ['Runtime Feature Overlay', 'Prepare updates', 'Apply ready', 'Create handoff', 'Export']) { if (!overlay.includes(marker)) warnings.push(`RuntimeFeatureOverlay missing expected marker: ${marker}`); } } const packageFile = join(root, 'package.json'); if (existsSync(packageFile)) { const pkg = readFileSync(packageFile, 'utf8'); if (!pkg.includes('smoke:backend:real-read-pilot')) warnings.push('Root package is missing smoke:backend:real-read-pilot script.'); if (!pkg.includes('smoke:backend:vertical-slice')) warnings.push('Root package is missing smoke:backend:vertical-slice script.'); if (!pkg.includes('smoke:backend:runtime-suite')) warnings.push('Root package is missing smoke:backend:runtime-suite script.'); } console.log('ProjectBrain runtime readiness check'); console.log('===================================='); if (warnings.length) { console.log('\nWarnings:'); for (const warning of warnings) console.log(`- ${warning}`); } const p3ImplementationPlannerFile = join(root, 'src/features/operations/pages/RuntimeP3ImplementationPlanner.tsx'); if (existsSync(p3ImplementationPlannerFile)) { const planner = readFileSync(p3ImplementationPlannerFile, 'utf8'); for (const marker of ['Feature/Evidence parity reference', 'Create parity todos', 'Create parity handoff', 'Export parity plan']) { if (!planner.includes(marker)) warnings.push(`RuntimeP3ImplementationPlanner missing expected marker: ${marker}`); } } const contextPromptPilotFile = join(root, 'src/features/operations/pages/RuntimeContextPromptPilot.tsx'); if (existsSync(contextPromptPilotFile)) { const pilot = readFileSync(contextPromptPilotFile, 'utf8'); for (const marker of ['Runtime Context -> Prompt Pilot', 'Generate runtime prompt', 'realClient.prompts.generatePromptFromContextPack', 'useProjectContextPacksData']) { if (!pilot.includes(marker)) warnings.push(`RuntimeContextPromptPilot missing expected marker: ${marker}`); } } const promptGeneratorFile = join(root, 'src/features/prompts/pages/PromptGenerator.tsx'); if (existsSync(promptGeneratorFile)) { const prompt = readFileSync(promptGeneratorFile, 'utf8'); for (const marker of ['Prompt data source', 'realClient.prompts.generatePromptFromContextPack', 'useProjectContextPacksData']) { if (!prompt.includes(marker)) warnings.push(`PromptGenerator missing real prompt marker: ${marker}`); } } const contextPacksPageFile = join(root, 'src/features/context-packs/pages/ContextPacks.tsx'); if (existsSync(contextPacksPageFile)) { const packs = readFileSync(contextPacksPageFile, 'utf8'); for (const marker of ['Context pack data source', 'useProjectContextPacksData', 'Fastify R4 read endpoint']) { if (!packs.includes(marker)) warnings.push(`ContextPacks missing real context-pack marker: ${marker}`); } } const captureCenterFile = join(root, 'src/features/operations/pages/CaptureCenter.tsx'); if (existsSync(captureCenterFile)) { const captureCenter = readFileSync(captureCenterFile, 'utf8'); for (const marker of ['Capture data source', 'Real API pilot', 'createCaptureItem', 'classifyCaptureItem', 'sendCaptureToReview']) { if (!captureCenter.includes(marker)) warnings.push(`CaptureCenter missing real API pilot marker: ${marker}`); } } const reviewQueueFile = join(root, 'src/features/operations/pages/ReviewQueue.tsx'); if (existsSync(reviewQueueFile)) { const reviewQueue = readFileSync(reviewQueueFile, 'utf8'); for (const marker of ['Review Queue data source', 'Real API pilot', 'acceptReviewItem', 'convertReviewItem', 'mergeReviewItem']) { if (!reviewQueue.includes(marker)) warnings.push(`ReviewQueue missing real API pilot marker: ${marker}`); } } const backendPackageFile = join(root, 'backend/package.json'); if (existsSync(backendPackageFile)) { const backendPackage = readFileSync(backendPackageFile, 'utf8'); for (const marker of ['smoke:p6', 'smoke-p6.mjs', 'smoke:p7', 'smoke-p7.mjs']) { if (!backendPackage.includes(marker)) warnings.push(`backend package missing P6 marker: ${marker}`); } } const runtimePersistenceRouteFile = join(root, 'backend/src/routes/runtimePersistence.ts'); if (existsSync(runtimePersistenceRouteFile)) { const runtimePersistence = readFileSync(runtimePersistenceRouteFile, 'utf8'); for (const marker of ['accepted-truth', 'project-updates', 'operating-log', 'materialize-truth']) { if (!runtimePersistence.includes(marker)) warnings.push(`runtimePersistence route missing P6 marker: ${marker}`); } } else { warnings.push('Missing P6 runtimePersistence route file.'); } const p7RuntimeRouteFile = join(root, 'backend/src/routes/p7Runtime.ts'); if (existsSync(p7RuntimeRouteFile)) { const p7Runtime = readFileSync(p7RuntimeRouteFile, 'utf8'); for (const marker of ['current-state', 'handoff-bundles', 'codex-tasks', 'import-output']) { if (!p7Runtime.includes(marker)) warnings.push(`p7Runtime route missing P7 marker: ${marker}`); } } else { warnings.push('Missing P7 p7Runtime route file.'); } const knowledgePilotFile = join(root, 'src/features/operations/pages/RuntimeKnowledgePersistencePilot.tsx'); if (existsSync(knowledgePilotFile)) { const pilot = readFileSync(knowledgePilotFile, 'utf8'); for (const marker of ['Runtime Knowledge Persistence Pilot', 'Persist documentation', 'Persist knowledge', 'Persist memory rule']) { if (!pilot.includes(marker)) warnings.push(`RuntimeKnowledgePersistencePilot missing expected marker: ${marker}`); } } else { failures.push('Missing RuntimeKnowledgePersistencePilot.tsx'); } if (failures.length) { console.log('\nFailures:'); for (const failure of failures) console.log(`- ${failure}`); process.exit(1); } console.log('\nPASS: runtime readiness scaffolding is present.');