Skip to main content
Version: v5.7.0

The GUI Operations area

Included from Basic tier

The GUI's Operations area (Administration, /admin) is the operator console: one tab set covering the deployment, the runner and agent fleets, emergency controls, licence, maintenance, identity and the operational event stream. It is operational admin only: the governance feature surfaces (controls, review campaigns, evidence ledger, waivers, classification register, notification mandates + delivery evidence) live under the GUI's own /governance route, gated by pack entitlement and governance roles rather than admin status. The GUI is developed in a separate repository but ships inside the opschain binary; this page covers how it is served and maps each panel to the server endpoints that feed it and to the component page that explains the behaviour behind it — read those pages for semantics, this one to find them.

Serving: the embedded GUI at the root origin​

The server embeds a vendored snapshot of the GUI's production bundle (refreshed by make vendor-gui, provenance in the snapshot's manifest.json) and serves it at /: one download, one process, one port, with the API under /api on the same origin — no CORS, no proxy, no version skew (the gui block on GET /api/admin/status and the overview names the exact GUI commit the binary carries).

  • Precedence: /api/*, /healthz, /readyz, /metrics, /logs/tail, the /admin/* operational endpoints and the /opschain.runner.* / /opschain.agent.* RPC services always win; every other unknown path serves index.html, so client-side routes (e.g. /admin/runners) deep-link correctly. Fingerprinted /assets/* are served immutable (long-cache); index.html and version.json are no-cache so a new release is picked up on reload.
  • gui.enabled (config.yaml, default true in every posture): false stops serving the GUI for deployments that front it separately; unknown root paths then 404 exactly as before the GUI was embedded. See opschain docs config.
  • A build vendored with no snapshot serves a one-page "GUI not bundled" notice at / instead of a bare 404.

Access: the tabs show for superusers (or an admin-rule probe of the admin surface); maintenance, triggers, artifacts and settings screens ride path RBAC rather than the admin gate. The admin routes return plain JSON, not JSON:API. The GUI's /admin/* screen routes share exact paths with the server's unprefixed admin support endpoints; a browser navigation (no bearer, HTML Accept) to one of those paths serves the SPA rather than the endpoint's 401, so refreshes and deep links into the admin screens work (see opschain docs cli/admin-status).

Panel map​

PanelWhat it showsFed byComponent page
Overview (/admin)The whole deployment on one screen: server card, runner-group cards with per-group demand, agents card, unsatisfiable-queue card, halt/licence/maintenance bannersGET /api/admin/overview (snapshot), composed from the same truths as GET /api/admin/status, GET /api/runners, GET /api/runner_groups (+ /{name}/demand), GET /api/fleet/queue, GET /api/agents, GET /api/platform/postureopschain docs dispatch, opschain docs runner-registry, opschain docs agent-plane
Emergency controls (on Overview)The two-plane halt console: posture, reason, suspended attempts, resume. The estate-wide system quiesce is its own panel on the Server and Database pagesGET /api/platform/posture, POST /api/platform/halt, POST /api/platform/resume, POST /api/platform/halt/attemptsopschain docs platform-halt
Runners (/admin/runners)Runner groups and members with derived STATE (stopped/draining/quiesced/ready), a Capacity column (the runner's declared max_parallel_steps; unlimited when undeclared), drain/resume/forget verbs, the fleet-queue backlog with placement verdicts and a run-scoped chip on an entry whose run pins to one runner (its scope_source in the tooltip); New group… in the toolbar and Edit group… on every group row open the group dialog (below), and a group that exists only as a token name offers Store group… with the name pre-filledGET /api/runners, GET /api/runners/{id}, POST /api/runners/{id}/drain|resume|forget, GET /api/runner_groups, PUT/DELETE /api/runner_groups/{name}, POST /api/runner_groups/{name}/drain|resume, GET /api/runner_groups/{name}/demand, GET /api/fleet/queue, POST /api/fleet/quiesce|drain|resumeopschain docs runner-registry, opschain docs fleet-queue, opschain docs runner
Runner group dialog (on Runners)Create or edit a runner group's placement contract: description, the Exclusive switch, the placement attributes as key/value rows (keys offered from the registered vocabulary, a key's enumerated values offered as its allowed list) and the node-path bindings one absolute path per line; the dialog states that saving replaces the whole definition (attributes and bindings left out are removed), names a duplicated key before anything is sent, and renders the server's refusals verbatim — the unregistered key, the value outside the allowed list, the non-absolute binding, the invalid name and the runner-group licence limit on a new nameRunnerService.UpsertRunnerGroup, RunnerService.ListRunnerAttributesopschain docs cli/admin-runner-group-set, opschain docs fleet-queue
Placement attributes (panel on Runners)The registered placement attribute keys with their allowed values ((any) when unrestricted) and the reserved tag on location and network; Set attribute registers a key or replaces its allowed values wholesale (an empty list lifts the restriction), Remove takes a key out of the vocabulary behind a confirmation — the reserved-key refusal and the invalid-key refusal render verbatimRunnerService.ListRunnerAttributes, RunnerService.PutRunnerAttribute, RunnerService.DeleteRunnerAttributeopschain docs cli/admin-runner-attributes-set, opschain docs cli/admin-runner-attributes-remove
Server nodes (panel on Runners)The server nodes currently held by a quiesce posture (node, who quiesced it, since when) beside the answering node's own stable server name and held/serving chip; Quiesce server node… takes the node's stable server name, arms on a type-to-confirm of that name and names what drains (readiness, job offers, scheduler shards, cron leadership and membership, the in-flight run drives peers adopt) and that the posture survives restarts until Resume; Resume per held row — the not-quiesced refusal renders verbatimRunnerService.ListServerNodes, RunnerService.QuiesceServerNode, RunnerService.ResumeServerNodeopschain docs cli/admin-server-node-quiesce, opschain docs cli/admin-server-node-resume, opschain docs cli/admin-server-node-list
Sites (panel on Runners)The sites currently held by a quiesce posture (site, who quiesced it, since when) beside the answering node's own site identity (none without one) and held/serving chip; Quiesce site… takes the site identity, arms on a type-to-confirm and names the failover (every node carrying the identity drains; the site's runners fail over to their next configured server; the surviving site claims the site's location-pinned steps; only the site's servers are touched); Resume per held row — the not-quiesced refusal renders verbatimRunnerService.ListSitePostures, RunnerService.QuiesceSite, RunnerService.ResumeSiteopschain docs cli/admin-server-site-quiesce, opschain docs cli/admin-server-site-resume, opschain docs cli/admin-server-site-list
Asset versions by environment (dashboard panel, Personal tab; and the Versions by environment view of the project's Assets page only — the Table / Versions by environment switch beside the toolbar — at /projects/<code>/assets/versions)Which version each asset runs in each environment: every asset of the project as a row — the project-level assets first, listed under the environment - with the cell showing the template version they are on — every environment of the project as a column, the pinned template:version in each cell with locked / floating / archived / refresh badges, drift tinted against a chosen baseline column (the right-most environment by default), a "N of M assets differ" summary counted over the environment-scoped rows alone (a project-level asset has one cell and cannot drift, so it is in the table but not in the count), CSV export on the Assets page view (- in the environment column for a project-level asset). An environment's Assets page shows the table only, with no view switch. The dashboard panel shows the same rows, project-level assets included, and opens the project's viewEnvironmentService.ListEnvironments, AssetService.ListAssets for the project and per environment, TemplateService.ListTemplates (full view) — E + 3 reads per project, assembled in the browseropschain docs resources/template
Git remotes (Operations tab)Per-remote fetch health from the periodic sweep: totals (remotes, due now, failing, repins in 24 h), rows sorted failing-first — last fetched, outcome badge, consecutive failures with the masked last error, next fetch, floating versions, last repin; failures link to the audit history filtered to error:git_remote:fetch on the projectGitRemoteService.SummarizeGitRemoteHealth (admin read)opschain docs resources/git_remote
Infrastructure (dashboard panel, Personal tab; hidden without packs:infrastructure)The inventory summary per scope: a type × lifecycle-state matrix with archived separate, and an exceptions strip — stale facts, duplicate addresses, unused, destroyed-but-present, recently changed — each count opening the Infrastructure page pre-filtered to exactly the counted rowsInfrastructureService.SummarizeInfrastructure (one read per selected project, estate-wide when none)opschain docs infrastructure-nodes
Agents (dashboard panel, Personal tab; hidden without packs:agents)The agents enrolled in this estate under the scope: counts by tier, stale agents, agents over a token cap, owners who departed, agents without an owner — each opening Governance → Agents → Posture filtered to exactly the counted rowsAgentPostureService.ListAgentPosture (one read per selected project, estate-wide when none)opschain docs agent-posture
Registration tokens (panel on Runners and Agents)Minted runner/agent registration tokens: scope, uses, expiry, derived status; mint dialog showing the token onceGET /api/registration_tokens?kind=runner|agent, POST /api/registration_tokensopschain docs runner-registry, opschain docs agent-plane
Server (/admin/server)Build/replicas/leader, readiness checks, the System quiesce panel and active changes — single-responsibility: the replicas table carries the server-computed live/stale split and defaults to live + recently-dead rows with a show-all toggle, and a queue-depth line links to the Queue page (which owns the dispatch view; licence and the support bundle live on their own pages too). The System quiesce panel shows the estate-wide posture (phase, reason, who started it, the attempts a drain is waiting out) and carries its verbs: start with a required reason, abort a still-draining quiesce, resume (the only exit — there is no automatic resume)GET /api/admin/status, GET /readyz, GET /api/admin/changes/active; PlatformService.GetSystemQuiesce|StartSystemQuiesce|AbortSystemQuiesce|ResumeSystemQuiesceopschain docs dispatch, opschain docs cli/admin-platform-quiesce, opschain docs cli/admin-platform-resume
Diagnostics (/admin/diagnostics)The support-bundle download (redacted tar.gz) and the service-manager stop note — moved off the Server pageGET /api/admin/support_bundleopschain docs support-bundle
Licence online verification (/admin/licence, Online verification panel)Each stored online-enforcement licence document's phone-home state per installation — the licence service, the verify cadence, the last outcome (ok, current, revoked, error, no_credential), when it last verified, the next scheduled check, consecutive failures and the last error; Verify now forces a round immediately and reports each installation's outcome, the server's refusal verbatim; a server with no online documents says there is nothing to verifyLicenceService.GetLicenceStatus (online_verification), LicenceService.TriggerVerificationopschain docs cli/admin-licence-verify, opschain docs cli/admin-licence-show
Configuration (/admin/config)The config.yaml surface, exclusively: the full documented key catalog with set/default state (secrets redacted), a read-only file view, and a compose-and-download assist with server-side validation — never a write-back pathGET /api/admin/config, POST /api/admin/config/validateopschain docs config
Settings (/admin/settings)The runtime, database-authoritative settings editor (CAS by version) with history/diff. The Global config section carries a Rate limits block with one row per family: Secrets providers — the estate default secrets.default_rate_limit per lane (reads per second, token mints per minute), each showing its stored value or "Unlimited" when unset, editable in place, a lane left blank removed from the document; Inbound webhooks — the estate default webhooks.default_rate_per_minute as a choice of "Built-in default (60/min)" (the key absent) / "Unlimited" (-1 on the document) / "Custom budget", with the current value stated ("Currently 120/min"); API requests — the v2 request limiter (api.rate_limit.enabled, requests_per_minute, burst, max_concurrent_streams) rendered read-only from the config catalog ("Requests per minute per principal: 600 (burst 600)", "Concurrent streams per principal: 25", or "Off — api.rate_limit.enabled is false") with the note that it is set in the server configuration (config.yaml, deploy-authoritative) and a link to the server configuration page; Model providers — the line that no rate limit applies, token and spend budgets living on the model provider dashboards (linked)GET /api/system_configuration, GET/PATCH /api/settings/{id}, GET /api/settings/{id}/versions[/{version}], GET /api/admin/config (the read-only API row)opschain docs settings, opschain docs settings-reference
Agents (/admin/agents)The agent fleet: online/channel/halt state, drain/halt/forget/revoke verbs, trust summary and activity in the detail drawerGET /api/agents, GET /api/agents/{id}, POST /api/agents/{id}/drain|resume|forget|revoke|halt, POST /api/agents/{id}/halt/resume, plus the trust and activity readsopschain docs agent-plane
SIEM connections (/admin/siem, record at /admin/siem/{code})The SIEM forwarder registry: every connection with its kind (splunk_hec, syslog, otlp_http), target, event filter, whether a receiver token is stored (never the token), live delivery health and enabled state; create/edit dialogs mirroring the CLI's flags, delete behind a type-to-confirm arm, and the Test verb — one synthetic event through the real formatter and sender, the outcome shown inline on the record page; the record links to the connection's usage dashboardSiemService.ListSiemConnections|GetSiemConnection|CreateSiemConnection|UpdateSiemConnection|DeleteSiemConnection|TestSiemConnectionopschain docs integrations-siem
GitHub (/admin/github; Connections and Trust policies tabs)The GitHub App connections (host, App and installation ids, OIDC audience, the pinned private-key reference, the allowed mint scope, webhook ingestion state with the provisioning dialog that shows the generated signing secret once — its request budget a choice of Inherit estate default (webhooks.default_rate_per_minute, shown resolved) / Unlimited / Custom — health from the last test) and the trust policies that hang off them (claim predicates, service account, token TTL, the scope prefix clamp); create/edit/delete and enable toggles on both, the Test verb on connectionsGitHubIntegrationService.List|Get|Create|Update|Delete|TestGitHubConnection, …ProvisionGitHubWebhook, …List|Get|Create|Update|DeleteGitHubTrustPolicyopschain docs integrations-github
JSM (/admin/jsm, record at /admin/jsm/{code})The Jira Service Management connections: every connection with its authentication style (Atlassian cloud account email + API token, or a Jira Data Center personal access token sent as a bearer), base URL, project-key scope, whether a credential is pinned (the vault reference, never the token), Jira webhook ingestion state with the provisioning dialog that shows the generated signing secret once (its request budget a choice of Inherit estate default — webhooks.default_rate_per_minute, shown resolved — / Unlimited / Custom), health from the last test and the enabled toggle; a record page per connection (also the providers dashboard's "Open record") with its fields, the last test, the Test verb's outcome inline and the link to its usage dashboard; create/edit dialogs mirroring the CLI's flags with the API token / PAT write-only (an inline token is vaulted server-side, or an existing secret-vault:// reference is pinned); delete behind a type-to-confirm arm. Creating or enabling a connection, provisioning its webhook and every outbound write need the integrations:jira-service-management entitlement and show the refusal as the server states itJsmIntegrationService.List|Get|Create|Update|Delete|TestJsmConnection, …ProvisionJsmWebhookopschain docs integrations-jsm, cli/admin-jsm-connections
Service desk (a change's page, Service desk tab)The service desk requests bound to the change: the jsm:request / jira:issue typed references on its governance block with system, relationship, last update and the ticket link, and the audited write verbs on each — Comment (always a JSM internal note), Transition (by name or id, optional note), Set fields (labels to add/remove and a key/value field editor that builds the issue-edit JSON) and Resolve (the resolving transition plus evidence links; records the typed reference on this change's governance block and posts the evidence comment); Resolve a request… on the panel takes a request not yet bound. Verbs show for administrators and sit behind the integrations:jira-service-management entitlement; a refusal is shown as the server states itJsmIntegrationService.ListJsmRequestLinks, …CreateJsmRequestComment, …TransitionJsmRequest, …SetJsmRequestFields, …ResolveJsmRequestopschain docs integrations-jsm, cli/admin-jsm-requests
Inbound webhooks (/admin/inbound-webhooks)The generic inbound webhook connections (/api/hooks/<code>): every connection with its service account, replay window, request budget, whether a signing secret is stored, enabled state and hinted Git remote; create (the secret minted in the browser and revealed once), rotate, edit, enable/disable and delete. The "Rate limit (requests per minute)" field offers "Inherit estate default" (sends 0, the create default) / "Unlimited" (sends -1) / "Custom budget" (1–6000), with the resolved estate default webhooks.default_rate_per_minute shown ("Estate default: 60/min", "Estate default: unlimited"); the list renders the replay window beside the budget as "300s · 120/min", "300s · unlimited" or "300s · estate default"InboundWebhookService.List|Get|Create|Update|DeleteInboundWebhookConnection, GET /api/system_configuration (the estate default)opschain docs inbound-webhooks
Secrets providers (/admin/secrets_providers)The secrets-provider registry and the scope bindings that route secret-vault:// resolution by node position: every provider with its kind, address, auth method, KV version, resolution locus (server or runner — the chip reads server when the record carries no value, the API default), whether a credential is stored (a runner-resolved provider reads "held by runners": the server stores none, each runner carries it in the secrets_providers section of its own config.yaml), health from the last Test probe, the platform-vault badge and the enabled toggle; register/edit dialogs mirroring the CLI's flags with the credential write-only and the Resolution field gating it — choosing runner removes the credential inputs, moving a stored provider to runner warns inline that its credential is cleared, moving one back to server requires the credential in the same write — and the server's field violations rendered verbatim; delete behind a type-to-confirm arm, the Test verb, and the bindings panel (set a scope path to a provider, delete, the estate-default label)SecretsProviderService.ListSecretsProviders|CreateSecretsProvider|UpdateSecretsProvider|DeleteSecretsProvider|TestSecretsProvider, …ListSecretsProviderBindings|SetSecretsProviderBinding|DeleteSecretsProviderBindingopschain docs secrets-providers
Model providers (/admin/model_providers)The model-provider catalog: every provider with its code, kind, endpoint, credential presence (never the value), data-handling marker and enabled state; the register/edit dialog carries the kind's fields, the credential custody toggle, the TLS trust fields and a Token budget group — the provider-level model budget, one row per window (sliding minute, day, week, month, fiscal quarter, fiscal year), each Unlimited or Custom with the ceiling in tokens; Unlimited sends 0 (no ceiling), a negative value is refused verbatimModelProviderService.ListModelProviders, CreateModelProvider, UpdateModelProvider, DeleteModelProvideropschain docs model-providers, opschain docs cli/admin-model-providers
Model provider dashboard (/admin/providers/model/<code>)Beside the provider's token rows, a Provider ceiling block with one gauge per budget window the record sets — spend against ceiling, the fraction and the local boundary the window resets at (amber from the warning fraction, red at the ceiling) — read off the usage response's token_budget; absent while the record sets no ceiling. The Agent token caps panel below it (previously titled Budgets) shows the caps of the agents bound to the provider read-only, with one line naming where a cap is set — the agent's trust grant — and a link to it; the provider's own ceiling lives on the recordModelUsageService.ListProviderUsage (token_budget), AgentPostureService.ListAgentPostureopschain docs model-providers, opschain docs cli/admin-providers-usage
Model budgets (Administration → Model providers → Budgets tab, /admin/model_providers?tab=budgets)The one-pane estate view of allocated model budgets: one row per provider with the tokens per day allocated across its agents' trust grants, the spend today, the headroom, the provider's own day ceiling and an over-allocated marker when the grants together exceed that ceiling; a row expands to one line per agent and per grant with the same three numbers and a link to the grant. Grouping and sums happen in the browser; shown under packs:agents (or the agents feature) with the model-usage featureAgentPostureService.ListAgentPosture (caps and spend per agent), ModelProviderService.ListModelProvidersopschain docs model-providers, opschain docs agent-posture
Model budgets (dashboard panel, Personal tab; gated like the Model tokens and Agents panels)The per-provider allocated / spent / headroom totals and the agents nearest their cap, opening the Budgets tab aboveAgentPostureService.ListAgentPosture, ModelProviderService.ListModelProvidersopschain docs model-providers
Provider usage export (/admin/providers overview and the model provider dashboard /admin/providers/model/<code>)Export CSV downloads the model-usage export — one row per bucket, provider, model, project, agent and grant with the calendar columns, rows rolled under a previous calendar flagged calendar_superseded — over the dashboard's current range at its grain (the overview exports the dashboards' default window: the last 30 days by day); the export is the model lane's, so it is offered on the overview with no family filter or the model family selected and on a model provider's dashboard only; a refusal lands in the toast verbatimModelUsageService.ExportModelUsageopschain docs cli/agents-usage (-o csv), opschain docs cli/admin-providers-usage
Agent trust (Governance → Agents → Trust tab, and the Grant/Approve/Reject/Revoke verbs on each agent's sheet)What an agent may do: the grants with subject, scope, tier, actions, caps and approval state (write a grant, approve or reject a pending proposal, revoke; while an approval policy holds the raise for the Inbox, Approve and Reject are disabled with the reason — waiting on you, or not an approver and whom it waits on — and the row links the Inbox row), the assets-under-management assignments (assign, unassign), the per-type tier ceilings and the node-classification ceiling rules (set, replace, remove) — the reads for any governance role, the verbs for an administrator, ceiling writes on the step-up floorTrustService.ListTrustGrants|ApproveTrustGrant|RejectTrustGrant|ListTrustAssignments|CreateTrustAssignment|DeleteTrustAssignment; POST /api/trust/grants, POST /api/trust/grants/{id}/revoke, GET /api/trust/ceilings, PUT /api/trust/ceilings/{type}, POST/PUT/DELETE /api/trust/ceilings/nodes[/{id}]opschain docs agent-plane, opschain docs cli/admin-trust
Maintenance (/admin/maintenance)The estate console for maintenance windows: active/scheduled/ended, schedule/start/extend/end/cancel, deferred trigger firings per windowGET /api/maintenance, GET /api/maintenance/{window_id}/deferred_firings, POST /api/<node>/maintenance[/schedule|extend|end|cancel] (node-RBAC'd writes)opschain docs maintenance-windows, opschain docs triggers
Users & Groups (/admin/users)Local identity: users (provider chip, break-glass, disabled state, email), create/disable/enable/reset-password, an Edit user dialog for local users (stored email + per-user local group membership — directory users' details are read-only, though enable/disable work for them too: OpsChain-local state), local groups and membership (members added through the provider-aware user picker, so a same-named local/ldap pair is picked apart explicitly); both tabs filter server-side (debounced q substring + limit; users match username/email/group, groups match name/member, with the client-side pass kept so older servers degrade gracefully), a Show ghosts toggle lists the hidden ghost rows with a muted ghost badge (include_ghosts=true), and the groups tab creates groups (empty allowed; the first member is optional) and deletes them (refused verbatim while policy assignments reference the group), with member chips carrying each account's provider. Create service account… in the users toolbar mints a service-account row (no credential, no login lane; a username held by any identity is refused by name); the disable dialog's offboarding summary lists the automations the identity executes — triggers, scheduled activities and the agents it owns (agent_count, agent_names) — and a disabled row offers Reassign automations…, whose target picker lists enabled service accounts onlyGET/POST /api/admin/users, GET/PATCH /api/admin/users/{username} (+ /disable, /enable, /reset_password), GET /api/admin/groups, POST/DELETE /api/admin/groups/{groupname}/members[/{username}]; UserService.CreateServiceAccount, UserService.DisableUser (owned_automations), UserService.ReassignAutomationsopschain docs identity, opschain docs cli/admin-service-accounts-create, opschain docs cli/admin-users-reassign-automations
Preferences (profile menu → Preferences; Api keys and Password sections)The signed-in user's own credentials: Api keys lists their native API keys (id, description, expiry, created; never a value), Create api key… takes a description and an expiry and shows the key value exactly once, Revoke per row; Password changes their own password (current, new, retyped) — local users only, a directory-managed identity is refused by name as the server states itAuthService.ListAPIKeys|CreateAPIKey|RevokeAPIKey, AuthService.ChangePasswordopschain docs cli/tokens-create, opschain docs cli/tokens-list, opschain docs cli/tokens-revoke, opschain docs cli/passwd
Deleted nodes (Show deleted on the project, environment and asset lists)The soft-deleted subtrees under the list's scope with Restore and Destroy… per row — Destroy opens the manifest preview (every row type and count the destroy would remove, events excepted) and arms on a typed-path confirmation; the rows are derived from the node deleted / restored / destroyed events (newest 2000), so a node deleted through an ancestor appears under that ancestor, never on its ownNodeService.RestoreNode|GetNodeDestroyManifest|DestroyNode, EventService.ListEventsopschain docs cli/admin-nodes-restore, opschain docs cli/admin-nodes-destroy, opschain docs cli/admin-nodes
Export subtree (Export subtree… on a live node's actions menu)Downloads the node's subtree as the credential-free export zip (definitions, history, manifest) — the lasting record to take before a deleteNodeService.ExportNodeopschain docs cli/admin-nodes-export
Destroy workflow (Destroy with runs… on an archived workflow)Permanently removes an archived workflow, its versions and its runs with their logs after a manifest preview and a typed confirmation; a live workflow, an active run or a trigger or schedule still referencing it is refused by nameWorkflowService.GetWorkflowDestroyManifest|DestroyWorkflowopschain docs cli/admin-workflows-destroy
Delete Git remotes (Git remotes tab → Bulk actions → Delete Git remotes…)Deletes the selected remotes behind a confirmation; a remote templates, changes or scheduled changes still reference is refused by name, and an archived remote that finished changes reference keeps its row and loses its stored credentials, as the server reportsGitRemoteService.DeleteGitRemoteopschain docs cli/git-remotes-delete, opschain docs resources/git_remote
Import nodes (Infrastructure page → Import nodes…)Registers or updates a batch of infrastructure nodes under one parent: lines of code,type[,address[,fqdn[,name]]] or a JSON items array, each item's outcome and warnings reported after the batchInfrastructureService.BulkUpsertInfrastructureNodesopschain docs infrastructure-nodes, opschain docs cli/infrastructure-bulk-upsert
Run dialogs (Run change, Run workflow)Run during maintenance sends override_maintenance: the run is admitted through an active maintenance window instead of held, honoured only with update on every covering window's …/maintenance rule path and stamped overridden in the auditChangeService.CreateChange, WorkflowRunService.CreateWorkflowRunopschain docs maintenance-windows
Schedule dialog (create and edit)Maximum run count (maximum_run_count) and Allow parallel execution (allow_parallel_execution) beside the schedule helperScheduledActivityService.CreateScheduledActivity|UpdateScheduledActivityopschain docs resources/scheduled_activity, opschain docs scheduled-activities
Metadata profile dialog (Governance → Classification)Applies to node kinds (applies_to_kinds: project, environment, asset, infrastructure, entity; none selected applies everywhere) on create and reviseMetadataService.CreateMetadataProfile|UpdateMetadataProfileopschain docs metadata
Provider bindings (Secrets providers and Transport providers binding panels)A provider disabled chip on a binding whose provider is disabled (provider_enabled)SecretsProviderService.ListSecretsProviderBindings, TransportProviderService.ListTransportProviderBindingsopschain docs resources/secrets_binding, opschain docs resources/transport_provider
Packs (Administration → Packs)A Bundle column with the stored bundle's content digest and sizePackStoreService.ListPackVersions (bundle_digest, bundle_size)opschain docs resources/pack
Version activity (a templated node's Actions page)Each template-version-history window with its active_from / active_to bounds and links to the background tasks that ran under itAssetService.ListTemplateVersionHistoryopschain docs resources/template
Notification feed (the bell)Rows grouped by thread (thread_key): one run's notifications fold under one entry with the latest on topNotificationService.ListNotificationsopschain docs resources/notification
Pause (a change's or workflow run's page)The Pause verb shows while the server's typed pausable flag is true and Resume while the run is pausedChangeService.PauseChange|ResumeChange, WorkflowRunService.PauseWorkflowRun|ResumeWorkflowRunopschain docs resources/change
Activity (/admin/activity)The operational event stream, lensed over the ops vocabulary (warnings default; platform, licence, maintenance, agents, automation, auth)GET /api/events (JSON:API, filterable)opschain docs events
Database (/admin/database)The store console: maintenance status (per-table stats, autovacuum/analyze recency) with on-demand ANALYZE and VACUUM (ANALYZE) runs — optional table list, per-table timings and dead-tuple counts rendered after the run; the migration ledger (every migration with its state, the integrity verdict with its findings and remedy, Apply pending behind a type-to-confirm arm, the out-of-order and mismatch refusals verbatim); the System quiesce panel (start with a required reason, abort a drain, resume); the backup manifest captured inside the quiesced window (summary, download) and restore verification from a pasted or uploaded manifest (every check with its detail); the log-migration control plane (both phases' state and counters, start with the batch size, pause, resume, and the purge behind its named warning and arm); the encryption-at-rest census (current and configured keys, the key registry, per-column envelope counts, pending and missing keys, the last run) with re-encryption (batch size and row limit, refused by name while a referenced key is missing); and the estate export download. Database import and restore execution stay with the CLI — they move files on the server hostSystemService.GetDatabaseStatus|AnalyzeDatabase|VacuumDatabase, …ListMigrations|GetMigrationStatus|ApplyMigrations, …GetBackupInfo|VerifyRestore, …GetLogMigrationStatus|StartLogMigration|PauseLogMigration|ResumeLogMigration|StartLogPurge, …GetEncryptionStatus|ReencryptAtRest; PlatformService.GetSystemQuiesce|StartSystemQuiesce|AbortSystemQuiesce|ResumeSystemQuiesce; GET /api/admin/database/exportopschain docs database-maintenance, opschain docs cli/admin-database-analyze, cli/admin-database-vacuum, cli/admin-database-migrations-list, cli/admin-database-migrations-status, cli/admin-database-migrations-apply, cli/admin-database-backup-info, cli/admin-database-verify-restore, cli/admin-migrate-logs-status, cli/admin-migrate-logs-start, cli/admin-migrate-logs-pause, cli/admin-migrate-logs-resume, cli/admin-migrate-logs-purge, cli/admin-encryption-status, cli/admin-encryption-reencrypt, cli/admin-platform-quiesce, cli/admin-platform-resume

Governance surfaces​

The governance verbs that are operational acts (catalog curation, cadence configuration, hand-opening campaigns, the evidence export and the break-glass release) live under /governance beside their read surfaces. They answer to the same gates as the CLI verbs they mirror: the curation verbs show for administrators, the export needs the packs:security-governance entitlement, and break-glass shows for a superuser or a caller holding the change-governance determination at the root scope — the server still authorises every write, so a principal the GUI cannot see the standing for is refused by name, never silently.

SurfaceWhat it doesFed byComponent page
Controls (Governance → Evidence & controls → Controls)The control catalog with New control, per-row Edit (name, description, owner role, status active/retired, the instrument refs replaced wholesale) and Retire; the key opens the control's detail pageGovernanceService.ListControls, CreateControl, UpdateControlopschain docs governance, opschain docs cli/admin-governance-controls-create, cli/admin-governance-controls-update
Control detail (/governance/controls/<key>)One control: key, name, domain, status, owner role, description, the implementing instruments, and the review campaigns that cite it; an unknown key answers a not-found noticeGovernanceService.GetControl, ListReviewCampaignsopschain docs cli/governance-controls-show
Cadences (Governance → Reviews & approvals → Cadences)The review cadences: campaign kind, control, schedule, grace, enabled switch, next due and the latest campaign the cadence opened; New cadence and Edit dialogs, whose Schedule field is the same helper the run dialogs use — a preset list, a Builder that reads as a sentence (every N minutes/hours, every day, week, month, quarter or year, on a day at a time) and an Expression box for a typed 5-field cron expression, each read back in words; a new cadence opens on the quarterly review (02:00 on the first day of every quarter); administrators onlyGovernanceService.ListReviewCadences, CreateReviewCadence, UpdateReviewCadenceopschain docs cli/admin-governance-cadences-create, cli/admin-governance-cadences-update
Open campaign (Governance → Reviews & approvals → Campaigns)Beside Open access review: a campaign of any kind on a control, with an optional due time and the reviewable subjects typed row by row or pasted one per line as subject-kind:subject-id[:reviewer] (a malformed line is named before anything is sent)GovernanceService.OpenReviewCampaignopschain docs cli/admin-governance-campaigns-open
Evidence export (Governance → Evidence & controls → Evidence ledger → Export)One hash-chained batch for an auditor: the cursor (after seq) and batch size, the batch re-encoded to the canonical NDJSON in the browser and its SHA-256 checked against the server's digest before the .ndjson download; a mismatch is flagged and the CLI export named; an empty batch says the cursor is caught upGovernanceService.ExportEvidenceLedgeropschain docs cli/governance-evidence-export, opschain docs retention
Inbox (/manage_activity, the sidebar's one waiting-on-you destination)Role-lit perspectives at /manage_activity?view=: Steps (the steps waiting on the signed-in user, step-gate approvals included), Approvals (the governance approval checklists — agent trust reviews and break-glass included — lit when the change- or agent-governance role lights Reviews & approvals and the pack is not gated), Security reviews (the security role grant review queue, lit by the security-administrator gate) and Scheduled (the scheduled activity). A perspective the user's roles do not light is absent, never greyed; a pack-gated one is greyed with the pack named where its owning destination is. The sidebar count and the page title sum exactly the perspectives the page shows for this user — waiting steps + checklists waiting on them (+ security reviews waiting when that perspective is lit); a notification for an approval opens Inbox → ApprovalsChangeGovernanceService.ListPendingApprovals (the checklists waiting on the caller), the step and scheduled-activity reads the page already made, GitRemotePolicyService.ListSecurityRoleGrants (grants pending review)opschain docs change-governance, opschain docs cli/approvals-list, opschain learn core-gui-surfaces
Reviews & approvals (Governance → Reviews & approvals)The governance record: Campaigns, Cadences, Decided and the work items. Decided is the decision history — newest first, each row expanding to its approval rows and the finaliser's reason — filtered by Mine, Decided by, Outcome, Target path (prefix), Kind (change, workflow, trust grant, transport grant, agent release, agent rollover) and Requested from/to (local days, inclusive), the filters living in the URL (?tab=decided&target=&kind=&from=&to=) so a view is linkable; the Inbox's Approvals perspective links here ("Decision history", and its empty state) and the tab links back. It carries no inbox of its own: /governance/reviews?tab=approvals (and every approvals-tab link the GUI emits) redirects to /manage_activity?view=approvals, so bookmarks and notification links keep workingGovernanceService.ListReviewCampaigns|ListReviewCadences, ChangeGovernanceService.ListApprovalChecklists (the decided history)opschain docs governance, opschain docs cli/approvals-history
Break-glass release (Inbox → Approvals row)Releases a held subject without quorum: a mandatory reason, a confirmation naming the warn:approvals:break_glass event it lands, the server's refusal verbatimChangeGovernanceService.BreakGlassReleaseopschain docs change-governance, opschain docs cli/approvals-break-glass
Approval evidence (Inbox → Approvals row → Evidence — prior runs)On a pending change or workflow-run row, the prior-run evidence read when the panel opens: runs of the same action on the same pinned content on any target, each with when it ran, its kind, target and status and a link to the run — or the first-run-anywhere flag when no such run exists; the evidence informs the approver and never gates; the server's refusal renders verbatimChangeGovernanceService.GetApprovalChecklist (prior_runs, first_run_anywhere)opschain docs change-governance, opschain docs cli/approvals-show
Agent assignments and activity (Governance → Agents → agent sheet → Assignments and Activity tabs)The sheet's Assignments tab lists the agent's assets under management — each assigned node-path scope with its role, note and who recorded it when; the Activity tab is the agent's audit timeline, newest first — every platform-recorded event with its type and payload facts (the applied tier, a halt reason, a refusal), a departed agent's history marked read-only; each tab reads on opening, the server's refusal verbatim; an approver opening the sheet from the inbox without the agent-governance reader role sees no tabs, since the server refuses both readsAgentService.GetAgentAssignments, AgentService.GetAgentActivityopschain docs cli/admin-agent-assignments, opschain docs cli/admin-agent-activity, opschain docs agent-plane

Conventions the panels share​

  • Derived runner STATE is a GUI concern — the server exposes booleans and timestamps (online, draining, stopped_at, last_seen_at); the GUI derives the same labels as the CLI so support conversations line up.
  • Honest liveness — online: false means "has not polled for 3 minutes", not "dead"; every liveness dot is paired with a last-seen age, and a clean goodbye (stopped) renders distinctly from aged-out silence.
  • Reason-first destructive flows — halt and per-agent halt 422 without a reason; the dialogs make it a required field, because the reason is the audit record.
  • Every action proves itself — each verb's confirm names the telemetry (event, status field) that will show it took effect.
  • Greyed, named, never hidden — a destination, tab or verb the signed-in user cannot use renders greyed with the reason on hover: a pack-gated destination names the pack it needs; a role-gated one names the admitting determination (the Administration item and the Operations and Insights dashboard tabs need /admin; a governance destination names its governance role); a verb the server would refuse names the refusal (a trust raise held for the Inbox, an approval line the user is not on). Nothing a user lacks the right to use disappears from the navigation, so the ask is always "grant me this", never "does this exist".
  • Signing out clears the tab — logging out clears the browser tab's query cache (role probes, inbox counts, lists, preferences) and the stored dashboard tab, and a sign-in by a different principal in the same tab drops anything cached for the previous one before it renders, so a shared workstation never shows the last user's sidebar or rows.
  • opschain docs cli/admin-status, opschain docs cli/admin-queue, opschain docs cli/admin-runners-list, opschain docs cli/admin-licence-show, opschain docs cli/admin-platform-status, opschain docs cli/admin-database-status, opschain docs cli/maintenance-status, opschain docs cli/events — the CLI views of the same endpoints, sharing the panels' vocabulary.