Repository navigation
obo/ro: SoA lens reasoning surface, per-class LE row contract, one predicate home - #267
Conversation
…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.
Bugbot couldn't run - usage limit reachedBugbot 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) |
There was a problem hiding this comment.
💡 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); |
There was a problem hiding this comment.
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 👍 / 👎.
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-onlyancestors/related_via_ancestry/anatomy_of/phenotypes_ofare now generic over anEdgeSource. The only shipped sources:SpineSource—SpineLenslifted intoTermIdspace 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_atvisits 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 contractThe 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 — andENTITY_TYPE_SLAB_OFFSET/EDGE_LANE_SLAB_OFFSET/EDGE_LANE_COUNTare derived from the schema.row_schema_ofrefuses foreign concepts (incl.0x0306, call-slab shaped), and a pinning test fails if an independent literal reappears. Registry-sideClassView/ValueSchemaregistration 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}andNamespace::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 contiguous0x90..0xA5band (contiguity pinned by a test that can fail), replacing the name-keyed scan that invited byte→string→byte round-trips;for_obo_predicatecrosses the OBO/RO seam once, refusingHasAnatomy/Otherhonestly.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
ClassRowSchemain a bridge test.Generated by Claude Code