Email-Reactor fail-closed fix — classifier failure / partner mail no longer auto-archived (MC #103815)
Incident / Root Cause
~/system/daemons/email-agent.js was FAIL-OPEN. When Ollama classification failed (request timeout, JSON parse error, or no-JSON-match), ollamaClassify resolved to {category:'INFO', priority:'low'}. The auto-archive block then archived any info/spam/own row. The strategic-partner elevation block only ran when dbCategory === 'ACTION', so a misclassified partner email was never elevated.
Net effect: A revenue email from strategic partner Asmir Merdžanović ("QODY" project, email #9661, 2026-06-13) was silently auto-archived and never answered until he re-sent it 2026-06-17.
Fix (FAIL-CLOSED) — 3 Changes
- All three
ollamaClassifyfailure branches now resolve{category:'ACTION', priority:'medium', _classifyFailed:true}with distinct reason (timeout/parse_error/no_json) — an unclassifiable email defaults to actionable, never FYI/archive. matchStrategicPartner()now runs independent of category (guardif (!ARGS.dryRun)); on a partner match it elevates to ACTION viaemailInbox.updateClassification(...,'ACTION','high'), sets partner_tier, fires CEO push.- Auto-archive is guarded by
_skipArchiveDueToClassifyFailand partner-elevated rows (cat patched to 'action') never reach the archive branch.
New helper: updateClassification(id, classification, priority) added + exported in ~/system/tools/email-inbox.js.
Verification
node --checkclean on both files- Simulation harness
/tmp/evidence-103815/sim.test.js= 39 PASS / 0 FAIL incl. the exact Asmir/QODY regression - Independent verification: native verifier (7/7 atomic claims) + Proveo P2P PASS (mesh-thr-95c7fb0b / mesh-msg-008f947c)
Deployment
Daemon com.john.email-agent is StartInterval (spawns fresh node each cycle) → fix is live on the next cycle, no restart needed.
Residual Known Gap (Follow-on MC #103819)
Two heuristic INFO fallbacks OUTSIDE ollamaClassify (circuit-breaker path ~L2161 and promise-rejection catch ~L2177) do not yet carry _classifyFailed; narrow exposure (non-partner email during Ollama TCP error / breaker-open with no heuristic keyword match).
Lesson
Email triage must FAIL-CLOSED — an email the classifier could not process must never be silently archived; strategic-partner safety net must be category-independent.
Evidence bundle: /tmp/evidence-103815/
MC task: #103815
Date: 2026-06-17