elanous 0.2.43 → 0.2.44

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 (544) 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/{Om5xS9jpjSXJCeTNGYEi4 → HMXsxdy5MIIcHPMHv1wD4}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{3557ac4a.c8931684475018ad.js → 08334415.f0e80896acbef722.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1032-78ba4f6391258cab.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1082-53f86a26e03d309d.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1109-7d0e264f6f2edbc7.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1124-7c26330402481143.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/118.2a89982fe4276880.js +23 -0
  10. package/apps/pwa/out/_next/static/chunks/1244.6c435dbf1bf21d8a.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1252.9e665904d3aa3b1a.js +32 -0
  12. package/apps/pwa/out/_next/static/chunks/1266.a46cc33cb6a72d75.js +104 -0
  13. package/apps/pwa/out/_next/static/chunks/{3955.6922286237f2ac2b.js → 1306.967240ede9a0f757.js} +2 -2
  14. package/apps/pwa/out/_next/static/chunks/1344.3b95f3bd1b77a3fe.js +94 -0
  15. package/apps/pwa/out/_next/static/chunks/{5628.6ddb2d5ffba4ff4c.js → 1401.22dfe92640a2b1ac.js} +4 -4
  16. package/apps/pwa/out/_next/static/chunks/1431-f7c78bd5be21e011.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1451-cdd35a8a0b31834b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{2573.387a707f6f9d720c.js → 1694.18debfd77562e56d.js} +2 -2
  19. package/apps/pwa/out/_next/static/chunks/1708-f03d587b7a7545c8.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/1775-fa7152bdeff6c95f.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/178-4da509cd7266672a.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/{7910-6f139bcafd238b9f.js → 1850-522de4ee34957210.js} +1 -1
  23. package/apps/pwa/out/_next/static/chunks/1876-c6f6e0ddcc76c6a1.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/1976.097066b072432242.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/{1406.a1dc2ab6f8449374.js → 1978.eeb60a606dc5deac.js} +2 -2
  26. package/apps/pwa/out/_next/static/chunks/{3402.44b565b314f2263c.js → 2043.e233e3b5a3e790f5.js} +1 -1
  27. package/apps/pwa/out/_next/static/chunks/2150.71b94e3348107c83.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2158.ebc6fc5a10280ab7.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{3694.e0099884345f0198.js → 2216.802962c04f40a26e.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/2294.7890edcfa046c97d.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/235.c89aaae4bcd6233a.js +74 -0
  32. package/apps/pwa/out/_next/static/chunks/239.de075467b5523469.js +287 -0
  33. package/apps/pwa/out/_next/static/chunks/{1200.6a37c202f9f17e9a.js → 249.ba7051590d603c8f.js} +3 -3
  34. package/apps/pwa/out/_next/static/chunks/2571.a6ac4e26c8618403.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/2610.e149cd564a08913e.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/2705.9816f3c244f8b85f.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/2801.afeb8a4dae22f85f.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{3935.16701e33f8982dc9.js → 2954.bbefc95d6b20e0d8.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/{aa57532f.510551854ff239b1.js → 2e0f720a.a0697c08e3806a60.js} +1 -1
  40. package/apps/pwa/out/_next/static/chunks/3042.96ec235fe41c8d4e.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3097-8e358f158acef46b.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/3205-93b1abe28b4fb16a.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3273.b4434f0dcae7eb29.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/3311.9cbc43ea0c90d60c.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{5930.8b4df3b46c32b05a.js → 3349.b5f09ee474d9533e.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/{5866.366966af47fdde5d.js → 3503.a47a9755fb4d97b0.js} +1 -1
  47. package/apps/pwa/out/_next/static/chunks/3506-5f429b3b7e1392b0.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/{7900.096f455c7c1efc53.js → 3843.bad404d008893291.js} +2 -2
  49. package/apps/pwa/out/_next/static/chunks/3877-4b40e530b47e3bf9.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/435-ce2958253cf7de61.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/{8588.d1c6a2903727ce87.js → 4393.28fa5228d0eec217.js} +3 -3
  52. package/apps/pwa/out/_next/static/chunks/4404.7281c847c6e10dfc.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/{8062-7cd0bcc7f01455ba.js → 4415-b9d6a90960920a4a.js} +3 -3
  54. package/apps/pwa/out/_next/static/chunks/{8313-dfa1021bb58a46d6.js → 447-5b304de1fe098f43.js} +1 -1
  55. package/apps/pwa/out/_next/static/chunks/4484-8ebea83d431e6fae.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/{6944.309f4e3ea54d1537.js → 4502.bdcc877abd437a05.js} +1 -1
  57. package/apps/pwa/out/_next/static/chunks/4599-f95790fc5c65b8df.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/{3072.01338851ca21a6f7.js → 46.57c783fa4884714f.js} +2 -2
  59. package/apps/pwa/out/_next/static/chunks/463-b9114e411f33728e.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/4659.a57d1f0c5d754cd2.js +36 -0
  61. package/apps/pwa/out/_next/static/chunks/4722-a847e7a28115035f.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/{8986.8e2e4efbfa655c59.js → 4757.67c6d7473a038e78.js} +1 -1
  63. package/apps/pwa/out/_next/static/chunks/4874-c86f878ec4502ad3.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/4891.3f80ba517a3b2373.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/{8205.282ca4bb62d54a0a.js → 4998.810ca8833084caa9.js} +2 -2
  66. package/apps/pwa/out/_next/static/chunks/4f98febc.ea5841d4d616bfb2.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/{5789.2da35c258292e1e5.js → 5052.7dbb12a55d4f18f5.js} +1 -1
  68. package/apps/pwa/out/_next/static/chunks/5166-ca73b3e361085a6d.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/5180-039f4a18b07ad387.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/5232.5a2ce4daf7a9e11d.js +115 -0
  71. package/apps/pwa/out/_next/static/chunks/{9770.5f75bc6088b16109.js → 5439.3fec6dbce29ecb36.js} +1 -1
  72. package/apps/pwa/out/_next/static/chunks/{1313-19f737e0222c4444.js → 5612-074d9a5e00dfac6a.js} +1 -1
  73. package/apps/pwa/out/_next/static/chunks/5675-01989d524a84c505.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/5751.af641a1adf5ec697.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/5758-c6cb98714d18ab0c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/578eded8.b582637306e16964.js +122 -0
  77. package/apps/pwa/out/_next/static/chunks/{3969.272ee7f9fd6c62e5.js → 5790.5eb06a653ebd8571.js} +1 -1
  78. package/apps/pwa/out/_next/static/chunks/5853-4033e5bd5afbe06b.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/5904.97d70bb7f46b2db7.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/{6540.c7bef57ad8f90a87.js → 5989.7ecd362c5c44b747.js} +3 -3
  81. package/apps/pwa/out/_next/static/chunks/{0ad6802e.ae7afb63fdcb4491.js → 5a34fb2f.52f1b4e1baebb48a.js} +3 -3
  82. package/apps/pwa/out/_next/static/chunks/{0966f8a1.745fcd44f64a87ea.js → 5a5078f8.2099200e5ea95e16.js} +1 -1
  83. package/apps/pwa/out/_next/static/chunks/6036-c302c34ff0b3d410.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/606.ef81c313381f4264.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/616.1af54a928b1ba704.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/6201.bc936f71f613a8e9.js +41 -0
  87. package/apps/pwa/out/_next/static/chunks/6204-fdc86e0e64c4f92d.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/{2144.25b292396712196d.js → 6245.1182e007e9d230d9.js} +2 -2
  89. package/apps/pwa/out/_next/static/chunks/{363bfab3.9623b9f89363541f.js → 63699a35.17262e162bc514b2.js} +1 -1
  90. package/apps/pwa/out/_next/static/chunks/6420.494801a80030160c.js +27 -0
  91. package/apps/pwa/out/_next/static/chunks/{d96660fb.cbc21a2a88539dbb.js → 6549dad0.2740b25e51bf8f05.js} +7 -7
  92. package/apps/pwa/out/_next/static/chunks/{5564.9e72532188f57586.js → 6881.9e7955847640c7fe.js} +4 -4
  93. package/apps/pwa/out/_next/static/chunks/6931.fcdfb94141e67b3d.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/6991-8e081c6ce38c0ba1.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{3903.3ef4656c67572764.js → 7010.1bbd17a7f2b3e376.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/7029.d1466acf55fae2ed.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/7152-a123aa8e129c131f.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7455.196168fffac3b9c4.js +24 -0
  99. package/apps/pwa/out/_next/static/chunks/7638.6ca4770dd1129138.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/7649-f37d76260e5e2a5a.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/{2312.0c8b61e22d3136d7.js → 7679.32c40cdd14f20b4a.js} +1 -1
  102. package/apps/pwa/out/_next/static/chunks/7751.04bfbd16b4c6cd0a.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/7864.b1ff31d4030b8994.js +148 -0
  104. package/apps/pwa/out/_next/static/chunks/7869-c47bd2c075c1fefa.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{4199.ce86b281fd0a60b7.js → 8442.2f09ca969d631615.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/8445.2738dbd59a78c78c.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8447.5510c439f9938c6d.js +286 -0
  108. package/apps/pwa/out/_next/static/chunks/8551.f762945c2cda2e95.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/8635-57a9d8d9db70f4f1.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{fb7d20d5-6892502b6ee39ca6.js → 86961958-4b0689a5048f756b.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/8709.3c6019bb18f8554f.js +8 -0
  112. package/apps/pwa/out/_next/static/chunks/8759.c999528a0a907bf6.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/87f498e5-0881de09f2e44707.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/8843.c3197f904c952b81.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/{cb0f8df8.09a4a6be97e3fc5f.js → 892fd990.456232f326cc39c2.js} +1 -1
  116. package/apps/pwa/out/_next/static/chunks/{837-81336ebaca8198a8.js → 8965-135a2c9eaa2464cb.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/8971-8d3b9c96f8a6c958.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9059.c8598d96f8e5e9cd.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9115.90447ae198b84eae.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9147.d9b0a02e0babc9b4.js +93 -0
  121. package/apps/pwa/out/_next/static/chunks/9204-83075f4b70c61cdc.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9244-c32ef14b5dc72bdf.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/930.2a9a30f964350c66.js +90 -0
  124. package/apps/pwa/out/_next/static/chunks/{8637.90f92d5c8db4732c.js → 9398.1f56e3f17795f43f.js} +1 -1
  125. package/apps/pwa/out/_next/static/chunks/9527.3e5ad31c891c5fcb.js +79 -0
  126. package/apps/pwa/out/_next/static/chunks/9571-4ac933e774d1225c.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-9fc644de2d8edae3.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/approvals/page-0c9dace2db62bee8.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f5e65c3dc9d89f2a.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/board/page-2a9c19b9a140b7b1.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/botlab/page-61533ad92141adfb.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/bots/page-112004ced6fd0329.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/ceo/page-f733318c237a49d8.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/chat/page-51ea677d2d33bbc0.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/consult/page-428b41f2f9566e3c.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/control/page-1b29396ea90a61e5.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/decisions/page-cf83ec613ac904bf.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/design-check/page-3f4c0ecbc284bb5f.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/editor/page-b63c322f54f70cc6.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/exec/page-fe328c4ee9aac6b4.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/field/page-bfb855c584f0fb98.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/healthz/route-9fc644de2d8edae3.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/inside/page-47b1710c110eabd7.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/intake/page-42895214458bc6d2.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/layout-d03de0ebd8366e23.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/live/page-3ed6c47e4b1c61c2.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/live-run/page-ae653e9bf261c738.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/loops/page-23f3f0a0209c0ac4.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/market/page-88c691273aae66f9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e187ac52a95538b3.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/morning/page-6e45828daed1295e.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/not-found-edb5d7287bb46186.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/observatory/page-4a7eaacd93c3f6a5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ca073d43d74cc84.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1e9fee67b1199436.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-df1283ea963c6816.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/outputs/page-19fcf8d8301ccd18.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/page-5ab699e0303bbb40.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7cde0d29756984c5.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-9d4c598e8ee22f7a.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/sessions/page-cc1609a71f44ec62.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7659a9a1345bfaa9.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/settings/page-0afef60ecc0c4af5.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-a3553949f8f34f5f.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/setup/layout-9fc644de2d8edae3.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/setup/page-057a69702f3c67c7.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/share/page-c0f0e570f3f74c73.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/showroom/page-1825071ae34e3b89.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/tasks/page-6244e3e135d8ccfc.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/term/{page-0a815f34367b6db6.js → page-da787e8a10b8a82e.js} +1 -1
  171. package/apps/pwa/out/_next/static/chunks/app/today/page-1316d32498e2be42.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/trace/page-4df94572e343de2e.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/vault/page-708969f7475e88c1.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-c58add08c919a1dc.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/app/workflows/page-a24847f45e5d5bf9.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/app/workspace/page-acfec65a3a60e22e.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-3dfc598e6fbde245.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/framework-c658a626118411b7.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-4c73685fd891445b.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-6310f7e5de7dd01d.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-51c326bf48610be1.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-d0beadf754da59b0.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-acd243bfbf3f6732.js +1 -0
  184. package/apps/pwa/out/approvals/index.html +1 -1
  185. package/apps/pwa/out/approvals/index.txt +22 -22
  186. package/apps/pwa/out/autopilot/index.html +1 -1
  187. package/apps/pwa/out/autopilot/index.txt +22 -22
  188. package/apps/pwa/out/board/index.html +1 -1
  189. package/apps/pwa/out/board/index.txt +22 -22
  190. package/apps/pwa/out/botlab/index.html +1 -1
  191. package/apps/pwa/out/botlab/index.txt +21 -21
  192. package/apps/pwa/out/bots/index.html +1 -1
  193. package/apps/pwa/out/bots/index.txt +21 -21
  194. package/apps/pwa/out/ceo/index.html +1 -1
  195. package/apps/pwa/out/ceo/index.txt +22 -22
  196. package/apps/pwa/out/chat/index.html +1 -1
  197. package/apps/pwa/out/chat/index.txt +21 -21
  198. package/apps/pwa/out/consult/index.html +1 -1
  199. package/apps/pwa/out/consult/index.txt +22 -22
  200. package/apps/pwa/out/control/index.html +1 -1
  201. package/apps/pwa/out/control/index.txt +22 -22
  202. package/apps/pwa/out/decisions/index.html +1 -1
  203. package/apps/pwa/out/decisions/index.txt +21 -21
  204. package/apps/pwa/out/design-check/index.html +1 -1
  205. package/apps/pwa/out/design-check/index.txt +22 -22
  206. package/apps/pwa/out/editor/index.html +1 -1
  207. package/apps/pwa/out/editor/index.txt +22 -22
  208. package/apps/pwa/out/exec/index.html +1 -1
  209. package/apps/pwa/out/exec/index.txt +22 -22
  210. package/apps/pwa/out/field/index.html +1 -1
  211. package/apps/pwa/out/field/index.txt +22 -22
  212. package/apps/pwa/out/healthz +1 -1
  213. package/apps/pwa/out/index.html +1 -1
  214. package/apps/pwa/out/index.txt +21 -21
  215. package/apps/pwa/out/inside/index.html +1 -1
  216. package/apps/pwa/out/inside/index.txt +21 -21
  217. package/apps/pwa/out/intake/index.html +1 -1
  218. package/apps/pwa/out/intake/index.txt +22 -22
  219. package/apps/pwa/out/live/index.html +1 -1
  220. package/apps/pwa/out/live/index.txt +22 -22
  221. package/apps/pwa/out/live-run/index.html +1 -1
  222. package/apps/pwa/out/live-run/index.txt +22 -22
  223. package/apps/pwa/out/loops/index.html +1 -1
  224. package/apps/pwa/out/loops/index.txt +21 -21
  225. package/apps/pwa/out/market/index.html +1 -1
  226. package/apps/pwa/out/market/index.txt +21 -21
  227. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  228. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  229. package/apps/pwa/out/morning/index.html +1 -1
  230. package/apps/pwa/out/morning/index.txt +22 -22
  231. package/apps/pwa/out/observatory/index.html +1 -1
  232. package/apps/pwa/out/observatory/index.txt +22 -22
  233. package/apps/pwa/out/ops/checklist/index.html +1 -1
  234. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  235. package/apps/pwa/out/ops/release/index.html +1 -1
  236. package/apps/pwa/out/ops/release/index.txt +21 -21
  237. package/apps/pwa/out/ops/seats/index.html +1 -1
  238. package/apps/pwa/out/ops/seats/index.txt +21 -21
  239. package/apps/pwa/out/outputs/index.html +1 -1
  240. package/apps/pwa/out/outputs/index.txt +21 -21
  241. package/apps/pwa/out/reflection/index.html +1 -1
  242. package/apps/pwa/out/reflection/index.txt +22 -22
  243. package/apps/pwa/out/scheduler/index.html +1 -1
  244. package/apps/pwa/out/scheduler/index.txt +22 -22
  245. package/apps/pwa/out/sessions/index.html +1 -1
  246. package/apps/pwa/out/sessions/index.txt +21 -21
  247. package/apps/pwa/out/settings/devices/index.html +1 -1
  248. package/apps/pwa/out/settings/devices/index.txt +22 -22
  249. package/apps/pwa/out/settings/index.html +1 -1
  250. package/apps/pwa/out/settings/index.txt +22 -22
  251. package/apps/pwa/out/setup/done/index.html +1 -1
  252. package/apps/pwa/out/setup/done/index.txt +22 -22
  253. package/apps/pwa/out/setup/index.html +1 -1
  254. package/apps/pwa/out/setup/index.txt +22 -22
  255. package/apps/pwa/out/share/index.html +1 -1
  256. package/apps/pwa/out/share/index.txt +22 -22
  257. package/apps/pwa/out/showroom/index.html +1 -1
  258. package/apps/pwa/out/showroom/index.txt +21 -21
  259. package/apps/pwa/out/tasks/index.html +1 -1
  260. package/apps/pwa/out/tasks/index.txt +22 -22
  261. package/apps/pwa/out/term/index.html +1 -1
  262. package/apps/pwa/out/term/index.txt +22 -22
  263. package/apps/pwa/out/today/index.html +1 -1
  264. package/apps/pwa/out/today/index.txt +22 -22
  265. package/apps/pwa/out/trace/index.html +1 -1
  266. package/apps/pwa/out/trace/index.txt +22 -22
  267. package/apps/pwa/out/vault/index.html +1 -1
  268. package/apps/pwa/out/vault/index.txt +22 -22
  269. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  270. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  271. package/apps/pwa/out/workflows/index.html +1 -1
  272. package/apps/pwa/out/workflows/index.txt +22 -22
  273. package/apps/pwa/out/workspace/index.html +1 -1
  274. package/apps/pwa/out/workspace/index.txt +22 -22
  275. package/apps/pwa/out/worktrees/index.html +1 -1
  276. package/apps/pwa/out/worktrees/index.txt +22 -22
  277. package/graphs/overlays/README.md +6 -0
  278. package/graphs/release/release-loop.yaml +33 -17
  279. package/graphs/units/verbs/make-doc.yaml +1 -0
  280. package/package.json +1 -1
  281. package/scripts/bench-metering-plan.ts +229 -0
  282. package/scripts/demo/demo1104-parallel-host.ts +56 -0
  283. package/scripts/demo/demo1104-parallel.ts +72 -0
  284. package/scripts/public-leak-baseline.txt +0 -1
  285. package/scripts/release-loop/docs-node.ts +4 -2
  286. package/scripts/release-loop/gate-image-pin.ts +116 -2
  287. package/scripts/release-loop/gate-node.ts +217 -25
  288. package/scripts/release-loop/gate-progress-sim.ts +73 -0
  289. package/scripts/release-loop/notes-repair.ts +18 -1
  290. package/scripts/release-loop/preflight.ts +188 -8
  291. package/scripts/release-loop/render-warm-control-manifest.ts +22 -0
  292. package/scripts/release-loop/resume-release.ts +9 -7
  293. package/scripts/release-loop/resume.ts +13 -4
  294. package/scripts/release-loop/warm-control-forward.ts +178 -0
  295. package/scripts/retro-cycle.ts +30 -8
  296. package/scripts/rhythm/daily.ts +4 -1
  297. package/scripts/rhythm/linear-progress-sync.ts +28 -15
  298. package/scripts/ux-sim.ts +7 -1
  299. package/scripts/warm-pool-provider-config.ts +6 -1
  300. package/src/agent-mission/grok-auth-status.ts +78 -18
  301. package/src/agent-mission/mission-out.ts +2 -2
  302. package/src/agent-substrate/pr-reviewer.ts +147 -11
  303. package/src/agent-substrate/self-review-cli.ts +10 -2
  304. package/src/auto-research/research-fanout.ts +221 -0
  305. package/src/auto-research/research-turn.ts +282 -36
  306. package/src/autopilot/mission-codebase-gate.ts +7 -3
  307. package/src/cli/control-cli.ts +15 -6
  308. package/src/cli/log-event-names.ts +8 -0
  309. package/src/cli/setup-keys.ts +20 -8
  310. package/src/cli/tui-test-cli.ts +9 -5
  311. package/src/control-plane/ledger.ts +42 -4
  312. package/src/control-plane/member-tokens.ts +25 -2
  313. package/src/control-plane/ports.ts +8 -3
  314. package/src/control-plane/server.ts +26 -5
  315. package/src/core-turn/research-policy.ts +7 -1
  316. package/src/core-turn/run-core-turn.ts +186 -39
  317. package/src/core-turn/types.ts +2 -0
  318. package/src/dashboard/classic-sidetab-mission-job.ts +113 -24
  319. package/src/dashboard/classic-sidetab-mission-pair.ts +3 -2
  320. package/src/dashboard/classic-sidetab-mission-trio.ts +35 -12
  321. package/src/dashboard/classic-sidetab-mission.ts +2 -0
  322. package/src/dashboard/index.ts +9 -1
  323. package/src/dashboard/sidetab-runtime.ts +2 -0
  324. package/src/dashboard/visible-mission-diagnostics.ts +16 -0
  325. package/src/domains/retro-cycle-observation.ts +43 -0
  326. package/src/domains/retro-cycle.ts +13 -2
  327. package/src/domains/retro-proposals.ts +92 -0
  328. package/src/domains/retro-report.ts +6 -1
  329. package/src/graph-runner/graph-cli.ts +24 -1
  330. package/src/graph-runner/graph-grow-llm.ts +3 -1
  331. package/src/graph-runner/runner.ts +226 -30
  332. package/src/harness/harness-cli-command.ts +4 -2
  333. package/src/harness/harness-pod-dispatch.ts +3 -0
  334. package/src/index.ts +2 -2
  335. package/src/llm/child-first-llm-observation.ts +112 -0
  336. package/src/llm/provider-credentials.ts +60 -4
  337. package/src/llm/provider-failure-evidence.ts +44 -0
  338. package/src/llm.ts +170 -11
  339. package/src/mcp/client.ts +7 -0
  340. package/src/mcp/proxy-runtime.ts +6 -1
  341. package/src/mcp/server.ts +54 -0
  342. package/src/native-tool-catalog.ts +2 -2
  343. package/src/nexus/api/consult-requests.ts +18 -6
  344. package/src/nexus/api/discord-trigger-bot.ts +6 -6
  345. package/src/nexus/api/graphs-api.ts +4 -2
  346. package/src/nexus/api/grokbot-trigger-bot.ts +206 -0
  347. package/src/nexus/api/telegram-trigger-bot.ts +6 -6
  348. package/src/nexus/boot/register-mcp-clients.ts +114 -8
  349. package/src/nexus/index.ts +15 -0
  350. package/src/nexus/outbound/grokbot-adapter.ts +71 -0
  351. package/src/nexus/outbound/router.ts +33 -13
  352. package/src/oauth/codex-owner-mirror.ts +47 -10
  353. package/src/onboarding/first-run.ts +44 -6
  354. package/src/preview/terminal.ts +22 -7
  355. package/src/prompt-enhance/enhance.ts +10 -0
  356. package/src/pty-shell/pty-write-provenance.ts +21 -3
  357. package/src/pty-shell/registry.ts +9 -2
  358. package/src/release-loop/proposal-auto-place.ts +83 -0
  359. package/src/research/axis-fanout.ts +40 -5
  360. package/src/research/lenses/second-order.ts +312 -0
  361. package/src/self-dev/dev-cli.ts +3 -1
  362. package/src/self-dev/draft-sweep.ts +31 -10
  363. package/src/self-dev/draft-triage-rules.ts +60 -3
  364. package/src/self-dev/run-supervisor.ts +152 -2
  365. package/src/self-implement/goal-author.ts +208 -23
  366. package/src/self-implement/graph-overlay-yaml.ts +151 -0
  367. package/src/self-implement/graph-yaml.ts +68 -2
  368. package/src/self-implement/orchestrator.ts +62 -15
  369. package/src/self-implement/test-scenario-request.ts +37 -6
  370. package/src/session/chat.ts +2 -2
  371. package/src/session-runtime/index.ts +37 -5
  372. package/src/sidetab-core/model.ts +205 -10
  373. package/src/sidetab-core/visible-agent-mission-pair.ts +51 -0
  374. package/src/sidetab-core/visible-agent-mission.ts +105 -47
  375. package/src/skills/tools/omni-search.ts +4 -2
  376. package/src/task-agent/parent-host.ts +19 -1
  377. package/src/task-agent/recall-inject.ts +98 -0
  378. package/src/task-agent/task-hand.ts +26 -7
  379. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +19 -1
  380. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +15 -0
  381. package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +21 -9
  382. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +1 -1
  383. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +460 -96
  384. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +45 -3
  385. package/src/task-orchestrator/surfaces/self-implement-pod.ts +38 -8
  386. package/src/tool-hints/gate.ts +45 -14
  387. package/src/tool-hints/signals.ts +1 -1
  388. package/src/tool-hints/types.ts +2 -0
  389. package/src/tool-runtime/browser-hand-runtime.ts +11 -1
  390. package/src/tool-runtime/browser-runtime.ts +31 -18
  391. package/src/tool-runtime/elanous-linear-secretary-runtime.ts +152 -36
  392. package/src/tool-runtime/types.ts +2 -0
  393. package/src/tui/entry.ts +27 -7
  394. package/src/tui/sidetab/attach.ts +112 -0
  395. package/src/tui/sidetab/list.ts +3 -2
  396. package/src/tui-client/next-dashboard-runtime.ts +52 -0
  397. package/src/ux-sim/draft-inventory-builder.ts +2 -1
  398. package/src/ux-sim/linear-secretary.ts +4 -12
  399. package/src/ux-sim/mock-scenario-catalog.json +32 -29
  400. package/src/ux-sim/mock-scenario-catalog.ts +55 -3
  401. package/src/ux-sim/release-sim-rig.ts +62 -18
  402. package/src/ux-sim/service-key-setup.ts +63 -0
  403. package/src/version/packed-revision.json +1 -1
  404. package/apps/pwa/out/_next/static/chunks/114.2b90424d1a3ce84c.js +0 -1
  405. package/apps/pwa/out/_next/static/chunks/1151-5c2bb8f002ca2dd6.js +0 -1
  406. package/apps/pwa/out/_next/static/chunks/1261-a616d5728e02e624.js +0 -1
  407. package/apps/pwa/out/_next/static/chunks/1357.3bbef3976c37f94a.js +0 -1
  408. package/apps/pwa/out/_next/static/chunks/1362-20adddfaf662b0fa.js +0 -1
  409. package/apps/pwa/out/_next/static/chunks/1737-9491fc6ab29b9ec6.js +0 -1
  410. package/apps/pwa/out/_next/static/chunks/1803-4f91a8e7dcaf042c.js +0 -1
  411. package/apps/pwa/out/_next/static/chunks/1961.a81b12872c3e93a9.js +0 -23
  412. package/apps/pwa/out/_next/static/chunks/1970cf59.2d4d8ce5d6c81853.js +0 -1
  413. package/apps/pwa/out/_next/static/chunks/1971-8890f3962ba7ee0a.js +0 -1
  414. package/apps/pwa/out/_next/static/chunks/2073-ba274e00e4f9efb4.js +0 -1
  415. package/apps/pwa/out/_next/static/chunks/2268-53861f339e0b65a2.js +0 -1
  416. package/apps/pwa/out/_next/static/chunks/273.f156eee28f11af77.js +0 -1
  417. package/apps/pwa/out/_next/static/chunks/2873.d2140e5a82546401.js +0 -1
  418. package/apps/pwa/out/_next/static/chunks/3091.a5a4143dea33d197.js +0 -90
  419. package/apps/pwa/out/_next/static/chunks/3095.dc44586a5f83b86d.js +0 -1
  420. package/apps/pwa/out/_next/static/chunks/3113.d7472bbc27d580c7.js +0 -1
  421. package/apps/pwa/out/_next/static/chunks/3228-9650b6447b6fa288.js +0 -1
  422. package/apps/pwa/out/_next/static/chunks/360.ae9f9f4c33c395e8.js +0 -79
  423. package/apps/pwa/out/_next/static/chunks/3638.80412ea63aae8f3f.js +0 -286
  424. package/apps/pwa/out/_next/static/chunks/3744.54f87db52acfd1ab.js +0 -1
  425. package/apps/pwa/out/_next/static/chunks/4311-6dd3144002cc0c2d.js +0 -1
  426. package/apps/pwa/out/_next/static/chunks/4426-2b230fad00c88930.js +0 -1
  427. package/apps/pwa/out/_next/static/chunks/4445.7990c76b3751a918.js +0 -115
  428. package/apps/pwa/out/_next/static/chunks/4447-14c5161fa59166c7.js +0 -1
  429. package/apps/pwa/out/_next/static/chunks/4856-b0b8075bba8c53f4.js +0 -1
  430. package/apps/pwa/out/_next/static/chunks/4870-de370d65e73c0bb5.js +0 -1
  431. package/apps/pwa/out/_next/static/chunks/4885-2c989165c4b29fad.js +0 -1
  432. package/apps/pwa/out/_next/static/chunks/4894.fec2ca9e99caefa2.js +0 -1
  433. package/apps/pwa/out/_next/static/chunks/5093.8f04b7f8cb899a95.js +0 -94
  434. package/apps/pwa/out/_next/static/chunks/5122-2bb177cebf89e19a.js +0 -1
  435. package/apps/pwa/out/_next/static/chunks/5154.5f56dc3902e3d275.js +0 -36
  436. package/apps/pwa/out/_next/static/chunks/529.64ff7257180b2ac9.js +0 -1
  437. package/apps/pwa/out/_next/static/chunks/5394.5dabeb0c62293a28.js +0 -93
  438. package/apps/pwa/out/_next/static/chunks/5461.08bf2404ff38ec85.js +0 -1
  439. package/apps/pwa/out/_next/static/chunks/5474-22e08a85583209b2.js +0 -1
  440. package/apps/pwa/out/_next/static/chunks/5567-265df39ed8fe9dcb.js +0 -1
  441. package/apps/pwa/out/_next/static/chunks/5570-a94ae19811cb2046.js +0 -1
  442. package/apps/pwa/out/_next/static/chunks/5574-b47c9ef2dceff1fd.js +0 -1
  443. package/apps/pwa/out/_next/static/chunks/5730.43d7ccc09988e646.js +0 -1
  444. package/apps/pwa/out/_next/static/chunks/5824.da9527b15a3221e5.js +0 -1
  445. package/apps/pwa/out/_next/static/chunks/5963-c4d8469c52a0828b.js +0 -1
  446. package/apps/pwa/out/_next/static/chunks/6001.ec4049ceb3c43418.js +0 -27
  447. package/apps/pwa/out/_next/static/chunks/6120-471f03db1e299c0c.js +0 -1
  448. package/apps/pwa/out/_next/static/chunks/6175-41479e643aca1878.js +0 -1
  449. package/apps/pwa/out/_next/static/chunks/6291.a2de4f9787637075.js +0 -104
  450. package/apps/pwa/out/_next/static/chunks/6400-6699907c3537436a.js +0 -1
  451. package/apps/pwa/out/_next/static/chunks/6428.1f4327d6ae5fdf9a.js +0 -287
  452. package/apps/pwa/out/_next/static/chunks/644.02cb026fa44bcd0a.js +0 -1
  453. package/apps/pwa/out/_next/static/chunks/6466-6c87d60d3dd174fb.js +0 -1
  454. package/apps/pwa/out/_next/static/chunks/6773.d4264665ab31bec0.js +0 -1
  455. package/apps/pwa/out/_next/static/chunks/6822.3c789f1a8443e774.js +0 -1
  456. package/apps/pwa/out/_next/static/chunks/7261-8ff69d3b2ee671fd.js +0 -1
  457. package/apps/pwa/out/_next/static/chunks/7266.084c6bbc70035140.js +0 -1
  458. package/apps/pwa/out/_next/static/chunks/7271.5c0100e7320aa856.js +0 -1
  459. package/apps/pwa/out/_next/static/chunks/7429-bf5731358c8f2f68.js +0 -1
  460. package/apps/pwa/out/_next/static/chunks/7464.01f7a0ae1215fbe7.js +0 -1
  461. package/apps/pwa/out/_next/static/chunks/7479.0fcad5f37eb64f0c.js +0 -1
  462. package/apps/pwa/out/_next/static/chunks/7483.427a2fe2049e388d.js +0 -148
  463. package/apps/pwa/out/_next/static/chunks/7502-be74718178e13e56.js +0 -1
  464. package/apps/pwa/out/_next/static/chunks/7530.0889722b19572065.js +0 -24
  465. package/apps/pwa/out/_next/static/chunks/7645.5b2ee3ad45c55ea3.js +0 -1
  466. package/apps/pwa/out/_next/static/chunks/7788.7d1c79f1a8e18946.js +0 -1
  467. package/apps/pwa/out/_next/static/chunks/7966.f71c8958d1637548.js +0 -1
  468. package/apps/pwa/out/_next/static/chunks/8073.f6cf2f2c71aafbd0.js +0 -1
  469. package/apps/pwa/out/_next/static/chunks/8201.190b94088980f430.js +0 -74
  470. package/apps/pwa/out/_next/static/chunks/8447.7963352ef5f71b76.js +0 -1
  471. package/apps/pwa/out/_next/static/chunks/8574-868e8129525ef6d9.js +0 -1
  472. package/apps/pwa/out/_next/static/chunks/868.6e953be05bcf6dca.js +0 -41
  473. package/apps/pwa/out/_next/static/chunks/8706-e1fe0309343a2273.js +0 -1
  474. package/apps/pwa/out/_next/static/chunks/8749-06384cdfc4520add.js +0 -1
  475. package/apps/pwa/out/_next/static/chunks/8861-cc1fa1c7b920fa8e.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/8967-7dfebf710c9dec9d.js +0 -1
  477. package/apps/pwa/out/_next/static/chunks/8997-3c564dbb3b58b055.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/923.2034d10ae91e9c20.js +0 -1
  479. package/apps/pwa/out/_next/static/chunks/9312.bc1b89c5d4368033.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/943.39ae5e82f4f1893f.js +0 -1
  481. package/apps/pwa/out/_next/static/chunks/9469.0500480de55fb205.js +0 -32
  482. package/apps/pwa/out/_next/static/chunks/9810-2543267050e58b82.js +0 -1
  483. package/apps/pwa/out/_next/static/chunks/9870.8419702475254745.js +0 -8
  484. package/apps/pwa/out/_next/static/chunks/9941-376d1b74d51b01a4.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/9958.385434ab04241758.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-deea1450b17cb8dc.js +0 -1
  487. package/apps/pwa/out/_next/static/chunks/app/approvals/page-70985b904f8650ef.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a2e15e33e56a4353.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/app/board/page-fc72ce2db12d6ca9.js +0 -1
  490. package/apps/pwa/out/_next/static/chunks/app/botlab/page-be03e41f9436ebd9.js +0 -1
  491. package/apps/pwa/out/_next/static/chunks/app/bots/page-35a35999382da3f2.js +0 -1
  492. package/apps/pwa/out/_next/static/chunks/app/ceo/page-3ff5b1e6ca88b848.js +0 -1
  493. package/apps/pwa/out/_next/static/chunks/app/chat/page-a65101300a0ee5c1.js +0 -1
  494. package/apps/pwa/out/_next/static/chunks/app/consult/page-3aca5b6d67dba511.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/app/control/page-45b8ab0a71e61314.js +0 -1
  496. package/apps/pwa/out/_next/static/chunks/app/decisions/page-53046e282d4cda8e.js +0 -1
  497. package/apps/pwa/out/_next/static/chunks/app/design-check/page-17809e60e8354c17.js +0 -1
  498. package/apps/pwa/out/_next/static/chunks/app/editor/page-fd2442d347bf5898.js +0 -1
  499. package/apps/pwa/out/_next/static/chunks/app/exec/page-e9d720d6fc082e21.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/app/field/page-6b8b4267bab0a677.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/app/healthz/route-deea1450b17cb8dc.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/app/inside/page-8bcf6233ac7c17af.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/app/intake/page-7cc25591cfc2126f.js +0 -1
  504. package/apps/pwa/out/_next/static/chunks/app/layout-053e871f35c9beba.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/app/live/page-eff819f0c2d5e084.js +0 -1
  506. package/apps/pwa/out/_next/static/chunks/app/live-run/page-4d7e9d8db5274a87.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/app/loops/page-2b2d8f5aa5f69ad4.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/app/market/page-0b8f92c5062e68b1.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1bd9d0fdac2ced3d.js +0 -1
  510. package/apps/pwa/out/_next/static/chunks/app/morning/page-9ee28f7df07428ea.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/app/not-found-44b7a1ff468c6648.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/app/observatory/page-cbc6523711dc1b65.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-fdad47899c2695be.js +0 -1
  514. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-79a8b5fee4c20871.js +0 -1
  515. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-03e8ac9606aeaffb.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/app/outputs/page-4cd55c55ec287e2f.js +0 -1
  517. package/apps/pwa/out/_next/static/chunks/app/page-db17b4305404161e.js +0 -1
  518. package/apps/pwa/out/_next/static/chunks/app/reflection/page-30041d848350fd02.js +0 -1
  519. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c540da022dbf86b0.js +0 -1
  520. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9399efc538da057f.js +0 -1
  521. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ca2d09128c585ca4.js +0 -1
  522. package/apps/pwa/out/_next/static/chunks/app/settings/page-0e2635aecd343038.js +0 -1
  523. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ef7f4399b6b7726e.js +0 -1
  524. package/apps/pwa/out/_next/static/chunks/app/setup/layout-deea1450b17cb8dc.js +0 -1
  525. package/apps/pwa/out/_next/static/chunks/app/setup/page-caf530535b875468.js +0 -1
  526. package/apps/pwa/out/_next/static/chunks/app/share/page-eaa20c1543a5fd8e.js +0 -1
  527. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c541eb1b75120f61.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/app/tasks/page-ab5e213eda9479f4.js +0 -1
  529. package/apps/pwa/out/_next/static/chunks/app/today/page-e858ba0ed9393b68.js +0 -1
  530. package/apps/pwa/out/_next/static/chunks/app/trace/page-1638ee9dd6e0582f.js +0 -1
  531. package/apps/pwa/out/_next/static/chunks/app/vault/page-4cf5a399109391f2.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-b4396321238798ec.js +0 -1
  533. package/apps/pwa/out/_next/static/chunks/app/workflows/page-cb72bfd21006781a.js +0 -1
  534. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6135d0242afbc434.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a1dccf907eddb856.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/c7945435-b44d4dbe90ba0dcb.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/ea514caa.05a24f78d9dffe5f.js +0 -122
  538. package/apps/pwa/out/_next/static/chunks/framework-e8a911e19b1be41f.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/main-7022f418fabba021.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/main-app-e5f15df755756a1e.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/pages/_app-4525f91e36940c9b.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/pages/_error-140f0e519c085b0f.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/webpack-8f22ef63dcb865b1.js +0 -1
  544. /package/apps/pwa/out/_next/static/{Om5xS9jpjSXJCeTNGYEi4 → HMXsxdy5MIIcHPMHv1wD4}/_ssgManifest.js +0 -0
@@ -35,7 +35,10 @@ import {
35
35
  RESEARCH_TURN_DEEP_BUDGET_MS,
36
36
  RESEARCH_TURN_DEADLINE_STOP_ERROR,
37
37
  RESEARCH_TURN_FIRST_REPLY_BUDGET_MS,
38
+ RESEARCH_TURN_FINAL_ANSWER_DEADLINE_MS,
38
39
  RESEARCH_TURN_MAX_TOOL_TURNS,
40
+ RESEARCH_TURN_SHALLOW_FINAL_ANSWER_DEADLINE_MS,
41
+ RESEARCH_TURN_SHALLOW_BUDGET_MS,
39
42
  } from './research-policy.js';
40
43
  import type {
41
44
  CoreTurnContext,
@@ -163,7 +166,12 @@ export interface RunCoreTurnOptions {
163
166
  timers?: { setTimeout(callback: () => void, delayMs: number): ReturnType<typeof setTimeout>; clearTimeout(handle: ReturnType<typeof setTimeout>): void };
164
167
  firstReplyBudgetMs?: number;
165
168
  researchWallClockBudgetMs?: number;
166
- runResearch?: (request: string, signal: AbortSignal, admitToolCall?: (name: string) => boolean) => Promise<{ ok: boolean; output: string; error?: string }>;
169
+ runResearch?: (
170
+ request: string,
171
+ signal: AbortSignal,
172
+ admitToolCall?: (name: string) => boolean,
173
+ providerRouting?: Pick<CoreTurnContext, 'initialProvider' | 'skipProviders' | 'runId'>,
174
+ ) => Promise<{ ok: boolean; output: string; error?: string; axisCount?: number }>;
167
175
  }
168
176
 
169
177
  type ResearchTimer = ReturnType<typeof setTimeout>;
@@ -171,17 +179,20 @@ type ResearchTimer = ReturnType<typeof setTimeout>;
171
179
  type AbortRace<T> = { aborted: true } | { aborted: false; value: T };
172
180
 
173
181
  function settleBeforeAbort<T>(work: Promise<T>, signal: AbortSignal): Promise<AbortRace<T>> {
174
- if (signal.aborted) return Promise.resolve({ aborted: true });
175
182
  return new Promise((resolve, reject) => {
183
+ let abortGraceTimer: ReturnType<typeof setTimeout> | undefined;
176
184
  const onAbort = () => {
177
185
  signal.removeEventListener('abort', onAbort);
178
- resolve({ aborted: true });
186
+ // Let work handlers that synchronously settle in response to abort
187
+ // expose their final partial result before taking the deadline path.
188
+ abortGraceTimer = setTimeout(() => resolve({ aborted: true }), 50);
179
189
  };
180
- signal.addEventListener('abort', onAbort, { once: true });
181
190
  work.then(
182
- value => { signal.removeEventListener('abort', onAbort); resolve({ aborted: false, value }); },
183
- error => { signal.removeEventListener('abort', onAbort); reject(error); },
191
+ value => { signal.removeEventListener('abort', onAbort); if (abortGraceTimer) clearTimeout(abortGraceTimer); resolve({ aborted: false, value }); },
192
+ error => { signal.removeEventListener('abort', onAbort); if (abortGraceTimer) clearTimeout(abortGraceTimer); reject(error); },
184
193
  );
194
+ if (signal.aborted) onAbort();
195
+ else signal.addEventListener('abort', onAbort, { once: true });
185
196
  });
186
197
  }
187
198
 
@@ -220,6 +231,41 @@ function commitProvisionalTurn(
220
231
  commitCompletion(messages, handlers, setFinalPhaseAnswer);
221
232
  }
222
233
 
234
+ function completionWithFinalText(messages: TurnCompletion | undefined, text: string): TurnCompletion {
235
+ const completed = [...(messages ?? [])];
236
+ let lastAssistant = -1;
237
+ for (let index = completed.length - 1; index >= 0; index -= 1) {
238
+ if (completed[index]?.role === 'assistant') { lastAssistant = index; break; }
239
+ }
240
+ if (lastAssistant < 0) {
241
+ completed.push({ role: 'assistant', content: text, phase: 'final_answer' });
242
+ } else {
243
+ const previous = completed[lastAssistant]!;
244
+ let content: typeof previous.content;
245
+ if (typeof previous.content === 'string') {
246
+ content = text;
247
+ } else {
248
+ let lastText = -1;
249
+ for (let index = previous.content.length - 1; index >= 0; index -= 1) {
250
+ if (previous.content[index]?.type === 'text') { lastText = index; break; }
251
+ }
252
+ if (lastText < 0) {
253
+ // A tool-only assistant message must stay paired with its tool result;
254
+ // the synthesized prose is a separate final answer message.
255
+ completed.push({ role: 'assistant', content: text, phase: 'final_answer' });
256
+ return completed;
257
+ }
258
+ content = previous.content.map((block, index) => index === lastText && block.type === 'text'
259
+ ? { ...block, text }
260
+ : block);
261
+ }
262
+ completed[lastAssistant] = {
263
+ ...previous, content, phase: 'final_answer',
264
+ };
265
+ }
266
+ return completed;
267
+ }
268
+
223
269
  function commitStagedTurn(
224
270
  messages: TurnCompletion | undefined,
225
271
  handlers: StreamWithToolsHandlers,
@@ -228,8 +274,25 @@ function commitStagedTurn(
228
274
  setFinalPhaseAnswer: (value: boolean) => void,
229
275
  onReplaceText?: (fullText: string) => void,
230
276
  ): void {
231
- commitCompletion(messages, handlers, setFinalPhaseAnswer);
277
+ // Replacement must reach the stream bridge before completion: ACP tracks the
278
+ // visible tail in `onReplaceText` so its completion callback will not emit the
279
+ // same synthesized answer a second time.
232
280
  if (replaceVisibleText && text) onReplaceText?.(text);
281
+ commitCompletion(messages, handlers, setFinalPhaseAnswer);
282
+ }
283
+
284
+ function commitSynthesizedTurn(
285
+ staged: ReturnType<typeof createStagedHandlers>,
286
+ fallbackMessages: TurnCompletion | undefined,
287
+ handlers: StreamWithToolsHandlers,
288
+ finalText: string,
289
+ provisionalText: string,
290
+ setFinalPhaseAnswer: (value: boolean) => void,
291
+ onReplaceText?: (fullText: string) => void,
292
+ ): void {
293
+ const completion = staged.completion() ?? completionWithFinalText(fallbackMessages, finalText);
294
+ commitStagedTurn(completion, handlers, finalText, finalText !== provisionalText,
295
+ setFinalPhaseAnswer, onReplaceText);
233
296
  }
234
297
 
235
298
  export async function runCoreTurn(
@@ -270,6 +333,7 @@ export async function runCoreTurn(
270
333
  || (enforceResearchDocumentWrite && (RESEARCH_DOCUMENT_WRITE_TOOLS as readonly string[]).includes(name));
271
334
  let enforceResearchToolBudget = false;
272
335
  let researchToolCallCount = 0;
336
+ let researchAxisCount = 0;
273
337
  let researchStopReason: string | undefined;
274
338
  const loggedResearchStops = new Set<string>();
275
339
  const logResearchStop = (reason: string, extra: Record<string, unknown> = {}): void => {
@@ -279,6 +343,12 @@ export async function runCoreTurn(
279
343
  };
280
344
  const admitResearchToolCall = (name: string): boolean => {
281
345
  if (!enforceResearchToolBudget) return true;
346
+ if (name === 'Agent' && researchAxisCount < 3) {
347
+ debug.log('research.turn', 'subagent-skipped', {
348
+ sessionId: ctx.sessionId, reason: 'insufficient-judgment-axes', axisCount: researchAxisCount, minimum: 3,
349
+ });
350
+ return false;
351
+ }
282
352
  if (researchToolCallCount >= RESEARCH_TURN_MAX_TOOL_TURNS) {
283
353
  // A prior denied tool is observable, but it must not mask the hard
284
354
  // budget stop that requires tool-free synthesis. A wall-clock stop is
@@ -392,6 +462,15 @@ export async function runCoreTurn(
392
462
  success = true;
393
463
  return result;
394
464
  } finally {
465
+ if (name === 'Agent' && enforceResearchToolAllowlist) {
466
+ debug.log('research.turn', 'subagent-completed', {
467
+ sessionId: ctx.sessionId,
468
+ dispatchCount: currentDispatchCount,
469
+ durationMs: now() - startedAt,
470
+ completionMode: 'awaited-tool-result',
471
+ success,
472
+ });
473
+ }
395
474
  try {
396
475
  debug.log('core.turn', 'dispatch-done', {
397
476
  sessionId: ctx.sessionId,
@@ -475,15 +554,17 @@ export async function runCoreTurn(
475
554
  );
476
555
  // Preserve the pre-routing contract: a named skill only skips the research
477
556
  // prepass when skill_exec is actually active after the normal tier split.
478
- let explicitSkillToolRequest = requestsNamedSkill(surfaceUserText)
479
- && tieredTools.some((tool) => tool.name === 'skill_exec');
480
- if (!explicitSkillToolRequest && researchTurn && surfaceUserText?.trim()
481
- && tieredTools.some((tool) => tool.name === 'skill_exec')) {
482
- // Korean named-skill requests need the installed index to recognize the
483
- // skill slug before the research allowlist filters the normal tool loop.
557
+ // Resolve the installed skill name even if skill_exec is deferred/missing:
558
+ // a named request with no executor falls back to the unfiltered normal pool.
559
+ let installedSkillNames: string[] = [];
560
+ if (researchTurn && surfaceUserText?.trim()) {
484
561
  const { getSkillIndex } = await import('../skills/index.js');
485
- explicitSkillToolRequest = requestsNamedSkill(surfaceUserText, getSkillIndex().map(({ name }) => name));
562
+ installedSkillNames = getSkillIndex().map(({ name }) => name);
486
563
  }
564
+ const namedSkillRequest = requestsNamedSkill(surfaceUserText, installedSkillNames);
565
+ // A named skill only skips the research prepass when its executor is active.
566
+ const explicitSkillToolRequest = namedSkillRequest
567
+ && tieredTools.some((tool) => tool.name === 'skill_exec');
487
568
  const constrainDeepNonResearchTools = deepBloomDecision.apply && !researchTurn;
488
569
  // ToolSearch routes against the surface's full live pool, so hiding a tool
489
570
  // from the model alone is insufficient. Remove the summoner from the
@@ -504,11 +585,19 @@ export async function runCoreTurn(
504
585
  });
505
586
  }
506
587
  enforceResearchToolBudget = researchTurn;
507
- enforceResearchToolAllowlist = researchTurn && !explicitSkillToolRequest;
588
+ enforceResearchToolAllowlist = researchTurn && !namedSkillRequest;
508
589
  enforceResearchDocumentWrite = enforceResearchToolAllowlist && requestsResearchDocumentWrite(surfaceUserText);
590
+ // Codex Responses only supports tool_choice="required" (not a named
591
+ // function choice). Make the first request deterministic by exposing only
592
+ // skill_exec there; streamLLMWithTools restores the full pool on later turns.
593
+ const routedSkillTools = explicitSkillToolRequest
594
+ ? bloomFilteredTools.filter((tool) => tool.name === 'skill_exec')
595
+ : [];
509
596
  const tools = enforceResearchToolAllowlist
510
597
  ? bloomFilteredTools.filter((tool) => isAllowedResearchTool(tool.name))
511
598
  : bloomFilteredTools;
599
+ // Preserve the ordinary pool if a later filter removes the executor.
600
+ const firstTurnTools = routedSkillTools.length > 0 ? routedSkillTools : undefined;
512
601
  const maxToolTurns = researchTurn
513
602
  ? Math.min(ctx.maxToolTurns ?? RESEARCH_TURN_MAX_TOOL_TURNS, RESEARCH_TURN_MAX_TOOL_TURNS)
514
603
  : ctx.maxToolTurns;
@@ -550,16 +639,41 @@ export async function runCoreTurn(
550
639
  });
551
640
  }
552
641
  let researchResultPromise: Promise<{ ok: boolean; output: string; error?: string } | null> | undefined;
642
+ let researchDeadlineSignal: AbortSignal | undefined;
553
643
  let requestedSkillName: string | undefined;
554
644
  if (researchTurn && surfaceUserText?.trim() && explicitSkillToolRequest) {
555
645
  // Resolve a display name only for the research opening plan; ordinary
556
646
  // turns and unrequested research keep the core startup lean.
557
- const { getSkillIndex } = await import('../skills/index.js');
558
- const skillNames = getSkillIndex().map(({ name }) => name);
559
- requestedSkillName = requestedInstalledSkillName(surfaceUserText, skillNames);
647
+ requestedSkillName = requestedInstalledSkillName(surfaceUserText, installedSkillNames);
648
+ const selectedTool = firstTurnTools?.find((tool) => tool.name === 'skill_exec');
649
+ if (requestedSkillName && selectedTool) {
650
+ debug.log('research.turn', 'named-skill-route-first', {
651
+ sessionId: ctx.sessionId,
652
+ requestedSkillName,
653
+ selectedTool: selectedTool.name,
654
+ availableToolNames: firstTurnTools?.map((tool) => tool.name) ?? [],
655
+ });
656
+ }
560
657
  }
561
658
  if (researchTurn && surfaceUserText?.trim()) {
562
- const plan = (requestedSkillName ?? '검색 도구') + '로 요청한 주제의 근거를 찾습니다.\n질문 범위에 맞춰 결론과 근거를 정리합니다.';
659
+ // `tools` is the active post-tier-flip pool; use the shared research
660
+ // allowlist order so the plan names only currently callable tools.
661
+ const availableResearchTools = RESEARCH_TOOL_ALLOWLIST
662
+ .filter((name) => tools.some((tool) => tool.name === name));
663
+ const planTools = requestedSkillName && firstTurnTools?.some((tool) => tool.name === 'skill_exec')
664
+ ? [`${requestedSkillName} (skill_exec)`]
665
+ : availableResearchTools;
666
+ const plan = planTools.length > 0
667
+ ? [
668
+ `${planTools.join(' → ')}로 질문에 나온 주제와 요구 조건의 근거를 찾습니다.`,
669
+ '출처의 주장과 제약을 비교해 확인된 사실을 가립니다.',
670
+ '확인한 결론과 짧은 근거로 답합니다.',
671
+ ].join('\n')
672
+ : [
673
+ '현재 사용할 수 있는 조사 도구가 없습니다.',
674
+ '근거를 확인할 수 없어 결론을 단정하지 않습니다.',
675
+ '도구가 활성화되면 출처를 확인해 답합니다.',
676
+ ].join('\n');
563
677
  try { ctx.callbacks?.onStatus?.(plan); } catch { /* UI feedback is fail-soft. */ }
564
678
  }
565
679
  if (researchTurn && surfaceUserText?.trim() && !explicitSkillToolRequest) {
@@ -573,13 +687,17 @@ export async function runCoreTurn(
573
687
  // answer-first status that contradicts that plan; stream the provisional
574
688
  // answer while evidence collection runs, then reconcile in the second pass.
575
689
  const researchController = new AbortController();
690
+ researchDeadlineSignal = researchController.signal;
576
691
  const abortResearchFromParent = (): void => {
577
692
  if (researchStopReason !== 'wall-clock-budget') researchStopReason = 'parent-abort';
578
693
  researchController.abort(ctx.signal.reason);
579
694
  };
580
695
  if (ctx.signal.aborted) abortResearchFromParent();
581
696
  else ctx.signal.addEventListener('abort', abortResearchFromParent, { once: true });
582
- const researchWallClockBudgetMs = options.researchWallClockBudgetMs ?? RESEARCH_TURN_DEEP_BUDGET_MS;
697
+ const defaultResearchWallClockBudgetMs = deepBloomDecision.apply
698
+ ? RESEARCH_TURN_DEEP_BUDGET_MS
699
+ : RESEARCH_TURN_SHALLOW_BUDGET_MS;
700
+ const researchWallClockBudgetMs = options.researchWallClockBudgetMs ?? defaultResearchWallClockBudgetMs;
583
701
  let researchDeadlineTimer: ResearchTimer | undefined;
584
702
  if (!researchController.signal.aborted) {
585
703
  researchDeadlineTimer = timers.setTimeout(() => {
@@ -595,14 +713,23 @@ export async function runCoreTurn(
595
713
  }
596
714
  researchResultPromise = (async () => {
597
715
  try {
598
- const work = (options.runResearch ?? (async (request, signal, admitToolCall) => {
716
+ const work = (options.runResearch ?? (async (request, signal, admitToolCall, providerRouting) => {
599
717
  // Keep the Bloom/skill pipeline out of ordinary and packaged TUI startup graphs.
600
718
  const { researchTurnForGrounding, runResearchQuestionLadder } = await import('../auto-research/research-turn.js');
601
719
  return researchTurnForGrounding(await runResearchQuestionLadder(request, {
720
+ ...providerRouting,
602
721
  signal, admitToolCall, allowPartialOnAbort: true, allowOutputSkill: false,
722
+ deadlineMs: deepBloomDecision.apply
723
+ ? RESEARCH_TURN_FINAL_ANSWER_DEADLINE_MS
724
+ : Math.min(RESEARCH_TURN_SHALLOW_FINAL_ANSWER_DEADLINE_MS, Math.max(1, researchWallClockBudgetMs - 1)),
603
725
  }));
604
- }))(surfaceUserText, researchController.signal, admitResearchToolCall);
726
+ }))(surfaceUserText, researchController.signal, admitResearchToolCall, {
727
+ ...(ctx.initialProvider ? { initialProvider: ctx.initialProvider } : {}),
728
+ ...(ctx.skipProviders ? { skipProviders: ctx.skipProviders } : {}),
729
+ ...(ctx.runId ? { runId: ctx.runId } : {}),
730
+ });
605
731
  const result = await work;
732
+ researchAxisCount = result?.axisCount ?? 0;
606
733
  if (researchController.signal.aborted && !researchStopReason) researchStopReason = ctx.signal.aborted ? 'parent-abort' : 'research-aborted';
607
734
  if (researchStopReason) logResearchStop(researchStopReason, {
608
735
  stage: 'research-prepass',
@@ -635,8 +762,9 @@ export async function runCoreTurn(
635
762
  }
636
763
  const streamOptions = (turnTools: typeof tools, signal: AbortSignal = ctx.signal) => ({
637
764
  tools: turnTools,
765
+ ...(firstTurnTools ? { firstTurnTools } : {}),
638
766
  researchTurn,
639
- ...(explicitSkillToolRequest ? { toolChoice: { name: 'skill_exec' } } : {}),
767
+ ...(firstTurnTools ? { toolChoice: { name: 'skill_exec' } } : {}),
640
768
  signal,
641
769
  ...(ctx.requestSizeGuard ? { requestSizeGuard: ctx.requestSizeGuard } : {}),
642
770
  ...(ctx.reasoningEffort !== undefined ? { reasoningEffort: ctx.reasoningEffort } : {}),
@@ -678,6 +806,28 @@ export async function runCoreTurn(
678
806
  deferred: stats.deferredNames,
679
807
  unhydratable: stats.unhydratableNames,
680
808
  }, { compact: { arrayMax: Number.MAX_SAFE_INTEGER } });
809
+ const activeToolNames = new Set(tools.map((tool) => tool.name));
810
+ const immediateToolNames = new Set(tieredTools.map((tool) => tool.name));
811
+ const bloomToolNames = new Set(bloomFilteredTools.map((tool) => tool.name));
812
+ const excludedTools = ctx.tools
813
+ .filter((tool) => !activeToolNames.has(tool.name))
814
+ .map((tool) => ({
815
+ name: tool.name,
816
+ reason: !immediateToolNames.has(tool.name)
817
+ ? stats.deferredNames.includes(tool.name) ? 'deferred-tool-tier' : 'not-in-immediate-tier'
818
+ : !bloomToolNames.has(tool.name) ? 'deep-bloom-non-research-suppression'
819
+ : enforceResearchToolAllowlist && !isAllowedResearchTool(tool.name) ? 'research-tool-allowlist'
820
+ : 'not-active-after-turn-filtering',
821
+ }));
822
+ debug.log('capability.resolve', 'tier-split', {
823
+ sessionId: ctx.sessionId,
824
+ surfaceId: surface.id,
825
+ researchTurn,
826
+ activeTools: [...activeToolNames],
827
+ excludedTools,
828
+ deferredTools: stats.deferredNames,
829
+ unhydratableTools: stats.unhydratableNames,
830
+ }, { compact: { arrayMax: Number.MAX_SAFE_INTEGER } });
681
831
  if (stats.unhydratableCount > 0) {
682
832
  debug.log('capability.resolve', 'unhydratable-capabilities', {
683
833
  sessionId: ctx.sessionId,
@@ -714,7 +864,7 @@ export async function runCoreTurn(
714
864
  firstReplyTimer = timers.setTimeout(() => resolve({ timedOut: true }), firstReplyBudgetMs);
715
865
  });
716
866
  try {
717
- const firstPass = streamLLMWithTools(firstPassMessages, firstPassHandlers, streamOptions([], firstPassController.signal))
867
+ const firstPass = streamLLMWithTools(firstPassMessages, firstPassHandlers, streamOptions(tools, firstPassController.signal))
718
868
  .then(text => ({ timedOut: false as const, text }));
719
869
  const outcome = await Promise.race([firstPass, deadline]);
720
870
  if (outcome.timedOut) {
@@ -745,12 +895,17 @@ export async function runCoreTurn(
745
895
  });
746
896
  }
747
897
  if (researchResultPromise) {
748
- const racedResearch = await settleBeforeAbort(researchResultPromise, ctx.signal);
749
- if (racedResearch.aborted) {
898
+ const racedResearch = await settleBeforeAbort(researchResultPromise, researchDeadlineSignal ?? ctx.signal);
899
+ if (racedResearch.aborted && ctx.signal.aborted) {
750
900
  commitProvisionalTurn(provisionalTurnMessages, handlers, value => { finalPhaseAnswer = value; });
751
901
  return { stopReason: 'aborted', finalText };
752
902
  }
753
- const result = racedResearch.value;
903
+ // A native research tool can ignore cancellation and leave its promise
904
+ // pending. The deadline must still end the prepass and enter the
905
+ // no-tools synthesis path with the provisional answer.
906
+ const result = racedResearch.aborted
907
+ ? { ok: false, output: '', error: RESEARCH_TURN_DEADLINE_STOP_ERROR }
908
+ : racedResearch.value;
754
909
  if (ctx.signal.aborted) {
755
910
  commitProvisionalTurn(provisionalTurnMessages, handlers, value => { finalPhaseAnswer = value; });
756
911
  return { stopReason: 'aborted', finalText };
@@ -796,12 +951,8 @@ export async function runCoreTurn(
796
951
  outputChars: finalText.length,
797
952
  });
798
953
  logResearchStop('synthesis-complete', { stage: 'synthesis', outputChars: finalText.length });
799
- if (staged.completion()) {
800
- commitStagedTurn(staged.completion(), handlers, finalText, finalText !== provisionalText,
801
- value => { finalPhaseAnswer = value; }, ctx.callbacks?.onReplaceText);
802
- } else {
803
- commitProvisionalTurn(provisionalTurnMessages, handlers, value => { finalPhaseAnswer = value; });
804
- }
954
+ commitSynthesizedTurn(staged, provisionalTurnMessages, handlers, finalText, provisionalText,
955
+ value => { finalPhaseAnswer = value; }, ctx.callbacks?.onReplaceText);
805
956
  } catch (error) {
806
957
  commitProvisionalTurn(provisionalTurnMessages, handlers, value => { finalPhaseAnswer = value; });
807
958
  const stopReason = classifyStopReason(error, ctx.signal);
@@ -836,12 +987,8 @@ export async function runCoreTurn(
836
987
  }
837
988
  finalText = fallbackText || staged.text() || provisionalText;
838
989
  accumulatedText = finalText;
839
- if (staged.completion()) {
840
- commitStagedTurn(staged.completion(), handlers, finalText, finalText !== provisionalText,
841
- value => { finalPhaseAnswer = value; }, ctx.callbacks?.onReplaceText);
842
- } else {
843
- commitProvisionalTurn(provisionalTurnMessages, handlers, value => { finalPhaseAnswer = value; });
844
- }
990
+ commitSynthesizedTurn(staged, provisionalTurnMessages, handlers, finalText, provisionalText,
991
+ value => { finalPhaseAnswer = value; }, ctx.callbacks?.onReplaceText);
845
992
  } catch (error) {
846
993
  commitProvisionalTurn(provisionalTurnMessages, handlers, value => { finalPhaseAnswer = value; });
847
994
  const stopReason = classifyStopReason(error, ctx.signal);
@@ -125,6 +125,8 @@ export interface CoreTurnCallbacks {
125
125
  * `src/core-turn/` never imports from dashboard / chat / tui /
126
126
  * display — the headless guard test enforces this structurally. */
127
127
  export interface CoreTurnContext {
128
+ /** Caller-owned identity for correlating this turn's research and debug events. */
129
+ runId?: string;
128
130
  /** Identifier for the hosting session. Piped through for future
129
131
  * correlation; the turn logic does not branch on it. */
130
132
  sessionId: string;
@@ -1,4 +1,7 @@
1
1
  import type { PendingTaskNotification } from '../agent/task-notification.js';
2
+ import { randomUUID } from 'node:crypto';
3
+ import { mkdirSync, writeFileSync } from 'node:fs';
4
+ import { basename, isAbsolute, join, relative, sep } from 'node:path';
2
5
  import { debug } from '../debug/log.js';
3
6
  import { redactMissionResultPath, type StartedClassicMissionCliJob } from './mission-cli-consumer.js';
4
7
  import type { ClassicSidetabMissionResult } from './classic-sidetab-mission.js';
@@ -6,7 +9,6 @@ import type { ClassicSidetabMissionResult } from './classic-sidetab-mission.js';
6
9
  export type ClassicMissionNotificationEnqueue = (notification: PendingTaskNotification) => void;
7
10
  export const CLASSIC_SIDETAB_MISSION_LABEL = 'sidetab mission';
8
11
  const CLASSIC_SIDETAB_PAIR_TIMEOUT_MS = 60 * 60 * 1_000;
9
- const MAX_PAIR_ANSWER_CHARS = 12_000;
10
12
  export interface ClassicSidetabMissionPairCompletionResult {
11
13
  codex: ClassicSidetabMissionResult;
12
14
  claude: ClassicSidetabMissionResult;
@@ -19,9 +21,91 @@ interface ClassicSidetabMissionPairJob {
19
21
  taskId: string;
20
22
  parentSessionId?: string;
21
23
  startedAt: number;
24
+ mission: string;
25
+ workspaceDir: string;
22
26
  completion: Promise<ClassicSidetabPairOutcome>;
23
27
  }
24
28
 
29
+ function safeFilePart(value: string): string {
30
+ return value.replace(/[^a-zA-Z0-9_-]/g, '-').slice(0, 80) || 'pair';
31
+ }
32
+
33
+ function resultFileLabel(workspaceDir: string, result: ClassicSidetabPairOutcome): string {
34
+ if (!result.path) return '없음';
35
+ const rel = relative(workspaceDir, result.path);
36
+ return rel && !isAbsolute(rel) && rel !== '..' && !rel.startsWith(`..${sep}`) ? rel : basename(result.path);
37
+ }
38
+
39
+ function buildPairSynthesis(
40
+ pair: { codex: ClassicSidetabMissionPairJob; claude: ClassicSidetabMissionPairJob },
41
+ codex: ClassicSidetabPairOutcome,
42
+ claude: ClassicSidetabPairOutcome,
43
+ ): string {
44
+ const rows = [
45
+ { agent: 'Codex', job: pair.codex, result: codex },
46
+ { agent: 'Claude Code', job: pair.claude, result: claude },
47
+ ];
48
+ const cell = (value: string): string => value.replace(/[\r\n]+/g, ' ').trim().replaceAll('\\', '&#92;').replaceAll('|', '&#124;');
49
+ const table = rows.map(({ agent, job, result }) => {
50
+ const accepted = result.ok && Boolean(result.content?.trim());
51
+ const decision = accepted
52
+ ? '채택 — 별도 기여로 보존; 두 결과 간 우열을 임의 판정하지 않음'
53
+ : `미채택 — ${result.error ?? (result.ok ? '빈 결과' : '실패')}`;
54
+ const task = job.mission.length > 240 ? `${job.mission.slice(0, 240)}…` : job.mission;
55
+ return `| ${cell(agent)} | ${cell(task)} | ${cell(resultFileLabel(job.workspaceDir, result))} | ${accepted ? '성공' : '실패/빈 결과'} | ${cell(decision)} |`;
56
+ }).join('\n');
57
+ const contributions = rows.flatMap(({ agent, result }) => {
58
+ const content = result.ok ? result.content?.trim() : '';
59
+ if (!content) return [];
60
+ return [`## ${agent} 기여`, redactMissionResultPath(content, result.path)];
61
+ });
62
+ return [
63
+ '# Codex + Claude mission pair synthesis', '',
64
+ `- Codex mission: ${pair.codex.missionId ?? 'unavailable'}`,
65
+ `- Claude mission: ${pair.claude.missionId ?? 'unavailable'}`, '',
66
+ '## 비교·채택 표', '',
67
+ '| 손 | 맡은 작업 | 결과 파일 | 판정 | 채택 근거 |',
68
+ '|---|---|---|---|---|', table, '',
69
+ '채택 기준: 성공하고 비어 있지 않은 결과를 각자 독립 기여로 보존한다. 두 손의 답이 서로 다른 작업 분담에서 나온 경우 품질 순위를 추정하지 않으며, 실패·빈 결과는 채택하지 않고 사유를 남긴다.', '',
70
+ ...contributions.flatMap((section) => [section, '']),
71
+ ].join('\n').trimEnd() + '\n';
72
+ }
73
+
74
+ function persistPairSynthesis(
75
+ pair: { codex: ClassicSidetabMissionPairJob; claude: ClassicSidetabMissionPairJob },
76
+ taskId: string,
77
+ codex: ClassicSidetabPairOutcome,
78
+ claude: ClassicSidetabPairOutcome,
79
+ ): string {
80
+ if (typeof pair.codex.workspaceDir !== 'string' || !pair.codex.workspaceDir.trim()
81
+ || pair.codex.workspaceDir !== pair.claude.workspaceDir) {
82
+ throw new Error('pair members must share a workspace to persist one synthesis artifact');
83
+ }
84
+ const dir = join(pair.codex.workspaceDir, '.elanous', 'mission-results');
85
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
86
+ const path = join(dir, `classic-pair-synthesis-${safeFilePart(taskId)}-${randomUUID()}.md`);
87
+ writeFileSync(path, buildPairSynthesis(pair, codex, claude), { encoding: 'utf8', mode: 0o600, flag: 'wx' });
88
+ return path;
89
+ }
90
+
91
+ function compactPairNotification(status: 'done' | 'error', body: string, id: string): string {
92
+ const clean = (value: string): string => value.replace(/[\u0000-\u001f\u007f]/g, ' ').replace(/\s+/g, ' ').trim();
93
+ const payload = { status, body: clean(body), id: clean(id).slice(0, 80) || 'pair' };
94
+ let serialized = JSON.stringify(payload);
95
+ while (serialized.length > 500 && payload.body.length > 0) {
96
+ payload.body = payload.body.slice(0, -1);
97
+ serialized = JSON.stringify(payload);
98
+ }
99
+ return serialized;
100
+ }
101
+
102
+ function pairFailurePreview(name: string, result: ClassicSidetabPairOutcome): string {
103
+ const value = result.ok ? result.content?.trim() ?? '' : result.error ?? 'no result returned';
104
+ const redacted = redactMissionResultPath(value, result.path);
105
+ const clean = redacted.replace(/[\u0000-\u001f\u007f]/g, ' ').replace(/\s+/g, ' ').trim();
106
+ return `${name}: ${clean.slice(0, 110)}${clean.length > 110 ? '…' : ''}`;
107
+ }
108
+
25
109
  /** Deliver one eventual sidetab result through the parent's existing task-notification input path. */
26
110
  export function enqueueClassicSidetabMissionCompletion(
27
111
  job: StartedClassicMissionCliJob,
@@ -92,30 +176,34 @@ export function enqueueClassicSidetabMissionPairCompletion(
92
176
  resolve([failure('Codex'), failure('Claude')]);
93
177
  }, Math.max(1, timeoutMs));
94
178
  });
95
- return Promise.race([Promise.all([pair.codex.completion, pair.claude.completion]), timedOut]).then(([codex, claude]) => {
179
+ const rejected = (name: string) => (error: unknown): ClassicSidetabPairOutcome => ({
180
+ ok: false,
181
+ status: 'failed',
182
+ error: `${name} sidetab mission rejected: ${error instanceof Error ? error.message : String(error)}`,
183
+ });
184
+ return Promise.race([
185
+ Promise.all([pair.codex.completion.catch(rejected('Codex')), pair.claude.completion.catch(rejected('Claude'))]),
186
+ timedOut,
187
+ ]).then(([codex, claude]) => {
96
188
  const finishedAt = now();
97
- const ok = codex.ok && claude.ok && Boolean(codex.content?.trim()) && Boolean(claude.content?.trim());
98
- const result = { codex, claude, status: ok ? 'done' as const : 'error' as const, finishedAt };
189
+ const bothSucceeded = codex.ok && claude.ok && Boolean(codex.content?.trim()) && Boolean(claude.content?.trim());
190
+ let synthesisPath: string | undefined;
191
+ let synthesisError: string | undefined;
192
+ try { synthesisPath = persistPairSynthesis(pair, taskId, codex, claude); }
193
+ catch (error) {
194
+ synthesisError = error instanceof Error ? error.message : String(error);
195
+ debug.log('classic-sidetab.mission-pair', 'synthesis-write-failed', { taskId, reason: synthesisError }, { level: 'warn' });
196
+ }
197
+ const ok = bothSucceeded && Boolean(synthesisPath);
198
+ const result: ClassicSidetabMissionPairCompletionResult = {
199
+ codex, claude, status: ok ? 'done' : 'error', finishedAt,
200
+ };
99
201
  try { options.onComplete?.(result); }
100
202
  catch { debug.log('classic-sidetab.mission-pair', 'completion-callback-failed', { taskId, retry: false }); }
101
- let truncated = false;
102
- const body = (name: string, result: ClassicSidetabPairOutcome): string => {
103
- const content = result.content?.trim();
104
- const text = result.ok
105
- ? content ? redactMissionResultPath(content, result.path) : 'completed without an answer'
106
- : redactMissionResultPath(result.error ?? 'no result returned', result.path);
107
- if (text.length > MAX_PAIR_ANSWER_CHARS) truncated = true;
108
- const bounded = text.length > MAX_PAIR_ANSWER_CHARS
109
- ? `${text.slice(0, MAX_PAIR_ANSWER_CHARS)}\n[answer truncated]`
110
- : text;
111
- return result.ok ? `${name} answer:\n${bounded}` : `${name} failed: ${bounded}`;
112
- };
113
- const output = JSON.stringify({
114
- status: ok ? 'done' : 'error',
115
- body: `Concurrent Codex + Claude mission pair (${pair.codex.missionId ?? 'Codex unavailable'} / ${pair.claude.missionId ?? 'Claude unavailable'})\n\n${body('Codex', codex)}\n\n${body('Claude', claude)}`,
116
- artifacts: [],
117
- id: pair.codex.missionId ?? pair.claude.missionId ?? taskId,
118
- });
203
+ const summary = synthesisPath
204
+ ? bothSucceeded ? 'Both missions completed. Full comparison attached.' : 'Pair completed with failures. Full comparison attached.'
205
+ : `Synthesis save failed; ${pairFailurePreview('Codex', codex)}; ${pairFailurePreview('Claude', claude)}`;
206
+ const output = compactPairNotification(ok ? 'done' : 'error', summary, pair.codex.missionId ?? pair.claude.missionId ?? taskId);
119
207
  try {
120
208
  enqueue({
121
209
  taskId,
@@ -124,7 +212,8 @@ export function enqueueClassicSidetabMissionPairCompletion(
124
212
  label: CLASSIC_SIDETAB_MISSION_LABEL,
125
213
  state: ok ? 'done' : 'error',
126
214
  output,
127
- truncated,
215
+ truncated: !synthesisPath,
216
+ ...(synthesisPath ? { resultPath: synthesisPath } : {}),
128
217
  durationMs: Math.max(0, finishedAt - startedAt),
129
218
  finishedAt,
130
219
  });
@@ -148,7 +237,7 @@ export function enqueueClassicSidetabMissionPairCompletion(
148
237
  agentName: 'Codex + Claude',
149
238
  label: CLASSIC_SIDETAB_MISSION_LABEL,
150
239
  state: 'error',
151
- output: JSON.stringify({ status: 'error', body: 'Concurrent Codex/Claude missions failed before results were available', artifacts: [], id: pair.codex.missionId ?? pair.claude.missionId ?? taskId }),
240
+ output: compactPairNotification('error', 'Concurrent Codex/Claude missions failed before results were available', pair.codex.missionId ?? pair.claude.missionId ?? taskId),
152
241
  truncated: false,
153
242
  durationMs: Math.max(0, finishedAt - startedAt),
154
243
  finishedAt,
@@ -55,10 +55,11 @@ export function startClassicSidetabMissionPair<Session extends ClassicSidetabPai
55
55
  // callId is the parent tool invocation identity; falling back to a mission id
56
56
  // preserves queue uniqueness for embedders that do not expose a call id.
57
57
  const taskId = deps.context?.callId || activeCodexMissionId || activeClaudeMissionId || createId();
58
+ const workspaceDir = codexSession?.cwd ?? claudeSession?.cwd ?? '';
58
59
  const completion = missionIds.length
59
60
  ? enqueueClassicSidetabMissionPairCompletion({
60
- codex: { missionId: activeCodexMissionId, taskId, parentSessionId: deps.context?.parentSessionId, startedAt, completion: codexCompletion },
61
- claude: { missionId: activeClaudeMissionId, taskId, parentSessionId: deps.context?.parentSessionId, startedAt, completion: claudeCompletion },
61
+ codex: { missionId: activeCodexMissionId, taskId, parentSessionId: deps.context?.parentSessionId, startedAt, mission: codexPrompt, workspaceDir, completion: codexCompletion },
62
+ claude: { missionId: activeClaudeMissionId, taskId, parentSessionId: deps.context?.parentSessionId, startedAt, mission: claudePrompt, workspaceDir, completion: claudeCompletion },
62
63
  }, deps.enqueue, deps.now, {
63
64
  timeoutMs: deps.timeoutMs,
64
65
  onTimeout: () => { for (const sessionId of sessionIds) if (deps.hasSession(sessionId)) deps.killSession(sessionId); },