Skip to content

Repository files navigation

TraceGuard

A fail-closed safety runtime for AI trading agents on Bitget Agent Hub.

Bitget Agent Hub lets an AI agent reach real trading tools over MCP. TraceGuard sits between the agent and that tool surface and makes every trade-like action governable, approvable, single-use, replayable, and auditable — without slowing down harmless read-only analysis.

The core thesis is one sentence:

An agent that can call a trading tool is one hallucination away from an unwanted order. TraceGuard makes "place an order" structurally impossible unless a policy passed, a human approved that exact action, and the authorization had not already been spent — and it records the whole chain so you can replay why.

This repository is a working TypeScript implementation of that runtime with a deterministic, offline, one-command demo (pnpm demo) so anyone can reproduce a governed run without an exchange account.


Why this is infrastructure, not a trading bot

TraceGuard does not decide what to trade. It governs how an agent is allowed to use trading tools:

  • Manifest governance — imports the upstream tool list, fingerprints it, and classifies every tool by risk (public_read, account_read, trade_like, asset_movement, administrative). Public reads pass; asset movement and admin tools are blocked by default; unknown tools are frozen pending review.
  • Policy evaluation — trade-like proposals must carry a structured Decision Envelope and are checked against bounded limits (instrument allow-list, notional, leverage, approval thresholds) before anything is forwarded.
  • Single-use human approval — an approval is bound to one exact action digest and can be consumed exactly once ("burn-before-execute"). Approving an action is not granting standing permission.
  • Fail-closed execution — if policy fails, approval is denied, the authorization was already spent, or the upstream result is an error, no order reaches the exchange and the run ends RunFailed.
  • Hash-chained audit ledger — every step is an append-only, hash-linked event. Runs replay deterministically from the ledger.
  • Redaction — credentials and raw order bodies never enter the ledger or the agent-facing transcript.

Architecture

        AI trading agent  (Claude, Codex, any MCP client)
                     |
                     |  tool calls + Decision Envelopes
                     v
   +-- TraceGuard MCP gateway --------------------------------
   |      manifest governance    (risk classes)
   |      policy evaluation      (bounded limits)
   |      single-use human approval
   |      burn-before-execute
   |      fail-closed execution adapter
   |      redaction
   |      hash-chained audit ledger
   +---------------------------------------------------------
                     |
                     |  only authorized, in-policy actions
                     v
         bitget-mcp-server   (Bitget Agent Hub MCP server)
                     |
                     v
            Bitget market data  /  paper trading

TraceGuard is Bitget-first in product and provider-neutral in architecture: the first adapter targets Bitget Agent Hub, while the core ledger, policy engine, and execution interfaces are provider-agnostic.

The governed lifecycle

A protected run moves through six internal traceguard_ tools the gateway exposes alongside the upstream Bitget tools. Each one appends to the ledger and returns a governance envelope at result.traceguard:

Step Tool What it enforces
1 traceguard_start_run Open an audited run against a fingerprinted manifest.
2 traceguard_record_decision Capture the agent's Decision Envelope (instrument, action, thesis, requested notional).
3 traceguard_request_execution Evaluate policy; if it requires approval, mint a single-use authorization.
4 traceguard_check_approval Resolve the human decision (granted / denied) for that exact action.
5 traceguard_execute_authorized_action Burn the authorization, then call the execution adapter — fail-closed.
6 traceguard_finish_run Close the run and seal the ledger chain.

Quick start

Requirements

  • Node.js ≥ 22.12 (developed on v24)
  • pnpm (developed on 10.x) — npm install -g pnpm or corepack enable

The default demo is fully offline and needs no exchange credentials.

Install

git clone git@github.com:StarryDeserts/TraceGuard.git
cd TraceGuard
pnpm install

Run the demo

pnpm demo

This reproduces the governed run from the append-only ledger and prints the redacted transcript. It first runs a test that rebuilds the transcript in-memory from the real gateway runtime and asserts it byte-for-byte equals the committed sample — so a green run is proof the output is generated by the code, not a static file. Expected output:

==> Reproducing the governed run (deterministic backend, no live exchange)…

 Test Files  1 passed (1)
      Tests  1 passed (1)

================================================================
  Governed run transcript — replayed from the append-only ledger
