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
@@ -0,0 +1,549 @@
1
+ export type WorktreePathTouchAxis = 'touched' | 'untouched' | 'unreadable';
2
+
3
+ /** 겹친 경로가 실제로 손대어졌는지의 읽기 전용 관측. */
4
+ export interface WorktreePathTouchObservation {
5
+ readonly state: 'touched' | 'untouched' | 'unreadable' | 'worktree-unknown';
6
+ readonly uncommitted: WorktreePathTouchAxis | null;
7
+ readonly committed: WorktreePathTouchAxis | null;
8
+ }
9
+
10
+ /** 도는 런과 겹친 한 경로의 역할 — 골이 명시한 대상 또는 읽기 근거다. */
11
+ export interface LiveRunOverlapPath {
12
+ readonly path: string;
13
+ readonly role: 'target' | 'evidence' | 'unknown';
14
+ /** 실제 작업 트리 변경 관측. 없는 것은 구형 호출자가 이 값을 제공하지 않았다는 뜻이다. */
15
+ readonly worktreeTouch?: WorktreePathTouchObservation;
16
+ }
17
+
18
+ /** 검사 대상 한 건이 막힌 이유. `name` 은 사람이 바로 열어 볼 수 있는 식별자다. */
19
+ export interface LaunchPreflightBlocker {
20
+ readonly kind: 'open-pr' | 'sibling-pr' | 'live-run' | 'no-target-paths' | 'recent-change' | 'ask-outside-path' | 'ask-marker';
21
+ /** `#8100` · `run-6ce5765b…` 처럼 «바로 조회 가능한» 이름. */
22
+ readonly name: string;
23
+ /** 왜 막혔는지 한 줄 — 경로와 수를 포함한다. */
24
+ readonly detail: string;
25
+ /** draft PR 경고가 연 검사 대상 경로. 동일 경로의 경고를 렌더에서 묶는다. */
26
+ readonly draftPaths?: readonly string[];
27
+ /** 라이브 런 충돌의 경로별 역할. ask 대상 표지가 없으면 미상이라 생략한다. */
28
+ readonly overlapPaths?: readonly LiveRunOverlapPath[];
29
+ /** 라이브 런 충돌이 전부 읽기 근거인지. 역할을 모르면 거짓으로 접지 않고 생략한다. */
30
+ readonly allOverlapPathsAreEvidence?: boolean;
31
+ }
32
+
33
+ /** 검사 한 축의 «관측 상태» — ⛔ 0 · 못 셌음 · 잘렸음을 서로 다른 값으로 둔다. */
34
+ export type PreflightAxisStatus =
35
+ | { readonly state: 'checked'; readonly count: number }
36
+ | { readonly state: 'truncated'; readonly count: number; readonly limit: number }
37
+ | { readonly state: 'unknown'; readonly reason: string };
38
+
39
+ export interface PreflightPreexistingFailureRecord {
40
+ readonly file: string;
41
+ /** 관측 row에 있던 시점. 구형 입력에는 없으므로 사람이 읽게 '모름'으로 렌더한다. */
42
+ readonly observedAt: string | null;
43
+ /** 이 preexisting 기록 뒤 baseline에 같은 파일의 관측이 있었는지. null은 원 기록 시각 결손으로 판단할 수 없음을 뜻한다. */
44
+ readonly reconfirmed?: boolean | null;
45
+ }
46
+
47
+ /** Gate가 원래부터 실패하던 테스트로 기록한 파일의 읽기 결과. */
48
+ export type PreflightPreexistingFailuresStatus =
49
+ | { readonly state: 'checked'; readonly files: readonly string[]; readonly records?: readonly PreflightPreexistingFailureRecord[]; readonly unreadableTargets?: readonly PreflightUnreadableTarget[] }
50
+ | { readonly state: 'truncated'; readonly files: readonly string[]; readonly limit: number; readonly records?: readonly PreflightPreexistingFailureRecord[]; readonly unreadableTargets?: readonly PreflightUnreadableTarget[] }
51
+ | { readonly state: 'unreadable'; readonly reason: string };
52
+
53
+ /**
54
+ * ⛔ 「못 읽은 로그 우주」를 «값으로» 남긴다 — 경고 «문자열»이 아니다.
55
+ * 하나가 안 열려도 나머지에서 읽은 것은 살린다. 하나도 못 읽었을 때만 `unreadable` 이다.
56
+ * 📏 2026-09-12 실측: 등록 347 중 «1»(test:wt-hitl)이 안 열려 346에서 읽은 기록 13건이 통째로 버려졌다.
57
+ */
58
+ export interface PreflightUnreadableTarget {
59
+ readonly dbPath: string;
60
+ readonly reason: string;
61
+ }
62
+
63
+ /** 소스 경로를 같은 디렉터리의 짝 테스트 경로로 순수하게 바꾼다. */
64
+ export function siblingTestPath(path: string): string | null {
65
+ return path.endsWith('.ts') && !path.endsWith('.test.ts')
66
+ ? `${path.slice(0, -'.ts'.length)}.test.ts`
67
+ : null;
68
+ }
69
+
70
+ export function normalizePreexistingFailureObservedAt(observedAt: unknown): string | null {
71
+ return typeof observedAt === 'string' && observedAt.trim() !== '' ? observedAt : null;
72
+ }
73
+
74
+ export function normalizePreexistingFailureRecords(status: Exclude<PreflightPreexistingFailuresStatus, { readonly state: 'unreadable' }>): readonly PreflightPreexistingFailureRecord[] {
75
+ const byFile = new Map<string, PreflightPreexistingFailureRecord>();
76
+ for (const file of status.files) byFile.set(file, { file, observedAt: null, reconfirmed: null });
77
+ for (const record of status.records ?? []) {
78
+ const existing = byFile.get(record.file);
79
+ if (!existing) continue;
80
+ byFile.set(record.file, {
81
+ file: record.file,
82
+ observedAt: normalizePreexistingFailureObservedAt(record.observedAt) ?? existing.observedAt,
83
+ reconfirmed: record.reconfirmed ?? null,
84
+ });
85
+ }
86
+ return [...byFile.values()];
87
+ }
88
+
89
+ function preexistingFailureObservationTimeMs(observedAt: string | null): number | null {
90
+ if (observedAt === null) return null;
91
+ const parsed = Date.parse(observedAt);
92
+ return Number.isFinite(parsed) ? parsed : null;
93
+ }
94
+
95
+ /** 종료된 중단 런 조회는 읽지 못한 원장을 별도 상태로 남긴다. */
96
+ export interface PreflightInterruptedRunObservationFailures {
97
+ /** 원장 로더가 던진 횟수. */
98
+ readonly ledgerLoadThrows?: number;
99
+ /** 원장 로더가 null을 반환한 횟수. */
100
+ readonly nullLedgers?: number;
101
+ /** 원장 start 기록에 goalFile 이름이 없던 횟수. */
102
+ readonly missingGoalFileNames?: number;
103
+ /** 원장은 읽혔으나 가리키는 골 문서가 없어 경로를 모른다. 원장 판독 불가와 다른 수다. */
104
+ readonly unreadableOrMissingGoalDocuments?: number;
105
+ }
106
+
107
+ /** 구형 `unreadableRuns` 합계에 원인별 중단 런 관측 실패를 덧붙인다. */
108
+ export function interruptedRunObservationFailureCount(failures: PreflightInterruptedRunObservationFailures | undefined): number {
109
+ if (!failures) return 0;
110
+ return (failures.ledgerLoadThrows ?? 0)
111
+ + (failures.nullLedgers ?? 0)
112
+ + (failures.missingGoalFileNames ?? 0)
113
+ + (failures.unreadableOrMissingGoalDocuments ?? 0);
114
+ }
115
+
116
+ export type PreflightInterruptedRunsStatus = PreflightAxisStatus
117
+ | {
118
+ readonly state: 'unreadableRuns';
119
+ readonly count: number;
120
+ /** 기존 소비자를 위한 모든 원인 합계. */
121
+ readonly unreadableRuns: number;
122
+ /** 원장은 읽혔으나 가리키는 골 문서가 없다. `unreadableRuns` 와 합치지 않는다. */
123
+ readonly missingGoalDocuments?: number;
124
+ /** 새 소비자가 원인별로 판독 불가를 구분할 수 있는 선택적 보강값. */
125
+ readonly observationFailures?: PreflightInterruptedRunObservationFailures;
126
+ /** 판독 불가와 별개로 조회 상한에도 닿았으면 그 사실을 함께 보존한다. */
127
+ readonly truncated?: true;
128
+ readonly limit?: number;
129
+ };
130
+
131
+ export interface PreflightCompletedRun {
132
+ readonly runId: string;
133
+ readonly plannedPaths: readonly string[];
134
+ readonly ledgerDirectory: string;
135
+ }
136
+
137
+ export type PreflightCompletedRunsQuery = {
138
+ readonly entries: readonly PreflightCompletedRun[];
139
+ readonly unreadableRuns: number;
140
+ readonly missingGoalDocuments?: number;
141
+ } & (
142
+ | { readonly truncated?: false; readonly limit?: number }
143
+ | { readonly truncated: true; readonly limit: number }
144
+ );
145
+
146
+ export interface PreflightInterruptedRun {
147
+ readonly runId: string;
148
+ readonly plannedPaths: readonly string[];
149
+ readonly interruptionReason: string | null;
150
+ /** Terminal run-status timestamp, normalized by the ledger adapter. */
151
+ readonly terminatedAtMs?: number;
152
+ readonly ledgerDirectory: string;
153
+ }
154
+
155
+ export interface PreflightInterruptedRunsQuery {
156
+ readonly entries: readonly PreflightInterruptedRun[];
157
+ readonly unreadableRuns: number;
158
+ readonly observationFailures?: PreflightInterruptedRunObservationFailures;
159
+ readonly limit?: number;
160
+ }
161
+
162
+ export interface AskMarkerObservation {
163
+ readonly askText: 'absent' | 'present';
164
+ /** ask-marker 판정에 실제로 쓴 대상 루트. 생략해도 기존 저장소 래퍼의 실제 루트를 기록한다. */
165
+ readonly inspectionRoot?: string;
166
+ readonly axes: readonly { readonly label: string; readonly marker: boolean; readonly extracted: boolean }[];
167
+ readonly warnings: readonly string[];
168
+ }
169
+
170
+ export interface LaunchPreflightResult {
171
+ readonly paths: readonly string[];
172
+ /** 렌더에 표시한 선언 대상 경로 중 현재 작업 트리에 실재하지 않는 경로 수. 관측용이며 발사 판정에는 쓰지 않는다. */
173
+ readonly missingDeclaredPathCount: number;
174
+ /** 상대 선언 경로를 해석한 대상 저장소 뿌리. 렌더는 실재하지 않는 경로가 있을 때만 문면에 넣는다. */
175
+ readonly declaredPathsRoot?: string;
176
+ readonly blockers: readonly LaunchPreflightBlocker[];
177
+ readonly openPrs: PreflightAxisStatus;
178
+ /** 미완 런 원장 전체 수. ⛔ 이름은 기존 소비자 계약을 위해 유지한다. */
179
+ readonly liveRuns: PreflightAxisStatus;
180
+ /** 같은 대상 경로의 이미 완료된 런. 이 값은 경고·차단을 만들지 않는다. */
181
+ readonly completedRuns: PreflightInterruptedRunsStatus;
182
+ /** 여러 건이면 producer의 원장 위치·runId 정렬을 그대로 보존한다. */
183
+ readonly completedRunMatches: readonly PreflightCompletedRun[];
184
+ /** 같은 대상 경로의 이미 종료된 중단 런. 이 값은 경고·차단을 만들지 않는다. */
185
+ readonly interruptedRuns: PreflightInterruptedRunsStatus;
186
+ /** 여러 건이면 producer의 원장 위치·runId 정렬을 그대로 보존한다. */
187
+ readonly interruptedRunMatches: readonly PreflightInterruptedRun[];
188
+ /** 최근 30일에 종료된 같은 대상의 미완주 런. `unknown`은 원장을 못 읽었거나 종료 시각을 판독하지 못했음을 뜻한다. 차단에는 쓰지 않는다. */
189
+ readonly priorIncompleteRuns?: PreflightAxisStatus;
190
+ /** priorIncompleteRuns의 「최근」 창. 결과에 실어 어느 자로 쟀는지 보인다. */
191
+ readonly priorIncompleteRunWindowDays?: number;
192
+ /** 경로 겹침과 무관하게 나이가 임계 안인 미완 런 수 — 관측용이며 차단에는 쓰지 않는다. */
193
+ readonly activeUnfinishedRuns: PreflightAxisStatus;
194
+ /** 경로 겹침과 무관하게 나이가 임계 밖인 미완 런 수 — 관측용이다. */
195
+ readonly inactiveUnfinishedRuns: PreflightAxisStatus;
196
+ /** 경로 겹침과 무관하게 나이를 판독할 수 없는 미완 런 수. 기존 `unreadableRuns`와 다르다. */
197
+ readonly unreadableUnfinishedRunAges: PreflightAxisStatus;
198
+ /** 대상 경로의 최근 변경 이력 — `unknown`은 조회 실패이며 «변경 없음»이 아니다. */
199
+ readonly recentChanges: PreflightAxisStatus;
200
+ /** 골 전제를 판정 신호가 목으로 흉내 낸 원시 발견 수. 관측일 뿐 차단·경고를 만들지 않는다. */
201
+ readonly premiseMockedBySignal?: PreflightAxisStatus;
202
+ /** 골 문서 안 함수 선언의 반환 지점이 둘 이상인 원시 발견 수. 관측일 뿐 차단·경고를 만들지 않는다. */
203
+ readonly invariantFunctionExits?: PreflightAxisStatus;
204
+ /** gate가 preexisting으로 기록한 테스트 파일. 빈 배열은 기록된 일치가 없음을 뜻하며 깨끗함을 뜻하지 않는다. */
205
+ readonly preexistingFailures: PreflightPreexistingFailuresStatus;
206
+ /** 최근 변경을 조회한 기간 임계(일). 결과에 실어 어느 자로 쟀는지 보인다. */
207
+ readonly recentChangeWindowDays: number;
208
+ /** 막지는 않지만 «지나갔다»고 말해야 하는 것 — draft PR 충돌 등(대표 지시 2026-08-11).
209
+ * ⛔ 「경고가 있었다」와 「아무것도 없었다」는 다른 값이다. */
210
+ readonly warnings: readonly LaunchPreflightBlocker[];
211
+ /** 예정 경로나 나이를 «못 읽어» 판정에서 빠진 런의 수. ⛔ 0 이 아니면 이 검사는 «부분»이다. */
212
+ readonly unreadableRuns: number;
213
+ /** 「도는 런」 판정에 쓴 나이 임계(ms). 결과에 실어 «보이게» 한다. */
214
+ readonly liveRunWindowMs: number;
215
+ /** 별도 확신 판정의 비차단 부록. 기존 생성자는 생략할 수 있고 렌더러도 생략을 기존 동작으로 처리한다. */
216
+ readonly runningRunsConfidenceAppendix?: string;
217
+ /** 이미 계산한 ask 마커 판정. 있으면 실행 경로가 한 건의 구조화 관측으로 남긴다. */
218
+ readonly askMarkerObservation?: AskMarkerObservation;
219
+ }
220
+
221
+ export const emittedAskMarkerObservations = new WeakSet<LaunchPreflightResult>();
222
+
223
+ let askMarkerObserver: ((observation: AskMarkerObservation) => void) | undefined;
224
+ export function setAskMarkerObserver(observer: (observation: AskMarkerObservation) => void): void {
225
+ askMarkerObserver = observer;
226
+ }
227
+
228
+ export function emitAskMarkerObservation(result: LaunchPreflightResult): void {
229
+ if (result.askMarkerObservation === undefined || emittedAskMarkerObservations.has(result)) return;
230
+ try {
231
+ askMarkerObserver?.(result.askMarkerObservation);
232
+ } catch {
233
+ // Preflight observations never change the launch decision.
234
+ }
235
+ emittedAskMarkerObservations.add(result);
236
+ }
237
+
238
+ function renderAxis(label: string, status: PreflightAxisStatus): string {
239
+ if (status.state === 'checked') return `${label}: ${status.count}건 조회`;
240
+ if (status.state === 'truncated') {
241
+ return `${label}: ⚠️ ${status.count}건 — 상한 ${status.limit} 에 «닿았다» (⛔ 이것은 「전부」가 아니다)`;
242
+ }
243
+ return `${label}: ⚠️ 미지 — ${status.reason} (⛔ 「없음」이 아니다)`;
244
+ }
245
+
246
+ function renderAxisCount(status: PreflightAxisStatus): string {
247
+ if (status.state === 'checked') return `${status.count}건`;
248
+ if (status.state === 'truncated') return `⚠️ ${status.count}건 (상한 ${status.limit})`;
249
+ return `⚠️ 못 셌음 — ${status.reason}`;
250
+ }
251
+
252
+ /** 같은 경로 런을 한 줄에 붙이는 «항목 개수» 상한. 2026-08-26 `#13102` 도입.
253
+ *
254
+ * ⛔ 이 주석의 앞 판(2026-09-08 · `OBS-T458`)은 틀렸다 — 정정한다(`OBS-T464`·`OBS-T465`).
255
+ * 그 판은 「최대 17,256자 · 상한이 없어 넷 중 하나가 1,000자를 넘었다」고 적었는데,
256
+ * 17,256자는 ***이 상수가 생기기 «전»(~08-25)의 역사***이고, 지금 긴 줄의 원인도 «개수»가 아니다.
257
+ *
258
+ * 📏 재측정(2026-09-08 · `docs/goals/` 전수): 중앙값 128자 · 75% 1,425자.
259
+ * ~08-25(상수 «전») 최대 ***17,214자*** → 09-08 최대 ***1,789자***
260
+ * ✅ 이 상수는 «완벽히» 먹는다 — 09-07~08 의 1,000자 초과 줄 ***22건 전부 run id 가 «정확히 5개»***.
261
+ * ⚠️ 그런데도 1,000자 초과가 09-08 에 ***16건*** 난다.
262
+ * 🔑 ⇒ 길이를 만드는 것은 「id 개수」가 아니라 ***「id 옆에 붙는 «사유 문장 ⊕ 경로»」***다.
263
+ * 이 상수는 그 축을 ***안 덮는다***(덮으라고 만든 것도 아니다).
264
+ *
265
+ * ⛔ 그러므로 이 상수를 줄여도 그 16건은 안 줄어든다 — 겨냥이 «항목당 길이»여야 한다.
266
+ * ⛔ 접는 것은 목록뿐이다 — `N건 조회` · `N건 원장 판독 불가` · `같은 경로 N건` 은 참값.
267
+ * ⛔ 새 config 노브 없음. 숨긴 수와 전부 보기 명령을 같은 줄에 남겨 상한을 감추지 않는다. */
268
+ const SAME_PATH_RUN_INLINE_LIMIT = 5;
269
+
270
+ function renderSamePathRunQuery(paths: readonly string[]): string {
271
+ const encodedPaths = Buffer.from(JSON.stringify(paths), 'utf8').toString('base64url');
272
+ return `bun -e 'const { queryFederatedCompletedRunLedgers: completed, queryFederatedInterruptedRunLedgers: interrupted } = await import("./src/self-implement/run-ledger.ts"); const { resolveLogTargets } = await import("./src/cli/logs-cli.ts"); const { logsDbPath } = await import("./src/mss/logging/log-store.ts"); const paths = JSON.parse(Buffer.from(process.argv.at(-1), "base64url").toString("utf8")); const targets = [...resolveLogTargets({ all: true, includeTest: true }).targets, { name: "current", dbPath: logsDbPath() }]; const runIds = new Set(); for (const path of paths) { const all = { targets, path, limit: undefined }; for (const run of [...completed(all).entries, ...interrupted(all).entries]) runIds.add(run.runId); } console.log([...runIds].sort().join("\\n"));' ${encodedPaths}`;
273
+ }
274
+
275
+ function renderSamePathRunHits(hits: readonly string[], paths: readonly string[]): string {
276
+ if (hits.length === 0) return '';
277
+ const visible = hits.slice(0, SAME_PATH_RUN_INLINE_LIMIT).join(', ');
278
+ const hidden = hits.length - SAME_PATH_RUN_INLINE_LIMIT;
279
+ return hidden > 0
280
+ ? `: ${visible} · ${hidden}건 숨김 — 전부 보기: ${renderSamePathRunQuery(paths)}`
281
+ : `: ${visible}`;
282
+ }
283
+
284
+ function renderCompletedRunsAxis(status: PreflightInterruptedRunsStatus, matches: readonly PreflightCompletedRun[], paths: readonly string[]): string {
285
+ if (status.state === 'unknown') return `완료 런: ⚠️ 미지 — ${status.reason} (⛔ 「없음」이 아니다)`;
286
+ const suffix = status.state === 'truncated' || (status.state === 'unreadableRuns' && status.truncated) ? ` · 상한 ${status.limit} 에 «닿았다»` : '';
287
+ const hits = renderSamePathRunHits(matches.map((run) => `${run.runId} (${run.ledgerDirectory})`), paths);
288
+ const unreadable = status.state === 'unreadableRuns' && status.unreadableRuns > 0 ? ` · ${status.unreadableRuns}건 원장 판독 불가` : '';
289
+ const missingGoals = status.state === 'unreadableRuns' && (status.missingGoalDocuments ?? 0) > 0 ? ` · ${status.missingGoalDocuments}건 골 문서 사라짐` : '';
290
+ return `완료 런: ${status.state === 'unreadableRuns' ? '⚠️ ' : ''}${status.count}건 조회${unreadable}${missingGoals}${suffix} · 같은 경로 ${matches.length}건${hits}`;
291
+ }
292
+
293
+ function renderInterruptedRunObservationFailures(failures: PreflightInterruptedRunObservationFailures | undefined): string {
294
+ if (!failures) return '';
295
+ const failureCounts: Array<readonly [string, number]> = [
296
+ ['원장 로드 예외', failures.ledgerLoadThrows ?? 0],
297
+ ['null 원장', failures.nullLedgers ?? 0],
298
+ ['goalFile 이름 없음', failures.missingGoalFileNames ?? 0],
299
+ ['골 문서 사라짐', failures.unreadableOrMissingGoalDocuments ?? 0],
300
+ ];
301
+ const parts = failureCounts.filter(([, count]) => count > 0).map(([label, count]) => `${label} ${count}건`);
302
+ return parts.length === 0 ? '' : ` (${parts.join(' · ')})`;
303
+ }
304
+
305
+ function renderInterruptedRunsAxis(status: PreflightInterruptedRunsStatus, matches: readonly PreflightInterruptedRun[], paths: readonly string[]): string {
306
+ const hits = renderSamePathRunHits(matches.map((run) => `${run.runId} (${run.interruptionReason ?? '사유 없음'} · ${run.ledgerDirectory})`), paths);
307
+ if (status.state === 'unreadableRuns') {
308
+ // ⛔ 「골 문서 사라짐」은 `unreadableRuns` 에 «안» 들어간다(#19981) — 그러니 «판독 불가 합계»와 견줄 때 빼야 한다.
309
+ // 🩸 2026-09-23 실물: 안 빼서 「원인별 합계 80건이 전체 0건을 초과」라는 거짓 경고가 났다.
310
+ // ⚠️ 그 칸은 «섞여» 있다 — ENOENT(사라짐)는 `unreadableRuns` 밖, 그 밖의 읽기 예외는 안이다. 그래서 셋으로 가른다:
311
+ // unreadableRuns ≥ 전체 합계 → 종전대로(남으면 「기타/미분류」)
312
+ // 나머지 원인 ≤ unreadableRuns < 전체 → 경고 없음(골 문서 일부는 판독 불가 «밖»에 있다)
313
+ // unreadableRuns < 나머지 원인 → 「초과」(골 문서 칸을 빼고도 넘친다 — 진짜 불일치)
314
+ const allFailures = interruptedRunObservationFailureCount(status.observationFailures);
315
+ const readFailures = allFailures - (status.observationFailures?.unreadableOrMissingGoalDocuments ?? 0);
316
+ const knownFailures = renderInterruptedRunObservationFailures(status.observationFailures);
317
+ const failures = status.observationFailures === undefined
318
+ ? ''
319
+ : allFailures <= status.unreadableRuns
320
+ ? `${knownFailures}${allFailures < status.unreadableRuns ? ` · 기타/미분류 실패 ${status.unreadableRuns - allFailures}건` : ''}`
321
+ : readFailures <= status.unreadableRuns
322
+ ? knownFailures
323
+ : `${knownFailures} · ⚠️ 원인별 합계 ${readFailures}건이 전체 ${status.unreadableRuns}건을 초과`;
324
+ const unreadable = status.unreadableRuns > 0 ? ` · ${status.unreadableRuns}건 원장 판독 불가` : '';
325
+ const missingGoals = status.observationFailures === undefined && (status.missingGoalDocuments ?? 0) > 0
326
+ ? ` · ${status.missingGoalDocuments}건 골 문서 사라짐`
327
+ : '';
328
+ return `중단 런: ⚠️ ${status.count}건 조회${unreadable}${missingGoals}${failures}${status.truncated ? ` · 상한 ${status.limit} 에 «닿았다»` : ''} · 같은 경로 ${matches.length}건${hits}`;
329
+ }
330
+ if (status.state === 'unknown') return `중단 런: ⚠️ 미지 — ${status.reason} (⛔ 「없음」이 아니다)`;
331
+ const suffix = status.state === 'truncated' ? ` · 상한 ${status.limit} 에 «닿았다»` : '';
332
+ return `중단 런: ${status.count}건 조회${suffix} · 같은 경로 ${matches.length}건${hits}`;
333
+ }
334
+
335
+ /** 한 줄 상한 — 기존 중단 런 줄처럼 사유를 전부 이어 붙이지 않는다. */
336
+ const REPEATED_INTERRUPTION_REASON_LINE_LIMIT = 200;
337
+
338
+ function truncateRepeatedInterruptionReason(reason: string, budget: number): string {
339
+ if (budget <= 0) return '';
340
+ if (reason.length <= budget) return reason;
341
+ if (budget === 1) return '…';
342
+ return `${reason.slice(0, budget - 1)}…`;
343
+ }
344
+
345
+ /**
346
+ * 같은 경로 중단 런에서 반복된 사유를 한 줄로 말한다.
347
+ * ⛔ 2건 미만이면 아무 말도 하지 않는다 — 「1건입니다」는 소음이다.
348
+ * ⛔ `renderRepeatedBlockNotice` 를 부르지 않는다. 그 인자는 「막힌 횟수」이고 여기 문턱과 뜻이 다르다.
349
+ * ⛔ `interruptionReason` 이 없는 런은 「같은 사유」로 세지 않는다 — 「없음」과 「못 셌음」은 다른 값이다.
350
+ * 복수 그룹·동률: 반복 건수가 큰 쪽, 같으면 정규화 키 사전순. 표시 문면은 그 그룹에서 처음 본 사유.
351
+ */
352
+ export function renderRepeatedInterruptionReasonNotice(
353
+ matches: readonly PreflightInterruptedRun[],
354
+ ): string | null {
355
+ const groups = new Map<string, { count: number; reason: string }>();
356
+ for (const run of matches) {
357
+ const reason = run.interruptionReason;
358
+ if (reason == null || reason.trim() === '') continue;
359
+ const key = reason.toLowerCase().replace(/`[^`]*`/g, '').replace(/\d/g, '').replace(/\s+/g, ' ').trim();
360
+ const existing = groups.get(key);
361
+ if (existing) existing.count += 1;
362
+ else groups.set(key, { count: 1, reason: reason.replace(/\s+/g, ' ').trim() });
363
+ }
364
+
365
+ let representative: { key: string; count: number; reason: string } | null = null;
366
+ for (const [key, group] of groups) {
367
+ if (group.count < 2) continue;
368
+ if (
369
+ representative == null
370
+ || group.count > representative.count
371
+ || (group.count === representative.count && key < representative.key)
372
+ ) {
373
+ representative = { key, count: group.count, reason: group.reason };
374
+ }
375
+ }
376
+ if (representative == null) return null;
377
+
378
+ const prefix = `[preflight] 🔁 같은 사유 ${representative.count}건/${matches.length}건 — `;
379
+ const shortReason = truncateRepeatedInterruptionReason(
380
+ representative.reason,
381
+ REPEATED_INTERRUPTION_REASON_LINE_LIMIT - prefix.length,
382
+ );
383
+ return `${prefix}${shortReason}`;
384
+ }
385
+
386
+ export type LaunchPreflightPhase = 'before-authoring' | 'before-launch';
387
+
388
+ /** 사람이 읽는 한 화면. ⛔ 막혔든 아니든 «무엇을 봤는지»를 항상 낸다.
389
+ * ⛔ `forced` 를 주면 마지막 줄이 «실제 결정»과 일치한다 — 뚫고 가면서 「발사하지 않는다」라고
390
+ * 적으면 그 산출이 거짓이 된다(2026-08-11 리뷰 should-fix). */
391
+ export function renderLaunchPreflight(
392
+ result: LaunchPreflightResult,
393
+ forced = false,
394
+ phase: LaunchPreflightPhase = 'before-launch',
395
+ ): string {
396
+ emitAskMarkerObservation(result);
397
+ const lines: string[] = [];
398
+ const declaredPathLine = `[preflight] 요청문이 선언한 대상 경로 ${result.paths.length}개 · 실재하지 않음 ${result.missingDeclaredPathCount}개: ${result.paths.join(', ') || '(없음)'}`;
399
+ lines.push(
400
+ result.missingDeclaredPathCount > 0 && result.declaredPathsRoot
401
+ ? `${declaredPathLine} (기준 ${result.declaredPathsRoot})`
402
+ : declaredPathLine,
403
+ );
404
+ lines.push(`[preflight] ${renderAxis('열린 PR', result.openPrs)}`);
405
+ lines.push(`[preflight] ${renderAxis('미완 런', result.liveRuns)} · 그중 지금 도는 것 ${renderAxisCount(result.activeUnfinishedRuns)} · 나이 판독 불가 ${renderAxisCount(result.unreadableUnfinishedRunAges)} · 「도는 중」 임계 ${Math.round(result.liveRunWindowMs / 60000)}분`);
406
+ if (result.runningRunsConfidenceAppendix) lines.push(result.runningRunsConfidenceAppendix);
407
+ const completedRunsAxis = renderCompletedRunsAxis(result.completedRuns, result.completedRunMatches, result.paths);
408
+ lines.push(`[preflight] ${completedRunsAxis}`);
409
+ const interruptedMatches = result.interruptedRunMatches;
410
+ const interruptedRunsAxis = renderInterruptedRunsAxis(result.interruptedRuns, interruptedMatches, result.paths);
411
+ lines.push(`[preflight] ${interruptedRunsAxis}`);
412
+ const repeatedInterruptionReason = renderRepeatedInterruptionReasonNotice(interruptedMatches);
413
+ if (repeatedInterruptionReason) lines.push(repeatedInterruptionReason);
414
+ lines.push(`[preflight] ${renderAxis('최근 변경', result.recentChanges)} · 최근 변경 임계 ${result.recentChangeWindowDays}일`);
415
+ if (result.premiseMockedBySignal) lines.push(`[preflight] ${renderAxis('전제를 목으로 세운 판정 신호', result.premiseMockedBySignal)} — 원시 관측이며 발사를 막지 않는다`);
416
+ if (result.invariantFunctionExits) lines.push(`[preflight] ${renderAxis('반환 지점 둘 이상 함수', result.invariantFunctionExits)} — 원시 관측이며 발사를 막지 않는다`);
417
+ if (result.preexistingFailures.state === 'unreadable') {
418
+ lines.push(`[preflight] ⚠️ gate preexisting 실패 기록: 못 읽음 — ${result.preexistingFailures.reason} (⛔ 「기록 없음」이 아니다)`);
419
+ } else {
420
+ const records = normalizePreexistingFailureRecords(result.preexistingFailures);
421
+ const observedAtMs = records.flatMap((record) => {
422
+ const timestamp = preexistingFailureObservationTimeMs(record.observedAt);
423
+ return timestamp === null ? [] : [timestamp];
424
+ });
425
+ const unknownObservedAtCount = records.length - observedAtMs.length;
426
+ const oldestAge = observedAtMs.length === 0
427
+ ? '모름'
428
+ : `${Math.max(0, Math.floor((Date.now() - Math.min(...observedAtMs)) / 86_400_000))}일`;
429
+ const oldestLabel = unknownObservedAtCount > 0 ? '시각 확인 가능한 기록 중 가장 오래된 기록' : '가장 오래된 기록';
430
+ const diagnostic = ` · ${oldestLabel} ${oldestAge} 전 · 시각 모름 ${unknownObservedAtCount}개 · 재확인 없음 ${records.filter((record) => record.reconfirmed === false).length}개 · 재확인 판단 불가 ${records.filter((record) => record.reconfirmed === null).length}개`;
431
+ if (result.preexistingFailures.state === 'truncated') {
432
+ lines.push(`[preflight] ⚠️ gate preexisting 실패 기록: 같은 대상 ${result.preexistingFailures.files.length}개${result.preexistingFailures.files.length ? `: ${result.preexistingFailures.files.join(', ')}` : ''}${diagnostic} · 상한 ${result.preexistingFailures.limit} 에 «닿았다» (⛔ 이것은 「전부」가 아니다)`);
433
+ } else if (result.preexistingFailures.files.length > 0) {
434
+ lines.push(`[preflight] ⚠️ gate preexisting 실패 기록: 같은 대상 ${result.preexistingFailures.files.length}개: ${result.preexistingFailures.files.join(', ')}${diagnostic}`);
435
+ }
436
+ }
437
+ // ⛔ 「부분으로 읽었다」를 «값으로» 말한다 — 못 읽은 우주가 있으면 이 결과는 «전부»가 아니다.
438
+ const unreadableTargets = result.preexistingFailures.state === 'unreadable' ? undefined : result.preexistingFailures.unreadableTargets;
439
+ if (unreadableTargets && unreadableTargets.length > 0) {
440
+ lines.push(`[preflight] ⚠️ gate preexisting 실패 기록: 로그 우주 ${unreadableTargets.length}개를 «못 읽었다» — ${unreadableTargets.map((target) => `${target.dbPath} (${target.reason})`).join(', ')} (⛔ 위 목록은 「전부」가 아니다)`);
441
+ }
442
+ if (result.unreadableRuns > 0) {
443
+ lines.push(`[preflight] ⚠️ 그중 ${result.unreadableRuns}건은 예정 경로·나이를 «못 읽어» 판정에서 빠졌다 — 이 검사는 «부분»이다`);
444
+ }
445
+ // ⛔ 「지나갔다」와 「없었다」를 다른 값으로 — 경고는 막든 안 막든 «항상» 보인다.
446
+ const draftWarnings = result.warnings.filter((warning) => warning.kind === 'open-pr');
447
+ if (draftWarnings.length > 0) {
448
+ for (const warning of draftWarnings) lines.push(`[preflight] ⚠️ ${warning.name} — ${warning.detail}`);
449
+ const draftsByPath = new Map<string, LaunchPreflightBlocker[]>();
450
+ for (const warning of draftWarnings) {
451
+ for (const path of warning.draftPaths ?? []) {
452
+ const drafts = draftsByPath.get(path) ?? [];
453
+ drafts.push(warning);
454
+ draftsByPath.set(path, drafts);
455
+ }
456
+ }
457
+ for (const [path, drafts] of draftsByPath) {
458
+ if (drafts.length < 2) continue;
459
+ const numbers = drafts.map((draft) => draft.name.slice(1));
460
+ lines.push(`[preflight] ⚠️ ${path} 을 여는 draft PR ${drafts.length}건: ${drafts.map((draft) => draft.name).join(' ')} — 확인 명령: ${numbers.map((number) => `gh pr view ${number} --json body`).join(' ; ')}`);
461
+ }
462
+ }
463
+ const siblingPrWarnings = result.warnings.filter((warning) => warning.kind === 'sibling-pr');
464
+ for (const warning of siblingPrWarnings) lines.push(`[preflight] ⚠️ ${warning.name} — ${warning.detail}`);
465
+ const liveRunWarnings = result.warnings.filter((warning) => warning.kind === 'live-run');
466
+ for (const warning of liveRunWarnings) lines.push(`[preflight] ⚠️ ${warning.name} — ${warning.detail}`);
467
+ const askOutsidePathWarnings = result.warnings.filter((warning) => warning.kind === 'ask-outside-path');
468
+ for (const warning of askOutsidePathWarnings) lines.push(`[preflight] ⚠️ ${warning.name} — ${warning.detail}`);
469
+ if (result.askMarkerObservation) {
470
+ lines.push(`[preflight] ask 마커 검사 뿌리: ${result.askMarkerObservation.inspectionRoot ?? '기본 저장소'}`);
471
+ }
472
+ const askMarkerWarnings = result.warnings.filter((warning) => warning.kind === 'ask-marker');
473
+ for (const warning of askMarkerWarnings) lines.push(`[preflight] ⚠️ ${warning.name} — ${warning.detail}`);
474
+ const recentChangeWarnings = result.warnings.filter((warning) => warning.kind === 'recent-change');
475
+ if (recentChangeWarnings.length > 0) {
476
+ lines.push(`[preflight] ⚠️ 최근 변경 ${recentChangeWarnings.length}개 대상 경로 — 사람이 읽는다: ${recentChangeWarnings.map((w) => w.name).join(' ')}`);
477
+ for (const warning of recentChangeWarnings.filter((warning) => warning.name === 'gate preexisting 실패')) {
478
+ lines.push(`[preflight] ⚠️ ${warning.name} — ${warning.detail}`);
479
+ }
480
+ }
481
+ if (result.blockers.length === 0) {
482
+ if (phase === 'before-authoring') {
483
+ lines.push('[preflight] ✅ 막는 것 없음 — 예비 검사 완료; 저작 뒤 확정 재검사가 한 번 더 온다');
484
+ } else {
485
+ lines.push(result.warnings.length > 0
486
+ ? `[preflight] ✅ 막는 것 없음 — 확정 검사 완료; 발사로 간다 (경고 ${result.warnings.length}건은 위에 있다)`
487
+ : '[preflight] ✅ 막는 것 없음 — 확정 검사 완료; 발사로 간다');
488
+ }
489
+ return lines.join('\n');
490
+ }
491
+ lines.push(`[preflight] ⛔ 막는 것 ${result.blockers.length}건${forced ? '' : ' — 발사하지 않는다'}`);
492
+ for (const blocker of result.blockers) lines.push(`[preflight] · ${blocker.name} — ${blocker.detail}`);
493
+ lines.push(forced
494
+ ? '[preflight] ⚠️ --force-preflight — 위 막힘을 «뚫고» 발사한다 (이 우회는 관측에 남는다)'
495
+ : '[preflight] 그래도 가려면 --force-preflight (그 우회는 관측에 남는다) — elanous dev');
496
+ return lines.join('\n');
497
+ }
498
+
499
+ /** ⛔⭐⭐⭐ 「맹점 창」을 닫는 첫 조각 — ask 원문에서 «대상 경로 힌트»를 뽑는다.
500
+ *
501
+ * 📏 왜 필요한가(2026-08-11 실측): `dev --ask/--say` 는 ***저작(100~110초) 뒤에*** 전제 검사를 돈다.
502
+ * 그 사이 그 런은 아직 «아무 원장에도 없어서», 두 창이 거의 같은 시각에 발사하면 서로를 못 본다.
503
+ * 그날 두 트랙이 실제로 같은 파일을 겨냥한 골을 각각 저작했고 ***검사가 아니라 사람이 채널로 막았다.***
504
+ * ⊕ 그리고 그 창 때문에 저작 100초를 «쓰고 나서» 막힌 발사가 그날만 넷이었다.
505
+ *
506
+ * ⭐ 이 저장소의 ask 는 첫 줄이 `대상 경로: a · b` 로 시작하는 관행이 있다 ⇒ 저작 «전»에 그것으로 예비 검사를 한다.
507
+ * ⛔ 힌트가 «없으면» 「경로 없음」이 아니라 ***「못 뽑았다」***다 — 빈 배열을 「충돌 없음」으로 읽지 마라.
508
+ * (호출자는 빈 배열이면 예비 검사를 «건너뛰고» 그 사실을 말해야 한다.)
509
+ * ⛔ 이것은 «추정»이다 — 저작된 골의 TRACED PATHS 가 정본이고, 발사 직전 검사가 그것으로 다시 판정한다.
510
+ */
511
+ export type AskTargetPathHintRejectionReason = 'has-whitespace' | 'not-path-like' | 'empty';
512
+
513
+ /** ask 첫 줄에서 버린 대상 경로 조각 — 원문을 보존해 사람이 손실을 바로 고친다. */
514
+ export interface AskTargetPathHintRejection {
515
+ readonly fragment: string;
516
+ readonly reason: AskTargetPathHintRejectionReason;
517
+ }
518
+
519
+ /** 대상 경로 힌트 파싱의 관측 결과. `labelMissing`은 「0건」과 「못 셌음」을 가른다. */
520
+ export interface AskTargetPathHintsParseResult {
521
+ readonly paths: readonly string[];
522
+ readonly rejected: readonly AskTargetPathHintRejection[];
523
+ readonly labelMissing: boolean;
524
+ }
525
+
526
+ export function parseAskTargetPathHintsResult(askText: string): AskTargetPathHintsParseResult {
527
+ // ⛔ 첫 «비어 있지 않은» 줄만 본다 — 본문 전체를 훑으면 산문 속 경로까지 끌려와 오탐이 된다.
528
+ const firstLine = askText.split(/\r?\n/).find((line) => line.trim() !== '');
529
+ if (firstLine === undefined) return { paths: [], rejected: [], labelMissing: true };
530
+ const match = /^\s*(?:대상\s*경로|target\s*paths?)\s*[::]\s*(.*)$/i.exec(firstLine);
531
+ if (!match) return { paths: [], rejected: [], labelMissing: true };
532
+
533
+ const paths: string[] = [];
534
+ const rejected: AskTargetPathHintRejection[] = [];
535
+ for (const fragment of match[1]!.split(/[·,]/)) {
536
+ const piece = fragment.trim().replace(/^`+|`+$/g, '');
537
+ if (piece === '') rejected.push({ fragment, reason: 'empty' });
538
+ // ⛔ 「경로처럼 생긴 것」만 남긴다 — 확장자나 디렉터리 구분자가 있어야 한다.
539
+ else if (!/[/.]/.test(piece)) rejected.push({ fragment, reason: 'not-path-like' });
540
+ else if (/\s/.test(piece)) rejected.push({ fragment, reason: 'has-whitespace' });
541
+ else paths.push(piece);
542
+ }
543
+ return { paths, rejected, labelMissing: false };
544
+ }
545
+
546
+ /** 기존 호출자를 위한 호환 래퍼 — 판정과 반환 형태는 바꾸지 않는다. */
547
+ export function parseAskTargetPathHints(askText: string): readonly string[] {
548
+ return parseAskTargetPathHintsResult(askText).paths;
549
+ }