- Add optional Holepunch clone lag gate (holepunch-freshness-gate.json, verify-holepunch-clone-freshness.mjs) and wire into pretest/docs. - Extend stock ctx.bareOsHrpcRequest with disk.os replication routes; bump hrpc_allowlist_sketch proc to schema 2 with stockRoutes list. - Security posture: blindRelayAudit; hyper_multisig_trust_pointer schema 2 + vault multisig continuity env; login/unlock audit hook. - Syscalls schema 9 alignment (JSON schema, compatibility matrix, conformance matrix clock_gettime); boot budget telemetry schema 2 in metrics_live. - Coreutils hostname -s/--short man/options; rebuild kernel bins/man. - POSIX + P2P dashboard section in docs/README; handbook/DOCUMENTATION/ release-checklist/OTA/KERNEL_CONTRACT/PEAR-RUN and related reference updates. - verify-boot-policy-extension-signer-pins: scan kernel init fragments. Note: vendor drift section removed from kernel/lib/bare/README.md (intentional).
117 lines
3.7 KiB
JavaScript
117 lines
3.7 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Fail if `kernel/` and `packages/bare-os-seeder/kernel/` differ.
|
|
* Compares the **entire** recursive file set (relative paths + byte contents), not only `init.js`.
|
|
* Run after coreutils build so `bin/*` and `share/man/man.json` match when both trees were refreshed.
|
|
*/
|
|
|
|
import fs from 'node:fs'
|
|
import path from 'node:path'
|
|
import process from 'node:process'
|
|
import { fileURLToPath } from 'node:url'
|
|
import { assertKernelInitJsMatchesRecipe } from './lib/kernel-init-bundle.mjs'
|
|
|
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
|
|
const canonical = path.join(root, 'kernel')
|
|
const vendored = path.join(root, 'packages/bare-os-seeder/kernel')
|
|
|
|
function walkFiles(dir, base) {
|
|
/** @type {string[]} */
|
|
const out = []
|
|
if (!fs.existsSync(dir)) {
|
|
throw new Error(`Missing directory: ${dir}`)
|
|
}
|
|
for (const ent of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
const p = path.join(dir, ent.name)
|
|
const rel = path.relative(base, p)
|
|
if (ent.isDirectory()) {
|
|
out.push(...walkFiles(p, base))
|
|
} else if (ent.isFile()) {
|
|
out.push(rel)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
function main() {
|
|
try {
|
|
assertKernelInitJsMatchesRecipe(canonical)
|
|
} catch (e) {
|
|
console.error(
|
|
e instanceof Error ? e.message : e,
|
|
'(verify-kernel-seeder-parity)'
|
|
)
|
|
process.exit(1)
|
|
}
|
|
const a = new Set(walkFiles(canonical, canonical))
|
|
const b = new Set(walkFiles(vendored, vendored))
|
|
const onlyA = [...a].filter((x) => !b.has(x)).sort()
|
|
const onlyB = [...b].filter((x) => !a.has(x)).sort()
|
|
if (onlyA.length || onlyB.length) {
|
|
console.error(
|
|
'kernel/ vs packages/bare-os-seeder/kernel/: file set mismatch'
|
|
)
|
|
if (onlyA.length) console.error('Only in kernel/:', onlyA.join(', '))
|
|
if (onlyB.length) console.error('Only in seeder kernel/:', onlyB.join(', '))
|
|
console.error(
|
|
'Remediate from repo root: rsync -a --delete kernel/ packages/bare-os-seeder/kernel/'
|
|
)
|
|
process.exit(1)
|
|
}
|
|
/** @type {string[]} */
|
|
const diffs = []
|
|
for (const rel of [...a].sort()) {
|
|
const pa = path.join(canonical, rel)
|
|
const pb = path.join(vendored, rel)
|
|
const ba = fs.readFileSync(pa)
|
|
const bb = fs.readFileSync(pb)
|
|
if (!ba.equals(bb)) diffs.push(rel)
|
|
}
|
|
if (diffs.length) {
|
|
console.error(
|
|
'kernel/ vs packages/bare-os-seeder/kernel/: content differs for:',
|
|
diffs.join(', ')
|
|
)
|
|
console.error(
|
|
'Remediate: edit canonical kernel/ only, then: node scripts/bundle-kernel-init.mjs && rsync -a --delete kernel/ packages/bare-os-seeder/kernel/'
|
|
)
|
|
process.exit(1)
|
|
}
|
|
const required = [
|
|
'init.js',
|
|
'lib/init/init-main.js',
|
|
'lib/init/fragments/20-init-boot-policy.js',
|
|
'lib/init/fragments/30-init-kernel-extensions.js',
|
|
'lib/boot/00-pear-multisig-shape.js',
|
|
'lib/boot/01-invoke-ctx-hooks.js',
|
|
'lib/bare/manifest.json',
|
|
'lib/bare/bare-module-manifest.json'
|
|
]
|
|
for (const rel of required) {
|
|
const pa = path.join(canonical, rel)
|
|
if (!fs.existsSync(pa)) {
|
|
console.error('verify-kernel-seeder-parity: required file missing in kernel/:', rel)
|
|
process.exit(1)
|
|
}
|
|
}
|
|
/** Staged /bin scripts must carry the BARE_OS_BIN_API pragma (see coreutils runtime). */
|
|
const badBin = []
|
|
for (const rel of [...a].sort()) {
|
|
if (!rel.startsWith('bin/')) continue
|
|
const pa = path.join(canonical, rel)
|
|
if (!fs.statSync(pa).isFile()) continue
|
|
const head = fs.readFileSync(pa, 'utf8').slice(0, 400)
|
|
if (!head.includes('BARE_OS_BIN_API')) badBin.push(rel)
|
|
}
|
|
if (badBin.length) {
|
|
console.error(
|
|
'kernel/bin missing BARE_OS_BIN_API pragma:',
|
|
badBin.join(', ')
|
|
)
|
|
process.exit(1)
|
|
}
|
|
console.log('kernel/ and packages/bare-os-seeder/kernel/ are identical.')
|
|
}
|
|
|
|
main()
|