@battlegrid/mcp-server 31.2.65 → 31.2.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,6 +24,61 @@ Seeing package `31.x` alongside handshake `battlegrid@33.x` — the package **be
24
24
 
25
25
  **What this changes for you:** nothing about how you call anything. Upgrading the package no longer waits on a server deploy, and a server deploy no longer strands you on a package that names the wrong contract — reconnect and the announcement follows. **Contract breaking-change notes are no longer keyed to package versions**, since a contract move is no longer a release here; the v11-and-earlier notes below are kept as history, and the live vocabulary is always discovery.
26
26
 
27
+ ## Contract history — v86 (a refusal hint belongs to the operation that can act on it)
28
+
29
+ **Breaking at v86: refusals on most tools lose `details.nextAct`, two refusals change code, and one
30
+ draft read is reshaped.** v86 is the contract on top of v85.
31
+
32
+ ### Narrowed refusal details
33
+
34
+ - **`details.nextAct` follows the refusal's meaning.** `DRAFT_VERSION_MOVED` and `DRAFT_AXIS_CONTESTED`
35
+ still carry `get_draft` from every tool. A revision `CONFLICT` and the in-flight commit refusal
36
+ (`get_draft`) and a validation refusal (`stage`) now carry a hint only from `stage_<kind>_draft` and
37
+ `commit_<kind>_draft` of the strategy and agent kinds.
38
+ - **Removed from every other tool's validation refusal and revision `CONFLICT`**: `submit_market_grid`,
39
+ `fork_strategy`, `archive_strategy`, `restore_strategy`, and the arena and radar commit, pause, resume
40
+ and delete tools, and from the malformed-cursor refusal of `list_agent_drafts` and
41
+ `list_strategy_drafts`. The arena and radar `commit_*_draft` stale-revision refusals lose `get_draft`
42
+ too. A client that branched on `nextAct` from those tools reads the code instead.
43
+
44
+ ### Changed error codes
45
+
46
+ - **The strategy active-quota refusal is `FORBIDDEN`**, as the agent slot quota is, where it was
47
+ `VALIDATION_ERROR` with `nextAct: 'stage'`: on `commit_strategy_draft` and `restore_strategy`.
48
+ - **A create naming an id that is already the caller's strategy or agent is `DRAFT_VERSION_MOVED`**,
49
+ carrying the caller's draft version at that id, where it was `NOT_FOUND`. An agent create naming a
50
+ SYSTEM agent is `FORBIDDEN`, where it was `NOT_FOUND`.
51
+ - **The moved-draft refusals end "Read the draft again and show the player what it now holds before
52
+ committing."**, where they said to commit what it now holds. Read the draft again and show the player
53
+ before committing; never commit the re-read draft on your own.
54
+
55
+ ### Reshaped output
56
+
57
+ - **`get_agent_draft.impact` is a union on `operation`**: `{ operation: 'CREATE', capital }` for a create
58
+ draft, where it was `null`, and `{ operation: 'UPDATE', deployedPresetCount, openPositionCount,
59
+ radarArmedCoinCount, capital, rebind }` for an edit draft, where the counts sat at the top level. A
60
+ create draft's `capital` reads its trading configuration — drafted, or the platform's seed — over the
61
+ bound strategy's band, as the commit's capital check reads it.
62
+
63
+ ### Widened read
64
+
65
+ - **`get_strategy` with `includeInactive: true`** serves your own strategy in any state, and otherwise
66
+ the visible set the default read serves — every SYSTEM strategy among it — where it answered
67
+ `NOT_FOUND` for anything but an owned PRIVATE strategy. Another user's PRIVATE strategy is still
68
+ `NOT_FOUND`.
69
+
70
+ ### Behaviour behind unchanged schemas
71
+
72
+ - **The stage and commit descriptions** state the draft content cap (256,000 UTF-8 bytes) and its
73
+ refusal, what a commit reaches — it closes no position, and the one refusal an open position can cause
74
+ — and that a moved draft is shown to the player before any commit.
75
+ - **A stage's `DRAFT_VERSION_MOVED`** fires only for a version the draft never reached — read from a draft
76
+ since committed or discarded. A stage naming an older version than the draft holds is composed over the
77
+ newer draft.
78
+
79
+ A strict client re-reads the `get_agent_draft` output schema; list the tools again after the server
80
+ deploys.
81
+
27
82
  ## Contract history — v85 (agents and strategies change only through their drafts)
28
83
 
29
84
  **Breaking at v85: seven tools are retired, and a surviving tool refuses an input it accepted at v84.**
@@ -2162,8 +2217,8 @@ Retained for authors upgrading from 4.x. Everything below still describes the cu
2162
2217
 
2163
2218
  The v3 authoring contract below is unchanged and still current:
2164
2219
 
