Files
bare-operating-system/packages/bare-os-seeder/kernel/lib/init/init-main.js
T
2026-04-06 08:47:54 -04:00

2221 lines
68 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Hyperdrive-resident kernel (staged as /boot/init.js).
* Loaded by the booter with an injected ctx object (trusted replication source).
*
* Boot order: /etc/os-release → /etc/motd → optional profile rc → /etc/bare-os/rc →
* /etc/bare-os/rc.d/* (sorted; digit-prefixed snippet names) → /etc/bare-os/rc.local →
* /etc/bare-os/kernel.d/* (same naming rules as rc.d) → session banner →
* optional onboot lines when BARE_OS_SKIP_REPL → interactive loop.
*
* Profile: first non-empty line of /etc/bare-os/profile, overridden by BARE_OS_BOOT_PROFILE.
* When set, runs /etc/bare-os/rc.profile.<name> if present (trusted execLine, before main rc).
*
* Non-interactive onboot: when ctx.bareOsSkipRepl, runs each non-empty, non-# line from
* BARE_OS_ONBOOT (newline-separated) or, if unset, every such line from /etc/bare-os/onboot
* in file order (trusted). Then readLine yields EOF.
*
* BARE_OS_BOOT_TRACE=json logs one JSON object per boot stage on stderr: **`step`** (preferred), **`stage`**, legacy **`phase`** mirror, **`ms`**, **`bootTraceSchemaVersion`** (2). Guest **`os-release`**, **`motd`**, and **`banner`** lines also emit **`type":"bootOutput"`** previews on stderr (stdout body still goes through **`ctx.console.log`** only).
* BARE_OS_BOOT_TRACE=ndjson logs **`bootTraceSchemaVersion`**: **2** lines with **`type":"boot"`**, **`step`**, **`stage`**, **`phase`** (mirror), **`ms`**, **`sessionId`**, **`ts`**, plus **`type":"bootOutput"`** for guest-visible text previews.
*
* BARE_OS_BOOT_MINIMAL=1 or true: skip profile rc, rc, rc.d, rc.local, kernel.d (recovery shell).
* BARE_OS_BOOT_SAFE_MODE=1 or true: after boot policy merge, skip rc.d, kernel.ext.d, onboot (lighter recovery).
* BARE_OS_BOOT_TRANSACTION_JOURNAL=1, true, or ndjson: append boot stage NDJSON lines to
* /run/bare-os/boot-transaction.ndjson when ctx.vfs supports readFile/writeFile.
* BARE_OS_BOOT_CHECKPOINT=1 or true: write /run/bare-os/boot-checkpoint.json after each completed boot stage (schema 2 adds bootStage; legacy `phase` key retained).
* BARE_OS_BOOT_DRY_RUN=1 or true: parse rc/kernel.ext.d but skip trusted execLine and extension script execution (CI).
* BARE_OS_BOOT_POLICY_PATH=/etc/bare-os/… optional primary boot.policy.json path (must stay under /etc/bare-os/).
* BARE_OS_BOOT_ROLLBACK_APPLY=1: merge skip stages from /run/bare-os/boot-rollback.marker JSON when vfs supports readFile.
* BARE_OS_BOOT_BUNDLE_DIGEST_HEX: compared to boot.policy.json requireBootBundleSha256Hex when set.
* BARE_OS_REQUIRE_CTX_API_MIN & BARE_OS_BOOT_ABI_STRICT: enforce ctx.bareOsCtxApiVersion semver vs minimum (strict exits boot).
* BARE_OS_BOOT_SKIP_STAGES (preferred) and BARE_OS_BOOT_SKIP (legacy): comma-separated boot stages to skip among:
* profile, rc, rc.d, rc.local, kernel.d, kernel.ext.d, onboot (os-release and motd always run).
*
* BARE_OS_KERNEL_SELFTEST=1 or true: after boot snippets, run a short trusted self-check via execLine.
* BARE_OS_SELFTEST_FORMAT=tap: TAP-style lines on stderr for CI parsers; **junit**: single XML `<testsuite>` line on stderr.
* BARE_OS_KERNEL_STARTUP_CLASS: `critical` | `system` | `interactive` | `deferred` (default **interactive**); exposed as **`ctx.bareOsKernelStartupClass`** for extensions/initd.
* BARE_OS_BOOT_BUDGET_MS_COLD: optional cold-boot wall-time warning threshold (ms) after **`bareOsPublishBootReady`**.
* BARE_OS_BOOT_BUDGET_MS_BARE_STDLIB: optional wall-time budget (ms) for booter **`ctx.bare`** drive merge + host resolve (**`BARE_OS_BOOT_BARE_STDLIB_RESOLUTION_MS`**, set by the stock booter); guest logs and **`boot-perf.json`** when exceeded.
* BARE_OS_BOOT_BUDGET_STRICT=1 with **BARE_OS_BOOT_POLICY_STRICT**: exit via **`bareOsRequestBooterExit(1)`** when either budget is exceeded (after **`boot-transaction.ndjson`** row **`bootBudgetViolation`** when journaling is on).
* BARE_OS_BOOT_CAPABILITY_CONTRACT_DEBUG=1: log capability-contract merge diagnostics (strict builds).
* BARE_OS_BOOT_EXT_RESOLUTION_TRACE=1 with **BARE_OS_BOOT_POLICY_STRICT**: write **`/run/bare-os/kernel-ext-resolution.json`** (extension load order / cycle ids).
* BARE_OS_BOOT_RC_RESOLUTION_TRACE=1 with **BARE_OS_BOOT_POLICY_STRICT**: write **`/run/bare-os/rc-d-resolution.json`** and **`/run/bare-os/kernel-d-resolution.json`** (lexicographic execution order after filters).
* BARE_OS_BOOT_ALLOWLIST=1 and /etc/bare-os/boot.allow: only first-word commands in that file (plus shell builtins) run from trusted rc/onboot snippets.
*
* BARE_OS_BOOT_MANIFEST_SIGN=1: verify Ed25519 signature in /etc/bare-os/boot.manifest.sig over the raw
* manifest bytes; public key from BARE_OS_BOOT_MANIFEST_PUBKEY_HEX (64 hex chars). Uses ctx.bareOsVerifyBootManifestSignature.
*
* BARE_OS_KERNEL_EXT_D_HOT_RELOAD=1: after boot, exposes **`ctx.bareOsReloadKernelExtDropinsSafe()`** which re-scans
* `/etc/bare-os/kernel.ext.d` and runs only extension scripts not yet recorded in **`ctx.bareOsLoadedKernelExtScripts`**
* (append-only; does not unload). Append-only audit: **`/run/bare-os/kernel-ext-reload.ndjson`** when **`ctx.vfs.writeFile`** exists.
*
* BARE_OS_VFS_HYPERBLOBS_DEDUP=1: operator hint surfaced in **`/proc/bare_os/features`** — content-defined chunking may be enabled
* in host mirror/hyperblob pipelines; the guest VFS does not turn on hyperblobs automatically.
*
* BARE_OS_BOOT_POLICY=1: merge `skipBootStages` / `denyBootStages` from boot.policy (legacy `skipPhases` / `denyBootPhases` still honored; see applyBootPolicyFile). Optional `policyFallbackPaths` for tiered skip merge; `initdAdmission` sets initd env caps; `extensionSignerPinsV5` multi-signer pins.
* Boot policy v2 (optional): `maxExecLineDepth`, `denyEnvKeys`, `requireProcNodes` (VFS paths under /proc).
* Optional `minKernelCapabilitiesPrimary` / `requireSeedCaps` (integers) when ctx exposes
* `bareOsAdvertisedKernelCapabilityWords` / `bareOsSeedKernelCapabilityWords` (wire v2: `primary` word).
* `BARE_OS_BOOT_POLICY_STRICT=1`: exit boot on policy violation (via requestBooterExit(1)).
*
* kernel.d: optional leading comment lines `# ConditionEnvironment=KEY=VAL` or `# AssertEnvironment=KEY=VAL` skip the snippet when env does not match.
* kernel.ext.d: JSON drop-ins under /etc/bare-os/kernel.ext.d/*.json with `{ "scripts": ["/lib/bare-os/extensions/…"] }` (trusted).
* Optional per-drop-in **`minCtxApiVersion`** (semver): skip or strict-fail when **`ctx.bareOsCtxApiVersion`** is lower.
* Optional **`conflictsWith`**: string array of other extension **`id`** values; strict boot fails if both are present.
* Optional ordering: `dependsOn`, `requires` (merged into dependsOn), `after` (ids loaded before this drop-in),
* `before` (ids that must load after this drop-in). Cycles fail strict boot or fall back to filename order.
*
* BARE_OS_BOOT_STRICT=1 or true: first execLine throw in trusted boot snippets calls
* requestBooterExit(1) and stops further boot stages.
*
* BARE_OS_RC_D_SKIP: comma-separated rc.d basenames to skip; a pattern ending with * skips
* names with that prefix (e.g. 10-* skips 10-foo).
*
* BARE_OS_RC_PROPOSAL_MULTISIG_STRICT=1: before **rc.d**, require **`/etc/bare-os/pear.multisig.json`**
* ( **`bareOsPearMultisigShapeOk`** ) and validate every **`/etc/bare-os/rc.proposals/enabled/*.json`**
* (**`schema`**: **1**, **`proposalId`**, **`targetRcSnippet`** under **`/etc/bare-os/rc.d/`**, **`signaturesFrom`**: distinct
* public keys each listed in **`pear.multisig.json`** **`signers`**, count ≥ **`quorum`**). Emits **`ctx.bareOsAuditLogAppend`**
* rows **`rc.proposal.multisig_ok`** / **`rc.proposal.multisig_fail`** when the hook exists.
*
* Use ctx.registerKernelShutdownHook(fn) for teardown before initd disposers.
*/
/**
* @param {Record<string, unknown>} ctx
*/
function wantBootTrace(ctx) {
const v = ctx.env && ctx.env.BARE_OS_BOOT_TRACE
return v === '1' || v === 'true' || v === 'json' || v === 'ndjson'
}
/**
* @param {Record<string, unknown>} ctx
*/
function isBootTraceJson(ctx) {
return ctx.env && ctx.env.BARE_OS_BOOT_TRACE === 'json'
}
/**
* @param {Record<string, unknown>} ctx
*/
function isBootTraceNdjson(ctx) {
return ctx.env && ctx.env.BARE_OS_BOOT_TRACE === 'ndjson'
}
/**
* Guest-visible boot text via **`ctx.console.log`** only (booter session / var-log mirror).
* When **`BARE_OS_BOOT_TRACE`** is **`json`** or **`ndjson`**, append one stderr JSON line per emission (**`type":"bootOutput"`**, preview-capped) for CI and hosts.
* @param {Record<string, unknown>} ctx
* @param {string} step
* @param {string} text
*/
function bootGuestOutLine(ctx, step, text) {
const line = String(text)
const out = ctx.console
if (out && typeof out.log === 'function') out.log(line)
else if (
globalThis.console &&
typeof globalThis.console.log === 'function'
) {
globalThis.console.log(line)
}
if (!wantBootTrace(ctx)) return
const prev =
isBootTraceNdjson(ctx) && line.length > 400
? line.slice(0, 400) + '\u2026'
: isBootTraceJson(ctx) && line.length > 200
? line.slice(0, 200) + '\u2026'
: line
const errFn =
out && typeof out.error === 'function'
? out.error.bind(out)
: globalThis.console && typeof globalThis.console.error === 'function'
? globalThis.console.error.bind(globalThis.console)
: null
if (!errFn) return
if (isBootTraceNdjson(ctx)) {
errFn(
JSON.stringify({
type: 'bootOutput',
bootTraceSchemaVersion: 2,
step,
stream: 'stdout',
sessionId: String((ctx.env && ctx.env.BARE_OS_SESSION_ID) || ''),
ts: Date.now(),
textPreview: prev
})
)
} else if (isBootTraceJson(ctx)) {
errFn(
JSON.stringify({
bootTraceSchemaVersion: 2,
type: 'bootOutput',
step,
stream: 'stdout',
textPreview: prev
})
)
}
}
/**
* Prefer **`ctx.console`** for boot-policy and boot-stage messages; when **`BARE_OS_BOOT_TRACE`**
* is **`json`** or **`ndjson`**, also emit **`type":"bootLog"`** on stderr for structured parsers.
* @param {'error'|'warn'} severity
* @param {string} code Stable machine-readable code (policy field name, **`boot.allow`**, etc.).
* @param {string} humanLine Operator-visible line (keep **`[boot-policy]`** / **`[boot]`** prefixes).
*/
function bootStructuredLog(ctx, severity, code, humanLine) {
const out = ctx.console
const line = String(humanLine)
if (severity === 'warn') {
if (out && typeof out.warn === 'function') out.warn(line)
else if (globalThis.console && typeof globalThis.console.warn === 'function') {
globalThis.console.warn(line)
}
} else {
if (out && typeof out.error === 'function') out.error(line)
else if (globalThis.console && typeof globalThis.console.error === 'function') {
globalThis.console.error(line)
}
}
if (!wantBootTrace(ctx)) return
const errFn =
out && typeof out.error === 'function'
? out.error.bind(out)
: globalThis.console && typeof globalThis.console.error === 'function'
? globalThis.console.error.bind(globalThis.console)
: null
if (!errFn) return
const msg = line.length > 600 ? line.slice(0, 600) + '\u2026' : line
const payload = {
type: 'bootLog',
bootTraceSchemaVersion: 2,
severity,
code: String(code),
message: msg,
ts: Date.now(),
sessionId: String((ctx.env && ctx.env.BARE_OS_SESSION_ID) || '')
}
if (isBootTraceNdjson(ctx)) {
errFn(JSON.stringify(payload))
} else if (isBootTraceJson(ctx)) {
errFn(JSON.stringify({ ...payload, step: 'bootLog' }))
}
}
/**
* @param {Record<string, unknown>} ctx
*/
function bootMinimal(ctx) {
const v = ctx.env && ctx.env.BARE_OS_BOOT_MINIMAL
return v === '1' || v === 'true'
}
/**
* Recovery-oriented boot: skip rc.d snippets, kernel extensions, and onboot after policy merge.
* @param {Record<string, unknown>} ctx
*/
function applyBootSafeMode(ctx) {
const v = ctx.env && ctx.env.BARE_OS_BOOT_SAFE_MODE
if (v !== '1' && v !== 'true') return
const pol =
ctx.bareOsBootPolicySkipStages instanceof Set
? ctx.bareOsBootPolicySkipStages
: ctx.bareOsBootPolicySkipPhases
if (!(pol instanceof Set)) return
pol.add('rc.d')
pol.add('kernel.ext.d')
pol.add('onboot')
}
/**
* @param {Record<string, unknown>} ctx
*/
function kernelExtHotReloadEnabled(ctx) {
const v = ctx.env?.BARE_OS_KERNEL_EXT_D_HOT_RELOAD
return v === '1' || v === 'true'
}
/**
* @param {Record<string, unknown>} ctx
* @param {Record<string, unknown>} row
*/
async function maybeAppendKernelExtReloadJournal(ctx, row) {
const vfs = ctx.vfs
const b4 = ctx.b4a
if (!vfs || typeof vfs.writeFile !== 'function' || !b4) return
const path = '/run/bare-os/kernel-ext-reload.ndjson'
const line =
JSON.stringify({
kernelExtReloadSchemaVersion: 1,
ts: Date.now(),
...row
}) + '\n'
try {
let prev = ''
try {
const buf = await vfs.readFile(path)
if (buf) prev = b4.toString(buf)
} catch {
/* new */
}
await vfs.writeFile(path, b4.from(prev + line))
} catch {
/* ignore */
}
}
async function maybeAppendBootTransactionJournal(ctx, row) {
const en = ctx.env && ctx.env.BARE_OS_BOOT_TRANSACTION_JOURNAL
if (en !== '1' && en !== 'true' && en !== 'ndjson') return
const vfs = ctx.vfs
const b4 = ctx.b4a
if (!vfs || typeof vfs.readFile !== 'function' || typeof vfs.writeFile !== 'function' || !b4) return
const path = '/run/bare-os/boot-transaction.ndjson'
const phaseStr = String(row && row.phase !== undefined ? row.phase : '')
const txnState =
row && row.transactionState != null
? String(row.transactionState)
: BARE_OS_BOOT_TXN_STATE.STAGE_COMMITTED
const line =
JSON.stringify({
bootTransactionSchemaVersion: 2,
type: 'boot_transaction',
ts: Date.now(),
sessionId: String((ctx.env && ctx.env.BARE_OS_SESSION_ID) || ''),
...row,
transactionState: txnState,
bootStage:
row && typeof row.bootStage === 'string'
? row.bootStage
: bootStageForPhase(phaseStr)
}) + '\n'
try {
let prev = ''
try {
const buf = await vfs.readFile(path)
prev = b4.toString(buf)
} catch {
/* new */
}
await vfs.writeFile(path, b4.from(prev + line))
} catch {
/* ignore */
}
}
/**
* @param {Record<string, unknown>} ctx
* @param {string} phase
* @param {number} ms
*/
async function maybeWriteBootCheckpoint(ctx, phase, ms) {
const v = ctx.env && ctx.env.BARE_OS_BOOT_CHECKPOINT
if (v !== '1' && v !== 'true') return
const vfs = ctx.vfs
const b4 = ctx.b4a
if (!vfs || typeof vfs.writeFile !== 'function' || !b4) return
try {
const body =
JSON.stringify({
schema: 2,
phase: String(phase),
stage: String(phase),
bootStage: bootStageForPhase(String(phase)),
phaseMs: typeof ms === 'number' ? ms : 0,
stageMs: typeof ms === 'number' ? ms : 0,
atMs: Date.now(),
sessionId: String((ctx.env && ctx.env.BARE_OS_SESSION_ID) || '')
}) + '\n'
await vfs.writeFile('/run/bare-os/boot-checkpoint.json', b4.from(body))
} catch {
/* ignore */
}
}
/**
* Immutable boot snapshot under /run/bare-os/boot/snapshot.json for operators / doctor tooling.
* Schema **2** adds **`provenance`** (**`buildId`**, **`policyHashSketch`** from **`BARE_OS_BOOT_BUNDLE_DIGEST_HEX`**, **`sessionId`**).
* @param {Record<string, unknown>} ctx
* @param {Set<string>} skipSet
*/
async function maybeWriteBootSnapshotExport(ctx, skipSet) {
const vfs = ctx.vfs
const b4 = ctx.b4a
if (!vfs || typeof vfs.writeFile !== 'function' || !b4) return
const policyPathRaw = String(ctx.env?.BARE_OS_BOOT_POLICY_PATH || '').trim()
const policyPath =
policyPathRaw && policyPathRaw.startsWith('/etc/bare-os/')
? policyPathRaw
: '/etc/bare-os/boot.policy.json'
try {
const preview =
skipSet instanceof Set ? [...skipSet].map((s) => String(s).toLowerCase()).sort() : []
const sid = String((ctx.env && ctx.env.BARE_OS_SESSION_ID) || '')
const digestHex = String(ctx.env?.BARE_OS_BOOT_BUNDLE_DIGEST_HEX || '').trim()
const policyHashSketch =
digestHex.length >= 16 ? digestHex.slice(0, 16).toLowerCase() : null
const buildIdRaw = String(
ctx.env?.BARE_OS_BUILD_ID || ctx.env?.BARE_OS_IMAGE_BUILD_ID || ''
).trim()
const buildId = buildIdRaw ? buildIdRaw.slice(0, 128) : null
const body =
JSON.stringify({
schema: 2,
exportedAtMs: Date.now(),
sessionId: sid,
bootPolicyPath: policyPath,
bootPolicyEnabled:
ctx.env?.BARE_OS_BOOT_POLICY === '1' ||
ctx.env?.BARE_OS_BOOT_POLICY === 'true',
skipBootStagesPreview: preview,
bootSafeMode:
ctx.env?.BARE_OS_BOOT_SAFE_MODE === '1' ||
ctx.env?.BARE_OS_BOOT_SAFE_MODE === 'true',
bootMinimal: bootMinimal(ctx),
provenance: {
schema: 1,
buildId,
policyHashSketch,
sessionId: sid
}
}) + '\n'
await vfs.writeFile('/run/bare-os/boot/snapshot.json', b4.from(body))
} catch {
/* ignore */
}
}
/**
* @param {Record<string, unknown>} ctx
* @returns {Set<string>}
*/
function parseBootSkip(ctx) {
const out = new Set()
const env = ctx.env && typeof ctx.env === 'object' ? ctx.env : {}
for (const raw of [env.BARE_OS_BOOT_SKIP_STAGES, env.BARE_OS_BOOT_SKIP]) {
if (raw == null || !String(raw).trim()) continue
for (const p of String(raw)
.split(',')
.map((s) => s.trim().toLowerCase())
.filter(Boolean)) {
out.add(p)
}
}
return out
}
/**
* @param {Record<string, unknown>} ctx
* @param {string} stage
*/
function shouldSkipBootStage(ctx, stage) {
const pol =
ctx.bareOsBootPolicySkipStages instanceof Set
? ctx.bareOsBootPolicySkipStages
: ctx.bareOsBootPolicySkipPhases
const pl = String(stage).toLowerCase()
if (pol instanceof Set && pol.has(pl)) return true
if (bootMinimal(ctx)) {
return (
stage === 'profile' ||
stage === 'rc' ||
stage === 'rc.d' ||
stage === 'rc.local' ||
stage === 'kernel.d' ||
stage === 'kernel.ext.d' ||
stage === 'onboot'
)
}
return parseBootSkip(ctx).has(pl)
}
function bootStrict(ctx) {
const v = ctx.env && ctx.env.BARE_OS_BOOT_STRICT
return v === '1' || v === 'true'
}
/**
* @param {Record<string, unknown>} ctx
* @returns {string[]}
*/
function parseRcDSkipPatterns(ctx) {
const raw = ctx.env && ctx.env.BARE_OS_RC_D_SKIP
if (raw == null || !String(raw).trim()) return []
return String(raw)
.split(',')
.map((s) => s.trim())
.filter(Boolean)
}
/**
* @param {string} name
* @param {string[]} patterns
*/
function shouldSkipRcDName(name, patterns) {
for (const p of patterns) {
if (p === name) return true
if (p.endsWith('*') && p.length > 1) {
const pre = p.slice(0, -1)
if (name.startsWith(pre)) return true
}
}
return false
}
/**
* @param {Record<string, unknown>} ctx
* @returns {Promise<Set<string> | null>} null when allowlist disabled
*/
async function loadBootAllowSet(ctx) {
const v = ctx.env && ctx.env.BARE_OS_BOOT_ALLOWLIST
if (v !== '1' && v !== 'true') return null
const { drive, b4a } = ctx
const out = new Set()
try {
const buf = await drive.get('/etc/bare-os/boot.allow')
if (!buf) return out
for (const line of b4a.toString(buf).split(/\r?\n/)) {
const t = line.trim()
if (!t || t.startsWith('#')) continue
out.add(t)
}
} catch {
/* ignore */
}
return out
}
/**
* @param {string} line
*/
function firstShellCommandWord(line) {
const s = line.trim()
const m = s.match(/^(\S+)/)
return m ? m[1] : ''
}
/**
* @param {string} line
* @param {Set<string>} allow
*/
function bootLineAllowed(line, allow) {
const w = firstShellCommandWord(line)
if (!w) return true
if (
w === 'export' ||
w === 'unset' ||
w === 'readonly' ||
w === ':' ||
w === 'umask' ||
w === 'cd'
) {
return true
}
if (allow.has(w)) return true
const base = w.includes('/') ? w.split('/').pop() : w
return !!(base && allow.has(base))
}
/**
* @param {Record<string, unknown>} ctx
* @param {string} label
* @param {() => void | Promise<void>} fn
* @param {string[]} stageLog
*/
async function bootTimed(ctx, label, fn, stageLog) {
await invokeCtxBootHooks(ctx, {
phase: label,
stage: label,
when: 'before',
label
})
await maybeAppendBootTransactionJournal(ctx, {
phase: label,
stage: label,
ms: 0,
ok: true,
transactionState: BARE_OS_BOOT_TXN_STATE.STAGE_STARTED,
note: 'enter'
})
const t0 = Date.now()
try {
await fn()
} catch (err) {
const ms = Date.now() - t0
await maybeAppendBootTransactionJournal(ctx, {
phase: label,
stage: label,
ms,
ok: false,
transactionState: BARE_OS_BOOT_TXN_STATE.STAGE_ROLLBACK,
error: String(
err && /** @type {Error} */ (err).message
? /** @type {Error} */ (err).message
: err
)
})
throw err
}
const ms = Date.now() - t0
stageLog.push(label)
if (
ctx.env?.BARE_OS_BOOT_PERF_DETAIL === '1' ||
ctx.env?.BARE_OS_BOOT_PERF_DETAIL === 'true'
) {
if (!Array.isArray(ctx.bareOsBootStageTimings)) {
/** @type {{ label: string, wallMs: number, monotonicNs?: string }[]} */
ctx.bareOsBootStageTimings = []
}
let monotonicNs
let monotonicDeltaNs
try {
const bh = await import('bare-hrtime')
const bg = bh && (bh.bigint || bh.default?.bigint)
if (typeof bg === 'function') {
const now = bg.call(bh)
monotonicNs = String(now)
const prev = ctx.bareOsBootHrtimePrev
if (typeof prev === 'bigint')
monotonicDeltaNs = String(now - prev)
ctx.bareOsBootHrtimePrev = now
}
} catch {
/* optional native */
}
ctx.bareOsBootStageTimings.push({
label,
wallMs: ms,
...(monotonicNs ? { monotonicNs } : {}),
...(monotonicDeltaNs ? { monotonicDeltaNs } : {})
})
}
await maybeAppendBootTransactionJournal(ctx, {
phase: label,
stage: label,
ms,
ok: true,
transactionState: BARE_OS_BOOT_TXN_STATE.STAGE_COMMITTED
})
await maybeWriteBootCheckpoint(ctx, label, ms)
if (wantBootTrace(ctx)) {
if (isBootTraceNdjson(ctx)) {
const sid = (ctx.env && ctx.env.BARE_OS_SESSION_ID) || ''
const rec = {
type: 'boot',
bootTraceSchemaVersion: 2,
step: label,
stage: label,
phase: label,
ms,
sessionId: sid,
ts: Date.now()
}
const w11 = ctx.env && String(ctx.env.BARE_OS_PROBE_ID_HYPERCORE_PACK_HRPC_LIFECYCLE || '').trim()
if (w11) rec.hypercorePackHrpcLifecycleProbeId = w11.slice(0, 128)
const bp = ctx.env && String(ctx.env.BARE_OS_BARE_PACK_VERSION || '').trim()
if (bp) rec.barePackVersionHint = bp.slice(0, 64)
const ap = ctx.env &&
String(ctx.env.BARE_OS_BARE_ADDON_POLICY_VERSION || '').trim()
if (ap) rec.bareAddonPolicyVersionHint = ap.slice(0, 64)
ctx.console.error(JSON.stringify(rec))
} else if (isBootTraceJson(ctx)) {
const base = {
bootTraceSchemaVersion: 2,
step: label,
stage: label,
phase: label,
ms
}
const w11 = ctx.env && String(ctx.env.BARE_OS_PROBE_ID_HYPERCORE_PACK_HRPC_LIFECYCLE || '').trim()
if (w11) base.hypercorePackHrpcLifecycleProbeId = w11.slice(0, 128)
ctx.console.error(JSON.stringify(base))
} else {
ctx.console.error(`[boot] ${label}: ${ms}ms`)
}
}
if (typeof ctx.bareOsEmitBootEvent === 'function') {
ctx.bareOsEmitBootEvent({
type: 'boot',
phase: label,
stage: label,
bootStage: bootStageForPhase(label),
ms,
ts: Date.now(),
sessionId: (ctx.env && ctx.env.BARE_OS_SESSION_ID) || ''
})
}
if (typeof ctx.bareOsEmitKernelEvent === 'function') {
ctx.bareOsEmitKernelEvent({
type: 'kernel',
topic: 'boot.phase',
phase: label,
stage: label,
bootStage: bootStageForPhase(label),
ms,
ts: Date.now(),
sessionId: (ctx.env && ctx.env.BARE_OS_SESSION_ID) || ''
})
}
await invokeCtxBootHooks(ctx, {
phase: label,
stage: label,
when: 'after',
label
})
}
/** @type {Record<string, unknown> | null | undefined} */
let bootManifestMemo
/**
* @param {Record<string, unknown>} ctx
* @returns {Promise<Record<string, unknown> | null>}
*/
async function loadBootManifest(ctx) {
const v = ctx.env && ctx.env.BARE_OS_BOOT_MANIFEST
if (v !== '1' && v !== 'true') return null
if (bootManifestMemo !== undefined) return bootManifestMemo
const { drive, b4a } = ctx
try {
const buf = await drive.get('/etc/bare-os/boot.manifest.json')
if (!buf) {
bootManifestMemo = null
return null
}
const signOn =
ctx.env &&
(ctx.env.BARE_OS_BOOT_MANIFEST_SIGN === '1' ||
ctx.env.BARE_OS_BOOT_MANIFEST_SIGN === 'true')
if (signOn) {
const sigBuf = await drive.get('/etc/bare-os/boot.manifest.sig')
const pub =
ctx.env && ctx.env.BARE_OS_BOOT_MANIFEST_PUBKEY_HEX
? String(ctx.env.BARE_OS_BOOT_MANIFEST_PUBKEY_HEX).trim()
: ''
const verifyFn = ctx.bareOsVerifyBootManifestSignature
if (typeof verifyFn !== 'function' || !pub) {
bootStructuredLog(
ctx,
'error',
'bootManifestSignMissingVerifier',
'[boot] signed manifest requires ctx.bareOsVerifyBootManifestSignature and BARE_OS_BOOT_MANIFEST_PUBKEY_HEX'
)
bootManifestMemo = null
return null
}
if (!verifyFn(buf, sigBuf, pub)) {
bootStructuredLog(
ctx,
'error',
'bootManifestSignFailed',
'[boot] boot.manifest.json Ed25519 signature verification failed'
)
bootManifestMemo = null
return null
}
}
bootManifestMemo = JSON.parse(b4a.toString(buf))
return bootManifestMemo
} catch (e) {
bootStructuredLog(
ctx,
'error',
'bootManifestParse',
'[boot] boot.manifest.json: ' + ((e && e.message) || String(e))
)
bootManifestMemo = null
return null
}
}
/**
* @param {Record<string, unknown>} ctx
* @param {string} drivePath
* @param {string | Uint8Array} content
*/
async function bootManifestDigestOk(ctx, drivePath, content) {
const m = await loadBootManifest(ctx)
const sha = m && typeof m === 'object' ? m.sha256 : null
if (!sha || typeof sha !== 'object') return true
const exp = /** @type {Record<string, string>} */ (sha)[drivePath]
if (exp == null || exp === '') return true
if (typeof ctx.bareOsBootFileSha256Hex !== 'function') {
bootStructuredLog(
ctx,
'error',
'bootManifestMissingHasher',
'[boot] manifest present but bareOsBootFileSha256Hex missing'
)
return false
}
const buf =
typeof content === 'string' ? ctx.b4a.from(content, 'utf8') : content
const hex = ctx.bareOsBootFileSha256Hex(buf)
if (hex !== String(exp).trim().toLowerCase()) {
bootStructuredLog(
ctx,
'error',
'bootManifestSha256Mismatch',
'[boot] manifest sha256 mismatch: ' + drivePath
)
return false
}
return true
}
/**
* @param {Record<string, unknown>} ctx
* @param {string} text
* @returns {Promise<boolean>} false if BARE_OS_BOOT_STRICT and a line threw
*/
async function runRcLines(ctx, text) {
const { execLine } = ctx
const strict = bootStrict(ctx)
const allow = await loadBootAllowSet(ctx)
const dry = bootDryRun(ctx)
for (const line of text.split(/\r?\n/)) {
const t = line.trim()
if (!t || t.startsWith('#')) continue
if (allow && !bootLineAllowed(t, allow)) {
bootStructuredLog(
ctx,
'error',
'bootAllowDenied',
'[boot] command not in boot.allow: ' + t.slice(0, 120)
)
if (strict) {
if (typeof ctx.requestBooterExit === 'function')
ctx.requestBooterExit(1)
return false
}
continue
}
if (dry) {
bootStructuredLog(
ctx,
'error',
'bootDryRunExecLine',
'[boot-dry-run] skip execLine: ' + t.slice(0, 120)
)
continue
}
try {
await execLine(t)
} catch (e) {
bootStructuredLog(
ctx,
'error',
'execLineThrown',
(e && e.message) || String(e)
)
if (strict) {
if (typeof ctx.requestBooterExit === 'function')
ctx.requestBooterExit(1)
return false
}
}
}
return true
}
/**
* @param {Record<string, unknown>} ctx
*/
async function printOsRelease(ctx) {
const { drive, b4a } = ctx
try {
const rel = await drive.get('/etc/os-release')
if (rel) bootGuestOutLine(ctx, 'os-release', b4a.toString(rel))
} catch (e) {
const c = ctx.console
if (c && typeof c.error === 'function')
c.error((e && e.message) || String(e))
}
}
/**
* @param {Record<string, unknown>} ctx
*/
async function printMotd(ctx) {
const { drive, b4a } = ctx
try {
const motd = await drive.get('/etc/motd')
if (motd) bootGuestOutLine(ctx, 'motd', b4a.toString(motd).trimEnd())
} catch (e) {
const c = ctx.console
if (c && typeof c.error === 'function')
c.error((e && e.message) || String(e))
}
}
/**
* Boot profile name: BARE_OS_BOOT_PROFILE wins over first line of /etc/bare-os/profile.
* @param {Record<string, unknown>} ctx
* @returns {Promise<string>}
*/
async function resolveBootProfileName(ctx) {
const fromEnv = ctx.env && ctx.env.BARE_OS_BOOT_PROFILE
if (fromEnv != null && String(fromEnv).trim()) return String(fromEnv).trim()
const { drive, b4a } = ctx
try {
const buf = await drive.get('/etc/bare-os/profile')
if (!buf) return ''
const line = b4a.toString(buf).split(/\r?\n/)[0] || ''
return line.trim()
} catch {
return ''
}
}
/**
* Optional trusted snippet /etc/bare-os/rc.profile.<name> (before /etc/bare-os/rc).
* @param {Record<string, unknown>} ctx
* @param {string} profileName
* @returns {Promise<boolean>}
*/
async function runProfileRc(ctx, profileName) {
if (!profileName) return true
const safe = profileName.replace(/[^a-zA-Z0-9._-]/g, '')
if (safe !== profileName) {
bootStructuredLog(
ctx,
'error',
'bootProfileInvalidChars',
'[boot] profile name contains unsupported characters; skipping rc.profile'
)
return true
}
return await runRcFileAt(
ctx,
`/etc/bare-os/rc.profile.${safe}`,
`rc.profile.${safe}`
)
}
/**
* When stdin is non-interactive, run trusted boot commands (automation).
* @param {Record<string, unknown>} ctx
* @returns {Promise<boolean>}
*/
async function runOnboot(ctx) {
if (!ctx.bareOsSkipRepl) return true
const { execLine, drive, b4a, env } = ctx
const strict = bootStrict(ctx)
const allow = await loadBootAllowSet(ctx)
/** @type {string[]} */
const lines = []
const fromEnv = env && env.BARE_OS_ONBOOT
if (fromEnv != null && String(fromEnv).trim()) {
for (const raw of String(fromEnv).split(/\r?\n/)) {
const t = raw.trim()
if (!t || t.startsWith('#')) continue
lines.push(t)
}
} else {
try {
const buf = await drive.get('/etc/bare-os/onboot')
if (buf) {
for (const raw of b4a.toString(buf).split(/\r?\n/)) {
const t = raw.trim()
if (!t || t.startsWith('#')) continue
lines.push(t)
}
}
} catch (e) {
bootStructuredLog(
ctx,
'error',
'onbootRead',
'onboot: ' + ((e && e.message) || String(e))
)
}
}
const dry = bootDryRun(ctx)
for (const line of lines) {
if (allow && !bootLineAllowed(line, allow)) {
bootStructuredLog(
ctx,
'error',
'onbootBootAllowDenied',
'[boot] onboot command not in boot.allow: ' + line.slice(0, 120)
)
if (strict) {
if (typeof ctx.requestBooterExit === 'function')
ctx.requestBooterExit(1)
return false
}
continue
}
if (dry) {
bootStructuredLog(
ctx,
'error',
'bootDryRunOnboot',
'[boot-dry-run] skip onboot: ' + line.slice(0, 120)
)
continue
}
try {
await execLine(line)
} catch (e) {
bootStructuredLog(
ctx,
'error',
'onbootExecLineThrown',
(e && e.message) || String(e)
)
if (strict) {
if (typeof ctx.requestBooterExit === 'function')
ctx.requestBooterExit(1)
return false
}
}
}
return true
}
/**
* @param {Record<string, unknown>} ctx
* @param {string} drivePath absolute path on system drive
* @param {string} label for errors
* @returns {Promise<boolean>}
*/
async function runRcFileAt(ctx, drivePath, label) {
const { drive, b4a } = ctx
try {
const buf = await drive.get(drivePath)
if (!buf) return true
const text = b4a.toString(buf)
if (!(await bootManifestDigestOk(ctx, drivePath, text))) {
if (bootStrict(ctx)) {
if (typeof ctx.requestBooterExit === 'function')
ctx.requestBooterExit(1)
return false
}
return true
}
return await runRcLines(ctx, text)
} catch (e) {
bootStructuredLog(
ctx,
'error',
'rcFileRead',
`${label}: ` + ((e && e.message) || String(e))
)
return true
}
}
/**
* Only run rc.d files whose name starts with a digit (e.g. `10-local`).
* Skips README*, *.md, dotfiles, and *~ so documentation is never exec'd as shell.
* @param {string} name basename from readdir
*/
function isBareOsRcSnippetFile(name) {
if (!name || name.startsWith('.') || name.endsWith('~')) return false
if (/^README(\.|$)/i.test(name)) return false
if (/\.md$/i.test(name)) return false
return /^[0-9]/.test(name)
}
/**
* Optional snippets under /etc/bare-os/kernel.d/ — same rules as rc.d; runs after rc.local.
* @param {Record<string, unknown>} ctx
* @returns {Promise<boolean>}
*/
async function runBareOsKernelDir(ctx) {
const { drive, b4a } = ctx
try {
/** @type {string[]} */
const names = []
try {
for await (const n of drive.readdir('/etc/bare-os/kernel.d'))
names.push(n)
} catch {
return true
}
names.sort()
/** @type {string[]} */
const toRun = []
for (const name of names) {
if (!isBareOsRcSnippetFile(name)) continue
toRun.push(name)
}
const strictPol =
ctx.env?.BARE_OS_BOOT_POLICY_STRICT === '1' ||
ctx.env?.BARE_OS_BOOT_POLICY_STRICT === 'true'
const traceKd =
strictPol &&
(ctx.env?.BARE_OS_BOOT_RC_RESOLUTION_TRACE === '1' ||
ctx.env?.BARE_OS_BOOT_RC_RESOLUTION_TRACE === 'true')
if (traceKd && ctx.vfs && typeof ctx.vfs.writeFile === 'function' && ctx.b4a) {
try {
const body =
JSON.stringify({
schema: 1,
atMs: Date.now(),
sessionId: String((ctx.env && ctx.env.BARE_OS_SESSION_ID) || ''),
kernelDOrdered: toRun
}) + '\n'
await ctx.vfs.writeFile(
'/run/bare-os/kernel-d-resolution.json',
ctx.b4a.from(body)
)
} catch {
/* ignore */
}
}
for (const name of toRun) {
const p = `/etc/bare-os/kernel.d/${name}`
try {
const buf = await drive.get(p)
if (!buf) continue
const txt = b4a.toString(buf)
if (!kernelSnippetEnvGuardsOk(ctx, txt)) {
bootStructuredLog(
ctx,
'error',
'kernel.d.envGuardSkip',
`[boot] kernel.d/${name}: ConditionEnvironment / AssertEnvironment not met; skip`
)
continue
}
const cont = await runRcLines(ctx, txt)
if (!cont) return false
} catch (e) {
bootStructuredLog(
ctx,
'error',
'kernel.d.exec',
`kernel.d/${name}: ` + ((e && e.message) || String(e))
)
}
}
} catch (e) {
bootStructuredLog(
ctx,
'error',
'kernel.d.outer',
(e && e.message) || String(e)
)
}
return true
}
/**
* @param {Record<string, unknown>} ctx
* @param {Record<string, unknown>} entry
*/
function bareOsAppendRcProposalAudit(ctx, entry) {
try {
const fn = ctx.bareOsAuditLogAppend
if (typeof fn === 'function') fn(entry)
} catch {
/* ignore */
}
}
/**
* When **`BARE_OS_RC_PROPOSAL_MULTISIG_STRICT`**, every enabled proposal must cite enough
* **`pear.multisig.json`** signers (distinct keys). Cryptographic signature verification is host/seeder responsibility.
* @param {Record<string, unknown>} ctx
* @returns {Promise<boolean>}
*/
async function verifyRcProposalsMultisigStrict(ctx) {
const strict = ctx.env?.BARE_OS_RC_PROPOSAL_MULTISIG_STRICT
if (strict !== '1' && strict !== 'true') return true
const { drive, b4a } = ctx
let pearBuf
try {
pearBuf = await drive.get('/etc/bare-os/pear.multisig.json')
} catch {
pearBuf = null
}
if (!pearBuf) {
bootStructuredLog(
ctx,
'error',
'rc.proposal.multisig.pear_missing',
'[rc.proposals] BARE_OS_RC_PROPOSAL_MULTISIG_STRICT requires /etc/bare-os/pear.multisig.json'
)
bareOsAppendRcProposalAudit(ctx, {
type: 'rc.proposal.multisig_fail',
reason: 'pear_multisig_missing',
ts: Date.now()
})
return false
}
/** @type {unknown} */
let pearParsed
try {
pearParsed = JSON.parse(b4a.toString(pearBuf))
} catch (e) {
bootStructuredLog(
ctx,
'error',
'rc.proposal.multisig.pear_parse',
'[rc.proposals] pear.multisig.json: ' + ((e && e.message) || String(e))
)
bareOsAppendRcProposalAudit(ctx, {
type: 'rc.proposal.multisig_fail',
reason: 'pear_multisig_parse',
ts: Date.now()
})
return false
}
if (!bareOsPearMultisigShapeOk(pearParsed)) {
bootStructuredLog(
ctx,
'error',
'rc.proposal.multisig.pear_shape',
'[rc.proposals] pear.multisig.json must be { signers: string[], quorum: number } with 1 ≤ quorum ≤ signers.length'
)
bareOsAppendRcProposalAudit(ctx, {
type: 'rc.proposal.multisig_fail',
reason: 'pear_multisig_shape',
ts: Date.now()
})
return false
}
const pear = /** @type {{ signers: string[]; quorum: number }} */ (pearParsed)
const signerSet = new Set(pear.signers.map((s) => String(s).toLowerCase()))
const quorum = pear.quorum
/** @type {string[]} */
const proposalNames = []
try {
for await (const n of drive.readdir('/etc/bare-os/rc.proposals/enabled')) {
if (String(n).endsWith('.json')) proposalNames.push(String(n))
}
} catch {
return true
}
proposalNames.sort()
if (!proposalNames.length) return true
for (const fn of proposalNames) {
const p = `/etc/bare-os/rc.proposals/enabled/${fn}`
/** @type {unknown} */
let raw
try {
const buf = await drive.get(p)
if (!buf) {
bootStructuredLog(ctx, 'error', 'rc.proposal.missing', `[rc.proposals] empty: ${fn}`)
bareOsAppendRcProposalAudit(ctx, {
type: 'rc.proposal.multisig_fail',
reason: 'proposal_missing',
proposalFile: fn,
ts: Date.now()
})
return false
}
raw = JSON.parse(b4a.toString(buf))
} catch (e) {
bootStructuredLog(
ctx,
'error',
'rc.proposal.parse',
`[rc.proposals] ${fn}: ` + ((e && e.message) || String(e))
)
bareOsAppendRcProposalAudit(ctx, {
type: 'rc.proposal.multisig_fail',
reason: 'proposal_parse',
proposalFile: fn,
ts: Date.now()
})
return false
}
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
bootStructuredLog(ctx, 'error', 'rc.proposal.shape', `[rc.proposals] ${fn}: expected object`)
return false
}
const o = /** @type {Record<string, unknown>} */ (raw)
if (o.schema !== 1) {
bootStructuredLog(
ctx,
'error',
'rc.proposal.schema',
`[rc.proposals] ${fn}: schema must be 1`
)
bareOsAppendRcProposalAudit(ctx, {
type: 'rc.proposal.multisig_fail',
reason: 'proposal_schema',
proposalFile: fn,
ts: Date.now()
})
return false
}
const proposalId = String(o.proposalId || '').trim()
if (!proposalId) {
bootStructuredLog(ctx, 'error', 'rc.proposal.id', `[rc.proposals] ${fn}: proposalId required`)
bareOsAppendRcProposalAudit(ctx, {
type: 'rc.proposal.multisig_fail',
reason: 'proposal_id',
proposalFile: fn,
ts: Date.now()
})
return false
}
const targetRcSnippet = String(o.targetRcSnippet || '').trim()
if (!targetRcSnippet.startsWith('/etc/bare-os/rc.d/')) {
bootStructuredLog(
ctx,
'error',
'rc.proposal.target',
`[rc.proposals] ${fn}: targetRcSnippet must start with /etc/bare-os/rc.d/`
)
bareOsAppendRcProposalAudit(ctx, {
type: 'rc.proposal.multisig_fail',
reason: 'proposal_target',
proposalFile: fn,
proposalId,
ts: Date.now()
})
return false
}
const sigFrom = o.signaturesFrom
if (!Array.isArray(sigFrom)) {
bootStructuredLog(
ctx,
'error',
'rc.proposal.signaturesFrom',
`[rc.proposals] ${fn}: signaturesFrom must be an array of signer public keys`
)
bareOsAppendRcProposalAudit(ctx, {
type: 'rc.proposal.multisig_fail',
reason: 'signatures_from_shape',
proposalFile: fn,
proposalId,
ts: Date.now()
})
return false
}
/** @type {Set<string>} */
const approved = new Set()
for (const s of sigFrom) {
const k = String(s || '').toLowerCase().trim()
if (!k) continue
if (!signerSet.has(k)) {
bootStructuredLog(
ctx,
'error',
'rc.proposal.signer_unknown',
`[rc.proposals] ${fn}: signer not in pear.multisig.json`
)
bareOsAppendRcProposalAudit(ctx, {
type: 'rc.proposal.multisig_fail',
reason: 'signer_not_in_policy',
proposalFile: fn,
proposalId,
ts: Date.now()
})
return false
}
approved.add(k)
}
if (approved.size < quorum) {
bootStructuredLog(
ctx,
'error',
'rc.proposal.quorum',
`[rc.proposals] ${fn}: need ≥ pear.multisig quorum (${quorum}) distinct approved signers, got ${approved.size}`
)
bareOsAppendRcProposalAudit(ctx, {
type: 'rc.proposal.multisig_fail',
reason: 'quorum_not_met',
proposalFile: fn,
proposalId,
ts: Date.now()
})
return false
}
bareOsAppendRcProposalAudit(ctx, {
type: 'rc.proposal.multisig_ok',
proposalFile: fn,
proposalId,
targetRcSnippet,
signerCount: approved.size,
quorum,
ts: Date.now()
})
}
return true
}
/**
* Optional snippets under /etc/bare-os/rc.d/ — executed in lexicographic order.
* @param {Record<string, unknown>} ctx
* @returns {Promise<boolean>}
*/
async function runBareOsRcDir(ctx) {
const { drive, b4a } = ctx
if (!(await verifyRcProposalsMultisigStrict(ctx))) return false
const skip = parseRcDSkipPatterns(ctx)
try {
/** @type {string[]} */
const names = []
try {
for await (const n of drive.readdir('/etc/bare-os/rc.d')) names.push(n)
} catch {
return true
}
names.sort()
/** @type {string[]} */
const toRun = []
for (const name of names) {
if (!isBareOsRcSnippetFile(name)) continue
if (shouldSkipRcDName(name, skip)) continue
toRun.push(name)
}
const strictPol =
ctx.env?.BARE_OS_BOOT_POLICY_STRICT === '1' ||
ctx.env?.BARE_OS_BOOT_POLICY_STRICT === 'true'
const traceRc =
strictPol &&
(ctx.env?.BARE_OS_BOOT_RC_RESOLUTION_TRACE === '1' ||
ctx.env?.BARE_OS_BOOT_RC_RESOLUTION_TRACE === 'true')
if (traceRc && ctx.vfs && typeof ctx.vfs.writeFile === 'function' && ctx.b4a) {
try {
const body =
JSON.stringify({
schema: 1,
atMs: Date.now(),
sessionId: String((ctx.env && ctx.env.BARE_OS_SESSION_ID) || ''),
rcDOrdered: toRun
}) + '\n'
await ctx.vfs.writeFile(
'/run/bare-os/rc-d-resolution.json',
ctx.b4a.from(body)
)
} catch {
/* ignore */
}
}
for (const name of toRun) {
const p = `/etc/bare-os/rc.d/${name}`
try {
const buf = await drive.get(p)
if (!buf) continue
const cont = await runRcLines(ctx, b4a.toString(buf))
if (!cont) return false
} catch (e) {
bootStructuredLog(
ctx,
'error',
'rc.d.exec',
`rc.d/${name}: ` + ((e && e.message) || String(e))
)
}
}
} catch (e) {
bootStructuredLog(
ctx,
'error',
'rc.d.outer',
(e && e.message) || String(e)
)
}
return true
}
/**
* @param {Record<string, unknown>} ctx
*/
async function printSessionBanner(ctx) {
const { drive, b4a } = ctx
for (const p of ['/etc/bare-os/banner', '/etc/issue']) {
try {
const buf = await drive.get(p)
if (buf) {
bootGuestOutLine(ctx, 'banner', b4a.toString(buf).trimEnd())
return
}
} catch {
/* ignore */
}
}
const defaultBanner =
'Bare operating system — guest session (login [--new] <passphrase> to unlock)'
if (ctx.bareOsSkipRepl) {
bootGuestOutLine(
ctx,
'banner',
'Bare operating system — non-interactive session (BARE_OS_SKIP_REPL).'
)
return
}
bootGuestOutLine(ctx, 'banner', defaultBanner)
}
/**
* Trusted post-boot checks. **`BARE_OS_SELFTEST_FORMAT=tap`** and **`junit`** emit diagnostics on
* **`ctx.console.error`** (this function destructures **`ctx.console`** as **`console`**) so output
* follows the Test Anything Protocols stderr convention while staying on the booter session sink—
* not **`globalThis.console`**. Plain **`selftest:`** lines use the same sink.
*
* @param {Record<string, unknown>} ctx
* @returns {Promise<boolean>}
*/
async function runKernelSelftest(ctx) {
const v = ctx.env && ctx.env.BARE_OS_KERNEL_SELFTEST
if (v !== '1' && v !== 'true' && v !== 'upgrade') return true
const { execLine, console } = ctx
const strict = bootStrict(ctx)
const fmt = (ctx.env && ctx.env.BARE_OS_SELFTEST_FORMAT) || ''
const fmtLow = String(fmt).toLowerCase()
const tap = fmtLow === 'tap'
const junit = fmtLow === 'junit'
let tapN = 0
/** @type {{ ok: boolean, name: string, detail: string }[]} */
const junitCases = []
/** @param {string} s */
function escXml(s) {
return String(s || '')
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/"/g, '&quot;')
}
/** @param {string} name */
function tapLine(ok, name, detail) {
if (junit) {
junitCases.push({ ok, name, detail: detail || '' })
return
}
if (!tap) return
tapN++
if (ok) {
console.error(`ok ${tapN} ${name}`)
} else {
console.error(`not ok ${tapN} ${name}${detail ? ' — ' + detail : ''}`)
}
}
if (tap) {
console.error('TAP version 13')
}
/** @type {[string, string][]} */
const specs =
v === 'upgrade'
? [
['true', 'upgrade-smoke-true'],
[
'test -f /proc/bare_os/kernel_program.json && echo selftest_kernel_program',
'proc-kernel-program-upgrade'
],
[
'test -f /run/bare-os/boot.json && echo selftest_boot_json',
'run-boot-json-upgrade'
]
]
: [
[':', 'colon-builtin'],
['true', 'true-builtin'],
['false; echo selftest_false_ok', 'false-sequencing'],
['test -f /proc/version && echo selftest_proc', 'proc-version'],
[
'test -f /proc/bare_os_resources && echo selftest_resources',
'proc-bare_os_resources'
],
[
'test -f /proc/bare_os_features && echo selftest_features',
'proc-bare_os_features'
],
[
'test -f /proc/bare_os/index.json && echo selftest_bare_os_dir',
'proc-bare_os_dir'
],
['test -d /proc/self/fd && echo selftest_proc_fd', 'proc-self-fd'],
['test -d /sys/devices && echo selftest_sys_devices', 'sys-devices'],
['echo selftest_vfs | tee /dev/null', 'pipeline-tee-devnull'],
[
'test -f /lib/bare/manifest.json && echo selftest_bare_manifest',
'lib-bare-manifest'
],
[
'test -f /proc/bare_os/provenance && echo selftest_provenance',
'proc-bare_os_provenance'
],
[
'test -f /proc/bare_os/metrics_live.json && echo selftest_metrics_live',
'proc-metrics-live'
],
[
'test -f /proc/bare_os/net_summary.json && echo selftest_net_summary',
'proc-net-summary'
],
[
'test -f /proc/bare_os/host_os.json && echo selftest_host_os',
'proc-host-os'
],
[
'test -f /proc/bare_os/sync_window.json && echo selftest_sync_window',
'proc-sync-window'
],
[
'test -f /proc/bare_os/manifest_hints && echo selftest_manifest_hints',
'proc-manifest-hints'
],
['systemctl list-units 2>/dev/null || true', 'systemctl-list']
]
for (const [line, name] of specs) {
try {
await execLine(line)
tapLine(true, name, '')
} catch (e) {
const msg = (e && e.message) || String(e)
console.error('selftest: ' + msg)
tapLine(false, name, msg)
if (strict) {
if (typeof ctx.requestBooterExit === 'function')
ctx.requestBooterExit(1)
return false
}
}
}
try {
/** @type {string[]} */
const snames = []
for await (const n of ctx.drive.readdir('/etc/bare-os/selftest.d'))
snames.push(n)
snames.sort()
for (const name of snames) {
if (!isBareOsRcSnippetFile(name)) continue
const p = `/etc/bare-os/selftest.d/${name}`
const buf = await ctx.drive.get(p)
if (!buf) continue
const label = `selftest.d/${name}`
try {
await runRcLines(ctx, ctx.b4a.toString(buf))
tapLine(true, label, '')
} catch (e) {
const msg = (e && e.message) || String(e)
console.error('selftest: ' + msg)
tapLine(false, label, msg)
if (strict) {
if (typeof ctx.requestBooterExit === 'function')
ctx.requestBooterExit(1)
return false
}
}
}
} catch {
/* no selftest.d */
}
if (tap) {
console.error(`1..${tapN}`)
}
if (junit && junitCases.length) {
const failures = junitCases.filter((c) => !c.ok).length
const cases = junitCases
.map((c) => {
const body = c.ok
? ''
: `<failure message="selftest">${escXml(c.detail)}</failure>`
return `<testcase name="${escXml(c.name)}" classname="kernel.selftest">${body}</testcase>`
})
.join('')
console.error(
`<?xml version="1.0" encoding="UTF-8"?><testsuite name="bare-os-kernel-selftest" tests="${junitCases.length}" failures="${failures}">${cases}</testsuite>`
)
}
return true
}
/**
* @param {Record<string, unknown>} ctx
* @param {number} bootT0
* @param {{ kind: string, code: string, wallMs: number, limitMs: number }[]} violations
* @param {boolean} coldExceeded
* @param {boolean} stdlibExceeded
* @param {string[]} [stageLog]
*/
async function maybeWriteBootBudgetSummaryJson(
ctx,
bootT0,
violations,
coldExceeded,
stdlibExceeded,
stageLog
) {
const vfs = ctx.vfs
const b4 = ctx.b4a
if (!vfs || typeof vfs.writeFile !== 'function' || !b4) return
const wall = Date.now() - bootT0
const row =
JSON.stringify({
schema: 2,
atMs: Date.now(),
coldWallMs: wall,
coldExceeded,
bareStdlibExceeded: stdlibExceeded,
violationCodes: violations.map((v) => v.code).filter(Boolean),
violations,
bootStageCount:
Array.isArray(stageLog) && stageLog.length ? stageLog.length : null,
bootStageTail:
Array.isArray(stageLog) && stageLog.length
? stageLog.slice(-16)
: undefined,
procHint: '/proc/bare_os/boot_budget_summary.json',
note: 'Written every boot; operators mirror into proc via booter VFS provider. Schema 2 adds bootStageCount/bootStageTail from kernel stage log.'
}) + '\n'
try {
await vfs.writeFile('/run/bare-os/boot-budget-summary.json', b4.from(row))
} catch {
/* optional */
}
}
async function maybeWriteBootPerfJson(ctx, bootT0, stageLog) {
const vfs = ctx.vfs
const b4 = ctx.b4a
if (!vfs || typeof vfs.readFile !== 'function' || typeof vfs.writeFile !== 'function' || !b4)
return
const wall = Date.now() - bootT0
const budgetRaw = Number.parseInt(
String(ctx.env?.BARE_OS_BOOT_BUDGET_MS_COLD || ''),
10
)
const budget = Number.isFinite(budgetRaw) && budgetRaw > 0 ? budgetRaw : null
const stdlibWallRaw = Number.parseInt(
String(ctx.env?.BARE_OS_BOOT_BARE_STDLIB_RESOLUTION_MS || ''),
10
)
const stdlibWall =
Number.isFinite(stdlibWallRaw) && stdlibWallRaw >= 0 ? stdlibWallRaw : null
const stdlibBudgetRaw = Number.parseInt(
String(ctx.env?.BARE_OS_BOOT_BUDGET_MS_BARE_STDLIB || ''),
10
)
const stdlibBudget =
Number.isFinite(stdlibBudgetRaw) && stdlibBudgetRaw > 0
? stdlibBudgetRaw
: null
const stages =
Array.isArray(ctx.bareOsBootStageTimings) && ctx.bareOsBootStageTimings.length
? ctx.bareOsBootStageTimings
: undefined
let schema = stages ? 2 : 1
if (stdlibWall != null || stdlibBudget != null) schema = Math.max(schema, 3)
schema = Math.max(schema, 4)
schema = Math.max(schema, 5)
const bootBudgetTelemetry = {
schema: 1,
coldWallMs: wall,
coldBudgetMs: budget,
coldWithinBudget: budget == null ? null : wall <= budget,
stdlibWallMs: stdlibWall,
stdlibBudgetMs: stdlibBudget,
stdlibWithinBudget:
stdlibBudget == null || stdlibWall == null
? null
: stdlibWall <= stdlibBudget,
envCold: 'BARE_OS_BOOT_BUDGET_MS_COLD',
envStdlibWall: 'BARE_OS_BOOT_BARE_STDLIB_RESOLUTION_MS',
envStdlibBudget: 'BARE_OS_BOOT_BUDGET_MS_BARE_STDLIB',
note: 'Unified mirror of guest cold boot vs bare-stdlib resolution budgets; same values as top-level coldWallMs / bareStdlib* (booter sets BARE_OS_BOOT_BARE_STDLIB_RESOLUTION_MS).'
}
const row =
JSON.stringify({
schema,
bootGraphJsonPath: '/proc/bare_os/boot_graph.json',
stageLogSnapshot: [...stageLog],
coldWallMs: wall,
bootBudgetMsCold: budget,
withinBudget: budget == null ? null : wall <= budget,
bootBudgetWarning:
budget != null && wall > budget
? `cold boot ${wall}ms exceeded BARE_OS_BOOT_BUDGET_MS_COLD ${budget}ms`
: null,
bareStdlibResolutionWallMs: stdlibWall,
bareStdlibBudgetMs: stdlibBudget,
bareStdlibWithinBudget:
stdlibBudget == null || stdlibWall == null
? null
: stdlibWall <= stdlibBudget,
bareStdlibBudgetWarning:
stdlibBudget != null &&
stdlibWall != null &&
stdlibWall > stdlibBudget
? `bare stdlib resolution ${stdlibWall}ms exceeded BARE_OS_BOOT_BUDGET_MS_BARE_STDLIB ${stdlibBudget}ms`
: null,
bootBudgetTelemetry,
bootBudgetStrict:
ctx.env?.BARE_OS_BOOT_BUDGET_STRICT === '1' ||
ctx.env?.BARE_OS_BOOT_BUDGET_STRICT === 'true',
bootPolicyStrict:
ctx.env?.BARE_OS_BOOT_POLICY_STRICT === '1' ||
ctx.env?.BARE_OS_BOOT_POLICY_STRICT === 'true',
stageCount: stageLog.length,
stages,
completedAtMs: Date.now()
}) + '\n'
try {
await vfs.writeFile('/run/bare-os/boot-perf.json', b4.from(row))
} catch {
/* optional */
}
}
/**
* @param {Record<string, unknown>} ctx
* @param {string[]} stageLog
*/
function publishBootReady(ctx, stageLog) {
if (typeof ctx.bareOsPublishBootReady !== 'function') return
const sid = (ctx.env && ctx.env.BARE_OS_SESSION_ID) || ''
const gpen = ctx.env && ctx.env.BARE_OS_BOOT_TRANSACTION_JOURNAL
const safe =
ctx.env?.BARE_OS_BOOT_SAFE_MODE === '1' ||
ctx.env?.BARE_OS_BOOT_SAFE_MODE === 'true'
const bootStages = stageLog.map((label) => ({
label: String(label),
bootStage: bootStageForPhase(String(label))
}))
ctx.bareOsPublishBootReady({
ready: true,
stages: [...stageLog],
phases: [...stageLog],
steps: [...stageLog],
bootSteps: [...stageLog],
sessionId: sid,
completedAtMs: Date.now(),
minimal: bootMinimal(ctx),
subsystems: {
kernel: {
ready: true,
stageCount: stageLog.length,
phaseCount: stageLog.length,
stepCount: stageLog.length,
bootStages,
bootPhases: bootStages,
bootSteps: bootStages,
programProc: {
schema: 2,
programVersion: 2,
safeMode: safe,
bootDryRun: bootDryRun(ctx),
transactionJournal: gpen === '1' || gpen === 'true' || gpen === 'ndjson',
checkpoint:
ctx.env?.BARE_OS_BOOT_CHECKPOINT === '1' ||
ctx.env?.BARE_OS_BOOT_CHECKPOINT === 'true',
bootTransactionFsm: {
schema: 1,
state: 'committed',
note: 'Guest kernel finished boot stage sequence; see boot-transaction.ndjson for per-stage rows.'
},
kernelExtHotReload: kernelExtHotReloadEnabled(ctx)
}
},
initd: { awaited: true }
}
})
}
/**
* Merge sketch for seed vs advertised capability words under strict policy (expand over time).
* @param {Record<string, unknown>} ctx
*/
function mergeBootCapabilityContract(ctx) {
const strict =
ctx.env?.BARE_OS_BOOT_POLICY_STRICT === '1' ||
ctx.env?.BARE_OS_BOOT_POLICY_STRICT === 'true'
const adv = ctx.bareOsAdvertisedKernelCapabilityWords
const seed = ctx.bareOsSeedKernelCapabilityWords
if (
strict &&
adv &&
seed &&
typeof adv === 'object' &&
typeof seed === 'object'
) {
const ap = /** @type {{ primary?: number }} */ (adv).primary
const sp = /** @type {{ primary?: number }} */ (seed).primary
if (typeof ap === 'number' && typeof sp === 'number' && ap !== sp) {
bootStructuredLog(
ctx,
'error',
'bootCapabilityPrimaryMismatch',
'[boot] strict: primary kernel capability word mismatch (advertised vs seed)'
)
if (typeof ctx.requestBooterExit === 'function') ctx.requestBooterExit(1)
return false
}
}
const dbg =
ctx.env?.BARE_OS_BOOT_CAPABILITY_CONTRACT_DEBUG === '1' ||
ctx.env?.BARE_OS_BOOT_CAPABILITY_CONTRACT_DEBUG === 'true'
if (dbg) {
bootStructuredLog(
ctx,
'error',
'bootCapabilityContractDebug',
'[boot] capability contract debug: advertised=' +
(adv ? 'yes' : 'no') +
' seed=' +
(seed ? 'yes' : 'no')
)
}
return true
}
/**
* Boot ABI gate: optional `BARE_OS_REQUIRE_CTX_API_MIN` vs `ctx.bareOsCtxApiVersion`.
* @param {Record<string, unknown>} ctx
*/
function enforceBootCtxApiMin(ctx) {
const need = String(ctx.env?.BARE_OS_REQUIRE_CTX_API_MIN || '').trim()
if (!need) return true
const have =
typeof ctx.bareOsCtxApiVersion === 'string'
? ctx.bareOsCtxApiVersion.trim()
: ''
if (!have || !semverGte(have, need)) {
bootStructuredLog(
ctx,
'error',
'bootCtxApiMin',
'[boot] BARE_OS_REQUIRE_CTX_API_MIN not satisfied (need ' +
need +
', have ' +
(have || '(none)') +
')'
)
if (
ctx.env?.BARE_OS_BOOT_POLICY_STRICT === '1' ||
ctx.env?.BARE_OS_BOOT_POLICY_STRICT === 'true' ||
ctx.env?.BARE_OS_BOOT_ABI_STRICT === '1' ||
ctx.env?.BARE_OS_BOOT_ABI_STRICT === 'true'
) {
if (typeof ctx.requestBooterExit === 'function') ctx.requestBooterExit(1)
return false
}
}
return true
}
async function start(ctx) {
const bootT0 = Date.now()
const { readLine, execLine } = ctx
/** @type {string[]} */
const stageLog = []
const bootPolicySkipSet = new Set()
ctx.bareOsBootPolicySkipStages = bootPolicySkipSet
ctx.bareOsBootPolicySkipPhases = bootPolicySkipSet
{
const raw = String(ctx.env?.BARE_OS_KERNEL_STARTUP_CLASS || 'interactive')
.trim()
.toLowerCase()
const allowed = new Set(['critical', 'system', 'interactive', 'deferred'])
ctx.bareOsKernelStartupClass = allowed.has(raw)
? raw
: 'interactive'
}
if (!(await applyBootPolicyFile(ctx))) return
if (!enforceBootCtxApiMin(ctx)) return
if (!mergeBootCapabilityContract(ctx)) return
await maybeAppendBootTransactionJournal(ctx, {
phase: 'boot.policy',
stage: 'boot.policy',
bootStage: 'policy',
ms: 0,
ok: true,
transactionState: BARE_OS_BOOT_TXN_STATE.STAGE_COMMITTED
})
await maybeWriteBootCheckpoint(ctx, 'boot.policy', 0)
applyBootSafeMode(ctx)
await maybeWriteBootSnapshotExport(ctx, bootPolicySkipSet)
await bootTimed(ctx, 'os-release', () => printOsRelease(ctx), stageLog)
await bootTimed(ctx, 'motd', () => printMotd(ctx), stageLog)
const profileName = await resolveBootProfileName(ctx)
/** @type {boolean} */
let bootOk = true
if (!shouldSkipBootStage(ctx, 'profile')) {
await bootTimed(
ctx,
'rc.profile',
async () => {
bootOk = await runProfileRc(ctx, profileName)
},
stageLog
)
} else {
stageLog.push('rc.profile(skipped)')
}
if (!bootOk) {
await maybeWriteBootPerfJson(ctx, bootT0, stageLog)
return
}
if (!shouldSkipBootStage(ctx, 'rc')) {
await bootTimed(
ctx,
'rc',
async () => {
bootOk = await runRcFileAt(ctx, '/etc/bare-os/rc', 'rc')
},
stageLog
)
} else {
stageLog.push('rc(skipped)')
}
if (!bootOk) {
await maybeWriteBootPerfJson(ctx, bootT0, stageLog)
return
}
if (!shouldSkipBootStage(ctx, 'rc.d')) {
await bootTimed(
ctx,
'rc.d',
async () => {
bootOk = await runBareOsRcDir(ctx)
},
stageLog
)
} else {
stageLog.push('rc.d(skipped)')
}
if (!bootOk) {
await maybeWriteBootPerfJson(ctx, bootT0, stageLog)
return
}
if (!shouldSkipBootStage(ctx, 'rc.local')) {
await bootTimed(
ctx,
'rc.local',
async () => {
bootOk = await runRcFileAt(ctx, '/etc/bare-os/rc.local', 'rc.local')
},
stageLog
)
} else {
stageLog.push('rc.local(skipped)')
}
if (!bootOk) {
await maybeWriteBootPerfJson(ctx, bootT0, stageLog)
return
}
if (!shouldSkipBootStage(ctx, 'kernel.d')) {
await bootTimed(
ctx,
'kernel.d',
async () => {
bootOk = await runBareOsKernelDir(ctx)
},
stageLog
)
} else {
stageLog.push('kernel.d(skipped)')
}
if (!bootOk) {
await maybeWriteBootPerfJson(ctx, bootT0, stageLog)
return
}
if (!shouldSkipBootStage(ctx, 'kernel.ext.d')) {
await bootTimed(
ctx,
'kernel.ext.d',
async () => {
bootOk = await runKernelExtDropins(ctx)
},
stageLog
)
} else {
stageLog.push('kernel.ext.d(skipped)')
}
if (!bootOk) {
await maybeWriteBootPerfJson(ctx, bootT0, stageLog)
return
}
await bootTimed(
ctx,
'banner',
async () => {
await printSessionBanner(ctx)
},
stageLog
)
if (!shouldSkipBootStage(ctx, 'onboot')) {
await bootTimed(
ctx,
'onboot',
async () => {
bootOk = await runOnboot(ctx)
},
stageLog
)
} else {
stageLog.push('onboot(skipped)')
}
if (!bootOk) {
await maybeWriteBootPerfJson(ctx, bootT0, stageLog)
return
}
await bootTimed(
ctx,
'selftest',
async () => {
bootOk = await runKernelSelftest(ctx)
},
stageLog
)
if (!bootOk) {
await maybeWriteBootPerfJson(ctx, bootT0, stageLog)
return
}
publishBootReady(ctx, stageLog)
await maybeWriteBootPerfJson(ctx, bootT0, stageLog)
if (kernelExtHotReloadEnabled(ctx)) {
ctx.bareOsReloadKernelExtDropinsSafe = async () => {
if (!kernelExtHotReloadEnabled(ctx)) {
return { ok: false, reason: 'env_disabled', atMs: Date.now() }
}
/** @type {string[]} */
const ran = []
const ok = await runKernelExtDropins(ctx, {
incremental: true,
ranScripts: ran
})
await maybeAppendKernelExtReloadJournal(ctx, {
ok,
incremental: true,
ranScripts: ran,
sessionId: String((ctx.env && ctx.env.BARE_OS_SESSION_ID) || '')
})
return { ok, ranScripts: ran, atMs: Date.now() }
}
}
{
/** @type {{ kind: string, code: string, wallMs: number, limitMs: number }[]} */
let bootBudgetViolationsForSummary = []
const budgetStrict =
ctx.env?.BARE_OS_BOOT_BUDGET_STRICT === '1' ||
ctx.env?.BARE_OS_BOOT_BUDGET_STRICT === 'true'
const polStrict =
ctx.env?.BARE_OS_BOOT_POLICY_STRICT === '1' ||
ctx.env?.BARE_OS_BOOT_POLICY_STRICT === 'true'
let coldExceeded = false
let stdlibExceeded = false
const budget = Number.parseInt(
String(ctx.env?.BARE_OS_BOOT_BUDGET_MS_COLD || ''),
10
)
if (Number.isFinite(budget) && budget > 0) {
const wall = Date.now() - bootT0
if (wall > budget) {
coldExceeded = true
bootStructuredLog(
ctx,
'error',
'bootBudgetColdExceeded',
`[boot] cold wall ${wall}ms exceeds BARE_OS_BOOT_BUDGET_MS_COLD=${budget}ms`
)
if (ctx.env) {
ctx.env.BARE_OS_BOOT_BUDGET_COLD_EXCEEDED = '1'
ctx.env.BARE_OS_BOOT_BUDGET_COLD_WALL_MS = String(wall)
ctx.env.BARE_OS_BOOT_BUDGET_COLD_LIMIT_MS = String(budget)
}
}
}
const sb = Number.parseInt(
String(ctx.env?.BARE_OS_BOOT_BUDGET_MS_BARE_STDLIB || ''),
10
)
if (Number.isFinite(sb) && sb > 0) {
const sw = Number.parseInt(
String(ctx.env?.BARE_OS_BOOT_BARE_STDLIB_RESOLUTION_MS || ''),
10
)
if (Number.isFinite(sw) && sw > sb) {
stdlibExceeded = true
bootStructuredLog(
ctx,
'error',
'bootBudgetBareStdlibExceeded',
`[boot] bare stdlib resolution ${sw}ms exceeds BARE_OS_BOOT_BUDGET_MS_BARE_STDLIB=${sb}ms`
)
if (ctx.env) {
ctx.env.BARE_OS_BOOT_BUDGET_STDLIB_EXCEEDED = '1'
ctx.env.BARE_OS_BOOT_BUDGET_STDLIB_WALL_MS = String(sw)
ctx.env.BARE_OS_BOOT_BUDGET_STDLIB_LIMIT_MS = String(sb)
}
}
}
if (coldExceeded || stdlibExceeded) {
/** @type {{ kind: string, code: string, wallMs: number, limitMs: number }[]} */
const violations = []
if (coldExceeded && Number.isFinite(budget) && budget > 0) {
violations.push({
kind: 'cold',
code: 'BARE_OS_BOOT_BUDGET_COLD_EXCEEDED',
wallMs: Date.now() - bootT0,
limitMs: budget
})
}
if (stdlibExceeded && Number.isFinite(sb) && sb > 0) {
const sw = Number.parseInt(
String(ctx.env?.BARE_OS_BOOT_BARE_STDLIB_RESOLUTION_MS || ''),
10
)
violations.push({
kind: 'bare_stdlib',
code: 'BARE_OS_BOOT_BUDGET_BARE_STDLIB_EXCEEDED',
wallMs: Number.isFinite(sw) ? sw : 0,
limitMs: sb
})
}
await maybeAppendBootTransactionJournal(ctx, {
phase: 'boot.budget',
stage: 'boot.budget',
bootStage: 'budget',
ms: 0,
ok: false,
bootBudgetViolation: true,
bootBudgetSchemaVersion: 2,
coldBudgetExceeded: coldExceeded,
bareStdlibBudgetExceeded: stdlibExceeded,
bootBudgetViolations: violations,
transactionState: BARE_OS_BOOT_TXN_STATE.STAGE_COMMITTED
})
bootBudgetViolationsForSummary = violations
}
await maybeWriteBootBudgetSummaryJson(
ctx,
bootT0,
bootBudgetViolationsForSummary,
coldExceeded,
stdlibExceeded,
stageLog
)
if (budgetStrict && polStrict && (coldExceeded || stdlibExceeded)) {
bootStructuredLog(
ctx,
'error',
'bootBudgetStrictAbort',
'[boot] BARE_OS_BOOT_BUDGET_STRICT with BARE_OS_BOOT_POLICY_STRICT: exiting after budget violation'
)
if (typeof ctx.bareOsRequestBooterExit === 'function')
ctx.bareOsRequestBooterExit(1)
return
}
}
while (true) {
const line = await readLine('')
if (line == null) break
const t = line.trim()
if (t === '') continue
let status = 'ok'
try {
status = await execLine(t)
} catch (e) {
bootStructuredLog(
ctx,
'error',
'replExecLineThrown',
(e && e.message) || String(e)
)
}
if (status === 'exit') break
}
}