elanous 0.2.27 → 0.2.29

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 (700) 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/{Ev2jivDMTSoEc-5rIXdcy → cIpv5nU9AycwYWZI9H589}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{ab4d57c2.e90bc2cb31949045.js → 058a98ba.7eb28d5e6dc03565.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{4565-67e4c620597965c8.js → 1015-9cba22a5a4554797.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +8 -0
  9. package/apps/pwa/out/_next/static/chunks/{1516.83dd2c1b86b4e507.js → 1142.65d002789ab3af7d.js} +2 -2
  10. package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +34 -0
  12. package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1516.dfaceff3fd2d0e0d.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +286 -0
  16. package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +24 -0
  17. package/apps/pwa/out/_next/static/chunks/1782-59db1b5aa06df38a.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{1743.563d3168e95825ef.js → 1852.7f7b53991fcb99ef.js} +2 -2
  19. package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +36 -0
  22. package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +64 -0
  24. package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{65ebff95.081daeff622d238e.js → 285adb1a.5654e605dddf86d2.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +115 -0
  31. package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/3160-95c96f4d2a21dd26.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +90 -0
  36. package/apps/pwa/out/_next/static/chunks/328bb3ab-6628a1114fe3fb3b.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{9917-9e26abc5f7772735.js → 3396-97b97928c49190c9.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/{6196.34d6b229079e9e28.js → 3403.7199205e65124486.js} +1 -1
  40. package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/419.736c0d6f426249a7.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{6def8a8e.c81f9ca41028eccf.js → 425cfc4d.fb91158e3971c39f.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/{16e57f67.3ea19e893461e611.js → 46bd8bea.2f4b4099172fcdb7.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/{5081.a240b63fad28663a.js → 4759.1f76713aefb87db5.js} +1 -1
  51. package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +94 -0
  54. package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +62 -0
  60. package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +27 -0
  63. package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +104 -0
  64. package/apps/pwa/out/_next/static/chunks/{9974.e77b4ff4884557b3.js → 5591.a35e7a217734a8b9.js} +2 -2
  65. package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +93 -0
  66. package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/{5492-e05e26a033ba80d2.js → 6013-2f769370d8b4c2c6.js} +3 -3
  69. package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +24 -0
  70. package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +2 -0
  72. package/apps/pwa/out/_next/static/chunks/{5408.377c8c543635b81f.js → 6534.1ab00f370db7b105.js} +1 -1
  73. package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +148 -0
  74. package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +149 -0
  75. package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +79 -0
  77. package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/{8578.dff22d988cc2b106.js → 6767.1fcfc9b8be83975f.js} +16 -16
  79. package/apps/pwa/out/_next/static/chunks/6776.06ff1e3b464cc607.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/{9311.24c8f5ea793253dd.js → 6853.cc5174a9dee59593.js} +1 -1
  81. package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +287 -0
  86. package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/{94.4cfed21c0b781a06.js → 7375.050ea0d72968e49f.js} +16 -16
  92. package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +77 -0
  94. package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +74 -0
  97. package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7725-4f83d5541fbdb81b.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8332.6f0f49df772e163b.js +23 -0
  102. package/apps/pwa/out/_next/static/chunks/{7483.ba01c6c209b81bba.js → 8398.73a19b39715eda04.js} +1 -1
  103. package/apps/pwa/out/_next/static/chunks/{2846.d6a433b8663819a5.js → 8471.8d2a8c74f09c36ff.js} +3 -3
  104. package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +226 -0
  106. package/apps/pwa/out/_next/static/chunks/{5785-ea8d2c633b6688e3.js → 8767-2f6a634f5abeaa01.js} +1 -1
  107. package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +32 -0
  109. package/apps/pwa/out/_next/static/chunks/8795.32573a185af18c7b.js +41 -0
  110. package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/{4593.10f5b9bd702d4a6c.js → 9143.ff14585db1d275ff.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{4204.a409ab6250c0f6a8.js → 9907.49be0fcadaf214b5.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{973cbf1b.3bbcf2b41548eca7.js → a435ad95.577add051b4facb2.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-a5635eba0d73b84e.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-86feb08080261a2f.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/{page-ff27902d0b11ef4f.js → page-8aaa6dedc4c10dfb.js} +1 -1
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/{page-25a302273b054fd7.js → page-33bf667a5fb297bf.js} +1 -1
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-29900ed0011b2c83.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/{page-87b88f551f421d8b.js → page-9eb56166774eb256.js} +1 -1
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9f92737b8766009a.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{f4dfbfc0.a69fb12f854882aa.js → bc324b7c.02a09dd93f6a399b.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +122 -0
  177. package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.js +1 -0
  183. package/apps/pwa/out/approvals/index.html +1 -1
  184. package/apps/pwa/out/approvals/index.txt +22 -22
  185. package/apps/pwa/out/autopilot/index.html +1 -1
  186. package/apps/pwa/out/autopilot/index.txt +22 -22
  187. package/apps/pwa/out/board/index.html +1 -1
  188. package/apps/pwa/out/board/index.txt +22 -22
  189. package/apps/pwa/out/botlab/index.html +1 -1
  190. package/apps/pwa/out/botlab/index.txt +21 -21
  191. package/apps/pwa/out/bots/index.html +1 -1
  192. package/apps/pwa/out/bots/index.txt +21 -21
  193. package/apps/pwa/out/ceo/index.html +1 -1
  194. package/apps/pwa/out/ceo/index.txt +22 -22
  195. package/apps/pwa/out/chat/index.html +1 -1
  196. package/apps/pwa/out/chat/index.txt +21 -21
  197. package/apps/pwa/out/consult/index.html +1 -1
  198. package/apps/pwa/out/consult/index.txt +22 -22
  199. package/apps/pwa/out/control/index.html +1 -1
  200. package/apps/pwa/out/control/index.txt +22 -22
  201. package/apps/pwa/out/decisions/index.html +1 -1
  202. package/apps/pwa/out/decisions/index.txt +21 -21
  203. package/apps/pwa/out/design-check/index.html +1 -1
  204. package/apps/pwa/out/design-check/index.txt +22 -22
  205. package/apps/pwa/out/editor/index.html +1 -1
  206. package/apps/pwa/out/editor/index.txt +22 -22
  207. package/apps/pwa/out/exec/index.html +1 -1
  208. package/apps/pwa/out/exec/index.txt +22 -22
  209. package/apps/pwa/out/field/index.html +1 -1
  210. package/apps/pwa/out/field/index.txt +22 -22
  211. package/apps/pwa/out/healthz +1 -1
  212. package/apps/pwa/out/index.html +1 -1
  213. package/apps/pwa/out/index.txt +21 -21
  214. package/apps/pwa/out/inside/index.html +1 -1
  215. package/apps/pwa/out/inside/index.txt +21 -21
  216. package/apps/pwa/out/intake/index.html +1 -1
  217. package/apps/pwa/out/intake/index.txt +22 -22
  218. package/apps/pwa/out/live/index.html +1 -1
  219. package/apps/pwa/out/live/index.txt +22 -22
  220. package/apps/pwa/out/live-run/index.html +1 -1
  221. package/apps/pwa/out/live-run/index.txt +22 -22
  222. package/apps/pwa/out/loops/index.html +1 -1
  223. package/apps/pwa/out/loops/index.txt +21 -21
  224. package/apps/pwa/out/market/index.html +1 -1
  225. package/apps/pwa/out/market/index.txt +21 -21
  226. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  227. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  228. package/apps/pwa/out/morning/index.html +1 -1
  229. package/apps/pwa/out/morning/index.txt +22 -22
  230. package/apps/pwa/out/observatory/index.html +1 -1
  231. package/apps/pwa/out/observatory/index.txt +22 -22
  232. package/apps/pwa/out/ops/checklist/index.html +1 -1
  233. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  234. package/apps/pwa/out/ops/release/index.html +1 -1
  235. package/apps/pwa/out/ops/release/index.txt +21 -21
  236. package/apps/pwa/out/ops/seats/index.html +1 -1
  237. package/apps/pwa/out/ops/seats/index.txt +21 -21
  238. package/apps/pwa/out/outputs/index.html +1 -1
  239. package/apps/pwa/out/outputs/index.txt +21 -21
  240. package/apps/pwa/out/reflection/index.html +1 -1
  241. package/apps/pwa/out/reflection/index.txt +22 -22
  242. package/apps/pwa/out/scheduler/index.html +1 -1
  243. package/apps/pwa/out/scheduler/index.txt +22 -22
  244. package/apps/pwa/out/sessions/index.html +1 -1
  245. package/apps/pwa/out/sessions/index.txt +21 -21
  246. package/apps/pwa/out/settings/devices/index.html +1 -1
  247. package/apps/pwa/out/settings/devices/index.txt +22 -22
  248. package/apps/pwa/out/settings/index.html +1 -1
  249. package/apps/pwa/out/settings/index.txt +22 -22
  250. package/apps/pwa/out/setup/done/index.html +1 -1
  251. package/apps/pwa/out/setup/done/index.txt +22 -22
  252. package/apps/pwa/out/setup/index.html +1 -1
  253. package/apps/pwa/out/setup/index.txt +22 -22
  254. package/apps/pwa/out/share/index.html +1 -1
  255. package/apps/pwa/out/share/index.txt +22 -22
  256. package/apps/pwa/out/showroom/index.html +1 -1
  257. package/apps/pwa/out/showroom/index.txt +21 -21
  258. package/apps/pwa/out/tasks/index.html +1 -1
  259. package/apps/pwa/out/tasks/index.txt +22 -22
  260. package/apps/pwa/out/term/index.html +1 -1
  261. package/apps/pwa/out/term/index.txt +22 -22
  262. package/apps/pwa/out/today/index.html +1 -1
  263. package/apps/pwa/out/today/index.txt +22 -22
  264. package/apps/pwa/out/trace/index.html +1 -1
  265. package/apps/pwa/out/trace/index.txt +22 -22
  266. package/apps/pwa/out/vault/index.html +1 -1
  267. package/apps/pwa/out/vault/index.txt +22 -22
  268. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  269. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  270. package/apps/pwa/out/workflows/index.html +1 -1
  271. package/apps/pwa/out/workflows/index.txt +22 -22
  272. package/apps/pwa/out/workspace/index.html +1 -1
  273. package/apps/pwa/out/workspace/index.txt +22 -22
  274. package/apps/pwa/out/worktrees/index.html +1 -1
  275. package/apps/pwa/out/worktrees/index.txt +22 -22
  276. package/graphs/implement-loop.yaml +38 -1
  277. package/graphs/release/release-loop.yaml +6 -2
  278. package/graphs/steward/recipes.yaml +6 -0
  279. package/graphs/steward/release-day.yaml +23 -0
  280. package/graphs/steward/steward.yaml +9 -1
  281. package/graphs/work/code-pr.yaml +23 -0
  282. package/package.json +1 -1
  283. package/plugins/agent-team/agents/research.md +1 -0
  284. package/scripts/browser-observe-cycle.ts +76 -2
  285. package/scripts/ci-typecheck-changed.ts +53 -19
  286. package/scripts/coord-channel-watch.sh +26 -6
  287. package/scripts/coord-role-pack.ts +143 -0
  288. package/scripts/detect-test-interference.ts +31 -1
  289. package/scripts/lib/morning-report-options.ts +41 -0
  290. package/scripts/pr-land-extra-remote-gates.ts +49 -0
  291. package/scripts/release-loop/docs-node.ts +51 -22
  292. package/scripts/release-loop/gate-batch-safe.ts +23 -0
  293. package/scripts/release-loop/gate-history.ts +422 -0
  294. package/scripts/release-loop/gate-node.ts +336 -39
  295. package/scripts/release-loop/gate-triage-node.ts +190 -0
  296. package/scripts/release-loop/node-verdict.ts +3 -1
  297. package/scripts/release-loop/publish-node.ts +3 -0
  298. package/scripts/release-loop/spawn-lane.ts +68 -0
  299. package/scripts/release-loop/tui-node-checks.ts +28 -2
  300. package/scripts/release-loop/version-node.ts +62 -4
  301. package/scripts/skills/public-check.ts +5 -2
  302. package/scripts/test-deterministic.ts +549 -37
  303. package/scripts/usage-rollup.ts +11 -3
  304. package/scripts/ux-sim.ts +7 -1
  305. package/scripts/verify-kpack6-live.ts +230 -0
  306. package/src/acp/codex-plugins.ts +17 -0
  307. package/src/acp/core-turn-bridge.ts +98 -22
  308. package/src/acp/elanous-extensions.ts +2 -0
  309. package/src/acp/server.ts +2 -0
  310. package/src/agent/ref-grounding.ts +18 -0
  311. package/src/agent/task-notification.ts +2 -1
  312. package/src/agent-mission/in-agent-plugin.ts +8 -3
  313. package/src/agent-substrate/pr-reviewer.ts +29 -21
  314. package/src/agent-substrate/self-review-cli.ts +34 -10
  315. package/src/briefing/brief-items.ts +151 -35
  316. package/src/budget/llm-cost.ts +25 -2
  317. package/src/budget/pty-usage-reemit.ts +7 -0
  318. package/src/budget/run-usage-rollup.ts +9 -0
  319. package/src/budget/usage-daily-store.ts +98 -0
  320. package/src/budget/usage-outcomes.ts +32 -0
  321. package/src/capture/tui-self-report.ts +22 -4
  322. package/src/chat/index.ts +31 -10
  323. package/src/chat/pickers/modal-runtime.ts +1 -0
  324. package/src/chat/pickers/modals.ts +3 -1
  325. package/src/chat/turn-typeahead.ts +123 -16
  326. package/src/claims/claims-ledger.ts +23 -0
  327. package/src/claims/claims-render.ts +22 -2
  328. package/src/cli/brief-cli.ts +131 -10
  329. package/src/cli/claims-cli.ts +24 -4
  330. package/src/cli/dashboard-name-flag.ts +48 -0
  331. package/src/cli/doctor-cli.ts +80 -0
  332. package/src/cli/log-event-names.ts +12 -0
  333. package/src/cli/msg-cli.ts +210 -11
  334. package/src/cli/plugin-cli.ts +11 -3
  335. package/src/cli/pr-cli.ts +443 -104
  336. package/src/cli/pr-land-heavy-remote.ts +233 -0
  337. package/src/cli/pr-land-overlap-evidence.ts +104 -5
  338. package/src/cli/pr-land-refusal.ts +20 -0
  339. package/src/cli/pty-takeover-cli.ts +125 -16
  340. package/src/cli/release-cli.ts +46 -2
  341. package/src/cli/remote-resolve.ts +2 -1
  342. package/src/cli/rfc-cli.ts +24 -0
  343. package/src/cli/seat-cli.ts +26 -16
  344. package/src/cli/tailscale-serve.ts +5 -8
  345. package/src/cli/tasks-cli.ts +400 -27
  346. package/src/cli/usage-cli.ts +155 -16
  347. package/src/cli/usage-daily-cli.ts +84 -0
  348. package/src/context-bus/context-now.ts +82 -5
  349. package/src/core-turn/auth-rejected-notice.ts +41 -0
  350. package/src/core-turn/run-core-turn.ts +13 -2
  351. package/src/core-turn/run-goal-loop.ts +17 -1
  352. package/src/core-turn/short-question.ts +45 -12
  353. package/src/core-turn/types.ts +7 -0
  354. package/src/dashboard/acp-active-model.ts +40 -0
  355. package/src/dashboard/auto-compact-runtime.ts +2 -0
  356. package/src/dashboard/boot-banner.ts +80 -0
  357. package/src/dashboard/dashboard-status-lines.ts +11 -0
  358. package/src/dashboard/detail-viewer-runtime.ts +15 -2
  359. package/src/dashboard/event-loop-stall-monitor.ts +4 -0
  360. package/src/dashboard/first-screen-band.ts +63 -13
  361. package/src/dashboard/goal-loop-thinking.ts +16 -0
  362. package/src/dashboard/hitl-boot.ts +9 -4
  363. package/src/dashboard/index.ts +235 -389
  364. package/src/dashboard/input/chat-main-entry-runtime.ts +2 -0
  365. package/src/dashboard/input/chat-main-log-actions.ts +4 -0
  366. package/src/dashboard/input/chat-main-log-command.ts +12 -1
  367. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +172 -3
  368. package/src/dashboard/input/chat-main-session.ts +6 -2
  369. package/src/dashboard/input/chat-main-slash-command.ts +7 -0
  370. package/src/dashboard/input/chat-main-turn.ts +2 -1
  371. package/src/dashboard/input/compact-prepass-recovery.ts +97 -0
  372. package/src/dashboard/input/dashboard-chord-actions.ts +10 -1
  373. package/src/dashboard/input/dashboard-chord-runtime.ts +2 -0
  374. package/src/dashboard/input/external-input-host.ts +45 -0
  375. package/src/dashboard/input/log-fold-binding.ts +18 -0
  376. package/src/dashboard/input/mouse-wiring.ts +17 -4
  377. package/src/dashboard/input/turn-steer-bridge.ts +94 -0
  378. package/src/dashboard/log-click-runtime.ts +5 -3
  379. package/src/dashboard/running-build-status.ts +74 -0
  380. package/src/dashboard/seat-boot-preamble.ts +113 -0
  381. package/src/dashboard/seat-local-instructions.ts +305 -0
  382. package/src/dashboard/skill-detection-runtime.ts +24 -4
  383. package/src/dashboard/slash-runtime/dashboard-handlers.ts +100 -28
  384. package/src/dashboard/slash-runtime/model-choices.ts +35 -0
  385. package/src/dashboard/term-slash-runtime.ts +15 -0
  386. package/src/dashboard/turn-preamble.ts +30 -2
  387. package/src/dashboard/turn-session-layers.ts +176 -0
  388. package/src/dashboard/turn-stream-formatter.ts +14 -6
  389. package/src/dashboard/turn-stream-presentation-applier.ts +8 -0
  390. package/src/domains/morning-report.ts +3 -1
  391. package/src/domains/release-tool.ts +8 -9
  392. package/src/domains/surface-events.ts +4 -1
  393. package/src/domains/watch-default-scheduler.ts +8 -9
  394. package/src/fold-stack.ts +24 -1
  395. package/src/git-fs/dirty.ts +32 -4
  396. package/src/git-fs/index.ts +43 -1
  397. package/src/github/pr-labels.ts +10 -4
  398. package/src/graph-runner/runner.ts +102 -14
  399. package/src/harness/harness-clean.ts +21 -3
  400. package/src/harness/harness-cli-command.ts +22 -6
  401. package/src/harness/harness-gc.ts +32 -5
  402. package/src/harness/harness-pod-dispatch.ts +11 -4
  403. package/src/hq/seats.ts +17 -3
  404. package/src/index.ts +48 -6
  405. package/src/input/external-input-queue.ts +219 -0
  406. package/src/intelligence-map/model-bench-scores.ts +102 -0
  407. package/src/interactive-terminal-modal.ts +13 -0
  408. package/src/llm/route-decision.ts +25 -0
  409. package/src/llm-stream-retry-display.ts +59 -0
  410. package/src/llm.ts +253 -55
  411. package/src/log-entry.ts +3 -3
  412. package/src/log-pane/search.ts +29 -4
  413. package/src/loops/agent-reply.ts +256 -0
  414. package/src/loops/budget.ts +37 -7
  415. package/src/loops/loop-cli.ts +3 -2
  416. package/src/loops/msg-address.ts +57 -0
  417. package/src/loops/msg-wake.ts +282 -0
  418. package/src/loops/orchestrator/inbox.ts +130 -0
  419. package/src/loops/orchestrator/resync-shadow.ts +100 -12
  420. package/src/loops/orchestrator/tick.ts +94 -3
  421. package/src/loops/registry.ts +42 -4
  422. package/src/maturity/feature-maturity.ts +1 -1
  423. package/src/memory.ts +20 -5
  424. package/src/msg/msg-sse-server.ts +141 -0
  425. package/src/msg/msg-store.ts +84 -14
  426. package/src/native-tool-catalog.ts +125 -0
  427. package/src/nexus/api/http-server.ts +5 -0
  428. package/src/nexus/api/ops-api.ts +2 -0
  429. package/src/nexus/api/project-autopsy.ts +127 -0
  430. package/src/nexus/api/terminals.ts +3 -0
  431. package/src/nexus/api/workflow-approvals.ts +2 -0
  432. package/src/nexus/onboarding/first-boot-wizard.ts +56 -2
  433. package/src/oauth/codex-account-store.ts +15 -3
  434. package/src/oauth/codex-billing-route.ts +31 -0
  435. package/src/ops/overview-collect.ts +19 -2
  436. package/src/panes/log-pane.ts +67 -8
  437. package/src/patents/ledger.ts +128 -0
  438. package/src/persona/presets.ts +44 -0
  439. package/src/plugins/install/market-fetch.ts +32 -1
  440. package/src/plugins/maker/wizard-generate.ts +6 -4
  441. package/src/pod-lease/admission.ts +116 -41
  442. package/src/preview/terminal.ts +14 -1
  443. package/src/prompt-cache/types.ts +2 -0
  444. package/src/prompt-enhance/enhance.ts +24 -8
  445. package/src/prompt-library/universal-preamble.ts +273 -56
  446. package/src/pty-shell/pty-control-ipc.ts +4 -1
  447. package/src/pty-shell/pty-manifest.ts +77 -5
  448. package/src/pty-shell/registry.ts +19 -2
  449. package/src/pty-shell/tui-run-state.ts +253 -0
  450. package/src/release-loop/checklist.ts +11 -0
  451. package/src/release-loop/light-rc.ts +28 -3
  452. package/src/release-loop/merged-pr-checklist.ts +24 -5
  453. package/src/release-loop/rehearsal.ts +1 -1
  454. package/src/release-loop/rubric.ts +70 -0
  455. package/src/render.ts +5 -1
  456. package/src/rfc-registry/registry.ts +88 -0
  457. package/src/seat-dispatch/seat-request-ledger.ts +4 -0
  458. package/src/seat-loop/knowhow-lint.ts +233 -0
  459. package/src/seat-loop/seat-pack.ts +16 -4
  460. package/src/seat-loop/seat-report.ts +42 -2
  461. package/src/seat-loop/traffic-signal.ts +7 -0
  462. package/src/self-dev/ask-launch-flow.ts +48 -8
  463. package/src/self-dev/ask-path-candidates.ts +69 -14
  464. package/src/self-dev/decompose-proposal.ts +43 -1
  465. package/src/self-dev/graph-journey-nodes.ts +2 -0
  466. package/src/self-dev/launch-preflight-text.ts +5 -1
  467. package/src/self-dev/launch-preflight.ts +143 -10
  468. package/src/self-dev/run-supervisor.ts +71 -5
  469. package/src/self-dev/shard-aggregate.ts +2 -0
  470. package/src/self-dev/shard-run.ts +23 -2
  471. package/src/self-health/signatures.ts +132 -0
  472. package/src/self-implement/doctor-visit.ts +118 -0
  473. package/src/self-implement/gate-cli.ts +17 -4
  474. package/src/self-implement/goal-author-decompose.ts +80 -16
  475. package/src/self-implement/goal-author.ts +116 -73
  476. package/src/self-implement/goal-authoring-grounding.ts +1 -1
  477. package/src/self-implement/goal-file-name.ts +65 -0
  478. package/src/self-implement/goal-new-paths.ts +4 -5
  479. package/src/self-implement/graph-authority.ts +17 -3
  480. package/src/self-implement/graph-yaml.ts +15 -7
  481. package/src/self-implement/ground-goal.ts +2 -1
  482. package/src/self-implement/headless-elanous-driver.ts +16 -1
  483. package/src/self-implement/host-regate.ts +58 -9
  484. package/src/self-implement/orchestrator.ts +3 -10
  485. package/src/self-implement/review-mustfix-class.ts +115 -0
  486. package/src/self-implement/rework-policy.ts +80 -2
  487. package/src/self-implement/run-ledger.ts +111 -7
  488. package/src/self-implement/running-runs.ts +10 -6
  489. package/src/self-implement/self-implement-runtime.ts +32 -0
  490. package/src/self-implement/speed-claims.ts +145 -6
  491. package/src/session/pending-input.ts +62 -11
  492. package/src/session-runtime/index.ts +7 -1
  493. package/src/skills/tools/ops-ledger.ts +707 -0
  494. package/src/skills/tools/persistent-grounding.ts +103 -8
  495. package/src/skills/tools/shell.ts +196 -2
  496. package/src/status/bar.ts +32 -2
  497. package/src/status/status-provider-info.ts +58 -0
  498. package/src/steward/rejudge-tick.ts +12 -1
  499. package/src/steward/release-day.ts +158 -0
  500. package/src/steward/resync-tick.ts +123 -0
  501. package/src/task-agent/actions.ts +1 -0
  502. package/src/task-agent/adopt-pr.ts +140 -0
  503. package/src/task-agent/board.ts +11 -1
  504. package/src/task-agent/card-evidence.ts +37 -5
  505. package/src/task-agent/cover.ts +84 -17
  506. package/src/task-agent/failure-notify.ts +61 -0
  507. package/src/task-agent/green-sweep.ts +170 -0
  508. package/src/task-agent/land-worktree.ts +52 -5
  509. package/src/task-agent/live-move-history.ts +1 -0
  510. package/src/task-agent/live-moves.ts +43 -12
  511. package/src/task-agent/parent-host.ts +1 -1
  512. package/src/task-agent/postland-card.ts +139 -0
  513. package/src/task-agent/rejudge-on-head.ts +109 -7
  514. package/src/task-agent/remote-rejudge-bind.ts +91 -0
  515. package/src/task-agent/repair-branch-cas.ts +182 -0
  516. package/src/task-agent/repair-cycle.ts +288 -0
  517. package/src/task-agent/repair-next-move.ts +31 -0
  518. package/src/task-agent/repair-review.ts +24 -0
  519. package/src/task-agent/repair-worker.ts +87 -0
  520. package/src/task-agent/review-result-capture.ts +2 -1
  521. package/src/task-agent/shadow.ts +13 -7
  522. package/src/task-agent/task-hand.ts +115 -6
  523. package/src/task-orchestrator/surfaces/kubectl-transient-retry.ts +51 -0
  524. package/src/task-orchestrator/surfaces/pod-command-job.ts +63 -7
  525. package/src/task-orchestrator/surfaces/pod-install-slots.ts +6 -11
  526. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +76 -0
  527. package/src/task-orchestrator/surfaces/pod-repair-commit.ts +96 -0
  528. package/src/task-orchestrator/surfaces/self-implement-pod.ts +175 -43
  529. package/src/telegram.ts +30 -1
  530. package/src/terminal/session-registry.ts +6 -0
  531. package/src/thinking-line.ts +12 -3
  532. package/src/tool-runtime/index.ts +4 -0
  533. package/src/tool-runtime/ops-ledger-runtimes.ts +84 -0
  534. package/src/tool-runtime/ref-consult-runtime.ts +17 -2
  535. package/src/tool-runtime/run-shell-runtime.ts +4 -1
  536. package/src/tool-runtime/self-cognition-runtimes.ts +5 -1
  537. package/src/tui.ts +5 -0
  538. package/src/user-config.ts +62 -7
  539. package/src/ux-sim/fake-llm.ts +29 -0
  540. package/src/ux-sim/fault-sqlite-busy.ts +50 -0
  541. package/src/ux-sim/in-process-cli.ts +175 -0
  542. package/src/version/packed-revision.json +1 -1
  543. package/apps/pwa/out/_next/static/chunks/1027.a0f04663d24c2779.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/1038.676007ae505822e7.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/1113.a37eadf7f740d955.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/112-fa7c526c20ce1405.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/1144.5fa1fa1d48dbcd12.js +0 -36
  548. package/apps/pwa/out/_next/static/chunks/1146.80d15ea7c6e6ee95.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/1157.f08bf2b70915e176.js +0 -148
  550. package/apps/pwa/out/_next/static/chunks/119b405e.8fdd0e44d1ff37aa.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/1296.04560d98e73fbf51.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/1314-f604ba013ec535b0.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/1454-a9c338f5bb556f42.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/1464.f3209af0d8ae4ff2.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/1729-d73dd25e564679d4.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/1843.5924c24295243261.js +0 -27
  557. package/apps/pwa/out/_next/static/chunks/1987.e28149724b92918b.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/2066-5ca18ffa5a4be68b.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/2240.d10a66695155fd93.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/2391.e2cbc98d4abbb41a.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/2528.3868070ef1be69f9.js +0 -24
  562. package/apps/pwa/out/_next/static/chunks/2566-734cb83bbd405886.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/2697.76ca2ac3efef6f3b.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/275.0e6bad414729bfa0.js +0 -32
  565. package/apps/pwa/out/_next/static/chunks/2803-33bdae771855a8d1.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/3143.257997a5f1ed79df.js +0 -34
  567. package/apps/pwa/out/_next/static/chunks/3259-86f3be56e43eaf6a.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/3280-e177c33bfbdcfb0a.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/3294-2b6a6d45a46a6c1c.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/3309.364573ceedbdfd5f.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/3522.758840fc5e7fe630.js +0 -287
  572. package/apps/pwa/out/_next/static/chunks/3525-a7c989c1a661e880.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/3694.b1a66387756458c0.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/370.124f9e678a76fc01.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/3797-9643105335e660fe.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/4084.15ecaf4240bd9e77.js +0 -286
  577. package/apps/pwa/out/_next/static/chunks/4089-b3382b8843114eee.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/4293.928a8d573c16aab7.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/4402.f9238a3b18a7bd43.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/4490-9b090b0f9427f902.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/4548.13502d0ca3b4f862.js +0 -8
  582. package/apps/pwa/out/_next/static/chunks/4599-548bc96cda44a5a7.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/4625.206574e33a9e7ae8.js +0 -104
  584. package/apps/pwa/out/_next/static/chunks/4862-392c9a71f0d8dfb4.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/5054.2906d1b02542edc5.js +0 -149
  586. package/apps/pwa/out/_next/static/chunks/5102-c822bbbee5a022a4.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/5194-8c93f2e7e4b6f717.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/5305-bacd7eca0b9a5848.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/5311.9071ee3f44fd7ff5.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/5369.9f34353442daa421.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/589-49d730cb8138b397.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/5904-264a6412ae3c9028.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/5980.728531d5c566535c.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/599-a914cc0468f56143.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/6011.f525002e21bef0ac.js +0 -23
  596. package/apps/pwa/out/_next/static/chunks/6132.4381ab93683f1acf.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/6149.2e698635e454d8f6.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/6356-0afafc4230cf9767.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/6406.64756073f7df35b8.js +0 -77
  600. package/apps/pwa/out/_next/static/chunks/6479-16e62aedafa0e310.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/6599.b5246b46a2453329.js +0 -64
  602. package/apps/pwa/out/_next/static/chunks/6610.5c26eec011565acb.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/666.37d18474edc1c552.js +0 -2
  604. package/apps/pwa/out/_next/static/chunks/6904.a0b5b1ed4f2d2c20.js +0 -1
  605. package/apps/pwa/out/_next/static/chunks/7247-1f4aba94aba50d9f.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/7274-e71a7c5b7760cd02.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/7290.1fcaeef3adb5d0d4.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/7477-2c64e42760f82f33.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/7505-47002b76ff1aef6c.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/7600-11884ca4da68e5d9.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/7607.40d8bb3689697ccb.js +0 -62
  612. package/apps/pwa/out/_next/static/chunks/7752.5cbdd0b433c54af9.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/7763.f51fcc19ca1414ec.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/7785.846140c859b1adf6.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/7807-a0fdac6393e0bf36.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/7837-20a63b4b7e9342b1.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/800.7815414cf280545d.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/8085-1e5fce59500a2cc2.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/8100.415f2105faa63e97.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/8290.701aa42ed13aa767.js +0 -226
  621. package/apps/pwa/out/_next/static/chunks/83a80514-b897b64df43ce108.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/8444.d9c74214a3145a43.js +0 -93
  623. package/apps/pwa/out/_next/static/chunks/8569.98c915534928c7f9.js +0 -24
  624. package/apps/pwa/out/_next/static/chunks/8591.b1c7f876e5ec7cfb.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/8715-f63756021d3ab989.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/8879.776c2ec7732aa114.js +0 -115
  627. package/apps/pwa/out/_next/static/chunks/8881.ddca15b3c82c490c.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/8946.5da5c87f32a2e1a8.js +0 -41
  629. package/apps/pwa/out/_next/static/chunks/9117.080b9b75be90e14d.js +0 -74
  630. package/apps/pwa/out/_next/static/chunks/9167.f3ecb28f367d6e69.js +0 -94
  631. package/apps/pwa/out/_next/static/chunks/9224.66095370ee28c93b.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/9238-0682b013c83d6449.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/9449.d3ed795da4befb1c.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/949.1e7d45ccb71580aa.js +0 -90
  635. package/apps/pwa/out/_next/static/chunks/9638-d268329f2c6f4f8d.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/9842-d6644eb53d3dc6bf.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/9863.94ca3263e760696e.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/9938.b23e4d4dfa0114cd.js +0 -79
  639. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d9babd8795f396a5.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/app/approvals/page-a1ce306364f08da9.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-07110da72c45e68f.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/app/board/page-d2d76d4a7eae91bd.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/app/botlab/page-30007380f2e2a3c1.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/app/bots/page-e5a9302c105725a3.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/app/ceo/page-b93c04b5311c97ec.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/app/chat/page-718a49e86bf25f9c.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/app/consult/page-20662900d6b4b455.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/app/control/page-f707a509515ac50c.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/decisions/page-6a16a48d1aa6e91f.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/design-check/page-fcb06e305f515527.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/editor/page-6acf5ec4e6c6d1af.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/exec/page-39f82acf619cca23.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/field/page-7c2c8f81b185f9c0.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/healthz/route-d9babd8795f396a5.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/inside/page-ae7aff07e32676bb.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/intake/page-482c60c1bc540d0a.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/layout-7cb996c1aa08b6f5.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/live/page-623e08fe4477d606.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/live-run/page-db460cd8aecb8490.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/market/page-8397a5c6ca569bf4.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1917ea87ea71ab6b.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/not-found-670510eda8b9443f.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/observatory/page-d73c3f1e00d93986.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-65caacf54389081e.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-4bb7556e2e97a750.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-77e04b4f8762c666.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/outputs/page-15c0a4095baddfba.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/page-4eb96fc7241c2456.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/reflection/page-63e272a4cd3b6634.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-0d64ff212dc55d03.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/sessions/page-7f096248993fc2d4.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-e47fc72049149a38.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/settings/page-f7d808e31e005895.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-5c2b24b5496dad73.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/setup/layout-d9babd8795f396a5.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/setup/page-76cdb531668b5191.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/share/page-e2b63345bba1a11f.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/showroom/page-d376e0c83edc041a.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d6db55fe2c04d128.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/today/page-dab163b338e3b966.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/trace/page-08019efef111ed2e.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/vault/page-0260ffc7eda50db1.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-980ce6fe36ad95eb.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/workflows/page-99c4e6c7345a9156.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/workspace/page-0ab42e0f05823013.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-ad9220422d20ba33.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/dcf24383-2f82e35f2d827393.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/e117f801.e92bf10242653497.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/e87d89b9.2e71c0ae475d28a1.js +0 -122
  690. package/apps/pwa/out/_next/static/chunks/framework-bf135b997155e90e.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/main-5571537543bea91c.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/main-app-25c51c7df7f3a442.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/pages/_app-e3b2c1f5d82abd65.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/pages/_error-083f2e23e9bc3641.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/webpack-e94d22b7a028217b.js +0 -1
  696. package/src/dashboard/bench-slash-runtime.ts +0 -40
  697. package/src/dashboard/input/search-modal-router.ts +0 -9
  698. package/src/dashboard/modals/pane-key-router.ts +0 -27
  699. package/src/dashboard/view-slash-runtime.ts +0 -48
  700. /package/apps/pwa/out/_next/static/{Ev2jivDMTSoEc-5rIXdcy → cIpv5nU9AycwYWZI9H589}/_ssgManifest.js +0 -0
@@ -1,15 +1,31 @@
1
1
  import { execFileSync } from 'node:child_process';
2
2
  import { statSync } from 'node:fs';
3
- import { isAbsolute, relative, resolve } from 'node:path';
3
+ import { basename, extname, isAbsolute, relative, resolve } from 'node:path';
4
4
 
5
5
  export interface AskPathCandidateOptions {
6
6
  readonly cwd: string;
7
7
  readonly run?: (command: string, args: readonly string[], options: { cwd: string; encoding: 'utf8' }) => string;
8
8
  }
9
9
 
10
- export type AskPathCandidates =
11
- | { readonly tokens: string[]; readonly paths: string[]; readonly error?: undefined }
12
- | { readonly tokens: string[]; readonly paths: string[]; readonly error: string };
10
+ export interface AskPathCandidates {
11
+ readonly tokens: string[];
12
+ readonly paths: string[];
13
+ readonly evidence?: AskPathEvidence[];
14
+ readonly selection?: AskPathSelection;
15
+ readonly error?: string;
16
+ }
17
+
18
+ export interface AskPathEvidence {
19
+ readonly path: string;
20
+ readonly pathTokens: string[];
21
+ readonly strongestPathMatch: 'explicit-file' | 'filename' | 'directory' | null;
22
+ readonly contentTokens: string[];
23
+ readonly score: number;
24
+ }
25
+
26
+ export type AskPathSelection =
27
+ | { readonly path: string; readonly reason: 'unique-strongest-evidence' }
28
+ | { readonly path: null; readonly reason: 'tied-strongest-evidence' };
13
29
 
14
30
  const STOP_WORDS = new Set(['the', 'and', 'test', 'src', 'scripts', 'file', 'path', 'paths', 'code', 'with', 'from', 'this', 'that', 'into', 'for', 'then', 'when', 'have', 'does', 'should', 'will', 'please', 'target', 'change']);
15
31
  const WORD = /[-/]?[A-Za-z][A-Za-z0-9_.-]*(?:\/[A-Za-z0-9_.-]+)*/g;
@@ -63,7 +79,15 @@ function existingFile(fragment: string, cwd: string): string | null {
63
79
 
64
80
  /** Find existing code paths by lexical evidence from an unmodified ask. */
65
81
  export function findAskPathCandidates(askText: string, { cwd, run = execFileSync }: AskPathCandidateOptions): AskPathCandidates {
66
- const scores = new Map<string, Set<string>>();
82
+ const scores = new Map<string, { explicit: Set<string>; filename: Set<string>; directory: Set<string>; content: Set<string> }>();
83
+ const hitsFor = (path: string) => {
84
+ let hits = scores.get(path);
85
+ if (!hits) {
86
+ hits = { explicit: new Set(), filename: new Set(), directory: new Set(), content: new Set() };
87
+ scores.set(path, hits);
88
+ }
89
+ return hits;
90
+ };
67
91
  const tokens: string[] = [];
68
92
  const seen = new Set<string>();
69
93
  const body = stripAskWrapper(askText);
@@ -73,11 +97,7 @@ export function findAskPathCandidates(askText: string, { cwd, run = execFileSync
73
97
  const raw = match[0];
74
98
  const token = raw.replace(/^\//, '');
75
99
  const file = existingFile(token, cwd);
76
- if (file) {
77
- const hits = scores.get(file) ?? new Set<string>();
78
- hits.add(token);
79
- scores.set(file, hits);
80
- }
100
+ if (file) hitsFor(file).explicit.add(token);
81
101
  if (STOP_WORDS.has(token.toLowerCase()) || isGenericToken(token) || seen.has(token)) continue;
82
102
  if (!file && !token.includes('/') && !token.includes('.') && !token.includes('-') && !token.includes('_')
83
103
  && !/[a-z][A-Z]/.test(token) && token.length < 4) continue;
@@ -85,6 +105,24 @@ export function findAskPathCandidates(askText: string, { cwd, run = execFileSync
85
105
  tokens.push(token);
86
106
  }
87
107
  }
108
+ if (tokens.length > 0) {
109
+ let files: string;
110
+ try {
111
+ files = run('rg', ['--files', '--glob', '!*.test.ts', 'src', 'scripts'], { cwd, encoding: 'utf8' });
112
+ } catch (error) {
113
+ if ((error as { status?: number }).status === 1) files = '';
114
+ else return { tokens, paths: [], error: error instanceof Error ? error.message : String(error) };
115
+ }
116
+ for (const path of files.split(/\r?\n/).filter(Boolean)) {
117
+ const fileStem = basename(path, extname(path)).toLowerCase();
118
+ const directories = path.toLowerCase().split('/').slice(0, -1);
119
+ for (const token of tokens) {
120
+ const lower = token.toLowerCase();
121
+ if (fileStem === lower || basename(path).toLowerCase() === lower) hitsFor(path).filename.add(token);
122
+ else if (directories.includes(lower)) hitsFor(path).directory.add(token);
123
+ }
124
+ }
125
+ }
88
126
  for (const token of tokens) {
89
127
  let matches: string;
90
128
  try {
@@ -94,13 +132,30 @@ export function findAskPathCandidates(askText: string, { cwd, run = execFileSync
94
132
  return { tokens, paths: [], error: error instanceof Error ? error.message : String(error) };
95
133
  }
96
134
  for (const path of matches.split(/\r?\n/).filter(Boolean)) {
97
- const hits = scores.get(path) ?? new Set<string>();
98
- hits.add(token);
99
- scores.set(path, hits);
135
+ hitsFor(path).content.add(token);
100
136
  }
101
137
  }
138
+ const evidence = [...scores].map<AskPathEvidence>(([path, hits]) => {
139
+ const tier = hits.explicit.size > 0 ? 3 : hits.filename.size > 0 ? 2 : hits.directory.size > 0 ? 1 : 0;
140
+ return {
141
+ path,
142
+ pathTokens: [...new Set([...hits.explicit, ...hits.filename, ...hits.directory])],
143
+ strongestPathMatch: tier === 3 ? 'explicit-file' : tier === 2 ? 'filename' : tier === 1 ? 'directory' : null,
144
+ contentTokens: [...hits.content],
145
+ // Lexicographic tiers: even many directory hits cannot outrank one filename hit.
146
+ score: tier * 1000 + Math.min(hits.explicit.size + hits.filename.size + hits.directory.size, 9) * 100
147
+ + Math.min(hits.content.size, 99),
148
+ };
149
+ }).sort((a, b) => b.score - a.score || a.path.localeCompare(b.path, 'en'));
150
+ const top = evidence[0];
102
151
  return {
103
152
  tokens,
104
- paths: [...scores].sort(([a, aHits], [b, bHits]) => bHits.size - aHits.size || a.localeCompare(b, 'en')).slice(0, 5).map(([path]) => path),
153
+ paths: evidence.slice(0, 5).map(({ path }) => path),
154
+ ...(top ? {
155
+ evidence: evidence.slice(0, 5),
156
+ selection: evidence[1]?.score === top.score
157
+ ? { path: null, reason: 'tied-strongest-evidence' as const }
158
+ : { path: top.path, reason: 'unique-strongest-evidence' as const },
159
+ } : {}),
105
160
  };
106
161
  }
@@ -348,7 +348,31 @@ export interface DecomposeApplication {
348
348
  * ⓐ 같은 goal 을 «두 번» 쪼개지 않는다(alreadyDecomposed)
349
349
  * ⓑ 조각이 둘 미만인 제안은 애초에 안 온다(pickDecomposeProposals 가 거른다)
350
350
  * ⓒ 상한을 넘기면 «쪼개지 않는다» — 조각이 무한히 불어나는 것을 막는다
351
+ *
352
+ * ⭐ **조각은 원 골의 «대상 경로:» 머리줄을 물려받는다** (DECOMPOSE-PIECE-TARGET-LINE · 10-11 부검 run-76941fca):
353
+ * 조각 feature 가 골을 «통째로» 갈아 끼우면 첫 줄 선언이 사라져 Pod 예비 검사가 «대상 경로 0» →
354
+ * 재저작 NOT-GROUNDED 로 조각 전부가 exit 1 했다. 좁히는 규칙 = 원 선언 경로 중 조각 문장에
355
+ * 나오는 것만(없으면 원 선언 전부) · «신설:» 줄도 같은 규칙 · 첫 줄이 라벨이 아니면 지금 그대로.
351
356
  */
357
+
358
+ // ── 머리줄 선언을 읽고 좁히는 순수 조각 (위 규칙의 실물) ──────────────────────────
359
+ const TARGET_PATHS_LINE = /^대상 경로:[ \t]*(.*)$/;
360
+ const NEW_PATHS_LINE = /^신설:[ \t]*(.*)$/;
361
+
362
+ /** 선언 줄의 경로를 나눈다 — « · »·쉼표(`goal-new-paths` 와 같은 분리 규칙). 유효성은 걸러내지 않는다: 선언 그대로다. */
363
+ function splitDeclaredPaths(payload: string): string[] {
364
+ return payload.split(/[·,]/).map((token) => token.trim()).filter((token) => token.length > 0);
365
+ }
366
+
367
+ /** 조각 문장에 «나오는» 선언 경로만 남긴다. 하나도 안 나오면 원 선언 전부 — 선언 밖 경로는 지어내지 않는다. */
368
+ function narrowDeclaredPaths(declared: readonly string[], pieceFeature: string): string[] {
369
+ const mentioned = declared.filter((path) => {
370
+ const escaped = path.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
371
+ return new RegExp(`(^|[^\\w./-])${escaped}(?=$|[^\\w./-]|\\.(?:\\s|$))`).test(pieceFeature);
372
+ });
373
+ return mentioned.length ? mentioned : [...declared];
374
+ }
375
+
352
376
  export function applyDecomposeProposals(
353
377
  goals: readonly SelfDevGoal[],
354
378
  results: readonly SelfDevJobResult[],
@@ -374,11 +398,29 @@ export function applyDecomposeProposals(
374
398
  // ⛔ 상한을 넘기면 «쪼개지 않는다» — 조용히 자르지 않고 원본을 그대로 둔다.
375
399
  if (out.length + pieces.length + (goals.length - out.length - 1) > maxGoals) { out.push(goal); continue; }
376
400
  decomposed.push(goal.feature);
401
+ // 원 골의 머리줄 선언 — 첫 줄이 «대상 경로:» 가 아니면 조각은 지금 그대로(바이트 불변)다.
402
+ const goalLines = goal.feature.split('\n');
403
+ const targetLine = TARGET_PATHS_LINE.exec(goalLines[0] ?? '');
404
+ // «신설:» 상속은 머리줄 선언이 «있을 때만» — 첫 줄이 라벨이 아니면 조각은 바이트 불변이어야 한다.
405
+ const newLine = targetLine ? goalLines.map((line) => NEW_PATHS_LINE.exec(line)).find((m) => m !== null) : null;
377
406
  for (const piece of pieces) {
407
+ const inherited: string[] = [];
408
+ let paths: string[] = [];
409
+ if (targetLine) {
410
+ const declared = splitDeclaredPaths(targetLine[1]!);
411
+ paths = declared.length ? narrowDeclaredPaths(declared, piece.feature) : declared;
412
+ // 선언이 비어 있으면 원 줄을 그대로 실는다 — 라벨만이라도 예비 검사가 읽게 한다.
413
+ inherited.push(declared.length ? `대상 경로: ${paths.join(' · ')}` : goalLines[0]!);
414
+ }
415
+ if (newLine) {
416
+ const declaredNew = splitDeclaredPaths(newLine[1]!);
417
+ const narrowedNew = declaredNew.length ? narrowDeclaredPaths(declaredNew, piece.feature) : declaredNew;
418
+ inherited.push(declaredNew.length ? `신설: ${narrowedNew.join(' · ')}` : newLine[0]!);
419
+ }
378
420
  out.push({
379
421
  ...goal, // 승격 플래그(openPr·autoReview·autoMerge·base)를 물려받는다
380
422
  id: piece.id,
381
- feature: piece.feature,
423
+ feature: inherited.length ? [...inherited, piece.feature].join('\n') : piece.feature,
382
424
  ...(piece.dependsOn.length ? { dependsOn: [...piece.dependsOn] } : {}),
383
425
  // ⛔⭐ `...goal` 이 «부모의» hotPaths 를 그대로 흘린다 — 그러면 조각 전부가 서로 겹쳐
384
426
  // `orchestrate.ts` 가 전부를 직렬화한다(위상이 아니라 «한 줄»이 된다).
@@ -37,6 +37,8 @@ export const JOURNEY_NODE_IDS = [
37
37
  'salvage',
38
38
  'heal',
39
39
  'next-move',
40
+ 'ready',
41
+ 'pr-head-checkout',
40
42
  'stopped',
41
43
  ] as const;
42
44
  export type JourneyNodeId = typeof JOURNEY_NODE_IDS[number];
@@ -17,7 +17,7 @@ export interface LiveRunOverlapPath {
17
17
 
18
18
  /** 검사 대상 한 건이 막힌 이유. `name` 은 사람이 바로 열어 볼 수 있는 식별자다. */
19
19
  export interface LaunchPreflightBlocker {
20
- readonly kind: 'open-pr' | 'sibling-pr' | 'live-run' | 'no-target-paths' | 'recent-change' | 'ask-outside-path' | 'ask-marker';
20
+ readonly kind: 'open-pr' | 'sibling-pr' | 'live-run' | 'no-target-paths' | 'missing-traced-path' | 'goal-unreadable' | 'recent-change' | 'ask-outside-path' | 'ask-marker';
21
21
  /** `#8100` · `run-6ce5765b…` 처럼 «바로 조회 가능한» 이름. */
22
22
  readonly name: string;
23
23
  /** 왜 막혔는지 한 줄 — 경로와 수를 포함한다. */
@@ -490,6 +490,10 @@ export function renderLaunchPreflight(
490
490
  }
491
491
  lines.push(`[preflight] ⛔ 막는 것 ${result.blockers.length}건${forced ? '' : ' — 발사하지 않는다'}`);
492
492
  for (const blocker of result.blockers) lines.push(`[preflight] · ${blocker.name} — ${blocker.detail}`);
493
+ if (result.blockers.some((blocker) => blocker.kind === 'missing-traced-path' || blocker.kind === 'goal-unreadable')) {
494
+ lines.push('[preflight] 골 판독 실패 또는 traced path 오류는 --force-preflight 로 우회할 수 없다 — 골 문서와 경로를 바로잡아야 한다');
495
+ return lines.join('\n');
496
+ }
493
497
  lines.push(forced
494
498
  ? '[preflight] ⚠️ --force-preflight — 위 막힘을 «뚫고» 발사한다 (이 우회는 관측에 남는다)'
495
499
  : '[preflight] 그래도 가려면 --force-preflight (그 우회는 관측에 남는다) — elanous dev');
@@ -17,8 +17,10 @@
17
17
  // ⛔ 그래도 관측·산출에는 «그대로» 남긴다 — 「지나갔다」와 「없었다」는 다른 값이다.
18
18
 
19
19
  import { execFileSync } from 'node:child_process';
20
- import { existsSync } from 'node:fs';
21
- import { isAbsolute, resolve } from 'node:path';
20
+ import { closeSync, existsSync, lstatSync, openSync, readSync, statSync } from 'node:fs';
21
+ import { dirname, isAbsolute, resolve, sep } from 'node:path';
22
+ import { linesOutsideFencedCode } from '../self-implement/goal-author.js';
23
+ import { declaredNewFilePaths } from '../self-implement/goal-new-paths.js';
22
24
  import { resolveLogTargets } from '../cli/logs-cli.js';
23
25
  import { debug } from '../debug/log.js';
24
26
  import { siblingTestPath, normalizePreexistingFailureObservedAt, normalizePreexistingFailureRecords, emitAskMarkerObservation, emittedAskMarkerObservations, setAskMarkerObserver } from './launch-preflight-text.js';
@@ -734,8 +736,9 @@ export interface AskPreflightOptions {
734
736
  readonly openPrsLimit?: number;
735
737
  /** 중단 런 원장 조회의 최대 반환 행 수. 상한 도달은 결과의 `truncated` 상태로 남는다. */
736
738
  readonly interruptedRunsLimit?: number;
737
- /** ⛔ 저작 «전» 예비 검사용 — 주면 골 문서를 읽지 않고 이 경로로 판정한다(ask 힌트).
738
- * ⚠️ 이것은 «추정»이다. 정본은 저작된 골의 TRACED PATHS 이고 발사 직전에 다시 판정한다. */
739
+ /** ⛔ 저작 «전» 예비 검사용 — 충돌 판정에는 이 ask 힌트 경로를 쓴다.
740
+ * 골 파일이 이미 있으면 문서의 TRACED PATHS 는 별도로 읽어 누락을 검사한다.
741
+ * ⚠️ 힌트는 «추정»이다. 정본은 저작된 골의 TRACED PATHS 이고 발사 직전에 다시 판정한다. */
739
742
  readonly pathsOverride?: readonly string[];
740
743
  /** 원 ask 경로와 최종 대상의 차이를 ask-outside-path 경고에 보인다. */
741
744
  readonly askOutsidePathHints?: readonly string[];
@@ -770,6 +773,78 @@ export interface AskPreflightDecision {
770
773
  readonly plannedBranchResolution?: PlannedBranchResolution;
771
774
  }
772
775
 
776
+ /** OP #980: fragments kept by cleanup remain inspectable traced targets, including bare names. */
777
+ function isFileShapedTracedPath(path: string): boolean {
778
+ return path.trim().length > 0 && (!/\s/.test(path) || path.includes('/'));
779
+ }
780
+
781
+ // Keep lexical `..`/`.` segments: resolving them first hides ENOTDIR behind a file parent.
782
+ function tracedFsPath(path: string, root: string): string {
783
+ return isAbsolute(path) ? path : `${root}${root.endsWith(sep) ? '' : sep}${path}`;
784
+ }
785
+
786
+ function tracedPathExists(path: string, root: string): boolean {
787
+ try {
788
+ const target = tracedFsPath(path, root);
789
+ if (!statSync(target).isFile()) return false;
790
+ const fd = openSync(target, 'r');
791
+ try { readSync(fd, Buffer.alloc(1), 0, 1, 0); }
792
+ finally { closeSync(fd); }
793
+ return true;
794
+ }
795
+ catch { return false; }
796
+ }
797
+
798
+ function tracedPathIsFile(path: string, root: string): boolean {
799
+ try { return statSync(tracedFsPath(path, root)).isFile(); }
800
+ catch { return false; }
801
+ }
802
+
803
+ function tracedPathOccupation(path: string, root: string): 'occupied' | 'missing' | 'inaccessible' {
804
+ const target = tracedFsPath(path, root);
805
+ try { lstatSync(target); return 'occupied'; }
806
+ catch (error) {
807
+ if ((error as NodeJS.ErrnoException).code !== 'ENOENT') return 'inaccessible';
808
+ for (let parent = dirname(target); parent !== dirname(parent); parent = dirname(parent)) {
809
+ try {
810
+ if (lstatSync(parent).isSymbolicLink()) {
811
+ try { statSync(parent); } catch { return 'inaccessible'; }
812
+ }
813
+ } catch (parentError) {
814
+ if ((parentError as NodeJS.ErrnoException).code !== 'ENOENT') return 'inaccessible';
815
+ }
816
+ }
817
+ return 'missing';
818
+ }
819
+ }
820
+
821
+ /** Remove only malformed TRACED PATHS fragments before the child reads the goal file again. */
822
+ export function discardNonFileTracedPathItems(document: string, _root: string): { document: string; dropped: string[] } {
823
+ const dropped: string[] = [];
824
+ let inTracedPaths = false;
825
+ const outsideStarts = new Set(linesOutsideFencedCode(document).map((line) => line.start));
826
+ let offset = 0;
827
+ const lines = document.split('\n').flatMap((line) => {
828
+ const lineStart = offset;
829
+ offset += line.length + 1;
830
+ if (!outsideStarts.has(lineStart)) return [line];
831
+ const body = line.replace(/\r$/, '');
832
+ if (/^\s*##\s+TRACED PATHS\s*$/.test(body)) { inTracedPaths = true; return [line]; }
833
+ if (inTracedPaths && /^\s*#{1,6}\s/.test(body)) inTracedPaths = false;
834
+ if (!inTracedPaths) return [line];
835
+ const item = /^(\s*(?:[-*+]|\d+[.)])\s+)(.*)$/.exec(body);
836
+ if (!item) return [line];
837
+ // OP #980: a fragment with whitespace and no slash is prose; all other forms stay verbatim.
838
+ const fragments = item[2]!.split(' · ');
839
+ const kept = fragments.filter((fragment) => !(/\s/.test(fragment.trim()) && !fragment.includes('/')));
840
+ if (kept.length === fragments.length) return [line];
841
+ if (kept.length === 0) { dropped.push(line); return []; }
842
+ dropped.push(line);
843
+ return [`${item[1]}${kept.join(' · ')}${line.endsWith('\r') ? '\r' : ''}`];
844
+ });
845
+ return { document: lines.join('\n'), dropped };
846
+ }
847
+
773
848
  /** 인자 검증 — ⛔ 잘못된 값을 «조용히» 기본값으로 바꾸지 않는다(리뷰 should-fix). */
774
849
  /** ⛔ 기본값은 «내부 상수»다 — 아무도 안 넘기는 인자를 계약 표면으로 두지 않는다(리뷰 must-fix). */
775
850
  export const DEFAULT_LIVE_RUN_WINDOW_MINUTES = 30;
@@ -1001,20 +1076,48 @@ export function decideAskPreflight(
1001
1076
  ): AskPreflightDecision {
1002
1077
  const limit = opts.openPrsLimit ?? 200;
1003
1078
  const interruptedRunsLimit = resolveInterruptedRunsLimit(opts.interruptedRunsLimit);
1004
- // ⛔⭐ 「저작 전 예비 검사」 경로 — 골 파일이 «아직 없다». 그때는 ask 힌트를 대상 경로로 쓴다.
1005
- // ⚠️ 골 문서를 읽지 «않는다» — 없는 파일을 읽으려 하면 여기서 던져 저작 자체가 막힌다.
1079
+ // pathsOverride is an independent pre-authoring inspection, even if a stale goal file exists.
1006
1080
  let goalDocument: string | null = null;
1007
1081
  let goalRulersUnknownReason: string | undefined;
1082
+ let goalReadFailed = false;
1083
+ const resolvedGoalFile = opts.declaredPathsRoot?.trim() && !isAbsolute(opts.goalFile)
1084
+ ? resolve(opts.declaredPathsRoot, opts.goalFile)
1085
+ : opts.goalFile;
1008
1086
  if (!opts.pathsOverride) {
1009
1087
  try {
1010
- goalDocument = deps.readGoalDocument(opts.goalFile);
1088
+ goalDocument = deps.readGoalDocument(resolvedGoalFile);
1011
1089
  } catch (error) {
1090
+ goalReadFailed = true;
1012
1091
  goalRulersUnknownReason = `골 문서 판독 불가: ${error instanceof Error ? error.message.split('\n')[0] : String(error)}`;
1013
1092
  }
1014
1093
  } else {
1015
1094
  goalRulersUnknownReason = '저작 전 예비 검사에는 골 문서가 없다';
1016
1095
  }
1017
- const tracedPaths = opts.pathsOverride ?? (goalDocument === null ? [] : deps.tracedPaths(goalDocument));
1096
+ // Resolve against the caller's root, but keep injected virtual goal documents out of
1097
+ // filesystem checks when no authored file exists there.
1098
+ const hasAuthoredGoal = !opts.pathsOverride && opts.goalFile !== '' && goalDocument !== null
1099
+ && existsSync(resolvedGoalFile);
1100
+ const authoredTracedPaths = goalDocument === null ? [] : deps.tracedPaths(goalDocument);
1101
+ const tracedPathsRaw = opts.pathsOverride ?? authoredTracedPaths;
1102
+ const inspectionRoot = goalDocument === null || !hasAuthoredGoal
1103
+ ? undefined
1104
+ : opts.declaredPathsRoot?.trim() || process.cwd();
1105
+ const tracedPaths = inspectionRoot && !opts.pathsOverride
1106
+ ? tracedPathsRaw.filter((path) => tracedPathExists(path, inspectionRoot) || isFileShapedTracedPath(path))
1107
+ : tracedPathsRaw;
1108
+ const declaredNewPaths = goalDocument === null ? new Set<string>() : new Set(declaredNewFilePaths(goalDocument));
1109
+ const invalidTracedPaths: Array<{ path: string; reason: 'occupied-new' | 'not-file' | 'missing' | 'inaccessible' }> = inspectionRoot
1110
+ ? authoredTracedPaths.flatMap<{ path: string; reason: 'occupied-new' | 'not-file' | 'missing' | 'inaccessible' }>((path) => {
1111
+ const occupation = tracedPathOccupation(path, inspectionRoot);
1112
+ if (!isFileShapedTracedPath(path) && occupation !== 'occupied') return [];
1113
+ const isDeclaredNew = declaredNewPaths.has(path.replace(/^\.\//, ''));
1114
+ if (isDeclaredNew) return occupation === 'missing' ? [] : [{ path, reason: occupation === 'occupied' ? 'occupied-new' as const : 'inaccessible' as const }];
1115
+ if (tracedPathExists(path, inspectionRoot)) return [];
1116
+ return [{ path, reason: occupation === 'occupied'
1117
+ ? (tracedPathIsFile(path, inspectionRoot) ? 'inaccessible' as const : 'not-file' as const)
1118
+ : occupation }];
1119
+ })
1120
+ : [];
1018
1121
  let premiseMockedBySignal: number | null = null;
1019
1122
  let invariantFunctionExits: number | null = null;
1020
1123
  if (goalDocument !== null) {
@@ -1197,11 +1300,41 @@ export function decideAskPreflight(
1197
1300
  ...(interruptedRunsUnknownReason ? { interruptedRunsUnknownReason } : {}),
1198
1301
  ...(recentChangesUnknownReason ? { recentChangesUnknownReason } : {}),
1199
1302
  });
1200
- const decisionResult = { ...result, warnings: [...result.warnings, ...askMarkerWarnings], runningRunsConfidenceAppendix: runningRunsConfidence.appendix };
1303
+ const missingTracedPathBlockers: LaunchPreflightBlocker[] = [
1304
+ ...(hasAuthoredGoal && authoredTracedPaths.length === 0 ? [{
1305
+ kind: 'missing-traced-path' as const,
1306
+ name: '최종 골의 TRACED PATHS 경로 0',
1307
+ detail: '정리 후 보존된 traced 경로가 없다 — 실제 파일 또는 유효한 신설: 파일 경로를 골에 선언해야 발사할 수 있다',
1308
+ }] : []),
1309
+ ...invalidTracedPaths.map(({ path, reason }) => ({
1310
+ kind: 'missing-traced-path' as const,
1311
+ name: reason === 'occupied-new' ? `신설 traced path 가 이미 점유됨: ${path}`
1312
+ : reason === 'not-file' ? `traced path 가 파일이 아님: ${path}`
1313
+ : reason === 'inaccessible' ? `traced path 경로 접근 불가: ${path}` : `실재하지 않는 traced path: ${path}`,
1314
+ detail: reason === 'occupied-new'
1315
+ ? `골의 신설: 경로 ${path} 가 이미 파일·디렉터리·링크로 점유돼 있다 — 새 파일 경로를 바로잡아야 한다`
1316
+ : reason === 'not-file'
1317
+ ? `골의 TRACED PATHS 경로 ${path} 가 존재하지만 읽을 수 있는 파일이 아니다 — 파일 경로를 바로잡아야 한다`
1318
+ : reason === 'inaccessible'
1319
+ ? `골의 TRACED PATHS 경로 ${path} 를 검사할 수 없다 — 부모가 파일이거나 접근 권한이 없다. 경로를 바로잡아야 한다`
1320
+ : `골의 TRACED PATHS 에 선언됐지만 ${inspectionRoot} 에 없고 유효한 신설: 목록에도 없다 — 발사 전에 골 경로를 바로잡아야 한다. 신설은 파일 경로로(확장자 포함) 선언한다`,
1321
+ })),
1322
+ ];
1323
+ const goalReadBlockers: LaunchPreflightBlocker[] = goalReadFailed ? [{
1324
+ kind: 'goal-unreadable',
1325
+ name: `골 문서 판독 불가: ${opts.goalFile}`,
1326
+ detail: `${goalRulersUnknownReason} — 최종 골의 traced path 를 확인할 수 없어 발사를 멈춘다`,
1327
+ }] : [];
1328
+ const decisionResult = {
1329
+ ...result,
1330
+ blockers: [...result.blockers, ...missingTracedPathBlockers, ...goalReadBlockers],
1331
+ warnings: [...result.warnings, ...askMarkerWarnings],
1332
+ runningRunsConfidenceAppendix: runningRunsConfidence.appendix,
1333
+ };
1201
1334
  emittedAskMarkerObservations.add(decisionResult);
1202
1335
  return {
1203
1336
  result: decisionResult,
1204
- shouldLaunch: result.blockers.length === 0 || force,
1337
+ shouldLaunch: missingTracedPathBlockers.length === 0 && goalReadBlockers.length === 0 && (result.blockers.length === 0 || force),
1205
1338
  plannedBranchResolution,
1206
1339
  };
1207
1340
  }
@@ -11,6 +11,7 @@ import { sweepFrozenMerges } from '../self-implement/frozen-merges.js';
11
11
  import { routeSupervisorVerdict } from './supervisor-verdict-edges.js';
12
12
  import { recordTaskAgentShadowMove, runCardFor, type TaskAgentShadowInput } from '../task-agent/shadow.js';
13
13
  import { cardPrNumber, taskAgentStatePath } from '../task-agent/task-hand.js';
14
+ import { classifyMustFixRound, inferMustFixEvidence, type MustFixRoundClassification, type MustFixRoundObservation } from '../self-implement/review-mustfix-class.js';
14
15
 
15
16
  export interface SupervisorRound {
16
17
  round: number;
@@ -46,6 +47,8 @@ export interface SupervisorRound {
46
47
  * streak pairs rounds by this key. Omitted on older history — the guard then pairs by taskId as before.
47
48
  */
48
49
  noPrFeatureKeys?: string[];
50
+ /** REVIEW-MUSTFIX-CLASSIFY — that round's observed must-fix items; pairs the next round's classification. */
51
+ mustFix?: MustFixRoundObservation;
49
52
  }
50
53
 
51
54
  /** Failed without a PR — a result that carries either a PR number or a PR URL has one (fixtures and older producers set only one). */
@@ -116,6 +119,10 @@ export interface SupervisorDecision {
116
119
  deliverableUnmeasured: boolean;
117
120
  deliverableMergeCompleteness: 'unmeasured' | 'complete' | 'incomplete';
118
121
  reviewMustFixTrend: ReviewRework['trend'];
122
+ /** REVIEW-MUSTFIX-CLASSIFY — this round's leading must-fix class (② › ③ observed › ①); omitted when unmeasured (지금 동작 그대로). */
123
+ mustFix?: MustFixRoundClassification;
124
+ /** REVIEW-MUSTFIX-CLASSIFY — every oscillating task's measured class, so a mixed round keeps each task's decision. */
125
+ mustFixByTask?: Record<string, MustFixRoundClassification>;
119
126
  oscillation?: { taskIds: string[]; helper: 'review-oscillation'; signature: string; repairGoals?: Record<string, string>; heldTaskIds?: string[] };
120
127
  pendingDecision?: 'attempt-care-escalation';
121
128
  }
@@ -234,6 +241,41 @@ export function aggregateReviewTrend(results: readonly SelfDevJobResult[]): Revi
234
241
  return severity[Math.max(...trends.map((trend) => severity.indexOf(trend)))];
235
242
  }
236
243
 
244
+ /**
245
+ * REVIEW-MUSTFIX-CLASSIFY — this round's must-fix observation from the results' verbatim `reviewMustFix`.
246
+ * Each item carries its `taskId` so the next round pairs per task (one task's recurrence never holds another).
247
+ */
248
+ function mustFixFromResults(results: readonly SupervisorJobResult[]): MustFixRoundObservation {
249
+ const items = results.flatMap((result) => (result.reviewMustFix ?? []).map((text) => {
250
+ const evidence = inferMustFixEvidence(text);
251
+ return { text, taskId: result.taskId, ...(evidence === undefined ? {} : { evidence }) };
252
+ }));
253
+ return items.length > 0 ? { items } : {};
254
+ }
255
+
256
+ /**
257
+ * REVIEW-MUSTFIX-CLASSIFY — per-task class. `prev` is the preceding round's items of the same task or its repair
258
+ * lineage (`oscillationRepairOf`), and only when that preceding round authored a repair for it — «수리 뒤 같은 지적»
259
+ * means a repair ran between the last observation and this one, not «repaired at any time». Lineage items are
260
+ * re-scoped to this task so the pure pairing accepts them; unrelated tasks never pair.
261
+ */
262
+ function classifyTaskMustFix(result: SupervisorJobResult, preceding: SupervisorRound | undefined): MustFixRoundClassification {
263
+ const pairIds = new Set([result.taskId, ...(result.oscillationRepairOf ? [result.oscillationRepairOf] : [])]);
264
+ const repairedSincePrev = (preceding?.oscillationRepairTaskIds ?? []).some((id) => pairIds.has(id));
265
+ const prevItems = repairedSincePrev
266
+ ? (preceding?.mustFix?.items ?? []).filter((item) => item.taskId !== undefined && pairIds.has(item.taskId))
267
+ .map((item) => ({ ...item, taskId: result.taskId }))
268
+ : [];
269
+ return classifyMustFixRound(prevItems.length > 0 ? { items: prevItems } : undefined, mustFixFromResults([result]));
270
+ }
271
+
272
+ /**
273
+ * Classes that hold a task out of this round's same-run repair. Only ② acts in this slice; ③ recurring is
274
+ * observed (decision `mustFix`/`mustFixByTask` · crossReview suggestion) but behaves as ① — acting on it is a
275
+ * follow-up cell (REVIEW-MUSTFIX-CLASSIFY partial landing).
276
+ */
277
+ const MUST_FIX_HELD = new Set<MustFixRoundClassification['class']>(['post-land-evidence']);
278
+
237
279
  export function decideNextRun(input: {
238
280
  results: readonly SupervisorJobResult[];
239
281
  history?: readonly SupervisorRound[];
@@ -520,8 +562,27 @@ export function decideNextRun(input: {
520
562
  || (entry.oscillationRepairFeatures?.[index] !== undefined && entry.oscillationRepairFeatures[index] === result.feature
521
563
  && Object.values(entry.oscillationRepairGoals ?? {}).includes(result.feature))));
522
564
  // Per task: a task that already got its one oscillation repair is held for a human; a fresh one may get it.
523
- const fresh = oscillating.filter((result) => !isRepaired(result));
524
- const held = [...new Set(oscillating.filter(isRepaired).map((result) => result.taskId))];
565
+ // REVIEW-MUSTFIX-CLASSIFY — 슈퍼바이저는 추이 대신 회차 분류를 먼저 본다(대표 10-12 «노하우가 아니라 로직으로» · 임의 임계 없음).
566
+ // ① new-defect — 그대로 수렴(진동 수리 유지).
567
+ // ② post-land-evidence — 증거는 착지 뒤에만 난다 ⇒ 같은 런 재수리 0, «그림자 착지 → 관측 → live» 쪼개기 결정.
568
+ // ③ recurring — 수리 뒤 같은 지적 ⇒ 이 조각에선 관측만(교차 리뷰 제안을 결정에 싣고 동작은 ① 그대로 · 후속 칸).
569
+ // unmeasured — 분류 불가 ⇒ 지금 동작 그대로. 분류는 조각마다 — 한 조각의 분류가 다른 조각의 수리를 끊지 않는다.
570
+ const taskClasses = new Map(oscillating.map((result) => [result.taskId, classifyTaskMustFix(result, preceding)]));
571
+ const fresh = oscillating.filter((result) => !isRepaired(result) && !MUST_FIX_HELD.has(taskClasses.get(result.taskId)!.class));
572
+ const classes = [...taskClasses.values()];
573
+ // Decision-level class: ② (the only acting class) first, then observed ③, else ①.
574
+ const mustFixClass = classes.find((c) => c.class === 'post-land-evidence') ?? classes.find((c) => c.class === 'recurring')
575
+ ?? classes.find((c) => c.class === 'new-defect');
576
+ // Held = already repaired once, or classified ② — either way it never rides this round's rerun.
577
+ const classHeld = [...new Set(oscillating.filter((result) => !isRepaired(result)
578
+ && MUST_FIX_HELD.has(taskClasses.get(result.taskId)!.class)).map((result) => result.taskId))];
579
+ const held = [...new Set([...oscillating.filter(isRepaired).map((result) => result.taskId), ...classHeld])];
580
+ const repairedHeld = held.filter((id) => !classHeld.includes(id));
581
+ // Every task's measured class survives in the decision — a mixed round keeps ② split and the observed ③ cross-review suggestion both.
582
+ const mustFixByTask: Record<string, MustFixRoundClassification> = Object.fromEntries(
583
+ [...taskClasses].filter(([, c]) => c.class !== 'unmeasured'));
584
+ const heldReasons = [...new Set(classes.filter((c) => MUST_FIX_HELD.has(c.class)).map((c) => c.reason))];
585
+ const heldReasonSuffix = heldReasons.length ? ` · ${heldReasons.join(' · ')}` : '';
525
586
  const repairGoals: Record<string, string> = Object.fromEntries(fresh.flatMap((result) => {
526
587
  const goal = result.prNumber && result.reviewMustFix?.length
527
588
  ? authorRepairGoal({ pr: result.prNumber, category: 'review-oscillation', originalRequest: result.feature,
@@ -551,14 +612,16 @@ export function decideNextRun(input: {
551
612
  } : {}),
552
613
  action,
553
614
  ...(action === 'stop' ? { stopReason: 'review-oscillating' as const } : {}),
615
+ ...(mustFixClass ? { mustFix: mustFixClass } : {}),
616
+ ...(Object.keys(mustFixByTask).length ? { mustFixByTask } : {}),
554
617
  oscillation: { taskIds, helper: 'review-oscillation', signature, ...(Object.keys(repairGoals).length ? { repairGoals } : {}),
555
618
  ...(action === 'add-repair-task' && held.length ? { heldTaskIds: held } : {}) },
556
619
  pendingDecision: 'attempt-care-escalation',
557
620
  why: fresh.length === 0
558
- ? `리뷰 진동 반복 — ${signatureOf(oscillating)} · 사람 결정 필요(같은 전략 재발사 금지)`
621
+ ? `리뷰 진동 반복 — ${signatureOf(oscillating)} · 사람 결정 필요(같은 전략 재발사 금지)${heldReasonSuffix}`
559
622
  : cannotRepair
560
- ? `리뷰 진동 — ${signatureOf(oscillating)} · ${input.repairGoalExecution === false ? '이 감독 경로가 수리 골 실행을 선언하지 않았다(미선언 또는 불가)' : '수리 원문/PR 관측 불가'} · 사람 결정 필요(같은 전략 재발사 금지)`
561
- : `리뷰 진동 — ${signatureOf(fresh)} · review-oscillation 수리 조각을 한 번 붙인다${input.repairGoalExecution === true ? '' : '(실행 배선 미선언 — 결정 칸만)'}${held.length ? ` · 이미 수리한 조각 ${held.join(', ')} 은 사람 결정 대기` : ''}`,
623
+ ? `리뷰 진동 — ${signatureOf(oscillating)} · ${input.repairGoalExecution === false ? '이 감독 경로가 수리 골 실행을 선언하지 않았다(미선언 또는 불가)' : '수리 원문/PR 관측 불가'} · 사람 결정 필요(같은 전략 재발사 금지)${heldReasonSuffix}`
624
+ : `리뷰 진동 — ${signatureOf(fresh)} · review-oscillation 수리 조각을 한 번 붙인다${input.repairGoalExecution === true ? '' : '(실행 배선 미선언 — 결정 칸만)'}${repairedHeld.length ? ` · 이미 수리한 조각 ${repairedHeld.join(', ')} 은 사람 결정 대기` : ''}${classHeld.length ? ` · 분류로 보류한 조각 ${classHeld.join(', ')}` : ''}${heldReasonSuffix}`,
562
625
  };
563
626
  }
564
627
 
@@ -588,6 +651,8 @@ export function appendRound(
588
651
  const t = triageRun(results.filter((result) => result.salvage !== 'launched'), undefined, false, undefined, mainSyncRelaunchSpent(history));
589
652
  const baseCompleted = countBaseCompleted(results);
590
653
  const base = roundBase(results);
654
+ // REVIEW-MUSTFIX-CLASSIFY — 회차 원장에 관측을 실어 다음 회차 짝으로 쓴다(관측 없는 옛 원장은 그대로).
655
+ const mustFix = mustFixFromResults(results.filter((result) => result.salvage !== 'launched'));
591
656
  const noPrResults = results.filter(failedWithoutPr);
592
657
  const noPrTaskIds = noPrResults.map((result) => result.taskId);
593
658
  const noPrFeatureKeys = noPrResults.map((result) => noPrStreakKey(result.feature));
@@ -597,6 +662,7 @@ export function appendRound(
597
662
  ...(baseCompleted > 0 || base !== undefined ? { baseCompleted, ...(base === undefined ? {} : { base }) } : {}),
598
663
  actionable: countActionable(t),
599
664
  ...(reviewMustFixTrend === undefined ? {} : { reviewMustFixTrend }),
665
+ ...((mustFix.items ?? []).length > 0 ? { mustFix } : {}),
600
666
  ...(results.some((result) => result.rework?.signature)
601
667
  ? { signatures: Object.fromEntries(results.filter((result) => result.rework?.signature).map((result) => [result.taskId, result.rework!.signature])) } : {}),
602
668
  ...(decision && decision.action !== 'stop' && decision.relaunchOnMain.length > 0 ? {
@@ -16,6 +16,8 @@ export interface GateShardAttempt {
16
16
  baselineExitCode: number | null;
17
17
  currentSignal?: string | null;
18
18
  baselineSignal?: string | null;
19
+ currentDiagnostic?: string;
20
+ baselineDiagnostic?: string;
19
21
  /** LIGHT-RC-MEASURE — the shard files that exist in the baseline tree, i.e. what the baseline side actually ran.
20
22
  * Absent = every shard file (the old shape). Empty = the baseline side was not run and contributes zero cases. */
21
23
  baselineFiles?: readonly string[];
@@ -1,7 +1,7 @@
1
1
  import { existsSync, mkdtempSync, readFileSync, rmSync, statSync } from 'node:fs';
2
2
  import { tmpdir } from 'node:os';
3
3
  import { join } from 'node:path';
4
- import { debug } from '../debug/log.js';
4
+ import { debug, redactSecretText } from '../debug/log.js';
5
5
  import { prepareDeterministicChildEnvironment } from '../../scripts/lib/deterministic-env.js';
6
6
  import { withBaselineWorktree } from '../self-implement/gate-baseline.js';
7
7
  import { aggregateGateTestShards, type GateShardAttempt, type GateShardAggregate } from './shard-aggregate.js';
@@ -21,8 +21,25 @@ export type ShardProcess = (cwd: string, files: readonly string[]) => {
21
21
  junit?: string;
22
22
  rssMb?: number;
23
23
  seconds?: number;
24
+ /** Bounded, redacted process output for an abnormal exit before JUnit exists. */
25
+ diagnostic?: string;
24
26
  };
25
27
 
28
+ const DIAGNOSTIC_STREAM_LIMIT = 240;
29
+
30
+ function boundedDiagnostic(stdout: Uint8Array, stderr: Uint8Array): string | undefined {
31
+ const oneStream = (bytes: Uint8Array): string => {
32
+ const safe = redactSecretText(Buffer.from(bytes).toString('utf8')).replace(/[\r\n\t\x00-\x1f\x7f]+/g, ' ').trim();
33
+ if (safe.length <= DIAGNOSTIC_STREAM_LIMIT) return safe;
34
+ // Bun can print the cause after a long preamble; keep both ends within the same bound.
35
+ const head = Math.floor((DIAGNOSTIC_STREAM_LIMIT - 1) / 2);
36
+ return `${safe.slice(0, head)}…${safe.slice(-(DIAGNOSTIC_STREAM_LIMIT - 1 - head))}`;
37
+ };
38
+ const out = oneStream(stdout);
39
+ const err = oneStream(stderr);
40
+ return [out && `stdout: ${out}`, err && `stderr: ${err}`].filter(Boolean).join(' · ') || undefined;
41
+ }
42
+
26
43
  /** Absent only when the path provably is not a file there (missing, or not a regular file); any other stat error
27
44
  * (permissions …) is not evidence of absence, so the file stays in the baseline run (fail-closed: unmeasured). */
28
45
  const absentAtBaseline = (path: string): boolean => {
@@ -102,6 +119,7 @@ export function runShardedGateTests(
102
119
  currentJUnit: current.junit, baselineJUnit: base.junit,
103
120
  currentExitCode: current.exitCode, baselineExitCode: base.exitCode,
104
121
  currentSignal: current.signal, baselineSignal: base.signal,
122
+ currentDiagnostic: current.diagnostic, baselineDiagnostic: base.diagnostic,
105
123
  baselineFiles,
106
124
  });
107
125
  }
@@ -125,10 +143,13 @@ export function runBunShard(cwd: string, files: readonly string[]): ReturnType<S
125
143
  const result = Bun.spawnSync(['bun', ...args], {
126
144
  cwd, env: isolated.env, stdout: 'pipe', stderr: 'pipe', timeout: 300_000,
127
145
  });
146
+ const junit = existsSync(report) ? readFileSync(report, 'utf8') : undefined;
128
147
  return {
129
148
  exitCode: result.exitCode,
130
149
  signal: result.signalCode ? String(result.signalCode) : undefined,
131
- junit: existsSync(report) ? readFileSync(report, 'utf8') : undefined,
150
+ junit,
151
+ ...(junit === undefined && (result.exitCode !== 0 || result.signalCode)
152
+ ? { diagnostic: boundedDiagnostic(result.stdout, result.stderr) } : {}),
132
153
  rssMb: measured ? result.resourceUsage.maxRSS / (1024 * 1024) : undefined,
133
154
  seconds: measured ? (performance.now() - started) / 1000 : undefined,
134
155
  };