2165
- - **Strict authoring envelopes.** `get_strategy_section_template`, `update_strategy_signal_rule`, `compile_strategy_plan`, and `apply_strategy_plan` publish one strict server-owned object, `{ request: canonicalPayload }`. In multi-account mode the proxy adds `account` **only** as a sibling of `request`, producing exactly `{ account, request }`; on a call it strips only `account` and forwards the unchanged `{ request }`. It never descends into, flattens, or reconstructs the nested request.
2166
- - **`create_strategy` is retired.** Direct strategy creation no longer exists. Author strategies with the compile → review → apply workflow below, and bind them to agents at agent-creation time (`create_intelligence_agent({ …, strategyId })`). There is no alias, shim, or flat-payload fallback.
2220
+ - **Strict authoring envelopes.** `get_strategy_section_template` and every draft lifecycle tool (`stage_<kind>_draft`, `get_<kind>_draft`, `commit_<kind>_draft`, `discard_<kind>_draft`, `list_<kind>_drafts`) publish one strict server-owned object, `{ request: canonicalPayload }`. In multi-account mode the proxy adds `account` **only** as a sibling of `request`, producing exactly `{ account, request }`; on a call it strips only `account` and forwards the unchanged `{ request }`. It never descends into, flattens, or reconstructs the nested request.
2221
+ - **`create_strategy` is retired.** Direct strategy creation no longer exists. Author strategies through the strategy draft lifecycle below, and bind an agent to one through its draft's `STRATEGY_BINDING` axis. There is no alias, shim, or flat-payload fallback.
2167
2222
  - **Rediscover after deployment.** Publishing the package does **not** refresh a running proxy's cached capability snapshot. After the server cutover, restart/reconnect the proxy process and re-run `tools/list`, `prompts/list`, and `resources/list`.
2168
2223
 
