{"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":290,"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":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/santifer/career-ops/blob/60398d6549a46f5266929538af21cfab94badc75/reply-watch.mjs#L272-L308","documentation":"reply-watch.mjs classifies application replies into one suggested tracker status per reply, then groups them per application row (groupStatusRecommendations). When a single tracker number receives contradictory suggestions -- e.g. two replies say Rejected while one says Interview -- the tool refuses to auto-apply any of them, prints this header, and defers to manual review instead of picking a winner silently.","triggerScenarios":"Batch-classifying a mailbox where a company sent both a rejection and a later interview-reschedule; auto-reply noise mixing with human replies; threading ambiguity mapping two different roles onto one tracker row.","commonSituations":"Processing a week of accumulated mail in one run; companies that reject one application then invite for another; multiple applications to the same company.","solutions":["Read the per-conflict detail lines (next warning) to see which statuses and reply counts are fighting over each #num.","Open the raw replies for that row, decide the true current state, and apply it: node set-status.mjs <num> <State> --note 'context'.","Re-run reply-watch -- once the tracker reflects reality, the conflicting suggestions collapse."],"exampleFix":"# before\nConflicting status recommendations require manual review:\n  #42: Interview (1 reply) vs Rejected (2 replies) — no automatic update\n# after: resolve by hand from the actual emails, most recent wins\n$ node set-status.mjs 42 Rejected --note 'rejection email 2026-08-19 confirmed'","handlingStrategy":"validation","validationCode":"// Pre-group replies per tracker row and surface disagreements before classification\nfunction findConflicts(repliesByNum) {\n  return [...repliesByNum].filter(([, rs]) =>\n    new Set(rs.map(r => r.suggestedStatus)).size > 1\n  ).map(([num]) => num);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Process reply-watch frequently (daily) so contradictory replies arrive in separate, resolvable runs.","Keep one tracker row per distinct application; split same-company different-role mail into separate rows.","Resolve conflicts with node set-status.mjs and a dated note instead of editing the table by hand."],"tags":["reply-watch","status-conflict","manual-review","tracker","classification"],"backgroundTag":"conflicting-state-update","analyzedSha":"60398d6549a46f5266929538af21cfab94badc75","analyzedAt":"2026-08-20T23:00:06.764Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}