elanous 0.2.34 → 0.2.35

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 (611) 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/{L04y73dlwKeTW-GetaTF3 → T1mBQqmkwKDLGtyisDCOd}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{5014f970-22bef0b5210f7d60.js → 0368f25d-ad84af92fefee68f.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1165.bad13fc9151a7288.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/13.02a07436dec15f89.js +32 -0
  7. package/apps/pwa/out/_next/static/chunks/{2124.ed5bf480cea7f85b.js → 1530.0e612369b6fd7ea0.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +41 -0
  9. package/apps/pwa/out/_next/static/chunks/1674.2a65fd5668e1cc5f.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +24 -0
  11. package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +74 -0
  12. package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1993-c0007b7ad0c0ef41.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1c735de4.f993a30bbd3c57c4.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{8368.014caa8de2f5af34.js → 2018.a741297bce759490.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +148 -0
  23. package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2625.5d870aa999f33db1.js +34 -0
  25. package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +77 -0
  26. package/apps/pwa/out/_next/static/chunks/2833-0fe47af99ed13c29.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +62 -0
  29. package/apps/pwa/out/_next/static/chunks/3103.0df8da390948bb84.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +90 -0
  31. package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{1644.35dd25240ae24e4b.js → 3408.21d1570602f4b6c0.js} +2 -2
  33. package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/{3121.779fafe3e44612c5.js → 3589.5444a06bcf6e775c.js} +1 -1
  35. package/apps/pwa/out/_next/static/chunks/359-2250789a2d3499e7.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +36 -0
  37. package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{9131-fce7256c4180c4a5.js → 3677-4215f826f6aa68e5.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +79 -0
  40. package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3f7c4ee5.3dde54f01a816613.js +122 -0
  42. package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4346.8601952e73bf5803.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/{6053-d893974de92e6198.js → 4441-875b97f5821ed58a.js} +1 -1
  45. package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +286 -0
  46. package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +24 -0
  49. package/apps/pwa/out/_next/static/chunks/{1895-60ed0e341c658bd4.js → 4705-194e64e47ca0fbdb.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/{5576-82d3703636d5c4b9.js → 4718-17d2af636796a330.js} +3 -3
  51. package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/{7431.3051e9b8a4372d2d.js → 5101.e32282718f99ed6f.js} +2 -2
  57. package/apps/pwa/out/_next/static/chunks/5154.a118f3957ed14e36.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +23 -0
  61. package/apps/pwa/out/_next/static/chunks/{2987-30cf9c2eb7b8bdd5.js → 5483-dd5d7697f6bdb106.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5637.281e5dec4ea6ecf1.js +94 -0
  63. package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/56d372f2.681ab4ec4c998fae.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/{7386.5d8e7e42e818dfb6.js → 5852.db1f7449f4f74612.js} +2 -2
  67. package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/{3110.0a7065f25c841818.js → 6236.e18cced2d5ba6afb.js} +3 -3
  74. package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +8 -0
  75. package/apps/pwa/out/_next/static/chunks/630.fe5a46428d63b013.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +27 -0
  78. package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +93 -0
  80. package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6866-79aa5b4e47cac6aa.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6b89c8bd.24df687a820500b3.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +149 -0
  87. package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +104 -0
  88. package/apps/pwa/out/_next/static/chunks/{7005.1623d2aea78eb85f.js → 7385.50a308a477bdfc21.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/{6086.913a69e6fa3e4a8b.js → 7644.17e37ba6f1d4226e.js} +4 -4
  90. package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/8219.baa715d1deee80e2.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/8256.e3ac8421a71f82f4.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/{7193-cf355cca5ba6c5d5.js → 8437-8d5492094b166cfa.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/{2554.3b5e200f5f5cfcd6.js → 8444.4c26b379ca2b9596.js} +4 -4
  100. package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +226 -0
  101. package/apps/pwa/out/_next/static/chunks/8557-e7898769499cd56f.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +64 -0
  104. package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{2547.dd27303624cb4da8.js → 8637.47f5b35afcae5e6b.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/8714.ff0b7ce3ec3e3ae2.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{9550.d5f76828f972058c.js → 9214.63a510d39178e997.js} +2 -2
  111. package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +115 -0
  112. package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/{8548.036c344973968847.js → 938.66ad1ef0e5abae1c.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/{3414.172ad4ca2d9b08e8.js → 9512.5a76207a730e0491.js} +2 -2
  115. package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/967-2aa39b2d04b4c690.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/{6740.43de73fc427c9fe2.js → 9952.5daf5f94063a2b3e.js} +1 -1
  120. package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-406b47745b53f269.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/{page-d7bff0f0905a662c.js → page-26e6c18a1a750cf6.js} +1 -1
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-47c5d4db587266bd.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1f5a60f70cb4dd0c.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-bac7dee94e5eae4a.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/{page-df3445b207ceceab.js → page-dc0a532f5b9196ec.js} +1 -1
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{9a8cb466.cc9fc9e6e46038aa.js → b2f6ba4d.fb56fdbbf798df33.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/b6705a4f-b9a9047de9eecfd0.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/{4fa33ebd.21c1bd5b294496e6.js → cbe38a15.5a032598e39970c6.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{abb4b98b.163e0f56e84ae35d.js → d06f9160.a3d9062f95de8ad7.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/{9b48c871.204d5d13e7809bd0.js → da5176c6.6773b6c5994e1d99.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.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/bin/elanous.mjs +3 -2
  278. package/catalog/providers/opengateway.yaml +25 -0
  279. package/docs/goal-context/01-goal-authoring-checks.md +8 -0
  280. package/docs/goal-context/03-verification-menu.md +24 -0
  281. package/docs/goal-context/04-mock-scenarios.md +100 -0
  282. package/docs/goal-context/README.md +4 -0
  283. package/graphs/catalog/catalog.yaml +1 -1
  284. package/graphs/default-loop.yaml +57 -3
  285. package/graphs/document-loop.yaml +51 -3
  286. package/graphs/implement-loop.yaml +53 -4
  287. package/graphs/journey/ta-journey.yaml +11 -1
  288. package/graphs/journey/units/author-dialogue/author-dialogue.yaml +42 -0
  289. package/graphs/journey/units/author-dialogue/observe.ts +96 -0
  290. package/graphs/journey/units/author-dialogue/recipes.yaml +10 -0
  291. package/graphs/operate-loop.yaml +51 -3
  292. package/graphs/research-loop.yaml +137 -3
  293. package/graphs/test-diet/test-diet.yaml +3 -0
  294. package/package.json +1 -1
  295. package/scripts/coord-role-pack.ts +19 -6
  296. package/scripts/hq/standby-snapshot.ts +17 -12
  297. package/scripts/release-loop/docs-land-node.ts +21 -5
  298. package/scripts/release-loop/gate-baseline-receipt.ts +155 -0
  299. package/scripts/release-loop/gate-node.ts +181 -22
  300. package/scripts/release-loop/gate-partial.ts +65 -11
  301. package/scripts/release-loop/gate-radius-live.ts +177 -0
  302. package/scripts/release-loop/gate-radius-shadow.ts +1 -1
  303. package/scripts/release-loop/node-verdict.ts +12 -1
  304. package/scripts/release-loop/npm-publish-node.ts +66 -12
  305. package/scripts/release-loop/probe-pod-host-dirs-live.ts +5 -0
  306. package/scripts/release-loop/pwa-remote.ts +166 -0
  307. package/scripts/release-loop/pwa-scenarios-node.ts +19 -3
  308. package/scripts/release-loop/resume-release.ts +41 -4
  309. package/scripts/release-loop/unattended-release.ts +2 -0
  310. package/scripts/test-diet/lib.ts +6 -1
  311. package/scripts/test-diet/node.ts +194 -13
  312. package/scripts/ux-sim.ts +39 -0
  313. package/src/agent/self-ambient-cache.ts +8 -0
  314. package/src/agent-substrate/acp-reviewer.ts +39 -4
  315. package/src/agent-substrate/pr-reviewer.ts +17 -0
  316. package/src/agent-substrate/self-review-cli.ts +62 -13
  317. package/src/autopilot/pr-manager.ts +215 -36
  318. package/src/budget/run-usage-rollup.ts +1 -0
  319. package/src/chat/index.ts +0 -2
  320. package/src/chat/pickers/modal-runtime.ts +10 -27
  321. package/src/cli/agent-cli.ts +13 -2
  322. package/src/cli/doctor-cli.ts +4 -1
  323. package/src/cli/light-entry-route.ts +46 -6
  324. package/src/cli/pod-cli.ts +77 -3
  325. package/src/cli/pr-cli.ts +5 -2
  326. package/src/cli/pr-land-pod-shadow-job.ts +3 -0
  327. package/src/cli/release-checklist-read-cli.ts +79 -0
  328. package/src/cli/release-cli.ts +72 -102
  329. package/src/cli/remote-resolve.ts +1 -1
  330. package/src/cli/root-tui-entry.ts +48 -0
  331. package/src/cli/sim-cli.ts +22 -0
  332. package/src/cli/tasks-cli.ts +540 -31
  333. package/src/cli/usage-cli.ts +13 -11
  334. package/src/clipboard/history.ts +179 -13
  335. package/src/config.ts +8 -1
  336. package/src/dashboard/chat/acp-chat.ts +8 -0
  337. package/src/dashboard/index.ts +78 -10
  338. package/src/dashboard/render/theme-resolver.ts +33 -4
  339. package/src/domains/schedule-registry.ts +16 -2
  340. package/src/git-fs/idle-refresh.ts +76 -0
  341. package/src/git-fs/index.ts +18 -7
  342. package/src/git-fs/worktree.ts +42 -4
  343. package/src/graph-kinds/registry.ts +2 -2
  344. package/src/graph-runner/runner.ts +153 -10
  345. package/src/grok/credential.ts +10 -3
  346. package/src/harness/harness-cli-command.ts +112 -28
  347. package/src/harness/harness-incidents.ts +33 -0
  348. package/src/harness/launch-utterance-ledger.ts +208 -0
  349. package/src/impl-discipline/detector.ts +16 -4
  350. package/src/impl-discipline/system-prompt.ts +11 -0
  351. package/src/impl-discipline/types.ts +2 -2
  352. package/src/index.ts +496 -143
  353. package/src/intake-plane/already-built-hint.ts +4 -2
  354. package/src/intake-plane/requirement-funnel.ts +29 -1
  355. package/src/light-cli.ts +27 -11
  356. package/src/llm/opengateway-models.ts +11 -0
  357. package/src/llm/provider-credentials.ts +14 -0
  358. package/src/llm/provider-detect.ts +8 -1
  359. package/src/llm/runtime-model-family.ts +2 -1
  360. package/src/llm.ts +213 -56
  361. package/src/model-tier/llm-tier-map.ts +15 -1
  362. package/src/native-tool-catalog.ts +15 -1
  363. package/src/nexus/api/loop-resources.ts +13 -1
  364. package/src/oauth/codex.ts +7 -0
  365. package/src/ops/overview-collect.ts +18 -3
  366. package/src/ops/overview.ts +20 -7
  367. package/src/pr-tool/census.ts +261 -27
  368. package/src/pty-shell/pty-manifest.ts +7 -0
  369. package/src/release-loop/checklist.ts +24 -0
  370. package/src/release-loop/landed-but-yellow.ts +129 -5
  371. package/src/release-loop/light-rc.ts +1 -0
  372. package/src/release-loop/rehearsal.ts +2 -2
  373. package/src/repl/index.ts +174 -17
  374. package/src/repl/ops-msg-bridge.ts +32 -0
  375. package/src/self-dev/ask-launch-flow.ts +44 -5
  376. package/src/self-dev/cli-help-text.ts +17 -0
  377. package/src/self-dev/dev-cli.ts +11 -9
  378. package/src/self-dev/draft-residue.ts +37 -1
  379. package/src/self-dev/draft-sweep.ts +137 -11
  380. package/src/self-dev/draft-triage-rules.ts +107 -0
  381. package/src/self-dev/fleet-reduce.ts +3 -2
  382. package/src/self-dev/graph-front-nodes.ts +112 -0
  383. package/src/self-dev/graph-journey-nodes.ts +1 -0
  384. package/src/self-dev/harness-run-cli.ts +3 -15
  385. package/src/self-dev/orchestrate-cli-text.ts +10 -0
  386. package/src/self-dev/review-provider-fallback.ts +35 -1
  387. package/src/self-dev/self-orchestrate-runtime.ts +1 -11
  388. package/src/self-dev/shard-aggregate.ts +42 -5
  389. package/src/self-dev/shard-run.ts +8 -1
  390. package/src/self-implement/blocked-draft-policy.ts +20 -0
  391. package/src/self-implement/classify-shadow.ts +3 -7
  392. package/src/self-implement/doctor-visit.ts +18 -1
  393. package/src/self-implement/gate-baseline.ts +56 -17
  394. package/src/self-implement/gate-cli.ts +1 -0
  395. package/src/self-implement/gate-remote.ts +31 -20
  396. package/src/self-implement/goal-author-decompose.ts +275 -47
  397. package/src/self-implement/goal-author.ts +250 -0
  398. package/src/self-implement/goal-elaborate.ts +295 -0
  399. package/src/self-implement/goal-refine.ts +270 -0
  400. package/src/self-implement/graph-overlay-yaml.ts +14 -3
  401. package/src/self-implement/orchestrator.ts +152 -45
  402. package/src/self-implement/rework-budget-judgment.ts +5 -8
  403. package/src/self-implement/run-stop.ts +10 -1
  404. package/src/self-implement/running-runs.ts +29 -1
  405. package/src/self-implement/scope-adjacency.ts +113 -0
  406. package/src/self-implement/seams.ts +127 -24
  407. package/src/self-implement/stop-autoheal.ts +87 -1
  408. package/src/session-runtime/index.ts +1 -1
  409. package/src/setup/llm-env-detect.ts +5 -0
  410. package/src/skills/tools/agent.ts +140 -14
  411. package/src/skills/tools/msg-ask.ts +100 -0
  412. package/src/skills/tools/ops-ledger.ts +2 -1
  413. package/src/steward/hold-hygiene.ts +24 -6
  414. package/src/steward/triage-budget.ts +194 -0
  415. package/src/steward/triage.ts +20 -3
  416. package/src/task-agent/actions.ts +69 -1
  417. package/src/task-agent/green-sweep.ts +4 -0
  418. package/src/task-agent/live-moves.ts +160 -4
  419. package/src/task-agent/parent-host.ts +123 -3
  420. package/src/task-agent/shadow.ts +7 -1
  421. package/src/task-agent/task-hand.ts +54 -41
  422. package/src/task-agent/tier-split.ts +127 -0
  423. package/src/task-agent/work-order-build.ts +2 -0
  424. package/src/task-agent/work-order.ts +3 -2
  425. package/src/task-orchestrator/generator-prompt.ts +60 -11
  426. package/src/task-orchestrator/surfaces/pod-account-broker.ts +33 -0
  427. package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
  428. package/src/task-orchestrator/surfaces/pod-command-job.ts +45 -7
  429. package/src/task-orchestrator/surfaces/pod-image-source.ts +89 -1
  430. package/src/task-orchestrator/surfaces/pod-lease.ts +17 -8
  431. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +8 -2
  432. package/src/task-orchestrator/surfaces/pod-provenance.ts +76 -0
  433. package/src/task-orchestrator/surfaces/pod-source-receive.ts +18 -0
  434. package/src/task-orchestrator/surfaces/pod-warm-provenance.ts +81 -0
  435. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +6 -2
  436. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +3 -0
  437. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +37 -5
  438. package/src/task-orchestrator/surfaces/self-implement-pod.ts +368 -36
  439. package/src/task-orchestrator/surfaces/self-implement.ts +23 -0
  440. package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
  441. package/src/tui/README.md +2 -0
  442. package/src/tui/chat/background-job-status.ts +54 -0
  443. package/src/tui/chat/log-view.ts +80 -0
  444. package/src/tui/entry.ts +406 -0
  445. package/src/tui/input/composer.ts +144 -0
  446. package/src/tui/seat-mail-boot.ts +59 -0
  447. package/src/tui/slash/compact.ts +100 -0
  448. package/src/tui/slash/new-session.ts +35 -0
  449. package/src/tui-client/local-chat-turn.ts +239 -0
  450. package/src/tui-client/local-harness-command.ts +63 -0
  451. package/src/tui-client/local-provider-command.ts +184 -0
  452. package/src/user-config.ts +4 -2
  453. package/src/ux-sim/event-monkey.ts +378 -0
  454. package/src/ux-sim/fake-bin.ts +42 -7
  455. package/src/ux-sim/fault-nextmove-dispatch.ts +266 -0
  456. package/src/ux-sim/fault-pod-codex-503.ts +211 -0
  457. package/src/ux-sim/fault-scope-escape-lift.ts +189 -0
  458. package/src/version/packed-revision.json +1 -1
  459. package/apps/pwa/out/_next/static/chunks/1162.c69abda138c7ce43.js +0 -79
  460. package/apps/pwa/out/_next/static/chunks/1449-1fede62af84c3e43.js +0 -1
  461. package/apps/pwa/out/_next/static/chunks/1598-13fc845935e816df.js +0 -1
  462. package/apps/pwa/out/_next/static/chunks/1639.62c5e16fa20d242f.js +0 -94
  463. package/apps/pwa/out/_next/static/chunks/1661-adb8b2babc9aaf8c.js +0 -1
  464. package/apps/pwa/out/_next/static/chunks/2147.107c0fc6146fb15a.js +0 -23
  465. package/apps/pwa/out/_next/static/chunks/2202-ef1c9b000c3074fc.js +0 -1
  466. package/apps/pwa/out/_next/static/chunks/2247.1e326638ee43e672.js +0 -115
  467. package/apps/pwa/out/_next/static/chunks/2268.56e1e3d58180abae.js +0 -8
  468. package/apps/pwa/out/_next/static/chunks/2469-606819c812414021.js +0 -1
  469. package/apps/pwa/out/_next/static/chunks/2593.e53c1620c0bb3599.js +0 -1
  470. package/apps/pwa/out/_next/static/chunks/2690.e96671114222676a.js +0 -1
  471. package/apps/pwa/out/_next/static/chunks/2898-79ee1a5cc0cd9d13.js +0 -1
  472. package/apps/pwa/out/_next/static/chunks/298.26099a9f65e5c8ff.js +0 -1
  473. package/apps/pwa/out/_next/static/chunks/2992.51fc2a7295bd8139.js +0 -1
  474. package/apps/pwa/out/_next/static/chunks/3001-5a52788c813b6113.js +0 -1
  475. package/apps/pwa/out/_next/static/chunks/3014-291245fba9df7b5b.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/3068.ee78201f0251a18d.js +0 -1
  477. package/apps/pwa/out/_next/static/chunks/3083.cd399a17e9365f78.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/3103.84470c8445962f04.js +0 -34
  479. package/apps/pwa/out/_next/static/chunks/3117-e1c474683fd1f824.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/3251-2c17bd5a91f8de2e.js +0 -1
  481. package/apps/pwa/out/_next/static/chunks/326.3fb32322bb2ddf6d.js +0 -1
  482. package/apps/pwa/out/_next/static/chunks/3411-f87314c6c66ebc73.js +0 -1
  483. package/apps/pwa/out/_next/static/chunks/3421-7ff7fbaa156985a7.js +0 -1
  484. package/apps/pwa/out/_next/static/chunks/3498.cf2a15a8a9e5b926.js +0 -226
  485. package/apps/pwa/out/_next/static/chunks/381.f55dc63ea87735e6.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/3819.163d4777f0a597f6.js +0 -32
  487. package/apps/pwa/out/_next/static/chunks/3837.722e053fb9f321ad.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/4129-ab0a6189f1778633.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/4361.93d14ba594b3a035.js +0 -104
  490. package/apps/pwa/out/_next/static/chunks/4364.7a7eb19cceb67d2f.js +0 -286
  491. package/apps/pwa/out/_next/static/chunks/4406.d71f506f7c3ee9d3.js +0 -149
  492. package/apps/pwa/out/_next/static/chunks/4461.2ad1514180ae7e29.js +0 -148
  493. package/apps/pwa/out/_next/static/chunks/4479.bd309cbe0e3842ee.js +0 -64
  494. package/apps/pwa/out/_next/static/chunks/4522-05966f777d66d13b.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/4543-9a3e9812e845de65.js +0 -1
  496. package/apps/pwa/out/_next/static/chunks/4557.f8f1d84a0d90d590.js +0 -74
  497. package/apps/pwa/out/_next/static/chunks/4589-79b11542179ef58c.js +0 -1
  498. package/apps/pwa/out/_next/static/chunks/4633-9f8f9f88ffbb8f5c.js +0 -1
  499. package/apps/pwa/out/_next/static/chunks/4831.23af4d10c0697b5e.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/4983.5951b85724f61f2a.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/5028-f0722e6114c313e7.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/5249.96a848656b582a93.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/5311.16e0ffbfa5468b80.js +0 -62
  504. package/apps/pwa/out/_next/static/chunks/5446.edf141cff9ef647d.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/5489.ec2dd1b5272a19dc.js +0 -24
  506. package/apps/pwa/out/_next/static/chunks/559.df87695df637920c.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/5618-5c88f2f70178c4ad.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/5764.05487bf0b73ddb6b.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/5930.e678826c3f831aab.js +0 -1
  510. package/apps/pwa/out/_next/static/chunks/5dfb57f7.f2e3305326202474.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/6200-cefd6f33f59d765e.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/6314-edeba650ae686ac9.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/6316-bc9a9b74d7842d79.js +0 -1
  514. package/apps/pwa/out/_next/static/chunks/6476-13b9779b73528008.js +0 -1
  515. package/apps/pwa/out/_next/static/chunks/666-04db3ac4c8e3c66f.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/670.682e55106ef915a6.js +0 -77
  517. package/apps/pwa/out/_next/static/chunks/6816.b7ba9d0a1a4a46a7.js +0 -1
  518. package/apps/pwa/out/_next/static/chunks/690-fbbcc777f189af37.js +0 -1
  519. package/apps/pwa/out/_next/static/chunks/6989.0d3d4020e5cb3df6.js +0 -90
  520. package/apps/pwa/out/_next/static/chunks/7217-d17393fe7af78fa6.js +0 -1
  521. package/apps/pwa/out/_next/static/chunks/7232.24edbd938a69c8d0.js +0 -1
  522. package/apps/pwa/out/_next/static/chunks/7295cd1e.b4b557908888eeee.js +0 -1
  523. package/apps/pwa/out/_next/static/chunks/7323.adb02de21991883c.js +0 -1
  524. package/apps/pwa/out/_next/static/chunks/7448.478958ffbbba0ac0.js +0 -1
  525. package/apps/pwa/out/_next/static/chunks/7537.ba2208c5c656b8a3.js +0 -1
  526. package/apps/pwa/out/_next/static/chunks/7562.948255cbc3e79d33.js +0 -41
  527. package/apps/pwa/out/_next/static/chunks/7596-962ae6db6cfc9c83.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/7671.cff51beac212a2ba.js +0 -1
  529. package/apps/pwa/out/_next/static/chunks/7883.3916734ee16d3e58.js +0 -27
  530. package/apps/pwa/out/_next/static/chunks/7952.b192c31b6a0e00cc.js +0 -1
  531. package/apps/pwa/out/_next/static/chunks/801.5b24e81eded22d1b.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/8176.8c9a8613f5a01ac1.js +0 -36
  533. package/apps/pwa/out/_next/static/chunks/819e78a6.fa3dd7f7da19bf61.js +0 -1
  534. package/apps/pwa/out/_next/static/chunks/8220-78978450c3183d8d.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/8221-eb60b5bc692a3361.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/826.e9a26064f474949e.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/8459-a351487a4480f584.js +0 -1
  538. package/apps/pwa/out/_next/static/chunks/8482-75823d513a4ce151.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/8488.8da515248cda3f3a.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/8584.388a1779d9b203af.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/8637.a55e098e61ffefb8.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/8817.61bb7ffbba502ecb.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/9207-8e6a12db30373f32.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/9263-00ae932c62696a86.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/9318.caafc3a130e8769c.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/932.da3fb55951882562.js +0 -93
  547. package/apps/pwa/out/_next/static/chunks/9433.002f8426ac75b6b7.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/9464.dd631a5a14b1d660.js +0 -24
  549. package/apps/pwa/out/_next/static/chunks/9739.8d5f36ac67a3b236.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/9743.beeabb9d5f86abe4.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/9843-a23d3f32dc43f715.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/994-28211077c7c587d5.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-3b4c947f174e33d8.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/app/approvals/page-369d5ce99483f859.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-63c0ed0eb26e5fce.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/app/board/page-62802c6003bc85cc.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ecb41560d4e77be9.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/app/bots/page-7b65ad8130c93e95.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/app/ceo/page-8755477c15a9060c.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/app/chat/page-5725447dd972c471.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/app/consult/page-b979de0591a69375.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/app/control/page-6d0796bf4633751a.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/app/decisions/page-59c31dc0394e67b4.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/app/design-check/page-12dfc95f6cc5c718.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/app/editor/page-25788244e66aa4dd.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/app/exec/page-a2555dc705466322.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/app/field/page-4fb31eb476dcbad3.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/app/healthz/route-3b4c947f174e33d8.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/app/inside/page-578729adbeaa40cb.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/app/intake/page-a1d20fffbec35205.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/app/layout-4a558f94516b8004.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/app/live/page-9e3834705b86145e.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/app/loops/page-cb1c5fe746ea4014.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/app/market/page-9ee320507356582a.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66fd183b74835886.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/app/morning/page-3272a064a01a9927.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/app/not-found-f281b7a7f6ef2529.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/app/observatory/page-d45a65f8b7124fcd.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-e9c1fe684dd19a66.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-b8322932fc6e34de.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-82c66d9af2290575.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/app/outputs/page-63c6752009c97b05.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/app/page-bb33d42ebc358aec.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/app/reflection/page-7e4c9379197d7214.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-38bf1e9a7001732b.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/app/sessions/page-2e5b752012389d56.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-398c0faa173203f7.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/app/settings/page-002f53a965b6445c.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-7f75997f61a26269.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/app/setup/layout-3b4c947f174e33d8.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/app/setup/page-05631753294f23fb.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/app/share/page-edd700fd2cc3d7f8.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/app/showroom/page-105f83ecb4594365.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/app/tasks/page-5823e87d2017f19c.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/app/today/page-b51ca09566c03de7.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/app/trace/page-8aacd5ded5dbac60.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/app/vault/page-bae3365a0b3c6a8e.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9ed52b48ff1aa7fd.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b6f8cad35fe00946.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6d25ceda500d2457.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-b6401a5f2c962fe8.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/ebf6cf5e.0d2f887b040e80fb.js +0 -122
  603. package/apps/pwa/out/_next/static/chunks/f09ec7d7-d29abe23edcbb193.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/ffdc3a04.b9c23c1b28dd4a96.js +0 -1
  605. package/apps/pwa/out/_next/static/chunks/framework-9322cb8a56ac081c.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/main-2fbab294e49a1561.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/main-app-f36729f56621a8f3.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/pages/_app-2a62e450b47c6114.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/pages/_error-5e17f7b445f34d43.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/webpack-b4263e2190ea7adf.js +0 -1
  611. /package/apps/pwa/out/_next/static/{L04y73dlwKeTW-GetaTF3 → T1mBQqmkwKDLGtyisDCOd}/_ssgManifest.js +0 -0
package/src/llm.ts CHANGED
@@ -19,11 +19,13 @@ import {
19
19
  getOpenAIApiKey, OPENAI_MODEL, OPENAI_API_URL,
20
20
  getAnthropicApiKey, ANTHROPIC_MODEL, ANTHROPIC_API_URL,
21
21
  getOpenRouterApiKey, OPENROUTER_API_URL, OPENROUTER_MODEL,
22
+ getOpenGatewayApiKey, OPENGATEWAY_API_URL, OPENGATEWAY_MODEL,
22
23
  getLocalLLMUrl, LOCAL_LLM_MODEL,
23
24
  getGeminiApiKey, GEMINI_MODEL,
24
25
  DEFAULT_PROVIDER,
25
26
  } from './config.js';
26
27
  import { debug, redactSecrets, redactSecretText } from './debug/log.js';
28
+ import { isVerifiedOpenGatewayModel } from './llm/opengateway-models.js';
27
29
  import { llmUsageCostFields } from './budget/llm-cost.js';
28
30
  import { accumulateByokUsage } from './llm/openrouter-byok-cost.js';
29
31
  import { ACTION_PHASE_OPS_TOOLS, isSteeredShellRejection, REPAIR_PHASE_READ_ONLY_OPS_TOOLS } from './llm/tool-loop-steered-rejection.js';
@@ -354,6 +356,8 @@ export interface LLMOpts {
354
356
  onUsage?(usage: LLMUsage): void;
355
357
  /** Optional model role attached to this request's usage observation. */
356
358
  usageRole?: ModelRole;
359
+ /** Optional per-call metering phase; absent calls keep the existing ledger shape. */
360
+ usagePhase?: string;
357
361
  /** Optional streamLLM usage-ledger site override (defaults to "stream-llm"). */
358
362
  usageSite?: string;
359
363
  /**
@@ -1229,8 +1233,10 @@ export async function* parseOpenAISSELines(
1229
1233
  }
1230
1234
  };
1231
1235
  for await (const line of lines as AsyncIterable<string>) {
1232
- if (!line.startsWith('data: ')) continue;
1233
- const data = line.slice(6).trim();
1236
+ // SSE permits both `data: {...}` and `data:{...}`. OpenGateway emits
1237
+ // the latter, so requiring a space silently discarded its whole stream.
1238
+ if (!line.startsWith('data:')) continue;
1239
+ const data = line.slice(5).trim();
1234
1240
  if (data === '[DONE]') continue;
1235
1241
  let parsed: any;
1236
1242
  try { parsed = JSON.parse(data); } catch { continue; }
@@ -1413,6 +1419,7 @@ function retryOptsFor(
1413
1419
 
1414
1420
  function inferOpenAIProviderName(url: string): string {
1415
1421
  if (/^https?:\/\/openrouter\.ai(?::\d+)?(?:\/|$)/i.test(url)) return 'openrouter';
1422
+ if (/^https?:\/\/apis\.opengateway\.ai(?::\d+)?(?:\/|$)/i.test(url)) return 'opengateway';
1416
1423
  if (url.includes('x.ai')) return 'grok';
1417
1424
  if (url.includes('openai.com')) return 'openai';
1418
1425
  if (url.includes('localhost') || url.includes('127.0.0.1')) return 'local';
@@ -4044,6 +4051,14 @@ export const PROVIDERS: Record<string, LLMProvider> = {
4044
4051
  streamChat: (messages, opts = {}) => makeOpenRouterProvider({ provider: 'openrouter' }).streamChat!(messages, opts),
4045
4052
  chat: (messages, opts = {}) => makeOpenRouterProvider({ provider: 'openrouter' }).chat!(messages, opts),
4046
4053
  },
4054
+ // Explicit choice only. A new key never changes the established auto-provider order.
4055
+ opengateway: {
4056
+ name: 'opengateway',
4057
+ get defaultModel() { return OPENGATEWAY_MODEL; },
4058
+ available: () => !!getOpenGatewayApiKey(),
4059
+ streamChat: (messages, opts = {}) => makeOpenGatewayProvider({ provider: 'opengateway' }).streamChat!(messages, opts),
4060
+ chat: (messages, opts = {}) => makeOpenGatewayProvider({ provider: 'opengateway' }).chat!(messages, opts),
4061
+ },
4047
4062
  bedrock: BedrockProvider, // 명시 선택 전용 — 자동 순서·폴백 체인에 «안» 넣는다(src/llm/bedrock-provider.ts)
4048
4063
  };
4049
4064
 
@@ -4231,13 +4246,15 @@ export function decideProviderForConfig(
4231
4246
  return { provider, model: selectedModel, auth: baseUrl || getLocalLLMUrl() ? 'local' : 'none' };
4232
4247
  case 'openrouter':
4233
4248
  return { provider, model: selectedModel, auth: apiKey || getOpenRouterApiKey() ? 'apikey' : 'none' };
4249
+ case 'opengateway':
4250
+ return { provider, model: selectedModel, auth: apiKey || getOpenGatewayApiKey() ? 'apikey' : 'none' };
4234
4251
  case 'bedrock': return { provider, model: selectedModel, auth: authKindForProvider('bedrock', selectedModel) };
4235
4252
  }
4236
4253
  throw new Error(`unknown provider: ${provider as string}`);
4237
4254
  }
4238
4255
 
4239
4256
  function isKnownProviderName(provider: string): provider is ConcreteProviderName {
4240
- return provider === 'grok' || provider === 'openai' || provider === 'openai-codex' || provider === 'anthropic' || provider === 'gemini' || provider === 'local' || provider === 'openrouter' || provider === 'bedrock';
4257
+ return provider === 'grok' || provider === 'openai' || provider === 'openai-codex' || provider === 'anthropic' || provider === 'gemini' || provider === 'local' || provider === 'openrouter' || provider === 'opengateway' || provider === 'bedrock';
4241
4258
  }
4242
4259
 
4243
4260
  function authKindForProvider(provider: string, model: string, apiKey?: string): ProviderDecisionAuth {
@@ -4252,6 +4269,7 @@ function authKindForProvider(provider: string, model: string, apiKey?: string):
4252
4269
  if (provider === 'anthropic') return getAnthropicApiKey() ? 'apikey' : 'none';
4253
4270
  if (provider === 'gemini') return getGeminiApiKey() ? 'apikey' : 'none';
4254
4271
  if (provider === 'openrouter') return getOpenRouterApiKey() ? 'apikey' : 'none';
4272
+ if (provider === 'opengateway') return getOpenGatewayApiKey() ? 'apikey' : 'none';
4255
4273
  if (provider === 'bedrock') return BedrockProvider.available() ? 'apikey' : 'none';
4256
4274
  if (provider === 'openai-codex') {
4257
4275
  try {
@@ -4272,6 +4290,7 @@ function defaultModelForProvider(provider: ConcreteProviderName): string {
4272
4290
  case 'gemini': return GEMINI_MODEL;
4273
4291
  case 'local': return LOCAL_LLM_MODEL;
4274
4292
  case 'openrouter': return OPENROUTER_MODEL;
4293
+ case 'opengateway': return OPENGATEWAY_MODEL;
4275
4294
  case 'bedrock': return BedrockProvider.defaultModel;
4276
4295
  }
4277
4296
  throw new Error(`unknown provider: ${provider as string}`);
@@ -4837,7 +4856,7 @@ export async function streamLLM(
4837
4856
  if (consumed.ok) {
4838
4857
  if (consumed.usage !== 'unmeasured') {
4839
4858
  try {
4840
- logAgentTurnUsage(activeModel, consumed.usage, { providerName: activeProvider.name, site: opts.usageSite ?? 'stream-llm', role: opts.usageRole });
4859
+ logAgentTurnUsage(activeModel, consumed.usage, { providerName: activeProvider.name, site: opts.usageSite ?? 'stream-llm', role: opts.usageRole, phase: opts.usagePhase });
4841
4860
  } catch { /* best-effort observation */ }
4842
4861
  }
4843
4862
  debug.log('llm', 'outcome', { provider: activeProvider.name, status: 'ok', kind: 'streamLLM', durationMs: Date.now() - started });
@@ -8069,15 +8088,17 @@ export function billingRouteForProvider(provider: string | undefined, model: str
8069
8088
  }
8070
8089
 
8071
8090
  /** Observe usage with optional site/role metadata; a provider-name string remains supported. */
8072
- export function logAgentTurnUsage(model: string, usage: LLMUsage, providerNameOrOptions?: string | { providerName?: string; site?: string; role?: ModelRole }): void {
8091
+ export function logAgentTurnUsage(model: string, usage: LLMUsage, providerNameOrOptions?: string | { providerName?: string; site?: string; role?: ModelRole; phase?: string }): void {
8073
8092
  try {
8074
8093
  const providerName = typeof providerNameOrOptions === 'string' ? providerNameOrOptions : providerNameOrOptions?.providerName;
8075
8094
  const site = (typeof providerNameOrOptions === 'string' ? undefined : providerNameOrOptions?.site) ?? 'agent-turn';
8076
8095
  const role = typeof providerNameOrOptions === 'string' ? undefined : providerNameOrOptions?.role;
8096
+ const phase = typeof providerNameOrOptions === 'string' ? undefined : providerNameOrOptions?.phase;
8077
8097
  const billing = billingRouteForProvider(providerName, model);
8078
8098
  debug.log('llm.usage', 'llm-usage', {
8079
8099
  site,
8080
8100
  ...(role !== undefined ? { role } : {}),
8101
+ ...(phase !== undefined ? { phase } : {}),
8081
8102
  model,
8082
8103
  ...(usage.provider !== undefined && { provider: usage.provider }),
8083
8104
  // ⭐ `provider` 는 «선 어댑터»(openai/anthropic)다 — 과금 주체는 별칭 칸으로(BACKLOG B10).
@@ -8126,6 +8147,84 @@ export function attachFinalAnswerSupplement(
8126
8147
  return base + '\n\n' + supplement.trim();
8127
8148
  }
8128
8149
 
8150
+ export const GPT6_CODEX_GUARD_IDS = [
8151
+ 'anchor-grep',
8152
+ 'anchor-read',
8153
+ 'literal-glob',
8154
+ 'search-only-streak',
8155
+ 'post-read-broad-search',
8156
+ 'same-args-dedup',
8157
+ 'broad-spot-repeat',
8158
+ 'exploration-budget',
8159
+ 'inspect-budget',
8160
+ 'followup-hard-stop',
8161
+ 'max-turns',
8162
+ 'force-synthesis',
8163
+ ] as const;
8164
+ export type Gpt6CodexGuardId = typeof GPT6_CODEX_GUARD_IDS[number];
8165
+ export type Gpt6CodexGuardStats = Record<Gpt6CodexGuardId, { wouldBlock: number; blocked: number }>;
8166
+
8167
+ type Gpt6CodexGuardFlags = Record<Gpt6CodexGuardId, boolean>;
8168
+ const GPT6_CODEX_GUARD_DEFAULTS: Gpt6CodexGuardFlags = Object.fromEntries(
8169
+ GPT6_CODEX_GUARD_IDS.map((id) => [id, false]),
8170
+ ) as Gpt6CodexGuardFlags;
8171
+ let gpt6CodexGuardOverrides: Partial<Gpt6CodexGuardFlags> = {};
8172
+ const gpt6CodexGuardStats: Gpt6CodexGuardStats = Object.fromEntries(
8173
+ GPT6_CODEX_GUARD_IDS.map((id) => [id, { wouldBlock: 0, blocked: 0 }]),
8174
+ ) as Gpt6CodexGuardStats;
8175
+
8176
+ export function getGpt6CodexGuardFlags(): Gpt6CodexGuardFlags {
8177
+ return { ...GPT6_CODEX_GUARD_DEFAULTS, ...gpt6CodexGuardOverrides };
8178
+ }
8179
+
8180
+ export function getGpt6CodexGuardStats(): Gpt6CodexGuardStats {
8181
+ return Object.fromEntries(
8182
+ GPT6_CODEX_GUARD_IDS.map((id) => [id, { ...gpt6CodexGuardStats[id] }]),
8183
+ ) as Gpt6CodexGuardStats;
8184
+ }
8185
+
8186
+ export function resetGpt6CodexGuardObservations(): void {
8187
+ for (const id of GPT6_CODEX_GUARD_IDS) {
8188
+ gpt6CodexGuardStats[id].wouldBlock = 0;
8189
+ gpt6CodexGuardStats[id].blocked = 0;
8190
+ }
8191
+ }
8192
+
8193
+ /** @internal Test seam for the staged GPT-6 guard rollout. */
8194
+ export function _setGpt6CodexGuardFlagsForTest(flags: Partial<Gpt6CodexGuardFlags> | undefined): void {
8195
+ gpt6CodexGuardOverrides = flags ? { ...flags } : {};
8196
+ }
8197
+
8198
+ // Counter semantics (GPT-6 models only): `wouldBlock` = the guard predicate held;
8199
+ // `blocked` = the guard actually stopped/rejected. Grace burns and arming are NOT blocks.
8200
+ // `force-synthesis` is an intervention, not a rejection: blocked = the no-tools pass was
8201
+ // attempted; its met/unmet outcome is told apart only by events (`force-synthesis-pass.emitted`
8202
+ // vs `synthesis-ignored.hard-stop`).
8203
+ // ⚠️ Scope: the tally is module-level (process-global) — concurrent streams in one process
8204
+ // add into the same counters; there is no per-stream / per-run split.
8205
+ function gpt6CodexGuardEnabled(id: Gpt6CodexGuardId, model: string, legacyEnabled = false): boolean {
8206
+ // Rollout flags may add guards, but cannot disable behavior already active.
8207
+ return !isGpt6GenerationModel(model) || legacyEnabled || getGpt6CodexGuardFlags()[id];
8208
+ }
8209
+
8210
+ function noteGpt6CodexGuard(id: Gpt6CodexGuardId, model: string, blocked: boolean): void {
8211
+ if (!isGpt6GenerationModel(model)) return;
8212
+ gpt6CodexGuardStats[id].wouldBlock++;
8213
+ if (blocked) gpt6CodexGuardStats[id].blocked++;
8214
+ }
8215
+
8216
+ function applyCodexBehaviorGuard(
8217
+ id: Gpt6CodexGuardId,
8218
+ model: string,
8219
+ wouldBlock: boolean,
8220
+ legacyEnabled = false,
8221
+ ): boolean {
8222
+ if (!wouldBlock) return false;
8223
+ const enabled = gpt6CodexGuardEnabled(id, model, legacyEnabled);
8224
+ noteGpt6CodexGuard(id, model, enabled);
8225
+ return enabled;
8226
+ }
8227
+
8129
8228
  export async function streamLLMWithTools(
8130
8229
  messages: LLMMessage[],
8131
8230
  handlers: StreamWithToolsHandlers,
@@ -8141,14 +8240,14 @@ export async function streamLLMWithTools(
8141
8240
  let blockedProviders: ProviderFallbackAttempt[] = [];
8142
8241
  const effectiveModel = activeModel;
8143
8242
  const modelFamily = getModelFamily(effectiveModel);
8144
- // TUI-GPT6-GUARD-PARITY — codex «모델 행동» 가드 켬 여부(단일 원천 = models/prompts.ts
8145
- // usesCodexBehaviorGuards). gpt-6 세대도 true. 넓힌 자리·안 넓힌 자리는 그 함수 주석이 정본.
8243
+ // Preserve pre-existing GPT-6 behavior while observing Codex-only sites.
8146
8244
  const codexBehaviorGuards = usesCodexBehaviorGuards(effectiveModel);
8245
+ const codexGuardCandidate = codexBehaviorGuards || isGpt6GenerationModel(effectiveModel);
8147
8246
  debug.log('llm.router', 'streamLLMWithTools', {
8148
8247
  provider: provider.name,
8149
8248
  model: effectiveModel,
8150
8249
  modelFamily,
8151
- codexBehaviorGuards,
8250
+ codexBehaviorGuards: codexGuardCandidate,
8152
8251
  messageCount: messages.length,
8153
8252
  messageRoles: summarizeRoles(messages),
8154
8253
  tools: opts.tools?.map(t => t.name),
@@ -8872,7 +8971,7 @@ export async function streamLLMWithTools(
8872
8971
  // ⭐ 주 에이전트 턴의 토큰·비용을 «게이트 없이» 남긴다(2026-09-24 실측: 이 줄이 없어 3시간 `llm.usage`
8873
8972
  // 18행이 전부 곁가지 두 자리였고, 하니스 런 비용의 거의 전부가 관측 밖이었다). 곁가지와 같은 모양 ·
8874
8973
  // 모르는 모델은 금액 대신 `cost.kind='unknown'`. runId 는 debug.log 가 붙인다. 실패해도 턴은 계속.
8875
- logAgentTurnUsage(activeModel, ev.usage, { providerName: activeProvider.name, role: opts.usageRole });
8974
+ logAgentTurnUsage(activeModel, ev.usage, { providerName: activeProvider.name, role: opts.usageRole, phase: opts.usagePhase });
8876
8975
  // Wave A1 (2026-05-04) — turn-level cache hit rate forensic.
8877
8976
  // Each provider's usage event carries inputTokens / outputTokens
8878
8977
  // / cacheReadInputTokens (when cache hit). Emit the per-turn
@@ -9087,19 +9186,27 @@ export async function streamLLMWithTools(
9087
9186
  // the notice in a tool_result but keeps making tool calls until
9088
9187
  // maxTurns hard-stops it, producing 0 chars of output. Hard
9089
9188
  // rejection forces the synthesis that soft pressure couldn't.
9090
- const inSynthesisPhase =
9189
+ const inSynthesisPhase = applyCodexBehaviorGuard(
9190
+ 'max-turns',
9191
+ effectiveModel,
9091
9192
  !terminalOnlyTurn
9092
- && maxTurns >= BUDGET_WARNING_MIN_TURNS
9093
- && turn >= maxTurns - FINAL_SYNTHESIS_TURNS;
9094
- const codexInspectionStillProgressing =
9095
- modelFamily === 'codex'
9193
+ && maxTurns >= BUDGET_WARNING_MIN_TURNS
9194
+ && turn >= maxTurns - FINAL_SYNTHESIS_TURNS,
9195
+ true,
9196
+ );
9197
+ const codexInspectionStillProgressing = codexGuardCandidate
9198
+ && (modelFamily === 'codex' || getGpt6CodexGuardFlags()['inspect-budget'])
9096
9199
  && autoNarrowedReadCount > 0
9097
9200
  && autoNarrowedReadCount < inspectBudgetThreshold;
9098
- const inExplorationSynthesisPhase =
9201
+ const inExplorationSynthesisPhase = applyCodexBehaviorGuard(
9202
+ 'exploration-budget',
9203
+ effectiveModel,
9099
9204
  !terminalOnlyTurn
9100
- && exploratoryTurnStreak >= explorationThresholdForTurn
9101
- && isExploratoryTurn(pendingCalls)
9102
- && !codexInspectionStillProgressing;
9205
+ && exploratoryTurnStreak >= explorationThresholdForTurn
9206
+ && isExploratoryTurn(pendingCalls)
9207
+ && !codexInspectionStillProgressing,
9208
+ true,
9209
+ );
9103
9210
  const inInspectSynthesisPhase =
9104
9211
  !terminalOnlyTurn
9105
9212
  && inspectSynthesisArmed
@@ -9232,8 +9339,19 @@ export async function streamLLMWithTools(
9232
9339
  // as in the original PR #768 design. Forensic events at both the
9233
9340
  // grace-burn and the hard-stop branches so log/latest can audit
9234
9341
  // exactly which path each turn took.
9235
- const codexImmediateInspectStop = inInspectSynthesisPhase && modelFamily === 'codex';
9236
- const codexImmediateRepairStop = inRepairActionPhase && modelFamily === 'codex';
9342
+ // followup-hard-stop counting happens once per turn below the grace branches:
9343
+ // wouldBlock when any predicate held, blocked only when a grace=0 immediate stop fired.
9344
+ const followupHardStopEnabled = codexGuardCandidate
9345
+ && gpt6CodexGuardEnabled('followup-hard-stop', effectiveModel);
9346
+ const followupInspectActionHeld =
9347
+ inInspectActionPhase
9348
+ && !verifyActionArmed
9349
+ && editedFilePaths.length === 0
9350
+ && !executionLoopState.lastCommand;
9351
+ const followupHardStopHeld = codexGuardCandidate
9352
+ && (inInspectSynthesisPhase || inRepairActionPhase || followupInspectActionHeld);
9353
+ const codexImmediateInspectStop = inInspectSynthesisPhase && followupHardStopEnabled;
9354
+ const codexImmediateRepairStop = inRepairActionPhase && followupHardStopEnabled;
9237
9355
  // codexImmediateInspectActionStop predicate (PR #768 original):
9238
9356
  // restricted to pure-exploration state (no edits applied AND no
9239
9357
  // execution attempted). When edits/execution already happened the
@@ -9241,12 +9359,13 @@ export async function streamLLMWithTools(
9241
9359
  // logic (`buildFinalizationPolicySnapshot` → `[FINAL ANSWER
9242
9360
  // REQUIRED]`) can run — that branch produces a tailored "verify
9243
9361
  // done, just write the answer" UX which we must not preempt.
9244
- const codexImmediateInspectActionStop =
9245
- inInspectActionPhase
9246
- && modelFamily === 'codex'
9247
- && !verifyActionArmed
9248
- && editedFilePaths.length === 0
9249
- && !executionLoopState.lastCommand;
9362
+ const codexImmediateInspectActionStop = followupInspectActionHeld && followupHardStopEnabled;
9363
+ if (followupHardStopHeld) {
9364
+ noteGpt6CodexGuard('followup-hard-stop', effectiveModel,
9365
+ (codexImmediateInspectStop && codexInspectSynthesisGrace <= 0)
9366
+ || (codexImmediateRepairStop && codexRepairActionGrace <= 0)
9367
+ || (codexImmediateInspectActionStop && codexInspectActionGrace <= 0));
9368
+ }
9250
9369
  if (codexImmediateInspectStop && codexInspectSynthesisGrace <= 0) {
9251
9370
  debug.log('llm.router', 'tool-loop.inspect-synthesis-phase.codex-immediate-stop', {
9252
9371
  turn,
@@ -9370,7 +9489,11 @@ export async function streamLLMWithTools(
9370
9489
  inspectRejectionCount++;
9371
9490
  explorationRejectionCount = 0;
9372
9491
  synthesisRejectionCount = 0;
9373
- if (modelFamily === 'codex' || inspectRejectionCount >= 2) {
9492
+ // Already tallied above (followupHardStopHeld) — no second count for the same turn.
9493
+ // When followupHardStopEnabled is true this branch is unreachable for this phase
9494
+ // (codexImmediateInspectStop takes the turn), so a stop here is the generic
9495
+ // second-rejection path, not the GPT-6 guard — it is intentionally not `blocked`.
9496
+ if (followupHardStopEnabled || inspectRejectionCount >= 2) {
9374
9497
  hardStopText = buildIgnoredSynthesisNotice('inspect');
9375
9498
  }
9376
9499
  } else if (inInspectActionPhase) {
@@ -9985,7 +10108,7 @@ export async function streamLLMWithTools(
9985
10108
  debug.log('llm.router', 'tool-loop.dedup-blocked', { turn, tool: call.name, signature: signatureOf(call), priorCount: repeatedError.count, threshold: DEDUP_THRESHOLD, reason: 'repeated-error' });
9986
10109
  return { result: `${buildDedupStub(call, repeatedError.count)} Every one of those calls failed with the same error: ${repeatedError.error.slice(0, 200)}`, isError: false, phaseRejected: false };
9987
10110
  }
9988
- if (codexBehaviorGuards && EXPLORATORY_TOOLS.has(call.name)) {
10111
+ if (codexGuardCandidate && EXPLORATORY_TOOLS.has(call.name)) {
9989
10112
  // W4-anchor — Anchor file Grep blocking. AGENTS.md / CLAUDE.md
9990
10113
  // are already in the system prompt; greppling them is pure
9991
10114
  // token waste and trains codex to ignore the in-prompt copy.
@@ -9993,7 +10116,7 @@ export async function streamLLMWithTools(
9993
10116
  // every attempt gets the redirect. No threshold — anchor
9994
10117
  // grep is structurally redundant.
9995
10118
  const anchor = isAnchorGrep(call);
9996
- if (anchor !== null) {
10119
+ if (anchor !== null && applyCodexBehaviorGuard('anchor-grep', effectiveModel, true, true)) {
9997
10120
  if (debug.enabled) {
9998
10121
  debug.log('llm.router', 'tool-loop.anchor-grep-blocked', {
9999
10122
  turn,
@@ -10042,6 +10165,7 @@ export async function streamLLMWithTools(
10042
10165
  && autoNarrowedReadCount === 0
10043
10166
  && searchOnlyTurnStreak >= 3
10044
10167
  && SEARCH_ONLY_TOOLS.has(call.name)
10168
+ && applyCodexBehaviorGuard('search-only-streak', effectiveModel, true, true)
10045
10169
  ) {
10046
10170
  if (debug.enabled) {
10047
10171
  debug.log('llm.router', 'tool-loop.search-only-streak-blocked', {
@@ -10087,7 +10211,7 @@ export async function streamLLMWithTools(
10087
10211
  }
10088
10212
  return false;
10089
10213
  })();
10090
- if (isBroadPostRead) {
10214
+ if (isBroadPostRead && applyCodexBehaviorGuard('post-read-broad-search', effectiveModel, true, true)) {
10091
10215
  if (debug.enabled) {
10092
10216
  debug.log('llm.router', 'tool-loop.post-read-broad-blocked', {
10093
10217
  turn,
@@ -10122,7 +10246,7 @@ export async function streamLLMWithTools(
10122
10246
  // decided per-call by `anchorStubContext`, which inspects the
10123
10247
  // fences in `messages`. Companion to W4-anchor (Grep).
10124
10248
  const anchorRead = isAnchorRead(call);
10125
- if (anchorRead !== null) {
10249
+ if (anchorRead !== null && applyCodexBehaviorGuard('anchor-read', effectiveModel, true, true)) {
10126
10250
  if (debug.enabled) {
10127
10251
  debug.log('llm.router', 'tool-loop.anchor-read-blocked', {
10128
10252
  turn,
@@ -10150,7 +10274,7 @@ export async function streamLLMWithTools(
10150
10274
  // path is the next step. Block FIRST so the model is steered
10151
10275
  // to Read directly instead of Glob → Read pair.
10152
10276
  const literalPath = literalGlobPath(call);
10153
- if (literalPath !== null) {
10277
+ if (literalPath !== null && applyCodexBehaviorGuard('literal-glob', effectiveModel, true, true)) {
10154
10278
  if (debug.enabled) {
10155
10279
  debug.log('llm.router', 'tool-loop.literal-glob-blocked', {
10156
10280
  turn,
@@ -10179,7 +10303,8 @@ export async function streamLLMWithTools(
10179
10303
  const sig = signatureOf(call);
10180
10304
  const priorCount = seenToolCallSignatures.get(sig) ?? 0;
10181
10305
  seenToolCallSignatures.set(sig, priorCount + 1);
10182
- if (priorCount + 1 >= DEDUP_THRESHOLD) {
10306
+ if (priorCount + 1 >= DEDUP_THRESHOLD
10307
+ && applyCodexBehaviorGuard('same-args-dedup', effectiveModel, true, true)) {
10183
10308
  const stub = buildDedupStub(call, priorCount);
10184
10309
  if (debug.enabled) {
10185
10310
  debug.log('llm.router', 'tool-loop.dedup-blocked', {
@@ -10199,7 +10324,8 @@ export async function streamLLMWithTools(
10199
10324
  if (spotInfo !== null) {
10200
10325
  const priorSpot = seenBroadSpots.get(spotInfo.key) ?? 0;
10201
10326
  seenBroadSpots.set(spotInfo.key, priorSpot + 1);
10202
- if (priorSpot + 1 >= spotInfo.threshold) {
10327
+ if (priorSpot + 1 >= spotInfo.threshold
10328
+ && applyCodexBehaviorGuard('broad-spot-repeat', effectiveModel, true, true)) {
10203
10329
  if (debug.enabled) {
10204
10330
  debug.log('llm.router', 'tool-loop.broad-spot-blocked', {
10205
10331
  turn,
@@ -10324,7 +10450,7 @@ export async function streamLLMWithTools(
10324
10450
  // W4-A — Track Read dispatches (only successful ones; error
10325
10451
  // results don't count as "the file is in your context"). The
10326
10452
  // post-Read broad-search guard above reads this counter.
10327
- if (call.name === 'Read' && !isError && codexBehaviorGuards) {
10453
+ if (call.name === 'Read' && !isError && codexGuardCandidate) {
10328
10454
  dispatchedReadCount++;
10329
10455
  }
10330
10456
  return { result, isError, phaseRejected: false };
@@ -10676,28 +10802,31 @@ export async function streamLLMWithTools(
10676
10802
  && looksLikeStructuralAnalysis(history)
10677
10803
  && autoNarrowedInspections.length >= 2
10678
10804
  && narrowingBlockedCount >= 1;
10679
- if (modelFamily === 'codex' && autoNarrowedReadCount >= inspectBudgetThreshold) {
10805
+ if (codexGuardCandidate
10806
+ && (modelFamily === 'codex' || getGpt6CodexGuardFlags()['inspect-budget'])
10807
+ && autoNarrowedReadCount >= inspectBudgetThreshold) {
10680
10808
  inspectSynthesisArmed = true;
10681
10809
  }
10810
+ const inspectBudgetExecutionHeld = codexGuardCandidate
10811
+ && autoNarrowedThisTurn > 0
10812
+ && autoNarrowedInspections.length > 0
10813
+ && autoNarrowedReadCount >= inspectBudgetThreshold
10814
+ && inspectFollowupMode === 'execution';
10815
+ // Arming is a would-block signal only: it rejects nothing this turn, so blocked stays 0.
10816
+ if (inspectBudgetExecutionHeld) noteGpt6CodexGuard('inspect-budget', effectiveModel, false);
10682
10817
  if (structuralInspectFallbackReady) {
10683
10818
  hardStopText = buildInspectFallbackSummary(autoNarrowedInspections);
10684
10819
  hardStopReason = 'structural-inspect-fallback-ready';
10685
10820
  } else if (
10686
- modelFamily === 'codex'
10687
- && autoNarrowedThisTurn > 0
10821
+ autoNarrowedThisTurn > 0
10688
10822
  && autoNarrowedInspections.length > 0
10689
10823
  && autoNarrowedReadCount >= inspectBudgetThreshold
10690
10824
  && inspectFollowupMode === 'synthesis'
10825
+ && applyCodexBehaviorGuard('inspect-budget', effectiveModel, codexGuardCandidate)
10691
10826
  ) {
10692
10827
  hardStopText = buildInspectFallbackSummary(autoNarrowedInspections);
10693
10828
  hardStopReason = 'codex-inspect-budget-synthesis';
10694
- } else if (
10695
- modelFamily === 'codex'
10696
- && autoNarrowedThisTurn > 0
10697
- && autoNarrowedInspections.length > 0
10698
- && autoNarrowedReadCount >= inspectBudgetThreshold
10699
- && inspectFollowupMode === 'execution'
10700
- ) {
10829
+ } else if (inspectBudgetExecutionHeld && gpt6CodexGuardEnabled('inspect-budget', effectiveModel)) {
10701
10830
  inspectSynthesisArmed = true;
10702
10831
  debug.log('llm.router', 'tool-loop.inspect-synthesis-armed', {
10703
10832
  turn,
@@ -10904,12 +11033,12 @@ export async function streamLLMWithTools(
10904
11033
  // forceSynthesisOutcome="skipped" (was: non-codex-family). Same
10905
11034
  // fix shape (no-tools synthesis with prior tool_results as
10906
11035
  // context) lifts the empty reply to substantive answer.
10907
- const isForceSynthesisFamily =
10908
- codexBehaviorGuards || modelFamily === 'gemini';
11036
+ const isForceSynthesisFamily = codexGuardCandidate || modelFamily === 'gemini';
10909
11037
  const shouldForceSynthesis =
10910
- isForceSynthesisFamily
10911
- && !isUserInterventionRequired
10912
- && !forceSynthesisAttempted;
11038
+ !isUserInterventionRequired
11039
+ && !forceSynthesisAttempted
11040
+ && (modelFamily === 'gemini'
11041
+ || applyCodexBehaviorGuard('force-synthesis', effectiveModel, codexGuardCandidate, true));
10913
11042
  let synthesizedText: string | null = null;
10914
11043
  if (shouldForceSynthesis) {
10915
11044
  forceSynthesisAttempted = true;
@@ -10988,9 +11117,10 @@ export async function streamLLMWithTools(
10988
11117
  // synthesis attempt. Extended to gemini 2026-05-04 alongside
10989
11118
  // W5-E/W5-F for the same pathology shape.
10990
11119
  if (
10991
- (modelFamily === 'codex' || modelFamily === 'gemini')
10992
- && !forceSynthesisAttempted
11120
+ !forceSynthesisAttempted
10993
11121
  && noContentReadTurnStreak >= 4
11122
+ && (modelFamily === 'gemini'
11123
+ || applyCodexBehaviorGuard('force-synthesis', effectiveModel, codexGuardCandidate, true))
10994
11124
  ) {
10995
11125
  forceSynthesisAttempted = true;
10996
11126
  const earlyText = await tryForceSynthesisPass({
@@ -11073,8 +11203,9 @@ export async function streamLLMWithTools(
11073
11203
  let synthesizedText: string | null = null;
11074
11204
  const shouldForceSynthesisOnBudget =
11075
11205
  loopTermination === 'budget-exhausted'
11076
- && (codexBehaviorGuards || modelFamily === 'gemini')
11077
- && !forceSynthesisAttempted;
11206
+ && !forceSynthesisAttempted
11207
+ && (modelFamily === 'gemini'
11208
+ || applyCodexBehaviorGuard('force-synthesis', effectiveModel, codexGuardCandidate, true));
11078
11209
  if (shouldForceSynthesisOnBudget) {
11079
11210
  forceSynthesisAttempted = true;
11080
11211
  synthesizedText = await tryForceSynthesisPass({
@@ -11369,6 +11500,27 @@ function makeOpenRouterProvider(cfg: UCLLMConfig): LLMProvider {
11369
11500
  return inner;
11370
11501
  }
11371
11502
 
11503
+ /** The OpenGateway wire is standard OpenAI Chat Completions with a distinct URL and credential. */
11504
+ function makeOpenGatewayProvider(cfg: UCLLMConfig): LLMProvider {
11505
+ const selectedModel = cfg.model || OPENGATEWAY_MODEL;
11506
+ if (!isVerifiedOpenGatewayModel(selectedModel)) throw new Error(`opengateway model not verified: ${selectedModel}`);
11507
+ const portableKey = getOpenGatewayApiKey();
11508
+ if (cfg.apiKey?.trim() && portableKey && cfg.apiKey.trim() !== portableKey)
11509
+ throw new Error('opengateway config apiKey conflicts with env/cache key');
11510
+ const inner = makeOpenAICompatProvider('opengateway', selectedModel, OPENGATEWAY_API_URL,
11511
+ { ...cfg, reasoningLevel: undefined, apiKey: cfg.apiKey?.trim() || portableKey },
11512
+ { model: (model) => model.startsWith('opengateway/') ? model.slice('opengateway/'.length) : model,
11513
+ omitDefaultTemperature: true, omitMaxTokens: true,
11514
+ extraBody: { stream_options: { include_usage: true } } });
11515
+ return { ...inner, async *streamChat(messages, opts = {}) {
11516
+ if (opts.model && !isVerifiedOpenGatewayModel(opts.model)) throw new Error(`opengateway model not verified: ${opts.model}`);
11517
+ yield* inner.streamChat!(messages, { ...opts, reasoningEffort: undefined });
11518
+ }, async *chat(messages, opts = {}) {
11519
+ if (opts.model && !isVerifiedOpenGatewayModel(opts.model)) throw new Error(`opengateway model not verified: ${opts.model}`);
11520
+ yield* inner.chat!(messages, { ...opts, reasoningEffort: undefined });
11521
+ } };
11522
+ }
11523
+
11372
11524
  /** OR-TOOLARGS-REPAIR — 깨진 도구 인자 호출에 돌려주는 오류 문면(도구는 실행되지 않았다). */
11373
11525
  export function buildInvalidToolArgsMessage(info: ToolArgsInvalid): string {
11374
11526
  const truncated = info.finishReason === 'length';
@@ -11833,7 +11985,7 @@ export function anyProviderAvailable(userConfig?: UserConfig): boolean {
11833
11985
  } catch { return false; }
11834
11986
  }
11835
11987
  } catch { /* fall through to env check */ }
11836
- return Object.values(PROVIDERS).some(p => p.name !== 'bedrock' && p.available()); // bedrock 은 auto 후보가 아니다
11988
+ return Object.values(PROVIDERS).some(p => p.name !== 'bedrock' && p.name !== 'opengateway' && p.available()); // 명시 전용 공급자는 auto 가용성 아님
11837
11989
  }
11838
11990
 
11839
11991
  /** 직결 배선이 없는 계열 → OpenRouter 에서 그 벤더의 대표 모델(사다리 `openrouter` 에 선 것). */
@@ -11890,6 +12042,9 @@ export function getProviderForConfig(
11890
12042
  // Preserve the requesting config for OpenRouter, not the config-free singleton.
11891
12043
  return makeOpenRouterProvider({ provider: 'openrouter', model: decision.model, reasoningLevel: userConfig.llm.reasoningLevel });
11892
12044
  }
12045
+ if (resolvedProviderName === 'opengateway') {
12046
+ return makeOpenGatewayProvider({ provider: 'opengateway', model: decision.model, reasoningLevel: userConfig.llm.reasoningLevel });
12047
+ }
11893
12048
  return PROVIDERS[resolvedProviderName]!;
11894
12049
  }
11895
12050
  if (!isKnownProviderName(resolvedProviderName)) {
@@ -11930,6 +12085,8 @@ export function getProviderForConfig(
11930
12085
  return makeCodexProvider(llm);
11931
12086
  case 'openrouter':
11932
12087
  return makeOpenRouterProvider(userConfig.llm.provider === 'openrouter' ? llm : { provider: 'openrouter', model: decision.model, reasoningLevel: llm.reasoningLevel });
12088
+ case 'opengateway':
12089
+ return makeOpenGatewayProvider(userConfig.llm.provider === 'opengateway' ? llm : { provider: 'opengateway', model: decision.model, reasoningLevel: llm.reasoningLevel });
11933
12090
  case 'anthropic':
11934
12091
  return makeAnthropicProvider(llm);
11935
12092
  case 'bedrock': return makeBedrockProvider(llm);
@@ -11958,7 +12115,7 @@ export function getProviderForConfig(
11958
12115
  // union without a case here fails loud at first call.
11959
12116
  throw new Error(`unknown provider: ${provider as string}`);
11960
12117
  }
11961
- import { getModelFamily, usesCodexBehaviorGuards } from './models/prompts.js';
12118
+ import { getModelFamily, isGpt6GenerationModel, usesCodexBehaviorGuards } from './models/prompts.js';
11962
12119
  import type { ModelFamily } from './models/prompts.js';
11963
12120
 
11964
12121
  // COMPAT(llm-facade-openai-sampling-fields) · 기존 llm.ts 공개 API 유지.
@@ -24,6 +24,7 @@
24
24
  // surfaces tier label + model id + per-turn rationale only.
25
25
 
26
26
  import type { LLMProviderName, ReasoningLevel } from '../user-config.js';
27
+ import { OPENGATEWAY_DEFAULT_MODEL } from '../llm/opengateway-models.js';
27
28
  import type { ModelTier } from './types.js';
28
29
 
29
30
  export interface LlmTierSpec {
@@ -417,6 +418,18 @@ const OPENROUTER: TierMap = {
417
418
  loaded: { model: 'openrouter/moonshotai/kimi-k3', reasoningLevel: 'high', label: 'Kimi K3 · reasoning high (OpenRouter)', rationale: 'Loaded · deep multi-step', status: 'shipping' },
418
419
  };
419
420
 
421
+ // First OpenGateway slice has one measured model. Every explicit tier resolves to the same model
422
+ // until distinct tiers have their own live evidence; no quality or price ordering is implied.
423
+ const OPENGATEWAY_MODEL = OPENGATEWAY_DEFAULT_MODEL;
424
+ // The provider has no effort/thinking control; all five tiers use the verified model without reasoning options.
425
+ const OPENGATEWAY: TierMap = {
426
+ budget: { model: OPENGATEWAY_MODEL, reasoningLevel: 'off', label: 'DeepSeek V4.1 Flash Ultrafast (OpenGateway)', rationale: 'Single verified first-slice model', status: 'shipping' },
427
+ balanced: { model: OPENGATEWAY_MODEL, reasoningLevel: 'off', label: 'DeepSeek V4.1 Flash Ultrafast (OpenGateway)', rationale: 'Single verified first-slice model', status: 'shipping' },
428
+ better: { model: OPENGATEWAY_MODEL, reasoningLevel: 'off', label: 'DeepSeek V4.1 Flash Ultrafast (OpenGateway)', rationale: 'Single verified first-slice model', status: 'shipping' },
429
+ best: { model: OPENGATEWAY_MODEL, reasoningLevel: 'off', label: 'DeepSeek V4.1 Flash Ultrafast (OpenGateway)', rationale: 'Single verified first-slice model', status: 'shipping' },
430
+ loaded: { model: OPENGATEWAY_MODEL, reasoningLevel: 'off', label: 'DeepSeek V4.1 Flash Ultrafast (OpenGateway)', rationale: 'Single verified first-slice model', status: 'shipping' },
431
+ };
432
+
420
433
  // ── AWS Bedrock (BEDROCK-PROVIDER · 2026-10-11) ───────────────────
421
434
  // ⭐ 판단: ANTHROPIC 사다리의 «추론 수준·역할 배치»를 그대로 두고, 모델은 Bedrock 메시지 엔드포인트에서
422
435
  // 확인한 5.5 계열 id(`src/llm/bedrock.ts` BEDROCK_MODELS · 출처 platform.claude.com «Claude in Amazon Bedrock»
@@ -466,6 +479,7 @@ export const LLM_TIER_MAP_BY_PROVIDER: Readonly<Record<LlmTierProvider, TierMap>
466
479
  glm: GLM,
467
480
  grok: GROK,
468
481
  openrouter: OPENROUTER,
482
+ opengateway: OPENGATEWAY,
469
483
  bedrock: BEDROCK,
470
484
  } as const;
471
485
 
@@ -488,7 +502,7 @@ export function parseTierArg(raw: string): ModelTier | undefined {
488
502
  * tsc 는 배열 누락을 못 잡는다(2026-09-23 `#19900` 이 `openrouter` 를 빠뜨려 배선 계약 자가 그것을
489
503
  * 한 번도 누르지 않았다). 자 = `provider-wiring-contract.test.ts`. */
490
504
  export const TIER_PROVIDERS: readonly LlmTierProvider[] = [
491
- 'anthropic', 'openai', 'openai-codex', 'gemini', 'grok', 'local', 'kimi', 'qwen', 'glm', 'openrouter', 'bedrock',
505
+ 'anthropic', 'openai', 'openai-codex', 'gemini', 'grok', 'local', 'kimi', 'qwen', 'glm', 'openrouter', 'opengateway', 'bedrock',
492
506
  ];
493
507
 
494
508
  /** OpenRouter 모델 id(`openrouter/<vendor>/<model>` 또는 `<vendor>/<model>`)의 tier-map 칸.
@@ -392,7 +392,7 @@ export const nativeToolCatalog: NativeToolCatalogEntry[] = [
392
392
  // OP TUI turns drove msg list/post/ack and release checklist
393
393
  // list/move/set/add through `eln` RunShell calls — 1.3–2s of CLI
394
394
  // startup each, 30+ spawns per turn, shell stdout amplifying screen
395
- // defects. These eight tools reuse the SAME durable services
395
+ // defects. These ledger tools reuse the SAME durable services
396
396
  // in-process (msg-store SQLite ledger · release-loop checklist
397
397
  // ledger), preserving the structured results, the seat/OP permission
398
398
  // boundaries (ELANOUS_TRACK actor routing, seatMove rules, the HQ
@@ -429,6 +429,20 @@ export const nativeToolCatalog: NativeToolCatalogEntry[] = [
429
429
  intentScope: 'ops-fleet',
430
430
  cleanerFitThanShell: true,
431
431
  },
432
+ {
433
+ id: 'msg_ask',
434
+ kind: 'other',
435
+ aliases: ['MsgAsk', 'msg_ask'],
436
+ displayName: 'MsgAsk',
437
+ description: 'Post a durable seat question and wait for its first replyTo-linked reply. On timeout the question remains in the ledger and its ID is returned.',
438
+ promptSummary: '`MsgAsk(from, to, question, waitSeconds?)` (durable question + linked reply · in-process)',
439
+ host: ['skill', 'tui'],
440
+ safety: ['mutating'],
441
+ supportsParallel: false,
442
+ defaultEnabled: true,
443
+ intentScope: 'ops-fleet',
444
+ cleanerFitThanShell: true,
445
+ },
432
446
  {
433
447
  id: 'msg_ack',
434
448
  kind: 'other',
@@ -38,13 +38,25 @@ export function observeLoopResources(deps: {
38
38
  });
39
39
  }
40
40
 
41
+ /** The waiting cell a seat is served: the single ID the Nexus API and the PWA resource screen agree on. */
42
+ export function waitingCellId(cell: { id?: unknown } | null | undefined): string | null {
43
+ const id = cell?.id;
44
+ return typeof id === 'string' && id.trim() !== '' ? id : null;
45
+ }
46
+
47
+ /** A seat names a waiting cell only when that cell has a real ID; a blank ID is served as no cell. */
48
+ export function withWaitingCellIds(resource: TrafficResult): TrafficResult {
49
+ return { ...resource, seats: resource.seats.map(row =>
50
+ row.nextCell && waitingCellId(row.nextCell) === null ? { ...row, nextCell: null } : row) };
51
+ }
52
+
41
53
  /** The Nexus resource view reads the existing control ledger; it never allocates a second pool ledger. */
42
54
  export function handleLoopResourcesGet(
43
55
  observe: () => TrafficResult = observeLoopResources,
44
56
  listPodWorkers: () => ResourceView[] = () => new ResourceLedger(effectiveInstanceRoot()).list({ kind: 'pod-worker-lease' }),
45
57
  ): Response {
46
58
  try {
47
- const resource = observe();
59
+ const resource = withWaitingCellIds(observe());
48
60
  try {
49
61
  const podWorkers = listPodWorkers().map(row => ({ id: row.id, machine: row.machine, workerId: row.name,
50
62
  key: row.attrs.key, state: row.attrs.state, generation: row.attrs.generation, ageMs: row.ageMs, expired: row.expired }));