DataShield Ontology · documentation
Datasets, Analysis and Transforms
Measured against: /home/datashield/library at v0.22.188 (package.json:3), 2026-09-22. Audience: developers, analysts, AI agents routing through the MCP surface. Method: every claim below is read from code or migrations and cited file:line. Where the platform does not do something, this document says so explicitly rather than implying capability.
On this page
- 1. The dataset model — registry.datasets
- 2. Ingest paths
- 3. Analysis engines
- 4. Reading analysis and data
- 5. Derivatives that create a NEW dataset — dataset_admin.join_create / union_create
- 6. Derivatives inside an existing repo — file_repo.derivative_create
- 7. The declarative transform model — dataset_transform
- 8. Snapshots, lifecycle, publish / sync / archive / export
- 9. Generalization, fingerprint, evidence
- 10. Quick routing table for agents
1. The dataset model — registry.datasets
The dataset is the unit everything else attaches to. Its row was created in migrations/registry/0001_init.sql:102-142 and extended by later migrations. The base columns:
| Group | Columns (from 0001_init.sql:102-142) |
|---|---|
| Identity | id UUID PK, provider registry.provider_type NOT NULL, provider_dataset_id |
| Description | title, description, publisher_name, jurisdiction_level, jurisdiction_name, license, tags TEXT[], topics TEXT[] |
| Source | landing_url NOT NULL, landing_url_canonical NOT NULL, raw_page_payload JSONB, raw_source_payload JSONB, steward_notes |
| Liveness | is_active, confidence, discovered_at, last_checked_at, last_changed_at, next_check_at, check_status, http_status, content_hash |
| Usage | read_count, search_hit_count, last_accessed_at, search_tsv |
| Audit | created_at, updated_at |
Later migrations add 53 more columns by ALTER TABLE registry.datasets ADD COLUMN (measured across migrations/registry/*.sql; none is ever dropped):
| Family | Columns |
|---|---|
| Profile / shape | column_count, row_count, file_count, total_file_size_bytes, source_file_size_bytes, completeness_score, quality_score, quality_rating, has_analysis, table_type, dataset_type, file_type |
| Governance | compliance_level, has_pii, has_phi, classified_by, last_classified_at, needs_classification, visibility |
| Provenance / capture | source_category, source_system, source_mode, source_total_rows, row_count_drift, provider_metadata, capture_metadata, extras_json_text, notes_json_text, ai_tags, ai_tags_updated_at |
| Lifecycle | lifecycle_stage, deleted_at, deleted_by, purge_after, content_erased_at |
| Query engine | query_engine, query_engine_loaded_at, query_engine_last_refresh_at, query_store_size_bytes |
| Refresh | last_refresh_status, last_refresh_actor, last_refresh_attempted_at, last_refresh_completed_at, last_refresh_duration_ms, last_refresh_message, schedule_next_run_at |
| Snapshot / archive | snapshot_count, snapshot_total_size_bytes, archive_total_size_bytes |
| RAG | rag_indexed_at, rag_index_generation, rag_index_size_bytes, rag_indexed_record_count |
The derivative writers use a 16-column subset of that surface — visibility, source_mode, provider_metadata, capture_metadata and the governance trio among them (scripts/mcp-server/umbrellas/dataset_admin.ts:1258-1262).
Two facts an agent must not assume:
- No parent/derived column exists on
registry.datasets. Derivation is recorded on the file row
(conduit.repo_files.parent_file_id / derivation_type / derivation_config / pipeline_hash), not on the dataset (docs/audit/portal-ontology/05-library-derivative-datasets.md:114-116).
- No workspace binding lives on the dataset row. The Query-DB workspace resolves from
registry.dataset_loads
(latest load wins) then registry.dataset_settings; neither → typed workspace_unresolved (lib/analytics/deepAnalysis.ts:65-79).
Field-level metadata is a sibling table, registry.dataset_fields, populated by the analysis bridge (scripts/worker.ts:1030-1040, importAnalyticsProfile) and read by dataset_catalog (dataset_catalog.ts:63).
2. Ingest paths
Four doors write datasets and files. All URL fetches are SSRF-guarded (dataset_ingest.ts:821).
| Door | Commands (measured case list) | What it accepts / does | Source |
|---|---|---|---|
dataset_ingest | ingest, cancel, url_ingest, batch_ingest, url_and_wait, upload_urls_get, load, unload, status_get (9) | Inline content ≤10 MB (CSV/JSON, or PDF/DOCX/TXT/EML/HTML → document_collection dataset); URL download; async tabular batch (HEAD preflight sync, returns batch_id); url_and_wait tabular refresh orchestrator (job_id within 2 s); load into Query DB (masking_mode='physical' is async); unload is ADMIN + confirm:true. HTML pages are preflight-rejected by URL (LIB-BUG-210) — ingest inline. | dataset_ingest.ts:819-840, 950-1021 |
file_repo | list, read_file, analysis_runs, derivatives_list, summary, versions_list, derivative_create, drift_events, drift_acknowledge, download_url, upload (11) | Conduit file-repository access. Reads public; writes require API key. upload adds a file version; derivative_create stores caller-supplied bytes as a child of parent_file_id (§6). | file_repo.ts:189-198, 322-480 |
crawler | project_* (6), source_* (5), portal_discover, dataset_refresh (13) | Open-data portal crawls (socrata/arcgis/ckan/data_gov providers, :150), portal discovery over data.gov / global Socrata / known-portals registry (:161), and dataset_refresh → async refresh_analyze job (:139). scope.sample_policy:'plain' requires acknowledge_plain_samples:true, recorded as an audit row (:150). | crawler.ts:123-162 |
rest | endpoint_create, endpoint_update, endpoint_delete, endpoint_list, execute, responses_diff (6) | REST endpoint CRUD + execution; auto_save attaches the capture file_repo to the dataset (:200); optional cataloguing enqueues a discover scan on the account's rest_api catalog provider — refused endpoint_unbound_not_catalogable without auth_connection_id (:89). | rest.ts:24-89, 207-540 |
Post-analysis loading is a single seam: finalizeIngestAfterAnalysis (lib/ingest/postAnalysisLoad, called at scripts/worker.ts:912-913 and :940-941) — auto-load and downstream steps run there, not inside each engine.
3. Analysis engines
Jobs are dispatched by job_type in scripts/worker.ts. The engine name stamped on the stored run is what dataset_analysis.runs_list and file_repo.analysis_runs later report.
job_type (dispatch line) | Engine name stamped | What runs |
|---|---|---|
refresh_analyze (worker.ts:317) | inherits the analysis path | refreshDataset (lib/conduit/crawlerDownload) re-downloads by URL, then re-analyses and re-runs derivatives. |
dedup (worker.ts:422) | pg (:537) | FEAT-013 async entity dedup in the Query DB against a composite dedup_key (FEAT-009 key groups, :534); writes a _dedup_<ts> derivative table and pre/post/removed counts. |
deep_analysis (worker.ts:615) | — (writes registry.rel_atlas) | runDeepAnalysis → RelationshipAtlas (§3.1). completeJob with the consumed conduit runId (:625). |
rag_embedding (worker.ts:627) | — (no engine) | Declared but not implemented. The branch throws rag_embedding job type is not yet implemented (:628; same in worker-child.ts:193-196), and the type is listed in NOT_YET_IMPLEMENTED_JOB_TYPES (lib/conduit/analysisJobs.ts:46), which is what removes it from the dataset_analysis.submit wire enum. RAG indexing runs on its own lane, not through this worker. |
full_analysis / reprocess (worker.ts:629) | duckdb_profiler (:728) | Large CSV, any-size Parquet and routed JSON go to DuckDB: computeRawProfile + formatProfile (lib/conduit/duckdbProfiler, :715-719), stored via storeAnalysisRun, then bridged to registry.dataset_fields/dataset_analytics_profiles by importAnalyticsProfile with engineName:"duckdb_profiler", engineVersion:"1.0" (:749). LIB-BUG-269: small Parquet used to be dark because the in-memory engine cannot read PAR1. |
| same, document branch | document_processor (:914) / document_disposition (:929) | analyzeFileBuffer (lib/conduit/analyzeFile) text-extracts documents; a document with no extractable text stores a document_disposition run instead of failing (:918-944). |
| same, in-memory branch | worker_processor (:1016, :1036) | Default in-memory tabular analysis; bridged with profileType:"conduit_analysis" (:1038). |
Execution mode per account (client / server / auto) is read and set by dataset_analysis.analysis_mode_get/set and honoured by the server-side paths only (dataset_analysis.ts:1008, :1016).
3.1 RelationshipAtlas — deepAnalysis
lib/analytics/deepAnalysis.ts:1-24 states the contract, enforced in the module:
- Builds a RelationshipAtlas from the dataset's stored Conduit run plus governed correlation SQL; persists
atomically — the only write is a single INSERT into registry.rel_atlas after the full build succeeds (:9-10).
- Idempotent per
(dataset_id, snapshot_ref, config-set hash); a matching live row is returned, never duplicated (:7-8, hash at:83-90). - Edges capped top-k per node (
thresholds.atlas.max_edges_per_node); suppressed relationships always persist — "they are the safety product" (:11-12). - Guardrail outcomes surface as typed errors, never auto-forced (
:13); every constant loads from the versioned
analytics config store with hash-verified pins (thresholds, relationship-policy; :98-104).
- Premise (META-CALIBRATION 5): the DuckDB profiler stores an empty
pairwiseMatrix, so correlations are computed
via corr() through the masked-view query engine, bounded by compute_row_limit; r² = r·r (:17-22).
- Result shape:
{ atlasId, runId, reused, edgeCount, suppressedCount }(:55-61).
3.2 The AnalysisContract sections
config/analysis-contract-sections.config.ts:10-15 is the AnalysisContract v1.1 vocabulary (20 sections). Both engines stamp the full list on metadata.sectionsIncluded; a partial producer (the catalog pushdown profile) stamps a declared subset so a renderer shows which sections are absent instead of reading an empty section as "clean" (:2-8). The config carries names only (17 lines; no per-section prose) — the descriptions below are the author's reading of the producers in §3.
| Section | Carries |
|---|---|
executive-summary | Headline row/column counts, quality verdict, top findings |
data-completeness | Per-column null/missing percentages |
field-statistics, column-statistics-summary | Per-column type, cardinality, min/max/quantiles (value-bearing members are withheld on public reads — §4.3) |
top-values | Most frequent values per column (value-bearing; masked/withheld on egress) |
patterns-detected | Classification hits from the pattern library (semantic types, PII/PHI) |
before-after, data-pipeline, original-sample, final-sample | Transformation-pipeline effect and samples when a pipeline ran (JSON ingest path) |
dataset-profile, column-semantics | Dataset-level shape; per-column semantic type used by dataset_catalog.fields_search |
relationship-graph | Column relationships (deepAnalysis populates registry.rel_atlas separately) |
data-quality-metrics | Quality score inputs (registry.datasets.quality_score/quality_rating) |
compliance-governance | compliance_level, has_pii, has_phi, framework hits |
transformation-lineage, migration-playbook, business-rules | Lineage narrative, import-SQL guidance, inferred rules |
metadata | Engine name/version, sectionsIncluded, vocabulary_version (used by submit_batch scope:'vocabulary_stale', dataset_analysis.ts:1006) |
source-fingerprint | Source-system detection result (§9, fingerprint) |
4. Reading analysis and data
4.1 dataset_analysis (8 commands, dataset_analysis.ts:998-1017)
get (by run_id > file_id > dataset_id precedence, :1028-1034), runs_list (offset-paginated run history), create (store an analysis result with engine_name/engine_version), submit (enqueue full_analysis / refresh_analyze / reprocess / dedup / deep_analysis — the wire enum is SUBMITTABLE_JOB_TYPES, derived as JOB_TYPES minus NOT_YET_IMPLEMENTED_JOB_TYPES, :63-69), submit_batch (ADMIN staged re-analysis; dry_run defaults true; scopes stale / all / vocabulary_stale; DB-enforced idempotency against active jobs), preflight (HEAD+1 MB URL probe), analysis_mode_get/set. Job lifecycle moved to the job umbrella (:1017). Annotated destructiveHint:true because submit(refresh_analyze) replaces the stored file (:1018-1024).
Two state-source disagreements found while measuring this umbrella (META-CALIBRATION 5 — recorded, not resolved here):
create's own description says "store a 19-section analysis result" (:1004), andget'ssummary_only
describes the full body as "19-section" (:1035) — while the AnalysisContract vocabulary both engines stamp carries 20 sections (§3.2). The prose predates column-statistics-summary / source-fingerprint; the config is the authority.
submit's description lists four job types (:1005); the wire enum admits five (deep_analysisincluded,
:63-69). §10's deep_analysis row routes through submit and is correct.
4.2 dataset_data — the read-only query door (2 commands, dataset_data.ts:307-336)
query: a single-statementSELECT/WITHagainst one dataset (dataset_id, cost-guardrailed,forceoverride) or
2+ datasets (dataset_ids + aliases, cross-schema). Engine routing is automatic — PostgreSQL for loaded datasets, DuckDB directly on the file for unloaded/large ones (:311). The read-only guard rejects forbidden keywords, second statements and file/network table functions (:204). Positional $1 bind params work on every engine (:327).
sample: headers + first N rows, masking applied, DuckDB fallback (:312).- Canonical shape regardless of engine (LIB-BUG-439):
rowskeyed objects, authoritativecolumns[],types[],
totalRows, routing.engine (:313).
- Everything is served through masking views (
:310,:328). Loading isdataset_ingest.load; metadata search isdataset_catalog(:314).
4.3 dataset_catalog get / get_batch and the field-row projection
10 commands (dataset_catalog.ts:113): search, get, get_batch, stats, tables, fields_search, similar_list, change_history, catalog_facets, catalog_stats. get returns fields/resources/lineage/quality plus a row_drift signal (observed row_count vs provider source_total_rows, :118); get_batch does the same for 1–50 ids (:123). Field rows come from registry.dataset_fields (:63).
Field rows are value-free on this surface. sample_values and value-bearing statistics (min/max/quantiles) are withheld under the platform sample-value policy (default omit) because the catalog read is public-audience; each field instead carries sample_values_withheld {reason, policy}; count statistics (missing %, uniqueCount, cardinality) are returned in full (LIB-BUG-1395; :185, :220). The acknowledgement path that would release samples is unreachable on this door — no door passes it (:595). compact:true trims each field to a short projection (:263-264, :578-579); include_fields:false drops the list and keeps fieldCount (:261-262, :575-577). Column counts are reconciled against the field list (LIB-BUG-416, :258).
5. Derivatives that create a NEW dataset — dataset_admin.join_create / union_create
dataset_admin has 13 commands (title dataset_admin.ts:2444; schema union :2462-2602; handler cases :2625-2705) — settings_get, settings_update, bulk_action, summary_refresh, masking_reload, masking_set, changes_list, join_create, union_create, catalog_export, sync, refresh, columns_align. The two derivation verbs are join_create (:2644) and union_create (:2645).
| Property | join_create | union_create |
|---|---|---|
| Engine | in-memory DuckDB (duckdb-async, Database.create(":memory:"), :796, :845-846) | same |
| Reads | each source through its served masked relation — masked columns are materialised as masked tokens, never parent plaintext (:2455); a masked join key that is type-incompatible across sides refuses with a remedy (:1419-1430) | same masked-read contract (:2456, :1573) |
| Writes | new registry.datasets row (:1257-1264) + new conduit.repo_files row with derivation_type='join' (:1300-1305) | new dataset (:2110-2131) + repo_files row (:2147-2152) |
| Governance | born with strictest-of-parents compliance_level/has_pii/has_phi + framework union (:2455) | same (:1554) |
| Cardinality guard | estimates output rows; refuses join_cardinality_exceeded unless confirm_large_output:true (:2517) | — |
| Analysis re-enqueued | enqueueAnalysisJob full_analysis unless auto_analyze:false (:1356-1360) | full_analysis priority 5 + optional async dedup job (:2186-2199) |
| Parent link | JSONB only: derivation_config.join_sources[{dataset_id,file_id,role}] (:1308-1312); parent_file_id is NULL | derivation_config.union_sources[...] (:2156); parent_file_id NULL |
Consequence measured in docs/audit/portal-ontology/05-library-derivative-datasets.md:125-126: the 17 live new-dataset derivatives (6 join, 11 union) have parent_file_id NULL; registry.asset_edges holds 0 dataset→dataset rows and derived_from is declared with no writer (:118-119) — so the lineage canvas renders a join/union output with no upstream (:128-132). The OpenLineage store (M-1/M-2) is the planned fix, not a new materialiser (:133-135).
6. Derivatives inside an existing repo — file_repo.derivative_create
file_repo.derivative_create (file_repo.ts:403-442) stores caller-supplied base64 bytes as a new conduit.repo_files version under parent_file_id with derivation_type/derivation_config, optional analysis attach (:198, :251). The platform computes nothing here — it records what the caller computed (05-...md:148). It is dual-target gated (repo mutate + parent-file read, LIB-BUG-407; :316-317); a concurrent version allocation returns a retryable conflict (:509). No new dataset is created.
7. The declarative transform model — dataset_transform
7.1 Vocabulary (config/transform-model.config.ts)
TRANSFORM_TYPES (:55-77) — exactly 21, asserted at :797: `remove_column, rename_column, add_column, reorder_columns, filter, mask_pii, standardize_date, type_cast, deduplicate, aggregate, join, validate, custom_sql, custom_python, fill_null, trim, uppercase, lowercase, regex_replace, split_column, merge_columns`.
| Config | Value (measured) |
|---|---|
TRANSFORM_STATUSES (:92) | supported, narrowed, extension, unsupported |
TRANSFORM_STATUS_CENSUS (:701-705) | supported 9 · narrowed 3 · extension 5 · unsupported 4 |
TRANSFORM_KINDS (:102) | column, header, row_set, derived |
CODEGEN_CENSUS.pandas (:714-715) | emit 17 · recipe 2 (aggregate, join) · refuse 2 (custom_sql, custom_python) |
VALIDATION_RULE_ACTIONS / _SEVERITIES (:693-694) | log | filter | fail — and warning | error | fatal |
EVALUATION_FAILURE_POLICY.mode (:751-752) | count_and_report (alt. fail_closed) |
| Guards | REGEX_GUARD (:254), COLUMN_IDENTIFIER_RE + reserved list (:233-241), COLUMN_NAME_WIRE_CLAMP=128 (:231), PREVIEW_CONTRACT (:290) |
Each type has a TRANSFORM_MODEL[type] spec (:358-690) and the module self-checks duplicates, model coverage and the census on load (:793-810).
7.2 Commands (dataset_transform.ts:113-244)
json_to_csv, json_process, transform_preview, transform_recipe_list, transform_recipe_get, transform_codegen.
transform_preview(:198) — evaluates the pipeline in memory and returns what would change: column list,
row/column counts, per-column before/after shape tokens, change summary, flatten-spec and frame digests. Returns no cell values by construction and refuses if its own output scan finds one (:42). Unsupported step types (aggregate, join, custom_sql, custom_python) are refused with the reason, never dropped (:46).
transform_codegen(:244) — generates a complete pandas source file (helper prelude, named-parameter block,
pipeline, input-column assertion) plus attribution rows. Every caller literal is bound to a named parameter, never interpolated. Expression constructs and bare regex literals with no faithful re form refuse the whole request rather than emit code that computes something else (:43). attach writes the file as a derivative (text/x-python, derivation_type transform_codegen) into a repo the caller owns; parent_file_id must belong to repo_id (:81-82); ownership is checked before a byte is generated (:104).
7.3 P-3 — the no-execution invariant
"GENERATE-ONLY: the platform writes the file and NEVER runs it; there is no Python runtime, interpreter or sandbox on this surface" (dataset_transform.ts:43, :245). The invariant lives in config/codegen-no-execution.config.ts (05-...md:77). Note from the same audit (:80): no audit:codegen-no-execution gate exists in package.json — prior docs naming it as a gate were wrong; test:transform-engine and test:transform-bundle-smoke are the chained tests (package.json:98).
7.4 Honest statement — the model does not materialise a dataset
Per docs/audit/portal-ontology/05-library-derivative-datasets.md:26,58-59,137-146: there is **no transform_apply / materialize verb and no job kind runs applyTransformations**. transform_preview is a simulator; transform_codegen produces a real artefact that is never executed; the only path that applies the 21-type pipeline to rows is POST /api/conduit/json/ingest (REST, JSON input only), which writes a derivative file in the parent repo — not a dataset — and has 0 recorded uses (:143, :66). The only verbs that persist a new dataset from existing ones are join_create and union_create (§5).
8. Snapshots, lifecycle, publish / sync / archive / export
dataset_snapshot (7 commands, dataset_snapshot.ts:33-43): point-in-time snapshots of the loaded source table. create (server prefixes _snapshot_, bare label and handle both resolve), list (+ retention summary), get, compare (row-level diff, natural key auto-resolved from analysis else synthetic _row_id with a load-order caveat, :54), schema_diff (added/removed/renamed columns + type changes), delete and restore (zero-downtime swap, irreversible, confirm:true). Not a changeset reader: dataset_admin.changes_list (dataset_admin.ts:2640 → handleAdminChangesList, :474-494) runs queryCdcLog over the loaded schema's CDC log and refuses dataset_not_loaded otherwise — it does not read the changeset_computed derivative files auto-diff writes (05-...md:90, :147); nothing on the MCP surface reads those today.
dataset_lifecycle (6 commands, dataset_lifecycle.ts:360-370): delete (soft default; hard = DROP SCHEMA CASCADE, confirm:true, force on certified/reference, and mdm_disposition retain|purge REQUIRED — LIB-BUG-569, :379), undelete (refuses when content was erased, :533-541, or the dataset is hollow, :587-598), archive_create (S3/B2/R2/ Wasabi/Spaces/MinIO, optional drop_after), archive_list, archive_delete, restore. All commands take canonical dataset_id; bare id strict-rejects (:364). Stages: there is no dataset_admin.set_lifecycle_stage command — the stage is set either by dataset_admin.settings_update {lifecycle_stage} (dataset_admin.ts:2475) or by dataset_admin.bulk_action {action:'set_lifecycle_stage'} (BULK_ACTIONS, lib/lifecycle/bulkActions.ts:15-23), both over the same closed enum certified | reference | published | development | test | archived | uncategorized (config/lifecycle.config.ts:17-25).
Publish / sync / export (dataset_admin.ts:2457-2458):
sync— publish a governed copy to a remote S3-compatible connection: metadata sidecars
(dataset / schema / lineage / quality / governance / import SQL / README / manifest) plus by default the data file; apply_masking / row_limit / columns apply to the uploaded file and governance.json's data_file claim states exactly what was applied; a destination that cannot honour requested encryption refuses archive_encryption_unavailable rather than upload cleartext (:611, :2458).
catalog_export— Unity Catalog format by design, no format selector (:2457,:2646).05-...md:150records these as real writers with no catalogued run (W1) — sync/archive/export leave no lineage run today.
9. Generalization, fingerprint, evidence
generalization (7 commands, generalization.ts:136-147) — privacy-preserving column transforms. view mode is reversible masking applied at query / prompt-egress time and works; physical mode returns not_implemented (FEAT-033, :138, :141). Strategies and constrained options: dob_generalize (year|decade|age_range), zip_generalize (3|4 digits), age_band, phone_partial, ssn_partial, email_domain (:147). preview needs a loaded dataset; stats returns utility score + compliance coverage.
fingerprint (6 commands, fingerprint.ts:71-84) — identify the source system (Salesforce, SAP, Workday, …) from column names, sample values and metadata; 95 built-in + custom definitions (:77). detect scoring is IDF-weighted with calibrated confidence, raw score as the ranking key, matchedSignals and a basis string (:79); validate dry-runs ReDoS/length/count checks; create/delete are Developer tier+, creator-or-admin scoped. Feeds the source-fingerprint contract section (§3.2) and registry.datasets.source_system.
evidence (4 commands, evidence.ts:20-26) — the "prove" leg of find→prove→animate→watch. Rows are written at story.scan, pin their snapshot in the retention index and hash the payload over RFC 8785 canonical JSON. show (variant:'public' re-serves through the egress gate; PHI datasets refuse public without a §164.514(b)(1) determination), verify (re-hash vs content_hash), list (per claim), determine (admin; append-only PHI-publication determination; revocation is a new row, :26, :27-32).
10. Quick routing table for agents
| Need | Call |
|---|---|
| Add data | dataset_ingest.ingest / url_ingest / batch_ingest; documents inline via ingest |
| Make rows queryable | dataset_ingest.load → dataset_data.query / sample (masked) |
| Metadata, fields (value-free) | dataset_catalog.get / get_batch / fields_search |
| Run or read analysis | dataset_analysis.submit (poll job.get) / get / runs_list |
| Relationships | dataset_analysis.submit {job_type:'deep_analysis'} → registry.rel_atlas |
| New dataset from two or more | dataset_admin.join_create / union_create (DuckDB, masked-read, analysis re-enqueued) |
| Preview or generate a pipeline | dataset_transform.transform_preview / transform_codegen — nothing executes (P-3), nothing materialises |
| Store a computed file | file_repo.derivative_create (caller-computed bytes) |
| Point-in-time / diff | dataset_snapshot.create / compare / schema_diff |
| Publish a governed copy | dataset_admin.sync (sidecars + masked data file) |
| Cold storage / delete | dataset_lifecycle.archive_create / delete (hard requires mdm_disposition) |
Measured against the release named in the text. Raw Markdown: /ontology/documentation/datasets-analysis-transforms.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 →