Unreleased documentation. These pages follow the main branch and can change before the next release. For supported guidance, use v0.46.0.
If you are building a registry service on Registry Stack and ask “this rule or step, where do I put it?”, find its kind in the table, then follow the link to the product that holds it. Each kind of logic has one home, and each home declares its own interface.
Three things to know first
Section titled “Three things to know first”- There is no single cross-product operation grammar. A field rule, an Action plan, a hook, a workflow step, an Adapter route and a message template are each written in the notation of the product that owns them. Rhai appears in several products, but each product gives it its own inputs, helper functions and limits.
- Two products publish machine-readable operation catalogues. The Registry Coordinator
operation catalogue lists every versioned operation a workflow can call, with schemas, effect
class, idempotency key, recovery and receipt mode. The Registry Adapter effective contract lists
the operations one loaded Adapter exposes to a gateway. Neither covers the other products’ own
configuration, which each product’s schemas and
explainoutput describe. - Logic implemented outside the stack follows one pattern. Put it behind an Adapter facade
route and call it from a workflow through
external.command/v1(a POST that changes something) orexternal.get/v1(a read).
Where each kind of logic goes
Section titled “Where each kind of logic goes”Base Registry Engine (BReg) holds the rules that must hold whenever a record changes. The other products hold what happens around a record.
| Kind of logic | Holder and mechanism | Interface it declares | Machine-readable catalogue |
|---|---|---|---|
| Field validation and patterns | BReg Record type fields: type, bounds, vocabulary, required, and a pattern in PostgreSQL’s regular-expression syntax. An Action input can carry a pattern too. | The field declaration in registry.yaml | registry-project.schema.json; bregctl explain. A pattern is enforced by the database and is not published in the generated JSON Schema or OpenAPI. |
| Preconditions on current data | BReg Action requires and commitGuards, checked inside the transaction | Guard entries on the Action | bregctl explain actions |
| Derived values | BReg generated identifiers (generate on a string field) and live derived fields (reviewed SQL compiled to a read-only view) | The field declaration | registry-project.schema.json |
| Rates, thresholds and other parameters that change over time | BReg Record type with temporal validity, one record per period, changed through an Action (a Proposal Action when a change needs review). A plan cannot read stored records, so a workflow reads the record in force with breg.read-in-force/v1 and passes the values to the Action as inputs. | The Record type and the Action that changes it | registry-project.schema.json; generated/operations/catalog.json |
| Calculation and branching in an Action | BReg Action plan: fixed, a Rhai Function, or a Wasm Function | Typed Action inputs, declared write slots and declared refusal codes; Function ABI registry.action-plan/v1 | bregctl generate actions writes the action-contracts/v1 document |
| Record timers | BReg Record type timers, enabled by the root project’s timerGrants; each timer invokes one non-public immediate Action | The timer declaration on the Record type | registry-project.schema.json; a timer-only Action has no portable Action contract |
| Events and webhooks | BReg hooks: a url, rhai or wasm handler that runs after commit; local handlers use ABI registry.hook-handler/v1 | trigger, projection and optional when on the hook | bregctl explain events; generated/event-schemas/proposal-lifecycle.schema.json |
| Review, then apply | BReg Proposal Action (execution.mode: proposal); Casework supplies the review | The Action’s review and application declarations | bregctl generate actions |
| Multi-step or cross-product process | Registry Coordinator workflow.yaml: call, choose, wait-until, wait-for and finish steps, with pure Rhai Functions | Typed workflow input and named finishes | generated/operations/catalog.json and the generated project schema |
| Calls to systems outside the stack | Adapter pack routes (reviewed, in Camel route YAML, with Rhai mapping scripts), bound to a profile by a project and served as a facade | The profile’s operations | The Adapter effective contract |
| Answering a question about a person or record for another service | Registry Evidence: an AssertionDefinition, a Source bound to an Adapter pack route, and a derivation Function | The public Requirement URI, purpose and subject selectors | generated/evidence-definitions-v1.schema.json and the generated OpenAPI |
| Documents and certificates | Registry Render (Typst template bundle, byte-stable PDF) and the Registry Document Store (custody and release of a verified version) | Render: template bundle and record data. Document Store: document policy and grants | render/schemas/bundle.schema.json; the Document Store project schema and event schemas |
| Case steps | Registry Casework ReviewPolicy: stages, queues, outcomes and routing rules | The policy in casework.yaml | generated/project/project.schema.json; caseworkctl explain |
| Notifications | Registry Messaging: versioned templates with a JSON Schema each, providers and sender profiles | The template’s input schema | generated/authoring/template.schema.json; messagingctl generate templates |
| Appointments | Registry Scheduling policy: offerings, holds and bookings, with four observer triggers | The policy | generated/project/project.schema.json; schedulingctl explain |
Choosing a plan for an Action
Section titled “Choosing a plan for an Action”Start with a fixed plan, which writes declared values and needs no code. Move to a Rhai Function
when a value must be calculated from the inputs or the Action must decline for a stated reason. A
Wasm Function takes the same plan contract for logic written in another language, with narrower
rules: it reads only the declared inputs, calls no Evidence resolver, and cannot serve a Proposal
Action. All three produce effects only through write slots the compiler admitted, so a script
cannot reach a target, field or operation the project did not declare.
A plan runs only when its Action is invoked, and the Action context carries no trusted calendar date. If a rule must not be bypassed, withhold the ordinary create profile that could write the same state without the Action. The details are in Actions and Proposals.
Logic outside the stack
Section titled “Logic outside the stack”When a rule lives in another system, such as a licensing authority’s calculation service, the stack has no plugin mechanism to host it. Write an Adapter pack route that calls the system, and serve it as a facade route. The Adapter keeps the source credentials, an audit journal and an idempotency store for writes. A workflow then calls the route through one of two operations:
external.get/v1reads. The connection lists exact paths and a required response schema.external.command/v1sends one POST to the single relative path configured on the connection. The workflow supplies only the JSON body, and the alias’sinterpretFunction turns the reply intoaccepted,refusedoruncertain. Every attempt carries the same stored body and the sameIdempotency-Key, so the receiving route must deduplicate on that header.
Coordinator does not verify the provider’s effect, and neither operation takes an arbitrary method or a destination chosen at run time. The effective contract of the Adapter lists only operations it can serve as reads to a gateway; a write the facade serves appears there as unserved. The Coordinator catalogue therefore remains the place to see what a workflow can call, and the Adapter product page describes packs, profiles and facade routes.
Cookies on Registry Stack
We use optional cookies to understand how you use the main Registry Stack website and this documentation. If you contact us, we may link this activity to your enquiry. You can change your choice at any time. Read the privacy policy.
Your browser asks sites not to track you, so optional tracking stays off.
We could not use or save that choice. Optional tracking remains off.