@battlegrid/mcp-server 31.2.62 → 31.2.64

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,109 @@ 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 — v84 (the hold moves from the condition to each clause and group)
28
+
29
+ **Breaking at v84: a condition body accepted at v83 is refused, and condition evidence is reshaped.**
30
+ v84 is the contract on top of v83.
31
+
32
+ How many completed bars a reading must hold is no longer one number on the condition. Each clause
33
+ holds its own reading, counted on its own column's timeframe, and a group can hold its members'
34
+ same-bar reading.
35
+
36
+ ### Rejected input — `compile_strategy_plan`, `apply_strategy_plan`
37
+
38
+ - **A condition no longer carries `closes`.** A condition entry naming it is refused with the
39
+ unknown-key error, in a plan body and in every normalized post-state and strategy draft those tools
40
+ carry.
41
+ - **Every clause and every group requires `hold: { atLeast, of }`**, whole numbers of at least 1.
42
+ `{ "atLeast": 1, "of": 1 }` is one read (what every v83 condition did), `{n, n}` is "n closes in a
43
+ row", `{1, n}` is "within n closes", and anything else is "at least m of n closes". A clause or group
44
+ without `hold` is refused. A plan staged under v83 must be recompiled.
45
+ - **What a header admits is refused by the builder, never by the schema.** `atLeast` above `of`, a
46
+ window above the header's maximum, or a group hold over members that hold their own bars is a typed
47
+ remediation error.
48
+
49
+ ### Replaced output — `preview_strategy_report`, `list_strategy_vocabulary`
50
+
51
+ - **`closesReadable: boolean` is replaced by `conditionHold: { timeframe, maxWindow, maxAtLeast,
52
+ refusal }`** on each report condition column and each scalar metric. It names the timeframe a
53
+ clause counts on, the largest `of` and `atLeast` it admits (`maxAtLeast` is 1 for a cross or other
54
+ event, so an event can only be held "within n closes"), and why it admits one bar when it does:
55
+ `NOT_REWINDABLE`, `DEVELOPING`, `OFFSET`, `BAR_STATE` or `HISTORY`. Read the window from here
56
+ rather than assuming a ceiling; there is no longer a fixed 1–5 limit.
57
+
58
+ ### Reshaped output — condition evidence
59
+
60
+ - **Every clause-evidence entry gains `hold`, `counts` and `decidedBar`**, on `preview_strategy_report`,
61
+ `list_gate_blocks`, `get_radar_close_decisions`, `get_agent_coin_qualification`,
62
+ `preview_radar_resolution` and `get_signal_log`. `counts` is `{ trueCount, total, unresolvedCount }`
63
+ over the clause's own bars. `decidedBar` is `{ timeframe, closesBack }`, the bar its operand was read
64
+ on, or `null` when the hold that counts it reads one bar.
65
+ - **A condition outcome loses `hold`** (`closesHeld`, `closesRequired`, `liveOutcome`, `nextCloseAt`):
66
+ the counted outcome is the clause's own, on its evidence. A decision record's condition
67
+ `declaration` loses `closes`.
68
+ - **Every strategy read returns `hold` on each clause and group** and no `closes` on the condition.
69
+
70
+ ### Widened enum — the evidence union
71
+
72
+ - **The evidence union gains a `group` arm**, `{ kind: 'group', op, hold, counts, decidedBar, outcome,
73
+ memberCount }`, emitted only for a group holding more than one bar, just before the `memberCount`
74
+ entries that belong to it. A client switching exhaustively on `kind` must add the branch. A strategy
75
+ without group holds serves no new arm.
76
+
77
+ A strict client that rejects unknown keys fails to parse condition evidence at v84; list the tools
78
+ again after the server deploys.
79
+
80
+ ## Contract history — v70.1 (budget run-state)
81
+
82
+ **Additive at v70.1: one output field added to the risk budget.**
83
+
84
+ ### Added output — `get_agent_budget`, `reset_agent_drawdown_baseline`
85
+
86
+ - **`budget.runStatus`** is your run-state for the agent: `blocked`, `paused` or `active`, already
87
+ ranked by the server. `blocked` means the admission gate is refusing the agent for a reason other
88
+ than its halt (`blockedReason` names it). A halted agent reads `paused`, even while its own
89
+ `AGENT_HALTED` block stands. Read it rather than re-deriving it from `blockedReason` and `haltedAt`.
90
+ - A client that ignores the field is unaffected. A client that validates results against a cached,
91
+ closed output schema should list the tools again after the server deploys.
92
+
93
+ ## Contract history — v83 (a model's vendor is its vendor slug)
94
+
95
+ **Breaking at v83: four output fields renamed and retyped, one aggregation regrouped.** v83 is the
96
+ contract on top of v82.
97
+
98
+ Wherever a model's vendor is published, it is now the router vendor slug of the model's id — the part
99
+ before the `/` (`anthropic`, `z-ai`, `moonshotai`, …). It is never the BYOK provider enum, and never the
100
+ catalogue's display label, which sometimes named a hosting provider rather than the model's maker.
101
+
102
+ ### Reshaped output — the agent
103
+
104
+ - **Every agent loses `provider` and gains `modelVendorSlug: string`**, on `list_intelligence_agents`,
105
+ `get_intelligence_agent`, `create_intelligence_agent`, `update_intelligence_agent`,
106
+ `rebind_intelligence_agent`, `archive_intelligence_agent` and `activate_intelligence_agent`.
107
+ `provider` was the BYOK enum and was `null` for every agent; `modelVendorSlug` is never null. A
108
+ client reading `provider` reads nothing at v83.
109
+
110
+ ### Renamed output — `list_approved_models`
111
+
112
+ - **Each model's `provider` is renamed `vendorSlug`**, and its value changes: the vendor slug
113
+ (`z-ai`) where v82 served a display label that could name a host (`StreamLake`).
114
+
115
+ ### Renamed output, regrouped rows — `get_agent_explorer`
116
+
117
+ - **Each `modelVendors[]` row's `provider` / `providerImageUrl` are renamed `vendorSlug` /
118
+ `vendorImageUrl`.**
119
+ - **Rows group by vendor slug**, so every model one vendor makes shares a row whatever its display
120
+ label: three GLM labels that were three rows at v82 are one `z-ai` row at v83. Counts and sums add;
121
+ each mean is the merged total over the merged trade count.
122
+
123
+ ### Renamed output — the `ownerView` LLM-call envelope
124
+
125
+ - **The envelope's `provider` is renamed `modelVendorSlug`**, on `get_agent_journal`, `get_signal_log`,
126
+ `get_agent_game_history`, `get_user_agent_game_history`, `get_public_agent_signal_log_detail` and
127
+ `get_public_agent_game_history`. It is `null` exactly when `modelDisplayName` is — a call whose model
128
+ has left the catalogue.
129
+
27
130
  ## Contract history — v82 (approved models lose their pin flag)
