The language-agnostic agent ⇄ harness protocol.
Agents are external — a container or HTTP endpoint, in any language — not
Rust code. Each decision step the harness sends a [MarketObservation] (JSON)
and the agent replies with a [Decision] (JSON). Keeping this surface tiny and
stable is what lets any vendor compete (and is the whole adoption story).
All observations are point-in-time: close_history, fundamentals and
news only ever contain information available at or before date.
The wire contract is closed (breaking for entrants as of 0.11.0)
Every wire type carries #[serde(deny_unknown_fields)]. An agent that emits
a key the contract does not define is rejected at the transport boundary and
scored as an agent protocol fault, not silently accepted. This is a
deliberate departure from the additive-only discipline the rest of the
artifact formats follow: an attested benchmark cannot let an unread field
carry meaning the scorer never saw.
The authoritative machine-readable definition of the closed contract is
published as JSON Schema (draft 2020-12) alongside this crate:
schema/decision.schema.json and schema/observation.schema.json. Both set
additionalProperties: false to mirror deny_unknown_fields, and a
bidirectional drift guard (tests/schema_drift.rs) fails the build if the
schema and the Rust types disagree in either direction.
Entrants migrating from 0.10.x: drop any extra keys, or move them under
reasoning (free text) or cost (structured spend). [decision_from_wire]
produces the diagnostic that names the offending field.