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
@@ -2,10 +2,10 @@ import { spawnSync } from 'node:child_process';
2
2
  import { debug } from '../debug/log.js';
3
3
  import { listChecklist, setItemIfSnapshot, type Checklist } from '../release-loop/checklist.js';
4
4
  import { judgeLandedCell, parseJudgeSignals, type GreenVerdict } from '../release-loop/landed-to-green.js';
5
- import { HAND_MOVE_HISTORY_EVENT, LIVE_MOVE_HISTORY_EVENT, LIVE_MOVE_RESULT_EVENT, cardPrNumber, readTaskAgentState, taskAgentStatePath, updateTaskCard, type TaskCard } from './task-hand.js';
5
+ import { HAND_MOVE_HISTORY_EVENT, LIVE_MOVE_HISTORY_EVENT, LIVE_MOVE_RESULT_EVENT, cardPrNumber, readTaskAgentState, taskAgentStatePath, updateTaskCard, recordPostLandImplFindings, type TaskCard } from './task-hand.js';
6
6
  import { isGoalOnlyPr } from './judge.js';
7
7
 
8
- export interface LandedTaskPr { number: number; url: string; headRefOid: string; state: string; baseRefName: string; mergedAt: string; files?: Array<{ path: string }> }
8
+ export interface LandedTaskPr { number: number; url: string; headRefOid: string; state: string; baseRefName: string; mergedAt: string; body?: string | null; files?: Array<{ path: string }> }
9
9
  export interface PostlandDeps {
10
10
  statePath?: string;
11
11
  versions: readonly string[];
@@ -144,6 +144,39 @@ export function closeMergedTaskCard(pr: LandedTaskPr, cwd: string, deps: Postlan
144
144
  return item.id;
145
145
  }
146
146
 
147
+ /** Awaited postland feedback for the confirmed merge caller; card+PR URL/head must still bind exactly. */
148
+ export async function recordMergedTaskImplFindings(
149
+ pr: LandedTaskPr,
150
+ cwd: string,
151
+ options: { statePath?: string; ledgerDir?: string; followUp?: NonNullable<Parameters<typeof recordPostLandImplFindings>[2]>['followUp'] } = {},
152
+ ): Promise<Awaited<ReturnType<typeof recordPostLandImplFindings>> | null> {
153
+ if (pr.state !== 'MERGED' || pr.baseRefName !== 'main' || !pr.url || !pr.headRefOid || pr.body == null) return null;
154
+ const path = options.statePath ?? taskAgentStatePath();
155
+ const tasks = readTaskAgentState<{ tasks?: Record<string, TaskCard> }>(path).tasks ?? {};
156
+ const cards = Object.values(tasks).filter((card) => card.taLand && cardPrNumber(card) === pr.number
157
+ && typeof card.pr === 'object' && card.pr.url?.replace(/\/+$/, '') === pr.url!.replace(/\/+$/, '')
158
+ && card.status === 'done' && card.prTerminal?.pr === pr.number
159
+ && card.prTerminal.head.toLowerCase() === pr.headRefOid!.toLowerCase()
160
+ && card.prTerminal.url.replace(/\/+$/, '') === pr.url!.replace(/\/+$/, '')
161
+ && (card.landAttempts ?? []).some((attempt) => attempt.pr === pr.number && attempt.head.toLowerCase() === pr.headRefOid!.toLowerCase()));
162
+ if (cards.length !== 1) {
163
+ debug.log('task-agent', 'impl-findings-skipped', { pr: pr.number, reason: cards.length ? 'ambiguous-postland-card' : 'postland-card-not-bound' });
164
+ return null;
165
+ }
166
+ const card = cards[0]!;
167
+ const result = await recordPostLandImplFindings(card, { prBody: pr.body, ask: card.text }, {
168
+ ...(options.ledgerDir ? { ledgerDir: options.ledgerDir } : {}),
169
+ ...(options.followUp ? { followUp: options.followUp } : {}),
170
+ });
171
+ debug.log('task-agent', 'impl-findings-postland-result', {
172
+ pr: pr.number, card: card.id, appended: result?.appended ?? false,
173
+ lessonIds: result?.lessonIds ?? [], injectedSections: result?.injectedSections ?? [], skippedSections: result?.skippedSections ?? [],
174
+ authoringInjectionBytes: result ? Buffer.byteLength(result.authoringInjection, 'utf8') : 0,
175
+ followUp: result?.followUp?.queued ?? null,
176
+ });
177
+ return result;
178
+ }
179
+
147
180
  const defaultGit = (cwd: string, args: string[]): { status: number; stdout: string; stderr: string } => {
148
181
  const run = spawnSync('git', args, { cwd, encoding: 'utf8' });
149
182
  return { status: run.status ?? 1, stdout: run.stdout ?? '', stderr: run.stderr ?? '' };
@@ -45,14 +45,14 @@ import { remoteLedgerMirrorDir } from './parent-host.js';
45
45
  import { appendLandOrderRow, joinLandOrderRow } from './land-order-ledger.js';
46
46
  import { recordLiveMoveHistory } from './live-move-history.js';
47
47
  import { advanceLandedPieceMission } from './mission.js';
48
- import { runRepairCycle, type RepairLaunchRequest } from './repair-cycle.js';
48
+ import { runRepairCycle, resolveRepairOwner, type RepairLaunchRequest } from './repair-cycle.js';
49
49
  import { repairMustFixFromReview, repairReviewDigest } from './repair-review.js';
50
50
  import type { RepairCasOutcome, RepairCasRequest } from './repair-branch-cas.js';
51
51
  import { configuredMsb1Worker, defaultLandPrHead, defaultPrHead, defaultReviewRepoCandidates, executeLiveLand, executeLiveReview, landRetryPending, remoteTaWorkerCommand, type LiveMoveDeps, type LiveMoveResult, type PrHeadView, type ReviewRepoCandidate, type TaskAgentLiveMove } from './live-moves.js';
52
52
  import { capturedLandReview, captureReviewResults, parseReviewResultOutput, pendingReviewResults, reviewResultPath, type ParsedReviewResult } from './review-result-capture.js';
53
53
  import { boundPrTerminal, cardPrNumber, LIVE_MOVE_RESULT_EVENT, readTaskCard, taskAgentStatePath, updateTaskCard, type TaskCard } from './task-hand.js';
54
54
  import { verifiedTrainLanding, type TrainLanding } from './train-landing.js';
55
- import { isGoalOnlyPr } from './judge.js';
55
+ import { isGoalOnlyPr, judgeEmptyImplementation } from './judge.js';
56
56
  import { defaultPrFiles } from './shadow.js';
57
57
 
58
58
  export const REJUDGE_ON_HEAD_EVENT = 'rejudge-on-head';
@@ -671,6 +671,50 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
671
671
  step('repair', 'repair-stopped', 'PR branch name unavailable', true);
672
672
  return outcomes;
673
673
  }
674
+ // 빈 구현 must-fix — 같은 PR 수리(narrow-relaunch)로는 수렴하지 않는다: 첫 회는 같은 칸 새 발사(시험 먼저), 두 번째는 칸 주인 이관.
675
+ const priorEmpty = (card.history ?? []).filter((entry) => entry.event === REJUDGE_ON_HEAD_EVENT && entry.kind === 'repair'
676
+ && (entry.effect === 'empty-implementation-reimplement' || entry.effect === 'empty-implementation-needs-owner')).length;
677
+ const emptyJudgement = mustFix?.length ? judgeEmptyImplementation(mustFix, priorEmpty) : null;
678
+ if (emptyJudgement) {
679
+ if (emptyJudgement.move === 'needs-owner') {
680
+ let ownerSeat: string | null = card.seat ?? null;
681
+ try {
682
+ const owner = resolveRepairOwner(card);
683
+ if (owner?.seat) ownerSeat = owner.seat;
684
+ } catch { /* 결정 실패 시 칸 좌석을 유지한다 */ }
685
+ if (ownerSeat) {
686
+ try {
687
+ (deps.notifyRepair ?? (() => {}))(ownerSeat,
688
+ `빈 구현 needs-owner: 칸 ${card.id} PR #${pr} head ${toHead.slice(0, 12)} — ${emptyJudgement.reason} · 칸 주인이 재구현 지시를 결정한다`);
689
+ } catch { /* 통보 실패가 이관을 막지 않는다 */ }
690
+ }
691
+ const handedOver = updateTaskCard(statePath, card.id, (current) => {
692
+ if (!current) return undefined;
693
+ if ((current.history ?? []).some((entry) => entry.event === REJUDGE_ON_HEAD_EVENT && entry.kind === 'repair'
694
+ && entry.pr === pr && entry.head && sameHead(entry.head, toHead) && entry.effect === 'empty-implementation-needs-owner')) return current;
695
+ return { ...current, status: 'failed',
696
+ history: [...(current.history ?? []), { at: now().toISOString(), event: 'pr-superseded-candidate', kind: 'repair', pr,
697
+ ...(toHead ? { head: toHead } : {}), effect: 'superseded-candidate',
698
+ detail: `빈 구현 needs-owner — 옛 PR #${pr} 은 superseded 후보` }] };
699
+ });
700
+ if (handedOver) step('repair', 'empty-implementation-needs-owner',
701
+ `${emptyJudgement.reason} · 칸 주인 ${ownerSeat ?? 'unknown'} 이관 · 옛 PR #${pr} superseded 후보`, true);
702
+ return outcomes;
703
+ }
704
+ const relaunched = updateTaskCard(statePath, card.id, (current) => {
705
+ if (!current) return undefined;
706
+ if ((current.history ?? []).some((entry) => entry.event === REJUDGE_ON_HEAD_EVENT && entry.kind === 'repair'
707
+ && entry.pr === pr && entry.head && sameHead(entry.head, toHead) && entry.effect === 'empty-implementation-reimplement')) return current;
708
+ return { ...current, status: 'launch-failed',
709
+ text: `${current.text}\n- 재구현 지시(빈 구현 판정): 시험 먼저 — 구현 전에 실패하는 시험(RED)을 먼저 쓰고 구현 파일 변경 0이 되지 않게 한다.`,
710
+ history: [...(current.history ?? []), { at: now().toISOString(), event: 'pr-superseded-candidate', kind: 'repair', pr,
711
+ ...(toHead ? { head: toHead } : {}), effect: 'superseded-candidate',
712
+ detail: `빈 구현 재구현 — 옛 PR #${pr} 은 superseded 후보` }] };
713
+ });
714
+ if (relaunched) step('repair', 'empty-implementation-reimplement',
715
+ `${emptyJudgement.reason} · 같은 칸 새 발사(시험 먼저) · 옛 PR #${pr} superseded 후보`, true);
716
+ return outcomes;
717
+ }
674
718
  const result = await runRepairCycle({ card, statePath, repo: cwd, pr, head: toHead, branch: view.branch,
675
719
  mustFix: mustFix ?? [], liveMoves: deps.liveMoves, now: now(), readFile: read,
676
720
  ...(deps.requestRepair ? { request: deps.requestRepair } : {}),
@@ -532,7 +532,7 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
532
532
  else {
533
533
  passJourneyNode('next-move', { provenance: 'task-agent-repair', outcome: judged.judgement.move, runId,
534
534
  data: { card: card.id, source: `pr:${pr}`, pr, head, branch, mustFix: input.mustFix, moveId } });
535
- recordJourneyEdge(judged.route, 'dispatch', undefined, { moveId });
535
+ recordJourneyEdge(judged.route, 'dispatch', undefined, { moveId, runId, card: card.id, pr, head });
536
536
  }
537
537
  } catch (error) {
538
538
  const detail = `repair observation failed after worker launch: ${error instanceof Error ? error.message : String(error)}`;
@@ -14,6 +14,7 @@ import { dirname, join, posix, resolve } from 'node:path';
14
14
  import { fileURLToPath } from 'node:url';
15
15
  import { parse as parseYaml } from 'yaml';
16
16
  import { runGraph, validateUnitCalls, type GraphRunOptions, type GraphRunState } from '../graph-runner/runner.js';
17
+ import type { GraphWizardDeps } from '../graph-wizard/generate.js';
17
18
  import { parseGraphTemplateYaml } from '../self-implement/graph-yaml.js';
18
19
  import { resolveDaemonHarnessTarget } from '../intake-plane/harness-target.js';
19
20
  import { getUserConfig } from '../user-config.js';
@@ -22,6 +23,7 @@ import { HARNESS_RUN_ID_ENV, mintRunId, normalizeRunId } from '../harness/harnes
22
23
  import { newLaunchUtteranceId, recordLaunchUtterance } from '../harness/launch-utterance-ledger.js';
23
24
  import { debug } from '../debug/log.js';
24
25
  import { effectiveInstanceRoot } from '../instance/resolve.js';
26
+ import { LAUNCH_DOOR_RECEIPT_ENV, openLaunchRequestDoor, type LaunchRequestDoor } from '../execution-loop/launch-gate.js';
25
27
  import { withFileLockSync } from '../storage/file-lock.js';
26
28
  import { checkCompletionEvidence, deliverableReceiptEvidence } from './completion-evidence.js';
27
29
  import { judgeNextMove } from './judge.js';
@@ -37,10 +39,13 @@ import { draftClaimComment, draftClaimRecordLive, draftClaimState, draftReleaseC
37
39
  import { parseAskTargetPathHints, parseAskTargetPathHintsResult, type AskTargetPathHintsParseResult } from '../self-dev/launch-preflight-text.js';
38
40
  import { draftMissingGoalDoneBoundary, inspectGoalDoneBoundary, linesOutsideFencedCode } from '../self-implement/goal-author.js';
39
41
  import { selectKnowhowPack } from '../self-implement/knowhow-pack.js';
42
+ // IMPL-FINDINGS-FEEDBACK — 병합 판정(postLand) 뒤 구현이 밝힌 절의 되먹임(원장 1회 기록·다음 저작 주입·후속 초안).
43
+ import type { recordImplFindingsFeedback as RecordImplFindingsFeedback } from '../self-implement/impl-findings-feedback.js';
40
44
  import { INFLIGHT_REGISTRY_FILE, registerInflight } from '../pr-tool/inflight-registry.js';
41
45
  import { taskParentRoleEnv, taskParentRolePinsForChild } from './task-parent-role-llm.js';
42
46
  import { runHarvestUnit, type ReviewInvocation } from './harvest-unit.js';
43
47
  import { TASK_CARD_PREFIX } from './task-card-prefix.js';
48
+ import { childLlmEffortProblem } from '../intelligence-map/model-catalog.js';
44
49
 
45
50
  export interface ResolveHandTextDeps {
46
51
  cwd: string;
@@ -182,7 +187,22 @@ export interface CompositionSelection {
182
187
  export const COMPOSITION_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..', '..');
183
188
 
184
189
  /** 1판은 조합을 고르고 단위 해석 결과를 기록한다. 단위 실행은 2판의 몫이다. */
185
- export function selectTaskComposition(completion: CompletionKind, root = COMPOSITION_ROOT): CompositionSelection {
190
+ export function selectTaskComposition(completion: CompletionKind, root?: string): CompositionSelection;
191
+ export function selectTaskComposition(completion: CompletionKind, root: string, mission: {
192
+ text: string; ledgerPath: string; cardId: string; callLLM?: GraphWizardDeps['callLLM']; onPersist?: (persist: () => void) => void;
193
+ }): Promise<CompositionSelection>;
194
+ export function selectTaskComposition(completion: CompletionKind, root = COMPOSITION_ROOT, mission?: {
195
+ text: string; ledgerPath: string; cardId: string; callLLM?: GraphWizardDeps['callLLM']; onPersist?: (persist: () => void) => void;
196
+ }): CompositionSelection | Promise<CompositionSelection> {
197
+ if (mission) {
198
+ const standard = selectTaskComposition(completion, root);
199
+ return import('../graph-wizard/mission-compose.js').then(async ({ composeMissionGraph }) => {
200
+ const result = await composeMissionGraph({ text: mission.text, completion, root, ledgerPath: mission.ledgerPath,
201
+ cardId: mission.cardId, standard }, { callLLM: mission.callLLM, deferPersistence: mission.onPersist !== undefined });
202
+ mission.onPersist?.(result.persist);
203
+ return result.selection;
204
+ });
205
+ }
186
206
  const requested = `graphs/work/${completion}.yaml`;
187
207
  // DEFAULT-HANDS — 종류별 조합이 없으면 그 손의 기본 조합(«실행·조사»)으로 내려간다.
188
208
  // 비개발 종결이 «조합 없음»으로 막히면 사람별 표본이 과제 담당에 닿지도 못한다.
@@ -284,7 +304,7 @@ export interface TaskCard {
284
304
  completion?: CompletionKind;
285
305
  /** 선택된 일 조합 파일과 판(1판: 실행은 launcher 에 위임). */
286
306
  composition?: TaskComposition;
287
- graphSelectedBy?: 'completion';
307
+ graphSelectedBy?: 'completion' | 'mission-compose';
288
308
  unitsResolved?: boolean;
289
309
  missingUnits?: string[];
290
310
  /** 과제 대상 프로젝트(§A4b②) — target 은 절대 경로(git 이 아닐 수 있다). id 는 `task hand --project` 가 싣는다(옛 카드엔 없을 수 있다). */
@@ -395,7 +415,7 @@ export interface TaskCard {
395
415
  moveId?: string }>;
396
416
  }
397
417
 
398
- /** 구현 자식 LLM 선택 — 하니스 `--child-llm-provider/--child-llm-model/--child-llm-effort` 로 그대로 넘긴다(검증 권위는 하니스). */
418
+ /** 구현 자식 LLM 선택 — 하니스 `--child-llm-provider/--child-llm-model/--child-llm-effort` 로 넘긴다. */
399
419
  export interface TaskChildLlm { provider: string; model: string; effort?: string }
400
420
 
401
421
  /**
@@ -412,6 +432,8 @@ export function parseChildLlm(value: string, effort?: string): TaskChildLlm {
412
432
  const model = provider === 'openrouter' && !rest.startsWith('openrouter/') ? `openrouter/${rest}` : rest;
413
433
  if (effort === undefined) return { provider, model };
414
434
  if (!effort || /[\s\p{Cc}]/u.test(effort)) throw new Error(`--child-llm-effort 가 비었거나 공백·제어 문자를 담았다: ${JSON.stringify(effort)}`);
435
+ const problem = childLlmEffortProblem(model, effort);
436
+ if (problem) throw new Error(problem);
415
437
  return { provider, model, effort };
416
438
  }
417
439
 
@@ -839,6 +861,41 @@ export function readTaskCard(id: string, path = taskAgentStatePath()): TaskCard
839
861
  return readState(path).tasks?.[id];
840
862
  }
841
863
 
864
+ /**
865
+ * IMPL-FINDINGS-FEEDBACK — 착지(landed·landed-by-hand) 판정이 난 카드의 병합 PR 본문 절을
866
+ * 되먹임한다: 원장 1회 기록(중복 억제) ⊕ 관련 기록만 다음 저작 입력 주입 ⊕ 후속 초안(자동 발사 없음).
867
+ * PR 이 묶이지 않았거나 아직 착지 판정이 아니면 아무것도 하지 않는다. 실패는 관측(`debug.log`)만.
868
+ */
869
+ export async function recordPostLandImplFindings(
870
+ card: TaskCard,
871
+ input: { prBody: string; ask: string },
872
+ options: { ledgerDir?: string; followUp?: NonNullable<Parameters<typeof RecordImplFindingsFeedback>[1]>['followUp'] } = {},
873
+ ): Promise<Awaited<ReturnType<typeof RecordImplFindingsFeedback>> | null> {
874
+ const pr = cardPrNumber(card);
875
+ if (pr === undefined || !(card.status === 'landed' || card.status === 'landed-by-hand'
876
+ || (card.status === 'done' && card.prTerminal?.pr === pr))) return null;
877
+ if (!card.runId?.trim()) {
878
+ try { debug.log('task-agent', 'impl-findings-skipped', { card: card.id, pr, reason: 'run-id-missing' }); } catch { /* fail-soft */ }
879
+ return null;
880
+ }
881
+ try {
882
+ const { recordImplFindingsFeedback } = await import('../self-implement/impl-findings-feedback.js');
883
+ return await recordImplFindingsFeedback({
884
+ runId: card.runId,
885
+ prNumber: pr,
886
+ prBody: input.prBody,
887
+ ask: input.ask,
888
+ ...(card.goalId ? { goalId: card.goalId } : {}),
889
+ }, {
890
+ ...(options.ledgerDir ? { dir: options.ledgerDir } : {}),
891
+ ...(options.followUp ? { followUp: options.followUp } : {}),
892
+ });
893
+ } catch (error) {
894
+ try { debug.log('task-agent', 'impl-findings-failed', { card: card.id, pr, reason: error instanceof Error ? error.message : String(error) }); } catch { /* fail-soft */ }
895
+ return null;
896
+ }
897
+ }
898
+
842
899
  /** TA-REVIEW-PASS — runId 기준 단일 카드 멱등 생성 결과. `ok: false` 는 임의 생성 없이 사유만 남긴 보류(fail-closed)다. */
843
900
  export type IdempotentRunCardCreate =
844
901
  | { ok: true; card: TaskCard; created: boolean }
@@ -900,6 +957,9 @@ export function cardsTouchingPaths(cards: readonly TaskCard[], paths: readonly s
900
957
 
901
958
  export const CLOSED_BY_HAND_EVENT = 'closed-by-hand';
902
959
 
960
+ /** LAUNCH-SINGLE-DOOR-1C — 단일문 거절 줄 — 같은 requestId 로 이미 소비된 중복 발사를 카드 history 에 남긴다. */
961
+ export const LAUNCH_REFUSED_DUPLICATE_EVENT = 'launch-refused-duplicate';
962
+
903
963
  /** 카드를 손으로 닫는다 — 상태를 `failed` 로 두고 history 에 한 줄(`closed-by-hand`)을 남긴다. 이미 손으로 닫은 카드는 그대로 돌려준다(멱등). */
904
964
  export function closeTaskCard(card: TaskCard, input: { reason: string; by: string; at: string }): TaskCard {
905
965
  const reason = input.reason.trim();
@@ -1065,6 +1125,10 @@ export interface HandTaskOptions {
1065
1125
  statePath?: string;
1066
1126
  /** 시험에서만 조합 저장소를 바꿔 해석·거부를 검증한다. */
1067
1127
  compositionRoot?: string;
1128
+ /** Explicit opt-in for mission graph composition; omitted is the fixed completion graph. */
1129
+ composeGraph?: boolean;
1130
+ /** Injectable LLM boundary for isolated composition tests. */
1131
+ composeCallLLM?: GraphWizardDeps['callLLM'];
1068
1132
  /** `--live` 일 때만 불린다. */
1069
1133
  launcher?: TaskLauncher;
1070
1134
  /**
@@ -1096,6 +1160,11 @@ export interface HandTaskOptions {
1096
1160
  * 거짓이면 쓰지 않고 `TaskCardSupersededError` — 다른 넘김이 그 카드를 가져갔다(발사 전이면 발사하지 않는다).
1097
1161
  */
1098
1162
  writeGuard?: (current: TaskCard | undefined) => boolean;
1163
+ /**
1164
+ * LAUNCH-SINGLE-DOOR-1C — 발사 직전 단일문(append 요청 원장 ⊕ requestId 단위 단일 소비 영수증).
1165
+ * 생산은 기본 문(이 우주의 인스턴스 루트)을 쓰고, 시험은 격리 루트의 문을 주입해 같은 생산 경로로 검증한다.
1166
+ */
1167
+ launchRequestDoor?: LaunchRequestDoor;
1099
1168
  }
1100
1169
 
1101
1170
  /** `writeGuard` 가 거짓 — 다른 넘김이 카드를 가져갔다. 카드는 건드리지 않았다. */
@@ -1233,20 +1302,8 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1233
1302
  const parentRolePins = taskParentRolePinsForChild(opts.parentRoleLlm ?? [], childLlm);
1234
1303
  let parentRoleEnv = taskParentRoleEnv(parentRolePins); // validate before writing the card
1235
1304
  const completion = opts.completion ?? 'code-pr';
1236
- const selected = selectTaskComposition(completion, opts.compositionRoot);
1237
- // 2판 — launcher 'graph-run' 조합(단위 해석까지 완료)은 실제 graph run 으로 발사한다. 더 이상 거부하지 않는다.
1238
- const graphRun = selected.composition && selected.launcher === 'graph-run' && !selected.error && selected.unitsResolved
1239
- ? selected.composition : undefined;
1240
- const graphRunPath = graphRun ? join(opts.compositionRoot ?? COMPOSITION_ROOT, graphRun.file) : undefined;
1241
- const selectionFailure = graphRun ? undefined
1242
- : !selected.composition ? `조합 없음: graphs/work/${completion}.yaml`
1243
- : selected.error ?? (selected.launcher === 'graph-run' && !selected.unitsResolved
1244
- ? `조합 단위 미해석: ${selected.composition.file} — 대상 unit: ${selected.missingUnits.length ? selected.missingUnits.join(', ') : '해석 실패'} (graph-run 발사는 단위 해석이 필요하다)`
1245
- // DEFAULT-HANDS — 코드 하니스(harness-say 자식 구현 런)는 개발자 팩(code-pr)만 쓴다.
1246
- : !DEFAULT_HANDS[completion].codeHarness && selected.launcher === 'harness-say'
1247
- ? `조합 실행기 없음: ${selected.composition.file} — ${completion} 은 «실행·조사» 손이라 코드 하니스(harness-say)를 쓰지 않는다(개발자 팩 전용)`
1248
- : selected.launcher === undefined
1249
- ? `조합 실행기 없음: ${selected.composition.file} (발사 가능한 launcher: harness-say · graph-run)` : undefined);
1305
+ const now = (opts.now ?? (() => new Date()))();
1306
+ const id = opts.id ?? `${TASK_CARD_PREFIX}${now.toISOString().slice(0, 10).replaceAll('-', '')}-${randomBytes(3).toString('hex')}`;
1250
1307
  let project: TaskCard['project'];
1251
1308
  let targetIsGit: boolean | null = null;
1252
1309
  if (opts.project) {
@@ -1262,8 +1319,6 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1262
1319
  if (!selection.ok) throw new Error(`코드 종결은 git 대상이 필요 — --completion 을 고르거나 git init: ${target}`);
1263
1320
  project = { id: opts.project.id, target: selection.repo };
1264
1321
  }
1265
- const now = (opts.now ?? (() => new Date()))();
1266
- const id = opts.id ?? `${TASK_CARD_PREFIX}${now.toISOString().slice(0, 10).replaceAll('-', '')}-${randomBytes(3).toString('hex')}`;
1267
1322
  const mode = opts.live ? 'live' : 'shadow';
1268
1323
  // DRAFT-CLAIM-AUTO-2-FU — claim 은 카드를 쓰기 «전»에 판정한다(거부면 원장에 아무것도 남기지 않는다).
1269
1324
  // 견줄 상대는 카드 원장(디스크)의 다른 카드다 — 손이 들고 있는 사본이 아니라 정본을 본다.
@@ -1273,6 +1328,25 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1273
1328
  ...(opts.seat !== undefined ? { seat: opts.seat } : {}), now, ask: text,
1274
1329
  })
1275
1330
  : undefined;
1331
+ let persistComposition: (() => void) | undefined;
1332
+ const selected = (opts.composeGraph ?? (process.env.ELANOUS_MISSION_GRAPH_COMPOSE === '1'))
1333
+ ? await selectTaskComposition(completion, opts.compositionRoot ?? COMPOSITION_ROOT,
1334
+ { text, ledgerPath: path, cardId: id, callLLM: opts.composeCallLLM,
1335
+ onPersist: persist => { persistComposition = persist; } })
1336
+ : selectTaskComposition(completion, opts.compositionRoot);
1337
+ // 2판 — launcher 'graph-run' 조합(단위 해석까지 완료)은 실제 graph run 으로 발사한다. 더 이상 거부하지 않는다.
1338
+ const graphRun = selected.composition && selected.launcher === 'graph-run' && !selected.error && selected.unitsResolved
1339
+ ? selected.composition : undefined;
1340
+ const graphRunPath = graphRun ? resolve(opts.compositionRoot ?? COMPOSITION_ROOT, graphRun.file) : undefined;
1341
+ const selectionFailure = graphRun ? undefined
1342
+ : !selected.composition ? `조합 없음: graphs/work/${completion}.yaml`
1343
+ : selected.error ?? (selected.launcher === 'graph-run' && !selected.unitsResolved
1344
+ ? `조합 단위 미해석: ${selected.composition.file} — 대상 unit: ${selected.missingUnits.length ? selected.missingUnits.join(', ') : '해석 실패'} (graph-run 발사는 단위 해석이 필요하다)`
1345
+ // DEFAULT-HANDS — 코드 하니스(harness-say 자식 구현 런)는 개발자 팩(code-pr)만 쓴다.
1346
+ : !DEFAULT_HANDS[completion].codeHarness && selected.launcher === 'harness-say'
1347
+ ? `조합 실행기 없음: ${selected.composition.file} — ${completion} 은 «실행·조사» 손이라 코드 하니스(harness-say)를 쓰지 않는다(개발자 팩 전용)`
1348
+ : selected.launcher === undefined
1349
+ ? `조합 실행기 없음: ${selected.composition.file} (발사 가능한 launcher: harness-say · graph-run)` : undefined);
1276
1350
  let card: TaskCard = {
1277
1351
  id, text,
1278
1352
  ...(!targetPathHints.labelMissing ? { targetPaths } : {}),
@@ -1280,7 +1354,9 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1280
1354
  ...(opts.checklistId ? { checklistId: opts.checklistId } : {}),
1281
1355
  ...(opts.checklistVersion !== undefined ? { checklistVersion: opts.checklistVersion } : {}),
1282
1356
  ...(opts.completion ? { completion: opts.completion } : {}),
1283
- ...(selected.composition ? { composition: selected.composition, graphSelectedBy: 'completion' as const } : {}),
1357
+ ...(selected.composition ? { composition: selected.composition,
1358
+ graphSelectedBy: selected.composition.file === join(dirname(path), `${id}.generated.yaml`)
1359
+ ? 'mission-compose' as const : 'completion' as const } : {}),
1284
1360
  unitsResolved: selected.unitsResolved,
1285
1361
  missingUnits: selected.missingUnits,
1286
1362
  ...(project ? { project } : {}),
@@ -1378,6 +1454,7 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1378
1454
  }
1379
1455
  }
1380
1456
  writeCard(path, card);
1457
+ if (!selectionFailure && tierSplitBlocked === undefined && move?.kind === 'launch') persistComposition?.();
1381
1458
  try { debug.log('task-agent.hand', 'target-paths', { card: id, count: targetPaths.length, labelMissing: targetPathHints.labelMissing }); } catch { /* fail-soft */ }
1382
1459
  try { debug.log('task-agent.graph-select', !selected.composition ? 'composition-missing' : selected.error ? 'composition-invalid' : 'composition-selected', {
1383
1460
  completion, file: selected.composition?.file ?? `graphs/work/${completion}.yaml`,
@@ -1418,7 +1495,14 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1418
1495
  recordLaunchUtterance({ source: 'hand', utterance: opts.text, launchId });
1419
1496
  let state: GraphRunState;
1420
1497
  try {
1421
- state = await (opts.graphRunner ?? runGraph)(graphRunPath, { runId, input: { ask: text }, quiet: true });
1498
+ // Graph-run unit contracts consume all three envelope fields. `make-doc` forwards
1499
+ // context.worktree to its headless goal loop, so preserve the card's project target
1500
+ // when available; otherwise keep absence explicit for units that can decide safely.
1501
+ state = await (opts.graphRunner ?? runGraph)(graphRunPath, {
1502
+ runId,
1503
+ input: { ask: text, context: project ? { worktree: project.target } : {}, prior: {} },
1504
+ quiet: true,
1505
+ });
1422
1506
  } catch (error) {
1423
1507
  // 조합 파일·대상 node가 없으면 runGraph 가 구체 사유로 던진다 — 임의 성공 처리하지 않는다.
1424
1508
  const reason = `graph run 실패: ${error instanceof Error ? error.message : String(error)}`;
@@ -1431,8 +1515,9 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1431
1515
  const at = (opts.now ?? (() => new Date()))().toISOString();
1432
1516
  const ok = state.status === 'done';
1433
1517
  // 실패 종료도 구체 blocker(종료 상태·이유·마지막 node)를 기록한다 — 임의 성공 처리하지 않는다.
1518
+ const lastNode = state.nodes.at(-1);
1434
1519
  const blocker = ok ? undefined : `graph run 종료 상태 ${state.status}${state.reason ? ` — ${state.reason}` : ''}`
1435
- + `${state.nodes.length ? ` — 마지막 node ${state.nodes.at(-1)?.nodeId} (ok=${state.nodes.at(-1)?.ok})` : ' — node 없음'}`;
1520
+ + `${lastNode ? ` — 마지막 node ${lastNode.nodeId} (ok=${lastNode.ok})${lastNode.failure?.message ?? lastNode.reason ?? lastNode.error ? ` — ${lastNode.failure?.errorCode ?? 'GRAPH_NODE_FAILED'}: ${lastNode.failure?.message ?? lastNode.reason ?? lastNode.error}` : ''}` : ' — node 없음'}`;
1436
1521
  const launchedGraph: TaskCard = { ...card, status: ok ? 'launched' : 'failed', runId: state.runId, launchId,
1437
1522
  history: [...card.history,
1438
1523
  { at, event: 'launch', detail: `graph run ${graphRunPath} (run ${state.runId})` },
@@ -1440,7 +1525,7 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1440
1525
  ...(blocker ? [{ at, event: 'graph-run-failed', detail: blocker, runId: state.runId }] : [])] };
1441
1526
  writeCard(path, launchedGraph);
1442
1527
  try { debug.log('task-agent', 'launched', { taskId: id, seat: card.seat ?? null, runId: state.runId }); } catch { /* fail-soft */ }
1443
- return { card: launchedGraph, move, mode, launched: true, ...(project ? { cwd: project.target } : {}) };
1528
+ return { card: launchedGraph, move: ok ? move : nextMoveFor(launchedGraph), mode, launched: true, ...(project ? { cwd: project.target } : {}) };
1444
1529
  }
1445
1530
  if (!opts.launcher) throw new Error('--live 인데 launcher 가 없다');
1446
1531
  let prelaunch: AlreadyDoneDecision;
@@ -1501,21 +1586,42 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1501
1586
  const configuredRepo = project ? undefined : getUserConfig().harness?.defaultRepo;
1502
1587
  const knowhowRepo = project?.target ?? configuredRepo ?? resolve(import.meta.dir, '../..');
1503
1588
  const knowhow = selectKnowhowPack(knowhowRepo, card.text, targetPaths);
1504
- if (knowhow.text) childGoal = `${knowhow.text}\n\n${card.text}`;
1589
+ // Keep the card's target-path first line intact for launch preflight and PR title derivation.
1590
+ const injectKnowhow = getUserConfig().harness?.knowhowChildInjection === true;
1591
+ if (injectKnowhow && knowhow.text) childGoal = `${card.text}\n\n${knowhow.text}`;
1505
1592
  let repoRevision: string | null = null;
1506
1593
  try {
1507
1594
  const head = execFileSync('git', ['-C', knowhowRepo, 'rev-parse', '--verify', 'HEAD'], { encoding: 'utf8', timeout: 10_000, stdio: ['ignore', 'pipe', 'ignore'] }).trim();
1508
1595
  if (/^[0-9a-f]{40,64}$/i.test(head)) repoRevision = head;
1509
1596
  } catch { /* The source may be absent; reason=source-unreadable records that boundary. */ }
1510
- try { debug.log('task-agent', 'knowhow-pack', { taskId: id, ids: knowhow.ids, bytes: knowhow.bytes, injected: knowhow.bytes > 0,
1597
+ try { debug.log('task-agent', 'knowhow-pack', { taskId: id, goal: card.text.slice(0, 4096), ids: knowhow.ids, bytes: knowhow.bytes, injected: injectKnowhow && knowhow.bytes > 0,
1511
1598
  reason: knowhow.reason, repoPath: knowhowRepo, repoRevision,
1512
1599
  repoSource: project ? 'project' : configuredRepo ? 'harness.defaultRepo' : 'package' }); } catch { /* fail-soft */ }
1513
1600
  }
1601
+ // LAUNCH-SINGLE-DOOR-1C — 발사 직전 단일문: 모든 요청(중복 포함)은 원장에 append 되고, 소비 영수증은
1602
+ // requestId 단위로 최초 1회만 발급된다. 주입된 문이 없으면 생산 우주의 기본 문을 쓴다(시험 환경은 건너뛴다).
1603
+ const launchDoor = opts.launchRequestDoor
1604
+ ?? (process.env.NODE_ENV === 'test' ? undefined : openLaunchRequestDoor({ source: 'hand' }));
1605
+ const launchDoorRequestId = launchDoor?.requestId(card.text);
1606
+ let inheritedLaunchDoorReceipt: string | undefined;
1607
+ if (launchDoor !== undefined && launchDoorRequestId !== undefined) {
1608
+ const doorConsumption = launchDoor.consume(launchDoorRequestId);
1609
+ if (doorConsumption.status === 'refused') {
1610
+ const at = (opts.now ?? (() => new Date()))().toISOString();
1611
+ const refused: TaskCard = { ...card, history: [...card.history, { at, event: LAUNCH_REFUSED_DUPLICATE_EVENT, detail: doorConsumption.reason }] };
1612
+ writeCard(path, refused);
1613
+ try { debug.log('task-agent', 'launch-refused-duplicate', { taskId: id, requestId: launchDoorRequestId, reason: doorConsumption.reason }); } catch { /* fail-soft */ }
1614
+ return { card: refused, move, mode, launched: false, ...(project ? { cwd: project.target } : {}) };
1615
+ }
1616
+ // 소비 영수증을 자식 say 에 물려줘 그 문을 다시 두드리지 않게 한다(한 번만 상속).
1617
+ inheritedLaunchDoorReceipt = doorConsumption.status === 'consumed' ? launchDoorRequestId : undefined;
1618
+ }
1514
1619
  const runId = mintRunId();
1515
1620
  const launchId = newLaunchUtteranceId();
1516
1621
  recordLaunchUtterance({ source: 'hand', utterance: opts.text, launchId });
1517
1622
  const context: TaskLaunchContext = { runId, launchId, launchUtterance: opts.text, env: { [HARNESS_RUN_ID_ENV]: runId, ELANOUS_TASK_CARD_ID: card.id,
1518
1623
  ...parentRoleEnv,
1624
+ ...(inheritedLaunchDoorReceipt !== undefined ? { [LAUNCH_DOOR_RECEIPT_ENV]: inheritedLaunchDoorReceipt } : {}),
1519
1625
  ...(cardPrNumber(card) ? { ELANOUS_TASK_BOUND_PR: String(cardPrNumber(card)) } : {}),
1520
1626
  ...(card.checklistId ? { ELANOUS_POD_SLOT_ID: card.checklistId } : {}),
1521
1627
  ...(card.seat ? { ELANOUS_POD_OWNER_KIND: 'seat', ELANOUS_POD_OWNER_ID: card.seat } : {}),
@@ -1529,6 +1635,8 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1529
1635
  receipt = await opts.launcher(podLaunch ? [...move.command!.slice(0, -1), childGoal] : move.command!, project?.target, context);
1530
1636
  } catch (error) {
1531
1637
  const reason = error instanceof Error ? error.message : String(error);
1638
+ // LAUNCH-SINGLE-DOOR-1C — 발사 실패 사유를 원장에 append 한다(관측 — 소비된 영수증은 그대로다).
1639
+ if (launchDoor !== undefined && launchDoorRequestId !== undefined) launchDoor.fail(launchDoorRequestId, reason);
1532
1640
  const failed: TaskCard = { ...card, status: 'launch-failed', history: [
1533
1641
  ...card.history.filter((entry) => entry.event === 'child-model-reselected'),
1534
1642
  { at: (opts.now ?? (() => new Date()))().toISOString(), event: 'launch-failed', detail: reason },
@@ -30,6 +30,7 @@ export const TIER_SPLIT_DECOMPOSE_TIMEOUT_MS = 300_000;
30
30
 
31
31
  /** 조각이 부모 칸에서 물려받는 줄 머리 — hand 의 골 검사(완료 경계 셋)와 계약·경계 문맥. */
32
32
  const INHERITED_PARENT_LABELS = /^\s*(?:[-*]\s*)?(현재 계약|완료 경계 코드|완료 경계 실물|완료 경계 증거 명령|경계|증거 보충)\s*:/;
33
+ const PARENT_ACCEPTANCE_LABEL = /^\s*(?:[-*]\s*)?(수용선|판정|완료 조건|완료 경계 코드|완료 경계 실물|완료 경계 증거 명령)\s*:/;
33
34
  const VERIFICATION_PLAN_HEADING = '### 검증 계획(TDD)';
34
35
 
35
36
  /** Read a real Markdown section, ignoring headings inside fenced verbatim asks. */
@@ -77,7 +78,8 @@ export function composeSliceHandText(sliceGoal: string, parentText: string, mark
77
78
  inherited.push(...verificationPlan);
78
79
  // 표지는 리뷰 범위를 나르므로 장치 우선 조각(총 2 이상)은 상속 줄이 없어도 남는다 —
79
80
  // 다만 «물려받았다» 는 물려받은 줄에 대한 주장이므로 그 줄이 있을 때만 붙인다.
80
- if (inherited.length === 0 && (marker.total < 2 || !sliceGoal.includes(`동작: ${DEVICE_FIRST_STEP}`))) return sliceGoal;
81
+ const isAcceptanceIntegration = sliceGoal.includes('부모 수용선 몫(자동 통합 조각):');
82
+ if (inherited.length === 0 && (marker.total < 2 || (!isAcceptanceIntegration && !sliceGoal.includes(`동작: ${DEVICE_FIRST_STEP}`)))) return sliceGoal;
81
83
  const inheritedTopics = `계약·완료 경계${verificationPlan.length > 0 ? '·검증 계획' : ''}`;
82
84
  const inheritanceClaim = inherited.length > 0 ? ` 아래 ${inheritedTopics}는 부모 칸에서 물려받았다 — 이 조각 범위만 채운다.` : '';
83
85
  const tag = `조각 ${marker.index}/${marker.total} — 부모 ${marker.cid ?? '(칸 없음)'}(${marker.fromTier}) 를 중 이하로 나눈 몫.${inheritanceClaim}`;
@@ -88,22 +90,58 @@ export type TierSplitPlan =
88
90
  | { kind: 'split'; slices: SizedSlice[] }
89
91
  | { kind: 'blocked'; reason: string };
90
92
 
91
- /** 순수 판정 — 분해 결과 → 발사 계획. 이유 없는 상 조각이 하나라도 있으면 결과 전체를 실패로 본다(이유 없는 상 0). */
93
+ function parentAcceptanceLines(parentText: string): string[] {
94
+ return parentText.split(/\r?\n/u).map((line) => line.trim()).filter((line) => PARENT_ACCEPTANCE_LABEL.test(line));
95
+ }
96
+
97
+ function coveredAcceptanceLines(slices: readonly SizedSlice[], acceptance: readonly string[], parentText: string,
98
+ fromTier: '상' | '특', cid: string | null): string[] {
99
+ const effectiveGoals = slices.map((slice, index) => composeSliceHandText(slice.goal, parentText,
100
+ { index: index + 1, total: slices.length, fromTier, cid }));
101
+ return acceptance.filter((line) => effectiveGoals.some((goal) => goal.includes(line)));
102
+ }
103
+
104
+ function annotateAcceptanceShares(slices: readonly SizedSlice[], acceptance: readonly string[], integratedAdded = false): SizedSlice[] {
105
+ return slices.map((slice) => {
106
+ const share = acceptance.filter((line) => slice.goal.includes(line));
107
+ if (slice.goal.includes('부모 수용선 몫')) {
108
+ if (!integratedAdded || share.length >= acceptance.length || slice.goal.includes('누락 수용선은 자동 통합 조각이 담당한다.')) return slice;
109
+ return { ...slice, goal: `${slice.goal}\n- 누락 수용선은 자동 통합 조각이 담당한다.` };
110
+ }
111
+ if (share.length > 0) return { ...slice, goal: `${slice.goal}\n부모 수용선 몫:\n${share.map((line) => `- ${line}`).join('\n')}` };
112
+ if (acceptance.length > 0 && integratedAdded) return { ...slice, goal: `${slice.goal}\n부모 수용선 몫: 없음 — 누락 수용선은 자동 통합 조각이 담당한다.` };
113
+ return slice;
114
+ });
115
+ }
116
+
117
+ function recordAcceptanceCoverage(data: Record<string, unknown>): void {
118
+ try { debug.log('tier-split', 'slice-acceptance-coverage', data); } catch { /* fail-soft */ }
119
+ }
120
+
121
+ function integratedAcceptanceSlice(parentText: string, missing: readonly string[], slices: readonly SizedSlice[]): SizedSlice {
122
+ const paths = [...new Set(slices.flatMap((slice) => slice.goal.match(/[\w./-]+\.[A-Za-z][\w-]*/gu) ?? []))];
123
+ const goal = `${parentText}\n\n부모 수용선 몫(자동 통합 조각):\n${missing.map((line) => `- ${line}`).join('\n')}`;
124
+ return { goal, files: Math.max(1, paths.length), behaviours: Math.max(1, slices.reduce((sum, slice) => sum + slice.behaviours, 0)),
125
+ newFiles: slices.reduce((sum, slice) => sum + slice.newFiles, 0), tier: '상', unavoidable: 'acceptance-coverage-integration' };
126
+ }
127
+
128
+ /** 순수 판정 — 분해 결과에 남은 상 조각은 불가피 사유가 없어도 unavoidable=auto로 발사한다. */
92
129
  export function planTierSplit(result: TierSizedDecomposeResult): TierSplitPlan {
93
130
  if (!result.ok) return { kind: 'blocked', reason: `decompose-failed: ${result.reason}` };
94
131
  if (result.slices.length === 0) return { kind: 'blocked', reason: 'no-slices' };
95
132
  for (const [index, slice] of result.slices.entries()) {
96
133
  if (!['하', '중', '상'].includes(slice.tier)) return { kind: 'blocked', reason: `invalid-slice-tier: #${index + 1} ${String(slice.tier)}` };
97
134
  if (!slice.goal?.trim()) return { kind: 'blocked', reason: `empty-slice-goal: #${index + 1}` };
98
- if (slice.tier === '상' && !slice.unavoidable?.trim()) return { kind: 'blocked', reason: `unjustified-상-slice: #${index + 1}` };
99
135
  }
100
- const deviceSlices = result.slices.filter((slice) => slice.deviceFirst === 'device-test');
101
- if (deviceSlices.length === 0 && result.slices.some((slice) => slice.deviceFirst === 'feature'))
136
+ const slices = result.slices.map((slice) => slice.tier === '상'
137
+ ? { ...slice, unavoidable: slice.unavoidable?.trim() || 'auto' } : slice);
138
+ const deviceSlices = slices.filter((slice) => slice.deviceFirst === 'device-test');
139
+ if (deviceSlices.length === 0 && slices.some((slice) => slice.deviceFirst === 'feature'))
102
140
  return { kind: 'blocked', reason: 'device-first-stage-missing' };
103
- if (deviceSlices.length > 0 && (deviceSlices.length !== 1 || result.slices[0]?.deviceFirst !== 'device-test'
104
- || result.slices.slice(1).some((slice) => slice.deviceFirst !== 'feature')))
141
+ if (deviceSlices.length > 0 && (deviceSlices.length !== 1 || slices[0]?.deviceFirst !== 'device-test'
142
+ || slices.slice(1).some((slice) => slice.deviceFirst !== 'feature')))
105
143
  return { kind: 'blocked', reason: 'device-first-order-invalid' };
106
- return { kind: 'split', slices: result.slices };
144
+ return { kind: 'split', slices };
107
145
  }
108
146
 
109
147
  export interface TierSplitSliceOutcome { slice: SizedSlice; result?: HandTaskResult; error?: string }
@@ -144,19 +182,63 @@ export async function handTaskWithTierSplit(opts: TierSplitHandOptions): Promise
144
182
  record({ cid, fromTier, outcome: 'whole', reason: TIER_SPLIT_UNAVAILABLE, slices: [], unavoidable: [], ...acceptedSliceCounts([]) });
145
183
  return { kind: 'whole', result: await handTask(hand), reason: TIER_SPLIT_UNAVAILABLE };
146
184
  }
147
- let plan: TierSplitPlan;
148
- const controller = new AbortController();
149
- let timer: ReturnType<typeof setTimeout> | undefined;
150
- const timedOut = new Promise<'timeout'>((resolve) => { timer = setTimeout(() => { controller.abort(); resolve('timeout'); }, decomposeTimeoutMs); });
151
- try {
152
- const raced = await Promise.race([decompose(hand.text.trim(), { signal: controller.signal,
153
- ...(hand.project ? { repositoryRoot: resolve(hand.project.target) } : {}) }), timedOut]);
154
- plan = raced === 'timeout' ? { kind: 'blocked', reason: `decompose-timeout: ${decomposeTimeoutMs}ms` } : planTierSplit(raced);
155
- } catch (error) {
156
- plan = { kind: 'blocked', reason: `decompose-threw: ${String((error as Error)?.message ?? error).slice(0, 200)}` };
157
- } finally { clearTimeout(timer); }
185
+ const runDecompose = async (goal: string): Promise<{ plan: TierSplitPlan; result?: TierSizedDecomposeResult }> => {
186
+ const controller = new AbortController();
187
+ let timer: ReturnType<typeof setTimeout> | undefined;
188
+ const timedOut = new Promise<'timeout'>((resolve) => { timer = setTimeout(() => { controller.abort(); resolve('timeout'); }, decomposeTimeoutMs); });
189
+ try {
190
+ const raced = await Promise.race([decompose(goal, { signal: controller.signal,
191
+ ...(hand.project ? { repositoryRoot: resolve(hand.project.target) } : {}) }), timedOut]);
192
+ if (raced === 'timeout') return { plan: { kind: 'blocked', reason: `decompose-timeout: ${decomposeTimeoutMs}ms` } };
193
+ return { plan: planTierSplit(raced), result: raced };
194
+ } catch (error) {
195
+ return { plan: { kind: 'blocked', reason: `decompose-threw: ${String((error as Error)?.message ?? error).slice(0, 200)}` } };
196
+ } finally { clearTimeout(timer); }
197
+ };
198
+ const first = await runDecompose(hand.text.trim());
199
+ let plan = first.plan;
200
+ let decomposed = first.result;
201
+ const acceptance = parentAcceptanceLines(hand.text);
202
+ if (plan.kind === 'split') {
203
+ let candidateSlices = plan.slices;
204
+ let covered = coveredAcceptanceLines(candidateSlices, acceptance, hand.text, fromTier, cid);
205
+ let missing = acceptance.filter((line) => !covered.includes(line));
206
+ const inheritedByComposition = acceptance.filter((line) => INHERITED_PARENT_LABELS.test(line));
207
+ recordAcceptanceCoverage({ cid, fromTier, attempt: 1, coverageMode: 'exact-parent-line', inheritedByComposition, covered, missing });
208
+ if (missing.length > 0) {
209
+ const retryPrompt = `${hand.text.trim()}\n\n### 분해 필수 수용선\n각 조각의 "부모 수용선 몫"에 담당하는 원문 수용선 전체를 그대로 싣고, 조각들의 합집합으로 아래 모든 줄을 덮으세요.\n${missing.map((line) => `- ${line}`).join('\n')}`;
210
+ const retry = await runDecompose(retryPrompt);
211
+ if (retry.plan.kind === 'split') {
212
+ plan = retry.plan;
213
+ decomposed = retry.result;
214
+ candidateSlices = annotateAcceptanceShares(retry.plan.slices, acceptance);
215
+ }
216
+ covered = coveredAcceptanceLines(candidateSlices, acceptance, hand.text, fromTier, cid);
217
+ missing = acceptance.filter((line) => !covered.includes(line));
218
+ recordAcceptanceCoverage({ cid, fromTier, attempt: 2, coverageMode: 'exact-parent-line', inheritedByComposition, covered, missing,
219
+ retryReason: retry.plan.kind === 'blocked' ? retry.plan.reason : undefined });
220
+ let integratedAdded = false;
221
+ if (missing.length > 0) {
222
+ candidateSlices = [...candidateSlices, integratedAcceptanceSlice(hand.text, missing, candidateSlices)];
223
+ integratedAdded = true;
224
+ covered = coveredAcceptanceLines(candidateSlices, acceptance, hand.text, fromTier, cid);
225
+ missing = acceptance.filter((line) => !covered.includes(line));
226
+ }
227
+ candidateSlices = annotateAcceptanceShares(candidateSlices, acceptance, integratedAdded);
228
+ recordAcceptanceCoverage({ cid, fromTier, attempt: 'final', coverageMode: 'exact-parent-line', inheritedByComposition,
229
+ covered, missing, integrated: integratedAdded });
230
+ plan = { kind: 'split', slices: candidateSlices };
231
+ } else {
232
+ plan = { kind: 'split', slices: candidateSlices };
233
+ }
234
+ }
158
235
  if (plan.kind === 'blocked') {
159
- record({ cid, fromTier, outcome: 'blocked', reason: plan.reason, slices: [], unavoidable: [], ...acceptedSliceCounts([]) });
236
+ const rejectedOversized = decomposed?.ok
237
+ ? decomposed.slices.flatMap((slice, index) => slice.tier === '상' ? [{ index: index + 1, files: slice.files, behaviours: slice.behaviours }] : [])
238
+ : [];
239
+ record({ cid, fromTier, outcome: 'blocked', reason: plan.reason, slices: [], unavoidable: [],
240
+ ...(decomposed?.ok ? { redecomposed: decomposed.redecomposed } : {}),
241
+ rejectedOversized, rejectedOversizedCount: rejectedOversized.length, ...acceptedSliceCounts([]) });
160
242
  return { kind: 'blocked', result: await handTask({ ...hand, tierSplitBlocked: plan.reason }), reason: plan.reason };
161
243
  }
162
244
  const group = `${TASK_CARD_PREFIX}split-${randomBytes(4).toString('hex')}`;
@@ -165,7 +247,9 @@ export async function handTaskWithTierSplit(opts: TierSplitHandOptions): Promise
165
247
  const unavoidable = counts.unavoidableReasons;
166
248
  // 조각은 새 카드다 — 호출자 id·pr·goalId 를 조각마다 복제하면 «PR: #N» 조회·수확이 엇갈린다. 버린 것은 기록에 남긴다.
167
249
  const dropped = { ...(hand.id ? { id: hand.id } : {}), ...(hand.cardFields?.pr !== undefined ? { pr: hand.cardFields.pr } : {}), ...(hand.cardFields?.goalId !== undefined ? { goalId: hand.cardFields.goalId } : {}) };
168
- record({ cid, fromTier, outcome: 'split', group, ...(Object.keys(dropped).length ? { dropped } : {}), slices: plan.slices.map((s) => ({ tier: s.tier, files: s.files, behaviours: s.behaviours })), unavoidable: [...unavoidable],
250
+ record({ cid, fromTier, outcome: 'split', group, ...(Object.keys(dropped).length ? { dropped } : {}),
251
+ ...(decomposed?.ok ? { redecomposed: decomposed.redecomposed } : {}),
252
+ slices: plan.slices.map((s) => ({ tier: s.tier, files: s.files, behaviours: s.behaviours })), unavoidable: [...unavoidable],
169
253
  ...counts });
170
254
  const { id: _wholeId, cardFields, ...rest } = hand;
171
255
  const base = { ...rest, ...(cardFields?.handed !== undefined ? { cardFields: { handed: cardFields.handed } } : {}) };