"""Principle-level gold matching (importance layer #153, component 1). Flags the SPECIFIC principle a chair relied on — not the whole precedent. A chair cites a precedent for ONE holding; we embed the citation's ``match_context`` (or a digest's ``headline_holding``) and cosine-match it to the principles extracted from that precedent. The best match ≥ threshold gets the flag: • OUR_CHAIR (דפנה) cited it → ``gold_chair`` (tier-1, protective in the cull) • another committee chair cited it → ``chair_cited`` (tier-2, weight not protection) • a digest highlights it → ``gold_digest`` (tier-1) Embedding-only — NO LLM, so it is cheap and re-runnable (the periodic refresh job). Tuned toward recall (HALACHA_GOLD_MATCH_THRESHOLD): missing a chair-relied principle (buried by the cull) is worse than over-protecting one. """ from __future__ import annotations import logging from uuid import UUID from legal_mcp import config from legal_mcp.services import db, embeddings logger = logging.getLogger(__name__) async def _embed_all(texts: list[str]) -> list[list[float]]: """Embed in Voyage-sized batches (embed_texts already chunks at 128).""" return await embeddings.embed_texts(texts, input_type="query") if texts else [] async def match_all(threshold: float | None = None, apply: bool = False) -> dict: """Run gold matching over all chair citations + digests. Returns a stats dict; when ``apply`` writes the flags (idempotent — clears prior flags first). Dry-run computes everything but writes nothing. """ threshold = config.HALACHA_GOLD_MATCH_THRESHOLD if threshold is None else threshold if apply: cleared = await db.reset_principle_gold() logger.info("principle_gold: cleared %d prior flags before re-match", cleared) citations = await db.gold_chair_citations() digests = await db.gold_digest_holdings() cit_vecs = await _embed_all([c["match_context"] for c in citations]) dig_vecs = await _embed_all([d["holding_text"] for d in digests]) stats = {"threshold": threshold, "applied": apply, "chair_citations": len(citations), "digests": len(digests), "gold_chair": 0, "chair_cited": 0, "gold_digest": 0, "chair_no_match": 0, "digest_no_match": 0, "samples": []} async def _flag(case_law_id, vec, *, gold_chair=False, gold_digest=False, chair_cited=False, label=""): match = await db.nearest_original_principle(case_law_id, list(vec)) if match is None or match[1] < threshold: return None hid, sim = match if apply: await db.set_principle_gold( UUID(hid), gold_chair=gold_chair, gold_digest=gold_digest, chair_cited=chair_cited, score=sim) if len(stats["samples"]) < 12: stats["samples"].append({"label": label, "halacha_id": hid, "sim": round(sim, 3)}) return hid for c, vec in zip(citations, cit_vecs): cid = c["cited_case_law_id"] if c["is_our_chair"]: hid = await _flag(cid, vec, gold_chair=True, label="chair:דפנה") stats["gold_chair" if hid else "chair_no_match"] += 1 else: hid = await _flag(cid, vec, chair_cited=True, label=f"chair:{c['citing_chair']}") stats["chair_cited" if hid else "chair_no_match"] += 1 for d, vec in zip(digests, dig_vecs): hid = await _flag(d["linked_case_law_id"], vec, gold_digest=True, label="digest") stats["gold_digest" if hid else "digest_no_match"] += 1 if apply: stats["coverage"] = await db.gold_coverage_stats() return stats