elanous 0.2.24 → 0.2.27

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 (601) 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/{Q-7iofoxOEv1WX18S35of → Ev2jivDMTSoEc-5rIXdcy}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/1027.a0f04663d24c2779.js +1 -0
  5. package/apps/pwa/out/_next/static/chunks/1038.676007ae505822e7.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1113.a37eadf7f740d955.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/112-fa7c526c20ce1405.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1144.5fa1fa1d48dbcd12.js +36 -0
  9. package/apps/pwa/out/_next/static/chunks/1146.80d15ea7c6e6ee95.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1157.f08bf2b70915e176.js +148 -0
  11. package/apps/pwa/out/_next/static/chunks/119b405e.8fdd0e44d1ff37aa.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/1296.04560d98e73fbf51.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1314-f604ba013ec535b0.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1454-a9c338f5bb556f42.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1464.f3209af0d8ae4ff2.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/{8532.a86e99acf9b761cb.js → 1516.83dd2c1b86b4e507.js} +2 -2
  17. package/apps/pwa/out/_next/static/chunks/{89849432.9eaa2f4c9c010965.js → 16e57f67.3ea19e893461e611.js} +3 -3
  18. package/apps/pwa/out/_next/static/chunks/1729-d73dd25e564679d4.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/{1505.5826671109111e75.js → 1743.563d3168e95825ef.js} +2 -2
  20. package/apps/pwa/out/_next/static/chunks/1843.5924c24295243261.js +27 -0
  21. package/apps/pwa/out/_next/static/chunks/1987.e28149724b92918b.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2066-5ca18ffa5a4be68b.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/2240.d10a66695155fd93.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2391.e2cbc98d4abbb41a.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2528.3868070ef1be69f9.js +24 -0
  26. package/apps/pwa/out/_next/static/chunks/2566-734cb83bbd405886.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2697.76ca2ac3efef6f3b.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/275.0e6bad414729bfa0.js +32 -0
  29. package/apps/pwa/out/_next/static/chunks/2803-33bdae771855a8d1.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/2846.d6a433b8663819a5.js +309 -0
  31. package/apps/pwa/out/_next/static/chunks/3143.257997a5f1ed79df.js +34 -0
  32. package/apps/pwa/out/_next/static/chunks/{5967-c0a80f8ffe5d4050.js → 3259-86f3be56e43eaf6a.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/3280-e177c33bfbdcfb0a.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/3294-2b6a6d45a46a6c1c.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/3309.364573ceedbdfd5f.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3522.758840fc5e7fe630.js +287 -0
  37. package/apps/pwa/out/_next/static/chunks/3525-a7c989c1a661e880.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3694.b1a66387756458c0.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/370.124f9e678a76fc01.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3797-9643105335e660fe.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/{5578.ac963634373b28c6.js → 4084.15ecaf4240bd9e77.js} +2 -2
  42. package/apps/pwa/out/_next/static/chunks/4089-b3382b8843114eee.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/{8438.ee7f0df3b3f6fcb4.js → 4204.a409ab6250c0f6a8.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/4293.928a8d573c16aab7.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/4402.f9238a3b18a7bd43.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4490-9b090b0f9427f902.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4548.13502d0ca3b4f862.js +8 -0
  48. package/apps/pwa/out/_next/static/chunks/4565-67e4c620597965c8.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/{7905.b230b9d06cb4ad5d.js → 4593.10f5b9bd702d4a6c.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/4599-548bc96cda44a5a7.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4625.206574e33a9e7ae8.js +104 -0
  52. package/apps/pwa/out/_next/static/chunks/4862-392c9a71f0d8dfb4.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/5054.2906d1b02542edc5.js +149 -0
  54. package/apps/pwa/out/_next/static/chunks/{8569.b853a8daa8f31d12.js → 5081.a240b63fad28663a.js} +1 -1
  55. package/apps/pwa/out/_next/static/chunks/5102-c822bbbee5a022a4.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5194-8c93f2e7e4b6f717.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5305-bacd7eca0b9a5848.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5311.9071ee3f44fd7ff5.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5369.9f34353442daa421.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/{2528.0af5c0e1fad88df6.js → 5408.377c8c543635b81f.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{9502-32c5dc22e8f120f5.js → 5492-e05e26a033ba80d2.js} +3 -3
  62. package/apps/pwa/out/_next/static/chunks/5785-ea8d2c633b6688e3.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/589-49d730cb8138b397.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5904-264a6412ae3c9028.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/5980.728531d5c566535c.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/599-a914cc0468f56143.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/6011.f525002e21bef0ac.js +23 -0
  68. package/apps/pwa/out/_next/static/chunks/6132.4381ab93683f1acf.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/6149.2e698635e454d8f6.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/{5974.360f8441eb0ac1ec.js → 6196.34d6b229079e9e28.js} +1 -1
  71. package/apps/pwa/out/_next/static/chunks/6356-0afafc4230cf9767.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6406.64756073f7df35b8.js +77 -0
  73. package/apps/pwa/out/_next/static/chunks/6479-16e62aedafa0e310.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/6599.b5246b46a2453329.js +64 -0
  75. package/apps/pwa/out/_next/static/chunks/{ce383d63.d2ede338788ed18e.js → 65ebff95.081daeff622d238e.js} +1 -1
  76. package/apps/pwa/out/_next/static/chunks/6610.5c26eec011565acb.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/666.37d18474edc1c552.js +2 -0
  78. package/apps/pwa/out/_next/static/chunks/6904.a0b5b1ed4f2d2c20.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/{83cfc5c8.349535543c1548b6.js → 6def8a8e.c81f9ca41028eccf.js} +1 -1
  80. package/apps/pwa/out/_next/static/chunks/7247-1f4aba94aba50d9f.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7274-e71a7c5b7760cd02.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/7290.1fcaeef3adb5d0d4.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/7477-2c64e42760f82f33.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/{2721.bc9a8f36bd85c07a.js → 7483.ba01c6c209b81bba.js} +1 -1
  85. package/apps/pwa/out/_next/static/chunks/7505-47002b76ff1aef6c.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7600-11884ca4da68e5d9.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7607.40d8bb3689697ccb.js +62 -0
  88. package/apps/pwa/out/_next/static/chunks/{6702.ebbd165d5e4a4a14.js → 7752.5cbdd0b433c54af9.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/7763.f51fcc19ca1414ec.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7785.846140c859b1adf6.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7807-a0fdac6393e0bf36.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7837-20a63b4b7e9342b1.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/800.7815414cf280545d.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/{8925-2abfb48af477fb7f.js → 8085-1e5fce59500a2cc2.js} +1 -1
  95. package/apps/pwa/out/_next/static/chunks/8100.415f2105faa63e97.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/8290.701aa42ed13aa767.js +226 -0
  97. package/apps/pwa/out/_next/static/chunks/{b4e12462-5fab4a813a63dadd.js → 83a80514-b897b64df43ce108.js} +1 -1
  98. package/apps/pwa/out/_next/static/chunks/8444.d9c74214a3145a43.js +93 -0
  99. package/apps/pwa/out/_next/static/chunks/8569.98c915534928c7f9.js +24 -0
  100. package/apps/pwa/out/_next/static/chunks/{8264.00e434fbd02e9311.js → 8578.dff22d988cc2b106.js} +3 -3
  101. package/apps/pwa/out/_next/static/chunks/8591.b1c7f876e5ec7cfb.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8715-f63756021d3ab989.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8879.776c2ec7732aa114.js +115 -0
  104. package/apps/pwa/out/_next/static/chunks/8881.ddca15b3c82c490c.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8946.5da5c87f32a2e1a8.js +41 -0
  106. package/apps/pwa/out/_next/static/chunks/9117.080b9b75be90e14d.js +74 -0
  107. package/apps/pwa/out/_next/static/chunks/9167.f3ecb28f367d6e69.js +94 -0
  108. package/apps/pwa/out/_next/static/chunks/9224.66095370ee28c93b.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9238-0682b013c83d6449.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{7518.49161e8f5814abdb.js → 9311.24c8f5ea793253dd.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/{9976.8f28864317639fe6.js → 94.4cfed21c0b781a06.js} +3 -3
  112. package/apps/pwa/out/_next/static/chunks/9449.d3ed795da4befb1c.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/949.1e7d45ccb71580aa.js +90 -0
  114. package/apps/pwa/out/_next/static/chunks/9638-d268329f2c6f4f8d.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/{0e3acd34.d42b2ef87fdf4234.js → 973cbf1b.3bbcf2b41548eca7.js} +1 -1
  116. package/apps/pwa/out/_next/static/chunks/9842-d6644eb53d3dc6bf.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9863.94ca3263e760696e.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{6571-926ddf024a6ad5df.js → 9917-9e26abc5f7772735.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/9938.b23e4d4dfa0114cd.js +79 -0
  120. package/apps/pwa/out/_next/static/chunks/{740.90b31555290236a9.js → 9974.e77b4ff4884557b3.js} +2 -2
  121. package/apps/pwa/out/_next/static/chunks/{4c5e95ce.83e9b16add6fcd8c.js → ab4d57c2.e90bc2cb31949045.js} +7 -7
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d9babd8795f396a5.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-a1ce306364f08da9.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-07110da72c45e68f.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-d2d76d4a7eae91bd.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-30007380f2e2a3c1.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-e5a9302c105725a3.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-b93c04b5311c97ec.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-718a49e86bf25f9c.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-20662900d6b4b455.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-f707a509515ac50c.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-6a16a48d1aa6e91f.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/{page-26345242e4049f55.js → page-fcb06e305f515527.js} +1 -1
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-6acf5ec4e6c6d1af.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-39f82acf619cca23.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-7c2c8f81b185f9c0.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-d9babd8795f396a5.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-ae7aff07e32676bb.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-482c60c1bc540d0a.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-7cb996c1aa08b6f5.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-623e08fe4477d606.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-db460cd8aecb8490.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-ff27902d0b11ef4f.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-8397a5c6ca569bf4.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1917ea87ea71ab6b.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-25a302273b054fd7.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-670510eda8b9443f.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-d73c3f1e00d93986.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-65caacf54389081e.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-4bb7556e2e97a750.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-77e04b4f8762c666.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/{page-b92caddb5c715f30.js → page-15c0a4095baddfba.js} +1 -1
  153. package/apps/pwa/out/_next/static/chunks/app/page-4eb96fc7241c2456.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-63e272a4cd3b6634.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-0d64ff212dc55d03.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-7f096248993fc2d4.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-e47fc72049149a38.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-f7d808e31e005895.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-5c2b24b5496dad73.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-d9babd8795f396a5.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-76cdb531668b5191.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-e2b63345bba1a11f.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-d376e0c83edc041a.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d6db55fe2c04d128.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-87b88f551f421d8b.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-dab163b338e3b966.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-08019efef111ed2e.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-0260ffc7eda50db1.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-980ce6fe36ad95eb.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-99c4e6c7345a9156.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-0ab42e0f05823013.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-ad9220422d20ba33.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/dcf24383-2f82e35f2d827393.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/{53746282.1be36038d1abd949.js → e117f801.e92bf10242653497.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/e87d89b9.2e71c0ae475d28a1.js +122 -0
  176. package/apps/pwa/out/_next/static/chunks/{0673cc54.8e2ef1c23e49e190.js → f4dfbfc0.a69fb12f854882aa.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/framework-bf135b997155e90e.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-5571537543bea91c.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-app-25c51c7df7f3a442.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-e3b2c1f5d82abd65.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-083f2e23e9bc3641.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-e94d22b7a028217b.js +1 -0
  183. package/apps/pwa/out/approvals/index.html +1 -1
  184. package/apps/pwa/out/approvals/index.txt +22 -22
  185. package/apps/pwa/out/autopilot/index.html +1 -1
  186. package/apps/pwa/out/autopilot/index.txt +22 -22
  187. package/apps/pwa/out/board/index.html +1 -1
  188. package/apps/pwa/out/board/index.txt +22 -22
  189. package/apps/pwa/out/botlab/index.html +1 -1
  190. package/apps/pwa/out/botlab/index.txt +21 -21
  191. package/apps/pwa/out/bots/index.html +1 -1
  192. package/apps/pwa/out/bots/index.txt +21 -21
  193. package/apps/pwa/out/ceo/index.html +1 -1
  194. package/apps/pwa/out/ceo/index.txt +22 -22
  195. package/apps/pwa/out/chat/index.html +1 -1
  196. package/apps/pwa/out/chat/index.txt +21 -21
  197. package/apps/pwa/out/consult/index.html +1 -1
  198. package/apps/pwa/out/consult/index.txt +22 -22
  199. package/apps/pwa/out/control/index.html +1 -1
  200. package/apps/pwa/out/control/index.txt +22 -22
  201. package/apps/pwa/out/decisions/index.html +1 -1
  202. package/apps/pwa/out/decisions/index.txt +21 -21
  203. package/apps/pwa/out/design-check/index.html +1 -1
  204. package/apps/pwa/out/design-check/index.txt +22 -22
  205. package/apps/pwa/out/editor/index.html +1 -1
  206. package/apps/pwa/out/editor/index.txt +22 -22
  207. package/apps/pwa/out/exec/index.html +1 -1
  208. package/apps/pwa/out/exec/index.txt +22 -22
  209. package/apps/pwa/out/field/index.html +1 -1
  210. package/apps/pwa/out/field/index.txt +22 -22
  211. package/apps/pwa/out/healthz +1 -1
  212. package/apps/pwa/out/index.html +1 -1
  213. package/apps/pwa/out/index.txt +21 -21
  214. package/apps/pwa/out/inside/index.html +1 -1
  215. package/apps/pwa/out/inside/index.txt +21 -21
  216. package/apps/pwa/out/intake/index.html +1 -1
  217. package/apps/pwa/out/intake/index.txt +22 -22
  218. package/apps/pwa/out/live/index.html +1 -1
  219. package/apps/pwa/out/live/index.txt +22 -22
  220. package/apps/pwa/out/live-run/index.html +1 -1
  221. package/apps/pwa/out/live-run/index.txt +22 -22
  222. package/apps/pwa/out/loops/index.html +1 -1
  223. package/apps/pwa/out/loops/index.txt +21 -21
  224. package/apps/pwa/out/market/index.html +1 -1
  225. package/apps/pwa/out/market/index.txt +21 -21
  226. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  227. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  228. package/apps/pwa/out/morning/index.html +1 -1
  229. package/apps/pwa/out/morning/index.txt +22 -22
  230. package/apps/pwa/out/observatory/index.html +1 -1
  231. package/apps/pwa/out/observatory/index.txt +22 -22
  232. package/apps/pwa/out/ops/checklist/index.html +1 -1
  233. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  234. package/apps/pwa/out/ops/release/index.html +1 -1
  235. package/apps/pwa/out/ops/release/index.txt +21 -21
  236. package/apps/pwa/out/ops/seats/index.html +1 -1
  237. package/apps/pwa/out/ops/seats/index.txt +21 -21
  238. package/apps/pwa/out/outputs/index.html +1 -1
  239. package/apps/pwa/out/outputs/index.txt +21 -21
  240. package/apps/pwa/out/reflection/index.html +1 -1
  241. package/apps/pwa/out/reflection/index.txt +22 -22
  242. package/apps/pwa/out/scheduler/index.html +1 -1
  243. package/apps/pwa/out/scheduler/index.txt +22 -22
  244. package/apps/pwa/out/sessions/index.html +1 -1
  245. package/apps/pwa/out/sessions/index.txt +21 -21
  246. package/apps/pwa/out/settings/devices/index.html +1 -1
  247. package/apps/pwa/out/settings/devices/index.txt +22 -22
  248. package/apps/pwa/out/settings/index.html +1 -1
  249. package/apps/pwa/out/settings/index.txt +22 -22
  250. package/apps/pwa/out/setup/done/index.html +1 -1
  251. package/apps/pwa/out/setup/done/index.txt +22 -22
  252. package/apps/pwa/out/setup/index.html +1 -1
  253. package/apps/pwa/out/setup/index.txt +22 -22
  254. package/apps/pwa/out/share/index.html +1 -1
  255. package/apps/pwa/out/share/index.txt +22 -22
  256. package/apps/pwa/out/showroom/index.html +1 -1
  257. package/apps/pwa/out/showroom/index.txt +21 -21
  258. package/apps/pwa/out/tasks/index.html +1 -1
  259. package/apps/pwa/out/tasks/index.txt +22 -22
  260. package/apps/pwa/out/term/index.html +1 -1
  261. package/apps/pwa/out/term/index.txt +22 -22
  262. package/apps/pwa/out/today/index.html +1 -1
  263. package/apps/pwa/out/today/index.txt +22 -22
  264. package/apps/pwa/out/trace/index.html +1 -1
  265. package/apps/pwa/out/trace/index.txt +22 -22
  266. package/apps/pwa/out/vault/index.html +1 -1
  267. package/apps/pwa/out/vault/index.txt +22 -22
  268. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  269. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  270. package/apps/pwa/out/workflows/index.html +1 -1
  271. package/apps/pwa/out/workflows/index.txt +22 -22
  272. package/apps/pwa/out/workspace/index.html +1 -1
  273. package/apps/pwa/out/workspace/index.txt +22 -22
  274. package/apps/pwa/out/worktrees/index.html +1 -1
  275. package/apps/pwa/out/worktrees/index.txt +22 -22
  276. package/graphs/release/release-loop.yaml +5 -5
  277. package/graphs/steward/recipes.yaml +4 -0
  278. package/graphs/steward/steward.yaml +10 -1
  279. package/package.json +1 -1
  280. package/scripts/bench-report.ts +46 -1
  281. package/scripts/ci-typecheck-changed.ts +88 -7
  282. package/scripts/coord-msg-bridge.ts +209 -0
  283. package/scripts/coord-post.sh +40 -7
  284. package/scripts/coord-requests-bridge.ts +10 -5
  285. package/scripts/expose-rubric-suggest.ts +1 -1
  286. package/scripts/measure-tsc-affected-roots.ts +10 -1
  287. package/scripts/release-loop/auto-approve-node.ts +6 -0
  288. package/scripts/release-loop/export-check-node.ts +8 -5
  289. package/scripts/release-loop/gate-closure.ts +286 -0
  290. package/scripts/release-loop/gate-node.ts +73 -13
  291. package/scripts/release-loop/gate-partial.ts +34 -6
  292. package/scripts/release-loop/node-verdict.ts +7 -2
  293. package/scripts/release-loop/ops-upgrade-node.ts +63 -42
  294. package/scripts/release-loop/publish-node.ts +6 -0
  295. package/scripts/release-loop/resume-release.ts +37 -10
  296. package/scripts/release-loop/resume.ts +69 -4
  297. package/scripts/tsc-baseline-cache.ts +28 -3
  298. package/scripts/usage-rollup.ts +27 -13
  299. package/scripts/ux-sim.ts +30 -1
  300. package/skills/youtube-master/scripts/main.ts +4 -1
  301. package/skills/youtube-master/src/obsidian.ts +9 -0
  302. package/src/agent/task-notification.ts +30 -1
  303. package/src/agent-substrate/acp-implementer.ts +14 -7
  304. package/src/agent-substrate/pr-reviewer.ts +30 -10
  305. package/src/agent-substrate/review-observation.ts +9 -2
  306. package/src/agent-substrate/self-review-cli.ts +154 -16
  307. package/src/boot/daemon-tools/self-implement.ts +72 -4
  308. package/src/budget/cost-tier-advisor.ts +91 -0
  309. package/src/budget/llm-cost.ts +5 -1
  310. package/src/budget/shadow-arms.ts +77 -0
  311. package/src/budget/types.ts +5 -3
  312. package/src/budget/unified-usage.ts +172 -8
  313. package/src/cli/control-cli.ts +29 -0
  314. package/src/cli/doctor-cli.ts +106 -3
  315. package/src/cli/friendly-errors.ts +113 -0
  316. package/src/cli/intake-cli.ts +3 -1
  317. package/src/cli/memory-cli.ts +182 -0
  318. package/src/cli/model-watch-cli.ts +4 -1
  319. package/src/cli/msg-cli.ts +15 -5
  320. package/src/cli/pr-cli.ts +53 -0
  321. package/src/cli/pr-land-overlap-evidence.ts +18 -10
  322. package/src/cli/pr-land-pod-shadow.ts +54 -0
  323. package/src/cli/release-cli.ts +41 -12
  324. package/src/cli/release-run-if-ready.ts +11 -0
  325. package/src/cli/resource-cli.ts +48 -0
  326. package/src/cli/retro-cli.ts +12 -3
  327. package/src/cli/seat-cli.ts +121 -0
  328. package/src/cli/seat-requests-cli.ts +25 -0
  329. package/src/cli/self-utterances-cli.ts +140 -0
  330. package/src/cli/tasks-cli.ts +168 -14
  331. package/src/cli/usage-cli.ts +3 -1
  332. package/src/compact/verify-probe.ts +23 -3
  333. package/src/context-card/cell.ts +40 -0
  334. package/src/context-card/index.ts +50 -0
  335. package/src/control/control-status.ts +30 -1
  336. package/src/dashboard/boot-timing.ts +35 -0
  337. package/src/dashboard/index.ts +86 -24
  338. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +26 -0
  339. package/src/dashboard/slash-runtime/dashboard-handlers.ts +10 -138
  340. package/src/dashboard/slash-runtime/shell-slash.ts +145 -0
  341. package/src/debug/log-diet.ts +16 -4
  342. package/src/debug/log.ts +1 -1
  343. package/src/domains/morning-essential.ts +18 -3
  344. package/src/domains/release-tool.ts +29 -8
  345. package/src/domains/surface-events.ts +16 -0
  346. package/src/elanous-config-dir.ts +2 -2
  347. package/src/execution-loop/launch-gate.ts +158 -2
  348. package/src/fleet/host-doctor.ts +446 -0
  349. package/src/goals/judge.ts +20 -6
  350. package/src/graph-runner/runner.ts +12 -6
  351. package/src/graph-wizard/archetypes.ts +14 -8
  352. package/src/graph-wizard/generate.ts +77 -1
  353. package/src/grok.ts +13 -7
  354. package/src/harness/harness-cli-command.ts +102 -51
  355. package/src/harness/harness-stop.ts +93 -19
  356. package/src/index.ts +52 -179
  357. package/src/instance/current.ts +2 -6
  358. package/src/instance/resolve.ts +5 -6
  359. package/src/intake-plane/collect-github.ts +7 -2
  360. package/src/intake-plane/lens.ts +46 -4
  361. package/src/intake-plane/requirement-funnel.ts +53 -1
  362. package/src/intelligence-map/catalog-feed.ts +119 -0
  363. package/src/intelligence-map/model-watch-intake.ts +40 -0
  364. package/src/intelligence-map/model-watch-mission.ts +14 -1
  365. package/src/llm/open-weight-discipline.ts +21 -0
  366. package/src/llm/openai-sampling-fields.ts +89 -0
  367. package/src/llm/runtime-model-family.ts +61 -0
  368. package/src/llm/zai-coding-plan.ts +27 -1
  369. package/src/llm.ts +17 -97
  370. package/src/machines/machine-ledger.ts +31 -3
  371. package/src/maturity/cli-maturity.ts +13 -3
  372. package/src/maturity/feature-maturity.ts +1 -1
  373. package/src/msg/msg-store.ts +69 -7
  374. package/src/nexus/api/http-server.ts +22 -0
  375. package/src/oauth/codex-account-rotation.ts +4 -1
  376. package/src/oauth/codex-account-store.ts +20 -7
  377. package/src/oauth/codex-quota-policy.ts +33 -4
  378. package/src/ops/overview-collect.ts +3 -2
  379. package/src/ops/overview-owner.ts +29 -0
  380. package/src/plugin-hooks/shell-hook.ts +17 -2
  381. package/src/plugin-missions/evaluator-runner.ts +18 -2
  382. package/src/plugins/install/plugin-install.ts +11 -1
  383. package/src/preview/terminal.ts +15 -5
  384. package/src/project/project-store.ts +20 -0
  385. package/src/prompt-enhance/enhance.ts +11 -0
  386. package/src/release-loop/auto-start.ts +7 -5
  387. package/src/release-loop/checklist.ts +52 -5
  388. package/src/release-loop/feature-store.ts +10 -9
  389. package/src/release-loop/gate-shards.ts +4 -0
  390. package/src/release-loop/light-rc.ts +84 -13
  391. package/src/release-loop/merged-pr-checklist.ts +35 -5
  392. package/src/release-loop/rehearsal.ts +1 -1
  393. package/src/seat-loop/duty-ledger.ts +64 -0
  394. package/src/seat-loop/seat-loop.ts +5 -1
  395. package/src/self-dev/decompose.ts +37 -3
  396. package/src/self-dev/dev-pipeline.ts +32 -7
  397. package/src/self-dev/draft-residue.ts +16 -6
  398. package/src/self-dev/draft-sweep.ts +75 -18
  399. package/src/self-dev/fabric-decompose-adapter.ts +9 -2
  400. package/src/self-dev/orchestrate.ts +6 -2
  401. package/src/self-dev/run-supervisor.ts +72 -8
  402. package/src/self-implement/gate-cli.ts +29 -10
  403. package/src/self-implement/gate-remote.ts +4 -1
  404. package/src/self-implement/goal-author.ts +15 -29
  405. package/src/self-implement/goal-command-execution.ts +26 -0
  406. package/src/self-implement/goal-new-paths.ts +42 -0
  407. package/src/self-implement/host-regate.ts +124 -30
  408. package/src/self-implement/importer-test-index.ts +3 -1
  409. package/src/self-implement/l8-merge-queue.ts +80 -2
  410. package/src/self-implement/merge-train.ts +19 -0
  411. package/src/self-implement/off-diff-evidence.ts +40 -1
  412. package/src/self-implement/orchestrator.ts +90 -20
  413. package/src/self-implement/premise-review.ts +159 -0
  414. package/src/self-implement/pwa-import-graph.ts +194 -7
  415. package/src/self-implement/regate-detail.ts +79 -0
  416. package/src/self-implement/review-deferred-to-host.ts +21 -0
  417. package/src/self-implement/rework-budget-judgment.ts +23 -3
  418. package/src/self-implement/running-runs.ts +2 -2
  419. package/src/self-implement/scope-adjacency.ts +23 -0
  420. package/src/self-implement/seams.ts +42 -7
  421. package/src/self-implement/self-implement-runtime.ts +126 -21
  422. package/src/session/index.ts +14 -4
  423. package/src/session-runtime/index.ts +55 -11
  424. package/src/skills/tools/agent.ts +16 -1
  425. package/src/skills/tools/persistent-grounding.ts +11 -1
  426. package/src/skills/tools/shell.ts +33 -1
  427. package/src/steward/rejudge-tick.ts +142 -0
  428. package/src/task-agent/board.ts +92 -3
  429. package/src/task-agent/card-evidence.ts +88 -1
  430. package/src/task-agent/cover.ts +85 -1
  431. package/src/task-agent/live-moves.ts +14 -6
  432. package/src/task-agent/parent-host.ts +27 -3
  433. package/src/task-agent/rejudge-on-head.ts +370 -29
  434. package/src/task-agent/review-result-capture.ts +67 -2
  435. package/src/task-agent/shadow.ts +148 -21
  436. package/src/task-agent/task-hand.ts +22 -3
  437. package/src/task-orchestrator/surfaces/pod-command-job.ts +14 -0
  438. package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +122 -0
  439. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +23 -0
  440. package/src/task-orchestrator/surfaces/pod-pool.ts +53 -0
  441. package/src/task-orchestrator/surfaces/self-implement-pod.ts +236 -28
  442. package/src/tool-runtime/tool-search-runtime.ts +25 -0
  443. package/src/tui.ts +20 -1
  444. package/src/user-config.ts +21 -63
  445. package/src/ux-sim/fault-cred-expiry.ts +100 -0
  446. package/src/ux-sim/fault-pod-death.ts +74 -0
  447. package/src/ux-sim/fault-pool-cap.ts +81 -0
  448. package/src/version/packed-revision.json +1 -1
  449. package/src/webclone/qa-table.ts +22 -0
  450. package/apps/pwa/out/_next/static/chunks/0a09e062-34f747a17d8d8c2e.js +0 -1
  451. package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +0 -77
  452. package/apps/pwa/out/_next/static/chunks/1325-dc3f3c21eb181cb4.js +0 -1
  453. package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +0 -34
  454. package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +0 -24
  455. package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +0 -1
  456. package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +0 -1
  457. package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +0 -1
  458. package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +0 -1
  459. package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +0 -1
  460. package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +0 -1
  461. package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +0 -1
  462. package/apps/pwa/out/_next/static/chunks/1669-da843ed73aa301f5.js +0 -1
  463. package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +0 -1
  464. package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +0 -36
  465. package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +0 -122
  466. package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +0 -1
  467. package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +0 -62
  468. package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +0 -1
  469. package/apps/pwa/out/_next/static/chunks/272-0eed0fb0aab716b6.js +0 -1
  470. package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +0 -1
  471. package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +0 -1
  472. package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +0 -1
  473. package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +0 -1
  474. package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +0 -149
  475. package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +0 -1
  477. package/apps/pwa/out/_next/static/chunks/3961-aaae04ed1d32622f.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +0 -309
  479. package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +0 -1
  481. package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +0 -1
  482. package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +0 -1
  483. package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +0 -1
  484. package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +0 -1
  487. package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +0 -1
  490. package/apps/pwa/out/_next/static/chunks/5313.1697309c532b9856.js +0 -2
  491. package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +0 -1
  492. package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +0 -1
  493. package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +0 -1
  494. package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +0 -1
  496. package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +0 -1
  497. package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +0 -1
  498. package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +0 -74
  499. package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +0 -64
  503. package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +0 -1
  504. package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +0 -32
  506. package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +0 -24
  507. package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +0 -1
  510. package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +0 -93
  511. package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +0 -1
  514. package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +0 -1
  515. package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +0 -148
  516. package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +0 -226
  517. package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +0 -27
  518. package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +0 -1
  519. package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +0 -1
  520. package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +0 -115
  521. package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +0 -1
  522. package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +0 -1
  523. package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +0 -1
  524. package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +0 -1
  525. package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +0 -1
  526. package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +0 -1
  527. package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +0 -8
  528. package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +0 -23
  529. package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +0 -1
  530. package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +0 -1
  531. package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +0 -1
  533. package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +0 -90
  534. package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +0 -94
  535. package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +0 -41
  537. package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +0 -1
  538. package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +0 -287
  539. package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +0 -79
  540. package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +0 -104
  545. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/app/approvals/page-3b9fc39362473ae7.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f2b62c19ca68fef8.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/app/board/page-d7602d489edf5f37.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/app/botlab/page-24282bf9f90031a5.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/app/bots/page-8b7c5ab6b5bc8d64.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/app/ceo/page-4eb84d454f8c3415.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/app/chat/page-b2e494bdad57fcb5.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/app/consult/page-c0ab229673a8b0eb.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/app/control/page-3e2b45f3c36dbac4.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/app/decisions/page-c22aa511b28743ad.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/app/editor/page-bf88c0f558d8ef54.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/app/exec/page-52fec523e5b5d3ad.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/app/field/page-67723dfdcde92b31.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/app/inside/page-22725e2570f1126b.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/app/intake/page-1891335950d68b70.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/app/layout-3267af1ebdc73cf5.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/app/live/page-c314b75c11234998.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/app/live-run/page-9f9c85415f61782b.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/app/loops/page-c1d4276059085587.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/app/market/page-833aab587f26ad4c.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8526c17ae38e6a50.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/app/morning/page-f998637a8402115c.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/app/not-found-b7bb53828b17b335.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/app/observatory/page-1b1850de0257e46d.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6f23159fedb41f67.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1d809a87139dd024.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-da9e570234d481fd.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/app/page-8ce3a38e210b810a.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/app/reflection/page-57ffeeb6019440fd.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-abbb417bf514630b.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/app/sessions/page-2c2b3f29cec1efa4.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-9369279f72fc7b51.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/app/settings/page-64861f14039499c3.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ddc4c93efd8ab94b.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/app/setup/page-901a1391b81053bc.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/app/share/page-68d9bbaac9841a58.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/app/showroom/page-b5c0c996f329371e.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/app/tasks/page-89881ccbcf728978.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/app/term/page-0e87a803b3d7165e.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/app/today/page-58d4e5cb30ef4871.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/app/trace/page-02ce4c3b5f39e4d2.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/app/vault/page-e620d1bb8eadcec2.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-acf868c64d77f950.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/app/workflows/page-54fa605fa6dba457.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/app/workspace/page-bc79f0833533fa84.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-d5c4398eea03d8f3.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/framework-b2763b10dc6b3836.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +0 -1
  601. /package/apps/pwa/out/_next/static/{Q-7iofoxOEv1WX18S35of → Ev2jivDMTSoEc-5rIXdcy}/_ssgManifest.js +0 -0
@@ -1,20 +1,25 @@
1
1
  import { closeSync, existsSync, mkdirSync, openSync, readFileSync, readSync } from 'node:fs';
2
2
  import { tmpdir } from 'node:os';
3
3
  import { loadRunLedger as loadRunLedgerSync } from '../self-implement/run-ledger.js';
4
+ import { goalRunDbPath, loadGoalRunQuery } from '../self-implement/goal-run-store.js';
5
+ import { loadGoalAskRecords } from '../self-implement/goal-ask-store.js';
4
6
  import { join, resolve } from 'node:path';
5
7
  import { InvalidArgumentError, Option, type Command } from 'commander';
6
8
  import { debug } from '../debug/log.js';
7
9
  import { getElanousConfigDir } from '../elanous-config-dir.js';
8
10
  import { readNexusRuntime } from '../nexus/runtime.js';
9
11
  import { checklistDevVersion } from '../release-loop/checklist.js';
12
+ import { assignedVersions, releasedVersion, validateVersion } from '../release-loop/feature-store.js';
13
+ import { compareVersions } from '../directives/version-at.js';
10
14
  import { cardsBoard, countBoardTasks, INTERNAL_PACK_PROJECT, mergeBoards, releasePackBoard, type BoardNode } from '../task-agent/board.js';
11
15
  import type { Task } from '../task-orchestrator/types.js';
12
- import { cardPrNumber, CLOSED_BY_HAND_EVENT, closeTaskCard, COMPLETION_KINDS, handTask, updateTaskCard, LIVE_MOVE_HISTORY_EVENT, LIVE_MOVE_RESULT_EVENT, nextMoveFor, resolveHandText, readTaskAgentState, readTaskCard, taskAgentStatePath as taskStatePathDefault, shellQuote, TA_LAND_ENV, TASK_CARD_PREFIX, TASK_SEATS, type CompletionKind, type TaskCard, type TaskLaunchContext, type TaskLaunchReceipt, type TaskLauncher, type TaskSeat } from '../task-agent/task-hand.js';
13
- import { readCardSalvageBranch, refreshCardRunBinding, type CardRunEvidenceDeps } from '../task-agent/card-evidence.js';
16
+ import { cardPrNumber, CLOSED_BY_HAND_EVENT, closeTaskCard, COMPLETION_KINDS, handTask, updateTaskCard, LIVE_MOVE_HISTORY_EVENT, LIVE_MOVE_RESULT_EVENT, nextMoveFor, resolveHandText, readTaskAgentState, readTaskCard, taskAgentStatePath as taskStatePathDefault, shellQuote, TASK_CARD_PREFIX, TASK_SEATS, type CompletionKind, type TaskCard, type TaskLaunchContext, type TaskLaunchReceipt, type TaskLauncher, type TaskSeat } from '../task-agent/task-hand.js';
17
+ import { readCardSalvageBranch, recordWiringLiveVerified, refreshCardRunBinding, type CardRunEvidenceDeps } from '../task-agent/card-evidence.js';
14
18
  import { captureReviewResults } from '../task-agent/review-result-capture.js';
19
+ import { replayRemoteCardMoves } from '../task-agent/shadow.js';
15
20
  import { HAND_MOVE_KINDS, recordHandMove } from '../task-agent/live-move-history.js';
16
21
  import { advanceMission, handMission, MissionAdvanceError, openMissionIds, recordPieceRef, type AdvanceMissionResult, type MissionDecompose, type PieceEvidenceReader } from '../task-agent/mission.js';
17
- import { formatTaskAgentCover, measureTaskAgentCover, type CoverRow, type TaskAgentCoverInput } from '../task-agent/cover.js';
22
+ import { formatSevenVerbLive, formatTaskAgentCover, measureSevenVerbLive, measureTaskAgentCover, type CoverRow, type SevenVerbLive, type TaskAgentCoverInput } from '../task-agent/cover.js';
18
23
  import { LogStore, STORE_SAFETY_MAX, type LogQuery, type LogStoreRow } from '../mss/logging/log-store.js';
19
24
  import { resolveLogTargets } from './logs-cli.js';
20
25
 
@@ -38,9 +43,13 @@ export interface TasksCliDeps {
38
43
  /** `task advance` 의 착지 근거 읽기(시험 주입). 기본 = `predecessorState`(gh · 런 원장). */
39
44
  pieceEvidence?: PieceEvidenceReader;
40
45
  /** `task board` 의 내부 팩 어댑터(시험 주입). 기본 = 현재 판(`checklistDevVersion()`)의 `releasePackBoard` — 읽기만. */
41
- releaseBoard?: () => BoardNode[];
46
+ releaseBoard?: (version?: string) => BoardNode[];
47
+ /** `tasks hand --checklist` 판 목록(시험 주입). 기본은 발행 전 체크리스트가 있는 판 전부. */
48
+ releaseVersions?: () => string[];
42
49
  /** `tasks show`·`advance` 의 런 근거 읽기(시험 주입) — 기본 = 런 원장(이 우주 ⊕ 연합) ⊕ 호스트 logs 의 Pod job-finished. */
43
50
  cardRunEvidence?: CardRunEvidenceDeps;
51
+ /** `tasks live-verified` 가 적는 런 원장 디렉터리(시험 주입). 기본 = `runLedgerDir()`. */
52
+ liveVerifiedLedgerDir?: string;
44
53
  /** HARNESS-PARENT-ON-MSB1 — 원격 부모 카드의 원장 거울(시험 주입). 기본 = ssh 로 `<prodRoot>/remote-parents/<host>/run-ledger`. */
45
54
  remoteLedgerMirror?: (card: TaskCard) => void;
46
55
  /** `tasks parents` 의 낡은 부모 보고 의존(시험 주입). */
@@ -52,10 +61,16 @@ export interface TasksCliDeps {
52
61
  coverLogs?: (query: LogQuery) => LogStoreRow[] | CoverLogRead;
53
62
  /** `tasks cover --by-card` 카드 원장 읽기 seam(읽기 전용). 플래그가 있을 때만 부른다. 기본 = TA 카드 원장(task-agent-actions.json). null = 못 읽음. */
54
63
  coverCards?: () => CoverCardRow[] | null | Promise<CoverCardRow[] | null>;
64
+ /** Read-only authored goal provenance; null means the authoring ledger could not be read. */
65
+ coverGoalAsks?: () => { authorRunId: string; goalId: string; createdAt: string }[] | null;
66
+ /** Read-only terminal goal records; null means the goal ledger could not be read. */
67
+ coverGoalRuns?: () => { goalId: string; outcome: string; stage?: string; startedAt: string; completedAt?: string }[] | null;
55
68
  /** TA-REJUDGE-ON-HEAD — `tasks rejudge` 의 판단 의존(시험 주입 · 기본 = 설정 liveMoves ⊕ 실물 gh·리뷰·재게이트·land). */
56
69
  rejudge?: Partial<import('../task-agent/rejudge-on-head.js').RejudgeDeps>;
57
70
  /** TA-REJUDGE-ON-HEAD — `tasks regate-run` 의 재게이트(시험 주입 · 기본 `runHostRegate`). */
58
71
  hostRegate?: (input: import('../self-implement/host-regate.js').HostRegateInput) => Promise<import('../self-implement/host-regate.js').HostRegateResult>;
72
+ /** Isolated regate-run tests can disable the asynchronous completion callback explicitly. */
73
+ regateCompletion?: false;
59
74
  }
60
75
 
61
76
  /** `<조각id>=<값>` 반복 인자. */
@@ -150,8 +165,8 @@ async function tryRemoteParent(args: string[], cwd: string | undefined, context:
150
165
  try { debug.log('task-agent', 'parent-host-fallback', { host: target.host, runId: context.runId, gaps, facts }); } catch { /* fail-soft */ }
151
166
  notice(`[parent-host] ${target.host} 로 못 띄움 — ${multi ? '다음 호스트 또는 로컬 발사로 간다' : '로컬 발사로 간다'}: ${gaps.join(' · ')}`);
152
167
  };
153
- if (cwd || context.env[TA_LAND_ENV] === '1') {
154
- failed(targets[0]!, [cwd ? 'project-target-is-local' : 'ta-land-needs-local-parent']);
168
+ if (cwd) {
169
+ failed(targets[0]!, ['project-target-is-local']);
155
170
  return null;
156
171
  }
157
172
  let launchHoldActive = false;
@@ -174,6 +189,7 @@ async function tryRemoteParent(args: string[], cwd: string | undefined, context:
174
189
  try { preflight = parentHostModule.preflightParentHost({ target, localVersion: deps.localVersion ?? parentHostModule.localElanousVersion(), launchHoldActive, ...(deps.ssh ? { ssh: deps.ssh } : {}) }); }
175
190
  catch (error) { failed(target, [`preflight-error: ${error instanceof Error ? error.message : String(error)}`]); continue; }
176
191
  if (!preflight.ok) { failed(target, preflight.gaps, preflight.facts); continue; }
192
+ if (preflight.warnings.length) notice(`⚠ ${target.host} 자격: ${preflight.warnings.join(' · ')}`);
177
193
  try {
178
194
  const launched = parentHostModule.launchRemoteParent(target, args, context.env, deps.ssh);
179
195
  try { debug.log('task-agent', 'parent-host-launched', { host: target.host, runId: context.runId, pid: launched.pid, log: launched.log }); } catch { /* fail-soft */ }
@@ -499,7 +515,8 @@ export function readTaskAgentCover(
499
515
  window: { sinceMs?: number; untilMs?: number } = {},
500
516
  query: NonNullable<TasksCliDeps['coverLogs']> = queryCoverLogs,
501
517
  taskCards?: readonly { id: string }[] | null,
502
- ): { rows: CoverRow[]; limitReached: boolean; unreadableStores: number } {
518
+ goalReaders: Pick<TasksCliDeps, 'coverGoalAsks' | 'coverGoalRuns'> = {},
519
+ ): { rows: CoverRow[]; sevenVerbs: SevenVerbLive; limitReached: boolean; unreadableStores: number } {
503
520
  let unreadableStores = 0;
504
521
  const read = (category: 'task-agent' | 'pr.land', event: 'action' | 'step'): { rows: LogStoreRow[]; limitReached: boolean } | null => {
505
522
  try {
@@ -514,16 +531,51 @@ export function readTaskAgentCover(
514
531
  const actions = actionRead?.rows ?? null;
515
532
  const lands = landRead?.rows ?? null;
516
533
  const truncated = { taskAgentActions: actionRead?.limitReached === true, allLands: landRead?.limitReached === true };
534
+ const inWindow = (value: string): boolean => {
535
+ const time = Date.parse(value);
536
+ return Number.isFinite(time) && (window.sinceMs === undefined || time >= window.sinceMs) && (window.untilMs === undefined || time <= window.untilMs);
537
+ };
538
+ let goalAsks: ReturnType<NonNullable<TasksCliDeps['coverGoalAsks']>> = null;
539
+ let goalRuns: ReturnType<NonNullable<TasksCliDeps['coverGoalRuns']>> = null;
540
+ let goalAsksTruncated = false;
541
+ let goalRunsTruncated = false;
542
+ try {
543
+ if (goalReaders.coverGoalAsks) goalAsks = goalReaders.coverGoalAsks();
544
+ else {
545
+ const asks = loadGoalAskRecords({ limit: COVER_QUERY_LIMIT }, goalRunDbPath());
546
+ goalAsksTruncated = asks.length >= COVER_QUERY_LIMIT;
547
+ goalAsks = asks;
548
+ }
549
+ } catch { goalAsks = null; }
550
+ try {
551
+ if (goalReaders.coverGoalRuns) goalRuns = goalReaders.coverGoalRuns();
552
+ else {
553
+ const runs = loadGoalRunQuery({ limit: COVER_QUERY_LIMIT }, goalRunDbPath());
554
+ goalRunsTruncated = runs?.truncated ?? false;
555
+ goalRuns = runs?.records.map(({ goalId, record }) => ({
556
+ goalId, outcome: record.outcome, stage: record.stage, startedAt: record.startedAt ?? '', completedAt: record.completedAt,
557
+ })) ?? null;
558
+ }
559
+ } catch { goalRuns = null; }
560
+ const authoredGoalIds = new Set(goalAsks?.map((ask) => ask.goalId) ?? []);
517
561
  const input: TaskAgentCoverInput = {
518
562
  taskAgentActions: actions === null ? null : coverEvents(actions, 'task-agent', 'action', (data) =>
519
563
  typeof data.kind === 'string' && typeof data.result === 'string'
520
564
  ? { kind: data.kind as NonNullable<TaskAgentCoverInput['taskAgentActions']>[number]['kind'], result: data.result, ...(typeof data.taskId === 'string' ? { taskId: data.taskId } : {}) } : null),
521
565
  allLands: lands === null ? null : coverEvents(lands, 'pr.land', 'step', (data) =>
522
566
  typeof data.step === 'string' && typeof data.ok === 'boolean' ? { step: data.step, ok: data.ok } : null),
523
- truncated,
567
+ truncated: { ...truncated, goalAsks: goalAsksTruncated, goalRuns: goalRunsTruncated },
568
+ // Authoring may start before this window; completion is the event being counted.
569
+ goalAsks,
570
+ goalRuns: goalRuns && (window.sinceMs !== undefined || window.untilMs !== undefined)
571
+ ? goalRuns.some((run) => authoredGoalIds.has(run.goalId)
572
+ && run.stage === 'merged' && (run.outcome === 'completed' || run.outcome === 'merged')
573
+ && !Number.isFinite(Date.parse(run.completedAt ?? '')))
574
+ ? null : goalRuns.filter((run) => inWindow(run.completedAt ?? ''))
575
+ : goalRuns,
524
576
  ...(taskCards === undefined ? {} : { taskCards }),
525
577
  };
526
- return { rows: measureTaskAgentCover(input), limitReached: truncated.taskAgentActions || truncated.allLands, unreadableStores };
578
+ return { rows: measureTaskAgentCover(input), sevenVerbs: measureSevenVerbLive(input), limitReached: truncated.taskAgentActions || truncated.allLands || goalAsksTruncated || goalRunsTruncated, unreadableStores };
527
579
  }
528
580
 
529
581
  export function registerTasksCommands(program: Command, deps: TasksCliDeps = {}): void {
@@ -565,12 +617,15 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
565
617
  }
566
618
  taskCards = coverCardsInWindow(cards, { sinceMs, untilMs });
567
619
  }
568
- const { rows, limitReached, unreadableStores } = readTaskAgentCover({ sinceMs, untilMs }, deps.coverLogs, taskCards);
620
+ const { rows, sevenVerbs, limitReached, unreadableStores } = readTaskAgentCover({ sinceMs, untilMs }, deps.coverLogs, taskCards, deps);
569
621
  const limitWarning = limitReached ? `조회 상한 ${COVER_QUERY_LIMIT} 도달 — 더 오래된 사건이 있을 수 있다(절단된 수를 전체로 읽지 말 것)` : null;
570
622
  const storeWarning = unreadableStores > 0 ? `logs.db ${unreadableStores}개를 못 읽었다 — 그 우주의 사건은 수에 없다(«없다»로 읽지 말 것)` : null;
571
- if (opts.json) out(JSON.stringify({ rows, limitReached, unreadableStores, ...(limitWarning ? { warning: limitWarning } : {}), ...(storeWarning ? { storeWarning } : {}) }));
623
+ if (opts.json) out(JSON.stringify({ rows, sevenVerbs, limitReached, unreadableStores, ...(limitWarning ? { warning: limitWarning } : {}), ...(storeWarning ? { storeWarning } : {}) }));
572
624
  else {
573
- if (opts.lines) for (const row of rows) out(formatTaskAgentCover(row));
625
+ if (opts.lines) {
626
+ for (const row of rows) out(formatTaskAgentCover(row));
627
+ out(formatSevenVerbLive(sevenVerbs));
628
+ }
574
629
  else {
575
630
  out('동사\t대신\t전체\t비율\t상태\t관측 사건');
576
631
  for (const row of rows) out(`${row.verb}\t${row.byTaskAgent ?? '-'}\t${row.total ?? '-'}\t${row.ratio ?? '-'}\t${row.state}\t${row.observedActions ?? '-'}`);
@@ -618,6 +673,7 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
618
673
  .description('TASK-AGENT 에 과제 한 줄을 넘긴다 — 카드를 적고 첫 수(harness say --substrate pod --merge-by-host)를 고른다 · 기본 shadow(발사 0) · `--mission` 이면 조각 카드 ⊕ 선후로 쪼개 선행 없는 조각만 넘긴다')
619
674
  .addOption(new Option('--seat <seat>', `과제 자리 (${TASK_SEATS.join('|')})`).choices([...TASK_SEATS]))
620
675
  .option('--checklist <cellId>', '릴리스 체크리스트 칸 id')
676
+ .option('--version <version>', '체크리스트 판 고정(생략하면 발행 전 판을 가까운 순서로 탐색)')
621
677
  .addOption(new Option('--completion <kind>', `종결 종류 (${COMPLETION_KINDS.join('|')} · 기본 code-pr = PR 병합)`).choices([...COMPLETION_KINDS]))
622
678
  .option('--mission <text>', '미션 문면 — 조각(`- …`·`① …`·`1. …` ⊕ `after: 1`)으로 나열돼 있으면 결정론, 아니면 분해기로 쪼갠다')
623
679
  .option('--project <id>', '프로젝트 id — --target 과 함께')
@@ -629,7 +685,72 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
629
685
  .option('--child-llm <provider/model>', 'TASKS-HAND-CHILD-LLM — 구현 자식 LLM(예: grok/grok-4.7) → 발사 인자 --child-llm-provider <provider> --child-llm-model <model> · «첫» `/` 에서만 가른다(모델 id 의 `/` 는 보존) · openrouter 는 모델 id 가 openrouter/ 접두를 포함하므로 전체를 모델로(openrouter/z-ai/glm-5.3 → --child-llm-model openrouter/z-ai/glm-5.3) · 카드 childLlm · 안 주면 명령·카드 무변경')
630
686
  .option('--child-llm-effort <level>', '구현 자식 추론 노력 → 발사 인자 --child-llm-effort(검증은 하니스 · --child-llm 과 함께)')
631
687
  .option('--json', 'JSON 출력')
632
- .action(async (text: string | undefined, opts: { seat?: TaskSeat; checklist?: string; completion?: CompletionKind; mission?: string; project?: string; target?: string; goal?: string; milestone?: string; live?: boolean; taLand?: boolean; childLlm?: string; childLlmEffort?: string; json?: boolean }) => {
688
+ .action(async (text: string | undefined, opts: { seat?: TaskSeat; checklist?: string; version?: string; completion?: CompletionKind; mission?: string; project?: string; target?: string; goal?: string; milestone?: string; live?: boolean; taLand?: boolean; childLlm?: string; childLlmEffort?: string; json?: boolean }) => {
689
+ const suppliedText = text !== undefined;
690
+ if (opts.version !== undefined && opts.checklist === undefined) {
691
+ out('--version 은 --checklist 와 함께 준다');
692
+ process.exitCode = 1;
693
+ return;
694
+ }
695
+ if (opts.checklist !== undefined) {
696
+ const findTitle = (nodes: BoardNode[]): string | undefined => {
697
+ for (const node of nodes) {
698
+ if (node.level === 'task' && node.id === opts.checklist) return node.title;
699
+ const nested = node.children ? findTitle(node.children) : undefined;
700
+ if (nested !== undefined) return nested;
701
+ }
702
+ return undefined;
703
+ };
704
+ if (opts.version !== undefined) {
705
+ try { validateVersion(opts.version); }
706
+ catch (error) {
707
+ out(error instanceof Error ? error.message : String(error));
708
+ process.exitCode = 1;
709
+ return;
710
+ }
711
+ }
712
+ const versions = opts.version !== undefined ? [opts.version]
713
+ : [checklistDevVersion(), ...(deps.releaseVersions?.() ?? (deps.releaseBoard ? [] : (() => {
714
+ const released = releasedVersion();
715
+ return assignedVersions().filter((version) => !released || compareVersions(version, released) > 0);
716
+ })()))];
717
+ const current = checklistDevVersion();
718
+ const orderedVersions = [...new Set(versions)].sort((a, b) => {
719
+ if (a === current) return -1;
720
+ if (b === current) return 1;
721
+ const aFuture = compareVersions(a, current) > 0;
722
+ const bFuture = compareVersions(b, current) > 0;
723
+ if (aFuture !== bFuture) return aFuture ? -1 : 1;
724
+ return aFuture ? compareVersions(a, b) : compareVersions(b, a);
725
+ });
726
+ const matches: Array<{ version: string; title: string }> = [];
727
+ for (const version of orderedVersions) {
728
+ try {
729
+ const title = findTitle((deps.releaseBoard ?? releasePackBoard)(version));
730
+ if (title !== undefined) matches.push({ version, title });
731
+ } catch (error) {
732
+ if (opts.version !== undefined) {
733
+ out(`체크리스트 판 읽기 실패: ${version}`);
734
+ process.exitCode = 1;
735
+ return;
736
+ }
737
+ console.error(`⚠ 체크리스트 판 ${version} 읽기 실패 — 다른 판 계속 조회: ${error instanceof Error ? error.message : String(error)}`);
738
+ }
739
+ }
740
+ const title = matches[0]?.title;
741
+ if (title === undefined) {
742
+ out(`체크리스트 칸 없음: ${opts.checklist}`);
743
+ process.exitCode = 1;
744
+ return;
745
+ }
746
+ if (matches.length > 1) console.error(`⚠ 체크리스트 칸 ${opts.checklist} 중복: ${matches.map((match) => match.version).join(', ')} — 가장 가까운 판 ${matches[0]!.version} 선택 (--version 으로 고정 가능)`);
747
+ if (opts.mission === undefined && text === undefined) text = title;
748
+ }
749
+ if (opts.checklist !== undefined && opts.mission === undefined && suppliedText && !text!.split(/\r?\n/, 1)[0]!.startsWith('대상 경로:')) {
750
+ out('칸 문면을 쓰려면 문면 인자를 빼라');
751
+ process.exitCode = 1;
752
+ return;
753
+ }
633
754
  await registerTaskAgentSink(deps.registerSink);
634
755
  if ((text === undefined) === (opts.mission === undefined)) {
635
756
  out('과제 한 줄 «또는» --mission <문면> 중 하나만 준다');
@@ -706,7 +827,7 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
706
827
  out(`${result.card.id}\t${result.mode}\t${result.launched ? 'launched' : 'not launched'}`);
707
828
  out(`elanous ${result.move.command!.map(shellQuote).join(' ')}`);
708
829
  if (result.cwd) out(`(cwd: ${result.cwd})`);
709
- if (result.card.taLand) out('(ta-land — 발사 env ELANOUS_TA_LAND=1 · 로컬 부모 · taskAgent.liveMoves 에 propose-land 가 있으면 병합은 TASK-AGENT 몫, 없으면 종전대로 호스트 병합)');
830
+ if (result.card.taLand) out('(ta-land — 발사 env ELANOUS_TA_LAND=1 · 원격 또는 로컬 부모 · taskAgent.liveMoves 에 propose-land 가 있으면 병합은 TASK-AGENT 몫, 없으면 종전대로 호스트 병합)');
710
831
  if (!result.launched) out('(shadow — 띄우지 않았다 · 띄우려면 --live)');
711
832
  }
712
833
  } catch (error) {
@@ -736,6 +857,24 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
736
857
  out([id, 'hand-move', outcome.entry.kind, outcome.entry.by, outcome.entry.detail, ...(outcome.entry.pr !== undefined ? [`pr ${outcome.entry.pr}`] : [])].join('\t'));
737
858
  });
738
859
 
860
+ tasks.command('live-verified <card>')
861
+ .description('TA-WIRING-CHECK — 실물 1회를 돌린 뒤 그 카드 런 원장에 live-verified {pr, ref, ok, card} 한 줄을 남긴다 · --ref(실물로 돌린 명령·화면 근거)가 비면 거부')
862
+ .requiredOption('--pr <number>', '실물로 확인한 PR 번호')
863
+ .requiredOption('--ref <근거>', '실물로 돌린 명령·화면 근거 한 줄(비면 거부)')
864
+ .option('--fail', '실물이 실패했다(ok=false)')
865
+ .action(async (cardId: string, opts: { pr: string; ref: string; fail?: boolean }) => {
866
+ await registerTaskAgentSink(deps.registerSink);
867
+ const pr = Number(opts.pr);
868
+ if (!Number.isInteger(pr) || pr <= 0) { out(`--pr 은 자연수다: ${opts.pr}`); process.exitCode = 1; return; }
869
+ let card: TaskCard | undefined;
870
+ try { card = readTaskCard(cardId, deps.taskStatePath); } catch (error) { out(error instanceof Error ? error.message : '과제 카드 읽기 실패'); process.exitCode = 1; return; }
871
+ if (!card) { out(`과제 카드 없음: ${cardId}`); process.exitCode = 1; return; }
872
+ const outcome = recordWiringLiveVerified(card, { pr, ref: opts.ref, ok: !opts.fail }, deps.liveVerifiedLedgerDir ? { ledgerDir: deps.liveVerifiedLedgerDir } : {});
873
+ if (!outcome.written) { out(`live-verified 한 줄을 못 남겼다 — ${outcome.reason}`); process.exitCode = 1; return; }
874
+ try { debug.log('task-agent', 'wiring-live-verified', { card: card.id, runId: card.runId ?? null, pr, ok: outcome.entry.data.ok }); } catch { /* fail-soft */ }
875
+ out([card.id, 'live-verified', `pr ${pr}`, outcome.entry.data.ok ? 'ok' : 'fail', outcome.entry.data.ref].join('\t'));
876
+ });
877
+
739
878
  tasks.command('close <cardId>')
740
879
  .description('과제 카드를 손으로 닫는다 — 상태를 failed 로 두고 사유를 history(closed-by-hand)에 한 줄 남긴다 · 없는 카드 id 는 거부(exit 1)')
741
880
  .requiredOption('--reason <사유>', '닫는 사유(비면 거부)')
@@ -937,6 +1076,9 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
937
1076
  for (const cardId of bindable) {
938
1077
  // HARNESS-PARENT-ON-MSB1: 원격 부모 런은 원장이 그 호스트에 있다 — HQ 거울로 먼저 당긴다(읽기 전용).
939
1078
  await mirrorRemoteCardLedger(cardId, deps);
1079
+ try { await replayRemoteCardMoves(cardId, deps.taskStatePath ?? taskStatePathDefault(), deps.cardRunEvidence ?? {}); } catch (error) {
1080
+ try { debug.log('task-agent', 'card-binding-replay-failed', { card: cardId, reason: error instanceof Error ? error.message : String(error) }); } catch { /* fail-soft */ }
1081
+ }
940
1082
  try { await refreshCardRunBinding(cardId, deps.taskStatePath ?? taskStatePathDefault(), deps.cardRunEvidence ?? {}); } catch (error) {
941
1083
  // 근거 없음으로 보인다 — 원장 부재와 갈리게 실패는 남긴다.
942
1084
  try { debug.log('task-agent', 'card-bind-failed', { card: cardId, via: 'show', error: error instanceof Error ? error.message : String(error) }); } catch { /* fail-soft */ }
@@ -1016,6 +1158,10 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
1016
1158
  const liveMoves = deps.rejudge?.liveMoves ?? await configuredTaskAgentLiveMoves();
1017
1159
  const all = [];
1018
1160
  for (const cardId of ids) {
1161
+ await mirrorRemoteCardLedger(cardId, deps);
1162
+ try { await replayRemoteCardMoves(cardId, statePath, deps.cardRunEvidence ?? {}); } catch (error) {
1163
+ try { debug.log('task-agent', 'card-binding-replay-failed', { card: cardId, reason: error instanceof Error ? error.message : String(error) }); } catch { /* fail-soft */ }
1164
+ }
1019
1165
  let outcomes: Awaited<ReturnType<typeof rejudgeCardOnHead>>;
1020
1166
  try { outcomes = await rejudgeCardOnHead(cardId, { ...deps.rejudge, liveMoves, live: { ...deps.rejudge?.live, statePath } }); } catch (error) {
1021
1167
  // 카드 하나의 예외가 --all 의 나머지 카드 판단을 멈추지 않게 — 사유를 남기고 다음 카드로.
@@ -1049,6 +1195,14 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
1049
1195
  try { debug.log('task-agent', 'regate-run', { card: opts.card, ...record, failures: result.failures.slice(0, 3) }); } catch { /* fail-soft */ }
1050
1196
  mkdir(dir(opts.out), { recursive: true });
1051
1197
  write(opts.out, JSON.stringify(record));
1198
+ if (deps.regateCompletion !== false) {
1199
+ try {
1200
+ const { rejudgeCompletedTaskRegate } = await import('../task-agent/rejudge-on-head.js');
1201
+ await rejudgeCompletedTaskRegate(opts.card, pr, opts.head, opts.out, deps.taskStatePath ?? taskStatePathDefault(), undefined, deps.rejudge);
1202
+ } catch (error) {
1203
+ try { debug.log('task-agent', 'regate-completion-rejudge-failed', { card: opts.card, pr, head: opts.head, reason: String(error).slice(-300) }, { level: 'warn' }); } catch { /* fail-soft */ }
1204
+ }
1205
+ }
1052
1206
  if (!result.passed) process.exitCode = 1;
1053
1207
  });
1054
1208
 
@@ -10,6 +10,7 @@ import type { Command } from 'commander';
10
10
  import { collectUnifiedUsage, formatUnifiedUsage } from '../budget/unified-usage.js';
11
11
  import { consumeCodexResetCredits, listCodexResetCredits } from '../budget/codex-reset-credits.js';
12
12
  import { rollupRunUsage, type RunUsageInput } from '../budget/run-usage-rollup.js';
13
+ import { dedupePodRollupRows } from '../../scripts/usage-rollup.js';
13
14
  import { formatUsageOutcomes, outcomeTableHasCodexGrokUnknown, queryUsageOutcomes, type UsageOutcomesDeps, type UsageOutcomesReport } from '../budget/usage-outcomes.js';
14
15
  import { LogStore, logsDbPath, type LogQuery, type LogStoreRow } from '../mss/logging/log-store.js';
15
16
  import { LOGS_SINCE_OPTION, parseSince } from './logs-cli.js';
@@ -189,7 +190,8 @@ export function registerUsageCommand(program: Command, deps: UsageCliDeps = {}):
189
190
  ...(sinceMs !== undefined ? { sinceMs } : {}),
190
191
  });
191
192
  const unwrapPod = opts.by === 'stage' || opts.by === 'model' || opts.by === 'account';
192
- const inputs = rows.map((row) => usageData(row, unwrapPod)).filter((data): data is ExtendedRunUsageInput => data !== null)
193
+ // ⭐ METER-POD-ROLLUP-GAP-2 — Pod 사용량 재방출 행(podRollupKey)은 «더 완전한 한 행»만 센다(키 없는 행은 그대로).
194
+ const inputs = dedupePodRollupRows(rows.map((row) => usageData(row, unwrapPod)).filter((data): data is ExtendedRunUsageInput => data !== null))
193
195
  .filter((data) => opts.run === undefined || data.runId === opts.run);
194
196
  if (opts.by === 'stage' || opts.by === 'model' || opts.by === 'account') {
195
197
  const report = rollupByAxis(inputs, opts.by);
@@ -13,6 +13,7 @@
13
13
 
14
14
  import type { LLMMessage } from '../llm.js';
15
15
  import { streamLLM } from '../llm.js';
16
+ import { debug } from '../debug/log.js';
16
17
  import { resolveSummarizerModel } from './provider.js';
17
18
  import { buildCompactTranscript, stripCompactScratchpad } from './summarize.js';
18
19
 
@@ -36,13 +37,26 @@ export interface VerifyProbeArgs {
36
37
  activeModelId?: string;
37
38
  summarizerModel?: string;
38
39
  timeoutMs?: number;
40
+ /** Injectable stream call — default `streamLLM` (byte-identical
41
+ * behavior when omitted). Tests inject a stub so the probe can be
42
+ * exercised with zero real LLM calls. */
43
+ stream?: typeof streamLLM;
39
44
  }
40
45
 
46
+ export type VerifyProbeStatus = 'pass' | 'fail' | 'error';
47
+
41
48
  export interface VerifyProbeResult {
42
49
  /** True when the probe judged the summary acceptable. */
43
50
  ok: boolean;
44
51
  /** Probe's response text (free form). Empty when probe failed. */
45
52
  notes: string;
53
+ /** Outcome classification: 'pass' = probe accepted the summary,
54
+ * 'fail' = probe found a lost detail (ok:false), 'error' = probe
55
+ * call failed/timed out (fail-open — ok stays true). */
56
+ status: VerifyProbeStatus;
57
+ /** The model the probe ran on (resolveSummarizerModel result);
58
+ * null when unresolved. */
59
+ model: string | null;
46
60
  }
47
61
 
48
62
  export async function runVerifyProbe(
@@ -61,18 +75,24 @@ export async function runVerifyProbe(
61
75
  },
62
76
  ];
63
77
  const timeoutMs = args.timeoutMs ?? 30_000;
78
+ const stream = args.stream ?? streamLLM;
64
79
  try {
65
80
  const text = await Promise.race([
66
- streamLLM(req, () => { /* silent */ }, model ? { model } : {}),
81
+ stream(req, () => { /* silent */ }, model ? { model } : {}),
67
82
  new Promise<string>((_, reject) =>
68
83
  setTimeout(() => reject(new Error('verify probe timeout')), timeoutMs),
69
84
  ),
70
85
  ]);
71
86
  const notes = stripCompactScratchpad(text).trim();
72
87
  const ok = /^none\b/i.test(notes) || notes.length === 0;
73
- return { ok, notes };
88
+ const status: VerifyProbeStatus = ok ? 'pass' : 'fail';
89
+ const result: VerifyProbeResult = { ok, notes, status, model: model ?? null };
90
+ debug.log('compact.verify-probe', 'probe-result', { status, model });
91
+ return result;
74
92
  } catch {
75
93
  // Probe failure is non-fatal — accept the summary by default.
76
- return { ok: true, notes: '' };
94
+ const result: VerifyProbeResult = { ok: true, notes: '', status: 'error', model: model ?? null };
95
+ debug.log('compact.verify-probe', 'probe-result', { status: result.status, model: result.model });
96
+ return result;
77
97
  }
78
98
  }
@@ -0,0 +1,40 @@
1
+ import type { ContextCard } from './index.js';
2
+
3
+ export interface CellCardItem {
4
+ readonly id: string;
5
+ readonly title: string;
6
+ readonly status: string;
7
+ readonly owner?: string | null;
8
+ readonly disposition?: string;
9
+ readonly evidence?: string;
10
+ }
11
+
12
+ const POINTER_PATTERN = /#\d+|run-[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/giu;
13
+
14
+ function extractPointers(text: string): string[] {
15
+ return [...text.matchAll(POINTER_PATTERN)].map(([pointer]) => pointer);
16
+ }
17
+
18
+ /** Build a compact checklist-cell card; evidence is used only to derive stable source pointers. */
19
+ export function buildCellCard(version: string, item: CellCardItem, asOf: string): ContextCard {
20
+ const pointers = [...new Set([
21
+ ...extractPointers(item.evidence ?? ''),
22
+ ...extractPointers(item.title),
23
+ `checklist:${version}/${item.id}`,
24
+ ])];
25
+ const reasons = [
26
+ item.owner ? `담당 ${item.owner}` : undefined,
27
+ item.disposition ? `처분 ${item.disposition}` : undefined,
28
+ ].filter((value): value is string => value !== undefined);
29
+ return {
30
+ id: `cell:${version}/${item.id}`,
31
+ kind: 'cell',
32
+ conclusion: (item.title.split(/[\r\n\u2028\u2029]/u, 1)[0] ?? '').trim(),
33
+ why: reasons.join(' · '),
34
+ verdict: item.status,
35
+ remaining: [],
36
+ pointers,
37
+ source: `release-checklist:${version}`,
38
+ updatedAt: asOf,
39
+ };
40
+ }
@@ -43,3 +43,53 @@ export function serializeContextCard(card: ContextCard, maxChars = CONTEXT_CARD_
43
43
  if (length(text) > maxChars) throw new RangeError('card core and omission counts exceed maxChars');
44
44
  return text;
45
45
  }
46
+
47
+ /** RFC context-diet §3a — exact fallback wording for a PR body that states no conclusion / could not be read. */
48
+ export const PR_CONCLUSION_NONE = '없음(원문에 결론 없음)';
49
+ export const PR_CONCLUSION_UNREADABLE = '확인 불가';
50
+
51
+ export interface PrConclusionCardInput {
52
+ readonly id: string;
53
+ /** First paragraph of the original body; empty or omitted means the original states no conclusion. */
54
+ readonly firstParagraph?: string;
55
+ /** Set when the original body could not be read at all. */
56
+ readonly unreadable?: boolean;
57
+ readonly pointers: readonly string[];
58
+ readonly source: string;
59
+ readonly updatedAt: string;
60
+ readonly supersedes?: string;
61
+ }
62
+
63
+ /** First blank-line-delimited paragraph of the original body, or '' when the body is blank. */
64
+ export function firstParagraphOf(body: string): string {
65
+ const trimmed = body.trim();
66
+ return trimmed ? (trimmed.split(/\n\s*\n/)[0] ?? '') : '';
67
+ }
68
+
69
+ const oneLine = (text: string): string => text.replace(/\s+/g, ' ').trim();
70
+
71
+ /** kind-'pr' conclusion card on the existing ContextCard schema; why/verdict/remaining stay empty unless grounded. */
72
+ export function buildPrConclusionCard(input: PrConclusionCardInput): ContextCard {
73
+ const conclusion = input.unreadable
74
+ ? PR_CONCLUSION_UNREADABLE
75
+ : oneLine(input.firstParagraph ?? '') || PR_CONCLUSION_NONE;
76
+ return {
77
+ id: input.id,
78
+ kind: 'pr',
79
+ conclusion,
80
+ why: '',
81
+ verdict: '',
82
+ remaining: [],
83
+ pointers: [...input.pointers],
84
+ source: input.source,
85
+ updatedAt: input.updatedAt,
86
+ ...(input.supersedes === undefined ? {} : { supersedes: input.supersedes }),
87
+ };
88
+ }
89
+
90
+ /** §3a display header; fallback conclusions keep the prescribed wording verbatim with no pointer suffix. */
91
+ export function prConclusionCardHeader(card: ContextCard): string {
92
+ const fallback = card.conclusion === PR_CONCLUSION_NONE || card.conclusion === PR_CONCLUSION_UNREADABLE;
93
+ const pointers = card.pointers.join(' · ');
94
+ return `결론: ${card.conclusion}${fallback || !pointers ? '' : ` · 포인터: ${pointers}`}`;
95
+ }
@@ -1,5 +1,7 @@
1
1
  import { readHqLease } from '../hq/hq.js';
2
2
  import { fileLeaseStore } from '../hq/lease.js';
3
+ import { readFileSync } from 'node:fs';
4
+ import { homedir } from 'node:os';
3
5
  import { join } from 'node:path';
4
6
  import { effectiveInstanceRoot } from '../instance/resolve.js';
5
7
  import { getElanousConfigDirOverride } from '../elanous-config-dir.js';
@@ -20,6 +22,8 @@ export interface ControlStatusRow {
20
22
  export interface ControlStatusDeps {
21
23
  readLease?: () => ReturnType<typeof readHqLease> | Promise<ReturnType<typeof readHqLease>>;
22
24
  readVersion?: () => ControlStatusRow | Promise<ControlStatusRow>;
25
+ /** Prefix that holds this machine's install.json. Defaults to ~/.local/share/elanous. */
26
+ installRoot?: string;
23
27
  readResources?: () => ControlStatusRow | Promise<ControlStatusRow>;
24
28
  readCredentials?: () => ControlStatusRow | Promise<ControlStatusRow>;
25
29
  readFreeze?: () => ReturnType<typeof readLandingFreeze> | Promise<ReturnType<typeof readLandingFreeze>>;
@@ -31,6 +35,31 @@ export interface ControlStatusDeps {
31
35
 
32
36
  const missing = (row: ControlStatusRowName, reason: string): ControlStatusRow => ({ row, state: 'unmeasured', text: '못 쟀다', reason });
33
37
 
38
+ function localInstallRoot(): string {
39
+ return join(homedir(), '.local', 'share', 'elanous');
40
+ }
41
+
42
+ /** This machine's install.json only — daemon and public versions stay unconnected. */
43
+ function localInstallVersionRow(installRoot = localInstallRoot()): ControlStatusRow {
44
+ let raw: string;
45
+ try {
46
+ raw = readFileSync(join(installRoot, 'install.json'), 'utf8');
47
+ } catch (error) {
48
+ return missing('판', (error as NodeJS.ErrnoException).code === 'ENOENT' ? '이 기계 install.json 없음' : '이 기계 install.json 읽기 실패');
49
+ }
50
+ try {
51
+ const parsed: unknown = JSON.parse(raw);
52
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return missing('판', '이 기계 install.json 파싱 실패');
53
+ const record = parsed as { version?: unknown; commit?: unknown };
54
+ const version = typeof record.version === 'string' ? record.version.trim() : '';
55
+ const sha = typeof record.commit === 'string' ? record.commit.trim() : '';
56
+ if (!version || !sha) return missing('판', '이 기계 install.json에 판·sha 없음');
57
+ return { row: '판', state: 'ok', text: `설치본 ${version} · ${sha}` };
58
+ } catch {
59
+ return missing('판', '이 기계 install.json 파싱 실패');
60
+ }
61
+ }
62
+
34
63
  /** Read-only snapshot: each source fails independently; no lease renewal, freeze mutation or config sync. */
35
64
  export async function collectControlStatus(deps: ControlStatusDeps = {}): Promise<ControlStatusRow[]> {
36
65
  const rows: ControlStatusRow[] = [];
@@ -55,7 +84,7 @@ export async function collectControlStatus(deps: ControlStatusDeps = {}): Promis
55
84
  return { row: '집', state: expired ? 'warn' : 'ok',
56
85
  text: `본부 ${record.holder} · 세대 ${record.generation} · ${ageSeconds}초 전 · ${expired ? '만료' : '유효'}` };
57
86
  });
58
- await add('판', deps.readVersion ?? (() => missing('판', '기계별 install.json·데몬 판·공개 판 원천 미연결')));
87
+ await add('판', deps.readVersion ?? (() => localInstallVersionRow(deps.installRoot)));
59
88
  await add('자원', deps.readResources ?? (() => missing('자원', '기계별 Pod 실행/대기/실패·풀 상한·호스트 부하 원천 미연결')));
60
89
  await add('자격', deps.readCredentials ?? (() => missing('자격', '계정별 만료·쿼터·갱신자 원천 미연결')));
61
90
  await add('동결·몫', async () => {
@@ -0,0 +1,35 @@
1
+ import { debug } from '../debug/log.js';
2
+
3
+ export interface BootTimer {
4
+ begin(): void;
5
+ phase(name: string): void;
6
+ done(): void;
7
+ }
8
+
9
+ export function createBootTimer(now: () => number = performance.now): BootTimer {
10
+ const startedAt = now();
11
+ let phaseStartedAt = startedAt;
12
+ let lastPhase: string | undefined;
13
+ let slowest: { phase: string; ms: number } | undefined;
14
+ let completed = false;
15
+
16
+ return {
17
+ begin(): void {
18
+ phaseStartedAt = now();
19
+ },
20
+ phase(name: string): void {
21
+ const current = now();
22
+ const ms = current - phaseStartedAt;
23
+ phaseStartedAt = current;
24
+ lastPhase = name;
25
+ if (!slowest || ms > slowest.ms) slowest = { phase: name, ms };
26
+ try { debug.log('tui.boot', 'phase', { phase: name, ms }); } catch { /* logging must not block startup */ }
27
+ },
28
+ done(): void {
29
+ if (completed) return;
30
+ completed = true;
31
+ const totalMs = now() - startedAt;
32
+ try { debug.log('tui.boot', 'summary', { totalMs, slowest: slowest ?? (lastPhase ? { phase: lastPhase, ms: totalMs } : null) }); } catch { /* logging must not block startup */ }
33
+ },
34
+ };
35
+ }