elanous 0.2.37 → 0.2.40

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 (727) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/{8kITumG9GAZ1LwT9POrAR → HjeK7zONHfR7op1hKXp4k}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{1746.3563617ea64023a3.js → 1060.014f1f01a17aec26.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{9151.a2c51e93f9156dae.js → 1281.d81877e35b9068f4.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/1350.59f40e39e02d91b1.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1415.79821ec7ae99acdb.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1452.162bb2d9d699e82a.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/147.f92f63bbc5e85fa5.js +286 -0
  10. package/apps/pwa/out/_next/static/chunks/1537-6bb97b5214928ea9.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1661.fb425a1d8a065b72.js +149 -0
  12. package/apps/pwa/out/_next/static/chunks/1671-1c22b40b50b208f2.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1758.0204d3f48783c49d.js +90 -0
  14. package/apps/pwa/out/_next/static/chunks/1806.027bf78b6a94d340.js +104 -0
  15. package/apps/pwa/out/_next/static/chunks/{3578.4e9f9948a9a6f2f4.js → 2047.8f23e210995d4548.js} +2 -2
  16. package/apps/pwa/out/_next/static/chunks/2061-7f2bbc53ae96c88b.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/{7424.c0fe2a595d4232b5.js → 2066.a77257c8c350770a.js} +1 -1
  18. package/apps/pwa/out/_next/static/chunks/2096-a938496bc996dcbd.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/{4931.95cc6dbd230774ca.js → 2177.df8547f9d7215c4e.js} +16 -16
  20. package/apps/pwa/out/_next/static/chunks/2200-9a453b8f99687d49.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/{6680.6a693c28aae4cd19.js → 2226.2cf61ec781827219.js} +2 -2
  22. package/apps/pwa/out/_next/static/chunks/2281-b8cede695c6c650e.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/2499.02fbfd18126c10c0.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/{6252.240578f10952e091.js → 2522.f2766b76d22c8bdf.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/{1262.a89bb27a5b2f844e.js → 2566.beaffc3a5e1fcd2e.js} +1 -1
  26. package/apps/pwa/out/_next/static/chunks/261.0d471e8aded799f3.js +226 -0
  27. package/apps/pwa/out/_next/static/chunks/2615.3c9738153de3ef3f.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2727.e703d99ac414916d.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/2752.7904b8df0254d0ae.js +27 -0
  30. package/apps/pwa/out/_next/static/chunks/2762-5051a862dfa40e99.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/2767-31784bfedf8e245d.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{2318-450e75d07605b8fe.js → 2774-719820e3f5b2a3eb.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/2812-f016aa0dda149287.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/{4725-34bed25720cc326b.js → 2829-734fe8bf2eee7347.js} +1 -1
  35. package/apps/pwa/out/_next/static/chunks/311-32dcac79970985e8.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3175-f93f7495cd28253c.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3184.8da993f5502d2140.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3231-d7c981db0ff8bdcc.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3250.151309c5176d6b4b.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3330.7443183b7e6fdbdf.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3517.a5aa1797a9dbf2ee.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/3567-45f676877ed9e8a5.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3746-f80a78f220bf37b5.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/3819.8a1de79b2e8c7298.js +24 -0
  45. package/apps/pwa/out/_next/static/chunks/39.9b37b0be4c128a83.js +77 -0
  46. package/apps/pwa/out/_next/static/chunks/{4337e36d.f42c3b391b3d8f20.js → 3b355b3d.6f73c98bf6f9c749.js} +1 -1
  47. package/apps/pwa/out/_next/static/chunks/4023.a19045970a9ce16a.js +36 -0
  48. package/apps/pwa/out/_next/static/chunks/{58edce7d.f1b0c72acf13b123.js → 409c787b.e48c5bec8ec10456.js} +1 -1
  49. package/apps/pwa/out/_next/static/chunks/413-24c8284bda08241d.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4135.e45d6ebc29e20647.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4283.65502f5d0e6ff6c0.js +287 -0
  52. package/apps/pwa/out/_next/static/chunks/4305-4e28fa92a7b34a5b.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4335-50efa61fd7613142.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4351.0f37a6db2b34d50b.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/{5046.7fd5cbd859299448.js → 470.51a72a2348306455.js} +2 -2
  56. package/apps/pwa/out/_next/static/chunks/4720.ecbd1693fa151068.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/{2375.bf364c85dbb6f085.js → 4769.9fd582071301f382.js} +1 -1
  58. package/apps/pwa/out/_next/static/chunks/483.725e4a61be922788.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/{de8446d3.31b73eb239fecd7b.js → 4864a2ca.1c1c280a7772c5e5.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/4969-4b209d7307410c00.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5068-c7f53862f83c0917.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5315.bc96711c24dfefe2.js +74 -0
  63. package/apps/pwa/out/_next/static/chunks/{4383.18e5c54db3a22c88.js → 5383.bdfa5d886e39a826.js} +1 -1
  64. package/apps/pwa/out/_next/static/chunks/5436.fdf6fa8ae3e9588d.js +64 -0
  65. package/apps/pwa/out/_next/static/chunks/5542.efbf14f16baed4dd.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5622.94893f5aea7185d0.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5644.8f401a25601d05fc.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5658.35f70eb9871a54bf.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/5721.7bdc0e904c76ab51.js +8 -0
  70. package/apps/pwa/out/_next/static/chunks/5790-eef0ca20884a6bdf.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/5802.ef0d8598ca68fe84.js +62 -0
  72. package/apps/pwa/out/_next/static/chunks/5890.fb974729788dcb71.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/5924.5ef25cddd36d5dbf.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/5979-e59c099ebf8d1f35.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/6020.714cfeada2315e2e.js +94 -0
  76. package/apps/pwa/out/_next/static/chunks/6027-dfe0349d8c50f698.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/{6745-5a63492933959dd9.js → 6051-0ae955eedb10adb9.js} +3 -3
  78. package/apps/pwa/out/_next/static/chunks/6178.bc4730c86cf74536.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/{2283.edd9627b7bdfb546.js → 6257.c0037b8949239f5e.js} +2 -2
  80. package/apps/pwa/out/_next/static/chunks/6273.d808b0dcb3c2b155.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6292.6ef1df64fa6a4c8a.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/647-af8dd920ba46533c.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6541-170dc5c59e135c0c.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/6624.981ef7caeb680560.js +32 -0
  85. package/apps/pwa/out/_next/static/chunks/6742-a1ad4a94ba7bc37a.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/{6819.be5c9c4d67f22922.js → 6749.0744ce6eb08d40e9.js} +16 -16
  87. package/apps/pwa/out/_next/static/chunks/6836-493dc55c39187949.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/6856-53ac421c06039a18.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/6908.06008c67f6380ea9.js +148 -0
  90. package/apps/pwa/out/_next/static/chunks/6915.096931864206f522.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/6925.5e181fb7dcf90193.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/6cc1d1d6.9a98dd4622f1afc6.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7203-800e11037adc41eb.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7219-15bdd9a80661af8e.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7279.6170f591105936bb.js +93 -0
  96. package/apps/pwa/out/_next/static/chunks/7349-373165c7fbdcc3df.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/7514-a533ba0ca1cae4f4.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7515.1ad6efe157fa4448.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/7521.d919cc1fab80c1d9.js +24 -0
  100. package/apps/pwa/out/_next/static/chunks/7538.90e97bbdf9178cff.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/7611.85f045bf232053ac.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/7825-39203196a12579b2.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/7869.5e1a9a12fd70d6c7.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8086.1ab9103c41be884f.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8099.1cccf31c1baa7e1c.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8179-e61fffbdb70f1152.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8265.bdeb991b34db6a06.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/{2002-a43a3f380df873ec.js → 8272-025653884f9645d2.js} +1 -1
  109. package/apps/pwa/out/_next/static/chunks/{7867.e8725745ddd1d940.js → 8357.1aaa713b052a78b1.js} +4 -4
  110. package/apps/pwa/out/_next/static/chunks/8638-e42615f2166165b5.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/8639-92c11d069792429e.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/8691.54e22831d5e8ccf8.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/8d173e38.18a2f7b4e1848bdb.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/9069.657590a84afb8fac.js +41 -0
  115. package/apps/pwa/out/_next/static/chunks/9125-ae588d88a0293b93.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/{4313.76f232c304a15bde.js → 9175.2de5209a5ce6f68a.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/9184.45afbf44fec87574.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{8c58d09b.e8724a299658d86f.js → 9189505a.980427ac048c8c60.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/9311.f9f641a46a508611.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9371-a6fee8378ebfa3ee.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9421-3aa9ff4fa7f63d8a.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9992.07ce73c10bd5e6a1.js +79 -0
  123. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76394dc618d322c8.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/approvals/page-1b948637c37b3abd.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-c63400f1bcf3e47c.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/board/page-95d0957267819586.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ba957ff875a026a0.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/bots/page-bb6fd0714879cb87.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/ceo/page-8f9038520d2acbef.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/chat/page-d4b48397e05fce2c.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/consult/page-72d5744245dc0c27.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/control/page-37625dc8300fa43a.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/decisions/page-fbef9d160272dbc1.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/design-check/page-58424168df84928e.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/editor/page-72c12ba430ac57c0.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/exec/page-d53f3e9ed806d7e0.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/field/page-4d2fbd45feee0829.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/healthz/route-76394dc618d322c8.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/inside/page-8783dc0ed7590a2c.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/intake/page-3706cb390606e930.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/layout-9b0a86598e0111fd.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live/{page-3337c6a1328c2674.js → page-4edb8df90f4537ce.js} +1 -1
  143. package/apps/pwa/out/_next/static/chunks/app/live-run/page-83d27757e2b8060a.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/loops/page-47398b9ba1cc5e1b.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/market/page-fb86f55cfe2e681d.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e22345fc8fd47b1b.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/morning/{page-1e5da297557d2354.js → page-fca2e59a81744d9e.js} +1 -1
  148. package/apps/pwa/out/_next/static/chunks/app/not-found-6e96bda63100b31e.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/observatory/page-4d17ad8e0db8cea4.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-121f92766c33beaa.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-43f14212c545f92d.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ccec2023e7a974ec.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/outputs/page-b04f33f548b89a94.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/page-c8792823c0917021.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/reflection/page-8c0e32782ceef4cb.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-94bd3922eb230ce8.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/sessions/page-bca565887bafa03c.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ac1dffafe649fc6c.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/page-52374edb5e23e455.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ad4ebca120d43ca7.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/layout-76394dc618d322c8.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/page-718b89ce4b4ae4e4.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/share/page-204eca33eeeaddec.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/showroom/page-e58ba9bcdb9ac0f9.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/tasks/page-98f6dd50bafd7734.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/term/{page-ac2c1e6169cfce57.js → page-139d722de1dcd6c1.js} +1 -1
  167. package/apps/pwa/out/_next/static/chunks/app/today/page-5a4bdd72bff27057.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/trace/page-6f6ab17d44f984ce.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/vault/page-aabb7bd15fb72da9.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-e4322319164a4436.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/page-e9efc0c8f32e2371.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workspace/{page-c1c80e345fa9d6f5.js → page-ccde99f07aaf71f7.js} +1 -1
  173. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-80464aced9614390.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/{d9815f84.4918f682a45a8502.js → b84cad00.594027ebe0531fe2.js} +3 -3
  175. package/apps/pwa/out/_next/static/chunks/c696986b.5dc8bb1143af16d1.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/{709a918c.4fd3b4e2a32cb4e3.js → ca3702f8.2913182e73889fa2.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/d5d3cefc-373c4eb722ed848b.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/{5f6af561-f90b7a67f4f75d13.js → d8de0de2-dd0f4ac8e5ab1832.js} +1 -1
  179. package/apps/pwa/out/_next/static/chunks/framework-002b472a66935d31.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-49b88d47292c0476.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/main-app-fff2549cb10a133f.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_app-32abbbba3f3b76b7.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/pages/_error-9d9cfef60c60dd7a.js +1 -0
  184. package/apps/pwa/out/_next/static/chunks/webpack-cc7f483fa294034a.js +1 -0
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +22 -22
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +22 -22
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +22 -22
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +21 -21
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +21 -21
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +22 -22
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +21 -21
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +22 -22
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +22 -22
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +21 -21
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +22 -22
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +22 -22
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +22 -22
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +22 -22
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +21 -21
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +21 -21
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +22 -22
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +22 -22
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +22 -22
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +21 -21
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +21 -21
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +22 -22
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +22 -22
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +21 -21
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +21 -21
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +21 -21
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +22 -22
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +22 -22
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +21 -21
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +22 -22
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +22 -22
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +22 -22
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +22 -22
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +22 -22
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +21 -21
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +22 -22
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +22 -22
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +22 -22
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +22 -22
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +22 -22
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +22 -22
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +22 -22
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +22 -22
  278. package/graphs/demo/persona-marketer/fixtures/marketer-scenario.yaml +10 -0
  279. package/graphs/demo/persona-marketer/persona-marketer.yaml +25 -0
  280. package/graphs/demo/persona-marketer/recipes.yaml +19 -0
  281. package/graphs/release/recipes.yaml +9 -0
  282. package/graphs/release/release-loop.yaml +26 -18
  283. package/graphs/video/explainer-line.yaml +4 -1
  284. package/package.json +1 -1
  285. package/scripts/ask-op-inbox-once.ts +17 -0
  286. package/scripts/brand/check.ts +13 -4
  287. package/scripts/dead-code/report.ts +169 -0
  288. package/scripts/gate-0226-accepted-remaining-90.txt +91 -0
  289. package/scripts/gate-0226-failure-census.ts +39 -0
  290. package/scripts/intake-collect-telegram-saved-stage.ts +48 -0
  291. package/scripts/lib/morning-report-options.ts +3 -4
  292. package/scripts/lib/tui-regress-evidence.ts +56 -0
  293. package/scripts/morning-report.ts +5 -1
  294. package/scripts/provision-export-redactions.ts +15 -0
  295. package/scripts/public-copy-lint.ts +122 -0
  296. package/scripts/public-export.ts +77 -2
  297. package/scripts/ratchets/next-tui-entry-budget.ts +124 -0
  298. package/scripts/ratchets/train-side-invariants.sh +7 -1
  299. package/scripts/release-loop/cut-branch.ts +61 -12
  300. package/scripts/release-loop/export-check-node.ts +21 -3
  301. package/scripts/release-loop/gate-node.ts +527 -60
  302. package/scripts/release-loop/gate-partial.ts +82 -3
  303. package/scripts/release-loop/gate-prewarm-plan.ts +35 -0
  304. package/scripts/release-loop/gate-radius-live.ts +4 -2
  305. package/scripts/release-loop/gate-shard-dispatch.ts +128 -0
  306. package/scripts/release-loop/gate-shard-receipts.ts +89 -0
  307. package/scripts/release-loop/gate-wall.ts +5 -5
  308. package/scripts/release-loop/preflight.ts +6 -2
  309. package/scripts/release-loop/resume-cap.ts +2 -1
  310. package/scripts/release-loop/resume-release.ts +317 -13
  311. package/scripts/release-loop/resume.ts +61 -5
  312. package/scripts/release-loop/traffic-node.ts +12 -4
  313. package/scripts/release-loop/traffic-transition.ts +53 -13
  314. package/scripts/release-loop/version-node.ts +35 -5
  315. package/scripts/release-story/draft.ts +1 -1
  316. package/scripts/research-bench/README.md +53 -0
  317. package/scripts/research-bench/questions.json +66 -0
  318. package/scripts/research-bench/rubric.md +33 -0
  319. package/scripts/research-bench/run.ts +523 -0
  320. package/scripts/tui-regress.ts +85 -10
  321. package/scripts/ux-sim.ts +1 -1
  322. package/scripts/video-pipeline.ts +2 -2
  323. package/src/acp/core-turn-bridge.ts +14 -1
  324. package/src/agent/autonomous-tools.ts +10 -3
  325. package/src/agent/monad-agent-turn.ts +4 -1
  326. package/src/agent/registry.ts +26 -2
  327. package/src/agent/run-context.ts +1 -1
  328. package/src/agent/shared-app-tools.ts +1 -1
  329. package/src/agent/surface-ux/build.ts +12 -3
  330. package/src/agent/surface-ux/types.ts +1 -1
  331. package/src/agent/task-notification.ts +78 -7
  332. package/src/agent/types.ts +3 -0
  333. package/src/agent-mission/driver.ts +29 -3
  334. package/src/agent-mission/mission-cli.ts +2 -1
  335. package/src/agent-substrate/review-context-pack.ts +365 -0
  336. package/src/agent-substrate/review-observation.ts +10 -0
  337. package/src/agent-substrate/self-review-cli.ts +419 -42
  338. package/src/ask-user-question/index.ts +6 -0
  339. package/src/ask-user-question/inline-resolver.ts +49 -0
  340. package/src/auto-research/question-ladder-contract.ts +156 -0
  341. package/src/auto-research/research-turn.ts +467 -0
  342. package/src/autopilot/agent-loop.ts +1 -1
  343. package/src/autopilot/discovery/doc-lint.ts +1 -1
  344. package/src/autopilot/pty-control-loop.ts +8 -1
  345. package/src/boot/daemon-tools/index.ts +4 -3
  346. package/src/boot/daemon-tools/self-implement.ts +270 -2
  347. package/src/boot/daemon-tools/types.ts +2 -0
  348. package/src/bots/screen-probe.ts +1 -1
  349. package/src/budget/llm-cost.ts +44 -5
  350. package/src/budget/unified-usage.ts +17 -1
  351. package/src/capture/tui-self-report.ts +24 -2
  352. package/src/chat/index.ts +34 -7
  353. package/src/chat/tool-render/dispatch.ts +8 -1
  354. package/src/cli/agent-cli.ts +43 -8
  355. package/src/cli/guardian-cli.ts +3 -1
  356. package/src/cli/intake-cli.ts +70 -13
  357. package/src/cli/lesson-cli.ts +86 -10
  358. package/src/cli/log-event-names.ts +1 -0
  359. package/src/cli/pod-cli.ts +17 -2
  360. package/src/cli/pr-land-overlap-evidence.ts +38 -5
  361. package/src/cli/pr-land-refusal.ts +1 -1
  362. package/src/cli/pty-takeover-cli.ts +125 -12
  363. package/src/cli/release-checklist-read-cli.ts +5 -2
  364. package/src/cli/release-cli.ts +99 -15
  365. package/src/cli/repo-cli.ts +2 -1
  366. package/src/cli/review-carry.ts +77 -0
  367. package/src/cli/self-update.ts +1 -1
  368. package/src/cli/tasks-card-show.ts +31 -1
  369. package/src/cli/tasks-cli.ts +98 -32
  370. package/src/cli/tasks-read-cli.ts +13 -5
  371. package/src/context-bus/context-now.ts +86 -2
  372. package/src/control-plane/ledger.ts +21 -4
  373. package/src/core-turn/run-core-turn.ts +51 -3
  374. package/src/core-turn/run-goal-loop.ts +152 -8
  375. package/src/core-turn/types.ts +12 -0
  376. package/src/dashboard/chat/acp-chat.ts +2 -2
  377. package/src/dashboard/classic-sigquit.ts +16 -0
  378. package/src/dashboard/index.ts +339 -44
  379. package/src/dashboard/input/chat-main-interaction-opts.ts +3 -0
  380. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +7 -2
  381. package/src/dashboard/input/chat-main-slash-command.ts +7 -0
  382. package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
  383. package/src/dashboard/input/dashboard-priority-key-route.ts +21 -5
  384. package/src/dashboard/input/external-input-host.ts +2 -0
  385. package/src/dashboard/input/terminal-modal-router.ts +8 -159
  386. package/src/dashboard/side-basic-runtime.ts +61 -0
  387. package/src/dashboard/sidetab-runtime.ts +228 -0
  388. package/src/dashboard/slash-runtime/ask-clarification.ts +7 -1
  389. package/src/dashboard/slash-runtime/dashboard-handlers.ts +22 -8
  390. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -2
  391. package/src/dashboard/term-slash-runtime.ts +18 -18
  392. package/src/dashboard/turn-preamble.ts +30 -4
  393. package/src/domains/guardian-tick.ts +9 -0
  394. package/src/domains/knowledge.ts +1 -1
  395. package/src/esc-abort-gate.ts +33 -1
  396. package/src/execution-loop/launch-gate.ts +206 -1
  397. package/src/git-fs/watcher.ts +27 -22
  398. package/src/git-fs/worktree.ts +19 -3
  399. package/src/graph-runner/graph-cli.ts +6 -4
  400. package/src/graph-runner/graph-grow.ts +37 -9
  401. package/src/graph-runner/runner.ts +48 -11
  402. package/src/graph-wizard/generate.ts +16 -7
  403. package/src/graph-wizard/mission-compose.ts +201 -0
  404. package/src/grok/agent-search.ts +8 -2
  405. package/src/grok/credential.ts +112 -36
  406. package/src/grounding/ref-index.ts +11 -0
  407. package/src/grounding/ref-vector.ts +61 -0
  408. package/src/grounding/sources-cli.ts +2 -2
  409. package/src/grounding/sources.ts +15 -1
  410. package/src/harness/harness-cli-command.ts +38 -9
  411. package/src/harness/harness-pod-dispatch.ts +7 -1
  412. package/src/hq/fence-wrapper.ts +1 -1
  413. package/src/hq/transfer.ts +1 -1
  414. package/src/index.ts +60 -16
  415. package/src/input/external-input-queue.ts +10 -0
  416. package/src/intake-plane/collect-telegram-saved.ts +90 -6
  417. package/src/intake-plane/intake-to-tasks.ts +246 -3
  418. package/src/interactive-terminal-modal.ts +3 -0
  419. package/src/keybindings.ts +17 -22
  420. package/src/lessons/friction-ledger.ts +154 -0
  421. package/src/live-supply/collector.ts +149 -0
  422. package/src/live-supply/probes.ts +52 -0
  423. package/src/live-supply/snapshot.ts +40 -0
  424. package/src/llm/provider-credentials.ts +1 -1
  425. package/src/llm-tool-schema.ts +20 -0
  426. package/src/llm.ts +486 -61
  427. package/src/loops/orchestrator/inbox-once.ts +28 -0
  428. package/src/loops/orchestrator/inbox.ts +130 -1
  429. package/src/loops/orchestrator/tick.ts +14 -3
  430. package/src/maturity/feature-maturity.ts +1 -0
  431. package/src/nexus/api/channel-ask-op.ts +96 -0
  432. package/src/nexus/api/discord-trigger-bot.ts +28 -1
  433. package/src/nexus/api/harness-api.ts +2 -1
  434. package/src/nexus/api/telegram-trigger-bot.ts +24 -0
  435. package/src/nexus/api/terminals.ts +28 -6
  436. package/src/patents/ledger.ts +18 -1
  437. package/src/preview/terminal.ts +4 -2
  438. package/src/prompt-cache/anthropic.ts +2 -0
  439. package/src/prompt-enhance/enhance.ts +5 -0
  440. package/src/pty/snapshot.py +132 -0
  441. package/src/pty-shell/pty-control-ipc.ts +29 -2
  442. package/src/pty-shell/pty-manifest.ts +75 -5
  443. package/src/pty-shell/registry.ts +2 -0
  444. package/src/pty-shell/tui-run-state.ts +80 -3
  445. package/src/release-loop/gate-host-reservation.ts +13 -4
  446. package/src/release-loop/gate-shard-ledger.ts +68 -0
  447. package/src/release-loop/gate-shards.ts +61 -0
  448. package/src/release-loop/light-rc.ts +7 -4
  449. package/src/release-loop/merged-pr-checklist.ts +25 -2
  450. package/src/release-loop/rehearsal-shard-plan.ts +6 -1
  451. package/src/release-loop/rehearsal.ts +28 -1
  452. package/src/repl/index.ts +10 -0
  453. package/src/research/axis-fanout.ts +133 -0
  454. package/src/research/edge-decision.ts +197 -0
  455. package/src/research/gap-followup.ts +249 -0
  456. package/src/research/lenses/counter-evidence.ts +100 -0
  457. package/src/research/lenses/working-backwards.ts +89 -0
  458. package/src/research/output-router.ts +127 -0
  459. package/src/research/plugin-discovery.ts +242 -0
  460. package/src/research-bridge/format.ts +16 -1
  461. package/src/research-bridge/index.ts +1 -0
  462. package/src/research-bridge/invoke.ts +45 -7
  463. package/src/research-bridge/types.ts +2 -0
  464. package/src/self-dev/ask-launch-flow.ts +34 -106
  465. package/src/self-dev/decompose.ts +45 -9
  466. package/src/self-dev/dev-cli.ts +2 -0
  467. package/src/self-dev/dev-pipeline.ts +8 -4
  468. package/src/self-dev/draft-residue.ts +221 -2
  469. package/src/self-dev/draft-sweep.ts +29 -16
  470. package/src/self-dev/graph-journey-route.ts +10 -2
  471. package/src/self-dev/launch-preflight-text.ts +2 -2
  472. package/src/self-dev/launch-preflight.ts +38 -7
  473. package/src/self-dev/orchestrate-cli.ts +1 -0
  474. package/src/self-dev/orchestrate.ts +1 -0
  475. package/src/self-dev/run-supervisor.ts +41 -7
  476. package/src/self-dev/shard-run.ts +260 -3
  477. package/src/self-implement/comment-only-source.ts +54 -0
  478. package/src/self-implement/device-first.ts +8 -2
  479. package/src/self-implement/doctor-visit.ts +100 -57
  480. package/src/self-implement/gate-artifacts.ts +5 -2
  481. package/src/self-implement/gate-baseline.ts +119 -13
  482. package/src/self-implement/gate-cli.ts +466 -93
  483. package/src/self-implement/gate-failure-signature.ts +44 -0
  484. package/src/self-implement/gate-receipt-registry.ts +180 -0
  485. package/src/self-implement/gate-remote.ts +147 -22
  486. package/src/self-implement/goal-author-clarification.ts +178 -24
  487. package/src/self-implement/goal-author-decompose.ts +24 -15
  488. package/src/self-implement/goal-author.ts +82 -7
  489. package/src/self-implement/goal-doc/section.ts +22 -0
  490. package/src/self-implement/goal-supervisor-fill.ts +38 -4
  491. package/src/self-implement/host-regate.ts +120 -45
  492. package/src/self-implement/impl-findings-feedback.ts +188 -0
  493. package/src/self-implement/knowhow-pack.ts +301 -9
  494. package/src/self-implement/l8-merge-queue.ts +198 -32
  495. package/src/self-implement/off-diff-evidence.ts +147 -0
  496. package/src/self-implement/orchestrator.ts +137 -16
  497. package/src/self-implement/pod-inplace-worktree.ts +82 -0
  498. package/src/self-implement/pod-warm-pool-profile.ts +2 -2
  499. package/src/self-implement/premise-review.ts +7 -5
  500. package/src/self-implement/run-ledger.ts +304 -8
  501. package/src/self-implement/run-stop.ts +12 -0
  502. package/src/self-implement/seams.ts +39 -13
  503. package/src/self-implement/self-implement-cli.ts +30 -4
  504. package/src/session/channel-ask-op-envelope.ts +36 -0
  505. package/src/session/channel-op-reply-route.ts +200 -0
  506. package/src/session/chat.ts +92 -15
  507. package/src/session/index.ts +2 -0
  508. package/src/session-runtime/index.ts +9 -22
  509. package/src/session-runtime/provider-circuit.ts +140 -0
  510. package/src/shell-runner/file-engine.ts +1 -0
  511. package/src/shell-runner/types.ts +4 -0
  512. package/src/sidetab-core/model.ts +176 -0
  513. package/src/skills/runner.ts +7 -3
  514. package/src/skills/tools/dev-harness.ts +2 -2
  515. package/src/skills/tools/schedule-wakeup.ts +24 -7
  516. package/src/skills/tools/shell.ts +51 -5
  517. package/src/status/bar.ts +3 -3
  518. package/src/steward/directive-audit.ts +354 -0
  519. package/src/storage/file-lock.ts +17 -4
  520. package/src/surface/child-process.ts +31 -0
  521. package/src/surface/tui-stderr-owner.ts +48 -0
  522. package/src/task-agent/adopt-pr.ts +63 -2
  523. package/src/task-agent/cover.ts +30 -12
  524. package/src/task-agent/evidence-command-normalize.ts +42 -0
  525. package/src/task-agent/export-redactions-provision.ts +43 -0
  526. package/src/task-agent/judge.ts +56 -0
  527. package/src/task-agent/parent-host.ts +59 -12
  528. package/src/task-agent/postland-card.ts +35 -2
  529. package/src/task-agent/rejudge-on-head.ts +46 -2
  530. package/src/task-agent/repair-cycle.ts +68 -9
  531. package/src/task-agent/repair-worker.ts +37 -1
  532. package/src/task-agent/task-hand.ts +226 -33
  533. package/src/task-agent/tier-split.ts +142 -24
  534. package/src/task-orchestrator/surfaces/pod-command-job.ts +330 -2
  535. package/src/task-orchestrator/surfaces/pod-config-snapshot.ts +123 -0
  536. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +57 -5
  537. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +11 -8
  538. package/src/task-orchestrator/surfaces/pod-pool.ts +27 -4
  539. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +1 -1
  540. package/src/task-orchestrator/surfaces/pod-source-receive.ts +74 -6
  541. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +2 -1
  542. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +56 -15
  543. package/src/task-orchestrator/surfaces/self-implement-pod.ts +310 -79
  544. package/src/task-orchestrator/surfaces/self-implement.ts +33 -2
  545. package/src/terminal/session-registry.ts +1 -0
  546. package/src/terminal/terminal-modal-router.ts +156 -0
  547. package/src/tool-hints/gate.ts +6 -4
  548. package/src/tool-hints/signals.ts +33 -1
  549. package/src/tool-runtime/skill-exec-runtime.ts +95 -5
  550. package/src/tui/chat/background-job-status.ts +8 -2
  551. package/src/tui/entry.ts +483 -32
  552. package/src/tui/inline-choice.ts +188 -0
  553. package/src/tui/sidetab/attach.ts +304 -0
  554. package/src/tui/sidetab/list.ts +2 -0
  555. package/src/tui/sidetab/nl-tool.ts +136 -0
  556. package/src/tui/slash/resume-command.ts +23 -0
  557. package/src/tui/slash/resume.ts +3 -23
  558. package/src/tui/slash/term-next.ts +2 -1
  559. package/src/tui/slash/term.ts +12 -1
  560. package/src/tui-client/dashboard-session.ts +7 -1
  561. package/src/tui-client/local-chat-turn.ts +29 -8
  562. package/src/user-config.ts +42 -3
  563. package/src/ux-sim/classic-tui-seat-scenarios.ts +1 -7
  564. package/src/ux-sim/fake-land-queue.ts +88 -0
  565. package/src/ux-sim/fake-llm.ts +11 -5
  566. package/src/ux-sim/gate-shard-host-reroute.ts +82 -0
  567. package/src/ux-sim/goal-interim-trace.ts +24 -0
  568. package/src/ux-sim/next-tui-seat-scenarios.ts +61 -14
  569. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +4 -1
  570. package/src/version/packed-revision.json +1 -1
  571. package/src/video-pipeline/recipes/explainer.ts +54 -2
  572. package/src/web-search/grok.ts +32 -6
  573. package/src/web-search/index.ts +8 -7
  574. package/src/workflow-runtime/node-catalog.ts +53 -4
  575. package/apps/pwa/out/_next/static/chunks/1041-5841aae848fb6403.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/1087.3177e54f672dc526.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/1105.efe1e13503ac7a33.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/1224.2ceca6c180d5130b.js +0 -62
  579. package/apps/pwa/out/_next/static/chunks/1417-1768233ac92f8a5d.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/1612.81bbc19af06af16c.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/1766.728d42053070bb2d.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/1773.d38e945481e04125.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/1974-c12f9600da3d3c26.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/1ed5e8af.cf424815c7c0efad.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/2061.7232dc9dc058417f.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/210.90b2cbd64926cf34.js +0 -32
  587. package/apps/pwa/out/_next/static/chunks/244-a810d282a20f1783.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/2479-fe7e188bd9402d14.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/2514.03b60f266531a015.js +0 -148
  590. package/apps/pwa/out/_next/static/chunks/2526-a657538869888604.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/2533-6f0341ff075809e9.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/2676.e7994c695ef0f30d.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/2734.3ffdf54254fb6f99.js +0 -27
  594. package/apps/pwa/out/_next/static/chunks/2770-23252bf3a37880b9.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/2969.66b8b545139d1544.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/3128.a9210d08800ea6a8.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/3199.6a1a9b0e6cd01dc6.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/3212.12179fd3eee8cef1.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/3760-2909ddb9279281cd.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/3825.1921b5901bf33dce.js +0 -36
  601. package/apps/pwa/out/_next/static/chunks/3994-63eb884ed0547011.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/4036.d54e55e1ebf5acdc.js +0 -90
  603. package/apps/pwa/out/_next/static/chunks/4115.5b438b99f0ae729f.js +0 -226
  604. package/apps/pwa/out/_next/static/chunks/4269.d8f9f34bb0fc6c43.js +0 -287
  605. package/apps/pwa/out/_next/static/chunks/431-4eed5bd2c5fe1719.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/4324.c99ba3e83eb1b691.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/4599-96eff3f2a9c242c1.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/4825-a9d9d4e9f5892309.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/4833-7934c592c5569f00.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/4879-68518f547a207aff.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/4896.f9b70285363b27b2.js +0 -24
  612. package/apps/pwa/out/_next/static/chunks/4937-28d437999b77c9dd.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/49aa54ab.80f39398e0ed0f30.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/5056.482687319b82638e.js +0 -104
  615. package/apps/pwa/out/_next/static/chunks/506.16b83d56a437a9ee.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/5260-20593b0a25d0afbc.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/5404.cc4e9fec26fd5925.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/576.485e83e3f3dec19a.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/5832-a6be14e663f65726.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/5854-56648a9fe646b9a0.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/5925.3b1f8b135710249b.js +0 -93
  622. package/apps/pwa/out/_next/static/chunks/5952.294fc574a8625184.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/6168.17749aa3905fa073.js +0 -74
  624. package/apps/pwa/out/_next/static/chunks/6416.5d50b8ec9986ca98.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/6758.e7fbf532953c0783.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/6795.0cb8a59730d99703.js +0 -149
  627. package/apps/pwa/out/_next/static/chunks/6877-84d47b7e85d0c41e.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/6971-fb5f9dc0a2cb5d2d.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/717.522b08685979b814.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/7191.e41eb8f455c7f089.js +0 -41
  631. package/apps/pwa/out/_next/static/chunks/7233.8e744b7513119409.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/7238-97c2226f80504bd8.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/7285.307963afcf7e7660.js +0 -24
  634. package/apps/pwa/out/_next/static/chunks/7299-fbe4b8c47a87614a.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/7314.df0d95930b0c3f50.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/7406.c0589fdf2ee66629.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/752-90e3e7daad3d8e39.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/7524-bcd3d9928c6842d9.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/7549.9a4de3bf231cfc52.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/757-4fbaf50942b8c424.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/765.76ae970ceb597b5b.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/7893-e444a1b0809cd1e4.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/7956-33748cabb3a05562.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/7c5ed21f-f286708e57cf88f7.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/8030-aa66b478b53dbfca.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/8051.c88c07dacbbc5f21.js +0 -8
  647. package/apps/pwa/out/_next/static/chunks/8080-40d781e7704d3671.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/8149.80e402d4345e8dae.js +0 -77
  649. package/apps/pwa/out/_next/static/chunks/8205.50a5268f4e12ba0b.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/8231.a128feaa6f8b6079.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/85.4ddb1dda2ea3ffa2.js +0 -286
  652. package/apps/pwa/out/_next/static/chunks/8537.26517a09e8247beb.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/8595-e9b7081ab773a61f.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/8821-30cc65a61a60951f.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/8905.b3385aadb7b133e6.js +0 -79
  656. package/apps/pwa/out/_next/static/chunks/8983.246bb3a1ac38f50f.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/9072.18342f5941a1f3ec.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/9123.9df04866b2d6e00f.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/9175-7d383df15a82e2be.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/9181-bf89c07ce5b8f599.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/920-429bbc4504b45f71.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/9207.625edf45d656151c.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/9378.d2575c6ffd6dd756.js +0 -94
  664. package/apps/pwa/out/_next/static/chunks/957.db5b5c4d32a35240.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/958.53a8dcf4729e6997.js +0 -64
  666. package/apps/pwa/out/_next/static/chunks/9647.8f0cd0898c592a29.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/9665-26abb02665704c2c.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/9703.e7d81b6faef1050a.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/9882-7a9164b3c2dacbe5.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/9998.b74e033efadecd10.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c604fb980a634d88.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ec2d8a4979ca9075.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-cb6add08ad3c7660.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/board/page-e2eaa321ec223fe6.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/botlab/page-5b8a09c475b5f844.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/bots/page-91a77daedfbac191.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/ceo/page-f37fc5e974bda39b.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/chat/page-91429a0b78415a94.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/consult/page-b95798b58263b910.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/control/page-763d53e175e17aa1.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/decisions/page-d55023204055b12f.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/design-check/page-89d2140d78abc810.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/editor/page-82dc069abfe27f55.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/exec/page-25d9eee7beb552c0.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/field/page-770b4594c713ee97.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c604fb980a634d88.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/app/inside/page-ba8e0dcae4f83985.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/app/intake/page-5c112c6d7c33656e.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/app/layout-09788e1aa9a87db6.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/app/live-run/page-89acd5d68c0bc560.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/app/loops/page-5c13e2c76371d797.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/app/market/page-653a9f18642825c6.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-fe986fe79b107546.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/app/not-found-91ea9f5869a40943.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/observatory/page-7824e21b999962e2.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-53d00a60cc75a922.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-88a1edbff62eaf1d.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e931248b3f9574b.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/outputs/page-443364c9e4a23b31.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/app/page-b9af2ac1c4737ce8.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/app/reflection/page-25ab9c614c14129b.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-dbcdcfac0a395a8a.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/app/sessions/page-bf1de6645089ec58.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c4201761a5e839c9.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/app/settings/page-c304f469ea5d70e4.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8e5a238cf5e50c9c.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c604fb980a634d88.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/app/setup/page-32b526069ee50b3c.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/app/share/page-fb9e639c107f5f72.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/app/showroom/page-84220c776608cedc.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/app/tasks/page-e475618cbfd5ca2b.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/app/today/page-fccd3020af2f8806.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/app/trace/page-9c0d7198ff7b5a91.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/app/vault/page-d54b1ec9b9c6430d.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8c4bef1791d732ca.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/app/workflows/page-46fcc0b0bbc6fbfe.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7dfda00afd172f5b.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/f21fd540.63ac75328926ed30.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/framework-77fdcc873519a6cd.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/main-app-d0d620d2ce235713.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/main-e0ef79c79337ba90.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/pages/_app-84b1bc71e3f9ce6a.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/pages/_error-2acb61f1363128cb.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/webpack-462ff5727ceb7824.js +0 -1
  725. package/scripts/migrate-monad-to-elanous.ts +0 -195
  726. package/scripts/rebrand-elanous.ts +0 -242
  727. /package/apps/pwa/out/_next/static/{8kITumG9GAZ1LwT9POrAR → HjeK7zONHfR7op1hKXp4k}/_ssgManifest.js +0 -0
@@ -89,7 +89,7 @@ export function renderToolResultVariants(
89
89
  // Only successful MsgPost results enter the compact renderer. Returning
90
90
  // null for errors lets the dashboard formatter use its existing generic
91
91
  // result path, including its expanded argument/result view.
92
- if (kind === 'MsgPost' && extractErrorText(call.result)) return null;
92
+ if (kind === 'MsgPost' && isMsgPostErrorResult(call.result)) return null;
93
93
  const model = buildToolRenderModel(kind, call, config);
94
94
  const collapsed = renderToolBlock(model, config.blockMaxLines, config.foldMode, config.expandHint);
95
95
  // ⭐ MsgPost 는 접힌 행에서 본문을 빼고 펼친 행에서만 싣는다 ⇒ 같은 model 로는 두 변형을
@@ -113,6 +113,13 @@ interface ToolRenderModelOptions {
113
113
  includeMsgPostBody?: boolean;
114
114
  }
115
115
 
116
+ /** MsgPost 오류 — `llm.ts` 가 throw 를 `{ error }` 로 감싼 형태와, `ok: false` 결과. */
117
+ function isMsgPostErrorResult(result: unknown): boolean {
118
+ if (extractErrorText(result)) return true;
119
+ const rec = asRecord(result);
120
+ return rec?.ok === false;
121
+ }
122
+
116
123
  function normalizeToolRenderName(name: string): ToolRenderKind | null {
117
124
  if (name === 'update_plan' || name === 'UpdatePlan') return 'UpdatePlan';
118
125
  if (name === 'update_goal' || name === 'UpdateGoal') return 'UpdateGoal';
@@ -68,6 +68,25 @@ export function setCliAgentDispatchForTesting(dispatch: CliAgentDispatch | undef
68
68
  cliAgentDispatchForTesting = dispatch;
69
69
  }
70
70
 
71
+ /** A completed standalone agent turn must not wait forever for a tool's leftover handle. */
72
+ function armAgentCliExitSafetyNet(): void {
73
+ const timer = setTimeout(() => {
74
+ try {
75
+ const runtime = process as typeof process & {
76
+ _getActiveHandles?: () => Array<{ constructor?: { name?: string } }>;
77
+ _getActiveRequests?: () => Array<{ constructor?: { name?: string } }>;
78
+ };
79
+ const handleTypes = runtime._getActiveHandles?.().map(h => h.constructor?.name ?? 'unknown') ?? [];
80
+ const requestTypes = runtime._getActiveRequests?.().map(r => r.constructor?.name ?? 'unknown') ?? [];
81
+ debug.log('agent.cli.exit', 'grace-expired', { handleTypes, requestTypes }, { level: 'warn' });
82
+ debug.flush();
83
+ } finally {
84
+ process.exit(0);
85
+ }
86
+ }, 1_000);
87
+ timer.unref();
88
+ }
89
+
71
90
  export function registerAgentCommands(program: Command): void {
72
91
  const agentCommand = program
73
92
  .command('agent')
@@ -128,6 +147,10 @@ export function registerAgentCommands(program: Command): void {
128
147
  // commander stores --no-tools as `tools: false`, plain absence as undefined → default true here.
129
148
  enableTools: opts.tools !== false,
130
149
  });
150
+ // runChatTurnCli has already flushed its JSON reply. Let clean turns exit
151
+ // naturally; a referenced child/socket/timer left by a tool gets one second
152
+ // before we log the surviving handles and end this standalone process.
153
+ armAgentCliExitSafetyNet();
131
154
  });
132
155
 
133
156
  // ── agent dispatch — RFC #7333 `A1` (트리거) ──
@@ -413,7 +436,7 @@ tierCmd
413
436
  * ui.info trailer and instead emits exactly ONE JSON line on stdout
414
437
  * at end-of-turn:
415
438
  * {sessionId, provider, model, reply, finalReply, transcript, logPath,
416
- * budget, durationMs, ts}
439
+ * budget, durationMs, ts, incomplete}
417
440
  * Stable shape so LLMs can self-spawn `elanous chat` for follow-ups
418
441
  * without parsing human-readable terminal output. */
419
442
  export async function runChatTurnCli(opts: {
@@ -484,7 +507,7 @@ export async function runChatTurnCli(opts: {
484
507
  dbg.setAmbientSessionId?.(session.id);
485
508
  } catch { /* debug module unavailable — fine */ }
486
509
  const replyChunks: string[] = [];
487
- // Tool calls delimit assistant messages. finalReply retains its last non-empty-message meaning.
510
+ // Tool calls delimit assistant messages. Only text after the last tool call can be the final reply.
488
511
  let segmentChunks: string[] = [];
489
512
  let lastSegment = '';
490
513
  let finalMessage = '';
@@ -507,14 +530,17 @@ export async function runChatTurnCli(opts: {
507
530
  let tools: ReturnType<typeof buildCliAgentTools> | undefined;
508
531
  let dispatchTool: ((name: string, args: Record<string, unknown>) => Promise<unknown>) | undefined;
509
532
  let enabledToolNames: string[] | undefined;
533
+ const toolAbort = new AbortController();
534
+ const abortToolsOnSigint = (): void => toolAbort.abort();
510
535
  if (opts.enableTools) {
511
536
  const built = buildCliAgentTools(opts.cfg, harnessSpace ? {
512
537
  sessionId: session.id,
513
538
  emitFeedback: emitHarnessFeedbackProgress,
514
539
  } : undefined); // ★ cfg 전달 → financeEnabled 시 finance 팩 노출(서피스 게이팅 정리)
515
540
  tools = built;
516
- dispatchTool = built.dispatch;
541
+ dispatchTool = (name, args) => built.dispatch(name, args, { signal: toolAbort.signal });
517
542
  enabledToolNames = built.specs.map(s => s.name);
543
+ process.once('SIGINT', abortToolsOnSigint);
518
544
  }
519
545
  // Wire the universal preamble (project anchor + project tree +
520
546
  // family addendum + session-specific guidance) into every CLI system
@@ -604,6 +630,8 @@ export async function runChatTurnCli(opts: {
604
630
  process.exit(2);
605
631
  }
606
632
  throw err;
633
+ } finally {
634
+ if (opts.enableTools) process.removeListener('SIGINT', abortToolsOnSigint);
607
635
  }
608
636
  if (!sawToolCall && replyChunks.length === 0 && result.text) {
609
637
  replyChunks.push(result.text);
@@ -611,6 +639,7 @@ export async function runChatTurnCli(opts: {
611
639
  if (!opts.json && !opts.enableTools) process.stdout.write(result.text);
612
640
  }
613
641
  closeSegment();
642
+ const incomplete = sawToolCall && finalMessage.length === 0;
614
643
  if (opts.json) {
615
644
  let logPath: string | null = null;
616
645
  try {
@@ -624,17 +653,23 @@ export async function runChatTurnCli(opts: {
624
653
  model: result.model ?? null,
625
654
  reply: finalMessage,
626
655
  transcript: replyChunks.join(''),
627
- finalReply: lastSegment,
656
+ finalReply: sawToolCall ? finalMessage : lastSegment,
657
+ incomplete,
628
658
  budget: sessionBudget(session.id),
629
659
  durationMs: Date.now() - startedAt,
630
660
  logPath,
631
661
  ts: new Date().toISOString(),
632
662
  };
633
663
  await writeStdoutJson(JSON.stringify(out) + '\n');
664
+ if (incomplete) process.exitCode = 1;
634
665
  return;
635
666
  }
636
667
  if (opts.enableTools) process.stdout.write(`${finalMessage}\n`);
637
668
  else process.stdout.write('\n');
669
+ if (incomplete) {
670
+ console.error('Turn ended without a final assistant reply.');
671
+ process.exitCode = 1;
672
+ }
638
673
  ui.info(`[session ${session.id.slice(0, 8)} ${result.provider}${result.model ? '/' + result.model : ''} ${sessionBudget(session.id)}]`);
639
674
  }
640
675
 
@@ -655,7 +690,7 @@ export function buildCliAgentTools(
655
690
  trustedWorkingDirectory?: string,
656
691
  ): {
657
692
  specs: import('../llm.js').LLMToolSpec[];
658
- dispatch: (name: string, args: Record<string, unknown>) => Promise<unknown>;
693
+ dispatch: (name: string, args: Record<string, unknown>, context?: { signal?: AbortSignal }) => Promise<unknown>;
659
694
  workingDirectory: string;
660
695
  } {
661
696
  // An explicitly assigned child cwd is stable for its isolated lifetime. An
@@ -706,7 +741,7 @@ export function buildCliAgentTools(
706
741
  // 게이트. [[project_skill_native_duplication_surface_gating]].
707
742
  const shared = (require('../agent/shared-app-tools.js') as typeof import('../agent/shared-app-tools.js')).buildSharedAppTools(cfg);
708
743
  for (const s of shared.specs) specs.push(s);
709
- for (const name of shared.names) dispatchByName.set(name, async (args) => shared.dispatch(name, args));
744
+ for (const name of shared.names) dispatchByName.set(name, async (args, signal) => shared.dispatch(name, args, { surface: 'tui', signal }));
710
745
  // Installed knowledge is queryable in CLI chat as well as the dashboard runtime.
711
746
  // No installed packs => preserve the existing CLI tool list and avoid creating a KGS database.
712
747
  const { kgsDefaultDbPath } = require('../knowledge/kgs/sqlite-store.js') as typeof import('../knowledge/kgs/sqlite-store.js');
@@ -751,10 +786,10 @@ export function buildCliAgentTools(
751
786
  const dispatchSessionRuntimeTool = sr.dispatchSessionRuntimeTool;
752
787
  const createPlanner = sr.createSearchPlannerState;
753
788
  const plannerState = createPlanner({ maxAutoNarrowCandidates: 2 });
754
- const dispatch = async (name: string, args: Record<string, unknown>): Promise<unknown> => {
789
+ const dispatch = async (name: string, args: Record<string, unknown>, context?: { signal?: AbortSignal }): Promise<unknown> => {
755
790
  try {
756
791
  const direct = dispatchByName.get(name);
757
- if (direct) return await direct(args);
792
+ if (direct) return await direct(args, context?.signal);
758
793
  // ⭐ BACKLOG L1b (2026-09-25) — ToolSearch 는 지연 도구가 있으면 «자동으로 광고»되는데 이 CLI 디스패처만
759
794
  // 라우팅이 없어 `plugin tool unavailable in CLI: ToolSearch` 로 죽었다(daemon·monad-agent-turn 은 라우팅한다).
760
795
  // ⇒ 같은 공용 라우터로 이 CLI 의 도구 풀에서 찾는다.
@@ -72,7 +72,9 @@ export function registerGuardianCommands(program: Command): void {
72
72
  debug.log('ops.orphan-cli', 'observation-failed', { error: String(error) });
73
73
  } catch { /* guardian shadow still runs */ }
74
74
  }
75
- const result = await guardianTick(tickAt, plan, { config: cfg });
75
+ const result = await guardianTick(tickAt, plan, { config: cfg,
76
+ doctorShadow: async () => { (await import('../self-implement/doctor-visit.js')).recordPendingShadowDoctorReevaluations(); },
77
+ });
76
78
  await writeStdoutJson(JSON.stringify(result, null, 2) + '\n');
77
79
  } finally { db.close(); }
78
80
  });
@@ -5,7 +5,7 @@ import type { Command } from 'commander';
5
5
  import { getElanousConfigDir } from '../elanous-config-dir.js';
6
6
  import { readNexusRuntime } from '../nexus/runtime.js';
7
7
  import { resolveRoleLlm } from '../user-config.js';
8
- import { runIntakeToTasks, type IntakeTaskInput, type IntakeTaskRequest, type IntakeToTasksResult } from '../intake-plane/intake-to-tasks.js';
8
+ import { approveChannelPublish, runIntakeToTasks, type IntakeTaskInput, type IntakeTaskRequest, type IntakeToTasksResult } from '../intake-plane/intake-to-tasks.js';
9
9
  import { writeStdoutJson } from './stdout-json.js';
10
10
  import { writeStdoutFully } from './stdout-flush.js';
11
11
  import { runGitCommand } from '../git-fs/runner.js';
@@ -13,6 +13,7 @@ import { debug } from '../debug/log.js';
13
13
  import { getUserConfig } from '../user-config.js';
14
14
  import { registerIntakeSourceCommands } from './intake-source-cli.js';
15
15
  import type { IntakeItem } from '../intake-plane/items.js';
16
+ import type { CollectSavedResult, FetchSavedMessages } from '../intake-plane/collect-telegram-saved.js';
16
17
  import type { TaskCard } from '../task-cards/card-store.js';
17
18
  import { collectFunnelCandidates, type FunnelDirectiveRow } from '../intake-plane/requirement-funnel.js';
18
19
 
@@ -31,6 +32,15 @@ export interface IntakeCandidatesCliDeps {
31
32
  write?: (text: string) => Promise<void>;
32
33
  }
33
34
 
35
+ export interface IntakeCliDeps extends IntakeCandidatesCliDeps {
36
+ /** 흡수 원장 우주 (기본 effectiveInstanceRoot()) — 시험은 격리 임시 root 를 넣는다. */
37
+ root?: string;
38
+ /** 텔레그램 «저장된 메시지» 연결 (기본 gramjsFetchSaved) — 시험은 가짜 fetch 를 넣는다. */
39
+ connectSaved?: () => Promise<{ fetch: FetchSavedMessages; close: () => Promise<void> }>;
40
+ /** 수집 연결 실패를 CLI 사용자에게 보고한다. */
41
+ error?: (message: string) => void;
42
+ }
43
+
34
44
  /** `--limit` 원 문자열 → 0 이상의 정수. 숫자만(`/^\d+$/`) 받고 나머지('' · 공백 · 음수 · 소수)는 거부한다. */
35
45
  export function parseCandidatesLimit(raw: string): number {
36
46
  const limit = /^\d+$/.test(raw) ? Number(raw) : NaN;
@@ -187,6 +197,40 @@ export async function runIntakeDigestCli(
187
197
  return {};
188
198
  }
189
199
 
200
+ export interface CollectTelegramSavedCliDeps {
201
+ root?: string;
202
+ connect?: () => Promise<{ fetch: FetchSavedMessages; close: () => Promise<void> }>;
203
+ write?: (text: string) => Promise<void>;
204
+ error?: (message: string) => void;
205
+ }
206
+
207
+ /**
208
+ * `intake collect-telegram-saved` — 읽기만 · 커서 이후만.
209
+ * «메시지 0»(필터로 비었나 · 커서를 다른 주체가 넘겼나)과 «원장 입력 0»(다른 주체가 이미 가져갔나)을 갈라 보여준다.
210
+ */
211
+ export async function runCollectTelegramSavedCli(
212
+ opts: { max?: string; dryRun?: boolean; json?: boolean },
213
+ deps: CollectTelegramSavedCliDeps = {},
214
+ ): Promise<CollectSavedResult | undefined> {
215
+ const { collectTelegramSaved, gramjsFetchSaved, renderCollectTelegramSavedResult } = await import('../intake-plane/collect-telegram-saved.js');
216
+ const root = deps.root ?? (await import('../instance/resolve.js')).effectiveInstanceRoot();
217
+ let conn: { fetch: FetchSavedMessages; close: () => Promise<void> };
218
+ try { conn = await (deps.connect ?? (() => gramjsFetchSaved()))(); }
219
+ catch (e) { (deps.error ?? ((message: string) => console.error(message)))(String((e as Error).message ?? e)); process.exitCode = 2; return undefined; }
220
+ try {
221
+ const res = await collectTelegramSaved(root, conn.fetch, {
222
+ max: Math.max(1, Number(opts.max ?? 300) || 300),
223
+ ...(opts.dryRun ? { dryRun: true } : {}),
224
+ });
225
+ const write = deps.write ?? writeStdoutFully;
226
+ if (opts.json) await write(JSON.stringify(res, null, 2));
227
+ else await write(renderCollectTelegramSavedResult(res));
228
+ return res;
229
+ } finally {
230
+ await conn.close();
231
+ }
232
+ }
233
+
190
234
  export function resolveIntakeCheckRoot(
191
235
  cwd: string,
192
236
  git: typeof runGitCommand = runGitCommand,
@@ -200,7 +244,7 @@ export function resolveIntakeCheckRoot(
200
244
  }
201
245
  }
202
246
 
203
- export function registerIntakeCommands(program: Command, candidateDeps: IntakeCandidatesCliDeps = {}): void {
247
+ export function registerIntakeCommands(program: Command, candidateDeps: IntakeCliDeps = {}): void {
204
248
  // ── intake check — 바깥 사실을 elanous 현재와 대조 (태스크 등록 없음) ──
205
249
  const intakeCmd = program.command('intake').description('바깥 사실·문서를 elanous 현재와 대조하거나 태스크로 받는다');
206
250
  registerIntakeSourceCommands(intakeCmd);
@@ -493,6 +537,24 @@ export function registerIntakeCommands(program: Command, candidateDeps: IntakeCa
493
537
  if (result.failed > 0) process.exitCode = 1;
494
538
  });
495
539
 
540
+ intakeCmd
541
+ .command('approve-channel-post <id>')
542
+ .description('보호 범주의 채널 게시 초안을 사람 승인한다 (외부 게시 커넥터는 호출하지 않는다)')
543
+ .requiredOption('--by <approver>', '승인자: MK | 대표')
544
+ .option('--json', '구조화 출력')
545
+ .action(async (id: string, opts: { by: string; json?: boolean }) => {
546
+ const { effectiveInstanceRoot } = await import('../instance/resolve.js');
547
+ const approved = approveChannelPublish(candidateDeps.root ?? effectiveInstanceRoot(), id, opts.by);
548
+ if (!approved) {
549
+ console.error(`대기 중인 보호 초안을 찾지 못했거나 승인자(${opts.by})가 MK·대표가 아니다: ${id}`);
550
+ process.exitCode = 1;
551
+ return;
552
+ }
553
+ const result = { id, status: approved.status, approvedBy: approved.approvedBy, category: approved.category };
554
+ if (opts.json) await writeStdoutFully(JSON.stringify(result) + '\n');
555
+ else console.log(`${id} → ${approved.status} · 승인자 ${approved.approvedBy} · 외부 게시 미실행`);
556
+ });
557
+
496
558
  intakeCmd
497
559
  .command('collect-telegram-saved')
498
560
  .description('텔레그램 «저장된 메시지»를 읽기만 해 흡수 원장에 넣는다 (커서 이후만 · 호스트 전용 · 개인 메모는 user-private)')
@@ -500,17 +562,12 @@ export function registerIntakeCommands(program: Command, candidateDeps: IntakeCa
500
562
  .option('--dry-run', '원장·커서를 바꾸지 않고 건수만')
501
563
  .option('--json', '구조화 출력')
502
564
  .action(async (opts: { max?: string; dryRun?: boolean; json?: boolean }) => {
503
- const { collectTelegramSaved, gramjsFetchSaved } = await import('../intake-plane/collect-telegram-saved.js');
504
- const { effectiveInstanceRoot } = await import('../instance/resolve.js');
505
- let conn: Awaited<ReturnType<typeof gramjsFetchSaved>>;
506
- try { conn = await gramjsFetchSaved(); } catch (e) { console.error(String((e as Error).message ?? e)); process.exitCode = 2; return; }
507
- try {
508
- const res = await collectTelegramSaved(effectiveInstanceRoot(), conn.fetch, { max: Math.max(1, Number(opts.max ?? 300) || 300), ...(opts.dryRun ? { dryRun: true } : {}) });
509
- if (opts.json) await writeStdoutFully(JSON.stringify(res, null, 2));
510
- else console.log(`텔레그램 저장된 메시지: 메시지 ${res.messages} · 원장 입력 ${res.raws} · 커서 ${res.cursorBefore} → ${res.cursorAfter}${res.dryRun ? ' (dry-run · 안 씀)' : res.ingest ? ` · 새 ${res.ingest.added} · 합침 ${res.ingest.merged} · 이미 끝난 것 ${res.ingest.seen}` : ''}`);
511
- } finally {
512
- await conn.close();
513
- }
565
+ await runCollectTelegramSavedCli(opts, {
566
+ ...(candidateDeps.root ? { root: candidateDeps.root } : {}),
567
+ ...(candidateDeps.connectSaved ? { connect: candidateDeps.connectSaved } : {}),
568
+ ...(candidateDeps.write ? { write: candidateDeps.write } : {}),
569
+ ...(candidateDeps.error ? { error: candidateDeps.error } : {}),
570
+ });
514
571
  });
515
572
 
516
573
  intakeCmd
@@ -1,6 +1,8 @@
1
1
  import type { Command } from 'commander';
2
- import { resolve } from 'node:path';
2
+ import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
3
+ import { dirname, resolve } from 'node:path';
3
4
  import { debug } from '../debug/log.js';
5
+ import { FrictionInputError, FrictionLedger, frictionActor, type FrictionRecordInput } from '../lessons/friction-ledger.js';
4
6
  import { importLessons, scanLessonDocs } from '../lessons/lesson-import.js';
5
7
  import { LessonInputError, LessonLedger, type LessonLedgerOptions, type LessonRow, type LessonDetail } from '../lessons/lesson-ledger.js';
6
8
 
@@ -38,9 +40,26 @@ function detail(row: LessonDetail): string {
38
40
  '이력:', ...row.history.map(h => ` ${h.at} · ${h.event} · ${h.by} · ${h.detail}`)].join('\n');
39
41
  }
40
42
 
43
+ function validAuthoringLessonClass(value: string): boolean {
44
+ return new Set(['a-missing-predecessor', 'b-stale-path', 'c-unbounded-goal', 'd-rigid-acceptance',
45
+ 'e-format-trap', 'f-unaware-of-code', 'g-umbrella-scope']).has(value) || /^env-[a-z0-9][a-z0-9-]*$/u.test(value);
46
+ }
47
+
41
48
  export function registerLessonCommands(program: Command, options: LessonLedgerOptions = {}, out: Pick<Console, 'log'> = console): void {
42
49
  const root = program.command('lesson').description('사고 · 원인 · 처방 · 재발 교훈 원장');
43
50
  const ledger = () => new LessonLedger(options);
51
+ // 손 걸음 원장은 그림자 기록이다: 비밀 꼴 note 는 빼고 남기며, 어떤 경우에도 lesson 명령을 실패시키지 않는다.
52
+ const recordFriction = (input: FrictionRecordInput): void => {
53
+ const friction = new FrictionLedger(options);
54
+ const attempts = input.note ? [input, { ...input, note: '' }] : [input];
55
+ for (const attempt of attempts) {
56
+ try { friction.record(attempt); return; }
57
+ catch (error) {
58
+ debug.log('lessons.friction', 'skipped', { kind: attempt.kind, signature: attempt.signature,
59
+ reason: error instanceof FrictionInputError ? error.message : String(error) });
60
+ }
61
+ }
62
+ };
44
63
  const emit = (value: unknown, json: boolean | undefined, text: string) => out.log(json ? JSON.stringify(value) : text);
45
64
  root.command('import').description('INCIDENT·FINDING 문서 교훈 미리 보기 (기본값); --apply 로 적재')
46
65
  .option('--apply', '원장에 적재').option('--json', 'JSON 출력').option('--by <name>', '기록자 (기본 AI_AGENT)')
@@ -68,19 +87,76 @@ export function registerLessonCommands(program: Command, options: LessonLedgerOp
68
87
  reportError('page', error instanceof Error ? error.message : String(error));
69
88
  }
70
89
  });
71
- root.command('add <id>').requiredOption('--incident <text>').requiredOption('--cause <text>')
72
- .requiredOption('--remedy <text>').requiredOption('--owner <name>').requiredOption('--source <path>')
73
- .option('--enforced-by <paths>').option('--disproof <command>').option('--by <name>')
74
- .action(handle('add', (id: string, o: { incident: string; cause: string; remedy: string; owner: string; source: string; enforcedBy?: string; disproof?: string; by?: string }) => {
75
- const by = actor(o.by);
76
- const row = ledger().add({ id, incident: o.incident, cause: o.cause, remedy: o.remedy, owner: o.owner,
77
- source: o.source, by, ...(o.enforcedBy !== undefined ? { enforcedBy: o.enforcedBy } : {}),
78
- ...(o.disproof !== undefined ? { disproof: o.disproof } : {}) });
90
+ root.command('add [id]').option('--incident <text>').option('--cause <text>').option('--remedy <text>')
91
+ .option('--owner <name>').option('--source <path>').option('--enforced-by <paths>').option('--disproof <command>').option('--by <name>')
92
+ .option('--authoring', '05-authoring-lessons.jsonl에 저작 교훈 한 행 추가')
93
+ .option('--cell <name>').option('--class <class>').option('--diag <text>').option('--action <text>').option('--lesson <text>')
94
+ .option('--run <id>').option('--card <id>').option('--launch <id>').option('--goal-sha <sha>')
95
+ .option('--paths <paths>').option('--model <model>').option('--host <host>').option('--evidence <text>')
96
+ .option('--rule <text>').option('--ms <milliseconds>').option('--outcome <state>', 'pending, fixed 또는 repeated')
97
+ .option('--resolve-pending <state>', '같은 cell/class의 pending을 fixed 또는 repeated로 전이')
98
+ .action(handle('add', (id: string | undefined, o: Record<string, string | boolean | undefined>) => {
99
+ if (o.authoring) {
100
+ const required = ['source', 'cell', 'class', 'diag', 'action', 'lesson'] as const;
101
+ const missing = required.filter((key) => typeof o[key] !== 'string' || !(o[key] as string).trim());
102
+ if (missing.length) throw new LessonInputError(`authoring fields required: ${missing.map(key => `--${key}`).join(', ')}`);
103
+ if (!validAuthoringLessonClass(o.class as string)) throw new LessonInputError('--class is not in the authoring lesson class set');
104
+ const outcome = typeof o.outcome === 'string' ? o.outcome : 'pending';
105
+ if (!['pending', 'fixed', 'repeated'].includes(outcome)) throw new LessonInputError('--outcome must be pending, fixed, or repeated');
106
+ if (o.resolvePending !== undefined && !['fixed', 'repeated'].includes(o.resolvePending as string)) {
107
+ throw new LessonInputError('--resolve-pending must be fixed or repeated');
108
+ }
109
+ const row: Record<string, string> = {
110
+ ts: new Date().toISOString(), by: actor(typeof o.by === 'string' ? o.by : undefined),
111
+ source: o.source as string, cell: o.cell as string, class: o.class as string, diag: o.diag as string,
112
+ action: o.action as string, lesson: o.lesson as string, run: String(o.run ?? ''), card: String(o.card ?? ''),
113
+ launch: String(o.launch ?? ''), goalSha: String(o.goalSha ?? ''), paths: String(o.paths ?? ''),
114
+ model: String(o.model ?? ''), host: String(o.host ?? ''), evidence: String(o.evidence ?? ''),
115
+ rule: String(o.rule ?? ''), ms: String(o.ms ?? ''), outcome,
116
+ };
117
+ const path = resolve(process.cwd(), 'docs/goal-context/05-authoring-lessons.jsonl');
118
+ let lines: string[] = [];
119
+ try {
120
+ lines = readFileSync(path, 'utf8').split(/\r?\n/u).filter(Boolean);
121
+ for (const line of lines) {
122
+ const parsed: unknown = JSON.parse(line);
123
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) throw new Error('not an object');
124
+ }
125
+ } catch (error) {
126
+ if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw new LessonInputError('authoring lessons ledger is unreadable or malformed');
127
+ }
128
+ if (typeof o.resolvePending === 'string') {
129
+ lines = lines.map((line) => {
130
+ const prior = JSON.parse(line) as Record<string, unknown>;
131
+ return prior.cell === row.cell && prior.class === row.class && prior.outcome === 'pending'
132
+ ? JSON.stringify({ ...prior, outcome: o.resolvePending }) : line;
133
+ });
134
+ }
135
+ mkdirSync(dirname(path), { recursive: true });
136
+ const next = [...lines, JSON.stringify(row)].join('\n') + '\n';
137
+ const temp = `${path}.tmp-${process.pid}`;
138
+ writeFileSync(temp, next, { encoding: 'utf8', flag: 'w' });
139
+ renameSync(temp, path);
140
+ emit({ written: true, row }, false, `저작 교훈 추가 · ${row.cell} · ${row.class} · ${row.outcome}`);
141
+ return;
142
+ }
143
+ const required = ['incident', 'cause', 'remedy', 'owner', 'source'] as const;
144
+ const lessonId = id ?? '';
145
+ const missing: string[] = required.filter((key) => typeof o[key] !== 'string' || !(o[key] as string).trim());
146
+ if (!lessonId.trim()) missing.unshift('id');
147
+ if (missing.length) throw new LessonInputError(`required: ${missing.map(key => key === 'id' ? 'id' : `--${key}`).join(', ')}`);
148
+ const by = actor(typeof o.by === 'string' ? o.by : undefined);
149
+ const row = ledger().add({ id: lessonId, incident: o.incident as string, cause: o.cause as string, remedy: o.remedy as string,
150
+ owner: o.owner as string, source: o.source as string, by,
151
+ ...(o.enforcedBy !== undefined ? { enforcedBy: o.enforcedBy as string } : {}),
152
+ ...(o.disproof !== undefined ? { disproof: o.disproof as string } : {}) });
79
153
  emit(row, false, format(row));
80
154
  }));
81
155
  root.command('recur <id>').requiredOption('--source <path>').option('--note <text>').option('--by <name>')
82
156
  .action(handle('recur', (id: string, o: { source: string; note?: string; by?: string }) => {
83
- const row = ledger().recur(id, { source: o.source, note: o.note ?? '', by: actor(o.by) });
157
+ const by = actor(o.by);
158
+ const row = ledger().recur(id, { source: o.source, note: o.note ?? '', by });
159
+ recordFriction({ actor: frictionActor(by), kind: 'hand-step', signature: row.incident ?? `lesson ${row.id}`, note: o.note ?? '', ref: o.source });
84
160
  emit(row, false, format(row));
85
161
  }));
86
162
  root.command('enforce <id>').requiredOption('--enforced-by <paths>').option('--by <name>')
@@ -1362,6 +1362,7 @@ export const KNOWN_LOG_EVENT_NAMES: ReadonlySet<string> = new Set([
1362
1362
  "status",
1363
1363
  "status-ledger",
1364
1364
  "status-port-resolved",
1365
+ "status-question-interim-reprompt",
1365
1366
  "stdin-backpressure",
1366
1367
  "stdout",
1367
1368
  "step",
@@ -14,7 +14,7 @@ import { getUserConfig } from '../user-config.js';
14
14
  import { listCodexAccountsInStore } from '../oauth/codex-account-store.js';
15
15
  import { parsePodPool, resolvePodPoolSpec, podPoolHostLease, type PoolKubectl } from '../task-orchestrator/surfaces/pod-pool.js';
16
16
  import { leaseKubectl, measurePoolLease, probePoolDns, probePoolGitHub, recommendConcurrency, type PoolLeaseMeasure, type PoolDnsProbe, type ExternalGitHubProbe } from '../task-orchestrator/surfaces/pod-lease.js';
17
- import { POD_COMMAND_DEADLINE_SECONDS, runPodCommand, type PodCommandResult, type RunPodCommandOptions } from '../task-orchestrator/surfaces/pod-command-job.js';
17
+ import { POD_COMMAND_DEADLINE_SECONDS, parseCpuRightsizeRequest, runPodCommand, type PodCommandResult, type PodCpuRightsizeRequest, type RunPodCommandOptions } from '../task-orchestrator/surfaces/pod-command-job.js';
18
18
  import { hostLeaseCounts, leaseHasPendingPod } from '../pod-lease/host-lease.js';
19
19
 
20
20
  export interface PodCliIo {
@@ -220,7 +220,8 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
220
220
  .allowUnknownOption(true)
221
221
  .allowExcessArguments(true)
222
222
  .option('--lite', '네트워크 스킬(omni-crawl·omni-digest)만 쓰는 명령 — 작은 이미지 ⊕ 2Gi 한도(POD7 · clone 불가)')
223
- .action(async (opts: { pool?: string; skill?: string; llm?: string; clone?: boolean; deadline?: string; lite?: boolean }, command: Command) => {
223
+ .option('--cpu-rightsize <json>', 'POD-CPU-REQUEST-RIGHTSIZE-2-FU: 공존 재측정 요청(JSON 파일 경로 또는 인라인 JSON) — { condition?, samples[], priorLaunches[] }. 선행 조건·측정이 모자라면 발사하지 않는다')
224
+ .action(async (opts: { pool?: string; skill?: string; llm?: string; clone?: boolean; deadline?: string; lite?: boolean; cpuRightsize?: string }, command: Command) => {
224
225
  const argv = process.argv.slice(2);
225
226
  const sep = argv.indexOf('--');
226
227
  const fromArgv = sep >= 0 ? argv.slice(sep + 1) : [];
@@ -244,6 +245,19 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
244
245
  return;
245
246
  }
246
247
  }
248
+ // POD-CPU-REQUEST-RIGHTSIZE-2-FU — the OP-facing measurement launch reads its request from JSON (file path or inline).
249
+ let cpuRightsize: PodCpuRightsizeRequest | undefined;
250
+ if (opts.cpuRightsize !== undefined) {
251
+ try {
252
+ const source = opts.cpuRightsize.trim();
253
+ const text = source.startsWith('{') ? source : readFileSync(source, 'utf8');
254
+ cpuRightsize = parseCpuRightsizeRequest(JSON.parse(text), '--cpu-rightsize');
255
+ } catch (err) {
256
+ io.error(`pod run: --cpu-rightsize — ${err instanceof Error ? err.message : String(err)}`);
257
+ io.exit(2);
258
+ return;
259
+ }
260
+ }
247
261
  const skills = (opts.skill ?? '').split(',').map((s) => s.trim()).filter(Boolean);
248
262
  const cloneWarning = podCloneWithoutInstallWarning(commandArgs, opts.clone);
249
263
  if (cloneWarning !== null) {
@@ -268,6 +282,7 @@ export function registerPodCommands(program: Command, deps: PodCliDeps = {}): vo
268
282
  ...(opts.llm === 'grok' ? { llm: 'grok' as const } : {}),
269
283
  ...(opts.clone ? { clone: true } : {}),
270
284
  ...(opts.lite ? { lite: true } : {}),
285
+ ...(cpuRightsize ? { cpuRightsize } : {}),
271
286
  ...(deadlineSeconds !== undefined ? { deadlineSeconds } : {}),
272
287
  });
273
288
  if (result.image) io.error(`[pod] image ${result.image} · job ${result.job}`);
@@ -21,11 +21,13 @@
21
21
  * 하나라도 못 재거나 어긋나면 거부 — 호출부는 종전 거부를 그대로 낸다(fail-closed).
22
22
  * - 관측: `pr.land` · `overlap-evidence` (decision · reason · 잰 값).
23
23
  */
24
+ import { createHash } from 'node:crypto';
24
25
  import { basename, dirname, join, resolve } from 'node:path';
25
26
  import { debug } from '../debug/log.js';
26
27
  import type { CmdRunner } from '../autopilot/pr-manager.js';
27
28
  import { parseReviewResultOutput } from '../task-agent/review-result-capture.js';
28
29
  import { verifyVirtualRebasePatch } from './pr-land-virtual-rebase.js';
30
+ import { proveReviewCarry } from './review-carry.js';
29
31
 
30
32
  const SHA40 = /^[0-9a-f]{40}$/i;
31
33
 
@@ -36,6 +38,8 @@ interface OverlapEvidenceFile {
36
38
  gate?: { head: string; baseCommit: string; passed: boolean };
37
39
  /** `self review --json` stdout 을 받은 파일(TA: `<state>/review-results/<card>-<pr>-<head접두 10~40>.json`); 내용의 전체 head도 확인한다. */
38
40
  reviewResult: string;
41
+ /** Explicit old-head review for a mechanically merged main head. Always re-proved against Git. */
42
+ reviewCarry?: { oldHead: string; oldBase: string; newBase: string; patchId: string; pathsModesHash: string; reviewSha256: string };
39
43
  /** Evidence-file override for explicitly replaced failed reviews. Each reason is the verifier's refusal reason. */
40
44
  supersedes?: { reviewResult: string; reason: string }[];
41
45
  /** OPEN follow-up PR that owns the findings intentionally split from this landing. */
@@ -82,9 +86,15 @@ function checkSelectedReviewAttempts(input: VerifyOverlapEvidenceInput, e: Parti
82
86
  let names: readonly string[];
83
87
  try { names = input.listDir(dir); } catch { return { ok: false, reason: 'review-attempts-unmeasured' }; }
84
88
  const filename = new RegExp(`^[A-Za-z0-9][A-Za-z0-9._-]*-${input.pr}-([a-f0-9]{10,40})\\.json$`, 'i');
85
- const candidates = [...names].filter((name) => {
89
+ const selectedHead = e.reviewCarry?.oldHead?.toLowerCase() ?? head;
90
+ // A fresh review of the merged head supersedes carry. Never hide a failed current-head attempt.
91
+ if (e.reviewCarry && names.some((name) => {
86
92
  const match = filename.exec(name);
87
93
  return Boolean(match && head.startsWith(match[1]!.toLowerCase()));
94
+ })) return { ok: false, reason: 'carry-new-head-review-exists' };
95
+ const candidates = [...names].filter((name) => {
96
+ const match = filename.exec(name);
97
+ return Boolean(match && selectedHead.startsWith(match[1]!.toLowerCase()));
88
98
  }).map((name) => join(dir, name));
89
99
  if (!candidates.includes(selected)) return { ok: false, reason: 'review-selected-missing' };
90
100
  let physicalDir: string;
@@ -127,7 +137,7 @@ function checkSelectedReviewAttempts(input: VerifyOverlapEvidenceInput, e: Parti
127
137
  }
128
138
  for (const path of candidates) {
129
139
  if (path === selected) continue;
130
- const review = checkReview(input, { reviewResult: path }, head);
140
+ const review = checkReview(input, { reviewResult: path }, selectedHead);
131
141
  if (review.ok) {
132
142
  if (superseded.has(path)) return { ok: false, reason: 'review-supersedes-passing' };
133
143
  continue;
@@ -324,8 +334,12 @@ type Checked = { ok: false; reason: string; baseTip?: string; gateBase?: string;
324
334
  const ACCEPTED_REVIEW_VERDICTS: ReadonlySet<string> = new Set(['pass', 'warn']);
325
335
  const COMMIT_MARK = '\u0001';
326
336
 
327
- function checkReview(input: Pick<VerifyOverlapEvidenceInput, 'pr' | 'readFile'>, e: Partial<OverlapEvidenceFile>, head: string, baseTip?: string): { ok: false; reason: string; baseTip?: string } | { ok: true; reviewResult: string } {
337
+ function checkReview(input: Pick<VerifyOverlapEvidenceInput, 'pr' | 'readFile'> & Partial<Pick<VerifyOverlapEvidenceInput, 'cwd' | 'remote' | 'branch'>>,
338
+ e: Partial<OverlapEvidenceFile>, head: string, baseTip?: string): { ok: false; reason: string; baseTip?: string } | { ok: true; reviewResult: string } {
328
339
  if (typeof e.reviewResult !== 'string' || !e.reviewResult) return { ok: false, reason: 'review-missing', baseTip };
340
+ const carry = e.reviewCarry;
341
+ const reviewHead = carry?.oldHead?.toLowerCase() ?? head;
342
+ if (carry && (!SHA40.test(reviewHead) || reviewHead === head)) return { ok: false, reason: 'carry-invalid-old-head', baseTip };
329
343
  // TA 가 받는 자리(`<state>/review-results/<card>-<pr>-<head접두 10~40>.json` · reviewResultPath)만; 내용의 전체 head도 확인한다.
330
344
  const resultName = basename(e.reviewResult);
331
345
  const resultMatch = /^([A-Za-z0-9][A-Za-z0-9._-]*)-(\d+)-([a-f0-9]{10,40})\.json$/i.exec(resultName);
@@ -333,7 +347,7 @@ function checkReview(input: Pick<VerifyOverlapEvidenceInput, 'pr' | 'readFile'>,
333
347
  || !resultMatch
334
348
  || Number(resultMatch[2]) !== input.pr
335
349
  || resultMatch[3]!.length < 10
336
- || !head.startsWith(resultMatch[3]!.toLowerCase())) {
350
+ || !reviewHead.startsWith(resultMatch[3]!.toLowerCase())) {
337
351
  return { ok: false, reason: 'review-path-not-for-this-pr-head', baseTip };
338
352
  }
339
353
  let text: string;
@@ -341,7 +355,7 @@ function checkReview(input: Pick<VerifyOverlapEvidenceInput, 'pr' | 'readFile'>,
341
355
  const review = parseReviewResultOutput(text);
342
356
  if (!review) return { ok: false, reason: 'review-no-result', baseTip };
343
357
  if (review.pr !== input.pr) return { ok: false, reason: 'review-pr-mismatch', baseTip };
344
- if (!review.head || review.head.toLowerCase() !== head) return { ok: false, reason: 'review-head-mismatch', baseTip };
358
+ if (!review.head || review.head.toLowerCase() !== reviewHead) return { ok: false, reason: 'review-head-mismatch', baseTip };
345
359
  // The capture parser projects away model provenance; inspect the same last result-shaped line here.
346
360
  const raw = lastReviewRecord(text);
347
361
  if (raw) {
@@ -377,6 +391,25 @@ function checkReview(input: Pick<VerifyOverlapEvidenceInput, 'pr' | 'readFile'>,
377
391
  if (review.reviewed !== true) return { ok: false, reason: 'review-not-reviewed', baseTip };
378
392
  if (review.verdict === null || !ACCEPTED_REVIEW_VERDICTS.has(review.verdict)) return { ok: false, reason: `review-verdict-${review.verdict ?? 'null'}`, baseTip };
379
393
  if (review.mustFix !== 0) return { ok: false, reason: review.mustFix === null ? 'review-must-fix-unknown' : `review-must-fix-${review.mustFix}`, baseTip };
394
+ if (carry) {
395
+ if (!input.cwd || !input.remote || !input.branch) return { ok: false, reason: 'carry-repo-unmeasured', baseTip };
396
+ const digest = createHash('sha256').update(text).digest('hex');
397
+ if (carry.reviewSha256 !== digest) return { ok: false, reason: 'carry-review-hash-mismatch', baseTip };
398
+ const proof = proveReviewCarry(input.cwd, reviewHead, head, input.remote, input.branch);
399
+ if (!proof.ok) return { ok: false, reason: proof.reason, baseTip };
400
+ const gate = e.gate;
401
+ if (!gate || gate.passed !== true || gate.head?.toLowerCase() !== head
402
+ || gate.baseCommit?.toLowerCase() !== proof.newBase) {
403
+ return { ok: false, reason: 'carry-new-head-gate-missing-or-mismatch', baseTip };
404
+ }
405
+ if (carry.oldBase?.toLowerCase() !== proof.oldBase || carry.newBase?.toLowerCase() !== proof.newBase
406
+ || carry.patchId?.toLowerCase() !== proof.patchId || carry.pathsModesHash?.toLowerCase() !== proof.pathsModesHash) {
407
+ return { ok: false, reason: 'carry-proof-mismatch', baseTip };
408
+ }
409
+ debug.log('pr.land', 'review-carry', { pr: input.pr, remote: input.remote, branch: input.branch,
410
+ oldHead: reviewHead, newHead: head, oldBase: proof.oldBase,
411
+ newBase: proof.newBase, patchId: proof.patchId, reviewSha256: digest, decision: 'accepted' });
412
+ }
380
413
  return { ok: true, reviewResult: e.reviewResult };
381
414
  }
382
415
 
@@ -12,7 +12,7 @@ export function classifyPrLandRefusal(message: string, context: { isDraft?: bool
12
12
  if (message.startsWith('✗ ancestor-auto: ancestor-auto-not-ancestor:')) return 'not-ancestor';
13
13
  if (/^✗ (?:ancestor-auto|overlap-evidence): (?:review-missing|review-not-reviewed|review-error|review-no-result|review-unreadable|review-pr-mismatch|review-head-mismatch|review-path-not-for-this-pr-head|review-verdict-null|review-must-fix-unknown)(?:\b|$)/.test(message)) return 'review-missing';
14
14
  if (message.startsWith('✗ heavy-remote: PR base=unreadable ≠ main')) return 'pr-base-unreadable';
15
- if (/^✗ heavy-remote: (?:원격|병합 직전 원격|node-b) 게이트 gate-host-busy(?:\b|\s|$)/.test(message)) return 'gate-host-busy';
15
+ if (/^✗ heavy-remote: (?:원격|병합 직전 원격|[a-z][a-z0-9-]*) 게이트 gate-host-busy(?:\b|\s|$)/.test(message)) return 'gate-host-busy';
16
16
  if (message.startsWith('✗ heavy-remote: 원격 게이트 gate-rc-1 · remote: stdout: CONFLICT (content): Merge conflict')) return 'gate-merge-conflict';
17
17
  if (message.startsWith('✗ heavy-remote: 원격 게이트 gate-rc-1 · remote: stderr: 건드린 src/scripts 파일과 baseline 밖 test 파일은 tsc 클린이어야 합니다(touch-clean).')) return 'gate-touch-clean';
18
18
  if (message.startsWith('✗ public-export-leak: 바뀐 파일')) return 'public-export-leak';