@reefclaw/connect 0.1.10 → 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 (396) hide show
  1. package/assets/bridge/gateway/event-parser.d.ts +6 -1
  2. package/assets/bridge/gateway/event-parser.js +19 -2
  3. package/assets/bridge/gateway/heartbeat-cron.d.ts +27 -0
  4. package/assets/bridge/gateway/heartbeat-cron.js +85 -0
  5. package/assets/bridge/gateway/poller.d.ts +1 -0
  6. package/assets/bridge/gateway/poller.js +14 -2
  7. package/assets/bridge/providers/gateway.d.ts +24 -2
  8. package/assets/bridge/providers/gateway.js +124 -25
  9. package/assets/bridge/setup.js +6 -51
  10. package/assets/shared/signals/conditions/registry.js +11 -2
  11. package/assets/shared/signals/strategy-adapter.js +17 -7
  12. package/assets/skill/SKILL.md +2 -0
  13. package/dist/deps.js +2 -2
  14. package/dist/plugin.js +35 -7
  15. package/package.json +1 -1
  16. package/assets/plugin/audit/mode-transition-audit.d.ts +0 -11
  17. package/assets/plugin/audit/mode-transition-audit.js +0 -29
  18. package/assets/plugin/balance-utils.d.ts +0 -36
  19. package/assets/plugin/balance-utils.js +0 -98
  20. package/assets/plugin/ccxt/binance-ban-gate.d.ts +0 -47
  21. package/assets/plugin/ccxt/binance-ban-gate.js +0 -420
  22. package/assets/plugin/ccxt/binance-private.d.ts +0 -346
  23. package/assets/plugin/ccxt/binance-private.js +0 -1525
  24. package/assets/plugin/ccxt/binance-public.d.ts +0 -34
  25. package/assets/plugin/ccxt/binance-public.js +0 -180
  26. package/assets/plugin/ccxt/intel-public.d.ts +0 -25
  27. package/assets/plugin/ccxt/intel-public.js +0 -80
  28. package/assets/plugin/ccxt/public-market-data-api.d.ts +0 -12
  29. package/assets/plugin/ccxt/public-market-data-api.js +0 -9
  30. package/assets/plugin/config/agent-config-client.d.ts +0 -77
  31. package/assets/plugin/config/agent-config-client.js +0 -188
  32. package/assets/plugin/config/agent-config-poller.d.ts +0 -32
  33. package/assets/plugin/config/agent-config-poller.js +0 -101
  34. package/assets/plugin/config/brackets-config.d.ts +0 -22
  35. package/assets/plugin/config/brackets-config.js +0 -58
  36. package/assets/plugin/config/entitlement-gate.d.ts +0 -51
  37. package/assets/plugin/config/entitlement-gate.js +0 -137
  38. package/assets/plugin/config/gate-store.d.ts +0 -18
  39. package/assets/plugin/config/gate-store.js +0 -61
  40. package/assets/plugin/config/plugin-config-io.d.ts +0 -215
  41. package/assets/plugin/config/plugin-config-io.js +0 -111
  42. package/assets/plugin/config/position-review-config.d.ts +0 -35
  43. package/assets/plugin/config/position-review-config.js +0 -105
  44. package/assets/plugin/config/tool-gate.d.ts +0 -53
  45. package/assets/plugin/config/tool-gate.js +0 -128
  46. package/assets/plugin/config/user-data-stream-config.d.ts +0 -89
  47. package/assets/plugin/config/user-data-stream-config.js +0 -239
  48. package/assets/plugin/connector-supervisor.d.ts +0 -36
  49. package/assets/plugin/connector-supervisor.js +0 -149
  50. package/assets/plugin/exchange-adapter.d.ts +0 -65
  51. package/assets/plugin/exchange-adapter.js +0 -4
  52. package/assets/plugin/index.d.ts +0 -30
  53. package/assets/plugin/index.js +0 -2678
  54. package/assets/plugin/ingest/pending-entry-metadata.d.ts +0 -74
  55. package/assets/plugin/ingest/pending-entry-metadata.js +0 -236
  56. package/assets/plugin/ingest/position-auto-capture.d.ts +0 -103
  57. package/assets/plugin/ingest/position-auto-capture.js +0 -411
  58. package/assets/plugin/ingest/position-decisions-client.d.ts +0 -322
  59. package/assets/plugin/ingest/position-decisions-client.js +0 -296
  60. package/assets/plugin/ingest/readiness-reporter.d.ts +0 -42
  61. package/assets/plugin/ingest/readiness-reporter.js +0 -163
  62. package/assets/plugin/ingest/reconcile-db-vs-exchange.d.ts +0 -13
  63. package/assets/plugin/ingest/reconcile-db-vs-exchange.js +0 -114
  64. package/assets/plugin/ingest/reconciler-cleanup.d.ts +0 -37
  65. package/assets/plugin/ingest/reconciler-cleanup.js +0 -147
  66. package/assets/plugin/ingest/rest-gap-filler.d.ts +0 -191
  67. package/assets/plugin/ingest/rest-gap-filler.js +0 -565
  68. package/assets/plugin/ingest/touched-symbols-store.d.ts +0 -25
  69. package/assets/plugin/ingest/touched-symbols-store.js +0 -96
  70. package/assets/plugin/ingest/trade-store-client.d.ts +0 -40
  71. package/assets/plugin/ingest/trade-store-client.js +0 -125
  72. package/assets/plugin/ingest/ws-ingest.d.ts +0 -43
  73. package/assets/plugin/ingest/ws-ingest.js +0 -126
  74. package/assets/plugin/learning/setup-family.d.ts +0 -21
  75. package/assets/plugin/learning/setup-family.js +0 -103
  76. package/assets/plugin/lifecycle/install-signal-handlers.d.ts +0 -33
  77. package/assets/plugin/lifecycle/install-signal-handlers.js +0 -112
  78. package/assets/plugin/lifecycle/shutdown-coordinator.d.ts +0 -43
  79. package/assets/plugin/lifecycle/shutdown-coordinator.js +0 -131
  80. package/assets/plugin/lifecycle/trading-operation-lock.d.ts +0 -17
  81. package/assets/plugin/lifecycle/trading-operation-lock.js +0 -14
  82. package/assets/plugin/live/bracket-id.d.ts +0 -26
  83. package/assets/plugin/live/bracket-id.js +0 -112
  84. package/assets/plugin/live/bracket-ledger.d.ts +0 -54
  85. package/assets/plugin/live/bracket-ledger.js +0 -267
  86. package/assets/plugin/live/bracket-manager.d.ts +0 -82
  87. package/assets/plugin/live/bracket-manager.js +0 -478
  88. package/assets/plugin/live/bracket-params.d.ts +0 -22
  89. package/assets/plugin/live/bracket-params.js +0 -124
  90. package/assets/plugin/live/bracket-reconciler.d.ts +0 -95
  91. package/assets/plugin/live/bracket-reconciler.js +0 -573
  92. package/assets/plugin/live/bracket-types.d.ts +0 -102
  93. package/assets/plugin/live/bracket-types.js +0 -8
  94. package/assets/plugin/live/deposit-tracker.d.ts +0 -62
  95. package/assets/plugin/live/deposit-tracker.js +0 -97
  96. package/assets/plugin/live/emergency-controls.d.ts +0 -32
  97. package/assets/plugin/live/emergency-controls.js +0 -226
  98. package/assets/plugin/live/exchange-errors.d.ts +0 -12
  99. package/assets/plugin/live/exchange-errors.js +0 -130
  100. package/assets/plugin/live/exchange-info-cache.d.ts +0 -37
  101. package/assets/plugin/live/exchange-info-cache.js +0 -134
  102. package/assets/plugin/live/fact-subscriber.d.ts +0 -78
  103. package/assets/plugin/live/fact-subscriber.js +0 -182
  104. package/assets/plugin/live/intent-journal.d.ts +0 -42
  105. package/assets/plugin/live/intent-journal.js +0 -122
  106. package/assets/plugin/live/listen-key-manager.d.ts +0 -70
  107. package/assets/plugin/live/listen-key-manager.js +0 -169
  108. package/assets/plugin/live/live-adapter.d.ts +0 -287
  109. package/assets/plugin/live/live-adapter.js +0 -1777
  110. package/assets/plugin/live/live-balance-enricher.d.ts +0 -32
  111. package/assets/plugin/live/live-balance-enricher.js +0 -104
  112. package/assets/plugin/live/live-bracket-api.d.ts +0 -13
  113. package/assets/plugin/live/live-bracket-api.js +0 -20
  114. package/assets/plugin/live/live-state-store.d.ts +0 -194
  115. package/assets/plugin/live/live-state-store.js +0 -450
  116. package/assets/plugin/live/local-signal-service.d.ts +0 -57
  117. package/assets/plugin/live/local-signal-service.js +0 -151
  118. package/assets/plugin/live/local-strategy-evaluator.d.ts +0 -62
  119. package/assets/plugin/live/local-strategy-evaluator.js +0 -131
  120. package/assets/plugin/live/microstructure-assembler.d.ts +0 -54
  121. package/assets/plugin/live/microstructure-assembler.js +0 -148
  122. package/assets/plugin/live/order-poller.d.ts +0 -29
  123. package/assets/plugin/live/order-poller.js +0 -125
  124. package/assets/plugin/live/position-state-store.d.ts +0 -83
  125. package/assets/plugin/live/position-state-store.js +0 -237
  126. package/assets/plugin/live/proposal-decision-listener.d.ts +0 -70
  127. package/assets/plugin/live/proposal-decision-listener.js +0 -292
  128. package/assets/plugin/live/proposal-manager.d.ts +0 -76
  129. package/assets/plugin/live/proposal-manager.js +0 -140
  130. package/assets/plugin/live/rate-limiter.d.ts +0 -47
  131. package/assets/plugin/live/rate-limiter.js +0 -159
  132. package/assets/plugin/live/reconciler.d.ts +0 -39
  133. package/assets/plugin/live/reconciler.js +0 -175
  134. package/assets/plugin/live/setup-buckets.d.ts +0 -7
  135. package/assets/plugin/live/setup-buckets.js +0 -33
  136. package/assets/plugin/live/slippage-tracker.d.ts +0 -45
  137. package/assets/plugin/live/slippage-tracker.js +0 -78
  138. package/assets/plugin/live/stop-watcher.d.ts +0 -60
  139. package/assets/plugin/live/stop-watcher.js +0 -215
  140. package/assets/plugin/live/user-data-active-probe.d.ts +0 -54
  141. package/assets/plugin/live/user-data-active-probe.js +0 -180
  142. package/assets/plugin/live/user-data-stream-controller.d.ts +0 -200
  143. package/assets/plugin/live/user-data-stream-controller.js +0 -579
  144. package/assets/plugin/live/user-data-stream-ws.d.ts +0 -22
  145. package/assets/plugin/live/user-data-stream-ws.js +0 -63
  146. package/assets/plugin/live/user-data-stream.d.ts +0 -243
  147. package/assets/plugin/live/user-data-stream.js +0 -704
  148. package/assets/plugin/logger.d.ts +0 -2
  149. package/assets/plugin/logger.js +0 -2
  150. package/assets/plugin/mfe.d.ts +0 -21
  151. package/assets/plugin/mfe.js +0 -68
  152. package/assets/plugin/onboarding/mode-ladder.d.ts +0 -1
  153. package/assets/plugin/onboarding/mode-ladder.js +0 -3
  154. package/assets/plugin/onboarding/runtime.d.ts +0 -84
  155. package/assets/plugin/onboarding/runtime.js +0 -173
  156. package/assets/plugin/openclaw.plugin.json +0 -92
  157. package/assets/plugin/paper-adapter.d.ts +0 -24
  158. package/assets/plugin/paper-adapter.js +0 -91
  159. package/assets/plugin/persistence/state-manager.d.ts +0 -66
  160. package/assets/plugin/persistence/state-manager.js +0 -222
  161. package/assets/plugin/pinned-plan.d.ts +0 -9
  162. package/assets/plugin/pinned-plan.js +0 -23
  163. package/assets/plugin/portfolio/wave9-admission.d.ts +0 -67
  164. package/assets/plugin/portfolio/wave9-admission.js +0 -262
  165. package/assets/plugin/portfolio/wave9-policy.d.ts +0 -36
  166. package/assets/plugin/portfolio/wave9-policy.js +0 -183
  167. package/assets/plugin/risk/pre-trade-check.d.ts +0 -38
  168. package/assets/plugin/risk/pre-trade-check.js +0 -345
  169. package/assets/plugin/risk/pre-trade-types.d.ts +0 -60
  170. package/assets/plugin/risk/pre-trade-types.js +0 -3
  171. package/assets/plugin/shadow/shadow-tracker.d.ts +0 -36
  172. package/assets/plugin/shadow/shadow-tracker.js +0 -151
  173. package/assets/plugin/shadow/types.d.ts +0 -42
  174. package/assets/plugin/shadow/types.js +0 -20
  175. package/assets/plugin/shared/indicators-extended.d.ts +0 -52
  176. package/assets/plugin/shared/indicators-extended.js +0 -291
  177. package/assets/plugin/shared/indicators.d.ts +0 -15
  178. package/assets/plugin/shared/indicators.js +0 -114
  179. package/assets/plugin/signals/conditions/registry.d.ts +0 -16
  180. package/assets/plugin/signals/conditions/registry.js +0 -1324
  181. package/assets/plugin/signals/conditions/types.d.ts +0 -1
  182. package/assets/plugin/signals/conditions/types.js +0 -4
  183. package/assets/plugin/signals/direction-rules.d.ts +0 -3
  184. package/assets/plugin/signals/direction-rules.js +0 -24
  185. package/assets/plugin/signals/entry-rules.d.ts +0 -6
  186. package/assets/plugin/signals/entry-rules.js +0 -33
  187. package/assets/plugin/signals/serialize-context.d.ts +0 -4
  188. package/assets/plugin/signals/serialize-context.js +0 -39
  189. package/assets/plugin/signals/stop-rules.d.ts +0 -3
  190. package/assets/plugin/signals/stop-rules.js +0 -48
  191. package/assets/plugin/signals/strategy-adapter.d.ts +0 -47
  192. package/assets/plugin/signals/strategy-adapter.js +0 -199
  193. package/assets/plugin/signals/types.d.ts +0 -1
  194. package/assets/plugin/signals/types.js +0 -8
  195. package/assets/plugin/simulator/exchange-simulator.d.ts +0 -93
  196. package/assets/plugin/simulator/exchange-simulator.js +0 -689
  197. package/assets/plugin/simulator/fill-engine.d.ts +0 -53
  198. package/assets/plugin/simulator/fill-engine.js +0 -280
  199. package/assets/plugin/simulator/paper-market-feed.d.ts +0 -26
  200. package/assets/plugin/simulator/paper-market-feed.js +0 -104
  201. package/assets/plugin/simulator/realistic-fills.d.ts +0 -59
  202. package/assets/plugin/simulator/realistic-fills.js +0 -175
  203. package/assets/plugin/simulator/types.d.ts +0 -224
  204. package/assets/plugin/simulator/types.js +0 -43
  205. package/assets/plugin/strategy/builtin-strategies.d.ts +0 -2
  206. package/assets/plugin/strategy/builtin-strategies.js +0 -113
  207. package/assets/plugin/strategy/condition-registry.d.ts +0 -3
  208. package/assets/plugin/strategy/condition-registry.js +0 -153
  209. package/assets/plugin/strategy/evaluator.d.ts +0 -70
  210. package/assets/plugin/strategy/evaluator.js +0 -98
  211. package/assets/plugin/tools/assessment-validation.d.ts +0 -120
  212. package/assets/plugin/tools/assessment-validation.js +0 -415
  213. package/assets/plugin/tools/attach-brackets.d.ts +0 -39
  214. package/assets/plugin/tools/attach-brackets.js +0 -399
  215. package/assets/plugin/tools/audit-bracket-protection.d.ts +0 -49
  216. package/assets/plugin/tools/audit-bracket-protection.js +0 -527
  217. package/assets/plugin/tools/cancel-all-orders.d.ts +0 -9
  218. package/assets/plugin/tools/cancel-all-orders.js +0 -8
  219. package/assets/plugin/tools/cancel-order.d.ts +0 -14
  220. package/assets/plugin/tools/cancel-order.js +0 -60
  221. package/assets/plugin/tools/check-position-health.d.ts +0 -46
  222. package/assets/plugin/tools/check-position-health.js +0 -194
  223. package/assets/plugin/tools/clear-exchange-credentials.d.ts +0 -24
  224. package/assets/plugin/tools/clear-exchange-credentials.js +0 -70
  225. package/assets/plugin/tools/close-position.d.ts +0 -45
  226. package/assets/plugin/tools/close-position.js +0 -722
  227. package/assets/plugin/tools/create-order.d.ts +0 -82
  228. package/assets/plugin/tools/create-order.js +0 -1516
  229. package/assets/plugin/tools/exit-gate.d.ts +0 -58
  230. package/assets/plugin/tools/exit-gate.js +0 -162
  231. package/assets/plugin/tools/fetch-balance.d.ts +0 -5
  232. package/assets/plugin/tools/fetch-balance.js +0 -4
  233. package/assets/plugin/tools/fetch-ohlcv.d.ts +0 -11
  234. package/assets/plugin/tools/fetch-ohlcv.js +0 -8
  235. package/assets/plugin/tools/fetch-open-orders.d.ts +0 -7
  236. package/assets/plugin/tools/fetch-open-orders.js +0 -4
  237. package/assets/plugin/tools/fetch-positions.d.ts +0 -7
  238. package/assets/plugin/tools/fetch-positions.js +0 -4
  239. package/assets/plugin/tools/fetch-ticker.d.ts +0 -11
  240. package/assets/plugin/tools/fetch-ticker.js +0 -5
  241. package/assets/plugin/tools/get-agent-profile.d.ts +0 -4
  242. package/assets/plugin/tools/get-agent-profile.js +0 -6
  243. package/assets/plugin/tools/get-analytics.d.ts +0 -6
  244. package/assets/plugin/tools/get-analytics.js +0 -7
  245. package/assets/plugin/tools/get-backtest.d.ts +0 -12
  246. package/assets/plugin/tools/get-backtest.js +0 -91
  247. package/assets/plugin/tools/get-basis.d.ts +0 -7
  248. package/assets/plugin/tools/get-basis.js +0 -7
  249. package/assets/plugin/tools/get-bracket-config.d.ts +0 -11
  250. package/assets/plugin/tools/get-bracket-config.js +0 -24
  251. package/assets/plugin/tools/get-cascade-risk.d.ts +0 -7
  252. package/assets/plugin/tools/get-cascade-risk.js +0 -8
  253. package/assets/plugin/tools/get-crypto-metrics.d.ts +0 -18
  254. package/assets/plugin/tools/get-crypto-metrics.js +0 -62
  255. package/assets/plugin/tools/get-cvd.d.ts +0 -6
  256. package/assets/plugin/tools/get-cvd.js +0 -6
  257. package/assets/plugin/tools/get-divergences.d.ts +0 -6
  258. package/assets/plugin/tools/get-divergences.js +0 -6
  259. package/assets/plugin/tools/get-funding-context.d.ts +0 -6
  260. package/assets/plugin/tools/get-funding-context.js +0 -16
  261. package/assets/plugin/tools/get-liquidation-levels.d.ts +0 -7
  262. package/assets/plugin/tools/get-liquidation-levels.js +0 -7
  263. package/assets/plugin/tools/get-liquidation-pulse.d.ts +0 -9
  264. package/assets/plugin/tools/get-liquidation-pulse.js +0 -22
  265. package/assets/plugin/tools/get-market-breadth.d.ts +0 -6
  266. package/assets/plugin/tools/get-market-breadth.js +0 -8
  267. package/assets/plugin/tools/get-market-intel.d.ts +0 -19
  268. package/assets/plugin/tools/get-market-intel.js +0 -116
  269. package/assets/plugin/tools/get-market-structure.d.ts +0 -47
  270. package/assets/plugin/tools/get-market-structure.js +0 -198
  271. package/assets/plugin/tools/get-my-mined-patterns.d.ts +0 -20
  272. package/assets/plugin/tools/get-my-mined-patterns.js +0 -61
  273. package/assets/plugin/tools/get-my-proposed-learnings.d.ts +0 -20
  274. package/assets/plugin/tools/get-my-proposed-learnings.js +0 -55
  275. package/assets/plugin/tools/get-my-recent-reviews.d.ts +0 -22
  276. package/assets/plugin/tools/get-my-recent-reviews.js +0 -66
  277. package/assets/plugin/tools/get-orderbook.d.ts +0 -21
  278. package/assets/plugin/tools/get-orderbook.js +0 -32
  279. package/assets/plugin/tools/get-pattern-scan.d.ts +0 -7
  280. package/assets/plugin/tools/get-pattern-scan.js +0 -8
  281. package/assets/plugin/tools/get-regime.d.ts +0 -6
  282. package/assets/plugin/tools/get-regime.js +0 -7
  283. package/assets/plugin/tools/get-relevant-learnings.d.ts +0 -21
  284. package/assets/plugin/tools/get-relevant-learnings.js +0 -65
  285. package/assets/plugin/tools/get-resting-liquidity.d.ts +0 -6
  286. package/assets/plugin/tools/get-resting-liquidity.js +0 -11
  287. package/assets/plugin/tools/get-risk-scenario.d.ts +0 -29
  288. package/assets/plugin/tools/get-risk-scenario.js +0 -47
  289. package/assets/plugin/tools/get-risk-summary.d.ts +0 -51
  290. package/assets/plugin/tools/get-risk-summary.js +0 -118
  291. package/assets/plugin/tools/get-sentiment.d.ts +0 -4
  292. package/assets/plugin/tools/get-sentiment.js +0 -6
  293. package/assets/plugin/tools/get-session-review.d.ts +0 -7
  294. package/assets/plugin/tools/get-session-review.js +0 -8
  295. package/assets/plugin/tools/get-setup-detail.d.ts +0 -7
  296. package/assets/plugin/tools/get-setup-detail.js +0 -311
  297. package/assets/plugin/tools/get-signals.d.ts +0 -15
  298. package/assets/plugin/tools/get-signals.js +0 -54
  299. package/assets/plugin/tools/get-sizing.d.ts +0 -6
  300. package/assets/plugin/tools/get-sizing.js +0 -6
  301. package/assets/plugin/tools/get-trade-feedback.d.ts +0 -7
  302. package/assets/plugin/tools/get-trade-feedback.js +0 -8
  303. package/assets/plugin/tools/get-trade-flow.d.ts +0 -7
  304. package/assets/plugin/tools/get-trade-flow.js +0 -7
  305. package/assets/plugin/tools/get-volume-analysis.d.ts +0 -21
  306. package/assets/plugin/tools/get-volume-analysis.js +0 -74
  307. package/assets/plugin/tools/get-volume-profile.d.ts +0 -7
  308. package/assets/plugin/tools/get-volume-profile.js +0 -7
  309. package/assets/plugin/tools/get-wave9-status.d.ts +0 -127
  310. package/assets/plugin/tools/get-wave9-status.js +0 -796
  311. package/assets/plugin/tools/helpers.d.ts +0 -26
  312. package/assets/plugin/tools/helpers.js +0 -39
  313. package/assets/plugin/tools/intel-api.d.ts +0 -34
  314. package/assets/plugin/tools/intel-api.js +0 -119
  315. package/assets/plugin/tools/intel-cache.d.ts +0 -25
  316. package/assets/plugin/tools/intel-cache.js +0 -148
  317. package/assets/plugin/tools/list-strategies.d.ts +0 -17
  318. package/assets/plugin/tools/list-strategies.js +0 -23
  319. package/assets/plugin/tools/modify-stop.d.ts +0 -21
  320. package/assets/plugin/tools/modify-stop.js +0 -120
  321. package/assets/plugin/tools/modify-target.d.ts +0 -21
  322. package/assets/plugin/tools/modify-target.js +0 -110
  323. package/assets/plugin/tools/propose-learning.d.ts +0 -22
  324. package/assets/plugin/tools/propose-learning.js +0 -65
  325. package/assets/plugin/tools/query-review-outcomes.d.ts +0 -30
  326. package/assets/plugin/tools/query-review-outcomes.js +0 -64
  327. package/assets/plugin/tools/query-trades.d.ts +0 -21
  328. package/assets/plugin/tools/query-trades.js +0 -37
  329. package/assets/plugin/tools/record-position-reviews.d.ts +0 -38
  330. package/assets/plugin/tools/record-position-reviews.js +0 -147
  331. package/assets/plugin/tools/save-strategy.d.ts +0 -16
  332. package/assets/plugin/tools/save-strategy.js +0 -46
  333. package/assets/plugin/tools/scan-pairs.d.ts +0 -18
  334. package/assets/plugin/tools/scan-pairs.js +0 -231
  335. package/assets/plugin/tools/score-setup.d.ts +0 -31
  336. package/assets/plugin/tools/score-setup.js +0 -268
  337. package/assets/plugin/tools/set-bracket-requirement.d.ts +0 -18
  338. package/assets/plugin/tools/set-bracket-requirement.js +0 -81
  339. package/assets/plugin/tools/set-exchange-credentials.d.ts +0 -25
  340. package/assets/plugin/tools/set-exchange-credentials.js +0 -80
  341. package/assets/plugin/tools/set-trading-mode.d.ts +0 -26
  342. package/assets/plugin/tools/set-trading-mode.js +0 -135
  343. package/assets/plugin/tools/test-exchange-credentials.d.ts +0 -16
  344. package/assets/plugin/tools/test-exchange-credentials.js +0 -100
  345. package/assets/plugin/tools/toggle-strategy.d.ts +0 -8
  346. package/assets/plugin/tools/toggle-strategy.js +0 -15
  347. package/assets/plugin/trading-params-cache.d.ts +0 -26
  348. package/assets/plugin/trading-params-cache.js +0 -52
  349. package/assets/plugin/types.d.ts +0 -134
  350. package/assets/plugin/types.js +0 -7
  351. package/assets/plugin/util/plugin-paths.d.ts +0 -3
  352. package/assets/plugin/util/plugin-paths.js +0 -15
  353. package/assets/plugin/venues/hyperliquid/hl-balance.d.ts +0 -116
  354. package/assets/plugin/venues/hyperliquid/hl-balance.js +0 -145
  355. package/assets/plugin/venues/hyperliquid/hl-brackets.d.ts +0 -102
  356. package/assets/plugin/venues/hyperliquid/hl-brackets.js +0 -172
  357. package/assets/plugin/venues/hyperliquid/hl-cloid.d.ts +0 -22
  358. package/assets/plugin/venues/hyperliquid/hl-cloid.js +0 -82
  359. package/assets/plugin/venues/hyperliquid/hl-info-cache.d.ts +0 -46
  360. package/assets/plugin/venues/hyperliquid/hl-info-cache.js +0 -125
  361. package/assets/plugin/venues/hyperliquid/hl-live-adapter.d.ts +0 -88
  362. package/assets/plugin/venues/hyperliquid/hl-live-adapter.js +0 -353
  363. package/assets/plugin/venues/hyperliquid/hl-precision.d.ts +0 -61
  364. package/assets/plugin/venues/hyperliquid/hl-precision.js +0 -176
  365. package/assets/plugin/venues/hyperliquid/hl-private.d.ts +0 -88
  366. package/assets/plugin/venues/hyperliquid/hl-private.js +0 -357
  367. package/assets/plugin/venues/hyperliquid/hl-public.d.ts +0 -79
  368. package/assets/plugin/venues/hyperliquid/hl-public.js +0 -429
  369. package/assets/plugin/venues/hyperliquid/hl-rate-gate.d.ts +0 -57
  370. package/assets/plugin/venues/hyperliquid/hl-rate-gate.js +0 -220
  371. package/assets/plugin/venues/hyperliquid/hl-user-stream.d.ts +0 -90
  372. package/assets/plugin/venues/hyperliquid/hl-user-stream.js +0 -220
  373. package/assets/plugin/venues/registry.d.ts +0 -38
  374. package/assets/plugin/venues/registry.js +0 -46
  375. package/assets/plugin/venues/symbols.d.ts +0 -43
  376. package/assets/plugin/venues/symbols.js +0 -107
  377. package/assets/plugin/wave9/live-account-capture.d.ts +0 -67
  378. package/assets/plugin/wave9/live-account-capture.js +0 -435
  379. package/assets/plugin/wave9/live-autonomous-protection.d.ts +0 -39
  380. package/assets/plugin/wave9/live-autonomous-protection.js +0 -112
  381. package/assets/plugin/wave9/live-durable-reconciliation-scheduler.d.ts +0 -33
  382. package/assets/plugin/wave9/live-durable-reconciliation-scheduler.js +0 -115
  383. package/assets/plugin/wave9/live-execution-ledger.d.ts +0 -107
  384. package/assets/plugin/wave9/live-execution-ledger.js +0 -498
  385. package/assets/plugin/wave9/live-position-confirmation.d.ts +0 -18
  386. package/assets/plugin/wave9/live-position-confirmation.js +0 -111
  387. package/assets/plugin/wave9/live-residual-protection.d.ts +0 -18
  388. package/assets/plugin/wave9/live-residual-protection.js +0 -250
  389. package/assets/plugin/wave9/live-startup-reconciliation.d.ts +0 -38
  390. package/assets/plugin/wave9/live-startup-reconciliation.js +0 -454
  391. package/assets/plugin/wave9/live-symbol-ownership.d.ts +0 -20
  392. package/assets/plugin/wave9/live-symbol-ownership.js +0 -132
  393. package/assets/plugin/wave9/paper-admission-guard.d.ts +0 -199
  394. package/assets/plugin/wave9/paper-admission-guard.js +0 -650
  395. package/assets/plugin/wave9/usdm-evidence-provider.d.ts +0 -42
  396. package/assets/plugin/wave9/usdm-evidence-provider.js +0 -133