28
131
 
29
132
  **Breaking at v82: one output field removed.** v82 is the contract on top of v81.
@@ -970,7 +1073,8 @@ preview names it.
970
1073
 
971
1074
  - **`scalarFamilies` is where the vocabulary went.** Every report-level scalar family with its
972
1075
  section, and one entry per METRIC carrying its gloss, legal condition operators, closed label
973
- vocabulary, read contract (`closesReadable` / `developingRead`) and the scopes it is measured at.
1076
+ vocabulary, read contract (`closesReadable` / `developingRead`; v84 replaces `closesReadable` with
1077
+ `conditionHold`) and the scopes it is measured at.
974
1078
  One gloss per metric with its scopes named against it, never one per pair.
975
1079
 
976
1080
  - **Served whole under every category.** A scalar describes the report, not a metric family, so it
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.62";
52
+ export declare const PACKAGE_VERSION = "31.2.64";
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.62';
55
+ export const PACKAGE_VERSION = '31.2.64';
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.62",
3
+ "version": "31.2.64",
4
4
  "description": "BattleGrid MCP server — play crypto prediction games from AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "generator": "battlegrid-app/server/scripts/export-mcp-skills.mjs",
3
- "contractVersion": "76.0.0",
3
+ "contractVersion": "84.0.0",
4
4
  "files": {
5
5
  "battlegrid-agent-management/SKILL.md": "5ea8384ff76ccb9fdf00e4ec8b584f88fdba6d1c9d5679ce0b7380c23bfbaab1",
6
6
  "battlegrid-arena-play/SKILL.md": "4cfaa92a8d0dcaf477b227abd774e7aa8642c185d72108dfd401be0cf8aecd7f",
7
7
  "battlegrid-market-analysis/SKILL.md": "22fde9c4eac0261c89a8056ab8b20b66fcbe1fd58447fa0ac84fd410b4d134d7",
8
8
  "battlegrid-radar-deployment/SKILL.md": "17301fa66f4b128154435462ffa967efcb3d016df671b03c485d0f8b840fc891",
9
- "battlegrid-strategy-authoring/SKILL.md": "95e91dd1ff36922b7ed0f5eb92c98def98fa39cce37c3d7447269aea1b5a017f",
9
+ "battlegrid-strategy-authoring/SKILL.md": "6aa3a04fd4f0624a671d70aead009f4943db1ffa34402e403b588dd998e828c9",
10
10
  "battlegrid-strategy-doctor/SKILL.md": "a3446f24059be72ae797ba4e9669848d851ac3dc38675923fe3d307f557eb82f",
11
- "battlegrid-strategy-examples/SKILL.md": "a60b766de81f859f2fa9b352d65937b6a6f3eb24c4e88a064123a4985906bce5",
11
+ "battlegrid-strategy-examples/SKILL.md": "534c053e75021b6954e2365dbec4893ed9fc807a064a922f47f2d34a4e528221",
12
12
  "battlegrid-strategy-examples/references/playbooks.md": "02168e3af35268a30fd156f3337d25fe15e6df67da1592f4cb4d31090be3f94f",
13
13
  "battlegrid-strategy-examples/references/recipes.md": "53887daece17995543e7d3fe1bf2577fc41a6254c291acacde48d7de63853641",
14
14
  "battlegrid-strategy-examples/references/tradingview-ports.md": "2b13adbc137178955edcca31b6ab40c01c745a932a0750b91db8820c736700bb",
15
- "battlegrid-trade-analysis/SKILL.md": "f49482702f17d7fc44db00c31a19fc6e9350668fe76e8948d22faaa9c7e9d6bf",
15
+ "battlegrid-trade-analysis/SKILL.md": "f5d817022ab912f00e9c17ffa720a7599f6e6fa4b806d873fe5e7520c51a8dcd",
16
16
  "battlegrid-trade-proposal/SKILL.md": "9bf7b7648fb009db118a3a428b15abf38df5ba56a2ef4c8a4eae3d979bdc8bcb"
17
17
  }
