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
@@ -17,14 +17,14 @@ import { dirname, join, resolve } from 'node:path';
17
17
  import { fileURLToPath } from 'node:url';
18
18
 
19
19
  import { debug } from '../debug/log.js';
20
- import { createHerdrAgentReporter, type HerdrAgentReporterLike } from './herdr-agent-report.js';
20
+ import { createHerdrAgentReporter, guardHerdrReleaseOnSignal, type HerdrAgentReporterLike, type HerdrSignalTarget } from './herdr-agent-report.js';
21
21
  import { runGitCommand } from '../git-fs/runner.js';
22
22
  import { codeRevision, packageVersion, readInstallMetadataCommit } from '../version/code-revision.js';
23
23
  import {
24
24
  buildStaleInstallRelaunchCommand,
25
25
  formatStaleInstallNotice,
26
26
  versionedDashboardInstallDir,
27
- } from '../dashboard/stale-install-check.js';
27
+ } from './stale-install-check.js';
28
28
  import {
29
29
  updatePtyManifestBuild, updatePtyManifestTurn,
30
30
  type PtyBuildIdentity, type PtyManifestRow, type PtyTurnState,
@@ -321,6 +321,11 @@ export interface TuiRunStateRecorderDeps {
321
321
  * `null` 이면 신고하지 않는다.
322
322
  */
323
323
  readonly herdr?: HerdrAgentReporterLike | null;
324
+ /**
325
+ * SIGINT·SIGTERM 기본 죽음에도 herdr 를 반납하는 신호 지킴이의 대상(TUI-HERDR-EXIT-RACE).
326
+ * 생략 시: 기본 신고기(herdr 미주입)일 때만 실 `process` · 주입 herdr 는 지킴이 0. `null` 이면 안 건다.
327
+ */
328
+ readonly signals?: HerdrSignalTarget | null;
324
329
  }
325
330
 
326
331
  interface ActiveRecorder {
@@ -361,7 +366,14 @@ export function startTuiRunStateRecorder(surfaceId: string, deps: TuiRunStateRec
361
366
  active = recorder;
362
367
  writeTurnState(recorder, 'idle');
363
368
  if (herdr) { try { herdr.start(); } catch { /* 신고 실패가 녹음기를 깨지 않는다 */ } }
369
+ // raw 모드 전 ctrl+c(SIGINT 기본 죽음)는 'exit' 훅을 안 돌린다 — 신호에서도 반납한다.
370
+ const signals = deps.signals !== undefined ? deps.signals : (deps.herdr === undefined ? process : null);
371
+ let unguard: () => void = () => {};
372
+ if (herdr && signals) {
373
+ try { unguard = guardHerdrReleaseOnSignal(() => herdr.release(), signals); } catch { /* 지킴이 실패가 녹음기를 깨지 않는다 */ }
374
+ }
364
375
  return () => {
376
+ try { unguard(); } catch { /* 종료 경로를 깨지 않는다 */ }
365
377
  if (herdr) { try { herdr.release(); } catch { /* 종료 경로를 깨지 않는다 */ } }
366
378
  if (active === recorder) active = null;
367
379
  };
@@ -21,9 +21,13 @@ export type AutoStartDeferral = { deferred: true; reason: Exclude<ReleaseReadine
21
21
  export type AutoStartResult =
22
22
  | { status: 'no-cut' }
23
23
  | { status: 'planned'; version: string; cutAt: string }
24
- | { status: 'skipped'; version: string; reason: AutoStartDeferral['reason'] }
24
+ | { status: 'skipped'; version: string; reason: Exclude<AutoStartDeferral['reason'], 'already-running'> }
25
+ /** A live run of the selected version is a refusal (rc1), not a quiet deferral — the reason names that run. */
26
+ | { status: 'already-running'; version: string; runId: string; pid: number; startedAt: string }
25
27
  | { status: 'started'; version: string; cutAt: string; publishAt?: string };
26
28
 
29
+ export interface AutoStartActiveRun { runId: string; pid: number; startedAt: string }
30
+
27
31
  export interface AutoStartOptions {
28
32
  windowMinutes: number;
29
33
  apply?: boolean;
@@ -31,6 +35,8 @@ export interface AutoStartOptions {
31
35
  ledgerRoot?: string;
32
36
  schedules?: (root: string) => ReleaseSchedule[];
33
37
  readiness?: (version: string, ledgerRoot: string, now: Date) => ReleaseReadiness;
38
+ /** The live run of `version` (graph-run ledger · force marker · run.lock), asked before readiness on `--apply`. */
39
+ activeRun?: (version: string, ledgerRoot: string) => AutoStartActiveRun | undefined;
34
40
  launch?: (version: string, launchOptions?: { publishAt?: string }) => void | AutoStartDeferral | Promise<void | AutoStartDeferral>;
35
41
  }
36
42
 
@@ -43,11 +49,23 @@ export async function autoStartScheduledRelease(options: AutoStartOptions): Prom
43
49
  if (!schedule) return { status: 'no-cut' };
44
50
  const { version, cutAt, publishAt } = schedule;
45
51
  if (!options.apply) return { status: 'planned', version, cutAt };
52
+ const refuse = (run: AutoStartActiveRun): AutoStartResult => {
53
+ debug.log('release.schedule', 'auto-start-already-running', { version, cutAt, ...run });
54
+ return { status: 'already-running', version, ...run };
55
+ };
56
+ const active = options.activeRun?.(version, root);
57
+ if (active) return refuse(active);
46
58
  const readiness = (options.readiness ?? ((v, ledgerRoot, at) => releaseReadiness(v, { ledgerRoot, now: () => at })))(version, root, now);
59
+ // A live run.lock without a resolvable run identity still refuses; its pid is the readiness detail.
60
+ if (!readiness.ready && readiness.reason === 'already-running') return refuse({ runId: 'pending', pid: Number(readiness.details), startedAt: 'unknown' });
47
61
  if (!readiness.ready) return { status: 'skipped', version, reason: readiness.reason };
48
62
  if (!options.launch) throw new Error('auto-start apply requires a launch callback');
49
63
  const launched = await options.launch(version, publishAt != null ? { publishAt: publishAt } : {});
50
- if (launched?.deferred) return { status: 'skipped', version, reason: launched.reason };
64
+ if (launched?.deferred) {
65
+ const { reason } = launched;
66
+ if (reason === 'already-running') return refuse(options.activeRun?.(version, root) ?? { runId: 'pending', pid: 0, startedAt: 'unknown' });
67
+ return { status: 'skipped', version, reason };
68
+ }
51
69
  debug.log('release.schedule', 'auto-start', { version, cutAt, publishAt: publishAt ?? null });
52
70
  return { status: 'started', version, cutAt, ...(publishAt != null ? { publishAt: publishAt } : {}) };
53
71
  }
@@ -13,6 +13,15 @@ export type ChecklistKind = 'screen' | 'postpub';
13
13
  const CHECKLIST_KINDS: readonly ChecklistKind[] = ['screen', 'postpub'];
14
14
  export type ChecklistDispatchKind = 'code' | 'ops' | 'measure' | 'decision' | 'umbrella';
15
15
  const CHECKLIST_DISPATCH_KINDS: readonly ChecklistDispatchKind[] = ['code', 'ops', 'measure', 'decision', 'umbrella'];
16
+ /** MUST 지정 — 이 칸이 지켜야 하는 조건과 그 효과. 원장에는 `must` 이벤트(전체 값)로만 실린다. */
17
+ export interface ChecklistMust {
18
+ version: string;
19
+ reason: string;
20
+ setBy: string;
21
+ setAt: string;
22
+ effect: string;
23
+ }
24
+ const MUST_FIELDS = ['version', 'reason', 'setBy', 'setAt', 'effect'] as const;
16
25
  export interface ChecklistItem {
17
26
  id: string;
18
27
  title: string;
@@ -32,6 +41,8 @@ export interface ChecklistItem {
32
41
  kind?: ChecklistKind;
33
42
  /** Whether the seat dispatcher should launch a coding task. Missing in old rows means code. */
34
43
  dispatchKind?: ChecklistDispatchKind;
44
+ /** MUST 지정(있으면 이 칸은 MUST 다). 원장 스키마에 must 컬럼이 없어 `must` 이벤트에서 복원한다. */
45
+ must?: ChecklistMust;
35
46
  updatedAt: string;
36
47
  updatedBy: string;
37
48
  }
@@ -92,13 +103,51 @@ function decodeClaimHistory(data: Checklist): Checklist {
92
103
  return { ...data, history: data.history.map(decodeClaimHistoryEntry) };
93
104
  }
94
105
 
106
+ /** A `must` event carries the whole MUST value in `to`; anything that is not five strings is not a MUST. */
107
+ function mustValue(value: unknown): ChecklistMust | null {
108
+ if (!value || typeof value !== 'object') return null;
109
+ const record = value as Record<string, unknown>;
110
+ if (!MUST_FIELDS.every((field) => typeof record[field] === 'string')) return null;
111
+ return { version: record.version as string, reason: record.reason as string, setBy: record.setBy as string, setAt: record.setAt as string, effect: record.effect as string };
112
+ }
113
+
114
+ function decodeMustEntry<T extends ChecklistHistory>(entry: T): T {
115
+ if (entry.field !== 'must') return entry;
116
+ const must = mustValue(entry.to);
117
+ return must ? { ...entry, to: must } as T : entry;
118
+ }
119
+
120
+ /** The ledger event schema has no must column either; the last `must` event is this cell's MUST. */
121
+ function decodeMustHistory(data: Checklist): Checklist {
122
+ const latest = new Map<string, ChecklistMust>();
123
+ for (const entry of data.history) {
124
+ if (entry.field !== 'must') continue;
125
+ const must = mustValue(entry.to);
126
+ if (must) latest.set(entry.id, must);
127
+ }
128
+ if (!latest.size) return data;
129
+ return { ...data, items: data.items.map((item) => {
130
+ const must = latest.get(item.id);
131
+ return must ? { ...item, must } : item;
132
+ }) };
133
+ }
134
+
135
+ function latestMust(history: readonly ChecklistHistory[], id: string): ChecklistMust | null {
136
+ for (let index = history.length - 1; index >= 0; index--) {
137
+ const entry = history[index]!;
138
+ if (entry.id !== id || entry.field !== 'must') continue;
139
+ return mustValue(entry.to);
140
+ }
141
+ return null;
142
+ }
143
+
95
144
  export function listChecklist(v: string, root?: string): Checklist {
96
- return decodeClaimHistory(root === undefined ? store.list(v) : store.list(v, undefined, undefined, root));
145
+ return decodeMustHistory(decodeClaimHistory(root === undefined ? store.list(v) : store.list(v, undefined, undefined, root)));
97
146
  }
98
147
 
99
148
  /** Events for this id across every release, ordered by event time (then ledger sequence). */
100
149
  export function checklistHistory(id: string): Array<ChecklistHistory & { version: string; seq: number }> {
101
- return store.history(id).map(decodeClaimHistoryEntry);
150
+ return store.history(id).map((entry) => decodeMustEntry(decodeClaimHistoryEntry(entry)));
102
151
  }
103
152
 
104
153
  /** Status events in the requested window; other ledger fields never become status changes. */
@@ -116,8 +165,8 @@ function assertPredecessorsExist(predecessors: readonly string[] | undefined, da
116
165
  }
117
166
 
118
167
  function mutate(v: string, apply: (data: Checklist, otherItems: (id: string) => store.ChecklistCollision[]) => boolean): Checklist {
119
- // addItem/setItem/claimItem/removeItem/seedFromRoadmap reach the generation-fenced ledger write here.
120
- return decodeClaimHistory(store.mutate(v, store.releasedVersion(), devVersion(), apply));
168
+ // addItem/setItem/claimItem/removeItem/seedFromRoadmap/setMust reach the generation-fenced ledger write here.
169
+ return decodeMustHistory(decodeClaimHistory(store.mutate(v, store.releasedVersion(), devVersion(), apply)));
121
170
  }
122
171
 
123
172
  function change(data: Checklist, id: string, field: string, from: unknown, to: unknown, by: string, at: string): void {
@@ -360,6 +409,29 @@ export function setItem(v: string, id: string, patch: { status?: ChecklistStatus
360
409
  return setItemGuarded(v, id, patch, by);
361
410
  }
362
411
 
412
+ /** 효과 없는 MUST 는 게이트가 판단할 근거가 없다 — 거부한다. */
413
+ function validateMust(must: ChecklistMust): ChecklistMust {
414
+ if (!must.effect.trim()) throw new CliUserError('MUST 효과가 비었다', "release checklist must <id> --effect '<게이트에 미치는 효과>'");
415
+ return must;
416
+ }
417
+
418
+ /** 이 칸의 MUST 를 세운다. 저장은 `must` 이벤트(from = 이전 전체 값, to = 새 전체 값)로만 하고, 다른 칸 행은 건드리지 않는다. */
419
+ export function setMust(v: string, id: string, input: { version: string; reason: string; effect: string }, by: string): Checklist {
420
+ if (!by.trim()) throw new CliUserError('MUST 기록 주체가 비었다');
421
+ const at = new Date().toISOString();
422
+ const must = validateMust({ version: input.version, reason: input.reason, setBy: by, setAt: at, effect: input.effect });
423
+ return mutate(v, (data) => {
424
+ const item = data.items.find((entry) => entry.id === id);
425
+ if (!item) throw new CliUserError(`없는 칸: ${id}`, 'list 로 칸 목록을 본다');
426
+ const previous = latestMust(data.history, id);
427
+ if (previous && JSON.stringify(previous) === JSON.stringify(must)) return false;
428
+ item.updatedAt = at;
429
+ item.updatedBy = by;
430
+ change(data, id, 'must', previous, must, by, at);
431
+ return true;
432
+ });
433
+ }
434
+
363
435
  /** Remove only the exact machine-authored line; preserve all other evidence bytes and blank lines. */
364
436
  export function withoutDispatchSkipLine(evidence: string, line: string | null): string {
365
437
  if (!line) return evidence;
@@ -186,26 +186,23 @@ export function runRehearsalLeakCheck(checkout: string): { status: number | null
186
186
  } finally { rmSync(out, { recursive: true, force: true }); }
187
187
  }
188
188
 
189
- /** The hard rehearsal uses the release gate itself, pinned to the fetched main SHA and node-b Pod member. */
190
- async function runHardGate(version: string, checkout: string, sha: string, ledgerRoot: string, runId: string): Promise<HardGateResult> {
191
- const configuredPool = releaseLoopConfig().gatePodPool;
192
- if (!configuredPool) throw new Error('hard rehearsal requires release.loop.gatePodPool');
193
- const members = parsePodPool(configuredPool);
194
- const gateMember = members.find(member => member.sshHost === 'node-b');
195
- if (!gateMember) throw new Error('hard rehearsal requires a live node-b Pod member');
196
- const pool = configuredPool.split(',').map(part => part.trim())
197
- .find(part => part.split(/[#:]/, 1)[0] === `${gateMember.context}@${gateMember.sshHost}`);
198
- if (!pool) throw new Error('hard rehearsal cannot isolate the node-b Pod member');
199
- const previous = latestPublishedPreviousVersion(version, ledgerRoot);
200
- const logPath = join(ledgerRoot, 'release', version, 'rehearsal', `${runId}.log`);
201
- mkdirSync(dirname(logPath), { recursive: true });
202
- const run = (() => {
203
- const log = openSync(logPath, 'wx', 0o600);
204
- try { return spawnSync('bun', hardRehearsalGateArgs(version, runId, sha, previous, pool), {
205
- cwd: checkout, encoding: 'utf8', stdio: ['ignore', log, log], timeout: 4 * 60 * 60_000,
206
- env: { ...process.env, ELANOUS_STATE_DIR: ledgerRoot, ELANOUS_STATE_DIR_SOURCE: stateDirSourceForChild(ledgerRoot) },
207
- }); } finally { closeSync(log); }
208
- })();
189
+ /** Run the exact hard-gate subprocess with an isolated clock budget for timeout replay. */
190
+ export function spawnHardRehearsalGate(opts: {
191
+ binary: string; args: string[]; checkout: string; ledgerRoot: string; logPath: string; timeoutMs: number; sha: string;
192
+ }): HardGateResult {
193
+ mkdirSync(dirname(opts.logPath), { recursive: true });
194
+ const log = openSync(opts.logPath, 'wx', 0o600);
195
+ let run: ReturnType<typeof spawnSync>;
196
+ try {
197
+ run = spawnSync(opts.binary, opts.args, {
198
+ cwd: opts.checkout, encoding: 'utf8', stdio: ['ignore', log, log], timeout: opts.timeoutMs,
199
+ env: { ...process.env, ELANOUS_STATE_DIR: opts.ledgerRoot, ELANOUS_STATE_DIR_SOURCE: stateDirSourceForChild(opts.ledgerRoot) },
200
+ });
201
+ } finally { closeSync(log); }
202
+ return parseHardRehearsalGateResult(run, opts.logPath, opts.sha);
203
+ }
204
+
205
+ function parseHardRehearsalGateResult(run: ReturnType<typeof spawnSync>, logPath: string, sha: string): HardGateResult {
209
206
  // stdout and stderr stream to the claim's durable evidence while the child is still running.
210
207
  const output = readFileSync(logPath, 'utf8');
211
208
  const line = output.split(/\r?\n/).reverse().find(value => value.trim().startsWith('{'));
@@ -225,6 +222,25 @@ async function runHardGate(version: string, checkout: string, sha: string, ledge
225
222
  throw new Error(`hard rehearsal gate rc=${run.status ?? 'spawn'} disagrees with outcome=${result.outcome}`);
226
223
  }
227
224
 
225
+ /** The hard rehearsal uses the release gate itself, pinned to the fetched main SHA and node-b Pod member. */
226
+ async function runHardGate(version: string, checkout: string, sha: string, ledgerRoot: string, runId: string): Promise<HardGateResult> {
227
+ const configuredPool = releaseLoopConfig().gatePodPool;
228
+ if (!configuredPool) throw new Error('hard rehearsal requires release.loop.gatePodPool');
229
+ const members = parsePodPool(configuredPool);
230
+ const gateMember = members.find(member => member.sshHost === 'node-b');
231
+ if (!gateMember) throw new Error('hard rehearsal requires a live node-b Pod member');
232
+ const pool = configuredPool.split(',').map(part => part.trim())
233
+ .find(part => part.split(/[#:]/, 1)[0] === `${gateMember.context}@${gateMember.sshHost}`);
234
+ if (!pool) throw new Error('hard rehearsal cannot isolate the node-b Pod member');
235
+ const previous = latestPublishedPreviousVersion(version, ledgerRoot);
236
+ const logPath = join(ledgerRoot, 'release', version, 'rehearsal', `${runId}.log`);
237
+ mkdirSync(dirname(logPath), { recursive: true });
238
+ return spawnHardRehearsalGate({
239
+ binary: 'bun', args: hardRehearsalGateArgs(version, runId, sha, previous, pool),
240
+ checkout, ledgerRoot, logPath, timeoutMs: 4 * 60 * 60_000, sha,
241
+ });
242
+ }
243
+
228
244
  function oneLine(text: string): string { return text.replace(/\s+/g, ' ').trim(); }
229
245
 
230
246
  function outcomeLine(stamp: RehearsalStamp): string {
package/src/repl/index.ts CHANGED
@@ -50,6 +50,7 @@ import { parse as parseYaml } from 'yaml';
50
50
  import type { PendingTaskNotification } from '../agent/task-notification.js';
51
51
  import { dispatchReplMessageTool, isReplMessageTool } from './ops-msg-bridge.js';
52
52
  import { buildSeatBootSystemMessages, type SeatBootDeps } from '../dashboard/seat-boot-preamble.js';
53
+ import { installNextTuiSelfHealthTracker } from '../tui/chat/self-health-status.js';
53
54
 
54
55
  /** Private side channel for the next TUI. Ordinary REPL JSONL stdout is unchanged. */
55
56
  const NEXT_TUI_BG_PREFIX = 'ELANOUS_TUI_BG_STATUS\t';
@@ -189,6 +190,14 @@ function buildReplTools(): {
189
190
  const bashMod = require('../skills/tools/index.js') as typeof import('../skills/tools/index.js');
190
191
  specs.push(bashMod.buildBashTool());
191
192
  dispatchByName.set('Bash', async (args) => bashMod.dispatchBash(args, { cwd: process.cwd() }));
193
+ // TUI-NEXT-QUEUE-AND-WAKE: the next TUI parent opens an IPC hop only for its own REPL children;
194
+ // the classic ScheduleWakeup spec is advertised and each call is answered by the parent's scheduler.
195
+ const wakeMod = require('../tui-client/next-wakeup.js') as typeof import('../tui-client/next-wakeup.js');
196
+ const wakeup = wakeMod.createReplWakeupTool(process as unknown as import('../tui-client/next-wakeup.js').WakeupIpcProcess);
197
+ if (wakeup) {
198
+ specs.push(wakeup.spec);
199
+ dispatchByName.set(wakeup.spec.name, wakeup.dispatch);
200
+ }
192
201
  const planner = sr.createSearchPlannerState({ maxAutoNarrowCandidates: 2 });
193
202
  const dispatch = async (name: string, args: Record<string, unknown>): Promise<unknown> => {
194
203
  try {
@@ -594,6 +603,8 @@ export async function runRepl(opts: ReplOpts): Promise<number> {
594
603
  } catch { /* suggestions must not interrupt the REPL */ }
595
604
  }
596
605
  const sessionIdRef = { current: session.id };
606
+ const selfHealthTracker = installNextTuiSelfHealthTracker();
607
+ selfHealthTracker?.setSessionId(session.id);
597
608
 
598
609
  const nextTuiDelivery = process.env.ELANOUS_NEXT_TUI_BG_STATUS === '1'
599
610
  ? { pending: [] as PendingTaskNotification[] } : undefined;
@@ -747,6 +758,11 @@ export async function runRepl(opts: ReplOpts): Promise<number> {
747
758
  if (att) turnAttachments.push(att);
748
759
  }
749
760
  backgroundBridge?.beginTurn();
761
+ const selfHealth = selfHealthTracker?.snapshot(sessionIdRef.current) ?? null;
762
+ if (selfHealth && typeof turn.id === 'string') {
763
+ process.stdout.write(`${JSON.stringify({ event: 'self-health', turnId: turn.id, sessionId: sessionIdRef.current, selfHealth })}\n`);
764
+ }
765
+ const turnSystemPrompt = selfHealth ? `${systemPrompt}\n\n${selfHealth.line}` : systemPrompt;
750
766
  let result: Awaited<ReturnType<typeof runOneTurn>>;
751
767
  try {
752
768
  result = await runOneTurn(
@@ -755,7 +771,7 @@ export async function runRepl(opts: ReplOpts): Promise<number> {
755
771
  turn.prompt,
756
772
  turnAttachments,
757
773
  tools,
758
- systemPrompt,
774
+ turnSystemPrompt,
759
775
  true, // JSONL stream → always JSON output
760
776
  nextTuiDelivery,
761
777
  process.env.ELANOUS_NEXT_TUI_STREAM === '1' && typeof turn.id === 'string'
@@ -779,10 +795,12 @@ export async function runRepl(opts: ReplOpts): Promise<number> {
779
795
  durationMs: result.durationMs,
780
796
  logPath: result.logPath,
781
797
  assertFailures: failures,
798
+ selfHealth,
782
799
  };
783
800
  console.log(JSON.stringify(out));
784
801
  }
785
802
  backgroundBridge?.dispose();
803
+ selfHealthTracker?.dispose();
786
804
  return 0;
787
805
  }
788
806
 
@@ -139,7 +139,7 @@ interface KnowhowCard {
139
139
  }
140
140
 
141
141
  /** 카드 제목 — `## K-<자리>-<번호>` 뒤에는 줄 끝·공백·콜론·em 대시만 온다. */
142
- const CARD_HEADING = /^[ \t]{0,3}##\s+(K-[A-Za-z]+-\d+)(?=$|\s|:|—)/u;
142
+ const CARD_HEADING = /^[ \t]{0,3}##\s+(K-[A-Za-z]+(?:-[A-Za-z]{1,4})?-\d+)(?=$|\s|:|—)/u;
143
143
  /** 카드처럼 보이는 `##` 제목(예: `## K-OP-7a`) — CARD_HEADING 을 벗어나면 인식 실패로 명시 거부한다. */
144
144
  const CARD_HEADING_LIKE = /^[ \t]{0,3}##\s*(K-[^\s:]*)/iu;
145
145
 
@@ -84,6 +84,49 @@ function hotPathOverlapsOf(pieces: readonly DecomposePiece[]): HotPathOverlap[]
84
84
  return pairs;
85
85
  }
86
86
 
87
+ /** 분해 제안 문서를 «읽은» 결과. ⛔ 혼합 문서를 조각 문서로 «다시 매기지» 않는다. */
88
+ export type DecomposeDocument =
89
+ | { kind: 'pieces'; pieces: DecomposePiece[] }
90
+ /** 단계꼴(`step`/문자열)과 조각꼴(`feature`)이 «섞인» 문서. 조용히 다시 매기지 않고 거부한다. */
91
+ | { kind: 'rejected'; reason: 'mixed-document'; stepEntries: number; pieceEntries: number }
92
+ /** 읽을 조각이 «하나도» 없다 — 빈 문서와 거부를 같은 값으로 접지 않는다. */
93
+ | { kind: 'empty' };
94
+
95
+ /**
96
+ * 분해 제안 문서(원장 `data.pieces`)를 조각 목록으로 읽는다.
97
+ *
98
+ * ⛔⭐ **혼합 문서를 «다시 매기지» 않는다** — 단계꼴 항목(`{ step }`·맨 문자열)은 `feature` 가 없어
99
+ * 지금까지 «조용히» 버려졌고, 남은 조각 id 가 `String(pieces.length)` 로 **재번호**됐다.
100
+ * 그 재번호가 `shadow → live` 선행 간선을 «매달린» 것으로 바꿔, shadow 관측 없이 live 가 나갔다.
101
+ * ⇒ 단계꼴이 «하나라도» 섞여 있으면 문서 전체를 거부하고 두 수를 값으로 남긴다(처방이 다르다).
102
+ */
103
+ export function readDecomposeDocument(raw: unknown): DecomposeDocument {
104
+ if (!Array.isArray(raw) || raw.length === 0) return { kind: 'empty' };
105
+ const pieces: DecomposePiece[] = [];
106
+ let stepEntries = 0;
107
+ for (const entry of raw) {
108
+ if (typeof entry === 'string') { stepEntries++; continue; }
109
+ if (!entry || typeof entry !== 'object') continue;
110
+ const piece = entry as {
111
+ id?: unknown; feature?: unknown; dependsOn?: unknown; goalType?: unknown; hotPaths?: unknown; step?: unknown;
112
+ };
113
+ if (typeof piece.step === 'string' && piece.step.trim()) stepEntries++;
114
+ if (typeof piece.feature !== 'string' || !piece.feature.trim()) continue;
115
+ pieces.push({
116
+ id: typeof piece.id === 'string' && piece.id ? piece.id : String(pieces.length),
117
+ feature: piece.feature,
118
+ dependsOn: Array.isArray(piece.dependsOn) ? piece.dependsOn.filter((d): d is string => typeof d === 'string') : [],
119
+ ...(typeof piece.goalType === 'string' ? { goalType: piece.goalType } : {}),
120
+ ...(Array.isArray(piece.hotPaths) ? { hotPaths: piece.hotPaths.filter((path): path is string => typeof path === 'string') } : {}),
121
+ });
122
+ }
123
+ if (pieces.length === 0) return { kind: 'empty' };
124
+ if (stepEntries > 0) {
125
+ return { kind: 'rejected', reason: 'mixed-document', stepEntries, pieceEntries: pieces.length };
126
+ }
127
+ return { kind: 'pieces', pieces };
128
+ }
129
+
87
130
  /** 원장 엔트리들에서 조각별 «가장 늦은» 분해 제안을 뽑는다. 형제 겹침이 있으면 hot-path-overlap 관측을 낸다(fail-open). */
88
131
  export function pickDecomposeProposals(entries: readonly Ledgerish[]): Map<string, DecomposeProposal> {
89
132
  const out = new Map<string, DecomposeProposal>();
@@ -94,20 +137,20 @@ export function pickDecomposeProposals(entries: readonly Ledgerish[]): Map<strin
94
137
  : typeof entry.runId === 'string' && entry.runId.trim() ? entry.runId : null;
95
138
  if (!shardId) continue; // ⛔ 어느 조각인지도 어느 런인지도 모르는 제안은 «쓸 수 없다» — 조용히 아무 데나 붙이지 않는다
96
139
  const data = entry.data as { pieces?: unknown; round?: unknown } | undefined;
97
- const raw = Array.isArray(data?.pieces) ? data!.pieces : null;
98
- if (!raw?.length) continue;
99
- const pieces: DecomposePiece[] = [];
100
- for (const p of raw) {
101
- const piece = p as { id?: unknown; feature?: unknown; dependsOn?: unknown; goalType?: unknown; hotPaths?: unknown };
102
- if (typeof piece?.feature !== 'string' || !piece.feature.trim()) continue;
103
- pieces.push({
104
- id: typeof piece.id === 'string' && piece.id ? piece.id : String(pieces.length),
105
- feature: piece.feature,
106
- dependsOn: Array.isArray(piece.dependsOn) ? piece.dependsOn.filter((d): d is string => typeof d === 'string') : [],
107
- ...(typeof piece.goalType === 'string' ? { goalType: piece.goalType } : {}),
108
- ...(Array.isArray(piece.hotPaths) ? { hotPaths: piece.hotPaths.filter((path): path is string => typeof path === 'string') } : {}),
109
- });
140
+ const document = readDecomposeDocument(data?.pieces);
141
+ if (document.kind === 'empty') continue;
142
+ // ⛔ 혼합 문서는 «뽑지 않는다» — 다시 매기면 shadow→live 선행 간선이 매달린 것이 된다.
143
+ if (document.kind === 'rejected') {
144
+ try {
145
+ debug.log('self-dev.decompose', 'mixed-decompose-document', {
146
+ shardId,
147
+ stepEntries: document.stepEntries,
148
+ pieceEntries: document.pieceEntries,
149
+ });
150
+ } catch { /* fail-open */ }
151
+ continue;
110
152
  }
153
+ const pieces = document.pieces;
111
154
  // ⛔ 조각이 «하나»면 분해가 아니다 — 같은 골을 이름만 바꿔 다시 거는 셈이다.
112
155
  if (pieces.length < 2) continue;
113
156
  const round = typeof data?.round === 'number' ? data.round : undefined;
@@ -158,8 +201,9 @@ export interface DecomposePieceOrdering {
158
201
  * 겹침은 직렬화하지 않고 `DecomposeProposal.hotPathOverlaps` 로 형제 겹침으로 따로 남는다.
159
202
  * 덕분에 ⓐ 와 배열 위치가 반대 방향을 가리켜 가짜 순환을 만들던 충돌 자체가 사라졌다.
160
203
  *
161
- * ⛔ 매달린 `dependsOn`(조각 목록에 없는 id)은 «버리고 센다» — 그것 때문에 승격 전체를 막지 않는다
162
- * (연합 경로의 `pruneDanglingDependencies` 와 같은 판단).
204
+ * ⛔ 매달린 `dependsOn`(조각 목록에 없는 id)은 «버리고 센다» — 이 순서 계산기는 승격을 막지 않는다
205
+ * (연합 경로의 `pruneDanglingDependencies` 와 같은 판단). 승격 «입구»는 다르다 —
206
+ * `planShadowFirstDispatch` 가 매달린 간선을 «거부»한다(shadow 선행 간선이 사라진 채 live 가 나가는 것을 막는다).
163
207
  *
164
208
  * 순수 함수다 — 시계·파일·프로세스를 안 만진다. 동률은 «원래 순서»로 깬다(같은 입력 → 같은 출력).
165
209
  */
@@ -217,6 +261,73 @@ export function orderPiecesTopologically(pieces: readonly DecomposePiece[]): Dec
217
261
  return { ordered, dependsOnEdges, hotPathEdges: 0, danglingDependsOn };
218
262
  }
219
263
 
264
+ /** shadow 조각의 id — 관측만 하는 조각. ⛔ 이름은 하니스 산출이 canonical 이다. */
265
+ export const SHADOW_PIECE_ID = 'shadow';
266
+
267
+ /** shadow-first 집행 계획의 관측 값 — 무엇이 관측이고 어디에 선행 간선이 걸렸나. */
268
+ export interface ShadowFirstPlan {
269
+ shadowId: string;
270
+ /** shadow 뒤에 서는 «live» 조각 id — 제안 순서 그대로다. */
271
+ liveIds: string[];
272
+ /** 원 제안이 잃고 있어 «되살린» shadow 선행 간선 수. 0 이면 제안이 이미 shadow-first 였다. */
273
+ restoredEdges: number;
274
+ }
275
+
276
+ /** shadow-first 집행 판정. ⛔ 「고칠 수 없음」과 「거부」를 같은 값으로 접지 않는다. */
277
+ export type ShadowFirstDispatch =
278
+ | { kind: 'ok'; pieces: DecomposePiece[]; shadowFirst?: ShadowFirstPlan }
279
+ | { kind: 'rejected'; reason: 'dangling-dependsOn'; danglingIds: string[] };
280
+
281
+ /**
282
+ * ⭐⭐⭐ shadow 관측이 live 발사보다 «앞선다» — AUTHOR-SHADOW-FIRST-SPLIT ② (#26884 수확).
283
+ *
284
+ * 🔑 ***실패 뒤 분해 제안에서 관측이 «사라지고» live 만 나갔다.*** shadow 조각은
285
+ * `dependsOn` 없이 제안에 실리고, live 조각이 그 선행 간선을 «잃은» 채 오면 위상 정렬이
286
+ * 둘을 «동시에» 세운다 ⇒ 관측 없이 live 발사가 먼저 도착한다.
287
+ *
288
+ * ⛔ 판정은 «둘»로 가른다 — 접으면 다음 사람이 못 고친다:
289
+ * ⓐ 매달린 `dependsOn`(조각 목록에 없는 id) → `kind: 'rejected'`, 사유와 없는 id 를 값으로 남긴다.
290
+ * 없는 조각을 선행으로 단 제안은 승격하지 않는다(`danglingDependsOn` 을 세는 것만으로는 live 발사를 못 막는다).
291
+ * ⓑ shadow 조각이 «둘» 이상 → `kind: 'ok'` 지만 «가드 없음» — 어느 쪽이 관측인지 모르는 제안은 고치지 않는다.
292
+ *
293
+ * ⭐ 선행 간선은 «실제 발사 지점»(다른 조각이 의존하지 않는 끝 조각)에만 건다 — 중간 조각은
294
+ * 자기 선행 순서만 들고 있으면 되고, 그 것까지 shadow 에 매달면 계획이 사슬로 납작해진다.
295
+ * shadow 조각은 언제나 맨 앞으로 올라오고, 이미 shadow 를 선행으로 가진 조각은 건드리지 않는다.
296
+ *
297
+ * 순수 함수다 — 시계·파일·프로세스를 안 만진다. 입력 조각은 «변형하지 않는다».
298
+ */
299
+ export function planShadowFirstDispatch(pieces: readonly DecomposePiece[]): ShadowFirstDispatch {
300
+ const known = new Set(pieces.map((piece) => piece.id));
301
+ const danglingIds: string[] = [];
302
+ for (const piece of pieces) {
303
+ for (const dep of piece.dependsOn) {
304
+ if (dep === piece.id || known.has(dep) || danglingIds.includes(dep)) continue;
305
+ danglingIds.push(dep);
306
+ }
307
+ }
308
+ if (danglingIds.length) return { kind: 'rejected', reason: 'dangling-dependsOn', danglingIds };
309
+
310
+ const shadowPieces = pieces.filter((piece) => piece.id === SHADOW_PIECE_ID);
311
+ if (shadowPieces.length !== 1) return { kind: 'ok', pieces: [...pieces] };
312
+
313
+ const shadow = shadowPieces[0]!;
314
+ const rest = pieces.filter((piece) => piece !== shadow);
315
+ const dependedUpon = new Set<string>();
316
+ for (const piece of rest) for (const dep of piece.dependsOn) dependedUpon.add(dep);
317
+
318
+ let restoredEdges = 0;
319
+ const reordered = rest.map((piece) => {
320
+ if (dependedUpon.has(piece.id) || piece.dependsOn.includes(SHADOW_PIECE_ID)) return piece;
321
+ restoredEdges++;
322
+ return { ...piece, dependsOn: [...piece.dependsOn, SHADOW_PIECE_ID] };
323
+ });
324
+ return {
325
+ kind: 'ok',
326
+ pieces: [shadow, ...reordered],
327
+ shadowFirst: { shadowId: shadow.id, liveIds: rest.map((piece) => piece.id), restoredEdges },
328
+ };
329
+ }
330
+
220
331
  export interface DecomposeProposalScan {
221
332
  proposals: Map<string, DecomposeProposal>;
222
333
  goalPlanRevisions: Map<string, GoalPlanRevisionReadObservation>;
@@ -343,11 +454,21 @@ export function readDecomposeProposals(input: {
343
454
  };
344
455
  }
345
456
 
457
+ /** 승격하지 «않은» 제안 하나 — ⛔ 조용히 원본만 두면 다음 라운드가 같은 제안을 다시 쓴다. */
458
+ export interface DecomposeRejection {
459
+ feature: string;
460
+ reason: 'dangling-dependsOn';
461
+ /** 무엇이 매달렸나 — 조각 목록에 없는 선행 id 들. */
462
+ detail: string[];
463
+ }
464
+
346
465
  /** 조각 하나를 «쪼갠» 결과. ⛔ 「무엇을 무엇으로」가 값으로 남아야 다음 라운드가 중복하지 않는다. */
347
466
  export interface DecomposeApplication {
348
467
  goals: SelfDevGoal[];
349
468
  /** 이번에 쪼갠 원래 goal 의 feature 들. 비면 아무것도 안 바뀌었다. */
350
469
  decomposed: string[];
470
+ /** 거부한 제안들 — 사유와 매달린 id 를 «값»으로 남긴다. 거부가 없으면 빈 배열이다. */
471
+ rejected: DecomposeRejection[];
351
472
  }
352
473
 
353
474
  /**
@@ -358,10 +479,12 @@ export interface DecomposeApplication {
358
479
  * self_orchestrate 는 shouldDefer=true 라 «찾아야» 보인다. 그래서 복합도 단일로 들어온다.
359
480
  * ⇒ 📌 입구를 고치는 대신 ***「들어온 뒤 스스로 쪼개게」*** 한다.
360
481
  *
361
- * ⛔ **안전 장치 셋** — 다시 거는 것은 쉽고 «멈출 줄 아는 것»이 어렵다:
482
+ * ⛔ **안전 장치 넷** — 다시 거는 것은 쉽고 «멈출 줄 아는 것»이 어렵다:
362
483
  * ⓐ 같은 goal 을 «두 번» 쪼개지 않는다(alreadyDecomposed)
363
484
  * ⓑ 조각이 둘 미만인 제안은 애초에 안 온다(pickDecomposeProposals 가 거른다)
364
485
  * ⓒ 상한을 넘기면 «쪼개지 않는다» — 조각이 무한히 불어나는 것을 막는다
486
+ * ⓓ shadow 관측이 live 발사 «앞»에 선다(`planShadowFirstDispatch`) — 매달린 `dependsOn` 은
487
+ * 승격하지 않고 사유와 id 를 `rejected` 로 남긴다. 관측은 조각을 내보내기 «전»에 남는다.
365
488
  *
366
489
  * ⭐ **조각은 원 골의 «대상 경로:» 머리줄을 물려받는다** (DECOMPOSE-PIECE-TARGET-LINE · 10-11 부검 run-76941fca):
367
490
  * 조각 feature 가 골을 «통째로» 갈아 끼우면 첫 줄 선언이 사라져 Pod 예비 검사가 «대상 경로 0» →
@@ -402,22 +525,51 @@ export function applyDecomposeProposals(
402
525
  if (already.has(r.feature)) continue;
403
526
  byFeature.set(r.feature, pieces);
404
527
  }
405
- if (byFeature.size === 0) return { goals: [...goals], decomposed: [] };
528
+ if (byFeature.size === 0) return { goals: [...goals], decomposed: [], rejected: [] };
406
529
 
407
530
  const out: SelfDevGoal[] = [];
408
531
  const decomposed: string[] = [];
532
+ const rejected: DecomposeRejection[] = [];
409
533
  for (const goal of goals) {
410
534
  const pieces = byFeature.get(goal.feature);
411
535
  if (!pieces) { out.push(goal); continue; }
536
+ // ⛔⭐ shadow-first 가드 — 매달린 선행 간선이 있는 제안은 «쪼개지 않는다»(원본을 그대로 둔다).
537
+ const plan = planShadowFirstDispatch(pieces);
538
+ if (plan.kind === 'rejected') {
539
+ rejected.push({ feature: goal.feature, reason: plan.reason, detail: [...plan.danglingIds] });
540
+ // ⛔⭐ 거부를 «로그와 값에 다» 남긴다 — 조용히 버리면 다음 라운드가 같은 제안을 다시 쓴다.
541
+ // 혼합 문서 거부(mixed-decompose-document)와 같은 관측 채널·같은 fail-open 규율이다.
542
+ try {
543
+ debug.log('self-dev.decompose', 'decompose-rejected', {
544
+ feature: goal.feature,
545
+ reason: plan.reason,
546
+ danglingIds: [...plan.danglingIds],
547
+ });
548
+ } catch { /* fail-open */ }
549
+ out.push(goal);
550
+ continue;
551
+ }
552
+ const planned = plan.pieces;
412
553
  // ⛔ 상한을 넘기면 «쪼개지 않는다» — 조용히 자르지 않고 원본을 그대로 둔다.
413
- if (out.length + pieces.length + (goals.length - out.length - 1) > maxGoals) { out.push(goal); continue; }
554
+ if (out.length + planned.length + (goals.length - out.length - 1) > maxGoals) { out.push(goal); continue; }
414
555
  decomposed.push(goal.feature);
556
+ // ⭐ 관측이 live 발사보다 «앞»에 남는다 — 조각을 out 에 넣기 전에 이 자리에서 찍는다.
557
+ if (plan.shadowFirst) {
558
+ try {
559
+ debug.log('self-dev.decompose', 'shadow-first-dispatch', {
560
+ feature: goal.feature,
561
+ shadowId: plan.shadowFirst.shadowId,
562
+ liveIds: [...plan.shadowFirst.liveIds],
563
+ restoredEdges: plan.shadowFirst.restoredEdges,
564
+ });
565
+ } catch { /* fail-open */ }
566
+ }
415
567
  // 원 골의 머리줄 선언 — 첫 줄이 «대상 경로:» 가 아니면 조각은 지금 그대로(바이트 불변)다.
416
568
  const goalLines = goal.feature.split('\n');
417
569
  const targetLine = TARGET_PATHS_LINE.exec(goalLines[0] ?? '');
418
570
  // «신설:» 상속은 머리줄 선언이 «있을 때만» — 첫 줄이 라벨이 아니면 조각은 바이트 불변이어야 한다.
419
571
  const newLine = targetLine ? goalLines.map((line) => NEW_PATHS_LINE.exec(line)).find((m) => m !== null) : null;
420
- for (const piece of pieces) {
572
+ for (const piece of planned) {
421
573
  const inherited: string[] = [];
422
574
  let paths: string[] = [];
423
575
  if (targetLine) {
@@ -444,5 +596,5 @@ export function applyDecomposeProposals(
444
596
  } as SelfDevGoal);
445
597
  }
446
598
  }
447
- return { goals: out, decomposed };
599
+ return { goals: out, decomposed, rejected };
448
600
  }