2169
2224
  > Earlier majors: **v1.x** single/multi-account stdio proxy; **v2.0.0** moved the default `BATTLEGRID_API_URL` to the `/mcp` suffix; **v3.0.0** the strategy-authoring major; **v4.0.0** made `conditions` and `conditionVerdicts` required on the apply post-state; **v5.0.0** fused the conditions/verdicts split (section above). **v6.0.0** through **v11.0.0** were never published as separate package versions — they are absorbed by the v11 cutover at the top. See [Rediscovery & versioning](#rediscovery--versioning).
@@ -2385,7 +2440,7 @@ Strategies and intelligence agents change only through their drafts, with one to
2385
2440
  4. **Stage the change.** `stage_<kind>_draft({ request: { <id>?, draftVersion, axes } })` names the version you read. Each axis is whole, except a strategy's `SIGNAL_RULES`, whose rows replace the drafted rows for the same signals and keep every other one. Omit the id to open a new create draft; the response carries the minted id. A stage that has written never refuses: the composed draft's errors and warnings come back as `diagnostics`. It is refused only when the version is one the draft never reached (`DRAFT_VERSION_MOVED`) or when the player's own form changed an axis you are staging after that version (`DRAFT_AXIS_CONTESTED`, naming `contestedAxes`).
2386
2441
  5. **Review with the player, then commit.** Read the draft again, show the player its diff and impact, and on their explicit word call `commit_<kind>_draft({ request: { <id>, draftVersion, expectedRevision } })` with exactly the two numbers that read returned — `expectedRevision: null` creates the entity at revision 1. A draft that moved is refused `DRAFT_VERSION_MOVED`, a moved revision `CONFLICT`, and an invalid draft with the same code its diagnostics carried; nothing is written. Each refusal's `details.nextAct` says what to do next (`get_draft` or `stage`). The commit is idempotent on `{ id, draftVersion }`: a retried commit replays its outcome. Changed strategy configuration propagates to every bound agent immediately; committing a draft of an archived strategy restores it.
2387
2442
 
2388
- `discard_<kind>_draft({ request: { <id>, draftVersion } })` removes the draft at the version you read and never one that moved since. `preview_strategy_report({ coinSelection, source: { kind: 'DRAFT', strategyId, draftVersion } })` previews a draft as a commit would compose it. In multi-account mode every one of these calls uses the `{ account, request }` sibling envelope.
2443
+ `discard_<kind>_draft({ request: { <id>, draftVersion } })` removes the draft at the version you read and never one that moved since. `preview_strategy_report({ coinSelection, source: { kind: 'DRAFT', strategyId, draftVersion } })` previews a draft as a commit would compose it. In multi-account mode the lifecycle tools use the `{ account, request }` sibling envelope; `preview_strategy_report` keeps its own flat input and takes `account` beside `coinSelection` and `source`.
2389
2444
 
2390
2445
  **Strategy-bound agents.** An agent binds to a strategy through its draft's `STRATEGY_BINDING` axis — on a create draft, or on an edit draft as a rebind that commits through the same `commit_agent_draft` (discover `strategyId` via `list_strategies`). The plan tools, `update_strategy_signal_rule` and the direct agent writers are retired, and so is `create_strategy`.
2391
2446
 
package/SKILL.md CHANGED
@@ -68,8 +68,9 @@ than about authoring:
68
68
  is `null` for an entity not created yet. Commit only after the player has seen the diff and impact
69
69
  and said yes. `discard_<kind>_draft({ request: { <id>, draftVersion } })` is the same fence.
70
70
  - **The proxy forwards numbers and `null` unchanged.** It never fills in a version, never retries a
71
- refused call and never rebuilds a request: a `DRAFT_VERSION_MOVED`, `DRAFT_AXIS_CONTESTED` or
72
- revision `CONFLICT` refusal carries `details.nextAct`, and the next act is the caller's.
71
+ refused call and never rebuilds a request. A `DRAFT_VERSION_MOVED` or `DRAFT_AXIS_CONTESTED` refusal
72
+ carries `details.nextAct` from every tool, and a revision `CONFLICT` or validation refusal carries it
73
+ from a stage or commit; the next act is the caller's.
73
74
 
74
75
  `fork_strategy` copies a revision into a new create draft and creates nothing until that draft is
75
76
  committed. An agent binds to a strategy through its draft's `STRATEGY_BINDING` axis, on a create or
@@ -98,9 +99,9 @@ The `play-market-grid` prompt (discover via `prompts/list`) provides a guided en
98
99
  | `API key must start with "bg_live_"` | Invalid key format | Generate a new key at battlegrid.trade → Profile → MCP |
99
100
  | Authentication failed (401/403) | Key revoked/rotated | Generate a new key and **restart** the proxy (keys read once at startup) |
100
101
  | `"account" parameter is required` | Multi-account call missing `account` | Add the outer `account`; keep `request` unchanged |
101
- | `DRAFT_VERSION_MOVED` | The draft changed after you read it, or no draft is held (`details.draftVersion` null) | Call `get_<kind>_draft` again and commit what it now holds |
102
+ | `DRAFT_VERSION_MOVED` | The draft changed after you read it, or no draft is held (`details.draftVersion` null) | Call `get_<kind>_draft` again, show the player what it now holds, and commit only on their word |
102
103
  | `DRAFT_AXIS_CONTESTED` | The player changed `details.contestedAxes` in their open form after the version you staged against | Read the draft again and propose against what they now have |
103
- | `CONFLICT` on a commit | The live revision moved after the draft read | Read the draft again; commit at the new `committedRevision` |
104
+ | `CONFLICT` on a commit | The live revision moved after the draft read | Read the draft again, show the player the new diff and impact, and commit at the new `committedRevision` only on their word |
104
105
  | Required at allocation Off | A rule flags `required` on a signal weighted `0` (contract 34) | Read `details.inertRequiredSignalIds`; per signal either raise `allocation` or set `required: false` |
105
106
  | Method not found | Calling a retired/unknown tool | Re-run `tools/list`; stage, read and commit through the entity's draft |
106
107
  | `Wager scope required` | `mcp:wager` not enabled | Enable Server-Signed Wagers in Profile → MCP |
package/dist/index.d.ts CHANGED
@@ -49,7 +49,7 @@ import { type Implementation, type Prompt, type Resource } from '@modelcontextpr
49
49
  * being asked. Move it for a change to THIS package — a proxy fix, a dependency bump, a docs
50
50
  * correction. Never move it to track the server.
51
51
  */
52
- export declare const PACKAGE_VERSION = "31.2.65";
52
+ export declare const PACKAGE_VERSION = "31.2.67";
53
53
  export declare const DEFAULT_URL = "https://mcp.battlegrid.trade/mcp";
54
54
  export interface EnvConfig {
55
55
  apiKeys: string[];
package/dist/index.js CHANGED
@@ -52,7 +52,7 @@ import { ListToolsRequestSchema, CallToolRequestSchema, ListPromptsRequestSchema
52
52
  * being asked. Move it for a change to THIS package — a proxy fix, a dependency bump, a docs
53
53
  * correction. Never move it to track the server.
54
54
  */
55
- export const PACKAGE_VERSION = '31.2.65';
55
+ export const PACKAGE_VERSION = '31.2.67';
56
56
  export const DEFAULT_URL = 'https://mcp.battlegrid.trade/mcp';
57
57
  const MAX_RETRIES = 3;
58
58
  const RETRY_DELAYS_MS = [2000, 4000, 8000];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@battlegrid/mcp-server",
3
- "version": "31.2.65",
3
+ "version": "31.2.67",
4
4
  "description": "BattleGrid MCP server — play crypto prediction games from AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "generator": "battlegrid-app/server/scripts/export-mcp-skills.mjs",
3
- "contractVersion": "84.0.0",
3
+ "contractVersion": "86.0.0",
4
4
  "files": {
5
- "battlegrid-agent-management/SKILL.md": "5ea8384ff76ccb9fdf00e4ec8b584f88fdba6d1c9d5679ce0b7380c23bfbaab1",
5
+ "battlegrid-agent-management/SKILL.md": "b2f04d76480de2f9fdbd00f8cb25610d2b72fcaa4f87ca57a09bd9ffc78fdbba",
6
6
  "battlegrid-arena-play/SKILL.md": "4cfaa92a8d0dcaf477b227abd774e7aa8642c185d72108dfd401be0cf8aecd7f",
7
- "battlegrid-market-analysis/SKILL.md": "22fde9c4eac0261c89a8056ab8b20b66fcbe1fd58447fa0ac84fd410b4d134d7",
7
+ "battlegrid-market-analysis/SKILL.md": "3a9943de9f482a8230fb2983efd2f2d8b8c17d49c242e49b68e7243c20c3aa7b",
8
8
  "battlegrid-radar-deployment/SKILL.md": "17301fa66f4b128154435462ffa967efcb3d016df671b03c485d0f8b840fc891",
9
- "battlegrid-strategy-authoring/SKILL.md": "6aa3a04fd4f0624a671d70aead009f4943db1ffa34402e403b588dd998e828c9",
10
- "battlegrid-strategy-doctor/SKILL.md": "a3446f24059be72ae797ba4e9669848d851ac3dc38675923fe3d307f557eb82f",
11
- "battlegrid-strategy-examples/SKILL.md": "534c053e75021b6954e2365dbec4893ed9fc807a064a922f47f2d34a4e528221",
12
- "battlegrid-strategy-examples/references/playbooks.md": "02168e3af35268a30fd156f3337d25fe15e6df67da1592f4cb4d31090be3f94f",
13
- "battlegrid-strategy-examples/references/recipes.md": "53887daece17995543e7d3fe1bf2577fc41a6254c291acacde48d7de63853641",
9
+ "battlegrid-strategy-authoring/SKILL.md": "a5066740d7d57f095545fd812b0228a8eef6e3b08c87047596a0e1639ae4971d",
10
+ "battlegrid-strategy-doctor/SKILL.md": "14f20bff9e2b5a59d11634fe3615b1298d672d5e2eba06d3dc8698b571b3bee3",
11
+ "battlegrid-strategy-examples/SKILL.md": "3c11942f7327e00208d48a7a256faf83d80faf568bd0181b707657bace3c1ef9",
12
+ "battlegrid-strategy-examples/references/playbooks.md": "63aa07f3d55f97e53b2bf6401528807ab23bd093a4bbc37e598158249db24a59",
13
+ "battlegrid-strategy-examples/references/recipes.md": "61382acdd295fa159f055b787ba501f1c015f383f59a6714a973057f10de611f",
14
14
  "battlegrid-strategy-examples/references/tradingview-ports.md": "2b13adbc137178955edcca31b6ab40c01c745a932a0750b91db8820c736700bb",
15
15
  "battlegrid-trade-analysis/SKILL.md": "f5d817022ab912f00e9c17ffa720a7599f6e6fa4b806d873fe5e7520c51a8dcd",
16
16
  "battlegrid-trade-proposal/SKILL.md": "9bf7b7648fb009db118a3a428b15abf38df5ba56a2ef4c8a4eae3d979bdc8bcb"
@@ -22,8 +22,8 @@ step named beside it before doing anything else.
22
22
  verb that changes what the agent may do.* Every one of these has a reach the player cannot see
23
23
  from the verb: open positions that keep running, deployments that stop firing, materialized
24
24
  configuration that is replaced. State the reach from the reads BEFORE the confirm form. And a
25
- configuration change to an agent the player is mid-edit on is staged, not committed. → steps 3
26
- and 4.
25
+ configuration change is staged into the agent's draft and committed only on the player's
26
+ explicit pick. → steps 3 and 4.
27
27
  3. **Mis-lever'd halt recovery.** *Cue: "why is it stopped", "start it again", any halted agent.*
28
28
  The halt reason says why the agent stopped, not what clears it. Offering an exit the server's
29
29
  resume verdict does not offer is offering something that cannot work. → step 5.
@@ -33,16 +33,17 @@ step named beside it before doing anything else.
33
33
 
34
34
  ## Cross-skill rule: strategy changes are not yours
35
35
 
36
- `list_strategies` and `get_strategy` are yours — the binding lookup is part of commissioning.
37
- `compile_strategy_plan`, `apply_strategy_plan`, `fork_strategy`, `archive_strategy`,
38
- `restore_strategy` and `update_strategy_signal_rule` are **not**, even though activating this
39
- skill makes them visible in the conversation.
36
+ `list_strategies` and `get_strategy` are yours — the binding lookup is part of commissioning, and
37
+ which strategy an agent is bound to is the agent's own STRATEGY_BINDING axis (step 4).
38
+ `stage_strategy_draft`, `commit_strategy_draft`, `discard_strategy_draft`, `fork_strategy`,
39
+ `archive_strategy` and `restore_strategy` are **not**, even though activating this skill makes them
40
+ visible in the conversation.
40
41
 
41
42
  When the work is a strategy change, activate `strategy-authoring` and let its arc run — its
42
- evidence, spec-lock, compile-review and confirm rules bind from that point. Do not drive a
43
- strategy write from this arc's own steps. (Visibility is not authority: those tools keep their own
44
- server gates — plan token, schema confirm, ownership — and this rule is about which arc's
45
- discipline governs the change, not about what the server would accept.)
43
+ evidence, spec-lock, stage-review and confirm rules bind from that point. Do not drive a strategy
44
+ write from this arc's own steps. (Visibility is not authority: those tools keep their own server
45
+ fences — the draft version, the revision, ownership — and this rule is about which arc's discipline
46
+ governs the change, not about what the server would accept.)
46
47
 
47
48
  ## Sequence
48
49
 
@@ -53,8 +54,8 @@ discipline governs the change, not about what the server would accept.)
53
54
  currently-available models; a model you remember from another agent may be deprecated, which
54
55
  keeps serving agents already bound to it while refusing a new selection. Never name a model
55
56
  from memory. **Send the row's `modelId`** — the `provider/name` string, e.g. `z-ai/glm-5.3` —
56
- never its `id`. The `id` UUID identifies the catalogue row; `create_intelligence_agent` and
57
- `update_intelligence_agent` key on `modelId` and accept nothing else.
57
+ never its `id`. The `id` UUID identifies the catalogue row; the draft's MODEL axis,
58
+ `{ modelId }`, keys on `modelId` and accepts nothing else.
58
59
  - `list_strategies` — the binding candidates.
59
60
  - `list_agent_drafts` — what the player is already part-way through. **Mention an existing draft
60
61
  before starting new work** — "you have an unsaved <agent / new agent>, last touched from
@@ -63,7 +64,7 @@ discipline governs the change, not about what the server would accept.)
63
64
  Read each thing once. A roster or agent you already fetched in this conversation is still in front
