feat: compile GLS protocols into native runtime guards

This commit is contained in:
冰朔 2026-08-17 16:22:56 +08:00
commit d6b1290e1c
13 changed files with 1909 additions and 6 deletions

View file

@ -0,0 +1,139 @@
import { createHash } from 'node:crypto'
import { readdir, readFile, writeFile } from 'node:fs/promises'
import path from 'node:path'
import process from 'node:process'
const args = new Map()
for (let index = 2; index < process.argv.length; index += 2) {
args.set(process.argv[index], process.argv[index + 1])
}
const sourceRoot = args.get('--source-root')
const sourceCommit = args.get('--source-commit')
const output = args.get('--output')
const projectionsPath = args.get('--projections')
if (!sourceRoot || !sourceCommit || !output || !projectionsPath) {
throw new Error('usage: compile-gls-runtime-registry.mjs --source-root <REPO-012/gls> --source-commit <sha> --output <registry.json> --projections <projections.json>')
}
if (!/^[a-f0-9]{40}$/.test(sourceCommit)) throw new Error('source commit must be a full SHA-1')
async function walk(directory, prefix = '') {
const entries = await readdir(directory, { withFileTypes: true })
const paths = []
for (const entry of entries) {
const relative = prefix ? `${prefix}/${entry.name}` : entry.name
if (entry.isDirectory()) paths.push(...await walk(path.join(directory, entry.name), relative))
else paths.push(relative)
}
return paths
}
function sourceRank(relative) {
if (!relative.includes('/')) return 0
if (relative.startsWith('standards/')) return 1
if (relative.includes('/notion-export/')) return 3
return 2
}
function cleanHeading(line, id) {
return line
.replace(/^#+\s*/, '')
.replaceAll('**', '')
.replace(new RegExp(`^${id}\\s*[·:-]?\\s*`), '')
.trim() || id
}
function sourceStatus(raw) {
const line = raw.split(/\r?\n/, 100).find((item) => /^\s*(?:>|[-*]\s*)?(?:状态|Status)\s*[:]/i.test(item))
if (!line) return 'UNSPECIFIED_SOURCE_STATUS'
return line.replace(/^\s*(?:>|[-*]\s*)?(?:状态|Status)\s*[:]\s*/i, '').replaceAll('`', '').trim()
}
const projectionManifest = JSON.parse(await readFile(projectionsPath, 'utf8'))
if (projectionManifest.schema !== 'hololake.gls-executable-projections/v1' || projectionManifest.source_commit !== sourceCommit) {
throw new Error('projection manifest does not match the selected REPO-012 source commit')
}
const candidates = (await walk(sourceRoot))
.map((relative) => ({ relative, match: path.basename(relative).match(/^(GLS-\d{4}).*\.hdlp$/) }))
.filter((item) => item.match)
.map((item) => ({ id: item.match[1], relative: item.relative }))
const grouped = new Map()
for (const candidate of candidates) {
const group = grouped.get(candidate.id) || []
group.push(candidate.relative)
grouped.set(candidate.id, group)
}
const protocols = []
for (const [id, sources] of [...grouped.entries()].sort(([left], [right]) => left.localeCompare(right))) {
sources.sort((left, right) => sourceRank(left) - sourceRank(right) || left.localeCompare(right))
const relative = sources[0]
const raw = await readFile(path.join(sourceRoot, relative), 'utf8')
const heading = raw.split(/\r?\n/).find((line) => line.startsWith('#') && line.includes(id))
const projection = projectionManifest.projections[id]
protocols.push({
id,
title: cleanHeading(heading || id, id),
source_status: sourceStatus(raw),
source_path: `gls/${relative}`,
source_sha256: createHash('sha256').update(raw).digest('hex'),
alternate_source_count: sources.length - 1,
projection_state: projection ? 'EXECUTABLE_PROJECTION' : 'INVENTORIED_NOT_EXECUTABLE',
projection_kind: projection?.projection_kind || null,
adapter: projection?.adapter || null,
event_kinds: projection?.event_kinds || [],
dependencies: projection?.dependencies || [],
})
}
const known = new Set(protocols.map((protocol) => protocol.id))
for (const [id, projection] of Object.entries(projectionManifest.projections)) {
if (!known.has(id)) throw new Error(`projection references an unknown protocol: ${id}`)
for (const dependency of projection.dependencies) {
if (!projectionManifest.projections[dependency]) {
throw new Error(`${id} depends on a protocol without an executable projection: ${dependency}`)
}
}
}
const visiting = new Set()
const visited = new Set()
function visit(id) {
if (visiting.has(id)) throw new Error(`executable protocol dependency cycle at ${id}`)
if (visited.has(id)) return
visiting.add(id)
for (const dependency of projectionManifest.projections[id].dependencies) visit(dependency)
visiting.delete(id)
visited.add(id)
}
for (const id of Object.keys(projectionManifest.projections)) visit(id)
const executableCount = protocols.filter((protocol) => protocol.projection_state === 'EXECUTABLE_PROJECTION').length
const registry = {
schema: 'hololake.gls-protocol-runtime-registry/v1',
record_id: 'HLP-GLS-PROTOCOL-RUNTIME-001',
source: {
repository: 'REPO-012',
commit: sourceCommit,
root: 'gls',
},
compiler: {
source_protocol_is_human_and_machine_authority: true,
raw_protocol_text_executed: false,
arbitrary_protocol_code_allowed: false,
executable_projection_requires_explicit_adapter: true,
unprojected_protocol_behavior: 'INVENTORIED_NOT_EXECUTABLE',
dependency_cycles: 'REJECT',
unknown_protocol: 'FAIL_CLOSED',
},
protocol_count: protocols.length,
executable_projection_count: executableCount,
inventoried_not_executable_count: protocols.length - executableCount,
protocols,
}
await writeFile(output, `${JSON.stringify(registry, null, 2)}\n`)
console.log(`GLS_RUNTIME_REGISTRY_COMPILED protocols=${protocols.length} executable=${executableCount} output=${output}`)

View file

@ -0,0 +1,31 @@
import assert from 'node:assert/strict'
import { readFile } from 'node:fs/promises'
import test from 'node:test'
const registryUrl = new URL('../contracts/gls-runtime-registry.json', import.meta.url)
test('compiled GLS registry inventories every current numbered protocol without executing raw text', async () => {
const registry = JSON.parse(await readFile(registryUrl, 'utf8'))
assert.equal(registry.schema, 'hololake.gls-protocol-runtime-registry/v1')
assert.equal(registry.source.repository, 'REPO-012')
assert.equal(registry.source.commit, '2598fbfba8caf64c7ab9740a3036c5aab977502e')
assert.equal(registry.compiler.raw_protocol_text_executed, false)
assert.equal(registry.compiler.arbitrary_protocol_code_allowed, false)
assert.equal(registry.compiler.unprojected_protocol_behavior, 'INVENTORIED_NOT_EXECUTABLE')
assert.equal(registry.protocol_count, 75)
assert.equal(new Set(registry.protocols.map((protocol) => protocol.id)).size, 75)
assert.ok(registry.protocols.every((protocol) => /^[a-f0-9]{64}$/.test(protocol.source_sha256)))
})
test('only explicit deterministic projections enter the runtime enforcement set', async () => {
const registry = JSON.parse(await readFile(registryUrl, 'utf8'))
const protocols = Object.fromEntries(registry.protocols.map((protocol) => [protocol.id, protocol]))
assert.equal(protocols['GLS-0253'].projection_state, 'EXECUTABLE_PROJECTION')
assert.equal(protocols['GLS-0253'].adapter, 'zero-core-numbering')
assert.ok(protocols['GLS-0253'].event_kinds.includes('IDENTITY_ROUTE'))
assert.equal(protocols['GLS-0003'], undefined)
assert.equal(registry.executable_projection_count, 4)
assert.equal(registry.inventoried_not_executable_count, 71)
})

View file

@ -0,0 +1,28 @@
import assert from 'node:assert/strict'
import { readFile } from 'node:fs/promises'
import test from 'node:test'
const contractUrl = new URL('../contracts/zero-core-numbering-kernel.json', import.meta.url)
test('zero-core numbering kernel pins the canonical authority map and fails closed', async () => {
const contract = JSON.parse(await readFile(contractUrl, 'utf8'))
assert.equal(contract.schema, 'hololake.zero-core-numbering-kernel/v1')
assert.equal(contract.authority.map_id, 'GH-IDENTITY-AUTHORITY-MAP-001')
assert.equal(contract.authority.source_commit, '2598fbfba8caf64c7ab9740a3036c5aab977502e')
assert.equal(contract.runtime.number_shape_is_authority, false)
assert.equal(contract.runtime.unknown_number, 'FAIL_CLOSED')
assert.equal(contract.runtime.automatic_identity_issuance, false)
})
test('only registered human namespaces can enter a human route', async () => {
const contract = JSON.parse(await readFile(contractUrl, 'utf8'))
const namespaces = Object.fromEntries(contract.namespaces.map((item) => [item.id, item]))
assert.equal(namespaces.ICE_GL.subject_kind, 'FIFTH_DOMAIN_HUMAN')
assert.equal(namespaces.ICE_GL.human_entry, true)
assert.equal(namespaces.TCS_GL.subject_kind, 'ZERO_SENSE_HUMAN_CONTROLLER_TEAM_MEMBER')
assert.equal(namespaces.TCS_GL.human_entry, true)
assert.equal(namespaces.ICE_P.human_entry, false)
assert.equal(namespaces.ICE_BB.human_entry, false)
})