{"record":{"id":"2b488ecb38bd0f18","repo":"Yeachan-Heo/oh-my-codex","slug":"formatcodexgoalreconciliation-reconciliation","errorCode":null,"errorMessage":"formatCodexGoalReconciliation(reconciliation)","messagePattern":"formatCodexGoalReconciliation\\(reconciliation\\)","errorType":"validation","errorClass":"AutoresearchGoalError","httpStatus":null,"severity":"error","filePath":"src/autoresearch/goal.ts","lineNumber":243,"sourceCode":"    status: mission.status,\n    evidence,\n    artifact_path: options.artifactPath,\n  });\n  return { mission, completion };\n}\n\nexport async function completeAutoresearchGoal(cwd: string, slug: string, options: CompleteAutoresearchGoalOptions = {}): Promise<{ mission: AutoresearchGoalMission; completion: AutoresearchGoalCompletion }> {\n  const mission = await readAutoresearchGoal(cwd, slug);\n  const completion = await readAutoresearchGoalCompletion(cwd, mission.slug);\n  if (!completion || !completion.passed || completion.verdict !== 'pass') {\n    throw new AutoresearchGoalError(`Autoresearch goal ${mission.slug} cannot complete until professor-critic validation records verdict=pass in ${mission.completion_path}.`);\n  }\n  const reconciliation = reconcileAutoresearchCodexGoalSnapshot(\n    options.codexGoal === undefined ? null : parseCodexGoalSnapshot(options.codexGoal),\n    mission,\n    { requireSnapshot: true, requireComplete: true },\n  );\n  if (!reconciliation.ok) throw new AutoresearchGoalError(formatCodexGoalReconciliation(reconciliation));\n  const completedAt = iso(options.now);\n  mission.status = 'complete';\n  mission.updated_at = completedAt;\n  mission.completed_at = completedAt;\n  await writeMission(cwd, mission);\n  await appendLedger(cwd, mission.slug, {\n    ts: completedAt,\n    event: 'goal_completed',\n    slug: mission.slug,\n    status: mission.status,\n    evidence: completion.evidence,\n    artifact_path: completion.artifact_path,\n  });\n  return { mission, completion };\n}\n\nexport function buildAutoresearchGoalObjective(mission: Pick<AutoresearchGoalMission, 'topic' | 'rubric' | 'slug'>): string {\n  return [","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/Yeachan-Heo/oh-my-codex/blob/3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2/src/autoresearch/goal.ts#L225-L261","documentation":"completeAutoresearchGoal reconciles the supplied Codex goal snapshot (options.codexGoal, parsed by parseCodexGoalSnapshot) against the mission and throws with the formatted reconciliation report when reconciliation.ok is false. It enforces that a snapshot is present and the mission is complete, with all snapshot fields matching the mission.","triggerScenarios":"Calling completeAutoresearchGoal without options.codexGoal (requireSnapshot: true), passing a malformed/stale Codex goal snapshot, or a snapshot whose fields (goal, status, metrics) diverge from the mission state at completion time.","commonSituations":"Upgrading to a version that made the snapshot mandatory, passing a snapshot captured before the final verdict, JSON drift between the Codex output and the mission record, or omitting the snapshot entirely in older automation scripts.","solutions":["Pass options.codexGoal with the current Codex goal snapshot string when calling completeAutoresearchGoal","Read the formatted message from formatCodexGoalReconciliation — it lists exactly which fields mismatch; fix those fields and retry","Regenerate the snapshot from the live Codex goal state so it reflects the completed mission","If the snapshot is malformed, check parseCodexGoalSnapshot's expected input format before passing it"],"exampleFix":"// before\nawait completeAutoresearchGoal(repoRoot, 'fix-leak'); // throws: snapshot required / mismatch\n// after\nawait completeAutoresearchGoal(repoRoot, 'fix-leak', { codexGoal: currentCodexGoalSnapshotJson });","handlingStrategy":"validation","validationCode":"import { existsSync } from 'node:fs';\nif (!existsSync(join(repoRoot, '.omx', 'autoresearch-goal', `${slugifyMissionName(slug)}.json`))) {\n  throw new Error('Mission missing; snapshot reconciliation would fail.');\n}","typeGuard":"function isReconcilable(r: { ok: boolean; mismatches?: string[] }): boolean { return r.ok; }","tryCatchPattern":"try { await completeAutoresearchGoal(cwd, slug, { codexGoal }); }\ncatch (e) { if (e instanceof AutoresearchGoalError) console.error(e.message /* the reconciliation report lists mismatches */); throw e; }","preventionTips":["Always pass the current codexGoal snapshot to completeAutoresearchGoal","Capture the snapshot after the final verdict so it matches mission state","Log the reconciliation message verbatim; it enumerates the exact mismatched fields"],"tags":["autoresearch","codex","snapshot","reconciliation"],"backgroundTag":"state-reconciliation-mismatch","analyzedSha":"3ad79a8a6fe6e95fdbb8c00e40716fffe4011ce2","analyzedAt":"2026-08-27T22:18:39.783Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}