Live (part 4) — notify on match SUGGESTION + MISALIGNMENT
Goal¶
Part 4 of T-037. (a) New notifyMatchSuggestion producer for ambiguous / new-vendor /
no-match cases (today only console.logged) so misses surface for QA. (b) Wire the
misalignment/integrity alerts (notifyDataIntegrity / integrityEmail) to the matchers —
honors [[feedback_no_silent_fixes]] (detect + notify, never silently correct).
Optional extras (dormant infra, same system — fold here or split later)¶
- Resend webhook handler pages/api/webhooks/resend.ts (bounce/complaint) — stub, no logic.
- Overdue-invoice cron /api/cron/check-overdue-invoices.ts — doesn't exist.
- Verify RESEND_API_KEY set in PROD Vercel (gates all email).
Log¶
- 2026-06-14 created (T-037 split, owner).
Decision log¶
2026-07-09 — routed to Accounting (Diagnostics) (owner-confirmed)¶
- ✅ Read AGENTS.md. Owner confirmation (2026-07-09, verbatim): "T-041 for Accounting (Diagnostics) it is". Scope note from the 2026-07-09 backlog review: the core (match-SUGGESTION producer + misalignment alerts) is untouched and real; the "dormant extras" (Resend bounce webhook + delivery log) are carved out to T-162 P3 (User Management) — do not build them here. Queue behind the agent's active T-156/T-157/T-158 cluster; sibling re-scoped tasks T-038 + T-040 are the same producer family and also theirs.
- Source: EOP Local Assistance (fork) · session edb0abc7-6373-449b-8e31-379fd38d391b
2026-07-10 — BUILT + SHIPPED (owner: "proceed") — status → done¶
- ✅ Read AGENTS.md · checked the board by scope (no dup — T-162 owns consumption/preferences; the dormant extras are its P3 per the 2026-07-09 carve-out and were NOT built here) · tracking T-041.
- Source: Accounting (Diagnostics) · https://claude.ai/code/session_01G58Y71noihrYCDEDMexmea
- (a) Suggestions surface: new
notifyMatchSuggestionproducer + a NEW notification typematch_suggestion(topicbooks), registered across the full taxonomy (type union, labels, topic map, TYPE_META, bell + inbox icon/color maps — the exhaustiveRecord<NotificationType,…>pattern makes tsc enforce completeness). Severityinfo(advisory queue: a human should look, nothing is wrong yet). Wired from the two EVENT-driven hooks (tx sync + invoice upload); the engine's per-suggestiondetailstrings are already self-contained. - Noise controls (why not everywhere): suggestions are DERIVED fresh per run and never
persisted (owner design), so the Refresh-button
rescanMatching— which re-derives the same suggestions every click — stays silent per its own documented no-noise contract; and per-batch suggestion notifications cap at 10 (the T-040 digest carries the full count). - (b) Misalignment alerts: engine FAILURES now fire
notifyDataIntegrity(warning → also emails; watchdog-exempt in the preference engine): all three engine catch-blocks on the tx-sync path + the invoice-upload path — which previously could throw through the seam; it now swallows LOUDLY (notify + note), honoring both the no-silent-fixes rule and the seam contract ("hooks may never fail the create"). The missing-defaultGl throw inapplyVendorLinkis exactly the case this catches. - Carve-out honored: no Resend webhook, no delivery log, no preference/consumption work —
T-162 P3 / User Management. Coordination note left on T-162:
match_suggestionis a new row their matrix picks up automatically from TYPE_META. - Verification: 6 new tests (
matchSuggestionNotify.test.ts): per-suggestion notify on both event paths; the 10-cap; rescan silence (behavioral, not just static); engine-throw → data-integrity alert on both paths with the hook surviving. Suite 663/663; unfiltered tsc clean. - Commit SHAs (append-only): this ship commit (T-041 in subject; merged via PR).
- Deploy: pending (main 🟡🟡 manual).
- Blast radius: notification volume + one new NotificationType (
match_suggestion— UM's matrix/inbox pick it up from the taxonomy maps). Engine behavior change: an invoice-upload matcher crash no longer propagates to the create seam (was caught there anyway; now notified).