elanous 0.2.20 → 0.2.22

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 (456) 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/aBi6EyMtLsrl7J8eH4kF7/_buildManifest.js +1 -0
  4. package/apps/pwa/out/_next/static/chunks/088d8e8a.8069543d082bec12.js +160 -0
  5. package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +148 -0
  6. package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +32 -0
  7. package/apps/pwa/out/_next/static/chunks/119fc678.6f591cdb84ca5791.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +309 -0
  9. package/apps/pwa/out/_next/static/chunks/1307-08b716476f1d50af.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +122 -0
  11. package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +149 -0
  12. package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +79 -0
  13. package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +24 -0
  15. package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +27 -0
  19. package/apps/pwa/out/_next/static/chunks/1948.5f35b39eef222a94.js +5 -0
  20. package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +36 -0
  25. package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +286 -0
  26. package/apps/pwa/out/_next/static/chunks/{2489-ff55a35b202c0f94.js → 2489-d238d3e2eb5b2bf5.js} +1 -1
  27. package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +94 -0
  34. package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3522-1de1319d028ac89c.js +25 -0
  38. package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3857-5985236d9307f676.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +74 -0
  41. package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +34 -0
  45. package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +115 -0
  47. package/apps/pwa/out/_next/static/chunks/4588.ad3364cb7fb97ada.js +86 -0
  48. package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +77 -0
  50. package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/5633-d6852385000738ef.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +90 -0
  55. package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5977-5b9e8a45a5b0c823.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +8 -0
  60. package/apps/pwa/out/_next/static/chunks/{6158.af2e93b7adff709b.js → 6158.566c890adc06a459.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +64 -0
  62. package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +287 -0
  64. package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +226 -0
  65. package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6767.8e6c5f6e744fcd9f.js +38 -0
  67. package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/7175-350f4ce2873bc038.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +41 -0
  74. package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +24 -0
  75. package/apps/pwa/out/_next/static/chunks/7630.2b9a68659053ff4e.js +193 -0
  76. package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/7899.597af4a9996c907f.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/79b78388.663188133449d707.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/8194.484f51e273d9abd2.js +217 -0
  82. package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +104 -0
  83. package/apps/pwa/out/_next/static/chunks/8857-aa1cc4ac90af4d40.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/88729267.9c6c000157c83f2f.js +62 -0
  85. package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +93 -0
  87. package/apps/pwa/out/_next/static/chunks/9247-55bcfbb0e8057f59.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +23 -0
  89. package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +62 -0
  90. package/apps/pwa/out/_next/static/chunks/9832.2ab2e818013574c7.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/a9f2b54d-40c16bd0efdb04b8.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/app/approvals/{page-c855c24de7db74fe.js → page-88459e0903da2803.js} +1 -1
  93. package/apps/pwa/out/_next/static/chunks/app/autopilot/{page-85b316bb4235980b.js → page-d85c43f46f58716b.js} +1 -1
  94. package/apps/pwa/out/_next/static/chunks/app/board/{page-9b2b26a33cb2cd42.js → page-4e645600579ae952.js} +1 -1
  95. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-c9955fde67b1bcb5.js → page-87edbfd19117823b.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/app/bots/page-7f0c2b7801ac6a54.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/app/ceo/page-bf1f030a9d1adffd.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/app/chat/{page-4ba4abe096b6c2a8.js → page-cbaf66b1e1804adf.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/app/consult/{page-575d4a8b4f7becb2.js → page-80ed511e02c81412.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/app/control/{page-f5d56ff5f45ad164.js → page-9f5610caaa06178c.js} +1 -1
  101. package/apps/pwa/out/_next/static/chunks/app/decisions/{page-2260e9eef0357421.js → page-ec8f3575e339de74.js} +1 -1
  102. package/apps/pwa/out/_next/static/chunks/app/design-check/page-86d753e460f1a989.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/app/editor/page-4166a7d51cf0a57d.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/app/exec/{page-466bf0ee16ad1432.js → page-2a19c5cd3b562580.js} +1 -1
  105. package/apps/pwa/out/_next/static/chunks/app/field/{page-a23bc71713bcc08f.js → page-b6a09cde2e07521a.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/app/inside/page-f7eae1518ca0c353.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/app/intake/page-456a8573ad811381.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/app/layout-8462d6a543cbb2d9.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/app/live/page-2974cdfb87c0f9c9.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f927ffa25f3c86d1.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/app/loops/{page-35bfec2e631d3eae.js → page-abd86cd832aaa011.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/app/market/page-79daf68f6256adaa.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/{page-f9ccb1b1adbea14d.js → page-8c3f168fc3f91939.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/app/morning/{page-ec102c9b8b691e37.js → page-786fb4504d0f2fa9.js} +1 -1
  115. package/apps/pwa/out/_next/static/chunks/app/not-found-75209f14597dcb8f.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/app/observatory/page-bf30affe3a85af7e.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1187a44b7515434b.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-3d0910185a66ed54.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f401ee1dd5a26e25.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/app/outputs/page-5dfe7604fd842784.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/app/page-76cf838050a8d681.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/app/reflection/{page-db03ae3589a81c9e.js → page-7ec8e289b4c14df6.js} +1 -1
  123. package/apps/pwa/out/_next/static/chunks/app/scheduler/{page-4a6463b97f0ad94f.js → page-8c8ac17d52be2a79.js} +1 -1
  124. package/apps/pwa/out/_next/static/chunks/app/sessions/{page-75bffecc9aa1004e.js → page-d359ab048d63a9d9.js} +1 -1
  125. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-b8b345c880bf78d1.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/settings/{page-31d5b875760bb62d.js → page-f151cc10ad026940.js} +1 -1
  127. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-9875f103057da433.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/setup/page-9789328af9a9aa62.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/share/{page-46d5201d2207a511.js → page-bf495a1e284f4e00.js} +1 -1
  130. package/apps/pwa/out/_next/static/chunks/app/showroom/page-a263d94bca4be22a.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/tasks/page-3962eab8ec58d16e.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/term/{page-cf0a4b4abead71ea.js → page-9abcfac07e02a542.js} +1 -1
  133. package/apps/pwa/out/_next/static/chunks/app/today/page-bee49f927c333abb.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/trace/page-bac2d56dcb02d955.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/vault/page-937cbcc13176295c.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d09495594f7f480d.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/workflows/{page-0acc8e198f7b0dfb.js → page-69cb93d1a2e57e0e.js} +1 -1
  138. package/apps/pwa/out/_next/static/chunks/app/workspace/{page-34882c84f84021c5.js → page-72ec543928d67c3e.js} +1 -1
  139. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-82906eeda0186a7b.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/d70879db.c66c56a95a91efc6.js +66 -0
  141. package/apps/pwa/out/_next/static/chunks/f8626309.a4e5d362b1d55e59.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +1 -0
  143. package/apps/pwa/out/_next/static/css/{d3427996da11e480.css → b9d8151e48998417.css} +1 -1
  144. package/apps/pwa/out/_next/static/css/f2bd5257e6af88d8.css +1 -0
  145. package/apps/pwa/out/approvals/index.html +1 -1
  146. package/apps/pwa/out/approvals/index.txt +14 -14
  147. package/apps/pwa/out/autopilot/index.html +1 -1
  148. package/apps/pwa/out/autopilot/index.txt +14 -14
  149. package/apps/pwa/out/board/index.html +1 -1
  150. package/apps/pwa/out/board/index.txt +14 -14
  151. package/apps/pwa/out/botlab/index.html +1 -1
  152. package/apps/pwa/out/botlab/index.txt +14 -14
  153. package/apps/pwa/out/bots/index.html +1 -1
  154. package/apps/pwa/out/bots/index.txt +14 -14
  155. package/apps/pwa/out/ceo/index.html +1 -1
  156. package/apps/pwa/out/ceo/index.txt +14 -14
  157. package/apps/pwa/out/chat/index.html +1 -1
  158. package/apps/pwa/out/chat/index.txt +14 -14
  159. package/apps/pwa/out/consult/index.html +1 -1
  160. package/apps/pwa/out/consult/index.txt +14 -14
  161. package/apps/pwa/out/control/index.html +1 -1
  162. package/apps/pwa/out/control/index.txt +14 -14
  163. package/apps/pwa/out/decisions/index.html +1 -1
  164. package/apps/pwa/out/decisions/index.txt +14 -14
  165. package/apps/pwa/out/design-check/index.html +1 -1
  166. package/apps/pwa/out/design-check/index.txt +14 -14
  167. package/apps/pwa/out/editor/index.html +1 -1
  168. package/apps/pwa/out/editor/index.txt +15 -15
  169. package/apps/pwa/out/exec/index.html +1 -1
  170. package/apps/pwa/out/exec/index.txt +14 -14
  171. package/apps/pwa/out/field/index.html +1 -1
  172. package/apps/pwa/out/field/index.txt +14 -14
  173. package/apps/pwa/out/healthz +1 -1
  174. package/apps/pwa/out/index.html +1 -1
  175. package/apps/pwa/out/index.txt +14 -14
  176. package/apps/pwa/out/inside/index.html +1 -1
  177. package/apps/pwa/out/inside/index.txt +15 -15
  178. package/apps/pwa/out/intake/index.html +1 -1
  179. package/apps/pwa/out/intake/index.txt +14 -14
  180. package/apps/pwa/out/live/index.html +1 -1
  181. package/apps/pwa/out/live/index.txt +14 -14
  182. package/apps/pwa/out/live-run/index.html +1 -0
  183. package/apps/pwa/out/live-run/index.txt +35 -0
  184. package/apps/pwa/out/loops/index.html +1 -1
  185. package/apps/pwa/out/loops/index.txt +14 -14
  186. package/apps/pwa/out/market/index.html +1 -1
  187. package/apps/pwa/out/market/index.txt +14 -14
  188. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  189. package/apps/pwa/out/missions/placeholder/index.txt +14 -14
  190. package/apps/pwa/out/morning/index.html +1 -1
  191. package/apps/pwa/out/morning/index.txt +14 -14
  192. package/apps/pwa/out/observatory/index.html +1 -1
  193. package/apps/pwa/out/observatory/index.txt +14 -14
  194. package/apps/pwa/out/ops/checklist/index.html +1 -1
  195. package/apps/pwa/out/ops/checklist/index.txt +14 -14
  196. package/apps/pwa/out/ops/release/index.html +1 -1
  197. package/apps/pwa/out/ops/release/index.txt +14 -14
  198. package/apps/pwa/out/ops/seats/index.html +1 -1
  199. package/apps/pwa/out/ops/seats/index.txt +14 -14
  200. package/apps/pwa/out/outputs/index.html +1 -1
  201. package/apps/pwa/out/outputs/index.txt +14 -14
  202. package/apps/pwa/out/reflection/index.html +1 -1
  203. package/apps/pwa/out/reflection/index.txt +15 -15
  204. package/apps/pwa/out/scheduler/index.html +1 -1
  205. package/apps/pwa/out/scheduler/index.txt +14 -14
  206. package/apps/pwa/out/sessions/index.html +1 -1
  207. package/apps/pwa/out/sessions/index.txt +14 -14
  208. package/apps/pwa/out/settings/devices/index.html +1 -1
  209. package/apps/pwa/out/settings/devices/index.txt +14 -14
  210. package/apps/pwa/out/settings/index.html +1 -1
  211. package/apps/pwa/out/settings/index.txt +14 -14
  212. package/apps/pwa/out/setup/done/index.html +1 -1
  213. package/apps/pwa/out/setup/done/index.txt +14 -14
  214. package/apps/pwa/out/setup/index.html +1 -1
  215. package/apps/pwa/out/setup/index.txt +14 -14
  216. package/apps/pwa/out/share/index.html +1 -1
  217. package/apps/pwa/out/share/index.txt +14 -14
  218. package/apps/pwa/out/showroom/index.html +1 -1
  219. package/apps/pwa/out/showroom/index.txt +14 -14
  220. package/apps/pwa/out/tasks/index.html +1 -1
  221. package/apps/pwa/out/tasks/index.txt +14 -14
  222. package/apps/pwa/out/term/index.html +1 -1
  223. package/apps/pwa/out/term/index.txt +14 -14
  224. package/apps/pwa/out/today/index.html +1 -1
  225. package/apps/pwa/out/today/index.txt +14 -14
  226. package/apps/pwa/out/trace/index.html +1 -1
  227. package/apps/pwa/out/trace/index.txt +14 -14
  228. package/apps/pwa/out/vault/index.html +1 -1
  229. package/apps/pwa/out/vault/index.txt +14 -14
  230. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  231. package/apps/pwa/out/workflows/chat-ui/index.txt +14 -14
  232. package/apps/pwa/out/workflows/index.html +1 -1
  233. package/apps/pwa/out/workflows/index.txt +14 -14
  234. package/apps/pwa/out/workspace/index.html +1 -1
  235. package/apps/pwa/out/workspace/index.txt +14 -14
  236. package/apps/pwa/out/worktrees/index.html +1 -1
  237. package/apps/pwa/out/worktrees/index.txt +14 -14
  238. package/graphs/catalog/catalog.yaml +1 -1
  239. package/graphs/drafts/recipes.yaml +6 -6
  240. package/graphs/implement-loop.yaml +277 -5
  241. package/graphs/test-diet/recipes.yaml +3 -0
  242. package/graphs/test-diet/test-diet.yaml +3 -1
  243. package/package.json +1 -1
  244. package/scripts/coord-channel-watch.sh +31 -4
  245. package/scripts/docs-lint.ts +4 -1
  246. package/scripts/f-session-monitor.ts +69 -0
  247. package/scripts/hq/standby-snapshot.ts +7 -3
  248. package/scripts/knowledge-compress.ts +11 -0
  249. package/scripts/marketing/generate-ax-brief.ts +18 -1
  250. package/scripts/measure-nl-routing-corpus.ts +11 -3
  251. package/scripts/nightly-docops.ts +90 -3
  252. package/scripts/release-loop/gate-node.ts +5 -5
  253. package/scripts/release-loop/shard-plan.ts +50 -5
  254. package/scripts/research-coo-admin-dates.ts +39 -0
  255. package/scripts/rhythm/daily.ts +2 -1
  256. package/scripts/skills/public-check.ts +7 -2
  257. package/scripts/smart-merge/resync-shadow.ts +5 -3
  258. package/scripts/test-diet/lib.ts +81 -1
  259. package/scripts/test-diet/node.ts +48 -2
  260. package/scripts/verify-coo-admin-evidence.ts +83 -0
  261. package/src/acp/client.ts +4 -2
  262. package/src/agent/run-context.ts +4 -0
  263. package/src/agent-env/profile.ts +25 -5
  264. package/src/agent-mission/driver.ts +26 -12
  265. package/src/agent-mission/supervisor-metrics.ts +17 -2
  266. package/src/agent-substrate/acp-reviewer.ts +12 -5
  267. package/src/agent-substrate/pr-reviewer.ts +11 -4
  268. package/src/agent-substrate/review-intent.ts +102 -3
  269. package/src/autopilot/build/llm-conflict-merge.ts +22 -8
  270. package/src/autopilot/pr-manager.ts +18 -8
  271. package/src/away/release-watch.ts +47 -8
  272. package/src/briefing/brief-items.ts +104 -11
  273. package/src/browser-cdp/client.ts +10 -5
  274. package/src/chat/index.ts +1 -0
  275. package/src/cli/brief-cli.ts +20 -2
  276. package/src/cli/config-classify.ts +83 -0
  277. package/src/cli/control-cli.ts +14 -0
  278. package/src/cli/decisions-cli.ts +26 -16
  279. package/src/cli/logs-model-input.ts +1 -1
  280. package/src/cli/ops-cli.ts +11 -0
  281. package/src/cli/ops-overview-cli.ts +50 -0
  282. package/src/cli/pod-cli.ts +1 -0
  283. package/src/cli/pr-cli.ts +65 -8
  284. package/src/cli/release-cli.ts +21 -4
  285. package/src/cli/tasks-cli.ts +214 -1
  286. package/src/connectors/types.ts +6 -6
  287. package/src/context-bus/context-now-surfaces.ts +18 -0
  288. package/src/context-bus/coord-events.ts +32 -4
  289. package/src/context-bus/long-term-memory.ts +23 -6
  290. package/src/context-bus/nightly-condense.ts +169 -21
  291. package/src/control/control-status.ts +87 -0
  292. package/src/control-plane/light-member.ts +5 -3
  293. package/src/control-plane/member.ts +172 -7
  294. package/src/core-turn/run-goal-loop.ts +22 -1
  295. package/src/dashboard/index.ts +40 -4
  296. package/src/dashboard/slash-runtime/dashboard-handlers.ts +9 -0
  297. package/src/decisions/decision-cards.ts +20 -1
  298. package/src/decisions/decision-ledger.ts +11 -8
  299. package/src/decisions/web-push-decision-cards.ts +19 -3
  300. package/src/discord-self-message.ts +2 -2
  301. package/src/domains/coo-admin-dates.evidence.json +876 -0
  302. package/src/domains/coo-admin-tool.ts +48 -14
  303. package/src/domains/ops-status.ts +53 -0
  304. package/src/domains/outbound-alert.ts +24 -1
  305. package/src/esc-abort-gate.ts +3 -1
  306. package/src/exec-requests/planner.ts +6 -0
  307. package/src/graph-kinds/registry.ts +6 -6
  308. package/src/graph-runner/graph-cli.ts +91 -2
  309. package/src/graph-runner/graph-run-api.ts +20 -0
  310. package/src/graph-runner/graph-tick.ts +73 -12
  311. package/src/graph-runner/runner.ts +43 -11
  312. package/src/graph-unify/wf-to-graph.ts +79 -0
  313. package/src/graph-wizard/archetypes.ts +88 -0
  314. package/src/graph-wizard/generate.ts +577 -0
  315. package/src/graph-wizard/saved-steps.ts +120 -0
  316. package/src/graph-wizard/steps.ts +206 -0
  317. package/src/harness/harness-cli-command.ts +186 -32
  318. package/src/harness/harness-queue.ts +58 -14
  319. package/src/harness/launch-advice.ts +23 -0
  320. package/src/index.ts +43 -11
  321. package/src/intake-plane/digest.ts +18 -11
  322. package/src/knowledge/conclusion-compress.ts +93 -0
  323. package/src/knowledge/know-find.ts +9 -2
  324. package/src/knowledge/query.ts +20 -0
  325. package/src/llm.ts +26 -16
  326. package/src/loops/neighbor-runtime.ts +88 -0
  327. package/src/loops/orchestrator/author-depth.ts +29 -11
  328. package/src/loops/orchestrator/overlap.ts +7 -1
  329. package/src/loops/orchestrator/resync-shadow.ts +1 -1
  330. package/src/loops/orchestrator/tick.ts +35 -2
  331. package/src/loops/orchestrator/traffic.ts +2 -0
  332. package/src/loops/registry.ts +5 -0
  333. package/src/market/publish.ts +17 -1
  334. package/src/maturity/feature-maturity.ts +4 -2
  335. package/src/mss/logging/redaction.ts +17 -0
  336. package/src/nexus/api/draft-metrics.ts +128 -0
  337. package/src/nexus/api/graph-peer-edit.ts +77 -0
  338. package/src/nexus/api/graph-wizard-api.ts +61 -0
  339. package/src/nexus/api/graphs-api.ts +193 -17
  340. package/src/nexus/api/harness-traversal.ts +205 -0
  341. package/src/nexus/api/http-server.ts +122 -6
  342. package/src/nexus/api/plugins-market.ts +24 -0
  343. package/src/nexus/index.ts +3 -2
  344. package/src/nexus/outbound/router.ts +28 -8
  345. package/src/oauth/claude-pty-maturity.ts +24 -0
  346. package/src/oauth/fallback-chain.ts +27 -14
  347. package/src/onboarding/first-run.ts +3 -0
  348. package/src/ops/overview-collect.ts +345 -0
  349. package/src/ops/overview-seat-era.ts +90 -0
  350. package/src/ops/overview.ts +223 -0
  351. package/src/plugins/maker/market-bundle.ts +9 -0
  352. package/src/plugins/maker/plugin-maker.ts +9 -3
  353. package/src/plugins/maker/wizard-generate.ts +73 -9
  354. package/src/policy/llm-policy.ts +11 -6
  355. package/src/release-loop/checklist-board.ts +27 -0
  356. package/src/release-loop/checklist.ts +38 -0
  357. package/src/release-loop/gate-shards.ts +7 -2
  358. package/src/seat-address/seat-address.ts +1 -0
  359. package/src/seat-loop/seat-loop.ts +174 -20
  360. package/src/seat-loop/seat-report.ts +29 -1
  361. package/src/self-dev/ask-launch-flow.ts +4 -2
  362. package/src/self-dev/ask-launch-io.ts +3 -1
  363. package/src/self-dev/dev-cli.ts +90 -8
  364. package/src/self-dev/dev-pipeline.ts +20 -1
  365. package/src/self-dev/draft-sweep.ts +45 -8
  366. package/src/self-dev/graph-journey-nodes.ts +157 -0
  367. package/src/self-dev/graph-journey-route.ts +105 -0
  368. package/src/self-dev/launch-preflight.ts +43 -3
  369. package/src/self-dev/orchestrate.ts +3 -0
  370. package/src/self-dev/release-path-guard.ts +7 -4
  371. package/src/self-dev/review-provider-fallback.ts +83 -0
  372. package/src/self-dev/run-supervisor.ts +5 -1
  373. package/src/self-implement/frozen-merges.ts +23 -0
  374. package/src/self-implement/goal-author.ts +14 -0
  375. package/src/self-implement/harness-policy-gates.ts +7 -5
  376. package/src/self-implement/heal-intake.ts +3 -0
  377. package/src/self-implement/host-regate.ts +28 -14
  378. package/src/self-implement/l8-merge-queue.ts +80 -8
  379. package/src/self-implement/orchestrator.ts +84 -28
  380. package/src/self-implement/seams.ts +8 -3
  381. package/src/self-implement/self-implement-cli.ts +4 -0
  382. package/src/self-implement/self-implement-runtime.ts +12 -0
  383. package/src/session-runtime/index.ts +5 -3
  384. package/src/shell-env-bootstrap.ts +35 -6
  385. package/src/steward/triage.ts +25 -8
  386. package/src/storage/file-lock.ts +33 -4
  387. package/src/task-agent/card-evidence.ts +6 -0
  388. package/src/task-agent/completion-evidence.ts +31 -3
  389. package/src/task-agent/cover.ts +61 -0
  390. package/src/task-agent/live-moves.ts +126 -3
  391. package/src/task-agent/parent-host.ts +315 -0
  392. package/src/task-agent/shadow.ts +19 -4
  393. package/src/task-agent/task-hand.ts +11 -2
  394. package/src/task-orchestrator/surfaces/pod-command-job.ts +41 -6
  395. package/src/task-orchestrator/surfaces/pod-gate-deps.ts +123 -0
  396. package/src/task-orchestrator/surfaces/pod-pool.ts +138 -15
  397. package/src/task-orchestrator/surfaces/self-implement-pod.ts +39 -6
  398. package/src/task-orchestrator/surfaces/self-implement.ts +7 -0
  399. package/src/telegram-commands.ts +8 -0
  400. package/src/telegram-project-command.ts +6 -0
  401. package/src/telegram.ts +2 -2
  402. package/src/tool-runtime/browser-runtime.ts +87 -3
  403. package/src/tool-runtime/index.ts +1 -0
  404. package/src/typecheck-ratchet.ts +2 -1
  405. package/src/user-config.ts +55 -8
  406. package/src/version/packed-revision.json +1 -1
  407. package/src/workflow-runtime/executor.ts +24 -2
  408. package/src/workflow-runtime/triggers/registry.ts +27 -0
  409. package/src/workflow-runtime/triggers/schedule-source.ts +30 -3
  410. package/apps/pwa/out/_next/static/Bam1YziK2iH9bN4K0utGk/_buildManifest.js +0 -1
  411. package/apps/pwa/out/_next/static/chunks/1307-77fad80cf54477c6.js +0 -1
  412. package/apps/pwa/out/_next/static/chunks/1612-f60c0c93ec773f81.js +0 -1
  413. package/apps/pwa/out/_next/static/chunks/1844-9ec4b1d12f6e80eb.js +0 -1
  414. package/apps/pwa/out/_next/static/chunks/1866-e7a6999f25548b30.js +0 -1
  415. package/apps/pwa/out/_next/static/chunks/1948.15f356b15a625597.js +0 -5
  416. package/apps/pwa/out/_next/static/chunks/2116-6429c188eb846ab8.js +0 -1
  417. package/apps/pwa/out/_next/static/chunks/224-e7be8f762fe74986.js +0 -1
  418. package/apps/pwa/out/_next/static/chunks/2549-89c518a4c8ed4d00.js +0 -1
  419. package/apps/pwa/out/_next/static/chunks/2957-96ffab3d521fb08f.js +0 -1
  420. package/apps/pwa/out/_next/static/chunks/3857-995ea9f5ef33d71e.js +0 -1
  421. package/apps/pwa/out/_next/static/chunks/5360-be1f1d8f9fcc9755.js +0 -1
  422. package/apps/pwa/out/_next/static/chunks/5755-ea7ed88eb956f47b.js +0 -1
  423. package/apps/pwa/out/_next/static/chunks/5977-94ed6f78e9814b2b.js +0 -1
  424. package/apps/pwa/out/_next/static/chunks/7748-6e51bfe927019f5c.js +0 -25
  425. package/apps/pwa/out/_next/static/chunks/9247-c1753a059e7bac08.js +0 -1
  426. package/apps/pwa/out/_next/static/chunks/a9f2b54d-33c0689b70ed8cf3.js +0 -1
  427. package/apps/pwa/out/_next/static/chunks/app/bots/page-7a852956c74015a3.js +0 -1
  428. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c5a5c621be0e04ae.js +0 -1
  429. package/apps/pwa/out/_next/static/chunks/app/design-check/page-7c058069c5e7fa63.js +0 -1
  430. package/apps/pwa/out/_next/static/chunks/app/editor/page-dc5da0b8a2edb8a4.js +0 -1
  431. package/apps/pwa/out/_next/static/chunks/app/inside/page-ed4a6f799f005d09.js +0 -1
  432. package/apps/pwa/out/_next/static/chunks/app/intake/page-9cd565005b93aca6.js +0 -1
  433. package/apps/pwa/out/_next/static/chunks/app/layout-55f0f40c6db95f15.js +0 -1
  434. package/apps/pwa/out/_next/static/chunks/app/live/page-474cb5888ea0e8f3.js +0 -1
  435. package/apps/pwa/out/_next/static/chunks/app/market/page-9ca21f9ad3208a61.js +0 -1
  436. package/apps/pwa/out/_next/static/chunks/app/not-found-a9c2cfa8dda922a5.js +0 -1
  437. package/apps/pwa/out/_next/static/chunks/app/observatory/page-6da35144878feb6d.js +0 -1
  438. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-f6055495e9ed7ea8.js +0 -1
  439. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-25204694fa9984a5.js +0 -1
  440. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-a60e035f151d84d3.js +0 -1
  441. package/apps/pwa/out/_next/static/chunks/app/outputs/page-189c587f36874538.js +0 -1
  442. package/apps/pwa/out/_next/static/chunks/app/page-c56634bde705a65d.js +0 -1
  443. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a8d2fe0c669e0de4.js +0 -1
  444. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c26fa10aac6c21c4.js +0 -1
  445. package/apps/pwa/out/_next/static/chunks/app/setup/page-68793c6e10331d66.js +0 -1
  446. package/apps/pwa/out/_next/static/chunks/app/showroom/page-d81c07a7b4f618ae.js +0 -1
  447. package/apps/pwa/out/_next/static/chunks/app/tasks/page-be1c4e8697f22360.js +0 -1
  448. package/apps/pwa/out/_next/static/chunks/app/today/page-a4717e2c4bf7a28f.js +0 -1
  449. package/apps/pwa/out/_next/static/chunks/app/trace/page-0fd895fab9b62c1b.js +0 -1
  450. package/apps/pwa/out/_next/static/chunks/app/vault/page-8b6c1454a8e8f306.js +0 -1
  451. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-c6e4364d9de8f717.js +0 -1
  452. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-0506a1e0e4bdb2f5.js +0 -1
  453. package/apps/pwa/out/_next/static/chunks/webpack-c260571513bf43c2.js +0 -1
  454. package/apps/pwa/out/_next/static/css/c23d959d3ee15e57.css +0 -1
  455. /package/apps/pwa/out/_next/static/{Bam1YziK2iH9bN4K0utGk → aBi6EyMtLsrl7J8eH4kF7}/_ssgManifest.js +0 -0
  456. /package/skills/project-onboarding/{skill.md → SKILL.md} +0 -0
@@ -38,8 +38,12 @@
38
38
  # (파일 이름은 RFC 어휘를 남겨 둔다 — 사람이 찾는 이름과 조인 키가 다를 수 있다.)
39
39
  graph_id: self-implement
40
40
  version: 1
41
- entry_node: author
42
- terminal_nodes: [merge]
41
+ # ⭐ HARNESS-FULL-GRAPH (0.2.21 · 대표 10-08) — 입구부터 회수까지 «여정 전체»가 노드다.
42
+ # 📄 내부 문서 `RFC-harness-full-journey-as-graph-2026-10-08` · 코드 = src/self-dev/graph-journey-nodes.ts
43
+ # ⛔ 여정 노드(intake … stopped)의 id 는 원장·라이브 그래프 화면의 조인 키다 — 바꾸지 마라.
44
+ # 🔀 분기는 «데이터»다(`on:` 상태 키 ⊕ `map:` 값→노드) — 기본 = 풀세트, 환경(substrate·freeze·queue)이 일부를 건너뛴다.
45
+ entry_node: intake
46
+ terminal_nodes: [cleanup, stopped]
43
47
 
44
48
  # Runner-provided inputs are declared here so contract-flow can distinguish them from undeclared gaps.
45
49
  runner_inputs: [ask_text, goal, worktree, branch, review-intent, head-sha, base-branch]
@@ -61,8 +65,13 @@ runner_inputs: [ask_text, goal, worktree, branch, review-intent, head-sha, base-
61
65
  # 🔑 ⇒ ***여기 적은 도구 권한은 「선언」이고 「제한」이 아니다.*** 자식의 실제 권한은 코드가 정한다.
62
66
  # ⛔ 그러니 이 칸을 좁혀 「자식이 그 도구를 못 쓴다」고 읽지 마라 — 지금은 안 그렇다.
63
67
  # 🔎 반증: rg -n "readonly contract" src/self-implement/graph-templates.ts (⇒ 0건이면 여전히 그렇다)
68
+ # 🧩 `group:` = 나중에 `graphs/units/*.yaml` 로 들어 올릴 «한 노드로 부르는 부분 그래프» 단위(대표 10-08).
69
+ # entry · dispatch · author · dispatch-pod · build · verify · land · recover · end
70
+ # ⛔ 지금 파서는 이 칸을 «읽지 않는다»(무시) — 단위 호출은 0.2.22(RFC §6). 묶음은 «위치»가 아니라 이 태그로 정한다
71
+ # (오버레이가 /nodes/<번호> 로 가리켜 노드를 재배열할 수 없다).
64
72
  nodes:
65
73
  - node_id: author
74
+ group: author
66
75
  kind: agent
67
76
  recipe: goal-author
68
77
  max_visits: 2
@@ -74,6 +83,7 @@ nodes:
74
83
  outputs: [goal_path, goal_id, goal_type, grounding_context]
75
84
 
76
85
  - node_id: plan
86
+ group: author
77
87
  kind: agent
78
88
  recipe: harness-plan-rfc
79
89
  max_visits: 2
@@ -85,6 +95,7 @@ nodes:
85
95
  outputs: [rfc_path, markdown, arcs, open_questions]
86
96
 
87
97
  - node_id: decompose
98
+ group: author
88
99
  kind: judge
89
100
  recipe: fabric-decompose-adapter
90
101
  max_visits: 12
@@ -96,6 +107,7 @@ nodes:
96
107
  outputs: [pieces, ordering, depends_on_edges, hot_path_edges, omitted_goal_count]
97
108
 
98
109
  - node_id: implement
110
+ group: build
99
111
  kind: agent
100
112
  recipe: headless-goal-loop # seams.implement → 자식 PTY
101
113
  max_visits: 12
@@ -109,6 +121,7 @@ nodes:
109
121
  outputs: [diff, summary, changed-files]
110
122
 
111
123
  - node_id: gate
124
+ group: verify
112
125
  kind: gate
113
126
  recipe: gate-baseline # 변경 파일 «범위» · 새 회귀만
114
127
  max_visits: 11
@@ -122,6 +135,7 @@ nodes:
122
135
  outputs: [passed, gate-log, reflect-gate-facts]
123
136
 
124
137
  - node_id: review
138
+ group: verify
125
139
  kind: judge
126
140
  recipe: pr-reviewer # agent-substrate/pr-reviewer
127
141
  max_visits: 11
@@ -135,6 +149,7 @@ nodes:
135
149
  outputs: [verdict, must-fix, should-fix, review-summary]
136
150
 
137
151
  - node_id: rework
152
+ group: verify
138
153
  kind: agent
139
154
  recipe: headless-goal-loop # 같은 루프의 다음 라운드
140
155
  max_visits: 10
@@ -148,6 +163,7 @@ nodes:
148
163
  outputs: [diff, summary]
149
164
 
150
165
  - node_id: main-sync
166
+ group: land
151
167
  kind: git
152
168
  recipe: seams-git-merge-main # LLM 충돌해결 포함
153
169
  max_visits: 2
@@ -159,6 +175,7 @@ nodes:
159
175
  outputs: [synced, conflicts]
160
176
 
161
177
  - node_id: regate
178
+ group: land
162
179
  kind: gate
163
180
  recipe: gate-baseline # 충돌해결 «뒤» 재-gate
164
181
  max_visits: 2
@@ -170,6 +187,7 @@ nodes:
170
187
  outputs: [passed, gate-log]
171
188
 
172
189
  - node_id: open-pr
190
+ group: land
173
191
  kind: git
174
192
  recipe: seams-gh-open-pr
175
193
  # 📏 실측 2026-09-08 (원장 30일 · 전 우주 · 걸음 191개 소급 계산):
@@ -185,6 +203,7 @@ nodes:
185
203
  outputs: [pr-number, pr-url]
186
204
 
187
205
  - node_id: merge
206
+ group: land
188
207
  kind: git
189
208
  recipe: seams-gh-merge-squash
190
209
  # 📏 실측 2026-09-08 (원장 30일 · 전 우주 · 걸음 191개 소급 계산):
@@ -199,6 +218,176 @@ nodes:
199
218
  tools: gh-pr-merge
200
219
  outputs: [merged]
201
220
 
221
+ # ⛔ 여정 노드는 «목록 끝»에 둔다 — 오버레이가 JSON 포인터(/nodes/<번호>)로 노드를 가리킨다(rework-patient). 앞에 끼우면 번호가 밀린다.
222
+ # ───────── 여정 앞단: 입구 → 대기열 → 발사 관문 → 배치 ─────────
223
+ - node_id: intake
224
+ group: entry
225
+ kind: observe
226
+ recipe: harness-entrance # src/harness/harness-cli-command.ts (say · ask · TUI /harness)
227
+ max_visits: 1
228
+ terminal_stages: []
229
+ contract:
230
+ inputs: [ask_text]
231
+ tools: none
232
+ outputs: [entrance, journey_key]
233
+
234
+ - node_id: queue
235
+ group: entry
236
+ kind: gate
237
+ recipe: harness-queue # src/harness/harness-queue.ts (directSay 플래그 · 기본 끔 → 건너뜀)
238
+ max_visits: 1
239
+ terminal_stages: []
240
+ contract:
241
+ inputs: [entrance, seat]
242
+ tools: queue-write
243
+ outputs: [queue_item, queue_outcome]
244
+
245
+ - node_id: launch-gate
246
+ group: entry
247
+ kind: gate
248
+ recipe: pre-launch-gate # harness-cli-command.ts preLaunchGate (예산 · 같은 골 활성 런)
249
+ max_visits: 1
250
+ terminal_stages: []
251
+ contract:
252
+ inputs: [goal_id, budget]
253
+ tools: read-only
254
+ outputs: [launch_decision]
255
+
256
+ - node_id: dispatch
257
+ group: dispatch
258
+ kind: judge
259
+ recipe: harness-substrate-select # resolveLaunchSubstrate → substrate = local | pod
260
+ max_visits: 2
261
+ terminal_stages: []
262
+ contract:
263
+ inputs: [launch_decision]
264
+ tools: read-only
265
+ outputs: [substrate]
266
+
267
+ # ───────── Pod 배치 (substrate == pod 일 때만 — local 은 건너뛴다) ─────────
268
+ - node_id: pool-admit
269
+ group: dispatch-pod
270
+ kind: gate
271
+ recipe: pod-pool-admission # src/task-orchestrator/surfaces/self-implement-pod.ts (입장 · 멤버 슬롯 · 메모리 등급)
272
+ max_visits: 4
273
+ terminal_stages: []
274
+ contract:
275
+ inputs: [substrate, memory_tier]
276
+ tools: pod-lease
277
+ outputs: [pool_member]
278
+
279
+ - node_id: image-sync
280
+ group: dispatch-pod
281
+ kind: gate
282
+ recipe: pod-pool-image-sync # src/task-orchestrator/surfaces/pod-pool.ts syncPoolImages (멤버별 · pack 한 번)
283
+ max_visits: 4
284
+ terminal_stages: []
285
+ contract:
286
+ inputs: [pool_member]
287
+ tools: image-ship
288
+ outputs: [image_current]
289
+
290
+ - node_id: credential-refresh
291
+ group: dispatch-pod
292
+ kind: gate
293
+ recipe: pod-credential-prerefresh # self-implement-pod.ts podCodexCredentialWithPrerefresh
294
+ max_visits: 4
295
+ terminal_stages: []
296
+ contract:
297
+ inputs: [pool_member]
298
+ tools: credential-refresh
299
+ outputs: [usable_accounts]
300
+
301
+ # ───────── 착지: 동결 검사 → (보류) → 병합 → 회수 ─────────
302
+ - node_id: freeze-check
303
+ group: land
304
+ kind: gate
305
+ recipe: landing-freeze-admission # src/self-implement/frozen-merges.ts admitLandingMerge (병합 직전 한 곳)
306
+ max_visits: 4
307
+ terminal_stages: []
308
+ contract:
309
+ inputs: [pr-number]
310
+ tools: read-only
311
+ outputs: [freeze]
312
+
313
+ - node_id: hold
314
+ group: land
315
+ kind: hitl
316
+ recipe: frozen-merge-queue # frozen-merges.ts queueFrozenMerge → sweepFrozenMerges 가 해제 뒤 재개
317
+ max_visits: 4
318
+ terminal_stages: []
319
+ contract:
320
+ inputs: [pr-number, head-sha]
321
+ tools: queue-write
322
+ outputs: [held]
323
+
324
+ - node_id: cleanup
325
+ group: land
326
+ kind: git
327
+ recipe: post-merge-cleanup # src/self-implement/orchestrator.ts (워크트리 ⊕ 브랜치 회수)
328
+ max_visits: 1
329
+ terminal_stages: []
330
+ contract:
331
+ inputs: [worktree, branch]
332
+ tools: git-write
333
+ outputs: [cleaned]
334
+
335
+ # ───────── 실패 쪽: 결과 해석 → 수확 → heal → 다음 한 수 ─────────
336
+ - node_id: result-parse
337
+ group: recover
338
+ kind: observe
339
+ recipe: pod-failure-reason # src/task-orchestrator/surfaces/pod-failure-reason.ts
340
+ max_visits: 4
341
+ terminal_stages: []
342
+ contract:
343
+ inputs: [pod_log]
344
+ tools: read-only
345
+ outputs: [failure_reason]
346
+
347
+ - node_id: salvage
348
+ group: recover
349
+ kind: git
350
+ recipe: salvage-branch # salvage/si-task-<job>/… (Pod Job 이 push · salvage-branches.ts 가 읽는다)
351
+ max_visits: 4
352
+ terminal_stages: []
353
+ contract:
354
+ inputs: [worktree]
355
+ tools: git-write
356
+ outputs: [salvage_ref]
357
+
358
+ - node_id: heal
359
+ group: recover
360
+ kind: judge
361
+ recipe: heal-intake # src/self-implement/heal-intake.ts (호스트에서만)
362
+ max_visits: 4
363
+ terminal_stages: []
364
+ contract:
365
+ inputs: [failure_reason, salvage_ref]
366
+ tools: read-only
367
+ outputs: [heal_signature]
368
+
369
+ - node_id: next-move
370
+ group: recover
371
+ kind: judge
372
+ recipe: task-agent-judge # src/task-agent/judge.ts (판단부 → 실행부)
373
+ max_visits: 4
374
+ terminal_stages: []
375
+ contract:
376
+ inputs: [heal_signature]
377
+ tools: read-only
378
+ outputs: [next_action]
379
+
380
+ - node_id: stopped
381
+ group: end
382
+ kind: observe
383
+ recipe: journey-stopped # 거절·포기 — 종결
384
+ max_visits: 1
385
+ terminal_stages: []
386
+ contract:
387
+ inputs: []
388
+ tools: none
389
+ outputs: []
390
+
202
391
  # ═══════════════════════════════════════════════════════════════════════
203
392
  # 엣지 — ⛔ 출처는 «코드 선언 ⊕ 원장 실측» 둘 다다. 어느 하나만 보면 틀린다.
204
393
  # 📏 2026-09-08 실측 (pipeline-traversal-shadow 182 걸음 · 판정 함수가 «실제로 본» 것):
@@ -207,14 +396,83 @@ nodes:
207
396
  # gate→main-sync · gate→open-pr · review→open-pr
208
397
  # 🔑 그래서 엣지마다 `observed` 를 «값으로» 적는다 — 「선언했다」와 「돈다」를 가른다.
209
398
  edges:
399
+ # ───── 여정 앞단 — 분기는 «데이터»(on/map). 값은 코드가 낸다(RFC §4.3 ⑵) ─────
400
+ - from: intake
401
+ on: queue
402
+ map:
403
+ queued: queue # harness.queue.directSay 켬 ⊕ 자리 있음
404
+ direct: launch-gate # 기본(플래그 끔) — 대기열을 건너뛴다
405
+
406
+ - from: queue
407
+ on: queue_outcome
408
+ map:
409
+ launched: launch-gate # 대기열이 발사한 자식이 다시 intake 를 밟는다(queueLaunchId 로 잇는다)
410
+ waiting: stopped # 이 프로세스는 여기서 끝난다(발사는 대기열 tick 의 몫)
411
+ refused: stopped # 같은 요청이 이미 대기열에 있다
412
+
413
+ - from: launch-gate
414
+ on: outcome
415
+ map:
416
+ pass: dispatch
417
+ refuse: stopped
418
+
419
+ - from: dispatch
420
+ to: author
421
+
210
422
  - from: author
211
423
  to: plan
212
424
 
213
425
  - from: plan
214
426
  to: decompose
215
427
 
428
+ # ⭐ 실행 칸(substrate)이 «Pod 쪽 세 노드»를 켜고 끈다 — local 은 곧장 구현.
216
429
  - from: decompose
217
- to: implement
430
+ on: substrate
431
+ map:
432
+ local: implement
433
+ pod: pool-admit
434
+
435
+ - from: pool-admit
436
+ on: outcome
437
+ map:
438
+ admitted: image-sync
439
+ refused: stopped
440
+
441
+ - from: image-sync
442
+ to: credential-refresh
443
+
444
+ - from: credential-refresh
445
+ on: outcome
446
+ map:
447
+ usable: implement
448
+ exhausted: stopped
449
+
450
+ # 실패 쪽 — Pod 구현이 rc≠0 이면 결과 해석으로.
451
+ - from: implement
452
+ on: pod_result
453
+ map:
454
+ failed: result-parse
455
+
456
+ - from: result-parse
457
+ to: salvage
458
+
459
+ # ⚠️ heal 은 실패 사건 «접수»다 — 호스트에서만(Pod 안에서는 시작 안 함 · POD-RESULT-PARSE).
460
+ - from: salvage
461
+ to: heal
462
+
463
+ - from: heal
464
+ to: next-move
465
+
466
+ # 출구 라벨 = task-agent 판단부의 수(TaskMove · src/task-agent/judge.ts). 관측 배선은 0.2.22(판단이 카드 단위라 런 조인 먼저).
467
+ - from: next-move
468
+ on: move
469
+ map:
470
+ narrow-relaunch: dispatch
471
+ salvage-relaunch: dispatch
472
+ alternative: dispatch
473
+ wait-retry: dispatch
474
+ decision-card: stopped
475
+ wait: stopped
218
476
 
219
477
  - from: implement
220
478
  to: gate
@@ -264,6 +522,20 @@ edges:
264
522
  to: open-pr
265
523
  observed: 80
266
524
 
525
+ # ⭐ HARNESS-FULL-GRAPH — 코드 간선 open-pr→merge 사이에 «동결 검사»가 늘 끼어 있었다(병합 직전 한 곳).
267
526
  - from: open-pr
268
- to: merge
269
- observed: 80
527
+ to: freeze-check
528
+ observed: 80 # 옛 open-pr→merge 관측 — 그 사이에 동결 검사가 늘 있었다
529
+
530
+ - from: freeze-check
531
+ on: freeze
532
+ map:
533
+ open: merge
534
+ frozen: hold
535
+ taken: stopped # 다른 착지자(재개 sweep)가 그 PR 을 쥐었다
536
+
537
+ - from: hold
538
+ to: freeze-check # 해제 뒤 재검사
539
+
540
+ - from: merge
541
+ to: cleanup
@@ -10,3 +10,6 @@ audit:
10
10
  record:
11
11
  command: 'bun scripts/test-diet/node.ts record'
12
12
  timeout_ms: 300000
13
+ main-failures:
14
+ command: 'bun scripts/test-diet/node.ts main-failures'
15
+ timeout_ms: 2400000
@@ -14,9 +14,11 @@ nodes:
14
14
  - { node_id: pick, kind: judge, recipe: 'cmd:pick', max_visits: 1 }
15
15
  - { node_id: measure, kind: gate, recipe: 'cmd:measure', max_visits: 1 }
16
16
  - { node_id: record, kind: judge, recipe: 'cmd:record', max_visits: 1 }
17
+ - { node_id: main-failures, kind: judge, recipe: 'cmd:main-failures', max_visits: 1 }
17
18
  - { node_id: done, kind: gate, max_visits: 1 }
18
19
  - { node_id: failed, kind: gate, max_visits: 1 }
19
20
  edges:
20
21
  - { from: pick, on: outcome, map: { ok: measure, fail: failed, error: failed } }
21
22
  - { from: measure, on: outcome, map: { ok: record, fail: failed, error: failed } }
22
- - { from: record, on: outcome, map: { ok: done, fail: failed, error: failed } }
23
+ - { from: record, on: outcome, map: { ok: main-failures, fail: failed, error: failed } }
24
+ - { from: main-failures, on: outcome, map: { ok: done, fail: failed, error: failed } }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "elanous",
3
3
  "mcpName": "io.github.ElanvitalAI/elanous",
4
- "version": "0.2.20",
4
+ "version": "0.2.22",
5
5
  "description": "Self-healing coding harness where eyes, hands, and memory all turn on one sentence — it authors its own goals, implements them in isolated worktrees, and reviews its own work.",
6
6
  "license": "Apache-2.0",
7
7
  "author": "Elanvital AI",
@@ -240,15 +240,42 @@ lsof_fd1() {
240
240
  return 0
241
241
  }
242
242
 
243
+ # 🐧 lsof 가 없는 리눅스(게이트 Pod 이미지 · 0.2.20 컷 실측)에서는 /proc/<pid>/fd/1 을 읽어
244
+ # lsof -Ftn 과 «같은 모양»(t<type>\nn<name>)으로 낸다 — 아래 판정 표를 그대로 쓴다.
245
+ # ⛔ 못 읽으면(죽은 pid·권한) 1 을 돌려 「모름」으로 끝낸다.
246
+ proc_fd1() {
247
+ local pid="$1" target
248
+ target=$(readlink "/proc/$pid/fd/1" 2>/dev/null) || return 1
249
+ [ -n "$target" ] || return 1
250
+ case "$target" in
251
+ pipe:*) printf 'tPIPE\nn%s\n' "$target" ;;
252
+ socket:*) printf 'tunix\nn%s\n' "$target" ;;
253
+ *)
254
+ if [ -c "$target" ]; then printf 'tCHR\nn%s\n' "$target"
255
+ elif [ -f "$target" ]; then printf 'tREG\nn%s\n' "$target"
256
+ else printf 'tunknown\nn%s\n' "$target"
257
+ fi ;;
258
+ esac
259
+ return 0
260
+ }
261
+
243
262
  delivery_of() {
244
263
  local pid="$1" out t n
245
264
  case "$pid" in
246
265
  ''|*[!0-9]*) printf '⚠️ «못 쟀다»(감시자 pid 를 «증명하지 못했다») — 「정상」이 아니라 «모름»이다'; return 0 ;;
247
266
  esac
248
- command -v lsof >/dev/null 2>&1 || { printf '⚠️ «못 쟀다»(lsof 없음) — 「정상」이 아니라 «모름»이다'; return 0; }
249
- if ! out=$(lsof_fd1 "$pid"); then
250
- printf '⚠️ «못 쟀다»(lsof 가 %s틱 안에 안 끝나 죽였다) — 「정상」이 아니라 «모름»이다' "$LSOF_WAIT_TICKS"
251
- return 0
267
+ if command -v lsof >/dev/null 2>&1; then
268
+ if ! out=$(lsof_fd1 "$pid"); then
269
+ printf '⚠️ «못 쟀다»(lsof 가 %s틱 안에 안 끝나 죽였다) — 「정상」이 아니라 «모름»이다' "$LSOF_WAIT_TICKS"
270
+ return 0
271
+ fi
272
+ elif command -v readlink >/dev/null 2>&1 && [ -d /proc/self/fd ]; then
273
+ if ! out=$(proc_fd1 "$pid"); then
274
+ printf '⚠️ «못 쟀다»(/proc/%s/fd/1 을 못 읽었다 · lsof 없음) — 「정상」이 아니라 «모름»이다' "$pid"
275
+ return 0
276
+ fi
277
+ else
278
+ printf '⚠️ «못 쟀다»(lsof 없음) — 「정상」이 아니라 «모름»이다'; return 0
252
279
  fi
253
280
  t=$(printf '%s\n' "$out" | sed -n 's/^t//p' | head -1)
254
281
  n=$(printf '%s\n' "$out" | sed -n 's/^n//p' | head -1)
@@ -13,6 +13,7 @@ import {
13
13
  } from '../src/autopilot/discovery/doc-lint.js';
14
14
  import { parseIndexLinks } from '../src/autopilot/discovery/doc-inventory.js';
15
15
  import { execFileSync } from 'node:child_process';
16
+ import { runGitCommand } from '../src/git-fs/runner.js';
16
17
  import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
17
18
  import { basename, join, relative } from 'node:path';
18
19
  import { sourceIdentifierInventory, inlineCodeIdentifiers } from '../src/autopilot/discovery/source-identifiers.js';
@@ -80,7 +81,9 @@ const readText = (relPath: string): string | null => { try { return readFileSync
80
81
  // 전부 「못 읽음」이 되어 이 규칙이 통째로 잡음이 된다. 그래서 파일명 → repo 경로를 «한 번» 만든다.
81
82
  // ⛔ 같은 파일명이 둘 이상이면 «해석하지 않는다** — 틀린 파일을 대면 「어긋남」이 거짓으로 난다.
82
83
  const sourcePathsByBasename = new Map<string, string | null>();
83
- for (const relPath of execFileSync('git', ['ls-files', '*.ts', '*.tsx'], { cwd: repoRoot, encoding: 'utf-8' }).split('\n')) {
84
+ const lsFiles = runGitCommand(repoRoot, ['ls-files', '*.ts', '*.tsx'], { encoding: 'utf-8', maxBuffer: 64 * 1024 * 1024 });
85
+ if (lsFiles.status !== 0) throw new Error(`git ls-files failed: ${lsFiles.stderr.trim() || `rc=${lsFiles.status}`}`);
86
+ for (const relPath of lsFiles.stdout.split('\n')) {
84
87
  if (relPath === '') continue;
85
88
  const base = basename(relPath);
86
89
  sourcePathsByBasename.set(base, sourcePathsByBasename.has(base) ? null : relPath);
@@ -479,6 +479,75 @@ function collectChannel(anchor: Anchor, advance: boolean): Cell<{ pr: number; co
479
479
 
480
480
  // ── 관문표 ────────────────────────────────
481
481
  export type Verdict = "pass" | "fail" | "unknown";
482
+
483
+ /** TECHBLOG1 판정은 호출자가 제공한 근거만 읽는다. 스냅숏·출력·원장에는 연결하지 않는다. */
484
+ export interface Techblog1Entry {
485
+ readonly installment: number;
486
+ readonly publishedAt: string;
487
+ }
488
+
489
+ export interface Techblog1Candidate {
490
+ readonly installment: number;
491
+ readonly publishAt: string;
492
+ readonly measurements: readonly { readonly value: number; readonly source: string; readonly measuredAt: string }[];
493
+ readonly exposure: {
494
+ readonly publicBeforePublish: boolean;
495
+ readonly approved: boolean;
496
+ readonly revealsProtectedDetails: boolean;
497
+ readonly attorneyReviewed: boolean;
498
+ };
499
+ }
500
+
501
+ export interface Techblog1Verdict {
502
+ readonly verdict: Verdict;
503
+ readonly reasons: readonly string[];
504
+ }
505
+
506
+ /** 순번은 1부터 빠짐없이, 게시 간격은 직전 게시에서 48시간 이상이어야 한다. */
507
+ export function evaluateTechblog1(
508
+ published: readonly Techblog1Entry[],
509
+ candidate: Techblog1Candidate,
510
+ ): Techblog1Verdict {
511
+ const reasons: string[] = [];
512
+ const validPublicationDate = (iso: string) => {
513
+ if (typeof iso !== "string") return false;
514
+ const match = /^(\d{4})-(\d{2})-(\d{2})T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-](?:0\d|1\d|2[0-3]):[0-5]\d)$/.exec(iso);
515
+ if (!match || !Number.isFinite(Date.parse(iso))) return false;
516
+ const day = new Date(`${match[1]}-${match[2]}-${match[3]}T00:00:00Z`);
517
+ return day.getUTCFullYear() === Number(match[1])
518
+ && day.getUTCMonth() + 1 === Number(match[2])
519
+ && day.getUTCDate() === Number(match[3]);
520
+ };
521
+ const history = [...published].sort((a, b) => a.installment - b.installment);
522
+ if (history.some((entry, index) => entry.installment !== index + 1 || !validPublicationDate(entry.publishedAt))
523
+ || candidate.installment !== history.length + 1) {
524
+ reasons.push("TECHBLOG1 연재 순서 또는 이전 게시 시각이 유효하지 않음");
525
+ }
526
+ if (history.some((entry, index) => index > 0 && validPublicationDate(entry.publishedAt)
527
+ && validPublicationDate(history[index - 1]!.publishedAt)
528
+ && Date.parse(entry.publishedAt) - Date.parse(history[index - 1]!.publishedAt) < 48 * 60 * 60 * 1000)) {
529
+ reasons.push("TECHBLOG1 이전 연재의 이틀 간격이 지켜지지 않음");
530
+ }
531
+ if (!validPublicationDate(candidate.publishAt)) {
532
+ reasons.push("TECHBLOG1 게시 시각을 확인할 수 없음");
533
+ } else if (history.length > 0 && validPublicationDate(history[history.length - 1]!.publishedAt)
534
+ && Date.parse(candidate.publishAt) - Date.parse(history[history.length - 1]!.publishedAt) < 48 * 60 * 60 * 1000) {
535
+ reasons.push("TECHBLOG1 직전 게시에서 이틀이 지나지 않음");
536
+ }
537
+ if (candidate.measurements.length === 0 || candidate.measurements.some((m) =>
538
+ !Number.isFinite(m.value) || !m.source.trim() || !validPublicationDate(m.measuredAt)
539
+ || (validPublicationDate(candidate.publishAt) && Date.parse(m.measuredAt) > Date.parse(candidate.publishAt)))) {
540
+ reasons.push("TECHBLOG1 실측 수치·출처·측정 시각이 확인되지 않음");
541
+ }
542
+ if (candidate.exposure.revealsProtectedDetails && !candidate.exposure.attorneyReviewed) {
543
+ reasons.push("TECHBLOG1 보호 대상 상세는 변리사 검토 전 노출 불가");
544
+ }
545
+ if (candidate.exposure.publicBeforePublish && !candidate.exposure.approved) {
546
+ reasons.push("TECHBLOG1 공개 전 노출 승인 없음");
547
+ }
548
+ return { verdict: reasons.length === 0 ? "pass" : "fail", reasons };
549
+ }
550
+
482
551
  export interface Gate {
483
552
  phase: string;
484
553
  name: string;
@@ -85,7 +85,8 @@ export function planSnapshot(root: string, tier: Tier): PlanItem[] {
85
85
 
86
86
  const sha256 = (path: string) => createHash('sha256').update(readFileSync(path)).digest('hex');
87
87
 
88
- /** Consistent copy: SQLite through `.backup` (never a live-file copy), other files byte-for-byte. */
88
+ /** Consistent copy: SQLite through `VACUUM INTO` (never a live-file copy), other files byte-for-byte. */
89
+ export const SQLITE_SNAPSHOT_TIMEOUT_MS = 600_000;
89
90
  /** Host-specific settings that must never ride a replicated `config.json` (OP 10-04 12:02 · drill step 5:
90
91
  * mbp's `hq.hostName=mbp` reached node-b's promoted universe and made node-b call itself mbp). */
91
92
  export const HOST_LOCAL_CONFIG_KEYS = ['hq'] as const;
@@ -105,8 +106,11 @@ export function snapshotItem(root: string, out: string, item: PlanItem, sqlite3
105
106
  const dest = join(out, item.rel);
106
107
  mkdirSync(dirname(dest), { recursive: true });
107
108
  if (item.kind === 'sqlite') {
108
- const r = spawnSync(sqlite3, [join(root, item.rel), `.backup '${dest.replace(/'/g, "''")}'`], { encoding: 'utf8' });
109
- if (r.status !== 0) throw new Error(`sqlite backup failed: ${item.rel}: ${(r.stderr || '').trim()}`);
109
+ // `VACUUM INTO` copies one read transaction. The CLI `.backup` restarts from page 1 whenever another connection
110
+ // writes the source — on a busy logs.db (written every second) it ran 85+ minutes without finishing (10-09 00:43 obs tier).
111
+ rmSync(dest, { force: true });
112
+ const r = spawnSync(sqlite3, [join(root, item.rel), `VACUUM INTO '${dest.replace(/'/g, "''")}'`], { encoding: 'utf8', timeout: SQLITE_SNAPSHOT_TIMEOUT_MS });
113
+ if (r.status !== 0) throw new Error(`sqlite backup failed: ${item.rel}: ${(r.error ? String(r.error) : (r.stderr || '').trim()) || `rc=${r.status}`}`);
110
114
  } else if (item.rel === 'config.json') {
111
115
  const original = readFileSync(join(root, item.rel), 'utf8');
112
116
  const stripped = stripHostLocalConfig(original);
@@ -0,0 +1,11 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { compressConclusions, type ConclusionBatch } from '../src/knowledge/conclusion-compress.js';
3
+
4
+ /** bun scripts/knowledge-compress.ts <batch.json> (UTC day, version, explicitly verified conclusions and full originals). */
5
+ if (import.meta.main) {
6
+ const path = process.argv[2];
7
+ if (!path || process.argv.length !== 3) throw new Error('usage: bun scripts/knowledge-compress.ts <batch.json>');
8
+ const batch = JSON.parse(readFileSync(path, 'utf8')) as ConclusionBatch;
9
+ const receipt = compressConclusions(batch);
10
+ console.log(JSON.stringify(receipt));
11
+ }
@@ -1,10 +1,11 @@
1
1
  import { readFileSync, writeFileSync } from 'node:fs';
2
- import { resolve } from 'node:path';
2
+ import { basename, resolve } from 'node:path';
3
3
  import { FEATURE_MATURITY } from '../../src/maturity/feature-maturity.js';
4
4
  import type { ChecklistItem } from '../../src/release-loop/checklist.js';
5
5
  import type { ReleaseSchedule } from '../../src/release-loop/release-schedule.js';
6
6
  import type { MergedRunLedgerQuery } from '../../src/self-implement/run-ledger.js';
7
7
  import { generateFeatureMap } from './generate-feature-map.js';
8
+ import { draftReleaseStory } from '../release-story/draft.js';
8
9
 
9
10
  const MAP = resolve(import.meta.dir, '../../docs/marketing/MAP-value-props-to-features.md');
10
11
  const AUTONOMY = new Set(['ORCH1', 'ORCH2', 'LOOP-LIVE1', 'AUTOQ-LOOP', 'AUTHOR-PAR', 'RUN-HELPER', 'FINISH-RATE']);
@@ -110,6 +111,22 @@ export function generateAxBrief(version: string, sources: AxBriefSources): strin
110
111
  ].join('\n');
111
112
  }
112
113
 
114
+ /** Derive the next release's internal brief from its ledgers and the RELEASE-STORY version-note draft.
115
+ * The release loop supplies its version, ledger sources and isolated story paths; the standalone CLI stays unchanged. */
116
+ export function generateNextVersionAxBrief(
117
+ nextVersion: string,
118
+ sources: AxBriefSources,
119
+ storyOptions: Omit<Parameters<typeof draftReleaseStory>[0], 'version'> = {},
120
+ ): string {
121
+ const brief = generateAxBrief(nextVersion, sources);
122
+ const story = draftReleaseStory({ ...storyOptions, version: nextVersion });
123
+ const announcementFile = story.files.find((file) => basename(file) === 'announcement.md');
124
+ const announcement = story.status === 'drafted' && announcementFile
125
+ ? readFileSync(announcementFile, 'utf8').replace(/^# [^\r\n]*\r?\n/, '').trim()
126
+ : '사용자 대상 변경 없음 — RELEASE-STORY 초안을 건너뜀';
127
+ return `${brief}\n## 5. 다음 판 변화·근거 (RELEASE-STORY 초안)\n\n> 공개 전 CMO 확인 필요 · 원천: release/next.md, 해당 판의 green 칸, 연결된 검증 소구점 원장\n\n${announcement}\n`;
128
+ }
129
+
113
130
  if (import.meta.main) {
114
131
  const args = process.argv.slice(2);
115
132
  const option = (name: string) => {
@@ -3,7 +3,7 @@ import { readFileSync, writeFileSync } from 'node:fs';
3
3
  import { resolve } from 'node:path';
4
4
  import { buildEvalPromptToolSurface, EVAL_PROMPT_TOOL_SURFACES, isEvalPromptToolSurface, resolveReproModelId, runEvalPrompt, type EvalPromptToolSurface } from '../src/eval-prompt-cli.js';
5
5
  import { getModelFamily } from '../src/models/prompts.js';
6
- import { resolveDefaultProvider } from '../src/llm.js';
6
+ import { NoLlmProviderAvailableError, resolveDefaultProvider } from '../src/llm.js';
7
7
  import { filterToolsByDeny } from '../src/tool-runtime/tool-deny.js';
8
8
  import { getUserConfig } from '../src/user-config.js';
9
9
  import { resolveObserveOnlyDecision, type ObserveOnlyDecision } from '../src/self-implement/observe-only.js';
@@ -80,8 +80,16 @@ function formatMachineLoad(load: MachineLoad): string {
80
80
 
81
81
  function authoritativeSurfaceToolNames(surface: EvalPromptToolSurface): string[] {
82
82
  const cfg = getUserConfig();
83
- const provider = resolveDefaultProvider();
84
- const modelFamily = getModelFamily(resolveReproModelId(undefined, provider.defaultModel));
83
+ // ⛔ 안전 관문(노출된 변이 툴)은 «provider 해석보다 먼저» 닫혀야 한다 — 자격이 없는 기계(게이트 Pod)에서
84
+ // provider 해석이 먼저 던지면 관문이 안내 대신 「No LLM provider」로 끝났다(0.2.20 컷 pod-7·pod-22).
85
+ // provider 가 없으면 러너의 마지막 기본 모델로 서피스를 재서 관문을 그대로 판정한다(런은 어차피 못 돈다).
86
+ let providerDefaultModel: string | undefined;
87
+ try {
88
+ providerDefaultModel = resolveDefaultProvider().defaultModel;
89
+ } catch (error) {
90
+ if (!(error instanceof NoLlmProviderAvailableError)) throw error;
91
+ }
92
+ const modelFamily = getModelFamily(resolveReproModelId(undefined, providerDefaultModel));
85
93
  const { specs } = buildEvalPromptToolSurface(surface, modelFamily, cfg);
86
94
  const tools = filterToolsByDeny(specs, cfg.chat.toolDeny) ?? specs;
87
95
  return tools.map((tool) => tool.name);