Files
Web_FreeCAD_Bitbybit/scripts/check-freecad-naming-next-tasks.mjs
wangdequan f64b78865c
Some checks failed
real-verification / chrome (push) Has been cancelled
real-verification / freecad-oracle (push) Has been cancelled
real-verification / wasm (push) Has been cancelled
feat: complete production naming and reference lifecycle gates
2026-08-14 10:10:30 -04:00

23 lines
2.9 KiB
JavaScript

import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const packageJson = JSON.parse(await readFile(resolve(root, 'package.json'), 'utf8'))
const plan = JSON.parse(await readFile(resolve(root, 'config/freecad-naming-next-tasks.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD naming next tasks: ${message}`) }
const expectedIds = ['SDK-01', 'SDK-02A', 'SDK-02B', 'SDK-04', 'SDK-03', 'SDK-05', 'PAR-01', 'QA-01']
if (plan.schemaVersion !== 1 || plan.scope !== 'freecad-private-naming-and-parameter-followup') fail('unsupported schema or scope.')
if (JSON.stringify(plan.orderedTasks?.map(({ id }) => id)) !== JSON.stringify(expectedIds)) fail('ordered task list is incomplete or reordered.')
const taskById = new Map(plan.orderedTasks.map((task) => [task.id, task]))
for (const task of plan.orderedTasks) {
if (!['pending', 'in_progress', 'completed'].includes(task.status)) fail(`${task.id} has an invalid status.`)
if (!Array.isArray(task.deliverables) || !task.deliverables.length || !Array.isArray(task.acceptance) || !task.acceptance.length || !Array.isArray(task.evidence) || !task.evidence.length) fail(`${task.id} is missing its executable contract.`)
for (const dependency of task.dependencies ?? []) if (!taskById.has(dependency)) fail(`${task.id} depends on unknown task ${dependency}.`)
for (const evidence of task.evidence) if (!packageJson.scripts?.[evidence]) fail(`${task.id} references missing npm script ${evidence}.`)
}
if (taskById.get('SDK-01').status !== 'completed' || taskById.get('SDK-02A').status !== 'completed' || taskById.get('SDK-02B').status !== 'completed' || taskById.get('SDK-04').status !== 'completed' || taskById.get('SDK-03').status !== 'completed' || taskById.get('SDK-05').status !== 'completed' || taskById.get('PAR-01').status !== 'completed') fail('current SDK/parameter task status is stale.')
if (JSON.stringify(taskById.get('SDK-03').dependencies) !== JSON.stringify(['SDK-02B', 'SDK-04'])) fail('SDK-03 dependencies must retain both the archive set and isolated bridge.')
if (taskById.get('SDK-04').dependencies?.length !== 1 || taskById.get('SDK-04').dependencies[0] !== 'SDK-02B') fail('SDK-04 must start directly from the completed archive set.')
if (plan.boundary?.freecadNamingBuildStatus !== 'production-linked' || plan.boundary?.exTsn02 !== 'completed' || plan.boundary?.systemExact !== false || plan.boundary?.productionWorker?.availability !== 'available' || plan.boundary?.productionWorker?.callbacks?.length !== 3) fail('production boundary does not identify the callback-complete linked Worker.')
console.log(JSON.stringify({ status: 'freecad-naming-next-tasks-pass', tasks: plan.orderedTasks.length, completed: plan.orderedTasks.filter(({ status }) => status === 'completed').length, inProgress: plan.orderedTasks.filter(({ status }) => status === 'in_progress').map(({ id }) => id), boundary: plan.boundary }, null, 2))