Unreleased documentation. These pages follow the main branch and can change before the next release. For supported guidance, use v0.39.0.
A chat host, the application a citizen chats with, can help that citizen correct their own record
in a Base Registry Engine (BReg) without ever holding the power to change it. Two supporting
services make that possible: breg-mcp, the Model Context Protocol (MCP) gateway the chat host
calls, and breg-review, the page where the citizen reads and submits what the assistant
prepared. In this tutorial you run both against a local registry and watch one address correction
travel from a chat tool call to an applied change.
The run is maintained as a script in the repository. It is verified on macOS on Apple Silicon; no continuous integration job runs it.
Before you start
Section titled “Before you start”Clone the repository and confirm the script is present:
git clone --depth 1 --quiet https://github.com/registrystack/registry-stack.gitcd registry-stacktest -x products/breg/acceptance/citizen-address-correction/run-local.shprintf 'checkout ready\n'The last command reports:
checkout readyThe repository pins its Rust toolchain in rust-toolchain.toml, so rustup installs Rust 1.95.0
the first time cargo runs in the checkout. If another cargo comes first on your PATH, such as
one from Homebrew, put ~/.cargo/bin ahead of it for the commands in this tutorial.
Know what runs
Section titled “Know what runs”The script starts five parties on loopback addresses. Three of them are real, one is a test server, and one is a stub:
| Party | What runs |
|---|---|
| Base Registry Engine | The synthetic citizen address correction project on PostgreSQL 17 |
| Authorization server | A test server that issues the chat host’s token, performs the gateway’s token exchange, and signs the citizen in to the review page |
| Gateway | The breg-mcp binary |
| Review page | The breg-review binary |
| Review authority | A stub standing in for Registry Casework, which serves one approval |
The driver program plays the remaining roles: the chat host calling MCP tools, the citizen’s browser on the review page, and the registry staff member who applies the approved change. All names, identifiers, and addresses in the project are invented.
Run the journey
Section titled “Run the journey”From the repository root, run the script:
products/breg/acceptance/citizen-address-correction/run-local.shThe script starts a disposable postgres:17 container on a loopback port, builds breg-mcp,
breg-review, and the driver, and then runs the journey. The first build compiles the workspace
dependencies and takes most of the run. Cargo’s progress lines appear between the build: line
and the registry: line; they are left out here. Ports and identifiers differ on every run:
postgres: a disposable postgres:17 container is ready on 127.0.0.1:<port>build: breg-mcp, breg-review, and the local run driverregistry: the acceptance project is served on PostgreSQL at http://127.0.0.1:<port>authorization server: the test server issues at http://127.0.0.1:<port>breg-mcp: started, logging to <work-directory>/breg-mcp.logbreg-review: started, logging to <work-directory>/breg-review.logbreg-mcp: ready at http://127.0.0.1:<gateway-port>/readybreg-review: ready at http://127.0.0.1:<page-port>/readyregistry: seeded a person, their address, and their self-service linkgateway: the chat host connected over MCP at http://127.0.0.1:<gateway-port>/mcptool describe_service: answeredtool get_my_details: the current address is 4 Mill Streettool start_application: application <application-id> is preparedtool update_application: the locality is now Old Towntool prepare_review: the review link is http://127.0.0.1:<page-port>/requests/<application-id>review page: the citizen signed in through the authorization serverreview page: GET http://127.0.0.1:<page-port>/requests/<application-id> 200 OK, showing 4 Mill Street beside Old Townreview page: POST http://127.0.0.1:<page-port>/requests/<application-id>/submit 200 OKtool get_application_status: submittedregistry: the stored address is still 4 Mill Streetreview authority (stub standing in for Casework): approvedtool get_application_status: submitted (the agent profile reads no review outcome)registry: the applier applied the approved proposaltool get_application_status: appliedtool get_my_details: the current address is 2 Quay, Old Townregistry: the stored address is 2 Quay, Old Town, PS-200local run: the citizen journey reached appliedThe script exits with status 0 after the last line. It prints no credential.
Read what happened
Section titled “Read what happened”The chat host never held a registry credential. It sent its own access token to the gateway, and for every tool call the gateway exchanged that token at the authorization server for a delegated registry token naming the citizen as subject and the gateway as actor. The chat host’s token never reached the registry.
The chat host never named the record it wanted to change. start_application took only the
proposed address fields; the gateway found the citizen’s own linked address through the registry
and wrote the application’s target and owner itself.
The chat host could draft, but not decide. The gateway’s registry access profile is a standing
agent, and the registry compiler refuses such a profile any submit, direct write, or immediate
action. prepare_review returned a link and nothing more; the submission happened on the review
page, under the citizen’s own sign-in, after the page read the current address beside the
proposed one.
The review authority decided, and registry staff applied. Between the approval and the apply,
get_application_status still answered submitted: the agent profile cannot read the review
outcome, so the chat host learns the result only once the change is applied.
Clean up
Section titled “Clean up”The script removes what it created when it exits. On success it removes the PostgreSQL container and the temporary work directory that held both runtime configurations, their generated keys, and the two logs. On failure it still removes the container, keeps the work directory for diagnosis, and prints its path on standard error:
the run failed; the binaries' logs and configuration stay in <work-directory>Remove that directory when you are done with it. The build output stays in target/; run
cargo clean to reclaim the disk space.
To run the journey against a PostgreSQL 17 server you already have, set BREG_TEST_DATABASE_URL
before you run the script. The script then creates a fresh database on that server and drops it at
the end, and starts no container.
Point BREG_TEST_DATABASE_URL only at a disposable server. The run creates and drops databases on
it.
- Configure the citizen chat assistant to write both runtime configurations and prepare your authorization server.
- Operate the citizen chat assistant to run both services behind your proxy.
- Configure BReg to learn how standing agent access profiles are declared.