# Add a context 1. Decide its owning service, business language, aggregate boundary and command/ query outcomes. Create `services//contexts/` with domain, application and driving/driven adaptor modules. The domain has no technology imports. A co-located context has independent database authority. 2. Register `{ "owner": "", "service": "" }` in `contracts/contexts.json`. A read-only context without owned storage declares `"persistence": "none"`; it needs no database or migration manifest. Site-local SQLite contexts declare `"persistence": "sqlite"` and own their private journals without platform PostgreSQL credentials or migration enrolment. PostgreSQL contexts retain the default mode and add a migration manifest and SQL under `adaptors/persistence/migrations`. Runtime credentials cannot migrate schemas. Provision its database with the shared baseline schema and a restricted role, then apply `scripts/migrate.py`; schema checks reject owner/checksum mismatch. Beto also applies its service-owned delivery migration before the context migrations. Storage-free registrations stay outside this enrolment. A Beto context without broker contracts, events or subscriptions declares `"messaging": "none"`; it receives no broker user or credential. 3. Add context-specific typed Protobuf payloads, independent application DTOs, event metadata in `contracts/events/catalogue.json`, and the owning service's transport payload encoder/decoder. Root envelopes stay business-neutral. Declare Beto request contracts in `contracts/beto/messaging/catalogue.json` with the owner's `queries` file `pharos//v1/queries.proto`, its `commands` file `pharos//v1/commands.proto` (either may be `null`, not both) and their binding consumers (`api` and/or `metallo`). Declared owners must differ even with underscores removed, since generated Go names drop them: `model2` and `model_2` would both generate `Model2Query` and `model2v1`. The contract is split by role: `requests.proto` holds the `Request`, `Query`, `Command` and `Reply` wrappers and `RequestError`; `queries.proto` the query inputs; `replies.proto` what queries return; and `commands.proto` the commands. Each file declares `package pharos..v1` and `go_package` `github.com/pharos-ai-factory/pharos-platform/services/beto/contracts/requests/generated/pharos//v1;v1`, with underscores dropped from the final `v1`. Generation checks both and that each file holds exactly its role's messages. The files must exist under `contracts//messaging/proto/` and in no other context's proto root, and an undeclared role file is refused. Number a new owner's envelope this way: the request's `command = 10` and `query = 11`; the reply's `outcome = 10`, `error = 11` and results from 12; and each wrapper's alternatives from 10. Existing Project and Party Governance envelopes retain their field numbers; their frozen wire fixtures qualify compatibility separately. A declared contract generates Beto and API bindings before registration and receives no broker authority. A registered owner with requests names them and their callers in `contracts//messaging/broker.json`; each kind needs its declared file and no caller is implied. Governance authenticates RabbitMQ `UserId` against generated owner-specific policies. Only the API may carry actors or use private authentication/provider-binding protocols; `allow_actor` defaults to false. Production callers remain API-only until downstream enrolment is reviewed and qualified. Regenerate and review the scoped topology permissions. Host provisioning reads the generated `runtime_bindings`; caller `pharos_` uses `_BROKER_URL`. Add each binding to the projected Secret of Argo's broker provision Job; `beto_broker_deployment.py` checks the list. Prove allowed delivery and refused authority. In Beto, generate command/query values, responses and owner mappings from annotated Protobuf. Declare private events in the service's event catalogue and consumers in `services/beto/contracts/subscriptions.json`. The generator produces typed event codecs, subscription names, paired command queues and replay membership. See the [Beto adaptor map](../services/beto/adaptors/README.md). 4. Add a typed browser projection, its registered encoder and scoped gateway publisher credential only when the UI needs live state. Persist exact bytes and revision atomically; register server-side channel authorisation and owner reconciliation queries before mounting the feature. In Metallo, explicitly register `None` for an internal aggregate whose browser feature is deferred; persistence then saves its state and receipts without realtime rows. Unknown projection registrations remain errors. Beto and Themelio handlers explicitly publish through `RealtimeBusPort`; their requested snapshot or rejection must match committed state or recorded outcome. 5. Compose its ports, driving adaptors and workers in the service's `services` folder. Keep DI registrations here and inject plain ports into application handlers. Go persistence uses `support.Open("")` and explicit consumer binding; Python uses its owning service's context/subscription registry. Themelio uses Dependency Injector under `services/composition`; extend its empty contract generator before registering the first context. Its service-local delivery migrations are applied by the administrator. See the [Themelio scaffold guide](../services/themelio/README.md). No foreign implementation import or synchronous second-root command is permitted. Beto commands use `services/commandregistration` and a handler factory with a per-invocation owner write repository. The shared transaction owns receipts, version checks and outgoing intent. Integration publication and durable command reactions run through their declared subscribers. List each Beto owner whose request worker the binary composes, with its request kinds, in `services/beto/services/beto/di/owners.json`. Broker generation and provisioning refuse a registered owner with requests that the file does not list, and a listed owner that is not registered; a DI test checks the file against the composed workers. 6. When a browser feature needs access, explicitly bind its public route in the API, keeping its backend key separate from browser credentials. A Beto owner's HTTP translation is enrolled in [`services/api/adaptors/http/mappings/.json`](../services/api/adaptors/http/mappings/README.md); it needs the owner's catalogue entry for `api` and creates no route. The enrolment check also runs Party Governance's existing specialised generator. Add workload secret references, restricted broker topic permissions, the administrator-only topology bootstrap and exact NetworkPolicy edges. No database or broker admin key enters an application. 7. Regenerate contracts/checksum metadata, add owner-native behaviour tests and real transaction/delivery/recovery tests, then run all applicable lanes from `TESTING.md`. Add browser multi-window/history-gap tests for live projections. The skeleton deliberately makes registration explicit. A new folder or catalogue entry alone grants no routes, queue, credential, publisher, subscription or business authority. ### API command bindings Declare each POST route and its JSON schema in the owner's HTTP contract. Register a `CommandBinding` using the API's independently generated owner request/reply types. It reads `{id}`, `Idempotency-Key`, `If-Match`, optional `X-Correlation-ID` and the validated JSON body. The API supplies the authenticated session subject (or the separate provisioned CLI actor) as `actor_id`; headers/body cannot choose it. The typed request uses a fresh transport ID on every attempt while retaining the command ID. Owner errors and committed outcomes map to HTTP status codes. `RouteCommandBinding` also serves DELETE routes without a body, builders that read other route values, and creates named by their `Idempotency-Key` (`KeyTarget`). Queries that check member access carry the same subject in `QueryMetadata`. Beto validates actor metadata and exposes it as `CommandContext.ActorID` to the handler. Authorisation remains owner policy. Present actors contribute to the idempotency fingerprint; changing actor produces a conflict. Empty actors are reserved for trusted internal/legacy commands and convey no user authority. Project's published request surface remains query-only; technical fixtures exercise this public command path.