elanous 0.2.38 → 0.2.41

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 (712) hide show
  1. package/README.md +7 -7
  2. package/apps/pwa/out/404/index.html +1 -1
  3. package/apps/pwa/out/404.html +1 -1
  4. package/apps/pwa/out/_next/static/{RrjXTwz-urRAbChP1bX02 → GiOLWmt4MqDZePubBjA4Q}/_buildManifest.js +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1115.434ae2ecb0ad986d.js +149 -0
  6. package/apps/pwa/out/_next/static/chunks/1121.667cec0bcdbb3fdb.js +36 -0
  7. package/apps/pwa/out/_next/static/chunks/1178.1aa9cad0e7695427.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1197-54da59d250a6e476.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/{5203.51e5d8b5f1dcfe53.js → 1219.7e17964e0e7cd8e5.js} +3 -3
  10. package/apps/pwa/out/_next/static/chunks/1245.1cfd13b26dbd71d6.js +287 -0
  11. package/apps/pwa/out/_next/static/chunks/1494-f93046ff5c5a124d.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/1609.2b312797599b8e45.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1661.0dd330f3d89f73f3.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/167-0c121e4b47e0f9da.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1700.cdc2bf8cc685e221.js +90 -0
  16. package/apps/pwa/out/_next/static/chunks/1703-78e46acad29f3cfc.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/{7573.2376e13c9c21f1f8.js → 1765.679b29625c8e88d4.js} +2 -2
  18. package/apps/pwa/out/_next/static/chunks/{3528.e4b8ab70d339f965.js → 1800.f7ff51dc4978a958.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/1971-7efb628c471dc5a0.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/1999-8de7b7bb36801913.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2073.689dcb2680113d76.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2198-557d49184104d165.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/221-440ce67fa9f5c839.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/{8879.ac06755bcf3e44a1.js → 2263.e09b6edea33bad2d.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/2427-8ed8e98624cbd664.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2457-725c5827bc003795.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2491-2718b15a5ccb75a5.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2527-5c636a43c7cc5dde.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/2692-1027cb16fe4ccf49.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/2743.5d3f76948be32b34.js +41 -0
  31. package/apps/pwa/out/_next/static/chunks/2773.0e80b9d325fb5635.js +32 -0
  32. package/apps/pwa/out/_next/static/chunks/2873-0f3cb56c8e3528ea.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/{9fe1b809.738da85c8b17e3fb.js → 2fdf2931.b431eee4fb468bc3.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/{eaad0cba.771200940c529df7.js → 2fe2c302.41b517f88d6fe502.js} +1 -1
  35. package/apps/pwa/out/_next/static/chunks/3097.864e92bdaa2f4d15.js +79 -0
  36. package/apps/pwa/out/_next/static/chunks/3136-d6870ba63300a93e.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3173-0289113d434e83b7.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3230-49298c3b73ef2268.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/325-dd9208a1a0ab7ce4.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3283.528f430dd043fb4e.js +74 -0
  41. package/apps/pwa/out/_next/static/chunks/3295.cc8cb13b8f0dae1a.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/3688-86e3b88abf18cb3b.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3804-7220467a5473a8df.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/3808.3e1e247ce7bdf889.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{b7478fef.5917716286213fcc.js → 385e4574.e9886ab32759eda3.js} +3 -3
  46. package/apps/pwa/out/_next/static/chunks/3927.b5473ad109da44c5.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/3934-98ea94832e194796.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4133.2056bb4d78f621af.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4156.ba4de4a3664f04b4.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4297-239ca82f293faab0.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4320-dcc5a7734126f4c9.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4434.94b4c552a2d91e69.js +148 -0
  53. package/apps/pwa/out/_next/static/chunks/{8911.bf5e712acb25fb6c.js → 4527.a69f2894d1bc9f4a.js} +1 -1
  54. package/apps/pwa/out/_next/static/chunks/4579.03e4092f73950965.js +226 -0
  55. package/apps/pwa/out/_next/static/chunks/{5307.d7328020227880c2.js → 4667.97e31aa38c95c475.js} +4 -4
  56. package/apps/pwa/out/_next/static/chunks/{6142.913b44e260a3f925.js → 4702.4a4adc1f16d7c93b.js} +1 -1
  57. package/apps/pwa/out/_next/static/chunks/4815.481501c57b3568d9.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/487-d16e698ef14662d9.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/4888-7a38bf522c9cc6fe.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5034-30e429d6bb086881.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5040-35c494e60dadd97d.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/50c6ab1e.81a96e419350909d.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/5154.4b6a836179356f30.js +94 -0
  64. package/apps/pwa/out/_next/static/chunks/{8487.291666583bebe640.js → 5159.115f1c2ca471386c.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/5228-a8200df486278f2d.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/530.d26346e18089640a.js +115 -0
  67. package/apps/pwa/out/_next/static/chunks/5379.97af106d09566f69.js +8 -0
  68. package/apps/pwa/out/_next/static/chunks/{89d6c04f-6b8ab341748e468a.js → 53aeb4ee-51c92f8d683f5220.js} +1 -1
  69. package/apps/pwa/out/_next/static/chunks/{3291.f6c1005387d514bd.js → 5471.1e611302ed3a7c53.js} +2 -2
  70. package/apps/pwa/out/_next/static/chunks/5479-b6372e762719f92f.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/5534-699c5cbcbc96c5d7.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/{3086.fb14b60ce98b53d3.js → 5574.f35accf4f132b29d.js} +1 -1
  73. package/apps/pwa/out/_next/static/chunks/5701.9c4e8f250312eeee.js +24 -0
  74. package/apps/pwa/out/_next/static/chunks/{1632.7d87f998e714bede.js → 5744.b9415e18ad623100.js} +1 -1
  75. package/apps/pwa/out/_next/static/chunks/{5300.677c97e0393742e6.js → 5892.2526d962339662d8.js} +1 -1
  76. package/apps/pwa/out/_next/static/chunks/5937.c2df9e3447e1f667.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/5941.8210cc93c9202c0a.js +286 -0
  78. package/apps/pwa/out/_next/static/chunks/{7161-8f22db3ec5ed005e.js → 5947-135e26537d80a6b9.js} +3 -3
  79. package/apps/pwa/out/_next/static/chunks/{3124-561f7f037943cde2.js → 5964-7e21164a8f2cf0ce.js} +1 -1
  80. package/apps/pwa/out/_next/static/chunks/5975.4004f820ae3cecd5.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6142-7ccd48795d7abd55.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6160.bf9177b8c1bfb243.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6398.71ba0690c8027555.js +27 -0
  84. package/apps/pwa/out/_next/static/chunks/6492.2bd5c10edc1a064e.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/6552.a3840aa7da35ad68.js +62 -0
  86. package/apps/pwa/out/_next/static/chunks/6736.1e36d3ac5fa5e41d.js +24 -0
  87. package/apps/pwa/out/_next/static/chunks/6874.d5cf7eb8edb2cabe.js +2 -0
  88. package/apps/pwa/out/_next/static/chunks/6900.3ccbe069bdd4556a.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/71327eb4.add50b365f94bf3a.js +122 -0
  90. package/apps/pwa/out/_next/static/chunks/7136.deca3e3a2ddaa374.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7139-ee9f8ed2677a40b3.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{2415.738b777642a02233.js → 7191.fdc955f7d96064a4.js} +1 -1
  93. package/apps/pwa/out/_next/static/chunks/7423-e0aa5d9e2962120e.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7453.afc1ea7e05d56a8c.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7503-5e6a3d7fe67e4a0c.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/7761-476fd7bf768abd34.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/7975.eafb12097a0a9e62.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/{1026-44010f405704050c.js → 8050-9b364bdef8f71927.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/8152.64e253c35cccfaae.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/8190.620f0231b3924bcb.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/83184dcd-0ee6247ff41eb3f2.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8448.45b6b1f1a99eeb35.js +104 -0
  103. package/apps/pwa/out/_next/static/chunks/8464-e24f10451b658aac.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8477.e4c944bb3aa5d2f3.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8710.ca385257d5ca422e.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8830.627ccf294ec2465c.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8880.64c445592f04acaf.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8981.c706964c8ba27aff.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/{5638.107314dc479e2f37.js → 9048.212083de42d25be3.js} +2 -2
  110. package/apps/pwa/out/_next/static/chunks/9053.bd0fffaff8d3f836.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/9161-c66e723d7ec9d682.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9185.1ecdf9b65c0bb684.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9356.fccd5f58086b4ff5.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/9446.dc0406109371d329.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9506.dcf25d467a42627e.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/{8019.21ca554a821dad01.js → 9507.7026657a2f47eb64.js} +16 -16
  117. package/apps/pwa/out/_next/static/chunks/9541.eb8e2f8480c7feca.js +93 -0
  118. package/apps/pwa/out/_next/static/chunks/9577.ed7582186efa5482.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9579.4a8169600fff2058.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9642-ff2e039eb62e3b92.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9659-8f2323348113ad80.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/9724.4c5623af2db43153.js +34 -0
  123. package/apps/pwa/out/_next/static/chunks/{6493.27ad77de7aac7966.js → 9834.63ab2bbc3153172e.js} +1 -1
  124. package/apps/pwa/out/_next/static/chunks/{3389.012c70767a872f9b.js → 9869.81a1e24ca682d5a0.js} +1 -1
  125. package/apps/pwa/out/_next/static/chunks/{8994d93e.33ba491f95345fc2.js → a0a01613.6d1cca322238d7fe.js} +1 -1
  126. package/apps/pwa/out/_next/static/chunks/{de8b930d.d94c0f42acf807fc.js → addc2b32.8c4ff8f0aefe987d.js} +1 -1
  127. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-8d9d76ea322d855c.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed2c4e59f9f1fe21.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-2dc99e03c5d76ca0.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/board/page-b5a3a788330e920f.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-866aac5ff226a7f3.js → page-14949db884bfa672.js} +1 -1
  132. package/apps/pwa/out/_next/static/chunks/app/bots/page-ea76c85b36388a97.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/ceo/page-01716d20af62d325.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/chat/page-62baf6881a64b1e9.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/consult/page-f89ba590c2af8afa.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/control/page-22f8b0f78d9637e5.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/decisions/page-817f9d7e6820be80.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/design-check/page-ffb9bc0d2650249a.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/editor/page-f6d0e64873c0f629.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/exec/page-8bfa0d4ba23a209d.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/field/page-f5060462249e32c7.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/healthz/route-8d9d76ea322d855c.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/inside/page-b2049f8b1ef79117.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/intake/page-1446c5fa93907f11.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/layout-b48a7a07c5204156.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/live/page-e974b8c4ca47614c.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/live-run/page-8a919b869bd28594.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/loops/page-d31b8de6bfcd72ed.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/market/page-64765f817909db29.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-d128c8569a36ee9b.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/morning/page-b2679d357e9b9270.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/not-found-6fabec98a9e7b269.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/observatory/page-048f30149dcf1349.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-9113181d6b5a2725.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-40f9e19149024298.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-1e7a755a13227611.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3c8f8b67a203cf07.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/page-18032f5437215062.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/reflection/page-da3b739192fd0ee3.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d332545571bd6fd1.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/sessions/page-5237aa5b3f3b8ec5.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a142dfb0331a05f5.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/settings/page-d16e56c3989c147e.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6b6593600869e2cd.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/setup/layout-8d9d76ea322d855c.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/setup/page-29e8b8a8396b55cb.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/share/page-b3414d856a1a7e2f.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c3affa52b7ce961b.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f21dddf9f95b6fab.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/term/page-f5a30a24745bf088.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/today/page-8c8569a09b4d4e34.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/trace/page-2ce32722c0243483.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/vault/page-4767b0d9c0a98c6c.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-116ee1339c387a75.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/app/workflows/page-35e8c50ca4ef7ffc.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/app/workspace/page-52e17113356bb891.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7458ae05ed2ac1a0.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/b2271e54.c1de3347976e90b0.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/{b7459770.6539b11860eb8a9c.js → c0c1a699.0ba79f97005965d4.js} +7 -7
  180. package/apps/pwa/out/_next/static/chunks/framework-ad6c9dd524ad6ef8.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/main-app-2ddd1f2b44d6aa59.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/main-e3d82bdc358d20c5.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/pages/_app-71d5aa3896e1655f.js +1 -0
  184. package/apps/pwa/out/_next/static/chunks/pages/_error-03ffc54e00438546.js +1 -0
  185. package/apps/pwa/out/_next/static/chunks/webpack-56bb89af5a611d0b.js +1 -0
  186. package/apps/pwa/out/approvals/index.html +1 -1
  187. package/apps/pwa/out/approvals/index.txt +22 -22
  188. package/apps/pwa/out/autopilot/index.html +1 -1
  189. package/apps/pwa/out/autopilot/index.txt +22 -22
  190. package/apps/pwa/out/board/index.html +1 -1
  191. package/apps/pwa/out/board/index.txt +22 -22
  192. package/apps/pwa/out/botlab/index.html +1 -1
  193. package/apps/pwa/out/botlab/index.txt +21 -21
  194. package/apps/pwa/out/bots/index.html +1 -1
  195. package/apps/pwa/out/bots/index.txt +21 -21
  196. package/apps/pwa/out/ceo/index.html +1 -1
  197. package/apps/pwa/out/ceo/index.txt +22 -22
  198. package/apps/pwa/out/chat/index.html +1 -1
  199. package/apps/pwa/out/chat/index.txt +21 -21
  200. package/apps/pwa/out/consult/index.html +1 -1
  201. package/apps/pwa/out/consult/index.txt +22 -22
  202. package/apps/pwa/out/control/index.html +1 -1
  203. package/apps/pwa/out/control/index.txt +22 -22
  204. package/apps/pwa/out/decisions/index.html +1 -1
  205. package/apps/pwa/out/decisions/index.txt +21 -21
  206. package/apps/pwa/out/design-check/index.html +1 -1
  207. package/apps/pwa/out/design-check/index.txt +22 -22
  208. package/apps/pwa/out/editor/index.html +1 -1
  209. package/apps/pwa/out/editor/index.txt +22 -22
  210. package/apps/pwa/out/exec/index.html +1 -1
  211. package/apps/pwa/out/exec/index.txt +22 -22
  212. package/apps/pwa/out/field/index.html +1 -1
  213. package/apps/pwa/out/field/index.txt +22 -22
  214. package/apps/pwa/out/healthz +1 -1
  215. package/apps/pwa/out/index.html +1 -1
  216. package/apps/pwa/out/index.txt +21 -21
  217. package/apps/pwa/out/inside/index.html +1 -1
  218. package/apps/pwa/out/inside/index.txt +21 -21
  219. package/apps/pwa/out/intake/index.html +1 -1
  220. package/apps/pwa/out/intake/index.txt +22 -22
  221. package/apps/pwa/out/live/index.html +1 -1
  222. package/apps/pwa/out/live/index.txt +22 -22
  223. package/apps/pwa/out/live-run/index.html +1 -1
  224. package/apps/pwa/out/live-run/index.txt +22 -22
  225. package/apps/pwa/out/loops/index.html +1 -1
  226. package/apps/pwa/out/loops/index.txt +21 -21
  227. package/apps/pwa/out/market/index.html +1 -1
  228. package/apps/pwa/out/market/index.txt +21 -21
  229. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  230. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  231. package/apps/pwa/out/morning/index.html +1 -1
  232. package/apps/pwa/out/morning/index.txt +22 -22
  233. package/apps/pwa/out/observatory/index.html +1 -1
  234. package/apps/pwa/out/observatory/index.txt +22 -22
  235. package/apps/pwa/out/ops/checklist/index.html +1 -1
  236. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  237. package/apps/pwa/out/ops/release/index.html +1 -1
  238. package/apps/pwa/out/ops/release/index.txt +21 -21
  239. package/apps/pwa/out/ops/seats/index.html +1 -1
  240. package/apps/pwa/out/ops/seats/index.txt +21 -21
  241. package/apps/pwa/out/outputs/index.html +1 -1
  242. package/apps/pwa/out/outputs/index.txt +21 -21
  243. package/apps/pwa/out/reflection/index.html +1 -1
  244. package/apps/pwa/out/reflection/index.txt +22 -22
  245. package/apps/pwa/out/scheduler/index.html +1 -1
  246. package/apps/pwa/out/scheduler/index.txt +22 -22
  247. package/apps/pwa/out/sessions/index.html +1 -1
  248. package/apps/pwa/out/sessions/index.txt +21 -21
  249. package/apps/pwa/out/settings/devices/index.html +1 -1
  250. package/apps/pwa/out/settings/devices/index.txt +22 -22
  251. package/apps/pwa/out/settings/index.html +1 -1
  252. package/apps/pwa/out/settings/index.txt +22 -22
  253. package/apps/pwa/out/setup/done/index.html +1 -1
  254. package/apps/pwa/out/setup/done/index.txt +22 -22
  255. package/apps/pwa/out/setup/index.html +1 -1
  256. package/apps/pwa/out/setup/index.txt +22 -22
  257. package/apps/pwa/out/share/index.html +1 -1
  258. package/apps/pwa/out/share/index.txt +22 -22
  259. package/apps/pwa/out/showroom/index.html +1 -1
  260. package/apps/pwa/out/showroom/index.txt +21 -21
  261. package/apps/pwa/out/tasks/index.html +1 -1
  262. package/apps/pwa/out/tasks/index.txt +22 -22
  263. package/apps/pwa/out/term/index.html +1 -1
  264. package/apps/pwa/out/term/index.txt +22 -22
  265. package/apps/pwa/out/today/index.html +1 -1
  266. package/apps/pwa/out/today/index.txt +22 -22
  267. package/apps/pwa/out/trace/index.html +1 -1
  268. package/apps/pwa/out/trace/index.txt +22 -22
  269. package/apps/pwa/out/vault/index.html +1 -1
  270. package/apps/pwa/out/vault/index.txt +22 -22
  271. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  272. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  273. package/apps/pwa/out/workflows/index.html +1 -1
  274. package/apps/pwa/out/workflows/index.txt +22 -22
  275. package/apps/pwa/out/workspace/index.html +1 -1
  276. package/apps/pwa/out/workspace/index.txt +22 -22
  277. package/apps/pwa/out/worktrees/index.html +1 -1
  278. package/apps/pwa/out/worktrees/index.txt +22 -22
  279. package/bin/elanous.mjs +6 -1
  280. package/catalog/models/openai/gpt-6.1-sol.yaml +16 -0
  281. package/catalog/models/openai/gpt-6.1-terra.yaml +16 -0
  282. package/graphs/demo/persona-marketer/fixtures/marketer-scenario.yaml +10 -0
  283. package/graphs/demo/persona-marketer/persona-marketer.yaml +25 -0
  284. package/graphs/demo/persona-marketer/recipes.yaml +19 -0
  285. package/graphs/demo/persona-teacher/lesson-pack.yaml +16 -0
  286. package/graphs/demo/persona-teacher/recipes.yaml +17 -0
  287. package/graphs/demo/persona-teacher/weekly-lesson.yaml +36 -0
  288. package/graphs/overlays/stop-heal-ladder.yaml +23 -2
  289. package/graphs/release/release-loop.yaml +3 -1
  290. package/graphs/units/gate/gate.yaml +20 -0
  291. package/graphs/units/git/git.yaml +26 -0
  292. package/graphs/units/implement/implement.yaml +19 -0
  293. package/graphs/units/landing/landing.yaml +18 -0
  294. package/graphs/units/review/review.yaml +20 -0
  295. package/graphs/units/verbs/recipes.yaml +3 -0
  296. package/graphs/units/verbs/research.yaml +20 -0
  297. package/graphs/video/explainer-line.yaml +4 -1
  298. package/graphs/work/research-report.yaml +11 -1
  299. package/package.json +1 -1
  300. package/scripts/dead-code/report.ts +169 -0
  301. package/scripts/disk-steward.ts +46 -0
  302. package/scripts/fleet/node-setup.sh +50 -0
  303. package/scripts/graph-units/verbs/research.ts +55 -0
  304. package/scripts/lib/morning-report-options.ts +3 -4
  305. package/scripts/lib/tui-regress-evidence.ts +56 -0
  306. package/scripts/llm-cost-ledger.ts +179 -8
  307. package/scripts/measure-nl-routing-corpus.ts +10 -2
  308. package/scripts/morning-report.ts +5 -1
  309. package/scripts/persona-teacher/weekly-lesson-node.ts +172 -0
  310. package/scripts/public-copy-lint.ts +163 -19
  311. package/scripts/public-export.ts +15 -7
  312. package/scripts/ratchets/train-side-invariants.sh +0 -1
  313. package/scripts/release-loop/export-check-node.ts +21 -3
  314. package/scripts/release-loop/gate-autoheal.ts +117 -0
  315. package/scripts/release-loop/gate-baseline-receipt.ts +8 -1
  316. package/scripts/release-loop/gate-diff.ts +22 -3
  317. package/scripts/release-loop/gate-node.ts +583 -64
  318. package/scripts/release-loop/gate-shard-dispatch.ts +128 -0
  319. package/scripts/release-loop/gate-shard-load-flaky.ts +256 -0
  320. package/scripts/release-loop/gate-shard-receipts.ts +89 -0
  321. package/scripts/release-loop/gate-triage-node.ts +70 -10
  322. package/scripts/release-loop/gate-wall.ts +5 -5
  323. package/scripts/release-loop/preflight.ts +6 -2
  324. package/scripts/release-loop/resume-release.ts +267 -20
  325. package/scripts/release-loop/resume.ts +48 -0
  326. package/scripts/release-loop/traffic-node.ts +6 -3
  327. package/scripts/release-loop/unattended-release.ts +4 -2
  328. package/scripts/release-loop/version-node.ts +7 -2
  329. package/scripts/release-story/draft.ts +1 -1
  330. package/scripts/research-bench/README.md +53 -0
  331. package/scripts/research-bench/questions.json +66 -0
  332. package/scripts/research-bench/rubric.md +33 -0
  333. package/scripts/research-bench/run.ts +523 -0
  334. package/scripts/shadow-authoring-probe.ts +20 -0
  335. package/scripts/tui-regress.ts +85 -10
  336. package/scripts/ux-sim.ts +19 -2
  337. package/src/acp/core-turn-bridge.ts +94 -4
  338. package/src/agent/autonomous-tools.ts +10 -3
  339. package/src/agent/monad-agent-turn.ts +4 -1
  340. package/src/agent/registry.ts +26 -2
  341. package/src/agent/shared-app-tools.ts +1 -1
  342. package/src/agent/surface-ux/build.ts +12 -3
  343. package/src/agent/surface-ux/types.ts +1 -1
  344. package/src/agent/task-notification.ts +75 -6
  345. package/src/agent/types.ts +3 -0
  346. package/src/agent-mission/driver.ts +29 -3
  347. package/src/agent-mission/mission-cli.ts +2 -1
  348. package/src/agent-substrate/review-context-pack.ts +365 -0
  349. package/src/agent-substrate/self-review-cli.ts +291 -20
  350. package/src/ask-user-question/index.ts +6 -0
  351. package/src/ask-user-question/inline-resolver.ts +49 -0
  352. package/src/auto-research/question-ladder-contract.ts +22 -3
  353. package/src/auto-research/research-turn.ts +359 -17
  354. package/src/autopilot/agent-loop.ts +1 -1
  355. package/src/autopilot/discovery/wiki-claim-proposer.ts +22 -1
  356. package/src/autopilot/pty-control-loop.ts +8 -1
  357. package/src/boot/daemon-tools/index.ts +4 -3
  358. package/src/boot/daemon-tools/self-implement.ts +312 -7
  359. package/src/boot/daemon-tools/types.ts +2 -0
  360. package/src/budget/llm-cost.ts +44 -5
  361. package/src/budget/shadow-arms.ts +52 -0
  362. package/src/budget/unified-usage.ts +17 -1
  363. package/src/capture/tui-self-report.ts +14 -0
  364. package/src/chat/index.ts +33 -7
  365. package/src/chat/pickers/state.ts +7 -1
  366. package/src/cli/agent-cli.ts +43 -8
  367. package/src/cli/intake-cli.ts +22 -1
  368. package/src/cli/lesson-cli.ts +19 -3
  369. package/src/cli/log-event-names.ts +6 -0
  370. package/src/cli/mcp-login.ts +8 -18
  371. package/src/cli/msg-cli.ts +57 -1
  372. package/src/cli/pod-cli.ts +17 -2
  373. package/src/cli/pr-land-heavy-remote.ts +15 -9
  374. package/src/cli/pty-takeover-cli.ts +67 -7
  375. package/src/cli/release-cli.ts +79 -7
  376. package/src/cli/repo-cli.ts +2 -1
  377. package/src/cli/sim-cli.ts +7 -1
  378. package/src/cli/tasks-cli.ts +41 -13
  379. package/src/codex/models.ts +30 -15
  380. package/src/control-plane/ledger.ts +21 -4
  381. package/src/core-turn/run-core-turn.ts +47 -3
  382. package/src/core-turn/run-goal-loop.ts +240 -10
  383. package/src/core-turn/types.ts +9 -0
  384. package/src/dashboard/acp-boot.ts +72 -3
  385. package/src/dashboard/chat/acp-chat.ts +2 -2
  386. package/src/dashboard/classic-sigquit.ts +16 -0
  387. package/src/dashboard/index.ts +327 -27
  388. package/src/dashboard/input/chat-main-interaction-opts.ts +3 -0
  389. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +7 -2
  390. package/src/dashboard/input/chat-main-slash-command.ts +7 -0
  391. package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
  392. package/src/dashboard/input/dashboard-priority-key-route.ts +21 -5
  393. package/src/dashboard/input/external-input-host.ts +2 -0
  394. package/src/dashboard/sidetab-runtime.ts +228 -0
  395. package/src/dashboard/slash-runtime/ask-clarification.ts +7 -1
  396. package/src/dashboard/slash-runtime/dashboard-handlers.ts +20 -8
  397. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -2
  398. package/src/dashboard/term-slash-runtime.ts +16 -18
  399. package/src/dashboard/turn-preamble.ts +14 -1
  400. package/src/disk-steward/judge.ts +73 -0
  401. package/src/disk-steward/ledger.ts +122 -0
  402. package/src/disk-steward/steward.ts +373 -0
  403. package/src/domains/guardian-tick.ts +191 -2
  404. package/src/domains/knowledge.ts +1 -1
  405. package/src/esc-abort-gate.ts +33 -1
  406. package/src/execution-loop/launch-gate.ts +206 -1
  407. package/src/graph-runner/graph-cli.ts +27 -4
  408. package/src/graph-runner/in-process-registry.ts +37 -0
  409. package/src/graph-runner/runner.ts +63 -11
  410. package/src/graph-wizard/generate.ts +16 -7
  411. package/src/graph-wizard/mission-compose.ts +201 -0
  412. package/src/grok/agent-search.ts +8 -2
  413. package/src/grok/credential.ts +5 -0
  414. package/src/grounding/ref-index.ts +30 -0
  415. package/src/grounding/ref-vector.ts +61 -0
  416. package/src/grounding/sources-cli.ts +11 -3
  417. package/src/grounding/sources.ts +15 -1
  418. package/src/harness/harness-cli-command.ts +305 -23
  419. package/src/harness/harness-incidents.ts +312 -7
  420. package/src/harness/harness-pod-dispatch.ts +7 -1
  421. package/src/harness/harness-space.ts +15 -1
  422. package/src/harness/progress-worker-entry.ts +59 -0
  423. package/src/harness/progress-worker-runtime.ts +11 -0
  424. package/src/index.ts +35 -5
  425. package/src/input/external-input-queue.ts +10 -0
  426. package/src/instance/dev-project.ts +25 -0
  427. package/src/intake-plane/collect-telegram-saved.ts +36 -1
  428. package/src/intake-plane/intake-to-tasks.ts +246 -3
  429. package/src/intelligence-map/model-alias.ts +6 -5
  430. package/src/intelligence-map/model-catalog.ts +59 -2
  431. package/src/lessons/friction-ledger.ts +154 -0
  432. package/src/live-supply/collector.ts +149 -0
  433. package/src/live-supply/probes.ts +52 -0
  434. package/src/live-supply/snapshot.ts +40 -0
  435. package/src/llm/model-defaults.ts +4 -4
  436. package/src/llm.ts +473 -87
  437. package/src/loops/orchestrator/tick.ts +56 -0
  438. package/src/mcp/mcp-oauth.ts +3 -1
  439. package/src/model-tier/llm-tier-map.ts +9 -9
  440. package/src/model-tier/turn-tier.ts +1 -1
  441. package/src/msg/msg-mirror-github.ts +80 -0
  442. package/src/msg/msg-mirror-policy.ts +61 -0
  443. package/src/msg/msg-mirror-runner.ts +219 -0
  444. package/src/msg/msg-mirror-state.ts +33 -0
  445. package/src/msg/msg-store.ts +11 -0
  446. package/src/nexus/api/harness-api.ts +2 -1
  447. package/src/output-truncation.ts +41 -12
  448. package/src/project/project-store.ts +48 -1
  449. package/src/pty/snapshot.py +132 -0
  450. package/src/pty-shell/pty-control-ipc.ts +29 -2
  451. package/src/pty-shell/pty-manifest.ts +59 -3
  452. package/src/pty-shell/registry.ts +2 -0
  453. package/src/pty-shell/tui-run-state.ts +80 -3
  454. package/src/release-loop/gate-host-reservation.ts +157 -4
  455. package/src/release-loop/gate-shard-ledger.ts +68 -0
  456. package/src/release-loop/merged-pr-checklist.ts +25 -2
  457. package/src/release-loop/rehearsal-shard-plan.ts +6 -1
  458. package/src/release-loop/rehearsal.ts +27 -0
  459. package/src/release-loop/release-schedule.ts +90 -1
  460. package/src/research/bloom-exemplars.ts +135 -0
  461. package/src/research/edge-decision.ts +124 -15
  462. package/src/research/gap-followup.ts +249 -0
  463. package/src/research/lenses/counter-evidence.ts +100 -0
  464. package/src/research/lenses/working-backwards.ts +89 -0
  465. package/src/research/plugin-discovery.ts +242 -0
  466. package/src/research-bridge/invoke.ts +4 -2
  467. package/src/research-bridge/types.ts +2 -0
  468. package/src/self-dev/ask-launch-flow.ts +73 -131
  469. package/src/self-dev/dev-cli.ts +19 -17
  470. package/src/self-dev/dev-pipeline.ts +8 -4
  471. package/src/self-dev/graph-front-nodes.ts +23 -0
  472. package/src/self-dev/graph-journey-route.ts +10 -2
  473. package/src/self-dev/launch-preflight-text.ts +2 -2
  474. package/src/self-dev/launch-preflight.ts +47 -11
  475. package/src/self-dev/orchestrate-cli.ts +1 -0
  476. package/src/self-dev/orchestrate.ts +15 -0
  477. package/src/self-dev/run-supervisor.ts +204 -3
  478. package/src/self-dev/run-types.ts +3 -0
  479. package/src/self-implement/device-first.ts +8 -2
  480. package/src/self-implement/doctor-visit.ts +76 -58
  481. package/src/self-implement/gate-artifacts.ts +16 -0
  482. package/src/self-implement/gate-baseline.ts +75 -4
  483. package/src/self-implement/gate-cli.ts +368 -30
  484. package/src/self-implement/gate-receipt-registry.ts +180 -0
  485. package/src/self-implement/gate-remote.ts +165 -24
  486. package/src/self-implement/goal-author-clarification.ts +205 -32
  487. package/src/self-implement/goal-author-decompose.ts +24 -15
  488. package/src/self-implement/goal-author.ts +86 -10
  489. package/src/self-implement/graph-stage-units.ts +172 -0
  490. package/src/self-implement/graph-templates.ts +162 -1
  491. package/src/self-implement/graph-variant.ts +37 -4
  492. package/src/self-implement/host-regate.ts +124 -49
  493. package/src/self-implement/impl-findings-feedback.ts +188 -0
  494. package/src/self-implement/knowhow-pack.ts +227 -10
  495. package/src/self-implement/off-diff-evidence.ts +124 -0
  496. package/src/self-implement/orchestrator.ts +320 -28
  497. package/src/self-implement/run-ledger.ts +110 -14
  498. package/src/self-implement/run-stop.ts +33 -2
  499. package/src/self-implement/running-runs.ts +35 -12
  500. package/src/self-implement/seams.ts +6 -3
  501. package/src/self-implement/self-implement-cli.ts +40 -6
  502. package/src/self-implement/stop-autoheal-operational.ts +43 -0
  503. package/src/self-implement/stop-autoheal.ts +15 -6
  504. package/src/session/chat.ts +66 -15
  505. package/src/session/request-size-guard.ts +123 -0
  506. package/src/session-runtime/provider-circuit.ts +140 -0
  507. package/src/shell-runner/file-engine.ts +1 -0
  508. package/src/shell-runner/types.ts +4 -0
  509. package/src/sidetab-core/model.ts +312 -0
  510. package/src/skills/tools/schedule-wakeup.ts +23 -1
  511. package/src/skills/tools/shell.ts +51 -5
  512. package/src/steward/directive-audit.ts +354 -0
  513. package/src/surface/child-process.ts +31 -0
  514. package/src/surface/tui-stderr-owner.ts +48 -0
  515. package/src/task-agent/cover.ts +30 -12
  516. package/src/task-agent/judge.ts +56 -0
  517. package/src/task-agent/parent-host.ts +14 -1
  518. package/src/task-agent/postland-card.ts +35 -2
  519. package/src/task-agent/rejudge-on-head.ts +46 -2
  520. package/src/task-agent/repair-cycle.ts +1 -1
  521. package/src/task-agent/task-hand.ts +133 -25
  522. package/src/task-agent/tier-split.ts +105 -21
  523. package/src/task-orchestrator/surfaces/pod-command-job.ts +330 -2
  524. package/src/task-orchestrator/surfaces/pod-config-snapshot.ts +123 -0
  525. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +70 -2
  526. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +29 -4
  527. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +11 -8
  528. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +1 -1
  529. package/src/task-orchestrator/surfaces/pod-source-receive.ts +74 -6
  530. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +2 -1
  531. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +56 -15
  532. package/src/task-orchestrator/surfaces/self-implement-pod.ts +298 -45
  533. package/src/task-orchestrator/surfaces/self-implement.ts +18 -0
  534. package/src/tool-runtime/skill-exec-runtime.ts +95 -5
  535. package/src/tui/entry.ts +25 -5
  536. package/src/tui/inline-choice.ts +188 -0
  537. package/src/tui/sidetab/list.ts +36 -165
  538. package/src/tui/sidetab/nl-tool.ts +2 -136
  539. package/src/tui/sidetab/peek.ts +52 -0
  540. package/src/tui/slash/term.ts +12 -1
  541. package/src/tui-client/dashboard-session.ts +10 -1
  542. package/src/user-config.ts +45 -9
  543. package/src/ux-sim/classic-tui-seat-scenarios.ts +1 -7
  544. package/src/ux-sim/fake-land-queue.ts +88 -0
  545. package/src/ux-sim/fault-needs-human-reason-repair.ts +107 -0
  546. package/src/ux-sim/fault-pod-child-result.ts +42 -0
  547. package/src/ux-sim/gate-shard-host-reroute.ts +82 -0
  548. package/src/ux-sim/goal-interim-trace.ts +24 -0
  549. package/src/ux-sim/next-tui-seat-scenarios.ts +8 -13
  550. package/src/ux-sim/release-sim-rig.ts +262 -0
  551. package/src/ux-sim/seminar-rehearsal.ts +109 -0
  552. package/src/ux-sim/subagent-tools-device.ts +2 -2
  553. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +4 -1
  554. package/src/version/packed-revision.json +1 -1
  555. package/src/video-pipeline/recipes/explainer.ts +54 -2
  556. package/src/web-search/grok.ts +32 -6
  557. package/src/web-search/index.ts +8 -7
  558. package/src/workflow-runtime/node-catalog.ts +53 -4
  559. package/apps/pwa/out/_next/static/chunks/1118.a8a74ea29aac3e46.js +0 -27
  560. package/apps/pwa/out/_next/static/chunks/1204-2aa830479adf80f4.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/1341-43b7d2dc77d45c9d.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/1440-c3ea8882badfd9bf.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/1698-9c11cbf97f13717e.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/1770-3b1fc92253ef9f2f.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/1923-5c1695332240246a.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/1938.0e6c60ee91c4d7f5.js +0 -148
  567. package/apps/pwa/out/_next/static/chunks/2104.70e086d5174a4736.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/213-20675f20673ba22a.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/214.186a430da28338f1.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/2277.3bd4c0ac7f1b5996.js +0 -93
  571. package/apps/pwa/out/_next/static/chunks/240.e09f433f71c78ff4.js +0 -104
  572. package/apps/pwa/out/_next/static/chunks/2417.02151393605a7cd0.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/2463.cd2641a76daaa9ff.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/2576.b9e9c629c4b84c52.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/265-c021de53f0865bd9.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/2998-b1cc13956cd6a6e7.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/2e4782d3.ba2f0ab2b63a53e7.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/3130.626b54382b4dc379.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/3221-1bb3f99a55088613.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/3280.24edb1ffd03a7f3f.js +0 -24
  581. package/apps/pwa/out/_next/static/chunks/3288-eb3c22a1cbf2ae68.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/33.ef99e8374f96c6c4.js +0 -36
  583. package/apps/pwa/out/_next/static/chunks/3341-f09b9efbd7a82f70.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/3410-d7c0f14b329d6fda.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/3421.c87d6313a7d670f7.js +0 -287
  586. package/apps/pwa/out/_next/static/chunks/3422-83a3953f9bd67e26.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/3587-002e24e368c515a9.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/3644.f12a7d821ab940af.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/3660.d7516588e2d875c3.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/3695.b82e2610f4cd4ea9.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/3858.ca1f5bc0f577eac9.js +0 -94
  592. package/apps/pwa/out/_next/static/chunks/3959-e6ac4a139d9d4bcc.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/3f0de3de-2340c532c00395db.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/4032.53f62176514ec0ea.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/4199-f7c6eb40cd0322f8.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/4204-ef8484cbecd5d62f.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/4259-163129ca79913c4b.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/428-eaa77df3d0c85969.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/4432-97e400ffa1e161f5.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/449-aa427cf2cbb75f50.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/4491-39a0fd32bbaf3840.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/4588.b7cf06d382953979.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/4690.70ec8060825366ab.js +0 -32
  604. package/apps/pwa/out/_next/static/chunks/4804.6012b5cd33c22792.js +0 -90
  605. package/apps/pwa/out/_next/static/chunks/4881.e4d22d730e3b9df5.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/4937.ce2e340dc29cad3e.js +0 -79
  607. package/apps/pwa/out/_next/static/chunks/5-bb1c08d84bd71df3.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/5005.de98df23b37cdf3c.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/5035.dc64a89cad5573cc.js +0 -74
  610. package/apps/pwa/out/_next/static/chunks/5041-5aada92ca215ffdd.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/5207.1a224035455790fd.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/5255-1b60d50eabe9f057.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/5269.d0436ee6d773382a.js +0 -286
  614. package/apps/pwa/out/_next/static/chunks/5309.3367c4d50f52b489.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/552-689827d49780fa00.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/5539.34cc9d60622cb69b.js +0 -8
  617. package/apps/pwa/out/_next/static/chunks/5568.218dea0c00ca2ec7.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/5645.b7e3b055455a04ea.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/5662.18cc0f30353cbd96.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/5671.da24fc9dc5e98325.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/5b141171.324c40fd49cb6821.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/6175-d4621f6a10b0cfab.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/6290.3eb53a20746b72ce.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/6415-9307f3eafa90837f.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/6579-3de35d00aacd71b5.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/680-2f324c4e039a5b67.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/6845-331b3c7481da3ba3.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/7000.28157393caaf5343.js +0 -62
  629. package/apps/pwa/out/_next/static/chunks/7311-60a7ea80d23c7521.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/7401.525d0a12f7d02c06.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/7438.c2cf72b66dca6aa4.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/7488.966b116789f3d41a.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/7524.ce973525d30b3d52.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/7577.ea6e9ac72e035520.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/7628.6b16863ac3972333.js +0 -34
  636. package/apps/pwa/out/_next/static/chunks/7657.8d1fb3d2f7ebe273.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/7903-1435d5d2f0dd7807.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/7954.4f7a8832663ee979.js +0 -115
  639. package/apps/pwa/out/_next/static/chunks/7978-30a91192c5dbe3c2.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/8025-8795821525cf1a07.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/8191.3674a00f0b565c23.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/8217-604955d8885c5ef2.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/8298-eed6f5f2585a63f4.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/8509.3a54d4e61893d7cb.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/8758.ac421f726a189125.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/891.d6c723a51a067b36.js +0 -149
  647. package/apps/pwa/out/_next/static/chunks/9223.cbcc88e0e9950426.js +0 -41
  648. package/apps/pwa/out/_next/static/chunks/9299.24e2a7d9b6d1f91b.js +0 -226
  649. package/apps/pwa/out/_next/static/chunks/9317.6a9869039c231bb3.js +0 -24
  650. package/apps/pwa/out/_next/static/chunks/9383.e4755f275b3c11ff.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/9581.da63ddf41acfad46.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/9715.8c5529a0a5c41a36.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/9817.3009d65f0889ef1f.js +0 -2
  654. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76873dd80da4f715.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed32b6ec5dea8f23.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-fdd40e15babf3d25.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/board/page-384efc78e85e400b.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/bots/page-d91809c5aeed319a.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/ceo/page-128f3522f89a81ab.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/chat/page-595961abf3b43ad1.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/consult/page-f41dccb76d8c0263.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/control/page-a3205c2e28b7d0d9.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/decisions/page-c39a80277814a3f4.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/design-check/page-1ab3f98194513195.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/editor/page-a5246f7e254d77d0.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/exec/page-0f92287bdb81217d.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/field/page-5a37131ff63793ef.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/healthz/route-76873dd80da4f715.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/inside/page-ac4bd14bb2348bfd.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/intake/page-c348a3959c5b5fc6.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/layout-2addd81c0d3e2906.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/live/page-da6b765f58a3eefb.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/live-run/page-0661e40f8780c32c.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/loops/page-b89af1b1c8e4875b.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/market/page-da8aeb82ba751cdb.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-cc71317b239439db.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/morning/page-bde7fc1d64ffe369.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/not-found-e2797214f713fa58.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/observatory/page-2a35bcda70defaf6.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3af03deedde45032.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-d1d1210f99f620ae.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-46d1b5500885861d.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/outputs/page-291ab19fe2acb173.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/page-7f569e533ddeecba.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/reflection/page-990129c9fee46d8f.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-7737f785ebb1cdaf.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9f3c73a4f7ffd2f8.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-03be7fb347f01058.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/app/settings/page-96b0280625e4df2b.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-56855545049eb56d.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/app/setup/layout-76873dd80da4f715.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/app/setup/page-79a909c9981f0338.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/app/share/page-a9d9a3e66459c1e0.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c383cbf2013f7069.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f57c6a2e54dbdca4.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/term/page-6b140f77593576eb.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/today/page-6b767ae2d9d0adfc.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/trace/page-116d6198d5da0e3d.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/vault/page-b9c9b778c7501370.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-a6c78392ab8f6335.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/app/workflows/page-455183deb4ed0cfe.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6a63e99526bd63d0.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-31c22caafe788c08.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/bb6987f9.3647e1a23b0e3217.js +0 -122
  705. package/apps/pwa/out/_next/static/chunks/framework-4b12a946f352cee2.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/main-941155250ed2644b.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/main-app-f8b6765abed6d149.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/pages/_app-78432194c85388f9.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/pages/_error-cdf7390829512b1b.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/webpack-d5f0964a9c2e92d2.js +0 -1
  711. package/scripts/ratchets/next-tui-entry-budget.ts +0 -124
  712. /package/apps/pwa/out/_next/static/{RrjXTwz-urRAbChP1bX02 → GiOLWmt4MqDZePubBjA4Q}/_ssgManifest.js +0 -0
@@ -26,9 +26,10 @@ import { createGraphVariant, type GraphVariantPlan } from '../self-implement/gra
26
26
  import { psProcessStartMs, START_TOLERANCE_MS } from '../harness/harness-stop.js';
27
27
  import { executeBashNode } from '../workflow-runtime/nodes/bash.js';
28
28
  import { executeClassifyNode } from '../workflow-runtime/nodes/classify.js';
29
+ import { requireInProcessHandler, type InProcessHandlerRegistry } from './in-process-registry.js';
29
30
  import { interpolate } from '../workflow-runtime/variables.js';
30
31
  import type { BashNode, ClassifyNode, NodeExecContext, NodeOutput, WorkflowDeps } from '../workflow-runtime/types.js';
31
- import { releaseResumeAcceptedRegressions, releaseResumeGateExecutor, releaseResumeGatePodPool, releaseResumeWaiver, type AcceptedRegression, type GateExecutorOverride, type GatePodPoolOverride } from '../../scripts/release-loop/resume.js';
32
+ import { releaseResumeAcceptedRegressions, releaseResumeGateExecutor, releaseResumeGatePodPool, releaseResumeGateShardReroute, releaseResumeWaiver, type AcceptedRegression, type GateExecutorOverride, type GatePodPoolOverride, type GateShardRerouteOverride } from '../../scripts/release-loop/resume.js';
32
33
 
33
34
  type BashRun = WorkflowDeps['runBash'];
34
35
  const DEFAULT_BASH_TIMEOUT_MS = 5 * 60 * 1_000;
@@ -148,7 +149,8 @@ export interface GraphRunState {
148
149
  reason?: string;
149
150
  path: string[];
150
151
  /** startedAt/endedAt (ISO) and seconds are written when the node runs; ledgers before GRAPH-NODE-TIMES (0.2.19) have none. */
151
- nodes: Array<{ nodeId: string; ok: boolean; exit: number | null; executed: boolean; output?: unknown; error?: string; reason?: string; decidedBy?: string; decidedAt?: string;
152
+ nodes: Array<{ nodeId: string; ok: boolean; exit: number | null; executed: boolean; output?: unknown; error?: string; reason?: string;
153
+ failure?: { errorCode: string; message: string; stage: string }; decidedBy?: string; decidedAt?: string;
152
154
  startedAt?: string; endedAt?: string; seconds?: number;
153
155
  waiver?: { reason: string; at: string; /** RELEASE-WAIVE-UNMEASURED — why the waived gate had no verdict. */ unmeasured?: string; original: { exit: number | null; output?: unknown; error?: string } } }>;
154
156
  /** The node now running and when it started; cleared when its record is written. */
@@ -170,7 +172,7 @@ export interface GraphRunState {
170
172
  growthPark?: { from: string; outcome: string; reason: string; decisionId: string; decisionRef: string; growth: GraphGrowth; command?: GrowthCommand; approval?: string };
171
173
  resume?: { from: string; at: string; previousStatus: GraphRunState['status']; graph?: 'snapshot' | 'current' };
172
174
  /** GATE-HOST-EXECUTOR — every explicit input change a resume made (what was set and what it replaced), oldest first. */
173
- inputOverrides?: Array<GateExecutorOverride | GatePodPoolOverride>;
175
+ inputOverrides?: Array<GateExecutorOverride | GatePodPoolOverride | GateShardRerouteOverride>;
174
176
  executed: number;
175
177
  dryRun: boolean;
176
178
  statePath: string;
@@ -241,6 +243,8 @@ export interface GraphRunOptions {
241
243
  releaseGateExecutor?: { executor: string; host?: string };
242
244
  /** Release-only (RESUME-GATE-POOL-OVERRIDE): replace the saved gate pool for this resumed gate. */
243
245
  releaseGatePodPool?: string;
246
+ /** Release-only: remeasure a shard after the same-commit resume preflight. */
247
+ releaseGateShardReroute?: { shard: string; host?: string; os?: 'darwin' | 'linux' };
244
248
  useCurrentGraph?: boolean;
245
249
  /** Internal unit invocation context, propagated only by runGraph. */
246
250
  unitContext?: { parentRunId: string; ancestors: readonly string[]; remainingSteps: number; entryNodeId?: string };
@@ -254,7 +258,7 @@ export interface GraphRunOptions {
254
258
  releaseCommandSource?: { root: string; cutTip: string; git?: (args: string[]) => string };
255
259
  /** Optional per-run Bloom edge policy hook. */
256
260
  researchEdgeDecisionRegistry?: ResearchEdgeDecisionRegistry;
257
- deps?: { root?: string; runBash?: BashRun; callLLM?: (prompt: string) => Promise<string>; log?: (event: string, data: Record<string, unknown>) => void; beforeNode?: () => void; processStartMs?: (pid: number) => number | null; growthProposer?: GrowthProposer; growthLLM?: (prompt: string) => Promise<string>; classifyGrowthRecipe?: (node: GraphNodeSpec, resolved: { command?: string; approval?: string }) => GrowthRecipeEffect; growthDecision?: GrowthDecisionDeps & { list?: (filters: { status: 'all' }) => DecisionEntry[] } };
261
+ deps?: { root?: string; runBash?: BashRun; callLLM?: (prompt: string) => Promise<string>; log?: (event: string, data: Record<string, unknown>) => void; beforeNode?: () => void; processStartMs?: (pid: number) => number | null; growthProposer?: GrowthProposer; growthLLM?: (prompt: string) => Promise<string>; classifyGrowthRecipe?: (node: GraphNodeSpec, resolved: { command?: string; approval?: string }) => GrowthRecipeEffect; growthDecision?: GrowthDecisionDeps & { list?: (filters: { status: 'all' }) => DecisionEntry[] }; inProcessHandlers?: InProcessHandlerRegistry };
258
262
  }
259
263
 
260
264
  /** The command directory must itself be the checkout at the cut tip. */
@@ -652,6 +656,7 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
652
656
  if (options.releaseAcceptedRegressions && (!options.resumeRunId || !options.fromNodeId || options.releaseWaiver)) throw new Error('accepted regressions require a release resume boundary');
653
657
  if (options.releaseGateExecutor && (!options.resumeRunId || !options.fromNodeId)) throw new Error('gate executor override requires a release resume boundary');
654
658
  if (options.releaseGatePodPool !== undefined && (!options.resumeRunId || !options.fromNodeId)) throw new Error('gate pod pool override requires a release resume boundary');
659
+ if (options.releaseGateShardReroute && (!options.resumeRunId || options.fromNodeId !== 'gate')) throw new Error('shard reroute requires release resume --from gate');
655
660
  const root = options.deps?.root ?? effectiveInstanceRoot();
656
661
  const matchingRuns = options.resumeRunId && !options.resumeGraphId
657
662
  ? listGraphRuns(root).runs.filter((run) => run.runId === options.resumeRunId && run.graphPath === resolve(path)) : [];
@@ -718,6 +723,8 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
718
723
  return existsSync(graphsDir) && graphFile.startsWith(`${realpathSync(graphsDir)}${sep}`);
719
724
  });
720
725
  const credentials = owner ? pluginEnv(owner.name, pluginRoot) : {};
726
+ const redactCredentials = (text: string) => Object.values(credentials).filter(value => value.length > 0)
727
+ .reduce((safe, value) => safe.replaceAll(value, '[REDACTED]'), text);
721
728
  const declaredEnv = [...new Set(installed.map(item => item.name))]
722
729
  .flatMap(name => credentialStatus(name, pluginRoot).fields.map(field => field.env));
723
730
  const credentialFields = owner ? credentialStatus(owner.name, pluginRoot).fields.filter(field => field.set).map(field => field.name) : [];
@@ -750,6 +757,10 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
750
757
  for (const node of graph.nodes) {
751
758
  if (node.kind === 'classify' && node.recipe !== 'none') throw new Error(`classify node cannot execute a recipe: ${node.nodeId}`);
752
759
  if (node.recipe === 'none') continue;
760
+ if (node.recipe.startsWith('handler:')) {
761
+ requireInProcessHandler(node.recipe, node.nodeId, options.deps?.inProcessHandlers);
762
+ continue;
763
+ }
753
764
  const resolved = resolveNodeRecipe(node, recipes, catalogRoles);
754
765
  // Harness loop recipes are labels the self-implement harness dispatches by node id (most are outside the
755
766
  // node catalog — graph-catalog.test.ts); a planned loop never executes them, and a real run is refused above.
@@ -921,6 +932,13 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
921
932
  state.inputOverrides = [...(state.inputOverrides ?? []), override];
922
933
  debug.log('graph.runs', 'input-override', { graphId, runId, ...override });
923
934
  }
935
+ if (options.releaseGateShardReroute) {
936
+ if (graphId !== 'release-loop') throw new Error('shard reroute requires the release-loop graph');
937
+ const override = releaseResumeGateShardReroute(state, { from: options.fromNodeId, ...options.releaseGateShardReroute });
938
+ state.input = { ...(state.input as Record<string, unknown>), ...override.set };
939
+ state.inputOverrides = [...(state.inputOverrides ?? []), override];
940
+ debug.log('graph.runs', 'input-override', { graphId, runId, ...override });
941
+ }
924
942
  if (state.unitCalls) {
925
943
  const calls = state.unitCalls;
926
944
  state.unitCalls = calls.filter(call => {
@@ -1094,6 +1112,31 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
1094
1112
  let commandFailureReason: string | undefined;
1095
1113
  let output: unknown;
1096
1114
  const waiving = options.releaseWaiver?.nodeId === current && waivedRecord !== undefined;
1115
+ const inProcessHandler = requireInProcessHandler(node.recipe, current, options.deps?.inProcessHandlers);
1116
+ let handlerExecuted = false;
1117
+ if (inProcessHandler && !waiving && !state.dryRun && !resumingCompleted) {
1118
+ const outputs: Record<string, unknown> = Object.create(null);
1119
+ for (const previous of state.nodes) outputs[previous.nodeId] = lastJsonObject(previous.output) ?? previous.output ?? null;
1120
+ handlerExecuted = true;
1121
+ debug.log('graph.run', 'handler-dispatch', { graphId, runId, nodeId: current, recipe: node.recipe });
1122
+ try {
1123
+ const result = await inProcessHandler({ graphId, runId, nodeId: current, input: state.input ?? null, outputs });
1124
+ if (!result || typeof result.ok !== 'boolean' || typeof result.outcome !== 'string' || !result.outcome.trim())
1125
+ throw new Error(`invalid in-process handler result: ${current}`);
1126
+ output = JSON.stringify({ ...(result.evidence === undefined ? {} : { evidence: result.evidence }), outcome: result.outcome });
1127
+ ok = result.ok;
1128
+ exit = ok ? 0 : 1;
1129
+ error = result.error;
1130
+ } catch (cause) {
1131
+ ok = false;
1132
+ exit = 1;
1133
+ error = redactCredentials(cause instanceof Error ? cause.message : String(cause));
1134
+ output = JSON.stringify({ outcome: 'fail', error });
1135
+ }
1136
+ debug.log('graph.run', 'handler-result', { graphId, runId, nodeId: current, recipe: node.recipe, ok,
1137
+ outcome: lastJsonObject(output)?.outcome ?? null, ...(error ? { error } : {}) });
1138
+ state.executed++;
1139
+ }
1097
1140
  if (command && !waiving && (!approval || state.dryRun || ok) && (!state.dryRun || command.dry_run_command) && !resumingCompleted) {
1098
1141
  const outputs: Record<string, unknown> = Object.create(null);
1099
1142
  // 구조 산출(마지막 JSON 줄)이 있으면 그것을, 없으면 원문을 준다 — 다음 노드가 판단을 «값»으로 받는다.
@@ -1102,8 +1145,6 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
1102
1145
  mkdirSync(dirname(contextPath), { recursive: true });
1103
1146
  writeFileSync(contextPath, JSON.stringify({ graphId, runId, startedAt: state.startedAt, nodeId: current, input: state.input ?? null, outputs }, null, 2) + '\n');
1104
1147
  let code: number | null = null;
1105
- const redactCredentials = (text: string) => Object.values(credentials).filter(value => value.length > 0)
1106
- .reduce((safe, value) => safe.replaceAll(value, '[REDACTED]'), text);
1107
1148
  const runBash: BashRun = async (body, opts) => {
1108
1149
  const commandRoot = verifyReleaseSource();
1109
1150
  // Hash the actual /bin/bash argv after interpolation. Keep the command text (which may contain
@@ -1243,7 +1284,7 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
1243
1284
  log('graph.unit', { ...info, phase: 'exit', exit: childExit, steps });
1244
1285
  } catch (cause) {
1245
1286
  ok = false;
1246
- error = cause instanceof Error ? cause.message : String(cause);
1287
+ error = redactCredentials(cause instanceof Error ? cause.message : String(cause));
1247
1288
  if (entered) {
1248
1289
  debug.log('graph.unit', 'exit', { ...info, error });
1249
1290
  log('graph.unit', { ...info, phase: 'exit', error });
@@ -1326,7 +1367,16 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
1326
1367
  output = JSON.stringify({ outcome: ok ? 'approved' : 'rejected', graphId, runId, nodeId: current,
1327
1368
  ...(state.pending?.decidedBy === undefined ? {} : { decidedBy: state.pending.decidedBy }), decidedAt: state.pending?.decidedAt ?? null });
1328
1369
  }
1329
- state.nodes.push({ nodeId: current, ok, exit, executed: !waiving && ((!!command && (!state.dryRun || !!command.dry_run_command)) || (!!prompt && !state.dryRun) || (node.kind === 'classify' && !state.dryRun) || unitExecuted), ...((waiving || harnessLoopRoute || units.has(current) || ((command || prompt || approval || node.kind === 'classify') && (!state.dryRun || !!command?.dry_run_command))) && output !== undefined ? { output } : {}), ...(error ? { error } : {}), ...(commandFailureReason ? { reason: commandFailureReason } : {}),
1370
+ const failureMessage = !ok
1371
+ ? redactCredentials(commandFailureReason ?? error ?? `Node ${current} failed without a diagnostic.`)
1372
+ : undefined;
1373
+ const failure = failureMessage === undefined ? undefined : {
1374
+ errorCode: error?.startsWith('unit input missing:') ? 'GRAPH_UNIT_INPUT_MISSING' : 'GRAPH_NODE_FAILED',
1375
+ message: failureMessage,
1376
+ stage: units.has(current) ? 'unit-invocation' : command ? 'command-execution' : prompt ? 'prompt-execution' : 'node-execution',
1377
+ };
1378
+ state.nodes.push({ nodeId: current, ok, exit, executed: !waiving && (handlerExecuted || (!!command && (!state.dryRun || !!command.dry_run_command)) || (!!prompt && !state.dryRun) || (node.kind === 'classify' && !state.dryRun) || unitExecuted), ...((waiving || harnessLoopRoute || units.has(current) || handlerExecuted || ((command || prompt || approval || node.kind === 'classify') && (!state.dryRun || !!command?.dry_run_command))) && output !== undefined ? { output } : {}), ...(error ? { error } : {}),
1379
+ ...(failure ? { reason: failure.message, failure } : {}), ...(commandFailureReason && !failure ? { reason: commandFailureReason } : {}),
1330
1380
  ...(waiving ? { waiver: { reason: options.releaseWaiver!.reason, at: nodeEndedAt, ...(options.releaseWaiver!.unmeasured === undefined ? {} : { unmeasured: options.releaseWaiver!.unmeasured }), original: { exit: waivedRecord!.exit, ...(waivedRecord!.output === undefined ? {} : { output: waivedRecord!.output }), ...(waivedRecord!.error === undefined ? {} : { error: waivedRecord!.error }) } } } : {}),
1331
1381
  ...(approval && state.pending ? { ...(state.pending.decidedBy === undefined ? {} : { decidedBy: state.pending.decidedBy }), decidedAt: state.pending.decidedAt } : {}),
1332
1382
  startedAt: nodeStartedAt, endedAt: nodeEndedAt, seconds });
@@ -1339,15 +1389,17 @@ export async function runGraph(path: string, options: GraphRunOptions = {}): Pro
1339
1389
  delete state.pending;
1340
1390
  delete state.approvalSourceHash;
1341
1391
  }
1342
- const reported: unknown = waiving || harnessLoopRoute || units.has(current) || (prompt && !state.dryRun) || (command && (!state.dryRun || command.dry_run_command)) ? lastJsonObject(resumingCompleted ? completed?.output : output)?.outcome : undefined;
1392
+ const reported: unknown = waiving || harnessLoopRoute || units.has(current) || handlerExecuted || (resumingCompleted && inProcessHandler) || (prompt && !state.dryRun) || (command && (!state.dryRun || command.dry_run_command)) ? lastJsonObject(resumingCompleted ? completed?.output : output)?.outcome : undefined;
1343
1393
  const namedOutcome: string | undefined = typeof reported === 'string' ? reported : undefined;
1344
1394
  if (!options.quiet) console.error(`[graph] ${current} ${ok ? 'ok' : 'fail'} (${seconds.toFixed(2)}s)`);
1395
+ const nodeFailure = state.nodes.at(-1)?.nodeId === current ? state.nodes.at(-1)?.failure : undefined;
1396
+ const nodeReason = state.nodes.at(-1)?.nodeId === current ? state.nodes.at(-1)?.reason : undefined;
1345
1397
  debug.log('graph.run', 'node', { graphId, runId, nodeId: current, phase: ok ? 'ok' : 'fail', seconds, exit,
1346
- ...(commandFailureReason ? { reason: commandFailureReason } : {}) });
1398
+ ...(nodeReason ? { reason: nodeReason } : {}), ...(nodeFailure ? { failure: nodeFailure } : {}) });
1347
1399
  publishInsideEvent({ kind: 'node', graphId, runId, nodeId: current, phase: ok ? 'ok' : 'fail', seconds });
1348
1400
  publishInsideEvent({ kind: 'verdict', graphId, runId, nodeId: current, verdict: ok ? 'ok' : 'fail', ...(namedOutcome === undefined ? {} : { outcome: namedOutcome }) });
1349
1401
  log('node-end', { graphId, runId, nodeId: current, ok, exit,
1350
- ...(commandFailureReason ? { reason: commandFailureReason } : {}),
1402
+ ...(nodeReason ? { reason: nodeReason } : {}), ...(nodeFailure ? { failure: nodeFailure } : {}),
1351
1403
  ...(namedOutcome === undefined ? {} : { outcome: namedOutcome }), dryRun: state.dryRun });
1352
1404
  if (!resumingCompleted) {
1353
1405
  // Recipe commands expose stdout/exit but no provider usage; never infer zero from success.
@@ -34,6 +34,8 @@ export interface GraphWizardRequest {
34
34
  history?: GraphWizardTurn[];
35
35
  /** Installed pack selected for a knowledge (RAG) node. */
36
36
  packId?: string;
37
+ /** Task hand composition: only existing verb units and terminal gates, never free-form commands. */
38
+ missionBase?: { id: string; text: string };
37
39
  }
38
40
 
39
41
  export interface GraphWizardResult {
@@ -653,6 +655,11 @@ function buildPrompt(input: {
653
655
  if (req.history?.length) {
654
656
  lines.push('', '지금까지의 대화:', ...req.history.slice(-10).map((t) => `${t.role === 'user' ? '사용자' : '마법사'}: ${t.text.slice(0, 500)}`));
655
657
  }
658
+ if (req.missionBase) {
659
+ lines.push('', '미션 조합: 기존 graphs/work 표준 조합의 동사 단위(subgraph call: verb-…@정수판)와 끝 gate 만 사용한다.',
660
+ 'cmd·새 권한·외부 효과를 추가하지 마라. merge 앞에는 gate·freeze-check·review 가 모든 경로에서 먼저 와야 한다.',
661
+ `표준 조합 ${req.missionBase.id}:`, '```yaml', req.missionBase.text.trim(), '```');
662
+ }
656
663
  if (editing) {
657
664
  lines.push('', '지금 그래프(이것을 고친다 — 바뀌지 않는 노드의 id 는 그대로 둔다):', '```yaml', req.currentYaml!.trim(), '```',
658
665
  '', `사용자의 수정 지시: ${req.prompt}`,
@@ -705,7 +712,7 @@ export async function generateGraphFromPrompt(req: GraphWizardRequest, deps: Gra
705
712
  let id = editing ? currentId! : wizardGraphId(prompt, undefined, taken);
706
713
  const callLLM = deps.callLLM ?? defaultCallLLM;
707
714
  const maxAttempts = Math.max(1, deps.maxAttempts ?? GRAPH_WIZARD_MAX_ATTEMPTS);
708
- let base = keywordBase?.id;
715
+ let base = req.missionBase?.id ?? keywordBase?.id;
709
716
  let yaml = '';
710
717
  let issues: string[] = [];
711
718
  let llmSummary: string | undefined;
@@ -726,7 +733,7 @@ export async function generateGraphFromPrompt(req: GraphWizardRequest, deps: Gra
726
733
  }
727
734
  if (attempts === 1 && !editing) {
728
735
  const picked = lineValue(text, 'BASE');
729
- if (picked && picked !== base && templates.some((t) => t.id === picked)) { base = picked; baseReason = `LLM 재선택 (키워드 후보 ${keywordBase?.id ?? '-'})`; }
736
+ if (!req.missionBase && picked && picked !== base && templates.some((t) => t.id === picked)) { base = picked; baseReason = `LLM 재선택 (키워드 후보 ${keywordBase?.id ?? '-'})`; }
730
737
  const slug = lineValue(text, 'SLUG');
731
738
  if (slug && !currentId) id = wizardGraphId(prompt, slug, taken);
732
739
  }
@@ -746,13 +753,15 @@ export async function generateGraphFromPrompt(req: GraphWizardRequest, deps: Gra
746
753
  recipes = undefined;
747
754
  dryRun = undefined;
748
755
  if (kind === 'harness' && issues.length === 0) {
749
- issues = stepIssues(yaml, steps);
756
+ if (!req.missionBase) issues = stepIssues(yaml, steps);
750
757
  const nodes = ((parseYaml(yaml) as { nodes?: Array<{ node_id?: unknown; recipe?: unknown }> }).nodes ?? [])
751
758
  .map((n) => ({ nodeId: String(n.node_id), recipe: typeof n.recipe === 'string' ? n.recipe : '' }));
752
- recipes = recipesYamlFor(nodes, steps);
753
- const walked = await dryRunWizardGraph(yaml, recipes);
754
- dryRun = { status: walked.status, path: walked.path };
755
- if (walked.status !== 'done') issues.push(`graph run --dry-run: ${walked.status}${walked.error ? ` — ${walked.error}` : ''} (경로 ${walked.path.join(' → ')})`);
759
+ if (!req.missionBase) {
760
+ recipes = recipesYamlFor(nodes, steps);
761
+ const walked = await dryRunWizardGraph(yaml, recipes);
762
+ dryRun = { status: walked.status, path: walked.path };
763
+ if (walked.status !== 'done') issues.push(`graph run --dry-run: ${walked.status}${walked.error ? ` — ${walked.error}` : ''} (경로 ${walked.path.join(' → ')})`);
764
+ }
756
765
  }
757
766
  debug.log('graph.wizard', 'attempt', { id, attempt: attempts, base, ok: issues.length === 0, issues: issues.slice(0, 10) });
758
767
  if (issues.length === 0) break;
@@ -0,0 +1,201 @@
1
+ import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { parse as parseYaml } from 'yaml';
4
+ import { validateGraphYaml } from '../nexus/api/graph-kinds.js';
5
+ import { edgeMapOf, parseGraphTemplateYaml, type GraphTemplateSpec } from '../self-implement/graph-yaml.js';
6
+ import { resolveGraphUnit } from '../self-implement/graph-unit-resolver.js';
7
+ import { inspectPipelineGraph } from '../self-implement/pipeline-shape.js';
8
+ import { debug } from '../debug/log.js';
9
+ import { generateGraphFromPrompt, type GraphWizardDeps } from './generate.js';
10
+ import type { CompletionKind, CompositionSelection } from '../task-agent/task-hand.js';
11
+
12
+ export interface MissionComposeInput {
13
+ text: string;
14
+ completion: CompletionKind;
15
+ root: string;
16
+ ledgerPath: string;
17
+ cardId: string;
18
+ standard: CompositionSelection;
19
+ }
20
+
21
+ /** The LLM may choose the order of existing verb calls, but not their authority or the hand's launcher. */
22
+ export function missionGraphIssues(yaml: string, baseYaml: string, root: string, generatedPath?: string): string[] {
23
+ const checked = validateGraphYaml('harness', yaml);
24
+ const issues = checked.errors.map(error => typeof error === 'string' ? error : JSON.stringify(error));
25
+ const parsed = parseGraphTemplateYaml(yaml);
26
+ const base = parseGraphTemplateYaml(baseYaml);
27
+ issues.push(...parsed.errors.map(error => `${error.path}: ${error.message}`));
28
+ if (!parsed.template || !base.template) return issues;
29
+ const graph = parsed.template;
30
+ const standard = base.template;
31
+ const raw = parseYaml(yaml) as Record<string, unknown>;
32
+ const baseRaw = parseYaml(baseYaml) as Record<string, unknown>;
33
+ if (raw.launcher !== baseRaw.launcher) issues.push('I6: 표준 launcher 제어를 바꿀 수 없다');
34
+ for (const key of new Set([...Object.keys(baseRaw), ...Object.keys(raw)])) {
35
+ if (['graph_id', 'loop', 'nodes', 'edges'].includes(key)) continue;
36
+ if (JSON.stringify(raw[key]) !== JSON.stringify(baseRaw[key])) issues.push(`I6: 표준 제어 ${key} 변경 금지`);
37
+ }
38
+ if (raw.entry_node !== baseRaw.entry_node) issues.push('I6: 표준 진입 노드를 바꿀 수 없다');
39
+ if (JSON.stringify(raw.terminal_nodes) !== JSON.stringify(baseRaw.terminal_nodes)) issues.push('I4: 표준 종료 노드를 바꿀 수 없다');
40
+ const baseLoop = baseRaw.loop as { trigger?: unknown } | undefined;
41
+ const loop = raw.loop as { trigger?: unknown } | undefined;
42
+ if (JSON.stringify(loop?.trigger) !== JSON.stringify(baseLoop?.trigger)) issues.push('I6: 표준 트리거 변경 금지');
43
+ const rawNodes = Array.isArray(raw.nodes) ? raw.nodes as Array<Record<string, unknown>> : [];
44
+ const baseNodes = Array.isArray(baseRaw.nodes) ? baseRaw.nodes as Array<Record<string, unknown>> : [];
45
+ for (const node of rawNodes) {
46
+ const original = baseNodes.find(candidate => candidate.call && candidate.call === node.call)
47
+ ?? baseNodes.find(candidate => candidate.node_id === node.node_id && candidate.kind === 'gate');
48
+ if (!original) continue;
49
+ const keys = new Set([...Object.keys(node), ...Object.keys(original)]);
50
+ for (const key of keys) {
51
+ if (key === 'node_id' || key === 'max_visits') continue;
52
+ if (JSON.stringify(node[key]) !== JSON.stringify(original[key])) issues.push(`I6: ${String(node.node_id)} 권한 ${key} 변경 금지`);
53
+ }
54
+ }
55
+ const rawEdges = Array.isArray(raw.edges) ? raw.edges as Array<Record<string, unknown>> : [];
56
+ if (rawEdges.some(edge => Object.keys(edge).some(key => !['from', 'to', 'on', 'map'].includes(key))))
57
+ issues.push('I6: 간선 조건·폴백 권한 추가 금지');
58
+ const allowed = new Map(standard.nodes.filter(n => n.kind === 'subgraph' && n.call?.startsWith('verb-')).map(n => [n.call!, n]));
59
+ const standardById = new Map(standard.nodes.map(n => [n.nodeId, n]));
60
+ const seenCalls = new Set<string>();
61
+ for (const node of graph.nodes) {
62
+ const original = standardById.get(node.nodeId);
63
+ if (!original && /(?:merge|publish|send|pay|charge|deploy|release)/i.test(`${node.nodeId} ${node.call ?? ''}`))
64
+ issues.push(`I5: 외부 효과 동사 추가 금지 (${node.nodeId})`);
65
+ if (original?.kind === 'gate' && node.kind === 'gate'
66
+ && JSON.stringify(node) === JSON.stringify(original)) continue;
67
+ const known = node.kind === 'subgraph' && node.call ? allowed.get(node.call) : undefined;
68
+ if (!known || node.recipe !== 'none' || node.maxVisits > known.maxVisits
69
+ || JSON.stringify(node.contract) !== JSON.stringify(known.contract)
70
+ || JSON.stringify(node.budget) !== JSON.stringify(known.budget)
71
+ || node.skipWhen !== undefined || node.callEntry !== undefined)
72
+ issues.push(`권한 표: ${node.nodeId} 는 허용된 동사 단위가 아니다`);
73
+ if (node.call) seenCalls.add(node.call);
74
+ }
75
+ for (const call of allowed.keys()) if (!seenCalls.has(call)) issues.push(`권한 표: 표준 동사 단위 ${call} 누락`);
76
+ for (const required of standard.nodes.filter(n => n.kind === 'gate' || ['gate', 'freeze-check', 'review'].includes(n.nodeId))) {
77
+ if (!graph.nodes.some(n => n.nodeId === required.nodeId && JSON.stringify(n) === JSON.stringify(required))) issues.push(`권한 표: 보호 노드 ${required.nodeId} 누락 또는 변경`);
78
+ }
79
+ for (const terminal of standard.terminalNodes) if (!graph.terminalNodes.includes(terminal)) issues.push(`I4: 종료 ${terminal} 누락`);
80
+ const edges = edgeMapOf(graph);
81
+ issues.push(...inspectPipelineGraph(edges, graph.entryNode).map(defect => `I4: ${JSON.stringify(defect)}`));
82
+ for (const node of graph.nodes) {
83
+ const reachable = new Set<string>();
84
+ const queue = [node.nodeId];
85
+ while (queue.length) {
86
+ const id = queue.shift()!;
87
+ if (reachable.has(id)) continue;
88
+ reachable.add(id);
89
+ queue.push(...(edges[id] ?? []));
90
+ }
91
+ if (![...reachable].some(id => graph.terminalNodes.includes(id))) issues.push(`I4: ${node.nodeId} 에서 종료 불가`);
92
+ }
93
+ const mergeNodes = graph.nodes.filter(n => n.nodeId.includes('merge') || n.call?.includes('merge'));
94
+ for (const merge of mergeNodes) {
95
+ const prerequisites = ['gate', 'freeze-check', 'review'];
96
+ const walk = (id: string, seen: Set<string>, met: Set<string>): void => {
97
+ if (id === merge.nodeId) {
98
+ for (const required of prerequisites) if (!met.has(required)) issues.push(`I1~I3: merge 앞 ${required} 없음`);
99
+ return;
100
+ }
101
+ if (seen.has(id)) return;
102
+ const nextMet = new Set(met);
103
+ if (prerequisites.includes(id)) nextMet.add(id);
104
+ const nextSeen = new Set(seen).add(id);
105
+ for (const target of edges[id] ?? []) walk(target, nextSeen, nextMet);
106
+ };
107
+ walk(graph.entryNode, new Set(), new Set());
108
+ }
109
+ for (const node of graph.nodes.filter(n => n.kind === 'subgraph')) {
110
+ if (!node.call || !allowed.has(node.call)) continue;
111
+ try {
112
+ const canonical = resolveGraphUnit(node.call, join(root, 'graphs/work', 'generated.yaml'));
113
+ const actual = resolveGraphUnit(node.call, generatedPath ?? join(root, 'graphs/work', 'generated.yaml'));
114
+ const unit = actual.template;
115
+ if (actual.hash !== canonical.hash || `${unit.graphId}@${unit.version}` !== node.call || !unit.unit ||
116
+ JSON.stringify(unit.unit.inputs) !== JSON.stringify(node.contract?.inputs) ||
117
+ JSON.stringify(unit.unit.outputs) !== JSON.stringify(node.contract?.outputs)) issues.push(`권한 표: 동사 단위 미해석 ${node.call}`);
118
+ } catch { issues.push(`권한 표: 동사 단위 미해석 ${node.call}`); }
119
+ }
120
+ return [...new Set(issues)];
121
+ }
122
+
123
+ export async function composeMissionGraph(input: MissionComposeInput, deps: Pick<GraphWizardDeps, 'callLLM'> & { deferPersistence?: boolean } = {}): Promise<{
124
+ selection: CompositionSelection; reason: string; persist: () => void;
125
+ }> {
126
+ const fallback = input.standard;
127
+ let files: string[] = [];
128
+ try { files = readdirSync(join(input.root, 'graphs/work')).filter(name => name.endsWith('.yaml') && name !== 'recipes.yaml'); }
129
+ catch { /* The fixed selection already carries the missing or unreadable-template reason. */ }
130
+ const candidates = files.flatMap(file => {
131
+ const path = join(input.root, 'graphs/work', file);
132
+ try {
133
+ const yaml = readFileSync(path, 'utf8');
134
+ const parsed = parseGraphTemplateYaml(yaml, path);
135
+ return parsed.template && !parsed.errors.length && (parseYaml(yaml) as { launcher?: unknown }).launcher
136
+ ? [{ file: `graphs/work/${file}`, yaml, template: parsed.template }] : [];
137
+ } catch { return []; }
138
+ });
139
+ const standardFile = fallback.composition?.file;
140
+ const words = input.text.toLowerCase().match(/[\p{L}\p{N}]+/gu) ?? [];
141
+ const score = (item: { file: string; template: GraphTemplateSpec }) => {
142
+ const label = `${item.file} ${item.template.graphId} ${item.template.loop?.title ?? ''} ${item.template.loop?.description ?? ''}`.toLowerCase();
143
+ return words.reduce((total, word) => total + (word.length > 1 && label.includes(word) ? 1 : 0), 0);
144
+ };
145
+ const standardLauncher = standardFile ? candidates.find(item => item.file === standardFile) : undefined;
146
+ const compatible = candidates.filter(item => (parseYaml(item.yaml) as { launcher: unknown }).launcher ===
147
+ (standardLauncher ? (parseYaml(standardLauncher.yaml) as { launcher: unknown }).launcher : undefined)
148
+ && item.template.nodes.every(node => node.kind === 'gate' || node.kind === 'subgraph' && node.call?.startsWith('verb-')));
149
+ const base = compatible.sort((a, b) => score(b) - score(a) || Number(b.file === standardFile) - Number(a.file === standardFile))[0];
150
+ const prefix = base ? `문면 선택 ${base.file} (일치 ${score(base)})` : '표준 조합 없음';
151
+ let generated = '';
152
+ let issues: string[] = [];
153
+ let selection = fallback;
154
+ if (base && base.file !== standardFile && fallback.launcher === 'graph-run' && !fallback.error) {
155
+ const missingUnits: string[] = [];
156
+ const { validateUnitCalls } = await import('../graph-runner/runner.js');
157
+ try { validateUnitCalls(base.template, join(input.root, base.file), [], call => missingUnits.push(call)); }
158
+ catch (error) { issues.push(`표준 조합 단위 해석 오류: ${error instanceof Error ? error.message : String(error)}`); }
159
+ if (!issues.length && !missingUnits.length) selection = {
160
+ composition: { file: base.file, version: base.template.version }, launcher: 'graph-run', unitsResolved: true, missingUnits: [],
161
+ };
162
+ else if (missingUnits.length) issues.push(`표준 조합 단위 미해석: ${missingUnits.join(', ')}`);
163
+ }
164
+ if (base && selection.composition && !selection.error && !issues.length &&
165
+ (base.file === standardFile || selection.launcher === 'graph-run')) {
166
+ try {
167
+ const proposal = await generateGraphFromPrompt({ prompt: input.text, kind: 'harness', missionBase: { id: base.template.graphId, text: base.yaml } },
168
+ { callLLM: deps.callLLM, graphsDir: join(input.root, 'graphs'), existingIds: () => new Set(), maxAttempts: 1 });
169
+ generated = proposal.yaml;
170
+ const launcher = (parseYaml(base.yaml) as { launcher: string }).launcher;
171
+ if (!(parseYaml(generated) as { launcher?: unknown }).launcher)
172
+ generated = generated.replace(/^(graph_id:\s*[^\n]+\n)/, `$1launcher: ${launcher}\n`);
173
+ issues = missionGraphIssues(generated, base.yaml, input.root,
174
+ join(dirname(input.ledgerPath), `${input.cardId}.generated.yaml`));
175
+ if (!proposal.ok) issues.push(...proposal.issues);
176
+ if (launcher !== 'graph-run') issues.push('권한 표: harness-say 는 생성된 graph-run 조합으로 전환할 수 없다');
177
+ const directory = dirname(input.ledgerPath);
178
+ const recipePath = join(directory, 'recipes.yaml');
179
+ if (existsSync(recipePath) && readFileSync(recipePath, 'utf8') !== readFileSync(join(input.root, 'graphs/work/recipes.yaml'), 'utf8'))
180
+ issues.push('권한 표: 원장 옆 recipes.yaml 이 표준과 다르다');
181
+ if (!issues.length) {
182
+ const target = join(dirname(input.ledgerPath), `${input.cardId}.generated.yaml`);
183
+ selection = { composition: { file: target, version: parseGraphTemplateYaml(generated).template!.version },
184
+ launcher: launcher as 'graph-run' | 'harness-say', unitsResolved: true, missingUnits: [] };
185
+ }
186
+ } catch (error) { issues.push(`생성 실패: ${error instanceof Error ? error.message : String(error)}`); }
187
+ } else if (!issues.length) issues.push('표준 조합을 읽을 수 없다');
188
+ const reason = issues.length ? `${prefix} → fallback-standard: ${issues.join('; ')}` : `${prefix} → composed: 동사 단위 검증 통과`;
189
+ const persist = (): void => {
190
+ const directory = dirname(input.ledgerPath);
191
+ mkdirSync(directory, { recursive: true });
192
+ if (generated) writeFileSync(join(directory, `${input.cardId}.generated.yaml`), generated);
193
+ if (selection.composition?.file === join(directory, `${input.cardId}.generated.yaml`) && !existsSync(join(directory, 'recipes.yaml')))
194
+ writeFileSync(join(directory, 'recipes.yaml'), readFileSync(join(input.root, 'graphs/work/recipes.yaml'), 'utf8'), { flag: 'wx' });
195
+ writeFileSync(join(directory, `${input.cardId}.composition.json`), JSON.stringify({ base: base?.file ?? null,
196
+ selected: selection.composition?.file ?? null, reason, issues, generated: generated ? `${input.cardId}.generated.yaml` : null }));
197
+ };
198
+ if (!deps.deferPersistence) persist();
199
+ debug.log('graph.compose', issues.length ? 'fallback-standard' : 'composed', { card: input.cardId, base: base?.file ?? null, reason });
200
+ return { selection, reason, persist };
201
+ }
@@ -55,6 +55,9 @@ export interface GrokAgentSearchOpts {
55
55
  signal?: AbortSignal;
56
56
  fetchImpl?: FetchLike;
57
57
  apiKey?: string;
58
+ /** Subscription proxy endpoint and required CLI headers. Omit for the metered xAI API. */
59
+ baseUrl?: string;
60
+ headers?: Record<string, string>;
58
61
  }
59
62
 
60
63
  export interface GrokCitation {
@@ -106,10 +109,13 @@ export async function grokAgentSearch(
106
109
 
107
110
  let res: Response;
108
111
  try {
109
- res = await fetchImpl(GROK_RESPONSES_URL, {
112
+ const endpoint = opts.baseUrl
113
+ ? `${opts.baseUrl.replace(/\/$/, '').replace(/\/responses$/, '')}/responses`
114
+ : GROK_RESPONSES_URL;
115
+ res = await fetchImpl(endpoint, {
110
116
  method: 'POST',
111
117
  signal: ac.signal,
112
- headers: { 'content-type': 'application/json', authorization: `Bearer ${apiKey}` },
118
+ headers: { 'content-type': 'application/json', authorization: `Bearer ${apiKey}`, ...opts.headers },
113
119
  body: JSON.stringify({
114
120
  model,
115
121
  input,
@@ -345,6 +345,11 @@ function readGrokCredential(opts: {
345
345
  return null;
346
346
  }
347
347
 
348
+ /** Read-only credential check for synchronous provider availability. Never refreshes or calls the network. */
349
+ export function peekGrokCredential(opts: { home?: string; model?: string } = {}): GrokCredential | null {
350
+ return readGrokCredential(opts);
351
+ }
352
+
348
353
  export interface ResolveGrokCredentialOpts {
349
354
  env?: NodeJS.ProcessEnv;
350
355
  home?: string;
@@ -50,6 +50,8 @@ export interface ReferenceCard {
50
50
  kind: GroundingSource['kind'];
51
51
  name: string;
52
52
  oneLine: string;
53
+ /** Relative path that supplied oneLine, when a README was readable. */
54
+ oneLineFile?: string;
53
55
  directories: string[];
54
56
  receivedAt?: string;
55
57
  /** L1 */
@@ -57,6 +59,13 @@ export interface ReferenceCard {
57
59
  commands: string[];
58
60
  /** A file-count or byte limit cut the read short — the lists may be incomplete. */
59
61
  truncated: boolean;
62
+ /** Stable identity of this card inside the grounding orchestration log. */
63
+ orchestrationId: string;
64
+ }
65
+
66
+ /** Stable identity of this card inside the grounding orchestration log. */
67
+ export function orchestrationId(kind: string, id: string): string {
68
+ return `grounding:${kind}:${id}`;
60
69
  }
61
70
 
62
71
  export function buildReferenceCard(
@@ -132,14 +141,35 @@ export function buildReferenceCard(
132
141
  kind: source.kind,
133
142
  name: packageName ?? basename(root),
134
143
  oneLine,
144
+ ...(oneLine && readme ? { oneLineFile: readme.name } : {}),
135
145
  directories,
136
146
  ...(receivedAt ? { receivedAt } : {}),
137
147
  titles,
138
148
  commands,
139
149
  truncated,
150
+ orchestrationId: orchestrationId(source.kind, source.id),
140
151
  };
141
152
  }
142
153
 
154
+ /**
155
+ * Cards for a whole registry/discovery batch. Read-only: no writes anywhere.
156
+ * Non-local kinds and unreadable paths are skipped — one bad source must not
157
+ * sink the batch. Pure value out.
158
+ */
159
+ export function buildReferenceCardsForRegistry(
160
+ sources: readonly GroundingSource[],
161
+ fs: RefIndexFs = nodeRefIndexFs,
162
+ limits: Partial<RefIndexLimits> = {},
163
+ ): ReferenceCard[] {
164
+ const cards: ReferenceCard[] = [];
165
+ for (const source of sources) {
166
+ if ((source.kind !== 'local-repo' && source.kind !== 'local-docs') || !source.path) continue;
167
+ if (fs.mtimeMs(source.path) === undefined) continue;
168
+ cards.push(buildReferenceCard(source, fs, limits));
169
+ }
170
+ return cards;
171
+ }
172
+
143
173
  function receivedAtOf(source: GroundingSource, fs: RefIndexFs, root: string): string | undefined {
144
174
  if (source.kind === 'local-repo') {
145
175
  const commit = fs.lastCommitAt(root);
@@ -0,0 +1,61 @@
1
+ import type { Database } from 'bun:sqlite';
2
+ import { chunkReport, hybridQueryKnowledge, ingestText, type EmbedFn, type HybridMatch } from '../domains/knowledge.js';
3
+ import type { ReferenceCard } from './ref-index.js';
4
+
5
+ export interface ReferenceIngestOptions {
6
+ embed: EmbedFn;
7
+ maxChunks?: number;
8
+ }
9
+
10
+ export interface ReferenceQueryOptions {
11
+ embed: EmbedFn;
12
+ k?: number;
13
+ }
14
+
15
+ /** Keep the source ID and a real relative file path together in each returned citation. */
16
+ function sourceRef(id: string, file: string): string | null {
17
+ if (!id || !file || file.startsWith('/') || /^[a-zA-Z]:/.test(file) || file.split(/[\\/]/).some((part) => part === '..' || part === '.')) return null;
18
+ return `${id}#${file}`;
19
+ }
20
+
21
+ /** Index only card text whose original file is known; an invented README path must never become a citation. */
22
+ export async function ingestReferenceCard(
23
+ db: Database,
24
+ card: ReferenceCard,
25
+ opts: ReferenceIngestOptions,
26
+ ): Promise<{ ingested: number; truncated: boolean }> {
27
+ const maxChunks = opts.maxChunks ?? 200;
28
+ if (!Number.isSafeInteger(maxChunks) || maxChunks < 0) throw new Error('reference maxChunks must be a nonnegative integer');
29
+ const entries: Array<{ file: string; text: string }> = [];
30
+ if (card.oneLine && card.oneLineFile) entries.push({ file: card.oneLineFile, text: card.oneLine });
31
+ for (const title of card.titles) entries.push({ file: title.file, text: title.title });
32
+ for (const command of card.commands) entries.push({ file: 'package.json', text: command });
33
+ const chunks = entries.flatMap(({ file, text }) => {
34
+ const ref = sourceRef(card.id, file);
35
+ return ref ? chunkReport(text).map((chunk) => ({ ref, text: chunk })) : [];
36
+ });
37
+ let ingested = 0;
38
+ const ts = card.receivedAt ?? new Date(0).toISOString();
39
+ for (const [index, chunk] of chunks.slice(0, maxChunks).entries()) {
40
+ if (await ingestText(db, {
41
+ id: `reference:${card.id}:${index}`,
42
+ ts,
43
+ kind: 'reference',
44
+ domain: 'elanous',
45
+ text: chunk.text,
46
+ source_ref: chunk.ref,
47
+ }, opts.embed)) ingested++;
48
+ }
49
+ return { ingested, truncated: card.truncated || chunks.length > maxChunks };
50
+ }
51
+
52
+ /** Reuse the knowledge hybrid ranker, but never return a result without a source link. */
53
+ export async function queryReferences(
54
+ db: Database,
55
+ query: string,
56
+ opts: ReferenceQueryOptions,
57
+ ): Promise<HybridMatch[]> {
58
+ const k = Math.min(Math.max(opts.k ?? 5, 1), 20);
59
+ const matches = await hybridQueryKnowledge(db, query, { kind: 'reference', domain: 'elanous', k: 20, embed: opts.embed });
60
+ return matches.filter((match) => !!match.source_ref).slice(0, k);
61
+ }