elanous 0.2.32 → 0.2.35

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 (753) 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/{IVKr3AlRUVLKsw2fh7eXF → T1mBQqmkwKDLGtyisDCOd}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{997ce8a5-2ad501927003b41b.js → 0368f25d-ad84af92fefee68f.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1165.bad13fc9151a7288.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/13.02a07436dec15f89.js +32 -0
  7. package/apps/pwa/out/_next/static/chunks/{5525.86debf231e181813.js → 1530.0e612369b6fd7ea0.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +41 -0
  9. package/apps/pwa/out/_next/static/chunks/{7391.ebae168025c91b6a.js → 1674.2a65fd5668e1cc5f.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +24 -0
  11. package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +74 -0
  12. package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/{7947-d0759430f8042240.js → 1993-c0007b7ad0c0ef41.js} +1 -1
  15. package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/{60fb96c9.360b01d8d4927b7b.js → 1c735de4.f993a30bbd3c57c4.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{5307.60f2209e809bd627.js → 2018.a741297bce759490.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +148 -0
  23. package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/{3902.e1e71aaac850a045.js → 2625.5d870aa999f33db1.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +77 -0
  26. package/apps/pwa/out/_next/static/chunks/2833-0fe47af99ed13c29.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +62 -0
  29. package/apps/pwa/out/_next/static/chunks/3103.0df8da390948bb84.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +90 -0
  31. package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{4174.92ed04922709ac9e.js → 3408.21d1570602f4b6c0.js} +2 -2
  33. package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/3589.5444a06bcf6e775c.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/359-2250789a2d3499e7.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +36 -0
  37. package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{9398-6aed28f0a96d0d6f.js → 3677-4215f826f6aa68e5.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +79 -0
  40. package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3f7c4ee5.3dde54f01a816613.js +122 -0
  42. package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/{7371.80c05c653b08e907.js → 4346.8601952e73bf5803.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/4441-875b97f5821ed58a.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +286 -0
  46. package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +24 -0
  49. package/apps/pwa/out/_next/static/chunks/{2940-619bfd8ef337c611.js → 4705-194e64e47ca0fbdb.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/{1335-6731f392c35216eb.js → 4718-17d2af636796a330.js} +3 -3
  51. package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/{7502.ccd5b8065545edd0.js → 5101.e32282718f99ed6f.js} +2 -2
  57. package/apps/pwa/out/_next/static/chunks/{2001.6c7e0fd02190886c.js → 5154.a118f3957ed14e36.js} +1 -1
  58. package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +23 -0
  61. package/apps/pwa/out/_next/static/chunks/{5173-233188df2f42c626.js → 5483-dd5d7697f6bdb106.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5637.281e5dec4ea6ecf1.js +94 -0
  63. package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/{3267c0e6.d34854e7b3984a6e.js → 56d372f2.681ab4ec4c998fae.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +287 -0
  67. package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/{6433.fc573af22bbc9ab7.js → 6236.e18cced2d5ba6afb.js} +17 -17
  74. package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +8 -0
  75. package/apps/pwa/out/_next/static/chunks/630.fe5a46428d63b013.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +27 -0
  78. package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +93 -0
  80. package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6866-79aa5b4e47cac6aa.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/{6544cb48.a87fe20ddf137be2.js → 6b89c8bd.24df687a820500b3.js} +1 -1
  83. package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +149 -0
  87. package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +104 -0
  88. package/apps/pwa/out/_next/static/chunks/{2871.0bca6137343b3f76.js → 7385.50a308a477bdfc21.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/{2985.39ccdecd36848b12.js → 7644.17e37ba6f1d4226e.js} +4 -4
  90. package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/{8018.a32663f04a6fc5f9.js → 8219.baa715d1deee80e2.js} +1 -1
  95. package/apps/pwa/out/_next/static/chunks/{4111.2bfedbb233ad206b.js → 8256.e3ac8421a71f82f4.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/{2213.2ccbada92c33ea0f.js → 8444.4c26b379ca2b9596.js} +17 -17
  100. package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +226 -0
  101. package/apps/pwa/out/_next/static/chunks/8557-e7898769499cd56f.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +64 -0
  104. package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{6092.a7f99e68b188ca66.js → 8637.47f5b35afcae5e6b.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/8714.ff0b7ce3ec3e3ae2.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{3278.2e5d15b53a4091c8.js → 9214.63a510d39178e997.js} +2 -2
  111. package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +115 -0
  112. package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/{9221.7d22eaf353a2d4e7.js → 938.66ad1ef0e5abae1c.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/{6157.0c9af021de4fb31b.js → 9512.5a76207a730e0491.js} +2 -2
  115. package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/{69-0a2c8209c6d4a158.js → 967-2aa39b2d04b4c690.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/{7862.30a8d6482bb238eb.js → 9952.5daf5f94063a2b3e.js} +1 -1
  120. package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/{page-a27b1e5a0d1b308f.js → page-406b47745b53f269.js} +1 -1
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/{page-32866485913d6a04.js → page-47c5d4db587266bd.js} +1 -1
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1f5a60f70cb4dd0c.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-bac7dee94e5eae4a.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/{page-04d00ae9b0890349.js → page-dc0a532f5b9196ec.js} +1 -1
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{7a1887c4.f36b88fba31da8fd.js → b2f6ba4d.fb56fdbbf798df33.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/b6705a4f-b9a9047de9eecfd0.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/{b313b242.cb1265eea908db61.js → cbe38a15.5a032598e39970c6.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{409f1e57.d0649fc47691ebfe.js → d06f9160.a3d9062f95de8ad7.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/{0bb0ff36.b8d418980951e5ba.js → da5176c6.6773b6c5994e1d99.js} +7 -7
  178. package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +1 -0
  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/bin/elanous.mjs +10 -2
  278. package/catalog/providers/opengateway.yaml +25 -0
  279. package/docs/goal-context/01-goal-authoring-checks.md +8 -0
  280. package/docs/goal-context/03-verification-menu.md +24 -0
  281. package/docs/goal-context/04-mock-scenarios.md +100 -0
  282. package/docs/goal-context/README.md +5 -0
  283. package/graphs/catalog/catalog.yaml +1 -1
  284. package/graphs/default-loop.yaml +76 -5
  285. package/graphs/document-loop.yaml +71 -4
  286. package/graphs/implement-loop.yaml +59 -4
  287. package/graphs/journey/SCENARIOS.md +33 -0
  288. package/graphs/journey/recipes.yaml +1 -0
  289. package/graphs/journey/ta-journey.yaml +94 -0
  290. package/graphs/journey/units/author/author.yaml +20 -0
  291. package/graphs/journey/units/author/recipes.yaml +2 -0
  292. package/graphs/journey/units/author-dialogue/author-dialogue.yaml +42 -0
  293. package/graphs/journey/units/author-dialogue/observe.ts +96 -0
  294. package/graphs/journey/units/author-dialogue/recipes.yaml +10 -0
  295. package/graphs/journey/units/green/green.yaml +20 -0
  296. package/graphs/journey/units/green/recipes.yaml +2 -0
  297. package/graphs/journey/units/pr/pr.yaml +20 -0
  298. package/graphs/journey/units/pr/recipes.yaml +2 -0
  299. package/graphs/journey/units/remember/recipes.yaml +2 -0
  300. package/graphs/journey/units/remember/remember.yaml +20 -0
  301. package/graphs/operate-loop.yaml +71 -4
  302. package/graphs/overlays/stop-heal-ladder.yaml +1 -1
  303. package/graphs/release-rehearsal/recipes.yaml +1 -1
  304. package/graphs/release-rehearsal/release-rehearsal.yaml +2 -2
  305. package/graphs/research-loop.yaml +159 -4
  306. package/graphs/test-diet/test-diet.yaml +3 -0
  307. package/graphs/units/dispatch-pod/dispatch-pod.yaml +50 -0
  308. package/graphs/units/dispatch-pod/recipes.yaml +14 -0
  309. package/graphs/units/entry/entry.yaml +50 -0
  310. package/graphs/units/entry/recipes.yaml +14 -0
  311. package/graphs/units/harvest/harvest.yaml +25 -0
  312. package/graphs/units/harvest/recipes.yaml +4 -0
  313. package/graphs/units/land/land.yaml +45 -0
  314. package/graphs/units/land/recipes.yaml +3 -0
  315. package/graphs/units/recipes.yaml +7 -0
  316. package/graphs/units/recover.yaml +39 -0
  317. package/graphs/units/reflect/recipes.yaml +3 -0
  318. package/graphs/units/reflect/reflect.yaml +15 -0
  319. package/graphs/units/task-agent-recover-review.yaml +17 -0
  320. package/graphs/units/task-agent-recover-wait.yaml +17 -0
  321. package/graphs/units/verbs/make-doc.yaml +34 -0
  322. package/graphs/units/verbs/recipes.yaml +33 -0
  323. package/graphs/units/verbs/verify.yaml +55 -0
  324. package/graphs/work/recipes.yaml +2 -0
  325. package/graphs/work/research-report.yaml +28 -0
  326. package/package.json +1 -1
  327. package/scripts/ci-typecheck-changed.ts +69 -16
  328. package/scripts/coord-role-pack.ts +19 -6
  329. package/scripts/docs/generate-graph-anatomy.ts +19 -2
  330. package/scripts/graph-harvest-unit.ts +22 -0
  331. package/scripts/graph-units/journey-stub.ts +6 -0
  332. package/scripts/graph-units/land-enqueue.ts +78 -0
  333. package/scripts/graph-units/recover-plan.ts +15 -0
  334. package/scripts/graph-units/reflect-node.ts +88 -0
  335. package/scripts/graph-units/ta-journey-observe.ts +109 -0
  336. package/scripts/graph-units/verbs/headless-goal-loop.ts +152 -0
  337. package/scripts/graph-units/verbs/verify-stage.ts +75 -0
  338. package/scripts/graph-units/verbs-envelope.ts +139 -0
  339. package/scripts/hq/standby-snapshot.ts +30 -0
  340. package/scripts/public-export.ts +43 -1
  341. package/scripts/ratchets/train-side-invariants.sh +45 -0
  342. package/scripts/release-loop/auto-approve-node.ts +30 -16
  343. package/scripts/release-loop/docs-land-node.ts +21 -5
  344. package/scripts/release-loop/gate-baseline-receipt.ts +155 -0
  345. package/scripts/release-loop/gate-closure.ts +5 -1
  346. package/scripts/release-loop/gate-diff.ts +1 -1
  347. package/scripts/release-loop/gate-node.ts +675 -49
  348. package/scripts/release-loop/gate-partial.ts +68 -14
  349. package/scripts/release-loop/gate-radius-live.ts +177 -0
  350. package/scripts/release-loop/gate-radius-shadow.ts +138 -0
  351. package/scripts/release-loop/gate-traffic-mode.ts +128 -0
  352. package/scripts/release-loop/gate-triage-node.ts +5 -2
  353. package/scripts/release-loop/known-issues-0.2.33-approved.json +194 -0
  354. package/scripts/release-loop/known-issues-node.ts +77 -8
  355. package/scripts/release-loop/node-verdict.ts +12 -1
  356. package/scripts/release-loop/npm-publish-node.ts +66 -12
  357. package/scripts/release-loop/preflight.ts +93 -7
  358. package/scripts/release-loop/probe-pod-host-dirs-live.ts +5 -0
  359. package/scripts/release-loop/publish-node.ts +60 -9
  360. package/scripts/release-loop/pwa-remote.ts +166 -0
  361. package/scripts/release-loop/pwa-scenarios-node.ts +19 -3
  362. package/scripts/release-loop/resume-cap.ts +56 -0
  363. package/scripts/release-loop/resume-release.ts +155 -19
  364. package/scripts/release-loop/resume.ts +24 -1
  365. package/scripts/release-loop/tui-sim-node.ts +8 -2
  366. package/scripts/release-loop/unattended-release.ts +10 -2
  367. package/scripts/test-diet/lib.ts +6 -1
  368. package/scripts/test-diet/node.ts +194 -13
  369. package/scripts/ux-sim.ts +39 -0
  370. package/src/acp/core-turn-bridge.ts +20 -5
  371. package/src/acp/reasoning-thought-buffer.ts +45 -0
  372. package/src/agent/self-ambient-cache.ts +8 -0
  373. package/src/agent-substrate/acp-reviewer.ts +90 -15
  374. package/src/agent-substrate/pr-reviewer.ts +17 -0
  375. package/src/agent-substrate/review-finding-key.ts +53 -0
  376. package/src/agent-substrate/self-review-cli.ts +188 -18
  377. package/src/ask-user-question/pending-questions.ts +1 -1
  378. package/src/autopilot/pr-manager.ts +393 -65
  379. package/src/budget/run-usage-rollup.ts +1 -0
  380. package/src/chat/index.ts +0 -2
  381. package/src/chat/pickers/modal-runtime.ts +10 -27
  382. package/src/chat/tool-render/dispatch.ts +62 -10
  383. package/src/cli/agent-cli.ts +13 -2
  384. package/src/cli/control-cli.ts +24 -7
  385. package/src/cli/doctor-cli.ts +4 -1
  386. package/src/cli/guardian-cli.ts +10 -0
  387. package/src/cli/light-entry-route.ts +75 -0
  388. package/src/cli/llm-detect-cli.ts +23 -1
  389. package/src/cli/pod-cli.ts +77 -3
  390. package/src/cli/pr-cli.ts +81 -14
  391. package/src/cli/pr-land-base-read.ts +2 -0
  392. package/src/cli/pr-land-overlap-evidence.ts +154 -16
  393. package/src/cli/pr-land-pod-shadow-job.ts +3 -0
  394. package/src/cli/pr-land-recovery.ts +64 -0
  395. package/src/cli/pty-takeover-cli.ts +6 -5
  396. package/src/cli/release-checklist-read-cli.ts +79 -0
  397. package/src/cli/release-cli.ts +189 -132
  398. package/src/cli/release-run-if-ready.ts +29 -28
  399. package/src/cli/release-single-flight.ts +178 -0
  400. package/src/cli/remote-resolve.ts +1 -1
  401. package/src/cli/root-tui-entry.ts +48 -0
  402. package/src/cli/seat-cli.ts +37 -0
  403. package/src/cli/setup-cli.ts +40 -1
  404. package/src/cli/sim-cli.ts +22 -0
  405. package/src/cli/tasks-cli.ts +667 -14
  406. package/src/cli/usage-cli.ts +13 -11
  407. package/src/clipboard/history.ts +179 -13
  408. package/src/config.ts +8 -1
  409. package/src/control/control-status.ts +8 -3
  410. package/src/control-plane/ledger.ts +5 -3
  411. package/src/control-plane/server.ts +5 -3
  412. package/src/core-turn/short-question.ts +5 -1
  413. package/src/dashboard/chat/acp-chat.ts +8 -0
  414. package/src/dashboard/index.ts +114 -77
  415. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +3 -0
  416. package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
  417. package/src/dashboard/input/seat-autowake.ts +56 -3
  418. package/src/dashboard/render/theme-resolver.ts +33 -4
  419. package/src/dashboard/seat-boot-preamble.ts +1 -1
  420. package/src/dashboard/slash-runtime/ask-clarification.ts +48 -0
  421. package/src/dashboard/slash-runtime/dashboard-delegated-slashes.ts +68 -0
  422. package/src/dashboard/slash-runtime/dashboard-handlers.ts +62 -322
  423. package/src/dashboard/slash-runtime/dashboard-log-slash.ts +208 -0
  424. package/src/dashboard/turn-preamble.ts +47 -1
  425. package/src/dashboard/turn-stream-formatter.ts +34 -1
  426. package/src/dashboard/turn-stream-runtime.ts +2 -0
  427. package/src/dashboard/turn-typeahead-prompt-zone.ts +67 -0
  428. package/src/domains/guardian-tick.ts +54 -2
  429. package/src/domains/outbound-alert.ts +3 -2
  430. package/src/domains/schedule-registry.ts +16 -2
  431. package/src/extractors.ts +3 -1
  432. package/src/git-fs/idle-refresh.ts +76 -0
  433. package/src/git-fs/index.ts +18 -7
  434. package/src/git-fs/retry.ts +4 -0
  435. package/src/git-fs/runner.ts +2 -0
  436. package/src/git-fs/worktree.ts +42 -4
  437. package/src/graph-kinds/registry.ts +2 -2
  438. package/src/graph-runner/runner.ts +267 -54
  439. package/src/grok/credential.ts +15 -3
  440. package/src/harness/harness-cli-command.ts +151 -38
  441. package/src/harness/harness-incidents.ts +37 -0
  442. package/src/harness/harness-pod-dispatch.ts +38 -1
  443. package/src/harness/harness-salvage-cli.ts +14 -2
  444. package/src/harness/launch-utterance-ledger.ts +208 -0
  445. package/src/impl-discipline/detector.ts +16 -4
  446. package/src/impl-discipline/system-prompt.ts +11 -0
  447. package/src/impl-discipline/types.ts +2 -2
  448. package/src/index.ts +683 -146
  449. package/src/intake-plane/already-built-hint.ts +91 -0
  450. package/src/intake-plane/requirement-funnel.ts +29 -1
  451. package/src/knowhow/pack.ts +199 -0
  452. package/src/light-cli.ts +111 -0
  453. package/src/llm/opengateway-models.ts +11 -0
  454. package/src/llm/provider-credentials.ts +14 -0
  455. package/src/llm/provider-detect.ts +8 -1
  456. package/src/llm/runtime-model-family.ts +2 -1
  457. package/src/llm.ts +268 -65
  458. package/src/loops/budget.ts +95 -0
  459. package/src/loops/msg-wake.ts +8 -2
  460. package/src/loops/orchestrator/traffic.ts +132 -1
  461. package/src/model-tier/llm-tier-map.ts +15 -1
  462. package/src/mss/logging/log-store.ts +4 -5
  463. package/src/native-tool-catalog.ts +15 -1
  464. package/src/nexus/api/graphs-api.ts +22 -3
  465. package/src/nexus/api/http-server.ts +1 -1
  466. package/src/nexus/api/loop-resources.ts +13 -1
  467. package/src/nexus/api/ops-api.ts +12 -0
  468. package/src/oauth/claude-pty-maturity.ts +66 -0
  469. package/src/oauth/codex-access-mirror.ts +55 -0
  470. package/src/oauth/codex.ts +7 -0
  471. package/src/oauth/fallback-chain.ts +1 -1
  472. package/src/onboarding/first-run.ts +5 -3
  473. package/src/onboarding/non-interactive.ts +64 -13
  474. package/src/onboarding.ts +10 -2
  475. package/src/ops/overview-collect.ts +54 -4
  476. package/src/ops/overview.ts +31 -7
  477. package/src/pr-tool/census.ts +282 -30
  478. package/src/pr-tool/inflight-registry.ts +160 -7
  479. package/src/prompt-library/gpt6-family-addendum.ts +14 -1
  480. package/src/pty-shell/herdr-agent-report.ts +442 -0
  481. package/src/pty-shell/pty-control-ipc.ts +5 -5
  482. package/src/pty-shell/pty-manifest.ts +7 -0
  483. package/src/pty-shell/pty-write-outcome.ts +24 -6
  484. package/src/pty-shell/tui-run-state.ts +117 -3
  485. package/src/release-loop/checklist.ts +103 -5
  486. package/src/release-loop/feature-store.ts +19 -2
  487. package/src/release-loop/landed-but-yellow.ts +129 -5
  488. package/src/release-loop/light-rc.ts +1 -0
  489. package/src/release-loop/placement.ts +10 -3
  490. package/src/release-loop/rehearsal.ts +205 -25
  491. package/src/release-loop/rubric.ts +16 -2
  492. package/src/repl/index.ts +174 -17
  493. package/src/repl/ops-msg-bridge.ts +32 -0
  494. package/src/self-dev/ask-launch-flow.ts +44 -5
  495. package/src/self-dev/cli-help-text.ts +17 -0
  496. package/src/self-dev/dev-cli.ts +11 -9
  497. package/src/self-dev/draft-residue.ts +37 -1
  498. package/src/self-dev/draft-sweep.ts +188 -13
  499. package/src/self-dev/draft-triage-rules.ts +107 -0
  500. package/src/self-dev/fleet-reduce.ts +3 -2
  501. package/src/self-dev/graph-front-nodes.ts +112 -0
  502. package/src/self-dev/graph-journey-nodes.ts +11 -6
  503. package/src/self-dev/graph-journey-route.ts +60 -6
  504. package/src/self-dev/harness-run-cli.ts +3 -15
  505. package/src/self-dev/orchestrate-cli-text.ts +10 -0
  506. package/src/self-dev/orchestrate.ts +79 -3
  507. package/src/self-dev/review-provider-fallback.ts +35 -1
  508. package/src/self-dev/run-supervisor.ts +107 -12
  509. package/src/self-dev/run-types.ts +5 -1
  510. package/src/self-dev/self-orchestrate-runtime.ts +1 -11
  511. package/src/self-dev/shard-aggregate.ts +42 -5
  512. package/src/self-dev/shard-run.ts +8 -1
  513. package/src/self-implement/blocked-draft-policy.ts +20 -0
  514. package/src/self-implement/classify-shadow.ts +3 -7
  515. package/src/self-implement/doctor-visit.ts +18 -1
  516. package/src/self-implement/gate-baseline.ts +95 -12
  517. package/src/self-implement/gate-cli.ts +1 -0
  518. package/src/self-implement/gate-remote.ts +40 -25
  519. package/src/self-implement/goal-author-decompose.ts +275 -47
  520. package/src/self-implement/goal-author-identity.ts +66 -0
  521. package/src/self-implement/goal-author-preservation-obligation.ts +35 -0
  522. package/src/self-implement/goal-author.ts +254 -120
  523. package/src/self-implement/goal-elaborate.ts +295 -0
  524. package/src/self-implement/goal-refine.ts +270 -0
  525. package/src/self-implement/graph-overlay-yaml.ts +28 -2
  526. package/src/self-implement/graph-unit-flatten.ts +103 -0
  527. package/src/self-implement/graph-unit-resolver.ts +107 -0
  528. package/src/self-implement/graph-yaml.ts +151 -1
  529. package/src/self-implement/headless-elanous-driver.ts +1 -0
  530. package/src/self-implement/knowhow-pack.ts +103 -0
  531. package/src/self-implement/orchestrator.ts +160 -45
  532. package/src/self-implement/pod-warm-pool-profile.ts +45 -0
  533. package/src/self-implement/review-mustfix-class.ts +203 -0
  534. package/src/self-implement/rework-budget-judgment.ts +5 -8
  535. package/src/self-implement/run-stop.ts +17 -2
  536. package/src/self-implement/running-runs.ts +29 -1
  537. package/src/self-implement/scope-adjacency.ts +113 -0
  538. package/src/self-implement/seams.ts +138 -4
  539. package/src/self-implement/stop-autoheal.ts +112 -2
  540. package/src/session/chat.ts +27 -0
  541. package/src/session-runtime/index.ts +1 -1
  542. package/src/session-runtime/retry-policy.ts +2 -1
  543. package/src/setup/llm-env-detect.ts +5 -0
  544. package/src/skills/tools/agent.ts +140 -14
  545. package/src/skills/tools/msg-ask.ts +100 -0
  546. package/src/skills/tools/ops-ledger.ts +2 -1
  547. package/src/skills/tools/schedule-wakeup.ts +66 -17
  548. package/src/steward/hold-hygiene.ts +24 -6
  549. package/src/steward/release-day.ts +7 -3
  550. package/src/steward/triage-budget.ts +194 -0
  551. package/src/steward/triage.ts +57 -7
  552. package/src/task-agent/actions.ts +69 -1
  553. package/src/task-agent/green-sweep.ts +4 -0
  554. package/src/task-agent/harvest-unit.ts +141 -0
  555. package/src/task-agent/live-moves.ts +257 -15
  556. package/src/task-agent/parent-host.ts +216 -6
  557. package/src/task-agent/postland-card.ts +80 -1
  558. package/src/task-agent/rejudge-on-head.ts +112 -26
  559. package/src/task-agent/repair-branch-cas.ts +4 -1
  560. package/src/task-agent/repair-cycle.ts +16 -3
  561. package/src/task-agent/run-identity.ts +4 -3
  562. package/src/task-agent/shadow.ts +19 -3
  563. package/src/task-agent/task-hand.ts +96 -36
  564. package/src/task-agent/tier-split.ts +127 -0
  565. package/src/task-agent/work-order-build.ts +24 -0
  566. package/src/task-agent/work-order.ts +3 -2
  567. package/src/task-orchestrator/generator-prompt.ts +60 -11
  568. package/src/task-orchestrator/surfaces/pod-account-broker.ts +72 -3
  569. package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
  570. package/src/task-orchestrator/surfaces/pod-command-job.ts +47 -8
  571. package/src/task-orchestrator/surfaces/pod-image-source.ts +89 -1
  572. package/src/task-orchestrator/surfaces/pod-lease.ts +17 -8
  573. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +86 -8
  574. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +8 -2
  575. package/src/task-orchestrator/surfaces/pod-pool.ts +73 -17
  576. package/src/task-orchestrator/surfaces/pod-provenance.ts +76 -0
  577. package/src/task-orchestrator/surfaces/pod-source-receive.ts +72 -4
  578. package/src/task-orchestrator/surfaces/pod-warm-provenance.ts +81 -0
  579. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +32 -5
  580. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +3 -0
  581. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +421 -0
  582. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +2 -1
  583. package/src/task-orchestrator/surfaces/self-implement-pod.ts +588 -71
  584. package/src/task-orchestrator/surfaces/self-implement.ts +106 -2
  585. package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
  586. package/src/tool-runtime/truncation-store.ts +4 -0
  587. package/src/tui/README.md +2 -0
  588. package/src/tui/chat/background-job-status.ts +54 -0
  589. package/src/tui/chat/log-view.ts +80 -0
  590. package/src/tui/entry.ts +406 -0
  591. package/src/tui/input/composer.ts +144 -0
  592. package/src/tui/seat-mail-boot.ts +59 -0
  593. package/src/tui/slash/compact.ts +100 -0
  594. package/src/tui/slash/new-session.ts +35 -0
  595. package/src/tui-client/dashboard-session.ts +10 -1
  596. package/src/tui-client/local-chat-turn.ts +239 -0
  597. package/src/tui-client/local-harness-command.ts +63 -0
  598. package/src/tui-client/local-provider-command.ts +184 -0
  599. package/src/user-config/coercion.ts +36 -0
  600. package/src/user-config.ts +22 -43
  601. package/src/ux-sim/event-monkey.ts +378 -0
  602. package/src/ux-sim/fake-bin.ts +42 -7
  603. package/src/ux-sim/fault-nextmove-dispatch.ts +266 -0
  604. package/src/ux-sim/fault-pod-codex-503.ts +211 -0
  605. package/src/ux-sim/fault-scope-escape-lift.ts +189 -0
  606. package/src/ux-sim/scenario.ts +72 -13
  607. package/src/version/packed-revision.json +1 -1
  608. package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +0 -27
  611. package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +0 -287
  612. package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +0 -62
  613. package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/1654.32de4b324981a188.js +0 -23
  617. package/apps/pwa/out/_next/static/chunks/1834-98b64172bc1efe77.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +0 -149
  619. package/apps/pwa/out/_next/static/chunks/1913.7cc6fb6055b1ed3f.js +0 -41
  620. package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/2898.fd781bc7cf01a7b7.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +0 -115
  629. package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +0 -64
  630. package/apps/pwa/out/_next/static/chunks/3541-ce3a5424ed5ad7f1.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +0 -36
  636. package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +0 -286
  640. package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +0 -77
  641. package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +0 -226
  642. package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +0 -79
  644. package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +0 -148
  647. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/5458-16cd7a2b51b74c8c.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/5543.a438b8ab5a13ea47.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +0 -74
  653. package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +0 -94
  655. package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +0 -90
  661. package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +0 -32
  662. package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +0 -104
  663. package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +0 -24
  668. package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +0 -93
  669. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +0 -8
  674. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/8097-9530c03bcc550f02.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +0 -24
  685. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/9138.b6e80031afb1d973.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/9279-d28c5b7754d010ae.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/9989.3694300e5f000b14.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/approvals/page-504204b58c82c253.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a9717a67c2eecbaf.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/board/page-5c9ec30aee62dfbf.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/botlab/page-584191533721fa16.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/app/bots/page-73c4b4bb3ac7ab5f.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c0f1ca371f710b06.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/app/chat/page-46430d45a9e04eac.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/app/consult/page-3b2ebf1dc64ff0be.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/app/decisions/page-25654b82094f7d22.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8ea49a4c6dd2c6e7.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/app/editor/page-ce5113aefea0a8d1.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/app/exec/page-0e5a41fac1c75396.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/app/field/page-31aaf1ed37c6df9a.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/app/inside/page-3dcc1fa411e1f4e0.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/app/intake/page-c69247e7134d329d.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/app/layout-66dc5cd3a0999abe.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/app/live/page-26ff7ff651a7217d.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/app/live-run/page-617b3976981efa96.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/app/loops/page-d256f5d5d9552823.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/app/market/page-ce8f1907b8a6101c.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-33e182a316263116.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/app/not-found-7607cca9b84950c6.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eeab86176b03dc3b.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5b93dbae3432b996.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-77a6cb90a9cf2b10.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f47e768b5b242b5a.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/app/outputs/page-eb41aa3367fc2505.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/page-4d13ab0b8a267e3f.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/reflection/page-84dad32ff0fc0831.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-95306f892aa2d0ee.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/sessions/page-940fb6c217f6b470.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-8c66a3b24a745630.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/settings/page-7b675dfd35c36fc9.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8bd0d3cf7665bcfc.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/app/setup/page-c219f2ed171131be.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/app/share/page-40f8fa21bdae955b.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/app/showroom/page-468f8313e4f1fbd9.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/app/tasks/page-7bbb8fa353a246c4.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/app/today/page-4214b855d9233ea8.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/app/trace/page-936752c7aa58762e.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/app/vault/page-ec052ad359df1797.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8305570551091338.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/workflows/page-fad650e4793adb65.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/workspace/page-d90e64743826e1d8.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a16bcfd49af86a32.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +0 -122
  744. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +0 -1
  752. package/src/cli/g6a-registration-probe.ts +0 -16
  753. /package/apps/pwa/out/_next/static/{IVKr3AlRUVLKsw2fh7eXF → T1mBQqmkwKDLGtyisDCOd}/_ssgManifest.js +0 -0
@@ -0,0 +1,45 @@
1
+ /** Warm-pool profile labels select a host/tier allocation policy. */
2
+ export const WARM_POOL_PROFILES = ['fixed', 'gate', 'landing', 'feature'] as const;
3
+ export type WarmPoolProfile = (typeof WARM_POOL_PROFILES)[number];
4
+ export type WarmPoolTier = 'lite' | 'standard';
5
+ const STANDARD_HOST_MAX: Readonly<Record<string, number>> = {
6
+ node-b: 16,
7
+ node-c: 4,
8
+ 'host-e-wsl': 5,
9
+ };
10
+
11
+ // Only this host/tier pair has a measured lite allocation. Other pairs fail closed to zero.
12
+ const LITE_HOST_MAX: Readonly<Record<string, number>> = { mbp: 7 };
13
+
14
+ export function isWarmPoolProfile(value: unknown): value is WarmPoolProfile {
15
+ return typeof value === 'string' && (WARM_POOL_PROFILES as readonly string[]).includes(value);
16
+ }
17
+
18
+ /** Parse a configured profile. Missing or invalid values fail closed to the fixed profile. */
19
+ function parseWarmPoolProfile(value: unknown): WarmPoolProfile {
20
+ return isWarmPoolProfile(value) ? value : 'fixed';
21
+ }
22
+
23
+ /** Read the profile from either the full config object or its pod section. */
24
+ export function resolveWarmPoolProfile(config: unknown): WarmPoolProfile {
25
+ if (!config || typeof config !== 'object' || Array.isArray(config)) return 'fixed';
26
+ const root = config as Record<string, unknown>;
27
+ const pod = root.pod && typeof root.pod === 'object' && !Array.isArray(root.pod)
28
+ ? root.pod as Record<string, unknown>
29
+ : root;
30
+ const raw = root.raw && typeof root.raw === 'object' && !Array.isArray(root.raw)
31
+ ? root.raw as Record<string, unknown>
32
+ : undefined;
33
+ const rawPod = raw?.pod && typeof raw.pod === 'object' && !Array.isArray(raw.pod)
34
+ ? raw.pod as Record<string, unknown>
35
+ : undefined;
36
+ return parseWarmPoolProfile(pod.warmPoolProfile ?? rawPod?.warmPoolProfile);
37
+ }
38
+
39
+ /** Physical warm-worker cap for a host and worker memory tier; unknown pairs are unmeasured (0). */
40
+ export function resolveWarmPoolQuota(profile: WarmPoolProfile, host: string, tier: WarmPoolTier): number {
41
+ if (!isWarmPoolProfile(profile) || !host.trim()) return 0;
42
+ if (tier === 'lite') return Object.hasOwn(LITE_HOST_MAX, host) ? LITE_HOST_MAX[host] : 0;
43
+ if (tier === 'standard') return Object.hasOwn(STANDARD_HOST_MAX, host) ? STANDARD_HOST_MAX[host] : 0;
44
+ return 0;
45
+ }
@@ -113,3 +113,206 @@ export function classifyMustFixRound(
113
113
  }
114
114
  return { class: 'new-defect', reason: '앞 회차에 없던 새 지적 — 새 실결함 수렴으로 그대로 간다' };
115
115
  }
116
+
117
+ // ── 범위 판정 축 (REVIEW-MUSTFIX-CLASSIFY 첫 조각 · 대표 10-17 19:3x) ──
118
+ //
119
+ // 회차 분류(①②③) 위에 must-fix «한 줄마다» 범위를 가른다:
120
+ // in-scope (가) 이 PR 범위 안 — 언급한 파일이 PR 변경 파일·칸 대상 경로 안이고, 쪼갤 신호가 없다 → 고친다.
121
+ // split (나) 새 축 — PR 밖 파일 · 다른 PR · 설계 문서 · 다른 자리 결정 · 앞 라운드에 없던 축(r≥3) · ③ recurring
122
+ // · ② 착지 뒤 증거(③·② 는 범위 입력·경로와 무관하게 split) → 같은 런에서 고치지 않고 «중간 착지 ⊕ 연결 골»로 뗀다.
123
+ // ask-owner (다) 판단 불가 — 신호가 엇갈리거나, 범위 입력(변경 파일·대상 경로)이 없거나, 신호가 하나도 없다 → 칸 주인 HITL.
124
+ // ⛔ 결정적 신호만(이 조각엔 LLM 판정 없음). ⛔ 입력이 없으면 «범위 밖 신호 없음»으로 읽지 않는다 — ask-owner.
125
+ // ⛔ in-scope 는 «긍정 증거»(PR 안 파일 언급)가 있을 때만 — 신호가 없다고 범위 안이 아니다.
126
+
127
+ export type MustFixScope = 'in-scope' | 'split' | 'ask-owner';
128
+
129
+ export type MustFixScopeSignal =
130
+ | 'path-inside' | 'path-outside' | 'other-pr' | 'design-doc' | 'seat-decision'
131
+ | 'new-axis' | 'recurring' | 'post-land-evidence' | 'no-scope-input' | 'no-signal'
132
+ /** PR 번호를 언급했지만 이 PR 번호를 모른다 — 자기 번호일 수 있어 other-pr 로 단정하지 않는다. */
133
+ | 'pr-unknown'
134
+ /** 대상 경로 밖이지만 PR 변경 파일을 안 쟀다 — 실제 변경 파일일 수 있어 «밖»으로 단정하지 않는다. */
135
+ | 'path-unmeasured';
136
+
137
+ export interface MustFixScopeInput {
138
+ /** PR 변경 파일 목록. undefined = 안 쟀다(빈 배열과 다르다). */
139
+ readonly changedFiles?: readonly string[];
140
+ /** 칸·골 대상 경로(hotPaths). undefined = 안 쟀다. */
141
+ readonly targetPaths?: readonly string[];
142
+ /** 이 PR 번호 — 자기 번호 언급은 «다른 PR» 이 아니다. */
143
+ readonly prNumber?: number;
144
+ /** 리뷰 라운드(1부터). undefined = 안 쟀다 → new-axis 신호를 안 낸다. */
145
+ readonly reviewRound?: number;
146
+ /** 앞 라운드 must-fix. undefined = 안 쟀다 → new-axis 신호를 안 낸다. */
147
+ readonly prevItems?: readonly MustFixItem[];
148
+ /** 이 회차 ③ recurring 으로 짝지어진 정규화 문면. */
149
+ readonly recurring?: readonly string[];
150
+ }
151
+
152
+ export interface MustFixScopeJudgement {
153
+ readonly text: string;
154
+ readonly scope: MustFixScope;
155
+ readonly signals: readonly MustFixScopeSignal[];
156
+ readonly reason: string;
157
+ /** 언급한 경로 중 PR 범위 밖인 것 — 연결 골 대상 경로 초안. */
158
+ readonly outsidePaths?: readonly string[];
159
+ /** 언급한 경로 중 PR 범위 안인 것. */
160
+ readonly insidePaths?: readonly string[];
161
+ /** ② 착지 뒤 증거 종류 — 연결 골 판정선을 시험이 아니라 착지 후 관측으로 낸다. */
162
+ readonly evidence?: MustFixEvidenceKind;
163
+ }
164
+
165
+ const SPLIT_SIGNALS: ReadonlySet<MustFixScopeSignal> = new Set([
166
+ 'path-outside', 'other-pr', 'design-doc', 'seat-decision', 'new-axis', 'recurring', 'post-land-evidence',
167
+ ]);
168
+ /** «앞 라운드에 없던 축»이 쪼갤 신호가 되는 첫 라운드(대표 규칙 «r3 부터 (나) 먼저 뗀다»). */
169
+ export const NEW_AXIS_SPLIT_FROM_ROUND = 3;
170
+
171
+ const PATH_RE = /(?:[\w@.-]+\/)+[\w@.-]+\.[A-Za-z]{1,5}\b|\b[\w-]+(?:\.[\w-]+)*\.(?:tsx?|mjs|cjs|jsx?|json|md|ya?ml|sh|py)\b/gu;
172
+ const DESIGN_DOC_RE = /\b(?:RFC|MANUAL|DECISION)[-_\s]/u;
173
+ const SEAT_DECISION_RE = /(?:다른\s*자리|자리\s*결정|대표\s*결정|\u{1F451}|owner\s+decision|another\s+seat)/iu;
174
+
175
+ function normPath(p: string): string {
176
+ return p.replace(/^\.\//u, '').replace(/[),.;:]+$/u, '');
177
+ }
178
+
179
+ /** 경로가 범위 집합 안인가 — 정확 일치 · 디렉터리 접두 · (언급이 파일 이름뿐이면) 파일 이름 일치. */
180
+ function pathInside(mention: string, scope: readonly string[]): boolean {
181
+ const m = normPath(mention);
182
+ return scope.some((raw) => {
183
+ const s = normPath(raw);
184
+ if (s === m) return true;
185
+ if (s.endsWith('/') ? m.startsWith(s) : m.startsWith(`${s}/`)) return true;
186
+ return !m.includes('/') && s.split('/').at(-1) === m;
187
+ });
188
+ }
189
+
190
+ /** 단순 토큰 자카드(2자 이상 · 소문자) — 앞 라운드에 없던 축 판정용. */
191
+ export function mustFixTokenJaccard(a: string, b: string): number {
192
+ const tok = (s: string): Set<string> => new Set(s.toLowerCase().split(/[^\p{L}\p{N}_]+/u).filter((t) => t.length >= 2));
193
+ const x = tok(a);
194
+ const y = tok(b);
195
+ if (x.size === 0 && y.size === 0) return 0;
196
+ let inter = 0;
197
+ for (const t of x) if (y.has(t)) inter++;
198
+ return inter / (x.size + y.size - inter);
199
+ }
200
+
201
+ export function judgeMustFixScope(item: MustFixItem, input: MustFixScopeInput): MustFixScopeJudgement {
202
+ const signals: MustFixScopeSignal[] = [];
203
+ const scopePaths = [...(input.changedFiles ?? []), ...(input.targetPaths ?? [])];
204
+ const scopeMeasured = input.changedFiles !== undefined || input.targetPaths !== undefined;
205
+ const mentions = [...new Set((item.text.match(PATH_RE) ?? []).map(normPath))];
206
+ const insidePaths = scopeMeasured ? mentions.filter((m) => pathInside(m, scopePaths)) : [];
207
+ const outsidePaths = scopeMeasured ? mentions.filter((m) => !pathInside(m, scopePaths)) : mentions;
208
+ if (!scopeMeasured) signals.push('no-scope-input');
209
+ else {
210
+ if (insidePaths.length) signals.push('path-inside');
211
+ // 변경 파일을 안 쟀으면 대상 경로 밖이라는 사실만으로 «PR 밖»이 아니다.
212
+ if (outsidePaths.length) signals.push(input.changedFiles === undefined ? 'path-unmeasured' : 'path-outside');
213
+ }
214
+ const prs = [...item.text.matchAll(/#(\d{5})\b/gu)].map((m) => Number(m[1]));
215
+ if (prs.length > 0 && input.prNumber === undefined) signals.push('pr-unknown');
216
+ else if (prs.some((n) => n !== input.prNumber)) signals.push('other-pr');
217
+ if (DESIGN_DOC_RE.test(item.text)) signals.push('design-doc');
218
+ if (SEAT_DECISION_RE.test(item.text)) signals.push('seat-decision');
219
+ if (item.evidence !== undefined) signals.push('post-land-evidence');
220
+ if (input.recurring?.includes(mustFixKey(item.text))) signals.push('recurring');
221
+ if (input.reviewRound !== undefined && input.reviewRound >= NEW_AXIS_SPLIT_FROM_ROUND
222
+ && input.prevItems !== undefined && input.prevItems.length > 0
223
+ && input.prevItems.every((p) => mustFixTokenJaccard(p.text, item.text) === 0)) signals.push('new-axis');
224
+
225
+ const split = signals.filter((s) => SPLIT_SIGNALS.has(s));
226
+ const paths = {
227
+ ...(outsidePaths.length ? { outsidePaths } : {}),
228
+ ...(insidePaths.length ? { insidePaths } : {}),
229
+ ...(item.evidence !== undefined ? { evidence: item.evidence } : {}),
230
+ };
231
+ if (signals.includes('recurring')) {
232
+ return { text: item.text, scope: 'split', signals, reason: '같은 축이 수리 뒤 다시 나왔다 — 같은 런 재수리 대신 연결 골로 뗀다', ...paths };
233
+ }
234
+ // ② 착지 뒤 증거는 줄 단위 사실 — 경로가 PR 안이어도 같은 런에서 못 낸다. 회차 분류 ② 와 늘 같은 갈래(split)로 간다.
235
+ if (signals.includes('post-land-evidence')) {
236
+ return { text: item.text, scope: 'split', signals, reason: '증거는 착지 뒤에만 난다 — 그림자 착지 → 관측 → live 연결 골로 뗀다', ...paths };
237
+ }
238
+ if (signals.includes('path-unmeasured')) {
239
+ return { text: item.text, scope: 'ask-owner', signals, reason: '대상 경로 밖 경로를 언급했지만 PR 변경 파일을 안 쟀다 — PR 밖인지 못 가린다', ...paths };
240
+ }
241
+ if (signals.includes('pr-unknown')) {
242
+ return { text: item.text, scope: 'ask-owner', signals, reason: 'PR 번호를 언급했는데 이 PR 번호를 모른다 — 다른 PR 인지 못 가린다', ...paths };
243
+ }
244
+ if (split.length > 0 && !scopeMeasured) {
245
+ return { text: item.text, scope: 'ask-owner', signals, reason: `쪼갤 신호(${split.join(' · ')})는 있으나 범위 입력이 없다 — 이 PR 이 이미 맡았는지 못 가린다`, ...paths };
246
+ }
247
+ if (split.length > 0 && signals.includes('path-inside')) {
248
+ return { text: item.text, scope: 'ask-owner', signals, reason: `신호가 엇갈린다 — PR 안 파일 언급 ⊕ 쪼갤 신호(${split.join(' · ')})`, ...paths };
249
+ }
250
+ if (split.length > 0) {
251
+ return { text: item.text, scope: 'split', signals, reason: `이 PR 범위 밖 신호(${split.join(' · ')}) — 중간 착지 ⊕ 연결 골로 뗀다`, ...paths };
252
+ }
253
+ if (signals.includes('path-inside')) {
254
+ return { text: item.text, scope: 'in-scope', signals, reason: '언급한 파일이 PR 범위 안이고 쪼갤 신호가 없다 — 이 PR 에서 고친다', ...paths };
255
+ }
256
+ if (scopeMeasured) signals.push('no-signal');
257
+ return {
258
+ text: item.text, scope: 'ask-owner', signals,
259
+ reason: scopeMeasured ? '범위 신호가 하나도 없다 — «없다»를 범위 안으로 읽지 않고 칸 주인에게 묻는다' : '범위 입력(변경 파일·대상 경로)이 없다 — 칸 주인에게 묻는다',
260
+ ...paths,
261
+ };
262
+ }
263
+
264
+ /** (나) split 한 줄의 «중간 착지 ⊕ 연결 골» 제안 — 다음 라운드 intent 스코프 경계 문장 ⊕ 연결 골 초안. */
265
+ export interface MustFixSplitProposal {
266
+ readonly text: string;
267
+ /** 다음 라운드 intent «의도적 스코프 경계» 에 넣을 문장(이유 포함). */
268
+ readonly intentScopeBoundary: string;
269
+ /** 연결 골 초안 — 대상 경로 ⊕ 판정선 한 줄. targetPaths 가 비면 «대상 경로 미상»(저작 단계에서 채운다). */
270
+ readonly linkGoal: { readonly targetPaths: readonly string[]; readonly verdictLine: string };
271
+ }
272
+
273
+ function clip(text: string, n = 120): string {
274
+ const t = text.trim().replace(/\s+/gu, ' ');
275
+ return t.length > n ? `${t.slice(0, n - 1)}…` : t;
276
+ }
277
+
278
+ function testPathFor(path: string): string | undefined {
279
+ if (/\.test\.tsx?$/u.test(path)) return path;
280
+ const m = /^(.*)\.(tsx?)$/u.exec(path);
281
+ return m ? `${m[1]}.test.${m[2]}` : undefined;
282
+ }
283
+
284
+ const EVIDENCE_OBSERVATION: Record<MustFixEvidenceKind, string> = {
285
+ 'live-caller': 'live 호출자가 실제로 부르는 것',
286
+ 'ops-consumption': '운영이 실제로 소비하는 것',
287
+ 'artifact-landing': '실물이 실제로 착지한 것',
288
+ };
289
+
290
+ /**
291
+ * 연결 골 대상 경로는 지적이 «언급한» 경로만 — 원래 골의 hotPaths 를 끌어다 대지 않는다(근거 없음 → 미상, 저작 단계에서 채운다).
292
+ * ② 착지 뒤 증거는 시험 통과로 증명되지 않으므로 판정선을 «그림자 착지 뒤 관측»으로 낸다.
293
+ */
294
+ export function proposeMustFixSplit(j: MustFixScopeJudgement): MustFixSplitProposal {
295
+ const targetPaths = j.outsidePaths?.length ? [...j.outsidePaths] : j.insidePaths?.length ? [...j.insidePaths] : [];
296
+ const test = targetPaths.map(testPathFor).find((p): p is string => p !== undefined);
297
+ const subject = clip(j.text, 80);
298
+ if (j.evidence !== undefined) {
299
+ return {
300
+ text: j.text,
301
+ intentScopeBoundary: `«${subject}» — 미완이 아니라 이 PR 의 결정이다: ${j.reason}(신호 ${j.signals.join(' · ')}). 연결 골로 뗐다 · 이것으로 must-fix 를 만들지 말 것`,
302
+ linkGoal: {
303
+ targetPaths,
304
+ verdictLine: `판정(착지 뒤 관측): 그림자 착지 뒤 ${EVIDENCE_OBSERVATION[j.evidence]}을 로그·원장에서 관측 — 관측 명령은 저작 단계에서 채운다(시험 통과만으로는 증명 아님)`,
305
+ },
306
+ };
307
+ }
308
+ return {
309
+ text: j.text,
310
+ intentScopeBoundary: `«${subject}» — 미완이 아니라 이 PR 의 결정이다: ${j.reason}(신호 ${j.signals.join(' · ')}). 연결 골로 뗐다 · 이것으로 must-fix 를 만들지 말 것`,
311
+ linkGoal: {
312
+ targetPaths,
313
+ verdictLine: test
314
+ ? `판정: bun test ${test} → «${subject}» 고정 시험 ⊕ 0 fail`
315
+ : `판정: «${subject}» 해소를 반증 명령 한 줄로 — 대상 경로 ${targetPaths.length ? targetPaths.join(' ') : '미상'}(저작 단계에서 채운다)`,
316
+ },
317
+ };
318
+ }
@@ -1,4 +1,4 @@
1
- import { executeClassifyNode } from '../workflow-runtime/nodes/classify.js';
1
+ import { runGraphClassifyNode } from '../graph-runner/runner.js';
2
2
  import { buildPremiseCard, type PremiseReviewCard, type PremiseReviewInput } from './premise-review.js';
3
3
  import { SUPERVISION_REWORK_SOURCES, type SupervisionReworkSource } from './supervision-vocabulary.js';
4
4
  import type { ClassifyNode, JudgmentContext, JudgmentResult, NodeExecContext, WorkflowDefinition, WorkflowDeps } from '../workflow-runtime/types.js';
@@ -155,13 +155,10 @@ export function createReworkBudgetJudgment(callLLM: WorkflowDeps['callLLM'], opt
155
155
  };
156
156
  let modelReasoning = '';
157
157
  let premiseReview: PremiseReviewCard | undefined;
158
- const result = await executeClassifyNode(node, execContext, {
159
- callLLM: async (args) => {
160
- modelReasoning = await callLLM(args);
161
- return modelReasoning;
162
- },
163
- runBash: async () => ({ stdout: '', stderr: '', exitCode: 0 }),
164
- });
158
+ const result = await runGraphClassifyNode(node, execContext, async (args) => {
159
+ modelReasoning = await callLLM(args);
160
+ return modelReasoning;
161
+ }, { caller: 'rework-budget-judgment' });
165
162
  const evidence = (): ReworkBudgetEvidence => ({
166
163
  observations,
167
164
  modelReasoning,
@@ -11,23 +11,30 @@
11
11
  */
12
12
  import { debug } from '../debug/log.js';
13
13
  import { appendRunLedgerEntry, type RunLedgerEntry, type RunLedgerWriter, type RunShardIdentity } from './run-ledger.js';
14
+ import type { PodChildEvidence } from '../task-orchestrator/surfaces/self-implement.js';
14
15
 
15
16
  /** 닫힌 목록 — 못 고르면 `unclassified`. */
16
17
  export const RUN_STOP_CLASSES = [
17
18
  'env-unrelated', 'main-sync', 'pod-died', 'review-repeat',
18
- 'review-out-of-scope', 'evidence-uncovered', 'fabric', 'launch-failed', 'gate-failed', 'unclassified',
19
+ 'review-out-of-scope', 'scope-escape', 'evidence-uncovered', 'fabric', 'launch-failed', 'gate-failed', 'unclassified',
19
20
  ] as const;
20
21
  export type RunStopClass = typeof RUN_STOP_CLASSES[number];
21
22
 
22
23
  /** 런 원장 `event='stop'` 줄의 `data` 모양(STOP-AUTOHEAL 이 소비한다). */
23
24
  export interface RunStopRecord {
24
25
  class: RunStopClass;
26
+ /** Last known stop site; absent in older ledger rows. */
27
+ site?: string;
25
28
  /** 한 줄 · ≤120자 · 결정 라벨(원 로그 꼬리 금지). */
26
29
  cause: string;
27
30
  /** 근거 위치 — PR URL · `run-ledger:<runId>:<event>` · 파일 경로. */
28
31
  evidenceRef: string;
29
32
  /** 다음 한 수(사람·힐러가 읽는다). */
30
33
  nextMove: string;
34
+ /** Facts from the complete child JSON, lifted before the Pod stdout tail is shortened. */
35
+ childEvidence?: PodChildEvidence;
36
+ /** Exact structured Pod error code, when the host received one. */
37
+ terminationReason?: 'pod-job-failed';
31
38
  }
32
39
 
33
40
  export const RUN_STOP_EVENT = 'stop';
@@ -44,6 +51,8 @@ export interface RunStopInput {
44
51
  nextMove: string;
45
52
  /** 관측용 — 어느 자리가 불렀나(merge-hold · implement-aborted · draft-pr-open-failed · pod-exit · launch-failed). */
46
53
  site?: string;
54
+ childEvidence?: PodChildEvidence;
55
+ terminationReason?: 'pod-job-failed';
47
56
  }
48
57
 
49
58
  export function isRunStopClass(value: unknown): value is RunStopClass {
@@ -96,9 +105,12 @@ export function forgetRunStop(runId: string): void {
96
105
  export function recordRunStop(input: RunStopInput, write: RunLedgerWriter = appendRunLedgerEntry): RunLedgerEntry {
97
106
  const record: RunStopRecord = {
98
107
  class: isRunStopClass(input.class) ? input.class : 'unclassified',
108
+ ...(input.site ? { site: input.site } : {}),
99
109
  cause: boundRunStopCause(input.cause),
100
110
  evidenceRef: input.evidenceRef,
101
111
  nextMove: input.nextMove,
112
+ ...(input.childEvidence ? { childEvidence: input.childEvidence } : {}),
113
+ ...(input.terminationReason ? { terminationReason: input.terminationReason } : {}),
102
114
  };
103
115
  const entry: RunLedgerEntry = {
104
116
  timestamp: new Date().toISOString(), runId: input.runId, event: RUN_STOP_EVENT,
@@ -120,5 +132,8 @@ export function readRunStopRecord(entry: RunLedgerEntry): RunStopRecord | undefi
120
132
  if (entry.event !== RUN_STOP_EVENT) return undefined;
121
133
  const data = entry.data as Partial<RunStopRecord>;
122
134
  if (typeof data.cause !== 'string' || typeof data.evidenceRef !== 'string' || typeof data.nextMove !== 'string') return undefined;
123
- return { class: isRunStopClass(data.class) ? data.class : 'unclassified', cause: data.cause, evidenceRef: data.evidenceRef, nextMove: data.nextMove };
135
+ return { class: isRunStopClass(data.class) ? data.class : 'unclassified', cause: data.cause, evidenceRef: data.evidenceRef, nextMove: data.nextMove,
136
+ ...(typeof data.site === 'string' ? { site: data.site } : {}),
137
+ ...(data.childEvidence ? { childEvidence: data.childEvidence } : {}),
138
+ ...(data.terminationReason === 'pod-job-failed' ? { terminationReason: data.terminationReason } : {}) };
124
139
  }
@@ -424,6 +424,34 @@ export function assessRunningRuns(
424
424
  return { ...(partial ? { completeness: 'partial' as const, unreadable, count: { count: null, lowerBound: counts.running + counts['probable-running'], unreadable } } : {}), entries, counts, total, countedStatuses, quantities: quantitySummary({ entries, counts, total, countedStatuses, observation }), observation, lingeringLaunchParents: { observation: 'indeterminate' }, ledger: { ledgerDirectories: [], unreadableLedgerCount: ledgerObservation.unreadableLedgerCount, unreadableLedgerDirectoryCount: ledgerObservation.unreadableLedgerDirectoryCount, missingLedgerDirectoryCount: ledgerObservation.missingLedgerDirectoryCount, unreadableLedgerDirectoryAccessCount: ledgerObservation.unreadableLedgerDirectoryAccessCount, indeterminateLedgerDirectoryCount: ledgerObservation.indeterminateLedgerDirectoryCount }, pty: { unreadable: [...pty.unreadable], observedRefCount: pty.refs.length, withoutRunIdCount, notCountedRefCount }, phases: { targetCount: 0, readableTargetCount: 0, unreadableTargetCount: 0, unreadableTargets: [], discardedNonStageEventCount: 0 } };
425
425
  }
426
426
 
427
+ /** A legacy state alias can point at the same physical ledger. Keep missing or unreadable
428
+ * directories in the query so they still contribute an incomplete-observation signal. */
429
+ type LedgerDirectoryIdentity = { dev: bigint; ino: bigint; isDirectory(): boolean };
430
+
431
+ export function distinctPhysicalLedgerDirectories(
432
+ directories: readonly string[],
433
+ statDirectory: (directory: string) => LedgerDirectoryIdentity = (directory) => statSync(directory, { bigint: true }),
434
+ ): string[] {
435
+ const seen = new Map<string, string>();
436
+ const distinct: string[] = [];
437
+ for (const directory of directories) {
438
+ try {
439
+ const stat = statDirectory(directory);
440
+ if (stat.isDirectory()) {
441
+ const identity = `${stat.dev}:${stat.ino}`;
442
+ const first = seen.get(identity);
443
+ if (first !== undefined) {
444
+ debug.log('self-implement.running-runs', 'ledger-directory-alias', { first, alias: directory });
445
+ continue;
446
+ }
447
+ seen.set(identity, directory);
448
+ }
449
+ } catch { /* Preserve this target for the federated query's missing/unreadable judgment. */ }
450
+ distinct.push(directory);
451
+ }
452
+ return distinct;
453
+ }
454
+
427
455
  export function queryRunningRuns(options: { includeTest?: boolean; runIds?: readonly string[]; caller?: string; noCache?: boolean } = {}, deps: RunningRunsQueryDeps = {}): QueriedRunningRunsResult {
428
456
  const directoryFailures = new Map<string, ReturnType<typeof classifyFederatedLedgerDirectoryReadFailure>>();
429
457
  const queryLedgers = deps.queryLedgers ?? ((queryOptions: Parameters<typeof queryFederatedUnfinishedRunLedgers>[0]) => queryFederatedUnfinishedRunLedgers({
@@ -466,7 +494,7 @@ export function queryRunningRuns(options: { includeTest?: boolean; runIds?: read
466
494
  if (collectLedgerDirectories) {
467
495
  const ledgerDirectoryCollectionStartedAt = Date.now();
468
496
  try {
469
- collectedLedgerDirectories = ledgerDirectories({ includeTest: options.includeTest });
497
+ collectedLedgerDirectories = distinctPhysicalLedgerDirectories(ledgerDirectories({ includeTest: options.includeTest }));
470
498
  } finally {
471
499
  ledgerDirectoryCollectionElapsedMs = Date.now() - ledgerDirectoryCollectionStartedAt;
472
500
  }
@@ -21,3 +21,116 @@ export function classifyOutOfScope(outsideFiles: readonly string[], declaredPath
21
21
  for (const file of outsideFiles) (folders.has(dirOf(normalize(file))) ? adjacent : other).push(file);
22
22
  return { adjacent, other };
23
23
  }
24
+
25
+ // SCOPE-AS-DIRECTION (0.2.35 · 대표 10-21 «골은 방향·원칙·KPI 를 정하고 구현은 적응한다 — 파일 단위 마이크로 관리는 틀렸다»).
26
+ // 10-20: 13 runs held with PR 0; half of the crossed files were necessary wiring (CLI registration, production callers,
27
+ // ledger files). Target paths are now the starting point: outside edits are accepted, named with a kind, and handed to
28
+ // the reviewer in the PR body. Only a deletion, a protected path, or an outside count over the cap stops the run.
29
+
30
+ export type ScopeExpansionKind = 'neighbour' | 'caller-or-registration' | 'paired-test' | 'other';
31
+ export interface ScopeExpansionFile { path: string; kind: ScopeExpansionKind }
32
+ export interface ScopeExpansion { files: ScopeExpansionFile[]; count: number }
33
+ export type ScopeStopReason = 'deletion' | 'protected-path' | 'over-cap' | 'name-cap';
34
+
35
+ /** Accepted outside files above this count stop the run: past it the change is no longer «the goal, adapted». */
36
+ export const SCOPE_EXPANSION_CAP = 10;
37
+
38
+ const TEST_FILE = /\.(test|spec)\.[cm]?[jt]sx?$/;
39
+ const CODE_EXT = /\.(?:[cm]?[jt]sx?)$/;
40
+ const baseOf = (path: string): string => path.slice(path.lastIndexOf('/') + 1);
41
+ const stemOf = (path: string): string => baseOf(path).replace(TEST_FILE, '').replace(/\.[^.]+$/, '');
42
+ const withoutCodeExt = (path: string): string => path.replace(CODE_EXT, '');
43
+
44
+ /** Paths an unattended run never edits on its own: rules, anything credential-like, production elanous config. */
45
+ export function isProtectedScopePath(path: string): boolean {
46
+ const p = normalize(path);
47
+ if (p === '.rules' || p.startsWith('.rules/')) return true;
48
+ if (/credential|secret/i.test(p)) return true;
49
+ const base = baseOf(p);
50
+ if (base === 'auth.json' || base === '.env' || base.startsWith('.env.')) return true;
51
+ return /(^|\/)\.elanous[^/]*\/(.*\/)?config\.json$/.test(p);
52
+ }
53
+
54
+ function resolveRelative(fromFile: string, spec: string): string {
55
+ const parts = dirOf(fromFile) ? dirOf(fromFile).split('/') : [];
56
+ for (const seg of spec.split('/')) {
57
+ if (seg === '.' || seg === '') continue;
58
+ if (seg === '..') parts.pop(); else parts.push(seg);
59
+ }
60
+ return parts.join('/');
61
+ }
62
+
63
+ const escapeRegExp = (text: string): string => text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
64
+
65
+ /** Name each outside file's relation to the declared targets. Deterministic: path shape and plain text only.
66
+ * Order of kinds: paired-test → neighbour (same folder as a declared file) → caller-or-registration (index.ts,
67
+ * *-cli.ts, imports a declared file, or names an exported symbol of one) → other. `readFile` is relative to the tree. */
68
+ export function classifyScopeExpansion(
69
+ outsideFiles: readonly string[], declaredPaths: readonly string[], readFile: (path: string) => string | undefined = () => undefined,
70
+ ): ScopeExpansionFile[] {
71
+ const declared = declaredPaths.map(normalize);
72
+ const adjacentSet = new Set(classifyOutOfScope(outsideFiles, declaredPaths).adjacent);
73
+ const declaredFiles = declared.filter(path => /\.[A-Za-z0-9]+$/.test(baseOf(path)));
74
+ const declaredModules = new Set(declaredFiles.filter(path => CODE_EXT.test(path)).map(withoutCodeExt));
75
+ const pairStems = new Set([...declaredFiles, ...outsideFiles.map(normalize).filter(path => !TEST_FILE.test(path))].map(stemOf));
76
+ const exportedNames: string[] = [];
77
+ for (const file of declaredFiles) {
78
+ let text: string | undefined;
79
+ try { text = readFile(file); } catch { text = undefined; }
80
+ if (!text) continue;
81
+ for (const match of text.matchAll(/export\s+(?:default\s+)?(?:async\s+)?(?:function\*?|const|let|var|class|interface|type|enum)\s+([A-Za-z_$][\w$]*)/g)) {
82
+ if (match[1]!.length >= 4 && !exportedNames.includes(match[1]!)) exportedNames.push(match[1]!);
83
+ }
84
+ }
85
+ const namePatterns = exportedNames.map(name => new RegExp(`(^|[^\\w$])${escapeRegExp(name)}([^\\w$]|$)`));
86
+ const callsDeclared = (file: string): boolean => {
87
+ let text: string | undefined;
88
+ try { text = readFile(file); } catch { text = undefined; }
89
+ if (!text) return false;
90
+ for (const match of text.matchAll(/(?:from\s+|import\s*\(\s*|require\s*\(\s*|import\s+)['"]([^'"]+)['"]/g)) {
91
+ const spec = match[1]!;
92
+ if (spec.startsWith('.') && declaredModules.has(withoutCodeExt(resolveRelative(file, spec)))) return true;
93
+ }
94
+ return namePatterns.some(pattern => pattern.test(text!));
95
+ };
96
+ return outsideFiles.map(path => {
97
+ const p = normalize(path);
98
+ const base = baseOf(p);
99
+ const kind: ScopeExpansionKind = TEST_FILE.test(p) && pairStems.has(stemOf(p)) ? 'paired-test'
100
+ : adjacentSet.has(path) ? 'neighbour'
101
+ : /^index\.[cm]?[jt]sx?$/.test(base) || /-cli\.[cm]?[jt]sx?$/.test(base) || callsDeclared(p) ? 'caller-or-registration'
102
+ : 'other';
103
+ return { path, kind };
104
+ });
105
+ }
106
+
107
+ export type ScopeExpansionDecision =
108
+ | { accept: true; expansion: ScopeExpansion }
109
+ | { accept: false; reasons: ScopeStopReason[]; deleted: string[]; protectedPaths: string[]; expansion: ScopeExpansion };
110
+
111
+ /** Accept outside edits by default; stop only on a deletion, a protected path, a count over the cap, or an
112
+ * incomplete name list (the guard cannot judge files it did not see). */
113
+ export function decideScopeExpansion(input: {
114
+ outsideFiles: readonly string[]; declaredPaths: readonly string[]; deleted: readonly string[]; nameCapReached: boolean;
115
+ cap?: number; readFile?: (path: string) => string | undefined;
116
+ }): ScopeExpansionDecision {
117
+ const files = classifyScopeExpansion(input.outsideFiles, input.declaredPaths, input.readFile);
118
+ const expansion: ScopeExpansion = { files, count: files.length };
119
+ const protectedPaths = input.outsideFiles.filter(isProtectedScopePath);
120
+ const reasons: ScopeStopReason[] = [];
121
+ if (input.deleted.length) reasons.push('deletion');
122
+ if (protectedPaths.length) reasons.push('protected-path');
123
+ if (files.length > (input.cap ?? SCOPE_EXPANSION_CAP)) reasons.push('over-cap');
124
+ if (input.nameCapReached) reasons.push('name-cap');
125
+ return reasons.length ? { accept: false, reasons, deleted: [...input.deleted], protectedPaths, expansion } : { accept: true, expansion };
126
+ }
127
+
128
+ /** PR body section for the reviewer: each accepted outside file with its kind, judged against the goal's direction. */
129
+ export function renderScopeExpansionSection(expansion: ScopeExpansion | undefined): string {
130
+ if (!expansion || expansion.files.length === 0) return '';
131
+ return [
132
+ '', '', `## 범위 확장 (${expansion.count})`,
133
+ '대상 경로는 출발점이다 — 아래 파일은 대상 밖에서 바뀌었고 자동으로 받아들였다. 골의 방향·원칙·KPI 에 비춰 판단해 달라.',
134
+ ...expansion.files.map(file => `- \`${file.path}\` — ${file.kind}`),
135
+ ].join('\n');
136
+ }