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
@@ -10,6 +10,7 @@ import type { LLMUsage } from '../prompt-cache/types.js';
10
10
  import { debug } from '../debug/log.js';
11
11
  import { ensureDeviceFirstSteps, inspectDeviceFirstGoal } from './device-first.js';
12
12
  import { COMPLETION_BOUNDARY_STEP_PREFIX, FOLDED_DEVICE_FIRST_ACTION_MARKER } from './goal-author-decompose.js';
13
+ import { loadMockScenarioCatalog, type MockScenarioCatalog, type MockScenarioDevice, type MockScenarioEntry } from '../ux-sim/mock-scenario-catalog.js';
13
14
 
14
15
  function observeGoalAuthor(
15
16
  category: 'goal-author' | 'goal-author.clarify',
@@ -20,6 +21,7 @@ function observeGoalAuthor(
20
21
  debug.log(category === 'goal-author' ? 'harness.author' : 'harness.author.clarify', event, data);
21
22
  }
22
23
  import { getUserConfig } from '../user-config.js';
24
+ import { getProviderForConfig, streamLLM, type LLMMessage } from '../llm.js';
23
25
 
24
26
  export type GoalAuthorGrade = 'full' | 'lite';
25
27
  export type GoalAuthorGradeSource = 'flag' | 'env' | 'config' | 'default';
@@ -79,6 +81,12 @@ export interface GoalAuthorDeps {
79
81
  ground: (ask: string, groundingDeps?: GoalAuthorGroundingDeps) => Promise<CodebaseGrounding>;
80
82
  persistentGrounding?: GoalAuthorGroundingDeps;
81
83
  authorGrade?: GoalAuthorGradeSelection;
84
+ /** Read-only, compact inventory of reusable mocks and event-injection scenarios. */
85
+ mockScenarioCatalog?: string;
86
+ /** Production Terra reviewer precheck; omitted is disabled unless the shared config switch is on. */
87
+ reviewerPrecheckEnabled?: boolean;
88
+ /** Optional seam for focused tests; production uses the pinned Terra medium reviewer. */
89
+ reviewerPrecheck?: (document: string, authorRunId: string, context?: GoalAuthorReviewerPrecheckContext) => Promise<GoalAuthorReviewerPrecheckResult>;
82
90
  enhance: (ask: string, opts?: EnhanceOpts) => Promise<GoalEnhancement>;
83
91
  /** Additive enhancer options supplied by the file-writing entrypoint. */
84
92
  enhanceOpts?: EnhanceOpts;
@@ -137,12 +145,357 @@ export interface GoalAuthorDeps {
137
145
  authoringLessons?: string;
138
146
  }
139
147
 
148
+ export interface GoalAuthorReviewerPrecheckResult {
149
+ readonly suggestions: readonly string[];
150
+ readonly fixes: readonly string[];
151
+ /** Exact, replayable edits in fixes order; together they must explain the entire document diff. */
152
+ readonly fixEvidence?: readonly { readonly fix: string; readonly originalText: string; readonly revisedText: string }[];
153
+ readonly remainingNeedsHuman: readonly string[];
154
+ readonly revisedDocument: string;
155
+ readonly appliedFixes: readonly string[];
156
+ readonly unappliedItems: readonly string[];
157
+ }
158
+
159
+ export interface GoalAuthorReviewerPrecheckContext {
160
+ readonly conversationId: string;
161
+ readonly round: number;
162
+ readonly priorRejectionReasonCodes: readonly string[];
163
+ }
164
+
165
+ export type GoalAuthorReviewerDialogOutcome = 'skipped' | 'converged' | 'cap-hit' | 'provider-error';
166
+
167
+ export interface GoalAuthorReviewerDialogResult {
168
+ readonly document: string;
169
+ readonly status: 'skipped' | 'completed' | 'rejected-soft' | 'failed-soft';
170
+ readonly outcome: GoalAuthorReviewerDialogOutcome;
171
+ readonly rounds: number;
172
+ readonly hitl: boolean;
173
+ readonly result?: GoalAuthorReviewerPrecheckResult;
174
+ }
175
+
176
+ const GOAL_AUTHOR_REVIEWER_PRECHECK_MODEL = 'gpt-6.1-terra';
177
+
178
+ export function parseGoalAuthorReviewerPrecheck(raw: string): GoalAuthorReviewerPrecheckResult {
179
+ const text = raw.trim().replace(/^```(?:json)?\s*/iu, '').replace(/\s*```$/u, '');
180
+ const value: unknown = JSON.parse(text);
181
+ if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('reviewer response must be an object');
182
+ const record = value as Record<string, unknown>;
183
+ const readList = (key: string): string[] => {
184
+ const candidate = record[key];
185
+ if (!Array.isArray(candidate) || candidate.some((item) => typeof item !== 'string')) {
186
+ throw new Error(`reviewer response ${key} must be a string array`);
187
+ }
188
+ return candidate;
189
+ };
190
+ const revisedDocument = record.revisedDocument;
191
+ if (typeof revisedDocument !== 'string' || !revisedDocument.trim()) throw new Error('reviewer response revisedDocument must be non-empty text');
192
+ return {
193
+ suggestions: readList('suggestions'),
194
+ fixes: readList('fixes'),
195
+ ...(record.fixEvidence === undefined ? {} : {
196
+ fixEvidence: (() => {
197
+ const candidate = record.fixEvidence;
198
+ if (!Array.isArray(candidate) || candidate.some((item) => !item || typeof item !== 'object'
199
+ || typeof (item as Record<string, unknown>).fix !== 'string'
200
+ || typeof (item as Record<string, unknown>).originalText !== 'string'
201
+ || typeof (item as Record<string, unknown>).revisedText !== 'string')) {
202
+ throw new Error('reviewer response fixEvidence must be an array of { fix, originalText, revisedText }');
203
+ }
204
+ return candidate as { fix: string; originalText: string; revisedText: string }[];
205
+ })(),
206
+ }),
207
+ remainingNeedsHuman: readList('remainingNeedsHuman'),
208
+ revisedDocument,
209
+ appliedFixes: [],
210
+ unappliedItems: [],
211
+ };
212
+ }
213
+
214
+ function reviewerRevisionIsValid(original: string, revised: string): boolean {
215
+ if (!revised.trim() || verbatimOriginalAsk(revised) !== verbatimOriginalAsk(original)) return false;
216
+ if (parseGoalId(revised) !== parseGoalId(original)
217
+ || parseRootIntent(revised) !== parseRootIntent(original)
218
+ || parseGoalType(revised) !== parseGoalType(original)) return false;
219
+ if (JSON.stringify(canonicalBlocks(revised)) !== JSON.stringify(canonicalBlocks(original))) return false;
220
+ return !lintGoalFile(revised, 'reviewer-precheck').some((finding) => finding.level === 'ERROR');
221
+ }
222
+
223
+ function reviewerEditIsGrounded(original: string, edit: { fix: string; originalText: string; revisedText: string }): boolean {
224
+ if (!edit.originalText || edit.revisedText === edit.originalText || !edit.revisedText.startsWith(edit.originalText)) return false;
225
+ const acceptanceStart = original.indexOf('## ACCEPTANCE CRITERIA');
226
+ const evidenceStart = original.indexOf('## REQUIRED EVIDENCE');
227
+ const nextHeading = (start: number): number => {
228
+ const next = original.indexOf('\n## ', start + 1);
229
+ return next < 0 ? original.length : next;
230
+ };
231
+ const editStart = original.indexOf(edit.originalText);
232
+ if (editStart < 0 || original.indexOf(edit.originalText, editStart + edit.originalText.length) >= 0) return false;
233
+ const sectionTexts = [
234
+ acceptanceStart >= 0 ? original.slice(acceptanceStart + '## ACCEPTANCE CRITERIA'.length, nextHeading(acceptanceStart)) : '',
235
+ evidenceStart >= 0 ? original.slice(evidenceStart + '## REQUIRED EVIDENCE'.length, nextHeading(evidenceStart)) : '',
236
+ ];
237
+ const isCompleteCriterion = sectionTexts.some((section) => section.split('\n').some((line) =>
238
+ /^\s*[-*]\s+\S/u.test(line) && line.trim() === edit.originalText.trim()));
239
+ if (!isCompleteCriterion) return false;
240
+ const appended = edit.revisedText.slice(edit.originalText.length);
241
+ if (!/^\r?\n[ \t]*[-*][ \t]+\S/u.test(appended)) return false;
242
+ const added = appended
243
+ .replace(/^\r?\n[ \t]*[-*][ \t]*/u, '')
244
+ .replace(/^\[[a-z-]+\][ \t]*/iu, '')
245
+ .trim();
246
+ if (edit.fix !== added) return false;
247
+ const ask = verbatimOriginalAsk(original);
248
+ if (!added || !ask) return false;
249
+ const sentences = ask
250
+ .split(/(?<=[.!?])(?:[ \t]+|$)|\r?\n/u)
251
+ .map((sentence) => sentence.trim())
252
+ .filter(Boolean);
253
+ return sentences.includes(added);
254
+ }
255
+
256
+ export function resolveGoalAuthorReviewerPrecheckEnabled(config = getUserConfig()): boolean {
257
+ return config.tools.selfImplement.goalAuthorReviewerPrecheck === true;
258
+ }
259
+
260
+ export async function runGoalAuthorReviewerPrecheck(
261
+ document: string,
262
+ deps: { config?: ReturnType<typeof getUserConfig>; stream?: typeof streamLLM; reviewContext?: GoalAuthorReviewerPrecheckContext; mockScenarioCatalog?: string } = {},
263
+ ): Promise<GoalAuthorReviewerPrecheckResult> {
264
+ const config = deps.config ?? getUserConfig();
265
+ const pinnedConfig = {
266
+ ...config,
267
+ llm: { ...config.llm, provider: 'openai-codex' as const, model: GOAL_AUTHOR_REVIEWER_PRECHECK_MODEL },
268
+ };
269
+ const provider = getProviderForConfig(pinnedConfig, GOAL_AUTHOR_REVIEWER_PRECHECK_MODEL);
270
+ const prompt = [
271
+ 'Review this completed goal document before it is written. Return only JSON with string-array fields suggestions, fixes, remainingNeedsHuman, a fixEvidence array of { fix, originalText, revisedText }, and a revisedDocument string.',
272
+ 'Challenge each completion-boundary constraint instead of treating it as inherently necessary. 제약을 의심하라: 저작 문면의 세계와 구현의 세계에서 같은 제약인가? 카탈로그에 있는 목장치나 사건 주입으로 같은 동작을 관찰할 수 있는가? 실물 점검만 요구하는 경계라면 의도를 보존하는 목장치·주입 사건을 제안하라. Do not require a real-world inspection by default. Preserve a live check when the ask explicitly requires an external-system outcome.',
273
+ ...(deps.mockScenarioCatalog?.trim() ? ['Reusable mock-device and event-injection catalog (reference only, not a completion gate):', deps.mockScenarioCatalog.trim()] : []),
274
+ 'Apply each necessary fix to revisedDocument exactly once while preserving the original ask, GoalId, RootIntent, GoalType, every existing criterion and scope boundary, and canonical section structure. Be strictly conservative: only append one complete sentence copied verbatim from the original ask to an existing acceptance-criteria or required-evidence line; never append a partial substring or clause, especially one inside a negation or condition, and do not delete or reword existing text, add new scope, or edit other sections. For every fixes item, include one fixEvidence object in the same order: fixes item and fix must both equal the exact complete sentence appended from the original ask; originalText and revisedText must be exact spans where revisedText starts with originalText and appends that sentence, and replaying every single replacement reproduces the complete revisedDocument with no other edits. If you cannot explain and ground every change this way, return no fixes and leave revisedDocument byte-for-byte unchanged. Keep optional suggestions separate; list unresolved decisions or evidence as remainingNeedsHuman.',
275
+ ...(deps.reviewContext ? [
276
+ `Author feedback for round ${deps.reviewContext.round}: prior proposal rejection codes = ${deps.reviewContext.priorRejectionReasonCodes.join(', ') || '(none)'}. Reconsider only those rejected proposals; do not repeat an unsupported edit.`,
277
+ ] : []),
278
+ document,
279
+ ].join('\n\n');
280
+ const messages: LLMMessage[] = [{ role: 'user', content: prompt }];
281
+ let actualProvider = provider.name;
282
+ let actualModel = GOAL_AUTHOR_REVIEWER_PRECHECK_MODEL;
283
+ const raw = await (deps.stream ?? streamLLM)(messages, () => undefined, {
284
+ provider,
285
+ model: GOAL_AUTHOR_REVIEWER_PRECHECK_MODEL,
286
+ reasoningEffort: 'medium',
287
+ maxTokens: 3000,
288
+ usageRole: 'review',
289
+ usagePhase: 'author-reviewer-precheck',
290
+ usageSite: 'author-reviewer-precheck',
291
+ onResolvedProvider: (resolvedProvider, resolvedModel) => { actualProvider = resolvedProvider; actualModel = resolvedModel; },
292
+ });
293
+ debug.log('author.reviewer-precheck', 'response', { provider: actualProvider, model: actualModel, responseChars: raw.length });
294
+ return parseGoalAuthorReviewerPrecheck(raw);
295
+ }
296
+
297
+ export async function executeGoalAuthorReviewerPrecheck(
298
+ enabled: boolean,
299
+ document: string,
300
+ authorRunId: string,
301
+ run: (document: string, context?: GoalAuthorReviewerPrecheckContext) => Promise<GoalAuthorReviewerPrecheckResult> = (value) => runGoalAuthorReviewerPrecheck(value),
302
+ observe: (event: string, data: Record<string, unknown>) => void = (event, data) => debug.log('author.reviewer-precheck', event, data),
303
+ context?: GoalAuthorReviewerPrecheckContext,
304
+ ): Promise<{ status: 'skipped' | 'completed' | 'rejected-soft' | 'failed-soft'; result?: GoalAuthorReviewerPrecheckResult }> {
305
+ if (!enabled) {
306
+ observe('precheck-skipped', { authorRunId, reason: 'disabled', providerCalls: 0 });
307
+ return { status: 'skipped' };
308
+ }
309
+ try {
310
+ const proposed = await run(document, context);
311
+ const evidence = proposed.fixEvidence ?? [];
312
+ let replayed = document;
313
+ let fixesSupported = proposed.fixes.length === 0
314
+ ? proposed.revisedDocument === document && evidence.length === 0
315
+ : evidence.length === proposed.fixes.length;
316
+ if (fixesSupported) {
317
+ for (let index = 0; index < proposed.fixes.length; index += 1) {
318
+ const edit = evidence[index];
319
+ if (!edit || edit.fix !== proposed.fixes[index] || !reviewerEditIsGrounded(document, edit) || !replayed.includes(edit.originalText)) {
320
+ fixesSupported = false;
321
+ break;
322
+ }
323
+ const at = replayed.indexOf(edit.originalText);
324
+ if (replayed.indexOf(edit.originalText, at + edit.originalText.length) !== -1) {
325
+ fixesSupported = false;
326
+ break;
327
+ }
328
+ replayed = replayed.slice(0, at) + edit.revisedText + replayed.slice(at + edit.originalText.length);
329
+ }
330
+ fixesSupported = fixesSupported && replayed === proposed.revisedDocument;
331
+ }
332
+ const valid = reviewerRevisionIsValid(document, proposed.revisedDocument)
333
+ && fixesSupported
334
+ && (proposed.fixes.length === 0 || proposed.revisedDocument !== document);
335
+ const result: GoalAuthorReviewerPrecheckResult = valid
336
+ ? { ...proposed, appliedFixes: proposed.fixes, unappliedItems: [] }
337
+ : {
338
+ ...proposed,
339
+ revisedDocument: document,
340
+ appliedFixes: [],
341
+ unappliedItems: proposed.fixes,
342
+ remainingNeedsHuman: [...new Set([...proposed.remainingNeedsHuman, ...proposed.fixes])],
343
+ };
344
+ const status = valid ? 'completed' : 'rejected-soft';
345
+ observe(valid ? 'completed' : 'revision-rejected', {
346
+ authorRunId,
347
+ provider: 'openai-codex',
348
+ model: GOAL_AUTHOR_REVIEWER_PRECHECK_MODEL,
349
+ status,
350
+ proposedSuggestionCount: result.suggestions.length,
351
+ proposedFixCount: result.fixes.length,
352
+ appliedFixCount: result.appliedFixes.length,
353
+ appliedFixes: result.appliedFixes,
354
+ fixEvidence: result.fixEvidence ?? [],
355
+ correctedItems: result.appliedFixes.length,
356
+ unappliedItemCount: result.unappliedItems.length,
357
+ unappliedItems: result.unappliedItems,
358
+ remainingNeedsHuman: result.remainingNeedsHuman,
359
+ suggestionsResult: result.suggestions,
360
+ fixesResult: result.fixes,
361
+ remainingNeedsHumanResult: result.remainingNeedsHuman,
362
+ });
363
+ return { status, result };
364
+ } catch (error) {
365
+ observe('failed-soft', {
366
+ authorRunId,
367
+ reason: error instanceof Error ? error.message : String(error),
368
+ correctedItems: 0,
369
+ });
370
+ return { status: 'failed-soft' };
371
+ }
372
+ }
373
+
374
+ /** Run a bounded reviewer→author dialogue; every proposal remains grounded by the existing exact-edit validator. */
375
+ export async function executeGoalAuthorReviewerDialog(
376
+ enabled: boolean,
377
+ document: string,
378
+ conversationId: string,
379
+ run: (document: string, context: GoalAuthorReviewerPrecheckContext) => Promise<GoalAuthorReviewerPrecheckResult> = (value, context) => runGoalAuthorReviewerPrecheck(value, { reviewContext: context }),
380
+ observe: (event: string, data: Record<string, unknown>) => void = (event, data) => debug.log('author.dialog', event, data),
381
+ ): Promise<GoalAuthorReviewerDialogResult> {
382
+ const emit = (event: string, data: Record<string, unknown>): void => {
383
+ try { observe(event, data); } catch { /* observability never changes author output */ }
384
+ };
385
+ let currentDocument = document;
386
+ let lastResult: GoalAuthorReviewerPrecheckResult | undefined;
387
+ let status: GoalAuthorReviewerDialogResult['status'] = 'completed';
388
+ let outcome: GoalAuthorReviewerDialogOutcome = 'converged';
389
+ let rolledBack = false;
390
+ let rounds = 0;
391
+ let hitl = false;
392
+ let priorRejectionReasonCodes: string[] = [];
393
+ const allSuggestions: string[] = [];
394
+ const allFixes: string[] = [];
395
+ const allFixEvidence: NonNullable<GoalAuthorReviewerPrecheckResult['fixEvidence']>[number][] = [];
396
+ const allAppliedFixes: string[] = [];
397
+ const allUnappliedItems: string[] = [];
398
+ const allRemainingNeedsHuman: string[] = [];
399
+
400
+ if (!enabled) {
401
+ emit('author.reviewer-precheck.skipped', { authorRunId: conversationId, conversationId, runId: conversationId, reason: 'disabled', providerCalls: 0 });
402
+ return { document, status: 'skipped', outcome: 'skipped', rounds: 0, hitl: false };
403
+ }
404
+
405
+ for (let round = 1; round <= 2; round += 1) {
406
+ rounds = round;
407
+ const context: GoalAuthorReviewerPrecheckContext = { conversationId, round, priorRejectionReasonCodes };
408
+ const response = await executeGoalAuthorReviewerPrecheck(
409
+ true,
410
+ currentDocument,
411
+ conversationId,
412
+ (candidate, receivedContext) => run(candidate, receivedContext ?? context),
413
+ (event, data) => emit(`author.reviewer-precheck.${event}`, data),
414
+ context,
415
+ );
416
+ status = response.status;
417
+ lastResult = response.result ?? lastResult;
418
+ if (response.status === 'failed-soft') {
419
+ outcome = 'provider-error';
420
+ currentDocument = document;
421
+ rolledBack = allAppliedFixes.length > 0;
422
+ break;
423
+ }
424
+ if (!response.result) break;
425
+
426
+ const result = response.result;
427
+ allSuggestions.push(...result.suggestions);
428
+ allFixes.push(...result.fixes);
429
+ allFixEvidence.push(...(result.fixEvidence ?? []));
430
+ allAppliedFixes.push(...result.appliedFixes);
431
+ allUnappliedItems.push(...result.unappliedItems);
432
+ allRemainingNeedsHuman.push(...result.remainingNeedsHuman);
433
+ const proposalCount = result.fixes.length;
434
+ const appliedCount = result.appliedFixes.length;
435
+ const rejectedCount = result.unappliedItems.length;
436
+ const reasonCodes = rejectedCount > 0 ? ['fix-not-grounded'] : [];
437
+ emit('author.reviewer.round', {
438
+ conversationId,
439
+ runId: conversationId,
440
+ round,
441
+ proposalCount,
442
+ appliedCount,
443
+ rejectedCount,
444
+ rejectionReasonCodes: reasonCodes,
445
+ });
446
+ if (response.status === 'completed') currentDocument = result.revisedDocument;
447
+
448
+ const unresolved = rejectedCount > 0 || result.remainingNeedsHuman.length > 0;
449
+ if (!unresolved && appliedCount === 0) {
450
+ outcome = 'converged';
451
+ break;
452
+ }
453
+ priorRejectionReasonCodes = reasonCodes;
454
+ if (round === 2) {
455
+ outcome = 'cap-hit';
456
+ hitl = true;
457
+ }
458
+ }
459
+
460
+ emit('author.dialog.closed', { conversationId, runId: conversationId, outcome, rounds, hitl });
461
+ const aggregatedResult = lastResult ? {
462
+ ...lastResult,
463
+ suggestions: [...new Set(allSuggestions)],
464
+ fixes: [...new Set(allFixes)],
465
+ fixEvidence: allFixEvidence,
466
+ appliedFixes: rolledBack ? [] : [...new Set(allAppliedFixes)],
467
+ unappliedItems: [...new Set([...allUnappliedItems, ...(rolledBack ? allAppliedFixes : [])])],
468
+ remainingNeedsHuman: [...new Set([...allRemainingNeedsHuman, ...(rolledBack ? allAppliedFixes : [])])],
469
+ revisedDocument: currentDocument,
470
+ } : undefined;
471
+ return {
472
+ document: currentDocument,
473
+ status,
474
+ outcome,
475
+ rounds,
476
+ hitl,
477
+ ...(aggregatedResult ? { result: aggregatedResult } : {}),
478
+ };
479
+ }
480
+
140
481
  export type GoalAuthorGroundingPath = 'groundMissionInCodebase';
141
482
 
142
483
  export interface GoalAuthorGroundingDeps {
143
484
  /** Omit to preserve persistent grounding; false makes the authoring experiment opt out. */
144
485
  persistent?: false;
145
- groundMission?: (ask: string, deps: { cwd: string; seedPaths?: readonly string[]; persistent?: false }) => Promise<CodebaseGrounding>;
486
+ groundMission?: (ask: string, deps: { cwd: string; seedPaths?: readonly string[]; persistent?: false; mockScenarioCatalog?: string }) => Promise<CodebaseGrounding>;
487
+ /** Reference inventory for selecting existing mock devices during goal grounding. */
488
+ mockScenarioCatalog?: string;
489
+ }
490
+
491
+ /** Compact prompt view of the canonical catalog; detailed run evidence stays in the catalog itself. */
492
+ export function renderGoalAuthorMockScenarioCatalog(catalog: MockScenarioCatalog = loadMockScenarioCatalog()): string {
493
+ return [
494
+ 'Reusable mock devices (src/ux-sim/mock-scenario-catalog.json):',
495
+ ...catalog.devices.map((device) => `- ${device.id} (${device.name}): target=${device.target}; inputs=${device.inputs.join(', ')}; observes=${device.observations.join(', ')}; entry=${device.entryCommands.join(' | ')}`),
496
+ 'Reusable event-injection scenarios:',
497
+ ...catalog.scenarios.map((scenario) => `- ${scenario.id} (${scenario.kind}, device=${scenario.device}): trigger=${scenario.trigger}; observe=${scenario.observe.join(', ')}; expected=${scenario.expected}`),
498
+ ].join('\n');
146
499
  }
147
500
 
148
501
  export interface GoalAuthorGroundingResult {
@@ -663,9 +1016,164 @@ export function inspectGoalDoneBoundary(document: string): { values: Partial<Rec
663
1016
  return { values, missing: GOAL_DONE_BOUNDARY_LABELS.filter((label) => !values[label]) };
664
1017
  }
665
1018
 
666
- export function explicitGoalDoneBoundaryLines(ask: string): string[] {
1019
+ function goalDoneTestPaths(targetPath: string): string[] {
1020
+ if (/\.(?:test|spec)\.[cm]?[jt]sx?$/i.test(targetPath)) return [targetPath];
1021
+ const source = /^(.*)\.([cm]?[jt]sx?)$/i.exec(targetPath);
1022
+ if (!source) return [`${targetPath}.test.ts`, `${targetPath}.spec.ts`];
1023
+ const extension = source[2]!.toLowerCase();
1024
+ const siblingExtensions = extension === 'tsx' ? ['tsx', 'ts'] : extension === 'jsx' ? ['jsx', 'js'] : extension === 'ts' ? ['ts', 'tsx'] : extension === 'js' ? ['js', 'jsx'] : [extension];
1025
+ return siblingExtensions.flatMap((testExtension) => [`${source[1]}.test.${testExtension}`, `${source[1]}.spec.${testExtension}`]);
1026
+ }
1027
+
1028
+ function bunTestEvidencePath(command: string | undefined): string | undefined {
1029
+ if (command === undefined) return undefined;
1030
+ return /^bun\s+test\s+(?:(?:--\s+)?)(\S+\.(?:test|spec)\.[cm]?[jt]sx?)(?:\s|$)/u.exec(unwrapGoalDoneValue(command))?.[1];
1031
+ }
1032
+
1033
+ function goalPathTokens(paths: readonly string[]): Set<string> {
1034
+ return new Set(paths.map((path) => path.split(/[\\/]/u).at(-1) ?? path)
1035
+ .flatMap((path) => path.toLowerCase().split(/[._-]+/u))
1036
+ .filter((token) => token.length > 2 && !['src', 'test', 'tests', 'spec', 'tsx', 'ts', 'jsx', 'js'].includes(token)));
1037
+ }
1038
+
1039
+ function goalPathStems(paths: readonly string[]): Set<string> {
1040
+ return new Set(paths.map((path) => (path.split(/[\\/]/u).at(-1) ?? path).toLowerCase()
1041
+ .replace(/\.(?:test|spec)\.[^.]+$/u, '')
1042
+ .replace(/\.[^.]+$/u, '')));
1043
+ }
1044
+
1045
+ function matchingPathCount(paths: readonly string[], targetPaths: readonly string[]): number {
1046
+ const targetStems = goalPathStems(targetPaths);
1047
+ if ([...goalPathStems(paths)].some((stem) => targetStems.has(stem))) return 10;
1048
+ const targetTokens = goalPathTokens(targetPaths);
1049
+ return [...goalPathTokens(paths)].filter((token) => targetTokens.has(token)).length;
1050
+ }
1051
+
1052
+ function behaviorTokens(value: string): Set<string> {
1053
+ const stop = new Set(['the', 'and', 'with', 'from', 'this', 'that', 'when', 'then', 'into', 'only', 'are', 'is', 'for', 'bun', 'test', 'code', 'boundary', 'request', 'expected', 'target', 'file', '완료', '경계', '증거', '명령', '대상', '요청', '기대', '시험', '확인', '시나리오']);
1054
+ return new Set((value.toLowerCase().match(/[\p{L}\p{N}]{2,}/gu) ?? []).filter((token) => !stop.has(token)));
1055
+ }
1056
+
1057
+ function matchingScenarioBehaviorCount(scenario: MockScenarioEntry, ask: string): number {
1058
+ const { values } = inspectGoalDoneBoundary(ask);
1059
+ const requestedText = `${values['완료 경계 코드'] ?? ''} ${values['완료 경계 실물'] ?? ''}`
1060
+ .replace(/(?:실물|실제)\s*(?:점검|검증|확인|테스트)\s*(?:으로|로)?/giu, '')
1061
+ .replace(/real[- ]world\s+(?:check|inspection|verification|test)/giu, '');
1062
+ const describedText = `${scenario.name} ${scenario.kind} ${scenario.trigger} ${scenario.observe.join(' ')} ${scenario.expected}`;
1063
+ const requested = behaviorTokens(requestedText);
1064
+ const described = behaviorTokens(describedText);
1065
+ const polarity = (text: string, token: string): boolean => {
1066
+ const words = text.toLowerCase().match(/[\p{L}\p{N}]+/gu) ?? [];
1067
+ return words.some((word, index) => word === token && words.slice(Math.max(0, index - 3), index).some((nearby) => /^(?:not|never|no|without|isn't|doesn't|않|못|아니)/u.test(nearby)));
1068
+ };
1069
+ const oppositePairs = [
1070
+ ['distinct', 'indistinguishable'], ['preserved', 'lost'], ['visible', 'hidden'], ['visible', 'invisible'],
1071
+ ['harvestable', 'unharvestable'], ['independent', 'dependent'], ['succeeds', 'fails'], ['accepted', 'rejected'],
1072
+ ];
1073
+ const shared = [...described].filter((token) => requested.has(token));
1074
+ const covered = new Set(described);
1075
+ if (described.has('independent')) covered.add('distinct');
1076
+ if (described.has('distinct')) covered.add('independent');
1077
+ if (shared.some((token) => polarity(requestedText, token) !== polarity(describedText, token))
1078
+ || [...requested].some((token) => !covered.has(token))
1079
+ || oppositePairs.some(([left, right]) => (requested.has(left) && described.has(right)) || (requested.has(right) && described.has(left)))) return 0;
1080
+ return shared.length;
1081
+ }
1082
+
1083
+ function nextGoalScenarioId(catalogIds: readonly string[], targets: readonly string[]): string {
1084
+ const targetName = targets.map((path) => path.split(/[\\/]/u).at(-1) ?? '')
1085
+ .map((name) => name.replace(/\.[^.]+$/u, '').replace(/\.(?:test|spec)$/u, ''))
1086
+ .find(Boolean) ?? 'TARGET';
1087
+ const slug = targetName.toUpperCase().replace(/[^A-Z0-9]+/gu, '-').replace(/^-|-$/gu, '').slice(0, 32) || 'TARGET';
1088
+ const prefix = `MK-${slug}-TDD-EVIDENCE`;
1089
+ const existing = new Set(catalogIds);
1090
+ for (let sequence = 1; sequence <= 99; sequence++) {
1091
+ const candidate = `${prefix}-${String(sequence).padStart(2, '0')}`;
1092
+ if (!existing.has(candidate)) return candidate;
1093
+ }
1094
+ return `${prefix}-${Date.now().toString(36).toUpperCase()}`;
1095
+ }
1096
+
1097
+ function selectGoalMockStage(ask: string, targets: readonly string[]): { device: MockScenarioDevice; scenario?: MockScenarioEntry; pathMatched: boolean } | undefined {
1098
+ const catalog = loadMockScenarioCatalog();
1099
+ const matched = catalog.devices
1100
+ .map((candidate) => ({ candidate, score: matchingPathCount([...candidate.implementation, ...candidate.tests], targets) }))
1101
+ .filter((entry) => entry.score >= 2)
1102
+ .sort((left, right) => right.score - left.score)[0];
1103
+ const device = matched?.candidate
1104
+ ?? (/(?:author|goal|mission|저작|골|미션)/iu.test(`${targets.join(' ')}\n${ask}`)
1105
+ ? catalog.devices.find((candidate) => candidate.id === 'product-devices')
1106
+ : catalog.devices.find((candidate) => candidate.id === 'scenario-runner'));
1107
+ if (!device) return undefined;
1108
+ const scenario = catalog.scenarios
1109
+ .filter((candidate) => candidate.device === device.id)
1110
+ .map((candidate) => ({ candidate, pathScore: matchingPathCount([...candidate.implementation, ...candidate.tests], targets), behaviorScore: matchingScenarioBehaviorCount(candidate, ask) }))
1111
+ .filter((entry) => entry.pathScore >= 2 && entry.behaviorScore >= 2)
1112
+ .sort((left, right) => right.behaviorScore - left.behaviorScore || right.pathScore - left.pathScore)[0]?.candidate;
1113
+ return { device, ...(scenario ? { scenario } : {}), pathMatched: Boolean(matched) };
1114
+ }
1115
+
1116
+ function isGenericRealWorldInspectionBoundary(boundary: string, ask: string): boolean {
1117
+ const combined = `${boundary}\n${ask}`;
1118
+ const asksForRealInspection = /(?:실물\s*(?:점검|검증|확인|테스트)|실제\s*(?:점검|검증|확인|테스트)|real[- ]world\s+(?:check|inspection|verification|test)|live\s+(?:check|inspection|verification|test))/iu.test(boundary);
1119
+ const namesExternalOutcome = /(?:외부\s*(?:시스템|서비스|서버|클러스터|API|데이터베이스|DB)|실서비스|운영\s*(?:시스템|서비스|서버|클러스터|API|데이터베이스|DB)|실제\s*(?:계정|결제|API|서버|클러스터|고객|사용자)|(?:고객|사용자|customer|client|recipient).{0,20}(?:메일|이메일|email|발송|전송|receive|send)|(?:메일|이메일|email).{0,20}(?:고객|사용자|customer|client|recipient|발송|전송|receive|send)|\b(?:external\s+(?:system|service|server|cluster|api|database|db)|(?:actual|real|live|production|staging|stage|external)\s+(?:[\w-]+\s+){0,2}(?:system|service|server|cluster|api|database|db)|(?:staging|stage|production|prod|test|dev)\s+(?:system|service|server|cluster|api|database|db)|database|db|email|mail|slack|discord|teams|telegram|webhook|channel|gcp\d+|github|stripe|aws|production\s+\w+|live\s+(?:api|service|server|cluster)|(?:posts?|sends?|publishes?|writes?|pushes?|creates?|deletes?|charges?|updates?|submits?|delivers?|notifies?)\b.{0,80}\b(?:to|on|into|against|via))\b)/iu.test(combined);
1120
+ return asksForRealInspection && !namesExternalOutcome;
1121
+ }
1122
+
1123
+ export function explicitGoalDoneBoundaryLines(ask: string, repositoryRoot?: string): string[] {
667
1124
  const { values } = inspectGoalDoneBoundary(ask);
668
- return GOAL_DONE_BOUNDARY_LABELS.flatMap((label) => values[label] ? [`- ${label}: ${values[label]}`] : []);
1125
+ const explicitLines = GOAL_DONE_BOUNDARY_LABELS.flatMap((label) => values[label] ? [`- ${label}: ${values[label]}`] : []);
1126
+ // Keep the exported extractor's original contract for callers that only ask
1127
+ // for verbatim values. Goal authoring opts into catalog planning by supplying
1128
+ // its repository root at the production call sites below.
1129
+ if (repositoryRoot === undefined) return explicitLines;
1130
+ const unquotedAsk = ask.replace(/```[\s\S]*?```/gu, '');
1131
+ const targets = declaredTargetPaths(unquotedAsk);
1132
+ const existingEvidence = values['완료 경계 증거 명령'];
1133
+ const targetTestPaths = targets.flatMap(goalDoneTestPaths);
1134
+ const existingBunTestPath = bunTestEvidencePath(existingEvidence);
1135
+ const testPath = targetTestPaths.find((path) => existsSync(resolve(repositoryRoot, path)))
1136
+ ?? (existingBunTestPath && targetTestPaths.includes(existingBunTestPath) ? existingBunTestPath : undefined)
1137
+ ?? targetTestPaths[0]
1138
+ ?? existingBunTestPath;
1139
+ const shouldReplaceEvidence = existingBunTestPath === undefined;
1140
+ const plannedTestPath = !shouldReplaceEvidence && existingBunTestPath ? existingBunTestPath : testPath;
1141
+ const evidenceCommand = shouldReplaceEvidence && testPath ? `bun test ${testPath}` : existingEvidence;
1142
+ const needsNewTest = plannedTestPath !== undefined && !existsSync(resolve(repositoryRoot, plannedTestPath));
1143
+ const mockStage = targets.length ? selectGoalMockStage(ask, targets) : undefined;
1144
+ const lines = GOAL_DONE_BOUNDARY_LABELS.flatMap((label) => {
1145
+ if (label === '완료 경계 증거 명령' && evidenceCommand !== undefined) return [`- ${label}: ${evidenceCommand}`];
1146
+ return values[label] ? [`- ${label}: ${values[label]}`] : [];
1147
+ });
1148
+ if (needsNewTest && plannedTestPath) lines.push(`- 신설: ${plannedTestPath}`);
1149
+ if (shouldReplaceEvidence && existingEvidence && /type-?check|tsc|typescript/iu.test(existingEvidence)) {
1150
+ lines.push(`- 증거 보충: ${existingEvidence} (타입검사는 보조 검증)`);
1151
+ }
1152
+ if (mockStage) {
1153
+ lines.push(`- 장치: ${mockStage.device.id} — ${mockStage.device.name} (카탈로그 경로 일치: ${[...mockStage.device.implementation, ...mockStage.device.tests].filter((path) => matchingPathCount([path], targets) > 0).join(' · ') || mockStage.device.target})`);
1154
+ if (mockStage.scenario) {
1155
+ lines.push(`- 시나리오: ${mockStage.scenario.id} — ${mockStage.scenario.name}`);
1156
+ } else {
1157
+ const id = nextGoalScenarioId(loadMockScenarioCatalog().scenarios.map((scenario) => scenario.id), targets);
1158
+ const requestedCode = values['완료 경계 코드'] ?? '요청 대상의 완료 경계';
1159
+ const requestedObservation = values['완료 경계 실물'] ?? '격리 시험에서 요청된 생산 동작과 결과를 관측한다';
1160
+ lines.push(`- 시나리오: 신설 초안 (MS-id 후보: ${id})`);
1161
+ lines.push(`- 시나리오 초안: 사건은 ${targets.join(' · ') || '요청 대상'}에 «${requestedCode}» 경계를 적용한 입력; 기대는 생산 경로에서 «${requestedObservation}»을 관측하고 bun test ${plannedTestPath ?? '<대상 시험 파일>'}로 GREEN을 확인하는 것이다. 자식은 기존 카탈로그 API·ScenarioV0 형식에 맞춰 요청 대상의 사건·기대를 구체화해 등록한다.`);
1162
+ }
1163
+ const realWorldBoundary = values['완료 경계 실물'];
1164
+ if (realWorldBoundary && isGenericRealWorldInspectionBoundary(realWorldBoundary, ask) && mockStage?.pathMatched) {
1165
+ const { device, scenario } = mockStage;
1166
+ if (scenario) {
1167
+ lines.push(`- 목장치 치환안: 완료 경계 실물의 일반 실물 점검을 ${device.id} (${device.name})로 대체 제안; 기존 사건 주입 ${scenario.id}: ${scenario.trigger}; 관측=${scenario.observe.join(' · ')}; 기대=${scenario.expected}`);
1168
+ } else {
1169
+ const requestedCode = values['완료 경계 코드'] ?? '요청 코드 경계';
1170
+ const requestedObservation = values['완료 경계 실물'] ?? '요청된 생산 동작과 결과';
1171
+ lines.push(`- 목장치 치환안: ${device.id} (${device.name}) 신규 ScenarioV0 초안·미등록; trigger=«${requestedCode}»가 참이 되도록 사건을 입력한다(카탈로그 입력 후보: ${device.inputs.join(' · ')}); observe=«${requestedObservation}»(관측 후보: ${device.observations.join(' · ')}); expected=«${requestedObservation}». 입력·관측 selector를 해당 요청과 맞춰 등록하고 회귀 시험으로 확인할 제안이다.`);
1172
+ }
1173
+ }
1174
+ }
1175
+ if (plannedTestPath) lines.push(`- 검증 계획(TDD): 장치 ${mockStage?.device.id ?? '미선정'} · 시나리오 ${mockStage?.scenario?.id ?? '신설 초안'} · ${needsNewTest ? '신설 시험' : '기존 시험에 요청 동작 회귀 사례 추가'} ${plannedTestPath} · 피처 시험 bun test ${plannedTestPath}를 구현 전에 RED로 확인한다.`);
1176
+ return lines;
669
1177
  }
670
1178
 
671
1179
  /**
@@ -2535,6 +3043,8 @@ export interface AuthoredGoal {
2535
3043
  authorRunId: string;
2536
3044
  /** AUTHOR-TIMEBOX: present only when the `ground` phase was short-circuited for exceeding its budget. */
2537
3045
  groundingTimebox?: GoalAuthorGroundingTimebox;
3046
+ /** Raw structured reviewer output is preserved for the caller and run observability. */
3047
+ reviewerPrecheck?: GoalAuthorReviewerPrecheckResult;
2538
3048
  }
2539
3049
 
2540
3050
  /** AUTHOR-TIMEBOX 산출 — 예산과 실제 경과. 둘 다 «잰 값»이고 지어낸 값이 아니다. */
@@ -6113,6 +6623,16 @@ async function authorGoalWithSupersededRootIntent(
6113
6623
  }
6114
6624
  // ⭐ 이 저작 «한 번»의 id. goalId 보다 «먼저» 있어야 ground·enhance 의 소요를 그 골에 붙일 수 있다.
6115
6625
  const authorRunId = generateGoalId();
6626
+ if (deps.mockScenarioCatalog) {
6627
+ try {
6628
+ observeGoalAuthor('goal-author', 'mock-scenario-catalog-injected', {
6629
+ authorRunId,
6630
+ source: 'src/ux-sim/mock-scenario-catalog.json',
6631
+ availableConsumers: ['ground', 'enhance', 'reviewer-precheck'],
6632
+ contextChars: deps.mockScenarioCatalog.length,
6633
+ });
6634
+ } catch { /* observation must not change authoring */ }
6635
+ }
6116
6636
  const authorGrade = deps.authorGrade ?? resolveGoalAuthorGrade(undefined, getUserConfig().harness?.authorGrade);
6117
6637
  const lite = authorGrade.grade === 'lite';
6118
6638
  // lite 는 판정선을 남기는 대신 단계를 덜 한다 — 요청에 반증 줄이 하나도 없으면 판정선 없는 골이 나가므로 시작 전에 멈춘다.
@@ -6139,7 +6659,10 @@ async function authorGoalWithSupersededRootIntent(
6139
6659
  const groundStartedAt = startGoalAuthorPhase('ground', authorRunId, deps.onProgress);
6140
6660
  const timeboxBudgetMs = deps.groundTimeboxMs ?? GOAL_AUTHOR_GROUND_TIMEBOX_MS;
6141
6661
  try {
6142
- const groundOutcome = await groundWithinTimebox(() => deps.ground(ask, persistentGrounding.deps), timeboxBudgetMs, groundStartedAt);
6662
+ const groundOutcome = await groundWithinTimebox(() => deps.ground(ask, {
6663
+ ...persistentGrounding.deps,
6664
+ ...(deps.mockScenarioCatalog ? { mockScenarioCatalog: deps.mockScenarioCatalog } : {}),
6665
+ }), timeboxBudgetMs, groundStartedAt);
6143
6666
  if ('timebox' in groundOutcome) {
6144
6667
  // ⛔ `groundingError` 를 «안» 쓴다 — 접지가 던진 것과 예산 초과로 끊긴 것은 다른 사건이고,
6145
6668
  // 처방도 다르다(앞은 채널 복구, 뒤는 더 좁은 ask/재시도). 두 값을 한 칸에 접으면 못 가른다.
@@ -6178,8 +6701,8 @@ async function authorGoalWithSupersededRootIntent(
6178
6701
  ? await deps.enhance(
6179
6702
  enhanceAsk,
6180
6703
  persistentFacts.length > 0
6181
- ? { ...deps.enhanceOpts, groundedFacts: persistentFacts, onUsage: onEnhanceUsage }
6182
- : { ...deps.enhanceOpts, onUsage: onEnhanceUsage },
6704
+ ? { ...deps.enhanceOpts, groundedFacts: persistentFacts, onUsage: onEnhanceUsage, ...(deps.mockScenarioCatalog ? { mockScenarioCatalog: deps.mockScenarioCatalog } : {}) }
6705
+ : { ...deps.enhanceOpts, onUsage: onEnhanceUsage, ...(deps.mockScenarioCatalog ? { mockScenarioCatalog: deps.mockScenarioCatalog } : {}) },
6183
6706
  )
6184
6707
  : { original: ask, checklist: [], verbatimPreserved: true };
6185
6708
  // ⭐ goal-context 규범이 «어디에도 안 실린다»는 것을 관측으로 남긴다.
@@ -6236,7 +6759,7 @@ async function authorGoalWithSupersededRootIntent(
6236
6759
  '',
6237
6760
  '## ACCEPTANCE CRITERIA',
6238
6761
  ...enhancement.checklist.map(requestedCriterionLine),
6239
- ...explicitGoalDoneBoundaryLines(ask),
6762
+ ...explicitGoalDoneBoundaryLines(ask, deps.repositoryRoot ?? process.cwd()),
6240
6763
  '',
6241
6764
  '## REQUIRED EVIDENCE',
6242
6765
  '- [requested] Verify the decision signal and the verbatim ask.',
@@ -6721,7 +7244,7 @@ async function authorGoalWithSupersededRootIntent(
6721
7244
  : ['## STEPS', ...(resolvedSteps.length ? resolvedSteps.map((step) => `- ${step}`) : ['- No externally injected steps.']), '']),
6722
7245
  '## ACCEPTANCE CRITERIA',
6723
7246
  ...acceptanceSection,
6724
- ...explicitGoalDoneBoundaryLines(ask),
7247
+ ...explicitGoalDoneBoundaryLines(ask, deps.repositoryRoot ?? process.cwd()),
6725
7248
  ...preservationAmbiguityCriteria(ambiguities, clarificationAnswers),
6726
7249
  ...preservationAmbiguityNotice(ambiguities),
6727
7250
  ...preservationAmbiguityClarification(clarificationQuestions, clarificationResponses),
@@ -6844,6 +7367,7 @@ export async function groundForGoalAuthor(
6844
7367
  cwd,
6845
7368
  seedPaths: askPathTokens(ask),
6846
7369
  ...(deps.persistent !== undefined ? { persistent: deps.persistent } : {}),
7370
+ ...(deps.mockScenarioCatalog ? { mockScenarioCatalog: deps.mockScenarioCatalog } : {}),
6847
7371
  }),
6848
7372
  };
6849
7373
  }
@@ -6930,9 +7454,10 @@ async function runDefaultHelpProbe(cwd: string, argv: readonly string[]): Promis
6930
7454
  * ⇒ 배선만 무는 테스트가 이것을 직접 부른다.
6931
7455
  */
6932
7456
  export function defaultGoalAuthorDeps(cwd: string): GoalAuthorDeps {
7457
+ const mockScenarioCatalog = renderGoalAuthorMockScenarioCatalog();
6933
7458
  return {
6934
7459
  async ground(ask, groundingDeps) {
6935
- return (await groundForGoalAuthor(ask, cwd, groundingDeps)).facts;
7460
+ return (await groundForGoalAuthor(ask, cwd, { ...groundingDeps, mockScenarioCatalog })).facts;
6936
7461
  },
6937
7462
  /**
6938
7463
  * ⭐⭐ 저작 경로는 체크리스트를 «완주 판정»이 아니라 «골 문서 재료»로 쓴다 — 그래서 용도를 밝힌다.
@@ -6946,8 +7471,9 @@ export function defaultGoalAuthorDeps(cwd: string): GoalAuthorDeps {
6946
7471
  * 이 칸을 «안 주므로» 기본값 `coverage-gate` 로 종전 문면을 그대로 받는다.
6947
7472
  */
6948
7473
  enhance(ask, opts) {
6949
- return enhancePrompt(ask, { ...opts, checklistUse: 'authoring', config: opts?.config ?? getUserConfig() });
7474
+ return enhancePrompt(ask, { ...opts, mockScenarioCatalog, checklistUse: 'authoring', config: opts?.config ?? getUserConfig() });
6950
7475
  },
7476
+ mockScenarioCatalog,
6951
7477
  readSourceFile: createRepositoryReferencedFileReader(cwd),
6952
7478
  runHelpProbe: (argv) => runDefaultHelpProbe(cwd, argv),
6953
7479
  selfResolveClarification: defaultGoalAuthorSelfResolve,
@@ -7067,6 +7593,19 @@ export async function writeAuthoredGoal(
7067
7593
  ...(supersededGoalId && { goalId: supersededGoalId }),
7068
7594
  ...(supersededRootIntent !== null && { supersessionRootIntent: supersededRootIntent }),
7069
7595
  });
7596
+ const reviewerPrecheckEnabled = resolvedDeps.reviewerPrecheckEnabled ?? resolveGoalAuthorReviewerPrecheckEnabled();
7597
+ const dialog = await executeGoalAuthorReviewerDialog(
7598
+ reviewerPrecheckEnabled,
7599
+ authored.document,
7600
+ authored.authorRunId,
7601
+ (document, context) => (resolvedDeps.reviewerPrecheck
7602
+ ? resolvedDeps.reviewerPrecheck(document, authored.authorRunId, context)
7603
+ : runGoalAuthorReviewerPrecheck(document, { reviewContext: context, mockScenarioCatalog: resolvedDeps.mockScenarioCatalog })),
7604
+ );
7605
+ authored.document = dialog.document;
7606
+ if (dialog.result) {
7607
+ authored.reviewerPrecheck = dialog.result;
7608
+ }
7070
7609
  const stampedAt = fileDeps.now?.() ?? new Date();
7071
7610
  const identity = identityLines(ask, cwd, fileDeps.env ?? process.env, stampedAt);
7072
7611
  if (identity.length) {