Beta. IR mapping is live and in active development. The surface below is
real and tested; expect it to grow (more source formats, deeper composition).
It is REST-only today — there is no
pb.ir SDK namespace yet.The vocabulary
| Noun | What it is |
|---|---|
| Symbol table | The foreign type universe, resolved and version-stamped — every schema in the spec, keyed by path (#/components/schemas/Customer). |
| Correspondence | The one artifact you author: an edge from a foreign type to one of your ontology types, carrying a relation and your reasoning. |
| Relation | Four values: identity (same thing), subset (theirs is a narrower case of ours), related (meaningfully connected, not the same), disjoint (deliberately not mapped — a recorded decision, not an omission). |
| Coverage | Three-state completeness: mapped, disjoint, unmapped. Unmapped is work remaining; disjoint is work done. |
| Drift | Per-correspondence flags when either side changes: a type vanished from their spec, a version hash moved on yours. |
The loop
Everything runs through one endpoint:POST /v1/ir/<tool> with your API key.
Errors return in the body (isError: true), never as bare HTTP failures.
Open a mapping session
mapping_id — the session everything else operates
on. Mappings persist; you can come back to one.Ingest the spec
Pass a parsed OpenAPI 3.x document. The ingest walks
components.schemas,
resolves $ref / allOf / oneOf / anyOf, and produces the symbol
table.Adjudicate correspondences
One call per judgment. The relation and your reasoning are the artifact:
ir_map_property then adjudicates field-level pairs under a type-level
correspondence (with roles like titular); ir_remove_correspondence and
ir_unmap_property reverse decisions.A worked mapping
A commerce API mapped onto a CRM ontology — five judgments, five different answers:| Their type | Relation | Your type | Why |
|---|---|---|---|
Customer | identity | crm.Person | Same referent. |
Address | identity | crm.PostalAddress | Same referent. |
Order | identity | crm.SalesOrder | Same referent. |
LineItem | related | crm.OrderLine | Connected, but the granularities differ. |
Payment | disjoint | — | Deliberately out of scope, on the record. |
ir_analyze then reports { mapped: 4, disjoint: 1, unmapped: 3 } — the three
unmapped types (CardPayment, BankPayment, OrderStatus) are the visible
remaining work, not silent gaps.
Drift: when their spec changes
Re-ingest version 2 of the spec and runir_analyze again. If Address
disappeared from their schema, its correspondence flags left_dangling;
surviving correspondences flag left_version_changed so you know to re-confirm
them. Your integration’s semantic assumptions just became something a pipeline
can check — drift CI for meaning, the way dq.audit
is CI for graph writes.
The tools
| Tool | Safety | What it does |
|---|---|---|
ir_open_mapping | write | Open (or create) a persistent mapping session. |
ir_ingest_source | write | Ingest an OpenAPI 3.x document into the symbol table. |
ir_add_correspondence | write | Author one adjudicated type-level edge. |
ir_map_property | write | Adjudicate a property pair under a correspondence. |
ir_remove_correspondence / ir_unmap_property | write | Reverse a decision. |
ir_review_proposals | read | Gate LLM-proposed correspondences: each comes back admissible or rejected, with reasons. |
ir_inspect_mapping | read | Read the session: paths, correspondences, state. |
ir_analyze | read | Coverage, property coverage, drift, healthy. |
ir_review_proposals is the agent-era piece: let a model propose the mapping,
and let the deterministic gate decide what is admissible. Nothing enters the
mapping unreviewed.