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
@@ -0,0 +1,300 @@
1
+ import { readFileSync, readdirSync, statSync } from 'node:fs';
2
+ import { effectiveInstanceRoot } from '../instance/resolve.js';
3
+ import { join } from 'node:path';
4
+
5
+ export type ReviewFindingKind = 'a' | 'b' | 'c' | 'd' | 'unclassified';
6
+ export type ReviewBriefDirection = 'continue' | 'split' | 'partial-land' | 're-ground' | 'decision-card';
7
+
8
+ export interface ReviewResultFile {
9
+ path: string;
10
+ mtimeMs: number;
11
+ value: Record<string, unknown>;
12
+ }
13
+
14
+ export interface ReviewBriefInput {
15
+ pr: number;
16
+ head: string;
17
+ body: string;
18
+ changedFiles: string[];
19
+ results: ReviewResultFile[];
20
+ /** Explicit, separately attributed PR disposition comments; not saved reviews. */
21
+ comments?: string[];
22
+ /** Files that matched this PR's review-result naming pattern but could not be read. */
23
+ readErrors?: string[];
24
+ }
25
+
26
+ export interface ReviewBriefFinding {
27
+ id: string;
28
+ sourceHead: string;
29
+ text: string;
30
+ kind: ReviewFindingKind;
31
+ }
32
+
33
+ export interface ReviewRoundBrief {
34
+ status: 'ready' | 'unmeasured' | 'stale' | 'disposition-only' | 'unavailable';
35
+ /** Saved reviewed-head evidence versus a PR author's explicit split disposition. */
36
+ source: 'saved-review' | 'pr-disposition' | 'none';
37
+ pr: number;
38
+ head: string;
39
+ rounds: number;
40
+ currentHeadMeasured: boolean;
41
+ reviewedHead?: string;
42
+ reviewedVerdict: string;
43
+ reviewedRx: ReviewBriefDirection;
44
+ goalQuestion: string;
45
+ acceptanceSignal: string[];
46
+ declaredScopeBoundary: string[];
47
+ coreItems: ReviewBriefFinding[];
48
+ totalCoreItems: number;
49
+ omittedCoreItems: number;
50
+ resultPaths: string[];
51
+ priorFindings: ReviewBriefFinding[];
52
+ scopeItems: ReviewBriefFinding[];
53
+ totalScopeItems: number;
54
+ omittedScopeItems: number;
55
+ scopeBoundary: string;
56
+ totalPriorFindings: number;
57
+ omittedPriorFindings: number;
58
+ rx: ReviewBriefDirection;
59
+ reason?: string;
60
+ dispositionEvidence?: string;
61
+ readErrors?: string[];
62
+ }
63
+
64
+ const MAX_CORE_ITEMS = 5;
65
+ const MAX_INTENT_ACCEPTANCE_ITEMS = 5;
66
+ const MAX_INTENT_SOURCE_PATHS = 3;
67
+ const MAX_INTENT_ITEM_CHARS = 400;
68
+ export const REVIEW_BRIEF_INTENT_MAX_CHARS = 12_000;
69
+
70
+ function asString(value: unknown): string | null {
71
+ return typeof value === 'string' && value.trim() ? value.trim() : null;
72
+ }
73
+
74
+ function resultPr(value: Record<string, unknown>): number | null {
75
+ const raw = value.pr;
76
+ const parsed = typeof raw === 'number' ? raw : typeof raw === 'string' ? Number(raw) : NaN;
77
+ return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;
78
+ }
79
+
80
+ function resultHead(value: Record<string, unknown>): string | null {
81
+ const head = asString(value.headCommit) ?? asString(value.reviewedHeadCommit);
82
+ return head && /^[a-f0-9]{12,40}$/i.test(head) ? head.toLowerCase() : null;
83
+ }
84
+
85
+ function findings(value: Record<string, unknown>): string[] {
86
+ if (Array.isArray(value.mustFix) && value.mustFix.every((item) => typeof item === 'string')) {
87
+ return value.mustFix.map((item) => item.trim()).filter(Boolean);
88
+ }
89
+ return [];
90
+ }
91
+
92
+ function hasValidFindings(value: Record<string, unknown>): boolean {
93
+ return Array.isArray(value.mustFix) && value.mustFix.every((item) => typeof item === 'string');
94
+ }
95
+
96
+ function section(body: string, heading: string): string[] {
97
+ const lines = body.split(/\r?\n/);
98
+ const headingPattern = new RegExp(`^(#{1,3})\\s*(?:${heading})(?:\\s*[—–:-].*)?\\s*$`, 'i');
99
+ const start = lines.findIndex((line) => headingPattern.test(line.trim()));
100
+ if (start < 0) return [];
101
+ const level = headingPattern.exec(lines[start]!.trim())?.[1]?.length ?? 2;
102
+ const out: string[] = [];
103
+ for (const line of lines.slice(start + 1)) {
104
+ const nextHeading = /^(#{1,6})\s+/.exec(line.trim());
105
+ if (nextHeading && nextHeading[1]!.length <= level) break;
106
+ const text = line.replace(/^\s*[-*]\s*/, '').trim();
107
+ if (text) out.push(text);
108
+ }
109
+ return out;
110
+ }
111
+
112
+ function hasPathReference(text: string, changedFiles: readonly string[], body: string): boolean {
113
+ const paths = [...new Set([...changedFiles, ...(body.match(/(?:src|scripts|test|docs)\/[A-Za-z0-9_./-]+/g) ?? [])])];
114
+ return paths.some((path) => path.length > 3 && text.includes(path));
115
+ }
116
+
117
+ export function classifyReviewFinding(text: string, input: Pick<ReviewBriefInput, 'changedFiles' | 'body'>): ReviewFindingKind {
118
+ const lower = text.toLowerCase();
119
+ if (/\b(?:junit|telemetry|observability) evidence\b|\bmissing (?:log|artifact|ledger) evidence\b|관측 증거|장부 증거/.test(lower)) return 'b';
120
+ if (/\b(?:late lease|lease timeout|timeout race|concurrent|concurrency race|parallel ordering)\b|늦은 lease|lease 시간 초과|동시성 경합/.test(lower)) return 'c';
121
+ if (/\b(?:new (?:test|fixture|evidence) path|missing fixture|separate evidence file)\b|새 시험 경로|별도 증거 파일/.test(lower)) return 'd';
122
+ if (hasPathReference(text, input.changedFiles, input.body) && /accept|assert|must|should|verify|contract|criteria|pass|통과|수용|기준|검증/.test(lower)) return 'a';
123
+ return 'unclassified';
124
+ }
125
+
126
+ function parseReviewResultFiles(dir: string, pr: number): { results: ReviewResultFile[]; errors: string[] } {
127
+ let names: string[];
128
+ try { names = readdirSync(dir); } catch (error) {
129
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') return { results: [], errors: [] };
130
+ return { results: [], errors: [`${dir}: ${error instanceof Error ? error.message : String(error)}`] };
131
+ }
132
+ const suffix = new RegExp(`-${pr}-([a-f0-9]{7,40})\\.json$`, 'i');
133
+ const rows: ReviewResultFile[] = [];
134
+ const errors: string[] = [];
135
+ for (const name of names) {
136
+ const filenameHead = suffix.exec(name)?.[1]?.toLowerCase();
137
+ if (!filenameHead) continue;
138
+ const path = join(dir, name);
139
+ try {
140
+ const stat = statSync(path);
141
+ if (!stat.isFile()) continue;
142
+ const raw = readFileSync(path, 'utf8');
143
+ const value = JSON.parse(raw) as Record<string, unknown>;
144
+ const head = resultHead(value);
145
+ if (resultPr(value) !== pr || value.reviewed !== true || !head || !head.startsWith(filenameHead)) continue;
146
+ rows.push({ path, mtimeMs: stat.mtimeMs, value });
147
+ } catch (error) { errors.push(`${path}: ${error instanceof Error ? error.message : String(error)}`); }
148
+ }
149
+ return { results: rows, errors };
150
+ }
151
+
152
+ function explicitSplitDisposition(comments: readonly string[], input: ReviewBriefInput): Pick<ReviewRoundBrief, 'coreItems' | 'totalCoreItems' | 'omittedCoreItems' | 'dispositionEvidence'> | null {
153
+ for (const body of [...comments].reverse()) {
154
+ const match = /남은 범위\s*=\s*(.+?)\.\s*r(\d+)\s*상한 초과로 분리(?:[.。\s]|$)/i.exec(body);
155
+ if (!match) continue;
156
+ const round = Number(match[2]);
157
+ if (!Number.isSafeInteger(round) || round < 1) continue;
158
+ const items = match[1]!.split(/\s*[·⊕]\s*/).map((text) => text.trim()).filter(Boolean);
159
+ if (!items.length) continue;
160
+ const all = items.map((text, index) => ({ id: `${input.pr}:pr-disposition:${round}:${index + 1}`, sourceHead: input.head, text, kind: classifyReviewFinding(text, input) }));
161
+ return { coreItems: all.slice(0, MAX_CORE_ITEMS), totalCoreItems: all.length,
162
+ omittedCoreItems: Math.max(0, all.length - MAX_CORE_ITEMS), dispositionEvidence: body };
163
+ }
164
+ return null;
165
+ }
166
+
167
+ export function buildReviewRoundBrief(input: ReviewBriefInput): ReviewRoundBrief {
168
+ const perHead = new Map<string, ReviewResultFile>();
169
+ for (const result of input.results) {
170
+ const head = resultHead(result.value);
171
+ if (!head || resultPr(result.value) !== input.pr || result.value.reviewed !== true || !hasValidFindings(result.value)) continue;
172
+ const prior = perHead.get(head);
173
+ if (!prior || prior.mtimeMs < result.mtimeMs || (prior.mtimeMs === result.mtimeMs && prior.path.localeCompare(result.path) < 0)) perHead.set(head, result);
174
+ }
175
+ const rounds = perHead.size;
176
+ const currentHeadMeasured = perHead.has(input.head.toLowerCase());
177
+ const latest = [...perHead.values()].sort((left, right) => right.mtimeMs - left.mtimeMs || right.path.localeCompare(left.path))[0] ?? null;
178
+ const current = currentHeadMeasured ? perHead.get(input.head.toLowerCase())! : latest;
179
+ const sourceHead = current ? resultHead(current.value)! : input.head;
180
+ const orderedHeads = [...perHead.entries()].sort((a, b) => a[1].mtimeMs - b[1].mtimeMs || a[1].path.localeCompare(b[1].path));
181
+ const allFindings = orderedHeads.flatMap(([head, result]) => findings(result.value).map((text, index) => ({
182
+ id: `${input.pr}:${head}:mustFix:${index + 1}`, sourceHead: head, text, kind: classifyReviewFinding(text, input),
183
+ })));
184
+ const historicalFindings = allFindings.filter((item) => !currentHeadMeasured || item.sourceHead !== input.head.toLowerCase());
185
+ const prioritizedHistoricalFindings = !currentHeadMeasured && current
186
+ ? [...historicalFindings.filter((item) => item.sourceHead === sourceHead), ...historicalFindings.filter((item) => item.sourceHead !== sourceHead)]
187
+ : historicalFindings;
188
+ const rawFindings = currentHeadMeasured && current ? findings(current.value) : [];
189
+ const resultPaths = current
190
+ ? [current.path, ...orderedHeads.filter(([head]) => head !== sourceHead).map(([, result]) => result.path)]
191
+ : orderedHeads.map(([, result]) => result.path);
192
+ const classified = rawFindings.map((text, index) => ({ id: `${input.pr}:${sourceHead}:mustFix:${index + 1}`, sourceHead, text, kind: classifyReviewFinding(text, input) }));
193
+ const decisionItems = current ? findings(current.value).map((text, index) => ({ id: `${input.pr}:${sourceHead}:mustFix:${index + 1}`, sourceHead, text, kind: classifyReviewFinding(text, input) })) : [];
194
+ // Saved must-fix entries remain core regardless of their suggested FU kind.
195
+ // b/c/d are routing hints; they never erase a reviewer finding.
196
+ const allCoreItems = classified;
197
+ const coreItems = allCoreItems.slice(0, MAX_CORE_ITEMS);
198
+ const decisionScopeItems = decisionItems.filter((item) => item.kind === 'b' || item.kind === 'c' || item.kind === 'd');
199
+ const allScopeItems = currentHeadMeasured ? decisionScopeItems : [];
200
+ const scopeItems = allScopeItems.slice(0, MAX_CORE_ITEMS);
201
+ const scopeKinds = new Set(allScopeItems.map((item) => item.kind));
202
+ const goalQuestion = section(input.body, 'Q')[0] ?? '';
203
+ const acceptanceSignal = section(input.body, 'A');
204
+ const declaredScopeBoundary = section(input.body, '(?:경계|범위 경계|scope boundary|boundary)');
205
+ const verdict = typeof current?.value.verdict === 'string' ? current.value.verdict.toLowerCase() : '';
206
+ const reviewedRx: ReviewBriefDirection = input.readErrors?.length ? 'decision-card' : decisionItems.length > 0
207
+ ? 'continue'
208
+ : ['pass', 'warn'].includes(verdict) && acceptanceSignal.length > 0 ? 'partial-land' : 'decision-card';
209
+ const unresolvedHistoricalCore = !currentHeadMeasured && historicalFindings.length > 0;
210
+ const rx: ReviewBriefDirection = input.readErrors?.length ? 'decision-card' : currentHeadMeasured ? reviewedRx : unresolvedHistoricalCore ? 'continue' : 'decision-card';
211
+ const candidateDisposition = !input.readErrors?.length && !unresolvedHistoricalCore ? explicitSplitDisposition(input.comments ?? [], input) : null;
212
+ const dispositionRound = candidateDisposition ? Number(/r(\d+)\s*상한 초과로 분리/i.exec(candidateDisposition.dispositionEvidence ?? '')?.[1]) : 0;
213
+ const disposition = candidateDisposition && (!currentHeadMeasured || (Number.isSafeInteger(dispositionRound) && rounds >= dispositionRound))
214
+ ? candidateDisposition : null;
215
+ const scopeBoundary = disposition
216
+ ? currentHeadMeasured
217
+ ? 'PR 작성자의 상한 분리 처분 — 저장된 현재 head must-fix는 core에 그대로 남긴다'
218
+ : 'PR 작성자가 분리한 남은 범위 — 저장된 현재 head 리뷰의 판정으로 취급하지 않는다'
219
+ : scopeKinds.size
220
+ ? `${[...scopeKinds].sort().join('·')} 항목은 FU 후보로 기록하고 주인·칸을 별도 지정한다 · 이 분류만으로 must-fix 를 제거하지 말 것`
221
+ : '분리할 b·c·d 항목 없음 — 미분류 항목은 핵심 검토에 남긴다';
222
+ const status = input.readErrors?.length ? 'unavailable' : disposition && !currentHeadMeasured ? 'disposition-only' : rounds === 0 ? 'unmeasured' : !currentHeadMeasured ? 'stale' : 'ready';
223
+ return {
224
+ status, source: disposition && !currentHeadMeasured ? 'pr-disposition' : rounds ? 'saved-review' : 'none', pr: input.pr, head: input.head,
225
+ rounds, currentHeadMeasured, ...(current ? { reviewedHead: sourceHead } : {}), reviewedVerdict: currentHeadMeasured && !input.readErrors?.length ? verdict || 'unknown' : 'unknown', reviewedRx, goalQuestion, acceptanceSignal, declaredScopeBoundary,
226
+ coreItems: !currentHeadMeasured && disposition ? disposition.coreItems : coreItems, totalCoreItems: !currentHeadMeasured && disposition ? disposition.totalCoreItems : allCoreItems.length, omittedCoreItems: !currentHeadMeasured && disposition ? disposition.omittedCoreItems : Math.max(0, allCoreItems.length - coreItems.length),
227
+ resultPaths, priorFindings: prioritizedHistoricalFindings.slice(0, MAX_CORE_ITEMS),
228
+ totalPriorFindings: historicalFindings.length, omittedPriorFindings: Math.max(0, historicalFindings.length - MAX_CORE_ITEMS),
229
+ scopeItems, totalScopeItems: allScopeItems.length, omittedScopeItems: Math.max(0, allScopeItems.length - scopeItems.length), scopeBoundary, rx: disposition ? 'split' : rx, ...(disposition ? { dispositionEvidence: disposition.dispositionEvidence } : {}),
230
+ ...(status === 'unmeasured' ? { reason: '저장되고 reviewed=true인 리뷰 결과가 없어 라운드를 측정할 수 없습니다' } : {}),
231
+ ...(status === 'stale' ? { reason: '저장 리뷰에 현재 PR head가 없어 현재 라운드의 must-fix를 측정할 수 없습니다' } : {}),
232
+ ...(status === 'unavailable' ? { reason: '리뷰 결과 파일을 모두 읽지 못해 라운드 판정을 사용할 수 없습니다', readErrors: input.readErrors } : {}),
233
+ };
234
+ }
235
+
236
+ export function loadReviewRoundBrief(input: { pr: number; head: string; body: string; changedFiles: string[]; comments?: string[]; reviewResultsDir?: string }): ReviewRoundBrief {
237
+ const dir = input.reviewResultsDir ?? join(effectiveInstanceRoot(), 'review-results');
238
+ const parsed = parseReviewResultFiles(dir, input.pr);
239
+ return buildReviewRoundBrief({ ...input, results: parsed.results, readErrors: parsed.errors });
240
+ }
241
+
242
+ export function reviewBriefEvidence(brief: ReviewRoundBrief, runId?: string): Record<string, unknown> {
243
+ const intentBlock = renderReviewBriefIntentBlock(brief);
244
+ return {
245
+ pr: brief.pr, head: brief.head, round: brief.rounds, rounds: brief.rounds, source: brief.source,
246
+ verdict: brief.currentHeadMeasured ? brief.reviewedVerdict : 'unknown',
247
+ ...(brief.reviewedHead ? { reviewedHead: brief.reviewedHead } : {}),
248
+ key: `${brief.pr}:${brief.head}:${brief.rounds}`, rx: brief.rx,
249
+ coreItems: brief.totalCoreItems, scopeItems: brief.totalScopeItems,
250
+ ...(intentBlock ? { intentBlock } : {}),
251
+ status: brief.status, ...(brief.dispositionEvidence ? { dispositionEvidence: brief.dispositionEvidence } : {}),
252
+ ...(brief.reason ? { reason: brief.reason } : {}), ...(runId ? { runId } : {}),
253
+ };
254
+ }
255
+
256
+ /** Shadow addendum for a future R3 self-review; this function does not alter the live review path. */
257
+ export function renderReviewBriefIntentBlock(brief: ReviewRoundBrief): string | null {
258
+ if (brief.status === 'unavailable' || brief.source !== 'saved-review' || brief.rounds < 2 || !brief.reviewedHead) return null;
259
+ const shorten = (text: string) => text.length > MAX_INTENT_ITEM_CHARS ? `${text.slice(0, MAX_INTENT_ITEM_CHARS - 1)}…` : text;
260
+ const paths = brief.resultPaths.slice(0, MAX_INTENT_SOURCE_PATHS).map(shorten);
261
+ const essential = [
262
+ `런 닥터 brief · PR #${brief.pr} · ${brief.currentHeadMeasured ? 'current' : 'prior'} head ${brief.reviewedHead.slice(0, 12)} · current PR head ${brief.head.slice(0, 12)} · rounds=${brief.rounds} · verdict=${brief.reviewedVerdict} · rx=${brief.rx}`,
263
+ ...(brief.goalQuestion ? [`원래 질문: ${shorten(brief.goalQuestion)}`] : []),
264
+ ...(brief.acceptanceSignal.length ? [
265
+ '원래 수용 신호:',
266
+ ...brief.acceptanceSignal.slice(0, MAX_INTENT_ACCEPTANCE_ITEMS).map((item) => `- ${shorten(item)}`),
267
+ ...(brief.acceptanceSignal.length > MAX_INTENT_ACCEPTANCE_ITEMS ? [`수용 신호 ${brief.acceptanceSignal.length - MAX_INTENT_ACCEPTANCE_ITEMS}개 생략`] : []),
268
+ ] : []),
269
+ ...(brief.declaredScopeBoundary.length ? [
270
+ '명시적 범위 경계:',
271
+ ...brief.declaredScopeBoundary.slice(0, MAX_INTENT_ACCEPTANCE_ITEMS).map((item) => `- ${shorten(item)}`),
272
+ ...(brief.declaredScopeBoundary.length > MAX_INTENT_ACCEPTANCE_ITEMS ? [`범위 경계 ${brief.declaredScopeBoundary.length - MAX_INTENT_ACCEPTANCE_ITEMS}개 생략`] : []),
273
+ ] : []),
274
+ '저장된 must-fix (FU 분류도 삭제하지 않음):', ...(brief.coreItems.length ? brief.coreItems.map((item) => `- [${item.kind} · ${item.id}] ${shorten(item.text)}`) : [brief.currentHeadMeasured ? '- 현재 head의 must-fix 없음' : `- 현재 PR head 미측정 · 선택한 reviewed head ${brief.reviewedHead?.slice(0, 12) ?? 'unknown'}의 finding은 아래에 표시`]),
275
+ ...(brief.omittedCoreItems ? [`${brief.omittedCoreItems}개 생략: 핵심 must-fix`] : []),
276
+ ...(!brief.currentHeadMeasured && brief.totalPriorFindings > 0 ? [`실제 처방: 현재 head 리뷰 전까지 과거 미해결 must-fix를 유지하고 계속 진행 (${brief.rx})`] : []),
277
+ `의도적 스코프 경계: ${brief.scopeBoundary}`,
278
+ ];
279
+ const optional = [
280
+ `과거 라운드 검토 항목 (${brief.priorFindings.length}/${brief.totalPriorFindings}, head별 저장 결과):`, ...(brief.priorFindings.length ? brief.priorFindings.map((item) => `- [${item.kind} · ${item.id}] ${shorten(item.text)}`) : ['- 저장된 must-fix 없음']),
281
+ ...(brief.omittedPriorFindings ? [`과거 finding ${brief.omittedPriorFindings}개 생략`] : []),
282
+ `FU 후보 (${brief.scopeItems.length}/${brief.totalScopeItems}):`, ...(brief.scopeItems.length ? brief.scopeItems.map((item) => `- [${item.kind} · ${item.id}] ${shorten(item.text)}`) : ['- 현재 head에서 분류된 FU 후보 없음']),
283
+ ...(brief.omittedCoreItems ? [`핵심 항목 ${brief.omittedCoreItems}개 추가 생략`] : []),
284
+ ...(brief.omittedScopeItems ? [`FU 후보 ${brief.omittedScopeItems}개 생략`] : []),
285
+ ...(brief.resultPaths.length ? [`리뷰 원문 파일 (${paths.length}/${brief.resultPaths.length}): ${paths.join(', ')}`,
286
+ ...(brief.resultPaths.length > MAX_INTENT_SOURCE_PATHS ? [`원문 파일 ${brief.resultPaths.length - MAX_INTENT_SOURCE_PATHS}개 생략`] : [])] : []),
287
+ ];
288
+ const lines = [...essential];
289
+ const sourceReference = brief.resultPaths.length
290
+ ? `참고 원문 (${paths.length}/${brief.resultPaths.length}): ${paths.join(', ')}${brief.resultPaths.length > MAX_INTENT_SOURCE_PATHS ? ` · ${brief.resultPaths.length - MAX_INTENT_SOURCE_PATHS}개 생략` : ''}`
291
+ : '';
292
+ let omitted = 0;
293
+ for (const line of optional) {
294
+ if (lines.join('\n').length + line.length + 1 + sourceReference.length + 101 <= REVIEW_BRIEF_INTENT_MAX_CHARS) lines.push(line);
295
+ else omitted++;
296
+ }
297
+ if (omitted) lines.push(`보조 내용 ${omitted}줄 생략`);
298
+ if (sourceReference) lines.push(sourceReference);
299
+ return lines.join('\n');
300
+ }
@@ -11,6 +11,20 @@ import { eligibleRefutationGoalLines, MUST_FIX_REFUTATION_ACKNOWLEDGEMENT, REFUT
11
11
  import { SUPERVISION_REWORK_SOURCES, type SupervisionReworkSource } from './supervision-vocabulary.js';
12
12
  import { lookupLlmTierSpec } from '../model-tier/index.js';
13
13
 
14
+ export type ReviewRoundDecision = 'pass' | 'rework' | 'follow-up';
15
+
16
+ /** Classifies an actual review result against the current retry budget.
17
+ * A supervisor may extend that budget before the follow-up is finalized. */
18
+ export function decideReviewRound(input: {
19
+ verdict: 'pass' | 'warn' | 'fail';
20
+ mustFix: readonly string[];
21
+ round: number;
22
+ effectiveMax: number;
23
+ }): ReviewRoundDecision {
24
+ if (input.verdict !== 'fail' || input.mustFix.length === 0) return 'pass';
25
+ return input.round < input.effectiveMax ? 'rework' : 'follow-up';
26
+ }
27
+
14
28
  export type ReviewFindingRepeatSignal = 'repeat' | 'no-repeat' | 'unmeasurable' | 'insufficient-history';
15
29
  export type AdaptiveReworkReason = 'insufficient-fail-history' | 'zero-failures' | 'fail-count-not-decreased' | 'repeat-blocked-extension' | 'extended-by-fail-count' | 'hard-cap';
16
30
 
@@ -834,6 +834,8 @@ export interface RunLedgerTimelineEntry {
834
834
  shardId?: string;
835
835
  pieceIndex?: number;
836
836
  pieceTotal?: number;
837
+ /** Producer-recorded `graph.unit` visits of this run, with terminal unmatched enters reported as orphans. */
838
+ unitVisits?: GraphUnitVisitClassification;
837
839
  }
838
840
 
839
841
  export interface RunLedgerTimelineQueryOptions {
@@ -875,6 +877,7 @@ export function queryRunLedgerTimeline(missionId: string, options: RunLedgerTime
875
877
  ...(execution.shardId === undefined ? {} : { shardId: execution.shardId }),
876
878
  ...(execution.pieceIndex === undefined ? {} : { pieceIndex: execution.pieceIndex }),
877
879
  ...(execution.pieceTotal === undefined ? {} : { pieceTotal: execution.pieceTotal }),
880
+ unitVisits: classifyGraphUnitVisits(ledger),
878
881
  });
879
882
  } catch {
880
883
  // A corrupt or concurrently replaced ledger must not leak a partial run into another mission timeline.
@@ -883,6 +886,75 @@ export function queryRunLedgerTimeline(missionId: string, options: RunLedgerTime
883
886
  return entries.sort((left, right) => Date.parse(left.executedAt) - Date.parse(right.executedAt) || left.runId.localeCompare(right.runId));
884
887
  }
885
888
 
889
+ export interface GraphAdaptReport {
890
+ goalId: string;
891
+ runCount: number;
892
+ uniquePathSignatures: number;
893
+ unitCallCount: number;
894
+ adaptationCount: number;
895
+ adapted: { landed: number; denominator: number; rate: number | null };
896
+ nonAdapted: { landed: number; denominator: number; rate: number | null };
897
+ excludedCount: number;
898
+ exclusionReasons: Record<string, number>;
899
+ }
900
+
901
+ /** Measure only producer-observed traversals and variant applications; never activate adaptation. */
902
+ export function queryGraphAdaptReport(goalId: string, stateDir = elanousStateRoot()): GraphAdaptReport {
903
+ const dir = runLedgerDir(stateDir);
904
+ const signatures = new Set<string>();
905
+ const counts = { adapted: { landed: 0, denominator: 0 }, nonAdapted: { landed: 0, denominator: 0 } };
906
+ const exclusionReasons: Record<string, number> = {};
907
+ const exclude = (reason: string): void => { exclusionReasons[reason] = (exclusionReasons[reason] ?? 0) + 1; };
908
+ let unitCallCount = 0;
909
+ let adaptationCount = 0;
910
+ let fileNames: string[];
911
+ try { fileNames = readdirSync(dir); }
912
+ catch (error) {
913
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') fileNames = [];
914
+ else throw error;
915
+ }
916
+ for (const name of fileNames) {
917
+ const runId = runIdFromCanonicalLedgerFile(name);
918
+ if (!runId) continue;
919
+ let ledger: RunLedgerEntry[] | null;
920
+ try { ledger = loadRunLedger(runId, dir); }
921
+ catch { exclude('invalid-ledger'); continue; }
922
+ if (!ledger?.length) { exclude('empty-ledger'); continue; }
923
+ const goalIds = new Set(ledger.map(entry => entry.goalId).filter((id): id is string => typeof id === 'string' && id.length > 0));
924
+ if (goalIds.size === 1 && !goalIds.has(goalId)) continue;
925
+ if (goalIds.size !== 1) { exclude('goal-id-missing-or-conflicting'); continue; }
926
+ const traversals = ledger.filter(entry => entry.event === 'pipeline-traversal-shadow');
927
+ const paths = traversals.map(entry => entry.data.observedNodes);
928
+ if (paths.length === 0 || paths.some(path => !Array.isArray(path) || path.length === 0 || !path.every(node => typeof node === 'string' && node.length > 0))) {
929
+ exclude('path-missing-or-invalid'); continue;
930
+ }
931
+ let graphRun: unknown;
932
+ try { graphRun = JSON.parse(readFileSync(join(stateDir, 'graph-runs', 'self-implement', `${runId}.json`), 'utf8')); }
933
+ catch (error) {
934
+ if ((error as NodeJS.ErrnoException).code !== 'ENOENT') { exclude('graph-run-unreadable'); continue; }
935
+ }
936
+ const recorded = graphRun && typeof graphRun === 'object' && !Array.isArray(graphRun) ? graphRun as Record<string, unknown> : null;
937
+ if (recorded && (recorded.runId !== runId || recorded.graphId !== 'self-implement' ||
938
+ (recorded.unitCalls !== undefined && !Array.isArray(recorded.unitCalls)))) {
939
+ exclude('unit-calls-invalid'); continue;
940
+ }
941
+ const merge = [...ledger].reverse().find(entry => entry.event === 'merged');
942
+ if (merge && typeof merge.data.merged !== 'boolean') { exclude('landing-invalid'); continue; }
943
+ signatures.add(JSON.stringify(paths.at(-1)));
944
+ unitCallCount += recorded && Array.isArray(recorded.unitCalls) ? recorded.unitCalls.length : 0;
945
+ const adaptations = ledger.filter(entry => entry.event === 'graph-variant-applied');
946
+ adaptationCount += adaptations.length;
947
+ const group = adaptations.length ? counts.adapted : counts.nonAdapted;
948
+ group.denominator += 1;
949
+ if (merge?.data.merged === true) group.landed += 1;
950
+ }
951
+ const rate = (group: { landed: number; denominator: number }) => ({ ...group, rate: group.denominator ? group.landed / group.denominator : null });
952
+ return { goalId, runCount: counts.adapted.denominator + counts.nonAdapted.denominator,
953
+ uniquePathSignatures: signatures.size, unitCallCount, adaptationCount,
954
+ adapted: rate(counts.adapted), nonAdapted: rate(counts.nonAdapted),
955
+ excludedCount: Object.values(exclusionReasons).reduce((total, count) => total + count, 0), exclusionReasons };
956
+ }
957
+
886
958
  export interface GoalSourceDistributionQuery {
887
959
  ledgerDirectory: string;
888
960
  runCount: number;
@@ -1416,6 +1488,8 @@ export interface UnfinishedRunLedgerEntry {
1416
1488
  lifecycle: UnfinishedRunLifecycle;
1417
1489
  /** Non-blocking request record (kind·reason·next) carried by this runId's ledger; absent for runs without one. */
1418
1490
  nonBlocking?: NonBlockingRunLedgerRecord;
1491
+ /** ⭐ graph.unit enter without its exit on a *terminal* ledger — present only when non-empty. */
1492
+ orphanUnitVisits?: readonly GraphUnitOrphanVisit[];
1419
1493
  }
1420
1494
 
1421
1495
  export interface UnfinishedRunLedgerQuery {
@@ -1435,6 +1509,12 @@ export interface UnfinishedRunLedgerQuery {
1435
1509
  pathFilter?: string;
1436
1510
  matchingPathCount?: number;
1437
1511
  unknownPathCount?: number;
1512
+ /**
1513
+ * ⭐ Total orphan unit visits across **every scanned ledger** — including terminal runs that are not
1514
+ * returned as entries (they are counted, never revived). 같은 원장을 「미완」으로 되살리지 않고도
1515
+ * 엉킨 visit 을 셀 수 있게 하는 값이다.
1516
+ */
1517
+ orphanUnitVisitCount?: number;
1438
1518
  scope: 'self-implement-run-ledger';
1439
1519
  note: string;
1440
1520
  }
@@ -1546,6 +1626,78 @@ function isTerminalOnlyByTrailingRunStatus(ledger: readonly RunLedgerEntry[]): b
1546
1626
  && !hasHumanStopEvent(ledger);
1547
1627
  }
1548
1628
 
1629
+ /** One producer-recorded `graph.unit` enter that the run never closed with a matching exit. */
1630
+ export interface GraphUnitOrphanVisit {
1631
+ childRunId: string | null;
1632
+ graphId: string | null;
1633
+ nodeId: string | null;
1634
+ unit: string | null;
1635
+ /** Timestamp of the unmatched enter; null when the producer recorded none. */
1636
+ enteredAt: string | null;
1637
+ }
1638
+
1639
+ export interface GraphUnitVisitClassification {
1640
+ /** Whether the ledger itself records the run's end (`run-status`, `terminal`, or `human-stop`). */
1641
+ terminal: boolean;
1642
+ enterCount: number;
1643
+ exitCount: number;
1644
+ /** Unmatched enters in a terminal run. An open enter on a non-terminal ledger is in flight, not an orphan. */
1645
+ orphanCount: number;
1646
+ orphanUnitVisits: readonly GraphUnitOrphanVisit[];
1647
+ }
1648
+
1649
+ function dataString(data: Record<string, unknown>, field: string): string | null {
1650
+ const value = data[field];
1651
+ return typeof value === 'string' && value.length > 0 ? value : null;
1652
+ }
1653
+
1654
+ function graphUnitVisitOf(entry: RunLedgerEntry): GraphUnitOrphanVisit {
1655
+ return {
1656
+ childRunId: dataString(entry.data, 'childRunId'),
1657
+ graphId: dataString(entry.data, 'graphId'),
1658
+ nodeId: dataString(entry.data, 'nodeId'),
1659
+ unit: dataString(entry.data, 'unit'),
1660
+ enteredAt: entry.timestamp ?? null,
1661
+ };
1662
+ }
1663
+
1664
+ /** An exit closes the visit with its own childRunId; without one it closes the latest visit on the same node. */
1665
+ function closesUnitVisit(exitChildRunId: string | null, exitNodeId: string | null, open: GraphUnitOrphanVisit): boolean {
1666
+ if (open.childRunId !== null || exitChildRunId !== null) return open.childRunId === exitChildRunId;
1667
+ return open.nodeId !== null && open.nodeId === exitNodeId;
1668
+ }
1669
+
1670
+ /**
1671
+ * Pair each producer-recorded `graph.unit` enter with its exit and report the visits a terminal run left open.
1672
+ * This only reads the already-loaded ledger: it never synthesizes or writes an exit entry.
1673
+ */
1674
+ export function classifyGraphUnitVisits(ledger: readonly RunLedgerEntry[]): GraphUnitVisitClassification {
1675
+ const open: GraphUnitOrphanVisit[] = [];
1676
+ let enterCount = 0;
1677
+ let exitCount = 0;
1678
+ for (const entry of ledger) {
1679
+ if (entry.event !== 'graph.unit') continue;
1680
+ if (entry.data.phase === 'enter') {
1681
+ enterCount += 1;
1682
+ open.push(graphUnitVisitOf(entry));
1683
+ continue;
1684
+ }
1685
+ // `budget-exhausted` is a recorded failure the runner still follows with an exit, so it closes nothing.
1686
+ if (entry.data.phase !== 'exit') continue;
1687
+ exitCount += 1;
1688
+ const exitChildRunId = dataString(entry.data, 'childRunId');
1689
+ const exitNodeId = dataString(entry.data, 'nodeId');
1690
+ for (let index = open.length - 1; index >= 0; index -= 1) {
1691
+ if (!closesUnitVisit(exitChildRunId, exitNodeId, open[index]!)) continue;
1692
+ open.splice(index, 1);
1693
+ break;
1694
+ }
1695
+ }
1696
+ const terminal = hasTerminalRunStatus(ledger);
1697
+ const orphanUnitVisits = terminal ? open : [];
1698
+ return { terminal, enterCount, exitCount, orphanCount: orphanUnitVisits.length, orphanUnitVisits };
1699
+ }
1700
+
1549
1701
  /** ⛔⭐⭐⭐ 미완 항목의 «상태» — 종전엔 이 조회가 낸 것이 «한 값»(`terminal-status-missing`)뿐이었다.
1550
1702
  * 📏 2026-08-11 실측: 그 한 값 안에 서로 «다른 것»이 섞여 있었다 —
1551
1703
  * 실제로 도는 것 2 · 오래 전에 죽은 잔해 51(중앙 5.2일) · 종료를 «다른 이름»으로 적은 것 5.
@@ -1773,6 +1925,8 @@ interface UnfinishedLedgerFacts {
1773
1925
  goalFile: string | null;
1774
1926
  fixedLifecycle: UnfinishedRunLifecycle;
1775
1927
  nonBlocking: NonBlockingRunLedgerRecord | null;
1928
+ /** Held here so a terminal ledger's orphan visits are countable before the terminal `continue`. */
1929
+ unitVisits: GraphUnitVisitClassification;
1776
1930
  }
1777
1931
 
1778
1932
  // A full federated scan can exceed 5,000 files; keep the previous scan resident for stat-checked reuse.
@@ -1797,7 +1951,8 @@ function unfinishedLedgerCacheKey(path: string, read?: RunLedgerReader): string
1797
1951
  // 원장 옆에 (size, mtimeMs, ctimeMs) 스탬프로 저장하고, 스탬프가 같으면 재사용한다. 원장에 무엇이 «붙으면»
1798
1952
  // 스탬프가 바뀌므로 무효화는 자동이다 (같은 크기로 덮고 mtime 을 되돌려도 ctime 이 바뀐다). 읽기 실패는 전부 fail-soft: 색인이 없으면 그냥 새로 읽는다.
1799
1953
  const RUN_LEDGER_SCAN_INDEX_FILE = '.unfinished-scan-index.json';
1800
- const RUN_LEDGER_SCAN_INDEX_VERSION = 2;
1954
+ // v3 added facts.unitVisits; a v2 record would hand back a facts object without it.
1955
+ const RUN_LEDGER_SCAN_INDEX_VERSION = 3;
1801
1956
  const RUN_LEDGER_SCAN_INDEX_LIMIT = 32_768;
1802
1957
 
1803
1958
  /** Where the persisted scan index lives: beside its ledgers, never mistaken for one (readdir filters canonical names). */
@@ -1829,7 +1984,9 @@ function isScanIndexFacts(value: unknown): value is UnfinishedLedgerFacts {
1829
1984
  && typeof facts.lastActivityStatus === 'string'
1830
1985
  && (facts.targetRoot === null || typeof facts.targetRoot === 'string')
1831
1986
  && (facts.goalFile === null || typeof facts.goalFile === 'string')
1832
- && typeof facts.fixedLifecycle === 'string' && UNFINISHED_LIFECYCLE_WORDS.has(facts.fixedLifecycle);
1987
+ && typeof facts.fixedLifecycle === 'string' && UNFINISHED_LIFECYCLE_WORDS.has(facts.fixedLifecycle)
1988
+ && typeof (facts.unitVisits as GraphUnitVisitClassification | undefined)?.orphanCount === 'number'
1989
+ && Array.isArray((facts.unitVisits as GraphUnitVisitClassification | undefined)?.orphanUnitVisits);
1833
1990
  }
1834
1991
 
1835
1992
  function isScanIndexRecord(value: unknown): value is RunLedgerScanIndexRecord {
@@ -1895,6 +2052,7 @@ function unfinishedLedgerFacts(ledger: readonly RunLedgerEntry[]): UnfinishedLed
1895
2052
  goalFile: ledgerGoalDocument(ledger),
1896
2053
  fixedLifecycle: classifyUnfinishedLifecycle(ledger, null, 0),
1897
2054
  nonBlocking: readNonBlockingRunRecord(ledger),
2055
+ unitVisits: classifyGraphUnitVisits(ledger),
1898
2056
  };
1899
2057
  }
1900
2058
 
@@ -2014,6 +2172,8 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
2014
2172
  let cacheMisses = 0;
2015
2173
  let ledgerTargetCount = 0;
2016
2174
  let callerCwdCount = 0;
2175
+ // ⭐ 터미널 원장도 «세기만» 한다 — entries 로 되살리지 않는다(부활 금지).
2176
+ let orphanUnitVisitCount = 0;
2017
2177
  for (const fileName of fileNames) {
2018
2178
  const runId = runIdFromCanonicalLedgerFile(fileName);
2019
2179
  if (!runId) continue;
@@ -2037,6 +2197,9 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
2037
2197
  callerCwdCount += 1;
2038
2198
  continue;
2039
2199
  }
2200
+ const orphanUnitVisits = facts.unitVisits.orphanUnitVisits;
2201
+ orphanUnitVisitCount += facts.unitVisits.orphanCount;
2202
+ const orphanVisitField = orphanUnitVisits.length > 0 ? { orphanUnitVisits } : {};
2040
2203
  if (facts.terminal) {
2041
2204
  terminal += 1;
2042
2205
  if (facts.terminalByTrailingRunStatus) terminalByTrailingRunStatus += 1;
@@ -2070,7 +2233,7 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
2070
2233
  : goalDocument.status === 'directory-unreadable'
2071
2234
  ? 'goal-directory-unreadable'
2072
2235
  : 'goal-document-not-found';
2073
- entries.push({ runId, branch, status: 'terminal-status-missing', plannedPaths: [], plannedPathStatus, ...unknownDeclaredPaths(), pathMatchReasons: {}, goalDocumentPath: null, goalLookupBasis, goalDocumentSearchDirectory: searchDirectory, ...activity, lifecycle, ...(facts.nonBlocking ? { nonBlocking: facts.nonBlocking } : {}) });
2236
+ entries.push({ runId, branch, status: 'terminal-status-missing', plannedPaths: [], plannedPathStatus, ...unknownDeclaredPaths(), pathMatchReasons: {}, goalDocumentPath: null, goalLookupBasis, goalDocumentSearchDirectory: searchDirectory, ...activity, lifecycle, ...(facts.nonBlocking ? { nonBlocking: facts.nonBlocking } : {}), ...orphanVisitField });
2074
2237
  continue;
2075
2238
  }
2076
2239
  try {
@@ -2078,9 +2241,9 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
2078
2241
  const text = typeof document === 'string' ? document : document.toString('utf8');
2079
2242
  const paths = [...new Set(tracedPathReferences(text).map((reference) => reference.path))];
2080
2243
  const declared = declaredPathsFromGoalDocument(text);
2081
- entries.push({ runId, branch, status: 'terminal-status-missing', plannedPaths: paths, plannedPathStatus: paths.length > 0 ? goalDocument.source === 'ledger' ? 'found-ledger-goal-file' : 'found-branch-fallback' : 'no-traced-paths', ...declared, pathMatchReasons: pathMatchReasons(declared.declaredPaths, paths), goalDocumentPath: goalDocument.path, goalLookupBasis, goalDocumentSearchDirectory: searchDirectory, ...activity, lifecycle, ...(facts.nonBlocking ? { nonBlocking: facts.nonBlocking } : {}) });
2244
+ entries.push({ runId, branch, status: 'terminal-status-missing', plannedPaths: paths, plannedPathStatus: paths.length > 0 ? goalDocument.source === 'ledger' ? 'found-ledger-goal-file' : 'found-branch-fallback' : 'no-traced-paths', ...declared, pathMatchReasons: pathMatchReasons(declared.declaredPaths, paths), goalDocumentPath: goalDocument.path, goalLookupBasis, goalDocumentSearchDirectory: searchDirectory, ...activity, lifecycle, ...(facts.nonBlocking ? { nonBlocking: facts.nonBlocking } : {}), ...orphanVisitField });
2082
2245
  } catch {
2083
- entries.push({ runId, branch, status: 'terminal-status-missing', plannedPaths: [], plannedPathStatus: 'goal-document-unreadable', declaredPaths: [], declaredPathStatus: 'goal-document-unreadable', pathMatchReasons: {}, goalDocumentPath: goalDocument.path, goalLookupBasis, goalDocumentSearchDirectory: searchDirectory, ...activity, lifecycle, ...(facts.nonBlocking ? { nonBlocking: facts.nonBlocking } : {}) });
2246
+ entries.push({ runId, branch, status: 'terminal-status-missing', plannedPaths: [], plannedPathStatus: 'goal-document-unreadable', declaredPaths: [], declaredPathStatus: 'goal-document-unreadable', pathMatchReasons: {}, goalDocumentPath: goalDocument.path, goalLookupBasis, goalDocumentSearchDirectory: searchDirectory, ...activity, lifecycle, ...(facts.nonBlocking ? { nonBlocking: facts.nonBlocking } : {}), ...orphanVisitField });
2084
2247
  }
2085
2248
  }
