elanous 0.2.40 → 0.2.42

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 (685) hide show
  1. package/README.md +7 -7
  2. package/apps/pwa/out/404/index.html +1 -1
  3. package/apps/pwa/out/404.html +1 -1
  4. package/apps/pwa/out/_next/static/{HjeK7zONHfR7op1hKXp4k → X1ucLw10Cds_h614NoEnh}/_buildManifest.js +1 -1
  5. package/apps/pwa/out/_next/static/chunks/0244e5b5.6fc7670f8223d82d.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/{4769.9fd582071301f382.js → 1063.2fb8a9dc55c731f2.js} +1 -1
  7. package/apps/pwa/out/_next/static/chunks/1121.13ba7a8aff19df81.js +36 -0
  8. package/apps/pwa/out/_next/static/chunks/1147-5196d19c222051b3.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/{470.51a72a2348306455.js → 1262.e804feb8fd1acb8c.js} +2 -2
  10. package/apps/pwa/out/_next/static/chunks/1319.b9b815ae0f181e06.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1345-31427b833438f521.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/{7219-15bdd9a80661af8e.js → 1455-530ca16c7e71baff.js} +1 -1
  13. package/apps/pwa/out/_next/static/chunks/{1281.d81877e35b9068f4.js → 1487.2f67b79444062da6.js} +1 -1
  14. package/apps/pwa/out/_next/static/chunks/1574.878c18ecc97b1bd4.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1586.fafc33a9a5835cb7.js +32 -0
  16. package/apps/pwa/out/_next/static/chunks/1744.855fd60ae4c4a8c8.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/193.21a47a3e07ef6860.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1945.7b54990d578c119b.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/2004.e839fda7ea5a738a.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2044-dd681a5c08779ff8.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2101.2248decb38829b03.js +286 -0
  22. package/apps/pwa/out/_next/static/chunks/2160.a097e7b138ae1c55.js +23 -0
  23. package/apps/pwa/out/_next/static/chunks/2300.41ea70ac1bef1446.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2357-07b5eeb5fb12628d.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2364.28652020695a6db3.js +34 -0
  26. package/apps/pwa/out/_next/static/chunks/{1350.59f40e39e02d91b1.js → 2456.b6de0e1c05f28843.js} +1 -1
  27. package/apps/pwa/out/_next/static/chunks/2526.c3e50ac1fec064bd.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2549-cda50b716ff4250c.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/2550-5f1e88f615568045.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/261-319078c954e40d66.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/2690.0521c738b7749931.js +115 -0
  32. package/apps/pwa/out/_next/static/chunks/{5436.fdf6fa8ae3e9588d.js → 2974.595d1e29d040cb6a.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/{5383.bdfa5d886e39a826.js → 3207.a756c95e9ec8c3c8.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/3285.89ee2f298682f5e5.js +93 -0
  35. package/apps/pwa/out/_next/static/chunks/{2177.df8547f9d7215c4e.js → 3347.f846266b5e5f3ede.js} +3 -3
  36. package/apps/pwa/out/_next/static/chunks/3447.06edc7b092021417.js +41 -0
  37. package/apps/pwa/out/_next/static/chunks/{9184.45afbf44fec87574.js → 3482.a9ae9d2ad6a5bd97.js} +1 -1
  38. package/apps/pwa/out/_next/static/chunks/3507.97e1977bc4d5fb0a.js +2 -0
  39. package/apps/pwa/out/_next/static/chunks/3510-9ca392698bfe4391.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3541.772e5ce425aaa611.js +24 -0
  41. package/apps/pwa/out/_next/static/chunks/{8099.1cccf31c1baa7e1c.js → 3741.9cf76acaa2ee5298.js} +1 -1
  42. package/apps/pwa/out/_next/static/chunks/3837.a210d7d0db8d8abd.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3898-955c896f394217a6.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/3947-ef57acea76eaa8d2.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{4864a2ca.1c1c280a7772c5e5.js → 3d0154af.5331fec737ffe8c3.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/4037-3b82ebc7d78afdc7.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4043.6b91203436c9c86b.js +309 -0
  48. package/apps/pwa/out/_next/static/chunks/405.9022d4a478202b67.js +77 -0
  49. package/apps/pwa/out/_next/static/chunks/417-fb2cc9a9910e5968.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/{3330.7443183b7e6fdbdf.js → 4276.336d76d858fcdf1b.js} +1 -1
  51. package/apps/pwa/out/_next/static/chunks/4302.6ced9aa4535de947.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4320.583cbab64db6be02.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4768-8eac183fd291ca53.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4770.769c9cd9c7034eba.js +148 -0
  55. package/apps/pwa/out/_next/static/chunks/4895.65605ec3e6504e89.js +74 -0
  56. package/apps/pwa/out/_next/static/chunks/{3b355b3d.6f73c98bf6f9c749.js → 50061469.0326382241ef3b2d.js} +1 -1
  57. package/apps/pwa/out/_next/static/chunks/5112.4b9f300124fab7b3.js +149 -0
  58. package/apps/pwa/out/_next/static/chunks/5335.375ee922bcd5bc83.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5342.023a2e729689b320.js +27 -0
  60. package/apps/pwa/out/_next/static/chunks/{8d173e38.18a2f7b4e1848bdb.js → 53c73f84.373b6160adfa89a4.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{1537-6bb97b5214928ea9.js → 5431-72a1dbde59400691.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5440-4236de26c5ea5856.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/5486-b318c165f645d8ba.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5506-c7d2ec25c62a7c94.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/5570-c66ecbea26b4e3b1.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5696.ffca5aa259d8451e.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5793-8c584aea2aa87560.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5848-6de6b8c173351a90.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/5885.0a3e52c8faccec98.js +287 -0
  70. package/apps/pwa/out/_next/static/chunks/5999.94e3c83040200f31.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/5a7901d6-2d8d9b5587cf9042.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/{261.0d471e8aded799f3.js → 6131.348b7d6bdcd267ce.js} +3 -3
  73. package/apps/pwa/out/_next/static/chunks/6164.86133a0172611184.js +90 -0
  74. package/apps/pwa/out/_next/static/chunks/{9175.2de5209a5ce6f68a.js → 6377.bc7df239edbff244.js} +1 -1
  75. package/apps/pwa/out/_next/static/chunks/6515.e07e8b2b8a707a87.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6522-c005514f87d18982.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/{2226.2cf61ec781827219.js → 6632.0eac1c554f8f2ef3.js} +2 -2
  78. package/apps/pwa/out/_next/static/chunks/6642.648adb1767f39ecf.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6848.138805a09d001d09.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/7049-c09e2b7a253a24f3.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7072.1e00447d9fa39972.js +104 -0
  82. package/apps/pwa/out/_next/static/chunks/7106.64201c539c5e220c.js +94 -0
  83. package/apps/pwa/out/_next/static/chunks/7151-1f742b455986530e.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7199.18d6b25e001154ce.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7279-c199ea83f34338fa.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/728b938d.ffaa7ad583d60e58.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7309.171c3de54e0322f1.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/733.7a1ab3342e03306f.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/{b84cad00.594027ebe0531fe2.js → 73d2eb0e.4966ad55293c801a.js} +3 -3
  90. package/apps/pwa/out/_next/static/chunks/{6257.c0037b8949239f5e.js → 7411.9b4b8b747dc7b802.js} +2 -2
  91. package/apps/pwa/out/_next/static/chunks/7504.d5cf1e7cd89b1b08.js +24 -0
  92. package/apps/pwa/out/_next/static/chunks/7573-0fd4af62d65d4598.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/759.6f8267df4689c401.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7825-668b046f72f14483.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/7852-1538768b6eb19388.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/7868.cff810430bb63c91.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/{9189505a.980427ac048c8c60.js → 7a98bc80.fa935989e829f9c2.js} +1 -1
  98. package/apps/pwa/out/_next/static/chunks/8084-dfcc796874ab4e07.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/8138.6c10b2a356d52fca.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/{2566.beaffc3a5e1fcd2e.js → 8262.ddc03e06b733f184.js} +1 -1
  101. package/apps/pwa/out/_next/static/chunks/8266.6bf9b131b2584678.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8403.7b81d5e64074a725.js +8 -0
  103. package/apps/pwa/out/_next/static/chunks/8470.1998cbd0866a7eac.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8505.fd803c6c33b54cc3.js +79 -0
  105. package/apps/pwa/out/_next/static/chunks/{8272-025653884f9645d2.js → 8546-6f03f8ea34dd61d9.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/{6051-0ae955eedb10adb9.js → 8673-bab689a55f7e13b9.js} +3 -3
  107. package/apps/pwa/out/_next/static/chunks/8687-246fda8433d3477c.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/898-280022fb082936bc.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9098-50eefc1844212e3d.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/9211-330b6736a63d4cb3.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/{4351.0f37a6db2b34d50b.js → 9249.976f1e69a9d80754.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/9255-cf88fceda5666645.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9306-e523ba58bb8adc42.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/9324.a9866d717ba62cb6.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9325.a8510e8aa87c8143.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9353-12bfff0c130104cf.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9415.69e4a21c60c7d2db.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{6749.0744ce6eb08d40e9.js → 9427.96aa912ddb5801e0.js} +16 -16
  119. package/apps/pwa/out/_next/static/chunks/9479-154a697d4b6e4e98.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9540-65aa6ccc31b3fd78.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{7611.85f045bf232053ac.js → 9633.ce5bddc56784da72.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/{3746-f80a78f220bf37b5.js → 9656-374232558fd528d0.js} +1 -1
  123. package/apps/pwa/out/_next/static/chunks/9832.f4a98c878ecf2c0a.js +62 -0
  124. package/apps/pwa/out/_next/static/chunks/9865.f094440645f02d98.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/9a852a62-6192a6ea9346ced3.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-e772b4710df5d936.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4361368e6a76b967.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-802f349fdd65248d.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/board/page-7f35513988a2a495.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/botlab/page-798121656540e33e.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/bots/page-20a089490affe98c.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/ceo/page-e5e4ec786d70e604.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/chat/page-d12fe5d0801430e4.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/consult/page-d8cf21022fecc026.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/control/page-21ce565c9c57ee97.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/decisions/page-b56563025f619c9b.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/design-check/page-52f14dd133da8348.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/editor/page-c0ed7fdcdba76633.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/exec/page-af8c3020cb520f15.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/field/page-72eda67af9f5e35c.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/healthz/route-e772b4710df5d936.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/inside/page-67a6620d31f0a46f.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/intake/page-f059363aa0880ec2.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/layout-f9f917d6a57f69fb.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/live/page-d3ae55eee2f0826c.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/live-run/{page-83d27757e2b8060a.js → page-0e3d7b9421b79dac.js} +1 -1
  147. package/apps/pwa/out/_next/static/chunks/app/loops/page-ba738f7e233eb211.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/market/page-33438b98c74fd599.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-0b34d5fd990d793a.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/morning/page-0f291d3c8fd55a3a.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/not-found-3fced192be5279c1.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/observatory/page-04cb3cf182a7c1ea.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6ccbd2ab23a21542.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-aa0518c48a5f4e56.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4b32226d341ad7d7.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3224fd8f6383b61f.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/page-efbc97459f2914e2.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2fe487d88cd5d97c.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-48861dd1a858bab7.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/sessions/page-197d5d4d21d228ea.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a763ba89fbdd9c27.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/settings/page-7edb253510b1c136.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0c875702c61965ea.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/setup/layout-e772b4710df5d936.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/setup/page-e425c951151095f7.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/share/page-9c90e0aec4e27f77.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/showroom/page-733e09a02e727d42.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/tasks/page-4f899e14c34d77a1.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/term/{page-139d722de1dcd6c1.js → page-bf067887b3307423.js} +1 -1
  170. package/apps/pwa/out/_next/static/chunks/app/today/page-7af10868ff87d04e.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/trace/page-efe5304057aa11c7.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/vault/page-76bcd29aaa8a26c3.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-4cfd88e2273ce50f.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/app/workflows/page-0a1ddb47efba0a32.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/app/workspace/page-2a176c707152c892.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-efe03031b8797fbf.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/{409c787b.e48c5bec8ec10456.js → b450776b.3db34d8d965f82d3.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/{ca3702f8.2913182e73889fa2.js → e8543907.5b040a5f22a0b0e5.js} +7 -7
  179. package/apps/pwa/out/_next/static/chunks/framework-d0d2d673bfd8a8a9.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-4c9fceb2baa09cb7.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/main-app-b0ab8d8fc9a97556.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_app-7e2cc62a2e5cec96.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/pages/_error-22324935f753ec5e.js +1 -0
  184. package/apps/pwa/out/_next/static/chunks/webpack-9dc1bfa25334998a.js +1 -0
  185. package/apps/pwa/out/_next/static/css/{b9d8151e48998417.css → 62c858ad53854f47.css} +1 -1
  186. package/apps/pwa/out/approvals/index.html +1 -1
  187. package/apps/pwa/out/approvals/index.txt +22 -22
  188. package/apps/pwa/out/autopilot/index.html +1 -1
  189. package/apps/pwa/out/autopilot/index.txt +22 -22
  190. package/apps/pwa/out/board/index.html +1 -1
  191. package/apps/pwa/out/board/index.txt +22 -22
  192. package/apps/pwa/out/botlab/index.html +1 -1
  193. package/apps/pwa/out/botlab/index.txt +21 -21
  194. package/apps/pwa/out/bots/index.html +1 -1
  195. package/apps/pwa/out/bots/index.txt +21 -21
  196. package/apps/pwa/out/ceo/index.html +1 -1
  197. package/apps/pwa/out/ceo/index.txt +22 -22
  198. package/apps/pwa/out/chat/index.html +1 -1
  199. package/apps/pwa/out/chat/index.txt +21 -21
  200. package/apps/pwa/out/consult/index.html +1 -1
  201. package/apps/pwa/out/consult/index.txt +22 -22
  202. package/apps/pwa/out/control/index.html +1 -1
  203. package/apps/pwa/out/control/index.txt +22 -22
  204. package/apps/pwa/out/decisions/index.html +1 -1
  205. package/apps/pwa/out/decisions/index.txt +21 -21
  206. package/apps/pwa/out/design-check/index.html +1 -1
  207. package/apps/pwa/out/design-check/index.txt +22 -22
  208. package/apps/pwa/out/editor/index.html +1 -1
  209. package/apps/pwa/out/editor/index.txt +23 -24
  210. package/apps/pwa/out/exec/index.html +1 -1
  211. package/apps/pwa/out/exec/index.txt +22 -22
  212. package/apps/pwa/out/field/index.html +1 -1
  213. package/apps/pwa/out/field/index.txt +22 -22
  214. package/apps/pwa/out/healthz +1 -1
  215. package/apps/pwa/out/index.html +1 -1
  216. package/apps/pwa/out/index.txt +21 -21
  217. package/apps/pwa/out/inside/index.html +1 -1
  218. package/apps/pwa/out/inside/index.txt +22 -22
  219. package/apps/pwa/out/intake/index.html +1 -1
  220. package/apps/pwa/out/intake/index.txt +22 -22
  221. package/apps/pwa/out/live/index.html +1 -1
  222. package/apps/pwa/out/live/index.txt +23 -24
  223. package/apps/pwa/out/live-run/index.html +1 -1
  224. package/apps/pwa/out/live-run/index.txt +23 -24
  225. package/apps/pwa/out/loops/index.html +1 -1
  226. package/apps/pwa/out/loops/index.txt +21 -21
  227. package/apps/pwa/out/market/index.html +1 -1
  228. package/apps/pwa/out/market/index.txt +21 -21
  229. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  230. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  231. package/apps/pwa/out/morning/index.html +1 -1
  232. package/apps/pwa/out/morning/index.txt +22 -22
  233. package/apps/pwa/out/observatory/index.html +1 -1
  234. package/apps/pwa/out/observatory/index.txt +22 -22
  235. package/apps/pwa/out/ops/checklist/index.html +1 -1
  236. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  237. package/apps/pwa/out/ops/release/index.html +1 -1
  238. package/apps/pwa/out/ops/release/index.txt +21 -21
  239. package/apps/pwa/out/ops/seats/index.html +1 -1
  240. package/apps/pwa/out/ops/seats/index.txt +21 -21
  241. package/apps/pwa/out/outputs/index.html +1 -1
  242. package/apps/pwa/out/outputs/index.txt +21 -21
  243. package/apps/pwa/out/reflection/index.html +1 -1
  244. package/apps/pwa/out/reflection/index.txt +22 -22
  245. package/apps/pwa/out/scheduler/index.html +1 -1
  246. package/apps/pwa/out/scheduler/index.txt +22 -22
  247. package/apps/pwa/out/sessions/index.html +1 -1
  248. package/apps/pwa/out/sessions/index.txt +21 -21
  249. package/apps/pwa/out/settings/devices/index.html +1 -1
  250. package/apps/pwa/out/settings/devices/index.txt +22 -22
  251. package/apps/pwa/out/settings/index.html +1 -1
  252. package/apps/pwa/out/settings/index.txt +22 -22
  253. package/apps/pwa/out/setup/done/index.html +1 -1
  254. package/apps/pwa/out/setup/done/index.txt +22 -22
  255. package/apps/pwa/out/setup/index.html +1 -1
  256. package/apps/pwa/out/setup/index.txt +22 -22
  257. package/apps/pwa/out/share/index.html +1 -1
  258. package/apps/pwa/out/share/index.txt +22 -22
  259. package/apps/pwa/out/showroom/index.html +1 -1
  260. package/apps/pwa/out/showroom/index.txt +21 -21
  261. package/apps/pwa/out/tasks/index.html +1 -1
  262. package/apps/pwa/out/tasks/index.txt +22 -22
  263. package/apps/pwa/out/term/index.html +1 -1
  264. package/apps/pwa/out/term/index.txt +22 -22
  265. package/apps/pwa/out/today/index.html +1 -1
  266. package/apps/pwa/out/today/index.txt +22 -22
  267. package/apps/pwa/out/trace/index.html +1 -1
  268. package/apps/pwa/out/trace/index.txt +22 -22
  269. package/apps/pwa/out/vault/index.html +1 -1
  270. package/apps/pwa/out/vault/index.txt +22 -22
  271. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  272. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  273. package/apps/pwa/out/workflows/index.html +1 -1
  274. package/apps/pwa/out/workflows/index.txt +22 -22
  275. package/apps/pwa/out/workspace/index.html +1 -1
  276. package/apps/pwa/out/workspace/index.txt +22 -22
  277. package/apps/pwa/out/worktrees/index.html +1 -1
  278. package/apps/pwa/out/worktrees/index.txt +22 -22
  279. package/bin/elanous.mjs +6 -1
  280. package/catalog/models/openai/gpt-6.1-sol.yaml +16 -0
  281. package/catalog/models/openai/gpt-6.1-terra.yaml +16 -0
  282. package/docs/goal-context/04-mock-scenarios.md +13 -0
  283. package/graphs/catalog/catalog.yaml +1 -1
  284. package/graphs/demo/persona-teacher/lesson-pack.yaml +16 -0
  285. package/graphs/demo/persona-teacher/recipes.yaml +17 -0
  286. package/graphs/demo/persona-teacher/weekly-lesson.yaml +36 -0
  287. package/graphs/heal/heal-loop.yaml +1 -0
  288. package/graphs/overlays/stop-heal-ladder.yaml +136 -2
  289. package/graphs/release/release-loop.yaml +3 -1
  290. package/graphs/units/gate/gate.yaml +20 -0
  291. package/graphs/units/git/git.yaml +26 -0
  292. package/graphs/units/implement/implement.yaml +19 -0
  293. package/graphs/units/landing/landing.yaml +18 -0
  294. package/graphs/units/review/review.yaml +20 -0
  295. package/graphs/units/verbs/recipes.yaml +13 -10
  296. package/graphs/units/verbs/research.yaml +20 -0
  297. package/graphs/work/research-report.yaml +21 -3
  298. package/package.json +1 -1
  299. package/scripts/disk-steward.ts +46 -0
  300. package/scripts/fleet/node-setup.sh +50 -0
  301. package/scripts/graph-units/verbs/research.ts +55 -0
  302. package/scripts/heal/run-role.ts +99 -5
  303. package/scripts/land-global-checks.ts +6 -1
  304. package/scripts/lib/decompose-ab.ts +1 -0
  305. package/scripts/lib/fixtures/tui-regress/help-insufficient-commands.txt +15 -0
  306. package/scripts/lib/fixtures/tui-regress/help-live.txt +42 -0
  307. package/scripts/lib/fixtures/tui-regress/help-missing-keys.txt +21 -0
  308. package/scripts/lib/fixtures/tui-regress/help-original.txt +51 -0
  309. package/scripts/lib/fixtures/tui-regress/help-shifted-input.txt +26 -0
  310. package/scripts/lib/tui-regress-checks.ts +33 -13
  311. package/scripts/llm-cost-ledger.ts +179 -8
  312. package/scripts/measure-nl-routing-corpus.ts +10 -2
  313. package/scripts/persona-teacher/weekly-lesson-node.ts +172 -0
  314. package/scripts/public-copy-lint.ts +163 -19
  315. package/scripts/ratchets/train-side-invariants.sh +0 -1
  316. package/scripts/release-loop/gate-autoheal.ts +117 -0
  317. package/scripts/release-loop/gate-baseline-receipt.ts +55 -10
  318. package/scripts/release-loop/gate-diff.ts +22 -3
  319. package/scripts/release-loop/gate-image-pin.ts +81 -0
  320. package/scripts/release-loop/gate-node-sim.ts +207 -0
  321. package/scripts/release-loop/gate-node.ts +489 -62
  322. package/scripts/release-loop/gate-pod-image-sticky-plan.ts +99 -0
  323. package/scripts/release-loop/gate-radius-live.ts +97 -13
  324. package/scripts/release-loop/gate-shard-dispatch.ts +43 -0
  325. package/scripts/release-loop/gate-shard-load-flaky.ts +256 -0
  326. package/scripts/release-loop/gate-train-receipts.ts +122 -0
  327. package/scripts/release-loop/gate-triage-node.ts +70 -10
  328. package/scripts/release-loop/resume-release.ts +330 -23
  329. package/scripts/release-loop/traffic-node.ts +6 -3
  330. package/scripts/release-loop/unattended-release.ts +4 -2
  331. package/scripts/shadow-authoring-probe.ts +20 -0
  332. package/scripts/ux-sim.ts +37 -3
  333. package/scripts/warm-pool-provider-config.ts +263 -0
  334. package/skills/omni-crawl/SKILL.md +5 -2
  335. package/skills/omni-crawl/scripts/main.ts +84 -23
  336. package/src/acp/core-turn-bridge.ts +99 -4
  337. package/src/agent/registry.ts +2 -0
  338. package/src/agent/task-notification.ts +25 -5
  339. package/src/agent/types.ts +6 -0
  340. package/src/agent-mission/mission-cli.ts +24 -0
  341. package/src/agent-mission/mission-out.ts +595 -0
  342. package/src/agent-mission/tool-install.ts +88 -2
  343. package/src/agent-substrate/context-strategy.ts +4 -4
  344. package/src/agent-substrate/self-review-cli.ts +267 -40
  345. package/src/auto-research/research-turn.ts +133 -51
  346. package/src/autopilot/discovery/wiki-claim-proposer.ts +22 -1
  347. package/src/autopilot/pr-manager.ts +38 -7
  348. package/src/autopilot/pty-control-loop.ts +2 -0
  349. package/src/boot/daemon-tools/self-implement.ts +46 -9
  350. package/src/budget/shadow-arms.ts +52 -0
  351. package/src/capture/tui-self-report.ts +22 -6
  352. package/src/chat/index.ts +1 -1
  353. package/src/chat/pickers/state.ts +7 -1
  354. package/src/cli/fixtures/review-loop-breaker/opwaiver-32646-1694ccc7a170.json +1 -0
  355. package/src/cli/fixtures/review-loop-breaker/opwaiver-32853-bd8f73595c83.json +1 -0
  356. package/src/cli/fixtures/review-loop-breaker/opwaiver-33097-1cc85900413c.json +1 -0
  357. package/src/cli/fixtures/review-loop-breaker/opwaiver-33106-972f31e4a3ca.json +1 -0
  358. package/src/cli/fixtures/review-loop-breaker/opwaiver-33113-3ab51f05968f.json +1 -0
  359. package/src/cli/fixtures/review-loop-breaker/pr-33097-1cc85900413c.json +1 -0
  360. package/src/cli/log-event-names.ts +5 -0
  361. package/src/cli/mcp-login.ts +8 -18
  362. package/src/cli/msg-cli.ts +57 -1
  363. package/src/cli/pr-land-heavy-remote.ts +47 -9
  364. package/src/cli/pr-land-overlap-evidence.ts +100 -1
  365. package/src/cli/pr-land-pod-shadow-job.ts +60 -0
  366. package/src/cli/release-checklist-read-cli.ts +20 -10
  367. package/src/cli/release-cli.ts +27 -1
  368. package/src/cli/research-cli.ts +4 -5
  369. package/src/cli/sim-cli.ts +7 -1
  370. package/src/cli/tasks-cli.ts +12 -4
  371. package/src/codex/models.ts +30 -15
  372. package/src/compact/auto.ts +8 -1
  373. package/src/control-plane/ledger.ts +52 -2
  374. package/src/control-plane/server.ts +16 -2
  375. package/src/core-turn/run-core-turn.ts +313 -89
  376. package/src/core-turn/run-goal-loop.ts +106 -2
  377. package/src/core-turn/types.ts +2 -0
  378. package/src/dashboard/acp-boot.ts +72 -3
  379. package/src/dashboard/classic-sidetab-mission-job.ts +58 -0
  380. package/src/dashboard/classic-sidetab-mission.ts +185 -0
  381. package/src/dashboard/index.ts +155 -15
  382. package/src/dashboard/input/agent-wake.ts +23 -1
  383. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +9 -0
  384. package/src/dashboard/mission-cli-consumer.ts +153 -0
  385. package/src/dashboard/seat-boot-preamble.ts +171 -1
  386. package/src/dashboard/side-basic-runtime.ts +54 -1
  387. package/src/dashboard/sidetab-runtime.ts +90 -1
  388. package/src/dashboard/skill-catalog-preamble.ts +101 -0
  389. package/src/dashboard/skill-detection-runtime.ts +55 -15
  390. package/src/dashboard/slash-runtime/dashboard-handlers.ts +15 -0
  391. package/src/dashboard/turn-preamble.ts +65 -16
  392. package/src/dashboard/turn-prompt-runtime.ts +4 -2
  393. package/src/disk-steward/judge.ts +73 -0
  394. package/src/disk-steward/ledger.ts +122 -0
  395. package/src/disk-steward/steward.ts +373 -0
  396. package/src/domains/guardian-tick.ts +191 -2
  397. package/src/graph-runner/graph-cli.ts +44 -7
  398. package/src/graph-runner/graph-tick.ts +10 -2
  399. package/src/graph-runner/in-process-registry.ts +37 -0
  400. package/src/graph-runner/runner.ts +34 -4
  401. package/src/grok/agent-search.ts +14 -4
  402. package/src/grok/credential.ts +28 -11
  403. package/src/grounding/ref-index.ts +19 -0
  404. package/src/grounding/sources-cli.ts +9 -1
  405. package/src/harness/harness-cli-command.ts +267 -14
  406. package/src/harness/harness-incidents.ts +312 -7
  407. package/src/harness/harness-pod-dispatch.ts +81 -15
  408. package/src/harness/harness-space.ts +15 -1
  409. package/src/harness/harness-stop.ts +155 -11
  410. package/src/harness/progress-worker-entry.ts +59 -0
  411. package/src/harness/progress-worker-runtime.ts +11 -0
  412. package/src/index.ts +52 -7
  413. package/src/instance/dev-project.ts +25 -0
  414. package/src/instance/spawn-elanous.ts +6 -4
  415. package/src/intelligence-map/model-alias.ts +6 -5
  416. package/src/intelligence-map/model-catalog.ts +59 -2
  417. package/src/llm/model-defaults.ts +4 -4
  418. package/src/llm.ts +208 -19
  419. package/src/loops/orchestrator/coordinator-shadow.ts +226 -0
  420. package/src/loops/orchestrator/tick.ts +61 -0
  421. package/src/maturity/feature-maturity.ts +1 -1
  422. package/src/mcp/mcp-oauth.ts +3 -1
  423. package/src/model-tier/llm-tier-map.ts +9 -9
  424. package/src/model-tier/turn-tier.ts +1 -1
  425. package/src/msg/msg-mirror-github.ts +80 -0
  426. package/src/msg/msg-mirror-policy.ts +61 -0
  427. package/src/msg/msg-mirror-runner.ts +219 -0
  428. package/src/msg/msg-mirror-state.ts +33 -0
  429. package/src/msg/msg-store.ts +11 -0
  430. package/src/native-tool-catalog.ts +2 -2
  431. package/src/nexus/api/harness-traversal.ts +11 -0
  432. package/src/output-truncation.ts +41 -12
  433. package/src/pr-tool/census.ts +3 -2
  434. package/src/project/project-store.ts +48 -1
  435. package/src/pty-shell/tui-run-state.ts +188 -2
  436. package/src/release-loop/checklist-target-path-hint.ts +13 -0
  437. package/src/release-loop/checklist.ts +9 -1
  438. package/src/release-loop/gate-host-reservation.ts +144 -0
  439. package/src/release-loop/release-schedule.ts +90 -1
  440. package/src/repl/index.ts +43 -2
  441. package/src/research/axis-fanout.ts +121 -16
  442. package/src/research/bloom-exemplars.ts +137 -0
  443. package/src/research/gap-followup.ts +13 -1
  444. package/src/research/plugin-discovery.ts +36 -14
  445. package/src/research-bridge/invoke.ts +22 -5
  446. package/src/research-bridge/types.ts +2 -0
  447. package/src/self-dev/ask-launch-flow.ts +39 -25
  448. package/src/self-dev/decompose.ts +119 -5
  449. package/src/self-dev/dev-cli.ts +17 -17
  450. package/src/self-dev/graph-front-nodes.ts +23 -0
  451. package/src/self-dev/launch-preflight-text.ts +5 -6
  452. package/src/self-dev/launch-preflight.ts +9 -4
  453. package/src/self-dev/orchestrate.ts +27 -2
  454. package/src/self-dev/review-provider-fallback.ts +9 -2
  455. package/src/self-dev/run-supervisor.ts +226 -6
  456. package/src/self-dev/run-types.ts +7 -0
  457. package/src/self-implement/doctor-visit.ts +88 -0
  458. package/src/self-implement/gate-artifacts.ts +13 -0
  459. package/src/self-implement/gate-cli.ts +54 -24
  460. package/src/self-implement/gate-remote.ts +23 -5
  461. package/src/self-implement/goal-author-clarification.ts +31 -12
  462. package/src/self-implement/goal-author.ts +403 -8
  463. package/src/self-implement/graph-overlay-yaml.ts +7 -0
  464. package/src/self-implement/graph-stage-units.ts +172 -0
  465. package/src/self-implement/graph-templates.ts +162 -1
  466. package/src/self-implement/graph-variant.ts +37 -4
  467. package/src/self-implement/headless-elanous-driver.ts +31 -2
  468. package/src/self-implement/heal-intake.ts +112 -4
  469. package/src/self-implement/heal-triage.ts +20 -0
  470. package/src/self-implement/host-regate.ts +31 -8
  471. package/src/self-implement/knowhow-pack.ts +38 -0
  472. package/src/self-implement/merge-train.ts +5 -0
  473. package/src/self-implement/orchestrator.ts +359 -30
  474. package/src/self-implement/regate-detail.ts +38 -1
  475. package/src/self-implement/rework-child-provider.ts +25 -0
  476. package/src/self-implement/run-chart.ts +119 -0
  477. package/src/self-implement/run-ledger.ts +176 -17
  478. package/src/self-implement/run-stop.ts +208 -5
  479. package/src/self-implement/running-runs.ts +35 -12
  480. package/src/self-implement/self-implement-cli.ts +36 -4
  481. package/src/self-implement/stop-autoheal-operational.ts +43 -0
  482. package/src/self-implement/stop-autoheal.ts +28 -6
  483. package/src/session/chat.ts +69 -58
  484. package/src/session/request-size-guard.ts +123 -0
  485. package/src/session-runtime/index.ts +98 -4
  486. package/src/session-runtime/tier-flip.ts +3 -3
  487. package/src/sidetab-core/model.ts +150 -0
  488. package/src/sidetab-core/visible-agent-mission.ts +186 -0
  489. package/src/skills/name-match.ts +20 -0
  490. package/src/skills/tools/agent.ts +30 -2
  491. package/src/skills/tools/omni-search.ts +67 -5
  492. package/src/task-agent/parent-host.ts +14 -1
  493. package/src/task-agent/pod-distributor-entry.ts +3 -0
  494. package/src/task-agent/task-hand.ts +31 -1
  495. package/src/task-orchestrator/surfaces/pod-distributor.ts +48 -0
  496. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +43 -0
  497. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +38 -1
  498. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +29 -4
  499. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +33 -6
  500. package/src/task-orchestrator/surfaces/pod-source-bundle.ts +45 -9
  501. package/src/task-orchestrator/surfaces/pod-source-receive.ts +163 -13
  502. package/src/task-orchestrator/surfaces/pod-source-spec.ts +3 -3
  503. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +209 -39
  504. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +80 -3
  505. package/src/task-orchestrator/surfaces/self-implement-pod.ts +280 -60
  506. package/src/task-orchestrator/surfaces/self-implement.ts +18 -0
  507. package/src/tokens.ts +35 -2
  508. package/src/tool-runtime/agent-runtime.ts +1 -0
  509. package/src/tool-runtime/elanous-skills-list-runtime.ts +5 -1
  510. package/src/tool-runtime/skill-exec-runtime.ts +33 -13
  511. package/src/tool-runtime/types.ts +1 -0
  512. package/src/tui/entry.ts +24 -7
  513. package/src/tui/sidetab/attach.ts +47 -0
  514. package/src/tui/sidetab/list.ts +45 -0
  515. package/src/tui/sidetab/nl-tool.ts +2 -136
  516. package/src/tui/sidetab/peek.ts +52 -0
  517. package/src/tui-client/dashboard-session.ts +3 -0
  518. package/src/tui-client/local-chat-turn.ts +26 -13
  519. package/src/tui.ts +22 -0
  520. package/src/user-config.ts +11 -5
  521. package/src/ux-sim/fake-kubectl.ts +37 -3
  522. package/src/ux-sim/fault-needs-human-reason-repair.ts +107 -0
  523. package/src/ux-sim/fault-pod-child-result.ts +42 -0
  524. package/src/ux-sim/fault-pool-cap.ts +11 -6
  525. package/src/ux-sim/mock-scenario-catalog.json +41 -0
  526. package/src/ux-sim/mock-scenario-catalog.ts +156 -0
  527. package/src/ux-sim/release-sim-rig.ts +262 -0
  528. package/src/ux-sim/scenario.ts +116 -23
  529. package/src/ux-sim/seminar-rehearsal.ts +109 -0
  530. package/src/ux-sim/subagent-tools-device.ts +2 -2
  531. package/src/version/packed-revision.json +1 -1
  532. package/src/voice/voice-tts-singleton.ts +18 -3
  533. package/src/web-search/grok.ts +5 -9
  534. package/apps/pwa/out/_next/static/chunks/1060.014f1f01a17aec26.js +0 -115
  535. package/apps/pwa/out/_next/static/chunks/1415.79821ec7ae99acdb.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/1452.162bb2d9d699e82a.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/147.f92f63bbc5e85fa5.js +0 -286
  538. package/apps/pwa/out/_next/static/chunks/1661.fb425a1d8a065b72.js +0 -149
  539. package/apps/pwa/out/_next/static/chunks/1671-1c22b40b50b208f2.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/1758.0204d3f48783c49d.js +0 -90
  541. package/apps/pwa/out/_next/static/chunks/1806.027bf78b6a94d340.js +0 -104
  542. package/apps/pwa/out/_next/static/chunks/2047.8f23e210995d4548.js +0 -2
  543. package/apps/pwa/out/_next/static/chunks/2061-7f2bbc53ae96c88b.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/2066.a77257c8c350770a.js +0 -23
  545. package/apps/pwa/out/_next/static/chunks/2096-a938496bc996dcbd.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/2200-9a453b8f99687d49.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/2281-b8cede695c6c650e.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/2499.02fbfd18126c10c0.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/2522.f2766b76d22c8bdf.js +0 -34
  550. package/apps/pwa/out/_next/static/chunks/2615.3c9738153de3ef3f.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/2727.e703d99ac414916d.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/2752.7904b8df0254d0ae.js +0 -27
  553. package/apps/pwa/out/_next/static/chunks/2762-5051a862dfa40e99.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/2767-31784bfedf8e245d.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/2774-719820e3f5b2a3eb.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/2812-f016aa0dda149287.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/2829-734fe8bf2eee7347.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/311-32dcac79970985e8.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/3175-f93f7495cd28253c.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/3184.8da993f5502d2140.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/3231-d7c981db0ff8bdcc.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/3250.151309c5176d6b4b.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/3517.a5aa1797a9dbf2ee.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/3567-45f676877ed9e8a5.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/3819.8a1de79b2e8c7298.js +0 -24
  566. package/apps/pwa/out/_next/static/chunks/39.9b37b0be4c128a83.js +0 -77
  567. package/apps/pwa/out/_next/static/chunks/4023.a19045970a9ce16a.js +0 -36
  568. package/apps/pwa/out/_next/static/chunks/413-24c8284bda08241d.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/4135.e45d6ebc29e20647.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/4283.65502f5d0e6ff6c0.js +0 -287
  571. package/apps/pwa/out/_next/static/chunks/4305-4e28fa92a7b34a5b.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/4335-50efa61fd7613142.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/4720.ecbd1693fa151068.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/483.725e4a61be922788.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/4969-4b209d7307410c00.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/5068-c7f53862f83c0917.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/5315.bc96711c24dfefe2.js +0 -74
  578. package/apps/pwa/out/_next/static/chunks/5542.efbf14f16baed4dd.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/5622.94893f5aea7185d0.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/5644.8f401a25601d05fc.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/5658.35f70eb9871a54bf.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/5721.7bdc0e904c76ab51.js +0 -8
  583. package/apps/pwa/out/_next/static/chunks/5790-eef0ca20884a6bdf.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/5802.ef0d8598ca68fe84.js +0 -62
  585. package/apps/pwa/out/_next/static/chunks/5890.fb974729788dcb71.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/5924.5ef25cddd36d5dbf.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/5979-e59c099ebf8d1f35.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/6020.714cfeada2315e2e.js +0 -94
  589. package/apps/pwa/out/_next/static/chunks/6027-dfe0349d8c50f698.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/6178.bc4730c86cf74536.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/6273.d808b0dcb3c2b155.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/6292.6ef1df64fa6a4c8a.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/647-af8dd920ba46533c.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/6541-170dc5c59e135c0c.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/6624.981ef7caeb680560.js +0 -32
  596. package/apps/pwa/out/_next/static/chunks/6742-a1ad4a94ba7bc37a.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/6836-493dc55c39187949.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/6856-53ac421c06039a18.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/6908.06008c67f6380ea9.js +0 -148
  600. package/apps/pwa/out/_next/static/chunks/6915.096931864206f522.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/6925.5e181fb7dcf90193.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/6cc1d1d6.9a98dd4622f1afc6.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/7203-800e11037adc41eb.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/7279.6170f591105936bb.js +0 -93
  605. package/apps/pwa/out/_next/static/chunks/7349-373165c7fbdcc3df.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/7514-a533ba0ca1cae4f4.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/7515.1ad6efe157fa4448.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/7521.d919cc1fab80c1d9.js +0 -24
  609. package/apps/pwa/out/_next/static/chunks/7538.90e97bbdf9178cff.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/7825-39203196a12579b2.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/7869.5e1a9a12fd70d6c7.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/8086.1ab9103c41be884f.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/8179-e61fffbdb70f1152.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/8265.bdeb991b34db6a06.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/8357.1aaa713b052a78b1.js +0 -309
  616. package/apps/pwa/out/_next/static/chunks/8638-e42615f2166165b5.js +0 -1
  617. package/apps/pwa/out/_next/static/chunks/8639-92c11d069792429e.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/8691.54e22831d5e8ccf8.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/9069.657590a84afb8fac.js +0 -41
  620. package/apps/pwa/out/_next/static/chunks/9125-ae588d88a0293b93.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/9311.f9f641a46a508611.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/9371-a6fee8378ebfa3ee.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/9421-3aa9ff4fa7f63d8a.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/9992.07ce73c10bd5e6a1.js +0 -79
  625. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76394dc618d322c8.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/app/approvals/page-1b948637c37b3abd.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-c63400f1bcf3e47c.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/app/board/page-95d0957267819586.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/app/botlab/page-ba957ff875a026a0.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/app/bots/page-bb6fd0714879cb87.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/app/ceo/page-8f9038520d2acbef.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/app/chat/page-d4b48397e05fce2c.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/app/consult/page-72d5744245dc0c27.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/app/control/page-37625dc8300fa43a.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/app/decisions/page-fbef9d160272dbc1.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/app/design-check/page-58424168df84928e.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/app/editor/page-72c12ba430ac57c0.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/app/exec/page-d53f3e9ed806d7e0.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/app/field/page-4d2fbd45feee0829.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/app/healthz/route-76394dc618d322c8.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/app/inside/page-8783dc0ed7590a2c.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/app/intake/page-3706cb390606e930.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/app/layout-9b0a86598e0111fd.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/app/live/page-4edb8df90f4537ce.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/app/loops/page-47398b9ba1cc5e1b.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/app/market/page-fb86f55cfe2e681d.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e22345fc8fd47b1b.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/app/morning/page-fca2e59a81744d9e.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/not-found-6e96bda63100b31e.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/observatory/page-4d17ad8e0db8cea4.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-121f92766c33beaa.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-43f14212c545f92d.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ccec2023e7a974ec.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/outputs/page-b04f33f548b89a94.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/page-c8792823c0917021.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/reflection/page-8c0e32782ceef4cb.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-94bd3922eb230ce8.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/sessions/page-bca565887bafa03c.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ac1dffafe649fc6c.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/settings/page-52374edb5e23e455.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ad4ebca120d43ca7.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/setup/layout-76394dc618d322c8.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/setup/page-718b89ce4b4ae4e4.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/share/page-204eca33eeeaddec.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/showroom/page-e58ba9bcdb9ac0f9.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/tasks/page-98f6dd50bafd7734.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/today/page-5a4bdd72bff27057.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/trace/page-6f6ab17d44f984ce.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/vault/page-aabb7bd15fb72da9.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-e4322319164a4436.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/workflows/page-e9efc0c8f32e2371.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/workspace/page-ccde99f07aaf71f7.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-80464aced9614390.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/c696986b.5dc8bb1143af16d1.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/d5d3cefc-373c4eb722ed848b.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/d8de0de2-dd0f4ac8e5ab1832.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/framework-002b472a66935d31.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/main-49b88d47292c0476.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/main-app-fff2549cb10a133f.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/pages/_app-32abbbba3f3b76b7.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/pages/_error-9d9cfef60c60dd7a.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/webpack-cc7f483fa294034a.js +0 -1
  683. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +0 -1
  684. package/scripts/ratchets/next-tui-entry-budget.ts +0 -124
  685. /package/apps/pwa/out/_next/static/{HjeK7zONHfR7op1hKXp4k → X1ucLw10Cds_h614NoEnh}/_ssgManifest.js +0 -0
@@ -3,7 +3,8 @@ import { invokeResearchAxes } from '../research-bridge/index.js';
3
3
  import { invokeResearch } from '../research-bridge/invoke.js';
4
4
  import type { AxisFanoutResult } from '../research/axis-fanout.js';
5
5
  import { routeResearchOutput } from '../research/output-router.js';
6
- import { runGapFollowup } from '../research/gap-followup.js';
6
+ import { planGapFollowup, runGapFollowup } from '../research/gap-followup.js';
7
+ import type { ResearchGapFollowupInput, ResearchGapFollowupPlan } from '../research/gap-followup.js';
7
8
  import { debug, redactSecretText } from '../debug/log.js';
8
9
  import {
9
10
  buildWorkingBackwardsContractPrompt,
@@ -16,13 +17,18 @@ import { attachResearchEvidence, buildResearchQuestionLadderPrompt,
16
17
  type SixLevelResearchQuestionLadder } from './question-ladder-contract.js';
17
18
 
18
19
  export interface ResearchQuestionLadderRunOptions {
19
- generateContract?: (prompt: string) => Promise<string>;
20
- generate?: (prompt: string) => Promise<string>;
21
- invokeAxes?: (questions: SixLevelResearchQuestionLadder['questions']) => Promise<AxisFanoutResult>;
20
+ signal?: AbortSignal;
21
+ generateContract?: (prompt: string, signal?: AbortSignal) => Promise<string>;
22
+ generate?: (prompt: string, signal?: AbortSignal) => Promise<string>;
23
+ invokeAxes?: (questions: SixLevelResearchQuestionLadder['questions'], signal?: AbortSignal) => Promise<AxisFanoutResult>;
22
24
  routeOutput?: typeof routeResearchOutput;
23
- invokeOutputSkill?: (skill: string, args: string) => Promise<{ ok: boolean; output: string; error?: string }>;
25
+ invokeOutputSkill?: (skill: string, args: string, signal?: AbortSignal) => Promise<{ ok: boolean; output: string; error?: string }>;
24
26
  /** Test seam for the bounded Bloom 4/5 evidence-gap follow-up. */
25
27
  gapFollowup?: typeof runGapFollowup;
28
+ /** Test seam for deciding whether production gap-follow-up has any runnable calls. */
29
+ planGapFollowup?: (input: ResearchGapFollowupInput) => ResearchGapFollowupPlan;
30
+ /** Test/config seam for an explicitly installed private Bloom exemplar pack. */
31
+ bloomExemplarPackPath?: string;
26
32
  }
27
33
 
28
34
  export interface ResearchGroundingResult {
@@ -203,9 +209,10 @@ export async function runResearchQuestionLadder(
203
209
  const initial: SixLevelResearchQuestionLadder = { request, questions: [], evidence: [] };
204
210
  let contractRaw: string;
205
211
  try {
206
- contractRaw = await (options.generateContract ?? ((prompt) => defaultGenerate(prompt, 'research-working-backwards-contract')))(
207
- buildWorkingBackwardsContractPrompt(request),
212
+ contractRaw = await (options.generateContract ?? ((prompt, signal) => defaultGenerate(prompt, 'research-working-backwards-contract', signal)))(
213
+ buildWorkingBackwardsContractPrompt(request), options.signal,
208
214
  );
215
+ if (options.signal?.aborted) return { ok: false, ladder: initial, output: '', error: 'research aborted' };
209
216
  } catch (error) {
210
217
  const reason = errorText(error);
211
218
  debug.log('research.lens', 'working-backwards-contract-failed', { reason }, { level: 'warn' });
@@ -238,9 +245,18 @@ export async function runResearchQuestionLadder(
238
245
  let raw: string;
239
246
  try {
240
247
  const sectionIds = outputContract.sections.map((section) => section.id);
241
- raw = await (options.generate ?? ((prompt) => defaultGenerate(prompt, 'research-question-ladder')))(
242
- `${buildResearchQuestionLadderPrompt(request, sectionIds)}\n\n${ladderContext}${retroGroundingContext(request)}`,
248
+ // Keep the premium exemplar bank outside the TUI's static import closure.
249
+ const { getBloomExemplarContext } = await import('../research/bloom-exemplars.js');
250
+ const exemplar = getBloomExemplarContext(request, options.bloomExemplarPackPath);
251
+ debug.log('research.turn', 'bloom-exemplars-selected', {
252
+ domain: exemplar.domain, domainSignal: exemplar.domainSignal,
253
+ source: exemplar.source, count: exemplar.count, levels: exemplar.levels,
254
+ });
255
+ raw = await (options.generate ?? ((prompt, signal) => defaultGenerate(prompt, 'research-question-ladder', signal)))(
256
+ `${buildResearchQuestionLadderPrompt(request, sectionIds)}\n\n${exemplar.context ? `${exemplar.context}\n\n` : ''}${ladderContext}${retroGroundingContext(request)}`,
257
+ options.signal,
243
258
  );
259
+ if (options.signal?.aborted) return { ok: false, ladder: initial, outputContract, output: '', error: 'research aborted' };
244
260
  debug.log('research.turn', 'bloom-generated', { questionCount: 6 });
245
261
  } catch (error) {
246
262
  debug.log('research.turn', 'bloom-failed', { reason: errorText(error) }, { level: 'warn' });
@@ -267,7 +283,8 @@ export async function runResearchQuestionLadder(
267
283
  const observedAt = new Date().toISOString();
268
284
  let fanout: AxisFanoutResult;
269
285
  try {
270
- fanout = await (options.invokeAxes ?? invokeResearchAxes)(ladder.questions);
286
+ fanout = await (options.invokeAxes ?? ((questions, signal) => invokeResearchAxes(questions, { signal })))(ladder.questions, options.signal);
287
+ if (options.signal?.aborted) return { ok: false, ladder, outputContract, output: '', error: 'research aborted' };
271
288
  debug.log('research.turn', 'axis-evidence-collected', {
272
289
  axisCount: fanout.axes.length,
273
290
  evidenceCount: fanout.axes.reduce((count, axis) => count + axis.evidence.length, 0),
@@ -318,47 +335,92 @@ export async function runResearchQuestionLadder(
318
335
  stage: 'axis-fanout', reason: 'every output-contract section slot is filled',
319
336
  });
320
337
  }
321
- if (!finalBoundary.complete) {
322
- try {
323
- const followup = await (options.gapFollowup ?? runGapFollowup)({
324
- request,
325
- questions: ladder.questions,
326
- evidence: ladder.evidence,
327
- });
328
- const followupLines = [
329
- '## Bounded research gap follow-up',
330
- `Rounds: ${followup.rounds} · budget: ${followup.timeBudgetMs}ms`,
331
- ...followup.classifications.map((item) => `- ${item.questionId} [${item.action}/${item.reason}]${item.skill ? ` · ${item.skill}` : ''}: ${item.gap}`),
332
- ];
333
- for (const envelope of followup.followupEvidence) {
334
- const attached = attachResearchEvidence(ladder, envelope);
335
- if (!attached.ok) {
336
- evidenceRejected = true;
337
- followupLines.push(`- Evidence rejected: ${attached.reason}`);
338
- continue;
339
- }
340
- ladder.evidence = attached.value.evidence;
341
- followupLines.push(`- [${envelope.outcome}] ${envelope.sourceKind} · ${envelope.source}: ${envelope.content}`);
338
+ if (!finalBoundary.complete && !options.signal?.aborted) {
339
+ const followupStartedAt = performance.now();
340
+ const followupInput: ResearchGapFollowupInput = {
341
+ request,
342
+ questions: ladder.questions,
343
+ evidence: ladder.evidence,
344
+ ...(options.signal ? { signal: options.signal } : {}),
345
+ };
346
+ let followupPlan: ResearchGapFollowupPlan | undefined;
347
+ if (options.planGapFollowup || !options.gapFollowup) {
348
+ try {
349
+ followupPlan = (options.planGapFollowup ?? planGapFollowup)(followupInput);
350
+ debug.log('research.turn', 'gap-followup-planned', {
351
+ rounds: followupPlan.rounds,
352
+ classifications: followupPlan.classifications.length,
353
+ calls: followupPlan.followups.length,
354
+ elapsedMs: Math.round((performance.now() - followupStartedAt) * 10) / 10,
355
+ });
356
+ } catch (error) {
357
+ debug.log('research.turn', 'gap-followup-plan-failed', {
358
+ reason: errorText(error),
359
+ elapsedMs: Math.round((performance.now() - followupStartedAt) * 10) / 10,
360
+ }, { level: 'warn' });
361
+ }
362
+ }
363
+ if (followupPlan && followupPlan.followups.length === 0) {
364
+ if (followupPlan.classifications.length > 0) {
365
+ sections.push(
366
+ '## Bounded research gap follow-up',
367
+ `Rounds: ${followupPlan.rounds} · budget: ${followupPlan.timeBudgetMs}ms`,
368
+ ...followupPlan.classifications.map((item) => `- ${item.questionId} [${item.action}/${item.reason}]${item.skill ? ` · ${item.skill}` : ''}: ${item.gap}`),
369
+ );
342
370
  }
343
- for (const card of followup.discoveryCards ?? []) followupLines.push(card);
344
- if (followup.classifications.length || followup.followupEvidence.length) sections.push(...followupLines);
345
- debug.log('research.turn', 'gap-followup-completed', {
346
- rounds: followup.rounds,
347
- classifications: followup.classifications.length,
348
- evidenceCount: followup.followupEvidence.length,
349
- evidenceAttached: ladder.evidence.length,
371
+ debug.log('research.turn', 'gap-followup-skipped', {
372
+ reason: 'no-runnable-followup-calls',
373
+ classifications: followupPlan.classifications.length,
374
+ timeBudgetMs: followupPlan.timeBudgetMs,
350
375
  });
351
- finalBoundary = planWorkingBackwardsCompletion(outputContract, ladder.questions, ladder.evidence);
352
- logCompletionBoundary('gap-followup', finalBoundary);
353
- if (finalBoundary.complete) {
354
- debug.log('research.turn', 'completion-boundary-stop', {
355
- stage: 'gap-followup', reason: 'every output-contract section slot is filled',
376
+ } else {
377
+ const executionStartedAt = performance.now();
378
+ debug.log('research.turn', 'gap-followup-started', {
379
+ evidenceCount: ladder.evidence.length,
380
+ completeEvidenceCount: ladder.evidence.filter((item) => item.outcome === 'complete').length,
381
+ });
382
+ try {
383
+ const followup = await (options.gapFollowup ?? runGapFollowup)(followupInput);
384
+ const followupLines = [
385
+ '## Bounded research gap follow-up',
386
+ `Rounds: ${followup.rounds} · budget: ${followup.timeBudgetMs}ms`,
387
+ ...followup.classifications.map((item) => `- ${item.questionId} [${item.action}/${item.reason}]${item.skill ? ` · ${item.skill}` : ''}: ${item.gap}`),
388
+ ];
389
+ for (const envelope of followup.followupEvidence) {
390
+ const attached = attachResearchEvidence(ladder, envelope);
391
+ if (!attached.ok) {
392
+ evidenceRejected = true;
393
+ followupLines.push(`- Evidence rejected: ${attached.reason}`);
394
+ continue;
395
+ }
396
+ ladder.evidence = attached.value.evidence;
397
+ followupLines.push(`- [${envelope.outcome}] ${envelope.sourceKind} · ${envelope.source}: ${envelope.content}`);
398
+ }
399
+ for (const card of followup.discoveryCards ?? []) followupLines.push(card);
400
+ if (followup.classifications.length || followup.followupEvidence.length) sections.push(...followupLines);
401
+ debug.log('research.turn', 'gap-followup-completed', {
402
+ rounds: followup.rounds,
403
+ classifications: followup.classifications.length,
404
+ evidenceCount: followup.followupEvidence.length,
405
+ evidenceAttached: ladder.evidence.length,
406
+ elapsedMs: Math.round((performance.now() - executionStartedAt) * 10) / 10,
356
407
  });
408
+ finalBoundary = planWorkingBackwardsCompletion(outputContract, ladder.questions, ladder.evidence);
409
+ logCompletionBoundary('gap-followup', finalBoundary);
410
+ if (finalBoundary.complete) {
411
+ debug.log('research.turn', 'completion-boundary-stop', {
412
+ stage: 'gap-followup', reason: 'every output-contract section slot is filled',
413
+ });
414
+ }
415
+ } catch (error) {
416
+ debug.log('research.turn', 'gap-followup-failed', {
417
+ reason: errorText(error),
418
+ elapsedMs: Math.round((performance.now() - executionStartedAt) * 10) / 10,
419
+ }, { level: 'warn' });
357
420
  }
358
- } catch (error) {
359
- debug.log('research.turn', 'gap-followup-failed', { reason: errorText(error) }, { level: 'warn' });
360
421
  }
361
422
  }
423
+ if (options.signal?.aborted) return { ok: false, ladder, outputContract, output: '', error: 'research aborted' };
362
424
 
363
425
  const outputContractSectionIndex = sections.findIndex((section) => section.startsWith('## Output contract\n'));
364
426
  if (outputContractSectionIndex < 0) throw new Error('output contract section is missing from research output');
@@ -396,24 +458,43 @@ export async function runResearchQuestionLadder(
396
458
  fallbackReason: route?.fallbackReason ?? (route ? undefined : 'router-failed'),
397
459
  });
398
460
  let routedOutput = '';
399
- if (route?.skillCallPlan) {
461
+ const hasCompleteEvidence = ladder.evidence.some((item) => item.outcome === 'complete');
462
+ if (route?.skillCallPlan && !hasCompleteEvidence) {
463
+ debug.log('research.turn', 'output-skill-skipped', {
464
+ skill: route.skillCallPlan.skill,
465
+ reason: 'no-complete-evidence',
466
+ evidenceCount: ladder.evidence.length,
467
+ });
468
+ } else if (route?.skillCallPlan) {
469
+ const outputSkillStartedAt = performance.now();
470
+ debug.log('research.turn', 'output-skill-started', {
471
+ skill: route.skillCallPlan.skill,
472
+ evidenceCount: ladder.evidence.length,
473
+ completeEvidenceCount: ladder.evidence.filter((item) => item.outcome === 'complete').length,
474
+ });
400
475
  try {
401
476
  const formatted = await (options.invokeOutputSkill ?? defaultInvokeOutputSkill)(
402
- route.skillCallPlan.skill, route.skillCallPlan.args,
477
+ route.skillCallPlan.skill, route.skillCallPlan.args, options.signal,
403
478
  );
404
479
  if (formatted.ok && formatted.output.trim()) {
405
480
  routedOutput = `\n\n## Routed ${route.format} output (${route.skillCallPlan.skill})\n\n${formatted.output.trim()}`;
406
- debug.log('research.turn', 'output-skill-completed', { skill: route.skillCallPlan.skill, outputChars: formatted.output.length });
481
+ debug.log('research.turn', 'output-skill-completed', {
482
+ skill: route.skillCallPlan.skill,
483
+ outputChars: formatted.output.length,
484
+ elapsedMs: Math.round((performance.now() - outputSkillStartedAt) * 10) / 10,
485
+ });
407
486
  } else {
408
487
  debug.log('research.turn', 'output-skill-fallback', {
409
488
  skill: route.skillCallPlan.skill,
410
489
  reason: formatted.error ?? 'empty output',
490
+ elapsedMs: Math.round((performance.now() - outputSkillStartedAt) * 10) / 10,
411
491
  }, { level: 'warn' });
412
492
  }
413
493
  } catch (error) {
414
494
  debug.log('research.turn', 'output-skill-fallback', {
415
495
  skill: route.skillCallPlan.skill,
416
496
  reason: errorText(error),
497
+ elapsedMs: Math.round((performance.now() - outputSkillStartedAt) * 10) / 10,
417
498
  }, { level: 'warn' });
418
499
  }
419
500
  }
@@ -427,8 +508,8 @@ export async function runResearchQuestionLadder(
427
508
  };
428
509
  }
429
510
 
430
- async function defaultInvokeOutputSkill(skill: string, args: string) {
431
- const result = await invokeResearch(args, { skill });
511
+ async function defaultInvokeOutputSkill(skill: string, args: string, signal?: AbortSignal) {
512
+ const result = await invokeResearch(args, { skill, signal });
432
513
  return { ok: result.ok, output: result.output, ...(result.error ? { error: result.error } : {}) };
433
514
  }
434
515
 
@@ -442,10 +523,11 @@ export function researchTurnForGrounding(result: ResearchQuestionLadderRunResult
442
523
  };
443
524
  }
444
525
 
445
- async function defaultGenerate(prompt: string, usageSite: string): Promise<string> {
526
+ async function defaultGenerate(prompt: string, usageSite: string, signal?: AbortSignal): Promise<string> {
446
527
  return streamLLM([{ role: 'user', content: prompt }], () => {}, {
447
528
  usageSite,
448
529
  usagePhase: 'research',
530
+ ...(signal ? { signal } : {}),
449
531
  });
450
532
  }
451
533
 
@@ -2,7 +2,8 @@
2
2
  //
3
3
  // 구 핸드오프의 생존 지식을 **문서 전체 요약이 아닌 claim 단위**로 추출해, 기존 하이브리드 검색으로
4
4
  // 대상 WIKI-* living 페이지를 골라 doc-curate 큐에 제안한다. 핵심 규율(미션 불변식):
5
- // · 각 claim proposal 에 원문 구절·출처 경로·마지막 검증 시점(provenance) 필수.
5
+ // · 각 claim proposal 에 원문 구절·출처 경로·마지막 검증 시점(provenance) 필수 — 하나라도 없으면
6
+ // 제안이 성립하지 않는다(rejected 관측): 어떤 페이지에도 자동 쓰기·고치기·링크 제안을 남기지 않는다.
6
7
  // · 기존 claim 과 충돌하면 **덮어쓰지 않고** 병렬 근거 + contradiction 플래그(비파괴).
7
8
  // · 출력은 doc-curate CurationProposal(큐) 로만 — 자동 이동·병합·archive 없음(HITL 승인 게이트).
8
9
  // · 깨진 판정을 LLM 에 안 맡김(결정론 추출·검색/충돌만 주입). 새 큐/파서 안 만들고 재사용.
@@ -49,6 +50,7 @@ export function extractClaims(text: string, sourcePath: string, nowDate: string)
49
50
  }
50
51
 
51
52
  const WIKI_CLAIM_DISCARD_REASON = 'no-matching-wiki-page' as const;
53
+ const WIKI_CLAIM_REJECT_REASON = 'missing-provenance' as const;
52
54
 
53
55
  export interface WikiClaimStatistics {
54
56
  receivedClaims: number;
@@ -58,6 +60,12 @@ export interface WikiClaimStatistics {
58
60
  reason: typeof WIKI_CLAIM_DISCARD_REASON;
59
61
  sourcePaths: string[];
60
62
  };
63
+ /** 가산 관측(근거 필수 불변식 시행) — provenance 없어 명시적 거부된 claim. 0건이면 기존 계약 보존을 위해 필드를 싣지 않는다. */
64
+ rejected?: {
65
+ reason: typeof WIKI_CLAIM_REJECT_REASON;
66
+ claims: number;
67
+ sourcePaths: string[];
68
+ };
61
69
  }
62
70
 
63
71
  export type WikiClaimItems = CurationItem[] & { statistics: WikiClaimStatistics };
@@ -85,12 +93,22 @@ export function defaultDetectConflict(claim: Claim, existing: string): boolean {
85
93
  return hit >= 2 && neg;
86
94
  }
87
95
 
96
+ /** 근거(provenance 3요소 — 원문 구절·출처 경로·마지막 검증 시점)가 온전한가. 하나라도 비면 제안이 성립하지 않는다. */
97
+ function hasCompleteProvenance(claim: Claim): boolean {
98
+ return claim.sourceQuote.trim() !== '' && claim.sourcePath.trim() !== '' && claim.lastVerified.trim() !== '';
99
+ }
100
+
88
101
  /** claim → CurationItem (add/update · provenance · 충돌 시 contradiction 플래그·비파괴 diff). 순수+주입. */
89
102
  export function proposeWikiClaimItems(claims: readonly Claim[], deps: WikiClaimDeps): WikiClaimItems {
90
103
  const detect = deps.detectConflict ?? defaultDetectConflict;
91
104
  const items = [] as unknown as WikiClaimItems;
92
105
  const discardedSourcePaths: string[] = [];
106
+ const rejectedSourcePaths: string[] = [];
93
107
  for (const c of claims) {
108
+ if (!hasCompleteProvenance(c)) {
109
+ rejectedSourcePaths.push(c.sourcePath);
110
+ continue; // 근거 필수 불변식 — provenance 없는 claim 은 쓰기·고치기·링크 제안으로 성립하지 않는다.
111
+ }
94
112
  const page = deps.findWikiPage(c);
95
113
  if (!page) {
96
114
  discardedSourcePaths.push(c.sourcePath);
@@ -121,6 +139,9 @@ export function proposeWikiClaimItems(claims: readonly Claim[], deps: WikiClaimD
121
139
  proposedItems: items.length,
122
140
  discardedClaims: discardedSourcePaths.length,
123
141
  discarded: { reason: WIKI_CLAIM_DISCARD_REASON, sourcePaths: discardedSourcePaths },
142
+ ...(rejectedSourcePaths.length > 0
143
+ ? { rejected: { reason: WIKI_CLAIM_REJECT_REASON, claims: rejectedSourcePaths.length, sourcePaths: rejectedSourcePaths } }
144
+ : {}),
124
145
  };
125
146
  Object.defineProperty(items, 'statistics', { value: statistics, enumerable: false });
126
147
  try {
@@ -488,12 +488,15 @@ function editExistingPr(run: CmdRunner, input: UpsertPrInput, url: string): Upse
488
488
  /** Same-card rework may have a new run branch. Merge the bound PR head into that work,
489
489
  * then update the bound branch with a plain fast-forward push. Every identity read is
490
490
  * checked again after the inventory snapshot; an ambiguous or moved PR stays refused. */
491
- function reuseSameCellPr(run: CmdRunner, input: UpsertPrInput, target: NonNullable<GuardVerdict['sameCellReuse']>, recheck: () => GuardVerdict): UpsertPrOutcome {
491
+ function reuseSameCellPr(run: CmdRunner, input: UpsertPrInput, target: NonNullable<GuardVerdict['sameCellReuse']>,
492
+ initialInventory: GuardVerdict, recheck: () => GuardVerdict): UpsertPrOutcome {
492
493
  const cwd = input.worktreePath;
493
494
  const pushEvidence = { ref: `refs/heads/${target.branch}`, remoteHead: target.headSha, cardId: target.cardId };
494
- const fail = (detail: string): UpsertPrOutcome => {
495
+ const fail = (detail: string, inventoryEvidence?: { inventoryBefore: unknown; inventoryAfter: unknown; inventoryDiff: unknown }): UpsertPrOutcome => {
495
496
  const safeDetail = sanitizeCredentialText(detail).slice(0, 300);
496
- debug.log('autopilot.pr-manager', 'same-cell-push-decision', { ...pushEvidence, outcome: 'refused', reason: safeDetail }, { level: 'warn' });
497
+ debug.log('autopilot.pr-manager', 'same-cell-push-decision', {
498
+ ...pushEvidence, outcome: 'refused', reason: safeDetail, ...inventoryEvidence,
499
+ }, { level: 'warn' });
497
500
  return { ok: false, reason: 'guard', detail: `same-cell reuse: ${safeDetail}` };
498
501
  };
499
502
  if (!/^[0-9a-f]{40}$/i.test(target.headSha) || !Number.isSafeInteger(target.number) || target.number < 1
@@ -617,11 +620,39 @@ function reuseSameCellPr(run: CmdRunner, input: UpsertPrInput, target: NonNullab
617
620
  || finalPr.url !== pr.url) return fail('PR changed before push');
618
621
  const finalRemote = run('git', ['-C', cwd, 'ls-remote', '--exit-code', 'origin', remoteRef]);
619
622
  if (!finalRemote.ok || finalRemote.out.trim() !== `${target.headSha}\t${remoteRef}`) return fail('remote head changed before push');
620
- const latest = recheck().sameCellReuse;
623
+ const latestInventory = recheck();
624
+ const latest = latestInventory.sameCellReuse;
621
625
  if (!latest || latest.number !== target.number || latest.branch !== target.branch
622
626
  || latest.headSha !== target.headSha || latest.cellId !== target.cellId
623
- || latest.cardId !== target.cardId || Boolean(latest.legacyBound) !== Boolean(target.legacyBound))
624
- return fail('OPEN PR inventory changed before push');
627
+ || latest.cardId !== target.cardId || Boolean(latest.legacyBound) !== Boolean(target.legacyBound)) {
628
+ const snapshot = (verdict: GuardVerdict) => ({
629
+ conflicts: [...(verdict.sameCellConflicts ?? [])].map((row) => ({ pr: row.pr,
630
+ branch: row.branch === null ? null : sanitizeCredentialText(row.branch).slice(0, 180),
631
+ headSha: /^[0-9a-f]{40}$/i.test(row.headSha) ? row.headSha.toLowerCase() : 'invalid',
632
+ cardId: row.cardId === null ? null : sanitizeCredentialText(row.cardId).slice(0, 128), slice: row.slice ?? null,
633
+ })).sort((a, b) => a.pr - b.pr),
634
+ reusable: verdict.sameCellReuse ? { number: verdict.sameCellReuse.number,
635
+ branch: sanitizeCredentialText(verdict.sameCellReuse.branch).slice(0, 180),
636
+ headSha: /^[0-9a-f]{40}$/i.test(verdict.sameCellReuse.headSha) ? verdict.sameCellReuse.headSha.toLowerCase() : 'invalid',
637
+ cellId: sanitizeCredentialText(verdict.sameCellReuse.cellId).slice(0, 128),
638
+ cardId: sanitizeCredentialText(verdict.sameCellReuse.cardId).slice(0, 128),
639
+ legacyBound: Boolean(verdict.sameCellReuse.legacyBound) } : null,
640
+ });
641
+ const before = snapshot(initialInventory);
642
+ const after = snapshot(latestInventory);
643
+ const beforeByPr = new Map(before.conflicts.map((row) => [row.pr, row]));
644
+ const afterByPr = new Map(after.conflicts.map((row) => [row.pr, row]));
645
+ const inventoryDiff = {
646
+ added: after.conflicts.filter((row) => !beforeByPr.has(row.pr)),
647
+ removed: before.conflicts.filter((row) => !afterByPr.has(row.pr)),
648
+ changed: after.conflicts.flatMap((row) => {
649
+ const old = beforeByPr.get(row.pr);
650
+ return old && JSON.stringify(old) !== JSON.stringify(row) ? [{ pr: row.pr, before: old, after: row }] : [];
651
+ }),
652
+ reusableChanged: JSON.stringify(before.reusable) !== JSON.stringify(after.reusable),
653
+ };
654
+ return fail('OPEN PR inventory changed before push', { inventoryBefore: before, inventoryAfter: after, inventoryDiff });
655
+ }
625
656
  // The result descends from the exact fetched head. The explicit lease binds the
626
657
  // remote update to that head, so a delete or move between reads cannot be revived.
627
658
  // The Pod hook receives these values for this one push only. It checks the Pod card,
@@ -857,7 +888,7 @@ export function makePrManager(
857
888
  };
858
889
  const earlyVerdict = earlyGuard ? siblingSliceAllowed(earlyGuard) : undefined;
859
890
  const freshGuard = () => checkCreate!({ cwd, base: comparisonBase, seat: input.seat ?? seatFromEnvironment(), body: input.body }, run);
860
- if (earlyVerdict?.sameCellReuse) return reuseSameCellPr(run, input, earlyVerdict.sameCellReuse, freshGuard);
891
+ if (earlyVerdict?.sameCellReuse) return reuseSameCellPr(run, input, earlyVerdict.sameCellReuse, earlyVerdict, freshGuard);
861
892
  if (earlyVerdict?.status === 'refuse') return { ok: false, reason: 'guard', detail: sameCellGuardDetail(earlyVerdict, candidateCardId) };
862
893
  const earlyInventoryUnknown = !!candidateCardId && (!checkCreate || (earlyVerdict?.status === 'unknown'
863
894
  && earlyVerdict.reasons.length === 1 && earlyVerdict.reasons[0]?.code === 'inventory-unknown'));
@@ -73,6 +73,8 @@ export interface ControlObservation {
73
73
  readonly subjectPtyId?: string;
74
74
  /** 이 판단이 속한 harness run. harness 밖 감독자는 생략한다. */
75
75
  readonly runId?: string;
76
+ /** Recent same-run chart cells pulled immediately before this supervision judgment. */
77
+ readonly runChart?: readonly { device: string; stopKey: string; observed: string; verdict: string; action: string; handoff: string | null; why: string }[];
76
78
  /** Last structured action that could not be performed; brain sees the reason next round. */
77
79
  readonly unavailableAction?: string;
78
80
  }
@@ -13,9 +13,9 @@
13
13
  // - onProgress ← ux.progress (각 스테이지 진행을 서피스로).
14
14
  // - 큰 gate log → ux.spillFile (파일 첨부).
15
15
 
16
- import { basename, join } from 'node:path';
16
+ import { basename, isAbsolute, join, relative, resolve, sep } from 'node:path';
17
17
  import { createHash, randomUUID } from 'node:crypto';
18
- import { existsSync, linkSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
18
+ import { existsSync, linkSync, mkdirSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from 'node:fs';
19
19
  import type { LLMToolSpec } from '../../llm.js';
20
20
  import { childLifetimeSignal } from '../../turn-abort-scope.js';
21
21
  import { buildSelfImplementSpec } from '../../self-implement/self-implement-runtime.js';
@@ -48,7 +48,13 @@ export function resolveDispatchEntry(ctx: DaemonToolDispatchCtx): import('../../
48
48
 
49
49
  /** 데몬 서피스용 스펙 — 내부 툴과 단일 출처(buildSelfImplementSpec) 공유. */
50
50
  export function buildSelfImplementDaemonSpec(): LLMToolSpec {
51
- return buildSelfImplementSpec();
51
+ const spec = buildSelfImplementSpec();
52
+ const properties = spec.parameters.properties as Record<string, Record<string, unknown>>;
53
+ properties.goalFile = {
54
+ type: 'string',
55
+ description: '기존 SelfImplement 골 문서를 재개할 때만 지정한다. 문서에 결정을 반영한 뒤 같은 골을 다시 실행하며, 저장소 내부 GOAL-* 문서 경로만 허용된다.',
56
+ };
57
+ return spec;
52
58
  }
53
59
 
54
60
  // ⭐ 판정은 `../../self-implement/observe-only.js` **한 자리**가 한다 — 이 스위치를 타는 경로가
@@ -90,7 +96,7 @@ const END_STAGES: readonly SelfImplementProgressStage[] = ['pr-opened', 'aborted
90
96
  export type SelfImplementLaunchedToolResult = SelfImplementResult & { runId: string; kind: 'launched'; message: string; next: string; missing: string[] };
91
97
  export type SelfImplementPendingToolResult = Partial<SelfImplementResult> & { kind: 'pending'; message: string; next: string; missing: string[] };
92
98
  export type SelfImplementObservedOnlyToolResult = { kind: 'observed-only'; observed: true; message: string; next: string; missing: ['runId', 'node'] };
93
- export type SelfImplementFailedToolResult = Partial<SelfImplementResult> & { kind: 'failed'; reason: string; message: string; next: string; missing: string[] };
99
+ export type SelfImplementFailedToolResult = Partial<SelfImplementResult> & { kind: 'failed'; reason: string; message: string; next: string; missing: string[]; goalFile?: string };
94
100
  export type SelfImplementToolResult = SelfImplementLaunchedToolResult | SelfImplementPendingToolResult | SelfImplementObservedOnlyToolResult | SelfImplementFailedToolResult;
95
101
 
96
102
  /** 하니스가 런을 맡았다 — 파일 편집은 하니스 몫이므로 모델의 직접 Write/Edit 을 문면으로 막는다. */
@@ -220,6 +226,7 @@ const GOAL_ORIGINAL_TEXT_LIMIT = null;
220
226
 
221
227
  type GoalAuthorSummary = {
222
228
  authored: boolean;
229
+ reused: boolean;
223
230
  goalFile: string | null;
224
231
  userTextState: 'absent' | 'empty' | 'present';
225
232
  originalChars: number | null;
@@ -231,10 +238,23 @@ type GoalAuthorSummary = {
231
238
  function emitGoalAuthorSummary(ux: SurfaceUx, summary: GoalAuthorSummary): void {
232
239
  const message = summary.authored
233
240
  ? `goal-author authored ${basename(summary.goalFile!)} (${summary.userTextState}; ${summary.storedChars} chars; truncated=${summary.truncated})`
234
- : `goal-author not authored (${summary.userTextState}; no goal source)`;
241
+ : summary.reused
242
+ ? `goal-author resumed ${basename(summary.goalFile!)} (${summary.userTextState})`
243
+ : `goal-author not authored (${summary.userTextState}; no goal source)`;
235
244
  ux.progress(message, { phase: 'delta' });
236
245
  }
237
246
 
247
+ function resolveResumableGoalFile(requestedPath: string, cwd: string): string {
248
+ const root = realpathSync(cwd);
249
+ const candidate = realpathSync(isAbsolute(requestedPath) ? requestedPath : resolve(root, requestedPath));
250
+ const relativePath = relative(root, candidate);
251
+ if (!relativePath || relativePath === '..' || relativePath.startsWith(`..${sep}`) || isAbsolute(relativePath)
252
+ || !/^GOAL-[^/\\]+\.(?:md|txt)$/i.test(basename(candidate))) {
253
+ throw new Error('goalFile must point to an existing GOAL-*.md or GOAL-*.txt document inside the repository');
254
+ }
255
+ return candidate;
256
+ }
257
+
238
258
  /** Observability only; tool selection remains model-led. */
239
259
  function harnessMentionState(userText: string | undefined): 'absent' | 'matched' | 'not-matched' {
240
260
  if (userText === undefined) return 'absent';
@@ -293,7 +313,18 @@ export async function dispatchSelfImplement(
293
313
  }
294
314
 
295
315
  let goalFile: string | undefined;
296
- if (goalSourceText !== undefined) {
316
+ let resumedGoal = false;
317
+ if (args.goalFile !== undefined) {
318
+ if (typeof args.goalFile !== 'string' || !args.goalFile.trim()) {
319
+ return buildFailedToolResult('goalFile must be a non-empty path to an existing authored goal document');
320
+ }
321
+ try {
322
+ goalFile = resolveResumableGoalFile(args.goalFile, ctx.cwd);
323
+ resumedGoal = true;
324
+ } catch (error) {
325
+ return buildFailedToolResult(error instanceof Error ? error.message : String(error));
326
+ }
327
+ } else if (goalSourceText !== undefined) {
297
328
  const recentStepCounts = readRecentStepCountsFailOpen(recentStepCountReader);
298
329
  goalFile = (await authorGoal(goalSourceText, ctx.cwd, {
299
330
  goalTitle: feature,
@@ -334,7 +365,7 @@ export async function dispatchSelfImplement(
334
365
  if (clarification.decisionRequired.length > 0) {
335
366
  const ledger = decisionLedgerFactory?.() ?? new DecisionLedger();
336
367
  const decisions = clarification.decisionRequired.map((item) => {
337
- const ref = `self-implement-clarification:${args.runId ?? goalFile}:${item.questionId}`;
368
+ const ref = `self-implement-clarification:${goalFile}:${item.questionId}`;
338
369
  return ledger.raiseOnce({
339
370
  title: `SelfImplement 확인 필요: ${item.header}`.slice(0, 120),
340
371
  category: item.category,
@@ -360,7 +391,12 @@ export async function dispatchSelfImplement(
360
391
  unanswered: clarification.decisionRequired.length,
361
392
  reason: 'safety-critical-clarification-requires-recorded-decision',
362
393
  });
363
- return buildFailedToolResult(`goal author clarification requires a recorded decision before launch; record the answer in the goal document and rerun SelfImplement (${decisions.map((decision) => decision.id).join(', ')})`);
394
+ const reason = `goal author clarification requires a recorded decision before launch (${decisions.map((decision) => decision.id).join(', ')})`;
395
+ const next = `Edit ${goalFile} with the explicit answer, then rerun SelfImplement using the same feature and goalFile=${goalFile}; the decision card alone does not launch or resume work`;
396
+ return {
397
+ kind: 'failed', reason, goalFile, next, missing: ['runId', 'node'],
398
+ message: `SelfImplement did not launch: ${reason}. Record the answer in ${goalFile}, then rerun the same feature with goalFile=${goalFile}. A decision-card choice alone does not resume the run.`,
399
+ };
364
400
  }
365
401
  if (clarification.unanswered > 0) {
366
402
  debug.log('daemon-tools.self-implement', 'goal-clarification-assumption-incomplete', {
@@ -372,7 +408,8 @@ export async function dispatchSelfImplement(
372
408
  }
373
409
  }
374
410
  const goalAuthorSummary: GoalAuthorSummary = {
375
- authored: goalFile !== undefined,
411
+ authored: goalFile !== undefined && !resumedGoal,
412
+ reused: resumedGoal,
376
413
  goalFile: goalFile ?? null,
377
414
  userTextState: originalUserText === undefined ? 'absent' : originalUserText === '' ? 'empty' : 'present',
378
415
  originalChars,
@@ -75,3 +75,55 @@ export function planShadowArms(input: PlanShadowArmsInput): ShadowArmsPlan {
75
75
 
76
76
  return { fire, skipped, remainingUsd };
77
77
  }
78
+
79
+ // ── SHADOW-MODEL-ARMS · 그림자 «1팔» probe(명시 실행 · 관측만) ─────────────────────
80
+ /**
81
+ * ⭐ 그림자 1팔 probe — `planShadowArms` 를 일일 상한 안에서 «실제 호출»해
82
+ * 난이도·모델·예상/실제 비용·결과를 기록한다.
83
+ * ⛔ 관측만 한다 — 라이브 LLM 호출 0 · 파일 원장 쓰기 0. 팔은 «계획»이고 실행은 후속 조각이다.
84
+ * ⛔ 후보가 여러 개여도 첫 후보 «1팔»만 계획한다(저작 단계 팔은 단일 팔이다).
85
+ */
86
+ export interface ShadowArmProbeRecord {
87
+ stage: ShadowStage;
88
+ difficulty: ShadowDifficulty;
89
+ model: string;
90
+ result: 'fire' | 'skipped';
91
+ skipReason: 'over-daily-cap' | 'unknown-price' | null;
92
+ expectedUsd: number | null;
93
+ actualUsd: number;
94
+ remainingUsd: number;
95
+ }
96
+
97
+ /** 그림자 1팔을 실제 호출해 기록을 낸다 — 실제 지출은 없다(계획만, actualUsd=0). */
98
+ export function probeShadowArm(input: PlanShadowArmsInput): ShadowArmProbeRecord {
99
+ const model = input.candidates[0] ?? '';
100
+ const plan = planShadowArms({ ...input, candidates: [model] });
101
+ const fired = plan.fire[0];
102
+ const skipped = plan.skipped[0];
103
+ return {
104
+ stage: input.stage,
105
+ difficulty: input.difficulty,
106
+ model,
107
+ result: fired ? 'fire' : 'skipped',
108
+ skipReason: skipped?.reason ?? null,
109
+ expectedUsd: fired?.estUsd ?? null,
110
+ actualUsd: 0,
111
+ remainingUsd: plan.remainingUsd,
112
+ };
113
+ }
114
+
115
+ /** 한 줄 원장 형식 — 예상 비용이 없으면 `expectedUsd=unknown`, fire 사유는 `under-daily-cap` 이다. */
116
+ export function formatShadowArmProbeRecord(record: ShadowArmProbeRecord): string {
117
+ const reason = record.skipReason ?? 'under-daily-cap';
118
+ const expectedUsd = record.expectedUsd === null ? 'unknown' : `${record.expectedUsd}`;
119
+ return [
120
+ `shadow-arm stage=${record.stage}`,
121
+ `difficulty=${record.difficulty}`,
122
+ `model=${record.model}`,
123
+ `result=${record.result}`,
124
+ `reason=${reason}`,
125
+ `expectedUsd=${expectedUsd}`,
126
+ `actualUsd=${record.actualUsd}`,
127
+ `remainingUsd=${record.remainingUsd}`,
128
+ ].join(' ');
129
+ }