ruvnet/ruflo · error · Error
both Ed25519 private and public PEM keys are required
Error message
both Ed25519 private and public PEM keys are required
What it means
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.
Solutions
- Generate an Ed25519 keypair and supply both PEM keys
- Point the config at existing private and public PEM files
Example fix
Supply both the Ed25519 private PEM and public PEM keys when signing a flywheel receipt; generate a keypair if one is missing.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at v3/@claude-flow/cli/src/services/flywheel-receipt.ts:398 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of ruvnet/ruflo@2602b642d9 (2026-08-18).
Data as JSON: /api/errors/1f0f1d14ce2efab7.
Report an issue: GitHub.
Appendix: source
Thrown at v3/@claude-flow/cli/src/services/flywheel-receipt.ts:578
evidence: input.evidence ?? {
corpusRoles: {
selectionTaskIds: [],
promotionHoldoutTaskIds: [],
guardTaskIds: [],
},
verification: {},
canary: {},
},
termVerification: input.termVerification ?? [],
decision,
issuedAt: new Date(now).toISOString(),
expiresAt: new Date(now + (input.ttlMs ?? 24 * 60 * 60 * 1000)).toISOString(),
} satisfies Omit<FlywheelReceiptPayload, 'receiptId'>;
const receiptId = sha256Ref(canonicalizeJcs(receiptIdentityPayload(base)));
const payload: FlywheelReceiptPayload = { ...base, receiptId };
const receipt: FlywheelEvaluationReceipt = { payload };
if (input.privateKeyPem || input.publicKeyPem) {
if (!input.privateKeyPem || !input.publicKeyPem) throw new Error('both Ed25519 private and public PEM keys are required');
receipt.signature = {
algorithm: 'ed25519',
domain: RECEIPT_DOMAIN,
publicKeyPem: input.publicKeyPem,
signatureBase64: edSign(null, signedBytes(payload), input.privateKeyPem).toString('base64'),
};
}
return receipt;
}
export interface ReceiptVerification {
valid: boolean;
signed: boolean;
errors: string[];
}
export function verifyFlywheelReceipt(receipt: FlywheelEvaluationReceipt, trustedPublicKeys?: Set<string>): ReceiptVerification {
// The enforcement half of #3229. Before this, ruflo verified its ownView on GitHub (pinned to 2602b642d9)