Activate the MONDO close-match guard in disease glom (with build-vs-build clique-diff tool)#883
Activate the MONDO close-match guard in disease glom (with build-vs-build clique-diff tool)#883gaurav wants to merge 3 commits into
Conversation
A new tools/clique_diff package + `babel-clique-diff` entry point that compares the finished JSONL compendia of two builds and reports which cliques split/merged/lost members, and — the headline signal — which CURIEs were dropped from the output entirely. This is distinct from source-impact-report: that answers "what does adding source X do?" by re-glomming intermediate files with vs. without one source; this answers "how did the cliques change between build A and build B?" given the same inputs but different code, config, or upstream data. It works on finished compendia rather than glom state, so it can also compare a local build against a published stars.renci.org build without re-running glom — useful for validating any glom-logic change or as a release regression check. Includes unit tests for the four destination kinds (kept/regrouped/moved/dropped) and a docs/tools/README.md entry. The test module has a unique basename (test_clique_diff_tool) to avoid a pytest prepend-mode collision with tests/test_clique_diff.py. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
compute_cliques_for_impact_report() read MONDO_close with close_mondos[x[0]].add(x[1]), keying the MONDO subject to column 2 (the predicate, "oio:closeMatch") instead of column 3 (the close-match object). No clique ever contains the literal predicate string, so glom's `close=` guard never matched and was a silent no-op on every build, letting close (but not exact) matches collapse into exact cliques. Key on x[2] instead, matching the (stuff[0], stuff[2]) parsing every other concord in this function already uses. Activating the guard is a deliberate, SME-reviewable change: on a full local disease build it drops 1,219 MEDDRA identifiers from Disease.txt (present only via the dormant guard's incorrect close-as-exact merges). The before/after impact analysis and the SME-facing dropped-members list are committed under docs/pipelines/diseasephenotype/mondo-close-match-guard/. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Generated by babel-clique-diff against two full local disease builds (x[1] dormant guard vs x[2] active guard), differing only in the one-line MONDO_close parsing fix. glom is deterministic (two x[1] builds were clique-identical), so the diff is all signal. - README.md — the bug, the fix, and the SME decision (1,219 MEDDRA codes leave Disease.txt). - clique-diff.csv — every changed clique with destination_kind (kept/regrouped/moved/dropped). - dropped-members.csv — the 1,219 dropped CURIEs with the MONDO clique each left. - summary.json — per-compendium counts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cross-link the deferred x[1]->x[2] close-match-guard fix to its dedicated PR (#883), and note the concrete impact (~1,219 MEDDRA identifiers dropped from Disease.txt) that the follow-up's before/after analysis quantifies. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Heads up: the |
The extracted babel-clique-diff commit linked to #883's mondo-close-match-guard evidence dir, which is not present on this standalone tool branch. Replace it with the general commit-location convention for clique-diff outputs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cross-link the deferred x[1]->x[2] close-match-guard fix to its dedicated PR (#883), and note the concrete impact (~1,219 MEDDRA identifiers dropped from Disease.txt) that the follow-up's before/after analysis quantifies. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add docs/sources/MP/disjointness.md explaining the post-glom split, why unique_prefixes/concord-dropping are insufficient, and the measured impact (added/split/moved/deleted) from babel-clique-diff comparing the overlap-allowed build to the disjoint build. Commit the clique-diff CSV + summary JSON under docs/sources/MP/disjointness/. Update the MP and HP READMEs: MP/HP are now disjoint, so an MP clique carries only the Mammalia taxon and an HP clique only Homo sapiens (correcting the earlier "mixed cliques carry both taxa" note). Cross-link prior PRs (#790, #300, #883, #742/#781). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds `babel-clique-diff`, a build-vs-build clique diff tool that
compares the cliques in two
finished Babel compendium builds and reports, per `(changed
before-clique, after-destination)`
group, whether members were `kept`, `regrouped` (split into a different
clique), `moved` (retyped
into a different compendium file), or `dropped` (absent from every
compared after-compendium). It
emits a per-clique CSV and an optional per-compendium summary JSON (with
`dropped_member_count` /
`regrouped_member_count` as the headline regression signals).
```
uv run babel-clique-diff \
--before <baseline-compendia-dir> --after <comparison-compendia-dir> \
--files Disease.txt PhenotypicFeature.txt \
--out-csv clique-diff.csv --out-json clique-diff.summary.json
```
Unlike `source-impact-report` (which is hard-wired to an "exclude one
source" before/after and only
models added/expanded/merged cliques), this tool diffs **two arbitrary
builds** and can express
**splits and deletions** — needed whenever a config/policy change
regroups or drops members of
existing cliques rather than just adding new ones.
## Provenance / coordination
This is the `babel-clique-diff` commit extracted from PR #883
(`fix-mondo-close-match-guard`), so it can land independently of #883's
unrelated MONDO
close-match-guard change. It is stdlib-only and purely additive (new
`tools/clique_diff/` package,
a unit test, and one `[project.scripts]` entry).
- **Merge this before** the follow-up "MP kept disjoint from HP" PR,
which uses this tool to produce
its split/deleted impact report.
- **#883 should rebase** to drop its now-duplicated `babel-clique-diff`
commit once this merges.
## Test plan
- `uv run pytest tests/tools/test_clique_diff_tool.py -q` — green (5
passed): the four destination
kinds (kept/regrouped/moved/dropped), the cross-file moved-vs-dropped
distinction, the
unchanged-cliques-omitted rule, and malformed-JSONL rejection.
- `uv run pytest -m unit -q` — green (241 passed), collects cleanly
(unique test basename, no
`tests/tools/__init__.py`).
- `uv run babel-clique-diff --help` — console script resolves.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The NOTE in compute_cliques_for_impact_report and disjointness.md's "Related work" pointed the deferred close-match-guard fix at the old combined PR #883. That PR was split: the babel-clique-diff tool is now #885 and the close-match guard activation (keying glom's close= map on the object, x[2], rather than the predicate, x[1]) is now #888 (fix-mondo-close-guard). Point both references at the concrete PRs so they don't go stale. No behavior change -- this branch still preserves the predicate-keyed no-op that #888 will fix. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Build-vs-build diff isolating the close-match guard activation (#888, issue #912): both compendia built from identical cached disease intermediates, differing only in diseasephenotype.py keying close_mondos on the object (x[2]) vs the predicate (x[1]). Result: 1,218 MEDDRA identifiers drop from Disease.txt (the close-match terms that reached MONDO cliques via the UMLS concord), matching the ~1,219 figure from #883. PhenotypicFeature.txt is essentially unaffected. Indexes the new docs/sources/MONDO entry in docs/sources/README.md and CLAUDE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Closing: everything in this PR now lives either in Verified against
The one file with no direct counterpart on #888 is Nothing needs cherry-picking. The guard fix continues on #888. |
Important
Superseded by #888. The MONDO close-match guard fix has been split onto a clean,
main-based branch in #888 (the samex[1]→x[2]change applied directly tobuild_compendium, plus a focused regression test), and the build-vs-build clique-diff toolalready merged separately via #885. If #888 merges first, this guard change drops out of this
PR automatically once
mainis merged in — leaving #883 with nothing unique to contribute.Prefer reviewing #888 for the guard fix in isolation; this PR is kept only as the home of the
full add-mpo-base before/after impact analysis under
docs/pipelines/diseasephenotype/mondo-close-match-guard/.Summary
Fixes a latent bug in how the disease/phenotype build reads the
MONDO_closeconcord, whichleft glom's close-match guard a silent no-op, and adds a reusable build-vs-build clique-diff
tool plus the before/after impact analysis that this change requires.
This is the dedicated follow-up promised in #790, where the same code was touched only enough to
stop the build crashing (validating the real 3-column
MONDO_closeformat while preservingthe dormant
x[1]behaviour). Activating the guard changes disease clique merging broadly and isorthogonal to adding MP, so it lives here with its own evidence.
Note
Based on
add-mpo(#790), notmain— it builds on that PR'scompute_cliques_for_impact_reportrefactor. Merge #790 first; this PR will retarget to
mainautomatically.The bug
compute_cliques_for_impact_report()readMONDO_close(a 3-columnsubject predicate objectconcord) with
close_mondos[x[0]].add(x[1])— keying the MONDO subject to column 2, thepredicate (
oio:closeMatch) instead of column 3, the close-match object. No clique evercontains the literal string
oio:closeMatch, so glom'sclose=guard (if cd in newset) nevermatched. The guard has therefore never fired, on
mainand before it; close (but not exact)matches were free to collapse into exact cliques.
The fix is one line of intent: key on
x[2], matching the(stuff[0], stuff[2])parsing everyother concord in that function already uses.
Impact (why this needs SME review)
Measured on a full local
diseasebuild (Biolink 4.4.3), same intermediate ids/concords,differing only in
x[1]vsx[2]. glom is deterministic — twox[1]builds were clique-identical— so every difference is signal, not run-to-run noise.
Disease.txt. They were present only becausethe dormant guard let them merge into a MONDO disease clique; correctly kept out, they have no
independent disease typing in this pipeline and leave the compendium entirely.
PhenotypicFeature.txtis essentially unaffected (the close pairs are MONDO-subject).Dropping 1,219 MEDDRA codes is correct if they are genuinely distinct concepts (the guard's
premise), but a coverage loss if anything relies on that MEDDRA → MONDO normalization. Per the
project rule against dropping valid identifiers without good reason, this is an SME call — the
evidence is in
docs/pipelines/diseasephenotype/mondo-close-match-guard/(README.md,clique-diff.csv,dropped-members.csv,summary.json).New tool:
babel-clique-diffA reusable build-vs-build clique diff (
tools/clique_diff) that compares the finished compendia oftwo builds and reports split/merged/lost cliques and, crucially, dropped CURIEs.
It is deliberately distinct from
source-impact-report: that answers "what does adding sourceX do?" by re-glomming intermediates with vs. without one source; this answers "how did the cliques
change between build A and build B?" given the same inputs but different code/config/data.
Because it works on finished compendia rather than glom state, it can also compare a local build
against a published
stars.renci.orgbuild with no re-glom — useful for validating any glom-logicchange (close-match,
unique_prefixes, overuse filtering) or as a release regression check.Test plan
uv run ruff check/ruff format --check— clean.uv run rumdl check .— clean.uv run pytest -m unit -q— green (243 passed), including newtests/tools/test_clique_diff_tool.py.Out of scope
x[1](the production behaviour of that PR) and isnot regenerated here.
🤖 Generated with Claude Code