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
@@ -9,21 +9,24 @@
9
9
  // 구현을 교체(누적 아님). 기존 PR 없으면 새로 생성.
10
10
 
11
11
  import { spawnSync } from 'node:child_process';
12
+ import { randomUUID } from 'node:crypto';
12
13
  import { githubAutomationToken } from '../auth/github-app-token.js';
13
- import { debug } from '../debug/log.js';
14
+ import { debug, redactSecretText } from '../debug/log.js';
14
15
  import { POD_GITHUB_CREDENTIAL_TOKEN_ENV, POD_GITHUB_CREDENTIAL_URL_ENV } from '../nexus/api/pod-credential-api.js';
15
16
  import { runGitWithRetry } from '../git-fs/retry.js';
16
17
  import { DEFAULT_BRANCH_WORKTREE_BASE } from '../git-fs/worktree.js';
17
18
  import { isElanousRuntimeArtifactPath } from '../self-implement/gate-scope.js';
18
19
  import { isTransientExecutionFailure } from '../self-dev/execution-transient.js';
19
20
  import { withGhRestFallback } from './gh-rest-fallback.js';
20
- import { cellIdFromBody, guardNewPr, parseDiffHunks, readOpenPrs, recordGuardUnmeasured, type GuardVerdict, type HunkOverlapMode, type Seat } from '../pr-tool/census.js';
21
+ import { cardIdFromBody, cellIdFromBody, guardNewPr, hasCardMarker, parseDiffHunks, readOpenPrs, recordGuardUnmeasured, sharedCensusDiffCache, sliceMarkerFromBody, spawnParallelCommands, type GuardVerdict, type HunkOverlapMode, type PrToolParallelCommand, type Seat } from '../pr-tool/census.js';
22
+ import { labelsForAxis, PR_LABEL_NAMES } from '../github/pr-labels.js';
21
23
  import { getUserConfig } from '../user-config.js';
24
+ import { runSuffixKey } from '../self-implement/salvage-branches.js';
22
25
 
23
26
  /** ★ stderr 캡처(대표 2026-07-21·관측 갭) — 종전엔 stdout 만 담아 git/gh 실패 사유가 소실됐다
24
27
  * (705308: makePr 실패가 bare null 로 뭉뚱그려져 triage 가 "인증·네트워크"로 환각 오라우팅).
25
28
  * 이제 err 에 stderr 를 담아 upsertPr 가 실패 단계·사유를 구조화해 반환한다. */
26
- export interface CmdResult { ok: boolean; out: string; err?: string }
29
+ export interface CmdResult { ok: boolean; out: string; err?: string; /** 실제 종료 코드 — defaultCmdRunner 만 채운다(스텁은 ok 로만 판정). */ rc?: number }
27
30
  /** 명령 실행 추상화(주입형·테스트 스텁) — git/gh 를 실제로 돌리지 않고 로직 검증. */
28
31
  export type CmdRunner = (cmd: string, args: readonly string[], opts?: { cwd?: string }) => CmdResult;
29
32
 
@@ -75,7 +78,10 @@ export const defaultCmdRunner: CmdRunner = (cmd, args, opts) => {
75
78
  // never read an overflow as success.
76
79
  const r = spawnSync(cmd, [...args], { encoding: 'utf-8', timeout: 120_000, maxBuffer: 256 * 1024 * 1024, env, ...(opts?.cwd ? { cwd: opts.cwd } : {}) });
77
80
  const overflow = (r.error as NodeJS.ErrnoException | undefined)?.code === 'ENOBUFS';
78
- return { ok: r.status === 0 && !overflow, out: (r.stdout ?? '').trim(), err: [(r.stderr ?? '').trim(), overflow ? 'output exceeded 256MiB (ENOBUFS)' : ''].filter(Boolean).join('\n') };
81
+ const result: CmdResult = { ok: r.status === 0 && !overflow, out: (r.stdout ?? '').trim(), err: [(r.stderr ?? '').trim(), overflow ? 'output exceeded 256MiB (ENOBUFS)' : ''].filter(Boolean).join('\n') };
82
+ // Keep the historical enumerable result shape while making the exit code available to PR incidents.
83
+ if (typeof r.status === 'number') Object.defineProperty(result, 'rc', { value: r.status, enumerable: false });
84
+ return result;
79
85
  } catch (e) { return { ok: false, out: '', err: e instanceof Error ? e.message : String(e) }; }
80
86
  };
81
87
 
