{"record":{"id":"1f0f1d14ce2efab7","repo":"ruvnet/ruflo","slug":"both-ed25519-private-and-public-pem-keys-are-requi","errorCode":null,"errorMessage":"both Ed25519 private and public PEM keys are required","messagePattern":"both Ed25519 private and public PEM keys are required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/services/flywheel-receipt.ts","lineNumber":578,"sourceCode":"    evidence: input.evidence ?? {\n      corpusRoles: {\n        selectionTaskIds: [],\n        promotionHoldoutTaskIds: [],\n        guardTaskIds: [],\n      },\n      verification: {},\n      canary: {},\n    },\n    termVerification: input.termVerification ?? [],\n    decision,\n    issuedAt: new Date(now).toISOString(),\n    expiresAt: new Date(now + (input.ttlMs ?? 24 * 60 * 60 * 1000)).toISOString(),\n  } satisfies Omit<FlywheelReceiptPayload, 'receiptId'>;\n  const receiptId = sha256Ref(canonicalizeJcs(receiptIdentityPayload(base)));\n  const payload: FlywheelReceiptPayload = { ...base, receiptId };\n  const receipt: FlywheelEvaluationReceipt = { payload };\n  if (input.privateKeyPem || input.publicKeyPem) {\n    if (!input.privateKeyPem || !input.publicKeyPem) throw new Error('both Ed25519 private and public PEM keys are required');\n    receipt.signature = {\n      algorithm: 'ed25519',\n      domain: RECEIPT_DOMAIN,\n      publicKeyPem: input.publicKeyPem,\n      signatureBase64: edSign(null, signedBytes(payload), input.privateKeyPem).toString('base64'),\n    };\n  }\n  return receipt;\n}\n\nexport interface ReceiptVerification {\n  valid: boolean;\n  signed: boolean;\n  errors: string[];\n}\n\nexport function verifyFlywheelReceipt(receipt: FlywheelEvaluationReceipt, trustedPublicKeys?: Set<string>): ReceiptVerification {\n  // The enforcement half of #3229. Before this, ruflo verified its own","sourceCodeStart":560,"sourceCodeEnd":596,"githubUrl":"https://github.com/ruvnet/ruflo/blob/2602b642d92234c710ffbe96bfb33007d481ceab/v3/@claude-flow/cli/src/services/flywheel-receipt.ts#L560-L596","documentation":"Key-material guard in createFlywheelReceipt(): signing a receipt requires both an Ed25519 private and public PEM key, and at least one is missing. Receipt creation aborts rather than producing an unsigned (unverifiable) receipt.","triggerScenarios":"Thrown at v3/@claude-flow/cli/src/services/flywheel-receipt.ts:398 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Generate an Ed25519 keypair and supply both PEM keys","Point the config at existing private and public PEM files"],"exampleFix":"Supply both the Ed25519 private PEM and public PEM keys when signing a flywheel receipt; generate a keypair if one is missing.","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"2602b642d92234c710ffbe96bfb33007d481ceab","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}