@senpi/runtime 3.0.132 → 3.0.138

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 (287) hide show
  1. package/README.md +4 -12
  2. package/dist/actions/action-events.d.ts +7 -21
  3. package/dist/actions/action-events.d.ts.map +1 -1
  4. package/dist/actions/action-events.js +26 -54
  5. package/dist/actions/action-events.js.map +1 -1
  6. package/dist/actions/action-runtime-module.d.ts.map +1 -1
  7. package/dist/actions/action-runtime-module.js +7 -38
  8. package/dist/actions/action-runtime-module.js.map +1 -1
  9. package/dist/actions/close-position/close-position.action.d.ts.map +1 -1
  10. package/dist/actions/close-position/close-position.action.js +15 -122
  11. package/dist/actions/close-position/close-position.action.js.map +1 -1
  12. package/dist/actions/decision-engine.d.ts.map +1 -1
  13. package/dist/actions/decision-engine.js +2 -15
  14. package/dist/actions/decision-engine.js.map +1 -1
  15. package/dist/actions/event-derivation.d.ts +2 -71
  16. package/dist/actions/event-derivation.d.ts.map +1 -1
  17. package/dist/actions/event-derivation.js +8 -251
  18. package/dist/actions/event-derivation.js.map +1 -1
  19. package/dist/actions/open-position/open-position.action.d.ts +2 -12
  20. package/dist/actions/open-position/open-position.action.d.ts.map +1 -1
  21. package/dist/actions/open-position/open-position.action.js +41 -144
  22. package/dist/actions/open-position/open-position.action.js.map +1 -1
  23. package/dist/actions/position-tracker/position-tracker.action.d.ts +1 -2
  24. package/dist/actions/position-tracker/position-tracker.action.d.ts.map +1 -1
  25. package/dist/actions/position-tracker/position-tracker.action.js +17 -62
  26. package/dist/actions/position-tracker/position-tracker.action.js.map +1 -1
  27. package/dist/actions/store/types.d.ts +2 -9
  28. package/dist/actions/store/types.d.ts.map +1 -1
  29. package/dist/actions/store/types.js.map +1 -1
  30. package/dist/actions/types.d.ts +0 -13
  31. package/dist/actions/types.d.ts.map +1 -1
  32. package/dist/actions/types.js +0 -13
  33. package/dist/actions/types.js.map +1 -1
  34. package/dist/cli/guide-commands.d.ts.map +1 -1
  35. package/dist/cli/guide-commands.js +13 -8
  36. package/dist/cli/guide-commands.js.map +1 -1
  37. package/dist/cli/senpi-commands.d.ts.map +1 -1
  38. package/dist/cli/senpi-commands.js +11 -4
  39. package/dist/cli/senpi-commands.js.map +1 -1
  40. package/dist/constants/dsl/index.d.ts +0 -6
  41. package/dist/constants/dsl/index.d.ts.map +1 -1
  42. package/dist/constants/dsl/index.js +0 -6
  43. package/dist/constants/dsl/index.js.map +1 -1
  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 +6 -8
  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 +4 -27
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +41 -271
  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/auto-update/coordinator.d.ts +6 -13
  83. package/dist/runtime/auto-update/coordinator.d.ts.map +1 -1
  84. package/dist/runtime/auto-update/coordinator.js +18 -86
  85. package/dist/runtime/auto-update/coordinator.js.map +1 -1
  86. package/dist/runtime/auto-update/run-update-command.d.ts.map +1 -1
  87. package/dist/runtime/auto-update/run-update-command.js +3 -4
  88. package/dist/runtime/auto-update/run-update-command.js.map +1 -1
  89. package/dist/runtime/auto-update/types.d.ts +5 -11
  90. package/dist/runtime/auto-update/types.d.ts.map +1 -1
  91. package/dist/runtime/auto-update/types.js +0 -11
  92. package/dist/runtime/auto-update/types.js.map +1 -1
  93. package/dist/runtime/domain-events.d.ts.map +1 -1
  94. package/dist/runtime/domain-events.js +0 -7
  95. package/dist/runtime/domain-events.js.map +1 -1
  96. package/dist/runtime/lifecycle-events.d.ts +3 -15
  97. package/dist/runtime/lifecycle-events.d.ts.map +1 -1
  98. package/dist/runtime/lifecycle-events.js +3 -17
  99. package/dist/runtime/lifecycle-events.js.map +1 -1
  100. package/dist/runtime/lifecycle-reaper.d.ts +6 -4
  101. package/dist/runtime/lifecycle-reaper.d.ts.map +1 -1
  102. package/dist/runtime/lifecycle-reaper.js +6 -4
  103. package/dist/runtime/lifecycle-reaper.js.map +1 -1
  104. package/dist/runtime/reconcile-run.d.ts +3 -13
  105. package/dist/runtime/reconcile-run.d.ts.map +1 -1
  106. package/dist/runtime/reconcile-run.js +3 -4
  107. package/dist/runtime/reconcile-run.js.map +1 -1
  108. package/dist/runtime/reconcile-state.d.ts +0 -8
  109. package/dist/runtime/reconcile-state.d.ts.map +1 -1
  110. package/dist/runtime/reconcile-state.js +1 -4
  111. package/dist/runtime/reconcile-state.js.map +1 -1
  112. package/dist/runtime/risk-guard.d.ts +20 -1
  113. package/dist/runtime/risk-guard.d.ts.map +1 -1
  114. package/dist/runtime/risk-guard.js +47 -6
  115. package/dist/runtime/risk-guard.js.map +1 -1
  116. package/dist/runtime/run.d.ts +0 -1
  117. package/dist/runtime/run.d.ts.map +1 -1
  118. package/dist/runtime/run.js.map +1 -1
  119. package/dist/runtime/runtime-schema.js +3 -3
  120. package/dist/runtime/runtime-schema.js.map +1 -1
  121. package/dist/runtime/runtime.d.ts +3 -2
  122. package/dist/runtime/runtime.d.ts.map +1 -1
  123. package/dist/runtime/runtime.js +30 -37
  124. package/dist/runtime/runtime.js.map +1 -1
  125. package/dist/runtime/strategy-lifecycle.d.ts +108 -2
  126. package/dist/runtime/strategy-lifecycle.d.ts.map +1 -1
  127. package/dist/runtime/strategy-lifecycle.js +325 -4
  128. package/dist/runtime/strategy-lifecycle.js.map +1 -1
  129. package/dist/runtime/supervisor/long-running-supervisor.d.ts +0 -13
  130. package/dist/runtime/supervisor/long-running-supervisor.d.ts.map +1 -1
  131. package/dist/runtime/supervisor/long-running-supervisor.js +0 -1
  132. package/dist/runtime/supervisor/long-running-supervisor.js.map +1 -1
  133. package/dist/runtime/validate-dsl-position-tracking.d.ts.map +1 -1
  134. package/dist/runtime/validate-dsl-position-tracking.js +1 -2
  135. package/dist/runtime/validate-dsl-position-tracking.js.map +1 -1
  136. package/dist/runtime-api/handlers/ingest-signals.d.ts.map +1 -1
  137. package/dist/runtime-api/handlers/ingest-signals.js +0 -1
  138. package/dist/runtime-api/handlers/ingest-signals.js.map +1 -1
  139. package/dist/runtime-api/handlers/types.d.ts +0 -5
  140. package/dist/runtime-api/handlers/types.d.ts.map +1 -1
  141. package/dist/runtime-api/intake/intake-events.d.ts +1 -1
  142. package/dist/runtime-api/intake/intake-events.d.ts.map +1 -1
  143. package/dist/runtime-api/intake/intake-events.js +3 -9
  144. package/dist/runtime-api/intake/intake-events.js.map +1 -1
  145. package/dist/runtime-api/intake/intake-mount.d.ts.map +1 -1
  146. package/dist/runtime-api/intake/intake-mount.js +19 -4
  147. package/dist/runtime-api/intake/intake-mount.js.map +1 -1
  148. package/dist/runtime-api/intake/process-error-post.d.ts +1 -6
  149. package/dist/runtime-api/intake/process-error-post.d.ts.map +1 -1
  150. package/dist/runtime-api/intake/process-error-post.js +1 -5
  151. package/dist/runtime-api/intake/process-error-post.js.map +1 -1
  152. package/dist/runtime-api/intake/process-signal-post.d.ts +1 -7
  153. package/dist/runtime-api/intake/process-signal-post.d.ts.map +1 -1
  154. package/dist/runtime-api/intake/process-signal-post.js +0 -5
  155. package/dist/runtime-api/intake/process-signal-post.js.map +1 -1
  156. package/dist/runtime-api/intake/scaffold-error-router.js.map +1 -1
  157. package/dist/runtime-api/intake/scanner-launcher.d.ts.map +1 -1
  158. package/dist/runtime-api/intake/scanner-launcher.js +0 -15
  159. package/dist/runtime-api/intake/scanner-launcher.js.map +1 -1
  160. package/dist/runtime-api/intake/types.d.ts +0 -55
  161. package/dist/runtime-api/intake/types.d.ts.map +1 -1
  162. package/dist/runtime-api/routes/signals.d.ts +0 -2
  163. package/dist/runtime-api/routes/signals.d.ts.map +1 -1
  164. package/dist/runtime-api/routes/signals.js +1 -5
  165. package/dist/runtime-api/routes/signals.js.map +1 -1
  166. package/dist/runtime-api/routes/signals.schema.d.ts +0 -43
  167. package/dist/runtime-api/routes/signals.schema.d.ts.map +1 -1
  168. package/dist/runtime-api/routes/signals.schema.js +0 -43
  169. package/dist/runtime-api/routes/signals.schema.js.map +1 -1
  170. package/dist/runtime-api/server.d.ts +1 -7
  171. package/dist/runtime-api/server.d.ts.map +1 -1
  172. package/dist/runtime-api/server.js +0 -1
  173. package/dist/runtime-api/server.js.map +1 -1
  174. package/dist/scanners/engine/engine.d.ts +1 -22
  175. package/dist/scanners/engine/engine.d.ts.map +1 -1
  176. package/dist/scanners/engine/engine.js +11 -78
  177. package/dist/scanners/engine/engine.js.map +1 -1
  178. package/dist/scanners/engine/lifecycle.d.ts +1 -7
  179. package/dist/scanners/engine/lifecycle.d.ts.map +1 -1
  180. package/dist/scanners/events.d.ts +0 -4
  181. package/dist/scanners/events.d.ts.map +1 -1
  182. package/dist/scanners/events.js +0 -2
  183. package/dist/scanners/events.js.map +1 -1
  184. package/dist/scanners/external/scaffold/delivery.py +25 -194
  185. package/dist/scanners/external/scaffold/scaffold.py +31 -172
  186. package/dist/scanners/external/scaffold/senpi_mcp.py +8 -150
  187. package/dist/scanners/external-scanner-receiver.d.ts +0 -17
  188. package/dist/scanners/external-scanner-receiver.d.ts.map +1 -1
  189. package/dist/scanners/external-scanner-receiver.js +0 -8
  190. package/dist/scanners/external-scanner-receiver.js.map +1 -1
  191. package/dist/scanners/runtime-module.d.ts +0 -1
  192. package/dist/scanners/runtime-module.d.ts.map +1 -1
  193. package/dist/scanners/runtime-module.js +9 -66
  194. package/dist/scanners/runtime-module.js.map +1 -1
  195. package/dist/telemetry/attributes.d.ts +0 -20
  196. package/dist/telemetry/attributes.d.ts.map +1 -1
  197. package/dist/telemetry/attributes.js +0 -24
  198. package/dist/telemetry/attributes.js.map +1 -1
  199. package/dist/telemetry/event-builders.d.ts +6 -81
  200. package/dist/telemetry/event-builders.d.ts.map +1 -1
  201. package/dist/telemetry/event-builders.js +17 -141
  202. package/dist/telemetry/event-builders.js.map +1 -1
  203. package/dist/telemetry/event-store.d.ts +0 -6
  204. package/dist/telemetry/event-store.d.ts.map +1 -1
  205. package/dist/telemetry/event-store.js +8 -12
  206. package/dist/telemetry/event-store.js.map +1 -1
  207. package/dist/telemetry/metrics.d.ts +2 -14
  208. package/dist/telemetry/metrics.d.ts.map +1 -1
  209. package/dist/telemetry/metrics.js +4 -19
  210. package/dist/telemetry/metrics.js.map +1 -1
  211. package/dist/telemetry/spans/redact-pii.d.ts.map +1 -1
  212. package/dist/telemetry/spans/redact-pii.js +2 -18
  213. package/dist/telemetry/spans/redact-pii.js.map +1 -1
  214. package/dist/telemetry/tracing.d.ts +0 -9
  215. package/dist/telemetry/tracing.d.ts.map +1 -1
  216. package/dist/telemetry/tracing.js +0 -36
  217. package/dist/telemetry/tracing.js.map +1 -1
  218. package/dist/types/dsl/index.d.ts +0 -48
  219. package/dist/types/dsl/index.d.ts.map +1 -1
  220. package/dist/types/scanner.d.ts +0 -15
  221. package/dist/types/scanner.d.ts.map +1 -1
  222. package/dist/utils/event-catalog.d.ts +0 -202
  223. package/dist/utils/event-catalog.d.ts.map +1 -1
  224. package/dist/utils/event-catalog.js +0 -26
  225. package/dist/utils/event-catalog.js.map +1 -1
  226. package/dist/utils/logger.d.ts +1 -4
  227. package/dist/utils/logger.d.ts.map +1 -1
  228. package/dist/utils/logger.js.map +1 -1
  229. package/dist/validate/recipe-checks.d.ts.map +1 -1
  230. package/dist/validate/recipe-checks.js +2 -2
  231. package/dist/validate/recipe-checks.js.map +1 -1
  232. package/openclaw.plugin.json +4 -8
  233. package/package.json +1 -1
  234. package/dist/actions/skipped-signal-results.d.ts +0 -25
  235. package/dist/actions/skipped-signal-results.d.ts.map +0 -1
  236. package/dist/actions/skipped-signal-results.js +0 -71
  237. package/dist/actions/skipped-signal-results.js.map +0 -1
  238. package/dist/runtime-api/intake/ingest-request.d.ts +0 -17
  239. package/dist/runtime-api/intake/ingest-request.d.ts.map +0 -1
  240. package/dist/runtime-api/intake/ingest-request.js +0 -34
  241. package/dist/runtime-api/intake/ingest-request.js.map +0 -1
  242. package/dist/runtime-api/intake/scaffold-tick-router.d.ts +0 -39
  243. package/dist/runtime-api/intake/scaffold-tick-router.d.ts.map +0 -1
  244. package/dist/runtime-api/intake/scaffold-tick-router.js +0 -122
  245. package/dist/runtime-api/intake/scaffold-tick-router.js.map +0 -1
  246. package/dist/scanners/external/scaffold/tick_facts.py +0 -130
  247. package/dist/scanners/external/scaffold/ulid.py +0 -58
  248. package/dist/telemetry/dsl-positions.d.ts +0 -111
  249. package/dist/telemetry/dsl-positions.d.ts.map +0 -1
  250. package/dist/telemetry/dsl-positions.js +0 -118
  251. package/dist/telemetry/dsl-positions.js.map +0 -1
  252. package/dist/telemetry/live-telemetry.d.ts +0 -257
  253. package/dist/telemetry/live-telemetry.d.ts.map +0 -1
  254. package/dist/telemetry/live-telemetry.js +0 -959
  255. package/dist/telemetry/live-telemetry.js.map +0 -1
  256. package/dist/telemetry/scanner-stats.d.ts +0 -143
  257. package/dist/telemetry/scanner-stats.d.ts.map +0 -1
  258. package/dist/telemetry/scanner-stats.js +0 -426
  259. package/dist/telemetry/scanner-stats.js.map +0 -1
  260. package/dist/telemetry/scanner-tick-feed.d.ts +0 -87
  261. package/dist/telemetry/scanner-tick-feed.d.ts.map +0 -1
  262. package/dist/telemetry/scanner-tick-feed.js +0 -48
  263. package/dist/telemetry/scanner-tick-feed.js.map +0 -1
  264. package/dist/telemetry/strategy-topology.d.ts +0 -99
  265. package/dist/telemetry/strategy-topology.d.ts.map +0 -1
  266. package/dist/telemetry/strategy-topology.js +0 -93
  267. package/dist/telemetry/strategy-topology.js.map +0 -1
  268. package/dist/telemetry/telemetry-publisher.d.ts +0 -83
  269. package/dist/telemetry/telemetry-publisher.d.ts.map +0 -1
  270. package/dist/telemetry/telemetry-publisher.js +0 -256
  271. package/dist/telemetry/telemetry-publisher.js.map +0 -1
  272. package/dist/telemetry/tick-frame.d.ts +0 -212
  273. package/dist/telemetry/tick-frame.d.ts.map +0 -1
  274. package/dist/telemetry/tick-frame.js +0 -421
  275. package/dist/telemetry/tick-frame.js.map +0 -1
  276. package/dist/telemetry/timeline-buffer.d.ts +0 -95
  277. package/dist/telemetry/timeline-buffer.d.ts.map +0 -1
  278. package/dist/telemetry/timeline-buffer.js +0 -237
  279. package/dist/telemetry/timeline-buffer.js.map +0 -1
  280. package/dist/utils/telemetry-required-log.d.ts +0 -60
  281. package/dist/utils/telemetry-required-log.d.ts.map +0 -1
  282. package/dist/utils/telemetry-required-log.js +0 -105
  283. package/dist/utils/telemetry-required-log.js.map +0 -1
  284. package/dist/utils/ulid.d.ts +0 -9
  285. package/dist/utils/ulid.d.ts.map +0 -1
  286. package/dist/utils/ulid.js +0 -43
  287. package/dist/utils/ulid.js.map +0 -1
