Skip to content
Registry StackDocsv0.25.0

Publish and consume a Registry Discovery index

For the assertion provider and data publisher and operator and consumer or verifier

View as Markdown

Build a local Registry Discovery index from exact Evidence Gateway and Registry Relay publication bytes, resolve and select one record for each product, then verify both selections through the maintained native clients and adopter-owned trust.

Outcome
One immutable local index, exact Evidence and Relay selections, and two direct native client handoffs.
Time
About 15 minutes after the Rust dependencies are available
Level
Local development with synthetic data
Prerequisites
GitRust 1.95.0 through rustupPython 3curlshasumBashLocal ports 38080 and 38090

Use a clean checkout. The tutorial compiles the two Discovery binaries from the locked workspace, starts only loopback services, and creates its authoring project in a temporary directory.

Terminal window
git clone --depth 1 --quiet https://github.com/registrystack/registry-stack.git
cd registry-stack
test -f products/discovery/scripts/test-adopter-tutorial.sh
printf 'checkout ready\n'

The final two commands report:

checkout ready

The Evidence assertion provider and Relay data publisher each contribute one closed, public JSON-LD description. Confirm the exact bytes supplied by the checkout.

Terminal window
shasum -a 256 \
products/discovery/fixtures/descriptions/evidence.jsonld \
products/discovery/fixtures/descriptions/relay.jsonld
fc96f3a8cb0d82239425ea5712dceca975a5899e5528616648174da661fae905 products/discovery/fixtures/descriptions/evidence.jsonld
5a34fa469803b7c28b3d5e7134a42398e326a2f173aacae9090d29787bc8f4d7 products/discovery/fixtures/descriptions/relay.jsonld

The fixture bytes are deterministic examples of the same closed profile the two native products derive and package. A provider deploys the exact packaged file at its public description URL; the Discovery runtime does not reconstruct provider metadata.

The operator owns an explicit list of provider description URLs. Local HTTP is enabled only for this loopback tutorial.

Terminal window
sed -n '1,80p' products/discovery/tutorial/project/origins.yaml
schemaVersion: registry-discovery/origins/v1alpha1
origins:
- originId: tutorial-evidence
catalogUrl: http://127.0.0.1:38090/evidence.jsonld
profile: registry-discovery-v1alpha1
enabled: true
- originId: tutorial-relay
catalogUrl: http://127.0.0.1:38090/relay.jsonld
profile: registry-discovery-v1alpha1
enabled: true

The operator also owns the mapping from an application requirement to one Evidence type.

Terminal window
sed -n '1,80p' products/discovery/tutorial/project/mappings/adult-status.yaml
schemaVersion: registry-discovery/evidence-mapping/v1alpha1
mappingId: urn:example:mapping:adult-status
mappingAuthorityId: urn:example:mapping-authority
requirementId: urn:example:requirement:adult-status
jurisdiction: urn:example:jurisdiction
alternatives:
- evidenceTypeListId: urn:example:evidence-type-list:adult-status
evidenceTypeIds:
- urn:example:evidence-type:adult-status

discoveryctl check validates these authoring files without contacting either URL. The later explicit build is the only step that fetches the enabled origins.

Run the product-owned reader journey. The script builds discovery and discoveryctl, copies the operator project into a fresh temporary directory, checks it before starting the provider, performs one explicit build, waits for readiness, and calls the real resolve and search routes.

Terminal window
bash products/discovery/scripts/test-adopter-tutorial.sh

The output ends with these role-oriented results. Revision and record digests are stable for the checked-in semantic inputs.

