elanous 0.2.22 → 0.2.24

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 (803) hide show
  1. package/NOTICE +7 -0
  2. package/README.md +32 -22
  3. package/apps/pwa/out/404/index.html +1 -1
  4. package/apps/pwa/out/404.html +1 -1
  5. package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → Q-7iofoxOEv1WX18S35of}/_buildManifest.js +1 -1
  6. package/apps/pwa/out/_next/static/chunks/{119fc678.6f591cdb84ca5791.js → 0673cc54.8e2ef1c23e49e190.js} +1 -1
  7. package/apps/pwa/out/_next/static/chunks/{a9f2b54d-40c16bd0efdb04b8.js → 0a09e062-34f747a17d8d8c2e.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/{f8626309.a4e5d362b1d55e59.js → 0e3acd34.d42b2ef87fdf4234.js} +1 -1
  9. package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +77 -0
  10. package/apps/pwa/out/_next/static/chunks/{7175-350f4ce2873bc038.js → 1325-dc3f3c21eb181cb4.js} +1 -1
  11. package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +34 -0
  12. package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +24 -0
  13. package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/{6767.8e6c5f6e744fcd9f.js → 1505.5826671109111e75.js} +2 -2
  15. package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/{7327-2d69fb321ba73389.js → 1669-da843ed73aa301f5.js} +1 -1
  22. package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +36 -0
  24. package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +122 -0
  25. package/apps/pwa/out/_next/static/chunks/2528.0af5c0e1fad88df6.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +62 -0
  28. package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/272-0eed0fb0aab716b6.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/{7899.597af4a9996c907f.js → 2721.bc9a8f36bd85c07a.js} +1 -1
  31. package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +149 -0
  36. package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3961-aaae04ed1d32622f.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +309 -0
  40. package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/{d70879db.c66c56a95a91efc6.js → 4c5e95ce.83e9b16add6fcd8c.js} +1 -1
  49. package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/{6158.566c890adc06a459.js → 5313.1697309c532b9856.js} +2 -2
  53. package/apps/pwa/out/_next/static/chunks/{79b78388.663188133449d707.js → 53746282.1be36038d1abd949.js} +1 -1
  54. package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5578.ac963634373b28c6.js +286 -0
  57. package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5967-c0a80f8ffe5d4050.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/{1268.0840ff91e083fcbd.js → 5974.360f8441eb0ac1ec.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +74 -0
  65. package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/6571-926ddf024a6ad5df.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +64 -0
  70. package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/{9832.2ab2e818013574c7.js → 6702.ebbd165d5e4a4a14.js} +1 -1
  72. package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +32 -0
  74. package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +24 -0
  75. package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +93 -0
  79. package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/{6110.1297d4093fdfbb0d.js → 740.90b31555290236a9.js} +2 -2
  84. package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +148 -0
  85. package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +226 -0
  86. package/apps/pwa/out/_next/static/chunks/{9070.067c106528ec1ae6.js → 7518.49161e8f5814abdb.js} +1 -1
  87. package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +27 -0
  88. package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +115 -0
  91. package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7905.b230b9d06cb4ad5d.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/{8194.484f51e273d9abd2.js → 8264.00e434fbd02e9311.js} +16 -16
  98. package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +8 -0
  100. package/apps/pwa/out/_next/static/chunks/{088d8e8a.8069543d082bec12.js → 83cfc5c8.349535543c1548b6.js} +1 -1
  101. package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +23 -0
  102. package/apps/pwa/out/_next/static/chunks/{1948.5f35b39eef222a94.js → 8438.ee7f0df3b3f6fcb4.js} +1 -1
  103. package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{4588.ad3364cb7fb97ada.js → 8532.a86e99acf9b761cb.js} +2 -2
  106. package/apps/pwa/out/_next/static/chunks/8569.b853a8daa8f31d12.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/8925-2abfb48af477fb7f.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{88729267.9c6c000157c83f2f.js → 89849432.9eaa2f4c9c010965.js} +3 -3
  111. package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +90 -0
  112. package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +94 -0
  113. package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +41 -0
  115. package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +287 -0
  117. package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +79 -0
  118. package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/{3522-1de1319d028ac89c.js → 9502-32c5dc22e8f120f5.js} +3 -3
  121. package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +104 -0
  124. package/apps/pwa/out/_next/static/chunks/{7630.2b9a68659053ff4e.js → 9976.8f28864317639fe6.js} +16 -16
  125. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/approvals/page-3b9fc39362473ae7.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f2b62c19ca68fef8.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/board/page-d7602d489edf5f37.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/botlab/page-24282bf9f90031a5.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/bots/page-8b7c5ab6b5bc8d64.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/ceo/page-4eb84d454f8c3415.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/chat/page-b2e494bdad57fcb5.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/consult/{page-80ed511e02c81412.js → page-c0ab229673a8b0eb.js} +1 -1
  134. package/apps/pwa/out/_next/static/chunks/app/control/page-3e2b45f3c36dbac4.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/decisions/page-c22aa511b28743ad.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/design-check/page-26345242e4049f55.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/editor/page-bf88c0f558d8ef54.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/exec/page-52fec523e5b5d3ad.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/field/page-67723dfdcde92b31.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/inside/page-22725e2570f1126b.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/intake/page-1891335950d68b70.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/layout-3267af1ebdc73cf5.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/live/page-c314b75c11234998.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/live-run/page-9f9c85415f61782b.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/loops/page-c1d4276059085587.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/market/page-833aab587f26ad4c.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8526c17ae38e6a50.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/morning/page-f998637a8402115c.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/not-found-b7bb53828b17b335.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/observatory/page-1b1850de0257e46d.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6f23159fedb41f67.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1d809a87139dd024.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-da9e570234d481fd.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/outputs/page-b92caddb5c715f30.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/page-8ce3a38e210b810a.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/reflection/page-57ffeeb6019440fd.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-abbb417bf514630b.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/sessions/page-2c2b3f29cec1efa4.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-9369279f72fc7b51.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/settings/page-64861f14039499c3.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ddc4c93efd8ab94b.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/setup/page-901a1391b81053bc.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/share/page-68d9bbaac9841a58.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/showroom/page-b5c0c996f329371e.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/tasks/page-89881ccbcf728978.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/term/page-0e87a803b3d7165e.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/today/page-58d4e5cb30ef4871.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/trace/page-02ce4c3b5f39e4d2.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/vault/page-e620d1bb8eadcec2.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-acf868c64d77f950.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workflows/page-54fa605fa6dba457.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/workspace/page-bc79f0833533fa84.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-d5c4398eea03d8f3.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/b4e12462-5fab4a813a63dadd.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/{f6b7c9ba.64a895b8b2fedbdc.js → ce383d63.d2ede338788ed18e.js} +1 -1
  179. package/apps/pwa/out/_next/static/chunks/{framework-5c169757551134ed.js → framework-b2763b10dc6b3836.js} +1 -1
  180. package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +1 -0
  184. package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +1 -0
  185. package/apps/pwa/out/_next/static/css/72becfd42807b50d.css +1 -0
  186. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +1 -0
  187. package/apps/pwa/out/approvals/index.html +1 -1
  188. package/apps/pwa/out/approvals/index.txt +23 -23
  189. package/apps/pwa/out/autopilot/index.html +1 -1
  190. package/apps/pwa/out/autopilot/index.txt +23 -23
  191. package/apps/pwa/out/board/index.html +1 -1
  192. package/apps/pwa/out/board/index.txt +23 -23
  193. package/apps/pwa/out/botlab/index.html +1 -1
  194. package/apps/pwa/out/botlab/index.txt +22 -22
  195. package/apps/pwa/out/bots/index.html +1 -1
  196. package/apps/pwa/out/bots/index.txt +22 -22
  197. package/apps/pwa/out/ceo/index.html +1 -1
  198. package/apps/pwa/out/ceo/index.txt +23 -23
  199. package/apps/pwa/out/chat/index.html +1 -1
  200. package/apps/pwa/out/chat/index.txt +22 -22
  201. package/apps/pwa/out/consult/index.html +1 -1
  202. package/apps/pwa/out/consult/index.txt +23 -23
  203. package/apps/pwa/out/control/index.html +1 -1
  204. package/apps/pwa/out/control/index.txt +23 -23
  205. package/apps/pwa/out/decisions/index.html +1 -1
  206. package/apps/pwa/out/decisions/index.txt +22 -22
  207. package/apps/pwa/out/design-check/index.html +1 -1
  208. package/apps/pwa/out/design-check/index.txt +23 -23
  209. package/apps/pwa/out/editor/index.html +1 -1
  210. package/apps/pwa/out/editor/index.txt +24 -23
  211. package/apps/pwa/out/exec/index.html +1 -1
  212. package/apps/pwa/out/exec/index.txt +23 -23
  213. package/apps/pwa/out/field/index.html +1 -1
  214. package/apps/pwa/out/field/index.txt +23 -23
  215. package/apps/pwa/out/healthz +1 -1
  216. package/apps/pwa/out/index.html +1 -1
  217. package/apps/pwa/out/index.txt +22 -22
  218. package/apps/pwa/out/inside/index.html +1 -1
  219. package/apps/pwa/out/inside/index.txt +22 -22
  220. package/apps/pwa/out/intake/index.html +1 -1
  221. package/apps/pwa/out/intake/index.txt +23 -23
  222. package/apps/pwa/out/live/index.html +1 -1
  223. package/apps/pwa/out/live/index.txt +23 -23
  224. package/apps/pwa/out/live-run/index.html +1 -1
  225. package/apps/pwa/out/live-run/index.txt +24 -23
  226. package/apps/pwa/out/loops/index.html +1 -1
  227. package/apps/pwa/out/loops/index.txt +22 -22
  228. package/apps/pwa/out/market/index.html +1 -1
  229. package/apps/pwa/out/market/index.txt +22 -22
  230. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  231. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  232. package/apps/pwa/out/morning/index.html +1 -1
  233. package/apps/pwa/out/morning/index.txt +23 -23
  234. package/apps/pwa/out/observatory/index.html +1 -1
  235. package/apps/pwa/out/observatory/index.txt +23 -23
  236. package/apps/pwa/out/ops/checklist/index.html +1 -1
  237. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  238. package/apps/pwa/out/ops/release/index.html +1 -1
  239. package/apps/pwa/out/ops/release/index.txt +22 -22
  240. package/apps/pwa/out/ops/seats/index.html +1 -1
  241. package/apps/pwa/out/ops/seats/index.txt +22 -22
  242. package/apps/pwa/out/outputs/index.html +1 -1
  243. package/apps/pwa/out/outputs/index.txt +22 -22
  244. package/apps/pwa/out/reflection/index.html +1 -1
  245. package/apps/pwa/out/reflection/index.txt +23 -23
  246. package/apps/pwa/out/scheduler/index.html +1 -1
  247. package/apps/pwa/out/scheduler/index.txt +23 -23
  248. package/apps/pwa/out/sessions/index.html +1 -1
  249. package/apps/pwa/out/sessions/index.txt +22 -22
  250. package/apps/pwa/out/settings/devices/index.html +1 -1
  251. package/apps/pwa/out/settings/devices/index.txt +23 -23
  252. package/apps/pwa/out/settings/index.html +1 -1
  253. package/apps/pwa/out/settings/index.txt +23 -23
  254. package/apps/pwa/out/setup/done/index.html +1 -1
  255. package/apps/pwa/out/setup/done/index.txt +23 -23
  256. package/apps/pwa/out/setup/index.html +1 -1
  257. package/apps/pwa/out/setup/index.txt +23 -23
  258. package/apps/pwa/out/share/index.html +1 -1
  259. package/apps/pwa/out/share/index.txt +23 -23
  260. package/apps/pwa/out/showroom/index.html +1 -1
  261. package/apps/pwa/out/showroom/index.txt +22 -22
  262. package/apps/pwa/out/tasks/index.html +1 -1
  263. package/apps/pwa/out/tasks/index.txt +23 -23
  264. package/apps/pwa/out/term/index.html +1 -1
  265. package/apps/pwa/out/term/index.txt +23 -23
  266. package/apps/pwa/out/today/index.html +1 -1
  267. package/apps/pwa/out/today/index.txt +23 -23
  268. package/apps/pwa/out/trace/index.html +1 -1
  269. package/apps/pwa/out/trace/index.txt +23 -23
  270. package/apps/pwa/out/vault/index.html +1 -1
  271. package/apps/pwa/out/vault/index.txt +23 -23
  272. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  273. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  274. package/apps/pwa/out/workflows/index.html +1 -1
  275. package/apps/pwa/out/workflows/index.txt +23 -23
  276. package/apps/pwa/out/workspace/index.html +1 -1
  277. package/apps/pwa/out/workspace/index.txt +23 -23
  278. package/apps/pwa/out/worktrees/index.html +1 -1
  279. package/apps/pwa/out/worktrees/index.txt +23 -23
  280. package/catalog/models/anthropic/claude-haiku-5-5.yaml +32 -0
  281. package/catalog/models/anthropic/claude-opus-5-5.yaml +5 -0
  282. package/catalog/models/anthropic/claude-sonnet-5-5.yaml +31 -0
  283. package/catalog/models/anthropic/claude-sonnet-5.yaml +8 -2
  284. package/catalog/models/openai/gpt-6-astra.yaml +6 -0
  285. package/catalog/models/openai/gpt-6-luna.yaml +6 -0
  286. package/catalog/models/openai/gpt-6-sol.yaml +6 -0
  287. package/catalog/models/openrouter/deepseek-v4-pro-0813.yaml +39 -0
  288. package/catalog/models/openrouter/deepseek-v4.1-flash.yaml +38 -0
  289. package/catalog/models/openrouter/glm-5.3-flash.yaml +35 -0
  290. package/catalog/providers/openrouter.yaml +2 -0
  291. package/graphs/implement-loop.yaml +31 -0
  292. package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
  293. package/graphs/log-horizon/recipes.yaml +3 -0
  294. package/graphs/ops/harness-gc.yaml +17 -0
  295. package/graphs/ops/recipes.yaml +3 -0
  296. package/graphs/overlays/README.md +1 -1
  297. package/graphs/overlays/stop-heal-ladder.yaml +105 -0
  298. package/graphs/release/recipes.yaml +1 -1
  299. package/graphs/release/release-loop.yaml +6 -2
  300. package/graphs/release-rehearsal/recipes.yaml +12 -0
  301. package/graphs/release-rehearsal/release-rehearsal.yaml +17 -0
  302. package/package.json +4 -1
  303. package/scripts/add-api-key.sh +1 -1
  304. package/scripts/bench-report.ts +82 -3
  305. package/scripts/ci-typecheck-changed.ts +80 -14
  306. package/scripts/fleet/bedrock-pod-secret.ts +122 -0
  307. package/scripts/fleet/node-setup-linux.sh +97 -0
  308. package/scripts/fleet/node-setup.sh +11 -0
  309. package/scripts/fleet/zai-pod-secret.ts +86 -0
  310. package/scripts/hq/hq-fence-wrapper.sh +148 -0
  311. package/scripts/land-global-checks.ts +3 -0
  312. package/scripts/lib/typecheck-ratchet.ts +51 -0
  313. package/scripts/measure-log-diet-2.ts +213 -0
  314. package/scripts/measure-tsc-affected-roots.ts +289 -0
  315. package/scripts/openai-relay-server.ts +5 -1
  316. package/scripts/release-loop/docs-node.ts +258 -43
  317. package/scripts/release-loop/gate-executor.ts +28 -0
  318. package/scripts/release-loop/gate-method.ts +59 -0
  319. package/scripts/release-loop/gate-node.ts +335 -33
  320. package/scripts/release-loop/gate-wall.ts +208 -0
  321. package/scripts/release-loop/known-issues-node.ts +53 -8
  322. package/scripts/release-loop/publish-at.ts +14 -0
  323. package/scripts/release-loop/publish-node.ts +17 -2
  324. package/scripts/release-loop/resume-release.ts +40 -4
  325. package/scripts/release-loop/resume.ts +94 -0
  326. package/scripts/release-loop/shard-plan.ts +3 -11
  327. package/scripts/release-loop/tui-node-checks.ts +22 -0
  328. package/scripts/release-loop/unattended-release.ts +29 -7
  329. package/scripts/rhythm/daily.ts +51 -2
  330. package/scripts/rhythm/weekly.ts +3 -2
  331. package/scripts/tsc-baseline-cache.ts +147 -0
  332. package/scripts/tsc-main-safety-net.ts +189 -0
  333. package/scripts/usage-rollup.ts +64 -8
  334. package/src/acp/codex-plugins.ts +48 -6
  335. package/src/agent/monad-agent-turn.ts +67 -5
  336. package/src/agent/run-context.ts +20 -0
  337. package/src/agent/tool-profile.ts +28 -2
  338. package/src/agent-mission/acp-judge.ts +8 -2
  339. package/src/agent-mission/capabilities-cli.ts +16 -1
  340. package/src/agent-mission/driver.ts +19 -4
  341. package/src/agent-mission/pr-review-watch.ts +6 -2
  342. package/src/agent-mission/resource-ladder.ts +8 -3
  343. package/src/agent-mission/review-loop.ts +41 -7
  344. package/src/agent-substrate/acp-implementer.ts +139 -0
  345. package/src/agent-substrate/acp-reviewer.ts +17 -8
  346. package/src/agent-substrate/pr-reviewer.ts +191 -28
  347. package/src/agent-substrate/review-intent.ts +6 -4
  348. package/src/agent-substrate/self-review-cli.ts +155 -21
  349. package/src/agent-substrate/shard-boundary-intent.ts +92 -26
  350. package/src/ask-user-question/pending-questions.ts +8 -2
  351. package/src/autopilot/build/llm-conflict-merge.ts +216 -12
  352. package/src/autopilot/codebase-grounding.ts +44 -0
  353. package/src/autopilot/llm-control-brain.ts +13 -1
  354. package/src/autopilot/mission-codebase-gate.ts +8 -77
  355. package/src/autopilot/mission-critique.ts +18 -5
  356. package/src/autopilot/mission-feasibility-negotiate.ts +11 -10
  357. package/src/autopilot/mission-trace.ts +12 -1
  358. package/src/autopilot/pr-manager.ts +12 -3
  359. package/src/autopilot/system-lookback-run.ts +16 -10
  360. package/src/bench/bench.ts +183 -0
  361. package/src/boot/acp-server.ts +4 -7
  362. package/src/boot/acp-socket-path.ts +7 -0
  363. package/src/briefing/brief-items.ts +21 -13
  364. package/src/budget/fetchers/grok.ts +15 -5
  365. package/src/budget/llm-cost.ts +37 -5
  366. package/src/budget/types.ts +8 -2
  367. package/src/budget/unified-usage.ts +88 -6
  368. package/src/chat/index.ts +12 -3
  369. package/src/cli/agent-cli.ts +20 -0
  370. package/src/cli/bench-cli.ts +34 -0
  371. package/src/cli/brief-cli.ts +27 -21
  372. package/src/cli/cli-user-error.ts +9 -2
  373. package/src/cli/guardian-cli.ts +26 -1
  374. package/src/cli/image-cli.ts +101 -0
  375. package/src/cli/log-event-names.ts +7 -0
  376. package/src/cli/logs-cli.ts +1 -0
  377. package/src/cli/mcp-login.ts +111 -37
  378. package/src/cli/plugin-cli.ts +21 -1
  379. package/src/cli/pod-cli.ts +26 -0
  380. package/src/cli/pr-cli.ts +90 -5
  381. package/src/cli/pr-land-overlap-evidence.ts +279 -0
  382. package/src/cli/release-cli.ts +63 -12
  383. package/src/cli/rfc-status.ts +52 -2
  384. package/src/cli/self-update.ts +277 -10
  385. package/src/cli/skills-cli.ts +12 -3
  386. package/src/cli/tasks-cli.ts +241 -30
  387. package/src/cli/usage-cli.ts +91 -8
  388. package/src/context-bus/context-first.ts +51 -2
  389. package/src/context-bus/context-now-surfaces.ts +13 -2
  390. package/src/context-bus/long-term-memory.ts +3 -1
  391. package/src/context-bus/nightly-condense.ts +3 -2
  392. package/src/core-turn/run-goal-loop.ts +87 -2
  393. package/src/dashboard/ad-run-setup-bindings.ts +279 -0
  394. package/src/dashboard/chat-fold.ts +20 -0
  395. package/src/dashboard/first-screen-band.ts +151 -1
  396. package/src/dashboard/index.ts +45 -281
  397. package/src/dashboard/slash-runtime/dashboard-handlers.ts +5 -3
  398. package/src/dashboard/stale-install-check.ts +24 -2
  399. package/src/dashboard/turn-stream-formatter.ts +25 -0
  400. package/src/debug/log-diet.ts +190 -0
  401. package/src/debug/log.ts +70 -17
  402. package/src/display/coordinator.ts +25 -2
  403. package/src/domains/coo-admin-tool.ts +27 -0
  404. package/src/domains/cron-match.ts +1 -0
  405. package/src/domains/outbound-alert.ts +17 -6
  406. package/src/domains/release-tool.ts +158 -10
  407. package/src/domains/schedule-registry.ts +10 -7
  408. package/src/domains/schedule-runner.ts +1 -0
  409. package/src/elanous-config-dir.ts +2 -2
  410. package/src/elanous-daemon.ts +3 -3
  411. package/src/error-report/report.ts +21 -4
  412. package/src/execution-loop/launch-gate.ts +1 -1
  413. package/src/expression/i18n/messages.en.ts +5 -0
  414. package/src/expression/i18n/messages.ja.ts +5 -0
  415. package/src/expression/i18n/messages.ko.ts +5 -0
  416. package/src/expression/i18n/messages.zh.ts +5 -0
  417. package/src/expression/i18n/types.ts +8 -0
  418. package/src/github/pr-labels.ts +2 -0
  419. package/src/graph-runner/graph-cli.ts +42 -1
  420. package/src/graph-runner/runner.ts +218 -8
  421. package/src/grok/usage.ts +23 -2
  422. package/src/grounding/ref-index.ts +253 -0
  423. package/src/harness/dispatch-backpressure.ts +267 -0
  424. package/src/harness/harness-clean.ts +199 -78
  425. package/src/harness/harness-cli-command.ts +229 -35
  426. package/src/harness/harness-gc.ts +331 -0
  427. package/src/harness/harness-seams.ts +2 -20
  428. package/src/harness/harness-stop.ts +4 -2
  429. package/src/harness/harness-substrate-default.ts +214 -8
  430. package/src/harness/launch-registry.ts +6 -0
  431. package/src/harness/nested-elanous-policy.ts +4 -2
  432. package/src/harness/worktree-branch-prefix.ts +9 -0
  433. package/src/hq/fence-wrapper.ts +7 -0
  434. package/src/hq/fence.ts +187 -0
  435. package/src/hq/hq.ts +33 -2
  436. package/src/hq/lease.ts +13 -0
  437. package/src/hq/seats.ts +133 -21
  438. package/src/images/image-ledger.ts +179 -0
  439. package/src/index.ts +250 -69
  440. package/src/instance/child-scope.ts +32 -1
  441. package/src/instance/dev-project.ts +133 -0
  442. package/src/instance/resolve.ts +24 -0
  443. package/src/instance/spawn-elanous.ts +45 -0
  444. package/src/intake-plane/collect-github.ts +19 -1
  445. package/src/intake-plane/digest.ts +45 -20
  446. package/src/intake-plane/lens.ts +36 -8
  447. package/src/intake-plane/ref-prefetch.ts +110 -0
  448. package/src/intelligence-map/model-alias.ts +6 -0
  449. package/src/intelligence-map/model-catalog.ts +113 -0
  450. package/src/knowledge/kgs/pack.ts +5 -2
  451. package/src/knowledge/kgs/sqlite-store.ts +15 -0
  452. package/src/knowledge/tools/knowledge-query.ts +20 -2
  453. package/src/knowledge/write.ts +234 -2
  454. package/src/llm/bedrock-eventstream.ts +215 -0
  455. package/src/llm/bedrock-provider.ts +248 -0
  456. package/src/llm/bedrock.ts +491 -0
  457. package/src/llm/openrouter-byok-cost.ts +96 -0
  458. package/src/llm/openrouter-deepseek.ts +151 -0
  459. package/src/llm/openrouter-upstream-pins.config.ts +25 -0
  460. package/src/llm/provider-credentials.ts +3 -1
  461. package/src/llm/zai-coding-plan.ts +700 -0
  462. package/src/llm.ts +383 -41
  463. package/src/loops/budget.ts +150 -0
  464. package/src/loops/checker.ts +148 -9
  465. package/src/loops/orchestrator/resync-shadow.ts +34 -7
  466. package/src/loops/orchestrator/seat-share.ts +6 -49
  467. package/src/loops/orchestrator/traffic.ts +5 -81
  468. package/src/market/signed-index.ts +42 -0
  469. package/src/maturity/feature-maturity.ts +2 -2
  470. package/src/mcp/mcp-oauth.ts +136 -17
  471. package/src/model-tier/llm-tier-map.ts +52 -4
  472. package/src/models/prompts.ts +23 -1
  473. package/src/mss/logging/horizon-watch.ts +168 -0
  474. package/src/mss/logging/log-store.ts +262 -26
  475. package/src/native-tool-catalog.ts +1 -1
  476. package/src/nexus/api/consult-requests.ts +7 -10
  477. package/src/nexus/api/discord-trigger-bot.ts +6 -3
  478. package/src/nexus/api/error-reports.ts +30 -8
  479. package/src/nexus/api/http-server.ts +8 -0
  480. package/src/nexus/api/loop-resources.ts +42 -0
  481. package/src/nexus/api/missions.ts +73 -2
  482. package/src/nexus/api/ops-api.ts +18 -0
  483. package/src/nexus/api/outbound-report.ts +8 -3
  484. package/src/nexus/api/telegram-trigger-bot.ts +6 -3
  485. package/src/nexus/index.ts +17 -75
  486. package/src/nexus/outbound/format.ts +2 -0
  487. package/src/nexus/outbound/router.ts +198 -13
  488. package/src/nexus/tools-kind.ts +78 -0
  489. package/src/oauth/codex-account-rotation.ts +55 -20
  490. package/src/oauth/codex-account-store.ts +451 -23
  491. package/src/oauth/fallback-chain.ts +75 -15
  492. package/src/onboarding/first-run.ts +37 -18
  493. package/src/onboarding/web-first.ts +20 -2
  494. package/src/onboarding.ts +2 -1
  495. package/src/ops/machine-heartbeat.ts +185 -0
  496. package/src/ops/overview-cache.ts +175 -0
  497. package/src/ops/overview.ts +8 -0
  498. package/src/plugins/adapters/claude-package.ts +4 -12
  499. package/src/plugins/core/capability-policy.ts +141 -0
  500. package/src/plugins/core/host.ts +21 -8
  501. package/src/plugins/core/manifest.ts +19 -2
  502. package/src/plugins/core/trust-store.ts +15 -0
  503. package/src/plugins/core/types.ts +12 -0
  504. package/src/plugins/install/market-fetch.ts +68 -16
  505. package/src/plugins/install/plugin-install.ts +187 -16
  506. package/src/plugins/maker/plugin-maker.ts +25 -20
  507. package/src/plugins/maker/wizard-generate.ts +16 -2
  508. package/src/policy/llm-policy.ts +14 -1
  509. package/src/process/pid-liveness.ts +1 -1
  510. package/src/prompt-cache/openai.ts +13 -6
  511. package/src/prompt-cache/openrouter.ts +94 -0
  512. package/src/prompt-cache/types.ts +5 -0
  513. package/src/prompt-enhance/enhance.ts +69 -5
  514. package/src/prompt-library/family-prompt-coverage.ts +1 -0
  515. package/src/prompt-library/universal-preamble.ts +2 -2
  516. package/src/registry/discovery/openrouter-live-resolve.ts +122 -0
  517. package/src/registry/loader.ts +6 -1
  518. package/src/release-loop/checklist.ts +24 -9
  519. package/src/release-loop/feature-store.ts +3 -0
  520. package/src/release-loop/gate-shards.ts +48 -4
  521. package/src/release-loop/landed-to-green.ts +81 -0
  522. package/src/release-loop/light-rc.ts +11 -1
  523. package/src/release-loop/merged-pr-checklist.ts +10 -0
  524. package/src/release-loop/placement.ts +107 -23
  525. package/src/release-loop/rehearsal.ts +317 -0
  526. package/src/release-loop/release-schedule.ts +13 -1
  527. package/src/release-loop/rubric-types.ts +1 -0
  528. package/src/release-loop/rubric.ts +2 -2
  529. package/src/requirements/requirement-ledger.ts +536 -0
  530. package/src/retro/daily.ts +26 -12
  531. package/src/seat-loop/seat-loop.ts +66 -11
  532. package/src/seat-loop/traffic-signal.ts +44 -0
  533. package/src/self-dev/ask-launch-flow.ts +2 -2
  534. package/src/self-dev/dev-cli.ts +109 -11
  535. package/src/self-dev/dev-pipeline.ts +11 -8
  536. package/src/self-dev/draft-residue.ts +475 -0
  537. package/src/self-dev/draft-sweep.ts +254 -10
  538. package/src/self-dev/draft-triage-rules.ts +27 -1
  539. package/src/self-dev/graph-journey-route.ts +6 -0
  540. package/src/self-dev/launch-preflight-text.ts +549 -0
  541. package/src/self-dev/launch-preflight.ts +10 -545
  542. package/src/self-dev/orchestrate-cli.ts +82 -5
  543. package/src/self-dev/orchestrate-summary-line.ts +13 -0
  544. package/src/self-dev/orchestrate.ts +49 -141
  545. package/src/self-dev/review-provider-fallback.ts +115 -19
  546. package/src/self-dev/run-store.ts +1 -3
  547. package/src/self-dev/run-supervisor.ts +190 -36
  548. package/src/self-dev/run-types.ts +191 -0
  549. package/src/self-dev/shard-aggregate.ts +61 -13
  550. package/src/self-dev/shard-plan.ts +5 -1
  551. package/src/self-dev/shard-run.ts +23 -5
  552. package/src/self-dev/supervisor-verdict-edges.ts +3 -4
  553. package/src/self-implement/blocked-draft-policy.ts +3 -19
  554. package/src/self-implement/budget-gate.ts +53 -13
  555. package/src/self-implement/child-context-composition.ts +139 -0
  556. package/src/self-implement/child-llm-preference.ts +13 -5
  557. package/src/self-implement/claude-acp-implement.ts +67 -0
  558. package/src/self-implement/draft-on-stop-mode.ts +18 -0
  559. package/src/self-implement/flex-signals.ts +59 -0
  560. package/src/self-implement/follow-up-goals.ts +114 -38
  561. package/src/self-implement/frozen-merges.ts +8 -3
  562. package/src/self-implement/gate-baseline-reap.ts +157 -0
  563. package/src/self-implement/gate-baseline.ts +78 -16
  564. package/src/self-implement/gate-cli.ts +12 -2
  565. package/src/self-implement/gate-remote.ts +17 -6
  566. package/src/self-implement/goal-author-decompose.ts +10 -2
  567. package/src/self-implement/goal-author.ts +48 -13
  568. package/src/self-implement/goal-digest.ts +19 -0
  569. package/src/self-implement/graph-overlay-condition.ts +32 -0
  570. package/src/self-implement/graph-overlay-yaml.ts +41 -7
  571. package/src/self-implement/graph-templates.ts +33 -1
  572. package/src/self-implement/graph-yaml.ts +56 -0
  573. package/src/self-implement/headless-elanous-driver.ts +11 -9
  574. package/src/self-implement/heal-intake.ts +5 -1
  575. package/src/self-implement/host-regate.ts +120 -29
  576. package/src/self-implement/l8-merge-queue.ts +67 -5
  577. package/src/self-implement/merge-train.ts +131 -0
  578. package/src/self-implement/off-diff-evidence.ts +9 -0
  579. package/src/self-implement/orchestrator.ts +271 -25
  580. package/src/self-implement/review-finding-recurrence.ts +28 -0
  581. package/src/self-implement/rework-policy.ts +2 -1
  582. package/src/self-implement/round-summary-card.ts +63 -0
  583. package/src/self-implement/run-ledger.ts +4 -3
  584. package/src/self-implement/run-step-projection.ts +147 -0
  585. package/src/self-implement/run-stop.ts +1 -1
  586. package/src/self-implement/running-runs.ts +75 -5
  587. package/src/self-implement/seams.ts +83 -4
  588. package/src/self-implement/self-implement-cli.ts +12 -5
  589. package/src/self-implement/stop-autoheal.ts +69 -2
  590. package/src/self-implement/train-gate-remote.ts +158 -0
  591. package/src/session-runtime/index.ts +10 -1
  592. package/src/session-runtime/retry-api.ts +11 -1
  593. package/src/session-runtime/retry-policy.ts +2 -1
  594. package/src/skills/gift-install.ts +119 -0
  595. package/src/skills/runner.ts +59 -2
  596. package/src/skills/skill-feedback.ts +31 -1
  597. package/src/skills/skill-tier.ts +1 -0
  598. package/src/smart-wizard/capability-index.ts +231 -0
  599. package/src/smart-wizard/rung.ts +74 -0
  600. package/src/steward/launch.ts +22 -10
  601. package/src/steward/triage-budget.ts +62 -0
  602. package/src/steward/triage.ts +87 -24
  603. package/src/storage/file-lock.ts +8 -1
  604. package/src/task-agent/actions.ts +66 -5
  605. package/src/task-agent/card-evidence.ts +59 -13
  606. package/src/task-agent/completion-evidence.ts +5 -0
  607. package/src/task-agent/cover.ts +101 -3
  608. package/src/task-agent/judge.ts +20 -3
  609. package/src/task-agent/land-order-ledger.ts +95 -0
  610. package/src/task-agent/land-worktree.ts +201 -0
  611. package/src/task-agent/live-move-history.ts +219 -0
  612. package/src/task-agent/live-moves.ts +451 -34
  613. package/src/task-agent/parent-host.ts +117 -8
  614. package/src/task-agent/rejudge-on-head.ts +352 -0
  615. package/src/task-agent/review-prior-fix.ts +146 -0
  616. package/src/task-agent/review-result-capture.ts +218 -0
  617. package/src/task-agent/run-adopt.ts +136 -0
  618. package/src/task-agent/shadow.ts +154 -14
  619. package/src/task-agent/task-hand.ts +186 -14
  620. package/src/task-orchestrator/surfaces/pod-account-broker.ts +38 -5
  621. package/src/task-orchestrator/surfaces/pod-bedrock-child.ts +74 -0
  622. package/src/task-orchestrator/surfaces/pod-child-default.ts +50 -0
  623. package/src/task-orchestrator/surfaces/pod-child-providers.ts +42 -0
  624. package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
  625. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +94 -7
  626. package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
  627. package/src/task-orchestrator/surfaces/pod-lease.ts +110 -17
  628. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +32 -3
  629. package/src/task-orchestrator/surfaces/pod-pool.ts +86 -18
  630. package/src/task-orchestrator/surfaces/pod-zai-child.ts +101 -0
  631. package/src/task-orchestrator/surfaces/self-implement-pod.ts +463 -50
  632. package/src/task-orchestrator/surfaces/self-implement.ts +25 -3
  633. package/src/telegram-service.ts +5 -1
  634. package/src/telegram.ts +17 -4
  635. package/src/time/format.ts +13 -4
  636. package/src/tool-runtime/goal-author-runtime.ts +1 -0
  637. package/src/tool-runtime/self-cognition-catalog.ts +23 -0
  638. package/src/tool-runtime/self-cognition-runtimes.ts +2 -24
  639. package/src/typecheck-ratchet.ts +1 -0
  640. package/src/user-config.ts +180 -32
  641. package/src/ux-sim/slash-menu-frames.ts +168 -0
  642. package/src/version/packed-revision.json +1 -1
  643. package/src/web-terminal/preview-tap-registry.ts +5 -2
  644. package/src/workflow-runtime/triggers/registry.ts +59 -0
  645. package/src/workflow-runtime/triggers/scheduler.ts +1 -0
  646. package/src/workflow-runtime/triggers/webhook-source.ts +35 -5
  647. package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +0 -148
  648. package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +0 -32
  649. package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +0 -309
  650. package/apps/pwa/out/_next/static/chunks/1307-08b716476f1d50af.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +0 -122
  652. package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +0 -149
  653. package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +0 -79
  654. package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +0 -24
  656. package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +0 -27
  661. package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +0 -36
  670. package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +0 -286
  671. package/apps/pwa/out/_next/static/chunks/2489-d238d3e2eb5b2bf5.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +0 -94
  684. package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/3857-5985236d9307f676.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +0 -74
  692. package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +0 -34
  697. package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +0 -115
  699. package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +0 -77
  703. package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/5633-d6852385000738ef.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +0 -90
  708. package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/5977-5b9e8a45a5b0c823.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +0 -8
  713. package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +0 -64
  714. package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +0 -287
  716. package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +0 -226
  717. package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +0 -41
  725. package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +0 -24
  728. package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +0 -104
  738. package/apps/pwa/out/_next/static/chunks/8857-aa1cc4ac90af4d40.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +0 -93
  741. package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/9247-55bcfbb0e8057f59.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +0 -23
  745. package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +0 -62
  746. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/approvals/page-88459e0903da2803.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d85c43f46f58716b.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/board/page-4e645600579ae952.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/botlab/page-87edbfd19117823b.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/bots/page-7f0c2b7801ac6a54.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/ceo/page-bf1f030a9d1adffd.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/chat/page-cbaf66b1e1804adf.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/control/page-9f5610caaa06178c.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/decisions/page-ec8f3575e339de74.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/design-check/page-86d753e460f1a989.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/editor/page-4166a7d51cf0a57d.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/exec/page-2a19c5cd3b562580.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/field/page-b6a09cde2e07521a.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/inside/page-f7eae1518ca0c353.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/intake/page-456a8573ad811381.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/layout-8462d6a543cbb2d9.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/live/page-2974cdfb87c0f9c9.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f927ffa25f3c86d1.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/app/loops/page-abd86cd832aaa011.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/app/market/page-79daf68f6256adaa.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8c3f168fc3f91939.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/app/morning/page-786fb4504d0f2fa9.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/app/not-found-75209f14597dcb8f.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/app/observatory/page-bf30affe3a85af7e.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1187a44b7515434b.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-3d0910185a66ed54.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f401ee1dd5a26e25.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/app/outputs/page-5dfe7604fd842784.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/app/page-76cf838050a8d681.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7ec8e289b4c14df6.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-8c8ac17d52be2a79.js +0 -1
  779. package/apps/pwa/out/_next/static/chunks/app/sessions/page-d359ab048d63a9d9.js +0 -1
  780. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-b8b345c880bf78d1.js +0 -1
  781. package/apps/pwa/out/_next/static/chunks/app/settings/page-f151cc10ad026940.js +0 -1
  782. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-9875f103057da433.js +0 -1
  783. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +0 -1
  784. package/apps/pwa/out/_next/static/chunks/app/setup/page-9789328af9a9aa62.js +0 -1
  785. package/apps/pwa/out/_next/static/chunks/app/share/page-bf495a1e284f4e00.js +0 -1
  786. package/apps/pwa/out/_next/static/chunks/app/showroom/page-a263d94bca4be22a.js +0 -1
  787. package/apps/pwa/out/_next/static/chunks/app/tasks/page-3962eab8ec58d16e.js +0 -1
  788. package/apps/pwa/out/_next/static/chunks/app/term/page-9abcfac07e02a542.js +0 -1
  789. package/apps/pwa/out/_next/static/chunks/app/today/page-bee49f927c333abb.js +0 -1
  790. package/apps/pwa/out/_next/static/chunks/app/trace/page-bac2d56dcb02d955.js +0 -1
  791. package/apps/pwa/out/_next/static/chunks/app/vault/page-937cbcc13176295c.js +0 -1
  792. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d09495594f7f480d.js +0 -1
  793. package/apps/pwa/out/_next/static/chunks/app/workflows/page-69cb93d1a2e57e0e.js +0 -1
  794. package/apps/pwa/out/_next/static/chunks/app/workspace/page-72ec543928d67c3e.js +0 -1
  795. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-82906eeda0186a7b.js +0 -1
  796. package/apps/pwa/out/_next/static/chunks/f6231284-45726550aba08fca.js +0 -1
  797. package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +0 -1
  798. package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +0 -1
  799. package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +0 -1
  800. package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +0 -1
  801. package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +0 -1
  802. package/apps/pwa/out/_next/static/css/f2bd5257e6af88d8.css +0 -1
  803. /package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → Q-7iofoxOEv1WX18S35of}/_ssgManifest.js +0 -0
@@ -0,0 +1,231 @@
1
+ import { Database } from 'bun:sqlite';
2
+ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
3
+ import { join, resolve } from 'node:path';
4
+ import { elanousStateRoot } from '../autopilot/state-paths.js';
5
+ import { buildCapabilityMatrix } from '../agent-mission/capability-matrix.js';
6
+ import { createCapabilityReaders } from '../agent-mission/capability-readers.js';
7
+ import type { CapabilityEntry } from '../agent-mission/capability-types.js';
8
+ import { readCodexPluginsFromAppServer, type CodexPluginObservation } from '../acp/codex-plugins.js';
9
+ import { kgsDefaultDbPath } from '../knowledge/kgs/sqlite-store.js';
10
+ import { OFFICIAL_INDEX_KEYS } from '../market/official-keys.js';
11
+ import { verifyIndex, type MarketplaceIndex } from '../market/signed-index.js';
12
+ import { readClaudePackageLedger, type ClaudePackageLedger } from '../plugins/adapters/claude-package.js';
13
+ import { ELANOUS_MARKET_URL } from '../plugins/install/market-fetch.js';
14
+ import { buildSkillIndex, skillIndexProblems, type SkillIndexEntry } from '../skills/index.js';
15
+ import { defaultSkillDirs } from '../user-config.js';
16
+
17
+ export type CapabilitySource = 'skills' | 'plugins' | 'knowledge' | 'codex' | 'claude' | 'market';
18
+ export type CapabilityAuth = 'subscription' | 'free' | 'api-key' | 'paid' | 'unknown';
19
+ export interface IndexedCapability {
20
+ readonly id: string;
21
+ readonly kind: 'skill' | 'plugin' | 'knowledge' | 'connector';
22
+ readonly source: CapabilitySource;
23
+ readonly provenance: string;
24
+ readonly auth: CapabilityAuth;
25
+ readonly state: 'installed' | 'candidate' | 'ready' | 'unavailable' | 'unknown';
26
+ readonly capabilities: readonly string[];
27
+ }
28
+ export interface CapabilityIndex {
29
+ readonly sources: Record<CapabilitySource, 'ok' | 'unknown'>;
30
+ readonly entries: readonly IndexedCapability[];
31
+ }
32
+
33
+ export interface CapabilityIndexReaders {
34
+ skills?: () => readonly SkillIndexEntry[];
35
+ skillProblems?: () => readonly { name: string; dir: string }[];
36
+ plugins?: () => readonly { name: string; market: string }[];
37
+ knowledge?: () => readonly { name: string; provenance: string }[];
38
+ codex?: () => Promise<CodexPluginObservation>;
39
+ claude?: () => ClaudePackageLedger;
40
+ /** Production verifies fetched bytes; tests may inject a checked fixture. */
41
+ market?: () => Promise<MarketplaceIndex>;
42
+ matrix?: () => readonly CapabilityEntry[];
43
+ /** Default-path observations (used only when `skills` / `plugins` are not injected). */
44
+ localSkills?: () => LocalSkillsObservation;
45
+ localPlugins?: () => LocalPluginsObservation;
46
+ /** Already verified by the caller (never accepts unverified JSON). */
47
+ verifiedMarket?: MarketplaceIndex;
48
+ }
49
+
50
+ export interface LocalSkillsObservation {
51
+ readonly entries: readonly SkillIndexEntry[];
52
+ /** Roots that exist (or could not be proven absent) but could not be read. */
53
+ readonly unreadableRoots: readonly string[];
54
+ }
55
+
56
+ /** Per-root read: an unreadable root is reported, readable roots keep their candidates. */
57
+ export function readLocalSkills(dirs: readonly string[] = defaultSkillDirs()): LocalSkillsObservation {
58
+ // A missing root is optional; any other stat/read failure must remain unknown.
59
+ const readable: string[] = [];
60
+ const unreadableRoots: string[] = [];
61
+ for (const dir of dirs) {
62
+ try {
63
+ if (!statSync(dir).isDirectory()) throw new Error('skill root is not a directory');
64
+ readdirSync(dir);
65
+ readable.push(dir);
66
+ } catch (error) {
67
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') continue;
68
+ unreadableRoots.push(dir);
69
+ }
70
+ }
71
+ return { entries: readable.length ? buildSkillIndex(readable) : [], unreadableRoots };
72
+ }
73
+
74
+ /** Strict form: throws when any root is unreadable. */
75
+ export function listLocalSkills(dirs: readonly string[] = defaultSkillDirs()): readonly SkillIndexEntry[] {
76
+ const observed = readLocalSkills(dirs);
77
+ if (observed.unreadableRoots.length) throw new Error(`unreadable skill roots: ${observed.unreadableRoots.join(', ')}`);
78
+ return observed.entries;
79
+ }
80
+
81
+ export interface LocalPluginsObservation {
82
+ readonly plugins: readonly { name: string; market: string }[];
83
+ /** `absent` = ENOENT (no installs recorded); `unreadable` = exists but stat/read/parse failed. */
84
+ readonly ledger: 'ok' | 'absent' | 'unreadable';
85
+ /** Plugin directories that exist (or could not be proven absent) but could not be listed. */
86
+ readonly unreadableDirs: readonly string[];
87
+ }
88
+
89
+ /** ENOENT → absent; every other failure is a read failure, never "no candidates". */
90
+ function statKind(path: string, want: 'any' | 'file' = 'any'): 'present' | 'absent' | 'unreadable' {
91
+ try { const stat = statSync(path); return want === 'file' && !stat.isFile() ? 'absent' : 'present'; }
92
+ catch (error) { return (error as NodeJS.ErrnoException).code === 'ENOENT' ? 'absent' : 'unreadable'; }
93
+ }
94
+
95
+ export function readLocalPlugins(
96
+ ledgerPath: string = join(elanousStateRoot(), 'plugins', 'installed.json'),
97
+ localDirs: readonly string[] = [resolve(import.meta.dir, '../../plugins')],
98
+ ): LocalPluginsObservation {
99
+ const plugins: { name: string; market: string }[] = [];
100
+ let ledger: LocalPluginsObservation['ledger'] = 'absent';
101
+ const ledgerKind = statKind(ledgerPath);
102
+ if (ledgerKind === 'unreadable') ledger = 'unreadable';
103
+ else if (ledgerKind === 'present') {
104
+ try {
105
+ const rows: unknown = JSON.parse(readFileSync(ledgerPath, 'utf8'));
106
+ if (!Array.isArray(rows) || !rows.every(row => row && typeof row.name === 'string' && typeof row.market === 'string')) throw new Error('invalid installed plugin ledger');
107
+ plugins.push(...rows.map(row => ({ name: row.name as string, market: row.market as string })));
108
+ ledger = 'ok';
109
+ } catch { ledger = 'unreadable'; }
110
+ }
111
+ const unreadableDirs: string[] = [];
112
+ for (const dir of localDirs) {
113
+ const kind = statKind(dir);
114
+ if (kind === 'absent') continue;
115
+ const found: { name: string; market: string }[] = [];
116
+ try {
117
+ if (kind === 'unreadable') throw new Error('plugin directory unreadable');
118
+ for (const item of readdirSync(dir, { withFileTypes: true })) {
119
+ if (!item.isDirectory()) continue;
120
+ const path = join(dir, item.name);
121
+ const manifests = [statKind(join(path, 'plugin.ts'), 'file'), statKind(join(path, 'plugin.json'), 'file')];
122
+ if (manifests.includes('present')) found.push({ name: item.name, market: dir });
123
+ else if (manifests.includes('unreadable')) unreadableDirs.push(path);
124
+ }
125
+ plugins.push(...found);
126
+ } catch { unreadableDirs.push(dir); }
127
+ }
128
+ return { plugins, ledger, unreadableDirs };
129
+ }
130
+
131
+ function listLocalKnowledge(): readonly { name: string; provenance: string }[] {
132
+ const path = kgsDefaultDbPath();
133
+ if (!existsSync(path)) throw new Error('knowledge store unavailable');
134
+ const db = new Database(path, { readonly: true, create: false });
135
+ try {
136
+ return (db.query('SELECT slug, version FROM kgs_pack ORDER BY slug, version').all() as Array<{ slug: string; version: string }>)
137
+ .map(row => ({ name: `${row.slug}@${row.version}`, provenance: path }));
138
+ } finally { db.close(); }
139
+ }
140
+
141
+ async function readOfficialMarket(): Promise<MarketplaceIndex> {
142
+ const url = new URL('marketplace.json', ELANOUS_MARKET_URL);
143
+ const [raw, sig] = await Promise.all([fetch(url), fetch(new URL('index.sig', url))]);
144
+ if (!raw.ok || !sig.ok) throw new Error('official index unavailable');
145
+ const checked = verifyIndex({ marketplaceBytes: new Uint8Array(await raw.arrayBuffer()), signatureText: await sig.text(), trustedKeys: OFFICIAL_INDEX_KEYS });
146
+ if (!checked.ok || checked.index.name !== 'elanous') throw new Error('official index unverified');
147
+ return checked.index;
148
+ }
149
+
150
+ function marketAuth(entry: MarketplaceIndex['plugins'][number]): CapabilityAuth {
151
+ const policy = entry.policy?.authentication?.toLowerCase();
152
+ if (policy === 'api-key' || policy === 'api_key') return 'api-key';
153
+ if (policy === 'subscription') return 'subscription';
154
+ if (policy === 'paid') return 'paid';
155
+ if (policy === 'none' || policy === 'free') return 'free';
156
+ return 'unknown';
157
+ }
158
+
159
+ /** Read-only, per-source index. No source failure is interpreted as an empty inventory. */
160
+ export async function buildCapabilityIndex(readers: CapabilityIndexReaders = {}): Promise<CapabilityIndex> {
161
+ const sources: CapabilityIndex['sources'] = { skills: 'ok', plugins: 'ok', knowledge: 'ok', codex: 'ok', claude: 'ok', market: 'ok' };
162
+ const entries: IndexedCapability[] = [];
163
+ const attempt = async (source: CapabilitySource, read: () => Promise<void> | void): Promise<void> => {
164
+ const start = entries.length;
165
+ try { await read(); } catch { sources[source] = 'unknown'; entries.splice(start); }
166
+ };
167
+ await attempt('skills', () => {
168
+ const observed: LocalSkillsObservation = readers.skills
169
+ ? { entries: readers.skills(), unreadableRoots: [] }
170
+ : (readers.localSkills ?? readLocalSkills)();
171
+ for (const skill of observed.entries) entries.push({ id: skill.name, kind: 'skill', source: 'skills', provenance: skill.rootDir, auth: 'unknown', state: 'installed', capabilities: [skill.name] });
172
+ if (observed.unreadableRoots.length) {
173
+ sources.skills = 'unknown';
174
+ for (const dir of observed.unreadableRoots) entries.push({ id: dir, kind: 'skill', source: 'skills', provenance: dir, auth: 'unknown', state: 'unknown', capabilities: [] });
175
+ }
176
+ const problems = (readers.skillProblems ?? skillIndexProblems)();
177
+ if (problems.length) {
178
+ sources.skills = 'unknown';
179
+ for (const problem of problems) entries.push({ id: problem.name, kind: 'skill', source: 'skills', provenance: problem.dir, auth: 'unknown', state: 'unknown', capabilities: [problem.name] });
180
+ }
181
+ });
182
+ let installed: readonly { name: string; market: string }[] | undefined;
183
+ await attempt('plugins', () => {
184
+ if (readers.plugins) installed = readers.plugins();
185
+ else {
186
+ const observed = (readers.localPlugins ?? readLocalPlugins)();
187
+ installed = observed.plugins;
188
+ // Absent ledger keeps the earlier contract (unknown); unreadable ledger/dirs never read as "no installs".
189
+ if (observed.ledger !== 'ok' || observed.unreadableDirs.length) sources.plugins = 'unknown';
190
+ for (const dir of observed.unreadableDirs) entries.push({ id: dir, kind: 'plugin', source: 'plugins', provenance: dir, auth: 'unknown', state: 'unknown', capabilities: [] });
191
+ }
192
+ for (const plugin of installed) entries.push({ id: plugin.name, kind: 'plugin', source: 'plugins', provenance: plugin.market, auth: 'unknown', state: 'installed', capabilities: [plugin.name] });
193
+ });
194
+ await attempt('knowledge', () => {
195
+ for (const pack of (readers.knowledge ?? listLocalKnowledge)()) entries.push({ id: pack.name, kind: 'knowledge', source: 'knowledge', provenance: pack.provenance, auth: 'unknown', state: 'installed', capabilities: [pack.name] });
196
+ });
197
+ await attempt('codex', async () => {
198
+ const observation = await (readers.codex ?? readCodexPluginsFromAppServer)();
199
+ if (observation.status === 'unknown') { sources.codex = 'unknown'; return; }
200
+ for (const plugin of observation.plugins) entries.push({ id: plugin.name, kind: 'plugin', source: 'codex', provenance: plugin.marketplace, auth: 'unknown', state: plugin.enabled ? 'installed' : 'unavailable', capabilities: [plugin.name] });
201
+ });
202
+ await attempt('claude', () => {
203
+ const ledger = (readers.claude ?? readClaudePackageLedger)();
204
+ if (ledger.status !== 'ok') sources.claude = 'unknown';
205
+ for (const pkg of ledger.packages) entries.push({ id: pkg.plugin, kind: 'plugin', source: 'claude', provenance: `${pkg.marketplace}:${pkg.source}`, auth: 'unknown', state: 'installed', capabilities: [pkg.plugin] });
206
+ });
207
+ await attempt('market', async () => {
208
+ const index = readers.verifiedMarket ?? await (readers.market ?? readOfficialMarket)();
209
+ if (index.name !== 'elanous') throw new Error('not official market');
210
+ for (const plugin of index.plugins) {
211
+ entries.push({ id: plugin.name, kind: 'plugin', source: 'market', provenance: `${index.name}:${plugin.source.source}`, auth: marketAuth(plugin),
212
+ state: sources.plugins === 'unknown' ? 'unknown' : installed?.some(row => row.name === plugin.name && row.market === index.name) ? 'installed' : 'candidate',
213
+ capabilities: [plugin.name, ...plugin['ai.elanous'].capabilities, ...(plugin['ai.elanous'].vocab ?? [])] });
214
+ for (const connector of plugin['ai.elanous'].connectors) entries.push({ id: connector.id, kind: 'connector', source: 'market', provenance: `${index.name}:${plugin.name}`, auth: marketAuth(plugin), state: sources.plugins === 'unknown' ? 'unknown' : 'candidate', capabilities: [connector.id] });
215
+ }
216
+ for (const pack of index.knowledgePacks ?? []) {
217
+ if (pack.visibility !== 'public') continue;
218
+ entries.push({ id: pack.name, kind: 'knowledge', source: 'market', provenance: index.name, auth: 'unknown', state: 'candidate', capabilities: [pack.name] });
219
+ }
220
+ });
221
+ // Matrix is an additional service observation, not proof of plugin installation.
222
+ let matrix: readonly CapabilityEntry[] = [];
223
+ try { matrix = (readers.matrix ?? (() => buildCapabilityMatrix(createCapabilityReaders())))(); }
224
+ catch { /* Matrix is supplementary; plugin inventories keep their own observation status. */ }
225
+ for (const service of matrix) {
226
+ // Only backends that are index sources are attributed; grok has no source row here, so it is not relabelled.
227
+ if (!service.service || service.service === '*' || (service.backend !== 'codex' && service.backend !== 'claude')) continue;
228
+ entries.push({ id: service.service, kind: 'connector', source: service.backend, provenance: `${service.backend}:mcp`, auth: 'unknown', state: service.state, capabilities: [service.service] });
229
+ }
230
+ return { sources, entries };
231
+ }
@@ -0,0 +1,74 @@
1
+ // The condition extraction (including any LLM judgment) happens before this deterministic selector.
2
+ export type WizardRung = 'a' | 'b' | 'c' | 'd' | 'e';
3
+ export type GraphValueSignal = 'verification' | 'rework' | 'approval' | 'branching' | 'resume' | 'parallel' | 'resolution';
4
+
5
+ export type RungConditions = {
6
+ capabilityGaps: number;
7
+ graphSignals: readonly GraphValueSignal[];
8
+ recurring: boolean;
9
+ needsMemory: boolean;
10
+ unattended: boolean;
11
+ roles: number;
12
+ differentCadences: boolean;
13
+ differentPermissions: boolean;
14
+ handoffs: number;
15
+ };
16
+
17
+ export type RungDecision = {
18
+ rung: WizardRung;
19
+ reasons: string[];
20
+ rejectedHigher: string[];
21
+ };
22
+
23
+ const graphSignalNames: readonly GraphValueSignal[] = [
24
+ 'verification', 'rework', 'approval', 'branching', 'resume', 'parallel', 'resolution',
25
+ ];
26
+ const rungOrder: readonly WizardRung[] = ['a', 'b', 'c', 'd', 'e'];
27
+
28
+ /** Select the lowest rung sufficient for the supplied, already-established conditions. */
29
+ export function classifyRung(conditions: RungConditions): RungDecision {
30
+ const { capabilityGaps, graphSignals, recurring, needsMemory, unattended, roles,
31
+ differentCadences, differentPermissions, handoffs } = conditions;
32
+ for (const [name, value] of Object.entries({ capabilityGaps, roles, handoffs })) {
33
+ if (!Number.isSafeInteger(value) || value < 0) throw new RangeError(`${name} must be a non-negative safe integer`);
34
+ }
35
+ if (graphSignals.some(signal => !graphSignalNames.includes(signal))) {
36
+ throw new TypeError('graphSignals contains an unknown signal');
37
+ }
38
+
39
+ const distinctSignals = graphSignalNames.filter(signal => graphSignals.includes(signal));
40
+ const graphWorthwhile = distinctSignals.length >= 2;
41
+ const loopNeeded = recurring && (needsMemory || unattended);
42
+ const collectiveNeeded = roles >= 2 && (differentCadences || differentPermissions) && handoffs >= 1;
43
+ let rung: WizardRung = 'a';
44
+ const reasons: string[] = [];
45
+ if (capabilityGaps > 0) {
46
+ rung = 'b';
47
+ reasons.push(`b: capability gaps ${capabilityGaps} > 0`);
48
+ }
49
+ if (graphWorthwhile) {
50
+ rung = 'c';
51
+ reasons.push(`c: ${distinctSignals.length} graph value signals >= 2 (${distinctSignals.join(', ')})`);
52
+ }
53
+ if (loopNeeded) {
54
+ rung = 'd';
55
+ reasons.push(`d: recurring and ${[needsMemory && 'needs memory', unattended && 'unattended'].filter(Boolean).join(' / ')}`);
56
+ }
57
+ if (collectiveNeeded) {
58
+ rung = 'e';
59
+ reasons.push(`e: ${roles} roles >= 2, ${[differentCadences && 'different cadences', differentPermissions && 'different permissions'].filter(Boolean).join(' / ')}, handoffs ${handoffs} >= 1`);
60
+ }
61
+ if (reasons.length === 0) reasons.push('a: no higher-rung condition met; one skill call or short chain suffices');
62
+
63
+ const rejected = {
64
+ b: `b: capability gaps ${capabilityGaps} = 0`,
65
+ c: `c: ${distinctSignals.length} distinct graph value signals < 2`,
66
+ d: `d: ${!recurring ? 'not recurring' : 'neither memory nor unattended execution'}`,
67
+ e: `e: ${[
68
+ roles < 2 && `roles ${roles} < 2`,
69
+ !differentCadences && !differentPermissions && 'neither different cadences nor different permissions',
70
+ handoffs < 1 && `handoffs ${handoffs} < 1`,
71
+ ].filter(Boolean).join('; ')}`,
72
+ };
73
+ return { rung, reasons, rejectedHigher: rungOrder.slice(rungOrder.indexOf(rung) + 1).map(higher => rejected[higher as keyof typeof rejected]) };
74
+ }
@@ -1,6 +1,8 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import { closeSync, mkdirSync, openSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
3
- import { join, resolve } from 'node:path';
3
+ import { join } from 'node:path';
4
+ import { getElanousConfigDir } from '../elanous-config-dir.js';
5
+ import { installedCliArgv, resolveHqLaunchSeat } from '../hq/seats.js';
4
6
  import { debug } from '../debug/log.js';
5
7
  import { publishInsideEvent } from '../nexus/api/inside-events.js';
6
8
  import { redactSecrets } from '../task-cards/card-store.js';
@@ -42,9 +44,11 @@ export interface LaunchDeps {
42
44
  settings: StewardSettings;
43
45
  ledger: LaunchLedger;
44
46
  /** Injected command boundary; the production adapter runs only argv, never a shell. */
45
- command?: (args: string[]) => { exitCode: number; stdout: string; stderr?: string };
46
- spawn?: (args: string[], log: string) => { pid: number };
47
+ command?: (args: string[], seat?: string) => { exitCode: number; stdout: string; stderr?: string };
48
+ spawn?: (args: string[], log: string, seat?: string) => { pid: number };
47
49
  gate?: (goalId: string, budget: BudgetDecision | 'unknown') => PreLaunchGateDecision;
50
+ /** Production commands run from the registered OP view; tests can supply an isolated view. */
51
+ launchSeat?: () => string;
48
52
  }
49
53
 
50
54
  const RUN_ID = /\brun-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/i;
@@ -52,7 +56,7 @@ const DEFAULT_POOL = 'pool-node-b@node-b:8';
52
56
  // `harness budget --json` outcomes: proceed | next-provider | wait-reset | stop. next-provider still runs (the harness switches provider itself).
53
57
  const BUDGET_PROCEED: readonly string[] = ['proceed', 'next-provider'];
54
58
  const launchMode = (settings: StewardSettings): 'off' | 'shadow' | 'live' => launchModeOf(settings.mode ?? settings.launch ?? 'shadow');
55
- const cli = (args: string[]) => ['bun', 'bin/elanous.mjs', ...(process.env.NODE_ENV === 'test' ? ['--test'] : []), ...args];
59
+ const cli = (args: string[]) => installedCliArgv([...(process.env.NODE_ENV === 'test' ? ['--test'] : []), ...args]);
56
60
  const sourceOf = (issue: TriageIssue): string => /^출처: (telegram|pwa|tui|cli)$/m.exec(issue.body)?.[1] ?? `linear:${issue.identifier}`;
57
61
  const promptOf = (issue: TriageIssue): string => `${issue.title}\n${issue.body.slice(0, 1500)}`;
58
62
  const argvFor = (issue: TriageIssue, settings: StewardSettings): string[] =>
@@ -100,15 +104,20 @@ export function planLaunches(rows: ScheduledDecision[], issues: TriageIssue[], l
100
104
  return { launches, hitl };
101
105
  }
102
106
 
103
- function runCommand(args: string[]): { exitCode: number; stdout: string; stderr: string } {
104
- const result = Bun.spawnSync(args, { cwd: resolve(import.meta.dir, '../..'), stdout: 'pipe', stderr: 'pipe' });
107
+ function stewardLaunchSeat(): string {
108
+ return resolveHqLaunchSeat('OP', getElanousConfigDir());
109
+ }
110
+
111
+ /** Read commands run in the registered OP seat as well: the tree this module was loaded from may be a stale clone. */
112
+ function runCommand(args: string[], cwd = stewardLaunchSeat()): { exitCode: number; stdout: string; stderr: string } {
113
+ const result = Bun.spawnSync(args, { cwd, stdout: 'pipe', stderr: 'pipe' });
105
114
  return { exitCode: result.exitCode, stdout: result.stdout.toString(), stderr: result.stderr.toString() };
106
115
  }
107
116
 
108
- function spawnDetached(args: string[], log: string): { pid: number } {
117
+ function spawnDetached(args: string[], log: string, seat = stewardLaunchSeat()): { pid: number } {
109
118
  const fd = openSync(log, 'a');
110
119
  try {
111
- const child = Bun.spawn(args, { cwd: resolve(import.meta.dir, '../..'), stdout: fd, stderr: fd, stdin: 'ignore', detached: true });
120
+ const child = Bun.spawn(args, { cwd: seat, stdout: fd, stderr: fd, stdin: 'ignore', detached: true });
112
121
  child.unref();
113
122
  return { pid: child.pid };
114
123
  } finally { closeSync(fd); }
@@ -149,9 +158,12 @@ export function launch(item: LaunchItem, deps: LaunchDeps): LaunchEntry {
149
158
  // L6: a launch must remain on the isolated Pod pool, never fall back to the host or another substrate.
150
159
  if (!/^[a-zA-Z0-9_-]+(?:@[a-zA-Z0-9._-]+(?::[1-9][0-9]*)?)?$/.test(settings.podPool ?? DEFAULT_POOL))
151
160
  return blocked('blocked-location', 'invalid steward pod pool');
161
+ let seat: string;
162
+ try { seat = (deps.launchSeat ?? stewardLaunchSeat)(); }
163
+ catch (error) { return blocked('blocked-location', `steward OP seat unavailable: ${String(error)}`); }
152
164
  let budget: BudgetDecision | 'unknown' = 'unknown';
153
165
  try {
154
- const result = command(cli(['harness', 'budget', '--json']));
166
+ const result = command(cli(['harness', 'budget', '--json']), seat);
155
167
  const decision = result.exitCode === 0 ? lastJson(result.stdout) : {};
156
168
  if (!BUDGET_PROCEED.includes(String(decision.outcome)))
157
169
  return blocked('skipped-budget', result.exitCode === 0 ? JSON.stringify(decision.reasons ?? ['budget unavailable']) : result.stderr ?? 'budget unavailable');
@@ -171,7 +183,7 @@ export function launch(item: LaunchItem, deps: LaunchDeps): LaunchEntry {
171
183
  ledger.launches[key] = entry;
172
184
  saveLaunchLedger(root, ledger);
173
185
  try {
174
- entry.pid = (deps.spawn ?? spawnDetached)(argvFor(item.issue, settings), entry.log).pid;
186
+ entry.pid = (deps.spawn ?? spawnDetached)(argvFor(item.issue, settings), entry.log, seat).pid;
175
187
  } catch (error) {
176
188
  entry.status = 'failed';
177
189
  entry.reason = redactSecrets(String(error));
@@ -1,6 +1,7 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import { debug } from '../debug/log.js';
3
3
  import type { TriageDecision, TriageIssue } from './triage.js';
4
+ import { InvalidWorkingBackwardsDraft } from './working-backwards.js';
4
5
 
5
6
  export interface HashedTriageDecision extends TriageDecision {
6
7
  inputHash: string;
@@ -125,3 +126,64 @@ export async function triageWithinBudget({ issues, previous, judge, tracks, conc
125
126
  debug.log('steward.triage', 'budget', stats);
126
127
  return { decisions, stats };
127
128
  }
129
+
130
+ export interface CarriedDraft<T> {
131
+ wish: T;
132
+ /** `deadline` = never started before the stage deadline; `timeout` = per-item or stage deadline hit mid-draft. */
133
+ reason: 'timeout' | 'deadline' | 'error';
134
+ }
135
+
136
+ type DraftOutcome<T> = { kind: 'drafted' } | { kind: 'invalid' } | { kind: 'carried'; reason: CarriedDraft<T>['reason'] };
137
+
138
+ export async function draftWithinBudget<T>({ wishes, draft, concurrency = 4, perItemMs = 120_000, deadlineMs = 240_000, now = Date.now }: {
139
+ wishes: T[];
140
+ /** `expired` rejects once this item's own deadline passes; drafts should race their slow calls against it. */
141
+ draft: (wish: T, expired: Promise<never>) => Promise<void>;
142
+ concurrency?: number;
143
+ perItemMs?: number;
144
+ deadlineMs?: number;
145
+ now?: () => number;
146
+ }): Promise<{ drafted: T[]; carried: Array<CarriedDraft<T>>; invalid: T[]; stats: { drafted: number; carried: number; invalid: number } }> {
147
+ const end = now() + deadlineMs;
148
+ const slots = Number.isFinite(concurrency) ? Math.max(1, Math.floor(concurrency)) : 4;
149
+ const outcomes: Array<DraftOutcome<T> | undefined> = new Array(wishes.length);
150
+ let stageTimer: ReturnType<typeof setTimeout> | undefined;
151
+ const stageExpired = new Promise<void>(resolve => { stageTimer = setTimeout(resolve, Math.max(0, end - now())); });
152
+ const timedOut = Symbol('draft-timeout');
153
+ let cursor = 0;
154
+ const worker = async (): Promise<void> => {
155
+ while (cursor < wishes.length) {
156
+ const remaining = end - now();
157
+ if (remaining <= 0) return;
158
+ const index = cursor++;
159
+ let itemTimer: ReturnType<typeof setTimeout> | undefined;
160
+ const expired = new Promise<never>((_, reject) => { itemTimer = setTimeout(() => reject(timedOut), Math.min(perItemMs, remaining)); });
161
+ // The draft may finish without ever racing this promise — never leave its rejection unhandled.
162
+ expired.catch(() => undefined);
163
+ const work = Promise.resolve().then(() => draft(wishes[index]!, expired));
164
+ const settled = work.then(() => undefined, () => undefined);
165
+ try {
166
+ await Promise.race([work, expired]);
167
+ outcomes[index] = { kind: 'drafted' };
168
+ } catch (error) {
169
+ outcomes[index] = error instanceof InvalidWorkingBackwardsDraft ? { kind: 'invalid' }
170
+ : { kind: 'carried', reason: error === timedOut ? 'timeout' : 'error' };
171
+ // A timed-out draft keeps its concurrency slot until the underlying call settles or the stage ends.
172
+ await Promise.race([settled, stageExpired]);
173
+ } finally { if (itemTimer) clearTimeout(itemTimer); }
174
+ }
175
+ };
176
+ try {
177
+ await Promise.all(Array.from({ length: Math.min(slots, wishes.length) }, () => worker()));
178
+ } finally { if (stageTimer) clearTimeout(stageTimer); }
179
+ const result = { drafted: [] as T[], carried: [] as Array<CarriedDraft<T>>, invalid: [] as T[] };
180
+ for (const [index, wish] of wishes.entries()) {
181
+ const outcome = outcomes[index];
182
+ if (outcome?.kind === 'drafted') result.drafted.push(wish);
183
+ else if (outcome?.kind === 'invalid') result.invalid.push(wish);
184
+ else result.carried.push({ wish, reason: outcome?.kind === 'carried' ? outcome.reason : 'deadline' });
185
+ }
186
+ const stats = { drafted: result.drafted.length, carried: result.carried.length, invalid: result.invalid.length };
187
+ debug.log('steward.triage', 'draft-budget', stats);
188
+ return { ...result, stats };
189
+ }
@@ -8,6 +8,10 @@ import { getUserConfig } from '../user-config.js';
8
8
  import { emitDecision } from '../live/detail-switch.js';
9
9
  import { debug, redactSecretText } from '../debug/log.js';
10
10
  import { loopEvent } from '../loops/observe.js';
11
+ import { checkLoops, daemonScheduleEntries, entriesFromRegistry, extendHealthyLauncher, launcherEvidence, notifyOwners, scheduleFindings, versionEvidence, type CheckEntry } from '../loops/checker.js';
12
+ import { listSchedules, schedulesDbPath, type ScheduleRow } from '../domains/schedule-registry.js';
13
+ import { Database } from 'bun:sqlite';
14
+ import { defaultLoopRoot, listAllLoops, listLoops } from '../loops/registry.js';
11
15
  import { effectiveInstanceRoot } from '../instance/resolve.js';
12
16
  import { redactSecrets } from '../task-cards/card-store.js';
13
17
  import { directiveHash } from './directive.js';
@@ -17,7 +21,7 @@ import { planLaunches, launch, collectOutcomes, raiseHitl, readLaunchLedger, sav
17
21
  import { listFabricExecutionCandidates } from '../self-dev/fabric-plan-core.js';
18
22
  import { InvalidWorkingBackwardsDraft, recordWorkingBackwardsOnCards } from './working-backwards.js';
19
23
  import { CardStore } from '../task-cards/card-store.js';
20
- import { triageWithinBudget } from './triage-budget.js';
24
+ import { draftWithinBudget, triageWithinBudget } from './triage-budget.js';
21
25
  import { askSteward, classifyIssue, installedCapabilities, planIssues, ruleJudgment, unsafeReason, type ClassifiedIssue, type StewardAsk } from './triage-plan.js';
22
26
  import { failureAlertText, markStageStart, markStageEnd, readFailureStreak, shouldAlert, writeFailureStreak, type FailureStreak, type StewardStage } from './failure-streak.js';
23
27
 
@@ -59,13 +63,20 @@ export interface StewardDeps {
59
63
  ask?: StewardAsk;
60
64
  /** Maximum time for each working-backwards wish draft in schedule (milliseconds). */
61
65
  draftItemMs?: number;
66
+ /** Maximum time for the whole wish-drafting phase in schedule (milliseconds); wishes still undrafted are carried. */
67
+ draftDeadlineMs?: number;
62
68
  launchSettings?: Pick<StewardSettings, 'mode' | 'launch' | 'maxParallel' | 'podPool'>;
63
69
  launchCommand?: LaunchDeps['command'];
64
70
  spawnLaunch?: LaunchDeps['spawn'];
71
+ /** Isolated OP view for tests; production resolves the registered HQ seat (launch.ts stewardLaunchSeat). */
72
+ launchSeat?: LaunchDeps['launchSeat'];
65
73
  launchGate?: LaunchDeps['gate'];
66
74
  outcomeNotify?: Pick<OutcomeNotifyDeps, 'document' | 'message' | 'worktreeCommand' | 'loadOrigin' | 'loadOrigins'>;
67
75
  /** Internal command boundary: the current sync has already claimed this pid. */
68
76
  stageOwnedByCommand?: boolean;
77
+ /** Isolated scheduler inventory for this tick; production reads the unified registry. */
78
+ scheduleInventory?: () => CheckEntry[];
79
+ daemonSchedules?: () => ScheduleRow[];
69
80
  }
70
81
 
71
82
  /** rescue launches/harvests like live (HQ-SEAT). */
@@ -312,6 +323,61 @@ function logStageFailure(root: string, stage: StewardStage, reason: string): voi
312
323
  if (runId) try { rmSync(tickDecisionPath(root, runId), { force: true }); } catch { /* Observation must not change the failure. */ }
313
324
  logTickDecision(root, 'failed', `${stage}: ${reason}`);
314
325
  }
326
+ const SCHEDULE_CHECK_MS = 15 * 60_000;
327
+
328
+ /** Called by runStewardStage(sync) under its stage slot, never from the checker CLI. */
329
+ async function checkStewardSchedules(root: string, settings: StewardSettings, deps: StewardDeps): Promise<void> {
330
+ const now = (deps.now ?? (() => new Date()))();
331
+ const marker = join(root, 'steward', 'schedule-check.json');
332
+ let previous: { at?: string } = {};
333
+ try { previous = JSON.parse(readFileSync(marker, 'utf8')) as typeof previous; }
334
+ catch (error) { if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error; }
335
+ const elapsed = now.getTime() - Date.parse(previous.at ?? '');
336
+ if (Number.isFinite(elapsed) && elapsed >= 0 && elapsed < SCHEDULE_CHECK_MS) return;
337
+ const inventory = deps.scheduleInventory ?? (() => {
338
+ const repo = deps.root ? process.cwd() : defaultLoopRoot();
339
+ const registryOptions = { now, root: repo, stateRoot: root,
340
+ ...(deps.root ? { schedules: [] } : {}) };
341
+ const { entries } = entriesFromRegistry({ now, listAllLoops: () => listAllLoops(registryOptions) });
342
+ const graphs = listLoops(registryOptions);
343
+ const byId = new Map(graphs.map(graph => [graph.id, graph.file]));
344
+ return versionEvidence(launcherEvidence(entries.map(entry => byId.has(entry.id)
345
+ ? { ...entry, file: byId.get(entry.id) } : entry), root), repo, root);
346
+ });
347
+ const daemonRows = deps.daemonSchedules ?? (() => {
348
+ const path = deps.root ? join(root, 'schedules.db') : schedulesDbPath();
349
+ if (!existsSync(path)) return [];
350
+ try {
351
+ const db = new Database(path, { readonly: true });
352
+ try { return listSchedules(db); } finally { db.close(); }
353
+ } catch (error) {
354
+ debug.log('steward.schedule-check', 'daemon-inventory-unavailable', { reason: redactSecretText(String(error)) });
355
+ return [];
356
+ }
357
+ });
358
+ const entries = inventory();
359
+ const seen = new Set(entries.map(entry => entry.id));
360
+ const checked = checkLoops([...entries, ...daemonScheduleEntries(daemonRows(), now).filter(row => !seen.has(row.id))], now);
361
+ const findings = scheduleFindings(checked, now);
362
+ if (settings.mode === 'live') {
363
+ let recovered = 0;
364
+ const unresolved = findings.filter(finding => {
365
+ try {
366
+ if (extendHealthyLauncher(root, finding, now)) { recovered++; return false; }
367
+ } catch (error) {
368
+ debug.log('steward.schedule-check', 'recovery-failed', { id: finding.id, reason: redactSecretText(String(error)) });
369
+ }
370
+ return true;
371
+ });
372
+ const remainingChecks = checked.filter(row => unresolved.some(finding => finding.id === row.id && finding.kind === row.state));
373
+ const ownerRequests = notifyOwners(remainingChecks, { root, now }, unresolved);
374
+ const opEscalations = notifyOwners(remainingChecks, { root, now }, unresolved, true);
375
+ debug.log('steward.schedule-check', 'routing', { ownerRequests, opEscalations, recovered });
376
+ }
377
+ debug.log('steward.schedule-check', 'checked', { count: checked.length, findings: findings.length, mode: settings.mode });
378
+ writeFileSync(marker, JSON.stringify({ at: now.toISOString() }));
379
+ }
380
+
315
381
  function readState(path: string): { issues: Record<string, string>; digestDay?: string } {
316
382
  try { return JSON.parse(readFileSync(path, 'utf8')) as ReturnType<typeof readState>; }
317
383
  catch (error) { if ((error as NodeJS.ErrnoException).code === 'ENOENT') return { issues: {} }; throw error; }
@@ -341,6 +407,11 @@ export async function runStewardStage(stage: 'sync' | 'triage' | 'schedule' | 'r
341
407
  const runId = (graphRunId() ?? process.env.ELANOUS_RUN_ID?.trim()) || `steward-stage-${randomUUID()}`;
342
408
  let outcome: 'ok' | 'fail' = 'fail';
343
409
  try {
410
+ if (stage === 'sync') {
411
+ // The schedule check is an add-on to sync: its failure is observed, never allowed to stop the Linear sync.
412
+ try { await checkStewardSchedules(root, settings, deps); }
413
+ catch (error) { debug.log('steward.schedule-check', 'failed', { reason: redactSecretText(String(error)) }, { level: 'warn' }); }
414
+ }
344
415
  const key = await (deps.getSecret ?? getSecretAsync)('connector.linear.apiKey');
345
416
  if (!key) throw new Error('connector.linear.apiKey missing');
346
417
  if (stage === 'sync') {
@@ -418,27 +489,19 @@ export async function runStewardStage(stage: 'sync' | 'triage' | 'schedule' | 'r
418
489
  const carried = new Set<string>();
419
490
  if (store) try {
420
491
  recordTriageOnCards(wishes, issues, { root, store, now: deps.now });
421
- for (const wish of wishes) {
422
- const timedOut = Symbol('draft-timeout');
423
- let timer: ReturnType<typeof setTimeout> | undefined;
424
- const timeout = new Promise<never>((_, reject) => {
425
- timer = setTimeout(() => reject(timedOut), deps.draftItemMs ?? 120_000);
426
- });
427
- // The draft may finish without ever racing this promise (no ask needed) — never leave its rejection unhandled.
428
- timeout.catch(() => undefined);
429
- try {
430
- // Bound the ask itself so a late answer cannot write to a store closed after this tick.
431
- const ask: StewardAsk = (prompt, role) => Promise.race([(deps.ask ?? askSteward)(prompt, role), timeout]);
432
- await recordWorkingBackwardsOnCards([wish], issues, store, ask);
433
- } catch (error) {
434
- if (error instanceof InvalidWorkingBackwardsDraft) {
435
- invalid.add(wish.issue);
436
- debug.log('steward.stage', 'draft-invalid', { issue: wish.issue });
437
- } else {
438
- carried.add(wish.issue);
439
- debug.log('steward.schedule', 'draft-carried', { issue: wish.issue, reason: error === timedOut ? 'timeout' : 'error' });
440
- }
441
- } finally { if (timer) clearTimeout(timer); }
492
+ const outcome = await draftWithinBudget({
493
+ wishes, perItemMs: deps.draftItemMs ?? 120_000, deadlineMs: deps.draftDeadlineMs ?? 240_000,
494
+ // Bound the ask itself so a late answer cannot write to a store closed after this tick.
495
+ draft: (wish, expired) => recordWorkingBackwardsOnCards([wish], issues, store,
496
+ (prompt, role) => Promise.race([(deps.ask ?? askSteward)(prompt, role), expired])),
497
+ });
498
+ for (const wish of outcome.invalid) {
499
+ invalid.add(wish.issue);
500
+ debug.log('steward.stage', 'draft-invalid', { issue: wish.issue });
501
+ }
502
+ for (const { wish, reason } of outcome.carried) {
503
+ carried.add(wish.issue);
504
+ debug.log('steward.schedule', 'draft-carried', { issue: wish.issue, reason });
442
505
  }
443
506
  } finally { if (!deps.cardStore) store.close(); }
444
507
  if (invalid.size || carried.size) rows = rows.map(row => invalid.has(row.issue)
@@ -450,7 +513,7 @@ export async function runStewardStage(stage: 'sync' | 'triage' | 'schedule' | 'r
450
513
  }); } catch { /* logging must not change the schedule */ }
451
514
  writeFileSync(schedule, JSON.stringify(rows));
452
515
  const ledger = readLaunchLedger(root);
453
- const launchDeps: LaunchDeps = { root, settings, ledger, command: deps.launchCommand, spawn: deps.spawnLaunch, gate: deps.launchGate };
516
+ const launchDeps: LaunchDeps = { root, settings, ledger, command: deps.launchCommand, spawn: deps.spawnLaunch, gate: deps.launchGate, launchSeat: deps.launchSeat };
454
517
  const cardDeps = { root, store: deps.cardStore, now: deps.now };
455
518
  collectOutcomes(ledger, launchDeps);
456
519
  const plan = planLaunches(rows, issues, ledger, settings);
@@ -510,7 +573,7 @@ export async function runStewardStage(stage: 'sync' | 'triage' | 'schedule' | 'r
510
573
  writeFileSync(path, JSON.stringify(state));
511
574
  }
512
575
  const ledger = readLaunchLedger(root);
513
- const outcomes = collectOutcomes(ledger, { root, settings, ledger, command: deps.launchCommand, spawn: deps.spawnLaunch });
576
+ const outcomes = collectOutcomes(ledger, { root, settings, ledger, command: deps.launchCommand, spawn: deps.spawnLaunch, launchSeat: deps.launchSeat });
514
577
  for (const outcome of outcomes) {
515
578
  const issue = issues.find(item => item.identifier === outcome.issue) ??
516
579
  { identifier: outcome.issue, title: outcome.title, ref: '', body: '' };