DataShield Ontology · documentation
DataShield Ontology: Overview and Architecture
*Measured against the tree at v0.22.188 (package.json), 2026-09-22. Read-only pass; every capability claim below carries a file:line citation or names the measured source it was taken from. Normative keywords (MUST, MUST NOT, SHOULD, MAY) are used per RFC 2119. Where the code and the stated direction disagree, the disagreement is stated rather than resolved. Companion measured source: docs/audit/portal-ontology/03-ontology-capability-map.md (cited below as CAP-MAP §A.n).*
Audience: developers, data-governance teams, analysts, and AI agents adopting the Ontology at library.myorg.ai.
On this page
1. What the Ontology is
The DataShield Ontology (production name still "DataShield MCP Dataset Library"; process prefix pdl-*) is an agentic data fabric: one server-side catalog of data assets, their governance state and their processing runs, exposed identically to AI agents (MCP), programs (REST) and humans (UI). It is not a notebook, a DAG scheduler, or a BI tool; those are consumers of the catalog, never peers of it.
The governing direction is the data catalog is the north star — docs/standards/STANDARD-011-catalog-north-star-DRAFT.md. Its headline rules, quoted as measured from the file:
| Rule | Text (abridged) | Source |
|---|---|---|
| R-1 | The catalog is the system of record for every data asset, interaction, run and output. An asset the platform can read/write/profile/classify/transform/distribute MUST have a catalog identity. | STANDARD-011 :31-32 |
| R-2 | Other tools are consumers and layers, never peers of the catalog. | :40 |
| R-3 | The north star is falsifiable: a claim that a surface "goes through the catalog" MUST be measured from code. | :48 |
| R-4 | Reads enter through the ONE declared door: data_catalog.scan_run with a CRAWLER_PURPOSES member. | :72-73 |
| R-5 | Outputs are catalogued assets. | :80-81 |
| R-6 | A pipeline is a catalogued run graph, not a separate tool. | :88 |
| R-10 | One lineage emitter seam, and only one. | :119 |
| R-14 | MCP, REST and UI derive from ONE declaration. | :153-154 |
| R-20 | A second implementation of an existing capability is a defect. | :201-202 |
Status caveat (measured): STANDARD-011 is DRAFT — not ratified; its §10 lists four operator decisions outstanding (STANDARD-011:3). Readers MUST treat R-1..R-20 as the direction the code is being moved toward, not as a description of what every code path does today. Where a stage below is absent or stub, the gap is stated.
Depth vocabulary used below (STANDARD-005 §13): real = measured working code with live rows; stub = declared seam that returns a typed pending result; absent = no code. Row counts are the read-only SELECT count(*) values recorded in CAP-MAP on 2026-09-22.
2. Three surfaces, one declaration
The platform serves the same capability set on three surfaces. The parity rule is STANDARD-011 R-14/R-15/R-16 (:153-171): settings, actions, parameters and help text MUST be declared once (config) and rendered by all three surfaces; a UI action MUST execute the same server-side capability as MCP; a surface MUST NOT introduce a control, default or permission the others lack.
| Surface | Location (measured) | Count | Notes |
|---|---|---|---|
| MCP umbrellas | scripts/mcp-server/umbrellas/*.ts | 45 files (ls), 45 tools / 462 commands / 89.0% .describe() coverage (docs/versions/v0.22.188/capability-manifest.json → summary) | One file per umbrella (STANDARD-003); shared kernel scripts/mcp-server/kernel.ts:1-5 (request-context, call-outcome, DESTRUCTIVE_COMMANDS singletons). Served by pdl-mcp on MCP_PORT: 3100 (ecosystem.config.cjs:70). |
| REST bridge | app/api/app/<umbrella>/[verb]/route.ts | 18 entries under app/api/app/ (ls), incl. _bridge/principal.ts (shared principal resolution :95) | The data_catalog and stewardship bridges are generic single dispatchers: verb table derived from the wire contract (app/api/app/data_catalog/_bridge/registry.ts), door derived from the same COMMAND_AUTH the MCP kernel enforces, args validated by the same zod union (_bridge/args.ts), command run through the same executor lib/data_catalog/dispatch.ts (app/api/app/data_catalog/[verb]/route.ts:6-15). Refusals are RFC 9457 problem+json from lib/server/problem.ts (route.ts:13-15). |
| UI | app/app/* (admin/alerts/crawlers/data-catalog/datasets/dev-studio/keys/logs/runs/sources/stewardship/support-studio) and app/data-catalog/* (datasets/lineage/tools + page.tsx) | measured by ls | Nav is configuration: config/app-nav.config.ts (NAV_SECTION_IDS = ["stewardship","data_catalog","management"] :132) and config/data-catalog-nav.config.ts (NAV_VERSION "4.0.0" :54, CATALOG_ROUTE "/data-catalog" :57, section param ?section= :61-62). Served by pdl-web on PORT: 3002 (ecosystem.config.cjs:34). |
Parity is enforced today only where a gate exists. npm run standards:parity-check (scripts/standards/parity-gate.ts, STANDARD-002 :18) gates the MCP-umbrella endpoint contract. The catalog-wide surface-parity gate R-14 names (audit:catalog-surface-parity) is PLANNED, not built (STANDARD-011:158-159). Adopters SHOULD therefore verify a capability on the surface they intend to use, not infer it from another surface. Not every umbrella has a REST twin: 18 REST bridge entries vs 45 umbrellas (measured ls); the data_catalog bridge is the reference implementation of parity-by-construction.
The MCP error envelope is not problem+json. MCP/JSON-RPC refusals use the compact canonical MCP envelope (config/mcp-rpc-codes.config.ts, imported at kernel.ts:11); REST uses RFC 9457 (CLAUDE.md headline; DEC-1 / LIB-BUG-318). The code extension is the same registry key on both surfaces (route.ts:14-15).
3. The processing chain, end to end
The Ontology has one processing model and it is catalog-shaped (CAP-MAP executive summary ¶1). One paragraph per stage; the "owning umbrella" is the MCP tool whose commands write the stage's tables.
3.1 Providers — owner data_catalog — real
A provider is a catalogued source system. Commands provider_create/list/get/update/retire/test (lib/data_catalog/dispatch.ts:433-486,:828). The kind registry PROVIDER_KINDS (config/data-catalog.config.ts:483, derived from PROVIDER_KIND_DECLARATIONS :227-482) declares each kind's STANDARD-010 connection path ("A" native dial, "B" REST+vault, or "ingest"). Table catalog.providers (migrations/registry/0220_data_catalog_schema.sql:41), 41 rows. UI app/app/data-catalog/sections/ProvidersSection.tsx. (CAP-MAP §A.1)
3.2 Connections — owner connection — real
Credentials plus the dial. Commands create/list/get/test/delete; dialers live in lib/data_catalog/resolver/dialer.ts (leased via withDialer :455). Path A dials natively for the seven measured kinds postgresql / snowflake / databricks / bigquery / sqlserver / mysql / s3; Path B saas_api dials via saas_get. Table registry.connections (0018_connections.sql:11), 1,341 rows. Secrets are vault-held (vault umbrella). Per STANDARD-010 there are two paths only; a provider-specific side door is forbidden (STANDARD-011 R-19 :191). (CAP-MAP §A.2)
3.3 Crawlers and scans — owner data_catalog (legacy crawler, crawler_run) — real
A crawler carries a purpose from CRAWLER_PURPOSES = discover | profile | extract | rescan (config/data-catalog.config.ts:910); data_catalog.scan_run (dispatch.ts:502-534) is the ONE admission door for reading provider data (R-4). A scan is recorded in catalog.scans (0220:143; `id, provider_id, purpose, status, scope, stats, error, started_at, finished_at, …), **98 rows**; crawler projects in registry.crawler_projects (0001_init.sql:57`), 213 rows. Execution runs as async-job kinds crawler.project_run / source_run / portal_discover (scripts/job-worker.ts:316,:334,:362) and the system-enqueued data_catalog.scan_run (config/job-lanes.config.ts:119-124). Lanes: harvest lib/data_catalog/harvest/apply.ts:320 applyHarvest(), profile profile/apply.ts:96 applyRelationProfile(), extract extract/index.ts:129 extractAssetToDataset() with a config-keyed EXTRACTORS registry (:47-77). The legacy crawler umbrella (13 commands) covers open-data portal crawls. UI app/app/crawlers/PageClient.tsx, app/app/data-catalog/sections/ScansSection.tsx. (CAP-MAP §A.3)
3.4 Assets, columns, terms, tags — owner data_catalog — real
Scans produce catalog.assets (0220:78, 4,549 rows), catalog.asset_columns (:108), catalog.terms (:206), catalog.mapping_decisions (:231) and catalog.asset_profiles. Commands `assets_list / asset_get / columns_list / columns_search / objects_search / profile_get / terms_materialize / terms_list / terms_grouped_list / asset_tag_set / asset_tag_remove / asset_register_enricher (dispatch.ts:95-96,:207,:535-671,:733`). terms_materialize is an async-job kind. Tags are free labels; classification labels are kernel outputs, not tags (STANDARD-011 R-8 :103-105; see §3.11). (CAP-MAP §A.4)
3.5 Bindings — owner data_catalog — real
A binding maps a catalog object to an MDM entity type — the MDM inbound leg. Commands bind_inbound / bindings_list / binding_get / unbind (dispatch.ts:671-701); rules in lib/data_catalog/bindings.ts:1-17 (full-extract requirement, primary-key ladder, STANDARD-006 P4 append-then-supersede, unbind deactivates the mapping in one transaction). Table catalog.bindings (0220:165), 27 rows; writes mdm.project_systems; governance-audit subject catalog_binding (migration 0225). Bind/unbind/remaster/terms_materialize are the four admin-floored verbs on the REST bridge (app/api/app/data_catalog/[verb]/route.ts:1-5). (CAP-MAP §A.5)
3.6 MDM / remaster — owners mdm (99 commands), mdm_project (15), stewardship (29) — real
data_catalog.remaster (dispatch.ts:701) decides run | skip | rescope on a pending remaster decision; lib/data_catalog/remaster.ts:1-13 hooks lib/conduit/autoDiff.ts onDatasetDiffed and enqueues mdm.resolution_run through the single ladder lib/mdm/resolutionEnqueue.ts. Resolution, training, rule enactment, preparer, recommendation and quality-axis work are async-job kinds (job-worker.ts:121-226). Golden records live in mdm.golden_entities (749 rows) with an outbox registry.golden_event_outbox (migration 0200). Stewardship UI app/app/stewardship/* (Sankey slots/FlowSankey.tsx) reads one flow_summary contract shared with data_catalog.flow_summary (dispatch.ts:706, lib/data_catalog/flowSummary.ts:1-12). (CAP-MAP §A.6, §A.15)
3.7 Datasets — owners dataset_catalog, dataset_ingest (9), dataset_admin (13), dataset_lifecycle (6), dataset_snapshot (7), dataset_data (2), file_repo (11) — real, with a stated disagreement
registry.datasets (0001_init.sql:102, 11,920 rows) is the platform's own asset plane: ingest (registry.ingests / ingest_steps 0045, ingest_jobs 0047), file storage conduit.repo_files (0017:99-123, carrying parent_file_id, derivation_type, derivation_config, pipeline_hash, version), snapshots, soft/hard delete and archive. REST /api/app/datasets/*, /api/app/my-datasets, /api/ingest; UI app/app/datasets/page.tsx, app/data-catalog/datasets. Disagreement (per META-CALIBRATION 5): STANDARD-011 N-4 calls for "one plane with namespaces", but today datasets are a second identity plane — ingest/publish/snapshot/transform outputs produce no catalog.assets row (CAP-MAP §A.7, W1 charter §0.1). A corpus IS a dataset (config/edges.config.ts:31). (CAP-MAP §A.7, §A.14)
3.8 Analysis engines (Conduit) — owner dataset_analysis (8) — real
Commands get / runs_list / create / submit / submit_batch / preflight / analysis_mode_get / analysis_mode_set; execution mode vocabulary client | server | auto (config/conduit-execution-mode.config.ts:37) with a parity contract between the server engines and the browser engine (:22-30). Server engines stamped by scripts/worker.ts: pg (:537), duckdb_profiler (:728), document_processor / document_disposition (:914,:929), worker_processor (:1016); large files fork scripts/worker-child.ts. The canonical 20-section analysis contract is lib/conduit/analysisContract.ts:244; deep analysis / RelationshipAtlas lib/analytics/deepAnalysis.ts:2. Runs in conduit.analysis_jobs (1,397 rows) and conduit.analysis_runs (0017:131); async kinds dataset_analysis.preflight / submit (job-worker.ts:378,:404). (CAP-MAP §A.8)
3.9 Transforms — owner dataset_transform (6) — real as compiler, absent as materialiser
Commands json_to_csv / json_process / transform_preview / transform_recipe_list / transform_recipe_get / transform_codegen (scripts/mcp-server/umbrellas/dataset_transform.ts:113-244). Model: 21 TRANSFORM_TYPES (config/transform-model.config.ts:55-77), 16 static recipes (config/transform-recipes.config.ts), compiler lib/conduit/transformModel.ts (compileTransformations :267, buildPreview :444, applyTransformations :526), pandas codegen lib/conduit/transformCodegen.ts (emitPandas :1048). Nothing is materialised: preview is in-memory and value-free; transform_codegen attach:true writes generated Python as a derivative file, not a dataset; config/edges.config.ts:266-268 states "dataset_transform materializes no datasets". aggregate / join / custom_sql / custom_python are refused with unsupported_reason. **Python is generated, never executed** on the server (P-3; the import-graph guard is declared as data in config/codegen-no-execution.config.ts (CODEGEN_NO_EXECUTION_SCAN) and asserted by the gated unit suite lib/conduit/__tests__/transformCodegen.test.ts, chained into release:gates at test:unit:gated — there is no audit:* script of its own). (CAP-MAP §A.9, ¶5)
3.10 Publish / archive / sync — owners dataset_lifecycle, dataset_admin — real as writes, absent as catalogued runs
dataset_lifecycle.delete / undelete / archive_create / archive_list / archive_delete / restore (lib/lifecycle/softDelete.ts, hardDelete.ts); dataset_admin.sync (:2650) → lib/sync/datasetSync.ts publishes to object-store / SQL targets with masking honoured (publish_masking_unapplicable :522); dataset_admin.catalog_export (:2646); join_create / union_create insert into conduit.repo_files directly. 34 write paths, 0 catalogued runs (W1 charter §1); the write seam catalogWrite() that R-5 requires is HELD. (CAP-MAP §A.10)
3.11 Classification and masking — owner classification (6), dataset_admin.masking_* — real (kernel in shadow)
STANDARD-009's pure kernel lib/classification/index.ts (`classifyColumn / classifyTable / deriveGovernance / classificationDigest) runs under config/classification-rollout.config.ts:6-11 (shadow DEFAULT / live / off`; the KERNEL_FORBIDDEN_IMPORTS gate keeps it pure). Masking is OFF by default and legally-required only (STANDARD-009 R2/R3): lib/query/maskingPolicy.ts, maskedRelation.ts, maskedMaterialize.ts; physical masking is an async-job kind (job-worker.ts:389). Tables registry.phi_determinations (0121:5), mdm.classification_systems / codes (0066:32,:69). unclassified is not public; readers fail closed (CLAUDE.md, STANDARD-009). (CAP-MAP §A.16)
3.12 Jobs — owner job (8) — real queue, absent DAG semantics
The ONE async queue is registry.async_jobs (0077_async_jobs.sql:29-59, 4,066 rows), consumed by scripts/job-worker.ts (HANDLERS :105, 21 kinds :109-404, dispatch :434, typed unknown_kind :436, failure shape {code,message,retryable,context} :496-533). Lanes are config-declared (config/job-lanes.config.ts:11-51), system-enqueued kinds at :67-137. Durable time-gated ticks use registry.scheduled_tick_state (migration 0227; lib/scheduler/durableTick.ts claimDurableTick :128). The older conduit.analysis_jobs worker (pdl-worker) runs beside it. Commands `get / list_mine / list_all / cancel / retry / history / stats / reset_circuit_breaker`. Measured gaps: no retry/backoff columns, no inter-job data passing, no fan-out/join, and no single enqueue seam — INSERT INTO registry.async_jobs appears in 17 non-test modules (CAP-MAP §A.11). Concurrency follows STANDARD-006 row-scoped patterns (P2 SKIP LOCKED etc.); table locks are forbidden.
3.13 Lineage — owner edges (5, read-only) — real for RAG containment, stub emitter, absent OpenLineage store
Commands predicates / neighbors / traverse / view / impact (scripts/mcp-server/umbrellas/edges.ts:55-92); predicate vocabulary config/edges.config.ts:79-172; WRITER_REGISTRY :196-215 declares three enabled writers: two RAG ones — writer:splitter and writer:citation_heal (lib/query/corpus.ts:935,:1143,:1179) — and writer:governance_harvest, the governance read lane's depends_on harvest (config/governance-control.config.ts:669, called at lib/data_catalog/harvest/apply.ts:488), which has written 0 rows to date. Store registry.asset_edges (0190:21-38), 17,888 rows, 100% document→document. REST /api/app/edges/view → lib/server/lineage/assembleView.ts (server-side longest-path layering); UI app/data-catalog/lineage/page.tsx (anchor-required :94-105) on components/lineage/LineageCanvasInner.tsx (@xyflow/react). Data lineage is not yet recorded: the emitter lib/data_catalog/extract/lineage.ts:109-116 emitLineage() returns {emitted:false, reason:"lineage_pending"} by type (:57), the lineage.* OpenLineage schema has 0 tables, and the seam R-10 names (lib/server/lineage/emit.ts) does not exist. Design: docs/specs/lineage-openlineage-design.md; gate audit:lineage-emitter-enrolment ships in warn. (CAP-MAP §A.12)
3.14 Workflows and RAG — owners workflow (4), rag (12) — real definitions; workflows are client-executed
workflow.list / get / run / save (umbrellas/workflow.ts:302-354) over 87 JSON recipes in library/workflows/*.json (schema lib/mcp/workflowRecipeSchema.ts, gate audit:workflow-recipe-integrity). **There is no server-side workflow executor** — the MCP client runs the steps (workflow.ts:324). rag indexes corpora (lib/query/corpus.ts) through the bulk job lane (job-worker.ts:257-305) and is the only writer that has actually written lineage edges — a third writer is declared and enabled but has produced no rows (§3.13). (CAP-MAP §A.13, §A.14)
3.15 Chain summary
| Stage | Owning umbrella | Primary table(s) | Live rows | Verdict |
|---|---|---|---|---|
| Providers | data_catalog | catalog.providers | 41 | real |
| Connections | connection | registry.connections | 1,341 | real |
| Crawlers → scans | data_catalog (+crawler, crawler_run) | registry.crawler_projects, catalog.scans | 213 / 98 | real |
| Assets / columns / terms | data_catalog | catalog.assets | 4,549 | real |
| Bindings | data_catalog | catalog.bindings | 27 | real |
| MDM / remaster | mdm, mdm_project, stewardship | mdm.golden_entities | 749 | real |
| Datasets | dataset_*, file_repo | registry.datasets | 11,920 | real (second plane) |
| Analysis | dataset_analysis | conduit.analysis_jobs | 1,397 | real |
| Transforms | dataset_transform | — (no persisted output) | — | real compiler / absent materialiser |
| Publish / sync | dataset_lifecycle, dataset_admin | conduit.repo_files | — | real writes / absent runs |
| Classification | classification | registry.phi_determinations | — | real (shadow) |
| Jobs | job | registry.async_jobs | 4,066 | real queue |
| Lineage | edges | registry.asset_edges / lineage.* | 17,888 / 0 tables | real RAG / stub emitter / absent OL |
4. Standards in force
All in docs/standards/. Status text is quoted from each file's header.
| Standard | One line | Status (measured) |
|---|---|---|
| STANDARD-001 — Report & Dashboard UI: scroll, sizing, script loading | Every HTML report/dashboard MUST follow the scroll/sizing contract; non-compliant reports MUST NOT be saved. | Enforced |
| STANDARD-002 — MCP Umbrella Endpoint Architecture | The master spec for umbrella endpoints; gated by npm run standards:parity-check (scripts/standards/parity-gate.ts). | approved direction, Phase 0 in progress |
| STANDARD-003 — mcp-server.ts modularization | One file per umbrella under scripts/mcp-server/umbrellas/, shared kernel singletons (invariant I5). | ADOPTED 2026-07-12 |
| STANDARD-004 — Server-side authorization & tenancy | Authorization and ownership scoping enforced server-side, identically for every surface. | ADOPTED 2026-07-19 |
| STANDARD-005 — Subagent fan-out quality | Mandatory governance for artifact-producing agent fleets; §13 source-depth verdicts. | MANDATORY |
| STANDARD-006 — Concurrency doctrine | Realtime + batch coexistence via five row-scoped patterns (P1–P5); never table locks. | MANDATORY (LIB-BUG-570, 2026-08-25) |
| STANDARD-007 — Shared-tree release lock | Every session writing the PRIMARY tree MUST hold/check the advisory release lock (npm run release-lock:*). | MANDATORY (2026-09-05) |
| STANDARD-008 — Master-detail surfaces | List + detail + summary-at-rest contract for UI surfaces. | DRAFT for ratification (2026-09-08) |
| STANDARD-009 — Privacy classification and masking | One kernel, pattern library as data, unclassified ≠ public, fail-closed readers, masking OFF by default / legally-required only. | MANDATORY (2026-09-12) |
| STANDARD-010 — Connection paths and connector ownership | Two connection paths only (Path A native dial / Path B REST+vault); Ontology owns data connectors, Auth owns security connectors. | operator ruling 2026-09-15 |
| STANDARD-011 — The data catalog is the north star | R-1..R-20 above; catalog as system of record; one seam per capability. | DRAFT — not ratified |
Adopters MUST also read docs/CC-DIRECTIVES.md (code-quality directives; Directive 9 adversarial vetting, Directive 11 privacy) and CLAUDE.md (headline value: no hardcoded values, configuration-based implementations, RFC/ISO standards).
5. Deployment shape
All processes run from the PRIMARY tree /home/datashield/library under pm2 (ecosystem.config.cjs, cwd: at :31,:67,:109,:152,:194,:222,:261,:293). Worktrees build but never deploy (STANDARD-007 :3-5). Bundles are esbuild ESM artifacts built by scripts/build-scripts.sh (:74-79) into dist-scripts/*.mjs; pdl-web is a Next.js build (npm run build, MUST run with NODE_ENV=production).
| pm2 process | Entry (ecosystem.config.cjs) | Role |
|---|---|---|
pdl-web | npm run start, PORT: 3002 (:28-34) | Next.js UI + REST bridge (app/**) |
pdl-mcp | node dist-scripts/mcp-server.mjs --http, MCP_PORT: 3100 (:64-70) | MCP server, 45 umbrellas |
pdl-worker | node dist-scripts/worker.mjs, 16 GB heap (:105-108) | Conduit analysis engines (conduit.analysis_jobs) |
pdl-worker-large | node dist-scripts/worker-large.mjs, 18 GB heap (:146-151) | Large-file analysis lane |
pdl-anomaly-detector | node dist-scripts/anomaly-detector.mjs (:191-193) | Anomaly detection |
pdl-job-worker | node dist-scripts/job-worker.mjs, 2 GB heap (:218-221) | The registry.async_jobs consumer (21 kinds); MUST be restarted every release (LIB-BUG-565) |
pdl-alerts-dispatcher | node dist-scripts/alerts-dispatcher.mjs (:258-260) | registry.alerts_queue dispatch |
pdl-billing-reconcile | node dist-scripts/billing-reconcile.mjs (:290-292) | Billing reconciliation |
Database: PostgreSQL myorg_dataset_library with schemas registry, catalog, conduit, mdm (migrations under migrations/registry/). Health: curl -s localhost:3002/api/health. Release reloads are a derived chain (npm run release:reloads, config/bundle-consumers.config.ts CONSUMER_RELOAD_POLICY); hand restarts are forbidden (CLAUDE.md canonical release sequence step 6).
6. Versioning and release notes
- Version of record:
package.jsonversion(0.22.188at this writing);pdl-mcpreads it at load
(scripts/mcp-server/kernel.ts:19-20 PKG_VERSION). The _hello umbrella returns version, current_release and available_versions (CLAUDE.md Rule 7a).
- Release snapshots:
docs/versions/vX.Y.Z/— 183 directories (ls | wc -l). Each holdsRELEASE-NOTES.md
(front-matter fromVersion/toVersion/fromCommit/toCommit/manifestSchemaVersion/generatedAt), RELEASE-REPORT.html, capability-manifest.json (tools/commands/describe-coverage), describe-wire-reachability.json, diff.json and per-tool markdown under tools/ (measured at docs/versions/v0.22.188/). Snapshots are write-once.
- Release sequence: TAG LAST — lock → migrate →
release:gates(205 chained links in this tree, derived from
package.json; CLAUDE.md's "174" is the count recorded at v0.22.170) → gen/snapshot/diff → publish → package-bump → tag → reload chain → T-8 report (CLAUDE.md, "canonical release-event sequence").
- Timestamps are RFC 3339 (
generatedAt: 2026-09-21T03:10:43.420Z); durations/dates ISO 8601. - Discovery for agents:
ux.helpandux.docs_getaccept aversionparameter for multi-version documentation;
ux.versions_list enumerates the versions and takes no parameters (measured against docs/versions/v0.22.188/capability-manifest.json; CLAUDE.md Rule 7a names all three, which overstates the third).
7. Adoption checklist (normative)
- Callers MUST enter provider reads through
data_catalog.scan_runwith a declared purpose (R-4); there is no other read door. - Callers MUST NOT expect
dataset_transformto persist output or execute code — it previews and generates (§3.9). - Callers MUST NOT rely on data lineage today; only RAG document containment edges exist (§3.13).
- Callers SHOULD treat the
registry.datasetsandcatalog.assetsplanes as distinct until N-4 lands (§3.7). - REST callers MUST handle RFC 9457 problem+json refusals; MCP callers MUST handle the compact MCP envelope (§2).
- Developers MUST extend an existing seam rather than add a second mechanism (R-20), and MUST route every change through
adversarial vetting before commit (CLAUDE.md headline; Directive 9).
- Nothing in this document authorises building: the §8s hold in
portal-migration-1-ratification.md— carried into
STANDARD-011's cross-reference table at STANDARD-011:295 — keeps catalog UI expansion on HOLD until layouts are approved by the operator.
Measured against the release named in the text. Raw Markdown: /ontology/documentation/overview-architecture.md. This page is also served as raw Markdown at the same URL with a .md suffix, for agents and search tools that prefer plain text. Every capability statement cites the source file and line it was measured from.
You've seen the proof
Ready for a number? Scope your deployment and we'll price it against your own economics.
Get your quote →