elanous 0.2.32 → 0.2.34

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 (633) 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/{IVKr3AlRUVLKsw2fh7eXF → L04y73dlwKeTW-GetaTF3}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/1162.c69abda138c7ce43.js +79 -0
  5. package/apps/pwa/out/_next/static/chunks/1449-1fede62af84c3e43.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1598-13fc845935e816df.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1639.62c5e16fa20d242f.js +94 -0
  8. package/apps/pwa/out/_next/static/chunks/{4174.92ed04922709ac9e.js → 1644.35dd25240ae24e4b.js} +2 -2
  9. package/apps/pwa/out/_next/static/chunks/1661-adb8b2babc9aaf8c.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/{2940-619bfd8ef337c611.js → 1895-60ed0e341c658bd4.js} +1 -1
  11. package/apps/pwa/out/_next/static/chunks/{5525.86debf231e181813.js → 2124.ed5bf480cea7f85b.js} +1 -1
  12. package/apps/pwa/out/_next/static/chunks/2147.107c0fc6146fb15a.js +23 -0
  13. package/apps/pwa/out/_next/static/chunks/2202-ef1c9b000c3074fc.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/2247.1e326638ee43e672.js +115 -0
  15. package/apps/pwa/out/_next/static/chunks/2268.56e1e3d58180abae.js +8 -0
  16. package/apps/pwa/out/_next/static/chunks/2469-606819c812414021.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/{6092.a7f99e68b188ca66.js → 2547.dd27303624cb4da8.js} +1 -1
  18. package/apps/pwa/out/_next/static/chunks/{2213.2ccbada92c33ea0f.js → 2554.3b5e200f5f5cfcd6.js} +16 -16
  19. package/apps/pwa/out/_next/static/chunks/2593.e53c1620c0bb3599.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2690.e96671114222676a.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2898-79ee1a5cc0cd9d13.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/298.26099a9f65e5c8ff.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/{5173-233188df2f42c626.js → 2987-30cf9c2eb7b8bdd5.js} +1 -1
  24. package/apps/pwa/out/_next/static/chunks/2992.51fc2a7295bd8139.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/{3541-ce3a5424ed5ad7f1.js → 3001-5a52788c813b6113.js} +1 -1
  26. package/apps/pwa/out/_next/static/chunks/3014-291245fba9df7b5b.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/3068.ee78201f0251a18d.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/3083.cd399a17e9365f78.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/3103.84470c8445962f04.js +34 -0
  30. package/apps/pwa/out/_next/static/chunks/{6433.fc573af22bbc9ab7.js → 3110.0a7065f25c841818.js} +17 -17
  31. package/apps/pwa/out/_next/static/chunks/3117-e1c474683fd1f824.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/3121.779fafe3e44612c5.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/3251-2c17bd5a91f8de2e.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/326.3fb32322bb2ddf6d.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/3411-f87314c6c66ebc73.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/{6157.0c9af021de4fb31b.js → 3414.172ad4ca2d9b08e8.js} +2 -2
  37. package/apps/pwa/out/_next/static/chunks/3421-7ff7fbaa156985a7.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{4745.67d6f99c245af3f7.js → 3498.cf2a15a8a9e5b926.js} +3 -3
  39. package/apps/pwa/out/_next/static/chunks/381.f55dc63ea87735e6.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3819.163d4777f0a597f6.js +32 -0
  41. package/apps/pwa/out/_next/static/chunks/{5543.a438b8ab5a13ea47.js → 3837.722e053fb9f321ad.js} +1 -1
  42. package/apps/pwa/out/_next/static/chunks/4129-ab0a6189f1778633.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4361.93d14ba594b3a035.js +104 -0
  44. package/apps/pwa/out/_next/static/chunks/4364.7a7eb19cceb67d2f.js +286 -0
  45. package/apps/pwa/out/_next/static/chunks/4406.d71f506f7c3ee9d3.js +149 -0
  46. package/apps/pwa/out/_next/static/chunks/4461.2ad1514180ae7e29.js +148 -0
  47. package/apps/pwa/out/_next/static/chunks/4479.bd309cbe0e3842ee.js +64 -0
  48. package/apps/pwa/out/_next/static/chunks/4522-05966f777d66d13b.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4543-9a3e9812e845de65.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4557.f8f1d84a0d90d590.js +74 -0
  51. package/apps/pwa/out/_next/static/chunks/4589-79b11542179ef58c.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4633-9f8f9f88ffbb8f5c.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4831.23af4d10c0697b5e.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4983.5951b85724f61f2a.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/{b313b242.cb1265eea908db61.js → 4fa33ebd.21c1bd5b294496e6.js} +1 -1
  56. package/apps/pwa/out/_next/static/chunks/{997ce8a5-2ad501927003b41b.js → 5014f970-22bef0b5210f7d60.js} +1 -1
  57. package/apps/pwa/out/_next/static/chunks/{2112-e4efc21a6505d5bc.js → 5028-f0722e6114c313e7.js} +1 -1
  58. package/apps/pwa/out/_next/static/chunks/{2898.fd781bc7cf01a7b7.js → 5249.96a848656b582a93.js} +1 -1
  59. package/apps/pwa/out/_next/static/chunks/5311.16e0ffbfa5468b80.js +62 -0
  60. package/apps/pwa/out/_next/static/chunks/{9407.e49124dedf0f5e72.js → 5446.edf141cff9ef647d.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{9002.e5658224e3dc1b6f.js → 5489.ec2dd1b5272a19dc.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/{1335-6731f392c35216eb.js → 5576-82d3703636d5c4b9.js} +3 -3
  63. package/apps/pwa/out/_next/static/chunks/559.df87695df637920c.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5618-5c88f2f70178c4ad.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/5764.05487bf0b73ddb6b.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5930.e678826c3f831aab.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5dfb57f7.f2e3305326202474.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/6053-d893974de92e6198.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/{2985.39ccdecd36848b12.js → 6086.913a69e6fa3e4a8b.js} +4 -4
  70. package/apps/pwa/out/_next/static/chunks/6200-cefd6f33f59d765e.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6314-edeba650ae686ac9.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6316-bc9a9b74d7842d79.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6476-13b9779b73528008.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/666-04db3ac4c8e3c66f.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/670.682e55106ef915a6.js +77 -0
  76. package/apps/pwa/out/_next/static/chunks/{7862.30a8d6482bb238eb.js → 6740.43de73fc427c9fe2.js} +1 -1
  77. package/apps/pwa/out/_next/static/chunks/6816.b7ba9d0a1a4a46a7.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/690-fbbcc777f189af37.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6989.0d3d4020e5cb3df6.js +90 -0
  80. package/apps/pwa/out/_next/static/chunks/{2871.0bca6137343b3f76.js → 7005.1623d2aea78eb85f.js} +1 -1
  81. package/apps/pwa/out/_next/static/chunks/7193-cf355cca5ba6c5d5.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/7217-d17393fe7af78fa6.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/7232.24edbd938a69c8d0.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7295cd1e.b4b557908888eeee.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7323.adb02de21991883c.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7386.5d8e7e42e818dfb6.js +287 -0
  87. package/apps/pwa/out/_next/static/chunks/{7502.ccd5b8065545edd0.js → 7431.3051e9b8a4372d2d.js} +2 -2
  88. package/apps/pwa/out/_next/static/chunks/{3583.a05e88cc8d594628.js → 7448.478958ffbbba0ac0.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/7537.ba2208c5c656b8a3.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7562.948255cbc3e79d33.js +41 -0
  91. package/apps/pwa/out/_next/static/chunks/7596-962ae6db6cfc9c83.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7671.cff51beac212a2ba.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7883.3916734ee16d3e58.js +27 -0
  94. package/apps/pwa/out/_next/static/chunks/{9989.3694300e5f000b14.js → 7952.b192c31b6a0e00cc.js} +1 -1
  95. package/apps/pwa/out/_next/static/chunks/801.5b24e81eded22d1b.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/8176.8c9a8613f5a01ac1.js +36 -0
  97. package/apps/pwa/out/_next/static/chunks/819e78a6.fa3dd7f7da19bf61.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8220-78978450c3183d8d.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/8221-eb60b5bc692a3361.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/826.e9a26064f474949e.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/{5307.60f2209e809bd627.js → 8368.014caa8de2f5af34.js} +1 -1
  102. package/apps/pwa/out/_next/static/chunks/8459-a351487a4480f584.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8482-75823d513a4ce151.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8488.8da515248cda3f3a.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{9221.7d22eaf353a2d4e7.js → 8548.036c344973968847.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/8584.388a1779d9b203af.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8637.a55e098e61ffefb8.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8817.61bb7ffbba502ecb.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/{9398-6aed28f0a96d0d6f.js → 9131-fce7256c4180c4a5.js} +1 -1
  110. package/apps/pwa/out/_next/static/chunks/9207-8e6a12db30373f32.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/9263-00ae932c62696a86.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9318.caafc3a130e8769c.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/932.da3fb55951882562.js +93 -0
  114. package/apps/pwa/out/_next/static/chunks/9433.002f8426ac75b6b7.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9464.dd631a5a14b1d660.js +24 -0
  116. package/apps/pwa/out/_next/static/chunks/{3278.2e5d15b53a4091c8.js → 9550.d5f76828f972058c.js} +2 -2
  117. package/apps/pwa/out/_next/static/chunks/{2534.e85ae21ad0dac829.js → 9739.8d5f36ac67a3b236.js} +1 -1
  118. package/apps/pwa/out/_next/static/chunks/9743.beeabb9d5f86abe4.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9843-a23d3f32dc43f715.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/994-28211077c7c587d5.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{7a1887c4.f36b88fba31da8fd.js → 9a8cb466.cc9fc9e6e46038aa.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/{0bb0ff36.b8d418980951e5ba.js → 9b48c871.204d5d13e7809bd0.js} +7 -7
  123. package/apps/pwa/out/_next/static/chunks/{409f1e57.d0649fc47691ebfe.js → abb4b98b.163e0f56e84ae35d.js} +1 -1
  124. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-3b4c947f174e33d8.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/approvals/page-369d5ce99483f859.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-63c0ed0eb26e5fce.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/board/page-62802c6003bc85cc.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ecb41560d4e77be9.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/bots/page-7b65ad8130c93e95.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/ceo/page-8755477c15a9060c.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/chat/page-5725447dd972c471.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/consult/page-b979de0591a69375.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/control/page-6d0796bf4633751a.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/decisions/page-59c31dc0394e67b4.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/design-check/page-12dfc95f6cc5c718.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/editor/page-25788244e66aa4dd.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/exec/page-a2555dc705466322.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/field/page-4fb31eb476dcbad3.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/healthz/route-3b4c947f174e33d8.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/inside/page-578729adbeaa40cb.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/intake/page-a1d20fffbec35205.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/layout-4a558f94516b8004.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live/page-9e3834705b86145e.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/live-run/page-d7bff0f0905a662c.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/loops/page-cb1c5fe746ea4014.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/market/page-9ee320507356582a.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66fd183b74835886.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/morning/page-3272a064a01a9927.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/not-found-f281b7a7f6ef2529.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/observatory/page-d45a65f8b7124fcd.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-e9c1fe684dd19a66.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-b8322932fc6e34de.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-82c66d9af2290575.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/outputs/page-63c6752009c97b05.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/page-bb33d42ebc358aec.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7e4c9379197d7214.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-38bf1e9a7001732b.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/sessions/page-2e5b752012389d56.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-8c66a3b24a745630.js → page-398c0faa173203f7.js} +1 -1
  160. package/apps/pwa/out/_next/static/chunks/app/settings/page-002f53a965b6445c.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-7f75997f61a26269.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/layout-3b4c947f174e33d8.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/page-05631753294f23fb.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/share/page-edd700fd2cc3d7f8.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/showroom/page-105f83ecb4594365.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/tasks/page-5823e87d2017f19c.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/term/{page-04d00ae9b0890349.js → page-df3445b207ceceab.js} +1 -1
  168. package/apps/pwa/out/_next/static/chunks/app/today/page-b51ca09566c03de7.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/trace/page-8aacd5ded5dbac60.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/vault/page-bae3365a0b3c6a8e.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ed52b48ff1aa7fd.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b6f8cad35fe00946.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6d25ceda500d2457.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-b6401a5f2c962fe8.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/ebf6cf5e.0d2f887b040e80fb.js +122 -0
  176. package/apps/pwa/out/_next/static/chunks/f09ec7d7-d29abe23edcbb193.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/{ebc7d829.264a0bcb6c750b50.js → ffdc3a04.b9c23c1b28dd4a96.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/framework-9322cb8a56ac081c.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-2fbab294e49a1561.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-f36729f56621a8f3.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-2a62e450b47c6114.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-5e17f7b445f34d43.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-b4263e2190ea7adf.js +1 -0
  184. package/apps/pwa/out/approvals/index.html +1 -1
  185. package/apps/pwa/out/approvals/index.txt +22 -22
  186. package/apps/pwa/out/autopilot/index.html +1 -1
  187. package/apps/pwa/out/autopilot/index.txt +22 -22
  188. package/apps/pwa/out/board/index.html +1 -1
  189. package/apps/pwa/out/board/index.txt +22 -22
  190. package/apps/pwa/out/botlab/index.html +1 -1
  191. package/apps/pwa/out/botlab/index.txt +21 -21
  192. package/apps/pwa/out/bots/index.html +1 -1
  193. package/apps/pwa/out/bots/index.txt +21 -21
  194. package/apps/pwa/out/ceo/index.html +1 -1
  195. package/apps/pwa/out/ceo/index.txt +22 -22
  196. package/apps/pwa/out/chat/index.html +1 -1
  197. package/apps/pwa/out/chat/index.txt +21 -21
  198. package/apps/pwa/out/consult/index.html +1 -1
  199. package/apps/pwa/out/consult/index.txt +22 -22
  200. package/apps/pwa/out/control/index.html +1 -1
  201. package/apps/pwa/out/control/index.txt +22 -22
  202. package/apps/pwa/out/decisions/index.html +1 -1
  203. package/apps/pwa/out/decisions/index.txt +21 -21
  204. package/apps/pwa/out/design-check/index.html +1 -1
  205. package/apps/pwa/out/design-check/index.txt +22 -22
  206. package/apps/pwa/out/editor/index.html +1 -1
  207. package/apps/pwa/out/editor/index.txt +22 -22
  208. package/apps/pwa/out/exec/index.html +1 -1
  209. package/apps/pwa/out/exec/index.txt +22 -22
  210. package/apps/pwa/out/field/index.html +1 -1
  211. package/apps/pwa/out/field/index.txt +22 -22
  212. package/apps/pwa/out/healthz +1 -1
  213. package/apps/pwa/out/index.html +1 -1
  214. package/apps/pwa/out/index.txt +21 -21
  215. package/apps/pwa/out/inside/index.html +1 -1
  216. package/apps/pwa/out/inside/index.txt +21 -21
  217. package/apps/pwa/out/intake/index.html +1 -1
  218. package/apps/pwa/out/intake/index.txt +22 -22
  219. package/apps/pwa/out/live/index.html +1 -1
  220. package/apps/pwa/out/live/index.txt +22 -22
  221. package/apps/pwa/out/live-run/index.html +1 -1
  222. package/apps/pwa/out/live-run/index.txt +22 -22
  223. package/apps/pwa/out/loops/index.html +1 -1
  224. package/apps/pwa/out/loops/index.txt +21 -21
  225. package/apps/pwa/out/market/index.html +1 -1
  226. package/apps/pwa/out/market/index.txt +21 -21
  227. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  228. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  229. package/apps/pwa/out/morning/index.html +1 -1
  230. package/apps/pwa/out/morning/index.txt +22 -22
  231. package/apps/pwa/out/observatory/index.html +1 -1
  232. package/apps/pwa/out/observatory/index.txt +22 -22
  233. package/apps/pwa/out/ops/checklist/index.html +1 -1
  234. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  235. package/apps/pwa/out/ops/release/index.html +1 -1
  236. package/apps/pwa/out/ops/release/index.txt +21 -21
  237. package/apps/pwa/out/ops/seats/index.html +1 -1
  238. package/apps/pwa/out/ops/seats/index.txt +21 -21
  239. package/apps/pwa/out/outputs/index.html +1 -1
  240. package/apps/pwa/out/outputs/index.txt +21 -21
  241. package/apps/pwa/out/reflection/index.html +1 -1
  242. package/apps/pwa/out/reflection/index.txt +22 -22
  243. package/apps/pwa/out/scheduler/index.html +1 -1
  244. package/apps/pwa/out/scheduler/index.txt +22 -22
  245. package/apps/pwa/out/sessions/index.html +1 -1
  246. package/apps/pwa/out/sessions/index.txt +21 -21
  247. package/apps/pwa/out/settings/devices/index.html +1 -1
  248. package/apps/pwa/out/settings/devices/index.txt +22 -22
  249. package/apps/pwa/out/settings/index.html +1 -1
  250. package/apps/pwa/out/settings/index.txt +22 -22
  251. package/apps/pwa/out/setup/done/index.html +1 -1
  252. package/apps/pwa/out/setup/done/index.txt +22 -22
  253. package/apps/pwa/out/setup/index.html +1 -1
  254. package/apps/pwa/out/setup/index.txt +22 -22
  255. package/apps/pwa/out/share/index.html +1 -1
  256. package/apps/pwa/out/share/index.txt +22 -22
  257. package/apps/pwa/out/showroom/index.html +1 -1
  258. package/apps/pwa/out/showroom/index.txt +21 -21
  259. package/apps/pwa/out/tasks/index.html +1 -1
  260. package/apps/pwa/out/tasks/index.txt +22 -22
  261. package/apps/pwa/out/term/index.html +1 -1
  262. package/apps/pwa/out/term/index.txt +22 -22
  263. package/apps/pwa/out/today/index.html +1 -1
  264. package/apps/pwa/out/today/index.txt +22 -22
  265. package/apps/pwa/out/trace/index.html +1 -1
  266. package/apps/pwa/out/trace/index.txt +22 -22
  267. package/apps/pwa/out/vault/index.html +1 -1
  268. package/apps/pwa/out/vault/index.txt +22 -22
  269. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  270. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  271. package/apps/pwa/out/workflows/index.html +1 -1
  272. package/apps/pwa/out/workflows/index.txt +22 -22
  273. package/apps/pwa/out/workspace/index.html +1 -1
  274. package/apps/pwa/out/workspace/index.txt +22 -22
  275. package/apps/pwa/out/worktrees/index.html +1 -1
  276. package/apps/pwa/out/worktrees/index.txt +22 -22
  277. package/bin/elanous.mjs +9 -2
  278. package/docs/goal-context/README.md +1 -0
  279. package/graphs/default-loop.yaml +20 -3
  280. package/graphs/document-loop.yaml +21 -2
  281. package/graphs/implement-loop.yaml +6 -0
  282. package/graphs/journey/SCENARIOS.md +33 -0
  283. package/graphs/journey/recipes.yaml +1 -0
  284. package/graphs/journey/ta-journey.yaml +84 -0
  285. package/graphs/journey/units/author/author.yaml +20 -0
  286. package/graphs/journey/units/author/recipes.yaml +2 -0
  287. package/graphs/journey/units/green/green.yaml +20 -0
  288. package/graphs/journey/units/green/recipes.yaml +2 -0
  289. package/graphs/journey/units/pr/pr.yaml +20 -0
  290. package/graphs/journey/units/pr/recipes.yaml +2 -0
  291. package/graphs/journey/units/remember/recipes.yaml +2 -0
  292. package/graphs/journey/units/remember/remember.yaml +20 -0
  293. package/graphs/operate-loop.yaml +21 -2
  294. package/graphs/overlays/stop-heal-ladder.yaml +1 -1
  295. package/graphs/release-rehearsal/recipes.yaml +1 -1
  296. package/graphs/release-rehearsal/release-rehearsal.yaml +2 -2
  297. package/graphs/research-loop.yaml +23 -2
  298. package/graphs/units/dispatch-pod/dispatch-pod.yaml +50 -0
  299. package/graphs/units/dispatch-pod/recipes.yaml +14 -0
  300. package/graphs/units/entry/entry.yaml +50 -0
  301. package/graphs/units/entry/recipes.yaml +14 -0
  302. package/graphs/units/harvest/harvest.yaml +25 -0
  303. package/graphs/units/harvest/recipes.yaml +4 -0
  304. package/graphs/units/land/land.yaml +45 -0
  305. package/graphs/units/land/recipes.yaml +3 -0
  306. package/graphs/units/recipes.yaml +7 -0
  307. package/graphs/units/recover.yaml +39 -0
  308. package/graphs/units/reflect/recipes.yaml +3 -0
  309. package/graphs/units/reflect/reflect.yaml +15 -0
  310. package/graphs/units/task-agent-recover-review.yaml +17 -0
  311. package/graphs/units/task-agent-recover-wait.yaml +17 -0
  312. package/graphs/units/verbs/make-doc.yaml +34 -0
  313. package/graphs/units/verbs/recipes.yaml +33 -0
  314. package/graphs/units/verbs/verify.yaml +55 -0
  315. package/graphs/work/recipes.yaml +2 -0
  316. package/graphs/work/research-report.yaml +28 -0
  317. package/package.json +1 -1
  318. package/scripts/ci-typecheck-changed.ts +69 -16
  319. package/scripts/docs/generate-graph-anatomy.ts +19 -2
  320. package/scripts/graph-harvest-unit.ts +22 -0
  321. package/scripts/graph-units/journey-stub.ts +6 -0
  322. package/scripts/graph-units/land-enqueue.ts +78 -0
  323. package/scripts/graph-units/recover-plan.ts +15 -0
  324. package/scripts/graph-units/reflect-node.ts +88 -0
  325. package/scripts/graph-units/ta-journey-observe.ts +109 -0
  326. package/scripts/graph-units/verbs/headless-goal-loop.ts +152 -0
  327. package/scripts/graph-units/verbs/verify-stage.ts +75 -0
  328. package/scripts/graph-units/verbs-envelope.ts +139 -0
  329. package/scripts/hq/standby-snapshot.ts +25 -0
  330. package/scripts/public-export.ts +43 -1
  331. package/scripts/ratchets/train-side-invariants.sh +45 -0
  332. package/scripts/release-loop/auto-approve-node.ts +30 -16
  333. package/scripts/release-loop/gate-closure.ts +5 -1
  334. package/scripts/release-loop/gate-diff.ts +1 -1
  335. package/scripts/release-loop/gate-node.ts +498 -31
  336. package/scripts/release-loop/gate-partial.ts +3 -3
  337. package/scripts/release-loop/gate-radius-shadow.ts +138 -0
  338. package/scripts/release-loop/gate-traffic-mode.ts +128 -0
  339. package/scripts/release-loop/gate-triage-node.ts +5 -2
  340. package/scripts/release-loop/known-issues-0.2.33-approved.json +194 -0
  341. package/scripts/release-loop/known-issues-node.ts +77 -8
  342. package/scripts/release-loop/preflight.ts +93 -7
  343. package/scripts/release-loop/publish-node.ts +60 -9
  344. package/scripts/release-loop/resume-cap.ts +56 -0
  345. package/scripts/release-loop/resume-release.ts +114 -15
  346. package/scripts/release-loop/resume.ts +24 -1
  347. package/scripts/release-loop/tui-sim-node.ts +8 -2
  348. package/scripts/release-loop/unattended-release.ts +8 -2
  349. package/src/acp/core-turn-bridge.ts +20 -5
  350. package/src/acp/reasoning-thought-buffer.ts +45 -0
  351. package/src/agent-substrate/acp-reviewer.ts +52 -12
  352. package/src/agent-substrate/review-finding-key.ts +53 -0
  353. package/src/agent-substrate/self-review-cli.ts +126 -5
  354. package/src/ask-user-question/pending-questions.ts +1 -1
  355. package/src/autopilot/pr-manager.ts +192 -43
  356. package/src/chat/tool-render/dispatch.ts +62 -10
  357. package/src/cli/control-cli.ts +24 -7
  358. package/src/cli/guardian-cli.ts +10 -0
  359. package/src/cli/light-entry-route.ts +35 -0
  360. package/src/cli/llm-detect-cli.ts +23 -1
  361. package/src/cli/pr-cli.ts +76 -12
  362. package/src/cli/pr-land-base-read.ts +2 -0
  363. package/src/cli/pr-land-overlap-evidence.ts +154 -16
  364. package/src/cli/pr-land-recovery.ts +64 -0
  365. package/src/cli/pty-takeover-cli.ts +6 -5
  366. package/src/cli/release-cli.ts +120 -33
  367. package/src/cli/release-run-if-ready.ts +29 -28
  368. package/src/cli/release-single-flight.ts +178 -0
  369. package/src/cli/seat-cli.ts +37 -0
  370. package/src/cli/setup-cli.ts +40 -1
  371. package/src/cli/tasks-cli.ts +149 -5
  372. package/src/control/control-status.ts +8 -3
  373. package/src/control-plane/ledger.ts +5 -3
  374. package/src/control-plane/server.ts +5 -3
  375. package/src/core-turn/short-question.ts +5 -1
  376. package/src/dashboard/index.ts +36 -67
  377. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +3 -0
  378. package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
  379. package/src/dashboard/input/seat-autowake.ts +56 -3
  380. package/src/dashboard/seat-boot-preamble.ts +1 -1
  381. package/src/dashboard/slash-runtime/ask-clarification.ts +48 -0
  382. package/src/dashboard/slash-runtime/dashboard-delegated-slashes.ts +68 -0
  383. package/src/dashboard/slash-runtime/dashboard-handlers.ts +62 -322
  384. package/src/dashboard/slash-runtime/dashboard-log-slash.ts +208 -0
  385. package/src/dashboard/turn-preamble.ts +47 -1
  386. package/src/dashboard/turn-stream-formatter.ts +34 -1
  387. package/src/dashboard/turn-stream-runtime.ts +2 -0
  388. package/src/dashboard/turn-typeahead-prompt-zone.ts +67 -0
  389. package/src/domains/guardian-tick.ts +54 -2
  390. package/src/domains/outbound-alert.ts +3 -2
  391. package/src/extractors.ts +3 -1
  392. package/src/git-fs/retry.ts +4 -0
  393. package/src/git-fs/runner.ts +2 -0
  394. package/src/graph-runner/runner.ts +114 -44
  395. package/src/grok/credential.ts +5 -0
  396. package/src/harness/harness-cli-command.ts +39 -10
  397. package/src/harness/harness-incidents.ts +4 -0
  398. package/src/harness/harness-pod-dispatch.ts +38 -1
  399. package/src/harness/harness-salvage-cli.ts +14 -2
  400. package/src/index.ts +192 -8
  401. package/src/intake-plane/already-built-hint.ts +89 -0
  402. package/src/knowhow/pack.ts +199 -0
  403. package/src/light-cli.ts +95 -0
  404. package/src/llm.ts +55 -9
  405. package/src/loops/budget.ts +95 -0
  406. package/src/loops/msg-wake.ts +8 -2
  407. package/src/loops/orchestrator/traffic.ts +132 -1
  408. package/src/mss/logging/log-store.ts +4 -5
  409. package/src/nexus/api/graphs-api.ts +22 -3
  410. package/src/nexus/api/http-server.ts +1 -1
  411. package/src/nexus/api/ops-api.ts +12 -0
  412. package/src/oauth/claude-pty-maturity.ts +66 -0
  413. package/src/oauth/codex-access-mirror.ts +55 -0
  414. package/src/oauth/fallback-chain.ts +1 -1
  415. package/src/onboarding/first-run.ts +5 -3
  416. package/src/onboarding/non-interactive.ts +64 -13
  417. package/src/onboarding.ts +10 -2
  418. package/src/ops/overview-collect.ts +36 -1
  419. package/src/ops/overview.ts +11 -0
  420. package/src/pr-tool/census.ts +23 -5
  421. package/src/pr-tool/inflight-registry.ts +160 -7
  422. package/src/prompt-library/gpt6-family-addendum.ts +14 -1
  423. package/src/pty-shell/herdr-agent-report.ts +442 -0
  424. package/src/pty-shell/pty-control-ipc.ts +5 -5
  425. package/src/pty-shell/pty-write-outcome.ts +24 -6
  426. package/src/pty-shell/tui-run-state.ts +117 -3
  427. package/src/release-loop/checklist.ts +79 -5
  428. package/src/release-loop/feature-store.ts +19 -2
  429. package/src/release-loop/placement.ts +10 -3
  430. package/src/release-loop/rehearsal.ts +205 -25
  431. package/src/release-loop/rubric.ts +16 -2
  432. package/src/self-dev/draft-sweep.ts +52 -3
  433. package/src/self-dev/graph-journey-nodes.ts +10 -6
  434. package/src/self-dev/graph-journey-route.ts +60 -6
  435. package/src/self-dev/orchestrate.ts +79 -3
  436. package/src/self-dev/run-supervisor.ts +107 -12
  437. package/src/self-dev/run-types.ts +5 -1
  438. package/src/self-implement/gate-baseline.ts +49 -5
  439. package/src/self-implement/gate-remote.ts +9 -5
  440. package/src/self-implement/goal-author-identity.ts +66 -0
  441. package/src/self-implement/goal-author-preservation-obligation.ts +35 -0
  442. package/src/self-implement/goal-author.ts +4 -120
  443. package/src/self-implement/graph-overlay-yaml.ts +17 -2
  444. package/src/self-implement/graph-unit-flatten.ts +103 -0
  445. package/src/self-implement/graph-unit-resolver.ts +107 -0
  446. package/src/self-implement/graph-yaml.ts +151 -1
  447. package/src/self-implement/headless-elanous-driver.ts +1 -0
  448. package/src/self-implement/knowhow-pack.ts +103 -0
  449. package/src/self-implement/orchestrator.ts +8 -0
  450. package/src/self-implement/pod-warm-pool-profile.ts +45 -0
  451. package/src/self-implement/review-mustfix-class.ts +203 -0
  452. package/src/self-implement/run-stop.ts +8 -2
  453. package/src/self-implement/seams.ts +32 -1
  454. package/src/self-implement/stop-autoheal.ts +25 -1
  455. package/src/session/chat.ts +27 -0
  456. package/src/session-runtime/retry-policy.ts +2 -1
  457. package/src/skills/tools/schedule-wakeup.ts +66 -17
  458. package/src/steward/release-day.ts +7 -3
  459. package/src/steward/triage.ts +37 -4
  460. package/src/task-agent/harvest-unit.ts +141 -0
  461. package/src/task-agent/live-moves.ts +98 -12
  462. package/src/task-agent/parent-host.ts +93 -3
  463. package/src/task-agent/postland-card.ts +80 -1
  464. package/src/task-agent/rejudge-on-head.ts +112 -26
  465. package/src/task-agent/repair-branch-cas.ts +4 -1
  466. package/src/task-agent/repair-cycle.ts +16 -3
  467. package/src/task-agent/run-identity.ts +4 -3
  468. package/src/task-agent/shadow.ts +12 -2
  469. package/src/task-agent/task-hand.ts +54 -7
  470. package/src/task-agent/work-order-build.ts +22 -0
  471. package/src/task-orchestrator/surfaces/pod-account-broker.ts +39 -3
  472. package/src/task-orchestrator/surfaces/pod-command-job.ts +2 -1
  473. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +86 -8
  474. package/src/task-orchestrator/surfaces/pod-pool.ts +73 -17
  475. package/src/task-orchestrator/surfaces/pod-source-receive.ts +54 -4
  476. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +26 -3
  477. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +389 -0
  478. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +2 -1
  479. package/src/task-orchestrator/surfaces/self-implement-pod.ts +223 -38
  480. package/src/task-orchestrator/surfaces/self-implement.ts +83 -2
  481. package/src/tool-runtime/truncation-store.ts +4 -0
  482. package/src/tui-client/dashboard-session.ts +10 -1
  483. package/src/user-config/coercion.ts +36 -0
  484. package/src/user-config.ts +18 -41
  485. package/src/ux-sim/scenario.ts +72 -13
  486. package/src/version/packed-revision.json +1 -1
  487. package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +0 -27
  490. package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +0 -287
  491. package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +0 -62
  492. package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +0 -1
  493. package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +0 -1
  494. package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/1654.32de4b324981a188.js +0 -23
  496. package/apps/pwa/out/_next/static/chunks/1834-98b64172bc1efe77.js +0 -1
  497. package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +0 -149
  498. package/apps/pwa/out/_next/static/chunks/1913.7cc6fb6055b1ed3f.js +0 -41
  499. package/apps/pwa/out/_next/static/chunks/2001.6c7e0fd02190886c.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +0 -1
  504. package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +0 -115
  506. package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +0 -64
  507. package/apps/pwa/out/_next/static/chunks/3267c0e6.d34854e7b3984a6e.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/3902.e1e71aaac850a045.js +0 -34
  510. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/4111.2bfedbb233ad206b.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +0 -36
  514. package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +0 -1
  515. package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +0 -1
  517. package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +0 -286
  518. package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +0 -77
  519. package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +0 -1
  520. package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +0 -79
  521. package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +0 -1
  522. package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +0 -1
  523. package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +0 -148
  524. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +0 -1
  525. package/apps/pwa/out/_next/static/chunks/5458-16cd7a2b51b74c8c.js +0 -1
  526. package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +0 -1
  527. package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +0 -74
  529. package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +0 -1
  530. package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +0 -94
  531. package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +0 -1
  533. package/apps/pwa/out/_next/static/chunks/60fb96c9.360b01d8d4927b7b.js +0 -1
  534. package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +0 -90
  538. package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +0 -32
  539. package/apps/pwa/out/_next/static/chunks/6544cb48.a87fe20ddf137be2.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +0 -104
  541. package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +0 -24
  546. package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +0 -93
  547. package/apps/pwa/out/_next/static/chunks/69-0a2c8209c6d4a158.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +0 -8
  555. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/8097-9530c03bcc550f02.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/9138.b6e80031afb1d973.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/9279-d28c5b7754d010ae.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/app/approvals/page-504204b58c82c253.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a9717a67c2eecbaf.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/app/board/page-5c9ec30aee62dfbf.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/app/botlab/page-584191533721fa16.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/app/bots/page-73c4b4bb3ac7ab5f.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c0f1ca371f710b06.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/app/chat/page-46430d45a9e04eac.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/app/consult/page-3b2ebf1dc64ff0be.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/app/control/page-a27b1e5a0d1b308f.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/app/decisions/page-25654b82094f7d22.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8ea49a4c6dd2c6e7.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/app/editor/page-ce5113aefea0a8d1.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/app/exec/page-0e5a41fac1c75396.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/app/field/page-31aaf1ed37c6df9a.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/app/inside/page-3dcc1fa411e1f4e0.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/app/intake/page-c69247e7134d329d.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/app/layout-66dc5cd3a0999abe.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/app/live/page-26ff7ff651a7217d.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/app/live-run/page-617b3976981efa96.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/app/loops/page-d256f5d5d9552823.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/app/market/page-ce8f1907b8a6101c.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-33e182a316263116.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/app/morning/page-32866485913d6a04.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/app/not-found-7607cca9b84950c6.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eeab86176b03dc3b.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5b93dbae3432b996.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-77a6cb90a9cf2b10.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f47e768b5b242b5a.js +0 -1
  605. package/apps/pwa/out/_next/static/chunks/app/outputs/page-eb41aa3367fc2505.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/app/page-4d13ab0b8a267e3f.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/app/reflection/page-84dad32ff0fc0831.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-95306f892aa2d0ee.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/app/sessions/page-940fb6c217f6b470.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/app/settings/page-7b675dfd35c36fc9.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8bd0d3cf7665bcfc.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/app/setup/page-c219f2ed171131be.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/app/share/page-40f8fa21bdae955b.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/app/showroom/page-468f8313e4f1fbd9.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/app/tasks/page-7bbb8fa353a246c4.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/app/today/page-4214b855d9233ea8.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/app/trace/page-936752c7aa58762e.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/app/vault/page-ec052ad359df1797.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8305570551091338.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/app/workflows/page-fad650e4793adb65.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/app/workspace/page-d90e64743826e1d8.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a16bcfd49af86a32.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +0 -122
  625. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +0 -1
  632. package/src/cli/g6a-registration-probe.ts +0 -16
  633. /package/apps/pwa/out/_next/static/{IVKr3AlRUVLKsw2fh7eXF → L04y73dlwKeTW-GetaTF3}/_ssgManifest.js +0 -0
@@ -29,10 +29,13 @@
29
29
  * - 관측: `task-agent` · `rejudge-on-head {card, pr, fromHead, toHead, step, decision, reason}` — 수가 난 판단은 카드 history 에도
30
30
  * 한 줄(`event:'rejudge-on-head'` · 같은 머리·같은 단계·같은 판단은 한 번).
31
31
  */
32
- import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
32
+ import { closeSync, mkdirSync, openSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
33
+ import { randomUUID } from 'node:crypto';
33
34
  import { spawn, spawnSync } from 'node:child_process';
34
35
  import { tmpdir } from 'node:os';
35
36
  import { dirname, join } from 'node:path';
37
+ import { planPrLandRecovery, type PrLandRecoveryPlan } from '../cli/pr-land-recovery.js';
38
+ import { lastJsonObject, runGraph } from '../graph-runner/runner.js';
36
39
  import { debug } from '../debug/log.js';
37
40
  import { prodInstanceRoot } from '../instance/resolve.js';
38
41
  import { getUserConfig } from '../user-config.js';
@@ -44,7 +47,7 @@ import { recordLiveMoveHistory } from './live-move-history.js';
44
47
  import { runRepairCycle, type RepairLaunchRequest } from './repair-cycle.js';
45
48
  import { repairMustFixFromReview, repairReviewDigest } from './repair-review.js';
46
49
  import type { RepairCasOutcome, RepairCasRequest } from './repair-branch-cas.js';
47
- import { defaultLandPrHead, defaultPrHead, defaultReviewRepoCandidates, executeLiveLand, executeLiveReview, landRetryPending, type LiveMoveDeps, type LiveMoveResult, type PrHeadView, type ReviewRepoCandidate, type TaskAgentLiveMove } from './live-moves.js';
50
+ import { configuredMsb1Worker, defaultLandPrHead, defaultPrHead, defaultReviewRepoCandidates, executeLiveLand, executeLiveReview, landRetryPending, remoteTaWorkerCommand, type LiveMoveDeps, type LiveMoveResult, type PrHeadView, type ReviewRepoCandidate, type TaskAgentLiveMove } from './live-moves.js';
48
51
  import { capturedLandReview, captureReviewResults, parseReviewResultOutput, pendingReviewResults, reviewResultPath, type ParsedReviewResult } from './review-result-capture.js';
49
52
  import { boundPrTerminal, cardPrNumber, LIVE_MOVE_RESULT_EVENT, readTaskCard, taskAgentStatePath, updateTaskCard, type TaskCard } from './task-hand.js';
50
53
  import { verifiedTrainLanding, type TrainLanding } from './train-landing.js';
@@ -98,6 +101,10 @@ export interface RejudgeDeps {
98
101
  notifyRepair?: (seat: string, body: string) => void;
99
102
  /** Shared new-launch budget for this `tasks rejudge --all` call. */
100
103
  repairBudget?: import('./repair-cycle.js').RepairTickBudget;
104
+ /** One review request across all candidates in one --all tick; standalone card rejudge is uncapped. */
105
+ reviewBudget?: { max: number; requested: number };
106
+ /** One land or queue attempt across all candidates in one --all tick. */
107
+ landBudget?: { max: number; requested: number };
101
108
  /** TA-REJUDGE-REBASE-LOOP — origin/main 을 PR 가지에 3-way merge 하고 일반 push. 시험은 주입한다. */
102
109
  catchUpMain?: (request: CatchUpRequest) => Promise<CatchUpResult>;
103
110
  log?: (category: string, event: string, data: Record<string, unknown>) => void;
@@ -265,12 +272,28 @@ export function regateRunArgs(entry: string, configDir: string, request: RegateR
265
272
  return [entry, '--config-dir', configDir, 'tasks', 'regate-run', '--card', request.card, '--pr', String(request.pr), '--head', request.head, '--repo', request.repoRoot, '--out', request.resultPath];
266
273
  }
267
274
 
268
- export async function defaultRequestRegate(request: RegateRequest, opts: { spawn?: DetachedSpawn; entry?: string; configDir?: string } = {}): Promise<void> {
275
+ export async function defaultRequestRegate(request: RegateRequest, opts: { spawn?: DetachedSpawn; entry?: string; configDir?: string; remote?: import('./parent-host.js').ParentHostConfig | null } = {}): Promise<void> {
269
276
  const { spawnDetachedConfirmed, ELANOUS_CLI_ENTRY } = await import('../cli/tasks-cli.js');
270
277
  const { getElanousConfigDirOverride } = await import('../elanous-config-dir.js');
271
278
  const { effectiveInstanceRoot } = await import('../instance/resolve.js');
272
279
  const configDir = opts.configDir ?? getElanousConfigDirOverride() ?? effectiveInstanceRoot();
273
- await spawnDetachedConfirmed(opts.spawn ?? (spawn as unknown as DetachedSpawn), process.execPath, regateRunArgs(opts.entry ?? ELANOUS_CLI_ENTRY, configDir, request), undefined, request.repoRoot);
280
+ const base = opts.spawn ?? (spawn as unknown as DetachedSpawn);
281
+ const remote = opts.remote === undefined ? (opts.spawn ? null : configuredMsb1Worker()) : opts.remote;
282
+ if (!remote) {
283
+ await spawnDetachedConfirmed(base, process.execPath, regateRunArgs(opts.entry ?? ELANOUS_CLI_ENTRY, configDir, request), undefined, request.repoRoot);
284
+ return;
285
+ }
286
+ // The remote worker writes its own result, then SSH carries only that JSON into the HQ result path.
287
+ const remoteResult = `/tmp/elanous-ta-regate-${randomUUID()}.json`;
288
+ const script = `${remoteTaWorkerCommand(remote, ['tasks', 'regate-run', '--card', request.card, '--pr', String(request.pr),
289
+ '--head', request.head, '--repo', remote.cwd, '--out', remoteResult])} >/dev/null; rc=$?; cat '${remoteResult}'; rm -f '${remoteResult}'; exit $rc`;
290
+ mkdirSync(dirname(request.resultPath), { recursive: true });
291
+ const fd = openSync(request.resultPath, 'w');
292
+ const toFile: DetachedSpawn = (command, args, options) =>
293
+ (base as unknown as (c: string, a: string[], o: unknown) => ReturnType<DetachedSpawn>)(command, args, { ...options, stdio: ['ignore', fd, 'ignore'] });
294
+ try {
295
+ await spawnDetachedConfirmed(toFile, 'ssh', ['-T', '-o', 'BatchMode=yes', '-o', 'ConnectTimeout=5', remote.host, script]);
296
+ } finally { closeSync(fd); }
274
297
  }
275
298
 
276
299
  /** 재게이트 결과 파일 — `tasks regate-run` 이 쓴다. */
@@ -513,6 +536,19 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
513
536
  }
514
537
  const step = (s: RejudgeStep, decision: string, reason: string, record: boolean, extra: Partial<RejudgeOutcome> = {}) =>
515
538
  emit({ card: card!.id, pr, fromHead, toHead, step: s, decision, reason, ...extra }, record);
539
+ const requestReview = async (candidate: TaskCard, reason: string, forceNewReview = false): Promise<void> => {
540
+ const budget = deps.reviewBudget;
541
+ if (budget && budget.requested >= budget.max) {
542
+ step('review', 'tick-cap', `review request cap ${budget.max} reached — next tick`, false);
543
+ return;
544
+ }
545
+ // Reserve before awaiting the worker so another candidate cannot launch a second request.
546
+ if (budget) budget.requested++;
547
+ const before = { reviewRequests: candidate.reviewRequests, landAttempts: candidate.landAttempts };
548
+ const result = await executeLiveReview(candidate, pr, { runId: candidate.runId ?? null, stopReason: reason, cwd, forceNewReview }, { ...live, ...(deps.log ? { log: deps.log } : {}) });
549
+ recordMove(statePath, candidate.id, candidate.runId, 'review', result, pr, before, now, deps.log);
550
+ step('review', result.executed ? 'review-requested' : 'review-request-failed', result.detail, true);
551
+ };
516
552
 
517
553
  // Adoption is a first judgement for the current head, even when the implementation run
518
554
  // already asked for a review. A captured failure needs repair; an accepted result must
@@ -526,10 +562,7 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
526
562
  } else if (!deps.liveMoves.has('review')) {
527
563
  step('review', 'would-review', 'adopted PR first judgement · review not enabled in HQ taskAgent.liveMoves — shadow', false);
528
564
  } else {
529
- const before = { reviewRequests: card.reviewRequests, landAttempts: card.landAttempts };
530
- const result = await executeLiveReview(card, pr, { runId: card.runId ?? null, stopReason: 'adopted-pr-first-judgement', cwd }, { ...live, ...(deps.log ? { log: deps.log } : {}) });
531
- recordMove(statePath, card.id, card.runId, 'review', result, pr, before, now, deps.log);
532
- step('review', result.executed ? 'review-requested' : 'review-request-failed', result.detail, true);
565
+ await requestReview(card, 'adopted-pr-first-judgement');
533
566
  }
534
567
  return outcomes;
535
568
  }
@@ -618,12 +651,7 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
618
651
 
619
652
  if (!reviews.length) {
620
653
  if (!deps.liveMoves.has('review')) step('review', 'would-review', 'remote run terminal proven · review not enabled in HQ taskAgent.liveMoves — shadow', false);
621
- else {
622
- const before = { reviewRequests: card.reviewRequests, landAttempts: card.landAttempts };
623
- const result = await executeLiveReview(card, pr, { runId: card.runId ?? null, stopReason: 'remote-run-terminal', cwd }, { ...live, ...(deps.log ? { log: deps.log } : {}) });
624
- recordMove(statePath, card.id, card.runId, 'review', result, pr, before, now, deps.log);
625
- step('review', result.executed ? 'review-requested' : 'review-request-failed', result.detail, true);
626
- }
654
+ else await requestReview(card, 'remote-run-terminal');
627
655
  return outcomes;
628
656
  }
629
657
 
@@ -642,10 +670,7 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
642
670
  if (pendingReviewResults(latest).some((entry) => entry.pr === pr && sameHead(entry.head, toHead))) {
643
671
  step('review', 'awaiting-review-result', 'exact-head review result pending', false);
644
672
  } else if (!latest.reviewRequests?.some((entry) => entry.pr === pr && sameHead(entry.head, toHead)) && deps.liveMoves.has('review')) {
645
- const before = { reviewRequests: latest.reviewRequests, landAttempts: latest.landAttempts };
646
- const result = await executeLiveReview(latest, pr, { runId: latest.runId ?? null, stopReason: 'queue-exact-head', cwd }, { ...live, ...(deps.log ? { log: deps.log } : {}) });
647
- recordMove(statePath, latest.id, latest.runId, 'review', result, pr, before, now, deps.log);
648
- step('review', result.executed ? 'review-requested' : 'review-request-failed', result.detail, true);
673
+ await requestReview(latest, 'queue-exact-head');
649
674
  } else step('review', 'not-landing', 'exact-head PASS/WARN mf0 review not captured', true);
650
675
  return outcomes;
651
676
  }
@@ -654,8 +679,13 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
654
679
  const reviewResult = latest.reviewRequests?.find((entry) => entry.pr === pr && sameHead(entry.head, toHead) && entry.resultPath)?.resultPath;
655
680
  if (!reviewResult) { step('land', 'not-landing', 'exact-head review JSON path missing', true); return outcomes; }
656
681
  const before = { reviewRequests: latest.reviewRequests, landAttempts: latest.landAttempts };
682
+ if (deps.landBudget && deps.landBudget.requested >= deps.landBudget.max) {
683
+ step('land', 'tick-cap', `land attempt cap ${deps.landBudget.max} reached — next tick`, false);
684
+ return outcomes;
685
+ }
657
686
  const queued = await executeLiveLand(latest, pr, { runId: latest.runId ?? null, cycleId: `queue:${latest.id}:${toHead}`, cwd,
658
687
  review, reviewResultPath: reviewResult }, { ...live, landQueueConfig: queueMode, ...(deps.log ? { log: deps.log } : {}) });
688
+ if (deps.landBudget && queued.executed) deps.landBudget.requested++;
659
689
  recordMove(statePath, latest.id, latest.runId, 'propose-land', queued, pr, before, now, deps.log);
660
690
  step('land', queued.queued ? 'queued' : queued.ok && !queued.executed ? 'queue-skipped' : 'queue-refused', queued.detail, true);
661
691
  return outcomes;
@@ -778,12 +808,7 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
778
808
  // ② 리뷰 — 지금 머리로 요청한 적이 없으면 다시(같은 머리는 한 번 · 상한은 ① 의 머리 수가 이미 막았다).
779
809
  if (!reviews.some((entry) => sameHead(entry.head, toHead))) {
780
810
  if (!deps.liveMoves.has('review')) step('review', 'would-review', 'review not enabled in taskAgent.liveMoves — shadow', false);
781
- else {
782
- const before = { reviewRequests: card.reviewRequests, landAttempts: card.landAttempts };
783
- const result = await executeLiveReview(card, pr, { runId: card.runId ?? null, stopReason: 'rejudge-on-head', cwd }, { ...live, ...(deps.log ? { log: deps.log } : {}) });
784
- recordMove(statePath, card.id, card.runId, 'review', result, pr, before, now, deps.log);
785
- step('review', result.executed ? 'review-requested' : 'review-request-failed', result.detail, true);
786
- }
811
+ else await requestReview(card, 'rejudge-on-head');
787
812
  return outcomes;
788
813
  }
789
814
  const latest = readTaskCard(card.id, statePath) ?? card;
@@ -828,10 +853,15 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
828
853
  return outcomes;
829
854
  }
830
855
  const before = { reviewRequests: latest.reviewRequests, landAttempts: latest.landAttempts };
856
+ if (deps.landBudget && deps.landBudget.requested >= deps.landBudget.max) {
857
+ step('land', 'tick-cap', `land attempt cap ${deps.landBudget.max} reached — next tick`, false);
858
+ return outcomes;
859
+ }
831
860
  // 주기 id — base-stale 재게이트 뒤의 land 는 새 base 를 붙여 앞 land 의 주기 표시(모듈 전역)와 갈린다 · gateAt 이 앞 base-stale 시도를 소비한다.
832
861
  const cycleId = `rejudge:${card.id}:${toHead}${regate.staleBase ? `:${regate.baseCommit.slice(0, 12)}` : ''}`;
833
862
  const landed = await executeLiveLand(latest, pr, { runId: card.runId ?? null, cycleId, cwd, review, reviewResultPath: reviewResult, overlapEvidence, gateAt: regate.at },
834
863
  { ...live, ...(deps.log ? { log: deps.log } : {}) });
864
+ if (deps.landBudget && landed.executed) deps.landBudget.requested++;
835
865
  // LAND-ORDER-LEDGER — executeLiveLand 직후 원장 한 줄(같은 pr+head 는 한 줄만). 쓰기가 실패해도 land 결과는 그대로(삼킨다).
836
866
  const landOrderLog = (event: 'appended' | 'append-failed') => { try { log('task-agent.land-order', event, { pr, head: toHead }); } catch { /* fail-soft */ } };
837
867
  try {
@@ -844,6 +874,38 @@ export async function rejudgeCardOnHead(cardId: string, deps: RejudgeDeps): Prom
844
874
  landOrderLog('append-failed');
845
875
  }
846
876
  recordMove(statePath, card.id, card.runId, 'propose-land', landed, pr, before, now, deps.log);
877
+ if (landed.executed && !landed.ok && /^✗/.test(landed.detail)) {
878
+ const context = { refusal: landed.detail, pr, head: toHead };
879
+ const preliminary = planPrLandRecovery(context);
880
+ if (preliminary.result.action === 'request-review' || preliminary.result.action === 'wait-retry') {
881
+ const entry = preliminary.result.action;
882
+ try {
883
+ const graphPath = entry === 'request-review' ? '../../graphs/units/task-agent-recover-review.yaml' : '../../graphs/units/task-agent-recover-wait.yaml';
884
+ const graph = await runGraph(join(import.meta.dir, graphPath), {
885
+ input: { ask: `TA land refusal for PR #${pr}`, context, prior: {} },
886
+ pinChildUniverse: true,
887
+ deps: { root: dirname(statePath) },
888
+ });
889
+ const output = lastJsonObject(graph.nodes.find((node) => node.nodeId === 'recover')?.output);
890
+ const plan = graph.status === 'done' && graph.unitCalls?.[0]?.entry === entry
891
+ && graph.unitCalls[0].exit === 'rework' ? output as unknown as PrLandRecoveryPlan | undefined : undefined;
892
+ const action = plan?.result?.action;
893
+ const matched = plan?.outcome === 'rework' && plan.result.pr === pr && plan.result.head === toHead
894
+ && action === preliminary.result.action && plan.evidence?.refusal === context.refusal.slice(0, 500)
895
+ && (action !== 'wait-retry' || plan.result.delayMs === 30_000);
896
+ if (!matched) step('land', 'recover-untrusted', `recover@1 ${entry} produced no pinned matching action`, true);
897
+ else if (action === 'request-review' && deps.liveMoves.has('review')) {
898
+ await requestReview(readTaskCard(card.id, statePath) ?? card, 'land-refusal-review-missing', true);
899
+ } else if (action === 'request-review') {
900
+ step('review', 'recover-review-disabled', 'recover@1 selected review but taskAgent.liveMoves excludes review', true);
901
+ } else if (action === 'wait-retry') {
902
+ step('land', 'recover-wait-retry', `recover@1 ${entry} selected existing retry admission after ${plan.result.delayMs}ms`, true);
903
+ } else step('land', 'recover-needs-human', `recover@1 ${entry}: ${plan.result.reason}`, true);
904
+ } catch (error) {
905
+ step('land', 'recover-failed', `recover@1 ${entry}: ${String(error).slice(0, 200)}`, true);
906
+ }
907
+ }
908
+ }
847
909
  // TA-LAND-RETRY-ON-INFRA — 실패한 시도는 갈래·사유·재시도 여부를 사유 줄에 싣는다(다음 틱이 왜 다시 하는지/안 하는지).
848
910
  const attempt = landed.landAttempt?.class
849
911
  ? ` · land-class ${landed.landAttempt.class} (${landed.landAttempt.reason}) · attempt ${landed.landAttempt.attempt} · ${landed.landAttempt.class === 'base-stale' ? 'base-stale → re-gate on a new base next tick (cap counts)' : landed.landAttempt.retryAllowed ? 'retry allowed on this head' : 'no retry on this head'}`
@@ -862,11 +924,35 @@ function recordMove(statePath: string, cardId: string, runId: string | undefined
862
924
  }
863
925
 
864
926
  /** 재판정 대상 카드 — 기존 리뷰 또는 HQ 가 종결 원장을 검증할 원격 부모 카드. */
865
- export function rejudgeCandidates(tasks: Readonly<Record<string, TaskCard>>): string[] {
927
+ export function rejudgeCandidates(tasks: Readonly<Record<string, TaskCard>>, opts: {
928
+ now?: Date; maxAgeHours?: number; onAgeSkip?: (card: TaskCard, ageHours: number | null) => void;
929
+ /** Fresh remote PR heads; mf0 only gets priority when it matches this head. */
930
+ currentHeads?: ReadonlyMap<string, string>;
931
+ } = {}): string[] {
932
+ const now = opts.now?.getTime() ?? Date.now();
933
+ const maxAgeHours = opts.maxAgeHours;
866
934
  return Object.values(tasks).filter((card) => {
867
935
  const pr = cardPrNumber(card);
868
- return pr !== undefined && !boundPrTerminal(card) && ((card.reviewRequests ?? []).some((entry) => entry.pr === pr)
936
+ const eligible = pr !== undefined && !boundPrTerminal(card) && ((card.reviewRequests ?? []).some((entry) => entry.pr === pr)
869
937
  || (card.status === 'launched' && card.taLand === true && ((!!card.parentHost && !!card.runId && !!card.runChildId)
870
938
  || (card.adoptedPr?.pr === pr && typeof card.pr === 'object' && !!card.pr.url && sameUrl(card.adoptedPr.url, card.pr.url)))));
939
+ if (!eligible) return false;
940
+ if (maxAgeHours !== undefined) {
941
+ const created = Date.parse(card.createdAt);
942
+ const ageHours = Number.isFinite(created) ? Math.max(0, (now - created) / 3_600_000) : null;
943
+ if (ageHours === null || ageHours > maxAgeHours) { opts.onAgeSkip?.(card, ageHours); return false; }
944
+ }
945
+ return true;
946
+ }).sort((a, b) => {
947
+ const hasMf0 = (card: TaskCard): number => {
948
+ const pr = cardPrNumber(card);
949
+ const head = card.reviewRequests?.filter((entry) => entry.pr === pr).at(-1)?.head;
950
+ const currentHead = opts.currentHeads?.get(card.id);
951
+ return pr !== undefined && head && currentHead?.toLowerCase() === head.toLowerCase()
952
+ && capturedLandReview(card, pr, head)?.mustFixCount === 0 ? 1 : 0;
953
+ };
954
+ const ageOrder = (Number.isFinite(Date.parse(b.createdAt)) ? Date.parse(b.createdAt) : 0)
955
+ - (Number.isFinite(Date.parse(a.createdAt)) ? Date.parse(a.createdAt) : 0);
956
+ return hasMf0(b) - hasMf0(a) || ageOrder || a.id.localeCompare(b.id);
871
957
  }).map((card) => card.id);
872
958
  }
@@ -24,7 +24,8 @@ export interface RepairCasRequest {
24
24
  result: RepairCommitResult;
25
25
  /** A previous push succeeded. Confirmation may inspect the remote and PR, but must never push again. */
26
26
  confirmationOnly?: boolean;
27
- branch?: string;
27
+ /** PR branch captured when this repair was requested. A rename cannot retarget its push. */
28
+ branch: string;
28
29
  /** Persist a single-use push intent after bundle/ancestry checks and before the push side effect. */
29
30
  claimBeforePush?: () => boolean;
30
31
  }
@@ -99,6 +100,8 @@ export function applyRepairBundle(request: RepairCasRequest, deps: RepairCasDeps
99
100
  try { bytes = readFileSync(bundlePath); } catch { return fail('repair bundle unreadable'); }
100
101
  if (createHash('sha256').update(bytes).digest('hex') !== result.bundleSha256.toLowerCase()) return fail('repair bundle sha256 mismatch');
101
102
  if (!initial || !originRepo || initial.headRepo.toLowerCase() !== originRepo) return fail('PR head repository differs from git origin');
103
+ if (!request.branch || git(['check-ref-format', '--branch', request.branch]).status !== 0) return fail('bound repair branch name invalid');
104
+ if (initial.branch !== request.branch) return fail('bound repair branch changed');
102
105
  const alreadyApplied = initial?.head.toLowerCase() === result.commit.toLowerCase();
103
106
  if (!initial || initial.state !== 'OPEN' || initial.crossRepository || (!alreadyApplied && initial.head.toLowerCase() !== expectedHead.toLowerCase()))
104
107
  return fail('PR head CAS mismatch or PR unavailable');
@@ -92,14 +92,15 @@ export async function repairModelAvailability(readInputs: () => Promise<Pick<Bud
92
92
  } catch { return { codexSubscription: false, grokSubscription: false }; }
93
93
  }
94
94
 
95
- /** Repair stays inside the dispatch tier. A missing legacy tier is high, with Sol allowed only on measured subscription quota. */
95
+ /** Repair stays inside the dispatch tier. A missing legacy tier is mid ('중'); Sol is reserved for the 특 tier and measured-subscription 상 repairs. */
96
96
  export function alternateRepairModel(card: TaskCard, availability: RepairModelAvailability = { codexSubscription: false, grokSubscription: false }): { from: string; to: TaskChildLlm } {
97
97
  const last = card.repairs?.at(-1);
98
98
  const from = last?.toModel ?? (card.childLlm ? `${card.childLlm.provider}/${card.childLlm.model}` : 'unknown');
99
99
  const glm: TaskChildLlm = { provider: 'openrouter', model: 'openrouter/z-ai/glm-5.3' };
100
100
  const sol: TaskChildLlm = { provider: 'openai-codex', model: 'gpt-6-sol' };
101
101
  const grok: TaskChildLlm = { provider: 'grok', model: 'grok-4.6' };
102
- const tier = card.tier ?? '상';
102
+ const luna: TaskChildLlm = { provider: 'openai-codex', model: 'gpt-6-luna' };
103
+ const tier = card.tier ?? '중';
103
104
  const pr = typeof card.pr === 'number' ? card.pr : card.pr?.number;
104
105
  const mixEven = ((pr ?? [...card.id].reduce((sum, ch) => sum + ch.charCodeAt(0), 0)) % 2) === 0;
105
106
  let to: TaskChildLlm;
@@ -108,6 +109,8 @@ export function alternateRepairModel(card: TaskCard, availability: RepairModelAv
108
109
  else if (tier === '상') to = availability.grokSubscription && from.includes('glm') ? grok
109
110
  : from.includes('glm-5.3-flash') ? glm
110
111
  : from.includes('glm-5.3') ? { provider: 'openrouter', model: 'openrouter/z-ai/glm-5.3-flash' } : glm;
112
+ else if (tier === '하') to = from.includes('glm-5.3-flash') ? luna : from.includes('glm-5.3')
113
+ ? { provider: 'openrouter', model: 'openrouter/z-ai/glm-5.3-flash' } : glm;
111
114
  else to = from.includes('glm-5.3-flash') ? glm : from.includes('glm-5.3')
112
115
  ? { provider: 'openrouter', model: 'openrouter/z-ai/glm-5.3-flash' } : glm;
113
116
  return { from, to };
@@ -192,7 +195,7 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
192
195
  const bundlePath = join(artifactDir, 'commit.bundle');
193
196
  let pushClaimed = false;
194
197
  applied = (input.apply ?? applyRepairBundle)({ repo, pr, expectedHead: latest.head,
195
- bundlePath, result: result.result,
198
+ bundlePath, result: result.result, branch: latest.branch,
196
199
  claimBeforePush: () => {
197
200
  let claimed = false;
198
201
  updateTaskCard(statePath, card.id, (current) => current?.repairs?.some((entry) => entry.runId === latest.runId && entry.status === 'requested')
@@ -308,6 +311,16 @@ export async function runRepairCycle(input: RepairCycleInput): Promise<RepairCyc
308
311
  ? { ...current, repairs: current.repairs.map((entry) => entry.runId === runId ? { ...entry, status: 'failed' as const, detail: reason } : entry) } : undefined);
309
312
  return { decision: 'repair-failed', reason };
310
313
  }
314
+ // The request may throw before a worker exists. A post-launch observation
315
+ // failure must not turn an accepted worker into a failed launch.
316
+ try {
317
+ updateTaskCard(statePath, card.id, (current) => current?.repairs?.some((entry) => entry.runId === runId)
318
+ && !current.history.some((entry) => entry.event === 'harness.role-llm' && entry.runId === runId)
319
+ ? { ...current, history: [...current.history, { at: now.toISOString(), event: 'harness.role-llm', pr, head, runId,
320
+ detail: `repair child model ${to.provider}/${to.model}` }] } : undefined);
321
+ } catch (error) {
322
+ try { debug.log('task-agent', 'repair-role-llm-observation-failed', { card: card.id, pr, head, runId, error: String(error) }); } catch { /* fail-soft */ }
323
+ }
311
324
  try {
312
325
  if (input.observeLaunch) input.observeLaunch(judged.judgement.move, runId);
313
326
  else {
@@ -6,7 +6,8 @@
6
6
  * 디스패처 배선은 RUN-IDENTITY-ADMIT).
7
7
  * - parse/validate: 목록 밖 값은 거부한다(조용히 다듬지 않는다).
8
8
  * - 출생 신분 자동(`deriveBirthIdentity`): 칸 우선순위(P0 = critical·special·protect ·
9
- * P1 = normal · 그 외 normal)·대표 표시에서 단다.
9
+ * P1 = normal · 그 외 normal)·대표 표시에서 단다. 권한(rights)은 명시 `--tag rights=…`만 기록한다
10
+ * (RUN-IDENTITY-RIGHTS — 체크리스트에는 권한 근거가 없으므로 출생값으로 추정하지 않는다).
10
11
  * - 태그 덮기(`applyRunIdentityTags`): `tasks hand --tag k=v`(반복) 이 출생 신분을 덮는다.
11
12
  * - ⛔ 모르는 칸을 기본값으로 확정하지 않는다: 칸 조회가 실패하면 명시 태그만 담고 나머지는 «미기록».
12
13
  * - 태그 바꾸기 감사(`runTagChange` — task-hand.ts): 카드 history 에 `run-tag-change`
@@ -129,7 +130,8 @@ const CROWN_MARK = '\u{1F451}';
129
130
 
130
131
  /**
131
132
  * 출생 신분 자동 — «조회에 성공한» 칸의 우선순위(P0 = critical·special·protect · P1 = normal · 그 외 normal)·대표 표시에서 단다.
132
- * 권한(rights)은 출생에서 올리지 않는다(기본 s · 올림은 `--tag rights=…` 명시만).
133
+ * 권한(rights)은 추정하지 않는다(RUN-IDENTITY-RIGHTS): 체크리스트 출생 정보에는 권한 근거가 없으므로
134
+ * `--tag rights=…` 명시 태그로만 기록하고, 태그가 없으면 «미기록».
133
135
  * ⛔ 칸을 못 읽었으면 부르지 않는다 — 그때는 `{ origin }` 에 명시 태그만 얹는다(나머지 «미기록»).
134
136
  * ⛔ 읽은 칸이라도 `priority`·`title` 이 비면 그 값에서 파생되는 칸을 확정하지 않는다(«미기록»):
135
137
  * class 는 priority 가 있어야 · care·protect 는 P0 이거나 대표 가 보이면 올리고, «안 올림»(standard·false)은
@@ -145,7 +147,6 @@ export function deriveBirthIdentity(cell: RunIdentityCell, origin: RunIdentityOr
145
147
  return {
146
148
  ...(priority !== undefined ? { class: critical ? 'critical' as const : 'normal' as const } : {}),
147
149
  ...(careKnown ? { care: raised ? 'special' as const : 'standard' as const, protect: raised } : {}),
148
- rights: 's',
149
150
  origin,
150
151
  };
151
152
  }
@@ -15,6 +15,8 @@ import { execFile } from 'node:child_process';
15
15
  import { promisify } from 'node:util';
16
16
  import { extname, join, relative, resolve } from 'node:path';
17
17
  import { debug } from '../debug/log.js';
18
+ import { passJourneyNode } from '../self-dev/graph-journey-nodes.js';
19
+ import { readJourneyEdge, recordJourneyEdge } from '../self-dev/graph-journey-route.js';
18
20
  import { readTaskAgentState, readTaskCard, taskAgentStatePath, TASK_CARD_PREFIX, type CompletionKind, type TaskCard } from './task-hand.js';
19
21
  import type { SupervisorJobResult, SupervisorStopReason } from '../self-dev/run-supervisor.js';
20
22
  import { executeNextAction, type ActionDeps, type DeliveryKind, type NextAction } from './actions.js';
@@ -327,14 +329,22 @@ export async function recordTaskAgentShadowMove(input: TaskAgentShadowInput, dep
327
329
  checklistId: delivery ? card?.checklistId ?? '' : '',
328
330
  ...(delivery ? { delivery } : {}),
329
331
  };
330
- const liveRetry = !delivery && deps.command !== undefined && deps.loadGate !== undefined
331
- && (LIVE_RETRY_MOVES as readonly string[]).includes(judgement.move) && liveMoves.has(judgement.move as TaskAgentLiveMove);
332
+ const retryMove = !delivery && (LIVE_RETRY_MOVES as readonly string[]).includes(judgement.move);
333
+ const route = retryMove ? readJourneyEdge('next-move', judgement.move,
334
+ { move: judgement.move, source: judgeInput.pr ? `pr:${judgeInput.pr}` : `run:${input.runId ?? 'unknown'}`, runId: input.runId }) : null;
335
+ const liveRetry = retryMove && route?.source === 'graph' && route.to === 'dispatch'
336
+ && deps.command !== undefined && deps.loadGate !== undefined && liveMoves.has(judgement.move as TaskAgentLiveMove);
332
337
  executorResult = await executeNextAction(action, {
333
338
  mode: delivery ? (deps.mode ?? 'shadow') : liveRetry ? 'live' : 'shadow',
334
339
  command: deps.command ?? (async () => { throw new Error('task-agent shadow path must not run commands'); }),
335
340
  observe: (_event, data) => { wouldDo = data.reason; },
336
341
  ...(liveRetry ? { liveMoves, retryLaunches, loadGate: deps.loadGate } : {}),
337
342
  });
343
+ if (liveRetry && executorResult === 'done' && route) {
344
+ passJourneyNode('next-move', { provenance: 'task-agent-terminal', outcome: judgement.move,
345
+ runId: input.runId ?? undefined, data: { source: judgeInput.pr ? `pr:${judgeInput.pr}` : `run:${input.runId ?? 'unknown'}`, pr: judgeInput.pr ?? null } });
346
+ recordJourneyEdge(route, 'dispatch');
347
+ }
338
348
  }
339
349
  const move: TaskAgentShadowMove = {
340
350
  runId: input.runId,
@@ -10,7 +10,7 @@
10
10
  import { execFileSync } from 'node:child_process';
11
11
  import { createHash, randomBytes } from 'node:crypto';
12
12
  import { mkdirSync, readFileSync, statSync, writeFileSync, type Stats } from 'node:fs';
13
- import { dirname, join, resolve } from 'node:path';
13
+ 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 { validateUnitCalls } from '../graph-runner/runner.js';
@@ -29,7 +29,8 @@ import { parseWorkOrder, renderWorkOrderGoal, WORK_ORDER_FILE_PATTERN, type Work
29
29
  import { inspectPrelaunchAlreadyDone, type AlreadyDoneDecision, type AlreadyDoneCandidate,
30
30
  type PrelaunchGitRunnerForTest } from './prelaunch-already-done.js';
31
31
  import { draftReleaseComment } from '../self-dev/draft-triage-rules.js';
32
- import { parseAskTargetPathHints } from '../self-dev/launch-preflight-text.js';
32
+ import { parseAskTargetPathHints, parseAskTargetPathHintsResult } from '../self-dev/launch-preflight-text.js';
33
+ import { inspectGoalDoneBoundary } from '../self-implement/goal-author.js';
33
34
  import { INFLIGHT_REGISTRY_FILE, registerInflight } from '../pr-tool/inflight-registry.js';
34
35
 
35
36
  export interface ResolveHandTextDeps {
@@ -210,6 +211,8 @@ export interface TaskCardMove { kind: 'launch' | 'wait'; command?: string[]; rea
210
211
  export interface TaskCard {
211
212
  id: string;
212
213
  text: string;
214
+ /** 첫 줄 대상 경로 라벨에서 확인한 저장소 상대 경로. 필드 부재는 경로를 모른다는 뜻이다. */
215
+ targetPaths?: string[];
213
216
  seat?: TaskSeat;
214
217
  checklistId?: string;
215
218
  /** Explicit release version for an adopted PR; post-land still confirms the cell exists there. */
@@ -231,8 +234,11 @@ export interface TaskCard {
231
234
  * launch-failed = 발사기가 띄우기에 실패했다(사유는 history 마지막 칸) — 다음 수는 다시 발사.
232
235
  * failed = 발사된 런이 PR·수확 가지 없이 죽었거나 끝내 안 떴다(TA-JUDGE-DEAD-RUN · `card-evidence.ts`) — 사유
233
236
  * (`failed/needs-owner|needs-relaunch — …`)는 history 마지막 칸 · 자동 재발사하지 않는다(사람/판단부 몫).
237
+ * landed-by-hand = 실패 카드에 묶인 PR을 사람이 손수 병합해 main 에 안착시켰다(TA-CARD-MERGE-RECONCILE ·
238
+ * `postland-card.ts` `reconcileHandMergedCard`) — 이전 status·사유는 history `hand-move` 줄에 보존된다.
239
+ * landed = 병합된 merge 커밋이 카드의 land attempt head 와 정확히 일치해 에이전트 착지로 확정했다(같은 정산 경로).
234
240
  */
235
- status: 'handed' | 'launched' | 'launch-failed' | 'failed' | 'done';
241
+ status: 'handed' | 'launched' | 'launch-failed' | 'failed' | 'landed-by-hand' | 'landed' | 'done';
236
242
  history: TaskCardEvent[];
237
243
  /** 미션 카드만 — 조각 카드 id(순서대로) · 쪼갠 출처(`mission.ts` splitMission). */
238
244
  pieces?: string[];
@@ -292,7 +298,7 @@ export interface TaskCard {
292
298
  * REJUDGE base-stale — `base-stale` (overlap evidence gate base went stale with PR-file overlap) waits for a re-gate on a new base;
293
299
  * only after that re-gate passes is the attempt consumed (`openLandAttempts`) and the same head may land once more.
294
300
  */
295
- landAttempts?: Array<{ pr: number; head: string; at: string; ok?: boolean; detail?: string; class?: 'infra' | 'judgement' | 'base-stale'; reason?: string }>;
301
+ landAttempts?: Array<{ pr: number; head: string; at: string; ok?: boolean; detail?: string; class?: 'infra' | 'judgement' | 'base-stale' | 'recovery'; reason?: string }>;
296
302
  /** TA-LIVE-LAND-2 — `tasks hand --ta-land`: this card's run leaves the merge to the task agent (propose-land). */
297
303
  taLand?: true;
298
304
  /** TASKS-HAND-CHILD-LLM — `tasks hand --child-llm <provider>/<model> [--child-llm-effort <level>]` → 발사 인자 `--child-llm-provider/-model/-effort`. */
@@ -434,6 +440,25 @@ export function readTaskCard(id: string, path = taskAgentStatePath()): TaskCard
434
440
  return readState(path).tasks?.[id];
435
441
  }
436
442
 
443
+ function canonicalTargetPaths(paths: readonly string[]): string[] {
444
+ return [...new Set(paths.filter((path): path is string => typeof path === 'string').map((path) => posix.normalize(path))
445
+ .filter((path) => path !== '.' && path !== '..' && !posix.isAbsolute(path)
446
+ && !path.startsWith('../') && !path.includes('\\') && !/^[A-Za-z]:\//.test(path)))].sort();
447
+ }
448
+
449
+ /** 같은 저장소 경로를 만지는 착지 전 카드만 돌려준다. 경로 미기록 카드는 추측하지 않는다. */
450
+ export function cardsTouchingPaths(cards: readonly TaskCard[], paths: readonly string[]): Array<{
451
+ card: TaskCard; checklistId?: string; runId?: string; pr?: number; paths: string[];
452
+ }> {
453
+ const wanted = new Set(canonicalTargetPaths(paths));
454
+ if (wanted.size === 0) return [];
455
+ return cards.filter((card) => card.status === 'launched' && !card.postLand && !card.trainLanding && !card.prTerminal)
456
+ .map((card) => ({ card, paths: canonicalTargetPaths(card.targetPaths ?? []).filter((path) => wanted.has(path)) }))
457
+ .filter((item) => item.paths.length > 0)
458
+ .map(({ card, paths }) => ({ card, ...(card.checklistId ? { checklistId: card.checklistId } : {}),
459
+ ...(card.runId ? { runId: card.runId } : {}), ...(cardPrNumber(card) !== undefined ? { pr: cardPrNumber(card) } : {}), paths }));
460
+ }
461
+
437
462
  export const CLOSED_BY_HAND_EVENT = 'closed-by-hand';
438
463
 
439
464
  /** 카드를 손으로 닫는다 — 상태를 `failed` 로 두고 history 에 한 줄(`closed-by-hand`)을 남긴다. 이미 손으로 닫은 카드는 그대로 돌려준다(멱등). */
@@ -552,7 +577,7 @@ export function shellQuote(arg: string): string {
552
577
  }
553
578
 
554
579
  /** 발사기에 넘기는 연결 — env(`ELANOUS_RUN_ID`)를 자식 환경에 얹으면 하니스 런이 `runId` 로 돈다(`resolveRunIdentity` 상속). launchId 는 카드에만 남는 발사 토큰이다. */
555
- export interface TaskLaunchContext { runId: string; launchId: string; env: Record<string, string>; cardLabelContext?: TaskCardLabelContext }
580
+ export interface TaskLaunchContext { runId: string; launchId: string; env: Record<string, string>; cardLabelContext?: TaskCardLabelContext; substrate?: 'pod'; podGoal?: string; effectiveChildProvider?: string }
556
581
  /** 발사기가 «이 런 id 로 띄웠다»고 돌려주는 영수증 — 없으면 카드에 런 id 를 적지 않는다(추측하지 않는다). */
557
582
  export interface TaskLaunchReceipt {
558
583
  runId?: string;
@@ -657,6 +682,8 @@ export function dispatchDeliverableCompletion(id: string, input: { ref: string;
657
682
  export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
658
683
  const text = opts.text.trim();
659
684
  if (!text) throw new Error('과제 한 줄이 비어 있다');
685
+ const targetPathHints = parseAskTargetPathHintsResult(text);
686
+ const targetPaths = canonicalTargetPaths(targetPathHints.paths);
660
687
  if (opts.seat !== undefined && !TASK_SEATS.includes(opts.seat)) throw new Error(`자리는 ${TASK_SEATS.join('|')} 중 하나다: ${opts.seat}`);
661
688
  if (opts.completion !== undefined && !COMPLETION_KINDS.includes(opts.completion)) throw new Error(`종결 종류는 ${COMPLETION_KINDS.join('|')} 중 하나다: ${opts.completion}`);
662
689
  for (const [flag, value] of [['--goal', opts.goal], ['--milestone', opts.milestone]] as const) {
@@ -708,6 +735,7 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
708
735
  const path = opts.statePath ?? taskAgentStatePath();
709
736
  const card: TaskCard = {
710
737
  id, text,
738
+ ...(!targetPathHints.labelMissing ? { targetPaths } : {}),
711
739
  ...(opts.seat ? { seat: opts.seat } : {}),
712
740
  ...(opts.checklistId ? { checklistId: opts.checklistId } : {}),
713
741
  ...(opts.checklistVersion !== undefined ? { checklistVersion: opts.checklistVersion } : {}),
@@ -748,6 +776,7 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
748
776
  if (!owned.ok) throw new TaskCardSupersededError(next.id);
749
777
  };
750
778
  writeCard(path, card);
779
+ try { debug.log('task-agent.hand', 'target-paths', { card: id, count: targetPaths.length, labelMissing: targetPathHints.labelMissing }); } catch { /* fail-soft */ }
751
780
  try { debug.log('task-agent.graph-select', !selected.composition ? 'composition-missing' : selected.error ? 'composition-invalid' : 'composition-selected', {
752
781
  completion, file: selected.composition?.file ?? `graphs/work/${completion}.yaml`,
753
782
  unitsResolved: selected.unitsResolved, missingUnits: selected.missingUnits,
@@ -761,6 +790,17 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
761
790
  }
762
791
  if (mode === 'shadow') return { card, move, mode, launched: false, ...(project ? { cwd: project.target } : {}) };
763
792
  if (!opts.launcher) throw new Error('--live 인데 launcher 가 없다');
793
+ if (completion === 'code-pr' && card.checklistId) {
794
+ const { missing } = inspectGoalDoneBoundary(text);
795
+ if (missing.length > 0) {
796
+ const reason = `goal-revision-required: 완료 경계 누락 ${missing.join(' · ')} — 골 문면을 고친 뒤 다시 넘기세요`;
797
+ const failed: TaskCard = { ...card, status: 'failed', history: [...card.history,
798
+ { at: (opts.now ?? (() => new Date()))().toISOString(), event: 'goal-revision-required', detail: reason }] };
799
+ writeCard(path, failed);
800
+ try { debug.log('task-agent.hand', 'done-boundary-missing', { taskId: id, checklistId: card.checklistId ?? null, missing, reason }); } catch { /* fail-soft */ }
801
+ throw new Error(`${reason} (카드 ${id})`);
802
+ }
803
+ }
764
804
  let prelaunch: AlreadyDoneDecision;
765
805
  try { prelaunch = completion === 'code-pr'
766
806
  ? (opts.prelaunchInspector ?? ((input, target) => inspectPrelaunchAlreadyDone(input, target,
@@ -779,9 +819,14 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
779
819
  const runId = mintRunId();
780
820
  const launchId = `tl-${randomBytes(6).toString('hex')}`;
781
821
  const context: TaskLaunchContext = { runId, launchId, env: { [HARNESS_RUN_ID_ENV]: runId, ELANOUS_TASK_CARD_ID: card.id,
822
+ ...(cardPrNumber(card) ? { ELANOUS_TASK_BOUND_PR: String(cardPrNumber(card)) } : {}),
782
823
  ...(card.checklistId ? { ELANOUS_POD_SLOT_ID: card.checklistId } : {}),
783
824
  ...(card.seat ? { ELANOUS_POD_OWNER_KIND: 'seat', ELANOUS_POD_OWNER_ID: card.seat } : {}),
784
- ...(card.taLand ? { [TA_LAND_ENV]: '1' } : {}) }, cardLabelContext: taskCardLabelContext(card) };
825
+ ...(card.taLand ? { [TA_LAND_ENV]: '1' } : {}) }, cardLabelContext: taskCardLabelContext(card),
826
+ // An omitted card provider uses the established Pod default. Carry the effective value explicitly so
827
+ // remote-parent code never has to infer a provider from the serialized CLI argv.
828
+ effectiveChildProvider: card.childLlm?.provider ?? 'openai-codex',
829
+ ...(completion === 'code-pr' && selected.launcher === 'harness-say' ? { substrate: 'pod' as const, podGoal: card.text } : {}) };
785
830
  let receipt: void | TaskLaunchReceipt;
786
831
  try {
787
832
  receipt = await opts.launcher(move.command!, project?.target, context);
@@ -812,9 +857,11 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
812
857
  // INFLIGHT-REGISTRY — 출발 때 맥락을 남긴다(머지 때 같은 파일 줄의 의도를 스마트 머지가 읽는다 · 착지하면 지운다).
813
858
  try {
814
859
  const [head = '', ...rest] = text.split(/\r?\n/);
860
+ const intentLines = (/^\s*(?:대상\s*경로|target\s*paths?)\s*[::]/i.test(head) ? rest : [head, ...rest])
861
+ .filter((line) => !/^\s*(?:[-*]\s*)?완료 경계 (?:코드|실물|증거 명령)\s*:/.test(line));
815
862
  registerInflight({
816
863
  runId: boundRunId ?? runId, cell: card.checklistId ?? card.id, cardId: card.id,
817
- intent: (/^\s*(?:대상\s*경로|target\s*paths?)\s*[::]/i.test(head) ? rest.join(' ') : text) || text,
864
+ intent: intentLines.join(' ').trim() || text,
818
865
  files: parseAskTargetPathHints(text),
819
866
  }, { path: join(dirname(path), INFLIGHT_REGISTRY_FILE), ...(opts.now ? { now: opts.now } : {}) });
820
867
  } catch (error) {
@@ -0,0 +1,22 @@
1
+ import { parseWorkOrder, type WorkOrder } from './work-order.js';
2
+
3
+ export interface BuildWorkOrderInput {
4
+ cellId: string;
5
+ version: string;
6
+ lifeId?: string;
7
+ priority?: string;
8
+ peers?: string;
9
+ }
10
+
11
+ /** Build the normalized nine-field core from already-grounded inputs; no CLI, filesystem, or launch side effects. */
12
+ export function buildWorkOrder(input: BuildWorkOrderInput): WorkOrder {
13
+ const parsed = parseWorkOrder(JSON.stringify({
14
+ cellId: input.cellId,
15
+ lifeId: input.lifeId,
16
+ version: input.version,
17
+ priority: input.priority,
18
+ peers: input.peers,
19
+ }));
20
+ if (!parsed.ok) throw new Error(parsed.reason);
21
+ return parsed.order;
22
+ }
@@ -17,6 +17,17 @@ export type PodProviderPlan =
17
17
  | { provider: 'grok'; excluded: PodAccountPlan['excluded']; grokSubscriptionEligible: boolean }
18
18
  | { provider: null; reasons: string[]; grokSubscriptionEligible: boolean };
19
19
 
20
+ /** Effective cap used by the Pod broker; callers carrying an owner-approved selection must carry this same value. */
21
+ export function podAccountThresholdPercent(name: string, options: {
22
+ excludeAt?: number;
23
+ thresholdPercentByAccount?: Readonly<Record<string, unknown>>;
24
+ } = {}): number {
25
+ return codexAccountThresholdPercent(name, {
26
+ thresholdPercent: options.excludeAt ?? POD_ACCOUNT_EXCLUDE_AT_PERCENT,
27
+ thresholdPercentByAccount: options.thresholdPercentByAccount,
28
+ });
29
+ }
30
+
20
31
  /** Pod 의 codex → grok 선택. 자격 종류는 과금 동의와 별도로 판단한다. */
21
32
  export function planPodProvider(input: {
22
33
  codexCandidates: readonly RotationCandidate[];
@@ -85,9 +96,7 @@ export function planPodAccounts(
85
96
  const known: RotationCandidate[] = [];
86
97
  const unknown: RotationCandidate[] = [];
87
98
  for (const c of candidates) {
88
- const threshold = typeof options === 'number'
89
- ? excludeAt
90
- : codexAccountThresholdPercent(c.name, { thresholdPercent: excludeAt, thresholdPercentByAccount });
99
+ const threshold = typeof options === 'number' ? excludeAt : podAccountThresholdPercent(c.name, { excludeAt, thresholdPercentByAccount });
91
100
  if (c.reached === true) { excluded.push({ name: c.name, why: 'quota reached' }); continue; }
92
101
  if (c.usedPercent !== undefined && c.usedPercent >= threshold) { excluded.push({ name: c.name, why: `used ${c.usedPercent}% ≥ ${threshold}%` }); continue; }
93
102
  (c.usedPercent === undefined ? unknown : known).push(c);
@@ -113,6 +122,33 @@ export function planPodAccounts(
113
122
  return { usable, excluded };
114
123
  }
115
124
 
125
+ /** HQ selects one owner account before remote-parent launch; keep the configured rotation order. */
126
+ export function planOwnerCodexMirrorCandidates(candidates: readonly RotationCandidate[], options: {
127
+ accountOrder: readonly string[];
128
+ thresholdPercentByAccount?: Readonly<Record<string, unknown>>;
129
+ }): RotationCandidate[] {
130
+ const usable = new Set(planPodAccounts(candidates, { thresholdPercentByAccount: options.thresholdPercentByAccount }).usable);
131
+ const rank = (name: string): number => {
132
+ const index = options.accountOrder.indexOf(name);
133
+ return index < 0 ? options.accountOrder.length : index;
134
+ };
135
+ return candidates.map((candidate, index) => ({ candidate, index })).filter(({ candidate }) => usable.has(candidate.name))
136
+ .sort((a, b) => rank(a.candidate.name) - rank(b.candidate.name) || a.index - b.index)
137
+ .map(({ candidate }) => candidate);
138
+ }
139
+
140
+ /** Remote owner-mirror runs may plan against exactly the account HQ selected and its measured usage. */
141
+ export function ownerCodexMirrorCandidate(candidates: readonly RotationCandidate[], account: string, usedPercent?: number): RotationCandidate[] {
142
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(account)) return [];
143
+ return candidates.filter((candidate) => candidate.name === account).map((candidate) => {
144
+ const ownerCandidate = { ...candidate };
145
+ delete ownerCandidate.usedPercent;
146
+ ownerCandidate.reached = false;
147
+ const measured = usedPercent !== undefined && Number.isFinite(usedPercent) ? usedPercent : undefined;
148
+ return { ...ownerCandidate, reached: false, ...(measured !== undefined ? { usedPercent: measured } : {}) };
149
+ });
150
+ }
151
+
116
152
  /** Job 마다 다음 계정 — 잔량 순으로 돌려 가며. 쓸 계정이 없으면 만들 때 이유를 대고 던진다. */
117
153
  export function makePodAccountBroker(plan: PodAccountPlan): () => string {
118
154
  if (plan.usable.length === 0) {