64
65
  of you; re-fetching costs the player the same payload twice and it rides every later step.
65
66
 
66
- ### 2. Commission: interview, restate, confirm, create
67
+ ### 2. Commission: interview, restate, draft, confirm, commit
67
68
 
68
69
  **No strategy, no agent.** If the player has no committed strategy they could bind, say so and
69
70
  offer the `strategy-authoring` arc first. Do not fabricate a binding, do not pick one on their
@@ -74,23 +75,32 @@ One interview with the player covering: **mandate** (what is this agent for), **
74
75
  scores and the strategy's own description, as the tools returned them.
75
76
 
76
77
  When the picks come back, restate in one line: *"Commissioning: <name>, bound to <strategy>, on
77
- <model>, <risk posture>."* Then one confirmation naming **the strategy, the model, and the
78
- budget posture** — the capital ceiling and stops the trading configuration will carry, or that it
79
- will take platform defaults.
78
+ <model>, <risk posture>."*
80
79
 
81
80
  **Build it in a create draft.** As the picks come back, stage them with `stage_agent_draft` —
82
- omit `agentId` and send `draftVersion: 0` on the first call, then reuse the id and the `version` it
83
- returns — each axis WHOLE: IDENTITY
84
- `{ displayName }`, BEHAVIOR `{ behavior: { risk, outlook, conviction } }`, MODEL `{ modelId }`,
85
- TRADING_CONFIG with every agent-owned field, and STRATEGY_BINDING `{ strategyId }`. The build then
86
- survives a refresh, lists in the Agents Hub as *not yet created*, and opens on the create screen,
87
- where **the player's Save creates it**. Staging creates nothing and spends no slot.
88
-
89
- Call `create_intelligence_agent` yourself only when the player asks you to create it from this
90
- conversation — on a surface with no create screen to save from — with an **`idempotencyKey`**
91
- derived from this conversation and this confirm turn. A create spends an agent slot against the player's rank quota; a retry after a
92
- dropped response would spend a second one. With the key, an ambiguous retry replays the original
93
- result instead.
81
+ omit `agentId` and send `draftVersion: 0` on the first call, then reuse the id it mints and the
82
+ `version` it returns — each axis WHOLE: IDENTITY `{ displayName }`, BEHAVIOR
83
+ `{ behavior: { risk, outlook, conviction } }`, MODEL `{ modelId }` and STRATEGY_BINDING
84
+ `{ strategyId }`, all four required to create, plus TRADING_CONFIG with every agent-owned field —
85
+ or no TRADING_CONFIG at all, to take the platform seed. The build then survives a refresh, lists in
86
+ the Agents Hub as *not yet created*, and opens on the create screen, where **the player's own
87
+ Create creates it**. Staging creates nothing and spends no slot.
88
+
89
+ **Then read it, confirm it, and commit it.** `get_agent_draft` serves the draft, its
90
+ `draftVersion`, a `committedRevision` of `null` and the diagnostics: a missing or invalid axis is
91
+ an error there, named, before anything is spent. Its impact is `operation: CREATE` with the
92
+ create's capital reading: the smallest order its configuration — drafted, or the platform seed —
93
+ places, against the order floor, and whether that is `feasible`. Then one confirmation naming **the
94
+ strategy, the model, and the budget posture** — the capital ceiling and stops the trading
95
+ configuration will carry, or that it will take the platform seed, with the smallest order against
96
+ the floor — and on the player's explicit pick call `commit_agent_draft` with the `agentId`, that
97
+ read's `draftVersion` and `expectedRevision: null`. A reading with `feasible: false` is a create the
98
+ commit will refuse: say so, and stage a larger ceiling or a looser configuration first. Where the player has the create screen open, their own Create is the
99
+ other way to commit it.
100
+
101
+ A create spends an agent slot against the player's rank quota, decided by the commit itself: a
102
+ full quota is refused there, with the draft unchanged. A retry of the same draft version after a
103
+ dropped response replays the original receipt, so an ambiguous retry never spends a second slot.
94
104
 
95
105
  **When the mandate names the arena, read `get_account_state` in the same breath.** The arena needs
96
106
  Agent Wagers: `mcpWagerEnabled: false` means every entry will be refused at the fee, so say the
@@ -100,39 +110,48 @@ Profile → Wallet tab path instead, because no control renders there. **Create
100
110
  way**: the consent gates entering a game, never commissioning one. A `true` flag is consent alone
101
111
  and not readiness — the pipeline's own refusal at the fee is the authority.
102
112
 
103
- ### 3. Stage, review, commit — never commit around an open draft
113
+ ### 3. Stage, read, confirm, commit — every change goes through the draft
104
114
 
105
115
  Before proposing any change to an existing agent, `get_agent_draft`. **A draft means the player is
106
- mid-edit in their form.** Then:
107
-
108
- - **Stage** the change with `stage_agent_draft`, naming as `draftVersion` the `version` the read you
109
- proposed against returned (0 when `get_agent_draft` returned null): it lands in their open form,
110
- labelled as yours, and **their Save commits it** together with their own edits.
111
- `update_intelligence_agent` and `rebind_intelligence_agent` are REFUSED while the draft exists —
112
- that refusal is the server's, so do not retry them.
113
- - A staging call **refused naming an axis** means the player changed it after the version you name:
114
- read again and propose against what they now have — never re-send the same values. A call refused
115
- because that version is one the draft never reached means the draft you read is gone: read again.
116
- Never raise the number to get past either refusal.
117
- - **Rebinding is never staged.** While a draft is open, ask the player to save or discard it first.
118
- - `discard_agent_draft` only on the player's word: call it with `confirm:false` first, tell them
119
- when the draft was last written and from which surface, ask, then confirm.
116
+ mid-edit in their form**, and every change you make joins it. Then:
117
+
118
+ - **Stage** the change with `stage_agent_draft`, naming as `draftVersion` the `draftVersion` the
119
+ read you proposed against returned (0 when it found no draft): it lands in their open form,
120
+ labelled as yours. Each axis you send is written WHOLE — BEHAVIOR carries all three of risk,
121
+ outlook and conviction, TRADING_CONFIG the complete configuration (step 6) — and the axes you
122
+ omit keep their values.
123
+ - **Read the stage's diagnostics.** Its `errors` are the refusals the commit would raise, each
124
+ naming its field: fix the axis and stage again before you ask for anything.
125
+ - A staging call refused **`DRAFT_AXIS_CONTESTED`** names an axis the player changed after the
126
+ version you named: read again and propose against what they now have — never re-send the same
127
+ values. One refused **`DRAFT_VERSION_MOVED`** names a version the draft never reached, or a draft
128
+ that is gone: read again. Never raise the number to get past either refusal.
129
+ - **Commit** through step 4: read the draft with `get_agent_draft`, state the radius from its diff
130
+ and impact, confirm, and on the player's explicit pick call `commit_agent_draft` with the
131
+ `agentId` and exactly the `draftVersion` and, as `expectedRevision`, the `committedRevision` that
132
+ read returned. The commit publishes every axis the draft holds — the player's own unsaved edits
133
+ included — so the confirmation reads out the whole diff, not only your proposal. Where their form
134
+ is open, their own Save is the other way to commit it.
135
+ - **Discard** only on the player's word. `get_agent_draft` is the read of what a discard destroys:
136
+ tell them what the draft holds, when it was last written and from which surface, ask, and call
137
+ `discard_agent_draft` with the `agentId` and the `draftVersion` you read. There is no dry run and
138
+ no confirmation parameter: a draft written since your read is refused with `DRAFT_VERSION_MOVED`
139
+ and nothing is removed — read again and show them.
120
140
 
121
141
  **In a conversation the agent console hosts** — your context names the agent console and an agent
122
142
  id — the player's form is open on that agent whether or not a draft exists yet. Stage every change
123
143
  into that agent's draft, naming that id as `agentId`, create or edit alike: the create recipe's
124
144
  omitted id does not apply there, because the screen already holds the id the agent will be created
125
- at. Create, update, rebind and discard are refused there — the player's own Create, Save or Discard
126
- is the act. On an existing agent a strategy change is a recommendation the player picks in the
127
- Strategy step. An axis their form rewrote after your proposal — typed over or undone — is their
128
- answer: propose it again only on their word.
129
-
130
- With **no draft open**, the update verb below stands, confirm and all — outside the agent console.
145
+ at. Their own Create or Save commits it; commit it yourself only when they explicitly confirm
146
+ through `ask_user`. On an existing agent a strategy change is staged into the draft's
147
+ STRATEGY_BINDING like any other axis, and lands in their Strategy step as a proposed binding. An
148
+ axis their form rewrote after your proposal — typed over or undone — is their answer: propose it
149
+ again only on their word.
131
150
 
132
151
  ### 4. Lifecycle verbs: read first, state the radius, then confirm
133
152
 
134
- Every one of update, rebind, halt, resume, activate and archive runs this shape. The reads
135
- (`get_agent_budget`, `get_agent_fund_allocation`, `get_agent_open_positions`,
153
+ Every one of a draft commit (an edit or a rebind), halt, resume, activate and archive runs this
154
+ shape. The reads (`get_agent_budget`, `get_agent_fund_allocation`, `get_agent_open_positions`,
136
155
  `get_agent_automation_status`, `get_agent_performance`, `get_agent_journal`) need no confirm and
137
156
  cost nothing but a call — do them first, always.
138
157
 
@@ -140,20 +159,32 @@ State the blast radius **from server fields, as numbers**, before the confirm fo
140
159
 
141
160
  - **Halt** — the open-position count (they keep running; halting opens no exit) and the deployment
142
161
  coverage that stops producing entries.
143
- - **Archive** — the same, plus that the agent stops entering games and signal evaluations, and
144
- that `activate_intelligence_agent` reverses it.
145
- - **Rebind** — that the target strategy's context modules, signal rules, prose and timeframe
146
- **replace** the ones materialized on the agent (this is not a merge), naming both strategies.
147
- Agent-owned settings are untouched.
148
- - **Update** — the concrete diff: each field, from what, to what.
162
+ - **Archive** — the same, plus that the agent stops entering games and signal evaluations, that
163
+ `activate_intelligence_agent` reverses it, and that the player's draft of it is kept.
164
+ - **Rebind** — a strategy change is the draft's STRATEGY_BINDING axis: stage `{ strategyId }`, read
165
+ `get_agent_draft`, and take both strategies from its `impact.rebind` — the strategy it replaces
166
+ (`fromStrategyName`) and the one it binds (`toStrategyName`, at `toStrategyRevision`). Say that
167
+ the target strategy's context modules, signal rules, prose and timeframe **replace** the ones
168
+ materialized on the agent (this is not a merge), naming both strategies. Agent-owned settings are
169
+ untouched. The commit checks the new strategy against the coins the radar acts on for this agent;
170
+ a refusal names the coin and the condition — surface it, never retry it unchanged.
171
+ - **Any other draft commit** — the concrete diff from the read: each field, from what, to what. And
172
+ the read's `impact`: the presets it is deployed to (`deployedPresetCount`), its open positions,
173
+ the coins its radar is armed on (`radarArmedCoinCount`), and the capital reading — its smallest
174
+ order (`smallestOrderUsd`) against the order floor (`orderFloorUsd`). `feasible: false` means the
175
+ agent could not place an order at those limits; say so before the form.
149
176
 
150
177
  Then one confirmation. Act only on an explicit pick — one of the options you offered. Free text
151
178
  while a confirmation is open is not consent, whether it arrives in chat or in the form's own
152
179
  answer-in-your-own-words box — answer what they said and re-present the same confirmation.
153
180
 
154
- **`expectedRevision` comes from the latest read.** A CONFLICT means the stored agent moved since
155
- you read it: re-read, re-state the radius against the NEW state, and re-confirm. Never retry with a
156
- bumped number — that is voting on a state you have not seen.
181
+ **The numbers a write names come from the latest read** — a commit's `draftVersion` and
182
+ `expectedRevision`, an archive's or activation's `expectedRevision`. A `CONFLICT` means the stored
183
+ agent moved since you read it, and a commit refused `DRAFT_VERSION_MOVED` means the draft did — the
184
+ player's form saved an edit, or another surface staged. Both carry `nextAct: get_draft`: re-read,
185
+ re-state the radius against the NEW state, and re-confirm. Never retry with a bumped number — that
186
+ is voting on a state you have not seen. A commit refused with `nextAct: stage` names the field the
187
+ diagnostics named: fix it in a stage, read, and confirm again.
157
188
 
158
189
  **A refused archive names its own blockers.** The refusal carries typed `archiveBlockers[]` —
159
190
  DEPLOYED / OPEN_TRADES / ACTIVE_SESSION, each with a count. Report each blocker and its count as
@@ -172,8 +203,10 @@ server's resume verdict. **The verdict decides the recovery**; the reason only e
172
203
  `resume_intelligence_agent`.
173
204
  - **`eligible: false`** — `breachedStop` names the stop still breached, with `breachingFigureUsd`
174
205
  against `limitUsd`. Present that stop and exactly the exits the verdict marks open:
175
- - `canRaiseTriggeringStop` — raise that stop above the figure through the update verb
176
- (`maxCumulativeDrawdownUsd` for the drawdown stop, `maxDailyLossUsd` for the daily loss limit);
206
+ - `canRaiseTriggeringStop` — raise that stop above the figure through the agent's draft (step 6:
207
+ `maxCumulativeDrawdownUsd` for the drawdown stop, `maxDailyLossUsd` for the daily loss limit).
208
+ The commit's receipt carries the new `haltResumeEligibility` when it moved a stop the resume
209
+ reads;
177
210
  - `canResetBaseline` — `reset_agent_drawdown_baseline`, which acknowledges the loss and re-arms
178
211
  the drawdown stop from today (it erases no history and journals the acknowledgement);
179
212
  - a `breachedStop` of `DAILY_LOSS` also clears at the UTC-day rollover.
@@ -191,13 +224,15 @@ read the verdict again rather than assuming it cleared.
191
224
 
192
225
  ### 6. Risk limits are a whole object
193
226
 
194
- `update_intelligence_agent`'s `tradingConfig` is a **complete** configuration: what you send
195
- replaces what is stored, and every field in that schema is required when the object is present.
227
+ The draft's TRADING_CONFIG axis is `{ tradingConfig }`, a **complete** configuration: what you
228
+ stage replaces the drafted one whole, and every agent-owned field is required in it.
196
229
 
197
- So: **read the current configuration, write the complete object with your change applied**, and
198
- name **every changed value** in the confirm — from what, to what. Never assemble a partial config
199
- and never echo a read config back unchanged: the read shape is wider than the write shape
200
- (`strategyTimeframe` and `regimeTimeframe` are strategy-derived and rejected as unknown keys).
230
+ So: **read the current configuration — the draft's TRADING_CONFIG when it holds one, otherwise the
231
+ agent's — and stage the complete object with your change applied**, then name **every changed
232
+ value** in the confirm, from what to what, as the draft read's diff serves it. Never assemble a
233
+ partial config and never echo a read config back unchanged: the agent's read shape is wider than
234
+ the axis (`strategyTimeframe` and `regimeTimeframe` are strategy-derived and refused as unknown
235
+ keys). The commit holds the configuration to the same risk rules the agent form's Save applies.
201
236
 