2086
2249
  entries.sort((left, right) => left.runId.localeCompare(right.runId));
@@ -2098,7 +2261,7 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
2098
2261
  ms: Date.now() - startedAt,
2099
2262
  });
2100
2263
  if (options.path === undefined) {
2101
- return { entries, ledgerDirectory: dir, goalsDirectory: goalsDir, unreadableLedgerCount, ledgerDirectoryMissing: false, terminalByTrailingRunStatus, cacheHits, cacheMisses, indexHits, indexOrigin, scope: 'self-implement-run-ledger', note: UNFINISHED_RUN_LEDGER_NOTE };
2264
+ return { entries, ledgerDirectory: dir, goalsDirectory: goalsDir, unreadableLedgerCount, orphanUnitVisitCount, ledgerDirectoryMissing: false, terminalByTrailingRunStatus, cacheHits, cacheMisses, indexHits, indexOrigin, scope: 'self-implement-run-ledger', note: UNFINISHED_RUN_LEDGER_NOTE };
2102
2265
  }
2103
2266
  const pathFilter = options.path;
2104
2267
  const unknownPathStatus = (entry: UnfinishedRunLedgerEntry): boolean => entry.plannedPathStatus !== 'found-ledger-goal-file'
@@ -2114,6 +2277,7 @@ export function queryUnfinishedRunLedgers(options: UnfinishedRunLedgerQueryOptio
2114
2277
  ledgerDirectory: dir,
2115
2278
  goalsDirectory: goalsDir,
2116
2279
  unreadableLedgerCount,
2280
+ orphanUnitVisitCount,
2117
2281
  ledgerDirectoryMissing: false,
2118
2282
  terminalByTrailingRunStatus,
2119
2283
  cacheHits,
@@ -15,7 +15,7 @@ import type { PodChildEvidence } from '../task-orchestrator/surfaces/self-implem
15
15
 
16
16
  /** 닫힌 목록 — 못 고르면 `unclassified`. */
17
17
  export const RUN_STOP_CLASSES = [
18
- 'env-unrelated', 'main-sync', 'pod-died', 'review-repeat',
18
+ 'env-unrelated', 'main-sync', 'pod-died', 'pod-vanished', 'review-repeat',
19
19
  'review-out-of-scope', 'scope-escape', 'evidence-uncovered', 'fabric', 'launch-failed', 'gate-failed', 'unclassified',
20
20
  ] as const;
21
21
  export type RunStopClass = typeof RUN_STOP_CLASSES[number];