Skip to content
Registry StackDocsLatest

Author an HTTP Registry Stack project

View as Markdown

Create a Registry Stack project with a bounded HTTP integration without editing product source code. You will copy the built-in starter, prove its synthetic journey offline, inspect the bounded acquisition and disclosure plan, and build separate unsigned inputs for Registry Relay and Registry Notary.

One project defines one registry trust domain. A deployment can use Relay only for governed materialization and records APIs, Notary only for source-free or self-attested evidence, or both products for registry-backed consultations and claims derived from Relay outputs. Independent registries require separate projects.

Outcome
A tested project workspace with reviewable bounded HTTP configuration and unsigned Relay and Notary Config Bundle inputs.
Time
About 10 minutes after registryctl is installed
Level
Local authoring with synthetic fixtures
Prerequisites
A registryctl build with project authoring commandsA shell and a text editor

This tutorial uses a fictional registry and synthetic records. Do not add source credentials, production endpoints, or real subject records.

Use this compact sequence as the workflow checklist. The sections that follow explain each command and the trust boundary it verifies.

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.

http: Custom HTTP

One fixed bounded HTTP request with a closed response projection.

registryctl init --from http --project-dir http-project
registryctl test --project-dir http-project --integration person-record --fixture active-person --trace
registryctl test --project-dir http-project --integration person-record --fixture active-person --watch
registryctl test --project-dir http-project
registryctl check --project-dir http-project --environment local --explain
registryctl build --project-dir http-project --environment local

Generated from the five starter workspaces compiled into registryctl.

Create a local project workspace:

Terminal window
registryctl init --from http --project-dir registry-project

The JSON report contains:

"status": "initialized",
"explanation": {
"id": "http",
"release": "0.10.0",
"state": "matches"
}

The copied registry-stack.yaml keeps the complete starter provenance, including its authored-content digest. Later, check --explain reports whether the workspace still matches that starter or has intentionally diverged.

The command creates this authored layout:

registry-project/
registry-stack.yaml
integrations/
person-record/
integration.yaml
fixtures/
environments/
local.yaml

The starter is copied into your workspace. Registry Stack does not resolve a remote package or download integration code at runtime.

Run one matching fixture and include its safe synthetic trace before changing the source contract:

Terminal window
registryctl test \
--project-dir registry-project \
--integration person-record \
--fixture active-person \
--trace

The JSON report identifies the selected fixture, typed input, source call, minimized output, claim results, and derived security cases. Its primary fixture contains:

{
"integration": "person-record",
"fixture": "active-person",
"inputs": ["person_id"],
"calls": ["request"],
"outputs": ["active"],
"claims": ["person-active", "person-record-exists"],
"outcome": "match",
"passed": true
}

The same report includes derived malformed-decoding, byte-ceiling, timeout, authorization-before-source, and output-minimization cases. The command does not contact Registry Relay, Registry Notary, or a source registry.

Keep the same fixture running while you edit the project:

Terminal window
registryctl test \
--project-dir registry-project \
--integration person-record \
--fixture active-person \
--watch

The command prints PASS: 1/1 fixtures passed, waits for an authored file to change, then reruns the selected fixture. Use the preceding non-watch command for the full trace. Press Ctrl+C after you confirm the initial pass. The watcher ignores generated .registry-stack output and never enables live source access.

For this synthetic journey, make these exact substitutions with your editor:

FileFieldReplaceWith
registry-stack.yamlregistry.idfictional-citizen-registryfictional-civic-support-registry
integrations/person-record/integration.yamlsource.productreplace-with-source-productfictional-civic-support-api
integrations/person-record/integration.yamlsource.versions.unverified[replace-with-source-version][tutorial-contract-v2]
environments/local.yamlsource.originhttps://citizen-registry.invalidhttps://civic-support.invalid

These values remain fictional and .invalid destinations cannot identify a live service. They do not alter the request shape proved by the starter fixtures. When you later change a method, path, query, header, or body, update each affected fixture’s expected interaction so the test proves the new canonical request.

For an actual integration, review all four authored surfaces and replace the fictional contract with approved project values:

  1. In registry-stack.yaml, name the registry, service, purpose, caller scopes, consultation input mapping, outputs, claims, disclosure modes, and credential claim allow-list.
  2. In integrations/person-record/integration.yaml, define selector and parameter input schemas, one fixed HTTP request, output pointers and schemas, cardinality, and any limit override proven necessary by fixtures.
  3. In integrations/person-record/fixtures/, replace the synthetic interactions and expected outputs and claims. Each fixture proves the canonical request as well as the response.
  4. In environments/local.yaml, bind the non-production source destination, secret references, caller fingerprints, Relay trust, and deployment services.

