/* RFC-1031: registers evolution.candidate.* kernel commands for the governed capability evolution controller. 9 commands covering the full candidate lifecycle: define, shadow, test, canary, activate, promote, rollback, quarantine, inspect. Does not implement evolution logic — that lives in controller.ts. Does not register non-evolution commands. RFC-1031: initial implementation — registers 9 evolution.candidate.* commands. */ import type { ModuleExport } from "@warpgogol/werkstatt-shared/kernel"; export async function createEvolutionModule(): Promise { const { runCandidateDefine, runCandidateShadow, runCandidateTest, runCandidateCanary, runCandidateActivate, runCandidatePromote, runCandidateRollback, runCandidateQuarantine, runCandidateInspect, } = await import("./evolution-commands.ts"); const modulePath = "packages/werkstatt-engine/src/evolution/evolution.module.ts"; return { name: "evolution", version: "0.1.0", declarations: [], commands: [ { name: "evolution.candidate.define", coverage: "operator" as const, modulePath, description: "Register a new capability candidate in the defined state. " + "Requires --component-id, --version, --artifact (content-addressed hash). " + "Optional --allow-agent-written flag for agent-authored candidates (RFC-1031).", scope: "workspace", mutatesState: true, cacheable: false, generates: [], flags: { "component-id": { kind: "string", description: "Component ID for the candidate." }, version: { kind: "string", description: "Semantic version of the candidate." }, artifact: { kind: "string", description: "Content-addressed artifact hash (sha256:...).", }, "allow-agent-written": { kind: "boolean", description: "Allow agent-authored candidates (default: false).", }, }, execute: runCandidateDefine, }, { name: "evolution.candidate.shadow", coverage: "operator" as const, modulePath, description: "Run candidate alongside active component in shadow mode. " + "Parallel invocation with comparison metric. Records CandidateEvidenceV1 (RFC-1031).", scope: "workspace", mutatesState: true, cacheable: false, generates: [], flags: { "candidate-id": { kind: "string", description: "Candidate ID to shadow." }, metric: { kind: "string", description: "Comparison metric (default: latency)." }, }, execute: runCandidateShadow, }, { name: "evolution.candidate.test", coverage: "operator" as const, modulePath, description: "Run held-out evaluation scenarios against the candidate. " + "Records CandidateEvidenceV1 for each scenario (RFC-1031).", scope: "workspace", mutatesState: true, cacheable: false, generates: [], flags: { "candidate-id": { kind: "string", description: "Candidate ID to test." }, scenarios: { kind: "string", description: "Path to evaluation scenarios (default: src/evolution/fixtures).", }, }, execute: runCandidateTest, }, { name: "evolution.candidate.canary", coverage: "operator" as const, modulePath, description: "Route a percentage of traffic to the candidate via deterministic hash routing. " + "Uses Sha256Digest of canonical JSON input bytes (RFC-0849, RFC-1031).", scope: "workspace", mutatesState: true, cacheable: false, generates: [], flags: { "candidate-id": { kind: "string", description: "Candidate ID to canary." }, "traffic-percent": { kind: "string", description: "Percentage of traffic to route (default: 10).", }, }, execute: runCandidateCanary, }, { name: "evolution.candidate.activate", coverage: "operator" as const, modulePath, description: "Atomically replace the active component with the candidate. " + "Uses ActivationTransaction for atomic replacement (RFC-1031).", scope: "workspace", mutatesState: true, cacheable: false, generates: [], flags: { "candidate-id": { kind: "string", description: "Candidate ID to activate." }, }, execute: runCandidateActivate, }, { name: "evolution.candidate.promote", coverage: "operator" as const, modulePath, description: "Promote the candidate to permanent status via the mission/release pipeline. " + "Creates a mission with the candidate artifact (RFC-1031).", scope: "workspace", mutatesState: true, cacheable: false, generates: [], flags: { "candidate-id": { kind: "string", description: "Candidate ID to promote." }, "mission-id": { kind: "string", description: "Mission ID for the promotion pipeline." }, }, execute: runCandidatePromote, }, { name: "evolution.candidate.rollback", coverage: "operator" as const, modulePath, description: "Reactivate the previous component and transition the candidate to rolled-back. " + "Used when a promoted candidate needs to be reverted (RFC-1031).", scope: "workspace", mutatesState: true, cacheable: false, generates: [], flags: { "component-id": { kind: "string", description: "Component ID to roll back." }, }, execute: runCandidateRollback, }, { name: "evolution.candidate.quarantine", coverage: "operator" as const, modulePath, description: "Transition candidate to quarantined state. " + "Triggered automatically after 3 consecutive health check failures or manually (RFC-1031).", scope: "workspace", mutatesState: true, cacheable: false, generates: [], flags: { "candidate-id": { kind: "string", description: "Candidate ID to quarantine." }, reason: { kind: "string", description: "Reason for quarantine (default: unspecified)." }, }, execute: runCandidateQuarantine, }, { name: "evolution.candidate.inspect", coverage: "operator" as const, modulePath, description: "Inspect all registered candidates with their states and transition history. " + "Returns JSON array of CapabilityCandidateV1 (RFC-1031).", scope: "workspace", mutatesState: false, cacheable: false, generates: [], flags: {}, execute: runCandidateInspect, }, ], pipelines: [], }; }