elanous 0.2.21 → 0.2.23

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 (780) 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/chunks/{119fc678.6f591cdb84ca5791.js → 0673cc54.8e2ef1c23e49e190.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/{a9f2b54d-40c16bd0efdb04b8.js → 0a09e062-34f747a17d8d8c2e.js} +1 -1
  7. package/apps/pwa/out/_next/static/chunks/{f8626309.a4e5d362b1d55e59.js → 0e3acd34.d42b2ef87fdf4234.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +77 -0
  9. package/apps/pwa/out/_next/static/chunks/{7175-350f4ce2873bc038.js → 1325-dc3f3c21eb181cb4.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +34 -0
  11. package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +24 -0
  12. package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/{6767.8e6c5f6e744fcd9f.js → 1505.5826671109111e75.js} +2 -2
  14. package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/{7327-2d69fb321ba73389.js → 1669-da843ed73aa301f5.js} +1 -1
  21. package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +36 -0
  23. package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +122 -0
  24. package/apps/pwa/out/_next/static/chunks/2528.0af5c0e1fad88df6.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +62 -0
  27. package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/272-b23d2e92161d11fd.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{7899.597af4a9996c907f.js → 2721.bc9a8f36bd85c07a.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +149 -0
  35. package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3961-fbef064c213b2b18.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +309 -0
  39. package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{d70879db.c66c56a95a91efc6.js → 4c5e95ce.83e9b16add6fcd8c.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/{6158.566c890adc06a459.js → 5313.1697309c532b9856.js} +2 -2
  52. package/apps/pwa/out/_next/static/chunks/{79b78388.663188133449d707.js → 53746282.1be36038d1abd949.js} +1 -1
  53. package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5578.ac963634373b28c6.js +286 -0
  56. package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5967-c0a80f8ffe5d4050.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/{1268.0840ff91e083fcbd.js → 5974.360f8441eb0ac1ec.js} +1 -1
  59. package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +74 -0
  64. package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/6571-926ddf024a6ad5df.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +64 -0
  69. package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/{9832.2ab2e818013574c7.js → 6702.ebbd165d5e4a4a14.js} +1 -1
  71. package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +32 -0
  73. package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +24 -0
  74. package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +93 -0
  78. package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/{6110.1297d4093fdfbb0d.js → 740.90b31555290236a9.js} +2 -2
  83. package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +148 -0
  84. package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +226 -0
  85. package/apps/pwa/out/_next/static/chunks/{9070.067c106528ec1ae6.js → 7518.49161e8f5814abdb.js} +1 -1
  86. package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +27 -0
  87. package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +115 -0
  90. package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7905.b230b9d06cb4ad5d.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/{8194.484f51e273d9abd2.js → 8264.00e434fbd02e9311.js} +16 -16
  97. package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +8 -0
  99. package/apps/pwa/out/_next/static/chunks/{088d8e8a.8069543d082bec12.js → 83cfc5c8.349535543c1548b6.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +23 -0
  101. package/apps/pwa/out/_next/static/chunks/{1948.5f35b39eef222a94.js → 8438.ee7f0df3b3f6fcb4.js} +1 -1
  102. package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/{4588.ad3364cb7fb97ada.js → 8532.a86e99acf9b761cb.js} +2 -2
  105. package/apps/pwa/out/_next/static/chunks/8569.b853a8daa8f31d12.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8925-2abfb48af477fb7f.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/{88729267.9c6c000157c83f2f.js → 89849432.9eaa2f4c9c010965.js} +3 -3
  110. package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +90 -0
  111. package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +94 -0
  112. package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +41 -0
  114. package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +287 -0
  116. package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +79 -0
  117. package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/{3522-1de1319d028ac89c.js → 9502-32c5dc22e8f120f5.js} +3 -3
  120. package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +104 -0
  123. package/apps/pwa/out/_next/static/chunks/{7630.2b9a68659053ff4e.js → 9976.8f28864317639fe6.js} +16 -16
  124. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d5341ac96203a983.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-0160ab83c8685a12.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/board/page-55c631c032dcc47e.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ad3bd8084048bee4.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/bots/page-e6784759a2531031.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/ceo/page-5c5d0e370f495ef6.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/chat/page-c325e21543cd48a8.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/consult/{page-111cabe4d1fd69ae.js → page-6168a7c43e6ef8f5.js} +1 -1
  133. package/apps/pwa/out/_next/static/chunks/app/control/page-31417d3604154a6d.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/decisions/page-e9606dc0bdec9305.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/design-check/page-a648bc464c9dc754.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/editor/page-25bb425afdb27541.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/exec/page-32d72fdef1afe11a.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/field/page-d27b794c8ba76bbb.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/inside/page-2bd9ce9c020d02d4.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/intake/page-a34096245e63b9f2.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/layout-22170f4f00a15496.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live/page-4cc66d22ca4ec502.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/live-run/page-83b14c729fcea837.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/loops/page-6e2781c523dad761.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/market/page-26dd415c8f13f341.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-ccdb83ed40c8d724.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/morning/page-7ad3de8fa06fdea9.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/not-found-015c02c4fec4023e.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/observatory/page-6b0ae5b5c42f6d2f.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-786111f30b6f0969.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-48fb31810693c357.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e17cce5e2ed0fee.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/outputs/page-cb154acadb025414.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/page-16258e956ea93fc2.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/reflection/page-c2dd2b19c93f90ab.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-85f35dd1dd96ae87.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/sessions/page-d3c007c8a0ddd7ee.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7837ce2aacb97b04.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/settings/page-7350ee93f4fe1033.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-00723458575f2b19.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/page-745d9b6c015076f8.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/share/page-736d33c7414a8a1a.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/showroom/page-119be9a0444d2482.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/tasks/page-fa806c018833e332.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/term/page-c782041b5f5199ba.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/today/page-d431fbdea6ad93dd.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/trace/page-0c056abff82b9891.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/vault/page-242d668e4fbf72c4.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-847c3de6ca8a4416.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/page-81dd0d8ae923ed72.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workspace/page-74e69ba2c8e970d4.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-70038f41ae7cf931.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/b4e12462-5fab4a813a63dadd.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/{f6b7c9ba.64a895b8b2fedbdc.js → ce383d63.d2ede338788ed18e.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/{framework-5c169757551134ed.js → framework-b2763b10dc6b3836.js} +1 -1
  179. package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +1 -0
  184. package/apps/pwa/out/_next/static/css/5619d59e87eddf66.css +1 -0
  185. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +1 -0
  186. package/apps/pwa/out/_next/static/{MObU8ujkMciAKr6ljAV05 → rfkMm4movqkqMebBrCXiR}/_buildManifest.js +1 -1
  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/graphs/catalog/catalog.yaml +1 -1
  288. package/graphs/drafts/recipes.yaml +2 -2
  289. package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
  290. package/graphs/log-horizon/recipes.yaml +3 -0
  291. package/graphs/release/recipes.yaml +1 -1
  292. package/graphs/release/release-loop.yaml +6 -2
  293. package/graphs/release-rehearsal/recipes.yaml +12 -0
  294. package/graphs/release-rehearsal/release-rehearsal.yaml +17 -0
  295. package/graphs/test-diet/recipes.yaml +3 -0
  296. package/graphs/test-diet/test-diet.yaml +3 -1
  297. package/package.json +4 -1
  298. package/scripts/bench-report.ts +82 -3
  299. package/scripts/ci-typecheck-changed.ts +10 -1
  300. package/scripts/f-session-monitor.ts +69 -0
  301. package/scripts/hq/hq-fence-wrapper.sh +148 -0
  302. package/scripts/hq/standby-snapshot.ts +7 -3
  303. package/scripts/knowledge-compress.ts +11 -0
  304. package/scripts/lib/typecheck-ratchet.ts +51 -0
  305. package/scripts/nightly-docops.ts +90 -3
  306. package/scripts/openai-relay-server.ts +5 -1
  307. package/scripts/release-loop/docs-node.ts +258 -43
  308. package/scripts/release-loop/gate-method.ts +59 -0
  309. package/scripts/release-loop/gate-node.ts +73 -7
  310. package/scripts/release-loop/gate-wall.ts +208 -0
  311. package/scripts/release-loop/known-issues-node.ts +53 -8
  312. package/scripts/release-loop/publish-at.ts +14 -0
  313. package/scripts/release-loop/publish-node.ts +17 -2
  314. package/scripts/release-loop/resume-release.ts +34 -4
  315. package/scripts/release-loop/resume.ts +53 -0
  316. package/scripts/release-loop/shard-plan.ts +3 -11
  317. package/scripts/release-loop/tui-node-checks.ts +22 -0
  318. package/scripts/release-loop/unattended-release.ts +8 -1
  319. package/scripts/research-coo-admin-dates.ts +39 -0
  320. package/scripts/rhythm/daily.ts +51 -2
  321. package/scripts/rhythm/weekly.ts +3 -2
  322. package/scripts/skills/public-check.ts +7 -2
  323. package/scripts/smart-merge/resync-shadow.ts +5 -3
  324. package/scripts/test-diet/lib.ts +81 -1
  325. package/scripts/test-diet/node.ts +48 -2
  326. package/scripts/tsc-main-safety-net.ts +189 -0
  327. package/scripts/usage-rollup.ts +8 -4
  328. package/scripts/verify-coo-admin-evidence.ts +83 -0
  329. package/src/acp/client.ts +4 -2
  330. package/src/acp/codex-plugins.ts +48 -6
  331. package/src/agent/monad-agent-turn.ts +67 -5
  332. package/src/agent/run-context.ts +14 -0
  333. package/src/agent/tool-profile.ts +28 -2
  334. package/src/agent-env/profile.ts +25 -5
  335. package/src/agent-mission/acp-judge.ts +8 -2
  336. package/src/agent-mission/capabilities-cli.ts +16 -1
  337. package/src/agent-mission/driver.ts +27 -13
  338. package/src/agent-mission/pr-review-watch.ts +6 -2
  339. package/src/agent-mission/review-loop.ts +33 -5
  340. package/src/agent-mission/supervisor-metrics.ts +17 -2
  341. package/src/agent-substrate/acp-reviewer.ts +25 -9
  342. package/src/agent-substrate/pr-reviewer.ts +175 -32
  343. package/src/agent-substrate/review-intent.ts +106 -5
  344. package/src/agent-substrate/self-review-cli.ts +111 -16
  345. package/src/agent-substrate/shard-boundary-intent.ts +92 -26
  346. package/src/ask-user-question/pending-questions.ts +8 -2
  347. package/src/autopilot/build/llm-conflict-merge.ts +238 -20
  348. package/src/autopilot/codebase-grounding.ts +44 -0
  349. package/src/autopilot/llm-control-brain.ts +13 -1
  350. package/src/autopilot/mission-codebase-gate.ts +8 -77
  351. package/src/autopilot/pr-manager.ts +30 -11
  352. package/src/away/release-watch.ts +47 -8
  353. package/src/boot/acp-server.ts +4 -7
  354. package/src/boot/acp-socket-path.ts +7 -0
  355. package/src/briefing/brief-items.ts +123 -22
  356. package/src/chat/index.ts +13 -3
  357. package/src/cli/agent-cli.ts +20 -0
  358. package/src/cli/brief-cli.ts +46 -22
  359. package/src/cli/cli-user-error.ts +9 -2
  360. package/src/cli/config-classify.ts +83 -0
  361. package/src/cli/control-cli.ts +14 -0
  362. package/src/cli/decisions-cli.ts +26 -16
  363. package/src/cli/log-event-names.ts +3 -0
  364. package/src/cli/logs-cli.ts +1 -0
  365. package/src/cli/logs-model-input.ts +1 -1
  366. package/src/cli/mcp-login.ts +111 -37
  367. package/src/cli/plugin-cli.ts +21 -1
  368. package/src/cli/pod-cli.ts +26 -0
  369. package/src/cli/pr-cli.ts +94 -9
  370. package/src/cli/pr-land-overlap-evidence.ts +131 -0
  371. package/src/cli/release-cli.ts +74 -15
  372. package/src/cli/self-update.ts +173 -10
  373. package/src/cli/skills-cli.ts +12 -3
  374. package/src/cli/tasks-cli.ts +241 -28
  375. package/src/connectors/types.ts +6 -6
  376. package/src/context-bus/context-first.ts +51 -2
  377. package/src/context-bus/context-now-surfaces.ts +29 -0
  378. package/src/context-bus/coord-events.ts +32 -4
  379. package/src/context-bus/long-term-memory.ts +26 -7
  380. package/src/context-bus/nightly-condense.ts +170 -21
  381. package/src/control/control-status.ts +87 -0
  382. package/src/control-plane/light-member.ts +5 -3
  383. package/src/control-plane/member.ts +172 -7
  384. package/src/core-turn/run-goal-loop.ts +108 -3
  385. package/src/dashboard/chat-fold.ts +20 -0
  386. package/src/dashboard/first-screen-band.ts +151 -1
  387. package/src/dashboard/index.ts +27 -5
  388. package/src/dashboard/slash-runtime/dashboard-handlers.ts +14 -3
  389. package/src/dashboard/stale-install-check.ts +13 -2
  390. package/src/dashboard/turn-stream-formatter.ts +25 -0
  391. package/src/debug/log-diet.ts +159 -0
  392. package/src/debug/log.ts +52 -17
  393. package/src/decisions/decision-cards.ts +20 -1
  394. package/src/decisions/decision-ledger.ts +11 -8
  395. package/src/decisions/web-push-decision-cards.ts +19 -3
  396. package/src/discord-self-message.ts +2 -2
  397. package/src/display/coordinator.ts +25 -2
  398. package/src/domains/coo-admin-dates.evidence.json +876 -0
  399. package/src/domains/coo-admin-tool.ts +75 -14
  400. package/src/domains/cron-match.ts +1 -0
  401. package/src/domains/ops-status.ts +53 -0
  402. package/src/domains/outbound-alert.ts +41 -7
  403. package/src/domains/release-tool.ts +119 -10
  404. package/src/domains/schedule-registry.ts +10 -7
  405. package/src/domains/schedule-runner.ts +1 -0
  406. package/src/elanous-config-dir.ts +2 -2
  407. package/src/elanous-daemon.ts +3 -3
  408. package/src/exec-requests/planner.ts +6 -0
  409. package/src/execution-loop/launch-gate.ts +1 -1
  410. package/src/expression/i18n/messages.en.ts +5 -0
  411. package/src/expression/i18n/messages.ja.ts +5 -0
  412. package/src/expression/i18n/messages.ko.ts +5 -0
  413. package/src/expression/i18n/messages.zh.ts +5 -0
  414. package/src/expression/i18n/types.ts +8 -0
  415. package/src/github/pr-labels.ts +1 -0
  416. package/src/graph-kinds/registry.ts +6 -6
  417. package/src/graph-runner/graph-cli.ts +34 -2
  418. package/src/graph-runner/graph-run-api.ts +7 -0
  419. package/src/graph-runner/graph-tick.ts +73 -12
  420. package/src/graph-runner/runner.ts +94 -13
  421. package/src/graph-unify/wf-to-graph.ts +79 -0
  422. package/src/graph-wizard/generate.ts +34 -2
  423. package/src/graph-wizard/steps.ts +13 -0
  424. package/src/harness/dispatch-backpressure.ts +259 -0
  425. package/src/harness/harness-cli-command.ts +227 -50
  426. package/src/harness/harness-queue.ts +58 -14
  427. package/src/harness/harness-seams.ts +2 -20
  428. package/src/harness/harness-substrate-default.ts +72 -1
  429. package/src/harness/launch-advice.ts +23 -0
  430. package/src/harness/nested-elanous-policy.ts +4 -2
  431. package/src/hq/fence-wrapper.ts +7 -0
  432. package/src/hq/hq.ts +33 -2
  433. package/src/hq/lease.ts +13 -0
  434. package/src/hq/seats.ts +114 -18
  435. package/src/index.ts +199 -71
  436. package/src/intake-plane/collect-github.ts +19 -1
  437. package/src/intake-plane/digest.ts +45 -20
  438. package/src/intake-plane/lens.ts +36 -8
  439. package/src/intelligence-map/model-alias.ts +6 -0
  440. package/src/intelligence-map/model-catalog.ts +41 -0
  441. package/src/knowledge/conclusion-compress.ts +93 -0
  442. package/src/knowledge/kgs/pack.ts +5 -2
  443. package/src/knowledge/kgs/sqlite-store.ts +15 -0
  444. package/src/knowledge/know-find.ts +9 -2
  445. package/src/knowledge/query.ts +20 -0
  446. package/src/knowledge/tools/knowledge-query.ts +20 -2
  447. package/src/knowledge/write.ts +234 -2
  448. package/src/llm/bedrock-provider.ts +175 -0
  449. package/src/llm/bedrock.ts +345 -0
  450. package/src/llm/provider-credentials.ts +3 -1
  451. package/src/llm.ts +332 -51
  452. package/src/loops/budget.ts +150 -0
  453. package/src/loops/neighbor-runtime.ts +88 -0
  454. package/src/loops/orchestrator/author-depth.ts +29 -11
  455. package/src/loops/orchestrator/overlap.ts +7 -1
  456. package/src/loops/orchestrator/resync-shadow.ts +1 -1
  457. package/src/loops/orchestrator/seat-share.ts +6 -49
  458. package/src/loops/orchestrator/tick.ts +35 -2
  459. package/src/loops/orchestrator/traffic.ts +6 -80
  460. package/src/loops/registry.ts +5 -0
  461. package/src/market/publish.ts +17 -1
  462. package/src/market/signed-index.ts +42 -0
  463. package/src/maturity/feature-maturity.ts +2 -1
  464. package/src/mcp/mcp-oauth.ts +136 -17
  465. package/src/model-tier/llm-tier-map.ts +48 -4
  466. package/src/models/prompts.ts +22 -1
  467. package/src/mss/logging/horizon-watch.ts +168 -0
  468. package/src/mss/logging/log-store.ts +204 -15
  469. package/src/mss/logging/redaction.ts +17 -0
  470. package/src/native-tool-catalog.ts +1 -1
  471. package/src/nexus/api/consult-requests.ts +7 -10
  472. package/src/nexus/api/discord-trigger-bot.ts +6 -3
  473. package/src/nexus/api/draft-metrics.ts +22 -8
  474. package/src/nexus/api/error-reports.ts +30 -8
  475. package/src/nexus/api/graph-peer-edit.ts +77 -0
  476. package/src/nexus/api/graph-wizard-api.ts +9 -1
  477. package/src/nexus/api/graphs-api.ts +145 -7
  478. package/src/nexus/api/http-server.ts +101 -8
  479. package/src/nexus/api/loop-resources.ts +42 -0
  480. package/src/nexus/api/outbound-report.ts +8 -3
  481. package/src/nexus/api/plugins-market.ts +24 -0
  482. package/src/nexus/api/telegram-trigger-bot.ts +6 -3
  483. package/src/nexus/index.ts +13 -2
  484. package/src/nexus/outbound/format.ts +2 -0
  485. package/src/nexus/outbound/router.ts +198 -13
  486. package/src/oauth/claude-pty-maturity.ts +24 -0
  487. package/src/oauth/codex-account-rotation.ts +16 -18
  488. package/src/oauth/codex-account-store.ts +134 -5
  489. package/src/oauth/fallback-chain.ts +50 -15
  490. package/src/onboarding.ts +2 -1
  491. package/src/plugins/adapters/claude-package.ts +4 -12
  492. package/src/plugins/core/capability-policy.ts +141 -0
  493. package/src/plugins/core/host.ts +21 -8
  494. package/src/plugins/core/manifest.ts +19 -2
  495. package/src/plugins/core/trust-store.ts +15 -0
  496. package/src/plugins/core/types.ts +12 -0
  497. package/src/plugins/install/market-fetch.ts +68 -16
  498. package/src/plugins/install/plugin-install.ts +187 -16
  499. package/src/plugins/maker/market-bundle.ts +9 -0
  500. package/src/plugins/maker/plugin-maker.ts +32 -21
  501. package/src/plugins/maker/wizard-generate.ts +87 -9
  502. package/src/policy/llm-policy.ts +24 -6
  503. package/src/process/pid-liveness.ts +1 -1
  504. package/src/prompt-cache/openai.ts +10 -6
  505. package/src/prompt-cache/openrouter.ts +94 -0
  506. package/src/prompt-enhance/enhance.ts +46 -5
  507. package/src/prompt-library/family-prompt-coverage.ts +1 -0
  508. package/src/prompt-library/universal-preamble.ts +2 -2
  509. package/src/registry/discovery/openrouter-live-resolve.ts +122 -0
  510. package/src/registry/loader.ts +6 -1
  511. package/src/release-loop/checklist-board.ts +27 -0
  512. package/src/release-loop/checklist.ts +62 -9
  513. package/src/release-loop/feature-store.ts +3 -0
  514. package/src/release-loop/gate-shards.ts +48 -4
  515. package/src/release-loop/landed-to-green.ts +81 -0
  516. package/src/release-loop/light-rc.ts +11 -1
  517. package/src/release-loop/merged-pr-checklist.ts +10 -0
  518. package/src/release-loop/placement.ts +91 -22
  519. package/src/release-loop/rehearsal.ts +317 -0
  520. package/src/release-loop/release-schedule.ts +13 -1
  521. package/src/release-loop/rubric-types.ts +1 -0
  522. package/src/release-loop/rubric.ts +2 -2
  523. package/src/retro/daily.ts +23 -9
  524. package/src/seat-address/seat-address.ts +1 -0
  525. package/src/seat-loop/seat-loop.ts +208 -21
  526. package/src/seat-loop/seat-report.ts +29 -1
  527. package/src/seat-loop/traffic-signal.ts +44 -0
  528. package/src/self-dev/ask-launch-flow.ts +2 -2
  529. package/src/self-dev/dev-cli.ts +157 -11
  530. package/src/self-dev/dev-pipeline.ts +18 -1
  531. package/src/self-dev/draft-residue.ts +463 -0
  532. package/src/self-dev/draft-sweep.ts +195 -17
  533. package/src/self-dev/draft-triage-rules.ts +27 -1
  534. package/src/self-dev/launch-preflight-text.ts +549 -0
  535. package/src/self-dev/launch-preflight.ts +10 -545
  536. package/src/self-dev/orchestrate-cli.ts +57 -2
  537. package/src/self-dev/orchestrate-summary-line.ts +13 -0
  538. package/src/self-dev/orchestrate.ts +9 -133
  539. package/src/self-dev/review-provider-fallback.ts +179 -0
  540. package/src/self-dev/run-store.ts +1 -3
  541. package/src/self-dev/run-supervisor.ts +8 -23
  542. package/src/self-dev/run-types.ts +178 -0
  543. package/src/self-dev/shard-aggregate.ts +61 -13
  544. package/src/self-dev/shard-plan.ts +5 -1
  545. package/src/self-dev/shard-run.ts +23 -5
  546. package/src/self-dev/supervisor-verdict-edges.ts +2 -4
  547. package/src/self-implement/blocked-draft-policy.ts +3 -19
  548. package/src/self-implement/draft-on-stop-mode.ts +18 -0
  549. package/src/self-implement/follow-up-goals.ts +114 -38
  550. package/src/self-implement/gate-baseline-reap.ts +157 -0
  551. package/src/self-implement/gate-baseline.ts +78 -16
  552. package/src/self-implement/gate-cli.ts +12 -2
  553. package/src/self-implement/gate-remote.ts +17 -6
  554. package/src/self-implement/goal-author.ts +24 -4
  555. package/src/self-implement/goal-digest.ts +19 -0
  556. package/src/self-implement/graph-overlay-condition.ts +4 -0
  557. package/src/self-implement/harness-policy-gates.ts +7 -5
  558. package/src/self-implement/headless-elanous-driver.ts +11 -9
  559. package/src/self-implement/host-regate.ts +148 -43
  560. package/src/self-implement/l8-merge-queue.ts +147 -13
  561. package/src/self-implement/merge-train.ts +131 -0
  562. package/src/self-implement/off-diff-evidence.ts +9 -0
  563. package/src/self-implement/orchestrator.ts +201 -43
  564. package/src/self-implement/review-finding-recurrence.ts +28 -0
  565. package/src/self-implement/rework-policy.ts +2 -1
  566. package/src/self-implement/round-summary-card.ts +63 -0
  567. package/src/self-implement/run-ledger.ts +4 -3
  568. package/src/self-implement/run-step-projection.ts +147 -0
  569. package/src/self-implement/run-stop.ts +1 -1
  570. package/src/self-implement/seams.ts +41 -6
  571. package/src/self-implement/self-implement-cli.ts +6 -0
  572. package/src/self-implement/train-gate-remote.ts +158 -0
  573. package/src/session-runtime/index.ts +10 -1
  574. package/src/session-runtime/retry-api.ts +11 -1
  575. package/src/shell-env-bootstrap.ts +19 -4
  576. package/src/skills/gift-install.ts +119 -0
  577. package/src/skills/runner.ts +59 -2
  578. package/src/skills/skill-feedback.ts +31 -1
  579. package/src/skills/skill-tier.ts +1 -0
  580. package/src/smart-wizard/capability-index.ts +231 -0
  581. package/src/smart-wizard/rung.ts +74 -0
  582. package/src/steward/launch.ts +20 -9
  583. package/src/steward/triage.ts +29 -10
  584. package/src/storage/file-lock.ts +40 -4
  585. package/src/task-agent/actions.ts +4 -0
  586. package/src/task-agent/card-evidence.ts +59 -13
  587. package/src/task-agent/completion-evidence.ts +31 -3
  588. package/src/task-agent/cover.ts +61 -0
  589. package/src/task-agent/judge.ts +4 -3
  590. package/src/task-agent/land-worktree.ts +201 -0
  591. package/src/task-agent/live-move-history.ts +133 -0
  592. package/src/task-agent/live-moves.ts +222 -12
  593. package/src/task-agent/parent-host.ts +117 -8
  594. package/src/task-agent/rejudge-on-head.ts +297 -0
  595. package/src/task-agent/review-result-capture.ts +218 -0
  596. package/src/task-agent/shadow.ts +118 -7
  597. package/src/task-agent/task-hand.ts +138 -11
  598. package/src/task-orchestrator/surfaces/pod-child-providers.ts +29 -0
  599. package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
  600. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +16 -2
  601. package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
  602. package/src/task-orchestrator/surfaces/pod-lease.ts +93 -12
  603. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +25 -2
  604. package/src/task-orchestrator/surfaces/pod-pool.ts +203 -28
  605. package/src/task-orchestrator/surfaces/self-implement-pod.ts +259 -36
  606. package/src/task-orchestrator/surfaces/self-implement.ts +11 -0
  607. package/src/telegram-commands.ts +8 -0
  608. package/src/telegram-project-command.ts +6 -0
  609. package/src/telegram-service.ts +5 -1
  610. package/src/telegram.ts +17 -4
  611. package/src/time/format.ts +13 -4
  612. package/src/tool-runtime/goal-author-runtime.ts +1 -0
  613. package/src/tool-runtime/self-cognition-catalog.ts +23 -0
  614. package/src/tool-runtime/self-cognition-runtimes.ts +2 -24
  615. package/src/typecheck-ratchet.ts +2 -1
  616. package/src/user-config.ts +167 -28
  617. package/src/ux-sim/slash-menu-frames.ts +168 -0
  618. package/src/version/packed-revision.json +1 -1
  619. package/src/web-terminal/preview-tap-registry.ts +5 -2
  620. package/src/workflow-runtime/executor.ts +24 -2
  621. package/src/workflow-runtime/triggers/registry.ts +27 -0
  622. package/src/workflow-runtime/triggers/schedule-source.ts +30 -3
  623. package/src/workflow-runtime/triggers/scheduler.ts +1 -0
  624. package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +0 -148
  625. package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +0 -32
  626. package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +0 -309
  627. package/apps/pwa/out/_next/static/chunks/1307-c97eba9fb72a9a5e.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +0 -122
  629. package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +0 -149
  630. package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +0 -79
  631. package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +0 -24
  633. package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +0 -27
  638. package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +0 -36
  647. package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +0 -286
  648. package/apps/pwa/out/_next/static/chunks/2489-ff55a35b202c0f94.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +0 -94
  661. package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/3857-995ea9f5ef33d71e.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +0 -74
  669. package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +0 -34
  674. package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +0 -115
  676. package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +0 -77
  680. package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +0 -90
  684. package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/5977-59fedea50d13c762.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +0 -8
  689. package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +0 -64
  690. package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +0 -287
  692. package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +0 -226
  693. package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +0 -41
  701. package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +0 -24
  704. package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +0 -104
  714. package/apps/pwa/out/_next/static/chunks/8857-f1762140ef9a96b1.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +0 -93
  717. package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/9247-7581825d511a64c0.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +0 -23
  721. package/apps/pwa/out/_next/static/chunks/9497-b0e758d1cd4ae8d7.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +0 -62
  723. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/approvals/page-937c92292a4ab4f0.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d781be3e3a9cfd74.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/board/page-b0a80997903852d8.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/botlab/page-2b1263165630d9c8.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/bots/page-ea998f7f5d156bea.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/ceo/page-33c328b64ca508f8.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/chat/page-e2d6bed48ac20120.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/app/control/page-544dd4bd4847eeb7.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/app/decisions/page-3ee191319bf97d87.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e4bcb2c503dab04b.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/app/editor/page-300897dcbbd5ed76.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/app/exec/page-a449f1ed472b81c2.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/app/field/page-9045094d6d3b5cd0.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/app/inside/page-c06673596849ef45.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/intake/page-103fa3191c1b2e08.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/layout-9f81233f29dcd409.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/live/page-be8b4615c919e36c.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/live-run/page-c685b104e0dfa609.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/app/loops/page-8d693331cfbb6add.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/market/page-cef4f30a4c22fae1.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66ea1b54fc83fa15.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/morning/page-7a12f61be4a579d1.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/not-found-c85b0589591a99c9.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/observatory/page-725a4da02dd129eb.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-8cc707bd09a497d9.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-90b55be1f15ce0e8.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cb16606e08be65db.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/outputs/page-16dc64b74ed6a40a.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/page-21bec4afeb2f0917.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/reflection/page-dc39ee7a36d26385.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-84ae759f76053672.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/sessions/page-3db58ddb61fe2be9.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c5315e30f3528dc4.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/settings/page-2fe368efb6de3b6a.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8d04132dd0ac5e10.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/setup/page-f23484de467c9ea3.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/share/page-c69762987b751174.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/showroom/page-5456692bda39aafb.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d75f7cd65845ce98.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/app/term/page-5603f5e568b25ce3.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/app/today/page-d2cc0f4e89f42028.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/app/trace/page-a6eb73b8a4840f1c.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/app/vault/page-c0a3f4d10edb83fa.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6c0b88068c143f15.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/app/workflows/page-7f8d7fcdf058a845.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/app/workspace/page-22163556cd38bc88.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-141436fd26dd56fc.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/f6231284-45726550aba08fca.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +0 -1
  779. package/apps/pwa/out/_next/static/css/e81df11490b4413b.css +0 -1
  780. /package/apps/pwa/out/_next/static/{MObU8ujkMciAKr6ljAV05 → rfkMm4movqkqMebBrCXiR}/_ssgManifest.js +0 -0
@@ -1,6 +1,8 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import { closeSync, mkdirSync, openSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
3
3
  import { join, resolve } from 'node:path';
4
+ import { getElanousConfigDir } from '../elanous-config-dir.js';
5
+ import { 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[]) => [process.execPath, resolve(import.meta.dir, '../../bin/elanous.mjs'), ...(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,19 @@ 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
+ function runCommand(args: string[], cwd = resolve(import.meta.dir, '../..')): { exitCode: number; stdout: string; stderr: string } {
112
+ const result = Bun.spawnSync(args, { cwd, stdout: 'pipe', stderr: 'pipe' });
105
113
  return { exitCode: result.exitCode, stdout: result.stdout.toString(), stderr: result.stderr.toString() };
106
114
  }
107
115
 
108
- function spawnDetached(args: string[], log: string): { pid: number } {
116
+ function spawnDetached(args: string[], log: string, seat = stewardLaunchSeat()): { pid: number } {
109
117
  const fd = openSync(log, 'a');
110
118
  try {
111
- const child = Bun.spawn(args, { cwd: resolve(import.meta.dir, '../..'), stdout: fd, stderr: fd, stdin: 'ignore', detached: true });
119
+ const child = Bun.spawn(args, { cwd: seat, stdout: fd, stderr: fd, stdin: 'ignore', detached: true });
112
120
  child.unref();
113
121
  return { pid: child.pid };
114
122
  } finally { closeSync(fd); }
@@ -149,9 +157,12 @@ export function launch(item: LaunchItem, deps: LaunchDeps): LaunchEntry {
149
157
  // L6: a launch must remain on the isolated Pod pool, never fall back to the host or another substrate.
150
158
  if (!/^[a-zA-Z0-9_-]+(?:@[a-zA-Z0-9._-]+(?::[1-9][0-9]*)?)?$/.test(settings.podPool ?? DEFAULT_POOL))
151
159
  return blocked('blocked-location', 'invalid steward pod pool');
160
+ let seat: string;
161
+ try { seat = (deps.launchSeat ?? stewardLaunchSeat)(); }
162
+ catch (error) { return blocked('blocked-location', `steward OP seat unavailable: ${String(error)}`); }
152
163
  let budget: BudgetDecision | 'unknown' = 'unknown';
153
164
  try {
154
- const result = command(cli(['harness', 'budget', '--json']));
165
+ const result = command(cli(['harness', 'budget', '--json']), seat);
155
166
  const decision = result.exitCode === 0 ? lastJson(result.stdout) : {};
156
167
  if (!BUDGET_PROCEED.includes(String(decision.outcome)))
157
168
  return blocked('skipped-budget', result.exitCode === 0 ? JSON.stringify(decision.reasons ?? ['budget unavailable']) : result.stderr ?? 'budget unavailable');
@@ -171,7 +182,7 @@ export function launch(item: LaunchItem, deps: LaunchDeps): LaunchEntry {
171
182
  ledger.launches[key] = entry;
172
183
  saveLaunchLedger(root, ledger);
173
184
  try {
174
- entry.pid = (deps.spawn ?? spawnDetached)(argvFor(item.issue, settings), entry.log).pid;
185
+ entry.pid = (deps.spawn ?? spawnDetached)(argvFor(item.issue, settings), entry.log, seat).pid;
175
186
  } catch (error) {
176
187
  entry.status = 'failed';
177
188
  entry.reason = redactSecrets(String(error));
@@ -57,9 +57,13 @@ export interface StewardDeps {
57
57
  cardStore?: StewardCardDeps['store'];
58
58
  warn?: (message: string) => void;
59
59
  ask?: StewardAsk;
60
+ /** Maximum time for each working-backwards wish draft in schedule (milliseconds). */
61
+ draftItemMs?: number;
60
62
  launchSettings?: Pick<StewardSettings, 'mode' | 'launch' | 'maxParallel' | 'podPool'>;
61
63
  launchCommand?: LaunchDeps['command'];
62
64
  spawnLaunch?: LaunchDeps['spawn'];
65
+ /** Isolated OP view for tests; production resolves the registered HQ seat (launch.ts stewardLaunchSeat). */
66
+ launchSeat?: LaunchDeps['launchSeat'];
63
67
  launchGate?: LaunchDeps['gate'];
64
68
  outcomeNotify?: Pick<OutcomeNotifyDeps, 'document' | 'message' | 'worktreeCommand' | 'loadOrigin' | 'loadOrigins'>;
65
69
  /** Internal command boundary: the current sync has already claimed this pid. */
@@ -413,27 +417,42 @@ export async function runStewardStage(stage: 'sync' | 'triage' | 'schedule' | 'r
413
417
  const wishes = rows.filter(row => present.has(row.issue) && row.capability === 'new-capability' && row.rung !== 'hitl');
414
418
  const store = wishes.length ? deps.cardStore ?? new CardStore(root) : undefined;
415
419
  const invalid = new Set<string>();
420
+ const carried = new Set<string>();
416
421
  if (store) try {
417
422
  recordTriageOnCards(wishes, issues, { root, store, now: deps.now });
418
423
  for (const wish of wishes) {
419
- try { await recordWorkingBackwardsOnCards([wish], issues, store, deps.ask ?? askSteward); }
420
- catch (error) {
421
- if (!(error instanceof InvalidWorkingBackwardsDraft)) throw error;
422
- invalid.add(wish.issue);
423
- debug.log('steward.stage', 'draft-invalid', { issue: wish.issue });
424
- }
424
+ const timedOut = Symbol('draft-timeout');
425
+ let timer: ReturnType<typeof setTimeout> | undefined;
426
+ const timeout = new Promise<never>((_, reject) => {
427
+ timer = setTimeout(() => reject(timedOut), deps.draftItemMs ?? 120_000);
428
+ });
429
+ // The draft may finish without ever racing this promise (no ask needed) — never leave its rejection unhandled.
430
+ timeout.catch(() => undefined);
431
+ try {
432
+ // Bound the ask itself so a late answer cannot write to a store closed after this tick.
433
+ const ask: StewardAsk = (prompt, role) => Promise.race([(deps.ask ?? askSteward)(prompt, role), timeout]);
434
+ await recordWorkingBackwardsOnCards([wish], issues, store, ask);
435
+ } catch (error) {
436
+ if (error instanceof InvalidWorkingBackwardsDraft) {
437
+ invalid.add(wish.issue);
438
+ debug.log('steward.stage', 'draft-invalid', { issue: wish.issue });
439
+ } else {
440
+ carried.add(wish.issue);
441
+ debug.log('steward.schedule', 'draft-carried', { issue: wish.issue, reason: error === timedOut ? 'timeout' : 'error' });
442
+ }
443
+ } finally { if (timer) clearTimeout(timer); }
425
444
  }
426
445
  } finally { if (!deps.cardStore) store.close(); }
427
- if (invalid.size) rows = rows.map(row => invalid.has(row.issue)
446
+ if (invalid.size || carried.size) rows = rows.map(row => invalid.has(row.issue)
428
447
  ? { ...row, rung: 'hitl' as const, disposition: 'hitl' as const, hitlReason: 'other' as const, why: 'working-backwards draft invalid' }
429
- : row);
448
+ : carried.has(row.issue) ? { ...row, deferred: true as const, disposition: 'wait' as const } : row);
430
449
  }
431
450
  for (const row of rows) try { debug.log('steward.schedule', 'decision', {
432
451
  kind: row.disposition, target: row.issue, wouldAct: row.disposition === 'now' && liveLike(settings.mode),
433
452
  }); } catch { /* logging must not change the schedule */ }
434
453
  writeFileSync(schedule, JSON.stringify(rows));
435
454
  const ledger = readLaunchLedger(root);
436
- const launchDeps: LaunchDeps = { root, settings, ledger, command: deps.launchCommand, spawn: deps.spawnLaunch, gate: deps.launchGate };
455
+ const launchDeps: LaunchDeps = { root, settings, ledger, command: deps.launchCommand, spawn: deps.spawnLaunch, gate: deps.launchGate, launchSeat: deps.launchSeat };
437
456
  const cardDeps = { root, store: deps.cardStore, now: deps.now };
438
457
  collectOutcomes(ledger, launchDeps);
439
458
  const plan = planLaunches(rows, issues, ledger, settings);
@@ -493,7 +512,7 @@ export async function runStewardStage(stage: 'sync' | 'triage' | 'schedule' | 'r
493
512
  writeFileSync(path, JSON.stringify(state));
494
513
  }
495
514
  const ledger = readLaunchLedger(root);
496
- const outcomes = collectOutcomes(ledger, { root, settings, ledger, command: deps.launchCommand, spawn: deps.spawnLaunch });
515
+ const outcomes = collectOutcomes(ledger, { root, settings, ledger, command: deps.launchCommand, spawn: deps.spawnLaunch, launchSeat: deps.launchSeat });
497
516
  for (const outcome of outcomes) {
498
517
  const issue = issues.find(item => item.identifier === outcome.issue) ??
499
518
  { identifier: outcome.issue, title: outcome.title, ref: '', body: '' };
@@ -27,9 +27,13 @@ const STALE_MS = 30_000;
27
27
  const RETRY_BUSY_MS = 25;
28
28
  const MAX_TRIES = 240; // ~6s upper bound
29
29
 
30
+ const SLEEP_CELL = new Int32Array(new SharedArrayBuffer(4));
31
+
30
32
  function busyWaitMs(ms: number): void {
33
+ // ⭐ A real sleep, not a CPU spin — a waiter may wait minutes (pod image ship lock, 10-08 flood).
34
+ try { Atomics.wait(SLEEP_CELL, 0, 0, ms); return; }
35
+ catch { /* Atomics.wait unavailable on this thread · fall back to the spin */ }
31
36
  const target = Date.now() + ms;
32
- // Trivial busy-loop. Nothing else to do synchronously.
33
37
  while (Date.now() < target) { /* spin */ }
34
38
  }
35
39
 
@@ -37,6 +41,22 @@ export interface LockOpts {
37
41
  staleMs?: number;
38
42
  retryBusyMs?: number;
39
43
  maxTries?: number;
44
+ /**
45
+ * Sync lock only: also break the lock when the pid on its first line is a dead process
46
+ * (a holder killed with -9 must not wedge waiters for `staleMs`).
47
+ */
48
+ breakDeadHolder?: boolean;
49
+ /** Called once, the first time the lock is found held by someone else. */
50
+ onWait?: (holder: string) => void;
51
+ }
52
+
53
+ function holderIsDead(lockPath: string): boolean {
54
+ let pid: number;
55
+ try { pid = Number.parseInt(readFileSync(lockPath, 'utf8').split(/[\n:]/)[0] ?? '', 10); }
56
+ catch { return false; }
57
+ if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return false;
58
+ try { process.kill(pid, 0); return false; }
59
+ catch (err) { return (err as NodeJS.ErrnoException).code === 'ESRCH'; }
40
60
  }
41
61
 
42
62
  export type ReleaseLock = () => void;
@@ -45,6 +65,7 @@ export function acquireLockSync(lockPath: string, opts: LockOpts = {}): ReleaseL
45
65
  const staleMs = opts.staleMs ?? STALE_MS;
46
66
  const retryBusyMs = opts.retryBusyMs ?? RETRY_BUSY_MS;
47
67
  const maxTries = opts.maxTries ?? MAX_TRIES;
68
+ let waited = false;
48
69
 
49
70
  for (let attempt = 0; attempt < maxTries; attempt += 1) {
50
71
  try {
@@ -63,15 +84,23 @@ export function acquireLockSync(lockPath: string, opts: LockOpts = {}): ReleaseL
63
84
  if (code !== 'EEXIST') throw err;
64
85
  // Lock exists · check for staleness.
65
86
  try {
66
- const age = Date.now() - statSync(lockPath).mtimeMs;
67
- if (age > staleMs) {
68
- try { unlinkSync(lockPath); } catch { /* race · retry */ }
87
+ const seen = statSync(lockPath);
88
+ const age = Date.now() - seen.mtimeMs;
89
+ if (age > staleMs || (opts.breakDeadHolder && holderIsDead(lockPath))) {
90
+ // Narrow the race: only unlink the file we judged (a fresh holder may have replaced it meanwhile).
91
+ try { if (statSync(lockPath).ino === seen.ino) unlinkSync(lockPath); } catch { /* race · retry */ }
69
92
  continue;
70
93
  }
71
94
  } catch {
72
95
  // Race: lock disappeared between EEXIST and stat → retry.
73
96
  continue;
74
97
  }
98
+ if (!waited && opts.onWait) {
99
+ waited = true;
100
+ let holder = '';
101
+ try { holder = readFileSync(lockPath, 'utf8').trim(); } catch { /* gone */ }
102
+ try { opts.onWait(holder); } catch { /* observer only */ }
103
+ }
75
104
  busyWaitMs(retryBusyMs);
76
105
  }
77
106
  }
@@ -108,6 +137,7 @@ export async function acquireLockAsync(lockPath: string, opts: LockOpts = {}): P
108
137
  const heartbeatMs = Math.max(50, Math.floor(staleMs / 3));
109
138
  // ⭐ **소유 토큰** — inode 보다 강하다(inode 는 재사용된다). 파일 내용이 곧 소유 증명이다.
110
139
  const token = `${process.pid}:${randomUUID()}`;
140
+ let waited = false;
111
141
 
112
142
  for (let attempt = 0; attempt < maxTries; attempt += 1) {
113
143
  try {
@@ -158,6 +188,12 @@ export async function acquireLockAsync(lockPath: string, opts: LockOpts = {}): P
158
188
  } catch {
159
189
  continue;
160
190
  }
191
+ if (!waited && opts.onWait) {
192
+ waited = true;
193
+ let holder = '';
194
+ try { holder = readFileSync(lockPath, 'utf8').trim(); } catch { /* gone */ }
195
+ try { opts.onWait(holder); } catch { /* observer only */ }
196
+ }
161
197
  await new Promise((resolve) => { setTimeout(resolve, retryBusyMs); });
162
198
  }
163
199
  }
@@ -164,6 +164,10 @@ export async function executeNextAction(action: NextAction, deps: ActionDeps): P
164
164
  parsed = item as typeof parsed;
165
165
  } catch { return record('failed', 'invalid review JSON'); }
166
166
  if (parsed.reviewed !== true) return record('failed', 'review was not performed');
167
+ // TA-LAND-MUSTFIX-ZERO — «pass» 라도 must-fix 가 남았거나 수를 못 읽으면 land 로 가지 않는다(#25941 `canAuto` 와 같은 축).
168
+ // `self review --json` 은 mustFix 배열을 «항상» 싣는다 — 배열이 아니면 «0» 이 아니라 «모름»으로 읽는다(fail-closed).
169
+ if (parsed.verdict === 'pass' && (!Array.isArray(parsed.mustFix) || !parsed.mustFix.every(fix => typeof fix === 'string'))) return card('review-must-fix-unknown: pass verdict without a readable must-fix list');
170
+ if (parsed.verdict === 'pass' && parsed.mustFix!.length > 0) return card(`review-warn-with-must-fix: pass verdict carries ${parsed.mustFix!.length} must-fix`);
167
171
  if (parsed.verdict === 'pass') { record('done', 'review pass'); return executeNextAction({ ...action, kind: 'land', history: [...(action.history ?? []), 'review pass'] }, deps); }
168
172
  if (parsed.verdict === 'fail' && Array.isArray(parsed.mustFix) && parsed.mustFix.length > 0 && parsed.mustFix.every(fix => typeof fix === 'string' && fix.trim())) { record('done', 'review fail'); return executeNextAction({ ...action, kind: 'retry', mustFix: parsed.mustFix, history: [...(action.history ?? []), 'review fail'] }, deps); }
169
173
  return card('review verdict or must-fix unavailable');
@@ -15,11 +15,13 @@ import { debug } from '../debug/log.js';
15
15
  import { LogStore, logsDbPath } from '../mss/logging/log-store.js';
16
16
  import type { RunLedgerEntry } from '../self-implement/run-ledger.js';
17
17
  import { cardPrNumber, taskAgentStatePath, updateTaskCard, readTaskCard, type TaskCard } from './task-hand.js';
18
- import { judgeNextMove } from './judge.js';
18
+ import { judgeNextMove, type TaskJudgeInput } from './judge.js';
19
+ import { remoteParentAlive, type SshRunner } from './parent-host.js';
19
20
 
20
21
  const GOAL_ID = /^[a-f0-9]{16}$/;
21
22
  const PR_URL = /^https:\/\/github\.com\/[\w.-]+\/[\w.-]+\/pull\/(\d+)$/;
22
23
  const RUN_ID = /^run-[A-Za-z0-9_-]{4,64}$/;
24
+ const LATE_LAUNCH_FAILURE = 'failed/needs-relaunch — card-run-bound 뒤 10분 동안 Pod 발사 근거 없음';
23
25
 
24
26
  /** 카드 런 하나의 원장 사진 — host = 카드 런 원장(없으면 null) · children = `pod-child-run` 자식 원장 · podFinishes = 호스트 logs. */
25
27
  export interface CardRunSnapshot {
@@ -131,6 +133,7 @@ export interface CardRunEvidenceDeps {
131
133
  launchBound?: (runId: string) => boolean;
132
134
  dispatchPod?: (runId: string, sinceIso: string) => boolean;
133
135
  runExit?: (runId: string) => RunExit | undefined;
136
+ ssh?: SshRunner;
134
137
  }
135
138
 
136
139
  async function defaultLoadLedger(): Promise<(runId: string) => RunLedgerEntry[] | null> {
@@ -212,19 +215,53 @@ export async function readCardRunSnapshot(card: Pick<TaskCard, 'runId' | 'create
212
215
  * 찾지 못했으면 쓰지 않는다. 쓴(또는 그대로인) 카드를 돌려준다.
213
216
  */
214
217
  export async function refreshCardRunBinding(cardId: string, statePath = taskAgentStatePath(), deps: CardRunEvidenceDeps = {}): Promise<{ card: TaskCard | undefined; evidence?: CardRunEvidence }> {
215
- const card = readTaskCard(cardId, statePath);
216
- // 수동 근거(refSource manual)는 덮지 않는다 · 둘 다 차 있으면 다시 읽지 않는다(한 번만).
217
- if (!card?.runId || card.refSource === 'manual' || (card.pr !== undefined && card.goalId !== undefined)) return { card };
218
+ let card = readTaskCard(cardId, statePath);
219
+ // 수동 근거(refSource manual)는 덮지 않는다 · 둘 다 차 있으면 다시 읽지 않는다(한 번만) —
220
+ // 단 «10분 발사 근거 없음»으로 failed 된 카드는 PR·골이 먼저 묶였어도 되살림 판정을 계속 받는다.
221
+ const awaitingRevival = card?.status === 'failed' && [...card.history].reverse().find((item) => item.event === 'failed')?.detail === LATE_LAUNCH_FAILURE;
222
+ if (!card?.runId || card.refSource === 'manual' || (card.pr !== undefined && card.goalId !== undefined && !awaitingRevival)) return { card };
223
+ const runId = card.runId;
218
224
  const snapshot = await readCardRunSnapshot(card, deps);
219
225
  if (snapshot.readErrors?.length) {
220
226
  try { debug.log('task-agent', 'card-bind-failed', { card: cardId, runId: card.runId, errors: snapshot.readErrors }); } catch { /* fail-soft */ }
221
227
  }
222
228
  const evidence = bindCardEvidence(card, snapshot);
223
- if (card.status === 'launched' && !card.pr && !evidence.pr && !snapshot.readErrors?.length) {
229
+ let revived = false;
230
+ const lastFailure = [...card.history].reverse().find((item) => item.event === 'failed');
231
+ if (card.status === 'failed' && lastFailure?.event === 'failed' && lastFailure.detail === LATE_LAUNCH_FAILURE
232
+ && lastFailure.runId === runId && !snapshot.readErrors?.length) {
233
+ const afterFailure = (entry: RunLedgerEntry) => entry.runId === runId && Date.parse(entry.timestamp ?? '') > Date.parse(lastFailure.at);
234
+ const lateChild = (snapshot.host ?? []).some((entry) => entry.event === 'pod-child-run' && afterFailure(entry));
235
+ const prRows = [...(snapshot.host ?? []), ...Object.values(snapshot.children).flatMap((entries) => entries ?? [])]
236
+ .filter((entry) => entry.event === 'pr-opened' && entry.data?.number === evidence.pr?.number && (entry.runId === runId || entry.runId === evidence.childRunId));
237
+ // PR 근거는 원장 `pr-opened`(실패 뒤 시각) 또는 호스트 logs 의 `job-finished`(podFinishes · 시각 없음) — 후자는
238
+ // `pod-child-run` 자식에게만 붙고, failed 판정은 그 자식이 «없을 때»만 났으므로 지금 보이면 그 자체로 늦은 근거다.
239
+ const prFromJobFinished = !!evidence.pr && !!evidence.childRunId && prRows.length === 0
240
+ && (snapshot.podFinishes ?? []).some((row) => row.childRunId === evidence.childRunId && row.prUrl === evidence.pr?.url);
241
+ const latePr = !!evidence.pr && (prFromJobFinished || prRows.some((entry) => Date.parse(entry.timestamp ?? '') > Date.parse(lastFailure.at)));
242
+ let lateDispatch = false;
243
+ try { lateDispatch = (deps.dispatchPod ?? defaultDispatchPod)(runId, new Date(Date.parse(lastFailure.at) + 1).toISOString()); } catch { /* 읽기 실패는 근거가 아니다 */ }
244
+ if (lateChild || latePr || lateDispatch) {
245
+ const at = (deps.now ?? (() => new Date()))().toISOString();
246
+ const next = updateTaskCard(statePath, cardId, (current) => {
247
+ const failed = [...(current?.history ?? [])].reverse().find((item) => item.event === 'failed');
248
+ return current?.status === 'failed' && current.runId === runId && current.refSource !== 'manual'
249
+ && failed?.event === 'failed' && failed.detail === LATE_LAUNCH_FAILURE && failed.runId === runId && failed.at === lastFailure.at
250
+ ? { ...current, status: 'launched', history: [...current.history, { at, event: 'revived', detail: 'late launch evidence', runId }] } : undefined;
251
+ });
252
+ revived = next?.status === 'launched' && next.history.at(-1)?.event === 'revived' && next.history.at(-1)?.at === at;
253
+ if (revived) {
254
+ try { debug.log('task-agent', 'card-revived', { card: cardId, runId }); } catch { /* fail-soft */ }
255
+ }
256
+ card = next ?? card;
257
+ }
258
+ }
259
+ if (!card) return { card, evidence };
260
+ if (!revived && card.status === 'launched' && !card.pr && !evidence.pr && !snapshot.readErrors?.length) {
224
261
  const rows = [...(snapshot.host ?? []), ...Object.values(snapshot.children).flatMap((entries) => entries ?? [])];
225
262
  let exit: RunExit | undefined;
226
263
  let exitReadFailed = false;
227
- try { exit = (deps.runExit ?? ((id) => readRunExits(effectiveInstanceRoot()).find((row) => row.runId === id)))(card.runId); }
264
+ try { exit = (deps.runExit ?? ((id) => readRunExits(effectiveInstanceRoot()).find((row) => row.runId === id)))(runId); }
228
265
  catch { exitReadFailed = true; }
229
266
  const finished = [...(snapshot.podFinishes ?? [])].reverse().find((item) => item.state === 'failed');
230
267
  const parentTerminal = [...(snapshot.host ?? [])].reverse().find((item) => item.event === 'run-status');
@@ -234,13 +271,21 @@ export async function refreshCardRunBinding(cardId: string, statePath = taskAgen
234
271
  const launched = rows.some((entry) => entry.event === 'pod-child-run');
235
272
  let dispatched = false;
236
273
  let dispatchReadFailed = false;
237
- try { dispatched = (deps.dispatchPod ?? defaultDispatchPod)(card.runId, boundAt ?? card.createdAt); }
274
+ try { dispatched = (deps.dispatchPod ?? defaultDispatchPod)(runId, boundAt ?? card.createdAt); }
238
275
  catch { dispatchReadFailed = true; }
239
276
  let launchBound = false;
240
277
  let launchReadFailed = false;
241
- try { launchBound = (deps.launchBound ?? ((id) => !!readLaunchBinding(id)))(card.runId); }
278
+ try { launchBound = (deps.launchBound ?? ((id) => !!readLaunchBinding(id)))(runId); }
242
279
  catch { launchReadFailed = true; }
243
- const timedOut = !finished && !launched && !dispatched && !dispatchReadFailed && !exit && !exitReadFailed && !launchBound && !launchReadFailed && Number.isFinite(elapsed) && elapsed >= 600_000;
280
+ const missingLaunchTimedOut = !finished && !launched && !dispatched && !dispatchReadFailed && !exit && !exitReadFailed && !launchBound && !launchReadFailed && Number.isFinite(elapsed) && elapsed >= 600_000;
281
+ let remoteState: ReturnType<typeof remoteParentAlive> | undefined;
282
+ if (missingLaunchTimedOut && card.parentHost) {
283
+ remoteState = remoteParentAlive({ ...card.parentHost, runId }, deps.ssh);
284
+ if (remoteState !== 'dead') {
285
+ try { debug.log('task-agent', 'card-remote-parent-alive', { card: cardId, runId: card.runId, host: card.parentHost.host, pid: card.parentHost.pid, state: remoteState }); } catch { /* fail-soft */ }
286
+ }
287
+ }
288
+ const timedOut = missingLaunchTimedOut && (!card.parentHost || remoteState === 'dead');
244
289
  const hasPr = !!card.pr || !!evidence.pr;
245
290
  const exitHarvestBranch = exit?.lastLines?.some((line) => /(?:수확할 브랜치: |ELANOUS_POD_SALVAGE )(?:salvage\/|self-impl\/)[^\s]+/.test(line)) ?? false;
246
291
  const ledgerFailure = rows.find((entry) => entry.event === 'run-status' && entry.data?.runStatus === 'failed'
@@ -251,14 +296,15 @@ export async function refreshCardRunBinding(cardId: string, statePath = taskAgen
251
296
  const deadExit = (exit?.reason === STOP_CLASS_POD_FAILURE || exit?.reason === 'unknown') && exit.status !== null && exit.status !== 0;
252
297
  const podFailure = !noLaunchExit && (launched || dispatched) && (parentFailed && (finished || !!ledgerFailure || !!resultFailure) || deadExit)
253
298
  && (finished || ledgerFailure || resultFailure || deadExit);
254
- const failure = podFailure ? judgeNextMove({ terminalRun: {
299
+ const terminalRun: TaskJudgeInput['terminalRun'] = podFailure ? {
255
300
  kind: STOP_CLASS_POD_FAILURE,
256
301
  reason: finished?.childError || (exit?.status != null ? `exit ${exit.status} · ${exit.reason || STOP_CLASS_POD_FAILURE}` : resultFailure ? 'result-without-error · failed' : finished ? `job-finished failed · ${STOP_CLASS_POD_FAILURE}` : `run-status failed · ${STOP_CLASS_POD_FAILURE}`),
257
302
  hasPr,
258
303
  hasHarvestBranch: exitHarvestBranch || rows.some((entry) => typeof entry.data?.harvestBranch === 'string' && !!entry.data.harvestBranch) || !!salvageBranchOf(rows),
259
- } }) : noLaunchExit ? judgeNextMove({ terminalRun: { kind: STOP_CLASS_NO_LAUNCH, reason: `exit ${exit!.status} · ${exit!.reason}`, hasPr, hasHarvestBranch: false } })
260
- : timedOut ? judgeNextMove({ terminalRun: { kind: STOP_CLASS_NO_LAUNCH, reason: 'card-run-bound 뒤 10분 동안 Pod 발사 근거 없음', hasPr: false, hasHarvestBranch: false } }) : undefined;
261
- if (failure?.reason.startsWith('failed/')) {
304
+ } : noLaunchExit ? { kind: STOP_CLASS_NO_LAUNCH, reason: `exit ${exit!.status} · ${exit!.reason}`, hasPr, hasHarvestBranch: false }
305
+ : timedOut ? { kind: STOP_CLASS_NO_LAUNCH, reason: 'card-run-bound 뒤 10분 동안 Pod 발사 근거 없음', hasPr: false, hasHarvestBranch: false } : undefined;
306
+ const failure = judgeNextMove({ terminalRun });
307
+ if (terminalRun && failure.reason.startsWith('failed/')) {
262
308
  const at = (deps.now ?? (() => new Date()))().toISOString();
263
309
  const next = updateTaskCard(statePath, cardId, (current) => current?.status === 'launched' && current.runId === card.runId && !current.pr && current.refSource !== 'manual' ? {
264
310
  ...current, status: 'failed', history: [...current.history, { at, event: 'failed', detail: failure.reason, runId: card.runId }],
@@ -1,10 +1,10 @@
1
- import { readFileSync, statSync } from 'node:fs';
1
+ import { readFileSync, realpathSync, statSync } from 'node:fs';
2
2
  import { extname, isAbsolute, relative, resolve, sep } from 'node:path';
3
3
  import type { Database } from 'bun:sqlite';
4
4
  import type { DecisionLedger } from '../decisions/decision-ledger.js';
5
5
  import { getLastStatus } from '../domains/schedule-registry.js';
6
6
 
7
- export type CompletionEvidenceKind = 'research-report' | 'artifact' | 'content' | 'ops-action' | 'watch-brief' | 'decision-support';
7
+ export type CompletionEvidenceKind = 'research-report' | 'artifact' | 'content' | 'ops-action' | 'watch-brief' | 'decision-support' | 'deliverable';
8
8
  export interface CompletionEvidenceDeps {
9
9
  ledger?: Pick<DecisionLedger, 'list'>;
10
10
  schedulesDb?: Database;
@@ -13,7 +13,7 @@ export interface CompletionEvidenceDeps {
13
13
  /** A missing record is negative evidence; a failed read is explicitly unmeasured. No store is opened or mutated here. */
14
14
  export function checkCompletionEvidence(
15
15
  kind: CompletionEvidenceKind,
16
- input: { dir: string; ref: string },
16
+ input: { dir: string; ref: string; receipt?: boolean },
17
17
  deps: CompletionEvidenceDeps = {},
18
18
  ): { ok: boolean; ref: string; missing: string[] } {
19
19
  const missing: string[] = [];
@@ -38,6 +38,34 @@ export function checkCompletionEvidence(
38
38
  };
39
39
 
40
40
  switch (kind) {
41
+ case 'deliverable': {
42
+ const ref = input.ref.trim();
43
+ if (/^https?:\/\//i.test(ref)) {
44
+ try {
45
+ const url = new URL(ref);
46
+ if (!url.hostname || !['http:', 'https:'].includes(url.protocol)) add('산출물 링크');
47
+ } catch { add('산출물 링크'); }
48
+ } else if (!ref || /^[a-z][a-z\d+.-]*:/i.test(ref)) {
49
+ add('산출물 경로 또는 링크');
50
+ } else {
51
+ const path = pathFor(ref);
52
+ if (!path) add('못 쟀다: 경로');
53
+ else {
54
+ try {
55
+ const root = realpathSync(input.dir);
56
+ const actual = realpathSync(path);
57
+ const rel = relative(root, actual);
58
+ if (rel === '..' || rel.startsWith(`..${sep}`)) add('못 쟀다: 경로');
59
+ else {
60
+ const stat = statSync(actual);
61
+ if (!stat.isFile() || stat.size === 0) add('산출물 파일');
62
+ }
63
+ } catch (error) { add((error as NodeJS.ErrnoException).code === 'ENOENT' ? '산출물 파일' : '못 쟀다: 산출물 파일 읽기'); }
64
+ }
65
+ }
66
+ if (input.receipt !== true) add('수신 확인');
67
+ break;
68
+ }
41
69
  case 'research-report': {
42
70
  const path = file();
43
71
  if (!path) break;
@@ -0,0 +1,61 @@
1
+ import type { NextActionKind } from './actions.js';
2
+
3
+ type CoverVerb = 'land' | 'review' | 'retry' | 'green';
4
+ export interface CoverRow {
5
+ verb: CoverVerb;
6
+ /** null means the TASK-AGENT action source could not be fully read. */
7
+ byTaskAgent: number | null;
8
+ /** Total work by all seats; null when no independent denominator is available. */
9
+ total: number | null;
10
+ /** TASK-AGENT events observed for this verb, including non-done outcomes; null if unreadable. */
11
+ observedActions: number | null;
12
+ ratio: number | null;
13
+ state: 'measured' | 'no-denominator' | 'unreadable';
14
+ /** Non-shadow action events, including failures; null if the action source is incomplete. */
15
+ liveActions: number | null;
16
+ /** Shadow action events; null if the action source is incomplete. */
17
+ shadowActions: number | null;
18
+ /** A transition is observable only with an independent denominator and a completed TA action. */
19
+ stewardTransition: 'observed' | 'not-observed' | 'unmeasured';
20
+ }
21
+
22
+ /** null means the source could not be read; [] means it was read and had no matching events. */
23
+ export interface TaskAgentCoverInput {
24
+ taskAgentActions: readonly { kind: NextActionKind; result: string }[] | null;
25
+ allLands: readonly { step: string; ok: boolean }[] | null;
26
+ /** A source reached the query safety limit; its aggregate is not known to be complete. */
27
+ truncated?: { taskAgentActions: boolean; allLands: boolean };
28
+ }
29
+
30
+ /** Only land has an independent denominator. The other three verbs have no hand-work source yet. */
31
+ export function measureTaskAgentCover(input: TaskAgentCoverInput): CoverRow[] {
32
+ const verbs: CoverVerb[] = ['land', 'review', 'retry', 'green'];
33
+ return verbs.map((verb) => {
34
+ const actions = input.taskAgentActions?.filter((action) => action.kind === verb);
35
+ const actionsUnreadable = actions === undefined || input.truncated?.taskAgentActions === true;
36
+ const byTaskAgent = actionsUnreadable ? null : actions.filter((action) => action.result === 'done').length;
37
+ const observedActions = actionsUnreadable ? null : actions.length;
38
+ const liveActions = actionsUnreadable ? null : actions.filter((action) => action.result !== 'shadow').length;
39
+ const shadowActions = actionsUnreadable ? null : actions.filter((action) => action.result === 'shadow').length;
40
+ const counts = { liveActions, shadowActions };
41
+ if (verb !== 'land') return {
42
+ verb, byTaskAgent, total: null, observedActions, ratio: null,
43
+ state: actionsUnreadable ? 'unreadable' : 'no-denominator',
44
+ ...counts, stewardTransition: 'unmeasured' as const,
45
+ };
46
+ const total = input.allLands === null || input.truncated?.allLands
47
+ ? null : input.allLands.filter((land) => land.step === 'merge' && land.ok === true).length;
48
+ const state = actionsUnreadable || total === null ? 'unreadable'
49
+ : total === 0 ? 'no-denominator' : 'measured';
50
+ const ratio = state === 'measured' && byTaskAgent !== null && total !== null ? byTaskAgent / total : null;
51
+ return { verb, byTaskAgent, total, observedActions, ratio, state, ...counts,
52
+ stewardTransition: ratio === null ? 'unmeasured' : byTaskAgent !== null && byTaskAgent > 0 ? 'observed' : 'not-observed',
53
+ };
54
+ });
55
+ }
56
+
57
+ /** A single human-readable line per verb; unknown numbers are never rendered as zero. */
58
+ export function formatTaskAgentCover(row: CoverRow): string {
59
+ const value = (count: number | null): string => count === null ? '-' : String(count);
60
+ return `${row.verb}: TA ${value(row.byTaskAgent)}/${value(row.total)} (${row.ratio === null ? '-' : `${(row.ratio * 100).toFixed(1)}%`}) · live ${value(row.liveActions)} · shadow ${value(row.shadowActions)} · steward-transition ${row.stewardTransition}`;
61
+ }
@@ -76,9 +76,10 @@ function base(input: TaskJudgeInput): Omit<TaskJudgement, 'executorKind'> {
76
76
  if (input.deliveryEvidence) return input.deliveryEvidence.ok
77
77
  ? { move: 'propose-green', stage: 'closing', reason: `전달 근거 확인: ${input.deliveryEvidence.files.join(', ')}` }
78
78
  : { move: 'wait', stage: 'waiting', reason: input.deliveryEvidence.reason };
79
- if (input.terminalRun && !input.terminalRun.hasPr && !input.terminalRun.hasHarvestBranch) {
80
- const disposition = input.terminalRun.kind === STOP_CLASS_POD_FAILURE ? 'needs-owner' : 'needs-relaunch';
81
- return { move: 'wait', stage: 'escalated', reason: `failed/${disposition} — ${input.terminalRun.reason.replace(/[\r\n]+/gu, ' ').trim() || input.terminalRun.kind}` };
79
+ if (input.terminalRun && !input.terminalRun.hasPr && !input.terminalRun.hasHarvestBranch && !input.pr) {
80
+ const disposition = input.terminalRun.kind === STOP_CLASS_POD_FAILURE ? 'needs-owner'
81
+ : input.terminalRun.kind === STOP_CLASS_NO_LAUNCH ? 'needs-relaunch' : undefined;
82
+ if (disposition) return { move: 'wait', stage: 'escalated', reason: `failed/${disposition} — ${input.terminalRun.reason.replace(/[\r\n]+/gu, ' ').trim() || input.terminalRun.kind}` };
82
83
  }
83
84
  const stop = input.stopReason;
84
85
  const kind = input.completion;