Jobs stay visible while you inspect
The jobs route combines state filters, structured search, queue/state bulk actions, and a paginated job table. Selecting a job opens a route-owned detail sheet instead of replacing the list, so operators keep their search and surrounding jobs in view. The archived filter is the dead-letter queue. Open an archived job to diagnose its errors and payload, retry one job from the detail sheet, or select reviewed rows for a bounded redrive.quarantined and undecodable remain separate filters because their
recovery paths are different.


blocked_by value is never presented as an invented
“unknown policy.”
Wait and Running durations advance once per second while their stage is live. Waiting,
active, completed, failed, and pending stages use distinct colors; nodes and connectors
enter progressively, with motion disabled when the operating system requests reduced motion.
Opening the sheet explicitly requests the selected job’s payload; list and search
responses remain payload-free.
Checkpoint inspection is also explicit: opening job detail requests the dedicated
/jobs/{id}/checkpoint endpoint. The resumable section shows completed/current steps,
cursor state, step-set identity, and per-step crashes; ordinary list and job responses do
not carry cursor bytes.
Encrypted payloads are detected from Headgate’s versioned envelope header. The console
shows the encryption version, key ID, and copyable ciphertext, but never receives a key or
decrypts the payload in the browser.
Periodic schedule event selection is URL-backed as ?events=<schedule-id>, so an event
view can be shared, refreshed, and traversed with browser history. Missed-run policies use
operator-facing labels and explanations rather than exposing only the wire enum. Enqueue
now creates one extra job without moving the schedule’s normal next-run time.
Workflows show live execution state
The workflow view renders dependencies as connected stages. Completed edges are solid, waiting edges are dashed, and the currently running card is highlighted. Every task card links to its ordinary job detail, including the same progress and attempt history available from the Jobs route.
Worker controls are state-aware
The worker row separates a command waiting in the store from the state acknowledged by the worker heartbeat. While a command is pending, conflicting controls remain disabled. After acknowledgement:- Quiet stops new admission while current jobs finish; only Resume becomes available.
- Resume returns a quiet worker to admission; Quiet becomes available again.
- Rolling restart releases singleton duties, drains without the ordinary shutdown deadline, and exits for the process supervisor to replace.
- Resign duties releases scheduler, reclaimer, quarantine, retention, and operations leases without stopping ordinary job processing. It stays disabled until process restart.
- Terminate releases duties and performs the configured bounded graceful shutdown.
Data architecture
- Every view owns its TanStack file route.
- TanStack Query owns reads, polling, mutations, and invalidation.
- The UI calls the OpenAPI control surface; it never connects to a store directly.
- Built assets are embedded in both language packages.
- List and search responses exclude payloads. Opening an individual job is the explicit payload request and should therefore sit behind the same operator authentication as the rest of the control plane.
ReadOnly disables mutation controls for clarity. Configure read-only mode on the control
API as well; disabled browser controls are not an authorization boundary. Content-hashed
assets are cached immutably, while the SPA shell is served with no-cache so its injected
API base and read-only configuration stay current.
Run the complete UI demo
Inspect realistic jobs, workflows, policies, workers, and schedules without a database.