@coool/opencode-adaptive 1.0.0 → 1.0.1

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 (380) hide show
  1. package/README.md +8 -7
  2. package/dist/adapters/codex-capacity/index.d.ts +0 -1
  3. package/dist/adapters/codex-capacity/index.js.map +1 -1
  4. package/dist/adapters/codex-capacity/parse.d.ts +2 -2
  5. package/dist/adapters/codex-capacity/parse.js +19 -3
  6. package/dist/adapters/codex-capacity/parse.js.map +1 -1
  7. package/dist/adapters/codex-capacity/reading.d.ts +0 -1
  8. package/dist/adapters/codex-capacity/reading.js.map +1 -1
  9. package/dist/adapters/codex-capacity/sensor.d.ts +0 -1
  10. package/dist/adapters/codex-capacity/sensor.js.map +1 -1
  11. package/dist/adapters/codex-capacity/types.d.ts +0 -4
  12. package/dist/adapters/codex-capacity/types.js +14 -0
  13. package/dist/adapters/codex-capacity/types.js.map +1 -1
  14. package/dist/adapters/opencode/escalation-tool.d.ts +0 -1
  15. package/dist/adapters/opencode/escalation-tool.js +5 -3
  16. package/dist/adapters/opencode/escalation-tool.js.map +1 -1
  17. package/dist/adapters/opencode/events.d.ts +0 -1
  18. package/dist/adapters/opencode/events.js.map +1 -1
  19. package/dist/adapters/opencode/hooks.d.ts +0 -1
  20. package/dist/adapters/opencode/hooks.js +24 -7
  21. package/dist/adapters/opencode/hooks.js.map +1 -1
  22. package/dist/adapters/opencode/index.d.ts +0 -1
  23. package/dist/adapters/opencode/index.js.map +1 -1
  24. package/dist/adapters/opencode/inventory.d.ts +0 -1
  25. package/dist/adapters/opencode/inventory.js.map +1 -1
  26. package/dist/adapters/opencode/report.d.ts +0 -1
  27. package/dist/adapters/opencode/report.js.map +1 -1
  28. package/dist/adapters/opencode/session-ops.d.ts +0 -1
  29. package/dist/adapters/opencode/session-ops.js.map +1 -1
  30. package/dist/adapters/opencode/storage.d.ts +0 -1
  31. package/dist/adapters/opencode/storage.js.map +1 -1
  32. package/dist/adapters/opencode/tier-tool.d.ts +0 -1
  33. package/dist/adapters/opencode/tier-tool.js.map +1 -1
  34. package/dist/adapters/opencode/types.d.ts +0 -1
  35. package/dist/adapters/opencode/types.js.map +1 -1
  36. package/dist/core/compatibility/gate.d.ts +0 -3
  37. package/dist/core/compatibility/gate.js +0 -4
  38. package/dist/core/compatibility/gate.js.map +1 -1
  39. package/dist/core/compatibility/index.d.ts +0 -1
  40. package/dist/core/compatibility/index.js.map +1 -1
  41. package/dist/core/compatibility/types.d.ts +0 -1
  42. package/dist/core/compatibility/types.js.map +1 -1
  43. package/dist/core/scheduler/admit.d.ts +0 -1
  44. package/dist/core/scheduler/admit.js +22 -21
  45. package/dist/core/scheduler/admit.js.map +1 -1
  46. package/dist/core/scheduler/escalate.d.ts +0 -1
  47. package/dist/core/scheduler/escalate.js +6 -17
  48. package/dist/core/scheduler/escalate.js.map +1 -1
  49. package/dist/core/scheduler/index.d.ts +0 -1
  50. package/dist/core/scheduler/index.js.map +1 -1
  51. package/dist/core/scheduler/mode.d.ts +0 -1
  52. package/dist/core/scheduler/mode.js.map +1 -1
  53. package/dist/core/scheduler/types.d.ts +2 -9
  54. package/dist/core/scheduler/types.js +2 -1
  55. package/dist/core/scheduler/types.js.map +1 -1
  56. package/dist/core/tier-policy/index.d.ts +0 -1
  57. package/dist/core/tier-policy/index.js.map +1 -1
  58. package/dist/core/tier-policy/resolve.d.ts +0 -1
  59. package/dist/core/tier-policy/resolve.js.map +1 -1
  60. package/dist/core/tier-policy/tier-list.d.ts +0 -1
  61. package/dist/core/tier-policy/tier-list.js.map +1 -1
  62. package/dist/core/tier-policy/types.d.ts +2 -1
  63. package/dist/core/tier-policy/types.js +4 -0
  64. package/dist/core/tier-policy/types.js.map +1 -1
  65. package/dist/core/work-unit/index.d.ts +0 -1
  66. package/dist/core/work-unit/index.js.map +1 -1
  67. package/dist/core/work-unit/interruption.d.ts +0 -1
  68. package/dist/core/work-unit/interruption.js.map +1 -1
  69. package/dist/core/work-unit/tracker.d.ts +11 -4
  70. package/dist/core/work-unit/tracker.js +26 -6
  71. package/dist/core/work-unit/tracker.js.map +1 -1
  72. package/dist/core/work-unit/types.d.ts +6 -1
  73. package/dist/core/work-unit/types.js.map +1 -1
  74. package/dist/execution/continuation/execute.d.ts +0 -1
  75. package/dist/execution/continuation/execute.js.map +1 -1
  76. package/dist/execution/continuation/index.d.ts +0 -2
  77. package/dist/execution/continuation/index.js +0 -1
  78. package/dist/execution/continuation/index.js.map +1 -1
  79. package/dist/execution/continuation/plan.d.ts +0 -1
  80. package/dist/execution/continuation/plan.js +1 -3
  81. package/dist/execution/continuation/plan.js.map +1 -1
  82. package/dist/execution/continuation/prompts.d.ts +0 -1
  83. package/dist/execution/continuation/prompts.js.map +1 -1
  84. package/dist/execution/continuation/types.d.ts +0 -2
  85. package/dist/execution/continuation/types.js.map +1 -1
  86. package/dist/execution/escalation/index.d.ts +0 -1
  87. package/dist/execution/escalation/index.js.map +1 -1
  88. package/dist/execution/escalation/types.d.ts +0 -1
  89. package/dist/execution/escalation/types.js.map +1 -1
  90. package/dist/execution/index.d.ts +0 -1
  91. package/dist/execution/index.js.map +1 -1
  92. package/dist/execution/parking/index.d.ts +0 -1
  93. package/dist/execution/parking/index.js.map +1 -1
  94. package/dist/execution/parking/plan.d.ts +0 -1
  95. package/dist/execution/parking/plan.js.map +1 -1
  96. package/dist/execution/retry/decide.d.ts +0 -1
  97. package/dist/execution/retry/decide.js +1 -2
  98. package/dist/execution/retry/decide.js.map +1 -1
  99. package/dist/execution/retry/index.d.ts +0 -1
  100. package/dist/execution/retry/index.js.map +1 -1
  101. package/dist/execution/retry/types.d.ts +0 -2
  102. package/dist/execution/retry/types.js.map +1 -1
  103. package/dist/gui-experimental.cjs +1 -1
  104. package/dist/gui.d.ts +0 -1
  105. package/dist/gui.js +6 -3
  106. package/dist/gui.js.map +1 -1
  107. package/dist/health/capacity/index.d.ts +0 -1
  108. package/dist/health/capacity/index.js.map +1 -1
  109. package/dist/health/capacity/merge.d.ts +0 -1
  110. package/dist/health/capacity/merge.js.map +1 -1
  111. package/dist/health/capacity/registry.d.ts +0 -1
  112. package/dist/health/capacity/registry.js.map +1 -1
  113. package/dist/health/capacity/types.d.ts +0 -1
  114. package/dist/health/capacity/types.js.map +1 -1
  115. package/dist/health/circuit-breaker/breaker.d.ts +8 -1
  116. package/dist/health/circuit-breaker/breaker.js +18 -0
  117. package/dist/health/circuit-breaker/breaker.js.map +1 -1
  118. package/dist/health/circuit-breaker/index.d.ts +0 -1
  119. package/dist/health/circuit-breaker/index.js.map +1 -1
  120. package/dist/health/circuit-breaker/types.d.ts +0 -1
  121. package/dist/health/circuit-breaker/types.js.map +1 -1
  122. package/dist/health/classifier/classify.d.ts +0 -1
  123. package/dist/health/classifier/classify.js.map +1 -1
  124. package/dist/health/classifier/index.d.ts +0 -1
  125. package/dist/health/classifier/index.js.map +1 -1
  126. package/dist/health/classifier/types.d.ts +0 -1
  127. package/dist/health/classifier/types.js.map +1 -1
  128. package/dist/health/index.d.ts +0 -1
  129. package/dist/health/index.js.map +1 -1
  130. package/dist/health/resource-health/index.d.ts +0 -1
  131. package/dist/health/resource-health/index.js.map +1 -1
  132. package/dist/health/resource-health/key.d.ts +0 -1
  133. package/dist/health/resource-health/key.js.map +1 -1
  134. package/dist/health/resource-health/registry.d.ts +6 -1
  135. package/dist/health/resource-health/registry.js +19 -1
  136. package/dist/health/resource-health/registry.js.map +1 -1
  137. package/dist/health/resource-health/transitions.d.ts +2 -4
  138. package/dist/health/resource-health/transitions.js +10 -18
  139. package/dist/health/resource-health/transitions.js.map +1 -1
  140. package/dist/health/resource-health/types.d.ts +7 -1
  141. package/dist/health/resource-health/types.js +1 -0
  142. package/dist/health/resource-health/types.js.map +1 -1
  143. package/dist/index.d.ts +0 -6
  144. package/dist/index.js +44 -19
  145. package/dist/index.js.map +1 -1
  146. package/dist/plugin-id.d.ts +0 -1
  147. package/dist/plugin-id.js.map +1 -1
  148. package/dist/rpc/definition.d.ts +24 -1
  149. package/dist/rpc/definition.js +28 -2
  150. package/dist/rpc/definition.js.map +1 -1
  151. package/dist/rpc/handlers.d.ts +12 -24
  152. package/dist/rpc/handlers.js +22 -8
  153. package/dist/rpc/handlers.js.map +1 -1
  154. package/dist/rpc/status.d.ts +0 -1
  155. package/dist/rpc/status.js.map +1 -1
  156. package/dist/rpc.d.ts +0 -1
  157. package/dist/rpc.js.map +1 -1
  158. package/dist/state/capacity/index.d.ts +0 -1
  159. package/dist/state/capacity/index.js.map +1 -1
  160. package/dist/state/capacity/parse.d.ts +0 -1
  161. package/dist/state/capacity/parse.js +14 -2
  162. package/dist/state/capacity/parse.js.map +1 -1
  163. package/dist/state/capacity/store.d.ts +0 -1
  164. package/dist/state/capacity/store.js +16 -2
  165. package/dist/state/capacity/store.js.map +1 -1
  166. package/dist/state/capacity/types.d.ts +0 -1
  167. package/dist/state/capacity/types.js.map +1 -1
  168. package/dist/state/health/index.d.ts +0 -1
  169. package/dist/state/health/index.js.map +1 -1
  170. package/dist/state/health/parse.d.ts +0 -1
  171. package/dist/state/health/parse.js +20 -4
  172. package/dist/state/health/parse.js.map +1 -1
  173. package/dist/state/health/store.d.ts +0 -1
  174. package/dist/state/health/store.js +16 -2
  175. package/dist/state/health/store.js.map +1 -1
  176. package/dist/state/health/types.d.ts +0 -1
  177. package/dist/state/health/types.js.map +1 -1
  178. package/dist/state/parked-work/index.d.ts +0 -1
  179. package/dist/state/parked-work/index.js.map +1 -1
  180. package/dist/state/parked-work/parse.d.ts +0 -1
  181. package/dist/state/parked-work/parse.js.map +1 -1
  182. package/dist/state/parked-work/store.d.ts +0 -1
  183. package/dist/state/parked-work/store.js +20 -3
  184. package/dist/state/parked-work/store.js.map +1 -1
  185. package/dist/state/parked-work/types.d.ts +0 -1
  186. package/dist/state/parked-work/types.js.map +1 -1
  187. package/dist/state/receipts/bound.d.ts +0 -1
  188. package/dist/state/receipts/bound.js.map +1 -1
  189. package/dist/state/receipts/index.d.ts +0 -1
  190. package/dist/state/receipts/index.js.map +1 -1
  191. package/dist/state/receipts/parse.d.ts +0 -1
  192. package/dist/state/receipts/parse.js.map +1 -1
  193. package/dist/state/receipts/store.d.ts +0 -1
  194. package/dist/state/receipts/store.js +24 -4
  195. package/dist/state/receipts/store.js.map +1 -1
  196. package/dist/state/receipts/types.d.ts +0 -1
  197. package/dist/state/receipts/types.js.map +1 -1
  198. package/dist/state/session-modes/index.d.ts +0 -1
  199. package/dist/state/session-modes/index.js.map +1 -1
  200. package/dist/state/session-modes/parse.d.ts +0 -1
  201. package/dist/state/session-modes/parse.js.map +1 -1
  202. package/dist/state/session-modes/store.d.ts +0 -1
  203. package/dist/state/session-modes/store.js +15 -1
  204. package/dist/state/session-modes/store.js.map +1 -1
  205. package/dist/state/session-modes/types.d.ts +0 -1
  206. package/dist/state/session-modes/types.js.map +1 -1
  207. package/dist/state/settings/index.d.ts +0 -1
  208. package/dist/state/settings/index.js.map +1 -1
  209. package/dist/state/settings/parse.d.ts +0 -1
  210. package/dist/state/settings/parse.js.map +1 -1
  211. package/dist/state/settings/store.d.ts +0 -1
  212. package/dist/state/settings/store.js +9 -1
  213. package/dist/state/settings/store.js.map +1 -1
  214. package/dist/state/settings/types.d.ts +0 -1
  215. package/dist/state/settings/types.js.map +1 -1
  216. package/dist/state/tier-requests/index.d.ts +4 -0
  217. package/dist/state/tier-requests/index.js +4 -0
  218. package/dist/state/tier-requests/index.js.map +1 -0
  219. package/dist/state/tier-requests/parse.d.ts +3 -0
  220. package/dist/state/tier-requests/parse.js +53 -0
  221. package/dist/state/tier-requests/parse.js.map +1 -0
  222. package/dist/state/tier-requests/store.d.ts +27 -0
  223. package/dist/state/tier-requests/store.js +96 -0
  224. package/dist/state/tier-requests/store.js.map +1 -0
  225. package/dist/state/tier-requests/types.d.ts +30 -0
  226. package/dist/state/tier-requests/types.js +7 -0
  227. package/dist/state/tier-requests/types.js.map +1 -0
  228. package/dist/supervisor/index.d.ts +0 -1
  229. package/dist/supervisor/index.js.map +1 -1
  230. package/dist/supervisor/log.d.ts +0 -1
  231. package/dist/supervisor/log.js.map +1 -1
  232. package/dist/supervisor/supervisor.d.ts +23 -6
  233. package/dist/supervisor/supervisor.js +397 -111
  234. package/dist/supervisor/supervisor.js.map +1 -1
  235. package/dist/supervisor/types.d.ts +0 -1
  236. package/dist/supervisor/types.js.map +1 -1
  237. package/dist/supervisor/view.d.ts +0 -1
  238. package/dist/supervisor/view.js.map +1 -1
  239. package/dist/tui.d.ts +0 -1
  240. package/dist/tui.js +14 -10
  241. package/dist/tui.js.map +1 -1
  242. package/dist/ui/gui/api.d.ts +0 -1
  243. package/dist/ui/gui/api.js.map +1 -1
  244. package/dist/ui/gui/view.d.ts +0 -1
  245. package/dist/ui/gui/view.js.map +1 -1
  246. package/dist/ui/tui/controller.d.ts +0 -1
  247. package/dist/ui/tui/controller.js +28 -12
  248. package/dist/ui/tui/controller.js.map +1 -1
  249. package/dist/ui/tui/menu.d.ts +1 -2
  250. package/dist/ui/tui/menu.js +2 -2
  251. package/dist/ui/tui/menu.js.map +1 -1
  252. package/dist/ui/tui/options.d.ts +0 -1
  253. package/dist/ui/tui/options.js.map +1 -1
  254. package/dist/ui/tui/receipts.d.ts +0 -1
  255. package/dist/ui/tui/receipts.js +4 -1
  256. package/dist/ui/tui/receipts.js.map +1 -1
  257. package/dist/ui/tui/status.d.ts +1 -2
  258. package/dist/ui/tui/status.js +4 -2
  259. package/dist/ui/tui/status.js.map +1 -1
  260. package/dist/ui/tui/tiers.d.ts +0 -1
  261. package/dist/ui/tui/tiers.js.map +1 -1
  262. package/package.json +2 -2
  263. package/dist/adapters/codex-capacity/index.d.ts.map +0 -1
  264. package/dist/adapters/codex-capacity/parse.d.ts.map +0 -1
  265. package/dist/adapters/codex-capacity/reading.d.ts.map +0 -1
  266. package/dist/adapters/codex-capacity/sensor.d.ts.map +0 -1
  267. package/dist/adapters/codex-capacity/types.d.ts.map +0 -1
  268. package/dist/adapters/opencode/escalation-tool.d.ts.map +0 -1
  269. package/dist/adapters/opencode/events.d.ts.map +0 -1
  270. package/dist/adapters/opencode/hooks.d.ts.map +0 -1
  271. package/dist/adapters/opencode/index.d.ts.map +0 -1
  272. package/dist/adapters/opencode/inventory.d.ts.map +0 -1
  273. package/dist/adapters/opencode/report.d.ts.map +0 -1
  274. package/dist/adapters/opencode/session-ops.d.ts.map +0 -1
  275. package/dist/adapters/opencode/storage.d.ts.map +0 -1
  276. package/dist/adapters/opencode/tier-tool.d.ts.map +0 -1
  277. package/dist/adapters/opencode/types.d.ts.map +0 -1
  278. package/dist/core/compatibility/gate.d.ts.map +0 -1
  279. package/dist/core/compatibility/index.d.ts.map +0 -1
  280. package/dist/core/compatibility/types.d.ts.map +0 -1
  281. package/dist/core/scheduler/admit.d.ts.map +0 -1
  282. package/dist/core/scheduler/escalate.d.ts.map +0 -1
  283. package/dist/core/scheduler/index.d.ts.map +0 -1
  284. package/dist/core/scheduler/mode.d.ts.map +0 -1
  285. package/dist/core/scheduler/types.d.ts.map +0 -1
  286. package/dist/core/tier-policy/index.d.ts.map +0 -1
  287. package/dist/core/tier-policy/resolve.d.ts.map +0 -1
  288. package/dist/core/tier-policy/tier-list.d.ts.map +0 -1
  289. package/dist/core/tier-policy/types.d.ts.map +0 -1
  290. package/dist/core/work-unit/index.d.ts.map +0 -1
  291. package/dist/core/work-unit/interruption.d.ts.map +0 -1
  292. package/dist/core/work-unit/tracker.d.ts.map +0 -1
  293. package/dist/core/work-unit/types.d.ts.map +0 -1
  294. package/dist/execution/continuation/execute.d.ts.map +0 -1
  295. package/dist/execution/continuation/index.d.ts.map +0 -1
  296. package/dist/execution/continuation/ledger.d.ts +0 -20
  297. package/dist/execution/continuation/ledger.d.ts.map +0 -1
  298. package/dist/execution/continuation/ledger.js +0 -31
  299. package/dist/execution/continuation/ledger.js.map +0 -1
  300. package/dist/execution/continuation/plan.d.ts.map +0 -1
  301. package/dist/execution/continuation/prompts.d.ts.map +0 -1
  302. package/dist/execution/continuation/types.d.ts.map +0 -1
  303. package/dist/execution/escalation/index.d.ts.map +0 -1
  304. package/dist/execution/escalation/types.d.ts.map +0 -1
  305. package/dist/execution/index.d.ts.map +0 -1
  306. package/dist/execution/parking/index.d.ts.map +0 -1
  307. package/dist/execution/parking/plan.d.ts.map +0 -1
  308. package/dist/execution/recovery/gate.d.ts +0 -20
  309. package/dist/execution/recovery/gate.d.ts.map +0 -1
  310. package/dist/execution/recovery/gate.js +0 -23
  311. package/dist/execution/recovery/gate.js.map +0 -1
  312. package/dist/execution/recovery/index.d.ts +0 -3
  313. package/dist/execution/recovery/index.d.ts.map +0 -1
  314. package/dist/execution/recovery/index.js +0 -2
  315. package/dist/execution/recovery/index.js.map +0 -1
  316. package/dist/execution/retry/decide.d.ts.map +0 -1
  317. package/dist/execution/retry/index.d.ts.map +0 -1
  318. package/dist/execution/retry/types.d.ts.map +0 -1
  319. package/dist/gui.d.ts.map +0 -1
  320. package/dist/health/capacity/index.d.ts.map +0 -1
  321. package/dist/health/capacity/merge.d.ts.map +0 -1
  322. package/dist/health/capacity/registry.d.ts.map +0 -1
  323. package/dist/health/capacity/types.d.ts.map +0 -1
  324. package/dist/health/circuit-breaker/breaker.d.ts.map +0 -1
  325. package/dist/health/circuit-breaker/index.d.ts.map +0 -1
  326. package/dist/health/circuit-breaker/types.d.ts.map +0 -1
  327. package/dist/health/classifier/classify.d.ts.map +0 -1
  328. package/dist/health/classifier/index.d.ts.map +0 -1
  329. package/dist/health/classifier/types.d.ts.map +0 -1
  330. package/dist/health/index.d.ts.map +0 -1
  331. package/dist/health/resource-health/index.d.ts.map +0 -1
  332. package/dist/health/resource-health/key.d.ts.map +0 -1
  333. package/dist/health/resource-health/registry.d.ts.map +0 -1
  334. package/dist/health/resource-health/transitions.d.ts.map +0 -1
  335. package/dist/health/resource-health/types.d.ts.map +0 -1
  336. package/dist/index.d.ts.map +0 -1
  337. package/dist/plugin-id.d.ts.map +0 -1
  338. package/dist/rpc/definition.d.ts.map +0 -1
  339. package/dist/rpc/handlers.d.ts.map +0 -1
  340. package/dist/rpc/status.d.ts.map +0 -1
  341. package/dist/rpc.d.ts.map +0 -1
  342. package/dist/state/capacity/index.d.ts.map +0 -1
  343. package/dist/state/capacity/parse.d.ts.map +0 -1
  344. package/dist/state/capacity/store.d.ts.map +0 -1
  345. package/dist/state/capacity/types.d.ts.map +0 -1
  346. package/dist/state/health/index.d.ts.map +0 -1
  347. package/dist/state/health/parse.d.ts.map +0 -1
  348. package/dist/state/health/store.d.ts.map +0 -1
  349. package/dist/state/health/types.d.ts.map +0 -1
  350. package/dist/state/parked-work/index.d.ts.map +0 -1
  351. package/dist/state/parked-work/parse.d.ts.map +0 -1
  352. package/dist/state/parked-work/store.d.ts.map +0 -1
  353. package/dist/state/parked-work/types.d.ts.map +0 -1
  354. package/dist/state/receipts/bound.d.ts.map +0 -1
  355. package/dist/state/receipts/index.d.ts.map +0 -1
  356. package/dist/state/receipts/parse.d.ts.map +0 -1
  357. package/dist/state/receipts/store.d.ts.map +0 -1
  358. package/dist/state/receipts/types.d.ts.map +0 -1
  359. package/dist/state/session-modes/index.d.ts.map +0 -1
  360. package/dist/state/session-modes/parse.d.ts.map +0 -1
  361. package/dist/state/session-modes/store.d.ts.map +0 -1
  362. package/dist/state/session-modes/types.d.ts.map +0 -1
  363. package/dist/state/settings/index.d.ts.map +0 -1
  364. package/dist/state/settings/parse.d.ts.map +0 -1
  365. package/dist/state/settings/store.d.ts.map +0 -1
  366. package/dist/state/settings/types.d.ts.map +0 -1
  367. package/dist/supervisor/index.d.ts.map +0 -1
  368. package/dist/supervisor/log.d.ts.map +0 -1
  369. package/dist/supervisor/supervisor.d.ts.map +0 -1
  370. package/dist/supervisor/types.d.ts.map +0 -1
  371. package/dist/supervisor/view.d.ts.map +0 -1
  372. package/dist/tui.d.ts.map +0 -1
  373. package/dist/ui/gui/api.d.ts.map +0 -1
  374. package/dist/ui/gui/view.d.ts.map +0 -1
  375. package/dist/ui/tui/controller.d.ts.map +0 -1
  376. package/dist/ui/tui/menu.d.ts.map +0 -1
  377. package/dist/ui/tui/options.d.ts.map +0 -1
  378. package/dist/ui/tui/receipts.d.ts.map +0 -1
  379. package/dist/ui/tui/status.d.ts.map +0 -1
  380. package/dist/ui/tui/tiers.d.ts.map +0 -1
