microbiomekg 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. microbiomekg-0.1.0/.gitignore +33 -0
  2. microbiomekg-0.1.0/.readthedocs.yaml +19 -0
  3. microbiomekg-0.1.0/CHANGELOG.md +135 -0
  4. microbiomekg-0.1.0/CITATION.cff +34 -0
  5. microbiomekg-0.1.0/CONTRIBUTING.md +84 -0
  6. microbiomekg-0.1.0/LICENSE +21 -0
  7. microbiomekg-0.1.0/PKG-INFO +230 -0
  8. microbiomekg-0.1.0/README.md +188 -0
  9. microbiomekg-0.1.0/bench/README.md +226 -0
  10. microbiomekg-0.1.0/blueprint.json +1863 -0
  11. microbiomekg-0.1.0/docs/benchmarks.md +227 -0
  12. microbiomekg-0.1.0/docs/claims/README.md +62 -0
  13. microbiomekg-0.1.0/docs/claims/benchmarks.md +149 -0
  14. microbiomekg-0.1.0/docs/claims/queries-by-task.md +67 -0
  15. microbiomekg-0.1.0/docs/conf.py +67 -0
  16. microbiomekg-0.1.0/docs/design/capability-gaps.md +774 -0
  17. microbiomekg-0.1.0/docs/design/library-pipeline.md +144 -0
  18. microbiomekg-0.1.0/docs/design/release-readiness.md +218 -0
  19. microbiomekg-0.1.0/docs/evaluation.md +794 -0
  20. microbiomekg-0.1.0/docs/getting-started.md +78 -0
  21. microbiomekg-0.1.0/docs/index.md +64 -0
  22. microbiomekg-0.1.0/docs/model.md +2365 -0
  23. microbiomekg-0.1.0/docs/queries-by-task.md +134 -0
  24. microbiomekg-0.1.0/docs/requirements.txt +5 -0
  25. microbiomekg-0.1.0/docs/research/existing-graphs-and-schemas.md +953 -0
  26. microbiomekg-0.1.0/docs/research/researcher-workflows.md +3017 -0
  27. microbiomekg-0.1.0/docs/research/source-formats.md +1096 -0
  28. microbiomekg-0.1.0/docs/sources.md +1006 -0
  29. microbiomekg-0.1.0/docs/usecases-and-pitfalls.md +2735 -0
  30. microbiomekg-0.1.0/microbiomekg/__init__.py +41 -0
  31. microbiomekg-0.1.0/microbiomekg/api.py +96 -0
  32. microbiomekg-0.1.0/microbiomekg/blueprints/bugsigdb.json +167 -0
  33. microbiomekg-0.1.0/microbiomekg/blueprints/card.json +203 -0
  34. microbiomekg-0.1.0/microbiomekg/blueprints/chembl.json +166 -0
  35. microbiomekg-0.1.0/microbiomekg/blueprints/core.json +229 -0
  36. microbiomekg-0.1.0/microbiomekg/blueprints/gutmdisorder.json +135 -0
  37. microbiomekg-0.1.0/microbiomekg/blueprints/hmdb.json +81 -0
  38. microbiomekg-0.1.0/microbiomekg/blueprints/kegg.json +62 -0
  39. microbiomekg-0.1.0/microbiomekg/blueprints/maier2018.json +186 -0
  40. microbiomekg-0.1.0/microbiomekg/blueprints/masi.json +467 -0
  41. microbiomekg-0.1.0/microbiomekg/blueprints/mimedb.json +42 -0
  42. microbiomekg-0.1.0/microbiomekg/blueprints/njc19.json +218 -0
  43. microbiomekg-0.1.0/microbiomekg/blueprints/reactome.json +85 -0
  44. microbiomekg-0.1.0/microbiomekg/blueprints/zimmermann2019.json +215 -0
  45. microbiomekg-0.1.0/microbiomekg/cli.py +105 -0
  46. microbiomekg-0.1.0/microbiomekg/conditions.py +411 -0
  47. microbiomekg-0.1.0/microbiomekg/coverage.py +347 -0
  48. microbiomekg-0.1.0/microbiomekg/download.py +1650 -0
  49. microbiomekg-0.1.0/microbiomekg/drugs.py +220 -0
  50. microbiomekg-0.1.0/microbiomekg/embedder.py +120 -0
  51. microbiomekg-0.1.0/microbiomekg/fragments.py +238 -0
  52. microbiomekg-0.1.0/microbiomekg/mcp/microbiomekg.skills/amr.md +96 -0
  53. microbiomekg-0.1.0/microbiomekg/mcp/microbiomekg.skills/drugs.md +299 -0
  54. microbiomekg-0.1.0/microbiomekg/mcp/microbiomekg.skills/evidence_audit.md +160 -0
  55. microbiomekg-0.1.0/microbiomekg/mcp/microbiomekg.skills/metabolites_pathways.md +205 -0
  56. microbiomekg-0.1.0/microbiomekg/mcp/microbiomekg.skills/reconciliation.md +208 -0
  57. microbiomekg-0.1.0/microbiomekg/mcp/microbiomekg.skills/signature_enrichment.md +127 -0
  58. microbiomekg-0.1.0/microbiomekg/mcp/microbiomekg.skills/taxon_disease_evidence.md +168 -0
  59. microbiomekg-0.1.0/microbiomekg/mcp/microbiomekg_mcp.yaml +108 -0
  60. microbiomekg-0.1.0/microbiomekg/ontology/__init__.py +163 -0
  61. microbiomekg-0.1.0/microbiomekg/ontology/__main__.py +10 -0
  62. microbiomekg-0.1.0/microbiomekg/ontology/bugsigdb.py +111 -0
  63. microbiomekg-0.1.0/microbiomekg/ontology/card.py +293 -0
  64. microbiomekg-0.1.0/microbiomekg/ontology/chembl.py +276 -0
  65. microbiomekg-0.1.0/microbiomekg/ontology/core.py +108 -0
  66. microbiomekg-0.1.0/microbiomekg/ontology/gutmdisorder.py +148 -0
  67. microbiomekg-0.1.0/microbiomekg/ontology/hmdb.py +225 -0
  68. microbiomekg-0.1.0/microbiomekg/ontology/kegg.py +86 -0
  69. microbiomekg-0.1.0/microbiomekg/ontology/maier2018.py +419 -0
  70. microbiomekg-0.1.0/microbiomekg/ontology/masi.py +723 -0
  71. microbiomekg-0.1.0/microbiomekg/ontology/mimedb.py +266 -0
  72. microbiomekg-0.1.0/microbiomekg/ontology/njc19.py +417 -0
  73. microbiomekg-0.1.0/microbiomekg/ontology/reactome.py +161 -0
  74. microbiomekg-0.1.0/microbiomekg/ontology/vocabulary.py +427 -0
  75. microbiomekg-0.1.0/microbiomekg/ontology/zimmermann2019.py +581 -0
  76. microbiomekg-0.1.0/microbiomekg/pipeline.py +966 -0
  77. microbiomekg-0.1.0/microbiomekg/preparation.py +129 -0
  78. microbiomekg-0.1.0/microbiomekg/preps/__init__.py +8 -0
  79. microbiomekg-0.1.0/microbiomekg/preps/prep_bugsigdb.py +805 -0
  80. microbiomekg-0.1.0/microbiomekg/preps/prep_card.py +724 -0
  81. microbiomekg-0.1.0/microbiomekg/preps/prep_chembl.py +714 -0
  82. microbiomekg-0.1.0/microbiomekg/preps/prep_gutmdisorder.py +823 -0
  83. microbiomekg-0.1.0/microbiomekg/preps/prep_hmdb.py +736 -0
  84. microbiomekg-0.1.0/microbiomekg/preps/prep_kegg.py +337 -0
  85. microbiomekg-0.1.0/microbiomekg/preps/prep_maier2018.py +794 -0
  86. microbiomekg-0.1.0/microbiomekg/preps/prep_masi.py +1081 -0
  87. microbiomekg-0.1.0/microbiomekg/preps/prep_mimedb.py +585 -0
  88. microbiomekg-0.1.0/microbiomekg/preps/prep_njc19.py +547 -0
  89. microbiomekg-0.1.0/microbiomekg/preps/prep_reactome.py +372 -0
  90. microbiomekg-0.1.0/microbiomekg/preps/prep_taxonomy.py +321 -0
  91. microbiomekg-0.1.0/microbiomekg/preps/prep_zimmermann2019.py +1018 -0
  92. microbiomekg-0.1.0/microbiomekg/rawdata.py +91 -0
  93. microbiomekg-0.1.0/microbiomekg/reconcile.py +652 -0
  94. microbiomekg-0.1.0/microbiomekg/serve.py +108 -0
  95. microbiomekg-0.1.0/microbiomekg/sources.py +208 -0
  96. microbiomekg-0.1.0/microbiomekg/tables.py +306 -0
  97. microbiomekg-0.1.0/pyproject.toml +130 -0
  98. microbiomekg-0.1.0/scripts/build.py +16 -0
  99. microbiomekg-0.1.0/scripts/build_blueprint.py +16 -0
  100. microbiomekg-0.1.0/scripts/check_install.py +114 -0
  101. microbiomekg-0.1.0/scripts/fetch.py +16 -0
  102. microbiomekg-0.1.0/scripts/serve.py +16 -0
  103. microbiomekg-0.1.0/scripts/sync_agent_adapters.py +297 -0
  104. microbiomekg-0.1.0/tests/claims/amr.md +54 -0
  105. microbiomekg-0.1.0/tests/claims/drugs.md +190 -0
  106. microbiomekg-0.1.0/tests/claims/evidence_audit.md +96 -0
  107. microbiomekg-0.1.0/tests/claims/manifest.md +54 -0
  108. microbiomekg-0.1.0/tests/claims/metabolites_pathways.md +132 -0
  109. microbiomekg-0.1.0/tests/claims/reconciliation.md +108 -0
  110. microbiomekg-0.1.0/tests/claims/signature_enrichment.md +56 -0
  111. microbiomekg-0.1.0/tests/claims/taxon_disease_evidence.md +78 -0
  112. microbiomekg-0.1.0/tests/conftest.py +72 -0
  113. microbiomekg-0.1.0/tests/fixtures/bugsigdb_mini.csv +49 -0
  114. microbiomekg-0.1.0/tests/fixtures/card_mini/card-data/PMID.tsv +97 -0
  115. microbiomekg-0.1.0/tests/fixtures/card_mini/card-data/aro_index.tsv +41 -0
  116. microbiomekg-0.1.0/tests/fixtures/card_mini/card-data/card.json +7435 -0
  117. microbiomekg-0.1.0/tests/fixtures/card_mini/card-ontology/aro.obo +4195 -0
  118. microbiomekg-0.1.0/tests/fixtures/card_mini/taxdump/delnodes.dmp +0 -0
  119. microbiomekg-0.1.0/tests/fixtures/card_mini/taxdump/merged.dmp +2 -0
  120. microbiomekg-0.1.0/tests/fixtures/card_mini/taxdump/names.dmp +551 -0
  121. microbiomekg-0.1.0/tests/fixtures/card_mini/taxdump/nodes.dmp +84 -0
  122. microbiomekg-0.1.0/tests/fixtures/card_mini/taxdump/rankedlineage.dmp +84 -0
  123. microbiomekg-0.1.0/tests/fixtures/chembl_mini/mechanism.jsonl +30 -0
  124. microbiomekg-0.1.0/tests/fixtures/chembl_mini/molecule_max_phase4.jsonl +12 -0
  125. microbiomekg-0.1.0/tests/fixtures/chembl_mini/target.jsonl +10 -0
  126. microbiomekg-0.1.0/tests/fixtures/duvallet2017_genera.tsv +52 -0
  127. microbiomekg-0.1.0/tests/fixtures/gutmdisorder_mini/human.xlsx +0 -0
  128. microbiomekg-0.1.0/tests/fixtures/gutmdisorder_mini/mouse.xlsx +0 -0
  129. microbiomekg-0.1.0/tests/fixtures/hmdb_mini/hmdb_metabolites.xml +820 -0
  130. microbiomekg-0.1.0/tests/fixtures/kegg_mini/conv_compound_pubchem.tsv +2 -0
  131. microbiomekg-0.1.0/tests/fixtures/kegg_mini/link_compound_pathway.tsv +8 -0
  132. microbiomekg-0.1.0/tests/fixtures/kegg_mini/list_compound.tsv +16 -0
  133. microbiomekg-0.1.0/tests/fixtures/kegg_mini/list_genome.tsv +2 -0
  134. microbiomekg-0.1.0/tests/fixtures/kegg_mini/list_pathway.tsv +4 -0
  135. microbiomekg-0.1.0/tests/fixtures/kegg_mini/list_pathway_hsa.tsv +2 -0
  136. microbiomekg-0.1.0/tests/fixtures/maier2018_mini/NIHMS76168-supplement-Supplementary_table_1.xlsx +0 -0
  137. microbiomekg-0.1.0/tests/fixtures/maier2018_mini/NIHMS76168-supplement-Supplementary_table_2.xlsx +0 -0
  138. microbiomekg-0.1.0/tests/fixtures/maier2018_mini/NIHMS76168-supplement-Supplementary_table_3.xlsx +0 -0
  139. microbiomekg-0.1.0/tests/fixtures/maier2018_mini/NIHMS76168-supplement-Supplementary_table_4.xlsx +0 -0
  140. microbiomekg-0.1.0/tests/fixtures/make_duvallet2017_reference.py +66 -0
  141. microbiomekg-0.1.0/tests/fixtures/make_gutmdisorder_mini.py +364 -0
  142. microbiomekg-0.1.0/tests/fixtures/make_hmdb_mini.py +502 -0
  143. microbiomekg-0.1.0/tests/fixtures/make_maier2018_mini.py +479 -0
  144. microbiomekg-0.1.0/tests/fixtures/make_masi_mini.py +822 -0
  145. microbiomekg-0.1.0/tests/fixtures/make_mimedb_mini.py +509 -0
  146. microbiomekg-0.1.0/tests/fixtures/make_njc19_mini.py +187 -0
  147. microbiomekg-0.1.0/tests/fixtures/make_zimmermann2019_mini.py +571 -0
  148. microbiomekg-0.1.0/tests/fixtures/masi_mini/MASI_v1.0_download_microbeDiseaseAssociationRecords.xlsx +0 -0
  149. microbiomekg-0.1.0/tests/fixtures/masi_mini/MASI_v1.0_download_microbeSubstanceInteractionRecords_ver20200928.xlsx +0 -0
  150. microbiomekg-0.1.0/tests/fixtures/masi_mini/MASI_v1.0_download_microbesInfo.xlsx +0 -0
  151. microbiomekg-0.1.0/tests/fixtures/masi_mini/MASI_v1.0_download_substanceInfo.xlsx +0 -0
  152. microbiomekg-0.1.0/tests/fixtures/mimedb_mini/mimedb_metabolites_v1.csv +12 -0
  153. microbiomekg-0.1.0/tests/fixtures/mimedb_mini/mimedb_metabolites_v2.csv +13 -0
  154. microbiomekg-0.1.0/tests/fixtures/mimedb_mini/mimedb_microbes_v1.csv +7 -0
  155. microbiomekg-0.1.0/tests/fixtures/mimedb_mini/mimedb_microbes_v2.csv +9 -0
  156. microbiomekg-0.1.0/tests/fixtures/mondo_mini.obo +361 -0
  157. microbiomekg-0.1.0/tests/fixtures/njc19_mini/41597_2020_516_MOESM1_ESM.xlsx +0 -0
  158. microbiomekg-0.1.0/tests/fixtures/reactome_mini/ChEBI2Reactome.txt +9 -0
  159. microbiomekg-0.1.0/tests/fixtures/reactome_mini/ReactomePathways.txt +8 -0
  160. microbiomekg-0.1.0/tests/fixtures/reactome_mini/ReactomePathwaysRelation.txt +8 -0
  161. microbiomekg-0.1.0/tests/fixtures/taxdump_mini/delnodes.dmp +3 -0
  162. microbiomekg-0.1.0/tests/fixtures/taxdump_mini/merged.dmp +7 -0
  163. microbiomekg-0.1.0/tests/fixtures/taxdump_mini/names.dmp +537 -0
  164. microbiomekg-0.1.0/tests/fixtures/taxdump_mini/nodes.dmp +221 -0
  165. microbiomekg-0.1.0/tests/fixtures/taxdump_mini/rankedlineage.dmp +220 -0
  166. microbiomekg-0.1.0/tests/fixtures/zimmermann2019_mini/41586_2019_1291_MOESM1_ESM.xlsx +0 -0
  167. microbiomekg-0.1.0/tests/mcp_support.py +268 -0
  168. microbiomekg-0.1.0/tests/prep_support.py +131 -0
  169. microbiomekg-0.1.0/tests/skill_claims.py +426 -0
  170. microbiomekg-0.1.0/tests/test_acceptance.py +3251 -0
  171. microbiomekg-0.1.0/tests/test_agent_adapters.py +106 -0
  172. microbiomekg-0.1.0/tests/test_api.py +118 -0
  173. microbiomekg-0.1.0/tests/test_build.py +1031 -0
  174. microbiomekg-0.1.0/tests/test_build_pipeline.py +531 -0
  175. microbiomekg-0.1.0/tests/test_card.py +926 -0
  176. microbiomekg-0.1.0/tests/test_chembl.py +806 -0
  177. microbiomekg-0.1.0/tests/test_conditions.py +310 -0
  178. microbiomekg-0.1.0/tests/test_coverage.py +142 -0
  179. microbiomekg-0.1.0/tests/test_docs_contract.py +224 -0
  180. microbiomekg-0.1.0/tests/test_documented_queries.py +173 -0
  181. microbiomekg-0.1.0/tests/test_drugs.py +196 -0
  182. microbiomekg-0.1.0/tests/test_fragments.py +421 -0
  183. microbiomekg-0.1.0/tests/test_gutmdisorder.py +718 -0
  184. microbiomekg-0.1.0/tests/test_hmdb.py +734 -0
  185. microbiomekg-0.1.0/tests/test_kegg.py +365 -0
  186. microbiomekg-0.1.0/tests/test_loader_contracts.py +163 -0
  187. microbiomekg-0.1.0/tests/test_maier2018.py +843 -0
  188. microbiomekg-0.1.0/tests/test_malformed_input.py +152 -0
  189. microbiomekg-0.1.0/tests/test_masi.py +1005 -0
  190. microbiomekg-0.1.0/tests/test_mcp_acceptance.py +205 -0
  191. microbiomekg-0.1.0/tests/test_mcp_manifest.py +207 -0
  192. microbiomekg-0.1.0/tests/test_mcp_skills.py +277 -0
  193. microbiomekg-0.1.0/tests/test_mimedb.py +692 -0
  194. microbiomekg-0.1.0/tests/test_njc19.py +699 -0
  195. microbiomekg-0.1.0/tests/test_ontology.py +414 -0
  196. microbiomekg-0.1.0/tests/test_packaging.py +150 -0
  197. microbiomekg-0.1.0/tests/test_prepare.py +219 -0
  198. microbiomekg-0.1.0/tests/test_reactome.py +368 -0
  199. microbiomekg-0.1.0/tests/test_reconcile.py +661 -0
  200. microbiomekg-0.1.0/tests/test_semantic_lookup.py +276 -0
  201. microbiomekg-0.1.0/tests/test_skill_claims.py +281 -0
  202. microbiomekg-0.1.0/tests/test_sources.py +191 -0
  203. microbiomekg-0.1.0/tests/test_tables.py +207 -0
  204. microbiomekg-0.1.0/tests/test_zimmermann2019.py +1100 -0
