elanous 0.2.38 → 0.2.41

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 (712) hide show
  1. package/README.md +7 -7
  2. package/apps/pwa/out/404/index.html +1 -1
  3. package/apps/pwa/out/404.html +1 -1
  4. package/apps/pwa/out/_next/static/{RrjXTwz-urRAbChP1bX02 → GiOLWmt4MqDZePubBjA4Q}/_buildManifest.js +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1115.434ae2ecb0ad986d.js +149 -0
  6. package/apps/pwa/out/_next/static/chunks/1121.667cec0bcdbb3fdb.js +36 -0
  7. package/apps/pwa/out/_next/static/chunks/1178.1aa9cad0e7695427.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1197-54da59d250a6e476.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/{5203.51e5d8b5f1dcfe53.js → 1219.7e17964e0e7cd8e5.js} +3 -3
  10. package/apps/pwa/out/_next/static/chunks/1245.1cfd13b26dbd71d6.js +287 -0
  11. package/apps/pwa/out/_next/static/chunks/1494-f93046ff5c5a124d.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/1609.2b312797599b8e45.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1661.0dd330f3d89f73f3.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/167-0c121e4b47e0f9da.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1700.cdc2bf8cc685e221.js +90 -0
  16. package/apps/pwa/out/_next/static/chunks/1703-78e46acad29f3cfc.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/{7573.2376e13c9c21f1f8.js → 1765.679b29625c8e88d4.js} +2 -2
  18. package/apps/pwa/out/_next/static/chunks/{3528.e4b8ab70d339f965.js → 1800.f7ff51dc4978a958.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/1971-7efb628c471dc5a0.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/1999-8de7b7bb36801913.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2073.689dcb2680113d76.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2198-557d49184104d165.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/221-440ce67fa9f5c839.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/{8879.ac06755bcf3e44a1.js → 2263.e09b6edea33bad2d.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/2427-8ed8e98624cbd664.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2457-725c5827bc003795.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2491-2718b15a5ccb75a5.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2527-5c636a43c7cc5dde.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/2692-1027cb16fe4ccf49.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/2743.5d3f76948be32b34.js +41 -0
  31. package/apps/pwa/out/_next/static/chunks/2773.0e80b9d325fb5635.js +32 -0
  32. package/apps/pwa/out/_next/static/chunks/2873-0f3cb56c8e3528ea.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/{9fe1b809.738da85c8b17e3fb.js → 2fdf2931.b431eee4fb468bc3.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/{eaad0cba.771200940c529df7.js → 2fe2c302.41b517f88d6fe502.js} +1 -1
  35. package/apps/pwa/out/_next/static/chunks/3097.864e92bdaa2f4d15.js +79 -0
  36. package/apps/pwa/out/_next/static/chunks/3136-d6870ba63300a93e.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3173-0289113d434e83b7.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3230-49298c3b73ef2268.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/325-dd9208a1a0ab7ce4.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3283.528f430dd043fb4e.js +74 -0
  41. package/apps/pwa/out/_next/static/chunks/3295.cc8cb13b8f0dae1a.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/3688-86e3b88abf18cb3b.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3804-7220467a5473a8df.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/3808.3e1e247ce7bdf889.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{b7478fef.5917716286213fcc.js → 385e4574.e9886ab32759eda3.js} +3 -3
  46. package/apps/pwa/out/_next/static/chunks/3927.b5473ad109da44c5.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/3934-98ea94832e194796.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4133.2056bb4d78f621af.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4156.ba4de4a3664f04b4.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4297-239ca82f293faab0.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4320-dcc5a7734126f4c9.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4434.94b4c552a2d91e69.js +148 -0
  53. package/apps/pwa/out/_next/static/chunks/{8911.bf5e712acb25fb6c.js → 4527.a69f2894d1bc9f4a.js} +1 -1
  54. package/apps/pwa/out/_next/static/chunks/4579.03e4092f73950965.js +226 -0
  55. package/apps/pwa/out/_next/static/chunks/{5307.d7328020227880c2.js → 4667.97e31aa38c95c475.js} +4 -4
  56. package/apps/pwa/out/_next/static/chunks/{6142.913b44e260a3f925.js → 4702.4a4adc1f16d7c93b.js} +1 -1
  57. package/apps/pwa/out/_next/static/chunks/4815.481501c57b3568d9.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/487-d16e698ef14662d9.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/4888-7a38bf522c9cc6fe.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5034-30e429d6bb086881.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5040-35c494e60dadd97d.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/50c6ab1e.81a96e419350909d.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/5154.4b6a836179356f30.js +94 -0
  64. package/apps/pwa/out/_next/static/chunks/{8487.291666583bebe640.js → 5159.115f1c2ca471386c.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/5228-a8200df486278f2d.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/530.d26346e18089640a.js +115 -0
  67. package/apps/pwa/out/_next/static/chunks/5379.97af106d09566f69.js +8 -0
  68. package/apps/pwa/out/_next/static/chunks/{89d6c04f-6b8ab341748e468a.js → 53aeb4ee-51c92f8d683f5220.js} +1 -1
  69. package/apps/pwa/out/_next/static/chunks/{3291.f6c1005387d514bd.js → 5471.1e611302ed3a7c53.js} +2 -2
  70. package/apps/pwa/out/_next/static/chunks/5479-b6372e762719f92f.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/5534-699c5cbcbc96c5d7.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/{3086.fb14b60ce98b53d3.js → 5574.f35accf4f132b29d.js} +1 -1
  73. package/apps/pwa/out/_next/static/chunks/5701.9c4e8f250312eeee.js +24 -0
  74. package/apps/pwa/out/_next/static/chunks/{1632.7d87f998e714bede.js → 5744.b9415e18ad623100.js} +1 -1
  75. package/apps/pwa/out/_next/static/chunks/{5300.677c97e0393742e6.js → 5892.2526d962339662d8.js} +1 -1
  76. package/apps/pwa/out/_next/static/chunks/5937.c2df9e3447e1f667.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/5941.8210cc93c9202c0a.js +286 -0
  78. package/apps/pwa/out/_next/static/chunks/{7161-8f22db3ec5ed005e.js → 5947-135e26537d80a6b9.js} +3 -3
  79. package/apps/pwa/out/_next/static/chunks/{3124-561f7f037943cde2.js → 5964-7e21164a8f2cf0ce.js} +1 -1
  80. package/apps/pwa/out/_next/static/chunks/5975.4004f820ae3cecd5.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6142-7ccd48795d7abd55.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6160.bf9177b8c1bfb243.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6398.71ba0690c8027555.js +27 -0
  84. package/apps/pwa/out/_next/static/chunks/6492.2bd5c10edc1a064e.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/6552.a3840aa7da35ad68.js +62 -0
  86. package/apps/pwa/out/_next/static/chunks/6736.1e36d3ac5fa5e41d.js +24 -0
  87. package/apps/pwa/out/_next/static/chunks/6874.d5cf7eb8edb2cabe.js +2 -0
  88. package/apps/pwa/out/_next/static/chunks/6900.3ccbe069bdd4556a.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/71327eb4.add50b365f94bf3a.js +122 -0
  90. package/apps/pwa/out/_next/static/chunks/7136.deca3e3a2ddaa374.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7139-ee9f8ed2677a40b3.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{2415.738b777642a02233.js → 7191.fdc955f7d96064a4.js} +1 -1
  93. package/apps/pwa/out/_next/static/chunks/7423-e0aa5d9e2962120e.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7453.afc1ea7e05d56a8c.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7503-5e6a3d7fe67e4a0c.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/7761-476fd7bf768abd34.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/7975.eafb12097a0a9e62.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/{1026-44010f405704050c.js → 8050-9b364bdef8f71927.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/8152.64e253c35cccfaae.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/8190.620f0231b3924bcb.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/83184dcd-0ee6247ff41eb3f2.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8448.45b6b1f1a99eeb35.js +104 -0
  103. package/apps/pwa/out/_next/static/chunks/8464-e24f10451b658aac.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8477.e4c944bb3aa5d2f3.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8710.ca385257d5ca422e.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8830.627ccf294ec2465c.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8880.64c445592f04acaf.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8981.c706964c8ba27aff.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/{5638.107314dc479e2f37.js → 9048.212083de42d25be3.js} +2 -2
  110. package/apps/pwa/out/_next/static/chunks/9053.bd0fffaff8d3f836.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/9161-c66e723d7ec9d682.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9185.1ecdf9b65c0bb684.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9356.fccd5f58086b4ff5.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/9446.dc0406109371d329.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9506.dcf25d467a42627e.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/{8019.21ca554a821dad01.js → 9507.7026657a2f47eb64.js} +16 -16
  117. package/apps/pwa/out/_next/static/chunks/9541.eb8e2f8480c7feca.js +93 -0
  118. package/apps/pwa/out/_next/static/chunks/9577.ed7582186efa5482.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9579.4a8169600fff2058.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9642-ff2e039eb62e3b92.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9659-8f2323348113ad80.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9724.4c5623af2db43153.js +34 -0
  123. package/apps/pwa/out/_next/static/chunks/{6493.27ad77de7aac7966.js → 9834.63ab2bbc3153172e.js} +1 -1
  124. package/apps/pwa/out/_next/static/chunks/{3389.012c70767a872f9b.js → 9869.81a1e24ca682d5a0.js} +1 -1
  125. package/apps/pwa/out/_next/static/chunks/{8994d93e.33ba491f95345fc2.js → a0a01613.6d1cca322238d7fe.js} +1 -1
  126. package/apps/pwa/out/_next/static/chunks/{de8b930d.d94c0f42acf807fc.js → addc2b32.8c4ff8f0aefe987d.js} +1 -1
  127. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-8d9d76ea322d855c.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed2c4e59f9f1fe21.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-2dc99e03c5d76ca0.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/board/page-b5a3a788330e920f.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-866aac5ff226a7f3.js → page-14949db884bfa672.js} +1 -1
  132. package/apps/pwa/out/_next/static/chunks/app/bots/page-ea76c85b36388a97.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/ceo/page-01716d20af62d325.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/chat/page-62baf6881a64b1e9.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/consult/page-f89ba590c2af8afa.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/control/page-22f8b0f78d9637e5.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/decisions/page-817f9d7e6820be80.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/design-check/page-ffb9bc0d2650249a.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/editor/page-f6d0e64873c0f629.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/exec/page-8bfa0d4ba23a209d.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/field/page-f5060462249e32c7.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/healthz/route-8d9d76ea322d855c.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/inside/page-b2049f8b1ef79117.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/intake/page-1446c5fa93907f11.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/layout-b48a7a07c5204156.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/live/page-e974b8c4ca47614c.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/live-run/page-8a919b869bd28594.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/loops/page-d31b8de6bfcd72ed.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/market/page-64765f817909db29.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-d128c8569a36ee9b.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/morning/page-b2679d357e9b9270.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/not-found-6fabec98a9e7b269.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/observatory/page-048f30149dcf1349.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-9113181d6b5a2725.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-40f9e19149024298.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-1e7a755a13227611.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3c8f8b67a203cf07.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/page-18032f5437215062.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/reflection/page-da3b739192fd0ee3.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d332545571bd6fd1.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/sessions/page-5237aa5b3f3b8ec5.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a142dfb0331a05f5.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/settings/page-d16e56c3989c147e.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6b6593600869e2cd.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/setup/layout-8d9d76ea322d855c.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/setup/page-29e8b8a8396b55cb.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/share/page-b3414d856a1a7e2f.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c3affa52b7ce961b.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f21dddf9f95b6fab.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/term/page-f5a30a24745bf088.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/today/page-8c8569a09b4d4e34.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/trace/page-2ce32722c0243483.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/vault/page-4767b0d9c0a98c6c.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-116ee1339c387a75.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/app/workflows/page-35e8c50ca4ef7ffc.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/app/workspace/page-52e17113356bb891.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7458ae05ed2ac1a0.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/b2271e54.c1de3347976e90b0.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/{b7459770.6539b11860eb8a9c.js → c0c1a699.0ba79f97005965d4.js} +7 -7
  180. package/apps/pwa/out/_next/static/chunks/framework-ad6c9dd524ad6ef8.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/main-app-2ddd1f2b44d6aa59.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/main-e3d82bdc358d20c5.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/pages/_app-71d5aa3896e1655f.js +1 -0
  184. package/apps/pwa/out/_next/static/chunks/pages/_error-03ffc54e00438546.js +1 -0
  185. package/apps/pwa/out/_next/static/chunks/webpack-56bb89af5a611d0b.js +1 -0
  186. package/apps/pwa/out/approvals/index.html +1 -1
  187. package/apps/pwa/out/approvals/index.txt +22 -22
  188. package/apps/pwa/out/autopilot/index.html +1 -1
  189. package/apps/pwa/out/autopilot/index.txt +22 -22
  190. package/apps/pwa/out/board/index.html +1 -1
  191. package/apps/pwa/out/board/index.txt +22 -22
  192. package/apps/pwa/out/botlab/index.html +1 -1
  193. package/apps/pwa/out/botlab/index.txt +21 -21
  194. package/apps/pwa/out/bots/index.html +1 -1
  195. package/apps/pwa/out/bots/index.txt +21 -21
  196. package/apps/pwa/out/ceo/index.html +1 -1
  197. package/apps/pwa/out/ceo/index.txt +22 -22
  198. package/apps/pwa/out/chat/index.html +1 -1
  199. package/apps/pwa/out/chat/index.txt +21 -21
  200. package/apps/pwa/out/consult/index.html +1 -1
  201. package/apps/pwa/out/consult/index.txt +22 -22
  202. package/apps/pwa/out/control/index.html +1 -1
  203. package/apps/pwa/out/control/index.txt +22 -22
  204. package/apps/pwa/out/decisions/index.html +1 -1
  205. package/apps/pwa/out/decisions/index.txt +21 -21
  206. package/apps/pwa/out/design-check/index.html +1 -1
  207. package/apps/pwa/out/design-check/index.txt +22 -22
  208. package/apps/pwa/out/editor/index.html +1 -1
  209. package/apps/pwa/out/editor/index.txt +22 -22
  210. package/apps/pwa/out/exec/index.html +1 -1
  211. package/apps/pwa/out/exec/index.txt +22 -22
  212. package/apps/pwa/out/field/index.html +1 -1
  213. package/apps/pwa/out/field/index.txt +22 -22
  214. package/apps/pwa/out/healthz +1 -1
  215. package/apps/pwa/out/index.html +1 -1
  216. package/apps/pwa/out/index.txt +21 -21
  217. package/apps/pwa/out/inside/index.html +1 -1
  218. package/apps/pwa/out/inside/index.txt +21 -21
  219. package/apps/pwa/out/intake/index.html +1 -1
  220. package/apps/pwa/out/intake/index.txt +22 -22
  221. package/apps/pwa/out/live/index.html +1 -1
  222. package/apps/pwa/out/live/index.txt +22 -22
  223. package/apps/pwa/out/live-run/index.html +1 -1
  224. package/apps/pwa/out/live-run/index.txt +22 -22
  225. package/apps/pwa/out/loops/index.html +1 -1
  226. package/apps/pwa/out/loops/index.txt +21 -21
  227. package/apps/pwa/out/market/index.html +1 -1
  228. package/apps/pwa/out/market/index.txt +21 -21
  229. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  230. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  231. package/apps/pwa/out/morning/index.html +1 -1
  232. package/apps/pwa/out/morning/index.txt +22 -22
  233. package/apps/pwa/out/observatory/index.html +1 -1
  234. package/apps/pwa/out/observatory/index.txt +22 -22
  235. package/apps/pwa/out/ops/checklist/index.html +1 -1
  236. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  237. package/apps/pwa/out/ops/release/index.html +1 -1
  238. package/apps/pwa/out/ops/release/index.txt +21 -21
  239. package/apps/pwa/out/ops/seats/index.html +1 -1
  240. package/apps/pwa/out/ops/seats/index.txt +21 -21
  241. package/apps/pwa/out/outputs/index.html +1 -1
  242. package/apps/pwa/out/outputs/index.txt +21 -21
  243. package/apps/pwa/out/reflection/index.html +1 -1
  244. package/apps/pwa/out/reflection/index.txt +22 -22
  245. package/apps/pwa/out/scheduler/index.html +1 -1
  246. package/apps/pwa/out/scheduler/index.txt +22 -22
  247. package/apps/pwa/out/sessions/index.html +1 -1
  248. package/apps/pwa/out/sessions/index.txt +21 -21
  249. package/apps/pwa/out/settings/devices/index.html +1 -1
  250. package/apps/pwa/out/settings/devices/index.txt +22 -22
  251. package/apps/pwa/out/settings/index.html +1 -1
  252. package/apps/pwa/out/settings/index.txt +22 -22
  253. package/apps/pwa/out/setup/done/index.html +1 -1
  254. package/apps/pwa/out/setup/done/index.txt +22 -22
  255. package/apps/pwa/out/setup/index.html +1 -1
  256. package/apps/pwa/out/setup/index.txt +22 -22
  257. package/apps/pwa/out/share/index.html +1 -1
  258. package/apps/pwa/out/share/index.txt +22 -22
  259. package/apps/pwa/out/showroom/index.html +1 -1
  260. package/apps/pwa/out/showroom/index.txt +21 -21
  261. package/apps/pwa/out/tasks/index.html +1 -1
  262. package/apps/pwa/out/tasks/index.txt +22 -22
  263. package/apps/pwa/out/term/index.html +1 -1
  264. package/apps/pwa/out/term/index.txt +22 -22
  265. package/apps/pwa/out/today/index.html +1 -1
  266. package/apps/pwa/out/today/index.txt +22 -22
  267. package/apps/pwa/out/trace/index.html +1 -1
  268. package/apps/pwa/out/trace/index.txt +22 -22
  269. package/apps/pwa/out/vault/index.html +1 -1
  270. package/apps/pwa/out/vault/index.txt +22 -22
  271. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  272. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  273. package/apps/pwa/out/workflows/index.html +1 -1
  274. package/apps/pwa/out/workflows/index.txt +22 -22
  275. package/apps/pwa/out/workspace/index.html +1 -1
  276. package/apps/pwa/out/workspace/index.txt +22 -22
  277. package/apps/pwa/out/worktrees/index.html +1 -1
  278. package/apps/pwa/out/worktrees/index.txt +22 -22
  279. package/bin/elanous.mjs +6 -1
  280. package/catalog/models/openai/gpt-6.1-sol.yaml +16 -0
  281. package/catalog/models/openai/gpt-6.1-terra.yaml +16 -0
  282. package/graphs/demo/persona-marketer/fixtures/marketer-scenario.yaml +10 -0
  283. package/graphs/demo/persona-marketer/persona-marketer.yaml +25 -0
  284. package/graphs/demo/persona-marketer/recipes.yaml +19 -0
  285. package/graphs/demo/persona-teacher/lesson-pack.yaml +16 -0
  286. package/graphs/demo/persona-teacher/recipes.yaml +17 -0
  287. package/graphs/demo/persona-teacher/weekly-lesson.yaml +36 -0
  288. package/graphs/overlays/stop-heal-ladder.yaml +23 -2
  289. package/graphs/release/release-loop.yaml +3 -1
  290. package/graphs/units/gate/gate.yaml +20 -0
  291. package/graphs/units/git/git.yaml +26 -0
  292. package/graphs/units/implement/implement.yaml +19 -0
  293. package/graphs/units/landing/landing.yaml +18 -0
  294. package/graphs/units/review/review.yaml +20 -0
  295. package/graphs/units/verbs/recipes.yaml +3 -0
  296. package/graphs/units/verbs/research.yaml +20 -0
  297. package/graphs/video/explainer-line.yaml +4 -1
  298. package/graphs/work/research-report.yaml +11 -1
  299. package/package.json +1 -1
  300. package/scripts/dead-code/report.ts +169 -0
  301. package/scripts/disk-steward.ts +46 -0
  302. package/scripts/fleet/node-setup.sh +50 -0
  303. package/scripts/graph-units/verbs/research.ts +55 -0
  304. package/scripts/lib/morning-report-options.ts +3 -4
  305. package/scripts/lib/tui-regress-evidence.ts +56 -0
  306. package/scripts/llm-cost-ledger.ts +179 -8
  307. package/scripts/measure-nl-routing-corpus.ts +10 -2
  308. package/scripts/morning-report.ts +5 -1
  309. package/scripts/persona-teacher/weekly-lesson-node.ts +172 -0
  310. package/scripts/public-copy-lint.ts +163 -19
  311. package/scripts/public-export.ts +15 -7
  312. package/scripts/ratchets/train-side-invariants.sh +0 -1
  313. package/scripts/release-loop/export-check-node.ts +21 -3
  314. package/scripts/release-loop/gate-autoheal.ts +117 -0
  315. package/scripts/release-loop/gate-baseline-receipt.ts +8 -1
  316. package/scripts/release-loop/gate-diff.ts +22 -3
  317. package/scripts/release-loop/gate-node.ts +583 -64
  318. package/scripts/release-loop/gate-shard-dispatch.ts +128 -0
  319. package/scripts/release-loop/gate-shard-load-flaky.ts +256 -0
  320. package/scripts/release-loop/gate-shard-receipts.ts +89 -0
  321. package/scripts/release-loop/gate-triage-node.ts +70 -10
  322. package/scripts/release-loop/gate-wall.ts +5 -5
  323. package/scripts/release-loop/preflight.ts +6 -2
  324. package/scripts/release-loop/resume-release.ts +267 -20
  325. package/scripts/release-loop/resume.ts +48 -0
  326. package/scripts/release-loop/traffic-node.ts +6 -3
  327. package/scripts/release-loop/unattended-release.ts +4 -2
  328. package/scripts/release-loop/version-node.ts +7 -2
  329. package/scripts/release-story/draft.ts +1 -1
  330. package/scripts/research-bench/README.md +53 -0
  331. package/scripts/research-bench/questions.json +66 -0
  332. package/scripts/research-bench/rubric.md +33 -0
  333. package/scripts/research-bench/run.ts +523 -0
  334. package/scripts/shadow-authoring-probe.ts +20 -0
  335. package/scripts/tui-regress.ts +85 -10
  336. package/scripts/ux-sim.ts +19 -2
  337. package/src/acp/core-turn-bridge.ts +94 -4
  338. package/src/agent/autonomous-tools.ts +10 -3
  339. package/src/agent/monad-agent-turn.ts +4 -1
  340. package/src/agent/registry.ts +26 -2
  341. package/src/agent/shared-app-tools.ts +1 -1
  342. package/src/agent/surface-ux/build.ts +12 -3
  343. package/src/agent/surface-ux/types.ts +1 -1
  344. package/src/agent/task-notification.ts +75 -6
  345. package/src/agent/types.ts +3 -0
  346. package/src/agent-mission/driver.ts +29 -3
  347. package/src/agent-mission/mission-cli.ts +2 -1
  348. package/src/agent-substrate/review-context-pack.ts +365 -0
  349. package/src/agent-substrate/self-review-cli.ts +291 -20
  350. package/src/ask-user-question/index.ts +6 -0
  351. package/src/ask-user-question/inline-resolver.ts +49 -0
  352. package/src/auto-research/question-ladder-contract.ts +22 -3
  353. package/src/auto-research/research-turn.ts +359 -17
  354. package/src/autopilot/agent-loop.ts +1 -1
  355. package/src/autopilot/discovery/wiki-claim-proposer.ts +22 -1
  356. package/src/autopilot/pty-control-loop.ts +8 -1
  357. package/src/boot/daemon-tools/index.ts +4 -3
  358. package/src/boot/daemon-tools/self-implement.ts +312 -7
  359. package/src/boot/daemon-tools/types.ts +2 -0
  360. package/src/budget/llm-cost.ts +44 -5
  361. package/src/budget/shadow-arms.ts +52 -0
  362. package/src/budget/unified-usage.ts +17 -1
  363. package/src/capture/tui-self-report.ts +14 -0
  364. package/src/chat/index.ts +33 -7
  365. package/src/chat/pickers/state.ts +7 -1
  366. package/src/cli/agent-cli.ts +43 -8
  367. package/src/cli/intake-cli.ts +22 -1
  368. package/src/cli/lesson-cli.ts +19 -3
  369. package/src/cli/log-event-names.ts +6 -0
  370. package/src/cli/mcp-login.ts +8 -18
  371. package/src/cli/msg-cli.ts +57 -1
  372. package/src/cli/pod-cli.ts +17 -2
  373. package/src/cli/pr-land-heavy-remote.ts +15 -9
  374. package/src/cli/pty-takeover-cli.ts +67 -7
  375. package/src/cli/release-cli.ts +79 -7
  376. package/src/cli/repo-cli.ts +2 -1
  377. package/src/cli/sim-cli.ts +7 -1
  378. package/src/cli/tasks-cli.ts +41 -13
  379. package/src/codex/models.ts +30 -15
  380. package/src/control-plane/ledger.ts +21 -4
  381. package/src/core-turn/run-core-turn.ts +47 -3
  382. package/src/core-turn/run-goal-loop.ts +240 -10
  383. package/src/core-turn/types.ts +9 -0
  384. package/src/dashboard/acp-boot.ts +72 -3
  385. package/src/dashboard/chat/acp-chat.ts +2 -2
  386. package/src/dashboard/classic-sigquit.ts +16 -0
  387. package/src/dashboard/index.ts +327 -27
  388. package/src/dashboard/input/chat-main-interaction-opts.ts +3 -0
  389. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +7 -2
  390. package/src/dashboard/input/chat-main-slash-command.ts +7 -0
  391. package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
  392. package/src/dashboard/input/dashboard-priority-key-route.ts +21 -5
  393. package/src/dashboard/input/external-input-host.ts +2 -0
  394. package/src/dashboard/sidetab-runtime.ts +228 -0
  395. package/src/dashboard/slash-runtime/ask-clarification.ts +7 -1
  396. package/src/dashboard/slash-runtime/dashboard-handlers.ts +20 -8
  397. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -2
  398. package/src/dashboard/term-slash-runtime.ts +16 -18
  399. package/src/dashboard/turn-preamble.ts +14 -1
  400. package/src/disk-steward/judge.ts +73 -0
  401. package/src/disk-steward/ledger.ts +122 -0
  402. package/src/disk-steward/steward.ts +373 -0
  403. package/src/domains/guardian-tick.ts +191 -2
  404. package/src/domains/knowledge.ts +1 -1
  405. package/src/esc-abort-gate.ts +33 -1
  406. package/src/execution-loop/launch-gate.ts +206 -1
  407. package/src/graph-runner/graph-cli.ts +27 -4
  408. package/src/graph-runner/in-process-registry.ts +37 -0
  409. package/src/graph-runner/runner.ts +63 -11
  410. package/src/graph-wizard/generate.ts +16 -7
  411. package/src/graph-wizard/mission-compose.ts +201 -0
  412. package/src/grok/agent-search.ts +8 -2
  413. package/src/grok/credential.ts +5 -0
  414. package/src/grounding/ref-index.ts +30 -0
  415. package/src/grounding/ref-vector.ts +61 -0
  416. package/src/grounding/sources-cli.ts +11 -3
  417. package/src/grounding/sources.ts +15 -1
  418. package/src/harness/harness-cli-command.ts +305 -23
  419. package/src/harness/harness-incidents.ts +312 -7
  420. package/src/harness/harness-pod-dispatch.ts +7 -1
  421. package/src/harness/harness-space.ts +15 -1
  422. package/src/harness/progress-worker-entry.ts +59 -0
  423. package/src/harness/progress-worker-runtime.ts +11 -0
  424. package/src/index.ts +35 -5
  425. package/src/input/external-input-queue.ts +10 -0
  426. package/src/instance/dev-project.ts +25 -0
  427. package/src/intake-plane/collect-telegram-saved.ts +36 -1
  428. package/src/intake-plane/intake-to-tasks.ts +246 -3
  429. package/src/intelligence-map/model-alias.ts +6 -5
  430. package/src/intelligence-map/model-catalog.ts +59 -2
  431. package/src/lessons/friction-ledger.ts +154 -0
  432. package/src/live-supply/collector.ts +149 -0
  433. package/src/live-supply/probes.ts +52 -0
  434. package/src/live-supply/snapshot.ts +40 -0
  435. package/src/llm/model-defaults.ts +4 -4
  436. package/src/llm.ts +473 -87
  437. package/src/loops/orchestrator/tick.ts +56 -0
  438. package/src/mcp/mcp-oauth.ts +3 -1
  439. package/src/model-tier/llm-tier-map.ts +9 -9
  440. package/src/model-tier/turn-tier.ts +1 -1
  441. package/src/msg/msg-mirror-github.ts +80 -0
  442. package/src/msg/msg-mirror-policy.ts +61 -0
  443. package/src/msg/msg-mirror-runner.ts +219 -0
  444. package/src/msg/msg-mirror-state.ts +33 -0
  445. package/src/msg/msg-store.ts +11 -0
  446. package/src/nexus/api/harness-api.ts +2 -1
  447. package/src/output-truncation.ts +41 -12
  448. package/src/project/project-store.ts +48 -1
  449. package/src/pty/snapshot.py +132 -0
  450. package/src/pty-shell/pty-control-ipc.ts +29 -2
  451. package/src/pty-shell/pty-manifest.ts +59 -3
  452. package/src/pty-shell/registry.ts +2 -0
  453. package/src/pty-shell/tui-run-state.ts +80 -3
  454. package/src/release-loop/gate-host-reservation.ts +157 -4
  455. package/src/release-loop/gate-shard-ledger.ts +68 -0
  456. package/src/release-loop/merged-pr-checklist.ts +25 -2
  457. package/src/release-loop/rehearsal-shard-plan.ts +6 -1
  458. package/src/release-loop/rehearsal.ts +27 -0
  459. package/src/release-loop/release-schedule.ts +90 -1
  460. package/src/research/bloom-exemplars.ts +135 -0
  461. package/src/research/edge-decision.ts +124 -15
  462. package/src/research/gap-followup.ts +249 -0
  463. package/src/research/lenses/counter-evidence.ts +100 -0
  464. package/src/research/lenses/working-backwards.ts +89 -0
  465. package/src/research/plugin-discovery.ts +242 -0
  466. package/src/research-bridge/invoke.ts +4 -2
  467. package/src/research-bridge/types.ts +2 -0
  468. package/src/self-dev/ask-launch-flow.ts +73 -131
  469. package/src/self-dev/dev-cli.ts +19 -17
  470. package/src/self-dev/dev-pipeline.ts +8 -4
  471. package/src/self-dev/graph-front-nodes.ts +23 -0
  472. package/src/self-dev/graph-journey-route.ts +10 -2
  473. package/src/self-dev/launch-preflight-text.ts +2 -2
  474. package/src/self-dev/launch-preflight.ts +47 -11
  475. package/src/self-dev/orchestrate-cli.ts +1 -0
  476. package/src/self-dev/orchestrate.ts +15 -0
  477. package/src/self-dev/run-supervisor.ts +204 -3
  478. package/src/self-dev/run-types.ts +3 -0
  479. package/src/self-implement/device-first.ts +8 -2
  480. package/src/self-implement/doctor-visit.ts +76 -58
  481. package/src/self-implement/gate-artifacts.ts +16 -0
  482. package/src/self-implement/gate-baseline.ts +75 -4
  483. package/src/self-implement/gate-cli.ts +368 -30
  484. package/src/self-implement/gate-receipt-registry.ts +180 -0
  485. package/src/self-implement/gate-remote.ts +165 -24
  486. package/src/self-implement/goal-author-clarification.ts +205 -32
  487. package/src/self-implement/goal-author-decompose.ts +24 -15
  488. package/src/self-implement/goal-author.ts +86 -10
  489. package/src/self-implement/graph-stage-units.ts +172 -0
  490. package/src/self-implement/graph-templates.ts +162 -1
  491. package/src/self-implement/graph-variant.ts +37 -4
  492. package/src/self-implement/host-regate.ts +124 -49
  493. package/src/self-implement/impl-findings-feedback.ts +188 -0
  494. package/src/self-implement/knowhow-pack.ts +227 -10
  495. package/src/self-implement/off-diff-evidence.ts +124 -0
  496. package/src/self-implement/orchestrator.ts +320 -28
  497. package/src/self-implement/run-ledger.ts +110 -14
  498. package/src/self-implement/run-stop.ts +33 -2
  499. package/src/self-implement/running-runs.ts +35 -12
  500. package/src/self-implement/seams.ts +6 -3
  501. package/src/self-implement/self-implement-cli.ts +40 -6
  502. package/src/self-implement/stop-autoheal-operational.ts +43 -0
  503. package/src/self-implement/stop-autoheal.ts +15 -6
  504. package/src/session/chat.ts +66 -15
  505. package/src/session/request-size-guard.ts +123 -0
  506. package/src/session-runtime/provider-circuit.ts +140 -0
  507. package/src/shell-runner/file-engine.ts +1 -0
  508. package/src/shell-runner/types.ts +4 -0
  509. package/src/sidetab-core/model.ts +312 -0
  510. package/src/skills/tools/schedule-wakeup.ts +23 -1
  511. package/src/skills/tools/shell.ts +51 -5
  512. package/src/steward/directive-audit.ts +354 -0
  513. package/src/surface/child-process.ts +31 -0
  514. package/src/surface/tui-stderr-owner.ts +48 -0
  515. package/src/task-agent/cover.ts +30 -12
  516. package/src/task-agent/judge.ts +56 -0
  517. package/src/task-agent/parent-host.ts +14 -1
  518. package/src/task-agent/postland-card.ts +35 -2
  519. package/src/task-agent/rejudge-on-head.ts +46 -2
  520. package/src/task-agent/repair-cycle.ts +1 -1
  521. package/src/task-agent/task-hand.ts +133 -25
  522. package/src/task-agent/tier-split.ts +105 -21
  523. package/src/task-orchestrator/surfaces/pod-command-job.ts +330 -2
  524. package/src/task-orchestrator/surfaces/pod-config-snapshot.ts +123 -0
  525. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +70 -2
  526. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +29 -4
  527. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +11 -8
  528. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +1 -1
  529. package/src/task-orchestrator/surfaces/pod-source-receive.ts +74 -6
  530. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +2 -1
  531. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +56 -15
  532. package/src/task-orchestrator/surfaces/self-implement-pod.ts +298 -45
  533. package/src/task-orchestrator/surfaces/self-implement.ts +18 -0
  534. package/src/tool-runtime/skill-exec-runtime.ts +95 -5
  535. package/src/tui/entry.ts +25 -5
  536. package/src/tui/inline-choice.ts +188 -0
  537. package/src/tui/sidetab/list.ts +36 -165
  538. package/src/tui/sidetab/nl-tool.ts +2 -136
  539. package/src/tui/sidetab/peek.ts +52 -0
  540. package/src/tui/slash/term.ts +12 -1
  541. package/src/tui-client/dashboard-session.ts +10 -1
  542. package/src/user-config.ts +45 -9
  543. package/src/ux-sim/classic-tui-seat-scenarios.ts +1 -7
  544. package/src/ux-sim/fake-land-queue.ts +88 -0
  545. package/src/ux-sim/fault-needs-human-reason-repair.ts +107 -0
  546. package/src/ux-sim/fault-pod-child-result.ts +42 -0
  547. package/src/ux-sim/gate-shard-host-reroute.ts +82 -0
  548. package/src/ux-sim/goal-interim-trace.ts +24 -0
  549. package/src/ux-sim/next-tui-seat-scenarios.ts +8 -13
  550. package/src/ux-sim/release-sim-rig.ts +262 -0
  551. package/src/ux-sim/seminar-rehearsal.ts +109 -0
  552. package/src/ux-sim/subagent-tools-device.ts +2 -2
  553. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +4 -1
  554. package/src/version/packed-revision.json +1 -1
  555. package/src/video-pipeline/recipes/explainer.ts +54 -2
  556. package/src/web-search/grok.ts +32 -6
  557. package/src/web-search/index.ts +8 -7
  558. package/src/workflow-runtime/node-catalog.ts +53 -4
  559. package/apps/pwa/out/_next/static/chunks/1118.a8a74ea29aac3e46.js +0 -27
  560. package/apps/pwa/out/_next/static/chunks/1204-2aa830479adf80f4.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/1341-43b7d2dc77d45c9d.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/1440-c3ea8882badfd9bf.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/1698-9c11cbf97f13717e.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/1770-3b1fc92253ef9f2f.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/1923-5c1695332240246a.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/1938.0e6c60ee91c4d7f5.js +0 -148
  567. package/apps/pwa/out/_next/static/chunks/2104.70e086d5174a4736.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/213-20675f20673ba22a.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/214.186a430da28338f1.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/2277.3bd4c0ac7f1b5996.js +0 -93
  571. package/apps/pwa/out/_next/static/chunks/240.e09f433f71c78ff4.js +0 -104
  572. package/apps/pwa/out/_next/static/chunks/2417.02151393605a7cd0.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/2463.cd2641a76daaa9ff.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/2576.b9e9c629c4b84c52.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/265-c021de53f0865bd9.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/2998-b1cc13956cd6a6e7.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/2e4782d3.ba2f0ab2b63a53e7.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/3130.626b54382b4dc379.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/3221-1bb3f99a55088613.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/3280.24edb1ffd03a7f3f.js +0 -24
  581. package/apps/pwa/out/_next/static/chunks/3288-eb3c22a1cbf2ae68.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/33.ef99e8374f96c6c4.js +0 -36
  583. package/apps/pwa/out/_next/static/chunks/3341-f09b9efbd7a82f70.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/3410-d7c0f14b329d6fda.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/3421.c87d6313a7d670f7.js +0 -287
  586. package/apps/pwa/out/_next/static/chunks/3422-83a3953f9bd67e26.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/3587-002e24e368c515a9.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/3644.f12a7d821ab940af.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/3660.d7516588e2d875c3.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/3695.b82e2610f4cd4ea9.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/3858.ca1f5bc0f577eac9.js +0 -94
  592. package/apps/pwa/out/_next/static/chunks/3959-e6ac4a139d9d4bcc.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/3f0de3de-2340c532c00395db.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/4032.53f62176514ec0ea.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/4199-f7c6eb40cd0322f8.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/4204-ef8484cbecd5d62f.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/4259-163129ca79913c4b.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/428-eaa77df3d0c85969.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/4432-97e400ffa1e161f5.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/449-aa427cf2cbb75f50.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/4491-39a0fd32bbaf3840.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/4588.b7cf06d382953979.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/4690.70ec8060825366ab.js +0 -32
  604. package/apps/pwa/out/_next/static/chunks/4804.6012b5cd33c22792.js +0 -90
  605. package/apps/pwa/out/_next/static/chunks/4881.e4d22d730e3b9df5.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/4937.ce2e340dc29cad3e.js +0 -79
  607. package/apps/pwa/out/_next/static/chunks/5-bb1c08d84bd71df3.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/5005.de98df23b37cdf3c.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/5035.dc64a89cad5573cc.js +0 -74
  610. package/apps/pwa/out/_next/static/chunks/5041-5aada92ca215ffdd.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/5207.1a224035455790fd.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/5255-1b60d50eabe9f057.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/5269.d0436ee6d773382a.js +0 -286
  614. package/apps/pwa/out/_next/static/chunks/5309.3367c4d50f52b489.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/552-689827d49780fa00.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/5539.34cc9d60622cb69b.js +0 -8
  617. package/apps/pwa/out/_next/static/chunks/5568.218dea0c00ca2ec7.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/5645.b7e3b055455a04ea.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/5662.18cc0f30353cbd96.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/5671.da24fc9dc5e98325.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/5b141171.324c40fd49cb6821.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/6175-d4621f6a10b0cfab.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/6290.3eb53a20746b72ce.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/6415-9307f3eafa90837f.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/6579-3de35d00aacd71b5.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/680-2f324c4e039a5b67.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/6845-331b3c7481da3ba3.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/7000.28157393caaf5343.js +0 -62
  629. package/apps/pwa/out/_next/static/chunks/7311-60a7ea80d23c7521.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/7401.525d0a12f7d02c06.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/7438.c2cf72b66dca6aa4.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/7488.966b116789f3d41a.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/7524.ce973525d30b3d52.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/7577.ea6e9ac72e035520.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/7628.6b16863ac3972333.js +0 -34
  636. package/apps/pwa/out/_next/static/chunks/7657.8d1fb3d2f7ebe273.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/7903-1435d5d2f0dd7807.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/7954.4f7a8832663ee979.js +0 -115
  639. package/apps/pwa/out/_next/static/chunks/7978-30a91192c5dbe3c2.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/8025-8795821525cf1a07.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/8191.3674a00f0b565c23.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/8217-604955d8885c5ef2.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/8298-eed6f5f2585a63f4.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/8509.3a54d4e61893d7cb.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/8758.ac421f726a189125.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/891.d6c723a51a067b36.js +0 -149
  647. package/apps/pwa/out/_next/static/chunks/9223.cbcc88e0e9950426.js +0 -41
  648. package/apps/pwa/out/_next/static/chunks/9299.24e2a7d9b6d1f91b.js +0 -226
  649. package/apps/pwa/out/_next/static/chunks/9317.6a9869039c231bb3.js +0 -24
  650. package/apps/pwa/out/_next/static/chunks/9383.e4755f275b3c11ff.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/9581.da63ddf41acfad46.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/9715.8c5529a0a5c41a36.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/9817.3009d65f0889ef1f.js +0 -2
  654. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76873dd80da4f715.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed32b6ec5dea8f23.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-fdd40e15babf3d25.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/board/page-384efc78e85e400b.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/bots/page-d91809c5aeed319a.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/ceo/page-128f3522f89a81ab.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/chat/page-595961abf3b43ad1.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/consult/page-f41dccb76d8c0263.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/control/page-a3205c2e28b7d0d9.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/decisions/page-c39a80277814a3f4.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/design-check/page-1ab3f98194513195.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/editor/page-a5246f7e254d77d0.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/exec/page-0f92287bdb81217d.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/field/page-5a37131ff63793ef.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/healthz/route-76873dd80da4f715.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/inside/page-ac4bd14bb2348bfd.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/intake/page-c348a3959c5b5fc6.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/layout-2addd81c0d3e2906.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/live/page-da6b765f58a3eefb.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/live-run/page-0661e40f8780c32c.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/loops/page-b89af1b1c8e4875b.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/market/page-da8aeb82ba751cdb.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-cc71317b239439db.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/morning/page-bde7fc1d64ffe369.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/not-found-e2797214f713fa58.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/observatory/page-2a35bcda70defaf6.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3af03deedde45032.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-d1d1210f99f620ae.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-46d1b5500885861d.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/outputs/page-291ab19fe2acb173.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/page-7f569e533ddeecba.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/reflection/page-990129c9fee46d8f.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-7737f785ebb1cdaf.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9f3c73a4f7ffd2f8.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-03be7fb347f01058.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/app/settings/page-96b0280625e4df2b.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-56855545049eb56d.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/app/setup/layout-76873dd80da4f715.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/app/setup/page-79a909c9981f0338.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/app/share/page-a9d9a3e66459c1e0.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c383cbf2013f7069.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f57c6a2e54dbdca4.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/term/page-6b140f77593576eb.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/today/page-6b767ae2d9d0adfc.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/trace/page-116d6198d5da0e3d.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/vault/page-b9c9b778c7501370.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-a6c78392ab8f6335.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/app/workflows/page-455183deb4ed0cfe.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6a63e99526bd63d0.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-31c22caafe788c08.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/bb6987f9.3647e1a23b0e3217.js +0 -122
  705. package/apps/pwa/out/_next/static/chunks/framework-4b12a946f352cee2.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/main-941155250ed2644b.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/main-app-f8b6765abed6d149.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/pages/_app-78432194c85388f9.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/pages/_error-cdf7390829512b1b.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/webpack-d5f0964a9c2e92d2.js +0 -1
  711. package/scripts/ratchets/next-tui-entry-budget.ts +0 -124
  712. /package/apps/pwa/out/_next/static/{RrjXTwz-urRAbChP1bX02 → GiOLWmt4MqDZePubBjA4Q}/_ssgManifest.js +0 -0
@@ -1,10 +1,12 @@
1
1
  import { Database } from 'bun:sqlite';
2
+ import { createHash } from 'node:crypto';
2
3
  import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync } from 'node:fs';
3
4
  import { join } from 'node:path';
4
5
  import { redactSecretText } from '../debug/log.js';
5
6
  import { refuseProductionLedgerWriteInTest } from './ledger-write-guard.js';
6
7
  import type { PodChildEvidence } from '../task-orchestrator/surfaces/self-implement.js';
7
8
  import { parsePodTermination, type PodTermination } from '../task-orchestrator/surfaces/pod-failure-reason.js';
9
+ import { loadRunLedger, runLedgerDir, type RunLedgerEntry } from '../self-implement/run-ledger.js';
8
10
 
9
11
  export interface RunExit {
10
12
  runId: string;
@@ -21,6 +23,21 @@ export interface RunExit {
21
23
  childEvidence?: PodChildEvidence;
22
24
  /** JOB-FAILURE-TERMINATION-CAPTURE — the current attempt's Job/Pod termination facts, captured before GC. */
23
25
  podTermination?: PodTermination;
26
+ /** Current Pod attempt + bounded child output + container exit + parent verdict, joined under this runId. */
27
+ terminalEvidence?: {
28
+ job: string;
29
+ childRunId: string;
30
+ attempt: number | 'unknown';
31
+ childOutputTail: string[] | 'unknown';
32
+ containerExitCode: number | 'unknown';
33
+ parentVerdict: string;
34
+ failureClassification: string | 'unknown';
35
+ terminationReason: string | 'unknown';
36
+ childFailureStage: string | 'unknown';
37
+ childRunStatus: { stage: string | 'unknown'; status: string | 'unknown'; failureKind: string | 'unknown' };
38
+ shardIdentityReadFailure: string | 'none' | 'unknown';
39
+ providerFailure: 'credential-not-configured' | 'provider-failed' | 'none' | 'unknown';
40
+ };
24
41
  /** INCIDENT-REASON-FROM-LASTLINES — 기록된 reason 이 unknown 이라 lastLines 로 다시 분류했으면 원래 값. */
25
42
  recordedReason?: string;
26
43
  /** reason 을 어디서 얻었나 — 'lastLines' 면 위 분류 규칙으로 정했다(기록 원문은 recordedReason). */
@@ -40,12 +57,132 @@ export interface IncidentBurst {
40
57
  hostname?: string;
41
58
  }
42
59
 
60
+ export type TcellHealthClass = 'healthy' | 'slow' | 'stalled' | 'infected' | 'zombie';
61
+
62
+ /** A read-only health-card snapshot supplied to the guardian tick. Times are epoch milliseconds. */
63
+ export interface TcellHealthCard {
64
+ runId: string;
65
+ stage: string;
66
+ startedAt: number;
67
+ progressAt: number | null;
68
+ stageBudgetMs: number;
69
+ heartbeatAt: number | null;
70
+ parentPresent: boolean;
71
+ leaseExpiresAt: number | null;
72
+ riskSignal: boolean;
73
+ stopClass?: string;
74
+ site?: string;
75
+ /** Stable signature tail, already bounded by the producer. Raw log tails are not accepted here. */
76
+ signatureTail?: string;
77
+ /** Deliberately excluded from cause grouping. */
78
+ hostname?: string;
79
+ }
80
+
81
+ export interface TcellHealthDecision {
82
+ runId: string;
83
+ stage: string;
84
+ classification: TcellHealthClass;
85
+ reason: 'heartbeat-missing' | 'parent-missing' | 'lease-expired' | 'risk-signal' | 'cause-quorum' | 'no-progress-30m' | 'over-stage-budget' | 'within-stage-budget';
86
+ causeGroupId?: string;
87
+ causeGroupSize?: number;
88
+ }
89
+
90
+ export interface TcellHealthClassification {
91
+ total: number;
92
+ measured: number;
93
+ unmeasuredRunIds: string[];
94
+ counts: Record<TcellHealthClass, number>;
95
+ decisions: TcellHealthDecision[];
96
+ }
97
+
98
+ const TCELL_STALLED_AFTER_MS = 30 * 60_000;
99
+ const TCELL_CAUSE_QUORUM = 3;
100
+
101
+ function tcellCauseGroupId(card: TcellHealthCard): string | undefined {
102
+ const stopClass = card.stopClass?.trim();
103
+ const site = card.site?.trim();
104
+ const signatureTail = card.signatureTail?.trim();
105
+ if (!stopClass || !site || !signatureTail) return undefined;
106
+ // Hash the exact stop.class + site + signature-tail tuple. Host is deliberately absent.
107
+ return createHash('sha256').update(JSON.stringify([stopClass, site, signatureTail])).digest('hex').slice(0, 16);
108
+ }
109
+
110
+ /** Pure shadow classification. Invalid/incomplete cards are reported as unmeasured, never as healthy or zombie. */
111
+ export function classifyTcellHealthCards(cards: readonly TcellHealthCard[], now: number): TcellHealthClassification {
112
+ if (!Number.isFinite(now)) throw new RangeError('invalid T-cell patrol time');
113
+ const valid: TcellHealthCard[] = [];
114
+ const unmeasuredRunIds: string[] = [];
115
+ const seen = new Set<string>();
116
+ for (const card of cards) {
117
+ const measured = typeof card.runId === 'string' && !!card.runId.trim() && !seen.has(card.runId)
118
+ && typeof card.stage === 'string' && !!card.stage.trim()
119
+ && Number.isFinite(card.startedAt) && card.startedAt <= now
120
+ && (card.progressAt === null || (Number.isFinite(card.progressAt) && card.progressAt <= now))
121
+ && Number.isFinite(card.stageBudgetMs) && card.stageBudgetMs > 0
122
+ && (card.heartbeatAt === null || (Number.isFinite(card.heartbeatAt) && card.heartbeatAt <= now))
123
+ && typeof card.parentPresent === 'boolean'
124
+ && (card.leaseExpiresAt === null || Number.isFinite(card.leaseExpiresAt))
125
+ && typeof card.riskSignal === 'boolean';
126
+ if (!measured) {
127
+ if (typeof card.runId === 'string' && card.runId.trim()) unmeasuredRunIds.push(card.runId);
128
+ continue;
129
+ }
130
+ seen.add(card.runId);
131
+ valid.push(card);
132
+ }
133
+
134
+ const groups = new Map<string, Set<string>>();
135
+ for (const card of valid) {
136
+ const groupId = tcellCauseGroupId(card);
137
+ if (!groupId) continue;
138
+ const members = groups.get(groupId) ?? new Set<string>();
139
+ members.add(card.runId);
140
+ groups.set(groupId, members);
141
+ }
142
+
143
+ const counts: Record<TcellHealthClass, number> = { healthy: 0, slow: 0, stalled: 0, infected: 0, zombie: 0 };
144
+ const decisions = valid.map((card): TcellHealthDecision => {
145
+ const causeGroupId = tcellCauseGroupId(card);
146
+ const causeGroupSize = causeGroupId ? groups.get(causeGroupId)?.size : undefined;
147
+ const progressAge = now - (card.progressAt ?? card.startedAt);
148
+ let classification: TcellHealthClass;
149
+ let reason: TcellHealthDecision['reason'];
150
+ if (card.heartbeatAt === null) { classification = 'zombie'; reason = 'heartbeat-missing'; }
151
+ else if (!card.parentPresent) { classification = 'zombie'; reason = 'parent-missing'; }
152
+ else if (card.leaseExpiresAt === null || card.leaseExpiresAt <= now) { classification = 'zombie'; reason = 'lease-expired'; }
153
+ else if (card.riskSignal) { classification = 'infected'; reason = 'risk-signal'; }
154
+ else if ((causeGroupSize ?? 0) >= TCELL_CAUSE_QUORUM) { classification = 'infected'; reason = 'cause-quorum'; }
155
+ else if (progressAge >= TCELL_STALLED_AFTER_MS) { classification = 'stalled'; reason = 'no-progress-30m'; }
156
+ else if (progressAge > card.stageBudgetMs * 2) { classification = 'slow'; reason = 'over-stage-budget'; }
157
+ else { classification = 'healthy'; reason = 'within-stage-budget'; }
158
+ counts[classification] += 1;
159
+ return { runId: card.runId, stage: card.stage, classification, reason,
160
+ ...(causeGroupId ? { causeGroupId, causeGroupSize } : {}) };
161
+ });
162
+ return { total: cards.length, measured: valid.length, unmeasuredRunIds, counts, decisions };
163
+ }
164
+
43
165
  /** Scrub before bounding: a token crossing the 200-character boundary must not leak. */
44
166
  export function incidentLastLines(output: string): string[] {
45
167
  return output.split(/\r?\n/).filter((line) => line.trim().length > 0).slice(-3)
46
168
  .map((line) => redactSecretText(line).slice(0, 200));
47
169
  }
48
170
 
171
+ function safeChildEvidence(value: PodChildEvidence | undefined): PodChildEvidence | undefined {
172
+ if (!value) return undefined;
173
+ const safeText = (text: string): string => redactSecretText(text).slice(0, 200);
174
+ return {
175
+ ...value,
176
+ ...(typeof value.error === 'string' ? { error: safeText(value.error) } : {}),
177
+ ...(typeof value.detail === 'string' ? { detail: safeText(value.detail) } : {}),
178
+ ...(typeof value.stderr === 'string' ? { stderr: safeText(value.stderr) } : {}),
179
+ ...(typeof value.podLogUnavailable === 'string' ? { podLogUnavailable: safeText(value.podLogUnavailable) } : {}),
180
+ ...(Array.isArray(value.podLogTail) ? { podLogTail: value.podLogTail.slice(-3).map(safeText) } : {}),
181
+ ...(value.prFailure && typeof value.prFailure.errorTail === 'string'
182
+ ? { prFailure: { ...value.prFailure, errorTail: safeText(value.prFailure.errorTail) } } : {}),
183
+ };
184
+ }
185
+
49
186
  const KST_OFFSET_MS = 9 * 60 * 60_000;
50
187
  const INCIDENT_FILE = /^\d{4}-\d{2}-\d{2}\.jsonl$/;
51
188
 
@@ -55,9 +192,9 @@ function kstDate(at: number): string {
55
192
 
56
193
  // ── INCIDENT-REASON-FROM-LASTLINES (0.2.36 · 10-22 · OP 대응 피처) ───────────────────────────────
57
194
  // 기록된 reason 이 «unknown» 인데 마지막 출력 줄에 사유가 그대로 있는 사고가 다수(10-22 경보) — 읽는 쪽에서
58
- // 결정론으로 다시 분류한다. 우선순위 = 더 구체적인 종료 사유 먼저. 아무것도 안 맞으면 unknown 그대로(추측 0).
195
+ // 결정론으로 다시 분류한다. 꼬리 전체에서 서로 다른 사유가 «정확히 하나» 일 때만 그 사유를 쓰고,
196
+ // 0개(무증거)나 2개 이상(충돌)이면 unknown 그대로 둔다(추측 0). 표 순서는 «첫 매치 우선순위»가 아니다.
59
197
  const LAST_LINE_REASONS: ReadonlyArray<[RegExp, string]> = [
60
- // 근본 원인 먼저 — 뒤 조각의 DEPENDENCY_NEEDS_HUMAN 은 앞 조각 실패의 «증상»이라 맨 뒤 쪽.
61
198
  [/goal-elaboration needs-human:\s*goal-elaboration-ungrounded-path\b/, 'goal-elaboration-ungrounded-path'],
62
199
  [/goal-elaboration needs-human:\s*goal-elaboration-protected-path\b/, 'goal-elaboration-protected-path'],
63
200
  [/goal-elaboration needs-human:\s*goal-elaboration-scope-conflict\b/, 'goal-elaboration-scope-conflict'],
@@ -72,12 +209,28 @@ const LAST_LINE_REASONS: ReadonlyArray<[RegExp, string]> = [
72
209
  ];
73
210
  const DEVICE_SLICE_PATH = /src\/ux-sim\/[\w.-]*-device(?:\.test)?\.ts|DEVICE-FIRST/;
74
211
 
75
- /** lastLines 에서 종료 사유를 꺼낸다 — 안 맞으면 null(unknown 유지). */
212
+ // 한 사건을 두 이름으로 서술한 꼬리(상세 표지 ⊕ 일반 표지)는 충돌이 아니다 — 상세 표지가 일반 표지를 흡수한다.
213
+ // 서로 다른 사건을 말하는 표지끼리만 충돌이다(예: GOAL_DONE_BOUNDARY_MISSING ⊕ DEPENDENCY_NEEDS_HUMAN).
214
+ const REASON_ABSORBS: ReadonlyArray<readonly [string, readonly string[]]> = [
215
+ ['goal-elaboration-ungrounded-path', ['needs-human']],
216
+ ['goal-elaboration-protected-path', ['needs-human']],
217
+ ['goal-elaboration-scope-conflict', ['needs-human']],
218
+ ['goal-elaboration-fixed-layer-conflict', ['needs-human']],
219
+ ['goal-done-boundary-missing', ['needs-human']],
220
+ ['pod-backoff-limit', ['pod-job-failed']],
221
+ ['pod-child-no-result', ['pod-job-failed']],
222
+ ['dependency-needs-human', ['needs-human']],
223
+ ];
224
+
225
+ /** lastLines 에서 종료 사유를 꺼낸다 — 무증거·충돌이면 null(unknown 유지). */
76
226
  export function classifyIncidentReasonFromLastLines(lines: readonly string[] | undefined): string | null {
77
227
  if (!lines?.length) return null;
78
228
  const text = lines.join('\n');
79
- for (const [pattern, reason] of LAST_LINE_REASONS) if (pattern.test(text)) return reason;
80
- return null;
229
+ const matched = LAST_LINE_REASONS.filter(([pattern]) => pattern.test(text)).map(([, reason]) => reason);
230
+ const distinct = [...new Set(matched)].filter(
231
+ (reason) => !REASON_ABSORBS.some(([specific, absorbed]) => specific !== reason && matched.includes(specific) && absorbed.includes(reason)),
232
+ );
233
+ return distinct.length === 1 ? (distinct[0] ?? null) : null;
81
234
  }
82
235
 
83
236
  function refinedReasonFields(reason: string, lines: readonly string[] | undefined): Pick<RunExit, 'reason' | 'recordedReason' | 'reasonSource' | 'slice'> {
@@ -126,12 +279,54 @@ export function readRunExits(root: string): RunExit[] {
126
279
  ...(row.childEvidence && typeof row.childEvidence === 'object' && !Array.isArray(row.childEvidence)
127
280
  ? { childEvidence: row.childEvidence } : {}),
128
281
  ...podTerminationField(row.podTermination),
282
+ ...terminalEvidenceField(row.terminalEvidence),
129
283
  });
130
284
  }
131
285
  }
132
286
  return rows.sort((a, b) => Date.parse(a.at) - Date.parse(b.at) || a.runId.localeCompare(b.runId));
133
287
  }
134
288
 
289
+ function terminalEvidenceField(value: unknown): { terminalEvidence?: RunExit['terminalEvidence'] } {
290
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return {};
291
+ const row = value as Record<string, unknown>;
292
+ const attempt = row.attempt;
293
+ const tail = row.childOutputTail;
294
+ const exitCode = row.containerExitCode;
295
+ if (typeof row.job !== 'string' || !row.job.trim() || typeof row.childRunId !== 'string' || !row.childRunId.trim()
296
+ || !(attempt === 'unknown' || (typeof attempt === 'number' && Number.isSafeInteger(attempt) && attempt > 0))
297
+ || !(tail === 'unknown' || (Array.isArray(tail) && tail.every((line) => typeof line === 'string')))
298
+ || !(exitCode === 'unknown' || (typeof exitCode === 'number' && Number.isSafeInteger(exitCode) && exitCode >= 0))
299
+ || typeof row.parentVerdict !== 'string'
300
+ || !(row.failureClassification === undefined || row.failureClassification === null || row.failureClassification === 'unknown' || typeof row.failureClassification === 'string')
301
+ || !(row.terminationReason === undefined || row.terminationReason === null || row.terminationReason === 'unknown' || typeof row.terminationReason === 'string')) return {};
302
+ const childOutputTail = tail === 'unknown' ? tail
303
+ : tail.slice(-3).map((line) => redactSecretText(line).slice(0, 200));
304
+ const failureClassification = row.failureClassification === undefined || row.failureClassification === null
305
+ ? 'unknown' : row.failureClassification === 'unknown' ? 'unknown' : redactSecretText(row.failureClassification).slice(0, 120);
306
+ const terminationReason = row.terminationReason === undefined || row.terminationReason === null
307
+ ? 'unknown' : row.terminationReason === 'unknown' ? 'unknown' : redactSecretText(row.terminationReason).slice(0, 200);
308
+ const childFailureStage = typeof row.childFailureStage === 'string' && row.childFailureStage.trim()
309
+ ? redactSecretText(row.childFailureStage).slice(0, 120) : 'unknown';
310
+ const childRunStatus = readChildRunStatus(row.childRunStatus);
311
+ const shardIdentityReadFailure = row.shardIdentityReadFailure === 'none' || row.shardIdentityReadFailure === 'unknown'
312
+ ? row.shardIdentityReadFailure
313
+ : typeof row.shardIdentityReadFailure === 'string' && row.shardIdentityReadFailure.trim()
314
+ ? redactSecretText(row.shardIdentityReadFailure).slice(0, 120) : 'unknown';
315
+ const providerFailure = row.providerFailure === 'credential-not-configured' || row.providerFailure === 'provider-failed'
316
+ || row.providerFailure === 'none' || row.providerFailure === 'unknown' ? row.providerFailure : 'unknown';
317
+ return { terminalEvidence: { job: row.job, childRunId: row.childRunId, attempt, childOutputTail,
318
+ containerExitCode: exitCode, parentVerdict: row.parentVerdict, failureClassification, terminationReason,
319
+ childFailureStage, childRunStatus, shardIdentityReadFailure, providerFailure } };
320
+ }
321
+
322
+ function readChildRunStatus(value: unknown): NonNullable<RunExit['terminalEvidence']>['childRunStatus'] {
323
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return { stage: 'unknown', status: 'unknown', failureKind: 'unknown' };
324
+ const row = value as Record<string, unknown>;
325
+ const safe = (field: unknown): string | 'unknown' => typeof field === 'string' && field.trim()
326
+ ? redactSecretText(field).slice(0, 120) : 'unknown';
327
+ return { stage: safe(row.stage), status: safe(row.status), failureKind: safe(row.failureKind) };
328
+ }
329
+
135
330
  function podTerminationField(value: unknown): { podTermination?: PodTermination } {
136
331
  const job = value && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>).job : undefined;
137
332
  const parsed = typeof job === 'string' ? parsePodTermination(value, job) : undefined;
@@ -152,8 +347,12 @@ export function recordRunExit(row: RunExit, root: string): void {
152
347
  lock.exec('BEGIN IMMEDIATE');
153
348
  try {
154
349
  if (!readRunExits(root).some((record) => record.runId === row.runId)) {
155
- const safeRow = row.lastLines === undefined ? row : {
156
- ...row, lastLines: row.lastLines.slice(-3).map((line) => redactSecretText(line).slice(0, 200)),
350
+ const terminalEvidence = deriveTerminalEvidence(row, root);
351
+ const safeRow: RunExit = {
352
+ ...row,
353
+ ...(row.lastLines === undefined ? {} : { lastLines: row.lastLines.slice(-3).map((line) => redactSecretText(line).slice(0, 200)) }),
354
+ ...(row.childEvidence === undefined ? {} : { childEvidence: safeChildEvidence(row.childEvidence) }),
355
+ ...(terminalEvidence ? { terminalEvidence } : {}),
157
356
  };
158
357
  appendFileSync(join(dir, `${kstDate(at)}.jsonl`), `${JSON.stringify(safeRow)}\n`);
159
358
  }
@@ -167,6 +366,112 @@ export function recordRunExit(row: RunExit, root: string): void {
167
366
  }
168
367
  }
169
368
 
369
+ /** Join exit facts through the last pod-child-run fence; never borrow a previous Pod attempt. */
370
+ function deriveTerminalEvidence(row: RunExit, root: string): RunExit['terminalEvidence'] | undefined {
371
+ let entries: RunLedgerEntry[] | null;
372
+ try { entries = loadRunLedger(row.runId, runLedgerDir(root)); }
373
+ catch { return undefined; /* observing the child ledger cannot block the parent incident record */ }
374
+ if (!entries) return undefined;
375
+ let startIndex = -1;
376
+ entries.forEach((entry, index) => { if (entry.event === 'pod-child-run') startIndex = index; });
377
+ const startEntry = startIndex >= 0 ? entries[startIndex] : undefined;
378
+ const start = startEntry?.data;
379
+ if (!start || typeof start.job !== 'string' || !start.job.trim()
380
+ || typeof start.childRunId !== 'string' || !start.childRunId.trim()) return undefined;
381
+ const currentRows = entries.slice(startIndex + 1).filter((entry) => entry.event === 'pod-child-evidence'
382
+ && entry.data.job === start.job && entry.data.childRunId === start.childRunId).map((entry) => entry.data);
383
+ const evidenceRow = currentRows.slice().reverse().find((data) => Object.hasOwn(data, 'childEvidence'));
384
+ const childEvidence = evidenceRow?.childEvidence && typeof evidenceRow.childEvidence === 'object' && !Array.isArray(evidenceRow.childEvidence)
385
+ ? evidenceRow.childEvidence as Record<string, unknown> : undefined;
386
+ const tailSource = Array.isArray(childEvidence?.podLogTail) && childEvidence.podLogTail.every((line) => typeof line === 'string')
387
+ ? childEvidence.podLogTail
388
+ : typeof childEvidence?.stderr === 'string' ? childEvidence.stderr.split(/\r?\n/) : undefined;
389
+ const childOutputTail = tailSource?.length
390
+ ? tailSource.slice(-3).map((line) => redactSecretText(line).slice(0, 200))
391
+ : 'unknown';
392
+ let termination: PodTermination | undefined;
393
+ for (const data of currentRows.slice().reverse()) {
394
+ termination = parsePodTermination(data.podTermination, start.job);
395
+ if (termination) break;
396
+ }
397
+ const finished = entries.slice(startIndex + 1).slice().reverse().find((entry) => {
398
+ if (entry.event !== 'pod-launch-finished' || entry.data.job !== start.job) return false;
399
+ const childRunId = typeof entry.data.childRun === 'string' ? entry.data.childRun : entry.data.run;
400
+ if (childRunId !== start.childRunId) return false;
401
+ const startAttempt = Number.isSafeInteger(start.attempt) && Number(start.attempt) > 0 ? Number(start.attempt) : undefined;
402
+ const finishAttempt = Number.isSafeInteger(entry.data.attempt) && Number(entry.data.attempt) > 0 ? Number(entry.data.attempt) : undefined;
403
+ return startAttempt === undefined || finishAttempt === startAttempt;
404
+ });
405
+ const classification = finished?.data.failureClassification;
406
+ const terminationReason = finished?.data.terminationReason;
407
+ const childRunDiagnosis = childRunDiagnosisFields(start.childRunId, root, {
408
+ job: start.job,
409
+ attempt: Number.isSafeInteger(start.attempt) && Number(start.attempt) > 0 ? Number(start.attempt) : undefined,
410
+ startedAt: startEntry?.timestamp,
411
+ finishedAt: finished?.timestamp,
412
+ });
413
+ return {
414
+ job: start.job,
415
+ childRunId: start.childRunId,
416
+ attempt: Number.isSafeInteger(start.attempt) && Number(start.attempt) > 0 ? Number(start.attempt) : 'unknown',
417
+ childOutputTail,
418
+ containerExitCode: typeof termination?.exitCode === 'number' ? termination.exitCode : 'unknown',
419
+ parentVerdict: row.reason,
420
+ failureClassification: typeof finished?.data.podExitClass === 'string' && finished.data.podExitClass
421
+ ? redactSecretText(finished.data.podExitClass).slice(0, 120)
422
+ : typeof classification === 'string' && classification ? redactSecretText(classification).slice(0, 120) : 'unknown',
423
+ terminationReason: typeof terminationReason === 'string' && terminationReason ? redactSecretText(terminationReason).slice(0, 200) : 'unknown',
424
+ childFailureStage: typeof finished?.data.childFailureStage === 'string' && finished.data.childFailureStage.trim()
425
+ ? redactSecretText(finished.data.childFailureStage).slice(0, 120) : 'unknown',
426
+ ...childRunDiagnosis,
427
+ };
428
+ }
429
+
430
+ function childRunDiagnosisFields(childRunId: string, root: string, current: {
431
+ job: string; attempt?: number; startedAt?: string; finishedAt?: string;
432
+ }): Pick<NonNullable<RunExit['terminalEvidence']>, 'childRunStatus' | 'shardIdentityReadFailure' | 'providerFailure'> {
433
+ let entries: RunLedgerEntry[] | null;
434
+ try { entries = loadRunLedger(childRunId, runLedgerDir(root)); }
435
+ catch { entries = null; }
436
+ const startedAt = typeof current.startedAt === 'string' ? Date.parse(current.startedAt) : NaN;
437
+ const finishedAt = typeof current.finishedAt === 'string' ? Date.parse(current.finishedAt) : NaN;
438
+ if (!entries || !current.job.trim() || current.attempt === undefined
439
+ || !Number.isFinite(startedAt) || !Number.isFinite(finishedAt) || finishedAt < startedAt) return {
440
+ childRunStatus: { stage: 'unknown', status: 'unknown', failureKind: 'unknown' },
441
+ shardIdentityReadFailure: 'unknown', providerFailure: 'unknown',
442
+ };
443
+
444
+ // Child ledgers can outlive a Pod retry that reuses childRunId. Only trust events
445
+ // timestamped inside this parent's exact Job/attempt interval; otherwise report unknown.
446
+ const attemptEntries = entries.filter((entry) => {
447
+ const timestamp = typeof entry.timestamp === 'string' ? Date.parse(entry.timestamp) : NaN;
448
+ return Number.isFinite(timestamp) && timestamp >= startedAt && timestamp <= finishedAt;
449
+ });
450
+ const status = attemptEntries.slice().reverse().find((entry) => entry.event === 'run-status')?.data;
451
+ const shardObservation = attemptEntries.slice().reverse().find((entry) => Object.hasOwn(entry, 'shardIdentityReadFailure')
452
+ || entry.event === 'shard-sibling-query');
453
+ // RunLedgerEntry's canonical shard identity is top-level (makeRunObserver writes it there).
454
+ // Accept data.* too for older/imported child rows that nested the field.
455
+ const shardValue = shardObservation?.shardIdentityReadFailure ?? shardObservation?.data.shardIdentityReadFailure;
456
+ const shardFailure = typeof shardValue === 'string' && shardValue !== 'none' && shardValue !== 'unknown' && shardValue.trim()
457
+ ? shardValue : undefined;
458
+ const providerSkip = attemptEntries.slice().reverse().find((entry) => entry.event === 'goal-elaboration-skipped'
459
+ && entry.data.outcome === 'skipped' && entry.data.reason === 'provider-failed');
460
+ const providerError = typeof providerSkip?.data.error === 'string' ? providerSkip.data.error : '';
461
+ const providerFailure: NonNullable<RunExit['terminalEvidence']>['providerFailure'] = providerSkip
462
+ ? /unavailable:\s*configure apiKey/iu.test(providerError) ? 'credential-not-configured' : 'provider-failed'
463
+ : 'unknown';
464
+ const safe = (value: unknown): string | 'unknown' => typeof value === 'string' && value.trim()
465
+ ? redactSecretText(value).slice(0, 120) : 'unknown';
466
+ return {
467
+ childRunStatus: { stage: safe(status?.stage), status: safe(status?.runStatus), failureKind: safe(status?.failureKind) },
468
+ shardIdentityReadFailure: shardFailure ? redactSecretText(shardFailure).slice(0, 120)
469
+ : shardValue === 'unknown' ? 'unknown'
470
+ : shardObservation?.event === 'shard-sibling-query' && shardObservation.data.reason === 'not-sharded' ? 'none' : 'unknown',
471
+ providerFailure,
472
+ };
473
+ }
474
+
170
475
  const HOSTNAME_BURST_WINDOW_MS = 60 * 60_000;
171
476
 
172
477
  function uniqueRunExits(rows: readonly RunExit[]): RunExit[] {
@@ -27,6 +27,7 @@ import { podMemoryLimitFor, type PodMemoryTier } from '../task-orchestrator/surf
27
27
  import { oldDoorInternalEnv } from '../self-dev/old-door.js';
28
28
  import { selectPodMemoryTier } from './pod-memory-policy.js';
29
29
  import { preflightGoalDoneBoundary } from '../self-dev/dev-pipeline.js';
30
+ import { forwardChildStderr } from '../surface/child-process.js';
30
31
 
31
32
  export interface HarnessPodDispatchInput {
32
33
  readonly entrance: 'cli-harness-ask' | 'cli-harness-say';
@@ -294,9 +295,14 @@ export function dispatchHarnessOnPod(input: HarnessPodDispatchInput, deps: PodDi
294
295
  goalChars, ...(input.entrance === 'cli-harness-ask' ? { goalPath: input.input } : {}),
295
296
  });
296
297
  const run = deps.run ?? ((cmd: string, a: readonly string[], childEnv: NodeJS.ProcessEnv) => new Promise<number>((resolveStatus) => {
297
- const child = (deps.spawnChild ?? spawn)(cmd, [...a], { stdio: deps.onOutput ? ['inherit', 'pipe', 'inherit'] : 'inherit', env: childEnv });
298
+ const ownsOutput = Boolean(deps.onOutput);
299
+ const child = (deps.spawnChild ?? spawn)(cmd, [...a], {
300
+ stdio: ownsOutput ? ['ignore', 'pipe', 'pipe'] : 'inherit',
301
+ env: childEnv,
302
+ });
298
303
  child.stdout?.setEncoding('utf8');
299
304
  child.stdout?.on('data', (chunk: string) => { process.stdout.write(chunk); deps.onOutput?.(chunk); });
305
+ if (ownsOutput) forwardChildStderr(child.stderr);
300
306
  let forwarded: NodeJS.Signals | undefined;
301
307
  const forward = (signal: NodeJS.Signals) => {
302
308
  forwarded = signal;
@@ -25,7 +25,7 @@
25
25
  // spaceId 선례와 동형. 계약 = [[DESIGN-executor-pty-ref-contract-2026-07-25]] ExecutorPtyRef.runId.
26
26
 
27
27
  import { createHash, randomUUID } from 'node:crypto';
28
- import { mkdirSync } from 'node:fs';
28
+ import { appendFileSync, mkdirSync } from 'node:fs';
29
29
  import { tmpdir } from 'node:os';
30
30
  import { isAbsolute, relative, resolve } from 'node:path';
31
31
  import { ensureHostId } from '../platform/host-id.js';
@@ -101,6 +101,20 @@ export function getHarnessBoundaryPath(env: NodeJS.ProcessEnv = process.env): st
101
101
  return env[HARNESS_BOUNDARY_ENV]?.trim() ?? '';
102
102
  }
103
103
 
104
+ /** TENANT-BOUNDARY (0.2.41): 경계 회신 mailbox(HARNESS_BOUNDARY_RESPONSES_ENV)에 payload 한 줄(JSONL)을
105
+ * 남긴다 — 익명 내보내기 전용 출구. env 가 비거나 절대경로가 아니면 fail-open(빈 문자열 반환, 파일 안 만듦). */
106
+ export function appendBoundaryResponseLine(env: NodeJS.ProcessEnv, payload: object): string {
107
+ const path = env[HARNESS_BOUNDARY_RESPONSES_ENV]?.trim() ?? '';
108
+ if (!path || !isAbsolute(path)) return '';
109
+ try {
110
+ mkdirSync(resolve(path, '..'), { recursive: true });
111
+ appendFileSync(path, `${JSON.stringify(payload)}\n`);
112
+ return path;
113
+ } catch {
114
+ return '';
115
+ }
116
+ }
117
+
104
118
  /** 전 공간 종류(SSOT) — logs `--space` 필터·검증 등이 공유. */
105
119
  export const HARNESS_SPACE_KINDS: readonly HarnessSpaceKind[] = ['self-implement', 'dev-harness', 'solve-mission', 'dev-hold'];
106
120
 
@@ -0,0 +1,59 @@
1
+ import { parentPort } from 'node:worker_threads';
2
+ import { queryRunningRuns, type RunningRunsResult } from '../self-implement/running-runs.js';
3
+
4
+ /**
5
+ * HARNESS-PROGRESS-HANG — `harness progress` 하위 조회의 «전용 워커 엔트리».
6
+ * 이 모듈은 CLI 디스패치(`src/index.ts`·`bin/elanous.mjs`)를 거치지 않고 워커에 직접 적재되므로,
7
+ * 번들·컴파일 산출물에서도 `parentPort` 핸들러가 반드시 이 스레드에 등록된다.
8
+ * 그 전에는 워커가 `import.meta.url` 로 배포 엔트리를 재진입해 핸들러가 아예 안 올랐다.
9
+ */
10
+ export interface ProgressQueryWorkerRequest {
11
+ readonly kind?: 'query';
12
+ readonly caller: string;
13
+ readonly runIds?: readonly string[];
14
+ readonly timeBudgetMs?: number;
15
+ }
16
+
17
+ /** 상한 도달 뒤 부모가 보내는 정지 요청 — 워커는 «현재 행» 을 회신하고 정상 종료한다. */
18
+ export interface ProgressQueryWorkerAbortRequest {
19
+ readonly kind: 'abort';
20
+ }
21
+
22
+ export type ProgressQueryWorkerMessage = ProgressQueryWorkerRequest | ProgressQueryWorkerAbortRequest;
23
+
24
+ export interface ProgressQueryWorkerReply {
25
+ readonly ok: boolean;
26
+ readonly result?: RunningRunsResult;
27
+ readonly error?: string;
28
+ readonly stopped?: 'aborted';
29
+ }
30
+
31
+ /**
32
+ * 워커의 `parentPort` 핸들러를 등록한다.
33
+ * - `query`: 하위 조회를 실행해 결과를 회신한다.
34
+ * - `abort`: 이 스레드가 마지막으로 계산한 행(`lastResult`)을 «보존 행» 으로 회신한다 —
35
+ * 부모의 상한 뒤 유예 창 안에 도착하면 `progress-command-late` 관측으로 그대로 보존된다.
36
+ */
37
+ export function installProgressWorkerEntry(port: NonNullable<typeof parentPort> | null | undefined = parentPort): void {
38
+ if (!port) return;
39
+ let lastResult: RunningRunsResult | undefined;
40
+ port.on('message', (message: ProgressQueryWorkerMessage) => {
41
+ if (message.kind === 'abort') {
42
+ port.postMessage({ ok: true, result: lastResult, stopped: 'aborted' } satisfies ProgressQueryWorkerReply);
43
+ return;
44
+ }
45
+ try {
46
+ const result = queryRunningRuns({
47
+ caller: message.caller,
48
+ ...(message.timeBudgetMs === undefined ? {} : { timeBudgetMs: message.timeBudgetMs }),
49
+ ...(message.runIds === undefined ? {} : { runIds: message.runIds }),
50
+ });
51
+ lastResult = result;
52
+ port.postMessage({ ok: true, result } satisfies ProgressQueryWorkerReply);
53
+ } catch (error) {
54
+ port.postMessage({ ok: false, error: error instanceof Error ? error.message : String(error) } satisfies ProgressQueryWorkerReply);
55
+ }
56
+ });
57
+ }
58
+
59
+ installProgressWorkerEntry();
@@ -0,0 +1,11 @@
1
+ import { isMainThread } from 'node:worker_threads';
2
+
3
+ /**
4
+ * HARNESS-PROGRESS-HANG — `harness progress` 하위 조회는 «전용 워커 엔트리»(`./progress-worker-entry.ts`)
5
+ * 를 직접 적재한다. 그 엔트리는 CLI 디스패치를 거치지 않으므로 번들·컴파일 산출물에서도 `parentPort`
6
+ * 핸들러가 워커 스레드에 오른다. 이 판정은 배포 엔트리(`bin/elanous.mjs`)가 워커 문맥에서 재진입됐을 때
7
+ * 대시보드·provider 선택·명령 디스패치를 다시 걸지 않게 가드한다.
8
+ */
9
+ export function shouldRunCliEntry(): boolean {
10
+ return isMainThread;
11
+ }
package/src/index.ts CHANGED
@@ -4739,6 +4739,7 @@ selfCmd
4739
4739
  .option('--shard-concurrency <number>', '동시에 실행할 조각 묶음 수 (1–4, 기본 3)')
4740
4740
  .option('--fixed-shard-distribution', '--shards N 과 함께만: RSS 사전 측정 없이 정렬된 파일을 N 조각에 라운드로빈 고정 배정한다(opt-in · 메모리 보증 아님 · 조각 타임아웃/OOM = unmeasured)')
4741
4741
  .option('--include-importers', '변경 모듈을 가져오는 importer 시험도 실행한다 (기본 caller 한도 밖까지)')
4742
+ .option('--no-inherit', '이전 게이트 시험 영수증의 통과 시험을 상속하지 않고 전체 범위를 실행한다')
4742
4743
  .option('--remote [host]', 'GATE-REMOTE — 같은 커밋을 원격 호스트(기본 config gateRemote.host=node-b)에서 돌리고 결과만 가져온다(깨끗한 트리 · --pr 은 로컬)')
4743
4744
  .option('--local', '원격 실행을 끄고 명시적으로 로컬에서 돌린다')
4744
4745
  .option('--artifact-dir <dir>', '조각별 지금/기준 JUnit ⊕ summary.json 을 이 디렉토리에 남긴다(판정 불변 · JUnit 은 --shards 경로만 · 원격 실행이면 그 호스트에서 가져온다)')
@@ -4746,7 +4747,21 @@ selfCmd
4746
4747
  .option('--shard-id <id>', 'GATE-REMOTE-SHARD-PLAN — 조각 id(예: <orchestration-id>/shard-2). 원격 명령줄에 그대로 실린다')
4747
4748
  .option('--shard-position <n>', 'GATE-REMOTE-SHARD-PLAN — 조각 위치(1부터 정수). 원격 명령줄에 그대로 실린다')
4748
4749
  .option('--shard-plan <path>', 'GATE-REMOTE-SHARD-PLAN — 조각 계획 파일 경로. 주면 원격 명령줄에 --shard-plan 으로 실린다')
4749
- .action(async (opts: { changed?: boolean; base?: string; pr?: string; shards?: string | boolean; shardConcurrency?: string; fixedShardDistribution?: boolean; includeImporters?: boolean; remote?: string | boolean; local?: boolean; artifactDir?: string; orchestrationId?: string; shardId?: string; shardPosition?: string; shardPlan?: string }) => {
4750
+ .action(async (opts: { changed?: boolean; base?: string; pr?: string; shards?: string | boolean; shardConcurrency?: string; fixedShardDistribution?: boolean; includeImporters?: boolean; inherit?: boolean; remote?: string | boolean; local?: boolean; artifactDir?: string; orchestrationId?: string; shardId?: string; shardPosition?: string; shardPlan?: string }) => {
4751
+ const { observeSelfGateTrainMarker, refuseSeatSelfGateWithoutTrainMarker, writeSeatSelfGateRefusalArtifact } = require('./self-implement/gate-cli.js') as typeof import('./self-implement/gate-cli.js');
4752
+ const trainMarker = observeSelfGateTrainMarker();
4753
+ if (process.env.ELANOUS_TRACK) {
4754
+ const seatRefusal = refuseSeatSelfGateWithoutTrainMarker(trainMarker);
4755
+ if (seatRefusal) {
4756
+ if (opts.artifactDir !== undefined) {
4757
+ try { writeSeatSelfGateRefusalArtifact(process.cwd(), opts.artifactDir, trainMarker); }
4758
+ catch (error) { ui.error(`self gate artifact: ${error instanceof Error ? error.message : String(error)}`); }
4759
+ }
4760
+ ui.error(seatRefusal.message);
4761
+ process.exitCode = 2;
4762
+ return;
4763
+ }
4764
+ }
4750
4765
  if (!opts.changed && opts.shards === undefined) { ui.error('self gate requires --changed or --shards'); process.exitCode = 2; return; }
4751
4766
  if (opts.fixedShardDistribution && opts.shards === undefined) { ui.error('self gate: --fixed-shard-distribution requires --shards <n>'); process.exitCode = 2; return; }
4752
4767
  if (opts.shardConcurrency !== undefined && (!/^[1-4]$/.test(opts.shardConcurrency))) { ui.error('self gate: --shard-concurrency must be 1–4'); process.exitCode = 2; return; }
@@ -4769,7 +4784,7 @@ selfCmd
4769
4784
  ranLocal = true;
4770
4785
  try {
4771
4786
  const { runSelfGateCliAsync } = require('./self-implement/gate-cli.js') as typeof import('./self-implement/gate-cli.js');
4772
- const result = await runSelfGateCliAsync(process.cwd(), { base: opts.base, pr: opts.pr, shards, ...(opts.shardConcurrency !== undefined ? { shardConcurrency: Number(opts.shardConcurrency) } : {}), ...(opts.fixedShardDistribution ? { fixedShardDistribution: true } : {}), includeImporterTests: !!opts.includeImporters, ...(opts.artifactDir !== undefined ? { artifactDir: opts.artifactDir } : {}) });
4787
+ const result = await runSelfGateCliAsync(process.cwd(), { base: opts.base, pr: opts.pr, shards, ...(opts.shardConcurrency !== undefined ? { shardConcurrency: Number(opts.shardConcurrency) } : {}), ...(opts.fixedShardDistribution ? { fixedShardDistribution: true } : {}), includeImporterTests: !!opts.includeImporters, noInherit: opts.inherit === false, trainGate: trainMarker.received, ...(opts.artifactDir !== undefined ? { artifactDir: opts.artifactDir } : {}) });
4773
4788
  console.log(result.lines.join('\n'));
4774
4789
  return result.exitCode;
4775
4790
  } catch (error) {
@@ -4802,6 +4817,7 @@ selfCmd
4802
4817
  const argv = remoteSelfGateArgv({
4803
4818
  changed: opts.changed, base: opts.base, shards, shardConcurrency: opts.shardConcurrency === undefined ? undefined : Number(opts.shardConcurrency), fixedShardDistribution: opts.fixedShardDistribution,
4804
4819
  includeImporters: opts.includeImporters,
4820
+ noInherit: opts.inherit === false,
4805
4821
  // A measured commit without this option rejects it (exit ≠ 0) — read as not passed, never as a silent measured run.
4806
4822
  artifactDir: remoteArtifacts && 'dir' in remoteArtifacts ? remoteArtifacts.dir : undefined,
4807
4823
  }, sha);
@@ -4852,6 +4868,8 @@ selfCmd
4852
4868
  const fetched = remoteArtifacts && 'dir' in remoteArtifacts ? remoteArtifacts.fetch : undefined;
4853
4869
  try {
4854
4870
  if (fetched?.ok) {
4871
+ const { recordGateTrainMarker } = await import('./self-implement/gate-artifacts.js');
4872
+ recordGateTrainMarker(fetched.summaryPath, trainMarker.received);
4855
4873
  console.log(`artifacts: ${fetched.summaryPath} (junit ${fetched.junitFiles.length} · fetched from remote)`);
4856
4874
  if (fetched.remoteDirKept) console.log(`⚠ artifacts: 원격 산출 디렉토리를 못 지웠다 — ${(remoteArtifacts as { dir: string }).dir} (판정은 그대로다)`);
4857
4875
  }
@@ -4859,7 +4877,7 @@ selfCmd
4859
4877
  const reason = remoteArtifacts && 'unsupported' in remoteArtifacts ? 'remote-unsupported' as const : 'remote-fetch-failed' as const;
4860
4878
  if (reason === 'remote-fetch-failed') console.log(`⚠ artifacts: 원격 산출을 못 가져왔다 — ${fetched && !fetched.ok ? fetched.reason : 'no remote fetch ran'} (판정은 그대로다)`);
4861
4879
  const { writeRemoteUnavailableGateArtifacts } = await import('./self-implement/gate-artifacts.js');
4862
- const written = writeRemoteUnavailableGateArtifacts(opts.artifactDir, process.cwd(), opts.base, Number(process.exitCode ?? 0), reason);
4880
+ const written = writeRemoteUnavailableGateArtifacts(opts.artifactDir, process.cwd(), opts.base, Number(process.exitCode ?? 0), reason, undefined, undefined, trainMarker.received);
4863
4881
  console.log(`artifacts: ${written.summaryPath} (junit 0 · unavailable=${reason})`);
4864
4882
  }
4865
4883
  } catch (error) {
@@ -6277,10 +6295,12 @@ selfCmd
6277
6295
  .option('--acp-timeout <sec>', 'ACP 리뷰 1턴 최대 대기 초(초과 시 cancel·기본 claude 600 · 그 외 300)')
6278
6296
  .option('--context <path>', '리뷰어가 함께 판단할 레포 상대 파일 경로(반복 가능)', (value: string, previous: string[] = []) => [...previous, value])
6279
6297
  .option('--context-text <text>', '리뷰어가 함께 판단할 텍스트(반복 가능)', (value: string, previous: string[] = []) => [...previous, value])
6298
+ .option('--no-context-pack', '기본 저장소 리뷰 맥락 팩을 끈다')
6280
6299
  .option('--json', '구조화 출력 {pr, verdict, mustFix, shouldFix, reviewed}')
6281
6300
  .option('--save <name>', '리뷰 결과를 상태 디렉터리의 review-results/<name>-<PR>-<head12>.json에 저장')
6301
+ .option('--since-review <saved review name|head>', '저장된 리뷰의 mustFix와 해당 head 이후 변경만 다시 판정')
6282
6302
  .option('--over-cap-reason <reason>', '저장 리뷰 r5 상한 이후 이번 호출 1회 예외 사유(doctor.review cap-override 기록)')
6283
- .action(async (prParts: string[], opts: { intent?: string; model?: string; acp?: boolean; acpModel?: string; acpBackend?: string; acpTimeout?: string; context?: string[]; contextText?: string[]; json?: boolean; save?: string; overCapReason?: string }) => {
6303
+ .action(async (prParts: string[], opts: { intent?: string; model?: string; acp?: boolean; acpModel?: string; acpBackend?: string; acpTimeout?: string; context?: string[]; contextText?: string[]; contextPack?: boolean; json?: boolean; save?: string; sinceReview?: string; overCapReason?: string }) => {
6284
6304
  const prArgs = prParts.flatMap((p) => String(p).split(/[,\s]+/).filter(Boolean)); // 번호/#번호/URL·콤마목록.
6285
6305
  if (!prArgs.length) { ui.error('PR 필요: elanous self review <번호|URL> [..]'); process.exit(2); }
6286
6306
  // ⭐ 본문은 seam(`runSelfReviewCliCommand`)에 있다 — 이 액션은 **의존 배선만** 한다.
@@ -6308,6 +6328,7 @@ selfCmd
6308
6328
  const configuredReviewModel = apiReviewModelFromRoleSpec(reviewRoleSpec);
6309
6329
  const { results, failed } = await runSelfReviewCliCommand(prArgs, {
6310
6330
  ...opts,
6331
+ noContextPack: opts.contextPack === false,
6311
6332
  ...(configuredReviewModel ? { configuredReviewModel } : {}),
6312
6333
  ...(configuredReviewModel && reviewRoleSpec?.provider ? { configuredReviewProvider: reviewRoleSpec.provider } : {}),
6313
6334
  ...(configuredAcpBackend ? { configuredAcpBackend } : {}),
@@ -7058,7 +7079,16 @@ agentCmd
7058
7079
  // runAgentMissionCliCommand(테스트 가능 seam)로 추출. 액션은 I/O(print/exit)만 담당.
7059
7080
  const { resolveBackend } = await import('./agent-mission/driver.js');
7060
7081
  const { runAgentMissionCliCommand } = await import('./agent-mission/mission-cli.js');
7061
- const outcome = await runAgentMissionCliCommand(textParts, opts as import('./agent-mission/mission-cli.js').MissionCliOpts, { resolveBackend });
7082
+ const controller = new AbortController();
7083
+ const onSigint = (): void => { controller.abort(); };
7084
+ process.once('SIGINT', onSigint);
7085
+ let outcome: Awaited<ReturnType<typeof runAgentMissionCliCommand>>;
7086
+ try {
7087
+ outcome = await runAgentMissionCliCommand(textParts, opts as import('./agent-mission/mission-cli.js').MissionCliOpts,
7088
+ { resolveBackend, signal: controller.signal });
7089
+ } finally {
7090
+ process.removeListener('SIGINT', onSigint);
7091
+ }
7062
7092
  if (!outcome.ok) { console.error(`❌ ${outcome.message}`); process.exit(outcome.exitCode); }
7063
7093
  await writeStdoutJson(JSON.stringify(outcome.result, null, 2) + '\n');
7064
7094
  process.exit(outcome.exitCode);