Skip to content

feat(routing): launch routing, reasoning effort, server preparation and sign-in - #69

Draft
BIackFIame wants to merge 7 commits into
howdeploy:mainfrom
BIackFIame:stack/7-routing-servers
Draft

BIackFIame wants to merge 7 commits into
howdeploy:mainfrom
BIackFIame:stack/7-routing-servers

Conversation

@BIackFIame

@BIackFIame BIackFIame commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Goal

Choose the right agent, account, server and reasoning effort for a task, prepare servers automatically, and sign in or add a key once in the app instead of on every server.

Behavior

  • Decision routing (opt-in): rules run first, with optional Jev evaluation. Routes are assembled automatically from accounts, servers and installed CLIs, ordered by task difficulty, and weigh cost, quality and limit headroom. Jev responses are validated tolerantly (extra fields, partial distributions), and the evaluator budget is reserved before waiting.
  • Reasoning effort is a launch dimension: Claude --effort, Codex model_reasoning_effort, Grok --reasoning-effort. It is refused for providers without it, for ACP and for containers, and it changes a route's cost and quality estimate.
  • "Prepare server" / "Prepare all servers" runs over SSH with root or passwordless sudo on Ubuntu or Debian. It installs base packages and only the agents whose API answers from that server. On machines under 2 GB it adds swap and fails if the kernel does not report it active.
  • API key forwarding: a key held in the app is sent per launch over SSH stdin into a 0600 tmpfs file, loaded into the agent's environment, and deleted before exec. It never appears in argv or on the server's disk.
  • Sign in once: Codex and Claude subscription accounts sign in through the app, on the computer the account is bound to, into a private managed directory. Credentials are created by the vendor CLI and never pass through CanvasTTY.
  • Orchestrator option: the launch dialog offers an explicit Orchestrator option. It is disabled with an explanation for agents without a verified orchestration adapter. Cards show Orchestrator or Subagent, and the role label stays readable on narrow cards.
  • Consent flows down the chain: a delegation chain whose root the person launched as an orchestrator carries that consent. The default class and the task-text floor warn instead of blocking every child, so orchestration works out of the box. Explicit classes, path policies, capsules and containers stay enforced, and an unconsented parent's child is still blocked.
  • Launchers keep agents that have a remote or container route even without a local CLI.
  • Direct launches on the default data class warn instead of blocking. This also holds when a session with a typed task is rechecked before spawn, restarted or restored; previously a project class below D2 blocked those. Delegated and automated launches stay blocked.
  • An account with unreviewed terms follows the same rule. A CLI-home account without a reviewed data-handling assessment signs in through the same consumer route as the CLI login and carries only the same estimate. A direct launch at the default class now warns instead of blocking; before, adding a Claude account made every task fail at the default D2. A reviewed assessment, an API route, a shared account, the person's own limit on the account, an explicitly raised class and unconsented delegation still block. The launcher uses the only compatible account without a separate choice, names the account in its warning and disables D0/D1 once a task is typed; account settings explain that the extra limit can only lower access.
  • Fixes: remote terminals open the server's login shell in the mapped folder. Cursor's reachability probe uses its real API host (api2.cursor.sh). Servers without curl are no longer excluded. The idle orchestration gateway runs no timers and stops on exit. Podman's read-only /run/.containerenv is accepted by the container bootstrap. The unused ExecutionIsolation planner is removed.

Documentation

docs/routing-decision-notes.md.