The integration fixes the method, path, input placement, minimized output fields, and bounds before deployment. The environment binds the one logical source origin and credentials. Consultation inputs can populate only declared request values. They cannot select an origin, method, credential, capability, projection, or response mapper.

An existing project can add another protocol view over the same logical source without starting a second project or copying generated product configuration. Use a stable integration id such as benefit-record, then add these authored files and references:

  1. Create integrations/benefit-record/integration.yaml and integrations/benefit-record/fixtures/. Add adapter.rhai and any reviewed local modules only when the integration uses capability.script.
  2. Add integrations.benefit-record.file: integrations/benefit-record/integration.yaml to registry-stack.yaml.
  3. Under the consuming evidence service, add a consultation with integration: benefit-record and bind every integration input to one typed request path. Add claims that select or derive from that consultation’s declared outputs.
  4. Add integrations.benefit-record.source to environments/local.yaml with its non-production origin, credential reference, and generation. Do not put credential values in the project files.

Run the new fixture first, then the complete offline and generated-config gates:

Terminal window
registryctl test --project-dir . --integration benefit-record --fixture <fixture-name> --trace
registryctl test --project-dir .
registryctl check --project-dir . --environment local --explain
registryctl build --project-dir . --environment local

The project model allows multiple integrations only when they are reviewed views over the same logical source trust domain. Start a separate project for an independent registry authority.

Use source.product as review metadata for the source system. It does not select a product executor or runtime capability. Mark a source version unverified until the required integration evidence exists.

Test every edited fixture, including match, no-match, ambiguity, source-shape, and derived security cases:

Terminal window
registryctl test --project-dir registry-project

The report must again contain:

"status": "passed"

Failures identify the authored file and fixture. A fixture can supply bounded source observations, but it cannot supply a destination, credential, worker command, authentication bypass, or decoder mode.

Compile the authored project through the Relay and Notary validators without writing build output:

Terminal window
registryctl check \
--project-dir registry-project \
--environment local \
--explain

The human-readable review report starts with:

Registry Stack project: fictional-citizen-registry (valid)
Environment: local
Baseline: initial_without_baseline

Review the fixed request authority, input mappings, caller scopes, purpose, outputs, claims, disclosure modes, and credential membership. Use --format json only when another tool needs the machine-readable report. An initial project without an approved baseline requires the claim, integration, service_policy, operator_security, and disclosure review classes. A valid report is not legal approval, source interoperability evidence, or deployment authority.

Generate deterministic unsigned product inputs for the existing Config Bundle v1 workflow:

Terminal window
registryctl build \
--project-dir registry-project \
--environment local

The JSON report contains:

"status": "built"

The output root contains:

registry-project/.registry-stack/build/local/
reviewable/
integration-packs/
consultation-contracts/
review.json
private/
relay/
config/relay.yaml
approval/review.json
notary/
config/notary.yaml
approval/review.json

The product input directories remain separate and contain secret references, not secret values. They are inputs to each product’s Config Bundle workflow, not a signed project root or a deployable bundle. build does not create a bundle manifest, sign a bundle, or read a secret value. Package, sign, verify, and activate each product directory through that product’s Config Bundle workflow. One signed project-level deployment bundle whose root binds compatible product submanifests is future work; the current CLI does not emit that artifact. Treat every generated directory as institutionally sensitive and keep it out of source control.

Keep registry-project/ as the authored project workspace. If you do not need the generated inputs, remove only registry-project/.registry-stack/build/local/. You can reproduce that directory with the same build command.

You copied a local HTTP starter, proved its positive and denial fixtures without source access, adapted the reviewed source contract, inspected the complete redacted plan, and generated separate unsigned Relay and Notary inputs. The generated profile keeps source acquisition in Relay and claim disclosure in Notary.

SymptomCauseFix
project destination must be absent or an empty real directoryinit found content, a non-directory, or a symlink.Choose an absent or empty real directory.
input.pattern_mismatchA fixture input does not satisfy the declared type or pattern.Correct the synthetic fixture or the reviewed input contract.
A fixture request proof differs from the traceThe expected interaction does not match the canonical request produced by the integration.Correct the integration or update the wholly synthetic interaction proof.
--against and --anchor must be supplied togetherOnly one approved-baseline argument was present.Supply the verified bundle and matching trust anchor together.
Generated configuration fails validationAuthored fields cannot produce a valid Relay or Notary startup contract.Correct the reported authored file and field, then rerun test and check.