Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "celltypepilot",
"version": "0.3.1",
"version": "0.4.0",
"description": "Single-cell annotation review plugin — governed context, independent state evidence, conservative abstention, and critic checks.",
"author": {
"name": "HERRY423"
Expand Down
2 changes: 1 addition & 1 deletion .codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "celltypepilot",
"version": "0.3.1",
"version": "0.4.0",
"description": "Single-cell annotation review plugin — governed context, independent state evidence, conservative abstention, and critic checks.",
"author": {
"name": "HERRY423",
Expand Down
19 changes: 18 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,20 @@ celltypepilot annotate \
--embedding-key <key> \
[--context <text>] \
[--context-file <context.json>] \
[--custom-markers <markers.csv>]
[--custom-markers <markers.csv>] \
[--candidate-table <celltypist.csv>] \
[--candidate-table <popv.csv>] \
[--native-backends <celltypepilot.native-backends.v1.json>]
```

`--native-backends` executes governed CellTypist, popV, SingleR, scANVI,
custom-reference, and optional LLM candidate runners inside ordinary annotation.
Backend failures remain explicit and contribute no vote. popV/scANVI require raw
counts; LLM requires explicit network opt-in and remains `hypothesis_only`.

This produces:
- `backend_candidates.csv` — normalized CellTypist/popV/SingleR/scANVI/custom-reference/LLM candidates plus evidence-only marker rows
- `hierarchical_decisions.csv` — accepted leaf/ancestor or fail-closed candidate-set/abstain decisions
- `data.annotated.h5ad` — AnnData with separate identity and state fields, candidate, decision, abstain reason, CL ID, and confidence in obs
- `evidence_table.csv` — per-cluster evidence: scores, score semantics, markers, critic flags, confidence, uncertainty-language fields
- `contrastive_evidence.csv` — top-two candidate contrast using the existing ranking; shared/unique support, gaps, conflicts, and provenance without reranking
Expand Down Expand Up @@ -163,6 +173,7 @@ Useful when the critic flags a cluster and you want additional validation.
| `celltypepilot annotate -i <path> -k <key>` | Full annotation pipeline |
| `celltypepilot benchmark ... --evaluation-unit cell\|cluster\|both` | Lock/evaluate independent holdouts with separate cell and cluster endpoints |
| `celltypepilot benchmark-run ... --evaluation-unit cell\|cluster\|both` | Execute fold-isolated comparators without blending evaluation units |
| `celltypepilot domain-validation-plan/run` | Lock and execute resumable lung, gut/IBD, and TME evidence workflows |
| `celltypepilot calibrate ...` | Fit a downgrade-only abstention policy on a separate calibration dataset |
| `celltypepilot critic -i <path> -k <key> -f <cluster>` | Deep-review a specific cluster |
| `celltypepilot markers -t <tissue>` | List available cell types and markers |
Expand Down Expand Up @@ -232,6 +243,9 @@ Bundled extended atlas (historical directory name `premium`, MIT-licensed and op
12. **Detection ≠ support** — detecting a species, tissue, or batch axis helps the Agent host route the workflow; it does not authorize unsupported atlas scoring or robustness claims
13. **Agent-native but deterministic** — MCP tools expose bounded CellTypePilot operations; do not add autonomous planning or self-directed biological claims
14. **Review auditability** — manual Web Review edits must leave an append-only audit trail and mark derived artifacts stale after write-back
15. **Backend-neutral identity** — CellTypist, popV, SingleR, scANVI, custom references, and optional LLMs generate candidates under one contract; marker scoring is evidence-only and cannot independently accept identity
16. **Hierarchical selective decision** — default leaf acceptance requires two independent backend groups; sibling disagreement may collapse only to a governed ancestor, otherwise write `Unknown`; backend agreement is not a calibrated probability
17. **Three depth-validation domains** — concentrate claim-building on lung, gut/IBD, and tumor microenvironment; broader Atlas coverage is exploratory until domain-specific locked evidence gates pass

## Project layout

Expand Down Expand Up @@ -264,6 +278,9 @@ celltypepilot/
│ │ └── state_atlas.json # Versioned exploratory cell-state modules
│ ├── templates/ # Jinja2 templates (HTML report, web dashboard)
│ ├── marker_scorer.py # DE + marker overlap scoring
│ ├── candidate_backends.py # Backend-neutral candidate normalization and role policy
│ ├── hierarchical_selector.py # Ontology-aware selective identity decisions
│ ├── validation_domains.py # Three-domain focus and claim-readiness boundary
│ ├── reference_scorer.py # Reference embedding scoring (4 backends)
│ ├── ensemble_scorer.py # Adaptive ensemble fusion
│ ├── pack_manager.py # Extension pack install/validate/merge (data-only)
Expand Down
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,35 @@ All notable changes to CellTypePilot are documented here. The project follows
[Semantic Versioning](https://semver.org/). Release claims remain bounded by the
validation scope recorded in the repository and generated manifests.

## [0.4.0] - 2026-08-11

### Added

- Backend-neutral candidate artifacts and an ontology-aware selective decision layer for
CellTypist, popV, SingleR, scANVI, custom references, and optional hypothesis-only LLM review.
- Native, resumable runners for those backends in ordinary `annotate`, with truth stripping and
fold-local reuse in public benchmarks.
- Three depth-domain Atlas contracts for lung, gut/IBD, and tumor microenvironment, including
governed scope packs and explicit evidence/claim boundaries.
- Outcome-blind donor-role locking for downgrade-only calibration and truth-free multi-lineage
coverage audits.
- A hash-verified governance freeze spanning decision code, Atlas content, state/novelty policy,
calibration policy, and domain contracts.

### Changed

- The marker scorer is evidence-only and no longer serves as the primary identity classifier when
backend-neutral candidates are configured.
- Domain validation uses fold-isolated native backends, separate cell/cluster endpoints, atomic
checkpoints, and retained unavailable/failed method statuses.

### Validation boundary

- The software release and lung multi-lineage addressability audit do not establish annotation
accuracy, calibrated selective risk, independent-cohort calibration, or domain validation.
- Three-domain and five-cohort evidence claims remain fail-closed until their locked minimum cohort,
runtime, calibration, expert-adjudication, and robustness requirements are satisfied.

## [0.3.1] - 2026-08-10

### Fixed
Expand Down Expand Up @@ -50,5 +79,6 @@ validation scope recorded in the repository and generated manifests.
- It does not establish biological superiority over CellTypist, SingleR, Azimuth, popV, or expert review.
- A qualified human remains responsible for final annotations and biological claims.

[0.4.0]: https://github.com/HERRY423/CellTypePilot/releases/tag/v0.4.0
[0.3.1]: https://github.com/HERRY423/CellTypePilot/releases/tag/v0.3.1
[0.3.0]: https://github.com/HERRY423/CellTypePilot/releases/tag/v0.3.0
93 changes: 80 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,18 @@ Claude Code. Installing the backend alone does not install the host plugin manif

**CellTypePilot** is a **plugin** for Claude Code / OpenAI Codex. It turns pre-clustered
single-cell data into auditable draft cell-type annotations — with a governed context interface,
**dual-engine** identity scoring (marker overlap + reference embedding), an independent cell-state
lens, conservative critic review, and a draft methodology paragraph for your paper.
a **backend-neutral hierarchical selective decision layer**, an independent cell-state lens,
conservative critic review, and a draft methodology paragraph for your paper. CellTypist, popV,
SingleR, scANVI, custom references, and optional LLM hypotheses are candidate generators; the
in-house marker scorer compiles evidence and may downgrade a call, but is not the primary classifier.

It is **not an autonomous analysis agent**. It is a deterministic, artifact-producing plugin
that adds evidence review, conservative abstention, benchmark hooks, and provenance to the
coding workspace you already use. A qualified human owns the final biological decision.

## Current validation boundary

| Available in v0.3.1 | Not yet claimed |
| Available in v0.4.0 | Not yet claimed |
|---|---|
| Direction-, log2FC-, FDR-, and expression-fraction-gated DE evidence | Biological superiority over CellTypist, SingleR, Azimuth, or popV |
| Complete expected-marker denominators, with missing genes separated from present-but-silent genes | A completed public multi-study/donor benchmark |
Expand All @@ -31,6 +33,8 @@ coding workspace you already use. A qualified human owns the final biological de
| Locked study/donor holdout runner and comparator adapters | Clinical-grade or fully automated biological decisions |
| Governed Context Pack: structured custom markers share the normal evidence gates; free text is provenance-only | That free-text biological context is validated evidence |
| Separate identity and state outputs; state scoring cannot overwrite identity or rescue an abstained identity | Calibrated cell-state accuracy or comprehensive state coverage |
| Backend-neutral candidate contract, ontology-aware parent fallback, and explicit candidate sets | That backend agreement is a calibrated probability or selective-risk guarantee |
| Three depth-validation domains: lung, gut/IBD, and tumor microenvironment, all currently fail-closed as `evidence_required` | Claim readiness before locked multi-study evidence, separate calibration, and expert adjudication are complete |

For `mkg-2026.08.1`, 280 of 599 bundled marker relationships have been upgraded to
`literature_cooccurrence_supported` via an auditable PubMed co-occurrence sweep
Expand All @@ -41,6 +45,30 @@ co-occurrence support; `edge_verified` and `primary` policies exclude literature
edges. The sweep report and curation queue are published in
[`docs/curate/`](docs/curate/) and [`docs/atlas_curation_queue.csv`](docs/atlas_curation_queue.csv).

### Core decision architecture

The runtime now separates candidate generation from evidence review. Candidate CSV/JSON artifacts
from `celltypist`, `popv`, `singler`, `scanvi`, or `custom_reference` enter
`celltypepilot.backend-candidates.v1`. An optional `llm` backend is hypothesis-only by default.
Marker rankings enter the same audit table with `decision_role=evidence_only` and never count as
an independent vote.

The default `celltypepilot.hierarchical-selective-decision.v1` policy requires two independent
backend families for a leaf call. Sibling disagreement may collapse only to a governed Atlas
ancestor within two hops; cross-lineage or unresolved disagreement writes a candidate set and
`Unknown`. Backend scores are retained with their native semantics and are never arithmetically
blended or described as calibrated probabilities. The marker critic runs after selection and can
only downgrade the result.

Product validation is concentrated on exactly three depth domains: **lung**, **gut/IBD**, and
**tumor microenvironment**. `validation_domains.json` records multi-study, platform-transport,
calibration, hierarchy-error, abstention-audit, and expert-adjudication gates. All three currently
remain `evidence_required`; the broader bundled Atlas remains available only as exploratory scope.
See [`docs/hierarchical_selective_decision.md`](docs/hierarchical_selective_decision.md) for the
candidate schema, independence groups, cell-to-cluster aggregation, and claim boundaries.
See [`docs/native_backend_execution.md`](docs/native_backend_execution.md) for native runner
configuration, checkpoint semantics, LLM boundaries, and the three-domain evidence workflow.

Cell Ontology identifiers are validated against the live Cell Ontology
(`celltypepilot ontology update` then `celltypepilot ontology check`). Unknown or
obsolete CL identifiers are flagged as errors; lexical label mismatches are warnings
Expand Down Expand Up @@ -80,7 +108,7 @@ output/
├── transitional_states.csv # Clusters flagged as differentiation intermediates
├── disagreements.csv # Marker vs reference disagreement analysis
├── report_draft.html # Self-contained HTML report with all figures embedded
├── methodology_draft.txt # "We annotated N clusters using CellTypePilot v0.3.1..."
├── methodology_draft.txt # "We annotated N clusters using CellTypePilot v0.4.0..."
├── manifest.json # Provenance: versions, params, data hash, output hashes
└── figures/
├── umap_cluster.png # UMAP by cluster (colorblind-friendly Wong palette)
Expand Down Expand Up @@ -113,6 +141,17 @@ celltypepilot annotate --input data.h5ad --cluster-key leiden --species human --
celltypepilot annotate --input data.h5ad --cluster-key leiden \
--reference atlas.h5ad --tissue blood

# 5b. Import independently produced backend candidates. Each artifact declares
# cluster, backend, cell_type (preferably cl_id), optional score, semantics, and rank.
celltypepilot annotate --input data.h5ad --cluster-key leiden --tissue blood \
--candidate-table celltypist.csv --candidate-table popv.csv \
--candidate-table singler.csv

# 5c. Execute governed native backends inside ordinary annotate. Failed runtimes
# remain explicit and contribute no vote; optional LLM output is hypothesis-only.
celltypepilot annotate --input data.h5ad --cluster-key leiden --tissue lung \
--native-backends native_backends.json

# 6. Check available reference scoring backends
celltypepilot backends

Expand All @@ -135,13 +174,35 @@ celltypepilot convert-rds --input data.rds --output data.h5ad
celltypepilot benchmark -i benchmark.h5ad --truth-key truth \
--study-key study --donor-key donor --output benchmark/

# 12. Actually execute CellTypePilot/CellTypist on every isolated fold.
# SingleR/Azimuth/popV use explicit JSON argv adapters under the same protocol.
# 12. Execute the hierarchical product and native comparators on isolated folds.
celltypepilot benchmark-run -i benchmark.h5ad --truth-key truth \
--study-key study --donor-key donor --cluster-key leiden \
--species human --tissue blood --methods celltypepilot,celltypist
--species human --tissue blood \
--methods celltypepilot,celltypist,popv,singler,scanvi,custom_reference

# 12a. Lock and execute the three depth-domain evidence workflow.
celltypepilot domain-validation-plan --registry benchmarks/public_v1/registry.json \
--output benchmarks/domain_depth_v1
celltypepilot domain-validation-run \
--plan benchmarks/domain_depth_v1/domain_validation_plan.json --domain lung

# 12b. Lock donor-disjoint calibration/evaluation roles before outcome scoring,
# then audit that fold-isolated candidates address multiple lineages without reading truth.
celltypepilot calibration-split --registry benchmarks/public_v1/registry.json \
--output benchmarks/calibration_v1
celltypepilot lineage-coverage-audit \
--predictions benchmarks/public_v1/runs/travaglini_lung_smartseq2_2020/out_of_fold_predictions.csv \
--cluster-map benchmarks/public_v1/runs/travaglini_lung_smartseq2_2020/cluster_map.csv \
--domain lung --output benchmarks/acceptance/lung_lineage_coverage_v1
celltypepilot calibrate-locked-donors \
--registry benchmarks/public_v1/registry.json \
--assignments benchmarks/calibration_v1/donor_role_assignments.csv \
--cohort travaglini_lung_smartseq2_2020 \
--predictions benchmarks/acceptance/lung_lineage_coverage_v1/selector_cell_predictions.csv \
--label-map benchmarks/public_v1/label_maps/travaglini_lung_smartseq2_2020.csv \
--output benchmarks/calibration_v1/travaglini_lung_smartseq2_selector_policy.json

# 12b. Assemble a public multi-cohort release. Inference is donor-level;
# 12c. Assemble a public multi-cohort release. Inference is donor-level;
# missing data, comparators, label maps, and diagnostics block claim-ready status.
celltypepilot benchmark-release \
--registry benchmarks/public_v1/registry.json \
Expand All @@ -153,6 +214,9 @@ celltypepilot calibrate -i calibration.h5ad --truth-key truth \
celltypepilot annotate -i query.h5ad -k leiden -t blood \
--calibration-policy abstention_policy.json

# 13b. Verify the immutable software-governance freeze shipped with the release.
celltypepilot governance-freeze-verify

# 14. Add disease context without turning prose into evidence. Structured markers
# are accepted only through a versioned JSON Context Pack and/or marker CSV.
celltypepilot annotate -i kidney_iri.h5ad -k leiden -s human -t kidney \
Expand Down Expand Up @@ -321,9 +385,9 @@ reference, evidence, and provenance gates apply as the CLI.
```
CellTypePilot/
├── .claude-plugin/
│ └── plugin.json ← Claude Code plugin manifest (v0.3.1)
│ └── plugin.json ← Claude Code plugin manifest (v0.4.0)
├── .codex-plugin/
│ └── plugin.json ← Codex plugin manifest (v0.3.1, with interface block)
│ └── plugin.json ← Codex plugin manifest (v0.4.0, with interface block)
├── skills/
│ └── celltypepilot/
│ ├── SKILL.md ← Shared skill instructions (4-stage workflow)
Expand Down Expand Up @@ -401,11 +465,13 @@ identity is not. It never permits a state to rescue or overwrite an abstained id
state modules currently have aggregate source-level provenance and are exploratory, not a claim
of calibrated state accuracy. See [`docs/state_lens.md`](docs/state_lens.md).

## Reference Embedding + Ensemble Fusion
## Backend-neutral candidate generation and hierarchical selection

For continuous differentiation trajectories (stem → progenitor → mature) and rare
transitional states, pure marker overlap scoring can fail. CellTypePilot addresses this
with a **dual-engine** architecture:
with a backend-neutral candidate contract and a separate selective decision layer. Marker scoring
is evidence-only; the legacy ensemble described below is retained only as a diagnostic artifact
and never drives final identity:

**Engine 1 — Marker Scorer** (deterministic):
Wilcoxon DE against the built-in marker knowledge graph. A supporting positive marker
Expand All @@ -423,7 +489,8 @@ Projects query cells into a reference embedding space and transfers labels. Four
| **KNN** | PCA + inverse-distance KNN label transfer | Quick mapping, no model needed | `sklearn` (always available) |
| **Correlation** | Pearson correlation with reference mean profiles | Lightweight fallback | None (always available) |

**Ensemble Fusion** — Adaptive weighting combines both engines:
**Legacy diagnostic ensemble** — these historical weights may be emitted for comparison, but
the hierarchical selector never uses the blended score:

| Marker confidence | Marker weight | Reference weight | Rationale |
|---|---|---|---|
Expand Down
Loading