Skip to content

PR 3: Source-adapter interface + deterministic CELLxGENE adapter - #5

Merged
mengerj merged 1 commit into
mainfrom
pr3-source-adapter-interface
Jun 24, 2026
Merged

PR 3: Source-adapter interface + deterministic CELLxGENE adapter#5
mengerj merged 1 commit into
mainfrom
pr3-source-adapter-interface

Conversation

@mengerj

@mengerj mengerj commented Jun 24, 2026

Copy link
Copy Markdown
Owner

Scope (roadmap PR 3)

Introduce the SourceAdapter / Normalizer contracts, refactor CELLxGENE into a
fully deterministic adapter + normalizer, and remove the LLM/Azure narrative
path entirely. One roadmap item; no work pulled forward.

New contracts

  • models/raw_record.pyRawRecord, the source-shaped boundary object between
    adapters and normalizers (source, study_id, title, free-form payload).
  • sources/base.pySourceAdapter Protocol (discover(query) -> [ref],
    fetch(ref) -> RawRecord).
  • normalize/base.pyNormalizer Protocol (normalize(record) -> KnowledgeGraphOutput).

CELLxGENE migrated (no LLM in its path)

  • tools/cellxgene_fetcher.pysources/cellxgene.py (CellxgeneAdapter).
    Cell-type extraction dropped — the cell_type* Census columns and the
    cell_types summary key are gone (data-inferred → leakage).
  • tools/ncbi_fetcher.pysources/publication.py (EuropePMC title helper).
  • graph/builder.pynormalize/cellxgene.py (CellxgeneNormalizer); reads
    record.source/title/payload instead of a hardcoded source. The
    organism→NCBITaxon map moves here (normalization; PR 4 resolver replaces it).
  • Vestigial @tool wrappers and the whole tools/ package (incl. the GEO stub)
    removed.

Narrative/LLM path removed

  • Deleted agent/curator.py, agent/prompts.py, models/narrative.py, the
    NarrativeOutput schema, and main.py's step-2 block. main.py is now a
    deterministic, synchronous discover → fetch → normalize → write pipeline.

Decisions

  • Per-study assembly is the Normalizer's job; graph/ is reserved for the PR 6
    cross-source merger (matches ARCHITECTURE §3). graph/+agent/ kept as
    documented placeholder packages.
  • discover is the identity on a DOI for CELLxGENE (a collection = a DOI);
    keyword search is backlog.
  • The Azure-coupled retry helpers were removed with their only caller (the LLM
    call). Follow-up: source-fetch resilience (Census/EuropePMC) should be
    re-added — noted in the Session Log.

mypy

  • Removed the parce.tools.* exemption (modules migrated, now fully type-checked).
    parce.agent.* exemption stays for PR 5.

Verification

All four CI gates pass locally, including a hermetic run with .env moved aside:

Gate Result
ruff check . ✅ All checks passed
ruff format --check . ✅ 24 files formatted
mypy src/parce ✅ 16 files, no issues
pytest -m "not integration" ✅ 47 passed

No dependency changes (agent-framework/azure-* retained for PR 5).

▶ Next up after this: PR 4 — Ontology resolver.

🤖 Generated with Claude Code

Introduce the SourceAdapter / Normalizer contracts and refactor CELLxGENE
into a fully deterministic adapter + normalizer, then rip out the LLM/Azure
narrative path entirely.

New contracts
- models/raw_record.py: RawRecord, the source-shaped boundary object between
  adapters and normalizers (source, study_id, title, free-form payload).
- sources/base.py: SourceAdapter Protocol (discover -> [ref], fetch -> RawRecord).
- normalize/base.py: Normalizer Protocol (normalize -> KnowledgeGraphOutput).

CELLxGENE migrated (no LLM in its path)
- tools/cellxgene_fetcher.py -> sources/cellxgene.py (CellxgeneAdapter). Cell-type
  extraction dropped: the cell_type* Census columns and cell_types summary key
  are gone (data-inferred -> leakage).
- tools/ncbi_fetcher.py -> sources/publication.py (EuropePMC title helper).
- graph/builder.py -> normalize/cellxgene.py (CellxgeneNormalizer); reads
  record.source/title/payload instead of a hardcoded source. The organism->
  NCBITaxon map moves here (normalization, future PR 4 resolver).
- Vestigial @tool wrappers and the whole tools/ package (incl. GEO stub) removed.

Narrative/LLM path removed
- Deleted agent/curator.py, agent/prompts.py, models/narrative.py, the
  NarrativeOutput schema, and main.py's step-2 block. main.py is now a
  deterministic, synchronous discover -> fetch -> normalize -> write pipeline.

Tooling/tests
- Removed the parce.tools.* mypy exemption (modules migrated, now type-checked);
  parce.agent.* exemption stays for PR 5.
- Tests: test_builder -> test_normalize, new test_sources (adapter + RawRecord +
  protocol conformance), rewritten test_orchestration, narrative tests removed.

Gates green locally (incl. hermetic run with .env moved aside): ruff check,
ruff format --check, mypy (16 files), 47 unit tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mengerj
mengerj marked this pull request as ready for review June 24, 2026 06:52
@mengerj
mengerj merged commit 772eb23 into main Jun 24, 2026
2 checks passed
@mengerj
mengerj deleted the pr3-source-adapter-interface branch June 24, 2026 06:53
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.

1 participant