{"challengeId":"sortnet-size-14","entry":"verifier.mjs","sha256":"2b88fa39727ec6397e5c8fe6b72799749517aaad621edcbef5abb29b5551cb21","scoreDirection":"minimize","scoreLabel":"comparators","seedPolicy":{"mode":"fixed","testCount":16384},"source":"// Frozen verifier for sortnet-size-14. Self-contained (no imports): it interprets\n// the candidate's sorting-network artifact and returns a Verdict. It never executes\n// agent code — build() already ran in the sandbox and handed us plain data.\n// This file is part of the challenge's PROTECTED surface.\n//\n// Mirrors sortnet-9's verifier with two changes: N = 14, and the artifact field is\n// `network` (an array of [i, j] comparator pairs). Correctness is PROVEN\n// exhaustively, not sampled. By the 0/1 principle (Knuth, TAOCP vol. 3, §5.3.4),\n// a comparator network that sorts every one of the 2^N binary input vectors sorts\n// every input of any ordered type. With N = 14 that is 2^14 = 16384 vectors —\n// small enough to check completely — so a network that passes here is a total\n// correctness proof, and there is nothing an agent can overfit to.\n// seedPolicy.mode is \"fixed\" for this reason. Everything below is pure\n// integer/bitwise arithmetic: no Math.pow/sqrt/trig/exp/log, no floats.\n\nconst N = 14;\nconst MAX_COMP = 4096;\n\nfunction gate(name, pass, detail) {\n  return { name, pass, detail };\n}\nfunction bad(name, detail) {\n  return { ok: false, score: null, gates: [gate(name, false, detail)], behavior: {}, logs: [] };\n}\n\n// Critical-path depth: greedily pack comparators into layers. A comparator must\n// start no earlier than the layer after the latest use of either of its wires.\nfunction computeDepth(comparators) {\n  const ready = new Array(N).fill(0); // next free layer per wire\n  let maxLayer = 0;\n  for (const [i, j] of comparators) {\n    const layer = ready[i] > ready[j] ? ready[i] : ready[j];\n    ready[i] = layer + 1;\n    ready[j] = layer + 1;\n    if (layer + 1 > maxLayer) maxLayer = layer + 1;\n  }\n  return maxLayer;\n}\n\nexport function verify(ctx) {\n  const sol = ctx.solution;\n  if (!sol || typeof sol !== 'object' || !Array.isArray(sol.network)) {\n    return bad('structure', 'expected { network: [[i, j], ...] }');\n  }\n  const cmp = sol.network;\n  if (cmp.length === 0) return bad('structure', 'network has no comparators');\n  if (cmp.length > MAX_COMP) return bad('structure', `too many comparators (> ${MAX_COMP})`);\n\n  // Validate every comparator: a pair of distinct, in-range wire indices.\n  for (let k = 0; k < cmp.length; k++) {\n    const c = cmp[k];\n    if (!Array.isArray(c) || c.length !== 2) {\n      return bad('structure', `comparator ${k} must be a pair [i, j]`);\n    }\n    const [i, j] = c;\n    if (!Number.isInteger(i) || !Number.isInteger(j) || i < 0 || j < 0 || i >= N || j >= N) {\n      return bad('structure', `comparator ${k} has an out-of-range wire (must be 0..${N - 1})`);\n    }\n    if (i === j) {\n      return bad('structure', `comparator ${k} compares a wire with itself`);\n    }\n  }\n\n  // 0/1 principle: exhaustively run all 2^N binary inputs through the network.\n  // A compare-exchange on [i, j] places min on the lower index, max on the\n  // higher — independent of the order the agent wrote the pair in.\n  const total = 1 << N; // 16384\n  let firstFail = '';\n  for (let mask = 0; mask < total && !firstFail; mask++) {\n    const a = new Array(N);\n    for (let b = 0; b < N; b++) a[b] = (mask >> b) & 1;\n    for (const [i, j] of cmp) {\n      const lo = i < j ? i : j;\n      const hi = i < j ? j : i;\n      if (a[lo] > a[hi]) {\n        const t = a[lo];\n        a[lo] = a[hi];\n        a[hi] = t;\n      }\n    }\n    for (let b = 1; b < N; b++) {\n      if (a[b - 1] > a[b]) {\n        firstFail = `input ${mask.toString(2).padStart(N, '0')} not sorted`;\n        break;\n      }\n    }\n  }\n\n  const depth = computeDepth(cmp);\n  const gates = [\n    gate('sorts-all-inputs', !firstFail, firstFail || `all ${total} binary inputs sorted (0/1 principle ⇒ total correctness)`),\n  ];\n  const ok = gates.every((g) => g.pass);\n  return {\n    ok,\n    score: ok ? cmp.length : null,\n    gates,\n    behavior: { comparators: cmp.length, depth },\n    logs: [`comparators=${cmp.length} depth=${depth}`],\n  };\n}\n"}