@reefclaw/connect 0.1.11 → 0.1.12

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.
Files changed (397) hide show
  1. package/assets/bridge/gateway/heartbeat-cron.d.ts +27 -0
  2. package/assets/bridge/gateway/heartbeat-cron.js +85 -0
  3. package/assets/bridge/providers/gateway.d.ts +2 -0
  4. package/assets/bridge/providers/gateway.js +57 -16
  5. package/assets/bridge/setup.js +6 -51
  6. package/dist/deps.js +2 -2
  7. package/dist/plugin.js +35 -7
  8. package/package.json +1 -1
  9. package/assets/plugin/audit/mode-transition-audit.d.ts +0 -11
  10. package/assets/plugin/audit/mode-transition-audit.js +0 -29
  11. package/assets/plugin/balance-utils.d.ts +0 -36
  12. package/assets/plugin/balance-utils.js +0 -98
  13. package/assets/plugin/ccxt/binance-ban-gate.d.ts +0 -47
  14. package/assets/plugin/ccxt/binance-ban-gate.js +0 -420
  15. package/assets/plugin/ccxt/binance-private.d.ts +0 -346
  16. package/assets/plugin/ccxt/binance-private.js +0 -1525
  17. package/assets/plugin/ccxt/binance-public.d.ts +0 -34
  18. package/assets/plugin/ccxt/binance-public.js +0 -180
  19. package/assets/plugin/ccxt/intel-public.d.ts +0 -25
  20. package/assets/plugin/ccxt/intel-public.js +0 -80
  21. package/assets/plugin/ccxt/public-market-data-api.d.ts +0 -26
  22. package/assets/plugin/ccxt/public-market-data-api.js +0 -23
  23. package/assets/plugin/config/agent-config-client.d.ts +0 -77
  24. package/assets/plugin/config/agent-config-client.js +0 -188
  25. package/assets/plugin/config/agent-config-poller.d.ts +0 -32
  26. package/assets/plugin/config/agent-config-poller.js +0 -101
  27. package/assets/plugin/config/brackets-config.d.ts +0 -22
  28. package/assets/plugin/config/brackets-config.js +0 -58
  29. package/assets/plugin/config/entitlement-gate.d.ts +0 -51
  30. package/assets/plugin/config/entitlement-gate.js +0 -137
  31. package/assets/plugin/config/gate-store.d.ts +0 -18
  32. package/assets/plugin/config/gate-store.js +0 -61
  33. package/assets/plugin/config/plugin-config-io.d.ts +0 -222
  34. package/assets/plugin/config/plugin-config-io.js +0 -126
  35. package/assets/plugin/config/position-review-config.d.ts +0 -35
  36. package/assets/plugin/config/position-review-config.js +0 -105
  37. package/assets/plugin/config/tool-gate.d.ts +0 -53
  38. package/assets/plugin/config/tool-gate.js +0 -128
  39. package/assets/plugin/config/user-data-stream-config.d.ts +0 -89
  40. package/assets/plugin/config/user-data-stream-config.js +0 -239
  41. package/assets/plugin/connector-supervisor.d.ts +0 -36
  42. package/assets/plugin/connector-supervisor.js +0 -149
  43. package/assets/plugin/exchange-adapter.d.ts +0 -65
  44. package/assets/plugin/exchange-adapter.js +0 -4
  45. package/assets/plugin/index.d.ts +0 -30
  46. package/assets/plugin/index.js +0 -2756
  47. package/assets/plugin/ingest/pending-entry-metadata.d.ts +0 -74
  48. package/assets/plugin/ingest/pending-entry-metadata.js +0 -236
  49. package/assets/plugin/ingest/position-auto-capture.d.ts +0 -171
  50. package/assets/plugin/ingest/position-auto-capture.js +0 -709
  51. package/assets/plugin/ingest/position-decisions-client.d.ts +0 -327
  52. package/assets/plugin/ingest/position-decisions-client.js +0 -306
  53. package/assets/plugin/ingest/readiness-reporter.d.ts +0 -42
  54. package/assets/plugin/ingest/readiness-reporter.js +0 -163
  55. package/assets/plugin/ingest/reconcile-db-vs-exchange.d.ts +0 -51
  56. package/assets/plugin/ingest/reconcile-db-vs-exchange.js +0 -170
  57. package/assets/plugin/ingest/reconciler-cleanup.d.ts +0 -37
  58. package/assets/plugin/ingest/reconciler-cleanup.js +0 -147
  59. package/assets/plugin/ingest/rest-gap-filler.d.ts +0 -191
  60. package/assets/plugin/ingest/rest-gap-filler.js +0 -565
  61. package/assets/plugin/ingest/touched-symbols-store.d.ts +0 -25
  62. package/assets/plugin/ingest/touched-symbols-store.js +0 -96
  63. package/assets/plugin/ingest/trade-store-client.d.ts +0 -40
  64. package/assets/plugin/ingest/trade-store-client.js +0 -125
  65. package/assets/plugin/ingest/ws-ingest.d.ts +0 -43
  66. package/assets/plugin/ingest/ws-ingest.js +0 -126
  67. package/assets/plugin/learning/setup-family.d.ts +0 -21
  68. package/assets/plugin/learning/setup-family.js +0 -103
  69. package/assets/plugin/lifecycle/install-signal-handlers.d.ts +0 -33
  70. package/assets/plugin/lifecycle/install-signal-handlers.js +0 -112
  71. package/assets/plugin/lifecycle/shutdown-coordinator.d.ts +0 -43
  72. package/assets/plugin/lifecycle/shutdown-coordinator.js +0 -131
  73. package/assets/plugin/lifecycle/trading-operation-lock.d.ts +0 -17
  74. package/assets/plugin/lifecycle/trading-operation-lock.js +0 -14
  75. package/assets/plugin/live/bracket-id.d.ts +0 -26
  76. package/assets/plugin/live/bracket-id.js +0 -112
  77. package/assets/plugin/live/bracket-ledger.d.ts +0 -54
  78. package/assets/plugin/live/bracket-ledger.js +0 -267
  79. package/assets/plugin/live/bracket-manager.d.ts +0 -82
  80. package/assets/plugin/live/bracket-manager.js +0 -478
  81. package/assets/plugin/live/bracket-params.d.ts +0 -22
  82. package/assets/plugin/live/bracket-params.js +0 -124
  83. package/assets/plugin/live/bracket-reconciler.d.ts +0 -95
  84. package/assets/plugin/live/bracket-reconciler.js +0 -573
  85. package/assets/plugin/live/bracket-types.d.ts +0 -102
  86. package/assets/plugin/live/bracket-types.js +0 -8
  87. package/assets/plugin/live/deposit-tracker.d.ts +0 -62
  88. package/assets/plugin/live/deposit-tracker.js +0 -97
  89. package/assets/plugin/live/emergency-controls.d.ts +0 -32
  90. package/assets/plugin/live/emergency-controls.js +0 -226
  91. package/assets/plugin/live/exchange-errors.d.ts +0 -12
  92. package/assets/plugin/live/exchange-errors.js +0 -130
  93. package/assets/plugin/live/exchange-info-cache.d.ts +0 -37
  94. package/assets/plugin/live/exchange-info-cache.js +0 -134
  95. package/assets/plugin/live/fact-subscriber.d.ts +0 -78
  96. package/assets/plugin/live/fact-subscriber.js +0 -182
  97. package/assets/plugin/live/fill-price.d.ts +0 -13
  98. package/assets/plugin/live/fill-price.js +0 -37
  99. package/assets/plugin/live/intent-journal.d.ts +0 -42
  100. package/assets/plugin/live/intent-journal.js +0 -122
  101. package/assets/plugin/live/listen-key-manager.d.ts +0 -70
  102. package/assets/plugin/live/listen-key-manager.js +0 -169
  103. package/assets/plugin/live/live-adapter.d.ts +0 -319
  104. package/assets/plugin/live/live-adapter.js +0 -1906
  105. package/assets/plugin/live/live-balance-enricher.d.ts +0 -32
  106. package/assets/plugin/live/live-balance-enricher.js +0 -104
  107. package/assets/plugin/live/live-bracket-api.d.ts +0 -13
  108. package/assets/plugin/live/live-bracket-api.js +0 -20
  109. package/assets/plugin/live/live-state-store.d.ts +0 -194
  110. package/assets/plugin/live/live-state-store.js +0 -450
  111. package/assets/plugin/live/local-signal-service.d.ts +0 -57
  112. package/assets/plugin/live/local-signal-service.js +0 -151
  113. package/assets/plugin/live/local-strategy-evaluator.d.ts +0 -62
  114. package/assets/plugin/live/local-strategy-evaluator.js +0 -131
  115. package/assets/plugin/live/microstructure-assembler.d.ts +0 -54
  116. package/assets/plugin/live/microstructure-assembler.js +0 -148
  117. package/assets/plugin/live/order-poller.d.ts +0 -29
  118. package/assets/plugin/live/order-poller.js +0 -125
  119. package/assets/plugin/live/position-state-store.d.ts +0 -87
  120. package/assets/plugin/live/position-state-store.js +0 -237
  121. package/assets/plugin/live/proposal-decision-listener.d.ts +0 -70
  122. package/assets/plugin/live/proposal-decision-listener.js +0 -292
  123. package/assets/plugin/live/proposal-manager.d.ts +0 -76
  124. package/assets/plugin/live/proposal-manager.js +0 -140
  125. package/assets/plugin/live/rate-limiter.d.ts +0 -47
  126. package/assets/plugin/live/rate-limiter.js +0 -159
  127. package/assets/plugin/live/reconciler.d.ts +0 -39
  128. package/assets/plugin/live/reconciler.js +0 -175
  129. package/assets/plugin/live/setup-buckets.d.ts +0 -7
  130. package/assets/plugin/live/setup-buckets.js +0 -33
  131. package/assets/plugin/live/slippage-tracker.d.ts +0 -45
  132. package/assets/plugin/live/slippage-tracker.js +0 -78
  133. package/assets/plugin/live/stop-watcher.d.ts +0 -67
  134. package/assets/plugin/live/stop-watcher.js +0 -218
  135. package/assets/plugin/live/user-data-active-probe.d.ts +0 -54
  136. package/assets/plugin/live/user-data-active-probe.js +0 -180
  137. package/assets/plugin/live/user-data-stream-controller.d.ts +0 -200
  138. package/assets/plugin/live/user-data-stream-controller.js +0 -579
  139. package/assets/plugin/live/user-data-stream-ws.d.ts +0 -22
  140. package/assets/plugin/live/user-data-stream-ws.js +0 -63
  141. package/assets/plugin/live/user-data-stream.d.ts +0 -243
  142. package/assets/plugin/live/user-data-stream.js +0 -704
  143. package/assets/plugin/logger.d.ts +0 -2
  144. package/assets/plugin/logger.js +0 -2
  145. package/assets/plugin/mfe.d.ts +0 -21
  146. package/assets/plugin/mfe.js +0 -68
  147. package/assets/plugin/onboarding/mode-ladder.d.ts +0 -1
  148. package/assets/plugin/onboarding/mode-ladder.js +0 -3
  149. package/assets/plugin/onboarding/runtime.d.ts +0 -90
  150. package/assets/plugin/onboarding/runtime.js +0 -184
  151. package/assets/plugin/openclaw.plugin.json +0 -92
  152. package/assets/plugin/paper-adapter.d.ts +0 -24
  153. package/assets/plugin/paper-adapter.js +0 -91
  154. package/assets/plugin/persistence/state-manager.d.ts +0 -66
  155. package/assets/plugin/persistence/state-manager.js +0 -222
  156. package/assets/plugin/pinned-plan.d.ts +0 -9
  157. package/assets/plugin/pinned-plan.js +0 -23
  158. package/assets/plugin/portfolio/reentry-tracker.d.ts +0 -36
  159. package/assets/plugin/portfolio/reentry-tracker.js +0 -127
  160. package/assets/plugin/portfolio/wave9-admission.d.ts +0 -67
  161. package/assets/plugin/portfolio/wave9-admission.js +0 -262
  162. package/assets/plugin/portfolio/wave9-policy.d.ts +0 -36
  163. package/assets/plugin/portfolio/wave9-policy.js +0 -183
  164. package/assets/plugin/risk/pre-trade-check.d.ts +0 -38
  165. package/assets/plugin/risk/pre-trade-check.js +0 -345
  166. package/assets/plugin/risk/pre-trade-types.d.ts +0 -60
  167. package/assets/plugin/risk/pre-trade-types.js +0 -3
  168. package/assets/plugin/shadow/shadow-tracker.d.ts +0 -36
  169. package/assets/plugin/shadow/shadow-tracker.js +0 -151
  170. package/assets/plugin/shadow/types.d.ts +0 -42
  171. package/assets/plugin/shadow/types.js +0 -20
  172. package/assets/plugin/shared/indicators-extended.d.ts +0 -52
  173. package/assets/plugin/shared/indicators-extended.js +0 -291
  174. package/assets/plugin/shared/indicators.d.ts +0 -15
  175. package/assets/plugin/shared/indicators.js +0 -114
  176. package/assets/plugin/signals/conditions/registry.d.ts +0 -16
  177. package/assets/plugin/signals/conditions/registry.js +0 -1333
  178. package/assets/plugin/signals/conditions/types.d.ts +0 -1
  179. package/assets/plugin/signals/conditions/types.js +0 -4
  180. package/assets/plugin/signals/direction-rules.d.ts +0 -3
  181. package/assets/plugin/signals/direction-rules.js +0 -24
  182. package/assets/plugin/signals/entry-rules.d.ts +0 -6
  183. package/assets/plugin/signals/entry-rules.js +0 -33
  184. package/assets/plugin/signals/serialize-context.d.ts +0 -4
  185. package/assets/plugin/signals/serialize-context.js +0 -39
  186. package/assets/plugin/signals/stop-rules.d.ts +0 -3
  187. package/assets/plugin/signals/stop-rules.js +0 -48
  188. package/assets/plugin/signals/strategy-adapter.d.ts +0 -47
  189. package/assets/plugin/signals/strategy-adapter.js +0 -209
  190. package/assets/plugin/signals/types.d.ts +0 -1
  191. package/assets/plugin/signals/types.js +0 -8
  192. package/assets/plugin/simulator/exchange-simulator.d.ts +0 -105
  193. package/assets/plugin/simulator/exchange-simulator.js +0 -759
  194. package/assets/plugin/simulator/fill-engine.d.ts +0 -53
  195. package/assets/plugin/simulator/fill-engine.js +0 -280
  196. package/assets/plugin/simulator/paper-market-feed.d.ts +0 -26
  197. package/assets/plugin/simulator/paper-market-feed.js +0 -104
  198. package/assets/plugin/simulator/realistic-fills.d.ts +0 -59
  199. package/assets/plugin/simulator/realistic-fills.js +0 -175
  200. package/assets/plugin/simulator/types.d.ts +0 -228
  201. package/assets/plugin/simulator/types.js +0 -43
  202. package/assets/plugin/strategy/builtin-strategies.d.ts +0 -2
  203. package/assets/plugin/strategy/builtin-strategies.js +0 -113
  204. package/assets/plugin/strategy/condition-registry.d.ts +0 -3
  205. package/assets/plugin/strategy/condition-registry.js +0 -153
  206. package/assets/plugin/strategy/evaluator.d.ts +0 -70
  207. package/assets/plugin/strategy/evaluator.js +0 -98
  208. package/assets/plugin/tools/assessment-validation.d.ts +0 -141
  209. package/assets/plugin/tools/assessment-validation.js +0 -473
  210. package/assets/plugin/tools/attach-brackets.d.ts +0 -39
  211. package/assets/plugin/tools/attach-brackets.js +0 -564
  212. package/assets/plugin/tools/audit-bracket-protection.d.ts +0 -49
  213. package/assets/plugin/tools/audit-bracket-protection.js +0 -683
  214. package/assets/plugin/tools/bracket-control.d.ts +0 -12
  215. package/assets/plugin/tools/bracket-control.js +0 -35
  216. package/assets/plugin/tools/cancel-all-orders.d.ts +0 -9
  217. package/assets/plugin/tools/cancel-all-orders.js +0 -8
  218. package/assets/plugin/tools/cancel-order.d.ts +0 -14
  219. package/assets/plugin/tools/cancel-order.js +0 -60
  220. package/assets/plugin/tools/check-position-health.d.ts +0 -46
  221. package/assets/plugin/tools/check-position-health.js +0 -194
  222. package/assets/plugin/tools/clear-exchange-credentials.d.ts +0 -24
  223. package/assets/plugin/tools/clear-exchange-credentials.js +0 -70
  224. package/assets/plugin/tools/close-position.d.ts +0 -45
  225. package/assets/plugin/tools/close-position.js +0 -722
  226. package/assets/plugin/tools/create-order.d.ts +0 -82
  227. package/assets/plugin/tools/create-order.js +0 -1544
  228. package/assets/plugin/tools/exit-gate.d.ts +0 -58
  229. package/assets/plugin/tools/exit-gate.js +0 -162
  230. package/assets/plugin/tools/fetch-balance.d.ts +0 -5
  231. package/assets/plugin/tools/fetch-balance.js +0 -4
  232. package/assets/plugin/tools/fetch-ohlcv.d.ts +0 -11
  233. package/assets/plugin/tools/fetch-ohlcv.js +0 -8
  234. package/assets/plugin/tools/fetch-open-orders.d.ts +0 -7
  235. package/assets/plugin/tools/fetch-open-orders.js +0 -4
  236. package/assets/plugin/tools/fetch-positions.d.ts +0 -7
  237. package/assets/plugin/tools/fetch-positions.js +0 -4
  238. package/assets/plugin/tools/fetch-ticker.d.ts +0 -11
  239. package/assets/plugin/tools/fetch-ticker.js +0 -5
  240. package/assets/plugin/tools/get-agent-profile.d.ts +0 -4
  241. package/assets/plugin/tools/get-agent-profile.js +0 -6
  242. package/assets/plugin/tools/get-analytics.d.ts +0 -6
  243. package/assets/plugin/tools/get-analytics.js +0 -7
  244. package/assets/plugin/tools/get-backtest.d.ts +0 -12
  245. package/assets/plugin/tools/get-backtest.js +0 -91
  246. package/assets/plugin/tools/get-basis.d.ts +0 -7
  247. package/assets/plugin/tools/get-basis.js +0 -7
  248. package/assets/plugin/tools/get-bracket-config.d.ts +0 -11
  249. package/assets/plugin/tools/get-bracket-config.js +0 -24
  250. package/assets/plugin/tools/get-cascade-risk.d.ts +0 -7
  251. package/assets/plugin/tools/get-cascade-risk.js +0 -8
  252. package/assets/plugin/tools/get-crypto-metrics.d.ts +0 -18
  253. package/assets/plugin/tools/get-crypto-metrics.js +0 -62
  254. package/assets/plugin/tools/get-cvd.d.ts +0 -6
  255. package/assets/plugin/tools/get-cvd.js +0 -6
  256. package/assets/plugin/tools/get-divergences.d.ts +0 -6
  257. package/assets/plugin/tools/get-divergences.js +0 -6
  258. package/assets/plugin/tools/get-funding-context.d.ts +0 -6
  259. package/assets/plugin/tools/get-funding-context.js +0 -16
  260. package/assets/plugin/tools/get-liquidation-levels.d.ts +0 -7
  261. package/assets/plugin/tools/get-liquidation-levels.js +0 -7
  262. package/assets/plugin/tools/get-liquidation-pulse.d.ts +0 -9
  263. package/assets/plugin/tools/get-liquidation-pulse.js +0 -22
  264. package/assets/plugin/tools/get-market-breadth.d.ts +0 -6
  265. package/assets/plugin/tools/get-market-breadth.js +0 -8
  266. package/assets/plugin/tools/get-market-intel.d.ts +0 -19
  267. package/assets/plugin/tools/get-market-intel.js +0 -116
  268. package/assets/plugin/tools/get-market-structure.d.ts +0 -47
  269. package/assets/plugin/tools/get-market-structure.js +0 -198
  270. package/assets/plugin/tools/get-my-mined-patterns.d.ts +0 -20
  271. package/assets/plugin/tools/get-my-mined-patterns.js +0 -61
  272. package/assets/plugin/tools/get-my-proposed-learnings.d.ts +0 -20
  273. package/assets/plugin/tools/get-my-proposed-learnings.js +0 -55
  274. package/assets/plugin/tools/get-my-recent-reviews.d.ts +0 -22
  275. package/assets/plugin/tools/get-my-recent-reviews.js +0 -66
  276. package/assets/plugin/tools/get-orderbook.d.ts +0 -21
  277. package/assets/plugin/tools/get-orderbook.js +0 -32
  278. package/assets/plugin/tools/get-pattern-scan.d.ts +0 -7
  279. package/assets/plugin/tools/get-pattern-scan.js +0 -8
  280. package/assets/plugin/tools/get-regime.d.ts +0 -6
  281. package/assets/plugin/tools/get-regime.js +0 -7
  282. package/assets/plugin/tools/get-relevant-learnings.d.ts +0 -21
  283. package/assets/plugin/tools/get-relevant-learnings.js +0 -65
  284. package/assets/plugin/tools/get-resting-liquidity.d.ts +0 -6
  285. package/assets/plugin/tools/get-resting-liquidity.js +0 -11
  286. package/assets/plugin/tools/get-risk-scenario.d.ts +0 -29
  287. package/assets/plugin/tools/get-risk-scenario.js +0 -47
  288. package/assets/plugin/tools/get-risk-summary.d.ts +0 -51
  289. package/assets/plugin/tools/get-risk-summary.js +0 -118
  290. package/assets/plugin/tools/get-sentiment.d.ts +0 -4
  291. package/assets/plugin/tools/get-sentiment.js +0 -6
  292. package/assets/plugin/tools/get-session-review.d.ts +0 -7
  293. package/assets/plugin/tools/get-session-review.js +0 -8
  294. package/assets/plugin/tools/get-setup-detail.d.ts +0 -7
  295. package/assets/plugin/tools/get-setup-detail.js +0 -322
  296. package/assets/plugin/tools/get-signals.d.ts +0 -15
  297. package/assets/plugin/tools/get-signals.js +0 -54
  298. package/assets/plugin/tools/get-sizing.d.ts +0 -6
  299. package/assets/plugin/tools/get-sizing.js +0 -6
  300. package/assets/plugin/tools/get-trade-feedback.d.ts +0 -7
  301. package/assets/plugin/tools/get-trade-feedback.js +0 -8
  302. package/assets/plugin/tools/get-trade-flow.d.ts +0 -7
  303. package/assets/plugin/tools/get-trade-flow.js +0 -7
  304. package/assets/plugin/tools/get-volume-analysis.d.ts +0 -21
  305. package/assets/plugin/tools/get-volume-analysis.js +0 -74
  306. package/assets/plugin/tools/get-volume-profile.d.ts +0 -7
  307. package/assets/plugin/tools/get-volume-profile.js +0 -7
  308. package/assets/plugin/tools/get-wave9-status.d.ts +0 -127
  309. package/assets/plugin/tools/get-wave9-status.js +0 -796
  310. package/assets/plugin/tools/helpers.d.ts +0 -26
  311. package/assets/plugin/tools/helpers.js +0 -39
  312. package/assets/plugin/tools/intel-api.d.ts +0 -34
  313. package/assets/plugin/tools/intel-api.js +0 -119
  314. package/assets/plugin/tools/intel-cache.d.ts +0 -25
  315. package/assets/plugin/tools/intel-cache.js +0 -148
  316. package/assets/plugin/tools/list-strategies.d.ts +0 -17
  317. package/assets/plugin/tools/list-strategies.js +0 -23
  318. package/assets/plugin/tools/modify-stop.d.ts +0 -21
  319. package/assets/plugin/tools/modify-stop.js +0 -120
  320. package/assets/plugin/tools/modify-target.d.ts +0 -21
  321. package/assets/plugin/tools/modify-target.js +0 -110
  322. package/assets/plugin/tools/propose-learning.d.ts +0 -22
  323. package/assets/plugin/tools/propose-learning.js +0 -65
  324. package/assets/plugin/tools/query-review-outcomes.d.ts +0 -30
  325. package/assets/plugin/tools/query-review-outcomes.js +0 -64
  326. package/assets/plugin/tools/query-trades.d.ts +0 -21
  327. package/assets/plugin/tools/query-trades.js +0 -37
  328. package/assets/plugin/tools/record-position-reviews.d.ts +0 -38
  329. package/assets/plugin/tools/record-position-reviews.js +0 -147
  330. package/assets/plugin/tools/save-strategy.d.ts +0 -16
  331. package/assets/plugin/tools/save-strategy.js +0 -46
  332. package/assets/plugin/tools/scan-pairs.d.ts +0 -22
  333. package/assets/plugin/tools/scan-pairs.js +0 -234
  334. package/assets/plugin/tools/score-setup.d.ts +0 -31
  335. package/assets/plugin/tools/score-setup.js +0 -268
  336. package/assets/plugin/tools/set-bracket-requirement.d.ts +0 -18
  337. package/assets/plugin/tools/set-bracket-requirement.js +0 -81
  338. package/assets/plugin/tools/set-exchange-credentials.d.ts +0 -25
  339. package/assets/plugin/tools/set-exchange-credentials.js +0 -80
  340. package/assets/plugin/tools/set-trading-mode.d.ts +0 -26
  341. package/assets/plugin/tools/set-trading-mode.js +0 -135
  342. package/assets/plugin/tools/test-exchange-credentials.d.ts +0 -16
  343. package/assets/plugin/tools/test-exchange-credentials.js +0 -100
  344. package/assets/plugin/tools/toggle-strategy.d.ts +0 -8
  345. package/assets/plugin/tools/toggle-strategy.js +0 -15
  346. package/assets/plugin/trading-params-cache.d.ts +0 -26
  347. package/assets/plugin/trading-params-cache.js +0 -52
  348. package/assets/plugin/types.d.ts +0 -134
  349. package/assets/plugin/types.js +0 -7
  350. package/assets/plugin/util/plugin-paths.d.ts +0 -3
  351. package/assets/plugin/util/plugin-paths.js +0 -15
  352. package/assets/plugin/venues/hyperliquid/hl-balance.d.ts +0 -116
  353. package/assets/plugin/venues/hyperliquid/hl-balance.js +0 -145
  354. package/assets/plugin/venues/hyperliquid/hl-bracket-coordinator.d.ts +0 -123
  355. package/assets/plugin/venues/hyperliquid/hl-bracket-coordinator.js +0 -533
  356. package/assets/plugin/venues/hyperliquid/hl-brackets.d.ts +0 -102
  357. package/assets/plugin/venues/hyperliquid/hl-brackets.js +0 -172
  358. package/assets/plugin/venues/hyperliquid/hl-cloid.d.ts +0 -22
  359. package/assets/plugin/venues/hyperliquid/hl-cloid.js +0 -82
  360. package/assets/plugin/venues/hyperliquid/hl-info-cache.d.ts +0 -46
  361. package/assets/plugin/venues/hyperliquid/hl-info-cache.js +0 -125
  362. package/assets/plugin/venues/hyperliquid/hl-live-adapter.d.ts +0 -146
  363. package/assets/plugin/venues/hyperliquid/hl-live-adapter.js +0 -728
  364. package/assets/plugin/venues/hyperliquid/hl-precision.d.ts +0 -61
  365. package/assets/plugin/venues/hyperliquid/hl-precision.js +0 -176
  366. package/assets/plugin/venues/hyperliquid/hl-private.d.ts +0 -88
  367. package/assets/plugin/venues/hyperliquid/hl-private.js +0 -357
  368. package/assets/plugin/venues/hyperliquid/hl-public.d.ts +0 -79
  369. package/assets/plugin/venues/hyperliquid/hl-public.js +0 -436
  370. package/assets/plugin/venues/hyperliquid/hl-rate-gate.d.ts +0 -57
  371. package/assets/plugin/venues/hyperliquid/hl-rate-gate.js +0 -220
  372. package/assets/plugin/venues/hyperliquid/hl-user-stream.d.ts +0 -90
  373. package/assets/plugin/venues/hyperliquid/hl-user-stream.js +0 -220
  374. package/assets/plugin/venues/registry.d.ts +0 -38
  375. package/assets/plugin/venues/registry.js +0 -46
  376. package/assets/plugin/venues/symbols.d.ts +0 -43
  377. package/assets/plugin/venues/symbols.js +0 -107
  378. package/assets/plugin/wave9/live-account-capture.d.ts +0 -67
  379. package/assets/plugin/wave9/live-account-capture.js +0 -435
  380. package/assets/plugin/wave9/live-autonomous-protection.d.ts +0 -39
  381. package/assets/plugin/wave9/live-autonomous-protection.js +0 -112
  382. package/assets/plugin/wave9/live-durable-reconciliation-scheduler.d.ts +0 -33
  383. package/assets/plugin/wave9/live-durable-reconciliation-scheduler.js +0 -115
  384. package/assets/plugin/wave9/live-execution-ledger.d.ts +0 -107
  385. package/assets/plugin/wave9/live-execution-ledger.js +0 -498
  386. package/assets/plugin/wave9/live-position-confirmation.d.ts +0 -18
  387. package/assets/plugin/wave9/live-position-confirmation.js +0 -111
  388. package/assets/plugin/wave9/live-residual-protection.d.ts +0 -18
  389. package/assets/plugin/wave9/live-residual-protection.js +0 -250
  390. package/assets/plugin/wave9/live-startup-reconciliation.d.ts +0 -38
  391. package/assets/plugin/wave9/live-startup-reconciliation.js +0 -454
  392. package/assets/plugin/wave9/live-symbol-ownership.d.ts +0 -20
  393. package/assets/plugin/wave9/live-symbol-ownership.js +0 -132
  394. package/assets/plugin/wave9/paper-admission-guard.d.ts +0 -199
  395. package/assets/plugin/wave9/paper-admission-guard.js +0 -650
  396. package/assets/plugin/wave9/usdm-evidence-provider.d.ts +0 -42
  397. package/assets/plugin/wave9/usdm-evidence-provider.js +0 -133
