import { readFile } from 'node:fs/promises'; import { readCampaignFlowSegments } from './campaign-flow-segments.mjs'; const { routes, segments, manifestHash } = await readCampaignFlowSegments(); const flowSource = await readFile(new URL('./verify-flow.mjs', import.meta.url), 'utf8'); const packageJson = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8')); assert(segments.length === 12, `Expected 12 campaign flow segments, received ${segments.length}.`); assert(routes.length === 66, `Expected 66 campaign battle routes, received ${routes.length}.`); assert(/^[a-f0-9]{64}$/.test(manifestHash), `Expected a SHA-256 flow manifest hash, received ${manifestHash}.`); const flattenedBattleIds = segments.flatMap(({ battleIds }) => battleIds); assert( JSON.stringify(flattenedBattleIds) === JSON.stringify(routes.map(({ battleId }) => battleId)), 'Campaign flow segments must preserve the canonical 66-battle route order.' ); const specialCheckpointSteps = { 'hanzhong-shuhan': 'shu-han-foundation-camp', 'yiling-baidi': 'baidi-entrustment-camp', nanzhong: 'northern-campaign-prep-camp', northern: 'ending-complete' }; for (const segment of segments) { assert(segment.index === segments.indexOf(segment), `Flow segment ${segment.id} has an invalid index.`); assert( countOccurrences(flowSource, `shouldRunFlowSegment('${segment.id}')`) === 1, `Flow segment ${segment.id} must have exactly one executable body boundary.` ); assert( countOccurrences(flowSource, `completeFlowSegment(page, '${segment.id}')`) === 1, `Flow segment ${segment.id} must have exactly one completion checkpoint.` ); const specialStep = specialCheckpointSteps[segment.id]; if (specialStep) { assert( segment.checkpointStep === specialStep, `Flow segment ${segment.id} must end at ${specialStep}, received ${segment.checkpointStep}.` ); } } assert( packageJson.scripts?.['verify:flow'] === 'node scripts/verify-flow-segments.mjs', 'The default verify:flow command must use the segmented orchestrator.' ); assert( packageJson.scripts?.['verify:flow:monolith'] === 'node scripts/verify-flow.mjs', 'The legacy monolith flow command must remain available for comparison.' ); console.log(`Verified ${segments.length} campaign flow segments across ${routes.length} ordered battles (${manifestHash.slice(0, 12)}).`); function countOccurrences(source, needle) { return source.split(needle).length - 1; } function assert(condition, message) { if (!condition) { throw new Error(message); } }