@@ -1,12 +1,32 @@
1
1
  /**
2
- * In-memory seed of the Theme-4 strategy lifecycle state machine (running→paused→stopped).
3
- * Short-term (§4); the durable crash-safe (SQLite) version is §5 merge work.
2
+ * Seed of the Theme-4 strategy lifecycle state machine (running→paused→stopped). The self-pause
3
+ * state is in memory; the halt latches are persisted (below). Short-term (§4); the durable
4
+ * crash-safe (SQLite) version is §5 merge work.
4
5
  *
5
6
  * Owns the self-pause state that RiskGuard used to hold. RiskGuard is now a stateless
6
7
  * gate evaluator that only reports; this component remembers which gates are currently
7
8
  * paused per strategy and fires the hook event + user notification on a genuine
8
9
  * running→paused transition, deduped so it alerts once per breach and re-arms only on
9
10
  * an explicit OPEN (re-running) of the same gate.
11
+ *
12
+ * It also owns the halt LATCH for the halt-class gates in {@link LATCHED_GATES}
13
+ * (daily loss, drawdown). Their live inputs are mark-to-market, so a strategy sitting
14
+ * near its limit reads breached / not-breached on every price bounce; without a latch
15
+ * each bounce reopened entries mid-day. {@link StrategyLifecycle.applyLatch} is called by
16
+ * the risk guard on every evaluation of those gates and overrides a fresh OPEN with
17
+ * CLOSED until the latch's release rule fires:
18
+ * - daily_loss_halt: the next UTC day (day taken from the MCP snapshot, not the box clock);
19
+ * - drawdown_halt: the next UTC day only when `drawdown_reset_on_day_rollover` is true;
20
+ * otherwise never.
21
+ * A latch for a gate that is no longer configured is dropped when the recipe is rebuilt
22
+ * ({@link StrategyLifecycle.pruneLatches}), so re-adding the rail later starts clean.
23
+ *
24
+ * Latches are persisted per strategy through {@link StrategyLifecycleDeps.latchStore} (the
25
+ * runtime's StateManager, file `<stateDir>/<address>/risk-halt-latch.json`), so a latch survives
26
+ * a gateway restart, an npm auto-update and a fleet redeploy: the restarted runtime reloads it on
27
+ * the strategy's first halt check and enforces it exactly as before, with the same release rules.
28
+ * The self-pause state above is still in memory only, so a restored latch announces its pause
29
+ * once more after a restart.
10
30
  */
