{"record":{"id":"37a89e229bf7f40f","repo":"pbakaus/impeccable","slug":"concept-seed-candidate-count-must-be-an-integer","errorCode":null,"errorMessage":"concept-seed: --candidate-count must be an integer from 5 to 7","messagePattern":"concept-seed: --candidate-count must be an integer from 5 to 7","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/skills/impeccable/scripts/concept-seed.mjs","lineNumber":333,"sourceCode":"  if (register !== null && reroll < 1) {\n    throw new Error('concept-seed: --register steers a re-roll round; pass --reroll <n> with it');\n  }\n  if (register !== null && scope !== 'direction') {\n    throw new Error('concept-seed: --register applies to direction rounds only');\n  }\n  if (mode !== null && !SEED_MODES.has(mode)) {\n    throw new Error('concept-seed: --mode must be persuade, operate, read, or experience');\n  }\n  // Grain needs no mode: how much of the product is in play is independent of\n  // which register of work it is.\n  if (grain !== null && !COMPOSITION_GRAINS.includes(grain)) {\n    throw new Error(`concept-seed: --grain must be one of ${COMPOSITION_GRAINS.join(', ')}`);\n  }\n  if (platform !== null && !COMPOSITION_PLATFORMS.includes(platform)) {\n    throw new Error(`concept-seed: --platform must be one of ${COMPOSITION_PLATFORMS.join(', ')}`);\n  }\n  if (!Number.isInteger(candidateCount) || candidateCount < 5 || candidateCount > 7) {\n    throw new Error('concept-seed: --candidate-count must be an integer from 5 to 7');\n  }\n  const unit = (salt) => {\n    const h = crypto.createHash('sha256').update(`${scope}:${salt}:${key}`).digest();\n    return h.readUInt32BE(0) / 0xffffffff;\n  };\n  const indexSalt = reroll === 0 ? 'index' : `index:reroll-${reroll}`;\n  const buildIndex = 3 + Math.floor(unit(indexSalt) * (candidateCount - 2)); // 3..candidateCount\n  // Surface scope deals a hand of three grounded structures: one card is not\n  // a choice, and the full ranked list would hand selection back to the\n  // model's taste. The dice pick all three; the primary index leads. The\n  // no-lineup rule stays direction-only, where it was written for worlds.\n  const dealtIndices = [buildIndex];\n  for (let draw = 0; scope === 'surface' && dealtIndices.length < Math.min(3, candidateCount); draw += 1) {\n    const idx = 1 + Math.floor(unit(`${indexSalt}:deal-${draw}`) * candidateCount);\n    if (!dealtIndices.includes(idx)) dealtIndices.push(idx);\n    if (draw > 64) { // hash repeats cannot stall the deal\n      for (let fill = 1; dealtIndices.length < Math.min(3, candidateCount); fill += 1) {\n        if (!dealtIndices.includes(fill)) dealtIndices.push(fill);","sourceCodeStart":315,"sourceCodeEnd":351,"githubUrl":"https://github.com/pbakaus/impeccable/blob/d14711ae3d1a1dd62dee61a358d27f107c51ccd0/plugin/skills/impeccable/scripts/concept-seed.mjs#L315-L351","documentation":"Thrown when --candidate-count is not an integer in [5,7]. The build index is computed as 3 + floor(unit * (candidateCount - 2)) and the dealt-indices logic assumes a hand of 5–7 grounded candidates, so values outside that range break the index math and the deal shape.","triggerScenarios":"Passing --candidate-count 4, 8, 10, a non-integer (5.5), or a string. The check is Number.isInteger(candidateCount) && candidateCount >= 5 && candidateCount <= 7.","commonSituations":"A caller assuming more candidates = better; CLI parsing leaving a string; a wrapper exposing a free spin count.","solutions":["Pass --candidate-count 5, 6, or 7 (default is 7).","Programmatic callers should validate Number.isInteger and the 5–7 range before calling."],"exampleFix":"// before\nseedConcepts({ scope: 'direction', candidateCount: 10 });\n\n// after\nseedConcepts({ scope: 'direction', candidateCount: 7 });","handlingStrategy":"validation","validationCode":"if (!Number.isInteger(candidateCount) || candidateCount < 5 || candidateCount > 7) {\n  throw new Error('--candidate-count must be an integer from 5 to 7');\n}","typeGuard":"function isValidCandidateCount(value) {\n  return Number.isInteger(value) && value >= 5 && value <= 7;\n}","tryCatchPattern":"try {\n  await seedConcepts({ scope: 'direction', candidateCount });\n} catch (err) {\n  if (/--candidate-count must be/.test(err.message)) {\n    console.error('Pass --candidate-count 5, 6, or 7.');\n  } else throw err;\n}","preventionTips":["Coerce CLI strings to Number and validate the 5–7 integer range before forwarding.","Clamp UI inputs for candidate count to 5–7.","Default candidateCount to 7 in callers so undefined never reaches the check."],"tags":["concept-seed","validation","candidate-count","cli-args"],"backgroundTag":null,"analyzedSha":"d14711ae3d1a1dd62dee61a358d27f107c51ccd0","analyzedAt":"2026-08-13T00:52:25.771Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}