dexbot 1.6.5 → 1.6.6
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/CHANGELOG.md +36 -4
- package/README.md +104 -35
- package/analysis/README.md +11 -16
- package/analysis/account_resolver.ts +1 -11
- package/analysis/bot_usage/kibana_bot_queries.ts +1 -1
- package/analysis/chain_pool.ts +1 -1
- package/analysis/fills_source.ts +0 -6
- package/analysis/grid_correction_check.ts +20 -26
- package/analysis/resolve_source.ts +1 -1
- package/analysis/trade_profitability.ts +2 -5
- package/analysis/trend_detection/README.md +1 -3
- package/analysis/trend_detection/package.json +1 -1
- package/claw/package.json +1 -1
- package/claw/runtimes/openclaw-plugin/openclaw.plugin.json +1 -1
- package/claw/runtimes/openclaw-plugin/package.json +1 -1
- package/claw/tests/test_claw_mcp_transport.ts +2 -2
- package/dist/analysis/account_resolver.d.ts +1 -4
- package/dist/analysis/account_resolver.d.ts.map +1 -1
- package/dist/analysis/account_resolver.js +1 -1
- package/dist/analysis/account_resolver.js.map +1 -1
- package/dist/analysis/bot_usage/kibana_bot_queries.d.ts +1 -2
- package/dist/analysis/bot_usage/kibana_bot_queries.d.ts.map +1 -1
- package/dist/analysis/bot_usage/kibana_bot_queries.js +1 -1
- package/dist/analysis/bot_usage/kibana_bot_queries.js.map +1 -1
- package/dist/analysis/chain_pool.d.ts +1 -3
- package/dist/analysis/chain_pool.d.ts.map +1 -1
- package/dist/analysis/chain_pool.js +1 -1
- package/dist/analysis/chain_pool.js.map +1 -1
- package/dist/analysis/fills_source.d.ts +1 -51
- package/dist/analysis/fills_source.d.ts.map +1 -1
- package/dist/analysis/fills_source.js +1 -1
- package/dist/analysis/fills_source.js.map +1 -1
- package/dist/analysis/grid_correction_check.d.ts +2 -3
- package/dist/analysis/grid_correction_check.d.ts.map +1 -1
- package/dist/analysis/grid_correction_check.js +18 -26
- package/dist/analysis/grid_correction_check.js.map +1 -1
- package/dist/analysis/resolve_source.d.ts +1 -1
- package/dist/analysis/resolve_source.d.ts.map +1 -1
- package/dist/analysis/trade_profitability.d.ts.map +1 -1
- package/dist/analysis/trade_profitability.js +2 -7
- package/dist/analysis/trade_profitability.js.map +1 -1
- package/dist/dexbot.d.ts.map +1 -1
- package/dist/dexbot.js +60 -74
- package/dist/dexbot.js.map +1 -1
- package/dist/market_adapter/core/kibana_candles.d.ts +1 -15
- package/dist/market_adapter/core/kibana_candles.d.ts.map +1 -1
- package/dist/market_adapter/core/kibana_candles.js +1 -1
- package/dist/market_adapter/core/kibana_candles.js.map +1 -1
- package/dist/market_adapter/inputs/fetch_lp_data.d.ts +1 -35
- package/dist/market_adapter/inputs/fetch_lp_data.d.ts.map +1 -1
- package/dist/market_adapter/inputs/fetch_lp_data.js +10 -54
- package/dist/market_adapter/inputs/fetch_lp_data.js.map +1 -1
- package/dist/market_adapter/inputs/kibana_feed_source.d.ts +1 -8
- package/dist/market_adapter/inputs/kibana_feed_source.d.ts.map +1 -1
- package/dist/market_adapter/inputs/kibana_feed_source.js +1 -1
- package/dist/market_adapter/inputs/kibana_feed_source.js.map +1 -1
- package/dist/market_adapter/inputs/window_cache.d.ts +2 -63
- package/dist/market_adapter/inputs/window_cache.d.ts.map +1 -1
- package/dist/market_adapter/inputs/window_cache.js +22 -102
- package/dist/market_adapter/inputs/window_cache.js.map +1 -1
- package/dist/modules/account_bots.d.ts +16 -2
- package/dist/modules/account_bots.d.ts.map +1 -1
- package/dist/modules/account_bots.js +107 -44
- package/dist/modules/account_bots.js.map +1 -1
- package/dist/modules/bitshares-native/crypto/ecc.browser.d.ts.map +1 -1
- package/dist/modules/bitshares-native/crypto/ecc.browser.js +0 -31
- package/dist/modules/bitshares-native/crypto/ecc.browser.js.map +1 -1
- package/dist/modules/credit_runtime.d.ts +0 -2
- package/dist/modules/credit_runtime.d.ts.map +1 -1
- package/dist/modules/credit_runtime.js +1 -10
- package/dist/modules/credit_runtime.js.map +1 -1
- package/dist/modules/dexbot_class.d.ts +13 -10
- package/dist/modules/dexbot_class.d.ts.map +1 -1
- package/dist/modules/dexbot_class.js +0 -9
- package/dist/modules/dexbot_class.js.map +1 -1
- package/dist/modules/dexbot_cow_runtime.d.ts +13 -0
- package/dist/modules/dexbot_cow_runtime.d.ts.map +1 -1
- package/dist/modules/dexbot_cow_runtime.js +13 -1
- package/dist/modules/dexbot_cow_runtime.js.map +1 -1
- package/dist/modules/order/accounting.d.ts +4 -18
- package/dist/modules/order/accounting.d.ts.map +1 -1
- package/dist/modules/order/accounting.js +4 -34
- package/dist/modules/order/accounting.js.map +1 -1
- package/dist/modules/order/export.d.ts +9 -12
- package/dist/modules/order/export.d.ts.map +1 -1
- package/dist/modules/order/export.js +9 -12
- package/dist/modules/order/export.js.map +1 -1
- package/dist/modules/order/grid.d.ts +35 -40
- package/dist/modules/order/grid.d.ts.map +1 -1
- package/dist/modules/order/grid.js +43 -43
- package/dist/modules/order/grid.js.map +1 -1
- package/dist/modules/order/grid_reconcile.d.ts.map +1 -1
- package/dist/modules/order/grid_reconcile.js +111 -20
- package/dist/modules/order/grid_reconcile.js.map +1 -1
- package/dist/modules/order/grid_reconcile_internal.d.ts +5 -3
- package/dist/modules/order/grid_reconcile_internal.d.ts.map +1 -1
- package/dist/modules/order/grid_reconcile_internal.js +18 -3
- package/dist/modules/order/grid_reconcile_internal.js.map +1 -1
- package/dist/modules/order/manager.d.ts +0 -8
- package/dist/modules/order/manager.d.ts.map +1 -1
- package/dist/modules/order/manager.js +0 -10
- package/dist/modules/order/manager.js.map +1 -1
- package/dist/modules/order/utils/order.d.ts +22 -7
- package/dist/modules/order/utils/order.d.ts.map +1 -1
- package/dist/modules/order/utils/order.js +103 -21
- package/dist/modules/order/utils/order.js.map +1 -1
- package/dist/modules/order/utils/withPoolRef.d.ts +12 -0
- package/dist/modules/order/utils/withPoolRef.d.ts.map +1 -1
- package/dist/modules/order/utils/withPoolRef.js +17 -0
- package/dist/modules/order/utils/withPoolRef.js.map +1 -1
- package/dist/modules/order/working_grid.d.ts +8 -13
- package/dist/modules/order/working_grid.d.ts.map +1 -1
- package/dist/modules/order/working_grid.js +8 -29
- package/dist/modules/order/working_grid.js.map +1 -1
- package/dist/scripts/sync-version.js +0 -22
- package/dist/scripts/sync-version.js.map +1 -1
- package/dist/scripts/update_dist_freshness.d.ts +12 -0
- package/dist/scripts/update_dist_freshness.d.ts.map +1 -1
- package/dist/scripts/update_dist_freshness.js +30 -1
- package/dist/scripts/update_dist_freshness.js.map +1 -1
- package/docs/BITSHARES_ONBOARDING.md +9 -6
- package/docs/COW_INVARIANTS.md +1 -0
- package/docs/DEXBOT_COMPARISON.md +11 -11
- package/docs/EVOLUTION.md +8 -7
- package/docs/FUND_MOVEMENT_AND_ACCOUNTING.md +1 -1
- package/docs/GRID_PRICE_INVARIANT.md +518 -0
- package/docs/GRID_RECALCULATION.md +1 -1
- package/docs/GRID_RECONCILE.md +60 -39
- package/docs/ORDER_ENGINE_POST_1.0_RETROSPECTIVE.md +556 -0
- package/docs/README.md +3 -3
- package/docs/WORKFLOW.md +12 -6
- package/docs/architecture.md +40 -38
- package/docs/developer_guide.md +4 -8
- package/market_adapter/README.md +16 -12
- package/modules/README.md +1 -1
- package/package.json +7 -3
- package/scripts/README.md +0 -9
- package/scripts/reset-settings.sh +1 -1
- package/analysis/ama_fitting/package.json +0 -12
- package/analysis/analyze_derivatives.ts +0 -320
- package/analysis/derivative_chart_generator.ts +0 -874
- package/analysis/trend_detection/SIGNAL_DOCUMENTATION.md +0 -403
- package/analysis/trend_detection/derivative_analyzer.ts +0 -1059
- package/dist/analysis/analyze_derivatives.d.ts +0 -68
- package/dist/analysis/analyze_derivatives.d.ts.map +0 -1
- package/dist/analysis/analyze_derivatives.js +0 -287
- package/dist/analysis/analyze_derivatives.js.map +0 -1
- package/dist/analysis/derivative_chart_generator.d.ts +0 -12
- package/dist/analysis/derivative_chart_generator.d.ts.map +0 -1
- package/dist/analysis/derivative_chart_generator.js +0 -891
- package/dist/analysis/derivative_chart_generator.js.map +0 -1
- package/dist/analysis/trend_detection/derivative_analyzer.d.ts +0 -248
- package/dist/analysis/trend_detection/derivative_analyzer.d.ts.map +0 -1
- package/dist/analysis/trend_detection/derivative_analyzer.js +0 -910
- package/dist/analysis/trend_detection/derivative_analyzer.js.map +0 -1
package/docs/GRID_RECONCILE.md
CHANGED
|
@@ -22,7 +22,7 @@ Reconciliation aligns the bot's model with on-chain reality. It runs at startup
|
|
|
22
22
|
|
|
23
23
|
The reconcile runs from [`recalculateGrid`](../modules/order/grid.ts) during startup full-resync. **There is no per-attempt wall-clock race around the reconcile itself** — an outer timeout would fire mid-batch and orphan in-flight broadcasts (the duplicate-accumulation death spiral). The reconcile is bounded only by the 10-minute total resync safety net, and every internal chain read follows the shared guarded-read standard.
|
|
24
24
|
|
|
25
|
-
Phase 1 does all reasoning in memory under `_gridLock` (fast); Phases 2 and 3 execute outside
|
|
25
|
+
Phase 1 does all reasoning in memory under `_gridLock` (fast); Phases 2 and 3 execute outside that planning lock — holding it across RPC calls would block fills, sync, and divergence checks. Phase 2 holds the broadcasting single-flight marker, while the sync/apply paths it invokes follow the canonical lock hierarchy. No planning-phase grid lock spans a network operation.
|
|
26
26
|
|
|
27
27
|
Phase 2 and 3 both respect the `dryRun` flag: when true, no on-chain mutations are attempted — plans are logged but not executed.
|
|
28
28
|
|
|
@@ -52,8 +52,8 @@ Phase 2 and 3 both respect the `dryRun` flag: when true, no on-chain mutations a
|
|
|
52
52
|
┌──────────────────────────────────────────────────┐
|
|
53
53
|
│ PHASE 2: Execution (outside _gridLock) │
|
|
54
54
|
│ │
|
|
55
|
-
│ 1. Cancellations —
|
|
56
|
-
│
|
|
55
|
+
│ 1. Cancellations — revalidate each plan against │
|
|
56
|
+
│ live ownership, geometry, and chain state │
|
|
57
57
|
│ 2. Updates — batch (3 retries), then sequential │
|
|
58
58
|
│ fallback with per-failure recovery sync │
|
|
59
59
|
│ 3. Creates — outside-in pairing (outermost grid │
|
|
@@ -78,7 +78,7 @@ Phase 2 and 3 both respect the `dryRun` flag: when true, no on-chain mutations a
|
|
|
78
78
|
|
|
79
79
|
### Phase 1 — Pure Planning Under `_gridLock`
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
**Source:** `reconcileGridOrders()` Phase 1 in `grid_reconcile.ts`.
|
|
82
82
|
|
|
83
83
|
1. **Phantom order sanitization** (lines 216-245): For each `isOrderPlaced()` order whose `orderId` is not in the chain snapshot, reset it to VIRTUAL with `skipAccounting` to prevent fund inflation. Two absence-decision guards make this safe:
|
|
84
84
|
- **Freshly-assigned deferral** (lines 226-235): an `orderId` assigned within `TIMING.SYNC_LOCK_TIMEOUT_MS` (via `manager._orderIdAssignedAt`) may be an in-flight create/adopt whose broadcast has not landed or is not yet visible to a lagging/truncated read — virtualizing it and re-creating would duplicate a real live order (the reconcile-timeout death-spiral root cause). It is skipped (deferred) rather than virtualized.
|
|
@@ -101,29 +101,52 @@ Returns `{ plannedCreates, plannedUpdates, plannedCancels, chainSellCount, chain
|
|
|
101
101
|
|
|
102
102
|
### Phase 2 — Blockchain Execution Outside Lock
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
**Source:** `reconcileGridOrders()` Phase 2 in `grid_reconcile.ts`.
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
Phase 1 releases `_gridLock` before network I/O. Phase 2 runs under the
|
|
107
|
+
broadcasting single-flight marker so a fill-driven COW rebalance cannot plan the
|
|
108
|
+
same slots concurrently; individual sync/apply paths follow the canonical lock
|
|
109
|
+
hierarchy. No planning-phase `_gridLock` is held across RPC calls.
|
|
107
110
|
|
|
108
|
-
**Cancellations
|
|
111
|
+
**Cancellations — v1.6.6 stale-plan guard:** Before submitting any
|
|
112
|
+
`plannedCancels`, reconcile performs one guarded pre-cancel read and builds a
|
|
113
|
+
per-order signature (type, price, size) from both the Phase-1 and current
|
|
114
|
+
snapshots. For every plan, `_startupCancelPlanStillCurrent()` requires:
|
|
109
115
|
|
|
110
|
-
|
|
116
|
+
- the target chain order still exists with its exact Phase-1 signature;
|
|
117
|
+
- a matched plan still owns the same chain order in the same live grid slot;
|
|
118
|
+
- planned type, slot price, boundary, and gap geometry still match; and
|
|
119
|
+
- an originally unmatched surplus is still not owned by any live slot.
|
|
120
|
+
|
|
121
|
+
Validation is per-plan: an earlier cancellation or unrelated order change does
|
|
122
|
+
not invalidate an otherwise untouched plan. A truncated or failed pre-cancel
|
|
123
|
+
read skips all cancellation submissions. A complete empty read is authoritative
|
|
124
|
+
but likewise causes no plans to execute because no target remains present.
|
|
125
|
+
This closes stale-cancellation replays without requiring the whole book to
|
|
126
|
+
remain unchanged.
|
|
127
|
+
|
|
128
|
+
Surplus settlement uses the same live-ownership decision. Only an order that is
|
|
129
|
+
still untracked and signature-unchanged reaches `_cancelChainOrder`; a now-owned
|
|
130
|
+
or geometry-changed order is skipped rather than released from the stale
|
|
131
|
+
snapshot.
|
|
132
|
+
|
|
133
|
+
**Updates:**
|
|
111
134
|
- Batch via `_executeStartupUpdateBatch` when `supportsBatchUpdate` is available
|
|
112
135
|
- Retry up to 3× (`maxBatchAttempts = 3`)
|
|
113
136
|
- On each failure: `_recoverStartupSyncFailure()` re-fetches open orders from chain (guarded read) and re-syncs `manager` state via `manager.syncFromOpenOrders()`, then `_refreshStartupUpdatePlans()` rebuilds plans against the fresh chain state
|
|
114
|
-
- If retries exhausted or batch helpers are unavailable → `_executeStartupSequentialUpdateFallback()` one-by-one with per-failure recovery
|
|
137
|
+
- If retries are exhausted or batch helpers are unavailable → `_executeStartupSequentialUpdateFallback()` one-by-one with per-failure recovery
|
|
115
138
|
|
|
116
|
-
**Creates
|
|
139
|
+
**Creates:** `_executePlannedStartupCreates` groups the outermost grid slots toward the center (BUY descending / SELL ascending), so the most price-critical orders are placed first. BitShares DEX batch-create operations are used where supported. Every created chain ID is captured into `phase2CreatedOrderIds` so Phase 3 cannot later cancel the freshly-created orders.
|
|
117
140
|
|
|
118
141
|
### Phase 3 — Fresh Re-read, Adoption, Stale Surplus Cleanup
|
|
119
142
|
|
|
120
|
-
|
|
143
|
+
**Source:** Phase 3 in `reconcileGridOrders()` (guarded by `if (!dryRun)`).
|
|
121
144
|
|
|
122
|
-
1. **Guarded fresh re-read
|
|
145
|
+
1. **Guarded fresh re-read:** `readOpenOrdersGuarded` re-fetches all open orders. A truncated result returns `null` and Phase 3 defers, keeping the pre-Phase-2 counts for the summary log; a capped window omits exactly the freshest Phase-2 creates.
|
|
123
146
|
|
|
124
|
-
2. **Adopt uncertain-landed creates
|
|
147
|
+
2. **Adopt uncertain-landed creates:** For any fresh chain order not matching a grid `orderId` and not created by a slot, it attempts targeted slot adoption — matching a VIRTUAL slot by type+price+size (within tolerance) and registering it via `_applySync(..., 'createOrder')` with the create-fee deduction. Full `syncFromOpenOrders` is deliberately **not** used here (its pass-1 virtualizes ACTIVE slots missing from the snapshot, and a lagging read right after the Phase-2 broadcast would destroy the confirmed grid). If adoption fails, the ID is still protected from surplus-cancel; the next sync loop's orphan adoption registers it.
|
|
125
148
|
|
|
126
|
-
3. **Stale surplus cancellation
|
|
149
|
+
3. **Stale surplus cancellation:** Per side, count orders exceeding `targetCount` that no grid slot holds via `orderId` (including the Phase-2 created IDs). Cancel only these untracked surplus orders, sorted by chain ID for determinism. This catches orphans lost during grid reinitialization — on-chain orders with no corresponding grid slot.
|
|
127
150
|
|
|
128
151
|
### Partial Failure State
|
|
129
152
|
|
|
@@ -132,8 +155,8 @@ If Phase 2 partially succeeds (some cancels, some creates fail), there is no rol
|
|
|
132
155
|
### Timeouts and Read Coverage
|
|
133
156
|
|
|
134
157
|
- **No per-attempt race** around the reconcile itself — the 1.4.8 change removed it to avoid orphaning mid-batch broadcasts (see the [`recalculateGrid`](../modules/order/grid.ts) call site in `modules/order/grid.ts`).
|
|
135
|
-
- The whole resync is bounded by a **10-minute total timeout** (`PIPELINE_TIMING.TIMEOUT_MS * 2`
|
|
136
|
-
- Every internal chain read goes through `readOpenOrdersGuarded`
|
|
158
|
+
- The whole resync is bounded by a **10-minute total timeout** (`PIPELINE_TIMING.TIMEOUT_MS * 2`) and applied with `Promise.race` in `recalculateGrid()`.
|
|
159
|
+
- Every internal chain read goes through `readOpenOrdersGuarded` with the 30s / 3-retry / node-failover standard. Truncated reads are always ambiguous and return `null`; empty reads are ambiguous only when a caller explicitly sets `deferEmpty: true`. Phase-2 cancellation uses the default empty-aware policy, then validates each plan against the fresh per-order signature before any mutation.
|
|
137
160
|
|
|
138
161
|
---
|
|
139
162
|
|
|
@@ -141,7 +164,7 @@ If Phase 2 partially succeeds (some cancels, some creates fail), there is no rol
|
|
|
141
164
|
|
|
142
165
|
### Fresh Grid Guard (`matchedOnGrid > 0`)
|
|
143
166
|
|
|
144
|
-
**`grid_reconcile_internal.ts
|
|
167
|
+
**`_reconcileStartupSide()` in `grid_reconcile_internal.ts`**
|
|
145
168
|
|
|
146
169
|
When a brand-new grid is generated, every slot is VIRTUAL — `matchedOnGrid = 0`. Without a guard, every on-chain order appears "unmatched" and would be cancelled as excess:
|
|
147
170
|
|
|
@@ -155,27 +178,25 @@ When `matchedOnGrid === 0` AND scaling up (`neededSlots > 0`), excess cancellati
|
|
|
155
178
|
|
|
156
179
|
### Grid-Edge Lock
|
|
157
180
|
|
|
158
|
-
**`grid_reconcile_internal.ts
|
|
181
|
+
**`_isGridEdgeFullyActive()` in `grid_reconcile_internal.ts`** detects when the grid boundary is fully active (all slots on-chain) before cancelling excess orders.
|
|
159
182
|
|
|
160
|
-
When all outermost orders of a side are ACTIVE with `orderId`, all balance is committed to the edges. Cancel the **largest** order among the update candidates (`_cancelLargestOrder
|
|
183
|
+
When all outermost orders of a side are ACTIVE with `orderId`, all balance is committed to the edges. Cancel the **largest** order among the update candidates (`_cancelLargestOrder()`) to free maximum funds with minimum operations, since the DEX does not expose partial-reduce in one operation. The cancelled slot gets a replacement create.
|
|
161
184
|
|
|
162
|
-
Detection
|
|
185
|
+
Detection sorts orders by price (BUY descending, SELL ascending) and checks that the outermost ones are all `isOrderPlaced()`.
|
|
163
186
|
|
|
164
187
|
### Duplicate Cancellation
|
|
165
188
|
|
|
166
|
-
**`grid_reconcile.ts
|
|
189
|
+
**`reconcileGridOrders()` in `grid_reconcile.ts`**
|
|
167
190
|
|
|
168
191
|
An unmatched chain order whose price equals an active same-type grid slot's price — exact slot-price equality via `priceSlotEqual` at the asset precision — is a **suspected duplicate** → queued for Phase 2 cancellation (not cancelled under lock). Non-equal neighbours are only logged with nearest-same-side diagnostics, never cancelled here. The earlier fuzzy `SUSPECTED_DUPLICATE_TOLERANCE_MULTIPLIER` (5× `calculatePriceTolerance`) was removed.
|
|
169
192
|
|
|
170
193
|
### Batch Update Failure Recovery
|
|
171
194
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
Up to 3 batch attempts. Each failure triggers a recovery sync + plan refresh. If all plans are empty → resolved early. After 3× → sequential fallback with per-plan recovery (each individual failure triggers a recovery sync + queue refresh).
|
|
195
|
+
Up to 3 batch attempts (`maxBatchAttempts = 3`). Each failure triggers a recovery sync + plan refresh. If all plans are empty → resolved early. After 3× → sequential fallback with per-plan recovery (each individual failure triggers a recovery sync + queue refresh).
|
|
175
196
|
|
|
176
197
|
### Phantom Orders via Reconcile
|
|
177
198
|
|
|
178
|
-
|
|
199
|
+
Reconcile's role in the defense-in-depth: during Phase 1, any ACTIVE/PARTIAL order whose `orderId` is not found on-chain is reset to VIRTUAL with `skipAccounting`. The freshly-assigned deferral protects in-flight broadcasts, and the ghost heuristic lets known fills pass. See [`developer_guide.md`](developer_guide.md#phantom-orders-prevention-defense-in-depth) for the full 3-layer defense.
|
|
179
200
|
|
|
180
201
|
### Shelf Orders (Fork-Kept Manual Orders)
|
|
181
202
|
|
|
@@ -187,7 +208,7 @@ Live on-chain orders with non-slot-N ids below the rail (e.g. `deep-*` manuals k
|
|
|
187
208
|
|
|
188
209
|
### COW Interaction
|
|
189
210
|
|
|
190
|
-
Reconcile Phase 1 runs under `_gridLock` with no side effects on the frozen master Map. The working grid is not involved — reconcile is a startup operation that runs before the COW pipeline is active. See [`COPY_ON_WRITE_MASTER_PLAN.md`](COPY_ON_WRITE_MASTER_PLAN.md#safety-guardrails) and [`COW_INVARIANTS.md`](COW_INVARIANTS.md#reconcile
|
|
211
|
+
Reconcile Phase 1 runs under `_gridLock` with no side effects on the frozen master Map. The working grid is not involved — reconcile is a startup operation that runs before the COW pipeline is active. See [`COPY_ON_WRITE_MASTER_PLAN.md`](COPY_ON_WRITE_MASTER_PLAN.md#safety-guardrails) and [`COW_INVARIANTS.md`](COW_INVARIANTS.md#reconcile) for COW rules.
|
|
191
212
|
|
|
192
213
|
### Slot-Price Invariant at the Reconcile Emission Sites
|
|
193
214
|
|
|
@@ -195,11 +216,11 @@ Three of the six guarded emission sites are reconcile sites (`RECONCILE-CREATE`,
|
|
|
195
216
|
|
|
196
217
|
### Truncated-Read Ambiguity (since 1.4.8)
|
|
197
218
|
|
|
198
|
-
Every chain read feeding an absence/surplus decision goes through `readOpenOrdersGuarded
|
|
219
|
+
Every chain read feeding an absence/surplus decision goes through `readOpenOrdersGuarded`. A truncated snapshot is always unreadable. An empty snapshot is also unreadable at callers that set `deferEmpty: true`; the Phase-2 cancellation pre-read intentionally accepts a complete empty result, executes no plan, and leaves all remaining state for the normal reconcile paths:
|
|
199
220
|
|
|
200
|
-
- `_recoverSyncFromChain
|
|
201
|
-
- `_adoptPossiblyLandedCreate
|
|
202
|
-
- Phase 3 final refresh
|
|
221
|
+
- `_recoverSyncFromChain()` — plus its recovery sites in `_createOrderFromGrid` / `_cancelChainOrder` — defers on empty/truncated reads (`deferEmpty: true`). A pass-1 phantom cleanup would otherwise virtualize live slots from a partial window.
|
|
222
|
+
- `_adoptPossiblyLandedCreate()` defers to an uncertain outcome on truncated reads, and the startup group batch uncertain verification follows the same rule.
|
|
223
|
+
- Phase 3 final refresh skips adoption/surplus-cancel on a truncated read, keeping the pre-phase-2 counts for the summary log.
|
|
203
224
|
- Adoption paths (`_adoptPossiblyLandedCreate`, grouping path, reconcile adoption loop) apply the create-fee deduction via `_applySync` for accounting parity.
|
|
204
225
|
|
|
205
226
|
The underlying rule is `INV-BROADCAST-004`: a capped `get_full_accounts` window omits the freshest orders (fresh creates sort last), so absence can never be authoritative on a truncated read.
|
|
@@ -208,7 +229,7 @@ The underlying rule is `INV-BROADCAST-004`: a capped `get_full_accounts` window
|
|
|
208
229
|
|
|
209
230
|
## Lock Hierarchy
|
|
210
231
|
|
|
211
|
-
**`manager.ts
|
|
232
|
+
**`manager.ts` lock declaration** — canonical reference in [`developer_guide.md`](developer_guide.md#lock-ordering-for-deadlock-prevention).
|
|
212
233
|
|
|
213
234
|
```
|
|
214
235
|
Level 0: _fillProcessingLock Level 1: _divergenceLock
|
|
@@ -234,10 +255,10 @@ Commit `e64db685` replaced 6 single-value boolean state fields with refcounts/st
|
|
|
234
255
|
|
|
235
256
|
| Constant | Value | File | Role |
|
|
236
257
|
|----------|-------|------|------|
|
|
237
|
-
| `maxBatchAttempts` | `3` | `grid_reconcile.ts
|
|
238
|
-
| `PRICE_TOLERANCE_MAX_PERCENT` | `0.01` (1%) | `constants.ts
|
|
239
|
-
| `PRICE_TOLERANCE_MIN_ABSOLUTE` | `0.0001` | `constants.ts
|
|
240
|
-
| `PIPELINE_TIMING.TIMEOUT_MS` | `300000` (5min) | `constants.ts
|
|
258
|
+
| `maxBatchAttempts` | `3` | `grid_reconcile.ts` | Update-batch retry limit |
|
|
259
|
+
| `PRICE_TOLERANCE_MAX_PERCENT` | `0.01` (1%) | `constants.ts::GRID_LIMITS` | Cap on price tolerance |
|
|
260
|
+
| `PRICE_TOLERANCE_MIN_ABSOLUTE` | `0.0001` | `constants.ts::GRID_LIMITS` | Floor for price tolerance |
|
|
261
|
+
| `PIPELINE_TIMING.TIMEOUT_MS` | `300000` (5min) | `constants.ts::PIPELINE_TIMING` | Base pipeline timing; resync uses 2× (10 min) |
|
|
241
262
|
|
|
242
263
|
---
|
|
243
264
|
|
|
@@ -246,7 +267,7 @@ Commit `e64db685` replaced 6 single-value boolean state fields with refcounts/st
|
|
|
246
267
|
| Test File | Coverage |
|
|
247
268
|
|-----------|----------|
|
|
248
269
|
| `tests/test_grid_reconcile.ts` | 8: grid detection, largest-order cancel, ordering |
|
|
249
|
-
| `tests/test_grid_reconcile_regressions.ts` |
|
|
270
|
+
| `tests/test_grid_reconcile_regressions.ts` | 16 startup scenarios: fund/fund-lock behavior, verified-after-failure, slot/skip cases, `matchedOnGrid`, Phase-3 surplus, phantom deferral, duplicate ownership and settlement, persistent-duplicate escalation, changed-plan rejection, per-plan independence, and truncated/failed pre-cancel reads |
|
|
250
271
|
| `tests/test_resync_duplicate_race.ts` | Phase 3 duplicate race |
|
|
251
272
|
| `tests/test_resync_balance_fix.ts` | Fund reuse during Phase 3 |
|
|
252
273
|
| `tests/test_resync_invariants.ts` | Fund invariant suppression during transient resync |
|
|
@@ -263,10 +284,10 @@ Commit `e64db685` replaced 6 single-value boolean state fields with refcounts/st
|
|
|
263
284
|
|
|
264
285
|
| File | Role |
|
|
265
286
|
|------|------|
|
|
266
|
-
| `modules/order/grid_reconcile.ts` | Public API + 3-phase orchestrator
|
|
267
|
-
| `modules/order/grid_reconcile_internal.ts` | Internal helpers — `_reconcileStartupSide`, grid detection, recovery, uncertainty
|
|
287
|
+
| `modules/order/grid_reconcile.ts` | Public API + 3-phase orchestrator, including per-plan Phase-2 cancellation validation |
|
|
288
|
+
| `modules/order/grid_reconcile_internal.ts` | Internal helpers — `_reconcileStartupSide`, grid detection, recovery, uncertainty |
|
|
268
289
|
| `modules/order/manager.ts` | Lock hierarchy definition, `_applyOrderUpdate`, phantom guard, `reconcileGrid` entry, COW integration |
|
|
269
|
-
| `modules/order/async_lock.ts` | AsyncLock engine with ALS re-entrancy
|
|
290
|
+
| `modules/order/async_lock.ts` | AsyncLock engine with ALS re-entrancy |
|
|
270
291
|
| `modules/order/sync_engine.ts` | Blockchain sync pipeline |
|
|
271
292
|
| `modules/order/grid.ts` | Grid creation, `recalculateGrid` (full resync) calls reconcile |
|
|
272
293
|
| `modules/chain_orders.ts` | `readOpenOrdersGuarded` / guarded read infrastructure |
|