elanous 0.2.32 → 0.2.35

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 (753) 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 → T1mBQqmkwKDLGtyisDCOd}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{997ce8a5-2ad501927003b41b.js → 0368f25d-ad84af92fefee68f.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1165.bad13fc9151a7288.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/13.02a07436dec15f89.js +32 -0
  7. package/apps/pwa/out/_next/static/chunks/{5525.86debf231e181813.js → 1530.0e612369b6fd7ea0.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +41 -0
  9. package/apps/pwa/out/_next/static/chunks/{7391.ebae168025c91b6a.js → 1674.2a65fd5668e1cc5f.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +24 -0
  11. package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +74 -0
  12. package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/{7947-d0759430f8042240.js → 1993-c0007b7ad0c0ef41.js} +1 -1
  15. package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/{60fb96c9.360b01d8d4927b7b.js → 1c735de4.f993a30bbd3c57c4.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{5307.60f2209e809bd627.js → 2018.a741297bce759490.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +148 -0
  23. package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/{3902.e1e71aaac850a045.js → 2625.5d870aa999f33db1.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +77 -0
  26. package/apps/pwa/out/_next/static/chunks/2833-0fe47af99ed13c29.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +62 -0
  29. package/apps/pwa/out/_next/static/chunks/3103.0df8da390948bb84.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +90 -0
  31. package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{4174.92ed04922709ac9e.js → 3408.21d1570602f4b6c0.js} +2 -2
  33. package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/3589.5444a06bcf6e775c.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/359-2250789a2d3499e7.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +36 -0
  37. package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{9398-6aed28f0a96d0d6f.js → 3677-4215f826f6aa68e5.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +79 -0
  40. package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3f7c4ee5.3dde54f01a816613.js +122 -0
  42. package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/{7371.80c05c653b08e907.js → 4346.8601952e73bf5803.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/4441-875b97f5821ed58a.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +286 -0
  46. package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +24 -0
  49. package/apps/pwa/out/_next/static/chunks/{2940-619bfd8ef337c611.js → 4705-194e64e47ca0fbdb.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/{1335-6731f392c35216eb.js → 4718-17d2af636796a330.js} +3 -3
  51. package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/{7502.ccd5b8065545edd0.js → 5101.e32282718f99ed6f.js} +2 -2
  57. package/apps/pwa/out/_next/static/chunks/{2001.6c7e0fd02190886c.js → 5154.a118f3957ed14e36.js} +1 -1
  58. package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +23 -0
  61. package/apps/pwa/out/_next/static/chunks/{5173-233188df2f42c626.js → 5483-dd5d7697f6bdb106.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5637.281e5dec4ea6ecf1.js +94 -0
  63. package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/{3267c0e6.d34854e7b3984a6e.js → 56d372f2.681ab4ec4c998fae.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +287 -0
  67. package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/{6433.fc573af22bbc9ab7.js → 6236.e18cced2d5ba6afb.js} +17 -17
  74. package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +8 -0
  75. package/apps/pwa/out/_next/static/chunks/630.fe5a46428d63b013.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +27 -0
  78. package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +93 -0
  80. package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6866-79aa5b4e47cac6aa.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/{6544cb48.a87fe20ddf137be2.js → 6b89c8bd.24df687a820500b3.js} +1 -1
  83. package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +149 -0
  87. package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +104 -0
  88. package/apps/pwa/out/_next/static/chunks/{2871.0bca6137343b3f76.js → 7385.50a308a477bdfc21.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/{2985.39ccdecd36848b12.js → 7644.17e37ba6f1d4226e.js} +4 -4
  90. package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/{8018.a32663f04a6fc5f9.js → 8219.baa715d1deee80e2.js} +1 -1
  95. package/apps/pwa/out/_next/static/chunks/{4111.2bfedbb233ad206b.js → 8256.e3ac8421a71f82f4.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/{2213.2ccbada92c33ea0f.js → 8444.4c26b379ca2b9596.js} +17 -17
  100. package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +226 -0
  101. package/apps/pwa/out/_next/static/chunks/8557-e7898769499cd56f.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +64 -0
  104. package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{6092.a7f99e68b188ca66.js → 8637.47f5b35afcae5e6b.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/8714.ff0b7ce3ec3e3ae2.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{3278.2e5d15b53a4091c8.js → 9214.63a510d39178e997.js} +2 -2
  111. package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +115 -0
  112. package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/{9221.7d22eaf353a2d4e7.js → 938.66ad1ef0e5abae1c.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/{6157.0c9af021de4fb31b.js → 9512.5a76207a730e0491.js} +2 -2
  115. package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/{69-0a2c8209c6d4a158.js → 967-2aa39b2d04b4c690.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/{7862.30a8d6482bb238eb.js → 9952.5daf5f94063a2b3e.js} +1 -1
  120. package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/{page-a27b1e5a0d1b308f.js → page-406b47745b53f269.js} +1 -1
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/{page-32866485913d6a04.js → page-47c5d4db587266bd.js} +1 -1
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1f5a60f70cb4dd0c.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-bac7dee94e5eae4a.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/{page-04d00ae9b0890349.js → page-dc0a532f5b9196ec.js} +1 -1
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{7a1887c4.f36b88fba31da8fd.js → b2f6ba4d.fb56fdbbf798df33.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/b6705a4f-b9a9047de9eecfd0.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/{b313b242.cb1265eea908db61.js → cbe38a15.5a032598e39970c6.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{409f1e57.d0649fc47691ebfe.js → d06f9160.a3d9062f95de8ad7.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/{0bb0ff36.b8d418980951e5ba.js → da5176c6.6773b6c5994e1d99.js} +7 -7
  178. package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.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 +10 -2
  278. package/catalog/providers/opengateway.yaml +25 -0
  279. package/docs/goal-context/01-goal-authoring-checks.md +8 -0
  280. package/docs/goal-context/03-verification-menu.md +24 -0
  281. package/docs/goal-context/04-mock-scenarios.md +100 -0
  282. package/docs/goal-context/README.md +5 -0
  283. package/graphs/catalog/catalog.yaml +1 -1
  284. package/graphs/default-loop.yaml +76 -5
  285. package/graphs/document-loop.yaml +71 -4
  286. package/graphs/implement-loop.yaml +59 -4
  287. package/graphs/journey/SCENARIOS.md +33 -0
  288. package/graphs/journey/recipes.yaml +1 -0
  289. package/graphs/journey/ta-journey.yaml +94 -0
  290. package/graphs/journey/units/author/author.yaml +20 -0
  291. package/graphs/journey/units/author/recipes.yaml +2 -0
  292. package/graphs/journey/units/author-dialogue/author-dialogue.yaml +42 -0
  293. package/graphs/journey/units/author-dialogue/observe.ts +96 -0
  294. package/graphs/journey/units/author-dialogue/recipes.yaml +10 -0
  295. package/graphs/journey/units/green/green.yaml +20 -0
  296. package/graphs/journey/units/green/recipes.yaml +2 -0
  297. package/graphs/journey/units/pr/pr.yaml +20 -0
  298. package/graphs/journey/units/pr/recipes.yaml +2 -0
  299. package/graphs/journey/units/remember/recipes.yaml +2 -0
  300. package/graphs/journey/units/remember/remember.yaml +20 -0
  301. package/graphs/operate-loop.yaml +71 -4
  302. package/graphs/overlays/stop-heal-ladder.yaml +1 -1
  303. package/graphs/release-rehearsal/recipes.yaml +1 -1
  304. package/graphs/release-rehearsal/release-rehearsal.yaml +2 -2
  305. package/graphs/research-loop.yaml +159 -4
  306. package/graphs/test-diet/test-diet.yaml +3 -0
  307. package/graphs/units/dispatch-pod/dispatch-pod.yaml +50 -0
  308. package/graphs/units/dispatch-pod/recipes.yaml +14 -0
  309. package/graphs/units/entry/entry.yaml +50 -0
  310. package/graphs/units/entry/recipes.yaml +14 -0
  311. package/graphs/units/harvest/harvest.yaml +25 -0
  312. package/graphs/units/harvest/recipes.yaml +4 -0
  313. package/graphs/units/land/land.yaml +45 -0
  314. package/graphs/units/land/recipes.yaml +3 -0
  315. package/graphs/units/recipes.yaml +7 -0
  316. package/graphs/units/recover.yaml +39 -0
  317. package/graphs/units/reflect/recipes.yaml +3 -0
  318. package/graphs/units/reflect/reflect.yaml +15 -0
  319. package/graphs/units/task-agent-recover-review.yaml +17 -0
  320. package/graphs/units/task-agent-recover-wait.yaml +17 -0
  321. package/graphs/units/verbs/make-doc.yaml +34 -0
  322. package/graphs/units/verbs/recipes.yaml +33 -0
  323. package/graphs/units/verbs/verify.yaml +55 -0
  324. package/graphs/work/recipes.yaml +2 -0
  325. package/graphs/work/research-report.yaml +28 -0
  326. package/package.json +1 -1
  327. package/scripts/ci-typecheck-changed.ts +69 -16
  328. package/scripts/coord-role-pack.ts +19 -6
  329. package/scripts/docs/generate-graph-anatomy.ts +19 -2
  330. package/scripts/graph-harvest-unit.ts +22 -0
  331. package/scripts/graph-units/journey-stub.ts +6 -0
  332. package/scripts/graph-units/land-enqueue.ts +78 -0
  333. package/scripts/graph-units/recover-plan.ts +15 -0
  334. package/scripts/graph-units/reflect-node.ts +88 -0
  335. package/scripts/graph-units/ta-journey-observe.ts +109 -0
  336. package/scripts/graph-units/verbs/headless-goal-loop.ts +152 -0
  337. package/scripts/graph-units/verbs/verify-stage.ts +75 -0
  338. package/scripts/graph-units/verbs-envelope.ts +139 -0
  339. package/scripts/hq/standby-snapshot.ts +30 -0
  340. package/scripts/public-export.ts +43 -1
  341. package/scripts/ratchets/train-side-invariants.sh +45 -0
  342. package/scripts/release-loop/auto-approve-node.ts +30 -16
  343. package/scripts/release-loop/docs-land-node.ts +21 -5
  344. package/scripts/release-loop/gate-baseline-receipt.ts +155 -0
  345. package/scripts/release-loop/gate-closure.ts +5 -1
  346. package/scripts/release-loop/gate-diff.ts +1 -1
  347. package/scripts/release-loop/gate-node.ts +675 -49
  348. package/scripts/release-loop/gate-partial.ts +68 -14
  349. package/scripts/release-loop/gate-radius-live.ts +177 -0
  350. package/scripts/release-loop/gate-radius-shadow.ts +138 -0
  351. package/scripts/release-loop/gate-traffic-mode.ts +128 -0
  352. package/scripts/release-loop/gate-triage-node.ts +5 -2
  353. package/scripts/release-loop/known-issues-0.2.33-approved.json +194 -0
  354. package/scripts/release-loop/known-issues-node.ts +77 -8
  355. package/scripts/release-loop/node-verdict.ts +12 -1
  356. package/scripts/release-loop/npm-publish-node.ts +66 -12
  357. package/scripts/release-loop/preflight.ts +93 -7
  358. package/scripts/release-loop/probe-pod-host-dirs-live.ts +5 -0
  359. package/scripts/release-loop/publish-node.ts +60 -9
  360. package/scripts/release-loop/pwa-remote.ts +166 -0
  361. package/scripts/release-loop/pwa-scenarios-node.ts +19 -3
  362. package/scripts/release-loop/resume-cap.ts +56 -0
  363. package/scripts/release-loop/resume-release.ts +155 -19
  364. package/scripts/release-loop/resume.ts +24 -1
  365. package/scripts/release-loop/tui-sim-node.ts +8 -2
  366. package/scripts/release-loop/unattended-release.ts +10 -2
  367. package/scripts/test-diet/lib.ts +6 -1
  368. package/scripts/test-diet/node.ts +194 -13
  369. package/scripts/ux-sim.ts +39 -0
  370. package/src/acp/core-turn-bridge.ts +20 -5
  371. package/src/acp/reasoning-thought-buffer.ts +45 -0
  372. package/src/agent/self-ambient-cache.ts +8 -0
  373. package/src/agent-substrate/acp-reviewer.ts +90 -15
  374. package/src/agent-substrate/pr-reviewer.ts +17 -0
  375. package/src/agent-substrate/review-finding-key.ts +53 -0
  376. package/src/agent-substrate/self-review-cli.ts +188 -18
  377. package/src/ask-user-question/pending-questions.ts +1 -1
  378. package/src/autopilot/pr-manager.ts +393 -65
  379. package/src/budget/run-usage-rollup.ts +1 -0
  380. package/src/chat/index.ts +0 -2
  381. package/src/chat/pickers/modal-runtime.ts +10 -27
  382. package/src/chat/tool-render/dispatch.ts +62 -10
  383. package/src/cli/agent-cli.ts +13 -2
  384. package/src/cli/control-cli.ts +24 -7
  385. package/src/cli/doctor-cli.ts +4 -1
  386. package/src/cli/guardian-cli.ts +10 -0
  387. package/src/cli/light-entry-route.ts +75 -0
  388. package/src/cli/llm-detect-cli.ts +23 -1
  389. package/src/cli/pod-cli.ts +77 -3
  390. package/src/cli/pr-cli.ts +81 -14
  391. package/src/cli/pr-land-base-read.ts +2 -0
  392. package/src/cli/pr-land-overlap-evidence.ts +154 -16
  393. package/src/cli/pr-land-pod-shadow-job.ts +3 -0
  394. package/src/cli/pr-land-recovery.ts +64 -0
  395. package/src/cli/pty-takeover-cli.ts +6 -5
  396. package/src/cli/release-checklist-read-cli.ts +79 -0
  397. package/src/cli/release-cli.ts +189 -132
  398. package/src/cli/release-run-if-ready.ts +29 -28
  399. package/src/cli/release-single-flight.ts +178 -0
  400. package/src/cli/remote-resolve.ts +1 -1
  401. package/src/cli/root-tui-entry.ts +48 -0
  402. package/src/cli/seat-cli.ts +37 -0
  403. package/src/cli/setup-cli.ts +40 -1
  404. package/src/cli/sim-cli.ts +22 -0
  405. package/src/cli/tasks-cli.ts +667 -14
  406. package/src/cli/usage-cli.ts +13 -11
  407. package/src/clipboard/history.ts +179 -13
  408. package/src/config.ts +8 -1
  409. package/src/control/control-status.ts +8 -3
  410. package/src/control-plane/ledger.ts +5 -3
  411. package/src/control-plane/server.ts +5 -3
  412. package/src/core-turn/short-question.ts +5 -1
  413. package/src/dashboard/chat/acp-chat.ts +8 -0
  414. package/src/dashboard/index.ts +114 -77
  415. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +3 -0
  416. package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
  417. package/src/dashboard/input/seat-autowake.ts +56 -3
  418. package/src/dashboard/render/theme-resolver.ts +33 -4
  419. package/src/dashboard/seat-boot-preamble.ts +1 -1
  420. package/src/dashboard/slash-runtime/ask-clarification.ts +48 -0
  421. package/src/dashboard/slash-runtime/dashboard-delegated-slashes.ts +68 -0
  422. package/src/dashboard/slash-runtime/dashboard-handlers.ts +62 -322
  423. package/src/dashboard/slash-runtime/dashboard-log-slash.ts +208 -0
  424. package/src/dashboard/turn-preamble.ts +47 -1
  425. package/src/dashboard/turn-stream-formatter.ts +34 -1
  426. package/src/dashboard/turn-stream-runtime.ts +2 -0
  427. package/src/dashboard/turn-typeahead-prompt-zone.ts +67 -0
  428. package/src/domains/guardian-tick.ts +54 -2
  429. package/src/domains/outbound-alert.ts +3 -2
  430. package/src/domains/schedule-registry.ts +16 -2
  431. package/src/extractors.ts +3 -1
  432. package/src/git-fs/idle-refresh.ts +76 -0
  433. package/src/git-fs/index.ts +18 -7
  434. package/src/git-fs/retry.ts +4 -0
  435. package/src/git-fs/runner.ts +2 -0
  436. package/src/git-fs/worktree.ts +42 -4
  437. package/src/graph-kinds/registry.ts +2 -2
  438. package/src/graph-runner/runner.ts +267 -54
  439. package/src/grok/credential.ts +15 -3
  440. package/src/harness/harness-cli-command.ts +151 -38
  441. package/src/harness/harness-incidents.ts +37 -0
  442. package/src/harness/harness-pod-dispatch.ts +38 -1
  443. package/src/harness/harness-salvage-cli.ts +14 -2
  444. package/src/harness/launch-utterance-ledger.ts +208 -0
  445. package/src/impl-discipline/detector.ts +16 -4
  446. package/src/impl-discipline/system-prompt.ts +11 -0
  447. package/src/impl-discipline/types.ts +2 -2
  448. package/src/index.ts +683 -146
  449. package/src/intake-plane/already-built-hint.ts +91 -0
  450. package/src/intake-plane/requirement-funnel.ts +29 -1
  451. package/src/knowhow/pack.ts +199 -0
  452. package/src/light-cli.ts +111 -0
  453. package/src/llm/opengateway-models.ts +11 -0
  454. package/src/llm/provider-credentials.ts +14 -0
  455. package/src/llm/provider-detect.ts +8 -1
  456. package/src/llm/runtime-model-family.ts +2 -1
  457. package/src/llm.ts +268 -65
  458. package/src/loops/budget.ts +95 -0
  459. package/src/loops/msg-wake.ts +8 -2
  460. package/src/loops/orchestrator/traffic.ts +132 -1
  461. package/src/model-tier/llm-tier-map.ts +15 -1
  462. package/src/mss/logging/log-store.ts +4 -5
  463. package/src/native-tool-catalog.ts +15 -1
  464. package/src/nexus/api/graphs-api.ts +22 -3
  465. package/src/nexus/api/http-server.ts +1 -1
  466. package/src/nexus/api/loop-resources.ts +13 -1
  467. package/src/nexus/api/ops-api.ts +12 -0
  468. package/src/oauth/claude-pty-maturity.ts +66 -0
  469. package/src/oauth/codex-access-mirror.ts +55 -0
  470. package/src/oauth/codex.ts +7 -0
  471. package/src/oauth/fallback-chain.ts +1 -1
  472. package/src/onboarding/first-run.ts +5 -3
  473. package/src/onboarding/non-interactive.ts +64 -13
  474. package/src/onboarding.ts +10 -2
  475. package/src/ops/overview-collect.ts +54 -4
  476. package/src/ops/overview.ts +31 -7
  477. package/src/pr-tool/census.ts +282 -30
  478. package/src/pr-tool/inflight-registry.ts +160 -7
  479. package/src/prompt-library/gpt6-family-addendum.ts +14 -1
  480. package/src/pty-shell/herdr-agent-report.ts +442 -0
  481. package/src/pty-shell/pty-control-ipc.ts +5 -5
  482. package/src/pty-shell/pty-manifest.ts +7 -0
  483. package/src/pty-shell/pty-write-outcome.ts +24 -6
  484. package/src/pty-shell/tui-run-state.ts +117 -3
  485. package/src/release-loop/checklist.ts +103 -5
  486. package/src/release-loop/feature-store.ts +19 -2
  487. package/src/release-loop/landed-but-yellow.ts +129 -5
  488. package/src/release-loop/light-rc.ts +1 -0
  489. package/src/release-loop/placement.ts +10 -3
  490. package/src/release-loop/rehearsal.ts +205 -25
  491. package/src/release-loop/rubric.ts +16 -2
  492. package/src/repl/index.ts +174 -17
  493. package/src/repl/ops-msg-bridge.ts +32 -0
  494. package/src/self-dev/ask-launch-flow.ts +44 -5
  495. package/src/self-dev/cli-help-text.ts +17 -0
  496. package/src/self-dev/dev-cli.ts +11 -9
  497. package/src/self-dev/draft-residue.ts +37 -1
  498. package/src/self-dev/draft-sweep.ts +188 -13
  499. package/src/self-dev/draft-triage-rules.ts +107 -0
  500. package/src/self-dev/fleet-reduce.ts +3 -2
  501. package/src/self-dev/graph-front-nodes.ts +112 -0
  502. package/src/self-dev/graph-journey-nodes.ts +11 -6
  503. package/src/self-dev/graph-journey-route.ts +60 -6
  504. package/src/self-dev/harness-run-cli.ts +3 -15
  505. package/src/self-dev/orchestrate-cli-text.ts +10 -0
  506. package/src/self-dev/orchestrate.ts +79 -3
  507. package/src/self-dev/review-provider-fallback.ts +35 -1
  508. package/src/self-dev/run-supervisor.ts +107 -12
  509. package/src/self-dev/run-types.ts +5 -1
  510. package/src/self-dev/self-orchestrate-runtime.ts +1 -11
  511. package/src/self-dev/shard-aggregate.ts +42 -5
  512. package/src/self-dev/shard-run.ts +8 -1
  513. package/src/self-implement/blocked-draft-policy.ts +20 -0
  514. package/src/self-implement/classify-shadow.ts +3 -7
  515. package/src/self-implement/doctor-visit.ts +18 -1
  516. package/src/self-implement/gate-baseline.ts +95 -12
  517. package/src/self-implement/gate-cli.ts +1 -0
  518. package/src/self-implement/gate-remote.ts +40 -25
  519. package/src/self-implement/goal-author-decompose.ts +275 -47
  520. package/src/self-implement/goal-author-identity.ts +66 -0
  521. package/src/self-implement/goal-author-preservation-obligation.ts +35 -0
  522. package/src/self-implement/goal-author.ts +254 -120
  523. package/src/self-implement/goal-elaborate.ts +295 -0
  524. package/src/self-implement/goal-refine.ts +270 -0
  525. package/src/self-implement/graph-overlay-yaml.ts +28 -2
  526. package/src/self-implement/graph-unit-flatten.ts +103 -0
  527. package/src/self-implement/graph-unit-resolver.ts +107 -0
  528. package/src/self-implement/graph-yaml.ts +151 -1
  529. package/src/self-implement/headless-elanous-driver.ts +1 -0
  530. package/src/self-implement/knowhow-pack.ts +103 -0
  531. package/src/self-implement/orchestrator.ts +160 -45
  532. package/src/self-implement/pod-warm-pool-profile.ts +45 -0
  533. package/src/self-implement/review-mustfix-class.ts +203 -0
  534. package/src/self-implement/rework-budget-judgment.ts +5 -8
  535. package/src/self-implement/run-stop.ts +17 -2
  536. package/src/self-implement/running-runs.ts +29 -1
  537. package/src/self-implement/scope-adjacency.ts +113 -0
  538. package/src/self-implement/seams.ts +138 -4
  539. package/src/self-implement/stop-autoheal.ts +112 -2
  540. package/src/session/chat.ts +27 -0
  541. package/src/session-runtime/index.ts +1 -1
  542. package/src/session-runtime/retry-policy.ts +2 -1
  543. package/src/setup/llm-env-detect.ts +5 -0
  544. package/src/skills/tools/agent.ts +140 -14
  545. package/src/skills/tools/msg-ask.ts +100 -0
  546. package/src/skills/tools/ops-ledger.ts +2 -1
  547. package/src/skills/tools/schedule-wakeup.ts +66 -17
  548. package/src/steward/hold-hygiene.ts +24 -6
  549. package/src/steward/release-day.ts +7 -3
  550. package/src/steward/triage-budget.ts +194 -0
  551. package/src/steward/triage.ts +57 -7
  552. package/src/task-agent/actions.ts +69 -1
  553. package/src/task-agent/green-sweep.ts +4 -0
  554. package/src/task-agent/harvest-unit.ts +141 -0
  555. package/src/task-agent/live-moves.ts +257 -15
  556. package/src/task-agent/parent-host.ts +216 -6
  557. package/src/task-agent/postland-card.ts +80 -1
  558. package/src/task-agent/rejudge-on-head.ts +112 -26
  559. package/src/task-agent/repair-branch-cas.ts +4 -1
  560. package/src/task-agent/repair-cycle.ts +16 -3
  561. package/src/task-agent/run-identity.ts +4 -3
  562. package/src/task-agent/shadow.ts +19 -3
  563. package/src/task-agent/task-hand.ts +96 -36
  564. package/src/task-agent/tier-split.ts +127 -0
  565. package/src/task-agent/work-order-build.ts +24 -0
  566. package/src/task-agent/work-order.ts +3 -2
  567. package/src/task-orchestrator/generator-prompt.ts +60 -11
  568. package/src/task-orchestrator/surfaces/pod-account-broker.ts +72 -3
  569. package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
  570. package/src/task-orchestrator/surfaces/pod-command-job.ts +47 -8
  571. package/src/task-orchestrator/surfaces/pod-image-source.ts +89 -1
  572. package/src/task-orchestrator/surfaces/pod-lease.ts +17 -8
  573. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +86 -8
  574. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +8 -2
  575. package/src/task-orchestrator/surfaces/pod-pool.ts +73 -17
  576. package/src/task-orchestrator/surfaces/pod-provenance.ts +76 -0
  577. package/src/task-orchestrator/surfaces/pod-source-receive.ts +72 -4
  578. package/src/task-orchestrator/surfaces/pod-warm-provenance.ts +81 -0
  579. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +32 -5
  580. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +3 -0
  581. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +421 -0
  582. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +2 -1
  583. package/src/task-orchestrator/surfaces/self-implement-pod.ts +588 -71
  584. package/src/task-orchestrator/surfaces/self-implement.ts +106 -2
  585. package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
  586. package/src/tool-runtime/truncation-store.ts +4 -0
  587. package/src/tui/README.md +2 -0
  588. package/src/tui/chat/background-job-status.ts +54 -0
  589. package/src/tui/chat/log-view.ts +80 -0
  590. package/src/tui/entry.ts +406 -0
  591. package/src/tui/input/composer.ts +144 -0
  592. package/src/tui/seat-mail-boot.ts +59 -0
  593. package/src/tui/slash/compact.ts +100 -0
  594. package/src/tui/slash/new-session.ts +35 -0
  595. package/src/tui-client/dashboard-session.ts +10 -1
  596. package/src/tui-client/local-chat-turn.ts +239 -0
  597. package/src/tui-client/local-harness-command.ts +63 -0
  598. package/src/tui-client/local-provider-command.ts +184 -0
  599. package/src/user-config/coercion.ts +36 -0
  600. package/src/user-config.ts +22 -43
  601. package/src/ux-sim/event-monkey.ts +378 -0
  602. package/src/ux-sim/fake-bin.ts +42 -7
  603. package/src/ux-sim/fault-nextmove-dispatch.ts +266 -0
  604. package/src/ux-sim/fault-pod-codex-503.ts +211 -0
  605. package/src/ux-sim/fault-scope-escape-lift.ts +189 -0
  606. package/src/ux-sim/scenario.ts +72 -13
  607. package/src/version/packed-revision.json +1 -1
  608. package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +0 -27
  611. package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +0 -287
  612. package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +0 -62
  613. package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/1654.32de4b324981a188.js +0 -23
  617. package/apps/pwa/out/_next/static/chunks/1834-98b64172bc1efe77.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +0 -149
  619. package/apps/pwa/out/_next/static/chunks/1913.7cc6fb6055b1ed3f.js +0 -41
  620. package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/2898.fd781bc7cf01a7b7.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +0 -115
  629. package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +0 -64
  630. package/apps/pwa/out/_next/static/chunks/3541-ce3a5424ed5ad7f1.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +0 -36
  636. package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +0 -286
  640. package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +0 -77
  641. package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +0 -226
  642. package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +0 -79
  644. package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +0 -148
  647. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/5458-16cd7a2b51b74c8c.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/5543.a438b8ab5a13ea47.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +0 -74
  653. package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +0 -94
  655. package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +0 -90
  661. package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +0 -32
  662. package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +0 -104
  663. package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +0 -24
  668. package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +0 -93
  669. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +0 -8
  674. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/8097-9530c03bcc550f02.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +0 -24
  685. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/9138.b6e80031afb1d973.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/9279-d28c5b7754d010ae.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/9989.3694300e5f000b14.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/approvals/page-504204b58c82c253.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a9717a67c2eecbaf.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/board/page-5c9ec30aee62dfbf.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/botlab/page-584191533721fa16.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/app/bots/page-73c4b4bb3ac7ab5f.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c0f1ca371f710b06.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/app/chat/page-46430d45a9e04eac.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/app/consult/page-3b2ebf1dc64ff0be.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/app/decisions/page-25654b82094f7d22.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8ea49a4c6dd2c6e7.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/app/editor/page-ce5113aefea0a8d1.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/app/exec/page-0e5a41fac1c75396.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/app/field/page-31aaf1ed37c6df9a.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/app/inside/page-3dcc1fa411e1f4e0.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/app/intake/page-c69247e7134d329d.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/app/layout-66dc5cd3a0999abe.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/app/live/page-26ff7ff651a7217d.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/app/live-run/page-617b3976981efa96.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/app/loops/page-d256f5d5d9552823.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/app/market/page-ce8f1907b8a6101c.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-33e182a316263116.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/app/not-found-7607cca9b84950c6.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eeab86176b03dc3b.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5b93dbae3432b996.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-77a6cb90a9cf2b10.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f47e768b5b242b5a.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/app/outputs/page-eb41aa3367fc2505.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/page-4d13ab0b8a267e3f.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/reflection/page-84dad32ff0fc0831.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-95306f892aa2d0ee.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/sessions/page-940fb6c217f6b470.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-8c66a3b24a745630.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/settings/page-7b675dfd35c36fc9.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8bd0d3cf7665bcfc.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/app/setup/page-c219f2ed171131be.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/app/share/page-40f8fa21bdae955b.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/app/showroom/page-468f8313e4f1fbd9.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/app/tasks/page-7bbb8fa353a246c4.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/app/today/page-4214b855d9233ea8.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/app/trace/page-936752c7aa58762e.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/app/vault/page-ec052ad359df1797.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8305570551091338.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/workflows/page-fad650e4793adb65.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/workspace/page-d90e64743826e1d8.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a16bcfd49af86a32.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +0 -122
  744. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +0 -1
  752. package/src/cli/g6a-registration-probe.ts +0 -16
  753. /package/apps/pwa/out/_next/static/{IVKr3AlRUVLKsw2fh7eXF → T1mBQqmkwKDLGtyisDCOd}/_ssgManifest.js +0 -0
@@ -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,28 @@ 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
- observe: (_event, data) => { wouldDo = data.reason; },
340
+ observe: (event, data) => {
341
+ wouldDo = data.reason;
342
+ // Keep new denominator rows out of the legacy task-agent/action aggregate.
343
+ if (event !== 'task-agent.entrance-denominator') return;
344
+ try { (deps.log ?? ((category, name, row) => debug.log(category, name, row)))('task-agent', 'entrance-denominator', { ...data }); }
345
+ catch { /* Observation must not alter the selected move. */ }
346
+ },
336
347
  ...(liveRetry ? { liveMoves, retryLaunches, loadGate: deps.loadGate } : {}),
337
348
  });
349
+ if (liveRetry && executorResult === 'done' && route) {
350
+ passJourneyNode('next-move', { provenance: 'task-agent-terminal', outcome: judgement.move,
351
+ runId: input.runId ?? undefined, data: { source: judgeInput.pr ? `pr:${judgeInput.pr}` : `run:${input.runId ?? 'unknown'}`, pr: judgeInput.pr ?? null } });
352
+ recordJourneyEdge(route, 'dispatch');
353
+ }
338
354
  }
339
355
  const move: TaskAgentShadowMove = {
340
356
  runId: input.runId,
@@ -10,13 +10,14 @@
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';
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';
20
+ import { newLaunchUtteranceId, recordLaunchUtterance } from '../harness/launch-utterance-ledger.js';
20
21
  import { debug } from '../debug/log.js';
21
22
  import { effectiveInstanceRoot } from '../instance/resolve.js';
22
23
  import { withFileLockSync } from '../storage/file-lock.js';
@@ -29,7 +30,8 @@ import { parseWorkOrder, renderWorkOrderGoal, WORK_ORDER_FILE_PATTERN, type Work
29
30
  import { inspectPrelaunchAlreadyDone, type AlreadyDoneDecision, type AlreadyDoneCandidate,
30
31
  type PrelaunchGitRunnerForTest } from './prelaunch-already-done.js';
31
32
  import { draftReleaseComment } from '../self-dev/draft-triage-rules.js';
32
- import { parseAskTargetPathHints } from '../self-dev/launch-preflight-text.js';
33
+ import { parseAskTargetPathHints, parseAskTargetPathHintsResult } from '../self-dev/launch-preflight-text.js';
34
+ import { inspectGoalDoneBoundary } from '../self-implement/goal-author.js';
33
35
  import { INFLIGHT_REGISTRY_FILE, registerInflight } from '../pr-tool/inflight-registry.js';
34
36
 
35
37
  export interface ResolveHandTextDeps {
@@ -50,38 +52,35 @@ function missingOrReadFailure(error: unknown): '없다' | '읽기 실패' {
50
52
  return code === 'ENOENT' || code === 'ENOTDIR' ? '없다' : '읽기 실패';
51
53
  }
52
54
 
53
- /**
54
- * TA-WORK-ORDER — `.work-order.json` 골 파일의 내용을 지시서로 검증한다.
55
- * 통과하면 골 문면으로 펼쳐 `work-order` 로, 깨진 JSON·칸 id 없음은 `rejected`(사유) 로 돌린다.
56
- * 관측: `debug.log('task-agent.work-order', 'parsed' | 'rejected', { cellId, unknownFields })`.
57
- */
58
- function resolveWorkOrderFile(content: string, path: string): ResolvedHandText {
59
- const parsed = parseWorkOrder(content);
60
- if (!parsed.ok) {
61
- try { debug.log('task-agent.work-order', 'rejected', { cellId: null, unknownFields: [] }); } catch { /* fail-soft */ }
62
- return { kind: 'rejected', path, reason: parsed.reason };
63
- }
64
- try { debug.log('task-agent.work-order', 'parsed', { cellId: parsed.order.cellId, unknownFields: parsed.order.unknownFields }); } catch { /* fail-soft */ }
65
- return { kind: 'work-order', text: renderWorkOrderGoal(parsed.order), path, order: parsed.order };
66
- }
67
-
68
- /** 파일 판정만 한다. 관측과 카드 작성은 호출자가 결과에 따라 수행한다. */
55
+ /** 파일 판정만 한다. 카드 작성은 호출자가 결과에 따라 수행한다. */
69
56
  export function resolveHandText(text: string, deps: ResolveHandTextDeps = { cwd: process.cwd(), stat: statSync, readFile: readFileSync }): ResolvedHandText {
70
- if (!text || /\s/.test(text)) return { kind: 'unchanged', text };
57
+ const workOrder = WORK_ORDER_FILE_PATTERN.test(text);
58
+ if (!text || (/\s/.test(text) && !workOrder)) return { kind: 'unchanged', text };
71
59
  const path = resolve(deps.cwd, text);
72
60
  const extension = /\.(?:md|markdown|txt)$/i.test(text);
61
+ const reject = (reason: string): ResolvedHandText => {
62
+ if (workOrder) {
63
+ try { debug.log('task-agent.work-order', 'rejected', { cellId: null, unknownFields: [] }); } catch { /* fail-soft */ }
64
+ }
65
+ return { kind: 'rejected', path, reason };
66
+ };
73
67
  let file: Pick<Stats, 'isFile' | 'isDirectory'>;
74
68
  try { file = deps.stat(path); } catch (error) {
75
- if (!extension) return { kind: 'unchanged', text };
76
- return { kind: 'rejected', path, reason: missingOrReadFailure(error) };
69
+ if (!extension && !workOrder) return { kind: 'unchanged', text };
70
+ return reject(missingOrReadFailure(error));
77
71
  }
78
- if (!file.isFile() && !extension && !file.isDirectory()) return { kind: 'unchanged', text };
79
- if (!file.isFile()) return { kind: 'rejected', path, reason: file.isDirectory() ? '디렉터리' : '읽기 실패' };
72
+ if (!file.isFile() && !extension && !workOrder && !file.isDirectory()) return { kind: 'unchanged', text };
73
+ if (!file.isFile()) return reject(file.isDirectory() ? '디렉터리' : '읽기 실패');
80
74
  let content: string;
81
75
  // stat 과 read 사이에 지워지거나 경로가 바뀌어도 사유는 같은 규칙(없다/읽기 실패)으로 가른다.
82
- try { content = deps.readFile(path, 'utf8'); } catch (error) { return { kind: 'rejected', path, reason: missingOrReadFailure(error) }; }
76
+ try { content = deps.readFile(path, 'utf8'); } catch (error) { return reject(missingOrReadFailure(error)); }
83
77
  // TA-WORK-ORDER — 지시서 골 파일은 인라인하지 않고 지시서로 검증해 골 문면으로 펼친다.
84
- if (WORK_ORDER_FILE_PATTERN.test(text)) return resolveWorkOrderFile(content, path);
78
+ if (workOrder) {
79
+ const parsed = parseWorkOrder(content);
80
+ if (!parsed.ok) return reject(parsed.reason);
81
+ try { debug.log('task-agent.work-order', 'parsed', { cellId: parsed.order.cellId, unknownFields: parsed.order.unknownFields }); } catch { /* fail-soft */ }
82
+ return { kind: 'work-order', text: renderWorkOrderGoal(parsed.order), path, order: parsed.order };
83
+ }
85
84
  const carried = content.trim();
86
85
  if (!carried) return { kind: 'rejected', path, reason: '비었다' };
87
86
  return { kind: 'inlined', text: content, path, chars: carried.length, sha256: createHash('sha256').update(carried).digest('hex') };
@@ -210,6 +209,8 @@ export interface TaskCardMove { kind: 'launch' | 'wait'; command?: string[]; rea
210
209
  export interface TaskCard {
211
210
  id: string;
212
211
  text: string;
212
+ /** 첫 줄 대상 경로 라벨에서 확인한 저장소 상대 경로. 필드 부재는 경로를 모른다는 뜻이다. */
213
+ targetPaths?: string[];
213
214
  seat?: TaskSeat;
214
215
  checklistId?: string;
215
216
  /** Explicit release version for an adopted PR; post-land still confirms the cell exists there. */
@@ -231,8 +232,11 @@ export interface TaskCard {
231
232
  * launch-failed = 발사기가 띄우기에 실패했다(사유는 history 마지막 칸) — 다음 수는 다시 발사.
232
233
  * failed = 발사된 런이 PR·수확 가지 없이 죽었거나 끝내 안 떴다(TA-JUDGE-DEAD-RUN · `card-evidence.ts`) — 사유
233
234
  * (`failed/needs-owner|needs-relaunch — …`)는 history 마지막 칸 · 자동 재발사하지 않는다(사람/판단부 몫).
235
+ * landed-by-hand = 실패 카드에 묶인 PR을 사람이 손수 병합해 main 에 안착시켰다(TA-CARD-MERGE-RECONCILE ·
236
+ * `postland-card.ts` `reconcileHandMergedCard`) — 이전 status·사유는 history `hand-move` 줄에 보존된다.
237
+ * landed = 병합된 merge 커밋이 카드의 land attempt head 와 정확히 일치해 에이전트 착지로 확정했다(같은 정산 경로).
234
238
  */
235
- status: 'handed' | 'launched' | 'launch-failed' | 'failed' | 'done';
239
+ status: 'handed' | 'launched' | 'launch-failed' | 'failed' | 'landed-by-hand' | 'landed' | 'done';
236
240
  history: TaskCardEvent[];
237
241
  /** 미션 카드만 — 조각 카드 id(순서대로) · 쪼갠 출처(`mission.ts` splitMission). */
238
242
  pieces?: string[];
@@ -292,13 +296,18 @@ export interface TaskCard {
292
296
  * 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
297
  * only after that re-gate passes is the attempt consumed (`openLandAttempts`) and the same head may land once more.
294
298
  */
295
- landAttempts?: Array<{ pr: number; head: string; at: string; ok?: boolean; detail?: string; class?: 'infra' | 'judgement' | 'base-stale'; reason?: string }>;
299
+ landAttempts?: Array<{ pr: number; head: string; at: string; ok?: boolean; detail?: string; class?: 'infra' | 'judgement' | 'base-stale' | 'recovery'; reason?: string }>;
296
300
  /** TA-LIVE-LAND-2 — `tasks hand --ta-land`: this card's run leaves the merge to the task agent (propose-land). */
297
301
  taLand?: true;
298
302
  /** TASKS-HAND-CHILD-LLM — `tasks hand --child-llm <provider>/<model> [--child-llm-effort <level>]` → 발사 인자 `--child-llm-provider/-model/-effort`. */
299
303
  childLlm?: TaskChildLlm;
300
304
  /** Dispatch difficulty, fixed at handoff so repair uses the same judgement. */
301
305
  tier?: '하' | '중' | '상' | '특';
306
+ /**
307
+ * TIER-SPLIT-BEFORE-LAUNCH — 상·특 hand 를 분해해 나온 조각 카드(`tier-split.ts`). group = 같은 hand 에서 나온 조각들의 묶음 id
308
+ * (칸 연결은 `checklistId` 가 그대로 잇는다) · fromTier = 원래 난이도 · unavoidable = 상으로 남은 조각의 불가피 이유.
309
+ */
310
+ tierSplit?: { group: string; fromTier: '상' | '특'; index: number; total: number; unavoidable?: string };
302
311
  /** RUN-IDENTITY-TAGS — 출생 신분 묶음(`run-identity.js` 정본): 칸 우선순위·대표 표시에서 태어나고 `--tag k=v` 가 덮는다. 카드 상태 파일이 원장 정본이다. */
303
312
  identity?: RunIdentity;
304
313
  /** Same-PR repair launches; exact source head and worker result are retained for CAS and retry limits. */
@@ -434,6 +443,25 @@ export function readTaskCard(id: string, path = taskAgentStatePath()): TaskCard
434
443
  return readState(path).tasks?.[id];
435
444
  }
436
445
 
446
+ function canonicalTargetPaths(paths: readonly string[]): string[] {
447
+ return [...new Set(paths.filter((path): path is string => typeof path === 'string').map((path) => posix.normalize(path))
448
+ .filter((path) => path !== '.' && path !== '..' && !posix.isAbsolute(path)
449
+ && !path.startsWith('../') && !path.includes('\\') && !/^[A-Za-z]:\//.test(path)))].sort();
450
+ }
451
+
452
+ /** 같은 저장소 경로를 만지는 착지 전 카드만 돌려준다. 경로 미기록 카드는 추측하지 않는다. */
453
+ export function cardsTouchingPaths(cards: readonly TaskCard[], paths: readonly string[]): Array<{
454
+ card: TaskCard; checklistId?: string; runId?: string; pr?: number; paths: string[];
455
+ }> {
456
+ const wanted = new Set(canonicalTargetPaths(paths));
457
+ if (wanted.size === 0) return [];
458
+ return cards.filter((card) => card.status === 'launched' && !card.postLand && !card.trainLanding && !card.prTerminal)
459
+ .map((card) => ({ card, paths: canonicalTargetPaths(card.targetPaths ?? []).filter((path) => wanted.has(path)) }))
460
+ .filter((item) => item.paths.length > 0)
461
+ .map(({ card, paths }) => ({ card, ...(card.checklistId ? { checklistId: card.checklistId } : {}),
462
+ ...(card.runId ? { runId: card.runId } : {}), ...(cardPrNumber(card) !== undefined ? { pr: cardPrNumber(card) } : {}), paths }));
463
+ }
464
+
437
465
  export const CLOSED_BY_HAND_EVENT = 'closed-by-hand';
438
466
 
439
467
  /** 카드를 손으로 닫는다 — 상태를 `failed` 로 두고 history 에 한 줄(`closed-by-hand`)을 남긴다. 이미 손으로 닫은 카드는 그대로 돌려준다(멱등). */
@@ -552,7 +580,7 @@ export function shellQuote(arg: string): string {
552
580
  }
553
581
 
554
582
  /** 발사기에 넘기는 연결 — env(`ELANOUS_RUN_ID`)를 자식 환경에 얹으면 하니스 런이 `runId` 로 돈다(`resolveRunIdentity` 상속). launchId 는 카드에만 남는 발사 토큰이다. */
555
- export interface TaskLaunchContext { runId: string; launchId: string; env: Record<string, string>; cardLabelContext?: TaskCardLabelContext }
583
+ export interface TaskLaunchContext { runId: string; launchId: string; env: Record<string, string>; /** exact untrimmed hand text (launch-utterance ledger pair) */ launchUtterance?: string; cardLabelContext?: TaskCardLabelContext; substrate?: 'pod'; podGoal?: string; effectiveChildProvider?: string }
556
584
  /** 발사기가 «이 런 id 로 띄웠다»고 돌려주는 영수증 — 없으면 카드에 런 id 를 적지 않는다(추측하지 않는다). */
557
585
  export interface TaskLaunchReceipt {
558
586
  runId?: string;
@@ -572,12 +600,18 @@ export interface HandTaskOptions {
572
600
  goal?: string;
573
601
  milestone?: string;
574
602
  live?: boolean;
603
+ /** Production `tasks hand --live` guard; test launchers opt in explicitly. */
604
+ preflightGoalDoneBoundary?: boolean;
575
605
  /** TA-LIVE-LAND-2 — `--ta-land`: card field `taLand` ⊕ launch env `ELANOUS_TA_LAND=1`. */
576
606
  taLand?: boolean;
577
607
  /** TASKS-HAND-CHILD-LLM — `<provider>/<model>`(`parseChildLlm`) ⊕ 선택 추론 노력. effort 만 주면 거부. */
578
608
  childLlm?: string;
579
609
  childLlmEffort?: string;
580
610
  tier?: TaskCard['tier'];
611
+ /** TIER-SPLIT-BEFORE-LAUNCH — 조각 카드에 싣는 분해 연결(`tier-split.ts` 만 준다). */
612
+ tierSplit?: TaskCard['tierSplit'];
613
+ /** TIER-SPLIT-BEFORE-LAUNCH — 분해 실패 사유. 주면 카드를 발사 없이 failed(history `tier-split-failed`)로 남기고 launched:false 로 돌아온다. */
614
+ tierSplitBlocked?: string;
581
615
  /** RUN-IDENTITY-TAGS — `tasks hand --tag k=v`(반복): 출생 신분을 덮는다. 목록 밖 값은 거부한다(`run-identity.js`). */
582
616
  tags?: string[];
583
617
  /** RUN-IDENTITY-TAGS — 칸 읽기 seam(우선순위·대표 표시). 주면 그 답이 최종이다(«칸 없음» 포함). */
@@ -657,6 +691,9 @@ export function dispatchDeliverableCompletion(id: string, input: { ref: string;
657
691
  export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
658
692
  const text = opts.text.trim();
659
693
  if (!text) throw new Error('과제 한 줄이 비어 있다');
694
+ const path = opts.statePath ?? taskAgentStatePath();
695
+ const targetPathHints = parseAskTargetPathHintsResult(text);
696
+ const targetPaths = canonicalTargetPaths(targetPathHints.paths);
660
697
  if (opts.seat !== undefined && !TASK_SEATS.includes(opts.seat)) throw new Error(`자리는 ${TASK_SEATS.join('|')} 중 하나다: ${opts.seat}`);
661
698
  if (opts.completion !== undefined && !COMPLETION_KINDS.includes(opts.completion)) throw new Error(`종결 종류는 ${COMPLETION_KINDS.join('|')} 중 하나다: ${opts.completion}`);
662
699
  for (const [flag, value] of [['--goal', opts.goal], ['--milestone', opts.milestone]] as const) {
@@ -664,6 +701,7 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
664
701
  }
665
702
  if (opts.childLlmEffort !== undefined && opts.childLlm === undefined) throw new Error('--child-llm-effort 는 --child-llm <provider>/<model> 과 함께 준다');
666
703
  if (opts.tier !== undefined && !['하', '중', '상', '특'].includes(opts.tier)) throw new Error(`--tier 는 하|중|상|특 중 하나다: ${opts.tier}`);
704
+ const tierSplitBlocked = opts.tierSplitBlocked;
667
705
  // RUN-IDENTITY-TAGS — 출생 신분: 칸 우선순위(P0 = critical·special·protect · P1 = normal · 그 외 normal)·대표 표시에서 단다.
668
706
  // `--tag k=v`(반복) 이 덮는다 — 칸·태그 없는 손은 오늘 모양 그대로다(신분 없음). 목록 밖 값은 카드를 적기 전에 거부한다(`run-identity.js` 정본).
669
707
  const birthCell = opts.checklistId === undefined ? undefined
@@ -705,9 +743,9 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
705
743
  const now = (opts.now ?? (() => new Date()))();
706
744
  const id = opts.id ?? `${TASK_CARD_PREFIX}${now.toISOString().slice(0, 10).replaceAll('-', '')}-${randomBytes(3).toString('hex')}`;
707
745
  const mode = opts.live ? 'live' : 'shadow';
708
- const path = opts.statePath ?? taskAgentStatePath();
709
746
  const card: TaskCard = {
710
747
  id, text,
748
+ ...(!targetPathHints.labelMissing ? { targetPaths } : {}),
711
749
  ...(opts.seat ? { seat: opts.seat } : {}),
712
750
  ...(opts.checklistId ? { checklistId: opts.checklistId } : {}),
713
751
  ...(opts.checklistVersion !== undefined ? { checklistVersion: opts.checklistVersion } : {}),
@@ -721,18 +759,21 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
721
759
  ...(opts.taLand === true ? { taLand: true as const } : {}),
722
760
  ...(childLlm ? { childLlm } : {}),
723
761
  ...(opts.tier ? { tier: opts.tier } : {}),
762
+ ...(opts.tierSplit ? { tierSplit: opts.tierSplit } : {}),
724
763
  ...(identity ? { identity } : {}),
725
764
  createdAt: now.toISOString(),
726
- status: selectionFailure ? 'failed' : 'handed',
765
+ status: selectionFailure || tierSplitBlocked !== undefined ? 'failed' : 'handed',
727
766
  history: selectionFailure ? [{ at: now.toISOString(), event: !selected.composition ? 'composition-missing'
728
- : selected.error ? 'composition-invalid' : 'composition-launcher-unavailable', detail: selectionFailure }] : [],
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}` }] : [],
729
769
  ...(opts.mission ? { mission: opts.mission, after: [...(opts.after ?? [])] } : {}),
730
770
  ...(opts.cardFields?.pr !== undefined ? { pr: opts.cardFields.pr } : {}),
731
771
  ...(opts.cardFields?.goalId !== undefined ? { goalId: opts.cardFields.goalId } : {}),
732
772
  ...(opts.cardFields?.handed !== undefined ? { handed: opts.cardFields.handed } : {}),
733
773
  };
734
774
  const move = selectionFailure ? undefined : nextMoveFor(card, opts.landed);
735
- if (move && move.kind !== 'launch') throw new Error(`발사할 수 없는 과제다 — ${move.reason}`);
775
+ // 분해 실패로 막은 카드는 wait(failed 사유)가 정답이다 — 던지지 않고 카드를 적은 뒤 발사 0 으로 돌아간다.
776
+ if (move && move.kind !== 'launch' && tierSplitBlocked === undefined) throw new Error(`발사할 수 없는 과제다 — ${move.reason}`);
736
777
  const guard = opts.writeGuard;
737
778
  const writeCard = (target: string, next: TaskCard): void => {
738
779
  if (!guard) { writeTaskCards(target, [next]); return; }
@@ -747,13 +788,24 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
747
788
  });
748
789
  if (!owned.ok) throw new TaskCardSupersededError(next.id);
749
790
  };
791
+ // Production Pod launches use the remote-parent lint's shared boundary judge.
792
+ // Injected launchers are test seams and opt in explicitly at the contract test.
793
+ if (opts.live && opts.preflightGoalDoneBoundary && !selectionFailure && move?.kind === 'launch') {
794
+ readTaskAgentState(path);
795
+ const { missing } = inspectGoalDoneBoundary(text);
796
+ if (missing.length > 0) {
797
+ throw new Error(`goal-revision-required: 완료 경계 누락 ${missing.join(' · ')} — 골 문면에 완료 경계 코드·완료 경계 실물·완료 경계 증거 명령을 적은 뒤 다시 넘기세요`);
798
+ }
799
+ }
750
800
  writeCard(path, card);
801
+ try { debug.log('task-agent.hand', 'target-paths', { card: id, count: targetPaths.length, labelMissing: targetPathHints.labelMissing }); } catch { /* fail-soft */ }
751
802
  try { debug.log('task-agent.graph-select', !selected.composition ? 'composition-missing' : selected.error ? 'composition-invalid' : 'composition-selected', {
752
803
  completion, file: selected.composition?.file ?? `graphs/work/${completion}.yaml`,
753
804
  unitsResolved: selected.unitsResolved, missingUnits: selected.missingUnits,
754
805
  ...(selected.error ? { error: selected.error } : {}),
755
806
  }); } catch { /* fail-soft */ }
756
807
  if (selectionFailure) throw new Error(`${selectionFailure} (카드 ${id})`);
808
+ if (tierSplitBlocked !== undefined && move) return { card, move, mode, launched: false, ...(project ? { cwd: project.target } : {}) };
757
809
  if (!move || move.kind !== 'launch') throw new Error('조합 선택 뒤 발사 수가 없다');
758
810
  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 */ }
759
811
  if (childLlm) {
@@ -777,11 +829,17 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
777
829
  return { card: candidate, move: nextMoveFor(candidate), mode, launched: false, ...(project ? { cwd: project.target } : {}) };
778
830
  }
779
831
  const runId = mintRunId();
780
- const launchId = `tl-${randomBytes(6).toString('hex')}`;
781
- const context: TaskLaunchContext = { runId, launchId, env: { [HARNESS_RUN_ID_ENV]: runId, ELANOUS_TASK_CARD_ID: card.id,
832
+ const launchId = newLaunchUtteranceId();
833
+ recordLaunchUtterance({ source: 'hand', utterance: opts.text, launchId });
834
+ const context: TaskLaunchContext = { runId, launchId, launchUtterance: opts.text, env: { [HARNESS_RUN_ID_ENV]: runId, ELANOUS_TASK_CARD_ID: card.id,
835
+ ...(cardPrNumber(card) ? { ELANOUS_TASK_BOUND_PR: String(cardPrNumber(card)) } : {}),
782
836
  ...(card.checklistId ? { ELANOUS_POD_SLOT_ID: card.checklistId } : {}),
783
837
  ...(card.seat ? { ELANOUS_POD_OWNER_KIND: 'seat', ELANOUS_POD_OWNER_ID: card.seat } : {}),
784
- ...(card.taLand ? { [TA_LAND_ENV]: '1' } : {}) }, cardLabelContext: taskCardLabelContext(card) };
838
+ ...(card.taLand ? { [TA_LAND_ENV]: '1' } : {}) }, cardLabelContext: taskCardLabelContext(card),
839
+ // An omitted card provider uses the established Pod default. Carry the effective value explicitly so
840
+ // remote-parent code never has to infer a provider from the serialized CLI argv.
841
+ effectiveChildProvider: card.childLlm?.provider ?? 'openai-codex',
842
+ ...(completion === 'code-pr' && selected.launcher === 'harness-say' ? { substrate: 'pod' as const, podGoal: card.text } : {}) };
785
843
  let receipt: void | TaskLaunchReceipt;
786
844
  try {
787
845
  receipt = await opts.launcher(move.command!, project?.target, context);
@@ -812,9 +870,11 @@ export async function handTask(opts: HandTaskOptions): Promise<HandTaskResult> {
812
870
  // INFLIGHT-REGISTRY — 출발 때 맥락을 남긴다(머지 때 같은 파일 줄의 의도를 스마트 머지가 읽는다 · 착지하면 지운다).
813
871
  try {
814
872
  const [head = '', ...rest] = text.split(/\r?\n/);
873
+ const intentLines = (/^\s*(?:대상\s*경로|target\s*paths?)\s*[::]/i.test(head) ? rest : [head, ...rest])
874
+ .filter((line) => !/^\s*(?:[-*]\s*)?완료 경계 (?:코드|실물|증거 명령)\s*:/.test(line));
815
875
  registerInflight({
816
876
  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,
877
+ intent: intentLines.join(' ').trim() || text,
818
878
  files: parseAskTargetPathHints(text),
819
879
  }, { path: join(dirname(path), INFLIGHT_REGISTRY_FILE), ...(opts.now ? { now: opts.now } : {}) });
820
880
  } catch (error) {
@@ -0,0 +1,127 @@
1
+ /**
2
+ * TIER-SPLIT-BEFORE-LAUNCH (0.2.35 P0) — `tasks hand --tier 상|특 --live` 를 한 덩어리로 쏘지 않고, 저작 분해
3
+ * (TC TIER-SIZED-DECOMPOSE `decomposeToTierSizedSlices`)가 만든 «중 이하 조각»으로 나눠 조각마다 hand 발사한다.
4
+ * 대표: «최우선으로 중·하 난이도로 쪼개기를 정착 · 구독 sol 은 웬만해선 소진 안 함».
5
+ *
6
+ * - 분해 규칙은 TC 몫 — 여기는 그 함수를 «주입 seam» 으로 받는다. 기본 seam 은 이 파일 한 곳(`DEFAULT_TIER_SIZED_DECOMPOSE`)에서만 정한다.
7
+ * - 분해기 «미배선»(seam 에 undefined 명시) = `decomposer-unavailable` → 종전처럼 한 덩어리 발사 ⊕ 기록. 기본 seam 은 TC 함수다.
8
+ * - 분해 «실패»(ok:false · throw · 불가피 이유 없는 상 조각 · 빈/잘못된 조각) → 발사 0 · 카드 failed(history `tier-split-failed`).
9
+ * - 관측: `debug.log('task-agent.hand', 'tier-split', {cid, fromTier, outcome, reason?, slices, unavoidable})`.
10
+ */
11
+ import { randomBytes } from 'node:crypto';
12
+ import { debug } from '../debug/log.js';
13
+ import { handTask, TASK_CARD_PREFIX, type HandTaskOptions, type HandTaskResult } from './task-hand.js';
14
+
15
+ // 분해 규칙·타입 정본 = TC `src/self-implement/goal-author-decompose.ts`(TIER-SIZED-DECOMPOSE · #29987).
16
+ import { decomposeToTierSizedSlices, type SizedSlice, type TierSizedDecomposeResult } from '../self-implement/goal-author-decompose.js';
17
+ export type { SizedSlice, TierSizedDecomposeResult };
18
+ export type TierSizedDecompose = (goal: string, opts?: { signal?: AbortSignal }) => Promise<TierSizedDecomposeResult>;
19
+
20
+ /** 기본 분해기 — TC `decomposeToTierSizedSlices`. seam 에 undefined 를 명시하면 «미배선»(decomposer-unavailable). */
21
+ export const DEFAULT_TIER_SIZED_DECOMPOSE: TierSizedDecompose | undefined = decomposeToTierSizedSlices;
22
+
23
+ export const TIER_SPLIT_UNAVAILABLE = 'decomposer-unavailable';
24
+
25
+ /** 분해 시간 상한 — LLM 이 매달려도 디스패처의 손 넘김 한 번을 끝없이 붙잡지 않는다. 넘으면 막힘(decompose-timeout). */
26
+ export const TIER_SPLIT_DECOMPOSE_TIMEOUT_MS = 300_000;
27
+
28
+ /** 조각이 부모 칸에서 물려받는 줄 머리 — hand 의 골 검사(완료 경계 셋)와 계약·경계 문맥. */
29
+ const INHERITED_PARENT_LABELS = /^\s*(?:[-*]\s*)?(현재 계약|완료 경계 코드|완료 경계 실물|완료 경계 증거 명령|경계|증거 보충)\s*:/;
30
+
31
+ /**
32
+ * 조각 hand 문면 = 조각 골(대상 경로·동작 — 첫 줄 유지) ⊕ 조각 표지 ⊕ 부모 칸의 계약·완료 경계·경계 줄.
33
+ * 분해기의 조각 골은 짧은 제목뿐이라 그대로 넘기면 hand 의 골 검사(완료 경계 누락)가 막는다(10-21 DEVICE-FIRST-AUTHORING 발사 0).
34
+ * 부모에 그 줄이 없으면 아무것도 더하지 않는다 — 검사가 지금처럼 거부한다(보수 쪽).
35
+ */
36
+ export function composeSliceHandText(sliceGoal: string, parentText: string, marker: { index: number; total: number; fromTier: '상' | '특'; cid: string | null }): string {
37
+ const sliceLines = sliceGoal.trim().split('\n');
38
+ const sliceHas = new Set(sliceLines.map((line) => INHERITED_PARENT_LABELS.exec(line)?.[1]).filter(Boolean));
39
+ const inherited = parentText.split('\n').filter((line) => {
40
+ const label = INHERITED_PARENT_LABELS.exec(line)?.[1];
41
+ return label !== undefined && !sliceHas.has(label);
42
+ });
43
+ if (inherited.length === 0) return sliceGoal;
44
+ const tag = `조각 ${marker.index}/${marker.total} — 부모 ${marker.cid ?? '(칸 없음)'}(${marker.fromTier}) 를 중 이하로 나눈 몫. 아래 계약·완료 경계는 부모 칸에서 물려받았다 — 이 조각 범위만 채운다.`;
45
+ return [...sliceLines, tag, ...inherited].join('\n');
46
+ }
47
+
48
+ export type TierSplitPlan =
49
+ | { kind: 'split'; slices: SizedSlice[] }
50
+ | { kind: 'blocked'; reason: string };
51
+
52
+ /** 순수 판정 — 분해 결과 → 발사 계획. 이유 없는 상 조각이 하나라도 있으면 결과 전체를 실패로 본다(이유 없는 상 0). */
53
+ export function planTierSplit(result: TierSizedDecomposeResult): TierSplitPlan {
54
+ if (!result.ok) return { kind: 'blocked', reason: `decompose-failed: ${result.reason}` };
55
+ if (result.slices.length === 0) return { kind: 'blocked', reason: 'no-slices' };
56
+ for (const [index, slice] of result.slices.entries()) {
57
+ if (!['하', '중', '상'].includes(slice.tier)) return { kind: 'blocked', reason: `invalid-slice-tier: #${index + 1} ${String(slice.tier)}` };
58
+ if (!slice.goal?.trim()) return { kind: 'blocked', reason: `empty-slice-goal: #${index + 1}` };
59
+ if (slice.tier === '상' && !slice.unavoidable?.trim()) return { kind: 'blocked', reason: `unjustified-상-slice: #${index + 1}` };
60
+ }
61
+ return { kind: 'split', slices: result.slices };
62
+ }
63
+
64
+ export interface TierSplitSliceOutcome { slice: SizedSlice; result?: HandTaskResult; error?: string }
65
+ export type TierSplitHandResult =
66
+ | { kind: 'whole'; result: HandTaskResult; reason?: string }
67
+ | { kind: 'blocked'; result: HandTaskResult; reason: string }
68
+ | { kind: 'split'; group: string; fromTier: '상' | '특'; slices: TierSplitSliceOutcome[] };
69
+
70
+ export interface TierSplitHandOptions extends HandTaskOptions {
71
+ /** 분해기 seam — 키를 안 주면 기본(`DEFAULT_TIER_SIZED_DECOMPOSE`) · undefined 를 명시하면 «미배선». */
72
+ decompose?: TierSizedDecompose;
73
+ /** 분해 시간 상한(시험 주입) — 기본 `TIER_SPLIT_DECOMPOSE_TIMEOUT_MS`. */
74
+ decomposeTimeoutMs?: number;
75
+ }
76
+
77
+ function record(data: Record<string, unknown>): void {
78
+ try { debug.log('task-agent.hand', 'tier-split', data); } catch { /* fail-soft */ }
79
+ }
80
+
81
+ /**
82
+ * `tasks hand` 의 발사 앞단. 분해는 `--live` ⊕ tier 상|특 일 때만 — 중·하·tier 없음·shadow 는 `handTask` 그대로(분해 호출 0).
83
+ */
84
+ export async function handTaskWithTierSplit(opts: TierSplitHandOptions): Promise<TierSplitHandResult> {
85
+ const { decompose: injected, decomposeTimeoutMs = TIER_SPLIT_DECOMPOSE_TIMEOUT_MS, ...hand } = opts;
86
+ const fromTier = hand.tier;
87
+ if (!hand.live || (fromTier !== '상' && fromTier !== '특')) return { kind: 'whole', result: await handTask(hand) };
88
+ const decompose = 'decompose' in opts ? injected : DEFAULT_TIER_SIZED_DECOMPOSE;
89
+ const cid = hand.checklistId ?? null;
90
+ if (!decompose) {
91
+ record({ cid, fromTier, outcome: 'whole', reason: TIER_SPLIT_UNAVAILABLE, slices: [], unavoidable: [] });
92
+ return { kind: 'whole', result: await handTask(hand), reason: TIER_SPLIT_UNAVAILABLE };
93
+ }
94
+ let plan: TierSplitPlan;
95
+ const controller = new AbortController();
96
+ let timer: ReturnType<typeof setTimeout> | undefined;
97
+ const timedOut = new Promise<'timeout'>((resolve) => { timer = setTimeout(() => { controller.abort(); resolve('timeout'); }, decomposeTimeoutMs); });
98
+ try {
99
+ const raced = await Promise.race([decompose(hand.text.trim(), { signal: controller.signal }), timedOut]);
100
+ plan = raced === 'timeout' ? { kind: 'blocked', reason: `decompose-timeout: ${decomposeTimeoutMs}ms` } : planTierSplit(raced);
101
+ } catch (error) {
102
+ plan = { kind: 'blocked', reason: `decompose-threw: ${String((error as Error)?.message ?? error).slice(0, 200)}` };
103
+ } finally { clearTimeout(timer); }
104
+ if (plan.kind === 'blocked') {
105
+ record({ cid, fromTier, outcome: 'blocked', reason: plan.reason, slices: [], unavoidable: [] });
106
+ return { kind: 'blocked', result: await handTask({ ...hand, tierSplitBlocked: plan.reason }), reason: plan.reason };
107
+ }
108
+ const group = `${TASK_CARD_PREFIX}split-${randomBytes(4).toString('hex')}`;
109
+ const total = plan.slices.length;
110
+ const unavoidable = plan.slices.filter((slice) => slice.tier === '상').map((slice) => slice.unavoidable!.trim());
111
+ // 조각은 새 카드다 — 호출자 id·pr·goalId 를 조각마다 복제하면 «PR: #N» 조회·수확이 엇갈린다. 버린 것은 기록에 남긴다.
112
+ const dropped = { ...(hand.id ? { id: hand.id } : {}), ...(hand.cardFields?.pr !== undefined ? { pr: hand.cardFields.pr } : {}), ...(hand.cardFields?.goalId !== undefined ? { goalId: hand.cardFields.goalId } : {}) };
113
+ record({ cid, fromTier, outcome: 'split', group, ...(Object.keys(dropped).length ? { dropped } : {}), slices: plan.slices.map((s) => ({ tier: s.tier, files: s.files, behaviours: s.behaviours })), unavoidable });
114
+ const { id: _wholeId, cardFields, ...rest } = hand;
115
+ const base = { ...rest, ...(cardFields?.handed !== undefined ? { cardFields: { handed: cardFields.handed } } : {}) };
116
+ const slices: TierSplitSliceOutcome[] = [];
117
+ for (const [index, slice] of plan.slices.entries()) {
118
+ try {
119
+ const result = await handTask({ ...base, text: composeSliceHandText(slice.goal, hand.text, { index: index + 1, total, fromTier, cid }), tier: slice.tier,
120
+ tierSplit: { group, fromTier, index: index + 1, total, ...(slice.tier === '상' ? { unavoidable: slice.unavoidable!.trim() } : {}) } });
121
+ slices.push({ slice, result });
122
+ } catch (error) {
123
+ slices.push({ slice, error: error instanceof Error ? error.message : String(error) });
124
+ }
125
+ }
126
+ return { kind: 'split', group, fromTier, slices };
127
+ }
@@ -0,0 +1,24 @@
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
+ boundary?: string;
10
+ }
11
+
12
+ /** Build the normalized nine-field core from already-grounded inputs; no CLI, filesystem, or launch side effects. */
13
+ export function buildWorkOrder(input: BuildWorkOrderInput): WorkOrder {
14
+ const parsed = parseWorkOrder(JSON.stringify({
15
+ cellId: input.cellId,
16
+ lifeId: input.lifeId,
17
+ version: input.version,
18
+ priority: input.priority,
19
+ peers: input.peers,
20
+ boundary: input.boundary,
21
+ }));
22
+ if (!parsed.ok) throw new Error(parsed.reason);
23
+ return parsed.order;
24
+ }
@@ -79,8 +79,9 @@ export function parseWorkOrder(source: string): ParseWorkOrderResult {
79
79
  const unknownFields: string[] = [];
80
80
  const cells = {} as Record<WorkOrderField, string>;
81
81
  for (const field of WORK_ORDER_FIELDS) {
82
- const text = cellText(record[field]);
83
- if (text === WORK_ORDER_UNKNOWN) unknownFields.push(field);
82
+ const value = record[field];
83
+ const text = cellText(value);
84
+ if (value == null || (typeof value === 'string' && !value.trim())) unknownFields.push(field);
84
85
  cells[field] = text;
85
86
  }
86
87
  return { ok: true, order: { cellId: rawCellId.trim(), ...cells, unknownFields } };