Skip to content

feat!: remove the no_map node mode so subjects and objects always resolve - #221

Merged
SkyeAv merged 2 commits into
mainfrom
no-map-overhaul
Oct 16, 2026
Merged

SkyeAv merged 2 commits into
mainfrom
no-map-overhaul

Conversation

@SkyeAv

@SkyeAv SkyeAv commented Oct 15, 2026 •

Copy link
Copy Markdown
Owner

Removes no_map, the mode that let a statement subject or object skip fullmap entity resolution and emit its own CURIE verbatim. It broke emitted output: with no lookup there is no role to derive, so every verbatim node was pinned to biolink:NamedThing and each edge derived from it flattened to biolink:Association. The resolution path goes back to how it worked in 20.0.0, and configs that still set the key now fail with a message that says why.

Removal

  • Config surface: NodeEncoding.no_map is gone from src/tablassert/models.py, along with the no_map_rejects_explicit_taxon, no_map_rejects_resolution_knobs, and no_map_literal_must_be_curie validators and the CURIE_PATTERN/is_curie helpers that only served them.
  • Build path: lib.curie_audit and the verbatim branch of Tcode._node_ops are deleted, so subject and object go back through the shared resolve_batch (src/tablassert/lib.py:1417). The op's matching PHASE_OF and runcache.OP_COST entries go with it, which tests/test_run_cache.py:352 requires.
  • Error codes: no-map-dead-config, no-map-bad-curie, and no-map-curie-violation are dropped from TablassertErrorCodes in src/tablassert/errors.py.
  • Qualifiers: Qualifier.resolved is vocabulary is None again, so CURIE-ranged qualifiers always resolve while enum-ranged qualifiers still pass their vocabulary tokens through verbatim. The mode rode this one shared field, so its qualifier half is removed with it.

Migration notice

  • DEPRECATED_KEYS: no_map is registered in src/tablassert/models.py so the before-hook names the removal and the migration before extra="forbid" rejects the key. Warn, then fail: popping the key instead would build the broken output the removal exists to prevent.
  • Tables that already carry CURIEs: nothing else to edit, because the fullmap indexes CURIEs and their equivalent identifiers as terms, so a CURIE cell resolves back to its own CURIE (docs/cli.md:118, docs/api/fullmap.md:245). Resolution rules still apply: taxon, prioritize/avoid, exclude_prefixes/exclude_regex, and a blank cell still drops the row.

Docs

  • docs/configuration/table.md loses the no_map row and the No-map mode section. tests/test_docs_source_of_truth.py::test_config_model_fields_match_live_models binds docs rows to live model fields in both directions, which is why code and docs land in one commit rather than two layers.
  • CHANGELOG.md is untouched: the release commit writes it, so 21.0.0's record stays as shipped and the breaking note belongs in the next release entry. Its 21.0.0 entry still names no_map and curie_audit, which is shipped history, not a missed edit.

Testing

  • uv run pytest -q --no-cov -> 1218 passed, 1 skipped (the skip is the opt-in corpus sweep at tests/test_realworld_configs.py:236, which needs TABLASSERT_CONFIG_CORPUS)
  • uv run ruff check . -> All checks passed!; uv run ruff format --check . -> 70 files already formatted
  • uv run pyright -> 0 errors, 0 warnings, 0 informations
  • cargo test --manifest-path rust/Cargo.toml -> 127 passed, 11 passed; 1 ignored, 17 passed, 1 passed; cargo clippy --all-targets -- -D warnings -> exit 0
  • uv run mkdocs build --strict -> exit 0
  • uv run tablassert validate <config with no_map: true> --schema table -> prints the removal note, then statement.subject.no_map: Extra inputs are not permitted [extra_forbidden], exit 1; the same run with no_map: false fails identically, since the hook keys on presence
  • Equivalence check: Tcode._node_ops, PHASE_OF, class NodeEncoding..class Qualifier, and Qualifier.resolved are byte-identical to git show 32f4478~1:src/tablassert/{lib,models}.py, so the restored path is the 20.0.0 path.

Risks

  • Breaking: any table config that still sets no_map stops validating, at either value: the hook warns on key presence and extra="forbid" rejects the key regardless of what it is set to, so a no_map: false config breaks too. A graph built with the mode under 21.0.0 emits different node categories and edge types once rebuilt. Deferred: no replacement "verbatim identifier" surface; the supported path is fullmap resolution.

