Skip to content

obo/ro: SoA lens reasoning surface, per-class LE row contract, one predicate home - #267

Merged
AdaWorldAPI merged 1 commit into
mainfrom
claude/medcare-rs-continue-ufsazd
Aug 13, 2026
Merged

AdaWorldAPI merged 1 commit into
mainfrom
claude/medcare-rs-continue-ufsazd

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

Follow-through on the 2026-08-13 crosswalk audit, under the operator rulings: no maps on the reasoning read path; a join is cross-domain only; inner-domain is the live SoA substrate; a missing edge family gets a sidecar SoA under the same contract, never a hand-rolled container.

1. reason::EdgeSource — the walk becomes a lens, sources are SoA-only

ancestors / related_via_ancestry / anatomy_of / phenotypes_of are now generic over an EdgeSource. The only shipped sources:

  • SpineSource — SpineLens lifted into TermId space via the derived inverses (Namespace::from_concept_id, render_classid); edge lanes decoded in place, nothing rebuilt.
  • Stacked — SoA lens stacking: several borrowed slabs read as one (spine slab + sidecar slab). Proven by a test where neither slab alone can answer (ancestry in slab 1, cross-angle relation in slab 2) and the stack can.

The pre-bake parse map does not implement the trait — bake input, structurally excluded from the read path. New SpineLens::rel_at visits all typed relations in one lane sweep. The per-term walk test now runs over baked lanes end-to-end.

2. layout::ClassRowSchema — the per-class little-endian row contract

The value-slab carve (EntityType @96, edge lanes @112..480) was two bare literals, hand-mirrored downstream, both diverging from the generic default tenant carve. Now the carve is declared once per concept — the classid picks the reading — and ENTITY_TYPE_SLAB_OFFSET / EDGE_LANE_SLAB_OFFSET / EDGE_LANE_COUNT are derived from the schema. row_schema_of refuses foreign concepts (incl. 0x0306, call-slab shaped), and a pinning test fails if an independent literal reappears. Registry-side ClassView/ValueSchema registration is the named paired follow-up at the contract's home. No bytes moved — declaration only; the artifacts stay valid.

3. One home per reading

  • Predicate::{ordinal, from_ordinal} and Namespace::from_concept_id (ogar-obo) — the byte↔predicate and classid↔namespace tables, previously re-derived by hand in two downstream repos.
  • ogar_ro::by_index — position lookup over the contiguous 0x90..0xA5 band (contiguity pinned by a test that can fail), replacing the name-keyed scan that invited byte→string→byte round-trips; for_obo_predicate crosses the OBO/RO seam once, refusing HasAnatomy/Other honestly.

Tests: 61 passing across ogar-obo + ogar-ro (incl. the new bake-lane walk, stacking, contiguity, and schema-pin tests); fmt + clippy clean.

Downstream (staged next, after this merges): the consumer replaces its boot-time HashMap graph rebuild with a stacked lens over its resident slabs and pins its rail mirror against ClassRowSchema in a bridge test.


Generated by Claude Code

…predicate home

Three coupled moves, all from the 2026-08-13 crosswalk audit and the operator
rulings that followed it (no maps on the read path; a join is cross-domain
only; inner-domain is the live SoA substrate; a missing edge family means a
sidecar SoA under the same contract, never a hand-rolled container):

1. reason::EdgeSource — the per-term walk (ancestors / related_via_ancestry /
   anatomy_of / phenotypes_of) is now generic over WHERE asserted edges come
   from, and the only shipped sources are SoA lenses: SpineSource (SpineLens
   lifted into TermId space via the derived classid<->namespace inverses) and
   Stacked (SoA lens stacking — several borrowed slabs read as one, the
   spine + sidecar deployment shape). The pre-bake parse map does NOT
   implement the trait: it is bake input, structurally excluded from the
   reasoning read path rather than discouraged. New SpineLens::rel_at visits
   all typed relations in one lane sweep. Tests: the per-term walk now runs
   over BAKED LANES (parse feeds bake, walk reads rows), plus a stacking
   proof where neither slab alone can answer (ancestry in slab 1, relation
   in slab 2) and the stack can.

2. layout::ClassRowSchema — the per-class little-endian row contract. The
   value-slab carve (EntityType @96, edge lanes @112..480) was two bare
   literals that a downstream consumer hand-mirrored while both diverged
   from the generic default tenant carve. Now the carve is DECLARED once
   per concept (the classid picks the reading), ENTITY_TYPE_SLAB_OFFSET /
   EDGE_LANE_SLAB_OFFSET / EDGE_LANE_COUNT are derived from the schema,
   row_schema_of refuses foreign concepts (incl. 0x0306, whose row is
   call-slab shaped), and a pinning test fails if an independent literal
   reappears. Registry-side ClassView/ValueSchema registration is the named
   paired follow-up at the contract's home.

3. Predicate::{ordinal, from_ordinal} + Namespace::from_concept_id (ogar-obo)
   and by_index + for_obo_predicate (ogar-ro) — the byte<->predicate and
   classid<->namespace readings each get ONE home. ogar-ro's lookup is a
   position computation over the contiguous 0x90..0xA5 band (pinned by a
   contiguity test that can fail), replacing name-keyed scans that invited
   byte->string->byte round-trips downstream; HasAnatomy/Other honestly
   return None rather than a lookalike row.
@cursor

cursor Bot commented Aug 13, 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_59326362-6b23-40c9-af0b-5127a929fb7b)

@AdaWorldAPI
AdaWorldAPI merged commit 26294f1 into main Aug 13, 2026
2 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: 087b07158f

ℹ️ 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".


impl EdgeSource for SpineSource<'_> {
fn is_a(&self, id: TermId, visit: &mut dyn FnMut(TermId)) {
let classid = id.namespace().render_classid(self.app_prefix);

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 Resolve TermIds through the bake registry

For slabs produced by bake_with using a non-core registry such as META_STUDY_SPINE (the supported bake_spine.rs flow), TermId::ns is that registry's ordinal, but this line interprets it as the Namespace enum ordinal. For example, meta-spine ordinal 0 is BFO (0x0340), yet it is queried as MONDO (0x0301), so resolve silently misses every row; the inverse path also drops all 0x034x targets in term_of. Consequently the new baked-lane reasoner returns empty ancestry and relations for these valid slabs. SpineSource should retain the NsRegistry used for the bake and perform both ordinal-to-classid and classid-to-ordinal translations through it.

Useful? React with 👍 / 👎.

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