logicsrc/docs/openontology-interoperability.md
Anthony Ettinger 58c942c67f
Some checks failed
CI / build (push) Has been cancelled
test / test (push) Has been cancelled
feat(openontology): implement OpenOntology Phase 0 + local engine and CLI (#99)
Implements OpenPRD 0001 through Phase 0 (specification, schemas, example,
docs surface) and Phase 1 (local engine, CLI, conformance tests).

Schemas (17 contracts, JSON Schema Draft 2020-12, additionalProperties:false)
  manifest, namespace, entity-type, property, relationship-type, constraint,
  query, action, entity, claim, source, evidence, changeset, review, approval,
  event, package — registered in @logicsrc/validators and exported from
  @logicsrc/schemas under https://logicsrc.com/schemas/openontology/.

@logicsrc/openontology
  - canonical JSON + sha256 package digests; YAML, JSON, NDJSON, and inline
    authoring all compile to the same bytes, so digests are authoring-agnostic
  - id profile: compact / IRI / urn with one canonicalization rule, prefix
    bound by a Namespace object so IRIs reverse unambiguously
  - validation: schema, graph (domain/range, datatypes, dangling refs),
    provenance (source-or-firstParty, agent runId, derivation inputs), policy
    (excerpt limits, licensing, visibility, staleness) and declared
    constraints; four severities, stable codes, text/json/yaml/markdown
  - portable triple-pattern query AST: multi-hop, 14 operators, asOf and
    recordedAsOf, per-status filtering, distinct/order/limit, explanation
    mode, and enforced depth/binding/row limits
  - append-only store: claims are immutable; dispute/retract/supersede append
    status transitions and the effective status is the latest one
  - change sets: 9 operations, atomic pre-flight, conflict detection on stale
    base revisions, semantic diff with duplicate-identity warnings and
    affected-query deltas, per-operation reviewer decisions
  - policy: agents propose but can never apply — the denial keys on actor
    type, so every scope plus high confidence plus --yolo still cannot apply;
    merges need approval, bulk retractions need two, undeclared action side
    effects are denied
  - JSON-LD 1.1 export/import with PROV-O aliases and lossy-field reporting
  - pluggable signature envelope with a jws-ed25519 reference profile and a
    fail-closed trust policy

CLI: logicsrc ontology init|validate|lint|build|inspect, entity, claim, query,
changeset, import, export, audit. Reads take --format, writes default to a
proposal, exit codes are stable for CI.

Example: examples/openontology/ethereum-ecosystem — 12 entity types, 17
relationship types, 63 entities, 169 claims, 25 sources, 31 evidence records,
5 saved queries, every claim lifecycle state, and a pending merge proposal.
All data is fictional; the directory is removable without affecting any core
test.

Docs: docs/openontology{,-governance,-interoperability}.md, a real
/openontology route, homepage + nav + sitemap entries, and a root README
section.

Verification: 112 new tests; full monorepo build and every workspace test
pass; conformance bundle (18 valid + 13 invalid fixtures) runs against the
published schemas alone; Node.js 25 and Bun 1.3 produce byte-identical
digests, revisions, event trails, and query results.

Not included (later PRD phases): MCP resources, REST/SSE, Turso adapter, TUI
and PWA surfaces, RDF/SHACL mappings, source adapters, governed actions.

Refs: prd/0001-add-logicsrc-openontology-spec.md

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 02:10:13 -07:00

125 lines
6.6 KiB
Markdown

# OpenOntology interoperability
How OpenOntology relates to JSON Schema, JSON-LD, RDF, SHACL, PROV-O, and external identifier systems — and, just as importantly, where the mappings stop. Companion to [OpenOntology](./openontology.md).
The guiding rule: **report what a format cannot carry; never drop it silently.**
## Where each format sits
| Format | Role |
| --- | --- |
| **JSON Schema 2020-12** | Canonical, normative contract. The schemas *are* the standard. |
| **Canonical JSON** | Deterministic bytes for hashing, signing, diffing, publishing. |
| **YAML** | Human authoring convenience. Compiles to canonical JSON. |
| **NDJSON** | Streaming format for large entity/claim/source files. |
| **JSON-LD 1.1** | Interoperability profile for the semantic-web world. |
| **RDF / Turtle** | Planned export of the losslessly mappable subset. |
| **SHACL** | Planned mapping for the constraint subset with equivalent semantics. |
| **PROV-O** | Vocabulary reused for provenance where the semantics genuinely match. |
OpenOntology does not require RDF, OWL, SPARQL, or a triple store. It maps to them so that consumers who need formal reasoning can get there.
## JSON-LD
```bash
logicsrc ontology export --dir ./ethereum-ecosystem --format jsonld --out graph.jsonld
```
Entities become nodes. Claims are **reified** — each claim is its own node with subject, predicate, object, status, time, confidence, and provenance — because the provenance is the point. A bare triple cannot say "asserted by this agent, from this commit, valid since April, confidence 0.94."
Provenance terms alias PROV-O rather than inventing parallel vocabulary:
| OpenOntology | JSON-LD term |
| --- | --- |
| `assertedAt` | `prov:generatedAtTime` |
| `assertedBy` | `prov:wasAttributedTo` |
| `sources` | `prov:wasDerivedFrom` |
| `runId` | `prov:wasGeneratedBy` |
| `confidence` | `oo:confidence` (`xsd:double`) |
| `validTime.from` / `.to` | `oo:validFrom` / `oo:validTo` |
| `status` | `oo:status` |
Compact ids canonicalize to IRIs against the package namespace; the `Namespace` object binds the prefix, which is what makes the reverse direction unambiguous. The round trip `JSON → JSON-LD → JSON` preserves ids, types, subjects, predicates, objects, typed values, language tags, statuses, times, confidence, sources, evidence, and supersession links.
### Lossy fields
The 0.1 JSON-LD profile does **not** carry: `tags`, `license`, `visibility`, `retention`, `changeSet`, `model`, `firstParty`, `derivedFrom`, `retractionReason`, and `extensions`. Export reports them per object:
```txt
warning: 3 object(s) have fields this format cannot carry:
eth:claim:0042: tags, license
```
The same holds in the other direction: importing a foreign vocabulary that expresses semantics the core model lacks reports the gap instead of quietly discarding it.
## External identifiers
An entity carries namespaced external ids without treating any external service as the identity authority:
```yaml
externalIds:
github: averyl
wikidata: Q000000
orcid: 0000-0000-0000-0000
did: "did:example:abc"
```
Lookup works by exact id, canonical name, alias, or external id. `findEntities` returns **ranked candidates with the evidence for each match** — never a silent single answer.
`sameAs` is a reviewable claim, not an implicit merge. Two records only become one through an approved `merge-entity` operation, and the losing id survives as a redirect.
## RDF, SHACL, OWL
Planned for a later phase, deliberately not faked in 0.1:
- **RDF/Turtle** — export and import of the losslessly mappable subset, using the same reified-claim shape as JSON-LD.
- **SHACL** — the constraint kinds with genuinely equivalent semantics (`required-predicate`, `cardinality`, `unique`, `allowed-values`, `domain-range`) map to shapes. Query-based constraints do not, and will be reported as unmapped.
- **OWL/RDFS** — an optional mapping for consumers needing formal reasoning. OpenOntology itself infers nothing: transitivity, symmetry, and inverses apply only when the schema declares them *and* a query asks.
Until those ship, the compatibility matrix below says "planned", not "supported". Claiming compatibility that has not been implemented and tested is the thing this document exists to prevent.
## Compatibility matrix
| Target | 0.1 status | Notes |
| --- | --- | --- |
| JSON Schema 2020-12 | **supported** | Canonical contract; 16 object kinds |
| Canonical JSON + digest | **supported** | Deterministic across Node.js and Bun |
| YAML authoring | **supported** | Same digest as equivalent JSON |
| NDJSON | **supported** | Streaming entity/claim/source/evidence files |
| JSON-LD 1.1 export | **supported** | Reified claims, PROV-O aliases, lossy report |
| JSON-LD 1.1 import | **supported** | Round-trips the reference profile |
| PROV-O | **partial** | Provenance terms aliased; full mapping later |
| RDF / Turtle | planned | Phase 3 |
| SHACL | planned | Phase 3, constraint subset only |
| OWL / RDFS | planned | Optional, for external reasoners |
| SPARQL | planned | Query AST → SPARQL adapter |
| Cypher | planned | Query AST → Cypher adapter |
| Datalog | planned | Query AST → Datalog adapter |
| SQLite / Turso | **supported** | Reference storage adapters |
| Neo4j / vector DBs | not required | Optional adapters; never mandatory |
## Query portability
The triple-pattern AST is deliberately small so a second implementation is achievable. Adapters translate it to SQL, SPARQL, Cypher, or Datalog and must **report their capabilities** — an adapter that cannot do multi-hop traversal or `asOf` says so rather than returning a subtly wrong answer.
Aggregation, grouping, faceting, and path-finding are P1: useful, but not in the 0.1 evaluator, so that the portable core stays implementable.
## Embeddings
Optional, rebuildable, provider-neutral derived data. They may improve discovery; they are never the sole representation of a fact and never authoritative. A package with its embeddings deleted loses nothing canonical.
## Importing
Imports **propose**; they never apply:
```bash
logicsrc ontology import --file graph.jsonld --dir ./my-ecosystem
```
```json
{ "entities": 63, "claims": 169, "proposedOperations": 12 }
```
The result is a set of operations for a change set. Source adapters must declare whether they can read public data, private data, incremental changes, and deletions, and what licence the source carries. An ingestion run is repeatable from its declared sources, mappings, parser version, and model configuration.
Deduplication runs on stable id, external id, exact alias, normalized URL, and reviewed similarity candidates — with the last of those always going to a human.