Released docs. You are viewing the documentation published with v0.46.0. Development docs are available at Latest.
If your Base Registry Engine (BReg) registry needs changes beyond field-by-field edits, declare them as Actions. Here you see what an Action declares, when it applies at once and when it becomes a reviewed Proposal, and how a Plan computes its effects. Change a registry with an Action runs both.
Start from the facility template
Section titled “Start from the facility template”bregctl init --template facility-registry facilitybregctl check facilityThe template declares three Actions: register-facility, correct-address, and
deactivate-facility; bregctl explain actions facility shows each one compiled.
What an Action declares
Section titled “What an Action declares”An Action has typed inputs, an execution mode, a plan
of effects, and optional commitGuards. deactivate-facility holds all four:
- id: deactivate-facility display: label: Deactivate facility description: Submit a durable deactivation that requires no external review. execution: mode: proposal proposal: review: {type: none} application: {mode: manual} retention: {mode: retain} commitGuards: targets: - {input: facility, revision: unchanged} - {input: facility, field: status, equals: active} inputs: - {id: facility, apiName: facilityId, type: reference, target: facility, required: true, classification: internal} plan: type: fixed effects: - id: facility-status target: {fromInput: facility} operation: patch set: status: {value: inactive}Commit guards are checked when the change commits: here, the facility must be unchanged since the Proposal froze it, and still active. The caller never chooses the execution mode.
Who may run an Action is an access-profile grant, invoke for an immediate Action and start
for a Proposal:
actions: - action: correct-address operations: [start]Other Proposal operations, such as submit, cancel, or apply, are granted separately under
permissions.proposals, so whoever drafts a change need not apply it.
The Action grant also declares targets. Every input that references an existing Record needs
current target authority, including a reference used only as a link in a newly created Record.
When two inputs reference the same Record type, BReg checks the target row boundaries against each
referenced Record independently. An in boundary therefore succeeds only when the array claim
covers both Records; authority over one does not authorize the other.
From a matching source checkout, run
bregctl dev start products/breg/fixtures/multi-reference-array-claim
to exercise the permitted and refused cases with local clients.
Immediate Actions return an ActionReceipt
Section titled “Immediate Actions return an ActionReceipt”register-facility declares execution: {mode: immediate}. One request checks the guards,
writes every effect, and commits the new revisions, the receipt, the audit entry, and any outbox
events together, or none of them. The answer is an
ActionReceipt naming each changed Record and its new revision.
Before invocation, use the caller-filtered Action descriptor to identify concurrency conditions.
requiredConditionKeys contains the API names of existing write targets and inputs with an
unchanged revision guard. When that list is nonempty, routes.targetConditions advertises the
endpoint that reads their current condition tokens. Send its returned preconditions unchanged
with the invocation. A reference used only as a link still needs target authority, but it is not a
condition input. When requiredConditionKeys is empty, omit preconditions.
The immediate Action API contract gives the request
rules.
A Record type can require a Proposal for an operation:
mutationPolicy: patch: proposal-requiredWith this on facility, neither a direct patch nor an immediate Action may patch a facility; only
a Proposal can. register-facility still creates facilities at once.
Proposals
Section titled “Proposals”An Action in proposal mode creates a Proposal instead.
correct-address requires review:
execution: mode: proposal proposal: review: type: required authority: casework source: facility-registryA Proposal starts as a draft its author can edit. Submitting it freezes the inputs, the
computed effects and their digest, the target revisions, and the Action revision; review and
application work on that frozen submission, so a later change to the Plan or policy cannot
reinterpret it. Revise or Rebase returns it to a new draft, which must be submitted, and
reviewed, again.
A Proposal ends in one of three states:
applied: the registry wrote the frozen effects, under the commit guards as they stand at that moment. With no review it follows submission; with required review it needs current approval of that exact submission.rejected: the review authority rejected the submission. This is final. A reviewer who wants another attempt returns it with changes requested instead, which keeps itsubmittedand offers Revise.cancelled: a caller with thecancelgrant withdrew it before it applied.
Application is automatic, under a restricted system grant for that one submission, unless the
Action declares application: {mode: manual}, as deactivate-facility does; then a caller with
the apply grant applies it. The Proposal’s applicationStatus reports progress: awaiting-review, pending,
applying while a worker is writing it, then applied, or blocked with a reason and a
recovery hint.
Review authorities, declared twice
Section titled “Review authorities, declared twice”The project names each review authority it relies on:
reviewAuthorities: - id: casework protocol: id.registrystack.org/protocols/review/v1 display: label: Casework review authority description: Logical authenticated review authority resolved by deployment configuration.The deployment binds that id to a running service. For local development, the template’s
README gives the dev-clients.yaml binding:
reviewAuthorities: casework: endpoint: http://127.0.0.1:8100/ profile: requester producerId: facility-registry recoveryDays: 30 client: requesterIn production the same map sits in the runtime configuration (runtime.yaml), with a tokenRef
or privateKeyJwt credential instead of client. A missing binding disables only the operations
that need it. An unreachable authority never counts as approval.
Registry Casework is one such authority. The registry sends it the frozen submission and applies only the correlated result; Review a Proposal in Casework pairs the two.
Plans and Evidence
Section titled “Plans and Evidence”A Plan is fixed, like deactivate-facility’s, or computed
by a Rhai Function. correct-address names its Function and bounds what it may write:
plan: type: function function: correct-address-plan inputs: [facility, address-line, city, postal-code] writes: - id: facility-address target: {fromInput: facility} operation: patch fields: [address-line, city, postal-code] refusals: - {code: invalid-postal-code, label: Postal code is invalid}The project’s functions entry names its script:
fn plan(ctx) { let postal_code = ctx.inputs["postal-code"]; postal_code.trim(); if postal_code == "" { return #{ refusal: #{ code: "invalid-postal-code", field: "postal-code" } }; }The planner receives ctx.inputs, holding only the inputs the Plan lists. It returns either a
refusal, whose code the Action declares, or effects: a list of maps, each with the id of a
declared write and its set or clear fields. The declaration fixes each write’s target and
operation, so the script cannot redirect one. Omitting a write skips it; the caller still needs
authority over its target.
Effects apply in authored order. A value fromEffect must name an earlier create, as
register-facility’s assignment names its new facility. Two effects that land on the same Record
are written together as one revision; two effects that write the same field fail bregctl check.
An Action with a Rhai Plan may also declare evidence: at most two capabilities, each naming an
Evidence provider the project declares, a requirement, its subjects, and the outputs it may read.
The script calls evidence::resolve("<capability id>", subjects) once per capability and
receives only those outputs; a failed call refuses the operation. commitGuards.evidence
instead checks a requirement at commit and never changes the effects. The provider’s endpoint and
credentials belong to the runtime configuration; BReg inherits no Evidence authorization.
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.