elanous 0.2.36 → 0.2.37

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 (630) 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/{uC-N0emedeNOFuaBQFv-I → 8kITumG9GAZ1LwT9POrAR}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/1041-5841aae848fb6403.js +1 -0
  5. package/apps/pwa/out/_next/static/chunks/1087.3177e54f672dc526.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1105.efe1e13503ac7a33.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1224.2ceca6c180d5130b.js +62 -0
  8. package/apps/pwa/out/_next/static/chunks/{4286.b70c4520306817e8.js → 1262.a89bb27a5b2f844e.js} +1 -1
  9. package/apps/pwa/out/_next/static/chunks/1417-1768233ac92f8a5d.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1612.81bbc19af06af16c.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/{3410.7f9af5ab77cbe65f.js → 1746.3563617ea64023a3.js} +1 -1
  12. package/apps/pwa/out/_next/static/chunks/1766.728d42053070bb2d.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1773.d38e945481e04125.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1974-c12f9600da3d3c26.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1ed5e8af.cf424815c7c0efad.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/{9250-072df22eaadaa6b5.js → 2002-a43a3f380df873ec.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/2061.7232dc9dc058417f.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/210.90b2cbd64926cf34.js +32 -0
  19. package/apps/pwa/out/_next/static/chunks/{3727.7949ccaacaa71242.js → 2283.edd9627b7bdfb546.js} +2 -2
  20. package/apps/pwa/out/_next/static/chunks/2318-450e75d07605b8fe.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/{4615.8525eb0add35eba6.js → 2375.bf364c85dbb6f085.js} +1 -1
  22. package/apps/pwa/out/_next/static/chunks/244-a810d282a20f1783.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/2479-fe7e188bd9402d14.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2514.03b60f266531a015.js +148 -0
  25. package/apps/pwa/out/_next/static/chunks/2526-a657538869888604.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2533-6f0341ff075809e9.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2676.e7994c695ef0f30d.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2734.3ffdf54254fb6f99.js +27 -0
  29. package/apps/pwa/out/_next/static/chunks/2770-23252bf3a37880b9.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/2969.66b8b545139d1544.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/3128.a9210d08800ea6a8.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{5711.957b095705c12560.js → 3199.6a1a9b0e6cd01dc6.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/3212.12179fd3eee8cef1.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/{2986.45d7652e4f13557e.js → 3578.4e9f9948a9a6f2f4.js} +2 -2
  35. package/apps/pwa/out/_next/static/chunks/3760-2909ddb9279281cd.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3825.1921b5901bf33dce.js +36 -0
  37. package/apps/pwa/out/_next/static/chunks/3994-63eb884ed0547011.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/4036.d54e55e1ebf5acdc.js +90 -0
  39. package/apps/pwa/out/_next/static/chunks/4115.5b438b99f0ae729f.js +226 -0
  40. package/apps/pwa/out/_next/static/chunks/4269.d8f9f34bb0fc6c43.js +287 -0
  41. package/apps/pwa/out/_next/static/chunks/431-4eed5bd2c5fe1719.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/{7481.39f7a4654907bf6e.js → 4313.76f232c304a15bde.js} +1 -1
  43. package/apps/pwa/out/_next/static/chunks/4324.c99ba3e83eb1b691.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4337e36d.f42c3b391b3d8f20.js +122 -0
  45. package/apps/pwa/out/_next/static/chunks/{6943.c6b24124853a47b2.js → 4383.18e5c54db3a22c88.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/4599-96eff3f2a9c242c1.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{3757-180308bc61021b05.js → 4725-34bed25720cc326b.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/4825-a9d9d4e9f5892309.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4833-7934c592c5569f00.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4879-68518f547a207aff.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4896.f9b70285363b27b2.js +24 -0
  52. package/apps/pwa/out/_next/static/chunks/{771.c3cdb6c1f7f47c02.js → 4931.95cc6dbd230774ca.js} +3 -3
  53. package/apps/pwa/out/_next/static/chunks/4937-28d437999b77c9dd.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/49aa54ab.80f39398e0ed0f30.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/{552.b7d061ad91eeac51.js → 5046.7fd5cbd859299448.js} +2 -2
  56. package/apps/pwa/out/_next/static/chunks/5056.482687319b82638e.js +104 -0
  57. package/apps/pwa/out/_next/static/chunks/506.16b83d56a437a9ee.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5260-20593b0a25d0afbc.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5404.cc4e9fec26fd5925.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/576.485e83e3f3dec19a.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5832-a6be14e663f65726.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5854-56648a9fe646b9a0.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/{9f31e478.fefcbcd3c388ebc5.js → 58edce7d.f1b0c72acf13b123.js} +1 -1
  64. package/apps/pwa/out/_next/static/chunks/5925.3b1f8b135710249b.js +93 -0
  65. package/apps/pwa/out/_next/static/chunks/{3136.30aaaa5fa03662a3.js → 5952.294fc574a8625184.js} +1 -1
  66. package/apps/pwa/out/_next/static/chunks/{da5ecc5c-b005ad8cac737d57.js → 5f6af561-f90b7a67f4f75d13.js} +1 -1
  67. package/apps/pwa/out/_next/static/chunks/6168.17749aa3905fa073.js +74 -0
  68. package/apps/pwa/out/_next/static/chunks/{3324.a09703033abcbd2f.js → 6252.240578f10952e091.js} +1 -1
  69. package/apps/pwa/out/_next/static/chunks/6416.5d50b8ec9986ca98.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/{8904.7d51af2dc033965c.js → 6680.6a693c28aae4cd19.js} +2 -2
  71. package/apps/pwa/out/_next/static/chunks/{275-02ea4c2a33980422.js → 6745-5a63492933959dd9.js} +3 -3
  72. package/apps/pwa/out/_next/static/chunks/6758.e7fbf532953c0783.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6795.0cb8a59730d99703.js +149 -0
  74. package/apps/pwa/out/_next/static/chunks/{528.38ce20ef8aa251ff.js → 6819.be5c9c4d67f22922.js} +3 -3
  75. package/apps/pwa/out/_next/static/chunks/6877-84d47b7e85d0c41e.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6971-fb5f9dc0a2cb5d2d.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/{3a3d9966.cc4d4585a2708e7c.js → 709a918c.4fd3b4e2a32cb4e3.js} +1 -1
  78. package/apps/pwa/out/_next/static/chunks/717.522b08685979b814.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/7191.e41eb8f455c7f089.js +41 -0
  80. package/apps/pwa/out/_next/static/chunks/7233.8e744b7513119409.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7238-97c2226f80504bd8.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/7285.307963afcf7e7660.js +24 -0
  83. package/apps/pwa/out/_next/static/chunks/7299-fbe4b8c47a87614a.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7314.df0d95930b0c3f50.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7406.c0589fdf2ee66629.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/{4304.e9b2512834a9e23e.js → 7424.c0fe2a595d4232b5.js} +1 -1
  87. package/apps/pwa/out/_next/static/chunks/752-90e3e7daad3d8e39.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7524-bcd3d9928c6842d9.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7549.9a4de3bf231cfc52.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/757-4fbaf50942b8c424.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/765.76ae970ceb597b5b.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{2683.c9773a0c589b031b.js → 7867.e8725745ddd1d940.js} +4 -4
  93. package/apps/pwa/out/_next/static/chunks/{6466-92e65a48490b68a9.js → 7893-e444a1b0809cd1e4.js} +1 -1
  94. package/apps/pwa/out/_next/static/chunks/7956-33748cabb3a05562.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{ccae1c4b-0cf414f5eff1b10d.js → 7c5ed21f-f286708e57cf88f7.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/8030-aa66b478b53dbfca.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8051.c88c07dacbbc5f21.js +8 -0
  98. package/apps/pwa/out/_next/static/chunks/{3840-5825d56d46976a92.js → 8080-40d781e7704d3671.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/8149.80e402d4345e8dae.js +77 -0
  100. package/apps/pwa/out/_next/static/chunks/8205.50a5268f4e12ba0b.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8231.a128feaa6f8b6079.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/85.4ddb1dda2ea3ffa2.js +286 -0
  103. package/apps/pwa/out/_next/static/chunks/8537.26517a09e8247beb.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8595-e9b7081ab773a61f.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8821-30cc65a61a60951f.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8905.b3385aadb7b133e6.js +79 -0
  107. package/apps/pwa/out/_next/static/chunks/8983.246bb3a1ac38f50f.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/{873d6c12.09bd499f57171543.js → 8c58d09b.e8724a299658d86f.js} +1 -1
  109. package/apps/pwa/out/_next/static/chunks/9072.18342f5941a1f3ec.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/9123.9df04866b2d6e00f.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/{575.d929793a53f27c4b.js → 9151.a2c51e93f9156dae.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/9175-7d383df15a82e2be.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9181-bf89c07ce5b8f599.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/920-429bbc4504b45f71.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9207.625edf45d656151c.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9378.d2575c6ffd6dd756.js +94 -0
  117. package/apps/pwa/out/_next/static/chunks/957.db5b5c4d32a35240.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{190.285c832bd9626f8c.js → 958.53a8dcf4729e6997.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/9647.8f0cd0898c592a29.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9665-26abb02665704c2c.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9703.e7d81b6faef1050a.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9882-7a9164b3c2dacbe5.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/9998.b74e033efadecd10.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c604fb980a634d88.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ec2d8a4979ca9075.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-cb6add08ad3c7660.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/board/page-e2eaa321ec223fe6.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/botlab/page-5b8a09c475b5f844.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/bots/page-91a77daedfbac191.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/ceo/page-f37fc5e974bda39b.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/chat/page-91429a0b78415a94.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/consult/page-b95798b58263b910.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/control/page-763d53e175e17aa1.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/decisions/page-d55023204055b12f.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/design-check/page-89d2140d78abc810.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/editor/page-82dc069abfe27f55.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/exec/page-25d9eee7beb552c0.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/field/page-770b4594c713ee97.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c604fb980a634d88.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/inside/page-ba8e0dcae4f83985.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/intake/page-5c112c6d7c33656e.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/layout-09788e1aa9a87db6.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live/{page-e2de2e59111c9aad.js → page-3337c6a1328c2674.js} +1 -1
  144. package/apps/pwa/out/_next/static/chunks/app/live-run/{page-f2b2e4bf6e981450.js → page-89acd5d68c0bc560.js} +1 -1
  145. package/apps/pwa/out/_next/static/chunks/app/loops/page-5c13e2c76371d797.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/market/page-653a9f18642825c6.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/{page-2af16e62c12f22df.js → page-fe986fe79b107546.js} +1 -1
  148. package/apps/pwa/out/_next/static/chunks/app/morning/page-1e5da297557d2354.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/not-found-91ea9f5869a40943.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/observatory/page-7824e21b999962e2.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-53d00a60cc75a922.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-88a1edbff62eaf1d.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e931248b3f9574b.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/outputs/page-443364c9e4a23b31.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/page-b9af2ac1c4737ce8.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/reflection/page-25ab9c614c14129b.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-dbcdcfac0a395a8a.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/sessions/page-bf1de6645089ec58.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c4201761a5e839c9.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/settings/page-c304f469ea5d70e4.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8e5a238cf5e50c9c.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c604fb980a634d88.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/page-32b526069ee50b3c.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/share/page-fb9e639c107f5f72.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/showroom/page-84220c776608cedc.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/tasks/page-e475618cbfd5ca2b.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/term/page-ac2c1e6169cfce57.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/today/page-fccd3020af2f8806.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/trace/page-9c0d7198ff7b5a91.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/vault/page-d54b1ec9b9c6430d.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8c4bef1791d732ca.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/page-46fcc0b0bbc6fbfe.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workspace/page-c1c80e345fa9d6f5.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7dfda00afd172f5b.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/{053a429e.9a63436527cc751c.js → d9815f84.4918f682a45a8502.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{ceba0382.650712b56b85b582.js → de8446d3.31b73eb239fecd7b.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/f21fd540.63ac75328926ed30.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/framework-77fdcc873519a6cd.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-app-d0d620d2ce235713.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-e0ef79c79337ba90.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-84b1bc71e3f9ce6a.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-2acb61f1363128cb.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-462ff5727ceb7824.js +1 -0
  184. package/apps/pwa/out/_next/static/css/{b5d88eba78a3d7bf.css → be9019f696217521.css} +1 -1
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +23 -23
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +23 -23
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +23 -23
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +22 -22
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +22 -22
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +23 -23
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +22 -22
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +23 -23
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +23 -23
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +22 -22
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +23 -23
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +23 -23
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +23 -23
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +23 -23
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +22 -22
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +22 -22
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +23 -23
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +23 -23
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +23 -23
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +22 -22
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +22 -22
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +23 -23
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +23 -23
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +22 -22
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +22 -22
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +22 -22
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +23 -23
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +23 -23
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +22 -22
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +23 -23
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +23 -23
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +23 -23
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +23 -23
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +23 -23
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +22 -22
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +23 -23
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +23 -23
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +23 -23
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +23 -23
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +23 -23
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +23 -23
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +23 -23
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +23 -23
  278. package/graphs/drafts/recipes.yaml +27 -7
  279. package/graphs/work/draft-close.yaml +54 -0
  280. package/graphs/work/green-close.yaml +37 -0
  281. package/graphs/work/recipes.yaml +46 -1
  282. package/graphs/work/run-research.yaml +35 -0
  283. package/package.json +1 -1
  284. package/scripts/__fixtures__/authoring-paths-10x3.json +32 -0
  285. package/scripts/boundary-proof-mapping-audit.ts +88 -0
  286. package/scripts/codex-fallback-live-probe.ts +17 -15
  287. package/scripts/fleet/node-setup.sh +32 -2
  288. package/scripts/fleet/run-light-worker.sh +9 -0
  289. package/scripts/gate-0226-failure-census.ts +507 -0
  290. package/scripts/goals/authoring-metrics.ts +258 -0
  291. package/scripts/graph-units/draft-close-node.ts +222 -0
  292. package/scripts/hook-order-sweep.ts +7 -4
  293. package/scripts/land-global-checks.ts +69 -1
  294. package/scripts/measure-nl-routing-corpus.ts +207 -2
  295. package/scripts/release-loop/docs-node.ts +140 -0
  296. package/scripts/release-loop/gate-closure.ts +48 -0
  297. package/scripts/release-loop/gate-diff.ts +2 -1
  298. package/scripts/release-loop/known-issues-node.ts +6 -4
  299. package/scripts/release-loop/notes-repair.ts +216 -0
  300. package/scripts/release-loop/prepare-node.ts +61 -5
  301. package/scripts/release-loop/resume-release.ts +114 -4
  302. package/scripts/release-loop/resume-test-traffic.ts +10 -0
  303. package/scripts/release-loop/version-node.ts +81 -12
  304. package/scripts/train/green-leg.ts +176 -0
  305. package/scripts/tui-continue-real-evidence.ts +47 -0
  306. package/scripts/ux-sim.ts +1 -1
  307. package/src/acp/client.ts +31 -5
  308. package/src/acp/core-turn-bridge.ts +6 -0
  309. package/src/acp/stderr-summary.ts +49 -0
  310. package/src/agent/monad-agent-turn.ts +1 -0
  311. package/src/agent/terminal-surface.ts +217 -0
  312. package/src/agent-substrate/pr-reviewer.ts +11 -3
  313. package/src/agent-substrate/self-review-cli.ts +343 -31
  314. package/src/autopilot/lineage/sources.ts +1 -1
  315. package/src/autopilot/pr-manager.ts +64 -13
  316. package/src/boot/daemon-runtime.ts +35 -3
  317. package/src/boot/daemon-tools/pty-shell.ts +2 -1
  318. package/src/budget/run-usage-rollup.ts +12 -7
  319. package/src/budget/unified-usage.ts +20 -0
  320. package/src/capture/tui-self-report.ts +32 -3
  321. package/src/cli/autopilot-cli.ts +24 -9
  322. package/src/cli/decisions-cli.ts +7 -4
  323. package/src/cli/doctor-cli.ts +116 -7
  324. package/src/cli/logs-cli.ts +357 -2
  325. package/src/cli/memory-cli.ts +30 -1
  326. package/src/cli/msg-cli.ts +15 -11
  327. package/src/cli/pr-granularity.ts +5 -3
  328. package/src/cli/release-checklist-read-cli.ts +109 -4
  329. package/src/cli/release-cli.ts +43 -10
  330. package/src/cli/self-update.ts +23 -5
  331. package/src/cli/self-utterances-cli.ts +13 -16
  332. package/src/cli/tasks-cli.ts +309 -11
  333. package/src/cli/usage-cli.ts +12 -10
  334. package/src/context-bus/claude-memory-import.ts +99 -0
  335. package/src/context-bus/long-term-memory.ts +125 -0
  336. package/src/core-turn/run-goal-loop.ts +5 -2
  337. package/src/core-turn/types.ts +2 -0
  338. package/src/dashboard/chat/acp-chat.ts +9 -0
  339. package/src/dashboard/index.ts +97 -13
  340. package/src/dashboard/input/agent-wake.ts +43 -0
  341. package/src/dashboard/input/chat-main-acp-dispatch.ts +21 -1
  342. package/src/dashboard/replay-preview.ts +25 -0
  343. package/src/dashboard/slash-runtime/dashboard-handlers.ts +17 -8
  344. package/src/dashboard/synchronized-frame-output.ts +74 -0
  345. package/src/display/coordinator.ts +45 -12
  346. package/src/display/resize-listener.ts +41 -20
  347. package/src/display/synchronized-output-region.ts +60 -0
  348. package/src/domains/surface-events.ts +80 -1
  349. package/src/exec-requests/planner.ts +37 -2
  350. package/src/execution-loop/launch-gate.ts +4 -3
  351. package/src/git-fs/cli-stderr.ts +45 -0
  352. package/src/git-fs/gh-cli.ts +6 -3
  353. package/src/git-fs/git-cli.ts +11 -5
  354. package/src/graph-runner/graph-cli.ts +26 -2
  355. package/src/graph-runner/graph-run-api.ts +3 -2
  356. package/src/graph-runner/runner.ts +17 -5
  357. package/src/graph-wizard/generate.ts +29 -6
  358. package/src/harness/harness-cli-command.ts +179 -33
  359. package/src/harness/review-adapter.ts +26 -6
  360. package/src/index.ts +116 -13
  361. package/src/instance/test-write-guard-real-transport.fixture.ts +52 -0
  362. package/src/llm/route-decision.ts +13 -0
  363. package/src/llm-tool-name.ts +37 -0
  364. package/src/llm-tool-schema.ts +35 -0
  365. package/src/llm.ts +123 -11
  366. package/src/loops/checker.ts +100 -0
  367. package/src/loops/consensus.ts +26 -2
  368. package/src/loops/loop-cli.ts +9 -4
  369. package/src/loops/orchestrator/anomaly-cluster.ts +243 -0
  370. package/src/loops/orchestrator/tick.ts +49 -4
  371. package/src/model-tier/llm-tier-map.ts +12 -17
  372. package/src/msg/msg-store.ts +17 -0
  373. package/src/native-tool-catalog.ts +1 -1
  374. package/src/nexus/api/graph-wizard-api.ts +27 -2
  375. package/src/nexus/api/grid.ts +24 -4
  376. package/src/nexus/api/http-server.ts +1 -1
  377. package/src/nexus/api/ops-api.ts +14 -6
  378. package/src/nexus/state/state.ts +7 -1
  379. package/src/oauth/codex-account-store.ts +34 -1
  380. package/src/ops/loops-map.ts +46 -0
  381. package/src/ops/overview-cache.ts +22 -4
  382. package/src/ops/overview.ts +41 -5
  383. package/src/policy/llm-policy.ts +3 -1
  384. package/src/prompt-enhance/enhance.ts +4 -4
  385. package/src/pty-shell/availability.ts +7 -0
  386. package/src/pty-shell/herdr-agent-report.ts +40 -31
  387. package/src/pty-shell/herdr-prune-stale.ts +17 -0
  388. package/src/pty-shell/herdr-sequence-lease.ts +60 -0
  389. package/src/pty-shell/pty-control-ipc.ts +187 -18
  390. package/src/pty-shell/registry.ts +25 -15
  391. package/src/pty-shell/tui-run-state.ts +235 -1
  392. package/src/release-loop/checklist.ts +50 -5
  393. package/src/release-loop/feature-store.ts +9 -9
  394. package/src/release-loop/landed-but-yellow.ts +93 -12
  395. package/src/repl/index.ts +8 -0
  396. package/src/seat-loop/seat-report.ts +1 -0
  397. package/src/self-dev/ask-launch-flow.ts +86 -10
  398. package/src/self-dev/decompose-proposal.ts +29 -18
  399. package/src/self-dev/dev-pipeline.ts +29 -7
  400. package/src/self-dev/draft-sweep.ts +241 -16
  401. package/src/self-dev/draft-triage-rules.ts +19 -5
  402. package/src/self-dev/review-provider-fallback.ts +45 -7
  403. package/src/self-dev/shard-plan.ts +48 -0
  404. package/src/self-dev/shard-run.ts +50 -3
  405. package/src/self-implement/doctor-visit.ts +83 -0
  406. package/src/self-implement/gate-artifacts.ts +6 -2
  407. package/src/self-implement/gate-baseline.ts +64 -1
  408. package/src/self-implement/gate-cli.ts +93 -9
  409. package/src/self-implement/gate-remote.ts +28 -4
  410. package/src/self-implement/gate-scope.ts +13 -1
  411. package/src/self-implement/goal-author.ts +333 -18
  412. package/src/self-implement/goal-supervisor-fill.ts +75 -26
  413. package/src/self-implement/importer-test-index.ts +215 -2
  414. package/src/self-implement/knowhow-pack.ts +5 -5
  415. package/src/self-implement/orchestrator.ts +318 -25
  416. package/src/self-implement/review-round-brief.ts +300 -0
  417. package/src/self-implement/rework-policy.ts +14 -0
  418. package/src/self-implement/run-ledger.ts +170 -6
  419. package/src/self-implement/run-stop.ts +1 -1
  420. package/src/self-implement/running-runs.ts +17 -3
  421. package/src/self-implement/seams.ts +12 -6
  422. package/src/self-implement/stop-autoheal.ts +1 -0
  423. package/src/self-implement/test-seams.ts +13 -1
  424. package/src/self-implement/train-reach-grouping.ts +8 -2
  425. package/src/session/chat.ts +7 -1
  426. package/src/session/id-prefix.ts +60 -0
  427. package/src/session/index.ts +4 -0
  428. package/src/session-runtime/index.ts +9 -1
  429. package/src/skills/tools/pty.ts +5 -0
  430. package/src/status/metrics.ts +12 -1
  431. package/src/steward/rejudge-tick.ts +12 -5
  432. package/src/steward/resync-tick.ts +31 -4
  433. package/src/task-agent/actions.ts +199 -4
  434. package/src/task-agent/boundary-proof-mapping.ts +12 -0
  435. package/src/task-agent/boundary-proof-producer.ts +147 -0
  436. package/src/task-agent/completion-evidence.ts +2 -1
  437. package/src/task-agent/green-close-recipe.ts +239 -0
  438. package/src/task-agent/green-sweep.ts +64 -10
  439. package/src/task-agent/live-moves.ts +48 -3
  440. package/src/task-agent/map-host-adapter.ts +134 -0
  441. package/src/task-agent/map-reduce.ts +158 -0
  442. package/src/task-agent/map-run-ledger.ts +226 -0
  443. package/src/task-agent/parent-host.ts +21 -11
  444. package/src/task-agent/rejudge-on-head.ts +72 -5
  445. package/src/task-agent/repair-cycle.ts +41 -0
  446. package/src/task-agent/repair-next-move.ts +12 -2
  447. package/src/task-agent/review-prior-fix.ts +12 -2
  448. package/src/task-agent/shadow.ts +188 -5
  449. package/src/task-agent/task-hand.ts +158 -13
  450. package/src/task-agent/task-parent-role-llm.ts +9 -0
  451. package/src/task-agent/tier-split.ts +4 -3
  452. package/src/task-agent/work-order.ts +53 -2
  453. package/src/task-orchestrator/dispatcher.ts +46 -1
  454. package/src/task-orchestrator/generator-prompt.ts +6 -0
  455. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +16 -6
  456. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +8 -6
  457. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +97 -0
  458. package/src/task-orchestrator/surfaces/pod-pool.ts +50 -4
  459. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +15 -9
  460. package/src/task-orchestrator/surfaces/self-implement-pod.ts +217 -36
  461. package/src/task-orchestrator/surfaces/self-implement.ts +4 -0
  462. package/src/testing/linux-env.ts +177 -0
  463. package/src/tui/chat/goal-interim.ts +5 -1
  464. package/src/tui/entry.ts +258 -4
  465. package/src/tui/input/at-picker.ts +55 -0
  466. package/src/tui/slash/resume.ts +35 -12
  467. package/src/tui/slash/signals.ts +114 -0
  468. package/src/tui/slash/term-next.ts +71 -0
  469. package/src/tui-client/local-chat-turn.ts +4 -3
  470. package/src/user-config.ts +19 -1
  471. package/src/ux-sim/boot-daemon-tools-pty-shell-device.ts +136 -0
  472. package/src/ux-sim/classic-tui-seat-scenarios.ts +158 -4
  473. package/src/ux-sim/fake-gh.ts +174 -0
  474. package/src/ux-sim/fake-kubectl.ts +142 -0
  475. package/src/ux-sim/fake-llm.ts +6 -1
  476. package/src/ux-sim/next-tui-seat-scenarios.ts +124 -6
  477. package/src/ux-sim/resume-picker-device.ts +173 -0
  478. package/src/ux-sim/session-id-seed.ts +60 -0
  479. package/src/ux-sim/skills-tools-shell-device.ts +156 -0
  480. package/src/ux-sim/task-agent-parent-host-device.ts +264 -0
  481. package/src/ux-sim/task-agent-rejudge-on-head-device.ts +114 -0
  482. package/src/version/packed-revision.json +1 -1
  483. package/apps/pwa/out/_next/static/chunks/109.f196abf3484bb97f.js +0 -287
  484. package/apps/pwa/out/_next/static/chunks/1201.afbfc5b1c5e5cbe4.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/1517.9275b89572098ff3.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/1574.ad11f8db8396ab45.js +0 -1
  487. package/apps/pwa/out/_next/static/chunks/1614.7a8c5c40aee0261f.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/1871-f1eb29d8dbb4065b.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/2193.0ea24c4a7aa1d004.js +0 -36
  490. package/apps/pwa/out/_next/static/chunks/223-ad865c1e80491d78.js +0 -1
  491. package/apps/pwa/out/_next/static/chunks/2265-f0d90b6dbec05f81.js +0 -1
  492. package/apps/pwa/out/_next/static/chunks/2267.eb4a62a209f09ec4.js +0 -149
  493. package/apps/pwa/out/_next/static/chunks/2341-86cd06c0cf01aa33.js +0 -1
  494. package/apps/pwa/out/_next/static/chunks/2352.9abc42422bade876.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/2397-c1653a816061842d.js +0 -1
  496. package/apps/pwa/out/_next/static/chunks/2500.cbc1257b774aae52.js +0 -1
  497. package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +0 -24
  498. package/apps/pwa/out/_next/static/chunks/2812ca6a.3b9f4a7a08885744.js +0 -1
  499. package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/2941.3c3546f96bc6efa7.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +0 -24
  502. package/apps/pwa/out/_next/static/chunks/3031-85328a92fcce4da6.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/3148-98efd4869d660a87.js +0 -1
  504. package/apps/pwa/out/_next/static/chunks/3155.2587a55196ecb394.js +0 -226
  505. package/apps/pwa/out/_next/static/chunks/3277.785db1cf09f98601.js +0 -1
  506. package/apps/pwa/out/_next/static/chunks/3320-f9c77381f85a2c0a.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/3386-91049feabff9a94e.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/339.80afb7e8839372af.js +0 -8
  509. package/apps/pwa/out/_next/static/chunks/3538.a445e50bb359d068.js +0 -32
  510. package/apps/pwa/out/_next/static/chunks/3540c645.2595a6af01a97672.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/3621.581b2054cc14bee4.js +0 -286
  512. package/apps/pwa/out/_next/static/chunks/3676.8c28d16fd84ca843.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/375-b84540853523fe52.js +0 -1
  514. package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +0 -74
  515. package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/4067-bf9aa60547972937.js +0 -1
  517. package/apps/pwa/out/_next/static/chunks/4116.a84a92a2492c080e.js +0 -1
  518. package/apps/pwa/out/_next/static/chunks/4176.e5729c93c29151eb.js +0 -104
  519. package/apps/pwa/out/_next/static/chunks/4227-e6c84686bc8946ca.js +0 -1
  520. package/apps/pwa/out/_next/static/chunks/4327.b9e08a71c0009348.js +0 -1
  521. package/apps/pwa/out/_next/static/chunks/4946.bd106eafd668f248.js +0 -148
  522. package/apps/pwa/out/_next/static/chunks/5085-bce4904931767ca6.js +0 -1
  523. package/apps/pwa/out/_next/static/chunks/5125.2eb9968b83767193.js +0 -93
  524. package/apps/pwa/out/_next/static/chunks/5128-75b733fd74a9a1eb.js +0 -1
  525. package/apps/pwa/out/_next/static/chunks/5489f3fe.4bb1458b09f6dead.js +0 -122
  526. package/apps/pwa/out/_next/static/chunks/5560-2a4648f6a30f16e7.js +0 -1
  527. package/apps/pwa/out/_next/static/chunks/5772-e29e14f8ff127122.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/5887.5b2f5b44ce0f7e9a.js +0 -1
  529. package/apps/pwa/out/_next/static/chunks/5899-4c112a2d908cf97f.js +0 -1
  530. package/apps/pwa/out/_next/static/chunks/599.c39c571b6733f2a2.js +0 -41
  531. package/apps/pwa/out/_next/static/chunks/6041.1b65efb796ebc2a5.js +0 -79
  532. package/apps/pwa/out/_next/static/chunks/6057-765c0a26028c86b2.js +0 -1
  533. package/apps/pwa/out/_next/static/chunks/6142.f289e0d039f453a6.js +0 -1
  534. package/apps/pwa/out/_next/static/chunks/6199-6bcd61d2a3910e04.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/6236.cdf7293e710a9b2d.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/6387-237e079dac9a3ae6.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/6448-b6d272d074276e14.js +0 -1
  538. package/apps/pwa/out/_next/static/chunks/6566.926a1d1b7c911442.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/6580-cdc0e4a634ce4708.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/6659-b242dc31b20b3f29.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/6690.c5d9b321b1f79384.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/671-e9b6ad0c771c5514.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/6862.bcbf89dd0f4496b3.js +0 -27
  544. package/apps/pwa/out/_next/static/chunks/6912-7b375ee48732c767.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/6925.562d532110879886.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/727.7deb87749b0a343a.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/7545.b1aa42cd15503319.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/7551-416d298c2dc4a9ab.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/7784.1f0ac4a16d190cf4.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/7870-309de463786ac1fc.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/7888-e29b151bb6a3bb8b.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/7891.03f910124a737985.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/7905-6ba78d9234608f79.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/8037.e254fd797aa224d1.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/8207.f527886b7c464529.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/856.50bda61439d465e6.js +0 -62
  557. package/apps/pwa/out/_next/static/chunks/9031-92e9b487edb681ee.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/9060.5410d9f6a95f6287.js +0 -90
  559. package/apps/pwa/out/_next/static/chunks/914.8abefd48d579547b.js +0 -94
  560. package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/9289.3e92f278821e18e0.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/9319.7816d3cc741cd34f.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/9327-e016bb9f1674d24f.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/9365.3de48bf75193ff9a.js +0 -77
  565. package/apps/pwa/out/_next/static/chunks/9383.5b5e9aa56b5fea97.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/9387-cb929573ef436f39.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/9489.c27becacc3283dec.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/9514.131c52cc75fe6439.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/9536.28962663c7734376.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/9686-12286f5bbf15a5a0.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/9776.289d40cc5a4c342a.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/9789.60f723d18097ec30.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/989.f0c17523c5e61f65.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/9972-1df393aa8d4f7d52.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-96750aba7430959f.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4105e5bbbb043024.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5d4fa75c2acb113e.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/app/board/page-a79a9bdb3b2142bf.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/app/botlab/page-f1c2047484992a35.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/app/bots/page-15ffc49b2d8c70e2.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/app/ceo/page-67d53a3fc8734135.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/app/chat/page-e30c8dc696491336.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/app/consult/page-2136e04fa77696e2.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/app/control/page-fecd2814790c2e12.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/app/decisions/page-280aa4a98fc5bb44.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/app/design-check/page-c14e96b65fb4b883.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/app/editor/page-187dac74825ed6bf.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/app/exec/page-6bc7246ea8c92448.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/app/field/page-083747f1d4518f61.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/app/healthz/route-96750aba7430959f.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/app/inside/page-15ca95a16ec96e1f.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/app/intake/page-a8ac031b3810eb64.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/app/layout-8835f93110494cda.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/app/loops/page-5b92b7f75df20948.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/app/market/page-468eddf2b1a84ecb.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/app/morning/page-18b40867a77a5793.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/app/not-found-fe934f2979f5a4a2.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/app/observatory/page-3eec435537357170.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ff88cbfd2aa99fc8.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-a5b39fb780c70ab5.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ae465dde1d1b3933.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/app/outputs/page-e7abc34a48a6f71e.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/app/page-cab9674fde9ead26.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1da49bc8712284d0.js +0 -1
  605. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5e8aa657551ac912.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/app/sessions/page-fcc36f36c6dc1fe2.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d22db22f2a7296ca.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/app/settings/page-d12dc7b1773878f0.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-99debec9ea7fbec0.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/app/setup/layout-96750aba7430959f.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/app/setup/page-2a088a78bad7e924.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/app/share/page-2e8ed57db7e69993.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/app/showroom/page-4b3a16213c2ae8fe.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f098747ddf38c98b.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/app/term/page-c15958835534404b.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/app/today/page-68279e3c843c1fd7.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/app/trace/page-a34a74453367a39d.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/app/vault/page-8767a7db2155a5bd.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-bd5976683460d7f2.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b7364835e7f2ef54.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/app/workspace/page-311af16b3ee0ffca.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-fb670757274ae990.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/f9a61e4d.1fc2c1dbdd49fe46.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/framework-6d497cbf1eef04c6.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/main-app-012f5edec932f337.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/main-da5aeb809edc94a2.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/pages/_app-5ee319af6f749dfe.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/pages/_error-4bc84653a718d6c6.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/webpack-8a96cf6775c73d6e.js +0 -1
  630. /package/apps/pwa/out/_next/static/{uC-N0emedeNOFuaBQFv-I → 8kITumG9GAZ1LwT9POrAR}/_ssgManifest.js +0 -0
@@ -28,6 +28,28 @@ function findGraphFile(graphId: string): string | undefined {
28
28
 
29
29
  export function registerGraphCommands(program: Command, runsDeps: { root?: string; processStartMs?: (pid: number) => number | null } = {}): void {
30
30
  const graph = program.command('graph').description('Run a declared command graph or inspect its latest run');
31
+ graph.command('adapt-report')
32
+ .description('Measure recorded graph path diversity, unit calls, adaptations and landings for one goal')
33
+ .requiredOption('--goal <id>', 'Goal ID to measure')
34
+ .option('--json', 'Print measurement as JSON')
35
+ .action(async (opts: { goal: string; json?: boolean }) => {
36
+ try {
37
+ const { queryGraphAdaptReport } = await import('../self-implement/run-ledger.js');
38
+ const report = queryGraphAdaptReport(opts.goal);
39
+ if (opts.json) await writeStdoutJson(JSON.stringify(report) + '\n');
40
+ else if (report.runCount === 0) console.log(`graph adapt-report: ${opts.goal} · 표본 0 · 제외 ${report.excludedCount} ${JSON.stringify(report.exclusionReasons)}`);
41
+ else {
42
+ const landing = (group: typeof report.adapted) => group.denominator
43
+ ? `${group.landed}/${group.denominator} (${(group.rate! * 100).toFixed(1)}%)` : '표본 0';
44
+ console.log(`graph adapt-report: ${opts.goal} · 경로 ${report.uniquePathSignatures} · 유닛 호출 ${report.unitCallCount} · 적응 ${report.adaptationCount}`);
45
+ console.log(`적응 착지율 ${landing(report.adapted)} · 비적응 착지율 ${landing(report.nonAdapted)}`);
46
+ console.log(`제외 ${report.excludedCount} ${JSON.stringify(report.exclusionReasons)}`);
47
+ }
48
+ } catch (error) {
49
+ console.error(`graph adapt-report: ${error instanceof Error ? error.message : String(error)}`);
50
+ process.exitCode = 1;
51
+ }
52
+ });
31
53
  graph.command('wizard-run <request>')
32
54
  .description('Run one request through the smart wizard graph and stop at its approval gate')
33
55
  .option('--json', 'Print run identity and transitions as JSON')
@@ -405,12 +427,14 @@ export function registerGraphCommands(program: Command, runsDeps: { root?: strin
405
427
  const state = matches[0]!;
406
428
  const detail = { ...row(state), nodes: state.nodes.map((node) => {
407
429
  const summary = lastJsonObject(node.output)?.summary;
408
- return { nodeId: node.nodeId, ok: node.ok, summary: typeof summary === 'string' ? summary.slice(0, 300) : null };
430
+ return { nodeId: node.nodeId, ok: node.ok, exit: node.exit,
431
+ ...(node.reason === undefined ? {} : { reason: node.reason }),
432
+ summary: typeof summary === 'string' ? summary.slice(0, 300) : null };
409
433
  }), pending: state.pending ?? null, resume: state.resume ?? null };
410
434
  if (opts.json) await writeStdoutJson(JSON.stringify(detail) + '\n');
411
435
  else {
412
436
  console.log(`${detail.runId} · ${detail.graphId} · ${detail.status} · alive=${detail.alive}`);
413
- for (const node of detail.nodes) console.log(` ${node.nodeId} · ok=${node.ok} · ${node.summary ?? '-'}`);
437
+ for (const node of detail.nodes) console.log(` ${node.nodeId} · ok=${node.ok} · exit=${node.exit ?? '-'} · ${node.reason ?? node.summary ?? '-'}`);
414
438
  console.log(`pending: ${JSON.stringify(detail.pending)}`);
415
439
  console.log(`resume: ${JSON.stringify(detail.resume)}`);
416
440
  }
@@ -117,7 +117,7 @@ export function runnableIssues(doc: Record<string, unknown>, allowedRecipes: Rea
117
117
  return issues;
118
118
  }
119
119
 
120
- export interface GraphRunNodeView { nodeId: string; ok: boolean; executed: boolean; startedAt?: string; endedAt?: string; error?: string }
120
+ export interface GraphRunNodeView { nodeId: string; ok: boolean; exit: number | null; executed: boolean; startedAt?: string; endedAt?: string; error?: string; reason?: string }
121
121
  export interface GraphRunView {
122
122
  graphId: string; runId: string; status: GraphRunState['status'] | 'starting';
123
123
  startedAt?: string; finishedAt?: string; path: string[];
@@ -130,9 +130,10 @@ export function graphRunView(state: GraphRunState): GraphRunView {
130
130
  ...(state.startedAt ? { startedAt: state.startedAt } : {}), ...(state.finishedAt ? { finishedAt: state.finishedAt } : {}),
131
131
  path: state.path,
132
132
  nodes: state.nodes.map((node) => ({
133
- nodeId: node.nodeId, ok: node.ok, executed: node.executed,
133
+ nodeId: node.nodeId, ok: node.ok, exit: node.exit, executed: node.executed,
134
134
  ...(node.startedAt ? { startedAt: node.startedAt } : {}), ...(node.endedAt ? { endedAt: node.endedAt } : {}),
135
135
  ...(node.error ? { error: node.error.slice(0, 300) } : {}),
136
+ ...(node.reason === undefined ? {} : { reason: node.reason }),
136
137
  })),
137
138
  ...(state.currentNode ? { currentNode: state.currentNode } : {}),
138
139
  };
@@ -144,7 +144,7 @@ export interface GraphRunState {
144
144
  reason?: string;
145
145
  path: string[];
146
146
  /** startedAt/endedAt (ISO) and seconds are written when the node runs; ledgers before GRAPH-NODE-TIMES (0.2.19) have none. */
147
- nodes: Array<{ nodeId: string; ok: boolean; exit: number | null; executed: boolean; output?: unknown; error?: string; decidedBy?: string; decidedAt?: string;
147
+ nodes: Array<{ nodeId: string; ok: boolean; exit: number | null; executed: boolean; output?: unknown; error?: string; reason?: string; decidedBy?: string; decidedAt?: string;
148
148
  startedAt?: string; endedAt?: string; seconds?: number;
149
149
  waiver?: { reason: string; at: string; /** RELEASE-WAIVE-UNMEASURED — why the waived gate had no verdict. */ unmeasured?: string; original: { exit: number | null; output?: unknown; error?: string } } }>;
150
150
  /** The node now running and when it started; cleared when its record is written. */
@@ -172,6 +172,11 @@ export interface GraphRunState {
172
172
  statePath: string;
173
173
  }
174
174
 
175
+ function failedCommandStderrTail(exitCode: number, stderr: string): string | undefined {
176
+ if (exitCode === 0 || !stderr.trim()) return undefined;
177
+ return stderr.replace(/(?:\r?\n)+$/, '').split(/\r?\n/).slice(-40).join('\n') || undefined;
178
+ }
179
+
175
180
  export interface GraphClassifyInput {
176
181
  arguments: string;
177
182
  classify: ClassifyNode['classify'];
@@ -1071,6 +1076,7 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
1071
1076
  let ok = approval && !state.dryRun ? state.pending?.decision === 'approved' : true;
1072
1077
  let exit: number | null = null;
1073
1078
  let error: string | undefined;
1079
+ let commandFailureReason: string | undefined;
1074
1080
  let output: unknown;
1075
1081
  const waiving = options.releaseWaiver?.nodeId === current && waivedRecord !== undefined;
1076
1082
  if (command && !waiving && (!approval || state.dryRun || ok) && (!state.dryRun || command.dry_run_command) && !resumingCompleted) {
@@ -1105,7 +1111,9 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
1105
1111
  try {
1106
1112
  const result = await execute(body, commandRoot ? { ...opts, cwd: commandRoot } : opts);
1107
1113
  code = result.exitCode;
1108
- return { ...result, stdout: redactCredentials(result.stdout), stderr: redactCredentials(result.stderr) };
1114
+ const stderr = redactCredentials(result.stderr);
1115
+ commandFailureReason = failedCommandStderrTail(result.exitCode, stderr);
1116
+ return { ...result, stdout: redactCredentials(result.stdout), stderr };
1109
1117
  } finally {
1110
1118
  if (state.activeNode?.nodeId === current) {
1111
1119
  delete state.activeNode;
@@ -1296,13 +1304,14 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
1296
1304
  exit = completed.exit;
1297
1305
  output = completed.output;
1298
1306
  error = completed.error;
1307
+ commandFailureReason = completed.reason;
1299
1308
  } else {
1300
1309
  // 승인 노드도 결과를 «값»으로 남긴다 — 뒤 노드가 문맥(outputs)에서 승인 여부를 확인할 수 있게(발행 노드가 승인 없이 돌지 않도록).
1301
1310
  if (approval && !state.dryRun && !command) {
1302
1311
  output = JSON.stringify({ outcome: ok ? 'approved' : 'rejected', graphId, runId, nodeId: current,
1303
1312
  ...(state.pending?.decidedBy === undefined ? {} : { decidedBy: state.pending.decidedBy }), decidedAt: state.pending?.decidedAt ?? null });
1304
1313
  }
1305
- state.nodes.push({ nodeId: current, ok, exit, executed: !waiving && ((!!command && (!state.dryRun || !!command.dry_run_command)) || (!!prompt && !state.dryRun) || (node.kind === 'classify' && !state.dryRun) || unitExecuted), ...((waiving || harnessLoopRoute || units.has(current) || ((command || prompt || approval || node.kind === 'classify') && (!state.dryRun || !!command?.dry_run_command))) && output !== undefined ? { output } : {}), ...(error ? { error } : {}),
1314
+ state.nodes.push({ nodeId: current, ok, exit, executed: !waiving && ((!!command && (!state.dryRun || !!command.dry_run_command)) || (!!prompt && !state.dryRun) || (node.kind === 'classify' && !state.dryRun) || unitExecuted), ...((waiving || harnessLoopRoute || units.has(current) || ((command || prompt || approval || node.kind === 'classify') && (!state.dryRun || !!command?.dry_run_command))) && output !== undefined ? { output } : {}), ...(error ? { error } : {}), ...(commandFailureReason ? { reason: commandFailureReason } : {}),
1306
1315
  ...(waiving ? { waiver: { reason: options.releaseWaiver!.reason, at: nodeEndedAt, ...(options.releaseWaiver!.unmeasured === undefined ? {} : { unmeasured: options.releaseWaiver!.unmeasured }), original: { exit: waivedRecord!.exit, ...(waivedRecord!.output === undefined ? {} : { output: waivedRecord!.output }), ...(waivedRecord!.error === undefined ? {} : { error: waivedRecord!.error }) } } } : {}),
1307
1316
  ...(approval && state.pending ? { ...(state.pending.decidedBy === undefined ? {} : { decidedBy: state.pending.decidedBy }), decidedAt: state.pending.decidedAt } : {}),
1308
1317
  startedAt: nodeStartedAt, endedAt: nodeEndedAt, seconds });
@@ -1318,10 +1327,13 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
1318
1327
  const reported: unknown = waiving || harnessLoopRoute || units.has(current) || (prompt && !state.dryRun) || (command && (!state.dryRun || command.dry_run_command)) ? lastJsonObject(resumingCompleted ? completed?.output : output)?.outcome : undefined;
1319
1328
  const namedOutcome: string | undefined = typeof reported === 'string' ? reported : undefined;
1320
1329
  if (!options.quiet) console.error(`[graph] ${current} ${ok ? 'ok' : 'fail'} (${seconds.toFixed(2)}s)`);
1321
- debug.log('graph.run', 'node', { graphId, runId, nodeId: current, phase: ok ? 'ok' : 'fail', seconds, exit });
1330
+ debug.log('graph.run', 'node', { graphId, runId, nodeId: current, phase: ok ? 'ok' : 'fail', seconds, exit,
1331
+ ...(commandFailureReason ? { reason: commandFailureReason } : {}) });
1322
1332
  publishInsideEvent({ kind: 'node', graphId, runId, nodeId: current, phase: ok ? 'ok' : 'fail', seconds });
1323
1333
  publishInsideEvent({ kind: 'verdict', graphId, runId, nodeId: current, verdict: ok ? 'ok' : 'fail', ...(namedOutcome === undefined ? {} : { outcome: namedOutcome }) });
1324
- log('node-end', { graphId, runId, nodeId: current, ok, exit, ...(namedOutcome === undefined ? {} : { outcome: namedOutcome }), dryRun: state.dryRun });
1334
+ log('node-end', { graphId, runId, nodeId: current, ok, exit,
1335
+ ...(commandFailureReason ? { reason: commandFailureReason } : {}),
1336
+ ...(namedOutcome === undefined ? {} : { outcome: namedOutcome }), dryRun: state.dryRun });
1325
1337
  if (!resumingCompleted) {
1326
1338
  // Recipe commands expose stdout/exit but no provider usage; never infer zero from success.
1327
1339
  observeModelInputTokens({ scope: 'harness-node', nodeKind: node.kind, runId, nodeId: current });
@@ -93,14 +93,36 @@ export function listKnownGraphUnits(dir = defaultGraphsDir()): KnownGraphUnit[]
93
93
  }).sort((a, b) => a.call.localeCompare(b.call));
94
94
  }
95
95
 
96
+ /** 호출 경계로 올리는 조작 growth 요약 — 어느 from 노드에서 무엇을 끼우려 했나. */
97
+ export interface GraphVariantGrowthTrace {
98
+ readonly from: string;
99
+ readonly outcome: string;
100
+ readonly nodeId: string;
101
+ readonly returnTo?: string;
102
+ }
103
+
104
+ /**
105
+ * 설계자 한 턴의 결말 — mode·reason 은 호출 경계가 관측으로 기록하는 필드다(composed 는 'composed',
106
+ * fallback-standard 는 그 사유 문자열 그대로). growth 는 설계자가 조작한 from 노드를 그대로 올린다.
107
+ */
96
108
  export type GraphVariantDesignResult =
97
- | { readonly status: 'composed'; readonly plan: GraphVariantPlan; readonly variant: Extract<GraphVariantResult, { ok: true }> }
98
- | { readonly status: 'fallback-standard'; readonly template: GraphTemplateSpec; readonly reason: string };
109
+ | { readonly mode: 'variant'; readonly status: 'composed'; readonly reason: 'composed'; readonly plan: GraphVariantPlan; readonly variant: Extract<GraphVariantResult, { ok: true }>; readonly growth?: GraphVariantGrowthTrace }
110
+ | { readonly mode: 'variant'; readonly status: 'fallback-standard'; readonly template: GraphTemplateSpec; readonly reason: string; readonly growth?: GraphVariantGrowthTrace };
99
111
 
100
112
  function isRecord(value: unknown): value is Record<string, unknown> {
101
113
  return value !== null && typeof value === 'object' && !Array.isArray(value);
102
114
  }
103
115
 
116
+ /** 설계자 출력에서 조작 growth 의 좌표만 읽는다 — 모양이 틀려도 «어느 from 이었나»는 남긴다. */
117
+ function growthTraceOf(record: Record<string, unknown> | null): GraphVariantGrowthTrace | undefined {
118
+ const growth = record?.growth;
119
+ if (!isRecord(growth) || typeof growth.from !== 'string' || typeof growth.outcome !== 'string') return undefined;
120
+ const node = isRecord(growth.node) ? growth.node : undefined;
121
+ if (typeof node?.nodeId !== 'string') return undefined;
122
+ return { from: growth.from, outcome: growth.outcome, nodeId: node.nodeId,
123
+ ...(typeof growth.returnTo === 'string' ? { returnTo: growth.returnTo } : {}) };
124
+ }
125
+
104
126
  /** One L2 designer proposal. The model returns only a plan; the existing variant authority decides whether it may run. */
105
127
  export async function designGraphVariantPlan(input: {
106
128
  readonly goal: string;
@@ -127,9 +149,10 @@ export async function designGraphVariantPlan(input: {
127
149
  catch (error) {
128
150
  const reason = `designer-output: ${error instanceof Error ? error.message : String(error)}`;
129
151
  debug.log('graph.compose', 'fallback-standard', { goal: input.goal, reason });
130
- return { status: 'fallback-standard', template: input.template, reason };
152
+ return { mode: 'variant', status: 'fallback-standard', template: input.template, reason };
131
153
  }
132
154
  const record = isRecord(raw) ? raw : null;
155
+ const growthTrace = growthTraceOf(record);
133
156
  const allowed = new Set(['maxVisits', 'routes', 'growth']);
134
157
  const maxVisits = record?.maxVisits;
135
158
  const routes = record?.routes;
@@ -158,17 +181,17 @@ export async function designGraphVariantPlan(input: {
158
181
  if (!valid) {
159
182
  const reason = 'designer-output: invalid GraphVariantPlan or unknown unit';
160
183
  debug.log('graph.compose', 'fallback-standard', { goal: input.goal, reason });
161
- return { status: 'fallback-standard', template: input.template, reason };
184
+ return { mode: 'variant', status: 'fallback-standard', template: input.template, reason, ...(growthTrace ? { growth: growthTrace } : {}) };
162
185
  }
163
186
  const plan = record as GraphVariantPlan;
164
187
  const variant = createGraphVariant({ template: input.template, goal: input.goal, plan });
165
188
  if (!variant.ok) {
166
189
  const reason = `variant-rejected: ${JSON.stringify(variant.rejections)}`;
167
190
  debug.log('graph.compose', 'fallback-standard', { goal: input.goal, reason });
168
- return { status: 'fallback-standard', template: input.template, reason };
191
+ return { mode: 'variant', status: 'fallback-standard', template: input.template, reason, ...(growthTrace ? { growth: growthTrace } : {}) };
169
192
  }
170
193
  debug.log('graph.compose', 'composed', { goal: input.goal, overlayId: variant.overlay.overlayId, patches: variant.patches.length });
171
- return { status: 'composed', plan, variant };
194
+ return { mode: 'variant', status: 'composed', reason: 'composed', plan, variant, ...(growthTrace ? { growth: growthTrace } : {}) };
172
195
  }
173
196
 
174
197
  /** Inventory used by the editor's pack picker and the wizard's validation. */
@@ -6,6 +6,7 @@ import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
6
6
  import { constants as osConstants, hostname } from 'node:os';
7
7
  import { basename, dirname, join, resolve, sep } from 'node:path';
8
8
  import { HarnessCliInputError } from '../cli/cli-user-error.js';
9
+ import { writeStdoutFully } from '../cli/stdout-flush.js';
9
10
  import { findGitDir } from '../git-fs/locate.js';
10
11
  import { LogStore, logsDbPath } from '../mss/logging/log-store.js';
11
12
  import { loadSelfDevRun } from '../self-dev/run-store.js';
@@ -30,7 +31,7 @@ import { buildRunProgressRows, isPartialRunningRuns, queryRunningRuns, renderRun
30
31
  import { launchBindingRunIds, readLaunchBinding } from './launch-registry.js';
31
32
  import { psProcessStartMs } from './harness-stop.js';
32
33
  import { DevPipelineError } from '../self-dev/dev-pipeline.js';
33
- import { collectDraftMetrics, collectOverlapMetrics, DRAFT_SWEEP_CONCURRENCY, mapBounded, resolveDraftSweepCloseCap, runDraftSweep, sweepFailureReason, type DraftSweepAdapters, type DraftSweepResult, type OverlapMetricAdapters, type SweepDraft, type SweepMergedPr, type SweepReviewGate } from '../self-dev/draft-sweep.js';
34
+ import { collectDraftMetrics, collectOverlapMetrics, DRAFT_SWEEP_CONCURRENCY, mapBounded, resolveDraftSweepCloseCap, runDraftSweep, sweepFailureReason, validateDraftSweepApplyPlan, type DraftSweepAdapters, type DraftSweepResult, type OverlapMetricAdapters, type SweepDraft, type SweepMergedPr, type SweepReviewGate } from '../self-dev/draft-sweep.js';
34
35
  import { readAskPreflightRowsSince, readSalvagedRowsSince } from '../self-dev/ask-launch-io.js';
35
36
  import { replayPodTerminals, type DraftResidueReplayOptions, type PrTerminalRecord } from '../self-dev/draft-residue.js';
36
37
  import { draftClaimComment, draftReleaseComment } from '../self-dev/draft-triage-rules.js';
@@ -2533,10 +2534,35 @@ const defaultDraftSweepStopRun: DraftSweepStopRun = async (runId) => {
2533
2534
  return stopHarnessRun(runId, defaultHarnessStopDeps());
2534
2535
  };
2535
2536
 
2536
- export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: DraftSweepGitExecute = runGitCommand, cwd = process.cwd(),
2537
+ export interface GithubDraftSweepAdapterOptions {
2538
+ /** Read-only preview bounds. Reaching a bound is reported as an incomplete inventory. */
2539
+ maxInventoryPages?: number;
2540
+ maxDrafts?: number;
2541
+ maxMerged?: number;
2542
+ onInventoryProgress?: (event: { state: 'open' | 'closed'; page: number; rows: number }) => void;
2543
+ /** Test seam: provide an isolated run-ledger inventory instead of enumerating the host's stores. */
2544
+ runLedgerMatches?: () => readonly RunLedgerMatch[];
2545
+ /** Test seam: provide isolated running-run observations instead of inspecting host processes and PTY stores. */
2546
+ runningRunStatuses?: () => ReadonlyMap<string, string>;
2547
+ /** Test seam for bounded GitHub check-run backoff. */
2548
+ checkRunRetryDelaysMs?: readonly number[];
2549
+ checkRunSleep?: (milliseconds: number) => Promise<void>;
2550
+ }
2551
+
2552
+ function createGithubDraftSweepAdapters(execute: GhExecute, git: DraftSweepGitExecute, cwd: string,
2537
2553
  executeAsync: (args: string[]) => Promise<string> = execute === executeGh ? executeGhAsync : async (args) => execute(args),
2538
- stopRun: DraftSweepStopRun = defaultDraftSweepStopRun): GithubDraftSweepAdapters {
2554
+ stopRun: DraftSweepStopRun = defaultDraftSweepStopRun, options: GithubDraftSweepAdapterOptions = {}): GithubDraftSweepAdapters {
2539
2555
  const ensuredSweepLabels = new Set<string>();
2556
+ const maxInventoryPages = Number.isSafeInteger(options.maxInventoryPages) && options.maxInventoryPages! > 0
2557
+ ? Math.min(options.maxInventoryPages!, 100) : 100;
2558
+ const maxDrafts = Number.isSafeInteger(options.maxDrafts) && options.maxDrafts! > 0 ? options.maxDrafts : undefined;
2559
+ const maxMerged = Number.isSafeInteger(options.maxMerged) && options.maxMerged! > 0 ? options.maxMerged : undefined;
2560
+ let inventoryIncompleteReason: string | undefined;
2561
+ const markInventoryIncomplete = (reason: string) => { inventoryIncompleteReason ??= reason; };
2562
+ const checkRunRetryDelays = options.checkRunRetryDelaysMs ?? [1_000, 2_000, 4_000];
2563
+ const sleepForCheckRunRetry = options.checkRunSleep ?? ((milliseconds: number) => new Promise<void>((resolve) => setTimeout(resolve, milliseconds)));
2564
+ let checkRunsQueue: Promise<void> = Promise.resolve();
2565
+ let checkRunsUnavailableReason: string | undefined;
2540
2566
  const inventory = async (repository: string, state: 'open' | 'closed'): Promise<GithubPull[]> => {
2541
2567
  // ⛔ A large repository has tens of thousands of closed PRs (2026-09-28: 21k → «exceeded pagination limit», no sweep at all).
2542
2568
  // Merged twins only matter after the oldest open draft was opened, so the closed listing stops at that time.
@@ -2548,15 +2574,28 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
2548
2574
  if (!Number.isFinite(cutoff)) throw new Error('Incomplete GitHub PR inventory');
2549
2575
  }
2550
2576
  const all: GithubPull[] = [];
2551
- for (let page = 1; page <= 100; page++) {
2552
- const batch = githubPullsPage(repository, state, page, execute);
2577
+ for (let page = 1; page <= maxInventoryPages; page++) {
2578
+ let batch: GithubPull[];
2579
+ try { batch = githubPullsPage(repository, state, page, execute); }
2580
+ catch (error) {
2581
+ if (maxInventoryPages < 100) {
2582
+ markInventoryIncomplete(`${state} PR inventory stopped after ${page - 1} pages (${all.length} rows): ${sweepFailureReason(error)}`);
2583
+ return all;
2584
+ }
2585
+ throw error;
2586
+ }
2553
2587
  if (!Array.isArray(batch) || batch.length > 100) throw new Error('Incomplete GitHub PR inventory');
2554
2588
  all.push(...batch);
2589
+ options.onInventoryProgress?.({ state, page, rows: all.length });
2555
2590
  if (batch.length < 100) return all;
2556
2591
  // An unknown update time cannot prove the rest is older — keep paging.
2557
2592
  const oldest = Date.parse(batch[batch.length - 1]!.updated_at ?? '');
2558
2593
  if (cutoff !== undefined && Number.isFinite(oldest) && oldest < cutoff) return all;
2559
2594
  }
2595
+ if (maxInventoryPages < 100) {
2596
+ markInventoryIncomplete(`${state} PR inventory capped at ${maxInventoryPages} pages (${all.length} rows observed)`);
2597
+ return all;
2598
+ }
2560
2599
  throw new Error('GitHub PR inventory exceeded pagination limit');
2561
2600
  };
2562
2601
  const open = new Map<string, Promise<GithubPull[]>>();
@@ -2643,17 +2682,57 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
2643
2682
  }
2644
2683
  throw new Error('Review inventory exceeded pagination limit');
2645
2684
  };
2646
- const checkRunsFor = async (repository: string, sha: string): Promise<Array<{ conclusion?: string | null }> | undefined> => {
2685
+ const readCheckRuns = async (repository: string, sha: string): Promise<Array<{ conclusion?: string | null }>> => {
2647
2686
  const runs: Array<{ conclusion?: string | null }> = [];
2648
2687
  for (let page = 1; page <= 100; page++) {
2649
- const result = await ghJsonAsync<{ total_count?: number; check_runs?: Array<{ conclusion?: string | null }> }>(
2650
- ['api', `repos/${repository}/commits/${sha}/check-runs?per_page=100&page=${page}`]);
2651
- if (!Array.isArray(result?.check_runs) || result.check_runs.length > 100) throw new Error('Incomplete check-run inventory');
2688
+ let result: { total_count?: number; check_runs?: Array<{ conclusion?: string | null }> } | undefined;
2689
+ let attempt = 0;
2690
+ while (true) {
2691
+ try {
2692
+ result = await ghJsonAsync<{ total_count?: number; check_runs?: Array<{ conclusion?: string | null }> }>(
2693
+ ['api', `repos/${repository}/commits/${sha}/check-runs?per_page=100&page=${page}`]);
2694
+ break;
2695
+ } catch (error) {
2696
+ const reason = sweepFailureReason(error);
2697
+ const retryable = /(?:\b403\b|\b429\b|rate.?limit|secondary rate)/i.test(reason);
2698
+ if (!retryable || attempt >= checkRunRetryDelays.length) {
2699
+ const incomplete = `check-run inventory incomplete for ${repository}@${sha}: ${reason}`;
2700
+ checkRunsUnavailableReason ??= incomplete;
2701
+ markInventoryIncomplete(incomplete);
2702
+ throw new Error(incomplete);
2703
+ }
2704
+ await sleepForCheckRunRetry(checkRunRetryDelays[attempt++]!);
2705
+ }
2706
+ }
2707
+ if (!Array.isArray(result?.check_runs) || result.check_runs.length > 100 || !Number.isSafeInteger(result.total_count) || result.total_count! < 0) {
2708
+ const incomplete = `check-run inventory incomplete for ${repository}@${sha}: malformed page ${page}`;
2709
+ checkRunsUnavailableReason ??= incomplete;
2710
+ markInventoryIncomplete(incomplete);
2711
+ throw new Error(incomplete);
2712
+ }
2652
2713
  runs.push(...result.check_runs);
2653
- if (Number.isSafeInteger(result.total_count) && runs.length >= result.total_count!) return runs;
2654
- if (result.check_runs.length < 100) return Number.isSafeInteger(result.total_count) && runs.length < result.total_count! ? undefined : runs;
2714
+ if (runs.length >= result.total_count!) return runs;
2715
+ if (result.check_runs.length < 100) {
2716
+ const incomplete = `check-run inventory incomplete for ${repository}@${sha}: expected ${result.total_count}, received ${runs.length} (check-runs may have changed during pagination or the response may be incomplete)`;
2717
+ checkRunsUnavailableReason ??= incomplete;
2718
+ markInventoryIncomplete(incomplete);
2719
+ throw new Error(incomplete);
2720
+ }
2655
2721
  }
2656
- return undefined;
2722
+ const incomplete = `check-run inventory incomplete for ${repository}@${sha}: pagination limit reached`;
2723
+ checkRunsUnavailableReason ??= incomplete;
2724
+ markInventoryIncomplete(incomplete);
2725
+ throw new Error(incomplete);
2726
+ };
2727
+ const checkRunsFor = async (repository: string, sha: string): Promise<Array<{ conclusion?: string | null }>> => {
2728
+ let release!: () => void;
2729
+ const previous = checkRunsQueue;
2730
+ checkRunsQueue = new Promise<void>((resolve) => { release = resolve; });
2731
+ await previous;
2732
+ try {
2733
+ if (checkRunsUnavailableReason) throw new Error(checkRunsUnavailableReason);
2734
+ return await readCheckRuns(repository, sha);
2735
+ } finally { release(); }
2657
2736
  };
2658
2737
  const headCommitTimeFor = async (repository: string, number: number): Promise<string | undefined> => {
2659
2738
  let latest: string | undefined;
@@ -2732,13 +2811,16 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
2732
2811
  const enrichedDrafts = (repository: string): Promise<SweepDraft[]> => {
2733
2812
  if (!draftRows.has(repository)) draftRows.set(repository, (async () => {
2734
2813
  const prs = (await listed(open, repository, 'open')).filter((pr) => pr.draft);
2735
- await prefetchDetails(repository, prs.map((pr) => pr.number));
2736
- const matches = ledgerMatches ??= listRunLedgers().matches;
2737
- return mapBounded(prs, DRAFT_SWEEP_CONCURRENCY, async (pr): Promise<SweepDraft> => {
2814
+ const selected = maxDrafts === undefined ? prs : prs.slice(0, maxDrafts);
2815
+ if (selected.length < prs.length) markInventoryIncomplete(`draft inventory capped at ${maxDrafts} drafts (${prs.length} drafts listed)`);
2816
+ await prefetchDetails(repository, selected.map((pr) => pr.number));
2817
+ const matches = readRunLedgerMatches();
2818
+ return mapBounded(selected, DRAFT_SWEEP_CONCURRENCY, async (pr): Promise<SweepDraft> => {
2738
2819
  return {
2739
2820
  number: pr.number, title: pr.title, branch: pr.head.ref,
2740
2821
  labels: pr.labels.map((item) => item.name), createdAt: pr.created_at, body: pr.body ?? undefined,
2741
2822
  changedFiles: await prFiles(repository, pr.number),
2823
+ ...(pr.head.sha ? { headSha: pr.head.sha } : {}),
2742
2824
  ...(pr.updated_at ? { updatedAt: pr.updated_at } : {}),
2743
2825
  runId: currentDraftSweepRunId(matches, repository, pr.number),
2744
2826
  };
@@ -2749,8 +2831,10 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
2749
2831
  const enrichedMerged = (repository: string): Promise<SweepMergedPr[]> => {
2750
2832
  if (!mergedRows.has(repository)) mergedRows.set(repository, (async () => {
2751
2833
  const prs = (await listed(closed, repository, 'closed')).filter((pr) => pr.merged_at !== null && pr.base?.ref === 'main');
2752
- await prefetchDetails(repository, prs.map((pr) => pr.number));
2753
- return mapBounded(prs, DRAFT_SWEEP_CONCURRENCY, async (pr): Promise<SweepMergedPr> => ({
2834
+ const selected = maxMerged === undefined ? prs : prs.slice(0, maxMerged);
2835
+ if (selected.length < prs.length) markInventoryIncomplete(`merged PR inventory capped at ${maxMerged} records (${prs.length} records listed)`);
2836
+ await prefetchDetails(repository, selected.map((pr) => pr.number));
2837
+ return mapBounded(selected, DRAFT_SWEEP_CONCURRENCY, async (pr): Promise<SweepMergedPr> => ({
2754
2838
  number: pr.number, title: pr.title, branch: pr.head.ref, body: pr.body ?? undefined,
2755
2839
  mergedAt: pr.merged_at ?? undefined, changedFiles: await prFiles(repository, pr.number),
2756
2840
  mergeCommitMessage: await mergeCommitMessageFor(repository, pr),
@@ -2760,19 +2844,35 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
2760
2844
  };
2761
2845
  let ledgerMatches: readonly RunLedgerMatch[] | undefined;
2762
2846
  let running: ReadonlyMap<string, string> | undefined;
2763
- const runStatusFor = (draft: SweepDraft, repository: string): string | undefined => {
2764
- ledgerMatches ??= listRunLedgers().matches;
2765
- running ??= new Map(queryRunningRuns().entries.map((entry) => [entry.runId, entry.status]));
2847
+ const readRunLedgerMatches = (): readonly RunLedgerMatch[] => {
2848
+ ledgerMatches ??= options.runLedgerMatches?.() ?? listRunLedgers().matches;
2849
+ return ledgerMatches;
2850
+ };
2851
+ const readRunningRunStatuses = (): ReadonlyMap<string, string> => {
2852
+ running ??= options.runningRunStatuses?.() ?? new Map(queryRunningRuns().entries.map((entry) => [entry.runId, entry.status]));
2853
+ return running;
2854
+ };
2855
+ const runStatusFor = (draft: Pick<SweepDraft, 'number' | 'branch' | 'runId'>, repository: string): string | undefined => {
2856
+ const matches = readRunLedgerMatches();
2857
+ const statuses = readRunningRunStatuses();
2766
2858
  if (draft.runId) {
2767
- const match = ledgerMatches.find((entry) => entry.runId === draft.runId);
2768
- return match ? draftSweepRunStatus([match], running, repository, draft.number) : undefined;
2859
+ const match = matches.find((entry) => entry.runId === draft.runId);
2860
+ return match ? draftSweepRunStatus([match], statuses, repository, draft.number) : undefined;
2769
2861
  }
2770
- return draftSweepRunStatus(ledgerMatches, running, repository, draft.number);
2862
+ return draftSweepRunStatus(matches, statuses, repository, draft.number);
2771
2863
  };
2772
2864
  return {
2865
+ inventoryStatus: async () => ({ complete: inventoryIncompleteReason === undefined, ...(inventoryIncompleteReason ? { reason: inventoryIncompleteReason } : {}) }),
2773
2866
  openPullRequests: (repository) => listed(open, repository, 'open'),
2774
- runLedgerMatches: () => (ledgerMatches ??= listRunLedgers().matches),
2867
+ runLedgerMatches: readRunLedgerMatches,
2775
2868
  getPrFiles: async (repository, number) => prFiles(repository, number),
2869
+ getDraftSnapshot: async (repository, number) => {
2870
+ const pr = await ghJsonAsync<GithubPull>(['api', `repos/${repository}/pulls/${number}`]);
2871
+ if (!pr || pr.number !== number || !Array.isArray(pr.labels) || !pr.head?.sha || !pr.updated_at
2872
+ || (pr.state !== 'open' && pr.state !== 'closed')) return undefined;
2873
+ return { number: pr.number, state: pr.state, draft: pr.draft, headSha: pr.head.sha,
2874
+ branch: pr.head.ref, updatedAt: pr.updated_at, labels: pr.labels.map((item) => item.name) };
2875
+ },
2776
2876
  getPr: async (repository, number) => {
2777
2877
  const pr = ghJson<GithubPull>(['api', `repos/${repository}/pulls/${number}`], execute);
2778
2878
  if (!pr || pr.number !== number || typeof pr.head?.ref !== 'string' || !Array.isArray(pr.labels)) return undefined;
@@ -2804,8 +2904,8 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
2804
2904
  getRunStatus: async (draft, repository) => runStatusFor(draft, repository),
2805
2905
  getLatestFileChanges: async (draft, repository) => latestFileChangesFor(draft, repository),
2806
2906
  hasFinalRunResult: async (draft, repository) => {
2807
- ledgerMatches ??= listRunLedgers().matches;
2808
- const ownedRuns = new Set(ledgerMatches.filter((match) => {
2907
+ const matches = readRunLedgerMatches();
2908
+ const ownedRuns = new Set(matches.filter((match) => {
2809
2909
  const prEvents = match.entries.filter((entry) => entry.event === 'pr-opened' && entry.data.number === draft.number);
2810
2910
  return prEvents.length > 0 && prEvents.every((entry) => ledgerPrRepository(entry.data, draft.number) === repository);
2811
2911
  }).map((match) => match.runId));
@@ -2863,7 +2963,7 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
2863
2963
  getActiveClaimRunId: async (repository, number) => activeClaimRunIdFromBodies(await claimCommentsFor(repository, number)),
2864
2964
  getLastClaimReleaseAt: async (repository, number) => lastClaimReleaseAtFromBodies(await claimCommentsFor(repository, number)),
2865
2965
  listTaskCards: async () => Object.values(readTaskAgentState<{ tasks?: Record<string, TaskCard> }>(taskAgentStatePath()).tasks ?? {}),
2866
- listPrTerminals: async () => listRunLedgers().matches.flatMap((match) => match.entries.filter((entry) => entry.event === 'pr-terminal')
2966
+ listPrTerminals: async () => readRunLedgerMatches().flatMap((match) => match.entries.filter((entry) => entry.event === 'pr-terminal')
2867
2967
  .map((entry) => entry.data as unknown as PrTerminalRecord)),
2868
2968
  commentDraft: async (repository, number, body) => { execute(['pr', 'comment', String(number), '--repo', repository, '--body', body]); },
2869
2969
  listIssueComments: async (repository, number) => issueCommentsFor(repository, number, 'same-cell'),
@@ -2885,6 +2985,18 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
2885
2985
  };
2886
2986
  }
2887
2987
 
2988
+ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: DraftSweepGitExecute = runGitCommand,
2989
+ cwd = process.cwd(), executeAsync?: (args: string[]) => Promise<string>, stopRun?: DraftSweepStopRun,
2990
+ options: GithubDraftSweepAdapterOptions = {}): GithubDraftSweepAdapters {
2991
+ return createGithubDraftSweepAdapters(execute, git, cwd, executeAsync, stopRun, options);
2992
+ }
2993
+
2994
+ export function githubDraftSweepPreviewAdapters(options: GithubDraftSweepAdapterOptions,
2995
+ execute: GhExecute = executeGh, git: DraftSweepGitExecute = runGitCommand, cwd = process.cwd(),
2996
+ executeAsync?: (args: string[]) => Promise<string>, stopRun?: DraftSweepStopRun): GithubDraftSweepAdapters {
2997
+ return createGithubDraftSweepAdapters(execute, git, cwd, executeAsync, stopRun, options);
2998
+ }
2999
+
2888
3000
  export interface HarnessDraftSweepDeps {
2889
3001
  /** DRAFT-LINEAGE-ONE-1 test seam for the real adapter's run stop; omitted ⇒ `harness stop`. */
2890
3002
  readonly stopRun?: DraftSweepStopRun;
@@ -3033,7 +3145,12 @@ function installHarnessDraftSweepCommand(harnessCmd: Command, deps: HarnessDraft
3033
3145
  .option('--json', '판정 결과를 JSON 으로 출력')
3034
3146
  .option('--repo <owner/name>', '조회할 GitHub 저장소')
3035
3147
  .option('--close-cap <n>', '이번 틱 최대 종료 수 (1~100 · config tools.selfImplement.draftSweepCloseCap 보다 우선 · 기본 10)')
3036
- .action(async (opts: { apply?: boolean; json?: boolean; repo?: string; closeCap?: string }) => {
3148
+ .option('--max-pages <n>', 'inventory 상한 (페이지, dry-run 기본 1 · apply 기본 100 · 1~100)')
3149
+ .option('--max-drafts <n>', 'draft 상한 (dry-run 기본 10 · apply 기본 무제한)')
3150
+ .option('--max-merged <n>', 'merged PR 상한 (dry-run 기본 50 · apply 기본 무제한)')
3151
+ .option('--emit-apply-plan', '완전한 dry-run 분류에서 고정 적용 계획을 JSON에 포함 (모든 PR에 head SHA와 updatedAt 필요)')
3152
+ .option('--apply-plan-file <path>', '고정 적용 계획 JSON 파일 (apply 전용)')
3153
+ .action(async (opts: { apply?: boolean; json?: boolean; repo?: string; closeCap?: string; maxPages?: string; maxDrafts?: string; maxMerged?: string; emitApplyPlan?: boolean; applyPlanFile?: string }) => {
3037
3154
  try {
3038
3155
  const write = deps.write ?? console.log;
3039
3156
  const execute = deps.execute ?? executeGh;
@@ -3044,8 +3161,26 @@ function installHarnessDraftSweepCommand(harnessCmd: Command, deps: HarnessDraft
3044
3161
  if (!DRAFT_SWEEP_REPOSITORY.test(repository) || repository.includes('..')) {
3045
3162
  throw new HarnessCliInputError(`invalid --repo (expected owner/name): ${repository}`);
3046
3163
  }
3164
+ const readLimit = (value: string | undefined, fallback: number, name: string, max: number): number => {
3165
+ const limit = value === undefined ? fallback : Number(value);
3166
+ if (!Number.isSafeInteger(limit) || limit < 1 || limit > max) throw new HarnessCliInputError(`invalid ${name} (expected 1~${max})`);
3167
+ return limit;
3168
+ };
3169
+ const applying = opts.apply === true;
3170
+ if (opts.emitApplyPlan && (applying || !opts.json)) throw new HarnessCliInputError('--emit-apply-plan requires dry-run --json');
3171
+ if (opts.applyPlanFile && !applying) throw new HarnessCliInputError('--apply-plan-file requires --apply');
3172
+ const applyPlan = opts.applyPlanFile
3173
+ ? validateDraftSweepApplyPlan(JSON.parse(readFileSync(resolve(opts.applyPlanFile), 'utf8')))
3174
+ : undefined;
3047
3175
  // One adapter instance per sweep: its open listing and ledger scan are shared with the RUN-TTL step.
3048
- const github = deps.adapters ? undefined : githubDraftSweepAdapters(deps.execute, undefined, undefined, undefined, deps.stopRun);
3176
+ const inventoryLimits = {
3177
+ maxInventoryPages: readLimit(opts.maxPages, applying ? 100 : 1, '--max-pages', 100),
3178
+ maxDrafts: opts.maxDrafts === undefined && applying ? undefined : readLimit(opts.maxDrafts, 10, '--max-drafts', 1_000),
3179
+ maxMerged: opts.maxMerged === undefined && applying ? undefined : readLimit(opts.maxMerged, 50, '--max-merged', 1_000),
3180
+ onInventoryProgress: ({ state, page, rows }: { state: 'open' | 'closed'; page: number; rows: number }) =>
3181
+ console.error(`[draft-sweep] inventory state=${state} page=${page} rows=${rows}`),
3182
+ };
3183
+ const github = deps.adapters ? undefined : githubDraftSweepPreviewAdapters(inventoryLimits, deps.execute, undefined, undefined, undefined, deps.stopRun);
3049
3184
  const configCap = deps.closeCapConfig
3050
3185
  ? deps.closeCapConfig()
3051
3186
  : (() => { try { return getUserConfig().tools?.selfImplement?.draftSweepCloseCap; } catch { return undefined; } })();
@@ -3055,7 +3190,7 @@ function installHarnessDraftSweepCommand(harnessCmd: Command, deps: HarnessDraft
3055
3190
  try { debug.log('self-dev.draft-sweep', 'close-cap-rejected', { warning, closeCap: cap.closeCap, closeCapSource: cap.closeCapSource }); } catch { /* fail-soft */ }
3056
3191
  }
3057
3192
  let replayClosed = 0;
3058
- if (opts.apply && (!deps.adapters || deps.residueReplay)) {
3193
+ if (opts.apply && !applyPlan && (!deps.adapters || deps.residueReplay)) {
3059
3194
  try {
3060
3195
  replayClosed = (await replayPodTerminals({ ...deps.residueReplay, repository, closeCap: cap.closeCap })).closed;
3061
3196
  } catch (error) {
@@ -3066,12 +3201,23 @@ function installHarnessDraftSweepCommand(harnessCmd: Command, deps: HarnessDraft
3066
3201
  }
3067
3202
  }
3068
3203
  const result: DraftSweepResult = await runDraftSweep({ repository, apply: opts.apply === true, includeTriage: opts.json === true, adapters: deps.adapters ?? github!,
3069
- closeCap: cap.closeCap, closeCapSource: cap.closeCapSource, alreadyClosed: replayClosed });
3204
+ closeCap: cap.closeCap, closeCapSource: cap.closeCapSource, alreadyClosed: replayClosed,
3205
+ includeApplyPlan: opts.emitApplyPlan === true, applyPlan });
3206
+ const frozenPlanMaintenance = applyPlan ? { postSweep: {
3207
+ residueReplay: 'skipped: frozen plan does not include terminal-residue PRs',
3208
+ runTtl: 'skipped: frozen plan does not include RUN-TTL PRs',
3209
+ } } : {};
3070
3210
  const reason = result.error ? sweepFailureReason(result.error) : undefined;
3071
3211
  const ttlStarted = Date.now();
3072
- const runTtl = await draftSweepRunTtl(repository, deps, github);
3212
+ const runTtl = result.complete && !applyPlan ? await draftSweepRunTtl(repository, deps, github) : undefined;
3073
3213
  try { debug.log('self-dev.draft-sweep', 'timing', { phase: 'run-ttl', ms: Date.now() - ttlStarted, count: runTtl && !('error' in runTtl) ? runTtl.considered : 0 }); } catch { /* fail-soft */ }
3074
- if (opts.json) write(JSON.stringify({ ...(reason ? { ...result, error: reason } : result), ...(runTtl ? { runTtl } : {}) }));
3214
+ if (opts.json) {
3215
+ const output = JSON.stringify({ ...(reason ? { ...result, error: reason } : result), ...frozenPlanMaintenance, ...(runTtl ? { runTtl } : {}) });
3216
+ // `src/index.ts` imports chalk, which makes Bun stdout non-blocking. Await the
3217
+ // write callback so a large JSON result cannot be silently cut at the pipe buffer.
3218
+ if (deps.write) write(output);
3219
+ else await writeStdoutFully(output);
3220
+ }
3075
3221
  else {
3076
3222
  if (runTtl) {
3077
3223
  write('error' in runTtl ? `run-ttl: 실패 (${runTtl.error})`
@@ -20,11 +20,13 @@ export interface GateLike {
20
20
  log?: string;
21
21
  }
22
22
 
23
+ const isMissingAtBaseLine = (line: string): boolean => /^- (?!(?:introduced|preexisting|unknown):).+: missing-at-base\b/.test(line);
24
+
23
25
  /** 리뷰어에게 줄 게이트 실행 증빙. 전체 로그 대신 러너/컴파일러가 낸 판정 줄만 원문으로 보존한다. */
24
26
  export function gateEvidenceNote(gate: GateLike): string | undefined {
25
27
  if (!gate.log?.trim()) return undefined;
26
28
  const lines = gate.log.split(/\r?\n/).filter((line) =>
27
- /(?:^\[gate-baseline\]|^- (?:introduced|preexisting|unknown):|^⚠️ .*책임이 아니다\.|Ran \d+ tests? across \d+ files?|\b\d+ (?:pass|fail)\b|error TS\d+|Verify-by-breaking|verify-by-breaking|원복 후|뒤집었을 때)/i.test(line),
29
+ isMissingAtBaseLine(line) || /(?:^\[gate-baseline\]|^\[changed-test-evidence\]|^- (?:introduced|preexisting|unknown):|^⚠️ .*책임이 아니다\.|Ran \d+ tests? across \d+ files?|\b\d+ (?:pass|fail)\b|error TS\d+|Verify-by-breaking|verify-by-breaking|원복 후|뒤집었을 때)/i.test(line),
28
30
  );
29
31
  if (!lines.length) return undefined;
30
32
 
@@ -33,19 +35,36 @@ export function gateEvidenceNote(gate: GateLike): string | undefined {
33
35
  const baselineHeads = lines.filter((line) => line.startsWith('[gate-baseline]'));
34
36
  const exonerations = lines.filter((line) => /^⚠️ .*책임이 아니다\.$/.test(line));
35
37
  const attributions = lines.filter((line) => /^- (?:introduced|preexisting|unknown):/.test(line));
38
+ const changedHeads = lines.filter((line) => line.startsWith('[changed-test-evidence]'));
39
+ const missingAtBase = lines.filter(isMissingAtBaseLine);
40
+ const changedEvidence = [
41
+ ...changedHeads.slice(0, 1),
42
+ ...(missingAtBase.length ? ['[changed-test-evidence] base에 없는 신규 모듈의 base RED 목격을 must-fix로 요구하지 말 것. missing-at-base는 RED 증거다.'] : []),
43
+ ...missingAtBase.slice(0, 4),
44
+ ...(missingAtBase.length > 4 ? [omission(missingAtBase.length - 4)] : []),
45
+ ...changedHeads.slice(1, 3),
46
+ ...(changedHeads.length > 3 ? [omission(changedHeads.length - 3)] : []),
47
+ ];
48
+ const prioritizedAttributions = changedEvidence.length
49
+ ? [...attributions.filter((line) => line.startsWith('- introduced:')),
50
+ ...attributions.filter((line) => !line.startsWith('- introduced:'))]
51
+ : attributions;
36
52
  const hasBaseline = baselineHeads.length > 0;
37
- const limit = 24;
38
- const rest = lines.filter((line) => !line.startsWith('[gate-baseline]') && !/^⚠️ .*책임이 아니다\.$/.test(line) && !/^- (?:introduced|preexisting|unknown):/.test(line));
53
+ const limit = 24; // evidence 줄 상한. 제목 한 줄을 더한 출력은 최대 25줄이다.
54
+ const rest = lines.filter((line) => !line.startsWith('[gate-baseline]') && !/^⚠️ .*책임이 아니다\.$/.test(line)
55
+ && !/^- (?:introduced|preexisting|unknown):/.test(line) && !line.startsWith('[changed-test-evidence]')
56
+ && !isMissingAtBaseLine(line));
39
57
  const ordered = hasBaseline
40
58
  ? [
41
59
  ...baselineHeads.slice(0, 1),
42
60
  ...exonerations.slice(0, 1),
43
- ...attributions,
61
+ ...changedEvidence,
62
+ ...prioritizedAttributions,
44
63
  ...baselineHeads.slice(1),
45
64
  ...exonerations.slice(1),
46
65
  ...rest,
47
66
  ]
48
- : lines;
67
+ : changedEvidence.length ? [...changedEvidence, ...exonerations, ...prioritizedAttributions, ...rest] : lines;
49
68
  if (!hasBaseline || ordered.length <= limit) {
50
69
  const selected = ordered.length <= limit
51
70
  ? ordered
@@ -58,7 +77,8 @@ export function gateEvidenceNote(gate: GateLike): string | undefined {
58
77
  const budgeted = [
59
78
  ...baselineHeads.slice(0, 1),
60
79
  ...exonerations.slice(0, 1),
61
- ...attributions.slice(0, attributionLimit),
80
+ ...changedEvidence,
81
+ ...prioritizedAttributions.slice(0, attributionLimit),
62
82
  ...(omittedAttributions ? [omission(omittedAttributions)] : []),
63
83
  ...baselineHeads.slice(1),
64
84
  ...exonerations.slice(1),