elanous 0.2.38 → 0.2.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (615) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/{RrjXTwz-urRAbChP1bX02 → HjeK7zONHfR7op1hKXp4k}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{7954.4f7a8832663ee979.js → 1060.014f1f01a17aec26.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{8911.bf5e712acb25fb6c.js → 1281.d81877e35b9068f4.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/{2104.70e086d5174a4736.js → 1350.59f40e39e02d91b1.js} +1 -1
  7. package/apps/pwa/out/_next/static/chunks/1415.79821ec7ae99acdb.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1452.162bb2d9d699e82a.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/147.f92f63bbc5e85fa5.js +286 -0
  10. package/apps/pwa/out/_next/static/chunks/1537-6bb97b5214928ea9.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1661.fb425a1d8a065b72.js +149 -0
  12. package/apps/pwa/out/_next/static/chunks/1671-1c22b40b50b208f2.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1758.0204d3f48783c49d.js +90 -0
  14. package/apps/pwa/out/_next/static/chunks/1806.027bf78b6a94d340.js +104 -0
  15. package/apps/pwa/out/_next/static/chunks/2047.8f23e210995d4548.js +2 -0
  16. package/apps/pwa/out/_next/static/chunks/2061-7f2bbc53ae96c88b.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/{1632.7d87f998e714bede.js → 2066.a77257c8c350770a.js} +1 -1
  18. package/apps/pwa/out/_next/static/chunks/2096-a938496bc996dcbd.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/{8019.21ca554a821dad01.js → 2177.df8547f9d7215c4e.js} +3 -3
  20. package/apps/pwa/out/_next/static/chunks/2200-9a453b8f99687d49.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/{3528.e4b8ab70d339f965.js → 2226.2cf61ec781827219.js} +2 -2
  22. package/apps/pwa/out/_next/static/chunks/2281-b8cede695c6c650e.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/{6493.27ad77de7aac7966.js → 2499.02fbfd18126c10c0.js} +1 -1
  24. package/apps/pwa/out/_next/static/chunks/{7628.6b16863ac3972333.js → 2522.f2766b76d22c8bdf.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/{3086.fb14b60ce98b53d3.js → 2566.beaffc3a5e1fcd2e.js} +1 -1
  26. package/apps/pwa/out/_next/static/chunks/{9299.24e2a7d9b6d1f91b.js → 261.0d471e8aded799f3.js} +3 -3
  27. package/apps/pwa/out/_next/static/chunks/2615.3c9738153de3ef3f.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2727.e703d99ac414916d.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/2752.7904b8df0254d0ae.js +27 -0
  30. package/apps/pwa/out/_next/static/chunks/2762-5051a862dfa40e99.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/2767-31784bfedf8e245d.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/2774-719820e3f5b2a3eb.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/2812-f016aa0dda149287.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/2829-734fe8bf2eee7347.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/311-32dcac79970985e8.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3175-f93f7495cd28253c.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3184.8da993f5502d2140.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3231-d7c981db0ff8bdcc.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3250.151309c5176d6b4b.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/{7524.ce973525d30b3d52.js → 3330.7443183b7e6fdbdf.js} +1 -1
  41. package/apps/pwa/out/_next/static/chunks/3517.a5aa1797a9dbf2ee.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/3567-45f676877ed9e8a5.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/{3124-561f7f037943cde2.js → 3746-f80a78f220bf37b5.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/3819.8a1de79b2e8c7298.js +24 -0
  45. package/apps/pwa/out/_next/static/chunks/39.9b37b0be4c128a83.js +77 -0
  46. package/apps/pwa/out/_next/static/chunks/{bb6987f9.3647e1a23b0e3217.js → 3b355b3d.6f73c98bf6f9c749.js} +1 -1
  47. package/apps/pwa/out/_next/static/chunks/4023.a19045970a9ce16a.js +36 -0
  48. package/apps/pwa/out/_next/static/chunks/{8994d93e.33ba491f95345fc2.js → 409c787b.e48c5bec8ec10456.js} +1 -1
  49. package/apps/pwa/out/_next/static/chunks/{5041-5aada92ca215ffdd.js → 413-24c8284bda08241d.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/4135.e45d6ebc29e20647.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4283.65502f5d0e6ff6c0.js +287 -0
  52. package/apps/pwa/out/_next/static/chunks/4305-4e28fa92a7b34a5b.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4335-50efa61fd7613142.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4351.0f37a6db2b34d50b.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/{5638.107314dc479e2f37.js → 470.51a72a2348306455.js} +2 -2
  56. package/apps/pwa/out/_next/static/chunks/4720.ecbd1693fa151068.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/{8487.291666583bebe640.js → 4769.9fd582071301f382.js} +1 -1
  58. package/apps/pwa/out/_next/static/chunks/{8509.3a54d4e61893d7cb.js → 483.725e4a61be922788.js} +1 -1
  59. package/apps/pwa/out/_next/static/chunks/{9fe1b809.738da85c8b17e3fb.js → 4864a2ca.1c1c280a7772c5e5.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/4969-4b209d7307410c00.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5068-c7f53862f83c0917.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5315.bc96711c24dfefe2.js +74 -0
  63. package/apps/pwa/out/_next/static/chunks/{8879.ac06755bcf3e44a1.js → 5383.bdfa5d886e39a826.js} +1 -1
  64. package/apps/pwa/out/_next/static/chunks/{6142.913b44e260a3f925.js → 5436.fdf6fa8ae3e9588d.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/5542.efbf14f16baed4dd.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5622.94893f5aea7185d0.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5644.8f401a25601d05fc.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5658.35f70eb9871a54bf.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/5721.7bdc0e904c76ab51.js +8 -0
  70. package/apps/pwa/out/_next/static/chunks/5790-eef0ca20884a6bdf.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/5802.ef0d8598ca68fe84.js +62 -0
  72. package/apps/pwa/out/_next/static/chunks/5890.fb974729788dcb71.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/5924.5ef25cddd36d5dbf.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/5979-e59c099ebf8d1f35.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/6020.714cfeada2315e2e.js +94 -0
  76. package/apps/pwa/out/_next/static/chunks/6027-dfe0349d8c50f698.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/{7161-8f22db3ec5ed005e.js → 6051-0ae955eedb10adb9.js} +3 -3
  78. package/apps/pwa/out/_next/static/chunks/6178.bc4730c86cf74536.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/{3291.f6c1005387d514bd.js → 6257.c0037b8949239f5e.js} +2 -2
  80. package/apps/pwa/out/_next/static/chunks/6273.d808b0dcb3c2b155.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6292.6ef1df64fa6a4c8a.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/647-af8dd920ba46533c.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6541-170dc5c59e135c0c.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/6624.981ef7caeb680560.js +32 -0
  85. package/apps/pwa/out/_next/static/chunks/6742-a1ad4a94ba7bc37a.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/{5203.51e5d8b5f1dcfe53.js → 6749.0744ce6eb08d40e9.js} +3 -3
  87. package/apps/pwa/out/_next/static/chunks/6836-493dc55c39187949.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/6856-53ac421c06039a18.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/{1938.0e6c60ee91c4d7f5.js → 6908.06008c67f6380ea9.js} +2 -2
  90. package/apps/pwa/out/_next/static/chunks/6915.096931864206f522.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/6925.5e181fb7dcf90193.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{de8b930d.d94c0f42acf807fc.js → 6cc1d1d6.9a98dd4622f1afc6.js} +1 -1
  93. package/apps/pwa/out/_next/static/chunks/7203-800e11037adc41eb.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7219-15bdd9a80661af8e.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7279.6170f591105936bb.js +93 -0
  96. package/apps/pwa/out/_next/static/chunks/7349-373165c7fbdcc3df.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/7514-a533ba0ca1cae4f4.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7515.1ad6efe157fa4448.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/7521.d919cc1fab80c1d9.js +24 -0
  100. package/apps/pwa/out/_next/static/chunks/7538.90e97bbdf9178cff.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/7611.85f045bf232053ac.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/7825-39203196a12579b2.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/7869.5e1a9a12fd70d6c7.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8086.1ab9103c41be884f.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8099.1cccf31c1baa7e1c.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8179-e61fffbdb70f1152.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8265.bdeb991b34db6a06.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/{1026-44010f405704050c.js → 8272-025653884f9645d2.js} +1 -1
  109. package/apps/pwa/out/_next/static/chunks/{5307.d7328020227880c2.js → 8357.1aaa713b052a78b1.js} +4 -4
  110. package/apps/pwa/out/_next/static/chunks/8638-e42615f2166165b5.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/{4199-f7c6eb40cd0322f8.js → 8639-92c11d069792429e.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/8691.54e22831d5e8ccf8.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/8d173e38.18a2f7b4e1848bdb.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/9069.657590a84afb8fac.js +41 -0
  115. package/apps/pwa/out/_next/static/chunks/9125-ae588d88a0293b93.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9175.2de5209a5ce6f68a.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9184.45afbf44fec87574.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{eaad0cba.771200940c529df7.js → 9189505a.980427ac048c8c60.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/9311.f9f641a46a508611.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9371-a6fee8378ebfa3ee.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9421-3aa9ff4fa7f63d8a.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9992.07ce73c10bd5e6a1.js +79 -0
  123. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76394dc618d322c8.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/approvals/page-1b948637c37b3abd.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-c63400f1bcf3e47c.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/board/page-95d0957267819586.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-866aac5ff226a7f3.js → page-ba957ff875a026a0.js} +1 -1
  128. package/apps/pwa/out/_next/static/chunks/app/bots/page-bb6fd0714879cb87.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/ceo/page-8f9038520d2acbef.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/chat/page-d4b48397e05fce2c.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/consult/page-72d5744245dc0c27.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/control/page-37625dc8300fa43a.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/decisions/page-fbef9d160272dbc1.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/design-check/page-58424168df84928e.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/editor/page-72c12ba430ac57c0.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/exec/page-d53f3e9ed806d7e0.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/field/page-4d2fbd45feee0829.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/healthz/route-76394dc618d322c8.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/inside/page-8783dc0ed7590a2c.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/intake/page-3706cb390606e930.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/layout-9b0a86598e0111fd.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live/page-4edb8df90f4537ce.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live-run/page-83d27757e2b8060a.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/loops/page-47398b9ba1cc5e1b.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/market/page-fb86f55cfe2e681d.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e22345fc8fd47b1b.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/morning/page-fca2e59a81744d9e.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/not-found-6e96bda63100b31e.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/observatory/page-4d17ad8e0db8cea4.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-121f92766c33beaa.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-43f14212c545f92d.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ccec2023e7a974ec.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/outputs/page-b04f33f548b89a94.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/page-c8792823c0917021.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/reflection/page-8c0e32782ceef4cb.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-94bd3922eb230ce8.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/sessions/page-bca565887bafa03c.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ac1dffafe649fc6c.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/page-52374edb5e23e455.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ad4ebca120d43ca7.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/layout-76394dc618d322c8.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/page-718b89ce4b4ae4e4.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/share/page-204eca33eeeaddec.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/showroom/page-e58ba9bcdb9ac0f9.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/tasks/page-98f6dd50bafd7734.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/term/page-139d722de1dcd6c1.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/today/page-5a4bdd72bff27057.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/trace/page-6f6ab17d44f984ce.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/vault/page-aabb7bd15fb72da9.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-e4322319164a4436.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/page-e9efc0c8f32e2371.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workspace/page-ccde99f07aaf71f7.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-80464aced9614390.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/{b7478fef.5917716286213fcc.js → b84cad00.594027ebe0531fe2.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/c696986b.5dc8bb1143af16d1.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/{b7459770.6539b11860eb8a9c.js → ca3702f8.2913182e73889fa2.js} +7 -7
  177. package/apps/pwa/out/_next/static/chunks/{3f0de3de-2340c532c00395db.js → d5d3cefc-373c4eb722ed848b.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/{89d6c04f-6b8ab341748e468a.js → d8de0de2-dd0f4ac8e5ab1832.js} +1 -1
  179. package/apps/pwa/out/_next/static/chunks/{framework-4b12a946f352cee2.js → framework-002b472a66935d31.js} +1 -1
  180. package/apps/pwa/out/_next/static/chunks/main-49b88d47292c0476.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/main-app-fff2549cb10a133f.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_app-32abbbba3f3b76b7.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/pages/_error-9d9cfef60c60dd7a.js +1 -0
  184. package/apps/pwa/out/_next/static/chunks/webpack-cc7f483fa294034a.js +1 -0
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +22 -22
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +22 -22
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +22 -22
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +21 -21
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +21 -21
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +22 -22
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +21 -21
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +22 -22
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +22 -22
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +21 -21
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +22 -22
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +22 -22
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +22 -22
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +22 -22
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +21 -21
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +21 -21
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +22 -22
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +22 -22
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +22 -22
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +21 -21
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +21 -21
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +22 -22
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +22 -22
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +21 -21
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +21 -21
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +21 -21
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +22 -22
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +22 -22
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +21 -21
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +22 -22
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +22 -22
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +22 -22
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +22 -22
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +22 -22
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +21 -21
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +22 -22
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +22 -22
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +22 -22
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +22 -22
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +22 -22
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +22 -22
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +22 -22
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +22 -22
  278. package/graphs/demo/persona-marketer/fixtures/marketer-scenario.yaml +10 -0
  279. package/graphs/demo/persona-marketer/persona-marketer.yaml +25 -0
  280. package/graphs/demo/persona-marketer/recipes.yaml +19 -0
  281. package/graphs/video/explainer-line.yaml +4 -1
  282. package/package.json +1 -1
  283. package/scripts/dead-code/report.ts +169 -0
  284. package/scripts/lib/morning-report-options.ts +3 -4
  285. package/scripts/lib/tui-regress-evidence.ts +56 -0
  286. package/scripts/morning-report.ts +5 -1
  287. package/scripts/public-export.ts +15 -7
  288. package/scripts/release-loop/export-check-node.ts +21 -3
  289. package/scripts/release-loop/gate-node.ts +379 -48
  290. package/scripts/release-loop/gate-shard-dispatch.ts +128 -0
  291. package/scripts/release-loop/gate-shard-receipts.ts +89 -0
  292. package/scripts/release-loop/gate-wall.ts +5 -5
  293. package/scripts/release-loop/preflight.ts +6 -2
  294. package/scripts/release-loop/resume-release.ts +20 -5
  295. package/scripts/release-loop/resume.ts +48 -0
  296. package/scripts/release-loop/version-node.ts +7 -2
  297. package/scripts/release-story/draft.ts +1 -1
  298. package/scripts/research-bench/README.md +53 -0
  299. package/scripts/research-bench/questions.json +66 -0
  300. package/scripts/research-bench/rubric.md +33 -0
  301. package/scripts/research-bench/run.ts +523 -0
  302. package/scripts/tui-regress.ts +85 -10
  303. package/src/acp/core-turn-bridge.ts +8 -0
  304. package/src/agent/autonomous-tools.ts +10 -3
  305. package/src/agent/monad-agent-turn.ts +4 -1
  306. package/src/agent/registry.ts +26 -2
  307. package/src/agent/shared-app-tools.ts +1 -1
  308. package/src/agent/surface-ux/build.ts +12 -3
  309. package/src/agent/surface-ux/types.ts +1 -1
  310. package/src/agent/task-notification.ts +75 -6
  311. package/src/agent/types.ts +3 -0
  312. package/src/agent-mission/driver.ts +29 -3
  313. package/src/agent-mission/mission-cli.ts +2 -1
  314. package/src/agent-substrate/review-context-pack.ts +365 -0
  315. package/src/agent-substrate/self-review-cli.ts +226 -17
  316. package/src/ask-user-question/index.ts +6 -0
  317. package/src/ask-user-question/inline-resolver.ts +49 -0
  318. package/src/auto-research/question-ladder-contract.ts +22 -3
  319. package/src/auto-research/research-turn.ts +350 -17
  320. package/src/autopilot/agent-loop.ts +1 -1
  321. package/src/autopilot/pty-control-loop.ts +8 -1
  322. package/src/boot/daemon-tools/index.ts +4 -3
  323. package/src/boot/daemon-tools/self-implement.ts +270 -2
  324. package/src/boot/daemon-tools/types.ts +2 -0
  325. package/src/budget/llm-cost.ts +44 -5
  326. package/src/budget/unified-usage.ts +17 -1
  327. package/src/capture/tui-self-report.ts +14 -0
  328. package/src/chat/index.ts +33 -7
  329. package/src/cli/agent-cli.ts +43 -8
  330. package/src/cli/intake-cli.ts +22 -1
  331. package/src/cli/lesson-cli.ts +19 -3
  332. package/src/cli/log-event-names.ts +1 -0
  333. package/src/cli/pod-cli.ts +17 -2
  334. package/src/cli/pty-takeover-cli.ts +67 -7
  335. package/src/cli/release-cli.ts +52 -6
  336. package/src/cli/repo-cli.ts +2 -1
  337. package/src/cli/tasks-cli.ts +36 -9
  338. package/src/control-plane/ledger.ts +21 -4
  339. package/src/core-turn/run-core-turn.ts +44 -3
  340. package/src/core-turn/run-goal-loop.ts +152 -8
  341. package/src/core-turn/types.ts +9 -0
  342. package/src/dashboard/chat/acp-chat.ts +2 -2
  343. package/src/dashboard/classic-sigquit.ts +16 -0
  344. package/src/dashboard/index.ts +321 -27
  345. package/src/dashboard/input/chat-main-interaction-opts.ts +3 -0
  346. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +7 -2
  347. package/src/dashboard/input/chat-main-slash-command.ts +7 -0
  348. package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
  349. package/src/dashboard/input/dashboard-priority-key-route.ts +21 -5
  350. package/src/dashboard/input/external-input-host.ts +2 -0
  351. package/src/dashboard/sidetab-runtime.ts +228 -0
  352. package/src/dashboard/slash-runtime/ask-clarification.ts +7 -1
  353. package/src/dashboard/slash-runtime/dashboard-handlers.ts +20 -8
  354. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -2
  355. package/src/dashboard/term-slash-runtime.ts +16 -18
  356. package/src/dashboard/turn-preamble.ts +2 -0
  357. package/src/domains/knowledge.ts +1 -1
  358. package/src/esc-abort-gate.ts +33 -1
  359. package/src/execution-loop/launch-gate.ts +206 -1
  360. package/src/graph-runner/graph-cli.ts +6 -4
  361. package/src/graph-runner/runner.ts +31 -9
  362. package/src/graph-wizard/generate.ts +16 -7
  363. package/src/graph-wizard/mission-compose.ts +201 -0
  364. package/src/grok/agent-search.ts +8 -2
  365. package/src/grok/credential.ts +5 -0
  366. package/src/grounding/ref-index.ts +11 -0
  367. package/src/grounding/ref-vector.ts +61 -0
  368. package/src/grounding/sources-cli.ts +2 -2
  369. package/src/grounding/sources.ts +15 -1
  370. package/src/harness/harness-cli-command.ts +38 -9
  371. package/src/harness/harness-pod-dispatch.ts +7 -1
  372. package/src/index.ts +18 -4
  373. package/src/input/external-input-queue.ts +10 -0
  374. package/src/intake-plane/collect-telegram-saved.ts +36 -1
  375. package/src/intake-plane/intake-to-tasks.ts +246 -3
  376. package/src/lessons/friction-ledger.ts +154 -0
  377. package/src/live-supply/collector.ts +149 -0
  378. package/src/live-supply/probes.ts +52 -0
  379. package/src/live-supply/snapshot.ts +40 -0
  380. package/src/llm.ts +431 -76
  381. package/src/loops/orchestrator/tick.ts +8 -0
  382. package/src/nexus/api/harness-api.ts +2 -1
  383. package/src/pty/snapshot.py +132 -0
  384. package/src/pty-shell/pty-control-ipc.ts +29 -2
  385. package/src/pty-shell/pty-manifest.ts +59 -3
  386. package/src/pty-shell/registry.ts +2 -0
  387. package/src/pty-shell/tui-run-state.ts +80 -3
  388. package/src/release-loop/gate-host-reservation.ts +13 -4
  389. package/src/release-loop/gate-shard-ledger.ts +68 -0
  390. package/src/release-loop/merged-pr-checklist.ts +25 -2
  391. package/src/release-loop/rehearsal-shard-plan.ts +6 -1
  392. package/src/release-loop/rehearsal.ts +27 -0
  393. package/src/research/edge-decision.ts +124 -15
  394. package/src/research/gap-followup.ts +249 -0
  395. package/src/research/lenses/counter-evidence.ts +100 -0
  396. package/src/research/lenses/working-backwards.ts +89 -0
  397. package/src/research/plugin-discovery.ts +242 -0
  398. package/src/research-bridge/invoke.ts +4 -2
  399. package/src/research-bridge/types.ts +2 -0
  400. package/src/self-dev/ask-launch-flow.ts +34 -106
  401. package/src/self-dev/dev-cli.ts +2 -0
  402. package/src/self-dev/dev-pipeline.ts +8 -4
  403. package/src/self-dev/graph-journey-route.ts +10 -2
  404. package/src/self-dev/launch-preflight-text.ts +2 -2
  405. package/src/self-dev/launch-preflight.ts +38 -7
  406. package/src/self-dev/orchestrate-cli.ts +1 -0
  407. package/src/self-dev/run-supervisor.ts +19 -0
  408. package/src/self-implement/device-first.ts +8 -2
  409. package/src/self-implement/doctor-visit.ts +76 -58
  410. package/src/self-implement/gate-artifacts.ts +3 -0
  411. package/src/self-implement/gate-baseline.ts +75 -4
  412. package/src/self-implement/gate-cli.ts +317 -9
  413. package/src/self-implement/gate-receipt-registry.ts +180 -0
  414. package/src/self-implement/gate-remote.ts +145 -22
  415. package/src/self-implement/goal-author-clarification.ts +178 -24
  416. package/src/self-implement/goal-author-decompose.ts +24 -15
  417. package/src/self-implement/goal-author.ts +9 -5
  418. package/src/self-implement/host-regate.ts +120 -45
  419. package/src/self-implement/impl-findings-feedback.ts +188 -0
  420. package/src/self-implement/knowhow-pack.ts +189 -10
  421. package/src/self-implement/off-diff-evidence.ts +124 -0
  422. package/src/self-implement/orchestrator.ts +85 -7
  423. package/src/self-implement/run-ledger.ts +46 -8
  424. package/src/self-implement/run-stop.ts +12 -0
  425. package/src/self-implement/seams.ts +6 -3
  426. package/src/self-implement/self-implement-cli.ts +4 -2
  427. package/src/session/chat.ts +89 -15
  428. package/src/session-runtime/provider-circuit.ts +140 -0
  429. package/src/shell-runner/file-engine.ts +1 -0
  430. package/src/shell-runner/types.ts +4 -0
  431. package/src/sidetab-core/model.ts +176 -0
  432. package/src/skills/tools/schedule-wakeup.ts +23 -1
  433. package/src/skills/tools/shell.ts +51 -5
  434. package/src/steward/directive-audit.ts +354 -0
  435. package/src/surface/child-process.ts +31 -0
  436. package/src/surface/tui-stderr-owner.ts +48 -0
  437. package/src/task-agent/cover.ts +30 -12
  438. package/src/task-agent/judge.ts +56 -0
  439. package/src/task-agent/postland-card.ts +35 -2
  440. package/src/task-agent/rejudge-on-head.ts +46 -2
  441. package/src/task-agent/repair-cycle.ts +1 -1
  442. package/src/task-agent/task-hand.ts +129 -24
  443. package/src/task-agent/tier-split.ts +105 -21
  444. package/src/task-orchestrator/surfaces/pod-command-job.ts +330 -2
  445. package/src/task-orchestrator/surfaces/pod-config-snapshot.ts +123 -0
  446. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +27 -2
  447. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +11 -8
  448. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +1 -1
  449. package/src/task-orchestrator/surfaces/pod-source-receive.ts +74 -6
  450. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +2 -1
  451. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +56 -15
  452. package/src/task-orchestrator/surfaces/self-implement-pod.ts +186 -33
  453. package/src/tool-runtime/skill-exec-runtime.ts +95 -5
  454. package/src/tui/entry.ts +15 -2
  455. package/src/tui/inline-choice.ts +188 -0
  456. package/src/tui/sidetab/list.ts +2 -176
  457. package/src/tui/slash/term.ts +12 -1
  458. package/src/tui-client/dashboard-session.ts +7 -1
  459. package/src/user-config.ts +34 -4
  460. package/src/ux-sim/classic-tui-seat-scenarios.ts +1 -7
  461. package/src/ux-sim/fake-land-queue.ts +88 -0
  462. package/src/ux-sim/gate-shard-host-reroute.ts +82 -0
  463. package/src/ux-sim/goal-interim-trace.ts +24 -0
  464. package/src/ux-sim/next-tui-seat-scenarios.ts +8 -13
  465. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +4 -1
  466. package/src/version/packed-revision.json +1 -1
  467. package/src/video-pipeline/recipes/explainer.ts +54 -2
  468. package/src/web-search/grok.ts +32 -6
  469. package/src/web-search/index.ts +8 -7
  470. package/src/workflow-runtime/node-catalog.ts +53 -4
  471. package/apps/pwa/out/_next/static/chunks/1118.a8a74ea29aac3e46.js +0 -27
  472. package/apps/pwa/out/_next/static/chunks/1204-2aa830479adf80f4.js +0 -1
  473. package/apps/pwa/out/_next/static/chunks/1341-43b7d2dc77d45c9d.js +0 -1
  474. package/apps/pwa/out/_next/static/chunks/1440-c3ea8882badfd9bf.js +0 -1
  475. package/apps/pwa/out/_next/static/chunks/1698-9c11cbf97f13717e.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/1770-3b1fc92253ef9f2f.js +0 -1
  477. package/apps/pwa/out/_next/static/chunks/1923-5c1695332240246a.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/213-20675f20673ba22a.js +0 -1
  479. package/apps/pwa/out/_next/static/chunks/214.186a430da28338f1.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/2277.3bd4c0ac7f1b5996.js +0 -93
  481. package/apps/pwa/out/_next/static/chunks/240.e09f433f71c78ff4.js +0 -104
  482. package/apps/pwa/out/_next/static/chunks/2415.738b777642a02233.js +0 -1
  483. package/apps/pwa/out/_next/static/chunks/2417.02151393605a7cd0.js +0 -1
  484. package/apps/pwa/out/_next/static/chunks/2463.cd2641a76daaa9ff.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/2576.b9e9c629c4b84c52.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/265-c021de53f0865bd9.js +0 -1
  487. package/apps/pwa/out/_next/static/chunks/2998-b1cc13956cd6a6e7.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/2e4782d3.ba2f0ab2b63a53e7.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/3130.626b54382b4dc379.js +0 -1
  490. package/apps/pwa/out/_next/static/chunks/3221-1bb3f99a55088613.js +0 -1
  491. package/apps/pwa/out/_next/static/chunks/3280.24edb1ffd03a7f3f.js +0 -24
  492. package/apps/pwa/out/_next/static/chunks/3288-eb3c22a1cbf2ae68.js +0 -1
  493. package/apps/pwa/out/_next/static/chunks/33.ef99e8374f96c6c4.js +0 -36
  494. package/apps/pwa/out/_next/static/chunks/3341-f09b9efbd7a82f70.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/3389.012c70767a872f9b.js +0 -1
  496. package/apps/pwa/out/_next/static/chunks/3410-d7c0f14b329d6fda.js +0 -1
  497. package/apps/pwa/out/_next/static/chunks/3421.c87d6313a7d670f7.js +0 -287
  498. package/apps/pwa/out/_next/static/chunks/3422-83a3953f9bd67e26.js +0 -1
  499. package/apps/pwa/out/_next/static/chunks/3587-002e24e368c515a9.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/3644.f12a7d821ab940af.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/3660.d7516588e2d875c3.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/3695.b82e2610f4cd4ea9.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/3858.ca1f5bc0f577eac9.js +0 -94
  504. package/apps/pwa/out/_next/static/chunks/3959-e6ac4a139d9d4bcc.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/4032.53f62176514ec0ea.js +0 -1
  506. package/apps/pwa/out/_next/static/chunks/4204-ef8484cbecd5d62f.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/4259-163129ca79913c4b.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/428-eaa77df3d0c85969.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/4432-97e400ffa1e161f5.js +0 -1
  510. package/apps/pwa/out/_next/static/chunks/449-aa427cf2cbb75f50.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/4491-39a0fd32bbaf3840.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/4588.b7cf06d382953979.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/4690.70ec8060825366ab.js +0 -32
  514. package/apps/pwa/out/_next/static/chunks/4804.6012b5cd33c22792.js +0 -90
  515. package/apps/pwa/out/_next/static/chunks/4881.e4d22d730e3b9df5.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/4937.ce2e340dc29cad3e.js +0 -79
  517. package/apps/pwa/out/_next/static/chunks/5-bb1c08d84bd71df3.js +0 -1
  518. package/apps/pwa/out/_next/static/chunks/5005.de98df23b37cdf3c.js +0 -1
  519. package/apps/pwa/out/_next/static/chunks/5035.dc64a89cad5573cc.js +0 -74
  520. package/apps/pwa/out/_next/static/chunks/5207.1a224035455790fd.js +0 -1
  521. package/apps/pwa/out/_next/static/chunks/5255-1b60d50eabe9f057.js +0 -1
  522. package/apps/pwa/out/_next/static/chunks/5269.d0436ee6d773382a.js +0 -286
  523. package/apps/pwa/out/_next/static/chunks/5300.677c97e0393742e6.js +0 -1
  524. package/apps/pwa/out/_next/static/chunks/5309.3367c4d50f52b489.js +0 -1
  525. package/apps/pwa/out/_next/static/chunks/552-689827d49780fa00.js +0 -1
  526. package/apps/pwa/out/_next/static/chunks/5539.34cc9d60622cb69b.js +0 -8
  527. package/apps/pwa/out/_next/static/chunks/5568.218dea0c00ca2ec7.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/5645.b7e3b055455a04ea.js +0 -1
  529. package/apps/pwa/out/_next/static/chunks/5662.18cc0f30353cbd96.js +0 -1
  530. package/apps/pwa/out/_next/static/chunks/5671.da24fc9dc5e98325.js +0 -1
  531. package/apps/pwa/out/_next/static/chunks/5b141171.324c40fd49cb6821.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/6175-d4621f6a10b0cfab.js +0 -1
  533. package/apps/pwa/out/_next/static/chunks/6290.3eb53a20746b72ce.js +0 -1
  534. package/apps/pwa/out/_next/static/chunks/6415-9307f3eafa90837f.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/6579-3de35d00aacd71b5.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/680-2f324c4e039a5b67.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/6845-331b3c7481da3ba3.js +0 -1
  538. package/apps/pwa/out/_next/static/chunks/7000.28157393caaf5343.js +0 -62
  539. package/apps/pwa/out/_next/static/chunks/7311-60a7ea80d23c7521.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/7401.525d0a12f7d02c06.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/7438.c2cf72b66dca6aa4.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/7488.966b116789f3d41a.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/7573.2376e13c9c21f1f8.js +0 -77
  544. package/apps/pwa/out/_next/static/chunks/7577.ea6e9ac72e035520.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/7657.8d1fb3d2f7ebe273.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/7903-1435d5d2f0dd7807.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/7978-30a91192c5dbe3c2.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/8025-8795821525cf1a07.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/8191.3674a00f0b565c23.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/8217-604955d8885c5ef2.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/8298-eed6f5f2585a63f4.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/8758.ac421f726a189125.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/891.d6c723a51a067b36.js +0 -149
  554. package/apps/pwa/out/_next/static/chunks/9223.cbcc88e0e9950426.js +0 -41
  555. package/apps/pwa/out/_next/static/chunks/9317.6a9869039c231bb3.js +0 -24
  556. package/apps/pwa/out/_next/static/chunks/9383.e4755f275b3c11ff.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/9581.da63ddf41acfad46.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/9715.8c5529a0a5c41a36.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/9817.3009d65f0889ef1f.js +0 -2
  560. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76873dd80da4f715.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed32b6ec5dea8f23.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-fdd40e15babf3d25.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/app/board/page-384efc78e85e400b.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/app/bots/page-d91809c5aeed319a.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/app/ceo/page-128f3522f89a81ab.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/app/chat/page-595961abf3b43ad1.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/app/consult/page-f41dccb76d8c0263.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/app/control/page-a3205c2e28b7d0d9.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/app/decisions/page-c39a80277814a3f4.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/app/design-check/page-1ab3f98194513195.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/app/editor/page-a5246f7e254d77d0.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/app/exec/page-0f92287bdb81217d.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/app/field/page-5a37131ff63793ef.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/app/healthz/route-76873dd80da4f715.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/app/inside/page-ac4bd14bb2348bfd.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/app/intake/page-c348a3959c5b5fc6.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/app/layout-2addd81c0d3e2906.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/app/live/page-da6b765f58a3eefb.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/app/live-run/page-0661e40f8780c32c.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/app/loops/page-b89af1b1c8e4875b.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/app/market/page-da8aeb82ba751cdb.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-cc71317b239439db.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/app/morning/page-bde7fc1d64ffe369.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/app/not-found-e2797214f713fa58.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/app/observatory/page-2a35bcda70defaf6.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3af03deedde45032.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-d1d1210f99f620ae.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-46d1b5500885861d.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/app/outputs/page-291ab19fe2acb173.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/app/page-7f569e533ddeecba.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/app/reflection/page-990129c9fee46d8f.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-7737f785ebb1cdaf.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9f3c73a4f7ffd2f8.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-03be7fb347f01058.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/app/settings/page-96b0280625e4df2b.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-56855545049eb56d.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/app/setup/layout-76873dd80da4f715.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/app/setup/page-79a909c9981f0338.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/app/share/page-a9d9a3e66459c1e0.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c383cbf2013f7069.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f57c6a2e54dbdca4.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/app/term/page-6b140f77593576eb.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/app/today/page-6b767ae2d9d0adfc.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/app/trace/page-116d6198d5da0e3d.js +0 -1
  605. package/apps/pwa/out/_next/static/chunks/app/vault/page-b9c9b778c7501370.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-a6c78392ab8f6335.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/app/workflows/page-455183deb4ed0cfe.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6a63e99526bd63d0.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-31c22caafe788c08.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/main-941155250ed2644b.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/main-app-f8b6765abed6d149.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/pages/_app-78432194c85388f9.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/pages/_error-cdf7390829512b1b.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/webpack-d5f0964a9c2e92d2.js +0 -1
  615. /package/apps/pwa/out/_next/static/{RrjXTwz-urRAbChP1bX02 → HjeK7zONHfR7op1hKXp4k}/_ssgManifest.js +0 -0
@@ -76,6 +76,62 @@ export function mustFixSignature(mustFix?: readonly string[]): string | undefine
76
76
  return `fnv1a-${hash.toString(16).padStart(8, '0')}`;
77
77
  }
78
78
 
79
+ /**
80
+ * 빈 구현 must-fix 신호(대상 3종) — 리뷰가 이 신호를 담은 must-fix 를 내면 같은 PR 수리(narrow-relaunch)로는 수렴하지 않는다.
81
+ * 결정론 분류만 한다(LLM 경로 없음). 판별은 문구 일치로 하되 오탐을 피해 좁게 잡는다.
82
+ */
83
+ const EMPTY_IMPLEMENTATION_SIGNALS: readonly { name: string; patterns: readonly RegExp[] }[] = [
84
+ {
85
+ name: '구현 파일 변경 0',
86
+ patterns: [
87
+ /빈 구현/u,
88
+ /empty[- ]implementation/iu,
89
+ /구현 파일[^\n.]{0,8}(없음|없다|미변경)|구현 파일[^\n.]{0,24}변경[^\n.]{0,8}0(?!\d)/u,
90
+ /구현 (diff|변경|차분)[^\n.]{0,8}0(?!\d)/u,
91
+ /implementation files?[^\n.]{0,32}(unchanged|zero|no change)/iu,
92
+ /(no|zero) (implementation|code) (changes|diff)/iu,
93
+ /target diff (is )?0(?!\d)/iu,
94
+ ],
95
+ },
96
+ {
97
+ name: 'GOODHART/자기 문구 시험',
98
+ patterns: [/GOODHART/iu, /자기 ?문구/u, /골 문면/u, /goal[ -]?(text|wording)/iu],
99
+ },
100
+ {
101
+ name: '대상 경로 미배선',
102
+ patterns: [/미배선/u, /배선되지 않/u, /호출부[^\n.]{0,8}(없음|없다)/u, /not[ -]?wired/iu, /unwired/iu, /no caller/iu, /dead code/iu],
103
+ },
104
+ ];
105
+
106
+ /** 빈 구현 must-fix 판정의 수 — 첫 회는 같은 칸 새 발사(재구현), 이미 두 번째면 칸 주인 이관(needs-owner). */
107
+ export type EmptyImplementationMove = 'reimplement' | 'needs-owner';
108
+
109
+ /** 판정 관측 한 줄 — `reason` 이 그대로 관측 로그 문면이다(줄바꿈 없음). */
110
+ export interface EmptyImplementationJudgement {
111
+ move: EmptyImplementationMove;
112
+ signals: readonly string[];
113
+ reason: string;
114
+ }
115
+
116
+ /**
117
+ * 리뷰 must-fix 가 «빈 구현» 신호(구현 파일 변경 0 · GOODHART/자기 문구 시험 · 대상 경로 미배선)를 담는지 결정론 분류한다.
118
+ * 신호를 담으면 narrow-relaunch 대신 재구현 판정 — 같은 칸의 앞 런에서 이미 빈 구현 must-fix 였으면
119
+ * (priorEmptyImplementation ≥ 1) 두 번째이므로 needs-owner. 신호가 없으면 null — 일반 must-fix 는 종전대로 narrow-relaunch.
120
+ */
121
+ export function judgeEmptyImplementation(
122
+ mustFix: readonly string[] | undefined,
123
+ priorEmptyImplementation = 0,
124
+ ): EmptyImplementationJudgement | null {
125
+ const signals: string[] = [];
126
+ for (const { name, patterns } of EMPTY_IMPLEMENTATION_SIGNALS) {
127
+ if ((mustFix ?? []).some(fix => typeof fix === 'string' && patterns.some(pattern => pattern.test(fix)))) signals.push(name);
128
+ }
129
+ if (!signals.length) return null;
130
+ const move: EmptyImplementationMove = priorEmptyImplementation >= 1 ? 'needs-owner' : 'reimplement';
131
+ const disposition = move === 'needs-owner' ? '두 번째 빈 구현 — 칸 주인에게 이관' : '같은 PR 수리로는 수렴 불가 — 같은 칸 새 발사(시험 먼저)';
132
+ return { move, signals, reason: `빈 구현 must-fix(${signals.join(' · ')}) — ${disposition}` };
133
+ }
134
+
79
135
  export interface TaskJudgement {
80
136
  move: TaskMove;
81
137
  stage: 'observing' | 'closing' | 'reviewing' | 'repairing' | 'waiting' | 'escalated';
@@ -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,6 +39,8 @@ 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';
@@ -182,7 +186,22 @@ export interface CompositionSelection {
182
186
  export const COMPOSITION_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..', '..');
183
187
 
184
188
  /** 1판은 조합을 고르고 단위 해석 결과를 기록한다. 단위 실행은 2판의 몫이다. */
185
- export function selectTaskComposition(completion: CompletionKind, root = COMPOSITION_ROOT): CompositionSelection {
189
+ export function selectTaskComposition(completion: CompletionKind, root?: string): CompositionSelection;
190
+ export function selectTaskComposition(completion: CompletionKind, root: string, mission: {
191
+ text: string; ledgerPath: string; cardId: string; callLLM?: GraphWizardDeps['callLLM']; onPersist?: (persist: () => void) => void;
192
+ }): Promise<CompositionSelection>;
193
+ export function selectTaskComposition(completion: CompletionKind, root = COMPOSITION_ROOT, mission?: {
194
+ text: string; ledgerPath: string; cardId: string; callLLM?: GraphWizardDeps['callLLM']; onPersist?: (persist: () => void) => void;
195
+ }): CompositionSelection | Promise<CompositionSelection> {
196
+ if (mission) {
197
+ const standard = selectTaskComposition(completion, root);
198
+ return import('../graph-wizard/mission-compose.js').then(async ({ composeMissionGraph }) => {
199
+ const result = await composeMissionGraph({ text: mission.text, completion, root, ledgerPath: mission.ledgerPath,
200
+ cardId: mission.cardId, standard }, { callLLM: mission.callLLM, deferPersistence: mission.onPersist !== undefined });
201
+ mission.onPersist?.(result.persist);
202
+ return result.selection;
203
+ });
204
+ }
186
205
  const requested = `graphs/work/${completion}.yaml`;
187
206
  // DEFAULT-HANDS — 종류별 조합이 없으면 그 손의 기본 조합(«실행·조사»)으로 내려간다.
188
207
  // 비개발 종결이 «조합 없음»으로 막히면 사람별 표본이 과제 담당에 닿지도 못한다.
@@ -284,7 +303,7 @@ export interface TaskCard {
284
303
  completion?: CompletionKind;
285
304
  /** 선택된 일 조합 파일과 판(1판: 실행은 launcher 에 위임). */
286
305
  composition?: TaskComposition;
287
- graphSelectedBy?: 'completion';
306
+ graphSelectedBy?: 'completion' | 'mission-compose';
288
307
  unitsResolved?: boolean;
289
308
  missingUnits?: string[];
290
309
  /** 과제 대상 프로젝트(§A4b②) — target 은 절대 경로(git 이 아닐 수 있다). id 는 `task hand --project` 가 싣는다(옛 카드엔 없을 수 있다). */
@@ -839,6 +858,41 @@ export function readTaskCard(id: string, path = taskAgentStatePath()): TaskCard
839
858
  return readState(path).tasks?.[id];
840
859
  }
841
860
 
861
+ /**
862
+ * IMPL-FINDINGS-FEEDBACK — 착지(landed·landed-by-hand) 판정이 난 카드의 병합 PR 본문 절을
863
+ * 되먹임한다: 원장 1회 기록(중복 억제) ⊕ 관련 기록만 다음 저작 입력 주입 ⊕ 후속 초안(자동 발사 없음).
864
+ * PR 이 묶이지 않았거나 아직 착지 판정이 아니면 아무것도 하지 않는다. 실패는 관측(`debug.log`)만.
865
+ */
866
+ export async function recordPostLandImplFindings(
867
+ card: TaskCard,
868
+ input: { prBody: string; ask: string },
869
+ options: { ledgerDir?: string; followUp?: NonNullable<Parameters<typeof RecordImplFindingsFeedback>[1]>['followUp'] } = {},
870
+ ): Promise<Awaited<ReturnType<typeof RecordImplFindingsFeedback>> | null> {
871
+ const pr = cardPrNumber(card);
872
+ if (pr === undefined || !(card.status === 'landed' || card.status === 'landed-by-hand'
873
+ || (card.status === 'done' && card.prTerminal?.pr === pr))) return null;
874
+ if (!card.runId?.trim()) {
875
+ try { debug.log('task-agent', 'impl-findings-skipped', { card: card.id, pr, reason: 'run-id-missing' }); } catch { /* fail-soft */ }
876
+ return null;
877
+ }
878
+ try {
879
+ const { recordImplFindingsFeedback } = await import('../self-implement/impl-findings-feedback.js');
880
+ return await recordImplFindingsFeedback({
881
+ runId: card.runId,
882
+ prNumber: pr,
883
+ prBody: input.prBody,
884
+ ask: input.ask,
885
+ ...(card.goalId ? { goalId: card.goalId } : {}),
886
+ }, {
887
+ ...(options.ledgerDir ? { dir: options.ledgerDir } : {}),
888
+ ...(options.followUp ? { followUp: options.followUp } : {}),
889
+ });
890
+ } catch (error) {
891
+ try { debug.log('task-agent', 'impl-findings-failed', { card: card.id, pr, reason: error instanceof Error ? error.message : String(error) }); } catch { /* fail-soft */ }
892
+ return null;
893
+ }
894
+ }
895
+
842
896
  /** TA-REVIEW-PASS — runId 기준 단일 카드 멱등 생성 결과. `ok: false` 는 임의 생성 없이 사유만 남긴 보류(fail-closed)다. */
843
897
  export type IdempotentRunCardCreate =
844
898
  | { ok: true; card: TaskCard; created: boolean }
@@ -900,6 +954,9 @@ export function cardsTouchingPaths(cards: readonly TaskCard[], paths: readonly s
900
954
 
901
955
  export const CLOSED_BY_HAND_EVENT = 'closed-by-hand';
902
956
 
957
+ /** LAUNCH-SINGLE-DOOR-1C — 단일문 거절 줄 — 같은 requestId 로 이미 소비된 중복 발사를 카드 history 에 남긴다. */
958
+ export const LAUNCH_REFUSED_DUPLICATE_EVENT = 'launch-refused-duplicate';
959
+
903
960
  /** 카드를 손으로 닫는다 — 상태를 `failed` 로 두고 history 에 한 줄(`closed-by-hand`)을 남긴다. 이미 손으로 닫은 카드는 그대로 돌려준다(멱등). */
904
961
  export function closeTaskCard(card: TaskCard, input: { reason: string; by: string; at: string }): TaskCard {
905
962
  const reason = input.reason.trim();
@@ -1065,6 +1122,10 @@ export interface HandTaskOptions {
1065
1122
  statePath?: string;
1066
1123
  /** 시험에서만 조합 저장소를 바꿔 해석·거부를 검증한다. */
1067
1124
  compositionRoot?: string;
1125
+ /** Explicit opt-in for mission graph composition; omitted is the fixed completion graph. */
1126
+ composeGraph?: boolean;
1127
+ /** Injectable LLM boundary for isolated composition tests. */
1128
+ composeCallLLM?: GraphWizardDeps['callLLM'];
1068
1129
  /** `--live` 일 때만 불린다. */
1069
1130
  launcher?: TaskLauncher;
1070
1131
  /**
@@ -1096,6 +1157,11 @@ export interface HandTaskOptions {
1096
1157
  * 거짓이면 쓰지 않고 `TaskCardSupersededError` — 다른 넘김이 그 카드를 가져갔다(발사 전이면 발사하지 않는다).
1097
1158
  */
1098
1159
  writeGuard?: (current: TaskCard | undefined) => boolean;
1160
+ /**
1161
+ * LAUNCH-SINGLE-DOOR-1C — 발사 직전 단일문(append 요청 원장 ⊕ requestId 단위 단일 소비 영수증).
1162
+ * 생산은 기본 문(이 우주의 인스턴스 루트)을 쓰고, 시험은 격리 루트의 문을 주입해 같은 생산 경로로 검증한다.
1163
+ */
1164
+ launchRequestDoor?: LaunchRequestDoor;
1099
1165
  }
1100
1166
 
1101
1167
  /** `writeGuard` 가 거짓 — 다른 넘김이 카드를 가져갔다. 카드는 건드리지 않았다. */
@@ -1233,20 +1299,8 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1233
1299
  const parentRolePins = taskParentRolePinsForChild(opts.parentRoleLlm ?? [], childLlm);
1234
1300
  let parentRoleEnv = taskParentRoleEnv(parentRolePins); // validate before writing the card
1235
1301
  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);
1302
+ const now = (opts.now ?? (() => new Date()))();
1303
+ const id = opts.id ?? `${TASK_CARD_PREFIX}${now.toISOString().slice(0, 10).replaceAll('-', '')}-${randomBytes(3).toString('hex')}`;
1250
1304
  let project: TaskCard['project'];
1251
1305
  let targetIsGit: boolean | null = null;
1252
1306
  if (opts.project) {
@@ -1262,8 +1316,6 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1262
1316
  if (!selection.ok) throw new Error(`코드 종결은 git 대상이 필요 — --completion 을 고르거나 git init: ${target}`);
1263
1317
  project = { id: opts.project.id, target: selection.repo };
1264
1318
  }
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
1319
  const mode = opts.live ? 'live' : 'shadow';
1268
1320
  // DRAFT-CLAIM-AUTO-2-FU — claim 은 카드를 쓰기 «전»에 판정한다(거부면 원장에 아무것도 남기지 않는다).
1269
1321
  // 견줄 상대는 카드 원장(디스크)의 다른 카드다 — 손이 들고 있는 사본이 아니라 정본을 본다.
@@ -1273,6 +1325,25 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1273
1325
  ...(opts.seat !== undefined ? { seat: opts.seat } : {}), now, ask: text,
1274
1326
  })
1275
1327
  : undefined;
1328
+ let persistComposition: (() => void) | undefined;
1329
+ const selected = (opts.composeGraph ?? (process.env.ELANOUS_MISSION_GRAPH_COMPOSE === '1'))
1330
+ ? await selectTaskComposition(completion, opts.compositionRoot ?? COMPOSITION_ROOT,
1331
+ { text, ledgerPath: path, cardId: id, callLLM: opts.composeCallLLM,
1332
+ onPersist: persist => { persistComposition = persist; } })
1333
+ : selectTaskComposition(completion, opts.compositionRoot);
1334
+ // 2판 — launcher 'graph-run' 조합(단위 해석까지 완료)은 실제 graph run 으로 발사한다. 더 이상 거부하지 않는다.
1335
+ const graphRun = selected.composition && selected.launcher === 'graph-run' && !selected.error && selected.unitsResolved
1336
+ ? selected.composition : undefined;
1337
+ const graphRunPath = graphRun ? resolve(opts.compositionRoot ?? COMPOSITION_ROOT, graphRun.file) : undefined;
1338
+ const selectionFailure = graphRun ? undefined
1339
+ : !selected.composition ? `조합 없음: graphs/work/${completion}.yaml`
1340
+ : selected.error ?? (selected.launcher === 'graph-run' && !selected.unitsResolved
1341
+ ? `조합 단위 미해석: ${selected.composition.file} — 대상 unit: ${selected.missingUnits.length ? selected.missingUnits.join(', ') : '해석 실패'} (graph-run 발사는 단위 해석이 필요하다)`
1342
+ // DEFAULT-HANDS — 코드 하니스(harness-say 자식 구현 런)는 개발자 팩(code-pr)만 쓴다.
1343
+ : !DEFAULT_HANDS[completion].codeHarness && selected.launcher === 'harness-say'
1344
+ ? `조합 실행기 없음: ${selected.composition.file} — ${completion} 은 «실행·조사» 손이라 코드 하니스(harness-say)를 쓰지 않는다(개발자 팩 전용)`
1345
+ : selected.launcher === undefined
1346
+ ? `조합 실행기 없음: ${selected.composition.file} (발사 가능한 launcher: harness-say · graph-run)` : undefined);
1276
1347
  let card: TaskCard = {
1277
1348
  id, text,
1278
1349
  ...(!targetPathHints.labelMissing ? { targetPaths } : {}),
@@ -1280,7 +1351,9 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1280
1351
  ...(opts.checklistId ? { checklistId: opts.checklistId } : {}),
1281
1352
  ...(opts.checklistVersion !== undefined ? { checklistVersion: opts.checklistVersion } : {}),
1282
1353
  ...(opts.completion ? { completion: opts.completion } : {}),
1283
- ...(selected.composition ? { composition: selected.composition, graphSelectedBy: 'completion' as const } : {}),
1354
+ ...(selected.composition ? { composition: selected.composition,
1355
+ graphSelectedBy: selected.composition.file === join(dirname(path), `${id}.generated.yaml`)
1356
+ ? 'mission-compose' as const : 'completion' as const } : {}),
1284
1357
  unitsResolved: selected.unitsResolved,
1285
1358
  missingUnits: selected.missingUnits,
1286
1359
  ...(project ? { project } : {}),
@@ -1378,6 +1451,7 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1378
1451
  }
1379
1452
  }
1380
1453
  writeCard(path, card);
1454
+ if (!selectionFailure && tierSplitBlocked === undefined && move?.kind === 'launch') persistComposition?.();
1381
1455
  try { debug.log('task-agent.hand', 'target-paths', { card: id, count: targetPaths.length, labelMissing: targetPathHints.labelMissing }); } catch { /* fail-soft */ }
1382
1456
  try { debug.log('task-agent.graph-select', !selected.composition ? 'composition-missing' : selected.error ? 'composition-invalid' : 'composition-selected', {
1383
1457
  completion, file: selected.composition?.file ?? `graphs/work/${completion}.yaml`,
@@ -1418,7 +1492,14 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1418
1492
  recordLaunchUtterance({ source: 'hand', utterance: opts.text, launchId });
1419
1493
  let state: GraphRunState;
1420
1494
  try {
1421
- state = await (opts.graphRunner ?? runGraph)(graphRunPath, { runId, input: { ask: text }, quiet: true });
1495
+ // Graph-run unit contracts consume all three envelope fields. `make-doc` forwards
1496
+ // context.worktree to its headless goal loop, so preserve the card's project target
1497
+ // when available; otherwise keep absence explicit for units that can decide safely.
1498
+ state = await (opts.graphRunner ?? runGraph)(graphRunPath, {
1499
+ runId,
1500
+ input: { ask: text, context: project ? { worktree: project.target } : {}, prior: {} },
1501
+ quiet: true,
1502
+ });
1422
1503
  } catch (error) {
1423
1504
  // 조합 파일·대상 node가 없으면 runGraph 가 구체 사유로 던진다 — 임의 성공 처리하지 않는다.
1424
1505
  const reason = `graph run 실패: ${error instanceof Error ? error.message : String(error)}`;
@@ -1431,8 +1512,9 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1431
1512
  const at = (opts.now ?? (() => new Date()))().toISOString();
1432
1513
  const ok = state.status === 'done';
1433
1514
  // 실패 종료도 구체 blocker(종료 상태·이유·마지막 node)를 기록한다 — 임의 성공 처리하지 않는다.
1515
+ const lastNode = state.nodes.at(-1);
1434
1516
  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 없음'}`;
1517
+ + `${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
1518
  const launchedGraph: TaskCard = { ...card, status: ok ? 'launched' : 'failed', runId: state.runId, launchId,
1437
1519
  history: [...card.history,
1438
1520
  { at, event: 'launch', detail: `graph run ${graphRunPath} (run ${state.runId})` },
@@ -1440,7 +1522,7 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1440
1522
  ...(blocker ? [{ at, event: 'graph-run-failed', detail: blocker, runId: state.runId }] : [])] };
1441
1523
  writeCard(path, launchedGraph);
1442
1524
  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 } : {}) };
1525
+ return { card: launchedGraph, move: ok ? move : nextMoveFor(launchedGraph), mode, launched: true, ...(project ? { cwd: project.target } : {}) };
1444
1526
  }
1445
1527
  if (!opts.launcher) throw new Error('--live 인데 launcher 가 없다');
1446
1528
  let prelaunch: AlreadyDoneDecision;
@@ -1501,21 +1583,42 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1501
1583
  const configuredRepo = project ? undefined : getUserConfig().harness?.defaultRepo;
1502
1584
  const knowhowRepo = project?.target ?? configuredRepo ?? resolve(import.meta.dir, '../..');
1503
1585
  const knowhow = selectKnowhowPack(knowhowRepo, card.text, targetPaths);
1504
- if (knowhow.text) childGoal = `${knowhow.text}\n\n${card.text}`;
1586
+ // Keep the card's target-path first line intact for launch preflight and PR title derivation.
1587
+ const injectKnowhow = getUserConfig().harness?.knowhowChildInjection === true;
1588
+ if (injectKnowhow && knowhow.text) childGoal = `${card.text}\n\n${knowhow.text}`;
1505
1589
  let repoRevision: string | null = null;
1506
1590
  try {
1507
1591
  const head = execFileSync('git', ['-C', knowhowRepo, 'rev-parse', '--verify', 'HEAD'], { encoding: 'utf8', timeout: 10_000, stdio: ['ignore', 'pipe', 'ignore'] }).trim();
1508
1592
  if (/^[0-9a-f]{40,64}$/i.test(head)) repoRevision = head;
1509
1593
  } 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,
1594
+ 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
1595
  reason: knowhow.reason, repoPath: knowhowRepo, repoRevision,
1512
1596
  repoSource: project ? 'project' : configuredRepo ? 'harness.defaultRepo' : 'package' }); } catch { /* fail-soft */ }
1513
1597
  }
1598
+ // LAUNCH-SINGLE-DOOR-1C — 발사 직전 단일문: 모든 요청(중복 포함)은 원장에 append 되고, 소비 영수증은
1599
+ // requestId 단위로 최초 1회만 발급된다. 주입된 문이 없으면 생산 우주의 기본 문을 쓴다(시험 환경은 건너뛴다).
1600
+ const launchDoor = opts.launchRequestDoor
1601
+ ?? (process.env.NODE_ENV === 'test' ? undefined : openLaunchRequestDoor({ source: 'hand' }));
1602
+ const launchDoorRequestId = launchDoor?.requestId(card.text);
1603
+ let inheritedLaunchDoorReceipt: string | undefined;
1604
+ if (launchDoor !== undefined && launchDoorRequestId !== undefined) {
1605
+ const doorConsumption = launchDoor.consume(launchDoorRequestId);
1606
+ if (doorConsumption.status === 'refused') {
1607
+ const at = (opts.now ?? (() => new Date()))().toISOString();
1608
+ const refused: TaskCard = { ...card, history: [...card.history, { at, event: LAUNCH_REFUSED_DUPLICATE_EVENT, detail: doorConsumption.reason }] };
1609
+ writeCard(path, refused);
1610
+ try { debug.log('task-agent', 'launch-refused-duplicate', { taskId: id, requestId: launchDoorRequestId, reason: doorConsumption.reason }); } catch { /* fail-soft */ }
1611
+ return { card: refused, move, mode, launched: false, ...(project ? { cwd: project.target } : {}) };
1612
+ }
1613
+ // 소비 영수증을 자식 say 에 물려줘 그 문을 다시 두드리지 않게 한다(한 번만 상속).
1614
+ inheritedLaunchDoorReceipt = doorConsumption.status === 'consumed' ? launchDoorRequestId : undefined;
1615
+ }
1514
1616
  const runId = mintRunId();
1515
1617
  const launchId = newLaunchUtteranceId();
1516
1618
  recordLaunchUtterance({ source: 'hand', utterance: opts.text, launchId });
1517
1619
  const context: TaskLaunchContext = { runId, launchId, launchUtterance: opts.text, env: { [HARNESS_RUN_ID_ENV]: runId, ELANOUS_TASK_CARD_ID: card.id,
1518
1620
  ...parentRoleEnv,
1621
+ ...(inheritedLaunchDoorReceipt !== undefined ? { [LAUNCH_DOOR_RECEIPT_ENV]: inheritedLaunchDoorReceipt } : {}),
1519
1622
  ...(cardPrNumber(card) ? { ELANOUS_TASK_BOUND_PR: String(cardPrNumber(card)) } : {}),
1520
1623
  ...(card.checklistId ? { ELANOUS_POD_SLOT_ID: card.checklistId } : {}),
1521
1624
  ...(card.seat ? { ELANOUS_POD_OWNER_KIND: 'seat', ELANOUS_POD_OWNER_ID: card.seat } : {}),
@@ -1529,6 +1632,8 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
1529
1632
  receipt = await opts.launcher(podLaunch ? [...move.command!.slice(0, -1), childGoal] : move.command!, project?.target, context);
1530
1633
  } catch (error) {
1531
1634
  const reason = error instanceof Error ? error.message : String(error);
1635
+ // LAUNCH-SINGLE-DOOR-1C — 발사 실패 사유를 원장에 append 한다(관측 — 소비된 영수증은 그대로다).
1636
+ if (launchDoor !== undefined && launchDoorRequestId !== undefined) launchDoor.fail(launchDoorRequestId, reason);
1532
1637
  const failed: TaskCard = { ...card, status: 'launch-failed', history: [
1533
1638
  ...card.history.filter((entry) => entry.event === 'child-model-reselected'),
1534
1639
  { at: (opts.now ?? (() => new Date()))().toISOString(), event: 'launch-failed', detail: reason },