{"record":{"id":"3e1e4f025a0fd65c","repo":"ruvnet/ruflo","slug":"policy-value-must-be-finite","errorCode":null,"errorMessage":"policy value must be finite","messagePattern":"policy value must be finite","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/services/flywheel-receipt.ts","lineNumber":347,"sourceCode":" * Encode an opaque policy object so every fractional value is a scale-12\n * decimal string, per ADR-322C rule 2 and conformance-checklist A3.\n *\n * `candidatePolicy` is declared \"Opaque to this contract; its shape is owned by\n * policySchemaVersion. Must still satisfy the ADR-322C number rules\" — a rule\n * the JSON Schema cannot express for an opaque object, so nothing enforced it\n * and the producer wrote binary floats (`{\"alpha\": 0.3, \"mmrLambda\": 0.5}`).\n * Ruflo's own verifier accepted them because `assertJsonValue` only checked\n * finite-and-not-negative-zero; autogenous's stricter verifier correctly\n * rejected the receipt (ruvnet/ruflo#3229, ruvnet/autogenous#15).\n *\n * Integers stay JSON numbers and only non-integers are encoded, which is what\n * the contract's own example shows: `{\"hnswEf\": 128, \"hybridWeight\": \"0.65\"}`.\n * Recurses through nested objects and arrays, because \"every fractional value\"\n * is not limited to the top level.\n */\nexport function encodePolicyFractions(value: unknown): unknown {\n  if (typeof value === 'number') {\n    if (!Number.isFinite(value)) throw new Error('policy value must be finite');\n    // Integers are exact in JSON and the contract permits scaled integers, so\n    // they are left alone; -0 is normalized away by `decimal`.\n    return Number.isInteger(value) && !Object.is(value, -0) ? value : decimal(value);\n  }\n  if (Array.isArray(value)) return value.map(encodePolicyFractions);\n  if (value && typeof value === 'object') {\n    return Object.fromEntries(\n      Object.entries(value as Record<string, unknown>).map(([k, v]) => [k, encodePolicyFractions(v)]),\n    );\n  }\n  return value;\n}\n\nfunction seedFrom(parts: string[]): { seed: number; hex: string } {\n  const digest = createHash('sha256').update(parts.join('')).digest();\n  return { seed: digest.readUInt32BE(0), hex: digest.toString('hex') };\n}\n","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/ruvnet/ruflo/blob/2602b642d92234c710ffbe96bfb33007d481ceab/v3/@claude-flow/cli/src/services/flywheel-receipt.ts#L329-L365","documentation":"encodePolicyFractions normalizes policy objects so every fractional value becomes a scale-12 decimal string. Because NaN and Infinity have no decimal representation and would break deterministic receipt signing, the function throws immediately when it encounters a non-finite number.","triggerScenarios":"Passing an object containing NaN, Infinity, or -Infinity to encodePolicyFractions, directly or through receipt-signing helpers such as candidatePolicy/policyCandidateId.","commonSituations":"Policy values computed from division by zero or uninitialized variables; JSON.parse of a document serialized with Infinity (non-standard); test fixtures using placeholder NaN values.","solutions":["Trace where the NaN/Infinity value originates and fix the computation producing it","Validate policy numbers are finite before encoding","Replace placeholder non-finite values with defined numbers or omit the field"],"exampleFix":"// before\nconst weight = total / count; // count === 0 -> Infinity\n// after\nconst weight = count > 0 ? total / count : 0;","handlingStrategy":"validation","validationCode":"const assertFinitePolicy = (obj) => JSON.stringify(obj, (k, v) => { if (typeof v === 'number' && !Number.isFinite(v)) throw new Error(`non-finite value at key ${k}`); return v; });","typeGuard":"const isFiniteNumber = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);","tryCatchPattern":"try { encodePolicyFractions(policy); } catch (e) { if (e.message === 'policy value must be finite') { /* locate NaN/Infinity in policy, fix computation */ } throw e; }","preventionTips":["Guard division denominators before assigning policy values","Avoid JSON round-trips of Infinity/NaN","Assert finiteness of computed metrics before building policy objects"],"tags":["validation","decimal","finite-value","policy"],"backgroundTag":"invalid-argument-value","analyzedSha":"2602b642d92234c710ffbe96bfb33007d481ceab","analyzedAt":"2026-09-15T22:58:14.805Z","contentChangedAt":"2026-09-15T22:58:14.805Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}