@@ -88,6 +94,8 @@ export function extractPrNumber(prUrl: string): number | null {
88
94
  export interface UpsertPrInput {
89
95
  /** 안정 브랜치명(se/…-<phaseHex>) — 재활용 키. */
90
96
  branch: string;
97
+ /** Owning self-implement run; used to keep temporary upload refs inside its Pod push fence. */
98
+ runId?: string;
91
99
  /** 격리 worktree 경로(git cwd). */
92
100
  worktreePath: string;
93
101
  title: string;
@@ -118,8 +126,10 @@ export interface UpsertPrResult { url: string; reused: boolean }
118
126
  * 특히 `noop`(nothing to commit)은 **실패가 아니라 이미 반영된 no-op** — 호출부가 정직 PASS 처리.
119
127
  * 나머지 reason(add/commit/push/gh)은 진짜 실패로 detail(stderr)과 함께 관측·pr-failed. */
120
128
  export type UpsertPrOutcome =
121
- | { ok: true; url: string; reused: boolean; labelsApplied?: boolean; labelsOmitted?: boolean }
122
- | { ok: false; reason: 'add' | 'commit' | 'base' | 'noop' | 'push' | 'gh' | 'guard'; detail: string };
129
+ | { ok: true; url: string; reused: boolean; labelsApplied?: boolean; labelsOmitted?: boolean;
130
+ supersededPr?: number }
131
+ | { ok: false; reason: 'add' | 'commit' | 'base' | 'noop' | 'push' | 'gh' | 'guard'; detail: string;
132
+ incident?: PrCreateFailureIncident };
123
133
 
124
134
  /** 관측된 문면 두 가지:
125
135
  * could not add label: 'auto-review' not found
@@ -178,7 +188,7 @@ function readPrMergeState(run: CmdRunner, prNumber: number, cwd?: string): Merge
178
188
  export type FindPrForBranchOutcome =
179
189
  | { status: 'ok OUTPUT'; url: string }
180
190
  | { status: 'ok EMPTY'; url: null }
181
- | { status: 'FAILED'; url: null }
191
+ | { status: 'FAILED'; url: null; rc?: number; stderrTail?: string }
182
192
  | { status: 'SKIPPED'; url: null };
183
193
 
184
194
  export interface PrManager {
@@ -316,25 +326,276 @@ function isTransientPushFailure(detail: string): boolean {
316
326
  return isTransientExecutionFailure(pushFailureMessageForTransientCheck(detail));
317
327
  }
318
328
 
329
+ // ── 칸 PR-CREATE-FAIL-OBSERVE-FU — PR 생성 실패 incident(관측 단위) ──────────────
330
+ // run-7308cfbf·run-fabc2564·run-32bca71e·run-42876ab6 의 draft PR 생성 실패가
331
+ // outcome 원장만으로는 push·gh create·인증·원격 충돌 중 어느 단계인지 못 가렸다.
332
+ // 하나의 incident 가 push 와 gh 단계를 각각 식별해 rc·stderr 꼬리·branch/remote·push 성패를 남긴다.
333
+ /** PR 생성 경로에서 실패 관측 대상인 단계. */
334
+ export type PrCreateStageId = 'push' | 'gh';
335
+ /** 단계별 관측: 실행 여부 · 종료 코드 · (자격증명 제거된) stderr 꼬리 · push 성공 여부. */
336
+ export interface PrCreateStageObservation {
337
+ stage: PrCreateStageId;
338
+ ran: boolean;
339
+ rc?: number;
340
+ stderrTail?: string;
341
+ /** push 단계 전용 — force-push 최종 성공 여부. */
342
+ ok?: boolean;
343
+ }
344
+ /** PR 생성 실패 한 건 — push/gh 두 단계 관측을 하나의 기록에. */
345
+ export interface PrCreateFailureIncident {
346
+ runId?: string;
347
+ branch: string;
348
+ remote: string;
349
+ push: PrCreateStageObservation;
350
+ gh: PrCreateStageObservation;
351
+ }
352
+ /** stderr 꼬리로 남기는 최대 글자 수. */
353
+ export const PR_CREATE_STDERR_TAIL_CHARS = 400;
354
+
355
+ /** 토큰·URL 자격증명을 기록 전에 지운다(원문 꼬리는 살리고 비밀만 뭉개기). */
356
+ const CREDENTIAL_REDACTION_PATTERNS: readonly { pattern: RegExp; replacement: string }[] = [
357
+ // GitHub token prefixes(ghp_/gho_/ghu_/ghs_/ghr_/github_pat_ …) — secret 부분만 치환.
358
+ { pattern: /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{16,}/g, replacement: '[REDACTED]' },
359
+ { pattern: /\bgithub_pat_[A-Za-z0-9_]{20,}/g, replacement: '[REDACTED]' },
360
+ // URL userInfo(https://user:pass@host · ssh://user:pass@host) — 스킴은 살리고 자격증명만.
361
+ { pattern: /((?:https?|ssh|git\+ssh):\/\/)[^\s/@]+:[^\s/@]+@/g, replacement: '$1[REDACTED]@' },
362
+ ];
363
+
364
+ /** stderr 텍스트에서 토큰·URL 자격증명을 제거한다. */
365
+ export function sanitizeCredentialText(text: string): string {
366
+ let out = text;
367
+ for (const { pattern, replacement } of CREDENTIAL_REDACTION_PATTERNS) out = out.replace(pattern, replacement);
368
+ return redactSecretText(out);
369
+ }
370
+
371
+ /** stderr 를 자격증명 제거 뒤 꼬리(기본 400자)만 남긴다. 비면 undefined. */
372
+ export function stderrTailOf(err: string | undefined, chars: number = PR_CREATE_STDERR_TAIL_CHARS): string | undefined {
373
+ const sanitized = sanitizeCredentialText(err ?? '').trim();
374
+ return sanitized ? sanitized.slice(-chars) : undefined;
375
+ }
376
+
377
+ /** PR 생성 실패 incident 를 원장(debug.log)에 남긴다. 성공 경로는 기록하지 않는다. */
378
+ export function recordPrCreateFailureIncident(incident: PrCreateFailureIncident): PrCreateFailureIncident {
379
+ const safe: PrCreateFailureIncident = {
380
+ ...(incident.runId ? { runId: sanitizeCredentialText(incident.runId) } : {}),
381
+ branch: sanitizeCredentialText(incident.branch),
382
+ remote: sanitizeCredentialText(incident.remote),
383
+ push: { ...incident.push, ...(incident.push.stderrTail ? { stderrTail: stderrTailOf(incident.push.stderrTail) } : {}) },
384
+ gh: { ...incident.gh, ...(incident.gh.stderrTail ? { stderrTail: stderrTailOf(incident.gh.stderrTail) } : {}) },
385
+ };
386
+ debug.log('autopilot.pr-manager', 'pr-create-failure-incident', safe);
387
+ return safe;
388
+ }
389
+
390
+ function prCreateFailureOutcome(input: UpsertPrInput, reason: 'push' | 'gh' | 'guard', detail: string,
391
+ push: PrCreateStageObservation, gh: PrCreateStageObservation, targetBranch = input.branch): UpsertPrOutcome {
392
+ const incident = recordPrCreateFailureIncident({
393
+ ...(input.runId ? { runId: input.runId } : {}), branch: targetBranch, remote: 'origin', push, gh,
394
+ });
395
+ const safeDetail = sanitizeCredentialText(detail).slice(0, 300);
396
+ // The production caller carries detail into its child failure record.
397
+ return input.runId
398
+ ? { ok: false, reason, detail: `${safeDetail}\npr-create-incident=${JSON.stringify(incident)}`, incident }
399
+ : { ok: false, reason, detail: safeDetail };
400
+ }
401
+
319
402
  function seatFromEnvironment(): Seat | null {
320
403
  // Production launchers stamp this in harness-pod-dispatch.ts and harness-cli-command.ts.
321
404
  const value = process.env.ELANOUS_HARNESS_SEAT;
322
405
  return value === 'OP' || value === 'TC' || value === 'MK' || value === 'UX' ? value : null;
323
406
  }
324
407
 
408
+ function sameCellGuardDetail(verdict: GuardVerdict, candidateCardId: string | null): string {
409
+ const reasons = verdict.reasons.map(reason => `${reason.code}: ${reason.detail}${reason.prs?.length ? ` (${reason.prs.map(number => `#${number}`).join(', ')})` : ''}`).join('; ');
410
+ return verdict.sameCellConflicts?.length
411
+ ? `${reasons}; candidateCardId=${candidateCardId ?? 'unknown'}; blockers=${verdict.sameCellConflicts.map(({ pr, cardId }) => `#${pr}:${cardId ?? 'unknown'}`).join(',')}`
412
+ : reasons;
413
+ }
414
+
325
415
  /** PR-GUARD-HUNK-WARN: config `prTool.hunkOverlap` — 'refuse' 만 옛 거부, 없거나 그 밖은 'warn'. */
326
416
  export function configuredHunkOverlapMode(raw: Record<string, unknown> | undefined = getUserConfig().raw): HunkOverlapMode {
327
417
  const prTool = raw?.prTool as { hunkOverlap?: unknown } | undefined;
328
418
  return prTool?.hunkOverlap === 'refuse' ? 'refuse' : 'warn';
329
419
  }
330
420
 
421
+ /** PR-CENSUS-PARALLEL: the guard's `gh pr diff` fan-out, with the same gh credentials as {@link defaultCmdRunner}. */
422
+ export const defaultCensusParallelRunner: PrToolParallelCommand = (calls, concurrency) =>
423
+ spawnParallelCommands(calls, { concurrency, env: ghAutomationEnv(process.env) });
424
+
331
425
  function defaultPrCreateGuard(input: { cwd: string; base: string | undefined; seat: Seat | null; body: string }, run: CmdRunner): GuardVerdict {
332
426
  if (!input.base) return guardNewPr({ files: null, seat: input.seat }, { status: 'unknown', reason: '비교 base 없음' });
333
427
  const diff = run('git', ['-C', input.cwd, 'diff', '--name-only', '-z', `${input.base}...HEAD`]);
334
428
  const files = diff.ok ? diff.out.split('\0').filter(Boolean) : null;
335
429
  const patch = run('git', ['-C', input.cwd, 'diff', '--unified=0', `${input.base}...HEAD`]);
336
430
  if (!patch.ok) return guardNewPr({ files: null, seat: input.seat }, { status: 'unknown', reason: `후보 수정 줄 조회 실패: ${patch.err || patch.out}` });
337
- return guardNewPr({ files, seat: input.seat, cellId: cellIdFromBody(input.body), hunks: parseDiffHunks(patch.out), hunkOverlap: configuredHunkOverlapMode() }, readOpenPrs(run, { cwd: input.cwd, ...(files ? { candidateFiles: files } : {}) }));
431
+ const boundRaw = process.env.ELANOUS_TASK_BOUND_PR;
432
+ const boundPrNumber = boundRaw && /^[1-9]\d*$/.test(boundRaw) ? Number(boundRaw) : undefined;
433
+ return guardNewPr({ files, seat: input.seat, cellId: cellIdFromBody(input.body), cardId: cardIdFromBody(input.body),
434
+ slice: sliceMarkerFromBody(input.body),
435
+ ...(boundPrNumber && Number.isSafeInteger(boundPrNumber) ? { boundPrNumber } : {}),
436
+ hunks: parseDiffHunks(patch.out), hunkOverlap: configuredHunkOverlapMode() }, readOpenPrs(run, { cwd: input.cwd, ...(files ? { candidateFiles: files } : {}),
437
+ runParallel: defaultCensusParallelRunner, diffCache: sharedCensusDiffCache }));
438
+ }
439
+
440
+ function editExistingPr(run: CmdRunner, input: UpsertPrInput, url: string): UpsertPrOutcome {
441
+ const opts = { cwd: input.worktreePath };
442
+ const detailOf = (r: CmdResult) => (r.err || r.out || '').slice(0, 300);
443
+ const editArgs = ['pr', 'edit', url, '--title', input.title, '--body', input.body];
444
+ const explicitBase = input.base?.trim();
445
+ if (explicitBase && !isBranchSelfRef(explicitBase, input.branch)) editArgs.push('--base', prBaseFromComparison(explicitBase));
446
+ for (const label of new Set((input.labels ?? []).map(label => label.trim()).filter(Boolean))) editArgs.push('--add-label', label);
447
+ const edited = run('gh', editArgs, opts);
448
+ if (!edited.ok) return { ok: false, reason: 'gh', detail: detailOf(edited) || 'gh pr edit 실패' };
449
+ if (input.draft !== undefined) {
450
+ const stateR = run('gh', ['pr', 'view', url, '--json', 'isDraft', '-q', '.isDraft'], opts);
451
+ const raw = stateR.out.trim();
452
+ if (!stateR.ok || (raw !== 'true' && raw !== 'false'))
453
+ return { ok: false, reason: 'gh', detail: detailOf(stateR) || `draft 상태 조회 실패(isDraft=${raw || 'empty'})` };
454
+ if (input.draft === false && raw === 'true') {
455
+ const ready = run('gh', ['pr', 'ready', url], opts);
456
+ if (!ready.ok) return { ok: false, reason: 'gh', detail: detailOf(ready) || 'gh pr ready 실패' };
457
+ } else if (input.draft === true && raw === 'false') {
458
+ const undo = run('gh', ['pr', 'ready', url, '--undo'], opts);
459
+ if (!undo.ok) return { ok: false, reason: 'gh', detail: detailOf(undo) || 'gh pr ready --undo 실패' };
460
+ }
461
+ }
462
+ if (input.reuseComment) run('gh', ['pr', 'comment', url, '--body', input.reuseComment], opts);
463
+ return { ok: true, url, reused: true };
464
+ }
465
+
466
+ /** Same-card rework may have a new run branch. Merge the bound PR head into that work,
467
+ * then update the bound branch with a plain fast-forward push. Every identity read is
468
+ * checked again after the inventory snapshot; an ambiguous or moved PR stays refused. */
469
+ function reuseSameCellPr(run: CmdRunner, input: UpsertPrInput, target: NonNullable<GuardVerdict['sameCellReuse']>, recheck: () => GuardVerdict): UpsertPrOutcome {
470
+ const cwd = input.worktreePath;
471
+ const pushEvidence = { ref: `refs/heads/${target.branch}`, remoteHead: target.headSha, cardId: target.cardId };
472
+ const fail = (detail: string): UpsertPrOutcome => {
473
+ const safeDetail = sanitizeCredentialText(detail).slice(0, 300);
474
+ debug.log('autopilot.pr-manager', 'same-cell-push-decision', { ...pushEvidence, outcome: 'refused', reason: safeDetail }, { level: 'warn' });
475
+ return { ok: false, reason: 'guard', detail: `same-cell reuse: ${safeDetail}` };
476
+ };
477
+ if (!/^[0-9a-f]{40}$/i.test(target.headSha) || !Number.isSafeInteger(target.number) || target.number < 1
478
+ || cellIdFromBody(input.body) !== target.cellId || cardIdFromBody(input.body) !== target.cardId)
479
+ return fail('candidate identity mismatch');
480
+ const validBranch = run('git', ['-C', cwd, 'check-ref-format', '--branch', target.branch]);
481
+ if (!validBranch.ok) return fail('PR branch name invalid');
482
+ const viewFields = 'state,headRefOid,headRefName,body,isCrossRepository,url,isDraft,labels';
483
+ const view = run('gh', ['pr', 'view', String(target.number), '--json', viewFields], { cwd });
484
+ if (!view.ok) return fail('PR identity read failed');
485
+ let pr: Record<string, unknown>;
486
+ try { pr = JSON.parse(view.out) as Record<string, unknown>; } catch { return fail('PR identity malformed'); }
487
+ if (pr.state !== 'OPEN' || pr.isCrossRepository !== false || pr.headRefOid !== target.headSha
488
+ || pr.headRefName !== target.branch || typeof pr.body !== 'string'
489
+ || cellIdFromBody(pr.body) !== target.cellId
490
+ || (sliceMarkerFromBody(input.body)?.slice ?? null) !== (sliceMarkerFromBody(pr.body)?.slice ?? null)
491
+ || (sliceMarkerFromBody(input.body)?.total ?? null) !== (sliceMarkerFromBody(pr.body)?.total ?? null)
492
+ || (target.legacyBound ? hasCardMarker(pr.body) || process.env.ELANOUS_TASK_BOUND_PR !== String(target.number)
493
+ : cardIdFromBody(pr.body) !== target.cardId)
494
+ || typeof pr.url !== 'string' || extractPrNumber(pr.url) !== target.number)
495
+ return fail('PR state, head, repository, or card lineage changed');
496
+ const remoteRef = `refs/heads/${target.branch}`;
497
+ const remote = run('git', ['-C', cwd, 'ls-remote', '--exit-code', 'origin', remoteRef]);
498
+ if (!remote.ok || remote.out.trim() !== `${target.headSha}\t${remoteRef}`) return fail('remote head changed');
499
+ const localRef = `refs/elanous/pr-reuse/${target.number}-${target.headSha.slice(0, 12)}`;
500
+ const fetched = run('git', ['-C', cwd, 'fetch', 'origin', `${remoteRef}:${localRef}`]);
501
+ const fetchedHead = fetched.ok ? run('git', ['-C', cwd, 'rev-parse', localRef]) : undefined;
502
+ if (!fetched.ok || !fetchedHead?.ok || fetchedHead.out.trim() !== target.headSha) return fail('PR head fetch mismatch');
503
+ const merged = run('git', ['-C', cwd, 'merge', '--no-edit', target.headSha]);
504
+ if (!merged.ok) {
505
+ const aborted = run('git', ['-C', cwd, 'merge', '--abort']);
506
+ if (!aborted.ok) return fail(`PR head merge abort failed: ${(aborted.err || aborted.out).slice(0, 220)}`);
507
+ // A conflicting same-card draft cannot be fast-forwarded. Preserve this run's
508
+ // head on its own branch, and let the returned new PR URL bind the card.
509
+ if (pr.isDraft !== true) return fail('conflicting PR is not a draft');
510
+ const clean = run('git', ['-C', cwd, 'status', '--porcelain', '--untracked-files=no']);
511
+ if (!clean.ok || clean.out.trim()) return fail('worktree changed after merge abort');
512
+ const before = run('gh', ['pr', 'view', String(target.number), '--json', viewFields], { cwd });
513
+ let old: Record<string, unknown>;
514
+ try { old = JSON.parse(before.out) as Record<string, unknown>; } catch { return fail('PR pre-create identity malformed'); }
515
+ const remoteNow = run('git', ['-C', cwd, 'ls-remote', '--exit-code', 'origin', remoteRef]);
516
+ const latest = recheck().sameCellReuse;
517
+ if (!before.ok || old.state !== 'OPEN' || old.isDraft !== true || old.headRefOid !== target.headSha
518
+ || old.headRefName !== target.branch || old.body !== pr.body || old.url !== pr.url
519
+ || !remoteNow.ok || remoteNow.out.trim() !== `${target.headSha}\t${remoteRef}`
520
+ || !latest || latest.number !== target.number || latest.branch !== target.branch
521
+ || latest.headSha !== target.headSha || latest.cellId !== target.cellId
522
+ || latest.cardId !== target.cardId || Boolean(latest.legacyBound) !== Boolean(target.legacyBound))
523
+ return fail('PR changed before superseding draft');
524
+ const newRef = `refs/heads/${input.branch}`;
525
+ if (!run('git', ['-C', cwd, 'check-ref-format', '--branch', input.branch]).ok) return fail('new run branch name invalid');
526
+ const newRemote = run('git', ['-C', cwd, 'ls-remote', '--heads', 'origin', newRef]);
527
+ if (!newRemote.ok || newRemote.out.trim()) return fail('new run branch already exists or remote unreadable');
528
+ const localHead = run('git', ['-C', cwd, 'rev-parse', 'HEAD']);
529
+ if (!localHead.ok || !/^[0-9a-f]{40}$/i.test(localHead.out.trim())) return fail('new run head unreadable');
530
+ // Upload the commit through a unique scratch ref. GitHub's create-ref API then
531
+ // atomically refuses a concurrent writer of the intended branch name.
532
+ const runKey = input.runId ? runSuffixKey(input.runId) : null;
533
+ if (!runKey) return fail(input.runId ? 'new run id invalid for scratch ref' : 'run id required for scratch ref');
534
+ const scratch = `self-impl/pr-create-r${runKey}-${randomUUID()}`;
535
+ const scratchRef = `refs/heads/${scratch}`;
536
+ const uploaded = run('git', ['-C', cwd, 'push', 'origin', `HEAD:${scratchRef}`]);
537
+ if (!uploaded.ok) return fail(`new run object upload failed: ${(uploaded.err || uploaded.out).slice(0, 220)}`);
538
+ const repository = run('gh', ['repo', 'view', '--json', 'nameWithOwner', '-q', '.nameWithOwner'], { cwd });
539
+ const repoName = repository.out.trim();
540
+ const createdRef = repository.ok && /^[^/\s]+\/[^/\s]+$/.test(repoName)
541
+ ? run('gh', ['api', '--method', 'POST', `repos/${repoName}/git/refs`, '-f', `ref=${newRef}`, '-f', `sha=${localHead.out.trim()}`], { cwd })
542
+ : { ok: false, out: '', err: 'repository identity unavailable' };
543
+ const removedScratch = run('git', ['-C', cwd, 'push', 'origin', `:${scratchRef}`]);
544
+ if (!removedScratch.ok) debug.log('autopilot.pr-manager', 'same-cell-scratch-cleanup-failed',
545
+ { scratchRef, detail: removedScratch.err || removedScratch.out,
546
+ stderr: removedScratch.err ?? '', stdout: removedScratch.out, truncated: false }, { level: 'warn' });
547
+ if (!createdRef.ok) return fail(`new run branch create refused: ${(createdRef.err || createdRef.out).slice(0, 220)}`);
548
+ const stateLabels = new Set(labelsForAxis('state').map(label => label.name));
549
+ const labels = [...new Set([...(input.labels ?? []).filter(label => !stateLabels.has(label as typeof PR_LABEL_NAMES.running)),
550
+ PR_LABEL_NAMES.running, ...(input.seat ? [`seat:${input.seat}`] : [])])];
551
+ const body = `${input.body.trimEnd()}\n\nSupersedes: #${target.number}`;
552
+ const create = ['pr', 'create', '--draft', '--head', input.branch, '--title', input.title, '--body', body];
553
+ const base = input.base?.trim();
554
+ if (base && !isBranchSelfRef(base, input.branch)) create.push('--base', prBaseFromComparison(base));
555
+ for (const label of labels) create.push('--label', label);
556
+ const created = run('gh', create, { cwd });
557
+ const newUrl = created.out.trim();
558
+ const newNumber = extractPrNumber(newUrl);
559
+ if (!created.ok || !newNumber) return { ok: false, reason: 'gh', detail: `superseding draft create failed: ${(created.err || created.out).slice(0, 220)}` };
560
+ debug.log('autopilot.pr-manager', 'same-cell-conflict-new-draft',
561
+ { oldPr: target.number, newPr: newNumber, cardId: target.cardId, oldDraftCleanup: 'deferred' });
562
+ return { ok: true, url: newUrl, reused: false, supersededPr: target.number };
563
+ }
564
+ if (!run('git', ['-C', cwd, 'merge-base', '--is-ancestor', target.headSha, 'HEAD']).ok) return fail('PR head is not ancestor of result');
565
+ const finalView = run('gh', ['pr', 'view', String(target.number), '--json', viewFields], { cwd });
566
+ let finalPr: Record<string, unknown>;
567
+ try { finalPr = JSON.parse(finalView.out) as Record<string, unknown>; } catch { return fail('PR pre-push identity read failed'); }
568
+ if (!finalView.ok || finalPr.state !== 'OPEN' || finalPr.isCrossRepository !== false
569
+ || finalPr.headRefOid !== target.headSha || finalPr.headRefName !== target.branch
570
+ || typeof finalPr.body !== 'string' || cellIdFromBody(finalPr.body) !== target.cellId
571
+ || (sliceMarkerFromBody(input.body)?.slice ?? null) !== (sliceMarkerFromBody(finalPr.body)?.slice ?? null)
572
+ || (sliceMarkerFromBody(input.body)?.total ?? null) !== (sliceMarkerFromBody(finalPr.body)?.total ?? null)
573
+ || (target.legacyBound ? hasCardMarker(finalPr.body) || process.env.ELANOUS_TASK_BOUND_PR !== String(target.number)
574
+ : cardIdFromBody(finalPr.body) !== target.cardId)
575
+ || finalPr.url !== pr.url) return fail('PR changed before push');
576
+ const finalRemote = run('git', ['-C', cwd, 'ls-remote', '--exit-code', 'origin', remoteRef]);
577
+ if (!finalRemote.ok || finalRemote.out.trim() !== `${target.headSha}\t${remoteRef}`) return fail('remote head changed before push');
578
+ const latest = recheck().sameCellReuse;
579
+ if (!latest || latest.number !== target.number || latest.branch !== target.branch
580
+ || latest.headSha !== target.headSha || latest.cellId !== target.cellId
581
+ || latest.cardId !== target.cardId || Boolean(latest.legacyBound) !== Boolean(target.legacyBound))
582
+ return fail('OPEN PR inventory changed before push');
583
+ // The result descends from the exact fetched head. The explicit lease binds the
584
+ // remote update to that head, so a delete or move between reads cannot be revived.
585
+ // The Pod hook receives these values for this one push only. It checks the Pod card,
586
+ // exact remote head and ancestry independently before allowing another run's ref.
587
+ const podReuseConfig = input.runId && process.env.ELANOUS_TASK_CARD_ID ? [
588
+ '-c', `elanous.sameCellReuseRef=${remoteRef}`,
589
+ '-c', `elanous.sameCellReuseHead=${target.headSha}`,
590
+ '-c', `elanous.sameCellReuseCard=${target.cardId}`,
591
+ ] : [];
592
+ const pushed = run('git', ['-C', cwd,
593
+ ...podReuseConfig,
594
+ 'push', `--force-with-lease=${remoteRef}:${target.headSha}`, 'origin', `HEAD:${remoteRef}`]);
595
+ if (!pushed.ok) return fail(`fast-forward push refused: ${(pushed.err || pushed.out).slice(0, 220)}`);
596
+ debug.log('autopilot.pr-manager', 'same-cell-push-decision', { ...pushEvidence, outcome: 'allowed', reason: 'bound-card-pr-head-fast-forward' });
597
+ debug.log('autopilot.pr-manager', 'same-cell-reused', { pr: target.number, cellId: target.cellId, cardId: target.cardId, branch: target.branch });
598
+ return editExistingPr(run, input, pr.url);
338
599
  }
339
600
 
340
601
  /** ★ PR 매니저 팩토리(대표 2026-07-12) — CmdRunner 주입(테스트 스텁). 실 배선은 기본 러너. */
@@ -362,7 +623,9 @@ export function makePrManager(
362
623
  const r = run('gh', ['pr', 'list', '--head', branch, '--state', 'open', '--json', 'url', '--jq', '.[0].url // ""'], cwd ? { cwd } : undefined);
363
624
  const url = r.out.trim() || null;
364
625
  const outcome: FindPrForBranchOutcome = !r.ok
365
- ? { status: 'FAILED', url: null }
626
+ ? { status: 'FAILED', url: null,
627
+ ...(typeof r.rc === 'number' ? { rc: r.rc } : {}),
628
+ ...(stderrTailOf(r.err || r.out) ? { stderrTail: stderrTailOf(r.err || r.out) } : {}) }
366
629
  : url
367
630
  ? { status: 'ok OUTPUT', url }
368
631
  : { status: 'ok EMPTY', url: null };
@@ -378,21 +641,34 @@ export function makePrManager(
378
641
  return {
379
642
  findPrForBranch,
380
643
  findPrForBranchOutcome,
381
- upsertPr(input) {
644
+ upsertPr(candidateInput) {
645
+ // ★ sibling-slice(쪼개기 정착) — composeSliceHandText(tier-split.ts)가 hand 문면에 표지를 쓰고
646
+ // prBody(orchestrator.ts)가 그 문면을 PR 본문에 보존한다. 조각 번호만 제목에 덧붙인다.
647
+ const candidateSlice = sliceMarkerFromBody(candidateInput.body);
648
+ const input: UpsertPrInput = candidateSlice
649
+ ? { ...candidateInput,
650
+ title: `${candidateInput.title} · 조각 ${candidateSlice.slice}/${candidateSlice.total}`,
651
+ body: candidateInput.body }
652
+ : candidateInput;
653
+ const taskCardId = process.env.ELANOUS_TASK_CARD_ID;
654
+ if (taskCardId && (!hasCardMarker(input.body) || cardIdFromBody(input.body) !== taskCardId))
655
+ return { ok: false, reason: 'guard', detail: `task card PR body missing or conflicting card marker: expected=${taskCardId}` };
382
656
  const cwd = input.worktreePath;
383
657
  const opts = { cwd };
384
658
  const runGitWrite = (args: string[]): CmdResult => {
659
+ let lastRc: number | undefined;
385
660
  const result = runGitWithRetry(
386
661
  args,
387
662
  (gitArgs) => {
388
663
  const command = run('git', gitArgs, opts);
389
- return { status: command.ok ? 0 : 1, stdout: command.out, stderr: command.err ?? '' };
664
+ lastRc = command.rc;
665
+ return { status: command.ok ? 0 : (command.rc && command.rc !== 0 ? command.rc : 1), stdout: command.out, stderr: command.err ?? '' };
390
666
  },
391
667
  (attempt) => debug.log('autopilot.pr-manager', 'git-write.retry-succeeded', { attempt, args }),
392
668
  );
393
- return { ok: result.status === 0, out: result.stdout, err: result.stderr };
669
+ return { ok: result.status === 0, out: result.stdout, err: result.stderr, rc: lastRc ?? (typeof result.status === 'number' ? result.status : undefined) };
394
670
  };
395
- const detailOf = (r: CmdResult) => (r.err || r.out || '').slice(0, 300);
671
+ const detailOf = (r: CmdResult) => sanitizeCredentialText(r.err || r.out || '').slice(0, 300);
396
672
  // ★ gitignored 경로는 exclude pathspec 에서 뺀다(대표 2026-07-21·705308 근본). git add -A 는 gitignored
397
673
  // (node_modules·apps/pwa/out 심링크)를 이미 자동 skip 하는데, `:(exclude)<ignored>` 로 명시 지목하면
398
674
  // git 이 "paths ignored by .gitignore … use -f" 로 exit 1 을 뱉는다(staging 은 성공하지만 exit≠0).
@@ -496,11 +772,71 @@ export function makePrManager(
496
772
  }
497
773
  // ahead > 0 + 내용차 존재 → 이미 커밋된 산출. commit 스킵하고 아래 push + PR 로 fall-through.
498
774
  }
775
+ // 카드 계보를 아는 재작업은 새 run 가지를 발사하기 전에 같은 칸 PR 을 찾는다.
776
+ // 같은 카드로 증명된 단일 PR 만 기존 가지를 빠른 전진시킨다. 다른 계보·모호한 목록은 종전 가드다.
777
+ const candidateCardId = cardIdFromBody(input.body);
778
+ if (hasCardMarker(input.body) && !candidateCardId)
779
+ return { ok: false, reason: 'guard', detail: 'candidate card lineage is ambiguous' };
780
+ const earlyGuard = candidateCardId && checkCreate
781
+ ? checkCreate({ cwd, base: comparisonBase, seat: input.seat ?? seatFromEnvironment(), body: input.body }, run)
782
+ : undefined;
783
+ // ★ sibling-slice 허용 분기 — 같은 칸의 «다른 조각» OPEN PR 은 충돌로 보지 않는다.
784
+ // 다른 조각 번호(같은 total) → same-cell 사유만 빼고 새 draft 허용 · 같은 조각 번호 → 기존
785
+ // 재사용/거부 그대로 · 후보에 표지 없음 → 기존 가드 그대로(siblingSliceAllowed 는 그대로 반환).
786
+ const siblingSliceAllowed = (verdict: GuardVerdict): GuardVerdict => {
787
+ // Injected guards may still use the old card-only reuse predicate. Never force-push
788
+ // one slice over another, even when the card lineage matches.
789
+ const reused = verdict.sameCellReuse;
790
+ const reusedConflict = reused && verdict.sameCellConflicts?.find(conflict => conflict.pr === reused.number);
791
+ const safeReuse = !reused || ((candidateSlice?.slice ?? null) === (reusedConflict?.slice?.slice ?? null)
792
+ && (candidateSlice?.total ?? null) === (reusedConflict?.slice?.total ?? null));
793
+ const checkedVerdict = safeReuse ? verdict : { ...verdict, sameCellReuse: undefined };
794
+ if (!candidateSlice || checkedVerdict.status !== 'refuse' || checkedVerdict.sameCellReuse || !checkedVerdict.sameCellConflicts?.length)
795
+ return checkedVerdict;
796
+ const conflicts = checkedVerdict.sameCellConflicts;
797
+ if (conflicts.some(conflict => !conflict.slice || conflict.slice.slice === candidateSlice.slice)) return checkedVerdict;
798
+ if (!conflicts.every(conflict => conflict.slice!.total === candidateSlice.total)) return checkedVerdict;
799
+ debug.log('autopilot.pr-manager', 'same-cell-sibling-slice', {
800
+ cell: cellIdFromBody(input.body), slice: candidateSlice.slice, total: candidateSlice.total,
801
+ existingSlice: conflicts[0]!.slice!.slice, outcome: 'allowed' });
802
+ const reasons = checkedVerdict.reasons.filter(reason => reason.code !== 'same-cell');
803
+ return reasons.length ? { ...checkedVerdict, reasons } : { ...checkedVerdict, status: 'allow', reasons: [] };
804
+ };
805
+ const earlyVerdict = earlyGuard ? siblingSliceAllowed(earlyGuard) : undefined;
806
+ const freshGuard = () => checkCreate!({ cwd, base: comparisonBase, seat: input.seat ?? seatFromEnvironment(), body: input.body }, run);
807
+ if (earlyVerdict?.sameCellReuse) return reuseSameCellPr(run, input, earlyVerdict.sameCellReuse, freshGuard);
808
+ if (earlyVerdict?.status === 'refuse') return { ok: false, reason: 'guard', detail: sameCellGuardDetail(earlyVerdict, candidateCardId) };
809
+ const earlyInventoryUnknown = !!candidateCardId && (!checkCreate || (earlyVerdict?.status === 'unknown'
810
+ && earlyVerdict.reasons.length === 1 && earlyVerdict.reasons[0]?.code === 'inventory-unknown'));
811
+ if (candidateCardId && earlyVerdict?.status !== 'allow' && !earlyInventoryUnknown)
812
+ return { ok: false, reason: 'guard', detail: 'candidate card inventory unmeasured before push' };
813
+ if (earlyInventoryUnknown) debug.log('pr-tool.open-guard', 'candidate-inventory-unmeasured', {
814
+ branch: input.branch, cardId: candidateCardId, stage: 'before-push',
815
+ reason: earlyVerdict?.reasons[0]?.detail ?? 'create guard unavailable',
816
+ });
817
+ if (candidateCardId) {
818
+ const branchPr = findPrForBranchOutcome(input.branch, cwd);
819
+ if (branchPr.status === 'FAILED' || branchPr.url)
820
+ return { ok: false, reason: 'guard', detail: 'candidate run branch PR already exists or is unmeasured before push' };
821
+ }
499
822
  // force-push — 재구현이 이전 구현을 교체(기존 브랜치 갱신 or 신규). 안정 브랜치명이라 기존 PR 이
500
823
  // 있으면 GitHub 이 그 PR 을 자동 업데이트(닫고 새로 안 만듦). elanous 자체 SE 브랜치라 force 안전.
501
824
  // 일시 원격 실패(5xx·연결 끊김 등)만 최대 3회. 영구 거부는 한 번에 끝낸다.
502
825
  const waitForPushRetry = input.waitForPushRetry ?? defaultWaitForPushRetry;
503
- const pushArgs = ['-C', cwd, 'push', '--force', '-u', 'origin', input.branch];
826
+ // ★ 칸 PR-CREATE-FAIL-OBSERVE-FU — push/gh 단계 관측을 쌓아 실패 시 한 incident 로.
827
+ const pushStage: PrCreateStageObservation = { stage: 'push', ran: false };
828
+ const ghStage: PrCreateStageObservation = { stage: 'gh', ran: false };
829
+ const markGhRan = (r: CmdResult): CmdResult => {
830
+ ghStage.ran = true;
831
+ ghStage.rc = r.rc;
832
+ ghStage.stderrTail = stderrTailOf(r.err);
833
+ return r;
834
+ };
835
+ const failedCreate = (reason: 'push' | 'gh', detail: string): UpsertPrOutcome =>
836
+ prCreateFailureOutcome(input, reason, detail, pushStage, ghStage);
837
+ const pushArgs = candidateCardId
838
+ ? ['-C', cwd, 'push', '-u', 'origin', input.branch]
839
+ : ['-C', cwd, 'push', '--force', '-u', 'origin', input.branch];
504
840
  let pushR = runGitWrite(pushArgs);
505
841
  let pushAttempts = 1;
506
842
  while (!pushR.ok && pushAttempts < MAX_PUSH_ATTEMPTS && isTransientPushFailure(detailOf(pushR))) {
@@ -508,80 +844,68 @@ export function makePrManager(
508
844
  pushR = runGitWrite(pushArgs);
509
845
  pushAttempts += 1;
510
846
  }
847
+ pushStage.ran = true;
848
+ pushStage.ok = pushR.ok;
849
+ pushStage.rc = pushR.rc;
850
+ pushStage.stderrTail = stderrTailOf(pushR.err);
511
851
  if (!pushR.ok) {
512
852
  const detail = pushAttempts > 1
513
853
  ? `push ${pushAttempts}/${MAX_PUSH_ATTEMPTS} failed: ${detailOf(pushR)}`
514
854
  : detailOf(pushR);
515
- return { ok: false, reason: 'push', detail };
855
+ return failedCreate('push', detail);
516
856
  }
517
857
  const existing = findPrForBranchOutcome(input.branch, cwd);
518
- if (existing.url) {
519
- // 재사용: openPr 계약(title/body/base/draft/labels)을 기존 PR 에 반영한다.
520
- // - base: 미전달 시 요청 base 와 어긋난 기존 PR 을 성공으로 반환할 수 있어 명시 전달.
521
- // - labels: --add-label 로 부착(auto-review 등 무인 리뷰 진입 라벨이 재실행에도 유지되도록).
522
- // - draft: 현재 상태를 조회해 실제 전이가 필요할 때만 수행(멱등) — 이미 요청 상태면 no-op.
523
- // draft=false && 현재 draft → gh pr ready · draft=true && 현재 ready → gh pr ready --undo.
524
- const editArgs = ['pr', 'edit', existing.url, '--title', input.title, '--body', input.body];
525
- // ⚠️ 재사용 경로는 **명시 base 만** 넘긴다(리뷰 must-fix 2026-07-26). 추론한 base 를 넘기면
526
- // `release/*` 등 비기본 브랜치를 대상으로 열려 있던 기존 PR 을 **main 으로 재타기팅**하는
527
- // 회귀가 된다(요청자는 base 를 지정하지도 않았는데). 미지정 = "base 는 건드리지 마라".
528
- // 신규 생성은 base 가 반드시 필요하므로 그쪽만 추론값을 쓴다.
529
- // 트림은 신규 경로(resolveDeliverableBase)와 동일하게 — 공백 전용 base 는 미지정으로 본다(리뷰 should-fix).
530
- const explicitBase = input.base?.trim();
531
- if (explicitBase && !isBranchSelfRef(explicitBase, input.branch)) editArgs.push('--base', prBaseFromComparison(explicitBase));
532
- for (const label of new Set((input.labels ?? []).map(label => label.trim()).filter(Boolean))) editArgs.push('--add-label', label);
533
- let edited = run('gh', editArgs, opts);
534
- if (!edited.ok) return { ok: false, reason: 'gh', detail: detailOf(edited) || 'gh pr edit 실패' };
535
- if (input.draft !== undefined) {
536
- // 현재 draft 상태 조회 — 조회 실패/비정상 출력은 fail-closed(요청 draft 를 적용 못했는데
537
- // 성공 반환하면 openPr 계약 위반). 정상 조회 시에만 실제 전이가 필요할 때 수행(멱등).
538
- const stateR = run('gh', ['pr', 'view', existing.url, '--json', 'isDraft', '-q', '.isDraft'], opts);
539
- const raw = stateR.out.trim();
540
- if (!stateR.ok || (raw !== 'true' && raw !== 'false')) {
541
- return { ok: false, reason: 'gh', detail: detailOf(stateR) || `draft 상태 조회 실패(isDraft=${raw || 'empty'})` };
542
- }
543
- const isDraft = raw === 'true';
544
- if (input.draft === false && isDraft) {
545
- const ready = run('gh', ['pr', 'ready', existing.url], opts);
546
- if (!ready.ok) return { ok: false, reason: 'gh', detail: detailOf(ready) || 'gh pr ready 실패' };
547
- } else if (input.draft === true && !isDraft) {
548
- const undo = run('gh', ['pr', 'ready', existing.url, '--undo'], opts);
549
- if (!undo.ok) return { ok: false, reason: 'gh', detail: detailOf(undo) || 'gh pr ready --undo 실패' };
550
- }
858
+ if (existing.status !== 'SKIPPED') {
859
+ ghStage.ran = true;
860
+ if (existing.status === 'FAILED') {
861
+ ghStage.rc = existing.rc;
862
+ ghStage.stderrTail = existing.stderrTail;
551
863
  }
552
- if (input.reuseComment) run('gh', ['pr', 'comment', existing.url, '--body', input.reuseComment], opts);
553
- return { ok: true, url: existing.url, reused: true };
554
864
  }
555
- let guardUnmeasured = false;
865
+ if (existing.url) {
866
+ if (candidateCardId)
867
+ return { ok: false, reason: 'guard', detail: 'candidate run branch PR appeared after push; refuse edit' };
868
+ return editExistingPr(run, input, existing.url);
869
+ }
870
+ if (existing.status === 'FAILED') {
871
+ return failedCreate('gh', 'existing PR branch lookup failed');
872
+ }
873
+ let guardUnmeasured = earlyInventoryUnknown;
556
874
  let hunkOverlapWarning: { prs: readonly number[]; files: readonly string[] } | null = null;
557
875
  if (checkCreate) {
558
876
  const seat = input.seat ?? seatFromEnvironment();
877
+ // Another run may open a PR after the early inventory and before this create.
878
+ // Read the complete OPEN inventory again after push, immediately before create.
559
879
  const verdict = checkCreate({ cwd, base: comparisonBase, seat, body: input.body }, run);
560
- const hunkWarn = verdict.status === 'allow' ? verdict.warnings.find(warning => warning.code === 'hunk-overlap') : undefined;
880
+ // sibling-slice: 같은 칸의 다른 조각이 inventories 사이 열려도 생성은 허용한다(위 분기와 동일 규칙).
881
+ const siblingVerdict = siblingSliceAllowed(verdict);
882
+ if (siblingVerdict.sameCellReuse)
883
+ return { ok: false, reason: 'guard', detail: 'same-cell PR appeared after run branch push; retry from fresh inventory' };
884
+ const hunkWarn = siblingVerdict.status === 'allow' ? siblingVerdict.warnings.find(warning => warning.code === 'hunk-overlap') : undefined;
561
885
  if (hunkWarn) hunkOverlapWarning = { prs: hunkWarn.prs ?? [], files: hunkWarn.files ?? [] };
562
- if (verdict.status === 'unknown' && verdict.reasons.length === 1 && verdict.reasons[0]?.code === 'inventory-unknown') {
886
+ if (siblingVerdict.status === 'unknown' && siblingVerdict.reasons.length === 1 && siblingVerdict.reasons[0]?.code === 'inventory-unknown') {
563
887
  const inPod = process.env.ELANOUS_SUBSTRATE === 'pod'
564
888
  || Object.keys(process.env).some(key => key.startsWith('ELANOUS_POD_'));
565
889
  if (inPod) {
566
890
  // Pod state and mailbox are local to this Job. Count and alert only
567
891
  // in the host parent, where the shared instance root is authoritative.
568
- debug.log('pr-tool.open-guard', 'pod-unmeasured', { seat, reason: verdict.reasons[0].detail });
892
+ debug.log('pr-tool.open-guard', 'pod-unmeasured', { seat, reason: siblingVerdict.reasons[0].detail });
569
893
  } else {
570
- const count = recordUnmeasured({ seat, reason: verdict.reasons[0].detail });
894
+ const count = recordUnmeasured({ seat, reason: siblingVerdict.reasons[0].detail });
571
895
  if (count.blocked) {
572
- const alert = run('eln', ['msg', 'post', '--from', seat ?? 'HARNESS', '--to', 'OP', '--kind', 'alert', '--body', `PR open-guard 판정 불가 1시간 ${count.count}회 · 새 PR 차단 · ${count.reason ?? verdict.reasons[0].detail}`]);
896
+ const alert = run('eln', ['msg', 'post', '--from', seat ?? 'HARNESS', '--to', 'OP', '--kind', 'alert', '--body', `PR open-guard 판정 불가 1시간 ${count.count}회 · ${candidateCardId ? '카드 후보는 draft 관측' : '새 PR 차단'} · ${count.reason ?? siblingVerdict.reasons[0].detail}`]);
573
897
  if (!alert.ok) debug.log('pr-tool.open-guard', 'op-alert-failed', { seat, reason: alert.err || alert.out || 'eln msg post 실패' });
574
- return { ok: false, reason: 'guard', detail: `inventory-unknown: 1시간 ${count.count}회 · 새 PR 차단${count.reason ? ` (${count.reason})` : ''}` };
898
+ if (!candidateCardId) return { ok: false, reason: 'guard', detail: `inventory-unknown: 1시간 ${count.count}회 · 새 PR 차단${count.reason ? ` (${count.reason})` : ''}` };
575
899
  }
576
900
  }
577
901
  guardUnmeasured = true;
578
- } else if (verdict.status !== 'allow') {
579
- return { ok: false, reason: 'guard', detail: verdict.reasons.map(reason => `${reason.code}: ${reason.detail}${reason.prs?.length ? ` (${reason.prs.map(number => `#${number}`).join(', ')})` : ''}`).join('; ') };
902
+ } else if (siblingVerdict.status !== 'allow') {
903
+ return { ok: false, reason: 'guard', detail: sameCellGuardDetail(siblingVerdict, candidateCardId) };
580
904
  }
581
905
  }
582
906
  const createArgs = ['pr', 'create', '--head', input.branch, '--title', input.title, '--body', input.body];
583
907
  if (prBase) createArgs.push('--base', prBase);
584
- if (input.draft) createArgs.push('--draft');
908
+ if (input.draft || guardUnmeasured) createArgs.push('--draft');
585
909
  const seat = input.seat ?? seatFromEnvironment();
586
910
  const requiredLabels = [...(seat ? [`seat:${seat}`] : []), ...(guardUnmeasured ? ['pr-guard:unmeasured'] : [])];
587
911
  // PR-GUARD-HUNK-WARN: 줄 겹침 경고 라벨은 «최선» — 만들기 실패해도 아래 재시도가 빼고 PR 을 연다.
@@ -590,15 +914,18 @@ export function makePrManager(
590
914
  const requestedLabels = [...new Set([...(input.labels ?? []), ...creatableLabels].map((label) => label.trim()).filter(Boolean))];
591
915
  const labeledArgs = [...createArgs];
592
916
  for (const label of requestedLabels) labeledArgs.push('--label', label);
593
- let created = run('gh', labeledArgs, opts);
917
+ let created = markGhRan(run('gh', labeledArgs, opts));
594
918
  if (!created.ok && creatableLabels.length && isLabelNotFoundFailure(created, creatableLabels)) {
595
919
  for (const label of creatableLabels) run('gh', ['label', 'create', label, '--color', 'BFDADC'], opts);
596
- created = run('gh', labeledArgs, opts);
920
+ created = markGhRan(run('gh', labeledArgs, opts));
597
921
  }
598
922
  const logHunkOverlapWarn = (url: string): void => {
599
923
  if (hunkOverlapWarning) debug.log('pr-tool.guard', 'hunk-overlap-warn', { pr: extractPrNumber(url), files: hunkOverlapWarning.files, against: hunkOverlapWarning.prs });
600
924
  };
601
925
  if (created.ok && created.out) {
926
+ if (guardUnmeasured) debug.log('pr-tool.open-guard', 'candidate-draft-unmeasured', {
927
+ branch: input.branch, cardId: candidateCardId ?? null, url: created.out,
928
+ });
602
929
  logHunkOverlapWarn(created.out);
603
930
  return {
604
931
  ok: true,
@@ -610,7 +937,7 @@ export function makePrManager(
610
937
  if (requestedLabels.length > 0 && isLabelNotFoundFailure(created, requestedLabels)) {
611
938
  const retryArgs = [...createArgs];
612
939
  for (const label of requiredLabels) retryArgs.push('--label', label);
613
- const retry = run('gh', retryArgs, opts);
940
+ const retry = markGhRan(run('gh', retryArgs, opts));
614
941
  if (retry.ok && retry.out) {
615
942
  logHunkOverlapWarn(retry.out);
616
943
  debug.log('autopilot.pr-manager', 'create.labels-omitted', {
@@ -621,9 +948,10 @@ export function makePrManager(
621
948
  });
622
949
  return { ok: true, url: retry.out, reused: false, labelsOmitted: true };
623
950
  }
624
- return { ok: false, reason: 'gh', detail: detailOf(retry) || 'gh pr create 실패' };
951
+ return failedCreate('gh', detailOf(retry) || 'gh pr create 실패');
625
952
  }
626
- return { ok: false, reason: 'gh', detail: detailOf(created) || 'gh pr create 실패' };
953
+ // 여기까지 흘러내려왔으면 성공 return 을 못 만났다 — 실패 incident 로 마무리.
954
+ return failedCreate('gh', detailOf(created) || 'gh pr create 실패');
627
955
  },
628
956
  closePr(prUrl, comment) {
629
957
  const n = extractPrNumber(prUrl);