elanous 0.2.28 → 0.2.31

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 (818) 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/{y1ltt7oCZxVpC6zVPhZ2O → LSXfY0u9QtfDbejY0Ukf_}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{ab4d57c2.e90bc2cb31949045.js → 0bb0ff36.b8d418980951e5ba.js} +7 -7
  5. package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +27 -0
  8. package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +287 -0
  9. package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +62 -0
  10. package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/{5492-e05e26a033ba80d2.js → 1335-6731f392c35216eb.js} +3 -3
  12. package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1654.32de4b324981a188.js +23 -0
  15. package/apps/pwa/out/_next/static/chunks/1834-50625904996a8fa8.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +149 -0
  17. package/apps/pwa/out/_next/static/chunks/1913.7cc6fb6055b1ed3f.js +41 -0
  18. package/apps/pwa/out/_next/static/chunks/2001.6c7e0fd02190886c.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/{8578.dff22d988cc2b106.js → 2213.2ccbada92c33ea0f.js} +3 -3
  24. package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/{5081.a240b63fad28663a.js → 2871.0bca6137343b3f76.js} +1 -1
  28. package/apps/pwa/out/_next/static/chunks/2898.fd781bc7cf01a7b7.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/2940-619bfd8ef337c611.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/{2846.d6a433b8663819a5.js → 2985.39ccdecd36848b12.js} +4 -4
  31. package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +115 -0
  32. package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +64 -0
  33. package/apps/pwa/out/_next/static/chunks/{f4dfbfc0.a69fb12f854882aa.js → 3267c0e6.d34854e7b3984a6e.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/3278.2e5d15b53a4091c8.js +2 -0
  35. package/apps/pwa/out/_next/static/chunks/3541-ce3a5424ed5ad7f1.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{3143.257997a5f1ed79df.js → 3902.e1e71aaac850a045.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/{16e57f67.3ea19e893461e611.js → 409f1e57.d0649fc47691ebfe.js} +1 -1
  41. package/apps/pwa/out/_next/static/chunks/{1146.80d15ea7c6e6ee95.js → 4111.2bfedbb233ad206b.js} +1 -1
  42. package/apps/pwa/out/_next/static/chunks/{1516.83dd2c1b86b4e507.js → 4174.92ed04922709ac9e.js} +2 -2
  43. package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +36 -0
  45. package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +286 -0
  49. package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +77 -0
  50. package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +226 -0
  51. package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/{9938.b23e4d4dfa0114cd.js → 4999.c064a4000c2a9e94.js} +2 -2
  53. package/apps/pwa/out/_next/static/chunks/5173-233188df2f42c626.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/{1157.f08bf2b70915e176.js → 5304.04d24756f242a094.js} +2 -2
  57. package/apps/pwa/out/_next/static/chunks/{7752.5cbdd0b433c54af9.js → 5307.60f2209e809bd627.js} +1 -1
  58. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/{9917-9e26abc5f7772735.js → 5458-16cd7a2b51b74c8c.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/{6196.34d6b229079e9e28.js → 5525.86debf231e181813.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{4593.10f5b9bd702d4a6c.js → 5543.a438b8ab5a13ea47.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +74 -0
  65. package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +94 -0
  67. package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/{7483.ba01c6c209b81bba.js → 6092.a7f99e68b188ca66.js} +1 -1
  70. package/apps/pwa/out/_next/static/chunks/60fb96c9.360b01d8d4927b7b.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/{9974.e77b4ff4884557b3.js → 6157.0c9af021de4fb31b.js} +2 -2
  72. package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/{3309.364573ceedbdfd5f.js → 6323.8672b4817a306928.js} +1 -1
  74. package/apps/pwa/out/_next/static/chunks/{94.4cfed21c0b781a06.js → 6433.fc573af22bbc9ab7.js} +4 -4
  75. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/{949.1e7d45ccb71580aa.js → 6517.4147878ac06d584d.js} +2 -2
  77. package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +32 -0
  78. package/apps/pwa/out/_next/static/chunks/6544cb48.a87fe20ddf137be2.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +104 -0
  80. package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/{2528.3868070ef1be69f9.js → 6767.ea607cf0c20a25af.js} +2 -2
  85. package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +93 -0
  86. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{1743.563d3168e95825ef.js → 7502.ccd5b8065545edd0.js} +2 -2
  93. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +8 -0
  94. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{5408.377c8c543635b81f.js → 7862.30a8d6482bb238eb.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/{65ebff95.081daeff622d238e.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/{2697.76ca2ac3efef6f3b.js → 8018.a32663f04a6fc5f9.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/8097-92f87bd108322f66.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +24 -0
  109. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/9138.b6e80031afb1d973.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/{4204.a409ab6250c0f6a8.js → 9221.7d22eaf353a2d4e7.js} +1 -1
  113. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/{5785-ea8d2c633b6688e3.js → 9279-d28c5b7754d010ae.js} +1 -1
  115. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9398-6aed28f0a96d0d6f.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/997ce8a5-2ad501927003b41b.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{9311.24c8f5ea793253dd.js → 9989.3694300e5f000b14.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-bf3634a117322df7.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-3535a4a69f1fafaa.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-b9f51447f757fbf2.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-fa46d4588e8442c2.js → page-2ebb8fd59b9461f9.js} +1 -1
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-a2fc4e49a4fa4ba8.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-5a503541353e60a8.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-6025101384e361a5.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-f4b630cc8b5273cd.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-a645f00a06483e9a.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-61ac22cbab1ee4ec.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e9bab7413b028b28.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-c992eafe028b642e.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-e547e6ce55f1fb33.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-d27e1b9850fd54bf.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-805ac2e137b7a121.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-0fec29c7ba01894b.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-339a07410cd6f36b.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/{page-ced0bcfc6542b3fc.js → page-349f2752d8cd37ad.js} +1 -1
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-d5c6dcf31c25cecc.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-2fd93ed8c9f16580.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-9b564dbff0fefc35.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-62f4475d3c38fb9b.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-814ba51385225776.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-397d479626e5a459.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-af1bba4e3251b728.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ad3be5e7d3fdce9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-f219ccdbc0bf27df.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4da93ad35d4a8d28.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-456666766e5ce6fc.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-7404e377e8adb8c5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-14456240ed2a36ad.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-3a658d5fa6d16a25.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-0157de6e85f8bb6b.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-cb249e81ed339318.js → page-0a07363b130182a1.js} +1 -1
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-841d73d4ac44ed49.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6f43a3d1146e6377.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-521ee23ac8c0abfa.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-a9992ee285efaa83.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-3d48e85fa89ec04f.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d2ced71132fac9b2.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-f08358bdf251adb9.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-233c71cd5f68f0d7.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-70151d78de2f375e.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-dcac33a3e2cb72c0.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-149dc1caba411bb9.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-0448145ccd5c45c1.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-9cb0c444903da65d.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-17e504c396e0e389.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{6def8a8e.c81f9ca41028eccf.js → b313b242.cb1265eea908db61.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/{e87d89b9.2e71c0ae475d28a1.js → e5012ffe.f727e23c231f4342.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/{e117f801.e92bf10242653497.js → ebc7d829.264a0bcb6c750b50.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +1 -0
  183. package/apps/pwa/out/_next/static/css/{72becfd42807b50d.css → 3f5fc6f96e2cf7b2.css} +1 -1
  184. package/apps/pwa/out/approvals/index.html +1 -1
  185. package/apps/pwa/out/approvals/index.txt +23 -23
  186. package/apps/pwa/out/autopilot/index.html +1 -1
  187. package/apps/pwa/out/autopilot/index.txt +23 -23
  188. package/apps/pwa/out/board/index.html +1 -1
  189. package/apps/pwa/out/board/index.txt +23 -23
  190. package/apps/pwa/out/botlab/index.html +1 -1
  191. package/apps/pwa/out/botlab/index.txt +22 -22
  192. package/apps/pwa/out/bots/index.html +1 -1
  193. package/apps/pwa/out/bots/index.txt +22 -22
  194. package/apps/pwa/out/ceo/index.html +1 -1
  195. package/apps/pwa/out/ceo/index.txt +23 -23
  196. package/apps/pwa/out/chat/index.html +1 -1
  197. package/apps/pwa/out/chat/index.txt +22 -22
  198. package/apps/pwa/out/consult/index.html +1 -1
  199. package/apps/pwa/out/consult/index.txt +23 -23
  200. package/apps/pwa/out/control/index.html +1 -1
  201. package/apps/pwa/out/control/index.txt +23 -23
  202. package/apps/pwa/out/decisions/index.html +1 -1
  203. package/apps/pwa/out/decisions/index.txt +22 -22
  204. package/apps/pwa/out/design-check/index.html +1 -1
  205. package/apps/pwa/out/design-check/index.txt +23 -23
  206. package/apps/pwa/out/editor/index.html +1 -1
  207. package/apps/pwa/out/editor/index.txt +23 -23
  208. package/apps/pwa/out/exec/index.html +1 -1
  209. package/apps/pwa/out/exec/index.txt +23 -23
  210. package/apps/pwa/out/field/index.html +1 -1
  211. package/apps/pwa/out/field/index.txt +23 -23
  212. package/apps/pwa/out/healthz +1 -1
  213. package/apps/pwa/out/index.html +1 -1
  214. package/apps/pwa/out/index.txt +22 -22
  215. package/apps/pwa/out/inside/index.html +1 -1
  216. package/apps/pwa/out/inside/index.txt +22 -22
  217. package/apps/pwa/out/intake/index.html +1 -1
  218. package/apps/pwa/out/intake/index.txt +23 -23
  219. package/apps/pwa/out/live/index.html +1 -1
  220. package/apps/pwa/out/live/index.txt +23 -23
  221. package/apps/pwa/out/live-run/index.html +1 -1
  222. package/apps/pwa/out/live-run/index.txt +23 -23
  223. package/apps/pwa/out/loops/index.html +1 -1
  224. package/apps/pwa/out/loops/index.txt +22 -22
  225. package/apps/pwa/out/market/index.html +1 -1
  226. package/apps/pwa/out/market/index.txt +22 -22
  227. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  228. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  229. package/apps/pwa/out/morning/index.html +1 -1
  230. package/apps/pwa/out/morning/index.txt +23 -23
  231. package/apps/pwa/out/observatory/index.html +1 -1
  232. package/apps/pwa/out/observatory/index.txt +23 -23
  233. package/apps/pwa/out/ops/checklist/index.html +1 -1
  234. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  235. package/apps/pwa/out/ops/release/index.html +1 -1
  236. package/apps/pwa/out/ops/release/index.txt +22 -22
  237. package/apps/pwa/out/ops/seats/index.html +1 -1
  238. package/apps/pwa/out/ops/seats/index.txt +22 -22
  239. package/apps/pwa/out/outputs/index.html +1 -1
  240. package/apps/pwa/out/outputs/index.txt +22 -22
  241. package/apps/pwa/out/reflection/index.html +1 -1
  242. package/apps/pwa/out/reflection/index.txt +23 -23
  243. package/apps/pwa/out/scheduler/index.html +1 -1
  244. package/apps/pwa/out/scheduler/index.txt +23 -23
  245. package/apps/pwa/out/sessions/index.html +1 -1
  246. package/apps/pwa/out/sessions/index.txt +22 -22
  247. package/apps/pwa/out/settings/devices/index.html +1 -1
  248. package/apps/pwa/out/settings/devices/index.txt +23 -23
  249. package/apps/pwa/out/settings/index.html +1 -1
  250. package/apps/pwa/out/settings/index.txt +23 -23
  251. package/apps/pwa/out/setup/done/index.html +1 -1
  252. package/apps/pwa/out/setup/done/index.txt +23 -23
  253. package/apps/pwa/out/setup/index.html +1 -1
  254. package/apps/pwa/out/setup/index.txt +23 -23
  255. package/apps/pwa/out/share/index.html +1 -1
  256. package/apps/pwa/out/share/index.txt +23 -23
  257. package/apps/pwa/out/showroom/index.html +1 -1
  258. package/apps/pwa/out/showroom/index.txt +22 -22
  259. package/apps/pwa/out/tasks/index.html +1 -1
  260. package/apps/pwa/out/tasks/index.txt +23 -23
  261. package/apps/pwa/out/term/index.html +1 -1
  262. package/apps/pwa/out/term/index.txt +23 -23
  263. package/apps/pwa/out/today/index.html +1 -1
  264. package/apps/pwa/out/today/index.txt +23 -23
  265. package/apps/pwa/out/trace/index.html +1 -1
  266. package/apps/pwa/out/trace/index.txt +23 -23
  267. package/apps/pwa/out/vault/index.html +1 -1
  268. package/apps/pwa/out/vault/index.txt +23 -23
  269. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  270. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  271. package/apps/pwa/out/workflows/index.html +1 -1
  272. package/apps/pwa/out/workflows/index.txt +23 -23
  273. package/apps/pwa/out/workspace/index.html +1 -1
  274. package/apps/pwa/out/workspace/index.txt +23 -23
  275. package/apps/pwa/out/worktrees/index.html +1 -1
  276. package/apps/pwa/out/worktrees/index.txt +23 -23
  277. package/bin/elanous.mjs +7 -3
  278. package/graphs/context/nightly-condense.yaml +1 -0
  279. package/graphs/intake/intake-daily.yaml +8 -1
  280. package/graphs/intake/recipes.yaml +5 -0
  281. package/graphs/lecture/lecture-note.yaml +2 -2
  282. package/graphs/ops/harness-gc.yaml +1 -0
  283. package/graphs/release/recipes.yaml +3 -0
  284. package/graphs/release/release-loop.yaml +15 -7
  285. package/graphs/units/recipes.yaml +3 -0
  286. package/graphs/units/release-gate-recheck.yaml +15 -0
  287. package/package.json +2 -1
  288. package/plugins/agent-team/agents/research.md +1 -0
  289. package/scripts/check-native-tool-wiring.ts +3 -2
  290. package/scripts/ci-android-unit-tests.ts +16 -0
  291. package/scripts/ci-typecheck-changed.ts +40 -11
  292. package/scripts/coord-channel-watch.sh +45 -19
  293. package/scripts/coord-role-pack.ts +222 -0
  294. package/scripts/cron-run.ts +96 -3
  295. package/scripts/detect-test-interference.ts +38 -5
  296. package/scripts/gate-pr-cache.ts +65 -0
  297. package/scripts/gh-surface/capture.ts +126 -0
  298. package/scripts/gh-surface/gh +40 -0
  299. package/scripts/import-graph-scc.ts +38 -0
  300. package/scripts/install.ps1 +19 -0
  301. package/scripts/intake-social.ts +181 -0
  302. package/scripts/lecture-note/node.ts +71 -4
  303. package/scripts/lib/android-toolchain.ts +32 -0
  304. package/scripts/lib/deterministic-env.ts +62 -0
  305. package/scripts/lib/gate-test-env.ts +19 -0
  306. package/scripts/lib/morning-report-options.ts +41 -0
  307. package/scripts/measure-goal-grounding-corpus.ts +2 -1
  308. package/scripts/pr-land-extra-remote-gates.ts +49 -0
  309. package/scripts/ratchets/test-interference-patterns.allowlist.txt +257 -0
  310. package/scripts/ratchets/test-interference-patterns.ts +367 -0
  311. package/scripts/release-loop/cut-branch.ts +4 -3
  312. package/scripts/release-loop/export-check-node.ts +0 -1
  313. package/scripts/release-loop/fixtures/warm-failure-assertion/sample.junit.xml +8 -0
  314. package/scripts/release-loop/fixtures/warm-job-029/sample.json +1 -0
  315. package/scripts/release-loop/fixtures/warm-job-029/sample.junit.xml +10 -0
  316. package/scripts/release-loop/gate-batch-safe.ts +23 -0
  317. package/scripts/release-loop/gate-closure.ts +12 -8
  318. package/scripts/release-loop/gate-diff.ts +1 -1
  319. package/scripts/release-loop/gate-history.ts +422 -0
  320. package/scripts/release-loop/gate-host-mirror.ts +66 -0
  321. package/scripts/release-loop/gate-node.ts +806 -94
  322. package/scripts/release-loop/gate-partial.ts +106 -9
  323. package/scripts/release-loop/gate-pr-cache.ts +66 -0
  324. package/scripts/release-loop/gate-prewarm-plan.ts +66 -0
  325. package/scripts/release-loop/gate-r2-verdict.ts +189 -0
  326. package/scripts/release-loop/gate-recheck-plan-node.ts +52 -0
  327. package/scripts/release-loop/gate-triage-node.ts +190 -0
  328. package/scripts/release-loop/gate-warm-artifacts.ts +253 -0
  329. package/scripts/release-loop/import-graph-scc-run.ts +54 -0
  330. package/scripts/release-loop/import-graph-scc.ts +215 -0
  331. package/scripts/release-loop/node-verdict.ts +2 -0
  332. package/scripts/release-loop/probe-pod-host-dirs-live.ts +113 -0
  333. package/scripts/release-loop/resume-release.ts +33 -4
  334. package/scripts/release-loop/resume.ts +13 -5
  335. package/scripts/release-loop/spawn-lane.ts +51 -0
  336. package/scripts/release-loop/tui-node-checks.ts +23 -0
  337. package/scripts/release-loop/tui-sim-node.ts +3 -2
  338. package/scripts/release-loop/unattended-release.ts +16 -0
  339. package/scripts/release-loop/version-node.ts +62 -4
  340. package/scripts/test-deterministic.ts +46 -73
  341. package/scripts/train-reach-grouping.ts +48 -0
  342. package/scripts/tsc-incremental-cache.ts +86 -0
  343. package/scripts/tsc-incremental-diagnostics.ts +76 -0
  344. package/scripts/tsc-main-safety-net.ts +2 -2
  345. package/scripts/usage-rollup.ts +11 -3
  346. package/src/acp/client.ts +4 -1
  347. package/src/acp/core-turn-bridge.ts +145 -24
  348. package/src/acp/elanous-extensions.ts +2 -0
  349. package/src/acp/server.ts +2 -0
  350. package/src/ad-pipeline/run.ts +4 -2
  351. package/src/agent/ref-grounding.ts +18 -0
  352. package/src/agent/runner.ts +169 -3
  353. package/src/agent/subagent-callable.ts +3 -2
  354. package/src/agent-mission/review-loop.ts +6 -3
  355. package/src/agent-substrate/acp-implementer.ts +14 -2
  356. package/src/agent-substrate/pr-reviewer.ts +41 -21
  357. package/src/agent-substrate/self-review-cli.ts +30 -4
  358. package/src/autopilot/pr-manager.ts +62 -7
  359. package/src/briefing/brief-items.ts +24 -22
  360. package/src/budget/pty-usage-reemit.ts +7 -0
  361. package/src/budget/run-usage-rollup.ts +9 -0
  362. package/src/budget/usage-daily-store.ts +98 -0
  363. package/src/capture/tui-self-report.ts +37 -4
  364. package/src/chat/chat-cli.ts +10 -2
  365. package/src/chat/index.ts +107 -20
  366. package/src/chat/input-control-key.ts +5 -3
  367. package/src/chat/pickers/modal-runtime.ts +1 -0
  368. package/src/chat/pickers/modals.ts +3 -1
  369. package/src/chat/tool-interrupt-behavior.ts +38 -0
  370. package/src/chat/tool-render/dispatch.ts +5 -1
  371. package/src/chat/turn-typeahead.ts +191 -29
  372. package/src/cli/__fixtures__/agent-help-before/agent.txt +4 -2
  373. package/src/cli/agent-cli.ts +41 -13
  374. package/src/cli/config-audit.ts +123 -0
  375. package/src/cli/dashboard-name-flag.ts +48 -0
  376. package/src/cli/decisions-cli.ts +80 -6
  377. package/src/cli/doctor-cli.ts +80 -0
  378. package/src/cli/log-event-names.ts +19 -0
  379. package/src/cli/mcp-login.ts +21 -5
  380. package/src/cli/msg-cli.ts +133 -2
  381. package/src/cli/pr-cli.ts +546 -112
  382. package/src/cli/pr-land-heavy-remote.ts +233 -0
  383. package/src/cli/pr-land-overlap-evidence.ts +167 -14
  384. package/src/cli/pr-land-pod-shadow-job.ts +83 -0
  385. package/src/cli/pr-land-pod-shadow.ts +16 -3
  386. package/src/cli/pr-land-virtual-rebase.ts +108 -0
  387. package/src/cli/pty-takeover-cli.ts +125 -16
  388. package/src/cli/release-cli.ts +122 -14
  389. package/src/cli/remote-resolve.ts +2 -1
  390. package/src/cli/seat-cli.ts +164 -19
  391. package/src/cli/self-update.ts +5 -2
  392. package/src/cli/tasks-cli.ts +105 -21
  393. package/src/cli/usage-cli.ts +146 -12
  394. package/src/cli/usage-daily-cli.ts +84 -0
  395. package/src/context-bus/context-first.ts +13 -0
  396. package/src/context-bus/context-now.ts +95 -7
  397. package/src/context-bus/ops-events.ts +75 -0
  398. package/src/control-plane/lease-holder.ts +12 -8
  399. package/src/control-plane/ledger.ts +163 -4
  400. package/src/control-plane/server.ts +91 -11
  401. package/src/core-turn/auth-rejected-notice.ts +41 -0
  402. package/src/core-turn/run-core-turn.ts +14 -2
  403. package/src/core-turn/run-goal-loop.ts +239 -4
  404. package/src/core-turn/seat-turn-cap.ts +79 -0
  405. package/src/core-turn/short-question.ts +78 -13
  406. package/src/core-turn/types.ts +10 -0
  407. package/src/dashboard/acp-active-model.ts +40 -0
  408. package/src/dashboard/acp-boot.ts +3 -0
  409. package/src/dashboard/auto-compact-runtime.ts +2 -0
  410. package/src/dashboard/boot-banner.ts +80 -0
  411. package/src/dashboard/dashboard-status-lines.ts +11 -0
  412. package/src/dashboard/detail-viewer-runtime.ts +15 -2
  413. package/src/dashboard/event-loop-stall-monitor.ts +4 -0
  414. package/src/dashboard/goal-loop-thinking.ts +16 -0
  415. package/src/dashboard/hitl-boot.ts +9 -4
  416. package/src/dashboard/index.ts +448 -998
  417. package/src/dashboard/input/chat-main-entry-runtime.ts +2 -0
  418. package/src/dashboard/input/chat-main-log-actions.ts +4 -0
  419. package/src/dashboard/input/chat-main-log-command.ts +12 -1
  420. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +176 -4
  421. package/src/dashboard/input/chat-main-session.ts +14 -3
  422. package/src/dashboard/input/chat-main-slash-command.ts +7 -0
  423. package/src/dashboard/input/chat-main-turn.ts +14 -4
  424. package/src/dashboard/input/compact-prepass-recovery.ts +130 -0
  425. package/src/dashboard/input/dashboard-chord-actions.ts +10 -1
  426. package/src/dashboard/input/dashboard-chord-runtime.ts +2 -0
  427. package/src/dashboard/input/external-input-host.ts +71 -0
  428. package/src/dashboard/input/internal-turn.ts +261 -0
  429. package/src/dashboard/input/log-fold-binding.ts +18 -0
  430. package/src/dashboard/input/mouse-wiring.ts +17 -4
  431. package/src/dashboard/input/seat-autowake.ts +318 -0
  432. package/src/dashboard/input/turn-steer-bridge.ts +164 -0
  433. package/src/dashboard/log-click-runtime.ts +5 -3
  434. package/src/dashboard/loop-scheduler.ts +72 -0
  435. package/src/dashboard/running-build-status.ts +74 -0
  436. package/src/dashboard/seat-boot-preamble.ts +131 -0
  437. package/src/dashboard/seat-local-instructions.ts +305 -0
  438. package/src/dashboard/skill-runtime.ts +2 -0
  439. package/src/dashboard/slash-runtime/dashboard-handlers.ts +220 -1203
  440. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
  441. package/src/dashboard/slash-runtime/index.ts +13 -0
  442. package/src/dashboard/slash-runtime/model-choices.ts +35 -0
  443. package/src/dashboard/term-slash-runtime.ts +15 -0
  444. package/src/dashboard/turn-busy-teardown.ts +50 -0
  445. package/src/dashboard/turn-preamble.ts +30 -2
  446. package/src/dashboard/turn-session-layers.ts +176 -0
  447. package/src/dashboard/turn-stream-formatter.ts +14 -6
  448. package/src/dashboard/turn-stream-presentation-applier.ts +8 -0
  449. package/src/decisions/decision-ledger.ts +45 -4
  450. package/src/discord-self-message.ts +4 -4
  451. package/src/domains/release-tool.ts +26 -10
  452. package/src/domains/surface-events.ts +4 -1
  453. package/src/domains/watch-default-scheduler.ts +8 -9
  454. package/src/field-note/transcribe.ts +17 -0
  455. package/src/fold-stack.ts +24 -1
  456. package/src/git-fs/dirty.ts +32 -4
  457. package/src/git-fs/index.ts +43 -1
  458. package/src/github/remote-call.ts +81 -0
  459. package/src/goals/registry.ts +46 -6
  460. package/src/goals/types.ts +7 -1
  461. package/src/graph-runner/runner.ts +2 -0
  462. package/src/grok/credential.ts +26 -0
  463. package/src/harness/harness-clean.ts +2 -1
  464. package/src/harness/harness-cli-command.ts +52 -5
  465. package/src/harness/harness-gc.ts +34 -6
  466. package/src/harness/harness-incidents.ts +57 -20
  467. package/src/harness/harness-pod-dispatch.ts +87 -10
  468. package/src/harness/harness-queue.ts +53 -4
  469. package/src/harness/harness-stop.ts +4 -3
  470. package/src/harness/harness-substrate-default.ts +78 -7
  471. package/src/harness/harness-worktree-auto.ts +2 -1
  472. package/src/harness/harness-worktrees.ts +3 -2
  473. package/src/hooks/dispatch.ts +2 -1
  474. package/src/index.ts +166 -26
  475. package/src/input/external-input-queue.ts +251 -0
  476. package/src/intake-plane/slash.ts +14 -3
  477. package/src/interactive-terminal-modal.ts +13 -0
  478. package/src/keybindings.ts +4 -1
  479. package/src/llm/route-decision.ts +25 -0
  480. package/src/llm/tool-loop-steered-rejection.ts +33 -0
  481. package/src/llm-stream-retry-display.ts +59 -0
  482. package/src/llm.ts +391 -74
  483. package/src/log-entry.ts +3 -3
  484. package/src/log-pane/search.ts +29 -4
  485. package/src/loops/agent-reply.ts +256 -0
  486. package/src/loops/budget.ts +37 -7
  487. package/src/loops/consensus.ts +348 -0
  488. package/src/loops/loop-cli.ts +3 -2
  489. package/src/loops/msg-address.ts +57 -0
  490. package/src/loops/msg-wake.ts +484 -0
  491. package/src/loops/observe.ts +19 -3
  492. package/src/loops/orchestrator/inbox.ts +60 -3
  493. package/src/loops/orchestrator/tick.ts +80 -6
  494. package/src/loops/orchestrator/traffic.ts +64 -1
  495. package/src/loops/registry.ts +72 -4
  496. package/src/market/signed-index.ts +14 -0
  497. package/src/mcp/mcp-oauth.ts +54 -5
  498. package/src/memory.ts +20 -5
  499. package/src/models/prompts.ts +28 -0
  500. package/src/msg/msg-sse-client.ts +223 -0
  501. package/src/msg/msg-store.ts +86 -2
  502. package/src/mss/logging/log-store.ts +225 -1
  503. package/src/native-tool-catalog.ts +125 -0
  504. package/src/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
  505. package/src/nexus/api/http-server.ts +59 -15
  506. package/src/nexus/api/loop-resources.ts +19 -3
  507. package/src/nexus/api/ops-api.ts +13 -0
  508. package/src/nexus/api/project-autopsy.ts +127 -0
  509. package/src/nexus/api/terminals.ts +3 -0
  510. package/src/nexus/api/workflow-approvals.ts +2 -0
  511. package/src/nexus/daemon-thin-inventory.md +37 -0
  512. package/src/nexus/index.ts +70 -0
  513. package/src/nexus/onboarding/first-boot-wizard.ts +56 -2
  514. package/src/nexus/state/state.ts +1 -0
  515. package/src/oauth/codex-account-store.ts +15 -3
  516. package/src/oauth/codex-billing-route.ts +31 -0
  517. package/src/oauth/store.ts +32 -7
  518. package/src/onboarding/first-run.ts +28 -3
  519. package/src/ops/overview-cache.ts +16 -4
  520. package/src/ops/overview-collect.ts +19 -2
  521. package/src/ops/resources.ts +82 -0
  522. package/src/panes/log-pane.ts +67 -8
  523. package/src/persona/presets.ts +44 -0
  524. package/src/plugins/maker/connector-maker.ts +41 -0
  525. package/src/plugins/maker/skill-maker.ts +42 -0
  526. package/src/plugins/maker/wizard-generate.ts +6 -4
  527. package/src/pr-tool/census.ts +288 -0
  528. package/src/preview/terminal.ts +14 -1
  529. package/src/prompt-cache/types.ts +2 -0
  530. package/src/prompt-enhance/enhance.ts +24 -8
  531. package/src/prompt-library/chat-conciseness.ts +13 -0
  532. package/src/prompt-library/universal-preamble.ts +283 -61
  533. package/src/pty-shell/pty-control-ipc.ts +4 -1
  534. package/src/pty-shell/pty-manifest.ts +77 -5
  535. package/src/pty-shell/registry.ts +19 -2
  536. package/src/pty-shell/tui-run-state.ts +253 -0
  537. package/src/release-loop/gate-host-reservation.ts +97 -0
  538. package/src/release-loop/landing-freeze.ts +5 -0
  539. package/src/release-loop/light-rc.ts +32 -4
  540. package/src/release-loop/placement.ts +92 -1
  541. package/src/release-loop/rehearsal-shard-plan.ts +149 -0
  542. package/src/release-loop/rehearsal.ts +73 -17
  543. package/src/render.ts +5 -1
  544. package/src/repl/index.ts +20 -2
  545. package/src/seat-loop/seat-knowhow.ts +282 -0
  546. package/src/seat-loop/seat-loop.ts +41 -2
  547. package/src/seat-loop/seat-report.ts +42 -2
  548. package/src/seat-loop/traffic-signal.ts +3 -0
  549. package/src/self-dev/ask-launch-flow.ts +24 -3
  550. package/src/self-dev/decompose-compose-graph.ts +28 -27
  551. package/src/self-dev/decompose-proposal.ts +53 -38
  552. package/src/self-dev/decompose.ts +17 -0
  553. package/src/self-dev/dev-pipeline.ts +31 -2
  554. package/src/self-dev/draft-residue.ts +24 -9
  555. package/src/self-dev/draft-sweep.ts +59 -4
  556. package/src/self-dev/external-call-zero.ts +77 -0
  557. package/src/self-dev/launch-preflight-text.ts +6 -0
  558. package/src/self-dev/launch-preflight.ts +25 -3
  559. package/src/self-dev/local-supervisor-judge.ts +185 -0
  560. package/src/self-dev/run-supervisor.ts +300 -24
  561. package/src/self-dev/run-types.ts +20 -0
  562. package/src/self-dev/shard-aggregate.ts +15 -2
  563. package/src/self-dev/shard-plan.ts +47 -0
  564. package/src/self-dev/shard-run.ts +135 -12
  565. package/src/self-dev/spawn-lane-files.ts +19 -0
  566. package/src/self-health/signatures.ts +132 -0
  567. package/src/self-implement/app-api-budget.ts +51 -11
  568. package/src/self-implement/config-gate.ts +2 -1
  569. package/src/self-implement/doctor-visit.ts +118 -0
  570. package/src/self-implement/expose-gate.ts +2 -1
  571. package/src/self-implement/gate-artifacts.ts +405 -0
  572. package/src/self-implement/gate-cli.ts +212 -18
  573. package/src/self-implement/gate-remote.ts +110 -25
  574. package/src/self-implement/gate-scenario.ts +85 -0
  575. package/src/self-implement/goal-author-decompose.ts +80 -16
  576. package/src/self-implement/goal-author.ts +270 -76
  577. package/src/self-implement/goal-authoring-grounding.ts +1 -1
  578. package/src/self-implement/goal-file-name.ts +65 -0
  579. package/src/self-implement/graph-authority.ts +38 -6
  580. package/src/self-implement/graph-overlay-condition.ts +92 -1
  581. package/src/self-implement/ground-goal.ts +2 -1
  582. package/src/self-implement/heal-triage.ts +79 -0
  583. package/src/self-implement/host-regate.ts +74 -2
  584. package/src/self-implement/orchestrator.ts +14 -123
  585. package/src/self-implement/pr-title.ts +123 -0
  586. package/src/self-implement/review-mustfix-class.ts +115 -0
  587. package/src/self-implement/run-checkpoint.ts +235 -0
  588. package/src/self-implement/run-ledger.ts +266 -17
  589. package/src/self-implement/run-stop.ts +4 -3
  590. package/src/self-implement/run-ttl.ts +28 -4
  591. package/src/self-implement/running-runs.ts +10 -6
  592. package/src/self-implement/seams.ts +2 -0
  593. package/src/self-implement/self-implement-runtime.ts +32 -0
  594. package/src/self-implement/shadow-stage.ts +7 -6
  595. package/src/self-implement/stop-autoheal.ts +2 -1
  596. package/src/self-implement/train-gate-remote.ts +37 -8
  597. package/src/self-implement/train-reach-grouping.ts +157 -0
  598. package/src/self-implement/train-scenario-layers.ts +133 -0
  599. package/src/self-implement/uncommitted-work.ts +2 -0
  600. package/src/session/pending-input.ts +81 -11
  601. package/src/session/session-start.ts +224 -0
  602. package/src/session-runtime/index.ts +7 -1
  603. package/src/session-runtime/parallel-dispatch.ts +22 -5
  604. package/src/skills/tools/dev-harness.ts +6 -4
  605. package/src/skills/tools/ops-ledger.ts +707 -0
  606. package/src/skills/tools/persistent-grounding.ts +47 -7
  607. package/src/skills/tools/shell.ts +117 -1
  608. package/src/status/bar.ts +32 -2
  609. package/src/status/status-provider-info.ts +58 -0
  610. package/src/steward/resync-tick.ts +114 -23
  611. package/src/steward/ta-repair-event-collect.ts +158 -0
  612. package/src/task-agent/card-evidence.ts +25 -1
  613. package/src/task-agent/green-sweep.ts +8 -3
  614. package/src/task-agent/judge.ts +76 -0
  615. package/src/task-agent/land-queue.ts +79 -0
  616. package/src/task-agent/live-moves.ts +30 -9
  617. package/src/task-agent/postland-card.ts +5 -0
  618. package/src/task-agent/prelaunch-already-done.ts +98 -0
  619. package/src/task-agent/real-launch-guard.ts +37 -0
  620. package/src/task-agent/rejudge-on-head.ts +93 -13
  621. package/src/task-agent/remote-rejudge-bind.ts +62 -13
  622. package/src/task-agent/repair-cycle.ts +58 -7
  623. package/src/task-agent/repair-worker.ts +7 -0
  624. package/src/task-agent/run-identity.ts +200 -0
  625. package/src/task-agent/shadow.ts +50 -3
  626. package/src/task-agent/task-hand.ts +158 -5
  627. package/src/task-agent/train-landing.ts +77 -0
  628. package/src/task-agent/work-order.ts +104 -0
  629. package/src/task-orchestrator/surfaces/kubectl-transient-retry.ts +51 -0
  630. package/src/task-orchestrator/surfaces/pod-command-job.ts +138 -22
  631. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +88 -19
  632. package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +2 -1
  633. package/src/task-orchestrator/surfaces/pod-image-source.ts +2 -1
  634. package/src/task-orchestrator/surfaces/pod-install-slots.ts +122 -15
  635. package/src/task-orchestrator/surfaces/pod-lease.ts +20 -6
  636. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +169 -0
  637. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +103 -0
  638. package/src/task-orchestrator/surfaces/pod-result-marker-wait.ts +33 -0
  639. package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +63 -0
  640. package/src/task-orchestrator/surfaces/pod-source-receive.ts +19 -3
  641. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +141 -0
  642. package/src/task-orchestrator/surfaces/pod-warm-ta-shadow.ts +85 -0
  643. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +153 -0
  644. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +208 -0
  645. package/src/task-orchestrator/surfaces/self-implement-pod.ts +237 -46
  646. package/src/telegram.ts +2 -4
  647. package/src/terminal/session-registry.ts +6 -0
  648. package/src/thinking-line.ts +12 -3
  649. package/src/tool-runtime/index.ts +4 -0
  650. package/src/tool-runtime/ops-ledger-runtimes.ts +84 -0
  651. package/src/tool-runtime/ref-consult-runtime.ts +17 -2
  652. package/src/tool-runtime/run-shell-runtime.ts +4 -1
  653. package/src/tool-runtime/self-cognition-runtimes.ts +5 -1
  654. package/src/tui/input/pickers.ts +732 -0
  655. package/src/tui/slash/mission.ts +492 -0
  656. package/src/tui/slash/term.ts +877 -0
  657. package/src/tui-client/dashboard-session.ts +9 -0
  658. package/src/tui.ts +53 -0
  659. package/src/user-config/gemini-server-tools.ts +9 -0
  660. package/src/user-config.ts +106 -21
  661. package/src/util/spawn-sync-output.ts +7 -0
  662. package/src/ux-sim/fake-bin.ts +154 -0
  663. package/src/ux-sim/fake-clock.ts +36 -0
  664. package/src/ux-sim/fake-llm.ts +29 -0
  665. package/src/ux-sim/headless-tui.ts +72 -0
  666. package/src/ux-sim/in-process-cli.ts +176 -0
  667. package/src/ux-sim/temp-git-remote.ts +82 -0
  668. package/src/version/packed-revision.json +1 -1
  669. package/src/video-pipeline/recipes/vlog.ts +25 -7
  670. package/apps/pwa/out/_next/static/chunks/1027.a0f04663d24c2779.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/1038.676007ae505822e7.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/1113.a37eadf7f740d955.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/112-fa7c526c20ce1405.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/1144.5fa1fa1d48dbcd12.js +0 -36
  675. package/apps/pwa/out/_next/static/chunks/119b405e.8fdd0e44d1ff37aa.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/1296.04560d98e73fbf51.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/1314-f604ba013ec535b0.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/1454-29d1d773d5996a49.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/1464.f3209af0d8ae4ff2.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/1729-d73dd25e564679d4.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/1843.5924c24295243261.js +0 -27
  682. package/apps/pwa/out/_next/static/chunks/1987.e28149724b92918b.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/2066-5ca18ffa5a4be68b.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/2240.d10a66695155fd93.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/2391.e2cbc98d4abbb41a.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/2566-734cb83bbd405886.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/275.0e6bad414729bfa0.js +0 -32
  688. package/apps/pwa/out/_next/static/chunks/2803-33bdae771855a8d1.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/3259-86f3be56e43eaf6a.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/3280-e177c33bfbdcfb0a.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/3294-2b6a6d45a46a6c1c.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/3522.758840fc5e7fe630.js +0 -287
  693. package/apps/pwa/out/_next/static/chunks/3525-a7c989c1a661e880.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/3694.b1a66387756458c0.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/370.124f9e678a76fc01.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/3797-9643105335e660fe.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/4084.15ecaf4240bd9e77.js +0 -286
  698. package/apps/pwa/out/_next/static/chunks/4089-b3382b8843114eee.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/4293.928a8d573c16aab7.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/4402.f9238a3b18a7bd43.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/4490-9b090b0f9427f902.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/4548.13502d0ca3b4f862.js +0 -8
  703. package/apps/pwa/out/_next/static/chunks/4565-67e4c620597965c8.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/4599-548bc96cda44a5a7.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/4625.206574e33a9e7ae8.js +0 -104
  706. package/apps/pwa/out/_next/static/chunks/4862-392c9a71f0d8dfb4.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/5054.2906d1b02542edc5.js +0 -149
  708. package/apps/pwa/out/_next/static/chunks/5102-c822bbbee5a022a4.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/5194-8c93f2e7e4b6f717.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/5305-bacd7eca0b9a5848.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/5311.9071ee3f44fd7ff5.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/5369.9f34353442daa421.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/589-49d730cb8138b397.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/5904-264a6412ae3c9028.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/5980.728531d5c566535c.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/599-56f2c0a5cc4a7295.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/6011.f525002e21bef0ac.js +0 -23
  718. package/apps/pwa/out/_next/static/chunks/6132.4381ab93683f1acf.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/6149.2e698635e454d8f6.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/6356-0afafc4230cf9767.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/6406.64756073f7df35b8.js +0 -77
  722. package/apps/pwa/out/_next/static/chunks/6479-16e62aedafa0e310.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/6599.b5246b46a2453329.js +0 -64
  724. package/apps/pwa/out/_next/static/chunks/6610.5c26eec011565acb.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/666.37d18474edc1c552.js +0 -2
  726. package/apps/pwa/out/_next/static/chunks/6904.a0b5b1ed4f2d2c20.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/7247-1f4aba94aba50d9f.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/7274-e71a7c5b7760cd02.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/7290.1fcaeef3adb5d0d4.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/7477-2c64e42760f82f33.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/7505-47002b76ff1aef6c.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/7600-11884ca4da68e5d9.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/7607.40d8bb3689697ccb.js +0 -62
  734. package/apps/pwa/out/_next/static/chunks/7763.f51fcc19ca1414ec.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/7785.846140c859b1adf6.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/7807-a0fdac6393e0bf36.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/7837-20a63b4b7e9342b1.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/800.7815414cf280545d.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/8085-1e5fce59500a2cc2.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/8100.415f2105faa63e97.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/8290.701aa42ed13aa767.js +0 -226
  742. package/apps/pwa/out/_next/static/chunks/83a80514-b897b64df43ce108.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/8444.d9c74214a3145a43.js +0 -93
  744. package/apps/pwa/out/_next/static/chunks/8569.98c915534928c7f9.js +0 -24
  745. package/apps/pwa/out/_next/static/chunks/8591.b1c7f876e5ec7cfb.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/8715-f63756021d3ab989.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/8879.776c2ec7732aa114.js +0 -115
  748. package/apps/pwa/out/_next/static/chunks/8881.ddca15b3c82c490c.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/8946.5da5c87f32a2e1a8.js +0 -41
  750. package/apps/pwa/out/_next/static/chunks/9117.080b9b75be90e14d.js +0 -74
  751. package/apps/pwa/out/_next/static/chunks/9167.f3ecb28f367d6e69.js +0 -94
  752. package/apps/pwa/out/_next/static/chunks/9224.66095370ee28c93b.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/9238-0682b013c83d6449.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/9449.d3ed795da4befb1c.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/9638-d268329f2c6f4f8d.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/973cbf1b.3bbcf2b41548eca7.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/9842-d6644eb53d3dc6bf.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/9863.94ca3263e760696e.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d9babd8795f396a5.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/approvals/page-5ab1e47978577c5e.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-24453f6a302816b4.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/board/page-6c131d30bb1cf871.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/bots/page-dc0772b11861af51.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/ceo/page-66ad46ed0279feb9.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/app/chat/page-5159dc8752c6cd29.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/app/consult/page-c5a2478861c08b87.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/app/control/page-f722a9dec084e08b.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/app/decisions/page-256ffd365d32e100.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e0de78ae7b99f01c.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/app/editor/page-cfbdc44b708d9801.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/app/exec/page-4c741eb760f2f77c.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/app/field/page-e9ba98f5f1440a21.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/app/healthz/route-d9babd8795f396a5.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/app/inside/page-dafc901bb1b72b5f.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/app/intake/page-2f6f303fa114ec24.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/app/layout-1634081c5272006c.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/app/live-run/page-bb1f05cd51c38944.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/app/loops/page-646b50f63b6fe732.js +0 -1
  779. package/apps/pwa/out/_next/static/chunks/app/market/page-db069b48a59c8c00.js +0 -1
  780. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-f736324afa2117c1.js +0 -1
  781. package/apps/pwa/out/_next/static/chunks/app/morning/page-6f131b51193a36f9.js +0 -1
  782. package/apps/pwa/out/_next/static/chunks/app/not-found-435f5e2faf02bc01.js +0 -1
  783. package/apps/pwa/out/_next/static/chunks/app/observatory/page-497e0eedf20e7890.js +0 -1
  784. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-a8d28fdf995e16ea.js +0 -1
  785. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-8966452228753c5e.js +0 -1
  786. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fd5d18656cb432b6.js +0 -1
  787. package/apps/pwa/out/_next/static/chunks/app/outputs/page-5663779cb1a37609.js +0 -1
  788. package/apps/pwa/out/_next/static/chunks/app/page-66a67eb19ebd976b.js +0 -1
  789. package/apps/pwa/out/_next/static/chunks/app/reflection/page-3b492aa78cf3c4a6.js +0 -1
  790. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c71267e7681da982.js +0 -1
  791. package/apps/pwa/out/_next/static/chunks/app/sessions/page-a21d1e1797172692.js +0 -1
  792. package/apps/pwa/out/_next/static/chunks/app/settings/page-781cfc5114e097da.js +0 -1
  793. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-478157214db6a023.js +0 -1
  794. package/apps/pwa/out/_next/static/chunks/app/setup/layout-d9babd8795f396a5.js +0 -1
  795. package/apps/pwa/out/_next/static/chunks/app/setup/page-86141f12cf090b7f.js +0 -1
  796. package/apps/pwa/out/_next/static/chunks/app/share/page-7256c73bb1c36751.js +0 -1
  797. package/apps/pwa/out/_next/static/chunks/app/showroom/page-5c738ca7adef3de5.js +0 -1
  798. package/apps/pwa/out/_next/static/chunks/app/tasks/page-0138c8091ec17224.js +0 -1
  799. package/apps/pwa/out/_next/static/chunks/app/term/page-cc2f24f16d85e735.js +0 -1
  800. package/apps/pwa/out/_next/static/chunks/app/today/page-979d318a534e92da.js +0 -1
  801. package/apps/pwa/out/_next/static/chunks/app/trace/page-182d394f7e6e096b.js +0 -1
  802. package/apps/pwa/out/_next/static/chunks/app/vault/page-21050928a697ed7a.js +0 -1
  803. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-44b9d807005a9030.js +0 -1
  804. package/apps/pwa/out/_next/static/chunks/app/workflows/page-601fb77340e63c9a.js +0 -1
  805. package/apps/pwa/out/_next/static/chunks/app/workspace/page-75d3fb5d47af0edf.js +0 -1
  806. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-11bf9e5725a72c22.js +0 -1
  807. package/apps/pwa/out/_next/static/chunks/dcf24383-2f82e35f2d827393.js +0 -1
  808. package/apps/pwa/out/_next/static/chunks/framework-bf135b997155e90e.js +0 -1
  809. package/apps/pwa/out/_next/static/chunks/main-5571537543bea91c.js +0 -1
  810. package/apps/pwa/out/_next/static/chunks/main-app-25c51c7df7f3a442.js +0 -1
  811. package/apps/pwa/out/_next/static/chunks/pages/_app-e3b2c1f5d82abd65.js +0 -1
  812. package/apps/pwa/out/_next/static/chunks/pages/_error-083f2e23e9bc3641.js +0 -1
  813. package/apps/pwa/out/_next/static/chunks/webpack-e94d22b7a028217b.js +0 -1
  814. package/src/dashboard/bench-slash-runtime.ts +0 -40
  815. package/src/dashboard/input/search-modal-router.ts +0 -9
  816. package/src/dashboard/modals/pane-key-router.ts +0 -27
  817. package/src/dashboard/view-slash-runtime.ts +0 -48
  818. /package/apps/pwa/out/_next/static/{y1ltt7oCZxVpC6zVPhZ2O → LSXfY0u9QtfDbejY0Ukf_}/_ssgManifest.js +0 -0
@@ -1,8 +1,9 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import { realpath } from 'node:fs/promises';
3
3
  import { isAbsolute, relative, resolve, sep } from 'node:path';
4
- import { runGoalLoop, type CoreTurnContext, type CoreTurnDispatchTool, type GoalLoopOptions } from '../../core-turn/index.js';
4
+ import { runGoalLoop, type CoreTurnContext, type CoreTurnDispatchTool, type GoalLoopOptions, type GoalLoopResult } from '../../core-turn/index.js';
5
5
  import { debug } from '../../debug/log.js';
6
+ import { selectPlanningLlm } from '../../prompt-enhance/enhance.js';
6
7
  import type { LLMMessage, LLMToolSpec } from '../../llm.js';
7
8
  import { buildAstGrepTool, dispatchAstGrep, hasAstGrep } from './ast-grep.js';
8
9
  import { buildGlobTool, dispatchGlob } from './glob.js';
@@ -22,6 +23,8 @@ export interface PersistentGroundingDeps {
22
23
  relativePath?: (from: string, to: string) => string;
23
24
  /** Terms generated by an upstream grounding consumer; the loop must prioritize them for code discovery. */
24
25
  terms?: string[];
26
+ /** Authoring model selection seam; production follows the planning role, including the Pod relay. */
27
+ planningLlm?: () => Pick<ReturnType<typeof selectPlanningLlm>, 'model' | 'modelSource' | 'fallbackReason' | 'requestedModel' | 'requestedSource'>;
25
28
  }
26
29
 
27
30
  export interface PersistentGroundingResult {
@@ -215,7 +218,7 @@ function groundingMessages(goal: string, terms: readonly string[]): LLMMessage[]
215
218
  function unreadEvidencePaths(evidence: string, readFiles: ReadonlySet<string>): string[] {
216
219
  return Array.from(new Set(evidence.split(/\r?\n/)
217
220
  .flatMap(repositoryRelativeCodePaths)
218
- .filter((path) => isCodeRootPath(path) && !readFiles.has(path)))).slice(0, 8);
221
+ .filter((path) => isCodeRootPath(path) && !readFiles.has(path))));
219
222
  }
220
223
 
221
224
  function rejectedEvidenceFeedback(evidence: string, readFiles: ReadonlySet<string>): LLMMessage {
@@ -224,10 +227,11 @@ function rejectedEvidenceFeedback(evidence: string, readFiles: ReadonlySet<strin
224
227
  return {
225
228
  role: 'user',
226
229
  content: [
227
- 'Your completion evidence was rejected because it cited a repository path that Read did not verify.',
230
+ 'Your completion evidence was rejected: Glob, Grep, and ListDir prove discovery, but they do not verify a file for completion evidence.',
228
231
  `Unverified paths: ${unread.length ? unread.join(', ') : '(none in allowed code roots)'}`,
229
232
  `Paths actually Read: ${read.length ? read.join(', ') : '(none)'}`,
230
- 'Try once more. Read each relevant unverified path before citing it, or remove it from the evidence. Cite only repository-relative code paths that this grounding run actually Read, each with a concrete reason. If no path is relevant, do not invent evidence.',
233
+ ...(unread.length ? [`Next tool calls: ${unread.map((path) => `Read({"file_path":"${path}"})`).join(' ; ')}`] : []),
234
+ 'Before calling update_goal(status="complete"), Read at least one relevant path above and wait for its successful result. Cite only paths that this grounding run actually Read, each with a concrete reason. If a Read fails, omit that path. Finish by calling update_goal; ending with prose alone does not complete this task.',
231
235
  ].join('\n'),
232
236
  };
233
237
  }
@@ -248,7 +252,10 @@ export async function groundPersistently(goal: string, cwd: string, deps: Persis
248
252
  if (!astGrepAvailable) debug.log('grounding.persistent', 'tool-unavailable', { sessionId, tool: 'AstGrep' }, { level: 'warn' });
249
253
  const toolCalls: Record<string, number> = {};
250
254
  let completedIterations: number | undefined;
255
+ let resolvedProvider: string | undefined;
256
+ let resolvedModel: string | undefined;
251
257
  try {
258
+ const planningLlm = (deps.planningLlm ?? selectPlanningLlm)();
252
259
  const loop = deps.runGoalLoop ?? runGoalLoop;
253
260
  let completionEvidence = '';
254
261
  const readFiles = new Set<string>();
@@ -259,7 +266,12 @@ export async function groundPersistently(goal: string, cwd: string, deps: Persis
259
266
  dispatchTool: guardedDispatchTool(cwd, deps.dispatchTool, readFiles, deps.relativePath),
260
267
  signal: new AbortController().signal,
261
268
  maxToolTurns: 4,
269
+ ...(planningLlm.model ? { modelOverride: planningLlm.model } : {}),
262
270
  callbacks: {
271
+ onResolvedProvider: (provider, model) => {
272
+ resolvedProvider = provider;
273
+ resolvedModel = model;
274
+ },
263
275
  onToolCall: (call) => {
264
276
  toolCalls[call.name] = (toolCalls[call.name] ?? 0) + 1;
265
277
  if (call.name === 'update_goal' && call.args.status === 'complete' && typeof call.args.evidence === 'string') completionEvidence = call.args.evidence;
@@ -282,6 +294,8 @@ export async function groundPersistently(goal: string, cwd: string, deps: Persis
282
294
  let verified = firstVerified;
283
295
  let feedbackRetry = false;
284
296
  let retryIterations = 0;
297
+ let retryStopReason: GoalLoopResult['stopReason'] | undefined;
298
+ let retryOutcome: 'not-needed' | 'verified' | 'incomplete' | 'evidence-rejected' | 'failed' | 'aborted' | 'auth-rejected' = 'not-needed';
285
299
  if (firstVerified.rejection.notRead > 0) {
286
300
  feedbackRetry = true;
287
301
  const feedback = rejectedEvidenceFeedback(completionEvidence, readFiles);
@@ -290,6 +304,11 @@ export async function groundPersistently(goal: string, cwd: string, deps: Persis
290
304
  const retry = await loop({ ...ctx, sessionId: `${sessionId}-evidence-retry`, messages: [...ctx.messages, feedback] },
291
305
  { ...options, maxIterations: 2 });
292
306
  retryIterations = retry.iterations;
307
+ retryStopReason = retry.stopReason;
308
+ retryOutcome = retry.goalComplete && retry.stopReason === 'goal_complete' ? 'evidence-rejected'
309
+ : retry.stopReason === 'auth_rejected' ? 'auth-rejected'
310
+ : retry.stopReason === 'aborted' || retry.stopReason === 'soft_stop' ? 'aborted'
311
+ : retry.stopReason === 'error' ? 'failed' : 'incomplete';
293
312
  const retryVerified = retry.goalComplete && retry.stopReason === 'goal_complete'
294
313
  ? verifiedEvidenceFromCompletion(completionEvidence, readFiles)
295
314
  : null;
@@ -300,8 +319,10 @@ export async function groundPersistently(goal: string, cwd: string, deps: Persis
300
319
  rejection: retryVerified.rejection,
301
320
  };
302
321
  result = retry;
322
+ if (retryVerified.evidence.length > 0) retryOutcome = 'verified';
303
323
  }
304
324
  } catch (error) {
325
+ retryOutcome = 'failed';
305
326
  try {
306
327
  debug.log('grounding.persistent', 'evidence-retry-failed', { sessionId,
307
328
  reason: error instanceof Error ? error.message.slice(0, 200) : String(error).slice(0, 200) }, { level: 'warn' });
@@ -311,22 +332,41 @@ export async function groundPersistently(goal: string, cwd: string, deps: Persis
311
332
  }
312
333
  }
313
334
  const totalIterations = first.iterations + retryIterations;
335
+ let stopReason: string = result.stopReason;
336
+ // A verified line remains useful evidence, but it cannot turn an unsuccessful
337
+ // feedback retry into a successful completion of the whole grounding task.
338
+ switch (retryOutcome) {
339
+ case 'incomplete': stopReason = 'evidence_retry_incomplete'; break;
340
+ case 'evidence-rejected': stopReason = 'evidence_retry_rejected'; break;
341
+ case 'failed': stopReason = retryStopReason === 'error' ? 'error' : 'evidence_retry_failed'; break;
342
+ case 'auth-rejected': stopReason = 'auth_rejected'; break;
343
+ case 'aborted': stopReason = retryStopReason === 'soft_stop' ? 'soft_stop' : 'aborted'; break;
344
+ }
314
345
  try {
315
346
  debug.log('grounding.persistent', 'finished', {
316
347
  sessionId,
317
348
  maxIterations,
318
349
  durationMs: durationMs(),
319
350
  iterations: totalIterations,
320
- stopReason: result.stopReason,
351
+ stopReason,
321
352
  // ⛔ 「끝났다」가 두 뜻이다 — ⓐ 스스로 목표를 끝냈다 ⓑ 턴이 «그냥» 끝났다.
322
353
  // 📏 2026-08-11 72차 전수(400건): 후보 0인 finished 가 5건이고 ***다섯 다 end_turn*** 이었다.
323
354
  // 그 둘을 한 이름에 두면 「접지는 성공인데 코드가 0」이라는 «없는 수수께끼»가 생긴다.
324
- outcome: result.goalComplete && result.stopReason === 'goal_complete' ? 'goal-complete' : 'stopped-without-goal',
355
+ outcome: result.goalComplete && stopReason === 'goal_complete' ? 'goal-complete' : 'stopped-without-goal',
325
356
  candidates: verified.files,
326
357
  candidateCount: verified.files.length,
327
358
  evidenceCount: verified.evidence.length,
328
359
  evidenceRejection: verified.rejection,
329
360
  feedbackRetry,
361
+ retryOutcome,
362
+ retryStopReason: retryStopReason ?? null,
363
+ provider: resolvedProvider ?? null,
364
+ model: resolvedModel ?? null,
365
+ planningModel: planningLlm.model ?? null,
366
+ planningModelSource: planningLlm.modelSource,
367
+ planningFallbackReason: planningLlm.fallbackReason ?? null,
368
+ planningRequestedModel: planningLlm.requestedModel ?? null,
369
+ planningRequestedSource: planningLlm.requestedSource ?? null,
330
370
  ...(feedbackRetry ? { firstEvidenceRejection: firstVerified.rejection } : {}),
331
371
  toolCalls,
332
372
  });
@@ -337,7 +377,7 @@ export async function groundPersistently(goal: string, cwd: string, deps: Persis
337
377
  files: verified.files,
338
378
  evidence: verified.evidence,
339
379
  iterations: totalIterations,
340
- stopReason: result.stopReason,
380
+ stopReason,
341
381
  };
342
382
  } catch (error) {
343
383
  try {
@@ -178,6 +178,116 @@ function rejectedCdResult(): RunShellDispatchResult {
178
178
  };
179
179
  }
180
180
 
181
+ // ── ops-ledger CLI steering (RunShell-0 convergence) ────────────────────────
182
+ // The durable mailbox and release-checklist ledgers have in-process native
183
+ // tools (MsgList/MsgPost/MsgAck · ChecklistList/Add/Set/Move —
184
+ // src/skills/tools/ops-ledger.ts, registered for the same skill+tui hosts as
185
+ // RunShell). Shelling out to the `elanous` CLI for exactly those covered ops
186
+ // pays 1.3–2s of process startup for work the host process does in <300ms,
187
+ // and the CLI's human-oriented stdout amplifies TUI screen defects — so the
188
+ // call is steered to the native tool with a structured refusal naming it.
189
+ //
190
+ // Deliberately NOT a blanket elanous-CLI ban: only the seven covered ops are
191
+ // refused, and argv that explicitly scopes another universe (--test /
192
+ // --config-dir / --state-dir) is allowed through because the native tools
193
+ // always serve THIS process's instance.
194
+ const LEDGER_CLI_BIN = /(?:^|[/\\])(?:elanous|elanous\.mjs|elanous\.cjs|eln)$/;
195
+ const LEDGER_ENV_BIN = /(?:^|[/\\])env$/;
196
+ export const LEDGER_CLI_NATIVE_TOOL: Readonly<Record<string, string>> = {
197
+ 'msg list': 'MsgList',
198
+ 'msg post': 'MsgPost',
199
+ 'msg ack': 'MsgAck',
200
+ 'release checklist list': 'ChecklistList',
201
+ 'release checklist add': 'ChecklistAdd',
202
+ 'release checklist set': 'ChecklistSet',
203
+ 'release checklist move': 'ChecklistMove',
204
+ };
205
+
206
+ /** The covered ops-ledger CLI op in this argv and its exposed native tool,
207
+ * or null when the command should run normally. */
208
+ export function matchLedgerCli(
209
+ command: readonly string[], availableToolNames: readonly string[] = [],
210
+ ): { covered: string; tool: string } | null {
211
+ let binIndex = 0;
212
+ // RunShell receives argv, so recognize only argv-preserving env wrappers.
213
+ // An alternate instance must still run its own CLI, never this process's native tool;
214
+ // so must a changed or unset ELANOUS_TRACK — the native tools record THIS process's
215
+ // seat as the actor and route ChecklistMove permissions by it.
216
+ if (LEDGER_ENV_BIN.test(command[0] ?? '')) {
217
+ binIndex = 1;
218
+ while (binIndex < command.length) {
219
+ const arg = command[binIndex]!;
220
+ if (arg === '-i' || arg === '--ignore-environment') return null;
221
+ if (arg === '--') { binIndex += 1; continue; }
222
+ if (arg === '-u' || arg === '--unset') {
223
+ const name = command[binIndex + 1];
224
+ if (!name || /^ELANOUS_(?:STATE_DIR|CONFIG_DIR|TEST_STATE_DIR|TRACK)$/.test(name)) return null;
225
+ binIndex += 2;
226
+ continue;
227
+ }
228
+ if (arg.startsWith('--unset=')) {
229
+ if (/^--unset=ELANOUS_(?:STATE_DIR|CONFIG_DIR|TEST_STATE_DIR|TRACK)$/.test(arg)) return null;
230
+ binIndex += 1;
231
+ continue;
232
+ }
233
+ if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(arg)) {
234
+ if (/^ELANOUS_(?:STATE_DIR|CONFIG_DIR|TEST_STATE_DIR|TRACK)=/.test(arg)) return null;
235
+ binIndex += 1;
236
+ continue;
237
+ }
238
+ break;
239
+ }
240
+ }
241
+ if (command[binIndex] === 'bun' || command[binIndex] === 'bunx' || command[binIndex] === 'node' || command[binIndex] === 'npx') {
242
+ binIndex += 1;
243
+ if (command[binIndex] === '--bun') binIndex += 1;
244
+ }
245
+ if (!LEDGER_CLI_BIN.test(command[binIndex] ?? '')) return null;
246
+ const args = command.slice(binIndex + 1);
247
+ if (args.some((arg) => arg === '--test' || arg === '--config-dir' || arg.startsWith('--config-dir=')
248
+ || arg === '--state-dir' || arg.startsWith('--state-dir=')
249
+ || arg === '--test-state-dir' || arg.startsWith('--test-state-dir='))) return null;
250
+ let i = 0;
251
+ while (i < args.length && args[i]!.startsWith('-')) i += 1;
252
+ const sub = args[i];
253
+ const covered = sub === 'msg'
254
+ ? `msg ${args[i + 1]}`
255
+ : sub === 'release' && args[i + 1] === 'checklist'
256
+ ? `release checklist ${args[i + 2]}`
257
+ : '';
258
+ const tool = covered ? LEDGER_CLI_NATIVE_TOOL[covered] : undefined;
259
+ if (!tool || !availableToolNames.includes(tool)) return null;
260
+ return { covered, tool };
261
+ }
262
+
263
+ function ledgerCliSteerOutput(shellTool: string, covered: string, tool: string): string {
264
+ const metadata = covered === 'release checklist set' ? ' — for owner/priority/disposition/kind/… use ChecklistEdit, one field per call' : '';
265
+ return `${shellTool} rejected \`${covered}\`: call the native ${tool} tool instead (same ledger, same permissions and audit, no CLI startup)${metadata}.`;
266
+ }
267
+
268
+ /** Structured refusal steering a covered ops-ledger CLI argv to its native
269
+ * tool, or null when the command should run normally. Exported so tests
270
+ * can exercise the matcher without spawning anything. */
271
+ export function rejectedLedgerCliResult(
272
+ command: readonly string[], availableToolNames: readonly string[] = [],
273
+ ): RunShellDispatchResult | null {
274
+ const match = matchLedgerCli(command, availableToolNames);
275
+ if (!match) return null;
276
+ const { covered, tool } = match;
277
+ return {
278
+ output: ledgerCliSteerOutput('RunShell', covered, tool),
279
+ exitCode: null,
280
+ outcome: 'spawn-error',
281
+ elapsedMs: 0,
282
+ stdout: '',
283
+ stderr: `use the native ${tool} tool instead of the ${covered} CLI`,
284
+ truncated: false,
285
+ approvalKey: 'rejected:ops-ledger-cli',
286
+ sandboxed: false,
287
+ sandboxTool: 'none',
288
+ };
289
+ }
290
+
181
291
  function logShellDispatch(event: string, data: Record<string, unknown>): void {
182
292
  debug.log('shell.dispatch', event, data);
183
293
  }
@@ -240,7 +350,7 @@ export function enqueueShellCompletionNotice(
240
350
 
241
351
  export async function dispatchRunShell(
242
352
  rawArgs: Record<string, unknown>,
243
- opts: { signal?: AbortSignal } = {},
353
+ opts: { signal?: AbortSignal; availableToolNames?: readonly string[] } = {},
244
354
  ): Promise<RunShellDispatchResult> {
245
355
  const command = asCommand(rawArgs.command);
246
356
  const cwd = typeof rawArgs.cwd === 'string' ? rawArgs.cwd : undefined;
@@ -255,6 +365,12 @@ export async function dispatchRunShell(
255
365
  logShellDispatch('cd.rejected', { reason: 'argv-state-does-not-persist' });
256
366
  return rejectedCdResult();
257
367
  }
368
+ const ledgerCliMatch = matchLedgerCli(command, opts.availableToolNames);
369
+ if (ledgerCliMatch) {
370
+ // covered op ⊕ tool only — the argv can carry a message body.
371
+ logShellDispatch('ledger-cli.steered', { shell: 'run-shell', ...ledgerCliMatch });
372
+ return rejectedLedgerCliResult(command, opts.availableToolNames)!;
373
+ }
258
374
  const effectiveCwd = cwd ?? getSessionCwd();
259
375
  const cwdSource = cwd === undefined ? 'session' : 'argument';
260
376
  const boundaryReject = harnessCommandWriteReject(command, effectiveCwd, 'run-shell');
package/src/status/bar.ts CHANGED
@@ -213,6 +213,9 @@ export interface GitSegmentState {
213
213
  ahead?: number;
214
214
  /** Commits behind upstream. Non-zero → peach tone with "-N". */
215
215
  behind?: number;
216
+ /** Optional axis label after the glyph (e.g. `트리`) — set when a
217
+ * running-build pill sits next to it so the two SHAs are not confused. */
218
+ label?: string;
216
219
  }
217
220
 
218
221
  /** Git state — flat colored text. No pill background.
@@ -241,7 +244,7 @@ export function gitSegment(
241
244
  const head = state.branch
242
245
  ? truncateGitHead(state.branch, 20)
243
246
  : `HEAD@${(state.detachedSha ?? '').slice(0, 7)}`;
244
- const parts: string[] = [`⌥ ${head}`];
247
+ const parts: string[] = [state.label ? `⌥ ${state.label} ${head}` : `⌥ ${head}`];
245
248
  const dirty = Math.max(0, state.dirtyTotal ?? 0);
246
249
  if (dirty > 0) parts.push(`*${dirty}`);
247
250
  if ((state.ahead ?? 0) > 0) parts.push(`+${state.ahead}`);
@@ -260,6 +263,33 @@ export function gitSegment(
260
263
  : strongText(parts.join(' '), tone, opts);
261
264
  }
262
265
 
266
+ /** The code this TUI process loaded at boot (not the session tree HEAD). */
267
+ export interface RunningBuildState {
268
+ /** Boot commit (full or short); '' = unknown (rendered as `?`). */
269
+ sha: string;
270
+ /** True when the installed/checkout code moved after boot — a relaunch runs the new build.
271
+ * null = could not compare (not the same as «not stale»). */
272
+ stale: boolean | null;
273
+ /** The commit a relaunch would run, when known. */
274
+ currentSha?: string;
275
+ }
276
+
277
+ /** Running-build pill.
278
+ *
279
+ * ▶ 실행 5c0f98f — boot build matches current code (overlay)
280
+ * ▶ 실행 5c0f98f ⟳ 재기동 필요 → 1a2b3c4 — code moved after boot (yellow, bold)
281
+ * ▶ 실행 5c0f98f ? — could not compare (overlay)
282
+ * ▶ 실행 ? — boot build unknown (overlay) */
283
+ export function runningBuildSegment(state: RunningBuildState | null | undefined, opts: StatusBarRenderOptions = {}): string {
284
+ if (!state) return '';
285
+ if (!state.sha) return text('▶ 실행 ?', 'overlay', opts);
286
+ const label = `▶ 실행 ${state.sha.slice(0, 7)}`;
287
+ if (state.stale === null) return text(`${label} ?`, 'overlay', opts);
288
+ if (!state.stale) return text(label, 'overlay', opts);
289
+ const target = state.currentSha ? ` → ${state.currentSha.slice(0, 7)}` : '';
290
+ return strongText(`${label} ⟳ 재기동 필요${target}`, 'yellow', opts);
291
+ }
292
+
263
293
  /** Truncate a model id at the first parameter-size marker (e.g.
264
294
  * `qwen3.6-35b-a3b-ud-mlx` → `qwen3.6-35b`). The marker pattern
265
295
  * matches one or more digits followed by `b`/`B` (e.g. `7b`, `35b`,
@@ -289,7 +319,7 @@ function truncateAtParamSize(model: string): string {
289
319
  * - `local:qwen3.6-35b-a3b-ud-mlx` → `local:qwen3.6-35b`
290
320
  * - `node-b:qwen2.5-72b-instruct` → `node-b:qwen2.5-72b`
291
321
  * - `claude-opus-4-6` → unchanged (no `\d+b` marker) */
292
- export function modelSegment(info: ActiveProviderInfo, opts: StatusBarRenderOptions = {}): string {
322
+ export function modelSegment(info: Pick<ActiveProviderInfo, 'provider' | 'model'>, opts: StatusBarRenderOptions = {}): string {
293
323
  if (!info.model || info.model === '(none)') {
294
324
  return strongText(info.provider, 'pink', opts);
295
325
  }
@@ -0,0 +1,58 @@
1
+ // ── Status-line provider/model reader ──
2
+ //
3
+ // 하단 상태줄은 키 입력마다 다시 그린다. 종전엔 그때마다 `inspectActiveProvider()` 를 불러
4
+ // ① `getUserConfig()` 의 stat ② `decideProviderForConfig()` 의 자격 확인 ③ 상태줄이 «안 쓰는»
5
+ // `authDetail`(codex 면 auth 스토어 readFileSync + JSON.parse) 을 매 렌더 동기로 했다.
6
+ // 📏 실측(10-14 mbp · 운영 HOME · 500회 평균): 렌더 1회 98µs.
7
+ // ⇒ 상태줄이 쓰는 것은 provider·model 둘뿐이라, 그 둘만 짧게 기억한다.
8
+ // ⛔ 기억이 «낡은 값»으로 굳지 않게: runtimeModel 이 바뀌면 즉시, 설정 파일이 바뀌면 TTL(2s) 안에 다시 읽고,
9
+ // 그렇지 않아도 `maxAgeMs` 마다 다시 판정한다(auto 공급자는 자격 유무로 갈리므로). 표시 전용이라 2s 지연은 허용.
10
+
11
+ import { inspectActiveProvider, type ActiveProviderInfo } from '../provider-summary.js';
12
+ import { getUserConfig, type UserConfig } from '../user-config.js';
13
+
14
+ export type StatusProviderInfo = Pick<ActiveProviderInfo, 'provider' | 'model'>;
15
+
16
+ export interface StatusProviderInfoReaderDeps {
17
+ readConfig?: () => UserConfig;
18
+ inspect?: (cfg: UserConfig, runtimeModel?: string) => StatusProviderInfo;
19
+ now?: () => number;
20
+ /** 이 안에서는 설정도 다시 안 읽는다(렌더 경로 0 I/O). */
21
+ ttlMs?: number;
22
+ /** 설정이 그대로여도 이만큼 지나면 다시 판정한다. */
23
+ maxAgeMs?: number;
24
+ }
25
+
26
+ export function createStatusProviderInfoReader(
27
+ deps: StatusProviderInfoReaderDeps = {},
28
+ ): (runtimeModel?: string) => StatusProviderInfo {
29
+ const readConfig = deps.readConfig ?? (() => getUserConfig());
30
+ const inspect = deps.inspect ?? ((cfg, runtimeModel) => inspectActiveProvider(cfg, runtimeModel));
31
+ const now = deps.now ?? Date.now;
32
+ const ttlMs = deps.ttlMs ?? 2_000;
33
+ const maxAgeMs = deps.maxAgeMs ?? 30_000;
34
+ let memo: {
35
+ info: StatusProviderInfo;
36
+ cfg: UserConfig;
37
+ runtimeModel: string | undefined;
38
+ checkedAt: number;
39
+ inspectedAt: number;
40
+ } | null = null;
41
+
42
+ return (runtimeModel?: string): StatusProviderInfo => {
43
+ const t = now();
44
+ // ⛔ 조기 반환에도 최대 수명을 건다 — TTL 만 보면 «29초에 설정 확인 → 30.001초 렌더»가 재판정 없이 지나간다.
45
+ const fresh = memo !== null && t - memo.inspectedAt < maxAgeMs;
46
+ if (memo && fresh && memo.runtimeModel === runtimeModel && t - memo.checkedAt < ttlMs) return memo.info;
47
+ // getUserConfig() 는 파일 mtime 이 같으면 «같은 객체»를, 바뀌면 새 객체를 돌려준다(user-config.ts getUserConfig).
48
+ const cfg = readConfig();
49
+ if (memo && fresh && memo.cfg === cfg && memo.runtimeModel === runtimeModel) {
50
+ memo.checkedAt = t;
51
+ return memo.info;
52
+ }
53
+ const full = inspect(cfg, runtimeModel);
54
+ const info: StatusProviderInfo = { provider: full.provider, model: full.model };
55
+ memo = { info, cfg, runtimeModel, checkedAt: t, inspectedAt: t };
56
+ return info;
57
+ };
58
+ }
@@ -1,11 +1,12 @@
1
1
  /** Resync labeled PRs before the steward's TA rejudge node sees their heads. */
2
2
  import { debug } from '../debug/log.js';
3
3
  import { spawnSync } from 'node:child_process';
4
- import { mkdirSync, writeFileSync } from 'node:fs';
4
+ import { closeSync, constants, fstatSync, lstatSync, mkdirSync, openSync, writeFileSync } from 'node:fs';
5
5
  import { dirname, join } from 'node:path';
6
+ import { dlopen, FFIType } from 'bun:ffi';
6
7
  import { getElanousConfigDir } from '../elanous-config-dir.js';
7
8
  import { resolveHqLaunchSeat } from '../hq/seats.js';
8
- import { effectiveInstanceRoot } from '../instance/resolve.js';
9
+ import { effectiveInstanceRoot, normRoot, releaseLedgerRoot } from '../instance/resolve.js';
9
10
  import { runResyncShadow, type ResyncShadowSummary } from '../loops/orchestrator/resync-shadow.js';
10
11
  import { listSchedules, type ReleaseSchedule } from '../release-loop/release-schedule.js';
11
12
 
@@ -71,6 +72,90 @@ export function defaultResyncRun(
71
72
  execute: typeof runResyncShadow = runResyncShadow,
72
73
  ): Promise<ResyncShadowSummary> { return execute(3, { repoRoot }, 'live'); }
73
74
 
75
+ const LOCK_EX = 2;
76
+ const LOCK_NB = 4;
77
+ const LOCK_UN = 8;
78
+ type FlockFn = (fd: number, op: number) => number;
79
+ let flockFn: FlockFn | undefined;
80
+
81
+ function osFlock(): FlockFn {
82
+ if (flockFn) return flockFn;
83
+ const names = process.platform === 'darwin'
84
+ ? ['/usr/lib/libSystem.B.dylib', 'libc.dylib']
85
+ : ['libc.so.6', `libc.musl-${process.arch === 'arm64' ? 'aarch64' : 'x86_64'}.so.1`];
86
+ let lastError: unknown;
87
+ for (const name of names) {
88
+ try {
89
+ const lib = dlopen(name, { flock: { args: [FFIType.i32, FFIType.i32], returns: FFIType.i32 } });
90
+ flockFn = (fd, op) => lib.symbols.flock(fd, op) as number;
91
+ return flockFn;
92
+ } catch (error) { lastError = error; }
93
+ }
94
+ throw new Error(`OP seat flock unavailable (${names.join(', ')}): ${String(lastError)}`);
95
+ }
96
+
97
+ /**
98
+ * The one root every OP-seat locker resolves to (steward resync · manual resume · unattended release). It is the
99
+ * release ledger root — an explicit `--config-dir` universe, otherwise machine-wide prod — because the OP seat is
100
+ * machine-wide: a resync from a tree-derived test universe and a release run must still meet on the same lock file.
101
+ * An injected root (tests, a caller that already decided) is used as is. Normalized so `x` and `x/` share one inode.
102
+ */
103
+ export function opSeatLockRoot(explicit?: string): string {
104
+ return normRoot(explicit ?? releaseLedgerRoot());
105
+ }
106
+
107
+ /** Persistent inode for the shared OP-seat kernel flock. Never unlink: a replacement inode would split lockers. */
108
+ export function opSeatFlockPath(root?: string): string {
109
+ return join(opSeatLockRoot(root), 'steward', 'op-seat.flock');
110
+ }
111
+
112
+ export interface OpSeatFlock {
113
+ path: string;
114
+ release(): void;
115
+ }
116
+
117
+ /** Exclusive kernel flock covering OP-seat HEAD, index, and workfile mutation. Released on every exit, including throw. */
118
+ export async function acquireOpSeatFlock(root?: string, waitMs = 120_000): Promise<OpSeatFlock> {
119
+ const path = opSeatFlockPath(root);
120
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
121
+ const flock = osFlock();
122
+ const fd = openSync(path, constants.O_CREAT | constants.O_RDWR | constants.O_NOFOLLOW, 0o600);
123
+ let acquired = false;
124
+ try {
125
+ const stat = fstatSync(fd);
126
+ const current = lstatSync(path);
127
+ if (!stat.isFile() || (stat.mode & 0o077) !== 0 || stat.ino !== current.ino || stat.dev !== current.dev) {
128
+ throw new Error('OP seat flock must be a private regular file (0600)');
129
+ }
130
+ const deadline = Date.now() + waitMs;
131
+ while (flock(fd, LOCK_EX | LOCK_NB) !== 0) {
132
+ if (Date.now() >= deadline) throw new Error(`OP seat flock timed out: ${path}`);
133
+ await Bun.sleep(25);
134
+ }
135
+ acquired = true;
136
+ const locked = lstatSync(path);
137
+ if (stat.ino !== locked.ino || stat.dev !== locked.dev) throw new Error('OP seat flock changed');
138
+ } catch (error) {
139
+ try { if (acquired) flock(fd, LOCK_UN); } finally { closeSync(fd); }
140
+ throw error;
141
+ }
142
+ let released = false;
143
+ return {
144
+ path,
145
+ release() {
146
+ if (released) return;
147
+ released = true;
148
+ try { flock(fd, LOCK_UN); } finally { closeSync(fd); }
149
+ },
150
+ };
151
+ }
152
+
153
+ export async function withOpSeatFlock<T>(action: () => Promise<T> | T, root?: string): Promise<T> {
154
+ const held = await acquireOpSeatFlock(root);
155
+ try { return await action(); }
156
+ finally { held.release(); }
157
+ }
158
+
74
159
  export async function resyncTick(
75
160
  run: () => Promise<ResyncShadowSummary> = () => defaultResyncRun(),
76
161
  log: (event: string, data: Record<string, unknown>) => void = (event, data) => debug.log('loop.steward', event, data),
@@ -84,32 +169,38 @@ export async function resyncTickWithReleaseProbe(
84
169
  releaseProbe: () => ReleaseRunState,
85
170
  windowProbe: () => ReleaseWindowState = releaseWindowState,
86
171
  ): Promise<ResyncTickResult> {
87
- let result: ResyncTickResult;
172
+ // Acquisition failure (unreadable lock file, 120s timeout) is a tick failure: it takes the same
173
+ // `{ decision: 'failed' }` + log path as any other resync error instead of escaping to the caller.
174
+ let held: OpSeatFlock | undefined;
88
175
  try {
89
- const release = releaseProbe();
90
- if (release !== 'idle') {
91
- result = { decision: 'skipped-release', reason: release === 'active' ? 'release run active' : 'release process probe unavailable' };
92
- } else {
93
- const window = windowProbe();
94
- if (window !== 'outside') {
95
- result = { decision: 'skipped-release-window', reason: window === 'inside' ? 'scheduled release window' : 'release schedule unavailable' };
176
+ let result: ResyncTickResult;
177
+ try {
178
+ held = await acquireOpSeatFlock();
179
+ const release = releaseProbe();
180
+ if (release !== 'idle') {
181
+ result = { decision: 'skipped-release', reason: release === 'active' ? 'release run active' : 'release process probe unavailable' };
96
182
  } else {
97
- const summary = await run();
98
- if (summary.saved > 0) {
99
- mkdirSync(dirname(pendingPath), { recursive: true });
100
- writeFileSync(pendingPath, JSON.stringify({ savedAt: new Date().toISOString() }));
183
+ const window = windowProbe();
184
+ if (window !== 'outside') {
185
+ result = { decision: 'skipped-release-window', reason: window === 'inside' ? 'scheduled release window' : 'release schedule unavailable' };
186
+ } else {
187
+ const summary = await run();
188
+ if (summary.saved > 0) {
189
+ mkdirSync(dirname(pendingPath), { recursive: true });
190
+ writeFileSync(pendingPath, JSON.stringify({ savedAt: new Date().toISOString() }));
191
+ }
192
+ result = { decision: 'ran', summary };
101
193
  }
102
- result = { decision: 'ran', summary };
103
194
  }
104
195
  }
105
- }
106
- catch (error) { result = { decision: 'failed', reason: (error instanceof Error ? error.message : String(error)).slice(-300) }; }
107
- try { log('resync-tick', { ...result }); }
108
- catch (error) {
109
- result = { decision: 'failed', reason: `log failed: ${error instanceof Error ? error.message : String(error)}`.slice(-300) };
110
- console.error(`steward resync: ${result.reason}`);
111
- }
112
- return result;
196
+ catch (error) { result = { decision: 'failed', reason: (error instanceof Error ? error.message : String(error)).slice(-300) }; }
197
+ try { log('resync-tick', { ...result }); }
198
+ catch (error) {
199
+ result = { decision: 'failed', reason: `log failed: ${error instanceof Error ? error.message : String(error)}`.slice(-300) };
200
+ console.error(`steward resync: ${result.reason}`);
201
+ }
202
+ return result;
203
+ } finally { held?.release(); }
113
204
  }
114
205
 
115
206
  if (import.meta.main) {