@battlegrid/mcp-server 31.2.46 → 31.2.49

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,110 @@ 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 — v68.1 (Arena regime sets)
28
+
29
+ Purely additive in schema, with **one refusal behind unchanged ones.** An Arena rule's regime condition
30
+ is a SET in the draft, as it always was in the committed deployment: one rule can fire in several
31
+ regimes, instead of one rule per regime.
32
+
33
+ ### Wider input — `stage_deployment_policy_draft`
34
+
35
+ - **A rule's `regimes` may name several regimes**, where the draft capped it at one. The set is stored in
36
+ the selectable-regime order, so a staged `[VOLATILE, BULL_EXPANSION]` reads back
37
+ `[BULL_EXPANSION, VOLATILE]`. A regime named twice is refused.
38
+
39
+ ### Wider output — `get_deployment_policy_draft`
40
+
41
+ - **The draft may return such a set.** `get_deployment_policy` has served sets all along, so a client that
42
+ reads a committed deployment already handles them.
43
+
44
+ ### Refusals behind unchanged schemas
45
+
46
+ - **`preview_deployment_resolution` (SLOTS), `preview_radar_resolution` (SLOTS) and
47
+ `test_generate_deployment_grid` refuse a regime condition naming one regime twice**, as
48
+ `VALIDATION_ERROR` at its `regimes` field, where they used to resolve or generate over it. The stage tools
49
+ already refused a repeat, so no commit changes; a repeated member is a malformed set.
50
+
51
+ ## Contract history — v68 (Arena drafts)
52
+
53
+ **Breaking: one tool retired, two inputs reshaped.** Arena deployment content now commits only as a
54
+ draft the player was shown a live preview of, as radar content has since v66. The player's deploy
55
+ editor and every conversation share one unsaved draft per arena.
56
+
57
+ ### Removed tool — something you call no longer exists
58
+
59
+ - **`upsert_deployment_policy` is retired**, with no alias. Calling it is an unknown-tool error. To
60
+ deploy or change an arena's deployment:
61
+ 1. `stage_deployment_policy_draft` the axes you are changing (`RULES`, `DEFAULT_SLOT`,
62
+ `REGIME_ANCHOR`), with the `draftVersion` your last read returned;
63
+ 2. `preview_deployment_resolution` with `request: { kind: "DRAFT", draftVersion }` at the version
64
+ staging returned;
65
+ 3. show the player the resolution and whether it will play (`enabledAfterCommit`), and on their word
66
+ call `commit_deployment_policy_draft` with the `previewToken` that preview returned and
67
+ `confirm: true`.
68
+
69
+ Pausing is no longer a flag on the write: use `pause_deployment_policy`. **A first deployment always
70
+ plays**; a replacement keeps its pause.
71
+
72
+ ### Rejected input — something you send is no longer accepted
73
+
74
+ - **`preview_deployment_resolution`'s `request` needs a `kind`.** `{ kind: "SLOTS", slots, … }` is the
75
+ old request. `{ kind: "DRAFT", draftVersion }` previews the player's draft of the arena at that
76
+ version, composed over the deployed policy exactly as the commit writes it. `{ kind: "COMMITTED" }`
77
+ previews the deployed policy a resume would arm. A request without `kind` is refused.
78
+ - **`delete_deployment_policy` requires `expectedPolicyId`** beside `expectedRevision`: a revision
79
+ restarts at 1 when an arena is redeployed, so only the pair names the deployment you read.
80
+ - **A regime anchor override names its coin and timeframe together, or neither**, on every path
81
+ including `test_generate_deployment_grid` and the SLOTS preview.
82
+
83
+ ### Wider surface — eight tools added
84
+
85
+ - **`stage_deployment_policy_draft`**, **`get_deployment_policy_draft`**,
86
+ **`list_deployment_policy_drafts`** and **`discard_deployment_policy_draft`** (`mcp:read`). None of
87
+ them commits or arms anything.
88
+ - **`commit_deployment_policy_draft`** (`presetId`, `previewToken`, `confirm: true`; `mcp:wager`) — the
89
+ only MCP committer of Arena content.
90
+ - **`pause_deployment_policy`** (`presetId`; `mcp:wager`) — no revision and no certificate.
91
+ - **`resume_deployment_policy`** (`presetId`, `previewToken`, `confirm: true`; `mcp:wager`) — needs the
92
+ certificate a live `COMMITTED` preview returned.
93
+ - **`cancel_market_grid_submission`** (`sessionId`, `confirm: true`; `mcp:wager`) — the player's own
94
+ cancellation and refund of one entry.
95
+
96
+ ### Reshaped and wider output
97
+
98
+ - **`preview_deployment_resolution`** nests the resolution under `resolution` and gains
99
+ **`previewToken`** (the certificate a live DRAFT or COMMITTED preview earns, null otherwise, good for
100
+ five minutes) and **`enabledAfterCommit`**.
101
+ - **`pause_deployment_policy` and `delete_deployment_policy` return `openEntries`**: the entries the
102
+ player's agent already made in the arena's pending sessions, each with its lock time and entry fee.
103
+ They play out unless the player cancels them — tell the player and ask, then call
104
+ `cancel_market_grid_submission` only for the entries they pick.
105
+ - **`get_deployment_policy`'s `authoringContext`** gains the arena's header facts
106
+ (`regimeReferenceTicker`, `presetBadgeImageUrl`, `entryFee`, and `playerCount` — null when the arena
107
+ has no pending session to count).
108
+ - The thought-log **`outcome`** gains **`SKIPPED_DEPLOYMENT_DISARMED`**: an entry job that found its
109
+ deployment withdrawn, paused or no longer slotting its agent stood down before paying.
110
+
111
+ ### Refusals worth knowing before you commit or resume
112
+
113
+ - **The certificate is bound to what you previewed**: your credential, the player, the arena, the
114
+ subject, the deployment and its revision, the draft version and the composed content. Anything that
115
+ moves is a `CONFLICT` and nothing is written. Preview again; never reuse the old certificate.
116
+ - **A commit never withdraws**: a draft with no rule and no catch-all is refused, naming
117
+ `delete_deployment_policy`.
118
+ - **Resume is refused on a retired arena and on one the player's access was revoked from**; pausing and
119
+ withdrawing stay open.
120
+ - **Deployment refusals answer `INVALID_DEPLOYMENT_POLICY`.**
121
+ - **`delete_deployment_policy` also ends the player's draft of the arena.**
122
+
123
+ ### Vocabulary
124
+
125
+ `toolCount` goes 134 → 141 (eight added, one retired). `preview_deployment_resolution`'s input and
126
+ output, `delete_deployment_policy`'s input and output, `get_deployment_policy`'s and
127
+ `list_deployment_policies`' outputs, the three journal outputs and `test_generate_deployment_grid`'s
128
+ input (a session start now accepts up to 288 times a day) move; `upsert_deployment_policy`'s are
129
+ removed.
130
+
27
131
  ## Contract history — v66.1 → v67
28
132
 
29
133
  **Breaking at v67: four output fields removed.** v66.1 and v66.2 were additive and are recorded here
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.46";
52
+ export declare const PACKAGE_VERSION = "31.2.49";
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.46';
55
+ export const PACKAGE_VERSION = '31.2.49';
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.46",
3
+ "version": "31.2.49",
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.