Skip to content

/cpic pharmacogenomics cockpit (endpoint + page) over a shared reason()#63

Merged
AdaWorldAPI merged 1 commit into
mainfrom
claude/cpic-cockpit
Jun 25, 2026
Merged

/cpic pharmacogenomics cockpit (endpoint + page) over a shared reason()#63
AdaWorldAPI merged 1 commit into
mainfrom
claude/cpic-cockpit

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

/cpic — gene-first pharmacogenomics cockpit

Adds a /cpic cockpit (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 of cpic's bin/reason.rs into the lib so the CLI and the new cockpit endpoint share one engine.

Changes

  • cpic libreason(&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 via include_str! (no runtime files; Railway-safe). When CPIC has no simple phenotype→recommendation, resolved == false and flags say why (unknown drug, unresolvable phenotype, complex / multi-gene guideline) — surfaced, never fabricated. 2 unit tests.
  • cpic/src/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).
  • cockpit-server pgx.rsPOST /api/cpic/reason (→ Outcome) and GET /api/cpic/catalog over a LazyLock<Kb> = Kb::embedded(). The module is named pgx, not cpic, so it doesn't shadow the cpic dependency crate in the edition-2024 extern prelude. Routes registered in main.rs next to the clinical route.
  • CpicCockpit.tsx + /cpic route — 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.
  • root Cargo.tomlexclude the standalone cpic crate (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.
  • cockpit frontend: tsc (strict) + vite build.
  • pgx.rs: the exact handlers + route registration type-check against axum 0.7 + cpic (verified in isolation, since the full cockpit-server build is blocked — see below).

Note — pre-existing lance-graph-ogar blocker (independent of this PR)

The full cockpit-server build currently cannot complete locally because of a pre-existing const-assert in the sibling lance-graph-ogar: COUNT_FUSE at crates/lance-graph-ogar/src/lib.rs:118 fires because lance_graph_contract::ogar_codebook::CODEBOOK (the contract's wire mirror) has drifted from ogar_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/reason verifies there exactly as the clinical endpoint did. The fix belongs in lance-graph (update the contract CODEBOOK to 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

…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
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@AdaWorldAPI, we couldn't start this review because you've reached your PR review rate limit.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8c166800-f43c-471b-a6bc-98c7de3f7be8

📥 Commits

Reviewing files that changed from the base of the PR and between 62f4eaa and ee1196d.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • cpic/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • Cargo.toml
  • cockpit/src/CpicCockpit.tsx
  • cockpit/src/main.tsx
  • cpic/Cargo.toml
  • cpic/src/bin/reason.rs
  • cpic/src/lib.rs
  • crates/cockpit-server/Cargo.toml
  • crates/cockpit-server/src/main.rs
  • crates/cockpit-server/src/pgx.rs

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@AdaWorldAPI AdaWorldAPI merged commit 4fecece into main Jun 25, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants