feat(protocol)!: kernel capability wire v2 and ctx capability maps
Replace top-level seed/proc bits (bits, bits2, … bits11) with kernelCapabilityWords (semantic camelCase keys), kernelCapabilityWireVersion, and helpers in kernel-capability-wire.js. Bump bare-os-protocol to 0.9.0 and BARE_OS_KERNEL_FEATURE_BITS_DOC to 15. Booter: emit/consume v2 on bare_os.capabilities, /proc/bare_os_features, debug proc, offline LKG seedCapabilityInfo; BARE_OS_SEED_CAP_STRICT walks semantic keys. Guest ctx exposes frozen bareOsAdvertisedKernelCapabilityWords and bareOsSeedKernelCapabilityWords; remove per-word bareOsAdvertisedKernelCapabilities* and bareOsSeedCapability* (BARE_OS_CTX_API_VERSION 1.22.0). Kernel boot policy (stock init.js + seeder copy) reads advertised/seed words via those maps. Update bare-os-ctx.d.ts, CI verifiers, compatibility matrix, capability-words docs, ADR 001, and changelogs. Fix duplicate re-exports of EXTENDED_SEEDING_PLATFORM and RLIMITS_DELEGATES_SHELL in bare-os-protocol/index.js (Pear/Bare duplicate export error).
This commit is contained in:
@@ -0,0 +1,387 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* CI: kernel capability contract checks (wire v2 kernelCapabilityWords, seed RPC registry, boot policy keys).
|
||||
*/
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
|
||||
|
||||
function read(rel) {
|
||||
return fs.readFileSync(path.join(root, rel), 'utf8')
|
||||
}
|
||||
|
||||
function main() {
|
||||
const bits = read('packages/bare-os-protocol/lib/kernel-feature-bits.js')
|
||||
if (!bits.includes('BARE_OS_KERNEL_FEATURES_STOCK_WORD_OFFLINE_NET_EXTENSIONS')) {
|
||||
console.error(
|
||||
'kernel-feature-bits.js missing BARE_OS_KERNEL_FEATURES_STOCK_WORD_OFFLINE_NET_EXTENSIONS'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bits.includes('BARE_OS_KERNEL_FEATURES_STOCK_WORD_HOST_TRANSPORT_DELEGATES')) {
|
||||
console.error(
|
||||
'kernel-feature-bits.js missing BARE_OS_KERNEL_FEATURES_STOCK_WORD_HOST_TRANSPORT_DELEGATES'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bits.includes('BARE_OS_KERNEL_FEATURES_STOCK_WORD_REPLICATION_OPERATOR_SURFACE')) {
|
||||
console.error(
|
||||
'kernel-feature-bits.js missing BARE_OS_KERNEL_FEATURES_STOCK_WORD_REPLICATION_OPERATOR_SURFACE'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bits.includes('BARE_OS_KERNEL_FEATURES_STOCK_WORD_PEAR_CORESTORE_HRPC')) {
|
||||
console.error(
|
||||
'kernel-feature-bits.js missing BARE_OS_KERNEL_FEATURES_STOCK_WORD_PEAR_CORESTORE_HRPC'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bits.includes('BARE_OS_KERNEL_FEATURES_STOCK_WORD_BARE_RUNTIME_PROTO_MUX')) {
|
||||
console.error(
|
||||
'kernel-feature-bits.js missing BARE_OS_KERNEL_FEATURES_STOCK_WORD_BARE_RUNTIME_PROTO_MUX'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bits.includes('BARE_OS_KERNEL_FEATURES_STOCK_WORD_BARE_MODULE_CRYPTO_STAGING')) {
|
||||
console.error(
|
||||
'kernel-feature-bits.js missing BARE_OS_KERNEL_FEATURES_STOCK_WORD_BARE_MODULE_CRYPTO_STAGING'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bits.includes('BARE_OS_KERNEL_FEATURES_STOCK_WORD_PEAR_INSPECT_LOGGER_TLS')) {
|
||||
console.error(
|
||||
'kernel-feature-bits.js missing BARE_OS_KERNEL_FEATURES_STOCK_WORD_PEAR_INSPECT_LOGGER_TLS'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bits.includes('BARE_OS_KERNEL_FEATURES_STOCK_WORD_HYPERCORE_PACK_HRPC_LIFECYCLE')) {
|
||||
console.error(
|
||||
'kernel-feature-bits.js missing BARE_OS_KERNEL_FEATURES_STOCK_WORD_HYPERCORE_PACK_HRPC_LIFECYCLE'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bits.includes('BARE_OS_KERNEL_FEATURE_BITS_DOC = 15')) {
|
||||
console.error(
|
||||
'kernel-feature-bits.js: expected BARE_OS_KERNEL_FEATURE_BITS_DOC = 15'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bits.includes('BARE_OS_FEATURE4_OFFLINE_LKG_BOOT')) {
|
||||
console.error('kernel-feature-bits.js missing FEATURE4_OFFLINE_LKG_BOOT')
|
||||
process.exit(1)
|
||||
}
|
||||
const chan = read('packages/bare-os-protocol/lib/channel.js')
|
||||
if (!chan.includes('BARE_OS_KERNEL_CAPABILITY_WORDS_JSON_KEY')) {
|
||||
console.error(
|
||||
'channel.js capabilities must use BARE_OS_KERNEL_CAPABILITY_WORDS_JSON_KEY (wire v2)'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!chan.includes('buildKernelCapabilityWordsObject')) {
|
||||
console.error('channel.js must build capabilities via buildKernelCapabilityWordsObject')
|
||||
process.exit(1)
|
||||
}
|
||||
const seedRpc = read('packages/bare-os-protocol/lib/seed-rpc-methods.js')
|
||||
if (!seedRpc.includes('BARE_OS_SEED_RPC_METHOD_SHORT_NAMES')) {
|
||||
console.error('seed-rpc-methods.js missing method list')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!chan.includes('BARE_OS_SEED_RPC_METHODS')) {
|
||||
console.error('channel.js must use BARE_OS_SEED_RPC_METHODS for kernel_info')
|
||||
process.exit(1)
|
||||
}
|
||||
for (const rpc of [
|
||||
'replication_queue',
|
||||
'capability_attestation',
|
||||
'mbr_layout',
|
||||
'snapshot_hints',
|
||||
'peer_firewall_stats',
|
||||
'replication_plan',
|
||||
'dht_bootstrap_hint',
|
||||
'snapshot_chain',
|
||||
'mirror_compaction_hint',
|
||||
'updater_state',
|
||||
'blind_peer_topology_v2',
|
||||
'compact_ping',
|
||||
'corestore_stats',
|
||||
'snapshot_manifest_slice',
|
||||
'mirror_drive_hint_v2',
|
||||
'hrpc_registry_summary',
|
||||
'protomux_capability_ad',
|
||||
'dht_address_book',
|
||||
'replication_throttle_hint',
|
||||
'bundlebee_stage',
|
||||
'http_dht_proxy_hint',
|
||||
'protomux_rpc_pool_hint',
|
||||
'hyperblob_store_hint',
|
||||
'signing_request_queue_hint',
|
||||
'core_storage_layout_hint',
|
||||
'mirror_drive_compaction_v3',
|
||||
'bundlebee_cli_stage',
|
||||
'ready_guard_v2',
|
||||
'blind_relay_circuit_hint',
|
||||
'http_dht_proxy_routes',
|
||||
'pear_stage_hint',
|
||||
'updater_channel_matrix',
|
||||
'appling_bundle_pointer',
|
||||
'drive_resolve_policy',
|
||||
'bundle_id_fingerprint',
|
||||
'hyperdb_migration_hint',
|
||||
'sidecar_bundle_index_v2',
|
||||
'pear_message_queue_sketch',
|
||||
'runtime_bootstrap_etag',
|
||||
'force_update_guard',
|
||||
'gracedown_window',
|
||||
'tryboot_slot',
|
||||
'hotmods_allowlist',
|
||||
'prefetcher_budget',
|
||||
'opstream_backpressure',
|
||||
'multisig_link_pointer',
|
||||
'md_render_caps',
|
||||
'bundlebee_cli_stage_v2',
|
||||
'seed_manifest_diff_v2',
|
||||
'peer_handshake_latency_budget',
|
||||
'mirror_drive_compaction_v4',
|
||||
'ready_guard_v3',
|
||||
'blind_relay_circuit_v2',
|
||||
'http_dht_proxy_routes_v2',
|
||||
'pear_doctor_hint',
|
||||
'pear_info_sketch',
|
||||
'pear_inspect_caps',
|
||||
'pear_dump_budget',
|
||||
'pear_reset_guard',
|
||||
'pear_restart_window',
|
||||
'pear_run_flags',
|
||||
'pear_bundle_manifest_slice',
|
||||
'pear_pack_layout_hint',
|
||||
'pear_seed_topology',
|
||||
'pear_state_snapshot',
|
||||
'pear_stamp_pointer',
|
||||
'pear_shake_latency',
|
||||
'pear_crasher_class',
|
||||
'pear_errors_rate_hint',
|
||||
'pear_bridge_health',
|
||||
'pear_link_matrix',
|
||||
'pear_pipe_backpressure',
|
||||
'pear_opwait_budget',
|
||||
'pear_terminal_caps',
|
||||
'ready_guard_v4',
|
||||
'mirror_drive_compaction_v5',
|
||||
'blind_relay_circuit_v3',
|
||||
'compact_ping_v4',
|
||||
'hypercore_replicate_budget_v2',
|
||||
'drive_version_graph',
|
||||
'protomux_backpressure_v3',
|
||||
'pear_runtime_matrix',
|
||||
'bundle_preload_hint',
|
||||
'autopass_rotation_hint',
|
||||
'hrpc_method_allowlist',
|
||||
'sidecar_resource_cap',
|
||||
'git_lfs_budget',
|
||||
'net_qos_class',
|
||||
'storage_tier_hint',
|
||||
'indexer_catchup',
|
||||
'multisig_quorum_hint',
|
||||
'relay_geo_hint',
|
||||
'compact_ping_v5',
|
||||
'staging_slot_v8',
|
||||
'peer_firewall_stats_v6',
|
||||
'http_dht_proxy_routes_v3',
|
||||
'ready_guard_v5',
|
||||
'mirror_drive_compaction_v6'
|
||||
]) {
|
||||
if (!seedRpc.includes("'" + rpc + "'")) {
|
||||
console.error('seed-rpc-methods.js missing short name', rpc)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
const bootIdx = read('packages/bare-os-booter/index.js')
|
||||
if (!bootIdx.includes('BARE_OS_KERNEL_FEATURES_STOCK_WORD_OFFLINE_NET_EXTENSIONS')) {
|
||||
console.error(
|
||||
'booter index.js must import BARE_OS_KERNEL_FEATURES_STOCK_WORD_OFFLINE_NET_EXTENSIONS'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bootIdx.includes('BARE_OS_KERNEL_FEATURES_STOCK_WORD_HOST_TRANSPORT_DELEGATES')) {
|
||||
console.error(
|
||||
'booter index.js must import BARE_OS_KERNEL_FEATURES_STOCK_WORD_HOST_TRANSPORT_DELEGATES'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bootIdx.includes('BARE_OS_KERNEL_FEATURES_STOCK_WORD_REPLICATION_OPERATOR_SURFACE')) {
|
||||
console.error(
|
||||
'booter index.js must import BARE_OS_KERNEL_FEATURES_STOCK_WORD_REPLICATION_OPERATOR_SURFACE'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bootIdx.includes('BARE_OS_KERNEL_FEATURES_STOCK_WORD_PEAR_CORESTORE_HRPC')) {
|
||||
console.error(
|
||||
'booter index.js must import BARE_OS_KERNEL_FEATURES_STOCK_WORD_PEAR_CORESTORE_HRPC'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bootIdx.includes('BARE_OS_KERNEL_FEATURES_STOCK_WORD_BARE_RUNTIME_PROTO_MUX')) {
|
||||
console.error(
|
||||
'booter index.js must import BARE_OS_KERNEL_FEATURES_STOCK_WORD_BARE_RUNTIME_PROTO_MUX'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bootIdx.includes('BARE_OS_KERNEL_FEATURES_STOCK_WORD_BARE_MODULE_CRYPTO_STAGING')) {
|
||||
console.error(
|
||||
'booter index.js must import BARE_OS_KERNEL_FEATURES_STOCK_WORD_BARE_MODULE_CRYPTO_STAGING'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bootIdx.includes('BARE_OS_KERNEL_FEATURES_STOCK_WORD_PEAR_INSPECT_LOGGER_TLS')) {
|
||||
console.error(
|
||||
'booter index.js must import BARE_OS_KERNEL_FEATURES_STOCK_WORD_PEAR_INSPECT_LOGGER_TLS'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bootIdx.includes('BARE_OS_KERNEL_FEATURES_STOCK_WORD_HYPERCORE_PACK_HRPC_LIFECYCLE')) {
|
||||
console.error(
|
||||
'booter index.js must import BARE_OS_KERNEL_FEATURES_STOCK_WORD_HYPERCORE_PACK_HRPC_LIFECYCLE'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bootIdx.includes('KERNEL_CAPABILITY_SEED_STRICT_ROWS')) {
|
||||
console.error('booter must define KERNEL_CAPABILITY_SEED_STRICT_ROWS')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bootIdx.includes('kernelCapabilityWords.${key}')) {
|
||||
console.error('booter strict check must report kernelCapabilityWords.${key} failures')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bootIdx.includes('seeder capabilities missing kernelCapabilityWords')) {
|
||||
console.error('booter strict check must require kernelCapabilityWords object')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!bootIdx.includes('loadOsFromOfflineLkg')) {
|
||||
console.error('booter index.js must define loadOsFromOfflineLkg')
|
||||
process.exit(1)
|
||||
}
|
||||
const pol = read('docs/schemas/boot.policy.schema.json')
|
||||
if (!pol.includes('requireKernelCapabilitiesOfflineNetExtensions')) {
|
||||
console.error('boot.policy.schema.json missing requireKernelCapabilitiesOfflineNetExtensions')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!pol.includes('denyExecLineBuiltins')) {
|
||||
console.error('boot.policy.schema.json missing denyExecLineBuiltins')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!pol.includes('requireKernelCapabilitiesHostTransportDelegates')) {
|
||||
console.error('boot.policy.schema.json missing requireKernelCapabilitiesHostTransportDelegates')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!pol.includes('requireInitJsSha256')) {
|
||||
console.error('boot.policy.schema.json missing requireInitJsSha256')
|
||||
process.exit(1)
|
||||
}
|
||||
for (const k of [
|
||||
'requireKernelCapabilitiesReplicationOperatorSurface',
|
||||
'requireKernelCapabilitiesPearCorestoreHrpc',
|
||||
'requireKernelCapabilitiesBareRuntimeProtoMux',
|
||||
'requireKernelCapabilitiesBareModuleCryptoStaging',
|
||||
'requireKernelCapabilitiesPearInspectLoggerTls',
|
||||
'requireKernelCapabilitiesHypercorePackHrpcLifecycle',
|
||||
'requireBareBootMin',
|
||||
'denyBareRpcMethodPatterns',
|
||||
'maxPearInspectDepth',
|
||||
'maxHrpcAllowlistDepth',
|
||||
'requireBareLoggerMin',
|
||||
'denyAutobaseDiscoveryChannels',
|
||||
'requireBareTlsMin',
|
||||
'requireBarePackMin',
|
||||
'requireBareAddonPolicyMin',
|
||||
'extensionSignerPinsV3',
|
||||
'extensionSignerPinsV4',
|
||||
'offlineLkgRequirePearStamp',
|
||||
'offlineLkgRequireHypercorePackHrpcLifecycle',
|
||||
'bootPhasesRequireLifecycleMinSchema',
|
||||
'requirePearRuntimeRange',
|
||||
'denyBareModuleSpecifierPatterns',
|
||||
'requireBareCryptoMin',
|
||||
'denyKernelSyscalls',
|
||||
'requirePearIpcMin',
|
||||
'extensionSignerPinsV2',
|
||||
'offlineLkgManifestMaxAgeSec',
|
||||
'bootPhasesRequireProcIndexMinSchema',
|
||||
'requireBareRuntimeMin',
|
||||
'denySeedRpcMethods',
|
||||
'maxProtomuxChannelNameLength',
|
||||
'requireBooterSemver',
|
||||
'requireCtxApiMin',
|
||||
'requirePearRuntimeMin',
|
||||
'requireProtocolPackageMin',
|
||||
'denyKernelExtensionIds',
|
||||
'denyCtxMethodPrefixes',
|
||||
'maxKernelExtensionDepth',
|
||||
'gitPartialClonePolicy',
|
||||
'kernelExtensionHashPins',
|
||||
'offlineLkgIntegrityStrict'
|
||||
]) {
|
||||
if (!pol.includes('"' + k + '"')) {
|
||||
console.error('boot.policy.schema.json missing', k)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
const kInit = read('kernel/init.js')
|
||||
if (!kInit.includes('requireKernelCapabilitiesOfflineNetExtensions')) {
|
||||
console.error('kernel/init.js must enforce requireKernelCapabilitiesOfflineNetExtensions')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!kInit.includes('requireKernelCapabilitiesHostTransportDelegates')) {
|
||||
console.error('kernel/init.js must enforce requireKernelCapabilitiesHostTransportDelegates')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!kInit.includes('requireInitJsSha256')) {
|
||||
console.error('kernel/init.js must enforce requireInitJsSha256')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!kInit.includes('requireKernelCapabilitiesReplicationOperatorSurface')) {
|
||||
console.error('kernel/init.js must enforce requireKernelCapabilitiesReplicationOperatorSurface')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!kInit.includes('requireKernelCapabilitiesPearCorestoreHrpc')) {
|
||||
console.error('kernel/init.js must enforce requireKernelCapabilitiesPearCorestoreHrpc')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!kInit.includes('requireKernelCapabilitiesBareRuntimeProtoMux')) {
|
||||
console.error('kernel/init.js must enforce requireKernelCapabilitiesBareRuntimeProtoMux')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!kInit.includes('requireKernelCapabilitiesBareModuleCryptoStaging')) {
|
||||
console.error('kernel/init.js must enforce requireKernelCapabilitiesBareModuleCryptoStaging')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!kInit.includes('requireKernelCapabilitiesPearInspectLoggerTls')) {
|
||||
console.error('kernel/init.js must enforce requireKernelCapabilitiesPearInspectLoggerTls')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!kInit.includes('requireKernelCapabilitiesHypercorePackHrpcLifecycle')) {
|
||||
console.error('kernel/init.js must enforce requireKernelCapabilitiesHypercorePackHrpcLifecycle')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!kInit.includes('requireBareRuntimeMin')) {
|
||||
console.error('kernel/init.js must enforce requireBareRuntimeMin')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!kInit.includes('requirePearRuntimeMin')) {
|
||||
console.error('kernel/init.js must enforce requirePearRuntimeMin')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!kInit.includes('requireProtocolPackageMin')) {
|
||||
console.error('kernel/init.js must enforce requireProtocolPackageMin')
|
||||
process.exit(1)
|
||||
}
|
||||
if (!kInit.includes('requireBooterSemver')) {
|
||||
console.error('kernel/init.js must enforce requireBooterSemver')
|
||||
process.exit(1)
|
||||
}
|
||||
console.log('verify-kernel-capabilities-contract: OK')
|
||||
}
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user