elanous 0.2.29 → 0.2.32

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 (775) 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/{cIpv5nU9AycwYWZI9H589 → IVKr3AlRUVLKsw2fh7eXF}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{058a98ba.7eb28d5e6dc03565.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/{6013-2f769370d8b4c2c6.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/{8332.6f0f49df772e163b.js → 1654.32de4b324981a188.js} +1 -1
  15. package/apps/pwa/out/_next/static/chunks/1834-98b64172bc1efe77.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +149 -0
  17. package/apps/pwa/out/_next/static/chunks/{8795.32573a185af18c7b.js → 1913.7cc6fb6055b1ed3f.js} +2 -2
  18. package/apps/pwa/out/_next/static/chunks/{419.736c0d6f426249a7.js → 2001.6c7e0fd02190886c.js} +1 -1
  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/{6767.1fcfc9b8be83975f.js → 2213.2ccbada92c33ea0f.js} +16 -16
  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/{4759.1f76713aefb87db5.js → 2871.0bca6137343b3f76.js} +1 -1
  28. package/apps/pwa/out/_next/static/chunks/{6776.06ff1e3b464cc607.js → 2898.fd781bc7cf01a7b7.js} +1 -1
  29. package/apps/pwa/out/_next/static/chunks/{1782-59db1b5aa06df38a.js → 2940-619bfd8ef337c611.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/{8471.8d2a8c74f09c36ff.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/{bc324b7c.02a09dd93f6a399b.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/{7725-4f83d5541fbdb81b.js → 3541-ce3a5424ed5ad7f1.js} +1 -1
  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/3902.e1e71aaac850a045.js +34 -0
  39. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/{46bd8bea.2f4b4099172fcdb7.js → 409f1e57.d0649fc47691ebfe.js} +1 -1
  41. package/apps/pwa/out/_next/static/chunks/4111.2bfedbb233ad206b.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/{1142.65d002789ab3af7d.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/4999.c064a4000c2a9e94.js +79 -0
  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/5304.04d24756f242a094.js +148 -0
  57. package/apps/pwa/out/_next/static/chunks/5307.60f2209e809bd627.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/{3396-97b97928c49190c9.js → 5458-16cd7a2b51b74c8c.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/{3403.7199205e65124486.js → 5525.86debf231e181813.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{9143.ff14585db1d275ff.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/{8398.73a19b39715eda04.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/{5591.a35e7a217734a8b9.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/6323.8672b4817a306928.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/{7375.050ea0d72968e49f.js → 6433.fc573af22bbc9ab7.js} +17 -17
  75. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +90 -0
  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/6767.ea607cf0c20a25af.js +24 -0
  85. package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +93 -0
  86. package/apps/pwa/out/_next/static/chunks/69-0a2c8209c6d4a158.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/{1852.7f7b53991fcb99ef.js → 7502.ccd5b8065545edd0.js} +2 -2
  94. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +8 -0
  95. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/{6534.1ab00f370db7b105.js → 7862.30a8d6482bb238eb.js} +1 -1
  97. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/{285adb1a.5654e605dddf86d2.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8097-9530c03bcc550f02.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +24 -0
  110. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/{1516.dfaceff3fd2d0e0d.js → 9138.b6e80031afb1d973.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/{9907.49be0fcadaf214b5.js → 9221.7d22eaf353a2d4e7.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/{8767-2f6a634f5abeaa01.js → 9279-d28c5b7754d010ae.js} +1 -1
  116. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/{3160-95c96f4d2a21dd26.js → 9398-6aed28f0a96d0d6f.js} +1 -1
  118. package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{328bb3ab-6628a1114fe3fb3b.js → 997ce8a5-2ad501927003b41b.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/{6853.cc5174a9dee59593.js → 9989.3694300e5f000b14.js} +1 -1
  123. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/approvals/page-504204b58c82c253.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a9717a67c2eecbaf.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/board/page-5c9ec30aee62dfbf.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/botlab/page-584191533721fa16.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/bots/page-73c4b4bb3ac7ab5f.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c0f1ca371f710b06.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/chat/page-46430d45a9e04eac.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/consult/page-3b2ebf1dc64ff0be.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/control/page-a27b1e5a0d1b308f.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/decisions/page-25654b82094f7d22.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8ea49a4c6dd2c6e7.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/editor/page-ce5113aefea0a8d1.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/exec/page-0e5a41fac1c75396.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/field/page-31aaf1ed37c6df9a.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/inside/page-3dcc1fa411e1f4e0.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/intake/page-c69247e7134d329d.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/layout-66dc5cd3a0999abe.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live/page-26ff7ff651a7217d.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live-run/page-617b3976981efa96.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/loops/page-d256f5d5d9552823.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/market/page-ce8f1907b8a6101c.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-33e182a316263116.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/morning/page-32866485913d6a04.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/not-found-7607cca9b84950c6.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eeab86176b03dc3b.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5b93dbae3432b996.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-77a6cb90a9cf2b10.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f47e768b5b242b5a.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/outputs/page-eb41aa3367fc2505.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/page-4d13ab0b8a267e3f.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/reflection/page-84dad32ff0fc0831.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-95306f892aa2d0ee.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/sessions/page-940fb6c217f6b470.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-8c66a3b24a745630.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/page-7b675dfd35c36fc9.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8bd0d3cf7665bcfc.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/{page-29900ed0011b2c83.js → page-c219f2ed171131be.js} +1 -1
  163. package/apps/pwa/out/_next/static/chunks/app/share/page-40f8fa21bdae955b.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/showroom/page-468f8313e4f1fbd9.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/tasks/page-7bbb8fa353a246c4.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/term/page-04d00ae9b0890349.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/today/page-4214b855d9233ea8.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/trace/page-936752c7aa58762e.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/vault/page-ec052ad359df1797.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8305570551091338.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/page-fad650e4793adb65.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workspace/page-d90e64743826e1d8.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a16bcfd49af86a32.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/{425cfc4d.fb91158e3971c39f.js → b313b242.cb1265eea908db61.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +122 -0
  176. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +1 -0
  184. package/apps/pwa/out/_next/static/css/b5d88eba78a3d7bf.css +1 -0
  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 +26 -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/bin/elanous.mjs +7 -3
  279. package/graphs/context/nightly-condense.yaml +1 -0
  280. package/graphs/implement-loop.yaml +5 -0
  281. package/graphs/intake/intake-daily.yaml +8 -1
  282. package/graphs/intake/recipes.yaml +5 -0
  283. package/graphs/lecture/lecture-note.yaml +2 -2
  284. package/graphs/ops/harness-gc.yaml +1 -0
  285. package/graphs/release/recipes.yaml +3 -0
  286. package/graphs/release/release-loop.yaml +9 -5
  287. package/graphs/units/recipes.yaml +3 -0
  288. package/graphs/units/release-gate-recheck.yaml +15 -0
  289. package/package.json +2 -1
  290. package/scripts/check-native-tool-wiring.ts +3 -2
  291. package/scripts/ci-android-unit-tests.ts +16 -0
  292. package/scripts/ci-typecheck-changed.ts +63 -10
  293. package/scripts/coord-channel-watch.sh +22 -16
  294. package/scripts/coord-role-pack.ts +81 -2
  295. package/scripts/cron-run.ts +96 -3
  296. package/scripts/detect-test-interference.ts +38 -5
  297. package/scripts/gate-pr-cache.ts +65 -0
  298. package/scripts/gh-surface/capture.ts +126 -0
  299. package/scripts/gh-surface/gh +40 -0
  300. package/scripts/import-graph-scc.ts +38 -0
  301. package/scripts/install.ps1 +19 -0
  302. package/scripts/intake-social.ts +181 -0
  303. package/scripts/lecture-note/node.ts +71 -4
  304. package/scripts/lib/android-toolchain.ts +32 -0
  305. package/scripts/lib/deterministic-env.ts +62 -0
  306. package/scripts/lib/gate-test-env.ts +19 -0
  307. package/scripts/measure-goal-grounding-corpus.ts +2 -1
  308. package/scripts/measure-si-task-cpu.ts +143 -0
  309. package/scripts/ratchets/test-interference-patterns.allowlist.txt +255 -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-closure.ts +12 -8
  317. package/scripts/release-loop/gate-diff.ts +1 -1
  318. package/scripts/release-loop/gate-host-mirror.ts +66 -0
  319. package/scripts/release-loop/gate-node.ts +523 -75
  320. package/scripts/release-loop/gate-partial.ts +106 -9
  321. package/scripts/release-loop/gate-pr-cache.ts +66 -0
  322. package/scripts/release-loop/gate-prewarm-plan.ts +66 -0
  323. package/scripts/release-loop/gate-r2-verdict.ts +189 -0
  324. package/scripts/release-loop/gate-recheck-plan-node.ts +52 -0
  325. package/scripts/release-loop/gate-warm-artifacts.ts +253 -0
  326. package/scripts/release-loop/import-graph-scc-run.ts +54 -0
  327. package/scripts/release-loop/import-graph-scc.ts +215 -0
  328. package/scripts/release-loop/node-verdict.ts +2 -0
  329. package/scripts/release-loop/prepare-node.ts +102 -4
  330. package/scripts/release-loop/probe-pod-host-dirs-live.ts +113 -0
  331. package/scripts/release-loop/resume-release.ts +33 -4
  332. package/scripts/release-loop/resume.ts +13 -5
  333. package/scripts/release-loop/spawn-lane.ts +2 -19
  334. package/scripts/release-loop/tui-sim-node.ts +3 -2
  335. package/scripts/release-loop/unattended-release.ts +16 -0
  336. package/scripts/test-deterministic.ts +5 -61
  337. package/scripts/train-reach-grouping.ts +48 -0
  338. package/scripts/tsc-incremental-cache.ts +86 -0
  339. package/scripts/tsc-incremental-diagnostics.ts +76 -0
  340. package/scripts/tsc-main-safety-net.ts +2 -2
  341. package/src/acp/client.ts +4 -1
  342. package/src/acp/core-turn-bridge.ts +65 -8
  343. package/src/acp/elanous-extensions.ts +3 -0
  344. package/src/acp/server.ts +3 -0
  345. package/src/acp/tool-trace.ts +186 -11
  346. package/src/ad-pipeline/run.ts +4 -2
  347. package/src/agent/runner.ts +169 -3
  348. package/src/agent/self-ambient-cache.ts +156 -0
  349. package/src/agent/self-ambient.ts +8 -1
  350. package/src/agent/subagent-callable.ts +3 -2
  351. package/src/agent/task-notification.ts +5 -0
  352. package/src/agent-mission/review-loop.ts +6 -3
  353. package/src/agent-substrate/acp-implementer.ts +14 -2
  354. package/src/agent-substrate/pr-reviewer.ts +14 -0
  355. package/src/agent-substrate/self-review-cli.ts +30 -4
  356. package/src/ask-user-question/tool.ts +22 -0
  357. package/src/autopilot/build/llm-conflict-merge.ts +56 -10
  358. package/src/autopilot/pr-manager.ts +80 -7
  359. package/src/briefing/brief-items.ts +24 -22
  360. package/src/capture/frame-state-detect.ts +39 -0
  361. package/src/capture/tui-self-report.ts +149 -6
  362. package/src/chat/chat-cli.ts +10 -2
  363. package/src/chat/index.ts +138 -26
  364. package/src/chat/input-control-key.ts +5 -3
  365. package/src/chat/pickers/modal-runtime.ts +6 -0
  366. package/src/chat/pickers/modals.ts +8 -2
  367. package/src/chat/tool-interrupt-behavior.ts +38 -0
  368. package/src/chat/tool-render/dispatch.ts +5 -1
  369. package/src/chat/turn-typeahead.ts +75 -20
  370. package/src/cli/__fixtures__/agent-help-before/agent.txt +4 -2
  371. package/src/cli/agent-cli.ts +41 -13
  372. package/src/cli/ask-bare.ts +1 -0
  373. package/src/cli/config-audit.ts +123 -0
  374. package/src/cli/decisions-cli.ts +80 -6
  375. package/src/cli/import-cli.ts +12 -0
  376. package/src/cli/log-event-names.ts +17 -0
  377. package/src/cli/mcp-login.ts +21 -5
  378. package/src/cli/msg-cli.ts +89 -0
  379. package/src/cli/pod-cli.ts +14 -3
  380. package/src/cli/pr-cli.ts +273 -81
  381. package/src/cli/pr-land-base-read.ts +34 -0
  382. package/src/cli/pr-land-heavy-remote.ts +82 -26
  383. package/src/cli/pr-land-overlap-evidence.ts +109 -11
  384. package/src/cli/pr-land-pod-shadow-job.ts +106 -0
  385. package/src/cli/pr-land-pod-shadow.ts +16 -3
  386. package/src/cli/pr-land-refusal.ts +20 -5
  387. package/src/cli/pr-land-virtual-rebase.ts +108 -0
  388. package/src/cli/pty-takeover-cli.ts +88 -14
  389. package/src/cli/release-cli.ts +80 -14
  390. package/src/cli/seat-cli.ts +138 -3
  391. package/src/cli/self-update.ts +5 -2
  392. package/src/cli/sim-cli.ts +18 -0
  393. package/src/cli/tasks-cli.ts +97 -19
  394. package/src/context-bus/context-first.ts +13 -0
  395. package/src/context-bus/context-now.ts +13 -2
  396. package/src/context-bus/ops-events.ts +79 -0
  397. package/src/control-plane/lease-holder.ts +12 -8
  398. package/src/control-plane/ledger.ts +163 -4
  399. package/src/control-plane/server.ts +91 -11
  400. package/src/core-turn/run-core-turn.ts +2 -0
  401. package/src/core-turn/run-goal-loop.ts +243 -3
  402. package/src/core-turn/seat-turn-cap.ts +79 -0
  403. package/src/core-turn/short-question.ts +38 -6
  404. package/src/core-turn/types.ts +6 -0
  405. package/src/dashboard/acp-active-model.ts +42 -1
  406. package/src/dashboard/acp-boot.ts +3 -0
  407. package/src/dashboard/background-jobs-status.ts +66 -0
  408. package/src/dashboard/index.ts +339 -657
  409. package/src/dashboard/input/agent-wake.ts +242 -0
  410. package/src/dashboard/input/chat-main-entry-runtime.ts +6 -1
  411. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +4 -1
  412. package/src/dashboard/input/chat-main-session.ts +8 -1
  413. package/src/dashboard/input/chat-main-turn.ts +12 -3
  414. package/src/dashboard/input/compact-prepass-recovery.ts +33 -0
  415. package/src/dashboard/input/external-input-host.ts +49 -9
  416. package/src/dashboard/input/internal-turn.ts +261 -0
  417. package/src/dashboard/input/mouse-wiring.ts +108 -11
  418. package/src/dashboard/input/seat-autowake.ts +318 -0
  419. package/src/dashboard/input/turn-steer-bridge.ts +70 -0
  420. package/src/dashboard/log-click-runtime.ts +118 -2
  421. package/src/dashboard/loop-scheduler.ts +72 -0
  422. package/src/dashboard/seat-boot-preamble.ts +18 -0
  423. package/src/dashboard/skill-runtime.ts +2 -0
  424. package/src/dashboard/slash-runtime/dashboard-handlers.ts +126 -1181
  425. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
  426. package/src/dashboard/slash-runtime/index.ts +13 -0
  427. package/src/dashboard/turn-busy-teardown.ts +50 -0
  428. package/src/dashboard/turn-preamble.ts +116 -40
  429. package/src/dashboard/turn-session-layers.ts +4 -2
  430. package/src/dashboard/turn-start-segments.ts +222 -0
  431. package/src/decisions/decision-ledger.ts +45 -4
  432. package/src/discord-self-message.ts +4 -4
  433. package/src/display/prompt-row-owner.ts +146 -0
  434. package/src/display/resize-listener.ts +33 -2
  435. package/src/domains/release-tool.ts +18 -1
  436. package/src/field-note/transcribe.ts +17 -0
  437. package/src/fold-stack.ts +4 -2
  438. package/src/git-fs/index.ts +263 -36
  439. package/src/github/remote-call.ts +81 -0
  440. package/src/goals/registry.ts +46 -6
  441. package/src/goals/types.ts +7 -1
  442. package/src/graph-runner/runner.ts +1 -0
  443. package/src/grok/credential.ts +26 -0
  444. package/src/harness/gate-reserve.ts +87 -0
  445. package/src/harness/harness-clean.ts +2 -1
  446. package/src/harness/harness-cli-command.ts +52 -5
  447. package/src/harness/harness-gc.ts +2 -1
  448. package/src/harness/harness-incidents.ts +70 -20
  449. package/src/harness/harness-pod-dispatch.ts +87 -10
  450. package/src/harness/harness-queue.ts +68 -4
  451. package/src/harness/harness-stop.ts +4 -3
  452. package/src/harness/harness-substrate-default.ts +78 -7
  453. package/src/harness/harness-worktree-auto.ts +2 -1
  454. package/src/harness/harness-worktrees.ts +3 -2
  455. package/src/hooks/dispatch.ts +2 -1
  456. package/src/index.ts +156 -27
  457. package/src/input/external-input-queue.ts +64 -7
  458. package/src/intake-plane/slash.ts +14 -3
  459. package/src/keybindings.ts +4 -1
  460. package/src/llm/route-decision.ts +36 -0
  461. package/src/llm/tool-loop-steered-rejection.ts +41 -0
  462. package/src/llm-request-shape.ts +209 -0
  463. package/src/llm.ts +301 -283
  464. package/src/loops/consensus.ts +348 -0
  465. package/src/loops/msg-wake.ts +206 -4
  466. package/src/loops/observe.ts +19 -3
  467. package/src/loops/orchestrator/tick.ts +88 -12
  468. package/src/loops/orchestrator/traffic.ts +64 -1
  469. package/src/loops/registry.ts +30 -0
  470. package/src/market/signed-index.ts +14 -0
  471. package/src/maturity/feature-maturity.ts +1 -1
  472. package/src/mcp/mcp-oauth.ts +54 -5
  473. package/src/models/prompts.ts +28 -0
  474. package/src/msg/msg-sse-client.ts +223 -0
  475. package/src/msg/msg-store.ts +86 -2
  476. package/src/mss/logging/log-store.ts +225 -1
  477. package/src/mss/logging/render-categories.ts +5 -0
  478. package/src/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
  479. package/src/nexus/api/http-server.ts +54 -15
  480. package/src/nexus/api/loop-resources.ts +19 -3
  481. package/src/nexus/api/ops-api.ts +11 -0
  482. package/src/nexus/daemon-thin-inventory.md +37 -0
  483. package/src/nexus/index.ts +70 -0
  484. package/src/nexus/state/state.ts +1 -0
  485. package/src/oauth/store.ts +32 -7
  486. package/src/onboarding/first-run.ts +28 -3
  487. package/src/ops/overview-cache.ts +16 -4
  488. package/src/ops/overview.ts +59 -2
  489. package/src/ops/resources.ts +82 -0
  490. package/src/plugins/maker/connector-maker.ts +41 -0
  491. package/src/plugins/maker/skill-maker.ts +42 -0
  492. package/src/pr-tool/census.ts +303 -0
  493. package/src/pr-tool/inflight-registry.ts +143 -0
  494. package/src/prompt-library/chat-conciseness.ts +13 -0
  495. package/src/prompt-library/universal-preamble.ts +10 -5
  496. package/src/pty-shell/pty-manifest.ts +12 -3
  497. package/src/pty-shell/tui-run-state.ts +34 -3
  498. package/src/release-loop/gate-host-reservation.ts +97 -0
  499. package/src/release-loop/landing-freeze.ts +5 -0
  500. package/src/release-loop/light-rc.ts +5 -2
  501. package/src/release-loop/placement.ts +92 -1
  502. package/src/release-loop/rehearsal-shard-plan.ts +149 -0
  503. package/src/release-loop/rehearsal.ts +73 -17
  504. package/src/repl/index.ts +20 -2
  505. package/src/seat-loop/seat-knowhow.ts +282 -0
  506. package/src/seat-loop/seat-loop.ts +41 -2
  507. package/src/seat-loop/traffic-signal.ts +5 -1
  508. package/src/self-dev/ask-launch-flow.ts +37 -3
  509. package/src/self-dev/decompose-compose-graph.ts +28 -27
  510. package/src/self-dev/decompose-proposal.ts +53 -38
  511. package/src/self-dev/decompose.ts +17 -0
  512. package/src/self-dev/dev-pipeline.ts +31 -2
  513. package/src/self-dev/draft-residue.ts +267 -33
  514. package/src/self-dev/draft-sweep.ts +59 -4
  515. package/src/self-dev/external-call-zero.ts +77 -0
  516. package/src/self-dev/launch-preflight-text.ts +6 -0
  517. package/src/self-dev/launch-preflight.ts +25 -3
  518. package/src/self-dev/local-supervisor-judge.ts +185 -0
  519. package/src/self-dev/run-supervisor.ts +229 -19
  520. package/src/self-dev/run-types.ts +20 -0
  521. package/src/self-dev/shard-aggregate.ts +13 -2
  522. package/src/self-dev/shard-plan.ts +56 -1
  523. package/src/self-dev/shard-run.ts +207 -12
  524. package/src/self-dev/spawn-lane-files.ts +19 -0
  525. package/src/self-implement/app-api-budget.ts +51 -11
  526. package/src/self-implement/config-gate.ts +2 -1
  527. package/src/self-implement/elanous-tui-spawn.ts +14 -0
  528. package/src/self-implement/expose-gate.ts +2 -1
  529. package/src/self-implement/follow-up-placement.ts +79 -0
  530. package/src/self-implement/gate-artifacts.ts +416 -0
  531. package/src/self-implement/gate-baseline.ts +96 -5
  532. package/src/self-implement/gate-cli.ts +207 -17
  533. package/src/self-implement/gate-remote.ts +136 -26
  534. package/src/self-implement/gate-scenario.ts +85 -0
  535. package/src/self-implement/goal-author.ts +160 -8
  536. package/src/self-implement/graph-authority.ts +38 -6
  537. package/src/self-implement/graph-overlay-condition.ts +92 -1
  538. package/src/self-implement/heal-triage.ts +79 -0
  539. package/src/self-implement/host-regate.ts +97 -7
  540. package/src/self-implement/orchestrator.ts +115 -134
  541. package/src/self-implement/pr-title.ts +123 -0
  542. package/src/self-implement/run-checkpoint.ts +235 -0
  543. package/src/self-implement/run-ledger.ts +162 -15
  544. package/src/self-implement/run-stop.ts +4 -3
  545. package/src/self-implement/run-ttl.ts +28 -4
  546. package/src/self-implement/seams.ts +2 -0
  547. package/src/self-implement/shadow-stage.ts +7 -6
  548. package/src/self-implement/stop-autoheal.ts +2 -1
  549. package/src/self-implement/train-gate-remote.ts +37 -8
  550. package/src/self-implement/train-reach-grouping.ts +157 -0
  551. package/src/self-implement/train-scenario-layers.ts +133 -0
  552. package/src/self-implement/uncommitted-work.ts +2 -0
  553. package/src/session/pending-input.ts +19 -0
  554. package/src/session/session-start.ts +224 -0
  555. package/src/session-runtime/index.ts +22 -267
  556. package/src/session-runtime/parallel-dispatch.ts +22 -5
  557. package/src/shell-runner/background-surface.ts +15 -5
  558. package/src/skills/tools/agent.ts +39 -6
  559. package/src/skills/tools/dev-harness.ts +6 -4
  560. package/src/skills/tools/list-dir.ts +11 -0
  561. package/src/skills/tools/schedule-wakeup.ts +408 -0
  562. package/src/skills/tools/shell.ts +246 -4
  563. package/src/status/bar.ts +26 -0
  564. package/src/steward/digest-delivery.ts +118 -0
  565. package/src/steward/hold-hygiene.ts +120 -0
  566. package/src/steward/resync-tick.ts +114 -23
  567. package/src/steward/ta-repair-event-collect.ts +158 -0
  568. package/src/steward/triage.ts +10 -0
  569. package/src/surface/shell-runner-boot.ts +5 -2
  570. package/src/task-agent/card-evidence.ts +25 -1
  571. package/src/task-agent/green-sweep.ts +8 -3
  572. package/src/task-agent/judge.ts +76 -0
  573. package/src/task-agent/land-queue.ts +79 -0
  574. package/src/task-agent/live-moves.ts +30 -9
  575. package/src/task-agent/postland-card.ts +5 -0
  576. package/src/task-agent/prelaunch-already-done.ts +98 -0
  577. package/src/task-agent/real-launch-guard.ts +37 -0
  578. package/src/task-agent/rejudge-on-head.ts +89 -12
  579. package/src/task-agent/remote-rejudge-bind.ts +28 -8
  580. package/src/task-agent/repair-cycle.ts +45 -7
  581. package/src/task-agent/repair-worker.ts +7 -0
  582. package/src/task-agent/run-identity.ts +200 -0
  583. package/src/task-agent/shadow.ts +50 -3
  584. package/src/task-agent/task-hand.ts +182 -5
  585. package/src/task-agent/train-landing.ts +77 -0
  586. package/src/task-agent/work-order.ts +104 -0
  587. package/src/task-orchestrator/surfaces/pod-command-job.ts +151 -37
  588. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +88 -19
  589. package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +2 -1
  590. package/src/task-orchestrator/surfaces/pod-image-source.ts +2 -1
  591. package/src/task-orchestrator/surfaces/pod-install-slots.ts +121 -9
  592. package/src/task-orchestrator/surfaces/pod-lease.ts +118 -6
  593. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +1 -1
  594. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +169 -0
  595. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +27 -0
  596. package/src/task-orchestrator/surfaces/pod-pool.ts +3 -1
  597. package/src/task-orchestrator/surfaces/pod-result-marker-wait.ts +33 -0
  598. package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +67 -0
  599. package/src/task-orchestrator/surfaces/pod-source-receive.ts +19 -3
  600. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +141 -0
  601. package/src/task-orchestrator/surfaces/pod-warm-ta-shadow.ts +85 -0
  602. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +525 -0
  603. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +153 -0
  604. package/src/task-orchestrator/surfaces/pod-warm-worker-runner.ts +90 -0
  605. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +362 -0
  606. package/src/task-orchestrator/surfaces/self-implement-pod.ts +138 -19
  607. package/src/telegram.ts +2 -4
  608. package/src/tui/chat/execution-badge.ts +5 -1
  609. package/src/tui/input/pickers.ts +732 -0
  610. package/src/tui/input-lag-probe.ts +230 -0
  611. package/src/tui/slash/mission.ts +492 -0
  612. package/src/tui/slash/term.ts +877 -0
  613. package/src/tui-client/dashboard-session.ts +9 -0
  614. package/src/tui.ts +52 -0
  615. package/src/user-config/gemini-server-tools.ts +9 -0
  616. package/src/user-config.ts +53 -16
  617. package/src/util/spawn-sync-output.ts +7 -0
  618. package/src/ux-sim/fake-bin.ts +154 -0
  619. package/src/ux-sim/fake-clock.ts +36 -0
  620. package/src/ux-sim/headless-tui.ts +72 -0
  621. package/src/ux-sim/in-process-cli.ts +2 -1
  622. package/src/ux-sim/scenario.ts +255 -0
  623. package/src/ux-sim/temp-git-remote.ts +82 -0
  624. package/src/version/packed-revision.json +1 -1
  625. package/src/video-pipeline/recipes/vlog.ts +25 -7
  626. package/apps/pwa/out/_next/static/chunks/1015-9cba22a5a4554797.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +0 -8
  630. package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +0 -34
  632. package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +0 -286
  635. package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +0 -24
  636. package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +0 -36
  639. package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +0 -64
  641. package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +0 -115
  647. package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +0 -90
  651. package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +0 -94
  662. package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +0 -62
  668. package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +0 -27
  671. package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +0 -104
  672. package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +0 -93
  673. package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +0 -24
  676. package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +0 -2
  678. package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +0 -148
  679. package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +0 -149
  680. package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +0 -79
  682. package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +0 -287
  688. package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +0 -77
  695. package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +0 -74
  698. package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +0 -226
  703. package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +0 -32
  705. package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/a435ad95.577add051b4facb2.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/app/botlab/page-a5635eba0d73b84e.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/app/ceo/page-86feb08080261a2f.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/app/loops/page-8aaa6dedc4c10dfb.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/morning/page-33bf667a5fb297bf.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/term/page-9eb56166774eb256.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9f92737b8766009a.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +0 -122
  768. package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.js +0 -1
  774. package/apps/pwa/out/_next/static/css/72becfd42807b50d.css +0 -1
  775. /package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → IVKr3AlRUVLKsw2fh7eXF}/_ssgManifest.js +0 -0
@@ -0,0 +1,235 @@
1
+ /**
2
+ * run-checkpoint/v1 묶음 스키마 — 런의 «체크포인트» 스냅샷을 판 번호 있는 타입으로 직렬화한다.
3
+ *
4
+ * ⛔ 이 판은 «묶음 정의 ⊕ 조립 ⊕ 디스크 기록»까지만 담는다. orchestrator 배선 · run-ledger
5
+ * additive 이벤트('checkpoint'/'resumed'/'checkpoint-failed') · salvage CLI 명령은
6
+ * 같은 골의 형제 조각이 담당한다(의도적 경계 — 분해 판 4조각의 1번).
7
+ *
8
+ * 📐 run-ledger 패턴을 «어느 것을 왜» 따르나(원문이 'writeCheckpoi'에서 끊겨 임의로 정하지 않는다):
9
+ * ① `runLedgerDir`(run-ledger.ts:205) — 상태 뿌리에서 «자기 저장소 이름»의 디렉터리를 여는 방식.
10
+ * 여기도 `elanousStateRoot()` 아래 `run-checkpoint/` 디렉터리로 열어, 저장 위치가 run-ledger 와
11
+ * 같은 축(state root)에 있게 한다. 원문이 저장 위치의 경로를 정하지 않았으므로 이 패턴을 따른다.
12
+ * ② `runLedgerPath`(run-ledger.ts:209) — runId 를 «normalizeRunId 의 산출 집합»으로 검증하고
13
+ * 거부는 유지하되 정규화는 «하지 않는다»(경로 탈출 방어). 여기도 같은 검사를 쓰되 파일은
14
+ * 스냅샷이므로 JSONL 추가가 아니라 «덮어쓰기» 하나로 `<runId>.checkpoint.json` 을 쓴다.
15
+ * JSONL 이 아닌 이유: 원장은 사건의 «추가», 체크포인트는 마지막 상태의 «스냅샷»이다 —
16
+ * appendRunLedgerEntry 가 줄을 «쌓는» 것과 달리 resume 은 «최신 하나»만 읽으면 된다.
17
+ * ③ `appendRunLedgerEntry`(run-ledger.ts:411) — 쓰기 전 ①`refuseProductionLedgerWriteInTest`
18
+ * 가드(테스트 중 운영 원장 쓰기 차단) ② `mkdirSync(dir, { recursive: true })` 순서를 그대로 따른다.
19
+ * «run-ledger 줄 하나»가 아니라 «JSON 파일 하나»이지만 쓰기 관문·디렉터리 보증은 같아야 한다.
20
+ */
21
+ import { createHash, randomUUID } from 'node:crypto';
22
+ import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
23
+ import { join } from 'node:path';
24
+ import { refuseProductionLedgerWriteInTest } from '../harness/ledger-write-guard.js';
25
+ import { normalizeRunId } from '../harness/harness-space.js';
26
+ import { elanousStateRoot } from '../autopilot/state-paths.js';
27
+
28
+ /** 판 번호 — 묶음 필드 구성이 바뀌면 이 값을 올리고 읽는 쪽은 판을 검사한다. */
29
+ export const CHECKPOINT_SCHEMA_VERSION = 1;
30
+
31
+ /** 판 번호가 문자열 표면(직렬화된 JSON 안)에 남는 형태. */
32
+ export const CHECKPOINT_SCHEMA_ID = 'run-checkpoint/v1';
33
+
34
+ /** 라운드 카드 — 조립 시점에 판을 정하지 않는다(원문이 카드의 필드를 정하지 않았다). */
35
+ export type CheckpointRoundCard = Record<string, unknown>;
36
+
37
+ /** 미배달 감독 지시 한 줄 — 조립자가 주는 문면 그대로. */
38
+ export type UndeliveredSupervisorDirective = string;
39
+
40
+ /**
41
+ * run-checkpoint/v1 묶음 — 전 필드의 원문 명세:
42
+ * runId · 골 문면(goalText) · 판정 상태(verdictStatus) · salvage 가지 sha(salvageBranchSha) ·
43
+ * 세션 대화 기록(sessionTranscript) · 라운드 카드(roundCards) · EVIDENCE/RESULT(evidenceResult) ·
44
+ * 미배달 감독 지시(undeliveredSupervisorDirectives) · 자식 모델(childModel) · 쓴 토큰(tokensUsed) ·
45
+ * sha256(«전 필드 포함» — sha256 자기 자신만 제외한 나머지 전 필드의 정규화 직렬화에 걸친다).
46
+ */
47
+ export interface RunCheckpointBundle {
48
+ /** 판이자 종류 표지 — 항상 `${CHECKPOINT_SCHEMA_ID}`. */
49
+ schema: typeof CHECKPOINT_SCHEMA_ID;
50
+ /** 판 번호(정수) — CHECKPOINT_SCHEMA_VERSION 과 같다. */
51
+ schemaVersion: typeof CHECKPOINT_SCHEMA_VERSION;
52
+ runId: string;
53
+ goalText: string;
54
+ verdictStatus: string;
55
+ /** 없으면 null — «모름»과 «없음»을 나눈다. */
56
+ salvageBranchSha: string | null;
57
+ /** null = «미확인»(조립자가 주지 않음) — 빈 문자열(«실제로 비어 있음»)과 구별한다. */
58
+ sessionTranscript: string | null;
59
+ /** null = «미확인» — 빈 배열(«카드 0장»)과 구별한다. */
60
+ roundCards: readonly CheckpointRoundCard[] | null;
61
+ /** null = «미확인» — 빈 문자열과 구별한다. */
62
+ evidenceResult: string | null;
63
+ /** null = «미확인» — 빈 배열(«미배달 지시 0건»)과 구별한다. */
64
+ undeliveredSupervisorDirectives: readonly UndeliveredSupervisorDirective[] | null;
65
+ childModel: string | null;
66
+ tokensUsed: number | null;
67
+ /** sha256 — 자기를 제외한 전 필드 정규화 직렬화에 대한 sha256 hex. */
68
+ sha256: string;
69
+ recordedAt: string;
70
+ }
71
+
72
+ /** 조립 재료 — run 사실 원형. `buildCheckpointBundle` 이 여기서 묶음을 만든다. */
73
+ export interface RunCheckpointFacts {
74
+ runId: string;
75
+ goalText: string;
76
+ verdictStatus: string;
77
+ salvageBranchSha?: string | null;
78
+ sessionTranscript?: string | null;
79
+ roundCards?: readonly CheckpointRoundCard[] | null;
80
+ evidenceResult?: string | null;
81
+ undeliveredSupervisorDirectives?: readonly UndeliveredSupervisorDirective[] | null;
82
+ childModel?: string | null;
83
+ tokensUsed?: number | null;
84
+ recordedAt?: string;
85
+ }
86
+
87
+ /** 정렬된 키 직렬화 — 입력은 이미 «JSON 값»(toJSON·undefined·NaN 이 풀린 뒤)이어야 한다. */
88
+ function sortedJson(value: unknown): string {
89
+ if (value === null || typeof value !== 'object') return JSON.stringify(value);
90
+ if (Array.isArray(value)) return `[${value.map((item) => sortedJson(item)).join(',')}]`;
91
+ const entries = Object.entries(value as Record<string, unknown>)
92
+ .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
93
+ return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${sortedJson(v)}`).join(',')}}`;
94
+ }
95
+
96
+ /**
97
+ * 객체 키를 «정렬된» 안정 직렬화로 — 같은 값이면 같은 문자열(sha256 재현성).
98
+ * ⭐ 해시와 저장이 «같은 직렬화»를 보도록 먼저 `JSON.stringify` 의미론(toJSON·Date→ISO ·
99
+ * 배열 속 undefined→null · 객체 속 undefined 제거 · NaN→null)으로 한 번 풀고 키만 정렬한다.
100
+ * 그래야 `writeCheckpoint` 가 쓴 파일을 `readCheckpoint` 가 다시 해시해도 같은 값이 나온다.
101
+ */
102
+ function canonicalJson(value: unknown): string {
103
+ const json = JSON.stringify(value);
104
+ if (json === undefined) return 'null';
105
+ return sortedJson(JSON.parse(json));
106
+ }
107
+
108
+ /** sha256 조수 — hex 문자열. 묶음의 sha256 필드에 넣는 값과 같은 계산이다. */
109
+ export function sha256Hex(value: unknown): string {
110
+ return createHash('sha256').update(canonicalJson(value), 'utf8').digest('hex');
111
+ }
112
+
113
+ /** sha256 자기 자신을 제외한 «전 필드»를 걸치는 다이제스트(원문: 'sha256 전 필드 포함'). */
114
+ export function bundleSha256(bundle: Omit<RunCheckpointBundle, 'sha256'>): string {
115
+ const { sha256: _omit, ...rest } = bundle as RunCheckpointBundle;
116
+ return sha256Hex(rest);
117
+ }
118
+
119
+ const isStringArray = (v: unknown): boolean => Array.isArray(v) && v.every((x) => typeof x === 'string');
120
+ const isNullableString = (v: unknown): boolean => v === null || typeof v === 'string';
121
+
122
+ /**
123
+ * 묶음의 판(schema ⊕ schemaVersion)과 필수 필드의 존재·타입을 검증한다 — 쓰기·읽기 공통 관문.
124
+ * 판 번호는 «지원하는 판»과 정확히 같아야 한다(다른 판을 v1 으로 받아들이지 않는다).
125
+ */
126
+ export function assertCheckpointShape(value: unknown): asserts value is RunCheckpointBundle {
127
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
128
+ throw new Error('invalid checkpoint: not an object');
129
+ }
130
+ const b = value as Record<string, unknown>;
131
+ if (b.schema !== CHECKPOINT_SCHEMA_ID) {
132
+ throw new Error(`unknown checkpoint schema: ${String(b.schema)}`);
133
+ }
134
+ if (b.schemaVersion !== CHECKPOINT_SCHEMA_VERSION) {
135
+ throw new Error(`unsupported checkpoint schemaVersion: ${String(b.schemaVersion)}`);
136
+ }
137
+ const bad: string[] = [];
138
+ for (const key of ['runId', 'goalText', 'verdictStatus', 'sha256', 'recordedAt']) {
139
+ if (typeof b[key] !== 'string') bad.push(key);
140
+ }
141
+ if (!isNullableString(b.salvageBranchSha)) bad.push('salvageBranchSha');
142
+ // null = «미확인» 을 받아들인다(빈 값과 다른 값) — 키 자체가 없으면(undefined) 거부한다.
143
+ if (!isNullableString(b.sessionTranscript)) bad.push('sessionTranscript');
144
+ if (!isNullableString(b.evidenceResult)) bad.push('evidenceResult');
145
+ if (!isNullableString(b.childModel)) bad.push('childModel');
146
+ if (!(b.tokensUsed === null || (typeof b.tokensUsed === 'number' && Number.isFinite(b.tokensUsed)))) {
147
+ bad.push('tokensUsed');
148
+ }
149
+ if (b.roundCards !== null && (!Array.isArray(b.roundCards) || !b.roundCards.every((c) => c !== null && typeof c === 'object' && !Array.isArray(c)))) {
150
+ bad.push('roundCards');
151
+ }
152
+ if (b.undeliveredSupervisorDirectives !== null && !isStringArray(b.undeliveredSupervisorDirectives)) bad.push('undeliveredSupervisorDirectives');
153
+ if (bad.length > 0) throw new Error(`invalid checkpoint fields: ${bad.join(', ')}`);
154
+ }
155
+
156
+ /** run 사실에서 run-checkpoint/v1 묶음을 조립한다 — sha256 도 이 안에서 계산해 넣는다. */
157
+ export function buildCheckpointBundle(facts: RunCheckpointFacts): RunCheckpointBundle {
158
+ const runId = facts.runId;
159
+ // runLedgerPath 패턴: 정규화는 하지 않고, normalizeRunId 의 «산출 집합»만 받아들인다.
160
+ if (!runId || runId !== normalizeRunId(runId)) throw new Error(`invalid runId: ${runId}`);
161
+ const partial: Omit<RunCheckpointBundle, 'sha256'> = {
162
+ schema: CHECKPOINT_SCHEMA_ID,
163
+ schemaVersion: CHECKPOINT_SCHEMA_VERSION,
164
+ runId,
165
+ goalText: facts.goalText,
166
+ verdictStatus: facts.verdictStatus,
167
+ salvageBranchSha: facts.salvageBranchSha ?? null,
168
+ // 생략 = «미확인»(null) — 빈 값으로 채워 «실제로 비어 있음»으로 위장하지 않는다.
169
+ sessionTranscript: facts.sessionTranscript ?? null,
170
+ roundCards: facts.roundCards ?? null,
171
+ evidenceResult: facts.evidenceResult ?? null,
172
+ undeliveredSupervisorDirectives: facts.undeliveredSupervisorDirectives ?? null,
173
+ childModel: facts.childModel ?? null,
174
+ tokensUsed: facts.tokensUsed ?? null,
175
+ recordedAt: facts.recordedAt ?? new Date().toISOString(),
176
+ };
177
+ // 저장될 꼴(JSON 값)로 한 번 풀어, 메모리 묶음 = 파일에서 읽은 묶음이 되게 한다(Date→ISO 등).
178
+ const stored = JSON.parse(JSON.stringify(partial)) as Omit<RunCheckpointBundle, 'sha256'>;
179
+ return { ...stored, sha256: bundleSha256(stored) };
180
+ }
181
+
182
+ /** runLedgerDir 패턴 — state root 아래 «자기 저장소 이름» 디렉터리. */
183
+ export function checkpointDir(stateDir?: string): string {
184
+ return join(stateDir ?? elanousStateRoot(), 'run-checkpoint');
185
+ }
186
+
187
+ /** runLedgerPath 패턴 — runId 검증(정규화 아님) 후 경로 결정. */
188
+ export function checkpointPath(runId: string, dir = checkpointDir()): string {
189
+ if (runId !== normalizeRunId(runId) || !runId) throw new Error(`invalid runId: ${runId}`);
190
+ return join(dir, `${runId}.checkpoint.json`);
191
+ }
192
+
193
+ /**
194
+ * 묶음을 디스크에 기록한다(appendRunLedgerEntry 의 쓰기 관문·디렉터리 보증을 따른다).
195
+ * 반환값은 기록한 파일 경로 — 형제 조각의 원장 이벤트 'checkpoint' {bundleRef} 가 여기 담긴다.
196
+ *
197
+ * ⛔ 스냅샷은 «최신 하나»라 덮어쓰기가 곧 이전 상태의 소실이다. 그래서
198
+ * ① 쓰기 «전»에 판·sha256 을 검증해 무효 묶음이면 던지고 기존 파일을 건드리지 않는다.
199
+ * ② 임시 파일에 쓴 뒤 rename 으로 원자 교체한다(쓰다 죽어도 반쪽 파일이 남지 않는다).
200
+ */
201
+ export function writeCheckpoint(bundle: RunCheckpointBundle, dir = checkpointDir()): string {
202
+ assertCheckpointShape(bundle);
203
+ const path = checkpointPath(bundle.runId, dir);
204
+ const body = `${JSON.stringify(bundle, null, 2)}\n`;
205
+ // 저장될 꼴 그대로를 다시 해시한다 — 읽기 쪽 검증과 같은 입력이다.
206
+ const expected = bundleSha256(JSON.parse(body) as RunCheckpointBundle);
207
+ if (bundle.sha256 !== expected) {
208
+ throw new Error(`checkpoint sha256 mismatch: ${bundle.sha256} != ${expected}`);
209
+ }
210
+ if (refuseProductionLedgerWriteInTest(dir, 'run-checkpoint')) return '';
211
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
212
+ const tmp = `${path}.${process.pid}.${randomUUID()}.tmp`;
213
+ try {
214
+ writeFileSync(tmp, body, 'utf8');
215
+ renameSync(tmp, path);
216
+ } catch (error) {
217
+ rmSync(tmp, { force: true });
218
+ throw error;
219
+ }
220
+ return path;
221
+ }
222
+
223
+ /** 기록된 묶음을 읽어 sha256 이 전 필드에 대해 아직 성립하는지 검증과 함께 돌려준다. */
224
+ export function readCheckpoint(runId: string, dir = checkpointDir()): RunCheckpointBundle {
225
+ const raw: unknown = JSON.parse(readFileSync(checkpointPath(runId, dir), 'utf8'));
226
+ assertCheckpointShape(raw);
227
+ if (raw.runId !== runId) {
228
+ throw new Error(`checkpoint runId mismatch: requested ${runId}, file has ${raw.runId}`);
229
+ }
230
+ const expected = bundleSha256(raw);
231
+ if (raw.sha256 !== expected) {
232
+ throw new Error(`checkpoint sha256 mismatch: ${raw.sha256} != ${expected}`);
233
+ }
234
+ return raw;
235
+ }
@@ -1,4 +1,4 @@
1
- import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync, unlinkSync } from 'node:fs';
1
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
2
2
  import { dirname, isAbsolute, join, resolve } from 'node:path';
3
3
  import { refuseProductionLedgerWriteInTest } from '../harness/ledger-write-guard.js';
4
4
  import { tracedPathReferences, verbatimOriginalAsk } from './goal-author.js';
@@ -20,6 +20,7 @@ export interface RunLedgerEntry {
20
20
  event: string;
21
21
  data: Record<string, unknown>;
22
22
  goalId?: string;
23
+ devProject?: string;
23
24
  orchestrationId?: string;
24
25
  shardId?: string;
25
26
  siblingShardIds?: string[];
@@ -412,8 +413,12 @@ export function appendRunLedgerEntry(entry: RunLedgerEntry, dir = runLedgerDir()
412
413
  if (refuseProductionLedgerWriteInTest(dir, 'run-ledger')) return;
413
414
  if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
414
415
  const live = runLedgerPath(entry.runId, dir);
416
+ const devProject = process.env.ELANOUS_DEV_PROJECT;
417
+ const row = entry.devProject === undefined && typeof devProject === 'string' && devProject.startsWith('prj-')
418
+ ? { ...entry, devProject }
419
+ : entry;
415
420
  withRunLedgerLock(dir, entry.runId, () => {
416
- const line = `${JSON.stringify(entry)}\n`;
421
+ const line = `${JSON.stringify(row)}\n`;
417
422
  if (!restoreArchivedRunLedger(dir, entry.runId, line)) appendFileSync(live, line, 'utf8');
418
423
  });
419
424
  }
@@ -1315,6 +1320,10 @@ export interface UnfinishedRunLedgerQuery {
1315
1320
  terminalByTrailingRunStatus?: number;
1316
1321
  cacheHits?: number;
1317
1322
  cacheMisses?: number;
1323
+ /** Hits served by the persisted cross-process scan index (subset of cacheHits). */
1324
+ indexHits?: number;
1325
+ /** Whether that index was loaded from disk, started fresh, or was bypassed. */
1326
+ indexOrigin?: RunLedgerScanIndexOrigin;
1318
1327
  pathFilter?: string;
1319
1328
  matchingPathCount?: number;
1320
1329
  unknownPathCount?: number;
@@ -1658,9 +1667,9 @@ interface UnfinishedLedgerFacts {
1658
1667
  nonBlocking: NonBlockingRunLedgerRecord | null;
1659
1668
  }
1660
1669
 
1661
- // A full federated scan can exceed 5,000 files; keep the previous scan resident for mtime-checked reuse.
1670
+ // A full federated scan can exceed 5,000 files; keep the previous scan resident for stat-checked reuse.
1662
1671
  const UNFINISHED_LEDGER_CACHE_LIMIT = 32_768;
1663
- const unfinishedLedgerCache = new Map<string, { size: number; mtimeMs: number; facts: UnfinishedLedgerFacts }>();
1672
+ const unfinishedLedgerCache = new Map<string, { size: number; mtimeMs: number; ctimeMs: number; facts: UnfinishedLedgerFacts }>();
1664
1673
  const unfinishedReaderIds = new WeakMap<RunLedgerReader, number>();
1665
1674
  let nextUnfinishedReaderId = 1;
1666
1675
 
@@ -1674,6 +1683,97 @@ function unfinishedLedgerCacheKey(path: string, read?: RunLedgerReader): string
1674
1683
  return `${path}\u0000reader:${id}`;
1675
1684
  }
1676
1685
 
1686
+ // ⭐ 프로세스 간 유효 스캔 색인(칸 CONTEXT-NOW-RUN-SCAN-INDEX).
1687
+ // `/now`(contextNowInWorker)는 요청마다 «새 워커 프로세스»를 띄우므로 위 프로세스 캐시는 매번 빈 채로 시작한다
1688
+ // (실측 2026-10-14: scanned=7893, cacheHits=0, 조회 6.3~8.9초). 색인은 파싱된 파일별 facts 를
1689
+ // 원장 옆에 (size, mtimeMs, ctimeMs) 스탬프로 저장하고, 스탬프가 같으면 재사용한다. 원장에 무엇이 «붙으면»
1690
+ // 스탬프가 바뀌므로 무효화는 자동이다 (같은 크기로 덮고 mtime 을 되돌려도 ctime 이 바뀐다). 읽기 실패는 전부 fail-soft: 색인이 없으면 그냥 새로 읽는다.
1691
+ const RUN_LEDGER_SCAN_INDEX_FILE = '.unfinished-scan-index.json';
1692
+ const RUN_LEDGER_SCAN_INDEX_VERSION = 2;
1693
+ const RUN_LEDGER_SCAN_INDEX_LIMIT = 32_768;
1694
+
1695
+ /** Where the persisted scan index lives: beside its ledgers, never mistaken for one (readdir filters canonical names). */
1696
+ export function runLedgerScanIndexPath(dir: string): string {
1697
+ return join(dir, RUN_LEDGER_SCAN_INDEX_FILE);
1698
+ }
1699
+
1700
+ export interface RunLedgerScanIndexRecord {
1701
+ size: number;
1702
+ mtimeMs: number;
1703
+ ctimeMs: number;
1704
+ facts: UnfinishedLedgerFacts;
1705
+ }
1706
+
1707
+ /** Whether the persisted index was loaded, started fresh, or was bypassed (noCache or an injected reader). */
1708
+ export type RunLedgerScanIndexOrigin = 'loaded' | 'fresh' | 'bypassed';
1709
+
1710
+ const UNFINISHED_LIFECYCLE_WORDS = new Set<string>([
1711
+ 'live', 'orphaned', 'human-stopped', 'terminal-other-vocabulary', 'terminal-run-status-superseded', 'unjudgeable',
1712
+ ]);
1713
+
1714
+ function isScanIndexFacts(value: unknown): value is UnfinishedLedgerFacts {
1715
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return false;
1716
+ const facts = value as Record<string, unknown>;
1717
+ return typeof facts.terminal === 'boolean'
1718
+ && typeof facts.terminalByTrailingRunStatus === 'boolean'
1719
+ && (facts.branch === null || typeof facts.branch === 'string')
1720
+ && (facts.lastActivityTimestamp === null || typeof facts.lastActivityTimestamp === 'string')
1721
+ && typeof facts.lastActivityStatus === 'string'
1722
+ && (facts.targetRoot === null || typeof facts.targetRoot === 'string')
1723
+ && (facts.goalFile === null || typeof facts.goalFile === 'string')
1724
+ && typeof facts.fixedLifecycle === 'string' && UNFINISHED_LIFECYCLE_WORDS.has(facts.fixedLifecycle);
1725
+ }
1726
+
1727
+ function isScanIndexRecord(value: unknown): value is RunLedgerScanIndexRecord {
1728
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return false;
1729
+ const record = value as Record<string, unknown>;
1730
+ return Number.isFinite(record.size) && Number.isFinite(record.mtimeMs) && Number.isFinite(record.ctimeMs) && isScanIndexFacts(record.facts);
1731
+ }
1732
+
1733
+ const scanIndexCache = new Map<string, { stamp: string; entries: Map<string, RunLedgerScanIndexRecord> }>();
1734
+
1735
+ function scanIndexFileStamp(path: string): string {
1736
+ try { const stat = statSync(path); return `${stat.size}:${stat.mtimeMs}`; } catch { return 'missing'; }
1737
+ }
1738
+
1739
+ /** Load (memoized by index-file stamp) the persisted per-directory scan index; malformed or absent behaves as fresh. */
1740
+ export function loadRunLedgerScanIndex(dir: string): Map<string, RunLedgerScanIndexRecord> {
1741
+ const path = runLedgerScanIndexPath(dir);
1742
+ const stamp = scanIndexFileStamp(path);
1743
+ const cached = scanIndexCache.get(dir);
1744
+ if (cached && cached.stamp === stamp) return cached.entries;
1745
+ const entries = new Map<string, RunLedgerScanIndexRecord>();
1746
+ if (stamp !== 'missing') {
1747
+ try {
1748
+ const parsed: unknown = JSON.parse(readFileSync(path, 'utf8'));
1749
+ const raw = parsed && typeof parsed === 'object' && !Array.isArray(parsed)
1750
+ && (parsed as Record<string, unknown>).version === RUN_LEDGER_SCAN_INDEX_VERSION
1751
+ && typeof (parsed as Record<string, unknown>).entries === 'object'
1752
+ && (parsed as Record<string, unknown>).entries !== null && !Array.isArray((parsed as Record<string, unknown>).entries)
1753
+ ? (parsed as { entries: Record<string, unknown> }).entries : null;
1754
+ if (raw) for (const [runId, record] of Object.entries(raw)) {
1755
+ if (isScanIndexRecord(record)) entries.set(runId, record);
1756
+ }
1757
+ } catch { /* a malformed index behaves as absent */ }
1758
+ }
1759
+ scanIndexCache.set(dir, { stamp, entries });
1760
+ return entries;
1761
+ }
1762
+
1763
+ /** Persist the index beside its ledgers, best-effort: any failure just leaves the next scan reading fresh. */
1764
+ function persistRunLedgerScanIndex(dir: string, entries: ReadonlyMap<string, RunLedgerScanIndexRecord>): boolean {
1765
+ if (refuseProductionLedgerWriteInTest(dir, 'run-ledger-scan-index')) return false;
1766
+ const bounded = entries.size > RUN_LEDGER_SCAN_INDEX_LIMIT
1767
+ ? new Map([...entries].slice(entries.size - RUN_LEDGER_SCAN_INDEX_LIMIT))
1768
+ : entries;
1769
+ try {
1770
+ writeFileSync(runLedgerScanIndexPath(dir), JSON.stringify({ version: RUN_LEDGER_SCAN_INDEX_VERSION, entries: Object.fromEntries(bounded) }), 'utf8');
1771
+ return true;
1772
+ } catch {
1773
+ return false;
1774
+ }
1775
+ }
1776
+
1677
1777
  function unfinishedLedgerFacts(ledger: readonly RunLedgerEntry[]): UnfinishedLedgerFacts {
1678
1778
  const last = ledger.at(-1)?.timestamp;
1679
1779
  const lastActivityTimestamp = last !== undefined && Number.isFinite(Date.parse(last)) ? last : null;
@@ -1690,31 +1790,52 @@ function unfinishedLedgerFacts(ledger: readonly RunLedgerEntry[]): UnfinishedLed
1690
1790
  };
1691
1791
  }
1692
1792
 
1693
- function readUnfinishedLedgerFacts(runId: string, dir: string, read?: RunLedgerReader, noCache?: boolean): { facts: UnfinishedLedgerFacts; hit: boolean } {
1793
+ function readUnfinishedLedgerFacts(
1794
+ runId: string,
1795
+ dir: string,
1796
+ read?: RunLedgerReader,
1797
+ noCache?: boolean,
1798
+ index?: Map<string, RunLedgerScanIndexRecord>,
1799
+ ): { facts: UnfinishedLedgerFacts; hit: boolean; source: 'process' | 'index' | 'read' } {
1694
1800
  const path = runLedgerPath(runId, dir);
1695
1801
  const key = noCache ? null : unfinishedLedgerCacheKey(path, read);
1696
1802
  const stamp = noCache ? null : statSync(path);
1697
1803
  const cached = key === null ? undefined : unfinishedLedgerCache.get(key);
1698
- if (cached && stamp && key !== null && cached.size === stamp.size && cached.mtimeMs === stamp.mtimeMs) {
1804
+ if (cached && stamp && key !== null && cached.size === stamp.size && cached.mtimeMs === stamp.mtimeMs && cached.ctimeMs === stamp.ctimeMs) {
1699
1805
  unfinishedLedgerCache.delete(key);
1700
1806
  unfinishedLedgerCache.set(key, cached);
1701
- return { facts: cached.facts, hit: true };
1807
+ return { facts: cached.facts, hit: true, source: 'process' };
1702
1808
  }
1703
1809
  if (key !== null) unfinishedLedgerCache.delete(key);
1810
+ // ⭐ 프로세스 캐시가 비었어도(새 워커) 디스크 색인의 스탬프가 같으면 재사용한다.
1811
+ // 주입된 reader 는 실제 파일 내용과 무관한 대역이라 색인에 넣지 «도», 색인에서 읽지 «도» 않는다.
1812
+ if (index !== undefined && stamp && read === undefined) {
1813
+ const record = index.get(runId);
1814
+ if (record && record.size === stamp.size && record.mtimeMs === stamp.mtimeMs && record.ctimeMs === stamp.ctimeMs) {
1815
+ if (key !== null) unfinishedLedgerCache.set(key, { size: stamp.size, mtimeMs: stamp.mtimeMs, ctimeMs: stamp.ctimeMs, facts: record.facts });
1816
+ return { facts: record.facts, hit: true, source: 'index' };
1817
+ }
1818
+ }
1704
1819
  try {
1705
1820
  const ledger = loadRunLedger(runId, dir, read);
1706
1821
  if (ledger === null && stamp !== null) throw new Error(`run ledger disappeared after stat: ${path}`);
1707
1822
  const facts = unfinishedLedgerFacts(ledger ?? []);
1708
1823
  if (stamp !== null && key !== null) {
1709
1824
  const after = statSync(path);
1710
- if (after.size === stamp.size && after.mtimeMs === stamp.mtimeMs) {
1711
- unfinishedLedgerCache.set(key, { size: stamp.size, mtimeMs: stamp.mtimeMs, facts });
1825
+ if (after.size === stamp.size && after.mtimeMs === stamp.mtimeMs && after.ctimeMs === stamp.ctimeMs) {
1826
+ unfinishedLedgerCache.set(key, { size: stamp.size, mtimeMs: stamp.mtimeMs, ctimeMs: stamp.ctimeMs, facts });
1712
1827
  if (unfinishedLedgerCache.size > UNFINISHED_LEDGER_CACHE_LIMIT) unfinishedLedgerCache.delete(unfinishedLedgerCache.keys().next().value!);
1828
+ // Persist only facts read from a stable ledger; an append during the read must be retried next scan.
1829
+ if (index !== undefined && read === undefined) index.set(runId, { size: stamp.size, mtimeMs: stamp.mtimeMs, ctimeMs: stamp.ctimeMs, facts });
1830
+ } else {
1831
+ index?.delete(runId);
1713
1832
  }
1714
1833
  }
1715
- return { facts, hit: false };
1834
+ return { facts, hit: false, source: 'read' };
1716
1835
  } catch (error) {
1717
1836
  if (key !== null) unfinishedLedgerCache.delete(key);
1837
+ // 원장이 사라졌거나 바뀐 사이에 읽었다 — 색인의 스탬프는 이미 무효이므로 치운다(무효화).
1838
+ index?.delete(runId);
1718
1839
  throw error;
1719
1840
  }
1720
1841
  }
@@ -1734,6 +1855,11 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
1734
1855
  const goalsDir = resolve(options.goalsDir ?? resolveGoalDocumentsDir(process.cwd()).directory);
1735
1856
  const list = options.list ?? readdirSync;
1736
1857
  const liveWindowMs = options.liveWindowMs ?? DEFAULT_UNFINISHED_LIVE_WINDOW_MS;
1858
+ // ⭐ 색인은 noCache 나 주입된 reader 가 아니어야만 켠다 — 그 둘은 «정직한 재읽기» 계약을 지켜야 한다.
1859
+ const scanIndex = !options.noCache && options.read === undefined ? loadRunLedgerScanIndex(dir) : undefined;
1860
+ const indexOrigin: RunLedgerScanIndexOrigin = scanIndex === undefined ? 'bypassed' : scanIndex.size > 0 ? 'loaded' : 'fresh';
1861
+ let indexHits = 0;
1862
+ let indexChanged = false;
1737
1863
  let fileNames: string[];
1738
1864
  try {
1739
1865
  fileNames = list(dir);
@@ -1748,6 +1874,8 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
1748
1874
  terminalByTrailingRunStatus: 0,
1749
1875
  cacheHits: 0,
1750
1876
  cacheMisses: 0,
1877
+ indexHits: 0,
1878
+ indexOrigin,
1751
1879
  ...(options.path === undefined ? {} : { pathFilter: options.path, matchingPathCount: 0, unknownPathCount: 0 }),
1752
1880
  scope: 'self-implement-run-ledger',
1753
1881
  note: UNFINISHED_RUN_LEDGER_NOTE,
@@ -1760,6 +1888,8 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
1760
1888
  terminalByTrailingRunStatus: 0,
1761
1889
  cacheHits: 0,
1762
1890
  cacheMisses: 0,
1891
+ indexOrigin,
1892
+ indexHits: 0,
1763
1893
  ms: Date.now() - startedAt,
1764
1894
  });
1765
1895
  return missing;
@@ -1782,12 +1912,18 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
1782
1912
  scanned += 1;
1783
1913
  let facts: UnfinishedLedgerFacts;
1784
1914
  try {
1785
- const observed = readUnfinishedLedgerFacts(runId, dir, options.read, options.noCache);
1915
+ const observed = readUnfinishedLedgerFacts(runId, dir, options.read, options.noCache, scanIndex);
1786
1916
  facts = observed.facts;
1787
- if (observed.hit) cacheHits += 1;
1788
- else cacheMisses += 1;
1917
+ if (observed.hit) {
1918
+ cacheHits += 1;
1919
+ if (observed.source === 'index') indexHits += 1;
1920
+ } else {
1921
+ cacheMisses += 1;
1922
+ if (scanIndex !== undefined) indexChanged = true;
1923
+ }
1789
1924
  } catch {
1790
1925
  cacheMisses += 1;
1926
+ if (scanIndex?.delete(runId)) indexChanged = true;
1791
1927
  unreadableLedgerCount += 1;
1792
1928
  entries.push({ runId, branch: null, status: 'ledger-unreadable', plannedPaths: [], plannedPathStatus: 'unknown', ...unknownDeclaredPaths(), pathMatchReasons: {}, goalDocumentPath: null, goalLookupBasis: 'caller-cwd', goalDocumentSearchDirectory: null, lastActivityTimestamp: null, lastActivityAgeMs: null, lastActivityStatus: 'ledger-unreadable', lifecycle: 'unjudgeable' });
1793
1929
  callerCwdCount += 1;
@@ -1840,6 +1976,7 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
1840
1976
  }
1841
1977
  }
1842
1978
  entries.sort((left, right) => left.runId.localeCompare(right.runId));
1979
+ if (scanIndex !== undefined && indexChanged) persistRunLedgerScanIndex(dir, scanIndex);
1843
1980
  debug.log('self-implement.run-ledger', 'goal-lookup-basis', { ledgerTarget: ledgerTargetCount, callerCwd: callerCwdCount });
1844
1981
  debug.log('self-implement.run-ledger', 'unfinished-query', {
1845
1982
  scanned,
@@ -1848,10 +1985,12 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
1848
1985
  terminalByTrailingRunStatus,
1849
1986
  cacheHits,
1850
1987
  cacheMisses,
1988
+ indexOrigin,
1989
+ indexHits,
1851
1990
  ms: Date.now() - startedAt,
1852
1991
  });
1853
1992
  if (options.path === undefined) {
1854
- return { entries, ledgerDirectory: dir, goalsDirectory: goalsDir, unreadableLedgerCount, ledgerDirectoryMissing: false, terminalByTrailingRunStatus, cacheHits, cacheMisses, scope: 'self-implement-run-ledger', note: UNFINISHED_RUN_LEDGER_NOTE };
1993
+ return { entries, ledgerDirectory: dir, goalsDirectory: goalsDir, unreadableLedgerCount, ledgerDirectoryMissing: false, terminalByTrailingRunStatus, cacheHits, cacheMisses, indexHits, indexOrigin, scope: 'self-implement-run-ledger', note: UNFINISHED_RUN_LEDGER_NOTE };
1855
1994
  }
1856
1995
  const pathFilter = options.path;
1857
1996
  const unknownPathStatus = (entry: UnfinishedRunLedgerEntry): boolean => entry.plannedPathStatus !== 'found-ledger-goal-file'
@@ -1871,6 +2010,8 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
1871
2010
  terminalByTrailingRunStatus,
1872
2011
  cacheHits,
1873
2012
  cacheMisses,
2013
+ indexHits,
2014
+ indexOrigin,
1874
2015
  pathFilter,
1875
2016
  matchingPathCount: matchingEntries.length,
1876
2017
  unknownPathCount: unknownEntries.length,
@@ -1908,6 +2049,8 @@ export interface FederatedUnfinishedRunLedgerQuery {
1908
2049
  reconciledTerminatedElsewhereCount: number;
1909
2050
  cacheHits?: number;
1910
2051
  cacheMisses?: number;
2052
+ /** Hits served by the persisted cross-process scan index (subset of cacheHits). */
2053
+ indexHits?: number;
1911
2054
  pathFilter?: string;
1912
2055
  matchingPathCount?: number;
1913
2056
  unknownPathCount?: number;
@@ -1947,6 +2090,7 @@ export function queryFederatedUnfinishedRunLedgers(options: FederatedUnfinishedR
1947
2090
  let unknownPathCount = 0;
1948
2091
  let cacheHits = 0;
1949
2092
  let cacheMisses = 0;
2093
+ let indexHits = 0;
1950
2094
  const recordDirectoryFailure = (kind: FederatedLedgerDirectoryFailureKind): void => {
1951
2095
  if (kind === 'missing') missingLedgerDirectoryCount += 1;
1952
2096
  else if (kind === 'unreadable') unreadableLedgerDirectoryAccessCount += 1;
@@ -1972,6 +2116,7 @@ export function queryFederatedUnfinishedRunLedgers(options: FederatedUnfinishedR
1972
2116
  unknownPathCount += result.unknownPathCount ?? 0;
1973
2117
  cacheHits += result.cacheHits ?? 0;
1974
2118
  cacheMisses += result.cacheMisses ?? 0;
2119
+ indexHits += result.indexHits ?? 0;
1975
2120
  entries.push(...result.entries.map((entry) => ({ ...entry, ledgerDirectory })));
1976
2121
  } catch (error) {
1977
2122
  recordDirectoryFailure(classifyFederatedLedgerDirectoryReadFailure(error));
@@ -1993,7 +2138,8 @@ export function queryFederatedUnfinishedRunLedgers(options: FederatedUnfinishedR
1993
2138
  for (const runId of unfinishedRunIds) {
1994
2139
  for (const ledgerDirectory of ledgerDirectories) {
1995
2140
  try {
1996
- if (readUnfinishedLedgerFacts(runId, ledgerDirectory, undefined, options.noCache).facts.terminal) { terminatedElsewhere.add(runId); break; }
2141
+ const reconciliationIndex = options.noCache ? undefined : loadRunLedgerScanIndex(ledgerDirectory);
2142
+ if (readUnfinishedLedgerFacts(runId, ledgerDirectory, undefined, options.noCache, reconciliationIndex).facts.terminal) { terminatedElsewhere.add(runId); break; }
1997
2143
  } catch { /* An absent or unreadable sibling cannot establish termination. */ }
1998
2144
  }
1999
2145
  }
@@ -2014,6 +2160,7 @@ export function queryFederatedUnfinishedRunLedgers(options: FederatedUnfinishedR
2014
2160
  reconciledTerminatedElsewhereCount,
2015
2161
  cacheHits,
2016
2162
  cacheMisses,
2163
+ indexHits,
2017
2164
  ...(options.path === undefined ? {} : { pathFilter: options.path, matchingPathCount, unknownPathCount }),
2018
2165
  scope: 'self-implement-run-ledger-federated',
2019
2166
  note: FEDERATED_UNFINISHED_RUN_LEDGER_NOTE,
@@ -15,7 +15,7 @@ import { appendRunLedgerEntry, type RunLedgerEntry, type RunLedgerWriter, type R
15
15
  /** 닫힌 목록 — 못 고르면 `unclassified`. */
16
16
  export const RUN_STOP_CLASSES = [
17
17
  'env-unrelated', 'main-sync', 'pod-died', 'review-repeat',
18
- 'review-out-of-scope', 'evidence-uncovered', 'fabric', 'launch-failed', 'unclassified',
18
+ 'review-out-of-scope', 'evidence-uncovered', 'fabric', 'launch-failed', 'gate-failed', 'unclassified',
19
19
  ] as const;
20
20
  export type RunStopClass = typeof RUN_STOP_CLASSES[number];
21
21
 
@@ -68,8 +68,9 @@ export function classifyMergeHoldStop(mergeReason: string | undefined): RunStopC
68
68
  return 'unclassified';
69
69
  }
70
70
 
71
- /** Pod exit 분류 사유 → 닫힌 목록. */
72
- export function classifyPodExitStop(reason: string | undefined): RunStopClass {
71
+ /** Pod exit 분류 사유 → 닫힌 목록. `stage` 가 호스트 재게이트 실패(`host-regate-failed`)면 `gate-failed`, 인자가 없으면 지금과 똑같이. */
72
+ export function classifyPodExitStop(reason: string | undefined, stage?: string): RunStopClass {
73
+ if (stage === 'host-regate-failed') return 'gate-failed';
73
74
  switch (reason) {
74
75
  case 'pod-failure': case 'pod-error': case 'OOMKilled': case 'ENOBUFS': case 'signal': return 'pod-died';
75
76
  case 'no-launch': return 'launch-failed';