{"record":{"id":"76096b4f024ba6d9","repo":"ruvnet/ruflo","slug":"lambda-must-be-in-0-1","errorCode":null,"errorMessage":"lambda must be in (0, 1)","messagePattern":"lambda must be in \\(0, 1\\)","errorType":"validation","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/services/flywheel-sequential-evidence.ts","lineNumber":97,"sourceCode":"  if (!Number.isInteger(testIndex) || testIndex < 1) throw new RangeError('testIndex must be a positive integer');\n  if (!(alphaTotal > 0 && alphaTotal < 1)) throw new RangeError('alphaTotal must be in (0, 1)');\n  return (alphaTotal * 6) / (Math.PI * Math.PI * testIndex * testIndex);\n}\n\n/**\n * Fold paired outcomes into an anytime-valid e-value and judge it against the\n * k-th test's allocated alpha. Deterministic; order of outcomes does not\n * change the final e-value (the product commutes).\n */\nexport function sequentialEvidenceVerdict(\n  outcomes: PairedTaskOutcome[],\n  testIndex: number,\n  config: SequentialEvidenceConfig = {},\n): SequentialEvidenceVerdict {\n  const alphaTotal = config.alphaTotal ?? DEFAULT_ALPHA_TOTAL;\n  const lambda = config.lambda ?? DEFAULT_LAMBDA;\n  const epsilon = config.epsilon ?? DEFAULT_SCORE_EPSILON;\n  if (!(lambda > 0 && lambda < 1)) throw new RangeError('lambda must be in (0, 1)');\n  const alphaAllocated = alphaForTest(testIndex, alphaTotal);\n  const threshold = 1 / alphaAllocated;\n\n  let eValue = 1;\n  let informativePairs = 0;\n  for (const o of outcomes) {\n    const delta = o.candidateScore - o.baselineScore;\n    if (Math.abs(delta) <= epsilon) continue; // concordant: no information\n    informativePairs++;\n    // Under the null a discordant pair favors either arm with probability 1/2,\n    // so E[multiplier] = 1 and the running product is a martingale.\n    eValue *= delta > 0 ? 1 + lambda : 1 - lambda;\n  }\n\n  return {\n    significant: eValue >= threshold,\n    eValue,\n    threshold,","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/cli/src/services/flywheel-sequential-evidence.ts#L79-L115","documentation":"Thrown by sequentialEvidenceVerdict() as a RangeError when the e-process betting fraction lambda is not strictly in the open interval (0, 1). Lambda determines the per-discordant-pair multiplier (1+lambda for a candidate win, 1-lambda for a baseline win); at 0 or 1 the martingale property breaks (trivial multiplier or bankruptcy). Default is 0.5 (no tuning needed).","triggerScenarios":"Calling sequentialEvidenceVerdict(outcomes, k, { lambda: 0 }), { lambda: 1 }, { lambda: 1.5 }, or { lambda: -0.1 }. Flow comes from PromoteOptions.sequentialLambda through the promotion path.","commonSituations":"A misconfigured sequentialLambda passed via the promotion command; a config file that set lambda to 0 thinking it disables the check; a tuning experiment with an out-of-range value.","solutions":["Omit lambda from config to use the 0.5 default.","Use any value strictly between 0 and 1 (e.g. 0.3, 0.5, 0.8).","Validate sequentialLambda before invoking the promotion path."],"exampleFix":"// before\nsequentialEvidenceVerdict(outcomes, k, { lambda: 1 });\n// after\nsequentialEvidenceVerdict(outcomes, k); // default lambda = 0.5","handlingStrategy":"validation","validationCode":"if (config.lambda !== undefined && !(config.lambda > 0 && config.lambda < 1)) {\n  throw new RangeError(`lambda must be in (0,1), got ${config.lambda}`);\n}","typeGuard":"const isValidLambda = (x: unknown): x is number => typeof x === 'number' && x > 0 && x < 1;","tryCatchPattern":null,"preventionTips":["Omit lambda in config to use the 0.5 default (no tuning needed).","Validate sequentialLambda once at config load and reject early.","Document that lambda is strictly exclusive of 0 and 1."],"tags":["validation","statistics","sequential-evidence","range-error"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}