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
@@ -4,6 +4,7 @@ import type { BloomResearchQuestion, ResearchEvidenceEnvelope } from '../auto-re
4
4
  import { getAvailableResearchWebSearchProviders } from '../web-search/index.js';
5
5
  import type { WebSearchHit, WebSearchProvider } from '../web-search/provider.js';
6
6
  import { debug } from '../debug/log.js';
7
+ import { dispatchWebFetch } from '../skills/tools/webfetch.js';
7
8
 
8
9
  const RESEARCH_SEARCH_ENGINES = ['exa', 'firecrawl'] as const;
9
10
  const RESEARCH_WEB_FALLBACK_IDS = ['exa', 'firecrawl'] as const;
@@ -42,8 +43,9 @@ export type AxisSearch = (query: string, signal?: AbortSignal, context?: AxisSea
42
43
 
43
44
  export interface AxisFanoutDeps {
44
45
  search?: AxisSearch;
46
+ fetchPage?: (url: string, question: BloomResearchQuestion, signal?: AbortSignal) => Promise<{ url: string; output: string }>;
45
47
  signal?: AbortSignal;
46
- admitToolCall?: (toolName: 'OmniSearch') => boolean;
48
+ admitToolCall?: (toolName: 'OmniSearch' | 'WebFetch') => boolean;
47
49
  }
48
50
 
49
51
  interface ProviderHealth {
@@ -201,15 +203,34 @@ export async function fanOutAxisEvidence(
201
203
  throw new Error('research axis question IDs must be unique');
202
204
  }
203
205
  const search = deps.search ?? createResearchAxisSearcher();
204
- const settled = await Promise.allSettled(plan.map(call => {
206
+ const fetchPage = deps.fetchPage ?? (!deps.search
207
+ ? async (url: string, question: BloomResearchQuestion, signal?: AbortSignal) =>
208
+ dispatchWebFetch({ url, prompt: question.prompt }, { signal })
209
+ : undefined);
210
+ const fetchedQuestions = new Set<string>();
211
+ const settled = await Promise.allSettled(plan.map(async call => {
205
212
  if (deps.admitToolCall && !deps.admitToolCall('OmniSearch')) {
206
- return Promise.resolve({ hits: [], errors: ['research tool budget reached'] } satisfies AxisSearchResult);
213
+ return { hits: [], errors: ['research tool budget reached'] } satisfies AxisSearchResult;
207
214
  }
208
215
  const question = questions.find(candidate => candidate.id === call.questionId)!;
209
- return search(call.query, deps.signal, {
216
+ const raw = await search(call.query, deps.signal, {
210
217
  questionPrompt: question.prompt,
211
218
  requestedWindow: question.requestedWindow,
212
219
  });
220
+ const response = Array.isArray(raw) ? { hits: raw, errors: [] } : raw;
221
+ if (!fetchPage || response.hits.length === 0 || fetchedQuestions.has(question.id)) return response;
222
+ fetchedQuestions.add(question.id);
223
+ if (deps.admitToolCall && !deps.admitToolCall('WebFetch')) return response;
224
+ try {
225
+ const page = await fetchPage(response.hits[0]!.url, question, deps.signal);
226
+ return { ...response, fetchedPage: page };
227
+ } catch (error) {
228
+ const message = error instanceof Error ? error.message : String(error);
229
+ debug.log('research.search', 'native-fetch-failed', {
230
+ questionId: question.id, reason: message.slice(0, 200),
231
+ }, { level: 'warn' });
232
+ return response;
233
+ }
213
234
  }));
214
235
  const axes: AxisEvidenceGroup[] = questions.map(question => ({ questionId: question.id, evidence: [] }));
215
236
  const groups = new Map(axes.map(axis => [axis.questionId, axis]));
@@ -226,10 +247,24 @@ export async function fanOutAxisEvidence(
226
247
  const group = groups.get(call.questionId)!;
227
248
  const question = byQuestion.get(call.questionId)!;
228
249
  if (outcome.status === 'fulfilled') {
229
- const response = Array.isArray(outcome.value) ? { hits: outcome.value, errors: [] } : outcome.value;
250
+ const response = outcome.value;
230
251
  if (response.hits.length === 0 && response.errors.length === 0) {
231
252
  group.evidence.push({ ...failedEvidence(question, call.query, 'no hits returned'), outcome: 'partial' });
232
253
  }
254
+ const fetchedPage = 'fetchedPage' in response ? response.fetchedPage : undefined;
255
+ if (fetchedPage) {
256
+ const content = fetchedPage.output;
257
+ const excerpt = Array.from(content).slice(0, 8_000).join('');
258
+ group.evidence.push({
259
+ questionId: question.id,
260
+ sourceKind: 'web-fetch',
261
+ source: fetchedPage.url,
262
+ ...(question.requestedWindow ? { requestedWindow: question.requestedWindow } : {}),
263
+ content: excerpt,
264
+ outcome: excerpt ? 'complete' : 'partial',
265
+ truncated: Array.from(content).length > 8_000,
266
+ });
267
+ }
233
268
  for (const hit of response.hits) {
234
269
  try {
235
270
  group.evidence.push(evidenceFromHit(question, hit));
@@ -0,0 +1,312 @@
1
+ /** Chain order a synthesis step lands in: what happens first, what that causes, what that settles. */
2
+ export type SecondOrderOrder = 'primary' | 'secondary' | 'tertiary';
3
+
4
+ export interface SecondOrderLensStage {
5
+ order: SecondOrderOrder;
6
+ label: string;
7
+ horizonDays: number;
8
+ purpose: string;
9
+ }
10
+
11
+ /** Public lens definition: what the T2 second-order lens is and which orders it fans a synthesis into. */
12
+ export interface SecondOrderLensDefinition {
13
+ id: string;
14
+ cell: string;
15
+ tier: string;
16
+ rfc: string;
17
+ description: string;
18
+ stages: readonly SecondOrderLensStage[];
19
+ }
20
+
21
+ /** Public verification format attached to every secondary effect. */
22
+ export interface SecondOrderVerificationNode {
23
+ claim: string;
24
+ scenarioCondition: string | null;
25
+ metric: string | null;
26
+ expectedValue: number | null;
27
+ threshold: number | null;
28
+ unit: string | null;
29
+ windowDays: number;
30
+ falsifiable: boolean | null;
31
+ measurementStatus: 'unmeasured' | 'needs-operationalization';
32
+ evidenceSource: string | null;
33
+ }
34
+
35
+ export interface SecondOrderEvidenceFact {
36
+ questionId: string;
37
+ question: string;
38
+ content: string;
39
+ source: string;
40
+ outcome: 'complete' | 'partial' | 'failed';
41
+ observedWindow?: string;
42
+ units?: string;
43
+ }
44
+
45
+ export interface SecondOrderChainNode {
46
+ id: string;
47
+ order: SecondOrderOrder;
48
+ orderIndex: 1 | 2 | 3;
49
+ statement: string;
50
+ horizonDays: number;
51
+ derivedFrom: readonly string[];
52
+ verification: SecondOrderVerificationNode | null;
53
+ }
54
+
55
+ /** Public result-chain format: primary → secondary → tertiary, with secondary effects verified. */
56
+ export interface SecondOrderResultChain {
57
+ lensId: string;
58
+ question: string;
59
+ orderStages: readonly SecondOrderLensStage[];
60
+ nodes: readonly SecondOrderChainNode[];
61
+ }
62
+
63
+ export type SecondOrderTriggerKind = 'decision' | 'forecast' | 'none';
64
+
65
+ export interface SecondOrderTriggerDecision {
66
+ triggered: boolean;
67
+ kind: SecondOrderTriggerKind;
68
+ score: number;
69
+ matchedSignals: readonly string[];
70
+ reason: string;
71
+ }
72
+
73
+ export interface SecondOrderLensInput {
74
+ question: string;
75
+ synthesis: readonly string[];
76
+ /** IDs must align with synthesis; evidence is joined by questionId, never by flat-array position. */
77
+ synthesisQuestionIds?: readonly string[];
78
+ evidenceFacts?: readonly SecondOrderEvidenceFact[];
79
+ }
80
+
81
+ export interface SecondOrderLensResult {
82
+ lens: SecondOrderLensDefinition;
83
+ trigger: SecondOrderTriggerDecision;
84
+ chain: SecondOrderResultChain | null;
85
+ }
86
+
87
+ /** Injection seam lets a host supply private trigger calibration without shipping it here. */
88
+ export type SecondOrderTriggerClassifier = (question: string) => SecondOrderTriggerDecision;
89
+
90
+ export const SECOND_ORDER_LENS: SecondOrderLensDefinition = {
91
+ id: 'second-order',
92
+ cell: 'THINK-LENS-T2-SECOND-ORDER',
93
+ tier: 'T2',
94
+ rfc: 'RFC-PRO §2',
95
+ description: '결정·예측 질문에서 6단 종합을 1차 → 2차 → 3차 결과 사슬로 펼치고, 2차 효과마다 검증 노드를 붙인다.',
96
+ stages: [
97
+ {
98
+ order: 'primary',
99
+ label: '1차 결과',
100
+ horizonDays: 30,
101
+ purpose: '결정이나 예측이 직접 만드는 즉시 효과',
102
+ },
103
+ {
104
+ order: 'secondary',
105
+ label: '2차 결과',
106
+ horizonDays: 180,
107
+ purpose: '1차 효과가 다른 주체로 전이되며 생기는 효과 — 검증 노드가 붙는 자리',
108
+ },
109
+ {
110
+ order: 'tertiary',
111
+ label: '3차 결과',
112
+ horizonDays: 540,
113
+ purpose: '2차 효과가 구조·규범·시장에 정착하며 생기는 효과',
114
+ },
115
+ ],
116
+ };
117
+
118
+ const DECISION_QUESTION_FORM = /(?:해야\s*(?:할까|하나|할지)|(?:고르|선택|결정|전환|도입|투자|진입|매수|매도)(?:해야\s*(?:할까|하나|할지)|할까|할지\s*(?:말지|여부)))|\b(?:should\s+(?:i|we)|whether\s+to|choose\s+between|decide\s+whether)\b/i;
119
+ const FORECAST_QUESTION_FORM = /(?:얼마나\s+[^?\n]{0,80}(?:될|오를|내릴|늘어날|줄어들|바뀔|변할)|(?:언제|몇)\s+[^?\n]{0,80}(?:될|오를|내릴|늘어날|줄어들|바뀔)|어떻게\s+(?:될까|변할까))|\b(?:how\s+much|how\s+many)\s+(?:will|might|could|is\s+expected\s+to|is\s+projected\s+to)\b.{0,120}\b(?:rise|fall|grow|shrink|change|cost|be)\b|\b(?:when\s+will|what\s+will)\b.{0,120}\b(?:rise|fall|grow|shrink|change|cost|be)\b|\bwill\s+[^?\n]{1,120}\b(?:increase|decrease|rise|fall|grow|shrink|change|cost|remain|reach|exceed|decline)\b/i;
120
+
121
+ /** Decide whether a question is a decision or a forecast, i.e. whether the second-order lens applies. */
122
+ export function detectSecondOrderTrigger(question: string): SecondOrderTriggerDecision {
123
+ const text = requireText(question, 'question').toLowerCase();
124
+ if (!/[??]\s*$/u.test(text)) return noTrigger();
125
+ const decision = DECISION_QUESTION_FORM.exec(text);
126
+ const forecast = FORECAST_QUESTION_FORM.exec(text);
127
+ const kind: SecondOrderTriggerKind = decision ? 'decision' : forecast ? 'forecast' : 'none';
128
+ const score = kind === 'none' ? 0 : 1;
129
+ const matchedSignals = Object.freeze(kind === 'decision' ? ['decision-form'] : kind === 'forecast' ? ['forecast-form'] : []);
130
+ if (kind === 'none') {
131
+ return {
132
+ triggered: false,
133
+ kind: 'none',
134
+ score,
135
+ matchedSignals,
136
+ reason: '질문이 결정이나 예측이 아니라 결과 사슬을 펼치지 않는다',
137
+ };
138
+ }
139
+ return {
140
+ triggered: true,
141
+ kind,
142
+ score,
143
+ matchedSignals,
144
+ reason: kind === 'decision'
145
+ ? '결정 질문이므로 1차 → 2차 → 3차 결과 사슬을 펼친다'
146
+ : '예측 질문이므로 1차 → 2차 → 3차 결과 사슬을 펼친다',
147
+ };
148
+ }
149
+
150
+ function noTrigger(): SecondOrderTriggerDecision {
151
+ return {
152
+ triggered: false,
153
+ kind: 'none',
154
+ score: 0,
155
+ matchedSignals: Object.freeze([]),
156
+ reason: '결정·예측 질문형이 아니므로 결과 사슬을 펼치지 않는다',
157
+ };
158
+ }
159
+
160
+ /** Expand synthesis steps into a primary → secondary → tertiary chain with a verification node on each secondary effect. */
161
+ export function buildSecondOrderResultChain(input: SecondOrderLensInput): SecondOrderResultChain {
162
+ const question = requireText(input.question, 'question');
163
+ const steps = input.synthesis.map((step, index) => requireText(step, `synthesis[${index}]`));
164
+ if (input.evidenceFacts?.length && input.synthesisQuestionIds?.length !== steps.length) {
165
+ throw new Error('synthesisQuestionIds must align with synthesis when evidenceFacts are supplied');
166
+ }
167
+ if (steps.length < SECOND_ORDER_LENS.stages.length) {
168
+ throw new Error('synthesis requires at least three steps to expand into a result chain');
169
+ }
170
+
171
+ const buckets = splitIntoOrders(steps, SECOND_ORDER_LENS.stages.length);
172
+ const nodes: SecondOrderChainNode[] = [];
173
+ let previousIds: string[] = [];
174
+ for (const [stageIndex, stage] of SECOND_ORDER_LENS.stages.entries()) {
175
+ const stageIds: string[] = [];
176
+ for (const [stepIndex, statement] of buckets[stageIndex]!.entries()) {
177
+ const inputIndex = buckets.slice(0, stageIndex).reduce((count, bucket) => count + bucket.length, 0) + stepIndex;
178
+ const questionId = input.synthesisQuestionIds?.[inputIndex];
179
+ const fact = questionId ? combineQuestionEvidence(questionId, input.evidenceFacts ?? []) : undefined;
180
+ const id = `${stage.order}-${stepIndex + 1}`;
181
+ stageIds.push(id);
182
+ const parentIndex = stageIndex === 0 ? -1 : Math.min(stepIndex, previousIds.length - 1);
183
+ const parentId = parentIndex >= 0 ? previousIds[parentIndex] : undefined;
184
+ const parent = parentId ? nodes.find((node) => node.id === parentId) : undefined;
185
+ const outputStatement = fact
186
+ ? makeOutcomeHypothesis(stage.order, question, fact, parent?.statement)
187
+ : stage.order === 'primary'
188
+ ? `1차 가설: ${statement}`
189
+ : `${stage.order === 'secondary' ? '2차' : '3차'} 가설: ${parent?.statement ?? '앞 단계 결과'}가 이어지면 ${statement}라는 후속 결과가 생길 수 있다.`;
190
+ nodes.push({
191
+ id,
192
+ order: stage.order,
193
+ orderIndex: (stageIndex + 1) as 1 | 2 | 3,
194
+ statement: outputStatement,
195
+ horizonDays: stage.horizonDays,
196
+ derivedFrom: Object.freeze(parentId ? [parentId] : []),
197
+ verification: stage.order === 'secondary'
198
+ ? buildVerificationNode(outputStatement, fact, stepIndex)
199
+ : null,
200
+ });
201
+ }
202
+ previousIds = stageIds;
203
+ }
204
+
205
+ return {
206
+ lensId: SECOND_ORDER_LENS.id,
207
+ question,
208
+ orderStages: SECOND_ORDER_LENS.stages,
209
+ nodes: Object.freeze(nodes),
210
+ };
211
+ }
212
+
213
+ /** Run the lens: the trigger decides whether a chain is produced at all. */
214
+ export function applySecondOrderLens(
215
+ input: SecondOrderLensInput,
216
+ classifyTrigger: SecondOrderTriggerClassifier = detectSecondOrderTrigger,
217
+ ): SecondOrderLensResult {
218
+ const trigger = classifyTrigger(input.question);
219
+ if (!trigger.triggered) return { lens: SECOND_ORDER_LENS, trigger, chain: null };
220
+ return { lens: SECOND_ORDER_LENS, trigger, chain: buildSecondOrderResultChain(input) };
221
+ }
222
+
223
+ function buildVerificationNode(statement: string, fact: SecondOrderEvidenceFact | undefined, index: number): SecondOrderVerificationNode {
224
+ const metric = fact?.outcome === 'complete' ? extractObservableMetric(fact.content) : null;
225
+ const windowDays = 90 * (index + 1);
226
+ const scenarioCondition = metric && fact
227
+ ? `${fact.observedWindow ? `${fact.observedWindow} 기준선` : '확인 가능한 기준선'}과 ${windowDays}일 뒤 ${metric}을 비교한다. 판정 임계값은 아직 정하지 않았다.`
228
+ : null;
229
+ return {
230
+ claim: statement,
231
+ scenarioCondition,
232
+ metric,
233
+ expectedValue: null,
234
+ threshold: null,
235
+ unit: fact?.units ?? null,
236
+ windowDays,
237
+ falsifiable: null,
238
+ measurementStatus: metric ? 'needs-operationalization' : 'unmeasured',
239
+ evidenceSource: fact?.source ?? null,
240
+ };
241
+ }
242
+
243
+ function splitIntoOrders(steps: readonly string[], orderCount: number): string[][] {
244
+ const base = Math.floor(steps.length / orderCount);
245
+ const remainder = steps.length % orderCount;
246
+ const buckets: string[][] = [];
247
+ let cursor = 0;
248
+ for (let index = 0; index < orderCount; index += 1) {
249
+ const size = base + (index < remainder ? 1 : 0);
250
+ buckets.push(steps.slice(cursor, cursor + size));
251
+ cursor += size;
252
+ }
253
+ return buckets;
254
+ }
255
+
256
+ function makeOutcomeHypothesis(
257
+ order: SecondOrderOrder,
258
+ question: string,
259
+ fact: SecondOrderEvidenceFact,
260
+ parentStatement?: string,
261
+ ): string {
262
+ const detail = compactEvidence(fact.content);
263
+ const citation = `[${fact.questionId}; ${fact.source}; ${fact.outcome}]`;
264
+ if (fact.outcome !== 'complete') {
265
+ return `${order === 'primary' ? '1차' : order === 'secondary' ? '2차' : '3차'} 가설 미작성: ${fact.question}에 대한 완전한 근거를 확보하지 못했다 (${fact.outcome}; ${citation}).`;
266
+ }
267
+ if (order === 'primary') return `1차 가설: 「${question}」의 직접 효과 후보는 「${detail}」이다. 근거 ${citation}`;
268
+ if (order === 'secondary') return `2차 가설: 「${parentStatement ?? '직접 결과'}」가 이어질 경우 「${detail}」라는 후속 효과가 생길 수 있다. 근거 ${citation}`;
269
+ return `3차 가설: 「${parentStatement ?? '2차 효과'}」가 지속될 경우 「${detail}」라는 장기 결과로 이어질 수 있다. 근거 ${citation}`;
270
+ }
271
+
272
+ function compactEvidence(value: string): string {
273
+ const normalized = value.replace(/\s+/g, ' ').trim();
274
+ return normalized.length > 180 ? `${normalized.slice(0, 177)}…` : normalized;
275
+ }
276
+
277
+ function combineQuestionEvidence(questionId: string, evidenceFacts: readonly SecondOrderEvidenceFact[]): SecondOrderEvidenceFact | undefined {
278
+ const matching = evidenceFacts.filter((fact) => fact.questionId === questionId);
279
+ if (!matching.length) return undefined;
280
+ const complete = matching.filter((fact) => fact.outcome === 'complete');
281
+ const selected = complete.length ? complete : matching;
282
+ const units = [...new Set(selected.map((fact) => fact.units).filter((unit): unit is string => Boolean(unit)))].join(', ');
283
+ const observedWindow = [...new Set(selected.map((fact) => fact.observedWindow).filter((window): window is string => Boolean(window)))].join(', ');
284
+ return {
285
+ questionId,
286
+ question: selected[0]!.question,
287
+ content: selected.map((fact) => fact.content).join(' · '),
288
+ source: [...new Set(selected.map((fact) => fact.source))].join(', '),
289
+ outcome: complete.length ? 'complete' : selected.some((fact) => fact.outcome === 'partial') ? 'partial' : 'failed',
290
+ ...(observedWindow ? { observedWindow } : {}),
291
+ ...(units ? { units } : {}),
292
+ };
293
+ }
294
+
295
+ function extractObservableMetric(value: string): string | null {
296
+ const patterns = [
297
+ /(?:응답\s*시간|처리\s*시간|처리량|대기\s*시간|전환율|이탈률|잔존율|오류율|정확도|매출|수익|비용|수출액|수출량|문의\s*건수|사용자\s*수|판매량|생산성|파이프라인)/iu,
298
+ /\b(?:response time|processing time|wait time|conversion rate|churn rate|retention rate|error rate|accuracy|revenue|cost|export volume|inquiry count|user count|sales volume|productivity|pipeline|adoption rate|demand)\b/iu,
299
+ ];
300
+ for (const pattern of patterns) {
301
+ const match = value.match(pattern);
302
+ if (match?.[0]) return match[0].replace(/\s+/g, ' ').trim();
303
+ }
304
+ return null;
305
+ }
306
+
307
+ function requireText(value: unknown, field: string): string {
308
+ if (typeof value !== 'string' || value.trim().length === 0) {
309
+ throw new Error(`${field} must not be empty`);
310
+ }
311
+ return value.trim();
312
+ }
@@ -930,7 +930,9 @@ export function startDraftTriage(
930
930
  const inventory = inventories.find((entry) => entry.repository === repository)?.snapshot;
931
931
  const enriched = { ...draft, branch: draft.branch ?? '', ...inventoryByUrl.get(draft.url!) };
932
932
  if ((!inventory || !inventoryByUrl.has(draft.url!)) && !IN_TEST_PROCESS()) { unobservedDrafts.push(draft.number); continue; }
933
- const decision = decideDraft({ draft: enriched, runStatus: resolvedStatus, mergedTwins: inventory?.merged ?? [], ageHours: (nowMs() - draft.openedAtMs) / 3_600_000, liveBranches });
933
+ const triageNow = nowMs();
934
+ const decision = decideDraft({ draft: enriched, now: new Date(triageNow), runStatus: resolvedStatus,
935
+ mergedTwins: inventory?.merged ?? [], ageHours: (triageNow - draft.openedAtMs) / 3_600_000, liveBranches });
934
936
  if (decision.reason.startsWith('superseded-by')) decisions.superseded += 1;
935
937
  else if (decision.reason === 'stale-ended-run') decisions.staleEndedRun += 1;
936
938
  else if (decision.reason.startsWith('label:')) decisions.humanApproval += 1; // approval-waiting or human «keep»
@@ -1,6 +1,6 @@
1
1
  import { CLAIM_IDLE_HOURS, PR_LABELS, STALLED_DRAFT_HOURS } from '../github/pr-labels.js';
2
2
  import { debug } from '../debug/log.js';
3
- import { assessDraftTriage, decideDraft, draftClaimComment, draftClaimState, draftReleaseComment, laterMergedTwins, sameGoalPr, PROTECTED_LABELS, type DraftTriageAssessment, type DraftTriagePr, type DraftTriageReviewState } from './draft-triage-rules.js';
3
+ import { assessDraftTriage, decideDraft, draftClaimComment, draftClaimState, draftIntentHoldReason, draftIntentHoldRejection, draftReleaseComment, harvestDeferredMarker, laterMergedTwins, parseDraftIntentHold, sameGoalPr, PROTECTED_LABELS, type DraftTriageAssessment, type DraftTriagePr, type DraftTriageReviewState } from './draft-triage-rules.js';
4
4
  import { cellIdFromBody } from '../pr-tool/census.js';
5
5
  import { RELEASE_PATH_LABEL } from './release-path-guard.js';
6
6
  import { cardPrNumber, draftTaskOwner, type TaskCard } from '../task-agent/task-hand.js';
@@ -659,12 +659,14 @@ export function resolveDraftSweepCloseCap(input: { flag?: unknown; config?: unkn
659
659
  export async function supersedeDraftsOnMerge(input: {
660
660
  repository: string;
661
661
  merged: SweepMergedPr & { createdAt: string; mergedAt: string };
662
+ now?: Date;
662
663
  /** `pr land` and HQ train invoke only the explicit same-cell successor path. */
663
664
  onlyExplicitSameCell?: boolean;
664
665
  adapters: Pick<DraftSweepAdapters, 'listDrafts' | 'listLiveBranches' | 'getRunStatus' | 'setLabels' | 'closeDraft'>
665
666
  & Pick<Partial<DraftSweepAdapters>, 'getLatestFileChanges' | 'getPrFiles' | 'commentDraft' | 'listIssueComments'>;
666
667
  }): Promise<{ closed: number[]; kept: number[] }> {
667
668
  const { repository, merged, adapters } = input;
669
+ const now = input.now ?? new Date();
668
670
  const closed: number[] = [];
669
671
  const kept: number[] = [];
670
672
  let drafts: SweepDraft[] = [];
@@ -691,6 +693,7 @@ export async function supersedeDraftsOnMerge(input: {
691
693
  const old = drafts.find((draft) => draft.number === explicitOld);
692
694
  if (old && cellIdFromBody(old.body ?? '') === mergedCell
693
695
  && Date.parse(old.createdAt) < Date.parse(merged.mergedAt)
696
+ && !parseDraftIntentHold(old.body, now)
694
697
  && !old.labels.some((label) => PROTECTED_LABELS.has(label))
695
698
  && PR_LABELS.filter((label) => label.axis === 'state' && old.labels.includes(label.name)).length <= 1) {
696
699
  const marker = `<!-- elanous:same-cell-superseded #${old.number} -> #${merged.number} -->`;
@@ -745,7 +748,7 @@ export async function supersedeDraftsOnMerge(input: {
745
748
  kept.push(draft.number);
746
749
  continue;
747
750
  }
748
- const decision = decideDraft({ draft, runStatus: statuses.get(draft.number),
751
+ const decision = decideDraft({ draft, now, runStatus: statuses.get(draft.number),
749
752
  mergedTwins: [landed], liveBranches, ageHours: NaN });
750
753
  if (decision.action !== 'close' || !decision.reason.startsWith(`superseded-by #${merged.number}`)
751
754
  || PR_LABELS.filter((entry) => entry.axis === 'state' && draft.labels.includes(entry.name)).length > 1
@@ -1345,6 +1348,16 @@ export async function runDraftSweep({ repository, adapters, apply = false, now =
1345
1348
  ...(claimWriteFailed ? { error: claimWriteError, ...(claimPartialApplied ? { partialApplied: true } : {}) } : {}) });
1346
1349
  continue;
1347
1350
  }
1351
+ // DRAFT-ZERO's failed-run harvest evidence remains the strongest explicit hold; this intent marker
1352
+ // must not rewrite its reason or mask the harvest classification.
1353
+ if (runStatus === 'failed' && harvestDeferredMarker(draft.body)) {
1354
+ record({ number: draft.number, action: 'keep', reason: 'harvest-deferred', applied: false });
1355
+ continue;
1356
+ }
1357
+ const intentHoldRejection = draftIntentHoldRejection(draft.body, now);
1358
+ if (intentHoldRejection) {
1359
+ try { debug.log('self-dev.draft-sweep', 'intent-hold-rejected', { pr: draft.number, reason: intentHoldRejection }); } catch { /* fail-soft */ }
1360
+ }
1348
1361
  if (draft.labels.includes(releaseHoldLabel ?? '') || draft.labels.includes(RELEASE_PATH_LABEL)
1349
1362
  || (!contradiction && draft.labels.includes(keepLabel ?? ''))) {
1350
1363
  const held = draft.labels.includes(keepLabel ?? '') ? keepLabel
@@ -1352,6 +1365,19 @@ export async function runDraftSweep({ repository, adapters, apply = false, now =
1352
1365
  record({ number: draft.number, action: 'keep', reason: `label:${held}`, applied: false });
1353
1366
  continue;
1354
1367
  }
1368
+ // Outside-harness drafts keep their established jurisdiction reason, even when they carry a valid marker.
1369
+ if (!contradiction && !states.length && !draft.branch.startsWith('self-impl/')) {
1370
+ record({ number: draft.number, action: 'keep', reason: 'outside-harness', applied: false });
1371
+ continue;
1372
+ }
1373
+ const intentHold = parseDraftIntentHold(draft.body, now);
1374
+ if (intentHold) {
1375
+ const reason = draftIntentHoldReason(intentHold);
1376
+ record({ number: draft.number, action: 'keep', reason, applied: false });
1377
+ try { debug.log('self-dev.draft-sweep', 'intent-hold-kept', { pr: draft.number, owner: intentHold.owner,
1378
+ reason: intentHold.reason, expiresAt: intentHold.expiresAt }); } catch { /* fail-soft */ }
1379
+ continue;
1380
+ }
1355
1381
  const claimState = contradiction ? 'unclaimed' : draftClaimState(draft, now);
1356
1382
  const isClaimed = claimState !== 'unclaimed';
1357
1383
  const ageHours = (now.getTime() - Date.parse(draft.createdAt)) / 3_600_000;
@@ -1368,7 +1394,7 @@ export async function runDraftSweep({ repository, adapters, apply = false, now =
1368
1394
  const cellNewer = contradiction || lineageNewer ? undefined : newerSameCellDraft(draft, drafts);
1369
1395
  const duplicateNewer = lineageNewer ?? cellNewer;
1370
1396
  if (duplicateNewer) {
1371
- const base = decideDraft({ draft, runStatus, mergedTwins: merged, openDrafts: drafts, liveBranches,
1397
+ const base = decideDraft({ draft, now, runStatus, mergedTwins: merged, openDrafts: drafts, liveBranches,
1372
1398
  finalRunResult, ageHours: runStatus ? ageHours : idleHours });
1373
1399
  if (!base.reason.startsWith('label:') && !base.reason.startsWith('superseded-by #') && !base.reason.startsWith('duplicate-of-open #')) {
1374
1400
  const runLive = isLiveDraftRun(runStatus, draft.branch, liveBranches);
@@ -1457,7 +1483,7 @@ export async function runDraftSweep({ repository, adapters, apply = false, now =
1457
1483
  }
1458
1484
  // An unobserved claim may still have a merged twin: liveness/holds retain their priority,
1459
1485
  // but a superseded draft must not be hidden by the six-hour claim window.
1460
- const mergedDecision = isClaimed ? decideDraft({ draft, runStatus, mergedTwins: merged, openDrafts: drafts, liveBranches,
1486
+ const mergedDecision = isClaimed ? decideDraft({ draft, now, runStatus, mergedTwins: merged, openDrafts: drafts, liveBranches,
1461
1487
  finalRunResult, ageHours: idleHours }) : undefined;
1462
1488
  const supersededClaim = mergedDecision?.reason.startsWith('superseded-by #') === true
1463
1489
  || mergedDecision?.reason.startsWith('duplicate-of-open #') === true;
@@ -1509,12 +1535,7 @@ export async function runDraftSweep({ repository, adapters, apply = false, now =
1509
1535
  }
1510
1536
  continue;
1511
1537
  }
1512
- // Unlabelled non-harness drafts are outside the sweeper's jurisdiction.
1513
- if (!contradiction && !states.length && !draft.branch.startsWith('self-impl/')) {
1514
- record({ number: draft.number, action: 'keep', reason: 'outside-harness', applied: false });
1515
- continue;
1516
- }
1517
- let decision = supersededClaim ? mergedDecision! : decideDraft({ draft, runStatus, mergedTwins: merged, openDrafts: drafts, liveBranches,
1538
+ let decision = supersededClaim ? mergedDecision! : decideDraft({ draft, now, runStatus, mergedTwins: merged, openDrafts: drafts, liveBranches,
1518
1539
  finalRunResult, ageHours: runStatus ? ageHours : idleHours });
1519
1540
  const fallback = decision.reason === 'unobserved' || decision.reason === 'stale-unobserved'
1520
1541
  || decision.reason === 'recent' || decision.reason.startsWith('recent (') || decision.reason.startsWith('stale-ended-run');
@@ -23,12 +23,64 @@ export function draftClaimRecordLive(at: string, now: Date): boolean {
23
23
  return Number.isFinite(updated) && (now.getTime() - updated) / 3_600_000 < CLAIM_IDLE_HOURS;
24
24
  }
25
25
 
26
+ export interface DraftIntentHold {
27
+ readonly owner: string;
28
+ readonly reason: string;
29
+ readonly expiresAt: string;
30
+ }
31
+
32
+ function inspectDraftIntentHold(body: string | undefined, now = new Date()): { hold?: DraftIntentHold; rejection?: string } {
33
+ if (!body || !body.includes('<!-- elanous:draft-intent-hold')) return {};
34
+ if (!Number.isFinite(now.getTime())) return { rejection: 'invalid-sweep-time' };
35
+ const matches = [...body.matchAll(/<!-- elanous:draft-intent-hold ([\s\S]*?) -->/g)];
36
+ const markerStarts = body.match(/<!-- elanous:draft-intent-hold\b/g) ?? [];
37
+ if (matches.length !== 1 || markerStarts.length !== 1) return { rejection: 'marker-count-or-termination' };
38
+ const raw = matches[0]![1]!;
39
+ let value: unknown;
40
+ try { value = JSON.parse(raw); } catch { return { rejection: 'invalid-json' }; }
41
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return { rejection: 'invalid-shape' };
42
+ const row = value as Record<string, unknown>;
43
+ if (Object.keys(row).length !== 3 || !Object.hasOwn(row, 'owner') || !Object.hasOwn(row, 'reason') || !Object.hasOwn(row, 'expiresAt')) {
44
+ return { rejection: 'invalid-fields' };
45
+ }
46
+ const { owner, reason, expiresAt } = row;
47
+ if (typeof owner !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/.test(owner)
48
+ || typeof reason !== 'string' || !reason.trim() || reason !== reason.trim() || reason.length > 240
49
+ || /[\r\n;=]/.test(reason) || reason.includes('-->')
50
+ || typeof expiresAt !== 'string' || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(expiresAt)) {
51
+ return { rejection: 'invalid-fields' };
52
+ }
53
+ // Compare against the one writer-defined field order. JSON.stringify(parsedObject) alone preserves
54
+ // incoming key order and would silently accept alternate serializations or duplicate keys.
55
+ if (JSON.stringify({ owner, reason, expiresAt }) !== raw) return { rejection: 'noncanonical-json' };
56
+ const expiry = Date.parse(expiresAt);
57
+ if (!Number.isFinite(expiry) || new Date(expiry).toISOString() !== expiresAt) return { rejection: 'invalid-expiry' };
58
+ if (expiry <= now.getTime()) return { rejection: 'expired' };
59
+ return { hold: { owner, reason: reason.trim(), expiresAt } };
60
+ }
61
+
62
+ /** Only one canonical, complete, unexpired body marker is a hold; malformed or ambiguous markers fail open to normal triage. */
63
+ export function parseDraftIntentHold(body: string | undefined, now = new Date()): DraftIntentHold | undefined {
64
+ return inspectDraftIntentHold(body, now).hold;
65
+ }
66
+
67
+ /** Diagnostic for a present but rejected hold marker; absence is not an error. */
68
+ export function draftIntentHoldRejection(body: string | undefined, now = new Date()): string | undefined {
69
+ return inspectDraftIntentHold(body, now).rejection;
70
+ }
71
+
72
+ export function draftIntentHoldReason(hold: DraftIntentHold): string {
73
+ return `intent-hold owner=${hold.owner}; reason=${hold.reason}; expiresAt=${hold.expiresAt}`;
74
+ }
75
+
26
76
  export interface DraftTriagePr {
27
77
  number: number;
28
78
  title?: string;
29
79
  branch: string;
30
80
  labels?: readonly string[];
31
81
  body?: string;
82
+ /** Last PR update (push, label, comment); absence is not an expiry timestamp. */
83
+ updatedAt?: string;
32
84
  mergeCommitMessage?: string;
33
85
  landingVerifiedComments?: readonly string[];
34
86
  createdAt?: string;
@@ -109,7 +161,8 @@ export function assessDraftTriage(input: DraftTriageAssessmentInput): DraftTriag
109
161
  const clock = now.getTime();
110
162
  const ageHours = Number.isFinite(latestCommit) && Number.isFinite(clock) ? (clock - latestCommit) / 3_600_000 : NaN;
111
163
  const protectedLabel = (draft.labels ?? []).find((name) => CLOSE_PROTECTED_LABELS.has(name));
112
- const protectedState = Boolean(protectedLabel);
164
+ const intentHold = parseDraftIntentHold(draft.body, now);
165
+ const protectedState = Boolean(protectedLabel || intentHold);
113
166
  const running = input.runStatus === 'running' || input.runStatus === 'probable-running'
114
167
  || (draft.labels ?? []).includes('elanous:running');
115
168
  const cellComplete = input.cellStatus === 'green' || input.cellStatus === 'done';
@@ -146,7 +199,8 @@ export function assessDraftTriage(input: DraftTriageAssessmentInput): DraftTriag
146
199
  : { state: 'unknown', evidence: '현재 adapter는 같은 칸 병합 PR과 이 초안의 대체 관계를 증명하지 않음; follow-up 필요' },
147
200
  'newer-same-card': { state: input.newerSameCellSameCard === undefined ? 'unknown' : input.newerSameCellSameCard ? 'yes' : 'no', evidence: `${input.newerSameCellSameCard === undefined ? '같은 칸·카드 새 draft 관계 미관측' : `same-cell-same-card-newer=${input.newerSameCellSameCard}`}; 관측 표지이며 대체 증거가 아님` },
148
201
  'idle-48h': { state: Number.isFinite(ageHours) ? (idle48h ? 'yes' : 'no') : 'unknown', evidence: Number.isFinite(ageHours) ? `head age=${ageHours.toFixed(1)}h` : 'head commit 시각 미관측' },
149
- protected: { state: protectedState ? 'yes' : 'no', evidence: protectedLabel ? `보호 표지=${protectedLabel}` : '보호 표지 없음' },
202
+ protected: { state: protectedState ? 'yes' : 'no', evidence: protectedLabel ? `보호 표지=${protectedLabel}`
203
+ : intentHold ? draftIntentHoldReason(intentHold) : '보호 표지 없음' },
150
204
  'recent-commit': { state: Number.isFinite(latestCommit) ? (recentCommit ? 'yes' : 'no') : 'unknown', evidence: Number.isFinite(latestCommit) ? `last commit=${draft.latestCommitAt}; cutoff=09:30 KST` : 'head commit 시각 미관측' },
151
205
  running: { state: running ? 'yes' : runNotRunning ? 'no' : 'unknown', evidence: running ? `run=${input.runStatus ?? 'elanous:running'}` : runNotRunning ? `종결 run=${input.runStatus}` : `run 상태 미관측${input.runStatus ? ` (${input.runStatus})` : ''}` },
152
206
  'owner-confirmed': { state: input.ownerConfirmed === undefined ? 'unknown' : input.ownerConfirmed ? 'yes' : 'no', evidence: input.ownerConfirmed === undefined ? '소유자 출처 미관측' : input.ownerConfirmed ? '고유 카드 또는 활성 claim owner 확인' : '고유 소유자 없음' },
@@ -161,6 +215,7 @@ export function assessDraftTriage(input: DraftTriageAssessmentInput): DraftTriag
161
215
 
162
216
  export interface DraftTriageInput {
163
217
  draft: DraftTriagePr;
218
+ now?: Date;
164
219
  runStatus: string | undefined;
165
220
  mergedTwins: readonly DraftTriagePr[];
166
221
  openDrafts?: readonly DraftTriagePr[];
@@ -251,10 +306,12 @@ export function harvestDeferredMarker(body: string | undefined): boolean {
251
306
  && rows.length > 0 && rows.every((value) => value === HARVEST_DEFERRED_MARKER_VALUE);
252
307
  }
253
308
 
254
- export function decideDraft({ draft, runStatus, mergedTwins, openDrafts, ageHours, liveBranches, finalRunResult }: DraftTriageInput): DraftDecision {
309
+ export function decideDraft({ draft, runStatus, mergedTwins, openDrafts, ageHours, liveBranches, finalRunResult, now = new Date() }: DraftTriageInput): DraftDecision {
255
310
  // DRAFT-ZERO — a verified harvest-deferred marker is the strongest hold: it outranks protected labels
256
311
  // and every close rule, so a failed run's harvestable draft survives the sweep for harvest.
257
312
  if (runStatus === 'failed' && harvestDeferredMarker(draft.body)) return { action: 'keep', reason: 'harvest-deferred' };
313
+ const intentHold = parseDraftIntentHold(draft.body, now);
314
+ if (intentHold) return { action: 'keep', reason: draftIntentHoldReason(intentHold) };
258
315
  const held = draft.labels?.find((label) => PROTECTED_LABELS.has(label));
259
316
  if (held) return { action: 'keep', reason: `label:${held}` };
260
317
  if (runStatus !== 'self-implement.result final' && draft.branch && liveBranches.has(draft.branch)