{"record":{"id":"b3179db2dcb4ce14","repo":"Yeachan-Heo/oh-my-codex","slug":"evaluator-output-must-include-boolean-pass","errorCode":null,"errorMessage":"Evaluator output must include boolean pass.","messagePattern":"Evaluator output must include boolean pass\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/autoresearch/contracts.ts","lineNumber":200,"sourceCode":"    body,\n  };\n}\n\nexport function parseEvaluatorResult(raw: string): AutoresearchEvaluatorResult {\n  let parsed: unknown;\n  try {\n    parsed = JSON.parse(raw);\n  } catch {\n    throw contractError('Evaluator output must be valid JSON with required boolean pass and optional numeric score.');\n  }\n\n  if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n    throw contractError('Evaluator output must be a JSON object.');\n  }\n\n  const result = parsed as Record<string, unknown>;\n  if (typeof result.pass !== 'boolean') {\n    throw contractError('Evaluator output must include boolean pass.');\n  }\n  if (result.score !== undefined && typeof result.score !== 'number') {\n    throw contractError('Evaluator output score must be numeric when provided.');\n  }\n\n  return {\n    pass: result.pass,\n    ...(result.score === undefined ? {} : { score: result.score }),\n  };\n}\n\nexport async function loadAutoresearchMissionContract(missionDirArg: string): Promise<AutoresearchMissionContract> {\n  const missionDir = resolve(missionDirArg);\n  if (!existsSync(missionDir)) {\n    throw contractError(`mission-dir does not exist: ${missionDir}`);\n  }\n\n  const repoRoot = readGit(missionDir, ['rev-parse', '--show-toplevel']);","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/autoresearch/contracts.ts#L182-L218","documentation":"parseEvaluatorResult throws when the parsed JSON object lacks a 'pass' field of boolean type. pass is the mandatory verdict of the evaluator; without it the result cannot be interpreted as success or failure.","triggerScenarios":"Evaluator prints '{\"score\": 0.9}' (no pass), '{\"passed\": true}' (wrong key name), or '{\"pass\": \"true\"}' (string instead of boolean).","commonSituations":"Key naming mismatches (passed/success/ok vs pass); truthy strings from shell-built JSON; forgetting to add pass when adding score reporting.","solutions":["Include a literal boolean pass field: '{\"pass\": true, \"score\": 0.9}'.","Use JSON.stringify({pass, score}) in the evaluator rather than string templates.","Check for exact key name 'pass' and boolean type (no quotes)."],"exampleFix":"# before\necho '{\"passed\":true,\"score\":0.9}'\n\n# after\necho '{\"pass\":true,\"score\":0.9}'","handlingStrategy":"type-guard","validationCode":"function outputHasBooleanPass(raw: string): boolean {\n  try {\n    const v = JSON.parse(raw);\n    return !!v && typeof v === 'object' && !Array.isArray(v)\n      && typeof (v as any).pass === 'boolean';\n  } catch { return false; }\n}","typeGuard":"const hasBooleanPass = (v: unknown): boolean =>\n  isJsonObject(v) && typeof (v as Record<string, unknown>).pass === 'boolean';","tryCatchPattern":"try {\n  parseEvaluatorResult(stdout);\n} catch (err) {\n  if ((err as Error).message.includes('boolean pass')) {\n    // rename passed/success -> pass and ensure it is a real boolean\n  }\n  throw err;\n}","preventionTips":["The exact key 'pass' with a JSON boolean is mandatory.","Build output with JSON.stringify to avoid 'true' as a string."],"tags":["evaluator","json","required-field","boolean"],"backgroundTag":"missing-required-json-field","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}