/* RFC-1030: thin kernel command handlers for runtime.reflect.* commands. Each handler delegates to the pure functions in reflection.ts (reflectRuntime, createCapabilityCatalog) and wraps the result in KernelCommandResult. Does not implement business logic — all logic lives in reflection.ts. Does not register commands — registration lives in component-runtime.module.ts. RFC-1030: initial implementation — 5 reflection command handlers. RFC-1249: wire werkstatt.commands.validate into packages.check + retire CMD-OUTPUT debt */ import { join } from "node:path"; import type { KernelCommandInput, KernelCommandResult, KernelRuntimeContext, } from "@warpgogol/werkstatt-shared/kernel"; import { createCapabilityCatalog, reflectRuntime, assertNoForbiddenFields, type LawKernelSummary, type ReflectionInput, type RuntimeReflectionV1, type CapabilityCatalogV1, } from "./reflection.ts"; export interface ReflectionCommandContext { reflectionInput: ReflectionInput; lawKernelSummary: LawKernelSummary; } function parseContext(context: KernelRuntimeContext): ReflectionCommandContext { const ctx = context as unknown as { reflectionInput?: ReflectionInput; lawKernelSummary?: LawKernelSummary; }; if (!ctx.reflectionInput) { throw new Error("REFLECTION-CMD-01: reflectionInput not provided in kernel context"); } if (!ctx.lawKernelSummary) { throw new Error("REFLECTION-CMD-02: lawKernelSummary not provided in kernel context"); } return { reflectionInput: ctx.reflectionInput, lawKernelSummary: ctx.lawKernelSummary }; } export function runReflectGraph( _input: KernelCommandInput, context: KernelRuntimeContext, ): KernelCommandResult { const { reflectionInput, lawKernelSummary } = parseContext(context); const reflection = reflectRuntime(reflectionInput, lawKernelSummary); assertNoForbiddenFieldsReflection(reflection); return { data: reflection, exitCode: 0, summary: `[reflection.commands] Reflected ${reflection.components.length} components`, }; } export function runReflectCapabilities( _input: KernelCommandInput, context: KernelRuntimeContext, ): KernelCommandResult { const { reflectionInput } = parseContext(context); const catalog = createCapabilityCatalog(reflectionInput); assertNoForbiddenFields(catalog); return { data: catalog, exitCode: 0, summary: `[reflection.commands] Catalog has ${catalog.entries.length} entries`, }; } export function runReflectHealth( _input: KernelCommandInput, context: KernelRuntimeContext, ): KernelCommandResult { const { reflectionInput, lawKernelSummary } = parseContext(context); const reflection = reflectRuntime(reflectionInput, lawKernelSummary); const healthResults = reflection.components.map((c) => ({ componentId: c.componentId, health: c.health ?? { status: "unknown" as const }, })); return { data: { ...reflection, components: healthResults as never }, exitCode: 0, summary: `[reflection.commands] Health checked ${healthResults.length} components`, }; } export function runReflectFibers( _input: KernelCommandInput, context: KernelRuntimeContext, ): KernelCommandResult> { const { reflectionInput, lawKernelSummary } = parseContext(context); const reflection = reflectRuntime(reflectionInput, lawKernelSummary); const fibers = reflection.components.map((c) => ({ componentId: c.componentId, fiberState: c.fiberState, })); return { data: fibers, exitCode: 0, summary: `[reflection.commands] ${fibers.length} fiber states`, }; } export async function runReflectCatalogGenerate( _input: KernelCommandInput, context: KernelRuntimeContext, ): Promise> { const { reflectionInput } = parseContext(context); const catalog = createCapabilityCatalog(reflectionInput); assertNoForbiddenFields(catalog); const outputPath = join(context.workspaceRoot, "docs", "runtime-catalog.generated.yaml"); const yaml = catalogToYaml(catalog); await context.io.writeFile(outputPath, yaml); return { data: { path: "docs/runtime-catalog.generated.yaml" }, exitCode: 0, summary: `[reflection.commands] Catalog written to docs/runtime-catalog.generated.yaml (${catalog.entries.length} entries)`, }; } function assertNoForbiddenFieldsReflection(reflection: RuntimeReflectionV1): void { const json = JSON.stringify(reflection); const forbidden = [ "secrets", "credentials", "privateState", "rawGrants", "prompts", "executableBytes", "leaseTokens", "authorityMaterial", "artifactBytes", "sourceCode", ]; for (const field of forbidden) { if (json.includes(field)) { throw new Error(`REFLECTION-02: reflection contains forbidden field name: ${field}`); } } } function catalogToYaml(catalog: CapabilityCatalogV1): string { const lines: string[] = [ `schema: ${catalog.schema}`, `observedAt: ${catalog.observedAt}`, `resolvedComponentSetHash: ${catalog.resolvedComponentSetHash}`, `catalogHash: ${catalog.catalogHash}`, `entries:`, ]; for (const entry of catalog.entries) { lines.push(` - capability: ${entry.capability}`); lines.push(` version: ${entry.version}`); lines.push(` schemaHash: ${entry.schemaHash}`); lines.push(` componentId: ${entry.componentId}`); lines.push(` lifecycleState: ${entry.lifecycleState}`); lines.push(` callable: ${entry.callable}`); } return lines.join("\n") + "\n"; }