elanous 0.2.42 → 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 (764) 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/{X1ucLw10Cds_h614NoEnh → HMXsxdy5MIIcHPMHv1wD4}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/08334415.f0e80896acbef722.js +1 -0
  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/{2160.a097e7b138ae1c55.js → 118.2a89982fe4276880.js} +1 -1
  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/1306.967240ede9a0f757.js +24 -0
  14. package/apps/pwa/out/_next/static/chunks/1344.3b95f3bd1b77a3fe.js +94 -0
  15. package/apps/pwa/out/_next/static/chunks/{4043.6b91203436c9c86b.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/{6632.0eac1c554f8f2ef3.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/1850-522de4ee34957210.js +1 -0
  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/{3507.97e1977bc4d5fb0a.js → 1978.eeb60a606dc5deac.js} +2 -2
  26. package/apps/pwa/out/_next/static/chunks/2043.e233e3b5a3e790f5.js +1 -0
  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/2216.802962c04f40a26e.js +64 -0
  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/{5885.0a3e52c8faccec98.js → 239.de075467b5523469.js} +2 -2
  33. package/apps/pwa/out/_next/static/chunks/249.ba7051590d603c8f.js +226 -0
  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/2954.bbefc95d6b20e0d8.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/2e0f720a.a0697c08e3806a60.js +1 -0
  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/{1487.2f67b79444062da6.js → 3349.b5f09ee474d9533e.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/3503.a47a9755fb4d97b0.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/3506-5f429b3b7e1392b0.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/3843.bad404d008893291.js +77 -0
  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/4393.28fa5228d0eec217.js +149 -0
  52. package/apps/pwa/out/_next/static/chunks/4404.7281c847c6e10dfc.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/{8673-bab689a55f7e13b9.js → 4415-b9d6a90960920a4a.js} +3 -3
  54. package/apps/pwa/out/_next/static/chunks/447-5b304de1fe098f43.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/4484-8ebea83d431e6fae.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/{8262.ddc03e06b733f184.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/{1262.e804feb8fd1acb8c.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/{1063.2fb8a9dc55c731f2.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/{6377.bc7df239edbff244.js → 4891.3f80ba517a3b2373.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/4998.810ca8833084caa9.js +62 -0
  66. package/apps/pwa/out/_next/static/chunks/4f98febc.ea5841d4d616bfb2.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/{3482.a9ae9d2ad6a5bd97.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/5439.3fec6dbce29ecb36.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/5612-074d9a5e00dfac6a.js +1 -0
  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/5790.5eb06a653ebd8571.js +34 -0
  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/{3347.f846266b5e5f3ede.js → 5989.7ecd362c5c44b747.js} +3 -3
  81. package/apps/pwa/out/_next/static/chunks/{73d2eb0e.4966ad55293c801a.js → 5a34fb2f.52f1b4e1baebb48a.js} +3 -3
  82. package/apps/pwa/out/_next/static/chunks/{7a98bc80.fa935989e829f9c2.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/{7411.9b4b8b747dc7b802.js → 6245.1182e007e9d230d9.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/{b450776b.3db34d8d965f82d3.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/{e8543907.5b040a5f22a0b0e5.js → 6549dad0.2740b25e51bf8f05.js} +1 -1
  92. package/apps/pwa/out/_next/static/chunks/{9427.96aa912ddb5801e0.js → 6881.9e7955847640c7fe.js} +17 -17
  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/7010.1bbd17a7f2b3e376.js +1 -0
  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/7679.32c40cdd14f20b4a.js +1 -0
  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/{8138.6c10b2a356d52fca.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/{9415.69e4a21c60c7d2db.js → 8551.f762945c2cda2e95.js} +1 -1
  109. package/apps/pwa/out/_next/static/chunks/8635-57a9d8d9db70f4f1.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/86961958-4b0689a5048f756b.js +1 -0
  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/{9a852a62-6192a6ea9346ced3.js → 87f498e5-0881de09f2e44707.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/8843.c3197f904c952b81.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/{3d0154af.5331fec737ffe8c3.js → 892fd990.456232f326cc39c2.js} +1 -1
  116. package/apps/pwa/out/_next/static/chunks/8965-135a2c9eaa2464cb.js +1 -0
  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/9398.1f56e3f17795f43f.js +1 -0
  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-da787e8a10b8a82e.js +1 -0
  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/_next/static/css/d1f8bb401740a549.css +1 -0
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +23 -23
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +23 -23
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +23 -23
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +22 -22
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +22 -22
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +23 -23
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +22 -22
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +23 -23
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +23 -23
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +22 -22
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +23 -23
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +23 -23
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +23 -23
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +23 -23
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +22 -22
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +22 -22
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +23 -23
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +23 -23
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +23 -23
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +22 -22
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +22 -22
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +23 -23
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +23 -23
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +22 -22
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +22 -22
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +22 -22
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +23 -23
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +23 -23
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +22 -22
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +23 -23
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +23 -23
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +23 -23
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +23 -23
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +23 -23
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +22 -22
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +23 -23
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +23 -23
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +23 -23
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +23 -23
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +23 -23
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +23 -23
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +23 -23
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +23 -23
  278. package/catalog/external-commands.yaml +5 -3
  279. package/catalog/meta/catalogVersion.yaml +2 -1
  280. package/catalog/signing/catalog-signing-public.pem +3 -0
  281. package/graphs/intake/intake-daily.yaml +16 -0
  282. package/graphs/intake/news-sources.yaml +1 -0
  283. package/graphs/intake/recipes.yaml +7 -0
  284. package/graphs/overlays/README.md +6 -0
  285. package/graphs/overlays/examples/research-runtime-empty-terminal.yaml +28 -0
  286. package/graphs/profiles/local.yaml +5 -0
  287. package/graphs/profiles/pod.yaml +4 -0
  288. package/graphs/release/release-loop.yaml +33 -17
  289. package/graphs/units/verbs/make-doc.yaml +1 -0
  290. package/package.json +6 -2
  291. package/plugins/demo-absorption-briefing/plugin.json +18 -0
  292. package/plugins/demo-absorption-briefing/skills/demo-absorption-briefing/SKILL.md +8 -0
  293. package/plugins/demo-browser-hand/plugin.json +13 -0
  294. package/plugins/demo-browser-hand/skills/demo-browser-hand/SKILL.md +8 -0
  295. package/plugins/demo-linear-secretary/plugin.json +15 -0
  296. package/plugins/demo-linear-secretary/skills/demo-linear-secretary/SKILL.md +8 -0
  297. package/plugins/demo-plugin-wizard/plugin.json +11 -0
  298. package/plugins/demo-plugin-wizard/skills/demo-plugin-wizard/SKILL.md +8 -0
  299. package/plugins/demo-research/plugin.json +16 -0
  300. package/plugins/demo-research/skills/demo-research/SKILL.md +8 -0
  301. package/plugins/demo-video-briefing/plugin.json +15 -0
  302. package/plugins/demo-video-briefing/skills/demo-video-briefing/SKILL.md +8 -0
  303. package/scripts/bench-metering-plan.ts +229 -0
  304. package/scripts/build-signed-catalog.ts +48 -0
  305. package/scripts/ci-typecheck-main-delta.sh +88 -0
  306. package/scripts/codex-fallback-live-probe.ts +1 -1
  307. package/scripts/demo/demo1104-parallel-host.ts +56 -0
  308. package/scripts/demo/demo1104-parallel-scenes.ts +301 -0
  309. package/scripts/demo/demo1104-parallel.ts +72 -0
  310. package/scripts/demo/demo1104-stage.config.ts +21 -0
  311. package/scripts/demo/demo1104-stage.ts +316 -0
  312. package/scripts/goal-method-audit.ts +17 -1
  313. package/scripts/graph-units/land-enqueue.ts +90 -0
  314. package/scripts/hooks/codex-notify.sh +32 -0
  315. package/scripts/install.sh +10 -38
  316. package/scripts/landing-heal/land-plan.ts +57 -0
  317. package/scripts/public-leak-baseline.txt +0 -1
  318. package/scripts/release-loop/auto-approve-node.ts +1 -1
  319. package/scripts/release-loop/docs-node.ts +4 -2
  320. package/scripts/release-loop/gate-autoheal-sim-evidence.ts +60 -0
  321. package/scripts/release-loop/gate-image-pin.ts +116 -2
  322. package/scripts/release-loop/gate-method.ts +139 -0
  323. package/scripts/release-loop/gate-node.ts +395 -43
  324. package/scripts/release-loop/gate-progress-sim.ts +73 -0
  325. package/scripts/release-loop/gate-traffic-mode.ts +151 -3
  326. package/scripts/release-loop/node-verdict.ts +38 -25
  327. package/scripts/release-loop/notes-repair.ts +18 -1
  328. package/scripts/release-loop/preflight.ts +544 -10
  329. package/scripts/release-loop/render-warm-control-manifest.ts +22 -0
  330. package/scripts/release-loop/resume-release.ts +9 -7
  331. package/scripts/release-loop/resume.ts +13 -4
  332. package/scripts/release-loop/unattended-release.ts +20 -9
  333. package/scripts/release-loop/warm-control-forward.ts +178 -0
  334. package/scripts/retro-cycle.ts +30 -8
  335. package/scripts/rhythm/daily.ts +39 -4
  336. package/scripts/rhythm/linear-progress-sync.ts +311 -0
  337. package/scripts/ux-sim.ts +7 -1
  338. package/scripts/video-pipeline.ts +9 -1
  339. package/scripts/warm-pool-provider-config.ts +35 -7
  340. package/src/acp/agent-manager.ts +1 -0
  341. package/src/acp/codex-app-server-agent.ts +33 -0
  342. package/src/acp/codex-app-server-client.ts +153 -16
  343. package/src/acp/core-turn-bridge.ts +17 -12
  344. package/src/acp/event-router.ts +20 -1
  345. package/src/acp/server.ts +6 -0
  346. package/src/agent-mission/browser-roundtrip-coordinator.ts +85 -0
  347. package/src/agent-mission/claude-headless.ts +4 -1
  348. package/src/agent-mission/codex-exec.ts +105 -0
  349. package/src/agent-mission/driver.ts +192 -11
  350. package/src/agent-mission/grok-auth-status.ts +107 -0
  351. package/src/agent-mission/hand-hooks.ts +101 -0
  352. package/src/agent-mission/mission-cli.ts +56 -21
  353. package/src/agent-mission/mission-hand-reply.ts +118 -0
  354. package/src/agent-mission/mission-line.ts +180 -0
  355. package/src/agent-mission/mission-out.ts +256 -18
  356. package/src/agent-mission/tool-install.ts +122 -11
  357. package/src/agent-substrate/pr-reviewer.ts +147 -11
  358. package/src/agent-substrate/self-review-cli.ts +10 -2
  359. package/src/agents/general-purpose.md +1 -1
  360. package/src/auto-research/research-fanout.ts +221 -0
  361. package/src/auto-research/research-turn.ts +362 -31
  362. package/src/autopilot/mission-codebase-gate.ts +7 -3
  363. package/src/autopilot/pr-manager.ts +31 -3
  364. package/src/boot/daemon-tools/self-implement.ts +3 -1
  365. package/src/boot/daemon-tools/web-search.ts +1 -2
  366. package/src/briefing/brief-items.ts +55 -11
  367. package/src/cli/agent-cli.ts +2 -1
  368. package/src/cli/catalog-cli.ts +31 -0
  369. package/src/cli/connector-cli.ts +16 -0
  370. package/src/cli/control-cli.ts +15 -6
  371. package/src/cli/doctor-fix.ts +2 -2
  372. package/src/cli/intake-source-cli.ts +44 -8
  373. package/src/cli/log-event-names.ts +8 -0
  374. package/src/cli/msg-cli.ts +32 -3
  375. package/src/cli/pr-cli.ts +21 -1
  376. package/src/cli/pr-land-heavy-remote.ts +44 -6
  377. package/src/cli/pr-land-overlap-evidence.ts +13 -1
  378. package/src/cli/pr-land-pod-shadow-job.ts +143 -5
  379. package/src/cli/pr-land-pod-shadow.ts +9 -2
  380. package/src/cli/release-checklist-read-cli.ts +44 -16
  381. package/src/cli/release-cli.ts +23 -3
  382. package/src/cli/research-cli.ts +9 -0
  383. package/src/cli/setup-cli.ts +166 -6
  384. package/src/cli/setup-keys.ts +199 -0
  385. package/src/cli/task-plugin-wizard-host.ts +114 -0
  386. package/src/cli/tasks-cli.ts +54 -9
  387. package/src/cli/tui-test-cli.ts +190 -0
  388. package/src/config.ts +4 -2
  389. package/src/connectors/linear-daily-progress.ts +228 -0
  390. package/src/connectors/linear-projector.ts +34 -12
  391. package/src/connectors/linear.ts +151 -7
  392. package/src/control-plane/ledger.ts +42 -4
  393. package/src/control-plane/member-tokens.ts +25 -2
  394. package/src/control-plane/ports.ts +8 -3
  395. package/src/control-plane/server.ts +26 -5
  396. package/src/core-turn/deep-turn-bloom.ts +67 -0
  397. package/src/core-turn/research-policy.ts +43 -0
  398. package/src/core-turn/run-core-turn.ts +488 -51
  399. package/src/core-turn/types.ts +4 -0
  400. package/src/dashboard/chat/acp-chat.ts +10 -0
  401. package/src/dashboard/classic-sidetab-mission-job.ts +192 -0
  402. package/src/dashboard/classic-sidetab-mission-pair.ts +82 -0
  403. package/src/dashboard/classic-sidetab-mission-trio.ts +242 -0
  404. package/src/dashboard/classic-sidetab-mission.ts +169 -5
  405. package/src/dashboard/index.ts +387 -14
  406. package/src/dashboard/input/chat-main-acp-dispatch.ts +23 -0
  407. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +8 -0
  408. package/src/dashboard/mission-cli-consumer.ts +20 -8
  409. package/src/dashboard/plugin-wizard-runtime.ts +50 -0
  410. package/src/dashboard/plugin-wizard-tool.ts +55 -0
  411. package/src/dashboard/sidetab-runtime.ts +3 -1
  412. package/src/dashboard/terminal-popup-runtime.ts +6 -3
  413. package/src/dashboard/visible-mission-diagnostics.ts +16 -0
  414. package/src/decisions/linear-progress-summary.ts +78 -0
  415. package/src/decisions/linear-progress-sync.ts +152 -0
  416. package/src/domains/outbound-alert.ts +49 -11
  417. package/src/domains/retro-cycle-observation.ts +43 -0
  418. package/src/domains/retro-cycle.ts +13 -2
  419. package/src/domains/retro-proposals.ts +92 -0
  420. package/src/domains/retro-report.ts +6 -1
  421. package/src/domains/telegram-kind-route.ts +16 -9
  422. package/src/graph-runner/arg-allowance.ts +13 -0
  423. package/src/graph-runner/graph-cli.ts +24 -1
  424. package/src/graph-runner/graph-grow-llm.ts +3 -1
  425. package/src/graph-runner/graph-run-api.ts +3 -1
  426. package/src/graph-runner/runner.ts +310 -46
  427. package/src/graph-wizard/mission-compose.ts +407 -12
  428. package/src/harness/dispatch-backpressure.ts +54 -1
  429. package/src/harness/dispatch-shadow-compare.ts +74 -0
  430. package/src/harness/harness-cli-command.ts +15 -3
  431. package/src/harness/harness-pod-dispatch.ts +3 -0
  432. package/src/harness/skill-exec.ts +21 -9
  433. package/src/harness/skill-select.ts +1 -1
  434. package/src/hooks/error-report-cloud.ts +101 -0
  435. package/src/hooks/receiver.ts +29 -2
  436. package/src/index.ts +129 -12
  437. package/src/intake-plane/actions.ts +354 -0
  438. package/src/intake-plane/adapters/telegram-ambient.ts +34 -18
  439. package/src/intake-plane/intake-sources.ts +78 -8
  440. package/src/intake-plane/items.ts +14 -4
  441. package/src/intake-plane/linear-mission-sync.ts +80 -0
  442. package/src/intake-plane/linear-secretary-runtime.ts +178 -0
  443. package/src/intake-plane/linear-wish.ts +227 -1
  444. package/src/life/life-cli.ts +168 -0
  445. package/src/life/life-kinds.ts +160 -0
  446. package/src/live-supply/budget-consumer.ts +78 -0
  447. package/src/live-supply/read.ts +3 -0
  448. package/src/live-supply/snapshot.ts +45 -0
  449. package/src/llm/child-first-llm-observation.ts +112 -0
  450. package/src/llm/provider-credentials.ts +68 -6
  451. package/src/llm/provider-failure-evidence.ts +44 -0
  452. package/src/llm.ts +172 -12
  453. package/src/maturity/feature-maturity.ts +3 -3
  454. package/src/mcp/client.ts +7 -0
  455. package/src/mcp/proxy-runtime.ts +6 -1
  456. package/src/mcp/server.ts +54 -0
  457. package/src/msg/msg-sse-server.ts +3 -3
  458. package/src/msg/msg-store.ts +177 -19
  459. package/src/native-tool-catalog.ts +36 -2
  460. package/src/nexus/api/consult-requests.ts +18 -6
  461. package/src/nexus/api/discord-trigger-bot.ts +6 -6
  462. package/src/nexus/api/graphs-api.ts +4 -2
  463. package/src/nexus/api/grokbot-trigger-bot.ts +206 -0
  464. package/src/nexus/api/http-server.ts +37 -1
  465. package/src/nexus/api/mcp-public-allowlist.ts +2 -0
  466. package/src/nexus/api/telegram-trigger-bot.ts +6 -6
  467. package/src/nexus/boot/register-mcp-clients.ts +114 -8
  468. package/src/nexus/index.ts +22 -2
  469. package/src/nexus/outbound/format.ts +9 -0
  470. package/src/nexus/outbound/grokbot-adapter.ts +71 -0
  471. package/src/nexus/outbound/router.ts +121 -16
  472. package/src/nexus/setup-status.ts +9 -0
  473. package/src/nexus/state/state.ts +3 -0
  474. package/src/oauth/codex-account-store.ts +20 -7
  475. package/src/oauth/codex-owner-mirror.ts +81 -0
  476. package/src/oauth/codex.ts +17 -2
  477. package/src/oauth/fallback-chain.ts +47 -17
  478. package/src/onboarding/first-run-doctor.ts +8 -1
  479. package/src/onboarding/first-run.ts +126 -29
  480. package/src/onboarding/key-setup.ts +103 -0
  481. package/src/onboarding/menu-answer.ts +13 -0
  482. package/src/onboarding/secret-prompt.ts +37 -0
  483. package/src/plugins/install/plugin-install.ts +59 -0
  484. package/src/pr-tool/census.ts +130 -0
  485. package/src/preview/terminal.ts +22 -7
  486. package/src/prompt-enhance/enhance.ts +10 -0
  487. package/src/pty-shell/pty-control-ipc.ts +4 -1
  488. package/src/pty-shell/pty-write-provenance.ts +21 -3
  489. package/src/pty-shell/registry.ts +9 -2
  490. package/src/registry/catalog-server.ts +232 -0
  491. package/src/registry/loader.ts +45 -1
  492. package/src/registry/types.ts +1 -2
  493. package/src/release-loop/proposal-auto-place.ts +83 -0
  494. package/src/research/axis-fanout.ts +79 -29
  495. package/src/research/lenses/second-order.ts +312 -0
  496. package/src/self-dev/ask-launch-flow.ts +72 -1
  497. package/src/self-dev/dev-cli.ts +7 -2
  498. package/src/self-dev/dev-pipeline.ts +5 -0
  499. package/src/self-dev/draft-residue.ts +64 -5
  500. package/src/self-dev/draft-sweep.ts +31 -10
  501. package/src/self-dev/draft-triage-rules.ts +60 -3
  502. package/src/self-dev/graph-front-nodes.ts +2 -1
  503. package/src/self-dev/graph-journey-route.ts +76 -21
  504. package/src/self-dev/launch-preflight.ts +58 -0
  505. package/src/self-dev/orchestrate.ts +1 -1
  506. package/src/self-dev/run-supervisor.ts +152 -2
  507. package/src/self-dev/shard-aggregate.ts +4 -0
  508. package/src/self-dev/shard-run.ts +36 -15
  509. package/src/self-implement/abandoned-classification.ts +12 -3
  510. package/src/self-implement/budget-gate.ts +7 -0
  511. package/src/self-implement/child-llm-preference.ts +10 -1
  512. package/src/self-implement/doctor-visit.ts +30 -8
  513. package/src/self-implement/elanous-tui-spawn.ts +3 -0
  514. package/src/self-implement/fixtures/tdd-green-missing-passing-child-transcript.txt +2 -0
  515. package/src/self-implement/gate-artifacts.ts +2 -1
  516. package/src/self-implement/goal-author-cli.ts +4 -2
  517. package/src/self-implement/goal-author.ts +549 -10
  518. package/src/self-implement/graph-overlay-yaml.ts +181 -4
  519. package/src/self-implement/graph-overlay.ts +3 -1
  520. package/src/self-implement/graph-profile-yaml.ts +107 -0
  521. package/src/self-implement/graph-yaml.ts +94 -5
  522. package/src/self-implement/off-diff-evidence.ts +249 -5
  523. package/src/self-implement/orchestrator.ts +298 -26
  524. package/src/self-implement/run-chart.ts +6 -3
  525. package/src/self-implement/run-ledger.ts +51 -1
  526. package/src/self-implement/runtime-overlay-run-steps.ts +95 -0
  527. package/src/self-implement/tdd-evidence-tags.ts +9 -0
  528. package/src/self-implement/test-scenario-request.ts +37 -6
  529. package/src/self-implement/train-gate-receipt.ts +166 -0
  530. package/src/self-implement/train-gate-remote.ts +62 -18
  531. package/src/session/chat.ts +6 -4
  532. package/src/session/session-fanout.ts +2 -0
  533. package/src/session/streaming/acp-stream-sink.ts +2 -1
  534. package/src/session/streaming/chunk-producer.ts +6 -0
  535. package/src/session/streaming/stream-compositor.ts +3 -2
  536. package/src/session-runtime/index.ts +74 -6
  537. package/src/session-runtime/retry-policy.ts +1 -1
  538. package/src/setup/llm-env-detect.ts +3 -0
  539. package/src/setup/service-key-catalog.ts +46 -0
  540. package/src/setup/service-keys.ts +241 -0
  541. package/src/sidetab-core/model.ts +205 -10
  542. package/src/sidetab-core/visible-agent-mission-pair.ts +51 -0
  543. package/src/sidetab-core/visible-agent-mission.ts +182 -48
  544. package/src/skills/tools/agent.ts +23 -4
  545. package/src/skills/tools/omni-search.ts +127 -27
  546. package/src/task-agent/parent-host.ts +29 -1
  547. package/src/task-agent/recall-inject.ts +98 -0
  548. package/src/task-agent/repair-outcomes.ts +65 -0
  549. package/src/task-agent/task-hand.ts +46 -14
  550. package/src/task-orchestrator/dispatcher.ts +14 -1
  551. package/src/task-orchestrator/linear-capture-events.ts +55 -0
  552. package/src/task-orchestrator/store.ts +16 -5
  553. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +23 -1
  554. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +107 -1
  555. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +113 -14
  556. package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +21 -9
  557. package/src/task-orchestrator/surfaces/pod-source-receive.ts +23 -11
  558. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +2 -0
  559. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +1 -1
  560. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +467 -77
  561. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +45 -3
  562. package/src/task-orchestrator/surfaces/self-implement-pod.ts +210 -14
  563. package/src/task-orchestrator/surfaces/self-implement.ts +27 -3
  564. package/src/task-orchestrator/surfaces/warm-reuse-evidence.ts +169 -0
  565. package/src/task-orchestrator/types.ts +14 -0
  566. package/src/telegram.ts +14 -16
  567. package/src/terminal/coding-agent.ts +14 -5
  568. package/src/terminal/session-registry.ts +1 -1
  569. package/src/tool-hints/gate.ts +46 -14
  570. package/src/tool-hints/signals.ts +1 -1
  571. package/src/tool-hints/types.ts +2 -0
  572. package/src/tool-runtime/agent-runtime.ts +1 -0
  573. package/src/tool-runtime/browser-hand-runtime.ts +391 -0
  574. package/src/tool-runtime/browser-runtime.ts +33 -19
  575. package/src/tool-runtime/elanous-linear-issue-runtime.ts +76 -0
  576. package/src/tool-runtime/elanous-linear-secretary-runtime.ts +173 -0
  577. package/src/tool-runtime/graph-mcp-runtimes.ts +240 -0
  578. package/src/tool-runtime/index.ts +6 -0
  579. package/src/tool-runtime/types.ts +5 -0
  580. package/src/tui/entry.ts +51 -8
  581. package/src/tui/sidetab/attach.ts +252 -11
  582. package/src/tui/sidetab/herdr-portal.ts +225 -0
  583. package/src/tui/sidetab/list.ts +3 -2
  584. package/src/tui-client/next-dashboard-runtime.ts +52 -0
  585. package/src/user-config.ts +34 -9
  586. package/src/user-intent/types.ts +4 -3
  587. package/src/ux-sim/browser-hand.ts +165 -0
  588. package/src/ux-sim/draft-inventory-builder.ts +199 -0
  589. package/src/ux-sim/fake-browser-page.ts +81 -0
  590. package/src/ux-sim/fake-linear-device.ts +31 -0
  591. package/src/ux-sim/graph-engine-sim.ts +47 -0
  592. package/src/ux-sim/linear-secretary.ts +208 -0
  593. package/src/ux-sim/mock-scenario-catalog.json +81 -26
  594. package/src/ux-sim/mock-scenario-catalog.ts +175 -5
  595. package/src/ux-sim/onboarding-first-run-device.ts +31 -21
  596. package/src/ux-sim/release-sim-rig.ts +62 -18
  597. package/src/ux-sim/scenario.ts +70 -26
  598. package/src/ux-sim/service-key-setup.ts +113 -0
  599. package/src/ux-sim/term-slash-device.ts +74 -0
  600. package/src/ux-sim/turn-throw-sim.ts +31 -0
  601. package/src/version/packed-revision.json +1 -1
  602. package/src/web-search/exa.ts +77 -0
  603. package/src/web-search/index.ts +30 -9
  604. package/src/web-search/provider.ts +4 -1
  605. package/src/web-search/x-intent.ts +5 -0
  606. package/apps/pwa/out/_next/static/chunks/0244e5b5.6fc7670f8223d82d.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/1121.13ba7a8aff19df81.js +0 -36
  608. package/apps/pwa/out/_next/static/chunks/1147-5196d19c222051b3.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/1319.b9b815ae0f181e06.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/1345-31427b833438f521.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/1455-530ca16c7e71baff.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/1574.878c18ecc97b1bd4.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/1586.fafc33a9a5835cb7.js +0 -32
  614. package/apps/pwa/out/_next/static/chunks/1744.855fd60ae4c4a8c8.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/193.21a47a3e07ef6860.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/1945.7b54990d578c119b.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/2004.e839fda7ea5a738a.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/2044-dd681a5c08779ff8.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/2101.2248decb38829b03.js +0 -286
  620. package/apps/pwa/out/_next/static/chunks/2300.41ea70ac1bef1446.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/2357-07b5eeb5fb12628d.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/2364.28652020695a6db3.js +0 -34
  623. package/apps/pwa/out/_next/static/chunks/2456.b6de0e1c05f28843.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/2526.c3e50ac1fec064bd.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/2549-cda50b716ff4250c.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/2550-5f1e88f615568045.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/261-319078c954e40d66.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/2690.0521c738b7749931.js +0 -115
  629. package/apps/pwa/out/_next/static/chunks/2974.595d1e29d040cb6a.js +0 -64
  630. package/apps/pwa/out/_next/static/chunks/3207.a756c95e9ec8c3c8.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/3285.89ee2f298682f5e5.js +0 -93
  632. package/apps/pwa/out/_next/static/chunks/3447.06edc7b092021417.js +0 -41
  633. package/apps/pwa/out/_next/static/chunks/3510-9ca392698bfe4391.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/3541.772e5ce425aaa611.js +0 -24
  635. package/apps/pwa/out/_next/static/chunks/3741.9cf76acaa2ee5298.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/3837.a210d7d0db8d8abd.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/3898-955c896f394217a6.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/3947-ef57acea76eaa8d2.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/4037-3b82ebc7d78afdc7.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/405.9022d4a478202b67.js +0 -77
  641. package/apps/pwa/out/_next/static/chunks/417-fb2cc9a9910e5968.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/4276.336d76d858fcdf1b.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/4302.6ced9aa4535de947.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/4320.583cbab64db6be02.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/4768-8eac183fd291ca53.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/4770.769c9cd9c7034eba.js +0 -148
  647. package/apps/pwa/out/_next/static/chunks/4895.65605ec3e6504e89.js +0 -74
  648. package/apps/pwa/out/_next/static/chunks/50061469.0326382241ef3b2d.js +0 -122
  649. package/apps/pwa/out/_next/static/chunks/5112.4b9f300124fab7b3.js +0 -149
  650. package/apps/pwa/out/_next/static/chunks/5335.375ee922bcd5bc83.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/5342.023a2e729689b320.js +0 -27
  652. package/apps/pwa/out/_next/static/chunks/53c73f84.373b6160adfa89a4.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/5431-72a1dbde59400691.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/5440-4236de26c5ea5856.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/5486-b318c165f645d8ba.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/5506-c7d2ec25c62a7c94.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/5570-c66ecbea26b4e3b1.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/5696.ffca5aa259d8451e.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/5793-8c584aea2aa87560.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/5848-6de6b8c173351a90.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/5999.94e3c83040200f31.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/5a7901d6-2d8d9b5587cf9042.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/6131.348b7d6bdcd267ce.js +0 -226
  664. package/apps/pwa/out/_next/static/chunks/6164.86133a0172611184.js +0 -90
  665. package/apps/pwa/out/_next/static/chunks/6515.e07e8b2b8a707a87.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/6522-c005514f87d18982.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/6642.648adb1767f39ecf.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/6848.138805a09d001d09.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/7049-c09e2b7a253a24f3.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/7072.1e00447d9fa39972.js +0 -104
  671. package/apps/pwa/out/_next/static/chunks/7106.64201c539c5e220c.js +0 -94
  672. package/apps/pwa/out/_next/static/chunks/7151-1f742b455986530e.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/7199.18d6b25e001154ce.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/7279-c199ea83f34338fa.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/728b938d.ffaa7ad583d60e58.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/7309.171c3de54e0322f1.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/733.7a1ab3342e03306f.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/7504.d5cf1e7cd89b1b08.js +0 -24
  679. package/apps/pwa/out/_next/static/chunks/7573-0fd4af62d65d4598.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/759.6f8267df4689c401.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/7825-668b046f72f14483.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/7852-1538768b6eb19388.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/7868.cff810430bb63c91.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/8084-dfcc796874ab4e07.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/8266.6bf9b131b2584678.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/8403.7b81d5e64074a725.js +0 -8
  687. package/apps/pwa/out/_next/static/chunks/8470.1998cbd0866a7eac.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/8505.fd803c6c33b54cc3.js +0 -79
  689. package/apps/pwa/out/_next/static/chunks/8546-6f03f8ea34dd61d9.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/8687-246fda8433d3477c.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/898-280022fb082936bc.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/9098-50eefc1844212e3d.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/9211-330b6736a63d4cb3.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/9249.976f1e69a9d80754.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/9255-cf88fceda5666645.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/9306-e523ba58bb8adc42.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/9324.a9866d717ba62cb6.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/9325.a8510e8aa87c8143.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/9353-12bfff0c130104cf.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/9479-154a697d4b6e4e98.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/9540-65aa6ccc31b3fd78.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/9633.ce5bddc56784da72.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/9656-374232558fd528d0.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/9832.f4a98c878ecf2c0a.js +0 -62
  705. package/apps/pwa/out/_next/static/chunks/9865.f094440645f02d98.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-e772b4710df5d936.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4361368e6a76b967.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-802f349fdd65248d.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/app/board/page-7f35513988a2a495.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/app/botlab/page-798121656540e33e.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/app/bots/page-20a089490affe98c.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/app/ceo/page-e5e4ec786d70e604.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/app/chat/page-d12fe5d0801430e4.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/app/consult/page-d8cf21022fecc026.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/app/control/page-21ce565c9c57ee97.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/app/decisions/page-b56563025f619c9b.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/app/design-check/page-52f14dd133da8348.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/app/editor/page-c0ed7fdcdba76633.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/app/exec/page-af8c3020cb520f15.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/app/field/page-72eda67af9f5e35c.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/app/healthz/route-e772b4710df5d936.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/app/inside/page-67a6620d31f0a46f.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/app/intake/page-f059363aa0880ec2.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/layout-f9f917d6a57f69fb.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/live/page-d3ae55eee2f0826c.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/live-run/page-0e3d7b9421b79dac.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/loops/page-ba738f7e233eb211.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/market/page-33438b98c74fd599.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-0b34d5fd990d793a.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/morning/page-0f291d3c8fd55a3a.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/app/not-found-3fced192be5279c1.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/app/observatory/page-04cb3cf182a7c1ea.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6ccbd2ab23a21542.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-aa0518c48a5f4e56.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4b32226d341ad7d7.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3224fd8f6383b61f.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/app/page-efbc97459f2914e2.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2fe487d88cd5d97c.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-48861dd1a858bab7.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/sessions/page-197d5d4d21d228ea.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a763ba89fbdd9c27.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/settings/page-7edb253510b1c136.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0c875702c61965ea.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/setup/layout-e772b4710df5d936.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/setup/page-e425c951151095f7.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/share/page-9c90e0aec4e27f77.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/showroom/page-733e09a02e727d42.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/tasks/page-4f899e14c34d77a1.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/term/page-bf067887b3307423.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/today/page-7af10868ff87d04e.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/trace/page-efe5304057aa11c7.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/vault/page-76bcd29aaa8a26c3.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-4cfd88e2273ce50f.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/workflows/page-0a1ddb47efba0a32.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/workspace/page-2a176c707152c892.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-efe03031b8797fbf.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/framework-d0d2d673bfd8a8a9.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/main-4c9fceb2baa09cb7.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/main-app-b0ab8d8fc9a97556.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/pages/_app-7e2cc62a2e5cec96.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/pages/_error-22324935f753ec5e.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/webpack-9dc1bfa25334998a.js +0 -1
  763. package/apps/pwa/out/_next/static/css/be9019f696217521.css +0 -1
  764. /package/apps/pwa/out/_next/static/{X1ucLw10Cds_h614NoEnh → HMXsxdy5MIIcHPMHv1wD4}/_ssgManifest.js +0 -0
@@ -49,6 +49,27 @@ export function isDemotableScopeRevertMustFix(mustFix: string): boolean {
49
49
  return isScopeRevertMustFix(mustFix) && !SCOPE_REVERT_KEEP_BLOCKER.test(mustFix);
50
50
  }
51
51
 
52
+ export interface ReauthorClassification {
53
+ class: 'code-defect' | 'authorship-defect';
54
+ finding: string;
55
+ recommendation?: string;
56
+ }
57
+
58
+ function hasReauthorFuRecommendation(classification: ReauthorClassification): boolean {
59
+ const recommendation = classification.recommendation;
60
+ if (recommendation === undefined) return false;
61
+ const cellId = recommendation.split(';', 1)[0]?.trim();
62
+ if (!cellId || !/^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)*-FU$/u.test(cellId)) return false;
63
+ const scopeCut = /(?:^|;)\s*scope-cut\s*=\s*([^;]+)/iu.exec(recommendation)?.[1]?.trim();
64
+ const paths = /(?:^|;)\s*paths\s*=\s*([^;]+)/iu.exec(recommendation)?.[1]?.trim();
65
+ const boundary = /(?:^|;)\s*boundary\s*=\s*([^;]+)/iu.exec(recommendation)?.[1]?.trim();
66
+ const hasCutAction = scopeCut !== undefined && /제외|미포함|분리|빼|후속|exclude|omit|remove|split|defer|out.of.scope/iu.test(scopeCut);
67
+ const hasConcretePaths = paths !== undefined && /[/.\\]/u.test(paths) && paths.length >= 3;
68
+ const hasBoundary = boundary !== undefined && boundary.length >= 8 && !/^(?:tbd|unknown|todo|n\/a)$/iu.test(boundary);
69
+ const hasMockScenario = /(?:^|;)\s*MS-[A-Z0-9][A-Z0-9-]*/iu.test(recommendation);
70
+ return hasCutAction && hasConcretePaths && hasBoundary && hasMockScenario;
71
+ }
72
+
52
73
  export interface ReviewResult {
53
74
  verdict: ReviewVerdict;
54
75
  mustFix: string[];
@@ -76,8 +97,13 @@ export interface ReviewResult {
76
97
  failureReason?: string;
77
98
  /** Subscription reviewer unavailable: the default reviewer produced this verdict. */
78
99
  reviewerFallback?: string;
100
+ /** r3+ shadow classification; never triggers checklist mutation or relaunch. */
101
+ reauthorClassifications?: ReauthorClassification[];
79
102
  }
80
103
 
104
+ /** Invalid reauthor classifications travel from parsing to chunk folding without entering public review JSON. */
105
+ const invalidReauthorFindingsByResult = new WeakMap<ReviewResult, ReadonlySet<string>>();
106
+
81
107
  /** 모든 리뷰 관측 생산자가 공유하는 diff 예산 필드 계약. 예산 부재는 빈 객체로 보존한다.
82
108
  * ⚠️ 내부 타입 — 소비자는 `...reviewDiffBudgetObservation(r)` 로 스프레드만 하므로 이름을 참조하지
83
109
  * 않는다(dead export 금지·review · `pty-control-ipc.ts:7` 선례). 실 소비자가 생기면 그때 export 한다. */
@@ -317,7 +343,7 @@ export function planReviewChunks(
317
343
  */
318
344
  export function foldReviewResults(
319
345
  results: readonly ReviewResult[],
320
- ): Pick<ReviewResult, 'verdict' | 'mustFix' | 'shouldFix' | 'scopeRevertDemoted' | 'requirements' | 'reviewed' | 'failureReason' | 'reviewerFallback'> {
346
+ ): Pick<ReviewResult, 'verdict' | 'mustFix' | 'shouldFix' | 'scopeRevertDemoted' | 'requirements' | 'reviewed' | 'failureReason' | 'reviewerFallback' | 'reauthorClassifications'> {
321
347
  const dedupe = (values: readonly string[]): string[] => [...new Set(values)];
322
348
  const collect = (pick: (r: ReviewResult) => readonly string[] | undefined): string[] =>
323
349
  dedupe(results.flatMap((r) => [...(pick(r) ?? [])]));
@@ -330,6 +356,15 @@ export function foldReviewResults(
330
356
  const scopeRevertDemoted = collect((r) => r.scopeRevertDemoted);
331
357
  const failed = results.find((r) => r.reviewed !== true);
332
358
  const reviewerFallback = results.find((r) => r.reviewerFallback)?.reviewerFallback;
359
+ const reauthorCandidates = results.flatMap((r) => r.reauthorClassifications ?? []);
360
+ const invalidReauthorFindings = new Set(results.flatMap((r) => [...(invalidReauthorFindingsByResult.get(r) ?? [])]));
361
+ const candidateCounts = new Map<string, number>();
362
+ for (const candidate of reauthorCandidates) candidateCounts.set(candidate.finding, (candidateCounts.get(candidate.finding) ?? 0) + 1);
363
+ const reauthorClassifications = reauthorCandidates.filter((candidate) =>
364
+ mustFix.includes(candidate.finding)
365
+ && !invalidReauthorFindings.has(candidate.finding)
366
+ && candidateCounts.get(candidate.finding) === 1
367
+ && (candidate.class === 'code-defect' || hasReauthorFuRecommendation(candidate)));
333
368
  return {
334
369
  verdict,
335
370
  mustFix,
@@ -339,6 +374,7 @@ export function foldReviewResults(
339
374
  reviewed: results.length > 0 && failed === undefined,
340
375
  ...(failed?.failureReason ? { failureReason: failed.failureReason } : {}),
341
376
  ...(reviewerFallback ? { reviewerFallback } : {}),
377
+ ...(reauthorClassifications.length ? { reauthorClassifications } : {}),
342
378
  };
343
379
  }
344
380
 
@@ -618,6 +654,14 @@ export function buildReviewPrompt(
618
654
  // ⚠️ 무표식 절단 금지(리뷰 must-fix) — 잘렸으면 **어느 절부터**인지 리뷰어가 알아야 한다.
619
655
  phaseIntentHeading, phaseIntent,
620
656
  ...(input.acceptance ? ['## Acceptance criteria', input.acceptance.slice(0, 1000)] : []),
657
+ ...(input.reviewContext?.round !== undefined && input.reviewContext.round >= 3 ? [
658
+ '## 저작 재점검 (review round >= 3)',
659
+ '각 MUST-FIX 후보를 (a) 코드 결함 또는 (b) 저작 결함으로 분류하라.',
660
+ '(b) 불필요한 경계·목표, 아직 없는 부품, 아직 배선되지 않은 운영 경로, 실물 전제 등 미래 가정을 시험/수용기준이 요구하는 경우다.',
661
+ '원래 MUST-FIX 후보는 verdict 와 MUST-FIX 목록에 그대로 보존하라. 저작 결함의 scope-cut/FU 는 아래 REAUTHOR-CLASSIFICATION 문법으로 별도 관측하라; 분류나 권고로 MUST-FIX 를 제거·대체하지 마라.',
662
+ '각 원래 blocker 를 `REAUTHOR-CLASSIFICATION:` 아래 정확히 `- CODE-DEFECT: <finding>` 또는 `- AUTHORSHIP-DEFECT: <finding> | SCOPE CUT + FU: <cell>-FU; scope-cut=<specific excluded/deferred work>; paths=<repository paths>; boundary=<observable completion boundary>; MS-<mock scenario id>` 로 한 줄씩 내고, finding 은 원문 그대로 복사하라.',
663
+ '(a) 실제 코드의 정확성·안전·데이터 손실 결함만 MUST-FIX로 유지하라.',
664
+ ] : []),
621
665
  'This is a POST-PR review of the produced artifact. Judge whether the PR actually',
622
666
  'delivers the phase intent CORRECTLY and soundly: (1) correctness/latent bugs, (2) does it meet the stated',
623
667
  'acceptance criteria, (3) design/regression risk, (4) missing wiring (new code never called), (5) tests present',
@@ -640,6 +684,13 @@ export function buildReviewPrompt(
640
684
  ' On that same finding line, state what would pass: one concrete observation and where to see it. Examples:',
641
685
  ' run the real entrypoint and assert runtime output this change did not author; force the call site to fail',
642
686
  ' and check that the error names that site; use values the real caller produces instead of synthetic input.',
687
+ ...(input.reviewContext?.round !== undefined && input.reviewContext.round >= 3 ? [
688
+ '',
689
+ '## Reauthor classification (shadow observation only; no automatic cell creation or relaunch)',
690
+ 'For each blocker classify it as CODE-DEFECT (required behavior is incorrectly implemented) or AUTHORSHIP-DEFECT (the goal asks for an unnecessary boundary/goal, absent component, future wiring, or real-world prerequisite not required by this phase).',
691
+ 'Do not change the original verdict, MUST-FIX, or SHOULD-FIX lists because of this classification. For AUTHORSHIP-DEFECT, the recommendation must name a `<cell>-FU` and include a concrete `scope-cut=<specific excluded/deferred work>`, `paths=<repository paths>`, `boundary=<observable completion boundary>`, and `MS-<mock scenario id>`; a FU token by itself is invalid.',
692
+ 'Add one line per original blocker under `REAUTHOR-CLASSIFICATION:` exactly as `- CODE-DEFECT: <finding>` or `- AUTHORSHIP-DEFECT: <finding> | SCOPE CUT + FU: <cell>-FU; scope-cut=<specific excluded/deferred work>; paths=<repository paths>; boundary=<observable completion boundary>; MS-<mock scenario id>`. Keep the finding text verbatim for joining. This is advisory only and must not affect the verdict or finding lists.',
693
+ ] : []),
643
694
  'Do NOT rubber-stamp; an empty review is a failed review — always surface at least a watch item.',
644
695
  '',
645
696
  ...(input.workingMemory ? ['## Prior decisions / reuse boundaries (working memory)', input.workingMemory.slice(0, 1200)] : []),
@@ -776,20 +827,23 @@ export function isNoneSentinelFinding(finding: string): boolean {
776
827
  /** ⭐ `VERDICT: PASS|WARN|FAIL` 판정 줄 — `parseReviewResult` 와 `reviewedResultFromRaw` 가 «같은» 정규식을 쓴다(존재 판정이 갈리면 안 된다). */
777
828
  const VERDICT_LINE = /VERDICT:\s*(PASS|WARN|FAIL)/i;
778
829
 
779
- export function parseReviewResult(text: string): ReviewResult {
830
+ export function parseReviewResult(text: string, round?: number): ReviewResult {
780
831
  const vm = VERDICT_LINE.exec(text);
781
832
  const verdict = (vm ? vm[1]!.toLowerCase() : 'pass') as ReviewVerdict;
782
833
  const lines = text.split('\n').map((l) => l.trim());
783
834
  const mustFix: string[] = [];
784
835
  const shouldFix: string[] = [];
785
836
  const requirements: string[] = [];
837
+ const reauthorCandidates: ReauthorClassification[] = [];
838
+ const reauthorRawLines: string[] = [];
786
839
  let fallbackFinding: string | undefined;
787
840
  let droppedNonePlaceholders = 0;
788
- let section: 'must' | 'should' | 'requirements' | null = null;
841
+ let section: 'must' | 'should' | 'requirements' | 'reauthor' | null = null;
789
842
  for (const l of lines) {
790
843
  if (/^MUST-?FIX/i.test(l)) { section = 'must'; continue; }
791
844
  if (/^SHOULD-?FIX/i.test(l)) { section = 'should'; continue; }
792
845
  if (/^REQUIREMENTS:\s*$/i.test(l)) { section = 'requirements'; continue; }
846
+ if (/^REAUTHOR-CLASSIFICATION:/i.test(l)) { section = 'reauthor'; continue; }
793
847
  if (/^(WATCH|VERDICT)/i.test(l)) { section = null; continue; }
794
848
  if (l.startsWith('- ')) {
795
849
  const f = l.slice(2).trim();
@@ -799,6 +853,18 @@ export function parseReviewResult(text: string): ReviewResult {
799
853
  else mustFix.push(f);
800
854
  } else if (section === 'should') shouldFix.push(f);
801
855
  else if (section === 'requirements') requirements.push(f);
856
+ else if (section === 'reauthor') {
857
+ reauthorRawLines.push(f);
858
+ const match = /^(CODE-DEFECT|AUTHORSHIP-DEFECT):\s*(.+)$/.exec(f);
859
+ if (match) {
860
+ const [finding, recommendation] = match[2]!.split(/\s+\|\s+SCOPE CUT \+ FU:\s*/i, 2);
861
+ reauthorCandidates.push({
862
+ class: match[1] === 'CODE-DEFECT' ? 'code-defect' : 'authorship-defect',
863
+ finding: finding!.trim(),
864
+ ...(recommendation?.trim() ? { recommendation: recommendation.trim() } : {}),
865
+ });
866
+ }
867
+ }
802
868
  else fallbackFinding ??= f;
803
869
  }
804
870
  }
@@ -826,15 +892,42 @@ export function parseReviewResult(text: string): ReviewResult {
826
892
  remainingMustFix: kept.length, heads: scopeRevertDemoted.map((finding) => safeLogText(finding, 120)) });
827
893
  } catch { /* observation must not change parsed review data */ }
828
894
  }
895
+ const candidateCounts = new Map<string, number>();
896
+ for (const candidate of reauthorCandidates) candidateCounts.set(candidate.finding, (candidateCounts.get(candidate.finding) ?? 0) + 1);
897
+ const referencedReauthorFindings = [...new Set(reauthorRawLines.map(rawReauthorFinding).filter(Boolean))];
898
+ const reauthorInvalidFindings = referencedReauthorFindings.filter((finding) => {
899
+ const rawLines = reauthorRawLines.filter((line) => rawReauthorFinding(line) === finding);
900
+ const candidates = reauthorCandidates.filter((candidate) => candidate.finding === finding);
901
+ return rawLines.length !== 1 || candidates.length !== 1
902
+ || (candidates[0]!.class === 'authorship-defect' && !hasReauthorFuRecommendation(candidates[0]!));
903
+ });
904
+ const invalidFindingSet = new Set(reauthorInvalidFindings);
905
+ const reauthorClassifications = round !== undefined && round >= 3 ? reauthorCandidates.filter((candidate) => {
906
+ if (!mustFix.includes(candidate.finding) || invalidFindingSet.has(candidate.finding) || candidateCounts.get(candidate.finding) !== 1) return false;
907
+ if (candidate.class === 'code-defect') return true;
908
+ return hasReauthorFuRecommendation(candidate);
909
+ }) : [];
829
910
  const fallback = text.match(/\n\[reviewer fallback: ([^\r\n]+)\]$/);
830
- return {
911
+ const result: ReviewResult = {
831
912
  verdict: finalVerdict,
832
913
  mustFix: mustFix.slice(0, 6),
833
914
  shouldFix: shouldFix.slice(0, 6),
834
915
  ...(scopeRevertDemoted.length ? { scopeRevertDemoted } : {}),
835
916
  ...(fallback ? { reviewerFallback: fallback[1] } : {}),
836
917
  ...(requirements.length ? { requirements } : {}),
918
+ ...(reauthorClassifications.length ? { reauthorClassifications } : {}),
837
919
  };
920
+ if (round !== undefined && round >= 3 && reauthorInvalidFindings.length) {
921
+ invalidReauthorFindingsByResult.set(result, new Set(reauthorInvalidFindings));
922
+ }
923
+ return result;
924
+ }
925
+
926
+ /** Extract the exact referenced finding from a raw classification bullet, even if its class label is invalid. */
927
+ function rawReauthorFinding(line: string): string {
928
+ const colon = line.indexOf(':');
929
+ const body = colon < 0 ? line : line.slice(colon + 1).trim();
930
+ return body.split(/\s+\|/, 1)[0]!.trim();
838
931
  }
839
932
 
840
933
  /** 판정 줄 없는 응답의 사유 값 — 기존 «리뷰 못 함» 경로(`reviewed:false` ⊕ `failureReason`)를 그대로 탄다. */
@@ -851,8 +944,22 @@ export const NO_VERDICT_LINE_REASON = 'no-verdict-line';
851
944
  * ⛔ 계약: `reviewed:false` 일 때 `verdict` 는 «의미 없는 자리값»(`pass`)이다 — catch·미주입 경로와 같다.
852
945
  * 소비처는 `reviewed` 를 «먼저» 본다(`renderReview`·`self-review-cli`·`review-adapter`·orchestrator).
853
946
  */
854
- function reviewedResultFromRaw(raw: string, runId: string | undefined, pass?: { index: number; of: number }): ReviewResult {
855
- if (VERDICT_LINE.test(raw)) return { ...parseReviewResult(raw), reviewed: true };
947
+ function reviewedResultFromRaw(
948
+ raw: string,
949
+ runId: string | undefined,
950
+ round?: number,
951
+ pass?: { index: number; of: number },
952
+ ): ReviewResult {
953
+ if (VERDICT_LINE.test(raw)) {
954
+ const parsed = parseReviewResult(raw, round);
955
+ if (round !== undefined && round >= 3) {
956
+ const result = { ...parsed, reviewed: true };
957
+ const invalid = invalidReauthorFindingsByResult.get(parsed);
958
+ if (invalid) invalidReauthorFindingsByResult.set(result, invalid);
959
+ return result;
960
+ }
961
+ return { ...parsed, reviewed: true };
962
+ }
856
963
  try {
857
964
  debug.log('review.verdict', NO_VERDICT_LINE_REASON, {
858
965
  chars: raw.length,
@@ -865,6 +972,24 @@ function reviewedResultFromRaw(raw: string, runId: string | undefined, pass?: {
865
972
  return { verdict: 'pass', mustFix: [], shouldFix: [], reviewed: false, failureReason: NO_VERDICT_LINE_REASON };
866
973
  }
867
974
 
975
+ function observeReauthorClassification(input: ReviewInput, result: ReviewResult): void {
976
+ const round = input.reviewContext?.round;
977
+ if (round === undefined || round < 3) return;
978
+ try {
979
+ const invalidFindings = invalidReauthorFindingsByResult.get(result) ?? new Set<string>();
980
+ const classifications = (result.reauthorClassifications ?? []).filter((entry) => !invalidFindings.has(entry.finding));
981
+ debug.log('review.reauthor', 'shadow-classification', {
982
+ round,
983
+ mode: 'shadow-only',
984
+ status: result.reviewed === false ? 'unavailable' : result.mustFix.length === 0 ? 'no-blockers' : 'observed',
985
+ classifications,
986
+ unclassified: (result.mustFix ?? []).filter((finding) =>
987
+ !classifications.some((entry) => entry.finding === finding)),
988
+ ...(input.reviewContext?.runId !== undefined ? { runId: input.reviewContext.runId } : {}),
989
+ });
990
+ } catch { /* Observation must not prevent the review. */ }
991
+ }
992
+
868
993
  /** REVIEW-PROMPT-SIZE — llmReview 호출 하나(단일·청크 패스)마다 프롬프트·응답 크기를 남긴다.
869
994
  * 관측이 리뷰를 막지 않는다(다른 review.* 관측과 같은 계약). */
870
995
  function logReviewPromptSize(
@@ -908,7 +1033,11 @@ export async function reviewPullRequest(
908
1033
  /** ⭐ `P4b` — 두 번째 인자로 이미지를 «같이» 받는다. 안 받는 리뷰어(API 백엔드)는 그냥 무시한다. */
909
1034
  llmReview?: (prompt: string, images?: readonly ReviewImage[]) => Promise<string>,
910
1035
  ): Promise<ReviewResult> {
911
- if (!llmReview) return { verdict: 'pass', mustFix: [], shouldFix: [], reviewed: false }; // 리뷰어 미주입=미검토.
1036
+ if (!llmReview) {
1037
+ const result = { verdict: 'pass' as const, mustFix: [], shouldFix: [], reviewed: false };
1038
+ observeReauthorClassification(input, result);
1039
+ return result; // 리뷰어 미주입=미검토.
1040
+ }
912
1041
  try {
913
1042
  const diffBudget = budgetedDiff(input.prDiff);
914
1043
  // Existing caller: self-review-cli.ts runSelfReviewCliCommand → deps.reviewPullRequest(reviewInput, llmReview).
@@ -1039,10 +1168,13 @@ export async function reviewPullRequest(
1039
1168
  const passImages = reviewImages.length > 0 && index === 0 ? reviewImages : undefined;
1040
1169
  const passRaw = await llmReview(passPrompt, passImages);
1041
1170
  logReviewPromptSize(passPrompt, passRaw, { pass: index + 1, chunked: true }, input.reviewContext?.runId);
1042
- passResults.push(reviewedResultFromRaw(passRaw, input.reviewContext?.runId, { index, of: plan.passes.length }));
1171
+ const passResult = reviewedResultFromRaw(passRaw, input.reviewContext?.runId, input.reviewContext?.round, { index, of: plan.passes.length });
1172
+ passResults.push(passResult);
1043
1173
  }
1174
+ const folded = foldReviewResults(passResults);
1175
+ observeReauthorClassification(input, folded);
1044
1176
  return {
1045
- ...foldReviewResults(passResults),
1177
+ ...folded,
1046
1178
  diffBudget: {
1047
1179
  // ⭐ 「전부 봤나」가 truncated 의 «정의»다 — 상한에 걸렸거나 초대형 파일이 있으면 여전히 true.
1048
1180
  truncated: !plan.coversAll,
@@ -1066,8 +1198,10 @@ export async function reviewPullRequest(
1066
1198
  const prompt = buildReviewPrompt(input, diffBudget, referencedContext.text, singleContextBudget);
1067
1199
  const raw = await llmReview(prompt, reviewImages.length > 0 ? reviewImages : undefined);
1068
1200
  logReviewPromptSize(prompt, raw, { pass: 1, chunked: false }, input.reviewContext?.runId);
1201
+ const result = reviewedResultFromRaw(raw, input.reviewContext?.runId, input.reviewContext?.round);
1202
+ observeReauthorClassification(input, result);
1069
1203
  return {
1070
- ...reviewedResultFromRaw(raw, input.reviewContext?.runId),
1204
+ ...result,
1071
1205
  diffBudget: {
1072
1206
  truncated: diffBudget.truncated,
1073
1207
  shownChars: diffBudget.shownChars,
@@ -1107,7 +1241,9 @@ export async function reviewPullRequest(
1107
1241
  // 출력 «경계마다» 막으면 새 소비처가 생길 때 하나를 빠뜨린다 ⇒ 여기서 한 번 막는다.
1108
1242
  // ⚠️ `review-observation` 의 `pr-reviewer` import 는 «타입 전용»이라 런타임 순환이 없다.
1109
1243
  const reason = failureReasonText(error);
1110
- return { verdict: 'pass', mustFix: [], shouldFix: [], reviewed: false, failureReason: reason };
1244
+ const result = { verdict: 'pass' as const, mustFix: [], shouldFix: [], reviewed: false, failureReason: reason };
1245
+ observeReauthorClassification(input, result);
1246
+ return result;
1111
1247
  }
1112
1248
  }
1113
1249
 
@@ -2155,7 +2155,12 @@ async function runSelfReviewCliCommandPinned(
2155
2155
  }
2156
2156
  const diffRead = diffResult.read;
2157
2157
  const loopLock = readReviewLoopBreakerLock(pr);
2158
- if (loopLock) {
2158
+ // A cap refusal writes a loop-breaker lock before an OP can authorize the
2159
+ // retry. Let the normal cap preflight/one-use claim govern that specific
2160
+ // lock; other loop-breaker reasons remain an unconditional stop.
2161
+ const opAuthorizedCapRetry = loopLock?.reason === 'review-cap-exceeded'
2162
+ && previousRoundCount >= 5 && opAllowsReviewOverCap(pr) && Boolean(reason);
2163
+ if (loopLock && !opAuthorizedCapRetry) {
2159
2164
  const message = `PR ${pr}: 반복 리뷰 중단 (${String(loopLock.reason ?? 'waiver-needed')}); OP 웨이버가 필요합니다.`;
2160
2165
  deps.observeDoctorReview?.('loop-breaker', { pr, head: diffRead.headCommit, state: 'waiver-needed', reason: loopLock.reason }, { level: 'warn' });
2161
2166
  deps.log('review.loop-breaker', { pr, head: diffRead.headCommit, state: 'waiver-needed', reason: loopLock.reason }, { level: 'warn' });
@@ -2551,7 +2556,10 @@ async function runSelfReviewCliCommandPinned(
2551
2556
  phaseIntent: intent,
2552
2557
  evidenceNote: evidenceLine,
2553
2558
  ...(reviewerContext.items.length ? { reviewerContext: reviewerContext.items } : {}),
2554
- ...(decompositionContext.runId ? { reviewContext: { runId: decompositionContext.runId } } : {}),
2559
+ reviewContext: {
2560
+ ...(decompositionContext.runId ? { runId: decompositionContext.runId } : {}),
2561
+ round: previousRoundCount + 1,
2562
+ },
2555
2563
  ...(deps.readReferencedFile ? { readReferencedFile: deps.readReferencedFile } : {}),
2556
2564
  ...(goalAcceptance.acceptance ? { acceptance: goalAcceptance.acceptance } : {}),
2557
2565
  };
@@ -8,7 +8,7 @@ You are a sub-agent spawned by a parent task. The parent has delegated a focused
8
8
 
9
9
  ## What you have
10
10
  - A task description (the `prompt` argument the parent sent)
11
- - Full tool access: Bash, Read, Edit, Grep, WebFetch
11
+ - Use the exact tool catalog supplied to this child. Standard CLI defaults are Bash, Read, Edit, Grep, and WebFetch; the TUI may provide a wider policy-filtered catalog.
12
12
  - Your own context window — what you read here does not pollute the parent's
13
13
 
14
14
  ## What you owe back
@@ -0,0 +1,221 @@
1
+ import { debug } from '../debug/log.js';
2
+
3
+ export interface ResearchFanoutAngle {
4
+ id: 'primary-data' | 'news-filings' | 'counterevidence';
5
+ label: string;
6
+ instruction: string;
7
+ }
8
+
9
+ export interface ResearchFanoutSource {
10
+ url: string;
11
+ title?: string;
12
+ excerpt?: string;
13
+ }
14
+
15
+ export interface ResearchFanoutWorkerResult {
16
+ text: string;
17
+ sources?: ResearchFanoutSource[];
18
+ /** Production workers set false when claims do not cite observed search results. */
19
+ verified?: boolean;
20
+ verificationError?: string;
21
+ }
22
+
23
+ export interface ResearchFanoutAngleResult {
24
+ angle: ResearchFanoutAngle;
25
+ status: 'complete' | 'failed';
26
+ text: string;
27
+ sources: ResearchFanoutSource[];
28
+ error?: string;
29
+ }
30
+
31
+ export interface ResearchFanoutResult {
32
+ angles: ResearchFanoutAngleResult[];
33
+ output: string;
34
+ }
35
+
36
+ export const RESEARCH_FANOUT_WORKER_TIMEOUT_MS = 90_000;
37
+
38
+ export type ResearchFanoutWorker = (
39
+ angle: ResearchFanoutAngle,
40
+ request: string,
41
+ signal?: AbortSignal,
42
+ ) => Promise<ResearchFanoutWorkerResult>;
43
+
44
+ export const RESEARCH_FANOUT_ANGLES: readonly ResearchFanoutAngle[] = [
45
+ {
46
+ id: 'primary-data',
47
+ label: '1차 데이터',
48
+ instruction: '공식 원문·공공 통계·기업/기관 발표에서 기준일, 기간, 분모, 수치와 상태를 확인한다.',
49
+ },
50
+ {
51
+ id: 'news-filings',
52
+ label: '뉴스·공시',
53
+ instruction: '날짜가 확인되는 최신 뉴스와 공시를 조사하고 사건 시점, 보도 시점, 진행 상태를 구분한다.',
54
+ },
55
+ {
56
+ id: 'counterevidence',
57
+ label: '반대 근거',
58
+ instruction: '주요 주장과 충돌하는 원문·데이터·반론을 찾아 어떤 조건에서 결론이 달라지는지 확인한다.',
59
+ },
60
+ ];
61
+
62
+ function errorText(error: unknown): string {
63
+ return error instanceof Error ? error.message : String(error);
64
+ }
65
+
66
+ function renderAngleResult(result: ResearchFanoutAngleResult): string[] {
67
+ const statusLabel = result.status === 'complete'
68
+ ? '완료'
69
+ : result.error === 'agent returned no verifiable sources' ? '보류(출처 없음)'
70
+ : result.error?.includes('citations') || result.error?.includes('search result')
71
+ ? '보류(근거 부족)' : '실패';
72
+ const lines = [`### ${result.angle.label} (${result.angle.id}) · ${statusLabel}`];
73
+ if (result.status === 'failed') lines.push(`조사 실패: ${result.error ?? 'unknown error'}`);
74
+ if (result.status === 'complete' && result.text.trim()) lines.push(result.text.trim());
75
+ if (result.sources.length > 0) {
76
+ lines.push('출처:');
77
+ for (const source of result.sources) {
78
+ lines.push(`- ${source.title ? `[${source.title}](${source.url})` : source.url}${source.excerpt ? ` — ${source.excerpt}` : ''}`);
79
+ }
80
+ }
81
+ return lines;
82
+ }
83
+
84
+ function parseSearchSources(output: string): ResearchFanoutSource[] {
85
+ const sources: ResearchFanoutSource[] = [];
86
+ for (const match of output.matchAll(/\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g)) {
87
+ const [, title, url] = match;
88
+ if (title && url) sources.push({ title, url });
89
+ }
90
+ return sources;
91
+ }
92
+
93
+ function hasOnlyVerifiedInlineCitations(output: string, sources: readonly ResearchFanoutSource[]): boolean {
94
+ const knownUrls = new Set(sources.map(({ url }) => url));
95
+ const contentLines = output.split(/\r?\n/).map((line) => line.trim())
96
+ .filter((line) => line && !line.startsWith('#') && !/^[-*_]{3,}$/.test(line));
97
+ const citedUrls = new Set<string>();
98
+ const everyClaimHasVerifiedCitations = contentLines.length > 0 && contentLines.every((line) => {
99
+ const links = [...line.matchAll(/\[[^\]]+\]\((https?:\/\/[^\s)]+)\)/g)].map((match) => match[1]!);
100
+ if (!links.length || links.some((url) => !knownUrls.has(url))) return false;
101
+ links.forEach((url) => citedUrls.add(url));
102
+ return true;
103
+ });
104
+ if (!everyClaimHasVerifiedCitations) return false;
105
+ // One observed result cannot carry an entire multi-claim synthesis. Require
106
+ // at least two independently retrieved URLs when the agent makes multiple claims.
107
+ return contentLines.length === 1 || citedUrls.size > 1;
108
+ }
109
+
110
+ /** Run three independent research agents concurrently; each rejection is retained as a failed angle. */
111
+ export async function runResearchFanout(
112
+ request: string,
113
+ worker: ResearchFanoutWorker,
114
+ options: { signal?: AbortSignal; runId?: string; workerTimeoutMs?: number } = {},
115
+ ): Promise<ResearchFanoutResult> {
116
+ const runId = options.runId ?? process.env.ELANOUS_RUN_ID;
117
+ const startedAt = Date.now();
118
+ debug.log('research.fanout', 'started', {
119
+ ...(runId ? { runId } : {}), requestChars: request.length,
120
+ angleIds: RESEARCH_FANOUT_ANGLES.map(({ id }) => id),
121
+ });
122
+
123
+ const settled = await Promise.allSettled(RESEARCH_FANOUT_ANGLES.map(async (angle) => {
124
+ const timeout = AbortSignal.timeout(options.workerTimeoutMs ?? RESEARCH_FANOUT_WORKER_TIMEOUT_MS);
125
+ const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;
126
+ const aborted = new Promise<never>((_, reject) => {
127
+ if (signal.aborted) reject(signal.reason ?? new Error('research agent aborted'));
128
+ else signal.addEventListener('abort', () => reject(signal.reason ?? new Error('research agent aborted')), { once: true });
129
+ });
130
+ return Promise.race([worker(angle, request, signal), aborted]);
131
+ }));
132
+ const angles = settled.map((result, index): ResearchFanoutAngleResult => {
133
+ const angle = RESEARCH_FANOUT_ANGLES[index]!;
134
+ if (result.status === 'rejected') {
135
+ return { angle, status: 'failed', text: '', sources: [], error: errorText(result.reason) };
136
+ }
137
+ const sources = (result.value.sources ?? []).filter((source) => /^https?:\/\//i.test(source.url));
138
+ const hasFindings = result.value.text.trim().length > 0;
139
+ const hasSources = sources.length > 0;
140
+ const verified = result.value.verified !== false;
141
+ return {
142
+ angle,
143
+ status: hasFindings && hasSources && verified ? 'complete' : 'failed',
144
+ text: result.value.text,
145
+ sources,
146
+ ...(!hasFindings ? { error: 'agent returned no findings' }
147
+ : !hasSources ? { error: 'agent returned no verifiable sources' }
148
+ : !verified ? { error: result.value.verificationError ?? 'agent claims did not cite observed search results' } : {}),
149
+ };
150
+ });
151
+ const output = ['## Parallel research angles', ...angles.flatMap(renderAngleResult)].join('\n\n');
152
+ const result: ResearchFanoutResult = { angles, output };
153
+ debug.log('research.fanout', 'completed', {
154
+ ...(runId ? { runId } : {}),
155
+ requestChars: request.length,
156
+ completeCount: angles.filter(({ status }) => status === 'complete').length,
157
+ failedAngleIds: angles.filter(({ status }) => status === 'failed').map(({ angle }) => angle.id),
158
+ sourceCount: angles.reduce((count, angle) => count + angle.sources.length, 0),
159
+ elapsedMs: Date.now() - startedAt,
160
+ });
161
+ return result;
162
+ }
163
+
164
+ /** Production worker: a read-only general sub-agent with only the research web search tool. */
165
+ export const runResearchSubagent: ResearchFanoutWorker = async (angle, request, signal) => {
166
+ const [{ dispatchAgent }, { buildOmniSearchTool, dispatchResearchOmniSearch }] = await Promise.all([
167
+ import('../skills/tools/agent.js'),
168
+ import('../skills/tools/omni-search.js'),
169
+ ]);
170
+ const prompt = [
171
+ `Research this question from the angle “${angle.label}”: ${request}`,
172
+ angle.instruction,
173
+ 'Use OmniSearch for web research. Return a concise synthesis with a precise date, denominator/time window and state when relevant.',
174
+ 'Attach a Markdown link for every factual claim. Clearly label unresolved conflicts and uncertainty. Never invent a source or date.',
175
+ ].join('\n\n');
176
+ const searchSources = new Map<string, ResearchFanoutSource>();
177
+ const result = await dispatchAgent({
178
+ description: `Research ${angle.label}`,
179
+ prompt,
180
+ subagent_type: 'general-purpose',
181
+ max_turns: 5,
182
+ mode: 'default',
183
+ }, {
184
+ cwd: process.cwd(), signal,
185
+ hostTools: [buildOmniSearchTool()],
186
+ dispatchTool: async (name, args) => {
187
+ if (name !== 'OmniSearch') throw new Error(`research agent tool is not permitted: ${name}`);
188
+ const search = await dispatchResearchOmniSearch(args, {
189
+ signal,
190
+ onSource: ({ url, title, snippet }) => searchSources.set(url, { url, title, excerpt: snippet }),
191
+ });
192
+ for (const source of parseSearchSources(search.output)) searchSources.set(source.url, source);
193
+ return search.output;
194
+ },
195
+ resolveAgentDef: () => ({
196
+ name: `research-${angle.id}`,
197
+ description: `Research sub-agent for ${angle.label}`,
198
+ role: angle.label,
199
+ goal: angle.instruction,
200
+ systemPrompt: 'You are a careful research analyst. Use web search, cite original URLs, preserve dates and uncertainty.',
201
+ tools: ['OmniSearch'],
202
+ permissionMode: 'read-only',
203
+ maxTurns: 5,
204
+ }),
205
+ });
206
+ const sources = [...searchSources.values()];
207
+ const verified = hasOnlyVerifiedInlineCitations(result.output, sources);
208
+ const hasSeveralClaims = result.output.split(/\r?\n/).filter((line) => line.trim() && !line.trim().startsWith('#')).length > 1;
209
+ return {
210
+ text: result.output,
211
+ sources,
212
+ verified,
213
+ ...(!verified ? {
214
+ verificationError: sources.length === 0
215
+ ? 'agent claims lack citations because OmniSearch returned no source'
216
+ : hasSeveralClaims && new Set([...result.output.matchAll(/\[[^\]]+\]\((https?:\/\/[^\s)]+)\)/g)].map((match) => match[1]!)).size < 2
217
+ ? 'one OmniSearch result cannot support multiple claims'
218
+ : 'agent claims lack verified inline citations to observed OmniSearch results',
219
+ } : {}),
220
+ };
221
+ };