Skip to main content

User interface

The UI is a SvelteKit single-page app embedded in the server (stack.md §3). It is a view over the management API: it holds no state of its own, and everything it does, a script can do with stratactl.

1. Principles​

  • Every view has a URL. Filters, selectors, tabs and the selected revision live in the URL, so a link shows the same view to a colleague (who sees what their own permissions allow).
  • Live, not polled. Views subscribe to the SSE topics they display (GET /api/v1/events) and re-fetch on change.
  • Changes go through change sets. Every spec edit opens or extends a draft change set; nothing in the UI writes a revision directly.
  • The equivalent command is one click away. Every action and filtered list offers "Copy as stratactl".
  • Permissions decide what is offered. Actions the caller's roles cannot perform are hidden; a 403 that still happens (scope) shows the role and scope that would be needed. Data the caller may not see is absent, never greyed out. An action a tenant limit blocks stays visible but disabled, with the limit and its usage.
  • Empty is explained. An empty list says whether nothing exists yet or the filters match nothing, and offers the next step: the first object to create, the enrollment command, or clearing the filters.
  • Confirmations state consequences. A destructive or disruptive action confirms in a dialog that names what it affects, with counts ("12 agents use this pin; they fall back to the release"). Irreversible deletes of tenant-wide objects (teams, sinks, trust anchors) ask for the object's name to be typed.
  • Unsaved input is guarded. Leaving a form with unsaved changes asks first. Saved spec edits need no guard: they live in the draft change set; the editor asks only for text not saved into it yet.
  • Secrets are never shown. Secret fields are write-only; rendered configs show <secret:name@vN>.
  • Accessible. Keyboard operable throughout, WCAG 2.2 AA, light and dark themes; charts have a table view.

2. Layout​

┌──────────────────────────────────────────────────────────────────────────┐
│ acme ▾ [ search hosts, agents, files, CS-…, RO-… ] ● live user ▾ │
├────────────┬──────────────────────────────────────────────┬──────────────┤
│ Overview │ │ Assistant │
│ Fleet │ page │ (panel, │
│ Spec │ │ opens with │
│ Changes │ │ the page │
│ Rollouts │ │ as context)│
│ Secrets │ │ │
│ Journeys │ │ │
│ Catalog │ │ │
│ Admin │ │ │
└────────────┴──────────────────────────────────────────────┴──────────────┘

The tenant name opens the user menu; with several tenants it offers to switch, which opens the tenant choice (§3.11). The search finds hosts, agents, spec files and objects, change sets and rollouts by name or number, and pages and actions (such as a new enrollment token) by name. The badge next to Changes counts change sets waiting for the caller's review. When the tenant's usage of a limit (architecture.md §12) reaches 90 %, every page shows a banner with the usage; tenant admins get a link to Admin › Tenant, others are asked to contact an admin.

Lists show a fixed set of columns. Hosts and agents sort by any column (clicking its header; the sort lives in the URL), by default hosts by name and agents by instance id. Times show relative ("4 min ago") with the absolute time on hover. Lists with bulk actions have a checkbox per row and a selection bar ("12 selected") with the actions; a bulk action runs per object and reports the result per object, as operation progress (§4).

3. Pages​

3.1 Overview​

Agents per kind by health and sync, with the reasons behind out_of_sync and render errors; change sets waiting for the caller's review; active rollouts with their current stage; failing journeys; agent version distribution against the catalog. Each number links to the filtered list.

3.2 Fleet​

ViewShowsActions
HostsSelector bar; host, kind, owner, columns for chosen labels, agents with health dots; clicking a label value adds it to the selectorBulk: edit manual labels, forget
HostLabels by source with the effective one marked; agents; layers whose selector matches; placements that picked itEdit manual labels, kind, owner; forget
AgentsA health bar per kind (segments link to the filtered list); filters for kind, health, sync, version, desired and applied revision, pending approval; agent, host, kind, health, sync, version, applied revision, last report; with retention.silentAgents set (spec-format.md §3.8), when a not_reporting agent will be forgottenBulk: approve, quarantine / release, forget (e.g. all not_reporting)
AgentStatus: health, sync and reason, desired / served / applied with revisions and times, flags, identity and assurance, pin or rollout that decides its revisionApprove, quarantine / release, SETTINGS action, revoke credential, forget
Agent: ConfigThe desired, served or applied config; diff between any two–
Agent: ExplainInstance keys; per option the winning value and the overridden ones (spec-format.md §4)–
Agent: Logs, EventsHeartbeat logs (Telegraf, Vector), component and unit state (Elastic Agent), status transitions–
PlacementsPer placement and spread value: wanted, picked hosts, candidates, shortfall– (edited as spec files)