18
18
  }
@@ -115,10 +115,13 @@ question you would otherwise guess — and a refusal you would otherwise earn:
115
115
  - **The `entry` axis is required on every CREATE**, all three keys, no defaults — `trigger`,
116
116
  `levelOffsetAtrMultiple`, `validForBars`. Every trigger is decided at the close of the strategy's
117
117
  OWN bar, so there is no confirm-timeframe key; for the level triggers the level itself is derived
118
- from the trigger and the trade's direction, never named. A multi-bar hold belongs to the condition
119
- that needs it (its own `closes`, counted in completed strategy bars), not to this axis. The
120
- `strategy-examples` skill carries the vocabulary, the hold's legality and the per-column
121
- Confirmed / Developing read; a CREATE without it is refused outright.
118
+ from the trigger and the trade's direction, never named. A multi-bar hold belongs to the clause
119
+ or group that needs it — its own `hold: { atLeast, of }`, which the editor calls **Hold** (Once,
120
+ In a row, Within, At least), counted in completed bars of the column's own timeframe — not to this
121
+ axis. Every clause and group carries `hold`; `{ "atLeast": 1, "of": 1 }` is Once. The
122
+ `strategy-examples` skill carries the vocabulary, the served hold domain (a crossover is held
123
+ "within" only; a Developing column cannot be held) and the per-column Confirmed / Developing read;
124
+ a CREATE without it is refused outright.
122
125
  - `get_strategy_column_contract` → `outputs[].conditionOperators`. An empty array means that
