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
@@ -55,8 +55,11 @@ export function readRunChart(runId: string, device: RunChartDevice, dir: string)
55
55
  export function runChartMetrics(entries: readonly RunLedgerEntry[]): { emptyHandoffs: number; unreadHandoffs: number; conflictingVerdicts: number } {
56
56
  const cells = entries.filter((e) => e.event === 'run-chart-cell');
57
57
  const emptyHandoffs = cells.filter((e) => !String(e.data.handoff ?? '').trim()).length;
58
- const unreadHandoffs = cells.filter((e) => Boolean(e.data.handoff)
59
- && !cells.some((next) => next.data.readStopKeys instanceof Array && next.data.readStopKeys.includes(String(e.data.stopKey)))).length;
58
+ const unreadHandoffs = cells.filter((e) => {
59
+ const handoff = String(e.data.handoff ?? '').trim().toLowerCase();
60
+ return handoff !== '' && handoff !== 'none'
61
+ && !cells.some((next) => next.data.readStopKeys instanceof Array && next.data.readStopKeys.includes(String(e.data.stopKey)));
62
+ }).length;
60
63
  const verdicts = new Map<string, Set<string>>();
61
64
  for (const cell of cells) {
62
65
  const key = `${String(cell.data.device)}\0${String(cell.data.stopKey)}`;
@@ -90,7 +93,7 @@ export function recordRunChartDecision(input: RunChartDecision): RunChartWriteRe
90
93
  }
91
94
  append.push({ timestamp: new Date().toISOString(), runId: input.runId, event: 'run-chart-cell', data: {
92
95
  device: input.device, stopKey: input.stopKey, observed: input.observed.slice(0, 240), verdict: input.verdict,
93
- action: input.action, handoff: input.handoff, why: input.why.slice(0, 240), readStopKeys: input.readStopKeys.slice(-RUN_CHART_READ_CELLS),
96
+ action: input.action, handoff: input.handoff ?? 'none', why: input.why.slice(0, 240), readStopKeys: input.readStopKeys.slice(-RUN_CHART_READ_CELLS),
94
97
  ...(input.waitCount === undefined ? {} : { waitCount: input.waitCount }),
95
98
  ...(input.failureClass === undefined ? {} : { failureClass: input.failureClass }),
96
99
  } });
@@ -1,4 +1,5 @@
1
- import { appendFileSync, closeSync, existsSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
1
+ import { appendFileSync, closeSync, existsSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, statSync, truncateSync, unlinkSync, writeFileSync } from 'node:fs';
2
+ import { createHash } from 'node:crypto';
2
3
  import { dirname, isAbsolute, join, resolve } from 'node:path';
3
4
  import { parse as parseYaml } from 'yaml';
4
5
  import { refuseProductionLedgerWriteInTest } from '../harness/ledger-write-guard.js';
@@ -32,9 +33,15 @@ export interface RunLedgerEntry {
32
33
  shardIdentityReadFailure?: RunShardIdentityReadFailure;
33
34
  }
34
35
 
36
+ /** Stable signature for an ordered observed route; callers record the evidence basis separately. */
37
+ export function pathSignatureOf(steps: readonly { readonly from: string; readonly to: string; readonly skipped?: readonly string[] }[]): string {
38
+ return createHash('sha256').update(JSON.stringify(steps.map(step => [step.from, step.to, step.skipped ?? []]))).digest('hex').slice(0, 12);
39
+ }
40
+
35
41
  const RUN_GRAPH_STEP_EVENTS = new Set([
36
42
  'node-enter', 'node-exit', 'edge-taken', 'node-skipped', 'node-added', 'edge-rerouted',
37
43
  'unit-expanded', 'unit-collapsed', 'pipeline-node-entry', 'pipeline-node-exit', 'graph-edge-taken',
44
+ 'graph.path',
38
45
  ]);
39
46
 
40
47
  function isRunGraphStepEvent(entry: RunLedgerEntry): boolean {
@@ -192,6 +199,7 @@ export interface RunOriginData extends Record<string, unknown> {
192
199
  }
193
200
 
194
201
  export type RunLedgerWriter = (entry: RunLedgerEntry) => void;
202
+ export type RunLedgerBatchWriter = (entries: readonly RunLedgerEntry[]) => void;
195
203
  export type RunLedgerReader = (path: string, encoding?: 'utf8') => string | Buffer;
196
204
 
197
205
  /** A live PTY lacks its producer correlation id, or that id lacks an observable JSONL ledger. */
@@ -820,6 +828,48 @@ export function appendRunLedgerEntry(entry: RunLedgerEntry, dir = runLedgerDir()
820
828
  }
821
829
  }
822
830
 
831
+ /** Append one run's structural graph events as a rollback-protected ledger batch. */
832
+ export function appendRunLedgerEntries(entries: readonly RunLedgerEntry[], dir = runLedgerDir()): void {
833
+ if (entries.length === 0) return;
834
+ const runId = entries[0]!.runId;
835
+ if (!runId || entries.some((entry) => entry.runId !== runId)) throw new Error('run ledger batch must have one runId');
836
+ if (entries.some((entry) => !isRunGraphStepEvent(entry))) throw new Error('run ledger batch accepts graph-step events only');
837
+ if (refuseProductionLedgerWriteInTest(dir, 'run-ledger')) return;
838
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
839
+ const live = runLedgerPath(runId, dir);
840
+ const devProject = process.env.ELANOUS_DEV_PROJECT;
841
+ withRunLedgerLock(dir, runId, () => {
842
+ restoreArchivedRunLedger(dir, runId);
843
+ let lastSequence = lastRunGraphEventSequence(runId, dir);
844
+ const rows = entries.map((entry) => {
845
+ const sequenced = sequenceRunGraphEvent(entry, lastSequence);
846
+ lastSequence = sequenced.seq ?? (typeof sequenced.data.seq === 'number' ? sequenced.data.seq : lastSequence);
847
+ return sequenced.devProject === undefined && typeof devProject === 'string' && devProject.startsWith('prj-')
848
+ ? { ...sequenced, devProject }
849
+ : sequenced;
850
+ });
851
+ const lines = rows.map((row) => `${JSON.stringify(row)}\n`).join('');
852
+ const appendLine = separateAppendedLedgerLine(live, lines);
853
+ const existed = existsSync(live);
854
+ const sizeBefore = existed ? statSync(live).size : 0;
855
+ try {
856
+ appendFileSync(live, appendLine, 'utf8');
857
+ } catch (error) {
858
+ try {
859
+ if (existed) truncateSync(live, sizeBefore);
860
+ else if (existsSync(live)) unlinkSync(live);
861
+ } catch (rollbackError) {
862
+ throw new AggregateError([error, rollbackError], `run ledger batch append and rollback failed: ${runId}`);
863
+ }
864
+ throw error;
865
+ }
866
+ });
867
+ for (const entry of entries) {
868
+ try { recordRunRequestVsEffectiveFromLedger(runId, dir, entry); }
869
+ catch { /* This comparison is observation and cannot fail a committed batch. */ }
870
+ }
871
+ }
872
+
823
873
  /** Caller decision inside `appendRunLedgerEntryChecked`: either `append` exactly one entry, or skip with `result`. */
824
874
  export type RunLedgerCheckedAppendDecision<T> =
825
875
  | { append: false; result: T }
@@ -0,0 +1,95 @@
1
+ import type { GraphTemplate } from './graph-templates.js';
2
+ import type { GraphTemplateSpec } from './graph-yaml.js';
3
+ import type { RunLedgerEntry } from './run-ledger.js';
4
+
5
+ type RuntimeOverlayGraph = Pick<GraphTemplate, 'nodes' | 'edges'> | Pick<GraphTemplateSpec, 'nodes' | 'edges'>;
6
+
7
+ const DEFAULT_OUTCOME = '$default';
8
+ const ABSENT_ROUTE = '$absent';
9
+
10
+ export interface RuntimeOverlayRunStepsInput {
11
+ readonly runId: string;
12
+ readonly timestamp: string;
13
+ readonly before: RuntimeOverlayGraph;
14
+ readonly after: RuntimeOverlayGraph;
15
+ readonly overlayIds: readonly string[];
16
+ readonly round: number;
17
+ }
18
+
19
+ interface GraphRoute {
20
+ readonly from: string;
21
+ readonly outcome: string;
22
+ readonly to: string;
23
+ }
24
+
25
+ function routesOf(graph: RuntimeOverlayGraph): Map<string, GraphRoute> {
26
+ const routes = new Map<string, GraphRoute>();
27
+ if (!Array.isArray(graph.edges)) {
28
+ const compiledEdges = graph.edges as Readonly<Record<string, readonly string[]>>;
29
+ for (const [from, destinations] of Object.entries(compiledEdges)) {
30
+ for (const [index, to] of destinations.entries()) {
31
+ routes.set(`${from}\u0000${index}`, { from, outcome: String(index), to: String(to) });
32
+ }
33
+ }
34
+ return routes;
35
+ }
36
+ for (const edge of graph.edges) {
37
+ if (edge.to !== undefined) {
38
+ routes.set(`${edge.from}\u0000${DEFAULT_OUTCOME}`, { from: edge.from, outcome: DEFAULT_OUTCOME, to: edge.to });
39
+ continue;
40
+ }
41
+ for (const [outcome, to] of Object.entries(edge.map ?? {})) {
42
+ routes.set(`${edge.from}\u0000${outcome}`, { from: edge.from, outcome, to: String(to) });
43
+ }
44
+ }
45
+ return routes;
46
+ }
47
+
48
+ function reason(input: RuntimeOverlayRunStepsInput): string {
49
+ return `runtime overlay ${input.overlayIds.join(', ')} applied at round ${input.round}`;
50
+ }
51
+
52
+ /** Convert an already accepted runtime overlay into the existing structural ledger vocabulary. */
53
+ export function runtimeOverlayRunSteps(input: RuntimeOverlayRunStepsInput): RunLedgerEntry[] {
54
+ if (input.overlayIds.length === 0) return [];
55
+ const detail = reason(input);
56
+ const beforeNodes = new Set(input.before.nodes.map((node) => node.nodeId));
57
+ const entries: RunLedgerEntry[] = input.after.nodes
58
+ .filter((node) => !beforeNodes.has(node.nodeId))
59
+ .map((node) => ({
60
+ timestamp: input.timestamp,
61
+ runId: input.runId,
62
+ event: 'node-added',
63
+ data: {
64
+ node: node.nodeId,
65
+ kind: node.kind,
66
+ decider: 'runtime-overlay',
67
+ reason: detail,
68
+ trigger: { overlayIds: input.overlayIds, round: input.round },
69
+ },
70
+ }));
71
+
72
+ const beforeRoutes = routesOf(input.before);
73
+ const afterRoutes = routesOf(input.after);
74
+ const changedRoutes = [...afterRoutes.entries()]
75
+ .filter(([key, route]) => beforeRoutes.get(key)?.to !== route.to)
76
+ .sort(([left], [right]) => left.localeCompare(right));
77
+ for (const [key, route] of changedRoutes) {
78
+ entries.push({
79
+ timestamp: input.timestamp,
80
+ runId: input.runId,
81
+ event: 'edge-rerouted',
82
+ data: {
83
+ from: route.from,
84
+ outcome: route.outcome,
85
+ to: route.to,
86
+ was: beforeRoutes.get(key)?.to ?? ABSENT_ROUTE,
87
+ decider: 'runtime-overlay',
88
+ reason: detail,
89
+ },
90
+ });
91
+ }
92
+ return entries;
93
+ }
94
+
95
+ export { ABSENT_ROUTE, DEFAULT_OUTCOME };
@@ -0,0 +1,9 @@
1
+ /** Stable TDD terminal-evidence tags shared by the producer and Pod result mapper. */
2
+ export const TDD_RED_TAG = 'tdd-red' as const;
3
+ export const TDD_GREEN_TAG = 'tdd-green' as const;
4
+ export const TDD_RECORD_TAGS = [TDD_RED_TAG, TDD_GREEN_TAG] as const;
5
+ export type TddRecordTag = typeof TDD_RECORD_TAGS[number];
6
+
7
+ export function isTddRecordTag(value: unknown): value is TddRecordTag {
8
+ return value === TDD_RED_TAG || value === TDD_GREEN_TAG;
9
+ }
@@ -28,6 +28,8 @@ export interface TestScenarioRequestInput {
28
28
  readonly registeredMethodologies: readonly string[];
29
29
  /** 라이브 명령의 «출처» — 보통 저작 중인 골 문서의 경로. 없으면 measured 로 못 간다. */
30
30
  readonly commandSource?: string;
31
+ /** Multiple authoritative source candidates are retained for review, never chosen by priority. */
32
+ readonly commandSourceCandidates?: readonly string[];
31
33
  }
32
34
 
33
35
  export type TestScenarioLiveStatus = 'measured' | 'unmeasured';
@@ -61,7 +63,25 @@ export function requestTestScenario(input: TestScenarioRequestInput): TestScenar
61
63
  const canLaunch = input.launch !== null
62
64
  && (input.launch.port !== undefined || (input.launch.entrypoint ?? '').trim() !== '');
63
65
  const methodologyAvailable = input.registeredMethodologies.includes(LAUNCH_METHODOLOGY);
64
- const commandSource = input.commandSource?.trim();
66
+ const commandSourceCandidates = [...new Set((input.commandSourceCandidates ?? [])
67
+ .map((candidate) => candidate.trim())
68
+ .filter((candidate) => /^[^:\s]+:[^:\s]+$/u.test(candidate)))];
69
+ const explicitCommandSource = input.commandSource?.trim() || undefined;
70
+ const candidateConflict = commandSourceCandidates.length > 1
71
+ || (commandSourceCandidates.length === 1 && explicitCommandSource !== undefined && commandSourceCandidates[0] !== explicitCommandSource);
72
+ const commandSource = candidateConflict
73
+ ? undefined
74
+ : explicitCommandSource || commandSourceCandidates[0];
75
+ // Ambiguous declarations must use file:key tokens. Preserve a legacy explicit
76
+ // document path as a labeled source token rather than emitting a malformed item.
77
+ const explicitAmbiguityCandidate = explicitCommandSource
78
+ ? (/^[^:\s]+:[^:\s]+$/u.test(explicitCommandSource) ? explicitCommandSource : `${explicitCommandSource}:explicit-command-source`)
79
+ : undefined;
80
+ const ambiguityCandidates = [...new Set([
81
+ ...commandSourceCandidates,
82
+ ...(candidateConflict && explicitAmbiguityCandidate ? [explicitAmbiguityCandidate] : []),
83
+ ])];
84
+ const commandSourceAmbiguous = candidateConflict || (!commandSource && commandSourceCandidates.length > 1);
65
85
 
66
86
  if (canLaunch && methodologyAvailable && commandSource) {
67
87
  return {
@@ -76,15 +96,17 @@ export function requestTestScenario(input: TestScenarioRequestInput): TestScenar
76
96
  }
77
97
 
78
98
  // ⛔ 사유를 «가장 바깥 원인»으로 고른다 — 선언이 없으면 방법론·명령출처를 따질 자리가 아니다.
79
- const reason = !canLaunch
80
- ? 'no-launch-declaration'
99
+ const reason = commandSourceAmbiguous
100
+ ? 'ambiguous-command-source'
101
+ : !canLaunch
102
+ ? 'no-launch-declaration'
81
103
  : !methodologyAvailable
82
104
  ? 'no-methodology'
83
105
  : 'no-command-source';
84
106
  return {
85
107
  sections: [
86
108
  scenarioSection(UNKNOWN_DELIVERABLE, input.acceptanceCriteria),
87
- unmeasuredLiveSection(reason),
109
+ unmeasuredLiveSection(reason, reason === 'ambiguous-command-source' ? ambiguityCandidates : [], reason === 'ambiguous-command-source' && candidateConflict ? explicitCommandSource : undefined),
88
110
  resultReportSection(),
89
111
  ],
90
112
  deliverableType: UNKNOWN_DELIVERABLE,
@@ -138,13 +160,22 @@ function measuredLiveSection(methodology: string, commandSource: string, launch:
138
160
  }
139
161
 
140
162
  /** L 층(측정 불가) — ⛔ 방법론·명령출처·기동·눈·기대를 «싣지 않는다»(파서가 금지한다). */
141
- function unmeasuredLiveSection(reason: string): string {
163
+ function unmeasuredLiveSection(reason: string, candidates: readonly string[] = [], explicitSource?: string): string {
164
+ const prerequisite = reason === 'no-launch-declaration'
165
+ ? '골이 `## 산출물을 어떻게 켜나` 절에 `Port:` 또는 `Entrypoint:` 를 선언했으면 됐다'
166
+ : reason === 'ambiguous-command-source'
167
+ ? '골이 후보 중 하나를 권위 있는 명령 출처로 확정했으면 됐다'
168
+ : reason === 'no-methodology'
169
+ ? '호출자가 등록 방법론 레지스트리에 `deliverable-verify` 를 등록했으면 됐다'
170
+ : '골이 권위 있는 명령 출처를 선언했으면 됐다';
142
171
  return [
143
172
  '## L. 라이브',
144
173
  '',
145
174
  '### 상태 `unmeasured`',
146
175
  `- 사유: \`${reason}\``,
147
- '- 무엇이 있었으면 됐나: 골이 `## 산출물을 어떻게 켜나` 절에 `Port:` 또는 `Entrypoint:` 를 선언했으면 됐다',
176
+ ...(reason.startsWith('ambiguous-') ? [`- 후보 목록: ${candidates.join(', ')}`] : []),
177
+ ...(explicitSource ? [`- 원래 명시 출처(후보와 별도): \`${explicitSource}\``] : []),
178
+ `- 무엇이 있었으면 됐나: ${prerequisite}`,
148
179
  '',
149
180
  '> ⚠️ ⛔ 「측정 불가」는 「결함 없음」이 «아니다». 이 골은 라이브 층을 «안 본 채» 끝난다.',
150
181
  ].join('\n');
@@ -0,0 +1,166 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { readFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
5
+ import {
6
+ computeReceiptKey,
7
+ gateEnvFingerprint,
8
+ gateLockfileHash,
9
+ GATE_RECEIPT_SCHEMA,
10
+ loadGateReceipts,
11
+ saveGateReceipt,
12
+ type GateReceipt,
13
+ type GateReceiptIdentity,
14
+ } from './gate-receipt-registry.js';
15
+
16
+ export interface TrainGateReceiptInput {
17
+ repo: string;
18
+ commit: string;
19
+ baseSha: string;
20
+ changedFiles: readonly string[];
21
+ deletedFiles?: readonly string[];
22
+ scenarioTests?: readonly string[];
23
+ }
24
+
25
+ export interface PassedSelfGateReceiptInput extends TrainGateReceiptInput {
26
+ /** Exact artifact emitted by `self gate --artifact-dir`; its pass and typecheck binding are revalidated here. */
27
+ summaryPath: string;
28
+ }
29
+
30
+ type Execute = (script: string, cwd: string) => { status: number | null; stdout: string; stderr: string };
31
+
32
+ const SHA40 = /^[0-9a-f]{40}$/i;
33
+ const TEST_FILE = /\.test\.[cm]?[jt]sx?$/;
34
+ const quote = (value: string) => `'${value.replaceAll("'", `'\\''`)}'`;
35
+
36
+ function registryPath(repo: string): string | undefined {
37
+ const result = spawnSync('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], { cwd: repo, encoding: 'utf8', timeout: 10_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER });
38
+ const commonDir = (result.stdout ?? '').trim();
39
+ return result.status === 0 && commonDir ? join(commonDir, 'elanous-host-regate', 'gate-receipts.json') : undefined;
40
+ }
41
+
42
+ function identityFor(input: TrainGateReceiptInput, checks?: readonly string[]): GateReceiptIdentity | undefined {
43
+ if (!SHA40.test(input.commit) || !SHA40.test(input.baseSha)) return undefined;
44
+ const bun = spawnSync('bun', ['--version'], { cwd: input.repo, encoding: 'utf8', timeout: 10_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER });
45
+ const bunVersion = (bun.stdout ?? '').trim();
46
+ if (bun.status !== 0 || !bunVersion) return undefined;
47
+ return {
48
+ headCommit: input.commit,
49
+ baseCommit: input.baseSha,
50
+ bunVersion,
51
+ lockfileHash: gateLockfileHash(input.repo),
52
+ radiusFiles: [...new Set(input.changedFiles)].sort(),
53
+ checks: checks ? [...checks] : [
54
+ 'train:changed-file-typecheck',
55
+ ...(input.scenarioTests?.length || input.changedFiles.some((file) => TEST_FILE.test(file) && !input.deletedFiles?.includes(file)) ? ['train:deterministic-tests'] : []),
56
+ ...(input.scenarioTests ?? []).map((file) => `train:scenario-test:${file}`),
57
+ 'train:pwa-build',
58
+ ],
59
+ envFingerprint: gateEnvFingerprint(process.env),
60
+ };
61
+ }
62
+
63
+ /** Record only after revalidating the exact self-gate summary, then independently measure changed-only interference. */
64
+ export async function recordPassedSelfGateReceipt(
65
+ input: PassedSelfGateReceiptInput,
66
+ detect: (files: readonly string[]) => Promise<{ status: 'no-interference' | 'interference' | 'unmeasurable' }> = async (files) => {
67
+ const { detectTestInterference } = await import('../../scripts/detect-test-interference.js');
68
+ return detectTestInterference(files);
69
+ },
70
+ ): Promise<GateReceipt | undefined> {
71
+ let summary: Record<string, unknown>;
72
+ try { summary = JSON.parse(readFileSync(input.summaryPath, 'utf8')) as Record<string, unknown>; }
73
+ catch { return undefined; }
74
+ const typecheck = summary.typecheck as Record<string, unknown> | undefined;
75
+ const cohort = Array.isArray(summary.cohort) ? summary.cohort.filter((file): file is string => typeof file === 'string') : [];
76
+ const changedTestFiles = [...new Set(input.changedFiles.filter((file) => TEST_FILE.test(file)
77
+ && !input.deletedFiles?.includes(file)))].sort();
78
+ if (summary.head40 !== input.commit || summary.base40 !== input.baseSha || summary.exitCode !== 0
79
+ || !['passed', 'pass'].includes(String(summary.verdict)) || summary.introduced !== 0
80
+ || summary.unknown !== 0 || summary.unrunImporters !== 0
81
+ || typecheck?.status !== 'passed' || typecheck.base40 !== input.baseSha
82
+ || typecheck.head40 !== input.commit || typecheck.exitCode !== 0 || typecheck.newErrors !== 0
83
+ || changedTestFiles.some((file) => !cohort.includes(file))) return undefined;
84
+ const testFiles = [...new Set(input.changedFiles.filter((file) => TEST_FILE.test(file)
85
+ && !input.deletedFiles?.includes(file)))].sort();
86
+ if (!testFiles.length) return undefined;
87
+ const interference = await detect(testFiles);
88
+ if (interference.status !== 'no-interference') return undefined;
89
+ const identity = identityFor(input, ['test-interference:changed-only']);
90
+ const path = process.env.ELANOUS_GATE_RECEIPT_REGISTRY_PATH || registryPath(input.repo);
91
+ if (!identity || !path) return undefined;
92
+ const receipt = passedEvidenceReceipt(identity, input.changedFiles);
93
+ try { saveGateReceipt(path, receipt); }
94
+ catch { return undefined; }
95
+ return receipt;
96
+ }
97
+
98
+ function scriptFor(input: TrainGateReceiptInput, files: readonly string[]): string {
99
+ const tests = [...new Set([
100
+ ...files.filter((file) => TEST_FILE.test(file) && !input.deletedFiles?.includes(file)),
101
+ ...(input.scenarioTests ?? []),
102
+ ])];
103
+ return [
104
+ `TSC_BASE_REF=${quote(input.baseSha)} bun scripts/ci-typecheck-changed.ts --local`,
105
+ ...(tests.length ? [`bun run test:deterministic ${tests.map(quote).join(' ')}`] : []),
106
+ `bun scripts/ci-pwa-build-gate.ts --changed-files ${files.map(quote).join(' ')}`,
107
+ ].join(' && ');
108
+ }
109
+
110
+ function passedEvidenceReceipt(identity: GateReceiptIdentity, files: readonly string[]): GateReceipt {
111
+ const receiptIdentity: GateReceiptIdentity = { ...identity, radiusFiles: [...new Set(files)].sort() };
112
+ return {
113
+ ...receiptIdentity,
114
+ schema: GATE_RECEIPT_SCHEMA,
115
+ key: computeReceiptKey(receiptIdentity, 'passed'),
116
+ verdict: 'passed',
117
+ savedAt: new Date().toISOString(),
118
+ };
119
+ }
120
+
121
+ export function runTrainGateWithReceipts(input: TrainGateReceiptInput, execute: Execute = (script, cwd) => {
122
+ const result = spawnSync('sh', ['-c', script], { cwd, encoding: 'utf8', timeout: 120 * 60_000, maxBuffer: 32 * 1024 * 1024 });
123
+ return { status: result.status, stdout: result.stdout ?? '', stderr: result.stderr ?? '' };
124
+ }): { status: number | null; stdout: string; stderr: string } {
125
+ const context = identityFor(input);
126
+ const path = process.env.ELANOUS_GATE_RECEIPT_REGISTRY_PATH || registryPath(input.repo);
127
+ if (!context || !path) return execute(scriptFor(input, input.changedFiles), input.repo);
128
+
129
+ const changedFiles = [...new Set(input.changedFiles)].sort();
130
+ const result = execute(scriptFor(input, changedFiles), input.repo);
131
+ if (result.status === 0 && changedFiles.length) {
132
+ try { saveGateReceipt(path, passedEvidenceReceipt(context, changedFiles)); }
133
+ catch { /* A receipt is an optimization; a passed gate remains passed if persistence fails. */ }
134
+ }
135
+ return result;
136
+ }
137
+
138
+ if (import.meta.main) {
139
+ const raw = process.argv[2];
140
+ try {
141
+ if (!raw) throw new Error('train gate receipt input is required');
142
+ const input = JSON.parse(raw) as TrainGateReceiptInput & Partial<PassedSelfGateReceiptInput>;
143
+ if (input.summaryPath) {
144
+ const receipt = await recordPassedSelfGateReceipt(input as PassedSelfGateReceiptInput);
145
+ const registryFile = process.env.ELANOUS_GATE_RECEIPT_REGISTRY_PATH;
146
+ if (registryFile) {
147
+ const registry = loadGateReceipts(registryFile);
148
+ process.stdout.write(`${String.fromCharCode(10)}__GATE_RECEIPTS__${Buffer.from(JSON.stringify(registry)).toString('base64')}${String.fromCharCode(10)}`);
149
+ }
150
+ if (!receipt) process.exitCode = 1;
151
+ } else {
152
+ const result = runTrainGateWithReceipts({ ...input, repo: process.cwd() });
153
+ process.stdout.write(result.stdout);
154
+ process.stderr.write(result.stderr);
155
+ const registryFile = process.env.ELANOUS_GATE_RECEIPT_REGISTRY_PATH;
156
+ if (registryFile) {
157
+ const registry = loadGateReceipts(registryFile);
158
+ process.stdout.write(`${String.fromCharCode(10)}__GATE_RECEIPTS__${Buffer.from(JSON.stringify(registry)).toString('base64')}${String.fromCharCode(10)}`);
159
+ }
160
+ process.exitCode = result.status ?? 1;
161
+ }
162
+ } catch (error) {
163
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
164
+ process.exitCode = 1;
165
+ }
166
+ }
@@ -3,8 +3,12 @@
3
3
  * Unlike `dispatchHeavyCheck` it never falls back to a local run: a busy host or an infra failure is «unmeasured».
4
4
  * The only local commands are git (cat-file · rev-parse · push · diff). */
5
5
  import { debug } from '../debug/log.js';
6
+ import { spawnSync } from 'node:child_process';
6
7
  import { parseGateScenario, readGateScenarioFile } from './gate-scenario.js';
7
8
  import { getDefaultLogStore } from '../mss/logging/log-store.js';
9
+ import { join } from 'node:path';
10
+ import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
11
+ import { saveGateReceipt, type GateReceipt } from './gate-receipt-registry.js';
8
12
  import {
9
13
  gateRemoteHostCap, realGateRemoteRunner, resolveGateRemoteSettings, runOnRemote,
10
14
  type GateRemoteRunner, type GateRemoteSettings, type RemoteRunOutcome,
@@ -30,6 +34,51 @@ export interface TrainGateInput {
30
34
 
31
35
  export interface TrainGateResult { outcome: TrainGateOutcome; host: string; ms?: number; rc?: number; reason?: string }
32
36
 
37
+ const GATE_RECEIPTS_MARKER = String.fromCharCode(10) + '__GATE_RECEIPTS__';
38
+
39
+ function sharedGateReceiptPath(repo: string, runner: GateRemoteRunner): string | undefined {
40
+ try {
41
+ const result = runner.local('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], repo);
42
+ const commonDir = result.stdout.trim();
43
+ return result.rc === 0 && commonDir ? join(commonDir, 'elanous-host-regate', 'gate-receipts.json') : undefined;
44
+ } catch { return undefined; }
45
+ }
46
+
47
+ /** The exact persistent registry used by local train receipt merging. */
48
+ export function gateReceiptRegistryPathForRepo(repo: string): string | undefined {
49
+ const result = spawnSync('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], {
50
+ cwd: repo, encoding: 'utf8', timeout: 10_000, maxBuffer: SPAWN_SYNC_MAX_BUFFER,
51
+ });
52
+ const commonDir = (result.stdout ?? '').trim();
53
+ return result.status === 0 && commonDir ? join(commonDir, 'elanous-host-regate', 'gate-receipts.json') : undefined;
54
+ }
55
+
56
+ /** Merge the existing remote-writer marker into the local common-dir registry. Invalid rows fail closed. */
57
+ export function mergeGateReceiptRegistryPayload(payload: string, path: string): number {
58
+ let saved = 0;
59
+ try {
60
+ const rows = JSON.parse(Buffer.from(payload, 'base64').toString('utf8')) as Record<string, unknown>;
61
+ for (const [key, value] of Object.entries(rows)) {
62
+ if (!value || typeof value !== 'object' || Array.isArray(value)) continue;
63
+ const receipt = value as GateReceipt;
64
+ if (receipt.key !== key) continue;
65
+ try { saveGateReceipt(path, receipt); saved++; }
66
+ catch { /* Invalid remote records are discarded; local gates remain fail-open. */ }
67
+ }
68
+ } catch { /* A malformed response never changes the measured gate verdict. */ }
69
+ return saved;
70
+ }
71
+
72
+ function mergeReturnedReceipts(outcome: RemoteRunOutcome, path: string | undefined): RemoteRunOutcome {
73
+ if (outcome.kind !== 'ran' || outcome.rc !== 0 || !path) return outcome;
74
+ const stdout = outcome.stdout.toString('utf8');
75
+ const marker = stdout.lastIndexOf(GATE_RECEIPTS_MARKER);
76
+ if (marker < 0) return outcome;
77
+ const payload = stdout.slice(marker + GATE_RECEIPTS_MARKER.length).trim();
78
+ mergeGateReceiptRegistryPayload(payload, path);
79
+ return { ...outcome, stdout: Buffer.from(stdout.slice(0, marker)) };
80
+ }
81
+
33
82
  export interface TrainGateObservation {
34
83
  host: string; commit: string; baseSha: string; outcome: TrainGateOutcome;
35
84
  rc?: number; ms?: number; reason?: string; changedFiles: number;
@@ -42,22 +91,6 @@ export interface TrainGateDeps {
42
91
  observe?: (entry: TrainGateObservation) => void;
43
92
  }
44
93
 
45
- const quote = (value: string) => `'${value.replaceAll("'", `'\\''`)}'`;
46
- const TEST_FILE = /\.test\.[cm]?[jt]sx?$/;
47
-
48
- /** The host-side shell body: each step runs only if the one before it passed. Exported for tests. */
49
- export function trainGateScript(baseSha: string, changedFiles: readonly string[], deleted: ReadonlySet<string> = new Set(), scenarioTests: readonly string[] = []): string {
50
- // A deleted test file is a changed path (tsc/PWA reach) but not something to run.
51
- const changedTests = changedFiles.filter((file) => TEST_FILE.test(file) && !deleted.has(file));
52
- const tests = scenarioTests.length ? [...new Set([...changedTests, ...scenarioTests])] : changedTests;
53
- const steps = [
54
- `TSC_BASE_REF=${quote(baseSha)} bun scripts/ci-typecheck-changed.ts --local`,
55
- ...(tests.length ? [`bun run test:deterministic ${tests.map(quote).join(' ')}`] : []),
56
- `bun scripts/ci-pwa-build-gate.ts --changed-files ${changedFiles.map(quote).join(' ')}`,
57
- ];
58
- return steps.join(' && ');
59
- }
60
-
61
94
  async function loadSettings(): Promise<GateRemoteSettings> {
62
95
  try {
63
96
  const { getUserConfig } = await import('../user-config.js');
@@ -76,6 +109,10 @@ export const TRAIN_GATE_HOST = 'node-b';
76
109
 
77
110
  export async function runTrainGateOnHost(input: TrainGateInput, runner: GateRemoteRunner = realGateRemoteRunner, deps: TrainGateDeps = {}): Promise<TrainGateResult> {
78
111
  const settings = input.settings ?? await loadSettings();
112
+ const receiptPath = sharedGateReceiptPath(input.repo, runner);
113
+ // Each remote full gate writes into a fresh scratch registry; returned rows merge into the local shared registry.
114
+ // No existing registry contents are needed for receipt registration.
115
+ const payloadFiles = receiptPath ? [{ env: 'ELANOUS_GATE_RECEIPT_REGISTRY_PATH', content: '{}' }] : undefined;
79
116
  const host = settings.host;
80
117
  const hostCap = gateRemoteHostCap(settings, host);
81
118
  let scenarioTests: string[] = [];
@@ -110,14 +147,21 @@ export async function runTrainGateOnHost(input: TrainGateInput, runner: GateRemo
110
147
  const sleep = deps.sleep ?? ((ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)));
111
148
  const now = deps.now ?? Date.now;
112
149
  const deadline = now() + settings.slotWaitSeconds * 1000;
113
- const script = trainGateScript(input.baseSha, input.changedFiles, new Set(input.deletedFiles ?? []), scenarioTests);
114
150
  let outcome: RemoteRunOutcome;
115
151
  for (;;) {
116
152
  try {
117
153
  outcome = runOnRemote({
118
154
  repo: input.repo, host, mirror: settings.mirror, commit: input.commit, refs: [input.baseSha],
119
- argv: ['sh', '-c', script], installPwa: true, hostCap,
155
+ argv: ['bun', 'src/self-implement/train-gate-receipt.ts', JSON.stringify({
156
+ repo: input.repo,
157
+ commit: input.commit,
158
+ baseSha: input.baseSha,
159
+ changedFiles: input.changedFiles,
160
+ deletedFiles: input.deletedFiles ?? [],
161
+ scenarioTests,
162
+ })], installPwa: true, hostCap, ...(payloadFiles ? { payloadFiles } : {}),
120
163
  }, runner);
164
+ outcome = mergeReturnedReceipts(outcome, receiptPath);
121
165
  } catch (error) {
122
166
  outcome = { kind: 'infra', reason: `exception: ${error instanceof Error ? error.message : String(error)}` };
123
167
  }
@@ -20,7 +20,7 @@ import { debug } from '../debug/log.js';
20
20
  import { createRequestSizeGuard, formatRequestSizeStatus, type RequestSizeGuard } from './request-size-guard.js';
21
21
  import type { InputSourceKind } from '../input/input-source-kind.js';
22
22
  import {
23
- getProviderForConfig, streamLLMWithTools, type LLMMessage, type LLMOpts, type LLMProvider,
23
+ getProviderForConfigAsync, streamLLMWithTools, type LLMMessage, type LLMOpts, type LLMProvider,
24
24
  type LLMToolSpec, type ContentBlock,
25
25
  } from '../llm.js';
26
26
  import type { UserConfig } from '../user-config.js';
@@ -407,7 +407,7 @@ export async function runTurn(opts: RunTurnOpts): Promise<RunTurnResult> {
407
407
  reasoningEffort: llmOpts?.reasoningEffort ?? null,
408
408
  });
409
409
  }
410
- const provider = opts.provider ?? getProviderForConfig(opts.userConfig, llmOpts?.model);
410
+ const provider = opts.provider ?? await getProviderForConfigAsync(opts.userConfig, llmOpts?.model);
411
411
 
412
412
  // 2) Assemble, trim, call. When images are attached for THIS turn,
413
413
  // swap the string content of the latest user message for
@@ -511,8 +511,9 @@ export async function runTurn(opts: RunTurnOpts): Promise<RunTurnResult> {
511
511
  // streamLLMWithTools)으로 라우팅. 미아밍이면 아래 기존 single-turn 경로 그대로(회귀 0).
512
512
  const goalLoopCfg = opts.userConfig.llm.goalLoop;
513
513
  const armGoalLoop = opts.goalLoop === true || goalLoopCfg?.enabled === true;
514
- const armTuiResearchTurn = opts.utteranceSurface === 'tui' && turnTools.length > 0 && isResearchAgentIntent(opts.userText);
515
- if (armGoalLoop || armTuiResearchTurn) {
514
+ const armResearchTurn = (opts.utteranceSurface === 'tui' || opts.utteranceSurface === 'ask')
515
+ && turnTools.length > 0 && isResearchAgentIntent(opts.userText);
516
+ if (armGoalLoop || armResearchTurn) {
516
517
  // ⭐ CHILD-CONTEXT-BUDGET(0.2.35 칸) — 구현 자식(self-implement 공간)의 첫 goal-loop
517
518
  // 턴에서 실제 effectiveSystemPrompt·turnTools 스키마·userText(골)의 구성 바이트를
518
519
  // composeChildContext 로 계측해 child.context-composition 사건 1회로 남긴다.
@@ -563,6 +564,7 @@ export async function runTurn(opts: RunTurnOpts): Promise<RunTurnResult> {
563
564
  },
564
565
  },
565
566
  ...(turnLlmOpts?.model ? { modelOverride: turnLlmOpts.model } : {}),
567
+ ...(turnLlmOpts?.reasoningEffort ? { reasoningEffort: turnLlmOpts.reasoningEffort } : {}),
566
568
  ...(turnLlmOpts?.budgetGrant ? { budgetGrant: turnLlmOpts.budgetGrant } : {}),
567
569
  ...(guardedTurnLlmOpts?.requestSizeGuard
568
570
  ? { requestSizeGuard: guardedTurnLlmOpts.requestSizeGuard } : {}),
@@ -224,6 +224,8 @@ export interface SessionChunkEvent {
224
224
  seq: number;
225
225
  /** 텍스트 델타(누적은 sink 의 라이브핸들이). */
226
226
  delta?: string;
227
+ /** Replace the current assistant text accumulated for this stream. */
228
+ textOperation?: 'replace';
227
229
  /** 툴 활동(⚙️…✓ inline 렌더용). */
228
230
  tool?: { id: string; name: string; phase: 'call' | 'result'; ok?: boolean };
229
231
  /** 🧠 추론(모드 gated·선택). */
@@ -36,7 +36,8 @@ export function createAcpStreamSink(broadcast: AcpBroadcast): StreamingSurfaceSi
36
36
  if (!sessionId) return;
37
37
  if (ev.delta) {
38
38
  // push(chunk) 등가 — agent_message_chunk(byte-identical).
39
- void broadcast(sessionId, { sessionUpdate: 'agent_message_chunk', content: { type: 'text', text: ev.delta } });
39
+ void broadcast(sessionId, { sessionUpdate: 'agent_message_chunk', content: { type: 'text', text: ev.delta },
40
+ ...(ev.textOperation === 'replace' ? { _meta: { elanous: { textOperation: 'replace' } } } : {}) });
40
41
  }
41
42
  if (ev.reasoning) {
42
43
  // 🧠 추론 — agent_thought_chunk(ACP 의 thought 채널).
@@ -20,6 +20,7 @@ import { debug } from '../../debug/log.js';
20
20
  * shadow 시엔 'acp' 구독자 부재 → tg/dc/pwa 미러만. reasoning 채널 추가 지원. */
21
21
  export interface AcpChunkProducer {
22
22
  delta: (text: string) => void;
23
+ replaceText: (text: string) => void;
23
24
  /** ⭐ `result` 는 «결과 단계»에서만 뜻이 있고, 주면 ACP `rawOutput` 으로 실려 나간다.
24
25
  *
25
26
  * ⛔⭐⭐ **「안 줬다」의 «사유»를 여기서 만들지 않는다.**
@@ -53,6 +54,11 @@ export function makeAcpChunkProducer(sessionId: string, opts: { streamId?: strin
53
54
  fo({ streamId, seq: seq++, delta: text });
54
55
  deltas++;
55
56
  },
57
+ replaceText(text: string): void {
58
+ accum = text;
59
+ fo({ streamId, seq: seq++, delta: text, textOperation: 'replace' });
60
+ deltas++;
61
+ },
56
62
  tool(id, name, phase, ok, result): void {
57
63
  fo({ streamId, seq: seq++, tool: {
58
64
  id, name, phase,