Preview release.These docs are a work in progress. Pages are still being written, links may break, and structure may shift without notice. Treat everything here as a draft and report issues onGitHub.
Configure an exact snapshot materialization
Use this guide when Registry Relay must query an immutable local materialization instead of
opening a source connection for each consultation.
You will declare one logical entity, bind its physical source once in the private
environment, and reuse the published snapshot for a governed records API and exact snapshot
consultations.
When to use this
Section titled “When to use this”Use snapshot for an exact key lookup over a separately ingested local snapshot.
The consultation reports materialized_snapshot provenance and does not open a registry
connection during the request.
Background ingest can acquire more data than one consultation. Record the complete materialization footprint and do not describe snapshot publication time as source observation time.
Before you start
Section titled “Before you start”You need:
- A Registry Stack project with an immutable CSV, XLSX, or other supported snapshot source.
- A logical entity schema and stable primary key.
- A private provider path and one physical column for every logical field.
- Reviewed records API scopes, purposes, filters, pagination, relationships, and aggregates.
Keep provider paths, worksheet or table names, and physical columns out of public entity and integration files.
Try the bundled snapshot starter
Section titled “Try the bundled snapshot starter”The starter proves an exact lookup over an immutable local materialization. Its offline fixture does not open a source connection.
Run these commands in order. The focused test prints a safe synthetic trace. The next command starts the same fixture as a watch smoke; press Ctrl+C after its initial passing report. The final three commands test every fixture, explain the redacted plan, and build the unsigned product inputs.
snapshot: Exact snapshot
An exact lookup over one immutable local materialization.
registryctl init --from snapshot --project-dir snapshot-project
registryctl test --project-dir snapshot-project --integration person-snapshot --fixture snapshot-match --trace
registryctl test --project-dir snapshot-project --integration person-snapshot --fixture snapshot-match --watch
registryctl test --project-dir snapshot-project
registryctl check --project-dir snapshot-project --environment local --explain
registryctl build --project-dir snapshot-project --environment localGenerated from the five starter workspaces compiled into registryctl.
Define the logical entity
Section titled “Define the logical entity”Create entities/people.yaml with logical names only:
version: 1id: peoplerevision: 1primary_key: person_idschema: type: object additionalProperties: false required: [person_id, registration_status, eligible] properties: person_id: { type: string, maxLength: 64 } registration_status: { type: [string, "null"], maxLength: 32 } eligible: { type: [boolean, "null"] }materialization: max_records: 1000000 max_bytes: 256MiB refresh: manual retain_generations: 2The entity owns the reusable logical schema and bounded materialization footprint.
It rejects physical provider, path, table, worksheet, and column members. A records service is
optional and does not change the entity used by snapshot.
Add the records service
Section titled “Add the records service”Reference the entity and configure its optional records service in registry-stack.yaml:
entities: people: { file: entities/people.yaml }services: people-records: kind: records_api entity: people title: Population records sensitivity: personal access_rights: restricted update_frequency: daily api: scopes: metadata: people:metadata rows: people:rows purposes: [case-management] projection: [person_id, registration_status, eligible] pagination: { default_limit: 50, max_limit: 100 } filters: person_id: [eq] registration_status: [eq] required_principal_filters: [person_id] standards: { ogc_features: false, sp_dci: false }This records service is the Relay-owned records API exposure of people. It preserves only its
declared scopes, purposes, projection, filters, pagination, relationships, aggregates, and
standards adapters.
Define the exact snapshot integration
Section titled “Define the exact snapshot integration”Create an integration that refers to logical entity fields:
version: 1id: population-person-snapshotrevision: 1input: person_id: role: selector type: string maxLength: 12 pattern: "^PER-[0-9]{8}$"capability: snapshot: entity: people exact: person_id: { input: person_id } freshness: 24houtputs: [registration_status, eligible]The snapshot capability applies the complete exact selector to one immutable published handle and probes at
most two rows.
Two matches return ambiguous; Registry Relay does not choose one.
Add an evidence service and consultation in registry-stack.yaml, mapping person_id from one
declared request identifier. This Notary-owned service defines its service policy, claims,
disclosure, and optional credential profiles. Claims can select only the integration’s closed
outputs through their authored output field.
Bind the physical source once
Section titled “Bind the physical source once”In environments/<environment>.yaml, bind the logical entity to its private provider:
entities: people: provider: type: csv path: /var/lib/registry/population.csv header_row: 1 columns: person_id: subject_key registration_status: status_code eligible: benefit_eligible source_revision: population-export-v1 generation: 2026-07-12Every logical field has one physical column, and physical columns must be unique.
Change generation when the provider or mapping changes.
registryctl build emits one ingest plan and one materialization identity.
The records service and compatible snapshot profiles capture the same published handle
instead of creating another source path or copying the physical mapping.
Verify shared materialization
Section titled “Verify shared materialization”Run the fixtures, semantic check, and build:
registryctl test --project-dir <project>registryctl check \ --project-dir <project> \ --environment <environment> \ --explainregistryctl build \ --project-dir <project> \ --environment <environment>The test and build JSON reports contain "status": "passed" and "status": "built".
The human-readable check report marks the project valid.
Confirm that the explanation names one logical materialization and that no reviewable integration
pack or consultation contract contains the provider path or physical column names.
If the snapshot is absent, stale, or does not match the active generation and digest, only the dependent profiles become unready. Registry Relay does not fall back to live source access.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Cause | Fix |
|---|---|---|
| The entity schema rejects a provider or column | Physical mapping was placed in the public definition. | Move the provider and columns into the environment entity binding. |
| The environment rejects duplicate columns | Two logical fields map to one physical column. | Provide an injective physical mapping. |
| A provider change is rejected | The mapping changed without a new generation. | Advance the generation and repeat operator-security review. |
| Only snapshot profiles are unready | The shared materialization is missing, stale, or inconsistent. | Publish and verify the expected immutable generation without enabling live fallback. |
- Return to Author an HTTP Registry Stack project for the ordinary review and unsigned-build workflow.
- Use Configure a script source adapter only for a reviewed live HTTP recipe that declarative operations cannot express maintainably.