123
126
  rendered header has no comparison semantics and cannot appear in a condition clause at all.
124
127
  Legality is per rendered header, not per column: a trajectory's slot header and its `_trend`
@@ -86,12 +86,15 @@ against a literal; neither of those shapes is what a previous-session level need
86
86
 
87
87
  ## Conditions
88
88
 
89
- `{ conditionKey, name, definition, verdict, required, exit, closes }` — all seven
90
- required, no defaults. A `clock` key is REFUSED: the per-condition evidence clock was retired in
91
- contract `61.0.0`. Clauses: numeric/rank headers take `lt|lte|gte|gt|between`;
89
+ `{ conditionKey, name, definition, verdict, required, exit }` — all six
90
+ required, no defaults. A `clock` key is REFUSED (the per-condition evidence clock was retired in
91
+ contract `61.0.0`), and so is a condition-level `closes` key: the hold lives on each clause and each
92
+ group (contract `84.0.0`). Clauses: numeric/rank headers take `lt|lte|gte|gt|between`;
92
93
  classification/direction headers take `is|in` with the served vocabulary. Groups:
93
- `ALL | ANY | NOT | N_OF` (with `n`), depth ≤ 2. `conditionRef` composes named conditions (no
94
- cycles; forward refs legal). `sectionKey: null` is sugar for a report-unique header only.
94
+ `ALL | ANY | NOT | N_OF` (with `n`), depth ≤ 2. Every clause and every group carries a required
95
+ `hold: { atLeast, of }` — `{ "atLeast": 1, "of": 1 }` is a single read; a clause or group without
96
+ `hold` is refused (`CONDITION_HOLD_INVALID`). `conditionRef` composes named conditions (no
97
+ cycles; forward refs legal) and carries no hold of its own. `sectionKey: null` is sugar for a report-unique header only.
95
98
  Verdicts: resolution is taken over the DISTINCT verdicts of the carriers that read TRUE. One
96
99
  distinct verdict decides, and the first carrier in declaration order carrying it is named as the
97
100
  decider — so order breaks ties between carriers that AGREE. Carriers that DISAGREE resolve
@@ -121,19 +124,55 @@ bar a condition reads is decided by the surface asking — a decision (the radar
121
124
  compose that takes the trade, the exit sweep) reads completed strategy bars; a display read shows the
122
125
  forming one and decides nothing — and by each candle column's own Confirmed / Developing selector.
123
126
 