@@ -1,650 +0,0 @@
1
- import { createHash, randomBytes, timingSafeEqual } from 'node:crypto';
2
- import { WAVE9_SYMBOL_PRIORITY } from '../portfolio/wave9-policy.js';
3
- /** One catalog toggle represents both frozen Wave 9 strategy legs. */
4
- export const WAVE9_BUNDLE_SETUP_TYPE = 'wave9_28d_momentum_reversal';
5
- export const WAVE9_MECHANICAL_EXIT_REASON = 'wave9_signal_reversal';
6
- /** Conservative shared identity check for current, legacy, or Wave 9-mission positions. */
7
- export function isWave9ManagedPosition(position) {
8
- return position.setupType === WAVE9_BUNDLE_SETUP_TYPE
9
- || position.setupType === 'wave9_daily_tsmom'
10
- || position.missionId?.startsWith('wave9_') === true;
11
- }
12
- const TOKEN_PATTERN = /^w9[ex]_[A-Za-z0-9_-]{43}$/;
13
- const FINGERPRINT_PATTERN = /^[a-f0-9]{64}$/;
14
- const DECIMAL_PATTERN = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
15
- const MAX_ID_LENGTH = 512;
16
- export class Wave9PaperAdmissionGuardError extends Error {
17
- constructor(message) {
18
- super(message);
19
- this.name = 'Wave9PaperAdmissionGuardError';
20
- }
21
- }
22
- function canonicalSymbol(symbol) {
23
- return symbol.toUpperCase().replace(/[^A-Z0-9]/g, '').replace(/USDTUSDT$/, 'USDT');
24
- }
25
- function requireFinite(value, label) {
26
- if (!Number.isFinite(value))
27
- throw new Wave9PaperAdmissionGuardError(`${label} must be finite`);
28
- }
29
- function finiteOrNull(value) {
30
- return typeof value === 'number' && Number.isFinite(value) ? value : null;
31
- }
32
- function exactPositiveNumber(value, label) {
33
- if (typeof value !== 'string' || !DECIMAL_PATTERN.test(value)) {
34
- throw new Wave9PaperAdmissionGuardError(`${label} must be an exact decimal string`);
35
- }
36
- const parsed = Number(value);
37
- if (!Number.isFinite(parsed) || parsed <= 0 || String(parsed) !== value) {
38
- throw new Wave9PaperAdmissionGuardError(`${label} must be the canonical string form of a positive finite number`);
39
- }
40
- return parsed;
41
- }
42
- function exactText(value, label) {
43
- if (typeof value !== 'string' || value.length === 0 || value.length > MAX_ID_LENGTH || value.trim() !== value) {
44
- throw new Wave9PaperAdmissionGuardError(`${label} is malformed`);
45
- }
46
- }
47
- function requireExecutionMode(value) {
48
- if (value !== 'PAPER' && value !== 'LIVE') {
49
- throw new Wave9PaperAdmissionGuardError('Wave 9 execution mode must be PAPER or LIVE');
50
- }
51
- }
52
- function sameSecret(left, right) {
53
- const a = Buffer.from(left);
54
- const b = Buffer.from(right);
55
- return a.length === b.length && timingSafeEqual(a, b);
56
- }
57
- function stableMissionId(candidateId) {
58
- return `wave9_${createHash('sha256').update(candidateId).digest('hex').slice(0, 32)}`;
59
- }
60
- function parseEntryCandidate(decision) {
61
- const parts = decision.candidateId.split('|');
62
- if (parts.length !== 4)
63
- throw new Wave9PaperAdmissionGuardError('candidateId is not a frozen Wave 9 identity');
64
- const [eventTime, symbol, strategy, direction] = parts;
65
- const eventMs = Date.parse(eventTime);
66
- if (!Number.isFinite(eventMs) || new Date(eventMs).toISOString() !== eventTime) {
67
- throw new Wave9PaperAdmissionGuardError('candidateId event time is not canonical ISO');
68
- }
69
- if (symbol !== decision.symbol || !['LONG', 'SHORT'].includes(direction)) {
70
- throw new Wave9PaperAdmissionGuardError('candidateId does not match symbol/direction');
71
- }
72
- if ((direction === 'LONG' && strategy !== 'tsmom_28d_long_flat_reversal_1d')
73
- || (direction === 'SHORT' && strategy !== 'tsmom_28d_short_flat_reversal_1d')) {
74
- throw new Wave9PaperAdmissionGuardError('candidateId does not name a frozen Wave 9 leg');
75
- }
76
- if ((direction === 'LONG' ? 'BUY' : 'SELL') !== decision.side) {
77
- throw new Wave9PaperAdmissionGuardError('entry side does not match candidate direction');
78
- }
79
- return { eventTime, direction: direction };
80
- }
81
- /**
82
- * Capture the complete process-local book inputs used to defend a Wave 9
83
- * admission against local TOCTOU. This is deliberately labelled non-
84
- * authoritative: the production paper deployment has no cross-process owner
85
- * lease, so a matching hash is useful fail-closed protection, never parity or
86
- * promotion evidence.
87
- */
88
- export function captureWave9PaperAccountSnapshot(adapter) {
89
- if (adapter.isLive) {
90
- throw new Wave9PaperAdmissionGuardError('Wave 9 paper account capture hard-refuses a live adapter');
91
- }
92
- const simulator = adapter.getSimulator?.();
93
- if (!simulator) {
94
- throw new Wave9PaperAdmissionGuardError('Wave 9 account fingerprint requires a local paper simulator');
95
- }
96
- const state = simulator.getState();
97
- const quoteCurrency = state.config.quoteCurrency;
98
- const positions = state.positions.map((position) => {
99
- const markPrice = simulator.getLastTicker(position.symbol)?.last ?? position.entryPrice;
100
- const stopPrice = finiteOrNull(position.metadata?.originalStopPrice ?? position.metadata?.stopPrice);
101
- return {
102
- symbol: position.symbol,
103
- side: position.side,
104
- quantity: position.quantity,
105
- entryPrice: position.entryPrice,
106
- markPrice,
107
- openedAt: position.openedAt,
108
- missionId: position.metadata?.missionId ?? null,
109
- setupType: position.metadata?.setupType ?? null,
110
- candidateId: position.metadata?.candidateId ?? null,
111
- strategy: position.metadata?.strategy ?? null,
112
- accruedFundingUsd: finiteOrNull(position.metadata?.accruedFundingUsd),
113
- fundingThroughTime: position.metadata?.fundingThroughTime ?? null,
114
- stopPrice,
115
- initialOpenRiskUsd: stopPrice === null
116
- ? null
117
- : Math.abs(position.entryPrice - stopPrice) * position.quantity,
118
- };
119
- }).sort((left, right) => left.symbol.localeCompare(right.symbol)
120
- || left.side.localeCompare(right.side)
121
- || left.openedAt.localeCompare(right.openedAt));
122
- const openOrders = state.openOrders.map((order) => ({
123
- id: order.id,
124
- symbol: order.symbol,
125
- side: order.side,
126
- type: order.type,
127
- amount: order.amount,
128
- filled: order.filled,
129
- price: finiteOrNull(order.price),
130
- })).sort((left, right) => left.id.localeCompare(right.id));
131
- const snapshot = {
132
- schema: 'wave9-paper-account-v1',
133
- savedAt: finiteOrNull(state.savedAt),
134
- quoteCurrency,
135
- wallet: Object.entries(state.wallet).map(([currency, balance]) => ({
136
- currency,
137
- total: balance.total,
138
- available: balance.available,
139
- locked: balance.locked,
140
- })).sort((left, right) => left.currency.localeCompare(right.currency)),
141
- equityUsd: simulator.computeEquity(),
142
- sessionStartNavUsd: finiteOrNull(state.sessionStartNav),
143
- positions,
144
- openOrders,
145
- closedWave9CandidateIds: [...new Set(state.tradeHistory
146
- .filter((trade) => isWave9ManagedPosition(trade.metadata ?? {}))
147
- .map((trade) => trade.metadata?.candidateId)
148
- .filter((candidateId) => typeof candidateId === 'string' && candidateId.length > 0))]
149
- .sort((left, right) => left.localeCompare(right)),
150
- };
151
- const fingerprint = createHash('sha256').update(JSON.stringify(snapshot)).digest('hex');
152
- return {
153
- fingerprint,
154
- snapshot,
155
- authoritative: false,
156
- runtimeParity: false,
157
- provenance: 'process_local_unlocked_simulator',
158
- };
159
- }
160
- /** Stable held-position identity for a mechanical reversal close. */
161
- export function captureWave9PaperPositionFingerprint(adapter, symbol) {
162
- const account = captureWave9PaperAccountSnapshot(adapter);
163
- const canonical = canonicalSymbol(symbol);
164
- const matches = account.snapshot.positions.filter((position) => canonicalSymbol(position.symbol) === canonical);
165
- if (matches.length !== 1) {
166
- throw new Wave9PaperAdmissionGuardError(`Wave 9 exit fingerprint requires exactly one held ${canonical} position`);
167
- }
168
- const row = matches[0];
169
- const snapshot = {
170
- symbol: row.symbol,
171
- side: row.side,
172
- quantity: row.quantity,
173
- entryPrice: row.entryPrice,
174
- openedAt: row.openedAt,
175
- missionId: row.missionId,
176
- setupType: row.setupType,
177
- candidateId: row.candidateId,
178
- strategy: row.strategy,
179
- stopPrice: row.stopPrice,
180
- initialOpenRiskUsd: row.initialOpenRiskUsd,
181
- };
182
- return {
183
- fingerprint: createHash('sha256').update(JSON.stringify(snapshot)).digest('hex'),
184
- snapshot,
185
- authoritative: false,
186
- runtimeParity: false,
187
- provenance: 'process_local_unlocked_simulator',
188
- };
189
- }
190
- /** In-memory capability guard shared by get_wave9_status and mutation tools. */
191
- export class Wave9PaperAdmissionGuard {
192
- now;
193
- tokenTtlMs;
194
- batches = new Map();
195
- events = new Map();
196
- entriesByToken = new Map();
197
- exitsByIdentity = new Map();
198
- exitsByToken = new Map();
199
- constructor(options = {}) {
200
- this.now = options.now ?? Date.now;
201
- this.tokenTtlMs = options.tokenTtlMs ?? 120_000;
202
- if (!Number.isFinite(this.tokenTtlMs) || this.tokenTtlMs <= 0 || this.tokenTtlMs > 10 * 60_000) {
203
- throw new Wave9PaperAdmissionGuardError('tokenTtlMs must be in (0, 600000]');
204
- }
205
- }
206
- issueBatch(decisions) {
207
- if (decisions.length === 0)
208
- throw new Wave9PaperAdmissionGuardError('cannot issue an empty admission batch');
209
- if (decisions.length !== 1) {
210
- throw new Wave9PaperAdmissionGuardError('only the next accepted Wave 9 candidate may be authorized; re-evaluate the actual book after its fill');
211
- }
212
- const sorted = decisions.map((decision) => ({ ...decision })).sort((a, b) => a.sequence - b.sequence);
213
- const first = sorted[0];
214
- exactText(first.batchId, 'batchId');
215
- requireExecutionMode(first.tradingMode);
216
- if (!FINGERPRINT_PATTERN.test(first.accountFingerprint)) {
217
- throw new Wave9PaperAdmissionGuardError('accountFingerprint is malformed');
218
- }
219
- let eventTime = '';
220
- const identities = new Set();
221
- for (const decision of sorted) {
222
- if (!Number.isInteger(decision.sequence) || decision.sequence < 0) {
223
- throw new Wave9PaperAdmissionGuardError('entry sequence must be a non-negative integer');
224
- }
225
- requireExecutionMode(decision.tradingMode);
226
- if (decision.batchId !== first.batchId
227
- || decision.accountFingerprint !== first.accountFingerprint
228
- || decision.tradingMode !== first.tradingMode) {
229
- throw new Wave9PaperAdmissionGuardError('one batch must share batchId, accountFingerprint, and tradingMode');
230
- }
231
- exactText(decision.candidateId, 'candidateId');
232
- exactText(decision.missionId, 'missionId');
233
- if (identities.has(decision.candidateId))
234
- throw new Wave9PaperAdmissionGuardError('duplicate candidateId');
235
- identities.add(decision.candidateId);
236
- if (!WAVE9_SYMBOL_PRIORITY.includes(decision.symbol)) {
237
- throw new Wave9PaperAdmissionGuardError(`unsupported Wave 9 symbol ${decision.symbol}`);
238
- }
239
- const parsed = parseEntryCandidate(decision);
240
- if (eventTime && parsed.eventTime !== eventTime) {
241
- throw new Wave9PaperAdmissionGuardError('one admission batch must share an eventTime');
242
- }
243
- eventTime = parsed.eventTime;
244
- if (decision.missionId !== stableMissionId(decision.candidateId)) {
245
- throw new Wave9PaperAdmissionGuardError('missionId does not match stable candidate identity');
246
- }
247
- exactPositiveNumber(decision.quantity, 'quantity');
248
- exactPositiveNumber(decision.stopPrice, 'stopPrice');
249
- this.validateWindow(decision.notBeforeMs, decision.deadlineMs);
250
- }
251
- const event = this.events.get(eventTime) ?? { consumedCandidateIds: new Set() };
252
- this.events.set(eventTime, event);
253
- if (event.latchedReason || event.inFlightCandidateId)
254
- return [];
255
- if (event.consumedCandidateIds.has(first.candidateId))
256
- return [];
257
- let batch = this.batches.get(first.batchId);
258
- if (!batch) {
259
- // Invalidate every untouched capability for this event before binding a
260
- // newly evaluated fingerprint. Only one current mutation capability may
261
- // exist even when status uses fingerprinted batch IDs.
262
- for (const prior of this.batches.values()) {
263
- if (prior.eventTime !== eventTime)
264
- continue;
265
- for (const record of prior.records) {
266
- if (record.status !== 'issued')
267
- continue;
268
- this.entriesByToken.delete(record.token);
269
- record.status = 'consumed';
270
- record.retryableAfterAbort = false;
271
- }
272
- }
273
- batch = {
274
- batchId: first.batchId,
275
- accountFingerprint: first.accountFingerprint,
276
- eventTime,
277
- nextSequence: first.sequence,
278
- records: sorted.map((decision) => this.newEntryRecord(decision)),
279
- };
280
- this.batches.set(first.batchId, batch);
281
- for (const record of batch.records)
282
- this.entriesByToken.set(record.token, record);
283
- }
284
- else {
285
- const old = batch.records[0];
286
- const same = batch.eventTime === eventTime
287
- && batch.accountFingerprint === first.accountFingerprint
288
- && this.sameEntryDecision(old, first);
289
- if (same && old.status === 'consumed' && old.retryableAfterAbort) {
290
- this.entriesByToken.delete(old.token);
291
- batch = {
292
- batchId: first.batchId,
293
- accountFingerprint: first.accountFingerprint,
294
- eventTime,
295
- nextSequence: first.sequence,
296
- records: [this.newEntryRecord(first)],
297
- };
298
- this.batches.set(first.batchId, batch);
299
- this.entriesByToken.set(batch.records[0].token, batch.records[0]);
300
- }
301
- else if (!same) {
302
- if (old.status === 'in_flight') {
303
- throw new Wave9PaperAdmissionGuardError('cannot replace an in-flight Wave 9 admission');
304
- }
305
- if (old.status === 'consumed'
306
- && !old.retryableAfterAbort
307
- && !event.consumedCandidateIds.has(old.candidateId)) {
308
- throw new Wave9PaperAdmissionGuardError('cannot replace an attempted Wave 9 admission');
309
- }
310
- this.entriesByToken.delete(old.token);
311
- batch = {
312
- batchId: first.batchId,
313
- accountFingerprint: first.accountFingerprint,
314
- eventTime,
315
- nextSequence: first.sequence,
316
- records: [this.newEntryRecord(first)],
317
- };
318
- this.batches.set(first.batchId, batch);
319
- this.entriesByToken.set(batch.records[0].token, batch.records[0]);
320
- }
321
- }
322
- if (batch.latchedReason)
323
- return [];
324
- const now = this.now();
325
- const issued = [];
326
- for (const record of batch.records) {
327
- if (record.status === 'consumed' || record.sequence < batch.nextSequence || record.deadlineMs <= now)
328
- continue;
329
- if (record.status === 'issued' && record.tokenDeadlineMs <= now)
330
- this.rotateEntryToken(record);
331
- if (record.status !== 'issued')
332
- continue;
333
- issued.push({
334
- token: record.token,
335
- batchId: record.batchId,
336
- candidateId: record.candidateId,
337
- missionId: record.missionId,
338
- sequence: record.sequence,
339
- deadlineMs: record.tokenDeadlineMs,
340
- accountFingerprint: record.accountFingerprint,
341
- tradingMode: record.tradingMode,
342
- });
343
- }
344
- return issued;
345
- }
346
- issueExitBatch(decisions) {
347
- if (decisions.length === 0)
348
- throw new Wave9PaperAdmissionGuardError('cannot issue an empty exit batch');
349
- const now = this.now();
350
- const seen = new Set();
351
- const issued = [];
352
- for (const input of decisions) {
353
- const decision = { ...input };
354
- this.validateExitDecision(decision);
355
- const identity = this.exitIdentity(decision);
356
- if (seen.has(identity))
357
- throw new Wave9PaperAdmissionGuardError('duplicate exit identity');
358
- seen.add(identity);
359
- let record = this.exitsByIdentity.get(identity);
360
- if (record) {
361
- // A reduce-only LIVE close can have an ambiguous response or leave a
362
- // partial position. Once its in-flight lease is explicitly aborted as
363
- // retryable, a fresh trusted position snapshot must be able to issue a
364
- // new authorization even though the residual fingerprint changed.
365
- // Evaluate that terminal retry state before exact-decision replacement;
366
- // otherwise the changed fingerprint is rejected as an attempted exit.
367
- if (record.status === 'consumed' && record.retryableAfterAbort) {
368
- this.exitsByToken.delete(record.token);
369
- record = this.newExitRecord(decision);
370
- this.exitsByIdentity.set(identity, record);
371
- this.exitsByToken.set(record.token, record);
372
- }
373
- else {
374
- const same = this.sameExitDecision(record, decision);
375
- if (!same && record.status === 'issued') {
376
- this.exitsByToken.delete(record.token);
377
- record = this.newExitRecord(decision);
378
- this.exitsByIdentity.set(identity, record);
379
- this.exitsByToken.set(record.token, record);
380
- }
381
- else if (!same) {
382
- throw new Wave9PaperAdmissionGuardError('cannot replace an attempted Wave 9 exit authorization');
383
- }
384
- if (record.status === 'consumed')
385
- continue;
386
- if (record.status === 'issued' && record.tokenDeadlineMs <= now && record.deadlineMs > now) {
387
- this.rotateExitToken(record);
388
- }
389
- }
390
- }
391
- else {
392
- record = this.newExitRecord(decision);
393
- this.exitsByIdentity.set(identity, record);
394
- this.exitsByToken.set(record.token, record);
395
- }
396
- if (record.status === 'issued' && record.deadlineMs > now) {
397
- issued.push({
398
- token: record.token,
399
- candidateId: record.candidateId,
400
- missionId: record.missionId,
401
- deadlineMs: record.tokenDeadlineMs,
402
- positionFingerprint: record.positionFingerprint,
403
- tradingMode: record.tradingMode,
404
- });
405
- }
406
- }
407
- return issued;
408
- }
409
- beginEntry(request) {
410
- this.validateTokenShape(request.token, 'entry');
411
- const record = this.entriesByToken.get(request.token);
412
- if (!record || !sameSecret(record.token, request.token))
413
- throw new Wave9PaperAdmissionGuardError('unknown Wave 9 admission token');
414
- const batch = this.batches.get(record.batchId);
415
- if (!batch)
416
- throw new Wave9PaperAdmissionGuardError('Wave 9 admission batch is unavailable');
417
- if (batch.latchedReason)
418
- throw new Wave9PaperAdmissionGuardError(`Wave 9 admission batch is latched: ${batch.latchedReason}`);
419
- this.assertUsable(record);
420
- if (record.sequence !== batch.nextSequence) {
421
- throw new Wave9PaperAdmissionGuardError(`Wave 9 admission sequence ${record.sequence} cannot run before ${batch.nextSequence}`);
422
- }
423
- const event = this.events.get(batch.eventTime);
424
- if (!event || event.latchedReason || event.inFlightCandidateId) {
425
- throw new Wave9PaperAdmissionGuardError('Wave 9 daily event is unavailable or already in flight');
426
- }
427
- if (request.setupType !== WAVE9_BUNDLE_SETUP_TYPE)
428
- throw new Wave9PaperAdmissionGuardError('Wave 9 setup_type mismatch');
429
- requireExecutionMode(request.tradingMode);
430
- if (request.type.toLowerCase() !== 'market')
431
- throw new Wave9PaperAdmissionGuardError('Wave 9 entries must use immediate market execution');
432
- if (canonicalSymbol(request.symbol) !== record.symbol
433
- || request.side.toUpperCase() !== record.side
434
- || request.quantity !== exactPositiveNumber(record.quantity, 'quantity')
435
- || request.stopPrice !== exactPositiveNumber(record.stopPrice, 'stopPrice')
436
- || request.candidateId !== record.candidateId
437
- || request.missionId !== record.missionId
438
- || request.tradingMode !== record.tradingMode) {
439
- throw new Wave9PaperAdmissionGuardError('Wave 9 order does not exactly match its frozen admission');
440
- }
441
- this.assertFingerprint(record.accountFingerprint, request.accountFingerprint);
442
- event.inFlightCandidateId = record.candidateId;
443
- return this.lease(record, 'entry');
444
- }
445
- beginExit(request) {
446
- this.validateTokenShape(request.token, 'exit');
447
- const record = this.exitsByToken.get(request.token);
448
- if (!record || !sameSecret(record.token, request.token))
449
- throw new Wave9PaperAdmissionGuardError('unknown Wave 9 exit token');
450
- this.assertUsable(record);
451
- requireExecutionMode(request.tradingMode);
452
- if (!isWave9ManagedPosition({ setupType: request.setupType, missionId: request.missionId })
453
- || request.reason !== WAVE9_MECHANICAL_EXIT_REASON
454
- || canonicalSymbol(request.symbol) !== record.symbol
455
- || request.positionSide !== record.positionSide
456
- || request.candidateId !== record.candidateId
457
- || request.missionId !== record.missionId
458
- || request.tradingMode !== record.tradingMode) {
459
- throw new Wave9PaperAdmissionGuardError('Wave 9 close does not exactly match its reversal authorization');
460
- }
461
- this.assertFingerprint(record.positionFingerprint, request.positionFingerprint);
462
- return this.lease(record, 'exit');
463
- }
464
- revalidate(lease, fingerprint) {
465
- const record = this.recordForLease(lease);
466
- if (record.status !== 'in_flight' || record.leaseId !== lease.leaseId) {
467
- throw new Wave9PaperAdmissionGuardError('Wave 9 authorization lease is no longer active');
468
- }
469
- if (this.now() >= record.tokenDeadlineMs || this.now() >= record.deadlineMs) {
470
- throw new Wave9PaperAdmissionGuardError('Wave 9 authorization expired before mutation');
471
- }
472
- const expected = lease.kind === 'entry'
473
- ? record.accountFingerprint
474
- : record.positionFingerprint;
475
- this.assertFingerprint(expected, fingerprint);
476
- }
477
- commit(lease) {
478
- const record = this.recordForLease(lease);
479
- if (record.status !== 'in_flight' || record.leaseId !== lease.leaseId) {
480
- throw new Wave9PaperAdmissionGuardError('Wave 9 authorization lease is no longer active');
481
- }
482
- record.status = 'consumed';
483
- record.leaseId = undefined;
484
- if (lease.kind === 'entry') {
485
- const entry = record;
486
- const batch = this.batches.get(entry.batchId);
487
- if (!batch || entry.sequence !== batch.nextSequence) {
488
- throw new Wave9PaperAdmissionGuardError('Wave 9 entry committed outside its frozen sequence');
489
- }
490
- batch.nextSequence += 1;
491
- const event = this.events.get(batch.eventTime);
492
- if (event) {
493
- event.inFlightCandidateId = undefined;
494
- event.consumedCandidateIds.add(entry.candidateId);
495
- }
496
- }
497
- else {
498
- record.retryableAfterAbort = false;
499
- }
500
- }
501
- /**
502
- * Consume a failed capability. Entry failure latches the whole projected
503
- * batch because later sizing assumed every earlier accepted entry. Exit
504
- * retry is allowed when the caller explicitly proves another attempt stays
505
- * risk-reducing, including a residual/unknown result after a reduce-only
506
- * LIVE close submission.
507
- */
508
- abort(lease, reason, options = {}) {
509
- const record = this.recordForLease(lease);
510
- if (record.status !== 'in_flight' || record.leaseId !== lease.leaseId)
511
- return;
512
- record.status = 'consumed';
513
- record.leaseId = undefined;
514
- if (lease.kind === 'entry') {
515
- const entry = record;
516
- entry.retryableAfterAbort = options.retryable === true;
517
- const batch = this.batches.get(entry.batchId);
518
- if (batch) {
519
- const event = this.events.get(batch.eventTime);
520
- if (event)
521
- event.inFlightCandidateId = undefined;
522
- if (options.latchEvent !== false) {
523
- batch.latchedReason = reason.slice(0, 300);
524
- if (event) {
525
- event.latchedReason = batch.latchedReason;
526
- }
527
- }
528
- }
529
- }
530
- else {
531
- record.retryableAfterAbort = options.retryable === true;
532
- }
533
- }
534
- validateWindow(notBeforeMs, deadlineMs) {
535
- requireFinite(notBeforeMs, 'notBeforeMs');
536
- requireFinite(deadlineMs, 'deadlineMs');
537
- if (!Number.isInteger(notBeforeMs) || !Number.isInteger(deadlineMs) || deadlineMs < notBeforeMs) {
538
- throw new Wave9PaperAdmissionGuardError('authorization window is malformed');
539
- }
540
- }
541
- newEntryRecord(decision) {
542
- const token = this.newToken('entry');
543
- return {
544
- ...decision,
545
- token,
546
- tokenDeadlineMs: Math.min(decision.deadlineMs, this.now() + this.tokenTtlMs),
547
- status: 'issued',
548
- retryableAfterAbort: false,
549
- };
550
- }
551
- newExitRecord(decision) {
552
- const token = this.newToken('exit');
553
- return {
554
- ...decision,
555
- token,
556
- tokenDeadlineMs: Math.min(decision.deadlineMs, this.now() + this.tokenTtlMs),
557
- status: 'issued',
558
- retryableAfterAbort: false,
559
- };
560
- }
561
- rotateEntryToken(record) {
562
- this.entriesByToken.delete(record.token);
563
- record.token = this.newToken('entry');
564
- record.tokenDeadlineMs = Math.min(record.deadlineMs, this.now() + this.tokenTtlMs);
565
- this.entriesByToken.set(record.token, record);
566
- }
567
- rotateExitToken(record) {
568
- this.exitsByToken.delete(record.token);
569
- record.token = this.newToken('exit');
570
- record.tokenDeadlineMs = Math.min(record.deadlineMs, this.now() + this.tokenTtlMs);
571
- this.exitsByToken.set(record.token, record);
572
- }
573
- newToken(kind) {
574
- return `w9${kind === 'entry' ? 'e' : 'x'}_${randomBytes(32).toString('base64url')}`;
575
- }
576
- validateTokenShape(token, kind) {
577
- if (typeof token !== 'string' || !TOKEN_PATTERN.test(token) || !token.startsWith(kind === 'entry' ? 'w9e_' : 'w9x_')) {
578
- throw new Wave9PaperAdmissionGuardError(`malformed Wave 9 ${kind} token`);
579
- }
580
- }
581
- assertUsable(record) {
582
- const now = this.now();
583
- if (record.status !== 'issued')
584
- throw new Wave9PaperAdmissionGuardError('Wave 9 authorization token is already used');
585
- if (now < record.notBeforeMs)
586
- throw new Wave9PaperAdmissionGuardError('Wave 9 authorization is not active yet');
587
- if (now >= record.tokenDeadlineMs || now >= record.deadlineMs)
588
- throw new Wave9PaperAdmissionGuardError('Wave 9 authorization token expired');
589
- }
590
- lease(record, kind) {
591
- const leaseId = randomBytes(24).toString('base64url');
592
- record.status = 'in_flight';
593
- record.leaseId = leaseId;
594
- return Object.freeze({ leaseId, kind, token: record.token });
595
- }
596
- recordForLease(lease) {
597
- const record = lease.kind === 'entry'
598
- ? this.entriesByToken.get(lease.token)
599
- : this.exitsByToken.get(lease.token);
600
- if (!record || record.leaseId !== lease.leaseId) {
601
- throw new Wave9PaperAdmissionGuardError('unknown Wave 9 authorization lease');
602
- }
603
- return record;
604
- }
605
- assertFingerprint(expected, actual) {
606
- if (!FINGERPRINT_PATTERN.test(actual) || !sameSecret(expected, actual)) {
607
- throw new Wave9PaperAdmissionGuardError('Wave 9 account changed after authorization; mutation refused');
608
- }
609
- }
610
- sameEntryDecision(record, decision) {
611
- return ['candidateId', 'missionId', 'symbol', 'side', 'quantity', 'stopPrice', 'sequence', 'notBeforeMs', 'deadlineMs', 'accountFingerprint', 'tradingMode']
612
- .every((key) => record[key] === decision[key]);
613
- }
614
- validateExitDecision(decision) {
615
- exactText(decision.candidateId, 'exit candidateId');
616
- exactText(decision.missionId, 'missionId');
617
- requireExecutionMode(decision.tradingMode);
618
- if (decision.reason !== 'signal_reversal')
619
- throw new Wave9PaperAdmissionGuardError('Wave 9 exit reason must be signal_reversal');
620
- if (!WAVE9_SYMBOL_PRIORITY.includes(decision.symbol)) {
621
- throw new Wave9PaperAdmissionGuardError(`unsupported Wave 9 symbol ${decision.symbol}`);
622
- }
623
- if (!['long', 'short'].includes(decision.positionSide))
624
- throw new Wave9PaperAdmissionGuardError('positionSide is malformed');
625
- if (decision.missionId !== stableMissionId(decision.candidateId)) {
626
- throw new Wave9PaperAdmissionGuardError('exit missionId does not match stable candidate identity');
627
- }
628
- const parts = decision.candidateId.split('|');
629
- const expectedStrategy = decision.positionSide === 'long'
630
- ? 'tsmom_28d_long_flat_reversal_1d'
631
- : 'tsmom_28d_short_flat_reversal_1d';
632
- const expectedDirection = decision.positionSide === 'long' ? 'LONG' : 'SHORT';
633
- if (parts.length !== 4
634
- || parts[1] !== decision.symbol
635
- || parts[2] !== expectedStrategy
636
- || parts[3] !== expectedDirection) {
637
- throw new Wave9PaperAdmissionGuardError('exit candidateId does not match held Wave 9 leg');
638
- }
639
- if (!FINGERPRINT_PATTERN.test(decision.positionFingerprint))
640
- throw new Wave9PaperAdmissionGuardError('positionFingerprint is malformed');
641
- this.validateWindow(decision.notBeforeMs, decision.deadlineMs);
642
- }
643
- exitIdentity(decision) {
644
- return `${decision.candidateId}|${decision.missionId}|${decision.symbol}|${decision.positionSide}|${decision.tradingMode}`;
645
- }
646
- sameExitDecision(record, decision) {
647
- return ['candidateId', 'missionId', 'symbol', 'positionSide', 'reason', 'notBeforeMs', 'deadlineMs', 'positionFingerprint', 'tradingMode']
648
- .every((key) => record[key] === decision[key]);
649
- }
650
- }