Skip to content

feat(ogar-dismech): mint 19 DisMech causal predicates as a Vocabulary - #275

Merged
AdaWorldAPI merged 1 commit into
mainfrom
claude/ogar-dismech-predicate-palette
Aug 18, 2026
Merged

feat(ogar-dismech): mint 19 DisMech causal predicates as a Vocabulary#275
AdaWorldAPI merged 1 commit into
mainfrom
claude/ogar-dismech-predicate-palette

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

What

Adds the DisMech causal-graph predicate palette on top of the existing DISMECH_CONCEPT_ID (0x0333) reservation in crates/ogar-dismech/, mirroring ogar-ro's RelationVocabulary structure exactly (DisMechPredicate struct, a dismech_palette! macro, contiguous FnIndex consts, a by_index position lookup, an ogar_loco::Vocabulary impl, and a plug_into helper for VocabularyRegistry).

The 19 predicates — a measured, closed set

These are the complete predicate vocabulary emitted by the upstream DisMech causal-graph builder (monarch-initiative/dismech, src/dismech/graph.py), minted contiguously from DOMAIN_FLOOR (0x90):

Slot Predicate Slot Predicate Slot Predicate
0x90 causes 0x97 influences 0x9E measures
0x91 leads_to 0x98 targets 0x9F rescues
0x92 triggers 0x99 treats 0xA0 readout
0x93 exacerbates 0x9A models 0xA1 contributes_to
0x94 predisposes_to 0x9B partially_models 0xA2 variant_of
0x95 protects_against 0x9C fails_to_model
0x96 modulates 0x9D perturbs

Each is a binary, non-branching, non-pushing leaf assertion (same shape as ogar-ro's relation calls: it asserts an edge, it does not compute a value for a caller), declaring the new DISMECH_TARGET_CODEBOOK — the basin-local operand-resolution codebook, mirroring RELATION_TARGET_CODEBOOK.

Why dismech:*, never RO:* — the whole decision

Every CURIE uses the dismech: namespace. This is grounded in what upstream itself does, not a style preference:

  • Upstream's own SEPIO exporter declines to claim RO terms for its causal predicates — it defines its own namespace constants (dismech:causally_upstream_of, dismech:has_pathophysiology) rather than reaching for a similar-sounding RO term.
  • Across the entire upstream src/ tree there is exactly one RO: literal, and it names corpus data (a gene-disease association), never one of the graph-builder's own predicate names.

So minting these 19 under RO: CURIEs — even where a plausible match exists (causesRO:0002411 is the tempting one) — would assert a claim upstream deliberately declined to make. ogar-ro's own 2026-08-10 precedent covers exactly this: its confounds_test predicate uses LOCAL:, and has_interpretation/interprets use SCTID:, specifically because "no RO term carries the [needed] semantics… the byte is the normalized predicate either way; the CURIE records provenance, never a second dispatch key." Same reasoning, applied uniformly to all 19 rows here.

Left open, not resolved: upstream's SEPIO export uses the label causally_upstream_of for its causal family, which is not one of the 19 graph-builder predicate names minted here. Whether dismech:causes and dismech:causally_upstream_of denote the same relation under two labels is undetermined — the module doc says so explicitly rather than assuming either way.

Tests

13 tests in ogar-dismech (up from 3): closed-set size (RELATIONS.len() == 19) and bounds (0x90..=0xA2), contiguous-slot by_index lookup with refusal at both edges, per-predicate binary/non-branching/non-pushing/codebook shape, an anti-vacuity CURIE-namespace guard (every CURIE starts with dismech:, and — the silence twin — none starts with RO:/BFO:), name/CURIE-suffix uniqueness, and registry plug_into + duplicate-concept refusal (RegistryError::ConceptTaken). The existing DISMECH_CONCEPT_ID const and its collision-guard tests are untouched and still pass.

Added an ogar-loco path dependency (same shape ogar-ro uses).

Verification

  • cargo test -p ogar-dismech — 13/13 pass
  • cargo test -p ogar-ro -p ogar-obo — no regression (47 + 10 + 4 integration tests pass)
  • cargo fmt -p ogar-dismech --check — clean
  • cargo clippy -p ogar-dismech --all-targets -- -D warnings — clean except one pre-existing clippy::assertions_on_constants finding in the untouched collision-guard test (stays_in_the_0x03_ontology_domain_clear_of_documented_bands), confirmed present on main before this PR and unrelated to this change; left untouched per the collision-guard-tests-stay-untouched instruction.

🤖 Generated with Claude Code


Generated by Claude Code

Adds the DisMech causal-graph predicate palette (Monarch Initiative
`dismech`, `src/dismech/graph.py`) on top of the existing
DISMECH_CONCEPT_ID (0x0333) reservation, mirroring ogar-ro's
RelationVocabulary structure exactly: a DisMechPredicate struct, the
dismech_palette! macro, 19 FnIndex consts minted contiguously at
DOMAIN_FLOOR (0x90) through 0xA2, a by_index position lookup, an
ogar_loco::Vocabulary impl (binary, non-branching, non-pushing leaf
assertions, each declaring the DISMECH_TARGET_CODEBOOK), and a
plug_into helper for VocabularyRegistry.

Every CURIE uses the dismech: namespace, never RO: or BFO:. This is
grounded in upstream's own behavior, not a style choice: its SEPIO
exporter defines its own namespace constants (dismech:causally_upstream_of,
dismech:has_pathophysiology) rather than reaching for RO terms, and the
entire upstream src/ tree contains exactly one RO: literal, which is
corpus data, not a graph-builder predicate name. ogar-ro's own
2026-08-10 LOCAL:/SCTID: precedent for confounds_test /
has_interpretation / interprets covers exactly this situation: when no
RO term carries the needed semantics, the CURIE records honest
provenance instead of a bent match. Left open, not resolved: whether
dismech:causes and upstream's dismech:causally_upstream_of denote the
same relation.

Tests: closed-set size/bounds, contiguous-slot lookup, binary/
non-pushing/codebook shape per predicate, anti-vacuity CURIE-namespace
guard (dismech: required, RO:/BFO: forbidden), name/CURIE-suffix
uniqueness, registry plug + duplicate-concept refusal, plus the
existing collision-guard suite untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KCGhDYoQBXs3poaR7sFuqp
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@cursor

cursor Bot commented Aug 18, 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_3fa6b0d8-8d34-4074-88b5-cb264ed68e06)

@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown

Important

Review available on request

  • 🔍 Trigger review

Reviews should be triggered manually for repositories with fewer than 10 stars. Select Trigger review above or comment @coderabbitai review to review the latest changes. For a full review, comment @coderabbitai full review.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 70050b49-7fe5-4352-ac25-ef1332dd658f


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.

@AdaWorldAPI
AdaWorldAPI merged commit e0a9cfe into main Aug 18, 2026
3 checks passed
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