elanous 0.2.35 → 0.2.36

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 (686) 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/chunks/{d06f9160.a3d9062f95de8ad7.js → 053a429e.9a63436527cc751c.js} +1 -1
  4. package/apps/pwa/out/_next/static/chunks/109.f196abf3484bb97f.js +287 -0
  5. package/apps/pwa/out/_next/static/chunks/{4346.8601952e73bf5803.js → 1201.afbfc5b1c5e5cbe4.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/1517.9275b89572098ff3.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1574.ad11f8db8396ab45.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1614.7a8c5c40aee0261f.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/1871-f1eb29d8dbb4065b.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/190.285c832bd9626f8c.js +64 -0
  11. package/apps/pwa/out/_next/static/chunks/2193.0ea24c4a7aa1d004.js +36 -0
  12. package/apps/pwa/out/_next/static/chunks/223-ad865c1e80491d78.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/2265-f0d90b6dbec05f81.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/2267.eb4a62a209f09ec4.js +149 -0
  15. package/apps/pwa/out/_next/static/chunks/2341-86cd06c0cf01aa33.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/2352.9abc42422bade876.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/2397-c1653a816061842d.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{3103.0df8da390948bb84.js → 2500.cbc1257b774aae52.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/{7644.17e37ba6f1d4226e.js → 2683.c9773a0c589b031b.js} +3 -3
  20. package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +24 -0
  21. package/apps/pwa/out/_next/static/chunks/{4718-17d2af636796a330.js → 275-02ea4c2a33980422.js} +3 -3
  22. package/apps/pwa/out/_next/static/chunks/2812ca6a.3b9f4a7a08885744.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/{8714.ff0b7ce3ec3e3ae2.js → 2941.3c3546f96bc6efa7.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +24 -0
  26. package/apps/pwa/out/_next/static/chunks/{9214.63a510d39178e997.js → 2986.45d7652e4f13557e.js} +2 -2
  27. package/apps/pwa/out/_next/static/chunks/3031-85328a92fcce4da6.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/3136.30aaaa5fa03662a3.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{3677-4215f826f6aa68e5.js → 3148-98efd4869d660a87.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/3155.2587a55196ecb394.js +226 -0
  31. package/apps/pwa/out/_next/static/chunks/3277.785db1cf09f98601.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/3320-f9c77381f85a2c0a.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/3324.a09703033abcbd2f.js +34 -0
  34. package/apps/pwa/out/_next/static/chunks/3386-91049feabff9a94e.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/339.80afb7e8839372af.js +8 -0
  36. package/apps/pwa/out/_next/static/chunks/3410.7f9af5ab77cbe65f.js +115 -0
  37. package/apps/pwa/out/_next/static/chunks/3538.a445e50bb359d068.js +32 -0
  38. package/apps/pwa/out/_next/static/chunks/3540c645.2595a6af01a97672.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3621.581b2054cc14bee4.js +286 -0
  40. package/apps/pwa/out/_next/static/chunks/3676.8c28d16fd84ca843.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/{9512.5a76207a730e0491.js → 3727.7949ccaacaa71242.js} +2 -2
  42. package/apps/pwa/out/_next/static/chunks/375-b84540853523fe52.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/{8557-e7898769499cd56f.js → 3757-180308bc61021b05.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +74 -0
  45. package/apps/pwa/out/_next/static/chunks/{359-2250789a2d3499e7.js → 3840-5825d56d46976a92.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{da5176c6.6773b6c5994e1d99.js → 3a3d9966.cc4d4585a2708e7c.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/4067-bf9aa60547972937.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4116.a84a92a2492c080e.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4176.e5729c93c29151eb.js +104 -0
  51. package/apps/pwa/out/_next/static/chunks/4227-e6c84686bc8946ca.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/{9952.5daf5f94063a2b3e.js → 4286.b70c4520306817e8.js} +1 -1
  53. package/apps/pwa/out/_next/static/chunks/4304.e9b2512834a9e23e.js +23 -0
  54. package/apps/pwa/out/_next/static/chunks/4327.b9e08a71c0009348.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/{938.66ad1ef0e5abae1c.js → 4615.8525eb0add35eba6.js} +1 -1
  56. package/apps/pwa/out/_next/static/chunks/4946.bd106eafd668f248.js +148 -0
  57. package/apps/pwa/out/_next/static/chunks/5085-bce4904931767ca6.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5125.2eb9968b83767193.js +93 -0
  59. package/apps/pwa/out/_next/static/chunks/5128-75b733fd74a9a1eb.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/{6236.e18cced2d5ba6afb.js → 528.38ce20ef8aa251ff.js} +16 -16
  61. package/apps/pwa/out/_next/static/chunks/5489f3fe.4bb1458b09f6dead.js +122 -0
  62. package/apps/pwa/out/_next/static/chunks/{3408.21d1570602f4b6c0.js → 552.b7d061ad91eeac51.js} +2 -2
  63. package/apps/pwa/out/_next/static/chunks/5560-2a4648f6a30f16e7.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5711.957b095705c12560.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/{1530.0e612369b6fd7ea0.js → 575.d929793a53f27c4b.js} +1 -1
  66. package/apps/pwa/out/_next/static/chunks/5772-e29e14f8ff127122.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5887.5b2f5b44ce0f7e9a.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5899-4c112a2d908cf97f.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/599.c39c571b6733f2a2.js +41 -0
  70. package/apps/pwa/out/_next/static/chunks/6041.1b65efb796ebc2a5.js +79 -0
  71. package/apps/pwa/out/_next/static/chunks/6057-765c0a26028c86b2.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6142.f289e0d039f453a6.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6199-6bcd61d2a3910e04.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/6236.cdf7293e710a9b2d.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/6387-237e079dac9a3ae6.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6448-b6d272d074276e14.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/6466-92e65a48490b68a9.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/6566.926a1d1b7c911442.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6580-cdc0e4a634ce4708.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/6659-b242dc31b20b3f29.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6690.c5d9b321b1f79384.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/671-e9b6ad0c771c5514.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6862.bcbf89dd0f4496b3.js +27 -0
  84. package/apps/pwa/out/_next/static/chunks/6912-7b375ee48732c767.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/6925.562d532110879886.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/{7385.50a308a477bdfc21.js → 6943.c6b24124853a47b2.js} +1 -1
  87. package/apps/pwa/out/_next/static/chunks/{630.fe5a46428d63b013.js → 727.7deb87749b0a343a.js} +1 -1
  88. package/apps/pwa/out/_next/static/chunks/{2018.a741297bce759490.js → 7481.39f7a4654907bf6e.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/7545.b1aa42cd15503319.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7551-416d298c2dc4a9ab.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/{8444.4c26b379ca2b9596.js → 771.c3cdb6c1f7f47c02.js} +17 -17
  92. package/apps/pwa/out/_next/static/chunks/7784.1f0ac4a16d190cf4.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7870-309de463786ac1fc.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7888-e29b151bb6a3bb8b.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{3589.5444a06bcf6e775c.js → 7891.03f910124a737985.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/7905-6ba78d9234608f79.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8037.e254fd797aa224d1.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8207.f527886b7c464529.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/856.50bda61439d465e6.js +62 -0
  100. package/apps/pwa/out/_next/static/chunks/{b2f6ba4d.fb56fdbbf798df33.js → 873d6c12.09bd499f57171543.js} +1 -1
  101. package/apps/pwa/out/_next/static/chunks/{5101.e32282718f99ed6f.js → 8904.7d51af2dc033965c.js} +2 -2
  102. package/apps/pwa/out/_next/static/chunks/9031-92e9b487edb681ee.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/9060.5410d9f6a95f6287.js +90 -0
  104. package/apps/pwa/out/_next/static/chunks/{5637.281e5dec4ea6ecf1.js → 914.8abefd48d579547b.js} +2 -2
  105. package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/{4705-194e64e47ca0fbdb.js → 9250-072df22eaadaa6b5.js} +1 -1
  107. package/apps/pwa/out/_next/static/chunks/9289.3e92f278821e18e0.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9319.7816d3cc741cd34f.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9327-e016bb9f1674d24f.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/9365.3de48bf75193ff9a.js +77 -0
  111. package/apps/pwa/out/_next/static/chunks/9383.5b5e9aa56b5fea97.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9387-cb929573ef436f39.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9489.c27becacc3283dec.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/{8637.47f5b35afcae5e6b.js → 9514.131c52cc75fe6439.js} +1 -1
  115. package/apps/pwa/out/_next/static/chunks/9536.28962663c7734376.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9686-12286f5bbf15a5a0.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9776.289d40cc5a4c342a.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{1674.2a65fd5668e1cc5f.js → 9789.60f723d18097ec30.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/989.f0c17523c5e61f65.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9972-1df393aa8d4f7d52.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9f31e478.fefcbcd3c388ebc5.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-96750aba7430959f.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4105e5bbbb043024.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5d4fa75c2acb113e.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-a79a9bdb3b2142bf.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-f1c2047484992a35.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-15ffc49b2d8c70e2.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-67d53a3fc8734135.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-e30c8dc696491336.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-2136e04fa77696e2.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-fecd2814790c2e12.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-280aa4a98fc5bb44.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-c14e96b65fb4b883.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-187dac74825ed6bf.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-6bc7246ea8c92448.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-083747f1d4518f61.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-96750aba7430959f.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-15ca95a16ec96e1f.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-a8ac031b3810eb64.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-8835f93110494cda.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-e2de2e59111c9aad.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f2b2e4bf6e981450.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-5b92b7f75df20948.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-468eddf2b1a84ecb.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-2af16e62c12f22df.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-18b40867a77a5793.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-fe934f2979f5a4a2.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-3eec435537357170.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ff88cbfd2aa99fc8.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-a5b39fb780c70ab5.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ae465dde1d1b3933.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-e7abc34a48a6f71e.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-cab9674fde9ead26.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1da49bc8712284d0.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5e8aa657551ac912.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-fcc36f36c6dc1fe2.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d22db22f2a7296ca.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-d12dc7b1773878f0.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-99debec9ea7fbec0.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-96750aba7430959f.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-2a088a78bad7e924.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-2e8ed57db7e69993.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-4b3a16213c2ae8fe.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f098747ddf38c98b.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-c15958835534404b.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-68279e3c843c1fd7.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-a34a74453367a39d.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-8767a7db2155a5bd.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-bd5976683460d7f2.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b7364835e7f2ef54.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-311af16b3ee0ffca.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-fb670757274ae990.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{0368f25d-ad84af92fefee68f.js → ccae1c4b-0cf414f5eff1b10d.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/{cbe38a15.5a032598e39970c6.js → ceba0382.650712b56b85b582.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/{b6705a4f-b9a9047de9eecfd0.js → da5ecc5c-b005ad8cac737d57.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{56d372f2.681ab4ec4c998fae.js → f9a61e4d.1fc2c1dbdd49fe46.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/framework-6d497cbf1eef04c6.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-app-012f5edec932f337.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-da5aeb809edc94a2.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-5ee319af6f749dfe.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-4bc84653a718d6c6.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-8a96cf6775c73d6e.js +1 -0
  183. package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → uC-N0emedeNOFuaBQFv-I}/_buildManifest.js +1 -1
  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/docs/goal-context/05-authoring-lessons.jsonl +47 -0
  278. package/docs/goal-context/README.md +3 -0
  279. package/graphs/default-loop.yaml +6 -1
  280. package/graphs/implement-loop.yaml +24 -0
  281. package/graphs/release/recipes.yaml +6 -0
  282. package/graphs/release/release-loop.yaml +17 -4
  283. package/graphs/wizard/recipes.yaml +44 -0
  284. package/graphs/wizard/wizard-loop.yaml +44 -0
  285. package/graphs/work/research-report.yaml +2 -0
  286. package/package.json +1 -1
  287. package/scripts/ci-typecheck-changed.ts +139 -5
  288. package/scripts/coord-role-pack.ts +1 -1
  289. package/scripts/first10-gate.ts +416 -0
  290. package/scripts/fleet/wsl-node-setup.sh +432 -0
  291. package/scripts/release-loop/docs-node.ts +204 -8
  292. package/scripts/release-loop/gate-node.ts +249 -53
  293. package/scripts/release-loop/node-verdict.ts +2 -0
  294. package/scripts/release-loop/resume-cap.ts +14 -34
  295. package/scripts/release-loop/resume-release.ts +37 -11
  296. package/scripts/release-loop/traffic-node.ts +59 -0
  297. package/scripts/release-loop/traffic-transition.ts +159 -0
  298. package/scripts/rhythm/daily.ts +137 -3
  299. package/scripts/ux-sim.ts +53 -0
  300. package/skills/README.md +1 -0
  301. package/src/acp/core-turn-bridge.ts +48 -6
  302. package/src/agent/delegate-hint.ts +16 -0
  303. package/src/agent/runner.ts +82 -2
  304. package/src/agent/task-notification.ts +56 -10
  305. package/src/agent/types.ts +4 -0
  306. package/src/agent-substrate/pr-reviewer.ts +55 -3
  307. package/src/agent-substrate/review-intent.ts +29 -2
  308. package/src/agent-substrate/review-observation.ts +3 -0
  309. package/src/agent-substrate/self-review-cli.ts +168 -16
  310. package/src/autopilot/mission-codebase-gate.ts +141 -12
  311. package/src/autopilot/pr-manager.ts +25 -5
  312. package/src/boot/daemon-tools/self-implement.ts +1 -0
  313. package/src/budget/usage-outcomes.ts +8 -4
  314. package/src/capture/tui-self-report.ts +102 -0
  315. package/src/chat/goal-continue-verdict.ts +41 -0
  316. package/src/chat/index.ts +30 -4
  317. package/src/chat/internal-turn-origin.ts +1 -0
  318. package/src/chat/paste-fold.ts +86 -0
  319. package/src/chat/tool-render/block.ts +32 -0
  320. package/src/chat/tool-render/dispatch.ts +2 -20
  321. package/src/chat/tool-render/result-text.ts +98 -0
  322. package/src/chat/turn-typeahead.ts +70 -7
  323. package/src/cli/config-audit.ts +119 -0
  324. package/src/cli/doctor-cli.ts +22 -0
  325. package/src/cli/guardian-cli.ts +10 -0
  326. package/src/cli/herdr-cli.ts +34 -0
  327. package/src/cli/light-entry-route.ts +6 -3
  328. package/src/cli/log-event-names.ts +2 -0
  329. package/src/cli/make-cli.ts +247 -11
  330. package/src/cli/msg-cli.ts +117 -3
  331. package/src/cli/pr-cli.ts +29 -16
  332. package/src/cli/pr-land-base-read.ts +11 -2
  333. package/src/cli/pr-land-heavy-remote.ts +6 -3
  334. package/src/cli/pr-land-overlap-evidence.ts +23 -4
  335. package/src/cli/pr-land-recovery.ts +117 -1
  336. package/src/cli/pty-takeover-cli.ts +8 -7
  337. package/src/cli/release-cli.ts +21 -5
  338. package/src/cli/release-single-flight.ts +1 -1
  339. package/src/cli/tasks-card-show.ts +162 -0
  340. package/src/cli/tasks-cli.ts +574 -356
  341. package/src/cli/tasks-read-cli.ts +197 -0
  342. package/src/core-turn/run-core-turn.ts +4 -2
  343. package/src/core-turn/run-goal-loop.ts +73 -16
  344. package/src/core-turn/types.ts +6 -1
  345. package/src/dashboard/context/keys.ts +8 -31
  346. package/src/dashboard/index.ts +202 -49
  347. package/src/dashboard/input/agent-wake.ts +7 -1
  348. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +146 -3
  349. package/src/dashboard/input/chat-main-slash-command.ts +4 -2
  350. package/src/dashboard/input/goal-continue.ts +210 -0
  351. package/src/dashboard/input/goal-interim.ts +2 -0
  352. package/src/dashboard/input/internal-turn.ts +2 -8
  353. package/src/dashboard/input/seat-autowake.ts +9 -7
  354. package/src/dashboard/input/turn-autoheal.ts +52 -0
  355. package/src/dashboard/seat-boot-preamble.ts +132 -5
  356. package/src/dashboard/slash-runtime/chat-persona.ts +65 -8
  357. package/src/dashboard/slash-runtime/dashboard-handlers.ts +3 -2
  358. package/src/dashboard/slash-runtime/model-choices.ts +15 -0
  359. package/src/dashboard/stale-install-check.ts +3 -99
  360. package/src/debug/batch-queue.ts +119 -0
  361. package/src/debug/tui-log-tag.ts +67 -0
  362. package/src/display/agent-surface.ts +7 -0
  363. package/src/domains/standalone-log-sink.ts +15 -2
  364. package/src/esc-abort-gate.ts +69 -0
  365. package/src/git-fs/worktree.ts +95 -1
  366. package/src/graph-runner/graph-cli.ts +18 -0
  367. package/src/graph-runner/runner.ts +20 -11
  368. package/src/graph-wizard/generate.ts +108 -4
  369. package/src/graph-wizard/steps.ts +15 -0
  370. package/src/grounding/proactive-ground.ts +86 -0
  371. package/src/harness/control-inbox.ts +49 -1
  372. package/src/harness/harness-cli-command.ts +51 -7
  373. package/src/harness/harness-incidents.ts +52 -1
  374. package/src/harness/pod-control-send.ts +33 -5
  375. package/src/harness/self-send-remote.ts +69 -0
  376. package/src/harness/self-send-routing-guard.ts +6 -0
  377. package/src/harness/self-send-target.ts +4 -3
  378. package/src/index.ts +327 -12
  379. package/src/input-core/context-key-runtime.ts +21 -0
  380. package/src/light-cli.ts +6 -1
  381. package/src/llm-wellformed.ts +70 -0
  382. package/src/llm.ts +35 -4
  383. package/src/loops/msg-wake.ts +35 -39
  384. package/src/loops/orchestrator/inbox.ts +59 -11
  385. package/src/loops/orchestrator/knowhow-pack.ts +364 -0
  386. package/src/loops/orchestrator/tick.ts +5 -1
  387. package/src/maturity/feature-maturity.ts +1 -1
  388. package/src/models/prompts.ts +17 -2
  389. package/src/msg/msg-post-office.ts +116 -0
  390. package/src/mss/logging/log-store.ts +79 -22
  391. package/src/nexus/api/decisions-route.ts +38 -18
  392. package/src/nexus/api/graph-wizard-api.ts +20 -2
  393. package/src/nexus/boot/register-mcp-clients.ts +263 -38
  394. package/src/nexus/onboarding/first-boot-wizard.ts +56 -8
  395. package/src/onboarding/first-run.ts +37 -6
  396. package/src/onboarding/web-first.ts +43 -11
  397. package/src/ops/overview-collect.ts +12 -6
  398. package/src/ops/overview.ts +3 -3
  399. package/src/persona/loader.ts +11 -0
  400. package/src/persona/types.ts +8 -0
  401. package/src/prompt-library/session-guidance.ts +14 -0
  402. package/src/provider-summary.ts +8 -0
  403. package/src/pty-shell/herdr-agent-report.ts +118 -9
  404. package/src/pty-shell/herdr-prompt.ts +266 -0
  405. package/src/pty-shell/pty-control-ipc.ts +151 -8
  406. package/src/pty-shell/pty-special-keys.ts +42 -2
  407. package/src/pty-shell/stale-install-check.ts +99 -0
  408. package/src/pty-shell/tui-run-state.ts +14 -2
  409. package/src/release-loop/auto-start.ts +20 -2
  410. package/src/release-loop/checklist.ts +76 -4
  411. package/src/release-loop/rehearsal.ts +36 -20
  412. package/src/repl/index.ts +19 -1
  413. package/src/seat-loop/knowhow-lint.ts +1 -1
  414. package/src/self-dev/decompose-proposal.ts +172 -20
  415. package/src/self-dev/decompose.ts +61 -0
  416. package/src/self-dev/dev-cli.ts +37 -3
  417. package/src/self-dev/dev-pipeline.ts +8 -2
  418. package/src/self-dev/draft-triage-rules.ts +31 -0
  419. package/src/self-dev/glm-credential-guard.ts +77 -0
  420. package/src/self-dev/graph-journey-nodes.ts +1 -0
  421. package/src/self-dev/graph-journey-route.ts +12 -2
  422. package/src/self-dev/orchestrate-cli.ts +68 -3
  423. package/src/self-dev/orchestrate.ts +116 -17
  424. package/src/self-dev/run-supervisor.ts +55 -2
  425. package/src/self-dev/run-types.ts +1 -1
  426. package/src/self-health/autoheal.ts +153 -0
  427. package/src/self-health/signatures.ts +6 -0
  428. package/src/self-implement/device-first.ts +116 -0
  429. package/src/self-implement/doctor-visit.ts +239 -1
  430. package/src/self-implement/evidence-command-budget.ts +80 -0
  431. package/src/self-implement/goal-author-cli.ts +1 -0
  432. package/src/self-implement/goal-author-decompose.ts +265 -4
  433. package/src/self-implement/goal-author.ts +33 -8
  434. package/src/self-implement/goal-elaborate.ts +176 -22
  435. package/src/self-implement/goal-refine.ts +3 -0
  436. package/src/self-implement/graph-variant.ts +40 -6
  437. package/src/self-implement/headless-elanous-driver.ts +19 -3
  438. package/src/self-implement/off-diff-evidence.ts +58 -6
  439. package/src/self-implement/orchestrator.ts +222 -21
  440. package/src/self-implement/pod-warm-pool-profile.ts +1 -0
  441. package/src/self-implement/pwa-import-graph.ts +1 -1
  442. package/src/self-implement/rework-policy.ts +30 -0
  443. package/src/self-implement/run-ledger.ts +108 -0
  444. package/src/self-implement/run-ttl.ts +38 -24
  445. package/src/self-implement/scope-adjacency.ts +3 -1
  446. package/src/self-implement/seams.ts +60 -4
  447. package/src/self-implement/wiring-check.ts +358 -0
  448. package/src/shell-env-bootstrap.ts +11 -4
  449. package/src/skills/runner.ts +4 -2
  450. package/src/skills/tools/agent.ts +290 -48
  451. package/src/skills/tools/schedule-wakeup.ts +23 -4
  452. package/src/skills/tools/shell.ts +61 -6
  453. package/src/skills/tools/terminal-modal-inject.ts +1 -2
  454. package/src/skills/tools/terminal-modal.ts +10 -8
  455. package/src/skills/url-router.ts +41 -1
  456. package/src/smart-wizard/run.ts +66 -0
  457. package/src/status/bar.ts +34 -6
  458. package/src/status/status-provider-info.ts +37 -6
  459. package/src/steward/rejudge-tick.ts +10 -2
  460. package/src/steward/ta-repair-event-collect.ts +17 -6
  461. package/src/task-agent/actions.ts +3 -1
  462. package/src/task-agent/land-queue.ts +21 -8
  463. package/src/task-agent/live-moves.ts +22 -6
  464. package/src/task-agent/mission.ts +30 -0
  465. package/src/task-agent/rejudge-on-head.ts +15 -0
  466. package/src/task-agent/repair-cycle.ts +138 -32
  467. package/src/task-agent/repair-next-move.ts +31 -3
  468. package/src/task-agent/repair-outcomes.ts +29 -0
  469. package/src/task-agent/repair-worker.ts +14 -4
  470. package/src/task-agent/shadow.ts +41 -3
  471. package/src/task-agent/task-card-prefix.ts +2 -0
  472. package/src/task-agent/task-hand.ts +477 -22
  473. package/src/task-agent/task-parent-role-llm.ts +36 -0
  474. package/src/task-agent/tier-split.ts +78 -9
  475. package/src/task-orchestrator/surfaces/pod-account-broker.ts +9 -0
  476. package/src/task-orchestrator/surfaces/pod-child-reuse.ts +146 -0
  477. package/src/task-orchestrator/surfaces/pod-command-job.ts +86 -5
  478. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +215 -3
  479. package/src/task-orchestrator/surfaces/pod-launch-history.ts +133 -0
  480. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +11 -0
  481. package/src/task-orchestrator/surfaces/pod-pool.ts +76 -4
  482. package/src/task-orchestrator/surfaces/pod-provenance.ts +8 -2
  483. package/src/task-orchestrator/surfaces/pod-repair-commit.ts +18 -3
  484. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +16 -0
  485. package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +224 -0
  486. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +201 -0
  487. package/src/task-orchestrator/surfaces/pod-si-warm-provider.ts +444 -0
  488. package/src/task-orchestrator/surfaces/pod-si-warm-runner.ts +387 -0
  489. package/src/task-orchestrator/surfaces/pod-si-warm-transport.ts +157 -0
  490. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +4 -0
  491. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +485 -36
  492. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +3 -0
  493. package/src/task-orchestrator/surfaces/self-implement-pod.ts +396 -19
  494. package/src/task-orchestrator/surfaces/self-implement.ts +42 -2
  495. package/src/tool-runtime/index.ts +15 -2
  496. package/src/tool-runtime/mcp-proxy-bootstrap.ts +29 -0
  497. package/src/tty-foreground.ts +155 -0
  498. package/src/tui/chat/goal-interim.ts +173 -0
  499. package/src/tui/chat/log-view.ts +205 -18
  500. package/src/tui/chat/self-health-status.ts +232 -0
  501. package/src/tui/entry.ts +370 -81
  502. package/src/tui/input/composer.ts +8 -1
  503. package/src/tui/slash/compact-command.ts +7 -0
  504. package/src/tui/slash/compact.ts +1 -7
  505. package/src/tui/slash/resume.ts +75 -0
  506. package/src/tui-client/local-chat-turn.ts +45 -2
  507. package/src/tui-client/next-dashboard-runtime.ts +8 -0
  508. package/src/tui-client/next-loop-command.ts +70 -0
  509. package/src/tui-client/next-wakeup.ts +191 -0
  510. package/src/tui.ts +37 -0
  511. package/src/ui/modal-adapter.ts +2 -2
  512. package/src/ux-sim/classic-tui-seat-scenarios.ts +516 -0
  513. package/src/ux-sim/cli-config-audit-device.ts +121 -0
  514. package/src/ux-sim/dashboard-event-loop-stall-monitor-device.ts +238 -0
  515. package/src/ux-sim/event-monkey.ts +3 -2
  516. package/src/ux-sim/fake-bin.ts +45 -0
  517. package/src/ux-sim/fake-herdr.ts +238 -0
  518. package/src/ux-sim/fake-llm.ts +111 -6
  519. package/src/ux-sim/fault-glm-no-credential.ts +116 -0
  520. package/src/ux-sim/fault-nextmove-dispatch.ts +102 -1
  521. package/src/ux-sim/fault-scope-escape-lift.ts +33 -6
  522. package/src/ux-sim/fault-tui-400-autoheal.ts +297 -0
  523. package/src/ux-sim/goal-device.ts +619 -0
  524. package/src/ux-sim/in-process-cli.ts +22 -5
  525. package/src/ux-sim/mock-authoring-first-run-child.ts +35 -0
  526. package/src/ux-sim/mock-authoring-first-run.ts +97 -0
  527. package/src/ux-sim/mock-seat-pty-frame-child.ts +29 -0
  528. package/src/ux-sim/mock-seat-pty-frame.ts +297 -0
  529. package/src/ux-sim/mock-seat-pty-sequence-child.ts +21 -0
  530. package/src/ux-sim/mock-seat-pty-sequence.ts +206 -0
  531. package/src/ux-sim/next-tui-seat-scenarios.ts +631 -0
  532. package/src/ux-sim/onboarding-first-run-device.ts +269 -0
  533. package/src/ux-sim/pty-key-modifiers-device.ts +85 -0
  534. package/src/ux-sim/subagent-tools-device.ts +81 -0
  535. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +250 -0
  536. package/src/ux-sim/tty-foreground-steal-child.ts +21 -0
  537. package/src/version/packed-revision.json +1 -1
  538. package/apps/pwa/out/_next/static/chunks/1165.bad13fc9151a7288.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/13.02a07436dec15f89.js +0 -32
  540. package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +0 -41
  541. package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +0 -24
  542. package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +0 -74
  543. package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/1993-c0007b7ad0c0ef41.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/1c735de4.f993a30bbd3c57c4.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +0 -148
  553. package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/2625.5d870aa999f33db1.js +0 -34
  555. package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +0 -77
  556. package/apps/pwa/out/_next/static/chunks/2833-0fe47af99ed13c29.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +0 -62
  559. package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +0 -90
  560. package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +0 -36
  563. package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +0 -79
  565. package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/3f7c4ee5.3dde54f01a816613.js +0 -122
  567. package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/4441-875b97f5821ed58a.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +0 -286
  570. package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +0 -24
  573. package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/5154.a118f3957ed14e36.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +0 -23
  582. package/apps/pwa/out/_next/static/chunks/5483-dd5d7697f6bdb106.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +0 -287
  586. package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +0 -8
  593. package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +0 -27
  595. package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +0 -93
  597. package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/6866-79aa5b4e47cac6aa.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/6b89c8bd.24df687a820500b3.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +0 -149
  604. package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +0 -104
  605. package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/8219.baa715d1deee80e2.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/8256.e3ac8421a71f82f4.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +0 -226
  615. package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +0 -64
  617. package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +0 -115
  622. package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/967-2aa39b2d04b4c690.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/app/control/page-406b47745b53f269.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/morning/page-47c5d4db587266bd.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1f5a60f70cb4dd0c.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/outputs/page-bac7dee94e5eae4a.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/term/page-dc0a532f5b9196ec.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +0 -1
  686. /package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → uC-N0emedeNOFuaBQFv-I}/_ssgManifest.js +0 -0
@@ -7,13 +7,13 @@
7
7
  * - 기본은 SHADOW: 카드와 명령만 남기고 아무것도 띄우지 않는다. `--live` 일 때만 주입된 launcher 로 띄운다.
8
8
  * - 관측: `debug.log('task-agent', 'handed', {taskId, seat, checklistId, mode, runPriority})`.
9
9
  */
10
- import { execFileSync } from 'node:child_process';
10
+ import { execFile, 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
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
- import { validateUnitCalls } from '../graph-runner/runner.js';
16
+ import { runGraph, validateUnitCalls, type GraphRunOptions, type GraphRunState } from '../graph-runner/runner.js';
17
17
  import { parseGraphTemplateYaml } from '../self-implement/graph-yaml.js';
18
18
  import { resolveDaemonHarnessTarget } from '../intake-plane/harness-target.js';
19
19
  import { HARNESS_RUN_ID_ENV, mintRunId, normalizeRunId } from '../harness/harness-space.js';
@@ -25,14 +25,19 @@ import { checkCompletionEvidence, deliverableReceiptEvidence } from './completio
25
25
  import { judgeNextMove } from './judge.js';
26
26
  import { checklistDevVersion, listChecklist } from '../release-loop/checklist.js';
27
27
  import { loadRunLedger, runLedgerDir } from '../self-implement/run-ledger.js';
28
+ // Keep doctor-visit recording synchronous: updateTaskCard callers observe it before the transition returns.
29
+ import { recordTaskAgentNeedsOwnerVisit } from '../self-implement/doctor-visit.js';
28
30
  import { applyRunIdentityTag, applyRunIdentityTags, deriveBirthIdentity, parseRunIdentityTag, runIdentityFieldText, runIdentityQueuePriority, runPriorityClass, validateRunIdentity, type RunIdentity, type RunIdentityCell, type RunIdentityOrigin } from './run-identity.js';
29
31
  import { parseWorkOrder, renderWorkOrderGoal, WORK_ORDER_FILE_PATTERN, type WorkOrder } from './work-order.js';
30
32
  import { inspectPrelaunchAlreadyDone, type AlreadyDoneDecision, type AlreadyDoneCandidate,
31
33
  type PrelaunchGitRunnerForTest } from './prelaunch-already-done.js';
32
- import { draftReleaseComment } from '../self-dev/draft-triage-rules.js';
34
+ import { draftClaimComment, draftClaimRecordLive, draftClaimState, draftReleaseComment } from '../self-dev/draft-triage-rules.js';
33
35
  import { parseAskTargetPathHints, parseAskTargetPathHintsResult } from '../self-dev/launch-preflight-text.js';
34
- import { inspectGoalDoneBoundary } from '../self-implement/goal-author.js';
36
+ import { inspectGoalDoneBoundary, linesOutsideFencedCode } from '../self-implement/goal-author.js';
35
37
  import { INFLIGHT_REGISTRY_FILE, registerInflight } from '../pr-tool/inflight-registry.js';
38
+ import { taskParentRoleEnv } from './task-parent-role-llm.js';
39
+ import { runHarvestUnit, type ReviewInvocation } from './harvest-unit.js';
40
+ import { TASK_CARD_PREFIX } from './task-card-prefix.js';
36
41
 
37
42
  export interface ResolveHandTextDeps {
38
43
  cwd: string;
@@ -88,8 +93,8 @@ export function resolveHandText(text: string, deps: ResolveHandTextDeps = { cwd:
88
93
 
89
94
  export const TASK_SEATS = ['OP', 'TC', 'MK', 'UX'] as const;
90
95
  export type TaskSeat = typeof TASK_SEATS[number];
91
- /** 과제 카드 id 접두 — `task show <id>` 가 이 접두로 TOX 태스크와 갈린다. */
92
- export const TASK_CARD_PREFIX = 'ta-';
96
+ /** 과제 카드 id 접두 — `task show <id>` 가 이 접두로 TOX 태스크와 갈린다(정본 = task-card-prefix.ts). */
97
+ export { TASK_CARD_PREFIX };
93
98
  /** Pod Job 의 metadata.labels 에 붙일 카드 식별자 — 원장의 카드 id 와 정확히 같아야 한다. */
94
99
  export const TASK_CARD_LABEL = 'elanous.task-card';
95
100
  /**
@@ -133,8 +138,11 @@ export interface CompositionSelection {
133
138
  error?: string;
134
139
  }
135
140
 
141
+ /** 조합 저장소 루트(기본) — `graphs/work/<completion>.yaml` 는 이 루트에서 읽는다. */
142
+ export const COMPOSITION_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..', '..');
143
+
136
144
  /** 1판은 조합을 고르고 단위 해석 결과를 기록한다. 단위 실행은 2판의 몫이다. */
137
- export function selectTaskComposition(completion: CompletionKind, root = join(dirname(fileURLToPath(import.meta.url)), '..', '..')): CompositionSelection {
145
+ export function selectTaskComposition(completion: CompletionKind, root = COMPOSITION_ROOT): CompositionSelection {
138
146
  const file = `graphs/work/${completion}.yaml`;
139
147
  const path = join(root, file);
140
148
  let source: string;
@@ -198,6 +206,9 @@ export interface TaskCardEvent {
198
206
  verdict?: string | null; reviewed?: boolean | null; mustFix?: number | null; reviewRoute?: string | null;
199
207
  /** Exact bytes of the captured review stdout; repair must read the same resultPath and digest. */
200
208
  reviewSha256?: string;
209
+ /** HARNESS-FULL-GRAPH-NEXTMOVE — next-move 결정 순간 만든 수 id(간선·발사와 같은 값). `repair-launched` · `relaunch-launched`(일반 재발사) ·
210
+ * `repair-result`(결과 파일의 값이 카드와 짝지어졌을 때만 · NEXTMOVE-GENERAL-RELAUNCH-MOVEID) 줄에 싣는다. */
211
+ moveId?: string;
201
212
  }
202
213
  /** 카드 history 의 live-move 줄 이벤트 이름 — 상태 사유(«마지막 칸») 판정에서 뺀다. */
203
214
  export const LIVE_MOVE_HISTORY_EVENT = 'live-move';
@@ -262,6 +273,11 @@ export interface TaskCard {
262
273
  goalId?: string;
263
274
  /** `manual` = pr/goalId 를 사람이 적었다(`recordPieceRef`) — 런 묶기가 건드리지 않는다. */
264
275
  refSource?: 'manual';
276
+ /**
277
+ * DRAFT-CLAIM-AUTO-2-FU — 이 손이 그 draft 로 남긴 claim 기록. `body` 는 PR 에 달 «🔧 처리 중» 문면이고
278
+ * claim 이 성립한 손만 갖는다(수확이 머리를 확정하지 못하면 `body` 없이 `harvest` 사유만 남는다).
279
+ */
280
+ draftClaim?: TaskCardDraftClaimRecord;
265
281
  /** 조각 카드만 — ② 가 선행 착지 뒤 넘겼다(한 번만 · 같은 잠금 안에서 먼저 적는다). */
266
282
  handed?: { at: string; mode: 'shadow' | 'live'; claim?: string; error?: string };
267
283
  /**
@@ -301,6 +317,8 @@ export interface TaskCard {
301
317
  taLand?: true;
302
318
  /** TASKS-HAND-CHILD-LLM — `tasks hand --child-llm <provider>/<model> [--child-llm-effort <level>]` → 발사 인자 `--child-llm-provider/-model/-effort`. */
303
319
  childLlm?: TaskChildLlm;
320
+ /** Explicit parent role pins; the implementation child remains controlled by childLlm. */
321
+ parentRoleLlm?: string[];
304
322
  /** Dispatch difficulty, fixed at handoff so repair uses the same judgement. */
305
323
  tier?: '하' | '중' | '상' | '특';
306
324
  /**
@@ -313,7 +331,9 @@ export interface TaskCard {
313
331
  /** Same-PR repair launches; exact source head and worker result are retained for CAS and retry limits. */
314
332
  repairs?: Array<{ pr: number; head: string; branch: string; at: string; move: string; runId: string;
315
333
  resultPath: string; fromModel: string; toModel: string; status: 'requested' | 'unconfirmed' | 'failed' | 'applied';
316
- detail?: string; commit?: string; bundleSha256?: string; bundlePath?: string }>;
334
+ detail?: string; commit?: string; bundleSha256?: string; bundlePath?: string;
335
+ /** HARNESS-FULL-GRAPH-NEXTMOVE — next-move 결정 순간 만든 수 id. 이 칸 전 원장 줄엔 없다. */
336
+ moveId?: string }>;
317
337
  }
318
338
 
319
339
  /** 구현 자식 LLM 선택 — 하니스 `--child-llm-provider/--child-llm-model/--child-llm-effort` 로 그대로 넘긴다(검증 권위는 하니스). */
@@ -362,14 +382,295 @@ export function abandonedDraftReleaseNote(card: Pick<TaskCard, 'id' | 'status' |
362
382
 
363
383
  /** A uniquely launched code-PR card may own a draft through its PR or its opening run. */
364
384
  export function draftTaskOwner(cards: readonly TaskCard[], draft: { number: number; runId?: string | null }): TaskCard | undefined {
365
- const owners = cards.filter((card) => card.status === 'launched' && (card.completion ?? 'code-pr') === 'code-pr'
385
+ const owners = draftTaskOwners(cards, draft);
386
+ return owners.length === 1 ? owners[0] : undefined;
387
+ }
388
+
389
+ /**
390
+ * DRAFT-CLAIM-AUTO-2-FU — 그 draft 를 쥐고 있다고 말하는 카드 «전부». `draftTaskOwner` 는 이 목록이 한 장일 때만
391
+ * 주인을 돌려주므로, 두 장 이상이면 어느 쪽이 진짜인지 모른다 = 중복 claim.
392
+ */
393
+ export function draftTaskOwners(cards: readonly TaskCard[], draft: { number: number; runId?: string | null }): TaskCard[] {
394
+ return cards.filter((card) => card.status === 'launched' && (card.completion ?? 'code-pr') === 'code-pr'
366
395
  && card.seat && (card.runId || card.runChildId) && (cardPrNumber(card) === draft.number
367
396
  || (draft.runId && (card.runId === draft.runId || card.runChildId === draft.runId))));
368
- return owners.length === 1 ? owners[0] : undefined;
397
+ }
398
+
399
+ /** DRAFT-CLAIM-AUTO-2-FU — 손이 draft 하나를 잡을 때의 «지금» 관측값(라벨·갱신 시각은 호출자가 관측해 넘긴다). */
400
+ export interface HandTaskDraftClaim {
401
+ /** 관측한 draft PR 번호 — 손이 잡으려는 PR. 카드에 묶인 PR 과 같은 번호다. */
402
+ pr: number;
403
+ /** 그 PR 의 지금 라벨(claim·harvestable 판정 입력 · `draftClaimState`). */
404
+ labels: readonly string[];
405
+ /** 그 PR 의 마지막 갱신 시각 — 없으면 만료인지 아닌지 모르므로 claim 하지 않는다. */
406
+ updatedAt?: string;
407
+ /** 그 PR 을 연 런 id(카드 묶기 키 — `draftTaskOwner`). */
408
+ runId?: string | null;
409
+ /** 손 수확 — 리뷰 결과로 머리를 확정한 «뒤에만» claim 한다. */
410
+ harvest?: HandTaskDraftHarvest;
411
+ /** DRAFT-CLAIM-AUTO-2-FU — claim 문면을 «실제 PR 댓글»로 게시하는 포트. 생산 배선(`tasks hand --draft-claim <pr>`)이 gh 게시자를 준다. 없으면 `body` 를 카드에만 남긴다. */
412
+ postComment?: (pr: number, body: string) => Promise<string | undefined>;
413
+ }
414
+
415
+ /**
416
+ * DRAFT-CLAIM-AUTO-2-FU — 손 수확: 그 머리에서 리뷰를 다시 받아 수확이 성립할 때만 claim 한다.
417
+ * 생산 배선(`handDraftClaim`)이 관측한 PR 머리(`expectedHead`) ⊕ 포트의 리뷰 러너(`invokeReview`)로 조립한다.
418
+ */
419
+ export interface HandTaskDraftHarvest {
420
+ /** 리뷰를 요청한 머리(40-hex) — 없거나 지금 머리와 다르면 수확은 성립하지 않는다(claim 0). */
421
+ expectedHead?: string;
422
+ /** 리뷰 의도 문면(없으면 손 문면을 쓴다). */
423
+ reviewIntent?: string;
424
+ /** `elanous self review <pr> --json` 를 부르는 자리 — 호출자(관측 포트)가 준다. */
425
+ invokeReview: (args: { pr: string; intent: string }) => Promise<ReviewInvocation>;
426
+ }
427
+
428
+ /** DRAFT-CLAIM-AUTO-2-FU — 카드에 남는 claim 기록. */
429
+ export interface TaskCardDraftClaimRecord {
430
+ pr: number;
431
+ at: string;
432
+ /** 만료된 claim 을 다시 잡았나(= 재claim). */
433
+ reclaim: boolean;
434
+ /** PR 에 달 «🔧 처리 중» 문면 — claim 이 성립한 손만. */
435
+ body?: string;
436
+ /** shadow 는 게시 예약이 아니므로 live claim 을 막지 않는다. 옛 기록은 live 로 취급한다. */
437
+ mode?: 'shadow' | 'live';
438
+ /** DRAFT-CLAIM-AUTO-2-FU — 게시한 PR 댓글 위치(댓글 url·id · `postComment` 포트가 있는 생산 경로만). */
439
+ postedTo?: string;
440
+ /** 쥐고 있던 카드 id(관측됐을 때). */
441
+ ownerId?: string;
442
+ /** 손 수확 증거 — 머리를 확정하지 못했으면 `outcome`·`reason` 만 있고 `body` 는 없다. */
443
+ harvest?: { outcome: 'done' | 'rework' | 'needs-human' | 'failed'; headCommit?: string; reason?: string };
444
+ }
445
+
446
+ /** DRAFT-CLAIM-AUTO-2-FU — 이 손이 draft 를 잡아도 되나(중복 claim 거부 · 만료된 claim 만 재claim). */
447
+ export type DraftClaimJudgement =
448
+ | { ok: true; body: string; reclaim: boolean; ownerId?: string }
449
+ | { ok: false; reason: string; ownerId?: string };
450
+
451
+ /**
452
+ * DRAFT-CLAIM-AUTO-2-FU — 판정선: ⑴ 두 장 이상의 카드가 같은 draft 를 쥐고 있으면 거부(어느 쪽이 진짜인지 모른다),
453
+ * ⑵ 갱신 시각을 못 읽으면(`unobserved`) 만료인지 알 수 없으니 거부, ⑶ 살아 있는 claim 을 다른 카드가 쥐고 있으면 거부
454
+ * (중복 claim), ⑷ 다른 카드에 남은 «살아 있는» claim 기록(카드 `draftClaim`)이 같은 PR 을 쥐고 있으면 거부 —
455
+ * 연속된 손 호출이 «같은» draft 를 다시 claim 하지 못하게(launched 카드의 PR·런 소유권 가드만으는 부족하다),
456
+ * ⑸ «만료»로 관측된 claim 만 다시 잡는다(재claim 문면).
457
+ */
458
+ export function judgeDraftClaim(input: {
459
+ draft: { number: number; labels: readonly string[]; updatedAt?: string; runId?: string | null };
460
+ cards: readonly TaskCard[];
461
+ cardId: string;
462
+ seat?: TaskSeat;
463
+ now: Date;
464
+ }): DraftClaimJudgement {
465
+ const owners = draftTaskOwners(input.cards, input.draft);
466
+ if (owners.length > 1) {
467
+ return { ok: false, reason: `duplicate-claim: ${owners.map((card) => card.id).join(', ')} 가 같은 PR #${input.draft.number} 를 쥐고 있다` };
468
+ }
469
+ const owner = owners[0];
470
+ const state = draftClaimState(input.draft, input.now);
471
+ if (state === 'unobserved') {
472
+ return { ok: false, ...(owner ? { ownerId: owner.id } : {}), reason: `claim-unobserved: PR #${input.draft.number} 의 claim 시각을 못 읽었다` };
473
+ }
474
+ if (state === 'claimed' && owner?.id !== input.cardId) {
475
+ return {
476
+ ok: false,
477
+ ...(owner ? { ownerId: owner.id } : {}),
478
+ reason: `duplicate-claim: ${owner ? owner.id : '카드 원장 밖 주인'} 가 PR #${input.draft.number} 를 처리 중이다`,
479
+ };
480
+ }
481
+ const recordOwner = input.cards.find((card) => {
482
+ const record = card.draftClaim;
483
+ return card.id !== input.cardId && record !== undefined && record.pr === input.draft.number
484
+ && record.body !== undefined && record.mode !== 'shadow' && draftClaimRecordLive(record.at, input.now);
485
+ });
486
+ if (recordOwner) {
487
+ return { ok: false, ownerId: recordOwner.id, reason: `duplicate-claim: 카드 ${recordOwner.id} 가 PR #${input.draft.number} 의 claim 기록을 쥐고 있다` };
488
+ }
489
+ const reclaim = state === 'expired';
490
+ return {
491
+ ok: true,
492
+ reclaim,
493
+ ...(owner ? { ownerId: owner.id } : {}),
494
+ body: draftClaimComment(input.seat ?? input.cardId, input.now, reclaim ? '만료 claim 재claim — 자동' : undefined),
495
+ };
496
+ }
497
+
498
+ /** DRAFT-CLAIM-AUTO-2-FU — 그 draft 를 이미 다른 카드가 쥐고 있다(또는 만료인지 못 정한다). 이때 카드는 «쓰지 않는다». */
499
+ export class TaskDraftClaimRejectedError extends Error {
500
+ readonly cardId: string;
501
+ readonly reason: string;
502
+ constructor(cardId: string, reason: string) {
503
+ super(`draft claim 거부 (${cardId}): ${reason}`);
504
+ this.name = 'TaskDraftClaimRejectedError';
505
+ this.cardId = cardId;
506
+ this.reason = reason;
507
+ }
508
+ }
509
+
510
+ /**
511
+ * DRAFT-CLAIM-AUTO-2-FU — 손 수확(있으면) → claim 판정을 생산 진입점 안에서 닫는다.
512
+ *
513
+ * ⑴ 수확이 머리를 확정하지 못하면(`needs-human`·`failed`) claim 문면(`body`)을 만들지 않고 사유만 남긴다 —
514
+ * 다른 PR/낡은 머리 리뷰를 이 claim 에 붙이지 않는다. ⑵ 머리를 확정했으면 카드 원장(디스크)의 다른 카드와
515
+ * 견줘 중복·만료를 판정하고, 거부면 던진다(호출자가 카드를 쓰기 «전»에 멈춘다).
516
+ */
517
+ async function resolveHandDraftClaim(input: {
518
+ claim: HandTaskDraftClaim;
519
+ cards: readonly TaskCard[];
520
+ cardId: string;
521
+ seat?: TaskSeat;
522
+ now: Date;
523
+ ask: string;
524
+ }): Promise<TaskCardDraftClaimRecord> {
525
+ const { claim } = input;
526
+ const harvest = claim.harvest ? await runHarvestUnit({
527
+ ask: input.ask,
528
+ context: {
529
+ pr: claim.pr,
530
+ ...(claim.harvest.expectedHead !== undefined ? { expectedHead: claim.harvest.expectedHead } : {}),
531
+ reviewIntent: claim.harvest.reviewIntent ?? input.ask,
532
+ },
533
+ }, claim.harvest.invokeReview) : undefined;
534
+ const reason = harvest
535
+ ? typeof harvest.result.reason === 'string' ? harvest.result.reason
536
+ : typeof harvest.result.error === 'string' ? harvest.result.error : undefined
537
+ : undefined;
538
+ const harvestRecord: TaskCardDraftClaimRecord['harvest'] | undefined = harvest ? {
539
+ outcome: harvest.outcome,
540
+ ...(typeof harvest.result.headCommit === 'string' ? { headCommit: harvest.result.headCommit } : {}),
541
+ ...(reason !== undefined ? { reason } : {}),
542
+ } : undefined;
543
+ const at = input.now.toISOString();
544
+ if (harvest && harvest.outcome !== 'done' && harvest.outcome !== 'rework') {
545
+ try { debug.log('task-agent.draft-claim', 'harvest-unconfirmed', { card: input.cardId, pr: claim.pr, outcome: harvest.outcome, reason: reason ?? null }); } catch { /* fail-soft */ }
546
+ return { pr: claim.pr, at, reclaim: false, ...(harvestRecord ? { harvest: harvestRecord } : {}) };
547
+ }
548
+ const judgement = judgeDraftClaim({
549
+ draft: { number: claim.pr, labels: claim.labels,
550
+ ...(claim.updatedAt !== undefined ? { updatedAt: claim.updatedAt } : {}),
551
+ ...(claim.runId !== undefined ? { runId: claim.runId } : {}) },
552
+ cards: input.cards,
553
+ cardId: input.cardId,
554
+ ...(input.seat !== undefined ? { seat: input.seat } : {}),
555
+ now: input.now,
556
+ });
557
+ if (!judgement.ok) {
558
+ try { debug.log('task-agent.draft-claim', 'rejected', { card: input.cardId, pr: claim.pr, reason: judgement.reason }); } catch { /* fail-soft */ }
559
+ throw new TaskDraftClaimRejectedError(input.cardId, judgement.reason);
560
+ }
561
+ try { debug.log('task-agent.draft-claim', judgement.reclaim ? 'reclaimed' : 'claimed', { card: input.cardId, pr: claim.pr, ownerId: judgement.ownerId ?? null }); } catch { /* fail-soft */ }
562
+ return {
563
+ pr: claim.pr, at, reclaim: judgement.reclaim, body: judgement.body,
564
+ ...(judgement.ownerId !== undefined ? { ownerId: judgement.ownerId } : {}),
565
+ ...(harvestRecord ? { harvest: harvestRecord } : {}),
566
+ };
369
567
  }
370
568
 
371
569
  interface TaskAgentStateFile { tasks?: Record<string, TaskCard>; [key: string]: unknown }
372
570
 
571
+ /**
572
+ * DRAFT-CLAIM-AUTO-2-FU — 손이 draft 를 잡을 때 필요한 관측·게시·수확 리뷰 포트(생산 기본값은 gh CLI ⊕ `elanous self
573
+ * review` 러너 · 시험은 가짜 포트로 몽크). `handDraftClaim` 이 이 포트들로 `draftClaim`(⊕ 손 수확)을 조립한다.
574
+ */
575
+ export interface DraftClaimGhPorts {
576
+ /** PR 을 관측해 라벨·갱신 시각(·런 id)·머리(headRefOid · 손 수확 `expectedHead` 근거)을 읽는다. */
577
+ observePr: (pr: number) => Promise<{ labels: readonly string[]; updatedAt?: string; runId?: string | null; head?: string }>;
578
+ /** PR 댓글을 게시한다 — 게시 위치(댓글 url·id)를 돌려준다. */
579
+ postComment: (pr: number, body: string) => Promise<string | undefined>;
580
+ /**
581
+ * DRAFT-CLAIM-AUTO-2-FU — 손 수확 리뷰 러너: `elanous self review <pr> --json` 관측 원문(stdout·stderr·exitCode)을
582
+ * 돌려준다(판정은 `runHarvestUnit` 몫). 주면 생산 배선이 관측한 PR 머리와 함께 손 수확을 조립한다 — 없으면 수확 없이 claim 한다.
583
+ */
584
+ runReview?: (args: { pr: string; intent: string }) => Promise<ReviewInvocation>;
585
+ }
586
+
587
+ function ghExec(args: readonly string[]): Promise<string> {
588
+ return new Promise((done, fail) => {
589
+ execFile('gh', [...args], { encoding: 'utf8', maxBuffer: 32 * 1024 * 1024 }, (error, stdout) => {
590
+ if (error) fail(new Error(`gh ${args.join(' ')} 실패: ${error.message}`));
591
+ else done(String(stdout));
592
+ });
593
+ });
594
+ }
595
+
596
+ /**
597
+ * DRAFT-CLAIM-AUTO-2-FU — 손 수확 리뷰 러너(생산 기본값): 지금 도는 진입점으로 같은 우주의
598
+ * `elanous self review <pr> --json --intent <intent>` 를 «기다려» 관측 원문(stdout·stderr·exitCode)을 돌려준다
599
+ * (argv 는 `liveReviewArgs` 정본 — `defaultRequestReview` 가 떼어 띄우는 것과 같다). 판정·파싱은 `runHarvestUnit` 몫이다.
600
+ */
601
+ export async function defaultDraftClaimReviewRunner(args: { pr: string; intent: string }): Promise<ReviewInvocation> {
602
+ const { ELANOUS_CLI_ENTRY } = await import('../cli/tasks-cli.js');
603
+ const { getElanousConfigDirOverride } = await import('../elanous-config-dir.js');
604
+ const { liveReviewArgs } = await import('./live-moves.js');
605
+ const configDir = getElanousConfigDirOverride() ?? effectiveInstanceRoot();
606
+ const argv = liveReviewArgs(ELANOUS_CLI_ENTRY, configDir, Number(args.pr), args.intent);
607
+ return await new Promise<ReviewInvocation>((done) => {
608
+ execFile(process.execPath, argv, { encoding: 'utf8', maxBuffer: 32 * 1024 * 1024 }, (error, stdout, stderr) => {
609
+ const exitCode = error ? (typeof (error as { code?: unknown }).code === 'number' ? (error as { code: number }).code : 1) : 0;
610
+ done({ stdout: String(stdout), stderr: String(stderr), exitCode });
611
+ });
612
+ });
613
+ }
614
+
615
+ /** 생산 기본 포트 — gh CLI 로 PR 을 관측(라벨·갱신 시각·머리)하고 댓글을 게시하며, 손 수확 리뷰는 같은 우주의 `elanous self review` 러너로 돌린다(자격·원격 저장소는 각 설정을 따른다). */
616
+ export function defaultDraftClaimGhPorts(): DraftClaimGhPorts {
617
+ return {
618
+ async observePr(pr: number) {
619
+ let parsed: Record<string, unknown>;
620
+ try {
621
+ parsed = JSON.parse(await ghExec(['pr', 'view', String(pr), '--json', 'labels,updatedAt,headRefOid'])) as Record<string, unknown>;
622
+ } catch (error) {
623
+ throw new Error(`PR #${pr} 관측 실패(gh pr view): ${error instanceof Error ? error.message : String(error)}`);
624
+ }
625
+ const labels = Array.isArray(parsed.labels) ? parsed.labels
626
+ .map((label) => typeof label === 'string' ? label : (label as { name?: unknown } | null)?.name)
627
+ .filter((name): name is string => typeof name === 'string') : [];
628
+ const updatedAt = typeof parsed.updatedAt === 'string' ? parsed.updatedAt : undefined;
629
+ const head = typeof parsed.headRefOid === 'string' && /^[0-9a-f]{40}$/i.test(parsed.headRefOid) ? parsed.headRefOid : undefined;
630
+ return { labels, ...(updatedAt !== undefined ? { updatedAt } : {}), ...(head !== undefined ? { head } : {}) };
631
+ },
632
+ async postComment(pr: number, body: string) {
633
+ await ghExec(['pr', 'comment', String(pr), '--body', body]);
634
+ return `PR #${pr} 댓글`;
635
+ },
636
+ // DRAFT-CLAIM-AUTO-2-FU — 손 수확 리뷰 러너(생산): handDraftClaim 이 관측한 머리와 함께 조립한다.
637
+ runReview: defaultDraftClaimReviewRunner,
638
+ };
639
+ }
640
+
641
+ /**
642
+ * DRAFT-CLAIM-AUTO-2-FU — 생산 진입점 배선: 관측 포트로 PR 을 읽어 `draftClaim` 을 «조립해» `handTask` 에 넘긴다
643
+ * (`tasks hand --draft-claim <pr>` 가 부른다). 손 수확도 여기서 조립한다 — 관측한 PR 머리(`expectedHead`) ⊕ 포트의
644
+ * 리뷰 러너(`invokeReview` · 생산 기본값 `elanous self review <pr> --json`)로 `runHarvestUnit` 을 거치게 한다.
645
+ * 시험도 이 경로로 돌며 gh·리뷰 포트만 몽크한다 — `draftClaim` 을 직접 주입하지 않는다. 호출자가 직접 준 `harvest`
646
+ * 가 우선(시험 주입)이고 리뷰 러너가 없는 포트는 종전대로 수확 없이 claim 한다(기본 동작 보존).
647
+ */
648
+ export async function handDraftClaim(input: {
649
+ pr: number;
650
+ gh: DraftClaimGhPorts;
651
+ /** DRAFT-CLAIM-AUTO-2-FU — 직접 주는 수확(시험 주입). 안 주면 배선이 관측한 머리 ⊕ 포트의 리뷰 러너로 조립한다. */
652
+ harvest?: HandTaskDraftHarvest;
653
+ } & Omit<Parameters<typeof handTask>[0], 'draftClaim'>): Promise<Awaited<ReturnType<typeof handTask>>> {
654
+ const { pr, gh, harvest, ...handOpts } = input;
655
+ const observed = await gh.observePr(pr);
656
+ // DRAFT-CLAIM-AUTO-2-FU — 손 수확 조립(생산): 관측한 PR 머리(expectedHead) + 포트의 리뷰 러너(invokeReview).
657
+ const handHarvest: HandTaskDraftHarvest | undefined = harvest ?? (gh.runReview === undefined ? undefined : {
658
+ ...(observed.head !== undefined ? { expectedHead: observed.head } : {}),
659
+ invokeReview: gh.runReview,
660
+ });
661
+ return handTask({
662
+ ...handOpts,
663
+ draftClaim: {
664
+ pr,
665
+ labels: observed.labels,
666
+ ...(observed.updatedAt !== undefined ? { updatedAt: observed.updatedAt } : {}),
667
+ ...(observed.runId !== undefined ? { runId: observed.runId } : {}),
668
+ ...(handHarvest !== undefined ? { harvest: handHarvest } : {}),
669
+ postComment: gh.postComment,
670
+ },
671
+ });
672
+ }
673
+
373
674
  function isGitWorkTree(path: string): boolean {
374
675
  try {
375
676
  return execFileSync('git', ['rev-parse', '--is-inside-work-tree'], { cwd: path, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim() === 'true';
@@ -427,16 +728,35 @@ export function writeTaskCards(path: string, cards: readonly TaskCard[]): void {
427
728
  }
428
729
 
429
730
  /** 카드 하나를 잠금 안에서 읽고 고쳐 쓴다 — `update` 가 undefined 를 돌려주면 쓰지 않는다. 쓴(또는 그대로인) 카드를 돌려준다. */
430
- export function updateTaskCard(path: string, id: string, update: (card: TaskCard | undefined, tasks: Readonly<Record<string, TaskCard>>) => TaskCard | undefined): TaskCard | undefined {
431
- return withFileLockSync(`${path}.lock`, () => {
731
+ export function updateTaskCard(path: string, id: string, update: (card: TaskCard | undefined, tasks: Readonly<Record<string, TaskCard>>) => TaskCard | undefined,
732
+ options: { doctorLedgerDir?: string } = {}): TaskCard | undefined {
733
+ let needsOwner: { runId: string; at: string; reason: string; transitionIndex: number } | undefined;
734
+ const result = withFileLockSync(`${path}.lock`, () => {
432
735
  const disk = readState(path);
433
736
  const current = disk.tasks?.[id];
434
737
  const next = update(current, disk.tasks ?? {});
435
738
  if (!next) return current;
739
+ const transitionIndex = next.history.length - 1;
740
+ const last = next.history[transitionIndex];
741
+ if (current?.status === 'launched' && next.status === 'failed' && next.runId
742
+ && next.history.length > (current?.history.length ?? 0) && last?.event === 'failed'
743
+ && last.detail?.startsWith('failed/needs-owner')) {
744
+ needsOwner = { runId: next.runId, at: last.at, reason: last.detail, transitionIndex };
745
+ }
436
746
  mkdirSync(dirname(path), { recursive: true });
437
747
  writeFileSync(path, JSON.stringify({ ...disk, tasks: { ...(disk.tasks ?? {}), [id]: next } }));
438
748
  return next;
439
749
  });
750
+ if (needsOwner) {
751
+ try {
752
+ const visit = recordTaskAgentNeedsOwnerVisit({ ...needsOwner, cardId: id, dir: options.doctorLedgerDir });
753
+ debug.log('task-agent', 'doctor-visit', { card: id, runId: needsOwner.runId, status: visit.status });
754
+ } catch (error) {
755
+ debug.log('task-agent', 'doctor-visit-failed', { card: id, runId: needsOwner.runId,
756
+ reason: error instanceof Error ? error.message : String(error) });
757
+ }
758
+ }
759
+ return result;
440
760
  }
441
761
 
442
762
  export function readTaskCard(id: string, path = taskAgentStatePath()): TaskCard | undefined {
@@ -607,6 +927,7 @@ export interface HandTaskOptions {
607
927
  /** TASKS-HAND-CHILD-LLM — `<provider>/<model>`(`parseChildLlm`) ⊕ 선택 추론 노력. effort 만 주면 거부. */
608
928
  childLlm?: string;
609
929
  childLlmEffort?: string;
930
+ parentRoleLlm?: string[];
610
931
  tier?: TaskCard['tier'];
611
932
  /** TIER-SPLIT-BEFORE-LAUNCH — 조각 카드에 싣는 분해 연결(`tier-split.ts` 만 준다). */
612
933
  tierSplit?: TaskCard['tierSplit'];
@@ -627,6 +948,11 @@ export interface HandTaskOptions {
627
948
  compositionRoot?: string;
628
949
  /** `--live` 일 때만 불린다. */
629
950
  launcher?: TaskLauncher;
951
+ /**
952
+ * 2판 — launcher 'graph-run' 조합을 실제 graph run 으로 발사한다(기본 = src/graph-runner/runner.ts runGraph).
953
+ * 시험은 이 seam 을 주입해 발사 인자(선택된 조합 경로 ⊕ GraphRunOptions)를 'calls' capture 로 검증한다.
954
+ */
955
+ graphRunner?: (path: string, options: GraphRunOptions) => Promise<GraphRunState>;
630
956
  /** Deterministic contract seam; production uses the pinned-main verifier. */
631
957
  prelaunchInspector?: (text: string, projectTarget?: string) => AlreadyDoneDecision;
632
958
  /** Test-only: inject Git calls into the production verifier; no CLI/config surface. */
@@ -640,6 +966,12 @@ export interface HandTaskOptions {
640
966
  landed?: ReadonlySet<string>;
641
967
  /** 카드에 그대로 싣는 칸(② 의 넘김 표지·착지 근거) — handTask 가 카드를 새로 적을 때 지워지지 않게. */
642
968
  cardFields?: Pick<TaskCard, 'pr' | 'goalId' | 'handed'>;
969
+ /**
970
+ * DRAFT-CLAIM-AUTO-2-FU — 손이 잡으려는 draft(PR)의 «지금» 관측값(라벨·갱신 시각·리뷰 러너).
971
+ * 주면 `handTask` 가 손 수확(있으면) → `judgeDraftClaim` 을 거쳐 카드 `draftClaim` 에 기록한다. 거부면
972
+ * 카드를 쓰기 전에 `TaskDraftClaimRejectedError`. 안 주면 종전과 똑같이 claim 을 하지 않는다(기본 동작 보존).
973
+ */
974
+ draftClaim?: HandTaskDraftClaim;
643
975
  /**
644
976
  * 있으면 카드 쓰기마다 잠금 안에서 디스크 카드를 보고 참일 때만 쓴다(② 의 claim 소유 확인).
645
977
  * 거짓이면 쓰지 않고 `TaskCardSupersededError` — 다른 넘김이 그 카드를 가져갔다(발사 전이면 발사하지 않는다).
@@ -688,6 +1020,26 @@ export function dispatchDeliverableCompletion(id: string, input: { ref: string;
688
1020
  return closed;
689
1021
  }
690
1022
 
1023
+ /**
1024
+ * ENTRANCE-EVIDENCE-COMMAND-ONLY — 증거 명령 줄의 «형태» 판정. 기존 TA-HAND-PREFLIGHT 의 계약 줄 «존재» 검사
1025
+ * (`inspectGoalDoneBoundary`)와 구분된다: 세 경계 줄이 이미 갖춰진 골에서 증거 명령 줄의 값이 명령 원문인지만 본다.
1026
+ * 설명 접미(예: `→ 0 fail`)와 백틱 장식은 줄마다 이유를 붙여 거부한다. 빈 값·누락은 존재 검사 몫이다.
1027
+ */
1028
+ const GOAL_EVIDENCE_COMMAND_LINE = /^\s*(?:[-*]\s*)?완료 경계 증거 명령\s*:\s*(.*?)\s*$/;
1029
+ const GOAL_EVIDENCE_COMMAND_DESCRIPTION_SUFFIX = /->|→/;
1030
+ const GOAL_EVIDENCE_COMMAND_BACKTICK_DECORATION = /`/;
1031
+
1032
+ function goalEvidenceCommandFormViolations(document: string): string[] {
1033
+ const violations: string[] = [];
1034
+ for (const line of linesOutsideFencedCode(document)) {
1035
+ const value = GOAL_EVIDENCE_COMMAND_LINE.exec(line.text)?.[1];
1036
+ if (value === undefined || !value.trim()) continue;
1037
+ if (GOAL_EVIDENCE_COMMAND_BACKTICK_DECORATION.test(value)) violations.push(`백틱 장식: ${value}`);
1038
+ else if (GOAL_EVIDENCE_COMMAND_DESCRIPTION_SUFFIX.test(value)) violations.push(`설명 접미: ${value}`);
1039
+ }
1040
+ return violations;
1041
+ }
1042
+
691
1043
  export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
692
1044
  const text = opts.text.trim();
693
1045
  if (!text) throw new Error('과제 한 줄이 비어 있다');
@@ -720,11 +1072,19 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
720
1072
  launcher: 'hand',
721
1073
  }, birthTags);
722
1074
  const childLlm = opts.childLlm !== undefined ? parseChildLlm(opts.childLlm, opts.childLlmEffort) : undefined;
1075
+ const parentRoleEnv = taskParentRoleEnv(opts.parentRoleLlm ?? []); // validate before writing the card
723
1076
  const completion = opts.completion ?? 'code-pr';
724
1077
  const selected = selectTaskComposition(completion, opts.compositionRoot);
725
- const selectionFailure = !selected.composition ? `조합 없음: graphs/work/${completion}.yaml`
726
- : selected.error ?? (completion !== 'code-pr' || selected.launcher !== 'harness-say'
727
- ? `조합 실행기 없음: ${selected.composition.file} (1판은 code-pr harness-say만 발사)` : undefined);
1078
+ // 2판 — launcher 'graph-run' 조합(단위 해석까지 완료)은 실제 graph run 으로 발사한다. 더 이상 거부하지 않는다.
1079
+ const graphRun = selected.composition && selected.launcher === 'graph-run' && !selected.error && selected.unitsResolved
1080
+ ? selected.composition : undefined;
1081
+ const graphRunPath = graphRun ? join(opts.compositionRoot ?? COMPOSITION_ROOT, graphRun.file) : undefined;
1082
+ const selectionFailure = graphRun ? undefined
1083
+ : !selected.composition ? `조합 없음: graphs/work/${completion}.yaml`
1084
+ : selected.error ?? (selected.launcher === 'graph-run' && !selected.unitsResolved
1085
+ ? `조합 단위 미해석: ${selected.composition.file} — 대상 unit: ${selected.missingUnits.length ? selected.missingUnits.join(', ') : '해석 실패'} (graph-run 발사는 단위 해석이 필요하다)`
1086
+ : completion !== 'code-pr' || selected.launcher !== 'harness-say'
1087
+ ? `조합 실행기 없음: ${selected.composition.file} (발사 가능한 launcher: code-pr harness-say · graph-run)` : undefined);
728
1088
  let project: TaskCard['project'];
729
1089
  let targetIsGit: boolean | null = null;
730
1090
  if (opts.project) {
@@ -743,7 +1103,15 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
743
1103
  const now = (opts.now ?? (() => new Date()))();
744
1104
  const id = opts.id ?? `${TASK_CARD_PREFIX}${now.toISOString().slice(0, 10).replaceAll('-', '')}-${randomBytes(3).toString('hex')}`;
745
1105
  const mode = opts.live ? 'live' : 'shadow';
746
- const card: TaskCard = {
1106
+ // DRAFT-CLAIM-AUTO-2-FU — claim 은 카드를 쓰기 «전»에 판정한다(거부면 원장에 아무것도 남기지 않는다).
1107
+ // 견줄 상대는 카드 원장(디스크)의 다른 카드다 — 손이 들고 있는 사본이 아니라 정본을 본다.
1108
+ const draftClaim = opts.draftClaim
1109
+ ? await resolveHandDraftClaim({
1110
+ claim: opts.draftClaim, cards: Object.values(readState(path).tasks ?? {}), cardId: id,
1111
+ ...(opts.seat !== undefined ? { seat: opts.seat } : {}), now, ask: text,
1112
+ })
1113
+ : undefined;
1114
+ let card: TaskCard = {
747
1115
  id, text,
748
1116
  ...(!targetPathHints.labelMissing ? { targetPaths } : {}),
749
1117
  ...(opts.seat ? { seat: opts.seat } : {}),
@@ -758,24 +1126,57 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
758
1126
  ...(opts.milestone ? { milestone: opts.milestone } : {}),
759
1127
  ...(opts.taLand === true ? { taLand: true as const } : {}),
760
1128
  ...(childLlm ? { childLlm } : {}),
1129
+ ...(opts.parentRoleLlm?.length ? { parentRoleLlm: [...opts.parentRoleLlm] } : {}),
761
1130
  ...(opts.tier ? { tier: opts.tier } : {}),
762
1131
  ...(opts.tierSplit ? { tierSplit: opts.tierSplit } : {}),
763
1132
  ...(identity ? { identity } : {}),
764
1133
  createdAt: now.toISOString(),
765
1134
  status: selectionFailure || tierSplitBlocked !== undefined ? 'failed' : 'handed',
766
- history: selectionFailure ? [{ at: now.toISOString(), event: !selected.composition ? 'composition-missing'
767
- : selected.error ? 'composition-invalid' : 'composition-launcher-unavailable', detail: selectionFailure }]
768
- : tierSplitBlocked !== undefined ? [{ at: now.toISOString(), event: 'tier-split-failed', detail: `tier-split-failed: ${tierSplitBlocked}` }] : [],
1135
+ history: [
1136
+ ...(selectionFailure ? [{ at: now.toISOString(), event: !selected.composition ? 'composition-missing'
1137
+ : selected.error ? 'composition-invalid' : 'composition-launcher-unavailable', detail: selectionFailure }] : []),
1138
+ ...(tierSplitBlocked !== undefined ? [{ at: now.toISOString(), event: 'tier-split-failed', detail: `tier-split-failed: ${tierSplitBlocked}` }] : []),
1139
+ ],
769
1140
  ...(opts.mission ? { mission: opts.mission, after: [...(opts.after ?? [])] } : {}),
770
1141
  ...(opts.cardFields?.pr !== undefined ? { pr: opts.cardFields.pr } : {}),
771
1142
  ...(opts.cardFields?.goalId !== undefined ? { goalId: opts.cardFields.goalId } : {}),
772
1143
  ...(opts.cardFields?.handed !== undefined ? { handed: opts.cardFields.handed } : {}),
1144
+ ...(draftClaim ? { draftClaim } : {}),
773
1145
  };
774
- const move = selectionFailure ? undefined : nextMoveFor(card, opts.landed);
1146
+ // 2판 graph-run 조합의 다음 수는 실제 graph run — harness say 인자를 조립하지 않는다.
1147
+ const move = graphRun && graphRunPath ? { kind: 'launch' as const, command: ['graph', 'run', graphRunPath], reason: `조합 launcher graph-run — ${graphRun.file}` } satisfies TaskCardMove
1148
+ : selectionFailure ? undefined : nextMoveFor(card, opts.landed);
775
1149
  // 분해 실패로 막은 카드는 wait(failed 사유)가 정답이다 — 던지지 않고 카드를 적은 뒤 발사 0 으로 돌아간다.
776
1150
  if (move && move.kind !== 'launch' && tierSplitBlocked === undefined) throw new Error(`발사할 수 없는 과제다 — ${move.reason}`);
777
1151
  const guard = opts.writeGuard;
778
1152
  const writeCard = (target: string, next: TaskCard): void => {
1153
+ if (next.draftClaim?.body !== undefined && opts.draftClaim) {
1154
+ let written = false;
1155
+ const saved = updateTaskCard(target, next.id, (current, tasks) => {
1156
+ if (guard && !guard(current)) return undefined;
1157
+ // 같은 파일 잠금 안에서 판정과 기록을 마친다. 댓글은 잠금 밖에서 기록 성공 후 게시한다.
1158
+ const judgement = judgeDraftClaim({
1159
+ draft: { number: opts.draftClaim!.pr, labels: opts.draftClaim!.labels,
1160
+ ...(opts.draftClaim!.updatedAt !== undefined ? { updatedAt: opts.draftClaim!.updatedAt } : {}),
1161
+ ...(opts.draftClaim!.runId !== undefined ? { runId: opts.draftClaim!.runId } : {}) },
1162
+ cards: Object.values(tasks), cardId: next.id,
1163
+ ...(opts.seat !== undefined ? { seat: opts.seat } : {}), now,
1164
+ });
1165
+ if (!judgement.ok) throw new TaskDraftClaimRejectedError(next.id, judgement.reason);
1166
+ written = true;
1167
+ const claim: TaskCardDraftClaimRecord = { ...next.draftClaim!, body: judgement.body, reclaim: judgement.reclaim, mode,
1168
+ ...(judgement.ownerId !== undefined ? { ownerId: judgement.ownerId } : {}) };
1169
+ const { pr: _stalePr, goalId: _staleGoal, refSource: _staleSource, ...base } = next;
1170
+ const evidence = current ?? next;
1171
+ return { ...base, draftClaim: claim,
1172
+ ...(evidence.pr !== undefined ? { pr: evidence.pr } : {}),
1173
+ ...(evidence.goalId !== undefined ? { goalId: evidence.goalId } : {}),
1174
+ ...(evidence.refSource ? { refSource: evidence.refSource } : {}) };
1175
+ });
1176
+ if (!written) throw new TaskCardSupersededError(next.id);
1177
+ if (saved) card = saved;
1178
+ return;
1179
+ }
779
1180
  if (!guard) { writeTaskCards(target, [next]); return; }
780
1181
  const owned = { ok: false };
781
1182
  // 착지 근거(pr·goalId)는 `recordPieceRef` 소유 — claim 뒤에 적힌 최신 근거를 디스크에서 이어 받는다.
@@ -790,12 +1191,17 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
790
1191
  };
791
1192
  // Production Pod launches use the remote-parent lint's shared boundary judge.
792
1193
  // Injected launchers are test seams and opt in explicitly at the contract test.
793
- if (opts.live && opts.preflightGoalDoneBoundary && !selectionFailure && move?.kind === 'launch') {
1194
+ if (opts.live && opts.preflightGoalDoneBoundary && !selectionFailure && tierSplitBlocked === undefined && move?.kind === 'launch') {
794
1195
  readTaskAgentState(path);
795
1196
  const { missing } = inspectGoalDoneBoundary(text);
796
1197
  if (missing.length > 0) {
797
1198
  throw new Error(`goal-revision-required: 완료 경계 누락 ${missing.join(' · ')} — 골 문면에 완료 경계 코드·완료 경계 실물·완료 경계 증거 명령을 적은 뒤 다시 넘기세요`);
798
1199
  }
1200
+ // ENTRANCE-EVIDENCE-COMMAND-ONLY — 존재 검사와 구분된 형태 판정: 증거 명령 줄은 명령 원문만 받는다.
1201
+ const formViolations = goalEvidenceCommandFormViolations(text);
1202
+ if (formViolations.length > 0) {
1203
+ throw new Error(`goal-revision-required: 완료 경계 증거 명령은 명령 원문이어야 한다 ${formViolations.join(' · ')} — 증거 명령 줄에 설명 접미(예: → 0 fail)나 백틱 장식을 붙이지 말고 명령만 적은 뒤 다시 넘기세요`);
1204
+ }
799
1205
  }
800
1206
  writeCard(path, card);
801
1207
  try { debug.log('task-agent.hand', 'target-paths', { card: id, count: targetPaths.length, labelMissing: targetPathHints.labelMissing }); } catch { /* fail-soft */ }
@@ -804,14 +1210,62 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
804
1210
  unitsResolved: selected.unitsResolved, missingUnits: selected.missingUnits,
805
1211
  ...(selected.error ? { error: selected.error } : {}),
806
1212
  }); } catch { /* fail-soft */ }
1213
+ if (tierSplitBlocked !== undefined) return { card, move: move ?? nextMoveFor(card), mode, launched: false, ...(project ? { cwd: project.target } : {}) };
807
1214
  if (selectionFailure) throw new Error(`${selectionFailure} (카드 ${id})`);
808
- if (tierSplitBlocked !== undefined && move) return { card, move, mode, launched: false, ...(project ? { cwd: project.target } : {}) };
809
1215
  if (!move || move.kind !== 'launch') throw new Error('조합 선택 뒤 발사 수가 없다');
1216
+ if (opts.live && opts.draftClaim?.postComment && card.draftClaim?.body !== undefined) {
1217
+ let postedTo: string | undefined;
1218
+ try {
1219
+ postedTo = await opts.draftClaim.postComment(opts.draftClaim.pr, card.draftClaim.body);
1220
+ } catch (error) {
1221
+ // 댓글이 없으면 «살아 있는» 예약도 남기지 않는다. 다음 손이 다시 claim 할 수 있다.
1222
+ card = updateTaskCard(path, card.id, (current) => current?.draftClaim
1223
+ ? { ...current, draftClaim: { ...current.draftClaim, body: undefined } } : undefined) ?? card;
1224
+ throw error;
1225
+ }
1226
+ if (postedTo !== undefined) {
1227
+ card = updateTaskCard(path, card.id, (current) => current?.draftClaim
1228
+ ? { ...current, draftClaim: { ...current.draftClaim, postedTo } } : undefined) ?? card;
1229
+ }
1230
+ try { debug.log('task-agent.draft-claim', 'comment-posted', { card: id, pr: opts.draftClaim.pr,
1231
+ ...(postedTo !== undefined ? { postedTo } : {}) }); } catch { /* fail-soft */ }
1232
+ }
810
1233
  try { debug.log('task-agent', 'handed', { taskId: id, seat: card.seat ?? null, checklistId: card.checklistId ?? null, mode, projectId: project?.id ?? null, targetIsGit, taLand: card.taLand === true, runPriority: card.identity ? runPriorityClass(card.identity) : null }); } catch { /* fail-soft */ }
811
1234
  if (childLlm) {
812
1235
  try { debug.log('task-agent', 'child-llm', { taskId: id, input: opts.childLlm, provider: childLlm.provider, model: childLlm.model, effort: childLlm.effort ?? null, mode }); } catch { /* fail-soft */ }
813
1236
  }
814
1237
  if (mode === 'shadow') return { card, move, mode, launched: false, ...(project ? { cwd: project.target } : {}) };
1238
+ // 2판 — launcher 'graph-run' 조합은 launcher(harness say 발사기) 대신 실제 graph run 진입점(runGraph)으로 발사한다.
1239
+ if (graphRun && graphRunPath) {
1240
+ const runId = mintRunId();
1241
+ const launchId = newLaunchUtteranceId();
1242
+ recordLaunchUtterance({ source: 'hand', utterance: opts.text, launchId });
1243
+ let state: GraphRunState;
1244
+ try {
1245
+ state = await (opts.graphRunner ?? runGraph)(graphRunPath, { runId, input: { ask: text }, quiet: true });
1246
+ } catch (error) {
1247
+ // 조합 파일·대상 node가 없으면 runGraph 가 구체 사유로 던진다 — 임의 성공 처리하지 않는다.
1248
+ const reason = `graph run 실패: ${error instanceof Error ? error.message : String(error)}`;
1249
+ const failed: TaskCard = { ...card, status: 'launch-failed', runId, launchId,
1250
+ history: [...card.history, { at: (opts.now ?? (() => new Date()))().toISOString(), event: 'launch-failed', detail: reason, runId }] };
1251
+ writeCard(path, failed);
1252
+ try { debug.log('task-agent', 'launch-failed', { taskId: id, seat: card.seat ?? null, reason }); } catch { /* fail-soft */ }
1253
+ throw new TaskLaunchError(failed, reason);
1254
+ }
1255
+ const at = (opts.now ?? (() => new Date()))().toISOString();
1256
+ const ok = state.status === 'done';
1257
+ // 실패 종료도 구체 blocker(종료 상태·이유·마지막 node)를 기록한다 — 임의 성공 처리하지 않는다.
1258
+ const blocker = ok ? undefined : `graph run 종료 상태 ${state.status}${state.reason ? ` — ${state.reason}` : ''}`
1259
+ + `${state.nodes.length ? ` — 마지막 node ${state.nodes.at(-1)?.nodeId} (ok=${state.nodes.at(-1)?.ok})` : ' — node 없음'}`;
1260
+ const launchedGraph: TaskCard = { ...card, status: ok ? 'launched' : 'failed', runId: state.runId, launchId,
1261
+ history: [...card.history,
1262
+ { at, event: 'launch', detail: `graph run ${graphRunPath} (run ${state.runId})` },
1263
+ { at, event: 'run-bound', detail: state.runId, runId: state.runId },
1264
+ ...(blocker ? [{ at, event: 'graph-run-failed', detail: blocker, runId: state.runId }] : [])] };
1265
+ writeCard(path, launchedGraph);
1266
+ try { debug.log('task-agent', 'launched', { taskId: id, seat: card.seat ?? null, runId: state.runId }); } catch { /* fail-soft */ }
1267
+ return { card: launchedGraph, move, mode, launched: true, ...(project ? { cwd: project.target } : {}) };
1268
+ }
815
1269
  if (!opts.launcher) throw new Error('--live 인데 launcher 가 없다');
816
1270
  let prelaunch: AlreadyDoneDecision;
817
1271
  try { prelaunch = completion === 'code-pr'
@@ -832,6 +1286,7 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
832
1286
  const launchId = newLaunchUtteranceId();
833
1287
  recordLaunchUtterance({ source: 'hand', utterance: opts.text, launchId });
834
1288
  const context: TaskLaunchContext = { runId, launchId, launchUtterance: opts.text, env: { [HARNESS_RUN_ID_ENV]: runId, ELANOUS_TASK_CARD_ID: card.id,
1289
+ ...parentRoleEnv,
835
1290
  ...(cardPrNumber(card) ? { ELANOUS_TASK_BOUND_PR: String(cardPrNumber(card)) } : {}),
836
1291
  ...(card.checklistId ? { ELANOUS_POD_SLOT_ID: card.checklistId } : {}),
837
1292
  ...(card.seat ? { ELANOUS_POD_OWNER_KIND: 'seat', ELANOUS_POD_OWNER_ID: card.seat } : {}),