phylohist 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.
- phylohist-0.1.0/LICENSE +21 -0
- phylohist-0.1.0/PKG-INFO +319 -0
- phylohist-0.1.0/README.md +297 -0
- phylohist-0.1.0/phylohist/__init__.py +31 -0
- phylohist-0.1.0/phylohist/acts.py +35 -0
- phylohist-0.1.0/phylohist/blocks.py +342 -0
- phylohist-0.1.0/phylohist/claims.py +1340 -0
- phylohist-0.1.0/phylohist/cli.py +295 -0
- phylohist-0.1.0/phylohist/closure.py +413 -0
- phylohist-0.1.0/phylohist/derivatives.py +103 -0
- phylohist-0.1.0/phylohist/evaluation.py +279 -0
- phylohist-0.1.0/phylohist/loader/__init__.py +15 -0
- phylohist-0.1.0/phylohist/loader/checks.py +101 -0
- phylohist-0.1.0/phylohist/loader/corpus.py +78 -0
- phylohist-0.1.0/phylohist/loader/io.py +282 -0
- phylohist-0.1.0/phylohist/loader/load.py +582 -0
- phylohist-0.1.0/phylohist/loader/material.py +706 -0
- phylohist-0.1.0/phylohist/loader/nomenclature.py +293 -0
- phylohist-0.1.0/phylohist/loader/research.py +317 -0
- phylohist-0.1.0/phylohist/loader/taxa.py +1111 -0
- phylohist-0.1.0/phylohist/mcp.py +219 -0
- phylohist-0.1.0/phylohist/names.py +45 -0
- phylohist-0.1.0/phylohist/plan.py +269 -0
- phylohist-0.1.0/phylohist/ranks.py +112 -0
- phylohist-0.1.0/phylohist/regenerate.py +68 -0
- phylohist-0.1.0/phylohist/render.py +534 -0
- phylohist-0.1.0/phylohist/resolve.py +319 -0
- phylohist-0.1.0/phylohist/store.py +1733 -0
- phylohist-0.1.0/phylohist/table/1740_tilas.jsonl +3 -0
- phylohist-0.1.0/phylohist/table/1741_linnaeus.jsonl +4 -0
- phylohist-0.1.0/phylohist/table/1758_linnaeus.jsonl +751 -0
- phylohist-0.1.0/phylohist/table/1761_bohadsch.jsonl +33 -0
- phylohist-0.1.0/phylohist/table/1761_linnaeus.jsonl +118 -0
- phylohist-0.1.0/phylohist/table/1762_gaertner.jsonl +34 -0
- phylohist-0.1.0/phylohist/table/1766_linnaeus.jsonl +9 -0
- phylohist-0.1.0/phylohist/table/1766b_pallas.jsonl +334 -0
- phylohist-0.1.0/phylohist/table/1767_gunnerus.jsonl +17 -0
- phylohist-0.1.0/phylohist/table/1767_linnaeus.jsonl +333 -0
- phylohist-0.1.0/phylohist/table/1772_gyllenhaal.jsonl +12 -0
- phylohist-0.1.0/phylohist/table/1773_m/303/274ller.o.f.jsonl +44 -0
- phylohist-0.1.0/phylohist/table/1774_van phelsum.jsonl +4 -0
- phylohist-0.1.0/phylohist/table/1774a_m/303/274ller.o.f.jsonl +24 -0
- phylohist-0.1.0/phylohist/table/1774b_m/303/274ller.o.f.jsonl +36 -0
- phylohist-0.1.0/phylohist/table/1776_m/303/274ller.o.f.jsonl +348 -0
- phylohist-0.1.0/phylohist/table/1776_walch.jsonl +4 -0
- phylohist-0.1.0/phylohist/table/1778_klein.jsonl +2 -0
- phylohist-0.1.0/phylohist/table/1778_leske.jsonl +466 -0
- phylohist-0.1.0/phylohist/table/1789a_brugui/303/250re.jsonl +252 -0
- phylohist-0.1.0/phylohist/table/1791_brugui/303/250re.jsonl +17 -0
- phylohist-0.1.0/phylohist/table/1798_cuvier.jsonl +198 -0
- phylohist-0.1.0/phylohist/table/1801_lamarck.jsonl +275 -0
- phylohist-0.1.0/phylohist/table/1802_hisinger.jsonl +8 -0
- phylohist-0.1.0/phylohist/table/1815_lamarck.jsonl +9 -0
- phylohist-0.1.0/phylohist/table/1816a_lamarck.jsonl +312 -0
- phylohist-0.1.0/phylohist/table/1816b_lamarck.jsonl +840 -0
- phylohist-0.1.0/phylohist/table/1817a_cuvier.jsonl +7 -0
- phylohist-0.1.0/phylohist/table/1817b_cuvier.jsonl +35 -0
- phylohist-0.1.0/phylohist/table/1817c_cuvier.jsonl +0 -0
- phylohist-0.1.0/phylohist/table/1817d_cuvier.jsonl +73 -0
- phylohist-0.1.0/phylohist/table/1820_say.jsonl +5 -0
- phylohist-0.1.0/phylohist/table/1821_macleay.jsonl +83 -0
- phylohist-0.1.0/phylohist/table/1821_miller.j.s.jsonl +143 -0
- phylohist-0.1.0/phylohist/table/1821_wahlenberg.jsonl +35 -0
- phylohist-0.1.0/phylohist/table/1825a_say.jsonl +41 -0
- phylohist-0.1.0/phylohist/table/1825b_sowerby.g.b.jsonl +17 -0
- phylohist-0.1.0/phylohist/table/1825i_gray.j.e.jsonl +91 -0
- phylohist-0.1.0/phylohist/table/1826_meyer.jsonl +5 -0
- phylohist-0.1.0/phylohist/table/1826_schlotheim.jsonl +50 -0
- phylohist-0.1.0/phylohist/table/1828_hisinger.jsonl +55 -0
- phylohist-0.1.0/phylohist/table/1830_pander.jsonl +59 -0
- phylohist-0.1.0/phylohist/table/1837_hisinger.jsonl +59 -0
- phylohist-0.1.0/phylohist/table/1839_murchison.jsonl +59 -0
- phylohist-0.1.0/phylohist/table/1840_eichwald.jsonl +125 -0
- phylohist-0.1.0/phylohist/table/1840a_buch.jsonl +48 -0
- phylohist-0.1.0/phylohist/table/1840b_buch.jsonl +29 -0
- phylohist-0.1.0/phylohist/table/1842_conrad.t.a.jsonl +19 -0
- phylohist-0.1.0/phylohist/table/1842_vanuxem.jsonl +28 -0
- phylohist-0.1.0/phylohist/table/1842_volborth.jsonl +18 -0
- phylohist-0.1.0/phylohist/table/1843_hall.jsonl +37 -0
- phylohist-0.1.0/phylohist/table/1844_buch.jsonl +57 -0
- phylohist-0.1.0/phylohist/table/1845_buch.jsonl +72 -0
- phylohist-0.1.0/phylohist/table/1846a_buch.jsonl +4 -0
- phylohist-0.1.0/phylohist/table/1847_hall.jsonl +92 -0
- phylohist-0.1.0/phylohist/table/1848_leuckart.jsonl +20 -0
- phylohist-0.1.0/phylohist/table/1848b_forbes.jsonl +129 -0
- phylohist-0.1.0/phylohist/table/1852_hall.jsonl +210 -0
- phylohist-0.1.0/phylohist/table/1854_m/303/274ller.j.p.jsonl +83 -0
- phylohist-0.1.0/phylohist/table/1854a_billings.jsonl +10 -0
- phylohist-0.1.0/phylohist/table/1854b_billings.jsonl +18 -0
- phylohist-0.1.0/phylohist/table/1854c_billings.jsonl +32 -0
- phylohist-0.1.0/phylohist/table/1857_billings.jsonl +181 -0
- phylohist-0.1.0/phylohist/table/1858_salter_billings.jsonl +13 -0
- phylohist-0.1.0/phylohist/table/1858a_billings.jsonl +119 -0
- phylohist-0.1.0/phylohist/table/1858b_billings.jsonl +41 -0
- phylohist-0.1.0/phylohist/table/1887_billings.w.r.jsonl +16 -0
- phylohist-0.1.0/phylohist/table/1896_pompeckj.jsonl +26 -0
- phylohist-0.1.0/phylohist/table/1897_whiteaves.jsonl +20 -0
- phylohist-0.1.0/phylohist/table/1898_whiteaves.jsonl +8 -0
- phylohist-0.1.0/phylohist/table/1900_bather.jsonl +134 -0
- phylohist-0.1.0/phylohist/table/1914c_bather.jsonl +18 -0
- phylohist-0.1.0/phylohist/table/1935_bassler.jsonl +395 -0
- phylohist-0.1.0/phylohist/table/1936_bassler.jsonl +218 -0
- phylohist-0.1.0/phylohist/table/1941_whitehouse.jsonl +60 -0
- phylohist-0.1.0/phylohist/table/1960_gill_caster.jsonl +112 -0
- phylohist-0.1.0/phylohist/table/1961_dehm.jsonl +40 -0
- phylohist-0.1.0/phylohist/table/1961_rievers.jsonl +7 -0
- phylohist-0.1.0/phylohist/table/1962_fay.jsonl +15 -0
- phylohist-0.1.0/phylohist/table/1963_brown.i.a.jsonl +18 -0
- phylohist-0.1.0/phylohist/table/1963_durham_caster.jsonl +17 -0
- phylohist-0.1.0/phylohist/table/1965_fell.jsonl +113 -0
- phylohist-0.1.0/phylohist/table/1966_durham.jsonl +14 -0
- phylohist-0.1.0/phylohist/table/1966_durham_caster.jsonl +19 -0
- phylohist-0.1.0/phylohist/table/1966_kesling.jsonl +53 -0
- phylohist-0.1.0/phylohist/table/1966_regn/303/251ll.jsonl +166 -0
- phylohist-0.1.0/phylohist/table/1967_paul.c.r.c.jsonl +56 -0
- phylohist-0.1.0/phylohist/table/1967a_durham.jsonl +16 -0
- phylohist-0.1.0/phylohist/table/1967a_fay.jsonl +19 -0
- phylohist-0.1.0/phylohist/table/1967a_ubaghs.jsonl +52 -0
- phylohist-0.1.0/phylohist/table/1967b_durham.jsonl +15 -0
- phylohist-0.1.0/phylohist/table/1967b_fay.jsonl +18 -0
- phylohist-0.1.0/phylohist/table/1967c_durham.jsonl +41 -0
- phylohist-0.1.0/phylohist/table/1967e_ubaghs.jsonl +20 -0
- phylohist-0.1.0/phylohist/table/1968_webby.jsonl +22 -0
- phylohist-0.1.0/phylohist/table/1968a_paul.c.r.c.jsonl +10 -0
- phylohist-0.1.0/phylohist/table/1968b_paul.c.r.c.jsonl +194 -0
- phylohist-0.1.0/phylohist/table/1969_robison_sprinkle.jsonl +15 -0
- phylohist-0.1.0/phylohist/table/1970_mintz.jsonl +16 -0
- phylohist-0.1.0/phylohist/table/1971_paul.c.r.c.jsonl +5 -0
- phylohist-0.1.0/phylohist/table/1972_paul.c.r.c.jsonl +3 -0
- phylohist-0.1.0/phylohist/table/1973_sprinkle.jsonl +1044 -0
- phylohist-0.1.0/phylohist/table/1975_bell.b.m.jsonl +45 -0
- phylohist-0.1.0/phylohist/table/1975_broadhead_strimple.jsonl +13 -0
- phylohist-0.1.0/phylohist/table/1975_kolata.jsonl +385 -0
- phylohist-0.1.0/phylohist/table/1976_bell.b.m.jsonl +272 -0
- phylohist-0.1.0/phylohist/table/1976_bell.b.m_petersen.m.s.jsonl +15 -0
- phylohist-0.1.0/phylohist/table/1978_bell.b.m_sprinkle.jsonl +17 -0
- phylohist-0.1.0/phylohist/table/1978_durham.jsonl +9 -0
- phylohist-0.1.0/phylohist/table/1979_guensburg.jsonl +19 -0
- phylohist-0.1.0/phylohist/table/1980_bell.b.m.jsonl +107 -0
- phylohist-0.1.0/phylohist/table/1980_sprinkle.jsonl +73 -0
- phylohist-0.1.0/phylohist/table/1981_bockelie.jsonl +70 -0
- phylohist-0.1.0/phylohist/table/1981_derstler.jsonl +23 -0
- phylohist-0.1.0/phylohist/table/1982_bell.b.m.jsonl +39 -0
- phylohist-0.1.0/phylohist/table/1982_broadhead.jsonl +61 -0
- phylohist-0.1.0/phylohist/table/1982_kolata.jsonl +14 -0
- phylohist-0.1.0/phylohist/table/1982_smith.a.b.jsonl +13 -0
- phylohist-0.1.0/phylohist/table/1982_sprinkle_parsley.jsonl +17 -0
- phylohist-0.1.0/phylohist/table/1982a_parsley.jsonl +74 -0
- phylohist-0.1.0/phylohist/table/1982b_parsley.jsonl +28 -0
- phylohist-0.1.0/phylohist/table/1982c_parsley.jsonl +25 -0
- phylohist-0.1.0/phylohist/table/1982g_sprinkle.jsonl +75 -0
- phylohist-0.1.0/phylohist/table/1982h_sprinkle.jsonl +18 -0
- phylohist-0.1.0/phylohist/table/1982i_sprinkle.jsonl +20 -0
- phylohist-0.1.0/phylohist/table/1983_bockelie_paul.c.r.c.jsonl +32 -0
- phylohist-0.1.0/phylohist/table/1983_brett_frest_sprinkle_clement.c.r.jsonl +23 -0
- phylohist-0.1.0/phylohist/table/1983_holloway_jell.jsonl +62 -0
- phylohist-0.1.0/phylohist/table/1983_jell.jsonl +54 -0
- phylohist-0.1.0/phylohist/table/1985_fatka_kordule.jsonl +12 -0
- phylohist-0.1.0/phylohist/table/1985_jell_burrett_banks.jsonl +84 -0
- phylohist-0.1.0/phylohist/table/1985_smith.a.b.jsonl +175 -0
- phylohist-0.1.0/phylohist/table/1985_sprinkle.jsonl +16 -0
- phylohist-0.1.0/phylohist/table/1987_gehling.jsonl +16 -0
- phylohist-0.1.0/phylohist/table/1987_lewis.r.d_sprinkle_bailey.j.b_moffit.j_parsley.jsonl +16 -0
- phylohist-0.1.0/phylohist/table/1987_smith.a.b_arbizu.jsonl +63 -0
- phylohist-0.1.0/phylohist/table/1987_ubaghs.jsonl +28 -0
- phylohist-0.1.0/phylohist/table/1988_guensburg.jsonl +46 -0
- phylohist-0.1.0/phylohist/table/1988_ubaghs_robison.jsonl +42 -0
- phylohist-0.1.0/phylohist/table/1990_fatka_kordule.jsonl +12 -0
- phylohist-0.1.0/phylohist/table/1990_smith.a.b_jell.jsonl +158 -0
- phylohist-0.1.0/phylohist/table/1990_ubaghs_vizca/303/257no.jsonl +12 -0
- phylohist-0.1.0/phylohist/table/1991_fatka_kordule.jsonl +14 -0
- phylohist-0.1.0/phylohist/table/1992_sumrall.jsonl +14 -0
- phylohist-0.1.0/phylohist/table/1993_dzik_or/305/202owski.jsonl +14 -0
- phylohist-0.1.0/phylohist/table/1993_sumrall.jsonl +41 -0
- phylohist-0.1.0/phylohist/table/1993_young.t.p_donovan.s.k.jsonl +19 -0
- phylohist-0.1.0/phylohist/table/1994_guensburg_sprinkle.jsonl +351 -0
- phylohist-0.1.0/phylohist/table/1994_sprinkle_wahlman.jsonl +55 -0
- phylohist-0.1.0/phylohist/table/1995_dzik_or/305/202owski.jsonl +10 -0
- phylohist-0.1.0/phylohist/table/1996_sumrall.jsonl +68 -0
- phylohist-0.1.0/phylohist/table/1996_sumrall_bowsher.jsonl +21 -0
- phylohist-0.1.0/phylohist/table/1997_paul.c.r.c.jsonl +175 -0
- phylohist-0.1.0/phylohist/table/1997_sumrall_sprinkle_guensburg.jsonl +99 -0
- phylohist-0.1.0/phylohist/table/1998_dean.j_smith.a.b.jsonl +33 -0
- phylohist-0.1.0/phylohist/table/1999_dom/303/255nguez alonso.jsonl" +80 -0
- phylohist-0.1.0/phylohist/table/1999_ubaghs.jsonl +52 -0
- phylohist-0.1.0/phylohist/table/1999_zhao.y.l_yuan.j.l_zhu.m.y_yang.r.d_guo.q.j_qian.y_huang.y.z_pan.y.jsonl +81 -0
- phylohist-0.1.0/phylohist/table/2000_grigo.jsonl +45 -0
- phylohist-0.1.0/phylohist/table/2000_sumrall_garbisch_pope.j.p.jsonl +63 -0
- phylohist-0.1.0/phylohist/table/2001_rozhnov_fedorov.jsonl +17 -0
- phylohist-0.1.0/phylohist/table/2001_sumrall.jsonl +22 -0
- phylohist-0.1.0/phylohist/table/2001_sumrall_sprinkle_guensburg.jsonl +12 -0
- phylohist-0.1.0/phylohist/table/2002_gil cid_dom/303/255nguez alonso.jsonl" +8 -0
- phylohist-0.1.0/phylohist/table/2003_guensburg_sprinkle.jsonl +122 -0
- phylohist-0.1.0/phylohist/table/2003_sumrall_parsley.jsonl +10 -0
- phylohist-0.1.0/phylohist/table/2004_parsley_prokop.jsonl +30 -0
- phylohist-0.1.0/phylohist/table/2005_frest.jsonl +21 -0
- phylohist-0.1.0/phylohist/table/2006_parsley_zhao.y.l.jsonl +58 -0
- phylohist-0.1.0/phylohist/table/2006_sprinkle_collins.d.jsonl +34 -0
- phylohist-0.1.0/phylohist/table/2006_sumrall_brett_cornell.jsonl +18 -0
- phylohist-0.1.0/phylohist/table/2006_sumrall_gahn.jsonl +75 -0
- phylohist-0.1.0/phylohist/table/2006_sumrall_sprinkle_bonem.jsonl +40 -0
- phylohist-0.1.0/phylohist/table/2007_hu.s.x_luo.h.l_hou.s.g_erdtmann.jsonl +4 -0
- phylohist-0.1.0/phylohist/table/2007_zhao.y.l_parsley_peng.j.jsonl +15 -0
- phylohist-0.1.0/phylohist/table/2007a_nardin.jsonl +17 -0
- phylohist-0.1.0/phylohist/table/2007b_nardin.jsonl +8 -0
- phylohist-0.1.0/phylohist/table/2008_luo.h.l_li.y_hu.s.x_fu.x.p_hou.s.g_liu.x.r_chen.l.z_li.j.f_pang.j.y_liu.q.jsonl +10 -0
- phylohist-0.1.0/phylohist/table/2008_zhao.y.l_parsley_peng.j.jsonl +19 -0
- phylohist-0.1.0/phylohist/table/2009_guensburg_sprinkle.jsonl +47 -0
- phylohist-0.1.0/phylohist/table/2009_sumrall.jsonl +12 -0
- phylohist-0.1.0/phylohist/table/2009_sumrall_brett_mckinney.jsonl +14 -0
- phylohist-0.1.0/phylohist/table/2009_zamora_gozalo_li/303/261/303/241n.jsonl +20 -0
- phylohist-0.1.0/phylohist/table/2010_liu.q_hu.s.x_zhang.z_cuevas-castell_gong.y.m_tao.j.l.jsonl +30 -0
- phylohist-0.1.0/phylohist/table/2010_m/303/274ller.p_hahn.jsonl +121 -0
- phylohist-0.1.0/phylohist/table/2010_parsley_zhao.y.l.jsonl +17 -0
- phylohist-0.1.0/phylohist/table/2010_sumrall.jsonl +28 -0
- phylohist-0.1.0/phylohist/table/2010_zamora_smith.a.b.jsonl +16 -0
- phylohist-0.1.0/phylohist/table/2010_zhao.y.l_sumrall_parsley_peng.j.jsonl +14 -0
- phylohist-0.1.0/phylohist/table/2011_sprinkle_parsley_zhao.y.l_peng.j.jsonl +20 -0
- phylohist-0.1.0/phylohist/table/2011_sumrall_zamora.jsonl +115 -0
- phylohist-0.1.0/phylohist/table/2012_doweld.jsonl +66 -0
- phylohist-0.1.0/phylohist/table/2012_zamora_smith.a.b.jsonl +48 -0
- phylohist-0.1.0/phylohist/table/2013_m/303/274ller.p_hahn_bohat/303/275.jsonl +32 -0
- phylohist-0.1.0/phylohist/table/2013_nardin_bohat/303/275.jsonl +72 -0
- phylohist-0.1.0/phylohist/table/2013_smith.a.b_zamora.jsonl +31 -0
- phylohist-0.1.0/phylohist/table/2013_sumrall_heredia_rodr/303/255guez.c.m_mestre.jsonl +62 -0
- phylohist-0.1.0/phylohist/table/2013_zamora.jsonl +36 -0
- phylohist-0.1.0/phylohist/table/2013_zamora_sumrall_vizca/303/257no.jsonl +16 -0
- phylohist-0.1.0/phylohist/table/2014_chen.g.y_han.n.r.jsonl +10 -0
- phylohist-0.1.0/phylohist/table/2014_jell.jsonl +22 -0
- phylohist-0.1.0/phylohist/table/2014_makhlouf_lefebvre_nardin_nedjari_r/303/251gnault_ferhi.jsonl +19 -0
- phylohist-0.1.0/phylohist/table/2014_zhu.x.j_zamora_lefebvre.jsonl +13 -0
- phylohist-0.1.0/phylohist/table/2015_rahman_stewart_zamora.jsonl +13 -0
- phylohist-0.1.0/phylohist/table/2015_sprinkle_sumrall.jsonl +25 -0
- phylohist-0.1.0/phylohist/table/2015_sumrall_zamora.jsonl +13 -0
- phylohist-0.1.0/phylohist/table/2015_yang.z.c_lin.j.p_zhang.y.p_wu.y.s_meng.x.y.jsonl +18 -0
- phylohist-0.1.0/phylohist/table/2015_zamora_sumrall_sprinkle.jsonl +15 -0
- phylohist-0.1.0/phylohist/table/2015_zhao.y.l_peng.j_wu.m.y_luo.x.c_wen.r.q_liu.y.j.jsonl +16 -0
- phylohist-0.1.0/phylohist/table/2017_allaire_lefebvre_nardin_martin.e.l.o_vaucher_escarguel.jsonl +41 -0
- phylohist-0.1.0/phylohist/table/2017_briggs.d.e.g_siveter.de.j_siveter.da.j_sutton.m.d_rahman.jsonl +16 -0
- phylohist-0.1.0/phylohist/table/2017_nardin_lefebvre_fatka_nohejlov/303/241_ka/305/241i/304/215a_/305/241in/303/241gl_szabad.jsonl +70 -0
- phylohist-0.1.0/phylohist/table/2017_zamora_sumrall_zhu.x.j_lefebvre.jsonl +64 -0
- phylohist-0.1.0/phylohist/table/2018_lefebvre_lerosey-aubril.jsonl +17 -0
- phylohist-0.1.0/phylohist/table/2019_nohejlov/303/241_nardin_fatka_ka/305/241i/304/215a_szabad.jsonl +30 -0
- phylohist-0.1.0/phylohist/table/2019_wen.r.q_babcock_peng.j_robison.jsonl +13 -0
- phylohist-0.1.0/phylohist/table/2020_ewin_martin.m_isotalo_zamora.jsonl +93 -0
- phylohist-0.1.0/phylohist/table/2020_guensburg_sprinkle_mooi_lefebvre_david_roux_derstler.jsonl +161 -0
- phylohist-0.1.0/phylohist/table/2020_zamora_sprinkle_sumrall.jsonl +26 -0
- phylohist-0.1.0/phylohist/table/2021_jell_sprinkle.jsonl +94 -0
- phylohist-0.1.0/phylohist/table/2021_parsley.jsonl +32 -0
- phylohist-0.1.0/phylohist/table/2022_deshmukh.jsonl +10 -0
- phylohist-0.1.0/phylohist/table/2022_zamora_rahman_sumrall_gibson_thompson.jsonl +86 -0
- phylohist-0.1.0/phylohist/table/2022_zhao.j_guo.j_selden_cong.p.y_li.y.j.jsonl +17 -0
- phylohist-0.1.0/phylohist/table/2022_zhao.j_rahman_zamora_chen.a_cong.p.y.jsonl +26 -0
- phylohist-0.1.0/phylohist/table/2024_wang.d.z_nohejlov/303/241_sun.z.x_zeng.h_lefebvre_yang.x.l_zhao.f.c.jsonl +14 -0
- phylohist-0.1.0/phylohist/table/2024_zamora_guensburg_sprinkle.jsonl +23 -0
- phylohist-0.1.0/phylohist/table/manifest.json +30046 -0
- phylohist-0.1.0/phylohist/table/names.json +46279 -0
- phylohist-0.1.0/phylohist/table/ranks.yaml +112 -0
- phylohist-0.1.0/phylohist/table/repositories.json +496 -0
- phylohist-0.1.0/phylohist/tools.py +529 -0
- phylohist-0.1.0/phylohist/words.py +935 -0
- phylohist-0.1.0/pyproject.toml +77 -0
phylohist-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Henry H. Andrews
|
|
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.
|
phylohist-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: phylohist
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Published taxonomic opinions on Palaeozoic echinoderms, recorded as printed, with tools that answer from them
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: taxonomy,phylogenetics,palaeontology,echinoderms,nomenclature,mcp,human-in-the-loop,local-first
|
|
8
|
+
Author: Henry H. Andrews
|
|
9
|
+
Author-email: henry@henryandrews.net
|
|
10
|
+
Requires-Python: >=3.12,<4
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
15
|
+
Requires-Dist: coloredlog (>=0.2.5,<0.3)
|
|
16
|
+
Requires-Dist: json-schema-engine (>=0.0.6,<0.0.7)
|
|
17
|
+
Requires-Dist: mcp (>=2.2.0,<3)
|
|
18
|
+
Requires-Dist: pyyaml (>=6.0.3,<7)
|
|
19
|
+
Project-URL: Repository, https://github.com/handrews/phylohist
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# Phylohist: Exploring changes in systematics over time
|
|
23
|
+
|
|
24
|
+
Science is always in motion. Most online taxonomy or phylogeny
|
|
25
|
+
databases attempt to show a consensus or accepted view, with
|
|
26
|
+
each site having its own editorial policy for what gets included.
|
|
27
|
+
Some include historical information, but do not make it a central
|
|
28
|
+
or easily-accessible part of the sysetm.
|
|
29
|
+
|
|
30
|
+
The `phylohist` project instead provides access to trees as published,
|
|
31
|
+
over time, while leaving the judgement of what to accept or reject to
|
|
32
|
+
the researcher. An LLM-driven interface supports complex queries over
|
|
33
|
+
a curated corpus stored as YAML data. This uses a model where one is
|
|
34
|
+
needed, and prioritizes reliability, reproducibility, speed,
|
|
35
|
+
and lower costs where one is not.
|
|
36
|
+
|
|
37
|
+
The current corpus holds over 200 papers entered in whole or in part, from
|
|
38
|
+
the mid-1700s to the present, mostly focusing on Paleozoic echinoderms.
|
|
39
|
+
A coverage system tracks how much of the information from a paper has
|
|
40
|
+
been entered and reviewed.
|
|
41
|
+
|
|
42
|
+
## Status and future plans
|
|
43
|
+
|
|
44
|
+
This repository began as a place to store my notes, and gradually evolved
|
|
45
|
+
into a software package, featuring more and more modern software engineering
|
|
46
|
+
best practices as I have found time to add them. However, it remains
|
|
47
|
+
a solo, unfunded project that I work on whenever I can.
|
|
48
|
+
|
|
49
|
+
The package is published on PyPI as `phylohist` from version 0.1.0.
|
|
50
|
+
Next steps include writing human-user-friendly documentation,
|
|
51
|
+
continuing to improve the software development methodology, curating
|
|
52
|
+
additional data and adding more features.
|
|
53
|
+
|
|
54
|
+
A data model for capturing specimen information has recenlty been
|
|
55
|
+
designed but data entry for this area is in its infancy. Additional
|
|
56
|
+
areas of fuure work are proper support for cladograms (currently
|
|
57
|
+
allowed in the data but treated more-or-less like systematic trees)
|
|
58
|
+
and data visualization.
|
|
59
|
+
|
|
60
|
+
## Corpus Scope and Editorial Curation Policy
|
|
61
|
+
|
|
62
|
+
Because `phylohist` relies on manual validation and a human-in-the-loop
|
|
63
|
+
workflow, data ingestion proceeds slowly to prioritize high fidelity
|
|
64
|
+
over unchecked volume.
|
|
65
|
+
|
|
66
|
+
No data is entered purely by AI. The data model has grown from my experience
|
|
67
|
+
of manually reading papers and figuring out how to work with the data as
|
|
68
|
+
it was published. Current LLMs are too eager to make things "work" rather
|
|
69
|
+
than step back and consider the user experience.
|
|
70
|
+
|
|
71
|
+
### Intentional Scoping and Partial Entry
|
|
72
|
+
|
|
73
|
+
Data entry is guided by the target research scope, currently focusing primarily
|
|
74
|
+
on Paleozoic echinoderms and their relatives in the Ambulacrarian stem group.
|
|
75
|
+
|
|
76
|
+
* **Partial Ingestion:** For vast foundational texts such as Linnaeus’s
|
|
77
|
+
*Systema Naturae*, only the specific branches of interest to the active
|
|
78
|
+
dataset are entered.
|
|
79
|
+
* **Closed-World Boundaries:** The data model is being enhanced with ways
|
|
80
|
+
to indicate when data is complete by some metric. However, updating
|
|
81
|
+
the data with these fields is itself a large, ongoing project.
|
|
82
|
+
|
|
83
|
+
### Archival Fidelity vs. Modern Interpretation
|
|
84
|
+
|
|
85
|
+
Tracking archaic, text-heavy literature (particularly pre-19th-century sources
|
|
86
|
+
written in informal prose) presents a unique archival challenge.
|
|
87
|
+
|
|
88
|
+
* **Philosophy:** The core directive of this corpus is to capture the published
|
|
89
|
+
author's opinions *as they published them*. However, no data model is
|
|
90
|
+
perfect, so `phylohist` attempts to get as close as possible while
|
|
91
|
+
capturing literal text and editorial reasoning to inform users of
|
|
92
|
+
possible discrepancies and inferences. Only ICZN-mandated
|
|
93
|
+
textual normalizations are performed. In more recently-entered data,
|
|
94
|
+
the original textual form is also captured (e.g. "Asterias caputmedusae"
|
|
95
|
+
vs "Aſterias Caput meduſæ"). The common use of only non-Latin names for
|
|
96
|
+
higher taxa in earlier publications introduces further difficulty, as
|
|
97
|
+
does the uneven introduction of ranks other than those first used by Linnaeus.
|
|
98
|
+
* **Continuous Ingestion:** Determining how to translate loose, informal
|
|
99
|
+
prose into deterministic YAML schemas without breaking historical context
|
|
100
|
+
is an ongoing design effort. Often, a paper will inspire a revision
|
|
101
|
+
to the data model, meaning that data entered at different times shows
|
|
102
|
+
different levels of completion. Older data may use less precise structures
|
|
103
|
+
that will eventually brought in line with the current design so that
|
|
104
|
+
the older structures can be dropped.
|
|
105
|
+
|
|
106
|
+
*The project welcomes feedback or additions to schemas and coverage maps
|
|
107
|
+
via GitHub issues. Please open an issue prior to working on a pull request
|
|
108
|
+
to ensure that the request will be well-received.*
|
|
109
|
+
|
|
110
|
+
## Humans, Models, and Code
|
|
111
|
+
|
|
112
|
+
The internet has made a tremendous amount of information available,
|
|
113
|
+
but finding what you need and verifying its accuracy is a lot of work.
|
|
114
|
+
Humans have the deepest judgement for data curation, while models
|
|
115
|
+
handle flexible querying beyond what fixed database queries can provide.
|
|
116
|
+
Underneath it all, deterministic code ensures fast, repeatable, and
|
|
117
|
+
accurate outcomes.
|
|
118
|
+
|
|
119
|
+
This diagram shows the roles of humans (the top row), models (the middle)
|
|
120
|
+
and code. The third column shows the expected typical interactive usage,
|
|
121
|
+
where the model interprets the questions and chooses the tools to call and
|
|
122
|
+
output shapes to render, but leaves the querying and output construction
|
|
123
|
+
to code.
|
|
124
|
+
|
|
125
|
+
This avoids verbose or hallucinated output while spending tokens only
|
|
126
|
+
on the work that really requires a model's reasoning and flexibility.
|
|
127
|
+
|
|
128
|
+
<picture>
|
|
129
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/handrews/phylohist/main/docs/architecture-dark.svg">
|
|
130
|
+
<img alt="How phylohist fits together: three lanes, human, model and code, read in four columns, the data, the CLI, chat and the eval" src="https://raw.githubusercontent.com/handrews/phylohist/main/docs/architecture.svg">
|
|
131
|
+
</picture>
|
|
132
|
+
|
|
133
|
+
- **The data.** The curator records each publication's opinions as
|
|
134
|
+
printed: who published what systematic information in which paper.
|
|
135
|
+
That is names and nomenclatural acts, placements, usages and
|
|
136
|
+
synonymies, the specimens they rest on with their geological context,
|
|
137
|
+
and the page, plate and figure numbers that locate each of these. It
|
|
138
|
+
is not diagnoses, descriptions or a narration of the paper; a
|
|
139
|
+
researcher who wants those follows the citation to the paper itself.
|
|
140
|
+
The model's part is optional and reviewable: it reads a
|
|
141
|
+
paper against its tree and writes a review (`notes/reviews/`), or
|
|
142
|
+
drafts a tree (`drafts/`) that code validates and the researcher
|
|
143
|
+
audits before it enters `data/`. The human and the model review each
|
|
144
|
+
other's work; code checks both against the schema and regenerates the
|
|
145
|
+
claim table, which CI keeps current.
|
|
146
|
+
- **The CLI.** A question goes from the researcher to the tools with no
|
|
147
|
+
model in the lane: `phylohist history rhenopyrgus` renders the block.
|
|
148
|
+
- **Chat.** Claude asks the MCP server. The model resolves the
|
|
149
|
+
names and papers the question mentions and states a plan, the blocks
|
|
150
|
+
the answer is made of; code builds and renders them. The model
|
|
151
|
+
chooses; code answers. The only words of the model's own that reach a
|
|
152
|
+
reader are a one-line header stating the parameters it chose.
|
|
153
|
+
- **The eval.** The runner drives the model over the committed
|
|
154
|
+
questions in compose or planner mode, the grader is code, and a model
|
|
155
|
+
judges only the header. The researcher writes the questions and
|
|
156
|
+
reviews the grades and write-ups (`eval/`).
|
|
157
|
+
|
|
158
|
+
## Correctness, Performance, and Cost
|
|
159
|
+
|
|
160
|
+
The project's evolution can be seen through the evaluation
|
|
161
|
+
[metrics](https://github.com/handrews/phylohist/blob/main/eval/findings/metrics.md).
|
|
162
|
+
|
|
163
|
+
Moving from AI-written prose answers to planned queries with modular
|
|
164
|
+
output blocks improved key measurements across complete evaluation runs:
|
|
165
|
+
|
|
166
|
+
* The measured pass rate rose from 61% to 87% on the original question
|
|
167
|
+
set, with several failure modes eliminated entirely; the latest run
|
|
168
|
+
(2026-11-02, the run version 0.1.0 ships with) passes 80% of those
|
|
169
|
+
questions and 80% of the expanded set of 56.
|
|
170
|
+
* Wall clock time was cut from around 25 minutes to around 10 minutes,
|
|
171
|
+
over a quarter more questions.
|
|
172
|
+
* Token usage dropped from 2.25 million to 0.60 million.
|
|
173
|
+
|
|
174
|
+
Future improvements to how the model selects blocks are expected to raise
|
|
175
|
+
the correctness score.
|
|
176
|
+
|
|
177
|
+
## Tools and MCP
|
|
178
|
+
|
|
179
|
+
The `phylohist` CLI runs queries over the claims table generated from
|
|
180
|
+
the curated YAML data. These result in output data blocks rendered
|
|
181
|
+
as text, Markdown, or JSON based on the `--style` argument.
|
|
182
|
+
|
|
183
|
+
The CLI has one subcommand per tool:
|
|
184
|
+
|
|
185
|
+
poetry run phylohist resolve "Palæaster"
|
|
186
|
+
poetry run phylohist contents 1994_guensburg_sprinkle astrocystitidae --synonymy
|
|
187
|
+
poetry run phylohist descendants edrioblastoidea
|
|
188
|
+
poetry run phylohist ancestors astrocystitidae cyathocystidae rhenopyrgidae
|
|
189
|
+
poetry run phylohist history rhenopyrgus --style markdown
|
|
190
|
+
poetry run phylohist history "Rhenopyrgus grayae"
|
|
191
|
+
poetry run phylohist under rhenopyrgus edrioblastoidina
|
|
192
|
+
poetry run phylohist statements "Rhenopyrgus viviani"
|
|
193
|
+
poetry run phylohist gap "Holloway & Jell 1983" material
|
|
194
|
+
poetry run phylohist source "Lamarck 1816"
|
|
195
|
+
poetry run phylohist plan my-plan.yaml
|
|
196
|
+
poetry run python scripts/eval_run.py --mode planner --ask "Who first placed Rhenopyrgus under Edrioblastoidina?"
|
|
197
|
+
|
|
198
|
+
The same tools are served over MCP by the `phylohist-mcp` command
|
|
199
|
+
(`phylohist/mcp.py`), which `.mcp.json` registers for Claude Code:
|
|
200
|
+
a chat model can read blocks or state a plan and get the rendered answer.
|
|
201
|
+
The "Reading the table" section of `docs/claims.md` describes the blocks
|
|
202
|
+
and the tools.
|
|
203
|
+
|
|
204
|
+
### Tool Examples
|
|
205
|
+
|
|
206
|
+
What one paper places in a family, showing only what the paper included:
|
|
207
|
+
|
|
208
|
+
$ poetry run phylohist contents 1994_guensburg_sprinkle astrocystitidae
|
|
209
|
+
Guensburg & Sprinkle 1994
|
|
210
|
+
Family Astrocystitidae emend.
|
|
211
|
+
Genus Astrocystites
|
|
212
|
+
Genus Cambroblastus
|
|
213
|
+
Genus Lampteroblastus gen. nov.
|
|
214
|
+
Type species. Lampteroblastus hintzei
|
|
215
|
+
Lampteroblastus hintzei sp. nov.
|
|
216
|
+
|
|
217
|
+
The emendation, the new genus and species, and the type species are the
|
|
218
|
+
paper's own statements; nothing here is inferred, and a source whose
|
|
219
|
+
listing is not yet entered says so instead.
|
|
220
|
+
|
|
221
|
+
See [`docs/walkthrough.md`](https://github.com/handrews/phylohist/blob/main/docs/walkthrough.md) for additional examples.
|
|
222
|
+
|
|
223
|
+
### Asking from the CLI
|
|
224
|
+
|
|
225
|
+
The `eval_run.py` script can be used to ask a question without using the
|
|
226
|
+
chat interface to see how the model plans the queries and selects the output
|
|
227
|
+
blocks. It requires an Anthropic API key to be configured.
|
|
228
|
+
|
|
229
|
+
poetry run python scripts/eval_run.py --ask "Who first placed Rhenopyrgus under Edrioblastoidina?"
|
|
230
|
+
|
|
231
|
+
Rhenopyrgus (including its subgenus rank variant) placed under Edrioblastoidina (= Edrioblastoidea); taxonomy tree, all years
|
|
232
|
+
|
|
233
|
+
Rhenopyrgus Dehm 1961 under Edrioblastoidina Fay 1962: 4 papers, 4 co-author sets, 1994–2020
|
|
234
|
+
first Guensburg & Sprinkle 1994, last Ewin et al. 2020
|
|
235
|
+
|
|
236
|
+
1994 Guensburg & Sprinkle Cyathocystidae › Rhenopyrginae › Rhenopyrgus
|
|
237
|
+
2000 Grigo Cyathocystidae › Rhenopyrginae › Rhenopyrgus
|
|
238
|
+
2013 Sumrall et al. Rhenopyrgidae › Rhenopyrgus
|
|
239
|
+
2020 Ewin et al. Rhenopyrgidae › Rhenopyrgus
|
|
240
|
+
|
|
241
|
+
--- trail
|
|
242
|
+
resolve_name {"query": "Rhenopyrgus"} -> 2 candidate(s)
|
|
243
|
+
resolve_name {"query": "Edrioblastoidina"} -> 1 candidate(s)
|
|
244
|
+
placed_under {"record": "rhenopyrgus", "parent": "edrioblastoidina", "include_variants": true} -> 1 block(s)
|
|
245
|
+
header: Rhenopyrgus (including its subgenus rank variant) placed under Edrioblastoidina (= Edrioblastoidea); taxonomy tree, all years
|
|
246
|
+
21227+375 tokens, 6.9s, tool_use
|
|
247
|
+
|
|
248
|
+
## Install
|
|
249
|
+
|
|
250
|
+
From PyPI, for the tools and the MCP server over the claim table as of
|
|
251
|
+
the release (Python 3.12 or later):
|
|
252
|
+
|
|
253
|
+
pip install phylohist
|
|
254
|
+
phylohist history rhenopyrgus
|
|
255
|
+
phylohist-mcp
|
|
256
|
+
|
|
257
|
+
The second command is the server over stdio, which any MCP client runs
|
|
258
|
+
by name. For Claude Desktop or Claude Code the entry is
|
|
259
|
+
|
|
260
|
+
{"mcpServers": {"phylohist": {"command": "phylohist-mcp"}}}
|
|
261
|
+
|
|
262
|
+
or, with nothing installed, `uvx --from phylohist phylohist-mcp` as the
|
|
263
|
+
command and its arguments.
|
|
264
|
+
|
|
265
|
+
From a checkout, for the loader, the generator and the eval,
|
|
266
|
+
[Poetry](https://python-poetry.org/):
|
|
267
|
+
|
|
268
|
+
poetry install
|
|
269
|
+
|
|
270
|
+
The claim table the tools read is generated into `phylohist/table/`, so
|
|
271
|
+
a built package carries the table as of its build and a clone answers
|
|
272
|
+
from the table as `poetry run regenerate` last wrote it.
|
|
273
|
+
`PHYLOHIST_CLAIMS` names another table to read.
|
|
274
|
+
|
|
275
|
+
Only `scripts/eval_run.py` and the grader's `--judge` call a model;
|
|
276
|
+
their client is the `eval` dependency group, and they read
|
|
277
|
+
`ANTHROPIC_API_KEY` from the environment or from a git-ignored `.env` at
|
|
278
|
+
the repository root. Nothing else needs a key.
|
|
279
|
+
|
|
280
|
+
## Checks
|
|
281
|
+
|
|
282
|
+
CI runs these on Python 3.12 and 3.14 and fails if the generated
|
|
283
|
+
schema census, the claim table or the expected-warnings file is stale;
|
|
284
|
+
after editing `data/` or the schema, `poetry run regenerate` rewrites all
|
|
285
|
+
three (a warning the load no longer produces leaves the file; a new one
|
|
286
|
+
is added with `scripts/expected_warnings.py --add`):
|
|
287
|
+
|
|
288
|
+
poetry run ruff check .
|
|
289
|
+
poetry run ruff format --check .
|
|
290
|
+
poetry run pytest --cov=phylohist --cov-fail-under=90
|
|
291
|
+
poetry run regenerate
|
|
292
|
+
git diff --exit-code scripts/schema-usage.md phylohist/table/ tests/expected-warnings.txt
|
|
293
|
+
poetry run python scripts/check_draft.py drafts/<file>.yaml
|
|
294
|
+
|
|
295
|
+
The tests run over the frozen copy of the data under `tests/corpus/`;
|
|
296
|
+
only those marked `production` load `data/` itself, so improving the
|
|
297
|
+
data cannot break a test of the code. `poetry run pytest --demo` adds the
|
|
298
|
+
eval questions and the walkthrough over the committed `phylohist/table/`, which
|
|
299
|
+
hold for the data they were last refreshed against.
|
|
300
|
+
|
|
301
|
+
## Where things are
|
|
302
|
+
|
|
303
|
+
* `docs/` will contain user documentation; for now it explains how
|
|
304
|
+
recorded tree data is converted to the claims that the tools use,
|
|
305
|
+
as well as the tools and the answer formats.
|
|
306
|
+
* `notes/` contains project development information from both the human
|
|
307
|
+
and LLM developers; some of this information might be out-of-date.
|
|
308
|
+
* `eval/` holds the evaluation questions, results, write-ups, and metrics.
|
|
309
|
+
* `drafts/` holds AI-drafted trees awaiting a human audit.
|
|
310
|
+
|
|
311
|
+
## Licence
|
|
312
|
+
|
|
313
|
+
`LICENSE` (MIT) covers everything in the repository and in the released
|
|
314
|
+
package: the code; the YAML under `data/`, which is the owner's
|
|
315
|
+
compilation of published opinions, recorded as printed; the claim table
|
|
316
|
+
generated from it; and `notes/`, the owner's and the assistant's writing.
|
|
317
|
+
If the corpus is useful in published work, please cite it
|
|
318
|
+
(`CITATION.cff`).
|
|
319
|
+
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# Phylohist: Exploring changes in systematics over time
|
|
2
|
+
|
|
3
|
+
Science is always in motion. Most online taxonomy or phylogeny
|
|
4
|
+
databases attempt to show a consensus or accepted view, with
|
|
5
|
+
each site having its own editorial policy for what gets included.
|
|
6
|
+
Some include historical information, but do not make it a central
|
|
7
|
+
or easily-accessible part of the sysetm.
|
|
8
|
+
|
|
9
|
+
The `phylohist` project instead provides access to trees as published,
|
|
10
|
+
over time, while leaving the judgement of what to accept or reject to
|
|
11
|
+
the researcher. An LLM-driven interface supports complex queries over
|
|
12
|
+
a curated corpus stored as YAML data. This uses a model where one is
|
|
13
|
+
needed, and prioritizes reliability, reproducibility, speed,
|
|
14
|
+
and lower costs where one is not.
|
|
15
|
+
|
|
16
|
+
The current corpus holds over 200 papers entered in whole or in part, from
|
|
17
|
+
the mid-1700s to the present, mostly focusing on Paleozoic echinoderms.
|
|
18
|
+
A coverage system tracks how much of the information from a paper has
|
|
19
|
+
been entered and reviewed.
|
|
20
|
+
|
|
21
|
+
## Status and future plans
|
|
22
|
+
|
|
23
|
+
This repository began as a place to store my notes, and gradually evolved
|
|
24
|
+
into a software package, featuring more and more modern software engineering
|
|
25
|
+
best practices as I have found time to add them. However, it remains
|
|
26
|
+
a solo, unfunded project that I work on whenever I can.
|
|
27
|
+
|
|
28
|
+
The package is published on PyPI as `phylohist` from version 0.1.0.
|
|
29
|
+
Next steps include writing human-user-friendly documentation,
|
|
30
|
+
continuing to improve the software development methodology, curating
|
|
31
|
+
additional data and adding more features.
|
|
32
|
+
|
|
33
|
+
A data model for capturing specimen information has recenlty been
|
|
34
|
+
designed but data entry for this area is in its infancy. Additional
|
|
35
|
+
areas of fuure work are proper support for cladograms (currently
|
|
36
|
+
allowed in the data but treated more-or-less like systematic trees)
|
|
37
|
+
and data visualization.
|
|
38
|
+
|
|
39
|
+
## Corpus Scope and Editorial Curation Policy
|
|
40
|
+
|
|
41
|
+
Because `phylohist` relies on manual validation and a human-in-the-loop
|
|
42
|
+
workflow, data ingestion proceeds slowly to prioritize high fidelity
|
|
43
|
+
over unchecked volume.
|
|
44
|
+
|
|
45
|
+
No data is entered purely by AI. The data model has grown from my experience
|
|
46
|
+
of manually reading papers and figuring out how to work with the data as
|
|
47
|
+
it was published. Current LLMs are too eager to make things "work" rather
|
|
48
|
+
than step back and consider the user experience.
|
|
49
|
+
|
|
50
|
+
### Intentional Scoping and Partial Entry
|
|
51
|
+
|
|
52
|
+
Data entry is guided by the target research scope, currently focusing primarily
|
|
53
|
+
on Paleozoic echinoderms and their relatives in the Ambulacrarian stem group.
|
|
54
|
+
|
|
55
|
+
* **Partial Ingestion:** For vast foundational texts such as Linnaeus’s
|
|
56
|
+
*Systema Naturae*, only the specific branches of interest to the active
|
|
57
|
+
dataset are entered.
|
|
58
|
+
* **Closed-World Boundaries:** The data model is being enhanced with ways
|
|
59
|
+
to indicate when data is complete by some metric. However, updating
|
|
60
|
+
the data with these fields is itself a large, ongoing project.
|
|
61
|
+
|
|
62
|
+
### Archival Fidelity vs. Modern Interpretation
|
|
63
|
+
|
|
64
|
+
Tracking archaic, text-heavy literature (particularly pre-19th-century sources
|
|
65
|
+
written in informal prose) presents a unique archival challenge.
|
|
66
|
+
|
|
67
|
+
* **Philosophy:** The core directive of this corpus is to capture the published
|
|
68
|
+
author's opinions *as they published them*. However, no data model is
|
|
69
|
+
perfect, so `phylohist` attempts to get as close as possible while
|
|
70
|
+
capturing literal text and editorial reasoning to inform users of
|
|
71
|
+
possible discrepancies and inferences. Only ICZN-mandated
|
|
72
|
+
textual normalizations are performed. In more recently-entered data,
|
|
73
|
+
the original textual form is also captured (e.g. "Asterias caputmedusae"
|
|
74
|
+
vs "Aſterias Caput meduſæ"). The common use of only non-Latin names for
|
|
75
|
+
higher taxa in earlier publications introduces further difficulty, as
|
|
76
|
+
does the uneven introduction of ranks other than those first used by Linnaeus.
|
|
77
|
+
* **Continuous Ingestion:** Determining how to translate loose, informal
|
|
78
|
+
prose into deterministic YAML schemas without breaking historical context
|
|
79
|
+
is an ongoing design effort. Often, a paper will inspire a revision
|
|
80
|
+
to the data model, meaning that data entered at different times shows
|
|
81
|
+
different levels of completion. Older data may use less precise structures
|
|
82
|
+
that will eventually brought in line with the current design so that
|
|
83
|
+
the older structures can be dropped.
|
|
84
|
+
|
|
85
|
+
*The project welcomes feedback or additions to schemas and coverage maps
|
|
86
|
+
via GitHub issues. Please open an issue prior to working on a pull request
|
|
87
|
+
to ensure that the request will be well-received.*
|
|
88
|
+
|
|
89
|
+
## Humans, Models, and Code
|
|
90
|
+
|
|
91
|
+
The internet has made a tremendous amount of information available,
|
|
92
|
+
but finding what you need and verifying its accuracy is a lot of work.
|
|
93
|
+
Humans have the deepest judgement for data curation, while models
|
|
94
|
+
handle flexible querying beyond what fixed database queries can provide.
|
|
95
|
+
Underneath it all, deterministic code ensures fast, repeatable, and
|
|
96
|
+
accurate outcomes.
|
|
97
|
+
|
|
98
|
+
This diagram shows the roles of humans (the top row), models (the middle)
|
|
99
|
+
and code. The third column shows the expected typical interactive usage,
|
|
100
|
+
where the model interprets the questions and chooses the tools to call and
|
|
101
|
+
output shapes to render, but leaves the querying and output construction
|
|
102
|
+
to code.
|
|
103
|
+
|
|
104
|
+
This avoids verbose or hallucinated output while spending tokens only
|
|
105
|
+
on the work that really requires a model's reasoning and flexibility.
|
|
106
|
+
|
|
107
|
+
<picture>
|
|
108
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/handrews/phylohist/main/docs/architecture-dark.svg">
|
|
109
|
+
<img alt="How phylohist fits together: three lanes, human, model and code, read in four columns, the data, the CLI, chat and the eval" src="https://raw.githubusercontent.com/handrews/phylohist/main/docs/architecture.svg">
|
|
110
|
+
</picture>
|
|
111
|
+
|
|
112
|
+
- **The data.** The curator records each publication's opinions as
|
|
113
|
+
printed: who published what systematic information in which paper.
|
|
114
|
+
That is names and nomenclatural acts, placements, usages and
|
|
115
|
+
synonymies, the specimens they rest on with their geological context,
|
|
116
|
+
and the page, plate and figure numbers that locate each of these. It
|
|
117
|
+
is not diagnoses, descriptions or a narration of the paper; a
|
|
118
|
+
researcher who wants those follows the citation to the paper itself.
|
|
119
|
+
The model's part is optional and reviewable: it reads a
|
|
120
|
+
paper against its tree and writes a review (`notes/reviews/`), or
|
|
121
|
+
drafts a tree (`drafts/`) that code validates and the researcher
|
|
122
|
+
audits before it enters `data/`. The human and the model review each
|
|
123
|
+
other's work; code checks both against the schema and regenerates the
|
|
124
|
+
claim table, which CI keeps current.
|
|
125
|
+
- **The CLI.** A question goes from the researcher to the tools with no
|
|
126
|
+
model in the lane: `phylohist history rhenopyrgus` renders the block.
|
|
127
|
+
- **Chat.** Claude asks the MCP server. The model resolves the
|
|
128
|
+
names and papers the question mentions and states a plan, the blocks
|
|
129
|
+
the answer is made of; code builds and renders them. The model
|
|
130
|
+
chooses; code answers. The only words of the model's own that reach a
|
|
131
|
+
reader are a one-line header stating the parameters it chose.
|
|
132
|
+
- **The eval.** The runner drives the model over the committed
|
|
133
|
+
questions in compose or planner mode, the grader is code, and a model
|
|
134
|
+
judges only the header. The researcher writes the questions and
|
|
135
|
+
reviews the grades and write-ups (`eval/`).
|
|
136
|
+
|
|
137
|
+
## Correctness, Performance, and Cost
|
|
138
|
+
|
|
139
|
+
The project's evolution can be seen through the evaluation
|
|
140
|
+
[metrics](https://github.com/handrews/phylohist/blob/main/eval/findings/metrics.md).
|
|
141
|
+
|
|
142
|
+
Moving from AI-written prose answers to planned queries with modular
|
|
143
|
+
output blocks improved key measurements across complete evaluation runs:
|
|
144
|
+
|
|
145
|
+
* The measured pass rate rose from 61% to 87% on the original question
|
|
146
|
+
set, with several failure modes eliminated entirely; the latest run
|
|
147
|
+
(2026-11-02, the run version 0.1.0 ships with) passes 80% of those
|
|
148
|
+
questions and 80% of the expanded set of 56.
|
|
149
|
+
* Wall clock time was cut from around 25 minutes to around 10 minutes,
|
|
150
|
+
over a quarter more questions.
|
|
151
|
+
* Token usage dropped from 2.25 million to 0.60 million.
|
|
152
|
+
|
|
153
|
+
Future improvements to how the model selects blocks are expected to raise
|
|
154
|
+
the correctness score.
|
|
155
|
+
|
|
156
|
+
## Tools and MCP
|
|
157
|
+
|
|
158
|
+
The `phylohist` CLI runs queries over the claims table generated from
|
|
159
|
+
the curated YAML data. These result in output data blocks rendered
|
|
160
|
+
as text, Markdown, or JSON based on the `--style` argument.
|
|
161
|
+
|
|
162
|
+
The CLI has one subcommand per tool:
|
|
163
|
+
|
|
164
|
+
poetry run phylohist resolve "Palæaster"
|
|
165
|
+
poetry run phylohist contents 1994_guensburg_sprinkle astrocystitidae --synonymy
|
|
166
|
+
poetry run phylohist descendants edrioblastoidea
|
|
167
|
+
poetry run phylohist ancestors astrocystitidae cyathocystidae rhenopyrgidae
|
|
168
|
+
poetry run phylohist history rhenopyrgus --style markdown
|
|
169
|
+
poetry run phylohist history "Rhenopyrgus grayae"
|
|
170
|
+
poetry run phylohist under rhenopyrgus edrioblastoidina
|
|
171
|
+
poetry run phylohist statements "Rhenopyrgus viviani"
|
|
172
|
+
poetry run phylohist gap "Holloway & Jell 1983" material
|
|
173
|
+
poetry run phylohist source "Lamarck 1816"
|
|
174
|
+
poetry run phylohist plan my-plan.yaml
|
|
175
|
+
poetry run python scripts/eval_run.py --mode planner --ask "Who first placed Rhenopyrgus under Edrioblastoidina?"
|
|
176
|
+
|
|
177
|
+
The same tools are served over MCP by the `phylohist-mcp` command
|
|
178
|
+
(`phylohist/mcp.py`), which `.mcp.json` registers for Claude Code:
|
|
179
|
+
a chat model can read blocks or state a plan and get the rendered answer.
|
|
180
|
+
The "Reading the table" section of `docs/claims.md` describes the blocks
|
|
181
|
+
and the tools.
|
|
182
|
+
|
|
183
|
+
### Tool Examples
|
|
184
|
+
|
|
185
|
+
What one paper places in a family, showing only what the paper included:
|
|
186
|
+
|
|
187
|
+
$ poetry run phylohist contents 1994_guensburg_sprinkle astrocystitidae
|
|
188
|
+
Guensburg & Sprinkle 1994
|
|
189
|
+
Family Astrocystitidae emend.
|
|
190
|
+
Genus Astrocystites
|
|
191
|
+
Genus Cambroblastus
|
|
192
|
+
Genus Lampteroblastus gen. nov.
|
|
193
|
+
Type species. Lampteroblastus hintzei
|
|
194
|
+
Lampteroblastus hintzei sp. nov.
|
|
195
|
+
|
|
196
|
+
The emendation, the new genus and species, and the type species are the
|
|
197
|
+
paper's own statements; nothing here is inferred, and a source whose
|
|
198
|
+
listing is not yet entered says so instead.
|
|
199
|
+
|
|
200
|
+
See [`docs/walkthrough.md`](https://github.com/handrews/phylohist/blob/main/docs/walkthrough.md) for additional examples.
|
|
201
|
+
|
|
202
|
+
### Asking from the CLI
|
|
203
|
+
|
|
204
|
+
The `eval_run.py` script can be used to ask a question without using the
|
|
205
|
+
chat interface to see how the model plans the queries and selects the output
|
|
206
|
+
blocks. It requires an Anthropic API key to be configured.
|
|
207
|
+
|
|
208
|
+
poetry run python scripts/eval_run.py --ask "Who first placed Rhenopyrgus under Edrioblastoidina?"
|
|
209
|
+
|
|
210
|
+
Rhenopyrgus (including its subgenus rank variant) placed under Edrioblastoidina (= Edrioblastoidea); taxonomy tree, all years
|
|
211
|
+
|
|
212
|
+
Rhenopyrgus Dehm 1961 under Edrioblastoidina Fay 1962: 4 papers, 4 co-author sets, 1994–2020
|
|
213
|
+
first Guensburg & Sprinkle 1994, last Ewin et al. 2020
|
|
214
|
+
|
|
215
|
+
1994 Guensburg & Sprinkle Cyathocystidae › Rhenopyrginae › Rhenopyrgus
|
|
216
|
+
2000 Grigo Cyathocystidae › Rhenopyrginae › Rhenopyrgus
|
|
217
|
+
2013 Sumrall et al. Rhenopyrgidae › Rhenopyrgus
|
|
218
|
+
2020 Ewin et al. Rhenopyrgidae › Rhenopyrgus
|
|
219
|
+
|
|
220
|
+
--- trail
|
|
221
|
+
resolve_name {"query": "Rhenopyrgus"} -> 2 candidate(s)
|
|
222
|
+
resolve_name {"query": "Edrioblastoidina"} -> 1 candidate(s)
|
|
223
|
+
placed_under {"record": "rhenopyrgus", "parent": "edrioblastoidina", "include_variants": true} -> 1 block(s)
|
|
224
|
+
header: Rhenopyrgus (including its subgenus rank variant) placed under Edrioblastoidina (= Edrioblastoidea); taxonomy tree, all years
|
|
225
|
+
21227+375 tokens, 6.9s, tool_use
|
|
226
|
+
|
|
227
|
+
## Install
|
|
228
|
+
|
|
229
|
+
From PyPI, for the tools and the MCP server over the claim table as of
|
|
230
|
+
the release (Python 3.12 or later):
|
|
231
|
+
|
|
232
|
+
pip install phylohist
|
|
233
|
+
phylohist history rhenopyrgus
|
|
234
|
+
phylohist-mcp
|
|
235
|
+
|
|
236
|
+
The second command is the server over stdio, which any MCP client runs
|
|
237
|
+
by name. For Claude Desktop or Claude Code the entry is
|
|
238
|
+
|
|
239
|
+
{"mcpServers": {"phylohist": {"command": "phylohist-mcp"}}}
|
|
240
|
+
|
|
241
|
+
or, with nothing installed, `uvx --from phylohist phylohist-mcp` as the
|
|
242
|
+
command and its arguments.
|
|
243
|
+
|
|
244
|
+
From a checkout, for the loader, the generator and the eval,
|
|
245
|
+
[Poetry](https://python-poetry.org/):
|
|
246
|
+
|
|
247
|
+
poetry install
|
|
248
|
+
|
|
249
|
+
The claim table the tools read is generated into `phylohist/table/`, so
|
|
250
|
+
a built package carries the table as of its build and a clone answers
|
|
251
|
+
from the table as `poetry run regenerate` last wrote it.
|
|
252
|
+
`PHYLOHIST_CLAIMS` names another table to read.
|
|
253
|
+
|
|
254
|
+
Only `scripts/eval_run.py` and the grader's `--judge` call a model;
|
|
255
|
+
their client is the `eval` dependency group, and they read
|
|
256
|
+
`ANTHROPIC_API_KEY` from the environment or from a git-ignored `.env` at
|
|
257
|
+
the repository root. Nothing else needs a key.
|
|
258
|
+
|
|
259
|
+
## Checks
|
|
260
|
+
|
|
261
|
+
CI runs these on Python 3.12 and 3.14 and fails if the generated
|
|
262
|
+
schema census, the claim table or the expected-warnings file is stale;
|
|
263
|
+
after editing `data/` or the schema, `poetry run regenerate` rewrites all
|
|
264
|
+
three (a warning the load no longer produces leaves the file; a new one
|
|
265
|
+
is added with `scripts/expected_warnings.py --add`):
|
|
266
|
+
|
|
267
|
+
poetry run ruff check .
|
|
268
|
+
poetry run ruff format --check .
|
|
269
|
+
poetry run pytest --cov=phylohist --cov-fail-under=90
|
|
270
|
+
poetry run regenerate
|
|
271
|
+
git diff --exit-code scripts/schema-usage.md phylohist/table/ tests/expected-warnings.txt
|
|
272
|
+
poetry run python scripts/check_draft.py drafts/<file>.yaml
|
|
273
|
+
|
|
274
|
+
The tests run over the frozen copy of the data under `tests/corpus/`;
|
|
275
|
+
only those marked `production` load `data/` itself, so improving the
|
|
276
|
+
data cannot break a test of the code. `poetry run pytest --demo` adds the
|
|
277
|
+
eval questions and the walkthrough over the committed `phylohist/table/`, which
|
|
278
|
+
hold for the data they were last refreshed against.
|
|
279
|
+
|
|
280
|
+
## Where things are
|
|
281
|
+
|
|
282
|
+
* `docs/` will contain user documentation; for now it explains how
|
|
283
|
+
recorded tree data is converted to the claims that the tools use,
|
|
284
|
+
as well as the tools and the answer formats.
|
|
285
|
+
* `notes/` contains project development information from both the human
|
|
286
|
+
and LLM developers; some of this information might be out-of-date.
|
|
287
|
+
* `eval/` holds the evaluation questions, results, write-ups, and metrics.
|
|
288
|
+
* `drafts/` holds AI-drafted trees awaiting a human audit.
|
|
289
|
+
|
|
290
|
+
## Licence
|
|
291
|
+
|
|
292
|
+
`LICENSE` (MIT) covers everything in the repository and in the released
|
|
293
|
+
package: the code; the YAML under `data/`, which is the owner's
|
|
294
|
+
compilation of published opinions, recorded as printed; the claim table
|
|
295
|
+
generated from it; and `notes/`, the owner's and the assistant's writing.
|
|
296
|
+
If the corpus is useful in published work, please cite it
|
|
297
|
+
(`CITATION.cff`).
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
import coloredlog
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ColourHandler(coloredlog.ConsoleHandler):
|
|
10
|
+
"""`coloredlog` writes its colour codes into the record it is given, and
|
|
11
|
+
every handler after it then sees them: a collector comparing messages
|
|
12
|
+
with the expected warnings, pytest's caplog. This colours a copy."""
|
|
13
|
+
|
|
14
|
+
def emit(self, record):
|
|
15
|
+
super().emit(copy.copy(record))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
_phylohist_logger = logging.getLogger(__name__)
|
|
19
|
+
_log_formatter = logging.Formatter(
|
|
20
|
+
'%(asctime)s %(filename)s:%(lineno)d [%(levelname)s] %(message)s',
|
|
21
|
+
)
|
|
22
|
+
_log_handler = (
|
|
23
|
+
ColourHandler(stream=sys.stderr)
|
|
24
|
+
if sys.stderr.isatty() or os.getenv('PHYLOHIST_COLOR') == '1'
|
|
25
|
+
else logging.StreamHandler()
|
|
26
|
+
)
|
|
27
|
+
_log_handler.setFormatter(_log_formatter)
|
|
28
|
+
_phylohist_logger.addHandler(_log_handler)
|
|
29
|
+
_phylohist_logger.setLevel(logging.INFO)
|
|
30
|
+
|
|
31
|
+
logger = _phylohist_logger
|