================================================================

# TraceGuard — Governed Paper-Trading Demo
...
## Happy path — approval granted, paper order placed
1. Run run_1 started by demo-agent — Governed paper-trading demo
2. Decision dec_1: buy BTCUSDT (spot), size 2500
3. Approval appr_1 requested — policy outcome: require_approval
4. Approval granted by ops-desk
5. Authorization authz_1 consumed
6. Execution simulated — receipt receipt:exec_1
7. Run finished — completed

## Fail-closed — approval denied, nothing reaches the exchange
1. Run run_1 started by demo-agent — Governed paper-trading demo
2. Decision dec_1: buy BTCUSDT (spot), size 2500
3. Approval appr_1 requested — policy outcome: require_approval
4. Approval denied by ops-desk
5. Run finished — completed

The two scenarios are the whole point: the same proposal is approved once and paper-executed in the happy path, and denied in the fail-closed path where nothing reaches the exchange.

Run the live paper-trading demo

pnpm demo is deterministic and offline. To go one runnability tier further and exercise the same governance against the real Bitget Agent Hub MCP server on live market data:

pnpm demo:live

This boots the TraceGuard gateway in front of bitget-mcp-server --paper-trading and, reproducibly, proves the governance holds against a real upstream:

  • the gateway imports and fingerprints the real upstream tool manifest, and asset-movement tools (withdraw, transfer, …) are excluded by default;
  • a real spot_get_ticker BTCUSDT call against Bitget passes governance;
  • a raw spot_place_order with no Decision Envelope is rejected (DECISION_ENVELOPE_REQUIRED);
  • an in-policy decision (2× leverage) is ALLOWED and an out-of-policy one (10× leverage) is POLICY_BLOCKED.

Unlike pnpm demo, this needs network access and spawns bitget-mcp-server --paper-trading, which uses public market data only — no API keys, no private endpoints, no real funds. It runs the live integration test gated behind the TRACEGUARD_LIVE_MCP env var, so the gate is opt-in and the default pnpm test suite stays offline.

Verifiable usage record

Two committed artifacts back the runnability claim:

  • Offline transcriptdocs/superpowers/demo/sample-governed-run.md, the sample input/output pnpm demo reproduces. The demo's golden test asserts the runtime still produces exactly that file byte-for-byte.
  • Live event logdocs/superpowers/demo/live-paper-trading-evidence.md, a hash-chained, timestamped ledger captured running against the real bitget-mcp-server --paper-trading. It shows the full burn-before-execute chain fail-closing at the live exchange, and an approval-denied run where nothing reaches the exchange. The raw logs (happy · denied) are committed so a reviewer can verify the hash chain independently.

Integrating TraceGuard with Bitget Agent Hub

1. Build the governed gateway

The gateway ships as a single self-contained MCP server. Bundle it once:

pnpm install
pnpm build:bin

This produces packages/mcp-gateway/dist/bin/gateway-local.mjs — a portable ESM bin that runs under plain node, no TypeScript runner required. Smoke-test it directly; it reports how many governed tools it serves and then stays up holding an MCP stdio connection:

pnpm gateway
# [gateway-local] served tools: 31
# [gateway-local] manifestHash: 3a2999…

2. Point your MCP client at TraceGuard (not at Bitget directly)

The agent connects to TraceGuard, and TraceGuard launches bitget-mcp-server --paper-trading as its own upstream — so every Bitget tool the agent can see has already been risk-classified and wrapped in the governance pipeline. Registering Bitget directly with your client instead would bypass governance entirely. Add the gateway to any MCP-capable client (paths must be absolute):

{
  "mcpServers": {
    "traceguard": {
      "command": "node",
      "args": [
        "/absolute/path/to/TraceGuard/packages/mcp-gateway/dist/bin/gateway-local.mjs"
      ],
      "env": {
        "TRACEGUARD_LEDGER_DIR": "/absolute/path/to/your/traceguard-ledger"
      }
    }
  }
}

For the Claude Code CLI the equivalent one-liner is:

claude mcp add -s user traceguard -- \
  node /absolute/path/to/TraceGuard/packages/mcp-gateway/dist/bin/gateway-local.mjs

