elanous 0.2.21 → 0.2.23

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 (780) hide show
  1. package/NOTICE +7 -0
  2. package/README.md +32 -22
  3. package/apps/pwa/out/404/index.html +1 -1
  4. package/apps/pwa/out/404.html +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{119fc678.6f591cdb84ca5791.js → 0673cc54.8e2ef1c23e49e190.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/{a9f2b54d-40c16bd0efdb04b8.js → 0a09e062-34f747a17d8d8c2e.js} +1 -1
  7. package/apps/pwa/out/_next/static/chunks/{f8626309.a4e5d362b1d55e59.js → 0e3acd34.d42b2ef87fdf4234.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +77 -0
  9. package/apps/pwa/out/_next/static/chunks/{7175-350f4ce2873bc038.js → 1325-dc3f3c21eb181cb4.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +34 -0
  11. package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +24 -0
  12. package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/{6767.8e6c5f6e744fcd9f.js → 1505.5826671109111e75.js} +2 -2
  14. package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/{7327-2d69fb321ba73389.js → 1669-da843ed73aa301f5.js} +1 -1
  21. package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +36 -0
  23. package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +122 -0
  24. package/apps/pwa/out/_next/static/chunks/2528.0af5c0e1fad88df6.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +62 -0
  27. package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/272-b23d2e92161d11fd.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{7899.597af4a9996c907f.js → 2721.bc9a8f36bd85c07a.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +149 -0
  35. package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3961-fbef064c213b2b18.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +309 -0
  39. package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{d70879db.c66c56a95a91efc6.js → 4c5e95ce.83e9b16add6fcd8c.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/{6158.566c890adc06a459.js → 5313.1697309c532b9856.js} +2 -2
  52. package/apps/pwa/out/_next/static/chunks/{79b78388.663188133449d707.js → 53746282.1be36038d1abd949.js} +1 -1
  53. package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5578.ac963634373b28c6.js +286 -0
  56. package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5967-c0a80f8ffe5d4050.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/{1268.0840ff91e083fcbd.js → 5974.360f8441eb0ac1ec.js} +1 -1
  59. package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +74 -0
  64. package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/6571-926ddf024a6ad5df.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +64 -0
  69. package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/{9832.2ab2e818013574c7.js → 6702.ebbd165d5e4a4a14.js} +1 -1
  71. package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +32 -0
  73. package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +24 -0
  74. package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +93 -0
  78. package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/{6110.1297d4093fdfbb0d.js → 740.90b31555290236a9.js} +2 -2
  83. package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +148 -0
  84. package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +226 -0
  85. package/apps/pwa/out/_next/static/chunks/{9070.067c106528ec1ae6.js → 7518.49161e8f5814abdb.js} +1 -1
  86. package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +27 -0
  87. package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +115 -0
  90. package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7905.b230b9d06cb4ad5d.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/{8194.484f51e273d9abd2.js → 8264.00e434fbd02e9311.js} +16 -16
  97. package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +8 -0
  99. package/apps/pwa/out/_next/static/chunks/{088d8e8a.8069543d082bec12.js → 83cfc5c8.349535543c1548b6.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +23 -0
  101. package/apps/pwa/out/_next/static/chunks/{1948.5f35b39eef222a94.js → 8438.ee7f0df3b3f6fcb4.js} +1 -1
  102. package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/{4588.ad3364cb7fb97ada.js → 8532.a86e99acf9b761cb.js} +2 -2
  105. package/apps/pwa/out/_next/static/chunks/8569.b853a8daa8f31d12.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8925-2abfb48af477fb7f.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/{88729267.9c6c000157c83f2f.js → 89849432.9eaa2f4c9c010965.js} +3 -3
  110. package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +90 -0
  111. package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +94 -0
  112. package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +41 -0
  114. package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +287 -0
  116. package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +79 -0
  117. package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/{3522-1de1319d028ac89c.js → 9502-32c5dc22e8f120f5.js} +3 -3
  120. package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +104 -0
  123. package/apps/pwa/out/_next/static/chunks/{7630.2b9a68659053ff4e.js → 9976.8f28864317639fe6.js} +16 -16
  124. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d5341ac96203a983.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-0160ab83c8685a12.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/board/page-55c631c032dcc47e.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ad3bd8084048bee4.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/bots/page-e6784759a2531031.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/ceo/page-5c5d0e370f495ef6.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/chat/page-c325e21543cd48a8.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/consult/{page-111cabe4d1fd69ae.js → page-6168a7c43e6ef8f5.js} +1 -1
  133. package/apps/pwa/out/_next/static/chunks/app/control/page-31417d3604154a6d.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/decisions/page-e9606dc0bdec9305.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/design-check/page-a648bc464c9dc754.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/editor/page-25bb425afdb27541.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/exec/page-32d72fdef1afe11a.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/field/page-d27b794c8ba76bbb.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/inside/page-2bd9ce9c020d02d4.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/intake/page-a34096245e63b9f2.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/layout-22170f4f00a15496.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live/page-4cc66d22ca4ec502.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/live-run/page-83b14c729fcea837.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/loops/page-6e2781c523dad761.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/market/page-26dd415c8f13f341.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-ccdb83ed40c8d724.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/morning/page-7ad3de8fa06fdea9.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/not-found-015c02c4fec4023e.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/observatory/page-6b0ae5b5c42f6d2f.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-786111f30b6f0969.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-48fb31810693c357.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e17cce5e2ed0fee.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/outputs/page-cb154acadb025414.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/page-16258e956ea93fc2.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/reflection/page-c2dd2b19c93f90ab.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-85f35dd1dd96ae87.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/sessions/page-d3c007c8a0ddd7ee.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7837ce2aacb97b04.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/settings/page-7350ee93f4fe1033.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-00723458575f2b19.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/page-745d9b6c015076f8.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/share/page-736d33c7414a8a1a.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/showroom/page-119be9a0444d2482.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/tasks/page-fa806c018833e332.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/term/page-c782041b5f5199ba.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/today/page-d431fbdea6ad93dd.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/trace/page-0c056abff82b9891.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/vault/page-242d668e4fbf72c4.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-847c3de6ca8a4416.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/page-81dd0d8ae923ed72.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workspace/page-74e69ba2c8e970d4.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-70038f41ae7cf931.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/b4e12462-5fab4a813a63dadd.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/{f6b7c9ba.64a895b8b2fedbdc.js → ce383d63.d2ede338788ed18e.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/{framework-5c169757551134ed.js → framework-b2763b10dc6b3836.js} +1 -1
  179. package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +1 -0
  184. package/apps/pwa/out/_next/static/css/5619d59e87eddf66.css +1 -0
  185. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +1 -0
  186. package/apps/pwa/out/_next/static/{MObU8ujkMciAKr6ljAV05 → rfkMm4movqkqMebBrCXiR}/_buildManifest.js +1 -1
  187. package/apps/pwa/out/approvals/index.html +1 -1
  188. package/apps/pwa/out/approvals/index.txt +23 -23
  189. package/apps/pwa/out/autopilot/index.html +1 -1
  190. package/apps/pwa/out/autopilot/index.txt +23 -23
  191. package/apps/pwa/out/board/index.html +1 -1
  192. package/apps/pwa/out/board/index.txt +23 -23
  193. package/apps/pwa/out/botlab/index.html +1 -1
  194. package/apps/pwa/out/botlab/index.txt +22 -22
  195. package/apps/pwa/out/bots/index.html +1 -1
  196. package/apps/pwa/out/bots/index.txt +22 -22
  197. package/apps/pwa/out/ceo/index.html +1 -1
  198. package/apps/pwa/out/ceo/index.txt +23 -23
  199. package/apps/pwa/out/chat/index.html +1 -1
  200. package/apps/pwa/out/chat/index.txt +22 -22
  201. package/apps/pwa/out/consult/index.html +1 -1
  202. package/apps/pwa/out/consult/index.txt +23 -23
  203. package/apps/pwa/out/control/index.html +1 -1
  204. package/apps/pwa/out/control/index.txt +23 -23
  205. package/apps/pwa/out/decisions/index.html +1 -1
  206. package/apps/pwa/out/decisions/index.txt +22 -22
  207. package/apps/pwa/out/design-check/index.html +1 -1
  208. package/apps/pwa/out/design-check/index.txt +23 -23
  209. package/apps/pwa/out/editor/index.html +1 -1
  210. package/apps/pwa/out/editor/index.txt +24 -23
  211. package/apps/pwa/out/exec/index.html +1 -1
  212. package/apps/pwa/out/exec/index.txt +23 -23
  213. package/apps/pwa/out/field/index.html +1 -1
  214. package/apps/pwa/out/field/index.txt +23 -23
  215. package/apps/pwa/out/healthz +1 -1
  216. package/apps/pwa/out/index.html +1 -1
  217. package/apps/pwa/out/index.txt +22 -22
  218. package/apps/pwa/out/inside/index.html +1 -1
  219. package/apps/pwa/out/inside/index.txt +22 -22
  220. package/apps/pwa/out/intake/index.html +1 -1
  221. package/apps/pwa/out/intake/index.txt +23 -23
  222. package/apps/pwa/out/live/index.html +1 -1
  223. package/apps/pwa/out/live/index.txt +23 -23
  224. package/apps/pwa/out/live-run/index.html +1 -1
  225. package/apps/pwa/out/live-run/index.txt +24 -23
  226. package/apps/pwa/out/loops/index.html +1 -1
  227. package/apps/pwa/out/loops/index.txt +22 -22
  228. package/apps/pwa/out/market/index.html +1 -1
  229. package/apps/pwa/out/market/index.txt +22 -22
  230. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  231. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  232. package/apps/pwa/out/morning/index.html +1 -1
  233. package/apps/pwa/out/morning/index.txt +23 -23
  234. package/apps/pwa/out/observatory/index.html +1 -1
  235. package/apps/pwa/out/observatory/index.txt +23 -23
  236. package/apps/pwa/out/ops/checklist/index.html +1 -1
  237. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  238. package/apps/pwa/out/ops/release/index.html +1 -1
  239. package/apps/pwa/out/ops/release/index.txt +22 -22
  240. package/apps/pwa/out/ops/seats/index.html +1 -1
  241. package/apps/pwa/out/ops/seats/index.txt +22 -22
  242. package/apps/pwa/out/outputs/index.html +1 -1
  243. package/apps/pwa/out/outputs/index.txt +22 -22
  244. package/apps/pwa/out/reflection/index.html +1 -1
  245. package/apps/pwa/out/reflection/index.txt +23 -23
  246. package/apps/pwa/out/scheduler/index.html +1 -1
  247. package/apps/pwa/out/scheduler/index.txt +23 -23
  248. package/apps/pwa/out/sessions/index.html +1 -1
  249. package/apps/pwa/out/sessions/index.txt +22 -22
  250. package/apps/pwa/out/settings/devices/index.html +1 -1
  251. package/apps/pwa/out/settings/devices/index.txt +23 -23
  252. package/apps/pwa/out/settings/index.html +1 -1
  253. package/apps/pwa/out/settings/index.txt +23 -23
  254. package/apps/pwa/out/setup/done/index.html +1 -1
  255. package/apps/pwa/out/setup/done/index.txt +23 -23
  256. package/apps/pwa/out/setup/index.html +1 -1
  257. package/apps/pwa/out/setup/index.txt +23 -23
  258. package/apps/pwa/out/share/index.html +1 -1
  259. package/apps/pwa/out/share/index.txt +23 -23
  260. package/apps/pwa/out/showroom/index.html +1 -1
  261. package/apps/pwa/out/showroom/index.txt +22 -22
  262. package/apps/pwa/out/tasks/index.html +1 -1
  263. package/apps/pwa/out/tasks/index.txt +23 -23
  264. package/apps/pwa/out/term/index.html +1 -1
  265. package/apps/pwa/out/term/index.txt +23 -23
  266. package/apps/pwa/out/today/index.html +1 -1
  267. package/apps/pwa/out/today/index.txt +23 -23
  268. package/apps/pwa/out/trace/index.html +1 -1
  269. package/apps/pwa/out/trace/index.txt +23 -23
  270. package/apps/pwa/out/vault/index.html +1 -1
  271. package/apps/pwa/out/vault/index.txt +23 -23
  272. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  273. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  274. package/apps/pwa/out/workflows/index.html +1 -1
  275. package/apps/pwa/out/workflows/index.txt +23 -23
  276. package/apps/pwa/out/workspace/index.html +1 -1
  277. package/apps/pwa/out/workspace/index.txt +23 -23
  278. package/apps/pwa/out/worktrees/index.html +1 -1
  279. package/apps/pwa/out/worktrees/index.txt +23 -23
  280. package/catalog/models/anthropic/claude-haiku-5-5.yaml +32 -0
  281. package/catalog/models/anthropic/claude-opus-5-5.yaml +5 -0
  282. package/catalog/models/anthropic/claude-sonnet-5-5.yaml +31 -0
  283. package/catalog/models/anthropic/claude-sonnet-5.yaml +8 -2
  284. package/catalog/models/openai/gpt-6-astra.yaml +6 -0
  285. package/catalog/models/openai/gpt-6-luna.yaml +6 -0
  286. package/catalog/models/openai/gpt-6-sol.yaml +6 -0
  287. package/graphs/catalog/catalog.yaml +1 -1
  288. package/graphs/drafts/recipes.yaml +2 -2
  289. package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
  290. package/graphs/log-horizon/recipes.yaml +3 -0
  291. package/graphs/release/recipes.yaml +1 -1
  292. package/graphs/release/release-loop.yaml +6 -2
  293. package/graphs/release-rehearsal/recipes.yaml +12 -0
  294. package/graphs/release-rehearsal/release-rehearsal.yaml +17 -0
  295. package/graphs/test-diet/recipes.yaml +3 -0
  296. package/graphs/test-diet/test-diet.yaml +3 -1
  297. package/package.json +4 -1
  298. package/scripts/bench-report.ts +82 -3
  299. package/scripts/ci-typecheck-changed.ts +10 -1
  300. package/scripts/f-session-monitor.ts +69 -0
  301. package/scripts/hq/hq-fence-wrapper.sh +148 -0
  302. package/scripts/hq/standby-snapshot.ts +7 -3
  303. package/scripts/knowledge-compress.ts +11 -0
  304. package/scripts/lib/typecheck-ratchet.ts +51 -0
  305. package/scripts/nightly-docops.ts +90 -3
  306. package/scripts/openai-relay-server.ts +5 -1
  307. package/scripts/release-loop/docs-node.ts +258 -43
  308. package/scripts/release-loop/gate-method.ts +59 -0
  309. package/scripts/release-loop/gate-node.ts +73 -7
  310. package/scripts/release-loop/gate-wall.ts +208 -0
  311. package/scripts/release-loop/known-issues-node.ts +53 -8
  312. package/scripts/release-loop/publish-at.ts +14 -0
  313. package/scripts/release-loop/publish-node.ts +17 -2
  314. package/scripts/release-loop/resume-release.ts +34 -4
  315. package/scripts/release-loop/resume.ts +53 -0
  316. package/scripts/release-loop/shard-plan.ts +3 -11
  317. package/scripts/release-loop/tui-node-checks.ts +22 -0
  318. package/scripts/release-loop/unattended-release.ts +8 -1
  319. package/scripts/research-coo-admin-dates.ts +39 -0
  320. package/scripts/rhythm/daily.ts +51 -2
  321. package/scripts/rhythm/weekly.ts +3 -2
  322. package/scripts/skills/public-check.ts +7 -2
  323. package/scripts/smart-merge/resync-shadow.ts +5 -3
  324. package/scripts/test-diet/lib.ts +81 -1
  325. package/scripts/test-diet/node.ts +48 -2
  326. package/scripts/tsc-main-safety-net.ts +189 -0
  327. package/scripts/usage-rollup.ts +8 -4
  328. package/scripts/verify-coo-admin-evidence.ts +83 -0
  329. package/src/acp/client.ts +4 -2
  330. package/src/acp/codex-plugins.ts +48 -6
  331. package/src/agent/monad-agent-turn.ts +67 -5
  332. package/src/agent/run-context.ts +14 -0
  333. package/src/agent/tool-profile.ts +28 -2
  334. package/src/agent-env/profile.ts +25 -5
  335. package/src/agent-mission/acp-judge.ts +8 -2
  336. package/src/agent-mission/capabilities-cli.ts +16 -1
  337. package/src/agent-mission/driver.ts +27 -13
  338. package/src/agent-mission/pr-review-watch.ts +6 -2
  339. package/src/agent-mission/review-loop.ts +33 -5
  340. package/src/agent-mission/supervisor-metrics.ts +17 -2
  341. package/src/agent-substrate/acp-reviewer.ts +25 -9
  342. package/src/agent-substrate/pr-reviewer.ts +175 -32
  343. package/src/agent-substrate/review-intent.ts +106 -5
  344. package/src/agent-substrate/self-review-cli.ts +111 -16
  345. package/src/agent-substrate/shard-boundary-intent.ts +92 -26
  346. package/src/ask-user-question/pending-questions.ts +8 -2
  347. package/src/autopilot/build/llm-conflict-merge.ts +238 -20
  348. package/src/autopilot/codebase-grounding.ts +44 -0
  349. package/src/autopilot/llm-control-brain.ts +13 -1
  350. package/src/autopilot/mission-codebase-gate.ts +8 -77
  351. package/src/autopilot/pr-manager.ts +30 -11
  352. package/src/away/release-watch.ts +47 -8
  353. package/src/boot/acp-server.ts +4 -7
  354. package/src/boot/acp-socket-path.ts +7 -0
  355. package/src/briefing/brief-items.ts +123 -22
  356. package/src/chat/index.ts +13 -3
  357. package/src/cli/agent-cli.ts +20 -0
  358. package/src/cli/brief-cli.ts +46 -22
  359. package/src/cli/cli-user-error.ts +9 -2
  360. package/src/cli/config-classify.ts +83 -0
  361. package/src/cli/control-cli.ts +14 -0
  362. package/src/cli/decisions-cli.ts +26 -16
  363. package/src/cli/log-event-names.ts +3 -0
  364. package/src/cli/logs-cli.ts +1 -0
  365. package/src/cli/logs-model-input.ts +1 -1
  366. package/src/cli/mcp-login.ts +111 -37
  367. package/src/cli/plugin-cli.ts +21 -1
  368. package/src/cli/pod-cli.ts +26 -0
  369. package/src/cli/pr-cli.ts +94 -9
  370. package/src/cli/pr-land-overlap-evidence.ts +131 -0
  371. package/src/cli/release-cli.ts +74 -15
  372. package/src/cli/self-update.ts +173 -10
  373. package/src/cli/skills-cli.ts +12 -3
  374. package/src/cli/tasks-cli.ts +241 -28
  375. package/src/connectors/types.ts +6 -6
  376. package/src/context-bus/context-first.ts +51 -2
  377. package/src/context-bus/context-now-surfaces.ts +29 -0
  378. package/src/context-bus/coord-events.ts +32 -4
  379. package/src/context-bus/long-term-memory.ts +26 -7
  380. package/src/context-bus/nightly-condense.ts +170 -21
  381. package/src/control/control-status.ts +87 -0
  382. package/src/control-plane/light-member.ts +5 -3
  383. package/src/control-plane/member.ts +172 -7
  384. package/src/core-turn/run-goal-loop.ts +108 -3
  385. package/src/dashboard/chat-fold.ts +20 -0
  386. package/src/dashboard/first-screen-band.ts +151 -1
  387. package/src/dashboard/index.ts +27 -5
  388. package/src/dashboard/slash-runtime/dashboard-handlers.ts +14 -3
  389. package/src/dashboard/stale-install-check.ts +13 -2
  390. package/src/dashboard/turn-stream-formatter.ts +25 -0
  391. package/src/debug/log-diet.ts +159 -0
  392. package/src/debug/log.ts +52 -17
  393. package/src/decisions/decision-cards.ts +20 -1
  394. package/src/decisions/decision-ledger.ts +11 -8
  395. package/src/decisions/web-push-decision-cards.ts +19 -3
  396. package/src/discord-self-message.ts +2 -2
  397. package/src/display/coordinator.ts +25 -2
  398. package/src/domains/coo-admin-dates.evidence.json +876 -0
  399. package/src/domains/coo-admin-tool.ts +75 -14
  400. package/src/domains/cron-match.ts +1 -0
  401. package/src/domains/ops-status.ts +53 -0
  402. package/src/domains/outbound-alert.ts +41 -7
  403. package/src/domains/release-tool.ts +119 -10
  404. package/src/domains/schedule-registry.ts +10 -7
  405. package/src/domains/schedule-runner.ts +1 -0
  406. package/src/elanous-config-dir.ts +2 -2
  407. package/src/elanous-daemon.ts +3 -3
  408. package/src/exec-requests/planner.ts +6 -0
  409. package/src/execution-loop/launch-gate.ts +1 -1
  410. package/src/expression/i18n/messages.en.ts +5 -0
  411. package/src/expression/i18n/messages.ja.ts +5 -0
  412. package/src/expression/i18n/messages.ko.ts +5 -0
  413. package/src/expression/i18n/messages.zh.ts +5 -0
  414. package/src/expression/i18n/types.ts +8 -0
  415. package/src/github/pr-labels.ts +1 -0
  416. package/src/graph-kinds/registry.ts +6 -6
  417. package/src/graph-runner/graph-cli.ts +34 -2
  418. package/src/graph-runner/graph-run-api.ts +7 -0
  419. package/src/graph-runner/graph-tick.ts +73 -12
  420. package/src/graph-runner/runner.ts +94 -13
  421. package/src/graph-unify/wf-to-graph.ts +79 -0
  422. package/src/graph-wizard/generate.ts +34 -2
  423. package/src/graph-wizard/steps.ts +13 -0
  424. package/src/harness/dispatch-backpressure.ts +259 -0
  425. package/src/harness/harness-cli-command.ts +227 -50
  426. package/src/harness/harness-queue.ts +58 -14
  427. package/src/harness/harness-seams.ts +2 -20
  428. package/src/harness/harness-substrate-default.ts +72 -1
  429. package/src/harness/launch-advice.ts +23 -0
  430. package/src/harness/nested-elanous-policy.ts +4 -2
  431. package/src/hq/fence-wrapper.ts +7 -0
  432. package/src/hq/hq.ts +33 -2
  433. package/src/hq/lease.ts +13 -0
  434. package/src/hq/seats.ts +114 -18
  435. package/src/index.ts +199 -71
  436. package/src/intake-plane/collect-github.ts +19 -1
  437. package/src/intake-plane/digest.ts +45 -20
  438. package/src/intake-plane/lens.ts +36 -8
  439. package/src/intelligence-map/model-alias.ts +6 -0
  440. package/src/intelligence-map/model-catalog.ts +41 -0
  441. package/src/knowledge/conclusion-compress.ts +93 -0
  442. package/src/knowledge/kgs/pack.ts +5 -2
  443. package/src/knowledge/kgs/sqlite-store.ts +15 -0
  444. package/src/knowledge/know-find.ts +9 -2
  445. package/src/knowledge/query.ts +20 -0
  446. package/src/knowledge/tools/knowledge-query.ts +20 -2
  447. package/src/knowledge/write.ts +234 -2
  448. package/src/llm/bedrock-provider.ts +175 -0
  449. package/src/llm/bedrock.ts +345 -0
  450. package/src/llm/provider-credentials.ts +3 -1
  451. package/src/llm.ts +332 -51
  452. package/src/loops/budget.ts +150 -0
  453. package/src/loops/neighbor-runtime.ts +88 -0
  454. package/src/loops/orchestrator/author-depth.ts +29 -11
  455. package/src/loops/orchestrator/overlap.ts +7 -1
  456. package/src/loops/orchestrator/resync-shadow.ts +1 -1
  457. package/src/loops/orchestrator/seat-share.ts +6 -49
  458. package/src/loops/orchestrator/tick.ts +35 -2
  459. package/src/loops/orchestrator/traffic.ts +6 -80
  460. package/src/loops/registry.ts +5 -0
  461. package/src/market/publish.ts +17 -1
  462. package/src/market/signed-index.ts +42 -0
  463. package/src/maturity/feature-maturity.ts +2 -1
  464. package/src/mcp/mcp-oauth.ts +136 -17
  465. package/src/model-tier/llm-tier-map.ts +48 -4
  466. package/src/models/prompts.ts +22 -1
  467. package/src/mss/logging/horizon-watch.ts +168 -0
  468. package/src/mss/logging/log-store.ts +204 -15
  469. package/src/mss/logging/redaction.ts +17 -0
  470. package/src/native-tool-catalog.ts +1 -1
  471. package/src/nexus/api/consult-requests.ts +7 -10
  472. package/src/nexus/api/discord-trigger-bot.ts +6 -3
  473. package/src/nexus/api/draft-metrics.ts +22 -8
  474. package/src/nexus/api/error-reports.ts +30 -8
  475. package/src/nexus/api/graph-peer-edit.ts +77 -0
  476. package/src/nexus/api/graph-wizard-api.ts +9 -1
  477. package/src/nexus/api/graphs-api.ts +145 -7
  478. package/src/nexus/api/http-server.ts +101 -8
  479. package/src/nexus/api/loop-resources.ts +42 -0
  480. package/src/nexus/api/outbound-report.ts +8 -3
  481. package/src/nexus/api/plugins-market.ts +24 -0
  482. package/src/nexus/api/telegram-trigger-bot.ts +6 -3
  483. package/src/nexus/index.ts +13 -2
  484. package/src/nexus/outbound/format.ts +2 -0
  485. package/src/nexus/outbound/router.ts +198 -13
  486. package/src/oauth/claude-pty-maturity.ts +24 -0
  487. package/src/oauth/codex-account-rotation.ts +16 -18
  488. package/src/oauth/codex-account-store.ts +134 -5
  489. package/src/oauth/fallback-chain.ts +50 -15
  490. package/src/onboarding.ts +2 -1
  491. package/src/plugins/adapters/claude-package.ts +4 -12
  492. package/src/plugins/core/capability-policy.ts +141 -0
  493. package/src/plugins/core/host.ts +21 -8
  494. package/src/plugins/core/manifest.ts +19 -2
  495. package/src/plugins/core/trust-store.ts +15 -0
  496. package/src/plugins/core/types.ts +12 -0
  497. package/src/plugins/install/market-fetch.ts +68 -16
  498. package/src/plugins/install/plugin-install.ts +187 -16
  499. package/src/plugins/maker/market-bundle.ts +9 -0
  500. package/src/plugins/maker/plugin-maker.ts +32 -21
  501. package/src/plugins/maker/wizard-generate.ts +87 -9
  502. package/src/policy/llm-policy.ts +24 -6
  503. package/src/process/pid-liveness.ts +1 -1
  504. package/src/prompt-cache/openai.ts +10 -6
  505. package/src/prompt-cache/openrouter.ts +94 -0
  506. package/src/prompt-enhance/enhance.ts +46 -5
  507. package/src/prompt-library/family-prompt-coverage.ts +1 -0
  508. package/src/prompt-library/universal-preamble.ts +2 -2
  509. package/src/registry/discovery/openrouter-live-resolve.ts +122 -0
  510. package/src/registry/loader.ts +6 -1
  511. package/src/release-loop/checklist-board.ts +27 -0
  512. package/src/release-loop/checklist.ts +62 -9
  513. package/src/release-loop/feature-store.ts +3 -0
  514. package/src/release-loop/gate-shards.ts +48 -4
  515. package/src/release-loop/landed-to-green.ts +81 -0
  516. package/src/release-loop/light-rc.ts +11 -1
  517. package/src/release-loop/merged-pr-checklist.ts +10 -0
  518. package/src/release-loop/placement.ts +91 -22
  519. package/src/release-loop/rehearsal.ts +317 -0
  520. package/src/release-loop/release-schedule.ts +13 -1
  521. package/src/release-loop/rubric-types.ts +1 -0
  522. package/src/release-loop/rubric.ts +2 -2
  523. package/src/retro/daily.ts +23 -9
  524. package/src/seat-address/seat-address.ts +1 -0
  525. package/src/seat-loop/seat-loop.ts +208 -21
  526. package/src/seat-loop/seat-report.ts +29 -1
  527. package/src/seat-loop/traffic-signal.ts +44 -0
  528. package/src/self-dev/ask-launch-flow.ts +2 -2
  529. package/src/self-dev/dev-cli.ts +157 -11
  530. package/src/self-dev/dev-pipeline.ts +18 -1
  531. package/src/self-dev/draft-residue.ts +463 -0
  532. package/src/self-dev/draft-sweep.ts +195 -17
  533. package/src/self-dev/draft-triage-rules.ts +27 -1
  534. package/src/self-dev/launch-preflight-text.ts +549 -0
  535. package/src/self-dev/launch-preflight.ts +10 -545
  536. package/src/self-dev/orchestrate-cli.ts +57 -2
  537. package/src/self-dev/orchestrate-summary-line.ts +13 -0
  538. package/src/self-dev/orchestrate.ts +9 -133
  539. package/src/self-dev/review-provider-fallback.ts +179 -0
  540. package/src/self-dev/run-store.ts +1 -3
  541. package/src/self-dev/run-supervisor.ts +8 -23
  542. package/src/self-dev/run-types.ts +178 -0
  543. package/src/self-dev/shard-aggregate.ts +61 -13
  544. package/src/self-dev/shard-plan.ts +5 -1
  545. package/src/self-dev/shard-run.ts +23 -5
  546. package/src/self-dev/supervisor-verdict-edges.ts +2 -4
  547. package/src/self-implement/blocked-draft-policy.ts +3 -19
  548. package/src/self-implement/draft-on-stop-mode.ts +18 -0
  549. package/src/self-implement/follow-up-goals.ts +114 -38
  550. package/src/self-implement/gate-baseline-reap.ts +157 -0
  551. package/src/self-implement/gate-baseline.ts +78 -16
  552. package/src/self-implement/gate-cli.ts +12 -2
  553. package/src/self-implement/gate-remote.ts +17 -6
  554. package/src/self-implement/goal-author.ts +24 -4
  555. package/src/self-implement/goal-digest.ts +19 -0
  556. package/src/self-implement/graph-overlay-condition.ts +4 -0
  557. package/src/self-implement/harness-policy-gates.ts +7 -5
  558. package/src/self-implement/headless-elanous-driver.ts +11 -9
  559. package/src/self-implement/host-regate.ts +148 -43
  560. package/src/self-implement/l8-merge-queue.ts +147 -13
  561. package/src/self-implement/merge-train.ts +131 -0
  562. package/src/self-implement/off-diff-evidence.ts +9 -0
  563. package/src/self-implement/orchestrator.ts +201 -43
  564. package/src/self-implement/review-finding-recurrence.ts +28 -0
  565. package/src/self-implement/rework-policy.ts +2 -1
  566. package/src/self-implement/round-summary-card.ts +63 -0
  567. package/src/self-implement/run-ledger.ts +4 -3
  568. package/src/self-implement/run-step-projection.ts +147 -0
  569. package/src/self-implement/run-stop.ts +1 -1
  570. package/src/self-implement/seams.ts +41 -6
  571. package/src/self-implement/self-implement-cli.ts +6 -0
  572. package/src/self-implement/train-gate-remote.ts +158 -0
  573. package/src/session-runtime/index.ts +10 -1
  574. package/src/session-runtime/retry-api.ts +11 -1
  575. package/src/shell-env-bootstrap.ts +19 -4
  576. package/src/skills/gift-install.ts +119 -0
  577. package/src/skills/runner.ts +59 -2
  578. package/src/skills/skill-feedback.ts +31 -1
  579. package/src/skills/skill-tier.ts +1 -0
  580. package/src/smart-wizard/capability-index.ts +231 -0
  581. package/src/smart-wizard/rung.ts +74 -0
  582. package/src/steward/launch.ts +20 -9
  583. package/src/steward/triage.ts +29 -10
  584. package/src/storage/file-lock.ts +40 -4
  585. package/src/task-agent/actions.ts +4 -0
  586. package/src/task-agent/card-evidence.ts +59 -13
  587. package/src/task-agent/completion-evidence.ts +31 -3
  588. package/src/task-agent/cover.ts +61 -0
  589. package/src/task-agent/judge.ts +4 -3
  590. package/src/task-agent/land-worktree.ts +201 -0
  591. package/src/task-agent/live-move-history.ts +133 -0
  592. package/src/task-agent/live-moves.ts +222 -12
  593. package/src/task-agent/parent-host.ts +117 -8
  594. package/src/task-agent/rejudge-on-head.ts +297 -0
  595. package/src/task-agent/review-result-capture.ts +218 -0
  596. package/src/task-agent/shadow.ts +118 -7
  597. package/src/task-agent/task-hand.ts +138 -11
  598. package/src/task-orchestrator/surfaces/pod-child-providers.ts +29 -0
  599. package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
  600. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +16 -2
  601. package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
  602. package/src/task-orchestrator/surfaces/pod-lease.ts +93 -12
  603. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +25 -2
  604. package/src/task-orchestrator/surfaces/pod-pool.ts +203 -28
  605. package/src/task-orchestrator/surfaces/self-implement-pod.ts +259 -36
  606. package/src/task-orchestrator/surfaces/self-implement.ts +11 -0
  607. package/src/telegram-commands.ts +8 -0
  608. package/src/telegram-project-command.ts +6 -0
  609. package/src/telegram-service.ts +5 -1
  610. package/src/telegram.ts +17 -4
  611. package/src/time/format.ts +13 -4
  612. package/src/tool-runtime/goal-author-runtime.ts +1 -0
  613. package/src/tool-runtime/self-cognition-catalog.ts +23 -0
  614. package/src/tool-runtime/self-cognition-runtimes.ts +2 -24
  615. package/src/typecheck-ratchet.ts +2 -1
  616. package/src/user-config.ts +167 -28
  617. package/src/ux-sim/slash-menu-frames.ts +168 -0
  618. package/src/version/packed-revision.json +1 -1
  619. package/src/web-terminal/preview-tap-registry.ts +5 -2
  620. package/src/workflow-runtime/executor.ts +24 -2
  621. package/src/workflow-runtime/triggers/registry.ts +27 -0
  622. package/src/workflow-runtime/triggers/schedule-source.ts +30 -3
  623. package/src/workflow-runtime/triggers/scheduler.ts +1 -0
  624. package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +0 -148
  625. package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +0 -32
  626. package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +0 -309
  627. package/apps/pwa/out/_next/static/chunks/1307-c97eba9fb72a9a5e.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +0 -122
  629. package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +0 -149
  630. package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +0 -79
  631. package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +0 -24
  633. package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +0 -27
  638. package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +0 -36
  647. package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +0 -286
  648. package/apps/pwa/out/_next/static/chunks/2489-ff55a35b202c0f94.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +0 -94
  661. package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/3857-995ea9f5ef33d71e.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +0 -74
  669. package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +0 -34
  674. package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +0 -115
  676. package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +0 -77
  680. package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +0 -90
  684. package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/5977-59fedea50d13c762.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +0 -8
  689. package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +0 -64
  690. package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +0 -287
  692. package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +0 -226
  693. package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +0 -41
  701. package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +0 -24
  704. package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +0 -104
  714. package/apps/pwa/out/_next/static/chunks/8857-f1762140ef9a96b1.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +0 -93
  717. package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/9247-7581825d511a64c0.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +0 -23
  721. package/apps/pwa/out/_next/static/chunks/9497-b0e758d1cd4ae8d7.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +0 -62
  723. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/approvals/page-937c92292a4ab4f0.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d781be3e3a9cfd74.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/board/page-b0a80997903852d8.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/botlab/page-2b1263165630d9c8.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/bots/page-ea998f7f5d156bea.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/ceo/page-33c328b64ca508f8.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/chat/page-e2d6bed48ac20120.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/app/control/page-544dd4bd4847eeb7.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/app/decisions/page-3ee191319bf97d87.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e4bcb2c503dab04b.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/app/editor/page-300897dcbbd5ed76.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/app/exec/page-a449f1ed472b81c2.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/app/field/page-9045094d6d3b5cd0.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/app/inside/page-c06673596849ef45.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/intake/page-103fa3191c1b2e08.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/layout-9f81233f29dcd409.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/live/page-be8b4615c919e36c.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/live-run/page-c685b104e0dfa609.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/app/loops/page-8d693331cfbb6add.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/market/page-cef4f30a4c22fae1.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66ea1b54fc83fa15.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/morning/page-7a12f61be4a579d1.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/not-found-c85b0589591a99c9.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/observatory/page-725a4da02dd129eb.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-8cc707bd09a497d9.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-90b55be1f15ce0e8.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cb16606e08be65db.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/outputs/page-16dc64b74ed6a40a.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/page-21bec4afeb2f0917.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/reflection/page-dc39ee7a36d26385.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-84ae759f76053672.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/sessions/page-3db58ddb61fe2be9.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c5315e30f3528dc4.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/settings/page-2fe368efb6de3b6a.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8d04132dd0ac5e10.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/setup/page-f23484de467c9ea3.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/share/page-c69762987b751174.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/showroom/page-5456692bda39aafb.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d75f7cd65845ce98.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/app/term/page-5603f5e568b25ce3.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/app/today/page-d2cc0f4e89f42028.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/app/trace/page-a6eb73b8a4840f1c.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/app/vault/page-c0a3f4d10edb83fa.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6c0b88068c143f15.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/app/workflows/page-7f8d7fcdf058a845.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/app/workspace/page-22163556cd38bc88.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-141436fd26dd56fc.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/f6231284-45726550aba08fca.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +0 -1
  779. package/apps/pwa/out/_next/static/css/e81df11490b4413b.css +0 -1
  780. /package/apps/pwa/out/_next/static/{MObU8ujkMciAKr6ljAV05 → rfkMm4movqkqMebBrCXiR}/_ssgManifest.js +0 -0
@@ -18,6 +18,14 @@ export interface MemoryItem {
18
18
  conflict?: { owner: 'OP'; sources: [string, string] };
19
19
  }
20
20
 
21
+ /** Guardian retention boundary: lifecycle hygiene, independent of librarian promotion. */
22
+ export function guardianRetireAged(items: readonly MemoryItem[], now: Date): MemoryItem[] {
23
+ const cutoff = now.getTime() - 30 * DAY_MS;
24
+ return items.map(item => ({ ...item,
25
+ status: Date.parse(item.updatedAt) < cutoff ? 'retired' as const : item.status,
26
+ }));
27
+ }
28
+
21
29
  export type MemorySource =
22
30
  | { kind: 'event'; at: string; seat: string; text: string; source: string }
23
31
  | { kind: 'decision'; at: string; seat: string; text: string; source: string };
@@ -28,6 +36,8 @@ export interface MemorySummary {
28
36
  summary: string;
29
37
  /** Only supply this when the two strings identify the same fact and mutually exclusive values. */
30
38
  claim?: { key: string; value: string };
39
+ /** Sleep-review task agent's promotion decision; not stored in a MemoryItem. */
40
+ promote?: boolean;
31
41
  }
32
42
 
33
43
  type CondenseEvent = CoordEvent & { surface?: string };
@@ -38,7 +48,7 @@ export interface MemoryDeps {
38
48
  decisions?: () => DecisionEntry[];
39
49
  }
40
50
 
41
- export type CondenseSkipReason = 'no-seat' | 'no-project' | 'no-topic' | 'no-summary' | 'bad-link' | 'bad-claim' | 'no-claim' | 'summarize-failed';
51
+ export type CondenseSkipReason = 'not-promoted' | 'no-seat' | 'no-project' | 'no-topic' | 'no-summary' | 'bad-link' | 'bad-claim' | 'no-claim' | 'summarize-failed';
42
52
  export type CondenseSkipped = Partial<Record<CondenseSkipReason, number>>;
43
53
  export interface FunnelCount { total: number; bySeat: Record<string, number> }
44
54
  export interface CondenseFunnel {
@@ -77,22 +87,25 @@ export function readCondenseEvents(since: string): CondenseEvent[] {
77
87
  /** Condense one UTC day; callers persist the returned snapshot, not raw transcripts. Read-only ledger access. */
78
88
  export async function condenseContextDay(
79
89
  day: string, previous: readonly MemoryItem[], deps: MemoryDeps, now: Date = new Date(),
90
+ policy: { promotion?: 'sleep-review'; retention?: 'guardian' } = {},
80
91
  ): Promise<MemoryItem[]> {
81
92
  if (!/^\d{4}-\d\d-\d\d$/.test(day) || new Date(`${day}T00:00:00.000Z`).toISOString().slice(0, 10) !== day) {
82
93
  throw new Error('day must be a valid UTC YYYY-MM-DD');
83
94
  }
84
- return condenseContextWindow(`${day}T00:00:00.000Z`, new Date(Date.parse(`${day}T00:00:00.000Z`) + DAY_MS).toISOString(), previous, deps, now);
95
+ return condenseContextWindow(`${day}T00:00:00.000Z`, new Date(Date.parse(`${day}T00:00:00.000Z`) + DAY_MS).toISOString(), previous, deps, now, policy);
85
96
  }
86
97
 
87
98
  /** Read-only condensation over an exact rolling UTC window; the caller owns any persistence. */
88
99
  export async function condenseContextWindow(
89
100
  since: string, until: string, previous: readonly MemoryItem[], deps: MemoryDeps, now: Date = new Date(),
101
+ policy: { promotion?: 'sleep-review'; retention?: 'guardian' } = {},
90
102
  ): Promise<MemoryItem[]> {
91
- return (await condenseContextWindowWithReport(since, until, previous, deps, now)).cards;
103
+ return (await condenseContextWindowWithReport(since, until, previous, deps, now, policy)).cards;
92
104
  }
93
105
 
94
106
  export async function condenseContextWindowWithReport(
95
107
  since: string, until: string, previous: readonly MemoryItem[], deps: MemoryDeps, now: Date = new Date(),
108
+ policy: { promotion?: 'sleep-review'; retention?: 'guardian' } = {},
96
109
  ): Promise<CondenseWindowReport> {
97
110
  const start = Date.parse(since);
98
111
  const end = Date.parse(until);
@@ -228,6 +241,7 @@ export async function condenseContextWindowWithReport(
228
241
  try { summary = await deps.summarize(source); }
229
242
  catch { skip('summarize-failed', source); continue; }
230
243
  bump(funnel.summarized, source.seat);
244
+ if (policy.promotion === 'sleep-review' && summary.promote !== true) { skip('not-promoted', source); continue; }
231
245
  const project = safeLine(summary?.project);
232
246
  const topic = safeLine(summary?.topic);
233
247
  const text = safeLine(summary?.summary);
@@ -238,7 +252,9 @@ export async function condenseContextWindowWithReport(
238
252
  if (!/^(?:https?:\/\/|elanous:\/\/)[^\s]+$/.test(link)) { skip('bad-link', source); continue; }
239
253
  const claim = summary.claim && { key: safeLine(summary.claim.key), value: safeLine(summary.claim.value) };
240
254
  if (claim && (!claim.key || !claim.value)) { skip('bad-claim', source); continue; }
241
- if (source.kind === 'event' && !claim) { skip('no-claim', source); continue; }
255
+ // Sleep review can promote a sourced durable event without asserting a comparable fact.
256
+ // The ordinary condense command still requires a claim for event candidates.
257
+ if (source.kind === 'event' && !claim && policy.promotion !== 'sleep-review') { skip('no-claim', source); continue; }
242
258
  kept++;
243
259
  bump(funnel.summarized.accepted, source.seat);
244
260
  const key = keyFor({ project, seat, topic });
@@ -253,17 +269,20 @@ export async function condenseContextWindowWithReport(
253
269
  updatedKeys.add(key);
254
270
  }
255
271
  const cutoff = now.getTime() - 30 * DAY_MS;
256
- // Compare only the winning, non-retired assertions; a superseded claim cannot keep a decision candidate alive.
272
+ // The nightly librarian makes promotion judgments; guardian retention runs at the record boundary.
273
+ // The ordinary condense command keeps its existing retention behavior.
257
274
  const finalItems: MemoryItem[] = [...items.values()].map(({ conflict: _conflict, ...item }) => ({ ...item,
258
- status: Date.parse(item.updatedAt) < cutoff ? 'retired' as const : 'active' as const,
275
+ status: policy.retention === 'guardian' ? item.status
276
+ : Date.parse(item.updatedAt) < cutoff ? 'retired' as const : 'active' as const,
259
277
  }));
260
278
  finalItems.sort((a, b) => Date.parse(a.updatedAt) - Date.parse(b.updatedAt) || a.source.localeCompare(b.source)
261
279
  || a.seat.localeCompare(b.seat));
262
280
  for (let index = 0; index < finalItems.length; index++) {
263
281
  const item = finalItems[index]!;
264
- if (item.status !== 'active' || !item.claim) continue;
282
+ if (item.status !== 'active' || !item.claim || (policy.retention === 'guardian' && Date.parse(item.updatedAt) < cutoff)) continue;
265
283
  const { key, value } = item.claim;
266
284
  const conflicting = finalItems.slice(0, index).find(other => other.status === 'active'
285
+ && (policy.retention !== 'guardian' || Date.parse(other.updatedAt) >= cutoff)
267
286
  && other.project === item.project
268
287
  && other.claim?.key === key && other.claim.value !== value);
269
288
  if (conflicting) {
@@ -1,14 +1,58 @@
1
- import { readFileSync, readdirSync, mkdirSync, writeFileSync, renameSync, existsSync } from 'node:fs';
1
+ import { readFileSync, readdirSync, mkdirSync, writeFileSync, renameSync, existsSync, unlinkSync } from 'node:fs';
2
+ import { gzipSync, gunzipSync } from 'node:zlib';
2
3
  import { dirname, join, resolve } from 'node:path';
3
4
  import { streamLLM } from '../llm.js';
4
- import { condenseContextDay, type MemoryItem, type MemorySource, type MemorySummary } from './long-term-memory.js';
5
- import { listCoordEvents, type CoordEvent } from './coord-events.js';
5
+ import { condenseContextDay, guardianRetireAged, readCondenseEvents, type MemoryItem, type MemorySource, type MemorySummary } from './long-term-memory.js';
6
+ import type { CoordEvent } from './coord-events.js';
6
7
  import { DecisionLedger, type DecisionEntry } from '../decisions/decision-ledger.js';
7
8
  import { acquireLockAsync } from '../storage/file-lock.js';
8
9
 
9
10
  type Stage = 'collect' | 'condense' | 'record' | 'conflict-candidates';
10
11
  type Input = { day?: string; events?: CoordEvent[]; decisions?: DecisionEntry[]; summaries?: Record<string, MemorySummary> };
11
- type Context = { graphId?: string; nodeId?: string; input: Input | null; outputs: Record<string, { day?: string; events?: CoordEvent[]; decisions?: DecisionEntry[]; items?: MemoryItem[] } | null> };
12
+ type Context = { graphId?: string; nodeId?: string; input: Input | null; outputs: Record<string, { day?: string; events?: CoordEvent[]; decisions?: DecisionEntry[]; items?: MemoryItem[]; memoryItems?: MemoryItem[] } | null> };
13
+ type NightlyTask = (source: MemorySource, assignee: 'nightly-task-agent', recipe: 'sleep-review') => Promise<MemorySummary>;
14
+ type GuardianTask = (items: readonly MemoryItem[], assignee: 'guardian', now: Date) => MemoryItem[] | Promise<MemoryItem[]>;
15
+ type NightlyAssignment = { owner: 'coordinator'; assignee: 'nightly-task-agent'; contract: 'librarian'; recipe: 'sleep-review'; source: MemorySource; summary?: MemorySummary };
16
+ type GuardianAssignment = { owner: 'guardian'; assignee: 'guardian'; recipe: 'retire-aged'; items: readonly MemoryItem[]; now: string }
17
+ | { owner: 'guardian'; assignee: 'guardian'; recipe: 'store-snapshot'; root: string; project: string; seat: string; value: MemoryItem[] }
18
+ | { owner: 'guardian'; assignee: 'guardian'; recipe: 'store-candidates'; root: string; value: unknown[] };
19
+ type Assignment = NightlyAssignment | GuardianAssignment;
20
+
21
+ /** Execute an assigned recipe in a separate, short-lived task worker, never in the coordinator's stage process. */
22
+ async function dispatchAssignment<T>(assignment: Assignment): Promise<{ result: T; workerPid: number }> {
23
+ const worker = Bun.spawn([process.execPath, import.meta.path, '--assigned-task'], {
24
+ stdin: 'pipe', stdout: 'pipe', stderr: 'pipe',
25
+ });
26
+ worker.stdin.write(JSON.stringify(assignment));
27
+ worker.stdin.end();
28
+ const [stdout, stderr, exit] = await Promise.all([
29
+ new Response(worker.stdout).text(), new Response(worker.stderr).text(), worker.exited,
30
+ ]);
31
+ if (exit !== 0) throw new Error(`nightly ${assignment.recipe} task failed: ${stderr.trim()}`);
32
+ return { result: JSON.parse(stdout) as T, workerPid: worker.pid };
33
+ }
34
+
35
+ async function executeAssignment(assignment: Assignment): Promise<MemorySummary | MemoryItem[] | { stored: true }> {
36
+ if (assignment.owner === 'coordinator' && assignment.assignee === 'nightly-task-agent'
37
+ && assignment.contract === 'librarian' && assignment.recipe === 'sleep-review') {
38
+ return summarize(assignment.source, assignment.summary ? { [assignment.source.source]: assignment.summary } : undefined, assignment.recipe);
39
+ }
40
+ if (assignment.owner === 'guardian' && assignment.assignee === 'guardian') {
41
+ if (assignment.recipe === 'retire-aged') return guardianRetireAged(assignment.items, new Date(assignment.now));
42
+ if (assignment.recipe === 'store-snapshot') {
43
+ if (!assignment.value.every(item => item.project === assignment.project && item.seat === assignment.seat)) {
44
+ throw new Error('guardian memory group mismatch');
45
+ }
46
+ guardianSave(snapshotPath(assignment.root, assignment.project, assignment.seat), assignment.value);
47
+ return { stored: true };
48
+ }
49
+ if (assignment.recipe === 'store-candidates') {
50
+ guardianSave(join(assignment.root, 'context-memory', 'conflict-candidates.json'), assignment.value);
51
+ return { stored: true };
52
+ }
53
+ }
54
+ throw new Error('invalid nightly assignment');
55
+ }
12
56
 
13
57
  const dayBefore = (date: Date) => new Date(date.getTime() - 86_400_000).toISOString().slice(0, 10);
14
58
  const fileName = (value: string) => encodeURIComponent(value).replace(/\./g, '%2E');
@@ -25,6 +69,39 @@ function save(file: string, value: unknown): void {
25
69
  renameSync(temp, file);
26
70
  }
27
71
 
72
+ const GUARDIAN_SIZE_BUDGET_BYTES = 16 * 1024 * 1024;
73
+
74
+ /** Guardian-owned snapshot hygiene. The JSON ledger stays byte-for-byte in its existing format. */
75
+ function guardianSave(file: string, value: unknown): void {
76
+ const text = JSON.stringify(value, null, 2) + '\n';
77
+ const previous = existsSync(file) ? readFileSync(file) : undefined;
78
+ const backup = `${file}.gz`;
79
+ if (previous) {
80
+ // Write the new backup beside the old one and verify it on disk before it replaces the old backup,
81
+ // so a failed or corrupt backup write never destroys the previous backup.
82
+ const backupTemp = `${backup}.${process.pid}.tmp`;
83
+ try {
84
+ writeFileSync(backupTemp, gzipSync(previous));
85
+ if (!gunzipSync(readFileSync(backupTemp)).equals(previous)) throw new Error('guardian backup integrity check failed');
86
+ renameSync(backupTemp, backup);
87
+ } catch (error) {
88
+ if (existsSync(backupTemp)) unlinkSync(backupTemp);
89
+ throw error;
90
+ }
91
+ }
92
+ try {
93
+ if (Buffer.byteLength(text) > GUARDIAN_SIZE_BUDGET_BYTES) throw new Error('guardian memory size budget exceeded');
94
+ save(file, value);
95
+ if (readFileSync(file, 'utf8') !== text) throw new Error('guardian memory integrity check failed');
96
+ } catch (error) {
97
+ if (previous) writeFileSync(file, gunzipSync(readFileSync(backup)));
98
+ else if (existsSync(file)) unlinkSync(file);
99
+ const temp = `${file}.${process.pid}.tmp`;
100
+ if (existsSync(temp)) unlinkSync(temp);
101
+ throw error;
102
+ }
103
+ }
104
+
28
105
  async function withCurrentDay<T>(root: string, day: string, write: () => T): Promise<T> {
29
106
  const dir = join(root, 'context-memory');
30
107
  mkdirSync(dir, { recursive: true });
@@ -39,7 +116,7 @@ async function withCurrentDay<T>(root: string, day: string, write: () => T): Pro
39
116
  if (!lock.stillHeld()) throw new Error('nightly memory write lock lost');
40
117
  // Reserve the day before touching either output, so a failed writer cannot let an older run overwrite it.
41
118
  if (!latest || latest < day) save(marker, day);
42
- return write();
119
+ return await write();
43
120
  } finally { lock.release(); }
44
121
  }
45
122
 
@@ -64,20 +141,38 @@ function storedItems(root: string): MemoryItem[] {
64
141
  return items;
65
142
  }
66
143
 
67
- export async function summarize(source: MemorySource, injected?: Record<string, MemorySummary>): Promise<MemorySummary> {
144
+ /** A sleep-review rejection: counted as `not-promoted` by the condenser, never as a malformed summary. */
145
+ function notPromoted(value: Record<string, unknown>): MemorySummary {
146
+ const text = (key: string) => typeof value[key] === 'string' ? value[key] as string : '';
147
+ return { promote: false, project: text('project'), topic: text('topic'), summary: text('summary') };
148
+ }
149
+
150
+ export function summaryInstruction(recipe: 'standard' | 'sleep-review' = 'standard'): string {
151
+ const system = 'Summarize this one-line context event as a compact project/seat memory item. Return ONLY JSON: {"project":"...","topic":"...","summary":"...","claim":{"key":"...","value":"..."}}. Omit claim when the event makes no comparable factual assertion. Never invent a project, topic or claim.';
152
+ if (recipe === 'standard') return system;
153
+ // SLEEP1 builds on this librarian recipe; the guardian owns storage hygiene, not promotion judgments.
154
+ return `${system.replace('"project":"..."', '"promote":false,"project":"..."')} You are the nightly task agent (librarian). Sleep review (librarian contract): apply the coordinator promotion policy. Return a boolean "promote" for every source. Set promote=true only for sourced, durable project/seat facts or decisions, including durable updates without a comparable claim; set promote=false for chatter or speculative claims. A correction with a later timestamp wins; return a comparable claim only for an explicit factual assertion so opposing claims can become OP conflict candidates. Do not perform guardian hygiene (retention, compression, size, backup, integrity or rollback).`;
155
+ }
156
+
157
+ export async function summarize(source: MemorySource, injected?: Record<string, MemorySummary>, recipe: 'standard' | 'sleep-review' = 'standard'): Promise<MemorySummary> {
68
158
  if (injected) {
69
159
  const result = injected[source.source];
70
160
  if (!result) throw new Error(`missing test summary: ${source.source}`);
161
+ if (recipe === 'sleep-review' && typeof result.promote !== 'boolean') throw new Error('invalid memory summary');
162
+ if (recipe === 'sleep-review' && result.promote === false) return notPromoted(result as unknown as Record<string, unknown>);
71
163
  return result;
72
164
  }
73
165
  const response = await streamLLM([
74
- { role: 'system', content: 'Summarize this one-line context event as a compact project/seat memory item. Return ONLY JSON: {"project":"...","topic":"...","summary":"...","claim":{"key":"...","value":"..."}}. Omit claim when the event makes no comparable factual assertion. Never invent a project, topic or claim.' },
166
+ { role: 'system', content: summaryInstruction(recipe) },
75
167
  { role: 'user', content: JSON.stringify(source) },
76
168
  ], () => {}, { maxTokens: 350, usageRole: 'research' });
77
169
  const parsed: unknown = JSON.parse(response.replace(/^```(?:json)?\s*|\s*```$/g, '').trim());
78
170
  if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) throw new Error('invalid memory summary');
79
171
  const value = parsed as Record<string, unknown>;
172
+ // A librarian rejection needs no project/topic/summary — chatter often has none to give.
173
+ if (recipe === 'sleep-review' && value.promote === false) return notPromoted(value);
80
174
  if (typeof value.project !== 'string' || typeof value.topic !== 'string' || typeof value.summary !== 'string' ||
175
+ (recipe === 'sleep-review' && typeof value.promote !== 'boolean') ||
81
176
  (value.claim !== undefined && (!value.claim || typeof value.claim !== 'object' || Array.isArray(value.claim) ||
82
177
  typeof (value.claim as Record<string, unknown>).key !== 'string' || typeof (value.claim as Record<string, unknown>).value !== 'string'))) {
83
178
  throw new Error('invalid memory summary');
@@ -85,8 +180,14 @@ export async function summarize(source: MemorySource, injected?: Record<string,
85
180
  return value as unknown as MemorySummary;
86
181
  }
87
182
 
183
+ const defaultGuardianTask: GuardianTask = (items, assignee, now) => {
184
+ if (assignee !== 'guardian') throw new Error('invalid guardian assignee');
185
+ return guardianRetireAged(items, now);
186
+ };
187
+
88
188
  /** Stage outputs travel only through the graph runner's per-run contexts. No decision ledger write occurs here. */
89
- export async function runNightlyStage(stage: Stage, context: Context, root: string, dryRun: boolean, now = new Date()): Promise<Record<string, unknown>> {
189
+ export async function runNightlyStage(stage: Stage, context: Context, root: string, dryRun: boolean, now = new Date(),
190
+ nightlyTask?: NightlyTask, guardianTask: GuardianTask = defaultGuardianTask): Promise<Record<string, unknown>> {
90
191
  const input = context.input ?? {};
91
192
  if (dryRun && stage !== 'collect' && (!input.events || !input.decisions || !input.summaries)) {
92
193
  throw new Error('dry-run requires fake events, decisions and summaries');
@@ -103,51 +204,99 @@ export async function runNightlyStage(stage: Stage, context: Context, root: stri
103
204
  if (dryRun && (!input.events || !input.decisions || !input.summaries)) {
104
205
  throw new Error('dry-run requires fake events, decisions and summaries');
105
206
  }
106
- const events = input.events ?? listCoordEvents({ since: new Date(Date.parse(`${day}T00:00:00Z`) - 86_400_000).toISOString() });
107
- const decisions = input.decisions ?? (dryRun ? [] : new DecisionLedger().list({ status: 'all' }));
207
+ const events = input.events ?? readCondenseEvents(new Date(Date.parse(`${day}T00:00:00Z`) - 86_400_000).toISOString());
208
+ const decisions = input.decisions ?? (dryRun ? [] : new DecisionLedger({ stateDir: root }).list({ status: 'all' })
209
+ .filter(decision => decision.raisedBy.agent !== 'context-condense'));
108
210
  return { outcome: 'ok', day, events, decisions };
109
211
  }
110
212
  const collected = context.outputs.collect;
111
213
  if (!collected?.day || !collected.events || !collected.decisions) throw new Error('collect output missing');
112
214
  if (stage === 'condense') {
215
+ const assignments: Array<{ owner: 'coordinator'; assignee: 'nightly-task-agent'; contract: 'librarian'; recipe: 'sleep-review'; workerPid: number }> = [];
216
+ const policy = { promotion: 'sleep-review', retention: 'guardian' } as const;
113
217
  const items = await condenseContextDay(collected.day, dryRun ? [] : storedItems(root).filter(item => Date.parse(item.updatedAt) < Date.parse(`${collected.day}T00:00:00Z`)), {
114
218
  events: () => collected.events!, decisions: () => collected.decisions!,
115
- summarize: source => summarize(source, input.summaries),
116
- }, now);
117
- return { outcome: 'ok', items };
219
+ summarize: async source => {
220
+ if (dryRun) return summarize(source, input.summaries, 'sleep-review');
221
+ if (nightlyTask) return nightlyTask(source, 'nightly-task-agent', 'sleep-review');
222
+ const { result, workerPid } = await dispatchAssignment<MemorySummary>({ owner: 'coordinator', assignee: 'nightly-task-agent',
223
+ contract: 'librarian', recipe: 'sleep-review', source, ...(input.summaries ? { summary: input.summaries[source.source] } : {}) });
224
+ assignments.push({ owner: 'coordinator', assignee: 'nightly-task-agent', contract: 'librarian', recipe: 'sleep-review', workerPid });
225
+ return result;
226
+ },
227
+ }, now, policy);
228
+ return { outcome: 'ok', items, assignments };
118
229
  }
119
230
  const items = context.outputs.condense?.items;
120
231
  if (!items) throw new Error('condense output missing');
121
232
  if (stage === 'record') {
122
233
  const grouped = new Map<string, MemoryItem[]>();
123
- for (const item of items) {
234
+ // The guardian task owns retirement; the librarian never mutates the stored status.
235
+ const guardianRun = guardianTask === defaultGuardianTask && !dryRun
236
+ ? await dispatchAssignment<MemoryItem[]>({ owner: 'guardian', assignee: 'guardian', recipe: 'retire-aged', items, now: now.toISOString() })
237
+ : { result: await guardianTask(items, 'guardian', now), workerPid: undefined };
238
+ const memoryItems = guardianRun.result;
239
+ for (const item of memoryItems) {
124
240
  const file = snapshotPath(root, item.project, item.seat);
125
241
  grouped.set(file, [...grouped.get(file) ?? [], item]);
126
242
  }
127
- if (!dryRun) await withCurrentDay(root, day, () => {
128
- for (const [file, group] of grouped) save(file, group);
243
+ if (!dryRun) await withCurrentDay(root, day, async () => {
244
+ // The record is all-or-nothing: each guardian write rolls back its own file, and if a later group
245
+ // fails (size budget, integrity, worker error) the files this record already wrote are restored too.
246
+ const written: Array<{ file: string; previous: Buffer | undefined; previousBackup: Buffer | undefined }> = [];
247
+ const snapshot = (path: string) => existsSync(path) ? readFileSync(path) : undefined;
248
+ try {
249
+ for (const [file, group] of grouped) {
250
+ const first = group[0]!;
251
+ written.push({ file, previous: snapshot(file), previousBackup: snapshot(`${file}.gz`) });
252
+ const stored = await dispatchAssignment<{ stored: true }>({ owner: 'guardian', assignee: 'guardian', recipe: 'store-snapshot',
253
+ root, project: first.project, seat: first.seat, value: group });
254
+ if (!stored.result.stored) throw new Error('guardian snapshot not stored');
255
+ }
256
+ } catch (error) {
257
+ // Restore both the snapshot and its backup to what they were before this record started.
258
+ for (const { file, previous, previousBackup } of written.reverse()) {
259
+ for (const [path, before] of [[file, previous], [`${file}.gz`, previousBackup]] as const) {
260
+ if (before) writeFileSync(path, before);
261
+ else if (existsSync(path)) unlinkSync(path);
262
+ }
263
+ }
264
+ throw error;
265
+ }
129
266
  });
130
- return { outcome: 'ok', files: [...grouped.keys()], items: items.length, memoryItems: dryRun ? items : undefined, dryRun };
267
+ return { outcome: 'ok', files: [...grouped.keys()], items: items.length, memoryItems, dryRun,
268
+ guardian: { assignee: 'guardian', recipe: 'retire-aged', retired: memoryItems.filter(item => item.status === 'retired').length,
269
+ workerPid: guardianRun.workerPid } };
131
270
  }
132
271
  if (stage === 'conflict-candidates') {
133
272
  if (!context.outputs.record) throw new Error('record output missing');
134
- const candidates = items.filter(item => item.conflict && item.status === 'active').map(item => ({
273
+ const recorded = context.outputs.record.memoryItems;
274
+ if (!recorded) throw new Error('guardian record output missing');
275
+ const candidates = recorded.filter(item => item.conflict && item.status === 'active').map(item => ({
135
276
  project: item.project, topic: item.topic, owner: item.conflict!.owner,
136
277
  sources: item.conflict!.sources, status: 'candidate' as const,
137
278
  }));
138
- if (!dryRun) await withCurrentDay(root, day, () => save(join(root, 'context-memory', 'conflict-candidates.json'), candidates));
279
+ if (!dryRun) await withCurrentDay(root, day, async () => {
280
+ const stored = await dispatchAssignment<{ stored: true }>({ owner: 'guardian', assignee: 'guardian', recipe: 'store-candidates',
281
+ root, value: candidates });
282
+ if (!stored.result.stored) throw new Error('guardian candidates not stored');
283
+ });
139
284
  return { outcome: 'ok', candidates, published: 0 };
140
285
  }
141
286
  throw new Error(`unknown stage: ${stage}`);
142
287
  }
143
288
 
144
- if (import.meta.main) {
289
+ if (import.meta.main && process.argv[2] === '--assigned-task') {
290
+ const assignment = await new Response(Bun.stdin.stream()).json() as Assignment;
291
+ console.log(JSON.stringify(await executeAssignment(assignment)));
292
+ } else if (import.meta.main) {
145
293
  const stage = process.argv[2] as Stage;
146
294
  const path = process.env.ELANOUS_GRAPH_CONTEXT;
147
295
  if (!path || !['collect', 'condense', 'record', 'conflict-candidates'].includes(stage)) throw new Error('invalid nightly graph stage');
148
296
  const context = JSON.parse(readFileSync(path, 'utf8')) as Context;
149
297
  if (context.graphId !== 'nightly-condense' || context.nodeId !== stage) throw new Error('nightly graph context mismatch');
150
298
  const statePath = resolve(path, '..', '..', '..', '..');
151
- const result = await runNightlyStage(stage, context, statePath, process.env.ELANOUS_GRAPH_DRY_RUN === '1');
299
+ const result = await runNightlyStage(stage, context, statePath, process.env.ELANOUS_GRAPH_DRY_RUN === '1',
300
+ new Date());
152
301
  console.log(JSON.stringify(result));
153
302
  }
@@ -0,0 +1,87 @@
1
+ import { readHqLease } from '../hq/hq.js';
2
+ import { fileLeaseStore } from '../hq/lease.js';
3
+ import { join } from 'node:path';
4
+ import { effectiveInstanceRoot } from '../instance/resolve.js';
5
+ import { getElanousConfigDirOverride } from '../elanous-config-dir.js';
6
+ import { readLandingFreeze } from '../release-loop/landing-freeze.js';
7
+ import { entriesFromRegistry, checkLoops, countLoopStates } from '../loops/checker.js';
8
+ import { computeDrift, discoverUniverses } from '../cli/config-drift.js';
9
+ import { debug } from '../debug/log.js';
10
+
11
+ export type ControlStatusState = 'ok' | 'warn' | 'unmeasured';
12
+ export type ControlStatusRowName = '집' | '판' | '자원' | '자격' | '동결·몫' | '루프' | 'config';
13
+ export interface ControlStatusRow {
14
+ row: ControlStatusRowName;
15
+ state: ControlStatusState;
16
+ text: string;
17
+ reason?: string;
18
+ }
19
+
20
+ export interface ControlStatusDeps {
21
+ readLease?: () => ReturnType<typeof readHqLease> | Promise<ReturnType<typeof readHqLease>>;
22
+ readVersion?: () => ControlStatusRow | Promise<ControlStatusRow>;
23
+ readResources?: () => ControlStatusRow | Promise<ControlStatusRow>;
24
+ readCredentials?: () => ControlStatusRow | Promise<ControlStatusRow>;
25
+ readFreeze?: () => ReturnType<typeof readLandingFreeze> | Promise<ReturnType<typeof readLandingFreeze>>;
26
+ readLoops?: () => ReturnType<typeof entriesFromRegistry> | Promise<ReturnType<typeof entriesFromRegistry>>;
27
+ readDrift?: () => ReturnType<typeof computeDrift> | Promise<ReturnType<typeof computeDrift>>;
28
+ now?: () => Date;
29
+ log?: typeof debug.log;
30
+ }
31
+
32
+ const missing = (row: ControlStatusRowName, reason: string): ControlStatusRow => ({ row, state: 'unmeasured', text: '못 쟀다', reason });
33
+
34
+ /** Read-only snapshot: each source fails independently; no lease renewal, freeze mutation or config sync. */
35
+ export async function collectControlStatus(deps: ControlStatusDeps = {}): Promise<ControlStatusRow[]> {
36
+ const rows: ControlStatusRow[] = [];
37
+ const add = async (row: ControlStatusRowName, read: () => ControlStatusRow | Promise<ControlStatusRow>) => {
38
+ let result: ControlStatusRow;
39
+ try { result = await read(); }
40
+ catch (error) {
41
+ // Source errors may contain file contents or credentials; report the failure class, not the raw message.
42
+ result = missing(row, error instanceof Error ? `읽기 실패(${error.name})` : '읽기 실패');
43
+ }
44
+ rows.push(result);
45
+ try { (deps.log ?? debug.log.bind(debug))('control.status', 'row', { row, state: result.state }); }
46
+ catch { /* logging must not mask another row */ }
47
+ };
48
+
49
+ await add('집', async () => {
50
+ const readLease = deps.readLease ?? (() => readHqLease(getElanousConfigDirOverride() !== undefined
51
+ ? { store: fileLeaseStore(join(effectiveInstanceRoot(), 'hq', 'lease.json')), hostPath: join(effectiveInstanceRoot(), 'hq', 'host') }
52
+ : {}));
53
+ const { record, ageSeconds, expired } = await readLease();
54
+ if (!record) return missing('집', '본부 임대 기록 없음');
55
+ return { row: '집', state: expired ? 'warn' : 'ok',
56
+ text: `본부 ${record.holder} · 세대 ${record.generation} · ${ageSeconds}초 전 · ${expired ? '만료' : '유효'}` };
57
+ });
58
+ await add('판', deps.readVersion ?? (() => missing('판', '기계별 install.json·데몬 판·공개 판 원천 미연결')));
59
+ await add('자원', deps.readResources ?? (() => missing('자원', '기계별 Pod 실행/대기/실패·풀 상한·호스트 부하 원천 미연결')));
60
+ await add('자격', deps.readCredentials ?? (() => missing('자격', '계정별 만료·쿼터·갱신자 원천 미연결')));
61
+ await add('동결·몫', async () => {
62
+ const freeze = await (deps.readFreeze ?? readLandingFreeze)();
63
+ return { row: '동결·몫', state: freeze ? 'warn' : 'unmeasured',
64
+ text: freeze ? `동결 켬 · ${freeze.reason} · 끝 ${freeze.until ?? '미지정'} · 자리별 몫 못 쟀다` : '동결 끔 · 자리별 몫 못 쟀다',
65
+ reason: '자리별 몫/도는 수 원천 미연결' };
66
+ });
67
+ await add('루프', async () => {
68
+ const { entries, scope } = await (deps.readLoops ?? entriesFromRegistry)();
69
+ if (entries.length === 0) return missing('루프', `${scope} 루프 목록에 측정 대상 없음`);
70
+ const results = checkLoops(entries, (deps.now ?? (() => new Date()))());
71
+ const counts = countLoopStates(results);
72
+ if (counts.unknown + counts.unregistered + counts.off === results.length) return missing('루프', '활성 등록 루프의 마지막 실행/예정 시각을 잴 수 없음');
73
+ const failing = results.filter(result => result.state === 'failing').map(result => result.id);
74
+ const late = results.filter(result => result.state === 'late').map(result => result.id);
75
+ return { row: '루프', state: failing.length || late.length || counts.unknown || counts.unregistered || counts.off ? 'warn' : 'ok',
76
+ text: `failing ${counts.failing}${failing.length ? ` (${failing.join(', ')})` : ''} · late ${counts.late}${late.length ? ` (${late.join(', ')})` : ''} · unknown ${counts.unknown} · unregistered ${counts.unregistered} · off ${counts.off}` };
77
+ });
78
+ await add('config', async () => {
79
+ const report = await (deps.readDrift ?? (() => computeDrift(discoverUniverses(getElanousConfigDirOverride() !== undefined
80
+ ? { prodRoot: effectiveInstanceRoot(), registryPath: null, treeScanRoots: [] } : {}))))();
81
+ if (report.prodStatus !== 'ok' || !report.registry.ok || report.universes.unreadable > 0 || report.universes.compared === 0) {
82
+ return missing('config', `드리프트 비교 불가(집 ${report.prodStatus} · 레지스트리 ${report.registry.ok ? '읽음' : '못 읽음'} · 비교 ${report.universes.compared} · 못 읽은 우주 ${report.universes.unreadable})`);
83
+ }
84
+ return { row: 'config', state: report.rows.length ? 'warn' : 'ok', text: `드리프트 키 ${report.rows.length}` };
85
+ });
86
+ return rows;
87
+ }
@@ -67,12 +67,14 @@ export async function runLightMember(opts: LightMemberOptions): Promise<LightMem
67
67
  const root = opts.root ?? effectiveInstanceRoot();
68
68
  const configured = readMachineProfile(root);
69
69
  if (configured) assertJoinedMachineId(configured.id, root);
70
- const machineAttrs = () => {
70
+ // measureLoad is async (harness parents · disk I/O); a pending Promise would serialize as `{}` and blank `load`.
71
+ const pageoutBaseline: { value: number } = { value: Number.NaN };
72
+ const machineAttrs = async () => {
71
73
  const profile = readMachineProfile(root);
72
74
  if (profile && profile.id !== machine) {
73
75
  throw new Error(`machine id ${profile.id} differs from joined machine ${machine}`);
74
76
  }
75
- return { load: measureLoad(now), ...(profile ? { duties: profile.duties, seats: profile.seats } : {}) };
77
+ return { load: await measureLoad(now, pageoutBaseline), ...(profile ? { duties: profile.duties, seats: profile.seats } : {}) };
76
78
  };
77
79
  const interval = opts.intervalMs ?? DEFAULT_INTERVAL_MS;
78
80
  if (!Number.isFinite(interval) || interval <= 0 || interval > MAX_RETRY_MS) throw new Error('invalid member heartbeat interval');
@@ -119,7 +121,7 @@ export async function runLightMember(opts: LightMemberOptions): Promise<LightMem
119
121
  while (!signal.aborted) {
120
122
  const resources: LightMemberResult['resources'] = [];
121
123
  try {
122
- const attrs = machineAttrs();
124
+ const attrs = await machineAttrs();
123
125
  await post(machineId, registered.has(machineId) ? { attrs } : {
124
126
  id: machineId, kind: 'machine', machine, name: machine, owner: '',
125
127
  attrs, observedAt: now(), ttlMs: TTL_MS,