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
@@ -1,4 +1,12 @@
1
1
  #!/usr/bin/env bun
2
+ /**
3
+ * GOAL-BENCH-FU — 열 과제×세 경로(문면·구체화·구현 결과) 결과표와 절차 삭제 후보.
4
+ *
5
+ * bun scripts/goals/authoring-metrics.ts --records <ledger.json|ledger.jsonl> [--json]
6
+ *
7
+ * 레코드 = { task, path, landed, rounds, procedureSteps }. `--records` 가 없으면 기존 측정 모드
8
+ * (경로 인자 · chars/bytes/sections/marker)가 그대로 돈다 — 표 형식·요약 JSON 불변.
9
+ */
2
10
  import { readFileSync } from 'node:fs';
3
11
  import { inspectAskMarkers } from '../ask-marker-check.js';
4
12
 
@@ -35,7 +43,257 @@ export function median(numbers: readonly number[]): number | null {
35
43
  : (sorted[middle - 1]! + sorted[middle]!) / 2;
36
44
  }
37
45
 
46
+ /** 골이 지나는 세 경로 — 문면(text) · 구체화(elaboration) · 구현 결과(implementation). */
47
+ export type AuthoringPath = 'text' | 'elaboration' | 'implementation';
48
+
49
+ const AUTHORING_PATHS: readonly AuthoringPath[] = ['text', 'elaboration', 'implementation'];
50
+
51
+ export interface AuthoringRecord {
52
+ readonly task: string;
53
+ readonly path: AuthoringPath;
54
+ /** 그 과제가 그 경로에서 착지했나. */
55
+ readonly landed: boolean;
56
+ /** 착지까지 든 라운드 수. */
57
+ readonly rounds: number;
58
+ /** 그 경로에서 실제로 밟은 절차 단계 — 삭제 후보 판정의 입력. */
59
+ readonly procedureSteps: readonly string[];
60
+ }
61
+
62
+ export interface PathCell {
63
+ readonly path: AuthoringPath;
64
+ readonly landed: number;
65
+ readonly total: number;
66
+ /** 착지율 0~1. 레코드가 없으면 null. */
67
+ readonly groundingRate: number | null;
68
+ /** 평균 라운드. 레코드가 없으면 null. */
69
+ readonly rounds: number | null;
70
+ }
71
+
72
+ export interface ResultRow {
73
+ readonly task: string;
74
+ /** buildResultTable 의 columns 와 같은 순서. 그 경로 레코드가 없으면 total 0 셀. */
75
+ readonly cells: readonly PathCell[];
76
+ }
77
+
78
+ export interface ResultTable {
79
+ readonly columns: readonly AuthoringPath[];
80
+ readonly rows: readonly ResultRow[];
81
+ readonly summary: readonly PathCell[];
82
+ }
83
+
84
+ export interface DeletionCandidate {
85
+ readonly step: string;
86
+ readonly withGroundingRate: number | null;
87
+ readonly withoutGroundingRate: number | null;
88
+ readonly withRounds: number | null;
89
+ readonly withoutRounds: number | null;
90
+ readonly withSamples: number;
91
+ readonly withoutSamples: number;
92
+ readonly reason: string;
93
+ }
94
+
95
+ export function computeGroundingRate(records: readonly AuthoringRecord[]): number | null {
96
+ if (records.length === 0) return null;
97
+ return records.filter((record) => record.landed).length / records.length;
98
+ }
99
+
100
+ function meanRounds(records: readonly AuthoringRecord[]): number | null {
101
+ if (records.length === 0) return null;
102
+ return records.reduce((sum, record) => sum + record.rounds, 0) / records.length;
103
+ }
104
+
105
+ function cellFor(path: AuthoringPath, records: readonly AuthoringRecord[]): PathCell {
106
+ return {
107
+ path,
108
+ landed: records.filter((record) => record.landed).length,
109
+ total: records.length,
110
+ groundingRate: computeGroundingRate(records),
111
+ rounds: meanRounds(records),
112
+ };
113
+ }
114
+
115
+ /** 행 = 과제, 열 = 경로, 셀 = 착지율·라운드. summary 는 경로별 전체 집계다. */
116
+ export function buildResultTable(records: readonly AuthoringRecord[]): ResultTable {
117
+ const columns = AUTHORING_PATHS.filter((path) => records.some((record) => record.path === path));
118
+ const tasks: string[] = [];
119
+ for (const record of records) if (!tasks.includes(record.task)) tasks.push(record.task);
120
+ return {
121
+ columns,
122
+ rows: tasks.map((task) => ({
123
+ task,
124
+ cells: columns.map((path) =>
125
+ cellFor(path, records.filter((record) => record.task === task && record.path === path))),
126
+ })),
127
+ summary: columns.map((path) => cellFor(path, records.filter((record) => record.path === path))),
128
+ };
129
+ }
130
+
131
+ /**
132
+ * 그 단계를 밟은 레코드가 «안 밟은 레코드보다» 착지율이 높지도 않고 라운드도 줄이지 못하면 삭제 후보다.
133
+ * 대조군이 없는 단계(모든 레코드가 밟음)는 판정할 근거가 없으므로 후보로 올리지 않는다.
134
+ */
135
+ export function findDeletionCandidates(records: readonly AuthoringRecord[]): readonly DeletionCandidate[] {
136
+ const steps = [...new Set(records.flatMap((record) => record.procedureSteps))].sort();
137
+ const candidates: DeletionCandidate[] = [];
138
+ for (const step of steps) {
139
+ const withStep = records.filter((record) => record.procedureSteps.includes(step));
140
+ const withoutStep = records.filter((record) => !record.procedureSteps.includes(step));
141
+ if (withStep.length === 0 || withoutStep.length === 0) continue;
142
+ const withGroundingRate = computeGroundingRate(withStep);
143
+ const withoutGroundingRate = computeGroundingRate(withoutStep);
144
+ const withRounds = meanRounds(withStep);
145
+ const withoutRounds = meanRounds(withoutStep);
146
+ if (withGroundingRate === null || withoutGroundingRate === null) continue;
147
+ if (withRounds === null || withoutRounds === null) continue;
148
+ if (withGroundingRate > withoutGroundingRate) continue;
149
+ if (withRounds < withoutRounds) continue;
150
+ candidates.push({
151
+ step,
152
+ withGroundingRate,
153
+ withoutGroundingRate,
154
+ withRounds,
155
+ withoutRounds,
156
+ withSamples: withStep.length,
157
+ withoutSamples: withoutStep.length,
158
+ reason: `착지율 ${formatPercent(withGroundingRate)} ≤ ${formatPercent(withoutGroundingRate)}`
159
+ + ` · 라운드 ${withRounds.toFixed(1)} ≥ ${withoutRounds.toFixed(1)}`,
160
+ });
161
+ }
162
+ return candidates.sort((a, b) =>
163
+ (b.withRounds! - b.withoutRounds!) - (a.withRounds! - a.withoutRounds!)
164
+ || (a.withGroundingRate! - b.withGroundingRate!)
165
+ || a.step.localeCompare(b.step));
166
+ }
167
+
168
+ function formatPercent(rate: number | null): string {
169
+ return rate === null ? '—' : `${(rate * 100).toFixed(1)}%`;
170
+ }
171
+
172
+ function formatRounds(rounds: number | null): string {
173
+ return rounds === null ? '—' : rounds.toFixed(1);
174
+ }
175
+
176
+ function formatCell(cell: PathCell): string {
177
+ if (cell.total === 0) return '—';
178
+ return `${formatPercent(cell.groundingRate)}/${formatRounds(cell.rounds)}`;
179
+ }
180
+
181
+ export function renderResultTable(table: ResultTable): string {
182
+ const lines = [`task\t${table.columns.join('\t')}`];
183
+ for (const row of table.rows) lines.push(`${row.task}\t${row.cells.map(formatCell).join('\t')}`);
184
+ lines.push(`summary\t${table.summary.map(formatCell).join('\t')}`);
185
+ return lines.join('\n');
186
+ }
187
+
188
+ export function renderDeletionCandidates(candidates: readonly DeletionCandidate[]): string {
189
+ if (candidates.length === 0) return 'candidates\tnone';
190
+ const lines = ['step\twith.landing\twithout.landing\twith.rounds\twithout.rounds\tsamples'];
191
+ for (const candidate of candidates) {
192
+ lines.push([
193
+ candidate.step,
194
+ formatPercent(candidate.withGroundingRate),
195
+ formatPercent(candidate.withoutGroundingRate),
196
+ formatRounds(candidate.withRounds),
197
+ formatRounds(candidate.withoutRounds),
198
+ `${candidate.withSamples}/${candidate.withoutSamples}`,
199
+ ].join('\t'));
200
+ }
201
+ return lines.join('\n');
202
+ }
203
+
204
+ export type ParsedRecords =
205
+ | { readonly ok: true; readonly records: readonly AuthoringRecord[] }
206
+ | { readonly ok: false; readonly error: string };
207
+
208
+ function parseRecord(entry: unknown): AuthoringRecord | string {
209
+ if (typeof entry !== 'object' || entry === null) return 'is not an object';
210
+ const value = entry as Record<string, unknown>;
211
+ if (typeof value.task !== 'string' || value.task.trim() === '') return 'task must be a non-empty string';
212
+ if (!AUTHORING_PATHS.includes(value.path as AuthoringPath)) {
213
+ return `path must be one of ${AUTHORING_PATHS.join('|')}`;
214
+ }
215
+ if (typeof value.landed !== 'boolean') return 'landed must be a boolean';
216
+ if (typeof value.rounds !== 'number' || !Number.isFinite(value.rounds) || value.rounds < 0) {
217
+ return 'rounds must be a finite number >= 0';
218
+ }
219
+ const steps = value.procedureSteps;
220
+ if (steps !== undefined && (!Array.isArray(steps)
221
+ || steps.some((step) => typeof step !== 'string' || step.trim() === ''))) {
222
+ return 'procedureSteps must be an array of non-empty strings';
223
+ }
224
+ return {
225
+ task: value.task,
226
+ path: value.path as AuthoringPath,
227
+ landed: value.landed,
228
+ rounds: value.rounds,
229
+ procedureSteps: (steps ?? []) as readonly string[],
230
+ };
231
+ }
232
+
233
+ /** JSON 배열 한 덩어리 또는 JSON Lines(원장 한 줄 = 레코드 하나) 둘 다 받는다. */
234
+ export function parseRecords(text: string): ParsedRecords {
235
+ const trimmed = text.trim();
236
+ if (trimmed === '') return { ok: true, records: [] };
237
+ const entries: unknown[] = [];
238
+ if (trimmed.startsWith('[')) {
239
+ let parsed: unknown;
240
+ try {
241
+ parsed = JSON.parse(trimmed);
242
+ } catch {
243
+ return { ok: false, error: 'records ledger is not valid JSON' };
244
+ }
245
+ if (!Array.isArray(parsed)) return { ok: false, error: 'records must be a JSON array or JSON Lines' };
246
+ entries.push(...parsed);
247
+ } else {
248
+ for (const [index, line] of trimmed.split(/\r?\n/).entries()) {
249
+ if (line.trim() === '') continue;
250
+ try {
251
+ entries.push(JSON.parse(line) as unknown);
252
+ } catch {
253
+ return { ok: false, error: `line ${index + 1} is not valid JSON` };
254
+ }
255
+ }
256
+ }
257
+ const records: AuthoringRecord[] = [];
258
+ for (const [index, entry] of entries.entries()) {
259
+ const parsed = parseRecord(entry);
260
+ if (typeof parsed === 'string') return { ok: false, error: `record ${index + 1}: ${parsed}` };
261
+ records.push(parsed);
262
+ }
263
+ return { ok: true, records };
264
+ }
265
+
266
+ function printRecordsLedger(argv: readonly string[]): number {
267
+ const file = argv[argv.indexOf('--records') + 1];
268
+ if (file === undefined || file.startsWith('--')) {
269
+ console.error('authoring-metrics: --records needs a ledger path');
270
+ return 2;
271
+ }
272
+ let text: string;
273
+ try {
274
+ text = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(readFileSync(file));
275
+ } catch {
276
+ console.error(`authoring-metrics: unreadable records ledger: ${file}`);
277
+ return 1;
278
+ }
279
+ const parsed = parseRecords(text);
280
+ if (!parsed.ok) {
281
+ console.error(`authoring-metrics: ${parsed.error}`);
282
+ return 1;
283
+ }
284
+ const table = buildResultTable(parsed.records);
285
+ const candidates = findDeletionCandidates(parsed.records);
286
+ if (argv.includes('--json')) {
287
+ console.log(JSON.stringify({ columns: table.columns, rows: table.rows, summary: table.summary, candidates }));
288
+ } else {
289
+ console.log(renderResultTable(table));
290
+ console.log(renderDeletionCandidates(candidates));
291
+ }
292
+ return 0;
293
+ }
294
+
38
295
  function main(argv: readonly string[]): number {
296
+ if (argv.includes('--records')) return printRecordsLedger(argv);
39
297
  const json = argv.includes('--json');
40
298
  const paths = argv.filter((argument) => argument !== '--json');
41
299
  const decoder = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });
@@ -0,0 +1,222 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { PROTECTED_LABELS, decideDraft, type DraftTriagePr } from '../../src/self-dev/draft-triage-rules.js';
3
+
4
+ type Json = Record<string, unknown>;
5
+ type DraftCloseKind = 'harvest' | 'close-candidate' | 'hold';
6
+ type DraftCloseOutcome = DraftCloseKind | 'failed';
7
+ const DRAFT_CLOSE_PROTECTED_LABELS = new Set([...PROTECTED_LABELS, 'elanous:running', 'elanous:claim', 'elanous:harvest-claimed']);
8
+
9
+ interface DraftCloseRow extends Json {
10
+ mapRunId: string | null;
11
+ snapshotTime: string | null;
12
+ inventoryComplete: boolean;
13
+ pr: number | null;
14
+ headOid: string | null;
15
+ kind: DraftCloseKind;
16
+ classification: string;
17
+ reason: string;
18
+ replacement: number | null;
19
+ protectedReason: string | null;
20
+ evidence: string[];
21
+ writes: readonly [];
22
+ }
23
+
24
+ interface DraftCloseDecision {
25
+ outcome: DraftCloseOutcome;
26
+ result: DraftCloseRow;
27
+ evidence: Json;
28
+ }
29
+
30
+ function record(value: unknown): Json {
31
+ return value && typeof value === 'object' && !Array.isArray(value) ? value as Json : {};
32
+ }
33
+
34
+ function string(value: unknown): string | undefined {
35
+ return typeof value === 'string' && value.trim() ? value.trim() : undefined;
36
+ }
37
+
38
+ function strings(value: unknown): string[] | undefined {
39
+ return Array.isArray(value) && value.every((item) => typeof item === 'string') ? value as string[] : undefined;
40
+ }
41
+
42
+ function row(input: {
43
+ mapRunId?: string;
44
+ snapshotTime?: string;
45
+ inventoryComplete: boolean;
46
+ pr?: number;
47
+ headOid?: string;
48
+ kind: DraftCloseKind;
49
+ classification: string;
50
+ reason: string;
51
+ replacement?: number;
52
+ protectedReason?: string;
53
+ evidence: string[];
54
+ extra?: Json;
55
+ }): DraftCloseRow {
56
+ return {
57
+ mapRunId: input.mapRunId ?? null,
58
+ snapshotTime: input.snapshotTime ?? null,
59
+ inventoryComplete: input.inventoryComplete,
60
+ pr: input.pr ?? null,
61
+ headOid: input.headOid ?? null,
62
+ kind: input.kind,
63
+ classification: input.classification,
64
+ reason: input.reason,
65
+ replacement: input.replacement ?? null,
66
+ protectedReason: input.protectedReason ?? null,
67
+ evidence: input.evidence,
68
+ writes: [],
69
+ ...input.extra,
70
+ };
71
+ }
72
+
73
+ function failClosed(mapRunId: string | undefined, snapshotTime: string | undefined, reason: string): DraftCloseDecision {
74
+ const result = row({ mapRunId, snapshotTime, inventoryComplete: false, kind: 'hold', classification: 'inventory-incomplete',
75
+ reason, evidence: [reason], extra: { rowsSuppressed: true } });
76
+ return { outcome: 'hold', result, evidence: { rowsSuppressed: true } };
77
+ }
78
+
79
+ function holdItem(input: { mapRunId?: string; snapshotTime?: string; pr?: number; headOid?: string; reason: string }): DraftCloseDecision {
80
+ const result = row({ mapRunId: input.mapRunId, snapshotTime: input.snapshotTime, inventoryComplete: true, pr: input.pr,
81
+ headOid: input.headOid, kind: 'hold', classification: 'human', reason: input.reason, evidence: [input.reason] });
82
+ return { outcome: 'hold', result, evidence: { reason: input.reason } };
83
+ }
84
+
85
+ /** Pure, deterministic item classifier used by the draft-close graph's observe node. */
86
+ export function decideDraftClose(raw: unknown): DraftCloseDecision {
87
+ const envelope = record(raw);
88
+ const context = Object.keys(record(envelope.context)).length > 0 ? record(envelope.context) : envelope;
89
+ const inventory = record(context.inventory);
90
+ const item = record(context.item);
91
+ const mapRunId = string(context.mapRunId);
92
+ const snapshotTime = string(context.snapshotTime) ?? string(inventory.snapshotTime);
93
+ const completenessClaims = [context.inventoryComplete, inventory.complete].filter((value): value is boolean => typeof value === 'boolean');
94
+ const inventoryComplete = completenessClaims.length > 0 && completenessClaims.every(Boolean);
95
+ const completenessConflict = completenessClaims.some((value) => value !== completenessClaims[0]);
96
+ const truncated = context.truncated === true || inventory.truncated === true;
97
+ const inventoryError = string(context.inventoryError) ?? string(inventory.error);
98
+ if (!inventoryComplete || completenessConflict || truncated || inventoryError) {
99
+ return failClosed(mapRunId, snapshotTime, inventoryError ?? (truncated ? 'inventory truncated/page limit'
100
+ : completenessConflict ? 'conflicting inventory completeness claims' : 'inventory completeness not proven'));
101
+ }
102
+
103
+ const prValue = item.pr ?? item.number;
104
+ const pr = typeof prValue === 'number' && Number.isSafeInteger(prValue) && prValue > 0 ? prValue
105
+ : typeof prValue === 'string' && /^\d+$/.test(prValue) ? Number(prValue) : undefined;
106
+ const headOid = string(item.headOid) ?? string(item.headSha);
107
+ const mainSha = string(context.mainSha) ?? string(inventory.mainSha);
108
+ const repository = string(item.repository);
109
+ const state = string(item.state)?.toLowerCase();
110
+ const labels = strings(item.labels);
111
+ const branch = string(item.branch);
112
+ const title = string(item.title);
113
+ const body = typeof item.body === 'string' ? item.body : undefined;
114
+ const createdAt = string(item.createdAt);
115
+ const changedFiles = strings(item.changedFiles);
116
+ const latestFileChanges = record(item.latestFileChanges) as Record<string, string>;
117
+ const snapshotMs = Date.parse(snapshotTime ?? '');
118
+ if (!pr || !headOid || !repository || !mainSha || !snapshotTime || !Number.isFinite(snapshotMs)
119
+ || state !== 'open' || item.isDraft !== true || !labels || !branch || !title || body === undefined || !createdAt
120
+ || !changedFiles || item.changedFilesComplete !== true) {
121
+ return holdItem({ mapRunId, snapshotTime, pr, headOid,
122
+ reason: 'PR snapshot lacks required id/head/repo/state/labels/body/files or main/snapshot proof' });
123
+ }
124
+
125
+ const protectedLabel = labels.find((label) => DRAFT_CLOSE_PROTECTED_LABELS.has(label));
126
+ if (protectedLabel) {
127
+ const result = row({ mapRunId, snapshotTime, inventoryComplete: true, pr, headOid, kind: 'hold', classification: 'protected',
128
+ reason: `protected label ${protectedLabel}`, protectedReason: protectedLabel, evidence: [`label=${protectedLabel}`, `head=${headOid}`] });
129
+ return { outcome: 'hold', result, evidence: { protectedReason: protectedLabel } };
130
+ }
131
+
132
+ const reviewGate = record(item.reviewGate);
133
+ const reviewHead = string(reviewGate.headOid);
134
+ const gateHead = string(reviewGate.gateHeadOid);
135
+ const review = string(reviewGate.review)?.toLowerCase();
136
+ const gate = string(reviewGate.gate)?.toLowerCase();
137
+ const mustFix = reviewGate.mustFix;
138
+ const reviewPass = reviewHead === headOid && ['pass', 'warn'].includes(review ?? '')
139
+ && Array.isArray(mustFix) && mustFix.length === 0;
140
+ const gatePass = gateHead === headOid && gate === 'pass' && reviewGate.introduced === 0;
141
+ if (reviewPass && gatePass) {
142
+ const reason = 'same-head GLM mustFix=0 and changed gate introduced=0';
143
+ const result = row({ mapRunId, snapshotTime, inventoryComplete: true, pr, headOid, kind: 'harvest', classification: 'harvest', reason,
144
+ evidence: [reason, `repository=${repository}`, `mainSha=${mainSha}`, `head=${headOid}`], extra: {
145
+ handoff: ['merge-origin-main-into-branch', 'resolve-conflicts-on-same-branch', 'changed-gate-introduced-0',
146
+ 'GLM-review-same-head-mustFix-0', 'land-enqueue-without-gate-summary'],
147
+ } });
148
+ return { outcome: 'harvest', result, evidence: { headOid, mainSha, handoff: result.handoff } };
149
+ }
150
+
151
+ if (item.openDraftsComplete !== true || item.mergedTwinsComplete !== true) {
152
+ const reason = 'open/merged peer inventory incomplete; close decision suppressed';
153
+ return holdItem({ mapRunId, snapshotTime, pr, headOid, reason: `${reason}; mainSha=${mainSha}` });
154
+ }
155
+
156
+ const latestCommitAt = string(item.lastCommitAt) ?? string(item.latestCommitAt);
157
+ const latestCommitMs = Date.parse(latestCommitAt ?? '');
158
+ const ageHours = Number.isFinite(latestCommitMs) ? (snapshotMs - latestCommitMs) / 3_600_000 : Number.NaN;
159
+ if (!latestCommitAt || !Number.isFinite(latestCommitMs)) {
160
+ return holdItem({ mapRunId, snapshotTime, pr, headOid, reason: 'last commit time unavailable; 48h/stale decision suppressed' });
161
+ }
162
+ const openDrafts = Array.isArray(item.openDrafts) ? item.openDrafts as DraftTriagePr[] : [];
163
+ const mergedTwins = Array.isArray(item.mergedTwins) ? item.mergedTwins as DraftTriagePr[] : [];
164
+ const liveBranches = new Set(strings(item.liveBranches) ?? []);
165
+ const runStatus = string(item.runStatus);
166
+ const decision = decideDraft({
167
+ draft: { number: pr, title, branch, labels, body, createdAt, changedFiles, latestFileChanges, latestCommitAt },
168
+ runStatus,
169
+ mergedTwins,
170
+ openDrafts,
171
+ ageHours,
172
+ liveBranches,
173
+ ...(typeof item.finalRunResult === 'boolean' ? { finalRunResult: item.finalRunResult } : {}),
174
+ });
175
+ if (decision.action === 'keep') {
176
+ const result = row({ mapRunId, snapshotTime, inventoryComplete: true, pr, headOid, kind: 'hold', classification: 'keep',
177
+ reason: decision.reason, evidence: [`decideDraft=${decision.action}:${decision.reason}`, `head=${headOid}`, `mainSha=${mainSha}`] });
178
+ return { outcome: 'hold', result, evidence: { decision } };
179
+ }
180
+
181
+ // Keep item-level completeness guards beside the close decision even though the envelope guard above also checks them.
182
+ if (decision.reason.startsWith('duplicate-of-open') && item.openDraftsComplete !== true) {
183
+ return failClosed(mapRunId, snapshotTime, 'complete open-draft inventory required for duplicate close proposal');
184
+ }
185
+ if ((decision.reason.includes('all-files-landed') || decision.reason.startsWith('superseded-by'))
186
+ && (item.mergedTwinsComplete !== true || item.changedFilesComplete !== true)) {
187
+ return failClosed(mapRunId, snapshotTime, 'complete changed-file and merged-peer evidence required for superseded close proposal');
188
+ }
189
+
190
+ const match = /#(\d+)/.exec(decision.reason);
191
+ const replacement = match ? Number(match[1]) : undefined;
192
+ const classification = decision.reason.includes('all-files-landed') ? 'all-files-landed'
193
+ : decision.reason.startsWith('duplicate-of-open') ? 'duplicate-of-open'
194
+ : decision.reason.startsWith('superseded-by') ? 'superseded' : 'stale';
195
+ const result = row({ mapRunId, snapshotTime, inventoryComplete: true, pr, headOid, kind: 'close-candidate', classification,
196
+ reason: decision.reason, replacement, evidence: [`decideDraft=close:${decision.reason}`, `lastCommitAt=${latestCommitAt}`,
197
+ `ageHours=${ageHours}`, `repository=${repository}`, `mainSha=${mainSha}`, `head=${headOid}`], extra: { writeBoundary: 'reduce-only' } });
198
+ return { outcome: 'close-candidate', result, evidence: { decision, latestCommitAt, ageHours, mainSha, headOid } };
199
+ }
200
+
201
+ function graphContext(): Json {
202
+ const path = process.env.ELANOUS_GRAPH_CONTEXT;
203
+ if (!path) throw new Error('ELANOUS_GRAPH_CONTEXT is required');
204
+ return JSON.parse(readFileSync(path, 'utf8')) as Json;
205
+ }
206
+
207
+ if (import.meta.main) {
208
+ const context = graphContext();
209
+ const mode = process.argv[2];
210
+ if (mode === 'decide') {
211
+ const decision = decideDraftClose(context.input);
212
+ process.stdout.write(`${JSON.stringify(decision)}\n`);
213
+ } else if (mode === 'emit') {
214
+ const branch = process.argv[3] as DraftCloseKind | undefined;
215
+ const decided = record(record(context.outputs).decide);
216
+ const result = record(decided.result);
217
+ if (!branch || result.kind !== branch) throw new Error(`decision row kind does not match branch ${branch ?? '<missing>'}`);
218
+ process.stdout.write(`${JSON.stringify({ outcome: 'done', result, evidence: decided.evidence ?? {} })}\n`);
219
+ } else {
220
+ throw new Error(`unknown draft-close mode: ${mode ?? '<missing>'}`);
221
+ }
222
+ }
@@ -106,9 +106,10 @@ function isFunctionLike(ts: Ts, node: Node): boolean {
106
106
  return ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node) || ts.isMethodDeclaration(node);
