Hermes_Trader_Action_Contract_v0.1.md 6.2 KB

Hermes → Trader Action Contract (v0.1)

This document defines the narrow write contract from hermes-mcp to trader-mcp.

Goal

Keep Hermes in charge of decisions and keep Trader in charge of safe application.

Hermes should send one explicit control decision. Trader should validate it, apply it if safe, and return a structured result.

Design rules

  1. One Hermes write entry point.
  2. Small explicit schema.
  3. No duplicate control surfaces.
  4. Safe rejection is a normal outcome.
  5. Every applied or rejected action is auditable.
  6. keep is not a Trader write action. Hermes may record keep on its own side.

Canonical Hermes write tool

Trader exposes one canonical Hermes write tool:

  • apply_control_decision(payload)

Hermes should not need to combine multiple Trader tools to express one decision.

Non-canonical helpers

These may still exist internally or for operator use, but they are not the Hermes contract:

  • control_strategy(...)
  • set_strategy_policy(...)
  • switch_strategy(...)
  • pause_strategy(...)
  • resume_strategy(...)
  • reconcile_instance(...)

They are runtime helpers, not the cross-system write boundary.

Supported actions

The Hermes write contract supports only these actions:

  • switch
  • pause
  • resume
  • set_risk_mode

Not supported here:

  • keep
  • free-form policy mutation
  • multi-step orchestration batches
  • broad config editing

Request shape

{
  "decision_id": "dec_2026_04_16_001",
  "concern_id": "qndd8o9ppop6:xrpusd",
  "account_id": "qndd8o9ppop6",
  "market_symbol": "xrpusd",
  "action": "switch",
  "target_strategy_id": "0c555fee-e4c8-4543-ae70-c132517017e1",
  "expected_active_strategy_id": "9cf29124-65a7-4950-ac18-65f938e0239b",
  "risk_mode": "normal",
  "reason": "trend strategy still fits the directional narrative",
  "confidence": 0.83,
  "dry_run": false,
  "override": false,
  "requested_at": "2026-04-16T20:15:00Z"
}

Required fields

  • decision_id
  • concern_id
  • account_id
  • market_symbol
  • action
  • reason
  • confidence

Conditionally required fields

For switch

  • target_strategy_id

For set_risk_mode

  • risk_mode

For guarded transitions

  • expected_active_strategy_id is strongly recommended

Field meanings

decision_id

Stable id from Hermes. Trader stores it and uses it for audit linkage and idempotency checks.

concern_id

The account-market concern Hermes is acting on.

expected_active_strategy_id

What Hermes believes is active right now. If provided and Trader sees something else, Trader should reject unless override=true.

reason

Human-readable explanation. Short, concrete, stable enough for audit logs.

confidence

Normalized float in [0, 1]. Trader does not have to trust it blindly, but may use it in guardrails.

dry_run

Validate and simulate only. No state-changing action should occur.

override

Explicit emergency bypass for guarded rejection paths. Use sparingly and always record it.

Response shape

{
  "ok": true,
  "status": "applied",
  "decision_id": "dec_2026_04_16_001",
  "concern_id": "qndd8o9ppop6:xrpusd",
  "action": "switch",
  "from_strategy_id": "9cf29124-65a7-4950-ac18-65f938e0239b",
  "to_strategy_id": "0c555fee-e4c8-4543-ae70-c132517017e1",
  "risk_mode": "normal",
  "dry_run": false,
  "validation": {
    "concern_match": true,
    "account_match": true,
    "market_match": true,
    "expected_active_match": true,
    "target_exists": true,
    "target_runnable": true
  },
  "warnings": [],
  "errors": [],
  "result": {
    "mode_change": "applied",
    "reconciled": true
  },
  "applied_at": "2026-04-16T20:15:01Z"
}

Status values

  • applied
  • rejected
  • noop
  • failed

applied

Validation passed and Trader changed state.

rejected

Trader refused the request due to validation or safety rules. This is a valid control outcome.

noop

The requested state already exists. Example: Hermes asks to resume a strategy that is already active.

failed

Trader attempted the action but could not complete it due to runtime or persistence failure.

Validation rules

Trader should validate at least the following:

  1. account_id matches the target strategy or concern.
  2. market_symbol matches the target strategy or concern.
  3. target_strategy_id exists for switch.
  4. the target strategy belongs to the same account-market pair.
  5. if expected_active_strategy_id is provided, it matches reality unless override=true.
  6. the action is currently safe under runtime guardrails.
  7. confidence is a valid numeric value in range.

Initial safety gates

Version 0.1 implements a small set of safety gates:

  • expected active strategy check
  • target existence check
  • account-market match check
  • degraded execution rejection unless override=true
  • idempotent duplicate decision rejection or noop handling

Current implementation also records each attempt in Trader audit storage and reconciles the affected strategy runtime after an applied state change.

Idempotency

Trader should treat decision_id as an idempotency key. Repeated submissions of the same already-applied decision should not reapply the state transition.

Audit persistence

Trader should persist every Hermes action attempt, including:

  • request payload
  • validation result
  • final status
  • result payload
  • timestamps

A rejected action is still important and should be stored.

Read/write separation

Hermes read path should stay separate from Hermes write path.

Read

  • list_strategies()
  • get_strategy()

Write

  • apply_control_decision(payload)

Avoid proliferating extra Hermes-facing tools unless a real gap appears.

Suggested implementation mapping inside Trader

apply_control_decision(payload) may internally call existing runtime helpers:

  • control_strategy(...)
  • set_strategy_policy(...)
  • reconcile_instance(...)
  • a new internal switch_strategy(...)

But Hermes should only see one write entry point.

Versioning rule

Keep this contract small. Future versions should extend it only when a real decision or execution need appears. If a new field does not improve safety, auditability, or decision fidelity, it probably does not belong here.