Verification

  • npm run typecheck, npm run audit:secrets and git diff --check passed. Full suite: 1445/1445; Even G2 companion tests (npm run test:even): 47/47. npm run build succeeded. The CI browser smoke (31 steps) and provider-helper smoke passed locally with an off-screen window, as they do on upstream main. Packaging and the Windows job were not run locally.
  • Live, against three fresh Ubuntu servers and macOS:
    • Server preparation on all three. The 889 MB server got an active 2 GB swap and all four agents; the regional server installed only the agents whose APIs answer there.
    • Key forwarding with OpenCode: the key reached the remote process environment, was absent from argv, and left no file behind.
    • Remote agents: Claude on a server with --effort high. Disposing a session killed its remote process.
    • Podman: a container shell on a server ran after the .containerenv fix.
    • Off-screen Electron UI check of the launch dialog (effort, privacy notice), agent install rows and route preview.
  • Real models, in the app itself (off-screen window, empty temporary folders):
    • OpenCode (Z.AI plan) wrote a working calc.py from a launcher task.
    • A project rule reached the model: the new file started with the exact line the rule required.
    • An orchestrator OpenCode session called spawn_agent through the orchestration MCP. The child was refused by the privacy policy, as designed, because an OpenCode subscription login has no account adapter.
    • This run found the recheck bug fixed above.
    • An OpenCode orchestrator delegated to OpenCode subagents through spawn_agent, waited for a result, and stopped a second child with cancel_agent. A second recheck bug (a child's task floor) was found this way and fixed.
  • Settings layout evidence: 18 screenshots of the changed sections at 920×620 and 1440×900, UI scale 0.85 and 1.25, RU and EN, with 0 horizontally overflowing elements, in the pr-evidence branch.
  • Codex and Claude sign-in reached the vendor's browser step; completing it needs the account owner. Jev was not called live (no API key).

Series

Each part is one commit on top of the previous one. Please merge them in order. Until #68 is merged, GitHub also shows the earlier parts here; review only the top commit 5d294d8 (Commits tab → last commit).

Part PR Scope Lines
1 #63 Providers: Cursor, MiniMax Code, Devin, Antigravity +579/−90
2 #64 API keys, API profiles, agent delegation (MCP) +4275/−63
3 #65 Remote servers, placement, privacy tiers, accounts +6620/−40
4 #66 Isolation: capsules, worktrees, containers +5508/−839
5 #67 ACP, connection settings, remote containers +6827/−563
6 #68 Project context and learning +6148/−370
7 #69 Routing, reasoning effort, server preparation, sign-in +3122/−467
8 #70 Open issues and safe fixes from open PRs +306/−58

Compatibility with open upstream PRs

integration/stack-with-open-prs is this whole stack with #54–#62 merged on top and every conflict resolved. On that branch both TypeScript checks, 1492/1492 tests, npm run test:even (47/47) and electron-vite build pass.

I will rebase this stack onto whichever of these lands first.

🤖 Generated with Claude Code

BIackFIame and others added 6 commits September 23, 2026 17:16
Provider CLI resolution is driven by declarative command definitions
instead of assuming the executable matches the provider id. MiniMax
Code (`mcode`), Antigravity (`agy`) and Cursor resolve through the same
registry, known install directories, recheck and install links that howdeploy#52
introduced. Cursor prefers `cursor-agent`; a generic `agent` is accepted
only when its real path is verified as Cursor, because Grok also
installs an `agent` executable.

Each new agent gets normal and resume launches where the CLI documents
them, its YOLO flag only where one exists, launcher entries with a
settings migration, its provider mark and session restore. MiniMax Code
has no permission-bypass flag, so its YOLO profile launches the stock
CLI and says so. Antigravity restores as a fresh session because it has
no resumable id that CanvasTTY can persist.

Provider ids, labels and launcher order live in a dependency-free
`providerCatalog.ts` that `contracts.ts` re-exports, so the Even G2
companion bundle stays free of URLs outside its network whitelist; its
phone launcher lists the new agents too.

Lifecycle hooks are prepared only for providers that have a hook adapter, so
the new agents never write Grok's shared hook configuration.

ADR: docs/adr/ADR-20260921-provider-cli-command-definitions.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tion

- Provider API keys are stored in the main process, encrypted with
  Electron safeStorage; the renderer only sees which keys exist.
- API profiles name a model backend (protocol, HTTPS base URL, key
  reference, default model) with built-in presets.
- Sessions carry role and parent metadata; restore drops orphaned
  subagents instead of resurrecting them.
- Per-provider capability descriptors state what CanvasTTY can really do
  with each agent, and agent control (spawn, send, observe, result,
  cancel, children) works over ordinary terminal sessions.
- An orchestration MCP surface rides the existing agent-bridge design:
  authenticated user-local socket, one-use bootstrap capabilities, scoping
  to the caller's own session subtree, and MCP injection for Claude,
  Codex, OpenCode, Kimi and Hermes. Only orchestrator sessions receive it;
  ordinary launches are unchanged.

ADR: docs/adr/ADR-20260921-orchestration-mcp-rides-agent-bridge.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…accounts

- Saved remote hosts use the system OpenSSH client (BatchMode, no stored
  passwords) for connectivity checks, remote terminals, CLI discovery,
  light load/memory metrics and per-host workspace mapping.
- Automatic placement applies hard filters (reachability, provider rules,
  workspace mapping, capacity) before ranking by load and free memory,
  and probes whether each provider's API answers from that host.
- spawn_agent can request a host, so subagents may run remotely.
- Data-handling tiers D0-D3 are enforced at spawn time, with host
  confidentiality ceilings and repository path policies.
- Several accounts per provider with subscription tiers; each account is
  bound to its own computer.
- Security fixes: lease supersession, an authentication hang and SSH
  option injection through host fields.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Bounded task capsules and workspace sandbox plans; protected mounts
  are rejected and hidden edits are retained.
- One live launch policy for create, restart and restore, enforcing
  account host affinity, budgets and privacy before every spawn.
- Bounded host probes that honour account placement.
- Accounts launch their bound model with isolated API credentials;
  Kimi homes and OpenCode API protocols are aligned.
- Durable isolated git worktrees that preserve agent output.
- Configured Docker/Podman containers run with durable owned
  workspaces, a fixed Python bootstrap that verifies limits, capabilities
  and mounts before exec, and cleanup fenced against pending creation.
- A responsive API profile editor and launcher controls for workspaces
  and containers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Local ACP conversations and lifecycle for Kimi, Cursor and MiniMax,
  with model selection confirmed before prompts are admitted.
- Settings gain account connections, host controls, explicit account
  launch routing and responsive navigation.
- Remote API agents run in containers with host-local credentials;
  retained remote output can be reviewed and exported.
- Capsules retain output, launch only verified selected files in owned
  containers, apply reviewed snapshots and run saved checks in isolated
  snapshots; orchestration is scoped to live parent authority.
- Initial tasks are delivered through literal startup arguments instead
  of typed PTY input.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Stored project preferences with scopes, delivered to agents through
  fixed launch routes with a route preview.
- Live imports of project conventions (AGENTS.md, CLAUDE.md, Cursor
  rules with bounded frontmatter parsing) and design token editing.
- Learning from explicit corrections and accepted changes, checks of
  reviewed changes against project conventions, and explicit read-only
  agent review of capsule patches.
- Container inventory and launch previews across computers, with
  complete eligible routes launched through the shared policy gates.
- Keyboard focus and control visibility fixes; explicit delegation. The
  Browser card is unchanged, per the maintainer's browser freeze.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@BIackFIame
BIackFIame force-pushed the stack/7-routing-servers branch from f68a19c to 574a8fc Compare September 23, 2026 14:26
…nd sign-in

- Opt-in decision routing: rules first, optional Jev evaluation. Routes
  are assembled automatically from accounts, hosts and installed CLIs,
  ordered by task difficulty, and weigh cost, quality and limit headroom.
  Jev responses are validated tolerantly and the evaluator budget is
  reserved before waiting.
- Reasoning effort is a launch dimension (Claude --effort, Codex
  model_reasoning_effort, Grok --reasoning-effort) and changes the
  cost/quality estimate of a route.
- "Prepare server" and "Prepare all servers" install base packages and
  only the agents whose API answers from that server, adding swap on
  small machines and verifying it is active.
- An API key held in the app can be forwarded per launch to any saved
  server over SSH stdin into a 0600 tmpfs file that is deleted before
  exec; it never appears in argv or on disk.
- Codex and Claude subscription accounts sign in once through the app,
  on the computer the account is bound to.
- Launchers keep agents that have a remote or container route even
  without a local CLI.
- The launch dialog offers an explicit Orchestrator option (disabled with an
  explanation for agents without an orchestration adapter), cards show
  Orchestrator or Subagent, and a delegation chain whose root the person
  launched as an orchestrator carries that consent: implicit floors warn,
  explicit classes, path policies, capsules and containers stay enforced.
- Direct launches on the default data class warn instead of blocking,
  including the recheck before spawn, restart and restore of a session
  whose task the person typed; delegated and automated launches stay
  blocked.
- Remote terminals open the server's own login shell in the mapped
  folder; Cursor's reachability probe uses its real API host; servers
  without curl are no longer excluded; Podman's read-only
  /run/.containerenv mount is accepted by the container bootstrap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant