@battlegrid/mcp-server 31.2.45 → 31.2.48

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,40 @@ 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 — v66.1 → v67
28
+
29
+ **Breaking at v67: four output fields removed.** v66.1 and v66.2 were additive and are recorded here
30
+ with it.
31
+
32
+ ### Reshaped output — `get_agents_hub` (v67, breaking)
33
+
34
+ - **`summary` loses `messagesUsedToday`, `dailyLimit`, `messagesUsedPercent` and
35
+ `avgCostPerMessageUsd`.** They reported the in-app arena chat's daily message quota, and that chat
36
+ is retired, so every value would have read zero. A strict client that reads them fails to parse the
37
+ summary. The rest of the summary is unchanged; per-agent spend stays on each row's `cost24hUsd`.
38
+
39
+ ### Wider surface — two tools added (v66.2)
40
+
41
+ - **`scan_coin_agents`** (`coinTicker`; `mcp:read`) — one coin evaluated against every one of the
42
+ caller's own agents, ranked in four arrays: `qualified` by score, `rejected` with the first failing
43
+ gate, `unscorable`, and `ineligible` with the code `propose_entry_decision` would refuse the agent
44
+ with (`AGENT_NOT_ACTIVE`, `MODEL_INACTIVE`, `AGENT_HALTED`). `rank` is global across the four.
45
+ Rate-limited per user: a refusal is `RATE_LIMITED` with `retryAfterSeconds`.
46
+ - **`get_onboarding_requirements`** (no input; `mcp:read`) — the caller's readiness ladder: every
47
+ rung, the spine counts and the next rung.
48
+
49
+ ### Reshaped output — `get_strategy_draft` (v66.1)
50
+
51
+ - **`draft` gains `lastSource`** — the surface of the draft's latest write (`form`, `commander`,
52
+ `telegram` or `mcp`), as the agent and radar draft reads already publish. Before v66.1 every read of
53
+ an existing strategy draft failed its output check with `INTERNAL_ERROR`; it now succeeds.
54
+
55
+ ### Vocabulary
56
+
57
+ `toolCount` goes 132 → 134. The added tools' schemas are new; `get_strategy_draft`'s and
58
+ `get_agents_hub`'s output schemas move. Descriptions that named the app's retired Agent Toolbox trade
59
+ tab now name Commander.
60
+
27
61
  ## Contract history — v66
28
62
 
29
63
  **Breaking: one tool retired and one input reshaped.** Radar content now commits only as a draft the
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.45";
52
+ export declare const PACKAGE_VERSION = "31.2.48";
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.45';
55
+ export const PACKAGE_VERSION = '31.2.48';
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.45",
3
+ "version": "31.2.48",
4
4
  "description": "BattleGrid MCP server — play crypto prediction games from AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "generator": "battlegrid-app/server/scripts/export-mcp-skills.mjs",
3
- "contractVersion": "66.1.0",
3
+ "contractVersion": "68.0.0",
4
4
  "files": {
5
5
  "battlegrid-agent-management/SKILL.md": "fbc602e9445d0f72353bfba23c30a364b478bd04a9cc6248418cfeec66717eb1",
6
6
  "battlegrid-arena-play/SKILL.md": "4cfaa92a8d0dcaf477b227abd774e7aa8642c185d72108dfd401be0cf8aecd7f",
7
7
  "battlegrid-market-analysis/SKILL.md": "22fde9c4eac0261c89a8056ab8b20b66fcbe1fd58447fa0ac84fd410b4d134d7",
8
- "battlegrid-radar-deployment/SKILL.md": "40cff6a1f5beac8a9f7d6e7a0805af6209613691170eddc19f9a7bc301cdeded",
8
+ "battlegrid-radar-deployment/SKILL.md": "e2098ac23d80ab985eb93d46f6cc81c84b63dbba12b3bb3eb4cfdcef10ef3b82",
9
9
  "battlegrid-strategy-authoring/SKILL.md": "95e91dd1ff36922b7ed0f5eb92c98def98fa39cce37c3d7447269aea1b5a017f",
10
10
  "battlegrid-strategy-doctor/SKILL.md": "d0b9e9e07648246d5a23b0c17183278b70b5bcbb5f472ac7da13d03e42a6c6c6",
11
11
  "battlegrid-strategy-examples/SKILL.md": "17e8cf8040813622bd5b82165c7af82e03287fee1f6aac974e0b6c584580dd27",
@@ -13,6 +13,6 @@
13
13
  "battlegrid-strategy-examples/references/recipes.md": "53887daece17995543e7d3fe1bf2577fc41a6254c291acacde48d7de63853641",
14
14
  "battlegrid-strategy-examples/references/tradingview-ports.md": "2b13adbc137178955edcca31b6ab40c01c745a932a0750b91db8820c736700bb",
15
15
  "battlegrid-trade-analysis/SKILL.md": "f49482702f17d7fc44db00c31a19fc6e9350668fe76e8948d22faaa9c7e9d6bf",
16
- "battlegrid-trade-proposal/SKILL.md": "a198dd360bd7a1de5f00237b544a3535fc7c373612c09cf9a9dae4f2607c489a"
16
+ "battlegrid-trade-proposal/SKILL.md": "4cdb46a543cc126092874a4b385670ea2160de0384b7b5087c93b0aa72830b79"
17
17
  }
18
18
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: battlegrid-radar-deployment
3
- description: Deploy the player's agents to standing duty — per-coin Radar policies that fire real trades on confirmed regime flips, and per-preset Arena deployment policies that enter sessions automatically. Reads what is deployed now, stages a Radar change into the player's draft, previews what it would actually resolve to, commits it only after the player has seen that preview, and un-deploys with the blast radius stated. Activate whenever the player wants an agent put on duty, wants to change or pause a deployment, asks what would fire right now or why nothing is firing, or wants to stop a coin or a preset being traded automatically.
3
+ description: Deploy the player's agents to standing duty — per-coin Radar policies that fire real trades on confirmed regime flips, and per-preset Arena deployment policies that enter sessions automatically. Reads what is deployed now, stages a change into the player's draft, previews what it would actually resolve to, commits it only after the player has seen that preview, and un-deploys with the blast radius stated. Activate whenever the player wants an agent put on duty, wants to change or pause a deployment, asks what would fire right now or why nothing is firing, or wants to stop a coin or a preset being traded automatically.
4
4
  ---
5
5
 
6
6
  # Radar & Deployment
@@ -17,15 +17,14 @@ and never describe them as one thing with two modes.
17
17
  ## The five failures this flow exists to prevent
18
18
 
19
19
  1. **A write with no fresh preview.** *Cue: any `commit_radar_deployment_draft`,
20
- `resume_radar_deployment` or `upsert_deployment_policy`.* The preview is the only place the
20
+ `resume_radar_deployment`, `commit_deployment_policy_draft` or `resume_deployment_policy`.* The preview is the only place the
21
21
  player sees which agent actually goes on duty and why. → steps 2–3.
22
22
  2. **A blind retry.** *Cue: a CONFLICT on a write.* Something moved under you — the stored policy,
23
- or for Radar the player's draft. Retrying overwrites an edit you never read. → step 3.
23
+ or the player's draft. Retrying overwrites an edit you never read. → step 3.
24
24
  3. **Previewing one thing and writing another.** *Cue: the player adjusts a slot, a bar, a window
25
25
  or a regime after you previewed.* A preview vouches only for what it resolved. → step 2.
26
- 4. **A replacement that silently drops slots.** *Cue: a Radar `RULES` axis staged over a deployed
27
- coin, or any Arena upsert on a preset that already has a policy.* Radar's `RULES` is the COMPLETE
28
- ordered rule list and Arena's `slots` the complete slot set: a rule or slot you did not resend is
26
+ 4. **A replacement that silently drops rules.** *Cue: a `RULES` axis staged over a deployed coin or
27
+ a deployed arena.* `RULES` is the COMPLETE ordered rule list on both: a rule you did not resend is
29
28
  deleted. → step 3.
30
29
  5. **Answering "why isn't it firing?" by paging the journal.** *Cue: any question about why a
31
30
  deployed agent has been quiet — "is it working?", "it hasn't traded all day", "what's blocking
@@ -55,9 +54,10 @@ Then read what exists:
55
54
  `list_radar_deployment_drafts` when no coin is named yet. The player may be part-way through a
56
55
  change in their radar builder. **If a draft exists, say so** — what it holds, and when and from
57
56
  where it was last written — and propose against it rather than starting over beside it.
58
- - `get_deployment_policy` / `list_deployment_policies` for Arena. The read supplies
59
- `expectedRevision` for the Arena write: **`null` only for a first deploy** — a preset with no
60
- policy at all.
57
+ - `get_deployment_policy` / `list_deployment_policies` for Arena, and **the player's draft of the
58
+ arena** with `get_deployment_policy_draft` — or `list_deployment_policy_drafts` when no arena is
59
+ named yet, which also lists arenas the player started but never deployed. Mention an existing draft
60
+ the same way: what it holds, and when and from where it was last written.
61
61
 
62
62
  `get_regime_snapshot` / `get_regime_history` when the policy turns on regime conditions.
63
63
 
@@ -80,7 +80,17 @@ If the question is *why did my radar agent not fire*, do not start from the jour
80
80
  To try a slot set without touching the draft, preview `{ kind: "SLOTS", deploymentTimeframe, slots }` —
81
81
  it certifies nothing and cannot be committed.
82
82
 
83
- **Arena** → `preview_deployment_resolution` with the draft slots.
83
+ **Arena** — the same shape, keyed on `presetId`:
84
+
85
+ 1. `stage_deployment_policy_draft` with `draftVersion` = the `version` you read (0 when there was no
86
+ draft) and only the axes you are changing, each WHOLE: `RULES` (the complete ordered rule list —
87
+ first is highest priority, one regime per rule), `DEFAULT_SLOT` (the catch-all, or null for none)
88
+ and `REGIME_ANCHOR` (the anchor override, or null to inherit the arena's). Pausing is never staged.
89
+ 2. `preview_deployment_resolution` with `request: { kind: "DRAFT", draftVersion }` at the version
90
+ staging returned.
91
+
92
+ A draft that would hold no rule and no catch-all is a withdrawal, which a commit never does — that is
93
+ `delete_deployment_policy` (step 4).
84
94
 
85
95
  Both previews run the **same resolver the live sweep runs**, so the preview is the real outcome, not
86
96
  an estimate. Neither writes anything and neither costs the player an LLM call — so previewing
@@ -90,8 +100,8 @@ Render the preview as a card and read it out: which agent goes on duty, which sl
90
100
  what priority, the regime and conviction used, the qualification verdict, and any typed idle or
91
101
  blocked reason. **Render `section` as the server sends it — never re-derive it.** A non-null reason
92
102
  does not mean idle (`ON_DUTY_BUT_POSITION_BLOCKED` carries a reason and is not idle), so deciding
93
- the headline yourself gets it wrong. For Radar, `enabledAfterCommit` says whether the policy will
94
- trade once committed — a paused policy stays paused.
103
+ the headline yourself gets it wrong. `enabledAfterCommit` says whether the policy will play once
104
+ committed — a paused policy stays paused, and a first Arena deployment always plays.
95
105
 
96
106
  **If anything changes after a preview, re-preview.** A preview never vouches for what it did not
97
107
  resolve.
@@ -104,20 +114,20 @@ the reason — and **names what the change does to the stored policy**, read fro
104
114
  - every rule or slot the change **removes** (by agent and priority), because `RULES` and `slots` are
105
115
  the whole set;
106
116
  - a bar, window or regime that **changes** on a rule or slot that survives;
107
- - for Arena, `enabled` going false (**paused, slots kept — nothing fires**) or true (**resumed — it can
108
- fire again from the next confirmed flip**).
117
+ - whether it will play once committed, from `enabledAfterCommit` — a commit never changes a pause.
109
118
 
110
119
  Then:
111
120
 
112
121
  - **Radar** → `commit_radar_deployment_draft({ coinId, previewToken, confirm: true })`, with the
113
122
  `previewToken` the **live** DRAFT preview returned — no `simulatedRegime`, within five minutes. The
114
123
  draft ends when it commits.
115
- - **Arena** → `upsert_deployment_policy` with the revision from step 1.
124
+ - **Arena** → `commit_deployment_policy_draft({ presetId, previewToken, confirm: true })`, the same
125
+ way: the live DRAFT preview's token, within five minutes. The draft ends when it commits.
116
126
 
117
127
  **On a typed CONFLICT: re-read, re-preview, re-confirm.** In that order, and all three. The draft or
118
128
  the policy changed under you, so the state your preview resolved and the radius you stated are both
119
- stale. A Radar certificate is bound to the draft version, the deployment and its content, so a
120
- retry with the old one is refused again — only a fresh preview earns a new one.
129
+ stale. A certificate is bound to the draft version, the deployment and its content, so a retry
130
+ with the old one is refused again — only a fresh preview earns a new one.
121
131
 
122
132
  ### 4. Pause, resume, discard, delete
123
133
 
@@ -127,23 +137,34 @@ never waits on a read. The player's draft is kept. **Resume** → preview the de
127
137
  `resume_radar_deployment({ coinId, previewToken, confirm: true })` with the token that preview
128
138
  returned.
129
139
 
130
- **Discard a Radar draft** only on the player's word. Call `discard_radar_deployment_draft` with
140
+ **Pause an arena** → `pause_deployment_policy({ presetId })`, and **resume** it the Radar way: preview
141
+ `{ kind: "COMMITTED" }`, then `resume_deployment_policy({ presetId, previewToken, confirm: true })` on
142
+ the player's word. Both touch only the pause, never the rules or the player's draft.
143
+
144
+ **Entries already made stand.** A pause or a delete of an arena returns `openEntries` — the sessions
145
+ the player's agent already entered that have not locked, each with its lock time and entry fee. They
146
+ play out unless the player cancels them. Name each one, ask whether to cancel it, and call
147
+ `cancel_market_grid_submission({ sessionId, confirm: true })` only for the entries they pick — the
148
+ same cancellation and refund as their own Cancel button. Say nothing is cancelled when they decline.
149
+
150
+ **Discard a draft** only on the player's word. Call `discard_radar_deployment_draft` or
151
+ `discard_deployment_policy_draft` with
131
152
  `confirm: false` first: the answer names what the draft holds, its version, and when and from where
132
153
  it was last written. Tell the player, ask, and call with `confirm: true` and `expectedVersion` set to
133
154
  **the version you were shown**. If the draft moved since, nothing is removed and the answer names what
134
155
  it now holds — show them again.
135
156
 
136
157
  **Deletes** — `delete_radar_deployment` / `delete_deployment_policy` remove the **entire** policy —
137
- every slot and condition — and revoke the standing authority. Un-deploying a Radar coin **also ends
138
- the player's draft of it**. There is no preview here, and correctly so: there is no resolution to
139
- preview once the policy is gone. The evidence is **the deployment's own read**, which supplies the
140
- `expectedRevision` the delete carries.
158
+ every slot and condition — and revoke the standing authority. Un-deploying **also ends the player's
159
+ draft** of the coin or the arena. There is no preview here, and correctly so: there is no resolution
160
+ to preview once the policy is gone. The evidence is **the deployment's own read**, which supplies the
161
+ `expectedRevision` the delete carries — and for Arena the `expectedPolicyId` beside it.
141
162
 
142
163
  State what stops, from that read: which agents were on duty or eligible, what the policy was
143
164
  firing on, and that the slots are not recoverable. Both tools carry a schema-level `confirm: true`.
144
165
 
145
166
  **If the player wants to stop trading without losing the slots, that is not a delete** — it is
146
- `pause_radar_deployment` for Radar, and an upsert with `enabled: false` for Arena. Offer that
167
+ `pause_radar_deployment` for Radar and `pause_deployment_policy` for Arena. Offer that
147
168
  whenever the ask sounds like "pause", "stop for now", or "take it off duty for a while".
148
169
 
149
170
  ### 5. "Why isn't it firing?" — state, then pattern, then rows
@@ -187,23 +208,19 @@ Two negatives, both checkable:
187
208
  rollup's counts span every matching row inside `windowStartAt`–`windowEndAt` — quote them with
188
209
  that window ("41 times in the last 7 days"), never as a total.
189
210
 
190
- ## Preview-before-commit: enforced for Radar, this flow's rule for Arena
211
+ ## Preview-before-commit: enforced for both
191
212
 
192
- **Radar** arms only with a certificate. `commit_radar_deployment_draft` takes the certificate a live
193
- preview of that draft returned, and `resume_radar_deployment` one from a live preview of the deployed
194
- policy. Each is bound to your credential, the player, the coin, the subject previewed, the deployment
195
- and its revision, the draft version and the content the preview resolved, and expires after five
196
- minutes. A simulated preview returns none. So a commit of anything the player was not shown is
213
+ A deployment arms only with a certificate. `commit_radar_deployment_draft` and
214
+ `commit_deployment_policy_draft` take the certificate a live preview of that draft returned, and
215
+ `resume_radar_deployment` and `resume_deployment_policy` one from a live preview of the deployed
216
+ policy. Each is bound to your credential, the player, the coin or arena, the subject previewed, the
217
+ deployment and its revision, the draft version and the content the preview resolved, and expires after
218
+ five minutes. A simulated preview returns none. So a commit of anything the player was not shown is
197
219
  refused by the server — but the player's confirmation is still yours to ask for, against the preview.
198
220
 
199
- **Arena** has no server-side preview receipt: the upsert takes no token proving a preview happened,
200
- and the CAS revision is the only cross-call state. There the sequence above is what holds the
201
- invariant. Treat it as binding anyway: an Arena write that reaches the player's confirm with no
202
- preview in the conversation is a failure of this skill even if the server accepts it.
203
-
204
221
  ## When a write's outcome is unknown
205
222
 
206
- An interrupted or timed-out commit, pause, resume, upsert or delete may have landed. **Read the
223
+ An interrupted or timed-out commit, pause, resume, delete or cancel may have landed. **Read the
207
224
  deployment first** (`get_radar_deployment` / `get_deployment_policy`) and report what is actually
208
225
  stored. A committed change is a success to report, not a call to repeat. Never blind-retry a write
209
226
  whose outcome you did not see.
@@ -211,7 +228,7 @@ whose outcome you did not see.
211
228
  ## `test_generate_deployment_grid`
212
229
 
213
230
  This one runs a **billed LLM generation** against the player's intelligence credits and writes
214
- thought and activity records. It is a composition aid for tuning a draft deployment — say that it
231
+ thought and activity records. It is a composition aid for tuning an Arena deployment — say that it
215
232
  is billed **before** invoking it, and only invoke it when the player is actually iterating on slots
216
233
  and wants to see what the resolved agent would produce. It is never a diagnostic read.
217
234
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: battlegrid-trade-proposal
3
- description: Find and stage a trade for one of the player's agents, for the player to approve. Activate whenever the player asks which coins fit an agent right now, wants a trade found or proposed for an agent, asks the agent to evaluate a coin, or wants to approve or decline a proposal it made. The scan is the agent's own gates over every active coin; a proposal is QUEUED for the agent's next strategy-bar close and answered into the conversation when that bar is decided; approval is always the player's word.
3
+ description: Find and stage a trade for one of the player's agents, for the player to approve. Activate whenever the player asks which coins fit an agent right now, which of their agents fits a coin, wants a trade found or proposed for an agent or on a coin, asks the agent to evaluate a coin, or wants to approve or decline a proposal it made. The scans are the agents' own gates — one agent over every active coin, or one coin over every one of the player's agents; a proposal is QUEUED for the agent's next strategy-bar close and answered into the conversation when that bar is decided; approval is always the player's word.
4
4
  ---
5
5
 
6
6
  # Trade Proposal
@@ -16,7 +16,23 @@ re-sorts a list, re-derives a verdict, or approves on the player's behalf.
16
16
  it is accepted, cancelled or expires. **Never propose on a coin the player already holds a pending
17
17
  or live position on** — say why, and name the decision or position that holds it.
18
18
 
19
- ## 1. Which coins fit the agent right now
19
+ ## 1. When the player names a coin and not an agent — choose the agent
20
+
21
+ - `scan_coin_agents` for the coin. The rows arrive server-ranked across the player's own agents:
22
+ `qualified` by score, then `rejected` with the first failing gate, then `unscorable` with the
23
+ reason, then `ineligible` with the refusal `propose_entry_decision` would give (`AGENT_NOT_ACTIVE`,
24
+ `MODEL_INACTIVE`, `AGENT_HALTED`). Read them **as written** — never re-sort or re-derive a verdict.
25
+ - **Ask the top-ranked qualifying agent**, and name the other agents that qualified so the player can
26
+ choose one of them instead. One request per coin: the platform holds one pending request per coin
27
+ across all of the player's agents, so ask one agent, not each of them.
28
+ - **When none qualifies, say so plainly.** Name each agent's blocking gate or ineligibility, and offer
29
+ the strategy doctor for the one closest to qualifying. Never propose through an agent the scan
30
+ reports rejected, unscorable or ineligible.
31
+ - **When the player has no agent at all**, the scan is empty: say so, and the next step is building one
32
+ (a strategy first, when they have none).
33
+ - A refused scan (`RATE_LIMITED`) is a refusal with its retry-after, never "nothing fits".
34
+
35
+ ## 2. Which coins fit the agent right now
20
36
 
21
37
  - `scan_agent_coins` for the agent. The rows arrive server-ranked: qualifying coins first by score,
22
38
  then the rest with their first failing gate, then coins that could not be scored with the reason.
@@ -29,16 +45,7 @@ re-sorts a list, re-derives a verdict, or approves on the player's behalf.
29
45
  - A refused scan (`RATE_LIMITED`) is a refusal: say the scan was refused and when it can be retried
30
46
  (`retryAfterSeconds`). Never say "nothing fits".
31
47
 
32
- ## 2. Queue the request
33
-
34
- **In a conversation the Agent Toolbox hosts, this section does not apply: name the coin and stop.**
35
- The player presses **Request a trade** in the trade lane beside you and the same queued request is
36
- registered from there, free and without a model turn; your job is to say which coin is worth
37
- requesting and what the gates read, and to leave the press to them. `propose_entry_decision` and
38
- `cancel_entry_request` are refused from such a conversation as tool errors, so calling one spends an
39
- op of your budget and queues nothing. The refusal is **host-wide** — every tool that writes is
40
- refused there, which is why no other skill carries a paragraph of its own — and every read in this
41
- flow stays available.
48
+ ## 3. Queue the request
42
49
 
43
50
  - `propose_entry_decision` **only** on the coins the player named, or on the top qualifying row
44
51
  when they asked for the best fit. One coin per call.
@@ -50,7 +57,7 @@ flow stays available.
50
57
  - **One pending request per coin.** A second is refused with `CONFLICT` / `REQUEST_PENDING` — read
51
58
  the one that exists with `get_entry_request` rather than asking again.
52
59
 
53
- ## 3. Tell the player what they are waiting for
60
+ ## 4. Tell the player what they are waiting for
54
61
 
55
62
  - `type: "queued"` is the normal answer. Read `request` back to them: the bar being decided
56
63
  (`barStart`), when the answer is due (`decidesBy`), and the deadline past which that bar can no
@@ -71,10 +78,10 @@ flow stays available.
71
78
  `topupAvailable` is true. A refused request (`RATE_LIMITED`) is a refusal with its retry-after.
72
79
  Never "nothing to do".
73
80
  - `type: "recommendation"` and `type: "no_trade"` arrive only as the **replay** of a request made
74
- before the queued contract shipped. Report them as step 4 describes and do not expect them from a
81
+ before the queued contract shipped. Report them as step 5 describes and do not expect them from a
75
82
  fresh call.
76
83
 
77
- ## 4. When the answer arrives — approve or decline only on the player's word
84
+ ## 5. When the answer arrives — approve or decline only on the player's word
78
85
 
79
86
  **On a web Commander surface the approval is the card's own.** The decided close lands on the
80
87
  delegation card in this conversation, carrying the player's Accept and Decline. `accept_entry_decision`
@@ -82,12 +89,6 @@ and `cancel_entry_decision` remain yours for the external and Telegram doors, an
82
89
  the player's explicit typed word — never inferred from interest, agreement, or a question about the
83
90
  trade.
84
91
 
85
- **In a conversation the Agent Toolbox hosts, the approval is not yours to send at all.** The decided
86
- close lands on the trade card in the lane beside you, carrying the player's own Accept and Decline;
87
- `accept_entry_decision` and `cancel_entry_decision` are refused there as tool errors, so calling one
88
- spends an op and moves nothing. Read the card back to them — the direction, the levels, the
89
- conviction, the expiry — and say what you would do, which is the whole of your part.
90
-
91
92
  - A decided close produces one of: a PROPOSED decision awaiting approval; a no-trade with the
92
93
  reason and the next coins worth asking about; a close that did not qualify; a window that passed
93
94
  with no sweep; or a bar the agent's own radar deployment decided first and traded in full.