0b4b52ac45
The UI is a full control plane: it can create tasks, release or complete them, and inject approval keystrokes into live panes. authz.HTTP did cover it (an absent surface header defaults to Web), but the gate is opt-in and the deployed env sets no tokens while binding all interfaces, so in practice it was reachable unauthenticated from the LAN. Setting the token alone did not work either: a browser cannot put a bearer token on a document load, so the UI would 401 on index.html. - ORCHESTRA_WEB_TOKEN is now mandatory; startup fails rather than silently serving an open control plane. - authz.Sessions issues random values stored SHA-256-hashed, with a TTL, so a leaked snapshot yields nothing usable. - POST /v1/ui/session verifies the token in constant time and returns it as an HttpOnly, SameSite=Strict, Secure cookie. This is a presentable form of the same credential, not a new authority. - HTTPWithSessions accepts that cookie in place of the bearer token, and only for the Web surface. The login endpoint and non-/v1/ GETs (the SPA shell) are exempt by necessity; every /v1/ control path stays gated. Note this is a breaking config change: .orchestra-config/orchestra.env sets no tokens, so the service will not start until it does, and setting a Web token newly gates the other /v1/ surfaces that default to Web. AUDIT.md is reconciled against the code rather than against itself. B14, B15 and B16 are closed with their evidence; B17 is closed on the worker path only; the stale claim that B13 was open is corrected. Adds the previously undocumented command channel and web UI, and files what that implementation pass surfaced: federated approvals emit no event (B19), the local capture revision is a timestamp rather than a change counter and can silently defeat approvals (B20), the command queue never prunes (B21), the ntfy token serves two unrelated purposes (S12), and a dead copy of the authorization policy sits in main.go (S13). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01535A3Y8RtkAi8wYuWhtkEd