@@ -0,0 +1,33 @@
1
+ # Third-party raw input: 7.5 GB, operator-owned. Never committed, and never
2
+ # pruned by anything in this repo — three of its origins (HMDB, MiMeDB, MASI)
3
+ # are browser-only downloads that no script can re-fetch. `make
4
+ # check-data-bounds` reports its size and touches nothing.
5
+ data/raw/
6
+ # In this checkout `data` and `graph` are symlinks into the sibling
7
+ # MicrobiomeKG-Data/ folder (raw/, graph/), so the library tree stays
8
+ # clean; the two links are local state like everything they point at.
9
+ /data
10
+ /graph
11
+ *.kgl
12
+ graph/
13
+ # Written by scripts/build.py beside the graph; a pure function of the sources.
14
+ ontology.json
15
+
16
+ docs/_build/
17
+ .venv/
18
+ __pycache__/
19
+ .pytest_cache/
20
+ .ruff_cache/
21
+ .DS_Store
22
+
23
+ # The local working system: plans, scratch, the todo index (dev-docs/) and the
24
+ # cross-project channel (inbox/). Local state, never committed — each folder's
25
+ # own README.md is its layout map, and CLAUDE.md's R4 table names every tier's
26
+ # bound and owner. `make check-dev-docs` enforces the size bound.
27
+ /dev-docs/
28
+ /inbox/
29
+
30
+ # Agent skill trees are local working state for this checkout, not part of the
31
+ # public repository. The local `make gate` still verifies the adapter mirror.
32
+ .claude/skills/
33
+ .agents/skills/
@@ -0,0 +1,19 @@
1
+ # Read the Docs configuration for the `microbiomekg` project, served at
2
+ # https://microbiomekg.readthedocs.io (docs/design/release-readiness.md §5).
3
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html
4
+
5
+ version: 2
6
+
7
+ build:
8
+ os: ubuntu-24.04
9
+ tools:
10
+ python: "3.12"
11
+
12
+ sphinx:
13
+ configuration: docs/conf.py
14
+
15
+ python:
16
+ install:
17
+ - requirements: docs/requirements.txt
18
+ - method: pip
19
+ path: .
@@ -0,0 +1,135 @@
1
+ # Changelog
2
+
3
+ All notable changes to MicrobiomeKG will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+ User-visible changes land under `[Unreleased]` as they happen; a release
8
+ promotes that section into a version block. Internal refactors, test-only
9
+ changes and formatting do not get entries.
10
+
11
+ ## [Unreleased]
12
+
13
+ ## [0.1.0] - 2026-09-09
14
+
15
+ ### Added
16
+ - **Guidance in the data-loading path.** `prepare(data_dir)` creates the input
17
+ layout and prints a dataset table with availability, total size and oldest
18
+ local file age. Missing files and files above `max_age_days` (30 by default;
19
+ CLI `--max-age-days`) get download URLs and expected filenames. `status` and the CLI fetch report share the same guidance;
20
+ `status --create` creates the layout from the shell. Python `status` remains
21
+ a silent evaluator with per-file metadata on `SourceStatus.files`.
22
+ - **Fetch missing inputs.** `fetch(data_dir, missing=True)` and `fetch --missing`
23
+ select fetchers for missing required inputs, deduplicating shared sources
24
+ and excluding optional KEGG unless explicitly selected with `only` / `--only`.
25
+ Selected fetchers retain their existing cache and update behavior.
26
+ - **PyPI publishing.** `[project.urls]` (homepage, repository, docs,
27
+ changelog, issues) so the PyPI page links somewhere, and
28
+ `.github/workflows/publish.yml`: trusted publishing on a `v*` tag, a wheel
29
+ **and** an sdist with the artifact set asserted before and after the upload,
30
+ and a verification job that installs the *published* wheel into a clean venv
31
+ outside any checkout and runs the CLI there.
32
+ - **`CITATION.cff` and `CONTRIBUTING.md`**, and a **Licence** section in the
33
+ README: the code is MIT and covers only this repository; no data and no built
34
+ graph is distributed; every edge carries the `source_licence` it came with,
35
+ and 80,118 of them carry an `-unstated` token against 68,752 that are CC0.
36
+ Per-source terms stay in `docs/sources.md`.
37
+ - **The sdist carries `blueprint.json` and `CHANGELOG.md`.** The composed
38
+ blueprint is what the fragment-drift gate reads at the repo root, so it was
39
+ missing from the one distribution that ships the tests; the gate now runs
40
+ from an unpacked sdist.
41
+ - **G6, coverage of two external curations.** `microbiomekg.coverage` reads
42
+ HMDAD and Peryton, reconciles them the way the preps do, and reports how
43
+ many of their (taxon, disease) pairs the graph asserts, with the evidence
44
+ histogram and direction agreement; neither set is loaded. Both are fetched
45
+ by `microbiomekg fetch --only hmdad` / `--only peryton`, and the numbers
46
+ ride into `docs/benchmarks.md` from a tracked capture.
47
+ - **G7, the breadth proxy against a published meta-analysis.** D14's
48
+ signature-breadth ranking scored against Duvallet et al. 2017's non-specific
49
+ genus set: nine of the top ten at genus rank, claim-gated in
50
+ `docs/benchmarks.md`. The reference set is fetched by
51
+ `microbiomekg fetch --only duvallet2017` and cut to a checked-in table.
52
+ - **Source to graph, with nothing on disk in between.** Every prep is a
53
+ function, `run(raw, store, ...)`, that puts its tables into one in-memory
54
+ store; the build composes a blueprint whose `files:` section declares each
55
+ table as a frame and loads it with kglite 0.16.23's `frames=`. The
56
+ `BuildResult` carries the store, ledgers included.
57
+ - **The package surface.** `import microbiomekg` gives `status(data_dir)`,
58
+ `fetch(data_dir)` and `build(data_dir)` over one data directory; `build`
59
+ returns a `BuildResult` holding the kglite graph and a `BuildReport`. The
60
+ `microbiomekg` console script runs the same three verbs over `--data`, plus
61
+ `serve` over `--graph`. The package is a wheel: `make check-install` builds it and proves
62
+ it in a clean venv.
63
+ - **`SourceStatus`.** Every prep declares `RAW_INPUTS`, and `status` reports
64
+ each source as `absent`, `present`, `stale` or `manual`, with the missing
65
+ files and a `how_to_get` line as data — the three browser-only origins'
66
+ instructions included.
67
+ - **A build with nothing in it succeeds.** An empty data directory exits 0,
68
+ names every source as skipped, and writes no graph; a directory holding only
69
+ the NCBI taxdump builds the Taxon spine and says "taxonomy-only".
70
+ - `docs/benchmarks.md`: the association-layer shape, reconciliation confidence,
71
+ the two drug-screen headline reproductions, BugSigDB loader fidelity and
72
+ cross-source direction agreement, every number executed by the claim gate.
73
+ - The Sphinx docs (`make docs`, built under `-W`) and the human-first README,
74
+ also claim-gated.
75
+
76
+ ### Changed
77
+ - **The benchmark harness's scratch directory defaults to a sibling of the
78
+ checkout** (`../MicrobiomeKG-bench`) instead of one machine's absolute path.
79
+ `MICROBIOMEKG_BENCH_SCRATCH` moves it per machine, `--scratch` per run.
80
+ - **`docs/sources.md` reads in numeric order** — the MONDO section (11) sat
81
+ after 17.
82
+ - **The kglite floor is `>=0.17.1`.** The graph rebuilds table-for-table
83
+ identical on it (56 tables, 864,132 taxa, 112,966 `taxon_condition` rows),
84
+ and the full suite — the acceptance goldens, the documented queries and the
85
+ claim gate against a 0.17.1-built graph — is unchanged. 0.17.0 also closes
86
+ two more `docs/model.md` §8 engine asks: a Cypher query can force the exact
87
+ vector scan with `{exact: true}` and read which lane served it from the
88
+ result's retrieval diagnostics, and the ontology audits *node* properties
89
+ as well as edge ones.
90
+ - **A blueprint fragment names its input with `file` only.** The pre-0.16.23
91
+ `csv` spelling, which the build and `declared_types` still accepted and
92
+ rewrote, is no longer read; no fragment used it.
93
+ - **`mondo.obo` is a declared input.** The three preps that key conditions on
94
+ MONDO list `mondo/mondo.obo` in `RAW_INPUTS`, `status` reports it, `fetch`
95
+ pulls it (`--only mondo`, and with BugSigDB and gutMDisorder), and an absent
96
+ file skips the source with the reason instead of silently writing every
97
+ disease under its source's own id. Withholding any declared input — not only
98
+ the first — now makes its prep refuse by name; that also caught MiMeDB's
99
+ microbes dump and four of the five taxonomy dumps.
100
+ - `--csv` and `--skip-prep` are gone from the build: there is no CSV
101
+ directory to point at or reuse, and `microbiomekg build --data D` reads
102
+ `D/raw/` only. A prep's absent input is a `MissingInput` exception the
103
+ build reports as the skip, not an exit code.
104
+ - kglite ≥ 0.16.23 is required.
105
+ - The preps, blueprint fragments, MCP manifest and skills, and the build,
106
+ fetch and serve modules moved into the package (`microbiomekg/preps/`,
107
+ `microbiomekg/blueprints/`, `microbiomekg/mcp/`, `pipeline.py`,
108
+ `download.py`, `serve.py`); `scripts/*.py` are thin callers. The build runs
109
+ preps as `python -m microbiomekg.preps.<name>`.
110
+ - The build no longer rewrites the tracked `blueprint.json`; `make gate`
111
+ composes it in `--check` mode.
112
+ - The claim gate covers tracked markdown pages (`DOC_UNITS`), not only the
113
+ MCP prose.
114
+
115
+ ### Fixed
116
+ - Data guidance uses the chosen data directory, quotes shell paths, and
117
+ distinguishes missing automatic inputs within a partly manual source.
118
+ Malformed manifest shapes no longer prevent status inspection. The fetch
119
+ CLI now exits unsuccessfully when a fetcher raises, while still displaying
120
+ the remaining input status.
121
+ - **A malformed raw file skips its source instead of ending the build.** The
122
+ workbook preps (Maier 2018, Zimmermann 2019, NJC19) raised `SystemExit`
123
+ when a sheet or header row was not where the paper put it, or when a rule
124
+ derived from the file stopped reproducing the paper's own numbers; the
125
+ build caught none of it, so one renamed header ended a multi-minute build
126
+ with no report and no census. They raise `MalformedInput` now, the build
127
+ reports the source as present-but-malformed beside the absent ones, and
128
+ `<graph>.build.json` carries every skip's reason under `skip_reasons`.
129
+ - Ten preps reported a missing NCBI taxdump through argparse (exit 2), which
130
+ the build reads as fatal; every prep now exits 3, the skip code.
131
+ - A relative `--csv` loaded the ontology from a doubled path; the build
132
+ resolves its paths first.
133
+ - `docs/evaluation.md` §5 compared the comparator's disease *nodes* to ours
134
+ and quoted a stale metabolite count; `docs/usecases-and-pitfalls.md` D17
135
+ quoted pre-MASI goldens.
@@ -0,0 +1,34 @@
1
+ cff-version: 1.2.0
2
+ title: "MicrobiomeKG: a microbiome knowledge graph pipeline with an auditable evidence model"
3
+ message: >-
4
+ If you use this software, please cite it as below — and cite the sources you
5
+ actually loaded, which docs/sources.md lists with their papers and licences.
6
+ type: software
7
+ authors:
8
+ - family-names: "Kollsgård"
9
+ given-names: "Kristian de Figueiredo"
10
+ repository-code: "https://github.com/kkollsga/microbiomekg"
11
+ url: "https://github.com/kkollsga/microbiomekg"
12
+ license: MIT
13
+ version: 0.1.0
14
+ abstract: >-
15
+ A pipeline that builds a microbiome knowledge graph on kglite from curated
16
+ public sources over NCBI taxonomy. Its point is the evidence model rather
17
+ than the size: every association edge carries its provenance set — primary
18
+ source, source record id, source licence, study design, assay, both group
19
+ sizes and the citing paper — nothing is stored as a score, direction is
20
+ recorded per study and never aggregated, and measured negatives ("somebody
21
+ looked and found nothing") are first-class edges rather than absent rows.
22
+ Names that will not resolve go to a ledger with the reason, so "dropped" is
23
+ a number the graph can report. The software is MIT-licensed; no data and no
24
+ built graph is distributed, and each edge carries the licence of the source
25
+ it came from.
26
+ keywords:
27
+ - microbiome
28
+ - knowledge graph
29
+ - evidence
30
+ - provenance
31
+ - cypher
32
+ - kglite
33
+ - bioinformatics
34
+ - NCBI taxonomy
@@ -0,0 +1,84 @@
1
+ # Contributing
2
+
3
+ Thanks for looking. This is a research pipeline with an unusually strict rule
4
+ about prose, so the short version is worth reading before you open a PR.
5
+
6
+ ## The loop
7
+
8
+ 1. **Branch** — `feat/…`, `fix/…`, `refactor/…`. Never work on `main`.
9
+ 2. **Commit per phase.** A change that has steps gets one commit per step, each
10
+ independently runnable and testable, so a bisect lands on something small.
11
+ Format: `type: short description` (`feat`, `fix`, `docs`, `refactor`,
12
+ `test`, `chore`).
13
+ 3. **Open a draft PR** and let CI run: the gate, the full suite on Python
14
+ 3.11–3.14, `sphinx -W`, and a build against an empty data directory.
15
+ 4. **Mark it ready** when every required check is green.
16
+
17
+ ## The gate
18
+
19
+ ```bash
20
+ make venv # provision .venv and install the package editable
21
+ make gate # ruff, adapter mirror, accumulation bounds, blueprint composition,
22
+ # and the two truth gates (~30 s)
23
+ make test # the full suite
24
+ make docs # sphinx -W
25
+ ```
26
+
27
+ Run `make gate` before every push. It is fast, and it catches the things CI
28
+ cannot: **CI has no built graph**, so the acceptance goldens, the documented
29
+ queries and the claim gate self-skip there. A green PR does not mean those
30
+ passed — only a local run against a built graph does. A skipped test is not a
31
+ pass.
32
+
33
+ Building the graph needs raw input the repository does not ship
34
+ (`docs/sources.md` says where each source comes from, and three of them are
35
+ browser-only downloads). `microbiomekg status --data ./data` prints the
36
+ to-do list. Without it you can still change and test everything that is
37
+ fixture-backed, which is most of the suite.
38
+
39
+ ## Two rules that are not style preferences
40
+
41
+ **A claim in prose is executed.** Every number and every existential phrase in
42
+ `microbiomekg/mcp/` — the skills an LLM agent reads — and in the pages listed
43
+ in `tests/skill_claims.py` (`README.md`, `docs/benchmarks.md`,
44
+ `docs/queries-by-task.md`) is covered by a claim in `tests/claims/` or
45
+ `docs/claims/`, and every graph claim is run against the built graph. If your
46
+ change moves a number, re-measure it and update the claim. **Never loosen the
47
+ gate to make a sentence pass.** The gate exists because a shipped skill once
48
+ told agents there was no `CONSUMES` edge in a graph holding 4,784 of them,
49
+ while every test passed.
50
+
51
+ **A fix lands with the test that fails without it**, in the same commit, and a
52
+ new gate is not trusted until it has been seen red — break the thing it guards,
53
+ watch it fail, restore, and say so in the commit message.
54
+
55
+ ## Adding a source
56
+
57
+ A source is four files and edits no shared file:
58
+
59
+ | file | what it carries |
60
+ |---|---|
61
+ | `microbiomekg/preps/prep_<src>.py` | `run(raw, store, …)`: raw files → tables, plus `DEPENDS_ON` and `RAW_INPUTS` |
62
+ | `microbiomekg/blueprints/<src>.json` | the node types and junction edges it writes rows into |
63
+ | `microbiomekg/ontology/<src>.py` | its audit rules, evidence mapping and licence |
64
+ | `tests/test_<src>.py` | its fixture-backed tests, against a real cut of the source |
65
+
66
+ Preps are discovered, not listed, so nothing central needs editing — and the
67
+ test file is what notices a source that forgot one of the four. Fixtures carry
68
+ real NCBI ids, cut from the real source; an invented id resolves to something
69
+ real and wrong the day the dump moves.
70
+
71
+ A source's edges must be able to say where they came from: `primary_source`,
72
+ `source_record_id`, `source_licence`, the study design, both group sizes and
73
+ the citing paper. An edge that cannot does not get written, and a value nobody
74
+ has read is `not_provided` rather than a plausible default — the point is that
75
+ the gap stays countable.
76
+
77
+ `docs/model.md` is the graph model, `docs/usecases-and-pitfalls.md` is the user
78
+ contract, and `CLAUDE.md` is the full set of conventions this repository works
79
+ under.
80
+
81
+ ## Licence
82
+
83
+ Contributions are accepted under the MIT licence in `LICENSE`, which covers the
84
+ code only. No data is redistributed here (see the README's Licence section).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kristian de Figueiredo Kollsgård
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,230 @@
1
+ Metadata-Version: 2.5
2
+ Name: microbiomekg
3
+ Version: 0.1.0
4
+ Summary: A microbiome knowledge graph on kglite, with the evidence model as the point.
5
+ Project-URL: Homepage, https://github.com/kkollsga/microbiomekg
6
+ Project-URL: Repository, https://github.com/kkollsga/microbiomekg
7
+ Project-URL: Documentation, https://microbiomekg.readthedocs.io
8
+ Project-URL: Changelog, https://github.com/kkollsga/microbiomekg/blob/main/CHANGELOG.md
9
+ Project-URL: Issues, https://github.com/kkollsga/microbiomekg/issues
10
+ Author: Kristian dF Kollsgård
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: bugsigdb,cypher,evidence,kglite,knowledge-graph,llm-agents,mcp,microbiome,ncbi-taxonomy
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Operating System :: MacOS
17
+ Classifier: Operating System :: Microsoft :: Windows
18
+ Classifier: Operating System :: POSIX :: Linux
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Programming Language :: Python :: 3.14
24
+ Classifier: Programming Language :: Python :: Implementation :: CPython
25
+ Classifier: Topic :: Database
26
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
27
+ Requires-Python: >=3.11
28
+ Requires-Dist: kglite>=0.17.1
29
+ Requires-Dist: openpyxl>=3.1
30
+ Requires-Dist: pandas>=2.0
31
+ Requires-Dist: requests>=2.31
32
+ Provides-Extra: docs
33
+ Requires-Dist: furo; extra == 'docs'
34
+ Requires-Dist: myst-parser; extra == 'docs'
35
+ Requires-Dist: sphinx-autoapi; extra == 'docs'
36
+ Requires-Dist: sphinx-copybutton; extra == 'docs'
37
+ Requires-Dist: sphinx>=8.1.3; extra == 'docs'
38
+ Provides-Extra: test
39
+ Requires-Dist: pytest-timeout>=2.3; extra == 'test'
40
+ Requires-Dist: pytest>=8.0; extra == 'test'
41
+ Description-Content-Type: text/markdown
42
+
43
+ # MicrobiomeKG
44
+
45
+ A microbiome knowledge graph on [kglite](https://github.com/kkollsga/kglite),
46
+ **with the evidence model as the point**. Every association edge carries the
47
+ study design, the direction, both group sizes and the citing paper; nothing is
48
+ stored as a score; direction is per study and never aggregated, so forty
49
+ reports on one pair stay forty reports, dissent included. And the **measured
50
+ negatives are first-class**: 61,127 edges record that somebody looked and found
51
+ nothing — 42,233 drugs that did not inhibit a gut isolate, 17,479 that no
52
+ strain metabolised, 894 metabolites with no exchange, and 521 curated
53
+ non-effects — each as its own relationship, so no query mistakes "never
54
+ tested" for "tested and clean".
55
+
56
+ Eleven curated sources over NCBI taxonomy: BugSigDB, gutMDisorder, CARD, HMDB,
57
+ Reactome, ChEMBL, MiMeDB, NJC19, the Maier 2018 and Zimmermann 2019 drug
58
+ screens, and MASI. 934,206 nodes and 1,324,684 edges; 105,880
59
+ microbe–disease reports over 56,306 distinct pairs. KEGG has a loader and is
60
+ off by default, because its licence forbids redistributing a graph carrying it.
61
+
62
+ No data and no built graph ships. What ships is the pipeline: one directory
63
+ is the entire input, a source is discovered rather than listed, and a source
64
+ whose raw files are absent is skipped loudly, never silently.
65
+
66
+ ## Install, get the data and build
67
+
68
+ Install MicrobiomeKG from PyPI, then use one data directory throughout:
69
+
70
+ ```bash
71
+ python -m pip install microbiomekg
72
+ microbiomekg status --data ./my-data --create
73
+ microbiomekg fetch --data ./my-data --missing
74
+ microbiomekg build --data ./my-data
75
+ ```
76
+
77
+ `status --create` creates the required raw-input directories and shows a table
78
+ of dataset availability, size and age. Missing files and files older than the
79
+ configurable age threshold get a download URL and expected filename below the
80
+ table. It does not download anything. `fetch --missing` selects the automatic fetchers needed
81
+ for missing default inputs, then prints the same report so remaining manual
82
+ work stays visible. A build can use a partial data directory and names every
83
+ source it skipped. See the [getting-started guide](docs/getting-started.md) for
84
+ the browser-only inputs and Python equivalent.
85
+
86
+ ## Python
87
+
88
+ ```python
89
+ import microbiomekg as mkg
90
+
91
+ data = "./my-data"
92
+ mkg.prepare(data) # create directories and print the input report
93
+ mkg.fetch(data, missing=True) # fetch missing automatic inputs; report again
94
+ result = mkg.build(data) # build from what is present; does not save by default
95
+ g = result.graph
96
+
97
+ g.cypher("""
98
+ MATCH (t:Taxon {id: 851})-[r:ASSOCIATED_WITH]->(d:Disease {id: 'MONDO:0005575'})
99
+ RETURN r.direction, r.evidence_level, r.study_design, r.group_1_size, r.pmid
100
+ ORDER BY r.evidence_level
101
+ """)
102
+ ```
103
+
104
+ That query — *Fusobacterium nucleatum* in colorectal cancer — returns 40 rows
105
+ from 21 studies, one of them `decreased`. It is never one aggregated row, and
106
+ the dissent is never removed. The twenty documented queries in
107
+ [`docs/usecases-and-pitfalls.md`](docs/usecases-and-pitfalls.md) are the user
108
+ contract; each has a golden the test suite asserts.
109
+
110
+ ## Cypher
111
+
112
+ The graph is a kglite `.kgl` file: open it in Python, or over Bolt for driver
113
+ tooling. Three of the documented queries, as the shape of what it answers:
114
+
115
+ ```cypher
116
+ // D17 — where do studies disagree, and which pairs rest on a single cohort?
117
+ MATCH (t:Taxon)-[r:ASSOCIATED_WITH]->(d:Disease)
118
+ WITH t, d, collect(DISTINCT r.direction) AS directions,
119
+ count(DISTINCT r.study_id) AS n_studies, count(r) AS n_edges
120
+ RETURN t.title, d.title, directions, n_studies,
121
+ size(directions) > 1 AS direction_conflict, n_studies = 1 AS single_cohort
122
+ ORDER BY n_edges DESC LIMIT 50
123
+ ```
124
+
125
+ ```cypher
126
+ // D8 — does a drug inhibit gut bacteria, and is it metabolised by them?
127
+ MATCH (d:Drug {pref_name: 'METFORMIN'})-[r]->(t:Taxon)
128
+ RETURN type(r) AS relationship, count(*) AS strains
129
+ ```
130
+
131
+ ```cypher
132
+ // D6 — which taxa consume a metabolite, and which produce it? (cross-feeding)
133
+ MATCH (m:Metabolite {title: 'Butyric acid'})
134
+ OPTIONAL MATCH (p:Taxon)-[:PRODUCES]->(m)
135
+ OPTIONAL MATCH (c:Taxon)-[:CONSUMES]->(m)
136
+ RETURN count(DISTINCT p) AS producers, count(DISTINCT c) AS consumers
137
+ ```
138
+
139
+ The model — node types, the evidence-field contract, the reconciliation ledger
140
+ — is [`docs/model.md`](docs/model.md); the per-source licences and provenance
141
+ are [`docs/sources.md`](docs/sources.md); what the graph reproduces and
142
+ against what is [`docs/benchmarks.md`](docs/benchmarks.md).
143
+
144
+ ## MCP
145
+
146
+ ```bash
147
+ microbiomekg serve --selftest # green/red configuration check
148
+ microbiomekg serve # kglite's MCP server on stdio, read-only
149
+ ```
150
+
151
+ The manifest and the skills ship inside the package. One skill per use-case
152
+ family, injected into the tool descriptions an agent reads, so the evidence
153
+ rules travel with the tool; the prose in them is held to the graph by the
154
+ same claim gate that holds this README.
155
+
156
+ ## Adding a source
157
+
158
+ A source is four files, discovered rather than listed, and adding one never
159
+ edits a shared file:
160
+
161
+ | file | what it carries |
162
+ |---|---|
163
+ | `microbiomekg/preps/prep_<src>.py` | `run(raw, store, …)`: raw files → tables in the build's store, plus `DEPENDS_ON` and `RAW_INPUTS` |
164
+ | `microbiomekg/blueprints/<src>.json` | the node types and junction edges it writes rows into |
165
+ | `microbiomekg/ontology/<src>.py` | its audit rules, evidence mapping and licence |
166
+ | `tests/test_<src>.py` | its fixture-backed tests, against a real cut of the source |
167
+
168
+ Fragments merge and never override: declaring the same key with a different
169
+ value is a build error naming both fragments.
170
+
171
+ ## Layout
172
+
173
+ - `microbiomekg/` — the package: `api.py` (the three verbs), `cli.py`, the
174
+ preps, the blueprint fragments, the ontology modules, `pipeline.py` (the
175
+ build), `download.py` (fetch), `sources.py` (status), `serve.py`, and `mcp/`.
176
+ - `scripts/` — thin callers into the package, so `scripts/build.py` and
177
+ friends work from a checkout; `scripts/check_install.py` is the wheel proof.
178
+ - `docs/` — the guides, the design notes, and the Sphinx build (`make docs`).
179
+ - `tests/` — offline, fixture-backed; the graph-backed suites read the built
180
+ `graph/microbiomekg.kgl`. `tests/claims/` and `docs/claims/` hold the claims
181
+ the truth gate executes.
182
+ - `bench/` — the longitudinal cost record.
183
+ - `data/` and `graph/` are not in the tree: a checkout symlinks them to the
184
+ sibling `../MicrobiomeKG-Data/` (`raw/`, `graph/`), and
185
+ `--data ../MicrobiomeKG-Data` names the same directory without the links.
186
+
187
+ ## Building and testing
188
+
189
+ ```bash
190
+ make venv # provision .venv and install the package editable
191
+ make build # the graph (minutes; needs data/raw — see docs/sources.md)
192
+ make gate # the pre-commit gate: ruff, bounds, blueprint composition, the truth gates
193
+ make test # the full suite
194
+ make docs # sphinx -W
195
+ ```
196
+
197
+ Two flags are off by default. `--with-kegg` is a licence gate. `--with-vectors`
198
+ is a cost gate: the character-n-gram vector index buys query-time tolerance for
199
+ a *misspelt* organism name and nothing else, while costing +82.6 s of build,
200
+ `.kgl` 46.7 MB → 212.7 MB, load 1.03 s → 2.41 s and serving RSS 1.2 GB → 3.7 GB
201
+ (the `2026-09-03` capture, `bench/results/`). A default build says in its report
202
+ that the lane was skipped and which flag turns it on.
203
+
204
+ The conventions an agent works under are `CLAUDE.md`, and `CONTRIBUTING.md` is
205
+ the short version for a contributor.
206
+
207
+ ## Licence
208
+
209
+ **The code is MIT** (`LICENSE`). That covers this repository — the preps, the
210
+ blueprint fragments, the ontology modules, the build and the MCP surface — and
211
+ nothing else.
212
+
213
+ **The data is not ours to relicense, and none of it ships here.** No raw input
214
+ and no built graph is distributed: a build reads sources the operator fetched
215
+ under each source's own terms, and every edge carries the `source_licence` it
216
+ came with. In a default build that is `CC-BY-4.0`, `CC0-1.0`,
217
+ `CC-BY-SA-3.0`, `CARD-noncommercial`, `HMDB-noncommercial`, `unknown`, and an
218
+ `-unstated` token on the sources whose papers state no redistribution terms —
219
+ so a query can select exactly the cut it is allowed to pass on. It is a real
220
+ constraint: 80,118 edges carry an `-unstated` token, against 68,752 that are
221
+ CC0.
222
+
223
+ Per-source terms are in `docs/sources.md` ("Redistribution: what blocks
224
+ shipping a built graph"); what that leaves a redistributable cut looking like
225
+ is measured in `docs/evaluation.md`. KEGG is behind `--with-kegg` for exactly
226
+ this reason.
227
+
228
+ If you use this pipeline in published work, `CITATION.cff` has the citation —
229
+ and cite the sources you actually loaded, which `docs/sources.md` lists with
230
+ their papers.