Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions cli/mcp_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,42 @@ def funding_hedge_backtest(
return json.dumps({"error": str(exc)}, indent=2)
return json.dumps(backtest.to_dict(), indent=2)

@mcp.tool(**_ann("funding_hedge_execute", "Execute funding hedge"))
def funding_hedge_execute(
coin: str = "BTC",
dry_run: bool = False,
mainnet: bool = False,
confirmed: bool = False,
ctx: FastMCPContext = None,
) -> str:
"""Execute a BTCSWP funding-rate hedge on Hyperliquid. WARNING: places a real order.

Args:
coin: Coin to hedge (BTC, ETH).
dry_run: Preview only; do not sign or submit.
mainnet: Use mainnet instead of testnet.
confirmed: Explicit confirmation for hosted gateway sessions that require it.
"""
env_overrides = _request_env(ctx)
error = _context_limit_error(
"funding_hedge_execute",
env_overrides,
mainnet=mainnet,
confirmed=confirmed,
require_signing=not dry_run,
)
if error:
return _json_error(error)

args = ["hedge", "execute", coin]
if dry_run:
args.append("--dry-run")
if mainnet:
args.append("--mainnet")
if confirmed or env_overrides or dry_run:
args.append("--yes")
return _run_hl(*args, env_overrides=env_overrides)

@mcp.tool(**_ann("account", "Account state"))
def account(mainnet: bool = False, ctx: FastMCPContext = None) -> str:
"""Get Hyperliquid account state (balances, positions)."""
Expand Down
48 changes: 48 additions & 0 deletions docs/A2.8-strategy-def.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# A2.8 / A2.9 Strategy Definitions (Exhibit A)

**Signed:** Jae Lee — 2026-07-07
**Network:** HL mainnet, minimal funds

## A2.8 — `run_strategy` (run strategies)

| Parameter | Value |
|-----------|-------|
| MCP tool | `run_strategy` |
| Strategy | `cfi_hedge` |
| Instrument | `BTCSWP-PARA` (mainnet Paragon swap perp) |
| Tick interval | 10 seconds |
| Max ticks | 3 |
| Max notional | Bounded by AgentWallets spend/position caps (configure ≤ $5 spend, ≤ $2 position for tests) |
| Stop condition | `max_ticks=3` completes, or SIGINT from operator |
| Confirmation | `confirmed=true` on hosted gateway `live_trading` tier |
| Mock/dry-run first | Run once with `dry_run=true` before live |

**CLI equivalent:**

```bash
hl run cfi_hedge -i BTCSWP-PARA -t 10 --max-ticks 3 --mainnet
```

**MCP equivalent:**

```json
{
"name": "run_strategy",
"arguments": {
"strategy": "cfi_hedge",
"instrument": "BTCSWP-PARA",
"tick": 10,
"max_ticks": 3,
"mainnet": true,
"confirmed": true
}
}
```

## A2.9 — `apex_run` — BLOCKED

| Status | Reason |
|--------|--------|
| **BLOCKED** | `apex_run` MCP tool exists but Exhibit A danger-section substitute is A2.8 `cfi_hedge` per product scope (CFI funding hedge focus). |

**Acceptance:** A2.8 `run_strategy` with `cfi_hedge` satisfies the "run strategies" gate. Document BLOCKED in tracker; no Apex promotion required for July launch.
2 changes: 2 additions & 0 deletions docs/EXHIBIT_A_TESTING_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ This document is the **agent-cli** view of Exhibit A. Validation spans three rep

Use [`exhibit-a-tracker.md`](exhibit-a-tracker.md) to record PASS/FAIL/BLOCKED per test ID.

**Execute:** [`exhibit-a-execution-runbook.md`](exhibit-a-execution-runbook.md) — scripts, CI baseline, live smoke commands.

---

## Architecture
Expand Down
42 changes: 42 additions & 0 deletions docs/exhibit-a-ci-baseline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Exhibit A CI Baseline — 2026-07-07

Run before marking any live section PASS.

## agent-cli

```bash
cd ~/agent-cli
.venv/bin/python -m pytest tests/test_web_auth_signer.py tests/test_mcp_gateway_context.py \
tests/test_session_policy.py tests/test_mcp_annotations.py tests/test_hl_safety_read_tools.py \
tests/test_hedge_margin_port.py tests/test_entrypoint.py -q
.venv/bin/python scripts/validate_agent_cli.py --profile e2e
```

| Suite | Result | Notes |
|-------|--------|-------|
| Exhibit A pytest (7 files) | **120 passed** | Fixed `test_mcp_annotations` for manifest/runner drift |
| validate_agent_cli e2e | Run locally with `.venv/bin/python` | Requires Python 3.12 venv |

## web-auth

```bash
cd ~/web-auth && node --test tests/*.test.mjs
```

| Suite | Result |
|-------|--------|
| pair-hosted-invariants + seat-overage | **31 passed** |

## mcp-gateway

```bash
cd ~/mcp-gateway && npm test
```

| Suite | Result |
|-------|--------|
| vitest (5 files) | **29 passed** |

## Defects logged

See [`exhibit-a-defects.md`](exhibit-a-defects.md).
11 changes: 11 additions & 0 deletions docs/exhibit-a-defects.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Exhibit A Defects Log

| ID | Test | Severity | Status | Owner | Notes |
|----|------|----------|--------|-------|-------|
| D6-1 | A3.4 daily-loss limit | High | **BLOCKED** | web-auth | `dailyLossLimitUsdc` shown in `AgentWallets.tsx` / `SignConfirmModal.tsx` but **not enforced** in `api/pair.js` `sessionAllowsSign()`. Mark A3.4 BLOCKED until wired. |
| D6-2 | A3.1–A3.3 automated | Medium | Open | web-auth | No `sessionAllowsSign` unit tests — PR adds `session-policy-adversarial.test.mjs` |
| D6-3 | A2.9 apex_run | Low | **BLOCKED** | agent-cli | Substituted by A2.8 `cfi_hedge` per [`A2.8-strategy-def.md`](A2.8-strategy-def.md) |
| D6-4 | A2.6 schedule hosted | Low | **BLOCKED** | agent-cli | `schedule_cancel` blocked on hosted `entrypoint.py`; test via stdio MCP only |
| D6-5 | A2.10 funding_hedge_execute | High | **Fixed** | agent-cli | MCP tool added in `cli/mcp_server.py` (was in manifest but missing from runner) |

**Re-run rule:** Any A3 FAIL on live tests → fix D6 → re-run **entire A.3**.
45 changes: 45 additions & 0 deletions docs/exhibit-a-execution-runbook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Exhibit A Execution Runbook

Scripts and docs to execute [`EXHIBIT_A_TESTING_PLAN.md`](EXHIBIT_A_TESTING_PLAN.md).

## Quick start

```bash
# 1. CI baseline (all three repos)
cd ~/agent-cli && .venv/bin/python -m pytest tests/test_web_auth_signer.py tests/test_mcp_gateway_context.py \
tests/test_session_policy.py tests/test_mcp_annotations.py tests/test_hl_safety_read_tools.py \
tests/test_hedge_margin_port.py tests/test_entrypoint.py -q
cd ~/web-auth && node --test tests/*.test.mjs
cd ~/mcp-gateway && npm test

# 2. Local MCP smoke (no wallet)
cd ~/agent-cli
EXHIBIT_A_ALLOW_WRITE=1 .venv/bin/python scripts/exhibit_a_mcp_smoke.py --section all

# 3. Gateway smoke (needs token from POST /api/mcp/connect)
export EXHIBIT_A_MCP_URL=https://agent.nunchi.trade/mcp/trading
export EXHIBIT_A_MCP_TOKEN=tok_...
./scripts/exhibit_a_gateway_smoke.sh read_only

# 4. Cost experiment pilot
.venv/bin/python scripts/mcp_workload_experiment.py --agents 5 --days 1 --quick --dry-run

# 5. Gate D dry run
export EXHIBIT_A_AUTH_URL=https://auth.nunchi.trade
export EXHIBIT_A_PAIR_TOKEN=...
./scripts/exhibit_a_gate_d_dry_run.sh
```

## Related docs

| Doc | Purpose |
|-----|---------|
| [`exhibit-a-preflight.md`](exhibit-a-preflight.md) | Environment checklist |
| [`exhibit-a-ci-baseline.md`](exhibit-a-ci-baseline.md) | CI results log |
| [`exhibit-a-defects.md`](exhibit-a-defects.md) | D6 defect tracker |
| [`A2.8-strategy-def.md`](A2.8-strategy-def.md) | Danger-section definitions |
| [`exhibit-a-tracker.md`](exhibit-a-tracker.md) | PASS/FAIL/BLOCKED matrix |

## Reports directory

Automated runs write JSON/JSONL to `data/exhibit-a/` (gitignored).
33 changes: 33 additions & 0 deletions docs/exhibit-a-preflight.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Exhibit A Pre-flight Checklist

Completed: 2026-07-07

## Environment

| Repo | Status | Verify command |
|------|--------|----------------|
| agent-cli | Python 3.12.12 venv at `.venv/` | `.venv/bin/python -m cli.main setup check` |
| web-auth | `npm install` OK | `node --check api/pair.js` |
| mcp-gateway | `npm install` OK | `npm test` |

**Note:** Use `.venv/bin/python` — system Python 3.9 lacks dependencies.

## Staging URLs

| Service | URL | Check |
|---------|-----|-------|
| web-auth | https://auth.nunchi.trade | HTTP reachable |
| mcp-gateway | https://agent.nunchi.trade | HTTP reachable |
| MCP trading | `POST https://agent.nunchi.trade/mcp/trading` | Requires bearer token |

## Live test prerequisites (Sam)

- [ ] Privy master wallet on HL **mainnet** with minimal USDC
- [ ] Agent sub-wallet created and bound via AgentWallets
- [ ] Caps configured in AgentWallets (spend, position, expiry)
- [ ] Screen recorder + shared folder for MCP JSON-RPC logs
- [ ] Railway runner URL confirmed in gateway env (`NUNCHI_MCP_TOOLS_RUNNER_URL`)

## Network decision

**Mainnet-with-minimal-funds** per July PDF. Set `HL_TESTNET=false` / mainnet consent in gateway tier for danger-section tests.
Loading