107
107
  }
108
108
 
109
- /** 이 노드와 소유자 사이에 «분기»가 있나 — 있으면 그 훅은 매 렌더에 안 돈다. */
109
+ /** 이 노드와 소유자 사이에 «분기»가 있나 — 단축 평가 연산자의 오른쪽만 조건부다. */
110
110
  function branchBetween(ts: Ts, node: Node, owner: Node): boolean {
111
- for (let current = node.parent; current && current !== owner; current = current.parent) {
111
+ let child: Node = node;
112
+ for (let current = node.parent; current && current !== owner; child = current, current = current.parent) {
112
113
  if (
113
114
  ts.isIfStatement(current)
114
115
  || ts.isConditionalExpression(current)
@@ -116,7 +117,9 @@ function branchBetween(ts: Ts, node: Node, owner: Node): boolean {
116
117
  || ts.isWhileStatement(current) || ts.isDoStatement(current)
117
118
  || ts.isSwitchStatement(current)
118
119
  || ts.isTryStatement(current) || ts.isCatchClause(current)
119
- || (ts.isBinaryExpression(current) && (current.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken || current.operatorToken.kind === ts.SyntaxKind.BarBarToken || current.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken))
120
+ || (ts.isBinaryExpression(current)
121
+ && child === current.right
122
+ && (current.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken || current.operatorToken.kind === ts.SyntaxKind.BarBarToken || current.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken))
120
123
  ) return true;
121
124
  }
122
125
  return false;
@@ -270,7 +273,7 @@ export function formatHookOrderReport(report: HookOrderReport): string[] {
270
273
  return [
271
274
  `[hook-order] denominator: hook calls=${report.hookCallsScanned}; components and custom hooks=${report.ownersScanned}; files=${report.filesScanned}; ruler=identifier call matching /^use[A-Z]/ in TypeScript sources under the scanned scopes; scope=${report.scanRoots.join(', ') || 'none'}; unmeasured scopes=${report.unavailableScopes.join(', ') || 'none'}`,
272
275
  `[hook-order] after early return: ${kindCount(report, 'after-early-return')}; ruler=hook call positioned after a return statement in the top-level statement list of its component, so a render that takes the early return calls fewer hooks`,
273
- `[hook-order] conditional: ${kindCount(report, 'conditional')}; ruler=hook call nested inside a branch, loop, switch, try, or short-circuit operator within its component`,
276
+ `[hook-order] conditional: ${kindCount(report, 'conditional')}; ruler=hook call nested inside a branch, loop, switch, try, or the right operand of &&, ||, or ?? within its component`,
274
277
  `[hook-order] nested function: ${kindCount(report, 'nested-function')}; ruler=hook call inside a function that is neither a component nor a custom hook, so it does not run on every render of the surrounding component`,
275
278
  `[hook-order] imported hook identity: not-measured; ruler=a locally declared function that calls no hook is excluded because a hook is a function that calls hooks, but an imported name and a property access such as React.useState are judged by the naming convention React itself enforces; a hook renamed on import to a name that does not start with use is outside this ruler and outside React's own convention`,
276
279
  `[hook-order] elapsed: ${report.elapsedSeconds.toFixed(2)}s`,
@@ -9,6 +9,9 @@
9
9
  // 재는 명령: `bun scripts/land-global-checks.ts` (표) · `bun scripts/land-global-checks.ts <바뀐 파일…>` (끌려오는 시험)
10
10
 
11
11
  import { spawnSync } from 'node:child_process';
12
+ import { existsSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
13
+ import { tmpdir } from 'node:os';
14
+ import { join } from 'node:path';
12
15
 
13
16
  type LandGlobalCheck = {
14
17
  /** 바뀐 파일 경로(저장소 루트 기준 · `/` 구분)에 대는 꼴. */
@@ -19,9 +22,16 @@ type LandGlobalCheck = {
19
22
  why: string;
20
23
  };
21
24
 
25
+ /** 착지 게이트가 실물 판정하는 next.md 경로 꼴 — 이번 착지가 이 꼴을 바꿀 때만 next.md 판정(landNextMdGate)이 돈다. */
26
+ const NEXT_MD_PATTERN = /^release\/next\.md$/;
27
+
22
28
  export const LAND_GLOBAL_CHECKS: readonly LandGlobalCheck[] = [
23
29
  { pattern: /^apps\/pwa\/.+\.tsx$/, test: 'test/hook-order-sweep.test.ts', why: 'PWA 컴포넌트 훅 순서(#24719)' },
24
- { pattern: /^release\/next\.md$/, test: 'scripts/release-story/draft.test.ts', why: '판 노트 초안·브랜드 규칙(#24688)' },
30
+ { pattern: NEXT_MD_PATTERN, test: 'scripts/release-story/draft.test.ts', why: '판 노트 초안·브랜드 규칙(#24688)' },
31
+ // 초안 규칙(draft.test)은 노트 줄에 B11 이 «없음»을 단언하는 길이라 발행 판정과 자가 다르다 — 0.2.24 는
32
+ // next.md 의 «신설:» 한 줄로 컷 노드 notes-check 가 두 번 ✗ 났는데(10-12 01:28 · 01:51) 착지에서는 그 줄이 통과했다.
33
+ // 착지 판정이 실제 next.md 를 발행과 같은 check() 로 보게 `landNextMdGate`(runLandGlobalChecksGate 안)가 판정 자를 맞춘다.
34
+ { pattern: NEXT_MD_PATTERN, test: 'scripts/announce-loop/check-node.test.ts', why: '발행 노트 한국어 B11(0.2.24 notes-check)' },
25
35
  { pattern: /^docs\/ops\/machines\.yaml$/, test: 'test/machines-ledger-data.test.ts', why: '기계 원장 데이터 ↔ 생성 Markdown(#24729)' },
26
36
  // 새 CLI 하위 명령은 `src/index.ts` 또는 `src/cli/` 의 등록 모듈에서 생긴다 — 입구 목록 시험(#24661).
27
37
  { pattern: /^src\/(?:index|cli\/(?:[^/]+\/)*[^/]+)(?<!\.test)\.ts$/, test: 'src/index.test.ts', why: 'CLI 입구·하위 명령 목록(#24661)' },
@@ -41,6 +51,59 @@ export function landGlobalChecks(changedFiles: readonly string[], table: readonl
41
51
 
42
52
  export type LandGlobalChecksRun = { status: number | null; output: string; error?: string };
43
53
 
54
+ const CHECK_NODE_SCRIPT = join(import.meta.dir, 'announce-loop', 'check-node.ts');
55
+
56
+ type NextMdFinding = { rule: string; file: string; line: number; text: string };
57
+
58
+ /** 발행 notes-check 와 같은 check()(scripts/announce-loop/check-node.ts)에 «실제 저장소의» release/next.md 를 넣고
59
+ * «착지» 범위(--landing)로 돈다 — gh·fetch 없이 B11·B8·공유 줄 규칙만(B1·B10 네트워크 검사는 발행 판정에만 있다). */
60
+ function runNextMdCheck(cwd: string): LandGlobalChecksRun {
61
+ const dir = mkdtempSync(join(tmpdir(), 'land-next-md-'));
62
+ const prfaq = join(dir, 'prfaq.md');
63
+ writeFileSync(prfaq, '');
64
+ try {
65
+ const r = spawnSync('bun', [CHECK_NODE_SCRIPT, '--landing', '--prfaq', prfaq, '--files', 'release/next.md'], {
66
+ cwd, encoding: 'utf8', maxBuffer: 8 * 1024 * 1024, timeout: 60_000,
67
+ });
68
+ return { status: r.status, output: `${r.stdout ?? ''}\n${r.stderr ?? ''}`, ...(r.error ? { error: r.error.message } : {}) };
69
+ } finally {
70
+ rmSync(dir, { recursive: true, force: true });
71
+ }
72
+ }
73
+
74
+ /**
75
+ * 착지 게이트가 실제 release/next.md 를 발행 판정과 같은 check() 로 본다 — 0.2.24 어긋남(착지 통과 · 발행 B11 ✗) 수리.
76
+ * ⚠️ 파일이 없으면 «해당 없음»으로 통과한다(착지 게이트는 무대의 실물만 본다).
77
+ * 호출부(runLandGlobalChecksGate)는 이번 착지의 바뀐 파일에 release/next.md 가 있을 때만 부른다 —
78
+ * next.md 를 건드리지 않은 PR 은 main 의 next.md 상태에 영향을 받지 않는다.
79
+ * 판정 범위는 «착지»(--landing) — B11·B8·공유 줄 규칙만. B1(PR 참조)·B10(링크) 네트워크 검사는 발행 판정에만 있다.
80
+ */
81
+ export function landNextMdGate(cwd: string, io: { log: (message: string) => void; error: (message: string) => void }): boolean {
82
+ const nextMd = join(cwd, 'release', 'next.md');
83
+ if (!existsSync(nextMd)) return true;
84
+ const result = runNextMdCheck(cwd);
85
+ if (result.error !== undefined || result.status === null) {
86
+ throw new Error(`release/next.md 발행 노트 검사 러너가 못 돌았다 — ${result.error ?? 'status=null'}`);
87
+ }
88
+ if (result.status === 0) {
89
+ io.log('✓ land-global-checks: 실제 release/next.md 발행 노트 검사(check-node) PASS — 위반 0.');
90
+ return true;
91
+ }
92
+ let findings: NextMdFinding[] = [];
93
+ const jsonLine = result.output.split(/\r?\n/).find((line) => line.trim().startsWith('{'));
94
+ if (jsonLine !== undefined) {
95
+ try { findings = (JSON.parse(jsonLine) as { findings?: NextMdFinding[] }).findings ?? []; } catch { findings = []; }
96
+ }
97
+ if (findings.length === 0) {
98
+ io.error(`✗ land-global-checks: 실제 release/next.md 발행 노트 검사(check-node)가 실패했다(종료 ${result.status}) — ${result.output.trim().split(/\r?\n/).at(-1) ?? ''}`);
99
+ }
100
+ for (const f of findings) {
101
+ io.error(`✗ land-global-checks: 실제 release/next.md — 발행 노트 검사(check-node) 위반 ${f.rule} ${f.file}:${f.line} ${f.text.trim()}`);
102
+ }
103
+ io.error('✗ land-global-checks: scripts/land-global-checks.ts blocked pr land — 실제 release/next.md 가 발행 notes-check(check-node) 판정에서 위반했다. 발행 판정과 착지 판정의 B11 자를 맞추려면 노트를 고치고 착지하라.');
104
+ return false;
105
+ }
106
+
44
107
  type LandGlobalChecksGateIo = {
45
108
  changedFiles: readonly string[];
46
109
  cwd: string;
@@ -59,9 +122,14 @@ function runDeterministic(tests: readonly string[], cwd: string): LandGlobalChec
59
122
 
60
123
  /**
61
124
  * 반환: true = 해당 없음 또는 끌려온 시험 통과 · false = 끌려온 시험이 실패했다(착지를 막는다).
125
+ * 실물 next.md 판정(landNextMdGate)은 이번 착지가 release/next.md 를 바꿀 때만 돈다 — 머리 주석의
126
+ * «바뀐 파일 꼴로 끌어온다» 계약을 따른다. next.md 를 건드리지 않은 PR 은 main 의 next.md 상태를 보지 않는다.
62
127
  * ⛔ 러너가 «못 돌았다»(spawn 실패·시간 초과)면 던진다 — 호출부(`gateVerdict`)가 「검사 못 함」으로 말한다.
63
128
  */
64
129
  export function runLandGlobalChecksGate(io: LandGlobalChecksGateIo): boolean {
130
+ if (io.changedFiles.some((file) => NEXT_MD_PATTERN.test(file.replace(/\\/g, '/')))) {
131
+ if (!landNextMdGate(io.cwd, io)) return false;
132
+ }
65
133
  const tests = landGlobalChecks(io.changedFiles);
66
134
  if (tests.length === 0) {
67
135
  io.log(`[land-global-checks] 해당 없음 — 바뀐 파일 ${io.changedFiles.length}개가 전역 검사 표(${LAND_GLOBAL_CHECKS.length}줄)의 꼴에 안 걸린다.`);