{"record":{"id":"5b224f8d8adedf69","repo":"santifer/career-ops","slug":"conflicting-status-recommendations-require-manual","errorCode":null,"errorMessage":"Conflicting status recommendations require manual review:","messagePattern":"Conflicting status recommendations require manual review:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"reply-watch.mjs","lineNumber":294,"sourceCode":"    console.log('');\n\n    if (match.application_num !== null && classification.suggestedTrackerUpdate !== 'none' && classification.suggestedTrackerUpdate !== 'Needs Review') {\n      const app = apps.find(a => a.num === match.application_num);\n      if (app && app.status !== classification.suggestedTrackerUpdate) {\n        recommendations.push({\n          num: app.num,\n          company: app.company,\n          role: app.role,\n          oldStatus: app.status,\n          newStatus: classification.suggestedTrackerUpdate\n        });\n      }\n    }\n  });\n\n  const groupedRecommendations = groupStatusRecommendations(recommendations);\n  if (groupedRecommendations.conflicts.length > 0) {\n    console.warn('Conflicting status recommendations require manual review:');\n    for (const conflict of groupedRecommendations.conflicts) {\n      const summary = conflict.choices\n        .map(choice => `${choice.newStatus} (${choice.count} ${choice.count === 1 ? 'reply' : 'replies'})`)\n        .join(' vs ');\n      console.warn(`  #${conflict.num}: ${summary} — no automatic update`);\n    }\n    console.log('');\n  }\n\n  if (groupedRecommendations.updates.length > 0) {\n    const updates = groupedRecommendations.updates;\n    console.log('Suggested status updates to apply:');\n    updates.forEach(r => {\n      const count = r.count > 1 ? ` (${r.count} replies)` : '';\n      console.log(`  #${r.num} ${r.company} (${r.role}): ${r.oldStatus} → ${r.newStatus}${count}`);\n    });\n    console.log('');\n","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/reply-watch.mjs#L276-L312","documentation":"reply-watch groups per-tracker-row status recommendations derived from classified replies. When replies for the same application number recommend different new statuses (a conflict), no automatic tracker update is performed; main prints this header and then one line per conflicting row so the user resolves manually.","triggerScenarios":"Running reply-watch over reply-candidates.json where one tracker # received multiple replies classified to different canonical states — e.g. one email reads as Responded and another as Rejected for the same #.","commonSituations":"An interview invite and a form rejection arriving for the same req; a recruiter email and an automated ATS rejection in the same window; misclassification of an ambiguous reply pushing a minority vote.","solutions":["Review the conflicting choices printed under this header and set the correct status yourself with `node set-status.mjs <#> <State> --note \"...\"`.","Re-check the individual replies (paste-reply.mjs / classification) — one is likely misclassified; correct it and re-run.","If both replies are genuinely distinct events, apply them in order manually (earliest first) so the tracker reflects the latest state.","Re-run reply-watch afterwards; the conflict disappears once the row's current status matches one of the recommendations."],"exampleFix":"// before\n// Conflicting status recommendations require manual review:\n//   #42: Responded (1 reply) vs Rejected (1 replies)\n// after\nnode set-status.mjs 42 Rejected --note \"ATS rejection supersedes earlier recruiter email\"","handlingStrategy":"validation","validationCode":"const recs = groupStatusRecommendations(recommendations);\nif (recs.conflicts.length > 0) {\n  console.warn('resolve conflicts manually with set-status.mjs before relying on automation');\n}","typeGuard":null,"tryCatchPattern":"if (groupedRecommendations.conflicts.length > 0) {\n  for (const c of groupedRecommendations.conflicts) console.warn(`#${c.num}: needs manual review`);\n  return; // never auto-update conflicting rows\n}","preventionTips":["Run reply-watch regularly so conflicts stay small and recent.","Correct misclassified replies in reply-candidates.json before applying updates.","Use set-status.mjs (not hand edits) so status-log history disambiguates conflicts."],"tags":["tracker","status-conflict","reply-watch","manual-review"],"backgroundTag":"invalid-state-transition","analyzedSha":"aac998c7ed7248ea853b720ceeb1fdbeb322fc5d","analyzedAt":"2026-09-16T06:35:29.214Z","contentChangedAt":"2026-09-16T06:35:29.214Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}