TRACEGUARD_LEDGER_DIR is optional: when set, the hash-chained ledger is persisted to <dir>/<workspaceId>.jsonl so runs survive restarts and stay independently auditable; when unset, the gateway keeps the ledger in memory. The bundled bin always runs its upstream in --paper-trading mode (public market data only — no API keys, no real funds).

The gateway:

  1. calls tools/list upstream, maps and fingerprints each tool, and assigns a risk class;
  2. exposes the upstream read tools plus the six traceguard_ governance tools;
  3. routes every trade-like call through the policy → approval → burn → execute pipeline above.

The same path is exercised live in this repo against bitget-mcp-server --paper-trading via the gateway's live backend (StdioUpstreamClient spawning the server, with the bitget_live execution adapter). The deterministic demo substitutes a fake upstream and a simulator adapter so it runs offline and byte-reproducibly.

3. Execution adapters and capability gating

Adapter When Behavior
simulator (default) Safe demo, replay Produces a receipt without touching any exchange.
bitget_live Only when explicitly selected Forwards to bitget-mcp-server; an upstream error throws and the run goes RunFailed (fail-closed).

Live execution is treated as a capability-gated adapter, not a default. See docs/bitget-agent-hub-integration.md for the full capability-detection and tool-classification design.


Safety boundaries — what is real, simulated, and not claimed

Real:

  • real governance logic (manifest fingerprint, policy evaluation, single-use approval, burn-before-execute, fail-closed execution);
  • a real append-only, hash-chained ledger that replays deterministically;
  • real redaction of credentials and order bodies.

Simulated by default:

  • order execution (the demo uses the simulator adapter and labels receipts as simulated). No real funds are ever used.

Not claimed:

  • not officially endorsed by Bitget;
  • does not guarantee safe trading or eliminate market risk;
  • does not perform live order execution by default. Note Bitget Agent Hub's own docs state order execution is not fully implemented upstream yet, so the bitget_live happy path currently ends fail-closed (RunFailed) rather than with a filled order — which is exactly the safe outcome TraceGuard is built to produce when execution cannot be confirmed.

Repository layout

packages/
  schemas/            zod schemas: events, Decision Envelope, scalars
  event-ledger/       append-only hash-chained ledger + canonical JSON
  tool-manifest/      upstream tool import, fingerprinting, risk classification
  policy-engine/      deterministic policy evaluation
  domain/             execution adapter + transition types
  runtime/            simulator + bitget_live execution adapters, orchestrator
  mcp-gateway/        the MCP gateway, internal traceguard_ tools, demo, bundled bin
  testing-fixtures/   shared test fixtures
docs/                 product spec, threat model, event/data/replay models, demo
scripts/demo.sh       one-click deterministic (offline) demo
scripts/demo-live.sh  one-click live paper-trading demo (real bitget-mcp-server)

Development

pnpm test        # run the full vitest suite (offline)
pnpm typecheck   # tsc --build type gate (vitest does not type-check)
pnpm build:bin   # bundle the gateway into a standalone node bin
pnpm gateway     # launch the bundled governed gateway (paper-trading upstream)
pnpm demo        # reproduce the governed-run transcript (offline)
pnpm demo:live   # govern a live run against bitget-mcp-server --paper-trading

Note on running entrypoints: each workspace package resolves to its TypeScript source ("main": "./src/index.ts"), so tests and the demo bins run through vitest (the project's TS runner), not node dist/.... The shippable exception is the gateway itself: pnpm build:bin bundles it with esbuild — inlining the workspace packages and rewriting their .js import specifiers back to source — into a standalone packages/mcp-gateway/dist/bin/gateway-local.mjs that runs under plain node. That bundled artifact is what MCP clients launch.


Documentation

Doc Purpose
product-spec.md What TraceGuard is and the v0.1 slice
architecture.md System architecture
bitget-agent-hub-integration.md Bitget-first integration design
threat-model.md Threats and mitigations
event-model.md · data-model.md Ledger events and aggregates
policy-semantics.md Policy evaluation semantics
replay-contract.md Deterministic replay guarantees
mcp-gateway-contract.md Gateway / tool contract
demo-script.md Full demo narrative
submission-zh.md 中文项目提交描述 (Chinese submission writeup)

Built for the Bitget AI Base Camp Hackathon S1 — Trading Infra track.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages