Invoice-to-contract matching fails on obvious matches (bikosigma invoice<->contract):
{"matches": []} because the prompt lacks the data needed to reason about the matchformat-document-summary in llm_decision.clj currently sends skeletal summaries. Enrich per type:
Invoice — add: line items (description, quantity, unit, amount), service period, PO/GR references, payment terms, due date
Contract — add: title, description, contract type, deliverables, base fee, variable components, payment schedule, PO references, currency, total value
Purchase Order — add: line items (description, quantity, unit, amount), contract reference, requisition number
GRN — add: line items (description, quantity-received, unit)
Send all line items/deliverables, no cap. Gemini 2.5 Flash has 1M token context; prompt truncation deferred until needed.
description-overlap SignalToken-level Jaccard similarity between document descriptions.
line-items[*].description and contract deliverables[*]|A ∩ B| / |A ∪ B|date-within-periodCurrent: requires both contract dates + invoice service period. All must be present.
New cascade:
invoice-date >= effective-dateinvoice-date against contract date rangeBefore: 0.6 * 0.787 + 0.4 * 0.0 = 0.472
After (description-overlap ~+25, date-within-period +20):
45/100 = 0.450.6 * 0.787 + 0.4 * 0.45 = 0.652Still below 0.70 auto-match threshold → goes to LLM, which now has enough data to match confidently.
src/com/getorcha/workers/matching/llm_decision.clj — format-document-summarysrc/com/getorcha/workers/matching/evidence.clj — collect-signals, new description-overlap + relaxed date-within-periodtest/com/getorcha/workers/matching/llm_decision_test.clj — updated test fixturestest/com/getorcha/workers/matching/evidence_test.clj — new signal tests