elanous 0.2.36 → 0.2.38

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 (741) 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/{uC-N0emedeNOFuaBQFv-I → RrjXTwz-urRAbChP1bX02}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{9250-072df22eaadaa6b5.js → 1026-44010f405704050c.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1118.a8a74ea29aac3e46.js +27 -0
  6. package/apps/pwa/out/_next/static/chunks/1204-2aa830479adf80f4.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1341-43b7d2dc77d45c9d.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1440-c3ea8882badfd9bf.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/{4304.e9b2512834a9e23e.js → 1632.7d87f998e714bede.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/1698-9c11cbf97f13717e.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1770-3b1fc92253ef9f2f.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/1923-5c1695332240246a.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1938.0e6c60ee91c4d7f5.js +148 -0
  14. package/apps/pwa/out/_next/static/chunks/{7784.1f0ac4a16d190cf4.js → 2104.70e086d5174a4736.js} +1 -1
  15. package/apps/pwa/out/_next/static/chunks/213-20675f20673ba22a.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/{6566.926a1d1b7c911442.js → 214.186a430da28338f1.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/2277.3bd4c0ac7f1b5996.js +93 -0
  18. package/apps/pwa/out/_next/static/chunks/240.e09f433f71c78ff4.js +104 -0
  19. package/apps/pwa/out/_next/static/chunks/{5711.957b095705c12560.js → 2415.738b777642a02233.js} +1 -1
  20. package/apps/pwa/out/_next/static/chunks/2417.02151393605a7cd0.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2463.cd2641a76daaa9ff.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2576.b9e9c629c4b84c52.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/265-c021de53f0865bd9.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2998-b1cc13956cd6a6e7.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2e4782d3.ba2f0ab2b63a53e7.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/{4286.b70c4520306817e8.js → 3086.fb14b60ce98b53d3.js} +1 -1
  27. package/apps/pwa/out/_next/static/chunks/{3148-98efd4869d660a87.js → 3124-561f7f037943cde2.js} +1 -1
  28. package/apps/pwa/out/_next/static/chunks/3130.626b54382b4dc379.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/3221-1bb3f99a55088613.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/3280.24edb1ffd03a7f3f.js +24 -0
  31. package/apps/pwa/out/_next/static/chunks/3288-eb3c22a1cbf2ae68.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{3727.7949ccaacaa71242.js → 3291.f6c1005387d514bd.js} +2 -2
  33. package/apps/pwa/out/_next/static/chunks/33.ef99e8374f96c6c4.js +36 -0
  34. package/apps/pwa/out/_next/static/chunks/3341-f09b9efbd7a82f70.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/3389.012c70767a872f9b.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3410-d7c0f14b329d6fda.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3421.c87d6313a7d670f7.js +287 -0
  38. package/apps/pwa/out/_next/static/chunks/3422-83a3953f9bd67e26.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/{8904.7d51af2dc033965c.js → 3528.e4b8ab70d339f965.js} +2 -2
  40. package/apps/pwa/out/_next/static/chunks/3587-002e24e368c515a9.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3644.f12a7d821ab940af.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/3660.d7516588e2d875c3.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3695.b82e2610f4cd4ea9.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/3858.ca1f5bc0f577eac9.js +94 -0
  45. package/apps/pwa/out/_next/static/chunks/3959-e6ac4a139d9d4bcc.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/3f0de3de-2340c532c00395db.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4032.53f62176514ec0ea.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/{3031-85328a92fcce4da6.js → 4199-f7c6eb40cd0322f8.js} +1 -1
  49. package/apps/pwa/out/_next/static/chunks/4204-ef8484cbecd5d62f.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4259-163129ca79913c4b.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/428-eaa77df3d0c85969.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4432-97e400ffa1e161f5.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/449-aa427cf2cbb75f50.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4491-39a0fd32bbaf3840.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/4588.b7cf06d382953979.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/4690.70ec8060825366ab.js +32 -0
  57. package/apps/pwa/out/_next/static/chunks/4804.6012b5cd33c22792.js +90 -0
  58. package/apps/pwa/out/_next/static/chunks/4881.e4d22d730e3b9df5.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/4937.ce2e340dc29cad3e.js +79 -0
  60. package/apps/pwa/out/_next/static/chunks/5-bb1c08d84bd71df3.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5005.de98df23b37cdf3c.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5035.dc64a89cad5573cc.js +74 -0
  63. package/apps/pwa/out/_next/static/chunks/5041-5aada92ca215ffdd.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/{528.38ce20ef8aa251ff.js → 5203.51e5d8b5f1dcfe53.js} +16 -16
  65. package/apps/pwa/out/_next/static/chunks/5207.1a224035455790fd.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5255-1b60d50eabe9f057.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5269.d0436ee6d773382a.js +286 -0
  68. package/apps/pwa/out/_next/static/chunks/5300.677c97e0393742e6.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/{2683.c9773a0c589b031b.js → 5307.d7328020227880c2.js} +4 -4
  70. package/apps/pwa/out/_next/static/chunks/5309.3367c4d50f52b489.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/552-689827d49780fa00.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/5539.34cc9d60622cb69b.js +8 -0
  73. package/apps/pwa/out/_next/static/chunks/5568.218dea0c00ca2ec7.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/{552.b7d061ad91eeac51.js → 5638.107314dc479e2f37.js} +2 -2
  75. package/apps/pwa/out/_next/static/chunks/5645.b7e3b055455a04ea.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/5662.18cc0f30353cbd96.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/5671.da24fc9dc5e98325.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/5b141171.324c40fd49cb6821.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6142.913b44e260a3f925.js +64 -0
  80. package/apps/pwa/out/_next/static/chunks/6175-d4621f6a10b0cfab.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6290.3eb53a20746b72ce.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6415-9307f3eafa90837f.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/{6925.562d532110879886.js → 6493.27ad77de7aac7966.js} +1 -1
  84. package/apps/pwa/out/_next/static/chunks/6579-3de35d00aacd71b5.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/680-2f324c4e039a5b67.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/6845-331b3c7481da3ba3.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7000.28157393caaf5343.js +62 -0
  88. package/apps/pwa/out/_next/static/chunks/{275-02ea4c2a33980422.js → 7161-8f22db3ec5ed005e.js} +3 -3
  89. package/apps/pwa/out/_next/static/chunks/7311-60a7ea80d23c7521.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7401.525d0a12f7d02c06.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7438.c2cf72b66dca6aa4.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{3136.30aaaa5fa03662a3.js → 7488.966b116789f3d41a.js} +1 -1
  93. package/apps/pwa/out/_next/static/chunks/{4116.a84a92a2492c080e.js → 7524.ce973525d30b3d52.js} +1 -1
  94. package/apps/pwa/out/_next/static/chunks/7573.2376e13c9c21f1f8.js +77 -0
  95. package/apps/pwa/out/_next/static/chunks/7577.ea6e9ac72e035520.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/{3324.a09703033abcbd2f.js → 7628.6b16863ac3972333.js} +1 -1
  97. package/apps/pwa/out/_next/static/chunks/7657.8d1fb3d2f7ebe273.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7903-1435d5d2f0dd7807.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/{3410.7f9af5ab77cbe65f.js → 7954.4f7a8832663ee979.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/7978-30a91192c5dbe3c2.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/{771.c3cdb6c1f7f47c02.js → 8019.21ca554a821dad01.js} +16 -16
  102. package/apps/pwa/out/_next/static/chunks/8025-8795821525cf1a07.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8191.3674a00f0b565c23.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8217-604955d8885c5ef2.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8298-eed6f5f2585a63f4.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/{4615.8525eb0add35eba6.js → 8487.291666583bebe640.js} +1 -1
  107. package/apps/pwa/out/_next/static/chunks/8509.3a54d4e61893d7cb.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8758.ac421f726a189125.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/{6943.c6b24124853a47b2.js → 8879.ac06755bcf3e44a1.js} +1 -1
  110. package/apps/pwa/out/_next/static/chunks/891.d6c723a51a067b36.js +149 -0
  111. package/apps/pwa/out/_next/static/chunks/{575.d929793a53f27c4b.js → 8911.bf5e712acb25fb6c.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/{9f31e478.fefcbcd3c388ebc5.js → 8994d93e.33ba491f95345fc2.js} +1 -1
  113. package/apps/pwa/out/_next/static/chunks/{da5ecc5c-b005ad8cac737d57.js → 89d6c04f-6b8ab341748e468a.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/{599.c39c571b6733f2a2.js → 9223.cbcc88e0e9950426.js} +2 -2
  115. package/apps/pwa/out/_next/static/chunks/9299.24e2a7d9b6d1f91b.js +226 -0
  116. package/apps/pwa/out/_next/static/chunks/9317.6a9869039c231bb3.js +24 -0
  117. package/apps/pwa/out/_next/static/chunks/9383.e4755f275b3c11ff.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{8037.e254fd797aa224d1.js → 9581.da63ddf41acfad46.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/9715.8c5529a0a5c41a36.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9817.3009d65f0889ef1f.js +2 -0
  121. package/apps/pwa/out/_next/static/chunks/{ceba0382.650712b56b85b582.js → 9fe1b809.738da85c8b17e3fb.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76873dd80da4f715.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed32b6ec5dea8f23.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-fdd40e15babf3d25.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-384efc78e85e400b.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-866aac5ff226a7f3.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-d91809c5aeed319a.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-128f3522f89a81ab.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-595961abf3b43ad1.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-f41dccb76d8c0263.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-a3205c2e28b7d0d9.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-c39a80277814a3f4.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-1ab3f98194513195.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-a5246f7e254d77d0.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-0f92287bdb81217d.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-5a37131ff63793ef.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-76873dd80da4f715.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-ac4bd14bb2348bfd.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-c348a3959c5b5fc6.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-2addd81c0d3e2906.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-da6b765f58a3eefb.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-0661e40f8780c32c.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-b89af1b1c8e4875b.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-da8aeb82ba751cdb.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-cc71317b239439db.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-bde7fc1d64ffe369.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-e2797214f713fa58.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-2a35bcda70defaf6.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3af03deedde45032.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-d1d1210f99f620ae.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-46d1b5500885861d.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/{page-e7abc34a48a6f71e.js → page-291ab19fe2acb173.js} +1 -1
  153. package/apps/pwa/out/_next/static/chunks/app/page-7f569e533ddeecba.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-990129c9fee46d8f.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-7737f785ebb1cdaf.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9f3c73a4f7ffd2f8.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-03be7fb347f01058.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-96b0280625e4df2b.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-56855545049eb56d.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-76873dd80da4f715.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-79a909c9981f0338.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-a9d9a3e66459c1e0.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c383cbf2013f7069.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f57c6a2e54dbdca4.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/{page-c15958835534404b.js → page-6b140f77593576eb.js} +1 -1
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-6b767ae2d9d0adfc.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-116d6198d5da0e3d.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-b9c9b778c7501370.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-a6c78392ab8f6335.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-455183deb4ed0cfe.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6a63e99526bd63d0.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-31c22caafe788c08.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{3a3d9966.cc4d4585a2708e7c.js → b7459770.6539b11860eb8a9c.js} +7 -7
  174. package/apps/pwa/out/_next/static/chunks/{053a429e.9a63436527cc751c.js → b7478fef.5917716286213fcc.js} +3 -3
  175. package/apps/pwa/out/_next/static/chunks/bb6987f9.3647e1a23b0e3217.js +122 -0
  176. package/apps/pwa/out/_next/static/chunks/{2812ca6a.3b9f4a7a08885744.js → de8b930d.d94c0f42acf807fc.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/{873d6c12.09bd499f57171543.js → eaad0cba.771200940c529df7.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/framework-4b12a946f352cee2.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-941155250ed2644b.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-f8b6765abed6d149.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-78432194c85388f9.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-cdf7390829512b1b.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-d5f0964a9c2e92d2.js +1 -0
  184. package/apps/pwa/out/_next/static/css/{b5d88eba78a3d7bf.css → be9019f696217521.css} +1 -1
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +23 -23
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +23 -23
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +23 -23
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +22 -22
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +22 -22
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +23 -23
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +22 -22
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +23 -23
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +23 -23
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +22 -22
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +23 -23
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +23 -23
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +23 -23
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +23 -23
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +22 -22
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +22 -22
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +23 -23
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +23 -23
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +23 -23
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +22 -22
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +22 -22
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +23 -23
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +23 -23
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +22 -22
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +22 -22
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +22 -22
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +23 -23
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +23 -23
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +22 -22
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +23 -23
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +23 -23
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +23 -23
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +23 -23
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +23 -23
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +22 -22
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +23 -23
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +23 -23
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +23 -23
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +23 -23
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +23 -23
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +23 -23
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +23 -23
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +23 -23
  278. package/graphs/drafts/recipes.yaml +27 -7
  279. package/graphs/release/recipes.yaml +9 -0
  280. package/graphs/release/release-loop.yaml +26 -18
  281. package/graphs/work/draft-close.yaml +54 -0
  282. package/graphs/work/green-close.yaml +37 -0
  283. package/graphs/work/recipes.yaml +46 -1
  284. package/graphs/work/run-research.yaml +35 -0
  285. package/package.json +1 -1
  286. package/scripts/__fixtures__/authoring-paths-10x3.json +32 -0
  287. package/scripts/ask-op-inbox-once.ts +17 -0
  288. package/scripts/boundary-proof-mapping-audit.ts +88 -0
  289. package/scripts/brand/check.ts +13 -4
  290. package/scripts/codex-fallback-live-probe.ts +17 -15
  291. package/scripts/fleet/node-setup.sh +32 -2
  292. package/scripts/fleet/run-light-worker.sh +9 -0
  293. package/scripts/gate-0226-accepted-remaining-90.txt +91 -0
  294. package/scripts/gate-0226-failure-census.ts +546 -0
  295. package/scripts/goals/authoring-metrics.ts +258 -0
  296. package/scripts/graph-units/draft-close-node.ts +222 -0
  297. package/scripts/hook-order-sweep.ts +7 -4
  298. package/scripts/intake-collect-telegram-saved-stage.ts +48 -0
  299. package/scripts/land-global-checks.ts +69 -1
  300. package/scripts/measure-nl-routing-corpus.ts +207 -2
  301. package/scripts/provision-export-redactions.ts +15 -0
  302. package/scripts/public-copy-lint.ts +122 -0
  303. package/scripts/public-export.ts +69 -2
  304. package/scripts/ratchets/next-tui-entry-budget.ts +124 -0
  305. package/scripts/ratchets/train-side-invariants.sh +7 -1
  306. package/scripts/release-loop/cut-branch.ts +61 -12
  307. package/scripts/release-loop/docs-node.ts +140 -0
  308. package/scripts/release-loop/gate-closure.ts +48 -0
  309. package/scripts/release-loop/gate-diff.ts +2 -1
  310. package/scripts/release-loop/gate-node.ts +161 -25
  311. package/scripts/release-loop/gate-partial.ts +82 -3
  312. package/scripts/release-loop/gate-prewarm-plan.ts +35 -0
  313. package/scripts/release-loop/gate-radius-live.ts +4 -2
  314. package/scripts/release-loop/known-issues-node.ts +6 -4
  315. package/scripts/release-loop/notes-repair.ts +216 -0
  316. package/scripts/release-loop/prepare-node.ts +61 -5
  317. package/scripts/release-loop/resume-cap.ts +2 -1
  318. package/scripts/release-loop/resume-release.ts +406 -7
  319. package/scripts/release-loop/resume-test-traffic.ts +10 -0
  320. package/scripts/release-loop/resume.ts +13 -5
  321. package/scripts/release-loop/traffic-node.ts +12 -4
  322. package/scripts/release-loop/traffic-transition.ts +53 -13
  323. package/scripts/release-loop/version-node.ts +109 -15
  324. package/scripts/train/green-leg.ts +176 -0
  325. package/scripts/tui-continue-real-evidence.ts +47 -0
  326. package/scripts/ux-sim.ts +1 -1
  327. package/scripts/video-pipeline.ts +2 -2
  328. package/src/acp/client.ts +31 -5
  329. package/src/acp/core-turn-bridge.ts +12 -1
  330. package/src/acp/stderr-summary.ts +49 -0
  331. package/src/agent/monad-agent-turn.ts +1 -0
  332. package/src/agent/run-context.ts +1 -1
  333. package/src/agent/task-notification.ts +3 -1
  334. package/src/agent/terminal-surface.ts +217 -0
  335. package/src/agent-substrate/pr-reviewer.ts +11 -3
  336. package/src/agent-substrate/review-observation.ts +10 -0
  337. package/src/agent-substrate/self-review-cli.ts +537 -57
  338. package/src/auto-research/question-ladder-contract.ts +137 -0
  339. package/src/auto-research/research-turn.ts +134 -0
  340. package/src/autopilot/discovery/doc-lint.ts +1 -1
  341. package/src/autopilot/lineage/sources.ts +1 -1
  342. package/src/autopilot/pr-manager.ts +64 -13
  343. package/src/boot/daemon-runtime.ts +35 -3
  344. package/src/boot/daemon-tools/pty-shell.ts +2 -1
  345. package/src/bots/screen-probe.ts +1 -1
  346. package/src/budget/run-usage-rollup.ts +12 -7
  347. package/src/budget/unified-usage.ts +20 -0
  348. package/src/capture/tui-self-report.ts +42 -5
  349. package/src/chat/index.ts +1 -0
  350. package/src/chat/tool-render/dispatch.ts +8 -1
  351. package/src/cli/autopilot-cli.ts +24 -9
  352. package/src/cli/decisions-cli.ts +7 -4
  353. package/src/cli/doctor-cli.ts +116 -7
  354. package/src/cli/guardian-cli.ts +3 -1
  355. package/src/cli/intake-cli.ts +48 -12
  356. package/src/cli/lesson-cli.ts +69 -9
  357. package/src/cli/logs-cli.ts +357 -2
  358. package/src/cli/memory-cli.ts +30 -1
  359. package/src/cli/msg-cli.ts +15 -11
  360. package/src/cli/pr-granularity.ts +5 -3
  361. package/src/cli/pr-land-overlap-evidence.ts +38 -5
  362. package/src/cli/pr-land-refusal.ts +1 -1
  363. package/src/cli/pty-takeover-cli.ts +58 -5
  364. package/src/cli/release-checklist-read-cli.ts +112 -4
  365. package/src/cli/release-cli.ts +89 -18
  366. package/src/cli/review-carry.ts +77 -0
  367. package/src/cli/self-update.ts +24 -6
  368. package/src/cli/self-utterances-cli.ts +13 -16
  369. package/src/cli/tasks-card-show.ts +31 -1
  370. package/src/cli/tasks-cli.ts +370 -33
  371. package/src/cli/tasks-read-cli.ts +13 -5
  372. package/src/cli/usage-cli.ts +12 -10
  373. package/src/context-bus/claude-memory-import.ts +99 -0
  374. package/src/context-bus/context-now.ts +86 -2
  375. package/src/context-bus/long-term-memory.ts +125 -0
  376. package/src/core-turn/run-core-turn.ts +9 -2
  377. package/src/core-turn/run-goal-loop.ts +5 -2
  378. package/src/core-turn/types.ts +5 -0
  379. package/src/dashboard/chat/acp-chat.ts +9 -0
  380. package/src/dashboard/index.ts +115 -30
  381. package/src/dashboard/input/agent-wake.ts +43 -0
  382. package/src/dashboard/input/chat-main-acp-dispatch.ts +21 -1
  383. package/src/dashboard/input/terminal-modal-router.ts +8 -159
  384. package/src/dashboard/replay-preview.ts +25 -0
  385. package/src/dashboard/side-basic-runtime.ts +61 -0
  386. package/src/dashboard/slash-runtime/dashboard-handlers.ts +19 -8
  387. package/src/dashboard/synchronized-frame-output.ts +74 -0
  388. package/src/dashboard/term-slash-runtime.ts +2 -0
  389. package/src/dashboard/turn-preamble.ts +28 -4
  390. package/src/display/coordinator.ts +45 -12
  391. package/src/display/resize-listener.ts +41 -20
  392. package/src/display/synchronized-output-region.ts +60 -0
  393. package/src/domains/guardian-tick.ts +9 -0
  394. package/src/domains/surface-events.ts +80 -1
  395. package/src/exec-requests/planner.ts +37 -2
  396. package/src/execution-loop/launch-gate.ts +4 -3
  397. package/src/git-fs/cli-stderr.ts +45 -0
  398. package/src/git-fs/gh-cli.ts +6 -3
  399. package/src/git-fs/git-cli.ts +11 -5
  400. package/src/git-fs/watcher.ts +27 -22
  401. package/src/git-fs/worktree.ts +19 -3
  402. package/src/graph-runner/graph-cli.ts +26 -2
  403. package/src/graph-runner/graph-grow.ts +37 -9
  404. package/src/graph-runner/graph-run-api.ts +3 -2
  405. package/src/graph-runner/runner.ts +34 -7
  406. package/src/graph-wizard/generate.ts +29 -6
  407. package/src/grok/credential.ts +107 -36
  408. package/src/harness/harness-cli-command.ts +179 -33
  409. package/src/harness/review-adapter.ts +26 -6
  410. package/src/hq/fence-wrapper.ts +1 -1
  411. package/src/hq/transfer.ts +1 -1
  412. package/src/index.ts +151 -18
  413. package/src/instance/test-write-guard-real-transport.fixture.ts +52 -0
  414. package/src/intake-plane/collect-telegram-saved.ts +54 -5
  415. package/src/interactive-terminal-modal.ts +3 -0
  416. package/src/keybindings.ts +17 -22
  417. package/src/llm/provider-credentials.ts +1 -1
  418. package/src/llm/route-decision.ts +13 -0
  419. package/src/llm-tool-name.ts +37 -0
  420. package/src/llm-tool-schema.ts +55 -0
  421. package/src/llm.ts +203 -21
  422. package/src/loops/checker.ts +100 -0
  423. package/src/loops/consensus.ts +26 -2
  424. package/src/loops/loop-cli.ts +9 -4
  425. package/src/loops/orchestrator/anomaly-cluster.ts +243 -0
  426. package/src/loops/orchestrator/inbox-once.ts +28 -0
  427. package/src/loops/orchestrator/inbox.ts +130 -1
  428. package/src/loops/orchestrator/tick.ts +55 -7
  429. package/src/maturity/feature-maturity.ts +1 -0
  430. package/src/model-tier/llm-tier-map.ts +12 -17
  431. package/src/msg/msg-store.ts +17 -0
  432. package/src/native-tool-catalog.ts +1 -1
  433. package/src/nexus/api/channel-ask-op.ts +96 -0
  434. package/src/nexus/api/discord-trigger-bot.ts +28 -1
  435. package/src/nexus/api/graph-wizard-api.ts +27 -2
  436. package/src/nexus/api/grid.ts +24 -4
  437. package/src/nexus/api/http-server.ts +1 -1
  438. package/src/nexus/api/ops-api.ts +14 -6
  439. package/src/nexus/api/telegram-trigger-bot.ts +24 -0
  440. package/src/nexus/api/terminals.ts +28 -6
  441. package/src/nexus/state/state.ts +7 -1
  442. package/src/oauth/codex-account-store.ts +34 -1
  443. package/src/ops/loops-map.ts +46 -0
  444. package/src/ops/overview-cache.ts +22 -4
  445. package/src/ops/overview.ts +41 -5
  446. package/src/patents/ledger.ts +18 -1
  447. package/src/policy/llm-policy.ts +3 -1
  448. package/src/preview/terminal.ts +4 -2
  449. package/src/prompt-cache/anthropic.ts +2 -0
  450. package/src/prompt-enhance/enhance.ts +9 -4
  451. package/src/pty-shell/availability.ts +7 -0
  452. package/src/pty-shell/herdr-agent-report.ts +40 -31
  453. package/src/pty-shell/herdr-prune-stale.ts +17 -0
  454. package/src/pty-shell/herdr-sequence-lease.ts +60 -0
  455. package/src/pty-shell/pty-control-ipc.ts +187 -18
  456. package/src/pty-shell/pty-manifest.ts +16 -2
  457. package/src/pty-shell/registry.ts +25 -15
  458. package/src/pty-shell/tui-run-state.ts +235 -1
  459. package/src/release-loop/checklist.ts +50 -5
  460. package/src/release-loop/feature-store.ts +9 -9
  461. package/src/release-loop/gate-shards.ts +61 -0
  462. package/src/release-loop/landed-but-yellow.ts +93 -12
  463. package/src/release-loop/light-rc.ts +7 -4
  464. package/src/release-loop/rehearsal.ts +1 -1
  465. package/src/repl/index.ts +18 -0
  466. package/src/research/axis-fanout.ts +133 -0
  467. package/src/research/edge-decision.ts +88 -0
  468. package/src/research/output-router.ts +127 -0
  469. package/src/research-bridge/format.ts +16 -1
  470. package/src/research-bridge/index.ts +1 -0
  471. package/src/research-bridge/invoke.ts +41 -5
  472. package/src/seat-loop/seat-report.ts +1 -0
  473. package/src/self-dev/ask-launch-flow.ts +86 -10
  474. package/src/self-dev/decompose-proposal.ts +29 -18
  475. package/src/self-dev/decompose.ts +45 -9
  476. package/src/self-dev/dev-pipeline.ts +29 -7
  477. package/src/self-dev/draft-residue.ts +221 -2
  478. package/src/self-dev/draft-sweep.ts +254 -16
  479. package/src/self-dev/draft-triage-rules.ts +19 -5
  480. package/src/self-dev/orchestrate.ts +1 -0
  481. package/src/self-dev/review-provider-fallback.ts +45 -7
  482. package/src/self-dev/run-supervisor.ts +22 -7
  483. package/src/self-dev/shard-plan.ts +48 -0
  484. package/src/self-dev/shard-run.ts +310 -6
  485. package/src/self-implement/comment-only-source.ts +54 -0
  486. package/src/self-implement/doctor-visit.ts +108 -0
  487. package/src/self-implement/gate-artifacts.ts +6 -2
  488. package/src/self-implement/gate-baseline.ts +99 -1
  489. package/src/self-implement/gate-cli.ts +231 -82
  490. package/src/self-implement/gate-failure-signature.ts +44 -0
  491. package/src/self-implement/gate-remote.ts +30 -4
  492. package/src/self-implement/gate-scope.ts +13 -1
  493. package/src/self-implement/goal-author.ts +407 -21
  494. package/src/self-implement/goal-doc/section.ts +22 -0
  495. package/src/self-implement/goal-supervisor-fill.ts +110 -27
  496. package/src/self-implement/importer-test-index.ts +215 -2
  497. package/src/self-implement/knowhow-pack.ts +125 -12
  498. package/src/self-implement/l8-merge-queue.ts +198 -32
  499. package/src/self-implement/off-diff-evidence.ts +23 -0
  500. package/src/self-implement/orchestrator.ts +369 -33
  501. package/src/self-implement/pod-inplace-worktree.ts +82 -0
  502. package/src/self-implement/pod-warm-pool-profile.ts +2 -2
  503. package/src/self-implement/premise-review.ts +7 -5
  504. package/src/self-implement/review-round-brief.ts +300 -0
  505. package/src/self-implement/rework-policy.ts +14 -0
  506. package/src/self-implement/run-ledger.ts +428 -6
  507. package/src/self-implement/run-stop.ts +1 -1
  508. package/src/self-implement/running-runs.ts +17 -3
  509. package/src/self-implement/seams.ts +45 -16
  510. package/src/self-implement/self-implement-cli.ts +26 -2
  511. package/src/self-implement/stop-autoheal.ts +1 -0
  512. package/src/self-implement/test-seams.ts +13 -1
  513. package/src/self-implement/train-reach-grouping.ts +8 -2
  514. package/src/session/channel-ask-op-envelope.ts +36 -0
  515. package/src/session/channel-op-reply-route.ts +200 -0
  516. package/src/session/chat.ts +10 -1
  517. package/src/session/id-prefix.ts +60 -0
  518. package/src/session/index.ts +6 -0
  519. package/src/session-runtime/index.ts +18 -23
  520. package/src/skills/runner.ts +7 -3
  521. package/src/skills/tools/dev-harness.ts +2 -2
  522. package/src/skills/tools/pty.ts +5 -0
  523. package/src/skills/tools/schedule-wakeup.ts +1 -6
  524. package/src/status/bar.ts +3 -3
  525. package/src/status/metrics.ts +12 -1
  526. package/src/steward/rejudge-tick.ts +12 -5
  527. package/src/steward/resync-tick.ts +31 -4
  528. package/src/storage/file-lock.ts +17 -4
  529. package/src/task-agent/actions.ts +199 -4
  530. package/src/task-agent/adopt-pr.ts +63 -2
  531. package/src/task-agent/boundary-proof-mapping.ts +12 -0
  532. package/src/task-agent/boundary-proof-producer.ts +147 -0
  533. package/src/task-agent/completion-evidence.ts +2 -1
  534. package/src/task-agent/evidence-command-normalize.ts +42 -0
  535. package/src/task-agent/export-redactions-provision.ts +43 -0
  536. package/src/task-agent/green-close-recipe.ts +239 -0
  537. package/src/task-agent/green-sweep.ts +64 -10
  538. package/src/task-agent/live-moves.ts +48 -3
  539. package/src/task-agent/map-host-adapter.ts +134 -0
  540. package/src/task-agent/map-reduce.ts +158 -0
  541. package/src/task-agent/map-run-ledger.ts +226 -0
  542. package/src/task-agent/parent-host.ts +74 -17
  543. package/src/task-agent/rejudge-on-head.ts +72 -5
  544. package/src/task-agent/repair-cycle.ts +108 -8
  545. package/src/task-agent/repair-next-move.ts +12 -2
  546. package/src/task-agent/repair-worker.ts +37 -1
  547. package/src/task-agent/review-prior-fix.ts +12 -2
  548. package/src/task-agent/shadow.ts +188 -5
  549. package/src/task-agent/task-hand.ts +253 -20
  550. package/src/task-agent/task-parent-role-llm.ts +9 -0
  551. package/src/task-agent/tier-split.ts +40 -5
  552. package/src/task-agent/work-order.ts +53 -2
  553. package/src/task-orchestrator/dispatcher.ts +46 -1
  554. package/src/task-orchestrator/generator-prompt.ts +6 -0
  555. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +16 -6
  556. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +31 -4
  557. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +8 -6
  558. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +97 -0
  559. package/src/task-orchestrator/surfaces/pod-pool.ts +77 -8
  560. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +15 -9
  561. package/src/task-orchestrator/surfaces/self-implement-pod.ts +338 -79
  562. package/src/task-orchestrator/surfaces/self-implement.ts +37 -2
  563. package/src/terminal/session-registry.ts +1 -0
  564. package/src/terminal/terminal-modal-router.ts +156 -0
  565. package/src/testing/linux-env.ts +177 -0
  566. package/src/tool-hints/gate.ts +6 -4
  567. package/src/tool-hints/signals.ts +33 -1
  568. package/src/tui/chat/background-job-status.ts +8 -2
  569. package/src/tui/chat/goal-interim.ts +5 -1
  570. package/src/tui/entry.ts +722 -30
  571. package/src/tui/input/at-picker.ts +55 -0
  572. package/src/tui/sidetab/attach.ts +304 -0
  573. package/src/tui/sidetab/list.ts +176 -0
  574. package/src/tui/sidetab/nl-tool.ts +136 -0
  575. package/src/tui/slash/resume-command.ts +23 -0
  576. package/src/tui/slash/resume.ts +38 -35
  577. package/src/tui/slash/signals.ts +114 -0
  578. package/src/tui/slash/term-next.ts +72 -0
  579. package/src/tui-client/local-chat-turn.ts +31 -9
  580. package/src/user-config.ts +30 -3
  581. package/src/ux-sim/boot-daemon-tools-pty-shell-device.ts +136 -0
  582. package/src/ux-sim/classic-tui-seat-scenarios.ts +158 -4
  583. package/src/ux-sim/fake-gh.ts +174 -0
  584. package/src/ux-sim/fake-kubectl.ts +142 -0
  585. package/src/ux-sim/fake-llm.ts +17 -6
  586. package/src/ux-sim/next-tui-seat-scenarios.ts +176 -6
  587. package/src/ux-sim/resume-picker-device.ts +173 -0
  588. package/src/ux-sim/session-id-seed.ts +60 -0
  589. package/src/ux-sim/skills-tools-shell-device.ts +156 -0
  590. package/src/ux-sim/task-agent-parent-host-device.ts +264 -0
  591. package/src/ux-sim/task-agent-rejudge-on-head-device.ts +114 -0
  592. package/src/version/packed-revision.json +1 -1
  593. package/apps/pwa/out/_next/static/chunks/109.f196abf3484bb97f.js +0 -287
  594. package/apps/pwa/out/_next/static/chunks/1201.afbfc5b1c5e5cbe4.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/1517.9275b89572098ff3.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/1574.ad11f8db8396ab45.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/1614.7a8c5c40aee0261f.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/1871-f1eb29d8dbb4065b.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/190.285c832bd9626f8c.js +0 -64
  600. package/apps/pwa/out/_next/static/chunks/2193.0ea24c4a7aa1d004.js +0 -36
  601. package/apps/pwa/out/_next/static/chunks/223-ad865c1e80491d78.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/2265-f0d90b6dbec05f81.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/2267.eb4a62a209f09ec4.js +0 -149
  604. package/apps/pwa/out/_next/static/chunks/2341-86cd06c0cf01aa33.js +0 -1
  605. package/apps/pwa/out/_next/static/chunks/2352.9abc42422bade876.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/2397-c1653a816061842d.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/2500.cbc1257b774aae52.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +0 -24
  609. package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/2941.3c3546f96bc6efa7.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +0 -24
  612. package/apps/pwa/out/_next/static/chunks/2986.45d7652e4f13557e.js +0 -2
  613. package/apps/pwa/out/_next/static/chunks/3155.2587a55196ecb394.js +0 -226
  614. package/apps/pwa/out/_next/static/chunks/3277.785db1cf09f98601.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/3320-f9c77381f85a2c0a.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/3386-91049feabff9a94e.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/339.80afb7e8839372af.js +0 -8
  618. package/apps/pwa/out/_next/static/chunks/3538.a445e50bb359d068.js +0 -32
  619. package/apps/pwa/out/_next/static/chunks/3540c645.2595a6af01a97672.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/3621.581b2054cc14bee4.js +0 -286
  621. package/apps/pwa/out/_next/static/chunks/3676.8c28d16fd84ca843.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/375-b84540853523fe52.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/3757-180308bc61021b05.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +0 -74
  625. package/apps/pwa/out/_next/static/chunks/3840-5825d56d46976a92.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/4067-bf9aa60547972937.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/4176.e5729c93c29151eb.js +0 -104
  629. package/apps/pwa/out/_next/static/chunks/4227-e6c84686bc8946ca.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/4327.b9e08a71c0009348.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/4946.bd106eafd668f248.js +0 -148
  632. package/apps/pwa/out/_next/static/chunks/5085-bce4904931767ca6.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/5125.2eb9968b83767193.js +0 -93
  634. package/apps/pwa/out/_next/static/chunks/5128-75b733fd74a9a1eb.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/5489f3fe.4bb1458b09f6dead.js +0 -122
  636. package/apps/pwa/out/_next/static/chunks/5560-2a4648f6a30f16e7.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/5772-e29e14f8ff127122.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/5887.5b2f5b44ce0f7e9a.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/5899-4c112a2d908cf97f.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/6041.1b65efb796ebc2a5.js +0 -79
  641. package/apps/pwa/out/_next/static/chunks/6057-765c0a26028c86b2.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/6142.f289e0d039f453a6.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/6199-6bcd61d2a3910e04.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/6236.cdf7293e710a9b2d.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/6387-237e079dac9a3ae6.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/6448-b6d272d074276e14.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/6466-92e65a48490b68a9.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/6580-cdc0e4a634ce4708.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/6659-b242dc31b20b3f29.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/6690.c5d9b321b1f79384.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/671-e9b6ad0c771c5514.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/6862.bcbf89dd0f4496b3.js +0 -27
  653. package/apps/pwa/out/_next/static/chunks/6912-7b375ee48732c767.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/727.7deb87749b0a343a.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/7481.39f7a4654907bf6e.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/7545.b1aa42cd15503319.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/7551-416d298c2dc4a9ab.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/7870-309de463786ac1fc.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/7888-e29b151bb6a3bb8b.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/7891.03f910124a737985.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/7905-6ba78d9234608f79.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/8207.f527886b7c464529.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/856.50bda61439d465e6.js +0 -62
  664. package/apps/pwa/out/_next/static/chunks/9031-92e9b487edb681ee.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/9060.5410d9f6a95f6287.js +0 -90
  666. package/apps/pwa/out/_next/static/chunks/914.8abefd48d579547b.js +0 -94
  667. package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/9289.3e92f278821e18e0.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/9319.7816d3cc741cd34f.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/9327-e016bb9f1674d24f.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/9365.3de48bf75193ff9a.js +0 -77
  672. package/apps/pwa/out/_next/static/chunks/9383.5b5e9aa56b5fea97.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/9387-cb929573ef436f39.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/9489.c27becacc3283dec.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/9514.131c52cc75fe6439.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/9536.28962663c7734376.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/9686-12286f5bbf15a5a0.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/9776.289d40cc5a4c342a.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/9789.60f723d18097ec30.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/989.f0c17523c5e61f65.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/9972-1df393aa8d4f7d52.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-96750aba7430959f.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4105e5bbbb043024.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5d4fa75c2acb113e.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/board/page-a79a9bdb3b2142bf.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/botlab/page-f1c2047484992a35.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/app/bots/page-15ffc49b2d8c70e2.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/app/ceo/page-67d53a3fc8734135.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/app/chat/page-e30c8dc696491336.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/app/consult/page-2136e04fa77696e2.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/app/control/page-fecd2814790c2e12.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/app/decisions/page-280aa4a98fc5bb44.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/app/design-check/page-c14e96b65fb4b883.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/app/editor/page-187dac74825ed6bf.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/exec/page-6bc7246ea8c92448.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/field/page-083747f1d4518f61.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/healthz/route-96750aba7430959f.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/inside/page-15ca95a16ec96e1f.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/intake/page-a8ac031b3810eb64.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/app/layout-8835f93110494cda.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/app/live/page-e2de2e59111c9aad.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f2b2e4bf6e981450.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/app/loops/page-5b92b7f75df20948.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/app/market/page-468eddf2b1a84ecb.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-2af16e62c12f22df.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/app/morning/page-18b40867a77a5793.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/app/not-found-fe934f2979f5a4a2.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/app/observatory/page-3eec435537357170.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ff88cbfd2aa99fc8.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-a5b39fb780c70ab5.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ae465dde1d1b3933.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/app/page-cab9674fde9ead26.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1da49bc8712284d0.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5e8aa657551ac912.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/app/sessions/page-fcc36f36c6dc1fe2.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d22db22f2a7296ca.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/app/settings/page-d12dc7b1773878f0.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-99debec9ea7fbec0.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/app/setup/layout-96750aba7430959f.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/app/setup/page-2a088a78bad7e924.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/app/share/page-2e8ed57db7e69993.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/app/showroom/page-4b3a16213c2ae8fe.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f098747ddf38c98b.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/today/page-68279e3c843c1fd7.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/trace/page-a34a74453367a39d.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/vault/page-8767a7db2155a5bd.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-bd5976683460d7f2.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b7364835e7f2ef54.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/workspace/page-311af16b3ee0ffca.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-fb670757274ae990.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/ccae1c4b-0cf414f5eff1b10d.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/f9a61e4d.1fc2c1dbdd49fe46.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/framework-6d497cbf1eef04c6.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/main-app-012f5edec932f337.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/main-da5aeb809edc94a2.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/pages/_app-5ee319af6f749dfe.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/pages/_error-4bc84653a718d6c6.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/webpack-8a96cf6775c73d6e.js +0 -1
  739. package/scripts/migrate-monad-to-elanous.ts +0 -195
  740. package/scripts/rebrand-elanous.ts +0 -242
  741. /package/apps/pwa/out/_next/static/{uC-N0emedeNOFuaBQFv-I → RrjXTwz-urRAbChP1bX02}/_ssgManifest.js +0 -0
@@ -11,19 +11,21 @@ import { getUserConfig, ORCHESTRATOR_DEFAULTS, resolveConfiguredAgentRoleLlm, ty
11
11
  import { rubricPriority } from '../../release-loop/rubric.js';
12
12
  import { debug } from '../../debug/log.js';
13
13
  import { emitLoopHeartbeat } from '../neighbor-runtime.js';
14
+ import { ConsensusEngine } from '../consensus.js';
14
15
  import { listSelfDevRuns, runSummaryLine, selfDevRunsDir } from '../../self-dev/run-store.js';
15
16
  import { planAction, runSeatLoopOnce, type SeatDeps, type SeatItem } from '../../seat-loop/seat-loop.js';
16
17
  import { addHarnessQueue, harnessQueueOutcome, setQueuedPoolHint } from '../../harness/harness-queue.js';
17
18
  import { placeOnGrid, type GridHost } from './grid-place.js';
18
19
  import { checkPodPool, parsePodPool, resolvePodPoolSpec } from '../../task-orchestrator/surfaces/pod-pool.js';
19
20
  import { leaseKubectl } from '../../task-orchestrator/surfaces/pod-lease.js';
21
+ import { defaultAnomalyCluster, extractContainerExit, type AnomalyCluster } from './anomaly-cluster.js';
20
22
  import { isLaunchEligible, isTrafficLaunch, recordDispatchCycle, seatOfTree, type TrafficProcess } from './traffic.js';
21
23
  import { defaultListHarnessProcesses } from '../../harness/harness-cli-command.js';
22
24
  import * as testGuard from '../../instance/test-write-guard.js';
23
25
  import { seatCapDetails } from '../budget.js';
24
26
  export { isLaunchEligible } from './traffic.js';
25
27
  import { readTaskAgentState, TASK_SEATS, type HandTaskOptions, type TaskCard as TaskAgentCard, type HandTaskResult, type TaskLauncher, type TaskSeat } from '../../task-agent/task-hand.js';
26
- import { runCoordinatorAgentInbox, runCoordinatorInbox, type CoordinatorInboxResult } from './inbox.js';
28
+ import { runAskOpContextInbox, runCoordinatorAgentInbox, type CoordinatorInboxResult } from './inbox.js';
27
29
  import type { KnowhowOptions } from './knowhow-pack.js';
28
30
  import { loadAgentRolePack, type AgentReplyInput } from '../agent-reply.js';
29
31
  import type { LLMProvider } from '../../llm.js';
@@ -32,7 +34,7 @@ export type Window = '08' | '12' | '18';
32
34
  export type Node = 'intake' | 'split' | 'place' | 'delegate' | 'launch' | 'reconcile' | 'report';
33
35
  export type Mode = 'off' | 'shadow' | 'live';
34
36
  const SEAT_LOOP_IDS: Readonly<Record<string, string>> = { OP: 'op-seat', MK: 'cmo-seat', TC: 'tc-seat', UX: 'ux-seat' };
35
- export interface Cell { id: string; title: string; kind?: string; seat?: string; host?: string; gridHost?: boolean; version?: string; cardId: string; origin: 'candidate' | 'flow1a'; priority?: 'P0' | 'P1' | 'P2' | 'P3' | 'P4'; predecessors?: string[] }
37
+ export interface Cell { id: string; title: string; kind?: string; seat?: string; host?: string; gridHost?: boolean; version?: string; cardId: string; origin: 'candidate' | 'flow1a'; priority?: 'P0' | 'P1' | 'P2' | 'P3' | 'P4'; predecessors?: string[]; consensusProposalId?: string }
36
38
  export interface TickState {
37
39
  runId: string; window: Window; mode: Mode; day: string;
38
40
  cards: TaskCard[]; skippedCards: Array<{ id: string; reason: string }>; cells: Cell[]; placed: number; unplaced?: number; delegated: number; wouldDelegate: number; rebalanced?: number; rebalanceBlocked?: Array<{ id: string; reason: string }>;
@@ -58,7 +60,7 @@ export interface TickState {
58
60
  missing: string[];
59
61
  }
60
62
  /** FLOW1a contract: with `{ shadow: true }` the splitter only proposes cells and writes nothing (cards, ledgers, LLM side effects excepted). */
61
- export type SplitAdapter = (card: TaskCard, opts?: { shadow?: boolean }) => Promise<Array<{ id: string; title: string; kind?: string; seat?: string; host?: string }>> | Array<{ id: string; title: string; kind?: string; seat?: string; host?: string }>;
63
+ export type SplitAdapter = (card: TaskCard, opts?: { shadow?: boolean }) => Promise<Array<{ id: string; title: string; kind?: string; seat?: string; host?: string; consensusProposalId?: string }>> | Array<{ id: string; title: string; kind?: string; seat?: string; host?: string; consensusProposalId?: string }>;
62
64
  /** RELPLAN1 `placeCell(input: PlacementCell)` — owner·priority·predecessors are required; the result carries no seat. */
63
65
  export type PlacementInput = { id: string; title: string; owner: string; priority: 'P0' | 'P1' | 'P2'; predecessors: string[] };
64
66
  export type PlaceAdapter = (cell: PlacementInput, deps?: { dryRun?: boolean; now?: Date }) => Promise<{ version?: string } | null> | { version?: string } | null;
@@ -73,6 +75,8 @@ export interface TickDeps {
73
75
  gridHosts?: readonly GridHost[];
74
76
  seatTurn?: (seat: string, root: string, host?: string, options?: Pick<SeatDeps, 'enqueue'>) => Promise<{ status: string; queueId?: string; runId?: string; item?: { source: string; id: string } }>;
75
77
  queueOutcome?: (queueId: string, root: string) => 'pending' | 'unknown' | 'retryable' | 'succeeded';
78
+ /** ANOMALY-CLUSTER — grouping state shared with the dispatcher relaunch gate; defaults to the process-wide instance. */
79
+ anomalyCluster?: AnomalyCluster;
76
80
  /** Snapshot of running harness processes for launch-cap decisions; an unreadable snapshot blocks launches. */
77
81
  launchProcesses?: () => { status: 'ok'; records: readonly TrafficProcess[] } | { status: 'incomplete' };
78
82
  /** 발사 전 대기열 항목의 풀 힌트 갱신(주입 안 하면 harness-queue `setQueuedPoolHint`). */
@@ -93,6 +97,8 @@ export interface TickDeps {
93
97
  coordinatorAgentProvider?: LLMProvider;
94
98
  /** Resident knowhow pack seam; the real intake reads 내부 문서 `KNOWHOW` every tick. */
95
99
  coordinatorKnowhow?: KnowhowOptions | false;
100
+ /** Deterministic read-only ask-op context seam for isolated tick tests. */
101
+ coordinatorContext?: typeof import('../../context-bus/context-now.js').askOpContextBundle;
96
102
  }
97
103
 
98
104
  /** ORCH-TA-HAND ledger — one row per handed `orch:<card>:<cell>` key so a cell is handed once across ticks and processes. */
@@ -453,6 +459,22 @@ export async function runOrchestratorNode(node: Node, deps: TickDeps = {}): Prom
453
459
  const root = deps.root ?? effectiveInstanceRoot();
454
460
  const runId = deps.runId ?? graphRunId() ?? `${kstDay(now)}-${window}`;
455
461
  const path = stateFile(root, runId);
462
+ const consensus = new ConsensusEngine({ stateDir: root });
463
+ const consensusAllows = (cell: Cell): boolean => {
464
+ if (cell.kind !== 'cross-branch-change' && !cell.consensusProposalId) return true;
465
+ const workKey = `orch:${cell.cardId}:${cell.id}`;
466
+ try {
467
+ if (cell.kind === 'cross-branch-change') {
468
+ const proposal = consensus.proposalForWork(workKey);
469
+ if (!proposal || (cell.consensusProposalId && cell.consensusProposalId !== proposal.id)) return false;
470
+ cell.consensusProposalId = proposal.id;
471
+ }
472
+ return !!cell.consensusProposalId && consensus.canExecute(cell.consensusProposalId);
473
+ } catch (error) {
474
+ debug.log('loop.orchestrator', 'consensus-gate-failed', { id: cell.consensusProposalId, workKey, error: String(error) }, { level: 'warn' });
475
+ return false;
476
+ }
477
+ };
456
478
  const orchestratorConfig = getUserConfig().loops?.orchestrator;
457
479
  const configured = deps.mode ?? orchestratorConfig?.mode;
458
480
  const mode: Mode = configured === 'off' || configured === 'live' ? configured : 'shadow';
@@ -501,8 +523,9 @@ export async function runOrchestratorNode(node: Node, deps: TickDeps = {}): Prom
501
523
  ? runCoordinatorAgentInbox({ role, pack: loadAgentRolePack('coordinator'), path: inboxPath, root,
502
524
  ...(deps.coordinatorAgentRun ? { runAgent: deps.coordinatorAgentRun } : {}),
503
525
  ...(deps.coordinatorAgentProvider ? { provider: deps.coordinatorAgentProvider } : {}) })
504
- : runCoordinatorInbox(undefined, 100, inboxPath,
505
- deps.coordinatorKnowhow === undefined ? {} : { knowhow: deps.coordinatorKnowhow });
526
+ : runAskOpContextInbox({ path: inboxPath, limit: 100,
527
+ ...(deps.coordinatorKnowhow === undefined ? {} : { knowhow: deps.coordinatorKnowhow }),
528
+ ...(deps.coordinatorContext ? { context: deps.coordinatorContext } : {}) });
506
529
  }))();
507
530
  if (inbox.replied || inbox.acknowledged) {
508
531
  observe('exchange', 'coordinator-inbox-replied', inbox.replied);
@@ -529,9 +552,12 @@ export async function runOrchestratorNode(node: Node, deps: TickDeps = {}): Prom
529
552
  const cells = ruleOnly ? [{ id: card.id, title: card.title }] : split ? await split(card, { shadow: mode === 'shadow' }) : [{ id: card.id, title: card.title }];
530
553
  for (const cell of cells) {
531
554
  if (!cell.id?.trim() || !cell.title?.trim()) throw new Error('invalid split cell');
555
+ const workKey = `orch:${card.id}:${cell.id}`;
556
+ const proposalId = cell.consensusProposalId ?? (cell.kind === 'cross-branch-change' ? consensus.proposalForWork(workKey)?.id : undefined);
532
557
  state.cells.push({ cardId: card.id, id: cell.id, title: cell.title, origin: split ? 'flow1a' : 'candidate',
533
558
  ...(ruleOnly ? { priority: rubricPriority(card.sections.map(section => section.content).join('\n')) } : {}),
534
- ...(cell.kind !== undefined ? { kind: cell.kind } : {}), ...(cell.seat ? { seat: cell.seat } : {}), ...(cell.host !== undefined ? { host: cell.host } : {}) });
559
+ ...(cell.kind !== undefined ? { kind: cell.kind } : {}), ...(cell.seat ? { seat: cell.seat } : {}), ...(cell.host !== undefined ? { host: cell.host } : {}),
560
+ ...(proposalId ? { consensusProposalId: proposalId } : {}) });
535
561
  }
536
562
  observe('exchange', `split:${card.id}`, cells.length);
537
563
  if (split && cells.length && mode === 'live') {
@@ -567,6 +593,7 @@ export async function runOrchestratorNode(node: Node, deps: TickDeps = {}): Prom
567
593
  }
568
594
  if (available && (mode === 'live' || !deps.placeCell)) for (const cell of state.cells) {
569
595
  if (cell.origin !== 'flow1a' || !cell.seat || !SEAT_LOOP_IDS[cell.seat]) continue;
596
+ if (!consensusAllows(cell)) { observe('consensus-blocked', cell.consensusProposalId, 1); continue; }
570
597
  // RELPLAN's dryRun calculates the same release without writing a checklist in shadow.
571
598
  try {
572
599
  const priority = cell.priority === 'P3' || cell.priority === 'P4' ? 'P2' : cell.priority ?? 'P2';
@@ -645,6 +672,7 @@ export async function runOrchestratorNode(node: Node, deps: TickDeps = {}): Prom
645
672
  };
646
673
  for (const cell of state.cells) {
647
674
  if (cell.origin !== 'flow1a' || !cell.seat) continue;
675
+ if (!consensusAllows(cell)) { observe('consensus-blocked', cell.consensusProposalId, 1); continue; }
648
676
  const targetLoopId = SEAT_LOOP_IDS[cell.seat];
649
677
  if (!targetLoopId) continue;
650
678
  const key = `orch:${cell.cardId}:${cell.id}`;
@@ -674,6 +702,17 @@ export async function runOrchestratorNode(node: Node, deps: TickDeps = {}): Prom
674
702
  // shadow 표본은 따로 센다 — 자리 경로로 아직 안 간 칸(shadow 틱·배치 전)이 나중에 live 로 바뀌면 그때 뜬다.
675
703
  // ⚠️ 이미 자리 저널에 들어간 칸은 live 로 바꿔도 다시 안 넘긴다(keys.has 에서 끝) — 한 칸의 발사 주체는 하나다(의도).
676
704
  const handKey = handLive ? key : `shadow:${key}`;
705
+ // ANOMALY-CLUSTER: the goal·host pair is the hold key (never part of the failure signature). While a
706
+ // signature with 3+ runs is un-judged, its relaunch is held and the cell is carried to the next tick.
707
+ const anomalyGoal = cell.cardId;
708
+ const anomalyHost = cell.seat;
709
+ const anomaly = deps.anomalyCluster ?? defaultAnomalyCluster();
710
+ const hold = anomaly.hold(anomalyGoal, anomalyHost);
711
+ if (hold.hold) {
712
+ (state.deferredCells ??= []).push(cell);
713
+ observe('anomaly-cluster-hold', `${key}:${hold.reason}`, 1, 'task-agent');
714
+ continue;
715
+ }
677
716
  mkdirSync(dirname(ledger), { recursive: true });
678
717
  mkdirSync(dirname(path), { recursive: true });
679
718
  // Claim under the seat-journal lock — the same lock the seat append takes, so a live claim and a seat row never both land.
@@ -693,9 +732,18 @@ export async function runOrchestratorNode(node: Node, deps: TickDeps = {}): Prom
693
732
  withFileLockSync(`${path}.lock`, () => appendFileSync(ledger, `${JSON.stringify({ key: handKey, cell: cell.id, cardId: result.card.id, mode: result.mode, launched: result.launched, status: 'handed', runId, at: now.toISOString() })}\n`));
694
733
  (state.handed ??= []).push({ key, cell: cell.id, cardId: result.card.id, mode: result.mode, launched: result.launched });
695
734
  observe('hand-to-task-agent', `${key}:${result.card.id}:${result.mode}${result.launched ? ':launched' : ''}`, 1, 'task-agent');
735
+ // A hand that went through is the cause verdict for this goal·host — clear a pending hold.
736
+ if (anomaly.isHeld(anomalyGoal, anomalyHost)) anomaly.release(anomalyGoal, anomalyHost, '원인 판정: hand-to-task-agent 성공');
696
737
  // A live hand is an assignment: it counts toward maxDelegatePerTick like a seat row (COORD-HA ②).
697
738
  if (handLive) { keys.add(key); state.delegatedKeys?.push(key); continue; }
698
739
  } catch (error) {
740
+ // ANOMALY-CLUSTER record point: signature from kind·container exit·stage·reason tail of lastLines.
741
+ const failureLines = [String(error)];
742
+ anomaly.record({
743
+ goal: anomalyGoal, host: anomalyHost, runId,
744
+ kind: 'hand-to-task-agent-failed', containerExit: extractContainerExit(failureLines[0]!),
745
+ stage: 'delegate', lastLines: failureLines, at: now.toISOString(),
746
+ });
699
747
  observe('hand-to-task-agent-failed', `${key}:${String(error).slice(0, 160)}`, 1, 'task-agent');
700
748
  // A failed live hand stays claimed (no relaunch loop) and does not fall back to the seat path — one launcher per cell.
701
749
  if (handLive) { keys.add(key); continue; }
@@ -754,7 +802,7 @@ export async function runOrchestratorNode(node: Node, deps: TickDeps = {}): Prom
754
802
  // shadow 는 저널을 읽지 않는다 — 깨진 live 저널이 관측 전용 틱을 넘어뜨리지 않게.
755
803
  const latestRequests = new Map(mode === 'live' && state.degradation?.level !== 2 ? readRequests(root).map(row => [row.key, row]) : []);
756
804
  const eligible = state.cells.filter(cell => state.degradation?.level !== 2 && cell.origin === 'flow1a' && cell.seat && SEAT_LOOP_IDS[cell.seat]
757
- && validVersion(cell.version) && (mode === 'shadow' || latestRequests.get(`orch:${cell.cardId}:${cell.id}`)?.status === 'queued')
805
+ && consensusAllows(cell) && validVersion(cell.version) && (mode === 'shadow' || latestRequests.get(`orch:${cell.cardId}:${cell.id}`)?.status === 'queued')
758
806
  && (orchestratorConfig?.maxDelegatePerTick === undefined || state.delegatedKeys?.includes(`orch:${cell.cardId}:${cell.id}`)
759
807
  || (mode === 'live' && latestRequests.has(`orch:${cell.cardId}:${cell.id}`))));
760
808
  const seats = [...new Set(eligible.map(cell => cell.seat!))];
@@ -137,6 +137,7 @@ export const FEATURE_MATURITY = {
137
137
  tablet: 'ops',
138
138
  surface: 'ops',
139
139
  term: 'tool',
140
+ side: 'tool',
140
141
  claude: 'tool',
141
142
  codex: 'tool',
142
143
  gemini: 'tool',
@@ -431,23 +431,17 @@ const OPENGATEWAY: TierMap = {
431
431
  };
432
432
 
433
433
  // ── AWS Bedrock (BEDROCK-PROVIDER · 2026-10-11) ───────────────────
434
- // ⭐ 판단: ANTHROPIC 사다리의 «추론 수준·역할 배치»를 그대로 두고, 모델은 Bedrock 메시지 엔드포인트에서
435
- // 확인한 5.5 계열 id(`src/llm/bedrock.ts` BEDROCK_MODELS · 출처 platform.claude.com «Claude in Amazon Bedrock»
436
- // Supported models)로만 채운다. 아래 칸(budget·balanced)은 ANTHROPIC 이 haiku-4-5·sonnet-5 를 쓰지만, 이 PR 이
437
- // 카탈로그에 올린 Bedrock id 는 5.5 셋뿐이라 같은 등급의 5.5(haiku-5-5·sonnet-5-5)로 올렸다.
438
434
  // ⛔ bedrock 은 명시 선택 전용 — 이 표는 `--role-llm <role>=bedrock/<tier>` 같은 «명시» 해석에만 쓰인다.
439
- // ⚠️ status = `wip`: 실 AWS 호출(계정별 5.5 접근 조건)을 아직 안 쟀고, 셋업 키 감지 표(PROVIDER_ENV_SPEC)에도
440
- // 없다(자격이 API 키가 아니라 AWS 체인이라). 첫 실호출 스모크 뒤 `shipping` 으로 올린다.
441
- // ⭐ BEDROCK-RUNTIME-PATH(10-11): 메시지 엔드포인트(mantle)에 5.5 가 없어(📏 `GET /v1/models`) 사다리 id 를 전역 추론 프로필
442
- // `global.anthropic.…`(runtime 경로 · bedrock.ts BEDROCK_MODELS 의 `route` 칸)로 옮겼다. 공급자 이름은 그대로 `bedrock`.
443
- // 📏 budget·balanced(haiku/sonnet 5.5)는 runtime 실호출 200 실측(ap-northeast-2) · opus 5.5 는 «추론 프로필 목록에 있음»까지만(호출 0).
444
- // status 는 그대로 `wip` — `shipping` 은 셋업 키 감지 표(PROVIDER_ENV_SPEC) 칸을 요구한다(provider-wiring-contract 시험 · 범위 밖).
435
+ // ⚠️ status = `wip`: mantle-openai 모델의 실제 호출 가능성은 계정별 IAM 접근 조건을 따르며,
436
+ // 셋업 키 감지 표(PROVIDER_ENV_SPEC)에도 없다(자격이 API 키가 아니라 AWS 체인이라).
437
+ // runtime Converse 모델(GLM 5.3·Kimi K3·Grok 4.7)은 OP/IAM 확인 뒤 별도 추가한다.
438
+ // ⛔ 아래 비-Anthropic id 들은 `src/llm/bedrock.ts` BEDROCK_MODELS 에 등록된 mantle-openai 행만 사용한다.
445
439
  const BEDROCK: TierMap = {
446
- budget: { model: 'global.anthropic.claude-haiku-5-5', reasoningLevel: 'off', label: 'Claude Haiku 5.5 (Bedrock)', rationale: 'Fast · cheap · bulk/classification', status: 'wip' },
447
- balanced: { model: 'global.anthropic.claude-sonnet-5-5', reasoningLevel: 'off', label: 'Claude Sonnet 5.5 (Bedrock)', rationale: 'Default · everyday coding (BEDROCK_DEFAULT_MODEL)', status: 'wip' },
448
- better: { model: 'global.anthropic.claude-opus-5-5', reasoningLevel: 'medium', label: 'Claude Opus 5.5 · thinking medium (Bedrock)', rationale: 'ANTHROPIC better 와 같은 배치(구현 = Opus 5.5)', status: 'wip' },
449
- best: { model: 'global.anthropic.claude-opus-5-5', reasoningLevel: 'medium', label: 'Claude Opus 5.5 · thinking medium (Bedrock)', rationale: 'Best reasoning · architecture', status: 'wip' },
450
- loaded: { model: 'global.anthropic.claude-opus-5-5', reasoningLevel: 'high', label: 'Claude Opus 5.5 · extended thinking (Bedrock)', rationale: 'Loaded · deep multi-step', status: 'wip' },
440
+ budget: { model: 'zai.glm-4.7-flash', reasoningLevel: 'off', label: 'GLM 4.7 Flash (Bedrock)', rationale: 'Fast · cheap · bulk/classification', status: 'wip' },
441
+ balanced: { model: 'openai.gpt-6-luna', reasoningLevel: 'off', label: 'GPT-6 Luna (Bedrock)', rationale: 'Default · balanced Bedrock mantle-openai model', status: 'wip' },
442
+ better: { model: 'deepseek.v3.2', reasoningLevel: 'medium', label: 'DeepSeek V3.2 (Bedrock)', rationale: 'Higher quality · mantle-openai', status: 'wip' },
443
+ best: { model: 'zai.glm-5', reasoningLevel: 'medium', label: 'GLM 5 (Bedrock)', rationale: 'Best reasoning · mantle-openai', status: 'wip' },
444
+ loaded: { model: 'openai.gpt-6-sol', reasoningLevel: 'high', label: 'GPT-6 Sol (Bedrock)', rationale: 'Loaded · deep multi-step · mantle-openai', status: 'wip' },
451
445
  };
452
446
 
453
447
  /** 가격·창 미측정이라 기존 tier 배치를 바꾸지 않고 명시 모델로만 고르는 칸.
@@ -523,8 +517,9 @@ export function lookupOpenRouterModelSpec(model: string): LlmTierSpec | undefine
523
517
  * `auto` and unknown providers have no concrete provider ladder, so both use
524
518
  * Anthropic's balanced default instead of crossing into the Codex family.
525
519
  * Existing execution path: src/llm/model-defaults.ts tierModel() calls this
526
- * function to fill the active provider's model at runtime. Explicit providers
527
- * keep their own ladders; CLI catalog commands reject unknown/'auto' directly. */
520
+ * function (`lookupLlmTierSpec(activeProviderForDefaults(provider), tier)`) to
521
+ * fill the active provider's model at runtime. Explicit providers keep their
522
+ * own ladders; CLI catalog commands reject unknown/'auto' directly. */
528
523
  export function lookupLlmTierSpec(
529
524
  provider: LLMProviderName,
530
525
  tier: ModelTier,
@@ -278,6 +278,23 @@ export class MsgStore {
278
278
  : []);
279
279
  }
280
280
 
281
+ /** A request and its direct replies, in insertion order, independent of recipient cursors. */
282
+ listThread(messageId: number, after: number = 0, limit: number = 100): Message[] {
283
+ if (!Number.isSafeInteger(messageId) || messageId < 1) throw new Error('message ID must be a positive integer');
284
+ validCursor(after);
285
+ if (!Number.isSafeInteger(limit) || limit < 1 || limit > 1000) throw new Error('limit must be between 1 and 1000');
286
+ return this.readWithSchema(hasReplyTo => {
287
+ const target = this.db.query(`SELECT id, ${hasReplyTo ? 'reply_to' : 'NULL AS reply_to'} FROM msg_messages WHERE id = ?`)
288
+ .get(messageId) as { id: number; reply_to: number | null } | null;
289
+ if (target === null) throw new Error(`message not found: #${messageId}`);
290
+ const rootId = target.reply_to ?? target.id;
291
+ const rows = this.db.query(`SELECT id, sender, recipient, body, kind, ${hasReplyTo ? 'reply_to' : 'NULL AS reply_to'}, created_at FROM msg_messages
292
+ WHERE id > ? AND (id = ? ${hasReplyTo ? 'OR reply_to = ?' : ''}) ORDER BY id ASC LIMIT ?`)
293
+ .all(...(hasReplyTo ? [after, rootId, rootId, limit] : [after, rootId, limit])) as MessageRow[];
294
+ return rows.map(fromRow);
295
+ });
296
+ }
297
+
281
298
  list(recipient: string, after: number = 0, limit: number = 100): Message[] {
282
299
  return this.listByRecipient(recipient, after, limit);
283
300
  }
@@ -7,7 +7,7 @@
7
7
 
8
8
  import type { VerifierSpec } from './verifier/types.js';
9
9
  import type { GuardianSpec } from './guardian/types.js';
10
- import { ptyAvailable } from './pty-shell/registry.js';
10
+ import { ptyAvailable } from './pty-shell/availability.js';
11
11
  import { krFlowAvailable } from './skills/tools/kr-flow.js';
12
12
  import { SELF_COGNITION_MCP_CATALOG_ENTRIES } from './tool-runtime/self-cognition-catalog.js';
13
13
  import { SKILLS_LIST_DESCRIPTION } from './onboarding/entry-hints.js';
@@ -0,0 +1,96 @@
1
+ import type { Message, MessageEnvelope } from '../../msg/msg-store.js';
2
+ import type { TgSlashCommand } from '../../telegram-commands.js';
3
+ import { ASK_OP_COMMAND, formatAskOpQuestionEnvelope } from '../../session/channel-ask-op-envelope.js';
4
+
5
+ export interface AskOpTelegramOptions {
6
+ allowedUserIds: readonly number[];
7
+ append: (message: MessageEnvelope, provenanceKey: string) => Message;
8
+ }
9
+
10
+ export interface AskOpDiscordOptions {
11
+ allowedUserIds: readonly string[];
12
+ allowedChannelIds: readonly string[];
13
+ resolveBotId: () => Promise<string>;
14
+ append: (message: MessageEnvelope, provenanceKey: string) => Message;
15
+ }
16
+
17
+ export interface AskOpDiscordContext {
18
+ userId: string;
19
+ channelId: string;
20
+ messageId: string;
21
+ text: string;
22
+ }
23
+
24
+ function appendAskOpQuestion(
25
+ options: { append: AskOpTelegramOptions['append'] },
26
+ input: { from: 'TELEGRAM' | 'DISCORD'; surface: string; correlation: string[]; question: string; provenanceKey: string },
27
+ ): Message {
28
+ return options.append({
29
+ from: input.from,
30
+ to: 'COORDINATOR',
31
+ kind: 'question',
32
+ body: [`${input.surface} /${ASK_OP_COMMAND}`, ...input.correlation, `question: ${input.question}`].join('\n'),
33
+ }, input.provenanceKey);
34
+ }
35
+
36
+ function extractQuestion(text: string): string | null {
37
+ const match = new RegExp(`^/(?:${ASK_OP_COMMAND}|ask-op)(?:@[-_a-z0-9]+)?(?:\\s+([\\s\\S]*))?$`, 'i').exec(text.trim());
38
+ const question = match?.[1]?.trim();
39
+ return question || null;
40
+ }
41
+
42
+ export function createAskOpTelegramSlashCommand(options: AskOpTelegramOptions): TgSlashCommand {
43
+ return {
44
+ name: ASK_OP_COMMAND,
45
+ description: '운영 책임자에게 질문을 보냅니다',
46
+ handler: async (_args, ctx) => {
47
+ if (!options.allowedUserIds.includes(ctx.userId)) return '허용된 사용자만 OP에게 질문할 수 있습니다.';
48
+ const question = extractQuestion(ctx.text);
49
+ if (!question) return `사용법: /${ASK_OP_COMMAND} <질문>`;
50
+ if (!Number.isSafeInteger(ctx.updateId) || ctx.updateId < 0) return 'Telegram update 식별값을 확인할 수 없어 질문을 저장하지 못했습니다.';
51
+
52
+ const botId = (ctx.botId ?? 'unknown').replace(/[^a-zA-Z0-9_-]/g, '_');
53
+ const message = options.append({
54
+ from: 'TELEGRAM',
55
+ to: 'COORDINATOR',
56
+ kind: 'question',
57
+ body: formatAskOpQuestionEnvelope({
58
+ surface: 'telegram', botId, chatId: ctx.chatId, threadId: ctx.threadId,
59
+ messageId: ctx.messageId, updateId: ctx.updateId, question,
60
+ }),
61
+ }, `coord:tg-${botId}-${ctx.updateId}:COORDINATOR`);
62
+
63
+ return `OP에게 질문 #${message.id}로 접수했습니다.`;
64
+ },
65
+ };
66
+ }
67
+
68
+ /** Handle a Discord text command from an already-routed message. Returning
69
+ * undefined leaves every non-/askop message on its existing chat path. */
70
+ export function createAskOpDiscordIngress(options: AskOpDiscordOptions) {
71
+ return async (ctx: AskOpDiscordContext): Promise<string | undefined> => {
72
+ const match = new RegExp(`^/${ASK_OP_COMMAND}(?:\\s+([\\s\\S]*))?$`, 'i').exec(ctx.text.trim());
73
+ if (!match) return undefined;
74
+ if (!options.allowedUserIds.includes(ctx.userId)) return '허용된 사용자만 OP에게 질문할 수 있습니다.';
75
+ if (!options.allowedChannelIds.includes(ctx.channelId)) return '허용된 Discord 채널에서만 OP에게 질문할 수 있습니다.';
76
+ const question = match[1]?.trim();
77
+ if (!question) return `사용법: /${ASK_OP_COMMAND} <질문>`;
78
+ if (!/^\d+$/.test(ctx.messageId)) return 'Discord 메시지 식별값을 확인할 수 없어 질문을 저장하지 못했습니다.';
79
+
80
+ let botId: string;
81
+ try { botId = await options.resolveBotId(); }
82
+ catch { return 'Discord 봇 식별값을 확인할 수 없어 질문을 저장하지 못했습니다.'; }
83
+ if (!/^[A-Za-z0-9_-]+$/.test(botId)) return 'Discord 봇 식별값이 올바르지 않아 질문을 저장하지 못했습니다.';
84
+
85
+ const message = appendAskOpQuestion(options, {
86
+ from: 'DISCORD', surface: 'Discord',
87
+ correlation: [
88
+ `botId=${botId}`, `channelId=${ctx.channelId}`,
89
+ `messageId=${ctx.messageId}`, `updateId=${ctx.messageId}`,
90
+ ],
91
+ question,
92
+ provenanceKey: `coord:dc-${botId}-${ctx.messageId}:COORDINATOR`,
93
+ });
94
+ return `OP에게 질문 #${message.id}로 접수했습니다.`;
95
+ };
96
+ }
@@ -37,6 +37,8 @@ import { createDiscordStreamSink } from '../../session/streaming/discord-stream-
37
37
  import { splitForDiscord } from '../../discord.js';
38
38
  import { formatForDiscord } from '../../discord-markdown.js';
39
39
  import { receiveChannelEvent } from '../outbound/router.js';
40
+ import { openMsgStore } from '../../msg/msg-store.js';
41
+ import { createAskOpDiscordIngress } from './channel-ask-op.js';
40
42
 
41
43
  export interface NexusDiscordTriggerBotOpts {
42
44
  /** Bot token (without `Bot ` prefix). Production reads
@@ -156,6 +158,30 @@ export function createNexusDiscordTriggerBot(
156
158
  // LF2 — 콘솔 하트비트 유지 + debug.log 병행(telegram-trigger 동형).
157
159
  const log = opts.log ?? createDiscordTriggerLogger();
158
160
  const onTriggerTap = buildDiscordTriggerTap(opts.dispatch, log);
161
+ let botRef: DiscordBot | undefined;
162
+ let botIdPromise: Promise<string> | undefined;
163
+ const askOpIngress = createAskOpDiscordIngress({
164
+ allowedUserIds: opts.allowedUsers,
165
+ allowedChannelIds: opts.guildTextChannels ?? [],
166
+ resolveBotId: () => {
167
+ if (!botRef) return Promise.reject(new Error('Discord bot is not ready'));
168
+ botIdPromise ??= botRef.getMe().then(({ id }) => id).catch((error: unknown) => {
169
+ botIdPromise = undefined;
170
+ throw error;
171
+ });
172
+ return botIdPromise;
173
+ },
174
+ append: (message, provenanceKey) => {
175
+ const store = openMsgStore();
176
+ try { return store.appendWithProvenance(message, provenanceKey); }
177
+ finally { store.close(); }
178
+ },
179
+ });
180
+ const onMessage: DcMessageHandler = async (ctx, streamer) => {
181
+ const askReply = await askOpIngress(ctx);
182
+ if (askReply !== undefined) return askReply;
183
+ return opts.onMessage?.(ctx, streamer);
184
+ };
159
185
 
160
186
  const botWasInjected = opts.bot !== undefined;
161
187
  const bot = opts.bot ?? new DiscordBot({
@@ -165,7 +191,7 @@ export function createNexusDiscordTriggerBot(
165
191
  // Chat path: the injected self-turn handler (M4b nexus wire) or the
166
192
  // legacy trigger-only no-op. Workflows wanting a chat reply can
167
193
  // still declare a `chatTrigger` (routes via `/v1/workflows/chat/*`).
168
- onMessage: opts.onMessage ?? (async () => undefined),
194
+ onMessage,
169
195
  log,
170
196
  onTriggerTap,
171
197
  ...(opts.voiceTap ? { voiceTap: opts.voiceTap } : {}),
@@ -173,6 +199,7 @@ export function createNexusDiscordTriggerBot(
173
199
  ...(opts.fetchImpl ? { fetchImpl: opts.fetchImpl } : {}),
174
200
  ...(opts.wsImpl ? { wsImpl: opts.wsImpl } : {}),
175
201
  });
202
+ botRef = bot;
176
203
 
177
204
  // §C3 — discord 서피스 sink(config gate·telegram-trigger 동형). shadowFanout OR
178
205
  // primary.discord 시 등록. endpoint 완전스코프면 parse→인스턴스 가드 후 channelId 배달,
@@ -2,6 +2,7 @@ import { debug } from '../../debug/log.js';
2
2
  import { GraphWizardInputError, designGraphVariantPlan, generateGraphFromPrompt, wizardInstalledPacks, type GraphWizardDeps, type GraphWizardTurn } from '../../graph-wizard/generate.js';
3
3
  import { defaultGraphsDir } from '../../self-implement/graph-templates.js';
4
4
  import { loadGraphTemplates } from '../../self-implement/graph-yaml.js';
5
+ import type { NexusEventBus } from './event-bus.js';
5
6
  import { jsonResponse } from './json-response.js';
6
7
 
7
8
  export function handleGraphWizardPacksGet(deps: GraphWizardDeps = {}): Response {
@@ -11,6 +12,28 @@ export function handleGraphWizardPacksGet(deps: GraphWizardDeps = {}): Response
11
12
  const MAX_PROMPT = 4000;
12
13
  const MAX_YAML = 200_000;
13
14
 
15
+ /** 호출 경계에서 variant 한 턴의 결말을 버스에 남긴다 — mode·reason ⊕ 조작 growth 좌표. */
16
+ function publishGraphCompose(eventBus: NexusEventBus | undefined, input: {
17
+ readonly result: Awaited<ReturnType<typeof designGraphVariantPlan>>;
18
+ readonly goal: string;
19
+ readonly templateId: string;
20
+ }): void {
21
+ const { result, goal, templateId } = input;
22
+ eventBus?.publish({
23
+ ts: Date.now(),
24
+ kind: 'graph.compose',
25
+ detail: {
26
+ mode: result.mode,
27
+ status: result.status,
28
+ reason: result.reason,
29
+ goal,
30
+ templateId,
31
+ ...(result.growth ? { growth: result.growth } : {}),
32
+ ...(result.status === 'composed' ? { overlayId: result.variant.overlay.overlayId, patches: result.variant.patches.length } : {}),
33
+ },
34
+ });
35
+ }
36
+
14
37
  /**
15
38
  * POST /v1/graphs/wizard {prompt, kind?, currentYaml?, history?} or
16
39
  * {mode:'variant', prompt, goal, templateId} for one validated L2 plan (no YAML generation).
@@ -18,8 +41,9 @@ const MAX_YAML = 200_000;
18
41
  * (labels·steps·recipes·dryRun·baseReason 는 v2 추가 필드 — 기존 필드는 그대로.)
19
42
  * currentYaml 이 빈 문자열이면 «빈 캔버스»로 보고 새 그래프를 짓는다(의도) · 내용이 있는데 id 가 없거나 형식 밖이면 400.
20
43
  * 저장하지 않는다 — 저장은 POST /v1/graphs(새 그래프) 또는 PUT /v1/graphs/<id>/yaml(내 그래프).
44
+ * variant 요청은 결말(mode·reason·조작 growth)을 주입된 버스에 `graph.compose` 이벤트로 남긴다.
21
45
  */
22
- export async function handleGraphWizardPost(req: Request, deps: GraphWizardDeps = {}): Promise<Response> {
46
+ export async function handleGraphWizardPost(req: Request, deps: GraphWizardDeps = {}, eventBus?: NexusEventBus): Promise<Response> {
23
47
  let body: Record<string, unknown>;
24
48
  try {
25
49
  const parsed: unknown = await req.json();
@@ -60,7 +84,8 @@ export async function handleGraphWizardPost(req: Request, deps: GraphWizardDeps
60
84
  const template = loadGraphTemplates(deps.graphsDir ?? defaultGraphsDir()).templates[body.templateId];
61
85
  if (!template) return jsonResponse({ error: 'bad_request', reason: `unknown templateId: ${body.templateId}` }, 400);
62
86
  const result = await designGraphVariantPlan({ goal: body.goal, prompt, template }, deps);
63
- return jsonResponse({ mode: 'variant', ...result });
87
+ publishGraphCompose(eventBus, { result, goal: body.goal, templateId: body.templateId });
88
+ return jsonResponse(result);
64
89
  }
65
90
  const result = await generateGraphFromPrompt({
66
91
  prompt,
@@ -1,13 +1,17 @@
1
1
  import { getUserConfig } from '../../user-config.js';
2
2
  import { readHqLease, type HqDeps } from '../../hq/hq.js';
3
- import { measurePoolLease, type PoolLeaseMeasure } from '../../task-orchestrator/surfaces/pod-lease.js';
3
+ import { measurePoolLease, type PoolLeaseMeasure, type PodLeaseMember } from '../../task-orchestrator/surfaces/pod-lease.js';
4
4
  import { parsePodPool, resolvePodPoolSpec, type PodPoolMember, type PoolKubectl } from '../../task-orchestrator/surfaces/pod-pool.js';
5
+ import type { GateReservation } from '../../ops/overview.js';
5
6
 
6
7
  export interface GridData {
7
8
  /** null means the arbiter could not be read, not that no lease exists. */
8
9
  hq: { record: ReturnType<typeof readHqLease>['record']; ageSeconds: number | null; expired: boolean | null; reason: string | null };
9
- /** Configured member order; capacity comes from measurePoolLease when available. occupied is running + pending, or null on measurement failure. */
10
- members: Array<{ context: string; capacity: number; running: number | null; pending: number | null; occupied: number | null; reason: string | null }>;
10
+ /**
11
+ * Configured member order; capacity comes from measurePoolLease when available. occupied is running + pending, or null on measurement failure.
12
+ * `gate` is GATE-RESERVE-AUTO's reservation for this member — absent when the job/cpu reading failed (unmeasured, not «no gate»).
13
+ */
14
+ members: Array<{ context: string; capacity: number; running: number | null; pending: number | null; occupied: number | null; reason: string | null; gate?: GateReservation }>;
11
15
  poolReason: string | null;
12
16
  }
13
17
 
@@ -20,6 +24,21 @@ export interface GridDeps {
20
24
  measure?: (members: readonly PodPoolMember[]) => PoolLeaseMeasure;
21
25
  }
22
26
 
27
+ /**
28
+ * GATE-RESERVE-AUTO 의 예약 몫을 자원 지도 축 꼴로 옮긴다. Job/CPU 읽기가 실패한 멤버는 undefined 다 —
29
+ * «게이트 없음»이 아니라 «못 잼»이므로 구속 조건 후보에서 빠진다(0 으로도 무한으로도 읽지 않는다).
30
+ * 게이트가 안 도는 멤버(jobs 0)는 값으로 남는다: 축은 «게이트 없음»이라고 말할 수 있어야 한다.
31
+ */
32
+ function gateOf(row: PodLeaseMember | undefined): GateReservation | undefined {
33
+ if (!row || typeof row.gateJobs !== 'number') return undefined;
34
+ return {
35
+ jobs: row.gateJobs,
36
+ unbound: typeof row.gateUnboundJobs === 'number' ? row.gateUnboundJobs : Number.NaN,
37
+ reservedMillicores: typeof row.gateCpuMillicores === 'number' ? row.gateCpuMillicores : Number.NaN,
38
+ schedulableMillicores: typeof row.schedulableCpuMillicores === 'number' ? row.schedulableCpuMillicores : Number.NaN,
39
+ };
40
+ }
41
+
23
42
  /** Independent, fail-soft read snapshots. No lease status/heartbeat, DNS probe Pod, host reservation or writes. */
24
43
  export function buildGridData(deps: GridDeps = {}): GridData {
25
44
  let hq: GridData['hq'];
@@ -45,9 +64,10 @@ export function buildGridData(deps: GridDeps = {}): GridData {
45
64
  const row = byContext.get(member.context);
46
65
  const running = row?.running ?? null;
47
66
  const pending = row?.pending ?? null;
67
+ const gate = gateOf(row);
48
68
  return { context: member.context, capacity: row?.capacity ?? member.capacity, running, pending,
49
69
  occupied: running === null || pending === null ? null : running + pending,
50
- reason: row?.reason ?? (row ? null : '측정 불가') };
70
+ reason: row?.reason ?? (row ? null : '측정 불가'), ...(gate ? { gate } : {}) };
51
71
  });
52
72
  } catch (error) {
53
73
  poolReason = String(error);
@@ -1523,7 +1523,7 @@ export async function routeRequest(
1523
1523
  if (method === 'POST' && pathname === '/v1/graphs/wizard') {
1524
1524
  if (!opts.metaApi) return jsonResponse({ error: 'meta-api-not-wired' }, 503);
1525
1525
  if (!checkAuth(req, opts.metaApi)) return jsonResponse({ error: 'unauthorized' }, 401);
1526
- return handleGraphWizardPost(req, opts.graphWizard);
1526
+ return handleGraphWizardPost(req, opts.graphWizard, opts.eventBus);
1527
1527
  }
1528
1528
 
1529
1529
  if (pathname === '/v1/fabric/decompose' || pathname.startsWith('/v1/fabric/plans/')) {
@@ -11,6 +11,7 @@ import { createSeatsCache, todayKst } from './ops-seats.js';
11
11
  import { liveSeatsSources } from './ops-seats-sources.js';
12
12
  import { createOverviewCache } from '../../ops/overview-cache.js';
13
13
  import { resourcesFromOverview } from '../../ops/resources.js';
14
+ import { loopsMapFromCache } from '../../ops/loops-map.js';
14
15
  import { parseSince } from '../../ops/overview-collect.js';
15
16
  import type { MetaApiOpts } from './meta-api.js';
16
17
 
@@ -184,6 +185,14 @@ export function readReleaseRuns(version: string | null = null,
184
185
  }).sort((a, b) => b.startedAt.localeCompare(a.startedAt)).slice(0, 20);
185
186
  }
186
187
 
188
+ /**
189
+ * 요청이 «자격을 하나라도 실어 왔는가» — operatorSignal 이 판정에 쓰는 축(베어러·프록시 헤더·쿠키)만 본다.
190
+ * 아무것도 없으면 401(인증 없음), 있는데 운영자가 아니면 403(권한 없음)으로 가른다.
191
+ */
192
+ function offeredCredential(req: Request): boolean {
193
+ return Boolean(req.headers.get('authorization') || req.headers.get('x-elanous-operator') || req.headers.get('cookie'));
194
+ }
195
+
187
196
  /** The sole data gate for every read-only /v1/ops endpoint. */
188
197
  export function handleOpsApi(req: Request, metaApi: MetaApiOpts | undefined): Response | Promise<Response> {
189
198
  const url = new URL(req.url);
@@ -195,6 +204,9 @@ export function handleOpsApi(req: Request, metaApi: MetaApiOpts | undefined): Re
195
204
  debug.log('ops.api', 'refused', { path: pathname, source: signal.operatorSource });
196
205
  // RES-FLOOR-API: no credential was offered at all — this endpoint names it 401; every other path keeps 403.
197
206
  if (pathname === '/v1/ops/resources') return jsonResponse({ error: 'unauthorized' }, 401);
207
+ // LOOP-MAP-API: a request that offers no credential at all is 401 in the same body shape;
208
+ // a credential that is not an operator stays 403, exactly like the neighbouring ops paths.
209
+ if (pathname === '/v1/ops/loops-map' && !offeredCredential(req)) return jsonResponse({ error: 'unauthorized' }, 401);
198
210
  return jsonResponse({ error: 'forbidden' }, 403);
199
211
  }
200
212
  const served = (response: Response): Response => {
@@ -226,12 +238,8 @@ export function handleOpsApi(req: Request, metaApi: MetaApiOpts | undefined): Re
226
238
  // (name·era·beat cell observedAt; null/unmeasured value and reason preserved);
227
239
  // no new remote fan-out of its own. Loop-edge joining is a later shard.
228
240
  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));
241
+ // peek, not get: a cold cache answers «아직 캐시 없음» instead of starting a collection.
242
+ return Promise.resolve(served(jsonResponse(loopsMapFromCache(overviewCache.peek()))));
235
243
  }
236
244
  if (pathname === '/v1/ops/seats') {
237
245
  const date = url.searchParams.get('date') ?? todayKst();