{"record":{"id":"6c381d48d2c92c39","repo":"ruvnet/ruflo","slug":"truthanchorstore-requires-a-signingkey-in-config","errorCode":null,"errorMessage":"TruthAnchorStore requires a signingKey in config. Anchors cannot be created without a signing key.","messagePattern":"TruthAnchorStore requires a signingKey in config\\. Anchors cannot be created without a signing key\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/guidance/src/truth-anchors.ts","lineNumber":205,"sourceCode":"// ============================================================================\n\n/**\n * Append-only store for truth anchors.\n *\n * Anchors are immutable once created. The store provides signing,\n * verification, querying, supersession, and capacity management\n * with LRU eviction of expired anchors only.\n */\nexport class TruthAnchorStore {\n  private readonly config: TruthAnchorConfig;\n  private readonly anchors: TruthAnchor[] = [];\n  private readonly indexById: Map<string, number> = new Map();\n\n  constructor(config: Partial<TruthAnchorConfig> = {}) {\n    this.config = { ...DEFAULT_CONFIG, ...config };\n\n    if (!this.config.signingKey) {\n      throw new Error(\n        'TruthAnchorStore requires a signingKey in config. ' +\n        'Anchors cannot be created without a signing key.',\n      );\n    }\n  }\n\n  /**\n   * Create and sign a new truth anchor.\n   *\n   * The anchor is appended to the store and can never be mutated.\n   * If the store exceeds capacity, expired anchors are evicted\n   * starting from the oldest.\n   */\n  anchor(params: AnchorParams): TruthAnchor {\n    const now = Date.now();\n\n    const partial: Omit<TruthAnchor, 'signature'> = {\n      id: randomUUID(),","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/guidance/src/truth-anchors.ts#L187-L223","documentation":"The TruthAnchorStore constructor throws when config.signingKey is absent (undefined or empty). Every truth anchor is HMAC-signed and immutable once appended, so the store cannot create or verify anchors without a key — there is deliberately no unsigned mode. This is a fail-fast configuration check at construction time.","triggerScenarios":"Calling new TruthAnchorStore() with no arguments, or with a config object whose signingKey is undefined/empty string — typically because the key was read from an environment variable or secret manager entry that was never set in the current environment.","commonSituations":"Key configured in the production profile but missing in CI or local dev; secrets loaded asynchronously after the store is constructed; a Partial<TruthAnchorConfig> built from sparse JSON where the signingKey field is absent; refactoring that renamed the config field.","solutions":["Pass a non-empty signingKey: new TruthAnchorStore({ signingKey: process.env.TRUTH_ANCHOR_KEY })","If no external key exists, generate a stable secret once (e.g. random 32-byte hex stored in your secret manager) and reuse it — the same key must verify previously created anchors","Fail fast at config-load time by asserting required secrets before constructing the store"],"exampleFix":"// before\nconst store = new TruthAnchorStore(); // throws: signingKey required\n\n// after\nconst store = new TruthAnchorStore({\n  signingKey: process.env.TRUTH_ANCHOR_SIGNING_KEY!,\n});","handlingStrategy":"validation","validationCode":"// Resolve the key before constructing the store\nconst signingKey = process.env.TRUTH_ANCHOR_SIGNING_KEY;\nif (!signingKey) {\n  throw new Error('TRUTH_ANCHOR_SIGNING_KEY is required to start this service');\n}\nconst store = new TruthAnchorStore({ signingKey });","typeGuard":"type SignedStoreConfig = Partial<TruthAnchorConfig> & { signingKey: string };\nfunction hasSigningKey(c: Partial<TruthAnchorConfig>): c is SignedStoreConfig {\n  return typeof c.signingKey === 'string' && c.signingKey.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Check required secrets at config-load time with a single bootstrap assertion","Use one stable signing key per environment; rotating it invalidates verification of old anchors","Include TruthAnchorStore construction in smoke tests so missing keys fail CI, not prod"],"tags":["truth-anchors","signing-key","configuration","guidance","constructor"],"backgroundTag":"missing-signing-key","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}