swcstudiospace/hypergrok
Turn your agent into an autonomous Hyperliquid trading desk: seven specialist roles and twenty-four skills, a policy gate that replaces per-trade approval, one gated sender, a kill switch, and a Claude Code guard. Runs on Grok Bot and Claude Code.
Changelog
v2.4.0 - 2026-09-07
Five levers on what the desk earns, none of them a promise. The gate and the sender are unchanged; each lever either lowers a cost the desk was already paying, adds a bet that is not the same bet, or shrinks risk when the account is losing. No number here is a forecast.
Exchange costs. scripts/desk_send.py records the account's real fee tier from the Hyperliquid userFees call into autonomy/fees.json (taker, maker, at, source: userFees), and scripts/strategy_engine.py and the tickets it writes use that taker rate instead of the 0.045% default. scripts/execution_stats.py (new) reads the steps of every maker-first execution record, computes per-market post and fill counts and the fill rate (a partial counts as half), and writes autonomy/execution-stats.json with a recommended block per market: a small controller nudges maker_offset_bps (step 0.25 bps, bounds 0.25 to 4.0) and maker_wait_s (step 15 s, bounds 15 to 180) toward a fill-rate band of 45 to 75%, waits longer when fills arrive late, and waits longer again when fees.json shows a maker rebate. It needs five samples per market and moves one step per run, so a handful of trades cannot swing it. The engine applies the recommendation to new entry tickets as execution_override; it changes no params.json. python3 scripts/execution_stats.py --desk-root ..
More independent bets. Two strategy folders ship in template/strategies/, both status: draft with share: 0.5: hg-carry (a funding-carry tilt: weights carry 0.7 and momentum 0.3, carry lookback 168 h, an 8-hour decision clock, minimum hold 48 h, maximum 240 h, 3.5 ATR stop) and hg-breakout (a Donchian-style breakout: weights breakout 0.7 and momentum 0.3, breakout_hours 168, a 4-hour clock, maximum hold 120 h, 2.5 ATR stop, maker offset 0.5 bps and wait 30 s). Neither carries a review; each has a BACKTEST.md that says so and how to run one. engine/signals.py gains two factors: breakout (the close's position relative to the prior N-hour high-low channel, in ATR units) and oi_change (open-interest change over oi_change_hours, default 24, read from data/oi-<network>.jsonl, which the engine now records on every universe refresh; while OI history is not yet available the factor's weight is renormalised away). Both default to weight 0 in hg-systematic, whose record is unchanged. scripts/strategy_correlation.py (new) prints the daily-return correlation matrix between every reviewed strategy, from the curve that review.json now stores, plus a combined equal-weight curve; a pair above 0.7 is one bet with two names. It reads only and changes no share and no status.
Risk ladder. engine/risk.py (new). limits.risk_ladder in autonomy.json is a list of {drawdown_pct, scale} rungs, default [{"drawdown_pct": 3.0, "scale": 0.5}, {"drawdown_pct": 6.0, "scale": 0.25}]. The desk keeps the equity peak per network in autonomy/equity-peak-<network>.json; when drawdown from that peak crosses a rung, the engine's gross exposure and the gate's per-trade risk budget are both multiplied by the rung's scale, and the risk-per-trade gate detail says so (ladder 0.5 at 3.2% drawdown from peak). The gate validates the ladder when it loads the policy (rungs ascending, scales in (0, 1]) and refuses every ticket on a malformed one, like any other invalid policy. The backtester applies the same ladder from the same code and reports the bars it was active. It is a ceiling multiplier: it never enlarges anything, and a policy without one behaves as before.
Better data. engine/data.py gains l2_depth(network, coin, bps), the resting USD depth within N bps of the mid from l2Book. limits.min_depth_multiple (default 20): before an entry ticket is written, the engine reads depth within 10 bps on the entry side and, when it is below the multiple times the intended notional, defers the entry: no ticket, the decision stays open, and the strategy's decision is retried for limits.entry_retry_minutes (default 30) before it is marked done; an unavailable book defers the same way. A ticket that is written carries the depth it saw under engine.depth_usd_10bps. Open interest is recorded to data/oi-<network>.jsonl on each universe refresh, as above.
Longer and wider validation. scripts/engine_backtest.py gains --bar-hours {1,4,24}: 1h reaches about 207 days on Hyperliquid, 4h back to 2024-05, 1d to 2020; --ablate now runs each active factor (non-zero weight) removed and each alone, so a zero-weight factor does not pad the table. scripts/strategy_review.py runs two more checks from template/strategy-criteria.json: long-history (4h bars, 5000 bars, about 833 days; return at least 0% and drawdown no worse than -25%) and wide-universe (the top 40 by open interest on the 1h window; return at least 0%), each printed with its days, coins, bar size and trade count. As evidence of what the checks measure, not of what comes next: hg-systematic on 1h bars over 208 days returned +15.5% (+16.4% under the maker-first blend); on 4h bars over 833 days it returned +13.47% with a Sharpe of 0.83, a -7.06% maximum drawdown, +8.36% in-sample, +4.72% out-of-sample and a worst perturbation of -4.85%. Both figures are in template/strategies/hg-systematic/BACKTEST.md with the caveat that they are one backtest each. The review's universe is pinned: template/strategy-criteria.json gains universe_floors (min_day_volume_usd 5,000,000, min_open_interest_usd 10,000,000), applied to the base and long-history universes, and wide_universe gains the same two keys. The live policy's $20M 24-hour volume floor moves with the hour of the week (a Monday-morning run kept 15 coins where a weekday afternoon keeps 20 or more), so validation ranks by open interest with lower floors to get a universe that is the same from one run to the next; when the wide floors produce no more coins than the base run, wide-universe reports "not wider than the base run ... no separate evidence" and passes without counting as evidence. strategy_review.py now records every coin the exchange would not serve as summary.skipped_coins and runs history-complete as its first check, which fails the review when any coin in the ranked universe could not be read: a review on a partial universe is not the review the criteria describe (one run lost ETH to a 429 and the same strategy scored +18.6% on 15 coins and +2.7% on 12 coins an hour apart). Behind that, engine/data.py post_info retries HTTP 429, 502, 503 and 504 with backoff (2, 5, 12 and 30 seconds) before raising DataError; other errors are not retried. A review should state its universe count, and two reviews with different universes are not comparable.
Docs and inventory. No new skill, command, agent or hook; twenty-four skills, seven roles, five commands, one hook. README's engine section, the FAQ, desk-strategy-engine, desk-strategy-research, desk-operations, desk-autonomy-policy, the Strategist and Risk Manager prompts, the architecture doc and the supervisor cron example cover the five levers; desk-operations adds execution_stats.py (weekly, or after five or more fills in a market) and strategy_correlation.py (before raising any strategy's share) to the operator routine.
v2.3.1 - 2026-09-07
The seven role prompts in agents/ are rewritten at two to three times their previous detail and structured with XML tags (<role>, <mission>, <desk_context>, <responsibilities>, <procedures>, <evidence_standard>, <decision_rules>, <boundaries>, <formats>, <requests>, <failure_modes>, <tone>), carrying every rule, format block and request from before plus the gate, sender, engine, strategy research, paper record, re-review, dashboard and secrets mechanics. Bot profile cards and frontmatter are unchanged, so Grok Bot setup is unaffected; the system prompt is still what the runbook sends each Bot as its first message.
v2.3.0 - 2026-09-07
The desk can now be left alone as a service. Nothing about the gate or the sender's authority changes; the release adds what stands between paper and real money, what demotes a strategy when its own criteria stop holding, a cheaper way to enter, a page to glance at, and a key the desk never sees.
The paper-record gate. status: live is refused by the engine unless strategies/<name>/paper-record.json exists, is signed for the strategy's current review and says ready. scripts/paper_record.py (new) reads the engine's realised events for the strategy on testnet since its review and compares them with the backtest distribution in the signed review, applying the new paper block of template/strategy-criteria.json: at least 20 closed trades over 7 days, win rate within 15 points, average hold within 50%, stop rate within 20 points, paper drawdown no worse than 1.5 times the backtest's. It writes the record signed with the gate key over the review's digest; engine/strategies.py verifies it and lists a live folder without one under skipped. Nobody hand-writes it: hooks/guard.py adds paper-record.json to the protected files and template/claude/settings.json denies editing it. commands/paper-record.md adds /hypergrok:paper-record <name> [desk-root], which reports every check and, on ready, the one-line edit for the user to make by hand.
Maker-first execution. An entry ticket whose execution.style is maker-first is sent by desk_send.py as a post-only Alo limit at the mid moved inside by maker_offset_bps, with its stop grouped as before; the sender polls by cloid for maker_wait_s, cancels what did not fill, protects any partial fill with a standalone stop for exactly the filled size, then sends the remainder as the bounded IOC the ticket would have been, with its own stop, unless the mid has moved past the ticket's slippage bound, in which case the remainder is dropped and the record says so. Every step is under steps in proposals/<id>.execution.json; the whole sequence is one approval and one invocation, and the exit codes are unchanged. The engine copies execution_style, maker_offset_bps and maker_wait_s from params.json into each entry ticket; the shipped params.json sets maker-first. engine/backtest.py models it with a stated maker_fill_rate assumption: on the real 208-day backtest, fees fall from 137 to 114 USD on 10,000 and the return moves from +15.5% to +16.4% at 50% maker fills, +16.7% at 80%. One point, because the strategy trades slowly; the assumption is not a measurement, and the paper record measures the real rate from steps. scripts/test_maker_first.py has 6 tests.
Recent-window criterion and the weekly re-review with demotion. scripts/strategy_review.py adds recent_window_days (30) and recent_min_return_pct (-5), so a strategy whose last month looks nothing like its history fails even when the whole period passes. scripts/strategy_rereview.py (new) reruns the review for every paper and live strategy on fresh history and, on a rejection, demotes one rung: live to paper, paper to draft, written into RULES.md by the script with a strategy_demoted event in autonomy/events.jsonl and an alert. It is the only path that moves a status downward on its own; nothing moves one upward. --dry-run reviews and reports without demoting. Meant for the user's weekly cron; deploy/supervisor-cron.example carries the line, and the engine's 14-day review expiry is the backstop if the cron dies.
Dashboard. scripts/desk_dashboard.py (new) renders autonomy/dashboard.html from the desk's own files: policy mode, halt, engine heartbeat age, equity, positions and protection, the universe, the last cycle, an equity line from the start-of-day records and realised events, every strategy with its status, review, backtest, paper record and slots, the last decisions, sends, realised results, alerts and today's journal. One self-contained file, no external requests, refreshes itself every minute, nothing on it can act. --serve <port> is a read-only file server for the autonomy folder, for localhost and an SSH tunnel only. A ten-minute cron line is in deploy/supervisor-cron.example.
The key. engine/secrets.py (new) resolves the API wallet key in order: HYPERLIQUID_PRIVATE_KEY in the environment; HYPERGROK_KEY_COMMAND, a command run without a shell whose stdout is the key, with recipes for 1Password, AWS Secrets Manager, GCP Secret Manager, Azure Key Vault, HashiCorp Vault and Doppler in desk-operations; then HYPERGROK_KEY_FILE or ~/.hyperliquid/api-wallet.key, which must be mode 600 or 400 and owned by the running user or it is refused. The key must be a 32-byte hex string. desk_send.py is the only caller, at the moment it signs, and it reports the source, never the value. template/claude/settings.json denies reading engine.env. scripts/test_operations.py has 6 tests across the resolver, the re-review and the dashboard.
Events. Engine realised_gain and realised_loss events now carry strategy, hold_hours, exit and network, which the paper record, the dashboard and the Trade Reviewer's exit-mix comparison read.
Skill and inventory. skills/desk-operations (new) covers the key, maker-first, the paper-record gate, the re-review, the dashboard, alerts and metrics, and the operator checklist. The Desk Lead and Execution Trader list it. Twenty-four skills (seventeen upstream plus seven autonomy skills), seven roles, five commands, one hook; claude plugin validate passes (29 skills including the 5 commands, 7 agents, 1 hook). README gains "Running it as a service"; SETUP.md, the bootstrap, research, execution-protocol, engine, multi-runtime, Claude Code runtime and Hyperliquid setup skills, the agents, the team rule, architecture, FAQ, provenance, attribution and contributing cover the five features. The clone pin is v2.3.0.
v2.2.0 - 2026-09-07
The agents may now write strategies, and a deterministic gate decides which of them the engine runs. The gate and the sender are unchanged; a strategy is one more thing that has to pass a written check before it is allowed to ask.
Agents write strategies. Any strategies/<name>/ folder with RULES.md (frontmatter status: draft | paper | live, share, optional allowed_markets; the hypothesis and rules in prose) and params.json (any key of engine.signals.DEFAULT_PARAMS) is a strategy for the shared factor engine. The Strategist owns a daily research loop (skills/desk-strategy-research, new): hypothesis before numbers, a folder, the gate, paper on testnet, a week of supervised paper trading, then a promotion proposal in the journal for the user. Budget: three new folders a week, one review rerun per folder per day, no knob-nudging toward the data; the Trade Reviewer checks it.
The strategy gate. scripts/strategy_review.py with template/strategy-criteria.json backtests a folder on real hourly history with the engine's own code and applies the written criteria: 40 trades and 120 days, profit factor 1.1, drawdown no worse than -15%, fees at most 5% of starting equity, a positive out-of-sample second 40%, and robustness under perturbation (weights tilted plus and minus 0.2, entry threshold shifted plus and minus 0.25, stop multiple scaled 0.75 and 1.25: worst variant loses no more than 10%, at least half positive). It writes review.json signed with the desk's gate key over the exact RULES.md and params.json bytes. hg-systematic passes the defaults: worst perturbation (weights tilt -0.2) -4.85% with an -18.6% drawdown, 83% of perturbations positive. That is a bar met on seven months of history, not a forecast.
Multi-strategy engine. engine/strategies.py (new) is the registry: the engine runs every paper (testnet only) or live folder whose review verifies (matching bytes, this desk's key, verdict eligible, younger than 14 days) and lists every other folder under skipped in the heartbeat with the reason. Editing a reviewed file voids its review. Slots are split by share of the policy's max_positions; each strategy trades its own universe subset and keeps its own decision clock; positions are attributed to the strategy that opened them, a strategy never exits another's position, and a coin held by one is not entered by another. Tickets carry origin: strategist:<name>.
Promotion ladder. draft (anyone; ignored), paper (the Strategist may set it after an eligible review), live (the user only). hooks/guard.py denies any agent tool writing status: live and any edit to a live strategy's RULES.md or params.json, and adds review.json to the protected files; review.json and strategy-criteria.json are never agent-written. Grok Build's deny rules and the Cowork task prompt say the same.
Alerts and metrics. engine/alerts.py (new). Set HYPERGROK_ALERT_WEBHOOK to a Slack, Discord or generic JSON webhook and the desk posts halts, unknown send results and repeated unavailable reads as plain text with a UTC time and the desk name, never a key, an address or a full ticket. Every alert is appended to autonomy/alerts.jsonl whether or not a webhook is set. Each engine tick rewrites autonomy/metrics.prom, a Prometheus text file.
Command. commands/strategy-review.md adds /hypergrok:strategy-review <name> [desk-root]: runs the gate, pastes the output into BACKTEST.md, reports the verdict, the failed checks and the worst perturbation, may set paper on testnet, never live.
Plugin install. claude plugin validate passes (27 skills including the 4 commands, 7 agents, 1 hook), and the local-path install (claude plugin marketplace add <checkout> then claude plugin install hypergrok@hypergrok) works today while the GitHub push of the tag is pending.
Docs and inventory. README gains "Agents write strategies"; SETUP.md, the bootstrap skill, the engine, runtime, loop, lab and multi-runtime skills, the agents, the team rule, architecture, FAQ, provenance and contributing cover the folder contract, the gate, the ladder, alerts and metrics. Twenty-three skills (the seventeen upstream plus six autonomy skills), seven roles, four commands, one hook. scripts/test_engine.py has 21 tests. The clone pin is v2.2.0.
v2.1.0 - 2026-09-07
The desk gains a deterministic strategy engine, an honest backtester, one shipped strategy at status: paper, deployment files, and two more runtimes. Nothing about the gate or the sender changes: the engine is one more thing that writes tickets and asks.
The strategy engine. scripts/strategy_engine.py and the new engine/ package (universe.py, data.py, signals.py, portfolio.py, backtest.py; standard library only) trade the dynamic top-20 liquid perp universe on the hg-systematic factor model: cross-sectional z-scores of vol-normalised momentum (48h and 168h), funding carry (72h) and short-horizon reversion (24h EMA in ATR units), combined 0.5/0.3/0.2, with a BTC regime filter that halves risk in the top 15% of BTC volatility and halves the slots against BTC's 96-hour trend. A one-minute clock handles risk (protection for any naked position, reconciliation, halts after three failed reads or an unknown send) and a four-hour clock handles decisions (exits at a zero crossing after a 24-hour minimum hold or at 168 hours; entries past plus or minus 1.0, IOC at the mid moved by the slippage bound with a 3 ATR stop grouped with the entry, sized on the stressed stop and capped by a 1% daily-vol target, the notional cap and margin). Every ticket is written as proposals/<id>.ticket.json plus a proposal markdown with origin: strategist:hg-systematic, goes through policy_gate.py check, and on PASS is sent by one desk_send.py call. The engine owns autonomy/engine-state.json, engine-heartbeat.json, engine.log and universe.json, and never writes the policy, the limits, the gate key, the ledger or the halt file. --dry-run, --observe, --once and --loop --interval. Tests in scripts/test_engine.py.
The backtester and its record. scripts/engine_backtest.py runs the same signal and sizing code on real hourly candles and funding from Hyperliquid's public /info endpoint (candleSnapshot, fundingHistory), with fills at the next bar's open, slippage and taker fees both ways, stops checked against each bar's range and filled worse than their trigger, funding accrued hourly, an in-sample / out-of-sample split, per-factor ablation (--ablate) and a saved JSON of every trade. template/strategies/hg-systematic/BACKTEST.md records what happened: the first, fast configuration lost 46% to fees and stop churn; the chosen defaults returned +15.5% over 208 days with a 5.1% drawdown across 128 trades, positive in both halves; and equal factor weights on the same data returned -32%. The record says in its own words that this is one regime, highly parameter-sensitive, and not a forecast.
The shipped strategy. template/strategies/hg-systematic/ (RULES.md at status: paper, params.json, BACKTEST.md, the raw trade record) is copied into <desk-root>/strategies/ at setup. paper trades only while the policy is on testnet and the engine refuses it on mainnet; live is the user's edit, on a separate day from mode: mainnet. The guard now denies writes to params.json beside autonomy.json, risk-limits.md and the gate key.
Policy. allowed_markets: ["*"] means the engine universe: the gate reads autonomy/universe.json and treats it as stale after six hours. A list still intersects with it.
Deployment. deploy/hypergrok-engine.service (systemd, ProtectSystem=strict, the desk root as the only writable path), deploy/Dockerfile, deploy/docker-compose.yml, deploy/engine.env.example and deploy/supervisor-cron.example with the Claude Code and Grok Build cron lines.
Four runtimes. Grok Bot (engine as a background process on the desk computer, one Desk Lead routine for the cycle and a second that restarts the engine), Grok Build (CLI) (engine as a service, cycle from cron with grok -p ... --yolo and --deny rules), Claude Cowork (supervises a desk on the user's linked computer from a scheduled task; does not host the engine), and Claude Code (CLI) (engine as a service, cycle from cron through autonomy_cycle.py --once, the guard hook). desk-multi-runtime has the matrix and the pre-flight.
Supervision. While the engine's heartbeat is fresh and it is trading or observing, the cycle (commands/desk-cycle.md, desk-autonomous-loop) replaces its scan, ideas, size, gate and send passes with the engine checks in desk-strategy-engine section 6: the Desk Lead checks the heartbeat and halts if the engine is silent with positions open; the Risk Manager audits every engine ticket's gate block and the book's open risk; the Execution Trader reconciles the engine's sends and writes no ticket of its own; the Strategist reads the engine's decisions against the scan and drafts parameter changes for the user, never applying them; the Trade Reviewer grades engine trades on process and reconciles its realised_* events against userFills. The agent files, rules/hypergrok-team.mdc and template/claude/CLAUDE.md say so.
Docs and inventory. README gains "The engine" and "Four runtimes"; SETUP.md, the bootstrap skill and the runtime skills add the strategy copy and the engine start; architecture, FAQ, provenance and contributing cover the engine, the backtest and the runtimes. Twenty-two skills (the seventeen upstream plus desk-autonomy-policy, desk-autonomous-loop, desk-claude-code-runtime, desk-strategy-engine, desk-multi-runtime), seven roles, three commands, one hook. The clone pin is v2.1.0.
v2.0.0 - 2026-09-07
The first release of HyperGrok Autonomous Desk, an SWC Studio fork of galleonlabs/hypergrok-trading-desk taken at v1.4.2 (a80d82c). One thing changed: the desk no longer waits for a human to approve each ticket. Everything below follows from that.
The policy gate replaces approval by ticket id. The user writes autonomy.json once (template/autonomy.json; schema, ceilings and ownership in the new desk-autonomy-policy skill). The Risk Manager's PASS now also writes proposals/<id>.ticket.json, the same numbers as the markdown ticket in a shape a script can check. scripts/policy_gate.py check verifies that ticket against the policy, the autonomy ceilings (1% per trade, 4% open, 10x, six positions, -5% a day, 10 sends an hour and 60 a day, 50 bps, 30 minutes of ticket age), autonomy/HALT, the send ledger, the rate caps, the loss cooldown, the daily loss stop and live clearinghouseState and frontendOpenOrders, prints every gate with its numbers, and on a PASS writes proposals/<id>.approval.json: an HMAC over the ticket bytes keyed by autonomy/gate.key, valid ten minutes, dead if the ticket changes, spent by one send. A policy looser than a ceiling is invalid as a whole. An unavailable read is exit 2, never a PASS. The ## approval heading in proposal files stays and now holds the gate output. Twenty-two tests in scripts/test_policy_gate.py.
One sender. scripts/desk_send.py is the only file that signs an /exchange action. It re-verifies the approval, checks the environment's network and account against the ticket, refuses if the mid has drifted past the ticket's slippage bound or a stop is on the wrong side of the mark, rounds per hyperliquid-orders, writes intent and cloids to autonomy/sends.jsonl before the request leaves the machine, sends once with a one-minute expiresAfter, reconciles by cloid, and writes proposals/<id>.execution.json. Exit 3 is an unknown result: playbook A, no resend.
Kill switch. scripts/kill_switch.py halt|status|resume. Any role may halt and must when a send result cannot be resolved, a position cannot be protected, the loss stop is hit, reads do not reconcile, the exchange is unreachable for a cycle, or the policy fails validation. While halted, entry tickets fail the halt gate; close and protect tickets still pass. Only the user resumes: the script refuses --by desk, and the Claude Code guard denies the command. Every halt and resume is in autonomy/events.jsonl.
The autonomous cycle. desk-autonomous-loop defines one bounded, ordered, journaled cycle: pre-flight, book and protection, reconcile open sends, scan, ideas, size, gate, send, reconcile, journal, with the roles as labelled passes and a CYCLE block in the journal. scripts/autonomy_cycle.py --once|--loop runs it headlessly in Claude Code (claude -p "/hypergrok:desk-cycle <root>" --permission-mode bypassPermissions) with a lock, a heartbeat, a log per cycle and a timeout; Grok Bot runs the same cycle as one Desk Lead routine. The cycle is idempotent: it reconciles first and never re-sends an id in the ledger.
Claude Code is a first-class runtime. commands/desk-cycle.md, commands/desk-status.md and commands/desk-halt.md ship as /hypergrok:desk-cycle, /hypergrok:desk-status and /hypergrok:desk-halt. hooks/hooks.json registers hooks/guard.py as a PreToolUse hook for Bash, Edit and Write: it allows desk_send.py only with a valid approval, denies raw /exchange, fund-moving and agent-approving actions, kill_switch.py resume, and writes to autonomy.json, risk-limits.md, gate.key, the ledger and the halt file, and allows the read-only scripts and /info reads so nothing prompts. template/claude/settings.json sets bypassPermissions with explicit allow and deny rules; template/claude/CLAUDE.md is the desk root's standing note. desk-claude-code-runtime explains the layers and the verification list. Seven tests in scripts/test_guard.py.
Idea origination. With originate: true in the policy, the Strategist evaluates every strategies/<name>/RULES.md with status: live against the cycle's scan and may add at most one discretionary proposal per cycle with a stated invalidation. Every proposal records origin (user, strategist:<name>, desk:discretionary); with originate: false the gate fails any ticket whose origin is not the user's.
Behaviour changes to upstream rules. "Never run anything unattended that sends", "routines may not send" and "no standing approval covers a mainnet entry" are replaced by "only desk_send.py sends, only on a policy-gate approval, whether a human, a routine or a cron started the cycle". Watches still never send; a watch condition opens a proposal for the next cycle. The protective-stop standing-approval question in SETUP.md section 7 is moot: the gate always passes protect tickets, even while halted. A typed "approve " is still honoured on a conversational desk as origin: user and is evidence; the gate is the gate. Engagement levels gain a fourth, autonomous; the default first run stays research and autonomy defaults to testnet.
Setup and docs. SETUP.md stays read-only and now records autonomy: off in the desk record, expects the Execution Trader to refuse without a policy-gate approval file, lists all twenty skills, and points the user at desk-autonomous-loop sections 3 and 4 to switch autonomy on later. The Grok Bot template manifest is ready-to-publish with no public URL; the Grok Bot install is the manual bootstrap path until one exists. README, architecture, FAQ, template, provenance, contributing, security and the skills index are rewritten for the fork, and the pump.fun, cursor.directory and botdirectory references are removed. Install: /plugin marketplace add swcstudiospace/hypergrok-autonomous-desk, /plugin install hypergrok@hypergrok; the clone pin is v2.0.0.
Inventory. Twenty skills (the seventeen upstream plus desk-autonomy-policy, desk-autonomous-loop, desk-claude-code-runtime), seven roles, three commands, one hook. Upstream's unreleased doctor and instruction-audit changes below are carried in this release.
Upstream (galleonlabs/hypergrok-trading-desk)
The history below is the original project's, kept as it was at the fork point. Its version numbers are upstream tags, not tags of this repository.
Unreleased at the fork point
scripts/desk_doctor.pyverified the install with two hardcoded counts,EXPECTED_SKILLS = 17andEXPECTED_AGENTS = 7, so any seventeen directories holding aSKILL.mdpassed whatever they were named.SETUP.mdsection 1 supports unpacking an attached archive when the clone fails; an unpack that droppeddesk-risk-limitsand left a straydesk-risk-limits.bakbehind still counted seventeen, and the doctor reported 0 failed checks on a desk whose Risk Manager had no sizing skill.scripts/check.shcatches that, but section 3 andhypergrok-bootstraprun the doctor, not the gate. When the count really was short the user gotexpected 17, found 16and no way to tell which of seventeen directories to restore. The doctor now checks components by name against the lists the checkout already publishes and the gate already keeps honest - theskills/README.mdindex and theagents/<name>.mdprofilesSETUP.mdtells the user to create - so it names what is missing and there is no constant left to bump at a release, which is the same defect the version check lost in 1.4.1. A directory the index does not list now warns instead of failing: a missing skill is caught by name, so an extra can no longer mask one, and a user's own skill is not a broken desk. Five tests cover a missing skill, a renamed skill that keeps the count, a missing profile, an undeclared extra and a missing index; all five fail against the counting doctor they replace.- Audit agent and skill instructions against OpenAI's GPT-6 Astra guidance: clarify task continuity, material questions, blocker explanations, and proportionate verification while preserving financial authorization and evidence gates.
- Add a contributor AGENTS.md and allow independent bootstrap preparation while manual Bot setup is pending. The published Grok template and pinned release are unchanged; these source edits await the next release.
scripts/desk_doctor.pychecked that every skill the release names is present, not that it is the skill that was reviewed.SETUP.mdsection 1 judges the clone byscripts/check.sh, which compares each body to the sha256 intemplate/grok-bot.json, but section 9 andhypergrok-bootstraprun the doctor alone andREADME.mdoffers it as the desk's standing health tool. So a skill body edited or truncated after the install gate - adesk-risk-limitsthat no longer says what the desk agreed - was reported as a healthy desk with 0 failed checks. The doctor now reads the same manifest the checkout already ships and names every path whose bytes no longer match, and fails rather than reporting an unverified desk when the manifest is missing or claims nothing. Four tests cover an edited body, an unreadable body, a missing manifest and an empty one; all four fail against the doctor they replace.
1.4.2 - 2026-09-04
- The public Grok Bot contract now exposes its exact release in the visible description. A stdlib checker compares the logged-out profile, description, action and deep-link id with
template/grok-bot.json, with positive and drift fixtures in the local gate and a daily GitHub Actions check against the live preview. The release runbook now makes re-authoring and that external proof part of every release instead of leaving the public template to drift silently. - Audited all seven public forks. Six have no commits absent from upstream; the only diverged fork is a 526-file replacement with an unreleased Python execution runtime whose own support policy disables capital-bearing use, so it is a different product rather than a safe patch source. Its useful repository-review ideas were brought back as required redacted verification evidence on bug reports and required verification and rollback plans on improvements.
- Re-authored the public HyperGrok Desk Lead template with all seventeen version-pinned
v1.4.2skills and no plugins, memories or routines. Its botdirectory listing still says sixteen skills; the correction is open at https://github.com/elie222/botdirectory.ai/pull/279.
1.4.1 - 2026-09-04
- The Opening Bell marked bands the book did not reach as floors, but never went and got the depth.
l2Bookcaps a page at 20 levels per side, and at full price resolution those levels stop 8.2 bps from the mid on ETH and 2.7 on BTC, so on BTC all three of the 5, 10 and 25 bps rows printed the same>=floor - 53 BTC where the depth within 25 bps was 467, understating the real book roughly ninefold.hyperliquid-market-dataalready documented the fix, re-requesting withnSigFigs: 4; the demo the desk runs first ignored its own skill.scripts/opening_bell.pynow pages the book coarser (nSigFigs4, then 3) until the widest band is measured, reads every band off the finest page that reaches it, keeps top of book and spread on the full-precision page, and names the page each figure came from because bucketing moves the band edges. A band no page reaches is still a floor. Verified live: ETH, BTC, SOL, HYPE and kPEPE now measure all three bands, SOL and HYPE escalating to 3 sig figs. Two robustness fixes came with it: anulll2Bookbody raised an uncaughtAttributeErrortraceback instead of the script's own "unavailable" line, and an unusable coarser page no longer discards a snapshot the full page can serve. The market-data skill records the measured reach of each resolution and the ladder. - The Opening Bell reported depth at 5, 10 and 25 bps by summing whatever
l2Bookreturned, but that response is capped at 20 levels per side, and on a liquid perp those levels stop a few bps from the mid - measured live at 8.1 bps on ETH and 2.5 bps on BTC. Every band wider than that reach therefore printed the same number: the whole returned page, quoted as a measured total. A new desk read25 bps bid $5.16Mas the depth within 25 bps when the book had run out at 8, and three identical rows read as a flat book when the real one is deep.hyperliquid-market-dataalready required saying "beyond visible depth" past the visible levels; the demo the desk runs first did not.scripts/opening_bell.pynow records how many levels each side returned and how far they reach, quotes any band beyond that as>= size, and names the cut-off under the table. The snapshot JSON carrieslevels_returned,visible_reach_bpsand a per-side*_completeflag per band. A short book, which is the whole book, is still reported as measured. The market-data jq snippet returnslevelsandreach_bpsalongside the bands and documentsnSigFigs: 4as the way to reach past 20 bps, and the Market Analyst is told to quote the reach with the bands. scripts/desk_doctor.pycomparedplugin.jsonagainst a hardcodedEXPECTED_VERSION = "1.3.0", so shipping 1.4.0 turned the doctor against its own release: a correct, freshly pinned clone was toldexpected 1.3.0, found 1.4.0andSETUP.md does not pin v1.3.0, and the check the runbook and bootstrap skill both run in section 3 exited 1 on every new desk. The doctor now reads the release fromplugin.jsonand checks theSETUP.mdpin against that, so it cannot lag the tag it ships in, and it verifies its own file is present as the "release files" detail already claimed. A test runscheck_repositoryagainst the real repository, so this can only fail in CI.SETUP.mdsection 1 pinned the clone tov1.4.0while the sentence directly below it still explainedv1.3.0, telling the reader two different releases were the reviewed one.check_manifests.pyguarded thegit clonecommand but nothing else, so the prose, and theblob/<tag>links in the manual fallback, could drift a release behind unnoticed. The sentence no longer repeats the version, and the check now fails when any instruction file names a release tag other than the one the manifests declare.CHANGELOG.mdandCONTRIBUTING.mdare exempt: they describe past releases by design. Two negative fixtures cover stale prose and a stale documented URL.
1.4.0 - 2026-08-31
- Added a versioned Grok Bot template contract for HyperGrok Desk Lead: exact public profile, pinned source URLs, mascot, seventeen skill paths and SHA-256 hashes, with plugins, memories and routines explicitly empty.
hypergrok-bootstrapandSETUP.mdnow recognise skills imported with the public template, install only what is missing and fail readiness on same-name content drift instead of creating duplicates or trusting a name alone.scripts/check_grok_template.pyverifies the release pin, public safety copy, avatar, exact skill inventory and hashes, empty optional capabilities and published-link wiring. Five negative fixtures prove the gate rejects release drift, missing skills, stale hashes, bundled plugins and invalid share URLs.docs/GROK_BOT_TEMPLATE.mddefines authoring, logged-out preview and clean-install acceptance. The supported path is one click and one message: Add to Grok Bot, then Start the desk.- Published the public template at https://x.ai/bot/PReCwAHq8Vgeex50r883H and verified its logged-out page returns the exact profile, safety copy and Add to Grok Bot deep link.
1.3.0 - 2026-08-31
Fast-start Trading Floor release. A fresh Grok Bot workspace can now build the full seven-role desk through one bounded bootstrap skill, show useful live data before asking setup questions, and return machine-checkable readiness evidence.
-
hypergrok-bootstrap: installs the pinned release, rings the Opening Bell, prepares the desk, creates the seven role profiles and private Trading Floor where supported, installs all seventeen skills, writes a research-only desk record and returns a result for every required check. It refuses keys, exchange writes and public sharing during bootstrap. -
scripts/opening_bell.py: a zero-dependency, zero-key snapshot from Hyperliquid public/info, covering mid, mark, oracle, 24-hour change and volume, hourly funding, open interest, spread and visible 5/10/25 bps depth. Every output identifies source, network and UTC time and states that no account or order path was touched. -
scripts/desk_doctor.py: deterministic release, inventory, workspace and public-connectivity checks. It never reads environment variables or account state. A missing desk record or risk limits is a visible warning; a broken release, missing component or dead public API is a failure. -
Four Opening Bell tests and three desk-doctor tests now run in
scripts/check.sh, including depth arithmetic, crossed-book rejection, missing-desk warnings and a key-like material guard. -
README.md,SETUP.md, the architecture, FAQ and skills index now present the fast path and retain the complete source-driven fallback. The distribution carries seventeen skills and pins setup tov1.3.0. -
SETUP.mdsection 1 pins the clone to a release tag, andCONTRIBUTING.mdalready recorded that a drifted pin is worse than none - "if step 4 is skipped, the release ships instructions pointing at the previous one". Nothing enforced it: bumping all six manifests and leaving the--branchpin behind passedscripts/check.shgreen, so the one command every new desk runs first would have installed the previous release while the docs described the new one.check_manifests.pynow fails when a documentedgit cloneof this repository names a tag other thanv<manifest version>, names a moving branch, or carries no ref at all, with three negative fixtures covering those cases. -
README linked the live skills.sh listing at
/galleonlabs/hypergrok-trading-desk/hypergrok. skills.sh indexes skill directories, not the plugin id, so that page reportshypergrokis not in the repository even though the pack page (16 skills) is live. The link now points at the pack.check_manifests.pyfails if a documented skills.sh URL orskills addargument names a slug this repository does not ship. -
desk-risk-limitsandagents/risk-manager.mdquoted the worked example'sslip_stopof 3.00 as "10 bps" on the trigger, but 10 bps of the 2,900 trigger is 2.90, which gives a stressed distance of 105.55 and a size of 0.4831 ETH - not the 105.65 and 0.4827 ETH those files,README.mdanddesk-trade-lifecycleall carry. 3.00 is 10 bps of the 3,000 ticket price, which is howdesk-trade-lifecyclealready quotes slippage. Both glosses now name that reference price, so a Risk Manager showing every line of the arithmetic reproduces the desk's own numbers instead of contradicting them.slip_stopstays defined in price units; no figure in the worked example moves.
1.2.0 - 2026-08-29
Correctness pass across the Hyperliquid skills and the incident playbooks, closing the last findings from the fork audit that genuinely apply to a markdown desk. Three of these could strand a real position.
A partial close stripped the remainder's protection. hyperliquid-positions said to cancel orphaned TP/SL "after any close". After a partial close the position still exists and still needs its stop, so the sweep removed the protection from what was left. Clean-up is now conditional on reading clearinghouseState: cancel orphans only on a confirmed full close; on a partial close, replace a fixed-size stop before cancelling the old one, and leave a position-tied stop alone. Same fix in the desk-execution-protocol close procedure, which had the same reflex.
The TypeScript bracket carried no client order ids. The grouped entry/tp/sl example omitted c: on all three legs, while desk-execution-protocol requires a cloid on every send and the whole unknown-result recovery path is a lookup by cloid. A send built from that example could not be reconciled. Every leg now carries its own.
The dead-man's switch is not position-aware. scheduleCancel cancels protective stops along with everything else, so arming it with a position open leaves that position naked when it fires, and nothing re-arms it. It is now scoped to a desk with resting orders and no position, and firing with a position open is an unprotected-position incident rather than clean-up.
desk-incident-response: playbook A matches the recovery rule from 1.1.0 - a clean check is not proof, and a replacement waits for the original to expire. Playbook D no longer lets an unprotected position wait forever on a human: the first alert carries exposure and distance to liquidation, escalation runs on a deadline recorded indesk.md, and when it passes the desk tells the user to fix it in the Hyperliquid app rather than pinging a channel nobody is reading.- Standing approvals are scoped by what they can do rather than by network. The ceiling is now "no standing approval for a mainnet send that can open or increase exposure", with reduce-only protection as the explicit carve-out on any network - it can only reduce risk, and the alternative is a naked position waiting on a message.
SETUP.mdasks the user that question during setup and records the answer, with a deadline, indesk.md. docs/FAQ.md,SECURITY.mdandagents/execution-trader.mddescribed the pre-1.1.0 approval and unknown-result rules. They now match the skills.SETUP.md: note thatgit clone --depth 1 --branch <tag>prints a harmlessrefs/tags/... is not a commit!warning for an annotated tag, so a Bot following the file does not read it as a failed install and abort.
1.1.1 - 2026-08-29
Consistency pass over the surfaces 1.1.0 changed underneath. 1.1.0 corrected the sizing arithmetic but left the desk's worked example, README.md and docs/ARCHITECTURE.md describing the old behaviour, so the front page taught the bug the release had just fixed.
- The
HG-20260816-01example is now one trade end to end at 0.4827 ETH:README.md,desk-trade-lifecycle,desk-monitoring,desk-post-trade-review,agents/execution-trader.mdandagents/trade-reviewer.md. Sizing is proportional, so the R multiple (+0.9R) and the cost figure (16 bps of notional) are unchanged; notional, margin, fees, funding and PnL scale with the size. The generic SDK snippets inhyperliquid-orderskeep a round size on purpose - they teach API syntax and are not part of the narrative. README.md: the ticket shows the stressed distance it was sized from, and the guarantees section no longer implies the approval phrase is itself the gate.docs/ARCHITECTURE.md: trust boundaries carry the bounded-send and expiry rule, the approval boundary matches the operating model, andunavailableis documented as a verdict.CONTRIBUTING.md: a release procedure, becauseSETUP.mdpins a tag and a pin drifts silently the momentmainmoves ahead of it. Also records that the worked example is cross-file state, and corrects the stated skill body budget (320 lines, which is whatscripts/check.shenforces).
1.1.0 - 2026-08-29
Risk, evidence and recovery hardening. Several of these came out of reviewing a public fork of this repository, which audited the desk against production-custody standards; the findings that survived being a markdown desk rather than a signing service are below.
Sizing now stresses the stop. desk-risk-limits sized from the nominal stop distance, which assumes a triggered stop fills at its trigger price. It does not: a stop is a trigger order that becomes a market order, slips, and pays taker on both legs. Every trade therefore risked more than the budget said. Size now comes from stressed_distance (slippage plus both fee legs). On the desk's own worked example the old arithmetic spent 0.528% of equity against a 0.5% budget; the new arithmetic lands on the budget exactly. agents/risk-manager.md carries the recomputed example.
desk-risk-limitssection 0: desk ceilings the user's limits file may only tighten, never loosen - 2% per trade, 6% total open risk, 20x, -10% daily, mandatory exchange-resting stop, and no standing approval covering a mainnet send. They are deliberately far looser than any sane setting; they exist so a mistyped or corrupted file cannot authorise a catastrophic ticket. Enforced in the sizing arithmetic, not only asserted.unavailableis a verdict, not silence.desk-operating-modelmakes missing, stale, gapped, partial or cross-network data a first-class outcome that never collapses into "the condition did not fire".desk-monitoringapplies it to watches: a dead feed reporting "not crossed" looks exactly like a calm market, so every watch carries a staleness bound and alerts when it cannot tell.- The approval line is evidence, not the gate. The Bots write the floor's messages, so an approval a Bot can read is one a Bot could have written.
desk-operating-modelanddesk-trade-lifecyclenow put enforcement out of band and forbid a Bot writing, quoting forward, inferring or simulating the user's approval. - Unknown results: a clean read was never proof. A send that timed out can still land after any number of quiet checks.
desk-execution-protocolnow requiresexpiresAfteron every send in the pre-send checklist and treats a ticket as dead only when the original is provably incapable of arriving, withnoopas the fallback when no expiry was set. desk-strategy-lab: a freeze checklist for claims imported from outside (a repository of settings, a thread, a screenshot), multiplicity across every variant tried including the source's, a block-bootstrap lower bound beside the mean expectancy, a cost-doubling sanity check, and the rule that looking at the holdout spends it.desk-execution-protocol: repaired a rule that was truncated mid-sentence ("Never let a routine send.").SETUP.md: the install no longer falls back to piping an unverified archive from a mutable branch intotar. It clones a pinned tag, runsscripts/check.shbefore a desk is built from the tree, and records the installed commit indesk.mdso the desk can say which rules it is running.- Docs: the exact Claude Code install commands (the marketplace add and plugin install pair for the upstream repository), verified end to end against the published repository. "Open the repository, enable it" was not an actionable path in Claude Code even though the marketplace manifest shipped and worked.
docs/ARCHITECTURE.mdnow lists the.claude-plugin/manifests alongside the others.scripts/check_manifests.py: install commands in the docs must name a marketplace and plugin id this repository actually declares.- Fixed:
predictedFundingsis normalised by each venue's own funding interval. - Fixed: the WebSocket watch no longer points at the rejected
webData2subscription.
Note on versions: the v1.0.0 git tag pointed at an orphaned lineage (the earlier Python CLI, with src/ and pyproject.toml) that is not an ancestor of main, while the 1.0.0 entry below describes this markdown desk. The stale tag has been removed; v1.1.0 is the first tag that matches what this repository actually ships.
1.0.0 - 2026-08-16
Launch. There is no v1.0.0 git tag for this entry; see the versioning note in 1.1.0 above.
SETUP.md: the file a Grok Bot follows to build the desk - repository onto the computer, seven Bots from profile cards, sixteen shared skills, one Trading Floor group chat, approval rules, desk record, read-only verification, receipt.- Seven roles with full system prompts: Desk Lead, Market Analyst, Research Analyst, Strategist, Risk Manager, Execution Trader, Trade Reviewer.
- Eight Hyperliquid skills: setup and API wallets, market data, account reads, orders, positions and margin, WebSocket, advanced actions, API reference.
curlfor reads, official Python SDK and@nktkas/hyperliquidfor writes; snippets verified against the live API. - Eight desk skills: operating model, trade lifecycle, risk limits and sizing, execution protocol, monitoring, post-trade review, incident response, strategy lab.
- Docs: how the desk works, FAQ, provenance. Mascot in
assets/. scripts/check.shand CI: frontmatter, links, one-writer rule.- Plugin manifests and rule so Grok Build, Cursor and Claude Code load the same roles and skills.