Add fifth feature word (STOCK_V5 / bits5) with ADR and capability docs.

Protocol: canonical seed RPC registry (seed-rpc-methods.js), bits5 on
capabilities, typed seed RPC errors, richer replication_queue and
staging_slot hints.

Booter: /proc host_os (bare-module on Bare, node:os on Node), sync_window,
debug.json, net_summary transport stats, HDMS hints/correlation, warm
profile reload, subprocess bridge snapshot helpers, boot policy v5 hooks,
BARE_OS_BIN_WORKER_ALLOW pattern groups, VFS symlink/union alignment, OTel
JSONL schema version 2 in var-log.

Seeder: pass staging/replication hints into seed channel; mirror kernel
init and boot policy example.

Kernel: enforce requireFeatureBits5 / requireInitJsSha256 when configured;
selftests for new proc surfaces.

CI/pretest: verify-doc-links, verify-man-coverage, verify-compat-matrix;
extend roadmap/ctx/dts verifiers. Add otel-bare-os-jsonl schema.

Docs: Wave 5 roadmap, kernel-extensions, handbook/devguide updates;
bare-module manifest tier/risk sample; bare-libs README.
This commit is contained in:
Raven Scott
2026-04-04 04:33:25 -04:00
parent f8a0dad897
commit 268b46dd3a
60 changed files with 1607 additions and 499 deletions
+2 -2
View File
@@ -10,9 +10,9 @@ Shared **wire format and constants** for the Bare operating system monorepo: Hyp
| `topicKey()` | 32-byte topic for `swarm.join()` |
| `BLOCK_SIZE`, `MBR_MAGIC` | 512-byte MBR, magic `BIOS` at offset 0 |
| `buildMbr` / `parseMbr` | Pack/unpack primary + optional failover Hyperdrive keys |
| `setupSeedChannel` | Wire Protomux messages 06 for RAM block reads, gossip bitfield, manifest path **search**, **RPC** (incl. `bare_os.capabilities` with **`bits`/`bits2`/`bits3`/`bits4`**, `bare_os.replication_status`, `bare_os.replication_queue`, `bare_os.capability_attestation`, `bare_os.mbr_layout`, `bare_os.manifest_hints`, `bare_os.peer_health`, `bare_os.staging_slot`, `bare_os.snapshot_hints`, `bare_os.peer_firewall_stats`, `bare_os.gossip`), and `drive.replicate` |
| `setupSeedChannel` | Wire Protomux messages 06 for RAM block reads, gossip bitfield, manifest path **search**, **RPC** (incl. `bare_os.capabilities` with **`bits`/`bits2`/`bits3`/`bits4`/`bits5`**, typed errors for unknown RPC methods, `bare_os.replication_status`, `bare_os.replication_queue`, `bare_os.capability_attestation`, `bare_os.mbr_layout`, `bare_os.manifest_hints`, `bare_os.peer_health`, `bare_os.staging_slot`, `bare_os.snapshot_hints`, `bare_os.peer_firewall_stats`, `bare_os.gossip`), and `drive.replicate` |
Subpath exports: `bare-os-protocol/constants.js`, `bare-os-protocol/messages` (compact-encoding schemas), `bare-os-protocol/kernel-feature-bits.js` (documented booter capability words **`STOCK_V1`** / **`STOCK_V2`** / **`STOCK_V3`** / **`STOCK_V4`**; surfaced in **`/proc/bare_os_features`** and **`/proc/bare_os/`**), `bare-os-protocol/protocol-meta.js` (**`BARE_OS_PROTOCOL_PACKAGE_VERSION`** for the seed handshake).
Subpath exports: `bare-os-protocol/constants.js`, `bare-os-protocol/messages` (compact-encoding schemas), `bare-os-protocol/kernel-feature-bits.js` (documented booter capability words **`STOCK_V1`** **`STOCK_V5`**; surfaced in **`/proc/bare_os_features`** and **`/proc/bare_os/`**), `bare-os-protocol/lib/seed-rpc-methods.js` (authoritative **`bare_os.*`** RPC name list for **`kernel_info`**), `bare-os-protocol/protocol-meta.js` (**`BARE_OS_PROTOCOL_PACKAGE_VERSION`** for the seed handshake).
## Consumers
+23 -1
View File
@@ -9,6 +9,11 @@ export {
} from './constants.js'
export { setupSeedChannel } from './lib/channel.js'
export {
BARE_OS_SEED_RPC_METHODS,
BARE_OS_SEED_RPC_METHOD_SHORT_NAMES,
BARE_OS_SEED_RPC_METHOD_SHORT_NAME_SET
} from './lib/seed-rpc-methods.js'
export { BARE_OS_PROTOCOL_PACKAGE_VERSION } from './lib/protocol-meta.js'
export {
BARE_OS_KERNEL_FEATURE_BITS_DOC,
@@ -93,5 +98,22 @@ export {
BARE_OS_FEATURE4_INITD_CONDITION_DIRECTORY,
BARE_OS_FEATURE4_DELEGATE_FAIRNESS_METRICS,
BARE_OS_FEATURE4_BIN_WORKER_ACTIVE,
BARE_OS_FEATURE4_SUBPROCESS_JOB_SURFACE
BARE_OS_FEATURE4_SUBPROCESS_JOB_SURFACE,
BARE_OS_KERNEL_FEATURES_STOCK_V5,
BARE_OS_FEATURE5_HOST_BARE_OS_PROC,
BARE_OS_FEATURE5_SUBPROCESS_BRIDGE_SNAPSHOT_V2,
BARE_OS_FEATURE5_NET_SUMMARY_TRANSPORT,
BARE_OS_FEATURE5_BOOT_POLICY_V5,
BARE_OS_FEATURE5_REPLICATION_SYNC_WINDOWS,
BARE_OS_FEATURE5_VFS_UNION_READLINK,
BARE_OS_FEATURE5_KERNEL_PROFILE_WARM,
BARE_OS_FEATURE5_HDMS_OPS_HINTS_V2,
BARE_OS_FEATURE5_TELEMETRY_OTEL_V2,
BARE_OS_FEATURE5_BIN_WORKER_PATTERN_ALLOW,
BARE_OS_FEATURE5_STAGING_ROLLBACK_HINTS,
BARE_OS_FEATURE5_KERNEL_DEBUG_PROC,
BARE_OS_FEATURE5_BARE_MANIFEST_RISK,
BARE_OS_FEATURE5_REPLICATION_QUEUE_METRICS_V2,
BARE_OS_FEATURE5_SEED_RPC_TYPED_ERRORS,
BARE_OS_FEATURE5_REPO_DOC_CI
} from './lib/kernel-feature-bits.js'
+65 -19
View File
@@ -6,8 +6,13 @@ import {
BARE_OS_KERNEL_FEATURES_STOCK_V1,
BARE_OS_KERNEL_FEATURES_STOCK_V2,
BARE_OS_KERNEL_FEATURES_STOCK_V3,
BARE_OS_KERNEL_FEATURES_STOCK_V4
BARE_OS_KERNEL_FEATURES_STOCK_V4,
BARE_OS_KERNEL_FEATURES_STOCK_V5
} from './kernel-feature-bits.js'
import {
BARE_OS_SEED_RPC_METHODS,
BARE_OS_SEED_RPC_METHOD_SHORT_NAME_SET
} from './seed-rpc-methods.js'
import { BARE_OS_PROTOCOL_PACKAGE_VERSION } from './protocol-meta.js'
import {
msgDataEncoding,
@@ -31,6 +36,9 @@ import {
* attestationJson?: string,
* snapshotHintsJson?: string,
* peerFirewallStatsJson?: string,
* replicationQueueDepthHint?: number,
* replicationSnapshotNoteJson?: string,
* stagingPreviousSlot?: string,
* drive?: { core?: { length?: number }, id?: Uint8Array }
* }} [opts]
*/
@@ -50,6 +58,9 @@ export function setupSeedChannel(mux, localRAM, replicateDrive, opts = {}) {
const stagingPendingSlot = String(
opts.stagingPendingSlot ?? opts.stagingPending ?? ''
).trim()
const stagingPreviousSlot = String(opts.stagingPreviousSlot ?? '')
.trim()
.toLowerCase()
const searchMax =
typeof opts.searchMaxMatches === 'number' && opts.searchMaxMatches > 0
? Math.min(opts.searchMaxMatches, 2000)
@@ -95,6 +106,30 @@ export function setupSeedChannel(mux, localRAM, replicateDrive, opts = {}) {
chan.addMessage({
encoding: msgRpcReqEncoding,
onmessage(m) {
if (m.module !== 'bare_os') {
chan.messages[6].send({
id: m.id,
success: false,
result: '',
error:
m.module == null || m.module === ''
? 'bare_os.rpc_missing_module'
: 'bare_os.rpc_wrong_module'
})
return
}
{
const meth = String(m.method ?? '').trim()
if (!BARE_OS_SEED_RPC_METHOD_SHORT_NAME_SET.has(meth)) {
chan.messages[6].send({
id: m.id,
success: false,
result: '',
error: 'bare_os.rpc_unknown_method'
})
return
}
}
if (m.module === 'bare_os' && m.method === 'version') {
chan.messages[6].send({
id: m.id,
@@ -126,22 +161,7 @@ export function setupSeedChannel(mux, localRAM, replicateDrive, opts = {}) {
success: true,
result: JSON.stringify({
protocol: PROTOCOL_NAME,
rpc: [
'bare_os.version',
'bare_os.health',
'bare_os.kernel_info',
'bare_os.capabilities',
'bare_os.gossip',
'bare_os.replication_status',
'bare_os.manifest_hints',
'bare_os.peer_health',
'bare_os.staging_slot',
'bare_os.replication_queue',
'bare_os.capability_attestation',
'bare_os.mbr_layout',
'bare_os.snapshot_hints',
'bare_os.peer_firewall_stats'
],
rpc: BARE_OS_SEED_RPC_METHODS,
note: 'Kernel and image semver are resolved at boot on the booter; this channel is seeder-local.'
}),
error: ''
@@ -159,6 +179,7 @@ export function setupSeedChannel(mux, localRAM, replicateDrive, opts = {}) {
bits2: BARE_OS_KERNEL_FEATURES_STOCK_V2 >>> 0,
bits3: BARE_OS_KERNEL_FEATURES_STOCK_V3 >>> 0,
bits4: BARE_OS_KERNEL_FEATURES_STOCK_V4 >>> 0,
bits5: BARE_OS_KERNEL_FEATURES_STOCK_V5 >>> 0,
protocolPackageVersion: BARE_OS_PROTOCOL_PACKAGE_VERSION,
role: 'seeder',
protocol: PROTOCOL_NAME
@@ -239,6 +260,9 @@ export function setupSeedChannel(mux, localRAM, replicateDrive, opts = {}) {
protocol: PROTOCOL_NAME,
activeSlot: stagingActiveSlot,
pendingSlot: stagingPendingSlot || null,
previousSlot: stagingPreviousSlot || null,
rollbackHint:
'pending slot is rollback candidate when switching A/B; verify image before activate',
atMs: Date.now()
}),
error: ''
@@ -254,6 +278,24 @@ export function setupSeedChannel(mux, localRAM, replicateDrive, opts = {}) {
} catch {
/* ignore */
}
const depthHint =
typeof opts.replicationQueueDepthHint === 'number' &&
opts.replicationQueueDepthHint >= 0
? Math.floor(opts.replicationQueueDepthHint)
: manifestPaths.length
let snapshotNote = ''
const snapRaw = String(opts.replicationSnapshotNoteJson ?? '').trim()
if (snapRaw) {
try {
const o = JSON.parse(snapRaw)
snapshotNote =
o && typeof o === 'object' && typeof o.note === 'string'
? o.note.slice(0, 256)
: 'snapshot-hint-json'
} catch {
snapshotNote = 'invalid replicationSnapshotNoteJson'
}
}
chan.messages[6].send({
id: m.id,
success: true,
@@ -263,7 +305,11 @@ export function setupSeedChannel(mux, localRAM, replicateDrive, opts = {}) {
manifestPathCount: manifestPaths.length,
localRamBlockCount: localRAM.size,
hypercoreLengthHint: coreLength,
note: 'hypercoreLengthHint is seeder-local; not a full replication queue.',
queueDepthEstimate: depthHint,
snapshotWorkflowNote:
snapshotNote ||
'Align long replication with corestore-snapshot-style cutover; guest does not verify crypto.',
note: 'hypercoreLengthHint and queueDepthEstimate are seeder-local hints only.',
atMs: Date.now()
}),
error: ''
@@ -373,7 +419,7 @@ export function setupSeedChannel(mux, localRAM, replicateDrive, opts = {}) {
id: m.id,
success: false,
result: '',
error: 'RPC not implemented on seeder'
error: 'bare_os.rpc_internal_unreachable'
})
}
})
@@ -4,7 +4,7 @@
*/
/** Protocol document version for this bitmask file (bump when bit semantics or governance changes). */
export const BARE_OS_KERNEL_FEATURE_BITS_DOC = 6
export const BARE_OS_KERNEL_FEATURE_BITS_DOC = 7
/**
* Second capability word (bits 031, always use `>>> 0` when masking).
@@ -226,6 +226,61 @@ export const BARE_OS_KERNEL_FEATURES_STOCK_V4 =
BARE_OS_FEATURE4_BIN_WORKER_ACTIVE |
BARE_OS_FEATURE4_SUBPROCESS_JOB_SURFACE
/**
* Fifth capability word (bits 031, use `>>> 0`). Wave 5 — ADR 001 §8.
*/
/** Word5 bit 0: `/proc/bare_os/host_os.json` (`BARE_OS_HOST_BARE_OS_PROC` / `BARE_OS_HOST_OS_JSON`). */
export const BARE_OS_FEATURE5_HOST_BARE_OS_PROC = 1 << 0
/** Word5 bit 1: `bareOsReadSubprocessBridgeSnapshot` + `BARE_OS_SUBPROCESS_BRIDGE_META_JSON`. */
export const BARE_OS_FEATURE5_SUBPROCESS_BRIDGE_SNAPSHOT_V2 = 1 << 1
/** Word5 bit 2: Transport counters in net summary (`BARE_OS_NET_TRANSPORT_STATS_JSON`). */
export const BARE_OS_FEATURE5_NET_SUMMARY_TRANSPORT = 1 << 2
/** Word5 bit 3: Boot policy v5 (`requireFeatureBits5`, `requireInitJsSha256`). */
export const BARE_OS_FEATURE5_BOOT_POLICY_V5 = 1 << 3
/** Word5 bit 4: Replication sync windows + `/proc/bare_os/sync_window.json`. */
export const BARE_OS_FEATURE5_REPLICATION_SYNC_WINDOWS = 1 << 4
/** Word5 bit 5: Union readlink shadow lookup on personal drive. */
export const BARE_OS_FEATURE5_VFS_UNION_READLINK = 1 << 5
/** Word5 bit 6: Warm profile reload (`BARE_OS_KERNEL_PROFILE_WARM`, `bareOsRequestKernelProfileReload`). */
export const BARE_OS_FEATURE5_KERNEL_PROFILE_WARM = 1 << 6
/** Word5 bit 7: HDMS hints v2 (`BARE_OS_HDMS_SUPPORT_CORRELATION_ID`). */
export const BARE_OS_FEATURE5_HDMS_OPS_HINTS_V2 = 1 << 7
/** Word5 bit 8: OTel JSONL schema v2 lines. */
export const BARE_OS_FEATURE5_TELEMETRY_OTEL_V2 = 1 << 8
/** Word5 bit 9: `BARE_OS_BIN_WORKER_ALLOW` pattern groups (`textproc:*`, …). */
export const BARE_OS_FEATURE5_BIN_WORKER_PATTERN_ALLOW = 1 << 9
/** Word5 bit 10: Staging rollback hints (`BARE_OS_SEED_STAGING_PREVIOUS_SLOT`). */
export const BARE_OS_FEATURE5_STAGING_ROLLBACK_HINTS = 1 << 10
/** Word5 bit 11: `/proc/bare_os/debug.json` when `BARE_OS_KERNEL_DEBUG=1`. */
export const BARE_OS_FEATURE5_KERNEL_DEBUG_PROC = 1 << 11
/** Word5 bit 12: Manifest / catalog `risk` metadata for `ctx.bare`. */
export const BARE_OS_FEATURE5_BARE_MANIFEST_RISK = 1 << 12
/** Word5 bit 13: Replication queue metrics v2 on seeder RPC. */
export const BARE_OS_FEATURE5_REPLICATION_QUEUE_METRICS_V2 = 1 << 13
/** Word5 bit 14: Typed seed RPC errors (`bare_os.rpc_unknown_method`). */
export const BARE_OS_FEATURE5_SEED_RPC_TYPED_ERRORS = 1 << 14
/** Word5 bit 15: Repo doc CI scripts (man coverage, compat matrix, doc links). */
export const BARE_OS_FEATURE5_REPO_DOC_CI = 1 << 15
/** Stock booter fifth word (wave 5). */
export const BARE_OS_KERNEL_FEATURES_STOCK_V5 =
BARE_OS_FEATURE5_HOST_BARE_OS_PROC |
BARE_OS_FEATURE5_SUBPROCESS_BRIDGE_SNAPSHOT_V2 |
BARE_OS_FEATURE5_NET_SUMMARY_TRANSPORT |
BARE_OS_FEATURE5_BOOT_POLICY_V5 |
BARE_OS_FEATURE5_REPLICATION_SYNC_WINDOWS |
BARE_OS_FEATURE5_VFS_UNION_READLINK |
BARE_OS_FEATURE5_KERNEL_PROFILE_WARM |
BARE_OS_FEATURE5_HDMS_OPS_HINTS_V2 |
BARE_OS_FEATURE5_TELEMETRY_OTEL_V2 |
BARE_OS_FEATURE5_BIN_WORKER_PATTERN_ALLOW |
BARE_OS_FEATURE5_STAGING_ROLLBACK_HINTS |
BARE_OS_FEATURE5_KERNEL_DEBUG_PROC |
BARE_OS_FEATURE5_BARE_MANIFEST_RISK |
BARE_OS_FEATURE5_REPLICATION_QUEUE_METRICS_V2 |
BARE_OS_FEATURE5_SEED_RPC_TYPED_ERRORS |
BARE_OS_FEATURE5_REPO_DOC_CI
/** Bit 0: IPC fan-out / pub-sub style channels (booter `bareOsIpc`). */
export const BARE_OS_FEATURE_IPC_FANOUT = 1 << 0
@@ -0,0 +1,30 @@
/**
* Single source of truth for `bare_os.*` seed RPC method names (short form, without `bare_os.` prefix).
* Used by `channel.js` for `kernel_info` and unknown-method handling.
*/
export const BARE_OS_SEED_RPC_METHOD_SHORT_NAMES = [
'version',
'health',
'kernel_info',
'capabilities',
'replication_status',
'gossip',
'manifest_hints',
'peer_health',
'staging_slot',
'replication_queue',
'capability_attestation',
'mbr_layout',
'snapshot_hints',
'peer_firewall_stats'
]
/** @type {Set<string>} */
export const BARE_OS_SEED_RPC_METHOD_SHORT_NAME_SET = new Set(
BARE_OS_SEED_RPC_METHOD_SHORT_NAMES
)
/** Full dotted names for documentation / tests. */
export const BARE_OS_SEED_RPC_METHODS = BARE_OS_SEED_RPC_METHOD_SHORT_NAMES.map(
(m) => 'bare_os.' + m
)
+16
View File
@@ -8,6 +8,11 @@ import {
BLOCK_SIZE,
TOPIC_STRING
} from './constants.js'
import {
BARE_OS_SEED_RPC_METHOD_SHORT_NAMES,
BARE_OS_SEED_RPC_METHODS
} from './lib/seed-rpc-methods.js'
import { BARE_OS_KERNEL_FEATURES_STOCK_V5 } from './lib/kernel-feature-bits.js'
import { msgDataEncoding, msgSearchReqEncoding } from './lib/messages.js'
test('topicKey is deterministic 32-byte hash', (t) => {
const a = topicKey()
@@ -60,3 +65,14 @@ test('msgSearchReqEncoding roundtrip', (t) => {
test('TOPIC_STRING is bare-os-v1', (t) => {
t.is(TOPIC_STRING, 'bare-os-v1')
})
test('seed RPC method list matches kernel_info surface', (t) => {
t.ok(BARE_OS_SEED_RPC_METHOD_SHORT_NAMES.includes('capabilities'))
t.ok(BARE_OS_SEED_RPC_METHOD_SHORT_NAMES.includes('replication_queue'))
t.is(BARE_OS_SEED_RPC_METHODS.length, BARE_OS_SEED_RPC_METHOD_SHORT_NAMES.length)
t.ok(BARE_OS_SEED_RPC_METHODS.every((m) => m.startsWith('bare_os.')))
})
test('STOCK_V5 is non-zero wave-5 advertisement', (t) => {
t.ok((BARE_OS_KERNEL_FEATURES_STOCK_V5 >>> 0) > 0)
})