/** * Declarative kernel boot stage graph for `/proc/bare_os/boot_graph.json`. * Mirrors the default sequence in kernel/init (trusted boot path). */ const DEFAULT_BOOT_STAGES = Object.freeze([ 'boot.policy', 'os-release', 'motd', 'rc.profile', 'rc', 'rc.d', 'rc.local', 'kernel.d', 'kernel.ext.d', 'onboot', 'session.banner', 'kernel.selftest', 'repl' ]) /** * @param {{ bootReadyJson?: () => string, stageMsHistogram?: Record }} [opts] */ export function buildBareOsBootGraphProcJson(opts = {}) { const nodes = DEFAULT_BOOT_STAGES.map((id, i) => ({ id, order: i, bootStage: bootStageForKernelLabel(id) })) /** @type {{ from: string, to: string, kind: string }[]} */ const edges = [] for (let i = 0; i < nodes.length - 1; i++) { edges.push({ from: nodes[i].id, to: nodes[i + 1].id, kind: 'sequence' }) } let ready = {} try { const t = opts.bootReadyJson && typeof opts.bootReadyJson === 'function' ? opts.bootReadyJson() : '' ready = t ? JSON.parse(String(t).trim() || '{}') : {} } catch { ready = {} } const hist = opts.stageMsHistogram && typeof opts.stageMsHistogram === 'object' ? opts.stageMsHistogram : {} return { schema: 1, note: 'Kernel boot stage edges (declarative); latency histogram is populated when journal export is enabled.', nodes, edges, stageMsHistogram: hist, bootReady: ready, atMs: Date.now() } } /** * @param {string} label */ function bootStageForKernelLabel(label) { const s = String(label || '').toLowerCase() if (s === 'boot.policy') return 'policy' if (s === 'os-release' || s === 'motd') return 'preflight' if (s.startsWith('rc') || s === 'kernel.d' || s === 'kernel.ext.d') return 'rc' if (s === 'onboot') return 'onboot' if (s.includes('selftest')) return 'selftest' if (s.includes('repl') || s.includes('banner')) return 'shell' return 'other' }