elanous 0.2.41 → 0.2.43

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 (796) 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/{GiOLWmt4MqDZePubBjA4Q → Om5xS9jpjSXJCeTNGYEi4}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{2fe2c302.41b517f88d6fe502.js → 0966f8a1.745fcd44f64a87ea.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{385e4574.e9886ab32759eda3.js → 0ad6802e.ae7afb63fdcb4491.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/114.2b90424d1a3ce84c.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1151-5c2bb8f002ca2dd6.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1200.6a37c202f9f17e9a.js +226 -0
  9. package/apps/pwa/out/_next/static/chunks/1261-a616d5728e02e624.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1313-19f737e0222c4444.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1357.3bbef3976c37f94a.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/1362-20adddfaf662b0fa.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/{6874.d5cf7eb8edb2cabe.js → 1406.a1dc2ab6f8449374.js} +2 -2
  14. package/apps/pwa/out/_next/static/chunks/1737-9491fc6ab29b9ec6.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1803-4f91a8e7dcaf042c.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/{5744.b9415e18ad623100.js → 1961.a81b12872c3e93a9.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/1970cf59.2d4d8ce5d6c81853.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1971-8890f3962ba7ee0a.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/2073-ba274e00e4f9efb4.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/{5471.1e611302ed3a7c53.js → 2144.25b292396712196d.js} +2 -2
  21. package/apps/pwa/out/_next/static/chunks/{3230-49298c3b73ef2268.js → 2268-53861f339e0b65a2.js} +1 -1
  22. package/apps/pwa/out/_next/static/chunks/{9834.63ab2bbc3153172e.js → 2312.0c8b61e22d3136d7.js} +1 -1
  23. package/apps/pwa/out/_next/static/chunks/{1800.f7ff51dc4978a958.js → 2573.387a707f6f9d720c.js} +2 -2
  24. package/apps/pwa/out/_next/static/chunks/273.f156eee28f11af77.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2873.d2140e5a82546401.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/{9048.212083de42d25be3.js → 3072.01338851ca21a6f7.js} +2 -2
  27. package/apps/pwa/out/_next/static/chunks/3091.a5a4143dea33d197.js +90 -0
  28. package/apps/pwa/out/_next/static/chunks/3095.dc44586a5f83b86d.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{2263.e09b6edea33bad2d.js → 3113.d7472bbc27d580c7.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/3228-9650b6447b6fa288.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/3402.44b565b314f2263c.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{addc2b32.8c4ff8f0aefe987d.js → 3557ac4a.c8931684475018ad.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/360.ae9f9f4c33c395e8.js +79 -0
  34. package/apps/pwa/out/_next/static/chunks/3638.80412ea63aae8f3f.js +286 -0
  35. package/apps/pwa/out/_next/static/chunks/{a0a01613.6d1cca322238d7fe.js → 363bfab3.9623b9f89363541f.js} +1 -1
  36. package/apps/pwa/out/_next/static/chunks/3694.e0099884345f0198.js +64 -0
  37. package/apps/pwa/out/_next/static/chunks/3744.54f87db52acfd1ab.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3903.3ef4656c67572764.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3935.16701e33f8982dc9.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3955.6922286237f2ac2b.js +24 -0
  41. package/apps/pwa/out/_next/static/chunks/3969.272ee7f9fd6c62e5.js +34 -0
  42. package/apps/pwa/out/_next/static/chunks/4199.ce86b281fd0a60b7.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4311-6dd3144002cc0c2d.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4426-2b230fad00c88930.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{530.d26346e18089640a.js → 4445.7990c76b3751a918.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/4447-14c5161fa59166c7.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4856-b0b8075bba8c53f4.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4870-de370d65e73c0bb5.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4885-2c989165c4b29fad.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4894.fec2ca9e99caefa2.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/5093.8f04b7f8cb899a95.js +94 -0
  52. package/apps/pwa/out/_next/static/chunks/5122-2bb177cebf89e19a.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/5154.5f56dc3902e3d275.js +36 -0
  54. package/apps/pwa/out/_next/static/chunks/529.64ff7257180b2ac9.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5394.5dabeb0c62293a28.js +93 -0
  56. package/apps/pwa/out/_next/static/chunks/5461.08bf2404ff38ec85.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5474-22e08a85583209b2.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/{1219.7e17964e0e7cd8e5.js → 5564.9e72532188f57586.js} +3 -3
  59. package/apps/pwa/out/_next/static/chunks/5567-265df39ed8fe9dcb.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5570-a94ae19811cb2046.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5574-b47c9ef2dceff1fd.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5628.6ddb2d5ffba4ff4c.js +309 -0
  63. package/apps/pwa/out/_next/static/chunks/5730.43d7ccc09988e646.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/{1178.1aa9cad0e7695427.js → 5789.2da35c258292e1e5.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/{4133.2056bb4d78f621af.js → 5824.da9527b15a3221e5.js} +1 -1
  66. package/apps/pwa/out/_next/static/chunks/5866.366966af47fdde5d.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/{4527.a69f2894d1bc9f4a.js → 5930.8b4df3b46c32b05a.js} +1 -1
  68. package/apps/pwa/out/_next/static/chunks/5963-c4d8469c52a0828b.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/6001.ec4049ceb3c43418.js +27 -0
  70. package/apps/pwa/out/_next/static/chunks/6120-471f03db1e299c0c.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6175-41479e643aca1878.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6291.a2de4f9787637075.js +104 -0
  73. package/apps/pwa/out/_next/static/chunks/6400-6699907c3537436a.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/6428.1f4327d6ae5fdf9a.js +287 -0
  75. package/apps/pwa/out/_next/static/chunks/644.02cb026fa44bcd0a.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6466-6c87d60d3dd174fb.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/{9507.7026657a2f47eb64.js → 6540.c7bef57ad8f90a87.js} +16 -16
  78. package/apps/pwa/out/_next/static/chunks/6773.d4264665ab31bec0.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6822.3c789f1a8443e774.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/{5574.f35accf4f132b29d.js → 6944.309f4e3ea54d1537.js} +1 -1
  81. package/apps/pwa/out/_next/static/chunks/7261-8ff69d3b2ee671fd.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/7266.084c6bbc70035140.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/7271.5c0100e7320aa856.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7429-bf5731358c8f2f68.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7464.01f7a0ae1215fbe7.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7479.0fcad5f37eb64f0c.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7483.427a2fe2049e388d.js +148 -0
  88. package/apps/pwa/out/_next/static/chunks/7502-be74718178e13e56.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7530.0889722b19572065.js +24 -0
  90. package/apps/pwa/out/_next/static/chunks/7645.5b2ee3ad45c55ea3.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7788.7d1c79f1a8e18946.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7900.096f455c7c1efc53.js +77 -0
  93. package/apps/pwa/out/_next/static/chunks/7910-6f139bcafd238b9f.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7966.f71c8958d1637548.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{5947-135e26537d80a6b9.js → 8062-7cd0bcc7f01455ba.js} +3 -3
  96. package/apps/pwa/out/_next/static/chunks/8073.f6cf2f2c71aafbd0.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8201.190b94088980f430.js +74 -0
  98. package/apps/pwa/out/_next/static/chunks/8205.282ca4bb62d54a0a.js +62 -0
  99. package/apps/pwa/out/_next/static/chunks/8313-dfa1021bb58a46d6.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/837-81336ebaca8198a8.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8447.7963352ef5f71b76.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8574-868e8129525ef6d9.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8588.d1c6a2903727ce87.js +149 -0
  104. package/apps/pwa/out/_next/static/chunks/8637.90f92d5c8db4732c.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{2743.5d3f76948be32b34.js → 868.6e953be05bcf6dca.js} +2 -2
  106. package/apps/pwa/out/_next/static/chunks/8706-e1fe0309343a2273.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8749-06384cdfc4520add.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/{5964-7e21164a8f2cf0ce.js → 8861-cc1fa1c7b920fa8e.js} +1 -1
  109. package/apps/pwa/out/_next/static/chunks/8967-7dfebf710c9dec9d.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{5159.115f1c2ca471386c.js → 8986.8e2e4efbfa655c59.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/8997-3c564dbb3b58b055.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/923.2034d10ae91e9c20.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9312.bc1b89c5d4368033.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/943.39ae5e82f4f1893f.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9469.0500480de55fb205.js +32 -0
  116. package/apps/pwa/out/_next/static/chunks/9770.5f75bc6088b16109.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9810-2543267050e58b82.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9870.8419702475254745.js +8 -0
  119. package/apps/pwa/out/_next/static/chunks/9941-376d1b74d51b01a4.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9958.385434ab04241758.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{b2271e54.c1de3347976e90b0.js → aa57532f.510551854ff239b1.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-deea1450b17cb8dc.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-70985b904f8650ef.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a2e15e33e56a4353.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-fc72ce2db12d6ca9.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-be03e41f9436ebd9.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-35a35999382da3f2.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-3ff5b1e6ca88b848.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-a65101300a0ee5c1.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-3aca5b6d67dba511.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-45b8ab0a71e61314.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-53046e282d4cda8e.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-17809e60e8354c17.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-fd2442d347bf5898.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-e9d720d6fc082e21.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-6b8b4267bab0a677.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-deea1450b17cb8dc.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-8bcf6233ac7c17af.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-7cc25591cfc2126f.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-053e871f35c9beba.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-eff819f0c2d5e084.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-4d7e9d8db5274a87.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-2b2d8f5aa5f69ad4.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-0b8f92c5062e68b1.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1bd9d0fdac2ced3d.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-9ee28f7df07428ea.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-44b7a1ff468c6648.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-cbc6523711dc1b65.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-fdad47899c2695be.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/{page-40f9e19149024298.js → page-79a8b5fee4c20871.js} +1 -1
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-03e8ac9606aeaffb.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-4cd55c55ec287e2f.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-db17b4305404161e.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-30041d848350fd02.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c540da022dbf86b0.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9399efc538da057f.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-a142dfb0331a05f5.js → page-ca2d09128c585ca4.js} +1 -1
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-0e2635aecd343038.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ef7f4399b6b7726e.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-deea1450b17cb8dc.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-caf530535b875468.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-eaa20c1543a5fd8e.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c541eb1b75120f61.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-ab5e213eda9479f4.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-0a815f34367b6db6.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-e858ba0ed9393b68.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-1638ee9dd6e0582f.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-4cf5a399109391f2.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-b4396321238798ec.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-cb72bfd21006781a.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6135d0242afbc434.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a1dccf907eddb856.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{53aeb4ee-51c92f8d683f5220.js → c7945435-b44d4dbe90ba0dcb.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/{2fdf2931.b431eee4fb468bc3.js → cb0f8df8.09a4a6be97e3fc5f.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/{c0c1a699.0ba79f97005965d4.js → d96660fb.cbc21a2a88539dbb.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/ea514caa.05a24f78d9dffe5f.js +122 -0
  177. package/apps/pwa/out/_next/static/chunks/{83184dcd-0ee6247ff41eb3f2.js → fb7d20d5-6892502b6ee39ca6.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/framework-e8a911e19b1be41f.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-7022f418fabba021.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-e5f15df755756a1e.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-4525f91e36940c9b.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-140f0e519c085b0f.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-8f22ef63dcb865b1.js +1 -0
  184. package/apps/pwa/out/_next/static/css/{b9d8151e48998417.css → 62c858ad53854f47.css} +1 -1
  185. package/apps/pwa/out/_next/static/css/d1f8bb401740a549.css +1 -0
  186. package/apps/pwa/out/approvals/index.html +1 -1
  187. package/apps/pwa/out/approvals/index.txt +23 -23
  188. package/apps/pwa/out/autopilot/index.html +1 -1
  189. package/apps/pwa/out/autopilot/index.txt +23 -23
  190. package/apps/pwa/out/board/index.html +1 -1
  191. package/apps/pwa/out/board/index.txt +23 -23
  192. package/apps/pwa/out/botlab/index.html +1 -1
  193. package/apps/pwa/out/botlab/index.txt +22 -22
  194. package/apps/pwa/out/bots/index.html +1 -1
  195. package/apps/pwa/out/bots/index.txt +22 -22
  196. package/apps/pwa/out/ceo/index.html +1 -1
  197. package/apps/pwa/out/ceo/index.txt +23 -23
  198. package/apps/pwa/out/chat/index.html +1 -1
  199. package/apps/pwa/out/chat/index.txt +22 -22
  200. package/apps/pwa/out/consult/index.html +1 -1
  201. package/apps/pwa/out/consult/index.txt +23 -23
  202. package/apps/pwa/out/control/index.html +1 -1
  203. package/apps/pwa/out/control/index.txt +23 -23
  204. package/apps/pwa/out/decisions/index.html +1 -1
  205. package/apps/pwa/out/decisions/index.txt +22 -22
  206. package/apps/pwa/out/design-check/index.html +1 -1
  207. package/apps/pwa/out/design-check/index.txt +23 -23
  208. package/apps/pwa/out/editor/index.html +1 -1
  209. package/apps/pwa/out/editor/index.txt +24 -25
  210. package/apps/pwa/out/exec/index.html +1 -1
  211. package/apps/pwa/out/exec/index.txt +23 -23
  212. package/apps/pwa/out/field/index.html +1 -1
  213. package/apps/pwa/out/field/index.txt +23 -23
  214. package/apps/pwa/out/healthz +1 -1
  215. package/apps/pwa/out/index.html +1 -1
  216. package/apps/pwa/out/index.txt +22 -22
  217. package/apps/pwa/out/inside/index.html +1 -1
  218. package/apps/pwa/out/inside/index.txt +23 -23
  219. package/apps/pwa/out/intake/index.html +1 -1
  220. package/apps/pwa/out/intake/index.txt +23 -23
  221. package/apps/pwa/out/live/index.html +1 -1
  222. package/apps/pwa/out/live/index.txt +24 -25
  223. package/apps/pwa/out/live-run/index.html +1 -1
  224. package/apps/pwa/out/live-run/index.txt +24 -25
  225. package/apps/pwa/out/loops/index.html +1 -1
  226. package/apps/pwa/out/loops/index.txt +22 -22
  227. package/apps/pwa/out/market/index.html +1 -1
  228. package/apps/pwa/out/market/index.txt +22 -22
  229. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  230. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  231. package/apps/pwa/out/morning/index.html +1 -1
  232. package/apps/pwa/out/morning/index.txt +23 -23
  233. package/apps/pwa/out/observatory/index.html +1 -1
  234. package/apps/pwa/out/observatory/index.txt +23 -23
  235. package/apps/pwa/out/ops/checklist/index.html +1 -1
  236. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  237. package/apps/pwa/out/ops/release/index.html +1 -1
  238. package/apps/pwa/out/ops/release/index.txt +22 -22
  239. package/apps/pwa/out/ops/seats/index.html +1 -1
  240. package/apps/pwa/out/ops/seats/index.txt +22 -22
  241. package/apps/pwa/out/outputs/index.html +1 -1
  242. package/apps/pwa/out/outputs/index.txt +22 -22
  243. package/apps/pwa/out/reflection/index.html +1 -1
  244. package/apps/pwa/out/reflection/index.txt +23 -23
  245. package/apps/pwa/out/scheduler/index.html +1 -1
  246. package/apps/pwa/out/scheduler/index.txt +23 -23
  247. package/apps/pwa/out/sessions/index.html +1 -1
  248. package/apps/pwa/out/sessions/index.txt +22 -22
  249. package/apps/pwa/out/settings/devices/index.html +1 -1
  250. package/apps/pwa/out/settings/devices/index.txt +23 -23
  251. package/apps/pwa/out/settings/index.html +1 -1
  252. package/apps/pwa/out/settings/index.txt +23 -23
  253. package/apps/pwa/out/setup/done/index.html +1 -1
  254. package/apps/pwa/out/setup/done/index.txt +23 -23
  255. package/apps/pwa/out/setup/index.html +1 -1
  256. package/apps/pwa/out/setup/index.txt +23 -23
  257. package/apps/pwa/out/share/index.html +1 -1
  258. package/apps/pwa/out/share/index.txt +23 -23
  259. package/apps/pwa/out/showroom/index.html +1 -1
  260. package/apps/pwa/out/showroom/index.txt +22 -22
  261. package/apps/pwa/out/tasks/index.html +1 -1
  262. package/apps/pwa/out/tasks/index.txt +23 -23
  263. package/apps/pwa/out/term/index.html +1 -1
  264. package/apps/pwa/out/term/index.txt +23 -23
  265. package/apps/pwa/out/today/index.html +1 -1
  266. package/apps/pwa/out/today/index.txt +23 -23
  267. package/apps/pwa/out/trace/index.html +1 -1
  268. package/apps/pwa/out/trace/index.txt +23 -23
  269. package/apps/pwa/out/vault/index.html +1 -1
  270. package/apps/pwa/out/vault/index.txt +23 -23
  271. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  272. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  273. package/apps/pwa/out/workflows/index.html +1 -1
  274. package/apps/pwa/out/workflows/index.txt +23 -23
  275. package/apps/pwa/out/workspace/index.html +1 -1
  276. package/apps/pwa/out/workspace/index.txt +23 -23
  277. package/apps/pwa/out/worktrees/index.html +1 -1
  278. package/apps/pwa/out/worktrees/index.txt +23 -23
  279. package/catalog/external-commands.yaml +5 -3
  280. package/catalog/meta/catalogVersion.yaml +2 -1
  281. package/catalog/signing/catalog-signing-public.pem +3 -0
  282. package/docs/goal-context/04-mock-scenarios.md +13 -0
  283. package/graphs/catalog/catalog.yaml +1 -1
  284. package/graphs/heal/heal-loop.yaml +1 -0
  285. package/graphs/intake/intake-daily.yaml +16 -0
  286. package/graphs/intake/news-sources.yaml +1 -0
  287. package/graphs/intake/recipes.yaml +7 -0
  288. package/graphs/overlays/examples/research-runtime-empty-terminal.yaml +28 -0
  289. package/graphs/overlays/stop-heal-ladder.yaml +113 -0
  290. package/graphs/profiles/local.yaml +5 -0
  291. package/graphs/profiles/pod.yaml +4 -0
  292. package/graphs/units/verbs/recipes.yaml +11 -11
  293. package/graphs/work/research-report.yaml +10 -2
  294. package/package.json +6 -2
  295. package/plugins/demo-absorption-briefing/plugin.json +18 -0
  296. package/plugins/demo-absorption-briefing/skills/demo-absorption-briefing/SKILL.md +8 -0
  297. package/plugins/demo-browser-hand/plugin.json +13 -0
  298. package/plugins/demo-browser-hand/skills/demo-browser-hand/SKILL.md +8 -0
  299. package/plugins/demo-linear-secretary/plugin.json +15 -0
  300. package/plugins/demo-linear-secretary/skills/demo-linear-secretary/SKILL.md +8 -0
  301. package/plugins/demo-plugin-wizard/plugin.json +11 -0
  302. package/plugins/demo-plugin-wizard/skills/demo-plugin-wizard/SKILL.md +8 -0
  303. package/plugins/demo-research/plugin.json +16 -0
  304. package/plugins/demo-research/skills/demo-research/SKILL.md +8 -0
  305. package/plugins/demo-video-briefing/plugin.json +15 -0
  306. package/plugins/demo-video-briefing/skills/demo-video-briefing/SKILL.md +8 -0
  307. package/scripts/build-signed-catalog.ts +48 -0
  308. package/scripts/ci-typecheck-main-delta.sh +88 -0
  309. package/scripts/codex-fallback-live-probe.ts +1 -1
  310. package/scripts/demo/demo1104-parallel-scenes.ts +301 -0
  311. package/scripts/demo/demo1104-stage.config.ts +21 -0
  312. package/scripts/demo/demo1104-stage.ts +316 -0
  313. package/scripts/goal-method-audit.ts +17 -1
  314. package/scripts/graph-units/land-enqueue.ts +90 -0
  315. package/scripts/heal/run-role.ts +99 -5
  316. package/scripts/hooks/codex-notify.sh +32 -0
  317. package/scripts/install.sh +10 -38
  318. package/scripts/land-global-checks.ts +6 -1
  319. package/scripts/landing-heal/land-plan.ts +57 -0
  320. package/scripts/lib/decompose-ab.ts +1 -0
  321. package/scripts/lib/fixtures/tui-regress/help-insufficient-commands.txt +15 -0
  322. package/scripts/lib/fixtures/tui-regress/help-live.txt +42 -0
  323. package/scripts/lib/fixtures/tui-regress/help-missing-keys.txt +21 -0
  324. package/scripts/lib/fixtures/tui-regress/help-original.txt +51 -0
  325. package/scripts/lib/fixtures/tui-regress/help-shifted-input.txt +26 -0
  326. package/scripts/lib/tui-regress-checks.ts +33 -13
  327. package/scripts/release-loop/auto-approve-node.ts +1 -1
  328. package/scripts/release-loop/gate-autoheal-sim-evidence.ts +60 -0
  329. package/scripts/release-loop/gate-baseline-receipt.ts +47 -9
  330. package/scripts/release-loop/gate-image-pin.ts +81 -0
  331. package/scripts/release-loop/gate-method.ts +139 -0
  332. package/scripts/release-loop/gate-node-sim.ts +207 -0
  333. package/scripts/release-loop/gate-node.ts +463 -64
  334. package/scripts/release-loop/gate-pod-image-sticky-plan.ts +99 -0
  335. package/scripts/release-loop/gate-radius-live.ts +97 -13
  336. package/scripts/release-loop/gate-shard-dispatch.ts +43 -0
  337. package/scripts/release-loop/gate-traffic-mode.ts +151 -3
  338. package/scripts/release-loop/gate-train-receipts.ts +122 -0
  339. package/scripts/release-loop/node-verdict.ts +38 -25
  340. package/scripts/release-loop/preflight.ts +362 -8
  341. package/scripts/release-loop/resume-release.ts +83 -8
  342. package/scripts/release-loop/unattended-release.ts +20 -9
  343. package/scripts/rhythm/daily.ts +36 -4
  344. package/scripts/rhythm/linear-progress-sync.ts +298 -0
  345. package/scripts/ux-sim.ts +18 -1
  346. package/scripts/video-pipeline.ts +9 -1
  347. package/scripts/warm-pool-provider-config.ts +286 -0
  348. package/skills/omni-crawl/SKILL.md +5 -2
  349. package/skills/omni-crawl/scripts/main.ts +84 -23
  350. package/src/acp/agent-manager.ts +1 -0
  351. package/src/acp/codex-app-server-agent.ts +33 -0
  352. package/src/acp/codex-app-server-client.ts +153 -16
  353. package/src/acp/core-turn-bridge.ts +27 -9
  354. package/src/acp/event-router.ts +20 -1
  355. package/src/acp/server.ts +6 -0
  356. package/src/agent/registry.ts +2 -0
  357. package/src/agent/task-notification.ts +25 -5
  358. package/src/agent/types.ts +6 -0
  359. package/src/agent-mission/browser-roundtrip-coordinator.ts +85 -0
  360. package/src/agent-mission/claude-headless.ts +4 -1
  361. package/src/agent-mission/codex-exec.ts +105 -0
  362. package/src/agent-mission/driver.ts +192 -11
  363. package/src/agent-mission/grok-auth-status.ts +47 -0
  364. package/src/agent-mission/hand-hooks.ts +101 -0
  365. package/src/agent-mission/mission-cli.ts +63 -4
  366. package/src/agent-mission/mission-hand-reply.ts +118 -0
  367. package/src/agent-mission/mission-line.ts +180 -0
  368. package/src/agent-mission/mission-out.ts +833 -0
  369. package/src/agent-mission/tool-install.ts +200 -3
  370. package/src/agent-substrate/context-strategy.ts +4 -4
  371. package/src/agent-substrate/self-review-cli.ts +178 -13
  372. package/src/agents/general-purpose.md +1 -1
  373. package/src/auto-research/research-turn.ts +211 -53
  374. package/src/autopilot/pr-manager.ts +69 -10
  375. package/src/autopilot/pty-control-loop.ts +2 -0
  376. package/src/boot/daemon-tools/self-implement.ts +3 -1
  377. package/src/boot/daemon-tools/web-search.ts +1 -2
  378. package/src/briefing/brief-items.ts +55 -11
  379. package/src/capture/tui-self-report.ts +22 -6
  380. package/src/chat/index.ts +1 -1
  381. package/src/cli/agent-cli.ts +2 -1
  382. package/src/cli/catalog-cli.ts +31 -0
  383. package/src/cli/connector-cli.ts +16 -0
  384. package/src/cli/doctor-fix.ts +2 -2
  385. package/src/cli/fixtures/review-loop-breaker/opwaiver-32646-1694ccc7a170.json +1 -0
  386. package/src/cli/fixtures/review-loop-breaker/opwaiver-32853-bd8f73595c83.json +1 -0
  387. package/src/cli/fixtures/review-loop-breaker/opwaiver-33097-1cc85900413c.json +1 -0
  388. package/src/cli/fixtures/review-loop-breaker/opwaiver-33106-972f31e4a3ca.json +1 -0
  389. package/src/cli/fixtures/review-loop-breaker/opwaiver-33113-3ab51f05968f.json +1 -0
  390. package/src/cli/fixtures/review-loop-breaker/pr-33097-1cc85900413c.json +1 -0
  391. package/src/cli/intake-source-cli.ts +44 -8
  392. package/src/cli/msg-cli.ts +32 -3
  393. package/src/cli/pr-cli.ts +21 -1
  394. package/src/cli/pr-land-heavy-remote.ts +75 -5
  395. package/src/cli/pr-land-overlap-evidence.ts +113 -2
  396. package/src/cli/pr-land-pod-shadow-job.ts +202 -4
  397. package/src/cli/pr-land-pod-shadow.ts +9 -2
  398. package/src/cli/release-checklist-read-cli.ts +57 -19
  399. package/src/cli/release-cli.ts +23 -3
  400. package/src/cli/research-cli.ts +13 -5
  401. package/src/cli/setup-cli.ts +166 -6
  402. package/src/cli/setup-keys.ts +187 -0
  403. package/src/cli/task-plugin-wizard-host.ts +114 -0
  404. package/src/cli/tasks-cli.ts +61 -9
  405. package/src/cli/tui-test-cli.ts +186 -0
  406. package/src/compact/auto.ts +8 -1
  407. package/src/config.ts +4 -2
  408. package/src/connectors/linear-daily-progress.ts +228 -0
  409. package/src/connectors/linear-projector.ts +34 -12
  410. package/src/connectors/linear.ts +151 -7
  411. package/src/control-plane/ledger.ts +52 -2
  412. package/src/control-plane/server.ts +16 -2
  413. package/src/core-turn/deep-turn-bloom.ts +67 -0
  414. package/src/core-turn/research-policy.ts +37 -0
  415. package/src/core-turn/run-core-turn.ts +606 -95
  416. package/src/core-turn/run-goal-loop.ts +18 -0
  417. package/src/core-turn/types.ts +4 -0
  418. package/src/dashboard/chat/acp-chat.ts +10 -0
  419. package/src/dashboard/classic-sidetab-mission-job.ts +161 -0
  420. package/src/dashboard/classic-sidetab-mission-pair.ts +81 -0
  421. package/src/dashboard/classic-sidetab-mission-trio.ts +219 -0
  422. package/src/dashboard/classic-sidetab-mission.ts +347 -0
  423. package/src/dashboard/index.ts +517 -18
  424. package/src/dashboard/input/agent-wake.ts +23 -1
  425. package/src/dashboard/input/chat-main-acp-dispatch.ts +23 -0
  426. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +17 -0
  427. package/src/dashboard/mission-cli-consumer.ts +165 -0
  428. package/src/dashboard/plugin-wizard-runtime.ts +50 -0
  429. package/src/dashboard/plugin-wizard-tool.ts +55 -0
  430. package/src/dashboard/seat-boot-preamble.ts +171 -1
  431. package/src/dashboard/side-basic-runtime.ts +54 -1
  432. package/src/dashboard/sidetab-runtime.ts +90 -1
  433. package/src/dashboard/skill-catalog-preamble.ts +101 -0
  434. package/src/dashboard/skill-detection-runtime.ts +55 -15
  435. package/src/dashboard/slash-runtime/dashboard-handlers.ts +15 -0
  436. package/src/dashboard/terminal-popup-runtime.ts +6 -3
  437. package/src/dashboard/turn-preamble.ts +53 -15
  438. package/src/dashboard/turn-prompt-runtime.ts +4 -2
  439. package/src/decisions/linear-progress-summary.ts +78 -0
  440. package/src/decisions/linear-progress-sync.ts +152 -0
  441. package/src/domains/outbound-alert.ts +49 -11
  442. package/src/domains/telegram-kind-route.ts +16 -9
  443. package/src/graph-runner/arg-allowance.ts +13 -0
  444. package/src/graph-runner/graph-cli.ts +23 -7
  445. package/src/graph-runner/graph-run-api.ts +3 -1
  446. package/src/graph-runner/graph-tick.ts +10 -2
  447. package/src/graph-runner/runner.ts +86 -18
  448. package/src/graph-wizard/mission-compose.ts +407 -12
  449. package/src/grok/agent-search.ts +14 -4
  450. package/src/grok/credential.ts +28 -11
  451. package/src/harness/dispatch-backpressure.ts +54 -1
  452. package/src/harness/dispatch-shadow-compare.ts +74 -0
  453. package/src/harness/harness-cli-command.ts +11 -1
  454. package/src/harness/harness-pod-dispatch.ts +81 -15
  455. package/src/harness/harness-stop.ts +155 -11
  456. package/src/harness/skill-exec.ts +21 -9
  457. package/src/harness/skill-select.ts +1 -1
  458. package/src/hooks/error-report-cloud.ts +101 -0
  459. package/src/hooks/receiver.ts +29 -2
  460. package/src/index.ts +159 -13
  461. package/src/instance/spawn-elanous.ts +6 -4
  462. package/src/intake-plane/actions.ts +354 -0
  463. package/src/intake-plane/adapters/telegram-ambient.ts +34 -18
  464. package/src/intake-plane/intake-sources.ts +78 -8
  465. package/src/intake-plane/items.ts +14 -4
  466. package/src/intake-plane/linear-mission-sync.ts +80 -0
  467. package/src/intake-plane/linear-secretary-runtime.ts +178 -0
  468. package/src/intake-plane/linear-wish.ts +227 -1
  469. package/src/life/life-cli.ts +168 -0
  470. package/src/life/life-kinds.ts +160 -0
  471. package/src/live-supply/budget-consumer.ts +78 -0
  472. package/src/live-supply/read.ts +3 -0
  473. package/src/live-supply/snapshot.ts +45 -0
  474. package/src/llm/provider-credentials.ts +8 -2
  475. package/src/llm.ts +168 -9
  476. package/src/loops/orchestrator/coordinator-shadow.ts +226 -0
  477. package/src/loops/orchestrator/tick.ts +13 -0
  478. package/src/maturity/feature-maturity.ts +4 -4
  479. package/src/msg/msg-sse-server.ts +3 -3
  480. package/src/msg/msg-store.ts +177 -19
  481. package/src/native-tool-catalog.ts +38 -4
  482. package/src/nexus/api/harness-traversal.ts +11 -0
  483. package/src/nexus/api/http-server.ts +37 -1
  484. package/src/nexus/api/mcp-public-allowlist.ts +2 -0
  485. package/src/nexus/index.ts +7 -2
  486. package/src/nexus/outbound/format.ts +9 -0
  487. package/src/nexus/outbound/router.ts +98 -13
  488. package/src/nexus/setup-status.ts +9 -0
  489. package/src/nexus/state/state.ts +3 -0
  490. package/src/oauth/codex-account-store.ts +20 -7
  491. package/src/oauth/codex-owner-mirror.ts +44 -0
  492. package/src/oauth/codex.ts +17 -2
  493. package/src/oauth/fallback-chain.ts +47 -17
  494. package/src/onboarding/first-run-doctor.ts +8 -1
  495. package/src/onboarding/first-run.ts +85 -26
  496. package/src/onboarding/key-setup.ts +103 -0
  497. package/src/onboarding/menu-answer.ts +13 -0
  498. package/src/onboarding/secret-prompt.ts +37 -0
  499. package/src/plugins/install/plugin-install.ts +59 -0
  500. package/src/pr-tool/census.ts +133 -2
  501. package/src/pty-shell/pty-control-ipc.ts +4 -1
  502. package/src/pty-shell/tui-run-state.ts +188 -2
  503. package/src/registry/catalog-server.ts +232 -0
  504. package/src/registry/loader.ts +45 -1
  505. package/src/registry/types.ts +1 -2
  506. package/src/release-loop/checklist-target-path-hint.ts +13 -0
  507. package/src/release-loop/checklist.ts +9 -1
  508. package/src/repl/index.ts +43 -2
  509. package/src/research/axis-fanout.ts +136 -16
  510. package/src/research/bloom-exemplars.ts +3 -1
  511. package/src/research/gap-followup.ts +13 -1
  512. package/src/research/plugin-discovery.ts +36 -14
  513. package/src/research-bridge/invoke.ts +22 -5
  514. package/src/research-bridge/types.ts +2 -0
  515. package/src/self-dev/ask-launch-flow.ts +72 -1
  516. package/src/self-dev/decompose.ts +119 -5
  517. package/src/self-dev/dev-cli.ts +4 -1
  518. package/src/self-dev/dev-pipeline.ts +5 -0
  519. package/src/self-dev/draft-residue.ts +64 -5
  520. package/src/self-dev/graph-front-nodes.ts +2 -1
  521. package/src/self-dev/graph-journey-route.ts +76 -21
  522. package/src/self-dev/launch-preflight-text.ts +5 -6
  523. package/src/self-dev/launch-preflight.ts +58 -0
  524. package/src/self-dev/orchestrate.ts +13 -3
  525. package/src/self-dev/review-provider-fallback.ts +9 -2
  526. package/src/self-dev/run-supervisor.ts +42 -4
  527. package/src/self-dev/run-types.ts +4 -0
  528. package/src/self-dev/shard-aggregate.ts +4 -0
  529. package/src/self-dev/shard-run.ts +36 -15
  530. package/src/self-implement/abandoned-classification.ts +12 -3
  531. package/src/self-implement/budget-gate.ts +7 -0
  532. package/src/self-implement/child-llm-preference.ts +10 -1
  533. package/src/self-implement/doctor-visit.ts +118 -8
  534. package/src/self-implement/elanous-tui-spawn.ts +3 -0
  535. package/src/self-implement/fixtures/tdd-green-missing-passing-child-transcript.txt +2 -0
  536. package/src/self-implement/gate-artifacts.ts +2 -1
  537. package/src/self-implement/goal-author-cli.ts +4 -2
  538. package/src/self-implement/goal-author.ts +684 -7
  539. package/src/self-implement/graph-overlay-yaml.ts +37 -4
  540. package/src/self-implement/graph-overlay.ts +3 -1
  541. package/src/self-implement/graph-profile-yaml.ts +107 -0
  542. package/src/self-implement/graph-yaml.ts +26 -3
  543. package/src/self-implement/headless-elanous-driver.ts +31 -2
  544. package/src/self-implement/heal-intake.ts +112 -4
  545. package/src/self-implement/heal-triage.ts +20 -0
  546. package/src/self-implement/host-regate.ts +27 -4
  547. package/src/self-implement/merge-train.ts +5 -0
  548. package/src/self-implement/off-diff-evidence.ts +249 -5
  549. package/src/self-implement/orchestrator.ts +365 -25
  550. package/src/self-implement/regate-detail.ts +38 -1
  551. package/src/self-implement/rework-child-provider.ts +25 -0
  552. package/src/self-implement/run-chart.ts +122 -0
  553. package/src/self-implement/run-ledger.ts +162 -11
  554. package/src/self-implement/run-stop.ts +188 -4
  555. package/src/self-implement/runtime-overlay-run-steps.ts +95 -0
  556. package/src/self-implement/stop-autoheal.ts +13 -0
  557. package/src/self-implement/tdd-evidence-tags.ts +9 -0
  558. package/src/self-implement/train-gate-receipt.ts +166 -0
  559. package/src/self-implement/train-gate-remote.ts +62 -18
  560. package/src/session/chat.ts +40 -4
  561. package/src/session/session-fanout.ts +2 -0
  562. package/src/session/streaming/acp-stream-sink.ts +2 -1
  563. package/src/session/streaming/chunk-producer.ts +6 -0
  564. package/src/session/streaming/stream-compositor.ts +3 -2
  565. package/src/session-runtime/index.ts +135 -5
  566. package/src/session-runtime/retry-policy.ts +1 -1
  567. package/src/session-runtime/tier-flip.ts +3 -3
  568. package/src/setup/llm-env-detect.ts +3 -0
  569. package/src/setup/service-key-catalog.ts +46 -0
  570. package/src/setup/service-keys.ts +241 -0
  571. package/src/sidetab-core/model.ts +19 -5
  572. package/src/sidetab-core/visible-agent-mission.ts +262 -0
  573. package/src/skills/name-match.ts +20 -0
  574. package/src/skills/tools/agent.ts +53 -6
  575. package/src/skills/tools/omni-search.ts +173 -13
  576. package/src/task-agent/parent-host.ts +10 -0
  577. package/src/task-agent/pod-distributor-entry.ts +3 -0
  578. package/src/task-agent/repair-outcomes.ts +65 -0
  579. package/src/task-agent/task-hand.ts +47 -7
  580. package/src/task-orchestrator/dispatcher.ts +14 -1
  581. package/src/task-orchestrator/linear-capture-events.ts +55 -0
  582. package/src/task-orchestrator/store.ts +16 -5
  583. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +4 -0
  584. package/src/task-orchestrator/surfaces/pod-distributor.ts +48 -0
  585. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +92 -1
  586. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +38 -1
  587. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +113 -14
  588. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +33 -6
  589. package/src/task-orchestrator/surfaces/pod-source-bundle.ts +45 -9
  590. package/src/task-orchestrator/surfaces/pod-source-receive.ts +178 -16
  591. package/src/task-orchestrator/surfaces/pod-source-spec.ts +3 -3
  592. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +2 -0
  593. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +237 -41
  594. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +80 -3
  595. package/src/task-orchestrator/surfaces/self-implement-pod.ts +337 -51
  596. package/src/task-orchestrator/surfaces/self-implement.ts +27 -3
  597. package/src/task-orchestrator/surfaces/warm-reuse-evidence.ts +169 -0
  598. package/src/task-orchestrator/types.ts +14 -0
  599. package/src/telegram.ts +14 -16
  600. package/src/terminal/coding-agent.ts +14 -5
  601. package/src/terminal/session-registry.ts +1 -1
  602. package/src/tokens.ts +35 -2
  603. package/src/tool-hints/gate.ts +1 -0
  604. package/src/tool-runtime/agent-runtime.ts +2 -0
  605. package/src/tool-runtime/browser-hand-runtime.ts +381 -0
  606. package/src/tool-runtime/browser-runtime.ts +2 -1
  607. package/src/tool-runtime/elanous-linear-issue-runtime.ts +76 -0
  608. package/src/tool-runtime/elanous-linear-secretary-runtime.ts +57 -0
  609. package/src/tool-runtime/elanous-skills-list-runtime.ts +5 -1
  610. package/src/tool-runtime/graph-mcp-runtimes.ts +240 -0
  611. package/src/tool-runtime/index.ts +6 -0
  612. package/src/tool-runtime/skill-exec-runtime.ts +33 -13
  613. package/src/tool-runtime/types.ts +4 -0
  614. package/src/tui/entry.ts +38 -5
  615. package/src/tui/sidetab/attach.ts +177 -1
  616. package/src/tui/sidetab/herdr-portal.ts +225 -0
  617. package/src/tui-client/local-chat-turn.ts +26 -13
  618. package/src/tui.ts +22 -0
  619. package/src/user-config.ts +34 -9
  620. package/src/user-intent/types.ts +4 -3
  621. package/src/ux-sim/browser-hand.ts +165 -0
  622. package/src/ux-sim/draft-inventory-builder.ts +198 -0
  623. package/src/ux-sim/fake-browser-page.ts +81 -0
  624. package/src/ux-sim/fake-kubectl.ts +37 -3
  625. package/src/ux-sim/fake-linear-device.ts +31 -0
  626. package/src/ux-sim/fault-pool-cap.ts +11 -6
  627. package/src/ux-sim/graph-engine-sim.ts +47 -0
  628. package/src/ux-sim/linear-secretary.ts +216 -0
  629. package/src/ux-sim/mock-scenario-catalog.json +93 -0
  630. package/src/ux-sim/mock-scenario-catalog.ts +274 -0
  631. package/src/ux-sim/onboarding-first-run-device.ts +31 -21
  632. package/src/ux-sim/scenario.ts +185 -48
  633. package/src/ux-sim/service-key-setup.ts +50 -0
  634. package/src/ux-sim/term-slash-device.ts +74 -0
  635. package/src/ux-sim/turn-throw-sim.ts +31 -0
  636. package/src/version/packed-revision.json +1 -1
  637. package/src/voice/voice-tts-singleton.ts +18 -3
  638. package/src/web-search/exa.ts +77 -0
  639. package/src/web-search/grok.ts +5 -9
  640. package/src/web-search/index.ts +30 -9
  641. package/src/web-search/provider.ts +4 -1
  642. package/src/web-search/x-intent.ts +5 -0
  643. package/apps/pwa/out/_next/static/chunks/1115.434ae2ecb0ad986d.js +0 -149
  644. package/apps/pwa/out/_next/static/chunks/1121.667cec0bcdbb3fdb.js +0 -36
  645. package/apps/pwa/out/_next/static/chunks/1197-54da59d250a6e476.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/1245.1cfd13b26dbd71d6.js +0 -287
  647. package/apps/pwa/out/_next/static/chunks/1494-f93046ff5c5a124d.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/1609.2b312797599b8e45.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/1661.0dd330f3d89f73f3.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/167-0c121e4b47e0f9da.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/1700.cdc2bf8cc685e221.js +0 -90
  652. package/apps/pwa/out/_next/static/chunks/1703-78e46acad29f3cfc.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/1765.679b29625c8e88d4.js +0 -77
  654. package/apps/pwa/out/_next/static/chunks/1971-7efb628c471dc5a0.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/1999-8de7b7bb36801913.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/2073.689dcb2680113d76.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/2198-557d49184104d165.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/221-440ce67fa9f5c839.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/2427-8ed8e98624cbd664.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/2457-725c5827bc003795.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/2491-2718b15a5ccb75a5.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/2527-5c636a43c7cc5dde.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/2692-1027cb16fe4ccf49.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/2773.0e80b9d325fb5635.js +0 -32
  665. package/apps/pwa/out/_next/static/chunks/2873-0f3cb56c8e3528ea.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/3097.864e92bdaa2f4d15.js +0 -79
  667. package/apps/pwa/out/_next/static/chunks/3136-d6870ba63300a93e.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/3173-0289113d434e83b7.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/325-dd9208a1a0ab7ce4.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/3283.528f430dd043fb4e.js +0 -74
  671. package/apps/pwa/out/_next/static/chunks/3295.cc8cb13b8f0dae1a.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/3688-86e3b88abf18cb3b.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/3804-7220467a5473a8df.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/3808.3e1e247ce7bdf889.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/3927.b5473ad109da44c5.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/3934-98ea94832e194796.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/4156.ba4de4a3664f04b4.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/4297-239ca82f293faab0.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/4320-dcc5a7734126f4c9.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/4434.94b4c552a2d91e69.js +0 -148
  681. package/apps/pwa/out/_next/static/chunks/4579.03e4092f73950965.js +0 -226
  682. package/apps/pwa/out/_next/static/chunks/4667.97e31aa38c95c475.js +0 -309
  683. package/apps/pwa/out/_next/static/chunks/4702.4a4adc1f16d7c93b.js +0 -64
  684. package/apps/pwa/out/_next/static/chunks/4815.481501c57b3568d9.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/487-d16e698ef14662d9.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/4888-7a38bf522c9cc6fe.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/5034-30e429d6bb086881.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/5040-35c494e60dadd97d.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/50c6ab1e.81a96e419350909d.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/5154.4b6a836179356f30.js +0 -94
  691. package/apps/pwa/out/_next/static/chunks/5228-a8200df486278f2d.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/5379.97af106d09566f69.js +0 -8
  693. package/apps/pwa/out/_next/static/chunks/5479-b6372e762719f92f.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/5534-699c5cbcbc96c5d7.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/5701.9c4e8f250312eeee.js +0 -24
  696. package/apps/pwa/out/_next/static/chunks/5892.2526d962339662d8.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/5937.c2df9e3447e1f667.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/5941.8210cc93c9202c0a.js +0 -286
  699. package/apps/pwa/out/_next/static/chunks/5975.4004f820ae3cecd5.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/6142-7ccd48795d7abd55.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/6160.bf9177b8c1bfb243.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/6398.71ba0690c8027555.js +0 -27
  703. package/apps/pwa/out/_next/static/chunks/6492.2bd5c10edc1a064e.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/6552.a3840aa7da35ad68.js +0 -62
  705. package/apps/pwa/out/_next/static/chunks/6736.1e36d3ac5fa5e41d.js +0 -24
  706. package/apps/pwa/out/_next/static/chunks/6900.3ccbe069bdd4556a.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/71327eb4.add50b365f94bf3a.js +0 -122
  708. package/apps/pwa/out/_next/static/chunks/7136.deca3e3a2ddaa374.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/7139-ee9f8ed2677a40b3.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/7191.fdc955f7d96064a4.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/7423-e0aa5d9e2962120e.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/7453.afc1ea7e05d56a8c.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/7503-5e6a3d7fe67e4a0c.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/7761-476fd7bf768abd34.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/7975.eafb12097a0a9e62.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/8050-9b364bdef8f71927.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/8152.64e253c35cccfaae.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/8190.620f0231b3924bcb.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/8448.45b6b1f1a99eeb35.js +0 -104
  720. package/apps/pwa/out/_next/static/chunks/8464-e24f10451b658aac.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/8477.e4c944bb3aa5d2f3.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/8710.ca385257d5ca422e.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/8830.627ccf294ec2465c.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/8880.64c445592f04acaf.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/8981.c706964c8ba27aff.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/9053.bd0fffaff8d3f836.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/9161-c66e723d7ec9d682.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/9185.1ecdf9b65c0bb684.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/9356.fccd5f58086b4ff5.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/9446.dc0406109371d329.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/9506.dcf25d467a42627e.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/9541.eb8e2f8480c7feca.js +0 -93
  733. package/apps/pwa/out/_next/static/chunks/9577.ed7582186efa5482.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/9579.4a8169600fff2058.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/9642-ff2e039eb62e3b92.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/9659-8f2323348113ad80.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/9724.4c5623af2db43153.js +0 -34
  738. package/apps/pwa/out/_next/static/chunks/9869.81a1e24ca682d5a0.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-8d9d76ea322d855c.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed2c4e59f9f1fe21.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-2dc99e03c5d76ca0.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/board/page-b5a3a788330e920f.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/app/botlab/page-14949db884bfa672.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/bots/page-ea76c85b36388a97.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/ceo/page-01716d20af62d325.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/chat/page-62baf6881a64b1e9.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/consult/page-f89ba590c2af8afa.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/control/page-22f8b0f78d9637e5.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/decisions/page-817f9d7e6820be80.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/design-check/page-ffb9bc0d2650249a.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/editor/page-f6d0e64873c0f629.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/exec/page-8bfa0d4ba23a209d.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/field/page-f5060462249e32c7.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/healthz/route-8d9d76ea322d855c.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/inside/page-b2049f8b1ef79117.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/intake/page-1446c5fa93907f11.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/layout-b48a7a07c5204156.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/live/page-e974b8c4ca47614c.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/live-run/page-8a919b869bd28594.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/loops/page-d31b8de6bfcd72ed.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/market/page-64765f817909db29.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-d128c8569a36ee9b.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/morning/page-b2679d357e9b9270.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/not-found-6fabec98a9e7b269.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/app/observatory/page-048f30149dcf1349.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-9113181d6b5a2725.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-1e7a755a13227611.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3c8f8b67a203cf07.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/app/page-18032f5437215062.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/app/reflection/page-da3b739192fd0ee3.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d332545571bd6fd1.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/app/sessions/page-5237aa5b3f3b8ec5.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/app/settings/page-d16e56c3989c147e.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6b6593600869e2cd.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/app/setup/layout-8d9d76ea322d855c.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/app/setup/page-29e8b8a8396b55cb.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/app/share/page-b3414d856a1a7e2f.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c3affa52b7ce961b.js +0 -1
  779. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f21dddf9f95b6fab.js +0 -1
  780. package/apps/pwa/out/_next/static/chunks/app/term/page-f5a30a24745bf088.js +0 -1
  781. package/apps/pwa/out/_next/static/chunks/app/today/page-8c8569a09b4d4e34.js +0 -1
  782. package/apps/pwa/out/_next/static/chunks/app/trace/page-2ce32722c0243483.js +0 -1
  783. package/apps/pwa/out/_next/static/chunks/app/vault/page-4767b0d9c0a98c6c.js +0 -1
  784. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-116ee1339c387a75.js +0 -1
  785. package/apps/pwa/out/_next/static/chunks/app/workflows/page-35e8c50ca4ef7ffc.js +0 -1
  786. package/apps/pwa/out/_next/static/chunks/app/workspace/page-52e17113356bb891.js +0 -1
  787. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7458ae05ed2ac1a0.js +0 -1
  788. package/apps/pwa/out/_next/static/chunks/framework-ad6c9dd524ad6ef8.js +0 -1
  789. package/apps/pwa/out/_next/static/chunks/main-app-2ddd1f2b44d6aa59.js +0 -1
  790. package/apps/pwa/out/_next/static/chunks/main-e3d82bdc358d20c5.js +0 -1
  791. package/apps/pwa/out/_next/static/chunks/pages/_app-71d5aa3896e1655f.js +0 -1
  792. package/apps/pwa/out/_next/static/chunks/pages/_error-03ffc54e00438546.js +0 -1
  793. package/apps/pwa/out/_next/static/chunks/webpack-56bb89af5a611d0b.js +0 -1
  794. package/apps/pwa/out/_next/static/css/be9019f696217521.css +0 -1
  795. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +0 -1
  796. /package/apps/pwa/out/_next/static/{GiOLWmt4MqDZePubBjA4Q → Om5xS9jpjSXJCeTNGYEi4}/_ssgManifest.js +0 -0
@@ -31,6 +31,8 @@ export interface GraphOverlaySpec {
31
31
  /** ⛔ 조건도 «값»이다 — 사람이 판단해 얹는 경로를 두지 않는다. */
32
32
  readonly appliesWhen: string;
33
33
  readonly patch: readonly OverlayPatchOp[];
34
+ /** Stop-reason vocabulary lives with heal declarations, not in TypeScript tables. */
35
+ readonly reasonMap?: Readonly<Record<string, string>>;
34
36
  }
35
37
 
36
38
  export interface OverlayParseResult {
@@ -93,6 +95,10 @@ function overlayFromRaw(raw: unknown, label: string): { overlay?: GraphOverlaySp
93
95
  if (!appliesWhen) errors.push({ path: `${label}/applies_when`, message: 'applies_when 이 없거나 문자열이 아니다' });
94
96
 
95
97
  const patch: OverlayPatchOp[] = [];
98
+ const reasonMapRaw = doc.reason_map;
99
+ const reasonMap = reasonMapRaw && typeof reasonMapRaw === 'object' && !Array.isArray(reasonMapRaw)
100
+ ? Object.fromEntries(Object.entries(reasonMapRaw as Record<string, unknown>).filter((entry): entry is [string, string] => typeof entry[1] === 'string'))
101
+ : undefined;
96
102
  const rawPatch = Array.isArray(doc.patch) ? doc.patch : [];
97
103
  if (rawPatch.length === 0) errors.push({ path: `${label}/patch`, message: 'patch 가 비었다 — 아무것도 안 바꾸는 오버레이다' });
98
104
  for (const [index, entry] of rawPatch.entries()) {
@@ -109,6 +115,7 @@ function overlayFromRaw(raw: unknown, label: string): { overlay?: GraphOverlaySp
109
115
  return {
110
116
  overlay: {
111
117
  overlayId: overlayId!, target: target!, stage: stage!, appliesWhen: appliesWhen!, patch,
118
+ ...(reasonMap && Object.keys(reasonMap).length ? { reasonMap } : {}),
112
119
  },
113
120
  errors,
114
121
  };
@@ -160,8 +167,10 @@ export function applyGraphOverlays(
160
167
  rejections.push({ kind: 'unknown-target', overlayId: overlay.overlayId, target: overlay.target });
161
168
  continue;
162
169
  }
170
+ const beforeNodes = new Map(next.nodes.map((node) => [node.nodeId, node]));
163
171
  const beforeVisits = new Map(next.nodes.map((node) => [node.nodeId, node.maxVisits]));
164
- const beforeRoutes = edgeMapOf(next);
172
+ const beforeRoutes = graphRouteMap(next);
173
+ const beforeEdgeMap = edgeMapOf(next);
165
174
  for (const op of overlay.patch) {
166
175
  const resolved = resolvePointer(next, op.path);
167
176
  if (!resolved) { rejections.push({ kind: 'bad-pointer', overlayId: overlay.overlayId, path: op.path }); continue; }
@@ -183,15 +192,27 @@ export function applyGraphOverlays(
183
192
  if (op.op === 'remove') delete bag[key]; else bag[key] = op.value;
184
193
  } else rejections.push({ kind: 'bad-pointer', overlayId: overlay.overlayId, path: op.path });
185
194
  }
195
+ for (const node of next.nodes) {
196
+ if (beforeNodes.has(node.nodeId)) continue;
197
+ patches.push({ overlayId: overlay.overlayId, field: 'node-added', node: node.nodeId, kind: node.kind, maxVisits: node.maxVisits });
198
+ }
199
+ const afterRoutes = graphRouteMap(next);
200
+ for (const [key, route] of afterRoutes) {
201
+ const before = beforeRoutes.get(key);
202
+ if (before && before.to !== route.to) {
203
+ patches.push({ overlayId: overlay.overlayId, field: 'edge-rerouted', from: route.from, outcome: route.outcome, was: before.to, to: route.to });
204
+ }
205
+ }
186
206
  for (const node of next.nodes) {
187
207
  const before = beforeVisits.get(node.nodeId);
188
208
  if (before !== undefined && before !== node.maxVisits) {
189
209
  patches.push({ overlayId: overlay.overlayId, field: 'maxVisits', node: node.nodeId, before, after: node.maxVisits });
190
210
  }
191
211
  }
192
- const afterRoutes = edgeMapOf(next);
193
- for (const [node, before] of Object.entries(beforeRoutes)) {
194
- const after = afterRoutes[node] ?? [];
212
+ const afterEdgeMap = edgeMapOf(next);
213
+ for (const node of Object.keys(beforeEdgeMap)) {
214
+ const before = beforeEdgeMap[node] ?? [];
215
+ const after = afterEdgeMap[node] ?? [];
195
216
  if (before.length !== after.length || before.some((destination, index) => destination !== after[index])) {
196
217
  patches.push({ overlayId: overlay.overlayId, field: 'routes', node, before, after });
197
218
  }
@@ -239,6 +260,18 @@ export function applyGraphOverlays(
239
260
  return { ok: true, template: next, overlayIds: applied, patches };
240
261
  }
241
262
 
263
+ /** Keep outcome names while comparing route changes; the compiled edge map deliberately drops them. */
264
+ function graphRouteMap(template: GraphTemplateSpec): Map<string, { from: string; outcome: string; to: string }> {
265
+ const routes = new Map<string, { from: string; outcome: string; to: string }>();
266
+ for (const [index, edge] of template.edges.entries()) {
267
+ if (edge.to) routes.set(`${edge.from}\u0000direct\u0000${index}`, { from: edge.from, outcome: '', to: edge.to });
268
+ for (const [outcome, to] of Object.entries(edge.map ?? {})) {
269
+ routes.set(`${edge.from}\u0000${edge.on ?? 'outcome'}\u0000${outcome}`, { from: edge.from, outcome, to });
270
+ }
271
+ }
272
+ return routes;
273
+ }
274
+
242
275
  export interface OverlayLoadResult {
243
276
  readonly overlays: readonly GraphOverlaySpec[];
244
277
  readonly errors: readonly GraphParseIssue[];
@@ -26,7 +26,9 @@ export type OverlayRejection =
26
26
 
27
27
  export type OverlayPatch =
28
28
  | { readonly overlayId: string; readonly field: 'maxVisits'; readonly node: string; readonly before: number; readonly after: number }
29
- | { readonly overlayId: string; readonly field: 'routes'; readonly node: string; readonly before: readonly string[]; readonly after: readonly string[] };
29
+ | { readonly overlayId: string; readonly field: 'routes'; readonly node: string; readonly before: readonly string[]; readonly after: readonly string[] }
30
+ | { readonly overlayId: string; readonly field: 'node-added'; readonly node: string; readonly kind: string; readonly maxVisits: number }
31
+ | { readonly overlayId: string; readonly field: 'edge-rerouted'; readonly from: string; readonly outcome: string; readonly was: string; readonly to: string };
30
32
 
31
33
  export type OverlayResult =
32
34
  | { ok: true; template: GraphTemplate; patches: readonly OverlayPatch[] }
@@ -0,0 +1,107 @@
1
+ import { readFileSync, readdirSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { parse as parseYaml } from 'yaml';
5
+ import { evaluateOverlayCondition, parseOverlayCondition } from './graph-overlay-condition.js';
6
+ import type { GraphParseIssue } from './graph-yaml.js';
7
+
8
+ /** L1 profile: a deterministic state bundle and references to already-declared overlays. */
9
+ export interface GraphProfileSpec {
10
+ readonly profileId: string;
11
+ readonly appliesWhen: string;
12
+ readonly state: Readonly<Record<string, string | number | boolean>>;
13
+ readonly overlays: readonly string[];
14
+ }
15
+
16
+ export interface GraphProfileParseResult {
17
+ readonly profile?: GraphProfileSpec;
18
+ readonly errors: readonly GraphParseIssue[];
19
+ }
20
+
21
+ export function parseGraphProfileYaml(source: string, label = '<inline>'): GraphProfileParseResult {
22
+ let raw: unknown;
23
+ try { raw = parseYaml(source); }
24
+ catch (error) {
25
+ return { errors: [{ path: label, message: `YAML 파싱 실패: ${error instanceof Error ? error.message : String(error)}` }] };
26
+ }
27
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
28
+ return { errors: [{ path: label, message: 'YAML 최상위가 맵이 아니다' }] };
29
+ const doc = raw as Record<string, unknown>;
30
+ const errors: GraphParseIssue[] = [];
31
+ const profileId = typeof doc.profile_id === 'string' && /^[a-z][a-z0-9-]*$/.test(doc.profile_id) ? doc.profile_id : undefined;
32
+ if (!profileId) errors.push({ path: `${label}/profile_id`, message: 'profile_id는 소문자·숫자·하이픈 식별자여야 한다' });
33
+ const appliesWhen = typeof doc.applies_when === 'string' ? doc.applies_when : undefined;
34
+ if (!appliesWhen || !parseOverlayCondition(appliesWhen).ok)
35
+ errors.push({ path: `${label}/applies_when`, message: 'applies_when은 오버레이 조건 한 개(key op literal)여야 한다' });
36
+ const stateRaw = doc.state;
37
+ const state: Record<string, string | number | boolean> = {};
38
+ if (!stateRaw || typeof stateRaw !== 'object' || Array.isArray(stateRaw)) {
39
+ errors.push({ path: `${label}/state`, message: 'state는 스칼라 값만 담는 맵이어야 한다' });
40
+ } else {
41
+ for (const [key, value] of Object.entries(stateRaw as Record<string, unknown>)) {
42
+ if (!/^[a-z_][a-z0-9_]*$/i.test(key) || !['string', 'number', 'boolean'].includes(typeof value)
43
+ || (typeof value === 'number' && !Number.isFinite(value))) {
44
+ errors.push({ path: `${label}/state/${key}`, message: 'state 키와 값은 조건 파서가 다루는 키·문자열·유한수·불리언이어야 한다' });
45
+ } else state[key] = value as string | number | boolean;
46
+ }
47
+ }
48
+ const overlaysRaw = doc.overlays;
49
+ const overlays = Array.isArray(overlaysRaw) ? overlaysRaw.filter((value): value is string => typeof value === 'string') : undefined;
50
+ if (!Array.isArray(overlaysRaw) || !overlays || overlays.length !== overlaysRaw.length || new Set(overlays).size !== overlays.length)
51
+ errors.push({ path: `${label}/overlays`, message: 'overlays는 중복 없는 문자열 목록이어야 한다' });
52
+ if (errors.length > 0) return { errors };
53
+ return { profile: { profileId: profileId!, appliesWhen: appliesWhen!, state, overlays: overlays! }, errors };
54
+ }
55
+
56
+ export interface GraphProfileLoadResult {
57
+ readonly profiles: readonly GraphProfileSpec[];
58
+ readonly errors: readonly GraphParseIssue[];
59
+ readonly scannedFiles: number;
60
+ }
61
+
62
+ export function loadGraphProfiles(dir: string): GraphProfileLoadResult {
63
+ let files: string[];
64
+ try { files = readdirSync(dir).filter((file) => file.endsWith('.yaml') || file.endsWith('.yml')).sort(); }
65
+ catch (error) { return { profiles: [], errors: [{ path: dir, message: `프로필 디렉토리를 못 읽었다: ${error instanceof Error ? error.message : String(error)}` }], scannedFiles: 0 }; }
66
+ const errors: GraphParseIssue[] = [];
67
+ const profiles: GraphProfileSpec[] = [];
68
+ for (const file of files) {
69
+ try {
70
+ const parsed = parseGraphProfileYaml(readFileSync(join(dir, file), 'utf8'), file);
71
+ errors.push(...parsed.errors);
72
+ if (parsed.profile) profiles.push(parsed.profile);
73
+ } catch (error) { errors.push({ path: file, message: `읽기 실패: ${error instanceof Error ? error.message : String(error)}` }); }
74
+ }
75
+ const seen = new Set<string>();
76
+ for (const profile of profiles) {
77
+ if (seen.has(profile.profileId)) errors.push({ path: `${dir}/${profile.profileId}`, message: `profile_id '${profile.profileId}'가 중복이다` });
78
+ seen.add(profile.profileId);
79
+ }
80
+ return errors.length ? { profiles: [], errors, scannedFiles: files.length } : { profiles, errors, scannedFiles: files.length };
81
+ }
82
+
83
+ export function defaultProfilesDir(): string {
84
+ return join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'graphs', 'profiles');
85
+ }
86
+
87
+ export interface GraphProfileSelection {
88
+ readonly applied: readonly GraphProfileSpec[];
89
+ readonly errors: readonly string[];
90
+ readonly state: Readonly<Record<string, unknown>>;
91
+ }
92
+
93
+ /** Match all profiles deterministically; conflicting owned state rejects the whole profile set. */
94
+ export function selectGraphProfiles(
95
+ profiles: readonly GraphProfileSpec[],
96
+ state: Readonly<Record<string, unknown>>,
97
+ ): GraphProfileSelection {
98
+ const applied = profiles.filter((profile) => evaluateOverlayCondition(profile.appliesWhen, state).kind === 'applies');
99
+ const owned = new Map<string, string | number | boolean>();
100
+ const errors: string[] = [];
101
+ for (const profile of applied) for (const [key, value] of Object.entries(profile.state)) {
102
+ if (owned.has(key) && owned.get(key) !== value) errors.push(`profile state conflict: ${key} (${String(owned.get(key))} vs ${String(value)})`);
103
+ else owned.set(key, value);
104
+ }
105
+ if (errors.length) return { applied: [], errors, state };
106
+ return { applied, errors, state: { ...state, ...Object.fromEntries(owned) } };
107
+ }
@@ -37,6 +37,8 @@ export interface GraphNodeSpec {
37
37
  /** Entry selected by this call when a unit exposes more than one entry. */
38
38
  readonly callEntry?: string;
39
39
  readonly budget?: { readonly innerSteps: number };
40
+ /** ARG L upper bound inherited by this child graph call. */
41
+ readonly allowance?: { readonly innerSteps: number };
40
42
  /** L1: skip this optional node when a measured state condition holds. */
41
43
  readonly skipWhen?: string;
42
44
  }
@@ -65,6 +67,8 @@ export interface GraphTemplateSpec {
65
67
  /** 문서 전용 변경이면 gate 노드를 건너뛸 수 있다는 템플릿 정책. */
66
68
  readonly docsOnlyGateSkip?: boolean;
67
69
  readonly state?: readonly string[];
70
+ /** ARG L upper bound for this graph's total executed steps. */
71
+ readonly allowance?: { readonly innerSteps: number };
68
72
  /** ⭐ 런 계약(선택) — 이 그래프가 «기본으로» 요구하는 실행 칸 등. 발사 인자가 덮는다(graph-run-contract.ts). */
69
73
  readonly runContract?: GraphRunContractSpec;
70
74
  readonly unit?: { readonly inputs: readonly string[]; readonly outputs: readonly string[]; readonly exits: readonly string[]; readonly entries?: readonly string[] };
@@ -148,6 +152,14 @@ export function parseGraphTemplateYaml(source: string, label = '<inline>'): Grap
148
152
 
149
153
  const terminalNodes = asArray(doc.terminal_nodes).filter((v): v is string => typeof v === 'string');
150
154
  if (terminalNodes.length === 0) errors.push({ path: `${label}/terminal_nodes`, message: 'terminal_nodes 가 비었다 — 끝날 수 없는 그래프다' });
155
+ let allowance: GraphTemplateSpec['allowance'];
156
+ if (doc.allowance !== undefined) {
157
+ const value = doc.allowance as Record<string, unknown> | undefined;
158
+ if (!value || typeof value !== 'object' || Array.isArray(value) || !Number.isSafeInteger(value.inner_steps) ||
159
+ (value.inner_steps as number) < 1 || Object.keys(value).some(key => key !== 'inner_steps'))
160
+ errors.push({ path: `${label}/allowance/inner_steps`, message: 'inner_steps 는 1 이상의 안전한 정수여야 한다' });
161
+ else allowance = { innerSteps: value.inner_steps as number };
162
+ }
151
163
 
152
164
  const journeyStages = doc.journey_stages;
153
165
  if (journeyStages !== undefined && (!Array.isArray(journeyStages) || journeyStages.length === 0
@@ -202,21 +214,28 @@ export function parseGraphTemplateYaml(source: string, label = '<inline>'): Grap
202
214
  : undefined;
203
215
  // A subgraph node becomes a unit call only when it names `call:`; without it the node keeps the
204
216
  // pre-unit meaning (catalog role / recipe node), so existing declarations stay valid.
205
- if (kind === 'subgraph' && (n.call !== undefined || n.budget !== undefined || n.call_entry !== undefined)) {
217
+ if (kind === 'subgraph' && (n.call !== undefined || n.budget !== undefined || n.allowance !== undefined || n.call_entry !== undefined)) {
206
218
  if (typeof n.call !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9._-]*@(?:\^?[1-9]\d*)$/.test(n.call))
207
219
  errors.push({ path: `${at}/call`, message: 'call 은 id@정수판 또는 id@^주판이어야 한다' });
208
220
  const budget = n.budget as Record<string, unknown> | undefined;
209
221
  if (!budget || typeof budget !== 'object' || Array.isArray(budget) ||
210
222
  !Number.isSafeInteger(budget.inner_steps) || (budget.inner_steps as number) < 1 || Object.keys(budget).some(key => key !== 'inner_steps'))
211
223
  errors.push({ path: `${at}/budget/inner_steps`, message: 'inner_steps 는 1 이상의 안전한 정수여야 한다' });
224
+ if (n.allowance !== undefined) {
225
+ const childAllowance = n.allowance as Record<string, unknown> | undefined;
226
+ if (!childAllowance || typeof childAllowance !== 'object' || Array.isArray(childAllowance) ||
227
+ !Number.isSafeInteger(childAllowance.inner_steps) || (childAllowance.inner_steps as number) < 1 ||
228
+ Object.keys(childAllowance).some(key => key !== 'inner_steps'))
229
+ errors.push({ path: `${at}/allowance/inner_steps`, message: 'inner_steps 는 1 이상의 안전한 정수여야 한다' });
230
+ }
212
231
  if (!contractRaw || !Array.isArray(contractRaw.inputs) || !contractRaw.inputs.every(v => typeof v === 'string') ||
213
232
  !Array.isArray(contractRaw.outputs) || !contractRaw.outputs.every(v => typeof v === 'string'))
214
233
  errors.push({ path: `${at}/contract`, message: 'subgraph 에는 inputs·outputs 계약이 필요하다' });
215
234
  if (recipe !== 'none') errors.push({ path: `${at}/recipe`, message: 'subgraph 는 recipe 를 실행하지 않는다' });
216
235
  if (n.call_entry !== undefined && (typeof n.call_entry !== 'string' || !n.call_entry.trim()))
217
236
  errors.push({ path: `${at}/call_entry`, message: 'call_entry 는 비어 있지 않은 노드 id 여야 한다' });
218
- } else if (kind !== 'subgraph' && (n.call !== undefined || n.budget !== undefined || n.call_entry !== undefined)) {
219
- errors.push({ path: at, message: 'call·call_entry·budget 은 subgraph 전용이다' });
237
+ } else if (kind !== 'subgraph' && (n.call !== undefined || n.budget !== undefined || n.allowance !== undefined || n.call_entry !== undefined)) {
238
+ errors.push({ path: at, message: 'call·call_entry·budget·allowance 은 subgraph 전용이다' });
220
239
  }
221
240
  // ⛔ 계약이 없으면 「이 노드가 무엇을 할 수 있나」를 답할 수 없다 — 경고로 남긴다(거절은 오버레이 쪽).
222
241
  if (contract === undefined) warnings.push({ path: `${at}/contract`, message: '계약(inputs·tools·outputs)이 없다 — 권한을 코드에서만 알 수 있다' });
@@ -235,6 +254,9 @@ export function parseGraphTemplateYaml(source: string, label = '<inline>'): Grap
235
254
  ...(kind === 'subgraph' && n.budget && typeof n.budget === 'object' && !Array.isArray(n.budget) &&
236
255
  typeof (n.budget as Record<string, unknown>).inner_steps === 'number'
237
256
  ? { budget: { innerSteps: (n.budget as { inner_steps: number }).inner_steps } } : {}),
257
+ ...(kind === 'subgraph' && n.allowance && typeof n.allowance === 'object' && !Array.isArray(n.allowance) &&
258
+ typeof (n.allowance as Record<string, unknown>).inner_steps === 'number'
259
+ ? { allowance: { innerSteps: (n.allowance as { inner_steps: number }).inner_steps } } : {}),
238
260
  ...(typeof n.skip_when === 'string' ? { skipWhen: n.skip_when } : {}),
239
261
  });
240
262
  }
@@ -358,6 +380,7 @@ export function parseGraphTemplateYaml(source: string, label = '<inline>'): Grap
358
380
  ...(loop ? { loop } : {}),
359
381
  ...(typeof doc.docs_only_gate_skip === 'boolean' ? { docsOnlyGateSkip: doc.docs_only_gate_skip } : {}),
360
382
  ...(Array.isArray(doc.state) ? { state: doc.state.filter((v): v is string => typeof v === 'string') } : {}),
383
+ ...(allowance ? { allowance } : {}),
361
384
  ...(runContract.spec ? { runContract: runContract.spec } : {}),
362
385
  },
363
386
  errors, warnings,
@@ -87,14 +87,14 @@ import type { ChannelBus } from '../terminal-matrix/channel-bus.js';
87
87
  import { federationObservation } from './orchestrator.js';
88
88
  // ⛔ 배달 상태는 「정하는 쪽」(orchestrator)이 소유한다 — 여기는 받아서 찍기만 한다.
89
89
  import type { SupervisorDeliveryLine, SupervisorDeliveryState } from './orchestrator.js';
90
- import type { RunShardIdentity } from './run-ledger.js';
90
+ import { runLedgerDir, type RunShardIdentity } from './run-ledger.js';
91
+ import { readRunChart, recordRunChartDecision, recordRunChartWaitHandoff, RUN_DOCTOR_HANDOFF_WAIT_THRESHOLD, RUN_DOCTOR_HANDOFF_INPUT_PREFIX } from './run-chart.js';
91
92
 
92
93
  const sleep = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));
93
94
 
94
95
  // Boundary requests observed up to about 788 characters; preserve the complete request record.
95
96
  const HARNESS_BOUNDARY_REQUEST_STRING_MAX = 1024;
96
97
  const WAIT_SUPERVISION_PROGRESS_BATCH_SIZE = 5;
97
-
98
98
  /** Renders untrusted boundary metadata as one inert terminal line for the parent surface. */
99
99
  export function singleLineBoundarySurfaceValue(value: string): string {
100
100
  return value
@@ -1267,6 +1267,9 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1267
1267
  let sameCommandStallCount = 0;
1268
1268
  let pendingWaitSupervisionCount = 0;
1269
1269
  let pendingWaitLatestJudgment: string | undefined;
1270
+ let consecutiveWaitDecisionCount = 0;
1271
+ let waitStreakHandoffSent = false;
1272
+ let waitStreakIndex = 0;
1270
1273
  // Repetition identity is exact full instruction-text equality after the existing delivery trim;
1271
1274
  // the first occurrence omits the surface marker, and later occurrences are only annotated.
1272
1275
  const inputInstructionOccurrences = new Map<string, number>();
@@ -1699,6 +1702,8 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1699
1702
  descriptor: { controlStance: stance },
1700
1703
  });
1701
1704
  previousIntervention = intervention;
1705
+ const chartDir = runLedgerDir(opts.stateDir);
1706
+ const chartBeforeJudgment = readRunChart(runId, 'run-supervisor', chartDir);
1702
1707
  const controlObs: ControlObservation = {
1703
1708
  screen: rendered,
1704
1709
  state: curState,
@@ -1708,6 +1713,8 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1708
1713
  sameScreenMs: Math.max(0, nowMs - frameObs.screenSinceMs),
1709
1714
  stallRung: frameObs.stallRung,
1710
1715
  ...(roundContext ? { roundContext } : {}),
1716
+ runId,
1717
+ runChart: chartBeforeJudgment,
1711
1718
  };
1712
1719
  const controller = new AbortController();
1713
1720
  let rejectParentAbort: ((reason: Error) => void) | undefined;
@@ -1821,11 +1828,14 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1821
1828
  debug.log('self-implement', 'brain.suggestion', supervisionVerdictPayload);
1822
1829
  debug.log('self-implement', 'run-supervision.verdict', supervisionVerdictPayload);
1823
1830
  if (decision.action === 'wait') {
1831
+ consecutiveWaitDecisionCount += 1;
1824
1832
  pendingWaitSupervisionCount += 1;
1825
1833
  pendingWaitLatestJudgment = decision.action;
1826
1834
  if (pendingWaitSupervisionCount >= WAIT_SUPERVISION_PROGRESS_BATCH_SIZE) flushWaitSupervisionProgress();
1827
1835
  } else {
1828
1836
  flushWaitSupervisionProgress();
1837
+ consecutiveWaitDecisionCount = 0;
1838
+ waitStreakHandoffSent = false;
1829
1839
  const input = decision.action === 'input' ? decision.text.trim() : '';
1830
1840
  const inputInstructionOccurrence = input ? countInputInstructionOccurrence(input) : undefined;
1831
1841
  const delivery = input ? (opts.onSupervisorInput ? 'queued' : 'not-delivered') : undefined;
@@ -1858,6 +1868,25 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1858
1868
  }), 'supervision');
1859
1869
  });
1860
1870
  }
1871
+ const handoffNow = decision.action === 'wait'
1872
+ && consecutiveWaitDecisionCount >= RUN_DOCTOR_HANDOFF_WAIT_THRESHOLD && !waitStreakHandoffSent;
1873
+ const chartStopKey = handoffNow ? `${runId}:wait-streak:${waitStreakIndex + 1}` : `${runId}:supervisor:${i}`;
1874
+ const chartWrite = handoffNow
1875
+ ? recordRunChartWaitHandoff({ runId, stopKey: chartStopKey, waitCount: consecutiveWaitDecisionCount,
1876
+ readStopKeys: chartBeforeJudgment.map((cell) => cell.stopKey), dir: chartDir })
1877
+ : recordRunChartDecision({ runId, device: 'run-supervisor', stopKey: chartStopKey,
1878
+ observed: `${curState}; stallRung=${st?.rung ?? NO_STALL}`, verdict: decision.action,
1879
+ action: decision.action === 'input' ? decision.text.slice(0, 120) : decision.action,
1880
+ handoff: decision.action === 'no-progress' ? 'macrophage' : null,
1881
+ why: decision.action === 'no-progress' ? decision.reason : `supervisor ${decision.action}`,
1882
+ readStopKeys: chartBeforeJudgment.map((cell) => cell.stopKey), dir: chartDir });
1883
+ if (handoffNow && (chartWrite === 'recorded' || chartWrite === 'already-recorded')) {
1884
+ waitStreakHandoffSent = true; waitStreakIndex += 1;
1885
+ debug.log('run-supervisor', 'doctor-handoff', { runId, stopKey: chartStopKey, waitCount: consecutiveWaitDecisionCount, handoff: 'doctor' });
1886
+ opts.onSupervisorInput?.(`${RUN_DOCTOR_HANDOFF_INPUT_PREFIX} runId=${runId} stopKey=${chartStopKey} waitCount=${consecutiveWaitDecisionCount}`, (delivery, reason) => {
1887
+ try { debug.log('run-supervisor', 'doctor-handoff-delivery', { runId, stopKey: chartStopKey, delivery, ...(reason ? { reason } : {}) }); } catch { /* observation is fail-soft */ }
1888
+ });
1889
+ }
1861
1890
  debug.log('self-implement', 'brain.input-outcome', {
1862
1891
  ptyId: h.id, runId, step: i, axis: 'assist', action: decision.action,
1863
1892
  applied: autoAssist.assist, why: autoAssist.why,
@@ -6,6 +6,7 @@ import { debug } from '../debug/log.js';
6
6
  import { passJourneyNode } from '../self-dev/graph-journey-nodes.js';
7
7
  import { getUserConfig } from '../user-config.js';
8
8
  import { psProcessStartMs, START_TOLERANCE_MS } from '../harness/harness-stop.js';
9
+ import { appendRunLedgerEntry, runLedgerDir } from './run-ledger.js';
9
10
 
10
11
  export type FailureSource = 'release-run' | 'harness-run' | 'loop-tick' | 'cron';
11
12
 
@@ -14,14 +15,19 @@ export interface FailureEvent {
14
15
  kind: string;
15
16
  ref: string;
16
17
  summary: string;
18
+ goalText?: string;
19
+ goalId?: string;
20
+ goalFile?: string;
21
+ cellKey?: string;
17
22
  at: string;
18
23
  }
19
24
 
20
25
  const FOLD_WINDOW_MS = 60 * 60 * 1_000;
21
26
  const HEAL_GRAPH = join(import.meta.dir, '../../graphs/heal/heal-loop.yaml');
22
27
 
23
- type HealLoopOptions = { runId: string; input: { failureEvent: FailureEvent }; deps: { root: string } };
28
+ type HealLoopOptions = { runId: string; input: { failureEvent: FailureEvent; runId?: string; goal?: string; goalId?: string; goalFile?: string }; deps: { root: string } };
24
29
  type StartHealLoop = (file: string, options: HealLoopOptions) => Promise<unknown>;
30
+ export type HealRelaunch = (input: { runId: string; goalText: string; goalId?: string; goalFile?: string; cellKey: string; stateRoot: string }) => Promise<unknown>;
25
31
 
26
32
  function healRunId(event: FailureEvent): string {
27
33
  return `heal-${createHash('sha256').update(JSON.stringify([event.source, event.ref, event.at])).digest('hex')}`;
@@ -68,7 +74,8 @@ function liveHealRuns(root: string): Set<string> {
68
74
 
69
75
  /** A test process must never start the real heal loop — it spawns external grounding (10-05 load 150 incident). */
70
76
  export async function startHealLoop(file: string, options: HealLoopOptions, env: NodeJS.ProcessEnv = process.env,
71
- run: StartHealLoop = async (graph, args) => (await import('../graph-runner/runner.js')).runGraph(graph, args)): Promise<unknown> {
77
+ run: StartHealLoop = async (graph, args) => (await import('../graph-runner/runner.js')).runGraph(graph, args),
78
+ relaunch: HealRelaunch = runReauthoredGoal): Promise<unknown> {
72
79
  if (env.ELANOUS_POD_NAME) {
73
80
  debug.log('heal.intake', 'skipped-in-pod', { ref: options.input.failureEvent.ref });
74
81
  return undefined;
@@ -112,8 +119,40 @@ export async function startHealLoop(file: string, options: HealLoopOptions, env:
112
119
  if (!selected) return undefined;
113
120
  let started = false;
114
121
  try {
115
- const result = await run(file, { runId: selected.runId, input: { failureEvent: selected.event }, deps: { root } });
122
+ const result = await run(file, { runId: selected.runId, input: { failureEvent: selected.event, runId: selected.event.ref, goal: selected.event.goalText, goalId: selected.event.goalId, goalFile: selected.event.goalFile }, deps: { root } });
116
123
  started = true;
124
+ const request = reauthorRequest(result);
125
+ if (request) {
126
+ const cellKey = selected.event.goalId || selected.event.goalFile || selected.event.cellKey
127
+ || (selected.event.goalText?.trim() ? `goal:${createHash('sha256').update(selected.event.goalText.replace(/\s+/g, ' ').trim()).digest('hex')}` : `run:${selected.event.ref}`);
128
+ if (!claimReauthorAttempt(root, cellKey, selected.runId)) {
129
+ debug.log('heal.intake', 'reauthor-already-attempted', { runId: selected.runId, goalId: selected.event.goalId ?? null });
130
+ return { result, reauthor: 'already-attempted' };
131
+ }
132
+ try {
133
+ debug.log('self-dev.supervisor', 'reauthor-relaunch-requested', { runId: selected.runId, goalId: selected.event.goalId ?? null });
134
+ const relaunched = await relaunch({ runId: selected.event.ref, goalText: request.revisedGoal,
135
+ ...(selected.event.goalId ? { goalId: selected.event.goalId } : {}),
136
+ ...(selected.event.goalFile ? { goalFile: selected.event.goalFile } : {}), cellKey, stateRoot: root });
137
+ if (relaunched && typeof relaunched === 'object' && 'ok' in relaunched && (relaunched as { ok?: unknown }).ok !== true) {
138
+ const value = relaunched as { stage?: unknown; node?: unknown; outcome?: unknown };
139
+ throw new Error(`needs-human: reauthored run failed (${String(value.stage ?? value.node ?? value.outcome ?? 'unknown')})`);
140
+ }
141
+ appendRunLedgerEntry({ timestamp: new Date().toISOString(), runId: selected.event.ref, event: 'reauthor-relaunch-result',
142
+ data: { outcome: 'started', goalId: selected.event.goalId ?? null, requestRunId: selected.runId, result: summarizeRelaunch(relaunched) } }, runLedgerDir(root));
143
+ return { result, reauthor: 'relaunched', relaunched };
144
+ } catch (error) {
145
+ appendRunLedgerEntry({ timestamp: new Date().toISOString(), runId: selected.event.ref, event: 'reauthor-relaunch-result',
146
+ data: { outcome: 'needs-human', reason: error instanceof Error ? error.message : String(error) } }, runLedgerDir(root));
147
+ return { result, reauthor: 'needs-human', reason: error instanceof Error ? error.message : String(error) };
148
+ }
149
+ }
150
+ const replanFailure = reauthorFailure(result);
151
+ if (replanFailure) {
152
+ appendRunLedgerEntry({ timestamp: new Date().toISOString(), runId: selected.event.ref, event: 'reauthor-relaunch-result',
153
+ data: { outcome: 'needs-human', reason: replanFailure, graphRunId: selected.runId } }, runLedgerDir(root));
154
+ return { result, reauthor: 'needs-human', reason: replanFailure };
155
+ }
117
156
  return result;
118
157
  } finally {
119
158
  withInboxLock(inboxPath(root), () => {
@@ -125,12 +164,81 @@ export async function startHealLoop(file: string, options: HealLoopOptions, env:
125
164
  }
126
165
  });
127
166
  // A completed run opens a slot; a pre-ledger failure waits for the next intake rather than retrying in a tight loop.
128
- if (started) void Promise.resolve().then(() => startHealLoop(file, options, env, run)).catch(error => {
167
+ if (started) void Promise.resolve().then(() => startHealLoop(file, options, env, run, relaunch)).catch(error => {
129
168
  debug.log('heal.intake', 'loop-start-failed', { runId: selected.runId, error: String(error) }, { level: 'error' });
130
169
  });
131
170
  }
132
171
  }
133
172
 
173
+ function graphOutput(result: unknown, nodeId: string): Record<string, unknown> | undefined {
174
+ if (!result || typeof result !== 'object') return undefined;
175
+ const nodes = (result as { nodes?: unknown }).nodes;
176
+ if (!Array.isArray(nodes)) return undefined;
177
+ const node = nodes.find((item) => item && typeof item === 'object' && (item as { nodeId?: unknown }).nodeId === nodeId) as { output?: unknown } | undefined;
178
+ if (typeof node?.output === 'string') {
179
+ const text = node.output.trim().split(/\r?\n/).at(-1) ?? '';
180
+ try { return JSON.parse(text) as Record<string, unknown>; } catch { return undefined; }
181
+ }
182
+ return node?.output && typeof node.output === 'object' ? node.output as Record<string, unknown> : undefined;
183
+ }
184
+
185
+ function reauthorRequest(result: unknown): { revisedGoal: string } | undefined {
186
+ const output = graphOutput(result, 'replan');
187
+ return output?.outcome === 'ok' && output.reauthor === true && typeof output.revisedGoal === 'string' && output.revisedGoal.trim()
188
+ ? { revisedGoal: output.revisedGoal } : undefined;
189
+ }
190
+
191
+ function reauthorFailure(result: unknown): string | undefined {
192
+ const output = graphOutput(result, 'replan');
193
+ return output?.outcome === 'fail' && output.needsHuman === true
194
+ ? (typeof output.reason === 'string' ? output.reason : 'reauthor could not produce a safe revised goal') : undefined;
195
+ }
196
+
197
+ function claimReauthorAttempt(root: string, cellKey: string, runId: string): boolean {
198
+ const path = join(root, 'heal', 'reauthor-attempts', `${createHash('sha256').update(cellKey).digest('hex')}.json`);
199
+ return withInboxLock(path, () => {
200
+ if (existsSync(path)) return false;
201
+ writeFileSync(path, JSON.stringify({ cellKey, runId, claimedAt: new Date().toISOString() }), { flag: 'wx', mode: 0o600 });
202
+ return true;
203
+ });
204
+ }
205
+
206
+ function summarizeRelaunch(result: unknown): Record<string, unknown> {
207
+ if (!result || typeof result !== 'object') return { resultType: typeof result };
208
+ const value = result as Record<string, unknown>;
209
+ return Object.fromEntries(['ok', 'stage', 'node', 'runId', 'worktreePath', 'branch', 'detail'].flatMap((key) => key in value ? [[key, value[key]]] : []));
210
+ }
211
+
212
+ async function runReauthoredGoal(input: Parameters<HealRelaunch>[0]): Promise<unknown> {
213
+ const [{ runSelfImplement, readQuotaExhausted }, { defaultSeams }, devCli, { reselectChildForRework }, { resolveGrokCredential }, { inspectCodexRotation }, ledger] = await Promise.all([
214
+ import('./orchestrator.js'), import('./seams.js'), import('../self-dev/dev-cli.js'), import('./rework-child-provider.js'),
215
+ import('../grok/credential.js'), import('../oauth/codex-account-store.js'), import('./run-ledger.js'),
216
+ ]);
217
+ let childLlm = devCli.buildChildLlmSelection({});
218
+ if (childLlm?.provider === 'grok') {
219
+ const grokQuota = devCli.readGrokQuotaForLaunch();
220
+ const grokCredential = resolveGrokCredential() ? 'available' as const : 'unavailable' as const;
221
+ const rotation = inspectCodexRotation();
222
+ const quota = readQuotaExhausted(inspectCodexRotation, 'openai-codex');
223
+ const hasCodex = rotation.knownAccountCount > 0;
224
+ const alternate = hasCodex ? { provider: 'openai-codex', model: devCli.defaultChildLlmModel('openai-codex'), source: 'config' as const } : undefined;
225
+ const decision = reselectChildForRework({ current: childLlm, grokQuota, grokCredential, ...(alternate ? { alternate } : {}),
226
+ alternateCredential: hasCodex ? 'available' : 'unavailable', alternateQuotaExhausted: quota.exhausted });
227
+ if (decision.action === 'reselect') {
228
+ childLlm = decision.selection;
229
+ ledger.appendRunLedgerEntry({ timestamp: new Date().toISOString(), runId: input.runId, event: 'rework-child-model-reselected',
230
+ data: { previousProvider: decision.previous.provider, previousModel: decision.previous.model, provider: childLlm.provider,
231
+ model: childLlm.model, reason: decision.reason, quota: grokQuota, grokCredential,
232
+ alternateQuotaExhausted: quota.exhausted ?? null } }, runLedgerDir(input.stateRoot));
233
+ }
234
+ else if (grokQuota === 'exhausted' || grokCredential === 'unavailable') throw new Error('needs-human: Grok unusable and no measured alternate provider');
235
+ }
236
+ const runId = `reauthor-${createHash('sha256').update(`${input.runId}\0${input.goalId ?? ''}`).digest('hex').slice(0, 20)}`;
237
+ return runSelfImplement({ feature: input.goalText, runId, ...(input.goalId ? { goalId: input.goalId } : {}),
238
+ ...(input.goalFile ? { goalFile: input.goalFile } : {}), healCellKey: input.cellKey, ...(childLlm ? { childLlm } : {}),
239
+ completion: 'worktree-only', draft: true, maxReworkRounds: 0, seams: defaultSeams({ stateDir: input.stateRoot }) });
240
+ }
241
+
134
242
  function inboxPath(root: string): string {
135
243
  return join(root, 'heal', 'inbox.jsonl');
136
244
  }
@@ -11,6 +11,7 @@ export type HealTriageOutcome =
11
11
  | 'needs-deeper-observation'
12
12
  | 'needs-grounding'
13
13
  | 'rework-with-citations'
14
+ | 'reauthor-from-materialized'
14
15
  | 'exhausted';
15
16
 
16
17
  export interface HealCitation {
@@ -30,6 +31,12 @@ export interface HealFailureSignature {
30
31
  readonly importerUnrunTests?: number;
31
32
  readonly environmentClaim?: string;
32
33
  readonly namedSource?: string;
34
+ /** Observations from the failed materialized run; no new collector is implied. */
35
+ readonly noProgressReason?: string;
36
+ readonly reportDeficit?: boolean;
37
+ readonly mustFix?: readonly string[];
38
+ readonly materializedPaths?: readonly string[];
39
+ readonly goalText?: string;
33
40
  }
34
41
 
35
42
  /** 게이트 사실로 채울 수 있는 칸. 없는 칸만 채운다. */
@@ -227,6 +234,19 @@ export function triageFailure(signature: HealFailureSignature, history?: HealTri
227
234
  const importer = signature.importerUnrunTests ?? 0;
228
235
  const claim = signature.environmentClaim?.trim() ?? '';
229
236
 
237
+ const mustFix = (signature.mustFix ?? []).map((item) => item.trim()).filter(Boolean);
238
+ const repeatedMustFix = mustFix.some((item, index) => mustFix.slice(0, index).includes(item));
239
+ if (signature.noProgressReason?.trim() || signature.reportDeficit || signature.materializedPaths?.length === 0
240
+ || repeatedMustFix || (signature.errorText ?? '').includes('tdd-evidence-missing')) {
241
+ return { outcome: 'reauthor-from-materialized', evidence: [
242
+ ...(signature.noProgressReason ? [`no-progress: ${signature.noProgressReason}`] : []),
243
+ ...(signature.reportDeficit ? ['report-deficit'] : []),
244
+ ...(signature.materializedPaths?.length === 0 ? ['actual target paths: 0'] : []),
245
+ ...(repeatedMustFix ? ['same must-fix repeated'] : []),
246
+ ...((signature.errorText ?? '').includes('tdd-evidence-missing') ? ['tdd-evidence-missing'] : []),
247
+ ] };
248
+ }
249
+
230
250
  if (claim && ENVIRONMENT_CLAIM.test(claim) && !visited(history, 'verify-evidence')) {
231
251
  return {
232
252
  outcome: 'environment-claimed',
@@ -12,7 +12,7 @@ import { detectTestInterference, failedNamesFromStreams, parseFailureCount, runB
12
12
  import { MAX_INSPECTED_TEST_FILES, runTestInterferenceGate } from '../../scripts/ci-test-interference-gate.js';
13
13
  import { pwaGraph, pwaReach } from '../../scripts/ci-pwa-build-gate.js';
14
14
  import { changedPathPairs, changedTsFiles, readGitFile, requiredExportFieldsInChanges } from '../../scripts/ci-typecheck-changed.js';
15
- import { classifyMergeFailure, clipRegateDetail, parseConflictFiles, type HostRegateFailure } from './regate-detail.js';
15
+ import { classifyMergeFailure, clipRegateDetail, parseConflictFiles, type HostRegateFailure, type HostRegatePrHeadFailureCondition, type HostRegatePrHeadSnapshot } from './regate-detail.js';
16
16
  import { buildImporterTestIndex, isTestPath } from './importer-test-index.js';
17
17
  import type { GateReceipt, GateReceiptIdentity } from './gate-receipt-registry.js';
18
18
 
@@ -386,9 +386,32 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
386
386
  release = await (deps.acquire ?? acquireSlot)(input.repoRoot);
387
387
  type PrView = { headRefOid?: string; baseRefName?: string; baseRefOid?: string; state?: string; isDraft?: boolean };
388
388
  const readPr = (): PrView => JSON.parse(run('gh', ['pr', 'view', String(input.prNumber), '--json', 'headRefOid,baseRefName,baseRefOid,state,isDraft'], input.repoRoot));
389
- const prHeadFailure = (seen: PrView): HostRegateResult => result('unmeasured', 'pr-head',
390
- `PR head, base commit, ready state or open state unavailable or changed (state=${seen.state ?? 'unknown'} · isDraft=${String(seen.isDraft)} · base=${seen.baseRefName ?? 'unknown'}@${seen.baseRefOid ?? 'unknown'})`,
391
- { expectedHead: input.headCommit, actualHead: typeof seen.headRefOid === 'string' ? seen.headRefOid : null });
389
+ const prHeadFailure = (seen: PrView): HostRegateResult => {
390
+ const failedConditions: HostRegatePrHeadFailureCondition[] = [];
391
+ const validHead = typeof seen.headRefOid === 'string' && /^[0-9a-f]{40}$/i.test(seen.headRefOid);
392
+ if (!validHead) failedConditions.push('head-unavailable');
393
+ else if (seen.headRefOid !== input.headCommit) failedConditions.push('head-mismatch');
394
+ if (typeof seen.state !== 'string') failedConditions.push('state-unavailable');
395
+ else if (seen.state !== 'OPEN') failedConditions.push('state-not-open');
396
+ if (typeof seen.isDraft !== 'boolean') failedConditions.push('draft-status-unavailable');
397
+ else if (seen.isDraft && !input.allowDraft) failedConditions.push('pr-is-draft');
398
+ if (!seen.baseRefName) failedConditions.push('base-name-unavailable');
399
+ const validBaseOid = typeof seen.baseRefOid === 'string' && /^[0-9a-f]{40}$/i.test(seen.baseRefOid);
400
+ if (!validBaseOid) failedConditions.push('base-oid-invalid');
401
+ failedConditions.sort();
402
+ const state: HostRegatePrHeadSnapshot['state'] =
403
+ seen.state === 'OPEN' || seen.state === 'CLOSED' || seen.state === 'MERGED' ? seen.state : typeof seen.state === 'string' ? 'OTHER' : null;
404
+ const snapshot: HostRegatePrHeadSnapshot = {
405
+ headRefOid: validHead ? seen.headRefOid! : null,
406
+ state,
407
+ isDraft: typeof seen.isDraft === 'boolean' ? seen.isDraft : null,
408
+ baseRefName: !seen.baseRefName ? null : seen.baseRefName === 'main' ? 'main' : 'other',
409
+ baseRefOid: validBaseOid ? seen.baseRefOid! : null,
410
+ };
411
+ return result('unmeasured', 'pr-head',
412
+ `PR head preflight failed: ${failedConditions.join(', ') || 'unknown'} (state=${snapshot.state ?? 'unknown'} · isDraft=${String(snapshot.isDraft)} · base=${snapshot.baseRefName ?? 'unknown'}@${snapshot.baseRefOid ?? 'unknown'})`,
413
+ { expectedHead: input.headCommit, actualHead: snapshot.headRefOid, failedConditions, prHeadSnapshot: snapshot });
414
+ };
392
415
  let view: PrView;
393
416
  try { view = readPr(); }
394
417
  catch (e) { return result('unmeasured', 'pr-view', String(e)); }