You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds a fail-closed, server-authorized mobile WebSocket contract at the gateway transport boundary.
Mobile clients request an explicit hermes.mobile audience and supported conversation scopes when minting a single-use WebSocket ticket.
The accepted socket carries the server-derived grant into tui_gateway.dispatch.
gateway.ready advertises the versioned protocol, contract, capabilities, and effective authorization grant.
Mobile requests are denied before dispatch when a method is unmapped, a required scope is missing, or parameters exceed the method policy.
Legacy dashboard tickets retain their existing full-authority behavior.
This is a current-main reconstruction of #62858. It preserves Eric Lewis's three original commits and authorship while reconciling the implementation with current gateway session, busy-turn redirect, MCP ownership, native auth, and transport-handoff behavior.
Why
Current /api/ws authenticates the connection and then exposes the full TUI JSON-RPC dispatcher. Authentication establishes identity, but it does not define which gateway methods a mobile client may invoke. This PR adds that missing authorization boundary without weakening the dashboard or stdio TUI.
Security and compatibility
Fail closed for mobile methods not present in the versioned policy.
conversation.read is mandatory for every mobile grant.
conversation.write, conversation.control, and conversation.delete remain distinct.
Approval resolution, shell execution, raw tool access, and unsupported parameters are not grantable through this contract version.
A writer without conversation.control may queue the next turn but cannot seize or interrupt the currently attached client's busy turn.
Bodyless legacy dashboard ticket requests are unchanged.
No new model tools, environment variables, prompt mutation, or telemetry.
Current-main reconciliation
Preserves current profile-scoped MCP discovery ownership; the WebSocket transport does not restart discovery.
Preserves current active-turn redirect, compute-host isolation, queue draining, and race-safe busy-submit behavior.
Rechecks write-only mobile busy submits under history_lock, preventing a prompt from being stranded if turn teardown drains the queue first.
Preserves current native desktop authorization routes added after the original PR base.
Adapts the positive dispatch test to the current offload model without leaking a background response into unrelated tests.
Result: contract-focused tests pass. The final GitHub slice passed 8,243 tests and failed only the current-main test_write_json_serializes_concurrent_writes background-output isolation flake; that test passes repeatedly alone. The repository's ci-reviewed workflow automatically reruns failed jobs when a maintainer reviews the PR.
Thanks for the focused transport-boundary work. The underlying gap remains on current main: hermes_cli/web_server.py:14472-14474 consumes a gated ticket but drops its grant, hermes_cli/web_server.py:15580-15590 passes no authorization into handle_ws, and tui_gateway/server.py:1703-1739 dispatches requests without a scoped transport gate. The PR's pre-dispatch policy at tui_gateway/mobile_contract.py:200-247 is therefore directed at a real boundary and preserves the legacy authority path.
The current branch is conflicting, and its prompt/busy changes target code moved by f67ca220ab into tui_gateway/methods_prompt.py:67-240. Salvage should port those changes onto that current handler rather than treating the old server.py context as live.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
area/authAuthentication, OAuth, credential poolscomp/dashboardWeb dashboard / control panel UI (dashboard/, landing)comp/tuiTerminal UI (ui-tui/ + tui_gateway/)needs-decisionAwaiting maintainer decision before any implementationP3Low — cosmetic, nice to havesweeper:blast-moderateSweeper blast radius: moderate — a subsystem or single platformsweeper:risk-compatibilitySweeper risk: may break existing users, config, migrations, defaults, or upgradessweeper:risk-message-deliverySweeper risk: may drop, duplicate, misroute, or suppress messagessweeper:risk-security-boundarySweeper risk: may affect sandboxing, auth, credentials, or sensitive datatype/featureNew feature or request
4 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a fail-closed, server-authorized mobile WebSocket contract at the gateway transport boundary.
hermes.mobileaudience and supported conversation scopes when minting a single-use WebSocket ticket.tui_gateway.dispatch.gateway.readyadvertises the versioned protocol, contract, capabilities, and effective authorization grant.This is a current-main reconstruction of #62858. It preserves Eric Lewis's three original commits and authorship while reconciling the implementation with current gateway session, busy-turn redirect, MCP ownership, native auth, and transport-handoff behavior.
Why
Current
/api/wsauthenticates the connection and then exposes the full TUI JSON-RPC dispatcher. Authentication establishes identity, but it does not define which gateway methods a mobile client may invoke. This PR adds that missing authorization boundary without weakening the dashboard or stdio TUI.Security and compatibility
conversation.readis mandatory for every mobile grant.conversation.write,conversation.control, andconversation.deleteremain distinct.conversation.controlmay queue the next turn but cannot seize or interrupt the currently attached client's busy turn.Current-main reconciliation
history_lock, preventing a prompt from being stranded if turn teardown drains the queue first.Test plan
Focused current-main suite:
Result: contract-focused tests pass. The final GitHub slice passed 8,243 tests and failed only the current-main
test_write_json_serializes_concurrent_writesbackground-output isolation flake; that test passes repeatedly alone. The repository'sci-reviewedworkflow automatically reruns failed jobs when a maintainer reviews the PR.Result: passed.
The WebSocket ticket test exercises the real FastAPI ticket → upgrade →
gateway.ready→ denied dispatch path rather than only mocking policy helpers.Attribution
Reconstructed from #62858 with the original commits and authorship preserved for Eric Lewis.
Checklist
git diff --checkpass