@@ -14,11 +14,15 @@ import { parseCapacityPayload } from "./parse.js";
14
14
  export class CapacityReadingStore {
15
15
  storage;
16
16
  #readings = [];
17
+ #queue = Promise.resolve();
17
18
  constructor(storage) {
18
19
  this.storage = storage;
19
20
  }
20
21
  /** Load the persisted mirror; unreadable or corrupt data is empty, not an error. */
21
- async load() {
22
+ load() {
23
+ return this.#serialize(() => this.#load());
24
+ }
25
+ async #load() {
22
26
  let raw;
23
27
  try {
24
28
  raw = await this.storage.read();
@@ -40,7 +44,10 @@ export class CapacityReadingStore {
40
44
  * instance persisted. Bound by MAX_CAPACITY_READINGS, evicting the oldest
41
45
  * observations first.
42
46
  */
43
- async replace(entries) {
47
+ replace(entries) {
48
+ return this.#serialize(() => this.#replace(entries));
49
+ }
50
+ async #replace(entries) {
44
51
  const byKey = new Map();
45
52
  for (const entry of this.#readings) {
46
53
  byKey.set(resourceKeyID(entry.key), entry);
@@ -60,5 +67,12 @@ export class CapacityReadingStore {
60
67
  await this.storage.write({ version: CAPACITY_VERSION, readings: next });
61
68
  this.#readings = next;
62
69
  }
70
+ // The merge must run after the preceding commit, and reloads cannot race
71
+ // writes. Rejections remain visible to callers without poisoning the tail.
72
+ #serialize(operation) {
73
+ const run = this.#queue.then(operation);
74
+ this.#queue = run.catch(() => undefined);
75
+ return run;
76
+ }
63
77
  }
64
78
  //# sourceMappingURL=store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/state/capacity/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAA;AACnE,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GAGtB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAEjD,MAAM,OAAO,oBAAoB;IAGF;IAF7B,SAAS,GAA+B,EAAE,CAAA;IAE1C,YAA6B,OAAwB;QAAxB,YAAO,GAAP,OAAO,CAAiB;IAAG,CAAC;IAEzD,oFAAoF;IACpF,KAAK,CAAC,IAAI;QACR,IAAI,GAAY,CAAA;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,SAAS,GAAG,EAAE,CAAA;YACnB,OAAM;QACR,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAA;IAC5C,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,SAAS,CAAA;IACvB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,OAAO,CAAC,OAA4C;QACxD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAoC,CAAA;QACzD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAA;QAC5C,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,EAAE,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YACnC,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YAC9B,IAAI,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;gBACrF,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;YACtB,CAAC;QACH,CAAC;QACD,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAA;QAClC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;QAClE,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAA;QACnD,0EAA0E;QAC1E,yDAAyD;QACzD,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;QACvE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAA;IACvB,CAAC;CACF"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/state/capacity/store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Persistence mirror of the in-memory capacity registry: loads what any\n * instance observed and keeps it bounded (oldest-observed evicted), merging\n * per resource key on every replace.\n *\n * As everywhere else in state/, memory is only advanced after a successful\n * write, so memory and disk never diverge; write failures propagate to the\n * caller — the wiring layer's fail-open wrapper decides how to degrade\n * (ADP-031).\n */\nimport { resourceKeyID } from \"../../health/resource-health/key.js\"\nimport {\n CAPACITY_VERSION,\n MAX_CAPACITY_READINGS,\n type CapacityStorage,\n type PersistedCapacityReading,\n} from \"./types.js\"\nimport { parseCapacityPayload } from \"./parse.js\"\n\nexport class CapacityReadingStore {\n #readings: PersistedCapacityReading[] = []\n #queue: Promise<unknown> = Promise.resolve()\n\n constructor(private readonly storage: CapacityStorage) {}\n\n /** Load the persisted mirror; unreadable or corrupt data is empty, not an error. */\n load(): Promise<void> {\n return this.#serialize(() => this.#load())\n }\n\n async #load(): Promise<void> {\n let raw: unknown\n try {\n raw = await this.storage.read()\n } catch {\n this.#readings = []\n return\n }\n this.#readings = parseCapacityPayload(raw)\n }\n\n snapshot(): readonly PersistedCapacityReading[] {\n return this.#readings\n }\n\n /**\n * Merge one refresh batch into the mirror and persist it. Merge — not\n * replace — per resource key, with the newest `observedAt` winning: the TUI\n * host loads this plugin into several supervisor instances, and an instance\n * whose sensors have seen nothing must never clobber what the observing\n * instance persisted. Bound by MAX_CAPACITY_READINGS, evicting the oldest\n * observations first.\n */\n replace(entries: readonly PersistedCapacityReading[]): Promise<void> {\n return this.#serialize(() => this.#replace(entries))\n }\n\n async #replace(entries: readonly PersistedCapacityReading[]): Promise<void> {\n const byKey = new Map<string, PersistedCapacityReading>()\n for (const entry of this.#readings) {\n byKey.set(resourceKeyID(entry.key), entry)\n }\n for (const entry of entries) {\n const id = resourceKeyID(entry.key)\n const previous = byKey.get(id)\n if (previous === undefined || entry.reading.observedAt > previous.reading.observedAt) {\n byKey.set(id, entry)\n }\n }\n const merged = [...byKey.values()]\n merged.sort((a, b) => b.reading.observedAt - a.reading.observedAt)\n const next = merged.slice(0, MAX_CAPACITY_READINGS)\n // Persist BEFORE committing memory: a write failure must leave memory and\n // disk consistent (the caller decides how to fail open).\n await this.storage.write({ version: CAPACITY_VERSION, readings: next })\n this.#readings = next\n }\n\n // The merge must run after the preceding commit, and reloads cannot race\n // writes. Rejections remain visible to callers without poisoning the tail.\n #serialize(operation: () => Promise<void>): Promise<void> {\n const run = this.#queue.then(operation)\n this.#queue = run.catch(() => undefined)\n return run\n }\n}\n"]}
@@ -35,4 +35,3 @@ export interface CapacityStorage {
35
35
  read(): Promise<unknown>;
36
36
  write(payload: CapacityPayload): Promise<void>;
37
37
  }
38
- //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/state/capacity/types.ts"],"names":[],"mappings":"AAeA,iFAAiF;AACjF,MAAM,CAAC,MAAM,YAAY,GAAG,yBAAyB,CAAA;AAErD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAA;AAEjC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAA"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/state/capacity/types.ts"],"names":[],"mappings":"AAeA,iFAAiF;AACjF,MAAM,CAAC,MAAM,YAAY,GAAG,yBAAyB,CAAA;AAErD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAA;AAEjC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAA","sourcesContent":["/**\n * Persisted capacity readings (ADP-020/ADP-031).\n *\n * The host's TUI-mode plugin reconciliation can load the plugin several times\n * into one process: the session hooks (the event pump that observes capacity\n * headers) and the RPC registration that serves status.get can land on\n * DIFFERENT supervisor instances. The in-memory capacity registry lives only\n * on the hook instance, so capacity would be invisible to the status-serving\n * instance — the same trap that health records solve with their persisted\n * mirror. Persisting readings lets every instance read what any instance\n * observed, like receipts/settings/parked work.\n */\nimport type { ResourceKey } from \"../../health/resource-health/types.js\"\nimport type { CapacityReading } from \"../../health/capacity/types.js\"\n\n/** Storage key for the capacity mirror (bound by the adapter to ctx.storage). */\nexport const CAPACITY_KEY = \"coool.adaptive/capacity\"\n\nexport const CAPACITY_VERSION = 1\n\n/**\n * Product bound — not a user knob. A capacity reading is only useful while it\n * is fresh (readings older than the max age are treated as absent), so far\n * fewer entries than the health bound suffice to cover every configured\n * resource.\n */\nexport const MAX_CAPACITY_READINGS = 64\n\nexport interface PersistedCapacityReading {\n readonly key: ResourceKey\n readonly reading: CapacityReading\n}\n\nexport interface CapacityPayload {\n readonly version: typeof CAPACITY_VERSION\n readonly readings: readonly PersistedCapacityReading[]\n}\n\n/** Storage seam — the adapter binds `CAPACITY_KEY` to `ctx.storage`. */\nexport interface CapacityStorage {\n read(): Promise<unknown>\n write(payload: CapacityPayload): Promise<void>\n}\n"]}
@@ -2,4 +2,3 @@ export { parseHealthPayload } from "./parse.js";
2
2
  export { HealthRecordStore } from "./store.js";
3
3
  export { HEALTH_KEY, HEALTH_VERSION, MAX_HEALTH_RECORDS } from "./types.js";
4
4
  export type { HealthPayload, HealthStorage } from "./types.js";
5
- //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/state/health/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/state/health/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA","sourcesContent":["export { parseHealthPayload } from \"./parse.js\"\nexport { HealthRecordStore } from \"./store.js\"\nexport { HEALTH_KEY, HEALTH_VERSION, MAX_HEALTH_RECORDS } from \"./types.js\"\nexport type { HealthPayload, HealthStorage } from \"./types.js\"\n"]}
@@ -1,3 +1,2 @@
1
1
  import type { ResourceRecord } from "../../health/resource-health/types.js";
2
2
  export declare function parseHealthPayload(raw: unknown): ResourceRecord[];
3
- //# sourceMappingURL=parse.d.ts.map
@@ -24,12 +24,15 @@ function parseVocab(raw, vocabulary) {
24
24
  return undefined;
25
25
  return vocabulary.find((entry) => entry === raw);
26
26
  }
27
- /** A non-empty bounded identifier string (provider/model/variant/account ids). */
27
+ /**
28
+ * A non-empty bounded identifier string (provider/model/variant/account ids).
29
+ * Over-long values are rejected, not truncated: the writer stores keys as-is,
30
+ * so a truncated key would name a different resource.
31
+ */
28
32
  function parseIdentifier(raw) {
29
- if (typeof raw !== "string")
33
+ if (typeof raw !== "string" || raw === "" || raw.length > 128)
30
34
  return undefined;
31
- const value = raw.length > 128 ? raw.slice(0, 128) : raw;
32
- return value === "" ? undefined : value;
35
+ return raw;
33
36
  }
34
37
  function parseKey(raw) {
35
38
  if (!isRecord(raw))
@@ -40,6 +43,13 @@ function parseKey(raw) {
40
43
  const accountID = parseIdentifier(raw["accountID"]);
41
44
  const modelID = parseIdentifier(raw["modelID"]);
42
45
  const variantID = parseIdentifier(raw["variantID"]);
46
+ // A present-but-unusable scope field would silently widen the key.
47
+ if (raw["accountID"] !== undefined && accountID === undefined)
48
+ return undefined;
49
+ if (raw["modelID"] !== undefined && modelID === undefined)
50
+ return undefined;
51
+ if (raw["variantID"] !== undefined && variantID === undefined)
52
+ return undefined;
43
53
  // Scope fields must form a valid prefix: a variant without a model, or a
44
54
  // model without its variant's provider context, is not a real resource.
45
55
  if (variantID !== undefined && modelID === undefined)
@@ -94,6 +104,12 @@ function parseRecord(raw) {
94
104
  if (!isFiniteNumber(updatedAt))
95
105
  return undefined;
96
106
  const window = parseWindow(raw["window"]);
107
+ // Windowed states lift only when their window elapses: without a valid
108
+ // window the record would block the resource permanently, so it is dropped
109
+ // (the resource reads as healthy until fresh evidence arrives).
110
+ if ((health === "rate_limited" || health === "quota_exhausted") && window === undefined) {
111
+ return undefined;
112
+ }
97
113
  return {
98
114
  key,
99
115
  health,
@@ -1 +1 @@
1
- {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/state/health/parse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/state/health/parse.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Read-side parsing for persisted health records. Every parser is total: it\n * accepts `unknown` and returns typed records, dropping anything invalid — a\n * corrupted health file can never take the plugin down (ADP-031). State and\n * breaker vocabularies are membership-checked; timestamps must be finite\n * numbers. An older plugin reading newer records may drop unknown-vocabulary\n * entries — health records are bounded mirrors of an in-memory registry, and\n * the payload version guards the schema itself.\n */\nimport { BREAKER_STATES } from \"../../health/circuit-breaker/types.js\"\nimport type { BreakerRecord } from \"../../health/circuit-breaker/types.js\"\nimport { HEALTH_STATES } from \"../../health/resource-health/types.js\"\nimport type {\n ResourceKey,\n ResourceRecord,\n ResourceWindow,\n} from \"../../health/resource-health/types.js\"\nimport { HEALTH_VERSION } from \"./types.js\"\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction isFiniteNumber(raw: unknown): raw is number {\n return typeof raw === \"number\" && Number.isFinite(raw)\n}\n\nfunction isNonNegativeInt(raw: unknown): raw is number {\n return isFiniteNumber(raw) && Number.isInteger(raw) && raw >= 0\n}\n\nfunction parseVocab<V extends readonly string[]>(\n raw: unknown,\n vocabulary: V,\n): V[number] | undefined {\n if (typeof raw !== \"string\") return undefined\n return vocabulary.find((entry) => entry === raw)\n}\n\n/**\n * A non-empty bounded identifier string (provider/model/variant/account ids).\n * Over-long values are rejected, not truncated: the writer stores keys as-is,\n * so a truncated key would name a different resource.\n */\nfunction parseIdentifier(raw: unknown): string | undefined {\n if (typeof raw !== \"string\" || raw === \"\" || raw.length > 128) return undefined\n return raw\n}\n\nfunction parseKey(raw: unknown): ResourceKey | undefined {\n if (!isRecord(raw)) return undefined\n const providerID = parseIdentifier(raw[\"providerID\"])\n if (providerID === undefined) return undefined\n const accountID = parseIdentifier(raw[\"accountID\"])\n const modelID = parseIdentifier(raw[\"modelID\"])\n const variantID = parseIdentifier(raw[\"variantID\"])\n // A present-but-unusable scope field would silently widen the key.\n if (raw[\"accountID\"] !== undefined && accountID === undefined) return undefined\n if (raw[\"modelID\"] !== undefined && modelID === undefined) return undefined\n if (raw[\"variantID\"] !== undefined && variantID === undefined) return undefined\n // Scope fields must form a valid prefix: a variant without a model, or a\n // model without its variant's provider context, is not a real resource.\n if (variantID !== undefined && modelID === undefined) return undefined\n return {\n providerID,\n ...(accountID !== undefined ? { accountID } : {}),\n ...(modelID !== undefined ? { modelID } : {}),\n ...(variantID !== undefined ? { variantID } : {}),\n }\n}\n\nfunction parseBreaker(raw: unknown): BreakerRecord | undefined {\n if (!isRecord(raw)) return undefined\n const state = parseVocab(raw[\"state\"], BREAKER_STATES)\n const failures = raw[\"failures\"]\n const openCount = raw[\"openCount\"]\n if (state === undefined) return undefined\n if (!(isNonNegativeInt(failures) && isNonNegativeInt(openCount))) return undefined\n const reopenAt = raw[\"reopenAt\"]\n const probeId = parseIdentifier(raw[\"probeId\"])\n const probeAt = raw[\"probeAt\"]\n return {\n state,\n failures,\n openCount,\n ...(isFiniteNumber(reopenAt) ? { reopenAt } : {}),\n ...(probeId !== undefined ? { probeId } : {}),\n ...(isFiniteNumber(probeAt) ? { probeAt } : {}),\n }\n}\n\nfunction parseWindow(raw: unknown): ResourceWindow | undefined {\n if (!isRecord(raw)) return undefined\n const kind = parseVocab(raw[\"kind\"], [\"rate-limit\", \"quota\"] as const)\n const until = raw[\"until\"]\n if (kind === undefined || !isFiniteNumber(until)) return undefined\n return { kind, until }\n}\n\nfunction parseRecord(raw: unknown): ResourceRecord | undefined {\n if (!isRecord(raw)) return undefined\n const key = parseKey(raw[\"key\"])\n const health = parseVocab(raw[\"health\"], HEALTH_STATES)\n const breaker = parseBreaker(raw[\"breaker\"])\n const updatedAt = raw[\"updatedAt\"]\n if (key === undefined || health === undefined || breaker === undefined) return undefined\n if (!isFiniteNumber(updatedAt)) return undefined\n const window = parseWindow(raw[\"window\"])\n // Windowed states lift only when their window elapses: without a valid\n // window the record would block the resource permanently, so it is dropped\n // (the resource reads as healthy until fresh evidence arrives).\n if ((health === \"rate_limited\" || health === \"quota_exhausted\") && window === undefined) {\n return undefined\n }\n return {\n key,\n health,\n breaker,\n ...(window !== undefined ? { window } : {}),\n updatedAt,\n }\n}\n\nexport function parseHealthPayload(raw: unknown): ResourceRecord[] {\n if (!isRecord(raw)) return []\n if (raw[\"version\"] !== HEALTH_VERSION) return []\n const list = raw[\"records\"]\n if (!Array.isArray(list)) return []\n const parsed: ResourceRecord[] = []\n for (const entry of list.slice(0, 512)) {\n const record = parseRecord(entry)\n if (record !== undefined) parsed.push(record)\n }\n return parsed\n}\n"]}
@@ -15,4 +15,3 @@ export declare class HealthRecordStore {
15
15
  */
16
16
  replace(records: readonly ResourceRecord[]): Promise<void>;
17
17
  }
18
- //# sourceMappingURL=store.d.ts.map
@@ -12,11 +12,15 @@ import { MAX_HEALTH_RECORDS, HEALTH_VERSION } from "./types.js";
12
12
  export class HealthRecordStore {
13
13
  storage;
14
14
  #records = [];
15
+ #queue = Promise.resolve();
15
16
  constructor(storage) {
16
17
  this.storage = storage;
17
18
  }
18
19
  /** Rebuild from storage (restart behavior). A read failure yields an empty store. */
19
- async load() {
20
+ load() {
21
+ return this.#serialize(() => this.#load());
22
+ }
23
+ async #load() {
20
24
  let raw;
21
25
  try {
22
26
  raw = await this.storage.read();
@@ -36,7 +40,10 @@ export class HealthRecordStore {
36
40
  * keeps the most recently updated records — stale scopes matter less than
37
41
  * the resources that are actually failing right now.
38
42
  */
39
- async replace(records) {
43
+ replace(records) {
44
+ return this.#serialize(() => this.#replace(records));
45
+ }
46
+ async #replace(records) {
40
47
  const next = records.length > MAX_HEALTH_RECORDS
41
48
  ? [...records]
42
49
  .sort((left, right) => right.updatedAt - left.updatedAt)
@@ -51,5 +58,12 @@ export class HealthRecordStore {
51
58
  await this.storage.write(payload);
52
59
  this.#records = next;
53
60
  }
61
+ // Reloads and writes share one queue; otherwise a slow persistence call
62
+ // can restore older state after a newer call has already committed.
63
+ #serialize(operation) {
64
+ const run = this.#queue.then(operation);
65
+ this.#queue = run.catch(() => undefined);
66
+ return run;
67
+ }
54
68
  }
55
69
  //# sourceMappingURL=store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/state/health/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAI/D,MAAM,OAAO,iBAAiB;IAGC;IAF7B,QAAQ,GAAqB,EAAE,CAAA;IAE/B,YAA6B,OAAsB;QAAtB,YAAO,GAAP,OAAO,CAAe;IAAG,CAAC;IAEvD,qFAAqF;IACrF,KAAK,CAAC,IAAI;QACR,IAAI,GAAY,CAAA;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAA;YAClB,OAAM;QACR,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAA;IACzC,CAAC;IAED,4BAA4B;IAC5B,QAAQ;QACN,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,OAAkC;QAC9C,MAAM,IAAI,GACR,OAAO,CAAC,MAAM,GAAG,kBAAkB;YACjC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;iBACT,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;iBACvD,KAAK,CAAC,CAAC,EAAE,kBAAkB,CAAC;YACjC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAA;QAClB,sEAAsE;QACtE,6DAA6D;QAC7D,MAAM,OAAO,GAAkB;YAC7B,OAAO,EAAE,cAAc;YACvB,OAAO,EAAE,IAAI;SACd,CAAA;QACD,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACjC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;IACtB,CAAC;CACF"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/state/health/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAI/D,MAAM,OAAO,iBAAiB;IAIC;IAH7B,QAAQ,GAAqB,EAAE,CAAA;IAC/B,MAAM,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAA;IAE5C,YAA6B,OAAsB;QAAtB,YAAO,GAAP,OAAO,CAAe;IAAG,CAAC;IAEvD,qFAAqF;IACrF,IAAI;QACF,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;IAC5C,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,GAAY,CAAA;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAA;YAClB,OAAM;QACR,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAA;IACzC,CAAC;IAED,4BAA4B;IAC5B,QAAQ;QACN,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAED;;;;OAIG;IACH,OAAO,CAAC,OAAkC;QACxC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;IACtD,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,OAAkC;QAC/C,MAAM,IAAI,GACR,OAAO,CAAC,MAAM,GAAG,kBAAkB;YACjC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;iBACT,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;iBACvD,KAAK,CAAC,CAAC,EAAE,kBAAkB,CAAC;YACjC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAA;QAClB,sEAAsE;QACtE,6DAA6D;QAC7D,MAAM,OAAO,GAAkB;YAC7B,OAAO,EAAE,cAAc;YACvB,OAAO,EAAE,IAAI;SACd,CAAA;QACD,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACjC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;IACtB,CAAC;IAED,wEAAwE;IACxE,oEAAoE;IACpE,UAAU,CAAC,SAA8B;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACvC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;QACxC,OAAO,GAAG,CAAA;IACZ,CAAC;CACF","sourcesContent":["/**\n * Bounded health-record store: a persistence mirror of the in-memory\n * resource-health registry. The store keeps the newest-updated records\n * (bounded, least-recently-updated evicted) and persists on every replace.\n * As everywhere else in `state/`, memory is only advanced after a successful\n * write, so memory and disk never diverge; write failures propagate to the\n * caller — the wiring layer's fail-open wrapper decides how to degrade\n * (ADP-031).\n */\nimport { parseHealthPayload } from \"./parse.js\"\nimport { MAX_HEALTH_RECORDS, HEALTH_VERSION } from \"./types.js\"\nimport type { HealthPayload, HealthStorage } from \"./types.js\"\nimport type { ResourceRecord } from \"../../health/resource-health/types.js\"\n\nexport class HealthRecordStore {\n #records: ResourceRecord[] = []\n #queue: Promise<unknown> = Promise.resolve()\n\n constructor(private readonly storage: HealthStorage) {}\n\n /** Rebuild from storage (restart behavior). A read failure yields an empty store. */\n load(): Promise<void> {\n return this.#serialize(() => this.#load())\n }\n\n async #load(): Promise<void> {\n let raw: unknown\n try {\n raw = await this.storage.read()\n } catch {\n this.#records = []\n return\n }\n this.#records = parseHealthPayload(raw)\n }\n\n /** All retained records. */\n snapshot(): readonly ResourceRecord[] {\n return this.#records\n }\n\n /**\n * Replace the whole record set with a fresh registry snapshot. The bound\n * keeps the most recently updated records — stale scopes matter less than\n * the resources that are actually failing right now.\n */\n replace(records: readonly ResourceRecord[]): Promise<void> {\n return this.#serialize(() => this.#replace(records))\n }\n\n async #replace(records: readonly ResourceRecord[]): Promise<void> {\n const next =\n records.length > MAX_HEALTH_RECORDS\n ? [...records]\n .sort((left, right) => right.updatedAt - left.updatedAt)\n .slice(0, MAX_HEALTH_RECORDS)\n : [...records]\n // Persist BEFORE committing memory: a write failure must leave memory\n // and disk consistent (the caller decides how to fail open).\n const payload: HealthPayload = {\n version: HEALTH_VERSION,\n records: next,\n }\n await this.storage.write(payload)\n this.#records = next\n }\n\n // Reloads and writes share one queue; otherwise a slow persistence call\n // can restore older state after a newer call has already committed.\n #serialize(operation: () => Promise<void>): Promise<void> {\n const run = this.#queue.then(operation)\n this.#queue = run.catch(() => undefined)\n return run\n }\n}\n"]}
@@ -21,4 +21,3 @@ export interface HealthStorage {
21
21
  read(): Promise<unknown>;
22
22
  write(payload: HealthPayload): Promise<void>;
23
23
  }
24
- //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/state/health/types.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,UAAU,GAAG,uBAAuB,CAAA;AACjD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAA;AAC/B,gFAAgF;AAChF,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAA"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/state/health/types.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,UAAU,GAAG,uBAAuB,CAAA;AACjD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAA;AAC/B,gFAAgF;AAChF,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAA","sourcesContent":["/**\n * Persisted resource health records. Health is otherwise memory-only state,\n * but the host's TUI-mode plugin reconciliation can load the plugin several\n * times into one process — hooks (the event pump) and RPC registration can\n * end up on different instances. Without persistence the status surface is\n * served by an instance whose registry never observed anything; persisted\n * records make health readable by every instance, exactly like receipts,\n * settings and parked work.\n */\nimport type { ResourceRecord } from \"../../health/resource-health/types.js\"\n\nexport const HEALTH_KEY = \"coool.adaptive/health\"\nexport const HEALTH_VERSION = 1\n/** Product bound — not a user knob. Keeps the most recently updated records. */\nexport const MAX_HEALTH_RECORDS = 512\n\nexport interface HealthPayload {\n readonly version: typeof HEALTH_VERSION\n readonly records: readonly ResourceRecord[]\n}\n\n/** Storage seam — the adapter binds `HEALTH_KEY` to `ctx.storage`. */\nexport interface HealthStorage {\n read(): Promise<unknown>\n write(payload: HealthPayload): Promise<void>\n}\n"]}
@@ -2,4 +2,3 @@ export { parseParkedPayload } from "./parse.js";
2
2
  export { ParkedWorkStore } from "./store.js";
3
3
  export { MAX_PARKED, MAX_PARKED_TEXT, PARKED_KEY, PARKED_VERSION } from "./types.js";
4
4
  export type { ParkedPayload, ParkedRecord, ParkedStorage } from "./types.js";
5
- //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/state/parked-work/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/state/parked-work/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA","sourcesContent":["export { parseParkedPayload } from \"./parse.js\"\nexport { ParkedWorkStore } from \"./store.js\"\nexport { MAX_PARKED, MAX_PARKED_TEXT, PARKED_KEY, PARKED_VERSION } from \"./types.js\"\nexport type { ParkedPayload, ParkedRecord, ParkedStorage } from \"./types.js\"\n"]}
@@ -4,4 +4,3 @@ import type { ParkedRecord } from "./types.js";
4
4
  * versionless draft array; anything else yields no records.
5
5
  */
6
6
  export declare function parseParkedPayload(raw: unknown): ParkedRecord[];
7
- //# sourceMappingURL=parse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/state/parked-work/parse.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAC5D,OAAO,EAAE,KAAK,EAAE,MAAM,iCAAiC,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAGxE,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC7E,CAAC;AAED,SAAS,WAAW,CAAC,GAAY;IAC/B,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IAC7C,OAAO,GAAG,CAAC,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;AAC3E,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAY;IACxC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;IAC9B,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAA;AACzC,CAAC;AAED,4EAA4E;AAC5E,SAAS,kBAAkB,CAAC,GAAY;IACtC,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,SAAS,CAAA;AACtC,CAAC;AAED,SAAS,WAAW,CAAC,GAAY;IAC/B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAA;IACpC,MAAM,EAAE,GAAG,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA;IAC1C,MAAM,SAAS,GAAG,oBAAoB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAA;IACxD,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC/B,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,CAAA;IAChC,IACE,EAAE,KAAK,SAAS;QAChB,SAAS,KAAK,SAAS;QACvB,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,SAAS,KAAK,QAAQ;QAC7B,OAAO,QAAQ,KAAK,QAAQ;QAC5B,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC1B,QAAQ,GAAG,CAAC,EACZ,CAAC;QACD,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,OAAO,CAAC,CAAA;IACrD,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAA;IAChE,IAAI,IAAI,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAChE,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;IAChD,MAAM,WAAW,GAAG,GAAG,CAAC,UAAU,CAAC,CAAA;IACnC,MAAM,QAAQ,GACZ,OAAO,WAAW,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,WAAW,IAAI,CAAC;QAClF,CAAC,CAAC,WAAW;QACb,CAAC,CAAC,SAAS,CAAA;IACf,OAAO;QACL,EAAE;QACF,SAAS;QACT,IAAI;QACJ,MAAM;QACN,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,QAAQ;QACR,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAY;IAC7C,IAAI,IAAa,CAAA;IACjB,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAClB,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAA;QAC9B,IAAI,OAAO,KAAK,cAAc,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,EAAE,CAAA;QAClE,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAA;IACtB,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,IAAI,GAAG,GAAG,CAAA;IACZ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAA;IACnC,MAAM,MAAM,GAAG,IAAI;SAChB,GAAG,CAAC,WAAW,CAAC;SAChB,MAAM,CAAC,CAAC,MAAM,EAA0B,EAAE,CAAC,MAAM,KAAK,SAAS,CAAC,CAAA;IACnE,OAAO,MAAM,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;AACxE,CAAC"}
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/state/parked-work/parse.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Read-side parsing for persisted parked records (ADP-024). Total: accepts\n * `unknown`, drops invalid entries, never throws (ADP-031). Vocabulary is\n * membership-checked (the write path is typed); free-text is re-bounded.\n */\nimport { PARK_REASONS } from \"../../core/scheduler/types.js\"\nimport { TIERS } from \"../../core/tier-policy/types.js\"\nimport { MAX_PARKED, MAX_PARKED_TEXT, PARKED_VERSION } from \"./types.js\"\nimport type { ParkedRecord } from \"./types.js\"\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction boundString(raw: unknown): string | undefined {\n if (typeof raw !== \"string\") return undefined\n return raw.length > MAX_PARKED_TEXT ? raw.slice(0, MAX_PARKED_TEXT) : raw\n}\n\nfunction parseOptionalBounded(raw: unknown): string | undefined {\n const value = boundString(raw)\n return value === \"\" ? undefined : value\n}\n\n/** Free-text detail keeps empty strings (round-trips through the store). */\nfunction parseDetailBounded(raw: unknown): string | undefined {\n return boundString(raw) ?? undefined\n}\n\nfunction parseParked(raw: unknown): ParkedRecord | undefined {\n if (!isRecord(raw)) return undefined\n const id = parseOptionalBounded(raw[\"id\"])\n const sessionID = parseOptionalBounded(raw[\"sessionID\"])\n const tierRaw = raw[\"tier\"]\n const reasonRaw = raw[\"reason\"]\n const parkedAt = raw[\"parkedAt\"]\n if (\n id === undefined ||\n sessionID === undefined ||\n typeof tierRaw !== \"string\" ||\n typeof reasonRaw !== \"string\" ||\n typeof parkedAt !== \"number\" ||\n !Number.isFinite(parkedAt) ||\n parkedAt < 0\n ) {\n return undefined\n }\n const tier = TIERS.find((entry) => entry === tierRaw)\n const reason = PARK_REASONS.find((entry) => entry === reasonRaw)\n if (tier === undefined || reason === undefined) return undefined\n const detail = parseDetailBounded(raw[\"detail\"])\n const attemptsRaw = raw[\"attempts\"]\n const attempts =\n typeof attemptsRaw === \"number\" && Number.isInteger(attemptsRaw) && attemptsRaw >= 0\n ? attemptsRaw\n : undefined\n return {\n id,\n sessionID,\n tier,\n reason,\n ...(detail !== undefined ? { detail } : {}),\n parkedAt,\n ...(attempts !== undefined ? { attempts } : {}),\n }\n}\n\n/**\n * Parse a persisted parked payload. Accepts the versioned shape and a\n * versionless draft array; anything else yields no records.\n */\nexport function parseParkedPayload(raw: unknown): ParkedRecord[] {\n let list: unknown\n if (isRecord(raw)) {\n const version = raw[\"version\"]\n if (version !== PARKED_VERSION && version !== undefined) return []\n list = raw[\"parked\"]\n } else if (Array.isArray(raw)) {\n list = raw\n }\n if (!Array.isArray(list)) return []\n const parsed = list\n .map(parseParked)\n .filter((record): record is ParkedRecord => record !== undefined)\n return parsed.length > MAX_PARKED ? parsed.slice(-MAX_PARKED) : parsed\n}\n"]}
@@ -15,4 +15,3 @@ export declare class ParkedWorkStore {
15
15
  */
16
16
  resume(id: string): Promise<ParkedRecord | undefined>;
17
17
  }
18
- //# sourceMappingURL=store.d.ts.map
@@ -15,11 +15,15 @@ function boundDetail(raw) {
15
15
  export class ParkedWorkStore {
16
16
  storage;
17
17
  #records = [];
18
+ #queue = Promise.resolve();
18
19
  constructor(storage) {
19
20
  this.storage = storage;
20
21
  }
21
22
  /** Rebuild from storage (restart behavior). A read failure yields an empty store. */
22
- async load() {
23
+ load() {
24
+ return this.#serialize(() => this.#load());
25
+ }
26
+ async #load() {
23
27
  let raw;
24
28
  try {
25
29
  raw = await this.storage.read();
@@ -37,7 +41,10 @@ export class ParkedWorkStore {
37
41
  count() {
38
42
  return this.#records.length;
39
43
  }
40
- async park(record) {
44
+ park(record) {
45
+ return this.#serialize(() => this.#park(record));
46
+ }
47
+ async #park(record) {
41
48
  const bounded = {
42
49
  ...record,
43
50
  ...(record.detail !== undefined ? { detail: boundDetail(record.detail) } : {}),
@@ -53,7 +60,10 @@ export class ParkedWorkStore {
53
60
  * Remove a parked record and return it so the execution layer knows what
54
61
  * to continue. `undefined` (no record, no write) when the id is unknown.
55
62
  */
56
- async resume(id) {
63
+ resume(id) {
64
+ return this.#serialize(() => this.#resume(id));
65
+ }
66
+ async #resume(id) {
57
67
  const record = this.#records.find((entry) => entry.id === id);
58
68
  if (record === undefined)
59
69
  return undefined;
@@ -69,6 +79,13 @@ export class ParkedWorkStore {
69
79
  const dropped = new Set(byOldest.slice(0, records.length - MAX_PARKED).map((r) => r.id));
70
80
  return records.filter((record) => !dropped.has(record.id));
71
81
  }
82
+ // Reads share the queue so reloads cannot overwrite newer commits. Recover
83
+ // the queue after rejection while preserving the failing caller's promise.
84
+ #serialize(operation) {
85
+ const run = this.#queue.then(operation);
86
+ this.#queue = run.catch(() => undefined);
87
+ return run;
88
+ }
72
89
  /** Writes the given next state; the caller commits memory only on success. */
73
90
  async #persist(parked) {
74
91
  const payload = {
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/state/parked-work/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/state/parked-work/store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Parked-work store (ADP-024). Records are keyed by unit id — parking the\n * same unit again replaces the record (latest park wins). The cap\n * `MAX_PARKED` evicts the oldest `parkedAt` first: parked work is waiting\n * work, and unbounded growth would mean recovery never happens. Write\n * failures propagate to the caller (fail-open is the wiring layer's call), and\n * the in-memory list is only advanced after a successful write — memory and\n * disk never diverge.\n */\nimport { parseParkedPayload } from \"./parse.js\"\nimport { MAX_PARKED, MAX_PARKED_TEXT, PARKED_VERSION } from \"./types.js\"\nimport type { ParkedPayload, ParkedRecord, ParkedStorage } from \"./types.js\"\n\nfunction boundDetail(raw: string): string {\n return raw.length > MAX_PARKED_TEXT ? raw.slice(0, MAX_PARKED_TEXT) : raw\n}\n\nexport class ParkedWorkStore {\n #records: ParkedRecord[] = []\n #queue: Promise<unknown> = Promise.resolve()\n\n constructor(private readonly storage: ParkedStorage) {}\n\n /** Rebuild from storage (restart behavior). A read failure yields an empty store. */\n load(): Promise<void> {\n return this.#serialize(() => this.#load())\n }\n\n async #load(): Promise<void> {\n let raw: unknown\n try {\n raw = await this.storage.read()\n } catch {\n this.#records = []\n return\n }\n this.#records = parseParkedPayload(raw)\n }\n\n /** All parked records, insertion order. */\n list(): readonly ParkedRecord[] {\n return this.#records\n }\n\n count(): number {\n return this.#records.length\n }\n\n park(record: ParkedRecord): Promise<void> {\n return this.#serialize(() => this.#park(record))\n }\n\n async #park(record: ParkedRecord): Promise<void> {\n const bounded: ParkedRecord = {\n ...record,\n ...(record.detail !== undefined ? { detail: boundDetail(record.detail) } : {}),\n }\n const withoutId = this.#records.filter((entry) => entry.id !== bounded.id)\n const next = this.#evictOldest([...withoutId, bounded])\n // Persist BEFORE committing memory: a failed resume must not silently\n // drop the parked unit (memory and disk stay consistent on failure).\n await this.#persist(next)\n this.#records = next\n }\n\n /**\n * Remove a parked record and return it so the execution layer knows what\n * to continue. `undefined` (no record, no write) when the id is unknown.\n */\n resume(id: string): Promise<ParkedRecord | undefined> {\n return this.#serialize(() => this.#resume(id))\n }\n\n async #resume(id: string): Promise<ParkedRecord | undefined> {\n const record = this.#records.find((entry) => entry.id === id)\n if (record === undefined) return undefined\n const next = this.#records.filter((entry) => entry.id !== id)\n await this.#persist(next)\n this.#records = next\n return record\n }\n\n #evictOldest(records: ParkedRecord[]): ParkedRecord[] {\n if (records.length <= MAX_PARKED) return records\n const byOldest = [...records].sort((a, b) => a.parkedAt - b.parkedAt)\n const dropped = new Set(byOldest.slice(0, records.length - MAX_PARKED).map((r) => r.id))\n return records.filter((record) => !dropped.has(record.id))\n }\n\n // Reads share the queue so reloads cannot overwrite newer commits. Recover\n // the queue after rejection while preserving the failing caller's promise.\n #serialize<T>(operation: () => Promise<T>): Promise<T> {\n const run = this.#queue.then(operation)\n this.#queue = run.catch(() => undefined)\n return run\n }\n\n /** Writes the given next state; the caller commits memory only on success. */\n async #persist(parked: readonly ParkedRecord[]): Promise<void> {\n const payload: ParkedPayload = {\n version: PARKED_VERSION,\n parked,\n }\n await this.storage.write(payload)\n }\n}\n"]}
@@ -39,4 +39,3 @@ export interface ParkedStorage {
39
39
  read(): Promise<unknown>;
40
40
  write(payload: ParkedPayload): Promise<void>;
41
41
  }
42
- //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/state/parked-work/types.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,UAAU,GAAG,uBAAuB,CAAA;AACjD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAA;AAC/B,2EAA2E;AAC3E,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAA;AAC5B,qEAAqE;AACrE,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAA"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/state/parked-work/types.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,UAAU,GAAG,uBAAuB,CAAA;AACjD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAA;AAC/B,2EAA2E;AAC3E,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAA;AAC5B,qEAAqE;AACrE,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAA","sourcesContent":["/**\n * Durable parked work (ADP-024): admission-time records for work with no\n * compatible healthy resource, persisted so they survive restart. A parked\n * record carries only identity and routing context — resumption (T-13) is a\n * clean continuation that re-runs routing fresh; it is never the resurrection\n * of a failed network call.\n */\nimport type { ParkReason } from \"../../core/scheduler/types.js\"\nimport type { TierName } from \"../../core/tier-policy/types.js\"\n\nexport const PARKED_KEY = \"coool.adaptive/parked\"\nexport const PARKED_VERSION = 1\n/** Product bound — not a user knob. Eviction drops the oldest parkedAt. */\nexport const MAX_PARKED = 64\n/** Free-text detail is bounded like every other persisted string. */\nexport const MAX_PARKED_TEXT = 128\n\nexport interface ParkedRecord {\n /** Unit id (`${sessionID}#${episode}`) — one parked record per unit. */\n readonly id: string\n readonly sessionID: string\n /** Required tier at park time; resumption re-runs routing fresh. */\n readonly tier: TierName\n readonly reason: ParkReason\n readonly detail?: string | undefined\n /** Park timestamp (adapter clock, ms epoch). */\n readonly parkedAt: number\n /**\n * Failed resume attempts (absent = never retried). The resume planner\n * drops records whose attempts reach the planner's budget so a\n * persistently failing continuation cannot retry forever (ADP-011).\n */\n readonly attempts?: number | undefined\n}\n\nexport interface ParkedPayload {\n readonly version: typeof PARKED_VERSION\n readonly parked: readonly ParkedRecord[]\n}\n\n/** Storage seam — the adapter binds `PARKED_KEY` to `ctx.storage`. */\nexport interface ParkedStorage {\n read(): Promise<unknown>\n write(payload: ParkedPayload): Promise<void>\n}\n"]}
@@ -12,4 +12,3 @@ export declare function boundText(raw: string): string;
12
12
  * the `observe-only` recursion (max one nesting level is ever produced).
13
13
  */
14
14
  export declare function boundDecision(decision: Decision, depth?: number): Decision;
15
- //# sourceMappingURL=bound.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bound.js","sourceRoot":"","sources":["../../../src/state/receipts/bound.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bound.js","sourceRoot":"","sources":["../../../src/state/receipts/bound.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Bounding for receipts (ADP-030). Receipts are built from typed scheduler\n * decisions, but every string they can carry is truncated to\n * `MAX_RECEIPT_TEXT` before persisting — including identifiers. Boundedness\n * is what makes the no-secrets invariant checkable: no field accepts\n * unbounded text, so nothing unbounded can be persisted.\n */\nimport type {\n ApplyDecision,\n DeferDecision,\n Decision,\n EscalateDecision,\n ObserveOnlyDecision,\n ParkDecision,\n} from \"../../core/scheduler/types.js\"\nimport type { ModelRef } from \"../../core/work-unit/types.js\"\nimport { MAX_RECEIPT_TEXT } from \"./types.js\"\n\nexport function boundText(raw: string): string {\n return raw.length > MAX_RECEIPT_TEXT ? raw.slice(0, MAX_RECEIPT_TEXT) : raw\n}\n\nfunction boundRef(ref: ModelRef): ModelRef {\n return {\n providerID: boundText(ref.providerID),\n id: boundText(ref.id),\n ...(ref.variant !== undefined ? { variant: boundText(ref.variant) } : {}),\n }\n}\n\nfunction boundApply(decision: ApplyDecision): ApplyDecision {\n return {\n kind: \"apply\",\n model: boundRef(decision.model),\n ...(decision.tier !== undefined ? { tier: decision.tier } : {}),\n reason: decision.reason,\n evidence: {\n skipped: decision.evidence.skipped.map((skip) => ({\n ref: boundRef(skip.ref),\n why: skip.why,\n })),\n ...(decision.evidence.probeId !== undefined\n ? { probeId: boundText(decision.evidence.probeId) }\n : {}),\n },\n }\n}\n\nfunction boundDefer(decision: DeferDecision): DeferDecision {\n return {\n kind: \"defer\",\n reason: decision.reason,\n ...(decision.detail !== undefined ? { detail: boundText(decision.detail) } : {}),\n }\n}\n\nfunction boundPark(decision: ParkDecision): ParkDecision {\n return {\n kind: \"park\",\n reason: decision.reason,\n ...(decision.detail !== undefined ? { detail: boundText(decision.detail) } : {}),\n }\n}\n\nfunction boundEscalate(decision: EscalateDecision): EscalateDecision {\n return {\n kind: \"escalate\",\n target: boundRef(decision.target),\n step: decision.step,\n tier: decision.tier,\n evidence: decision.evidence.map((item) => ({\n kind: item.kind,\n ...(item.detail !== undefined ? { detail: boundText(item.detail) } : {}),\n })),\n budgetRemaining: decision.budgetRemaining,\n }\n}\n\nfunction boundObserveOnly(decision: ObserveOnlyDecision, depth: number): ObserveOnlyDecision {\n return { kind: \"observe-only\", would: boundDecision(decision.would, depth + 1) }\n}\n\n/**\n * Structural copy of a decision with every string bounded. `depth` guards\n * the `observe-only` recursion (max one nesting level is ever produced).\n */\nexport function boundDecision(decision: Decision, depth = 0): Decision {\n switch (decision.kind) {\n case \"apply\":\n return boundApply(decision)\n case \"defer\":\n return boundDefer(decision)\n case \"park\":\n return boundPark(decision)\n case \"escalate\":\n return boundEscalate(decision)\n case \"observe-only\":\n return depth < 2 ? boundObserveOnly(decision, depth) : decision\n }\n}\n"]}
@@ -4,4 +4,3 @@ export { ReceiptStore } from "./store.js";
4
4
  export type { ReceiptRef } from "./store.js";
5
5
  export { MAX_RECEIPTS, MAX_RECEIPT_TEXT, RECEIPTS_KEY, RECEIPTS_VERSION } from "./types.js";
6
6
  export type { Receipt, ReceiptInput, ReceiptMeta, ReceiptOutcome, ReceiptsPayload, ReceiptsStorage, } from "./types.js";
7
- //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/state/receipts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/state/receipts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA","sourcesContent":["export { boundDecision, boundText } from \"./bound.js\"\nexport { parseReceiptsPayload } from \"./parse.js\"\nexport { ReceiptStore } from \"./store.js\"\nexport type { ReceiptRef } from \"./store.js\"\nexport { MAX_RECEIPTS, MAX_RECEIPT_TEXT, RECEIPTS_KEY, RECEIPTS_VERSION } from \"./types.js\"\nexport type {\n Receipt,\n ReceiptInput,\n ReceiptMeta,\n ReceiptOutcome,\n ReceiptsPayload,\n ReceiptsStorage,\n} from \"./types.js\"\n"]}
@@ -4,4 +4,3 @@ import type { Receipt } from "./types.js";
4
4
  * versionless draft array; anything else yields no receipts.
5
5
  */
6
6
  export declare function parseReceiptsPayload(raw: unknown): Receipt[];
7
- //# sourceMappingURL=parse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/state/receipts/parse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/state/receipts/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,aAAa,EACb,yBAAyB,EACzB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,uBAAuB,GACxB,MAAM,+BAA+B,CAAA;AAWtC,OAAO,EAAE,KAAK,EAAE,MAAM,iCAAiC,CAAA;AAEvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAA;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAG7E,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC7E,CAAC;AAED,SAAS,WAAW,CAAC,GAAY;IAC/B,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IAC7C,OAAO,GAAG,CAAC,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;AAC7E,CAAC;AAED,SAAS,mBAAmB,CAAC,GAAY;IACvC,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;AACpE,CAAC;AAED,SAAS,UAAU,CACjB,GAAY,EACZ,UAAa;IAEb,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IAC7C,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,GAAG,CAAC,CAAA;AAClD,CAAC;AAED,SAAS,SAAS,CAAC,GAAY;IAC7B,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IAC7C,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,GAAG,CAAC,CAAA;AAC3C,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAY;IACxC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;IAC9B,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAA;AACzC,CAAC;AAED,4EAA4E;AAC5E,SAAS,kBAAkB,CAAC,GAAY;IACtC,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,SAAS,CAAA;AACtC,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAY;IACtC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAA;IACpC,MAAM,UAAU,GAAG,GAAG,CAAC,SAAS,CAAC,CAAA;IACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC;QAAE,OAAO,SAAS,CAAA;IAChD,MAAM,OAAO,GAAuB,EAAE,CAAA;IACtC,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC3C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,SAAQ;QAC9B,MAAM,GAAG,GAAG,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;QACvC,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC,CAAA;QAClD,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS;YAAE,SAAQ;QACpD,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAA;IAC5B,CAAC;IACD,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAA;IAClD,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAA;AACnE,CAAC;AAED,SAAS,UAAU,CAAC,GAA4B;IAC9C,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;IACzC,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC,CAAA;IACvD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAA;IACpD,IAAI,KAAK,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC1E,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;IACnC,OAAO;QACL,IAAI,EAAE,OAAO;QACb,KAAK;QACL,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,MAAM;QACN,QAAQ;KACT,CAAA;AACH,CAAC;AAED,SAAS,UAAU,CAAC,GAA4B;IAC9C,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,uBAAuB,CAAC,CAAA;IACjE,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAC1C,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;IAChD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAA;AAC/E,CAAC;AAED,SAAS,SAAS,CAAC,GAA4B;IAC7C,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC,CAAA;IACtD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAC1C,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;IAChD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAA;AAC9E,CAAC;AAED,SAAS,aAAa,CAAC,GAA4B;IACjD,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC3C,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC,CAAA;IACtD,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;IACnC,MAAM,kBAAkB,GAAG,GAAG,CAAC,iBAAiB,CAAC,CAAA;IACjD,IACE,MAAM,KAAK,SAAS;QACpB,IAAI,KAAK,SAAS;QAClB,IAAI,KAAK,SAAS;QAClB,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,EACxC,CAAC;QACD,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,MAAM,WAAW,GAAG,GAAG,CAAC,UAAU,CAAC,CAAA;IACnC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;QAAE,OAAO,SAAS,CAAA;IACjD,MAAM,QAAQ,GAAyB,EAAE,CAAA;IACzC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC5C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,SAAQ;QAC9B,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,yBAAyB,CAAC,CAAA;QACjE,IAAI,IAAI,KAAK,SAAS;YAAE,SAAQ;QAChC,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAA;QAClD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IACtE,CAAC;IACD,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,MAAM;QACN,IAAI;QACJ,IAAI;QACJ,QAAQ;QACR,eAAe,EAAE,kBAAkB;KACpC,CAAA;AACH,CAAC;AAED,gFAAgF;AAChF,MAAM,eAAe,GAAG,CAAC,CAAA;AAEzB,SAAS,gBAAgB,CACvB,GAA4B,EAC5B,KAAa;IAEb,IAAI,KAAK,IAAI,eAAe;QAAE,OAAO,SAAS,CAAA;IAC9C,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAA;IACpD,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,CAAA;AAC1E,CAAC;AAED,SAAS,aAAa,CAAC,GAAY,EAAE,KAAK,GAAG,CAAC;IAC5C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAA;IACpC,QAAQ,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACpB,KAAK,OAAO;YACV,OAAO,UAAU,CAAC,GAAG,CAAC,CAAA;QACxB,KAAK,OAAO;YACV,OAAO,UAAU,CAAC,GAAG,CAAC,CAAA;QACxB,KAAK,MAAM;YACT,OAAO,SAAS,CAAC,GAAG,CAAC,CAAA;QACvB,KAAK,UAAU;YACb,OAAO,aAAa,CAAC,GAAG,CAAC,CAAA;QAC3B,KAAK,cAAc;YACjB,OAAO,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QACrC;YACE,OAAO,SAAS,CAAA;IACpB,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,GAAY;IAChC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAA;IACpC,QAAQ,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtB,KAAK,WAAW;YACd,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;QAChC,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC,CAAA;YAChE,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAA;QAC5E,CAAC;QACD,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC,CAAA;YAC3D,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,CAAA;QAC7E,CAAC;QACD;YACE,OAAO,SAAS,CAAA;IACpB,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,GAAY;IAChC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAA;IACpC,MAAM,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,CAAA;IACpB,MAAM,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,CAAA;IACpB,MAAM,SAAS,GAAG,oBAAoB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAA;IACxD,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAA;IAC/C,IACE,CAAC,CAAC,mBAAmB,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,mBAAmB,CAAC,EAAE,CAAC,CAAC;QAC7E,SAAS,KAAK,SAAS;QACvB,QAAQ,KAAK,SAAS,EACtB,CAAC;QACD,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,MAAM,MAAM,GAAG,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;IAClD,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;IACnC,wEAAwE;IACxE,wEAAwE;IACxE,iEAAiE;IACjE,IAAI,OAAmC,CAAA;IACvC,IAAI,GAAG,CAAC,SAAS,CAAC,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAA;QACtC,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,SAAS,CAAA;IAC7C,CAAC;IACD,OAAO;QACL,EAAE;QACF,EAAE;QACF,SAAS;QACT,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,QAAQ;QACR,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9C,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAY;IAC/C,IAAI,IAAa,CAAA;IACjB,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAClB,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAA;QAC9B,IAAI,OAAO,KAAK,gBAAgB,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,EAAE,CAAA;QACpE,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,CAAA;IACxB,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,IAAI,GAAG,GAAG,CAAA;IACZ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAA;IACnC,MAAM,MAAM,GAAG,IAAI;SAChB,GAAG,CAAC,YAAY,CAAC;SACjB,MAAM,CAAC,CAAC,OAAO,EAAsB,EAAE,CAAC,OAAO,KAAK,SAAS,CAAC,CAAA;IACjE,OAAO,MAAM,CAAC,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;AAC5E,CAAC","sourcesContent":["/**\n * Read-side parsing for persisted receipts. Every parser is total: it accepts\n * `unknown` and returns typed records, dropping anything invalid — a\n * corrupted receipts file can never take the plugin down (ADP-031). Reason\n * vocabularies are membership-checked (the write path is typed); free-text\n * fields are re-bounded. An older plugin reading newer receipts may drop\n * unknown-vocabulary entries — receipts are bounded diagnostics, eviction is\n * expected behavior, and the payload version guards the schema itself.\n */\nimport {\n APPLY_REASONS,\n ESCALATION_EVIDENCE_KINDS,\n ESCALATION_STEPS,\n PARK_REASONS,\n SKIP_REASONS,\n SCHEDULER_DEFER_REASONS,\n} from \"../../core/scheduler/types.js\"\nimport type {\n ApplyDecision,\n DeferDecision,\n Decision,\n EscalateDecision,\n EscalationEvidence,\n ObserveOnlyDecision,\n ParkDecision,\n SkippedCandidate,\n} from \"../../core/scheduler/types.js\"\nimport { TIERS } from \"../../core/tier-policy/types.js\"\nimport type { TierName } from \"../../core/tier-policy/types.js\"\nimport { INTERRUPT_REASONS } from \"../../core/work-unit/interruption.js\"\nimport { FAILURE_CATEGORIES } from \"../../health/classifier/types.js\"\nimport { parseModelRef } from \"../settings/parse.js\"\nimport { MAX_RECEIPTS, MAX_RECEIPT_TEXT, RECEIPTS_VERSION } from \"./types.js\"\nimport type { Receipt, ReceiptOutcome } from \"./types.js\"\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction boundString(raw: unknown): string | undefined {\n if (typeof raw !== \"string\") return undefined\n return raw.length > MAX_RECEIPT_TEXT ? raw.slice(0, MAX_RECEIPT_TEXT) : raw\n}\n\nfunction isFiniteNonNegative(raw: unknown): raw is number {\n return typeof raw === \"number\" && Number.isFinite(raw) && raw >= 0\n}\n\nfunction parseVocab<V extends readonly string[]>(\n raw: unknown,\n vocabulary: V,\n): V[number] | undefined {\n if (typeof raw !== \"string\") return undefined\n return vocabulary.find((entry) => entry === raw)\n}\n\nfunction parseTier(raw: unknown): TierName | undefined {\n if (typeof raw !== \"string\") return undefined\n return TIERS.find((tier) => tier === raw)\n}\n\nfunction parseOptionalBounded(raw: unknown): string | undefined {\n const value = boundString(raw)\n return value === \"\" ? undefined : value\n}\n\n/** Free-text detail keeps empty strings (round-trips through the store). */\nfunction parseDetailBounded(raw: unknown): string | undefined {\n return boundString(raw) ?? undefined\n}\n\nfunction parseApplyEvidence(raw: unknown): ApplyDecision[\"evidence\"] | undefined {\n if (!isRecord(raw)) return undefined\n const skippedRaw = raw[\"skipped\"]\n if (!Array.isArray(skippedRaw)) return undefined\n const skipped: SkippedCandidate[] = []\n for (const entry of skippedRaw.slice(0, 8)) {\n if (!isRecord(entry)) continue\n const ref = parseModelRef(entry[\"ref\"])\n const why = parseVocab(entry[\"why\"], SKIP_REASONS)\n if (ref === undefined || why === undefined) continue\n skipped.push({ ref, why })\n }\n const probeId = parseDetailBounded(raw[\"probeId\"])\n return { skipped, ...(probeId !== undefined ? { probeId } : {}) }\n}\n\nfunction parseApply(raw: Record<string, unknown>): ApplyDecision | undefined {\n const model = parseModelRef(raw[\"model\"])\n const reason = parseVocab(raw[\"reason\"], APPLY_REASONS)\n const evidence = parseApplyEvidence(raw[\"evidence\"])\n if (model === undefined || reason === undefined || evidence === undefined) {\n return undefined\n }\n const tier = parseTier(raw[\"tier\"])\n return {\n kind: \"apply\",\n model,\n ...(tier !== undefined ? { tier } : {}),\n reason,\n evidence,\n }\n}\n\nfunction parseDefer(raw: Record<string, unknown>): DeferDecision | undefined {\n const reason = parseVocab(raw[\"reason\"], SCHEDULER_DEFER_REASONS)\n if (reason === undefined) return undefined\n const detail = parseDetailBounded(raw[\"detail\"])\n return { kind: \"defer\", reason, ...(detail !== undefined ? { detail } : {}) }\n}\n\nfunction parsePark(raw: Record<string, unknown>): ParkDecision | undefined {\n const reason = parseVocab(raw[\"reason\"], PARK_REASONS)\n if (reason === undefined) return undefined\n const detail = parseDetailBounded(raw[\"detail\"])\n return { kind: \"park\", reason, ...(detail !== undefined ? { detail } : {}) }\n}\n\nfunction parseEscalate(raw: Record<string, unknown>): EscalateDecision | undefined {\n const target = parseModelRef(raw[\"target\"])\n const step = parseVocab(raw[\"step\"], ESCALATION_STEPS)\n const tier = parseTier(raw[\"tier\"])\n const budgetRemainingRaw = raw[\"budgetRemaining\"]\n if (\n target === undefined ||\n step === undefined ||\n tier === undefined ||\n !isFiniteNonNegative(budgetRemainingRaw)\n ) {\n return undefined\n }\n const evidenceRaw = raw[\"evidence\"]\n if (!Array.isArray(evidenceRaw)) return undefined\n const evidence: EscalationEvidence[] = []\n for (const entry of evidenceRaw.slice(0, 4)) {\n if (!isRecord(entry)) continue\n const kind = parseVocab(entry[\"kind\"], ESCALATION_EVIDENCE_KINDS)\n if (kind === undefined) continue\n const detail = parseDetailBounded(entry[\"detail\"])\n evidence.push({ kind, ...(detail !== undefined ? { detail } : {}) })\n }\n return {\n kind: \"escalate\",\n target,\n step,\n tier,\n evidence,\n budgetRemaining: budgetRemainingRaw,\n }\n}\n\n/** Max `observe-only` nesting accepted on read (the scheduler produces ≤ 1). */\nconst MAX_PARSE_DEPTH = 2\n\nfunction parseObserveOnly(\n raw: Record<string, unknown>,\n depth: number,\n): ObserveOnlyDecision | undefined {\n if (depth >= MAX_PARSE_DEPTH) return undefined\n const would = parseDecision(raw[\"would\"], depth + 1)\n return would === undefined ? undefined : { kind: \"observe-only\", would }\n}\n\nfunction parseDecision(raw: unknown, depth = 0): Decision | undefined {\n if (!isRecord(raw)) return undefined\n switch (raw[\"kind\"]) {\n case \"apply\":\n return parseApply(raw)\n case \"defer\":\n return parseDefer(raw)\n case \"park\":\n return parsePark(raw)\n case \"escalate\":\n return parseEscalate(raw)\n case \"observe-only\":\n return parseObserveOnly(raw, depth)\n default:\n return undefined\n }\n}\n\nfunction parseOutcome(raw: unknown): ReceiptOutcome | undefined {\n if (!isRecord(raw)) return undefined\n switch (raw[\"status\"]) {\n case \"succeeded\":\n return { status: \"succeeded\" }\n case \"failed\": {\n const category = parseVocab(raw[\"category\"], FAILURE_CATEGORIES)\n return category === undefined ? undefined : { status: \"failed\", category }\n }\n case \"interrupted\": {\n const reason = parseVocab(raw[\"reason\"], INTERRUPT_REASONS)\n return reason === undefined ? undefined : { status: \"interrupted\", reason }\n }\n default:\n return undefined\n }\n}\n\nfunction parseReceipt(raw: unknown): Receipt | undefined {\n if (!isRecord(raw)) return undefined\n const id = raw[\"id\"]\n const at = raw[\"at\"]\n const sessionID = parseOptionalBounded(raw[\"sessionID\"])\n const decision = parseDecision(raw[\"decision\"])\n if (\n !(isFiniteNonNegative(id) && Number.isInteger(id) && isFiniteNonNegative(at)) ||\n sessionID === undefined ||\n decision === undefined\n ) {\n return undefined\n }\n const unitID = parseOptionalBounded(raw[\"unitID\"])\n const tier = parseTier(raw[\"tier\"])\n // A present-but-invalid outcome invalidates the whole record: stripping\n // just the outcome would break first-outcome-wins across a restart (the\n // receipt would accept a later, different outcome as its first).\n let outcome: ReceiptOutcome | undefined\n if (raw[\"outcome\"] !== undefined) {\n outcome = parseOutcome(raw[\"outcome\"])\n if (outcome === undefined) return undefined\n }\n return {\n id,\n at,\n sessionID,\n ...(unitID !== undefined ? { unitID } : {}),\n ...(tier !== undefined ? { tier } : {}),\n decision,\n ...(outcome !== undefined ? { outcome } : {}),\n }\n}\n\n/**\n * Parse a persisted receipts payload. Accepts the versioned shape and a\n * versionless draft array; anything else yields no receipts.\n */\nexport function parseReceiptsPayload(raw: unknown): Receipt[] {\n let list: unknown\n if (isRecord(raw)) {\n const version = raw[\"version\"]\n if (version !== RECEIPTS_VERSION && version !== undefined) return []\n list = raw[\"receipts\"]\n } else if (Array.isArray(raw)) {\n list = raw\n }\n if (!Array.isArray(list)) return []\n const parsed = list\n .map(parseReceipt)\n .filter((receipt): receipt is Receipt => receipt !== undefined)\n return parsed.length > MAX_RECEIPTS ? parsed.slice(-MAX_RECEIPTS) : parsed\n}\n"]}
@@ -32,4 +32,3 @@ export declare class ReceiptStore {
32
32
  */
33
33
  adoptUnit(sessionID: string, unitID: string): Promise<number>;
34
34
  }
35
- //# sourceMappingURL=store.d.ts.map
@@ -15,11 +15,15 @@ export class ReceiptStore {
15
15
  storage;
16
16
  #receipts = [];
17
17
  #counter = 0;
18
+ #queue = Promise.resolve();
18
19
  constructor(storage) {
19
20
  this.storage = storage;
20
21
  }
21
22
  /** Rebuild from storage (restart behavior). A read failure yields an empty store. */
22
- async load() {
23
+ load() {
24
+ return this.#serialize(() => this.#load());
25
+ }
26
+ async #load() {
23
27
  let raw;
24
28
  try {
25
29
  raw = await this.storage.read();
@@ -36,7 +40,10 @@ export class ReceiptStore {
36
40
  snapshot() {
37
41
  return this.#receipts;
38
42
  }
39
- async record(input) {
43
+ record(input) {
44
+ return this.#serialize(() => this.#record(input));
45
+ }
46
+ async #record(input) {
40
47
  // A receipt with no session can never be attributed to anything, and the
41
48
  // read path drops empty identifiers — persisting one would make it vanish
42
49
  // across a restart. Throw instead; the wiring layer fail-open-catches.
@@ -69,7 +76,10 @@ export class ReceiptStore {
69
76
  * (first outcome wins). Returns how many receipts were updated; zero
70
77
  * updates do not touch storage.
71
78
  */
72
- async attachOutcome(ref, outcome) {
79
+ attachOutcome(ref, outcome) {
80
+ return this.#serialize(() => this.#attachOutcome(ref, outcome));
81
+ }
82
+ async #attachOutcome(ref, outcome) {
73
83
  let updated = 0;
74
84
  const next = this.#receipts.map((receipt) => {
75
85
  if (receipt.outcome !== undefined)
@@ -99,7 +109,10 @@ export class ReceiptStore {
99
109
  * unit ever opened), stamping all of them would attach this unit's outcome
100
110
  * to foreign admission decisions; the older receipts stay pending instead.
101
111
  */
102
- async adoptUnit(sessionID, unitID) {
112
+ adoptUnit(sessionID, unitID) {
113
+ return this.#serialize(() => this.#adoptUnit(sessionID, unitID));
114
+ }
115
+ async #adoptUnit(sessionID, unitID) {
103
116
  let target;
104
117
  this.#receipts.forEach((receipt, index) => {
105
118
  if (receipt.unitID !== undefined || receipt.outcome !== undefined)
@@ -116,6 +129,13 @@ export class ReceiptStore {
116
129
  this.#receipts = next;
117
130
  return 1;
118
131
  }
132
+ // Include reads in the chain so a reload cannot overwrite a newer commit.
133
+ // A failed write rejects its caller without blocking subsequent operations.
134
+ #serialize(operation) {
135
+ const run = this.#queue.then(operation);
136
+ this.#queue = run.catch(() => undefined);
137
+ return run;
138
+ }
119
139
  /** Writes the given next state; the caller commits memory only on success. */
120
140
  async #persist(receipts) {
121
141
  const payload = {