12// Bundled-world CI gate. Keep this deliberately sequential: a proof's solver3// budget is the authored resource limit, and running several large frontiers4// at once hides memory regressions.5import { readFileSync } from 'node:fs';6import { resolve } from 'node:path';7import { levels as coreLevels } from '../src/levels.js';8import { loadMod } from '../src/mods.js';9import { checkLevel } from '../src/solver/check-level.js';1011const root = resolve(new URL('..', import.meta.url).pathname);12const packs = [13 { manifest: { id: 'core', name: 'Miau core' }, levels: coreLevels },14 ...['crossword', 'crate-works', 'tidewater', 'clockwork'].map(id => {15 const filename = resolve(root, `mods/worlds/${id}.cjs`);16 return loadMod(readFileSync(filename, 'utf8'), { filename });17 }),18];1920let failures = 0;21for (const pack of packs) {22 console.log(`${pack.manifest.name} (${pack.manifest.id}), ${pack.levels.length} levels`);23 for (const level of pack.levels) {24 const checked = checkLevel(level);25 const result = checked.checks.result;26 const details = result.status === 'SOLVED'27 ? `${result.path.length} steps ${result.path}`28 : `after ${result.explored} states`;29 const suffix = [30 ...checked.issues.map(issue => `ERROR: ${issue}`),31 ...checked.warnings.map(warning => `WARNING: ${warning}`),32 ].join(' ');33 console.log(` ${level.id.padEnd(28)} ${result.status.padEnd(8)} ${details}${suffix ? ` ${suffix}` : ''}`);34 if (!checked.ok) failures++;35 }36}3738if (failures) {39 console.error(`Bundled-world check failed: ${failures} level${failures === 1 ? '' : 's'}`);40 process.exitCode = 1;41} else {42 console.log('Bundled-world check passed');43}