Skip to content

Orgabot is in private alpha. Request access, or join our Discord.

← All documentation
Reference

Deployment topology

Choose where each Orgabot capability runs - local, a cloud provider, or a supported hybrid - and see the resolved answer, its provenance, and the custody boundaries it crosses.

What this is

Orgabot is local-first, and a fresh install is local-only: everything runs on your machine and no cloud account is involved. Deployment topology is the decision underneath that default - which provider serves each of ten capabilities, and where each one runs.

You do not have to make that decision. If you never create the configuration file, every capability resolves to its local default. This page is for the point where you want one thing somewhere else: a database that survives the laptop, a webhook URL that works when you are on a coffee-shop network, or GitHub Actions holding the authoritative test suite instead of your CPU.

See the resolved answer

orgabot topology

It prints one line per capability: the provider serving it, where that provider runs, whose account holds its data, and what chose it - a built-in default, a reference profile, or an explicit line in your configuration. That last column is the one that matters when something surprises you.

Two more views:

orgabot topology --matrix      every capability, every provider, and its status
orgabot topology --profiles    the reference topologies and what each is for

The same answer appears on the dashboard's System tab, and a closed-schema summary of it travels in the redacted support bundle.

orgabot topology is read-only. A placement changes by editing the file below, never by a command flag, because a one-token way to relocate an install's data is not a feature.

The ten capabilities

CapabilityWhat it owns
state_storeThe operational store and configuration documents
secret_custodyConnector credentials, tokens, and keys
artifact_storeMission logs, worker transcripts, produced artifacts
durable_runtimeThe workflow runtime that makes a killed process resumable
control_planeThe dashboard, the API, and your actions
mission_executionWorkers in isolated worktrees
verification_runnerThe suite that produces exit-code evidence
ingressInbound signed webhook deliveries
scheduled_dutiesRecurring duties and background passes
backupA restorable copy of state and artifacts

The full matrix, including every provider's requirements, readiness signal, and migration boundary, is generated from the code into docs/deployment-capability-matrix.md in the repository.

Configuring it

~/.orgabot/deployment.json. Everything in it is optional.

{
  "profile": "hybrid_ci_verification",
  "capabilities": {
    "verification_runner": "github_actions"
  },
  "settings": {
    "ingress": { "publicUrl": "https://hooks.example.com/orgabot" }
  },
  "acknowledgedDataMovement": ["verification_runner:mission_execution"]
}
  • `profile` names a reference topology to start from. Every capability it sets can still be overridden line by line below it.
  • `capabilities` selects a provider per capability. This wins over the profile.
  • `settings` carries the per-provider configuration a provider requires. It never carries a credential: requirements that need one take a secret handle, which the broker resolves under its own permission model. A connection string with a password in it does not belong in this file.
  • `acknowledgedDataMovement` is explained below.

If the file does not exist, you get local-only defaults. If it exists and cannot be read, parsed, or validated, Orgabot refuses to resolve a topology at all rather than falling back to those defaults. Treating an unreadable file as an absent one would resolve a local install for someone who had pointed Orgabot at a managed database, which is the exact silent relocation this contract exists to prevent. An unknown key is refused for the same reason: "capabilties" parses fine and would discard everything under it.

Custody boundaries

Placement says where compute runs. Custody says whose account holds the bytes, and those are different: GitHub Actions is cloud placement under GitHub's custody, not your cloud account's.

Orgabot will not cross a custody boundary silently. When a capability depends on another whose custody differs, resolution refuses until your configuration names that exact edge:

unacknowledged_data_movement  verification_runner ("github_actions", third party)
  reads mission_execution ("local_worktrees", workstation) ... add
  "verification_runner:mission_execution" to acknowledgedDataMovement to accept it

The acknowledgement is per edge on purpose. A blanket opt-out would accept every future boundary too, including one introduced by a provider you added months later for an unrelated reason.

