0061 — Support context and development broker provisioning
Status: Accepted. Date: 7 October 2026. Broker provisioning superseded by decision 0046 on 21 October 2026.
21 October 2026. The Support context and its link rules stand. Its broker provisioning below does not: Support now follows decision 0046. Its broker roles, queues and permissions are generated from
contracts/support/messaging/broker.jsonandservices/beto/contracts/subscriptions.jsonintoservices/beto/services/topology/permissions.generated.json, and the administration process provisions them;contracts/events/topology/beto.json, the Goamqp.Planand theimport_definitionsstep are gone. The.deadretention policy is not carried over; dead letters are replayed with main's replay tool. The text below is kept as the record of the original decision.
Beto owns the Support context. Its SupportCustomer aggregate, keyed by the
Pharos user ID, links each Pharos user to a customer in the support service
(today Zammad, whose user ID stays an opaque binding). The flow follows the Miro
frame "Final create user in support service flow simple method": a link is
pending, linked, failed (support service unreachable, retried) or conflict
(email owned by another Pharos user, or HTTP 422; a person resolves it and the
retry after 24 hours picks the fix up). A support-retry CronJob retries links
with no attempt limit; unresolvedSince feeds an age alert instead.
Support is the first context with broker delivery inside a cluster. Beto's composition root therefore lists contexts, delivery contexts and realtime contexts separately, as Metallo does. Support has delivery and no realtime projection.
Runtime broker users have no topology or administration rights. Each delivery
context gets a pharos_<owner> user: configure ^$; write only its delivery
exchange and pharos.events; read only ref.<owner>.*; topic permissions to
publish only domain|integration.<owner>.* and read its own private events plus
public ones. Development provisioning imports these users as salted SHA-256
hashes, their permissions, the topology and Support's .dead retention policy
(7 days, 10,000 messages, oldest dropped) with one rabbitmqctl import_definitions
read from stdin into a private broker-local file. This reuses the mechanism of
the hello-world decision on feat/metallo-hello-world (its 0002, not yet merged);
the two scripts should merge, and this record renumbered, when that branch lands.
The broker topology is declared once, in Beto's Go amqp.Plan. Declare uses it
and topology -definitions prints it; pnpm generate:contracts writes
contracts/events/topology/beto.json, which provisioning imports. A Go test fails
when the committed file or the Go catalogue drifts from the code and the shared
contracts/events/catalogue.json.
Only support.customer_link_requested is published: mandatory routing would
block the outbox for an event without a consumer. Linked, conflict and failure
outcomes are aggregate state until something consumes them. No UserCreated
event exists yet, so a development-only Beto endpoint stands in for it.
Page source
Source snapshot · Revision f928834c8.