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
@@ -20,14 +20,16 @@
20
20
  */
21
21
  import { lstatSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
22
22
  import type { ReviewRework } from '../../self-dev/run-types.js';
23
+ import type { WarmWorkerCommand } from './pod-warm-worker-protocol.js';
23
24
  import { oldDoorInternalEnv } from '../../self-dev/old-door.js';
24
25
  import { selfDevRunsDir } from '../../self-dev/run-store.js';
25
- import { debug } from '../../debug/log.js';
26
+ import { debug, redactSecretText } from '../../debug/log.js';
26
27
  import { join, resolve } from 'node:path';
27
28
  import { findGitDir } from '../../git-fs/locate.js';
28
29
  import { isAbandonedClassification, type AbandonedClassificationResult } from '../../self-implement/abandoned-classification.js';
29
30
  import { createExecution, type Task, type TaskExecution } from '../types.js';
30
31
  import type { DispatchContext, DispatchResult } from '../surface-registry.js';
32
+ import { nestedPodResult } from './pod-failure-reason.js';
31
33
 
32
34
  /** Result of one self-implement subprocess. */
33
35
  export interface SelfImplementJobDone {
@@ -92,6 +94,70 @@ export interface SelfImplementDisposition {
92
94
  reviewMustFixCount?: number;
93
95
  rework?: ReviewRework;
94
96
  mustFix?: string[];
97
+ /** Structured failure facts copied from the child's terminal JSON into the host ledger. */
98
+ childEvidence?: PodChildEvidence;
99
+ }
100
+
101
+ export interface PodChildEvidence {
102
+ /** Bounded, redacted diagnostics copied only from a failed child terminal result. */
103
+ error?: string;
104
+ detail?: string;
105
+ stderr?: string;
106
+ exitCode?: number;
107
+ classification?: string;
108
+ scopeEscape?: true;
109
+ outOfScopeEdits?: unknown;
110
+ abandonedClassification?: Record<string, unknown>;
111
+ supervisorVerdict?: unknown;
112
+ goalCauseObserved?: true;
113
+ terminationReason?: unknown;
114
+ accountAvailability?: Record<string, unknown>;
115
+ }
116
+
117
+ /** Preserve only named terminal facts; the full child detail may contain logs or credentials. */
118
+ export function podChildEvidenceFromResult(o: Record<string, unknown>): PodChildEvidence | undefined {
119
+ const object = (value: unknown): Record<string, unknown> | undefined =>
120
+ value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined;
121
+ const scrub = (value: Record<string, unknown> | undefined): Record<string, unknown> | undefined => {
122
+ if (!value) return undefined;
123
+ try { return JSON.parse(redactSecretText(JSON.stringify(value))) as Record<string, unknown>; }
124
+ catch { return undefined; }
125
+ };
126
+ const abandoned = scrub(object(o.abandonedClassification));
127
+ const quota = object(o.quotaExhaustionAssessment);
128
+ const accountAvailability = scrub(object(quota?.accountAvailability) ?? object(abandoned?.quotaAccountAvailability));
129
+ const scrubValue = (value: unknown): unknown => {
130
+ if (value === undefined) return undefined;
131
+ try { return JSON.parse(redactSecretText(JSON.stringify(value))); }
132
+ catch { return undefined; }
133
+ };
134
+ const failedText = (value: unknown): string | undefined => {
135
+ if (o.ok !== false || typeof value !== 'string' || !value.trim()) return undefined;
136
+ return redactSecretText(value).slice(0, 4_000);
137
+ };
138
+ const failureExitCode = o.ok === false && typeof o.exitCode === 'number'
139
+ && Number.isInteger(o.exitCode) && o.exitCode >= 0 && o.exitCode <= 255 ? o.exitCode : undefined;
140
+ const outOfScopeEdits = scrubValue(o.outOfScopeEdits);
141
+ const scopeEscape = (Array.isArray(outOfScopeEdits) && outOfScopeEdits.length > 0)
142
+ || (typeof o.detail === 'string' && /^Out-of-scope edits held in the worktree(?:[.;]|$)/i.test(o.detail.trim()));
143
+ const classification = scopeEscape ? 'scope-escape'
144
+ : typeof abandoned?.classification === 'string' ? redactSecretText(abandoned.classification)
145
+ : typeof o.failureClassification === 'string' ? redactSecretText(o.failureClassification) : undefined;
146
+ const evidence: PodChildEvidence = {
147
+ ...(failedText(o.error) ? { error: failedText(o.error) } : {}),
148
+ ...(failedText(o.detail) ? { detail: failedText(o.detail) } : {}),
149
+ ...(failedText(o.stderr) ? { stderr: failedText(o.stderr) } : {}),
150
+ ...(failureExitCode !== undefined ? { exitCode: failureExitCode } : {}),
151
+ ...(classification ? { classification } : {}),
152
+ ...(scopeEscape ? { scopeEscape: true } : {}),
153
+ ...(outOfScopeEdits !== undefined ? { outOfScopeEdits } : {}),
154
+ ...(abandoned ? { abandonedClassification: abandoned } : {}),
155
+ ...(o.supervisorVerdict !== undefined ? { supervisorVerdict: scrubValue(o.supervisorVerdict) } : {}),
156
+ ...(o.goalCauseObserved === true ? { goalCauseObserved: true } : {}),
157
+ ...(o.terminationReason !== undefined ? { terminationReason: scrubValue(o.terminationReason) } : {}),
158
+ ...(accountAvailability ? { accountAvailability } : {}),
159
+ };
160
+ return Object.keys(evidence).length ? evidence : undefined;
95
161
  }
96
162
 
97
163
  /**
@@ -117,6 +183,8 @@ export interface SelfImplementJobSpawn {
117
183
  /** Distinct-per-job harness-space id → own screen/log buffer. */
118
184
  spaceId: string;
119
185
  signal?: AbortSignal;
186
+ /** Optional TC-owned warm-worker command. The warm request is advisory; this feature Job remains authoritative. */
187
+ warmWorkerCommand?: WarmWorkerCommand;
120
188
  }): {
121
189
  /** `self-impl:<spaceId>` — keyed so `elanous logs --space` / metrics
122
190
  * can attribute without re-parsing. */
@@ -462,7 +530,18 @@ export function parseSelfImplementJson(stdout: string): SelfImplementDisposition
462
530
  const line = lines[i]!.trim();
463
531
  if (!line.startsWith('{') || !line.endsWith('}')) continue;
464
532
  try {
465
- const o = JSON.parse(line) as Record<string, unknown>;
533
+ const row = JSON.parse(line) as Record<string, unknown>;
534
+ if (typeof row.kind === 'string' && row.kind !== 'self' && row.kind !== 'external') continue;
535
+ const childKind = row.kind === 'self' || row.kind === 'external';
536
+ const nestedEnvelope = childKind && Object.prototype.hasOwnProperty.call(row, 'result');
537
+ let o = row;
538
+ let nestedSuccess = false;
539
+ if (nestedEnvelope) {
540
+ const terminal = nestedPodResult(row);
541
+ if (!terminal || !row.result || typeof row.result !== 'object' || Array.isArray(row.result)) continue;
542
+ o = { ...(row.result as Record<string, unknown>), stage: terminal.stage, ok: terminal.ok };
543
+ nestedSuccess = terminal.ok;
544
+ }
466
545
  if (typeof o.stage !== 'string' && typeof o.ok !== 'boolean') continue;
467
546
  const failureClassification = failureClassificationFromJson(o);
468
547
  const rawRework = o.rework && typeof o.rework === 'object' && !Array.isArray(o.rework)
@@ -475,6 +554,7 @@ export function parseSelfImplementJson(stdout: string): SelfImplementDisposition
475
554
  // A measured trend needs two reviews, a direction change three — a contradictory pair is not an observation.
476
555
  && (rawRework.trend === 'unmeasured' ? rawRework.rounds === 1 : rawRework.rounds >= (rawRework.trend === 'oscillating' ? 3 : 2))
477
556
  ? { trend: rawRework.trend as ReviewRework['trend'], signature: rawRework.signature, rounds: rawRework.rounds } : undefined;
557
+ const childEvidence = nestedSuccess ? undefined : podChildEvidenceFromResult(o);
478
558
  const mapped: SelfImplementDisposition = {
479
559
  ...(typeof o.stage === 'string' ? { stage: o.stage } : {}),
480
560
  ...(typeof o.ok === 'boolean' ? { ok: o.ok } : {}),
@@ -502,6 +582,7 @@ export function parseSelfImplementJson(stdout: string): SelfImplementDisposition
502
582
  ...(typeof o.completionDisposition === 'string' && o.completionDisposition.trim()
503
583
  ? { completionDisposition: o.completionDisposition } : {}),
504
584
  ...(failureClassification ? { failureClassification } : {}),
585
+ ...(childEvidence ? { childEvidence } : {}),
505
586
  ...(o.providerErrors && typeof o.providerErrors === 'object' && !Array.isArray(o.providerErrors)
506
587
  && typeof (o.providerErrors as Record<string, unknown>).count === 'number'
507
588
  && Number.isFinite((o.providerErrors as Record<string, unknown>).count)
@@ -6,6 +6,10 @@ import type { ChatToolOutputConfig } from '../user-config.js';
6
6
  function defaultToolResultsRoot(): string {
7
7
  return join(effectiveInstanceRoot(), 'tool-results');
8
8
  }
9
+ /** 넘침 파일 뿌리 — TUI 가 «넘침 파일 다시 읽기» 를 잡무로 접을 때 같은 뿌리로 판별한다(TUI-TURN-NARRATION FU-5). */
10
+ export function toolResultsRoot(): string {
11
+ return defaultToolResultsRoot();
12
+ }
9
13
  const SWEEP_INTERVAL_MS = 60 * 60 * 1000;
10
14
  const lastSweepAt = new Map<string, number>();
11
15
 
@@ -12,7 +12,7 @@
12
12
  // completion-line presentation. dashboard/execution-badge.ts is now a
13
13
  // re-export shim for backward compat until callers migrate.
14
14
 
15
- import { currentRouteDecision } from '../../llm/route-decision.js';
15
+ import { currentRouteDecision, routeFallbackLabel } from '../../llm/route-decision.js';
16
16
  import { getUserConfig } from '../../user-config.js';
17
17
  import { effectiveReasoningLevel, modelSupportsReasoning } from '../../llm.js';
18
18
  import { executionBadge } from '../../telegram-exec-footer.js';
@@ -24,6 +24,10 @@ import { executionBadge } from '../../telegram-exec-footer.js';
24
24
  * execution footer uses, so both surfaces report the same truth. */
25
25
  export function resolveDashboardExecutionBadge(): string | undefined {
26
26
  const cfg = getUserConfig();
27
+ // 폴백(TUI-MODEL-BADGE-ACTUAL · 10-16) — 턴이 고른 모델과 «실제로 응답한» 모델이 다르면 «sol → grok».
28
+ // 생각 깊이는 결정 쪽 값이라 넘어간 공급자엔 맞지 않는다 → 폴백 배지엔 안 붙인다.
29
+ const fallback = routeFallbackLabel('dashboard');
30
+ if (fallback) return executionBadge({ model: fallback });
27
31
  const decision = currentRouteDecision('dashboard');
28
32
  const model = decision?.model || cfg.llm.model;
29
33
  if (!model) return undefined;
@@ -0,0 +1,230 @@
1
+ // TUI-TYPING-LAG-OBS — 타이핑 지연을 «재는» 관측(#28063 이 «실물 불가» 로 착지한 빈칸).
2
+ //
3
+ // 계약(UX SCENARIO-MOCK-RIG 와 합의 · ⛔ 이름·칸을 바꾸지 않는다):
4
+ // debug.log('tui.input-lag', 'measured', {
5
+ // phase: 'keystroke' | 'turn-start', keyToPaintMs?, loopDelayMs: { p99, max }, turnId?, busy, sampled })
6
+ //
7
+ // - keystroke: stdin 키 수신 → 그 뒤 첫 화면 칠(render · typeahead echo) 의 write 호출까지.
8
+ // 이벤트 루프가 막힌 동안 온 키는 막힘이 풀린 뒤에야 'data' 로 배달되므로, 배달 시각만 보면
9
+ // 막힌 시간이 빠진다. ⇒ 20ms 심장박동으로 «배달 전 기다린 시간» 을 추정해 더한다(상한 추정 ·
10
+ // 오차 ≤ 심장박동 간격). 기본 표본 = 10키 중 1(`sampled: 0.1`) · 50ms 이상은 항상 남긴다.
11
+ // - turn-start: turn-preamble 을 감싼 창(시작 → 끝 + 박동 두 번)의 루프 지연(`sampled: 1`) · busy 는 창 끝 값.
12
+ // - loopDelayMs: 그 창의 루프 지연 p99/max(ms) — 같은 20ms 심장박동의 드리프트 표본(최근 ~20초 고리).
13
+ // ⚠️ perf_hooks.monitorEventLoopDelay 를 «안» 쓴다: Bun 1.4.2 에서 동작은 하지만 인스턴스들이
14
+ // «히스토그램 하나를 공유» 하고 한 인스턴스의 disable() 이 전부를 멈춘다(node-c 실측 · 라이브에서
15
+ // turn-start 창을 닫은 뒤 keystroke 창이 {p99:0,max:0} 만 찍었다). 창이 겹치는 이 프로브엔 못 쓴다.
16
+ //
17
+ // 키 경로 비용: 키 청크마다 시각 호출 1회 ⊕ 비교 몇 개 · 할당 0(대기 중 키는 숫자 둘로 쥔다).
18
+ // 화면 칠마다: 대기 키가 없으면 비교 1회. 로그 객체는 «남길 때만» 만든다.
19
+ // 프로브가 등록되지 않으면(대시보드 밖 · 시험) 모든 훅은 null 검사 한 번으로 끝난다.
20
+
21
+ export const INPUT_LAG_CATEGORY = 'tui.input-lag';
22
+ export const INPUT_LAG_EVENT = 'measured';
23
+ /** 표본 비율의 분모 — 측정한 키 N개 중 1개를 남긴다. */
24
+ export const INPUT_LAG_SAMPLE_EVERY = 10;
25
+ /** 이 ms 이상 걸린 키는 표본과 무관하게 항상 남긴다. */
26
+ export const INPUT_LAG_ALWAYS_MS = 50;
27
+ const HEARTBEAT_MS = 20;
28
+ /** 루프가 «안 막힌 채» 이만큼 지나도 칠이 없으면 그 키는 칠을 안 낳은 키(무시 키 등)로 보고 놓는다 —
29
+ * 안 그러면 한참 뒤 다른 칠이 그 키에 붙어 수 분짜리 가짜 지연이 찍힌다(라이브 실측 150,963ms). */
30
+ export const INPUT_LAG_ABANDON_MS = 1000;
31
+ /** 루프 지연 표본 고리 크기 — 20ms 박동이면 ~20초. */
32
+ const LOOP_RING = 1024;
33
+
34
+ export interface LoopDelayMs { p99: number; max: number }
35
+
36
+ export interface InputLagMeasured {
37
+ phase: 'keystroke' | 'turn-start';
38
+ keyToPaintMs?: number;
39
+ loopDelayMs: LoopDelayMs;
40
+ turnId?: string;
41
+ busy: boolean;
42
+ sampled: number;
43
+ }
44
+
45
+ interface TimerLike { unref?: () => void }
46
+
47
+ export interface InputLagProbeOptions {
48
+ log: (category: string, event: string, data: InputLagMeasured) => void;
49
+ isBusy: () => boolean;
50
+ now?: () => number;
51
+ sampleEvery?: number;
52
+ alwaysMs?: number;
53
+ heartbeatMs?: number;
54
+ setIntervalFn?: (fn: () => void, ms: number) => TimerLike;
55
+ clearIntervalFn?: (timer: TimerLike) => void;
56
+ setTimeoutFn?: (fn: () => void, ms: number) => TimerLike;
57
+ }
58
+
59
+ export interface InputLagProbe {
60
+ /** 키 `count` 개가 한 번에 도착했다(한 stdin 청크가 여러 키를 낳을 수 있다). */
61
+ noteKey(count?: number): void;
62
+ notePaint(): void;
63
+ measureTurnStart<T>(fn: () => T, turnId?: string): T;
64
+ /** 같은 심장박동을 다른 관측(턴 시작 덩어리 · `dashboard/turn-start-segments.ts`)이 읽는 창 — 시계·할당 0. */
65
+ beats: InputLagBeatView;
66
+ dispose(): void;
67
+ }
68
+
69
+ export interface InputLagBeatView {
70
+ heartbeatMs: number;
71
+ /** 마지막 박동 시각(같은 `now` 시계). */
72
+ lastBeatAt(): number;
73
+ /** `since` 뒤 박동들의 루프 지연 p99/max — 남길 때만 부른다. */
74
+ loopDelaySince(since: number): LoopDelayMs;
75
+ }
76
+
77
+ const round1 = (ms: number): number => Math.round(Math.max(0, ms) * 10) / 10;
78
+
79
+ /** 드리프트 표본 고리에서 `since` «뒤»(초과) 표본의 p99/max. 남길 때만 부른다(그때만 할당). */
80
+ function readLoopDelay(drift: Float64Array, at: Float64Array, count: number, head: number, since: number): LoopDelayMs {
81
+ const picked: number[] = [];
82
+ for (let i = 0; i < count; i++) {
83
+ const idx = (head - 1 - i + LOOP_RING) % LOOP_RING;
84
+ if (at[idx]! <= since) break;
85
+ picked.push(drift[idx]!);
86
+ }
87
+ if (picked.length === 0) return { p99: 0, max: 0 };
88
+ picked.sort((x, y) => x - y);
89
+ return {
90
+ // 최근순위(nearest-rank) p99 — 짧은 창([0, 300])에서도 큰 막힘을 내림으로 잃지 않는다.
91
+ p99: round1(picked[Math.max(0, Math.ceil(picked.length * 0.99) - 1)]!),
92
+ max: round1(picked[picked.length - 1]!),
93
+ };
94
+ }
95
+
96
+ export function createInputLagProbe(opts: InputLagProbeOptions): InputLagProbe {
97
+ const now = opts.now ?? (() => performance.now());
98
+ const sampleEvery = Math.max(1, Math.floor(opts.sampleEvery ?? INPUT_LAG_SAMPLE_EVERY));
99
+ const alwaysMs = opts.alwaysMs ?? INPUT_LAG_ALWAYS_MS;
100
+ const heartbeatMs = opts.heartbeatMs ?? HEARTBEAT_MS;
101
+ const setIntervalFn = opts.setIntervalFn ?? ((fn, ms) => setInterval(fn, ms));
102
+ const clearIntervalFn = opts.clearIntervalFn ?? ((t) => clearInterval(t as ReturnType<typeof setInterval>));
103
+ const setTimeoutFn = opts.setTimeoutFn ?? ((fn, ms) => setTimeout(fn, ms));
104
+
105
+ // 칠을 기다리는 첫 키(뒤따르는 키는 같은 칠을 기다리므로 첫 키가 최악값이다).
106
+ let pendingAt = -1;
107
+ let pendingWaitMs = 0;
108
+ // 심장박동 — 마지막 박동 시각 ⊕ 방금 끝난 막힘(같은 루프 회전에서 키가 배달되면 그만큼 기다렸다).
109
+ let lastBeatAt = now();
110
+ let stallMs = 0;
111
+ let stallEndedAt = -Infinity;
112
+ const ringDrift = new Float64Array(LOOP_RING);
113
+ const ringAt = new Float64Array(LOOP_RING);
114
+ let ringHead = 0;
115
+ let ringCount = 0;
116
+ let keyWindowStart = lastBeatAt;
117
+ const loopDelaySince = (since: number): LoopDelayMs => readLoopDelay(ringDrift, ringAt, ringCount, ringHead, since);
118
+ const beat = setIntervalFn(() => {
119
+ const t = now();
120
+ const drift = t - lastBeatAt - heartbeatMs;
121
+ ringDrift[ringHead] = Math.max(0, drift);
122
+ ringAt[ringHead] = t;
123
+ ringHead = (ringHead + 1) % LOOP_RING;
124
+ if (ringCount < LOOP_RING) ringCount += 1;
125
+ if (drift > heartbeatMs) { stallMs = drift; stallEndedAt = t; }
126
+ lastBeatAt = t;
127
+ if (pendingAt >= 0 && t - Math.max(pendingAt, stallEndedAt) > INPUT_LAG_ABANDON_MS) pendingAt = -1;
128
+ }, heartbeatMs);
129
+ beat.unref?.();
130
+
131
+ // 표본 줄 사이에 들어온 실제 키 수(측정 횟수가 아니다) — 표본 줄을 남기면 sampleEvery 의 나머지를 이월한다.
132
+ let keysSinceLine = 0;
133
+ let disposed = false;
134
+
135
+ return {
136
+ noteKey(count = 1): void {
137
+ if (disposed) return;
138
+ keysSinceLine += count;
139
+ if (pendingAt >= 0) return;
140
+ const t = now();
141
+ // 박동이 밀려 있으면 루프가 아직 막혀 있었다. 마지막 박동이 막힘을 끝낸 박동이면(그 뒤 평상 박동이
142
+ // 아직 없으면) 막힘 동안 쌓인 키가 이제 배달되는 중이다 — 막힘 ⊕ 그 뒤 흐른 시간(상한 추정).
143
+ const overdue = t - lastBeatAt - heartbeatMs;
144
+ const justStalled = stallEndedAt === lastBeatAt ? stallMs + (t - stallEndedAt) : 0;
145
+ pendingAt = t;
146
+ pendingWaitMs = Math.max(0, overdue, justStalled);
147
+ },
148
+ notePaint(): void {
149
+ if (pendingAt < 0) return;
150
+ const keyToPaintMs = now() - pendingAt + pendingWaitMs;
151
+ pendingAt = -1;
152
+ // 50ms↑ 강제 줄은 표본을 소비하지 않는다(표본이 때가 됐어도 다음 칠로 넘긴다) ·
153
+ // 표본 줄은 넘친 키를 다음 표본으로 이월한다.
154
+ const forced = keyToPaintMs >= alwaysMs;
155
+ if (!forced) {
156
+ if (keysSinceLine < sampleEvery) return;
157
+ keysSinceLine %= sampleEvery;
158
+ }
159
+ const t = now();
160
+ const loopDelayMs = loopDelaySince(keyWindowStart);
161
+ keyWindowStart = t;
162
+ opts.log(INPUT_LAG_CATEGORY, INPUT_LAG_EVENT, {
163
+ phase: 'keystroke',
164
+ keyToPaintMs: round1(keyToPaintMs),
165
+ loopDelayMs,
166
+ busy: opts.isBusy(),
167
+ sampled: 1 / sampleEvery,
168
+ });
169
+ },
170
+ measureTurnStart<T>(fn: () => T, turnId?: string): T {
171
+ if (disposed) return fn();
172
+ const windowStart = now();
173
+ const finish = (): void => {
174
+ // busy 는 창이 닫히는 «지금» 잡는다 — 박동 두 번 뒤 읽으면 그 사이 바뀐 상태가 창에 붙는다.
175
+ const busy = opts.isBusy();
176
+ // 동기 막힘은 루프가 풀린 «뒤» 첫 박동에 찍힌다 — 박동 두 번만큼 기다렸다 읽는다.
177
+ const timer = setTimeoutFn(() => {
178
+ if (disposed) return;
179
+ const loopDelayMs = loopDelaySince(windowStart);
180
+ opts.log(INPUT_LAG_CATEGORY, INPUT_LAG_EVENT, {
181
+ phase: 'turn-start',
182
+ loopDelayMs,
183
+ ...(turnId !== undefined ? { turnId } : {}),
184
+ busy,
185
+ sampled: 1,
186
+ });
187
+ }, heartbeatMs * 2);
188
+ timer.unref?.();
189
+ };
190
+ try {
191
+ return fn();
192
+ } finally {
193
+ finish();
194
+ }
195
+ },
196
+ beats: {
197
+ heartbeatMs,
198
+ lastBeatAt: () => lastBeatAt,
199
+ loopDelaySince,
200
+ },
201
+ dispose(): void {
202
+ if (disposed) return;
203
+ disposed = true;
204
+ pendingAt = -1;
205
+ clearIntervalFn(beat);
206
+ },
207
+ };
208
+ }
209
+
210
+ // ── 등록 자리 — 대시보드가 하나 등록하고, 저수준 훅(tui.ts · chat · turn-preamble)은 부르기만 한다. ──
211
+ let activeProbe: InputLagProbe | null = null;
212
+
213
+ export function setInputLagProbe(probe: InputLagProbe | null): void {
214
+ activeProbe = probe;
215
+ }
216
+
217
+ /** stdin(또는 주입) 키 `count` 개 수신 — 키 경로 훅. 등록이 없으면 null 검사 한 번. */
218
+ export function noteInputLagKey(count = 1): void {
219
+ activeProbe?.noteKey(count);
220
+ }
221
+
222
+ /** 화면 칠(write 호출) 직후 — 칠 경로 훅. */
223
+ export function noteInputLagPaint(): void {
224
+ activeProbe?.notePaint();
225
+ }
226
+
227
+ /** turn-preamble 창을 잰다. 등록이 없으면 fn 만 부른다. */
228
+ export function measureInputLagTurnStart<T>(fn: () => T, turnId?: string): T {
229
+ return activeProbe ? activeProbe.measureTurnStart(fn, turnId) : fn();
230
+ }
@@ -130,6 +130,9 @@ export interface DashboardSendRequest {
130
130
  * more per turn, provider-dependent). Shape matches
131
131
  * `StreamWithToolsHandlers.onUsage` modulo the correlation id. */
132
132
  onUsage?(usage: DashboardSessionUsage): void;
133
+ /** TUI-TURN-NARRATION — `agent_thought_chunk` ⊕ `_meta.reasoning: true`(추론 요약 문단).
134
+ * 전에는 usage 봉투가 아니면 버려서 화면에 0줄이었다(결함 #87). */
135
+ onThought?(text: string): void;
133
136
  }
134
137
 
135
138
  export interface DashboardSendResult {
@@ -550,6 +553,7 @@ function buildSendInterceptor(req: DashboardSendRequest): SessionUpdateIntercept
550
553
  rawInput?: unknown;
551
554
  rawOutput?: unknown;
552
555
  status?: string;
556
+ _meta?: { reasoning?: unknown };
553
557
  };
554
558
  };
555
559
  const inner = n.update;
@@ -582,8 +586,13 @@ function buildSendInterceptor(req: DashboardSendRequest): SessionUpdateIntercept
582
586
  return;
583
587
  }
584
588
  case 'agent_thought_chunk': {
585
- if (!req.onUsage || inner.content?.type !== 'text') return;
589
+ if (inner.content?.type !== 'text') return;
586
590
  const text = inner.content.text ?? '';
591
+ if (inner._meta?.reasoning === true) {
592
+ req.onThought?.(text);
593
+ return;
594
+ }
595
+ if (!req.onUsage) return;
587
596
  const env = parseElanousUiEnvelope(text);
588
597
  if (!env || env.method !== 'usage') return;
589
598
  const { id: _id, ...rest } = env.payload as unknown as ElanousUiUsagePayload;
package/src/tui.ts CHANGED
@@ -5,6 +5,7 @@
5
5
  import chalk from 'chalk';
6
6
  import { StringDecoder } from 'node:string_decoder';
7
7
  import { perf } from './perf-counters.js';
8
+ import { noteInputLagKey, noteInputLagPaint } from './tui/input-lag-probe.js';
8
9
  import { debug } from './debug/log.js';
9
10
 
10
11
  // ── ANSI escape sequences ──
@@ -911,6 +912,7 @@ export function readKey(source: KeyTraceSource = 'main'): Promise<Key> {
911
912
  // split across chunk boundaries need a pending buffer that belongs
912
913
  // to this stream alone.
913
914
  const keys = _stdinParser.push(data);
915
+ if (keys.length > 0) noteInputLagKey(keys.length);
914
916
 
915
917
  // 2026-04-30 — also drain `_keyQueue` here so an `injectKey`
916
918
  // call that happened while `readKey` was already awaiting on
@@ -963,6 +965,7 @@ export function readKey(source: KeyTraceSource = 'main'): Promise<Key> {
963
965
  * §8.6 — "(A) auto-Enter via injectKey" approach. */
964
966
  export function injectKey(key: Key): boolean {
965
967
  if (!_raw) return false;
968
+ noteInputLagKey();
966
969
  _keyQueue.push(key);
967
970
  _injectedKeys.add(key);
968
971
  // Wake any in-flight readKey awaiting on stdin by emitting an empty
@@ -1109,6 +1112,7 @@ export function render(lines: string[], opts: RenderOptions = {}): void {
1109
1112
  }
1110
1113
  perf.recordStdoutWrite(buf.length, true);
1111
1114
  perf.markDrawEnd();
1115
+ noteInputLagPaint();
1112
1116
 
1113
1117
  _lastFrameLines = lines.slice(0, lineCount);
1114
1118
  _lastFrameRows = rows;
@@ -0,0 +1,36 @@
1
+ export function clampNum(v: unknown, fallback: number, min: number, max: number): number {
2
+ if (typeof v !== 'number' || !Number.isFinite(v)) return fallback;
3
+ if (v < min) return min;
4
+ if (v > max) return max;
5
+ return v;
6
+ }
7
+
8
+ export function positiveIntOr(v: unknown, fallback: number): number {
9
+ return typeof v === 'number' && Number.isSafeInteger(v) && v > 0 ? v : fallback;
10
+ }
11
+
12
+ export function str(v: unknown): string | undefined {
13
+ return typeof v === 'string' && v.length > 0 ? v : undefined;
14
+ }
15
+
16
+ export function strArray(v: unknown, fallback: string[]): string[] {
17
+ if (!Array.isArray(v)) return fallback;
18
+ const out = v.filter((x): x is string => typeof x === 'string' && x.length > 0);
19
+ return out.length > 0 ? out : fallback;
20
+ }
21
+
22
+ export function stringRecord(v: unknown): Record<string, string> {
23
+ if (!v || typeof v !== 'object' || Array.isArray(v)) return {};
24
+ const out: Record<string, string> = {};
25
+ for (const [k, val] of Object.entries(v as Record<string, unknown>)) {
26
+ if (typeof k === 'string' && k.length > 0 && typeof val === 'string' && val.length > 0) {
27
+ out[k] = val;
28
+ }
29
+ }
30
+ return out;
31
+ }
32
+
33
+ export function numArray(v: unknown, fallback: number[]): number[] {
34
+ if (!Array.isArray(v)) return fallback;
35
+ return v.filter((x): x is number => typeof x === 'number' && Number.isFinite(x));
36
+ }
@@ -64,6 +64,8 @@ import {
64
64
  import { lookupLlmTierSpec } from './model-tier/llm-tier-map.js';
65
65
  import { BEDROCK_DEFAULT_MODEL } from './llm/bedrock.js';
66
66
  import { userConfigPath as nexusUserConfigPath } from './nexus/config/paths.js';
67
+ import { getElanousConfigDirOverride } from './elanous-config-dir.js';
68
+ import { getTestStateRoot } from './nexus/paths.js';
67
69
  import { type StreamingMode, isStreamingMode } from './session/streaming/stream-compositor.js';
68
70
  import type { DevRequestRoutingConfig } from './skills/dev-request-router.js';
69
71
  import type { UrlRoutingConfig } from './skills/url-router.js';
@@ -72,6 +74,7 @@ import { withFileLockSync } from './storage/file-lock.js';
72
74
  import { debug } from './debug/log.js';
73
75
  import { setConfigTimeZoneSource } from './time/format.js';
74
76
  import { parseGeminiServerTools } from './user-config/gemini-server-tools.js';
77
+ import { clampNum, numArray, positiveIntOr, str, strArray, stringRecord } from './user-config/coercion.js';
75
78
  import type { FoldMode } from './log-entry.js';
76
79
  import {
77
80
  CLAUDE_PACKAGE_MISSING,
@@ -3892,7 +3895,7 @@ export interface UserConfig {
3892
3895
  guardian?: { mode?: 'shadow' | 'live'; /** Orphan CLI GC on the guardian tick: off = no ps collection, shadow (default) = evidence only, on = evidence then SIGTERM. */ orphanGc?: 'off' | 'shadow' | 'on' };
3893
3896
  /** Task-agent live move allow-list (`src/task-agent/live-moves.ts` validates its vocabulary).
3894
3897
  * Absent = env ELANOUS_TASK_AGENT_LIVE_MOVES, else none (pure shadow). */
3895
- taskAgent?: { liveMoves?: string[]; /** TA-REJUDGE-PERIODIC — steward tick runs `tasks rejudge --all` every N minutes (absent/0 = off). */ rejudgeEveryMinutes?: number; /** 1-minute load average above which that tick is skipped (default 60). */ rejudgeMaxLoad?: number; /** TA-REPAIR-TICK-CAP — new repair launches per `tasks rejudge --all` (default 3, 0 = none). */ repairMaxPerTick?: number; /** TA-LAND-AFTER-REVIEW — opt-in external queue adapter, never a direct merge command. */ landQueue?: { command: string; remote: string }; parentHost?: { host?: string; cwd?: string; elanous?: string; configDir?: string; podPool?: string; approvalCapacity?: number } | Array<{ host?: string; cwd?: string; elanous?: string; configDir?: string; podPool?: string; approvalCapacity?: number }> };
3898
+ taskAgent?: { liveMoves?: string[]; /** TA-REJUDGE-PERIODIC — steward tick runs `tasks rejudge --all` every N minutes (absent/0 = off). */ rejudgeEveryMinutes?: number; /** 1-minute load average above which that tick is skipped (default 60). */ rejudgeMaxLoad?: number; /** TA-REPAIR-TICK-CAP — new repair launches per `tasks rejudge --all` (default 3, 0 = none). */ repairMaxPerTick?: number; /** Old cards are skipped by periodic rejudge after this many hours (default 72). */ rejudgeMaxAgeHours?: number; /** TA-LAND-AFTER-REVIEW — opt-in external queue adapter, never a direct merge command. */ landQueue?: { command: string; remote: string }; parentHost?: { host?: string; cwd?: string; elanous?: string; configDir?: string; podPool?: string; approvalCapacity?: number } | Array<{ host?: string; cwd?: string; elanous?: string; configDir?: string; podPool?: string; approvalCapacity?: number }> };
3896
3899
  events?: EventsConfig;
3897
3900
  /** GATE-REMOTE — see GateRemoteConfig. Absent = defaults (auto on · node-b · load 20 · cap 2). */
3898
3901
  gateRemote?: GateRemoteConfig;
@@ -4204,7 +4207,7 @@ function parseTaskAgentConfig(raw: unknown): UserConfig['taskAgent'] {
4204
4207
  }
4205
4208
  const parentHost = parseTaskAgentParentHost((raw as Record<string, unknown>).parentHost);
4206
4209
  // TA-REJUDGE-PERIODIC — 음이 아닌 유한수만 산다(0 = 끔). 그 밖은 경고하고 버린다(= 끔 · 기본 부하 상한).
4207
- const rejudge: { rejudgeEveryMinutes?: number; rejudgeMaxLoad?: number; repairMaxPerTick?: number } = {};
4210
+ const rejudge: { rejudgeEveryMinutes?: number; rejudgeMaxLoad?: number; repairMaxPerTick?: number; rejudgeMaxAgeHours?: number } = {};
4208
4211
  for (const key of ['rejudgeEveryMinutes', 'rejudgeMaxLoad'] as const) {
4209
4212
  const value = (raw as Record<string, unknown>)[key];
4210
4213
  if (value === undefined) continue;
@@ -4216,6 +4219,12 @@ function parseTaskAgentConfig(raw: unknown): UserConfig['taskAgent'] {
4216
4219
  if (Number.isSafeInteger(repairMaxPerTick) && (repairMaxPerTick as number) >= 0) rejudge.repairMaxPerTick = repairMaxPerTick as number;
4217
4220
  else warnUserConfigDrop('taskAgent.repairMaxPerTick', `음이 아닌 정수가 아니다(${JSON.stringify(repairMaxPerTick)}) — 기본 3`);
4218
4221
  }
4222
+ const rejudgeMaxAgeHours = (raw as Record<string, unknown>).rejudgeMaxAgeHours;
4223
+ if (rejudgeMaxAgeHours !== undefined) {
4224
+ if (typeof rejudgeMaxAgeHours === 'number' && Number.isFinite(rejudgeMaxAgeHours) && rejudgeMaxAgeHours > 0)
4225
+ rejudge.rejudgeMaxAgeHours = rejudgeMaxAgeHours;
4226
+ else warnUserConfigDrop('taskAgent.rejudgeMaxAgeHours', `양의 유한수가 아니다(${JSON.stringify(rejudgeMaxAgeHours)}) — 기본 72`);
4227
+ }
4219
4228
  const queueRaw = (raw as Record<string, unknown>).landQueue;
4220
4229
  let landQueue: { command: string; remote: string } | undefined;
4221
4230
  if (queueRaw !== undefined) {
@@ -4541,6 +4550,13 @@ function emitXdgDeprecationWarningOnce(xdgPath: string): void {
4541
4550
  }
4542
4551
 
4543
4552
  export function userConfigPath(): string {
4553
+ // An explicit CLI override or an isolated root selected by --test or a
4554
+ // parent stamp must not be shadowed by legacy XDG from a parent shell.
4555
+ // All state roots, including bun test's isolation root, outrank legacy XDG.
4556
+ // XDG-only callers have no selected state root (covered by a spawned CLI).
4557
+ if (getElanousConfigDirOverride() !== undefined || process.env.ELANOUS_STATE_DIR?.trim() || getTestStateRoot() !== undefined) {
4558
+ return nexusUserConfigPath();
4559
+ }
4544
4560
  const xdg = process.env.XDG_CONFIG_HOME?.trim();
4545
4561
  if (xdg) {
4546
4562
  const xdgPath = join(xdg, 'elanous', 'config.json');
@@ -6994,45 +7010,6 @@ export function markOnboardingComplete(cfg: UserConfig): UserConfig {
6994
7010
 
6995
7011
  export function currentOnboardingVersion(): number { return ONBOARDING_VERSION; }
6996
7012
 
6997
- // ── Coercion helpers ─────────────────────────────────────────────────
6998
-
6999
- function clampNum(v: unknown, fallback: number, min: number, max: number): number {
7000
- if (typeof v !== 'number' || !Number.isFinite(v)) return fallback;
7001
- if (v < min) return min;
7002
- if (v > max) return max;
7003
- return v;
7004
- }
7005
-
7006
- function positiveIntOr(v: unknown, fallback: number): number {
7007
- return typeof v === 'number' && Number.isSafeInteger(v) && v > 0 ? v : fallback;
7008
- }
7009
-
7010
- function str(v: unknown): string | undefined {
7011
- return typeof v === 'string' && v.length > 0 ? v : undefined;
7012
- }
7013
-
7014
- function strArray(v: unknown, fallback: string[]): string[] {
7015
- if (!Array.isArray(v)) return fallback;
7016
- const out = v.filter((x): x is string => typeof x === 'string' && x.length > 0);
7017
- return out.length > 0 ? out : fallback;
7018
- }
7019
-
7020
- function stringRecord(v: unknown): Record<string, string> {
7021
- if (!v || typeof v !== 'object' || Array.isArray(v)) return {};
7022
- const out: Record<string, string> = {};
7023
- for (const [k, val] of Object.entries(v as Record<string, unknown>)) {
7024
- if (typeof k === 'string' && k.length > 0 && typeof val === 'string' && val.length > 0) {
7025
- out[k] = val;
7026
- }
7027
- }
7028
- return out;
7029
- }
7030
-
7031
- function numArray(v: unknown, fallback: number[]): number[] {
7032
- if (!Array.isArray(v)) return fallback;
7033
- return v.filter((x): x is number => typeof x === 'number' && Number.isFinite(x));
7034
- }
7035
-
7036
7013
  function normalizeProvider(v: unknown): LLMProviderName {
7037
7014
  const allowed = CONFIG_LLM_PROVIDER_NAMES;
7038
7015
  if (typeof v === 'string' && (allowed as readonly string[]).includes(v)) {