Skip to content

ogar-obo: producer flip — MONDO/HP/UBERON under the domain reference tree (S3) - #293

Merged
AdaWorldAPI merged 1 commit into
mainfrom
claude/medcare-rs-continue-6nhbxn
Aug 31, 2026
Merged

ogar-obo: producer flip — MONDO/HP/UBERON under the domain reference tree (S3)#293
AdaWorldAPI merged 1 commit into
mainfrom
claude/medcare-rs-continue-6nhbxn

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Aug 31, 2026

Copy link
Copy Markdown
Owner

What

The producer-side S3 step of the staged domain-classid migration, for the OBO five:

  • Namespace::concept_id now renders Mondo 0x9101 (disease compartment), Hpo 0x9202 (phenotype), Uberon 0x9303 (anatomy). Pato 0x0304 / Ro 0x0305 stay in the legacy page — neither has a domain_classids.tsv row (quality axis / predicate namespace), so there is nothing to flip them to.
  • from_concept_id accepts both forms (0x9101 | 0x0301 => Mondo, …), so every reader keeps resolving legacy artifacts unchanged. The alias stays a computation, per the staging doctrine.

Wire contract preserved

The enum order is a wire contract (ns as u8 = the value[96] category byte 0..4, TermId.ns ordinal) and is untouched. The old "concept ids ascend with ordinal" property retired with the 0x03 block; its sweep test is re-pinned to set-equality over all 8 accepted ids plus explicit per-variant ordinal assertions. Registry NsSpec ids, the spine-collision guard, and the domain-membership guard are re-pinned to the two-domain reality (hi == 0x03 || 0x90..=0x9D); test literals now derive addresses via target_classid / render_classid instead of pinning raw numbers.

The artifact carries over without a re-bake

examples/rekey_domain.rs transforms an existing obo-core .soa in place of a re-bake: it rewrites exactly the key classid (bytes 0..4) and the 23 edge-lane header classids per 512-byte row, preserves row order (the label slab is positional), and verifies on its own output that no byte outside those positions changed.

Measured on the real 60,478-row artifact:

rekey_domain: 60478 rows, order preserved
  keys moved 58587 / kept (PATO/RO) 1891
  lane headers moved 89118 / kept 9453
  0x03010000 23776 -> 0x91010000 23776
  0x03020000 19836 -> 0x92020000 19836
  0x03030000 14975 -> 0x93030000 14975
  0x03040000  1887    (kept)
  0x03050000     4    (kept)
foreign_diffs = 0

Gates

  • cargo test -p ogar-obo: 48/48; workspace suites green
  • cargo clippy -p ogar-obo --all-targets: clean
  • cargo fmt: clean

Consumer-side (MedCare) follow-up: upload the re-keyed artifact under a new tag, flip crosswalk/rails/census constants, symmetric fold in obo_store — separate PR in the private repo.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PFnYKqw6d7TTiB9cT8eFdK


Generated by Claude Code

Summary by CodeRabbit

  • New Features
    • Added a domain rekeying example that updates eligible class IDs in OBO artifacts while preserving other data.
  • Improvements
    • Updated MONDO, HPO, and Uberon identifiers to use dedicated domain address ranges.
    • Continued support for reading legacy MONDO, HPO, and Uberon identifiers.
    • Improved validation and reporting for class ID remapping.
  • Tests
    • Updated coverage to verify migrated identifiers, aliases, collision handling, and domain constraints.

…ence tree (S3)

Namespace::concept_id now renders the OBO three under their domain
compartments — Mondo 0x9101 (disease), Hpo 0x9202 (phenotype), Uberon
0x9303 (anatomy) — per the staged migration's S3 step; Pato 0x0304 and
Ro 0x0305 stay in the legacy page (no domain_classids.tsv row: quality
axis / predicate namespace). from_concept_id accepts BOTH forms, so
every reader resolves legacy artifacts unchanged.

The enum ORDER is a wire contract (ns as u8 = the value[96] category
byte, TermId.ns ordinal) and is untouched; the ascending-concept-id
sweep property retired with the 0x03 block and its test is re-pinned to
set-equality + explicit ordinal assertions. Registry NsSpec ids,
spine-collision and domain-membership guards re-pinned to the
two-domain reality; test literals now derive addresses via
target_classid/render_classid instead of pinning raw numbers.

examples/rekey_domain.rs carries an existing obo-core .soa across
WITHOUT a re-bake: rewrites exactly the key classid (bytes 0..4) and
the 23 edge-lane header classids per row, preserves row order (the
label slab is positional), and verifies on its own output that no byte
outside those positions changed. Measured on the real artifact:
60,478 rows, 58,587 keys moved / 1,891 kept, census exact,
foreign_diffs 0.
@cursor

cursor Bot commented Aug 31, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_15bb3bf1-5bb0-4236-a389-6de8f66ff332)

