elanous 0.2.35 → 0.2.37

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 (827) 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/{T1mBQqmkwKDLGtyisDCOd → 8kITumG9GAZ1LwT9POrAR}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/1041-5841aae848fb6403.js +1 -0
  5. package/apps/pwa/out/_next/static/chunks/1087.3177e54f672dc526.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1105.efe1e13503ac7a33.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1224.2ceca6c180d5130b.js +62 -0
  8. package/apps/pwa/out/_next/static/chunks/{9952.5daf5f94063a2b3e.js → 1262.a89bb27a5b2f844e.js} +1 -1
  9. package/apps/pwa/out/_next/static/chunks/1417-1768233ac92f8a5d.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1612.81bbc19af06af16c.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1746.3563617ea64023a3.js +115 -0
  12. package/apps/pwa/out/_next/static/chunks/1766.728d42053070bb2d.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1773.d38e945481e04125.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1974-c12f9600da3d3c26.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/{1dc5a567.9b092bfae3d7099b.js → 1ed5e8af.cf424815c7c0efad.js} +1 -1
  16. package/apps/pwa/out/_next/static/chunks/{4705-194e64e47ca0fbdb.js → 2002-a43a3f380df873ec.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/2061.7232dc9dc058417f.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{13.02a07436dec15f89.js → 210.90b2cbd64926cf34.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/{9512.5a76207a730e0491.js → 2283.edd9627b7bdfb546.js} +2 -2
  20. package/apps/pwa/out/_next/static/chunks/{6866-79aa5b4e47cac6aa.js → 2318-450e75d07605b8fe.js} +1 -1
  21. package/apps/pwa/out/_next/static/chunks/{938.66ad1ef0e5abae1c.js → 2375.bf364c85dbb6f085.js} +1 -1
  22. package/apps/pwa/out/_next/static/chunks/244-a810d282a20f1783.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/2479-fe7e188bd9402d14.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2514.03b60f266531a015.js +148 -0
  25. package/apps/pwa/out/_next/static/chunks/2526-a657538869888604.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2533-6f0341ff075809e9.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2676.e7994c695ef0f30d.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2734.3ffdf54254fb6f99.js +27 -0
  29. package/apps/pwa/out/_next/static/chunks/2770-23252bf3a37880b9.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/2969.66b8b545139d1544.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/3128.a9210d08800ea6a8.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/3199.6a1a9b0e6cd01dc6.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/3212.12179fd3eee8cef1.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/{9214.63a510d39178e997.js → 3578.4e9f9948a9a6f2f4.js} +2 -2
  35. package/apps/pwa/out/_next/static/chunks/3760-2909ddb9279281cd.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3825.1921b5901bf33dce.js +36 -0
  37. package/apps/pwa/out/_next/static/chunks/3994-63eb884ed0547011.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/4036.d54e55e1ebf5acdc.js +90 -0
  39. package/apps/pwa/out/_next/static/chunks/4115.5b438b99f0ae729f.js +226 -0
  40. package/apps/pwa/out/_next/static/chunks/4269.d8f9f34bb0fc6c43.js +287 -0
  41. package/apps/pwa/out/_next/static/chunks/431-4eed5bd2c5fe1719.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/{2018.a741297bce759490.js → 4313.76f232c304a15bde.js} +1 -1
  43. package/apps/pwa/out/_next/static/chunks/{1165.bad13fc9151a7288.js → 4324.c99ba3e83eb1b691.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/{3f7c4ee5.3dde54f01a816613.js → 4337e36d.f42c3b391b3d8f20.js} +1 -1
  45. package/apps/pwa/out/_next/static/chunks/{7385.50a308a477bdfc21.js → 4383.18e5c54db3a22c88.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/4599-96eff3f2a9c242c1.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{8557-e7898769499cd56f.js → 4725-34bed25720cc326b.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/4825-a9d9d4e9f5892309.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/{5483-dd5d7697f6bdb106.js → 4833-7934c592c5569f00.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/4879-68518f547a207aff.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4896.f9b70285363b27b2.js +24 -0
  52. package/apps/pwa/out/_next/static/chunks/{8444.4c26b379ca2b9596.js → 4931.95cc6dbd230774ca.js} +17 -17
  53. package/apps/pwa/out/_next/static/chunks/4937-28d437999b77c9dd.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/49aa54ab.80f39398e0ed0f30.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/{3408.21d1570602f4b6c0.js → 5046.7fd5cbd859299448.js} +1 -1
  56. package/apps/pwa/out/_next/static/chunks/5056.482687319b82638e.js +104 -0
  57. package/apps/pwa/out/_next/static/chunks/506.16b83d56a437a9ee.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5260-20593b0a25d0afbc.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5404.cc4e9fec26fd5925.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/576.485e83e3f3dec19a.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5832-a6be14e663f65726.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5854-56648a9fe646b9a0.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/58edce7d.f1b0c72acf13b123.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5925.3b1f8b135710249b.js +93 -0
  65. package/apps/pwa/out/_next/static/chunks/5952.294fc574a8625184.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/{b6705a4f-b9a9047de9eecfd0.js → 5f6af561-f90b7a67f4f75d13.js} +1 -1
  67. package/apps/pwa/out/_next/static/chunks/6168.17749aa3905fa073.js +74 -0
  68. package/apps/pwa/out/_next/static/chunks/6252.240578f10952e091.js +34 -0
  69. package/apps/pwa/out/_next/static/chunks/6416.5d50b8ec9986ca98.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/{5101.e32282718f99ed6f.js → 6680.6a693c28aae4cd19.js} +1 -1
  71. package/apps/pwa/out/_next/static/chunks/{4718-17d2af636796a330.js → 6745-5a63492933959dd9.js} +3 -3
  72. package/apps/pwa/out/_next/static/chunks/6758.e7fbf532953c0783.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6795.0cb8a59730d99703.js +149 -0
  74. package/apps/pwa/out/_next/static/chunks/{6236.e18cced2d5ba6afb.js → 6819.be5c9c4d67f22922.js} +16 -16
  75. package/apps/pwa/out/_next/static/chunks/6877-84d47b7e85d0c41e.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/{2833-0fe47af99ed13c29.js → 6971-fb5f9dc0a2cb5d2d.js} +1 -1
  77. package/apps/pwa/out/_next/static/chunks/{da5176c6.6773b6c5994e1d99.js → 709a918c.4fd3b4e2a32cb4e3.js} +1 -1
  78. package/apps/pwa/out/_next/static/chunks/717.522b08685979b814.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/7191.e41eb8f455c7f089.js +41 -0
  80. package/apps/pwa/out/_next/static/chunks/7233.8e744b7513119409.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7238-97c2226f80504bd8.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/7285.307963afcf7e7660.js +24 -0
  83. package/apps/pwa/out/_next/static/chunks/7299-fbe4b8c47a87614a.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7314.df0d95930b0c3f50.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7406.c0589fdf2ee66629.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7424.c0fe2a595d4232b5.js +23 -0
  87. package/apps/pwa/out/_next/static/chunks/752-90e3e7daad3d8e39.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7524-bcd3d9928c6842d9.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7549.9a4de3bf231cfc52.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/757-4fbaf50942b8c424.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/765.76ae970ceb597b5b.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{7644.17e37ba6f1d4226e.js → 7867.e8725745ddd1d940.js} +4 -4
  93. package/apps/pwa/out/_next/static/chunks/7893-e444a1b0809cd1e4.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7956-33748cabb3a05562.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{0368f25d-ad84af92fefee68f.js → 7c5ed21f-f286708e57cf88f7.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/8030-aa66b478b53dbfca.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8051.c88c07dacbbc5f21.js +8 -0
  98. package/apps/pwa/out/_next/static/chunks/{359-2250789a2d3499e7.js → 8080-40d781e7704d3671.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/8149.80e402d4345e8dae.js +77 -0
  100. package/apps/pwa/out/_next/static/chunks/8205.50a5268f4e12ba0b.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8231.a128feaa6f8b6079.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/85.4ddb1dda2ea3ffa2.js +286 -0
  103. package/apps/pwa/out/_next/static/chunks/8537.26517a09e8247beb.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8595-e9b7081ab773a61f.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8821-30cc65a61a60951f.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8905.b3385aadb7b133e6.js +79 -0
  107. package/apps/pwa/out/_next/static/chunks/8983.246bb3a1ac38f50f.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/{b2f6ba4d.fb56fdbbf798df33.js → 8c58d09b.e8724a299658d86f.js} +1 -1
  109. package/apps/pwa/out/_next/static/chunks/9072.18342f5941a1f3ec.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/9123.9df04866b2d6e00f.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/{1530.0e612369b6fd7ea0.js → 9151.a2c51e93f9156dae.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/{4441-875b97f5821ed58a.js → 9175-7d383df15a82e2be.js} +1 -1
  113. package/apps/pwa/out/_next/static/chunks/9181-bf89c07ce5b8f599.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/920-429bbc4504b45f71.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9207.625edf45d656151c.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9378.d2575c6ffd6dd756.js +94 -0
  117. package/apps/pwa/out/_next/static/chunks/957.db5b5c4d32a35240.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/958.53a8dcf4729e6997.js +64 -0
  119. package/apps/pwa/out/_next/static/chunks/9647.8f0cd0898c592a29.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9665-26abb02665704c2c.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9703.e7d81b6faef1050a.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9882-7a9164b3c2dacbe5.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/9998.b74e033efadecd10.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c604fb980a634d88.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ec2d8a4979ca9075.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-cb6add08ad3c7660.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/board/page-e2eaa321ec223fe6.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/botlab/page-5b8a09c475b5f844.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/bots/page-91a77daedfbac191.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/ceo/page-f37fc5e974bda39b.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/chat/page-91429a0b78415a94.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/consult/page-b95798b58263b910.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/control/page-763d53e175e17aa1.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/decisions/page-d55023204055b12f.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/design-check/page-89d2140d78abc810.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/editor/page-82dc069abfe27f55.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/exec/page-25d9eee7beb552c0.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/field/page-770b4594c713ee97.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c604fb980a634d88.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/inside/page-ba8e0dcae4f83985.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/intake/page-5c112c6d7c33656e.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/layout-09788e1aa9a87db6.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live/page-3337c6a1328c2674.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/live-run/page-89acd5d68c0bc560.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/loops/page-5c13e2c76371d797.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/market/page-653a9f18642825c6.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-fe986fe79b107546.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/morning/{page-47c5d4db587266bd.js → page-1e5da297557d2354.js} +1 -1
  149. package/apps/pwa/out/_next/static/chunks/app/not-found-91ea9f5869a40943.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/observatory/page-7824e21b999962e2.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-53d00a60cc75a922.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/release/{page-1f5a60f70cb4dd0c.js → page-88a1edbff62eaf1d.js} +1 -1
  153. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e931248b3f9574b.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/outputs/{page-bac7dee94e5eae4a.js → page-443364c9e4a23b31.js} +1 -1
  155. package/apps/pwa/out/_next/static/chunks/app/page-b9af2ac1c4737ce8.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/reflection/page-25ab9c614c14129b.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-dbcdcfac0a395a8a.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/sessions/page-bf1de6645089ec58.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c4201761a5e839c9.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/settings/page-c304f469ea5d70e4.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8e5a238cf5e50c9c.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c604fb980a634d88.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/page-32b526069ee50b3c.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/share/page-fb9e639c107f5f72.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/showroom/page-84220c776608cedc.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/tasks/page-e475618cbfd5ca2b.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/term/{page-dc0a532f5b9196ec.js → page-ac2c1e6169cfce57.js} +1 -1
  168. package/apps/pwa/out/_next/static/chunks/app/today/page-fccd3020af2f8806.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/trace/page-9c0d7198ff7b5a91.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/vault/page-d54b1ec9b9c6430d.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8c4bef1791d732ca.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/page-46fcc0b0bbc6fbfe.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workspace/page-c1c80e345fa9d6f5.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7dfda00afd172f5b.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/{d06f9160.a3d9062f95de8ad7.js → d9815f84.4918f682a45a8502.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{cbe38a15.5a032598e39970c6.js → de8446d3.31b73eb239fecd7b.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/f21fd540.63ac75328926ed30.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/framework-77fdcc873519a6cd.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-app-d0d620d2ce235713.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-e0ef79c79337ba90.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-84b1bc71e3f9ce6a.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-2acb61f1363128cb.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-462ff5727ceb7824.js +1 -0
  184. package/apps/pwa/out/_next/static/css/{b5d88eba78a3d7bf.css → be9019f696217521.css} +1 -1
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +23 -23
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +23 -23
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +23 -23
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +22 -22
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +22 -22
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +23 -23
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +22 -22
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +23 -23
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +23 -23
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +22 -22
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +23 -23
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +23 -23
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +23 -23
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +23 -23
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +22 -22
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +22 -22
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +23 -23
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +23 -23
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +23 -23
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +22 -22
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +22 -22
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +23 -23
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +23 -23
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +22 -22
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +22 -22
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +22 -22
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +23 -23
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +23 -23
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +22 -22
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +23 -23
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +23 -23
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +23 -23
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +23 -23
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +23 -23
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +22 -22
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +23 -23
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +23 -23
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +23 -23
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +23 -23
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +23 -23
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +23 -23
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +23 -23
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +23 -23
  278. package/docs/goal-context/05-authoring-lessons.jsonl +47 -0
  279. package/docs/goal-context/README.md +3 -0
  280. package/graphs/default-loop.yaml +6 -1
  281. package/graphs/drafts/recipes.yaml +27 -7
  282. package/graphs/implement-loop.yaml +24 -0
  283. package/graphs/release/recipes.yaml +6 -0
  284. package/graphs/release/release-loop.yaml +17 -4
  285. package/graphs/wizard/recipes.yaml +44 -0
  286. package/graphs/wizard/wizard-loop.yaml +44 -0
  287. package/graphs/work/draft-close.yaml +54 -0
  288. package/graphs/work/green-close.yaml +37 -0
  289. package/graphs/work/recipes.yaml +46 -1
  290. package/graphs/work/research-report.yaml +2 -0
  291. package/graphs/work/run-research.yaml +35 -0
  292. package/package.json +1 -1
  293. package/scripts/__fixtures__/authoring-paths-10x3.json +32 -0
  294. package/scripts/boundary-proof-mapping-audit.ts +88 -0
  295. package/scripts/ci-typecheck-changed.ts +139 -5
  296. package/scripts/codex-fallback-live-probe.ts +17 -15
  297. package/scripts/coord-role-pack.ts +1 -1
  298. package/scripts/first10-gate.ts +416 -0
  299. package/scripts/fleet/node-setup.sh +32 -2
  300. package/scripts/fleet/run-light-worker.sh +9 -0
  301. package/scripts/fleet/wsl-node-setup.sh +432 -0
  302. package/scripts/gate-0226-failure-census.ts +507 -0
  303. package/scripts/goals/authoring-metrics.ts +258 -0
  304. package/scripts/graph-units/draft-close-node.ts +222 -0
  305. package/scripts/hook-order-sweep.ts +7 -4
  306. package/scripts/land-global-checks.ts +69 -1
  307. package/scripts/measure-nl-routing-corpus.ts +207 -2
  308. package/scripts/release-loop/docs-node.ts +344 -8
  309. package/scripts/release-loop/gate-closure.ts +48 -0
  310. package/scripts/release-loop/gate-diff.ts +2 -1
  311. package/scripts/release-loop/gate-node.ts +249 -53
  312. package/scripts/release-loop/known-issues-node.ts +6 -4
  313. package/scripts/release-loop/node-verdict.ts +2 -0
  314. package/scripts/release-loop/notes-repair.ts +216 -0
  315. package/scripts/release-loop/prepare-node.ts +61 -5
  316. package/scripts/release-loop/resume-cap.ts +14 -34
  317. package/scripts/release-loop/resume-release.ts +151 -15
  318. package/scripts/release-loop/resume-test-traffic.ts +10 -0
  319. package/scripts/release-loop/traffic-node.ts +59 -0
  320. package/scripts/release-loop/traffic-transition.ts +159 -0
  321. package/scripts/release-loop/version-node.ts +81 -12
  322. package/scripts/rhythm/daily.ts +137 -3
  323. package/scripts/train/green-leg.ts +176 -0
  324. package/scripts/tui-continue-real-evidence.ts +47 -0
  325. package/scripts/ux-sim.ts +53 -0
  326. package/skills/README.md +1 -0
  327. package/src/acp/client.ts +31 -5
  328. package/src/acp/core-turn-bridge.ts +54 -6
  329. package/src/acp/stderr-summary.ts +49 -0
  330. package/src/agent/delegate-hint.ts +16 -0
  331. package/src/agent/monad-agent-turn.ts +1 -0
  332. package/src/agent/runner.ts +82 -2
  333. package/src/agent/task-notification.ts +56 -10
  334. package/src/agent/terminal-surface.ts +217 -0
  335. package/src/agent/types.ts +4 -0
  336. package/src/agent-substrate/pr-reviewer.ts +64 -4
  337. package/src/agent-substrate/review-intent.ts +29 -2
  338. package/src/agent-substrate/review-observation.ts +3 -0
  339. package/src/agent-substrate/self-review-cli.ts +490 -26
  340. package/src/autopilot/lineage/sources.ts +1 -1
  341. package/src/autopilot/mission-codebase-gate.ts +141 -12
  342. package/src/autopilot/pr-manager.ts +89 -18
  343. package/src/boot/daemon-runtime.ts +35 -3
  344. package/src/boot/daemon-tools/pty-shell.ts +2 -1
  345. package/src/boot/daemon-tools/self-implement.ts +1 -0
  346. package/src/budget/run-usage-rollup.ts +12 -7
  347. package/src/budget/unified-usage.ts +20 -0
  348. package/src/budget/usage-outcomes.ts +8 -4
  349. package/src/capture/tui-self-report.ts +132 -1
  350. package/src/chat/goal-continue-verdict.ts +41 -0
  351. package/src/chat/index.ts +30 -4
  352. package/src/chat/internal-turn-origin.ts +1 -0
  353. package/src/chat/paste-fold.ts +86 -0
  354. package/src/chat/tool-render/block.ts +32 -0
  355. package/src/chat/tool-render/dispatch.ts +2 -20
  356. package/src/chat/tool-render/result-text.ts +98 -0
  357. package/src/chat/turn-typeahead.ts +70 -7
  358. package/src/cli/autopilot-cli.ts +24 -9
  359. package/src/cli/config-audit.ts +119 -0
  360. package/src/cli/decisions-cli.ts +7 -4
  361. package/src/cli/doctor-cli.ts +137 -6
  362. package/src/cli/guardian-cli.ts +10 -0
  363. package/src/cli/herdr-cli.ts +34 -0
  364. package/src/cli/light-entry-route.ts +6 -3
  365. package/src/cli/log-event-names.ts +2 -0
  366. package/src/cli/logs-cli.ts +357 -2
  367. package/src/cli/make-cli.ts +247 -11
  368. package/src/cli/memory-cli.ts +30 -1
  369. package/src/cli/msg-cli.ts +132 -14
  370. package/src/cli/pr-cli.ts +29 -16
  371. package/src/cli/pr-granularity.ts +5 -3
  372. package/src/cli/pr-land-base-read.ts +11 -2
  373. package/src/cli/pr-land-heavy-remote.ts +6 -3
  374. package/src/cli/pr-land-overlap-evidence.ts +23 -4
  375. package/src/cli/pr-land-recovery.ts +117 -1
  376. package/src/cli/pty-takeover-cli.ts +8 -7
  377. package/src/cli/release-checklist-read-cli.ts +109 -4
  378. package/src/cli/release-cli.ts +64 -15
  379. package/src/cli/release-single-flight.ts +1 -1
  380. package/src/cli/self-update.ts +23 -5
  381. package/src/cli/self-utterances-cli.ts +13 -16
  382. package/src/cli/tasks-card-show.ts +162 -0
  383. package/src/cli/tasks-cli.ts +868 -352
  384. package/src/cli/tasks-read-cli.ts +197 -0
  385. package/src/cli/usage-cli.ts +12 -10
  386. package/src/context-bus/claude-memory-import.ts +99 -0
  387. package/src/context-bus/long-term-memory.ts +125 -0
  388. package/src/core-turn/run-core-turn.ts +4 -2
  389. package/src/core-turn/run-goal-loop.ts +76 -16
  390. package/src/core-turn/types.ts +8 -1
  391. package/src/dashboard/chat/acp-chat.ts +9 -0
  392. package/src/dashboard/context/keys.ts +8 -31
  393. package/src/dashboard/index.ts +299 -62
  394. package/src/dashboard/input/agent-wake.ts +50 -1
  395. package/src/dashboard/input/chat-main-acp-dispatch.ts +21 -1
  396. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +146 -3
  397. package/src/dashboard/input/chat-main-slash-command.ts +4 -2
  398. package/src/dashboard/input/goal-continue.ts +210 -0
  399. package/src/dashboard/input/goal-interim.ts +2 -0
  400. package/src/dashboard/input/internal-turn.ts +2 -8
  401. package/src/dashboard/input/seat-autowake.ts +9 -7
  402. package/src/dashboard/input/turn-autoheal.ts +52 -0
  403. package/src/dashboard/replay-preview.ts +25 -0
  404. package/src/dashboard/seat-boot-preamble.ts +132 -5
  405. package/src/dashboard/slash-runtime/chat-persona.ts +65 -8
  406. package/src/dashboard/slash-runtime/dashboard-handlers.ts +20 -10
  407. package/src/dashboard/slash-runtime/model-choices.ts +15 -0
  408. package/src/dashboard/stale-install-check.ts +3 -99
  409. package/src/dashboard/synchronized-frame-output.ts +74 -0
  410. package/src/debug/batch-queue.ts +119 -0
  411. package/src/debug/tui-log-tag.ts +67 -0
  412. package/src/display/agent-surface.ts +7 -0
  413. package/src/display/coordinator.ts +45 -12
  414. package/src/display/resize-listener.ts +41 -20
  415. package/src/display/synchronized-output-region.ts +60 -0
  416. package/src/domains/standalone-log-sink.ts +15 -2
  417. package/src/domains/surface-events.ts +80 -1
  418. package/src/esc-abort-gate.ts +69 -0
  419. package/src/exec-requests/planner.ts +37 -2
  420. package/src/execution-loop/launch-gate.ts +4 -3
  421. package/src/git-fs/cli-stderr.ts +45 -0
  422. package/src/git-fs/gh-cli.ts +6 -3
  423. package/src/git-fs/git-cli.ts +11 -5
  424. package/src/git-fs/worktree.ts +95 -1
  425. package/src/graph-runner/graph-cli.ts +44 -2
  426. package/src/graph-runner/graph-run-api.ts +3 -2
  427. package/src/graph-runner/runner.ts +37 -16
  428. package/src/graph-wizard/generate.ts +131 -4
  429. package/src/graph-wizard/steps.ts +15 -0
  430. package/src/grounding/proactive-ground.ts +86 -0
  431. package/src/harness/control-inbox.ts +49 -1
  432. package/src/harness/harness-cli-command.ts +230 -40
  433. package/src/harness/harness-incidents.ts +52 -1
  434. package/src/harness/pod-control-send.ts +33 -5
  435. package/src/harness/review-adapter.ts +26 -6
  436. package/src/harness/self-send-remote.ts +69 -0
  437. package/src/harness/self-send-routing-guard.ts +6 -0
  438. package/src/harness/self-send-target.ts +4 -3
  439. package/src/index.ts +443 -25
  440. package/src/input-core/context-key-runtime.ts +21 -0
  441. package/src/instance/test-write-guard-real-transport.fixture.ts +52 -0
  442. package/src/light-cli.ts +6 -1
  443. package/src/llm/route-decision.ts +13 -0
  444. package/src/llm-tool-name.ts +37 -0
  445. package/src/llm-tool-schema.ts +35 -0
  446. package/src/llm-wellformed.ts +70 -0
  447. package/src/llm.ts +158 -15
  448. package/src/loops/checker.ts +100 -0
  449. package/src/loops/consensus.ts +26 -2
  450. package/src/loops/loop-cli.ts +9 -4
  451. package/src/loops/msg-wake.ts +35 -39
  452. package/src/loops/orchestrator/anomaly-cluster.ts +243 -0
  453. package/src/loops/orchestrator/inbox.ts +59 -11
  454. package/src/loops/orchestrator/knowhow-pack.ts +364 -0
  455. package/src/loops/orchestrator/tick.ts +54 -5
  456. package/src/maturity/feature-maturity.ts +1 -1
  457. package/src/model-tier/llm-tier-map.ts +12 -17
  458. package/src/models/prompts.ts +17 -2
  459. package/src/msg/msg-post-office.ts +116 -0
  460. package/src/msg/msg-store.ts +17 -0
  461. package/src/mss/logging/log-store.ts +79 -22
  462. package/src/native-tool-catalog.ts +1 -1
  463. package/src/nexus/api/decisions-route.ts +38 -18
  464. package/src/nexus/api/graph-wizard-api.ts +46 -3
  465. package/src/nexus/api/grid.ts +24 -4
  466. package/src/nexus/api/http-server.ts +1 -1
  467. package/src/nexus/api/ops-api.ts +14 -6
  468. package/src/nexus/boot/register-mcp-clients.ts +263 -38
  469. package/src/nexus/onboarding/first-boot-wizard.ts +56 -8
  470. package/src/nexus/state/state.ts +7 -1
  471. package/src/oauth/codex-account-store.ts +34 -1
  472. package/src/onboarding/first-run.ts +37 -6
  473. package/src/onboarding/web-first.ts +43 -11
  474. package/src/ops/loops-map.ts +46 -0
  475. package/src/ops/overview-cache.ts +22 -4
  476. package/src/ops/overview-collect.ts +12 -6
  477. package/src/ops/overview.ts +44 -8
  478. package/src/persona/loader.ts +11 -0
  479. package/src/persona/types.ts +8 -0
  480. package/src/policy/llm-policy.ts +3 -1
  481. package/src/prompt-enhance/enhance.ts +4 -4
  482. package/src/prompt-library/session-guidance.ts +14 -0
  483. package/src/provider-summary.ts +8 -0
  484. package/src/pty-shell/availability.ts +7 -0
  485. package/src/pty-shell/herdr-agent-report.ts +155 -37
  486. package/src/pty-shell/herdr-prompt.ts +266 -0
  487. package/src/pty-shell/herdr-prune-stale.ts +17 -0
  488. package/src/pty-shell/herdr-sequence-lease.ts +60 -0
  489. package/src/pty-shell/pty-control-ipc.ts +327 -15
  490. package/src/pty-shell/pty-special-keys.ts +42 -2
  491. package/src/pty-shell/registry.ts +25 -15
  492. package/src/pty-shell/stale-install-check.ts +99 -0
  493. package/src/pty-shell/tui-run-state.ts +249 -3
  494. package/src/release-loop/auto-start.ts +20 -2
  495. package/src/release-loop/checklist.ts +126 -9
  496. package/src/release-loop/feature-store.ts +9 -9
  497. package/src/release-loop/landed-but-yellow.ts +93 -12
  498. package/src/release-loop/rehearsal.ts +36 -20
  499. package/src/repl/index.ts +27 -1
  500. package/src/seat-loop/knowhow-lint.ts +1 -1
  501. package/src/seat-loop/seat-report.ts +1 -0
  502. package/src/self-dev/ask-launch-flow.ts +86 -10
  503. package/src/self-dev/decompose-proposal.ts +183 -20
  504. package/src/self-dev/decompose.ts +61 -0
  505. package/src/self-dev/dev-cli.ts +37 -3
  506. package/src/self-dev/dev-pipeline.ts +37 -9
  507. package/src/self-dev/draft-sweep.ts +241 -16
  508. package/src/self-dev/draft-triage-rules.ts +50 -5
  509. package/src/self-dev/glm-credential-guard.ts +77 -0
  510. package/src/self-dev/graph-journey-nodes.ts +1 -0
  511. package/src/self-dev/graph-journey-route.ts +12 -2
  512. package/src/self-dev/orchestrate-cli.ts +68 -3
  513. package/src/self-dev/orchestrate.ts +116 -17
  514. package/src/self-dev/review-provider-fallback.ts +45 -7
  515. package/src/self-dev/run-supervisor.ts +55 -2
  516. package/src/self-dev/run-types.ts +1 -1
  517. package/src/self-dev/shard-plan.ts +48 -0
  518. package/src/self-dev/shard-run.ts +50 -3
  519. package/src/self-health/autoheal.ts +153 -0
  520. package/src/self-health/signatures.ts +6 -0
  521. package/src/self-implement/device-first.ts +116 -0
  522. package/src/self-implement/doctor-visit.ts +322 -1
  523. package/src/self-implement/evidence-command-budget.ts +80 -0
  524. package/src/self-implement/gate-artifacts.ts +6 -2
  525. package/src/self-implement/gate-baseline.ts +64 -1
  526. package/src/self-implement/gate-cli.ts +93 -9
  527. package/src/self-implement/gate-remote.ts +28 -4
  528. package/src/self-implement/gate-scope.ts +13 -1
  529. package/src/self-implement/goal-author-cli.ts +1 -0
  530. package/src/self-implement/goal-author-decompose.ts +265 -4
  531. package/src/self-implement/goal-author.ts +366 -26
  532. package/src/self-implement/goal-elaborate.ts +176 -22
  533. package/src/self-implement/goal-refine.ts +3 -0
  534. package/src/self-implement/goal-supervisor-fill.ts +75 -26
  535. package/src/self-implement/graph-variant.ts +40 -6
  536. package/src/self-implement/headless-elanous-driver.ts +19 -3
  537. package/src/self-implement/importer-test-index.ts +215 -2
  538. package/src/self-implement/knowhow-pack.ts +5 -5
  539. package/src/self-implement/off-diff-evidence.ts +58 -6
  540. package/src/self-implement/orchestrator.ts +536 -42
  541. package/src/self-implement/pod-warm-pool-profile.ts +1 -0
  542. package/src/self-implement/pwa-import-graph.ts +1 -1
  543. package/src/self-implement/review-round-brief.ts +300 -0
  544. package/src/self-implement/rework-policy.ts +44 -0
  545. package/src/self-implement/run-ledger.ts +278 -6
  546. package/src/self-implement/run-stop.ts +1 -1
  547. package/src/self-implement/run-ttl.ts +38 -24
  548. package/src/self-implement/running-runs.ts +17 -3
  549. package/src/self-implement/scope-adjacency.ts +3 -1
  550. package/src/self-implement/seams.ts +72 -10
  551. package/src/self-implement/stop-autoheal.ts +1 -0
  552. package/src/self-implement/test-seams.ts +13 -1
  553. package/src/self-implement/train-reach-grouping.ts +8 -2
  554. package/src/self-implement/wiring-check.ts +358 -0
  555. package/src/session/chat.ts +7 -1
  556. package/src/session/id-prefix.ts +60 -0
  557. package/src/session/index.ts +4 -0
  558. package/src/session-runtime/index.ts +9 -1
  559. package/src/shell-env-bootstrap.ts +11 -4
  560. package/src/skills/runner.ts +4 -2
  561. package/src/skills/tools/agent.ts +290 -48
  562. package/src/skills/tools/pty.ts +5 -0
  563. package/src/skills/tools/schedule-wakeup.ts +23 -4
  564. package/src/skills/tools/shell.ts +61 -6
  565. package/src/skills/tools/terminal-modal-inject.ts +1 -2
  566. package/src/skills/tools/terminal-modal.ts +10 -8
  567. package/src/skills/url-router.ts +41 -1
  568. package/src/smart-wizard/run.ts +66 -0
  569. package/src/status/bar.ts +34 -6
  570. package/src/status/metrics.ts +12 -1
  571. package/src/status/status-provider-info.ts +37 -6
  572. package/src/steward/rejudge-tick.ts +22 -7
  573. package/src/steward/resync-tick.ts +31 -4
  574. package/src/steward/ta-repair-event-collect.ts +17 -6
  575. package/src/task-agent/actions.ts +202 -5
  576. package/src/task-agent/boundary-proof-mapping.ts +12 -0
  577. package/src/task-agent/boundary-proof-producer.ts +147 -0
  578. package/src/task-agent/completion-evidence.ts +2 -1
  579. package/src/task-agent/green-close-recipe.ts +239 -0
  580. package/src/task-agent/green-sweep.ts +64 -10
  581. package/src/task-agent/land-queue.ts +21 -8
  582. package/src/task-agent/live-moves.ts +70 -9
  583. package/src/task-agent/map-host-adapter.ts +134 -0
  584. package/src/task-agent/map-reduce.ts +158 -0
  585. package/src/task-agent/map-run-ledger.ts +226 -0
  586. package/src/task-agent/mission.ts +30 -0
  587. package/src/task-agent/parent-host.ts +21 -11
  588. package/src/task-agent/rejudge-on-head.ts +87 -5
  589. package/src/task-agent/repair-cycle.ts +179 -32
  590. package/src/task-agent/repair-next-move.ts +42 -4
  591. package/src/task-agent/repair-outcomes.ts +29 -0
  592. package/src/task-agent/repair-worker.ts +14 -4
  593. package/src/task-agent/review-prior-fix.ts +12 -2
  594. package/src/task-agent/shadow.ts +229 -8
  595. package/src/task-agent/task-card-prefix.ts +2 -0
  596. package/src/task-agent/task-hand.ts +630 -30
  597. package/src/task-agent/task-parent-role-llm.ts +45 -0
  598. package/src/task-agent/tier-split.ts +80 -10
  599. package/src/task-agent/work-order.ts +53 -2
  600. package/src/task-orchestrator/dispatcher.ts +46 -1
  601. package/src/task-orchestrator/generator-prompt.ts +6 -0
  602. package/src/task-orchestrator/surfaces/pod-account-broker.ts +9 -0
  603. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +16 -6
  604. package/src/task-orchestrator/surfaces/pod-child-reuse.ts +146 -0
  605. package/src/task-orchestrator/surfaces/pod-command-job.ts +86 -5
  606. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +215 -3
  607. package/src/task-orchestrator/surfaces/pod-launch-history.ts +133 -0
  608. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +8 -6
  609. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +97 -0
  610. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +11 -0
  611. package/src/task-orchestrator/surfaces/pod-pool.ts +126 -8
  612. package/src/task-orchestrator/surfaces/pod-provenance.ts +8 -2
  613. package/src/task-orchestrator/surfaces/pod-repair-commit.ts +18 -3
  614. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +16 -0
  615. package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +224 -0
  616. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +201 -0
  617. package/src/task-orchestrator/surfaces/pod-si-warm-provider.ts +444 -0
  618. package/src/task-orchestrator/surfaces/pod-si-warm-runner.ts +387 -0
  619. package/src/task-orchestrator/surfaces/pod-si-warm-transport.ts +157 -0
  620. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +4 -0
  621. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +491 -36
  622. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +3 -0
  623. package/src/task-orchestrator/surfaces/self-implement-pod.ts +612 -54
  624. package/src/task-orchestrator/surfaces/self-implement.ts +46 -2
  625. package/src/testing/linux-env.ts +177 -0
  626. package/src/tool-runtime/index.ts +15 -2
  627. package/src/tool-runtime/mcp-proxy-bootstrap.ts +29 -0
  628. package/src/tty-foreground.ts +155 -0
  629. package/src/tui/chat/goal-interim.ts +177 -0
  630. package/src/tui/chat/log-view.ts +205 -18
  631. package/src/tui/chat/self-health-status.ts +232 -0
  632. package/src/tui/entry.ts +623 -80
  633. package/src/tui/input/at-picker.ts +55 -0
  634. package/src/tui/input/composer.ts +8 -1
  635. package/src/tui/slash/compact-command.ts +7 -0
  636. package/src/tui/slash/compact.ts +1 -7
  637. package/src/tui/slash/resume.ts +98 -0
  638. package/src/tui/slash/signals.ts +114 -0
  639. package/src/tui/slash/term-next.ts +71 -0
  640. package/src/tui-client/local-chat-turn.ts +49 -5
  641. package/src/tui-client/next-dashboard-runtime.ts +8 -0
  642. package/src/tui-client/next-loop-command.ts +70 -0
  643. package/src/tui-client/next-wakeup.ts +191 -0
  644. package/src/tui.ts +37 -0
  645. package/src/ui/modal-adapter.ts +2 -2
  646. package/src/user-config.ts +19 -1
  647. package/src/ux-sim/boot-daemon-tools-pty-shell-device.ts +136 -0
  648. package/src/ux-sim/classic-tui-seat-scenarios.ts +670 -0
  649. package/src/ux-sim/cli-config-audit-device.ts +121 -0
  650. package/src/ux-sim/dashboard-event-loop-stall-monitor-device.ts +238 -0
  651. package/src/ux-sim/event-monkey.ts +3 -2
  652. package/src/ux-sim/fake-bin.ts +45 -0
  653. package/src/ux-sim/fake-gh.ts +174 -0
  654. package/src/ux-sim/fake-herdr.ts +238 -0
  655. package/src/ux-sim/fake-kubectl.ts +142 -0
  656. package/src/ux-sim/fake-llm.ts +116 -6
  657. package/src/ux-sim/fault-glm-no-credential.ts +116 -0
  658. package/src/ux-sim/fault-nextmove-dispatch.ts +102 -1
  659. package/src/ux-sim/fault-scope-escape-lift.ts +33 -6
  660. package/src/ux-sim/fault-tui-400-autoheal.ts +297 -0
  661. package/src/ux-sim/goal-device.ts +619 -0
  662. package/src/ux-sim/in-process-cli.ts +22 -5
  663. package/src/ux-sim/mock-authoring-first-run-child.ts +35 -0
  664. package/src/ux-sim/mock-authoring-first-run.ts +97 -0
  665. package/src/ux-sim/mock-seat-pty-frame-child.ts +29 -0
  666. package/src/ux-sim/mock-seat-pty-frame.ts +297 -0
  667. package/src/ux-sim/mock-seat-pty-sequence-child.ts +21 -0
  668. package/src/ux-sim/mock-seat-pty-sequence.ts +206 -0
  669. package/src/ux-sim/next-tui-seat-scenarios.ts +749 -0
  670. package/src/ux-sim/onboarding-first-run-device.ts +269 -0
  671. package/src/ux-sim/pty-key-modifiers-device.ts +85 -0
  672. package/src/ux-sim/resume-picker-device.ts +173 -0
  673. package/src/ux-sim/session-id-seed.ts +60 -0
  674. package/src/ux-sim/skills-tools-shell-device.ts +156 -0
  675. package/src/ux-sim/subagent-tools-device.ts +81 -0
  676. package/src/ux-sim/task-agent-parent-host-device.ts +264 -0
  677. package/src/ux-sim/task-agent-rejudge-on-head-device.ts +114 -0
  678. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +250 -0
  679. package/src/ux-sim/tty-foreground-steal-child.ts +21 -0
  680. package/src/version/packed-revision.json +1 -1
  681. package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +0 -41
  682. package/apps/pwa/out/_next/static/chunks/1674.2a65fd5668e1cc5f.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +0 -24
  684. package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +0 -74
  685. package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/1993-c0007b7ad0c0ef41.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/1c735de4.f993a30bbd3c57c4.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +0 -148
  694. package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/2625.5d870aa999f33db1.js +0 -34
  696. package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +0 -77
  697. package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +0 -62
  699. package/apps/pwa/out/_next/static/chunks/3103.0df8da390948bb84.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +0 -90
  701. package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/3589.5444a06bcf6e775c.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +0 -36
  705. package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/3677-4215f826f6aa68e5.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +0 -79
  708. package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/4346.8601952e73bf5803.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +0 -286
  712. package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +0 -24
  715. package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/5154.a118f3957ed14e36.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +0 -23
  724. package/apps/pwa/out/_next/static/chunks/5637.281e5dec4ea6ecf1.js +0 -94
  725. package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/56d372f2.681ab4ec4c998fae.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +0 -287
  729. package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +0 -8
  736. package/apps/pwa/out/_next/static/chunks/630.fe5a46428d63b013.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +0 -27
  739. package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +0 -93
  741. package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/6b89c8bd.24df687a820500b3.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +0 -149
  747. package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +0 -104
  748. package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/8219.baa715d1deee80e2.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/8256.e3ac8421a71f82f4.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +0 -226
  758. package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +0 -64
  760. package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/8637.47f5b35afcae5e6b.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/8714.ff0b7ce3ec3e3ae2.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +0 -115
  767. package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/967-2aa39b2d04b4c690.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +0 -1
  779. package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +0 -1
  780. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +0 -1
  781. package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +0 -1
  782. package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +0 -1
  783. package/apps/pwa/out/_next/static/chunks/app/control/page-406b47745b53f269.js +0 -1
  784. package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +0 -1
  785. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +0 -1
  786. package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +0 -1
  787. package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +0 -1
  788. package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +0 -1
  789. package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +0 -1
  790. package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +0 -1
  791. package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +0 -1
  792. package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +0 -1
  793. package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +0 -1
  794. package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +0 -1
  795. package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +0 -1
  796. package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +0 -1
  797. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +0 -1
  798. package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +0 -1
  799. package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +0 -1
  800. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +0 -1
  801. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +0 -1
  802. package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +0 -1
  803. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +0 -1
  804. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +0 -1
  805. package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +0 -1
  806. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +0 -1
  807. package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +0 -1
  808. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +0 -1
  809. package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +0 -1
  810. package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +0 -1
  811. package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +0 -1
  812. package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +0 -1
  813. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +0 -1
  814. package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +0 -1
  815. package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +0 -1
  816. package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +0 -1
  817. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +0 -1
  818. package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +0 -1
  819. package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +0 -1
  820. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +0 -1
  821. package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +0 -1
  822. package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +0 -1
  823. package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +0 -1
  824. package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +0 -1
  825. package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +0 -1
  826. package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +0 -1
  827. /package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → 8kITumG9GAZ1LwT9POrAR}/_ssgManifest.js +0 -0
@@ -14,6 +14,7 @@ type ParseResult = Ledger[] | { error: Incomplete[]; ledgers: Ledger[] };
14
14
  const NON_PROGRESS_EVENTS = new Set(['progress-delivery-outcome']);
15
15
  const REEMIT_EXCLUDED_PREFIX = 'progress-delivery';
16
16
  type Emit = (category: string, event: string, data: Record<string, unknown>) => void;
17
+ export interface PodLedgerMeasurement { ledgerRead: boolean; activityMeasured: boolean }
17
18
  /** Heal-loop starter seam — defaults to the real `startHealLoop` inside `recordFailureEvent`. */
18
19
  type StartHealLoop = Parameters<typeof recordFailureEvent>[2];
19
20
 
@@ -174,7 +175,7 @@ export function createPodLedgerFollower(opts: {
174
175
  stallMinutes?: number;
175
176
  now?: () => number;
176
177
  onStall?: (message: string) => void;
177
- }): { poll(): void; readonly owned: boolean } {
178
+ }): { poll(): PodLedgerMeasurement; readonly owned: boolean } {
178
179
  const dir = opts.dir ?? runLedgerDir();
179
180
  const log = opts.log ?? defaultPodReemit();
180
181
  const emit: Emit = opts.emit ?? defaultPodReemit();
@@ -208,17 +209,17 @@ export function createPodLedgerFollower(opts: {
208
209
  return {
209
210
  get owned() { return owned; },
210
211
  poll() {
211
- if (disabled) return;
212
+ if (disabled) return { ledgerRead: true, activityMeasured: false };
212
213
  if (!owned && existsSync(path)) {
213
214
  disabled = true;
214
215
  log('self-implement.pod', 'ledger-live-skipped', { runId: opts.runId, reason: 'host-ledger-exists' });
215
- return;
216
+ return { ledgerRead: true, activityMeasured: false };
216
217
  }
217
218
  const since = `${Math.floor(lastActivityMeasuredAt / 1000)}.${String(lastActivityMeasuredAt % 1000).padStart(3, '0')}`;
218
219
  const measurementStartedAt = now();
219
220
  const until = `${Math.floor(measurementStartedAt / 1000)}.${String(measurementStartedAt % 1000).padStart(3, '0')}`;
220
221
  const r = opts.exec(`s="\${ELANOUS_STATE_DIR:-$HOME/.elanous}"; f="$s/run-ledger/${opts.runId}.jsonl"; w="$s/worktrees"; if [ -f "$f" ]; then tail -c +${offset + 1} "$f" || exit 1; fi; target=''; matches=0; for tree in "$w"/*/*.worktrees/*; do [ -e "$tree/.git" ] || continue; owner=$(git -C "$tree" config --worktree --get elanous.harness.owner 2>/dev/null) || continue; [ "$owner" = 'dev:${opts.runId}' ] || continue; target="$tree"; matches=$((matches + 1)); done; if [ "$matches" -eq 1 ]; then activity=$(find "$target" -type d \\( -name .git -o -name node_modules \\) -prune -o -type f -newermt '@${since}' ! -newermt '@${until}' -printf . 2>/dev/null) && printf '\\nELANOUS_ACTIVITY %s\\n' "\${#activity}" || printf '\\nELANOUS_ACTIVITY_ERROR\\n'; else printf '\\nELANOUS_ACTIVITY_ERROR\\n'; fi`);
221
- if (r.status !== 0) { log('self-implement.pod', 'ledger-live-unavailable', { runId: opts.runId, status: r.status, stderr: r.stderr.trim().slice(0, 200) }); checkStall(false, false); return; }
222
+ if (r.status !== 0) { log('self-implement.pod', 'ledger-live-unavailable', { runId: opts.runId, status: r.status, stderr: r.stderr.trim().slice(0, 200) }); checkStall(false, false); return { ledgerRead: false, activityMeasured: false }; }
222
223
  const marker = r.stdout.lastIndexOf('\nELANOUS_ACTIVITY');
223
224
  const activityLine = marker < 0 ? '' : r.stdout.slice(marker + 1);
224
225
  const activityMatch = /^ELANOUS_ACTIVITY (0|[1-9]\d*)\n$/.exec(activityLine);
@@ -241,11 +242,11 @@ export function createPodLedgerFollower(opts: {
241
242
  }
242
243
  }
243
244
  }
244
- if (!ledgerBytes) { checkStall(true, activityMeasured); return; }
245
+ if (!ledgerBytes) { checkStall(true, activityMeasured); return { ledgerRead: true, activityMeasured }; }
245
246
  offset += Buffer.byteLength(ledgerBytes);
246
247
  const text = pending + ledgerBytes;
247
248
  const cut = text.lastIndexOf('\n');
248
- if (cut < 0) { pending = text; checkStall(true, activityMeasured); return; }
249
+ if (cut < 0) { pending = text; checkStall(true, activityMeasured); return { ledgerRead: true, activityMeasured }; }
249
250
  const complete = text.slice(0, cut + 1);
250
251
  pending = text.slice(cut + 1);
251
252
  mkdirSync(dir, { recursive: true });
@@ -278,6 +279,7 @@ export function createPodLedgerFollower(opts: {
278
279
  nextStallMinute = stallMinutes;
279
280
  }
280
281
  checkStall(true, activityMeasured);
282
+ return { ledgerRead: true, activityMeasured };
281
283
  },
282
284
  };
283
285
  }
@@ -1,3 +1,100 @@
1
+ import { mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+
4
+ /** Capture a failed Job against its recorded placement, never the caller's current kubectl context. */
5
+ export function captureFailedPodJobs(input: {
6
+ runId: string;
7
+ job: string;
8
+ childRunId?: string;
9
+ ledgerPath: string;
10
+ artifactDir: string;
11
+ kubectl: (host: string, args: readonly string[]) => { status: number | null; stdout: string; stderr: string };
12
+ record: (event: string, data: Record<string, unknown>) => void;
13
+ now?: () => number;
14
+ }): void {
15
+ const { runId, job, ledgerPath, artifactDir, kubectl, record } = input;
16
+ const capturedAt = new Date((input.now ?? Date.now)()).toISOString();
17
+ const base = { runId, job, capturedAt };
18
+ const finish = (outcome: 'collected' | 'failed' | 'vanished', reason: string, extra: Record<string, unknown> = {}) =>
19
+ record('pod-failure-capture', { ...base, ...extra, outcome, reason });
20
+ if (!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(job)) { finish('failed', 'job-invalid'); return; }
21
+ if (!/^[a-zA-Z0-9_-]+$/.test(runId)) { finish('failed', 'run-id-invalid'); return; }
22
+ let rows: Array<{ runId?: string; event?: string; data?: Record<string, unknown> }>;
23
+ try {
24
+ rows = readFileSync(ledgerPath, 'utf8').trim().split('\n').map(line => JSON.parse(line));
25
+ if (rows.some(row => !row || typeof row !== 'object' || Array.isArray(row))) throw new Error('invalid ledger row');
26
+ } catch { finish('failed', 'ledger-unavailable'); return; }
27
+ if (rows.some(row => row.runId !== runId)) { finish('failed', 'ledger-run-mismatch'); return; }
28
+ const placements = rows.filter(row => row.event === 'pod-job-applied' && row.data?.job === job).map(row => row.data!);
29
+ if (!placements.length || placements.some(p => !['host', 'context', 'namespace', 'childRunId'].every(key => typeof p[key] === 'string' && /^[a-zA-Z0-9][a-zA-Z0-9.-]*$/.test(p[key] as string))
30
+ || typeof p.jobUid !== 'string' || !/^[a-zA-Z0-9][a-zA-Z0-9-]*$/.test(p.jobUid))) {
31
+ finish('failed', 'placement-incomplete'); return;
32
+ }
33
+ const selected = input.childRunId ? placements.filter(p => p.childRunId === input.childRunId) : placements;
34
+ if (!selected.length) { finish('failed', 'placement-incomplete'); return; }
35
+ const first = selected[0]!;
36
+ if (placements.some(p => ['host', 'context', 'namespace'].some(key => p[key] !== first[key]))
37
+ || selected.some(p => ['childRunId', 'jobUid'].some(key => p[key] !== first[key]))) {
38
+ finish('failed', 'placement-conflict'); return;
39
+ }
40
+ const location = { host: first.host, context: first.context, namespace: first.namespace, childRunId: first.childRunId, jobUid: first.jobUid };
41
+ const evidenceDir = join(artifactDir, 'pod-failure-capture', runId, job, first.childRunId as string);
42
+ const previous = rows.find(row => row.event === 'pod-failure-capture' && row.data?.job === job && row.data?.outcome === 'collected'
43
+ && row.data.childRunId === first.childRunId && row.data.jobUid === first.jobUid
44
+ && row.data.host === first.host && row.data.context === first.context && row.data.namespace === first.namespace);
45
+ // A ledger row describes a prior collection; it does not guarantee that its files survived.
46
+ // Check all three expected paths before treating it as complete, then recapture any missing evidence.
47
+ if (previous && ([['jobEvidence', 'job.json'], ['podEvidence', 'pods.json'], ['logEvidence', 'child.log']] as const)
48
+ .every(([field, filename]) => {
49
+ const path = join(evidenceDir, filename);
50
+ if (previous.data?.[field] !== path) return false;
51
+ try { return statSync(path).isFile(); } catch { return false; }
52
+ })) return;
53
+ const args = ['--context', first.context as string, '-n', first.namespace as string] as const;
54
+ try {
55
+ const jobResult = kubectl(first.host as string, [...args, 'get', 'job', job, '-o', 'json']);
56
+ if (jobResult.status !== 0) {
57
+ finish(/\bNotFound\b|not found/i.test(jobResult.stderr) ? 'vanished' : 'failed',
58
+ /\bNotFound\b|not found/i.test(jobResult.stderr) ? 'job-not-found' : 'job-read-failed', location);
59
+ return;
60
+ }
61
+ const jobBody = JSON.parse(jobResult.stdout) as { metadata?: { name?: string; uid?: string } };
62
+ if (jobBody.metadata?.name !== job || jobBody.metadata.uid !== first.jobUid) { finish('failed', 'job-identity-mismatch', location); return; }
63
+ mkdirSync(evidenceDir, { recursive: true });
64
+ const save = (filename: string, bytes: string, sameJob?: (existing: string) => boolean): string => {
65
+ const path = join(evidenceDir, filename);
66
+ try { writeFileSync(path, bytes, { flag: 'wx', mode: 0o600 }); }
67
+ catch (error) {
68
+ if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;
69
+ const existing = readFileSync(path, 'utf8');
70
+ if (existing !== bytes && !sameJob?.(existing)) throw error;
71
+ }
72
+ return path;
73
+ };
74
+ const jobEvidence = save('job.json', jobResult.stdout, existing => {
75
+ try {
76
+ const metadata = (JSON.parse(existing) as { metadata?: { name?: string; uid?: string } }).metadata;
77
+ return metadata?.name === job && metadata.uid === first.jobUid;
78
+ } catch { return false; }
79
+ });
80
+ const podResult = kubectl(first.host as string, [...args, 'get', 'pods', '-l', `job-name=${job}`, '-o', 'json']);
81
+ if (podResult.status !== 0) { finish('failed', 'pods-read-failed', { ...location, jobEvidence }); return; }
82
+ const pods = JSON.parse(podResult.stdout) as { items?: Array<{ metadata?: { name?: string; ownerReferences?: Array<{ uid?: string }> } }> };
83
+ if (!pods.items?.length || pods.items.some(p => !p.metadata?.ownerReferences?.some(owner => owner.uid === jobBody.metadata?.uid))) {
84
+ finish('failed', 'pod-owner-mismatch', { ...location, jobEvidence }); return;
85
+ }
86
+ const podEvidence = save('pods.json', podResult.stdout);
87
+ const podName = pods.items[0]?.metadata?.name;
88
+ if (pods.items.length !== 1 || !podName || !/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(podName)) {
89
+ finish('failed', 'pod-ambiguous', { ...location, jobEvidence, podEvidence }); return;
90
+ }
91
+ const logs = kubectl(first.host as string, [...args, 'logs', `pod/${podName}`, '-c', 'child']);
92
+ if (logs.status !== 0) { finish('failed', 'logs-read-failed', { ...location, jobEvidence, podEvidence }); return; }
93
+ const logEvidence = save('child.log', logs.stdout);
94
+ finish('collected', 'job-failed', { ...location, jobEvidence, podEvidence, logEvidence });
95
+ } catch { finish('failed', 'capture-error', location); }
96
+ }
97
+
1
98
  const SECRET_FIELD = /token|secret|password|authorization|key/i;
2
99
  const SAFE_FIELD = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;
3
100
  const SECRET_VALUE = /(?:\b(?:bearer|basic)\s+\S+|\b(?:token|secret|password|authorization|api[-_]?key|access[-_]?key|private[-_]?key)\b\s*(?:is|[=:])\s*["']?\S+|\b(?:sk-[A-Za-z0-9_-]{8,}|gh[pousr]_[A-Za-z0-9_]{8,}))\b/i;
@@ -12,6 +12,17 @@ export function stablePodManifestText(applied: Array<Record<string, any>>): stri
12
12
  let snapshots = 0;
13
13
  for (const manifest of manifests) {
14
14
  if (manifest.kind !== 'Job') continue;
15
+ // POD-LAUNCH-PROVENANCE — the request time and the 8-char run/parent labels are per launch like the run id.
16
+ for (const meta of [manifest.metadata, manifest.spec?.template?.metadata]) {
17
+ for (const bag of [meta?.labels, meta?.annotations]) {
18
+ if (!bag) continue;
19
+ if (bag['elanous.ai/requested-at'] !== undefined) bag['elanous.ai/requested-at'] = '<requested-at>';
20
+ if (meta?.labels === bag) for (const key of ['elanous.ai/run', 'elanous.ai/parent']) if (bag[key] !== undefined) bag[key] = '<run-label>';
21
+ }
22
+ }
23
+ for (const container of manifest.spec?.template?.spec?.containers ?? []) {
24
+ for (const entry of container.env ?? []) if (entry.name === 'ELANOUS_POD_REQUESTED_AT') entry.value = '<requested-at>';
25
+ }
15
26
  for (const container of manifest.spec?.template?.spec?.containers ?? []) {
16
27
  for (const entry of container.env ?? []) {
17
28
  if (entry.name !== BUDGET_SNAPSHOT_ENV) continue;
@@ -89,14 +89,29 @@ function defaultLocalImageInspect(image: string): { status: number | null; stdou
89
89
  return { status: r.status, stdout: r.stdout ?? '' };
90
90
  }
91
91
 
92
+ /** 레지스트리 안 이미지 이름 — `docker/harness/build.sh` 의 full/lite 규칙 그대로. */
93
+ function podRegistryImageName(image: string): string {
94
+ return image === 'elanous-harness-lite:local' ? 'elanous-harness-lite' : 'elanous-harness';
95
+ }
96
+
97
+ /** 레지스트리 태그 = 커밋 앞 12자리 (build.sh:295 와 같은 규칙). */
98
+ function podRegistryTag(commit: string): string {
99
+ return commit.slice(0, 12);
100
+ }
101
+
102
+ /** 노드 로컬 레지스트리의 HTTP 포트 — 호스트에서는 같은 포트의 localhost 로 조회한다. */
103
+ function memberRegistryPort(member: PodPoolMember): string {
104
+ const registry = memberRegistry(member);
105
+ return registry.slice(registry.lastIndexOf(':') + 1);
106
+ }
107
+
92
108
  /** 이 커밋의 이미지가 노드 레지스트리에 있나 — 있으면 클러스터 안 이미지 주소. */
93
109
  export function registryImageRef(member: PodPoolMember, commit: string | null, run: RemoteRun = defaultRemoteRun, image = 'elanous-harness:local'): string | null {
94
110
  if (!member.sshHost || !commit) return null;
95
- const imageName = image === 'elanous-harness-lite:local' ? 'elanous-harness-lite' : 'elanous-harness';
96
- const tag = commit.slice(0, 12);
111
+ const imageName = podRegistryImageName(image);
112
+ const tag = podRegistryTag(commit);
97
113
  const registry = memberRegistry(member);
98
- const port = registry.slice(registry.lastIndexOf(':') + 1);
99
- const r = run(member.sshHost, `curl -fsS --max-time 5 http://localhost:${port}/v2/${imageName}/tags/list 2>/dev/null`);
114
+ const r = run(member.sshHost, `curl -fsS --max-time 5 http://localhost:${memberRegistryPort(member)}/v2/${imageName}/tags/list 2>/dev/null`);
100
115
  if (r.status !== 0) return null;
101
116
  try {
102
117
  const tags = (JSON.parse(r.stdout) as { tags?: string[] }).tags ?? [];
@@ -104,6 +119,54 @@ export function registryImageRef(member: PodPoolMember, commit: string | null, r
104
119
  } catch { return null; }
105
120
  }
106
121
 
122
+ /** 레지스트리 HTTP 한 번 — 노드에서 `curl -fsS --max-time 5`(registryImageRef 와 같은 규칙). 실패면 null. */
123
+ function registryHttpGet(member: PodPoolMember, path: string, run: RemoteRun, accept?: string): string | null {
124
+ if (!member.sshHost) return null;
125
+ const header = accept ? `-H 'Accept: ${accept}' ` : '';
126
+ const r = run(member.sshHost, `curl -fsS --max-time 5 ${header}http://localhost:${memberRegistryPort(member)}/v2/${path} 2>/dev/null`);
127
+ return r.status === 0 && r.stdout.trim() ? r.stdout : null;
128
+ }
129
+
130
+ function registryLabelValue(raw: unknown): string | null {
131
+ return typeof raw === 'string' && raw.trim() && raw !== '<no value>' ? raw.trim() : null;
132
+ }
133
+
134
+ /**
135
+ * GATE-REGISTRY-IMAGE-FASTPATH (0.2.36): 레지스트리 HTTP 만으로 이 커밋 태그 이미지의 config label 을 읽는다 —
136
+ * 노드 Docker 데몬(`docker image inspect`)을 부르지 않는다. 태그 결손 · HTTP 오류 · manifest list(단일 config 없음) ·
137
+ * 비JSON 은 null 이다(판정하지 않고 종전 경로로 떨어진다).
138
+ * GET /v2/<이미지>/manifests/<커밋12> → config.digest → GET /v2/<이미지>/blobs/<digest> → config.Labels
139
+ */
140
+ export function registryImageLabels(member: PodPoolMember, image: string, commit: string | null, run: RemoteRun = defaultRemoteRun): { commit: string | null; skills: string | null } | null {
141
+ if (!member.sshHost || !commit) return null;
142
+ const imageName = podRegistryImageName(image);
143
+ const manifest = registryHttpGet(member, `${imageName}/manifests/${podRegistryTag(commit)}`, run, 'application/vnd.docker.distribution.manifest.v2+json');
144
+ if (!manifest) return null;
145
+ let digest: string | undefined;
146
+ try { digest = (JSON.parse(manifest) as { config?: { digest?: string } }).config?.digest; } catch { return null; }
147
+ if (!digest) return null;
148
+ // config digest 는 `sha256:<64 hex>` — 이 형태가 아니면 경로에 넣지 않는다.
149
+ if (!/^sha256:[0-9a-f]{64}$/u.test(digest)) return null;
150
+ const blob = registryHttpGet(member, `${imageName}/blobs/${digest}`, run);
151
+ if (!blob) return null;
152
+ let labels: Record<string, unknown> | undefined;
153
+ try { labels = (JSON.parse(blob) as { config?: { Labels?: Record<string, unknown> } }).config?.Labels; } catch { return null; }
154
+ if (!labels || typeof labels !== 'object') return null;
155
+ return { commit: registryLabelValue(labels['elanous.commit']), skills: registryLabelValue(labels['elanous.pod-skills']) };
156
+ }
157
+
158
+ /**
159
+ * 이 커밋 태그의 이미지 label 이 이번 발사 값과 모두 맞나 — 맞으면 Docker 조회 없이 그 판을 쓸 수 있다.
160
+ * 커밋 label 은 발사 커밋과 «정확히» 같아야 한다(태그가 다른 판을 가리키는 경우를 거른다).
161
+ * `localSkillsDigest` 가 없으면(모르는 값) 커밋 label 만 본다 — syncPoolImages 의 종전 skillsSame 과 같은 뜻.
162
+ */
163
+ export function registryImageLabelsMatch(member: PodPoolMember, image: string, commit: string | null, opts: { localSkillsDigest?: string | null; run?: RemoteRun } = {}): boolean {
164
+ if (!commit) return false;
165
+ const labels = registryImageLabels(member, image, commit, opts.run ?? defaultRemoteRun);
166
+ if (!labels || labels.commit !== commit) return false;
167
+ return opts.localSkillsDigest == null || labels.skills === opts.localSkillsDigest;
168
+ }
169
+
107
170
  /** IMAGE-ONE-SOURCE: 이 멤버의 노드에 레지스트리 컨테이너가 있나(syncPoolImages 의 판정과 같은 명령). 로컬 멤버는 false. */
108
171
  export function memberHasRegistry(member: PodPoolMember, run: RemoteRun = defaultRemoteRun): boolean {
109
172
  if (!member.sshHost) return false;
@@ -180,14 +243,27 @@ export function podWorkLabels(identity: PodWorkIdentity): Record<string, string>
180
243
  };
181
244
  }
182
245
 
183
- /** Minih standard-Job policy, independent of the configured pool member capacity. Not wired into allocation. */
246
+ /**
247
+ * MINIH-MODE (0.2.37) — where this pool's standard Jobs run: `home` (1 standard Job) or `external` (2).
248
+ * The location is declared explicitly by the launch (`minihLocationFrom` reads `ELANOUS_MINIH_LOCATION`); when it
249
+ * is absent the configured member capacities decide, exactly as before.
250
+ */
184
251
  export type MinihLocation = 'home' | 'external';
185
252
 
253
+ /** The declared location for a launch: `home` / `external` only. Absent, empty or unknown → null (configured capacity). */
254
+ export function minihLocationFrom(value: string | undefined | null): MinihLocation | null {
255
+ const normalized = value?.trim().toLowerCase();
256
+ return normalized === 'home' || normalized === 'external' ? normalized : null;
257
+ }
258
+
186
259
  export function minihStandardCapacity(location: MinihLocation): number {
187
260
  return location === 'home' ? 1 : 2;
188
261
  }
189
262
 
190
- /** A drain withholds new slots until occupancy falls to the target; it never evicts Running Pods. */
263
+ /**
264
+ * A drain withholds new slots until occupancy falls to the target; it never evicts Running Pods.
265
+ * `PodPoolScheduler.tryAcquire` applies this to new standard-Job admission when a location is declared.
266
+ */
191
267
  export function decideMinihDrain(location: MinihLocation, runningPods: number, pendingPods = 0): {
192
268
  capacity: number;
193
269
  runningPods: number;
@@ -519,6 +595,26 @@ export class PodPoolScheduler {
519
595
  recommended: Math.min(this.members.reduce((n, item) => n + item.capacity, 0), snapshots.reduce((n, item) => n + item.recommended, 0)),
520
596
  waiting: snapshots.flatMap((item) => item.waiting) };
521
597
  }
598
+ /**
599
+ * MINIH-MODE — withhold NEW standard-Job admission while the declared location has no free standard slot.
600
+ * Occupancy = the measured node-c Pods (Running ⊕ Pending; a Pending Pod already holds a slot) ⊕ this process's
601
+ * node-c inflight slots. Nothing here deletes, evicts or re-schedules a Pod: an excess above the location's capacity
602
+ * leaves only as those Pods finish, and until then new admissions wait. `lite` Jobs are not the standard
603
+ * admission this policy gates, and no declared location keeps the configured member capacities.
604
+ */
605
+ private minihHold(kind: PodPlacementKind | null, location: MinihLocation | null, reading: Record<string, MemberOccupancy>): { capacity: number; occupied: number; draining: boolean } | null {
606
+ if (!location || kind === 'lite') return null;
607
+ // A launch pool can contain node-b and WSL beside node-c. Their Pods do not occupy node-c's physical slots.
608
+ const minihMembers = this.members.filter((m) => m.capacity > 0 && (m.sshHost === 'node-c' || m.context === 'pool-node-c'));
609
+ if (minihMembers.length === 0) return null;
610
+ // Lite Jobs also hold a physical node-c slot while running, even though this policy never blocks their admission.
611
+ const inflight = minihMembers.reduce((count, m) => count + (this.inflight.get(m.context) ?? 0), 0);
612
+ // The measurement reports Running and Pending as one occupied count, and decideMinihDrain judges only their sum.
613
+ const occupied = minihMembers
614
+ .reduce((count, m) => count + (reading[m.context]?.occupied ?? 0), inflight);
615
+ const decision = decideMinihDrain(location, occupied);
616
+ return decision.availableSlots > 0 ? null : { capacity: decision.capacity, occupied, draining: decision.drainNewAdmissions };
617
+ }
522
618
  /**
523
619
  * Pick the member with the largest free share: (capacity − measured cluster occupancy − this process's inflight) / capacity.
524
620
  * POOL-SPREAD (10-06): comparing absolute free slots always picked the big member (node-b 25 vs node-c 4), so the small
@@ -530,9 +626,10 @@ export class PodPoolScheduler {
530
626
  * member the 0.2.15 gate launched its shards one at a time.
531
627
  * Ties keep the configured member order. Returns null when every readable member is full.
532
628
  */
533
- async tryAcquire(skip?: ReadonlySet<string>, onEmpty?: (reason: string) => void, mode: { selfCapped?: boolean; kind?: PodPlacementKind | null; onPlacement?: (placement: PodPlacement) => void; signal?: AbortSignal } = {}): Promise<PodPoolMember | null> {
629
+ async tryAcquire(skip?: ReadonlySet<string>, onEmpty?: (reason: string) => void, mode: { selfCapped?: boolean; kind?: PodPlacementKind | null; /** MINIH-MODE: a declared location gates new standard-Job admission (home 1 · external 2). */ minihLocation?: MinihLocation | null; onPlacement?: (placement: PodPlacement) => void; signal?: AbortSignal } = {}): Promise<PodPoolMember | null> {
534
630
  const selfCapped = mode.selfCapped === true;
535
631
  const kind = mode.kind ?? null;
632
+ const minihLocation = mode.minihLocation ?? null;
536
633
  // POOL-LITE: lite goals try the small member first, implementation goals the big one; full → overflow by free share.
537
634
  const preferred = new Set(preferredMembers(this.members, kind));
538
635
  let reading: Record<string, MemberOccupancy>;
@@ -545,6 +642,9 @@ export class PodPoolScheduler {
545
642
  }
546
643
  // A caller may abandon a slow occupancy read. Never acquire its lease after cancellation.
547
644
  if (mode.signal?.aborted) throw mode.signal.reason ?? new Error('pod pool acquisition aborted');
645
+ // MINIH-MODE: only node-c candidates are held. Other pool members retain their own configured capacity.
646
+ // Running/Pending Pods already in the pool stay exactly as they are.
647
+ const minihHeld = this.minihHold(kind, minihLocation, reading);
548
648
  const free: Record<string, number> = {};
549
649
  const measured: Record<string, boolean> = {};
550
650
  let best: { member: PodPoolMember; slots: number; measured: boolean; preferred: boolean } | null = null;
@@ -558,6 +658,10 @@ export class PodPoolScheduler {
558
658
  for (const m of this.members) {
559
659
  // A capacity-0 member is off — never chosen (and no division by zero in the share).
560
660
  if (m.capacity <= 0) continue;
661
+ if (minihHeld && (m.sshHost === 'node-c' || m.context === 'pool-node-c')) {
662
+ free[m.context] = 0;
663
+ continue;
664
+ }
561
665
  // LAUNCH-STALL: a member this launch cannot fit is skipped for this call only (other launches may fit it).
562
666
  if (skip?.has(m.context)) continue;
563
667
  const inflight = this.inflight.get(m.context) ?? 0;
@@ -572,7 +676,12 @@ export class PodPoolScheduler {
572
676
  if (better(cand)) best = cand;
573
677
  }
574
678
  if (!best) {
575
- onEmpty?.(`no free slot · free=${JSON.stringify(free)} · measured=${JSON.stringify(measured)}${selfCapped ? ' · selfCapped' : ''}${skip?.size ? ` · skipped=${[...skip].join(',')}` : ''}${kind ? ` · kind=${kind}` : ''}`);
679
+ if (minihHeld) {
680
+ const reason = `node-c 드레인: ${minihLocation} 표준 상한 ${minihHeld.capacity} · 점유 ${minihHeld.occupied}${minihHeld.draining
681
+ ? ' — 초과분이 빠질 때까지 새 입장 보류(기존 Pod 유지)' : ' — 상한이 찼다'}`;
682
+ debug.log('pod.pool', 'node-c-drain-hold', { location: minihLocation, capacity: minihHeld.capacity, occupied: minihHeld.occupied, draining: minihHeld.draining, kind });
683
+ onEmpty?.(reason);
684
+ } else onEmpty?.(`no free slot · free=${JSON.stringify(free)} · measured=${JSON.stringify(measured)}${selfCapped ? ' · selfCapped' : ''}${skip?.size ? ` · skipped=${[...skip].join(',')}` : ''}${kind ? ` · kind=${kind}` : ''}`);
576
685
  return null;
577
686
  }
578
687
  const chosen: { member: PodPoolMember; slots: number; measured: boolean; preferred: boolean } = best;
@@ -873,6 +982,15 @@ export async function syncPoolImages(members: readonly PodPoolMember[], image: s
873
982
  await Promise.all(members.map(async (m) => {
874
983
  const t0 = Date.now();
875
984
  if (!m.sshHost) { results.set(m.context, { ok: true, action: 'local', detail: 'this machine', ms: 0 }); return; }
985
+ // ⭐ GATE-REGISTRY-IMAGE-FASTPATH (0.2.36 · OP): 레지스트리 커밋 태그의 config label(commit ⊕ pod-skills)이 이번 발사
986
+ // 값과 같으면 노드 Docker 데몬을 «한 번도» 부르지 않고 그 커밋 ref 로 끝난다 — 데몬 조회가 느려도 gate 첫 Pod 이 뜬다.
987
+ // 태그 결손 · label 불일치 · HTTP 오류면 아래 종전 경로(원격 inspect → 노드 빌드 → 통째 전송)가 그대로 판정한다.
988
+ if (localCommit && registryImageLabelsMatch(m, image, localCommit, { ...(deps.localSkillsDigest !== undefined ? { localSkillsDigest: deps.localSkillsDigest } : {}), run })) {
989
+ const imageRef = `${memberRegistry(m)}/${podRegistryImageName(image)}:${podRegistryTag(localCommit)}`;
990
+ debug.log('pod.pool', 'image-fresh-registry-label', { context: m.context, host: m.sshHost, commit: localCommit, imageRef, skills: deps.localSkillsDigest ?? null, waitedMs: 0 });
991
+ results.set(m.context, { ok: true, action: 'fresh', detail: localCommit.slice(0, 12), ms: Date.now() - t0, imageRef });
992
+ return;
993
+ }
876
994
  const before = remoteImageCommit(m, image, run);
877
995
  const skillsNow = deps.localSkillsDigest;
878
996
  const refBefore = registryImageRef(m, localCommit, run, image);
@@ -17,6 +17,8 @@ export interface PodProvenance {
17
17
  commit?: string;
18
18
  shard?: string;
19
19
  reason?: string;
20
+ /** Parent runId / lease id — whose child this Pod is. Label keeps the first 8 characters like run/commit. */
21
+ parent?: string;
20
22
  pool?: string;
21
23
  cpuReq?: string;
22
24
  memReq?: string;
@@ -28,11 +30,15 @@ const required = ['actorKind', 'actor', 'kind', 'run', 'phase', 'requestedAt'] a
28
30
  const names: Record<keyof PodProvenance, string> = {
29
31
  actorKind: 'actor-kind', actor: 'actor', kind: 'kind', run: 'run', phase: 'phase', requestedAt: 'requested-at',
30
32
  character: 'character', launchHost: 'launch-host', entrance: 'entrance', graphNode: 'graph-node', cell: 'cell',
31
- version: 'version', commit: 'commit', shard: 'shard', reason: 'reason',
33
+ version: 'version', commit: 'commit', shard: 'shard', reason: 'reason', parent: 'parent',
32
34
  pool: 'pool', cpuReq: 'cpu-req', memReq: 'mem-req',
33
35
  warmReused: 'warm-reused', argv: 'argv',
34
36
  };
35
37
 
38
+ /** Every child env name the set can carry (`ELANOUS_POD_<KEY>`). */
39
+ export const POD_PROVENANCE_ENV_NAMES: readonly string[] = Object.values(names)
40
+ .map((name) => `ELANOUS_POD_${name.toUpperCase().replaceAll('-', '_')}`);
41
+
36
42
  const labelValue = (value: string): string => {
37
43
  const cleaned = value.toLowerCase().replace(/[^a-z0-9._-]/g, '-').replace(/^[^a-z0-9]+|[^a-z0-9]+$/g, '');
38
44
  return cleaned.slice(0, 63).replace(/[^a-z0-9]+$/g, '') || 'unknown';
@@ -67,7 +73,7 @@ export function podProvenanceMetadata(input: Partial<PodProvenance> | undefined,
67
73
  const annotations: Record<string, string> = {};
68
74
  const env: Array<{ name: string; value: string }> = [];
69
75
  for (const [name, value] of Object.entries(values)) {
70
- const label = name === 'run' || name === 'commit' ? value.slice(0, 8) : value;
76
+ const label = name === 'run' || name === 'commit' || name === 'parent' ? value.slice(0, 8) : value;
71
77
  if (name !== 'reason' && name !== 'argv') labels[`elanous.ai/${name}`] = labelValue(label);
72
78
  annotations[`elanous.ai/${name}`] = value;
73
79
  env.push({ name: `ELANOUS_POD_${name.toUpperCase().replaceAll('-', '_')}`, value });
@@ -3,6 +3,7 @@ import { execFileSync } from 'node:child_process';
3
3
  import { createHash } from 'node:crypto';
4
4
  import { mkdirSync, readFileSync, realpathSync, statSync, writeFileSync } from 'node:fs';
5
5
  import { isAbsolute, join, resolve } from 'node:path';
6
+ import { classifyGateEnvDeficit, GATE_ENV_DEFICIT_HARVESTABLE_MARK } from '../../self-implement/gate-env-retry.js';
6
7
 
7
8
  export const REPAIR_REF = 'refs/elanous/repair/result';
8
9
  export const REPAIR_BUNDLE_MAX_BYTES = 5 * 1024 * 1024;
@@ -39,15 +40,29 @@ function completedWorktree(output: string): { path: string; runId: string } {
39
40
  let value: Record<string, unknown>;
40
41
  try { value = JSON.parse(line) as Record<string, unknown>; } catch { continue; }
41
42
  if (value.kind === 'self' && value.result && typeof value.result === 'object') value = value.result as Record<string, unknown>;
42
- if (value.stage !== 'worktree-completed' || value.ok !== true || typeof value.worktreePath !== 'string'
43
+ const completed = value.stage === 'worktree-completed' && value.ok === true;
44
+ // The gate could not measure an environmental failure. Keep the implementation as a
45
+ // bundle for the pinned PR; the parent still has to review and rejudge that head.
46
+ const gate = value.gate && typeof value.gate === 'object' && !Array.isArray(value.gate)
47
+ ? value.gate as { passed?: unknown; log?: unknown; reflectGateFacts?: { introduced?: number; unknownReason?: string; childResponsibility?: string } }
48
+ : null;
49
+ const environmentHarvest = value.stage === 'gate-failed' && value.ok === false
50
+ && value.harvestable === true && typeof value.detail === 'string'
51
+ && value.detail.includes(GATE_ENV_DEFICIT_HARVESTABLE_MARK)
52
+ && gate?.passed === false
53
+ && gate.reflectGateFacts?.introduced === 0
54
+ && gate.reflectGateFacts?.childResponsibility === 'none'
55
+ && classifyGateEnvDeficit({ passed: false, ...(typeof gate.log === 'string' ? { log: gate.log } : {}),
56
+ ...(gate.reflectGateFacts ? { reflectGateFacts: gate.reflectGateFacts } : {}) }).envDeficit;
57
+ if ((!completed && !environmentHarvest) || typeof value.worktreePath !== 'string'
43
58
  || typeof value.runId !== 'string' || !value.runId)
44
- throw new Error('repair child final result is not a successful worktree-only result');
59
+ throw new Error('repair child final result is neither successful worktree-only nor environment-deficit harvestable');
45
60
  return { path: value.worktreePath, runId: value.runId };
46
61
  }
47
62
  throw new Error('repair child did not return a successful worktree-only result');
48
63
  }
49
64
 
50
- /** Called in the Pod after the child exits successfully and before artifact export. */
65
+ /** Called in the Pod after a successful child or a verified environment-deficit harvest. */
51
66
  export function writePodRepairCommit(input: { pr: number; baseHead: string; runId: string; output: string; repo: string; outbox: string }): PodRepairResult {
52
67
  if (!Number.isSafeInteger(input.pr) || input.pr < 1 || !SHA40.test(input.baseHead)) throw new Error('invalid repair PR or base head');
53
68
  if (!input.runId.trim()) throw new Error('repair parent run id missing');
@@ -0,0 +1,16 @@
1
+ /** Opt-in SI warm entry; the ordinary Pod spawn remains the default. */
2
+ import { podSelfImplementSpawn, type PodSpawnOptions } from './self-implement-pod.js';
3
+
4
+ export async function podSpawnWithSiWarm(base: PodSpawnOptions,
5
+ env: NodeJS.ProcessEnv = process.env) {
6
+ if (env.ELANOUS_SI_WARM_REUSE !== '1') return podSelfImplementSpawn(base);
7
+ const { acquireSiWarmChild, postprocessSiWarmChild } = await import('./pod-si-warm-host.js');
8
+ return podSelfImplementSpawn({ ...base,
9
+ siWarmAttempt: async input => {
10
+ const result = await acquireSiWarmChild(input, base);
11
+ return result.status === 'acquired' ? result.attempt : null;
12
+ },
13
+ siWarmHostPostprocess: (result, attempt, input) =>
14
+ postprocessSiWarmChild(input, result, attempt, base),
15
+ });
16
+ }