--- name: desk-multi-runtime description: How the autonomous desk runs on each of its four runtimes - Grok Bot, Grok Build (CLI), Claude Cowork and Claude Code (CLI) - what each one is responsible for (engine host, supervisor, or both), where the desk root lives, how the cycle is scheduled without prompts, which safety layer each runtime has, and what to check before switching on. Use when installing on a new runtime, when a runtime cannot see the desk files, when a prompt appears, or when deciding where the engine should live. license: MIT metadata: version: "1.1.0" author: SWC Studio category: desk --- # Four runtimes, one desk The desk is files plus scripts. Any runtime that can read the desk root, run Python, and start a prompt on a schedule can run it. The parts are the same everywhere: the engine (`strategy_engine.py`) that trades, the gate and sender that let it, the kill switch, and a supervising agent cycle that reads and journals. What differs per runtime is where the engine process lives, how the cycle is scheduled, and what stops a wrong write. ## 1. The matrix | Runtime | Hosts the engine | Runs the supervising cycle | Schedule | No-prompt mechanism | Independent guard | | --- | --- | --- | --- | --- | --- | | Grok Bot | yes, on the shared desk computer | yes, six Bots on the floor | one Desk Lead routine | Require Approval rule re-scoped to everything except `desk_send.py` | the rule itself | | Grok Build (CLI) | yes, on the machine it runs on | yes, one session, labelled passes | cron calling `grok -p ... --yolo` | `--yolo` plus `--deny` rules | `--deny` rules; the sender's own verification | | Claude Cowork | no; supervises a desk on your linked computer | yes, one session per scheduled task | Cowork scheduled task | Cowork runs unattended by design | the sender's own verification; the guard if the linked computer's Claude Code has it | | Claude Code (CLI) | yes, on the machine it runs on | yes, one session, labelled passes or subagents | cron calling `autonomy_cycle.py --once` | `bypassPermissions` plus allow rules | `hooks/guard.py` PreToolUse hook | The sender's own verification is the floor every runtime stands on: `desk_send.py` refuses without a valid gate approval whatever asked it to run, and the gate refuses anything outside the policy. The guard and the deny rules stop an agent from reaching around the sender; where a runtime has neither, the trade-only key and the ceilings bound what a reach-around could do, and the docs say so. Every runtime's environment (the engine's service file, the cron line, the Cowork task's computer) may also carry `HYPERGROK_ALERT_WEBHOOK`, a Slack, Discord or generic JSON webhook URL. When it is set, halts, unknown send results and repeated unavailable reads are posted there as plain text; when it is not, the same records still land in `autonomy/alerts.jsonl`, and `autonomy/metrics.prom` is rewritten each engine tick for whatever reads Prometheus text files. The same environment may carry `HYPERGROK_KEY_COMMAND` (a secrets-manager command whose stdout is the key, run without a shell by `engine/secrets.py`) or `HYPERGROK_KEY_FILE` instead of the key itself; `desk-operations` section 1 has the resolution order and the recipes. Two more schedules belong to the user on every runtime, beside the supervising cycle: the weekly walk-forward re-review (`strategy_rereview.py`, which demotes a paper or live strategy one rung on a rejected review) and the dashboard render (`desk_dashboard.py`, which writes the read-only `autonomy/dashboard.html`). Both lines are in `deploy/supervisor-cron.example`; they are plain Python on the machine that hosts the desk root and need no runtime prompt. ## 2. Grok Bot Bootstrap as before (`hypergrok-bootstrap`, read-only). Then, in this order and all by the user: API wallet through the secret store; `autonomy.json` on the desk computer; the strategy folder copied from `template/strategies/hg-systematic/` into `/workspace/trading-desk/strategies/`; the Require Approval rule re-scoped (`desk-autonomous-loop` section 4); the engine started on the desk computer as a background process: ```bash cd /workspace/trading-desk && nohup python3 /workspace/hypergrok/scripts/strategy_engine.py --desk-root /workspace/trading-desk --loop --interval 60 >> autonomy/engine.out 2>&1 & ``` and one Desk Lead routine on `cycle_interval_minutes` whose instruction is the supervising cycle from `desk-autonomous-loop` section 4 plus the engine checks in `desk-strategy-engine` section 6. A second routine, owned by the Desk Lead, restarts the engine if `engine-heartbeat.json` is older than five minutes and the desk is not halted. The re-review and the dashboard run from the desk computer's own crontab (the two lines in `deploy/supervisor-cron.example`), not from a Bot routine, because the re-review may demote a strategy and that belongs to a schedule the user owns. Grok Bot keeps only recent routine records, so the journal is the record. ## 3. Grok Build (CLI) Grok Build loads `.grok-plugin/` from the repository (`grok plugin marketplace add`, then `grok plugin install hypergrok`), so the roles, skills and rule are available in any session opened in the desk root. Headless runs use `grok -p "" --yolo --output-format json`; `--allow` and `--deny` take the same rule syntax as Claude Code (`Bash(...)`, `Edit(...)`, `WebFetch(domain:...)`) and deny wins. The supervising cycle on a schedule: ```bash cd /workspace/trading-desk && grok -p "Run one HyperGrok supervision cycle for /workspace/trading-desk following desk-autonomous-loop and desk-strategy-engine; play each role as a labelled pass." \ --yolo --deny "Bash(*kill_switch.py resume*)" --deny "Edit(**/autonomy.json)" --deny "Edit(**/risk-limits.md)" --deny "Edit(**/review.json)" --deny "Write(**/review.json)" --deny "Edit(**/paper-record.json)" --deny "Write(**/paper-record.json)" --deny "Edit(**/strategy-criteria.json)" --deny "Write(**/strategy-criteria.json)" --deny "Read(~/.hyperliquid/**)" --deny "Read(/etc/hypergrok/**)" --output-format json ``` The weekly re-review and the dashboard render are separate cron lines on the same machine (`deploy/supervisor-cron.example`); they are not part of the `grok -p` prompt. Grok Build's rule syntax cannot see inside a file, so it cannot deny `status: live` or an edit to a live strategy the way the Claude Code guard does; the record should say that the Strategist may author and review strategy folders there, and that the user reads the journal's promotion proposals before writing `live` by hand. `deploy/supervisor-cron.example` has the crontab line. Grok Build has no equivalent of the Claude Code PreToolUse guard in this repository, so its safety is the deny rules above plus the sender: say that plainly in the desk record, and keep the deny rules in the cron line rather than trusting a session to remember them. The engine runs as a service on the same machine (`deploy/hypergrok-engine.service` or Docker). ## 4. Claude Cowork Cowork sessions run in a cloud sandbox: they can install this plugin, read its skills, and run a scheduled task unattended, but they cannot keep a process alive and cannot see your desk unless your computer is linked. So in Cowork the desk is supervised, not hosted: 1. Run the engine on your own computer or a VPS (section 5 or 6), with the desk root in a folder you can connect to Cowork. 2. In the Cowork task, link that computer and connect the desk root folder. The session then reads `autonomy/`, `proposals/` and `journal/` through the linked folder and runs the read-only scripts (`desk_doctor.py`, `policy_gate.py policy`, `kill_switch.py status`) on your computer. 3. Create a scheduled task on `cycle_interval_minutes` whose prompt is: *"Open the connected trading-desk folder. Run one HyperGrok supervision cycle following the desk-autonomous-loop and desk-strategy-engine skills, playing each role as a labelled pass. Halt with kill_switch.py if the rules say so. Never resume, never edit autonomy.json, risk-limits.md, review.json, paper-record.json or strategy-criteria.json, never write status: live, and never edit a live strategy's files. Append the CYCLE block to today's journal and send me a one-paragraph summary."* Scheduled tasks start fresh sessions, so the prompt must be complete. 4. Cowork can also run the engine backtest and draft parameter changes as a document for you to apply. The re-review cron and the dashboard render live on the computer that hosts the engine, and a Cowork session reads `autonomy/dashboard.html` and `autonomy/rereview.log` through the linked folder like any other desk file. A Cowork session that is not linked to the computer can only work from what is in the conversation; it should say so and stop rather than pretend to have read the desk. ## 5. Claude Code (CLI) `desk-claude-code-runtime` in full. The engine runs as a service on the same machine; the cycle runs from cron through `autonomy_cycle.py --once`, with the weekly `strategy_rereview.py` line and the ten-minute `desk_dashboard.py` line beside it in the same crontab; the guard hook and the settings template keep the session quiet and bounded. The engine and the cycle share the desk root and never both write a ticket for the same idea: while the engine is trading, the cycle supervises. ## 6. Hosting the engine anywhere `deploy/Dockerfile` builds an image whose entrypoint is the engine loop; `deploy/docker-compose.yml` mounts the desk root and reads the three environment variables; `deploy/hypergrok-engine.service` is the systemd unit with `ProtectSystem=strict` and the desk root as the only writable path. Any Linux box with outbound HTTPS to `api.hyperliquid.xyz` (or the testnet host) will do. Keep the key out of the repository and out of any file under the desk root; the unit reads `/etc/hypergrok/engine.env` (mode 600), which may hold either the key or a `HYPERGROK_KEY_COMMAND` that fetches it from a secrets manager, and the container reads the same from its environment. ## 7. Before switching on, per runtime 1. `bash scripts/check.sh` passes in the checkout. 2. `desk_doctor.py --desk-root ` passes, including the autonomy checks. 3. `strategy_engine.py --once --dry-run` prints a universe, a regime line and a plan with no error. 4. The runtime's supervising cycle runs once with no prompt and writes a CYCLE block. 5. `RULES.md` says `status: paper`, `autonomy.json` says `mode: testnet`, and one full day of testnet cycles has been read by a human. 6. The re-review and dashboard cron lines are installed, and `desk_dashboard.py` has rendered a page the human has looked at. Only then `status: live`, which the engine accepts only with a `ready` paper record from `paper_record.py`, and only then `mode: mainnet`; two separate edits, by the user, on two separate days. ## Never - Never run the engine on two runtimes against one desk root at once. - Never let a Cowork or Grok Build session that cannot read the desk root claim to have supervised it. - Never put the key in a scheduled task prompt, a routine instruction, a cron line or a compose file committed to git. - Never skip a runtime's deny rules because the sender "checks anyway"; the two layers are the design.