@AdaWorldAPI
AdaWorldAPI merged commit fbce8d5 into main Aug 31, 2026
2 of 3 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e4f7d8169a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +208 to 212
Namespace::Mondo => 0x9101,
Namespace::Hpo => 0x9202,
Namespace::Uberon => 0x9303,
Namespace::Pato => 0x0304,
Namespace::Ro => 0x0305,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restore classid-sorted row generation

These assignments no longer sort in the enum/registry order used by bake_with: a full bake emits 0x9101, 0x9202, 0x9303, then 0x0304, 0x0305. The re-key tool explicitly preserves that same row order, but SpineLens::resolve binary-searches rows by (classid, num) and documents ascending classids as a precondition. Thus any full artifact containing Uberon followed by PATO/RO fails is_sorted() and can silently miss rows during ancestry or filler lookup; generation/re-keying must restore the lookup order (while moving positional labels consistently), or the resolver's ordering contract must change.

Useful? React with 👍 / 👎.

Comment on lines +208 to +210
Namespace::Mondo => 0x9101,
Namespace::Hpo => 0x9202,
Namespace::Uberon => 0x9303,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep exported crosswalk classids in sync

After these canonical IDs change, crosswalk::Crosswalk::from_bake returns 0x9101_0000 for MONDO and 0x9303_0000 for Uberon, while the public DISEASE_CLASSID and ANATOMY_CLASSID constants remain 0x0301_0000 and 0x0303_0000. Consumers following those constants' documented purpose—confirming the type of a resolved address—will now reject every newly baked crosswalk result, so the constants should derive from the new canonical namespace IDs.

Useful? React with 👍 / 👎.

Comment on lines +238 to +240
0x9101 | 0x0301 => Namespace::Mondo,
0x9202 | 0x0302 => Namespace::Hpo,
0x9303 | 0x0303 => Namespace::Uberon,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Recognize legacy aliases in row_schema_of

Although these aliases make pre-migration classids readable through Namespace::from_concept_id, layout::row_schema_of still recognizes concepts only by equality against the now-migrated registry::OBO_CORE entries. Consequently row_schema_of(0x0301), 0x0302, and 0x0303 returns None, so schema-driven readers reject the legacy artifacts that this migration explicitly promises remain readable; that lookup must normalize through these aliases or include their legacy IDs.

Useful? React with 👍 / 👎.

@coderabbitai

coderabbitai Bot commented Aug 31, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 80088b8b-9e3f-47cd-9aca-450adf150104

📥 Commits

Reviewing files that changed from the base of the PR and between ab1e4cd and e4f7d81.

📒 Files selected for processing (5)
  • crates/ogar-obo/examples/rekey_domain.rs
  • crates/ogar-obo/src/edges.rs
  • crates/ogar-obo/src/lib.rs
  • crates/ogar-obo/src/registry.rs
  • crates/ogar-obo/src/spine.rs

📝 Walkthrough

Walkthrough

The change migrates MONDO, HPO, and Uberon to domain-form IDs while retaining legacy aliases. It adds a .soa artifact re-keying example and updates tests to derive classids from Namespace.

Changes

OBO domain re-keying

Layer / File(s) Summary
Namespace mapping and aliases
crates/ogar-obo/src/lib.rs
MONDO, HPO, and Uberon now use 0x91xx0x93xx IDs for writing. Legacy IDs remain readable as aliases. Tests cover mixed addresses and preserved enum ordinals.
Registry domain validation
crates/ogar-obo/src/registry.rs
OBO_CORE uses migrated concept IDs. Registry validation accepts the legacy 0x03 page and migrated 0x90..=0x9D domain-reference tree.
Artifact re-keying and compatibility tests
crates/ogar-obo/examples/rekey_domain.rs, crates/ogar-obo/src/edges.rs, crates/ogar-obo/src/spine.rs
The new example rewrites eligible row and edge-lane classids, validates permitted byte changes, and reports statistics. Edge and spine tests derive expected classids from namespace mappings.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant SOAArtifact
  participant Namespace
  participant Validator
  CLI->>SOAArtifact: read input `.soa`
  SOAArtifact->>Namespace: resolve eligible classids
  Namespace-->>SOAArtifact: return mapped classids
  SOAArtifact->>Validator: verify keys and permitted byte changes
  Validator-->>CLI: return statistics and censuses
  CLI->>SOAArtifact: write output `.soa`
Loading

Poem

A rabbit maps the domains with care
New classids hop through data there
Old aliases remain in view
Rows keep their order, bytes stay true
The OBO lanes now burrow through

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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

AdaWorldAPI pushed a commit that referenced this pull request Aug 31, 2026
…space

The S3 producer flip (#293) set the reader rule at from_concept_id —
both 0x0301 and 0x9101 resolve Mondo — but row_schema_of still probed
the registry with the RAW concept id, so a pre-flip artifact's legacy
ids stopped resolving the carve the moment the registry minted the
domain forms. Fold through the namespace alias before the registry
probe; concepts without an alias (PATO/RO, spine, foreign) probe as
themselves, and 0x0306 / non-OBO ids stay refused.
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