[checkout] building discovery and discoveryctl from locked source
[provider] evidence.jsonld sha256=fc96f3a8cb0d82239425ea5712dceca975a5899e5528616648174da661fae905
[provider] relay.jsonld sha256=5a34fa469803b7c28b3d5e7134a42398e326a2f173aacae9090d29787bc8f4d7
[operator] offline check: valid origins=2 mappings=1
[operator] explicit build: built catalogRevision=sha256:b4b7195f36691c245bf49a88a248049ed899c0c41dbf1a87a386571c0dbfba0f mappingRevision=sha256:332004ca3920c498539180946e8f2637e9998ba7e49cd98f31e19d6f818857ac
[operator] readiness: {"status":"ready"}
[consumer] resolved evidenceType=urn:example:evidence-type:adult-status alternatives=1
[consumer] selected evidence recordId=urn:registrystack:discovery:record:sha256:676659c10ce5cc9d353f4fd2816673c7947e612151efbbe1cc4d42372d9be9d5
[consumer] selected relay recordId=urn:registrystack:discovery:record:sha256:aa220c11f493c266bc22adf5dc7ca82fb7a83842e6e887dc0e8e5680f4f84244
[handoff] adopter-owned Evidence trust accepted; native assertion verified
[handoff] adopter-owned Relay trust accepted; native list response verified
[cleanup] local services stopped; temporary project removed
Registry Discovery adopter tutorial: PASS

The consumer first resolves the requirement and chooses one complete Evidence Type alternative. Each alternative is an AND-list, so the consumer searches and explicitly chooses one provider for every required type. It separately searches one correlated Relay semantic-class and operation-family tuple and records one exact Relay result. The saved typed selections contain public metadata, complete resolution context, capability matches, and revision provenance only. Rust, Node.js, and Python applications perform the same workflow through their maintained Discovery client binding.

The final two handoff checks revalidate each persisted selection, then repeat the exact-selection boundary against publications derived by the native products. The adopter’s existing Evidence and Relay trust configurations must accept a saved selection before a credential is created or a native request is sent. The maintained Evidence client uses the selected requirement and Evidence Type with the adopter’s native request policy, then requests and verifies an assertion directly. The maintained Relay client uses native metadata to map the selected public tuple to a concrete operation, then reads a collection directly. Discovery is stopped before those direct calls.

RoleMaintained inputChange triggerHandoff
Assertion providerPackaged Evidence public descriptionPublic Evidence endpoint, profile, evidence type, or issuer role changesPublish the exact packaged bytes at the approved URL
Data publisherPackaged Relay public descriptionPublic Relay endpoint, profile, semantic class, operation family, or authority role changesPublish the exact sealed artifact bytes at the approved URL
Operatororigins.yaml, mapping files, immutable index, and runtime.yamlAn approved origin or mapping changesRun offline check, explicit build, deploy the complete index, then restart Discovery
Consumer or verifierSaved exact selection and native product trustA catalog revision, mapping revision, origin digest, binding, or local trust decision changesRe-evaluate local trust, then call the selected native endpoint directly

The operator does not run a synchronization scheduler or maintain a writable catalog. A failed build does not replace the deployed index. Deploy a complete new index and restart the process when the change is intentional.

The runner stops Discovery and the publication server and removes the temporary project on success, failure, or Ctrl+C. The compiled binaries remain under target/discovery-tutorial-source so a second run can reuse them. The runner’s final cleanup line confirms that neither loopback service remains active.

  • The provider roles supplied two deterministic public descriptions.
  • The operator checked explicit origins and mappings offline, built one immutable index, started Discovery, and waited for {"status":"ready"}.
  • The consumer resolved one Evidence requirement and made exact Evidence and Relay selections.
  • The verifier applied adopter-owned native trust and used the existing clients without routing credentials, native requests, or responses through Discovery.
SymptomCauseFix
The publication server or Discovery stops before readinessPort 38090 or 38080 is already in useStop the process using the port, then run the tutorial again
Cargo cannot resolve dependenciesThe clean checkout has not acquired the locked Rust dependenciesRestore network access to the Cargo registry or provide a populated Cargo cache
A publication digest differsThe provider bytes do not match the tutorial’s reviewed fixtureRestore the clean checkout or review the changed publication before indexing it
Native handoff is refusedThe selected binding does not match the adopter-owned product trust recordKeep the selection inert, correct the local trust decision, and retry the native handoff