@battlegrid/mcp-server 31.2.64 → 31.2.66

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.
@@ -9,8 +9,10 @@ The player configured an agent, pointed real money at it, and something did not
9
9
  to find out what, from the fields that actually say so — and then to say what would change it, in
10
10
  terms of levers that exist.
11
11
 
12
- Everything here is a **read**. You have no write path, and you do not acquire one by finding a
13
- problem: the fix runs through the flow that owns it, with that flow's own confirms.
12
+ Everything you do here is a **read**. You have no write path, and you do not acquire one by finding
13
+ a problem: the fix runs through the flow that owns it, with that flow's own confirms. The agent's
14
+ draft tools are visible in this skill so that a risk-limit improvement can name its lever exactly
15
+ (step 4) — never so that you call them from this arc.
14
16
 
15
17
  ## The five failures this flow exists to prevent
16
18
 
@@ -114,11 +116,14 @@ recommend.
114
116
 
115
117
  Present a ranked list. **Each item names the concrete thing that would apply it:**
116
118
 
117
- - a **strategy-rule** change → the `strategy-authoring` skill (its compile → review → confirm →
118
- apply arc);
119
+ - a **strategy-rule** change → the `strategy-authoring` skill, whose arc stages the change into
120
+ the strategy's draft, reads it back with its diff and impact, and commits only on the player's
121
+ confirming pick;
119
122
  - a **deployment or radar policy** change → the `radar-deployment` skill's tools, named;
120
- - a **risk-limit or budget** change → `agent-management`'s update verb, and note that it is a
121
- **whole-object** write: the current limits are read and the complete object written back;
123
+ - a **risk-limit or budget** change → `agent-management`'s draft: the complete TRADING_CONFIG
124
+ axis — a **whole-object** write, the current limits read and the complete object written back —
125
+ staged with `stage_agent_draft` and committed with `commit_agent_draft` once that flow's
126
+ confirmation is answered;
122
127
  - a **halt recovery** → the specific lever from step 3.
123
128
 
124
129
  An improvement with **no lever on this platform** is labelled as such, explicitly, and never
@@ -155,6 +160,10 @@ it is undetermined.
155
160
  one: route a rule change by naming the `strategy-authoring` skill, as step 4 does. The authoring
156
161
  tools are in a family this skill does not declare, and a skill body that names an unreachable tool
157
162
  — including in a negative — fails the registry's reachability check.
163
+ - **Never call the agent's draft tools from this arc.** Step 4 names `stage_agent_draft` and
164
+ `commit_agent_draft` as the lever a risk-limit change takes; applying it activates
165
+ `agent-management`, whose arc stages the change, reads the draft back, states the radius and asks
166
+ before anything is committed.
158
167
  - Never diagnose from the agent's own prose or overlay text where a typed field exists.
159
168
  - Never present a gate-block count as a rate, a trend, or a percentage — report it as served.
160
169
 
@@ -5,8 +5,8 @@ description: Full-surface composition patterns for the strategy studio — valid
5
5
 
6
6
  # Strategy Studio — full-power composition patterns
7
7
 
8
- `strategy-authoring` owns the flow (evidence → locked spec → discover → compile → review →
9
- apply). This skill owns **what to compose**: a default build — a few platform sections, no
8
+ `strategy-authoring` owns the flow (evidence → locked spec → discover → stage → review →
9
+ commit). This skill owns **what to compose**: a default build — a few platform sections, no
10
10
  conditions, untouched weights — wastes the studio. The playbooks below are compiled in CI, so their
11
11
  shapes are binding in the sense that matters — they are checked, not merely asserted. Loose tokens
12
12
  elsewhere in this file are not covered by that gate, and vocabulary moves with deploys, so discovery
@@ -17,14 +17,15 @@ them.
17
17
 
18
18
  ## The full-power checklist
19
19
 
20
- Before compiling a CREATE, every "no" here is a decision to state, not an omission:
20
+ Before committing a CREATE, every "no" here is a decision to state, not an omission:
21
21
 
22
22
  1. At least one **custom section** whose columns encode the thesis — not only platform modules.
23
23
  2. **Conditions** encode the entry logic: building blocks (`verdict: null`) + verdict carriers,
24
24
  and at least one `required: true` condition vetoing obvious disqualifiers **before any
25
25
  billing or LLM call**.
26
26
  3. **Every signal meant to score is named in `rules`** with a deliberate tier — unnamed signals
27
- keep server defaults (typically Off). Verify in the compiled scorecard, never assume.
27
+ keep server defaults (Off on a CREATE). Verify against the rule rows the draft read serves,
28
+ never assume.
28
29
  4. **Gates** (`minAggregateScore`, `minRequiredCount`, `minAtrPct`) are computed against the
29
30
  chosen weight budget, not guessed.
30
31
  5. **Trade levels + position management** match the setup's geometry and holding period.
@@ -66,9 +67,10 @@ standard market-leader regime gate. Platform `sectionKey`s are their literal key
66
67
  (`includeMtfConfluence`). Custom `sectionKey`s are the **server's** to issue, and which of the two
67
68
  things you do depends on the operation: on a **CREATE, omit `sectionKey` entirely** — supplying one
68
69
  is refused, since a new strategy owns no custom sections yet; on an **UPDATE or RESTORE, send back
69
- the keys `get_strategy` returned** for the sections you are keeping. Either way you never invent
70
- one. To section-qualify a duplicated header, read the key from a preview's `conditionColumns` or
71
- from the qualified candidates a `CONDITION_COLUMN_AMBIGUOUS` refusal offers.
70
+ the keys `get_strategy` returned** for the sections you are keeping, and omit it on a section you
71
+ add. Either way you never invent one. To section-qualify a duplicated header, read the key from a
72
+ preview's `conditionColumns` or from the qualified candidates a `CONDITION_COLUMN_AMBIGUOUS`
73
+ refusal offers.
72
74
 
73
75
  **Event columns print only on their event.** `MACD_cross` and `EMA5_13` (Bullish/Bearish) carry a
74
76
  value on the crossing bar and are null on every other one, which reads as UNRESOLVED. Use an event
@@ -220,11 +222,12 @@ scan has on that coin, or free the coin.
220
222
  **The refusal lands where an agent meets a coin**: at the radar deploy (its preview, the builder's
221
223
  Save and the draft commit); at a manual entry request, as `CONDITION_UNREADABLE_ON_COIN`;
222
224
  and, for an agent already deployed or holding an open position or a pending manual request, at a
223
- strategy save (`compile_strategy_plan`, `apply_strategy_plan`, `restore_strategy`) or a rebind. A save
224
- is checked only on behalf of those agents: a strategy carries no lane of its own, so one with no agent
225
- the radar acts on is never checked, and the same strategy is legal, and reads session-field scalars
226
- correctly, on an arena agent. A refused compile issues no plan token, so nothing can stage that
227
- content.
225
+ strategy commit (`commit_strategy_draft`, the builder's Save, `restore_strategy`) or a rebind (the
226
+ agent draft's STRATEGY_BINDING commit). A commit is checked only on behalf of those agents: a
227
+ strategy carries no lane of its own, so one with no agent the radar acts on is never checked, and
228
+ the same strategy is legal, and reads session-field scalars correctly, on an arena agent. A draft
229
+ may hold such content — staging never refuses a draft for being invalid — but its commit is
230
+ refused, so it never reaches the agents.
228
231
 
229
232
  **The exit role.** `exit: true` makes a settled TRUE reading close open positions its verdict
230
233
  opposes — UP exits SHORTs, DOWN exits LONGs, a NEITHER or `null` verdict exits both. Legal only over
@@ -247,11 +250,15 @@ anchor, or the author gates on something that admits most bars.
247
250
 
248
251
  ## Entry
249
252
 
250
- `{ trigger, levelOffsetAtrMultiple, validForBars }` — all three required on every CREATE, no
251
- defaults. This axis is replaced WHOLE on save, so an omitted key would silently revert an author's
252
- discipline rather than be refused. There is no level-source key: the level a level trigger rests at
253
- is DERIVED from the trigger and the trade's direction, never named. There is no confirm-timeframe
254
- key either: the bar whose close decides an entry is the strategy's OWN timeframe.
253
+ `{ trigger, levelOffsetAtrMultiple, validForBars }` — the axis's keys, and the trigger decides
254
+ which of them you send. `ON_CANDLE_CLOSE` is sent ALONE, as `{ "trigger": "ON_CANDLE_CLOSE" }`: a
255
+ `levelOffsetAtrMultiple` or `validForBars` beside it is refused as an unrecognized key. A level
256
+ trigger — `STOP_THROUGH_LEVEL` or `ON_RETEST` — sends both of them, no defaults. The axis is staged
257
+ WHOLE, so a level trigger missing one is refused rather than half-kept. It is not required on every
258
+ CREATE: a CREATE that stages no entry takes the platform's seed entry, so stage it whenever the
259
+ setup names one. There is no level-source key: the level a level trigger rests at is DERIVED from
260
+ the trigger and the trade's direction, never named. There is no confirm-timeframe key either: the
261
+ bar whose close decides an entry is the strategy's OWN timeframe.
255
262
 
256
263
  **Every trigger is decided at the close of the strategy's own bar — there are three, and the close
257
264
  is the only entry clock.** The newest completed bar is read on the closed basis — every one-close
@@ -259,7 +266,7 @@ condition resolves on that bar and the scorecard reads its close — and a readi
259
266
  fires at that close. A bar that does not qualify decides nothing and is not revisited. The fill lands
260
267
  at the next tick, and the platform refuses it if the market has already run past its own drift budget
261
268
  from that close. A fourth value, `AT_SIGNAL`, is readable on strategies authored before this contract
262
- and is REFUSED on every save; there is no live-reading entry to author.
269
+ and is REFUSED on every stage and save; there is no live-reading entry to author.
263
270
 
264
271
  - `ON_CANDLE_CLOSE` — the entry is taken AT the qualifying close, at market.
265
272
  - `STOP_THROUGH_LEVEL` — at the qualifying close a TRIGGER order rests past the Donchian channel's
@@ -285,10 +292,11 @@ correct side of the mark when the order is placed — a buy stop above it, a buy
285
292
  mirror for a sell — or the entry is refused rather than filled at the market; there is no limit on
286
293
  how far from the mark a level may rest.
287
294
 
288
- **The legality matrix runs one way.** All three keys are always present, so the question is never
289
- "is it set" but "is it set to something that MEANS anything under this trigger".
290
- `levelOffsetAtrMultiple` ≠ 0 and `validForBars` ≠ 4 are refused under a non-level trigger. Leave a
291
- dial at its inert value rather than setting one the platform will ignore.
295
+ **The trigger decides the shape, so there is no inert dial to leave.** Under `ON_CANDLE_CLOSE` the
296
+ two parameters do not exist on the input — the server stores its seed values for them — while a
297
+ read (`get_strategy`) still shows all three keys. Switching a level trigger back to
298
+ `ON_CANDLE_CLOSE` is staging `{ "trigger": "ON_CANDLE_CLOSE" }` alone; never copy the read's
299
+ parameters back beside it.
292
300
 
293
301
  ## Report sections
294
302
 
@@ -301,7 +309,9 @@ author's value silently. On a CREATE, omit `sectionKey` — it is derived from t
301
309
  ## Signal rules
302
310
 
303
311
  `{ signalId, allocation, required, params }` — one entry per signal you want scoring.
304
- `allocation` is the tier (0–3) and `params` replaces canonical defaults only when present.
312
+ `allocation` is the tier (0–3) and `params` replaces canonical defaults only when present. Staged
313
+ into the draft's SIGNAL_RULES axis, every row is complete — `allocation` and `required` on each —
314
+ and replaces the drafted row for its signal while every other row is kept.
305
315
 
306
316
  ## Signal weights and gate math
307
317
 
@@ -315,7 +325,7 @@ Weights are relative — build a pyramid: 1–2 Critical (thesis, usually `requi
315
325
  Important (independent confirmation, different modules), 1–3 Normal (context), rest Off so
316
326
  noise cannot dilute the average. Gate check: with 3/2/2/1 weights, Critical + one Important at
317
327
  score 1.0 → (3+2)/8 = 0.625, so a 0.6 gate means "thesis plus one confirmation".
318
- `simulate_aggregate_score` does this arithmetic from compiled values at review time.
328
+ `simulate_aggregate_score` does this arithmetic from the draft's values at review time.
319
329
  `required: true` counts the signal toward `minRequiredCount` when triggered; at
320
330
  `allocation: 0` it is rejected (contract 34). `params` replace canonical defaults only when
321
331
  present — read `get_strategy_signal_definition({ signalId, timeframe })` before tuning (e.g.
@@ -103,8 +103,8 @@ giveback 30 buffer 0.15; timeDecay ON aggressive (45/15, 15→60, stale 30).
103
103
 
104
104
  Discover → confirm headers (`get_strategy_column_contract`, or one `preview_strategy_report`
105
105
  whose `conditionColumns` lists every addressable header with operators and vocabulary) →
106
- calibrate literals against the previewed live values → compile once → review the compiled
107
- scorecard, condition outcomes, verdict tally, and `marketReadMarkers` (fix `unknown` /
108
- `ambiguous` markers) → apply per the strategy-authoring flow. Coin selection is call context,
109
- not strategy state: explicit tickers for focused work, `ranked` (with an optional category) for
110
- scanning books.
106
+ calibrate literals against the previewed live values → stage the draft and fix what its
107
+ diagnostics name → read it back and review the drafted rule rows, then the draft's own report
108
+ preview — condition outcomes, verdict tally, and `marketReadMarkers` (fix `unknown` / `ambiguous`
109
+ markers) → commit per the strategy-authoring flow. Coin selection is call context, not strategy
110
+ state: explicit tickers for focused work, `ranked` (with an optional category) for scanning books.
@@ -5,7 +5,7 @@ coin-selection and discovery shapes an author reaches for while writing a payloa
5
5
 
6
6
  **Shapes are binding. Tokens are illustrations** — re-discover every metric, transform and parameter
7
7
  against the live tools (`list_strategy_categories`, `list_strategy_vocabulary`,
8
- `get_metric_construction_hints`, `get_strategy_column_contract`) before compiling. A recipe is a
8
+ `get_metric_construction_hints`, `get_strategy_column_contract`) before staging. A recipe is a
9
9
  worked shape, never a substitute for discovery.
10
10
 
11
11
  Read `## Header grammar` and `## Conditions` in the skill body first: how a column's header is
@@ -89,7 +89,8 @@ thing a crowded-positioning playbook trades against.
89
89
 
90
90
  ## Coin selection
91
91
 
92
- `coinSelection` is required on every compile and is discriminated on `mode`:
92
+ `coinSelection` is required on every `preview_strategy_report` call — it is the cohort the preview
93
+ renders over, never strategy state — and is discriminated on `mode`:
93
94
 
94
95
  ```json
95
96
  { "mode": "ranked", "limit": 25, "category": "DEFI" }