Questions for the reviewer

  • Qualifier scope. no_map was a single field shared by subject, object, and qualifier, and the verbatim branch is the same code for all three, so this also drops the CURIE-ranged qualifier opt-out. If that knob has a real use case, it wants its own field and its own finalize op rather than the biolink:NamedThing category synthesis it inherited.

…olve

`no_map: true` on a statement subject or object (#219, released in 21.0.0)
skipped fullmap entity resolution and emitted the cell value as the node id
verbatim. It breaks the output: with no lookup there is no role to derive, so
the build pinned every verbatim node's category to `biolink:NamedThing` and
each edge derived from it degraded to `biolink:Association`, losing the typed
predicate categories KGX consumers expect. The mode is removed rather than
patched, restoring the 20.0.0 resolution path.

- `NodeEncoding.no_map` is gone, along with the `no-map-dead-config` and
  `no-map-bad-curie` config validators, the `no-map-curie-violation` code, and
  the `CURIE_PATTERN`/`is_curie` helpers that only served them.
- `lib.curie_audit` and its `Tcode._node_ops` verbatim branch are gone, so
  subject and object columns go back through the shared `resolve_batch`, plus
  the matching `PHASE_OF` and `runcache.OP_COST` entries.
- CURIE-ranged qualifiers always resolve again: `Qualifier.resolved` is
  `vocabulary is None`, so enum-ranged qualifiers still pass their vocabulary
  tokens through verbatim and nothing else does.
- The `no_map` row and the "No-map mode" section are removed from
  `docs/configuration/table.md`, and the tests written for the mode are gone.

Migration: drop `no_map: true` from subject and object encodings. Terms resolve
as they did before 21.0.0; tables that already carry CURIEs also resolve, since
the fullmap indexes CURIEs and their equivalent identifiers as terms.
With `no_map` deleted from `NodeEncoding`, a table config written against
21.0.0 failed with pydantic's bare "Extra inputs are not permitted", which
names no history and offers no migration step for an unattended pipeline run.
`models.DEPRECATED_KEYS` is the repo's scaffold for exactly this: the
before-hook warns, and `extra="forbid"` still rejects the key, so the config
never builds the output the removal exists to prevent.

- `no_map` is registered with a note that says the mode is gone, why (verbatim
  nodes pinned to `biolink:NamedThing` flattened edge typing), and what old
  configs should expect now: a CURIE cell resolves back to its own CURIE because
  the fullmap indexes CURIEs as terms, with the usual `taxon`,
  `prioritize`/`avoid`, and `exclude_*` rules still applying.
- The key is rejected on presence, not truthiness, so `tests/test_models.py`
  pins the warn-then-reject path for both `no_map: false` and `no_map: true`.
- The two existing deprecation tests' "registry is EMPTY" wording is corrected,
  since the registry now names one removed key.
@coderabbitai

coderabbitai Bot commented Oct 15, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 87b00831-cb74-4d50-ac4c-3576d1b9d695
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@SkyeAv SkyeAv changed the title no map overhaul feat!: remove the no_map node mode so subjects and objects always resolve Oct 15, 2026
@SkyeAv
SkyeAv merged commit 17ceaea into main Oct 16, 2026
5 checks passed
SkyeAv added a commit that referenced this pull request Oct 16, 2026
SkyeAv added a commit that referenced this pull request Oct 16, 2026
Cut 22.0.0 and bump the package version in pyproject.toml, CITATION.cff,
and uv.lock.

Major: the no_map node mode added in 21.0.0 is removed because verbatim
nodes cannot derive a role and collapsed to biolink:NamedThing with
flattened biolink:Association edges; configs setting the key are told
why, then rejected (#221). The user-facing docs are corrected against
the live sources, the changelog is normalized to plain ASCII, and
tests/test_docs_style.py now gates typography regressions (#222).

Changelog:
- Versioned the 22.0.0 section from the two merged PRs (no Unreleased
  section existed), added PR links to both entries, and added the
  migration note for the no_map removal.

Docs: none needed here; the docs pages themselves were aligned in #222
and the new style gate covers the CHANGELOG edit in the test suite.

Testing:
- make check -> exit 0: ruff check "All checks passed!", ruff format
  "71 files already formatted", pyright "0 errors, 0 warnings,
  0 informations", pytest "1222 passed, 1 skipped in 23.81s", cargo
  test 127 + 11 (1 ignored) + 17 + 1 passed, clippy -D warnings clean
- uv run mkdocs build --strict -> exit 0
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