11
31
  import type { RiskGateEvaluation, RiskGateId, RiskSource } from "../health/types.js";
12
32
  import type { HookSystem } from "../types/hooks.js";
@@ -43,6 +63,62 @@ export interface StrategyLifecycleDeps {
43
63
  notifications?: NotificationService;
44
64
  /** Runtime name attached to fired hook events (defaults to "runtime"). */
45
65
  runtimeName?: string;
66
+ /**
67
+ * Durable home for the halt latches (the runtime passes its StateManager). Without it the
68
+ * latches live in memory only and a gateway restart forgets them, which is the behaviour tests
69
+ * and the stub path get.
70
+ */
71
+ latchStore?: HaltLatchStore;
72
+ }
73
+ /**
74
+ * The slice of StateManager the halt latch persists through. Typed structurally so a test can
75
+ * hand in a fake; StateManager satisfies it as-is.
76
+ *
77
+ * Contract relied on: `getOrLoad` resolves undefined when nothing is stored (StateManager also
78
+ * resolves undefined for a corrupt file, which it tombstones and warns about) and REJECTS on a
79
+ * transient IO error; `set` persists durably or rejects.
80
+ */
81
+ export interface HaltLatchStore {
82
+ getOrLoad(key: string): Promise<unknown>;
83
+ set(key: string, value: unknown): Promise<void>;
84
+ }
85
+ /**
86
+ * State key of a strategy's persisted halt latches. StateManager maps it to
87
+ * `<stateDir>/<address>/risk-halt-latch.json`: inside the strategy's own dir, so it is archived
88
+ * with the strategy, and not `strategy` / `dsl-*`, so hydrate and the DSL listings ignore it.
89
+ */
90
+ export declare function haltLatchKey(address: string): string;
91
+ /** Schema version of the persisted latch file; any other version is read as "no latch". */
92
+ export declare const HALT_LATCH_STATE_VERSION = 1;
93
+ /**
94
+ * Halt-class gates whose genuine breach latches until its release rule fires, instead of
95
+ * reopening on the next non-breached reading. `max_entries_day` is deliberately absent:
96
+ * its mid-day reopen is tracked separately and keeps the pre-latch behaviour here.
97
+ */
98
+ export declare const LATCHED_GATES: ReadonlySet<RiskGateId>;
99
+ export interface ApplyLatchOpts {
100
+ /**
101
+ * Release the latch when an evaluation from a later UTC day arrives. Always true for
102
+ * daily_loss_halt; `drawdown_reset_on_day_rollover` for drawdown_halt.
103
+ */
104
+ releaseOnDayRollover: boolean;
105
+ }
106
+ /** What a latch remembers about the breach that set it. Also its persisted per-gate shape. */
107
+ export interface HaltLatch {
108
+ /** UTC day (YYYY-MM-DD) of the snapshot that tripped the gate. */
109
+ utcDay: string;
110
+ /** Wall-clock ISO time the latch was set. */
111
+ latchedAt: string;
112
+ /** The breaching evaluation's own reason (live numbers at trip time). */
113
+ trippedReason: string;
114
+ }
115
+ /**
116
+ * On-disk shape of one strategy's halt latches. An address with nothing latched is written as
117
+ * `{ version: 1, gates: {} }` rather than deleted, so "cleared" is a durable fact too.
118
+ */
119
+ export interface PersistedHaltLatches {
120
+ version: typeof HALT_LATCH_STATE_VERSION;
121
+ gates: Partial<Record<RiskGateId, HaltLatch>>;
46
122
  }
47
123
  export interface StrategyLifecycle {
48
124
  /**
@@ -53,6 +129,36 @@ export interface StrategyLifecycle {
53
129
  * @param source evaluation source (runtime / cli)
54
130
  */
55
131
  observe(address: string, label: string, evaluations: RiskGateEvaluation[], source: RiskSource): void;
132
+ /**
133
+ * Apply the halt latch to one fresh evaluation of a {@link LATCHED_GATES} gate and return
134
+ * the evaluation to enforce (other gates pass through untouched).
135
+ *
136
+ * - A genuine breach (CLOSED + evaluationOk + no fallback) sets the latch if none is held.
137
+ * Fail-closed / fallback evaluations never set it.
138
+ * - While latched, a fresh OPEN is overridden to CLOSED with a latched reason and
139
+ * `evaluationOk: true` — the evaluation itself succeeded; the gate is closed by the latch.
140
+ * - The latch is released only by a successful evaluation from a later UTC day, and only
141
+ * when `opts.releaseOnDayRollover` is true. The fresh evaluation is then enforced as-is.
142
+ *
143
+ * Async because of persistence: the strategy's persisted latches are loaded on its first call,
144
+ * and a set or release is written before the verdict returns. It cannot throw.
145
+ * - A failed load fails closed for that call: CLOSED with `evaluationOk: false`,
146
+ * `fallbackApplied: true`, `failureKind: "transport"`, like a failed snapshot fetch. A latch on
147
+ * disk this process has not read must not read as OPEN. Nothing is set or released on that
148
+ * call, so no pause fires; the next call retries the load.
149
+ * - A failed write is logged and never changes the verdict: the in-memory latch keeps enforcing.
150
+ */
151
+ applyLatch(address: string, evaluation: RiskGateEvaluation, opts: ApplyLatchOpts): Promise<RiskGateEvaluation>;
152
+ /**
153
+ * Drop the latches (and the matching pause state) of latched gates that are no longer
154
+ * configured for `address`. Called when the recipe is rebuilt: a gate whose rail was removed
155
+ * no longer enforces anything, so its latch must not resurface if the rail is added back later.
156
+ * Emits `runtime.resumed` for a dropped gate that was paused.
157
+ *
158
+ * Loads the persisted latches first (so a latch saved by an earlier process is pruned too) and
159
+ * writes the result. Never throws: the rebuild commit that calls it must not fail on disk IO.
160
+ */
161
+ pruneLatches(address: string, configured: ReadonlySet<RiskGateId>): Promise<void>;
56
162
  }
57
163
  export declare function createStrategyLifecycle(deps?: StrategyLifecycleDeps): StrategyLifecycle;
58
164
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"strategy-lifecycle.d.ts","sourceRoot":"","sources":["../../src/runtime/strategy-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,KAAK,EAAE,gBAAgB,EAAuB,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAO3G;;;kEAGkE;AAClE,UAAU,SAAS;IACjB,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;IACd;2DACuD;IACvD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,CAIrE,CAAC;AA6HF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EACnD,MAAM,EAAE,MAAM,GACb,gBAAgB,CAGlB;AAED,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,yEAAyE;IACzE,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,OAAO,CACL,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,kBAAkB,EAAE,EACjC,MAAM,EAAE,UAAU,GACjB,IAAI,CAAC;CACT;AAED,wBAAgB,uBAAuB,CAAC,IAAI,GAAE,qBAA0B,GAAG,iBAAiB,CAyE3F"}
1
+ {"version":3,"file":"strategy-lifecycle.d.ts","sourceRoot":"","sources":["../../src/runtime/strategy-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,KAAK,EAAE,gBAAgB,EAAuB,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAO3G;;;kEAGkE;AAClE,UAAU,SAAS;IACjB,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;IACd;2DACuD;IACvD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,CAIrE,CAAC;AAkIF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EACnD,MAAM,EAAE,MAAM,GACb,gBAAgB,CAGlB;AAED,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,yEAAyE;IACzE,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,2FAA2F;AAC3F,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,UAAU,CAGhD,CAAC;AAEH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED,8FAA8F;AAC9F,MAAM,WAAW,SAAS;IACxB,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,aAAa,EAAE,MAAM,CAAC;CACvB;AAgBD;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,wBAAwB,CAAC;IACzC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC;CAC/C;AA6ED,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,OAAO,CACL,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,kBAAkB,EAAE,EACjC,MAAM,EAAE,UAAU,GACjB,IAAI,CAAC;IAER;;;;;;;;;;;;;;;;;;OAkBG;IACH,UAAU,CACR,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,kBAAkB,EAC9B,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAE/B;;;;;;;;OAQG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnF;AAED,wBAAgB,uBAAuB,CAAC,IAAI,GAAE,qBAA0B,GAAG,iBAAiB,CAsQ3F"}
@@ -1,14 +1,35 @@
1
1
  /**
2
- * In-memory seed of the Theme-4 strategy lifecycle state machine (running→paused→stopped).
3
- * Short-term (§4); the durable crash-safe (SQLite) version is §5 merge work.
2
+ * Seed of the Theme-4 strategy lifecycle state machine (running→paused→stopped). The self-pause
3
+ * state is in memory; the halt latches are persisted (below). Short-term (§4); the durable
4
+ * crash-safe (SQLite) version is §5 merge work.
4
5
  *
5
6
  * Owns the self-pause state that RiskGuard used to hold. RiskGuard is now a stateless
6
7
  * gate evaluator that only reports; this component remembers which gates are currently
7
8
  * paused per strategy and fires the hook event + user notification on a genuine
8
9
  * running→paused transition, deduped so it alerts once per breach and re-arms only on
9
10
  * an explicit OPEN (re-running) of the same gate.
11
+ *
12
+ * It also owns the halt LATCH for the halt-class gates in {@link LATCHED_GATES}
13
+ * (daily loss, drawdown). Their live inputs are mark-to-market, so a strategy sitting
14
+ * near its limit reads breached / not-breached on every price bounce; without a latch
15
+ * each bounce reopened entries mid-day. {@link StrategyLifecycle.applyLatch} is called by
16
+ * the risk guard on every evaluation of those gates and overrides a fresh OPEN with
17
+ * CLOSED until the latch's release rule fires:
18
+ * - daily_loss_halt: the next UTC day (day taken from the MCP snapshot, not the box clock);
19
+ * - drawdown_halt: the next UTC day only when `drawdown_reset_on_day_rollover` is true;
20
+ * otherwise never.
21
+ * A latch for a gate that is no longer configured is dropped when the recipe is rebuilt
22
+ * ({@link StrategyLifecycle.pruneLatches}), so re-adding the rail later starts clean.
23
+ *
24
+ * Latches are persisted per strategy through {@link StrategyLifecycleDeps.latchStore} (the
25
+ * runtime's StateManager, file `<stateDir>/<address>/risk-halt-latch.json`), so a latch survives
26
+ * a gateway restart, an npm auto-update and a fleet redeploy: the restarted runtime reloads it on
27
+ * the strategy's first halt check and enforces it exactly as before, with the same release rules.
28
+ * The self-pause state above is still in memory only, so a restored latch announces its pause
29
+ * once more after a restart.
10
30
  */
11
31
  import { randomUUID } from "node:crypto";
32
+ import { RISK_GATE_NAMES } from "../health/types.js";
12
33
  import { HOOK_EVENT } from "../types/hooks.js";
13
34
  import { createLogger } from "../utils/logger.js";
14
35
  import { buildRuntimePausedEvent, buildRuntimeResumedEvent } from "./lifecycle-events.js";
@@ -114,10 +135,15 @@ const GATE_BLOCK_COPY_BUILDERS = {
114
135
  return fallbackLimitCopy(reason);
115
136
  }
116
137
  const ddStr = dd.toFixed(1);
138
+ // The halt latch stamps `latchReleasesAt`: an ISO instant when the latch releases at the next
139
+ // UTC midnight (`drawdown_reset_on_day_rollover: true`), null when it never auto-releases.
140
+ const releasesAtMidnight = typeof m.latchReleasesAt === "string";
117
141
  return {
118
142
  pushBody: `⚠️ <StrategySkillName/> drawdown limit — trades paused`,
119
143
  inApp: `⚠️ <b>Drawdown limit hit</b> — down <number>${ddStr}%</number> from peak<br>` +
120
- `New trades paused. Won't auto-reset — reply to review.`,
144
+ (releasesAtMidnight
145
+ ? `New trades paused until 00:00 UTC. Open positions keep running.`
146
+ : `New trades paused. Won't auto-reset — reply to review.`),
121
147
  };
122
148
  },
123
149
  };
@@ -142,6 +168,110 @@ export function buildGateBlockCopy(gateId, metrics, reason) {
142
168
  const m = (metrics ?? {});
143
169
  return GATE_BLOCK_COPY_BUILDERS[gateId]?.(m, reason) ?? fallbackLimitCopy(reason);
144
170
  }
171
+ /**
172
+ * State key of a strategy's persisted halt latches. StateManager maps it to
173
+ * `<stateDir>/<address>/risk-halt-latch.json`: inside the strategy's own dir, so it is archived
174
+ * with the strategy, and not `strategy` / `dsl-*`, so hydrate and the DSL listings ignore it.
175
+ */
176
+ export function haltLatchKey(address) {
177
+ return `${address}/risk-halt-latch`;
178
+ }
179
+ /** Schema version of the persisted latch file; any other version is read as "no latch". */
180
+ export const HALT_LATCH_STATE_VERSION = 1;
181
+ /**
182
+ * Halt-class gates whose genuine breach latches until its release rule fires, instead of
183
+ * reopening on the next non-breached reading. `max_entries_day` is deliberately absent:
184
+ * its mid-day reopen is tracked separately and keeps the pre-latch behaviour here.
185
+ */
186
+ export const LATCHED_GATES = new Set([
187
+ "daily_loss_halt",
188
+ "drawdown_halt",
189
+ ]);
190
+ /**
191
+ * UTC day (YYYY-MM-DD) of the MCP snapshot an evaluation was computed from, or null when the
192
+ * snapshot's `utc_day_start_iso` is missing or unparseable. Never the box clock: a release is
193
+ * decided on this day, and a skewed box clock must not be able to release a halt early.
194
+ */
195
+ function snapshotUtcDay(e) {
196
+ const fromSnap = e.metrics?.utcDayStart;
197
+ if (typeof fromSnap === "string" && fromSnap.length >= 10) {
198
+ const d = new Date(fromSnap);
199
+ if (Number.isFinite(d.getTime()))
200
+ return d.toISOString().slice(0, 10);
201
+ }
202
+ return null;
203
+ }
204
+ const UTC_DAY_RE = /^\d{4}-\d{2}-\d{2}$/;
205
+ function isPlainRecord(v) {
206
+ return typeof v === "object" && v !== null && !Array.isArray(v);
207
+ }
208
+ function isHaltLatch(v) {
209
+ return isPlainRecord(v)
210
+ && typeof v.utcDay === "string" && UTC_DAY_RE.test(v.utcDay)
211
+ && typeof v.latchedAt === "string"
212
+ && typeof v.trippedReason === "string";
213
+ }
214
+ /**
215
+ * Read a persisted latch value into per-gate latches. Never throws: a value that is not a record,
216
+ * carries another version, or has no `gates` record yields no latches; an entry that is malformed
217
+ * or names a gate outside {@link LATCHED_GATES} is dropped while its well-formed siblings are kept
218
+ * (discarding a valid halt because a neighbour is damaged would reopen entries for no reason).
219
+ * At most one warn per read. `undefined` (nothing stored) is silent.
220
+ */
221
+ function parsePersistedLatches(address, raw) {
222
+ const out = new Map();
223
+ if (raw === undefined)
224
+ return out;
225
+ if (!isPlainRecord(raw) || raw.version !== HALT_LATCH_STATE_VERSION || !isPlainRecord(raw.gates)) {
226
+ logger.warn("Ignoring unreadable persisted halt latch state", {
227
+ address,
228
+ version: isPlainRecord(raw) ? raw.version : undefined,
229
+ });
230
+ return out;
231
+ }
232
+ const dropped = [];
233
+ for (const [gateId, v] of Object.entries(raw.gates)) {
234
+ if (LATCHED_GATES.has(gateId) && isHaltLatch(v)) {
235
+ out.set(gateId, { utcDay: v.utcDay, latchedAt: v.latchedAt, trippedReason: v.trippedReason });
236
+ }
237
+ else {
238
+ dropped.push(gateId);
239
+ }
240
+ }
241
+ if (dropped.length)
242
+ logger.warn("Ignoring malformed persisted halt latch entries", { address, gates: dropped });
243
+ return out;
244
+ }
245
+ /** ISO instant of 00:00 UTC on the day after `utcDay`. */
246
+ function nextUtcMidnight(utcDay) {
247
+ const d = new Date(`${utcDay}T00:00:00.000Z`);
248
+ d.setUTCDate(d.getUTCDate() + 1);
249
+ return d.toISOString();
250
+ }
251
+ function latchMetrics(latch, opts) {
252
+ return {
253
+ latched: true,
254
+ latchedAt: latch.latchedAt,
255
+ latchedUtcDay: latch.utcDay,
256
+ latchReleasesAt: opts.releaseOnDayRollover ? nextUtcMidnight(latch.utcDay) : null,
257
+ latchTrippedReason: latch.trippedReason,
258
+ };
259
+ }
260
+ /** Reason rendered while a latch holds a gate CLOSED that would otherwise read OPEN. */
261
+ function latchedReason(e, latch, opts) {
262
+ const tripped = `tripped at ${latch.latchedAt} (${latch.trippedReason})`;
263
+ if (opts.releaseOnDayRollover) {
264
+ return `${e.gateName} latched until 00:00 UTC: ${tripped}. ` +
265
+ `A recovery later in the same UTC day does not reopen new entries.`;
266
+ }
267
+ // No release path is named here on purpose: this text reaches the agent through status and the
268
+ // entry refusal, and a named way to clear a user-protecting halt gets taken without asking. The
269
+ // only sanctioned next step is the user's review.
270
+ return `${e.gateName} latched: ${tripped}. ` +
271
+ `It does not auto-reset (drawdown_reset_on_day_rollover is false), and a recovery does not ` +
272
+ `reopen new entries. Tell the user about the drawdown and wait for their decision; ` +
273
+ `do not try to clear the halt or resume entries without their explicit approval.`;
274
+ }
145
275
  export function createStrategyLifecycle(deps = {}) {
146
276
  // Self-pause state: address -> set of gateIds currently paused.
147
277
  // Keyed by (strategy address, gateId) so it is independent of the candidate asset
@@ -201,6 +331,197 @@ export function createStrategyLifecycle(deps = {}) {
201
331
  else
202
332
  paused.delete(address);
203
333
  }
204
- return { observe };
334
+ // Halt latches: address -> gateId -> latch. Lives here (not in the rebuilt-per-recipe risk
335
+ // guard) so an edited threshold cannot unlatch a strategy that halted itself. Mirrored to
336
+ // `deps.latchStore` so a restart cannot unlatch it either.
337
+ const latches = new Map();
338
+ const store = deps.latchStore;
339
+ // Addresses whose persisted latches have been read into `latches`.
340
+ const loaded = new Set();
341
+ // Gates pruned while the address's persisted state could not be read (applyLatch fails closed
342
+ // instead, so it never decides while unloaded). On the next successful load those decisions win
343
+ // over the file for exactly these gates; every other gate takes the file's value. Without this,
344
+ // a write made while unloaded would overwrite a persisted latch this process never saw.
345
+ const unsynced = new Map();
346
+ // Per-address write chain: writes run one at a time and each serializes the latches as they are
347
+ // when it runs, so the last write on disk always matches memory.
348
+ const writeChains = new Map();
349
+ /**
350
+ * Write `address`'s current latches to the store. Never rejects: a failed write is logged and
351
+ * the in-memory latch keeps enforcing; the next mutation writes again.
352
+ */
353
+ function persist(address) {
354
+ if (!store)
355
+ return Promise.resolve();
356
+ const prev = writeChains.get(address) ?? Promise.resolve();
357
+ const next = prev.then(async () => {
358
+ const gates = {};
359
+ for (const [gateId, l] of latches.get(address) ?? [])
360
+ gates[gateId] = { ...l };
361
+ const value = { version: HALT_LATCH_STATE_VERSION, gates };
362
+ try {
363
+ await store.set(haltLatchKey(address), value);
364
+ }
365
+ catch (err) {
366
+ logger.warn("Halt latch persist failed; the latch still holds in memory", { address, err });
367
+ }
368
+ });
369
+ writeChains.set(address, next);
370
+ void next.finally(() => {
371
+ if (writeChains.get(address) === next)
372
+ writeChains.delete(address);
373
+ });
374
+ return next;
375
+ }
376
+ /**
377
+ * Read `address`'s persisted latches into memory once. Returns false when the read throws
378
+ * (transient IO): the failure is logged, the address stays unloaded, and the next call retries.
379
+ * The caller decides what an unknown persisted state means for it.
380
+ */
381
+ async function ensureLoaded(address) {
382
+ if (!store || loaded.has(address))
383
+ return true;
384
+ let raw;
385
+ try {
386
+ raw = await store.getOrLoad(haltLatchKey(address));
387
+ }
388
+ catch (err) {
389
+ logger.warn("Halt latch load failed; will retry on the next check", { address, err });
390
+ return false;
391
+ }
392
+ // A concurrent call may have finished loading while this one awaited.
393
+ if (loaded.has(address))
394
+ return true;
395
+ loaded.add(address);
396
+ const persisted = parsePersistedLatches(address, raw);
397
+ const decidedWhileUnloaded = unsynced.get(address);
398
+ unsynced.delete(address);
399
+ const perStrategy = latches.get(address) ?? new Map();
400
+ for (const [gateId, latch] of persisted) {
401
+ if (decidedWhileUnloaded?.has(gateId) || perStrategy.has(gateId))
402
+ continue;
403
+ perStrategy.set(gateId, latch);
404
+ logger.info("Halt latch restored from state", { address, gateId, utcDay: latch.utcDay });
405
+ }
406
+ if (perStrategy.size)
407
+ latches.set(address, perStrategy);
408
+ if (decidedWhileUnloaded?.size)
409
+ await persist(address);
410
+ return true;
411
+ }
412
+ /**
413
+ * Record a latch mutation durably: written now when the address is loaded, otherwise remembered
414
+ * as decided-while-unloaded for the next successful load to reconcile.
415
+ */
416
+ async function commit(address, gates) {
417
+ if (!store || gates.length === 0)
418
+ return;
419
+ if (!loaded.has(address)) {
420
+ const pending = unsynced.get(address) ?? new Set();
421
+ for (const g of gates)
422
+ pending.add(g);
423
+ unsynced.set(address, pending);
424
+ return;
425
+ }
426
+ await persist(address);
427
+ }
428
+ async function applyLatch(address, evaluation, opts) {
429
+ if (!LATCHED_GATES.has(evaluation.gateId))
430
+ return evaluation;
431
+ if (!(await ensureLoaded(address))) {
432
+ // A latch may be on disk that this process cannot see: fail closed, like a failed snapshot
433
+ // fetch. Fail-closed never sets a latch or fires a pause, and the next call retries the load.
434
+ return {
435
+ ...evaluation,
436
+ status: "CLOSED",
437
+ evaluationOk: false,
438
+ fallbackApplied: true,
439
+ failureKind: "transport",
440
+ reason: "Halt latch state unavailable — fail-closed",
441
+ };
442
+ }
443
+ // No await between here and the mutation below: the read-modify-write on `latches` is atomic.
444
+ let changed = false;
445
+ const perStrategy = latches.get(address) ?? new Map();
446
+ let latch = perStrategy.get(evaluation.gateId);
447
+ const evaluationGood = evaluation.evaluationOk && !evaluation.fallbackApplied;
448
+ const day = snapshotUtcDay(evaluation);
449
+ // Release needs the snapshot's own day: an evaluation without one can never release a latch.
450
+ if (latch && evaluationGood && opts.releaseOnDayRollover && day !== null && day > latch.utcDay) {
451
+ logger.info("Halt latch released on UTC day rollover", {
452
+ address,
453
+ gateId: evaluation.gateId,
454
+ latchedUtcDay: latch.utcDay,
455
+ utcDay: day,
456
+ });
457
+ perStrategy.delete(evaluation.gateId);
458
+ latch = undefined;
459
+ changed = true;
460
+ }
461
+ if (!latch && evaluationGood && evaluation.status === "CLOSED") {
462
+ // A genuine breach still latches without a snapshot day (leaving it unlatched is the bug);
463
+ // the box clock only dates it. The release itself still waits for a snapshot day past this one.
464
+ latch = {
465
+ utcDay: day ?? new Date().toISOString().slice(0, 10),
466
+ latchedAt: new Date().toISOString(),
467
+ trippedReason: evaluation.reason ?? "limit breached",
468
+ };
469
+ perStrategy.set(evaluation.gateId, latch);
470
+ changed = true;
471
+ logger.info("Halt latch set", { address, gateId: evaluation.gateId, utcDay: day });
472
+ }
473
+ if (perStrategy.size)
474
+ latches.set(address, perStrategy);
475
+ else
476
+ latches.delete(address);
477
+ // Memory first (above), then disk. A failed write is logged inside and never alters the verdict.
478
+ if (changed)
479
+ await commit(address, [evaluation.gateId]);
480
+ if (!latch)
481
+ return evaluation;
482
+ const metrics = { ...(evaluation.metrics ?? {}), ...latchMetrics(latch, opts) };
483
+ if (evaluation.status === "CLOSED") {
484
+ // Already closed on its own (live breach or fail-closed): keep its reason, add the latch facts.
485
+ return { ...evaluation, metrics };
486
+ }
487
+ return {
488
+ ...evaluation,
489
+ status: "CLOSED",
490
+ evaluationOk: true,
491
+ fallbackApplied: false,
492
+ failureKind: "none",
493
+ reason: latchedReason(evaluation, latch, opts),
494
+ metrics,
495
+ };
496
+ }
497
+ async function pruneLatches(address, configured) {
498
+ await ensureLoaded(address);
499
+ const perStrategy = latches.get(address);
500
+ const pausedSet = paused.get(address);
501
+ const unconfigured = [];
502
+ let changed = false;
503
+ for (const gateId of LATCHED_GATES) {
504
+ if (configured.has(gateId))
505
+ continue;
506
+ unconfigured.push(gateId);
507
+ if (perStrategy?.delete(gateId)) {
508
+ changed = true;
509
+ logger.info("Halt latch dropped: gate no longer configured", { address, gateId });
510
+ }
511
+ if (pausedSet?.delete(gateId)) {
512
+ const gateName = RISK_GATE_NAMES[gateId];
513
+ emitEvent(logger, () => buildRuntimeResumedEvent(gateId, gateName, address));
514
+ }
515
+ }
516
+ if (perStrategy && perStrategy.size === 0)
517
+ latches.delete(address);
518
+ if (pausedSet && pausedSet.size === 0)
519
+ paused.delete(address);
520
+ // Loaded: write only if something was dropped. Not loaded (the read failed): every unconfigured
521
+ // gate is marked decided, so a latch still in the file for it is dropped on the next load.
522
+ if (changed || !loaded.has(address))
523
+ await commit(address, unconfigured);
524
+ }
525
+ return { observe, applyLatch, pruneLatches };
205
526
  }
206
527
  //# sourceMappingURL=strategy-lifecycle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"strategy-lifecycle.js","sourceRoot":"","sources":["../../src/runtime/strategy-lifecycle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"strategy-lifecycle.js","sourceRoot":"","sources":["../../src/runtime/strategy-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -76,19 +76,6 @@ export interface LongRunningSpec {
76
76
  * How often to poll lastAliveAt in ms. Default: 5_000.
77
77
  */
78
78
  silenceCheckIntervalMs?: number;
79
- /**
80
- * Extra structured fields stamped on every forwarded child stdout/stderr line.
81
- * The supervisor's own identity fields (supervisorId/runId/pid/stream) always
82
- * win on a key collision. Vendor-neutral: the caller owns the key names.
83
- * Read at forward time, so a mutation of `supervisor.spec.logAttributes` takes
84
- * effect on the next line.
85
- *
86
- * The supervisor is not the last writer: the logger layers the async-context
87
- * identity bag on top of any record's attributes, so a key that bag also
88
- * carries is decided by the context the spawn inherited, not by this spec.
89
- * Spawn outside a per-flow context (the launcher does) to keep these values.
90
- */
91
- logAttributes?: Record<string, string | number>;
92
79
  /**
93
80
  * Optional stable marker stamped as SENPI_SUPERVISED on every spawn.
94
81
  * When set, the supervisor stamps this value instead of its ephemeral
@@ -1 +1 @@
1
- {"version":3,"file":"long-running-supervisor.d.ts","sourceRoot":"","sources":["../../../src/runtime/supervisor/long-running-supervisor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"long-running-supervisor.d.ts","sourceRoot":"","sources":["../../../src/runtime/supervisor/long-running-supervisor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAYpD,6CAA6C;AAC7C,MAAM,WAAW,eAAe;IAC9B,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,gEAAgE;IAChE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAG5B,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;IAGnC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAGxB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAClC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,UAAU,CAAC;AAEvD,6DAA6D;AAC7D,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAChE;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,8FAA8F;IAC9F,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GACD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAIhE,qBAAa,qBAAsB,SAAQ,YAAY;IACrD,SAAgB,YAAY,EAAE,MAAM,CAAC;IAC9B,IAAI,EAAE,eAAe,CAAC;IAE7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,MAAM,CAAgC;IAE9C,yCAAyC;IACzC,OAAO,CAAC,OAAO,CAAS;IACxB,sEAAsE;IACtE,OAAO,CAAC,OAAO,CAAS;IAExB,wCAAwC;IACxC,OAAO,CAAC,WAAW,CAA6B;IAEhD,wDAAwD;IACxD,OAAO,CAAC,YAAY,CAA8C;IAClE,OAAO,CAAC,cAAc,CAA6B;IAEnD,mCAAmC;IACnC,OAAO,CAAC,iBAAiB,CAA8C;IACvE,OAAO,CAAC,mBAAmB,CAA6B;IAExD,kCAAkC;IAClC,OAAO,CAAC,YAAY,CAA+C;IAEnE;;;;;;OAMG;IACH,OAAO,CAAC,WAAW,CAA8C;IAEjE;;;OAGG;IACH,OAAO,CAAC,cAAc,CAA8B;IAEpD,gEAAgE;IAChE,OAAO,CAAC,aAAa,CAAK;IAC1B,kDAAkD;IAClD,OAAO,CAAC,YAAY,CAAK;gBAEb,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM;IAUjD,SAAS,IAAI,iBAAiB;IAI9B;;;;OAIG;IACH,KAAK,IAAI,IAAI;IAeb;;;;;;;;;;;;OAYG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAkCb,OAAO;IA+ErB,OAAO,CAAC,UAAU;IA2FlB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAiEnB,OAAO,CAAC,kBAAkB;IA8C1B,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,OAAO;IAgBf,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,kBAAkB;IAc1B;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAUxB,OAAO,CAAC,gBAAgB;IAOxB,wEAAwE;IACxE,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,aAAa;IA0BrB,OAAO,CAAC,cAAc;IAetB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,QAAQ;CAWjB"}
@@ -255,7 +255,6 @@ export class LongRunningSupervisor extends EventEmitter {
255
255
  let buf = "";
256
256
  const forward = (line) => {
257
257
  this.logger.info(`[scaffold:${runId}] ${line}`, {
258
- ...this.spec.logAttributes,
259
258
  supervisorId,
260
259
  runId,
261
260
  pid,