124
- **The hold count.** `closes` is how many consecutive COMPLETED strategy bars must read TRUE (1–5). A
125
- hold counts the same completed bars whichever surface asks, so a held condition reads them on the
126
- display lane too. Above `1` it is legal **only** where a completed bar changes the reading: over a
127
- header resolved from this coin's own candle series, at offset 0, at or above the strategy timeframe,
128
- read Confirmed. Everything else is refused (`CONDITION_HOLD_OPERAND_ILLEGAL`) — perp-payload scalars,
129
- published rolling changes, ranks, zone entities, MDS regime labels, enrichment metrics, session
130
- scalars, a non-zero offset, a column BELOW the strategy timeframe (the retained lower series cannot
131
- reach an earlier strategy close), and a developing read (the bar in progress exists on the newest
132
- frame only). A hold also needs a clause of the condition's OWN
133
- (`CONDITION_HOLD_ILLEGAL`): a referenced condition is resolved once and contributes the same answer
134
- to every frame, so a hold that moves with the bar only through a reference would count reads that
135
- never happened. **Worked liquidity floor:** `LIQUID_FLOOR` holds one close because `vol24hUsd` is a
136
- bundle scalar. Reach for a split to keep a condition's MEANING separable, not to buy it a hold.
127
+ **Hold — how many closes a clause counts.** A clause's `hold: { atLeast, of }` reads TRUE when the
128
+ clause read TRUE on at least `atLeast` of its newest `of` COMPLETED bars — counted on the clause's
129
+ OWN column timeframe, not the strategy's: a `4h` column on a `1h` strategy held 3 reads three `4h`
130
+ bars. The editor calls the control **Hold** and offers four modes:
131
+
132
+ | Mode | Hold | Reads as |
133
+ |---|---|---|
134
+ | Once | `{ 1, 1 }` | a single read of the bar being decided |
135
+ | In a row | `{ n, n }` | "3 closes in a row" |
136
+ | Within | `{ 1, n }` | "within 5 closes" |
137
+ | At least | `{ m, n }` | "at least 2 of 5 closes" |
138
+
139
+ A hold counts the same completed bars whichever surface asks. Each bar is read or unreadable; an
140
+ unreadable bar is never replaced by an older one, and the count decides as soon as the bars read
141
+ decide it (TRUE once `atLeast` bars read TRUE, FALSE once the rest can no longer reach it), else
142
+ UNRESOLVED.
143
+
144
+ What a header admits is SERVED, never guessed: every column in the strategy's report catalog
145
+ (`preview_strategy_report` → `conditionColumns[].outputs[].conditionHold`, and each scalar metric in
146
+ the vocabulary) carries `{ timeframe, maxWindow, maxAtLeast, refusal }` — the timeframe it counts,
147
+ the largest `of`, the largest `atLeast`, and, when it admits only Once, why. `maxWindow` is the
148
+ history the store keeps for that column, less the column's own lookback and warm-up. A hold past
149
+ the served domain is refused (`CONDITION_HOLD_ILLEGAL`, the domain in `allowedDomain`). The reasons
150
+ a header admits only Once:
151
+
152
+ - `NOT_REWINDABLE` — the value is stored for the current bar only (session and universe scalars,
153
+ ranks, zone entities, enrichment metrics, published rolling changes). **Worked liquidity floor:**
154
+ `LIQUID_FLOOR` holds Once because `vol24hUsd` is a bundle scalar.
155
+ - `DEVELOPING` — the column reads the bar still forming. **Developing columns cannot be held**; set
156
+ the column Confirmed to count closes.
157
+ - `OFFSET` — the column already reads an earlier bar; remove the offset to count closes.
158
+ - `BAR_STATE` — the header describes only the bar being decided.
159
+ - `HISTORY` — not enough history is stored on that timeframe to count more than one close.
160
+
161
+ Candle columns (at, above or below the strategy timeframe), the regime (counted on the regime rung),
162
+ and the funding and open-interest histories (on the coarser of the strategy timeframe and their own
163
+ hourly cadence) can all be held. **A crossover is an event**: it fires on the bar a state changes,
164
+ so its `maxAtLeast` is 1 — hold a cross "within n closes", never "in a row".
165
+
166
+ **Group hold — closes counted together.** A group's `hold` counts its members' joint reading on the
167
+ same bar: the group's own outcome, its members folded by its operator, must read TRUE on at least
168
+ `atLeast` of its newest `of` bars, counted on its finest member's timeframe. The phrases add
169
+ "together": "together on 3 closes in a row", "together within 5 closes", "together on at least 2 of
170
+ 5 closes". Inside a group holding more than Once, every member holds Once and none is a
171
+ `conditionRef` — each read is counted by exactly one hold — so a row holding its own closes, a
172
+ reference, or a held group inside is refused, naming the member. A conjunction that needs a
173
+ crossover to be TRUE (`ALL(cross, x)`) admits "within" only. Reach for a split to keep a condition's
174
+ MEANING separable; a reference carries its condition's one answer for the bar being decided and is
175
+ never counted across closes.
137
176
 
138
177
  **Confirmed / Developing, per candle column.** Every transform whose home is the coin's candle series
139
178
  carries `bars`: `"closed"` is Confirmed — the newest bar completed at the strategy close — and
@@ -142,18 +181,18 @@ it completes. Left unset the default is a rule, not a value: Confirmed for a col
142
181
  strategy timeframe, and at or below it the series as the frame carries it. At or below the strategy
143
182
  timeframe the choice therefore sets only what the live lane shows — no bar is in progress at the
144
183
  anchor's own close — so Developing there is legal and changes no decision. A condition reading a
145
- developing bar is single-frame: it holds one close, carries no verdict and cannot take the `exit`
146
- role. One exception overrides both the stored value and the default: a column reading a metric with
184
+ developing bar is single-frame: its clause holds Once (a Developing column cannot be held), it
185
+ carries no verdict and it cannot take the `exit` role. One exception overrides both the stored value and the default: a column reading a metric with
147
186
  no live value (itself, or a `spread` operand) reads completed bars at every rung, because the forming
148
187
  bar publishes nothing for it. The resolved answer for a column is served on
149
188
  `effectiveParameters.bars`, and it states that exception.
150
189
 
151
190
  **A higher-timeframe level is measured from the current strategy-bar price.** The distance to a `4h`
152
191
  Donchian band, and every candle label classifier (`MA_ALIGN`, `PRICE_ZONE`, `BB_TOUCH`), compares
153
- against the frame's current price — the strategy bar's close under a decision, the live mark on
154
- display — not against the higher-timeframe bar's own close, which is up to one higher-timeframe bar
155
- stale. A distance CHAINED into a series transform keeps every slot on its own bar's close, so one
156
- series carries one reference basis.
192
+ against the frame's current price, `LAST` — the strategy bar's close under a decision, the last
193
+ traded price on display — not against the higher-timeframe bar's own close, which is up to one
194
+ higher-timeframe bar stale. A distance CHAINED into a series transform keeps every slot on its own
195
+ bar's close, so one series carries one reference basis.
157
196
 
158
197
  **The lane a strategy is deployed to.** Report-level scalars split by LANE, and the split is not a
159
198
  quality of the header — it is which reader runs. Market breadth and the reference pairs are ordinary
@@ -232,8 +271,8 @@ and is REFUSED on every save; there is no live-reading entry to author.
232
271
  short) by the offset, waiting for a return to it. Not filling is a correct outcome, not a
233
272
  failure; no unrecovered break in memory means no setup, never a fallback level.
234
273
 
235
- **A multi-bar hold belongs to the CONDITION that needs it.** Declare that condition's own `closes` —
236
- the entry axis counts no bars, and there is no displacement band: the
274
+ **A multi-bar hold belongs to the CLAUSE (or group) that needs it.** Declare that clause's own
275
+ `hold` — "3 closes in a row", "within 5 closes" — the entry axis counts no bars, and there is no displacement band: the
237
276
  platform's entry-deviation gate measures the live mark against the decided close and refuses a fill
238
277
  that drifted past the budget in either direction.
239
278
 
@@ -14,7 +14,7 @@ Start with where the money is, always, even when the question is narrower — a
14
14
  means nothing without the whole.
15
15
 
16
16
  - `get_account_state` for the account total.
17
- - `get_agent_fund_allocation` and `get_agent_budget` for what is committed per agent.
17
+ - `get_agent_budget` for each agent's capital at risk, and `get_agent_fund_allocation` for its funding envelope.
18
18
 
19
19
  Then state a **reconciliation line**: the account total against the sum of its parts. If they
20
20
  agree, say they agree. **If they do not, state the gap as a gap** — name the amount and say you