elanous 0.2.43 → 0.2.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (544) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/{Om5xS9jpjSXJCeTNGYEi4 → HMXsxdy5MIIcHPMHv1wD4}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{3557ac4a.c8931684475018ad.js → 08334415.f0e80896acbef722.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1032-78ba4f6391258cab.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1082-53f86a26e03d309d.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1109-7d0e264f6f2edbc7.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1124-7c26330402481143.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/118.2a89982fe4276880.js +23 -0
  10. package/apps/pwa/out/_next/static/chunks/1244.6c435dbf1bf21d8a.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1252.9e665904d3aa3b1a.js +32 -0
  12. package/apps/pwa/out/_next/static/chunks/1266.a46cc33cb6a72d75.js +104 -0
  13. package/apps/pwa/out/_next/static/chunks/{3955.6922286237f2ac2b.js → 1306.967240ede9a0f757.js} +2 -2
  14. package/apps/pwa/out/_next/static/chunks/1344.3b95f3bd1b77a3fe.js +94 -0
  15. package/apps/pwa/out/_next/static/chunks/{5628.6ddb2d5ffba4ff4c.js → 1401.22dfe92640a2b1ac.js} +4 -4
  16. package/apps/pwa/out/_next/static/chunks/1431-f7c78bd5be21e011.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1451-cdd35a8a0b31834b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{2573.387a707f6f9d720c.js → 1694.18debfd77562e56d.js} +2 -2
  19. package/apps/pwa/out/_next/static/chunks/1708-f03d587b7a7545c8.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/1775-fa7152bdeff6c95f.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/178-4da509cd7266672a.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/{7910-6f139bcafd238b9f.js → 1850-522de4ee34957210.js} +1 -1
  23. package/apps/pwa/out/_next/static/chunks/1876-c6f6e0ddcc76c6a1.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/1976.097066b072432242.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/{1406.a1dc2ab6f8449374.js → 1978.eeb60a606dc5deac.js} +2 -2
  26. package/apps/pwa/out/_next/static/chunks/{3402.44b565b314f2263c.js → 2043.e233e3b5a3e790f5.js} +1 -1
  27. package/apps/pwa/out/_next/static/chunks/2150.71b94e3348107c83.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2158.ebc6fc5a10280ab7.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{3694.e0099884345f0198.js → 2216.802962c04f40a26e.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/2294.7890edcfa046c97d.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/235.c89aaae4bcd6233a.js +74 -0
  32. package/apps/pwa/out/_next/static/chunks/239.de075467b5523469.js +287 -0
  33. package/apps/pwa/out/_next/static/chunks/{1200.6a37c202f9f17e9a.js → 249.ba7051590d603c8f.js} +3 -3
  34. package/apps/pwa/out/_next/static/chunks/2571.a6ac4e26c8618403.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/2610.e149cd564a08913e.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/2705.9816f3c244f8b85f.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/2801.afeb8a4dae22f85f.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{3935.16701e33f8982dc9.js → 2954.bbefc95d6b20e0d8.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/{aa57532f.510551854ff239b1.js → 2e0f720a.a0697c08e3806a60.js} +1 -1
  40. package/apps/pwa/out/_next/static/chunks/3042.96ec235fe41c8d4e.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3097-8e358f158acef46b.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/3205-93b1abe28b4fb16a.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3273.b4434f0dcae7eb29.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/3311.9cbc43ea0c90d60c.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{5930.8b4df3b46c32b05a.js → 3349.b5f09ee474d9533e.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/{5866.366966af47fdde5d.js → 3503.a47a9755fb4d97b0.js} +1 -1
  47. package/apps/pwa/out/_next/static/chunks/3506-5f429b3b7e1392b0.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/{7900.096f455c7c1efc53.js → 3843.bad404d008893291.js} +2 -2
  49. package/apps/pwa/out/_next/static/chunks/3877-4b40e530b47e3bf9.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/435-ce2958253cf7de61.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/{8588.d1c6a2903727ce87.js → 4393.28fa5228d0eec217.js} +3 -3
  52. package/apps/pwa/out/_next/static/chunks/4404.7281c847c6e10dfc.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/{8062-7cd0bcc7f01455ba.js → 4415-b9d6a90960920a4a.js} +3 -3
  54. package/apps/pwa/out/_next/static/chunks/{8313-dfa1021bb58a46d6.js → 447-5b304de1fe098f43.js} +1 -1
  55. package/apps/pwa/out/_next/static/chunks/4484-8ebea83d431e6fae.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/{6944.309f4e3ea54d1537.js → 4502.bdcc877abd437a05.js} +1 -1
  57. package/apps/pwa/out/_next/static/chunks/4599-f95790fc5c65b8df.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/{3072.01338851ca21a6f7.js → 46.57c783fa4884714f.js} +2 -2
  59. package/apps/pwa/out/_next/static/chunks/463-b9114e411f33728e.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/4659.a57d1f0c5d754cd2.js +36 -0
  61. package/apps/pwa/out/_next/static/chunks/4722-a847e7a28115035f.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/{8986.8e2e4efbfa655c59.js → 4757.67c6d7473a038e78.js} +1 -1
  63. package/apps/pwa/out/_next/static/chunks/4874-c86f878ec4502ad3.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/4891.3f80ba517a3b2373.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/{8205.282ca4bb62d54a0a.js → 4998.810ca8833084caa9.js} +2 -2
  66. package/apps/pwa/out/_next/static/chunks/4f98febc.ea5841d4d616bfb2.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/{5789.2da35c258292e1e5.js → 5052.7dbb12a55d4f18f5.js} +1 -1
  68. package/apps/pwa/out/_next/static/chunks/5166-ca73b3e361085a6d.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/5180-039f4a18b07ad387.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/5232.5a2ce4daf7a9e11d.js +115 -0
  71. package/apps/pwa/out/_next/static/chunks/{9770.5f75bc6088b16109.js → 5439.3fec6dbce29ecb36.js} +1 -1
  72. package/apps/pwa/out/_next/static/chunks/{1313-19f737e0222c4444.js → 5612-074d9a5e00dfac6a.js} +1 -1
  73. package/apps/pwa/out/_next/static/chunks/5675-01989d524a84c505.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/5751.af641a1adf5ec697.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/5758-c6cb98714d18ab0c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/578eded8.b582637306e16964.js +122 -0
  77. package/apps/pwa/out/_next/static/chunks/{3969.272ee7f9fd6c62e5.js → 5790.5eb06a653ebd8571.js} +1 -1
  78. package/apps/pwa/out/_next/static/chunks/5853-4033e5bd5afbe06b.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/5904.97d70bb7f46b2db7.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/{6540.c7bef57ad8f90a87.js → 5989.7ecd362c5c44b747.js} +3 -3
  81. package/apps/pwa/out/_next/static/chunks/{0ad6802e.ae7afb63fdcb4491.js → 5a34fb2f.52f1b4e1baebb48a.js} +3 -3
  82. package/apps/pwa/out/_next/static/chunks/{0966f8a1.745fcd44f64a87ea.js → 5a5078f8.2099200e5ea95e16.js} +1 -1
  83. package/apps/pwa/out/_next/static/chunks/6036-c302c34ff0b3d410.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/606.ef81c313381f4264.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/616.1af54a928b1ba704.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/6201.bc936f71f613a8e9.js +41 -0
  87. package/apps/pwa/out/_next/static/chunks/6204-fdc86e0e64c4f92d.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/{2144.25b292396712196d.js → 6245.1182e007e9d230d9.js} +2 -2
  89. package/apps/pwa/out/_next/static/chunks/{363bfab3.9623b9f89363541f.js → 63699a35.17262e162bc514b2.js} +1 -1
  90. package/apps/pwa/out/_next/static/chunks/6420.494801a80030160c.js +27 -0
  91. package/apps/pwa/out/_next/static/chunks/{d96660fb.cbc21a2a88539dbb.js → 6549dad0.2740b25e51bf8f05.js} +7 -7
  92. package/apps/pwa/out/_next/static/chunks/{5564.9e72532188f57586.js → 6881.9e7955847640c7fe.js} +4 -4
  93. package/apps/pwa/out/_next/static/chunks/6931.fcdfb94141e67b3d.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/6991-8e081c6ce38c0ba1.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{3903.3ef4656c67572764.js → 7010.1bbd17a7f2b3e376.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/7029.d1466acf55fae2ed.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/7152-a123aa8e129c131f.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7455.196168fffac3b9c4.js +24 -0
  99. package/apps/pwa/out/_next/static/chunks/7638.6ca4770dd1129138.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/7649-f37d76260e5e2a5a.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/{2312.0c8b61e22d3136d7.js → 7679.32c40cdd14f20b4a.js} +1 -1
  102. package/apps/pwa/out/_next/static/chunks/7751.04bfbd16b4c6cd0a.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/7864.b1ff31d4030b8994.js +148 -0
  104. package/apps/pwa/out/_next/static/chunks/7869-c47bd2c075c1fefa.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{4199.ce86b281fd0a60b7.js → 8442.2f09ca969d631615.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/8445.2738dbd59a78c78c.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8447.5510c439f9938c6d.js +286 -0
  108. package/apps/pwa/out/_next/static/chunks/8551.f762945c2cda2e95.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/8635-57a9d8d9db70f4f1.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{fb7d20d5-6892502b6ee39ca6.js → 86961958-4b0689a5048f756b.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/8709.3c6019bb18f8554f.js +8 -0
  112. package/apps/pwa/out/_next/static/chunks/8759.c999528a0a907bf6.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/87f498e5-0881de09f2e44707.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/8843.c3197f904c952b81.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/{cb0f8df8.09a4a6be97e3fc5f.js → 892fd990.456232f326cc39c2.js} +1 -1
  116. package/apps/pwa/out/_next/static/chunks/{837-81336ebaca8198a8.js → 8965-135a2c9eaa2464cb.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/8971-8d3b9c96f8a6c958.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9059.c8598d96f8e5e9cd.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9115.90447ae198b84eae.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9147.d9b0a02e0babc9b4.js +93 -0
  121. package/apps/pwa/out/_next/static/chunks/9204-83075f4b70c61cdc.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9244-c32ef14b5dc72bdf.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/930.2a9a30f964350c66.js +90 -0
  124. package/apps/pwa/out/_next/static/chunks/{8637.90f92d5c8db4732c.js → 9398.1f56e3f17795f43f.js} +1 -1
  125. package/apps/pwa/out/_next/static/chunks/9527.3e5ad31c891c5fcb.js +79 -0
  126. package/apps/pwa/out/_next/static/chunks/9571-4ac933e774d1225c.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-9fc644de2d8edae3.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/approvals/page-0c9dace2db62bee8.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f5e65c3dc9d89f2a.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/board/page-2a9c19b9a140b7b1.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/botlab/page-61533ad92141adfb.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/bots/page-112004ced6fd0329.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/ceo/page-f733318c237a49d8.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/chat/page-51ea677d2d33bbc0.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/consult/page-428b41f2f9566e3c.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/control/page-1b29396ea90a61e5.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/decisions/page-cf83ec613ac904bf.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/design-check/page-3f4c0ecbc284bb5f.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/editor/page-b63c322f54f70cc6.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/exec/page-fe328c4ee9aac6b4.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/field/page-bfb855c584f0fb98.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/healthz/route-9fc644de2d8edae3.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/inside/page-47b1710c110eabd7.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/intake/page-42895214458bc6d2.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/layout-d03de0ebd8366e23.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/live/page-3ed6c47e4b1c61c2.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/live-run/page-ae653e9bf261c738.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/loops/page-23f3f0a0209c0ac4.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/market/page-88c691273aae66f9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e187ac52a95538b3.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/morning/page-6e45828daed1295e.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/not-found-edb5d7287bb46186.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/observatory/page-4a7eaacd93c3f6a5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ca073d43d74cc84.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1e9fee67b1199436.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-df1283ea963c6816.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/outputs/page-19fcf8d8301ccd18.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/page-5ab699e0303bbb40.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7cde0d29756984c5.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-9d4c598e8ee22f7a.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/sessions/page-cc1609a71f44ec62.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7659a9a1345bfaa9.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/settings/page-0afef60ecc0c4af5.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-a3553949f8f34f5f.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/setup/layout-9fc644de2d8edae3.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/setup/page-057a69702f3c67c7.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/share/page-c0f0e570f3f74c73.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/showroom/page-1825071ae34e3b89.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/tasks/page-6244e3e135d8ccfc.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/term/{page-0a815f34367b6db6.js → page-da787e8a10b8a82e.js} +1 -1
  171. package/apps/pwa/out/_next/static/chunks/app/today/page-1316d32498e2be42.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/trace/page-4df94572e343de2e.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/vault/page-708969f7475e88c1.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-c58add08c919a1dc.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/app/workflows/page-a24847f45e5d5bf9.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/app/workspace/page-acfec65a3a60e22e.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-3dfc598e6fbde245.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/framework-c658a626118411b7.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-4c73685fd891445b.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-6310f7e5de7dd01d.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-51c326bf48610be1.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-d0beadf754da59b0.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-acd243bfbf3f6732.js +1 -0
  184. package/apps/pwa/out/approvals/index.html +1 -1
  185. package/apps/pwa/out/approvals/index.txt +22 -22
  186. package/apps/pwa/out/autopilot/index.html +1 -1
  187. package/apps/pwa/out/autopilot/index.txt +22 -22
  188. package/apps/pwa/out/board/index.html +1 -1
  189. package/apps/pwa/out/board/index.txt +22 -22
  190. package/apps/pwa/out/botlab/index.html +1 -1
  191. package/apps/pwa/out/botlab/index.txt +21 -21
  192. package/apps/pwa/out/bots/index.html +1 -1
  193. package/apps/pwa/out/bots/index.txt +21 -21
  194. package/apps/pwa/out/ceo/index.html +1 -1
  195. package/apps/pwa/out/ceo/index.txt +22 -22
  196. package/apps/pwa/out/chat/index.html +1 -1
  197. package/apps/pwa/out/chat/index.txt +21 -21
  198. package/apps/pwa/out/consult/index.html +1 -1
  199. package/apps/pwa/out/consult/index.txt +22 -22
  200. package/apps/pwa/out/control/index.html +1 -1
  201. package/apps/pwa/out/control/index.txt +22 -22
  202. package/apps/pwa/out/decisions/index.html +1 -1
  203. package/apps/pwa/out/decisions/index.txt +21 -21
  204. package/apps/pwa/out/design-check/index.html +1 -1
  205. package/apps/pwa/out/design-check/index.txt +22 -22
  206. package/apps/pwa/out/editor/index.html +1 -1
  207. package/apps/pwa/out/editor/index.txt +22 -22
  208. package/apps/pwa/out/exec/index.html +1 -1
  209. package/apps/pwa/out/exec/index.txt +22 -22
  210. package/apps/pwa/out/field/index.html +1 -1
  211. package/apps/pwa/out/field/index.txt +22 -22
  212. package/apps/pwa/out/healthz +1 -1
  213. package/apps/pwa/out/index.html +1 -1
  214. package/apps/pwa/out/index.txt +21 -21
  215. package/apps/pwa/out/inside/index.html +1 -1
  216. package/apps/pwa/out/inside/index.txt +21 -21
  217. package/apps/pwa/out/intake/index.html +1 -1
  218. package/apps/pwa/out/intake/index.txt +22 -22
  219. package/apps/pwa/out/live/index.html +1 -1
  220. package/apps/pwa/out/live/index.txt +22 -22
  221. package/apps/pwa/out/live-run/index.html +1 -1
  222. package/apps/pwa/out/live-run/index.txt +22 -22
  223. package/apps/pwa/out/loops/index.html +1 -1
  224. package/apps/pwa/out/loops/index.txt +21 -21
  225. package/apps/pwa/out/market/index.html +1 -1
  226. package/apps/pwa/out/market/index.txt +21 -21
  227. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  228. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  229. package/apps/pwa/out/morning/index.html +1 -1
  230. package/apps/pwa/out/morning/index.txt +22 -22
  231. package/apps/pwa/out/observatory/index.html +1 -1
  232. package/apps/pwa/out/observatory/index.txt +22 -22
  233. package/apps/pwa/out/ops/checklist/index.html +1 -1
  234. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  235. package/apps/pwa/out/ops/release/index.html +1 -1
  236. package/apps/pwa/out/ops/release/index.txt +21 -21
  237. package/apps/pwa/out/ops/seats/index.html +1 -1
  238. package/apps/pwa/out/ops/seats/index.txt +21 -21
  239. package/apps/pwa/out/outputs/index.html +1 -1
  240. package/apps/pwa/out/outputs/index.txt +21 -21
  241. package/apps/pwa/out/reflection/index.html +1 -1
  242. package/apps/pwa/out/reflection/index.txt +22 -22
  243. package/apps/pwa/out/scheduler/index.html +1 -1
  244. package/apps/pwa/out/scheduler/index.txt +22 -22
  245. package/apps/pwa/out/sessions/index.html +1 -1
  246. package/apps/pwa/out/sessions/index.txt +21 -21
  247. package/apps/pwa/out/settings/devices/index.html +1 -1
  248. package/apps/pwa/out/settings/devices/index.txt +22 -22
  249. package/apps/pwa/out/settings/index.html +1 -1
  250. package/apps/pwa/out/settings/index.txt +22 -22
  251. package/apps/pwa/out/setup/done/index.html +1 -1
  252. package/apps/pwa/out/setup/done/index.txt +22 -22
  253. package/apps/pwa/out/setup/index.html +1 -1
  254. package/apps/pwa/out/setup/index.txt +22 -22
  255. package/apps/pwa/out/share/index.html +1 -1
  256. package/apps/pwa/out/share/index.txt +22 -22
  257. package/apps/pwa/out/showroom/index.html +1 -1
  258. package/apps/pwa/out/showroom/index.txt +21 -21
  259. package/apps/pwa/out/tasks/index.html +1 -1
  260. package/apps/pwa/out/tasks/index.txt +22 -22
  261. package/apps/pwa/out/term/index.html +1 -1
  262. package/apps/pwa/out/term/index.txt +22 -22
  263. package/apps/pwa/out/today/index.html +1 -1
  264. package/apps/pwa/out/today/index.txt +22 -22
  265. package/apps/pwa/out/trace/index.html +1 -1
  266. package/apps/pwa/out/trace/index.txt +22 -22
  267. package/apps/pwa/out/vault/index.html +1 -1
  268. package/apps/pwa/out/vault/index.txt +22 -22
  269. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  270. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  271. package/apps/pwa/out/workflows/index.html +1 -1
  272. package/apps/pwa/out/workflows/index.txt +22 -22
  273. package/apps/pwa/out/workspace/index.html +1 -1
  274. package/apps/pwa/out/workspace/index.txt +22 -22
  275. package/apps/pwa/out/worktrees/index.html +1 -1
  276. package/apps/pwa/out/worktrees/index.txt +22 -22
  277. package/graphs/overlays/README.md +6 -0
  278. package/graphs/release/release-loop.yaml +33 -17
  279. package/graphs/units/verbs/make-doc.yaml +1 -0
  280. package/package.json +1 -1
  281. package/scripts/bench-metering-plan.ts +229 -0
  282. package/scripts/demo/demo1104-parallel-host.ts +56 -0
  283. package/scripts/demo/demo1104-parallel.ts +72 -0
  284. package/scripts/public-leak-baseline.txt +0 -1
  285. package/scripts/release-loop/docs-node.ts +4 -2
  286. package/scripts/release-loop/gate-image-pin.ts +116 -2
  287. package/scripts/release-loop/gate-node.ts +217 -25
  288. package/scripts/release-loop/gate-progress-sim.ts +73 -0
  289. package/scripts/release-loop/notes-repair.ts +18 -1
  290. package/scripts/release-loop/preflight.ts +188 -8
  291. package/scripts/release-loop/render-warm-control-manifest.ts +22 -0
  292. package/scripts/release-loop/resume-release.ts +9 -7
  293. package/scripts/release-loop/resume.ts +13 -4
  294. package/scripts/release-loop/warm-control-forward.ts +178 -0
  295. package/scripts/retro-cycle.ts +30 -8
  296. package/scripts/rhythm/daily.ts +4 -1
  297. package/scripts/rhythm/linear-progress-sync.ts +28 -15
  298. package/scripts/ux-sim.ts +7 -1
  299. package/scripts/warm-pool-provider-config.ts +6 -1
  300. package/src/agent-mission/grok-auth-status.ts +78 -18
  301. package/src/agent-mission/mission-out.ts +2 -2
  302. package/src/agent-substrate/pr-reviewer.ts +147 -11
  303. package/src/agent-substrate/self-review-cli.ts +10 -2
  304. package/src/auto-research/research-fanout.ts +221 -0
  305. package/src/auto-research/research-turn.ts +282 -36
  306. package/src/autopilot/mission-codebase-gate.ts +7 -3
  307. package/src/cli/control-cli.ts +15 -6
  308. package/src/cli/log-event-names.ts +8 -0
  309. package/src/cli/setup-keys.ts +20 -8
  310. package/src/cli/tui-test-cli.ts +9 -5
  311. package/src/control-plane/ledger.ts +42 -4
  312. package/src/control-plane/member-tokens.ts +25 -2
  313. package/src/control-plane/ports.ts +8 -3
  314. package/src/control-plane/server.ts +26 -5
  315. package/src/core-turn/research-policy.ts +7 -1
  316. package/src/core-turn/run-core-turn.ts +186 -39
  317. package/src/core-turn/types.ts +2 -0
  318. package/src/dashboard/classic-sidetab-mission-job.ts +113 -24
  319. package/src/dashboard/classic-sidetab-mission-pair.ts +3 -2
  320. package/src/dashboard/classic-sidetab-mission-trio.ts +35 -12
  321. package/src/dashboard/classic-sidetab-mission.ts +2 -0
  322. package/src/dashboard/index.ts +9 -1
  323. package/src/dashboard/sidetab-runtime.ts +2 -0
  324. package/src/dashboard/visible-mission-diagnostics.ts +16 -0
  325. package/src/domains/retro-cycle-observation.ts +43 -0
  326. package/src/domains/retro-cycle.ts +13 -2
  327. package/src/domains/retro-proposals.ts +92 -0
  328. package/src/domains/retro-report.ts +6 -1
  329. package/src/graph-runner/graph-cli.ts +24 -1
  330. package/src/graph-runner/graph-grow-llm.ts +3 -1
  331. package/src/graph-runner/runner.ts +226 -30
  332. package/src/harness/harness-cli-command.ts +4 -2
  333. package/src/harness/harness-pod-dispatch.ts +3 -0
  334. package/src/index.ts +2 -2
  335. package/src/llm/child-first-llm-observation.ts +112 -0
  336. package/src/llm/provider-credentials.ts +60 -4
  337. package/src/llm/provider-failure-evidence.ts +44 -0
  338. package/src/llm.ts +170 -11
  339. package/src/mcp/client.ts +7 -0
  340. package/src/mcp/proxy-runtime.ts +6 -1
  341. package/src/mcp/server.ts +54 -0
  342. package/src/native-tool-catalog.ts +2 -2
  343. package/src/nexus/api/consult-requests.ts +18 -6
  344. package/src/nexus/api/discord-trigger-bot.ts +6 -6
  345. package/src/nexus/api/graphs-api.ts +4 -2
  346. package/src/nexus/api/grokbot-trigger-bot.ts +206 -0
  347. package/src/nexus/api/telegram-trigger-bot.ts +6 -6
  348. package/src/nexus/boot/register-mcp-clients.ts +114 -8
  349. package/src/nexus/index.ts +15 -0
  350. package/src/nexus/outbound/grokbot-adapter.ts +71 -0
  351. package/src/nexus/outbound/router.ts +33 -13
  352. package/src/oauth/codex-owner-mirror.ts +47 -10
  353. package/src/onboarding/first-run.ts +44 -6
  354. package/src/preview/terminal.ts +22 -7
  355. package/src/prompt-enhance/enhance.ts +10 -0
  356. package/src/pty-shell/pty-write-provenance.ts +21 -3
  357. package/src/pty-shell/registry.ts +9 -2
  358. package/src/release-loop/proposal-auto-place.ts +83 -0
  359. package/src/research/axis-fanout.ts +40 -5
  360. package/src/research/lenses/second-order.ts +312 -0
  361. package/src/self-dev/dev-cli.ts +3 -1
  362. package/src/self-dev/draft-sweep.ts +31 -10
  363. package/src/self-dev/draft-triage-rules.ts +60 -3
  364. package/src/self-dev/run-supervisor.ts +152 -2
  365. package/src/self-implement/goal-author.ts +208 -23
  366. package/src/self-implement/graph-overlay-yaml.ts +151 -0
  367. package/src/self-implement/graph-yaml.ts +68 -2
  368. package/src/self-implement/orchestrator.ts +62 -15
  369. package/src/self-implement/test-scenario-request.ts +37 -6
  370. package/src/session/chat.ts +2 -2
  371. package/src/session-runtime/index.ts +37 -5
  372. package/src/sidetab-core/model.ts +205 -10
  373. package/src/sidetab-core/visible-agent-mission-pair.ts +51 -0
  374. package/src/sidetab-core/visible-agent-mission.ts +105 -47
  375. package/src/skills/tools/omni-search.ts +4 -2
  376. package/src/task-agent/parent-host.ts +19 -1
  377. package/src/task-agent/recall-inject.ts +98 -0
  378. package/src/task-agent/task-hand.ts +26 -7
  379. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +19 -1
  380. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +15 -0
  381. package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +21 -9
  382. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +1 -1
  383. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +460 -96
  384. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +45 -3
  385. package/src/task-orchestrator/surfaces/self-implement-pod.ts +38 -8
  386. package/src/tool-hints/gate.ts +45 -14
  387. package/src/tool-hints/signals.ts +1 -1
  388. package/src/tool-hints/types.ts +2 -0
  389. package/src/tool-runtime/browser-hand-runtime.ts +11 -1
  390. package/src/tool-runtime/browser-runtime.ts +31 -18
  391. package/src/tool-runtime/elanous-linear-secretary-runtime.ts +152 -36
  392. package/src/tool-runtime/types.ts +2 -0
  393. package/src/tui/entry.ts +27 -7
  394. package/src/tui/sidetab/attach.ts +112 -0
  395. package/src/tui/sidetab/list.ts +3 -2
  396. package/src/tui-client/next-dashboard-runtime.ts +52 -0
  397. package/src/ux-sim/draft-inventory-builder.ts +2 -1
  398. package/src/ux-sim/linear-secretary.ts +4 -12
  399. package/src/ux-sim/mock-scenario-catalog.json +32 -29
  400. package/src/ux-sim/mock-scenario-catalog.ts +55 -3
  401. package/src/ux-sim/release-sim-rig.ts +62 -18
  402. package/src/ux-sim/service-key-setup.ts +63 -0
  403. package/src/version/packed-revision.json +1 -1
  404. package/apps/pwa/out/_next/static/chunks/114.2b90424d1a3ce84c.js +0 -1
  405. package/apps/pwa/out/_next/static/chunks/1151-5c2bb8f002ca2dd6.js +0 -1
  406. package/apps/pwa/out/_next/static/chunks/1261-a616d5728e02e624.js +0 -1
  407. package/apps/pwa/out/_next/static/chunks/1357.3bbef3976c37f94a.js +0 -1
  408. package/apps/pwa/out/_next/static/chunks/1362-20adddfaf662b0fa.js +0 -1
  409. package/apps/pwa/out/_next/static/chunks/1737-9491fc6ab29b9ec6.js +0 -1
  410. package/apps/pwa/out/_next/static/chunks/1803-4f91a8e7dcaf042c.js +0 -1
  411. package/apps/pwa/out/_next/static/chunks/1961.a81b12872c3e93a9.js +0 -23
  412. package/apps/pwa/out/_next/static/chunks/1970cf59.2d4d8ce5d6c81853.js +0 -1
  413. package/apps/pwa/out/_next/static/chunks/1971-8890f3962ba7ee0a.js +0 -1
  414. package/apps/pwa/out/_next/static/chunks/2073-ba274e00e4f9efb4.js +0 -1
  415. package/apps/pwa/out/_next/static/chunks/2268-53861f339e0b65a2.js +0 -1
  416. package/apps/pwa/out/_next/static/chunks/273.f156eee28f11af77.js +0 -1
  417. package/apps/pwa/out/_next/static/chunks/2873.d2140e5a82546401.js +0 -1
  418. package/apps/pwa/out/_next/static/chunks/3091.a5a4143dea33d197.js +0 -90
  419. package/apps/pwa/out/_next/static/chunks/3095.dc44586a5f83b86d.js +0 -1
  420. package/apps/pwa/out/_next/static/chunks/3113.d7472bbc27d580c7.js +0 -1
  421. package/apps/pwa/out/_next/static/chunks/3228-9650b6447b6fa288.js +0 -1
  422. package/apps/pwa/out/_next/static/chunks/360.ae9f9f4c33c395e8.js +0 -79
  423. package/apps/pwa/out/_next/static/chunks/3638.80412ea63aae8f3f.js +0 -286
  424. package/apps/pwa/out/_next/static/chunks/3744.54f87db52acfd1ab.js +0 -1
  425. package/apps/pwa/out/_next/static/chunks/4311-6dd3144002cc0c2d.js +0 -1
  426. package/apps/pwa/out/_next/static/chunks/4426-2b230fad00c88930.js +0 -1
  427. package/apps/pwa/out/_next/static/chunks/4445.7990c76b3751a918.js +0 -115
  428. package/apps/pwa/out/_next/static/chunks/4447-14c5161fa59166c7.js +0 -1
  429. package/apps/pwa/out/_next/static/chunks/4856-b0b8075bba8c53f4.js +0 -1
  430. package/apps/pwa/out/_next/static/chunks/4870-de370d65e73c0bb5.js +0 -1
  431. package/apps/pwa/out/_next/static/chunks/4885-2c989165c4b29fad.js +0 -1
  432. package/apps/pwa/out/_next/static/chunks/4894.fec2ca9e99caefa2.js +0 -1
  433. package/apps/pwa/out/_next/static/chunks/5093.8f04b7f8cb899a95.js +0 -94
  434. package/apps/pwa/out/_next/static/chunks/5122-2bb177cebf89e19a.js +0 -1
  435. package/apps/pwa/out/_next/static/chunks/5154.5f56dc3902e3d275.js +0 -36
  436. package/apps/pwa/out/_next/static/chunks/529.64ff7257180b2ac9.js +0 -1
  437. package/apps/pwa/out/_next/static/chunks/5394.5dabeb0c62293a28.js +0 -93
  438. package/apps/pwa/out/_next/static/chunks/5461.08bf2404ff38ec85.js +0 -1
  439. package/apps/pwa/out/_next/static/chunks/5474-22e08a85583209b2.js +0 -1
  440. package/apps/pwa/out/_next/static/chunks/5567-265df39ed8fe9dcb.js +0 -1
  441. package/apps/pwa/out/_next/static/chunks/5570-a94ae19811cb2046.js +0 -1
  442. package/apps/pwa/out/_next/static/chunks/5574-b47c9ef2dceff1fd.js +0 -1
  443. package/apps/pwa/out/_next/static/chunks/5730.43d7ccc09988e646.js +0 -1
  444. package/apps/pwa/out/_next/static/chunks/5824.da9527b15a3221e5.js +0 -1
  445. package/apps/pwa/out/_next/static/chunks/5963-c4d8469c52a0828b.js +0 -1
  446. package/apps/pwa/out/_next/static/chunks/6001.ec4049ceb3c43418.js +0 -27
  447. package/apps/pwa/out/_next/static/chunks/6120-471f03db1e299c0c.js +0 -1
  448. package/apps/pwa/out/_next/static/chunks/6175-41479e643aca1878.js +0 -1
  449. package/apps/pwa/out/_next/static/chunks/6291.a2de4f9787637075.js +0 -104
  450. package/apps/pwa/out/_next/static/chunks/6400-6699907c3537436a.js +0 -1
  451. package/apps/pwa/out/_next/static/chunks/6428.1f4327d6ae5fdf9a.js +0 -287
  452. package/apps/pwa/out/_next/static/chunks/644.02cb026fa44bcd0a.js +0 -1
  453. package/apps/pwa/out/_next/static/chunks/6466-6c87d60d3dd174fb.js +0 -1
  454. package/apps/pwa/out/_next/static/chunks/6773.d4264665ab31bec0.js +0 -1
  455. package/apps/pwa/out/_next/static/chunks/6822.3c789f1a8443e774.js +0 -1
  456. package/apps/pwa/out/_next/static/chunks/7261-8ff69d3b2ee671fd.js +0 -1
  457. package/apps/pwa/out/_next/static/chunks/7266.084c6bbc70035140.js +0 -1
  458. package/apps/pwa/out/_next/static/chunks/7271.5c0100e7320aa856.js +0 -1
  459. package/apps/pwa/out/_next/static/chunks/7429-bf5731358c8f2f68.js +0 -1
  460. package/apps/pwa/out/_next/static/chunks/7464.01f7a0ae1215fbe7.js +0 -1
  461. package/apps/pwa/out/_next/static/chunks/7479.0fcad5f37eb64f0c.js +0 -1
  462. package/apps/pwa/out/_next/static/chunks/7483.427a2fe2049e388d.js +0 -148
  463. package/apps/pwa/out/_next/static/chunks/7502-be74718178e13e56.js +0 -1
  464. package/apps/pwa/out/_next/static/chunks/7530.0889722b19572065.js +0 -24
  465. package/apps/pwa/out/_next/static/chunks/7645.5b2ee3ad45c55ea3.js +0 -1
  466. package/apps/pwa/out/_next/static/chunks/7788.7d1c79f1a8e18946.js +0 -1
  467. package/apps/pwa/out/_next/static/chunks/7966.f71c8958d1637548.js +0 -1
  468. package/apps/pwa/out/_next/static/chunks/8073.f6cf2f2c71aafbd0.js +0 -1
  469. package/apps/pwa/out/_next/static/chunks/8201.190b94088980f430.js +0 -74
  470. package/apps/pwa/out/_next/static/chunks/8447.7963352ef5f71b76.js +0 -1
  471. package/apps/pwa/out/_next/static/chunks/8574-868e8129525ef6d9.js +0 -1
  472. package/apps/pwa/out/_next/static/chunks/868.6e953be05bcf6dca.js +0 -41
  473. package/apps/pwa/out/_next/static/chunks/8706-e1fe0309343a2273.js +0 -1
  474. package/apps/pwa/out/_next/static/chunks/8749-06384cdfc4520add.js +0 -1
  475. package/apps/pwa/out/_next/static/chunks/8861-cc1fa1c7b920fa8e.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/8967-7dfebf710c9dec9d.js +0 -1
  477. package/apps/pwa/out/_next/static/chunks/8997-3c564dbb3b58b055.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/923.2034d10ae91e9c20.js +0 -1
  479. package/apps/pwa/out/_next/static/chunks/9312.bc1b89c5d4368033.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/943.39ae5e82f4f1893f.js +0 -1
  481. package/apps/pwa/out/_next/static/chunks/9469.0500480de55fb205.js +0 -32
  482. package/apps/pwa/out/_next/static/chunks/9810-2543267050e58b82.js +0 -1
  483. package/apps/pwa/out/_next/static/chunks/9870.8419702475254745.js +0 -8
  484. package/apps/pwa/out/_next/static/chunks/9941-376d1b74d51b01a4.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/9958.385434ab04241758.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-deea1450b17cb8dc.js +0 -1
  487. package/apps/pwa/out/_next/static/chunks/app/approvals/page-70985b904f8650ef.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a2e15e33e56a4353.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/app/board/page-fc72ce2db12d6ca9.js +0 -1
  490. package/apps/pwa/out/_next/static/chunks/app/botlab/page-be03e41f9436ebd9.js +0 -1
  491. package/apps/pwa/out/_next/static/chunks/app/bots/page-35a35999382da3f2.js +0 -1
  492. package/apps/pwa/out/_next/static/chunks/app/ceo/page-3ff5b1e6ca88b848.js +0 -1
  493. package/apps/pwa/out/_next/static/chunks/app/chat/page-a65101300a0ee5c1.js +0 -1
  494. package/apps/pwa/out/_next/static/chunks/app/consult/page-3aca5b6d67dba511.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/app/control/page-45b8ab0a71e61314.js +0 -1
  496. package/apps/pwa/out/_next/static/chunks/app/decisions/page-53046e282d4cda8e.js +0 -1
  497. package/apps/pwa/out/_next/static/chunks/app/design-check/page-17809e60e8354c17.js +0 -1
  498. package/apps/pwa/out/_next/static/chunks/app/editor/page-fd2442d347bf5898.js +0 -1
  499. package/apps/pwa/out/_next/static/chunks/app/exec/page-e9d720d6fc082e21.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/app/field/page-6b8b4267bab0a677.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/app/healthz/route-deea1450b17cb8dc.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/app/inside/page-8bcf6233ac7c17af.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/app/intake/page-7cc25591cfc2126f.js +0 -1
  504. package/apps/pwa/out/_next/static/chunks/app/layout-053e871f35c9beba.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/app/live/page-eff819f0c2d5e084.js +0 -1
  506. package/apps/pwa/out/_next/static/chunks/app/live-run/page-4d7e9d8db5274a87.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/app/loops/page-2b2d8f5aa5f69ad4.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/app/market/page-0b8f92c5062e68b1.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1bd9d0fdac2ced3d.js +0 -1
  510. package/apps/pwa/out/_next/static/chunks/app/morning/page-9ee28f7df07428ea.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/app/not-found-44b7a1ff468c6648.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/app/observatory/page-cbc6523711dc1b65.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-fdad47899c2695be.js +0 -1
  514. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-79a8b5fee4c20871.js +0 -1
  515. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-03e8ac9606aeaffb.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/app/outputs/page-4cd55c55ec287e2f.js +0 -1
  517. package/apps/pwa/out/_next/static/chunks/app/page-db17b4305404161e.js +0 -1
  518. package/apps/pwa/out/_next/static/chunks/app/reflection/page-30041d848350fd02.js +0 -1
  519. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c540da022dbf86b0.js +0 -1
  520. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9399efc538da057f.js +0 -1
  521. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ca2d09128c585ca4.js +0 -1
  522. package/apps/pwa/out/_next/static/chunks/app/settings/page-0e2635aecd343038.js +0 -1
  523. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ef7f4399b6b7726e.js +0 -1
  524. package/apps/pwa/out/_next/static/chunks/app/setup/layout-deea1450b17cb8dc.js +0 -1
  525. package/apps/pwa/out/_next/static/chunks/app/setup/page-caf530535b875468.js +0 -1
  526. package/apps/pwa/out/_next/static/chunks/app/share/page-eaa20c1543a5fd8e.js +0 -1
  527. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c541eb1b75120f61.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/app/tasks/page-ab5e213eda9479f4.js +0 -1
  529. package/apps/pwa/out/_next/static/chunks/app/today/page-e858ba0ed9393b68.js +0 -1
  530. package/apps/pwa/out/_next/static/chunks/app/trace/page-1638ee9dd6e0582f.js +0 -1
  531. package/apps/pwa/out/_next/static/chunks/app/vault/page-4cf5a399109391f2.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-b4396321238798ec.js +0 -1
  533. package/apps/pwa/out/_next/static/chunks/app/workflows/page-cb72bfd21006781a.js +0 -1
  534. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6135d0242afbc434.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a1dccf907eddb856.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/c7945435-b44d4dbe90ba0dcb.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/ea514caa.05a24f78d9dffe5f.js +0 -122
  538. package/apps/pwa/out/_next/static/chunks/framework-e8a911e19b1be41f.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/main-7022f418fabba021.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/main-app-e5f15df755756a1e.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/pages/_app-4525f91e36940c9b.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/pages/_error-140f0e519c085b0f.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/webpack-8f22ef63dcb865b1.js +0 -1
  544. /package/apps/pwa/out/_next/static/{Om5xS9jpjSXJCeTNGYEi4 → HMXsxdy5MIIcHPMHv1wD4}/_ssgManifest.js +0 -0
@@ -1356,6 +1356,7 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
1356
1356
  // Wired below once the workflow daemon is constructed.
1357
1357
  let webPushDecisionTimer: ReturnType<typeof setInterval> | undefined;
1358
1358
  let workflowDiscordBot: NexusDiscordTriggerBotHandle | undefined;
1359
+ let workflowGrokbotBot: { start(): void; stop(): Promise<void> } | undefined;
1359
1360
  // V2.2-4 (2026-05-12) — NEXUS-hosted Telegram workflow trigger bot.
1360
1361
  let workflowTelegramBot: NexusTelegramTriggerBotHandle | undefined;
1361
1362
  /** R1 — 토큰마다 뜬 Q&A 폴러 «전부»(재시작 때 함께 비운다 · `workflowTelegramBot` 은 주 토큰 하나뿐). */
@@ -2812,6 +2813,16 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
2812
2813
  for (const wired of handles) adopt(wired);
2813
2814
  }
2814
2815
  }
2816
+ if (process.env.ELANOUS_GROKBOT_ENABLED === '1' && !isAutonomousRunContext()) {
2817
+ const { createGrokbotMainSessionDispatcher, createNexusGrokbotTriggerBot, createSshGrokbotMailbox } = await import('./api/grokbot-trigger-bot.js');
2818
+ const { makeElanousAgentRunTurn } = await import('../agent/monad-agent-turn.js');
2819
+ workflowGrokbotBot = createNexusGrokbotTriggerBot({
2820
+ mailbox: createSshGrokbotMailbox(),
2821
+ dispatch: createGrokbotMainSessionDispatcher(cfg, makeElanousAgentRunTurn(cfg, 'telegram')),
2822
+ });
2823
+ workflowGrokbotBot.start();
2824
+ debug.log('channel.grokbot', 'attached', { agent: 'COO', pollIntervalMs: 15_000 });
2825
+ }
2815
2826
  } catch (err: unknown) {
2816
2827
  const msg = err instanceof Error ? err.message : String(err);
2817
2828
  console.warn(`[nexus] trigger bot boot skipped: ${msg}`);
@@ -3592,6 +3603,10 @@ export async function runNexus(opts: RunNexusOptions = {}): Promise<RunNexusHand
3592
3603
  await Promise.all([...handles].map(async (handle) => {
3593
3604
  try { await handle.stop(); } catch { /* 종료는 계속 */ }
3594
3605
  }));
3606
+ if (workflowGrokbotBot) {
3607
+ try { await workflowGrokbotBot.stop(); } catch { /* 종료는 계속 */ }
3608
+ workflowGrokbotBot = undefined;
3609
+ }
3595
3610
  await next();
3596
3611
  };
3597
3612
 
@@ -0,0 +1,71 @@
1
+ import { debug } from '../../debug/log.js';
2
+ import { registerOutboundAdapter } from './router.js';
3
+ import type {
4
+ ChannelAdapter,
5
+ ChannelEnvelope,
6
+ ChannelResult,
7
+ OutboundChannelConfig,
8
+ RouterDeps,
9
+ } from './router.js';
10
+ import type { OutboundMsg } from './format.js';
11
+ import type { UserConfig } from '../../user-config.js';
12
+
13
+ export interface GrokbotAdapterOptions {
14
+ sendPrompt: (agent: string, prompt: string) => Promise<{ preview?: string }>;
15
+ now?: () => string;
16
+ log?: (event: string, data: Record<string, unknown>) => void;
17
+ agent?: string;
18
+ }
19
+
20
+ function safeError(error: unknown): string {
21
+ const message = error instanceof Error ? error.message : String(error);
22
+ return message.replace(/Bearer\s+\S+/gi, 'Bearer [redacted]').slice(0, 240);
23
+ }
24
+
25
+ function inboundEnvelope(payload: unknown): Omit<ChannelEnvelope, 'text'> & { text: string } | null {
26
+ if (!payload || typeof payload !== 'object' || Array.isArray(payload)) return null;
27
+ const event = payload as Record<string, unknown>;
28
+ if (typeof event.text !== 'string' || event.text.length === 0) return null;
29
+ if (typeof event.id !== 'string' && typeof event.id !== 'number') return null;
30
+ const kind = typeof event.kind === 'string' && event.kind.trim() ? event.kind : 'request';
31
+ return { text: event.text, kind, channel: 'COO', senderId: 'COO', messageId: event.id };
32
+ }
33
+
34
+ export function createGrokbotAdapter(options: GrokbotAdapterOptions): ChannelAdapter {
35
+ const agent = options.agent ?? 'COO';
36
+ const now = options.now ?? (() => new Date().toISOString());
37
+ const log = options.log ?? ((event, data) => debug.log('channel.grokbot', event, data));
38
+ return {
39
+ type: 'grokbot',
40
+ capabilities: {
41
+ send: true, receive: true, thread: false, topic: false, persona: false,
42
+ channelLifecycle: false, permissions: false, commands: false, attachments: false,
43
+ buttons: false, choices: true, deliveryConfirmation: false, rateLimit: false,
44
+ },
45
+ parseConfig: (raw): OutboundChannelConfig | undefined => raw.type === 'grokbot' ? { type: 'grokbot' } : undefined,
46
+ receive: (payload): ChannelEnvelope | null => {
47
+ const envelope = inboundEnvelope(payload);
48
+ if (!envelope) return null;
49
+ log('received', { id: envelope.messageId, text: envelope.text, receivedAt: now() });
50
+ return envelope;
51
+ },
52
+ send: async (_config: OutboundChannelConfig, message: OutboundMsg, _cfg: UserConfig, _deps: RouterDeps): Promise<ChannelResult> => {
53
+ const requestedAt = now();
54
+ log('request', { agent, text: message.text, requestedAt, kind: message.kind });
55
+ try {
56
+ const prompt = `[엘라누스 알림 — 아래를 대표님께 그대로 전해 주세요. 덧붙이지 마세요]\n\n${message.text}`;
57
+ const result = await options.sendPrompt(agent, prompt);
58
+ log('reply', { agent, repliedAt: now(), ...(result.preview ? { preview: result.preview } : {}) });
59
+ return { type: 'grokbot', ok: true };
60
+ } catch (error) {
61
+ const reason = safeError(error);
62
+ log('failure', { agent, failedAt: now(), reason });
63
+ return { type: 'grokbot', ok: false, error: reason };
64
+ }
65
+ },
66
+ };
67
+ }
68
+
69
+ export function registerGrokbotAdapter(options: GrokbotAdapterOptions): () => void {
70
+ return registerOutboundAdapter(createGrokbotAdapter(options));
71
+ }
@@ -110,9 +110,35 @@ export interface ChannelAdapter {
110
110
  parseConfig?: (raw: Record<string, unknown>) => OutboundChannelConfig | undefined;
111
111
  }
112
112
 
113
- /** Existing bot receive paths can normalize an accepted event through the same
114
- * adapter contract before dispatching to their unchanged workflow/chat handlers. */
115
- export function receiveChannelEvent(type: string, payload: unknown): ChannelEnvelope | null | Promise<ChannelEnvelope | null> {
113
+ /** Project adapter output onto the public envelope contract. Unknown keys and malformed optional fields are omitted; missing/non-string text or missing/empty/non-string kind rejects the event. Keep platform-specific data in the caller's raw tap instead. */
114
+ function normalizeChannelEnvelope(envelope: ChannelEnvelope | null): ChannelEnvelope | null {
115
+ if (!envelope || typeof envelope !== 'object' || typeof envelope.text !== 'string'
116
+ || typeof envelope.kind !== 'string' || !envelope.kind) return null;
117
+ return {
118
+ text: envelope.text,
119
+ kind: envelope.kind,
120
+ ...(typeof envelope.channel === 'string' ? { channel: envelope.channel } : {}),
121
+ ...(typeof envelope.senderId === 'string' ? { senderId: envelope.senderId } : {}),
122
+ ...(typeof envelope.messageId === 'string' || typeof envelope.messageId === 'number' ? { messageId: envelope.messageId } : {}),
123
+ ...(typeof envelope.threadId === 'string' ? { threadId: envelope.threadId } : {}),
124
+ ...(typeof envelope.topicId === 'string' ? { topicId: envelope.topicId } : {}),
125
+ ...(envelope.persona && typeof envelope.persona.name === 'string'
126
+ ? { persona: { name: envelope.persona.name, ...(typeof envelope.persona.avatarUrl === 'string' ? { avatarUrl: envelope.persona.avatarUrl } : {}) } }
127
+ : {}),
128
+ ...(Array.isArray(envelope.attachments) ? { attachments: envelope.attachments
129
+ .filter(item => item && typeof item.url === 'string')
130
+ .map(item => ({ url: item.url, ...(typeof item.name === 'string' ? { name: item.name } : {}) })) } : {}),
131
+ ...(Array.isArray(envelope.buttons) ? { buttons: envelope.buttons
132
+ .filter(item => item && typeof item.label === 'string' && typeof item.value === 'string')
133
+ .map(item => ({ label: item.label, value: item.value })) } : {}),
134
+ ...(Array.isArray(envelope.choices) ? { choices: envelope.choices
135
+ .filter(item => item && typeof item.label === 'string' && typeof item.value === 'string')
136
+ .map(item => ({ label: item.label, value: item.value })) } : {}),
137
+ };
138
+ }
139
+
140
+ /** Existing bot receive paths normalize accepted events before their unchanged handlers. */
141
+ export async function receiveChannelEvent(type: string, payload: unknown): Promise<ChannelEnvelope | null> {
116
142
  const adapter = outboundAdapters.get(type) ?? installedAdapters.get(type);
117
143
  if (!adapter?.capabilities.receive || !adapter.receive) return null;
118
144
  const recordOutcome = (outcome: 'accepted' | 'rejected' | 'error'): void => {
@@ -126,19 +152,13 @@ export function receiveChannelEvent(type: string, payload: unknown): ChannelEnve
126
152
  } catch { /* observation must not change channel receive behavior */ }
127
153
  };
128
154
  const recordResult = (envelope: ChannelEnvelope | null): ChannelEnvelope | null => {
129
- recordOutcome(envelope ? 'accepted' : 'rejected');
130
- return envelope;
155
+ const normalized = normalizeChannelEnvelope(envelope);
156
+ recordOutcome(normalized ? 'accepted' : 'rejected');
157
+ return normalized;
131
158
  };
132
159
 
133
160
  try {
134
- const result = adapter.receive(payload);
135
- if (result && typeof (result as Promise<ChannelEnvelope | null>).then === 'function') {
136
- return Promise.resolve(result).then(recordResult, error => {
137
- recordOutcome('error');
138
- throw error;
139
- });
140
- }
141
- return recordResult(result as ChannelEnvelope | null);
161
+ return recordResult(await adapter.receive(payload));
142
162
  } catch (error) {
143
163
  recordOutcome('error');
144
164
  throw error;
@@ -1,14 +1,36 @@
1
1
  import { hostname } from 'node:os';
2
- import { join } from 'node:path';
2
+ import { createHash } from 'node:crypto';
3
+ import { readFileSync } from 'node:fs';
4
+ import { dirname, isAbsolute, join } from 'node:path';
3
5
  import { elanousStateRoot } from '../autopilot/state-paths.js';
6
+ import { debug } from '../debug/log.js';
4
7
  import { getUserConfig } from '../user-config.js';
5
8
  import { loadTokens, type ProviderAuthState } from './store.js';
6
9
 
7
10
  export const CODEX_OWNER_MIRROR_RELATIVE_PATH = join('remote-parent-credentials', 'cli-mirror', 'auth.json');
8
- export const CODEX_OWNER_MIRROR_REQUIRED = 'Codex 주인 미러가 없거나 만료됐다 — 주인 호스트에서 `eln codex mirror push <host>` 를 실행해야 한다';
11
+ export const CODEX_OWNER_MIRROR_REQUIRED = 'Codex owner access mirror rejected — inspect llm.codex/owner-mirror-rejected for the precise reason';
9
12
 
10
13
  export function codexOwnerMirrorAuthPath(): string {
11
- return join(elanousStateRoot(), CODEX_OWNER_MIRROR_RELATIVE_PATH);
14
+ const stateRoot = elanousStateRoot();
15
+ const derivedPath = join(stateRoot, CODEX_OWNER_MIRROR_RELATIVE_PATH);
16
+ const configuredPath = process.env.ELANOUS_REMOTE_CODEX_ACCESS_ONLY === '1'
17
+ ? process.env.ELANOUS_REMOTE_CODEX_MIRROR_PATH?.trim()
18
+ : undefined;
19
+ const path = configuredPath && isAbsolute(configuredPath) ? configuredPath : derivedPath;
20
+ try {
21
+ debug.log('llm.codex', 'owner-mirror-path-compared', {
22
+ source: path === derivedPath ? 'state-root' : 'remote-explicit',
23
+ stateRootSha256: rootFingerprint(stateRoot),
24
+ derivedMirrorRootSha256: rootFingerprint(dirname(dirname(dirname(derivedPath)))),
25
+ resolvedMirrorRootSha256: rootFingerprint(dirname(dirname(dirname(path)))),
26
+ explicitPathAccepted: Boolean(configuredPath && path === configuredPath),
27
+ });
28
+ } catch { /* diagnostics must not block auth */ }
29
+ return path;
30
+ }
31
+
32
+ function rootFingerprint(root: string): string {
33
+ return createHash('sha256').update(root).digest('hex').slice(0, 16);
12
34
  }
13
35
 
14
36
  function normalizedHost(value: string): string {
@@ -30,15 +52,30 @@ export function readCodexOwnerAccessMirror(
30
52
  const path = opts.path ?? codexOwnerMirrorAuthPath();
31
53
  const now = opts.now ?? Date.now();
32
54
  let state: ProviderAuthState | null = null;
33
- try { state = loadTokens(storeKey, path); } catch { /* fail closed below */ }
55
+ let readFailure: 'missing-file' | 'read-error' | 'invalid-json' | undefined;
56
+ try {
57
+ const raw = readFileSync(path, 'utf8');
58
+ try { JSON.parse(raw); } catch { readFailure = 'invalid-json'; }
59
+ } catch (error) {
60
+ readFailure = (error as NodeJS.ErrnoException).code === 'ENOENT' ? 'missing-file' : 'read-error';
61
+ }
62
+ if (!readFailure) {
63
+ try { state = loadTokens(storeKey, path); } catch { /* classify safely below */ }
64
+ }
34
65
  const tokenFields = state?.tokens as (ProviderAuthState['tokens'] & { refresh_token?: unknown }) | undefined;
35
66
  const expiresAt = state?.tokens.expiresAt;
36
- if (!state || state.authMode !== 'chatgpt' || !state.tokens.accessToken
37
- || tokenFields?.refreshToken !== '' || tokenFields?.refresh_token !== ''
38
- || typeof expiresAt !== 'number'
39
- || !Number.isFinite(expiresAt) || expiresAt <= now + 120_000) {
40
- throw new Error(CODEX_OWNER_MIRROR_REQUIRED);
67
+ const reason = readFailure ?? (!state || !state.tokens ? 'no-access'
68
+ : state.authMode !== 'chatgpt' ? 'authMode'
69
+ : !state.tokens.accessToken ? 'no-access'
70
+ : typeof tokenFields?.refreshToken !== 'string' || typeof tokenFields?.refresh_token !== 'string' ? 'refresh-missing'
71
+ : tokenFields.refreshToken !== '' || tokenFields.refresh_token !== '' ? 'refresh-not-empty'
72
+ : typeof expiresAt !== 'number' || !Number.isFinite(expiresAt) || expiresAt <= now + 120_000 ? 'expiry'
73
+ : undefined);
74
+ if (reason) {
75
+ const root = dirname(dirname(dirname(path)));
76
+ try { debug.log('llm.codex', 'owner-mirror-rejected', { reason, storeKey, rootSha256: rootFingerprint(root) }, { level: 'warn' }); } catch { /* fail-soft */ }
77
+ throw new Error(`${CODEX_OWNER_MIRROR_REQUIRED} (reason=${reason}; storeKey=${storeKey}; rootSha256=${rootFingerprint(root)})`);
41
78
  }
42
- return state;
79
+ return state!;
43
80
  }
44
81
 
@@ -3,7 +3,7 @@ import { detectProviders, type DetectedProvider } from '../llm/provider-detect.j
3
3
  import { debug } from '../debug/log.js';
4
4
  import { detectLocale, type Locale } from '../expression/locale.js';
5
5
  import { unattendedNextStepLine } from './entry-hints.js';
6
- import { resolveProviderCredential } from '../llm/provider-credentials.js';
6
+ import { providerEnvKey, resolveProviderCredential, resolveProviderCredentialAsync } from '../llm/provider-credentials.js';
7
7
  import { zaiCodingPlanAvailable } from '../llm/zai-coding-plan.js';
8
8
  import { collectServiceKeys, printKeySetupReport } from './key-setup.js';
9
9
  import { getSecretAsync, setSecretAsync } from '../nexus/config/secrets/index.js';
@@ -121,8 +121,8 @@ export async function runFirstRun(deps: FirstRunDeps = {}): Promise<{
121
121
  // An incomplete onboarding marker does not mean the user's LLM is unconfigured.
122
122
  // Keep an already usable provider, key and model rather than replacing it with a detected subscription.
123
123
  const existing = cfg.llm.provider !== 'auto'
124
- ? resolveProviderCredential({ provider: cfg.llm.provider, rotation: cfg.llm.rotation,
125
- baseProvider: cfg.llm.provider, baseApiKey: cfg.llm.apiKey, env: deps.env })
124
+ ? await resolveProviderCredentialAsync({ provider: cfg.llm.provider, rotation: cfg.llm.rotation,
125
+ baseProvider: cfg.llm.provider, baseApiKey: cfg.llm.apiKey, env: deps.env }, deps.getSecretAsync)
126
126
  : undefined;
127
127
  const configured = existing && existing.source !== 'none'
128
128
  ? cfg.llm.provider
@@ -185,11 +185,11 @@ export async function runFirstRun(deps: FirstRunDeps = {}): Promise<{
185
185
  }
186
186
  }
187
187
  const credential = inputs === 1 || provider !== cfg.llm.provider
188
- ? resolveProviderCredential({
188
+ ? await resolveProviderCredentialAsync({
189
189
  provider, rotation: cfg.llm.rotation,
190
190
  baseProvider: cfg.llm.provider, baseApiKey: cfg.llm.apiKey,
191
191
  env: deps.env,
192
- })
192
+ }, deps.getSecretAsync)
193
193
  : undefined;
194
194
  if (inputs === 1 && credential?.source === 'none'
195
195
  && !(providerSetUpInPlace && provider === 'openai-codex')) {
@@ -206,7 +206,45 @@ export async function runFirstRun(deps: FirstRunDeps = {}): Promise<{
206
206
  });
207
207
  printKeySetupReport(results, print);
208
208
  if (results.length === 0 || results.some((result) => result.status !== 'success')) return needsLlm(inputs);
209
- return needsLlm(inputs, [text.keyStoredNotReady]);
209
+ // Probe the same lookup the runtime will use before marking first-run ready.
210
+ const secretId = providerEnvKey(provider);
211
+ let storedValue: string | undefined;
212
+ try {
213
+ storedValue = secretId
214
+ ? await (deps.getSecretAsync ?? getSecretAsync)(secretId)
215
+ : undefined;
216
+ } catch { /* keep the first-run state unready without exposing backend errors */ }
217
+ const storedCredential = resolveProviderCredential({
218
+ provider,
219
+ rotation: cfg.llm.rotation,
220
+ baseProvider: provider,
221
+ env: deps.env,
222
+ secretStoreApiKey: storedValue,
223
+ });
224
+ if (!storedValue?.trim() || storedCredential.source === 'none') return needsLlm(inputs, [text.keyStoredNotReady]);
225
+ // Only remove any legacy config key after the runtime can read its replacement.
226
+ // A failed SecretStore write/readback must leave the prior working config intact.
227
+ (deps.saveConfig ?? saveUserConfig)({
228
+ ...cfg,
229
+ llm: {
230
+ ...cfg.llm,
231
+ provider,
232
+ apiKey: undefined,
233
+ ...(provider !== cfg.llm.provider ? { baseUrl: undefined, model: undefined } : {}),
234
+ },
235
+ }, path);
236
+ (deps.saveConfig ?? saveUserConfig)({
237
+ ...cfg,
238
+ llm: {
239
+ ...cfg.llm,
240
+ provider,
241
+ apiKey: undefined,
242
+ ...(provider !== cfg.llm.provider ? { baseUrl: undefined, model: undefined } : {}),
243
+ },
244
+ onboarding: { ...cfg.onboarding, ready: true },
245
+ }, path);
246
+ observe('ready', inputs);
247
+ return { outcome: 'ready', provider, inputs };
210
248
  } catch {
211
249
  return needsLlm(inputs, [text.keySetupFailed]);
212
250
  }
@@ -559,10 +559,25 @@ export class PreviewTerminal {
559
559
 
560
560
  /** 자식 stdin 으로 바이트 전송(응답 채널·public write·마우스 공유). registry 모드면 handle.write,
561
561
  * 아니면 dup-fd(기본 경로 무접촉). */
562
- private writeToChild(data: string): void {
563
- if (this.registryHandle) { try { this.registryHandle.write(data); } catch { /* pty closing */ } return; }
564
- if (!this.alive || this.dupFd < 0) return;
565
- try { fs.writeSync(this.dupFd, data); } catch { /* pty closing */ }
562
+ private writeToChild(data: string): boolean {
563
+ if (this.registryHandle) {
564
+ try {
565
+ if (!this.registryHandle.canWrite()) return false;
566
+ this.registryHandle.write(data);
567
+ return true;
568
+ } catch { return false; }
569
+ }
570
+ if (!this.alive || this.dupFd < 0) return false;
571
+ try {
572
+ const bytes = Buffer.from(data, 'utf8');
573
+ let offset = 0;
574
+ while (offset < bytes.length) {
575
+ const written = fs.writeSync(this.dupFd, bytes, offset, bytes.length - offset);
576
+ if (written <= 0) return false;
577
+ offset += written;
578
+ }
579
+ return true;
580
+ } catch { return false; }
566
581
  }
567
582
 
568
583
  private scheduleUpdate(): void {
@@ -606,9 +621,9 @@ export class PreviewTerminal {
606
621
  return () => { this.rawOscTaps.delete(cb); };
607
622
  }
608
623
 
609
- /** Send raw bytes to the PTY (stdin from the child's perspective). */
610
- write(bytes: string): void {
611
- this.writeToChild(bytes);
624
+ /** Send raw bytes to the PTY and report whether its input handle accepted them. */
625
+ write(bytes: string): boolean {
626
+ return this.writeToChild(bytes);
612
627
  }
613
628
 
614
629
  /** Notify the PTY + emulator of new pane dimensions. Called on
@@ -120,6 +120,8 @@ export interface EnhanceOpts {
120
120
  groundedFacts?: readonly string[];
121
121
  /** Relevant prior-failure lessons for goal-authoring prompts only; never part of the original ask. */
122
122
  authoringLessons?: string;
123
+ /** Canonical reusable mock-device and event-injection inventory; reference only, not a completion gate. */
124
+ mockScenarioCatalog?: string;
123
125
  /** Clock seam for the first-token observation (ms epoch); defaults to `Date.now`. */
124
126
  now?: () => number;
125
127
  }
@@ -439,6 +441,14 @@ export async function enhancePrompt(raw: string, opts: EnhanceOpts = {}): Promis
439
441
  ...(opts.authoringLessons?.trim()
440
442
  ? ['', '## 지난 실패에서 배운 것', opts.authoringLessons.trim(), '위 교훈은 현재 ask의 대상 경로와 범위에 맞을 때만 적용하고, 맞지 않으면 무시하라.']
441
443
  : []),
444
+ ...(opts.mockScenarioCatalog?.trim()
445
+ ? [
446
+ '',
447
+ '## 재사용 가능한 목장치·사건 주입 카탈로그 (참고 자료 · 완료 조건이 아님)',
448
+ opts.mockScenarioCatalog.trim(),
449
+ '골의 완료 경계가 실물 점검만 요구하면 먼저 제약을 의심하라: 그 제약은 저작 문면의 세계와 구현의 세계에서 같은가? 카탈로그의 목장치나 사건 주입으로 같은 동작을 관찰할 수 있는가? 실제 외부 시스템 확인이 사용자의 의도인 경우에만 실물 점검을 유지하고, 목장치가 맞으면 해당 장치·입력·관측 신호를 제안하라.',
450
+ ]
451
+ : []),
442
452
  ].join('\n'),
443
453
  },
444
454
  ];
@@ -24,14 +24,32 @@
24
24
  * 장수 owner(데몬)는 PTY 를 계속 만든다. 훅만 믿으면 «한 번 새면 영영» 샌다. */
25
25
  const MAX_TRACKED_PTYS = 512;
26
26
 
27
- const writes = new Map<string, { count: number; lastAt: number; lastActor: string }>();
27
+ const writes = new Map<string, { count: number; lastAt: number; lastActor: string | null; accessMode?: 'read' | 'write' | 'auto' }>();
28
+
29
+ export function notePtyAccessMode(ptyId: string, accessMode: 'read' | 'write' | 'auto'): void {
30
+ const prev = writes.get(ptyId);
31
+ writes.delete(ptyId);
32
+ writes.set(ptyId, { count: prev?.count ?? 0, lastAt: prev?.lastAt ?? 0, lastActor: prev?.lastActor ?? null, accessMode });
33
+ while (writes.size > MAX_TRACKED_PTYS) {
34
+ const oldest = writes.keys().next();
35
+ if (oldest.done) break;
36
+ writes.delete(oldest.value);
37
+ }
38
+ }
39
+
40
+ export function ptyWriteControlState(ptyId: string): { accessMode: 'read' | 'write' | 'auto'; lastWriter: 'agent' | 'human' | null } | undefined {
41
+ const rec = writes.get(ptyId);
42
+ if (!rec?.accessMode) return undefined;
43
+ const lastWriter = rec.lastActor === 'agent' || rec.lastActor === 'human' ? rec.lastActor : null;
44
+ return { accessMode: rec.accessMode, lastWriter };
45
+ }
28
46
 
29
47
  /** 성공한 쓰기 1건을 기록한다. ⛔ 거부·실패는 세지 않는다(자식이 «본» 것만 세야 수가 뜻을 갖는다). */
30
48
  export function noteExternalWrite(ptyId: string, actor: string, now = Date.now()): void {
31
49
  const prev = writes.get(ptyId);
32
50
  // 재삽입으로 **삽입 순서를 갱신**한다 — 아래 축출이 「가장 오래 안 쓰인 것」을 버리게.
33
51
  writes.delete(ptyId);
34
- writes.set(ptyId, { count: (prev?.count ?? 0) + 1, lastAt: now, lastActor: actor });
52
+ writes.set(ptyId, { count: (prev?.count ?? 0) + 1, lastAt: now, lastActor: actor, ...(prev?.accessMode ? { accessMode: prev.accessMode } : {}) });
35
53
  while (writes.size > MAX_TRACKED_PTYS) {
36
54
  const oldest = writes.keys().next();
37
55
  if (oldest.done) break;
@@ -49,7 +67,7 @@ export function noteExternalWrite(ptyId: string, actor: string, now = Date.now()
49
67
  */
50
68
  export function externalWriteProvenance(ptyId: string, now = Date.now()): { externalWrites: number; externalWriteAgoMs: number; externalWriteActor: string } | undefined {
51
69
  const rec = writes.get(ptyId);
52
- if (!rec) return undefined;
70
+ if (!rec || rec.lastActor === null) return undefined;
53
71
  return { externalWrites: rec.count, externalWriteAgoMs: Math.max(0, now - rec.lastAt), externalWriteActor: rec.lastActor };
54
72
  }
55
73
 
@@ -30,7 +30,7 @@ import { resolveWriteDecision, resolveTakeover, type PtyWriteActor } from './pty
30
30
  import { addPtyManifestOutputBytes, upsertPtyManifest, updatePtyManifestSnapshot, updatePtyManifestNickname, markPtyManifestClosed, removePtyManifest, touchLivePtyManifest } from './pty-manifest.js';
31
31
  import { processPtyControlRequests } from './pty-control-ipc.js';
32
32
  import { tapPtyOutput, autoStopPtyRecording } from './pty-recording.js';
33
- import { forgetExternalWriteProvenance, noteExternalWrite } from './pty-write-provenance.js';
33
+ import { forgetExternalWriteProvenance, noteExternalWrite, notePtyAccessMode } from './pty-write-provenance.js';
34
34
  import { resolveRunIdentity } from '../harness/harness-space.js';
35
35
  import { addSelfDevRunParticipant, selfDevRunsDir } from '../self-dev/run-store.js';
36
36
  import { debug } from '../debug/log.js';
@@ -192,6 +192,8 @@ export interface PtyControlTarget {
192
192
  export interface PtyHandle extends PtyControlTarget {
193
193
  /** 고유 id — `<kind>_<hex>`. 같은 PTY 객체를 부르는 캐논 이름. */
194
194
  readonly id: string;
195
+ /** Actor of the last successful PTY write in this process; denied or failed writes do not update it. */
196
+ readonly lastWriteActor: PtyWriteActor | null;
195
197
  /**
196
198
  * 접근 모드(관찰 read / 인터랙션 write / 자율 auto). ⭐정책 매트릭스(§ 입력 중재):
197
199
  * - auto+locked = 보호된 자율(brain 소유·사람 write 불가). 위험 미션 무간섭.
@@ -508,10 +510,13 @@ export function startPty(opts: StartOpts): PtyHandle {
508
510
  } catch { term = null; }
509
511
 
510
512
  let nickname = opts.nickname;
513
+ let lastWriteActor: PtyWriteActor | null = null;
511
514
  let accessMode: PtyAccessMode = opts.accessMode ?? 'write';
512
515
  let transitionPolicy: PtyTransitionPolicy = opts.transitionPolicy ?? 'open';
516
+ notePtyAccessMode(id, accessMode);
513
517
  const handle: PtyHandle = {
514
518
  id,
519
+ get lastWriteActor() { return lastWriteActor; },
515
520
  kind: ptyKindOf(id),
516
521
  get nickname() { return nickname; },
517
522
  set nickname(v: string | undefined) { nickname = v; },
@@ -520,13 +525,14 @@ export function startPty(opts: StartOpts): PtyHandle {
520
525
  if (ptyManifestEnabled()) updatePtyManifestNickname(id, nickname, Date.now());
521
526
  },
522
527
  get accessMode() { return accessMode; },
523
- set accessMode(v: PtyAccessMode) { accessMode = v; },
528
+ set accessMode(v: PtyAccessMode) { accessMode = v; notePtyAccessMode(id, v); },
524
529
  get transitionPolicy() { return transitionPolicy; },
525
530
  set transitionPolicy(v: PtyTransitionPolicy) { transitionPolicy = v; },
526
531
  setAccessMode(mode: PtyAccessMode): boolean {
527
532
  // 정책 SSOT(canTransitionAccessMode): locked 면 다른 모드로 못 감(read+locked→write = write 불가).
528
533
  if (!canTransitionAccessMode(accessMode, mode, transitionPolicy)) return false;
529
534
  accessMode = mode;
535
+ notePtyAccessMode(id, mode);
530
536
  return true;
531
537
  },
532
538
  setTransitionPolicy(policy: PtyTransitionPolicy): void { transitionPolicy = policy; },
@@ -598,6 +604,7 @@ export function startPty(opts: StartOpts): PtyHandle {
598
604
  return;
599
605
  }
600
606
  adapter.write(chars);
607
+ lastWriteActor = actor;
601
608
  debug.log('pty.control', 'write', { ptyId: id, actor, mode: accessMode, bytes: chars.length });
602
609
  // ⭐⭐ 여기가 진짜 초크포인트다 — 허용 판정 뒤·바이트가 «실제로» 들어간 뒤. 모든 쓰기가
603
610
  // 이 자리로 모인다(크로스-프로세스 IPC · 같은 프로세스 감독 autoAssist · PtyShellSend).
@@ -0,0 +1,83 @@
1
+ import { runRequirementFunnel, type FunnelCandidate, type FunnelOptions, type RequirementDecision } from '../intake-plane/requirement-funnel.js';
2
+ import type { ConsensusEngine, ConsensusRepresentative } from '../loops/consensus.js';
3
+ import { placeCell, type PlacementDeps, type PlacementDecision } from './placement.js';
4
+ import { parseRubric, rubricGrade, rubricScore } from './rubric.js';
5
+
6
+ export interface ProposalPlacementInput {
7
+ /** The current funnel inputs; ledger capture and adoption hooks are intentionally not accepted here. */
8
+ funnel: Omit<FunnelOptions, 'ledger' | 'adopt' | 'mode' | 'placement'>;
9
+ rubricCandidate: FunnelCandidate;
10
+ consensus: Pick<ConsensusEngine, 'show'>;
11
+ consensusProposalId: string;
12
+ placement: PlacementDeps;
13
+ }
14
+
15
+ export type ProposalPlacementPlan =
16
+ | { status: 'not-eligible'; reason: string; decision?: RequirementDecision }
17
+ | { status: 'awaiting-consensus'; consensusProposalId: string; decision: RequirementDecision }
18
+ | { status: 'planned'; consensus: { id: string; status: 'agreed'; proposedBy: ConsensusRepresentative; agreedBy: ConsensusRepresentative };
19
+ decision: RequirementDecision; rubric: { score: number; grade: NonNullable<FunnelCandidate['grade']> }; placement: PlacementDecision };
20
+
21
+ /**
22
+ * Safe first slice for the proposal→placement path. It accepts a pre-collected rubric candidate and an existing
23
+ * dual-root card; the requirement funnel and both placement calculations run in shadow/dry-run only. There is no
24
+ * ledger writer, live adopter, proposal creator, or operational scheduler in this seam.
25
+ */
26
+ export function planAgreedProposalPlacement(input: ProposalPlacementInput): ProposalPlacementPlan {
27
+ const rubric = input.rubricCandidate;
28
+ if (rubric.score === null || rubric.grade === null) return { status: 'not-eligible', reason: 'candidate has no explicit rubric' };
29
+ const funnel = runRequirementFunnel({
30
+ ...input.funnel,
31
+ mode: 'shadow',
32
+ placement: { ...input.placement, dryRun: true },
33
+ });
34
+ const decision = funnel.decisions.find(({ candidate }) => candidate.id === rubric.id);
35
+ if (!decision) return { status: 'not-eligible', reason: `funnel candidate not found: ${rubric.id}` };
36
+ if (decision.status !== 'would-adopt') return { status: 'not-eligible', reason: decision.reason ?? `funnel status: ${decision.status}`, decision };
37
+ const sourceRubric = parseRubric(decision.candidate.text);
38
+ const sourceTitle = decision.candidate.text.split(/\s+루브릭:/, 1)[0]!.trim().slice(0, 80);
39
+ if (sourceTitle !== rubric.title) return { status: 'not-eligible', reason: 'rubric candidate title does not match funnel source', decision };
40
+ if (!sourceRubric || rubric.score !== rubricScore(sourceRubric) || rubric.grade !== rubricGrade(rubricScore(sourceRubric)))
41
+ return { status: 'not-eligible', reason: 'rubric score or grade does not match funnel source', decision };
42
+
43
+ let proposal;
44
+ try { proposal = input.consensus.show(input.consensusProposalId); }
45
+ catch (error) {
46
+ if (error instanceof Error && error.message === `consensus proposal not found: ${input.consensusProposalId}`)
47
+ return { status: 'awaiting-consensus', consensusProposalId: input.consensusProposalId, decision };
48
+ throw error;
49
+ }
50
+ if (proposal.category !== 'period-budget' || proposal.factId !== decision.candidate.id
51
+ || proposal.title !== rubric.title || proposal.thresholds.length > 0 || proposal.status !== 'agreed')
52
+ return { status: 'awaiting-consensus', consensusProposalId: input.consensusProposalId, decision };
53
+ const agreement = proposal.reviews.find((review) => review.verdict === 'agree' && review.by !== proposal.proposedBy);
54
+ if (!agreement) return { status: 'awaiting-consensus', consensusProposalId: input.consensusProposalId, decision };
55
+
56
+ const candidate = decision.candidate;
57
+ if (candidate.priority !== 'P1' && candidate.priority !== 'P2')
58
+ return { status: 'not-eligible', reason: 'funnel candidate priority is missing or unsupported', decision };
59
+ if (!candidate.owner) return { status: 'not-eligible', reason: 'funnel candidate owner is missing', decision };
60
+ let placement: PlacementDecision;
61
+ try {
62
+ // The funnel checks urgency/capacity eligibility; this second dry run applies the rubric's deferral grade.
63
+ placement = placeCell({
64
+ id: candidate.id,
65
+ title: candidate.text,
66
+ owner: candidate.owner,
67
+ priority: candidate.priority,
68
+ predecessors: [],
69
+ grade: rubric.grade,
70
+ ...(candidate.deadlineVersion ? { deadlineVersion: candidate.deadlineVersion } : {}),
71
+ }, { ...input.placement, dryRun: true });
72
+ } catch (error) {
73
+ return { status: 'not-eligible', reason: error instanceof Error ? error.message : String(error), decision };
74
+ }
75
+
76
+ return {
77
+ status: 'planned',
78
+ consensus: { id: proposal.id, status: 'agreed', proposedBy: proposal.proposedBy, agreedBy: agreement.by },
79
+ decision,
80
+ rubric: { score: rubric.score, grade: rubric.grade },
81
+ placement,
82
+ };
83
+ }