/cpic pharmacogenomics cockpit (endpoint + page) over a shared reason()#63
Conversation
…red reason() Extract the CPIC reasoning out of `bin/reason.rs` into the `cpic` lib so the CLI and a cockpit endpoint share ONE implementation, then wire the gene-first `/cpic` cockpit on top of it — additive alongside the organ-first `/fma-body`. cpic crate (lib extraction): - lib.rs: Truth, Kb (from_jsons/load/embedded/catalog), Catalog, ChainNode, Outcome, and reason(&Kb, gene, input, drug) -> Outcome. `reason` is a faithful port of the bin's logic returning structured data instead of printing; when CPIC has no simple phenotype->recommendation, `resolved == false` and `flags` say why (unknown drug, unresolvable phenotype, complex / multi-gene guideline) — surfaced, never fabricated. Kb::embedded() bakes the six CPIC tables via include_str!, so the endpoint needs no runtime files (Railway-safe). 2 unit tests. - bin/reason.rs: now a thin CLI over cpic::reason + a print fn (removes the duplicated Truth/Kb/load/resolve_phenotype/reason that lived only in the bin). - Cargo.toml: add serde derive (Outcome/Catalog/ChainNode are Serialize). cockpit-server endpoint: - pgx.rs: POST /api/cpic/reason (-> Outcome) and GET /api/cpic/catalog over a LazyLock<Kb> = Kb::embedded(). The module is named `pgx`, NOT `cpic`, so it does not shadow the `cpic` dependency crate in the edition-2024 extern prelude. - main.rs: mod pgx + the two routes (next to the clinical route). - Cargo.toml: cpic path dep (serde + serde_json only — drags no lance closure). frontend: - CpicCockpit.tsx: gene / diplotype / drug inputs (catalog-backed <datalist>), the reasoned diplotype->phenotype->recommendation chain with each node's routable (part_of:is_a) GUID, classification + CPIC-level badges, NARS f/c/expectation, the recommendation text, complexity flags, and an in-view "not clinical decision support" disclaimer. The four `reason` CLI demos appear as example chips. - main.tsx: /cpic route. workspace: - root Cargo.toml: exclude `cpic` (it keeps its own [workspace]) so cockpit-server's path dependency crosses the workspace boundary cleanly instead of tripping "multiple workspace roots found in the same workspace". Verified: cpic `cargo build` + `cargo test` (2 pass) + the CLI demo run (CYP2C19 *2/*2 -> Poor Metabolizer -> Strong f=0.950 c=0.767; CYP2C9/warfarin correctly surfaces the complex-guideline flag instead of fabricating). Cockpit frontend `tsc` (strict) + `vite build`. cockpit-server `cargo check` (full lance closure) running; runtime endpoint to be exercised on the Railway deploy, as the clinical endpoint was. POC over published CPIC rules — NOT clinical decision support. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TzqvDqbFRzyx17EkLKBoZF
|
Warning Review limit reached
More reviews will be available in 25 minutes and 32 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (9)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
/cpic — gene-first pharmacogenomics cockpit
Adds a
/cpiccockpit (gene → phenotype → recommendation, 2-hop NARS deduction over the real published CPIC tables), additive alongside the organ-first/fma-body. Extracts the CPIC reasoning out ofcpic'sbin/reason.rsinto the lib so the CLI and the new cockpit endpoint share one engine.Changes
cpiclib —reason(&Kb, gene, input, drug) -> Outcome, a faithful port of the bin's logic returning structured data instead of printing.Kb::embedded()bakes the six CPIC tables viainclude_str!(no runtime files; Railway-safe). When CPIC has no simple phenotype→recommendation,resolved == falseandflagssay why (unknown drug, unresolvable phenotype, complex / multi-gene guideline) — surfaced, never fabricated. 2 unit tests.cpic/src/bin/reason.rs— now a thin CLI overcpic::reason+ a print fn (removes the duplicatedTruth/Kb/load/resolve_phenotype/reasonthat lived only in the bin).cockpit-serverpgx.rs—POST /api/cpic/reason(→Outcome) andGET /api/cpic/catalogover aLazyLock<Kb> = Kb::embedded(). The module is namedpgx, notcpic, so it doesn't shadow thecpicdependency crate in the edition-2024 extern prelude. Routes registered inmain.rsnext to the clinical route.CpicCockpit.tsx+/cpicroute — gene / diplotype / drug inputs (catalog-backed<datalist>), the reasoned diplotype→phenotype→recommendation chain with each node's routable(part_of:is_a)GUID, classification + CPIC-level badges, NARS f/c/expectation, the recommendation text, complexity flags, and an in-view "not clinical decision support" disclaimer. The fourreasonCLI demos appear as example chips.Cargo.toml—excludethe standalonecpiccrate (it keeps its own[workspace]) so cockpit-server's path dependency crosses the workspace boundary cleanly instead of tripping "multiple workspace roots found in the same workspace".Verification
cpic:cargo build+cargo test(2 pass) + CLI demo run — CYP2C19*2/*2→ Poor Metabolizer → Strong (f=0.950, c=0.767); CYP2C9/warfarin correctly surfaces the complex-guideline flag instead of fabricating a recommendation.tsc(strict) +vite build.pgx.rs: the exact handlers + route registration type-check againstaxum 0.7+cpic(verified in isolation, since the full cockpit-server build is blocked — see below).Note — pre-existing
lance-graph-ogarblocker (independent of this PR)The full
cockpit-serverbuild currently cannot complete locally because of a pre-existing const-assert in the siblinglance-graph-ogar:COUNT_FUSEatcrates/lance-graph-ogar/src/lib.rs:118fires becauselance_graph_contract::ogar_codebook::CODEBOOK(the contract's wire mirror) has drifted fromogar_vocab::class_ids::ALL(concept-count mismatch). Its inputs are entirely inside lance-graph + its OGAR git pin — unrelated to cpic — and it blocks any cockpit-server build against the current OGAR pin. Railway builds lance-graph at a consistent ref (where the fuse passes), so/api/cpic/reasonverifies there exactly as the clinical endpoint did. The fix belongs in lance-graph (update the contractCODEBOOKto match OGAR).POC over published CPIC rules — NOT clinical decision support.
🤖 Generated with Claude Code
https://claude.ai/code/session_01TzqvDqbFRzyx17EkLKBoZF
Generated by Claude Code