3.3 Spec​

ViewShowsActions
FilesThe tree at a revision (default latest), filter by kind, owner, agent kind, plugin, "matches host"; per layer and bundle the instance count per plugin sectionEdit (opens a draft), new file (below), import a telegraf.conf or a Vector config as a new layer
FileWhat the object uses (bundles, routes, secrets, placements whose label its selectors select) and what uses it, with a note on a bundle, route, secret or placement nothing uses yet; canonical TOML; for layers and bundles also a structured view: instances with their plugin, options and merge directives; history of the fileEdit, restore an older version, view at any revision
HistoryRevisions with change set, author, message and files changed; diff between any two revisions (tick two, Compare)Revert a revision (creates a draft)

Editing. The editor (CodeMirror) works inside the caller's draft change set and offers:

  • completion and inline docs from the catalog schema of the target agent versions; TOML syntax errors while typing, L0/L1 diagnostics on every save; a problems panel lists both, each opening its line;
  • secret references and ${ENV} references highlighted apart from literals, with completion of secret names, and a reference panel on what each is for (secrets for credentials, ${ENV} for values that differ per host and are not secret);
  • a form view for a plugin instance, generated from its JSON Schema, with the TOML kept in sync;
  • for data_format options, a sample panel that runs telegraf-parse in the browser (agents/telegraf.md §8);
  • a preview pane: pick an agent (or a host, kind and version) and see the rendered config, its diff against the base and explain for the option under the cursor;
  • a selector field (§4) wherever a selector is edited.

New file. One dialog, here and in a change set (§3.4): the kinds grouped by what they are for (configure agents; credentials and hosts; synthetic checks; rollout, review and settings), each with a line on what it does, and for the chosen kind how it relates to the others and whether its changes need an admin's approval. Then what the template needs: the agent kind (defaulting to the kind with the most agents), name (for Settings the topic, one file each), owner team, for a layer the precedence with the recommended bands, the selector of a layer, journey, secret grant, placement or approval policy (§4), for a route the teams that may attach it, and the path. A Secret notes that its value and its references come after the merge. The template comments each key it holds; with a draft change set (one of the caller's or a new one), the file opens in the editor.

Import. A telegraf.conf or a Vector config file (uploaded, dropped or pasted; the agent is picked in the dialog) with an owner team, selector and precedence becomes a layer in the draft change set, converted as by stratactl import telegraf or stratactl import vector (agents/telegraf.md §9, agents/vector.md §9); the converter's warnings show before the file is added.

3.4 Changes​

ViewShowsActions
Change setsTabs: waiting for my review, mine, open, merged, closedNew change set
Change set: headerNumber, title, state, approved flag, base revision, merged revision and the rollouts delivering it, author (and assistant chat), digestEdit title and description, validate, submit, rebase, merge (optionally starting rollouts), close
Change set: FilesDiff per file against the base, with L0–L2 diagnostics inlineAdd or edit a file (a file of the base revision, or a new one as in §3.3), undo a file's change (back to the base revision)
Change set: RenderedRendered diffs for a sample agent per distinct diff, with the number of agents sharing it–
Change set: ImpactImpact set grouped by owner, kind, version or any label; the agent list. Merged and closed change sets show the summary of their last validation only; before the first validation the tab says it is not computed yet–
Change set: ValidationDiagnostics by level, file and agent version; sandbox resultsRe-run validation
Change set: ReviewRequirements with their reason and who satisfies them; reviews at current and earlier digestsApprove, reject or comment, choosing the teams an approval counts for

A change set whose base is no longer the latest revision shows a banner with Rebase; one with conflicts lists the files and opens them in the editor with conflict markers. Merge is offered when the change set is approved; the merge dialog shows the rollouts it would start.

3.5 Rollouts​

ViewShowsActions
RolloutsActive and past rollouts per agent kind; kinds without agents or rollouts on one lineStart a rollout (kind, target revision, policy)
RolloutThe stages as a pipeline: state, agents applied of total, bake time left, each guardrail's value against its threshold; the change sets delivered; halt reason; agents still applying the revision after their stage passedPause, resume, advance, abort, each with a reason
Rollout: AgentsAssigned agents per stage with baseline and current health and sync–
Releases and pinsRelease pointer per agent kind; pins, active and scheduled, with their agentsCreate a pin (selector with kinds, or an agent; revision; window; reason), delete a pin

3.6 Secrets​

