{"challengeId":"addchain-127","entry":"verifier.mjs","sha256":"95a645b44092453877ad447a9a34e2202594910e140c01d23a22c4c916a4c9b8","scoreDirection":"minimize","scoreLabel":"additions","seedPolicy":{"mode":"fixed","testCount":1},"source":"// Frozen verifier for addchain-127. Self-contained (no imports): it interprets\r\n// the candidate's addition-chain artifact and returns a Verdict. It never executes\r\n// agent code — build() already ran in the sandbox and handed us plain data. This\r\n// file is part of the challenge's PROTECTED surface.\r\n//\r\n// An addition chain for N is a sequence c[0], c[1], ... , c[L] with c[0] = 1,\r\n// c[L] = N, and every later element equal to the sum of two (not necessarily\r\n// distinct) EARLIER elements. The cost is the number of additions = L = length-1.\r\n// Fixed target N = 127. Correctness is decided exhaustively: every element must be\r\n// witnessed as a sum of two strictly-earlier elements (we recompute that witness\r\n// with integer arithmetic), and the last element must equal N. There is no hidden\r\n// test set and nothing to overfit, so seedPolicy.mode is \"fixed\".\r\n//\r\n// The binary square-and-multiply chain for 127 uses 12 additions; the known\r\n// optimum is 10, so this is a clean, finite, checkable ladder.\r\n\r\nconst TARGET = 127;\r\nconst MAX_LEN = 256;\r\n\r\nfunction gate(name, pass, detail) {\r\n  return { name, pass, detail };\r\n}\r\nfunction bad(name, detail) {\r\n  return { ok: false, score: null, gates: [gate(name, false, detail)], behavior: {}, logs: [] };\r\n}\r\n\r\nexport function verify(ctx) {\r\n  const sol = ctx.solution;\r\n  if (!sol || typeof sol !== 'object' || !Array.isArray(sol.chain)) {\r\n    return bad('structure', 'expected { chain: [1, ..., 127] }');\r\n  }\r\n  const chain = sol.chain;\r\n  if (chain.length < 1) return bad('structure', 'chain is empty');\r\n  if (chain.length > MAX_LEN) return bad('structure', `chain too long (> ${MAX_LEN})`);\r\n  for (let i = 0; i < chain.length; i++) {\r\n    if (!Number.isInteger(chain[i]) || chain[i] < 1) {\r\n      return bad('structure', `element ${i} must be a positive integer`);\r\n    }\r\n  }\r\n\r\n  if (chain[0] !== 1) {\r\n    return bad('starts-at-one', `chain must start at 1 (got ${chain[0]})`);\r\n  }\r\n\r\n  // Every element after the first must be the sum of two strictly-earlier ones.\r\n  // We recompute a witness pair (a, b) with chain[a] + chain[b] === chain[k].\r\n  let badStep = '';\r\n  for (let k = 1; k < chain.length && !badStep; k++) {\r\n    let witnessed = false;\r\n    for (let a = 0; a < k && !witnessed; a++) {\r\n      for (let b = a; b < k; b++) {\r\n        if (chain[a] + chain[b] === chain[k]) {\r\n          witnessed = true;\r\n          break;\r\n        }\r\n      }\r\n    }\r\n    if (!witnessed) {\r\n      badStep = `element ${k} (=${chain[k]}) is not the sum of two earlier elements`;\r\n    }\r\n  }\r\n  if (badStep) {\r\n    return {\r\n      ok: false,\r\n      score: null,\r\n      gates: [gate('valid-chain', false, badStep)],\r\n      behavior: {},\r\n      logs: [],\r\n    };\r\n  }\r\n\r\n  const reached = chain[chain.length - 1];\r\n  if (reached !== TARGET) {\r\n    return {\r\n      ok: false,\r\n      score: null,\r\n      gates: [gate('reaches-target', false, `final element ${reached} (want ${TARGET})`)],\r\n      behavior: {},\r\n      logs: [],\r\n    };\r\n  }\r\n\r\n  const additions = chain.length - 1;\r\n  const gates = [\r\n    gate('valid-chain', true, 'every element is a sum of two earlier elements'),\r\n    gate('reaches-target', true, `final element is ${TARGET}`),\r\n  ];\r\n  const ok = gates.every((g) => g.pass);\r\n  return {\r\n    ok,\r\n    score: ok ? additions : null,\r\n    gates,\r\n    behavior: { additions, length: chain.length },\r\n    logs: [`additions=${additions} length=${chain.length} target=${TARGET}`],\r\n  };\r\n}\r\n"}