@senpi/runtime 3.0.135 → 3.0.139

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 (293) hide show
  1. package/dist/actions/action-events.d.ts +7 -21
  2. package/dist/actions/action-events.d.ts.map +1 -1
  3. package/dist/actions/action-events.js +26 -54
  4. package/dist/actions/action-events.js.map +1 -1
  5. package/dist/actions/action-runtime-module.d.ts.map +1 -1
  6. package/dist/actions/action-runtime-module.js +7 -38
  7. package/dist/actions/action-runtime-module.js.map +1 -1
  8. package/dist/actions/close-position/close-position.action.d.ts.map +1 -1
  9. package/dist/actions/close-position/close-position.action.js +15 -122
  10. package/dist/actions/close-position/close-position.action.js.map +1 -1
  11. package/dist/actions/decision-engine.d.ts.map +1 -1
  12. package/dist/actions/decision-engine.js +2 -15
  13. package/dist/actions/decision-engine.js.map +1 -1
  14. package/dist/actions/event-derivation.d.ts +2 -71
  15. package/dist/actions/event-derivation.d.ts.map +1 -1
  16. package/dist/actions/event-derivation.js +8 -251
  17. package/dist/actions/event-derivation.js.map +1 -1
  18. package/dist/actions/open-position/open-position.action.d.ts +2 -12
  19. package/dist/actions/open-position/open-position.action.d.ts.map +1 -1
  20. package/dist/actions/open-position/open-position.action.js +41 -141
  21. package/dist/actions/open-position/open-position.action.js.map +1 -1
  22. package/dist/actions/position-tracker/position-tracker.action.d.ts +1 -2
  23. package/dist/actions/position-tracker/position-tracker.action.d.ts.map +1 -1
  24. package/dist/actions/position-tracker/position-tracker.action.js +17 -62
  25. package/dist/actions/position-tracker/position-tracker.action.js.map +1 -1
  26. package/dist/actions/store/types.d.ts +2 -9
  27. package/dist/actions/store/types.d.ts.map +1 -1
  28. package/dist/actions/store/types.js.map +1 -1
  29. package/dist/actions/types.d.ts +0 -13
  30. package/dist/actions/types.d.ts.map +1 -1
  31. package/dist/actions/types.js +0 -13
  32. package/dist/actions/types.js.map +1 -1
  33. package/dist/cli/guide-commands.d.ts.map +1 -1
  34. package/dist/cli/guide-commands.js +7 -4
  35. package/dist/cli/guide-commands.js.map +1 -1
  36. package/dist/constants/dsl/index.d.ts +0 -6
  37. package/dist/constants/dsl/index.d.ts.map +1 -1
  38. package/dist/constants/dsl/index.js +0 -6
  39. package/dist/constants/dsl/index.js.map +1 -1
  40. package/dist/constants/telemetry.d.ts +15 -0
  41. package/dist/constants/telemetry.d.ts.map +1 -0
  42. package/dist/constants/telemetry.js +28 -0
  43. package/dist/constants/telemetry.js.map +1 -0
  44. package/dist/dsl/engine-client/event-mapping.d.ts.map +1 -1
  45. package/dist/dsl/engine-client/event-mapping.js +0 -14
  46. package/dist/dsl/engine-client/event-mapping.js.map +1 -1
  47. package/dist/dsl/events/build-closed-event.d.ts +1 -16
  48. package/dist/dsl/events/build-closed-event.d.ts.map +1 -1
  49. package/dist/dsl/events/build-closed-event.js +0 -6
  50. package/dist/dsl/events/build-closed-event.js.map +1 -1
  51. package/dist/dsl/events/handlers.d.ts +0 -7
  52. package/dist/dsl/events/handlers.d.ts.map +1 -1
  53. package/dist/dsl/events/handlers.js +7 -37
  54. package/dist/dsl/events/handlers.js.map +1 -1
  55. package/dist/dsl/monitor/create-monitor.d.ts +2 -6
  56. package/dist/dsl/monitor/create-monitor.d.ts.map +1 -1
  57. package/dist/dsl/monitor/create-monitor.js +9 -82
  58. package/dist/dsl/monitor/create-monitor.js.map +1 -1
  59. package/dist/dsl/monitor/dsl-failure-events.d.ts +2 -45
  60. package/dist/dsl/monitor/dsl-failure-events.d.ts.map +1 -1
  61. package/dist/dsl/monitor/dsl-failure-events.js +3 -52
  62. package/dist/dsl/monitor/dsl-failure-events.js.map +1 -1
  63. package/dist/dsl/monitor/process-one-position.d.ts +0 -1
  64. package/dist/dsl/monitor/process-one-position.d.ts.map +1 -1
  65. package/dist/dsl/monitor/process-one-position.js +36 -159
  66. package/dist/dsl/monitor/process-one-position.js.map +1 -1
  67. package/dist/dsl/plugin/index.d.ts +2 -8
  68. package/dist/dsl/plugin/index.d.ts.map +1 -1
  69. package/dist/dsl/plugin/index.js +8 -20
  70. package/dist/dsl/plugin/index.js.map +1 -1
  71. package/dist/health/types.d.ts +0 -13
  72. package/dist/health/types.d.ts.map +1 -1
  73. package/dist/health/types.js +0 -12
  74. package/dist/health/types.js.map +1 -1
  75. package/dist/index.d.ts +8 -27
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +105 -272
  78. package/dist/index.js.map +1 -1
  79. package/dist/runtime/action-registry.d.ts.map +1 -1
  80. package/dist/runtime/action-registry.js +3 -4
  81. package/dist/runtime/action-registry.js.map +1 -1
  82. package/dist/runtime/domain-events.d.ts.map +1 -1
  83. package/dist/runtime/domain-events.js +0 -7
  84. package/dist/runtime/domain-events.js.map +1 -1
  85. package/dist/runtime/events-telemetry.d.ts +96 -0
  86. package/dist/runtime/events-telemetry.d.ts.map +1 -0
  87. package/dist/runtime/events-telemetry.js +232 -0
  88. package/dist/runtime/events-telemetry.js.map +1 -0
  89. package/dist/runtime/lifecycle-events.d.ts +3 -15
  90. package/dist/runtime/lifecycle-events.d.ts.map +1 -1
  91. package/dist/runtime/lifecycle-events.js +3 -17
  92. package/dist/runtime/lifecycle-events.js.map +1 -1
  93. package/dist/runtime/lifecycle-reaper.d.ts +6 -4
  94. package/dist/runtime/lifecycle-reaper.d.ts.map +1 -1
  95. package/dist/runtime/lifecycle-reaper.js +6 -4
  96. package/dist/runtime/lifecycle-reaper.js.map +1 -1
  97. package/dist/runtime/reconcile-run.d.ts +3 -13
  98. package/dist/runtime/reconcile-run.d.ts.map +1 -1
  99. package/dist/runtime/reconcile-run.js +3 -4
  100. package/dist/runtime/reconcile-run.js.map +1 -1
  101. package/dist/runtime/reconcile-state.d.ts +0 -8
  102. package/dist/runtime/reconcile-state.d.ts.map +1 -1
  103. package/dist/runtime/reconcile-state.js +1 -4
  104. package/dist/runtime/reconcile-state.js.map +1 -1
  105. package/dist/runtime/risk-guard.d.ts +20 -1
  106. package/dist/runtime/risk-guard.d.ts.map +1 -1
  107. package/dist/runtime/risk-guard.js +47 -6
  108. package/dist/runtime/risk-guard.js.map +1 -1
  109. package/dist/runtime/run.d.ts +7 -1
  110. package/dist/runtime/run.d.ts.map +1 -1
  111. package/dist/runtime/run.js +7 -0
  112. package/dist/runtime/run.js.map +1 -1
  113. package/dist/runtime/runtime-schema.js +3 -3
  114. package/dist/runtime/runtime-schema.js.map +1 -1
  115. package/dist/runtime/runtime.d.ts +22 -2
  116. package/dist/runtime/runtime.d.ts.map +1 -1
  117. package/dist/runtime/runtime.js +74 -39
  118. package/dist/runtime/runtime.js.map +1 -1
  119. package/dist/runtime/strategies-store.d.ts +26 -0
  120. package/dist/runtime/strategies-store.d.ts.map +1 -0
  121. package/dist/runtime/strategies-store.js +47 -0
  122. package/dist/runtime/strategies-store.js.map +1 -0
  123. package/dist/runtime/strategies-telemetry.d.ts +91 -0
  124. package/dist/runtime/strategies-telemetry.d.ts.map +1 -0
  125. package/dist/runtime/strategies-telemetry.js +128 -0
  126. package/dist/runtime/strategies-telemetry.js.map +1 -0
  127. package/dist/runtime/strategy-lifecycle.d.ts +108 -2
  128. package/dist/runtime/strategy-lifecycle.d.ts.map +1 -1
  129. package/dist/runtime/strategy-lifecycle.js +325 -4
  130. package/dist/runtime/strategy-lifecycle.js.map +1 -1
  131. package/dist/runtime/supervisor/long-running-supervisor.d.ts +0 -13
  132. package/dist/runtime/supervisor/long-running-supervisor.d.ts.map +1 -1
  133. package/dist/runtime/supervisor/long-running-supervisor.js +0 -1
  134. package/dist/runtime/supervisor/long-running-supervisor.js.map +1 -1
  135. package/dist/runtime/validate-dsl-position-tracking.d.ts.map +1 -1
  136. package/dist/runtime/validate-dsl-position-tracking.js +1 -2
  137. package/dist/runtime/validate-dsl-position-tracking.js.map +1 -1
  138. package/dist/runtime-api/handlers/ingest-signals.d.ts.map +1 -1
  139. package/dist/runtime-api/handlers/ingest-signals.js +0 -1
  140. package/dist/runtime-api/handlers/ingest-signals.js.map +1 -1
  141. package/dist/runtime-api/handlers/types.d.ts +0 -5
  142. package/dist/runtime-api/handlers/types.d.ts.map +1 -1
  143. package/dist/runtime-api/intake/intake-events.d.ts +1 -1
  144. package/dist/runtime-api/intake/intake-events.d.ts.map +1 -1
  145. package/dist/runtime-api/intake/intake-events.js +3 -9
  146. package/dist/runtime-api/intake/intake-events.js.map +1 -1
  147. package/dist/runtime-api/intake/intake-mount.d.ts +2 -0
  148. package/dist/runtime-api/intake/intake-mount.d.ts.map +1 -1
  149. package/dist/runtime-api/intake/intake-mount.js +25 -7
  150. package/dist/runtime-api/intake/intake-mount.js.map +1 -1
  151. package/dist/runtime-api/intake/process-error-post.d.ts +1 -6
  152. package/dist/runtime-api/intake/process-error-post.d.ts.map +1 -1
  153. package/dist/runtime-api/intake/process-error-post.js +1 -5
  154. package/dist/runtime-api/intake/process-error-post.js.map +1 -1
  155. package/dist/runtime-api/intake/process-signal-post.d.ts +1 -7
  156. package/dist/runtime-api/intake/process-signal-post.d.ts.map +1 -1
  157. package/dist/runtime-api/intake/process-signal-post.js +0 -5
  158. package/dist/runtime-api/intake/process-signal-post.js.map +1 -1
  159. package/dist/runtime-api/intake/scaffold-error-router.js.map +1 -1
  160. package/dist/runtime-api/intake/scanner-launcher.d.ts.map +1 -1
  161. package/dist/runtime-api/intake/scanner-launcher.js +0 -15
  162. package/dist/runtime-api/intake/scanner-launcher.js.map +1 -1
  163. package/dist/runtime-api/intake/types.d.ts +0 -55
  164. package/dist/runtime-api/intake/types.d.ts.map +1 -1
  165. package/dist/runtime-api/routes/signals.d.ts +0 -2
  166. package/dist/runtime-api/routes/signals.d.ts.map +1 -1
  167. package/dist/runtime-api/routes/signals.js +11 -5
  168. package/dist/runtime-api/routes/signals.js.map +1 -1
  169. package/dist/runtime-api/routes/signals.schema.d.ts +0 -43
  170. package/dist/runtime-api/routes/signals.schema.d.ts.map +1 -1
  171. package/dist/runtime-api/routes/signals.schema.js +0 -43
  172. package/dist/runtime-api/routes/signals.schema.js.map +1 -1
  173. package/dist/runtime-api/server.d.ts +1 -7
  174. package/dist/runtime-api/server.d.ts.map +1 -1
  175. package/dist/runtime-api/server.js +0 -1
  176. package/dist/runtime-api/server.js.map +1 -1
  177. package/dist/scanners/engine/engine.d.ts +1 -22
  178. package/dist/scanners/engine/engine.d.ts.map +1 -1
  179. package/dist/scanners/engine/engine.js +11 -78
  180. package/dist/scanners/engine/engine.js.map +1 -1
  181. package/dist/scanners/engine/lifecycle.d.ts +1 -7
  182. package/dist/scanners/engine/lifecycle.d.ts.map +1 -1
  183. package/dist/scanners/events.d.ts +0 -4
  184. package/dist/scanners/events.d.ts.map +1 -1
  185. package/dist/scanners/events.js +0 -2
  186. package/dist/scanners/events.js.map +1 -1
  187. package/dist/scanners/external/scaffold/delivery.py +25 -194
  188. package/dist/scanners/external/scaffold/scaffold.py +31 -172
  189. package/dist/scanners/external/scaffold/senpi_mcp.py +8 -150
  190. package/dist/scanners/external-scanner-receiver.d.ts +0 -17
  191. package/dist/scanners/external-scanner-receiver.d.ts.map +1 -1
  192. package/dist/scanners/external-scanner-receiver.js +0 -8
  193. package/dist/scanners/external-scanner-receiver.js.map +1 -1
  194. package/dist/scanners/runtime-module.d.ts +0 -1
  195. package/dist/scanners/runtime-module.d.ts.map +1 -1
  196. package/dist/scanners/runtime-module.js +9 -66
  197. package/dist/scanners/runtime-module.js.map +1 -1
  198. package/dist/state/state-manager.d.ts +2 -0
  199. package/dist/state/state-manager.d.ts.map +1 -1
  200. package/dist/state/state-manager.js +8 -0
  201. package/dist/state/state-manager.js.map +1 -1
  202. package/dist/telemetry/attributes.d.ts +0 -20
  203. package/dist/telemetry/attributes.d.ts.map +1 -1
  204. package/dist/telemetry/attributes.js +0 -24
  205. package/dist/telemetry/attributes.js.map +1 -1
  206. package/dist/telemetry/event-builders.d.ts +6 -81
  207. package/dist/telemetry/event-builders.d.ts.map +1 -1
  208. package/dist/telemetry/event-builders.js +17 -141
  209. package/dist/telemetry/event-builders.js.map +1 -1
  210. package/dist/telemetry/event-store.d.ts.map +1 -1
  211. package/dist/telemetry/event-store.js +2 -6
  212. package/dist/telemetry/event-store.js.map +1 -1
  213. package/dist/telemetry/metrics.d.ts +2 -14
  214. package/dist/telemetry/metrics.d.ts.map +1 -1
  215. package/dist/telemetry/metrics.js +4 -19
  216. package/dist/telemetry/metrics.js.map +1 -1
  217. package/dist/telemetry/spans/redact-pii.d.ts.map +1 -1
  218. package/dist/telemetry/spans/redact-pii.js +11 -16
  219. package/dist/telemetry/spans/redact-pii.js.map +1 -1
  220. package/dist/telemetry/tracing.d.ts +0 -9
  221. package/dist/telemetry/tracing.d.ts.map +1 -1
  222. package/dist/telemetry/tracing.js +0 -36
  223. package/dist/telemetry/tracing.js.map +1 -1
  224. package/dist/types/dsl/index.d.ts +0 -48
  225. package/dist/types/dsl/index.d.ts.map +1 -1
  226. package/dist/types/scanner.d.ts +0 -15
  227. package/dist/types/scanner.d.ts.map +1 -1
  228. package/dist/utils/event-catalog.d.ts +0 -202
  229. package/dist/utils/event-catalog.d.ts.map +1 -1
  230. package/dist/utils/event-catalog.js +0 -26
  231. package/dist/utils/event-catalog.js.map +1 -1
  232. package/dist/utils/logger.d.ts +1 -4
  233. package/dist/utils/logger.d.ts.map +1 -1
  234. package/dist/utils/logger.js.map +1 -1
  235. package/dist/validate/recipe-checks.d.ts.map +1 -1
  236. package/dist/validate/recipe-checks.js +2 -2
  237. package/dist/validate/recipe-checks.js.map +1 -1
  238. package/openclaw.plugin.json +1 -1
  239. package/package.json +1 -1
  240. package/dist/actions/skipped-signal-results.d.ts +0 -25
  241. package/dist/actions/skipped-signal-results.d.ts.map +0 -1
  242. package/dist/actions/skipped-signal-results.js +0 -71
  243. package/dist/actions/skipped-signal-results.js.map +0 -1
  244. package/dist/runtime-api/intake/ingest-request.d.ts +0 -17
  245. package/dist/runtime-api/intake/ingest-request.d.ts.map +0 -1
  246. package/dist/runtime-api/intake/ingest-request.js +0 -34
  247. package/dist/runtime-api/intake/ingest-request.js.map +0 -1
  248. package/dist/runtime-api/intake/scaffold-tick-router.d.ts +0 -39
  249. package/dist/runtime-api/intake/scaffold-tick-router.d.ts.map +0 -1
  250. package/dist/runtime-api/intake/scaffold-tick-router.js +0 -122
  251. package/dist/runtime-api/intake/scaffold-tick-router.js.map +0 -1
  252. package/dist/scanners/external/scaffold/tick_facts.py +0 -130
  253. package/dist/scanners/external/scaffold/ulid.py +0 -58
  254. package/dist/telemetry/dsl-positions.d.ts +0 -111
  255. package/dist/telemetry/dsl-positions.d.ts.map +0 -1
  256. package/dist/telemetry/dsl-positions.js +0 -118
  257. package/dist/telemetry/dsl-positions.js.map +0 -1
  258. package/dist/telemetry/live-telemetry.d.ts +0 -257
  259. package/dist/telemetry/live-telemetry.d.ts.map +0 -1
  260. package/dist/telemetry/live-telemetry.js +0 -959
  261. package/dist/telemetry/live-telemetry.js.map +0 -1
  262. package/dist/telemetry/scanner-stats.d.ts +0 -143
  263. package/dist/telemetry/scanner-stats.d.ts.map +0 -1
  264. package/dist/telemetry/scanner-stats.js +0 -426
  265. package/dist/telemetry/scanner-stats.js.map +0 -1
  266. package/dist/telemetry/scanner-tick-feed.d.ts +0 -87
  267. package/dist/telemetry/scanner-tick-feed.d.ts.map +0 -1
  268. package/dist/telemetry/scanner-tick-feed.js +0 -48
  269. package/dist/telemetry/scanner-tick-feed.js.map +0 -1
  270. package/dist/telemetry/strategy-topology.d.ts +0 -99
  271. package/dist/telemetry/strategy-topology.d.ts.map +0 -1
  272. package/dist/telemetry/strategy-topology.js +0 -93
  273. package/dist/telemetry/strategy-topology.js.map +0 -1
  274. package/dist/telemetry/telemetry-publisher.d.ts +0 -83
  275. package/dist/telemetry/telemetry-publisher.d.ts.map +0 -1
  276. package/dist/telemetry/telemetry-publisher.js +0 -256
  277. package/dist/telemetry/telemetry-publisher.js.map +0 -1
  278. package/dist/telemetry/tick-frame.d.ts +0 -212
  279. package/dist/telemetry/tick-frame.d.ts.map +0 -1
  280. package/dist/telemetry/tick-frame.js +0 -421
  281. package/dist/telemetry/tick-frame.js.map +0 -1
  282. package/dist/telemetry/timeline-buffer.d.ts +0 -95
  283. package/dist/telemetry/timeline-buffer.d.ts.map +0 -1
  284. package/dist/telemetry/timeline-buffer.js +0 -237
  285. package/dist/telemetry/timeline-buffer.js.map +0 -1
  286. package/dist/utils/telemetry-required-log.d.ts +0 -60
  287. package/dist/utils/telemetry-required-log.d.ts.map +0 -1
  288. package/dist/utils/telemetry-required-log.js +0 -105
  289. package/dist/utils/telemetry-required-log.js.map +0 -1
  290. package/dist/utils/ulid.d.ts +0 -9
  291. package/dist/utils/ulid.d.ts.map +0 -1
  292. package/dist/utils/ulid.js +0 -43
  293. package/dist/utils/ulid.js.map +0 -1
@@ -1,25 +0,0 @@
1
- /**
2
- * Per-signal `results[]` rows synthesized for a batch-level early exit — the exits that return
3
- * before the per-signal loop and would otherwise leave the scan's signals with no recorded outcome.
4
- * Entry shape matches the loop's own rows so the derived per-signal telemetry is identical in
5
- * structure: normalized `dex`, `direction`/`score` only when usable, and a zero-width work window
6
- * (both stamps present — a half window is dropped downstream, and a missing one is
7
- * indistinguishable from an unstamped legacy row).
8
- *
9
- * Each row carries `__signalIndex`, its position in the INPUT list, so the event mapper pairs the
10
- * row with THIS signal's `meta` rather than with the first signal sharing its asset. It is read
11
- * inside the loop, not zipped on by the caller: a dropped signal shifts every later output
12
- * position. The input list is the scan's own signal array, which is what the mapper indexes into;
13
- * close-position's static-params fallback list has no scan array behind it, so its index matches
14
- * nothing and the mapper degrades to its asset join, as it does for any unmatched index.
15
- *
16
- * A signal with no usable asset is dropped: an outcome that names no asset is not attributable.
17
- * A drop is a hole in the "no signal goes unrecorded" contract, so it is logged (once per call,
18
- * with the count) rather than passing silently. Counts are unaffected — the row is still absent.
19
- * Total by construction — it runs on the trading path and must never throw on a malformed entry.
20
- */
21
- export declare function skippedSignalResults(signals: readonly unknown[] | undefined, reason: string, nowMs: number, overrides?: {
22
- success?: boolean;
23
- error?: string;
24
- }): Array<Record<string, unknown>>;
25
- //# sourceMappingURL=skipped-signal-results.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"skipped-signal-results.d.ts","sourceRoot":"","sources":["../../src/actions/skipped-signal-results.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,EACvC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA8ChC"}
@@ -1,71 +0,0 @@
1
- import { createLogger } from '../utils/logger.js';
2
- const logger = createLogger('[actions][skipped-signal-results]');
3
- /**
4
- * Per-signal `results[]` rows synthesized for a batch-level early exit — the exits that return
5
- * before the per-signal loop and would otherwise leave the scan's signals with no recorded outcome.
6
- * Entry shape matches the loop's own rows so the derived per-signal telemetry is identical in
7
- * structure: normalized `dex`, `direction`/`score` only when usable, and a zero-width work window
8
- * (both stamps present — a half window is dropped downstream, and a missing one is
9
- * indistinguishable from an unstamped legacy row).
10
- *
11
- * Each row carries `__signalIndex`, its position in the INPUT list, so the event mapper pairs the
12
- * row with THIS signal's `meta` rather than with the first signal sharing its asset. It is read
13
- * inside the loop, not zipped on by the caller: a dropped signal shifts every later output
14
- * position. The input list is the scan's own signal array, which is what the mapper indexes into;
15
- * close-position's static-params fallback list has no scan array behind it, so its index matches
16
- * nothing and the mapper degrades to its asset join, as it does for any unmatched index.
17
- *
18
- * A signal with no usable asset is dropped: an outcome that names no asset is not attributable.
19
- * A drop is a hole in the "no signal goes unrecorded" contract, so it is logged (once per call,
20
- * with the count) rather than passing silently. Counts are unaffected — the row is still absent.
21
- * Total by construction — it runs on the trading path and must never throw on a malformed entry.
22
- */
23
- export function skippedSignalResults(signals, reason, nowMs, overrides) {
24
- if (!Array.isArray(signals))
25
- return [];
26
- const rows = [];
27
- let dropped = 0;
28
- for (const [index, raw] of signals.entries()) {
29
- if (raw === null || typeof raw !== 'object') {
30
- dropped++;
31
- continue;
32
- }
33
- const signal = raw;
34
- const rawAsset = signal.asset;
35
- // Kept verbatim (not trimmed) so it still joins the scanner signal it came from.
36
- const asset = typeof rawAsset === 'string' ? rawAsset : typeof rawAsset === 'number' ? String(rawAsset) : '';
37
- if (asset.trim() === '') {
38
- dropped++;
39
- continue;
40
- }
41
- const direction = signal.direction;
42
- const score = signal.score;
43
- // A decision-payload signal carries the book top-level (the strategy hoists it there); a raw
44
- // scanner signal carries it only on `meta`, since `Signal` has no `dex` field. Both call
45
- // shapes reach this helper, so both are read — top-level first, matching the per-signal loop.
46
- const meta = signal.meta;
47
- const metaDex = meta !== null && typeof meta === 'object' ? meta.dex : undefined;
48
- const dex = typeof signal.dex === 'string' && signal.dex.trim() !== '' ? signal.dex : metaDex;
49
- rows.push({
50
- asset,
51
- ...(direction === 'LONG' || direction === 'SHORT' ? { direction } : {}),
52
- dex: typeof dex === 'string' && dex.trim() !== '' ? dex.trim() : 'main',
53
- ...(typeof score === 'number' && Number.isFinite(score) ? { score } : {}),
54
- success: overrides?.success ?? true,
55
- reason,
56
- ...(overrides?.error !== undefined ? { error: overrides.error } : {}),
57
- startedAt: nowMs,
58
- endedAt: nowMs,
59
- __signalIndex: index,
60
- });
61
- }
62
- if (dropped > 0) {
63
- logger.warn('signals dropped from the skip rows: no usable asset to attribute the outcome to', undefined, {
64
- reason,
65
- dropped,
66
- recorded: rows.length,
67
- });
68
- }
69
- return rows;
70
- }
71
- //# sourceMappingURL=skipped-signal-results.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"skipped-signal-results.js","sourceRoot":"","sources":["../../src/actions/skipped-signal-results.ts"],"names":[],"mappings":"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"}
@@ -1,17 +0,0 @@
1
- /**
2
- * IntakeSignal → ExternalScannerIngestRequest.
3
- *
4
- * The single mapping between the intake wire shape and the engine's ingest shape. Both accept
5
- * seams call it: the live route closure in `src/index.ts` and `buildIntakeMount`'s `onAccepted`.
6
- */
7
- import type { ExternalScannerIngestRequest } from "../../scanners/external-scanner-receiver.js";
8
- import type { ScannerId } from "../../scanners/types.js";
9
- import type { IntakeSignal } from "./types.js";
10
- /**
11
- * Narrow one accepted intake signal to the ingest request the engine takes.
12
- *
13
- * @param scannerName Configured scanner NAME resolved from the registry, not the wire `scanner_id`.
14
- * @param correlationId Intake-minted id of the acceptance row that admitted this signal.
15
- */
16
- export declare function toIngestRequest(signal: IntakeSignal, correlationId: string, scannerName: ScannerId): ExternalScannerIngestRequest;
17
- //# sourceMappingURL=ingest-request.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ingest-request.d.ts","sourceRoot":"","sources":["../../../src/runtime-api/intake/ingest-request.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,6CAA6C,CAAC;AAChG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,YAAY,EACpB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,SAAS,GACrB,4BAA4B,CAoB9B"}
@@ -1,34 +0,0 @@
1
- /**
2
- * IntakeSignal → ExternalScannerIngestRequest.
3
- *
4
- * The single mapping between the intake wire shape and the engine's ingest shape. Both accept
5
- * seams call it: the live route closure in `src/index.ts` and `buildIntakeMount`'s `onAccepted`.
6
- */
7
- /**
8
- * Narrow one accepted intake signal to the ingest request the engine takes.
9
- *
10
- * @param scannerName Configured scanner NAME resolved from the registry, not the wire `scanner_id`.
11
- * @param correlationId Intake-minted id of the acceptance row that admitted this signal.
12
- */
13
- export function toIngestRequest(signal, correlationId, scannerName) {
14
- return {
15
- scanner: scannerName,
16
- signal_id: signal.signal_id, // greppable handle across intake→ingest (obs only)
17
- asset: signal.asset,
18
- direction: signal.direction,
19
- ...(signal.signal_type !== undefined && { signal_type: signal.signal_type }),
20
- data: signal.data,
21
- // Per-signal sizing rides at the top level; the open-position action reads
22
- // request.marginPct / request.leverage directly, else a supervised signal's
23
- // sizing is lost ("no margin source resolved").
24
- ...(signal.marginPct !== undefined && { marginPct: signal.marginPct }),
25
- ...(signal.leverage !== undefined && { leverage: signal.leverage }),
26
- // The producing scan and the admitting acceptance row.
27
- tick_id: signal.tick_id,
28
- correlationId,
29
- // Intentionally omitted: score (intake has none, defaults to 0 downstream),
30
- // valid_until/produced_at (acceptance-pipeline concerns, not ingest fields),
31
- // signals[] (single-signal shape: data, not signals[]).
32
- };
33
- }
34
- //# sourceMappingURL=ingest-request.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ingest-request.js","sourceRoot":"","sources":["../../../src/runtime-api/intake/ingest-request.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAoB,EACpB,aAAqB,EACrB,WAAsB;IAEtB,OAAO;QACL,OAAO,EAAE,WAAW;QACpB,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,mDAAmD;QAChF,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,GAAG,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;QAC5E,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,2EAA2E;QAC3E,4EAA4E;QAC5E,gDAAgD;QAChD,GAAG,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;QACtE,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;QACnE,uDAAuD;QACvD,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,aAAa;QACb,4EAA4E;QAC5E,6EAA6E;QAC7E,wDAAwD;KACzD,CAAC;AACJ,CAAC"}
@@ -1,39 +0,0 @@
1
- /**
2
- * The `/signals` and `/errors` routes' `onTick` — one implementation, used by both.
3
- *
4
- * A supervised external scanner runs in its own Python process, so the only facts the runtime has
5
- * about one of its ticks are the ones that arrive over the intake. Both routes already fire once
6
- * per tick — `/signals` on every clean tick including a quiet one, `/errors` on every failed one —
7
- * so the facts ride the request that tick already makes. No second channel, no extra POST, and a
8
- * producer that sends none behaves exactly as it did before.
9
- *
10
- * What this does with them is hand the run to the SAME process sink the in-process scanner runtime
11
- * hands its own finished runs to ({@link ../../telemetry/scanner-tick-feed.js}), which is a no-op
12
- * until a client is watching. Nothing here reaches `logger.event` or `appendDomainEvent`: a tick is
13
- * a LEVEL, and per-tick records would evict real decision rows from the on-disk ring and the
14
- * publisher's bounded buffer.
15
- *
16
- * ABSENT IS NOT ZERO, end to end. A field the producer did not send is left off the run rather than
17
- * defaulted, so the publisher can leave it off the frame and the screen can print "unknown" instead
18
- * of a number nobody measured.
19
- */
20
- import { type ScannerTickExtras } from "../../telemetry/scanner-tick-feed.js";
21
- import type { IntakeContext } from "./intake-context.js";
22
- import type { IntakeTickFacts } from "./types.js";
23
- /** The producer's facts as the tick feed's extras, with every unreadable field left off. */
24
- export declare function toTickExtras(facts: IntakeTickFacts): ScannerTickExtras;
25
- /**
26
- * Build the `onTick` both intake routes call.
27
- *
28
- * Resolves against the SHARED IntakeContext registry, like `onAccepted` and `onScaffoldError`, so
29
- * the tick is attributed to the scanner's STABLE name and its runtime's wallet rather than to the
30
- * ephemeral scanner_id a relaunch re-mints — which is the key a client joins a tick to its stats
31
- * row on.
32
- *
33
- * `now` is the runtime clock at the POST, used as the run's finish. The producer's own clock is not
34
- * used: it is a different machine's wall time, and a frame mixing the two would put ticks in an
35
- * order neither machine saw. `startedAt` is derived from the duration the producer measured, which
36
- * keeps `ms` the producer's own number while `t` stays on this box's clock.
37
- */
38
- export declare function buildScaffoldTickRouter(ctx: IntakeContext, now?: () => number): (scannerId: string, facts: IntakeTickFacts) => void;
39
- //# sourceMappingURL=scaffold-tick-router.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scaffold-tick-router.d.ts","sourceRoot":"","sources":["../../../src/runtime-api/intake/scaffold-tick-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,sCAAsC,CAAC;AAE9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAkB,eAAe,EAAE,MAAM,YAAY,CAAC;AAkClE,4FAA4F;AAC5F,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,iBAAiB,CA+BtE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,aAAa,EAClB,GAAG,GAAE,MAAM,MAAyB,GACnC,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,KAAK,IAAI,CAqBrD"}
@@ -1,122 +0,0 @@
1
- /**
2
- * The `/signals` and `/errors` routes' `onTick` — one implementation, used by both.
3
- *
4
- * A supervised external scanner runs in its own Python process, so the only facts the runtime has
5
- * about one of its ticks are the ones that arrive over the intake. Both routes already fire once
6
- * per tick — `/signals` on every clean tick including a quiet one, `/errors` on every failed one —
7
- * so the facts ride the request that tick already makes. No second channel, no extra POST, and a
8
- * producer that sends none behaves exactly as it did before.
9
- *
10
- * What this does with them is hand the run to the SAME process sink the in-process scanner runtime
11
- * hands its own finished runs to ({@link ../../telemetry/scanner-tick-feed.js}), which is a no-op
12
- * until a client is watching. Nothing here reaches `logger.event` or `appendDomainEvent`: a tick is
13
- * a LEVEL, and per-tick records would evict real decision rows from the on-disk ring and the
14
- * publisher's bounded buffer.
15
- *
16
- * ABSENT IS NOT ZERO, end to end. A field the producer did not send is left off the run rather than
17
- * defaulted, so the publisher can leave it off the frame and the screen can print "unknown" instead
18
- * of a number nobody measured.
19
- */
20
- import { hasScannerTickSink, recordScannerTick, } from "../../telemetry/scanner-tick-feed.js";
21
- /** The commit endings this box publishes. Anything else a producer sends is dropped, not relayed. */
22
- const COMMIT_OUTCOMES = new Set([
23
- "committed",
24
- "rolled_back",
25
- "persist_failed",
26
- ]);
27
- /** A finite, non-negative number, or `undefined` — which is how an unknown stays unknown. */
28
- function count(value) {
29
- return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : undefined;
30
- }
31
- function calls(rows) {
32
- if (!Array.isArray(rows))
33
- return undefined;
34
- const out = [];
35
- for (const row of rows) {
36
- if (row === null || typeof row !== "object")
37
- continue;
38
- if (typeof row.tool !== "string" || row.tool.length === 0)
39
- continue;
40
- out.push({
41
- tool: row.tool,
42
- ...(count(row.ms) === undefined ? {} : { ms: count(row.ms) }),
43
- ...(row.args !== null && typeof row.args === "object" && !Array.isArray(row.args)
44
- ? { args: row.args }
45
- : {}),
46
- ...(typeof row.error_type === "string" && row.error_type.length > 0
47
- ? { errorType: row.error_type }
48
- : {}),
49
- });
50
- }
51
- return out;
52
- }
53
- /** The producer's facts as the tick feed's extras, with every unreadable field left off. */
54
- export function toTickExtras(facts) {
55
- const commit = typeof facts.commit === "string" && COMMIT_OUTCOMES.has(facts.commit)
56
- ? facts.commit
57
- : undefined;
58
- const state = facts.state !== null && typeof facts.state === "object" && !Array.isArray(facts.state)
59
- ? facts.state
60
- : undefined;
61
- const mcpCalls = calls(facts.mcp_calls);
62
- return {
63
- ...(count(facts.mcp_failures) === undefined ? {} : { mcpFailures: count(facts.mcp_failures) }),
64
- ...(mcpCalls === undefined ? {} : { mcpCalls }),
65
- ...(count(facts.mcp_ms) === undefined ? {} : { mcpMs: count(facts.mcp_ms) }),
66
- ...(count(facts.quiet_ticks) === undefined ? {} : { quietTicks: count(facts.quiet_ticks) }),
67
- // The only signed field: a tick that ran EARLY reports a negative lag, and the frame omits it.
68
- ...(typeof facts.lag_ms === "number" && Number.isFinite(facts.lag_ms)
69
- ? { lagMs: facts.lag_ms }
70
- : {}),
71
- ...(count(facts.journal_pending) === undefined
72
- ? {}
73
- : { journalPending: count(facts.journal_pending) }),
74
- ...(commit === undefined ? {} : { commit }),
75
- ...(state === undefined ? {} : { state }),
76
- ...(count(facts.state_fields) === undefined
77
- ? {}
78
- : { stateFieldCount: count(facts.state_fields) }),
79
- ...(count(facts.state_changed) === undefined
80
- ? {}
81
- : { stateChangedCount: count(facts.state_changed) }),
82
- };
83
- }
84
- /**
85
- * Build the `onTick` both intake routes call.
86
- *
87
- * Resolves against the SHARED IntakeContext registry, like `onAccepted` and `onScaffoldError`, so
88
- * the tick is attributed to the scanner's STABLE name and its runtime's wallet rather than to the
89
- * ephemeral scanner_id a relaunch re-mints — which is the key a client joins a tick to its stats
90
- * row on.
91
- *
92
- * `now` is the runtime clock at the POST, used as the run's finish. The producer's own clock is not
93
- * used: it is a different machine's wall time, and a frame mixing the two would put ticks in an
94
- * order neither machine saw. `startedAt` is derived from the duration the producer measured, which
95
- * keeps `ms` the producer's own number while `t` stays on this box's clock.
96
- */
97
- export function buildScaffoldTickRouter(ctx, now = () => Date.now()) {
98
- return (scannerId, facts) => {
99
- if (facts === null || typeof facts !== "object")
100
- return;
101
- // Checked first, before anything is built: a box no client has ever reached pays one
102
- // comparison per tick and allocates nothing.
103
- if (!hasScannerTickSink())
104
- return;
105
- const entry = ctx.registry.resolve(scannerId);
106
- if (!entry)
107
- return; // zombie fence — a relaunch re-mints the id and unregisters the old one
108
- const finishedAt = now();
109
- const durationMs = count(facts.duration_ms);
110
- const run = {
111
- address: entry.wallet,
112
- scannerId: entry.scannerName,
113
- status: typeof facts.status === "string" && facts.status.length > 0 ? facts.status : "ok",
114
- ...(count(facts.candidate_count) === undefined
115
- ? {}
116
- : { signalCount: count(facts.candidate_count) }),
117
- tick: toTickExtras(facts),
118
- };
119
- recordScannerTick(run, durationMs === undefined ? undefined : finishedAt - durationMs, finishedAt);
120
- };
121
- }
122
- //# sourceMappingURL=scaffold-tick-router.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scaffold-tick-router.js","sourceRoot":"","sources":["../../../src/runtime-api/intake/scaffold-tick-router.ts"],"names":[],"mappings":"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"}
@@ -1,130 +0,0 @@
1
- """Per-tick observability facts the scaffold hands to the intake.
2
-
3
- A scanner tick produces nothing on roughly 99% of ticks, so the only thing a
4
- live screen can show about a working box is what the tick itself reports. These
5
- facts are assembled here, once per tick, and ride the POST the delivery sink
6
- already makes every tick — `/signals` on a clean tick, `/errors` on a failed
7
- one. There is no second channel and no extra request.
8
-
9
- ABSENT IS NOT ZERO. Every field is omitted when its value is unknown, never
10
- defaulted. A `candidate_count` of 0 is a scanner that found nothing; an absent
11
- one would be a scanner that did not say. The distinction has to survive from
12
- here to the screen, so nothing in this module substitutes one for the other.
13
-
14
- The state projection is the LAST COMMITTED row, which makes it stale by one tick
15
- whenever the current tick failed. That is deliberate: a tick that could not
16
- commit is exactly when the last agreed state is worth seeing.
17
- """
18
-
19
- from __future__ import annotations
20
-
21
- from typing import Any, Optional
22
-
23
-
24
- # Per-value character ceiling inside a projected row. An author may park a whole
25
- # serialised payload in one state key; this bounds what one tick can put on the
26
- # wire without bounding what the author may store.
27
- MAX_STATE_VALUE_CHARS = 1024
28
-
29
- # Keys projected out of one state row. Bounds an author's open-ended row the way
30
- # the runtime bounds an open attribute bag.
31
- MAX_STATE_KEYS = 32
32
-
33
-
34
- def _is_scalar(value: Any) -> bool:
35
- """A value a consumer can parse: str, bool, or a FINITE number.
36
-
37
- bool is checked before the numeric branch only implicitly — it is accepted
38
- either way. NaN and the infinities are rejected: they are not JSON, and a
39
- consumer reading one has no way to tell it from a real measurement.
40
- """
41
- if isinstance(value, bool) or isinstance(value, str):
42
- return True
43
- if isinstance(value, (int, float)):
44
- return value == value and value not in (float("inf"), float("-inf"))
45
- return False
46
-
47
-
48
- def project_state_row(row: Any) -> dict:
49
- """The scalar fields of one state row, capped and bounded.
50
-
51
- Returns {} for anything that is not a dict — a row the author replaced with
52
- a list or a string projects to nothing rather than raising inside the loop.
53
- """
54
- if not isinstance(row, dict):
55
- return {}
56
- projected: dict = {}
57
- for key in list(row.keys())[:MAX_STATE_KEYS]:
58
- if not isinstance(key, str):
59
- continue
60
- value = row[key]
61
- if not _is_scalar(value):
62
- continue
63
- projected[key] = value[:MAX_STATE_VALUE_CHARS] if isinstance(value, str) else value
64
- return projected
65
-
66
-
67
- def count_changed(current: dict, previous: Optional[dict]) -> int:
68
- """How many projected fields moved since the previously reported row.
69
-
70
- A first row counts every field as changed: nothing was known before it, so
71
- every value is new information. A key that disappeared counts too — its
72
- absence is a change the operator should see.
73
- """
74
- if previous is None:
75
- return len(current)
76
- keys = set(current) | set(previous)
77
- return sum(1 for key in keys if current.get(key) != previous.get(key))
78
-
79
-
80
- def build_tick_facts(
81
- *,
82
- tick_id: str,
83
- status: str,
84
- candidate_count: int,
85
- duration_ms: int,
86
- commit: Optional[str],
87
- quiet_ticks: int,
88
- lag_ms: Optional[int],
89
- mcp_snapshot: Optional[dict],
90
- call_snapshot: Optional[dict],
91
- state_row: Any,
92
- state_fields: Optional[int],
93
- state_changed: Optional[int],
94
- ) -> dict:
95
- """Assemble one tick's facts for the wire.
96
-
97
- `mcp_snapshot` / `call_snapshot` are the MCP boundary's own per-tick tallies,
98
- or None when the tick ran without an MCP client — which is not the same as a
99
- tick that made no calls, so both keys are then left off entirely.
100
- """
101
- facts: dict = {
102
- "tick_id": tick_id,
103
- "status": status,
104
- "candidate_count": candidate_count,
105
- "duration_ms": duration_ms,
106
- # Always known: the loop either commits, rolls back, or fails to persist.
107
- **({"commit": commit} if commit else {}),
108
- # Zero is a real answer here (this tick produced a signal), so it is sent.
109
- "quiet_ticks": quiet_ticks,
110
- }
111
- # Unknown on the very first tick of a process: there is no previous tick to
112
- # measure the gap against, and a 0 would claim the scanner was exactly on time.
113
- if lag_ms is not None:
114
- facts["lag_ms"] = lag_ms
115
- if mcp_snapshot is not None:
116
- # Every failure the boundary saw this tick. The overwhelming case is a failure the
117
- # author's own `except` caught and turned into an empty return — the one thing that
118
- # otherwise leaves no trace at all. A failure that escaped scan() is in the count too,
119
- # and needs no separating out: it already failed the tick, so `status` names it.
120
- facts["mcp_failures"] = int(mcp_snapshot.get("count") or 0)
121
- if call_snapshot is not None:
122
- facts["mcp_ms"] = call_snapshot.get("total_ms", 0)
123
- facts["mcp_calls"] = call_snapshot.get("calls", [])
124
- projected = project_state_row(state_row)
125
- if state_fields is not None:
126
- facts["state"] = projected
127
- facts["state_fields"] = state_fields
128
- if state_changed is not None:
129
- facts["state_changed"] = state_changed
130
- return facts
@@ -1,58 +0,0 @@
1
- """ULID minting: a 26-character, lexicographically sortable id — 48 bits of millisecond timestamp
2
- followed by 80 bits of randomness, rendered in Crockford's base32. Sortable ids are what let two
3
- ticks be ordered without carrying a second field, and 80 random bits make a collision between two
4
- ticks of the same millisecond unreachable.
5
-
6
- Mirrors src/utils/ulid.ts so a scaffold id and a runtime id are the same kind of value. The random
7
- half is read out of a `uuid.uuid4()`, taking only the ten bytes that carry no version or variant
8
- bits, so all 80 of them are random.
9
- """
10
-
11
- from __future__ import annotations
12
-
13
- import math
14
- import time
15
- import uuid
16
-
17
- # Crockford's base32: no I, L, O or U, so a transcribed id cannot be misread.
18
- CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
19
-
20
- TIME_CHARS = 10
21
- RANDOM_CHARS = 16
22
- MAX_TIME = 2 ** 48 - 1
23
-
24
-
25
- def _encode_time(ms) -> str:
26
- """Render `ms` as the 10-character time prefix.
27
-
28
- Clamped, and never raised from: a clock that reads non-finite, negative, or past the 48-bit
29
- ceiling must still yield a valid id rather than kill the tick that asked for one.
30
- """
31
- try:
32
- remaining = min(max(math.floor(ms), 0), MAX_TIME)
33
- except (OverflowError, ValueError, TypeError):
34
- remaining = 0
35
- out = ""
36
- for _ in range(TIME_CHARS):
37
- out = CROCKFORD[remaining % 32] + out
38
- remaining //= 32
39
- return out
40
-
41
-
42
- def _encode_random() -> str:
43
- """Render 80 random bits as the 16-character suffix, five bits at a time."""
44
- # uuid4 holds its version and variant in bytes 6 and 8; the ten bytes taken here are the
45
- # fully random ones.
46
- raw = uuid.uuid4().bytes
47
- acc = int.from_bytes(raw[:6] + raw[9:13], "big")
48
- return "".join(
49
- CROCKFORD[(acc >> shift) & 31]
50
- for shift in range(RANDOM_CHARS * 5 - 5, -1, -5)
51
- )
52
-
53
-
54
- def new_ulid(now_ms: int | None = None) -> str:
55
- """Mint a ULID. `now_ms` is injectable so a caller can pin the time half in a test."""
56
- if now_ms is None:
57
- now_ms = int(time.time() * 1000)
58
- return _encode_time(now_ms) + _encode_random()
@@ -1,111 +0,0 @@
1
- /**
2
- * Builder for the `plugin.senpi.dsl` payload — what the box believes about the protection on each
3
- * open position it holds DSL state for.
4
- *
5
- * Pure. Every fact arrives as an input; nothing is read from a state manager or a runtime handle
6
- * here, so the shape on the wire is testable without booting a runtime.
7
- *
8
- * Three properties this module exists to hold:
9
- *
10
- * - **Absence is a claim, and it is never spelled as a value.** A field the box has not measured is
11
- * omitted from the entry. `slOrderId: null` says there is no stop; an absent `slOrderId` says this
12
- * box cannot say. A `0`, a `""` or a synthesised timestamp in either place would read as a
13
- * measurement that was never taken, and the reader has no way to tell the difference afterwards.
14
- * That is why every field is copied through a presence test rather than defaulted, and why the
15
- * wire type marks them optional: the payload has to be able to make both statements.
16
- * - **The venue's answer is carried beside the belief, never folded into it.** `lastVenueStatus` is
17
- * what the venue said about the position's own {@link DslState.slOrderId}; `backendSlVenueStatus`
18
- * is what it said about the backend ratchet's `activeSLOrderId`. They are different orders, and a
19
- * panel that showed one under the other's name would state a confirmation the box never got.
20
- * - **The payload is bounded in bytes, not in entries.** See {@link capDslPositions}.
21
- */
22
- import type { DslState, HandoffStatus } from "../types/dsl/index.js";
23
- /** Payload schema version. Bump when a field changes meaning, not when one is added. */
24
- export declare const DSL_POSITIONS_VERSION = 1;
25
- /** One active DSL state, with the runtime that holds it. */
26
- export interface DslPositionSource {
27
- runtimeId: string;
28
- state: DslState;
29
- }
30
- /**
31
- * One position's protection, as it goes on the wire.
32
- *
33
- * Every field but the three identity ones is optional, and that is the contract rather than a
34
- * looseness: a state row that does not hold a field yields an entry that does not carry it, and a
35
- * client reads the missing key as "this box has not measured that" — the one reading it must never
36
- * confuse with a measured zero.
37
- */
38
- export interface DslPositionEntry {
39
- /** The runtime holding the state. Present always: it is the map key the source was read under. */
40
- runtimeId: string;
41
- /** Normalized, so this joins to the other payloads' `address` on the same spelling. */
42
- address: string;
43
- asset: string;
44
- /** The book. `""` is the default perp book and a real answer, which is why it is not a default. */
45
- dex?: string;
46
- direction?: "LONG" | "SHORT";
47
- entryPrice?: number;
48
- size?: number;
49
- leverage?: number;
50
- phase?: 1 | 2;
51
- /** The floor the breach check compares the mark against, as of the last evaluated tick. */
52
- floorPrice?: number;
53
- /** `phase1.absoluteFloor` — the max-loss level, the only thing the venue holds in phase 1. */
54
- absoluteFloor?: number;
55
- /** `null` means no stop is cached. Absent means this box has not measured one. */
56
- slOrderId?: number | null;
57
- /** The price REQUESTED of the venue, never one read back. */
58
- lastSyncedFloorPrice?: number | null;
59
- /** A write timestamp, not a confirmation timestamp. */
60
- slOrderIdUpdatedAt?: string | null;
61
- handoffStatus?: HandoffStatus | null;
62
- currentBreachCount?: number;
63
- /** `phase1.consecutiveBreachesRequired`, which the engine applies in both phases. */
64
- consecutiveBreachesRequired?: number;
65
- slSyncFailureCount?: number;
66
- pendingClose?: boolean;
67
- consecutiveFetchFailures?: number;
68
- /** The venue's last answer about {@link slOrderId}, verbatim. Absent until the venue answered. */
69
- lastVenueStatus?: string;
70
- lastVenueStatusAt?: number;
71
- /**
72
- * The venue's last answer about the BACKEND ratchet's `activeSLOrderId` — a different order from
73
- * {@link slOrderId}. It is what says why a handoff is sitting at `"pending"`.
74
- */
75
- backendSlVenueStatus?: string;
76
- backendSlVenueStatusAt?: number;
77
- }
78
- export interface DslPositionsPayload {
79
- v: number;
80
- epoch: string;
81
- generatedAt: number;
82
- positions: DslPositionEntry[];
83
- /**
84
- * Positions this frame could not carry within the byte budget. Always present: it is measured on
85
- * every build, so `0` here is the box saying it withheld nothing, not a field it never filled.
86
- */
87
- dropped: number;
88
- }
89
- export interface BuildDslPositionsInput {
90
- /** The buffer's epoch ULID. A change means the plugin restarted. */
91
- epoch: string;
92
- positions: DslPositionSource[];
93
- /** Injectable clock for deterministic tests. */
94
- now?: () => number;
95
- }
96
- /** Builds one `plugin.senpi.dsl` payload from an already-gathered set of active states. */
97
- export declare function buildDslPositions(input: BuildDslPositionsInput): DslPositionsPayload;
98
- /**
99
- * The payload, trimmed to fit one frame.
100
- *
101
- * Bytes and not an entry count, for the same reason the tick frame counts bytes: one non-ASCII
102
- * character in a venue-authored status costs up to three of them, and the read limit at the far end
103
- * counts bytes. A frame past that limit does not cost the one frame — it closes the client's socket
104
- * and costs the stream — so a box with more positions than fit sends the ones that do and states how
105
- * many it withheld, rather than sending an oversized frame or silently shortening the list.
106
- *
107
- * Taken on the SCRUBBED payload and never before it: a redaction can be longer than the text it
108
- * replaced, so a cut taken first bounds the input rather than what leaves.
109
- */
110
- export declare function capDslPositions(payload: DslPositionsPayload, maxBytes: number): DslPositionsPayload;
111
- //# sourceMappingURL=dsl-positions.d.ts.map