ViewShowsActions
SecretsName, owner, current version, unset badge, number of agents referencing it–
SecretGrant and minimum assurance (from the spec, with a link to the file); versions with state; agents referencing it; delivery auditWrite a new value (write-only field), disable a version

3.7 Journeys​

ViewShowsActions
JourneysPer journey: runners by latest result, stale and unplaced journeysImport a Chrome recording (into a draft change set); pair this computer as an exploration runner (the command to run, then its state)
JourneySettings and script (read-only; edited as a spec file); per runner the latest result, failing since, run counters; kept runs, filterable by result and by manual or scheduledEdit (opens a draft); Run now on all runners or one (journeys.md §3.1): the result per runner as it arrives, with links to the runs
RunStep timeline with durations; the failing step's screenshot and accessibility snapshot; the script with the failing line marked; output; for a manual run, who triggered itDownload evidence

3.8 Catalog​

Imported bundles per agent kind and version, with the number of agents on each version; plugins by section with schema, options, sample and docs.

3.9 Admin​

Visible to tenant admins.

ViewShowsActions
Users and teamsMembers (human and service accounts), teams and their members, sourceAdd a local member, disable / enable a membership, manage local teams
AccessRole bindings by subject, role and scope; for selector scopes the number of matching hostsCreate, delete
Service accounts and tokensService accounts; tokens with prefix, roles, expiry, last useCreate (expiry presets 7, 30, 90 and 365 days or a date; the token is shown once, with copy), revoke
EnrollmentEnrollment tokens with kind, mode, labels, uses; agents pending approval; trust anchorsCreate a token (shown once, with install snippets in tabs per agent kind and OS pointing at server.agent_url, class-mode snippet included, noting that the token is not stored in the snippet's history), revoke; add and delete trust anchors
Network zonesCIDRs with their labelsCreate, delete
AuditEvents with filters for object (id, CS-n or RO-n), actor, action and time, each object named and linked while it exists, an assistant's events as the assistant for its user, details folded; sinks with cursor, lag and last errorCreate, change and delete sinks
AssistantLLM providers and their models; API key statusEdit the provider list (keys write-only)
TenantLimits and usage–

3.10 Platform pages​

In a platform session (service mode) the UI shows only /platform: tenants (state, limits, usage; update, suspend, resume, delete), catalog bundles (import) and the platform audit chain. In a self-hosted installation a platform admin imports bundles on the tenant's Catalog page.

3.11 Sign-in and tenant choice​

/login offers single sign-on and, when enabled, local users. After signing in it returns to the page that sent the caller there. A failed single sign-on lands on /login with its reason (oidcCallback in the API): the sign-in took too long or was started elsewhere, the identity provider refused or failed, or the account is disabled. A session bound to no tenant (architecture.md §12) opens /choose: the caller's tenants (suspended ones shown, not selectable) and, for platform admins in service mode, the platform. A caller without a tenant sees that they have no access yet and can sign out. An OIDC login refused for an unconfirmed email address (architecture.md §12) lands on /verify-email: it asks the user to confirm their address with the link the identity provider sent, links to the account portal to send it again (service mode), and offers to sign in again.

3.12 Billing (service mode)​

The tenant's billing state comes with /api/v1/me (architecture.md §12). A read-only tenant shows a banner on every page: agents keep their configuration, nothing new can be changed or enrolled; tenant admins get Book a plan (the account UI's plans), others are asked to contact an admin. Tenant admins open the account UI from the user menu (Billing and plans) through a single-use link. On Admin › Users, Invite (email, name, role admin or member) replaces adding local members, and Remove access replaces disabling a member; both go through the billing service, which pushes the result.

4. Shared components​

ComponentBehaviour
Selector fieldShort form with autocomplete of label keys and values (/api/v1/labels/*), parse errors inline, and a live count of matching hosts with a link to them
Diff viewerUnified or side by side, TOML- and JSON-aware, secrets masked
Operation progressProgress and result of long operations (validation, imports), surviving a reload; for a bulk action, the result per object
Problem displayMaps problem codes to messages; lists diagnostics with links to file and line
Agent and host chipsName, kind, health and sync at a glance, linking to the detail

5. Assistant​

The assistant is a panel next to every page (assistant.md). Opening it from a page passes that page as context (a host, agent, file or change set). Answers are Markdown (GitHub flavour, rendered as they stream; raw HTML shows as text). Commands it runs appear as collapsible blocks; a change set it submits appears as a link, and reviewing and merging it happen on the change set page. While the assistant explores a website (journeys.md §8.3), the panel shows the page's latest screenshot, URL and outcome, with a button that stops the session.