{"record":{"id":"313b078ee5059b89","repo":"ruvnet/ruflo","slug":"evolutionpipeline-requires-an-explicit-signingkey","errorCode":null,"errorMessage":"EvolutionPipeline requires an explicit signingKey — hardcoded defaults are not secure","messagePattern":"EvolutionPipeline requires an explicit signingKey — hardcoded defaults are not secure","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/guidance/src/evolution.ts","lineNumber":255,"sourceCode":"// EvolutionPipeline\n// ============================================================================\n\n/**\n * The Evolution Pipeline manages the lifecycle of change proposals through\n * signing, simulation, comparison, staged rollout, and promotion or rollback.\n */\nexport class EvolutionPipeline {\n  private readonly signingKey: string;\n  private readonly maxDivergence: number;\n  private readonly defaultStages: RolloutStage[];\n\n  private proposals = new Map<string, ChangeProposal>();\n  private simulations = new Map<string, SimulationResult>();\n  private rollouts = new Map<string, StagedRollout>();\n\n  constructor(config: EvolutionPipelineConfig = {}) {\n    if (!config.signingKey) {\n      throw new Error('EvolutionPipeline requires an explicit signingKey — hardcoded defaults are not secure');\n    }\n    this.signingKey = config.signingKey;\n    this.maxDivergence = config.maxDivergence ?? DEFAULT_MAX_DIVERGENCE;\n    this.defaultStages = config.stages ?? DEFAULT_STAGES;\n  }\n\n  // ==========================================================================\n  // Propose\n  // ==========================================================================\n\n  /**\n   * Create and sign a new change proposal.\n   */\n  propose(params: {\n    kind: ChangeProposalKind;\n    title: string;\n    description: string;\n    author: string;","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/guidance/src/evolution.ts#L237-L273","documentation":"EvolutionPipeline signs change proposals, simulation results, and staged rollouts, so it requires `config.signingKey` at construction — the same no-hardcoded-default hardening as ArtifactLedger and ConformanceRunner. `new EvolutionPipeline()` or any config object without signingKey throws before any propose/simulate/stage work. There is no fallback key by design.","triggerScenarios":"`new EvolutionPipeline()`; `new EvolutionPipeline({ maxDivergence: 0.05 })` without signingKey; key sourced from an env var absent in the deployment environment.","commonSituations":"Deploying the evolution service without provisioning its signing secret; sharing config objects between components and dropping the key field; older docs/examples that omit signingKey.","solutions":["Construct with an explicit key: `new EvolutionPipeline({ signingKey: process.env.EVOLUTION_SIGNING_KEY! })`","Fail fast at boot if required env vars are missing","Use one shared secret-management path for all guidance components that need signing keys"],"exampleFix":"// before\nconst pipeline = new EvolutionPipeline({ maxDivergence: 0.05 }); // throws\n\n// after\nconst pipeline = new EvolutionPipeline({\n  signingKey: requiredEnv('EVOLUTION_SIGNING_KEY'),\n  maxDivergence: 0.05,\n});","handlingStrategy":"validation","validationCode":"const signingKey = process.env.EVOLUTION_SIGNING_KEY;\nif (!signingKey) {\n  throw new Error('EVOLUTION_SIGNING_KEY must be set before EvolutionPipeline');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Provision a dedicated signing key per environment for the evolution service","Assert required config fields before constructing signed components","Use one secret-loading path for all guidance components"],"tags":["security","signing-key","configuration","evolution","guidance"],"backgroundTag":"missing-required-config","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}