10.1 · Trading account

One user-owned master wallet, one Privy-managed execution wallet

TradingAccount

Privy
type TradingAccount = {
  id: string;
  userId: string;
  environment: "hyperliquid_testnet";

  masterWallet: {
    privyWalletId: string;
    address: `0x${string}`;
    ownership: "user";
  };

  executionWallet: {
    privyWalletId: string;
    address: `0x${string}`;
    hyperliquidAgentName: string;
    status:
      | "creating"
      | "awaiting_approval"
      | "approved"
      | "revoked"
      | "error";
    approvedAt?: number;
  };

  status:
    | "onboarding"
    | "ready"
    | "agent_revoked"
    | "account_unavailable"
    | "error";

  createdAt: number;
  updatedAt: number;
};

The execution wallet signs actions. Hyperliquid account state is queried with the master-wallet address.

10.2 · Harness binding

One provider, bound for the life of a POC mission

TradingHarnessBinding

T3 server
type TradingHarnessBinding = {
  provider: "codex" | "claude" | "opencode";
  providerInstanceId: string;
  providerSessionId?: string;
  resumeCursor?: string;
  threadId: string;
  model?: string;
  status: "available" | "unavailable";
};

The binding is immutable for an active POC mission.

10.3 · Trading mission

The durable mandate that outlives each harness turn

TradingMission

Harness
type TradingMission = {
  id: string;
  userId: string;
  tradingAccountId: string;

  instruction: string;
  market: "ETH";
  strategyFamily: "momentum";
  harness: TradingHarnessBinding;

  authority: TradingAuthority;
  strategy?: MomentumStrategyState;

  status:
    | "initializing"
    | "analysing"
    | "waiting"
    | "executing"
    | "position_open"
    | "paused"
    | "agent_unavailable"
    | "blocked"
    | "revoked"
    | "completed";

  blockedReason?:
    | "cumulative_loss_limit"
    | "protection_failure"
    | "account_unavailable"
    | "reconciliation_failure";

  control: {
    entriesAllowed: boolean;
    reentryAllowed: boolean;
    pauseAfterPositionClose: boolean;
  };

  strategyVersion: number;
  authorityVersion: number;
  lastHarnessRunId?: string;
  createdAt: number;
  updatedAt: number;
};

10.4 · Trading authority & risk policy

User-authorized limits, deterministic risk accounting

TradingAuthority

Authority
type TradingAuthority = {
  allocatedCapitalUsd: number;
  allowedDirections: Array<"long" | "short">;

  maximumLeverage: number;
  maximumGrossNotionalUsd: number;
  maximumCumulativeLossUsd: number;
  maximumPlannedRiskPerPositionUsd: number;

  marginModes: Array<"cross" | "isolated">;

  allowScaleIn: boolean;
  allowPartialReduction: boolean;
  allowReentry: boolean;
  allowDirectionReversal: boolean;

  validUntil: "revoked" | number;
};

type TradingRiskPolicy = {
  feeRateSource: "hyperliquid_user_fees";
  fallbackTakerFeeBpsPerSide: number;
  stopSlippageReserveBps: number;
  positivePnlExpandsLossBudget: false;
};

POC defaults

Authority
const pocAuthorityDefaults = {
  maximumLeverage: 3,
  maximumCumulativeLossPct: 10,
  maximumPlannedRiskPerPositionPct: 2,
  allowScaleIn: true,
  allowPartialReduction: true,
  allowReentry: true,
  allowDirectionReversal: true,
  marginModes: ["isolated", "cross"],
} as const;

const pocRiskPolicyDefaults: TradingRiskPolicy = {
  feeRateSource: "hyperliquid_user_fees",
  fallbackTakerFeeBpsPerSide: 5,
  stopSlippageReserveBps: 25,
  positivePnlExpandsLossBudget: false,
};

Worked example: $1,000 mandate

Allocated capital

$1,000

Maximum leverage

3x

Maximum gross notional

$3,000

Maximum cumulative mission loss

$100

Maximum planned loss per position

$20

Directions

Long & short

Scale-in & re-entry

Permitted

Valid until

Revoked

The harness may choose lower exposure.

10.5 · Momentum strategy state

Published conclusions, not hidden reasoning

TradingTimeframe & MomentumStrategyState

Harness
type TradingTimeframe = "1m" | "3m" | "5m" | "15m" | "1h";

type MomentumStrategyState = {
  version: number;
  name: string;
  market: "ETH";

  mode:
    | "breakout_continuation"
    | "breakdown_continuation"
    | "pullback_continuation"
    | "volatility_expansion";

  direction: "long" | "short" | "both" | "conditional";
  timeframes: TradingTimeframe[];

  belief: {
    summary: string;
    regime: string;
    confidence?: number;
    evidence: string[];
  };

  entryPlan: {
    explanation: string;
    initialNotionalUsd?: number;
    maximumIntendedNotionalUsd?: number;
    orderPreference: "marketable_ioc" | "resting_limit";
    conditions: AgentConditionDescription[];
  };

  positionManagement: {
    scaleInAllowed: boolean;
    scaleInConditions: AgentConditionDescription[];
    partialReductionAllowed: boolean;
    trailingMethod?: string;
  };

  protection: {
    stopMethod: string;
    stopPrice?: number;
    takeProfitMethod?: string;
    takeProfitPrice?: number;
    maximumPlannedLossUsd?: number;
  };

  exitConditions: AgentConditionDescription[];
  abandonmentConditions: AgentConditionDescription[];
  reentryConditions: AgentConditionDescription[];

  currentAction:
    | "analysing"
    | "waiting"
    | "entering"
    | "holding"
    | "scaling"
    | "reducing"
    | "exiting"
    | "reassessing"
    | "abandoning";

  explanation: string;
  updatedAt: number;
};

This stores published conclusions, not hidden reasoning.