pathiel-agent · diff
v2.0.0 to v2.0.0
6 added, 7 removed. Audit A to A.
---
name: pathiel-agent
description: Use when operating, maintaining, or debugging pathiel — the headless Hyperliquid trading desk Claude trades through its MCP server. Covers place_bracket/bracket_sweep/close_position, the risk-profile sizing path, MCP tool wiring, and Hyperliquid order-placement gotchas.
version: 2.0.0
author: Pathiel Agent
license: MIT
metadata:
pathiel:
tags: [trading, hyperliquid, mcp, quant]
related_skills: [hyperliquid-agent-wallets]
homepage: https://github.com/Julian-dev28/pathiel
---
# Pathiel Trading Desk
`pathiel` is a **headless Hyperliquid trading desk** (operator decision,
2026-10-23): Claude is the only trader on the wallet, placing every trade
through the **MCP server** (`scripts/pathiel-mcp-server.py`, registered in
`~/.pathiel/config.yaml` under `mcp_servers.pathiel`) — `place_bracket`,
`bracket_sweep`, `close_position`. There is no autonomous scan/research/
execute engine any more: the old scan→research→execute pipeline, its
trigger config, TA filter, risk gates, DSL exit loop, and the seven
strategy books it used to run are all retired. See
`docs/overhaul/HEADLESS_2026-10-23.md` for the wave-1 (strategy-book)
retirement and its wave-2 addendum (the engine itself) for the full history,
and `.claude/skills/desk-tick/SKILL.md` for the loop Claude actually runs
today: `/desk-tick <desk>` on a cron per active desk (oil every 15 min;
metals, ai and gas every 30 min), one position per account across all
desks, so a desk whose coin does not hold the slot logs SKIP and stops.
Repo: `/Users/julian_dev/Documents/code/pathiel`. The user may work on
dirty local branches and switch deploy branches between sessions. **Commit/push
only when the user asks, and never push directly to another branch without
explicit confirmation.**
## How a trade happens now
1. **Read the call.** `desk_brief {desk}` (oil is primary) for the desk's
current thesis, or `desk_refresh` to force a new one. `risk_limits` /
`risk_size_trade` for what the account may trade and how big — size
every trade with `risk_size_trade`, never by hand.
2. **Place it.** `place_bracket {coin, entry_px, stop_px, tp_px}` — one
entry with an exact stop and target. It sizes through
`services/risk/size.py`'s `size_trade()` against the operator's saved
risk profile, checks the stop against liquidation
(`pathiel.agents.bracket.check_leverage`), and refuses under the 1.5R
minimum or when a position/entry already exists on the coin.
3. **Housekeep.** `bracket_sweep {coin}` after every close: cancels the
stranded sibling order left by a fired stop/target and confirms an open
position is covered by a stop.
4. **Close.** `close_position {coin}` — market-closes with `reduce_only`,
cancels the coin's remaining SL/TP bracket, and reports the realized
PnL. Implemented in `pathiel/agents/bracket.py`'s `close_position()`
(moved there from the retired `executor.close_position_market`,
2026-10-23 wave 2).
Full tool list and safety annotations: `docs/overhaul/MCP.md`
(59 tools, generated by `scripts/mcp_tool_table.py` — regenerate it after
any tool change, never hand-edit).
## Running the server
Use `scripts/restart.sh` as the canonical process manager:
```bash
scripts/restart.sh # restart server + log rotator
scripts/restart.sh server # restart FastAPI server only
scripts/restart.sh stop # stop both, don't start
scripts/restart.sh status # show what's running
```
Logs land in `logs/server.log`. The MCP server
(`scripts/pathiel-mcp-server.py`) is intentionally NOT managed by
restart.sh — it's a transient stdio process respawned by the MCP client
on each tool call. If MCP code is stale: `pkill -f pathiel-mcp-server.py`
and the next tool call respawns it fresh.
Manual foreground launch is only for debugging: `python -m pathiel.server`.
There is no trading loop or scheduler process any more (both retired
2026-10-23, wave 2, with the rest of the autonomous engine) — only the
dashboard/API server and the log rotator run as standing processes.
## Risk sizing
Every trade sizes through `services/risk/size.py`'s `size_trade()`:
`notional = (equity × risk_per_trade_pct) / stop_distance`, clamped by the
operator's saved risk profile (`risk_limits` MCP tool / `/api/risk/*`) and
the coin's exchange max leverage. Leverage is already baked into the
notional — `position_notional = trade_notional`, never
`trade_notional × leverage` again. `pathiel.agents.bracket.min_tradable_equity`
is the structural floor below which the exchange can't clear a $10 order at
all; `services.risk.books.main_engine_spec` is the one `BookSpec` the
feasibility check (`risk_limits`/`risk_size_trade`/`place_bracket`) prices
against — there is no per-book roster any more.
## Operator rules (2026-10-24)
- The live risk profile (`.agent-config.json` → `risk_profile`) is
`risk_per_trade_pct 100`, `daily_loss_limit_pct 100`, `max_leverage 20`,
`max_open_positions 1` (contract `contracts/risk/models.py` 1.1.0 allows
100). One full-port position per account across every desk
(`pathiel.agents.bracket.slot_taken_by`; `scripts/desk_slot.py` is the
tick's first step).
- Never add to an open position. The operator wants the whole stake in one
position; the NEXT bracket sizes full-port, a filled one is left to its
stop or target. Never widen a stop.
- `set_leverage {coin, leverage}` on an open position keeps that position's
own margin type (isolated on HIP-3; the venue refuses a type switch with
a position open) and treats a venue "err" as an error. Hyperliquid keeps
the isolated margin in place, so the liquidation price does not move.
Confirm with `get_asset_positions`.
- The Desk page (`/`) is where the operator reads positions: the Wallets
card shows entry, mark, P&L, R, leverage, margin in use, liquidation,
stop and target for the Active account; a flat watch-only wallet shows
no card. `services/accounts/positions.py` reads only dexes holding at
least $1 or a position, raises on a venue read that never answered, and
serves the last good snapshot through a failed refresh.
- The dashboard server's venue budget is 200 burst + 8/s
(`scripts/restart.sh`); `GET /api/health/system` → `hl_budget` lists
weight granted and refused per request type and caller
(`pathiel/client/hl_client.py` labels every request `type<module.function`).
A page showing dashes or "No open positions" while the venue shows a
position starts there, never with the page.
## Asset-class / dex toggles
`.agent-config.json` carries:
- `enable_hip3` (default `true`) — includes HIP-3 perpDexes (xyz / vntl /
km / ...) in market reads.
- `hip3_dex_allowlist` / `hip3_dex_blocklist` — which HIP-3 dexes
`get_universe()` fetches at all (a cost control on market/desk reads, not
a per-trade safety gate — Claude names the coin explicitly on every
`place_bracket` call, so the discipline that used to be an autonomous
allowlist refusal is now the desk-tick skill's own scope).
- `coin_allowlist` / `coin_blocklist` — bare-ticker majors restriction
(`pathiel/agents/universe.py`), matched by bare ticker so one entry
covers every venue prefix for the same underlying.
2026-10-23 (wave 2) dropped `enable_crypto` and every per-trade sizing/
gating knob the retired autonomous engine read (leverage, equity-fraction,
the confidence/volume/regime gates, `dsl_exit`, `runner_entry_gate`, ...) —
see `pathiel/agents/config_store.py`'s `DEFAULT_CONFIG` for the full list
of what left and why.
- ## AI Brain Providers
+ ## LLM access
- `ai_brain` stays — `services/thesis`'s desk-refresh research and
- `services/trend_engine` both call `pathiel.agents.ai_brain.get_brain()`.
- Valid providers: `openrouter` (default HTTP), `claude_cli`
- (`claude -p --output-format json`), `codex_cli` (`codex exec --sandbox
- read-only --ephemeral -`). Selector precedence: `AI_BRAIN_PROVIDER` env
- var, then `.agent-config.json` → `ai_brain.provider`, then `openrouter`.
+ The one model call is the desk thesis writer: `services/thesis` through
+ `services/llm`, the local Claude Code CLI gateway (`PATHIEL_LLM_MODEL`
+ overrides the model). The bot-era `pathiel/agents/ai_brain.py` provider
+ switch (`openrouter` / `claude_cli` / `codex_cli`, `AI_BRAIN_PROVIDER`,
+ the `ai_brain` config block) was deleted 2026-10-25 with its last caller.
## State Files
Project state (all gitignored):
- `.agent-config.json` — mode (OFF/LIVE), AI brain provider, risk profile,
HIP-3 dex allow/blocklist, coin allow/blocklist
- `.state/strategies/<desk>/{theses,trades}/` — every desk's thesis and
trade journal (`services/strategies/journal.py`, `trades.py`) — the
evidence base under every graded call; back it up (`scripts/
backup_state.py`) the same way `.agent-memory.json`/`shadow_ledger` used
to matter.
- `.state/capital_flows.jsonl` — deposits/withdrawals, for flow-neutral
drawdown.
- `auth.db` — users, sessions, login nonces (`services/auth`).
- `logs/server.log` — the dashboard/API process log.
`.agent-memory.json`, `.dsl-state.json`, `.rebalancer_claims.json` and
`.state/shadow_ledger/` no longer exist — their writers
(`pathiel.agents.memory`, `dsl_exit`, `rebalancer_owned`'s claims registry,
`shadow_ledger`) are all retired.
## Hyperliquid gotchas
See `references/hyperliquid-gotchas.md` for order-placement gotchas
(decimals, tick size, the $10 minimum, client singletons, unified-account
equity). Still fully current — these are exchange facts, not bot-specific.
## MCP Server
`scripts/pathiel-mcp-server.py` (stdio, 59 tools) is registered the same
way it always was — see `references/mcp-config.md` for the config block
and tool-parameter table, `references/mcp-server.md` for server structure,
adding tools, and the audit invariant
(`scripts/audit_mcp_server.py` / `skills/pathiel-agent/scripts/
audit_mcp_server.py` — run before and after editing the server).
## Unified Accounts
On a Hyperliquid unified account the agent wallet signs orders while the
master account holds funds; `resolve_user_address()` picks
`HYPERLIQUID_MASTER_ADDRESS` first, else `HYPERLIQUID_WALLET_ADDRESS`.
Equity reads come from the master. For agent-wallet setup and the
`approveAgent` flow, see the `hyperliquid-agent-wallets` skill.
## HIP-3 Tokenized Equity / Commodity Perps
HIP-3 markets are namespaced as `<dex>:<symbol>` and live on separate
clearinghouses (`xyz`, `km`, `vntl`, `flx`, `hyna`, `abcd`, `cash`, `para`).
`fetch_account_state(..., include_hip3=True)` aggregates equity across
main + every HIP-3 dex. `place_bracket`/`close_position` check the target
dex's own balance before placing — a HIP-3 order on an underfunded dex is
refused, since agent wallets cannot transfer between dexes automatically.
## References
- `references/mcp-config.md` — MCP server config and tool list.
- `references/mcp-server.md` — server structure, adding tools, the audit invariant.
- `references/hyperliquid-gotchas.md` — order-placement gotchas (decimals, tick size, $10 min, singletons).
- `../../docs/overhaul/MCP.md` — the generated 59-tool table with safety annotations.
- `../../docs/overhaul/HEADLESS_2026-10-23.md` — the full headless-desk retirement history (wave 1: the strategy books; wave 2: the autonomous engine itself).
- `../../.claude/skills/desk-tick/SKILL.md` — the per-desk tick Claude actually runs (`/desk-tick oil|metals|ai|gas` on crons).