Workflow monitor¶
httk workflow monitor opens a stdlib curses view over one or more
registered workspaces:
httk workflow monitor --workspace default --refresh 3
httk workflow monitor --workspace cluster:runs
The left pane lists workspaces, per-state counts, and live managers. The centre pane is a page of jobs with key, state, step, placement, and priority columns. The right pane displays the selected job’s report, diagnosis, recent frames, and a bounded standard-output tail. Details are loaded only after selection.
Keys are:
j/k or arrows move; n/p page forward/back; Tab changes pane; f
filters by kind, placement prefix, or tag substring (enter space-separated
KIND path=PREFIX tag=TEXT); Enter loads bounded detail; w loads the full
diagnosis; l loads full history; t
follows logs/stdio.out; c, P, and C request cancel, pause, and
continue; m starts managers; x transfers selected jobs; D removes
removable jobs after confirmation; r refreshes; ? shows help; and q
quits. Prompts and worker errors appear in the status line.
--refresh accepts finite values from 0.5 through 3600 seconds.
The monitor never materializes a workspace’s job set. Counts use the marker
names, and the list uses the cursor-stable job list page API. A refresh reads
the current page and selected workspace counts; a detail read touches only the
selected job. This keeps the memory and state-read budget bounded even when a
workspace contains 100,000 jobs or more. Page cursors are exclusive and stable
within the weak-consistency guarantees of the workspace protocol.
A flat placement containing 100,000 markers is intentionally handled with one
directory listing and sort; that is the bounded, expected cost for that
placement (roughly the filesystem’s directory-listing cost, often about 100 ms)
and the monitor does not build a persistent index. With a finite page limit and
tag filtering, the reader examines at most max(limit * 100, 10,000) markers
per page. Therefore a filtered page can be partial even when fewer than limit
matches were found; its next_after cursor continues the filter scan. A human
table request without a limit scans the complete selected stream. Transfer
parent checks inspect only the waiting state subtree, so their cost is
bounded by waiting jobs rather than all jobs.
Remote workspaces use the existing adapter JSON read protocol: page, show,
history, and diagnosis requests are separate bounded adapter calls, and
canonical job IDs are used for detail actions. Remote standard-output following
is unavailable when the adapter does not expose the payload filesystem; the
status line says so. The phase-1 remote read protocol does not expose the
manager manifest, so the managers pane says unavailable (remote); local
manager records remain live. Remote removal is disabled, and remote actions
require canonical job IDs. Actions are dispatched through the existing request,
manager, and transfer command implementations. Remote page refreshes combine
the page and filtered counts in one adapter invocation; show, why, and log are
separate one-invocation reads when explicitly requested.
Removal is local-only and targeted: it preflights every selected marker as
removable, applies the same parent-join guard as garbage collection, then
removes that marker and payload. Use httk job delete for remote removal.
The command requires an interactive terminal. On platforms without the stdlib
curses module, it exits with a clear diagnostic; --non-interactive is an
explicit refusal useful to scripts that need to verify this requirement.