@@ -1,722 +0,0 @@
1
- // Tool: close_position — close a position at market (paper or live)
2
- // NO readiness gate — emergency control (flatten), must always work.
3
- //
4
- // SKILL.md v2.10.0 gate (Position Management Discipline): the agent must
5
- // submit a documented `reason` and (except for operator_command) a
6
- // structured `assessment` describing the reasoning behind the close. The
7
- // LLM's value is context-sensitive reasoning; we enforce the reasoning
8
- // at the API boundary via a schema, not a time floor.
9
- //
10
- // 2026-04-21 false-bracket_integrity safeguard: audit_bracket_protection
11
- // was observed reporting has_stop=false while the reconciler (same data
12
- // source, same call) consistently confirmed 2 live bracket orders on the
13
- // exchange. Agent used this false negative to trigger close_position with
14
- // reason=bracket_integrity, burning ~8–20 bps per cycle, 14+ cycles today.
15
- // Fix: before executing a bracket_integrity close, the plugin independently
16
- // verifies the ledger + exchange state. If the bracket is genuinely live
17
- // (ledger active/partial AND an exchange order matches the stored cid),
18
- // reject the close — audit was wrong, the position is protected. This is
19
- // a same-signal re-check at the API boundary, not a duplicate of the
20
- // audit tool; it catches the observed class of false negatives without
21
- // trusting the audit's own verdict.
22
- import { formatError, logger } from '../logger.js';
23
- import { fetchCurrentPrice, fetchOrderBook, isError } from './helpers.js';
24
- import { validateClosePosition, } from './assessment-validation.js';
25
- import { onClosePositionFilled } from '../ingest/position-auto-capture.js';
26
- import { evaluateExitGate, } from './exit-gate.js';
27
- import { getRecentAuditVerdictHistory } from './audit-bracket-protection.js';
28
- import { loadExitGateMode } from '../config/position-review-config.js';
29
- import { confirmWave9LivePositionFlat } from '../wave9/live-position-confirmation.js';
30
- import { reprotectWave9LiveResidual, } from '../wave9/live-residual-protection.js';
31
- import { captureWave9PaperPositionFingerprint, isWave9ManagedPosition, WAVE9_MECHANICAL_EXIT_REASON, } from '../wave9/paper-admission-guard.js';
32
- const TAG = 'close-position';
33
- function currentWave9ExecutionMode(deps) {
34
- const runtimeMode = deps.wave9TradingModeCheck?.() ?? deps.adapter.mode;
35
- if (!deps.adapter.isLive && deps.adapter.mode === 'PAPER' && runtimeMode === 'PAPER')
36
- return 'PAPER';
37
- if (deps.adapter.isLive && deps.adapter.mode === 'LIVE' && runtimeMode === 'LIVE')
38
- return 'LIVE';
39
- return null;
40
- }
41
- // Bracket-integrity circuit-breaker. Counts SUCCESSFUL close_position calls
42
- // with reason='bracket_integrity' in a rolling 60-min window. When the 3rd
43
- // such close is attempted, reject — repeated bracket-integrity flushes in
44
- // the same hour means EITHER the bracket subsystem is actually broken (in
45
- // which case the operator needs to know, not the agent quietly burning more
46
- // positions) OR the audit tool is false-negativing (same outcome: stop the
47
- // burn). 2026-05-15 session ran this exact pattern 3 times in 4 hours and
48
- // realised −$3.20 of bracket-integrity flushes before the operator caught it.
49
- const BRACKET_INTEGRITY_WINDOW_MS = 60 * 60 * 1000;
50
- const BRACKET_INTEGRITY_LIMIT = 3;
51
- let bracketIntegrityCloses = []; // timestamps of successful closes
52
- export async function closePositionTool(args, deps) {
53
- // Schema gate FIRST — reject before touching the exchange.
54
- const wave9ExitClaimed = args.reason !== 'operator_command' && (args.reason === WAVE9_MECHANICAL_EXIT_REASON
55
- || args.wave9_exit_token !== undefined
56
- || args.candidate_id !== undefined);
57
- if (wave9ExitClaimed && deps.wave9VenueCheck?.() !== 'binance') {
58
- return { error: 'Wave 9 reversal close refused: execution is pinned to Binance USD-M futures.' };
59
- }
60
- if (wave9ExitClaimed && !deps.operationLock) {
61
- return { error: 'Wave 9 reversal close refused: process-local trading operation lock is unavailable.' };
62
- }
63
- const initialWave9Mode = wave9ExitClaimed ? currentWave9ExecutionMode(deps) : null;
64
- let wave9Lease;
65
- if (wave9ExitClaimed) {
66
- if (!initialWave9Mode) {
67
- return {
68
- error: 'Wave 9 reversal close refused: capability execution requires an exact PAPER/paper-adapter ' +
69
- 'or LIVE/live-adapter runtime match.',
70
- };
71
- }
72
- if (args.reason !== WAVE9_MECHANICAL_EXIT_REASON
73
- || !args.wave9_exit_token
74
- || !args.candidate_id
75
- || !deps.wave9AdmissionGuard) {
76
- return { error: 'Wave 9 reversal close requires its exact reason, candidate identity, and short-lived exit token.' };
77
- }
78
- const executionCanonical = args.symbol.toUpperCase().replace(/[^A-Z0-9]/g, '').replace(/USDTUSDT$/, 'USDT');
79
- if (!executionCanonical.endsWith('USDT') || executionCanonical.length <= 4) {
80
- return { error: `Wave 9 reversal close refused: unsupported execution symbol ${args.symbol}.` };
81
- }
82
- if (initialWave9Mode === 'LIVE' && (!deps.captureWave9PositionFingerprint || !deps.wave9LiveLedger)) {
83
- return {
84
- error: 'Wave 9 live reversal close refused: authoritative live position capture and the durable ' +
85
- 'execution ledger are required.',
86
- };
87
- }
88
- args = { ...args, symbol: `${executionCanonical.slice(0, -4)}/USDT:USDT` };
89
- try {
90
- wave9Lease = await deps.operationLock.withAccountLock(`wave9-begin-close:${args.candidate_id ?? args.symbol}`, async () => {
91
- if (currentWave9ExecutionMode(deps) !== initialWave9Mode) {
92
- throw new Error('adapter or trading mode changed before Wave 9 reversal began');
93
- }
94
- let position;
95
- let positionFingerprint;
96
- if (initialWave9Mode === 'LIVE') {
97
- const capture = await deps.captureWave9PositionFingerprint(args.symbol);
98
- position = capture.position;
99
- positionFingerprint = capture.fingerprint;
100
- }
101
- else {
102
- deps.refreshPaperState?.();
103
- const positions = await deps.adapter.getPositionsOrNull();
104
- if (positions === null)
105
- throw new Error('paper position snapshot unavailable');
106
- const canonical = (value) => value.toUpperCase().replace(/[^A-Z0-9]/g, '').replace(/USDTUSDT$/, 'USDT');
107
- const matches = positions.filter((candidate) => canonical(candidate.symbol) === canonical(args.symbol));
108
- if (matches.length !== 1)
109
- throw new Error('exactly one matching held position is required');
110
- position = matches[0];
111
- positionFingerprint = captureWave9PaperPositionFingerprint(deps.adapter, args.symbol).fingerprint;
112
- }
113
- if (!isWave9ManagedPosition(position)
114
- || position.candidateId !== args.candidate_id
115
- || !position.missionId) {
116
- throw new Error('held position lacks exact Wave 9 identity/geometry');
117
- }
118
- return deps.wave9AdmissionGuard.beginExit({
119
- token: args.wave9_exit_token,
120
- candidateId: args.candidate_id,
121
- missionId: position.missionId,
122
- symbol: args.symbol,
123
- positionSide: position.side,
124
- setupType: position.setupType,
125
- reason: args.reason,
126
- positionFingerprint,
127
- tradingMode: initialWave9Mode,
128
- });
129
- });
130
- }
131
- catch (err) {
132
- return { error: `Wave 9 reversal close refused: ${formatError(err)}` };
133
- }
134
- }
135
- else {
136
- // Preserve the generic tool contract: malformed calls are rejected before
137
- // any adapter read. Wave 9 classification is an additional check only for
138
- // already-valid, non-operator risk-reducing closes.
139
- const v = validateClosePosition(args);
140
- if (!v.ok) {
141
- logger.warn(TAG, `close_position rejected: ${v.error} (symbol=${args.symbol}, reason=${args.reason ?? 'missing'})`);
142
- return { error: v.error ?? 'Invalid close_position arguments.' };
143
- }
144
- if (args.reason !== 'operator_command'
145
- && deps.adapter.isLive
146
- && deps.checkWave9LiveSymbolOwnership
147
- && !deps.operationLock) {
148
- return {
149
- error: 'Generic live close_position refused: the shared trading operation lock is required ' +
150
- 'while Wave 9 LIVE ownership checks are enabled.',
151
- };
152
- }
153
- // When a trusted position snapshot is available, do not route a held
154
- // Wave 9 position through a generic thesis/risk/bracket reason. Snapshot
155
- // failure stays fail-open because an ordinary risk-reducing close must not
156
- // be trapped by extra strategy-lifecycle I/O. Operator remains unconditional.
157
- if (args.reason !== 'operator_command') {
158
- try {
159
- const getTrusted = deps.adapter.getPositionsOrNull?.bind(deps.adapter);
160
- const held = getTrusted ? await getTrusted() : undefined;
161
- if (held) {
162
- const canonical = (value) => value.toUpperCase().replace(/[^A-Z0-9]/g, '').replace(/USDTUSDT$/, 'USDT');
163
- if (held.some((position) => canonical(position.symbol) === canonical(args.symbol)
164
- && isWave9ManagedPosition(position))) {
165
- return {
166
- error: `Wave 9 position close refused: call get_wave9_status and use reason=${WAVE9_MECHANICAL_EXIT_REASON} ` +
167
- 'with its single-use exit token. Only an explicit operator_command bypasses the strategy exit policy.',
168
- };
169
- }
170
- }
171
- else if (held === null) {
172
- logger.warn(TAG, 'Wave 9 generic-close classification unavailable; proceeding with legacy risk-reducing close semantics.');
173
- }
174
- }
175
- catch (err) {
176
- logger.warn(TAG, `Wave 9 generic-close classification failed (${formatError(err)}); proceeding with legacy risk-reducing close semantics.`);
177
- }
178
- }
179
- }
180
- // Exit-gate check — see docs/EXIT_GATE_DESIGN.md. The gate is orthogonal to
181
- // the bracket_integrity safeguard below; both can fire on the same call.
182
- // Behaviour by mode:
183
- // off — gate skipped entirely (no input fetch, no log).
184
- // shadow — gate runs, verdict logged to close_assessment.metadata.gate_eval,
185
- // close_position always proceeds.
186
- // observe — gate runs; on BLOCK we still proceed but the verdict is logged
187
- // and a warning printed to journalctl.
188
- // enforce — gate runs; on BLOCK we hard-reject with the recovery hint.
189
- const gateMode = deps.exitGateMode ?? loadExitGateMode();
190
- let gateVerdict = null;
191
- // 0a (2026-06-16): hoist the gate inputs to function scope so the post-close
192
- // capture block can persist a full inputs snapshot. Previously `inputs` was a
193
- // block-local const that went out of scope before the capture write, which is
194
- // why only {mode,outcome,tier,code} ever reached the journal (the §5 `inputs`
195
- // snapshot was never constructed). See docs/EXIT_DISCIPLINE_BUILD_PLAN.md
196
- // Step 0a + docs/EXIT_GATE_DESIGN.md §5.
197
- let gateInputs = null;
198
- if (!wave9ExitClaimed && gateMode !== 'off') {
199
- gateInputs = await buildExitGateInputs(args, deps);
200
- gateVerdict = evaluateExitGate(gateInputs);
201
- logger.info(TAG, `exit_gate mode=${gateMode} ${gateVerdict.outcome} tier=${gateVerdict.tier} code=${gateVerdict.code} (symbol=${args.symbol}, reason=${args.reason})`);
202
- if (gateVerdict.outcome === 'BLOCK' && gateMode === 'enforce') {
203
- logger.warn(TAG, `close_position REJECTED by exit gate (enforce): ${gateVerdict.code} — ${gateVerdict.recovery_hint ?? '(no hint)'}`);
204
- return {
205
- error: `close_position blocked by exit gate (${gateVerdict.code}). ` +
206
- (gateVerdict.recovery_hint ?? 'See docs/EXIT_GATE_DESIGN.md.'),
207
- };
208
- }
209
- if (gateVerdict.outcome === 'BLOCK' && gateMode === 'observe') {
210
- logger.warn(TAG, `close_position WOULD BE BLOCKED by exit gate (observe): ${gateVerdict.code} — ${gateVerdict.recovery_hint ?? '(no hint)'} — proceeding because mode=observe`);
211
- }
212
- }
213
- // In paper mode, fetch latest ticker + order book for realistic fills
214
- if (!deps.adapter.isLive) {
215
- try {
216
- const paperDeps = { binanceApi: deps.binanceApi, simulator: deps.adapter.getSimulator() };
217
- const [priceResult] = await Promise.all([
218
- fetchCurrentPrice(args.symbol, paperDeps),
219
- fetchOrderBook(args.symbol, paperDeps),
220
- ]);
221
- if (!isError(priceResult)) {
222
- // The helper updates the simulator mark used by the actual close fill.
223
- }
224
- else {
225
- if (wave9Lease) {
226
- deps.wave9AdmissionGuard.abort(wave9Lease, 'exit_market_data_unavailable', { retryable: true });
227
- wave9Lease = undefined;
228
- }
229
- return priceResult;
230
- }
231
- }
232
- catch (err) {
233
- if (wave9Lease) {
234
- deps.wave9AdmissionGuard.abort(wave9Lease, 'exit_market_data_threw', { retryable: true });
235
- wave9Lease = undefined;
236
- }
237
- return { error: `close_position market-data refresh failed: ${formatError(err)}` };
238
- }
239
- }
240
- // Log the assessment so every agent close is auditable in the journal.
241
- // We log after validation (we've confirmed the shape is sound) and before
242
- // the adapter call so the record is written even if the close fails.
243
- const reason = args.reason;
244
- const summary = formatAssessmentSummary(args.assessment);
245
- logger.info(TAG, `close_position ${args.symbol} reason=${reason}${summary ? ' | ' + summary : ''}`);
246
- // Circuit-breaker: if we've already let 2 bracket_integrity closes through
247
- // in the last hour, the 3rd is almost certainly the audit lying to us
248
- // rather than a real protection failure. Force the operator to either ack
249
- // by retrying with a different reason (regime_flip / risk_limit /
250
- // operator_command) or investigate the bracket subsystem.
251
- if (reason === 'bracket_integrity' && deps.adapter.isLive) {
252
- const now = Date.now();
253
- const windowStart = now - BRACKET_INTEGRITY_WINDOW_MS;
254
- bracketIntegrityCloses = bracketIntegrityCloses.filter(ts => ts >= windowStart);
255
- if (bracketIntegrityCloses.length >= BRACKET_INTEGRITY_LIMIT - 1) {
256
- logger.warn(TAG, `BRACKET-INTEGRITY CIRCUIT-BREAKER TRIPPED for ${args.symbol}: ` +
257
- `${bracketIntegrityCloses.length} prior bracket_integrity closes in the last ` +
258
- `${BRACKET_INTEGRITY_WINDOW_MS / 60_000} min. Refusing the ${bracketIntegrityCloses.length + 1}th. ` +
259
- `Audit-vs-reality bug is likelier than ${bracketIntegrityCloses.length + 1} consecutive real protection losses.`);
260
- return {
261
- error: `close_position rejected: circuit-breaker tripped — ` +
262
- `${bracketIntegrityCloses.length} bracket_integrity closes already fired in the last ` +
263
- `${BRACKET_INTEGRITY_WINDOW_MS / 60_000} min. This pattern almost always means the audit ` +
264
- `is unreliable, not that brackets are repeatedly failing on the exchange. ` +
265
- `Investigation steps: (1) run audit_bracket_protection and inspect 'reason' + ` +
266
- `ledger_state; (2) check the journal for 'AUDIT FLICKER' warnings; ` +
267
- `(3) if you truly need to exit, use reason='operator_command' (bypasses this check) ` +
268
- `or escalate to the operator.`,
269
- };
270
- }
271
- }
272
- // False-bracket_integrity safeguard — see module header comment.
273
- if (reason === 'bracket_integrity' && deps.adapter.isLive) {
274
- const integrity = await verifyBracketsGenuinelyMissing(deps.adapter, args.symbol);
275
- if (integrity.protected) {
276
- logger.warn(TAG, `close_position REJECTED — reason=bracket_integrity but plugin verified brackets live: ${integrity.detail} (symbol=${args.symbol}). This is the audit-vs-reality bug; the position is protected. If you want to close anyway, use reason=regime_flip, risk_limit, or operator_command.`);
277
- return {
278
- error: `close_position rejected: bracket_integrity claim contradicted by plugin (${integrity.detail}). ` +
279
- `Brackets are live on exchange. Use a different reason if you want to exit.`,
280
- };
281
- }
282
- logger.info(TAG, `bracket_integrity safeguard: ${integrity.detail} — allowing close`);
283
- }
284
- try {
285
- const close = async () => {
286
- if (!wave9ExitClaimed && !deps.adapter.isLive && reason !== 'operator_command') {
287
- deps.refreshPaperState?.();
288
- const positions = await deps.adapter.getPositionsOrNull();
289
- if (positions === null) {
290
- // Preserve the existing risk-reduction contract: the extra
291
- // classification read cannot trap an ordinary close.
292
- logger.warn(TAG, 'Wave 9 final close classification unavailable; proceeding risk-reducing fail-open.');
293
- }
294
- else {
295
- const canonical = (value) => value.toUpperCase().replace(/[^A-Z0-9]/g, '').replace(/USDTUSDT$/, 'USDT');
296
- const target = positions.find((position) => canonical(position.symbol) === canonical(args.symbol));
297
- if (target && isWave9ManagedPosition(target)) {
298
- throw new Error(`Generic close_position refused at mutation boundary: ${args.symbol} is now held by Wave 9.`);
299
- }
300
- }
301
- }
302
- if (!wave9ExitClaimed
303
- && deps.adapter.isLive
304
- && reason !== 'operator_command'
305
- && deps.checkWave9LiveSymbolOwnership) {
306
- let ownership;
307
- try {
308
- ownership = await deps.checkWave9LiveSymbolOwnership(args.symbol);
309
- }
310
- catch (err) {
311
- throw new Error(`Generic close_position refused at mutation boundary: Wave 9 LIVE ownership ` +
312
- `check failed for ${args.symbol} (${formatError(err)}).`);
313
- }
314
- if (ownership.status === 'owned' || ownership.status === 'ambiguous') {
315
- throw new Error(`Generic close_position refused at mutation boundary: ${args.symbol} has ` +
316
- `${ownership.status} Wave 9 LIVE ownership (${ownership.reason}). ` +
317
- 'Use get_wave9_status for a reversal authorization or operator_command for an emergency close.');
318
- }
319
- }
320
- return wave9ExitClaimed
321
- ? deps.adapter.closePosition(args.symbol, 'wave9_signal_reversal')
322
- : deps.adapter.closePosition(args.symbol);
323
- };
324
- const closeWave9 = async () => {
325
- if (!wave9Lease)
326
- throw new Error('Wave 9 exit lease is unavailable at mutation boundary.');
327
- if (currentWave9ExecutionMode(deps) !== initialWave9Mode) {
328
- deps.wave9AdmissionGuard.abort(wave9Lease, 'trading_mode_changed_before_exit_mutation', { retryable: true });
329
- wave9Lease = undefined;
330
- throw new Error('Wave 9 reversal close refused: adapter or trading mode changed before mutation.');
331
- }
332
- if (deps.wave9VenueCheck?.() !== 'binance') {
333
- deps.wave9AdmissionGuard.abort(wave9Lease, 'execution_venue_changed_before_exit_mutation', { retryable: true });
334
- wave9Lease = undefined;
335
- throw new Error('Wave 9 reversal close refused: execution venue changed away from Binance before mutation.');
336
- }
337
- let currentFingerprint;
338
- if (initialWave9Mode === 'LIVE') {
339
- const capture = await deps.captureWave9PositionFingerprint(args.symbol);
340
- if (!isWave9ManagedPosition(capture.position)
341
- || capture.position.candidateId !== args.candidate_id
342
- || !capture.position.missionId) {
343
- throw new Error('held live position no longer matches its exact Wave 9 identity');
344
- }
345
- currentFingerprint = capture.fingerprint;
346
- }
347
- else {
348
- deps.refreshPaperState?.();
349
- currentFingerprint = captureWave9PaperPositionFingerprint(deps.adapter, args.symbol).fingerprint;
350
- }
351
- deps.wave9AdmissionGuard.revalidate(wave9Lease, currentFingerprint);
352
- let order;
353
- let closeError;
354
- try {
355
- order = await close();
356
- }
357
- catch (err) {
358
- if (initialWave9Mode !== 'LIVE')
359
- throw err;
360
- closeError = formatError(err);
361
- }
362
- if (initialWave9Mode === 'LIVE') {
363
- const flat = await confirmWave9LivePositionFlat(deps.adapter, args.symbol);
364
- if (!flat.confirmed) {
365
- let protection;
366
- try {
367
- protection = await (deps.reprotectWave9LiveResidual ?? reprotectWave9LiveResidual)(deps.adapter, deps.wave9LiveLedger, args.candidate_id, args.symbol);
368
- }
369
- catch (err) {
370
- deps.wave9AdmissionGuard.abort(wave9Lease, `live_close_residual_reprotection_threw:${formatError(err)}`, { retryable: true });
371
- wave9Lease = undefined;
372
- throw new Error(`CRITICAL: Wave 9 LIVE reversal is not stably flat (${flat.detail}), and residual ` +
373
- `re-protection threw (${formatError(err)}). Durable ownership remains OPEN. ` +
374
- 'IMMEDIATE MANUAL INTERVENTION REQUIRED; a fresh exit authorization may retry.');
375
- }
376
- if (protection.status === 'protected') {
377
- deps.wave9AdmissionGuard.abort(wave9Lease, `live_close_residual_reprotected:${protection.stopClientOrderId ?? 'exact_stop'}`, { retryable: true });
378
- wave9Lease = undefined;
379
- throw new Error(`Wave 9 LIVE reversal close${closeError ? ` threw (${closeError}) and` : ''} left ` +
380
- `${protection.residualQuantity ?? 'a'} residual ` +
381
- `contract position. Durable ownership remains OPEN and the exact frozen stop ` +
382
- `${protection.stopPrice} is proven live; refresh get_wave9_status and use the ` +
383
- 'fresh exit authorization to retry the reduce-only close.');
384
- }
385
- deps.wave9AdmissionGuard.abort(wave9Lease, `live_close_residual_requires_manual_intervention:${protection.detail}`, { retryable: true });
386
- wave9Lease = undefined;
387
- throw new Error(`CRITICAL: Wave 9 LIVE reversal close${closeError ? ` threw (${closeError}) and` : ''} ` +
388
- `stable flat was not confirmed ` +
389
- `(${flat.detail}). Durable ownership remains OPEN. ${protection.detail}`);
390
- }
391
- await deps.wave9LiveLedger.markClosed(args.candidate_id);
392
- }
393
- deps.wave9AdmissionGuard.commit(wave9Lease);
394
- wave9Lease = undefined;
395
- if (closeError) {
396
- throw new Error(`Wave 9 LIVE reversal close acknowledgement failed (${closeError}), but stable flat was ` +
397
- 'proven and durable ownership is CLOSED. Do not retry this candidate.');
398
- }
399
- return order;
400
- };
401
- const order = wave9ExitClaimed
402
- ? await deps.operationLock.withAccountLock(`wave9-close-final:${args.symbol}`, closeWave9)
403
- : reason !== 'operator_command' && deps.operationLock
404
- ? await deps.operationLock.withAccountLock(`generic-close-final:${args.symbol}`, close)
405
- : await close();
406
- // Successful close — record the bracket_integrity timestamp so the
407
- // circuit-breaker can see the trend on the next attempt.
408
- if (reason === 'bracket_integrity' && deps.adapter.isLive) {
409
- bracketIntegrityCloses.push(Date.now());
410
- }
411
- // Auto-capture close to the Position Decision Journal — fail-open.
412
- if (deps.autoCapture) {
413
- const a = args.assessment;
414
- const assessmentForCapture = {
415
- ...a ?? {},
416
- };
417
- if (gateVerdict) {
418
- // 0a: persist the full inputs snapshot + would_have_blocked so shadow
419
- // verdicts are auditable from the journal (EXIT_GATE_DESIGN.md §5).
420
- // Keys are snake_case per the canonical-JSONB-key rule; every input is
421
- // null-coalesced so a MISSING input is recorded explicitly (that is the
422
- // point — it makes the inputs_unavailable_* skips diagnosable). The key
423
- // stays `outcome` (not §5's older `verdict`) to match the 148 historical
424
- // rows. `gateInputs` is non-null whenever `gateVerdict` is set (both are
425
- // assigned together when gateMode!=='off'); `gi` guard is for the type.
426
- const gi = gateInputs;
427
- const stopAtBE = gi && gi.side && typeof gi.stopPrice === 'number' && typeof gi.entryPrice === 'number'
428
- ? gi.side === 'long'
429
- ? gi.stopPrice >= gi.entryPrice
430
- : gi.stopPrice <= gi.entryPrice
431
- : null;
432
- assessmentForCapture.metadata = {
433
- ...assessmentForCapture.metadata ?? {},
434
- gate_eval: {
435
- mode: gateMode,
436
- outcome: gateVerdict.outcome,
437
- tier: gateVerdict.tier,
438
- code: gateVerdict.code,
439
- would_have_blocked: gateVerdict.outcome === 'BLOCK',
440
- ...(gateVerdict.discipline_failure
441
- ? { discipline_failure: gateVerdict.discipline_failure }
442
- : {}),
443
- ...(gi
444
- ? {
445
- inputs: {
446
- mfe_r_peak: gi.mfe_r_peak ?? null,
447
- current_r: gi.current_r ?? null,
448
- stop_at_BE: stopAtBE,
449
- last_review_verdict: gi.lastReview?.verdict ?? null,
450
- last_review_age_minutes: gi.lastReview
451
- ? Math.round((gi.now_ms - gi.lastReview.review_at_ms) / 6000) / 10
452
- : null,
453
- thesis_status: gi.lastReview?.thesis_status ?? null,
454
- // vol_shock is never computed by buildExitGateInputs yet, so
455
- // this is always false until the 3xATR shock is wired — do
456
- // NOT read it as a real signal during the soak.
457
- vol_shock: gi.volShock ?? false,
458
- // Provenance (set in buildExitGateInputs): which source
459
- // supplied each value — makes the inputs_unavailable_* and
460
- // computed-fallback paths diagnosable from the journal.
461
- mfe_src: gi.mfe_src ?? null,
462
- current_r_src: gi.current_r_src ?? null,
463
- },
464
- }
465
- : {}),
466
- },
467
- };
468
- }
469
- // Forensics: snapshot the audit verdict history (last 60min, up to
470
- // 120 samples) so the dashboard Position Timeline drawer can flag
471
- // closes that look like audit-flicker artefacts rather than real
472
- // market exits. The flicker-warn line in journal logs the same data
473
- // in real time; this lets us audit historical closes after the fact.
474
- // 2026-05-15 spiral root-cause work, item #8 of the bundle.
475
- if (deps.adapter.isLive) {
476
- const history = getRecentAuditVerdictHistory(args.symbol);
477
- if (history.length > 0) {
478
- assessmentForCapture.metadata = {
479
- ...assessmentForCapture.metadata ?? {},
480
- bracket_health_history: history,
481
- };
482
- }
483
- }
484
- onClosePositionFilled(deps.autoCapture, {
485
- symbol: args.symbol,
486
- closeReason: reason,
487
- closeAssessment: assessmentForCapture,
488
- scorecardVerdict: typeof a?.current_score === 'number' ? undefined : undefined,
489
- confluenceScore: typeof a?.current_score === 'number' ? a.current_score : undefined,
490
- regime: a?.current_regime,
491
- regimeConfidence: undefined,
492
- }, order).catch((err) => {
493
- // eslint-disable-next-line no-console
494
- console.warn(`[position-auto-capture] close capture threw: ${formatError(err)}`);
495
- });
496
- }
497
- return order;
498
- }
499
- catch (err) {
500
- if (wave9Lease) {
501
- deps.wave9AdmissionGuard.abort(wave9Lease, `exit_execution_failed:${formatError(err)}`, { retryable: initialWave9Mode === 'LIVE' });
502
- wave9Lease = undefined;
503
- }
504
- return { error: formatError(err) };
505
- }
506
- }
507
- /** Independent check used by the bracket_integrity safeguard. Looks at the
508
- * plugin's bracket ledger + a fresh exchange-side open-orders fetch; returns
509
- * `{protected: true}` only when BOTH confirm a live bracket (ledger row in a
510
- * non-terminal state with stored cids, AND at least one exchange order
511
- * carrying a matching `rc-<bracketId>-s` or `rc-<bracketId>-t` cid). Any
512
- * uncertainty (no ledger row, cids not stored, fetch error, nothing on
513
- * exchange) returns `{protected: false}` so the close is allowed — we only
514
- * block when we can definitively prove the audit was wrong. */
515
- async function verifyBracketsGenuinelyMissing(adapter, symbol) {
516
- const ledger = adapter.getBracketLedger?.();
517
- if (!ledger)
518
- return { protected: false, detail: 'brackets disabled' };
519
- const row = ledger.getBySymbol(symbol);
520
- if (!row)
521
- return { protected: false, detail: 'no ledger row' };
522
- const NON_TERMINAL = new Set(['pending_entry', 'attaching', 'active', 'partial']);
523
- if (!NON_TERMINAL.has(row.state)) {
524
- return { protected: false, detail: `ledger state=${row.state} (terminal)` };
525
- }
526
- if (!row.slCid && !row.tpCid) {
527
- return { protected: false, detail: `ledger state=${row.state} but no cids stored` };
528
- }
529
- let open = [];
530
- try {
531
- open = await adapter.getOpenOrders(symbol);
532
- }
533
- catch (err) {
534
- return { protected: false, detail: `getOpenOrders failed: ${formatError(err)}` };
535
- }
536
- const liveCids = new Set();
537
- for (const o of open) {
538
- if (o.clientOrderId)
539
- liveCids.add(o.clientOrderId);
540
- }
541
- const slLive = Boolean(row.slCid && liveCids.has(row.slCid));
542
- const tpLive = Boolean(row.tpCid && liveCids.has(row.tpCid));
543
- // Block the close only when BOTH bracket legs are live — that's the only
544
- // shape that proves the audit was definitively wrong (the original 2026-04-21
545
- // symbol-mapping bug). A position with only one leg live is half-bracketed:
546
- // the audit's `has_stop=false` (or `has_target=false`) is correct, the
547
- // operator/agent needs to flatten or re-attach, and the safeguard would
548
- // wrongly trap them. Per the docstring: only block when we can prove the
549
- // audit was wrong; one-leg-live does not prove that.
550
- if (slLive && tpLive) {
551
- return {
552
- protected: true,
553
- detail: `ledger state=${row.state}, exchange has SL(${row.slCid}) + TP(${row.tpCid}) open (${open.length} total orders on ${symbol})`,
554
- };
555
- }
556
- const observed = [];
557
- if (slLive)
558
- observed.push(`SL(${row.slCid}) only`);
559
- if (tpLive)
560
- observed.push(`TP(${row.tpCid}) only`);
561
- if (observed.length === 0)
562
- observed.push('neither cid on exchange');
563
- return {
564
- protected: false,
565
- detail: `ledger state=${row.state} (slCid=${row.slCid ?? '-'}, tpCid=${row.tpCid ?? '-'}) — ${observed.join(', ')} (${open.length} orders)`,
566
- };
567
- }
568
- /** Gather inputs for the exit gate from adapter + bracket ledger + state store.
569
- * Best-effort: any missing piece becomes `undefined` so the pure gate function
570
- * can decide whether to PASS('skipped') or proceed. Never throws — gate
571
- * evaluation must never crash close_position.
572
- */
573
- async function buildExitGateInputs(args, deps) {
574
- const reason = (args.reason ?? 'regime_flip');
575
- const a = args.assessment;
576
- const inputs = {
577
- reason,
578
- now_ms: Date.now(),
579
- mfe_r_peak: typeof a?.mfe_r_peak === 'number' ? a.mfe_r_peak : undefined,
580
- current_r: typeof a?.r_multiple_at_close === 'number' ? a.r_multiple_at_close : undefined,
581
- };
582
- // Provenance: agent-supplied values win (set the src tags now); the adapter
583
- // and computed fallbacks below only fire when these stay undefined.
584
- if (inputs.mfe_r_peak !== undefined)
585
- inputs.mfe_src = 'assessment';
586
- if (inputs.current_r !== undefined)
587
- inputs.current_r_src = 'assessment';
588
- // Bracket ledger — stop price + (canonical) ledger entry.
589
- // Only LiveAdapter exposes getBracketLedger; paper adapter falls back.
590
- try {
591
- const ledger = deps.adapter.getBracketLedger?.();
592
- if (ledger) {
593
- const row = ledger.getBySymbol(args.symbol);
594
- if (row) {
595
- if (typeof row.stopPrice === 'number' && Number.isFinite(row.stopPrice)) {
596
- inputs.stopPrice = row.stopPrice;
597
- }
598
- if (row.entrySide === 'buy')
599
- inputs.side = 'long';
600
- else if (row.entrySide === 'sell')
601
- inputs.side = 'short';
602
- }
603
- }
604
- }
605
- catch (err) {
606
- logger.warn(TAG, `exit_gate input fetch (bracket ledger): ${formatError(err)}`);
607
- }
608
- // Position — for entryPrice + side fallback, plus mfeR + bracket fallbacks.
609
- // LiveAdapter.getPositions decorates each row with a running mfeR (updated
610
- // from mark price on every call) and a bracket snapshot. When the agent
611
- // omits `assessment.mfe_r_peak` (observed on ~77% of closes during the
612
- // 2026-05-14 shadow soak), we read mfeR from the adapter so the gate can
613
- // still tier the close instead of returning inputs_unavailable_mfe.
614
- try {
615
- const positions = await deps.adapter.getPositions(args.symbol);
616
- const pos = positions.find((p) => p.contracts && p.contracts > 0);
617
- if (pos) {
618
- if (typeof pos.entryPrice === 'number' && Number.isFinite(pos.entryPrice)) {
619
- inputs.entryPrice = pos.entryPrice;
620
- }
621
- if (!inputs.side && pos.side === 'long')
622
- inputs.side = 'long';
623
- if (!inputs.side && pos.side === 'short')
624
- inputs.side = 'short';
625
- if (inputs.mfe_r_peak === undefined
626
- && typeof pos.mfeR === 'number'
627
- && Number.isFinite(pos.mfeR)) {
628
- inputs.mfe_r_peak = pos.mfeR;
629
- inputs.mfe_src = 'pos.mfeR';
630
- }
631
- if (inputs.stopPrice === undefined
632
- && pos.bracket
633
- && typeof pos.bracket.slPrice === 'number'
634
- && Number.isFinite(pos.bracket.slPrice)) {
635
- inputs.stopPrice = pos.bracket.slPrice;
636
- }
637
- // 0b: plugin-computed fallbacks for current_r (SIGNED) + an mfe peak-FLOOR
638
- // when the agent AND the adapter both left them undefined — the
639
- // inputs_unavailable_* skips (~16-30% of evals). R denominator is the
640
- // frozen entry→stop distance (originalStopPrice preferred; else the bracket
641
- // stop resolved above). Both gated on `=== undefined` so agent-supplied
642
- // values still win. current_r MUST stay signed (the T1-escape check
643
- // compares current_r <= -0.5R); the mfe value is a NON-NEGATIVE FLOOR (true
644
- // peak >= current excursion) — it lets the gate tier the close instead of
645
- // skipping, at the cost of under-classifying a round-tripped winner as T1
646
- // (acceptable: errs toward BLOCK in enforce). A position with no frozen
647
- // stop (no originalStopPrice, no bracket) still legitimately skips.
648
- // See docs/EXIT_DISCIPLINE_BUILD_PLAN.md Step 0b.
649
- const denomStop = typeof pos.originalStopPrice === 'number' && Number.isFinite(pos.originalStopPrice)
650
- ? pos.originalStopPrice
651
- : inputs.stopPrice;
652
- if (inputs.side
653
- && typeof pos.entryPrice === 'number' && Number.isFinite(pos.entryPrice)
654
- && typeof pos.markPrice === 'number' && Number.isFinite(pos.markPrice)
655
- && typeof denomStop === 'number' && Number.isFinite(denomStop)) {
656
- const denom = Math.abs(pos.entryPrice - denomStop);
657
- if (denom > 0) {
658
- const fav = inputs.side === 'long'
659
- ? pos.markPrice - pos.entryPrice
660
- : pos.entryPrice - pos.markPrice;
661
- if (inputs.current_r === undefined) {
662
- inputs.current_r = fav / denom; // signed
663
- inputs.current_r_src = 'computed';
664
- }
665
- if (inputs.mfe_r_peak === undefined) {
666
- inputs.mfe_r_peak = Math.max(0, fav / denom); // non-negative floor
667
- inputs.mfe_src = 'computed_floor';
668
- }
669
- }
670
- }
671
- }
672
- }
673
- catch (err) {
674
- logger.warn(TAG, `exit_gate input fetch (positions): ${formatError(err)}`);
675
- }
676
- // Last review — from state store, for contradicts-own-review + review override.
677
- try {
678
- const entry = deps.autoCapture?.stateStore?.get(args.symbol);
679
- if (entry?.lastVerdict && typeof entry.lastReviewAt === 'number') {
680
- inputs.lastReview = {
681
- verdict: entry.lastVerdict,
682
- thesis_status: entry.lastThesisStatus ?? 'intact',
683
- review_at_ms: entry.lastReviewAt,
684
- };
685
- }
686
- }
687
- catch (err) {
688
- logger.warn(TAG, `exit_gate input fetch (state store): ${formatError(err)}`);
689
- }
690
- return inputs;
691
- }
692
- /** Test seam — clears the circuit-breaker state between unit tests. */
693
- export const __testing__ = {
694
- resetCircuitBreaker() {
695
- bracketIntegrityCloses = [];
696
- },
697
- /** Inspect current circuit-breaker state — for assertions. */
698
- getCircuitBreakerCount() {
699
- const windowStart = Date.now() - BRACKET_INTEGRITY_WINDOW_MS;
700
- return bracketIntegrityCloses.filter(ts => ts >= windowStart).length;
701
- },
702
- };
703
- function formatAssessmentSummary(a) {
704
- if (!a)
705
- return '';
706
- const parts = [];
707
- if (typeof a.entry_score === 'number')
708
- parts.push(`entry=${a.entry_score}`);
709
- if (typeof a.current_score === 'number')
710
- parts.push(`current=${a.current_score}`);
711
- if (a.entry_regime)
712
- parts.push(`er=${a.entry_regime}`);
713
- if (a.current_regime)
714
- parts.push(`cr=${a.current_regime}`);
715
- if (a.contradicting_metric)
716
- parts.push(`metric="${a.contradicting_metric.slice(0, 80)}"`);
717
- if (typeof a.position_age_seconds === 'number')
718
- parts.push(`age=${a.position_age_seconds}s`);
719
- if (typeof a.r_multiple_at_close === 'number')
720
- parts.push(`R=${a.r_multiple_at_close}`);
721
- return parts.join(' ');
722
- }