elanous 0.2.40 → 0.2.42

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 (685) hide show
  1. package/README.md +7 -7
  2. package/apps/pwa/out/404/index.html +1 -1
  3. package/apps/pwa/out/404.html +1 -1
  4. package/apps/pwa/out/_next/static/{HjeK7zONHfR7op1hKXp4k → X1ucLw10Cds_h614NoEnh}/_buildManifest.js +1 -1
  5. package/apps/pwa/out/_next/static/chunks/0244e5b5.6fc7670f8223d82d.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/{4769.9fd582071301f382.js → 1063.2fb8a9dc55c731f2.js} +1 -1
  7. package/apps/pwa/out/_next/static/chunks/1121.13ba7a8aff19df81.js +36 -0
  8. package/apps/pwa/out/_next/static/chunks/1147-5196d19c222051b3.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/{470.51a72a2348306455.js → 1262.e804feb8fd1acb8c.js} +2 -2
  10. package/apps/pwa/out/_next/static/chunks/1319.b9b815ae0f181e06.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1345-31427b833438f521.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/{7219-15bdd9a80661af8e.js → 1455-530ca16c7e71baff.js} +1 -1
  13. package/apps/pwa/out/_next/static/chunks/{1281.d81877e35b9068f4.js → 1487.2f67b79444062da6.js} +1 -1
  14. package/apps/pwa/out/_next/static/chunks/1574.878c18ecc97b1bd4.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1586.fafc33a9a5835cb7.js +32 -0
  16. package/apps/pwa/out/_next/static/chunks/1744.855fd60ae4c4a8c8.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/193.21a47a3e07ef6860.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1945.7b54990d578c119b.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/2004.e839fda7ea5a738a.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2044-dd681a5c08779ff8.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2101.2248decb38829b03.js +286 -0
  22. package/apps/pwa/out/_next/static/chunks/2160.a097e7b138ae1c55.js +23 -0
  23. package/apps/pwa/out/_next/static/chunks/2300.41ea70ac1bef1446.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2357-07b5eeb5fb12628d.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2364.28652020695a6db3.js +34 -0
  26. package/apps/pwa/out/_next/static/chunks/{1350.59f40e39e02d91b1.js → 2456.b6de0e1c05f28843.js} +1 -1
  27. package/apps/pwa/out/_next/static/chunks/2526.c3e50ac1fec064bd.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2549-cda50b716ff4250c.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/2550-5f1e88f615568045.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/261-319078c954e40d66.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/2690.0521c738b7749931.js +115 -0
  32. package/apps/pwa/out/_next/static/chunks/{5436.fdf6fa8ae3e9588d.js → 2974.595d1e29d040cb6a.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/{5383.bdfa5d886e39a826.js → 3207.a756c95e9ec8c3c8.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/3285.89ee2f298682f5e5.js +93 -0
  35. package/apps/pwa/out/_next/static/chunks/{2177.df8547f9d7215c4e.js → 3347.f846266b5e5f3ede.js} +3 -3
  36. package/apps/pwa/out/_next/static/chunks/3447.06edc7b092021417.js +41 -0
  37. package/apps/pwa/out/_next/static/chunks/{9184.45afbf44fec87574.js → 3482.a9ae9d2ad6a5bd97.js} +1 -1
  38. package/apps/pwa/out/_next/static/chunks/3507.97e1977bc4d5fb0a.js +2 -0
  39. package/apps/pwa/out/_next/static/chunks/3510-9ca392698bfe4391.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3541.772e5ce425aaa611.js +24 -0
  41. package/apps/pwa/out/_next/static/chunks/{8099.1cccf31c1baa7e1c.js → 3741.9cf76acaa2ee5298.js} +1 -1
  42. package/apps/pwa/out/_next/static/chunks/3837.a210d7d0db8d8abd.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3898-955c896f394217a6.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/3947-ef57acea76eaa8d2.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{4864a2ca.1c1c280a7772c5e5.js → 3d0154af.5331fec737ffe8c3.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/4037-3b82ebc7d78afdc7.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4043.6b91203436c9c86b.js +309 -0
  48. package/apps/pwa/out/_next/static/chunks/405.9022d4a478202b67.js +77 -0
  49. package/apps/pwa/out/_next/static/chunks/417-fb2cc9a9910e5968.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/{3330.7443183b7e6fdbdf.js → 4276.336d76d858fcdf1b.js} +1 -1
  51. package/apps/pwa/out/_next/static/chunks/4302.6ced9aa4535de947.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4320.583cbab64db6be02.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4768-8eac183fd291ca53.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4770.769c9cd9c7034eba.js +148 -0
  55. package/apps/pwa/out/_next/static/chunks/4895.65605ec3e6504e89.js +74 -0
  56. package/apps/pwa/out/_next/static/chunks/{3b355b3d.6f73c98bf6f9c749.js → 50061469.0326382241ef3b2d.js} +1 -1
  57. package/apps/pwa/out/_next/static/chunks/5112.4b9f300124fab7b3.js +149 -0
  58. package/apps/pwa/out/_next/static/chunks/5335.375ee922bcd5bc83.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5342.023a2e729689b320.js +27 -0
  60. package/apps/pwa/out/_next/static/chunks/{8d173e38.18a2f7b4e1848bdb.js → 53c73f84.373b6160adfa89a4.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{1537-6bb97b5214928ea9.js → 5431-72a1dbde59400691.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5440-4236de26c5ea5856.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/5486-b318c165f645d8ba.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5506-c7d2ec25c62a7c94.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/5570-c66ecbea26b4e3b1.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5696.ffca5aa259d8451e.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5793-8c584aea2aa87560.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5848-6de6b8c173351a90.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/5885.0a3e52c8faccec98.js +287 -0
  70. package/apps/pwa/out/_next/static/chunks/5999.94e3c83040200f31.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/5a7901d6-2d8d9b5587cf9042.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/{261.0d471e8aded799f3.js → 6131.348b7d6bdcd267ce.js} +3 -3
  73. package/apps/pwa/out/_next/static/chunks/6164.86133a0172611184.js +90 -0
  74. package/apps/pwa/out/_next/static/chunks/{9175.2de5209a5ce6f68a.js → 6377.bc7df239edbff244.js} +1 -1
  75. package/apps/pwa/out/_next/static/chunks/6515.e07e8b2b8a707a87.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6522-c005514f87d18982.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/{2226.2cf61ec781827219.js → 6632.0eac1c554f8f2ef3.js} +2 -2
  78. package/apps/pwa/out/_next/static/chunks/6642.648adb1767f39ecf.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6848.138805a09d001d09.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/7049-c09e2b7a253a24f3.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7072.1e00447d9fa39972.js +104 -0
  82. package/apps/pwa/out/_next/static/chunks/7106.64201c539c5e220c.js +94 -0
  83. package/apps/pwa/out/_next/static/chunks/7151-1f742b455986530e.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7199.18d6b25e001154ce.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7279-c199ea83f34338fa.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/728b938d.ffaa7ad583d60e58.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7309.171c3de54e0322f1.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/733.7a1ab3342e03306f.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/{b84cad00.594027ebe0531fe2.js → 73d2eb0e.4966ad55293c801a.js} +3 -3
  90. package/apps/pwa/out/_next/static/chunks/{6257.c0037b8949239f5e.js → 7411.9b4b8b747dc7b802.js} +2 -2
  91. package/apps/pwa/out/_next/static/chunks/7504.d5cf1e7cd89b1b08.js +24 -0
  92. package/apps/pwa/out/_next/static/chunks/7573-0fd4af62d65d4598.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/759.6f8267df4689c401.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7825-668b046f72f14483.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7852-1538768b6eb19388.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/7868.cff810430bb63c91.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/{9189505a.980427ac048c8c60.js → 7a98bc80.fa935989e829f9c2.js} +1 -1
  98. package/apps/pwa/out/_next/static/chunks/8084-dfcc796874ab4e07.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/8138.6c10b2a356d52fca.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/{2566.beaffc3a5e1fcd2e.js → 8262.ddc03e06b733f184.js} +1 -1
  101. package/apps/pwa/out/_next/static/chunks/8266.6bf9b131b2584678.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8403.7b81d5e64074a725.js +8 -0
  103. package/apps/pwa/out/_next/static/chunks/8470.1998cbd0866a7eac.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8505.fd803c6c33b54cc3.js +79 -0
  105. package/apps/pwa/out/_next/static/chunks/{8272-025653884f9645d2.js → 8546-6f03f8ea34dd61d9.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/{6051-0ae955eedb10adb9.js → 8673-bab689a55f7e13b9.js} +3 -3
  107. package/apps/pwa/out/_next/static/chunks/8687-246fda8433d3477c.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/898-280022fb082936bc.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9098-50eefc1844212e3d.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/9211-330b6736a63d4cb3.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/{4351.0f37a6db2b34d50b.js → 9249.976f1e69a9d80754.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/9255-cf88fceda5666645.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9306-e523ba58bb8adc42.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/9324.a9866d717ba62cb6.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9325.a8510e8aa87c8143.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9353-12bfff0c130104cf.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9415.69e4a21c60c7d2db.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{6749.0744ce6eb08d40e9.js → 9427.96aa912ddb5801e0.js} +16 -16
  119. package/apps/pwa/out/_next/static/chunks/9479-154a697d4b6e4e98.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9540-65aa6ccc31b3fd78.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{7611.85f045bf232053ac.js → 9633.ce5bddc56784da72.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/{3746-f80a78f220bf37b5.js → 9656-374232558fd528d0.js} +1 -1
  123. package/apps/pwa/out/_next/static/chunks/9832.f4a98c878ecf2c0a.js +62 -0
  124. package/apps/pwa/out/_next/static/chunks/9865.f094440645f02d98.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/9a852a62-6192a6ea9346ced3.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-e772b4710df5d936.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4361368e6a76b967.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-802f349fdd65248d.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/board/page-7f35513988a2a495.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/botlab/page-798121656540e33e.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/bots/page-20a089490affe98c.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/ceo/page-e5e4ec786d70e604.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/chat/page-d12fe5d0801430e4.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/consult/page-d8cf21022fecc026.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/control/page-21ce565c9c57ee97.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/decisions/page-b56563025f619c9b.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/design-check/page-52f14dd133da8348.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/editor/page-c0ed7fdcdba76633.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/exec/page-af8c3020cb520f15.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/field/page-72eda67af9f5e35c.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/healthz/route-e772b4710df5d936.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/inside/page-67a6620d31f0a46f.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/intake/page-f059363aa0880ec2.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/layout-f9f917d6a57f69fb.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/live/page-d3ae55eee2f0826c.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/live-run/{page-83d27757e2b8060a.js → page-0e3d7b9421b79dac.js} +1 -1
  147. package/apps/pwa/out/_next/static/chunks/app/loops/page-ba738f7e233eb211.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/market/page-33438b98c74fd599.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-0b34d5fd990d793a.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/morning/page-0f291d3c8fd55a3a.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/not-found-3fced192be5279c1.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/observatory/page-04cb3cf182a7c1ea.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6ccbd2ab23a21542.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-aa0518c48a5f4e56.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4b32226d341ad7d7.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3224fd8f6383b61f.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/page-efbc97459f2914e2.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2fe487d88cd5d97c.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-48861dd1a858bab7.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/sessions/page-197d5d4d21d228ea.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a763ba89fbdd9c27.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/settings/page-7edb253510b1c136.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0c875702c61965ea.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/setup/layout-e772b4710df5d936.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/setup/page-e425c951151095f7.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/share/page-9c90e0aec4e27f77.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/showroom/page-733e09a02e727d42.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/tasks/page-4f899e14c34d77a1.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/term/{page-139d722de1dcd6c1.js → page-bf067887b3307423.js} +1 -1
  170. package/apps/pwa/out/_next/static/chunks/app/today/page-7af10868ff87d04e.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/trace/page-efe5304057aa11c7.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/vault/page-76bcd29aaa8a26c3.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-4cfd88e2273ce50f.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/workflows/page-0a1ddb47efba0a32.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/app/workspace/page-2a176c707152c892.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-efe03031b8797fbf.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/{409c787b.e48c5bec8ec10456.js → b450776b.3db34d8d965f82d3.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/{ca3702f8.2913182e73889fa2.js → e8543907.5b040a5f22a0b0e5.js} +7 -7
  179. package/apps/pwa/out/_next/static/chunks/framework-d0d2d673bfd8a8a9.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-4c9fceb2baa09cb7.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/main-app-b0ab8d8fc9a97556.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_app-7e2cc62a2e5cec96.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/pages/_error-22324935f753ec5e.js +1 -0
  184. package/apps/pwa/out/_next/static/chunks/webpack-9dc1bfa25334998a.js +1 -0
  185. package/apps/pwa/out/_next/static/css/{b9d8151e48998417.css → 62c858ad53854f47.css} +1 -1
  186. package/apps/pwa/out/approvals/index.html +1 -1
  187. package/apps/pwa/out/approvals/index.txt +22 -22
  188. package/apps/pwa/out/autopilot/index.html +1 -1
  189. package/apps/pwa/out/autopilot/index.txt +22 -22
  190. package/apps/pwa/out/board/index.html +1 -1
  191. package/apps/pwa/out/board/index.txt +22 -22
  192. package/apps/pwa/out/botlab/index.html +1 -1
  193. package/apps/pwa/out/botlab/index.txt +21 -21
  194. package/apps/pwa/out/bots/index.html +1 -1
  195. package/apps/pwa/out/bots/index.txt +21 -21
  196. package/apps/pwa/out/ceo/index.html +1 -1
  197. package/apps/pwa/out/ceo/index.txt +22 -22
  198. package/apps/pwa/out/chat/index.html +1 -1
  199. package/apps/pwa/out/chat/index.txt +21 -21
  200. package/apps/pwa/out/consult/index.html +1 -1
  201. package/apps/pwa/out/consult/index.txt +22 -22
  202. package/apps/pwa/out/control/index.html +1 -1
  203. package/apps/pwa/out/control/index.txt +22 -22
  204. package/apps/pwa/out/decisions/index.html +1 -1
  205. package/apps/pwa/out/decisions/index.txt +21 -21
  206. package/apps/pwa/out/design-check/index.html +1 -1
  207. package/apps/pwa/out/design-check/index.txt +22 -22
  208. package/apps/pwa/out/editor/index.html +1 -1
  209. package/apps/pwa/out/editor/index.txt +23 -24
  210. package/apps/pwa/out/exec/index.html +1 -1
  211. package/apps/pwa/out/exec/index.txt +22 -22
  212. package/apps/pwa/out/field/index.html +1 -1
  213. package/apps/pwa/out/field/index.txt +22 -22
  214. package/apps/pwa/out/healthz +1 -1
  215. package/apps/pwa/out/index.html +1 -1
  216. package/apps/pwa/out/index.txt +21 -21
  217. package/apps/pwa/out/inside/index.html +1 -1
  218. package/apps/pwa/out/inside/index.txt +22 -22
  219. package/apps/pwa/out/intake/index.html +1 -1
  220. package/apps/pwa/out/intake/index.txt +22 -22
  221. package/apps/pwa/out/live/index.html +1 -1
  222. package/apps/pwa/out/live/index.txt +23 -24
  223. package/apps/pwa/out/live-run/index.html +1 -1
  224. package/apps/pwa/out/live-run/index.txt +23 -24
  225. package/apps/pwa/out/loops/index.html +1 -1
  226. package/apps/pwa/out/loops/index.txt +21 -21
  227. package/apps/pwa/out/market/index.html +1 -1
  228. package/apps/pwa/out/market/index.txt +21 -21
  229. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  230. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  231. package/apps/pwa/out/morning/index.html +1 -1
  232. package/apps/pwa/out/morning/index.txt +22 -22
  233. package/apps/pwa/out/observatory/index.html +1 -1
  234. package/apps/pwa/out/observatory/index.txt +22 -22
  235. package/apps/pwa/out/ops/checklist/index.html +1 -1
  236. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  237. package/apps/pwa/out/ops/release/index.html +1 -1
  238. package/apps/pwa/out/ops/release/index.txt +21 -21
  239. package/apps/pwa/out/ops/seats/index.html +1 -1
  240. package/apps/pwa/out/ops/seats/index.txt +21 -21
  241. package/apps/pwa/out/outputs/index.html +1 -1
  242. package/apps/pwa/out/outputs/index.txt +21 -21
  243. package/apps/pwa/out/reflection/index.html +1 -1
  244. package/apps/pwa/out/reflection/index.txt +22 -22
  245. package/apps/pwa/out/scheduler/index.html +1 -1
  246. package/apps/pwa/out/scheduler/index.txt +22 -22
  247. package/apps/pwa/out/sessions/index.html +1 -1
  248. package/apps/pwa/out/sessions/index.txt +21 -21
  249. package/apps/pwa/out/settings/devices/index.html +1 -1
  250. package/apps/pwa/out/settings/devices/index.txt +22 -22
  251. package/apps/pwa/out/settings/index.html +1 -1
  252. package/apps/pwa/out/settings/index.txt +22 -22
  253. package/apps/pwa/out/setup/done/index.html +1 -1
  254. package/apps/pwa/out/setup/done/index.txt +22 -22
  255. package/apps/pwa/out/setup/index.html +1 -1
  256. package/apps/pwa/out/setup/index.txt +22 -22
  257. package/apps/pwa/out/share/index.html +1 -1
  258. package/apps/pwa/out/share/index.txt +22 -22
  259. package/apps/pwa/out/showroom/index.html +1 -1
  260. package/apps/pwa/out/showroom/index.txt +21 -21
  261. package/apps/pwa/out/tasks/index.html +1 -1
  262. package/apps/pwa/out/tasks/index.txt +22 -22
  263. package/apps/pwa/out/term/index.html +1 -1
  264. package/apps/pwa/out/term/index.txt +22 -22
  265. package/apps/pwa/out/today/index.html +1 -1
  266. package/apps/pwa/out/today/index.txt +22 -22
  267. package/apps/pwa/out/trace/index.html +1 -1
  268. package/apps/pwa/out/trace/index.txt +22 -22
  269. package/apps/pwa/out/vault/index.html +1 -1
  270. package/apps/pwa/out/vault/index.txt +22 -22
  271. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  272. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  273. package/apps/pwa/out/workflows/index.html +1 -1
  274. package/apps/pwa/out/workflows/index.txt +22 -22
  275. package/apps/pwa/out/workspace/index.html +1 -1
  276. package/apps/pwa/out/workspace/index.txt +22 -22
  277. package/apps/pwa/out/worktrees/index.html +1 -1
  278. package/apps/pwa/out/worktrees/index.txt +22 -22
  279. package/bin/elanous.mjs +6 -1
  280. package/catalog/models/openai/gpt-6.1-sol.yaml +16 -0
  281. package/catalog/models/openai/gpt-6.1-terra.yaml +16 -0
  282. package/docs/goal-context/04-mock-scenarios.md +13 -0
  283. package/graphs/catalog/catalog.yaml +1 -1
  284. package/graphs/demo/persona-teacher/lesson-pack.yaml +16 -0
  285. package/graphs/demo/persona-teacher/recipes.yaml +17 -0
  286. package/graphs/demo/persona-teacher/weekly-lesson.yaml +36 -0
  287. package/graphs/heal/heal-loop.yaml +1 -0
  288. package/graphs/overlays/stop-heal-ladder.yaml +136 -2
  289. package/graphs/release/release-loop.yaml +3 -1
  290. package/graphs/units/gate/gate.yaml +20 -0
  291. package/graphs/units/git/git.yaml +26 -0
  292. package/graphs/units/implement/implement.yaml +19 -0
  293. package/graphs/units/landing/landing.yaml +18 -0
  294. package/graphs/units/review/review.yaml +20 -0
  295. package/graphs/units/verbs/recipes.yaml +13 -10
  296. package/graphs/units/verbs/research.yaml +20 -0
  297. package/graphs/work/research-report.yaml +21 -3
  298. package/package.json +1 -1
  299. package/scripts/disk-steward.ts +46 -0
  300. package/scripts/fleet/node-setup.sh +50 -0
  301. package/scripts/graph-units/verbs/research.ts +55 -0
  302. package/scripts/heal/run-role.ts +99 -5
  303. package/scripts/land-global-checks.ts +6 -1
  304. package/scripts/lib/decompose-ab.ts +1 -0
  305. package/scripts/lib/fixtures/tui-regress/help-insufficient-commands.txt +15 -0
  306. package/scripts/lib/fixtures/tui-regress/help-live.txt +42 -0
  307. package/scripts/lib/fixtures/tui-regress/help-missing-keys.txt +21 -0
  308. package/scripts/lib/fixtures/tui-regress/help-original.txt +51 -0
  309. package/scripts/lib/fixtures/tui-regress/help-shifted-input.txt +26 -0
  310. package/scripts/lib/tui-regress-checks.ts +33 -13
  311. package/scripts/llm-cost-ledger.ts +179 -8
  312. package/scripts/measure-nl-routing-corpus.ts +10 -2
  313. package/scripts/persona-teacher/weekly-lesson-node.ts +172 -0
  314. package/scripts/public-copy-lint.ts +163 -19
  315. package/scripts/ratchets/train-side-invariants.sh +0 -1
  316. package/scripts/release-loop/gate-autoheal.ts +117 -0
  317. package/scripts/release-loop/gate-baseline-receipt.ts +55 -10
  318. package/scripts/release-loop/gate-diff.ts +22 -3
  319. package/scripts/release-loop/gate-image-pin.ts +81 -0
  320. package/scripts/release-loop/gate-node-sim.ts +207 -0
  321. package/scripts/release-loop/gate-node.ts +489 -62
  322. package/scripts/release-loop/gate-pod-image-sticky-plan.ts +99 -0
  323. package/scripts/release-loop/gate-radius-live.ts +97 -13
  324. package/scripts/release-loop/gate-shard-dispatch.ts +43 -0
  325. package/scripts/release-loop/gate-shard-load-flaky.ts +256 -0
  326. package/scripts/release-loop/gate-train-receipts.ts +122 -0
  327. package/scripts/release-loop/gate-triage-node.ts +70 -10
  328. package/scripts/release-loop/resume-release.ts +330 -23
  329. package/scripts/release-loop/traffic-node.ts +6 -3
  330. package/scripts/release-loop/unattended-release.ts +4 -2
  331. package/scripts/shadow-authoring-probe.ts +20 -0
  332. package/scripts/ux-sim.ts +37 -3
  333. package/scripts/warm-pool-provider-config.ts +263 -0
  334. package/skills/omni-crawl/SKILL.md +5 -2
  335. package/skills/omni-crawl/scripts/main.ts +84 -23
  336. package/src/acp/core-turn-bridge.ts +99 -4
  337. package/src/agent/registry.ts +2 -0
  338. package/src/agent/task-notification.ts +25 -5
  339. package/src/agent/types.ts +6 -0
  340. package/src/agent-mission/mission-cli.ts +24 -0
  341. package/src/agent-mission/mission-out.ts +595 -0
  342. package/src/agent-mission/tool-install.ts +88 -2
  343. package/src/agent-substrate/context-strategy.ts +4 -4
  344. package/src/agent-substrate/self-review-cli.ts +267 -40
  345. package/src/auto-research/research-turn.ts +133 -51
  346. package/src/autopilot/discovery/wiki-claim-proposer.ts +22 -1
  347. package/src/autopilot/pr-manager.ts +38 -7
  348. package/src/autopilot/pty-control-loop.ts +2 -0
  349. package/src/boot/daemon-tools/self-implement.ts +46 -9
  350. package/src/budget/shadow-arms.ts +52 -0
  351. package/src/capture/tui-self-report.ts +22 -6
  352. package/src/chat/index.ts +1 -1
  353. package/src/chat/pickers/state.ts +7 -1
  354. package/src/cli/fixtures/review-loop-breaker/opwaiver-32646-1694ccc7a170.json +1 -0
  355. package/src/cli/fixtures/review-loop-breaker/opwaiver-32853-bd8f73595c83.json +1 -0
  356. package/src/cli/fixtures/review-loop-breaker/opwaiver-33097-1cc85900413c.json +1 -0
  357. package/src/cli/fixtures/review-loop-breaker/opwaiver-33106-972f31e4a3ca.json +1 -0
  358. package/src/cli/fixtures/review-loop-breaker/opwaiver-33113-3ab51f05968f.json +1 -0
  359. package/src/cli/fixtures/review-loop-breaker/pr-33097-1cc85900413c.json +1 -0
  360. package/src/cli/log-event-names.ts +5 -0
  361. package/src/cli/mcp-login.ts +8 -18
  362. package/src/cli/msg-cli.ts +57 -1
  363. package/src/cli/pr-land-heavy-remote.ts +47 -9
  364. package/src/cli/pr-land-overlap-evidence.ts +100 -1
  365. package/src/cli/pr-land-pod-shadow-job.ts +60 -0
  366. package/src/cli/release-checklist-read-cli.ts +20 -10
  367. package/src/cli/release-cli.ts +27 -1
  368. package/src/cli/research-cli.ts +4 -5
  369. package/src/cli/sim-cli.ts +7 -1
  370. package/src/cli/tasks-cli.ts +12 -4
  371. package/src/codex/models.ts +30 -15
  372. package/src/compact/auto.ts +8 -1
  373. package/src/control-plane/ledger.ts +52 -2
  374. package/src/control-plane/server.ts +16 -2
  375. package/src/core-turn/run-core-turn.ts +313 -89
  376. package/src/core-turn/run-goal-loop.ts +106 -2
  377. package/src/core-turn/types.ts +2 -0
  378. package/src/dashboard/acp-boot.ts +72 -3
  379. package/src/dashboard/classic-sidetab-mission-job.ts +58 -0
  380. package/src/dashboard/classic-sidetab-mission.ts +185 -0
  381. package/src/dashboard/index.ts +155 -15
  382. package/src/dashboard/input/agent-wake.ts +23 -1
  383. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +9 -0
  384. package/src/dashboard/mission-cli-consumer.ts +153 -0
  385. package/src/dashboard/seat-boot-preamble.ts +171 -1
  386. package/src/dashboard/side-basic-runtime.ts +54 -1
  387. package/src/dashboard/sidetab-runtime.ts +90 -1
  388. package/src/dashboard/skill-catalog-preamble.ts +101 -0
  389. package/src/dashboard/skill-detection-runtime.ts +55 -15
  390. package/src/dashboard/slash-runtime/dashboard-handlers.ts +15 -0
  391. package/src/dashboard/turn-preamble.ts +65 -16
  392. package/src/dashboard/turn-prompt-runtime.ts +4 -2
  393. package/src/disk-steward/judge.ts +73 -0
  394. package/src/disk-steward/ledger.ts +122 -0
  395. package/src/disk-steward/steward.ts +373 -0
  396. package/src/domains/guardian-tick.ts +191 -2
  397. package/src/graph-runner/graph-cli.ts +44 -7
  398. package/src/graph-runner/graph-tick.ts +10 -2
  399. package/src/graph-runner/in-process-registry.ts +37 -0
  400. package/src/graph-runner/runner.ts +34 -4
  401. package/src/grok/agent-search.ts +14 -4
  402. package/src/grok/credential.ts +28 -11
  403. package/src/grounding/ref-index.ts +19 -0
  404. package/src/grounding/sources-cli.ts +9 -1
  405. package/src/harness/harness-cli-command.ts +267 -14
  406. package/src/harness/harness-incidents.ts +312 -7
  407. package/src/harness/harness-pod-dispatch.ts +81 -15
  408. package/src/harness/harness-space.ts +15 -1
  409. package/src/harness/harness-stop.ts +155 -11
  410. package/src/harness/progress-worker-entry.ts +59 -0
  411. package/src/harness/progress-worker-runtime.ts +11 -0
  412. package/src/index.ts +52 -7
  413. package/src/instance/dev-project.ts +25 -0
  414. package/src/instance/spawn-elanous.ts +6 -4
  415. package/src/intelligence-map/model-alias.ts +6 -5
  416. package/src/intelligence-map/model-catalog.ts +59 -2
  417. package/src/llm/model-defaults.ts +4 -4
  418. package/src/llm.ts +208 -19
  419. package/src/loops/orchestrator/coordinator-shadow.ts +226 -0
  420. package/src/loops/orchestrator/tick.ts +61 -0
  421. package/src/maturity/feature-maturity.ts +1 -1
  422. package/src/mcp/mcp-oauth.ts +3 -1
  423. package/src/model-tier/llm-tier-map.ts +9 -9
  424. package/src/model-tier/turn-tier.ts +1 -1
  425. package/src/msg/msg-mirror-github.ts +80 -0
  426. package/src/msg/msg-mirror-policy.ts +61 -0
  427. package/src/msg/msg-mirror-runner.ts +219 -0
  428. package/src/msg/msg-mirror-state.ts +33 -0
  429. package/src/msg/msg-store.ts +11 -0
  430. package/src/native-tool-catalog.ts +2 -2
  431. package/src/nexus/api/harness-traversal.ts +11 -0
  432. package/src/output-truncation.ts +41 -12
  433. package/src/pr-tool/census.ts +3 -2
  434. package/src/project/project-store.ts +48 -1
  435. package/src/pty-shell/tui-run-state.ts +188 -2
  436. package/src/release-loop/checklist-target-path-hint.ts +13 -0
  437. package/src/release-loop/checklist.ts +9 -1
  438. package/src/release-loop/gate-host-reservation.ts +144 -0
  439. package/src/release-loop/release-schedule.ts +90 -1
  440. package/src/repl/index.ts +43 -2
  441. package/src/research/axis-fanout.ts +121 -16
  442. package/src/research/bloom-exemplars.ts +137 -0
  443. package/src/research/gap-followup.ts +13 -1
  444. package/src/research/plugin-discovery.ts +36 -14
  445. package/src/research-bridge/invoke.ts +22 -5
  446. package/src/research-bridge/types.ts +2 -0
  447. package/src/self-dev/ask-launch-flow.ts +39 -25
  448. package/src/self-dev/decompose.ts +119 -5
  449. package/src/self-dev/dev-cli.ts +17 -17
  450. package/src/self-dev/graph-front-nodes.ts +23 -0
  451. package/src/self-dev/launch-preflight-text.ts +5 -6
  452. package/src/self-dev/launch-preflight.ts +9 -4
  453. package/src/self-dev/orchestrate.ts +27 -2
  454. package/src/self-dev/review-provider-fallback.ts +9 -2
  455. package/src/self-dev/run-supervisor.ts +226 -6
  456. package/src/self-dev/run-types.ts +7 -0
  457. package/src/self-implement/doctor-visit.ts +88 -0
  458. package/src/self-implement/gate-artifacts.ts +13 -0
  459. package/src/self-implement/gate-cli.ts +54 -24
  460. package/src/self-implement/gate-remote.ts +23 -5
  461. package/src/self-implement/goal-author-clarification.ts +31 -12
  462. package/src/self-implement/goal-author.ts +403 -8
  463. package/src/self-implement/graph-overlay-yaml.ts +7 -0
  464. package/src/self-implement/graph-stage-units.ts +172 -0
  465. package/src/self-implement/graph-templates.ts +162 -1
  466. package/src/self-implement/graph-variant.ts +37 -4
  467. package/src/self-implement/headless-elanous-driver.ts +31 -2
  468. package/src/self-implement/heal-intake.ts +112 -4
  469. package/src/self-implement/heal-triage.ts +20 -0
  470. package/src/self-implement/host-regate.ts +31 -8
  471. package/src/self-implement/knowhow-pack.ts +38 -0
  472. package/src/self-implement/merge-train.ts +5 -0
  473. package/src/self-implement/orchestrator.ts +359 -30
  474. package/src/self-implement/regate-detail.ts +38 -1
  475. package/src/self-implement/rework-child-provider.ts +25 -0
  476. package/src/self-implement/run-chart.ts +119 -0
  477. package/src/self-implement/run-ledger.ts +176 -17
  478. package/src/self-implement/run-stop.ts +208 -5
  479. package/src/self-implement/running-runs.ts +35 -12
  480. package/src/self-implement/self-implement-cli.ts +36 -4
  481. package/src/self-implement/stop-autoheal-operational.ts +43 -0
  482. package/src/self-implement/stop-autoheal.ts +28 -6
  483. package/src/session/chat.ts +69 -58
  484. package/src/session/request-size-guard.ts +123 -0
  485. package/src/session-runtime/index.ts +98 -4
  486. package/src/session-runtime/tier-flip.ts +3 -3
  487. package/src/sidetab-core/model.ts +150 -0
  488. package/src/sidetab-core/visible-agent-mission.ts +186 -0
  489. package/src/skills/name-match.ts +20 -0
  490. package/src/skills/tools/agent.ts +30 -2
  491. package/src/skills/tools/omni-search.ts +67 -5
  492. package/src/task-agent/parent-host.ts +14 -1
  493. package/src/task-agent/pod-distributor-entry.ts +3 -0
  494. package/src/task-agent/task-hand.ts +31 -1
  495. package/src/task-orchestrator/surfaces/pod-distributor.ts +48 -0
  496. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +43 -0
  497. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +38 -1
  498. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +29 -4
  499. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +33 -6
  500. package/src/task-orchestrator/surfaces/pod-source-bundle.ts +45 -9
  501. package/src/task-orchestrator/surfaces/pod-source-receive.ts +163 -13
  502. package/src/task-orchestrator/surfaces/pod-source-spec.ts +3 -3
  503. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +209 -39
  504. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +80 -3
  505. package/src/task-orchestrator/surfaces/self-implement-pod.ts +280 -60
  506. package/src/task-orchestrator/surfaces/self-implement.ts +18 -0
  507. package/src/tokens.ts +35 -2
  508. package/src/tool-runtime/agent-runtime.ts +1 -0
  509. package/src/tool-runtime/elanous-skills-list-runtime.ts +5 -1
  510. package/src/tool-runtime/skill-exec-runtime.ts +33 -13
  511. package/src/tool-runtime/types.ts +1 -0
  512. package/src/tui/entry.ts +24 -7
  513. package/src/tui/sidetab/attach.ts +47 -0
  514. package/src/tui/sidetab/list.ts +45 -0
  515. package/src/tui/sidetab/nl-tool.ts +2 -136
  516. package/src/tui/sidetab/peek.ts +52 -0
  517. package/src/tui-client/dashboard-session.ts +3 -0
  518. package/src/tui-client/local-chat-turn.ts +26 -13
  519. package/src/tui.ts +22 -0
  520. package/src/user-config.ts +11 -5
  521. package/src/ux-sim/fake-kubectl.ts +37 -3
  522. package/src/ux-sim/fault-needs-human-reason-repair.ts +107 -0
  523. package/src/ux-sim/fault-pod-child-result.ts +42 -0
  524. package/src/ux-sim/fault-pool-cap.ts +11 -6
  525. package/src/ux-sim/mock-scenario-catalog.json +41 -0
  526. package/src/ux-sim/mock-scenario-catalog.ts +156 -0
  527. package/src/ux-sim/release-sim-rig.ts +262 -0
  528. package/src/ux-sim/scenario.ts +116 -23
  529. package/src/ux-sim/seminar-rehearsal.ts +109 -0
  530. package/src/ux-sim/subagent-tools-device.ts +2 -2
  531. package/src/version/packed-revision.json +1 -1
  532. package/src/voice/voice-tts-singleton.ts +18 -3
  533. package/src/web-search/grok.ts +5 -9
  534. package/apps/pwa/out/_next/static/chunks/1060.014f1f01a17aec26.js +0 -115
  535. package/apps/pwa/out/_next/static/chunks/1415.79821ec7ae99acdb.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/1452.162bb2d9d699e82a.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/147.f92f63bbc5e85fa5.js +0 -286
  538. package/apps/pwa/out/_next/static/chunks/1661.fb425a1d8a065b72.js +0 -149
  539. package/apps/pwa/out/_next/static/chunks/1671-1c22b40b50b208f2.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/1758.0204d3f48783c49d.js +0 -90
  541. package/apps/pwa/out/_next/static/chunks/1806.027bf78b6a94d340.js +0 -104
  542. package/apps/pwa/out/_next/static/chunks/2047.8f23e210995d4548.js +0 -2
  543. package/apps/pwa/out/_next/static/chunks/2061-7f2bbc53ae96c88b.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/2066.a77257c8c350770a.js +0 -23
  545. package/apps/pwa/out/_next/static/chunks/2096-a938496bc996dcbd.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/2200-9a453b8f99687d49.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/2281-b8cede695c6c650e.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/2499.02fbfd18126c10c0.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/2522.f2766b76d22c8bdf.js +0 -34
  550. package/apps/pwa/out/_next/static/chunks/2615.3c9738153de3ef3f.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/2727.e703d99ac414916d.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/2752.7904b8df0254d0ae.js +0 -27
  553. package/apps/pwa/out/_next/static/chunks/2762-5051a862dfa40e99.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/2767-31784bfedf8e245d.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/2774-719820e3f5b2a3eb.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/2812-f016aa0dda149287.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/2829-734fe8bf2eee7347.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/311-32dcac79970985e8.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/3175-f93f7495cd28253c.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/3184.8da993f5502d2140.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/3231-d7c981db0ff8bdcc.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/3250.151309c5176d6b4b.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/3517.a5aa1797a9dbf2ee.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/3567-45f676877ed9e8a5.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/3819.8a1de79b2e8c7298.js +0 -24
  566. package/apps/pwa/out/_next/static/chunks/39.9b37b0be4c128a83.js +0 -77
  567. package/apps/pwa/out/_next/static/chunks/4023.a19045970a9ce16a.js +0 -36
  568. package/apps/pwa/out/_next/static/chunks/413-24c8284bda08241d.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/4135.e45d6ebc29e20647.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/4283.65502f5d0e6ff6c0.js +0 -287
  571. package/apps/pwa/out/_next/static/chunks/4305-4e28fa92a7b34a5b.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/4335-50efa61fd7613142.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/4720.ecbd1693fa151068.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/483.725e4a61be922788.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/4969-4b209d7307410c00.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/5068-c7f53862f83c0917.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/5315.bc96711c24dfefe2.js +0 -74
  578. package/apps/pwa/out/_next/static/chunks/5542.efbf14f16baed4dd.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/5622.94893f5aea7185d0.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/5644.8f401a25601d05fc.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/5658.35f70eb9871a54bf.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/5721.7bdc0e904c76ab51.js +0 -8
  583. package/apps/pwa/out/_next/static/chunks/5790-eef0ca20884a6bdf.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/5802.ef0d8598ca68fe84.js +0 -62
  585. package/apps/pwa/out/_next/static/chunks/5890.fb974729788dcb71.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/5924.5ef25cddd36d5dbf.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/5979-e59c099ebf8d1f35.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/6020.714cfeada2315e2e.js +0 -94
  589. package/apps/pwa/out/_next/static/chunks/6027-dfe0349d8c50f698.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/6178.bc4730c86cf74536.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/6273.d808b0dcb3c2b155.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/6292.6ef1df64fa6a4c8a.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/647-af8dd920ba46533c.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/6541-170dc5c59e135c0c.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/6624.981ef7caeb680560.js +0 -32
  596. package/apps/pwa/out/_next/static/chunks/6742-a1ad4a94ba7bc37a.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/6836-493dc55c39187949.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/6856-53ac421c06039a18.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/6908.06008c67f6380ea9.js +0 -148
  600. package/apps/pwa/out/_next/static/chunks/6915.096931864206f522.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/6925.5e181fb7dcf90193.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/6cc1d1d6.9a98dd4622f1afc6.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/7203-800e11037adc41eb.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/7279.6170f591105936bb.js +0 -93
  605. package/apps/pwa/out/_next/static/chunks/7349-373165c7fbdcc3df.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/7514-a533ba0ca1cae4f4.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/7515.1ad6efe157fa4448.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/7521.d919cc1fab80c1d9.js +0 -24
  609. package/apps/pwa/out/_next/static/chunks/7538.90e97bbdf9178cff.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/7825-39203196a12579b2.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/7869.5e1a9a12fd70d6c7.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/8086.1ab9103c41be884f.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/8179-e61fffbdb70f1152.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/8265.bdeb991b34db6a06.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/8357.1aaa713b052a78b1.js +0 -309
  616. package/apps/pwa/out/_next/static/chunks/8638-e42615f2166165b5.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/8639-92c11d069792429e.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/8691.54e22831d5e8ccf8.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/9069.657590a84afb8fac.js +0 -41
  620. package/apps/pwa/out/_next/static/chunks/9125-ae588d88a0293b93.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/9311.f9f641a46a508611.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/9371-a6fee8378ebfa3ee.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/9421-3aa9ff4fa7f63d8a.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/9992.07ce73c10bd5e6a1.js +0 -79
  625. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76394dc618d322c8.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/app/approvals/page-1b948637c37b3abd.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-c63400f1bcf3e47c.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/app/board/page-95d0957267819586.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ba957ff875a026a0.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/app/bots/page-bb6fd0714879cb87.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/app/ceo/page-8f9038520d2acbef.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/app/chat/page-d4b48397e05fce2c.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/app/consult/page-72d5744245dc0c27.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/app/control/page-37625dc8300fa43a.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/app/decisions/page-fbef9d160272dbc1.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/app/design-check/page-58424168df84928e.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/app/editor/page-72c12ba430ac57c0.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/app/exec/page-d53f3e9ed806d7e0.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/app/field/page-4d2fbd45feee0829.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/app/healthz/route-76394dc618d322c8.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/app/inside/page-8783dc0ed7590a2c.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/app/intake/page-3706cb390606e930.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/app/layout-9b0a86598e0111fd.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/app/live/page-4edb8df90f4537ce.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/app/loops/page-47398b9ba1cc5e1b.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/app/market/page-fb86f55cfe2e681d.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e22345fc8fd47b1b.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/app/morning/page-fca2e59a81744d9e.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/not-found-6e96bda63100b31e.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/observatory/page-4d17ad8e0db8cea4.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-121f92766c33beaa.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-43f14212c545f92d.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ccec2023e7a974ec.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/outputs/page-b04f33f548b89a94.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/page-c8792823c0917021.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/reflection/page-8c0e32782ceef4cb.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-94bd3922eb230ce8.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/sessions/page-bca565887bafa03c.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ac1dffafe649fc6c.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/settings/page-52374edb5e23e455.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ad4ebca120d43ca7.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/setup/layout-76394dc618d322c8.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/setup/page-718b89ce4b4ae4e4.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/share/page-204eca33eeeaddec.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/showroom/page-e58ba9bcdb9ac0f9.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/tasks/page-98f6dd50bafd7734.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/today/page-5a4bdd72bff27057.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/trace/page-6f6ab17d44f984ce.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/vault/page-aabb7bd15fb72da9.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-e4322319164a4436.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/workflows/page-e9efc0c8f32e2371.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/workspace/page-ccde99f07aaf71f7.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-80464aced9614390.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/c696986b.5dc8bb1143af16d1.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/d5d3cefc-373c4eb722ed848b.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/d8de0de2-dd0f4ac8e5ab1832.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/framework-002b472a66935d31.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/main-49b88d47292c0476.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/main-app-fff2549cb10a133f.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/pages/_app-32abbbba3f3b76b7.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/pages/_error-9d9cfef60c60dd7a.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/webpack-cc7f483fa294034a.js +0 -1
  683. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +0 -1
  684. package/scripts/ratchets/next-tui-entry-budget.ts +0 -124
  685. /package/apps/pwa/out/_next/static/{HjeK7zONHfR7op1hKXp4k → X1ucLw10Cds_h614NoEnh}/_ssgManifest.js +0 -0
@@ -38,6 +38,21 @@ export function parseConflictFiles(text: string): string[] {
38
38
 
39
39
  export type MergeFailureKind = 'base-modified' | 'head-moved' | 'conflict' | 'branch-policy' | 'other';
40
40
 
41
+ export const HOST_REGATE_PR_HEAD_FAILURE_CONDITIONS = [
42
+ 'head-unavailable', 'head-mismatch', 'state-unavailable', 'state-not-open',
43
+ 'draft-status-unavailable', 'pr-is-draft', 'base-name-unavailable', 'base-oid-invalid',
44
+ ] as const;
45
+ export type HostRegatePrHeadFailureCondition = typeof HOST_REGATE_PR_HEAD_FAILURE_CONDITIONS[number];
46
+
47
+ export interface HostRegatePrHeadSnapshot {
48
+ headRefOid: string | null;
49
+ state: 'OPEN' | 'CLOSED' | 'MERGED' | 'OTHER' | null;
50
+ isDraft: boolean | null;
51
+ /** The only raw ref retained is the conventional base; all other non-empty values collapse to `other`. */
52
+ baseRefName: 'main' | 'other' | null;
53
+ baseRefOid: string | null;
54
+ }
55
+
41
56
  /** Classify a `gh pr merge` failure so a reader can tell a race from a conflict from a policy block without the raw text. */
42
57
  export function classifyMergeFailure(detail: string, expectedHead?: string, actualHead?: string | null): MergeFailureKind {
43
58
  if (/base branch was modified/i.test(detail)) return 'base-modified';
@@ -48,12 +63,16 @@ export function classifyMergeFailure(detail: string, expectedHead?: string, actu
48
63
  return 'other';
49
64
  }
50
65
 
51
- /** One host-regate failure. The optional facts are filled for the pr-head, merge-conflict and merge steps. */
66
+ /** One host-regate failure. The optional facts are filled for PR-head, merge-conflict and merge steps. */
52
67
  export interface HostRegateFailure {
53
68
  step: string;
54
69
  detail: string;
55
70
  expectedHead?: string;
56
71
  actualHead?: string | null;
72
+ /** Discrete clauses that failed the initial PR-head readiness check. */
73
+ failedConditions?: HostRegatePrHeadFailureCondition[];
74
+ /** Bounded structured facts from the same `gh pr view` used for the check. */
75
+ prHeadSnapshot?: HostRegatePrHeadSnapshot;
57
76
  conflictFiles?: string[];
58
77
  /** Number omitted from conflictFiles when the ledger's 200-path bound is reached. */
59
78
  conflictFilesOmitted?: number;
@@ -66,12 +85,30 @@ export function regateFailureFacts(failure: unknown): Omit<HostRegateFailure, 's
66
85
  const f = failure as Record<string, unknown>;
67
86
  const sha = (value: unknown): value is string => typeof value === 'string' && /^[0-9a-f]{40}$/i.test(value);
68
87
  const kinds: readonly MergeFailureKind[] = ['base-modified', 'head-moved', 'conflict', 'branch-policy', 'other'];
88
+ const headConditions: readonly HostRegatePrHeadFailureCondition[] = HOST_REGATE_PR_HEAD_FAILURE_CONDITIONS;
69
89
  const conflictFiles = Array.isArray(f.conflictFiles) ? f.conflictFiles.filter((p): p is string => typeof p === 'string') : undefined;
70
90
  const priorOmitted = Number.isSafeInteger(f.conflictFilesOmitted) && (f.conflictFilesOmitted as number) > 0 ? f.conflictFilesOmitted as number : 0;
71
91
  const conflictFilesOmitted = Math.max(0, (conflictFiles?.length ?? 0) - 200) + priorOmitted;
92
+ const failedConditions = Array.isArray(f.failedConditions)
93
+ ? [...new Set(f.failedConditions.filter((condition): condition is HostRegatePrHeadFailureCondition => typeof condition === 'string' && headConditions.includes(condition as HostRegatePrHeadFailureCondition)))].sort()
94
+ : undefined;
95
+ const snapshot = f.prHeadSnapshot && typeof f.prHeadSnapshot === 'object' ? f.prHeadSnapshot as Record<string, unknown> : undefined;
96
+ const states = ['OPEN', 'CLOSED', 'MERGED', 'OTHER'] as const;
97
+ const prHeadSnapshot = snapshot
98
+ && (sha(snapshot.headRefOid) || snapshot.headRefOid === null)
99
+ && ((typeof snapshot.state === 'string' && states.includes(snapshot.state as typeof states[number])) || snapshot.state === null)
100
+ && (typeof snapshot.isDraft === 'boolean' || snapshot.isDraft === null)
101
+ && ((snapshot.baseRefName === 'main' || snapshot.baseRefName === 'other') || snapshot.baseRefName === null)
102
+ && (sha(snapshot.baseRefOid) || snapshot.baseRefOid === null)
103
+ ? { headRefOid: snapshot.headRefOid as string | null, state: snapshot.state as HostRegatePrHeadSnapshot['state'],
104
+ isDraft: snapshot.isDraft as boolean | null, baseRefName: snapshot.baseRefName as HostRegatePrHeadSnapshot['baseRefName'],
105
+ baseRefOid: snapshot.baseRefOid as string | null }
106
+ : undefined;
72
107
  return {
73
108
  ...(sha(f.expectedHead) ? { expectedHead: f.expectedHead } : {}),
74
109
  ...(sha(f.actualHead) || f.actualHead === null ? { actualHead: f.actualHead as string | null } : {}),
110
+ ...(failedConditions?.length ? { failedConditions } : {}),
111
+ ...(prHeadSnapshot ? { prHeadSnapshot } : {}),
75
112
  ...(conflictFiles ? { conflictFiles: conflictFiles.slice(0, 200) } : {}),
76
113
  ...(conflictFilesOmitted > 0 ? { conflictFilesOmitted } : {}),
77
114
  ...(typeof f.mergeFailureKind === 'string' && kinds.includes(f.mergeFailureKind as MergeFailureKind) ? { mergeFailureKind: f.mergeFailureKind as MergeFailureKind } : {}),
@@ -0,0 +1,25 @@
1
+ import type { ChildLlmSelection } from '../agent/run-context.js';
2
+
3
+ export type ProviderAvailability = 'available' | 'unavailable' | 'unknown';
4
+ export type ReworkChildProviderDecision =
5
+ | { action: 'keep'; selection: ChildLlmSelection; reason: 'not-grok' | 'quota-unknown' | 'quota-usable' | 'no-alternate' }
6
+ | { action: 'reselect'; selection: ChildLlmSelection; previous: ChildLlmSelection; reason: 'grok-quota-exhausted' | 'grok-credential-missing' };
7
+
8
+ /** Re-evaluate Grok immediately before a supervisor rework relaunch; unknown quota is never treated as exhaustion. */
9
+ export function reselectChildForRework(input: {
10
+ current: ChildLlmSelection;
11
+ grokQuota: 'usable' | 'exhausted' | 'unknown';
12
+ grokCredential: ProviderAvailability;
13
+ alternate?: ChildLlmSelection;
14
+ alternateCredential: ProviderAvailability;
15
+ alternateQuotaExhausted?: boolean;
16
+ }): ReworkChildProviderDecision {
17
+ if (input.current.provider !== 'grok') return { action: 'keep', selection: input.current, reason: 'not-grok' };
18
+ const reason = input.grokQuota === 'exhausted' ? 'grok-quota-exhausted'
19
+ : input.grokCredential === 'unavailable' ? 'grok-credential-missing' : undefined;
20
+ if (!reason) return { action: 'keep', selection: input.current, reason: input.grokQuota === 'unknown' ? 'quota-unknown' : 'quota-usable' };
21
+ if (!input.alternate || input.alternateCredential !== 'available' || input.alternateQuotaExhausted === true) {
22
+ return { action: 'keep', selection: input.current, reason: 'no-alternate' };
23
+ }
24
+ return { action: 'reselect', selection: input.alternate, previous: input.current, reason };
25
+ }
@@ -0,0 +1,119 @@
1
+ import { debug } from '../debug/log.js';
2
+ import { appendRunLedgerEntryChecked, loadRunLedger, type RunLedgerEntry } from './run-ledger.js';
3
+
4
+ export const RUN_DOCTOR_HANDOFF_WAIT_THRESHOLD = 3;
5
+ export const RUN_DOCTOR_HANDOFF_INPUT_PREFIX = '[run-chart handoff=doctor]';
6
+ export const RUN_CHART_MAX_CELLS = 20;
7
+ export const RUN_CHART_READ_CELLS = 5;
8
+ export type RunChartDevice = 'run-supervisor' | 'macrophage' | 'run-doctor' | 'outer-supervisor';
9
+ export interface RunChartCell {
10
+ runId: string; device: RunChartDevice | 'summary'; stopKey: string; observed: string; verdict: string; action: string;
11
+ handoff: string | null; why: string; readStopKeys: string[]; waitCount?: number; failureClass?: string;
12
+ }
13
+ export interface RunChartDecision extends Omit<RunChartCell, 'device'> { device: RunChartDevice; dir: string }
14
+ export type RunChartWriteResult = 'recorded' | 'already-recorded' | 'conflicting-verdict' | 'missing-ledger' | 'ledger-write-refused';
15
+
16
+ function chartEvents(entries: readonly RunLedgerEntry[]): RunLedgerEntry[] {
17
+ const all = entries.filter((e) => e.event === 'run-chart-cell');
18
+ const compactedAt = all.reduce((last, entry, index) => entry.data.compacted ? index : last, -1);
19
+ if (compactedAt < 0) return all;
20
+ const compacted = all[compactedAt]!;
21
+ const summaryData = compacted.data.compacted as Record<string, unknown>;
22
+ const cutoff = typeof summaryData.lastStopKey === 'string' ? summaryData.lastStopKey : '';
23
+ const cutoffDevice = typeof summaryData.lastDevice === 'string' ? summaryData.lastDevice : '';
24
+ const cutoffAt = all.findIndex((e) => e.data.device === cutoffDevice && e.data.stopKey === cutoff);
25
+ const summary: RunLedgerEntry = { ...compacted, data: { device: 'summary', stopKey: `summary:${String(compacted.data.stopKey)}`,
26
+ observed: `${String(summaryData.count)} earlier chart cells folded`, verdict: 'summary',
27
+ action: 'compact', handoff: null, why: String(summaryData.verdicts ?? ''), readStopKeys: [] } };
28
+ return [summary, ...all.slice(cutoffAt >= 0 ? cutoffAt + 1 : compactedAt)];
29
+ }
30
+
31
+ function toChartCell(runId: string, e: RunLedgerEntry): RunChartCell {
32
+ return {
33
+ runId, device: e.data.device as RunChartDevice | 'summary', stopKey: String(e.data.stopKey ?? ''),
34
+ observed: String(e.data.observed ?? ''), verdict: String(e.data.verdict ?? ''), action: String(e.data.action ?? ''),
35
+ handoff: typeof e.data.handoff === 'string' ? e.data.handoff : null, why: String(e.data.why ?? ''),
36
+ readStopKeys: Array.isArray(e.data.readStopKeys) ? e.data.readStopKeys.filter((x): x is string => typeof x === 'string') : [],
37
+ ...(typeof e.data.waitCount === 'number' ? { waitCount: e.data.waitCount } : {}),
38
+ ...(typeof e.data.failureClass === 'string' ? { failureClass: e.data.failureClass } : {}),
39
+ };
40
+ }
41
+
42
+ export function projectRunChart(runId: string, dir: string): RunChartCell[] {
43
+ return chartEvents(loadRunLedger(runId, dir) ?? []).map((entry) => toChartCell(runId, entry));
44
+ }
45
+
46
+ export function readRunChart(runId: string, device: RunChartDevice, dir: string): RunChartCell[] {
47
+ const entries = loadRunLedger(runId, dir) ?? [];
48
+ const cells = chartEvents(entries).slice(-RUN_CHART_READ_CELLS).map((e) => toChartCell(runId, e));
49
+ const metrics = runChartMetrics(entries);
50
+ try { debug.log('run-chart', 'read', { runId, device, count: cells.length, stopKeys: cells.map((c) => c.stopKey) });
51
+ debug.log('run-chart', 'metrics', { runId, ...metrics }); } catch { /* observation is fail-soft */ }
52
+ return cells;
53
+ }
54
+
55
+ export function runChartMetrics(entries: readonly RunLedgerEntry[]): { emptyHandoffs: number; unreadHandoffs: number; conflictingVerdicts: number } {
56
+ const cells = entries.filter((e) => e.event === 'run-chart-cell');
57
+ const emptyHandoffs = cells.filter((e) => !String(e.data.handoff ?? '').trim()).length;
58
+ const unreadHandoffs = cells.filter((e) => Boolean(e.data.handoff)
59
+ && !cells.some((next) => next.data.readStopKeys instanceof Array && next.data.readStopKeys.includes(String(e.data.stopKey)))).length;
60
+ const verdicts = new Map<string, Set<string>>();
61
+ for (const cell of cells) {
62
+ const key = `${String(cell.data.device)}\0${String(cell.data.stopKey)}`;
63
+ const values = verdicts.get(key) ?? new Set<string>(); values.add(String(cell.data.verdict)); verdicts.set(key, values);
64
+ }
65
+ const conflictingVerdicts = [...verdicts.values()].filter((values) => values.size > 1).length;
66
+ return { emptyHandoffs, unreadHandoffs, conflictingVerdicts };
67
+ }
68
+
69
+ export function recordRunChartDecision(input: RunChartDecision): RunChartWriteResult {
70
+ const result = appendRunLedgerEntryChecked(input.runId, (entries) => {
71
+ if (entries === null) return { append: false, result: 'missing-ledger' as const };
72
+ const existing = entries.find((entry) => entry.event === 'run-chart-cell'
73
+ && entry.data.device === input.device && entry.data.stopKey === input.stopKey);
74
+ if (existing) return { append: false, result: existing.data.verdict === input.verdict
75
+ ? 'already-recorded' as const : 'conflicting-verdict' as const };
76
+ const current = chartEvents(entries);
77
+ const overflow = current.length >= RUN_CHART_MAX_CELLS;
78
+ const foldCount = overflow ? current.length - (RUN_CHART_MAX_CELLS - 2) : 0;
79
+ const toFold = current.slice(0, foldCount);
80
+ const append: RunLedgerEntry[] = [];
81
+ if (toFold.length) {
82
+ const foldedCells = toFold.filter((e) => e.data.verdict !== 'summary');
83
+ const priorSummary = toFold.find((e) => e.data.verdict === 'summary');
84
+ const priorCount = Number(String(priorSummary?.data.observed ?? '').match(/^\d+/)?.[0] ?? 0);
85
+ const count = priorCount + foldedCells.length;
86
+ const lastFolded = foldedCells.at(-1);
87
+ append.push({ timestamp: new Date().toISOString(), runId: input.runId, event: 'run-chart-summary',
88
+ data: { count, firstStopKey: toFold[0]?.data.stopKey, lastStopKey: lastFolded?.data.stopKey,
89
+ verdicts: toFold.map((e) => `${String(e.data.device)}:${String(e.data.verdict)}`).join('; ').slice(0, 500) } });
90
+ }
91
+ append.push({ timestamp: new Date().toISOString(), runId: input.runId, event: 'run-chart-cell', data: {
92
+ device: input.device, stopKey: input.stopKey, observed: input.observed.slice(0, 240), verdict: input.verdict,
93
+ action: input.action, handoff: input.handoff, why: input.why.slice(0, 240), readStopKeys: input.readStopKeys.slice(-RUN_CHART_READ_CELLS),
94
+ ...(input.waitCount === undefined ? {} : { waitCount: input.waitCount }),
95
+ ...(input.failureClass === undefined ? {} : { failureClass: input.failureClass }),
96
+ } });
97
+ // appendRunLedgerEntryChecked writes one row. Store summary with the decision row as a compact payload.
98
+ return { append: true, entry: append.length === 1 ? append[0]! : { ...append[1]!, data: { ...append[1]!.data,
99
+ compacted: { count: append[0]!.data.count, firstStopKey: append[0]!.data.firstStopKey,
100
+ lastStopKey: append[0]!.data.lastStopKey, lastDevice: toFold.filter((e) => e.data.verdict !== 'summary').at(-1)?.data.device,
101
+ verdicts: append[0]!.data.verdicts } } } };
102
+ }, input.dir);
103
+ const status = result.appended ? 'recorded' : result.result ?? 'ledger-write-refused';
104
+ if (status === 'recorded') {
105
+ try { debug.log('run-chart', 'decision', { runId: input.runId, device: input.device, stopKey: input.stopKey,
106
+ handoff: input.handoff, why: input.why.slice(0, 120) }); } catch { /* observation is fail-soft */ }
107
+ }
108
+ return status;
109
+ }
110
+
111
+ export interface RunChartWaitHandoff { runId: string; stopKey: string; waitCount: number; dir: string; readStopKeys?: string[] }
112
+ export type RunChartWaitHandoffResult = RunChartWriteResult;
113
+ export function recordRunChartWaitHandoff(input: RunChartWaitHandoff): RunChartWaitHandoffResult {
114
+ const readStopKeys = input.readStopKeys ?? readRunChart(input.runId, 'run-supervisor', input.dir).map((cell) => cell.stopKey);
115
+ return recordRunChartDecision({ runId: input.runId, device: 'run-supervisor', stopKey: input.stopKey,
116
+ observed: `consecutive wait decisions=${input.waitCount}`, verdict: 'wait', action: 'wait', handoff: 'run-doctor',
117
+ why: 'wait streak reached run doctor handoff threshold', readStopKeys,
118
+ waitCount: input.waitCount, failureClass: 'implement-aborted', dir: input.dir });
119
+ }
@@ -1,4 +1,4 @@
1
- import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
1
+ import { appendFileSync, closeSync, existsSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
2
2
  import { dirname, isAbsolute, join, resolve } from 'node:path';
3
3
  import { parse as parseYaml } from 'yaml';
4
4
  import { refuseProductionLedgerWriteInTest } from '../harness/ledger-write-guard.js';
@@ -17,6 +17,8 @@ import { withRunLedgerLock, restoreArchivedRunLedger } from './run-ledger-compac
17
17
 
18
18
  export interface RunLedgerEntry {
19
19
  timestamp?: string;
20
+ /** Monotonic per-run ordering for graph/traversal events. Legacy rows may omit it. */
21
+ seq?: number;
20
22
  runId: string;
21
23
  event: string;
22
24
  data: Record<string, unknown>;
@@ -30,6 +32,89 @@ export interface RunLedgerEntry {
30
32
  shardIdentityReadFailure?: RunShardIdentityReadFailure;
31
33
  }
32
34
 
35
+ const RUN_GRAPH_STEP_EVENTS = new Set([
36
+ 'node-enter', 'node-exit', 'edge-taken', 'node-skipped', 'node-added', 'edge-rerouted',
37
+ 'unit-expanded', 'unit-collapsed', 'pipeline-node-entry', 'pipeline-node-exit', 'graph-edge-taken',
38
+ ]);
39
+
40
+ function isRunGraphStepEvent(entry: RunLedgerEntry): boolean {
41
+ return RUN_GRAPH_STEP_EVENTS.has(entry.event)
42
+ || (entry.event === 'applied' && ['add-node', 'reroute', 'zoom-in', 'collapse'].includes(String(entry.data.op)));
43
+ }
44
+
45
+ /** Assign a monotonic sequence at the locked append boundary; never infer it later from timestamps. */
46
+ function sequenceRunGraphEvent(entry: RunLedgerEntry, max: number): RunLedgerEntry {
47
+ if (!isRunGraphStepEvent(entry)) return entry;
48
+ const explicit = entry.seq ?? entry.data.seq;
49
+ if (typeof explicit === 'number' && Number.isSafeInteger(explicit) && explicit > max) {
50
+ return { ...entry, seq: explicit, ...(entry.data.seq === undefined ? {} : { data: { ...entry.data, seq: explicit } }) };
51
+ }
52
+ if (max >= Number.MAX_SAFE_INTEGER) throw new Error(`run graph event sequence exhausted: ${entry.runId}`);
53
+ const seq = max + 1;
54
+ return { ...entry, seq, ...(entry.data.seq === undefined ? {} : { data: { ...entry.data, seq } }) };
55
+ }
56
+
57
+ /** Read backward to the last sequenced graph step; repeated appends stay O(tail), not O(ledger²). */
58
+ function lastRunGraphEventSequence(runId: string, dir: string): number {
59
+ const path = runLedgerPath(runId, dir);
60
+ if (!existsSync(path)) return 0;
61
+ const fd = openSync(path, 'r');
62
+ try {
63
+ const size = statSync(path).size;
64
+ const chunkSize = 8 * 1024;
65
+ let end = size;
66
+ let carry = '';
67
+ while (end > 0) {
68
+ const start = Math.max(0, end - chunkSize);
69
+ const bytes = Buffer.alloc(end - start);
70
+ readSync(fd, bytes, 0, bytes.length, start);
71
+ const text = `${bytes.toString('utf8')}${carry}`;
72
+ const lines = text.split(/\r?\n/);
73
+ carry = lines[0] ?? '';
74
+ for (let index = lines.length - 1; index > 0; index -= 1) {
75
+ const line = lines[index]?.trim();
76
+ if (!line) continue;
77
+ let row: RunLedgerEntry;
78
+ try { row = parseRunLedgerEntry(line, 0, runId); }
79
+ catch (error) {
80
+ if (index === lines.length - 1 && !text.endsWith('\n') && isIncompleteJsonPrefix(line)) {
81
+ throw new Error(`incomplete trailing run ledger entry: ${runId}`);
82
+ }
83
+ throw error;
84
+ }
85
+ if (!isRunGraphStepEvent(row)) continue;
86
+ const seq = row.seq ?? row.data.seq;
87
+ if (typeof seq === 'number' && Number.isSafeInteger(seq) && seq > 0) return seq;
88
+ }
89
+ end = start;
90
+ }
91
+ if (carry.trim()) {
92
+ let row: RunLedgerEntry;
93
+ try { row = parseRunLedgerEntry(carry, 0, runId); }
94
+ catch (error) {
95
+ if (isIncompleteJsonPrefix(carry)) throw new Error(`incomplete trailing run ledger entry: ${runId}`);
96
+ throw error;
97
+ }
98
+ if (!isRunGraphStepEvent(row)) return 0;
99
+ const seq = row.seq ?? row.data.seq;
100
+ if (typeof seq === 'number' && Number.isSafeInteger(seq) && seq > 0) return seq;
101
+ }
102
+ return 0;
103
+ } finally { closeSync(fd); }
104
+ }
105
+
106
+ function separateAppendedLedgerLine(path: string, line: string): string {
107
+ if (!existsSync(path)) return line;
108
+ const size = statSync(path).size;
109
+ if (size === 0) return line;
110
+ const fd = openSync(path, 'r');
111
+ try {
112
+ const lastByte = Buffer.alloc(1);
113
+ readSync(fd, lastByte, 0, 1, size - 1);
114
+ return lastByte[0] === 0x0a ? line : `\n${line}`;
115
+ } finally { closeSync(fd); }
116
+ }
117
+
33
118
  export type RunShardIdentityReadFailure = 'malformed-structure' | 'invalid-values';
34
119
 
35
120
  export interface RunShardIdentity {
@@ -414,12 +499,20 @@ export function runGraphVariantPath(runId: string, dir = runLedgerDir()): string
414
499
  return `${runLedgerPath(runId, dir)}.graph.yaml`;
415
500
  }
416
501
 
502
+ /** 원장에 실린 unit 선언 근거 한 줄 — 경로와 내용 해시뿐이고 본문은 원장에 없다. */
503
+ export interface RunGraphVariantUnitDeclaration {
504
+ readonly path: string;
505
+ readonly contentHash: string;
506
+ }
507
+
417
508
  /** 최초 graph variant 선택의 원장 옆 재조회 계약 — 같은 runId·파일이면 같은 id·선택 이유가 돌아온다. */
418
509
  export interface RunGraphVariantSelection {
419
510
  /** createGraphVariant 가 골 종류·대상 경로 수에서 유도한 최초 variant id. */
420
511
  readonly variantId: string;
421
512
  /** 그 variant가 최초로 선택된 근거(종류·경로 수 기반) — 저장·재조회가 같은 문자열. */
422
513
  readonly reason: string;
514
+ /** 이 런이 읽은 unit 선언의 경로·내용 해시 — 옛 원장에는 키가 없어 값도 없다(추가 키). */
515
+ readonly unitDeclarations?: readonly RunGraphVariantUnitDeclaration[];
423
516
  }
424
517
 
425
518
  /** 런 원장 옆 .graph.yaml 을 처음 한 번 쓰고 저장 경로를 돌려준다 — 이미 있으면 덮쓰지 않는다(flag wx). */
@@ -447,9 +540,24 @@ export function loadRunGraphVariant(runId: string, dir = runLedgerDir()): RunGra
447
540
  throw new Error(`invalid run graph variant YAML at ${path}: ${error instanceof Error ? error.message : String(error)}`);
448
541
  }
449
542
  if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return null;
450
- const record = parsed as { variant_id?: unknown; reason?: unknown };
543
+ const record = parsed as { variant_id?: unknown; reason?: unknown; unit_declarations?: unknown };
451
544
  if (typeof record.variant_id !== 'string' || typeof record.reason !== 'string') return null;
452
- return { variantId: record.variant_id, reason: record.reason };
545
+ const unitDeclarations = parseRunGraphVariantUnitDeclarations(record.unit_declarations);
546
+ return { variantId: record.variant_id, reason: record.reason,
547
+ ...(unitDeclarations === undefined ? {} : { unitDeclarations }) };
548
+ }
549
+
550
+ /** `unit_declarations: [{ path, content_hash }]` 추가 키의 재읽기 — 키가 없거나 비면 근거도 없다. */
551
+ function parseRunGraphVariantUnitDeclarations(value: unknown): RunGraphVariantUnitDeclaration[] | undefined {
552
+ if (!Array.isArray(value)) return undefined;
553
+ const declarations: RunGraphVariantUnitDeclaration[] = [];
554
+ for (const entry of value) {
555
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) continue;
556
+ const record = entry as { path?: unknown; content_hash?: unknown };
557
+ if (typeof record.path !== 'string' || typeof record.content_hash !== 'string') continue;
558
+ declarations.push({ path: record.path, contentHash: record.content_hash });
559
+ }
560
+ return declarations.length === 0 ? undefined : declarations;
453
561
  }
454
562
 
455
563
  /**
@@ -689,12 +797,21 @@ export function appendRunLedgerEntry(entry: RunLedgerEntry, dir = runLedgerDir()
689
797
  if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
690
798
  const live = runLedgerPath(entry.runId, dir);
691
799
  const devProject = process.env.ELANOUS_DEV_PROJECT;
692
- const row = entry.devProject === undefined && typeof devProject === 'string' && devProject.startsWith('prj-')
693
- ? { ...entry, devProject }
694
- : entry;
695
800
  withRunLedgerLock(dir, entry.runId, () => {
696
- const line = `${JSON.stringify(row)}\n`;
697
- if (!restoreArchivedRunLedger(dir, entry.runId, line)) appendFileSync(live, line, 'utf8');
801
+ let sequenced = entry;
802
+ if (isRunGraphStepEvent(entry)) {
803
+ // Restore a compacted ledger before choosing its next sequence so appends keep the
804
+ // same per-run order across the live/archive boundary.
805
+ restoreArchivedRunLedger(dir, entry.runId);
806
+ sequenced = sequenceRunGraphEvent(entry, lastRunGraphEventSequence(entry.runId, dir));
807
+ }
808
+ const sequencedRow = sequenced.devProject === undefined && typeof devProject === 'string' && devProject.startsWith('prj-')
809
+ ? { ...sequenced, devProject }
810
+ : sequenced;
811
+ const line = `${JSON.stringify(sequencedRow)}\n`;
812
+ const appendLine = isRunGraphStepEvent(entry) ? separateAppendedLedgerLine(live, line) : line;
813
+ if (!isRunGraphStepEvent(entry) && restoreArchivedRunLedger(dir, entry.runId, appendLine)) return;
814
+ appendFileSync(live, appendLine, 'utf8');
698
815
  });
699
816
  try {
700
817
  recordRunRequestVsEffectiveFromLedger(entry.runId, dir, entry);
@@ -767,7 +884,8 @@ export function appendRunLedgerEntryChecked<T>(
767
884
  ): RunLedgerCheckedAppendOutcome<T> {
768
885
  if (refuseProductionLedgerWriteInTest(dir, 'run-ledger')) return { appended: false, result: null, refusal: 'ledger-write-refused' as const };
769
886
  return withRunLedgerLock(dir, runId, () => {
770
- const decision = decide(loadRunLedger(runId, dir));
887
+ const existing = loadRunLedger(runId, dir);
888
+ const decision = decide(existing);
771
889
  if (!decision.append) return { appended: false, result: decision.result, refusal: null };
772
890
  const entry = decision.entry;
773
891
  if (entry.runId !== runId) {
@@ -775,11 +893,16 @@ export function appendRunLedgerEntryChecked<T>(
775
893
  }
776
894
  const live = runLedgerPath(entry.runId, dir);
777
895
  const devProject = process.env.ELANOUS_DEV_PROJECT;
778
- const row = entry.devProject === undefined && typeof devProject === 'string' && devProject.startsWith('prj-')
779
- ? { ...entry, devProject }
780
- : entry;
896
+ const isGraphStep = isRunGraphStepEvent(entry);
897
+ if (isGraphStep) restoreArchivedRunLedger(dir, runId);
898
+ const sequenced = isGraphStep ? sequenceRunGraphEvent(entry, lastRunGraphEventSequence(runId, dir)) : entry;
899
+ const row = sequenced.devProject === undefined && typeof devProject === 'string' && devProject.startsWith('prj-')
900
+ ? { ...sequenced, devProject }
901
+ : sequenced;
781
902
  const line = `${JSON.stringify(row)}\n`;
782
- if (!restoreArchivedRunLedger(dir, entry.runId, line)) appendFileSync(live, line, 'utf8');
903
+ const appendLine = isGraphStep ? separateAppendedLedgerLine(live, line) : line;
904
+ if (!isGraphStep && restoreArchivedRunLedger(dir, entry.runId, appendLine)) return { appended: true, result: null, refusal: null };
905
+ appendFileSync(live, appendLine, 'utf8');
783
906
  return { appended: true, result: null, refusal: null };
784
907
  });
785
908
  }
@@ -902,6 +1025,7 @@ function parseRunLedgerEntry(line: string, lineNumber: number, expectedRunId: st
902
1025
  }
903
1026
  const entry = parsed as Partial<RunLedgerEntry>;
904
1027
  if ((entry.timestamp !== undefined && typeof entry.timestamp !== 'string') || typeof entry.runId !== 'string' || typeof entry.event !== 'string'
1028
+ || (entry.seq !== undefined && (!Number.isSafeInteger(entry.seq) || entry.seq < 1))
905
1029
  || !entry.data || typeof entry.data !== 'object' || Array.isArray(entry.data)
906
1030
  || (entry.goalId !== undefined && typeof entry.goalId !== 'string')
907
1031
  || (entry.orchestrationId !== undefined && typeof entry.orchestrationId !== 'string')
@@ -1811,6 +1935,8 @@ export interface UnfinishedRunLedgerQuery {
1811
1935
  * 엉킨 visit 을 셀 수 있게 하는 값이다.
1812
1936
  */
1813
1937
  orphanUnitVisitCount?: number;
1938
+ /** True when a caller deadline stopped the scan before every ledger was visited. */
1939
+ timedOut?: boolean;
1814
1940
  scope: 'self-implement-run-ledger';
1815
1941
  note: string;
1816
1942
  }
@@ -1824,6 +1950,8 @@ export interface UnfinishedRunLedgerQueryOptions {
1824
1950
  noCache?: boolean;
1825
1951
  /** ⛔ 「도는 중」으로 볼 마지막 활동 나이(ms). 호출자가 준다 — 이 모듈이 새 수를 정하지 않는다. */
1826
1952
  liveWindowMs?: number;
1953
+ /** Absolute wall-clock deadline; when reached, return the rows scanned so far as partial evidence. */
1954
+ deadlineAtMs?: number;
1827
1955
  }
1828
1956
 
1829
1957
  const UNFINISHED_RUN_LEDGER_NOTE = 'Read-only scan of the specified run-ledger directory. A terminal-status-missing ledger is not the same as an unreadable ledger; planned paths are extracted only from a goal document matched by the final hyphen-separated branch segment.';
@@ -2470,7 +2598,12 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
2470
2598
  let callerCwdCount = 0;
2471
2599
  // ⭐ 터미널 원장도 «세기만» 한다 — entries 로 되살리지 않는다(부활 금지).
2472
2600
  let orphanUnitVisitCount = 0;
2601
+ let timedOut = false;
2473
2602
  for (const fileName of fileNames) {
2603
+ if (options.deadlineAtMs !== undefined && Date.now() >= options.deadlineAtMs) {
2604
+ timedOut = true;
2605
+ break;
2606
+ }
2474
2607
  const runId = runIdFromCanonicalLedgerFile(fileName);
2475
2608
  if (!runId) continue;
2476
2609
  scanned += 1;
@@ -2555,9 +2688,10 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
2555
2688
  indexOrigin,
2556
2689
  indexHits,
2557
2690
  ms: Date.now() - startedAt,
2691
+ ...(timedOut ? { timedOut: true, stopReason: 'deadline-exceeded' } : {}),
2558
2692
  });
2559
2693
  if (options.path === undefined) {
2560
- return { entries, ledgerDirectory: dir, goalsDirectory: goalsDir, unreadableLedgerCount, orphanUnitVisitCount, ledgerDirectoryMissing: false, terminalByTrailingRunStatus, cacheHits, cacheMisses, indexHits, indexOrigin, scope: 'self-implement-run-ledger', note: UNFINISHED_RUN_LEDGER_NOTE };
2694
+ return { entries, ledgerDirectory: dir, goalsDirectory: goalsDir, unreadableLedgerCount, orphanUnitVisitCount, ledgerDirectoryMissing: false, terminalByTrailingRunStatus, cacheHits, cacheMisses, indexHits, indexOrigin, ...(timedOut ? { timedOut: true } : {}), scope: 'self-implement-run-ledger', note: UNFINISHED_RUN_LEDGER_NOTE };
2561
2695
  }
2562
2696
  const pathFilter = options.path;
2563
2697
  const unknownPathStatus = (entry: UnfinishedRunLedgerEntry): boolean => entry.plannedPathStatus !== 'found-ledger-goal-file'
@@ -2583,6 +2717,7 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
2583
2717
  pathFilter,
2584
2718
  matchingPathCount: matchingEntries.length,
2585
2719
  unknownPathCount: unknownEntries.length,
2720
+ ...(timedOut ? { timedOut: true } : {}),
2586
2721
  scope: 'self-implement-run-ledger',
2587
2722
  note: UNFINISHED_RUN_LEDGER_NOTE,
2588
2723
  };
@@ -2619,6 +2754,8 @@ export interface FederatedUnfinishedRunLedgerQuery {
2619
2754
  cacheMisses?: number;
2620
2755
  /** Hits served by the persisted cross-process scan index (subset of cacheHits). */
2621
2756
  indexHits?: number;
2757
+ timedOut?: boolean;
2758
+ stalledStage?: 'ledger-scan' | 'cross-directory-reconciliation';
2622
2759
  pathFilter?: string;
2623
2760
  matchingPathCount?: number;
2624
2761
  unknownPathCount?: number;
@@ -2640,6 +2777,7 @@ export interface FederatedUnfinishedRunLedgerQueryOptions {
2640
2777
  * canonical *.jsonl plus the cross-directory unfinished-runId reconciliation.
2641
2778
  */
2642
2779
  runIds?: readonly string[];
2780
+ deadlineAtMs?: number;
2643
2781
  }
2644
2782
 
2645
2783
  const FEDERATED_UNFINISHED_RUN_LEDGER_NOTE = 'Read-only union of run-ledger directories selected by the same --all/--include-test target policy as elanous logs. Each row carries its physical ledger directory because instance names can identify multiple state roots.';
@@ -2659,12 +2797,19 @@ export function queryFederatedUnfinishedRunLedgers(options: FederatedUnfinishedR
2659
2797
  let cacheHits = 0;
2660
2798
  let cacheMisses = 0;
2661
2799
  let indexHits = 0;
2800
+ let timedOut = false;
2801
+ let stalledStage: FederatedUnfinishedRunLedgerQuery['stalledStage'];
2662
2802
  const recordDirectoryFailure = (kind: FederatedLedgerDirectoryFailureKind): void => {
2663
2803
  if (kind === 'missing') missingLedgerDirectoryCount += 1;
2664
2804
  else if (kind === 'unreadable') unreadableLedgerDirectoryAccessCount += 1;
2665
2805
  else indeterminateLedgerDirectoryCount += 1;
2666
2806
  };
2667
2807
  for (const ledgerDirectory of candidateLedgerDirectories) {
2808
+ if (options.deadlineAtMs !== undefined && Date.now() >= options.deadlineAtMs) {
2809
+ timedOut = true;
2810
+ stalledStage = 'ledger-scan';
2811
+ break;
2812
+ }
2668
2813
  try {
2669
2814
  const listDirectory = options.list ?? readdirSync;
2670
2815
  const list = requestedRunIds === undefined
@@ -2673,7 +2818,7 @@ export function queryFederatedUnfinishedRunLedgers(options: FederatedUnfinishedR
2673
2818
  const runId = runIdFromCanonicalLedgerFile(fileName);
2674
2819
  return runId !== null && requestedRunIds.has(runId);
2675
2820
  });
2676
- const result = queryUnfinishedRunLedgers({ dir: ledgerDirectory, goalsDir: goalsDirectory, ...(options.path === undefined ? {} : { path: options.path }), ...(list === undefined ? {} : { list }), noCache: options.noCache });
2821
+ const result = queryUnfinishedRunLedgers({ dir: ledgerDirectory, goalsDir: goalsDirectory, ...(options.path === undefined ? {} : { path: options.path }), ...(list === undefined ? {} : { list }), noCache: options.noCache, deadlineAtMs: options.deadlineAtMs });
2677
2822
  if (result.ledgerDirectoryMissing) {
2678
2823
  recordDirectoryFailure('missing');
2679
2824
  continue;
@@ -2685,10 +2830,15 @@ export function queryFederatedUnfinishedRunLedgers(options: FederatedUnfinishedR
2685
2830
  cacheHits += result.cacheHits ?? 0;
2686
2831
  cacheMisses += result.cacheMisses ?? 0;
2687
2832
  indexHits += result.indexHits ?? 0;
2833
+ if (result.timedOut) {
2834
+ timedOut = true;
2835
+ stalledStage = 'ledger-scan';
2836
+ }
2688
2837
  entries.push(...result.entries.map((entry) => ({ ...entry, ledgerDirectory })));
2689
2838
  } catch (error) {
2690
2839
  recordDirectoryFailure(classifyFederatedLedgerDirectoryReadFailure(error));
2691
2840
  }
2841
+ if (timedOut) break;
2692
2842
  }
2693
2843
  const unreadableLedgerDirectoryCount = missingLedgerDirectoryCount + unreadableLedgerDirectoryAccessCount + indeterminateLedgerDirectoryCount;
2694
2844
  // ⛔⭐⭐ 가로 대조 — 원장 «하나»만 보고 「미완」이라 말하지 않는다 (2026-08-11 · 🅣 71차 실측).
@@ -2698,20 +2848,28 @@ export function queryFederatedUnfinishedRunLedgers(options: FederatedUnfinishedR
2698
2848
  // 📏 실측(2026-08-11): 미완 57 중 ***7*** 이 다른 원장에 종결을 갖고 있었다.
2699
2849
  // ⛔ 판정 술어는 스캐너와 «같은 것»을 쓴다(`run-status` 또는 `terminal`) — 어휘를 새로 만들지 않는다.
2700
2850
  const terminatedElsewhere = new Set<string>();
2851
+ const reconciledRunIds = new Set<string>();
2701
2852
  // Runs carrying a non-blocking request record never drop out of the union: their requestId
2702
2853
  // reason·next must survive restarts and cross-directory reconciliation alike.
2703
2854
  const unfinishedRunIds = requestedRunIds === undefined
2704
2855
  ? new Set(entries.filter((entry) => !entry.nonBlocking).map((entry) => entry.runId))
2705
2856
  : new Set([...requestedRunIds].filter((runId) => entries.some((entry) => entry.runId === runId && !entry.nonBlocking)));
2706
- for (const runId of unfinishedRunIds) {
2857
+ for (const runId of timedOut ? [] : unfinishedRunIds) {
2858
+ if (options.deadlineAtMs !== undefined && Date.now() >= options.deadlineAtMs) {
2859
+ timedOut = true;
2860
+ stalledStage = 'cross-directory-reconciliation';
2861
+ break;
2862
+ }
2707
2863
  for (const ledgerDirectory of ledgerDirectories) {
2708
2864
  try {
2709
2865
  const reconciliationIndex = options.noCache ? undefined : loadRunLedgerScanIndex(ledgerDirectory);
2710
2866
  if (readUnfinishedLedgerFacts(runId, ledgerDirectory, undefined, options.noCache, reconciliationIndex).facts.terminal) { terminatedElsewhere.add(runId); break; }
2711
2867
  } catch { /* An absent or unreadable sibling cannot establish termination. */ }
2712
2868
  }
2869
+ reconciledRunIds.add(runId);
2713
2870
  }
2714
- const reconciledEntries = entries.filter((entry) => !terminatedElsewhere.has(entry.runId));
2871
+ const reconciledEntries = entries.filter((entry) => !terminatedElsewhere.has(entry.runId)
2872
+ && (stalledStage !== 'cross-directory-reconciliation' || reconciledRunIds.has(entry.runId)));
2715
2873
  const reconciledTerminatedElsewhereCount = entries.length - reconciledEntries.length;
2716
2874
  entries.length = 0;
2717
2875
  entries.push(...reconciledEntries);
@@ -2729,6 +2887,7 @@ export function queryFederatedUnfinishedRunLedgers(options: FederatedUnfinishedR
2729
2887
  cacheHits,
2730
2888
  cacheMisses,
2731
2889
  indexHits,
2890
+ ...(timedOut ? { timedOut: true, stalledStage } : {}),
2732
2891
  ...(options.path === undefined ? {} : { pathFilter: options.path, matchingPathCount, unknownPathCount }),
2733
2892
  scope: 'self-implement-run-ledger-federated',
2734
2893
  note: FEDERATED_UNFINISHED_RUN_LEDGER_NOTE,