Skip to content

feat(admin): /dispatch console opens, checks and signs in to the web console (#708) - #729

Merged
edgehero merged 1 commit into
mainfrom
feat/dispatch-console-708a
Oct 21, 2026
Merged

edgehero merged 1 commit into
mainfrom
feat/dispatch-console-708a

Conversation

@edgehero

Copy link
Copy Markdown
Owner

Closes #708 together with #728 (the console as a service, merged).

What it does

/dispatch console [page] [--link [name]] [--no-open], operator-typed only:

  • Output. Everything goes to the operator's notice. Nothing reaches model context, and no tool exposes it.
  • Address. It prints the console's address, deep-linked to runs, fleet, insights, config, parked, audit or a run id.
  • Running or not. It asks /healthz through the worker's console probe. That is the same rule doctor uses, and it contacts only loopback or the socket.
  • --link. This mints a 60 s, single-use login code for an operator token, and asks which token when there are several.
    • It appends a panel audit row before the code exists, plus a failed row under the same ticket if the mint is refused.
    • It mints only while the console answers as running, only in pi's TUI mode, and only where the codes directory is guarded.
    • The link can carry a return page. Both the server and the page script check it against the console's own pages, so it cannot redirect elsewhere.
  • Opening the browser.
    • On a local session (no SSH, a display, a TCP listener), the link goes to the browser through a 0600 page in a 0700 temporary directory, so the code never appears in a process's arguments.
    • The URL is always printed, and --no-open only prints.
    • On Windows the opener now uses url.dll, so a URL holding & survives.
  • The login-codes directory joins the guarded files, as the tokens file is. It is judged by file identity, even before it exists. The console also refuses a code file that another account can read or owns, and one whose expiry is beyond the code's lifetime.

Specs

  • Amended:
    • REQ-ADMIN-VIA-PI-EXTENSION and DES-ADMIN-VIA-PI-EXTENSION: the subcommand, and a browser only for it on a local session.
    • OQ-024: reopened and closed again.
    • DES-OPERATOR-CONSOLE: the panel as a second minter, the return-path rule, and threat 4.
    • INT-CONSOLE-AUDIT-LOG.
  • UNCHANGED, checked: "binds no network port", the model-callable tool list, and REQ-CONSOLE-SECURITY.

Residuals (named in DES-OPERATOR-CONSOLE)

  • The code itself. It still appears in the notice, and stays in browser history until it is spent.
  • Snap or Flatpak browsers cannot read the page in /tmp, so the operator opens the printed link instead.
  • tmux attached over SSH opens on the unattended desktop.
  • Windows hosts cannot use one-time links, so the token is pasted instead.
  • Verified by reading only: rundll32.
  • bash remains the named residual for the guard, as for the tokens file.

Verification

  • Review: two adversarial rounds, all findings fixed.
  • Full suite with Valkey: only known flakes.
  • Build: node admin/build.mjs builds.
  • Checks: revision-row, test-count, temp-dir and dated-fixture all pass.
  • Manual run against a real serve: the probe said running and not running, a --link code signed in and landed on /runs, a reused code got 401, and the audit chain verified.

…console (#708)

Part of #708. An operator in pi types `/dispatch console` and gets the
console's address, whether it is running and, with --link, a one-time
sign-in link, all in one step.

- `/dispatch console [page] [--link [name]] [--no-open]` is
  operator-typed only. Its output goes to the operator's notice, never
  to model context, and no tool exposes it. `page` is runs, fleet,
  insights, config, parked, audit or a run id. The address follows
  consolePageLines' rules.
- Running or not: the worker's console probe (#728, the one rule doctor
  uses) asks /healthz on loopback or the socket only. "Not running"
  names `pi-dispatch-console serve` and `service install --console`.
- --link mints a 60 s, single-use login code in-process for an operator
  token (asking which when there are several). It appends a `panel`
  audit row first, and pairs it with a `failed` row under the same
  ticket if the mint is refused. It mints only when the console answers
  as running, only in pi's TUI mode, and only where the codes directory
  is guarded. The link can carry a return page (`#<code>&next=/runs`),
  judged by the server and by the page script against the console's own
  pages.
- On a local session (no SSH, a display, a TCP listener) the link is
  handed to the browser through a 0600 page in a 0700 temporary
  directory, so the code never appears in a process's arguments. The URL
  is always printed, and --no-open only prints. On Windows the opener
  uses url.dll so a URL holding & survives.
- The login-codes directory joins the guarded files, as the tokens file
  is, judged by identity even before it exists. The console also refuses
  a code file that another account can read or owns, and one whose
  expiry exceeds the code's lifetime.

Specs: REQ-ADMIN-VIA-PI-EXTENSION and DES-ADMIN-VIA-PI-EXTENSION (the
subcommand; a browser only for it on a local session), OQ-024 (reopened
and closed with the local-session rule), DES-OPERATOR-CONSOLE (the panel
as a second minter, the return-path rule, threat 4 covering the login
codes) and INT-CONSOLE-AUDIT-LOG are amended. UNCHANGED, checked: "binds
no network port", the model-callable tool list and REQ-CONSOLE-SECURITY.

Signed-off-by: Rob Boerman <robboerman@live.nl>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

/dispatch console: open, sign in to and check the web console from pi, and run it as a service

1 participant