202
237
  ### 7. Live positions: present the served state, name the bypass
203
238
 
@@ -221,15 +256,23 @@ never describe it as a permission check, and never add one of your own.
221
256
 
222
257
  ## When a write's outcome is unknown
223
258
 
224
- An interrupted or timed-out write may have landed. **Read current state first** — the agent
225
- (`get_intelligence_agent`), the budget, the positions — and report the committed outcome. If it
226
- committed, that is a success, not a failure to retry. Never re-issue a state-changing call over an
227
- unverified outcome, and never re-create over an unread roster.
259
+ An interrupted or timed-out write may have landed.
260
+
261
+ **A draft commit recovers by being sent again.** `commit_agent_draft` replays the original receipt
262
+ for the same draft version, so a create that landed is reported once and spends one slot. If the
263
+ retry is refused as moved, read the agent — or the roster, for a create — and reconcile with the
264
+ player before anything else.
265
+
266
+ For every other write, **read current state first** — the agent (`get_intelligence_agent`), the
267
+ budget, the positions — and report the committed outcome. If it committed, that is a success, not a
268
+ failure to retry. Never re-issue a state-changing call over an unverified outcome, and never
269
+ re-create over an unread roster.
228
270
 
229
271
  ## Reporting discipline
230
272
 
231
273
  - Report numbers exactly as the tools return them. Never recompute, re-derive, or round.
232
- - Reads are free of confirms; every write has one, and the radius is stated before the form.
274
+ - Reads and stages are free of confirms — a stage changes only the draft. Every commit and every
275
+ state verb has one, and the radius is stated before the form.
233
276
  - A tool that fails is reported as failed, with what could not be checked. Never convert a failed
234
277
  read into "no issue".
235
278
  - Be concise. Every write on this surface points real capital somewhere, or takes it away.
@@ -30,18 +30,22 @@ Run these in order. Skip a step only when the player's question makes it irrelev
30
30
  indicator modules ACROSS a set of coins (comparing RSI, funding or volatility over the leaders,
31
31
  over a category, over the session pool), use `preview_strategy_report`: one table per module with
32
32
  coins as rows, the schema preamble emitted once instead of per coin, and a server-reported token
33
- budget. Ask `list_strategy_categories` for the section catalogue and pass the sections you want as
34
- `{ "kind": "platform", "sectionKey": "includeRsi" }` — no authoring vocabulary is needed. Use
35
- `{ "mode": "ranked", "limit": N }` as the coin selection when you have no explicit list.
36
- Looping a per-coin tool over N coins costs several times this and returns the same values.
33
+ budget. Ask `list_strategy_categories` for the section catalogue and pass the sections you want,
34
+ each as `{ "kind": "platform", "sectionKey": "includeRsi" }`, inside
35
+ `source: { "kind": "FIELDS", "timeframe": …, "sections": [ … ] }` — no authoring vocabulary is
36
+ needed. Use `{ "mode": "ranked", "limit": N }` as the coin selection when you have no explicit
37
+ list. Looping a per-coin tool over N coins costs several times this and returns the same values.
37
38
  4. **Coin deep-dive**, when the player named a coin or when one dominates the read: the SAME
38
- `preview_strategy_report` call as step 3, with `{ "kind": "tickers", "tickers": ["SOL"] }` as the
39
+ `preview_strategy_report` call as step 3, with `{ "mode": "explicit", "tickers": ["SOL"] }` as the
39
40
  coin selection and the funding / open-interest / positioning sections chosen — one coin is a
40
41
  one-row report, not a different tool. Then `get_coin_candles` for the price action. For momentum
41
42
  across timeframes, add the Relative Strength section — it carries the PPO trajectory and its
42
43
  zero-crossing — or author `PPO` columns at the intervals you want pinned; that is the same read
43
44
  at the precision the catalog declares, in the call you are already making. Use
44
45
  `get_coin_performance_history` when the question is about how it has behaved, not where it is.
46
+ Coin symbols are case-insensitive and exchange symbols are accepted (`btc`, `kPEPE`,
47
+ `xyz:BRENTOIL`); a symbol that names no tracked coin is rejected with an error naming the field,
48
+ never answered as an empty read — say the coin is not tracked rather than retrying it.
45
49
  4b. **How much of the FIELD is moving, not just this coin.** Add the Market Breadth module
46
50
  (`{ "kind": "platform", "sectionKey": "includeMarketBreadth" }`) for the two-axis read: how much
47
51
  of the tracked universe closed up, and how much of it carries positive momentum. It reports per