elanous 0.2.35 → 0.2.36

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 (686) 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/chunks/{d06f9160.a3d9062f95de8ad7.js → 053a429e.9a63436527cc751c.js} +1 -1
  4. package/apps/pwa/out/_next/static/chunks/109.f196abf3484bb97f.js +287 -0
  5. package/apps/pwa/out/_next/static/chunks/{4346.8601952e73bf5803.js → 1201.afbfc5b1c5e5cbe4.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/1517.9275b89572098ff3.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1574.ad11f8db8396ab45.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1614.7a8c5c40aee0261f.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/1871-f1eb29d8dbb4065b.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/190.285c832bd9626f8c.js +64 -0
  11. package/apps/pwa/out/_next/static/chunks/2193.0ea24c4a7aa1d004.js +36 -0
  12. package/apps/pwa/out/_next/static/chunks/223-ad865c1e80491d78.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/2265-f0d90b6dbec05f81.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/2267.eb4a62a209f09ec4.js +149 -0
  15. package/apps/pwa/out/_next/static/chunks/2341-86cd06c0cf01aa33.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/2352.9abc42422bade876.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/2397-c1653a816061842d.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{3103.0df8da390948bb84.js → 2500.cbc1257b774aae52.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/{7644.17e37ba6f1d4226e.js → 2683.c9773a0c589b031b.js} +3 -3
  20. package/apps/pwa/out/_next/static/chunks/2709.8e1889034255fc5f.js +24 -0
  21. package/apps/pwa/out/_next/static/chunks/{4718-17d2af636796a330.js → 275-02ea4c2a33980422.js} +3 -3
  22. package/apps/pwa/out/_next/static/chunks/2812ca6a.3b9f4a7a08885744.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/284.ac77c0db55bfd3a8.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/{8714.ff0b7ce3ec3e3ae2.js → 2941.3c3546f96bc6efa7.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/2976.b000698a3c6512dc.js +24 -0
  26. package/apps/pwa/out/_next/static/chunks/{9214.63a510d39178e997.js → 2986.45d7652e4f13557e.js} +2 -2
  27. package/apps/pwa/out/_next/static/chunks/3031-85328a92fcce4da6.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/3136.30aaaa5fa03662a3.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{3677-4215f826f6aa68e5.js → 3148-98efd4869d660a87.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/3155.2587a55196ecb394.js +226 -0
  31. package/apps/pwa/out/_next/static/chunks/3277.785db1cf09f98601.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/3320-f9c77381f85a2c0a.js +1 -0
  33. package/apps/pwa/out/_next/static/chunks/3324.a09703033abcbd2f.js +34 -0
  34. package/apps/pwa/out/_next/static/chunks/3386-91049feabff9a94e.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/339.80afb7e8839372af.js +8 -0
  36. package/apps/pwa/out/_next/static/chunks/3410.7f9af5ab77cbe65f.js +115 -0
  37. package/apps/pwa/out/_next/static/chunks/3538.a445e50bb359d068.js +32 -0
  38. package/apps/pwa/out/_next/static/chunks/3540c645.2595a6af01a97672.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3621.581b2054cc14bee4.js +286 -0
  40. package/apps/pwa/out/_next/static/chunks/3676.8c28d16fd84ca843.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/{9512.5a76207a730e0491.js → 3727.7949ccaacaa71242.js} +2 -2
  42. package/apps/pwa/out/_next/static/chunks/375-b84540853523fe52.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/{8557-e7898769499cd56f.js → 3757-180308bc61021b05.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/379.ee262e37586fe1ae.js +74 -0
  45. package/apps/pwa/out/_next/static/chunks/{359-2250789a2d3499e7.js → 3840-5825d56d46976a92.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/3969-81054381eaec4c4c.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/{da5176c6.6773b6c5994e1d99.js → 3a3d9966.cc4d4585a2708e7c.js} +1 -1
  48. package/apps/pwa/out/_next/static/chunks/4067-bf9aa60547972937.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4116.a84a92a2492c080e.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4176.e5729c93c29151eb.js +104 -0
  51. package/apps/pwa/out/_next/static/chunks/4227-e6c84686bc8946ca.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/{9952.5daf5f94063a2b3e.js → 4286.b70c4520306817e8.js} +1 -1
  53. package/apps/pwa/out/_next/static/chunks/4304.e9b2512834a9e23e.js +23 -0
  54. package/apps/pwa/out/_next/static/chunks/4327.b9e08a71c0009348.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/{938.66ad1ef0e5abae1c.js → 4615.8525eb0add35eba6.js} +1 -1
  56. package/apps/pwa/out/_next/static/chunks/4946.bd106eafd668f248.js +148 -0
  57. package/apps/pwa/out/_next/static/chunks/5085-bce4904931767ca6.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5125.2eb9968b83767193.js +93 -0
  59. package/apps/pwa/out/_next/static/chunks/5128-75b733fd74a9a1eb.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/{6236.e18cced2d5ba6afb.js → 528.38ce20ef8aa251ff.js} +16 -16
  61. package/apps/pwa/out/_next/static/chunks/5489f3fe.4bb1458b09f6dead.js +122 -0
  62. package/apps/pwa/out/_next/static/chunks/{3408.21d1570602f4b6c0.js → 552.b7d061ad91eeac51.js} +2 -2
  63. package/apps/pwa/out/_next/static/chunks/5560-2a4648f6a30f16e7.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5711.957b095705c12560.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/{1530.0e612369b6fd7ea0.js → 575.d929793a53f27c4b.js} +1 -1
  66. package/apps/pwa/out/_next/static/chunks/5772-e29e14f8ff127122.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/5887.5b2f5b44ce0f7e9a.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5899-4c112a2d908cf97f.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/599.c39c571b6733f2a2.js +41 -0
  70. package/apps/pwa/out/_next/static/chunks/6041.1b65efb796ebc2a5.js +79 -0
  71. package/apps/pwa/out/_next/static/chunks/6057-765c0a26028c86b2.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6142.f289e0d039f453a6.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6199-6bcd61d2a3910e04.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/6236.cdf7293e710a9b2d.js +1 -0
  75. package/apps/pwa/out/_next/static/chunks/6387-237e079dac9a3ae6.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6448-b6d272d074276e14.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/6466-92e65a48490b68a9.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/6566.926a1d1b7c911442.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6580-cdc0e4a634ce4708.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/6659-b242dc31b20b3f29.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6690.c5d9b321b1f79384.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/671-e9b6ad0c771c5514.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6862.bcbf89dd0f4496b3.js +27 -0
  84. package/apps/pwa/out/_next/static/chunks/6912-7b375ee48732c767.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/6925.562d532110879886.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/{7385.50a308a477bdfc21.js → 6943.c6b24124853a47b2.js} +1 -1
  87. package/apps/pwa/out/_next/static/chunks/{630.fe5a46428d63b013.js → 727.7deb87749b0a343a.js} +1 -1
  88. package/apps/pwa/out/_next/static/chunks/{2018.a741297bce759490.js → 7481.39f7a4654907bf6e.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/7545.b1aa42cd15503319.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7551-416d298c2dc4a9ab.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/{8444.4c26b379ca2b9596.js → 771.c3cdb6c1f7f47c02.js} +17 -17
  92. package/apps/pwa/out/_next/static/chunks/7784.1f0ac4a16d190cf4.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/7870-309de463786ac1fc.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7888-e29b151bb6a3bb8b.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{3589.5444a06bcf6e775c.js → 7891.03f910124a737985.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/7905-6ba78d9234608f79.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8037.e254fd797aa224d1.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8207.f527886b7c464529.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/856.50bda61439d465e6.js +62 -0
  100. package/apps/pwa/out/_next/static/chunks/{b2f6ba4d.fb56fdbbf798df33.js → 873d6c12.09bd499f57171543.js} +1 -1
  101. package/apps/pwa/out/_next/static/chunks/{5101.e32282718f99ed6f.js → 8904.7d51af2dc033965c.js} +2 -2
  102. package/apps/pwa/out/_next/static/chunks/9031-92e9b487edb681ee.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/9060.5410d9f6a95f6287.js +90 -0
  104. package/apps/pwa/out/_next/static/chunks/{5637.281e5dec4ea6ecf1.js → 914.8abefd48d579547b.js} +2 -2
  105. package/apps/pwa/out/_next/static/chunks/9187-c87a2207d4ac5d46.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/{4705-194e64e47ca0fbdb.js → 9250-072df22eaadaa6b5.js} +1 -1
  107. package/apps/pwa/out/_next/static/chunks/9289.3e92f278821e18e0.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9319.7816d3cc741cd34f.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9327-e016bb9f1674d24f.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/9365.3de48bf75193ff9a.js +77 -0
  111. package/apps/pwa/out/_next/static/chunks/9383.5b5e9aa56b5fea97.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/9387-cb929573ef436f39.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9489.c27becacc3283dec.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/{8637.47f5b35afcae5e6b.js → 9514.131c52cc75fe6439.js} +1 -1
  115. package/apps/pwa/out/_next/static/chunks/9536.28962663c7734376.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/9686-12286f5bbf15a5a0.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9776.289d40cc5a4c342a.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{1674.2a65fd5668e1cc5f.js → 9789.60f723d18097ec30.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/989.f0c17523c5e61f65.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9972-1df393aa8d4f7d52.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9f31e478.fefcbcd3c388ebc5.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-96750aba7430959f.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-4105e5bbbb043024.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-5d4fa75c2acb113e.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-a79a9bdb3b2142bf.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-f1c2047484992a35.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-15ffc49b2d8c70e2.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-67d53a3fc8734135.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-e30c8dc696491336.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-2136e04fa77696e2.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-fecd2814790c2e12.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-280aa4a98fc5bb44.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-c14e96b65fb4b883.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-187dac74825ed6bf.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-6bc7246ea8c92448.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-083747f1d4518f61.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-96750aba7430959f.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-15ca95a16ec96e1f.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-a8ac031b3810eb64.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-8835f93110494cda.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-e2de2e59111c9aad.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-f2b2e4bf6e981450.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-5b92b7f75df20948.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-468eddf2b1a84ecb.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-2af16e62c12f22df.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-18b40867a77a5793.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-fe934f2979f5a4a2.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-3eec435537357170.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-ff88cbfd2aa99fc8.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-a5b39fb780c70ab5.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ae465dde1d1b3933.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-e7abc34a48a6f71e.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-cab9674fde9ead26.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1da49bc8712284d0.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5e8aa657551ac912.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-fcc36f36c6dc1fe2.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-d22db22f2a7296ca.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-d12dc7b1773878f0.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-99debec9ea7fbec0.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-96750aba7430959f.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-2a088a78bad7e924.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-2e8ed57db7e69993.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-4b3a16213c2ae8fe.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f098747ddf38c98b.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-c15958835534404b.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-68279e3c843c1fd7.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-a34a74453367a39d.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-8767a7db2155a5bd.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-bd5976683460d7f2.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-b7364835e7f2ef54.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-311af16b3ee0ffca.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-fb670757274ae990.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{0368f25d-ad84af92fefee68f.js → ccae1c4b-0cf414f5eff1b10d.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/{cbe38a15.5a032598e39970c6.js → ceba0382.650712b56b85b582.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/{b6705a4f-b9a9047de9eecfd0.js → da5ecc5c-b005ad8cac737d57.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{56d372f2.681ab4ec4c998fae.js → f9a61e4d.1fc2c1dbdd49fe46.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/framework-6d497cbf1eef04c6.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-app-012f5edec932f337.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-da5aeb809edc94a2.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-5ee319af6f749dfe.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-4bc84653a718d6c6.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-8a96cf6775c73d6e.js +1 -0
  183. package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → uC-N0emedeNOFuaBQFv-I}/_buildManifest.js +1 -1
  184. package/apps/pwa/out/approvals/index.html +1 -1
  185. package/apps/pwa/out/approvals/index.txt +22 -22
  186. package/apps/pwa/out/autopilot/index.html +1 -1
  187. package/apps/pwa/out/autopilot/index.txt +22 -22
  188. package/apps/pwa/out/board/index.html +1 -1
  189. package/apps/pwa/out/board/index.txt +22 -22
  190. package/apps/pwa/out/botlab/index.html +1 -1
  191. package/apps/pwa/out/botlab/index.txt +21 -21
  192. package/apps/pwa/out/bots/index.html +1 -1
  193. package/apps/pwa/out/bots/index.txt +21 -21
  194. package/apps/pwa/out/ceo/index.html +1 -1
  195. package/apps/pwa/out/ceo/index.txt +22 -22
  196. package/apps/pwa/out/chat/index.html +1 -1
  197. package/apps/pwa/out/chat/index.txt +21 -21
  198. package/apps/pwa/out/consult/index.html +1 -1
  199. package/apps/pwa/out/consult/index.txt +22 -22
  200. package/apps/pwa/out/control/index.html +1 -1
  201. package/apps/pwa/out/control/index.txt +22 -22
  202. package/apps/pwa/out/decisions/index.html +1 -1
  203. package/apps/pwa/out/decisions/index.txt +21 -21
  204. package/apps/pwa/out/design-check/index.html +1 -1
  205. package/apps/pwa/out/design-check/index.txt +22 -22
  206. package/apps/pwa/out/editor/index.html +1 -1
  207. package/apps/pwa/out/editor/index.txt +22 -22
  208. package/apps/pwa/out/exec/index.html +1 -1
  209. package/apps/pwa/out/exec/index.txt +22 -22
  210. package/apps/pwa/out/field/index.html +1 -1
  211. package/apps/pwa/out/field/index.txt +22 -22
  212. package/apps/pwa/out/healthz +1 -1
  213. package/apps/pwa/out/index.html +1 -1
  214. package/apps/pwa/out/index.txt +21 -21
  215. package/apps/pwa/out/inside/index.html +1 -1
  216. package/apps/pwa/out/inside/index.txt +21 -21
  217. package/apps/pwa/out/intake/index.html +1 -1
  218. package/apps/pwa/out/intake/index.txt +22 -22
  219. package/apps/pwa/out/live/index.html +1 -1
  220. package/apps/pwa/out/live/index.txt +22 -22
  221. package/apps/pwa/out/live-run/index.html +1 -1
  222. package/apps/pwa/out/live-run/index.txt +22 -22
  223. package/apps/pwa/out/loops/index.html +1 -1
  224. package/apps/pwa/out/loops/index.txt +21 -21
  225. package/apps/pwa/out/market/index.html +1 -1
  226. package/apps/pwa/out/market/index.txt +21 -21
  227. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  228. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  229. package/apps/pwa/out/morning/index.html +1 -1
  230. package/apps/pwa/out/morning/index.txt +22 -22
  231. package/apps/pwa/out/observatory/index.html +1 -1
  232. package/apps/pwa/out/observatory/index.txt +22 -22
  233. package/apps/pwa/out/ops/checklist/index.html +1 -1
  234. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  235. package/apps/pwa/out/ops/release/index.html +1 -1
  236. package/apps/pwa/out/ops/release/index.txt +21 -21
  237. package/apps/pwa/out/ops/seats/index.html +1 -1
  238. package/apps/pwa/out/ops/seats/index.txt +21 -21
  239. package/apps/pwa/out/outputs/index.html +1 -1
  240. package/apps/pwa/out/outputs/index.txt +21 -21
  241. package/apps/pwa/out/reflection/index.html +1 -1
  242. package/apps/pwa/out/reflection/index.txt +22 -22
  243. package/apps/pwa/out/scheduler/index.html +1 -1
  244. package/apps/pwa/out/scheduler/index.txt +22 -22
  245. package/apps/pwa/out/sessions/index.html +1 -1
  246. package/apps/pwa/out/sessions/index.txt +21 -21
  247. package/apps/pwa/out/settings/devices/index.html +1 -1
  248. package/apps/pwa/out/settings/devices/index.txt +22 -22
  249. package/apps/pwa/out/settings/index.html +1 -1
  250. package/apps/pwa/out/settings/index.txt +22 -22
  251. package/apps/pwa/out/setup/done/index.html +1 -1
  252. package/apps/pwa/out/setup/done/index.txt +22 -22
  253. package/apps/pwa/out/setup/index.html +1 -1
  254. package/apps/pwa/out/setup/index.txt +22 -22
  255. package/apps/pwa/out/share/index.html +1 -1
  256. package/apps/pwa/out/share/index.txt +22 -22
  257. package/apps/pwa/out/showroom/index.html +1 -1
  258. package/apps/pwa/out/showroom/index.txt +21 -21
  259. package/apps/pwa/out/tasks/index.html +1 -1
  260. package/apps/pwa/out/tasks/index.txt +22 -22
  261. package/apps/pwa/out/term/index.html +1 -1
  262. package/apps/pwa/out/term/index.txt +22 -22
  263. package/apps/pwa/out/today/index.html +1 -1
  264. package/apps/pwa/out/today/index.txt +22 -22
  265. package/apps/pwa/out/trace/index.html +1 -1
  266. package/apps/pwa/out/trace/index.txt +22 -22
  267. package/apps/pwa/out/vault/index.html +1 -1
  268. package/apps/pwa/out/vault/index.txt +22 -22
  269. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  270. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  271. package/apps/pwa/out/workflows/index.html +1 -1
  272. package/apps/pwa/out/workflows/index.txt +22 -22
  273. package/apps/pwa/out/workspace/index.html +1 -1
  274. package/apps/pwa/out/workspace/index.txt +22 -22
  275. package/apps/pwa/out/worktrees/index.html +1 -1
  276. package/apps/pwa/out/worktrees/index.txt +22 -22
  277. package/docs/goal-context/05-authoring-lessons.jsonl +47 -0
  278. package/docs/goal-context/README.md +3 -0
  279. package/graphs/default-loop.yaml +6 -1
  280. package/graphs/implement-loop.yaml +24 -0
  281. package/graphs/release/recipes.yaml +6 -0
  282. package/graphs/release/release-loop.yaml +17 -4
  283. package/graphs/wizard/recipes.yaml +44 -0
  284. package/graphs/wizard/wizard-loop.yaml +44 -0
  285. package/graphs/work/research-report.yaml +2 -0
  286. package/package.json +1 -1
  287. package/scripts/ci-typecheck-changed.ts +139 -5
  288. package/scripts/coord-role-pack.ts +1 -1
  289. package/scripts/first10-gate.ts +416 -0
  290. package/scripts/fleet/wsl-node-setup.sh +432 -0
  291. package/scripts/release-loop/docs-node.ts +204 -8
  292. package/scripts/release-loop/gate-node.ts +249 -53
  293. package/scripts/release-loop/node-verdict.ts +2 -0
  294. package/scripts/release-loop/resume-cap.ts +14 -34
  295. package/scripts/release-loop/resume-release.ts +37 -11
  296. package/scripts/release-loop/traffic-node.ts +59 -0
  297. package/scripts/release-loop/traffic-transition.ts +159 -0
  298. package/scripts/rhythm/daily.ts +137 -3
  299. package/scripts/ux-sim.ts +53 -0
  300. package/skills/README.md +1 -0
  301. package/src/acp/core-turn-bridge.ts +48 -6
  302. package/src/agent/delegate-hint.ts +16 -0
  303. package/src/agent/runner.ts +82 -2
  304. package/src/agent/task-notification.ts +56 -10
  305. package/src/agent/types.ts +4 -0
  306. package/src/agent-substrate/pr-reviewer.ts +55 -3
  307. package/src/agent-substrate/review-intent.ts +29 -2
  308. package/src/agent-substrate/review-observation.ts +3 -0
  309. package/src/agent-substrate/self-review-cli.ts +168 -16
  310. package/src/autopilot/mission-codebase-gate.ts +141 -12
  311. package/src/autopilot/pr-manager.ts +25 -5
  312. package/src/boot/daemon-tools/self-implement.ts +1 -0
  313. package/src/budget/usage-outcomes.ts +8 -4
  314. package/src/capture/tui-self-report.ts +102 -0
  315. package/src/chat/goal-continue-verdict.ts +41 -0
  316. package/src/chat/index.ts +30 -4
  317. package/src/chat/internal-turn-origin.ts +1 -0
  318. package/src/chat/paste-fold.ts +86 -0
  319. package/src/chat/tool-render/block.ts +32 -0
  320. package/src/chat/tool-render/dispatch.ts +2 -20
  321. package/src/chat/tool-render/result-text.ts +98 -0
  322. package/src/chat/turn-typeahead.ts +70 -7
  323. package/src/cli/config-audit.ts +119 -0
  324. package/src/cli/doctor-cli.ts +22 -0
  325. package/src/cli/guardian-cli.ts +10 -0
  326. package/src/cli/herdr-cli.ts +34 -0
  327. package/src/cli/light-entry-route.ts +6 -3
  328. package/src/cli/log-event-names.ts +2 -0
  329. package/src/cli/make-cli.ts +247 -11
  330. package/src/cli/msg-cli.ts +117 -3
  331. package/src/cli/pr-cli.ts +29 -16
  332. package/src/cli/pr-land-base-read.ts +11 -2
  333. package/src/cli/pr-land-heavy-remote.ts +6 -3
  334. package/src/cli/pr-land-overlap-evidence.ts +23 -4
  335. package/src/cli/pr-land-recovery.ts +117 -1
  336. package/src/cli/pty-takeover-cli.ts +8 -7
  337. package/src/cli/release-cli.ts +21 -5
  338. package/src/cli/release-single-flight.ts +1 -1
  339. package/src/cli/tasks-card-show.ts +162 -0
  340. package/src/cli/tasks-cli.ts +574 -356
  341. package/src/cli/tasks-read-cli.ts +197 -0
  342. package/src/core-turn/run-core-turn.ts +4 -2
  343. package/src/core-turn/run-goal-loop.ts +73 -16
  344. package/src/core-turn/types.ts +6 -1
  345. package/src/dashboard/context/keys.ts +8 -31
  346. package/src/dashboard/index.ts +202 -49
  347. package/src/dashboard/input/agent-wake.ts +7 -1
  348. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +146 -3
  349. package/src/dashboard/input/chat-main-slash-command.ts +4 -2
  350. package/src/dashboard/input/goal-continue.ts +210 -0
  351. package/src/dashboard/input/goal-interim.ts +2 -0
  352. package/src/dashboard/input/internal-turn.ts +2 -8
  353. package/src/dashboard/input/seat-autowake.ts +9 -7
  354. package/src/dashboard/input/turn-autoheal.ts +52 -0
  355. package/src/dashboard/seat-boot-preamble.ts +132 -5
  356. package/src/dashboard/slash-runtime/chat-persona.ts +65 -8
  357. package/src/dashboard/slash-runtime/dashboard-handlers.ts +3 -2
  358. package/src/dashboard/slash-runtime/model-choices.ts +15 -0
  359. package/src/dashboard/stale-install-check.ts +3 -99
  360. package/src/debug/batch-queue.ts +119 -0
  361. package/src/debug/tui-log-tag.ts +67 -0
  362. package/src/display/agent-surface.ts +7 -0
  363. package/src/domains/standalone-log-sink.ts +15 -2
  364. package/src/esc-abort-gate.ts +69 -0
  365. package/src/git-fs/worktree.ts +95 -1
  366. package/src/graph-runner/graph-cli.ts +18 -0
  367. package/src/graph-runner/runner.ts +20 -11
  368. package/src/graph-wizard/generate.ts +108 -4
  369. package/src/graph-wizard/steps.ts +15 -0
  370. package/src/grounding/proactive-ground.ts +86 -0
  371. package/src/harness/control-inbox.ts +49 -1
  372. package/src/harness/harness-cli-command.ts +51 -7
  373. package/src/harness/harness-incidents.ts +52 -1
  374. package/src/harness/pod-control-send.ts +33 -5
  375. package/src/harness/self-send-remote.ts +69 -0
  376. package/src/harness/self-send-routing-guard.ts +6 -0
  377. package/src/harness/self-send-target.ts +4 -3
  378. package/src/index.ts +327 -12
  379. package/src/input-core/context-key-runtime.ts +21 -0
  380. package/src/light-cli.ts +6 -1
  381. package/src/llm-wellformed.ts +70 -0
  382. package/src/llm.ts +35 -4
  383. package/src/loops/msg-wake.ts +35 -39
  384. package/src/loops/orchestrator/inbox.ts +59 -11
  385. package/src/loops/orchestrator/knowhow-pack.ts +364 -0
  386. package/src/loops/orchestrator/tick.ts +5 -1
  387. package/src/maturity/feature-maturity.ts +1 -1
  388. package/src/models/prompts.ts +17 -2
  389. package/src/msg/msg-post-office.ts +116 -0
  390. package/src/mss/logging/log-store.ts +79 -22
  391. package/src/nexus/api/decisions-route.ts +38 -18
  392. package/src/nexus/api/graph-wizard-api.ts +20 -2
  393. package/src/nexus/boot/register-mcp-clients.ts +263 -38
  394. package/src/nexus/onboarding/first-boot-wizard.ts +56 -8
  395. package/src/onboarding/first-run.ts +37 -6
  396. package/src/onboarding/web-first.ts +43 -11
  397. package/src/ops/overview-collect.ts +12 -6
  398. package/src/ops/overview.ts +3 -3
  399. package/src/persona/loader.ts +11 -0
  400. package/src/persona/types.ts +8 -0
  401. package/src/prompt-library/session-guidance.ts +14 -0
  402. package/src/provider-summary.ts +8 -0
  403. package/src/pty-shell/herdr-agent-report.ts +118 -9
  404. package/src/pty-shell/herdr-prompt.ts +266 -0
  405. package/src/pty-shell/pty-control-ipc.ts +151 -8
  406. package/src/pty-shell/pty-special-keys.ts +42 -2
  407. package/src/pty-shell/stale-install-check.ts +99 -0
  408. package/src/pty-shell/tui-run-state.ts +14 -2
  409. package/src/release-loop/auto-start.ts +20 -2
  410. package/src/release-loop/checklist.ts +76 -4
  411. package/src/release-loop/rehearsal.ts +36 -20
  412. package/src/repl/index.ts +19 -1
  413. package/src/seat-loop/knowhow-lint.ts +1 -1
  414. package/src/self-dev/decompose-proposal.ts +172 -20
  415. package/src/self-dev/decompose.ts +61 -0
  416. package/src/self-dev/dev-cli.ts +37 -3
  417. package/src/self-dev/dev-pipeline.ts +8 -2
  418. package/src/self-dev/draft-triage-rules.ts +31 -0
  419. package/src/self-dev/glm-credential-guard.ts +77 -0
  420. package/src/self-dev/graph-journey-nodes.ts +1 -0
  421. package/src/self-dev/graph-journey-route.ts +12 -2
  422. package/src/self-dev/orchestrate-cli.ts +68 -3
  423. package/src/self-dev/orchestrate.ts +116 -17
  424. package/src/self-dev/run-supervisor.ts +55 -2
  425. package/src/self-dev/run-types.ts +1 -1
  426. package/src/self-health/autoheal.ts +153 -0
  427. package/src/self-health/signatures.ts +6 -0
  428. package/src/self-implement/device-first.ts +116 -0
  429. package/src/self-implement/doctor-visit.ts +239 -1
  430. package/src/self-implement/evidence-command-budget.ts +80 -0
  431. package/src/self-implement/goal-author-cli.ts +1 -0
  432. package/src/self-implement/goal-author-decompose.ts +265 -4
  433. package/src/self-implement/goal-author.ts +33 -8
  434. package/src/self-implement/goal-elaborate.ts +176 -22
  435. package/src/self-implement/goal-refine.ts +3 -0
  436. package/src/self-implement/graph-variant.ts +40 -6
  437. package/src/self-implement/headless-elanous-driver.ts +19 -3
  438. package/src/self-implement/off-diff-evidence.ts +58 -6
  439. package/src/self-implement/orchestrator.ts +222 -21
  440. package/src/self-implement/pod-warm-pool-profile.ts +1 -0
  441. package/src/self-implement/pwa-import-graph.ts +1 -1
  442. package/src/self-implement/rework-policy.ts +30 -0
  443. package/src/self-implement/run-ledger.ts +108 -0
  444. package/src/self-implement/run-ttl.ts +38 -24
  445. package/src/self-implement/scope-adjacency.ts +3 -1
  446. package/src/self-implement/seams.ts +60 -4
  447. package/src/self-implement/wiring-check.ts +358 -0
  448. package/src/shell-env-bootstrap.ts +11 -4
  449. package/src/skills/runner.ts +4 -2
  450. package/src/skills/tools/agent.ts +290 -48
  451. package/src/skills/tools/schedule-wakeup.ts +23 -4
  452. package/src/skills/tools/shell.ts +61 -6
  453. package/src/skills/tools/terminal-modal-inject.ts +1 -2
  454. package/src/skills/tools/terminal-modal.ts +10 -8
  455. package/src/skills/url-router.ts +41 -1
  456. package/src/smart-wizard/run.ts +66 -0
  457. package/src/status/bar.ts +34 -6
  458. package/src/status/status-provider-info.ts +37 -6
  459. package/src/steward/rejudge-tick.ts +10 -2
  460. package/src/steward/ta-repair-event-collect.ts +17 -6
  461. package/src/task-agent/actions.ts +3 -1
  462. package/src/task-agent/land-queue.ts +21 -8
  463. package/src/task-agent/live-moves.ts +22 -6
  464. package/src/task-agent/mission.ts +30 -0
  465. package/src/task-agent/rejudge-on-head.ts +15 -0
  466. package/src/task-agent/repair-cycle.ts +138 -32
  467. package/src/task-agent/repair-next-move.ts +31 -3
  468. package/src/task-agent/repair-outcomes.ts +29 -0
  469. package/src/task-agent/repair-worker.ts +14 -4
  470. package/src/task-agent/shadow.ts +41 -3
  471. package/src/task-agent/task-card-prefix.ts +2 -0
  472. package/src/task-agent/task-hand.ts +477 -22
  473. package/src/task-agent/task-parent-role-llm.ts +36 -0
  474. package/src/task-agent/tier-split.ts +78 -9
  475. package/src/task-orchestrator/surfaces/pod-account-broker.ts +9 -0
  476. package/src/task-orchestrator/surfaces/pod-child-reuse.ts +146 -0
  477. package/src/task-orchestrator/surfaces/pod-command-job.ts +86 -5
  478. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +215 -3
  479. package/src/task-orchestrator/surfaces/pod-launch-history.ts +133 -0
  480. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +11 -0
  481. package/src/task-orchestrator/surfaces/pod-pool.ts +76 -4
  482. package/src/task-orchestrator/surfaces/pod-provenance.ts +8 -2
  483. package/src/task-orchestrator/surfaces/pod-repair-commit.ts +18 -3
  484. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +16 -0
  485. package/src/task-orchestrator/surfaces/pod-si-warm-host.ts +224 -0
  486. package/src/task-orchestrator/surfaces/pod-si-warm-protocol.ts +201 -0
  487. package/src/task-orchestrator/surfaces/pod-si-warm-provider.ts +444 -0
  488. package/src/task-orchestrator/surfaces/pod-si-warm-runner.ts +387 -0
  489. package/src/task-orchestrator/surfaces/pod-si-warm-transport.ts +157 -0
  490. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +4 -0
  491. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +485 -36
  492. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +3 -0
  493. package/src/task-orchestrator/surfaces/self-implement-pod.ts +396 -19
  494. package/src/task-orchestrator/surfaces/self-implement.ts +42 -2
  495. package/src/tool-runtime/index.ts +15 -2
  496. package/src/tool-runtime/mcp-proxy-bootstrap.ts +29 -0
  497. package/src/tty-foreground.ts +155 -0
  498. package/src/tui/chat/goal-interim.ts +173 -0
  499. package/src/tui/chat/log-view.ts +205 -18
  500. package/src/tui/chat/self-health-status.ts +232 -0
  501. package/src/tui/entry.ts +370 -81
  502. package/src/tui/input/composer.ts +8 -1
  503. package/src/tui/slash/compact-command.ts +7 -0
  504. package/src/tui/slash/compact.ts +1 -7
  505. package/src/tui/slash/resume.ts +75 -0
  506. package/src/tui-client/local-chat-turn.ts +45 -2
  507. package/src/tui-client/next-dashboard-runtime.ts +8 -0
  508. package/src/tui-client/next-loop-command.ts +70 -0
  509. package/src/tui-client/next-wakeup.ts +191 -0
  510. package/src/tui.ts +37 -0
  511. package/src/ui/modal-adapter.ts +2 -2
  512. package/src/ux-sim/classic-tui-seat-scenarios.ts +516 -0
  513. package/src/ux-sim/cli-config-audit-device.ts +121 -0
  514. package/src/ux-sim/dashboard-event-loop-stall-monitor-device.ts +238 -0
  515. package/src/ux-sim/event-monkey.ts +3 -2
  516. package/src/ux-sim/fake-bin.ts +45 -0
  517. package/src/ux-sim/fake-herdr.ts +238 -0
  518. package/src/ux-sim/fake-llm.ts +111 -6
  519. package/src/ux-sim/fault-glm-no-credential.ts +116 -0
  520. package/src/ux-sim/fault-nextmove-dispatch.ts +102 -1
  521. package/src/ux-sim/fault-scope-escape-lift.ts +33 -6
  522. package/src/ux-sim/fault-tui-400-autoheal.ts +297 -0
  523. package/src/ux-sim/goal-device.ts +619 -0
  524. package/src/ux-sim/in-process-cli.ts +22 -5
  525. package/src/ux-sim/mock-authoring-first-run-child.ts +35 -0
  526. package/src/ux-sim/mock-authoring-first-run.ts +97 -0
  527. package/src/ux-sim/mock-seat-pty-frame-child.ts +29 -0
  528. package/src/ux-sim/mock-seat-pty-frame.ts +297 -0
  529. package/src/ux-sim/mock-seat-pty-sequence-child.ts +21 -0
  530. package/src/ux-sim/mock-seat-pty-sequence.ts +206 -0
  531. package/src/ux-sim/next-tui-seat-scenarios.ts +631 -0
  532. package/src/ux-sim/onboarding-first-run-device.ts +269 -0
  533. package/src/ux-sim/pty-key-modifiers-device.ts +85 -0
  534. package/src/ux-sim/subagent-tools-device.ts +81 -0
  535. package/src/ux-sim/task-orchestrator-surfaces-self-implement-pod-device.ts +250 -0
  536. package/src/ux-sim/tty-foreground-steal-child.ts +21 -0
  537. package/src/version/packed-revision.json +1 -1
  538. package/apps/pwa/out/_next/static/chunks/1165.bad13fc9151a7288.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/13.02a07436dec15f89.js +0 -32
  540. package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +0 -41
  541. package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +0 -24
  542. package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +0 -74
  543. package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/1993-c0007b7ad0c0ef41.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/1c735de4.f993a30bbd3c57c4.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +0 -148
  553. package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/2625.5d870aa999f33db1.js +0 -34
  555. package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +0 -77
  556. package/apps/pwa/out/_next/static/chunks/2833-0fe47af99ed13c29.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +0 -62
  559. package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +0 -90
  560. package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +0 -36
  563. package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +0 -79
  565. package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/3f7c4ee5.3dde54f01a816613.js +0 -122
  567. package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/4441-875b97f5821ed58a.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +0 -286
  570. package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +0 -24
  573. package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/5154.a118f3957ed14e36.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +0 -23
  582. package/apps/pwa/out/_next/static/chunks/5483-dd5d7697f6bdb106.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +0 -287
  586. package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +0 -8
  593. package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +0 -27
  595. package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +0 -93
  597. package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/6866-79aa5b4e47cac6aa.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/6b89c8bd.24df687a820500b3.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +0 -149
  604. package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +0 -104
  605. package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +0 -1
  608. package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/8219.baa715d1deee80e2.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/8256.e3ac8421a71f82f4.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +0 -1
  613. package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +0 -226
  615. package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +0 -64
  617. package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +0 -1
  619. package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +0 -115
  622. package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/967-2aa39b2d04b4c690.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/app/control/page-406b47745b53f269.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/morning/page-47c5d4db587266bd.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1f5a60f70cb4dd0c.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/outputs/page-bac7dee94e5eae4a.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/term/page-dc0a532f5b9196ec.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +0 -1
  686. /package/apps/pwa/out/_next/static/{T1mBQqmkwKDLGtyisDCOd → uC-N0emedeNOFuaBQFv-I}/_ssgManifest.js +0 -0
@@ -24,6 +24,9 @@ export interface GoalFixedLayer {
24
24
  invariants: string[];
25
25
  /** 불변식 문면에서 «바꾸지 않는다/금지» 절에 실린 경로 — 카드가 건드리면 위반이다. */
26
26
  protectedPaths: string[];
27
+ /** ELABORATION-PROTECTED-PATH-INVERSION — 골이 «고치라고» 준 경로(대상 경로·신설·증거 명령의 파일).
28
+ * 이 경로는 불변식 문면에 같이 나와도 보호 구역이 되지 않는다(대상을 수정 금지로 뒤집지 않는다). */
29
+ targetPaths: string[];
27
30
  }
28
31
 
29
32
  export interface ElaborationCard {
@@ -37,17 +40,74 @@ export interface ElaborationCard {
37
40
 
38
41
  export type ElaborationOutcome =
39
42
  | { status: 'elaborated'; card: ElaborationCard; cardSha: string; fileCount: number; level: InjectionLevel; attempts: number; judge: 'llm' | 'deterministic-only'; judgeErrors?: string[]; fixedLayerEmpty?: boolean }
40
- | { status: 'needs-human'; attempts: number; violations: string[]; cardSha: string }
43
+ | { status: 'needs-human'; reason: ElaborationFailureReason; attempts: number; violations: string[]; cardSha: string }
41
44
  | { status: 'skipped'; reason: 'no-provider' | 'provider-failed' | 'card-unparseable'; attempts: number; error?: string };
42
45
 
43
46
  const MAX_LINES = 20;
44
47
  const MAX_LINE_CHARS = 300;
45
48
  const MAX_CARD_FILES = 30;
49
+ export type ElaborationFailureReason = 'goal-elaboration-ungrounded-path' | 'goal-elaboration-protected-path'
50
+ | 'goal-elaboration-scope-conflict' | 'goal-elaboration-fixed-layer-conflict';
51
+
52
+ function failureReason(violations: readonly string[]): ElaborationFailureReason {
53
+ if (violations.some((violation) => violation.startsWith('ungrounded path:'))) return 'goal-elaboration-ungrounded-path';
54
+ if (violations.some((violation) => violation.startsWith('protected path:'))) return 'goal-elaboration-protected-path';
55
+ // 판정기 자유 문면의 "KPI 범위 약화"는 확장 수복 대상이 아니다. 구조화된 kind=scope만 인정한다.
56
+ if (violations.some((violation) => violation.startsWith('scope expansion:'))) return 'goal-elaboration-scope-conflict';
57
+ return 'goal-elaboration-fixed-layer-conflict';
58
+ }
59
+
60
+ function repairInstruction(reason: ElaborationFailureReason, fixed: GoalFixedLayer): string {
61
+ switch (reason) {
62
+ case 'goal-elaboration-ungrounded-path':
63
+ return `없는 경로를 다시 접지한다. 저장소에 있는 파일이나 골에 명시된 대상 경로만 고르고, 새 파일은 골이 신설을 요구할 때만 newFiles에 적는다. 대상 경로: ${fixed.targetPaths.join(', ') || '(명시 없음)'}`;
64
+ case 'goal-elaboration-protected-path':
65
+ return `보호 경로를 카드에서 빼고 골의 대상 경로 안에서만 구현한다.${fixed.protectedPaths.length ? ` 보호 경로: ${fixed.protectedPaths.join(', ')}` : ' 위반 목록의 보호 경로 지적을 확인한다.'}`;
66
+ case 'goal-elaboration-scope-conflict':
67
+ return '범위 확장을 좁힌다. 골의 대상과 완료 경계를 유지하고 새 기능이나 새 판정 조건을 더하지 않는다.';
68
+ case 'goal-elaboration-fixed-layer-conflict':
69
+ return '고정 층의 방향·KPI·불변식을 보존한다. 지적된 문장만 고치고 완료 조건을 약화하지 않는다.';
70
+ }
71
+ }
46
72
  const KPI_LINE = /판정 신호|수용선|완료 경계|증거 명령|KPI|acceptance|verify:|반증/i;
47
73
  const INVARIANT_LINE = /불변|경계:|⛔|바꾸지 않는다|하지 않는다|금지|보호|invariant|must not|do not/i;
48
74
  const DIRECTION_LINE = /^(?:[-*]\s*)?(?:바꿀 것|목표|무엇|왜|현재 계약|Goal|Why|What)\s*[::]/i;
49
75
  const PROHIBITION = /바꾸지 않는다|건드리지 않는다|하지 않는다|금지|보호|⛔|must not|do not (?:touch|modify|change)/i;
50
76
  const PATH_TOKEN = /[\w@.-]+(?:\/[\w@.-]+)*\.(?:ts|tsx|js|mjs|cjs|json|ya?ml|md|sh)\b/g;
77
+ /** 골이 바꾸라고 준 경로가 실리는 줄 — 대상 경로 · 신설 · 증거 명령(bun test <파일>). */
78
+ // ⛔ «줄 처음 ⊕ 콜론» 고정 — 경계 줄 안의 «…판정 신호 불변…» 을 대상 줄로 읽으면 보호 경로가 빠진다.
79
+ // ① 대상·신설 줄 = 그 줄의 모든 경로 ② 증거 명령·판정 신호·현재 계약 줄 = `bun test` 바로 뒤 시험 파일만
80
+ // (그 줄의 «goal-author.ts 는 바꾸지 않는다» 같은 보호 경로를 대상으로 빼지 않게 · r1 must-fix).
81
+ const TARGET_LINE = /^(?:[-*]\s*)?(?:대상 경로|대상|신설|새 파일|target paths?|files?)\s*[::]/i;
82
+ const COMMAND_LINE = /^(?:[-*]\s*)?(?:완료 경계 증거 명령|증거 명령|판정 신호|현재 계약)\s*[::]/i;
83
+ const BUN_TEST_HEAD = /bun test\s+/g;
84
+ /** `bun test` 인자 — 경로 꼴 토큰이 끊기는 곳(`·`·문장·`→`)에서 멈추고 시험 파일만 낸다(r2 must-fix). */
85
+ export function bunTestPathArgs(line: string): string[] {
86
+ const out: string[] = [];
87
+ for (const head of line.matchAll(BUN_TEST_HEAD)) {
88
+ const rest = line.slice(head.index! + head[0].length).split(/\s+/);
89
+ for (const raw of rest) {
90
+ // 따옴표·백틱으로 감싼 인자도 시험 파일이다(r3 must-fix) — 짝이 맞는 감싸기만 벗긴다.
91
+ const tok = /^(["'`])(.*)\1$/.exec(raw)?.[2] ?? raw;
92
+ if (tok.startsWith('-')) continue;
93
+ if (!/^[\w@./-]+$/.test(tok)) break;
94
+ if (/\.(?:test|spec)\.[cm]?[jt]sx?$/.test(tok)) out.push(tok);
95
+ }
96
+ }
97
+ return out;
98
+ }
99
+ /** 경로 바로 뒤가 «의 …»·«안의 …»·«'s …» 면 그 금지는 파일 «안의 내용»(기존 단언·동작·계약)에 대한 것이다. */
100
+ const CONTENT_SCOPED = /^\s*(?:의|안의|에 있는|속)\s|^'s\s|^\s+(?:existing|assertions?|behaviou?r|contract)\b/i;
101
+ /** 형식이 안 맞아 «검증 불가»로 처리된 경계 줄 — 금지 불변식으로 격상하지 않는다(10-22 실물). */
102
+ const UNVERIFIABLE_LINE = /UNVERIFIABLE|검증 불가|형식 불일치/i;
103
+ /** 사람이 쓴 경계 줄 — 대상 경로를 보호로 이길 수 있는 유일한 자리. */
104
+ const BOUNDARY_LINE = /^(?:[-*]\s*)?경계\s*[::]/;
105
+ /** 경로 «바로 뒤»가 «는/를 바꾸지 않는다» 꼴일 때만 경로 자체 금지다 — «X 를 수정하되 기존 단언은 바꾸지 않는다» 는 아니다(r1 must-fix). */
106
+ const BARE_PATH_PROHIBITION = /^\s*(?:파일)?\s*(?:은|는|을|를|도)?\s*(?:(?:바꾸|건드리|수정하|고치|변경하)지\s*않는다|(?:수정|변경)\s*금지)/;
107
+
108
+ function samePathOrSuffix(a: string, b: string): boolean {
109
+ return a === b || a.endsWith(`/${b}`) || b.endsWith(`/${a}`);
110
+ }
51
111
 
52
112
  function clip(lines: string[]): string[] {
53
113
  return lines.slice(0, MAX_LINES).map((line) => (line.length > MAX_LINE_CHARS ? `${line.slice(0, MAX_LINE_CHARS)}…` : line));
@@ -57,17 +117,46 @@ function clip(lines: string[]): string[] {
57
117
  export function extractGoalFixedLayer(goal: string): GoalFixedLayer {
58
118
  const lines = goal.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
59
119
  const kpi = lines.filter((line) => KPI_LINE.test(line));
60
- const invariants = lines.filter((line) => INVARIANT_LINE.test(line));
120
+ const invariants = lines.filter((line) => INVARIANT_LINE.test(line) && !UNVERIFIABLE_LINE.test(line));
121
+ const targetPaths = new Set<string>();
122
+ for (const line of lines.filter((l) => TARGET_LINE.test(l))) {
123
+ // 대상 줄 안의 금지 절(«· X 는 바꾸지 않는다»)은 대상이 아니다 — 보호로 남긴다(r4 must-fix). 쪼개기는 보호 구역과 같은 규칙.
124
+ for (const clause of line.split(/[·;,]|\s-\s/)) {
125
+ if (PROHIBITION.test(clause)) continue;
126
+ for (const match of clause.matchAll(PATH_TOKEN)) targetPaths.add(match[0]);
127
+ }
128
+ }
129
+ /** 증거·판정 명령이 «돌리라고» 준 시험 파일 — 어떤 금지 줄로도 보호 구역이 되지 않는다(TA-REMOTE-MIRROR-BIND 10-22). */
130
+ const evidencePaths = new Set<string>();
131
+ for (const line of lines.filter((l) => COMMAND_LINE.test(l))) {
132
+ for (const path of bunTestPathArgs(line)) { targetPaths.add(path); evidencePaths.add(path); }
133
+ }
61
134
  let direction = lines.filter((line) => DIRECTION_LINE.test(line));
62
- if (!direction.length) direction = lines.filter((line) => !kpi.includes(line) && !invariants.includes(line)).slice(0, 3);
135
+ // UNVERIFIABLE 경계 줄은 방향 대체값으로도 고정 층에 들이지 않는다(r6 — 판정기 프롬프트에 «X 수정 금지»가 되살아났다).
136
+ if (!direction.length) direction = lines.filter((line) => !kpi.includes(line) && !invariants.includes(line) && !UNVERIFIABLE_LINE.test(line)).slice(0, 3);
63
137
  const protectedPaths = new Set<string>();
138
+ const explicitlyProtected = new Set<string>();
64
139
  for (const line of invariants) {
65
140
  for (const clause of line.split(/[·;,]|\s-\s/)) {
66
141
  if (!PROHIBITION.test(clause)) continue;
67
- for (const match of clause.matchAll(PATH_TOKEN)) protectedPaths.add(match[0]);
142
+ for (const match of clause.matchAll(PATH_TOKEN)) {
143
+ const isTarget = [...targetPaths].some((target) => samePathOrSuffix(match[0], target));
144
+ if (isTarget) {
145
+ // 골이 고치거나 돌리라고 준 파일(대상·신설·증거 시험)은 «추론»으로 보호되지 않는다 —
146
+ // 저작기가 덧붙인 분해 인용·«단정하지 않는다» 같은 동작 금지 문장이 같은 절의 대상까지 보호로 뒤집었다(TA-REMOTE-MIRROR-BIND 10-22).
147
+ // ⛔ 이기는 것은 사람이 쓴 «경계:» 줄의 맨 «X 는 바꾸지 않는다»(경로 자체 금지)뿐이고, 증거 명령의 시험 파일은 그것으로도 안 막는다(r5 ⊕ 이번 변종).
148
+ // «X 의 기존 단언·동작은 바꾸지 않는다» 는 «내용» 금지다 — 파일은 고친다(10-22 밤샘 parked 다수의 뒤집힘).
149
+ const pathLevel = BOUNDARY_LINE.test(line) && BARE_PATH_PROHIBITION.test(clause.slice(match.index! + match[0].length));
150
+ const isEvidence = [...evidencePaths].some((path) => samePathOrSuffix(match[0], path));
151
+ if (!pathLevel || isEvidence) continue;
152
+ explicitlyProtected.add(match[0]);
153
+ }
154
+ protectedPaths.add(match[0]);
155
+ }
68
156
  }
69
157
  }
70
- return { direction: clip(direction), kpi: clip(kpi), invariants: clip(invariants), protectedPaths: [...protectedPaths] };
158
+ const targets = [...targetPaths].filter((target) => ![...explicitlyProtected].some((p) => samePathOrSuffix(p, target)));
159
+ return { direction: clip(direction), kpi: clip(kpi), invariants: clip(invariants), protectedPaths: [...protectedPaths], targetPaths: targets };
71
160
  }
72
161
 
73
162
  function stringList(value: unknown): string[] | undefined {
@@ -132,7 +221,7 @@ export function checkCardAgainstFixedLayer(card: ElaborationCard, fixed: GoalFix
132
221
  const paths = [...new Set([...card.files, ...card.newFiles, card.firstTest.path])];
133
222
  for (const path of paths) {
134
223
  const hit = fixed.protectedPaths.find((protectedPath) => touchesProtected(path, protectedPath));
135
- if (hit) violations.push(`protected path: ${path} (goal invariant forbids changing ${hit})`);
224
+ if (hit) violations.push(protectedPathViolation(path, hit));
136
225
  else if (!card.newFiles.includes(path) && !fileExists(path)) violations.push(`ungrounded path: ${path} does not exist and is not listed in newFiles`);
137
226
  }
138
227
  return violations;
@@ -145,12 +234,12 @@ function section(title: string, lines: string[]): string {
145
234
  return [`### ${title}`, ...(lines.length ? lines.map((line) => `- ${line}`) : ['- (없음)'])].join('\n');
146
235
  }
147
236
 
148
- function buildCardPrompt(goal: string, context: string, fixed: GoalFixedLayer, previousViolations: string[] = []): string {
237
+ function buildCardPrompt(goal: string, context: string, fixed: GoalFixedLayer, previousViolations: string[] = [], repair?: string): string {
149
238
  return [
150
239
  '## 할 일 — 착수 구체화 카드(E1)',
151
240
  '아래 골을 구현하기 전에, 저장소 맥락을 근거로 «구체화 카드»를 쓴다. 고정 층(방향·KPI·불변식·보호 구역)은 바꾸지 않는다 — 카드는 «어디서부터 어떻게» 만 정한다.',
152
241
  'JSON 형식: {"files": [실제 건드릴 경로], "newFiles": [그중 새로 만들 경로], "requirements": [세부 요구], "firstTest": {"path": 시험 파일, "name": 시험 이름, "redReason": 지금 왜 실패하는가}, "stage": "unit|integration|live", "level": "L0|L1|L2|L3|L4"(주입 사다리 층)}',
153
- ...(previousViolations.length ? ['', '## 앞 카드가 고정 층과 어긋났다 — 고쳐 다시 쓴다', ...previousViolations.map((v) => `- ${v}`)] : []),
242
+ ...(previousViolations.length ? ['', '## 앞 카드가 고정 층과 어긋났다 — 이 사유로 딱 한 번 고쳐 다시 쓴다', ...(repair ? [repair] : []), ...previousViolations.map((v) => `- ${v}`)] : []),
154
243
  '',
155
244
  '## 고정 층(바꾸지 않는다)',
156
245
  section('방향', fixed.direction),
@@ -166,7 +255,9 @@ function buildCardPrompt(goal: string, context: string, fixed: GoalFixedLayer, p
166
255
  function buildJudgePrompt(fixed: GoalFixedLayer, card: ElaborationCard): string {
167
256
  return [
168
257
  '카드가 고정 층과 «맞는지만» 본다. 카드가 KPI·판정 신호를 약화·삭제·대체하거나, 방향을 바꾸거나, 불변식·보호 구역을 어기면 불일치다. 구현 방법의 좋고 나쁨은 판정하지 않는다.',
169
- 'JSON 형식: {"consistent": true|false, "violations": [어긋난 점]}',
258
+ 'JSON 형식: {"consistent": true|false, "violations": [{"kind": "path"|"content"|"scope", "path": "<경로 · path 일 때>", "text": "<어긋난 점>"}]}',
259
+ 'kind=path = 그 경로를 «건드리는 것 자체»가 금지라는 지적 · kind=content = 기존 단언·동작·계약·KPI 를 바꾸거나 약화했다는 지적 · kind=scope = 골 밖의 새 기능으로 범위를 확장했다는 지적.',
260
+ ...(fixed.targetPaths.length ? [`대상 경로(골이 고치라고 준 파일 · 건드리는 것 자체는 위반 아님 · 그 안의 기존 계약을 바꾸면 content 위반): ${fixed.targetPaths.join(', ')}`] : []),
170
261
  '',
171
262
  section('방향', fixed.direction),
172
263
  section('KPI·판정 신호', fixed.kpi),
@@ -177,11 +268,55 @@ function buildJudgePrompt(fixed: GoalFixedLayer, card: ElaborationCard): string
177
268
  ].join('\n');
178
269
  }
179
270
 
180
- function parseJudge(text: string): { consistent: boolean; violations: string[] } | undefined {
271
+ type JudgeViolation = { kind: 'path' | 'content' | 'scope' | 'unknown'; path?: string; text: string };
272
+
273
+ const PROTECTED_PATH_PREFIX = 'protected path:';
274
+ function protectedPathViolation(path: string, protectedPath: string): string {
275
+ return `${PROTECTED_PATH_PREFIX} ${path} (goal invariant forbids changing ${protectedPath})`;
276
+ }
277
+
278
+ function legacyProtectedPath(text: string): string | undefined {
279
+ const trimmed = text.trim();
280
+ if (!trimmed.toLowerCase().startsWith(PROTECTED_PATH_PREFIX)) return undefined;
281
+ const match = /^(\S+?)(?:\s+\(goal invariant forbids changing\s+(\S+)\))?\.?$/i.exec(trimmed.slice(PROTECTED_PATH_PREFIX.length).trim());
282
+ return match && (!match[2] || match[1] === match[2]) ? match[1] : undefined;
283
+ }
284
+
285
+ /** 판정기 지적이 «대상 경로를 건드리는 것 자체»(kind=path)인가 — 문구가 아니라 판정기가 낸 «종류»로 가른다(r2 must-fix).
286
+ * ⛔ content·종류 없음(옛 문자열 꼴)은 버리지 않는다 — 기존 단언·동작·계약 위반은 문구와 무관하게 남는다. */
287
+ function isTargetInversion(violation: JudgeViolation, targetPaths: readonly string[]): boolean {
288
+ // 이전 판정기는 kind 없이 결정론 검사와 똑같은 보호 경로 문장을 돌려주기도 했다
289
+ // (FIRST10-GATE: 신설 scripts/first10-gate.test.ts). 정확한 경로 수준 문법만 복구한다.
290
+ // 명시적 content 지적은 문구가 비슷해도 기존 계약 위반일 수 있으므로 버리지 않는다.
291
+ const legacy = violation.kind === 'unknown' ? legacyProtectedPath(violation.text) : undefined;
292
+ const path = violation.kind === 'path' ? violation.path
293
+ : legacy;
294
+ if (!path) return false;
295
+ return targetPaths.some((target) => samePathOrSuffix(path, target));
296
+ }
297
+
298
+ function judgeViolations(value: unknown): JudgeViolation[] {
299
+ if (!Array.isArray(value)) return [];
300
+ const out: JudgeViolation[] = [];
301
+ for (const item of value) {
302
+ if (typeof item === 'string') { if (item.trim()) out.push({ kind: 'unknown', text: item }); continue; }
303
+ if (!item || typeof item !== 'object') continue;
304
+ const rec = item as Record<string, unknown>;
305
+ const text = typeof rec.text === 'string' && rec.text.trim() ? rec.text : JSON.stringify(rec);
306
+ const kind = rec.kind === 'path' || rec.kind === 'content' || rec.kind === 'scope' ? rec.kind : 'unknown';
307
+ out.push({ kind, text, ...(typeof rec.path === 'string' && rec.path.trim() ? { path: rec.path.trim() } : {}) });
308
+ }
309
+ return out;
310
+ }
311
+
312
+ function parseJudge(text: string): { consistent: boolean; violations: JudgeViolation[] } | undefined {
181
313
  const raw = lastJsonObject(text) as Record<string, unknown> | undefined;
182
314
  if (!raw || typeof raw.consistent !== 'boolean') return undefined;
183
- const violations = stringList(raw.violations ?? []) ?? [];
184
- return { consistent: raw.consistent && violations.length === 0, violations: raw.consistent ? violations : violations.length ? violations : ['judge reported inconsistency'] };
315
+ const violations = judgeViolations(raw.violations ?? []);
316
+ return {
317
+ consistent: raw.consistent && violations.length === 0,
318
+ violations: raw.consistent ? violations : violations.length ? violations : [{ kind: 'unknown', text: 'judge reported inconsistency' }],
319
+ };
185
320
  }
186
321
 
187
322
  function cardSha(card: ElaborationCard): string {
@@ -198,21 +333,26 @@ function errorText(error: unknown): string {
198
333
  */
199
334
  export async function elaborateGoalOnArrival(
200
335
  input: { goal: string; context?: string; fileExists: (path: string) => boolean },
201
- deps: { callLLM?: ElaborationCallLLM; maxRewrites?: number },
336
+ deps: { callLLM?: ElaborationCallLLM; maxRewrites?: number; observe?: (event: string, data: Record<string, unknown>) => void },
202
337
  ): Promise<ElaborationOutcome> {
203
338
  if (!deps.callLLM) return { status: 'skipped', reason: 'no-provider', attempts: 0 };
204
339
  const fixed = extractGoalFixedLayer(input.goal);
205
- const maxAttempts = 1 + Math.max(0, deps.maxRewrites ?? 1);
340
+ // 같은 결함으로 LLM을 계속 부르지 않는다. 과도한 호출자 설정을 조용히 무시하지 않는다.
341
+ if (deps.maxRewrites !== undefined && deps.maxRewrites !== 0 && deps.maxRewrites !== 1) {
342
+ throw new RangeError('goal elaboration maxRewrites must be 0 or 1');
343
+ }
344
+ const maxAttempts = 1 + (deps.maxRewrites ?? 1);
206
345
  const fixedLayerEmpty = !fixed.kpi.length && !fixed.invariants.length;
207
346
  /** 다시 쓰기 프롬프트에 실을 앞 회차의 문제(판독 실패 포함). */
208
347
  let feedback: string[] = [];
348
+ let repair: string | undefined;
209
349
  /** 고정 층 위반은 «판독된 카드»에만 귀속한다 — 해시와 위반이 같은 카드를 가리킨다. */
210
- let lastRejected: { sha: string; violations: string[] } | undefined;
350
+ let lastRejected: { sha: string; violations: string[]; reason: ElaborationFailureReason } | undefined;
211
351
  const judgeErrors: string[] = [];
212
352
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
213
353
  let text: string;
214
354
  try {
215
- text = await deps.callLLM({ prompt: buildCardPrompt(input.goal, input.context ?? '', fixed, feedback), systemPrompt: CARD_SYSTEM });
355
+ text = await deps.callLLM({ prompt: buildCardPrompt(input.goal, input.context ?? '', fixed, feedback, repair), systemPrompt: CARD_SYSTEM });
216
356
  } catch (error) {
217
357
  return { status: 'skipped', reason: 'provider-failed', attempts: attempt, error: errorText(error) };
218
358
  }
@@ -230,7 +370,14 @@ export async function elaborateGoalOnArrival(
230
370
  const verdict = parseJudge(await deps.callLLM({ prompt: buildJudgePrompt(fixed, card), systemPrompt: JUDGE_SYSTEM }));
231
371
  if (verdict) {
232
372
  judge = 'llm';
233
- if (!verdict.consistent) violations = verdict.violations;
373
+ if (!verdict.consistent) {
374
+ // 판정기가 «대상 경로를 건드렸다 = 보호 구역 위반»이라고 하면 그 지적은 뒤집힘이다 — 버리고 관측에 남긴다.
375
+ const inverted = verdict.violations.filter((v) => isTargetInversion(v, fixed.targetPaths));
376
+ if (inverted.length) judgeErrors.push(`judge-target-inversion-dropped: ${inverted.length}`);
377
+ violations = verdict.violations.filter((v) => !isTargetInversion(v, fixed.targetPaths))
378
+ .map((v) => v.kind === 'scope' ? `scope expansion: ${v.text}`
379
+ : v.kind === 'content' ? `content violation: ${v.text}` : v.text);
380
+ }
234
381
  } else judgeErrors.push('judge-unparseable');
235
382
  } catch (error) {
236
383
  // 판정기 실패는 결정론 대조만으로 — 카드는 고정 층을 다시 쓰지 않는다. 실패 사실은 관측에 남긴다.
@@ -241,11 +388,16 @@ export async function elaborateGoalOnArrival(
241
388
  return { status: 'elaborated', card, cardSha: sha, fileCount: card.files.length, level: card.level, attempts: attempt, judge,
242
389
  ...(judgeErrors.length ? { judgeErrors } : {}), ...(fixedLayerEmpty ? { fixedLayerEmpty } : {}) };
243
390
  }
244
- lastRejected = { sha, violations };
391
+ const reason = failureReason(violations);
392
+ lastRejected = { sha, violations, reason };
245
393
  feedback = violations;
394
+ if (attempt < maxAttempts) {
395
+ repair = [...new Set(violations.map((violation) => failureReason([violation])))].map((kind) => repairInstruction(kind, fixed)).join('\n');
396
+ deps.observe?.('goal-elaboration-self-heal', { reason, attempt, cardSha: sha, violations });
397
+ }
246
398
  }
247
399
  if (!lastRejected) return { status: 'skipped', reason: 'card-unparseable', attempts: maxAttempts, error: feedback[0] };
248
- return { status: 'needs-human', attempts: maxAttempts, violations: lastRejected.violations, cardSha: lastRejected.sha };
400
+ return { status: 'needs-human', reason: lastRejected.reason, attempts: maxAttempts, violations: lastRejected.violations, cardSha: lastRejected.sha };
249
401
  }
250
402
 
251
403
  export function renderElaborationCard(card: ElaborationCard, sha: string): string {
@@ -275,8 +427,10 @@ export async function runArrivalElaboration(input: {
275
427
  const fileExists = input.fileExists ?? ((path: string) => existsSync(join(input.cwd ?? process.cwd(), path)));
276
428
  let outcome: ElaborationOutcome;
277
429
  try {
278
- outcome = await elaborateGoalOnArrival({ goal: input.goal, context: input.prompt, fileExists }, { callLLM: input.callLLM });
430
+ outcome = await elaborateGoalOnArrival({ goal: input.goal, context: input.prompt, fileExists }, { callLLM: input.callLLM,
431
+ observe: (event, data) => input.observe(event, data, { level: 'warn' }) });
279
432
  } catch (error) {
433
+ if (error instanceof RangeError && error.message === 'goal elaboration maxRewrites must be 0 or 1') throw error;
280
434
  outcome = { status: 'skipped', reason: 'provider-failed', attempts: 0, error: errorText(error) };
281
435
  }
282
436
  if (outcome.status === 'elaborated') {
@@ -287,8 +441,8 @@ export async function runArrivalElaboration(input: {
287
441
  return { prompt: `${input.prompt}\n\n${renderElaborationCard(outcome.card, outcome.cardSha)}`, parked: false };
288
442
  }
289
443
  if (outcome.status === 'needs-human') {
290
- input.observe('goal-elaboration-needs-human', { outcome: 'needs-human', attempts: outcome.attempts, violations: outcome.violations, cardSha: outcome.cardSha }, { level: 'warn' });
291
- return { prompt: input.prompt, parked: true, detail: `goal-elaboration needs-human: ${outcome.violations.join(' | ').slice(0, 500)}` };
444
+ input.observe('goal-elaboration-needs-human', { outcome: 'needs-human', reason: outcome.reason, attempts: outcome.attempts, violations: outcome.violations, cardSha: outcome.cardSha }, { level: 'warn' });
445
+ return { prompt: input.prompt, parked: true, detail: `goal-elaboration needs-human: ${outcome.reason} (attempts: ${outcome.attempts}) · ${outcome.violations.join(' | ').slice(0, 500)}` };
292
446
  }
293
447
  input.observe('goal-elaboration-skipped', { outcome: 'skipped', reason: outcome.reason, attempts: outcome.attempts, ...(outcome.error ? { error: outcome.error } : {}) }, outcome.reason === 'no-provider' ? undefined : { level: 'warn' });
294
448
  return { prompt: input.prompt, parked: false };
@@ -177,6 +177,8 @@ export interface FirstRoundEvidence {
177
177
  findings?: string;
178
178
  /** 첫 라운드가 실제로 건드린 파일. */
179
179
  changedFiles?: readonly string[];
180
+ /** SCOPE-ESCAPE-AS-REFINE — 대상 경로 밖에서 바뀌었고 수용된 파일(«구현이 알려준 새 범위» · 실패 아님). */
181
+ newScope?: readonly string[];
180
182
  }
181
183
 
182
184
  /** 내부 — 시험은 refineGoalFromFirstRound 가 LLM 에 넘긴 프롬프트로 본다. */
@@ -195,6 +197,7 @@ function buildRegroundingPrompt(v1: string, evidence: FirstRoundEvidence): strin
195
197
  '## 첫 라운드 실전',
196
198
  `- 자식 요약: ${(evidence.implSummary ?? '').replace(/\s+/g, ' ').trim().slice(0, 600) || '(없음)'}`,
197
199
  `- 건드린 파일: ${evidence.changedFiles?.length ? evidence.changedFiles.slice(0, 40).join(', ') : '(관측 없음)'}`,
200
+ ...(evidence.newScope?.length ? [`- 구현이 알려준 새 범위(대상 경로 밖 편집 · 실패 아님 · 예상 구역에 넣을지 판단): ${evidence.newScope.slice(0, 40).join(', ')}`] : []),
198
201
  '### gate·리뷰 지적',
199
202
  (evidence.findings ?? '').trim().slice(0, 4000) || '(없음)',
200
203
  '',
@@ -3,6 +3,7 @@ import { applyGraphOverlays, type GraphOverlaySpec, type OverlayPatchOp, type Ov
3
3
  import { edgeMapOf, graphVersionHash, type GraphEdgeSpec, type GraphNodeSpec, type GraphTemplateSpec } from './graph-yaml.js';
4
4
  import { inspectPipelineGraph } from './pipeline-shape.js';
5
5
  import { hasNodeKind } from '../graph-kinds/registry.js';
6
+ import { GOAL_TYPES, type GoalType } from './goal-author.js';
6
7
 
7
8
  /** A proposed change to one existing outcome of a conditional route. Unconditional and fallback edges are protected. */
8
9
  export interface GraphVariantRoute {
@@ -24,6 +25,18 @@ export interface GraphVariantPlan {
24
25
  readonly growth?: GraphVariantGrowth;
25
26
  }
26
27
 
28
+ /** 골 분석 중 최초 변형 선택이 보는 «두» 입력 — 문서 전용·저작 등급 같은 원 칸의 다른 축은 이 조각에 없다. */
29
+ export interface GraphVariantGoalAnalysis {
30
+ readonly goalType: GoalType;
31
+ readonly targetPathCount: number;
32
+ }
33
+
34
+ /** 최초 graph variant 선택 — id·선택 이유가 런 원장 옆 .graph.yaml 에 함께 저장되고 재조회된다. */
35
+ export interface GraphVariantSelection {
36
+ readonly variantId: string;
37
+ readonly reason: string;
38
+ }
39
+
27
40
  export type GraphVariantRejection =
28
41
  | { readonly kind: 'invalid-goal' }
29
42
  | { readonly kind: 'unknown-node'; readonly node: string }
@@ -35,25 +48,46 @@ export type GraphVariantRejection =
35
48
  | { readonly kind: 'unreachable-terminal'; readonly node: string }
36
49
  | { readonly kind: 'invalid-graph'; readonly defects: ReturnType<typeof inspectPipelineGraph> }
37
50
  | { readonly kind: 'overlay-rejected'; readonly rejections: readonly OverlayRejection[] }
38
- | { readonly kind: 'invalid-growth'; readonly reason: string };
51
+ | { readonly kind: 'invalid-growth'; readonly reason: string }
52
+ | { readonly kind: 'invalid-goal-analysis' };
39
53
 
40
54
  export type GraphVariantResult =
41
- | { readonly ok: true; readonly overlay: GraphOverlaySpec; readonly template: GraphTemplateSpec; readonly patches: readonly OverlayPatchOp[] }
55
+ | { readonly ok: true; readonly overlay: GraphOverlaySpec; readonly template: GraphTemplateSpec; readonly patches: readonly OverlayPatchOp[]; readonly selection?: GraphVariantSelection }
42
56
  | { readonly ok: false; readonly rejections: readonly GraphVariantRejection[] };
43
57
 
58
+ /** 최초 변형 선택(id·선택 이유)의 결정론적 유도 — 같은 종류·대상 경로 수면 항상 같은 값을 낸다. */
59
+ export function initialGraphVariantSelection(analysis: GraphVariantGoalAnalysis): GraphVariantSelection {
60
+ const variantId = `variant-${analysis.goalType}-${createHash('sha256')
61
+ .update(JSON.stringify({ goalType: analysis.goalType, targetPathCount: analysis.targetPathCount }))
62
+ .digest('hex').slice(0, 12)}`;
63
+ return {
64
+ variantId,
65
+ reason: `initial graph variant selected from goal type ${analysis.goalType} with ${analysis.targetPathCount} target path${analysis.targetPathCount === 1 ? '' : 's'}`,
66
+ };
67
+ }
68
+
44
69
  /** Pure, deterministic variant authoring. Never mutates the supplied template and never writes an overlay. */
45
70
  export function createGraphVariant(input: {
46
71
  readonly template: GraphTemplateSpec;
47
72
  readonly goal: string;
48
73
  readonly plan: GraphVariantPlan;
74
+ readonly goalAnalysis?: GraphVariantGoalAnalysis;
49
75
  }): GraphVariantResult {
50
- const { template, goal, plan } = input;
76
+ const { template, goal, plan, goalAnalysis } = input;
51
77
  const known = new Set(template.nodes.map((node) => node.nodeId));
52
78
  const rejections: GraphVariantRejection[] = [];
53
79
  if (!/^g_[a-z0-9_-]+$/i.test(goal)) rejections.push({ kind: 'invalid-goal' });
80
+ let selection: GraphVariantSelection | undefined;
81
+ if (goalAnalysis !== undefined) {
82
+ if (!GOAL_TYPES.includes(goalAnalysis.goalType) || !Number.isSafeInteger(goalAnalysis.targetPathCount) || goalAnalysis.targetPathCount < 0) {
83
+ rejections.push({ kind: 'invalid-goal-analysis' });
84
+ } else {
85
+ selection = initialGraphVariantSelection(goalAnalysis);
86
+ }
87
+ }
54
88
  if (plan.growth) {
55
89
  const { node, from, outcome, returnTo } = plan.growth;
56
- if (!node || typeof node !== 'object') return { ok: false, rejections: [{ kind: 'invalid-growth', reason: 'growth requires one new contracted node' }] };
90
+ if (!node || typeof node !== 'object') return { ok: false, rejections: [...rejections, { kind: 'invalid-growth', reason: 'growth requires one new contracted node' }] };
57
91
  const edgeIndex = template.edges.findIndex((edge) => edge.from === from);
58
92
  const edge = template.edges[edgeIndex];
59
93
  if (!known.has(from) || known.has(node.nodeId) || template.terminalNodes.includes(from) ||
@@ -94,7 +128,7 @@ export function createGraphVariant(input: {
94
128
  }
95
129
  const unreachable = projected.terminalNodes.filter((terminal) => !reached.has(terminal) || (edges[terminal]?.length ?? 0) !== 0);
96
130
  if (unreachable.length) return { ok: false, rejections: unreachable.map((terminal) => ({ kind: 'unreachable-terminal', node: terminal })) };
97
- return { ok: true, overlay, template: projected, patches };
131
+ return { ok: true, overlay, template: projected, patches, ...(selection === undefined ? {} : { selection }) };
98
132
  }
99
133
  const patches: OverlayPatchOp[] = [];
100
134
 
@@ -167,5 +201,5 @@ export function createGraphVariant(input: {
167
201
  })) };
168
202
  const applied = applyGraphOverlays(validationTemplate, [overlay]);
169
203
  if (!applied.ok) return { ok: false, rejections: [{ kind: 'overlay-rejected', rejections: applied.rejections }] };
170
- return { ok: true, overlay, template: projected, patches };
204
+ return { ok: true, overlay, template: projected, patches, ...(selection === undefined ? {} : { selection }) };
171
205
  }
@@ -72,6 +72,12 @@ import { setEventLoopActivity } from '../debug/event-loop-watchdog.js';
72
72
  import { resolveEscalateTarget, resolveExplicitChildEscalateTarget } from './rework-policy.js';
73
73
  import { tailWithOmissionMarker } from './off-diff-evidence.js';
74
74
  import type { EscalateTier } from './rework-policy.js';
75
+
76
+ const VERIFIED_PR_SUPERVISOR_INPUT = 'PR source already verified. Implement the requested repair in this worktree now.';
77
+
78
+ function supervisorInputForSource(input: string, verifiedPrSource: boolean | undefined): string {
79
+ return verifiedPrSource ? VERIFIED_PR_SUPERVISOR_INPUT : input;
80
+ }
75
81
  import { readRunLifecycleFromStateDir } from '../signal/lifecycle-bridge.js';
76
82
  import { lifecycleRootReportEnv, lifecycleRootReportPath, readLifecycleRootReport, removeLifecycleRootReport } from '../signal/lifecycle-root-report.js';
77
83
  import { compareLifecycleToScreen, type LifecycleScreenComparison } from './lifecycle-screen-scoreboard.js';
@@ -967,6 +973,8 @@ export interface HeadlessGoalLoopPtyOptions {
967
973
  sendOutbound?: typeof sendOutbound;
968
974
  /** Queues an argv child supervisor input for the orchestrator's next-round prompt; never writes stdin. */
969
975
  onSupervisorInput?: (text: string, updateDelivery: (delivery: SupervisorDeliveryState, reason?: string) => void) => void;
976
+ /** The Pod has already checked out its pinned PR source. Supervisor input must not relaunch it. */
977
+ verifiedPrSource?: boolean;
970
978
  /** ★ 턴 abort 신호(#21) — /cancel 이 이 신호를 abort 하면 호스팅 PTY 를 즉시 kill + 폴 루프 조기 종료
971
979
  * (고아 자식 프로세스 방지). 미주입 시 종전대로 exit/GOAL-COMPLETE/타임아웃까지 폴. */
972
980
  signal?: AbortSignal;
@@ -1720,7 +1728,7 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1720
1728
  // pipeline with a synthetic wait, whose evidence is honestly `action-wait`; calling
1721
1729
  // the brain would violate the no-consultation boundary, while weakening brainCalls
1722
1730
  // would hide that boundary instead of preserving it.
1723
- const decision: ControlDecision = blockedWrite
1731
+ const suggestedDecision: ControlDecision = blockedWrite
1724
1732
  ? { action: 'wait' }
1725
1733
  : await Promise.race([
1726
1734
  Promise.resolve(opts.brain.decide(controlObs, controller.signal)),
@@ -1735,6 +1743,13 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
1735
1743
  }),
1736
1744
  ...(parentAbort ? [parentAbort] : []),
1737
1745
  ]);
1746
+ // The supervisor suggestion is untrusted text. In a PR-source Pod the
1747
+ // source was verified before this process started, so any proposed
1748
+ // input is reduced to an implementation instruction before it can
1749
+ // reach either the child queue or the parent progress surface.
1750
+ const decision: ControlDecision = opts.verifiedPrSource && suggestedDecision.action === 'input'
1751
+ ? { action: 'input', text: supervisorInputForSource(suggestedDecision.text, opts.verifiedPrSource) }
1752
+ : suggestedDecision;
1738
1753
  const actionDetail = decision.action === 'input'
1739
1754
  ? decision.text.slice(0, 120)
1740
1755
  : decision.action === 'done' || decision.action === 'no-progress' ? decision.reason.slice(0, 120) : '';
@@ -2015,11 +2030,12 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
2015
2030
  });
2016
2031
  if (artifactDecision.kind === 'escalate-terminal-success') {
2017
2032
  reachedCompletion = false;
2033
+ const restartPacket = supervisorInputForSource(artifactDecision.restartPacket, opts.verifiedPrSource);
2018
2034
  debug.log('self-implement', 'headless.output-artifact-intervention', {
2019
2035
  ptyId, runId, kind: artifactDecision.kind, missing: artifactDecision.missing,
2020
- diagnostic: artifactDecision.diagnostic, restartPacket: artifactDecision.restartPacket,
2036
+ diagnostic: artifactDecision.diagnostic, restartPacket,
2021
2037
  }, { level: 'warn' });
2022
- opts.onSupervisorInput?.(artifactDecision.restartPacket, () => {});
2038
+ opts.onSupervisorInput?.(restartPacket, () => {});
2023
2039
  }
2024
2040
  }
2025
2041
  if (exitReason === 'loop-exhausted-without-completion' && reachedCompletion) {
@@ -3,6 +3,7 @@
3
3
  import { requirePosixShellCommand } from '../platform/default-shell.js';
4
4
  import { spawnSync } from 'node:child_process';
5
5
  import { debug } from '../debug/log.js';
6
+ import { narrowerEvidenceCommand } from './evidence-command-budget.js';
6
7
  import { resolveRunIdentity } from '../harness/harness-space.js';
7
8
  //
8
9
  // ⛔ **왜 필요한가** — 리뷰어의 증거 채널은 워크트리 diff 하나다(`seams.ts` 의 `reviewDiff`).
@@ -320,14 +321,21 @@ export function authorLimitationCountFromGoal(goal: string): number {
320
321
  * 추론된다. 위 두 타입과 같은 규율이다(죽은 공개 표면은 계약처럼 읽힌다 · 리뷰 must-fix). */
321
322
  interface RequiredEvidenceCheckRun {
322
323
  readonly tag: string;
324
+ /** Command required by the authored goal, even if a diagnostic substitute ran. */
323
325
  readonly command: string;
326
+ /** Command actually run; absent when the timeout budget stopped execution. */
327
+ readonly executedCommand?: string;
324
328
  readonly exitCode: number | null;
325
329
  readonly stdout: string;
326
330
  /** EVIDENCE-WIRING-EXEMPT — `bun test` writes its «N pass / 0 fail» summary to stderr. */
327
331
  readonly stderr: string;
328
332
  readonly durationMs: number;
333
+ /** A narrower smoke check diagnoses the timeout but cannot prove the original requirement. */
334
+ readonly substitutedFor?: string;
329
335
  }
330
336
 
337
+ type EvidenceCommandRunner = (command: string, cwd: string) => Pick<ReturnType<typeof spawnSync>, 'status' | 'stdout' | 'stderr' | 'error'>;
338
+
331
339
  /**
332
340
  * ★ `I-24` / `RUN-T6` — 골에서 **요구된 증거**를 읽는다. **순수**.
333
341
  *
@@ -394,7 +402,7 @@ export function goalDeclaresNoWiring(goal: string): boolean {
394
402
 
395
403
  /** A `bun test` check that ran its tests and failed none: rc 0 ⊕ «N pass» (N ≥ 1) ⊕ «0 fail» in its output. */
396
404
  function bunTestCheckPassed(run: RequiredEvidenceCheckRun): boolean {
397
- if (run.exitCode !== 0 || !/(?:^|[\s;&|(])bun\s+(?:run\s+)?test\b/.test(run.command)) return false;
405
+ if (run.substitutedFor || run.exitCode !== 0 || !/(?:^|[\s;&|(])bun\s+(?:run\s+)?test\b/.test(run.executedCommand ?? run.command)) return false;
398
406
  const output = `${run.stdout}\n${run.stderr}`;
399
407
  return /(?:^|\n)\s*[1-9]\d*\s+pass\b/.test(output) && /(?:^|\n)\s*0\s+fail\b/.test(output);
400
408
  }
@@ -418,20 +426,46 @@ export function settleUncoveredEvidence(
418
426
  }
419
427
 
420
428
  /** 골 작성자가 요구 줄에 명시한 셸 체크를 하니스 worktree에서 관측한다. `bun test` 체크의 통과는
421
- * settleUncoveredEvidence 가 그 요구의 덮임으로 받는다(EVIDENCE-WIRING-EXEMPT). */
422
- export function runRequiredEvidenceChecks(goal: string, cwd: string, runId?: string): RequiredEvidenceCheckRun[] {
429
+ * settleUncoveredEvidence 가 그 요구의 덮임으로 받는다(EVIDENCE-WIRING-EXEMPT).
430
+ * 단독 호출에 timeoutCounts/headCommit을 주지 않으면 재시도 예산이 없다. 실제 라운드 호출자는
431
+ * run 단위 createRequiredEvidenceBudget을 써야 HEAD 미확인 때도 임시 예산이 적용된다. */
432
+ export function runRequiredEvidenceChecks(goal: string, cwd: string, runId?: string, options: {
433
+ timeoutCounts?: Map<string, number>;
434
+ headCommit?: string;
435
+ run?: EvidenceCommandRunner;
436
+ } = {}): RequiredEvidenceCheckRun[] {
423
437
  const identity = resolveRunIdentity({ explicit: runId });
424
438
  const checks = requiredEvidenceFromGoal(goal).flatMap(({ tag, verifyCommand }) => verifyCommand ? [{ tag, command: verifyCommand }] : []);
439
+ // Direct callers without a measured HEAD have no stable revision identity;
440
+ // the run-owned wrapper supplies a temporary identity when appropriate.
441
+ const timeoutCounts = options.headCommit ? options.timeoutCounts : undefined;
442
+ const budgetKey = (command: string) => `${options.headCommit ?? ''}\0${command}`;
425
443
  const runs = checks.map(({ tag, command }) => {
426
444
  const startedAt = Date.now();
427
- const result = spawnSync(requirePosixShellCommand('/bin/sh'), ['-c', command], { cwd, encoding: 'utf8', timeout: 180_000, maxBuffer: 32 * 1024 * 1024 });
445
+ const priorTimeouts = timeoutCounts?.get(budgetKey(command)) ?? 0;
446
+ const replacement = priorTimeouts >= 2 ? narrowerEvidenceCommand(command, cwd) : null;
447
+ const executedCommand = replacement ?? command;
448
+ const replacementTimeouts = replacement ? (timeoutCounts?.get(budgetKey(replacement)) ?? 0) : 0;
449
+ if (priorTimeouts >= 2 && (!replacement || replacementTimeouts >= 2)) {
450
+ try { debug.log('self-implement.evidence', 'command-budget-stop', { runId: identity.runId, command, replacement, timeoutCount: priorTimeouts, replacementTimeoutCount: replacementTimeouts }); } catch { /* observation is fail-soft */ }
451
+ return { tag, command, exitCode: null, stdout: '', stderr: 'Evidence command timed out twice; no further identical test run was attempted.', durationMs: 0 };
452
+ }
453
+ if (replacement) {
454
+ try { debug.log('self-implement.evidence', 'command-budget-switch', { runId: identity.runId, from: command, to: replacement, timeoutCount: priorTimeouts }); } catch { /* observation is fail-soft */ }
455
+ }
456
+ const result = options.run?.(executedCommand, cwd)
457
+ ?? spawnSync(requirePosixShellCommand('/bin/sh'), ['-c', executedCommand], { cwd, encoding: 'utf8', timeout: 180_000, maxBuffer: 32 * 1024 * 1024 });
458
+ const timedOut = result.error && 'code' in result.error && result.error.code === 'ETIMEDOUT';
459
+ if (timedOut && timeoutCounts) timeoutCounts.set(budgetKey(executedCommand), (timeoutCounts.get(budgetKey(executedCommand)) ?? 0) + 1);
428
460
  return {
429
461
  tag,
430
462
  command,
463
+ executedCommand,
431
464
  exitCode: result.status,
432
- stdout: tailWithOmissionMarker(result.stdout ?? '', MAX_OFF_DIFF_EVIDENCE_RESULT_CHARS),
433
- stderr: tailWithOmissionMarker(result.stderr ?? '', MAX_OFF_DIFF_EVIDENCE_RESULT_CHARS),
465
+ stdout: tailWithOmissionMarker(typeof result.stdout === 'string' ? result.stdout : result.stdout?.toString('utf8') ?? '', MAX_OFF_DIFF_EVIDENCE_RESULT_CHARS),
466
+ stderr: tailWithOmissionMarker(typeof result.stderr === 'string' ? result.stderr : result.stderr?.toString('utf8') ?? '', MAX_OFF_DIFF_EVIDENCE_RESULT_CHARS),
434
467
  durationMs: Date.now() - startedAt,
468
+ ...(replacement ? { substitutedFor: command } : {}),
435
469
  };
436
470
  });
437
471
  const observation = { count: runs.length, runs };
@@ -443,6 +477,24 @@ export function runRequiredEvidenceChecks(goal: string, cwd: string, runId?: str
443
477
  return runs;
444
478
  }
445
479
 
480
+ /** One self-implement run owns this state; a changed HEAD starts a fresh budget. */
481
+ export function createRequiredEvidenceBudget(options: { run?: EvidenceCommandRunner } = {}): (
482
+ goal: string, cwd: string, runId: string | undefined, headCommit: string | undefined,
483
+ ) => RequiredEvidenceCheckRun[] {
484
+ let previousHead: string | undefined;
485
+ const timeoutCounts = new Map<string, number>();
486
+ // This closure is created once per self-implement run. Its unresolved key
487
+ // bounds repeats within that run without pooling with another run or SHA.
488
+ const unresolvedRunHead = 'unresolved-head-within-this-run';
489
+ return (goal, cwd, runId, headCommit) => {
490
+ if (previousHead !== headCommit) {
491
+ timeoutCounts.clear();
492
+ previousHead = headCommit;
493
+ }
494
+ return runRequiredEvidenceChecks(goal, cwd, runId, { timeoutCounts, headCommit: headCommit ?? unresolvedRunHead, run: options.run });
495
+ };
496
+ }
497
+
446
498
  /** 자식 프롬프트에 실을 요구 목록. 요구가 없으면 **아무 줄도 안 붙인다**(빈 계약을 만들지 않는다). */
447
499
  export function renderRequiredEvidencePrompt(items: readonly RequiredEvidenceItem[]): string[] {
448
500
  if (!items.length) return [];