elanous 0.2.31 → 0.2.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (715) 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/{LSXfY0u9QtfDbejY0Ukf_ → L04y73dlwKeTW-GetaTF3}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/1162.c69abda138c7ce43.js +79 -0
  5. package/apps/pwa/out/_next/static/chunks/1449-1fede62af84c3e43.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1598-13fc845935e816df.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1639.62c5e16fa20d242f.js +94 -0
  8. package/apps/pwa/out/_next/static/chunks/{4174.92ed04922709ac9e.js → 1644.35dd25240ae24e4b.js} +2 -2
  9. package/apps/pwa/out/_next/static/chunks/1661-adb8b2babc9aaf8c.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/{2940-619bfd8ef337c611.js → 1895-60ed0e341c658bd4.js} +1 -1
  11. package/apps/pwa/out/_next/static/chunks/{5525.86debf231e181813.js → 2124.ed5bf480cea7f85b.js} +1 -1
  12. package/apps/pwa/out/_next/static/chunks/2147.107c0fc6146fb15a.js +23 -0
  13. package/apps/pwa/out/_next/static/chunks/2202-ef1c9b000c3074fc.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/2247.1e326638ee43e672.js +115 -0
  15. package/apps/pwa/out/_next/static/chunks/2268.56e1e3d58180abae.js +8 -0
  16. package/apps/pwa/out/_next/static/chunks/2469-606819c812414021.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/{6092.a7f99e68b188ca66.js → 2547.dd27303624cb4da8.js} +1 -1
  18. package/apps/pwa/out/_next/static/chunks/{2213.2ccbada92c33ea0f.js → 2554.3b5e200f5f5cfcd6.js} +16 -16
  19. package/apps/pwa/out/_next/static/chunks/2593.e53c1620c0bb3599.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2690.e96671114222676a.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2898-79ee1a5cc0cd9d13.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/298.26099a9f65e5c8ff.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/{5173-233188df2f42c626.js → 2987-30cf9c2eb7b8bdd5.js} +1 -1
  24. package/apps/pwa/out/_next/static/chunks/2992.51fc2a7295bd8139.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/{3541-ce3a5424ed5ad7f1.js → 3001-5a52788c813b6113.js} +1 -1
  26. package/apps/pwa/out/_next/static/chunks/3014-291245fba9df7b5b.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/3068.ee78201f0251a18d.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/3083.cd399a17e9365f78.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/3103.84470c8445962f04.js +34 -0
  30. package/apps/pwa/out/_next/static/chunks/{6433.fc573af22bbc9ab7.js → 3110.0a7065f25c841818.js} +17 -17
  31. package/apps/pwa/out/_next/static/chunks/3117-e1c474683fd1f824.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/3121.779fafe3e44612c5.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/3251-2c17bd5a91f8de2e.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/326.3fb32322bb2ddf6d.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/3411-f87314c6c66ebc73.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/{6157.0c9af021de4fb31b.js → 3414.172ad4ca2d9b08e8.js} +2 -2
  37. package/apps/pwa/out/_next/static/chunks/3421-7ff7fbaa156985a7.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{4745.67d6f99c245af3f7.js → 3498.cf2a15a8a9e5b926.js} +3 -3
  39. package/apps/pwa/out/_next/static/chunks/381.f55dc63ea87735e6.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3819.163d4777f0a597f6.js +32 -0
  41. package/apps/pwa/out/_next/static/chunks/{5543.a438b8ab5a13ea47.js → 3837.722e053fb9f321ad.js} +1 -1
  42. package/apps/pwa/out/_next/static/chunks/4129-ab0a6189f1778633.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4361.93d14ba594b3a035.js +104 -0
  44. package/apps/pwa/out/_next/static/chunks/4364.7a7eb19cceb67d2f.js +286 -0
  45. package/apps/pwa/out/_next/static/chunks/4406.d71f506f7c3ee9d3.js +149 -0
  46. package/apps/pwa/out/_next/static/chunks/4461.2ad1514180ae7e29.js +148 -0
  47. package/apps/pwa/out/_next/static/chunks/4479.bd309cbe0e3842ee.js +64 -0
  48. package/apps/pwa/out/_next/static/chunks/4522-05966f777d66d13b.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4543-9a3e9812e845de65.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4557.f8f1d84a0d90d590.js +74 -0
  51. package/apps/pwa/out/_next/static/chunks/4589-79b11542179ef58c.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4633-9f8f9f88ffbb8f5c.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4831.23af4d10c0697b5e.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4983.5951b85724f61f2a.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/{b313b242.cb1265eea908db61.js → 4fa33ebd.21c1bd5b294496e6.js} +1 -1
  56. package/apps/pwa/out/_next/static/chunks/{997ce8a5-2ad501927003b41b.js → 5014f970-22bef0b5210f7d60.js} +1 -1
  57. package/apps/pwa/out/_next/static/chunks/{2112-e4efc21a6505d5bc.js → 5028-f0722e6114c313e7.js} +1 -1
  58. package/apps/pwa/out/_next/static/chunks/{2898.fd781bc7cf01a7b7.js → 5249.96a848656b582a93.js} +1 -1
  59. package/apps/pwa/out/_next/static/chunks/5311.16e0ffbfa5468b80.js +62 -0
  60. package/apps/pwa/out/_next/static/chunks/{9407.e49124dedf0f5e72.js → 5446.edf141cff9ef647d.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{9002.e5658224e3dc1b6f.js → 5489.ec2dd1b5272a19dc.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/{1335-6731f392c35216eb.js → 5576-82d3703636d5c4b9.js} +3 -3
  63. package/apps/pwa/out/_next/static/chunks/559.df87695df637920c.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5618-5c88f2f70178c4ad.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/5764.05487bf0b73ddb6b.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5930.e678826c3f831aab.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5dfb57f7.f2e3305326202474.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/6053-d893974de92e6198.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/{2985.39ccdecd36848b12.js → 6086.913a69e6fa3e4a8b.js} +4 -4
  70. package/apps/pwa/out/_next/static/chunks/6200-cefd6f33f59d765e.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6314-edeba650ae686ac9.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6316-bc9a9b74d7842d79.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6476-13b9779b73528008.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/666-04db3ac4c8e3c66f.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/670.682e55106ef915a6.js +77 -0
  76. package/apps/pwa/out/_next/static/chunks/{7862.30a8d6482bb238eb.js → 6740.43de73fc427c9fe2.js} +1 -1
  77. package/apps/pwa/out/_next/static/chunks/6816.b7ba9d0a1a4a46a7.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/690-fbbcc777f189af37.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6989.0d3d4020e5cb3df6.js +90 -0
  80. package/apps/pwa/out/_next/static/chunks/{2871.0bca6137343b3f76.js → 7005.1623d2aea78eb85f.js} +1 -1
  81. package/apps/pwa/out/_next/static/chunks/7193-cf355cca5ba6c5d5.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/7217-d17393fe7af78fa6.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/7232.24edbd938a69c8d0.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7295cd1e.b4b557908888eeee.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7323.adb02de21991883c.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7386.5d8e7e42e818dfb6.js +287 -0
  87. package/apps/pwa/out/_next/static/chunks/{7502.ccd5b8065545edd0.js → 7431.3051e9b8a4372d2d.js} +2 -2
  88. package/apps/pwa/out/_next/static/chunks/{3583.a05e88cc8d594628.js → 7448.478958ffbbba0ac0.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/7537.ba2208c5c656b8a3.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7562.948255cbc3e79d33.js +41 -0
  91. package/apps/pwa/out/_next/static/chunks/7596-962ae6db6cfc9c83.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7671.cff51beac212a2ba.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7883.3916734ee16d3e58.js +27 -0
  94. package/apps/pwa/out/_next/static/chunks/{9989.3694300e5f000b14.js → 7952.b192c31b6a0e00cc.js} +1 -1
  95. package/apps/pwa/out/_next/static/chunks/801.5b24e81eded22d1b.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/8176.8c9a8613f5a01ac1.js +36 -0
  97. package/apps/pwa/out/_next/static/chunks/819e78a6.fa3dd7f7da19bf61.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8220-78978450c3183d8d.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/8221-eb60b5bc692a3361.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/826.e9a26064f474949e.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/{5307.60f2209e809bd627.js → 8368.014caa8de2f5af34.js} +1 -1
  102. package/apps/pwa/out/_next/static/chunks/8459-a351487a4480f584.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8482-75823d513a4ce151.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8488.8da515248cda3f3a.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{9221.7d22eaf353a2d4e7.js → 8548.036c344973968847.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/8584.388a1779d9b203af.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8637.a55e098e61ffefb8.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8817.61bb7ffbba502ecb.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/{9398-6aed28f0a96d0d6f.js → 9131-fce7256c4180c4a5.js} +1 -1
  110. package/apps/pwa/out/_next/static/chunks/9207-8e6a12db30373f32.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/9263-00ae932c62696a86.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9318.caafc3a130e8769c.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/932.da3fb55951882562.js +93 -0
  114. package/apps/pwa/out/_next/static/chunks/9433.002f8426ac75b6b7.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9464.dd631a5a14b1d660.js +24 -0
  116. package/apps/pwa/out/_next/static/chunks/{3278.2e5d15b53a4091c8.js → 9550.d5f76828f972058c.js} +2 -2
  117. package/apps/pwa/out/_next/static/chunks/{2534.e85ae21ad0dac829.js → 9739.8d5f36ac67a3b236.js} +1 -1
  118. package/apps/pwa/out/_next/static/chunks/9743.beeabb9d5f86abe4.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9843-a23d3f32dc43f715.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/994-28211077c7c587d5.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{7a1887c4.f36b88fba31da8fd.js → 9a8cb466.cc9fc9e6e46038aa.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/{0bb0ff36.b8d418980951e5ba.js → 9b48c871.204d5d13e7809bd0.js} +7 -7
  123. package/apps/pwa/out/_next/static/chunks/{409f1e57.d0649fc47691ebfe.js → abb4b98b.163e0f56e84ae35d.js} +1 -1
  124. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-3b4c947f174e33d8.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/approvals/page-369d5ce99483f859.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-63c0ed0eb26e5fce.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/board/page-62802c6003bc85cc.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ecb41560d4e77be9.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/bots/page-7b65ad8130c93e95.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/ceo/page-8755477c15a9060c.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/chat/page-5725447dd972c471.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/consult/page-b979de0591a69375.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/control/page-6d0796bf4633751a.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/decisions/page-59c31dc0394e67b4.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/design-check/page-12dfc95f6cc5c718.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/editor/page-25788244e66aa4dd.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/exec/page-a2555dc705466322.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/field/page-4fb31eb476dcbad3.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/healthz/route-3b4c947f174e33d8.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/inside/page-578729adbeaa40cb.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/intake/page-a1d20fffbec35205.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/layout-4a558f94516b8004.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live/page-9e3834705b86145e.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/live-run/page-d7bff0f0905a662c.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/loops/page-cb1c5fe746ea4014.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/market/page-9ee320507356582a.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66fd183b74835886.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/morning/page-3272a064a01a9927.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/not-found-f281b7a7f6ef2529.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/observatory/page-d45a65f8b7124fcd.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-e9c1fe684dd19a66.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-b8322932fc6e34de.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-82c66d9af2290575.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/outputs/page-63c6752009c97b05.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/page-bb33d42ebc358aec.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7e4c9379197d7214.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-38bf1e9a7001732b.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/sessions/page-2e5b752012389d56.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-0a07363b130182a1.js → page-398c0faa173203f7.js} +1 -1
  160. package/apps/pwa/out/_next/static/chunks/app/settings/page-002f53a965b6445c.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-7f75997f61a26269.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/layout-3b4c947f174e33d8.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/page-05631753294f23fb.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/share/page-edd700fd2cc3d7f8.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/showroom/page-105f83ecb4594365.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/tasks/page-5823e87d2017f19c.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/term/page-df3445b207ceceab.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/today/page-b51ca09566c03de7.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/trace/page-8aacd5ded5dbac60.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/vault/page-bae3365a0b3c6a8e.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ed52b48ff1aa7fd.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b6f8cad35fe00946.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6d25ceda500d2457.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-b6401a5f2c962fe8.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/ebf6cf5e.0d2f887b040e80fb.js +122 -0
  176. package/apps/pwa/out/_next/static/chunks/f09ec7d7-d29abe23edcbb193.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/{ebc7d829.264a0bcb6c750b50.js → ffdc3a04.b9c23c1b28dd4a96.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/framework-9322cb8a56ac081c.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-2fbab294e49a1561.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-f36729f56621a8f3.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-2a62e450b47c6114.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-5e17f7b445f34d43.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-b4263e2190ea7adf.js +1 -0
  184. package/apps/pwa/out/_next/static/css/b5d88eba78a3d7bf.css +1 -0
  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 +26 -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/bin/elanous.mjs +9 -2
  279. package/docs/goal-context/README.md +1 -0
  280. package/graphs/default-loop.yaml +20 -3
  281. package/graphs/document-loop.yaml +21 -2
  282. package/graphs/implement-loop.yaml +11 -0
  283. package/graphs/journey/SCENARIOS.md +33 -0
  284. package/graphs/journey/recipes.yaml +1 -0
  285. package/graphs/journey/ta-journey.yaml +84 -0
  286. package/graphs/journey/units/author/author.yaml +20 -0
  287. package/graphs/journey/units/author/recipes.yaml +2 -0
  288. package/graphs/journey/units/green/green.yaml +20 -0
  289. package/graphs/journey/units/green/recipes.yaml +2 -0
  290. package/graphs/journey/units/pr/pr.yaml +20 -0
  291. package/graphs/journey/units/pr/recipes.yaml +2 -0
  292. package/graphs/journey/units/remember/recipes.yaml +2 -0
  293. package/graphs/journey/units/remember/remember.yaml +20 -0
  294. package/graphs/operate-loop.yaml +21 -2
  295. package/graphs/overlays/stop-heal-ladder.yaml +1 -1
  296. package/graphs/release-rehearsal/recipes.yaml +1 -1
  297. package/graphs/release-rehearsal/release-rehearsal.yaml +2 -2
  298. package/graphs/research-loop.yaml +23 -2
  299. package/graphs/units/dispatch-pod/dispatch-pod.yaml +50 -0
  300. package/graphs/units/dispatch-pod/recipes.yaml +14 -0
  301. package/graphs/units/entry/entry.yaml +50 -0
  302. package/graphs/units/entry/recipes.yaml +14 -0
  303. package/graphs/units/harvest/harvest.yaml +25 -0
  304. package/graphs/units/harvest/recipes.yaml +4 -0
  305. package/graphs/units/land/land.yaml +45 -0
  306. package/graphs/units/land/recipes.yaml +3 -0
  307. package/graphs/units/recipes.yaml +7 -0
  308. package/graphs/units/recover.yaml +39 -0
  309. package/graphs/units/reflect/recipes.yaml +3 -0
  310. package/graphs/units/reflect/reflect.yaml +15 -0
  311. package/graphs/units/task-agent-recover-review.yaml +17 -0
  312. package/graphs/units/task-agent-recover-wait.yaml +17 -0
  313. package/graphs/units/verbs/make-doc.yaml +34 -0
  314. package/graphs/units/verbs/recipes.yaml +33 -0
  315. package/graphs/units/verbs/verify.yaml +55 -0
  316. package/graphs/work/recipes.yaml +2 -0
  317. package/graphs/work/research-report.yaml +28 -0
  318. package/package.json +1 -1
  319. package/scripts/ci-typecheck-changed.ts +95 -17
  320. package/scripts/docs/generate-graph-anatomy.ts +19 -2
  321. package/scripts/graph-harvest-unit.ts +22 -0
  322. package/scripts/graph-units/journey-stub.ts +6 -0
  323. package/scripts/graph-units/land-enqueue.ts +78 -0
  324. package/scripts/graph-units/recover-plan.ts +15 -0
  325. package/scripts/graph-units/reflect-node.ts +88 -0
  326. package/scripts/graph-units/ta-journey-observe.ts +109 -0
  327. package/scripts/graph-units/verbs/headless-goal-loop.ts +152 -0
  328. package/scripts/graph-units/verbs/verify-stage.ts +75 -0
  329. package/scripts/graph-units/verbs-envelope.ts +139 -0
  330. package/scripts/hq/standby-snapshot.ts +25 -0
  331. package/scripts/measure-si-task-cpu.ts +143 -0
  332. package/scripts/public-export.ts +43 -1
  333. package/scripts/ratchets/test-interference-patterns.allowlist.txt +0 -2
  334. package/scripts/ratchets/train-side-invariants.sh +45 -0
  335. package/scripts/release-loop/auto-approve-node.ts +30 -16
  336. package/scripts/release-loop/gate-closure.ts +5 -1
  337. package/scripts/release-loop/gate-diff.ts +1 -1
  338. package/scripts/release-loop/gate-node.ts +498 -31
  339. package/scripts/release-loop/gate-partial.ts +3 -3
  340. package/scripts/release-loop/gate-radius-shadow.ts +138 -0
  341. package/scripts/release-loop/gate-traffic-mode.ts +128 -0
  342. package/scripts/release-loop/gate-triage-node.ts +5 -2
  343. package/scripts/release-loop/known-issues-0.2.33-approved.json +194 -0
  344. package/scripts/release-loop/known-issues-node.ts +77 -8
  345. package/scripts/release-loop/preflight.ts +93 -7
  346. package/scripts/release-loop/prepare-node.ts +102 -4
  347. package/scripts/release-loop/publish-node.ts +60 -9
  348. package/scripts/release-loop/resume-cap.ts +56 -0
  349. package/scripts/release-loop/resume-release.ts +114 -15
  350. package/scripts/release-loop/resume.ts +24 -1
  351. package/scripts/release-loop/tui-sim-node.ts +8 -2
  352. package/scripts/release-loop/unattended-release.ts +8 -2
  353. package/src/acp/core-turn-bridge.ts +36 -9
  354. package/src/acp/elanous-extensions.ts +3 -0
  355. package/src/acp/reasoning-thought-buffer.ts +45 -0
  356. package/src/acp/server.ts +3 -0
  357. package/src/acp/tool-trace.ts +186 -11
  358. package/src/agent/self-ambient-cache.ts +156 -0
  359. package/src/agent/self-ambient.ts +8 -1
  360. package/src/agent/task-notification.ts +5 -0
  361. package/src/agent-substrate/acp-reviewer.ts +52 -12
  362. package/src/agent-substrate/pr-reviewer.ts +3 -1
  363. package/src/agent-substrate/review-finding-key.ts +53 -0
  364. package/src/agent-substrate/self-review-cli.ts +126 -5
  365. package/src/ask-user-question/pending-questions.ts +1 -1
  366. package/src/ask-user-question/tool.ts +22 -0
  367. package/src/autopilot/build/llm-conflict-merge.ts +56 -10
  368. package/src/autopilot/pr-manager.ts +213 -46
  369. package/src/capture/frame-state-detect.ts +39 -0
  370. package/src/capture/tui-self-report.ts +134 -6
  371. package/src/chat/index.ts +61 -15
  372. package/src/chat/pickers/modal-runtime.ts +6 -0
  373. package/src/chat/pickers/modals.ts +8 -2
  374. package/src/chat/tool-render/dispatch.ts +62 -10
  375. package/src/cli/ask-bare.ts +1 -0
  376. package/src/cli/control-cli.ts +24 -7
  377. package/src/cli/guardian-cli.ts +10 -0
  378. package/src/cli/import-cli.ts +12 -0
  379. package/src/cli/light-entry-route.ts +35 -0
  380. package/src/cli/llm-detect-cli.ts +23 -1
  381. package/src/cli/log-event-names.ts +10 -0
  382. package/src/cli/msg-cli.ts +1 -0
  383. package/src/cli/pod-cli.ts +14 -3
  384. package/src/cli/pr-cli.ts +140 -41
  385. package/src/cli/pr-land-base-read.ts +36 -0
  386. package/src/cli/pr-land-heavy-remote.ts +81 -25
  387. package/src/cli/pr-land-overlap-evidence.ts +200 -18
  388. package/src/cli/pr-land-pod-shadow-job.ts +26 -3
  389. package/src/cli/pr-land-recovery.ts +64 -0
  390. package/src/cli/pr-land-refusal.ts +20 -5
  391. package/src/cli/pty-takeover-cli.ts +94 -19
  392. package/src/cli/release-cli.ts +120 -33
  393. package/src/cli/release-run-if-ready.ts +29 -28
  394. package/src/cli/release-single-flight.ts +178 -0
  395. package/src/cli/seat-cli.ts +37 -0
  396. package/src/cli/setup-cli.ts +40 -1
  397. package/src/cli/sim-cli.ts +18 -0
  398. package/src/cli/tasks-cli.ts +149 -5
  399. package/src/context-bus/ops-events.ts +6 -2
  400. package/src/control/control-status.ts +8 -3
  401. package/src/control-plane/ledger.ts +5 -3
  402. package/src/control-plane/server.ts +5 -3
  403. package/src/core-turn/run-core-turn.ts +1 -0
  404. package/src/core-turn/run-goal-loop.ts +21 -0
  405. package/src/core-turn/short-question.ts +5 -1
  406. package/src/core-turn/types.ts +3 -0
  407. package/src/dashboard/acp-active-model.ts +42 -1
  408. package/src/dashboard/background-jobs-status.ts +66 -0
  409. package/src/dashboard/index.ts +153 -111
  410. package/src/dashboard/input/agent-wake.ts +242 -0
  411. package/src/dashboard/input/chat-main-entry-runtime.ts +5 -0
  412. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +3 -0
  413. package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
  414. package/src/dashboard/input/external-input-host.ts +23 -9
  415. package/src/dashboard/input/mouse-wiring.ts +108 -11
  416. package/src/dashboard/input/seat-autowake.ts +56 -3
  417. package/src/dashboard/log-click-runtime.ts +118 -2
  418. package/src/dashboard/seat-boot-preamble.ts +1 -1
  419. package/src/dashboard/slash-runtime/ask-clarification.ts +48 -0
  420. package/src/dashboard/slash-runtime/dashboard-delegated-slashes.ts +68 -0
  421. package/src/dashboard/slash-runtime/dashboard-handlers.ts +62 -322
  422. package/src/dashboard/slash-runtime/dashboard-log-slash.ts +208 -0
  423. package/src/dashboard/turn-preamble.ts +163 -41
  424. package/src/dashboard/turn-session-layers.ts +4 -2
  425. package/src/dashboard/turn-start-segments.ts +222 -0
  426. package/src/dashboard/turn-stream-formatter.ts +34 -1
  427. package/src/dashboard/turn-stream-runtime.ts +2 -0
  428. package/src/dashboard/turn-typeahead-prompt-zone.ts +67 -0
  429. package/src/display/prompt-row-owner.ts +146 -0
  430. package/src/display/resize-listener.ts +33 -2
  431. package/src/domains/guardian-tick.ts +54 -2
  432. package/src/domains/outbound-alert.ts +3 -2
  433. package/src/extractors.ts +3 -1
  434. package/src/fold-stack.ts +4 -2
  435. package/src/git-fs/index.ts +263 -36
  436. package/src/git-fs/retry.ts +4 -0
  437. package/src/git-fs/runner.ts +2 -0
  438. package/src/graph-runner/runner.ts +114 -44
  439. package/src/grok/credential.ts +5 -0
  440. package/src/harness/gate-reserve.ts +87 -0
  441. package/src/harness/harness-cli-command.ts +39 -10
  442. package/src/harness/harness-incidents.ts +17 -0
  443. package/src/harness/harness-pod-dispatch.ts +38 -1
  444. package/src/harness/harness-queue.ts +15 -0
  445. package/src/harness/harness-salvage-cli.ts +14 -2
  446. package/src/index.ts +198 -12
  447. package/src/input/external-input-queue.ts +34 -9
  448. package/src/intake-plane/already-built-hint.ts +89 -0
  449. package/src/knowhow/pack.ts +199 -0
  450. package/src/light-cli.ts +95 -0
  451. package/src/llm/route-decision.ts +36 -0
  452. package/src/llm/tool-loop-steered-rejection.ts +8 -0
  453. package/src/llm-request-shape.ts +209 -0
  454. package/src/llm.ts +221 -276
  455. package/src/loops/budget.ts +95 -0
  456. package/src/loops/msg-wake.ts +8 -2
  457. package/src/loops/orchestrator/tick.ts +24 -2
  458. package/src/loops/orchestrator/traffic.ts +132 -1
  459. package/src/maturity/feature-maturity.ts +1 -1
  460. package/src/mss/logging/log-store.ts +4 -5
  461. package/src/mss/logging/render-categories.ts +5 -0
  462. package/src/nexus/api/graphs-api.ts +22 -3
  463. package/src/nexus/api/http-server.ts +1 -1
  464. package/src/nexus/api/ops-api.ts +12 -0
  465. package/src/oauth/claude-pty-maturity.ts +66 -0
  466. package/src/oauth/codex-access-mirror.ts +55 -0
  467. package/src/oauth/fallback-chain.ts +1 -1
  468. package/src/onboarding/first-run.ts +5 -3
  469. package/src/onboarding/non-interactive.ts +64 -13
  470. package/src/onboarding.ts +10 -2
  471. package/src/ops/overview-collect.ts +36 -1
  472. package/src/ops/overview.ts +70 -2
  473. package/src/pr-tool/census.ts +41 -8
  474. package/src/pr-tool/inflight-registry.ts +296 -0
  475. package/src/prompt-library/gpt6-family-addendum.ts +14 -1
  476. package/src/pty-shell/herdr-agent-report.ts +442 -0
  477. package/src/pty-shell/pty-control-ipc.ts +5 -5
  478. package/src/pty-shell/pty-manifest.ts +12 -3
  479. package/src/pty-shell/pty-write-outcome.ts +24 -6
  480. package/src/pty-shell/tui-run-state.ts +151 -6
  481. package/src/release-loop/checklist.ts +79 -5
  482. package/src/release-loop/feature-store.ts +19 -2
  483. package/src/release-loop/placement.ts +10 -3
  484. package/src/release-loop/rehearsal.ts +205 -25
  485. package/src/release-loop/rubric.ts +16 -2
  486. package/src/seat-loop/traffic-signal.ts +2 -1
  487. package/src/self-dev/ask-launch-flow.ts +13 -0
  488. package/src/self-dev/draft-residue.ts +243 -24
  489. package/src/self-dev/draft-sweep.ts +52 -3
  490. package/src/self-dev/graph-journey-nodes.ts +10 -6
  491. package/src/self-dev/graph-journey-route.ts +60 -6
  492. package/src/self-dev/orchestrate.ts +79 -3
  493. package/src/self-dev/run-supervisor.ts +107 -12
  494. package/src/self-dev/run-types.ts +5 -1
  495. package/src/self-dev/shard-plan.ts +11 -3
  496. package/src/self-dev/shard-run.ts +103 -10
  497. package/src/self-implement/elanous-tui-spawn.ts +14 -0
  498. package/src/self-implement/follow-up-placement.ts +79 -0
  499. package/src/self-implement/gate-artifacts.ts +15 -4
  500. package/src/self-implement/gate-baseline.ts +145 -10
  501. package/src/self-implement/gate-cli.ts +7 -2
  502. package/src/self-implement/gate-remote.ts +35 -6
  503. package/src/self-implement/goal-author-identity.ts +66 -0
  504. package/src/self-implement/goal-author-preservation-obligation.ts +35 -0
  505. package/src/self-implement/goal-author.ts +4 -120
  506. package/src/self-implement/graph-overlay-yaml.ts +17 -2
  507. package/src/self-implement/graph-unit-flatten.ts +103 -0
  508. package/src/self-implement/graph-unit-resolver.ts +107 -0
  509. package/src/self-implement/graph-yaml.ts +151 -1
  510. package/src/self-implement/headless-elanous-driver.ts +1 -0
  511. package/src/self-implement/host-regate.ts +36 -4
  512. package/src/self-implement/knowhow-pack.ts +103 -0
  513. package/src/self-implement/orchestrator.ts +109 -11
  514. package/src/self-implement/pod-warm-pool-profile.ts +45 -0
  515. package/src/self-implement/review-mustfix-class.ts +203 -0
  516. package/src/self-implement/run-ledger.ts +16 -14
  517. package/src/self-implement/run-stop.ts +8 -2
  518. package/src/self-implement/seams.ts +32 -1
  519. package/src/self-implement/stop-autoheal.ts +25 -1
  520. package/src/session/chat.ts +27 -0
  521. package/src/session-runtime/index.ts +22 -267
  522. package/src/session-runtime/retry-policy.ts +2 -1
  523. package/src/shell-runner/background-surface.ts +15 -5
  524. package/src/skills/tools/agent.ts +39 -6
  525. package/src/skills/tools/list-dir.ts +11 -0
  526. package/src/skills/tools/schedule-wakeup.ts +457 -0
  527. package/src/skills/tools/shell.ts +245 -3
  528. package/src/status/bar.ts +26 -0
  529. package/src/steward/digest-delivery.ts +118 -0
  530. package/src/steward/hold-hygiene.ts +120 -0
  531. package/src/steward/release-day.ts +7 -3
  532. package/src/steward/triage.ts +47 -4
  533. package/src/surface/shell-runner-boot.ts +5 -2
  534. package/src/task-agent/harvest-unit.ts +141 -0
  535. package/src/task-agent/live-moves.ts +98 -12
  536. package/src/task-agent/parent-host.ts +93 -3
  537. package/src/task-agent/postland-card.ts +80 -1
  538. package/src/task-agent/rejudge-on-head.ts +112 -26
  539. package/src/task-agent/repair-branch-cas.ts +4 -1
  540. package/src/task-agent/repair-cycle.ts +16 -3
  541. package/src/task-agent/run-identity.ts +4 -3
  542. package/src/task-agent/shadow.ts +12 -2
  543. package/src/task-agent/task-hand.ts +76 -5
  544. package/src/task-agent/work-order-build.ts +22 -0
  545. package/src/task-orchestrator/surfaces/pod-account-broker.ts +39 -3
  546. package/src/task-orchestrator/surfaces/pod-command-job.ts +67 -12
  547. package/src/task-orchestrator/surfaces/pod-lease.ts +98 -0
  548. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +1 -1
  549. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +86 -8
  550. package/src/task-orchestrator/surfaces/pod-pool.ts +76 -18
  551. package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +10 -6
  552. package/src/task-orchestrator/surfaces/pod-source-receive.ts +54 -4
  553. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +548 -0
  554. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +389 -0
  555. package/src/task-orchestrator/surfaces/pod-warm-worker-runner.ts +90 -0
  556. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +158 -3
  557. package/src/task-orchestrator/surfaces/self-implement-pod.ts +230 -43
  558. package/src/task-orchestrator/surfaces/self-implement.ts +83 -2
  559. package/src/tool-runtime/truncation-store.ts +4 -0
  560. package/src/tui/chat/execution-badge.ts +5 -1
  561. package/src/tui/input-lag-probe.ts +230 -0
  562. package/src/tui-client/dashboard-session.ts +10 -1
  563. package/src/tui.ts +4 -0
  564. package/src/user-config/coercion.ts +36 -0
  565. package/src/user-config.ts +18 -41
  566. package/src/ux-sim/scenario.ts +314 -0
  567. package/src/version/packed-revision.json +1 -1
  568. package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +0 -27
  571. package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +0 -287
  572. package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +0 -62
  573. package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/1654.32de4b324981a188.js +0 -23
  577. package/apps/pwa/out/_next/static/chunks/1834-50625904996a8fa8.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +0 -149
  579. package/apps/pwa/out/_next/static/chunks/1913.7cc6fb6055b1ed3f.js +0 -41
  580. package/apps/pwa/out/_next/static/chunks/2001.6c7e0fd02190886c.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +0 -115
  587. package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +0 -64
  588. package/apps/pwa/out/_next/static/chunks/3267c0e6.d34854e7b3984a6e.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/3902.e1e71aaac850a045.js +0 -34
  591. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/4111.2bfedbb233ad206b.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +0 -36
  595. package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +0 -286
  599. package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +0 -77
  600. package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +0 -79
  602. package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +0 -148
  605. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/5458-16cd7a2b51b74c8c.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +0 -74
  610. package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +0 -94
  612. package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/60fb96c9.360b01d8d4927b7b.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +0 -90
  619. package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +0 -32
  620. package/apps/pwa/out/_next/static/chunks/6544cb48.a87fe20ddf137be2.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +0 -104
  622. package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +0 -24
  627. package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +0 -93
  628. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +0 -8
  635. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/8097-92f87bd108322f66.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/9138.b6e80031afb1d973.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/9279-d28c5b7754d010ae.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/approvals/page-bf3634a117322df7.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-3535a4a69f1fafaa.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/board/page-b9f51447f757fbf2.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/botlab/page-2ebb8fd59b9461f9.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/bots/page-a2fc4e49a4fa4ba8.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/ceo/page-5a503541353e60a8.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/chat/page-6025101384e361a5.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/consult/page-f4b630cc8b5273cd.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/control/page-a645f00a06483e9a.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/decisions/page-61ac22cbab1ee4ec.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e9bab7413b028b28.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/editor/page-c992eafe028b642e.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/exec/page-e547e6ce55f1fb33.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/field/page-d27e1b9850fd54bf.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/inside/page-805ac2e137b7a121.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/intake/page-0fec29c7ba01894b.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/layout-339a07410cd6f36b.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/live/page-349f2752d8cd37ad.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/live-run/page-d5c6dcf31c25cecc.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/loops/page-2fd93ed8c9f16580.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/market/page-9b564dbff0fefc35.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-62f4475d3c38fb9b.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/morning/page-814ba51385225776.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/not-found-397d479626e5a459.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/observatory/page-af1bba4e3251b728.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ad3be5e7d3fdce9.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-f219ccdbc0bf27df.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4da93ad35d4a8d28.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/outputs/page-456666766e5ce6fc.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/page-7404e377e8adb8c5.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/app/reflection/page-14456240ed2a36ad.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-3a658d5fa6d16a25.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/app/sessions/page-0157de6e85f8bb6b.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/app/settings/page-841d73d4ac44ed49.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6f43a3d1146e6377.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/app/setup/page-521ee23ac8c0abfa.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/app/share/page-a9992ee285efaa83.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/showroom/page-3d48e85fa89ec04f.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d2ced71132fac9b2.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/term/page-f08358bdf251adb9.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/today/page-233c71cd5f68f0d7.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/trace/page-70151d78de2f375e.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/app/vault/page-dcac33a3e2cb72c0.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-149dc1caba411bb9.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/app/workflows/page-0448145ccd5c45c1.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/app/workspace/page-9cb0c444903da65d.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-17e504c396e0e389.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +0 -122
  706. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +0 -1
  713. package/apps/pwa/out/_next/static/css/3f5fc6f96e2cf7b2.css +0 -1
  714. package/src/cli/g6a-registration-probe.ts +0 -16
  715. /package/apps/pwa/out/_next/static/{LSXfY0u9QtfDbejY0Ukf_ → L04y73dlwKeTW-GetaTF3}/_ssgManifest.js +0 -0
@@ -58,11 +58,41 @@ export interface HarnessPodDispatchInput {
58
58
  readonly authorGradeSource?: import('../self-implement/goal-author.js').GoalAuthorGradeSource;
59
59
  }
60
60
 
61
+ /** The mbp fleet alias must select the installed local k3d context, with a deliberately small first capacity. */
62
+ export function resolveHarnessPodPool(spec: string | undefined): string | undefined {
63
+ if (!spec) return spec;
64
+ let changed = false;
65
+ let mbpCapacity = 0;
66
+ let mbpMembers = 0;
67
+ const members = spec.split(',').map((raw) => {
68
+ const part = raw.trim();
69
+ const alias = /^pool-mbp@mbp:(\d+)$/.exec(part);
70
+ const local = /^k3d-monad-h1:(\d+)$/.exec(part);
71
+ if (!alias && !local) {
72
+ if (/^pool-mbp@mbp(?::|$)/.test(part) || /^k3d-monad-h1(?::|$)/.test(part)) {
73
+ throw new Error(`mbp Pod 풀 스펙 오류: ${part}`);
74
+ }
75
+ return part;
76
+ }
77
+ const capacity = Number((alias ?? local)![1]);
78
+ if (!Number.isInteger(capacity) || capacity < 1 || capacity > 2) {
79
+ throw new Error(`mbp Pod 풀 상한은 1~2: ${part}`);
80
+ }
81
+ mbpCapacity += capacity;
82
+ mbpMembers++;
83
+ if (mbpCapacity > 2) throw new Error(`mbp Pod 풀 합산 상한은 2: ${spec}`);
84
+ if (mbpMembers > 1) throw new Error(`mbp Pod 풀 컨텍스트 중복: ${spec}`);
85
+ if (alias) changed = true;
86
+ return `k3d-monad-h1:${capacity}`;
87
+ });
88
+ return changed ? members.join(',') : spec;
89
+ }
90
+
61
91
  export function podOrchestrateArgs(input: HarnessPodDispatchInput, goalFile: string): string[] {
62
92
  return [
63
93
  ELANOUS_ENTRY_SCRIPT, 'self', 'orchestrate', '--goal-file', goalFile,
64
94
  '--substrate', 'pod',
65
- ...(input.podPool ? ['--pod-pool', input.podPool] : []),
95
+ ...(input.podPool ? ['--pod-pool', resolveHarnessPodPool(input.podPool)!] : []),
66
96
  // 하니스 기본(자동 병합)을 따른다 · 끄면 PR 까지 — 어느 쪽이든 Pod 가 사라져도 결과가 남는다.
67
97
  ...(input.repairCommitOnly ? [] : input.autoMerge === false ? ['--open-pr'] : ['--auto-merge']),
68
98
  ...(input.repairCommitOnly && input.source ? ['--base', `pr-${input.source.slice(3)}`] : input.base ? ['--base', input.base] : []),
@@ -99,6 +129,13 @@ export function dispatchHarnessOnPod(input: HarnessPodDispatchInput, deps: PodDi
99
129
  export function dispatchHarnessOnPod(input: HarnessPodDispatchInput, deps?: PodDispatchDeps): number | Promise<number>;
100
130
  export function dispatchHarnessOnPod(input: HarnessPodDispatchInput, deps: PodDispatchDeps = {}): number | Promise<number> {
101
131
  const cwd = deps.cwd ?? process.cwd();
132
+ try { resolveHarnessPodPool(input.podPool); }
133
+ catch (error) {
134
+ const reason = error instanceof Error ? error.message : String(error);
135
+ debug.log('harness.substrate', 'pod-pool-refused', { entrance: input.entrance, reason });
136
+ console.error(reason);
137
+ return 2;
138
+ }
102
139
  if (input.source !== undefined) {
103
140
  try {
104
141
  parsePodSourceSpec(input.source);
@@ -21,6 +21,7 @@ import { hostLeaseCounts, leaseHasPendingPod } from '../pod-lease/host-lease.js'
21
21
  import { leaseKubectl, measurePoolLease } from '../task-orchestrator/surfaces/pod-lease.js';
22
22
  import { parsePodPool, podPoolHostLease, resolvePodPoolSpec } from '../task-orchestrator/surfaces/pod-pool.js';
23
23
  import { writeHarnessQueueReceipt } from './harness-queue-child.js';
24
+ import { detectReleaseGateActive, gateReserve } from './gate-reserve.js';
24
25
  import { adviseLaunch, compareLaunchAdvice, type LaunchAdvice } from './launch-advice.js';
25
26
  import { finishAdvice, measureFinish, recordFinishHistory, type FinishMetrics } from '../loops/orchestrator/finish-rate.js';
26
27
  import { collectDraftMetrics, DRAFT_NEEDS_OWNER_SEAT_CAP, shouldHoldSeatNewLaunch, type DraftMetrics } from '../self-dev/draft-sweep.js';
@@ -85,6 +86,8 @@ export interface HarnessQueueDeps {
85
86
  pool?: () => QueuePool;
86
87
  /** Shadow-only advice seam; exceptions must not affect the queue decision. */
87
88
  advice?: typeof adviseLaunch;
89
+ /** Gate-reserve observation only; never changes seatCapDetails or decideSpawn inputs. */
90
+ releaseGateActive?: () => boolean | Promise<boolean>;
88
91
  launch?: (item: QueueItem, args: string[], root: string) => Promise<number>;
89
92
  /** Test seam: runs after a direct CLI call enqueued its row and before that call's own tick (race tests). */
90
93
  afterEnqueue?: (item: QueueItem) => void | Promise<void>;
@@ -1495,6 +1498,10 @@ async function tickHarnessQueueOnce(deps: HarnessQueueDeps, requestedId: string
1495
1498
  }
1496
1499
  return waiting();
1497
1500
  }
1501
+ // Shadow measurement runs outside the approval path. One async probe serves all candidates in this tick.
1502
+ const gateActivePromise = !childUniverses?.unreadable.length
1503
+ ? Promise.resolve().then(() => (deps.releaseGateActive ?? detectReleaseGateActive)()).catch(() => false)
1504
+ : undefined;
1498
1505
  // NEEDS-OWNER-CENSUS: one draft census per tick, shared by every candidate. A full census pages all
1499
1506
  // open drafts, the 48h closed cohort, and one claim-comment gh call per open draft — re-running it
1500
1507
  // per candidate multiplied those calls by the seat count and raced the rate limit the seat-loop tick
@@ -1516,6 +1523,14 @@ async function tickHarnessQueueOnce(deps: HarnessQueueDeps, requestedId: string
1516
1523
  const injectedCap = deps.cap?.(item.seat);
1517
1524
  const details = seatCapDetails({ seat: item.seat, caps, gate, injectedCap });
1518
1525
  const active = seatActive(item.seat);
1526
+ // An unreadable child universe makes the running count incomplete; do not emit a misleading cap sample.
1527
+ if (gateActivePromise) void gateActivePromise.then((gateActive) => {
1528
+ try {
1529
+ const reserve = gateReserve({ releaseGateActive: gateActive === true, seat: item.seat, configuredGateCap: gate?.[item.seat] ?? 4 });
1530
+ debug.log('harness.queue', 'gate-reserve-shadow', { seat: item.seat, active: reserve.active, wouldCap: reserve.wouldCap,
1531
+ cap: details.cap, running: active });
1532
+ } catch { /* Shadow observation cannot affect the decision. */ }
1533
+ });
1519
1534
  if (active >= details.cap) { blocked.set(item.seat, { reason: seatLine(item.seat, active, details), active }); continue; }
1520
1535
  if (!pool && !poolReason) {
1521
1536
  try { pool = (deps.pool ?? readHarnessQueuePool)(); }
@@ -5,7 +5,9 @@
5
5
  import type { Command } from 'commander';
6
6
  import { debug } from '../debug/log.js';
7
7
  import { normalizeRunId } from './harness-space.js';
8
- import { loadFederatedRunLedger } from '../self-implement/run-ledger.js';
8
+ import { loadFederatedRunLedger, loadRunLedger } from '../self-implement/run-ledger.js';
9
+ import { prodInstanceRoot } from '../instance/resolve.js';
10
+ import { remoteLedgerMirrorDirs } from '../task-agent/parent-host.js';
9
11
  import { getUserConfig } from '../user-config.js';
10
12
  import { resolveRepositoryName } from './repository-name.js';
11
13
  import {
@@ -35,9 +37,19 @@ export interface HarnessSalvageDeps {
35
37
  print?: (line: string) => void;
36
38
  }
37
39
 
40
+ /** 원격 부모 거울 원장 — remoteLedgerMirrorDirs(prodInstanceRoot()) 를 로컬·연합 원장 «뒤에»만 붙인다(tasks 쪽 원장 조회와 같은 재사용 경로 · 거울 생성·SSH 는 별개 칸). */
41
+ function loadMirroredRunLedger(runId: string): ReturnType<typeof loadRunLedger> {
42
+ for (const directory of remoteLedgerMirrorDirs(prodInstanceRoot())) {
43
+ const ledger = loadRunLedger(runId, directory);
44
+ if (ledger !== null) return ledger;
45
+ }
46
+ return null;
47
+ }
48
+
38
49
  function defaultReadPr(runId: string): RunPrState {
39
50
  try {
40
- return prStateFromLedger(loadFederatedRunLedger(runId, { includeTest: true }));
51
+ // 로컬·연합 원장 먼저, 없으면 원격 부모 거울 — 순서는 tasks 쪽 원장 조회와 같다.
52
+ return prStateFromLedger(loadFederatedRunLedger(runId, { includeTest: true }) ?? loadMirroredRunLedger(runId));
41
53
  } catch (error) {
42
54
  return { status: 'unknown', reason: `원장 읽기 실패 · ${error instanceof Error ? error.message : String(error)}` };
43
55
  }
package/src/index.ts CHANGED
@@ -44,7 +44,6 @@ import { applyTestFlagFromArgv, observeTestFlagOwnership, uncoveredTestFlagPaths
44
44
  import { registerPtyTakeoverCommands } from './cli/pty-takeover-cli.js';
45
45
  import { registerPtyRecordCommand } from './cli/pty-record-cli.js';
46
46
  import { registerLeaderCommands } from './cli/leader-cli.js';
47
- import { registerPrCommands } from './cli/pr-cli.js';
48
47
  import { registerRepoCommands } from './cli/repo-cli.js';
49
48
  import { registerAgentCommands, runChatTurnCli, emitDetachedProgress } from './cli/agent-cli.js';
50
49
  export { runChatTurnCli, buildCliAgentTools, setCliAgentDispatchForTesting, emitDetachedProgress, emitHarnessFeedbackProgress } from './cli/agent-cli.js';
@@ -916,7 +915,114 @@ async function runDevSayFromWords(
916
915
 
917
916
  registerPtyTakeoverCommands(program);
918
917
  registerPtyRecordCommand(program.commands.find((command) => command.name() === 'pty')!);
919
- registerPrCommands(program);
918
+ // Keep the public PR help slot but defer its large CI/landing import graph
919
+ // until the PR command is actually selected (including direct Commander use).
920
+ const prCommandOrder = program.commands.length;
921
+ const prShell = program.command('pr').description('PR landing commands');
922
+ // The exported Commander tree is also the public entrance inventory. Keep its
923
+ // lightweight declarations visible without importing the CI/landing graph.
924
+ prShell.command('supersede-drafts').description('확인된 병합 PR의 명시 Supersedes 같은 칸 draft만 정리')
925
+ .requiredOption('--pr <number>', '병합 PR 번호')
926
+ .option('--cwd <path>', '저장소 경로');
927
+ prShell.command('census').description('열린 PR 전체·골 문서만·2일 무커밋 draft·미닫힌 superseded 집계').option('--cwd <path>', '저장소 경로');
928
+ prShell.command('open-guard').description('새 PR 전에 같은 파일 OPEN PR·골 문서만·자리별 상한 검사')
929
+ .option('--cwd <path>', '작업 트리 경로').option('--base <ref>', '비교 base ref', 'origin/main')
930
+ .option('--seat <seat>', 'PR 소유 자리(OP|TC|MK|UX)').option('--cell <id>', '릴리스 칸 id (같은 칸 OPEN PR 검사)')
931
+ .option('--seat-cap <number>', '자리별 열린 PR 경고 상한', '30');
932
+ const prQueueShell = prShell.command('queue').description('Shadow merge queue (never lands PRs)');
933
+ prQueueShell.command('status').description('Show pending PRs and shadow verdicts');
934
+ prQueueShell.command('enqueue <pr>').description('Pin a ready PR at the tail of the shadow queue');
935
+ prQueueShell.command('run').description('Evaluate the first PR without merging').requiredOption('--shadow', 'Only evaluate; never land');
936
+ prShell.command('land').description('현재 브랜치 PR을 생성 또는 갱신해 ready 상태로 만들고 squash merge')
937
+ .option('--base <branch>', 'PR base branch').option('--cwd <path>', '작업 트리 경로')
938
+ .option('--pr <number>', '기존 PR 번호 고정 (--expected-head 와 함께)')
939
+ .option('--expected-head <sha>', '리뷰된 PR 머리 SHA 고정 (--pr 와 함께)')
940
+ .option('--heavy-remote', '머리 고정 착지의 무거운 게이트를 node-b·node-c 중 빈 호스트에서 실행; head⊕main 증거가 없거나 실패하면 거부(로컬 폴백 없음)')
941
+ .option('--heavy-on-pod-shadow', '--heavy-remote 판정을 유지하고 같은 head/main의 Pod 타입·변경 시험 결과를 비교만 한다')
942
+ .option('--dry-run', '변경 없이 landing 계획만 출력').option('--hold', 'PR을 생성 또는 갱신한 뒤 병합하지 않고 쌓아 둔다')
943
+ .option('--title <title>', 'PR title').option('--title-file <path>', 'PR title file')
944
+ .option('--body <body>', 'PR body').option('--body-file <path>', 'PR body file')
945
+ .option('--commit-message <message>', 'upsert commit message')
946
+ .option('--commit-message-file <path>', 'upsert commit message file (takes precedence over --commit-message)')
947
+ .option('--include-active-run-files', '도는 런 파일을 이번 착지에 포함 (기본 동작)')
948
+ .option('--exclude-active-run-files', '도는 런과 겹친 파일을 이번 착지에서 제외')
949
+ .option('--exclude-active-run-sources', '⚠ 위험: --exclude-active-run-files 가 골 문서가 아닌 파일(소스)을 빼도 착지를 강행')
950
+ .option('--land-reason <text>', '권고를 보고도 지금 내는 이유(예: 남이 기다리는 차단 해제)')
951
+ .option('--force-freeze <reason>', '동결을 넘겨 병합할 명시적 이유(필수)')
952
+ .option('--allow-public-leak', '바뀐 파일이 공개본에 사적 흔적을 실어도 착지(이유는 --land-reason)')
953
+ .option('--overlap-evidence <file>', '머리 고정 착지 전용: 비대화형 겹침 승인을 대신할 증거 JSON {pr, head, gate:{head,baseCommit,passed}, reviewResult} — 재기반·재게이트·리뷰를 CLI 가 다시 잰다(겹친 착지가 전부 머리의 조상이면 리뷰만 · gate 생략 가능)');
954
+ prShell.command('granularity').description('로컬 git log 로 최근 착지 단위(파일 중복·단일 파일 비율)를 센다')
955
+ .option('--since <window>', 'git log --since 창', '1 day ago')
956
+ .option('--cwd <path>', '작업 트리 경로').option('--base <branch>', '착지 집계에 쓸 base 브랜치')
957
+ .option('--with-source', 'PR 번호로 브랜치를 조회해 하니스↔사람 갈래를 함께 낸다 (gh 필요)');
958
+ const parseBeforePrRegistration = program.parse.bind(program);
959
+ const parseAsyncBeforePrRegistration = program.parseAsync.bind(program);
960
+ let prRegistered = false;
961
+ function ensurePrRegistered(): void {
962
+ if (prRegistered) return;
963
+ const { registerPrCommands } = require('./cli/pr-cli.js') as typeof import('./cli/pr-cli.js');
964
+ // Commander exposes this array as readonly in types, while registration still mutates it at runtime.
965
+ const commands = program.commands as Command[];
966
+ commands.splice(prCommandOrder, 1);
967
+ registerPrCommands(program);
968
+ const registered = commands.pop()!;
969
+ commands.splice(prCommandOrder, 0, registered);
970
+ prRegistered = true;
971
+ }
972
+ // Consumers may hold a reference to the exported PR subtree and parse that
973
+ // command directly, bypassing program.parse. Keep those references executable
974
+ // without loading the PR registrar until a direct parse actually occurs.
975
+ function deferPrSubtreeParse(shell: Command, path: number[] = []): void {
976
+ const selected = () => {
977
+ ensurePrRegistered();
978
+ let command = program.commands[prCommandOrder]!;
979
+ for (const index of path) command = command.commands[index]!;
980
+ return command;
981
+ };
982
+ shell.parse = (...args: Parameters<Command['parse']>) => selected().parse(...args);
983
+ shell.parseAsync = (...args: Parameters<Command['parseAsync']>) => selected().parseAsync(...args);
984
+ shell.commands.forEach((child, index) => deferPrSubtreeParse(child, [...path, index]));
985
+ }
986
+ deferPrSubtreeParse(prShell);
987
+ function selectedRootArgs(argv: readonly string[] | undefined, from?: string): { command: string | undefined; next: string | undefined; rootHelp: boolean } {
988
+ const args = (argv ?? process.argv).slice(from === 'user' ? 0 : from === 'electron' ? 1 : 2);
989
+ // parseOptions() emits Commander option events, so do not run it before the
990
+ // real parse. Only inspect leading root options; a subcommand owns the rest.
991
+ let position = 0;
992
+ let rootHelp = args.length === 0;
993
+ while (position < args.length) {
994
+ const token = args[position];
995
+ if (token === '--') { position++; break; }
996
+ if (token === '--help' || token === '-h' || token === '--help-all') {
997
+ rootHelp = true;
998
+ position++;
999
+ continue;
1000
+ }
1001
+ const option = program.options.find((item) => token === item.long || token === item.short
1002
+ || (item.long && token.startsWith(`${item.long}=`)));
1003
+ if (!option) {
1004
+ if (token.startsWith('-')) { position++; continue; }
1005
+ break;
1006
+ }
1007
+ position++;
1008
+ if (option.required && !token.includes('=')) position++;
1009
+ else if (option.optional && position < args.length && !args[position].startsWith('-')) position++;
1010
+ }
1011
+ return { command: args[position], next: args[position + 1], rootHelp };
1012
+ }
1013
+ function prSelectedForParse(argv: readonly string[] | undefined, from?: string): boolean {
1014
+ const { command, next, rootHelp } = selectedRootArgs(argv, from);
1015
+ return command === 'pr' || (command === 'help' && (!next || next === 'pr'))
1016
+ || (!command && rootHelp);
1017
+ }
1018
+ program.parse = (...args: Parameters<typeof program.parse>) => {
1019
+ if (prSelectedForParse(args[0], args[1]?.from)) ensurePrRegistered();
1020
+ return parseBeforePrRegistration(...args);
1021
+ };
1022
+ program.parseAsync = (...args: Parameters<typeof program.parseAsync>) => {
1023
+ if (prSelectedForParse(args[0], args[1]?.from)) ensurePrRegistered();
1024
+ return parseAsyncBeforePrRegistration(...args);
1025
+ };
920
1026
  registerRepoCommands(program);
921
1027
  registerRoleCommands(program);
922
1028
  registerMachineCommands(program);
@@ -4370,7 +4476,7 @@ selfCmd
4370
4476
  }
4371
4477
  };
4372
4478
  try {
4373
- const { dispatchHeavyCheck } = await import('./self-implement/gate-remote.js');
4479
+ const { dispatchHeavyCheck, remoteSelfGateArgv } = await import('./self-implement/gate-remote.js');
4374
4480
  const { runGitCommand } = await import('./git-fs/runner.js');
4375
4481
  const topLevel = runGitCommand(process.cwd(), ['rev-parse', '--show-toplevel'], { encoding: 'utf8' });
4376
4482
  if (topLevel.status !== 0) throw new Error(`git rev-parse --show-toplevel failed: ${topLevel.stderr.trim() || `rc=${topLevel.status}`}`);
@@ -4389,13 +4495,13 @@ selfCmd
4389
4495
  const { remoteCommitSupportsArtifactDir, newRemoteArtifactDir } = await import('./self-implement/gate-artifacts.js');
4390
4496
  remoteArtifacts = remoteCommitSupportsArtifactDir(repo) ? { dir: newRemoteArtifactDir() } : { unsupported: true };
4391
4497
  }
4392
- const remoteArtifactArgs = remoteArtifacts && 'dir' in remoteArtifacts ? ['--artifact-dir', remoteArtifacts.dir] : [];
4393
4498
  // origin/main is pinned to this machine's origin/main on the host; any other base is passed as its resolved sha.
4394
- const remoteArgv = (sha: (ref: string) => string) => ['bun', 'bin/elanous.mjs', 'self', 'gate', '--local', ...(opts.changed ? ['--changed'] : []),
4395
- ...(opts.base ? ['--base', opts.base === 'origin/main' ? opts.base : sha(opts.base)] : []), ...(shards !== undefined ? ['--shards', String(shards)] : []),
4499
+ const remoteArgv = (sha: (ref: string) => string) => remoteSelfGateArgv({
4500
+ changed: opts.changed, base: opts.base, shards, fixedShardDistribution: opts.fixedShardDistribution,
4501
+ includeImporters: opts.includeImporters,
4396
4502
  // A measured commit without this option rejects it (exit ≠ 0) — read as not passed, never as a silent measured run.
4397
- ...(opts.fixedShardDistribution ? ['--fixed-shard-distribution'] : []),
4398
- ...(opts.includeImporters ? ['--include-importers'] : []), ...remoteArtifactArgs];
4503
+ artifactDir: remoteArtifacts && 'dir' in remoteArtifacts ? remoteArtifacts.dir : undefined,
4504
+ }, sha);
4399
4505
  const { gateHostReservationRoot } = await import('./release-loop/gate-host-reservation.js');
4400
4506
  process.exitCode = await dispatchHeavyCheck({
4401
4507
  tool: 'self-gate', repo, installPwa: true, remoteArgv, refs: opts.base ? [opts.base] : [], reservationRoot: gateHostReservationRoot(),
@@ -4940,6 +5046,22 @@ const selfOrchestrateCmd = selfCmd
4940
5046
  const grokKeyNames = ['XAI_API_KEY', 'GROK_API_KEY', 'GROK_CODE_XAI_API_KEY'];
4941
5047
  // 명시 계정은 사람의 선택 — 공급자 폴백과 계정 브로커를 우회한다.
4942
5048
  const explicitPodAccount = (opts as { podAccount?: string }).podAccount;
5049
+ const ownerMirrorAccount = process.env.ELANOUS_REMOTE_CODEX_ACCOUNT?.trim();
5050
+ const childProvider = opts as { childLlmProvider?: string };
5051
+ const requestedChildProvider = childProvider.childLlmProvider?.trim();
5052
+ if (ownerMirrorAccount && explicitPodAccount && explicitPodAccount !== ownerMirrorAccount) {
5053
+ ui.error(`pod: HQ 미러 계정은 ${ownerMirrorAccount} 인데 --pod-account ${explicitPodAccount} 을 사용할 수 없다`);
5054
+ process.exit(2);
5055
+ }
5056
+ if (ownerMirrorAccount && requestedChildProvider && requestedChildProvider !== 'openai-codex') {
5057
+ const reason = `pod: HQ 미러 계정 ${ownerMirrorAccount} 은 openai-codex 전용이라 --child-llm-provider ${requestedChildProvider} 을 사용할 수 없다`;
5058
+ ui.error(reason);
5059
+ debug.log('self-implement.pod', 'child-provider-refused', { provider: requestedChildProvider, reason });
5060
+ process.exit(2);
5061
+ }
5062
+ // An owner mirror pins the Pod child to that access-only Codex account; do not let a configured
5063
+ // podChildDefault route the child to an unrelated provider.
5064
+ if (ownerMirrorAccount && !requestedChildProvider) childProvider.childLlmProvider = 'openai-codex';
4943
5065
  let accountBroker: (() => string) | undefined;
4944
5066
  let rotationAccounts: readonly string[] | undefined;
4945
5067
  let podProvider: import('./task-orchestrator/surfaces/pod-child-providers.js').PodChildProvider = 'openai-codex';
@@ -5031,7 +5153,8 @@ const selfOrchestrateCmd = selfCmd
5031
5153
  }
5032
5154
  }
5033
5155
  // 10-05 PODPROVIDER: a launch that named the child provider gets it, or is refused — never a silent codex.
5034
- const namedChild = (opts as { childLlmProvider?: string }).childLlmProvider?.trim();
5156
+ const explicitChild = (opts as { childLlmProvider?: string }).childLlmProvider?.trim();
5157
+ const namedChild = ownerMirrorAccount && !explicitChild ? 'openai-codex' : explicitChild;
5035
5158
  const { podNamedChildProvider, podFallbackCredentials, podGrokSubscriptionUsable: namedGrokUsable } = await import('./task-orchestrator/surfaces/self-implement-pod.js');
5036
5159
  const { readFileSync: readPodKeyFile } = await import('node:fs');
5037
5160
  const { homedir: podHome } = await import('node:os');
@@ -5051,12 +5174,27 @@ const selfOrchestrateCmd = selfCmd
5051
5174
  if (namedChildDecision.refuse) { ui.error(namedChildDecision.refuse); debug.log('self-implement.pod', 'child-provider-refused', { provider: namedChild, reason: namedChildDecision.refuse }); process.exit(2); }
5052
5175
  // A named codex child must stay codex — the plan may not fall back to grok (post-review must-fix).
5053
5176
  const namedCodex = namedChildDecision.provider === 'openai-codex';
5177
+ let planCandidates = inspectCodexRotation().candidates;
5178
+ if (ownerMirrorAccount) {
5179
+ const used = process.env.ELANOUS_REMOTE_CODEX_USED_PERCENT;
5180
+ const parsedUsed = used && used !== 'unknown' ? Number(used) : undefined;
5181
+ const threshold = Number(process.env.ELANOUS_REMOTE_CODEX_THRESHOLD_PERCENT);
5182
+ if (!Number.isFinite(threshold) || threshold <= 0 || threshold > 100) {
5183
+ ui.error('pod: HQ Codex 미러의 유효 임계 표지가 없어 발사를 거부한다');
5184
+ process.exit(2);
5185
+ }
5186
+ const { ownerCodexMirrorCandidate } = await import('./task-orchestrator/surfaces/pod-account-broker.js');
5187
+ planCandidates = ownerCodexMirrorCandidate(planCandidates, ownerMirrorAccount, parsedUsed !== undefined && Number.isFinite(parsedUsed) ? parsedUsed : undefined);
5188
+ if (planCandidates.length === 0) { ui.error(`pod: HQ Codex 미러 계정 ${ownerMirrorAccount} 이 원격 auth-store 후보에 없다`); process.exit(2); }
5189
+ }
5054
5190
  const plan: import('./task-orchestrator/surfaces/pod-account-broker.js').PodProviderPlan | null = namedChildDecision.provider === 'openrouter' || namedChildDecision.provider === 'anthropic' || namedChildDecision.provider === 'bedrock' || namedChildDecision.provider === 'glm' ? null : namedChildDecision.provider === 'grok'
5055
5191
  ? { provider: 'grok', excluded: [], grokSubscriptionEligible: credential?.kind === 'subscription' }
5056
5192
  : planPodProvider({
5057
- codexCandidates: inspectCodexRotation().candidates,
5193
+ codexCandidates: planCandidates,
5058
5194
  // Per-account caps (대표 default:97) override the Pod default cap — without them default was dropped at 60%.
5059
- thresholdPercentByAccount: launchPolicy.llm?.codexAccountRotationThresholdPercentByAccount,
5195
+ thresholdPercentByAccount: ownerMirrorAccount
5196
+ ? { [ownerMirrorAccount]: Number(process.env.ELANOUS_REMOTE_CODEX_THRESHOLD_PERCENT) }
5197
+ : launchPolicy.llm?.codexAccountRotationThresholdPercentByAccount,
5060
5198
  // 대표 한도 정책 한 값(`llm.codexQuotaPolicy`) — 크레딧·폴백을 같이 정한다.
5061
5199
  creditsAllowed: codexPolicyAllowsCredits(quotaPolicy),
5062
5200
  // SUBSCRIPTION-EXHAUST-REROUTE — 예비분 이하 잔액(«알려진» 값)의 계정은 크레딧으로 쓰지 않는다.
@@ -5759,7 +5897,8 @@ selfCmd
5759
5897
  .option('--context-text <text>', '리뷰어가 함께 판단할 텍스트(반복 가능)', (value: string, previous: string[] = []) => [...previous, value])
5760
5898
  .option('--json', '구조화 출력 {pr, verdict, mustFix, shouldFix, reviewed}')
5761
5899
  .option('--save <name>', '리뷰 결과를 상태 디렉터리의 review-results/<name>-<PR>-<head12>.json에 저장')
5762
- .action(async (prParts: string[], opts: { intent?: string; model?: string; acp?: boolean; acpModel?: string; acpBackend?: string; acpTimeout?: string; context?: string[]; contextText?: string[]; json?: boolean; save?: string }) => {
5900
+ .option('--over-cap-reason <reason>', '저장 리뷰 r5 상한 이후 이번 호출 1회 예외 사유(doctor.review cap-override 기록)')
5901
+ .action(async (prParts: string[], opts: { intent?: string; model?: string; acp?: boolean; acpModel?: string; acpBackend?: string; acpTimeout?: string; context?: string[]; contextText?: string[]; json?: boolean; save?: string; overCapReason?: string }) => {
5763
5902
  const prArgs = prParts.flatMap((p) => String(p).split(/[,\s]+/).filter(Boolean)); // 번호/#번호/URL·콤마목록.
5764
5903
  if (!prArgs.length) { ui.error('PR 필요: elanous self review <번호|URL> [..]'); process.exit(2); }
5765
5904
  // ⭐ 본문은 seam(`runSelfReviewCliCommand`)에 있다 — 이 액션은 **의존 배선만** 한다.
@@ -5850,6 +5989,17 @@ selfCmd
5850
5989
  roleFallbackModel: () => (getOpenRouterApiKeyForReview()?.trim() ? ROLE_REVIEWER_FALLBACK_MODEL : undefined),
5851
5990
  registerSink: async (surface) => { await registerStandaloneLogSink(surface); },
5852
5991
  log: (event, data, o) => debug.log('self-review', event, data, o ?? {}),
5992
+ observeDoctorReview: (event, data, o) => debug.log('doctor.review', event, data, o ?? {}),
5993
+ loadDoctorReviewBrief: async ({ pr, head, title, body, changedFiles }) => {
5994
+ // MK's doctor module is a separate PR. Until it lands, keep the original intent and record brief-unavailable.
5995
+ const modulePath = './self-implement/review-round-brief.js';
5996
+ const { effectiveInstanceRoot } = await import('./instance/resolve.js');
5997
+ const doctor = await import(modulePath) as {
5998
+ loadReviewRoundBrief(input: { pr: number; head: string; title: string; body: string; changedFiles: string[]; reviewResultsDir: string }): unknown;
5999
+ renderReviewBriefIntentBlock(brief: unknown): string | null;
6000
+ };
6001
+ return doctor.renderReviewBriefIntentBlock(doctor.loadReviewRoundBrief({ pr, head, title, body, changedFiles, reviewResultsDir: _joinPath(effectiveInstanceRoot(), 'review-results') }));
6002
+ },
5853
6003
  info: (t) => ui.info(t),
5854
6004
  error: (t) => ui.error(t),
5855
6005
  print: (t) => console.log(t),
@@ -6175,6 +6325,36 @@ async function loadJevAccessOrExit(): Promise<import('./decide/jev.js').JevAcces
6175
6325
  registerIntakeCommands(program);
6176
6326
 
6177
6327
  registerLogsCommands(program);
6328
+ // Keep the sim command in its public slot until either CLI or direct Commander
6329
+ // parsing selects it (or asks for help). The domain registrar owns its definition.
6330
+ const simCommandOrder = program.commands.length;
6331
+ program.command('sim').description('격리 시나리오를 실행하고 화면·로그 기대값을 대조한다');
6332
+ const parseWithRegisteredCommands = program.parse.bind(program);
6333
+ const parseAsyncWithRegisteredCommands = program.parseAsync.bind(program);
6334
+ let simRegistered = false;
6335
+ function ensureSimRegistered(): void {
6336
+ if (simRegistered) return;
6337
+ const { registerSimCommands } = require('./cli/sim-cli.js') as typeof import('./cli/sim-cli.js');
6338
+ const commands = program.commands as Command[];
6339
+ commands.splice(simCommandOrder, 1);
6340
+ registerSimCommands(program);
6341
+ const registered = commands.pop()!;
6342
+ commands.splice(simCommandOrder, 0, registered);
6343
+ simRegistered = true;
6344
+ }
6345
+ function simSelectedForParse(argv: readonly string[] | undefined, from?: string): boolean {
6346
+ const { command, next, rootHelp } = selectedRootArgs(argv, from);
6347
+ return command === 'sim' || (command === 'help' && next === 'sim')
6348
+ || (!command && rootHelp);
6349
+ }
6350
+ program.parse = (...parseArgs: Parameters<typeof program.parse>) => {
6351
+ if (simSelectedForParse(parseArgs[0], parseArgs[1]?.from)) ensureSimRegistered();
6352
+ return parseWithRegisteredCommands(...parseArgs);
6353
+ };
6354
+ program.parseAsync = (...parseArgs: Parameters<typeof program.parseAsync>) => {
6355
+ if (simSelectedForParse(parseArgs[0], parseArgs[1]?.from)) ensureSimRegistered();
6356
+ return parseAsyncWithRegisteredCommands(...parseArgs);
6357
+ };
6178
6358
 
6179
6359
  // ── ad (marketing-ad pipeline entrance) ──
6180
6360
  /** ⛔ 「있다」와 「읽을 수 있는 파일이다」는 다른 값 — 디렉토리·권한 없는 파일을 실사로 읽지 않는다. */
@@ -11852,6 +12032,12 @@ async function main(): Promise<void> {
11852
12032
  return;
11853
12033
  }
11854
12034
  const showAll = args[0] === '--help-all';
12035
+ if (firstCommand === 'sim' || (firstCommand === 'help' && args[1] === 'sim') || showAll || firstCommand === '--help' || firstCommand === '-h') {
12036
+ await ensureSimRegistered();
12037
+ }
12038
+ // Maturity filtering mutates command visibility; register the final PR
12039
+ // object before filtering so replacing the placeholder cannot reveal it.
12040
+ if (prSelectedForParse(['node', 'elanous', ...args])) ensurePrRegistered();
11855
12041
  const role = getUserConfig().cli?.helpRole ?? 'owner';
11856
12042
  const { shown, hidden } = filterCliRootHelp(program.commands, role, showAll);
11857
12043
  debug.log('cli.maturity', 'help-filtered', { role, shown, hidden });
@@ -15,6 +15,11 @@
15
15
  // - ⏹ 정확히 `/stop`·`/esc` 인 글(TUI-STOP-INPUT-BYPASS · #68): 대기열을 «건너뛰고» 지금 턴의 ESC 중단 경로
16
16
  // (`requestStop` → 대시보드 escGate)를 바로 부른다. 대기 중인 일반 항목은 그대로·순서대로 남는다.
17
17
  // 턴이 없으면 아무것도 안 하고 `tui-stop-no-active-turn`(멈출 길이 없으면 `tui-stop-undelivered`)으로 던져 바깥 호출자(rc≠0)에게 알린다.
18
+ // - ⏹ 원시 pty 길(TUI-STOP-RAW-PTY): `pty text pty_<id> /stop --enter`·tmux 처럼 TUI 를 띄운 «PTY 자체»에 쓰면
19
+ // 이 라우터를 안 지나 stdin 으로 들어오고, 턴 중 typeahead 가 «대기(응답 뒤)»에 쌓았다(10-17 재점검).
20
+ // ⇒ 턴 중 스트리밍 리스너가 stdin «한 청크»가 정확히 `/stop⏎`·`/esc⏎` 이면 `routeRawPtyStop` 으로 같은 `routeStop` 을 부른다.
21
+ // 키보드는 한 키씩 오고 붙여넣기는 봉투에 싸이므로, 한 청크에 온 «글 한 줄 ⊕ Enter» 는 바깥 주입이다.
22
+ // 턴 밖·Enter 없음·그 밖의 글은 종전대로 키로 흐른다(관측 `path: 'raw-pty'` · 제어 IPC 는 `'control-ipc'`).
18
23
  //
19
24
  // ⚠️ herdr/tmux 처럼 «터미널 자체»에 쓰는 길은 키보드와 구별할 수 없다 — 이 라우터는
20
25
  // elanous 제어 IPC(`pty text`) 경로만 가른다.
@@ -40,11 +45,13 @@ export interface ExternalInputHost {
40
45
  requestStop?(): boolean;
41
46
  /** 외부 stop 의 결과 표지(채팅 로그 한 줄). */
42
47
  onExternalStop?(result: 'stopped' | 'no-turn' | 'failed'): void;
43
- /** 대기열이 바뀌었다 — 화면 표지를 다시 그린다. */
44
- onQueueChange?(pending: readonly ExternalInputItem[], event: 'queued' | 'delivered'): void;
48
+ /** 대기열의 현재 상태가 바뀌었다 — 화면 표지를 다시 그린다. */
49
+ onQueueChange?(pending: readonly ExternalInputItem[]): void;
45
50
  }
46
51
 
47
52
  export type ExternalInputRoute = 'passthrough' | 'submitted' | 'queued' | 'stopped';
53
+ /** 외부 stop 이 들어온 길 — 제어 IPC(`tui:<pid>` · 이 라우터) / 원시 pty(stdin 한 청크). */
54
+ export type ExternalStopPath = 'control-ipc' | 'raw-pty';
48
55
  export type ExternalInputDecision = 'passthrough' | 'submit-now' | 'queue' | 'reject';
49
56
 
50
57
  const EXTERNAL_INPUT_SOURCE: InputSourceRef = { kind: 'terminal', provider: 'pty' };
@@ -133,8 +140,8 @@ export function createExternalInputQueue(deps: ExternalInputQueueDeps = {}) {
133
140
  // 경고는 머리 항목 «하나»에 한 번 — 머리가 실제로 바뀔 때만 다시 경고할 수 있다(제출 실패로 남은 같은 머리는 유지).
134
141
  let staleTurnWarnedHead: ExternalInputItem | null = null;
135
142
 
136
- const notify = (event: 'queued' | 'delivered'): void => {
137
- try { host?.onQueueChange?.(pending, event); } catch { /* fail-soft — 표지 실패가 입력을 막지 않는다 */ }
143
+ const notify = (): void => {
144
+ try { host?.onQueueChange?.(pending); } catch { /* fail-soft — 표지 실패가 입력을 막지 않는다 */ }
138
145
  };
139
146
  const ensurePump = (): void => {
140
147
  if (pending.length > 0 && !stopPump) stopPump = schedule(pump, PUMP_MS);
@@ -163,20 +170,20 @@ export function createExternalInputQueue(deps: ExternalInputQueueDeps = {}) {
163
170
  if (!ok) { log('deliver-failed', { length: head.text.length, pending: pending.length }); return false; }
164
171
  pending = pending.slice(1);
165
172
  log('delivered', { length: head.text.length, waitedMs: now() - head.at, pending: pending.length });
166
- notify('delivered');
173
+ notify();
167
174
  ensurePump();
168
175
  return true;
169
176
  }
170
177
 
171
178
  /** ⏹ 외부 stop — 대기열을 건너뛰고 지금 턴의 escGate 로. 대기열은 건드리지 않는다. */
172
- function routeStop(h: ExternalInputHost, text: string): ExternalInputRoute {
179
+ function routeStop(h: ExternalInputHost, text: string, path: ExternalStopPath): ExternalInputRoute {
173
180
  let turnActive = false;
174
181
  try { turnActive = h.isTurnActive(); } catch { turnActive = false; }
175
182
  let stopped = false;
176
183
  if (turnActive && h.requestStop) {
177
184
  try { stopped = h.requestStop(); } catch { stopped = false; }
178
185
  }
179
- logInput('external-stop', { hadTurn: turnActive, stopped, command: text, pending: pending.length });
186
+ logInput('external-stop', { hadTurn: turnActive, stopped, command: text, pending: pending.length, path });
180
187
  const result = stopped ? 'stopped' : turnActive ? 'failed' : 'no-turn';
181
188
  try { h.onExternalStop?.(result); } catch { /* fail-soft */ }
182
189
  if (result === 'no-turn') throw new Error('tui-stop-no-active-turn');
@@ -189,6 +196,7 @@ export function createExternalInputQueue(deps: ExternalInputQueueDeps = {}) {
189
196
  host = next;
190
197
  log('host-registered', { pending: pending.length });
191
198
  ensurePump();
199
+ if (pending.length > 0) notify();
192
200
  return () => {
193
201
  if (host !== next) return;
194
202
  host = null;
@@ -200,7 +208,7 @@ export function createExternalInputQueue(deps: ExternalInputQueueDeps = {}) {
200
208
  // `pty key`(input-key)는 «키»다 — 공백·`j` 처럼 출력 가능한 키도 종전대로 넣는다.
201
209
  if (keyCommandDepth > 0) return 'passthrough';
202
210
  const line = parseExternalTextLine(chars);
203
- if (line && host && isExternalStopCommand(line.text)) return routeStop(host, line.text);
211
+ if (line && host && isExternalStopCommand(line.text)) return routeStop(host, line.text, 'control-ipc');
204
212
  let turnActive = false; let composer: string | undefined; let pendingKeys = false;
205
213
  if (host && line) {
206
214
  try { turnActive = host.isTurnActive(); composer = host.composerText(); pendingKeys = host.hasPendingKeys(); }
@@ -229,10 +237,26 @@ export function createExternalInputQueue(deps: ExternalInputQueueDeps = {}) {
229
237
  }
230
238
  pending = [...pending, { text: line!.text, at: now() }];
231
239
  log('route', { ...base, route: 'queued', pending: pending.length });
232
- notify('queued');
240
+ notify();
233
241
  ensurePump();
234
242
  return 'queued';
235
243
  },
244
+ /**
245
+ * ⏹ 원시 pty 길 — 턴 중 stdin «한 청크»가 정확히 `/stop⏎`·`/esc⏎` 이면 `routeStop` 으로 보내고 true(키로 흘리지 않는다).
246
+ * 턴 밖·호스트 없음·Enter 없음·그 밖의 글은 false — 호출측이 종전대로 키를 넣는다.
247
+ */
248
+ routeRawStop(chunk: string): boolean {
249
+ const h = host;
250
+ if (!h) return false;
251
+ const line = parseExternalTextLine(chunk);
252
+ if (!line?.submit || !isExternalStopCommand(line.text)) return false;
253
+ let turnActive = false;
254
+ try { turnActive = h.isTurnActive(); } catch { turnActive = false; }
255
+ if (!turnActive) return false;
256
+ // 'failed'(중단 경로 없음)도 소비한다 — 표지(Esc 로 멈춰 주세요)는 routeStop 이 이미 남겼다.
257
+ try { routeStop(h, line.text, 'raw-pty'); } catch { /* 결과는 이벤트·표지로 남았다 */ }
258
+ return true;
259
+ },
236
260
  pump,
237
261
  pending: (): readonly ExternalInputItem[] => pending,
238
262
  };
@@ -249,3 +273,4 @@ const shared = createExternalInputQueue();
249
273
 
250
274
  export function registerExternalInputHost(host: ExternalInputHost): () => void { return shared.register(host); }
251
275
  export function routeExternalInput(chars: string): ExternalInputRoute { return shared.route(chars); }
276
+ export function routeRawPtyStop(chunk: string): boolean { return shared.routeRawStop(chunk); }
@@ -0,0 +1,89 @@
1
+ // ── ALREADY-BUILT-HINT — «이미 있는 기능» 알림 원시함수 (UX · 0.2.34 칸) ──────────
2
+ //
3
+ // RFC-harness-full-journey-as-graph §4f 판정 — 다른 폴더의 «이미 있는 기능»을 새 요구로
4
+ // 넣으면 근거 링크(커밋·파일) 붙은 알림을 낸다 · 관련 없으면 0건 · 거절한 짝은 다시 묻지
5
+ // 않는다. 순수 함수·부수효과 0. 관련도 점수는 세션 검색의 trigram FTS5 원시함수
6
+ // (src/session/search-index.ts rankByTrigramFts — BM25, 낮을수록 관련도 높음)를 그대로
7
+ // 재사용한다. DEV-FEATURE-MAP 행을 넘겨 부르는 인테이크·저작 경로 배선(intake.hint
8
+ // 관측)은 다음 조각(남은 것)이다.
9
+
10
+ import { rankByTrigramFts, type RankedDoc, type RankResult } from '../session/search-index.js';
11
+ import { hashContent } from '../hasher.js';
12
+
13
+ /** DEV-FEATURE-MAP 한 행 — «이미 있는 기능» 후보. evidence 가 비면 그 행은 버린다(근거 없으면 침묵). */
14
+ export interface AlreadyBuiltFeature {
15
+ readonly devProject: string;
16
+ readonly feature: string;
17
+ readonly text: string;
18
+ readonly evidence: { readonly commit?: string; readonly file?: string };
19
+ }
20
+
21
+ /** 거절한 짝 — «요구 해시 ⊕ feature». 요구 해시는 hashContent(request)(sha256 hex). */
22
+ export interface AlreadyBuiltRefusedPair {
23
+ readonly requestHash: string;
24
+ readonly feature: string;
25
+ }
26
+
27
+ export type AlreadyBuiltHintKind = 'already' | 'similar';
28
+
29
+ /** A compact notification: one best match and at most two related matches. */
30
+ const MAX_ALREADY_BUILT_HINTS = 3;
31
+
32
+ /** 힌트 1건 — 근거 링크(커밋·파일) + BM25 점수(낮을수록 관련도 높음). */
33
+ export interface AlreadyBuiltHint {
34
+ readonly kind: AlreadyBuiltHintKind;
35
+ readonly devProject: string;
36
+ readonly feature: string;
37
+ readonly evidence: { readonly commit?: string; readonly file?: string };
38
+ readonly score: number;
39
+ }
40
+
41
+ /** 근거 유무 — commit·file 중 하나라도 실값(빈 문자열 제외)이면 근거 있음. */
42
+ function hasEvidence(evidence: AlreadyBuiltFeature['evidence']): boolean {
43
+ return (evidence.commit != null && evidence.commit !== '') || (evidence.file != null && evidence.file !== '');
44
+ }
45
+
46
+ /**
47
+ * 새 요구가 «이미 있는 기능»을 가리키는지 판정하는 순수 함수.
48
+ *
49
+ * - 후보의 배열 인덱스를 sessionId 로 사용해 rankByTrigramFts(request, docs) 로
50
+ * BM25 관련도 점수를 매긴다(재사용 · 낮을수록 높음).
51
+ * - evidence 가 비면 그 행은 버리고(근거 없으면 침묵) refused 짝(요구 해시 ⊕ feature)에
52
+ * 있는 행은 뺀다.
53
+ * - 매칭 행 중 관련도순 상위 3건만 내고, 첫 행(최고 관련도)은 kind='already',
54
+ * 그 뒤는 kind='similar'.
55
+ * - 관련 없는 요구·3자 미만 요구·FTS 오류·남는 후보 없음 → [] (출력 없음 = 침묵).
56
+ */
57
+ export function alreadyBuiltHints(
58
+ request: string,
59
+ features: readonly AlreadyBuiltFeature[],
60
+ refused: readonly AlreadyBuiltRefusedPair[],
61
+ ): AlreadyBuiltHint[] {
62
+ const requestHash = hashContent(request);
63
+ const candidates = features.filter((f) =>
64
+ hasEvidence(f.evidence)
65
+ && !refused.some((p) => p.requestHash === requestHash && p.feature === f.feature),
66
+ );
67
+ if (candidates.length === 0) return [];
68
+
69
+ const docs: RankedDoc[] = candidates.map((f, index) => ({
70
+ sessionId: String(index),
71
+ content: f.text,
72
+ }));
73
+ const ranked: RankResult[] | null = rankByTrigramFts(request, docs);
74
+ if (!ranked || ranked.length === 0) return []; // 관련 없는 요구 · <3자 · FTS 오류 → 침묵
75
+
76
+ const hints: AlreadyBuiltHint[] = [];
77
+ for (const r of ranked.slice(0, MAX_ALREADY_BUILT_HINTS)) {
78
+ const f = candidates[Number(r.sessionId)];
79
+ if (!f) continue;
80
+ hints.push({
81
+ kind: hints.length === 0 ? 'already' : 'similar',
82
+ devProject: f.devProject,
83
+ feature: f.feature,
84
+ evidence: { ...f.evidence },
85
+ score: r.score,
86
+ });
87
+ }
88
+ return hints;
89
+ }