elanous 0.2.36 → 0.2.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (630) 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/{uC-N0emedeNOFuaBQFv-I → 8kITumG9GAZ1LwT9POrAR}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/1041-5841aae848fb6403.js +1 -0
  5. package/apps/pwa/out/_next/static/chunks/1087.3177e54f672dc526.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1105.efe1e13503ac7a33.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1224.2ceca6c180d5130b.js +62 -0
  8. package/apps/pwa/out/_next/static/chunks/{4286.b70c4520306817e8.js → 1262.a89bb27a5b2f844e.js} +1 -1
  9. package/apps/pwa/out/_next/static/chunks/1417-1768233ac92f8a5d.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1612.81bbc19af06af16c.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/{3410.7f9af5ab77cbe65f.js → 1746.3563617ea64023a3.js} +1 -1
  12. package/apps/pwa/out/_next/static/chunks/1766.728d42053070bb2d.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1773.d38e945481e04125.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1974-c12f9600da3d3c26.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1ed5e8af.cf424815c7c0efad.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/{9250-072df22eaadaa6b5.js → 2002-a43a3f380df873ec.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/2061.7232dc9dc058417f.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/210.90b2cbd64926cf34.js +32 -0
  19. package/apps/pwa/out/_next/static/chunks/{3727.7949ccaacaa71242.js → 2283.edd9627b7bdfb546.js} +2 -2
  20. package/apps/pwa/out/_next/static/chunks/2318-450e75d07605b8fe.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/{4615.8525eb0add35eba6.js → 2375.bf364c85dbb6f085.js} +1 -1
  22. package/apps/pwa/out/_next/static/chunks/244-a810d282a20f1783.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/2479-fe7e188bd9402d14.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2514.03b60f266531a015.js +148 -0
  25. package/apps/pwa/out/_next/static/chunks/2526-a657538869888604.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2533-6f0341ff075809e9.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2676.e7994c695ef0f30d.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2734.3ffdf54254fb6f99.js +27 -0
  29. package/apps/pwa/out/_next/static/chunks/2770-23252bf3a37880b9.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/2969.66b8b545139d1544.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/3128.a9210d08800ea6a8.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{5711.957b095705c12560.js → 3199.6a1a9b0e6cd01dc6.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/3212.12179fd3eee8cef1.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/{2986.45d7652e4f13557e.js → 3578.4e9f9948a9a6f2f4.js} +2 -2
  35. package/apps/pwa/out/_next/static/chunks/3760-2909ddb9279281cd.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3825.1921b5901bf33dce.js +36 -0
  37. package/apps/pwa/out/_next/static/chunks/3994-63eb884ed0547011.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/4036.d54e55e1ebf5acdc.js +90 -0
  39. package/apps/pwa/out/_next/static/chunks/4115.5b438b99f0ae729f.js +226 -0
  40. package/apps/pwa/out/_next/static/chunks/4269.d8f9f34bb0fc6c43.js +287 -0
  41. package/apps/pwa/out/_next/static/chunks/431-4eed5bd2c5fe1719.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/{7481.39f7a4654907bf6e.js → 4313.76f232c304a15bde.js} +1 -1
  43. package/apps/pwa/out/_next/static/chunks/4324.c99ba3e83eb1b691.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4337e36d.f42c3b391b3d8f20.js +122 -0
  45. package/apps/pwa/out/_next/static/chunks/{6943.c6b24124853a47b2.js → 4383.18e5c54db3a22c88.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/4599-96eff3f2a9c242c1.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{3757-180308bc61021b05.js → 4725-34bed25720cc326b.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/4825-a9d9d4e9f5892309.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4833-7934c592c5569f00.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4879-68518f547a207aff.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4896.f9b70285363b27b2.js +24 -0
  52. package/apps/pwa/out/_next/static/chunks/{771.c3cdb6c1f7f47c02.js → 4931.95cc6dbd230774ca.js} +3 -3
  53. package/apps/pwa/out/_next/static/chunks/4937-28d437999b77c9dd.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/49aa54ab.80f39398e0ed0f30.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/{552.b7d061ad91eeac51.js → 5046.7fd5cbd859299448.js} +2 -2
  56. package/apps/pwa/out/_next/static/chunks/5056.482687319b82638e.js +104 -0
  57. package/apps/pwa/out/_next/static/chunks/506.16b83d56a437a9ee.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5260-20593b0a25d0afbc.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5404.cc4e9fec26fd5925.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/576.485e83e3f3dec19a.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5832-a6be14e663f65726.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5854-56648a9fe646b9a0.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/{9f31e478.fefcbcd3c388ebc5.js → 58edce7d.f1b0c72acf13b123.js} +1 -1
  64. package/apps/pwa/out/_next/static/chunks/5925.3b1f8b135710249b.js +93 -0
  65. package/apps/pwa/out/_next/static/chunks/{3136.30aaaa5fa03662a3.js → 5952.294fc574a8625184.js} +1 -1
  66. package/apps/pwa/out/_next/static/chunks/{da5ecc5c-b005ad8cac737d57.js → 5f6af561-f90b7a67f4f75d13.js} +1 -1
  67. package/apps/pwa/out/_next/static/chunks/6168.17749aa3905fa073.js +74 -0
  68. package/apps/pwa/out/_next/static/chunks/{3324.a09703033abcbd2f.js → 6252.240578f10952e091.js} +1 -1
  69. package/apps/pwa/out/_next/static/chunks/6416.5d50b8ec9986ca98.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/{8904.7d51af2dc033965c.js → 6680.6a693c28aae4cd19.js} +2 -2
  71. package/apps/pwa/out/_next/static/chunks/{275-02ea4c2a33980422.js → 6745-5a63492933959dd9.js} +3 -3
  72. package/apps/pwa/out/_next/static/chunks/6758.e7fbf532953c0783.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6795.0cb8a59730d99703.js +149 -0
  74. package/apps/pwa/out/_next/static/chunks/{528.38ce20ef8aa251ff.js → 6819.be5c9c4d67f22922.js} +3 -3
  75. package/apps/pwa/out/_next/static/chunks/6877-84d47b7e85d0c41e.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6971-fb5f9dc0a2cb5d2d.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/{3a3d9966.cc4d4585a2708e7c.js → 709a918c.4fd3b4e2a32cb4e3.js} +1 -1
  78. package/apps/pwa/out/_next/static/chunks/717.522b08685979b814.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/7191.e41eb8f455c7f089.js +41 -0
  80. package/apps/pwa/out/_next/static/chunks/7233.8e744b7513119409.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7238-97c2226f80504bd8.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/7285.307963afcf7e7660.js +24 -0
  83. package/apps/pwa/out/_next/static/chunks/7299-fbe4b8c47a87614a.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7314.df0d95930b0c3f50.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7406.c0589fdf2ee66629.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/{4304.e9b2512834a9e23e.js → 7424.c0fe2a595d4232b5.js} +1 -1
  87. package/apps/pwa/out/_next/static/chunks/752-90e3e7daad3d8e39.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7524-bcd3d9928c6842d9.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7549.9a4de3bf231cfc52.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/757-4fbaf50942b8c424.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/765.76ae970ceb597b5b.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{2683.c9773a0c589b031b.js → 7867.e8725745ddd1d940.js} +4 -4
  93. package/apps/pwa/out/_next/static/chunks/{6466-92e65a48490b68a9.js → 7893-e444a1b0809cd1e4.js} +1 -1
  94. package/apps/pwa/out/_next/static/chunks/7956-33748cabb3a05562.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{ccae1c4b-0cf414f5eff1b10d.js → 7c5ed21f-f286708e57cf88f7.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/8030-aa66b478b53dbfca.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8051.c88c07dacbbc5f21.js +8 -0
  98. package/apps/pwa/out/_next/static/chunks/{3840-5825d56d46976a92.js → 8080-40d781e7704d3671.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/8149.80e402d4345e8dae.js +77 -0
  100. package/apps/pwa/out/_next/static/chunks/8205.50a5268f4e12ba0b.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8231.a128feaa6f8b6079.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/85.4ddb1dda2ea3ffa2.js +286 -0
  103. package/apps/pwa/out/_next/static/chunks/8537.26517a09e8247beb.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8595-e9b7081ab773a61f.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8821-30cc65a61a60951f.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8905.b3385aadb7b133e6.js +79 -0
  107. package/apps/pwa/out/_next/static/chunks/8983.246bb3a1ac38f50f.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/{873d6c12.09bd499f57171543.js → 8c58d09b.e8724a299658d86f.js} +1 -1
  109. package/apps/pwa/out/_next/static/chunks/9072.18342f5941a1f3ec.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/9123.9df04866b2d6e00f.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/{575.d929793a53f27c4b.js → 9151.a2c51e93f9156dae.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/9175-7d383df15a82e2be.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9181-bf89c07ce5b8f599.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/920-429bbc4504b45f71.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9207.625edf45d656151c.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9378.d2575c6ffd6dd756.js +94 -0
  117. package/apps/pwa/out/_next/static/chunks/957.db5b5c4d32a35240.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{190.285c832bd9626f8c.js → 958.53a8dcf4729e6997.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/9647.8f0cd0898c592a29.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9665-26abb02665704c2c.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9703.e7d81b6faef1050a.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9882-7a9164b3c2dacbe5.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/9998.b74e033efadecd10.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c604fb980a634d88.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ec2d8a4979ca9075.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-cb6add08ad3c7660.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/board/page-e2eaa321ec223fe6.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/botlab/page-5b8a09c475b5f844.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/bots/page-91a77daedfbac191.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/ceo/page-f37fc5e974bda39b.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/chat/page-91429a0b78415a94.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/consult/page-b95798b58263b910.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/control/page-763d53e175e17aa1.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/decisions/page-d55023204055b12f.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/design-check/page-89d2140d78abc810.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/editor/page-82dc069abfe27f55.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/exec/page-25d9eee7beb552c0.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/field/page-770b4594c713ee97.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c604fb980a634d88.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/inside/page-ba8e0dcae4f83985.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/intake/page-5c112c6d7c33656e.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/layout-09788e1aa9a87db6.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live/{page-e2de2e59111c9aad.js → page-3337c6a1328c2674.js} +1 -1
  144. package/apps/pwa/out/_next/static/chunks/app/live-run/{page-f2b2e4bf6e981450.js → page-89acd5d68c0bc560.js} +1 -1
  145. package/apps/pwa/out/_next/static/chunks/app/loops/page-5c13e2c76371d797.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/market/page-653a9f18642825c6.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/{page-2af16e62c12f22df.js → page-fe986fe79b107546.js} +1 -1
  148. package/apps/pwa/out/_next/static/chunks/app/morning/page-1e5da297557d2354.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/not-found-91ea9f5869a40943.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/observatory/page-7824e21b999962e2.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-53d00a60cc75a922.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-88a1edbff62eaf1d.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e931248b3f9574b.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/outputs/page-443364c9e4a23b31.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/page-b9af2ac1c4737ce8.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/reflection/page-25ab9c614c14129b.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-dbcdcfac0a395a8a.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/sessions/page-bf1de6645089ec58.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c4201761a5e839c9.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/settings/page-c304f469ea5d70e4.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8e5a238cf5e50c9c.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c604fb980a634d88.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/page-32b526069ee50b3c.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/share/page-fb9e639c107f5f72.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/showroom/page-84220c776608cedc.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/tasks/page-e475618cbfd5ca2b.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/term/page-ac2c1e6169cfce57.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/today/page-fccd3020af2f8806.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/trace/page-9c0d7198ff7b5a91.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/vault/page-d54b1ec9b9c6430d.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8c4bef1791d732ca.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workflows/page-46fcc0b0bbc6fbfe.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workspace/page-c1c80e345fa9d6f5.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7dfda00afd172f5b.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/{053a429e.9a63436527cc751c.js → d9815f84.4918f682a45a8502.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{ceba0382.650712b56b85b582.js → de8446d3.31b73eb239fecd7b.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/f21fd540.63ac75328926ed30.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/framework-77fdcc873519a6cd.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-app-d0d620d2ce235713.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-e0ef79c79337ba90.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-84b1bc71e3f9ce6a.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-2acb61f1363128cb.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-462ff5727ceb7824.js +1 -0
  184. package/apps/pwa/out/_next/static/css/{b5d88eba78a3d7bf.css → be9019f696217521.css} +1 -1
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +23 -23
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +23 -23
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +23 -23
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +22 -22
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +22 -22
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +23 -23
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +22 -22
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +23 -23
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +23 -23
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +22 -22
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +23 -23
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +23 -23
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +23 -23
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +23 -23
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +22 -22
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +22 -22
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +23 -23
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +23 -23
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +23 -23
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +22 -22
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +22 -22
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +23 -23
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +23 -23
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +22 -22
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +22 -22
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +22 -22
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +23 -23
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +23 -23
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +22 -22
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +23 -23
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +23 -23
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +23 -23
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +23 -23
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +23 -23
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +22 -22
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +23 -23
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +23 -23
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +23 -23
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +23 -23
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +23 -23
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +23 -23
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +23 -23
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +23 -23
  278. package/graphs/drafts/recipes.yaml +27 -7
  279. package/graphs/work/draft-close.yaml +54 -0
  280. package/graphs/work/green-close.yaml +37 -0
  281. package/graphs/work/recipes.yaml +46 -1
  282. package/graphs/work/run-research.yaml +35 -0
  283. package/package.json +1 -1
  284. package/scripts/__fixtures__/authoring-paths-10x3.json +32 -0
  285. package/scripts/boundary-proof-mapping-audit.ts +88 -0
  286. package/scripts/codex-fallback-live-probe.ts +17 -15
  287. package/scripts/fleet/node-setup.sh +32 -2
  288. package/scripts/fleet/run-light-worker.sh +9 -0
  289. package/scripts/gate-0226-failure-census.ts +507 -0
  290. package/scripts/goals/authoring-metrics.ts +258 -0
  291. package/scripts/graph-units/draft-close-node.ts +222 -0
  292. package/scripts/hook-order-sweep.ts +7 -4
  293. package/scripts/land-global-checks.ts +69 -1
  294. package/scripts/measure-nl-routing-corpus.ts +207 -2
  295. package/scripts/release-loop/docs-node.ts +140 -0
  296. package/scripts/release-loop/gate-closure.ts +48 -0
  297. package/scripts/release-loop/gate-diff.ts +2 -1
  298. package/scripts/release-loop/known-issues-node.ts +6 -4
  299. package/scripts/release-loop/notes-repair.ts +216 -0
  300. package/scripts/release-loop/prepare-node.ts +61 -5
  301. package/scripts/release-loop/resume-release.ts +114 -4
  302. package/scripts/release-loop/resume-test-traffic.ts +10 -0
  303. package/scripts/release-loop/version-node.ts +81 -12
  304. package/scripts/train/green-leg.ts +176 -0
  305. package/scripts/tui-continue-real-evidence.ts +47 -0
  306. package/scripts/ux-sim.ts +1 -1
  307. package/src/acp/client.ts +31 -5
  308. package/src/acp/core-turn-bridge.ts +6 -0
  309. package/src/acp/stderr-summary.ts +49 -0
  310. package/src/agent/monad-agent-turn.ts +1 -0
  311. package/src/agent/terminal-surface.ts +217 -0
  312. package/src/agent-substrate/pr-reviewer.ts +11 -3
  313. package/src/agent-substrate/self-review-cli.ts +343 -31
  314. package/src/autopilot/lineage/sources.ts +1 -1
  315. package/src/autopilot/pr-manager.ts +64 -13
  316. package/src/boot/daemon-runtime.ts +35 -3
  317. package/src/boot/daemon-tools/pty-shell.ts +2 -1
  318. package/src/budget/run-usage-rollup.ts +12 -7
  319. package/src/budget/unified-usage.ts +20 -0
  320. package/src/capture/tui-self-report.ts +32 -3
  321. package/src/cli/autopilot-cli.ts +24 -9
  322. package/src/cli/decisions-cli.ts +7 -4
  323. package/src/cli/doctor-cli.ts +116 -7
  324. package/src/cli/logs-cli.ts +357 -2
  325. package/src/cli/memory-cli.ts +30 -1
  326. package/src/cli/msg-cli.ts +15 -11
  327. package/src/cli/pr-granularity.ts +5 -3
  328. package/src/cli/release-checklist-read-cli.ts +109 -4
  329. package/src/cli/release-cli.ts +43 -10
  330. package/src/cli/self-update.ts +23 -5
  331. package/src/cli/self-utterances-cli.ts +13 -16
  332. package/src/cli/tasks-cli.ts +309 -11
  333. package/src/cli/usage-cli.ts +12 -10
  334. package/src/context-bus/claude-memory-import.ts +99 -0
  335. package/src/context-bus/long-term-memory.ts +125 -0
  336. package/src/core-turn/run-goal-loop.ts +5 -2
  337. package/src/core-turn/types.ts +2 -0
  338. package/src/dashboard/chat/acp-chat.ts +9 -0
  339. package/src/dashboard/index.ts +97 -13
  340. package/src/dashboard/input/agent-wake.ts +43 -0
  341. package/src/dashboard/input/chat-main-acp-dispatch.ts +21 -1
  342. package/src/dashboard/replay-preview.ts +25 -0
  343. package/src/dashboard/slash-runtime/dashboard-handlers.ts +17 -8
  344. package/src/dashboard/synchronized-frame-output.ts +74 -0
  345. package/src/display/coordinator.ts +45 -12
  346. package/src/display/resize-listener.ts +41 -20
  347. package/src/display/synchronized-output-region.ts +60 -0
  348. package/src/domains/surface-events.ts +80 -1
  349. package/src/exec-requests/planner.ts +37 -2
  350. package/src/execution-loop/launch-gate.ts +4 -3
  351. package/src/git-fs/cli-stderr.ts +45 -0
  352. package/src/git-fs/gh-cli.ts +6 -3
  353. package/src/git-fs/git-cli.ts +11 -5
  354. package/src/graph-runner/graph-cli.ts +26 -2
  355. package/src/graph-runner/graph-run-api.ts +3 -2
  356. package/src/graph-runner/runner.ts +17 -5
  357. package/src/graph-wizard/generate.ts +29 -6
  358. package/src/harness/harness-cli-command.ts +179 -33
  359. package/src/harness/review-adapter.ts +26 -6
  360. package/src/index.ts +116 -13
  361. package/src/instance/test-write-guard-real-transport.fixture.ts +52 -0
  362. package/src/llm/route-decision.ts +13 -0
  363. package/src/llm-tool-name.ts +37 -0
  364. package/src/llm-tool-schema.ts +35 -0
  365. package/src/llm.ts +123 -11
  366. package/src/loops/checker.ts +100 -0
  367. package/src/loops/consensus.ts +26 -2
  368. package/src/loops/loop-cli.ts +9 -4
  369. package/src/loops/orchestrator/anomaly-cluster.ts +243 -0
  370. package/src/loops/orchestrator/tick.ts +49 -4
  371. package/src/model-tier/llm-tier-map.ts +12 -17
  372. package/src/msg/msg-store.ts +17 -0
  373. package/src/native-tool-catalog.ts +1 -1
  374. package/src/nexus/api/graph-wizard-api.ts +27 -2
  375. package/src/nexus/api/grid.ts +24 -4
  376. package/src/nexus/api/http-server.ts +1 -1
  377. package/src/nexus/api/ops-api.ts +14 -6
  378. package/src/nexus/state/state.ts +7 -1
  379. package/src/oauth/codex-account-store.ts +34 -1
  380. package/src/ops/loops-map.ts +46 -0
  381. package/src/ops/overview-cache.ts +22 -4
  382. package/src/ops/overview.ts +41 -5
  383. package/src/policy/llm-policy.ts +3 -1
  384. package/src/prompt-enhance/enhance.ts +4 -4
  385. package/src/pty-shell/availability.ts +7 -0
  386. package/src/pty-shell/herdr-agent-report.ts +40 -31
  387. package/src/pty-shell/herdr-prune-stale.ts +17 -0
  388. package/src/pty-shell/herdr-sequence-lease.ts +60 -0
  389. package/src/pty-shell/pty-control-ipc.ts +187 -18
  390. package/src/pty-shell/registry.ts +25 -15
  391. package/src/pty-shell/tui-run-state.ts +235 -1
  392. package/src/release-loop/checklist.ts +50 -5
  393. package/src/release-loop/feature-store.ts +9 -9
  394. package/src/release-loop/landed-but-yellow.ts +93 -12
  395. package/src/repl/index.ts +8 -0
  396. package/src/seat-loop/seat-report.ts +1 -0
  397. package/src/self-dev/ask-launch-flow.ts +86 -10
  398. package/src/self-dev/decompose-proposal.ts +29 -18
  399. package/src/self-dev/dev-pipeline.ts +29 -7
  400. package/src/self-dev/draft-sweep.ts +241 -16
  401. package/src/self-dev/draft-triage-rules.ts +19 -5
  402. package/src/self-dev/review-provider-fallback.ts +45 -7
  403. package/src/self-dev/shard-plan.ts +48 -0
  404. package/src/self-dev/shard-run.ts +50 -3
  405. package/src/self-implement/doctor-visit.ts +83 -0
  406. package/src/self-implement/gate-artifacts.ts +6 -2
  407. package/src/self-implement/gate-baseline.ts +64 -1
  408. package/src/self-implement/gate-cli.ts +93 -9
  409. package/src/self-implement/gate-remote.ts +28 -4
  410. package/src/self-implement/gate-scope.ts +13 -1
  411. package/src/self-implement/goal-author.ts +333 -18
  412. package/src/self-implement/goal-supervisor-fill.ts +75 -26
  413. package/src/self-implement/importer-test-index.ts +215 -2
  414. package/src/self-implement/knowhow-pack.ts +5 -5
  415. package/src/self-implement/orchestrator.ts +318 -25
  416. package/src/self-implement/review-round-brief.ts +300 -0
  417. package/src/self-implement/rework-policy.ts +14 -0
  418. package/src/self-implement/run-ledger.ts +170 -6
  419. package/src/self-implement/run-stop.ts +1 -1
  420. package/src/self-implement/running-runs.ts +17 -3
  421. package/src/self-implement/seams.ts +12 -6
  422. package/src/self-implement/stop-autoheal.ts +1 -0
  423. package/src/self-implement/test-seams.ts +13 -1
  424. package/src/self-implement/train-reach-grouping.ts +8 -2
  425. package/src/session/chat.ts +7 -1
  426. package/src/session/id-prefix.ts +60 -0
  427. package/src/session/index.ts +4 -0
  428. package/src/session-runtime/index.ts +9 -1
  429. package/src/skills/tools/pty.ts +5 -0
  430. package/src/status/metrics.ts +12 -1
  431. package/src/steward/rejudge-tick.ts +12 -5
  432. package/src/steward/resync-tick.ts +31 -4
  433. package/src/task-agent/actions.ts +199 -4
  434. package/src/task-agent/boundary-proof-mapping.ts +12 -0
  435. package/src/task-agent/boundary-proof-producer.ts +147 -0
  436. package/src/task-agent/completion-evidence.ts +2 -1
  437. package/src/task-agent/green-close-recipe.ts +239 -0
  438. package/src/task-agent/green-sweep.ts +64 -10
  439. package/src/task-agent/live-moves.ts +48 -3
  440. package/src/task-agent/map-host-adapter.ts +134 -0
  441. package/src/task-agent/map-reduce.ts +158 -0
  442. package/src/task-agent/map-run-ledger.ts +226 -0
  443. package/src/task-agent/parent-host.ts +21 -11
  444. package/src/task-agent/rejudge-on-head.ts +72 -5
  445. package/src/task-agent/repair-cycle.ts +41 -0
  446. package/src/task-agent/repair-next-move.ts +12 -2
  447. package/src/task-agent/review-prior-fix.ts +12 -2
  448. package/src/task-agent/shadow.ts +188 -5
  449. package/src/task-agent/task-hand.ts +158 -13
  450. package/src/task-agent/task-parent-role-llm.ts +9 -0
  451. package/src/task-agent/tier-split.ts +4 -3
  452. package/src/task-agent/work-order.ts +53 -2
  453. package/src/task-orchestrator/dispatcher.ts +46 -1
  454. package/src/task-orchestrator/generator-prompt.ts +6 -0
  455. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +16 -6
  456. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +8 -6
  457. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +97 -0
  458. package/src/task-orchestrator/surfaces/pod-pool.ts +50 -4
  459. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +15 -9
  460. package/src/task-orchestrator/surfaces/self-implement-pod.ts +217 -36
  461. package/src/task-orchestrator/surfaces/self-implement.ts +4 -0
  462. package/src/testing/linux-env.ts +177 -0
  463. package/src/tui/chat/goal-interim.ts +5 -1
  464. package/src/tui/entry.ts +258 -4
  465. package/src/tui/input/at-picker.ts +55 -0
  466. package/src/tui/slash/resume.ts +35 -12
  467. package/src/tui/slash/signals.ts +114 -0
  468. package/src/tui/slash/term-next.ts +71 -0
  469. package/src/tui-client/local-chat-turn.ts +4 -3
  470. package/src/user-config.ts +19 -1
  471. package/src/ux-sim/boot-daemon-tools-pty-shell-device.ts +136 -0
  472. package/src/ux-sim/classic-tui-seat-scenarios.ts +158 -4
  473. package/src/ux-sim/fake-gh.ts +174 -0
  474. package/src/ux-sim/fake-kubectl.ts +142 -0
  475. package/src/ux-sim/fake-llm.ts +6 -1
  476. package/src/ux-sim/next-tui-seat-scenarios.ts +124 -6
  477. package/src/ux-sim/resume-picker-device.ts +173 -0
  478. package/src/ux-sim/session-id-seed.ts +60 -0
  479. package/src/ux-sim/skills-tools-shell-device.ts +156 -0
  480. package/src/ux-sim/task-agent-parent-host-device.ts +264 -0
  481. package/src/ux-sim/task-agent-rejudge-on-head-device.ts +114 -0
  482. package/src/version/packed-revision.json +1 -1
  483. package/apps/pwa/out/_next/static/chunks/109.f196abf3484bb97f.js +0 -287
  484. package/apps/pwa/out/_next/static/chunks/1201.afbfc5b1c5e5cbe4.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/1517.9275b89572098ff3.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/1574.ad11f8db8396ab45.js +0 -1
  487. package/apps/pwa/out/_next/static/chunks/1614.7a8c5c40aee0261f.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/1871-f1eb29d8dbb4065b.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/2193.0ea24c4a7aa1d004.js +0 -36
  490. package/apps/pwa/out/_next/static/chunks/223-ad865c1e80491d78.js +0 -1
  491. package/apps/pwa/out/_next/static/chunks/2265-f0d90b6dbec05f81.js +0 -1
  492. package/apps/pwa/out/_next/static/chunks/2267.eb4a62a209f09ec4.js +0 -149
  493. package/apps/pwa/out/_next/static/chunks/2341-86cd06c0cf01aa33.js +0 -1
  494. package/apps/pwa/out/_next/static/chunks/2352.9abc42422bade876.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/2397-c1653a816061842d.js +0 -1
  496. package/apps/pwa/out/_next/static/chunks/2500.cbc1257b774aae52.js +0 -1
  497. package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +0 -24
  498. package/apps/pwa/out/_next/static/chunks/2812ca6a.3b9f4a7a08885744.js +0 -1
  499. package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/2941.3c3546f96bc6efa7.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +0 -24
  502. package/apps/pwa/out/_next/static/chunks/3031-85328a92fcce4da6.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/3148-98efd4869d660a87.js +0 -1
  504. package/apps/pwa/out/_next/static/chunks/3155.2587a55196ecb394.js +0 -226
  505. package/apps/pwa/out/_next/static/chunks/3277.785db1cf09f98601.js +0 -1
  506. package/apps/pwa/out/_next/static/chunks/3320-f9c77381f85a2c0a.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/3386-91049feabff9a94e.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/339.80afb7e8839372af.js +0 -8
  509. package/apps/pwa/out/_next/static/chunks/3538.a445e50bb359d068.js +0 -32
  510. package/apps/pwa/out/_next/static/chunks/3540c645.2595a6af01a97672.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/3621.581b2054cc14bee4.js +0 -286
  512. package/apps/pwa/out/_next/static/chunks/3676.8c28d16fd84ca843.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/375-b84540853523fe52.js +0 -1
  514. package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +0 -74
  515. package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/4067-bf9aa60547972937.js +0 -1
  517. package/apps/pwa/out/_next/static/chunks/4116.a84a92a2492c080e.js +0 -1
  518. package/apps/pwa/out/_next/static/chunks/4176.e5729c93c29151eb.js +0 -104
  519. package/apps/pwa/out/_next/static/chunks/4227-e6c84686bc8946ca.js +0 -1
  520. package/apps/pwa/out/_next/static/chunks/4327.b9e08a71c0009348.js +0 -1
  521. package/apps/pwa/out/_next/static/chunks/4946.bd106eafd668f248.js +0 -148
  522. package/apps/pwa/out/_next/static/chunks/5085-bce4904931767ca6.js +0 -1
  523. package/apps/pwa/out/_next/static/chunks/5125.2eb9968b83767193.js +0 -93
  524. package/apps/pwa/out/_next/static/chunks/5128-75b733fd74a9a1eb.js +0 -1
  525. package/apps/pwa/out/_next/static/chunks/5489f3fe.4bb1458b09f6dead.js +0 -122
  526. package/apps/pwa/out/_next/static/chunks/5560-2a4648f6a30f16e7.js +0 -1
  527. package/apps/pwa/out/_next/static/chunks/5772-e29e14f8ff127122.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/5887.5b2f5b44ce0f7e9a.js +0 -1
  529. package/apps/pwa/out/_next/static/chunks/5899-4c112a2d908cf97f.js +0 -1
  530. package/apps/pwa/out/_next/static/chunks/599.c39c571b6733f2a2.js +0 -41
  531. package/apps/pwa/out/_next/static/chunks/6041.1b65efb796ebc2a5.js +0 -79
  532. package/apps/pwa/out/_next/static/chunks/6057-765c0a26028c86b2.js +0 -1
  533. package/apps/pwa/out/_next/static/chunks/6142.f289e0d039f453a6.js +0 -1
  534. package/apps/pwa/out/_next/static/chunks/6199-6bcd61d2a3910e04.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/6236.cdf7293e710a9b2d.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/6387-237e079dac9a3ae6.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/6448-b6d272d074276e14.js +0 -1
  538. package/apps/pwa/out/_next/static/chunks/6566.926a1d1b7c911442.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/6580-cdc0e4a634ce4708.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/6659-b242dc31b20b3f29.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/6690.c5d9b321b1f79384.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/671-e9b6ad0c771c5514.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/6862.bcbf89dd0f4496b3.js +0 -27
  544. package/apps/pwa/out/_next/static/chunks/6912-7b375ee48732c767.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/6925.562d532110879886.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/727.7deb87749b0a343a.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/7545.b1aa42cd15503319.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/7551-416d298c2dc4a9ab.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/7784.1f0ac4a16d190cf4.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/7870-309de463786ac1fc.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/7888-e29b151bb6a3bb8b.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/7891.03f910124a737985.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/7905-6ba78d9234608f79.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/8037.e254fd797aa224d1.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/8207.f527886b7c464529.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/856.50bda61439d465e6.js +0 -62
  557. package/apps/pwa/out/_next/static/chunks/9031-92e9b487edb681ee.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/9060.5410d9f6a95f6287.js +0 -90
  559. package/apps/pwa/out/_next/static/chunks/914.8abefd48d579547b.js +0 -94
  560. package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/9289.3e92f278821e18e0.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/9319.7816d3cc741cd34f.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/9327-e016bb9f1674d24f.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/9365.3de48bf75193ff9a.js +0 -77
  565. package/apps/pwa/out/_next/static/chunks/9383.5b5e9aa56b5fea97.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/9387-cb929573ef436f39.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/9489.c27becacc3283dec.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/9514.131c52cc75fe6439.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/9536.28962663c7734376.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/9686-12286f5bbf15a5a0.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/9776.289d40cc5a4c342a.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/9789.60f723d18097ec30.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/989.f0c17523c5e61f65.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/9972-1df393aa8d4f7d52.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-96750aba7430959f.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4105e5bbbb043024.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5d4fa75c2acb113e.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/app/board/page-a79a9bdb3b2142bf.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/app/botlab/page-f1c2047484992a35.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/app/bots/page-15ffc49b2d8c70e2.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/app/ceo/page-67d53a3fc8734135.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/app/chat/page-e30c8dc696491336.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/app/consult/page-2136e04fa77696e2.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/app/control/page-fecd2814790c2e12.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/app/decisions/page-280aa4a98fc5bb44.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/app/design-check/page-c14e96b65fb4b883.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/app/editor/page-187dac74825ed6bf.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/app/exec/page-6bc7246ea8c92448.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/app/field/page-083747f1d4518f61.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/app/healthz/route-96750aba7430959f.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/app/inside/page-15ca95a16ec96e1f.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/app/intake/page-a8ac031b3810eb64.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/app/layout-8835f93110494cda.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/app/loops/page-5b92b7f75df20948.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/app/market/page-468eddf2b1a84ecb.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/app/morning/page-18b40867a77a5793.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/app/not-found-fe934f2979f5a4a2.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/app/observatory/page-3eec435537357170.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ff88cbfd2aa99fc8.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-a5b39fb780c70ab5.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ae465dde1d1b3933.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/app/outputs/page-e7abc34a48a6f71e.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/app/page-cab9674fde9ead26.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1da49bc8712284d0.js +0 -1
  605. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5e8aa657551ac912.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/app/sessions/page-fcc36f36c6dc1fe2.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d22db22f2a7296ca.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/app/settings/page-d12dc7b1773878f0.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-99debec9ea7fbec0.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/app/setup/layout-96750aba7430959f.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/app/setup/page-2a088a78bad7e924.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/app/share/page-2e8ed57db7e69993.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/app/showroom/page-4b3a16213c2ae8fe.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f098747ddf38c98b.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/app/term/page-c15958835534404b.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/app/today/page-68279e3c843c1fd7.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/app/trace/page-a34a74453367a39d.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/app/vault/page-8767a7db2155a5bd.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-bd5976683460d7f2.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b7364835e7f2ef54.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/app/workspace/page-311af16b3ee0ffca.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-fb670757274ae990.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/f9a61e4d.1fc2c1dbdd49fe46.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/framework-6d497cbf1eef04c6.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/main-app-012f5edec932f337.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/main-da5aeb809edc94a2.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/pages/_app-5ee319af6f749dfe.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/pages/_error-4bc84653a718d6c6.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/webpack-8a96cf6775c73d6e.js +0 -1
  630. /package/apps/pwa/out/_next/static/{uC-N0emedeNOFuaBQFv-I → 8kITumG9GAZ1LwT9POrAR}/_ssgManifest.js +0 -0
@@ -44,9 +44,11 @@ import {
44
44
  DOCTOR_SYMPTOMS,
45
45
  DOCTOR_VISIT_SOURCES,
46
46
  doctorVisitRunExists,
47
+ doctorReviewVisits,
47
48
  isDoctorSymptom,
48
49
  isDoctorVisitSource,
49
50
  readDoctorVisits,
51
+ readDoctorReviewBrief,
50
52
  recordAutoLongRunVisit,
51
53
  recordDoctorVisit,
52
54
  type DoctorSymptom,
@@ -55,6 +57,8 @@ import { formatHostDoctorLines, runHostDoctor, type HostDoctorExpected, type Hos
55
57
  import { listMachineResources } from './control-cli.js';
56
58
  import type { ResourceView } from '../control-plane/ledger.js';
57
59
  import { loadMachineLedger } from '../machines/machine-ledger.js';
60
+ import { LogStore, logsDbPath, type LogStoreRow } from '../mss/logging/log-store.js';
61
+ import { reviewBriefEvidence } from '../self-implement/review-round-brief.js';
58
62
 
59
63
  function defaultCheckPythonEnv(): { status: 'ok' | 'fixable' | 'manual'; evidence: string; remedy?: string } {
60
64
  const c = checkPythonEnv(false);
@@ -223,10 +227,49 @@ export interface DoctorCliDeps extends DoctorOptions, Pick<DoctorFixDeps, 'home'
223
227
  hostDoctorMachineResources?: () => Promise<ResourceView[]>;
224
228
  /** `doctor visit`/`doctor status` 원장 디렉터리(시험 seam) — 기본 = `runLedgerDir()`. */
225
229
  doctorVisitLedgerDir?: string;
230
+ /** Isolated saved-review and PR metadata seams. */
231
+ reviewResultsDir?: string;
232
+ readReviewBriefPr?: Parameters<typeof readDoctorReviewBrief>[1];
233
+ /** Optional isolated observation transport and status reader for CLI tests. */
234
+ reviewBriefLog?: (event: Record<string, unknown>) => void;
235
+ readReviewBriefEvents?: (runId?: string) => Array<{ timestamp?: string; sequence?: number; runId?: string; key?: string; evidence?: string }>;
226
236
  /** `doctor visit` 사고 선례 연결 루트(시험 seam) — 기본 = `doctorVisitIncidentRoot()` · `null` 이면 건너뛴다. */
227
237
  doctorVisitIncidentRoot?: string | null;
228
238
  /** Deterministic clock for `doctor auto-long-run` isolated CLI tests. */
229
239
  doctorAutoLongRunNow?: () => string;
240
+ /** Standalone logs.db registration seam for the two run-doctor CLI emitters. */
241
+ registerDoctorLogSink?: () => Promise<unknown>;
242
+ /** Flush seam paired with registerDoctorLogSink. */
243
+ flushDoctorLogs?: () => void;
244
+ }
245
+
246
+ export function parseReviewBriefLogData(raw: unknown): Record<string, unknown> {
247
+ let data: unknown;
248
+ try { data = typeof raw === 'string' ? JSON.parse(raw) : raw; }
249
+ catch (error) { throw new Error(`malformed doctor.review/brief-issued event: ${error instanceof Error ? error.message : String(error)}`); }
250
+ if (!data || typeof data !== 'object' || Array.isArray(data)) throw new Error('malformed doctor.review/brief-issued event: expected object data');
251
+ const value = data as Record<string, unknown>;
252
+ if (typeof value.pr !== 'number' || typeof value.head !== 'string' || typeof value.round !== 'number') {
253
+ throw new Error('malformed doctor.review/brief-issued event: required pr/head/round fields are missing');
254
+ }
255
+ return value;
256
+ }
257
+
258
+ function readReviewBriefEventsFromLogs(dbPath = logsDbPath(), runId?: string): Array<{ timestamp?: string; sequence?: number; runId?: string; key?: string; evidence?: string }> {
259
+ if (!existsSync(dbPath)) return [];
260
+ let store: LogStore | undefined;
261
+ try {
262
+ store = LogStore.openReadOnly(dbPath);
263
+ return store.queryAll({ exactCategories: ['doctor.review'], events: ['brief-issued'] }).flatMap((row: LogStoreRow) => {
264
+ const data = parseReviewBriefLogData(row.data);
265
+ const rowRunId = typeof data.runId === 'string' && data.runId ? data.runId : undefined;
266
+ if (runId !== undefined && rowRunId !== runId) return [];
267
+ return [{ timestamp: new Date(row.ts_ms).toISOString(), sequence: row.id, ...(rowRunId ? { runId: rowRunId } : {}), key: String(data.pr), evidence: `PR #${data.pr} head ${data.head.slice(0, 12)} r${data.round} rx=${String(data.rx)}${data.source === 'pr-disposition' ? ' source=pr-disposition' : ''}` }];
268
+ });
269
+ } catch (error) {
270
+ throw new Error(`review event logs could not be read: ${error instanceof Error ? error.message : String(error)}`);
271
+ }
272
+ finally { store?.close(); }
230
273
  }
231
274
 
232
275
  const repositoryRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../..');
@@ -1293,6 +1336,9 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
1293
1336
  const out = deps.out ?? { log: (value: string) => console.log(value) };
1294
1337
  const err = deps.err ?? { error: (value: string) => console.error(value) };
1295
1338
  const setExitCode = deps.setExitCode ?? ((code: number) => { process.exitCode = code; });
1339
+ const registerDoctorLogSink = deps.registerDoctorLogSink ?? (async () =>
1340
+ (await import('../domains/standalone-log-sink.js')).registerStandaloneLogSink('cli'));
1341
+ const flushDoctorLogs = deps.flushDoctorLogs ?? (() => debug.flush());
1296
1342
  const doctor = program.command('doctor')
1297
1343
  .description('Reports whether credentials resolve and where each resolution comes from')
1298
1344
  .option('--json', 'structured output');
@@ -1358,9 +1404,10 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
1358
1404
  .argument('<runId>', 'run id whose ledger receives the visit')
1359
1405
  .requiredOption('--started-at <iso>', 'Pod status.startTime as an ISO timestamp')
1360
1406
  .option('--json', 'structured output')
1361
- .action((runId: string, opts: { startedAt: string; json?: boolean }, command: Command) => {
1407
+ .action(async (runId: string, opts: { startedAt: string; json?: boolean }, command: Command) => {
1362
1408
  const json = opts.json === true || command.parent?.opts().json === true;
1363
1409
  try {
1410
+ await registerDoctorLogSink();
1364
1411
  const result = recordAutoLongRunVisit({ runId, startedAt: opts.startedAt,
1365
1412
  ...(deps.doctorAutoLongRunNow ? { now: deps.doctorAutoLongRunNow() } : {}),
1366
1413
  ...(deps.doctorVisitLedgerDir !== undefined ? { dir: deps.doctorVisitLedgerDir } : {}) });
@@ -1370,6 +1417,8 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
1370
1417
  if (json) out.log(JSON.stringify({ status: 'rejected', reason }));
1371
1418
  else err.error(reason);
1372
1419
  setExitCode(1);
1420
+ } finally {
1421
+ flushDoctorLogs();
1373
1422
  }
1374
1423
  });
1375
1424
  doctor.command('visit')
@@ -1379,7 +1428,7 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
1379
1428
  .requiredOption('--from <who>', `closed sender list: ${DOCTOR_VISIT_SOURCES.join(', ')}`)
1380
1429
  .option('--evidence <text>', 'free-text evidence recorded with the visit')
1381
1430
  .option('--json', 'structured output')
1382
- .action((runId: string, opts: { symptom: string; from: string; evidence?: string; json?: boolean }, command: Command) => {
1431
+ .action(async (runId: string, opts: { symptom: string; from: string; evidence?: string; json?: boolean }, command: Command) => {
1383
1432
  const json = opts.json === true || command.parent?.opts().json === true;
1384
1433
  if (!isDoctorSymptom(opts.symptom)) {
1385
1434
  const reason = `unknown symptom: ${opts.symptom} — closed list: ${DOCTOR_SYMPTOMS.join(', ')}`;
@@ -1396,6 +1445,7 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
1396
1445
  return;
1397
1446
  }
1398
1447
  try {
1448
+ await registerDoctorLogSink();
1399
1449
  const visit = recordDoctorVisit({
1400
1450
  runId,
1401
1451
  from: opts.from,
@@ -1410,6 +1460,54 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
1410
1460
  if (json) out.log(JSON.stringify({ status: 'rejected', reason }));
1411
1461
  else err.error(reason);
1412
1462
  setExitCode(1);
1463
+ } finally {
1464
+ flushDoctorLogs();
1465
+ }
1466
+ });
1467
+ doctor.command('review-brief')
1468
+ .description('Build a review-round card from saved reviews for the current PR head')
1469
+ .requiredOption('--pr <number>', 'PR number')
1470
+ .option('--json', 'structured output')
1471
+ .action(async (opts: { pr: string; json?: boolean }, command: Command) => {
1472
+ const json = opts.json === true || command.parent?.opts().json === true;
1473
+ const pr = Number(opts.pr);
1474
+ if (!Number.isSafeInteger(pr) || pr <= 0) {
1475
+ const reason = 'PR number must be a positive integer';
1476
+ if (json) out.log(JSON.stringify({ status: 'rejected', reason })); else err.error(reason);
1477
+ setExitCode(1);
1478
+ return;
1479
+ }
1480
+ try {
1481
+ const brief = readDoctorReviewBrief(pr, deps.readReviewBriefPr, deps.reviewResultsDir);
1482
+ const event = reviewBriefEvidence(brief);
1483
+ const intentBlock = typeof event.intentBlock === 'string' ? event.intentBlock : null;
1484
+ if (deps.reviewBriefLog) deps.reviewBriefLog(event);
1485
+ else {
1486
+ await (await import('../domains/standalone-log-sink.js')).registerStandaloneLogSink('cli');
1487
+ debug.log('doctor.review', 'brief-issued', event);
1488
+ debug.flush();
1489
+ }
1490
+ out.log(json ? JSON.stringify({ ...brief, intentBlock }, null, 2) : [
1491
+ `PR #${pr} · ${brief.status} · rounds=${brief.rounds} · head=${brief.head.slice(0, 12)} · verdict=${brief.reviewedVerdict} · rx=${brief.rx}`,
1492
+ ...(brief.dispositionEvidence ? [`Source: PR author disposition (current head review unmeasured) · ${brief.dispositionEvidence}`] : []),
1493
+ ...(brief.goalQuestion ? [`Original question: ${brief.goalQuestion}`] : []),
1494
+ ...(brief.acceptanceSignal.length ? ['Acceptance signal:', ...brief.acceptanceSignal.map((item) => ` - ${item}`)] : []),
1495
+ `Core items (${brief.coreItems.length}/${brief.totalCoreItems}):`,
1496
+ ...brief.coreItems.map((item) => ` [${item.kind}] ${item.text}`),
1497
+ ...(brief.omittedCoreItems ? [`Core items omitted: ${brief.omittedCoreItems}; source files: ${brief.resultPaths.join(', ')}`] : []),
1498
+ `Prior findings (${brief.priorFindings.length}/${brief.totalPriorFindings}):`, ...brief.priorFindings.map((item) => ` [${item.kind} · ${item.sourceHead.slice(0, 12)}] ${item.text}`),
1499
+ ...(brief.omittedPriorFindings ? [`Prior findings omitted: ${brief.omittedPriorFindings}; source files: ${brief.resultPaths.join(', ')}`] : []),
1500
+ `Scope candidates (${brief.scopeItems.length}/${brief.totalScopeItems}):`, ...brief.scopeItems.map((item) => ` [${item.kind}] ${item.text}`),
1501
+ ...(brief.omittedScopeItems ? [`Scope candidates omitted: ${brief.omittedScopeItems}; source files: ${brief.resultPaths.join(', ')}`] : []),
1502
+ ...(brief.resultPaths.length ? [`Review source files: ${brief.resultPaths.join(', ')}`] : []),
1503
+ `Scope boundary: ${brief.scopeBoundary}`,
1504
+ ...(intentBlock ? ['R3 intent shadow output:', intentBlock] : []),
1505
+ ...(brief.reason ? [`Reason: ${brief.reason}`] : []),
1506
+ ].join('\n'));
1507
+ } catch (error) {
1508
+ const reason = observationError(error);
1509
+ if (json) out.log(JSON.stringify({ status: 'unavailable', pr, reason })); else err.error(reason);
1510
+ setExitCode(1);
1413
1511
  }
1414
1512
  });
1415
1513
  doctor.command('status')
@@ -1427,18 +1525,29 @@ export function registerDoctorCommand(program: Command, deps: DoctorCliDeps = {}
1427
1525
  return;
1428
1526
  }
1429
1527
  const visits = readDoctorVisits(opts.run, ledgerScope);
1528
+ let reviewEvents: Array<{ timestamp?: string; sequence?: number; runId?: string; key?: string; evidence?: string }>;
1529
+ try {
1530
+ reviewEvents = (deps.readReviewBriefEvents ?? ((runId?: string) => readReviewBriefEventsFromLogs(logsDbPath(), runId)))(opts.run);
1531
+ } catch (error) {
1532
+ const reason = observationError(error);
1533
+ if (json) out.log(JSON.stringify({ status: 'unavailable', reason, recordedVisits: visits }, null, 2));
1534
+ else out.log(`Doctor status unavailable: ${reason}\nRecorded doctor visits: ${visits.length}`);
1535
+ setExitCode(1);
1536
+ return;
1537
+ }
1538
+ const statusVisits = [...visits, ...doctorReviewVisits(reviewEvents)];
1430
1539
  const counts = Object.fromEntries(DOCTOR_SYMPTOMS.map((symptom: DoctorSymptom) => [symptom, 0])) as Record<DoctorSymptom, number>;
1431
- for (const visit of visits) counts[visit.symptom] += 1;
1540
+ for (const visit of statusVisits) counts[visit.symptom] += 1;
1432
1541
  if (json) {
1433
- out.log(JSON.stringify({ total: visits.length, counts, visits }, null, 2));
1542
+ out.log(JSON.stringify({ total: statusVisits.length, counts, visits: statusVisits }, null, 2));
1434
1543
  return;
1435
1544
  }
1436
1545
  out.log([
1437
- `Doctor visits: ${visits.length}`,
1546
+ `Doctor visits: ${statusVisits.length}`,
1438
1547
  ...DOCTOR_SYMPTOMS.map((symptom: DoctorSymptom) => ` ${symptom}: ${counts[symptom]}`),
1439
1548
  'Recent visits:',
1440
- ...visits.map((visit) => ` ${visit.timestamp ?? 'unknown-time'} runId=${visit.runId} from=${visit.from} symptom=${visit.symptom}${visit.evidence !== undefined ? ` evidence=${visit.evidence}` : ''}`),
1441
- ...(visits.length === 0 ? [' none'] : []),
1549
+ ...statusVisits.map((visit) => ` ${visit.timestamp ?? 'unknown-time'}${visit.runId ? ` runId=${visit.runId}` : ''} from=${visit.from} symptom=${visit.symptom}${visit.evidence !== undefined ? ` evidence=${visit.evidence}` : ''}`),
1550
+ ...(statusVisits.length === 0 ? [' none'] : []),
1442
1551
  ].join('\n'));
1443
1552
  });
1444
1553
  doctor
@@ -49,6 +49,8 @@ import { bookmarkAttachDefaults } from './remote-resolve.js';
49
49
  import { RemotesStore } from './remotes.js';
50
50
  import { detectRepeatedFailures, explainFailure } from '../domains/repeated-failure.js';
51
51
  import { redactSecretText } from '../debug/log.js';
52
+ // 타입 전용 — `graph-templates` 는 typescript 를 무는 모듈이라 «런타임 정적 의존»으로 두지 않는다.
53
+ import type { GraphTemplate } from '../self-implement/graph-templates.js';
52
54
 
53
55
  export interface LogsCliOpts {
54
56
  follow?: boolean;
@@ -99,6 +101,14 @@ export interface LogsCliOpts {
99
101
  all?: boolean;
100
102
  /** --all 연합에 격리 test 인스턴스도 포함(기본 제외 · Phase A). */
101
103
  includeTest?: boolean;
104
+ /** ⭐ 런 종료 «이후» L0 커버리지를 열린 스토어들(부모·Pod)의 걸음 행으로 다시 조인해 센다(ARG-L0-COVER). */
105
+ recompute?: boolean;
106
+ /** --recompute 조인 키 — runId. */
107
+ run?: string;
108
+ /** --recompute 조인 키 — journeyKey(Pod 자식이 물려받는 키). */
109
+ journey?: string;
110
+ /** --recompute 대상 그래프 id (기본 self-implement). */
111
+ graph?: string;
102
112
  }
103
113
 
104
114
  // ── 인스턴스 타겟 해석 (LF7-b) ────────────────────────────────────────
@@ -1522,14 +1532,349 @@ export function aggregateListEvents(
1522
1532
  return { events, truncated, unreadable };
1523
1533
  }
1524
1534
 
1535
+ // ── L0 커버리지 «런 종료 후» 조인 재계산 (ARG-L0-COVER · 2026-10-24) ──────
1536
+ //
1537
+ // 🩸 계기: `#25957` 은 런이 **끝나는 순간** logs.db «한 곳»만 읽어 `l0-coverage` 를 낸다.
1538
+ // 설치본 10-12 표본 = declarationCoverage 1 · traversalCoverage 11/26(0.423076923) · unjoinedNodes 15.
1539
+ // 그 15 는 «다른 프로세스(Pod)가 자기 우주에 남긴 걸음»이라 종료 시점엔 원리상 조인할 수 없다.
1540
+ // ⇒ 조회 시점에 부모·Pod 스토어를 `journeyKey`/`runId` 로 합쳐 다시 세는 경로가 «없어서»
1541
+ // 사람이 두 우주를 손으로 오가며 셌고, 그때마다 0.42 를 «미달»로 오독했다.
1542
+ //
1543
+ // ⛔ 이 재계산은 **조회 시점의 별도 표시**다 — 런 종료 관측(`l0-coverage`)과 원장 형식은 «그대로» 둔다.
1544
+ // ⛔ 미관측(unobserved)을 skipped 나 0 으로 접지 않는다. 셋은 서로 다른 값이다:
1545
+ // joined = 이 런/여정에서 실제로 걸었다(어느 스토어에서 봤는지까지 남긴다)
1546
+ // skipped = 조건이 거짓이라 안 걸었다 — **관측이 그렇게 판정한 행이 있을 때만**
1547
+ // unobserved = 아무도 안 봤다 — 분자에도 분모의 다른 칸에도 섞지 않는다
1548
+ // ⛔ 조인 안 된 노드를 `unjoinedNodes: ['a','b',…]` 하나로 뭉개지 않는다 —
1549
+ // **스토어(우주/호스트)별 + 사유별**로 낸다(사유가 다르면 처방이 다르다).
1550
+
1551
+ /** 조인되지 않은 «사유» — 닫힌 어휘. 자유 문자열이면 「왜 안 붙었나」를 셀 수 없다. */
1552
+ export type L0UnjoinedReason =
1553
+ /** 같은 그래프 선언이 아니다(다른 graphId/버전) — 노드 id 를 비교할 수 없다. */
1554
+ | 'graph-mismatch'
1555
+ /** 여정 단계(phase) 행이 아니다 — 걸음이 아니라 다른 관측이다. */
1556
+ | 'phase-mismatch'
1557
+ /** journeyKey 가 둘 다 있는데 다르다 — 다른 여정(프로세스)의 걸음이다. */
1558
+ | 'journey-key-mismatch'
1559
+ /** runId 가 둘 다 있는데 다르다 — 조인 키가 이 런이 아니다. */
1560
+ | 'run-id-mismatch'
1561
+ /** 행에 runId 도 journeyKey 도 없다 — «내 것인지» 판정할 근거가 없다(0 으로 접지 않는다). */
1562
+ | 'identity-absent';
1563
+
1564
+ export interface JoinedCoverageRow {
1565
+ readonly event: string;
1566
+ readonly data: string | null;
1567
+ }
1568
+
1569
+ export interface JoinedCoverageStore {
1570
+ readonly name: string;
1571
+ readonly rows: readonly JoinedCoverageRow[];
1572
+ }
1573
+
1574
+ export interface JoinedCoverageInput {
1575
+ readonly runId?: string;
1576
+ readonly journeyKey?: string;
1577
+ readonly stores: readonly JoinedCoverageStore[];
1578
+ /** 열지 못한 스토어(다른 우주/호스트) — «못 본» 사실을 수 옆에 남긴다. */
1579
+ readonly storesNotQueried?: readonly string[];
1580
+ }
1581
+
1582
+ export interface JoinedCoverageUnjoined {
1583
+ readonly node: string;
1584
+ readonly host: string;
1585
+ readonly reason: L0UnjoinedReason;
1586
+ }
1587
+
1588
+ export interface L0CoverageMeasureResult {
1589
+ readonly declarationCoverage: number | null;
1590
+ readonly traversalCoverage: number | null;
1591
+ readonly declaredStageCount: number;
1592
+ readonly listedStageCount: number;
1593
+ readonly accountedNodeCount: number;
1594
+ readonly declaredNodeCount: number;
1595
+ }
1596
+
1597
+ /** 계량기는 주입받는다 — `graph-templates`(typescript 를 싣는다)를 CLI 정적 의존으로 끌어오지 않기 위해서다. */
1598
+ export type L0CoverageMeasure = (
1599
+ template: GraphTemplate,
1600
+ entered: Iterable<string>,
1601
+ skipped: Iterable<string>,
1602
+ ) => L0CoverageMeasureResult;
1603
+
1604
+ export interface JoinedL0Coverage extends L0CoverageMeasureResult {
1605
+ readonly graphId: string;
1606
+ readonly graphVersion: string;
1607
+ readonly runId: string | null;
1608
+ readonly journeyKey: string | null;
1609
+ readonly joinedNodes: ReadonlyArray<{ readonly node: string; readonly hosts: readonly string[] }>;
1610
+ readonly skippedNodes: readonly string[];
1611
+ readonly unobservedNodes: readonly string[];
1612
+ readonly unjoinedNodes: readonly JoinedCoverageUnjoined[];
1613
+ readonly unjoinedByHost: ReadonlyArray<{
1614
+ readonly host: string;
1615
+ readonly count: number;
1616
+ readonly reasons: ReadonlyArray<{ readonly reason: L0UnjoinedReason; readonly nodes: readonly string[] }>;
1617
+ }>;
1618
+ readonly storesRead: ReadonlyArray<{
1619
+ readonly name: string;
1620
+ readonly nodeRows: number;
1621
+ readonly skippedRows: number;
1622
+ }>;
1623
+ readonly storesNotQueried: readonly string[];
1624
+ }
1625
+
1626
+ interface ParsedPipelineNodeRow {
1627
+ readonly host: string;
1628
+ readonly node: string;
1629
+ readonly runId?: string;
1630
+ readonly journeyKey?: string;
1631
+ readonly graphId?: string;
1632
+ readonly graphVersion?: string;
1633
+ readonly phase?: string;
1634
+ }
1635
+
1636
+ /** 원장 행(data JSON) → 조인 판정에 필요한 칸. `node` 가 없으면 걸음 행이 아니다. */
1637
+ function parsePipelineNodeRow(host: string, data: string | null): ParsedPipelineNodeRow | null {
1638
+ if (data === null) return null;
1639
+ let parsed: unknown;
1640
+ try { parsed = JSON.parse(data); } catch { return null; }
1641
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) return null;
1642
+ const record = parsed as Record<string, unknown>;
1643
+ if (typeof record.node !== 'string' || record.node.length === 0) return null;
1644
+ const text = (key: string): string | undefined => {
1645
+ const value = record[key];
1646
+ return typeof value === 'string' && value.length > 0 ? value : undefined;
1647
+ };
1648
+ const runId = text('runId');
1649
+ const journeyKey = text('journeyKey');
1650
+ const graphId = text('graphId');
1651
+ const graphVersion = text('graphVersion');
1652
+ const phase = text('phase');
1653
+ return {
1654
+ host,
1655
+ node: record.node,
1656
+ ...(runId === undefined ? {} : { runId }),
1657
+ ...(journeyKey === undefined ? {} : { journeyKey }),
1658
+ ...(graphId === undefined ? {} : { graphId }),
1659
+ ...(graphVersion === undefined ? {} : { graphVersion }),
1660
+ ...(phase === undefined ? {} : { phase }),
1661
+ };
1662
+ }
1663
+
1664
+ /** null = 이 런/여정의 걸음이다. 그 밖에는 «왜 아닌지» 하나. */
1665
+ function pipelineNodeRowMismatch(
1666
+ template: Pick<GraphTemplate, 'graphId' | 'version'>,
1667
+ key: Pick<JoinedCoverageInput, 'runId' | 'journeyKey'>,
1668
+ row: ParsedPipelineNodeRow,
1669
+ ): L0UnjoinedReason | null {
1670
+ if (row.graphId !== undefined && row.graphId !== template.graphId) return 'graph-mismatch';
1671
+ if (row.graphVersion !== undefined && row.graphVersion !== template.version) return 'graph-mismatch';
1672
+ if (row.phase !== undefined && row.phase !== 'journey') return 'phase-mismatch';
1673
+ // ⭐ Pod 자식은 runId 가 다르다 — journeyKey 가 같으면 «같은 여정»이라 붙인다(이 조각의 요점).
1674
+ const byJourney = key.journeyKey !== undefined && row.journeyKey === key.journeyKey;
1675
+ const byRun = key.runId !== undefined && row.runId === key.runId;
1676
+ if (byJourney || byRun) return null;
1677
+ if (key.journeyKey !== undefined && row.journeyKey !== undefined) return 'journey-key-mismatch';
1678
+ if (key.runId !== undefined && row.runId !== undefined) return 'run-id-mismatch';
1679
+ return 'identity-absent';
1680
+ }
1681
+
1682
+ /**
1683
+ * 여러 스토어(부모·Pod)의 `pipeline-node-entry`/`node-skipped` 를 조인 키로 합쳐
1684
+ * 선언·걸음 커버리지를 다시 센다. 런 종료 관측은 건드리지 않는다.
1685
+ */
1686
+ export function recomputeJoinedL0Coverage(
1687
+ template: GraphTemplate,
1688
+ input: JoinedCoverageInput,
1689
+ measure: L0CoverageMeasure,
1690
+ ): JoinedL0Coverage {
1691
+ const nodeRows: ParsedPipelineNodeRow[] = [];
1692
+ const skippedRows: ParsedPipelineNodeRow[] = [];
1693
+ const storesRead: Array<{ name: string; nodeRows: number; skippedRows: number }> = [];
1694
+ for (const store of input.stores) {
1695
+ let nodeRowCount = 0;
1696
+ let skippedRowCount = 0;
1697
+ for (const row of store.rows) {
1698
+ const parsed = parsePipelineNodeRow(store.name, row.data);
1699
+ if (parsed === null) continue;
1700
+ if (row.event === 'pipeline-node-entry') { nodeRows.push(parsed); nodeRowCount += 1; }
1701
+ else if (row.event === 'node-skipped') { skippedRows.push(parsed); skippedRowCount += 1; }
1702
+ }
1703
+ storesRead.push({ name: store.name, nodeRows: nodeRowCount, skippedRows: skippedRowCount });
1704
+ }
1705
+
1706
+ const declaredNodeIds = template.nodes.map((node) => node.nodeId);
1707
+ const enteredHosts = new Map<string, Set<string>>();
1708
+ const unjoined: JoinedCoverageUnjoined[] = [];
1709
+ const unjoinedSeen = new Set<string>();
1710
+
1711
+ for (const nodeId of declaredNodeIds) {
1712
+ const joinedHosts = new Set<string>();
1713
+ for (const row of nodeRows) {
1714
+ if (row.node !== nodeId) continue;
1715
+ const reason = pipelineNodeRowMismatch(template, input, row);
1716
+ if (reason === null) { joinedHosts.add(row.host); continue; }
1717
+ const dedupeKey = `${row.host}\u0000${reason}\u0000${nodeId}`;
1718
+ if (unjoinedSeen.has(dedupeKey)) continue;
1719
+ unjoinedSeen.add(dedupeKey);
1720
+ unjoined.push({ node: nodeId, host: row.host, reason });
1721
+ }
1722
+ if (joinedHosts.size > 0) enteredHosts.set(nodeId, joinedHosts);
1723
+ }
1724
+
1725
+ const unjoinedNodes = new Set(unjoined.map((entry) => entry.node));
1726
+ const joinedNodes = declaredNodeIds
1727
+ .filter((nodeId) => enteredHosts.has(nodeId))
1728
+ .map((nodeId) => ({ node: nodeId, hosts: [...enteredHosts.get(nodeId)!].sort() }));
1729
+
1730
+ const skipped = new Set<string>();
1731
+ for (const row of skippedRows) {
1732
+ if (!declaredNodeIds.includes(row.node)) continue;
1733
+ if (enteredHosts.has(row.node)) continue;
1734
+ if (pipelineNodeRowMismatch(template, input, row) !== null) continue;
1735
+ skipped.add(row.node);
1736
+ }
1737
+ const skippedNodes = [...skipped];
1738
+
1739
+ // ⛔ unobserved 는 «아무도 안 봤다» — joined·skipped·unjoined 중 어디에도 없는 칸에 그대로 남긴다.
1740
+ const unobservedNodes = declaredNodeIds.filter((nodeId) => (
1741
+ !enteredHosts.has(nodeId) && !skipped.has(nodeId) && !unjoinedNodes.has(nodeId)
1742
+ ));
1743
+
1744
+ const byHost = new Map<string, Map<L0UnjoinedReason, Set<string>>>();
1745
+ for (const entry of unjoined) {
1746
+ let reasons = byHost.get(entry.host);
1747
+ if (reasons === undefined) { reasons = new Map(); byHost.set(entry.host, reasons); }
1748
+ let nodes = reasons.get(entry.reason);
1749
+ if (nodes === undefined) { nodes = new Set(); reasons.set(entry.reason, nodes); }
1750
+ nodes.add(entry.node);
1751
+ }
1752
+ const unjoinedByHost = [...byHost.entries()]
1753
+ .sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))
1754
+ .map(([host, reasons]) => ({
1755
+ host,
1756
+ count: [...reasons.values()].reduce((sum, nodes) => sum + nodes.size, 0),
1757
+ reasons: [...reasons.entries()]
1758
+ .sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))
1759
+ .map(([reason, nodes]) => ({ reason, nodes: [...nodes].sort() })),
1760
+ }));
1761
+
1762
+ const coverage = measure(template, joinedNodes.map(({ node }) => node), skippedNodes);
1763
+ return {
1764
+ ...coverage,
1765
+ graphId: template.graphId,
1766
+ graphVersion: template.version,
1767
+ runId: input.runId ?? null,
1768
+ journeyKey: input.journeyKey ?? null,
1769
+ joinedNodes,
1770
+ skippedNodes,
1771
+ unobservedNodes,
1772
+ unjoinedNodes: [...unjoined].sort((a, b) => (
1773
+ a.host < b.host ? -1 : a.host > b.host ? 1 : a.node < b.node ? -1 : a.node > b.node ? 1 : 0
1774
+ )),
1775
+ unjoinedByHost,
1776
+ storesRead,
1777
+ storesNotQueried: input.storesNotQueried ?? [],
1778
+ };
1779
+ }
1780
+
1781
+ /** 사람용 렌더 — 각 수 옆에 «무엇을 셌나»를 붙인다(미관측·미조인·안 읽은 스토어를 접지 않는다). */
1782
+ export function renderJoinedL0Coverage(result: JoinedL0Coverage): string {
1783
+ const ratio = (value: number | null): string => (value === null ? '미측정' : String(value));
1784
+ const lines = [
1785
+ `L0 커버리지 재계산(조인) — ${result.graphId}@${result.graphVersion} · runId=${result.runId ?? '(없음)'} · journeyKey=${result.journeyKey ?? '(없음)'}`,
1786
+ ` 선언 커버리지 ${ratio(result.declarationCoverage)} (단계 ${result.declaredStageCount}/${result.listedStageCount})`,
1787
+ ` 걸음 커버리지 ${ratio(result.traversalCoverage)} (노드 ${result.accountedNodeCount}/${result.declaredNodeCount} = 조인 ${result.joinedNodes.length} + 건너뜀 ${result.skippedNodes.length} · 미관측 ${result.unobservedNodes.length} 는 세지 않음)`,
1788
+ ];
1789
+ if (result.storesRead.length > 0) {
1790
+ lines.push(` 읽은 스토어: ${result.storesRead.map((store) => `${store.name}(걸음 ${store.nodeRows}·건너뜀 ${store.skippedRows})`).join(' · ')}`);
1791
+ }
1792
+ if (result.joinedNodes.length > 0) {
1793
+ lines.push(` 조인된 노드 ${result.joinedNodes.length}개: ${result.joinedNodes.map(({ node, hosts }) => `${node}⟨${hosts.join('·')}⟩`).join(' ')}`);
1794
+ }
1795
+ if (result.skippedNodes.length > 0) {
1796
+ lines.push(` 건너뜀(조건 거짓 · 관측 판정) ${result.skippedNodes.length}개: ${result.skippedNodes.join(', ')}`);
1797
+ }
1798
+ if (result.unobservedNodes.length > 0) {
1799
+ lines.push(` ⛔ 미관측 ${result.unobservedNodes.length}개 — 건너뜀도 0도 아니다(아무도 안 봤다 · 읽은 스토어 원장에 이 런/여정 걸음이 없다): ${result.unobservedNodes.join(', ')}`);
1800
+ }
1801
+ for (const bucket of result.unjoinedByHost) {
1802
+ lines.push(` 미조인 ${bucket.host} ${bucket.count}개: ${bucket.reasons.map(({ reason, nodes }) => `${reason}=${nodes.join(',')}`).join(' · ')}`);
1803
+ }
1804
+ if (result.storesNotQueried.length > 0) {
1805
+ lines.push(` ⚠ 안 읽은 스토어 ${result.storesNotQueried.length}개: ${result.storesNotQueried.join(', ')} — 위 수는 «읽은 스토어 안에서만» 센 값이다(전체 미조인 수는 더 클 수 있다).`);
1806
+ }
1807
+ return lines.join('\n');
1808
+ }
1809
+
1810
+ /** `--recompute` 조회 — 열린 스토어들의 걸음 이벤트 행을 «전부» 모아 조인 계층이 이 런/여정인지 판정하게 넘긴다. */
1811
+ async function runLogsCoverageRecompute(
1812
+ opts: LogsCliOpts,
1813
+ opened: ReadonlyArray<{ name: string; store: LogStore }>,
1814
+ storesNotQueried: readonly string[],
1815
+ ): Promise<number> {
1816
+ const runId = opts.run?.trim() || undefined;
1817
+ const journeyKey = opts.journey?.trim() || undefined;
1818
+ const closeAll = (): void => { for (const { store } of opened) store.close(); };
1819
+ if (runId === undefined && journeyKey === undefined) {
1820
+ console.error('elanous logs: --recompute 는 조인 키가 필요하다 — --run <runId> 또는 --journey <journeyKey>');
1821
+ closeAll();
1822
+ return 1;
1823
+ }
1824
+ const graphId = opts.graph?.trim() || 'self-implement';
1825
+ // 동적 import — typescript 를 무는 모듈이라 «재계산 경로에서만» 싣는다(기본 조회 무회귀).
1826
+ const { GRAPH_TEMPLATES, measureL0Coverage } = await import('../self-implement/graph-templates.js');
1827
+ const template = GRAPH_TEMPLATES[graphId];
1828
+ if (template === undefined) {
1829
+ console.error(`elanous logs: --graph '${graphId}' 는 선언된 그래프가 아니다 (선언: ${Object.keys(GRAPH_TEMPLATES).join(', ')})`);
1830
+ closeAll();
1831
+ return 1;
1832
+ }
1833
+ // ⛔ 조회 단계에서 조인 키로 미리 거르지 않는다(`grep: runId|journeyKey` 사전필터 금지).
1834
+ // 미리 거르면 열린 스토어 안의 «다른 여정» 걸음 행이 조인 계층에 도달하지 못해,
1835
+ // `journey-key-mismatch` 로 잡혀야 할 선언 노드가 «아무도 안 봤다(unobserved)» 로 오분류된다.
1836
+ // ⇒ 이벤트 필터(`pipeline-node-entry`/`node-skipped`)로만 읽고 «내 것인가» 판정은 조인 계층에 전부 맡긴다.
1837
+ const stores: JoinedCoverageStore[] = [];
1838
+ const unreadable: string[] = [];
1839
+ for (const { name, store } of opened) {
1840
+ const rows: JoinedCoverageRow[] = [];
1841
+ try {
1842
+ for (const row of store.queryAll({ events: ['pipeline-node-entry', 'node-skipped'] })) {
1843
+ rows.push({ event: row.event, data: row.data });
1844
+ }
1845
+ } catch (error) {
1846
+ unreadable.push(name);
1847
+ console.error(`elanous logs: ${name} 조회 실패 — ${error instanceof Error ? error.message : String(error)}`);
1848
+ }
1849
+ stores.push({ name, rows });
1850
+ }
1851
+ const result = recomputeJoinedL0Coverage(template, {
1852
+ ...(runId === undefined ? {} : { runId }),
1853
+ ...(journeyKey === undefined ? {} : { journeyKey }),
1854
+ stores,
1855
+ storesNotQueried: [...storesNotQueried, ...unreadable],
1856
+ }, measureL0Coverage);
1857
+ if (opts.json) {
1858
+ console.log(JSON.stringify({ _meta: { type: 'log-query-l0-coverage-recomputed' }, ...result }));
1859
+ } else {
1860
+ console.log(renderJoinedL0Coverage(result));
1861
+ }
1862
+ closeAll();
1863
+ return unreadable.length > 0 ? 2 : 0;
1864
+ }
1865
+
1525
1866
  /** 조회 또는 follow. follow 는 Ctrl-C 까지 블록. 복수 타겟(--all)은 ts 병합. */
1526
1867
  export async function runLogsCli(opts: LogsCliOpts, deps: RunLogsCliDeps = {}): Promise<number> {
1527
1868
  const remoteFlag = resolveLogsRemoteFlag(opts);
1528
1869
  if (remoteFlag !== undefined) {
1529
1870
  if (opts.topFailures) { console.error('elanous logs: --top-failures 는 로컬 스토어 조회에서만 지원'); return 1; }
1871
+ // 조인 재계산은 «여러 스토어의 원장 행»을 합치는 일이다 — 원격 한 번 조회로는 성립하지 않는다.
1872
+ if (opts.recompute) { console.error('elanous logs: --recompute 는 로컬 스토어에서만 지원 — 원격은 로컬 원장을 못 본다'); return 1; }
1530
1873
  return runLogsCliRemote(opts, remoteFlag, deps);
1531
1874
  }
1532
1875
  if (opts.topFailures && opts.follow) { console.error('elanous logs: --top-failures 는 --follow 와 함께 쓸 수 없다'); return 1; }
1876
+ // 한 번의 조인 재계산은 «한 시점의 스냅숏»이다 — follow 와 섞으면 폴마다 다른 답을 낸다.
1877
+ if (opts.recompute && opts.follow) { console.error('elanous logs: --recompute 는 --follow 와 함께 쓸 수 없다'); return 1; }
1533
1878
  const threshold = opts.threshold === undefined ? 20 : Number(opts.threshold);
1534
1879
  if (opts.topFailures && (!Number.isSafeInteger(threshold) || threshold < 1)) {
1535
1880
  console.error('elanous logs: --threshold 는 양의 정수여야 한다'); return 1;
@@ -1548,10 +1893,12 @@ export async function runLogsCli(opts: LogsCliOpts, deps: RunLogsCliDeps = {}):
1548
1893
  // read-only open — 타겟이 어느 인스턴스든 CLI 조회는 write 0 (연합 불변식).
1549
1894
  const opened: Array<{ name: string; store: LogStore }> = [];
1550
1895
  const missing: string[] = [];
1896
+ /** 열지 못한 타겟 이름 — 조인 재계산이 «못 본 우주»를 0 으로 접지 않게 그대로 넘긴다. */
1897
+ const missingNames: string[] = [];
1551
1898
  for (const t of resolved.targets) {
1552
- if (!existsSync(t.dbPath)) { missing.push(`${t.name} (${t.dbPath})`); continue; }
1899
+ if (!existsSync(t.dbPath)) { missing.push(`${t.name} (${t.dbPath})`); missingNames.push(t.name); continue; }
1553
1900
  try { opened.push({ name: t.name, store: LogStore.openReadOnly(t.dbPath) }); }
1554
- catch { missing.push(`${t.name} (${t.dbPath} — open 실패)`); }
1901
+ catch { missing.push(`${t.name} (${t.dbPath} — open 실패)`); missingNames.push(t.name); }
1555
1902
  }
1556
1903
  const openedStores = opened.map(({ name, store }) => ({ name, path: store.path }));
1557
1904
  // 등록된 존재 DB의 고유 경로가 조회 가능 모집단이다. 선택 규칙은 건드리지 않고,
@@ -1589,6 +1936,8 @@ export async function runLogsCli(opts: LogsCliOpts, deps: RunLogsCliDeps = {}):
1589
1936
  return 1;
1590
1937
  }
1591
1938
  if (missing.length > 0) console.error(`elanous logs: 스킵 — ${missing.join(' · ')}`);
1939
+ // ⭐ 런 종료 «이후» 조인 재계산 — 별도 표시 모드다(기본 조회·런 종료 관측·원장 형식 무변경).
1940
+ if (opts.recompute === true) return runLogsCoverageRecompute(opts, opened, missingNames);
1592
1941
  if (opts.topFailures) {
1593
1942
  const rows: LogStoreRow[] = [];
1594
1943
  const unreadable: string[] = [];
@@ -2041,6 +2390,12 @@ const logsCmd = program.command('logs')
2041
2390
  .option('--instance <name>', '레지스트리 등록 인스턴스 타겟 (prod|test:<repo>|…)')
2042
2391
  .option('--all', '전 인스턴스 연합 조회 — read-only 병합·⟨instance⟩ 태그')
2043
2392
  .option('--include-test', '--all 연합에 격리 test 인스턴스도 포함(기본 제외)')
2393
+ // ⭐ ARG-L0-COVER — 런이 «끝난 뒤» 부모·Pod 스토어의 걸음을 journeyKey/runId 로 합쳐 다시 센다.
2394
+ // ⛔ 런 종료 관측(`l0-coverage`)을 덮어쓰지 않는다 — 조회 시점의 별도 표시다.
2395
+ .option('--recompute', '열린 스토어들(부모·Pod)의 pipeline-node-entry 로 L0 커버리지를 다시 조인 계산 (--run 또는 --journey 필요)')
2396
+ .option('--run <id>', '--recompute 조인 키: runId')
2397
+ .option('--journey <key>', '--recompute 조인 키: journeyKey (Pod 자식이 물려받은 키)')
2398
+ .option('--graph <id>', '--recompute 대상 그래프 (기본 self-implement)')
2044
2399
  // ⛔ `-r` 은 값을 받지 않는다 — default 북마크만. 이름은 `--remote <name>` 으로만 준다.
2045
2400
  .option('-r', 'query logs on the default remote bookmark (does not take a value)')
2046
2401
  .option('--remote <name>', 'query logs on a named remote bookmark via GET /v1/logs')
@@ -10,6 +10,8 @@ import {
10
10
  readIndex, memoryRoot, memoryIndexPath,
11
11
  type MemoryType,
12
12
  } from '../memory.js';
13
+ import { applyClaudeMemoryImport, claudeMemoryRoot, collectClaudeMemoryFiles } from '../context-bus/claude-memory-import.js';
14
+ import { importClaudeMemories } from '../context-bus/long-term-memory.js';
13
15
 
14
16
  export function registerMemoryCommands(program: Command): void {
15
17
  const memCmd = program.command('memory').description('Persistent memories injected into every chat turn (user / feedback / project / reference)');
@@ -179,4 +181,31 @@ export function registerMemoryCommands(program: Command): void {
179
181
  console.log(`memory dir ${memoryRoot()}`);
180
182
  console.log(`index file ${memoryIndexPath()}`);
181
183
  });
182
- }
184
+
185
+ // 대표 10-12 MEMORY-IMPORT-CLAUDE — Claude 자동 기억(~/.claude/projects/*/memory)을 엘라누스
186
+ // 장기 기억으로 가져온다. 에이전트 무관 — codex·elanous TUI 가 같은 기억을 바로 읽는다.
187
+ memCmd
188
+ .command('import-claude')
189
+ .description('Import Claude auto-memories (~/.claude/projects/*/memory) into elanous memories — same name overwrites')
190
+ .option('--root <path>', 'projects root or a single memory dir', claudeMemoryRoot())
191
+ .option('--as-of <date>', 'staleness basis «MM-DD 기준» (default: today)')
192
+ .option('--dry-run', 'preview without saving')
193
+ .action((opts: { root: string; asOf?: string; dryRun?: boolean }) => {
194
+ const asOf = opts.asOf ?? new Date().toISOString().slice(0, 10);
195
+ const files = collectClaudeMemoryFiles(opts.root);
196
+ if (opts.dryRun) {
197
+ const preview = importClaudeMemories(files, { asOf });
198
+ ui.header(`claude-memory (dry-run) ${files.length} files`);
199
+ for (const item of preview.items) console.log(` [${item.type.padEnd(9)}] ${item.name} ${item.summary}`);
200
+ if (preview.overwritten) console.log(` overwritten ${preview.overwritten}`);
201
+ for (const [reason, count] of Object.entries(preview.skipped)) console.log(` skipped ${reason}:${count}`);
202
+ return;
203
+ }
204
+ const result = applyClaudeMemoryImport(files, { asOf }, {
205
+ list: () => listMemories().map(entry => ({ id: entry.id, name: entry.name })),
206
+ save: record => { saveMemory(record); },
207
+ });
208
+ ui.info(`claude-memory: ${result.saved} new · ${result.updated} overwritten · ${result.items.length} imported (${files.length} files from ${opts.root})`);
209
+ for (const [reason, count] of Object.entries(result.skipped)) ui.info(` skipped ${reason}:${count}`);
210
+ });
211
+ }