elanous 0.2.32 → 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 (753) 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/{IVKr3AlRUVLKsw2fh7eXF → T1mBQqmkwKDLGtyisDCOd}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{997ce8a5-2ad501927003b41b.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/{5525.86debf231e181813.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/{7391.ebae168025c91b6a.js → 1674.2a65fd5668e1cc5f.js} +1 -1
  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/{7947-d0759430f8042240.js → 1993-c0007b7ad0c0ef41.js} +1 -1
  15. package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/{60fb96c9.360b01d8d4927b7b.js → 1c735de4.f993a30bbd3c57c4.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{5307.60f2209e809bd627.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/{3902.e1e71aaac850a045.js → 2625.5d870aa999f33db1.js} +1 -1
  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/{4174.92ed04922709ac9e.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/3589.5444a06bcf6e775c.js +1 -0
  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/{9398-6aed28f0a96d0d6f.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/{7371.80c05c653b08e907.js → 4346.8601952e73bf5803.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/4441-875b97f5821ed58a.js +1 -0
  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/{2940-619bfd8ef337c611.js → 4705-194e64e47ca0fbdb.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/{1335-6731f392c35216eb.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/{7502.ccd5b8065545edd0.js → 5101.e32282718f99ed6f.js} +2 -2
  57. package/apps/pwa/out/_next/static/chunks/{2001.6c7e0fd02190886c.js → 5154.a118f3957ed14e36.js} +1 -1
  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/{5173-233188df2f42c626.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/{3267c0e6.d34854e7b3984a6e.js → 56d372f2.681ab4ec4c998fae.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +287 -0
  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/{6433.fc573af22bbc9ab7.js → 6236.e18cced2d5ba6afb.js} +17 -17
  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/{6544cb48.a87fe20ddf137be2.js → 6b89c8bd.24df687a820500b3.js} +1 -1
  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/{2871.0bca6137343b3f76.js → 7385.50a308a477bdfc21.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/{2985.39ccdecd36848b12.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/{8018.a32663f04a6fc5f9.js → 8219.baa715d1deee80e2.js} +1 -1
  95. package/apps/pwa/out/_next/static/chunks/{4111.2bfedbb233ad206b.js → 8256.e3ac8421a71f82f4.js} +1 -1
  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/8437-8d5492094b166cfa.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/{2213.2ccbada92c33ea0f.js → 8444.4c26b379ca2b9596.js} +17 -17
  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/{6092.a7f99e68b188ca66.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/{3278.2e5d15b53a4091c8.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/{9221.7d22eaf353a2d4e7.js → 938.66ad1ef0e5abae1c.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/{6157.0c9af021de4fb31b.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/{69-0a2c8209c6d4a158.js → 967-2aa39b2d04b4c690.js} +1 -1
  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/{7862.30a8d6482bb238eb.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-a27b1e5a0d1b308f.js → page-406b47745b53f269.js} +1 -1
  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-26e6c18a1a750cf6.js +1 -0
  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-32866485913d6a04.js → page-47c5d4db587266bd.js} +1 -1
  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-04d00ae9b0890349.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/{7a1887c4.f36b88fba31da8fd.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/{b313b242.cb1265eea908db61.js → cbe38a15.5a032598e39970c6.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{409f1e57.d0649fc47691ebfe.js → d06f9160.a3d9062f95de8ad7.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/{0bb0ff36.b8d418980951e5ba.js → da5176c6.6773b6c5994e1d99.js} +7 -7
  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 +10 -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 +5 -0
  283. package/graphs/catalog/catalog.yaml +1 -1
  284. package/graphs/default-loop.yaml +76 -5
  285. package/graphs/document-loop.yaml +71 -4
  286. package/graphs/implement-loop.yaml +59 -4
  287. package/graphs/journey/SCENARIOS.md +33 -0
  288. package/graphs/journey/recipes.yaml +1 -0
  289. package/graphs/journey/ta-journey.yaml +94 -0
  290. package/graphs/journey/units/author/author.yaml +20 -0
  291. package/graphs/journey/units/author/recipes.yaml +2 -0
  292. package/graphs/journey/units/author-dialogue/author-dialogue.yaml +42 -0
  293. package/graphs/journey/units/author-dialogue/observe.ts +96 -0
  294. package/graphs/journey/units/author-dialogue/recipes.yaml +10 -0
  295. package/graphs/journey/units/green/green.yaml +20 -0
  296. package/graphs/journey/units/green/recipes.yaml +2 -0
  297. package/graphs/journey/units/pr/pr.yaml +20 -0
  298. package/graphs/journey/units/pr/recipes.yaml +2 -0
  299. package/graphs/journey/units/remember/recipes.yaml +2 -0
  300. package/graphs/journey/units/remember/remember.yaml +20 -0
  301. package/graphs/operate-loop.yaml +71 -4
  302. package/graphs/overlays/stop-heal-ladder.yaml +1 -1
  303. package/graphs/release-rehearsal/recipes.yaml +1 -1
  304. package/graphs/release-rehearsal/release-rehearsal.yaml +2 -2
  305. package/graphs/research-loop.yaml +159 -4
  306. package/graphs/test-diet/test-diet.yaml +3 -0
  307. package/graphs/units/dispatch-pod/dispatch-pod.yaml +50 -0
  308. package/graphs/units/dispatch-pod/recipes.yaml +14 -0
  309. package/graphs/units/entry/entry.yaml +50 -0
  310. package/graphs/units/entry/recipes.yaml +14 -0
  311. package/graphs/units/harvest/harvest.yaml +25 -0
  312. package/graphs/units/harvest/recipes.yaml +4 -0
  313. package/graphs/units/land/land.yaml +45 -0
  314. package/graphs/units/land/recipes.yaml +3 -0
  315. package/graphs/units/recipes.yaml +7 -0
  316. package/graphs/units/recover.yaml +39 -0
  317. package/graphs/units/reflect/recipes.yaml +3 -0
  318. package/graphs/units/reflect/reflect.yaml +15 -0
  319. package/graphs/units/task-agent-recover-review.yaml +17 -0
  320. package/graphs/units/task-agent-recover-wait.yaml +17 -0
  321. package/graphs/units/verbs/make-doc.yaml +34 -0
  322. package/graphs/units/verbs/recipes.yaml +33 -0
  323. package/graphs/units/verbs/verify.yaml +55 -0
  324. package/graphs/work/recipes.yaml +2 -0
  325. package/graphs/work/research-report.yaml +28 -0
  326. package/package.json +1 -1
  327. package/scripts/ci-typecheck-changed.ts +69 -16
  328. package/scripts/coord-role-pack.ts +19 -6
  329. package/scripts/docs/generate-graph-anatomy.ts +19 -2
  330. package/scripts/graph-harvest-unit.ts +22 -0
  331. package/scripts/graph-units/journey-stub.ts +6 -0
  332. package/scripts/graph-units/land-enqueue.ts +78 -0
  333. package/scripts/graph-units/recover-plan.ts +15 -0
  334. package/scripts/graph-units/reflect-node.ts +88 -0
  335. package/scripts/graph-units/ta-journey-observe.ts +109 -0
  336. package/scripts/graph-units/verbs/headless-goal-loop.ts +152 -0
  337. package/scripts/graph-units/verbs/verify-stage.ts +75 -0
  338. package/scripts/graph-units/verbs-envelope.ts +139 -0
  339. package/scripts/hq/standby-snapshot.ts +30 -0
  340. package/scripts/public-export.ts +43 -1
  341. package/scripts/ratchets/train-side-invariants.sh +45 -0
  342. package/scripts/release-loop/auto-approve-node.ts +30 -16
  343. package/scripts/release-loop/docs-land-node.ts +21 -5
  344. package/scripts/release-loop/gate-baseline-receipt.ts +155 -0
  345. package/scripts/release-loop/gate-closure.ts +5 -1
  346. package/scripts/release-loop/gate-diff.ts +1 -1
  347. package/scripts/release-loop/gate-node.ts +675 -49
  348. package/scripts/release-loop/gate-partial.ts +68 -14
  349. package/scripts/release-loop/gate-radius-live.ts +177 -0
  350. package/scripts/release-loop/gate-radius-shadow.ts +138 -0
  351. package/scripts/release-loop/gate-traffic-mode.ts +128 -0
  352. package/scripts/release-loop/gate-triage-node.ts +5 -2
  353. package/scripts/release-loop/known-issues-0.2.33-approved.json +194 -0
  354. package/scripts/release-loop/known-issues-node.ts +77 -8
  355. package/scripts/release-loop/node-verdict.ts +12 -1
  356. package/scripts/release-loop/npm-publish-node.ts +66 -12
  357. package/scripts/release-loop/preflight.ts +93 -7
  358. package/scripts/release-loop/probe-pod-host-dirs-live.ts +5 -0
  359. package/scripts/release-loop/publish-node.ts +60 -9
  360. package/scripts/release-loop/pwa-remote.ts +166 -0
  361. package/scripts/release-loop/pwa-scenarios-node.ts +19 -3
  362. package/scripts/release-loop/resume-cap.ts +56 -0
  363. package/scripts/release-loop/resume-release.ts +155 -19
  364. package/scripts/release-loop/resume.ts +24 -1
  365. package/scripts/release-loop/tui-sim-node.ts +8 -2
  366. package/scripts/release-loop/unattended-release.ts +10 -2
  367. package/scripts/test-diet/lib.ts +6 -1
  368. package/scripts/test-diet/node.ts +194 -13
  369. package/scripts/ux-sim.ts +39 -0
  370. package/src/acp/core-turn-bridge.ts +20 -5
  371. package/src/acp/reasoning-thought-buffer.ts +45 -0
  372. package/src/agent/self-ambient-cache.ts +8 -0
  373. package/src/agent-substrate/acp-reviewer.ts +90 -15
  374. package/src/agent-substrate/pr-reviewer.ts +17 -0
  375. package/src/agent-substrate/review-finding-key.ts +53 -0
  376. package/src/agent-substrate/self-review-cli.ts +188 -18
  377. package/src/ask-user-question/pending-questions.ts +1 -1
  378. package/src/autopilot/pr-manager.ts +393 -65
  379. package/src/budget/run-usage-rollup.ts +1 -0
  380. package/src/chat/index.ts +0 -2
  381. package/src/chat/pickers/modal-runtime.ts +10 -27
  382. package/src/chat/tool-render/dispatch.ts +62 -10
  383. package/src/cli/agent-cli.ts +13 -2
  384. package/src/cli/control-cli.ts +24 -7
  385. package/src/cli/doctor-cli.ts +4 -1
  386. package/src/cli/guardian-cli.ts +10 -0
  387. package/src/cli/light-entry-route.ts +75 -0
  388. package/src/cli/llm-detect-cli.ts +23 -1
  389. package/src/cli/pod-cli.ts +77 -3
  390. package/src/cli/pr-cli.ts +81 -14
  391. package/src/cli/pr-land-base-read.ts +2 -0
  392. package/src/cli/pr-land-overlap-evidence.ts +154 -16
  393. package/src/cli/pr-land-pod-shadow-job.ts +3 -0
  394. package/src/cli/pr-land-recovery.ts +64 -0
  395. package/src/cli/pty-takeover-cli.ts +6 -5
  396. package/src/cli/release-checklist-read-cli.ts +79 -0
  397. package/src/cli/release-cli.ts +189 -132
  398. package/src/cli/release-run-if-ready.ts +29 -28
  399. package/src/cli/release-single-flight.ts +178 -0
  400. package/src/cli/remote-resolve.ts +1 -1
  401. package/src/cli/root-tui-entry.ts +48 -0
  402. package/src/cli/seat-cli.ts +37 -0
  403. package/src/cli/setup-cli.ts +40 -1
  404. package/src/cli/sim-cli.ts +22 -0
  405. package/src/cli/tasks-cli.ts +667 -14
  406. package/src/cli/usage-cli.ts +13 -11
  407. package/src/clipboard/history.ts +179 -13
  408. package/src/config.ts +8 -1
  409. package/src/control/control-status.ts +8 -3
  410. package/src/control-plane/ledger.ts +5 -3
  411. package/src/control-plane/server.ts +5 -3
  412. package/src/core-turn/short-question.ts +5 -1
  413. package/src/dashboard/chat/acp-chat.ts +8 -0
  414. package/src/dashboard/index.ts +114 -77
  415. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +3 -0
  416. package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
  417. package/src/dashboard/input/seat-autowake.ts +56 -3
  418. package/src/dashboard/render/theme-resolver.ts +33 -4
  419. package/src/dashboard/seat-boot-preamble.ts +1 -1
  420. package/src/dashboard/slash-runtime/ask-clarification.ts +48 -0
  421. package/src/dashboard/slash-runtime/dashboard-delegated-slashes.ts +68 -0
  422. package/src/dashboard/slash-runtime/dashboard-handlers.ts +62 -322
  423. package/src/dashboard/slash-runtime/dashboard-log-slash.ts +208 -0
  424. package/src/dashboard/turn-preamble.ts +47 -1
  425. package/src/dashboard/turn-stream-formatter.ts +34 -1
  426. package/src/dashboard/turn-stream-runtime.ts +2 -0
  427. package/src/dashboard/turn-typeahead-prompt-zone.ts +67 -0
  428. package/src/domains/guardian-tick.ts +54 -2
  429. package/src/domains/outbound-alert.ts +3 -2
  430. package/src/domains/schedule-registry.ts +16 -2
  431. package/src/extractors.ts +3 -1
  432. package/src/git-fs/idle-refresh.ts +76 -0
  433. package/src/git-fs/index.ts +18 -7
  434. package/src/git-fs/retry.ts +4 -0
  435. package/src/git-fs/runner.ts +2 -0
  436. package/src/git-fs/worktree.ts +42 -4
  437. package/src/graph-kinds/registry.ts +2 -2
  438. package/src/graph-runner/runner.ts +267 -54
  439. package/src/grok/credential.ts +15 -3
  440. package/src/harness/harness-cli-command.ts +151 -38
  441. package/src/harness/harness-incidents.ts +37 -0
  442. package/src/harness/harness-pod-dispatch.ts +38 -1
  443. package/src/harness/harness-salvage-cli.ts +14 -2
  444. package/src/harness/launch-utterance-ledger.ts +208 -0
  445. package/src/impl-discipline/detector.ts +16 -4
  446. package/src/impl-discipline/system-prompt.ts +11 -0
  447. package/src/impl-discipline/types.ts +2 -2
  448. package/src/index.ts +683 -146
  449. package/src/intake-plane/already-built-hint.ts +91 -0
  450. package/src/intake-plane/requirement-funnel.ts +29 -1
  451. package/src/knowhow/pack.ts +199 -0
  452. package/src/light-cli.ts +111 -0
  453. package/src/llm/opengateway-models.ts +11 -0
  454. package/src/llm/provider-credentials.ts +14 -0
  455. package/src/llm/provider-detect.ts +8 -1
  456. package/src/llm/runtime-model-family.ts +2 -1
  457. package/src/llm.ts +268 -65
  458. package/src/loops/budget.ts +95 -0
  459. package/src/loops/msg-wake.ts +8 -2
  460. package/src/loops/orchestrator/traffic.ts +132 -1
  461. package/src/model-tier/llm-tier-map.ts +15 -1
  462. package/src/mss/logging/log-store.ts +4 -5
  463. package/src/native-tool-catalog.ts +15 -1
  464. package/src/nexus/api/graphs-api.ts +22 -3
  465. package/src/nexus/api/http-server.ts +1 -1
  466. package/src/nexus/api/loop-resources.ts +13 -1
  467. package/src/nexus/api/ops-api.ts +12 -0
  468. package/src/oauth/claude-pty-maturity.ts +66 -0
  469. package/src/oauth/codex-access-mirror.ts +55 -0
  470. package/src/oauth/codex.ts +7 -0
  471. package/src/oauth/fallback-chain.ts +1 -1
  472. package/src/onboarding/first-run.ts +5 -3
  473. package/src/onboarding/non-interactive.ts +64 -13
  474. package/src/onboarding.ts +10 -2
  475. package/src/ops/overview-collect.ts +54 -4
  476. package/src/ops/overview.ts +31 -7
  477. package/src/pr-tool/census.ts +282 -30
  478. package/src/pr-tool/inflight-registry.ts +160 -7
  479. package/src/prompt-library/gpt6-family-addendum.ts +14 -1
  480. package/src/pty-shell/herdr-agent-report.ts +442 -0
  481. package/src/pty-shell/pty-control-ipc.ts +5 -5
  482. package/src/pty-shell/pty-manifest.ts +7 -0
  483. package/src/pty-shell/pty-write-outcome.ts +24 -6
  484. package/src/pty-shell/tui-run-state.ts +117 -3
  485. package/src/release-loop/checklist.ts +103 -5
  486. package/src/release-loop/feature-store.ts +19 -2
  487. package/src/release-loop/landed-but-yellow.ts +129 -5
  488. package/src/release-loop/light-rc.ts +1 -0
  489. package/src/release-loop/placement.ts +10 -3
  490. package/src/release-loop/rehearsal.ts +205 -25
  491. package/src/release-loop/rubric.ts +16 -2
  492. package/src/repl/index.ts +174 -17
  493. package/src/repl/ops-msg-bridge.ts +32 -0
  494. package/src/self-dev/ask-launch-flow.ts +44 -5
  495. package/src/self-dev/cli-help-text.ts +17 -0
  496. package/src/self-dev/dev-cli.ts +11 -9
  497. package/src/self-dev/draft-residue.ts +37 -1
  498. package/src/self-dev/draft-sweep.ts +188 -13
  499. package/src/self-dev/draft-triage-rules.ts +107 -0
  500. package/src/self-dev/fleet-reduce.ts +3 -2
  501. package/src/self-dev/graph-front-nodes.ts +112 -0
  502. package/src/self-dev/graph-journey-nodes.ts +11 -6
  503. package/src/self-dev/graph-journey-route.ts +60 -6
  504. package/src/self-dev/harness-run-cli.ts +3 -15
  505. package/src/self-dev/orchestrate-cli-text.ts +10 -0
  506. package/src/self-dev/orchestrate.ts +79 -3
  507. package/src/self-dev/review-provider-fallback.ts +35 -1
  508. package/src/self-dev/run-supervisor.ts +107 -12
  509. package/src/self-dev/run-types.ts +5 -1
  510. package/src/self-dev/self-orchestrate-runtime.ts +1 -11
  511. package/src/self-dev/shard-aggregate.ts +42 -5
  512. package/src/self-dev/shard-run.ts +8 -1
  513. package/src/self-implement/blocked-draft-policy.ts +20 -0
  514. package/src/self-implement/classify-shadow.ts +3 -7
  515. package/src/self-implement/doctor-visit.ts +18 -1
  516. package/src/self-implement/gate-baseline.ts +95 -12
  517. package/src/self-implement/gate-cli.ts +1 -0
  518. package/src/self-implement/gate-remote.ts +40 -25
  519. package/src/self-implement/goal-author-decompose.ts +275 -47
  520. package/src/self-implement/goal-author-identity.ts +66 -0
  521. package/src/self-implement/goal-author-preservation-obligation.ts +35 -0
  522. package/src/self-implement/goal-author.ts +254 -120
  523. package/src/self-implement/goal-elaborate.ts +295 -0
  524. package/src/self-implement/goal-refine.ts +270 -0
  525. package/src/self-implement/graph-overlay-yaml.ts +28 -2
  526. package/src/self-implement/graph-unit-flatten.ts +103 -0
  527. package/src/self-implement/graph-unit-resolver.ts +107 -0
  528. package/src/self-implement/graph-yaml.ts +151 -1
  529. package/src/self-implement/headless-elanous-driver.ts +1 -0
  530. package/src/self-implement/knowhow-pack.ts +103 -0
  531. package/src/self-implement/orchestrator.ts +160 -45
  532. package/src/self-implement/pod-warm-pool-profile.ts +45 -0
  533. package/src/self-implement/review-mustfix-class.ts +203 -0
  534. package/src/self-implement/rework-budget-judgment.ts +5 -8
  535. package/src/self-implement/run-stop.ts +17 -2
  536. package/src/self-implement/running-runs.ts +29 -1
  537. package/src/self-implement/scope-adjacency.ts +113 -0
  538. package/src/self-implement/seams.ts +138 -4
  539. package/src/self-implement/stop-autoheal.ts +112 -2
  540. package/src/session/chat.ts +27 -0
  541. package/src/session-runtime/index.ts +1 -1
  542. package/src/session-runtime/retry-policy.ts +2 -1
  543. package/src/setup/llm-env-detect.ts +5 -0
  544. package/src/skills/tools/agent.ts +140 -14
  545. package/src/skills/tools/msg-ask.ts +100 -0
  546. package/src/skills/tools/ops-ledger.ts +2 -1
  547. package/src/skills/tools/schedule-wakeup.ts +66 -17
  548. package/src/steward/hold-hygiene.ts +24 -6
  549. package/src/steward/release-day.ts +7 -3
  550. package/src/steward/triage-budget.ts +194 -0
  551. package/src/steward/triage.ts +57 -7
  552. package/src/task-agent/actions.ts +69 -1
  553. package/src/task-agent/green-sweep.ts +4 -0
  554. package/src/task-agent/harvest-unit.ts +141 -0
  555. package/src/task-agent/live-moves.ts +257 -15
  556. package/src/task-agent/parent-host.ts +216 -6
  557. package/src/task-agent/postland-card.ts +80 -1
  558. package/src/task-agent/rejudge-on-head.ts +112 -26
  559. package/src/task-agent/repair-branch-cas.ts +4 -1
  560. package/src/task-agent/repair-cycle.ts +16 -3
  561. package/src/task-agent/run-identity.ts +4 -3
  562. package/src/task-agent/shadow.ts +19 -3
  563. package/src/task-agent/task-hand.ts +96 -36
  564. package/src/task-agent/tier-split.ts +127 -0
  565. package/src/task-agent/work-order-build.ts +24 -0
  566. package/src/task-agent/work-order.ts +3 -2
  567. package/src/task-orchestrator/generator-prompt.ts +60 -11
  568. package/src/task-orchestrator/surfaces/pod-account-broker.ts +72 -3
  569. package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
  570. package/src/task-orchestrator/surfaces/pod-command-job.ts +47 -8
  571. package/src/task-orchestrator/surfaces/pod-image-source.ts +89 -1
  572. package/src/task-orchestrator/surfaces/pod-lease.ts +17 -8
  573. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +86 -8
  574. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +8 -2
  575. package/src/task-orchestrator/surfaces/pod-pool.ts +73 -17
  576. package/src/task-orchestrator/surfaces/pod-provenance.ts +76 -0
  577. package/src/task-orchestrator/surfaces/pod-source-receive.ts +72 -4
  578. package/src/task-orchestrator/surfaces/pod-warm-provenance.ts +81 -0
  579. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +32 -5
  580. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +3 -0
  581. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +421 -0
  582. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +2 -1
  583. package/src/task-orchestrator/surfaces/self-implement-pod.ts +588 -71
  584. package/src/task-orchestrator/surfaces/self-implement.ts +106 -2
  585. package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
  586. package/src/tool-runtime/truncation-store.ts +4 -0
  587. package/src/tui/README.md +2 -0
  588. package/src/tui/chat/background-job-status.ts +54 -0
  589. package/src/tui/chat/log-view.ts +80 -0
  590. package/src/tui/entry.ts +406 -0
  591. package/src/tui/input/composer.ts +144 -0
  592. package/src/tui/seat-mail-boot.ts +59 -0
  593. package/src/tui/slash/compact.ts +100 -0
  594. package/src/tui/slash/new-session.ts +35 -0
  595. package/src/tui-client/dashboard-session.ts +10 -1
  596. package/src/tui-client/local-chat-turn.ts +239 -0
  597. package/src/tui-client/local-harness-command.ts +63 -0
  598. package/src/tui-client/local-provider-command.ts +184 -0
  599. package/src/user-config/coercion.ts +36 -0
  600. package/src/user-config.ts +22 -43
  601. package/src/ux-sim/event-monkey.ts +378 -0
  602. package/src/ux-sim/fake-bin.ts +42 -7
  603. package/src/ux-sim/fault-nextmove-dispatch.ts +266 -0
  604. package/src/ux-sim/fault-pod-codex-503.ts +211 -0
  605. package/src/ux-sim/fault-scope-escape-lift.ts +189 -0
  606. package/src/ux-sim/scenario.ts +72 -13
  607. package/src/version/packed-revision.json +1 -1
  608. package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +0 -27
  611. package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +0 -287
  612. package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +0 -62
  613. package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/1654.32de4b324981a188.js +0 -23
  617. package/apps/pwa/out/_next/static/chunks/1834-98b64172bc1efe77.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +0 -149
  619. package/apps/pwa/out/_next/static/chunks/1913.7cc6fb6055b1ed3f.js +0 -41
  620. package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/2898.fd781bc7cf01a7b7.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +0 -115
  629. package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +0 -64
  630. package/apps/pwa/out/_next/static/chunks/3541-ce3a5424ed5ad7f1.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +0 -36
  636. package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +0 -286
  640. package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +0 -77
  641. package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +0 -226
  642. package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +0 -79
  644. package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +0 -148
  647. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/5458-16cd7a2b51b74c8c.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/5543.a438b8ab5a13ea47.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +0 -74
  653. package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +0 -94
  655. package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +0 -90
  661. package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +0 -32
  662. package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +0 -104
  663. package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +0 -24
  668. package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +0 -93
  669. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +0 -8
  674. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/8097-9530c03bcc550f02.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +0 -24
  685. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/9138.b6e80031afb1d973.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/9279-d28c5b7754d010ae.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/9989.3694300e5f000b14.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/approvals/page-504204b58c82c253.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a9717a67c2eecbaf.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/board/page-5c9ec30aee62dfbf.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/botlab/page-584191533721fa16.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/app/bots/page-73c4b4bb3ac7ab5f.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c0f1ca371f710b06.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/app/chat/page-46430d45a9e04eac.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/app/consult/page-3b2ebf1dc64ff0be.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/app/decisions/page-25654b82094f7d22.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8ea49a4c6dd2c6e7.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/app/editor/page-ce5113aefea0a8d1.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/app/exec/page-0e5a41fac1c75396.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/app/field/page-31aaf1ed37c6df9a.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/app/inside/page-3dcc1fa411e1f4e0.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/app/intake/page-c69247e7134d329d.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/app/layout-66dc5cd3a0999abe.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/app/live/page-26ff7ff651a7217d.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/app/live-run/page-617b3976981efa96.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/app/loops/page-d256f5d5d9552823.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/app/market/page-ce8f1907b8a6101c.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-33e182a316263116.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/app/not-found-7607cca9b84950c6.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eeab86176b03dc3b.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5b93dbae3432b996.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-77a6cb90a9cf2b10.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f47e768b5b242b5a.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/app/outputs/page-eb41aa3367fc2505.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/page-4d13ab0b8a267e3f.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/reflection/page-84dad32ff0fc0831.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-95306f892aa2d0ee.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/sessions/page-940fb6c217f6b470.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-8c66a3b24a745630.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/settings/page-7b675dfd35c36fc9.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8bd0d3cf7665bcfc.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/app/setup/page-c219f2ed171131be.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/app/share/page-40f8fa21bdae955b.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/app/showroom/page-468f8313e4f1fbd9.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/app/tasks/page-7bbb8fa353a246c4.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/app/today/page-4214b855d9233ea8.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/app/trace/page-936752c7aa58762e.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/app/vault/page-ec052ad359df1797.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8305570551091338.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/workflows/page-fad650e4793adb65.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/workspace/page-d90e64743826e1d8.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a16bcfd49af86a32.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +0 -122
  744. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +0 -1
  752. package/src/cli/g6a-registration-probe.ts +0 -16
  753. /package/apps/pwa/out/_next/static/{IVKr3AlRUVLKsw2fh7eXF → T1mBQqmkwKDLGtyisDCOd}/_ssgManifest.js +0 -0
@@ -1,6 +1,10 @@
1
+ import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
1
3
  import { ORCHESTRATOR_DEFAULTS, type OrchestratorSeat } from '../user-config.js';
4
+ import { debug } from '../debug/log.js';
2
5
  import type { ChecklistItem } from '../release-loop/checklist.js';
3
6
  import type { TrafficCell, TrafficProcess, TrafficResult, TrafficSeatRow } from './orchestrator/traffic.js';
7
+ import { withFileLockSync } from '../storage/file-lock.js';
4
8
 
5
9
  const RESOURCE_SEATS: readonly OrchestratorSeat[] = ['OP', 'TC', 'MK', 'UX'];
6
10
 
@@ -277,3 +281,94 @@ export function budgetTrafficTick({ processes, now, caps, lastLaunchAt, idleSinc
277
281
  }
278
282
  return { seats, unassigned: launches.filter(process => process.seat === null).length, now, idleMinutes };
279
283
  }
284
+
285
+ /** A tick's seat rows as observed: one journal line per tick, kept for the 24h metrics only. */
286
+ export type TrafficTickSample = { at: string; seats: readonly TrafficSeatRow[] };
287
+
288
+ export interface TrafficSampleDeps {
289
+ log?: (category: string, event: string, data: Record<string, unknown>) => void;
290
+ }
291
+
292
+ /** Observation-only journal for 24h metrics: never read for launch decisions. A failure to record costs one metrics sample, never the tick itself. */
293
+ export function recordTrafficSample24h(root: string, sample: TrafficTickSample,
294
+ deps: TrafficSampleDeps = {}): void {
295
+ const log = deps.log ?? debug.log.bind(debug);
296
+ const path = join(root, 'orchestrator', 'traffic-samples-24h.jsonl');
297
+ try {
298
+ mkdirSync(dirname(path), { recursive: true });
299
+ withFileLockSync(`${path}.lock`, () => {
300
+ // A torn final line has no newline; separate it from the next valid JSONL row.
301
+ const previous = existsSync(path) ? readFileSync(path, 'utf8') : '';
302
+ const separator = previous === '' || previous.endsWith('\n') ? '' : '\n';
303
+ appendFileSync(path, `${separator}${JSON.stringify(sample)}\n`);
304
+ });
305
+ log('loop.orchestrator', 'traffic-sample-24h', { at: sample.at, path });
306
+ } catch (error) {
307
+ try { log('loop.orchestrator', 'traffic-sample-24h-failed', { error: String(error).slice(0, 200) }); }
308
+ catch { /* Observation cannot change a recorded decision. */ }
309
+ }
310
+ }
311
+
312
+ /** Read the 24h sample journal; torn lines are skipped (same rule as the dispatch ledger). */
313
+ export function readTrafficSamples24h(root: string, now: Date, windowMinutes = 1440): TrafficTickSample[] {
314
+ const path = join(root, 'orchestrator', 'traffic-samples-24h.jsonl');
315
+ if (!existsSync(path)) return [];
316
+ const floor = now.getTime() - windowMinutes * 60_000;
317
+ return readFileSync(path, 'utf8').split('\n').flatMap(line => {
318
+ if (!line.trim()) return [];
319
+ try {
320
+ const parsed = JSON.parse(line) as TrafficTickSample;
321
+ const at = Date.parse(parsed.at);
322
+ if (!Number.isFinite(at) || at < floor || at > now.getTime() || !Array.isArray(parsed.seats)) return [];
323
+ return [parsed];
324
+ } catch { return []; }
325
+ });
326
+ }
327
+
328
+ export type TrafficMetrics24h = {
329
+ /** Occupied share of the observed slot budget over all ticks (Σrunning / Σcap). */
330
+ utilizationRate: number;
331
+ running: number;
332
+ capacity: number;
333
+ /** Mean minutes an idle, empty seat has waited for its next launch; null when no waits were observed. */
334
+ meanWaitMinutes: number | null;
335
+ waitSamples: number;
336
+ /** Seat-ticks where a seat ran on borrowed share — its own base share could not keep it. */
337
+ preemptedSeatTicks: number;
338
+ sampledTicks: number;
339
+ windowMinutes: number;
340
+ firstSampleAt: string | null;
341
+ lastSampleAt: string | null;
342
+ };
343
+
344
+ /** Aggregate the 24h traffic metrics from the observation journal. Pure over the given samples. */
345
+ export function computeTrafficMetrics24h(samples: readonly TrafficTickSample[], windowMinutes = 1440): TrafficMetrics24h {
346
+ let running = 0;
347
+ let capacity = 0;
348
+ let waitSum = 0;
349
+ let waitSamples = 0;
350
+ let preemptedSeatTicks = 0;
351
+ for (const sample of samples) {
352
+ for (const row of sample.seats) {
353
+ running += row.running;
354
+ capacity += row.cap;
355
+ if (row.borrowed > 0) preemptedSeatTicks++;
356
+ if (row.idleFor !== null && row.idleFor > 0) {
357
+ waitSum += row.idleFor;
358
+ waitSamples++;
359
+ }
360
+ }
361
+ }
362
+ return {
363
+ utilizationRate: capacity > 0 ? Math.round((running / capacity) * 1000) / 1000 : 0,
364
+ running,
365
+ capacity,
366
+ meanWaitMinutes: waitSamples > 0 ? Math.round((waitSum / waitSamples) * 10) / 10 : null,
367
+ waitSamples,
368
+ preemptedSeatTicks,
369
+ sampledTicks: samples.length,
370
+ windowMinutes,
371
+ firstSampleAt: samples[0]?.at ?? null,
372
+ lastSampleAt: samples.at(-1)?.at ?? null,
373
+ };
374
+ }
@@ -309,7 +309,7 @@ export async function wakeRecipient(address: string, msgId: number, message: { f
309
309
 
310
310
  interface PendingWakeRow { address: string; first_msg_id: number; last_msg_id: number; last_from: string; count: number; since: number; attempts: number; reason: string }
311
311
 
312
- export type PendingWakeEvent = 'deferred' | 'redelivered' | 'gave-up' | 'dropped-read';
312
+ export type PendingWakeEvent = 'deferred' | 'redelivered' | 'gave-up' | 'dropped-read' | 'skip';
313
313
 
314
314
  function logPending(event: PendingWakeEvent, data: Record<string, unknown>): void {
315
315
  try { debug.log('loops.msg-wake', event, data); } catch { /* observability is fail-open */ }
@@ -389,8 +389,14 @@ export function redeliverLine(row: Pick<PendingWakeRow, 'address' | 'last_from'
389
389
  * Re-knock deferred wakes whose TUI is now recorded idle. `target` limits the sweep to one pty (the TUI's own poller).
390
390
  * Never throws per row; a row stays pending while the TUI is busy or the 5-minute window is held.
391
391
  */
392
+ // not-live 우주의 재점검은 침묵 대신 이유 한 줄을 남긴다 — 폴러가 15초마다 틱하므로 프로세스당 처음 한 번만(래치).
393
+ let notLiveSkipLogged = false;
394
+
392
395
  export async function redeliverPendingWakes(deps: WakeDeps = {}, opts: { target?: string } = {}): Promise<RedeliverOutcome[]> {
393
- if (!isLive(deps)) return [];
396
+ if (!isLive(deps)) {
397
+ if (!notLiveSkipLogged) { notLiveSkipLogged = true; logPending('skip', { reason: 'not-live' }); }
398
+ return [];
399
+ }
394
400
  const db = claimDbPath(deps);
395
401
  if (!existsSync(db)) return [];
396
402
  const conn = openWakeDb(db);
@@ -9,7 +9,8 @@ import { withFileLockSync } from '../../storage/file-lock.js';
9
9
  import { getUserConfig, ORCHESTRATOR_DEFAULTS, type OrchestratorLoopConfig, type OrchestratorSeat } from '../../user-config.js';
10
10
  import { finishAdvice, measureFinish, type FinishAdvice, type FinishMetrics, type MeasureFinishDeps } from './finish-rate.js';
11
11
  import { collectAuthorDepth, type AuthorDepthResult, type CollectAuthorDepthDeps } from './author-depth.js';
12
- import { budgetTrafficTick } from '../budget.js';
12
+ import { probeDegradation, type DegradationSignal } from './degradation.js';
13
+ import { budgetTrafficTick, computeTrafficMetrics24h, readTrafficSamples24h, recordTrafficSample24h, type TrafficSampleDeps } from '../budget.js';
13
14
 
14
15
  export const TRAFFIC_SEATS = ['OP', 'TC', 'MK', 'UX'] as const;
15
16
  export type TrafficCell = Pick<ChecklistItem, 'id' | 'title' | 'owner' | 'status'>;
@@ -33,6 +34,11 @@ export type DispatchCycle = {
33
34
  /** Separate journal: never extend or reinterpret seat-requests or per-run state rows. */
34
35
  export function recordDispatchCycle(root: string, cycle: DispatchCycle,
35
36
  log: (category: string, event: string, data: Record<string, unknown>) => void = debug.log.bind(debug)): void {
37
+ // 상시 게이트 관측: tick launch 노드와 runTrafficTick 이 지나는 이 배선 자체가 항상 켜져 있으므로
38
+ // 24h halt 저널은 이 자리에서 쌓인다 — `--metrics` 수동 읽기에만 매달면 관측 부재로 지표가
39
+ // 언제나 0이 되는 Goodhart 구조가 된다. 관측 전용: append 아래 원장 기록은 절대 막지 않는다.
40
+ try { observeGateHalt(root, { log }); }
41
+ catch { /* 게이트 저널은 관측일 뿐 — dispatch 원장은 관측 실패와 무관하게 기록된다 */ }
36
42
  const path = join(root, 'orchestrator', 'dispatch-ledger.jsonl');
37
43
  try {
38
44
  mkdirSync(dirname(path), { recursive: true });
@@ -207,6 +213,10 @@ export function runTrafficTick({ processes, now, caps, openCells, nextRound, tot
207
213
  skipped, dispatch: getUserConfig().loops?.orchestrator?.dispatch ?? ORCHESTRATOR_DEFAULTS.dispatch,
208
214
  });
209
215
  }
216
+ // 24h metrics journal: observation only, silent on the decision log, never read for this decision path.
217
+ recordTrafficSample24h(root, { at: now.toISOString(), seats: result.seats }, { log: () => {} });
218
+ // 게이트 관측은 위 recordDispatchCycle 상시 배선(과 tick launch 노드의 동일 호출)에서 매 사이클
219
+ // 쌓인다 — 이 틱에서 중복 관측을 또 하지 않는다. 관측 전용, 이 판정 경로는 이 저널을 읽지 않는다.
210
220
  let authorShadow: AuthorShadow | null = null;
211
221
  let shadowFailure: Record<string, unknown> | null = null;
212
222
  try {
@@ -228,9 +238,129 @@ export function runTrafficTick({ processes, now, caps, openCells, nextRound, tot
228
238
  return { result, queued, authorShadow };
229
239
  }
230
240
 
241
+ export type GateObservation = { at: string; level: 'L1' | 'L2' | null };
242
+
243
+ /** Map a degradation probe to the gate level that stops place/delegate/launch; L2 is the stronger gate. */
244
+ export function gateLevelOf(signal: Pick<DegradationSignal, 'llm' | 'board'>): 'L1' | 'L2' | null {
245
+ if (!signal.board) return 'L2';
246
+ if (!signal.llm) return 'L1';
247
+ return null;
248
+ }
249
+
250
+ export interface GateHaltDeps {
251
+ signal?: Pick<DegradationSignal, 'llm' | 'board'>;
252
+ probe?: (root: string) => Pick<DegradationSignal, 'llm' | 'board'>;
253
+ log?: (category: string, event: string, data: Record<string, unknown>) => void;
254
+ }
255
+
256
+ /** Observation-only journal for the 24h gate metric: probe the degradation gates and append the level. */
257
+ export function observeGateHalt(root: string, deps: GateHaltDeps = {}): GateObservation {
258
+ const log = deps.log ?? debug.log.bind(debug);
259
+ const signal = deps.signal ?? deps.probe?.(root) ?? probeDegradation(root);
260
+ const observation: GateObservation = { at: new Date().toISOString(), level: gateLevelOf(signal) };
261
+ const path = join(root, 'orchestrator', 'gate-halt-24h.jsonl');
262
+ try {
263
+ mkdirSync(dirname(path), { recursive: true });
264
+ withFileLockSync(`${path}.lock`, () => {
265
+ const previous = existsSync(path) ? readFileSync(path, 'utf8') : '';
266
+ const separator = previous === '' || previous.endsWith('\n') ? '' : '\n';
267
+ appendFileSync(path, `${separator}${JSON.stringify(observation)}\n`);
268
+ });
269
+ log('loop.orchestrator', 'gate-halt-24h', { ...observation, path });
270
+ } catch (error) {
271
+ try { log('loop.orchestrator', 'gate-halt-24h-failed', { error: String(error).slice(0, 200) }); }
272
+ catch { /* Observation cannot change a recorded decision. */ }
273
+ }
274
+ return observation;
275
+ }
276
+
277
+ /** Read the 24h gate journal; torn lines are skipped (same rule as the dispatch ledger). */
278
+ export function readGateObservations24h(root: string, now: Date, windowMinutes = 1440): GateObservation[] {
279
+ const path = join(root, 'orchestrator', 'gate-halt-24h.jsonl');
280
+ if (!existsSync(path)) return [];
281
+ const floor = now.getTime() - windowMinutes * 60_000;
282
+ return readFileSync(path, 'utf8').split('\n').flatMap(line => {
283
+ if (!line.trim()) return [];
284
+ try {
285
+ const parsed = JSON.parse(line) as GateObservation;
286
+ const at = Date.parse(parsed.at);
287
+ if (!Number.isFinite(at) || at < floor || at > now.getTime()) return [];
288
+ if (parsed.level !== null && parsed.level !== 'L1' && parsed.level !== 'L2') return [];
289
+ return [parsed];
290
+ } catch { return []; }
291
+ });
292
+ }
293
+
294
+ /** Read the dispatch ledger verbatim journal; torn lines are skipped, kept only for forensics. */
295
+ export function readDispatchLedger(root: string, now: Date, windowMinutes = 1440): DispatchCycle[] {
296
+ const path = join(root, 'orchestrator', 'dispatch-ledger.jsonl');
297
+ if (!existsSync(path)) return [];
298
+ const floor = now.getTime() - windowMinutes * 60_000;
299
+ return readFileSync(path, 'utf8').split('\n').flatMap(line => {
300
+ if (!line.trim()) return [];
301
+ try {
302
+ const parsed = JSON.parse(line) as DispatchCycle;
303
+ const at = Date.parse(parsed.at);
304
+ if (!Number.isFinite(at) || at < floor || at > now.getTime()) return [];
305
+ return [parsed];
306
+ } catch { return []; }
307
+ });
308
+ }
309
+
310
+ /** Gate-halted minutes: gate-active spans where the verbatim ledger shows zero launch attempts AND the gate's
311
+ * own skip reason (degraded-skip) — a gate-active span with no demand is not halted time. */
312
+ export function gateHaltedLaunchMinutes({ gate, ledger }: {
313
+ gate: readonly GateObservation[];
314
+ ledger?: readonly DispatchCycle[];
315
+ }): { minutes: number; launchAttempts: number; haltedTicks: number; activeObservations: number } {
316
+ const points = gate.map(observation => ({ observation, t: Date.parse(observation.at) }))
317
+ .filter(point => Number.isFinite(point.t)).sort((a, b) => a.t - b.t);
318
+ const cycles = (ledger ?? []).map(cycle => ({ cycle, t: Date.parse(cycle.at) }))
319
+ .filter(entry => Number.isFinite(entry.t));
320
+ let minutes = 0;
321
+ let launchAttempts = 0;
322
+ let haltedTicks = 0;
323
+ let activeObservations = 0;
324
+ for (const point of points) {
325
+ if (point.observation.level !== null) activeObservations++;
326
+ }
327
+ for (let i = 1; i < points.length; i++) {
328
+ if (points[i].observation.level === null || points[i - 1].observation.level === null) continue;
329
+ const from = points[i - 1].t;
330
+ const to = points[i].t;
331
+ const inSpan = cycles.filter(entry => entry.t >= from && entry.t <= to);
332
+ const attempts = inSpan.reduce((sum, entry) => sum + entry.cycle.eligible, 0);
333
+ // Only the ledger's own skip reason proves the gate stopped launches: eligible is structurally 0 while the
334
+ // gate skips, so attempts === 0 alone would also count zero-demand spans as «halted» (Goodhart).
335
+ const gateSkipped = inSpan.reduce((sum, entry) => sum + (entry.cycle.skipped['degraded-skip'] ?? 0), 0);
336
+ launchAttempts += attempts;
337
+ if (attempts === 0 && gateSkipped > 0) {
338
+ haltedTicks++;
339
+ minutes += Math.max(0, (to - from) / 60_000);
340
+ }
341
+ }
342
+ return { minutes, launchAttempts, haltedTicks, activeObservations };
343
+ }
344
+
231
345
  if (import.meta.main) {
232
346
  try {
233
347
  const args = process.argv.slice(2);
348
+ if (args.includes('--metrics')) {
349
+ if (args.some(arg => arg !== '--metrics' && arg !== '--json'))
350
+ throw new Error('usage: traffic.ts [--version <판>] [--json] | --metrics [--json]');
351
+ const root = effectiveInstanceRoot();
352
+ const now = new Date();
353
+ const observation = observeGateHalt(root);
354
+ const gate = gateHaltedLaunchMinutes({ gate: readGateObservations24h(root, now), ledger: readDispatchLedger(root, now) });
355
+ const traffic = computeTrafficMetrics24h(readTrafficSamples24h(root, now));
356
+ const report = { at: now.toISOString(), version: devVersion().replace(/-dev\.\d+$/, ''), traffic,
357
+ gate: { ...gate, observation } };
358
+ if (args.includes('--json')) console.log(JSON.stringify(report));
359
+ else {
360
+ const wait = traffic.meanWaitMinutes === null ? '?' : `${traffic.meanWaitMinutes}분`;
361
+ console.log(`traffic-24h utilization=${traffic.utilizationRate} (${traffic.running}/${traffic.capacity}) · mean-wait=${wait} (표본 ${traffic.waitSamples}) · preemptions=${traffic.preemptedSeatTicks} · gate-halt=${gate.minutes}분 (발사시도 ${gate.launchAttempts}) · ticks=${traffic.sampledTicks} · window=${traffic.windowMinutes}분`);
362
+ }
363
+ } else {
234
364
  const versionFlag = args.indexOf('--version');
235
365
  const version = versionFlag < 0 ? devVersion().replace(/-dev\.\d+$/, '') : args[versionFlag + 1];
236
366
  if (!version || version.startsWith('--')
@@ -253,6 +383,7 @@ if (import.meta.main) {
253
383
  });
254
384
  if (args.includes('--json')) console.log(JSON.stringify({ ...result, mode: cfg.trafficMode, queued, version, authorShadow }));
255
385
  else console.log(trafficLine(result, cfg.trafficMode));
386
+ }
256
387
  } catch (error) {
257
388
  console.error(`traffic: ${error instanceof Error ? error.message : String(error)}`);
258
389
  process.exitCode = 1;
@@ -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 칸.
@@ -1132,10 +1132,9 @@ export interface StaleOpenerCheck {
1132
1132
  }
1133
1133
 
1134
1134
  /** 설치 checkout의 Git 객체 그래프에서 선후를 확인한다. 알 수 없으면 다른 판으로 남긴다. */
1135
- function revisionRelation(openerSha: string | null | undefined, installedSha: string | null): StaleOpenerCheck['revisionRelation'] {
1135
+ function revisionRelation(openerSha: string | null | undefined, installedSha: string | null, root = resolve(dirname(fileURLToPath(import.meta.url)), '../../..')): StaleOpenerCheck['revisionRelation'] {
1136
1136
  if (!openerSha || !installedSha) return 'different';
1137
1137
  if (openerSha === installedSha) return 'same';
1138
- const root = resolve(dirname(fileURLToPath(import.meta.url)), '../../..');
1139
1138
  const ancestor = (from: string, to: string): boolean =>
1140
1139
  spawnSync('git', ['-C', root, 'merge-base', '--is-ancestor', from, to], { timeout: 2_000, stdio: 'ignore' }).status === 0;
1141
1140
  if (ancestor(openerSha, installedSha)) return 'older';
@@ -1167,17 +1166,17 @@ export interface StaleOpenerAlert {
1167
1166
  * 전 경로 fail-soft — 수호자가 retention 을 절대 깨지 않는다. */
1168
1167
  export function alertStaleLogDbOpeners(
1169
1168
  dbPath: string,
1170
- deps: { openers?: () => LogDbOpenerInfo[]; installedAtMs?: number | null } = {},
1169
+ deps: { openers?: () => LogDbOpenerInfo[]; installedAtMs?: number | null; installedRoot?: string } = {},
1171
1170
  ): StaleOpenerAlert[] {
1172
1171
  const alerts: StaleOpenerAlert[] = [];
1173
1172
  try {
1174
1173
  // must-fix: 옛 판 판정 마커는 모듈 파일 mtime 이 아니라 «설치 sha 의 설치 시점»이다.
1175
- const marker = resolveInstalledRevisionMarker();
1174
+ const marker = resolveInstalledRevisionMarker(deps.installedRoot);
1176
1175
  const installedAtMs = deps.installedAtMs ?? marker.installedAtMs;
1177
1176
  const openers = (deps.openers ?? (() => scanLogDbOpeners(dbPath)))();
1178
1177
  for (const opener of openers) {
1179
1178
  const relation = opener.revisionSha && marker.sha
1180
- ? revisionRelation(opener.revisionSha, marker.sha) : undefined;
1179
+ ? revisionRelation(opener.revisionSha, marker.sha, deps.installedRoot) : undefined;
1181
1180
  if (relation === 'different') {
1182
1181
  debug.log('log-store.retention', 'different-opener-alert', {
1183
1182
  pid: opener.pid, db: dbPath, openerSha: opener.revisionSha, installedSha: marker.sha,
@@ -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',
@@ -6,7 +6,8 @@ import { parse as parseYaml } from 'yaml';
6
6
  import { elanousStateRoot } from '../../autopilot/state-paths.js';
7
7
  import { debug } from '../../debug/log.js';
8
8
  import { defaultGraphsDir, loadGraphTemplatesFrom } from '../../self-implement/graph-templates.js';
9
- import { loadGraphTemplates } from '../../self-implement/graph-yaml.js';
9
+ import { graphVersionHash, loadGraphTemplates, parseGraphTemplateYaml } from '../../self-implement/graph-yaml.js';
10
+ import { flattenGraphTemplate } from '../../self-implement/graph-unit-resolver.js';
10
11
  import { validateGraphYaml } from './graph-kinds.js';
11
12
  import { parseWizardSteps, readWizardSteps, withWizardSteps } from '../../graph-wizard/saved-steps.js';
12
13
  import type { WizardNodeStep } from '../../graph-wizard/steps.js';
@@ -115,7 +116,7 @@ export async function handleGraphAccessPut(pathname: string, req: Request, deps:
115
116
 
116
117
  /** The peer token works only on this graph and the requested read/edit operation. */
117
118
  export function graphAccessForRequest(pathname: string, method: string, token: string | null, deps: GraphsApiDeps = {}): boolean {
118
- const match = /^\/v1\/graphs\/([^/]+)(?:\/(yaml))?$/.exec(pathname);
119
+ const match = /^\/v1\/graphs\/([^/]+)(?:\/(yaml|flat))?$/.exec(pathname);
119
120
  const id = match ? resolveId(match[1]!) : null;
120
121
  if (!id || !token || !TOKEN_PATTERN.test(token)) return false;
121
122
  if (method !== 'GET' && !(method === 'PUT' && match?.[2] === 'yaml')) return false;
@@ -266,7 +267,7 @@ export function handleGraphsGet(pathname: string, dir = defaultGraphsDir(), deps
266
267
  return jsonResponse({ graphs: [...(core.ok ? core.graphs : []), ...mine.filter((graph) => !coreIds.has(graph.id))] });
267
268
  }
268
269
 
269
- const yamlMatch = /^\/v1\/graphs\/([^/]+)\/yaml$/.exec(pathname);
270
+ const yamlMatch = /^\/v1\/graphs\/([^/]+)\/(yaml|flat)$/.exec(pathname);
270
271
  if (yamlMatch) {
271
272
  const id = resolveId(yamlMatch[1]!);
272
273
  if (!id) return jsonResponse({ error: 'bad_request', reason: 'invalid graph id' }, 400);
@@ -274,6 +275,24 @@ export function handleGraphsGet(pathname: string, dir = defaultGraphsDir(), deps
274
275
  const coreHit = core.ok ? indexByDeclaredId(coreDir).get(id) : undefined;
275
276
  const hit = mineHit ?? coreHit;
276
277
  if (!hit) return jsonResponse({ error: 'not-found', id }, 404);
278
+ if (pathname.endsWith('/flat')) {
279
+ const parsed = parseGraphTemplateYaml(hit.text, hit.file);
280
+ const spec = parsed.template;
281
+ if (!spec || parsed.errors.length) return jsonResponse({ error: 'invalid-graph', id, issues: parsed.errors }, 422);
282
+ try {
283
+ const flat = flattenGraphTemplate(spec, join(mineHit ? mineDir : coreDir, hit.file));
284
+ return jsonResponse({
285
+ id, source: mineHit ? 'mine' : 'core', editable: false,
286
+ entry_node: flat.entryNode,
287
+ terminal_nodes: flat.terminalNodes,
288
+ graph_hash: graphVersionHash(flat),
289
+ nodes: flat.nodes.map(({ nodeId, kind, recipe, maxVisits }) => ({ node_id: nodeId, kind, recipe, max_visits: maxVisits })),
290
+ edges: flat.edges.map(({ from, to, on, map, fallback }) => ({ from, ...(to === undefined ? {} : { to }), ...(on === undefined ? {} : { on }), ...(map === undefined ? {} : { map }), ...(fallback === undefined ? {} : { fallback }) })),
291
+ });
292
+ } catch (error) {
293
+ return jsonResponse({ error: 'unit-flatten-failed', id, message: error instanceof Error ? error.message : String(error) }, 422);
294
+ }
295
+ }
277
296
  const steps = mineHit ? readWizardSteps(mineDir, id, hit.text) : null;
278
297
  return jsonResponse({ id, source: mineHit ? 'mine' : 'core', editable: Boolean(mineHit), yaml: hit.text, ...(steps ? { steps } : {}) });
279
298
  }
@@ -3004,7 +3004,7 @@ export async function routeRequest(
3004
3004
  return handleGraphAccess(pathname, req);
3005
3005
  }
3006
3006
  // F-M1 read + P-F1 raw YAML. Writes live in the mutation block and never touch core graphs/.
3007
- if (method === 'GET' && (pathname === '/v1/graphs' || /^\/v1\/graphs\/[^/]+$/.test(pathname) || /^\/v1\/graphs\/[^/]+\/yaml$/.test(pathname))) {
3007
+ if (method === 'GET' && (pathname === '/v1/graphs' || /^\/v1\/graphs\/[^/]+$/.test(pathname) || /^\/v1\/graphs\/[^/]+\/(?:yaml|flat)$/.test(pathname))) {
3008
3008
  return handleGraphsGet(pathname);
3009
3009
  }
3010
3010
  if (method === 'GET' && /^\/v1\/graphs\/[^/]+\/versions$/.test(pathname)) {
@@ -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 }));
@@ -221,6 +221,18 @@ export function handleOpsApi(req: Request, metaApi: MetaApiOpts | undefined): Re
221
221
  ? served(jsonResponse(resourcesFromOverview(peeked.snapshot, peeked.pods, peeked.at)))
222
222
  : served(jsonResponse({ stale: true })));
223
223
  }
224
+ if (pathname === '/v1/ops/loops-map') {
225
+ // LOOP-MAP-API — projects only the shared overview cache's loops snapshot
226
+ // (name·era·beat cell observedAt; null/unmeasured value and reason preserved);
227
+ // no new remote fan-out of its own. Loop-edge joining is a later shard.
228
+ overviewCache ??= createOverviewCache();
229
+ return overviewCache.get()
230
+ .then((overview) => served(jsonResponse({
231
+ generatedAt: overview.generatedAt,
232
+ cacheAgeMs: overview.cacheAgeMs,
233
+ loops: overview.loops.map((loop) => ({ name: loop.name, era: loop.era, beat: loop.beat })),
234
+ })), () => jsonResponse({ error: 'overview-unavailable' }, 500));
235
+ }
224
236
  if (pathname === '/v1/ops/seats') {
225
237
  const date = url.searchParams.get('date') ?? todayKst();
226
238
  if (!DATE.test(date) || Number.isNaN(Date.parse(`${date}T00:00:00+09:00`))) return jsonResponse({ error: 'invalid-date' }, 400);
@@ -1,3 +1,7 @@
1
+ import { debug } from '../debug/log.js';
2
+ import { classifyLedgerRun, queryUsageOutcomes, type UsageOutcomesDeps } from '../budget/usage-outcomes.js';
3
+ import { loadRunLedger } from '../self-implement/run-ledger.js';
4
+
1
5
  export type ClaudePtyMaturity =
2
6
  | { readonly mature: true }
3
7
  | { readonly mature: false; readonly why: 'too-few-samples' | 'completion-below-70' | 'unknown-screen-above-10' | 'intervention-above-0.2' | 'sample-unreadable' };
@@ -9,6 +13,68 @@ export type ClaudePtyMaturitySample = {
9
13
  readonly interventionCount: number;
10
14
  };
11
15
 
16
+ /** Read the latest Claude PTY runs from the run ledger without changing the ledger or fallback path. */
17
+ export function collectClaudePtyMaturitySample(
18
+ deps: UsageOutcomesDeps & { readonly limit?: number },
19
+ ): ClaudePtyMaturitySample | null {
20
+ const limit = deps.limit ?? 10;
21
+ const nowMs = deps.nowMs ?? Date.now();
22
+ let runCount = 0;
23
+ let completedCount = 0;
24
+ let readable = Number.isSafeInteger(limit) && limit > 0;
25
+ let sample: ClaudePtyMaturitySample | null = null;
26
+
27
+ if (readable) {
28
+ const ledgers: { readonly runId: string; readonly entries: NonNullable<ReturnType<NonNullable<UsageOutcomesDeps['load']>>> }[] = [];
29
+ const load = deps.load ?? loadRunLedger;
30
+ try {
31
+ // The maturity sample is over the latest runs, not over a recent time window.
32
+ // Number.MAX_SAFE_INTEGER days covers the full JavaScript Date range.
33
+ const report = queryUsageOutcomes(Number.MAX_SAFE_INTEGER, {
34
+ ...deps,
35
+ load: (runId, dir, read) => {
36
+ const entries = load(runId, dir, read);
37
+ if (entries) ledgers.push({ runId, entries });
38
+ return entries;
39
+ },
40
+ });
41
+ const runs = ledgers.flatMap(({ runId, entries }) => {
42
+ const classified = classifyLedgerRun(entries, nowMs);
43
+ return classified?.provider === 'claude-pty' ? [{ runId, entries, classified }] : [];
44
+ }).sort((left, right) => right.classified.atMs - left.classified.atMs || right.runId.localeCompare(left.runId))
45
+ .slice(0, limit);
46
+ runCount = runs.length;
47
+ completedCount = runs.filter(({ classified }) => classified.outcome === 'landed').length;
48
+ readable = report.unreadableLedgers === 0 && runs.every(({ entries }) => {
49
+ const hasUnknownScreens = entries.some((entry) => Object.hasOwn(entry.data, 'claudePtyUnknownScreens'));
50
+ const hasInterventions = entries.some((entry) => Object.hasOwn(entry.data, 'humanInterventions'));
51
+ const unknownScreens = entries.find((entry) => Object.hasOwn(entry.data, 'claudePtyUnknownScreens'))?.data.claudePtyUnknownScreens;
52
+ const interventions = entries.find((entry) => Object.hasOwn(entry.data, 'humanInterventions'))?.data.humanInterventions;
53
+ return hasUnknownScreens && hasInterventions
54
+ && typeof unknownScreens === 'number' && Number.isSafeInteger(unknownScreens) && unknownScreens >= 0
55
+ && typeof interventions === 'number' && Number.isSafeInteger(interventions) && interventions >= 0;
56
+ });
57
+ if (readable) {
58
+ sample = runs.reduce<ClaudePtyMaturitySample>((total, { entries }) => {
59
+ const unknownScreens = entries.find((entry) => Object.hasOwn(entry.data, 'claudePtyUnknownScreens'))!.data.claudePtyUnknownScreens as number;
60
+ const interventions = entries.find((entry) => Object.hasOwn(entry.data, 'humanInterventions'))!.data.humanInterventions as number;
61
+ return {
62
+ runCount: total.runCount + 1,
63
+ completedCount: total.completedCount,
64
+ unknownScreenCount: total.unknownScreenCount + unknownScreens,
65
+ interventionCount: total.interventionCount + interventions,
66
+ };
67
+ }, { runCount: 0, completedCount, unknownScreenCount: 0, interventionCount: 0 });
68
+ }
69
+ } catch {
70
+ readable = false;
71
+ }
72
+ }
73
+
74
+ debug.log('oauth.claude-pty', 'maturity-sample', { runCount, completedCount, readable });
75
+ return readable ? sample : null;
76
+ }
77
+
12
78
  /** 최근 런의 계수만 판정한다. 표본을 못 읽거나 계수가 불가능하면 성숙으로 추정하지 않는다. */
13
79
  export function judgeClaudePtyMaturity(sample: ClaudePtyMaturitySample | null | undefined): ClaudePtyMaturity {
14
80
  if (!sample || ![sample.runCount, sample.completedCount, sample.unknownScreenCount, sample.interventionCount]