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
@@ -23,7 +23,6 @@ import { createArtifactStore } from '../artifact/index.js';
23
23
  import { tmpdir } from 'node:os';
24
24
  import { isAbsolute, join, relative, resolve, sep } from 'node:path';
25
25
  import { promisify } from 'node:util';
26
- import { forkSessionById, HARNESS_SESSION_ORIGIN, isHarnessSessionOrigin } from '../session/index.js';
27
26
  import { configuredWorktreeRoot, getUserConfig, resolveActiveProvider, resolveRoleLlm } from '../user-config.js';
28
27
  import { elanousStateRoot } from '../autopilot/state-paths.js';
29
28
  import { addHarnessQueue } from '../harness/harness-queue.js';
@@ -1287,7 +1286,7 @@ export interface SameCellCardRebindObservation {
1287
1286
  detail?: string;
1288
1287
  }
1289
1288
 
1290
- export type OpenPrOutcome = { url: string; number: number; rebind?: SameCellCardRebindObservation };
1289
+ export type OpenPrOutcome = { url: string; number: number; boundCardReuse?: { headRefName: string }; rebind?: SameCellCardRebindObservation };
1291
1290
 
1292
1291
  type DefaultSeamsResult = Omit<SelfImplementSeams, 'diagnose' | 'openPr'> & {
1293
1292
  diagnose: (ctx: DefaultSeamsDiagnoseInput) => Promise<string>;
@@ -1305,7 +1304,9 @@ type SameCellRebindDecision =
1305
1304
  type SameCellRebindExtra = { boundPr?: number; detail?: string };
1306
1305
 
1307
1306
  /** 같은 칸 새 draft 뒤 카드 재결속 — 사유를 다섯 갈래로 나눠 남기고, 카드 저장소가 없는 실행은 던지지 않고
1308
- * deferred 로 돌려준다(Pod 자식은 본부 카드 저장소가 없다 · 부모 pr-terminal 결속은 #29948 이 맡는다). */
1307
+ * deferred 로 돌려준다(Pod 자식은 본부 카드 저장소가 없다 · 부모 pr-terminal 결속은 #29948 이 맡는다).
1308
+ * 카드 저장소가 있는 호스트에서 card-missing·card-id-absent 는 조용한 성공이 아니라
1309
+ * debug.log('self-implement.same-cell','rebind-missing-on-host',{reason}) 경고로 분리한다(#30021 r4 shouldFix). */
1309
1310
  function rebindSameCellCardToPr(input: {
1310
1311
  taskCardId: string | undefined;
1311
1312
  storePath: string;
@@ -1329,8 +1330,14 @@ function rebindSameCellCardToPr(input: {
1329
1330
  debug.log('self-implement.pr', 'same-cell-card-rebind-failed', { ...base, ...extra, reason }, { level: 'warn' });
1330
1331
  throw new Error(`same-cell 새 draft ${input.url} 개설됨; 카드 재결속 실패(${reasonText}) — 새 PR 수확 필요`);
1331
1332
  };
1332
- if (!input.taskCardId) return deferred('card-id-absent');
1333
- if (!existsSync(input.storePath)) return deferred('card-store-absent');
1333
+ const hostStore = existsSync(input.storePath);
1334
+ /** 호스트(카드 저장소 있음)인데 결속 대상이 없으면 deferred 로 조용히 지나가지 않고 경고 이벤트로 분리한다. */
1335
+ const missingOnHost = (reason: SameCellCardRebindReason): SameCellCardRebindObservation => {
1336
+ debug.log('self-implement.same-cell', 'rebind-missing-on-host', { ...base, reason }, { level: 'warn' });
1337
+ return deferred(reason);
1338
+ };
1339
+ if (!input.taskCardId) return hostStore ? missingOnHost('card-id-absent') : deferred('card-id-absent');
1340
+ if (!hostStore) return deferred('card-store-absent');
1334
1341
  let decision: SameCellRebindDecision | undefined;
1335
1342
  let updated: ReturnType<typeof updateTaskCard>;
1336
1343
  try {
@@ -1372,7 +1379,7 @@ function rebindSameCellCardToPr(input: {
1372
1379
  case 'manual-ref':
1373
1380
  return failed('manual-ref');
1374
1381
  case 'card-missing':
1375
- return deferred('card-missing');
1382
+ return missingOnHost('card-missing');
1376
1383
  case 'already-rebound':
1377
1384
  observe('already-rebound');
1378
1385
  return { outcome: 'already-rebound', reason: 'already-rebound', cardId, oldPr: input.oldPr, newPr: input.newPr };
@@ -1674,6 +1681,7 @@ export function defaultSeams(o: DefaultSeamsOptions = {}): SelfImplementSeams {
1674
1681
  },
1675
1682
 
1676
1683
  forkSession: async (parentSessionId) => {
1684
+ const { forkSessionById, HARNESS_SESSION_ORIGIN, isHarnessSessionOrigin } = await import('../session/index.js');
1677
1685
  const forked = forkSessionById(parentSessionId, { origin: HARNESS_SESSION_ORIGIN });
1678
1686
  if (!forked) throw new Error(`self-implement fork: source session not found — ${parentSessionId}`);
1679
1687
  if (!isHarnessSessionOrigin(forked.meta.origin)) {
@@ -1738,7 +1746,11 @@ export function defaultSeams(o: DefaultSeamsOptions = {}): SelfImplementSeams {
1738
1746
  }
1739
1747
  // P1 — 대상 repo: 명시 repoRoot(외부 개발) 우선, 없으면 데몬 cwd 의 repo(=elanous 자신·현행).
1740
1748
  const repoRoot = o.repoRoot ?? resolveMainRepoRoot(process.cwd()) ?? process.cwd();
1741
- const r = createWorktree({
1749
+ // Keep the optional Pod-only implementation out of the TUI's static module graph.
1750
+ const inPlaceCandidate = process.env.ELANOUS_POD_INPLACE_WORKTREE === '1'
1751
+ ? (await import('./pod-inplace-worktree.js')).tryCreatePodInplaceWorktree({ repoRoot, cwd: process.cwd(), branch, ...(base ? { base } : {}), runId, ...(goalFile ? { goalFile } : {}), env: process.env })
1752
+ : null;
1753
+ const r = inPlaceCandidate ?? createWorktree({
1742
1754
  repoRoot,
1743
1755
  branch,
1744
1756
  worktreeRoot: configuredWorktreeRoot(),
@@ -1748,6 +1760,7 @@ export function defaultSeams(o: DefaultSeamsOptions = {}): SelfImplementSeams {
1748
1760
  ...(base ? { base } : {}),
1749
1761
  ...(runId ? { currentOwner: `dev:${runId}` } : {}),
1750
1762
  });
1763
+ const inPlace = 'inPlace' in r && r.inPlace === true;
1751
1764
  if (r.resolvedBase) baselineRefs.set(r.path, r.resolvedBase);
1752
1765
  const benchId = benchIdFromBase(base);
1753
1766
  if (benchId) benchWorktrees.set(r.path, benchId);
@@ -1775,6 +1788,7 @@ export function defaultSeams(o: DefaultSeamsOptions = {}): SelfImplementSeams {
1775
1788
  baseIsIntegration: baseIsIntegration(r.path, r.resolvedBase),
1776
1789
  baseFreshness: r.baseFreshness,
1777
1790
  ...(r.reused ? { reused: true } : {}),
1791
+ ...(inPlace ? { inPlace: true } : {}),
1778
1792
  ...provenance,
1779
1793
  };
1780
1794
  const goalMetadata: HarnessWorktreeGoalMetadata = {
@@ -1795,6 +1809,8 @@ export function defaultSeams(o: DefaultSeamsOptions = {}): SelfImplementSeams {
1795
1809
  const provenanceError = error instanceof Error ? error.message : String(error);
1796
1810
  // Manual creation rolls back on a metadata failure; self-implement retains its workspace and continues.
1797
1811
  debug.log('self-implement', 'worktree-provenance-failed', { path: r.path, ...(provenance ?? {}), reason: provenanceError }, { level: 'warn' });
1812
+ // This source tree is also the Pod's recovery anchor. Never continue in-place without an owner marker.
1813
+ if (inPlace) throw new Error(`pod in-place provenance unavailable: ${provenanceError}`);
1798
1814
  return {
1799
1815
  path: r.path,
1800
1816
  branch: r.branch,
@@ -1804,6 +1820,7 @@ export function defaultSeams(o: DefaultSeamsOptions = {}): SelfImplementSeams {
1804
1820
  baseIsIntegration: baseIsIntegration(r.path, r.resolvedBase),
1805
1821
  baseFreshness: r.baseFreshness,
1806
1822
  ...(r.reused ? { reused: true } : {}),
1823
+ ...(inPlace ? { inPlace: true } : {}),
1807
1824
  provenanceError,
1808
1825
  };
1809
1826
  }
@@ -2590,26 +2607,32 @@ export function defaultSeams(o: DefaultSeamsOptions = {}): SelfImplementSeams {
2590
2607
  "if (!testLine) process.exit(1);",
2591
2608
  "const m = testLine.match(/(\\d+)\\s+fail/); if (!m) process.exit(1);",
2592
2609
  "const failFromLog = Number(m[1]); if (failFromLog !== 0) process.exit(1);",
2593
- "if (log.indexOf('[gate-baseline] introduced=0, preexisting=0, unknown=0, precondition-unmet=0') < 0) process.exit(1);",
2610
+ // PASS는 시험 자체의 0 fail을 잰다. 실패 귀속 baseline이 없으면 'not run'으로만 기록한다.
2594
2611
  // 문서가 적은 관측값이 **로그에서 읽은 값과 같아야** 한다.
2595
2612
  "const sections = [body('## 불변식'), body('## 판정 신호')];",
2596
- "if (sections.some((p) => p.indexOf('UNVERIFIABLE') >= 0)) process.exit(1);",
2613
+ "if (sections.some((p) => /^- UNVERIFIABLE(?:[ \t]*:|[ \t]*$)/m.test(p))) process.exit(1);",
2597
2614
  "if (sections.some((p) => p.indexOf('filled-by: supervisor@round-' + e.round) < 0)) process.exit(1);",
2598
2615
  // ⛔ writer 가 넘긴 command 를 믿지 않는다 — **로그에서 직접** 뽑아 문서와 대조한다(리뷰 must-fix).
2599
2616
  "const cm = testLine.match(/^\\[test\\]\\s+PASS\\s+(.+?)\\s*(?:—|$)/); if (!cm) process.exit(1);",
2600
2617
  "const cmdFromLog = cm[1].trim();",
2601
- "if (sections.some((p) => p.indexOf(cmdFromLog) < 0)) process.exit(1);",
2618
+ "if (body('## 불변식').indexOf(cmdFromLog) < 0) process.exit(1);",
2602
2619
  // 문서가 baseline 문면도 담고 있어야 한다 — 근거가 문서 안에서 재검증 가능해야 한다.
2603
2620
  // ⛔ 부분 문자열이 아니라 **로그의 baseline 줄 전체**와 대조한다 — `preexisting=9` 같은
2604
2621
  // 불일치가 통과하면 근거가 근거가 아니다(리뷰 must-fix).
2605
- "const bl = log.split('\\n').find((l) => l.indexOf('[gate-baseline]') === 0); if (!bl) process.exit(1);",
2606
- "if (body('## 불변식').indexOf(bl.trim()) < 0) process.exit(1);",
2607
- // ② 조건 줄의 명령을 **그 필드에서** 파싱해 대조한다 — 절 어딘가에 있으면 통과하던 것을 막는다.
2622
+ "const bl = log.split('\\n').find((l) => l.indexOf('[gate-baseline]') === 0);",
2623
+ "if (bl) { if (!/^\\[gate-baseline\\] introduced=0, preexisting=0, unknown=0, precondition-unmet=0(?:,|$)/.test(bl)) process.exit(1); if (e.baselineLine !== bl.trim()) process.exit(1); if (sections.some((p) => p.indexOf(bl.trim()) < 0)) process.exit(1); }",
2624
+ "else { if (e.baselineLine !== undefined) process.exit(1); if (sections.some((p) => p.indexOf('baseline not run (test PASS)') < 0)) process.exit(1); }",
2625
+ // ② 조건 줄의 저작 명령을 **그 필드에서** 파싱하고, 해당 명령의 별도 실행 결과가
2626
+ // 정확히 일치하며 0으로 끝났는지 확인한다. 게이트 측정 명령은 독립된 증거다.
2608
2627
  "const condLine = body('## 불변식').split('\\n').find((l) => l.indexOf('조건 —') >= 0); if (!condLine) process.exit(1);",
2628
+ // 불변식에는 writer가 측정한 명령 전문을 기록하므로, 원문 gate 명령이 해당 필드에도 있어야 한다.
2609
2629
  "if (condLine.indexOf(cmdFromLog) < 0) process.exit(1);",
2630
+ "const signalLine = body('## 판정 신호').split('\\n').find((l) => l.indexOf('- Condition:') >= 0);",
2631
+ "const authoredCommand = signalLine?.match(/- Condition:\\s*(.+?)\\s*$/)?.[1]?.trim().replace(/^`([^`]+)`(?=\\s|를|$)/, '$1').replace(/\\s*를\\s*실행한다[.。]?$/, '').replace(/[.。]$/, '').trim();",
2632
+ "if (authoredCommand) { const s = e.authoredSignal; if (!s || s.command !== authoredCommand || s.exitCode !== 0) process.exit(1); const rendered = body('## 판정 신호'); if (!rendered.includes('exit 0') || !rendered.includes(s.command)) process.exit(1); const raw = (s.stdout + '\\n' + s.stderr).trim().slice(-1200) || '(출력 없음)'; if (!rendered.includes(raw.replace(/\\r?\\n/g, ' ⏎ '))) process.exit(1); }",
2610
2633
  // ⭐ 핵심 — 문서의 관측값이 로그의 값과 다르면 거부한다.
2611
2634
  "if (String(e.observedFail) !== String(failFromLog)) process.exit(1);",
2612
- "if (body('## 판정 신호').indexOf('fail ' + failFromLog) < 0) process.exit(1);",
2635
+ "if (!e.authoredSignal && body('## 판정 신호').indexOf('fail ' + failFromLog) < 0) process.exit(1);",
2613
2636
  // ⛔ 불변식 쪽 관측값도 대조한다 — 한쪽만 보면 다른 쪽에 거짓 수치가 들어간다(리뷰 must-fix).
2614
2637
  "if (body('## 불변식').indexOf('관측됨 — fail ' + failFromLog) < 0) process.exit(1);",
2615
2638
  // 문서 어디에도 로그와 **다른** fail 수치가 있으면 안 된다(정규식은 런타임에 만든다).
@@ -2622,8 +2645,9 @@ export function defaultSeams(o: DefaultSeamsOptions = {}): SelfImplementSeams {
2622
2645
  // 그 안에 게이트 로그가 통째로 들어 있어 `$(...)`·백틱이 **셸에서 실행**될 수 있었다(리뷰 must-fix).
2623
2646
  // ⇒ 파일로 넘기고 검사기가 읽는다. 명령 문자열에는 **고정 리터럴만** 남는다.
2624
2647
  writeFileSync(join(root, 'evidence.json'), JSON.stringify(evidence));
2648
+ writeFileSync(join(root, 'checker.cjs'), checker);
2625
2649
  const rule = withIndependentChecker({ kind: 'and', rules: [] }, {
2626
- command: `bun -e ${JSON.stringify(checker)}`,
2650
+ command: 'bun checker.cjs',
2627
2651
  timeoutMs: 5_000,
2628
2652
  });
2629
2653
  const outcome = await evaluateTermination(rule, { vault: {} as never, budget: {} as never, goalRoot: root });
@@ -2686,7 +2710,12 @@ export function defaultSeams(o: DefaultSeamsOptions = {}): SelfImplementSeams {
2686
2710
  taskCardId, storePath: taskAgentStatePath(), oldPr: outcome.supersededPr, newPr: number, url: outcome.url,
2687
2711
  });
2688
2712
  }
2689
- const opened: OpenPrOutcome = { url: outcome.url, number: Number.isFinite(number) ? number : 0, ...(rebind ? { rebind } : {}) };
2713
+ // `reused` also covers unbound legacy branches. The manager supplies the
2714
+ // proven old head only after exact same-card identity and lease checks.
2715
+ const boundCardReuse = outcome.reused && outcome.boundCardHeadRefName
2716
+ && !!taskCardId && /^[A-Za-z0-9][A-Za-z0-9._:-]{2,}$/.test(taskCardId)
2717
+ ? { headRefName: outcome.boundCardHeadRefName } : undefined;
2718
+ const opened: OpenPrOutcome = { url: outcome.url, number: Number.isFinite(number) ? number : 0, ...(boundCardReuse ? { boundCardReuse } : {}), ...(rebind ? { rebind } : {}) };
2690
2719
  return opened;
2691
2720
  },
2692
2721
 
@@ -19,6 +19,7 @@ import type { DocumentReferenceStatus } from './self-implement-runtime.js';
19
19
  import { resolveObserveOnlyDecision } from './observe-only.js';
20
20
  import { getUserConfig } from '../user-config.js';
21
21
  import { resolveAutoReview } from './context-capsule.js';
22
+ import { readDecomposeProposals } from '../self-dev/decompose-proposal.js';
22
23
 
23
24
  /** self implement CLI 옵션(commander) — `--no-draft` 는 draft:false 로, `--max-wait` 는 문자열로 도착. */
24
25
  export interface SelfImplementCliOpts {
@@ -71,6 +72,28 @@ export interface SelfImplementCliDeps {
71
72
  }>;
72
73
  /** runDevPipeline 내부 배선 주입(runSelfImplement/seams 등·테스트). */
73
74
  pipelineDeps?: DevPipelineDeps;
75
+ /** Parent-side run-ledger observation, injected to verify terminal JSON evidence. */
76
+ readGoalPlanRevision?: typeof readDecomposeProposals;
77
+ }
78
+
79
+ function attachGoalPlanRevisionObservation(
80
+ result: SelfImplementResult,
81
+ deps: SelfImplementCliDeps,
82
+ ): SelfImplementResult {
83
+ if (result.goalPlanRevision !== undefined || typeof result.runId !== 'string' || !result.runId.trim()) return result;
84
+ try {
85
+ // The ledger reader joins by shardId when present and otherwise by runId; a single-run
86
+ // child uses its runId as either key depending on the writer, so query both explicitly.
87
+ const scan = (deps.readGoalPlanRevision ?? readDecomposeProposals)({
88
+ shardIds: [result.runId],
89
+ runIds: [result.runId],
90
+ });
91
+ const observation = scan.goalPlanRevisions.get(result.runId) ?? scan.readFailure;
92
+ return observation ? { ...result, goalPlanRevision: observation } : result;
93
+ } catch {
94
+ // An unavailable observation stays absent; the supervisor treats that as a hold.
95
+ return result;
96
+ }
74
97
  }
75
98
 
76
99
  /**
@@ -210,6 +233,7 @@ export async function runSelfImplementCliCommand(
210
233
  : deps.pipelineDeps;
211
234
  const exec = deps.executeReroute ?? executeSelfImplementReroute;
212
235
  let { result, exitCode } = await exec(spec, pipelineDeps ? { pipelineDeps } : undefined);
236
+ result = attachGoalPlanRevisionObservation(result, deps);
213
237
 
214
238
  // ⭐⭐⭐ 단일 실행도 «루프»를 지난다 (E2) — 판정자는 연합과 «같은 자»다.
215
239
  // ⛔ 종전엔 단일이 실패하면 그냥 끝났다. 아무도 「다시 걸까」를 묻지 않았다.
@@ -257,9 +281,9 @@ export async function runSelfImplementCliCommand(
257
281
  rerun: async (_, invocation) => {
258
282
  const repairGoal = invocation.repairGoals?.[initialJob.taskId];
259
283
  const next = await exec(repairGoal ? { ...spec, input: { ...spec.input, text: repairGoal } } : spec, pipelineDeps ? { pipelineDeps } : undefined);
260
- result = next.result;
284
+ result = attachGoalPlanRevisionObservation(next.result, deps);
261
285
  exitCode = next.exitCode;
262
- return [{ ...singleRunAsJobResult(feature, next.result), taskId: initialJob.taskId }];
286
+ return [{ ...singleRunAsJobResult(feature, result), taskId: initialJob.taskId }];
263
287
  },
264
288
  });
265
289
  }
@@ -51,6 +51,7 @@ export const AUTOHEAL_ACTION_BY_CLASS: Readonly<Record<RunStopClass, AutohealAct
51
51
  'env-unrelated': 'clean-workspace-regate',
52
52
  'main-sync': 'rebase-regate',
53
53
  'pod-died': 'resume-from-salvage',
54
+ 'pod-vanished': 'needs-owner',
54
55
  'evidence-uncovered': 'derive-evidence-rejudge',
55
56
  'review-repeat': 'needs-owner',
56
57
  'review-out-of-scope': 'needs-owner',
@@ -11,7 +11,8 @@ export function seams(over: Partial<SelfImplementSeams> & { gateResults?: boolea
11
11
  const gateResults = over.gateResults ?? [true];
12
12
  let gateCall = 0;
13
13
  const features = over.features ?? [];
14
- return {
14
+ let openedHead = '';
15
+ const defaults: SelfImplementSeams = {
15
16
  // ⭐ 테스트는 «환경(실제 stdin)»이 아니라 계약을 검사한다 — 기본은 「사람이 있다」로 둔다.
16
17
  // 비-TTY 게이트 자체는 아래 전용 테스트가 «명시»로 확인한다.
17
18
  stdinIsInteractive: () => true,
@@ -41,4 +42,15 @@ export function seams(over: Partial<SelfImplementSeams> & { gateResults?: boolea
41
42
  decomposeShadowGoals: async () => ({ goals: [], decomposition: { recommendedMaxTasks: 6, actualTaskCount: 0, truncatedAtHardMax: false, exceededRecommendedMax: false, outcome: 'single-no-subtasks' } }),
42
43
  ...over,
43
44
  };
45
+ const openPr = defaults.openPr;
46
+ const defaultPrAttribution = Object.assign(async () => ({
47
+ headRefName: openedHead, createdAt: new Date(Date.now() + 60_000).toISOString(),
48
+ }), { testDefaultPrAttribution: true });
49
+ return {
50
+ ...defaults,
51
+ openPr: async (input) => { openedHead = input.head; return openPr(input); },
52
+ // Unit seams represent the PR just opened by this run. Tests of mismatch
53
+ // and metadata failures override this explicitly, without invoking gh.
54
+ readPrAttribution: over.readPrAttribution ?? defaultPrAttribution,
55
+ };
44
56
  }
@@ -2,6 +2,7 @@ import { spawnSync } from 'node:child_process';
2
2
  import { SPAWN_SYNC_MAX_BUFFER } from '../util/spawn-sync-output.js';
3
3
  import { isAbsolute } from 'node:path';
4
4
  import { selectGateTestFiles } from './gate-cli.js';
5
+ import { defineTrainGrouping } from '../../scripts/release-loop/gate-closure.js';
5
6
 
6
7
  export interface TrainReachCandidate {
7
8
  pr: string;
@@ -126,9 +127,14 @@ export function buildTrainReachDecision(input: TrainReachInput, inspect: Inspect
126
127
  const edges: Array<{ left: number; right: number; tests: string[]; paths: string[] }> = [];
127
128
  for (let left = 0; left < measured.length; left++) {
128
129
  for (let right = left + 1; right < measured.length; right++) {
129
- const tests = measured[left].tests.filter((path) => measured[right].tests.includes(path));
130
+ // 도달 시험 집합의 교집합이 «같은 열차»를 정한다 — TRAIN-REACH-GROUPING 원장(gate-closure.ts).
131
+ const grouping = defineTrainGrouping(
132
+ { pr: measured[left].candidate.pr, tests: measured[left].tests },
133
+ { pr: measured[right].candidate.pr, tests: measured[right].tests },
134
+ );
135
+ const tests = [...grouping.intersection];
130
136
  const paths = measured[left].files.filter((path) => measured[right].files.includes(path));
131
- if (!tests.length && !paths.length) continue;
137
+ if (!grouping.sameTrain && !paths.length) continue;
132
138
  edges.push({ left, right, tests, paths });
133
139
  parent[find(right)] = find(left);
134
140
  }
@@ -0,0 +1,36 @@
1
+ export interface AskOpQuestionEnvelope {
2
+ surface: 'telegram';
3
+ botId: string;
4
+ chatId: number | string;
5
+ threadId?: number | string;
6
+ messageId: number | string;
7
+ updateId: number | string;
8
+ question: string;
9
+ }
10
+
11
+ export const ASK_OP_COMMAND = 'askop';
12
+
13
+ export function formatAskOpQuestionEnvelope(input: AskOpQuestionEnvelope): string {
14
+ return [
15
+ `Telegram /${ASK_OP_COMMAND}`,
16
+ `botId=${input.botId}`,
17
+ `chatId=${input.chatId}`,
18
+ `threadId=${input.threadId ?? 'none'}`,
19
+ `messageId=${input.messageId}`,
20
+ `updateId=${input.updateId}`,
21
+ `question: ${input.question.trim()}`,
22
+ ].join('\n');
23
+ }
24
+
25
+ export function parseAskOpQuestionEnvelope(body: string): AskOpQuestionEnvelope | null {
26
+ const telegram = /^Telegram \/(?:askop|ask-op)\nbotId=([A-Za-z0-9_-]+)\nchatId=(-?\d+)\nthreadId=(none|\d+)\nmessageId=(\d+)\nupdateId=(\d+)\nquestion: ([\s\S]+)$/.exec(body);
27
+ if (telegram) {
28
+ const [, botId, chatId, threadId, messageId, updateId, question] = telegram;
29
+ return {
30
+ surface: 'telegram', botId: botId!, chatId: chatId!,
31
+ ...(threadId === 'none' ? {} : { threadId: threadId! }),
32
+ messageId: messageId!, updateId: updateId!, question: question!,
33
+ };
34
+ }
35
+ return null;
36
+ }
@@ -0,0 +1,200 @@
1
+ import { openMsgStore, openMsgStoreReadOnly, type Message, type MsgStore } from '../msg/msg-store.js';
2
+ import { subscribeMsgStream, type MsgStreamHandle } from '../msg/msg-sse-client.js';
3
+ import { join } from 'node:path';
4
+ import { elanousStateRoot } from '../autopilot/state-paths.js';
5
+ import { debug } from '../debug/log.js';
6
+ import { isOwnInstanceEndpoint, parseTelegramEndpoint, telegramEndpointKey } from './session-endpoint-key.js';
7
+ import type { TelegramBot } from '../telegram.js';
8
+ import { parseAskOpQuestionEnvelope } from './channel-ask-op-envelope.js';
9
+
10
+ export type ChannelOpEndpoint = { surface: 'telegram'; key: string } & NonNullable<ReturnType<typeof parseTelegramEndpoint>>;
11
+
12
+ export interface ChannelOpReplyTransport {
13
+ /** Must reject endpoint keys whose instance or bot is not served by this transport. */
14
+ canSend(endpoint: ChannelOpEndpoint): boolean;
15
+ /** The stable idempotency key lets a transport suppress retries if it supports them. */
16
+ send(endpoint: ChannelOpEndpoint, body: string, idempotencyKey: string): Promise<{ receiptId: string }>;
17
+ }
18
+
19
+ export function createTelegramChannelOpReplyTransport(input: {
20
+ bot: Pick<TelegramBot, 'sendMessage'>;
21
+ botId: string;
22
+ instance: string;
23
+ }): ChannelOpReplyTransport {
24
+ return {
25
+ canSend(endpoint) {
26
+ return endpoint.surface === 'telegram'
27
+ && isOwnInstanceEndpoint(endpoint.instance, input.instance)
28
+ && endpoint.botId === input.botId;
29
+ },
30
+ async send(endpoint, body, idempotencyKey) {
31
+ if (endpoint.surface !== 'telegram') throw new Error('Telegram transport cannot send to Discord');
32
+ const sent = await input.bot.sendMessage(Number(endpoint.chatId), body, {
33
+ ...(endpoint.threadId !== '0' ? { threadId: Number(endpoint.threadId) } : {}),
34
+ });
35
+ return { receiptId: sent && 'messageId' in sent ? `telegram:${sent.messageId}` : `telegram:${idempotencyKey}` };
36
+ },
37
+ };
38
+ }
39
+
40
+ export type ChannelOpReplyResult =
41
+ | { status: 'delivered'; receiptId: string }
42
+ | { status: 'already-delivered'; receiptId: string }
43
+ | { status: 'held' }
44
+ | { status: 'unknown' }
45
+ | { status: 'failed-permanent'; errorCode: number }
46
+ | { status: 'rejected'; reason: 'not-op-reply' | 'missing-question' | 'invalid-question' | 'invalid-endpoint' | 'unknown-endpoint' | 'already-answered' };
47
+
48
+ const CREATE_RECEIPTS = `CREATE TABLE IF NOT EXISTS channel_op_reply_receipts (
49
+ question_id INTEGER PRIMARY KEY REFERENCES msg_messages(id),
50
+ answer_id INTEGER NOT NULL UNIQUE REFERENCES msg_messages(id),
51
+ endpoint_key TEXT NOT NULL,
52
+ status TEXT NOT NULL CHECK(status IN ('sending', 'delivered', 'unknown', 'retry', 'failed-permanent')),
53
+ transport_receipt TEXT,
54
+ transport_error_code INTEGER,
55
+ updated_at TEXT NOT NULL
56
+ )`;
57
+
58
+ function telegramEndpoint(questionBody: string, instance: string): ChannelOpEndpoint | null {
59
+ const source = parseAskOpQuestionEnvelope(questionBody);
60
+ if (!source) return null;
61
+ const threadId = source.threadId ?? '0';
62
+ if (!Number.isSafeInteger(Number(source.chatId)) || !Number.isSafeInteger(Number(threadId))) return null;
63
+ const key = telegramEndpointKey({ instance, botId: source.botId, chatId: source.chatId, threadId });
64
+ const parsed = parseTelegramEndpoint(key);
65
+ return parsed ? { surface: 'telegram', key, ...parsed } : null;
66
+ }
67
+
68
+ function parseQuestionEndpoint(questionBody: string, instance: string): ChannelOpEndpoint | null {
69
+ return telegramEndpoint(questionBody, instance);
70
+ }
71
+
72
+ /**
73
+ * Resolve an OP reply through its durable replyTo link, claim one channel receipt,
74
+ * and send only to the endpoint captured in that question's stored envelope.
75
+ * An interrupted/ambiguous attempt is held rather than resent. Telegram 4xx
76
+ * responses other than rate limiting are terminal because the request cannot succeed unchanged.
77
+ */
78
+ export async function deliverChannelOpReply(
79
+ store: MsgStore,
80
+ answerId: number,
81
+ transport: ChannelOpReplyTransport,
82
+ options: { instance: string },
83
+ ): Promise<ChannelOpReplyResult> {
84
+ store.db.exec(CREATE_RECEIPTS);
85
+ const answer = store.getMessage(answerId);
86
+ if (!answer || answer.from !== 'OP' || answer.replyTo === undefined) return { status: 'rejected', reason: 'not-op-reply' };
87
+ const question = store.getMessage(answer.replyTo);
88
+ if (!question) return { status: 'rejected', reason: 'missing-question' };
89
+ if (question.to !== 'COORDINATOR' || question.kind !== 'question' || question.from !== 'TELEGRAM') {
90
+ return { status: 'rejected', reason: 'invalid-question' };
91
+ }
92
+ const source = parseAskOpQuestionEnvelope(question.body);
93
+ if (!source) return { status: 'rejected', reason: 'invalid-endpoint' };
94
+ const provenanceKey = `coord:tg-${source.botId}-${source.updateId}:COORDINATOR`;
95
+ const provenance = store.db.query(`SELECT 1 FROM msg_provenance WHERE provenance_key = ? AND message_id = ?`)
96
+ .get(provenanceKey, question.id);
97
+ if (!provenance) return { status: 'rejected', reason: 'invalid-question' };
98
+ const endpoint = parseQuestionEndpoint(question.body, options.instance);
99
+ if (!endpoint) return { status: 'rejected', reason: 'invalid-endpoint' };
100
+ if (!transport.canSend(endpoint)) return { status: 'rejected', reason: 'unknown-endpoint' };
101
+
102
+ const claim = store.db.transaction(() => {
103
+ const existing = store.db.query(`SELECT answer_id, endpoint_key, status, transport_receipt, transport_error_code
104
+ FROM channel_op_reply_receipts WHERE question_id = ?`).get(question.id) as {
105
+ answer_id: number; endpoint_key: string; status: 'sending' | 'delivered' | 'unknown' | 'retry' | 'failed-permanent'; transport_receipt: string | null; transport_error_code: number | null;
106
+ } | null;
107
+ if (existing) {
108
+ if (existing.answer_id !== answer.id || existing.endpoint_key !== endpoint.key) return { kind: 'already-answered' as const };
109
+ if (existing.status === 'delivered') return { kind: 'delivered' as const, receiptId: existing.transport_receipt ?? '' };
110
+ if (existing.status === 'failed-permanent') return { kind: 'failed-permanent' as const, errorCode: existing.transport_error_code ?? 400 };
111
+ if (existing.status !== 'retry') return { kind: 'held' as const };
112
+ store.db.query(`UPDATE channel_op_reply_receipts SET status = 'sending', updated_at = ?
113
+ WHERE question_id = ? AND answer_id = ? AND status = 'retry'`)
114
+ .run(new Date().toISOString(), question.id, answer.id);
115
+ return { kind: 'claimed' as const };
116
+ }
117
+ store.db.query(`INSERT INTO channel_op_reply_receipts(question_id, answer_id, endpoint_key, status, updated_at)
118
+ VALUES (?, ?, ?, 'sending', ?)`).run(question.id, answer.id, endpoint.key, new Date().toISOString());
119
+ return { kind: 'claimed' as const };
120
+ }).immediate();
121
+ if (claim.kind === 'already-answered') return { status: 'rejected', reason: 'already-answered' };
122
+ if (claim.kind === 'delivered') return { status: 'already-delivered', receiptId: claim.receiptId };
123
+ if (claim.kind === 'failed-permanent') return { status: 'failed-permanent', errorCode: claim.errorCode };
124
+ if (claim.kind === 'held') return { status: 'held' };
125
+
126
+ try {
127
+ const receipt = await transport.send(endpoint, answer.body, `ask-op-reply:${question.id}`);
128
+ store.db.transaction(() => {
129
+ store.db.query(`UPDATE channel_op_reply_receipts SET status = 'delivered', transport_receipt = ?, updated_at = ?
130
+ WHERE question_id = ? AND answer_id = ? AND status = 'sending'`)
131
+ .run(receipt.receiptId, new Date().toISOString(), question.id, answer.id);
132
+ }).immediate();
133
+ return { status: 'delivered', receiptId: receipt.receiptId };
134
+ } catch (error) {
135
+ const errorCode = error && typeof error === 'object' && 'errorCode' in error
136
+ ? (error as { errorCode?: unknown }).errorCode
137
+ : undefined;
138
+ const permanent4xx = typeof errorCode === 'number' && Number.isInteger(errorCode)
139
+ && errorCode >= 400 && errorCode < 500 && errorCode !== 429;
140
+ const permanentErrorCode = permanent4xx ? errorCode as number : null;
141
+ store.db.transaction(() => {
142
+ store.db.query(`UPDATE channel_op_reply_receipts SET status = ?, transport_error_code = ?, updated_at = ?
143
+ WHERE question_id = ? AND answer_id = ? AND status = 'sending'`)
144
+ .run(permanent4xx ? 'failed-permanent' : 'unknown', permanentErrorCode, new Date().toISOString(), question.id, answer.id);
145
+ }).immediate();
146
+ if (permanentErrorCode !== null) return { status: 'failed-permanent', errorCode: permanentErrorCode };
147
+ return { status: 'unknown' };
148
+ }
149
+ }
150
+
151
+ /** Explicit operator reconciliation for an ambiguous Telegram send. */
152
+ export function reconcileChannelOpReply(
153
+ store: MsgStore,
154
+ questionId: number,
155
+ decision: { status: 'delivered'; receiptId: string } | { status: 'not-delivered' },
156
+ ): boolean {
157
+ store.db.exec(CREATE_RECEIPTS);
158
+ if (decision.status === 'delivered' && !decision.receiptId.trim()) throw new Error('receiptId is required for delivered reconciliation');
159
+ const status = decision.status === 'delivered' ? 'delivered' : 'retry';
160
+ const receiptId = decision.status === 'delivered' ? decision.receiptId : null;
161
+ return store.db.transaction(() => store.db.query(`UPDATE channel_op_reply_receipts
162
+ SET status = ?, transport_receipt = ?, updated_at = ? WHERE question_id = ? AND status IN ('sending', 'unknown')`)
163
+ .run(status, receiptId, new Date().toISOString(), questionId).changes === 1).immediate();
164
+ }
165
+
166
+ export interface StartChannelOpReplyRouteOptions {
167
+ transport: ChannelOpReplyTransport;
168
+ instance: string;
169
+ botId: string;
170
+ cursorPath?: string;
171
+ openReadStore?: () => MsgStore;
172
+ openWriteStore?: () => MsgStore;
173
+ }
174
+
175
+ /** Listen to the Telegram seat mailbox and route only linked OP replies. */
176
+ export function startChannelOpReplyRoute(options: StartChannelOpReplyRouteOptions): MsgStreamHandle {
177
+ const cursorPath = options.cursorPath ?? join(
178
+ elanousStateRoot(), 'msg', 'sse-cursor', `TELEGRAM-channel-op-replies-${options.botId}.json`,
179
+ );
180
+ return subscribeMsgStream({
181
+ address: 'TELEGRAM',
182
+ cursorPath,
183
+ pollMs: 500,
184
+ openStore: options.openReadStore ?? (() => openMsgStoreReadOnly()),
185
+ onMessage: async (message: Message) => {
186
+ if (message.to !== 'TELEGRAM' || message.from !== 'OP' || message.replyTo === undefined) return;
187
+ const store = (options.openWriteStore ?? (() => openMsgStore()))();
188
+ try {
189
+ const result = await deliverChannelOpReply(store, message.id, options.transport, { instance: options.instance });
190
+ if (result.status === 'unknown' || result.status === 'rejected' || result.status === 'held' || result.status === 'failed-permanent') {
191
+ debug.log('channel-op-reply-route', result.status, {
192
+ answerId: message.id,
193
+ reason: result.status === 'rejected' ? result.reason : undefined,
194
+ errorCode: result.status === 'failed-permanent' ? result.errorCode : undefined,
195
+ });
196
+ }
197
+ } finally { store.close(); }
198
+ },
199
+ });
200
+ }
@@ -58,6 +58,8 @@ export interface RunTurnOpts {
58
58
  /** Optional callback for each streamed text delta — telegram uses this to
59
59
  * accumulate; CLI uses it to render live. */
60
60
  onDelta?: (delta: string) => void;
61
+ /** Optional transient stream recovery status for the originating UI. */
62
+ onStatusLine?: (line: string) => void;
61
63
  /** Optional provider override — for tests. */
62
64
  provider?: LLMProvider;
63
65
  /** Originating utterance surface. Omit only when the caller cannot
@@ -183,7 +185,7 @@ function toLLM(messages: SerializedMessage[], systemPrompt?: string): LLMMessage
183
185
  for (const m of messages) {
184
186
  // 'tool' = durable tool-telemetry (추적성·audit-only). Excluded from replay
185
187
  // so persisted tool rounds don't pollute the next turn's conversation context.
186
- if (m.role === 'tool') continue;
188
+ if (m.role === 'tool' || m.goalInterim === true) continue;
187
189
  const role: LLMMessage['role'] =
188
190
  m.role === 'user' ? 'user'
189
191
  : m.role === 'assistant' ? 'assistant'
@@ -473,6 +475,12 @@ export async function runTurn(opts: RunTurnOpts): Promise<RunTurnResult> {
473
475
  signal: opts.signal ?? new AbortController().signal,
474
476
  callbacks: {
475
477
  onText: (delta) => { opts.onDelta?.(delta); },
478
+ onGoalInterim: (interimText) => {
479
+ appendMessage(opts.sessionId, {
480
+ role: 'assistant', content: interimText, ts: new Date().toISOString(),
481
+ tokenEstimate: estimateTokens(interimText), goalInterim: true,
482
+ });
483
+ },
476
484
  onToolCall: (call) => { toolCallArgs.set(call.id, call.args); opts.onToolCall?.(call); },
477
485
  onToolResult: (call) => {
478
486
  try {
@@ -494,6 +502,7 @@ export async function runTurn(opts: RunTurnOpts): Promise<RunTurnResult> {
494
502
  onText: (delta /*, full */) => {
495
503
  opts.onDelta?.(delta);
496
504
  },
505
+ onStatus: (line) => { opts.onStatusLine?.(line); },
497
506
  dispatchTool: async (name, args, ctx) => dispatchTool(name, args, ctx),
498
507
  onToolCall: (call) => { toolCallArgs.set(call.id, call.args); opts.onToolCall?.(call); },
499
508
  onToolResult: (call) => {
@@ -0,0 +1,60 @@
1
+ // Shortest session-id prefix that still names exactly one session (TUI-RESUME-PICKER).
2
+ // Lists used to cut every id to 8 characters, so two sessions sharing those 8 looked the same and
3
+ // `/session load <shown prefix>` failed as ambiguous. `resolveSessionId` searches the whole index,
4
+ // so uniqueness is measured against every id there — not only the rows on screen.
5
+ import { listSessions } from './index.js';
6
+
7
+ /** Never shorter than this, so short lists keep the familiar 8-character look. */
8
+ export const SESSION_ID_PREFIX_MIN = 8;
9
+
10
+ function commonPrefixLength(a: string, b: string): number {
11
+ const n = Math.min(a.length, b.length);
12
+ let i = 0;
13
+ while (i < n && a.charCodeAt(i) === b.charCodeAt(i)) i++;
14
+ return i;
15
+ }
16
+
17
+ /**
18
+ * For each id in `ids`, the shortest prefix (≥ `min`) that no other id in `universe` starts with.
19
+ * An id that is itself a prefix of another id gets the whole id (resolveSessionId takes an exact match).
20
+ */
21
+ export function uniqueIdPrefixes(ids: readonly string[], universe: readonly string[], min = SESSION_ID_PREFIX_MIN): Map<string, string> {
22
+ const sorted = [...new Set([...universe, ...ids])].sort();
23
+ const position = new Map(sorted.map((id, i) => [id, i]));
24
+ const out = new Map<string, string>();
25
+ for (const id of ids) {
26
+ if (out.has(id)) continue;
27
+ const i = position.get(id)!;
28
+ // In sorted order the longest shared prefix is always with a direct neighbour.
29
+ const shared = Math.max(
30
+ i > 0 ? commonPrefixLength(id, sorted[i - 1]!) : 0,
31
+ i + 1 < sorted.length ? commonPrefixLength(id, sorted[i + 1]!) : 0,
32
+ );
33
+ out.set(id, id.slice(0, Math.min(id.length, Math.max(min, shared + 1))));
34
+ }
35
+ return out;
36
+ }
37
+
38
+ /** `uniqueIdPrefixes` against every session in the store (the set `/session load` resolves in). */
39
+ export function sessionIdPrefixes(ids: readonly string[], root?: string): Map<string, string> {
40
+ const universe = (root === undefined ? listSessions() : listSessions({}, root)).map((m) => m.id);
41
+ return uniqueIdPrefixes(ids, universe);
42
+ }
43
+
44
+ /** Display helper: the unique prefix of one id, padded so a column stays aligned. */
45
+ export function idPrefixCell(prefixes: ReadonlyMap<string, string>, id: string): string {
46
+ const width = Math.max(SESSION_ID_PREFIX_MIN, ...[...prefixes.values()].map((p) => p.length));
47
+ return (prefixes.get(id) ?? id.slice(0, SESSION_ID_PREFIX_MIN)).padEnd(width);
48
+ }
49
+
50
+ const pad2 = (n: number) => String(n).padStart(2, '0');
51
+
52
+ /**
53
+ * `MM-DD HH:mm` in the viewer's local time zone. Lists used to slice the stored UTC ISO string
54
+ * (`updatedAt.slice(5, 16)`), so a KST viewer saw 16:24 for a session touched at 01:24.
55
+ */
56
+ export function sessionListTime(iso: string): string {
57
+ const d = new Date(iso);
58
+ if (Number.isNaN(d.getTime())) return iso.slice(5, 16).replace('T', ' ');
59
+ return `${pad2(d.getMonth() + 1)}-${pad2(d.getDate())} ${pad2(d.getHours())}:${pad2(d.getMinutes())}`;
60
+ }