What is available today

Every local provider is implemented. The hosted foundation also implements managed PostgreSQL, cloud secret custody, object storage, a managed-container control plane, and GitHub Actions verification. Providers marked planned in the matrix remain contracts rather than implementations. Selecting one is refused, and the refusal names the issue that owns it:

provider_not_implemented  durable_runtime provider "managed_restate" is declared
  but not implemented in this build; issue #1270 owns its contract

Artifact storage has a provider-neutral contract with two backends behind it - local disk and object storage - and one conformance suite both pass. What each artifact class IS (whether a failed write is data loss, how long it is kept, and whether it may leave this machine at all) is written down rather than decided per call site, and a new file-backed artifact that nobody classified fails the test suite.

Object storage is selectable. Classified artifact writers route through the configured store, and local disk and object storage pass the same conformance contract. Managed PostgreSQL and the managed-container control plane are also selectable and form the data/control-plane core of an isolated hosted tenant.

The operational-store contract has the same shape behind SQLite and PostgreSQL, and one conformance suite runs against both real engines. The SQLite half runs in every npm test; the PostgreSQL half needs a database you are willing to throw away, named by ORGABOT_TEST_POSTGRES_URL, and runs with npm run test:postgres from framework/. It refuses to start without that variable rather than passing on the skipped half. A hosted deployment reads its store from ORGABOT_DATABASE_URL and starts only when that is a PostgreSQL URL; it never opens a local SQLite file or a JSON compatibility file as a fallback. The hosted control plane serves the dashboard page, GET /api/state, GET /api/state/head and the GET /api/stream change stream from that store, through the same buildDashboard, the same stream hub and the same browser code the local dashboard uses. The page carries a read credential derived one-way from the deployment's bearer token, never the bearer itself, and sets it as an HttpOnly, SameSite=Strict cookie so the browser's own fetches and its change-stream EventSource authenticate without a header. That credential authenticates GET and HEAD only, from the page-token header or the cookie; replayed as an Authorization: Bearer value it authorizes nothing, so a hosted page observes the tenant and cannot act. Only the deployment bearer on the Authorization header reaches a mutation route. Reads cover the domains the store holds; file-backed local state such as the project registry is absent until its own cutover, and stream delivery adds the feed mirror's poll interval (250 ms by default) to the store's own latency.

Secret custody is fully implemented on every platform: the macOS keychain, the Linux Secret Service, Windows DPAPI, and opt-in remote custody in your own cloud secret manager. See Connectors and tools.

Another non-local provider that works today is github_actions for verification_runner, which is why hybrid_ci_verification is the cheapest hybrid to adopt. It has one precondition Orgabot cannot observe from the topology alone - the project must actually nominate CI as its pre-ship verification authority, which a repository that merely runs Actions has not done. orgabot topology lists that as a precondition with the command that checks it, rather than reporting it as satisfied.

The generated matrix is the authority for the remaining boundary. The complete cloud_only reference profile is still not runnable because managed Restate, cloud sandbox mission execution, managed edge ingress, managed scheduling, and managed backup remain planned. Supported hybrid profiles can use the hosted pieces without pretending those remaining providers exist.

Is ingress actually working?

orgabot github ingress

It answers with evidence rather than a tick: one signed delivery, verified at this receiver, over a named transport, at a stated time. An install whose ingress verified an hour ago and is down now reads as "last verified an hour ago", because that is what is true.

It also reports refusals with their reason. An endpoint that is reachable and verifies nothing (a wrong webhook secret) looks identical to one nobody is sending to in any report that only counts accepted deliveries, and those have different repairs.

If you have not connected a webhook at all, it says so plainly: Orgabot reconciles GitHub state by polling instead, which is slower and bounded by the API rate limit. That is a supported mode, not a fault.

  • Invariants - the safety properties that hold regardless of where a capability runs.
  • Architecture - the mission control loop the capabilities serve.