Files
Integration-kit/scripts/checkCoreApi.js
wtclaude 8fa4210477
All checks were successful
PR Checks / prose (pull_request) Successful in 7s
PR Checks / template (pull_request) Successful in 26s
chore(ci): the pinned core is on main now, not edge
The module system cut over on 2026-08-12 and website's `edge` branch was
deleted, so `ci/core-ref.json` named a branch that no longer exists.

The sha did not move. The pinned commit is an ancestor of `main`, the contract
is still MODULE_API_VERSION 1.5.0, and no chapter changed - this is a label
correction, not a re-pin, and deliberately not the moment d2 exists to create.

Nothing in CI reads the `branch` field: the workflow clones the repo and checks
out the sha, which is both why the cutover could not break the build and why a
wrong label here would have sat unnoticed indefinitely. The field is for the
person deciding whether a newer core is worth re-reading the book for, and a
branch that no longer exists tells them nothing. The `why` block now says which
half is load-bearing.

checkCoreApi.js's not-a-core error also asserted that core `main` "has none
until the cutover", which stopped being true at the same merge. A reader hitting
that message would have gone looking for a cutover that already happened - the
kit's own lesson from the CRLF defect, that a failure message naming a diagnosis
has to be right about it, applied to the kit's own scripts.

Verified both paths: the check still passes against a real core (^1.5.0 vs
1.5.0), and the rewritten message renders as intended. checkLinks,
checkRenameSites and checkChapterPaths all clean.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-12 18:05:44 -05:00

82 lines
3.6 KiB
JavaScript

#!/usr/bin/env node
// The kit declares exactly one contract version, in `template/module.json`'s
// `coreApi` — the same field a reader copies. This asserts it still names the
// version the pinned core actually exports.
//
// WHY EQUALITY AND NOT "SATISFIES": a range check is what CORE does at load time,
// and it is right there — a module built against 1.4.0 should keep loading into
// 1.5.0. It is the wrong question here. This kit's job is to be *current*: if core
// moved to 1.5.0, `^1.4.0` still satisfies, the build stays green, and nobody ever
// re-reads the chapters. Green would mean "the template still loads", when what we
// need it to mean is "someone has looked at this since the contract changed".
//
// So the failure is deliberate and expected on every core bump, and the fix is a
// human reading the book — not a version string.
//
// Usage: node scripts/checkCoreApi.js --core <path to a core checkout>
const fs = require('fs')
const path = require('path')
const ROOT = path.resolve(__dirname, '..')
function arg(name) {
const i = process.argv.indexOf(name)
return i === -1 ? null : process.argv[i + 1]
}
const corePath = arg('--core')
if (!corePath) {
console.error('usage: node scripts/checkCoreApi.js --core <path to a core checkout>')
process.exit(2)
}
const manifestPath = path.join(ROOT, 'template', 'module.json')
if (!fs.existsSync(manifestPath)) {
// Slice 0 landed this check before the template it checks. Not an error: the
// workflow guards on the same file, and this message is what a local run says.
console.log('checkCoreApi: no template/module.json yet — nothing to check')
process.exit(0)
}
const versionFile = path.resolve(corePath, 'server/src/modules/version.js')
if (!fs.existsSync(versionFile)) {
console.error(`checkCoreApi: ${versionFile} does not exist.`)
console.error(' Either --core does not point at a website checkout, or the pin in')
console.error(' ci/core-ref.json names a core from before the module system existed')
console.error(' (it reached `main` at the 2026-08-12 cutover, so any ref older than')
console.error(' that on `main` has no server/src/modules/ at all).')
process.exit(1)
}
// Core's version.js is a plain CommonJS module with no dependencies, so it can be
// required straight out of an uninstalled checkout.
const { MODULE_API_VERSION: core } = require(versionFile)
const declared = String(JSON.parse(fs.readFileSync(manifestPath, 'utf8')).coreApi || '')
// A `coreApi` is a RANGE (`^1.4.0`); the version it is built on is its base.
const base = declared.replace(/^[\^~>=<\s]+/, '').trim()
if (!base) {
console.error(`checkCoreApi: template/module.json declares no coreApi (got ${JSON.stringify(declared)})`)
process.exit(1)
}
if (base !== core) {
console.error('checkCoreApi: the kit is written against a different core than it is pinned to.')
console.error('')
console.error(` template/module.json coreApi = ${declared} (base ${base})`)
console.error(` pinned core MODULE_API_VERSION = ${core}`)
console.error('')
console.error(' This is the anti-rot check firing, not a broken build. Someone has to:')
console.error(' 1. read MODULE_API.md §1.1 for what changed in the new version;')
console.error(' 2. read the book and the template for anything that is now untrue;')
console.error(' 3. update template/module.json and ci/core-ref.json together.')
console.error('')
console.error(' Bumping the two files without doing step 2 is the one way to make this')
console.error(' check worthless.')
process.exit(1)
}
console.log(`checkCoreApi: coreApi ${declared} matches the pinned core's ${core} — OK`)