elanous 0.2.32 → 0.2.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (753) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/{IVKr3AlRUVLKsw2fh7eXF → T1mBQqmkwKDLGtyisDCOd}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{997ce8a5-2ad501927003b41b.js → 0368f25d-ad84af92fefee68f.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1165.bad13fc9151a7288.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/13.02a07436dec15f89.js +32 -0
  7. package/apps/pwa/out/_next/static/chunks/{5525.86debf231e181813.js → 1530.0e612369b6fd7ea0.js} +1 -1
  8. package/apps/pwa/out/_next/static/chunks/1540.af38731fa7c4a3e0.js +41 -0
  9. package/apps/pwa/out/_next/static/chunks/{7391.ebae168025c91b6a.js → 1674.2a65fd5668e1cc5f.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/1850.f2b470ba5a471da0.js +24 -0
  11. package/apps/pwa/out/_next/static/chunks/193.62da94cd0b88323b.js +74 -0
  12. package/apps/pwa/out/_next/static/chunks/1975.260f6d249fac5f7c.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1982-67cd8dfe8682325f.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/{7947-d0759430f8042240.js → 1993-c0007b7ad0c0ef41.js} +1 -1
  15. package/apps/pwa/out/_next/static/chunks/1999-bb415351c8a2846c.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/{60fb96c9.360b01d8d4927b7b.js → 1c735de4.f993a30bbd3c57c4.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/1dc5a567.9b092bfae3d7099b.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/{5307.60f2209e809bd627.js → 2018.a741297bce759490.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/2085.8f950b4bda1cbbc7.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2159-6179a961376956b9.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/216.b5c2a421aa1d28a5.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2251.49fbe369f74c372c.js +148 -0
  23. package/apps/pwa/out/_next/static/chunks/2286-2939577360d3dcc0.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/{3902.e1e71aaac850a045.js → 2625.5d870aa999f33db1.js} +1 -1
  25. package/apps/pwa/out/_next/static/chunks/2668.34d21539e62bf111.js +77 -0
  26. package/apps/pwa/out/_next/static/chunks/2833-0fe47af99ed13c29.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2930.d0edb4f108787ef7.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/2973.77318e7d85f59477.js +62 -0
  29. package/apps/pwa/out/_next/static/chunks/3103.0df8da390948bb84.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/3123.2bee9ba15d320bd2.js +90 -0
  31. package/apps/pwa/out/_next/static/chunks/3162-6cf652bf7124d8cf.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{4174.92ed04922709ac9e.js → 3408.21d1570602f4b6c0.js} +2 -2
  33. package/apps/pwa/out/_next/static/chunks/3577-7340009f7007a795.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/3589.5444a06bcf6e775c.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/359-2250789a2d3499e7.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3618.f514792d6c59d7fd.js +36 -0
  37. package/apps/pwa/out/_next/static/chunks/3669.343f9119aa276001.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/{9398-6aed28f0a96d0d6f.js → 3677-4215f826f6aa68e5.js} +1 -1
  39. package/apps/pwa/out/_next/static/chunks/3736.c2efad489604cc3b.js +79 -0
  40. package/apps/pwa/out/_next/static/chunks/3817.f9aeab2bb6675d73.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3f7c4ee5.3dde54f01a816613.js +122 -0
  42. package/apps/pwa/out/_next/static/chunks/4182-0b9b1251c29cc0cf.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/{7371.80c05c653b08e907.js → 4346.8601952e73bf5803.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/4441-875b97f5821ed58a.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/4582.bd68683c076649e3.js +286 -0
  46. package/apps/pwa/out/_next/static/chunks/4605-6e623f55aec77422.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4607.5cc27468628eb4bf.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4627.f07508b3936fd6c0.js +24 -0
  49. package/apps/pwa/out/_next/static/chunks/{2940-619bfd8ef337c611.js → 4705-194e64e47ca0fbdb.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/{1335-6731f392c35216eb.js → 4718-17d2af636796a330.js} +3 -3
  51. package/apps/pwa/out/_next/static/chunks/4747-c22262c093e46807.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4775-178215aed0daba61.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/4815-6ffb8c3c991cc45d.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4834-beca8b47ad29a898.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5023-fb4802b6d2492b02.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/{7502.ccd5b8065545edd0.js → 5101.e32282718f99ed6f.js} +2 -2
  57. package/apps/pwa/out/_next/static/chunks/{2001.6c7e0fd02190886c.js → 5154.a118f3957ed14e36.js} +1 -1
  58. package/apps/pwa/out/_next/static/chunks/5210-a2e0015e3d4d5d9c.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5356.84ac712cc15928bf.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5401.22352141b6fd336e.js +23 -0
  61. package/apps/pwa/out/_next/static/chunks/{5173-233188df2f42c626.js → 5483-dd5d7697f6bdb106.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5637.281e5dec4ea6ecf1.js +94 -0
  63. package/apps/pwa/out/_next/static/chunks/5662.02eaa029af05ad46.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/{3267c0e6.d34854e7b3984a6e.js → 56d372f2.681ab4ec4c998fae.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/5760.22456f433c6f42c0.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/5852.db1f7449f4f74612.js +287 -0
  67. package/apps/pwa/out/_next/static/chunks/5891-0f11a7d7362a9072.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/5943.264d14a44ca32513.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/604-1b3c39df083c02aa.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/6121-5f97072330738caf.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6193.07d8ca5af4b09086.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6203-b3fea3a60d69ff14.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/{6433.fc573af22bbc9ab7.js → 6236.e18cced2d5ba6afb.js} +17 -17
  74. package/apps/pwa/out/_next/static/chunks/6286.d638fb5953e2e757.js +8 -0
  75. package/apps/pwa/out/_next/static/chunks/630.fe5a46428d63b013.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6301.ae0245f507e4395e.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/6673.fbbe5699f6ea5991.js +27 -0
  78. package/apps/pwa/out/_next/static/chunks/6777-f6d301efb5de828d.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6786.423f24c88de034c7.js +93 -0
  80. package/apps/pwa/out/_next/static/chunks/6854-cef64a948c5e122d.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6866-79aa5b4e47cac6aa.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/{6544cb48.a87fe20ddf137be2.js → 6b89c8bd.24df687a820500b3.js} +1 -1
  83. package/apps/pwa/out/_next/static/chunks/7037-fe27f001db30d323.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7080.2d826860534fd88e.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7118.8731be28c3ebb14b.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7196.44241bc1df3e26fe.js +149 -0
  87. package/apps/pwa/out/_next/static/chunks/7235.c7c4e6cb5c693c2d.js +104 -0
  88. package/apps/pwa/out/_next/static/chunks/{2871.0bca6137343b3f76.js → 7385.50a308a477bdfc21.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/{2985.39ccdecd36848b12.js → 7644.17e37ba6f1d4226e.js} +4 -4
  90. package/apps/pwa/out/_next/static/chunks/7706-58bfb1546637f217.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7839.5b91455338c9fd3f.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7857-31f13ee96f4011aa.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/81.f74cb60312fe4001.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/{8018.a32663f04a6fc5f9.js → 8219.baa715d1deee80e2.js} +1 -1
  95. package/apps/pwa/out/_next/static/chunks/{4111.2bfedbb233ad206b.js → 8256.e3ac8421a71f82f4.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/8310-444a6a895c402f12.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8423.f7dda8aca4fcaae5.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/8437-8d5492094b166cfa.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/{2213.2ccbada92c33ea0f.js → 8444.4c26b379ca2b9596.js} +17 -17
  100. package/apps/pwa/out/_next/static/chunks/8496.75649af8652c74f4.js +226 -0
  101. package/apps/pwa/out/_next/static/chunks/8557-e7898769499cd56f.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8576.65bb654b524f3614.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8609.558ce2f8f9aea2be.js +64 -0
  104. package/apps/pwa/out/_next/static/chunks/8614.caec96cfb91f4ae7.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{6092.a7f99e68b188ca66.js → 8637.47f5b35afcae5e6b.js} +1 -1
  106. package/apps/pwa/out/_next/static/chunks/8714.ff0b7ce3ec3e3ae2.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8732.367f44a916202353.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9141-7fd1f73a5400bdc2.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/921.c4267d0d69a65404.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{3278.2e5d15b53a4091c8.js → 9214.63a510d39178e997.js} +2 -2
  111. package/apps/pwa/out/_next/static/chunks/9261.3962c3321b047691.js +115 -0
  112. package/apps/pwa/out/_next/static/chunks/936-26efd1a0efdd44d3.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/{9221.7d22eaf353a2d4e7.js → 938.66ad1ef0e5abae1c.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/{6157.0c9af021de4fb31b.js → 9512.5a76207a730e0491.js} +2 -2
  115. package/apps/pwa/out/_next/static/chunks/9627-4b9efe616b27e2e2.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/{69-0a2c8209c6d4a158.js → 967-2aa39b2d04b4c690.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/9734.40eb1e558c29ccea.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9908.3aa54f7a586a73dc.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/{7862.30a8d6482bb238eb.js → 9952.5daf5f94063a2b3e.js} +1 -1
  120. package/apps/pwa/out/_next/static/chunks/9954-ca8d29752bdbb45a.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/9974-507fa67cb94066dd.js +1 -0
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-ce9e00f7fb45506a.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-fa59d6d17daa3389.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-53f68bbe7bd4b774.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-1c500fbb9f4a7a04.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-99d72673aa5c307c.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-d2d5adc1e9484c88.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c607c5aae637f1cc.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-fa8c23596d555c0f.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-bdab8c5e855c8416.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/{page-a27b1e5a0d1b308f.js → page-406b47745b53f269.js} +1 -1
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-a4276386b7051f50.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8a26bab9ad375f25.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-775f48aa1dc7a2d5.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-1c4dd5f959d0c558.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-c48938a8377c9f70.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-ce9e00f7fb45506a.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-c6e7905859425aa9.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-c280f4252452e830.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-cf8c57498f20970a.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-ca3a17caf409fc83.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-26e6c18a1a750cf6.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-3abc872cc6aeee39.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-f7481b7b2174fe3d.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1ae7ef8077680337.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/{page-32866485913d6a04.js → page-47c5d4db587266bd.js} +1 -1
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-415f1e243c7ccb13.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-73f380f17b76f95c.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-2991073ad66ee2d9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1f5a60f70cb4dd0c.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fbad60d1e358fb2c.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-bac7dee94e5eae4a.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-398047d6949e8ca5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-2d33a2231540ca89.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-5bf1e6bf70bcb96c.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-ba59c19376a0917d.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-111f187139add30f.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-acaae197d5be5779.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-0df20b0f546a0d7d.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-ce9e00f7fb45506a.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-27e1202d24b8fe35.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-bda78c50a78363e5.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-da592691293d9c9f.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f832994317a2e9f0.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/{page-04d00ae9b0890349.js → page-dc0a532f5b9196ec.js} +1 -1
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-cfccbbeae0473404.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-527e2073af84c81b.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-bac86e9112671357.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6d59dff410e9d76a.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-53a61f8be09f02d2.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-db8f559e763c17f9.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c02aa4cc66455093.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{7a1887c4.f36b88fba31da8fd.js → b2f6ba4d.fb56fdbbf798df33.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/b6705a4f-b9a9047de9eecfd0.js +1 -0
  175. package/apps/pwa/out/_next/static/chunks/{b313b242.cb1265eea908db61.js → cbe38a15.5a032598e39970c6.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/{409f1e57.d0649fc47691ebfe.js → d06f9160.a3d9062f95de8ad7.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/{0bb0ff36.b8d418980951e5ba.js → da5176c6.6773b6c5994e1d99.js} +7 -7
  178. package/apps/pwa/out/_next/static/chunks/framework-50e6acebc630849b.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-7a1ae342d5ed75e6.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-7ad7d505ba1f92b4.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-02edba75232cb235.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-97d6ebae3e8eee4a.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-e986adaa429163e8.js +1 -0
  184. package/apps/pwa/out/approvals/index.html +1 -1
  185. package/apps/pwa/out/approvals/index.txt +22 -22
  186. package/apps/pwa/out/autopilot/index.html +1 -1
  187. package/apps/pwa/out/autopilot/index.txt +22 -22
  188. package/apps/pwa/out/board/index.html +1 -1
  189. package/apps/pwa/out/board/index.txt +22 -22
  190. package/apps/pwa/out/botlab/index.html +1 -1
  191. package/apps/pwa/out/botlab/index.txt +21 -21
  192. package/apps/pwa/out/bots/index.html +1 -1
  193. package/apps/pwa/out/bots/index.txt +21 -21
  194. package/apps/pwa/out/ceo/index.html +1 -1
  195. package/apps/pwa/out/ceo/index.txt +22 -22
  196. package/apps/pwa/out/chat/index.html +1 -1
  197. package/apps/pwa/out/chat/index.txt +21 -21
  198. package/apps/pwa/out/consult/index.html +1 -1
  199. package/apps/pwa/out/consult/index.txt +22 -22
  200. package/apps/pwa/out/control/index.html +1 -1
  201. package/apps/pwa/out/control/index.txt +22 -22
  202. package/apps/pwa/out/decisions/index.html +1 -1
  203. package/apps/pwa/out/decisions/index.txt +21 -21
  204. package/apps/pwa/out/design-check/index.html +1 -1
  205. package/apps/pwa/out/design-check/index.txt +22 -22
  206. package/apps/pwa/out/editor/index.html +1 -1
  207. package/apps/pwa/out/editor/index.txt +22 -22
  208. package/apps/pwa/out/exec/index.html +1 -1
  209. package/apps/pwa/out/exec/index.txt +22 -22
  210. package/apps/pwa/out/field/index.html +1 -1
  211. package/apps/pwa/out/field/index.txt +22 -22
  212. package/apps/pwa/out/healthz +1 -1
  213. package/apps/pwa/out/index.html +1 -1
  214. package/apps/pwa/out/index.txt +21 -21
  215. package/apps/pwa/out/inside/index.html +1 -1
  216. package/apps/pwa/out/inside/index.txt +21 -21
  217. package/apps/pwa/out/intake/index.html +1 -1
  218. package/apps/pwa/out/intake/index.txt +22 -22
  219. package/apps/pwa/out/live/index.html +1 -1
  220. package/apps/pwa/out/live/index.txt +22 -22
  221. package/apps/pwa/out/live-run/index.html +1 -1
  222. package/apps/pwa/out/live-run/index.txt +22 -22
  223. package/apps/pwa/out/loops/index.html +1 -1
  224. package/apps/pwa/out/loops/index.txt +21 -21
  225. package/apps/pwa/out/market/index.html +1 -1
  226. package/apps/pwa/out/market/index.txt +21 -21
  227. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  228. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  229. package/apps/pwa/out/morning/index.html +1 -1
  230. package/apps/pwa/out/morning/index.txt +22 -22
  231. package/apps/pwa/out/observatory/index.html +1 -1
  232. package/apps/pwa/out/observatory/index.txt +22 -22
  233. package/apps/pwa/out/ops/checklist/index.html +1 -1
  234. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  235. package/apps/pwa/out/ops/release/index.html +1 -1
  236. package/apps/pwa/out/ops/release/index.txt +21 -21
  237. package/apps/pwa/out/ops/seats/index.html +1 -1
  238. package/apps/pwa/out/ops/seats/index.txt +21 -21
  239. package/apps/pwa/out/outputs/index.html +1 -1
  240. package/apps/pwa/out/outputs/index.txt +21 -21
  241. package/apps/pwa/out/reflection/index.html +1 -1
  242. package/apps/pwa/out/reflection/index.txt +22 -22
  243. package/apps/pwa/out/scheduler/index.html +1 -1
  244. package/apps/pwa/out/scheduler/index.txt +22 -22
  245. package/apps/pwa/out/sessions/index.html +1 -1
  246. package/apps/pwa/out/sessions/index.txt +21 -21
  247. package/apps/pwa/out/settings/devices/index.html +1 -1
  248. package/apps/pwa/out/settings/devices/index.txt +22 -22
  249. package/apps/pwa/out/settings/index.html +1 -1
  250. package/apps/pwa/out/settings/index.txt +22 -22
  251. package/apps/pwa/out/setup/done/index.html +1 -1
  252. package/apps/pwa/out/setup/done/index.txt +22 -22
  253. package/apps/pwa/out/setup/index.html +1 -1
  254. package/apps/pwa/out/setup/index.txt +22 -22
  255. package/apps/pwa/out/share/index.html +1 -1
  256. package/apps/pwa/out/share/index.txt +22 -22
  257. package/apps/pwa/out/showroom/index.html +1 -1
  258. package/apps/pwa/out/showroom/index.txt +21 -21
  259. package/apps/pwa/out/tasks/index.html +1 -1
  260. package/apps/pwa/out/tasks/index.txt +22 -22
  261. package/apps/pwa/out/term/index.html +1 -1
  262. package/apps/pwa/out/term/index.txt +22 -22
  263. package/apps/pwa/out/today/index.html +1 -1
  264. package/apps/pwa/out/today/index.txt +22 -22
  265. package/apps/pwa/out/trace/index.html +1 -1
  266. package/apps/pwa/out/trace/index.txt +22 -22
  267. package/apps/pwa/out/vault/index.html +1 -1
  268. package/apps/pwa/out/vault/index.txt +22 -22
  269. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  270. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  271. package/apps/pwa/out/workflows/index.html +1 -1
  272. package/apps/pwa/out/workflows/index.txt +22 -22
  273. package/apps/pwa/out/workspace/index.html +1 -1
  274. package/apps/pwa/out/workspace/index.txt +22 -22
  275. package/apps/pwa/out/worktrees/index.html +1 -1
  276. package/apps/pwa/out/worktrees/index.txt +22 -22
  277. package/bin/elanous.mjs +10 -2
  278. package/catalog/providers/opengateway.yaml +25 -0
  279. package/docs/goal-context/01-goal-authoring-checks.md +8 -0
  280. package/docs/goal-context/03-verification-menu.md +24 -0
  281. package/docs/goal-context/04-mock-scenarios.md +100 -0
  282. package/docs/goal-context/README.md +5 -0
  283. package/graphs/catalog/catalog.yaml +1 -1
  284. package/graphs/default-loop.yaml +76 -5
  285. package/graphs/document-loop.yaml +71 -4
  286. package/graphs/implement-loop.yaml +59 -4
  287. package/graphs/journey/SCENARIOS.md +33 -0
  288. package/graphs/journey/recipes.yaml +1 -0
  289. package/graphs/journey/ta-journey.yaml +94 -0
  290. package/graphs/journey/units/author/author.yaml +20 -0
  291. package/graphs/journey/units/author/recipes.yaml +2 -0
  292. package/graphs/journey/units/author-dialogue/author-dialogue.yaml +42 -0
  293. package/graphs/journey/units/author-dialogue/observe.ts +96 -0
  294. package/graphs/journey/units/author-dialogue/recipes.yaml +10 -0
  295. package/graphs/journey/units/green/green.yaml +20 -0
  296. package/graphs/journey/units/green/recipes.yaml +2 -0
  297. package/graphs/journey/units/pr/pr.yaml +20 -0
  298. package/graphs/journey/units/pr/recipes.yaml +2 -0
  299. package/graphs/journey/units/remember/recipes.yaml +2 -0
  300. package/graphs/journey/units/remember/remember.yaml +20 -0
  301. package/graphs/operate-loop.yaml +71 -4
  302. package/graphs/overlays/stop-heal-ladder.yaml +1 -1
  303. package/graphs/release-rehearsal/recipes.yaml +1 -1
  304. package/graphs/release-rehearsal/release-rehearsal.yaml +2 -2
  305. package/graphs/research-loop.yaml +159 -4
  306. package/graphs/test-diet/test-diet.yaml +3 -0
  307. package/graphs/units/dispatch-pod/dispatch-pod.yaml +50 -0
  308. package/graphs/units/dispatch-pod/recipes.yaml +14 -0
  309. package/graphs/units/entry/entry.yaml +50 -0
  310. package/graphs/units/entry/recipes.yaml +14 -0
  311. package/graphs/units/harvest/harvest.yaml +25 -0
  312. package/graphs/units/harvest/recipes.yaml +4 -0
  313. package/graphs/units/land/land.yaml +45 -0
  314. package/graphs/units/land/recipes.yaml +3 -0
  315. package/graphs/units/recipes.yaml +7 -0
  316. package/graphs/units/recover.yaml +39 -0
  317. package/graphs/units/reflect/recipes.yaml +3 -0
  318. package/graphs/units/reflect/reflect.yaml +15 -0
  319. package/graphs/units/task-agent-recover-review.yaml +17 -0
  320. package/graphs/units/task-agent-recover-wait.yaml +17 -0
  321. package/graphs/units/verbs/make-doc.yaml +34 -0
  322. package/graphs/units/verbs/recipes.yaml +33 -0
  323. package/graphs/units/verbs/verify.yaml +55 -0
  324. package/graphs/work/recipes.yaml +2 -0
  325. package/graphs/work/research-report.yaml +28 -0
  326. package/package.json +1 -1
  327. package/scripts/ci-typecheck-changed.ts +69 -16
  328. package/scripts/coord-role-pack.ts +19 -6
  329. package/scripts/docs/generate-graph-anatomy.ts +19 -2
  330. package/scripts/graph-harvest-unit.ts +22 -0
  331. package/scripts/graph-units/journey-stub.ts +6 -0
  332. package/scripts/graph-units/land-enqueue.ts +78 -0
  333. package/scripts/graph-units/recover-plan.ts +15 -0
  334. package/scripts/graph-units/reflect-node.ts +88 -0
  335. package/scripts/graph-units/ta-journey-observe.ts +109 -0
  336. package/scripts/graph-units/verbs/headless-goal-loop.ts +152 -0
  337. package/scripts/graph-units/verbs/verify-stage.ts +75 -0
  338. package/scripts/graph-units/verbs-envelope.ts +139 -0
  339. package/scripts/hq/standby-snapshot.ts +30 -0
  340. package/scripts/public-export.ts +43 -1
  341. package/scripts/ratchets/train-side-invariants.sh +45 -0
  342. package/scripts/release-loop/auto-approve-node.ts +30 -16
  343. package/scripts/release-loop/docs-land-node.ts +21 -5
  344. package/scripts/release-loop/gate-baseline-receipt.ts +155 -0
  345. package/scripts/release-loop/gate-closure.ts +5 -1
  346. package/scripts/release-loop/gate-diff.ts +1 -1
  347. package/scripts/release-loop/gate-node.ts +675 -49
  348. package/scripts/release-loop/gate-partial.ts +68 -14
  349. package/scripts/release-loop/gate-radius-live.ts +177 -0
  350. package/scripts/release-loop/gate-radius-shadow.ts +138 -0
  351. package/scripts/release-loop/gate-traffic-mode.ts +128 -0
  352. package/scripts/release-loop/gate-triage-node.ts +5 -2
  353. package/scripts/release-loop/known-issues-0.2.33-approved.json +194 -0
  354. package/scripts/release-loop/known-issues-node.ts +77 -8
  355. package/scripts/release-loop/node-verdict.ts +12 -1
  356. package/scripts/release-loop/npm-publish-node.ts +66 -12
  357. package/scripts/release-loop/preflight.ts +93 -7
  358. package/scripts/release-loop/probe-pod-host-dirs-live.ts +5 -0
  359. package/scripts/release-loop/publish-node.ts +60 -9
  360. package/scripts/release-loop/pwa-remote.ts +166 -0
  361. package/scripts/release-loop/pwa-scenarios-node.ts +19 -3
  362. package/scripts/release-loop/resume-cap.ts +56 -0
  363. package/scripts/release-loop/resume-release.ts +155 -19
  364. package/scripts/release-loop/resume.ts +24 -1
  365. package/scripts/release-loop/tui-sim-node.ts +8 -2
  366. package/scripts/release-loop/unattended-release.ts +10 -2
  367. package/scripts/test-diet/lib.ts +6 -1
  368. package/scripts/test-diet/node.ts +194 -13
  369. package/scripts/ux-sim.ts +39 -0
  370. package/src/acp/core-turn-bridge.ts +20 -5
  371. package/src/acp/reasoning-thought-buffer.ts +45 -0
  372. package/src/agent/self-ambient-cache.ts +8 -0
  373. package/src/agent-substrate/acp-reviewer.ts +90 -15
  374. package/src/agent-substrate/pr-reviewer.ts +17 -0
  375. package/src/agent-substrate/review-finding-key.ts +53 -0
  376. package/src/agent-substrate/self-review-cli.ts +188 -18
  377. package/src/ask-user-question/pending-questions.ts +1 -1
  378. package/src/autopilot/pr-manager.ts +393 -65
  379. package/src/budget/run-usage-rollup.ts +1 -0
  380. package/src/chat/index.ts +0 -2
  381. package/src/chat/pickers/modal-runtime.ts +10 -27
  382. package/src/chat/tool-render/dispatch.ts +62 -10
  383. package/src/cli/agent-cli.ts +13 -2
  384. package/src/cli/control-cli.ts +24 -7
  385. package/src/cli/doctor-cli.ts +4 -1
  386. package/src/cli/guardian-cli.ts +10 -0
  387. package/src/cli/light-entry-route.ts +75 -0
  388. package/src/cli/llm-detect-cli.ts +23 -1
  389. package/src/cli/pod-cli.ts +77 -3
  390. package/src/cli/pr-cli.ts +81 -14
  391. package/src/cli/pr-land-base-read.ts +2 -0
  392. package/src/cli/pr-land-overlap-evidence.ts +154 -16
  393. package/src/cli/pr-land-pod-shadow-job.ts +3 -0
  394. package/src/cli/pr-land-recovery.ts +64 -0
  395. package/src/cli/pty-takeover-cli.ts +6 -5
  396. package/src/cli/release-checklist-read-cli.ts +79 -0
  397. package/src/cli/release-cli.ts +189 -132
  398. package/src/cli/release-run-if-ready.ts +29 -28
  399. package/src/cli/release-single-flight.ts +178 -0
  400. package/src/cli/remote-resolve.ts +1 -1
  401. package/src/cli/root-tui-entry.ts +48 -0
  402. package/src/cli/seat-cli.ts +37 -0
  403. package/src/cli/setup-cli.ts +40 -1
  404. package/src/cli/sim-cli.ts +22 -0
  405. package/src/cli/tasks-cli.ts +667 -14
  406. package/src/cli/usage-cli.ts +13 -11
  407. package/src/clipboard/history.ts +179 -13
  408. package/src/config.ts +8 -1
  409. package/src/control/control-status.ts +8 -3
  410. package/src/control-plane/ledger.ts +5 -3
  411. package/src/control-plane/server.ts +5 -3
  412. package/src/core-turn/short-question.ts +5 -1
  413. package/src/dashboard/chat/acp-chat.ts +8 -0
  414. package/src/dashboard/index.ts +114 -77
  415. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +3 -0
  416. package/src/dashboard/input/dashboard-plain-turn-stream.ts +4 -0
  417. package/src/dashboard/input/seat-autowake.ts +56 -3
  418. package/src/dashboard/render/theme-resolver.ts +33 -4
  419. package/src/dashboard/seat-boot-preamble.ts +1 -1
  420. package/src/dashboard/slash-runtime/ask-clarification.ts +48 -0
  421. package/src/dashboard/slash-runtime/dashboard-delegated-slashes.ts +68 -0
  422. package/src/dashboard/slash-runtime/dashboard-handlers.ts +62 -322
  423. package/src/dashboard/slash-runtime/dashboard-log-slash.ts +208 -0
  424. package/src/dashboard/turn-preamble.ts +47 -1
  425. package/src/dashboard/turn-stream-formatter.ts +34 -1
  426. package/src/dashboard/turn-stream-runtime.ts +2 -0
  427. package/src/dashboard/turn-typeahead-prompt-zone.ts +67 -0
  428. package/src/domains/guardian-tick.ts +54 -2
  429. package/src/domains/outbound-alert.ts +3 -2
  430. package/src/domains/schedule-registry.ts +16 -2
  431. package/src/extractors.ts +3 -1
  432. package/src/git-fs/idle-refresh.ts +76 -0
  433. package/src/git-fs/index.ts +18 -7
  434. package/src/git-fs/retry.ts +4 -0
  435. package/src/git-fs/runner.ts +2 -0
  436. package/src/git-fs/worktree.ts +42 -4
  437. package/src/graph-kinds/registry.ts +2 -2
  438. package/src/graph-runner/runner.ts +267 -54
  439. package/src/grok/credential.ts +15 -3
  440. package/src/harness/harness-cli-command.ts +151 -38
  441. package/src/harness/harness-incidents.ts +37 -0
  442. package/src/harness/harness-pod-dispatch.ts +38 -1
  443. package/src/harness/harness-salvage-cli.ts +14 -2
  444. package/src/harness/launch-utterance-ledger.ts +208 -0
  445. package/src/impl-discipline/detector.ts +16 -4
  446. package/src/impl-discipline/system-prompt.ts +11 -0
  447. package/src/impl-discipline/types.ts +2 -2
  448. package/src/index.ts +683 -146
  449. package/src/intake-plane/already-built-hint.ts +91 -0
  450. package/src/intake-plane/requirement-funnel.ts +29 -1
  451. package/src/knowhow/pack.ts +199 -0
  452. package/src/light-cli.ts +111 -0
  453. package/src/llm/opengateway-models.ts +11 -0
  454. package/src/llm/provider-credentials.ts +14 -0
  455. package/src/llm/provider-detect.ts +8 -1
  456. package/src/llm/runtime-model-family.ts +2 -1
  457. package/src/llm.ts +268 -65
  458. package/src/loops/budget.ts +95 -0
  459. package/src/loops/msg-wake.ts +8 -2
  460. package/src/loops/orchestrator/traffic.ts +132 -1
  461. package/src/model-tier/llm-tier-map.ts +15 -1
  462. package/src/mss/logging/log-store.ts +4 -5
  463. package/src/native-tool-catalog.ts +15 -1
  464. package/src/nexus/api/graphs-api.ts +22 -3
  465. package/src/nexus/api/http-server.ts +1 -1
  466. package/src/nexus/api/loop-resources.ts +13 -1
  467. package/src/nexus/api/ops-api.ts +12 -0
  468. package/src/oauth/claude-pty-maturity.ts +66 -0
  469. package/src/oauth/codex-access-mirror.ts +55 -0
  470. package/src/oauth/codex.ts +7 -0
  471. package/src/oauth/fallback-chain.ts +1 -1
  472. package/src/onboarding/first-run.ts +5 -3
  473. package/src/onboarding/non-interactive.ts +64 -13
  474. package/src/onboarding.ts +10 -2
  475. package/src/ops/overview-collect.ts +54 -4
  476. package/src/ops/overview.ts +31 -7
  477. package/src/pr-tool/census.ts +282 -30
  478. package/src/pr-tool/inflight-registry.ts +160 -7
  479. package/src/prompt-library/gpt6-family-addendum.ts +14 -1
  480. package/src/pty-shell/herdr-agent-report.ts +442 -0
  481. package/src/pty-shell/pty-control-ipc.ts +5 -5
  482. package/src/pty-shell/pty-manifest.ts +7 -0
  483. package/src/pty-shell/pty-write-outcome.ts +24 -6
  484. package/src/pty-shell/tui-run-state.ts +117 -3
  485. package/src/release-loop/checklist.ts +103 -5
  486. package/src/release-loop/feature-store.ts +19 -2
  487. package/src/release-loop/landed-but-yellow.ts +129 -5
  488. package/src/release-loop/light-rc.ts +1 -0
  489. package/src/release-loop/placement.ts +10 -3
  490. package/src/release-loop/rehearsal.ts +205 -25
  491. package/src/release-loop/rubric.ts +16 -2
  492. package/src/repl/index.ts +174 -17
  493. package/src/repl/ops-msg-bridge.ts +32 -0
  494. package/src/self-dev/ask-launch-flow.ts +44 -5
  495. package/src/self-dev/cli-help-text.ts +17 -0
  496. package/src/self-dev/dev-cli.ts +11 -9
  497. package/src/self-dev/draft-residue.ts +37 -1
  498. package/src/self-dev/draft-sweep.ts +188 -13
  499. package/src/self-dev/draft-triage-rules.ts +107 -0
  500. package/src/self-dev/fleet-reduce.ts +3 -2
  501. package/src/self-dev/graph-front-nodes.ts +112 -0
  502. package/src/self-dev/graph-journey-nodes.ts +11 -6
  503. package/src/self-dev/graph-journey-route.ts +60 -6
  504. package/src/self-dev/harness-run-cli.ts +3 -15
  505. package/src/self-dev/orchestrate-cli-text.ts +10 -0
  506. package/src/self-dev/orchestrate.ts +79 -3
  507. package/src/self-dev/review-provider-fallback.ts +35 -1
  508. package/src/self-dev/run-supervisor.ts +107 -12
  509. package/src/self-dev/run-types.ts +5 -1
  510. package/src/self-dev/self-orchestrate-runtime.ts +1 -11
  511. package/src/self-dev/shard-aggregate.ts +42 -5
  512. package/src/self-dev/shard-run.ts +8 -1
  513. package/src/self-implement/blocked-draft-policy.ts +20 -0
  514. package/src/self-implement/classify-shadow.ts +3 -7
  515. package/src/self-implement/doctor-visit.ts +18 -1
  516. package/src/self-implement/gate-baseline.ts +95 -12
  517. package/src/self-implement/gate-cli.ts +1 -0
  518. package/src/self-implement/gate-remote.ts +40 -25
  519. package/src/self-implement/goal-author-decompose.ts +275 -47
  520. package/src/self-implement/goal-author-identity.ts +66 -0
  521. package/src/self-implement/goal-author-preservation-obligation.ts +35 -0
  522. package/src/self-implement/goal-author.ts +254 -120
  523. package/src/self-implement/goal-elaborate.ts +295 -0
  524. package/src/self-implement/goal-refine.ts +270 -0
  525. package/src/self-implement/graph-overlay-yaml.ts +28 -2
  526. package/src/self-implement/graph-unit-flatten.ts +103 -0
  527. package/src/self-implement/graph-unit-resolver.ts +107 -0
  528. package/src/self-implement/graph-yaml.ts +151 -1
  529. package/src/self-implement/headless-elanous-driver.ts +1 -0
  530. package/src/self-implement/knowhow-pack.ts +103 -0
  531. package/src/self-implement/orchestrator.ts +160 -45
  532. package/src/self-implement/pod-warm-pool-profile.ts +45 -0
  533. package/src/self-implement/review-mustfix-class.ts +203 -0
  534. package/src/self-implement/rework-budget-judgment.ts +5 -8
  535. package/src/self-implement/run-stop.ts +17 -2
  536. package/src/self-implement/running-runs.ts +29 -1
  537. package/src/self-implement/scope-adjacency.ts +113 -0
  538. package/src/self-implement/seams.ts +138 -4
  539. package/src/self-implement/stop-autoheal.ts +112 -2
  540. package/src/session/chat.ts +27 -0
  541. package/src/session-runtime/index.ts +1 -1
  542. package/src/session-runtime/retry-policy.ts +2 -1
  543. package/src/setup/llm-env-detect.ts +5 -0
  544. package/src/skills/tools/agent.ts +140 -14
  545. package/src/skills/tools/msg-ask.ts +100 -0
  546. package/src/skills/tools/ops-ledger.ts +2 -1
  547. package/src/skills/tools/schedule-wakeup.ts +66 -17
  548. package/src/steward/hold-hygiene.ts +24 -6
  549. package/src/steward/release-day.ts +7 -3
  550. package/src/steward/triage-budget.ts +194 -0
  551. package/src/steward/triage.ts +57 -7
  552. package/src/task-agent/actions.ts +69 -1
  553. package/src/task-agent/green-sweep.ts +4 -0
  554. package/src/task-agent/harvest-unit.ts +141 -0
  555. package/src/task-agent/live-moves.ts +257 -15
  556. package/src/task-agent/parent-host.ts +216 -6
  557. package/src/task-agent/postland-card.ts +80 -1
  558. package/src/task-agent/rejudge-on-head.ts +112 -26
  559. package/src/task-agent/repair-branch-cas.ts +4 -1
  560. package/src/task-agent/repair-cycle.ts +16 -3
  561. package/src/task-agent/run-identity.ts +4 -3
  562. package/src/task-agent/shadow.ts +19 -3
  563. package/src/task-agent/task-hand.ts +96 -36
  564. package/src/task-agent/tier-split.ts +127 -0
  565. package/src/task-agent/work-order-build.ts +24 -0
  566. package/src/task-agent/work-order.ts +3 -2
  567. package/src/task-orchestrator/generator-prompt.ts +60 -11
  568. package/src/task-orchestrator/surfaces/pod-account-broker.ts +72 -3
  569. package/src/task-orchestrator/surfaces/pod-child-providers.ts +1 -1
  570. package/src/task-orchestrator/surfaces/pod-command-job.ts +47 -8
  571. package/src/task-orchestrator/surfaces/pod-image-source.ts +89 -1
  572. package/src/task-orchestrator/surfaces/pod-lease.ts +17 -8
  573. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +86 -8
  574. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +8 -2
  575. package/src/task-orchestrator/surfaces/pod-pool.ts +73 -17
  576. package/src/task-orchestrator/surfaces/pod-provenance.ts +76 -0
  577. package/src/task-orchestrator/surfaces/pod-source-receive.ts +72 -4
  578. package/src/task-orchestrator/surfaces/pod-warm-provenance.ts +81 -0
  579. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +32 -5
  580. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +3 -0
  581. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +421 -0
  582. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +2 -1
  583. package/src/task-orchestrator/surfaces/self-implement-pod.ts +588 -71
  584. package/src/task-orchestrator/surfaces/self-implement.ts +106 -2
  585. package/src/tool-runtime/ops-ledger-runtimes.ts +10 -2
  586. package/src/tool-runtime/truncation-store.ts +4 -0
  587. package/src/tui/README.md +2 -0
  588. package/src/tui/chat/background-job-status.ts +54 -0
  589. package/src/tui/chat/log-view.ts +80 -0
  590. package/src/tui/entry.ts +406 -0
  591. package/src/tui/input/composer.ts +144 -0
  592. package/src/tui/seat-mail-boot.ts +59 -0
  593. package/src/tui/slash/compact.ts +100 -0
  594. package/src/tui/slash/new-session.ts +35 -0
  595. package/src/tui-client/dashboard-session.ts +10 -1
  596. package/src/tui-client/local-chat-turn.ts +239 -0
  597. package/src/tui-client/local-harness-command.ts +63 -0
  598. package/src/tui-client/local-provider-command.ts +184 -0
  599. package/src/user-config/coercion.ts +36 -0
  600. package/src/user-config.ts +22 -43
  601. package/src/ux-sim/event-monkey.ts +378 -0
  602. package/src/ux-sim/fake-bin.ts +42 -7
  603. package/src/ux-sim/fault-nextmove-dispatch.ts +266 -0
  604. package/src/ux-sim/fault-pod-codex-503.ts +211 -0
  605. package/src/ux-sim/fault-scope-escape-lift.ts +189 -0
  606. package/src/ux-sim/scenario.ts +72 -13
  607. package/src/version/packed-revision.json +1 -1
  608. package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +0 -1
  609. package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +0 -1
  610. package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +0 -27
  611. package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +0 -287
  612. package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +0 -62
  613. package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +0 -1
  615. package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +0 -1
  616. package/apps/pwa/out/_next/static/chunks/1654.32de4b324981a188.js +0 -23
  617. package/apps/pwa/out/_next/static/chunks/1834-98b64172bc1efe77.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +0 -149
  619. package/apps/pwa/out/_next/static/chunks/1913.7cc6fb6055b1ed3f.js +0 -41
  620. package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +0 -1
  625. package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/2898.fd781bc7cf01a7b7.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +0 -115
  629. package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +0 -64
  630. package/apps/pwa/out/_next/static/chunks/3541-ce3a5424ed5ad7f1.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +0 -1
  632. package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +0 -1
  635. package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +0 -36
  636. package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +0 -286
  640. package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +0 -77
  641. package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +0 -226
  642. package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +0 -79
  644. package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +0 -148
  647. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/5458-16cd7a2b51b74c8c.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/5543.a438b8ab5a13ea47.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +0 -74
  653. package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +0 -94
  655. package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +0 -90
  661. package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +0 -32
  662. package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +0 -104
  663. package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +0 -24
  668. package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +0 -93
  669. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +0 -8
  674. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/8097-9530c03bcc550f02.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +0 -24
  685. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/9138.b6e80031afb1d973.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/9279-d28c5b7754d010ae.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/9989.3694300e5f000b14.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/approvals/page-504204b58c82c253.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a9717a67c2eecbaf.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/board/page-5c9ec30aee62dfbf.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/botlab/page-584191533721fa16.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/app/bots/page-73c4b4bb3ac7ab5f.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c0f1ca371f710b06.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/app/chat/page-46430d45a9e04eac.js +0 -1
  703. package/apps/pwa/out/_next/static/chunks/app/consult/page-3b2ebf1dc64ff0be.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/app/decisions/page-25654b82094f7d22.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8ea49a4c6dd2c6e7.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/app/editor/page-ce5113aefea0a8d1.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/app/exec/page-0e5a41fac1c75396.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/app/field/page-31aaf1ed37c6df9a.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/app/inside/page-3dcc1fa411e1f4e0.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/app/intake/page-c69247e7134d329d.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/app/layout-66dc5cd3a0999abe.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/app/live/page-26ff7ff651a7217d.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/app/live-run/page-617b3976981efa96.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/app/loops/page-d256f5d5d9552823.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/app/market/page-ce8f1907b8a6101c.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-33e182a316263116.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/app/not-found-7607cca9b84950c6.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eeab86176b03dc3b.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5b93dbae3432b996.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-77a6cb90a9cf2b10.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f47e768b5b242b5a.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/app/outputs/page-eb41aa3367fc2505.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/page-4d13ab0b8a267e3f.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/reflection/page-84dad32ff0fc0831.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-95306f892aa2d0ee.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/sessions/page-940fb6c217f6b470.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-8c66a3b24a745630.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/settings/page-7b675dfd35c36fc9.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8bd0d3cf7665bcfc.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/app/setup/page-c219f2ed171131be.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/app/share/page-40f8fa21bdae955b.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/app/showroom/page-468f8313e4f1fbd9.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/app/tasks/page-7bbb8fa353a246c4.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/app/today/page-4214b855d9233ea8.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/app/trace/page-936752c7aa58762e.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/app/vault/page-ec052ad359df1797.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8305570551091338.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/workflows/page-fad650e4793adb65.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/workspace/page-d90e64743826e1d8.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a16bcfd49af86a32.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +0 -122
  744. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +0 -1
  752. package/src/cli/g6a-registration-probe.ts +0 -16
  753. /package/apps/pwa/out/_next/static/{IVKr3AlRUVLKsw2fh7eXF → T1mBQqmkwKDLGtyisDCOd}/_ssgManifest.js +0 -0
@@ -0,0 +1,139 @@
1
+ import { readFileSync } from 'node:fs';
2
+
3
+ type JsonMap = Record<string, unknown>;
4
+ interface GraphContext { readonly nodeId?: string; readonly input: unknown; readonly outputs: Record<string, unknown> }
5
+
6
+ function record(value: unknown): JsonMap {
7
+ return value && typeof value === 'object' && !Array.isArray(value) ? value as JsonMap : {};
8
+ }
9
+
10
+ function firstValue(context: GraphContext, key: string): unknown {
11
+ const input = record(context.input);
12
+ if (Object.hasOwn(input, key) && input[key] !== undefined && input[key] !== null) return input[key];
13
+ for (const output of Object.values(context.outputs ?? {})) {
14
+ const value = record(output)[key];
15
+ if (value !== undefined && value !== null) return value;
16
+ }
17
+ return null;
18
+ }
19
+
20
+ const VERIFY_INPUTS = ['worktree', 'changed-files', 'diff', 'review-intent', 'must-fix', 'gate-log'] as const;
21
+ const VERIFY_STARTS = new Set(['gate', 'review', 'rework']);
22
+
23
+ export interface MakeDocInputs {
24
+ readonly goal: string;
25
+ readonly worktree: unknown;
26
+ readonly branch: unknown;
27
+ readonly 'review-intent': unknown;
28
+ readonly 'head-sha': unknown;
29
+ readonly 'base-branch': unknown;
30
+ readonly prior: unknown;
31
+ }
32
+
33
+ /** Converts the public make-doc envelope into the existing document-loop recipe contract. */
34
+ export function unpackMakeDocEnvelope(envelope: { readonly ask?: unknown; readonly context?: unknown; readonly prior?: unknown }): MakeDocInputs {
35
+ const context = record(envelope.context);
36
+ const contextGoal = context.goal;
37
+ const ask = typeof envelope.ask === 'string' ? envelope.ask : '';
38
+ const reviewIntent = context['review-intent'] ?? (ask.trim() ? ask : null);
39
+ const goal = typeof contextGoal === 'string' && contextGoal.trim() ? contextGoal : ask;
40
+ return {
41
+ goal,
42
+ worktree: context.worktree ?? null,
43
+ branch: context.branch ?? null,
44
+ 'review-intent': reviewIntent,
45
+ 'head-sha': context['head-sha'] ?? null,
46
+ 'base-branch': context['base-branch'] ?? null,
47
+ prior: envelope.prior ?? null,
48
+ };
49
+ }
50
+
51
+ /** Keeps the make-doc outputs present on every declared exit. */
52
+ export function buildMakeDocOutput(context: GraphContext): JsonMap {
53
+ const draft = record(context.outputs?.['document-draft']);
54
+ const input = record(context.input);
55
+ const prior = record(input.prior);
56
+ const priorEvidence = record(prior.evidence);
57
+ const inputEvidence = record(input.evidence);
58
+ const draftEvidence = record(draft.evidence);
59
+ const evidence = { ...priorEvidence, ...inputEvidence, ...draftEvidence };
60
+ if (prior.result !== undefined) evidence['prior-result'] = prior.result;
61
+ return {
62
+ result: draft.result ?? draft.summary ?? input.result ?? null,
63
+ evidence,
64
+ };
65
+ }
66
+
67
+ /** Selects a verify entry while keeping every unit input explicit at the call boundary. */
68
+ export function buildVerifyEnvelope(context: GraphContext): JsonMap {
69
+ const input = record(context.input);
70
+ const detail = record(input.context);
71
+ const prior = record(input.prior);
72
+ const priorResult = record(prior.result);
73
+ const priorEvidence = record(prior.evidence);
74
+ const start = detail.start_at ?? detail.startAt;
75
+ const startAt = typeof start === 'string' && VERIFY_STARTS.has(start) ? start : 'gate';
76
+ const envelope: JsonMap = {
77
+ outcome: startAt,
78
+ ...Object.fromEntries(VERIFY_INPUTS.map(key => [key, detail[key] ?? prior[key] ?? priorEvidence[key] ?? priorResult[key] ?? firstValue(context, key)])),
79
+ };
80
+ if (detail['review-intent'] == null && typeof input.ask === 'string' && input.ask.trim()) envelope['review-intent'] = input.ask;
81
+ return envelope;
82
+ }
83
+
84
+ /** Emits the complete verify output contract from whichever routes ran. */
85
+ export function buildVerifyOutput(context: GraphContext, outcome: 'done' | 'rework' | 'needs-human' | 'failed'): JsonMap {
86
+ const input = record(context.input);
87
+ const prior = record(input.prior);
88
+ const priorEvidence = record(prior.evidence);
89
+ const outputsByNode = record(context.outputs);
90
+ const stageOrder = outcome === 'done'
91
+ ? ['prepare', 'rework-loop', 'gate', 'review']
92
+ : outcome === 'rework'
93
+ ? ['prepare', 'gate', 'review', 'rework-loop']
94
+ : (() => {
95
+ const source = ['prepare', 'gate', 'review', 'rework-loop']
96
+ .find(node => record(outputsByNode[node]).outcome === outcome);
97
+ if (source === 'gate') return ['prepare', 'review', 'rework-loop', 'gate'];
98
+ if (source === 'review') return ['prepare', 'rework-loop', 'gate', 'review'];
99
+ if (source === 'rework-loop') return ['prepare', 'gate', 'review', 'rework-loop'];
100
+ return ['prepare'];
101
+ })();
102
+ const outputs = stageOrder.map(node => record(outputsByNode[node]));
103
+ const evidence = { ...priorEvidence };
104
+ for (const output of outputs) Object.assign(evidence, record(output.evidence));
105
+ const latest = (key: string, aliases: readonly string[] = []): unknown => {
106
+ let value: unknown = priorEvidence[key] ?? null;
107
+ for (const output of outputs) {
108
+ const nodeValue = [key, ...aliases].map(name => output[name]).find(candidate => candidate !== undefined && candidate !== null);
109
+ const evidenceValue = record(output.evidence)[key];
110
+ if (nodeValue !== undefined) value = nodeValue;
111
+ else if (evidenceValue !== undefined && evidenceValue !== null) value = evidenceValue;
112
+ }
113
+ return value;
114
+ };
115
+ return {
116
+ result: outcome,
117
+ evidence: {
118
+ ...evidence,
119
+ ...(prior.result === undefined ? {} : { 'prior-result': prior.result }),
120
+ 'review-summary': latest('review-summary', ['review_summary']),
121
+ 'must-fix': outcome === 'done' ? [] : latest('must-fix', ['must_fix']),
122
+ 'gate-log': latest('gate-log', ['gate_log']),
123
+ },
124
+ };
125
+ }
126
+
127
+ if (import.meta.main) {
128
+ const contextPath = process.env.ELANOUS_GRAPH_CONTEXT;
129
+ if (!contextPath) throw new Error('ELANOUS_GRAPH_CONTEXT is required');
130
+ const context = JSON.parse(readFileSync(contextPath, 'utf8')) as GraphContext;
131
+ const mode = process.argv[2];
132
+ const output = mode === 'make-doc-input'
133
+ ? unpackMakeDocEnvelope(record(context.input) as { ask?: unknown; context?: unknown; prior?: unknown })
134
+ : mode === 'make-doc-output' ? buildMakeDocOutput(context)
135
+ : mode === 'verify-envelope' ? buildVerifyEnvelope(context)
136
+ : mode === 'verify-output' ? buildVerifyOutput(context, process.argv[3] as 'done' | 'rework' | 'needs-human' | 'failed') : undefined;
137
+ if (!output) throw new Error(`unknown verbs-envelope mode: ${mode ?? '<missing>'}`);
138
+ process.stdout.write(`${JSON.stringify(output)}\n`);
139
+ }
@@ -193,8 +193,38 @@ function pushSurvival(target: string, local: string, manifest: Manifest, root: s
193
193
  rmSync(staging, { recursive: true, force: true });
194
194
  }
195
195
 
196
+ /** Flags that need a value before any snapshot work (STANDBY-SURVIVAL-KEEP-ARGS · mirror parseVerifyArgs / parsePromoteArgs). */
197
+ export const SURVIVAL_VALUE_FLAGS = ['--survival-keep', '--survival-keep-daily', '--prune-survival'] as const;
198
+
199
+ /** Throw when a survival-keep / prune-survival flag is present without its value/target — same rule as `${flag} requires a value`. */
200
+ export function assertSurvivalKeepArgs(argv: string[]): void {
201
+ for (let i = 0; i < argv.length; i += 1) {
202
+ const token = argv[i];
203
+ const equalsAt = token.indexOf('=');
204
+ const flag = equalsAt < 0 ? token : token.slice(0, equalsAt);
205
+ if (!SURVIVAL_VALUE_FLAGS.some(candidate => candidate === flag)) continue;
206
+ if (equalsAt >= 0) {
207
+ if (token.slice(equalsAt + 1).length === 0) throw new Error(`${flag} requires a value`);
208
+ continue;
209
+ }
210
+ const value = argv[i + 1];
211
+ if (!value || value.startsWith('--')) throw new Error(`${flag} requires a value`);
212
+ }
213
+ }
214
+
215
+ function preflightStandbySnapshotArgs(argv: string[]): void {
216
+ // Preflight survival argument values before tier selection, staging, or snapshot work.
217
+ try {
218
+ assertSurvivalKeepArgs(argv);
219
+ } catch (error) {
220
+ console.error(`standby-snapshot: ${String(error)}`);
221
+ process.exit(2);
222
+ }
223
+ }
224
+
196
225
  if (import.meta.main) {
197
226
  const argv = process.argv.slice(2);
227
+ preflightStandbySnapshotArgs(argv);
198
228
  const val = (k: string) => { const i = argv.indexOf(k); return i >= 0 ? argv[i + 1] : undefined; };
199
229
  const tier = (val('--tier') ?? 'core') as Tier;
200
230
  if (tier !== 'core' && tier !== 'big' && tier !== 'obs') { console.error('--tier core|big|obs'); process.exit(2); }
@@ -283,6 +283,45 @@ export function scanLeaks(root: string, files: readonly string[], markers = LEAK
283
283
  return hits;
284
284
  }
285
285
 
286
+ /** Code literals are reported separately for the crown marker: they are not document/comment leakage. */
287
+ function codeLiteralRanges(file: string, text: string): Array<[number, number]> {
288
+ if (!/\.(?:ts|tsx|mts|cts|js|jsx|mjs|cjs)$/iu.test(file)) return [];
289
+ const scanner = ts.createScanner(ts.ScriptTarget.Latest, false, /\.(?:tsx|jsx)$/iu.test(file) ? ts.LanguageVariant.JSX : ts.LanguageVariant.Standard, text);
290
+ const ranges: Array<[number, number]> = [];
291
+ for (let token = scanner.scan(); token !== ts.SyntaxKind.EndOfFileToken; token = scanner.scan()) {
292
+ if (token === ts.SyntaxKind.StringLiteral || token === ts.SyntaxKind.NoSubstitutionTemplateLiteral ||
293
+ token === ts.SyntaxKind.TemplateHead || token === ts.SyntaxKind.TemplateMiddle || token === ts.SyntaxKind.TemplateTail) {
294
+ ranges.push([scanner.getTokenPos(), scanner.getTextPos()]);
295
+ }
296
+ }
297
+ return ranges;
298
+ }
299
+
300
+ export function splitCodeLiteralCeoMarks(files: readonly string[], contents: ReadonlyMap<string, string>, hits: readonly LeakHit[]): { leaks: LeakHit[]; codeLiterals: LeakHit[] } {
301
+ const leaks: LeakHit[] = [];
302
+ const codeLiterals: LeakHit[] = [];
303
+ const fileSet = new Set(files);
304
+ const classification = new Map<string, Set<number>>();
305
+ for (const file of new Set(hits.filter((hit) => hit.marker === 'ceo-mark' && !/\.(?:test|spec)\.(?:ts|tsx|mts|cts|js|jsx|mjs|cjs)$/iu.test(hit.file)).map((hit) => hit.file))) {
306
+ const text = contents.get(file);
307
+ if (text === undefined || !fileSet.has(file)) continue;
308
+ const ranges = codeLiteralRanges(file, text);
309
+ const lines = new Set<number>();
310
+ let offset = 0;
311
+ text.split('\n').forEach((line, index) => {
312
+ const marks = [...line.matchAll(/\u{1F451}/gu)];
313
+ if (marks.length && marks.every((mark) => ranges.some(([from, to]) => offset + mark.index! >= from && offset + mark.index! + mark[0].length <= to))) lines.add(index + 1);
314
+ offset += line.length + 1;
315
+ });
316
+ classification.set(file, lines);
317
+ }
318
+ for (const hit of hits) {
319
+ if (hit.marker !== 'ceo-mark' || /\.(?:test|spec)\.(?:ts|tsx|mts|cts|js|jsx|mjs|cjs)$/iu.test(hit.file)) { leaks.push(hit); continue; }
320
+ (classification.get(hit.file)?.has(hit.line) ? codeLiterals : leaks).push(hit);
321
+ }
322
+ return { leaks, codeLiterals };
323
+ }
324
+
286
325
  /**
287
326
  * 🆕 `runtime-path-outside-export` — 공개되는 «코드»가 공개본에 «없는» 저장소 경로를 문자열로 쥐고 있다.
288
327
  * 계기: `docs/graph-templates/**` 가 허용 목록에서 빠져 공개본 영상 라인이 실행 중에 죽을 뻔했다(🅣 · `#20098`).
@@ -448,12 +487,13 @@ export function run(argv: readonly string[], root = resolve(import.meta.dir, '..
448
487
  }
449
488
  console.error(`exported ${files.length} files (+${Object.keys(config.replace).length} replaced) → ${target}`);
450
489
  }
451
- const hits = [
490
+ const rawHits = [
452
491
  ...gitIgnoredExportFiles(root, files).filter(inScope).map((file) => ({ marker: 'export-gitignored', file, line: 0, text: '공개본 .gitignore 에 걸린다 — 커밋하면 사라진다' })),
453
492
  ...scanLeaks(root, scanned, LEAK_MARKERS, transformed.contents, realDocs),
454
493
  ...(redactions ? scanLeaks(root, scanned, privateIdentifierMarkers(redactions), transformed.contents, realDocs) : []),
455
494
  ...(!redactions && !noPrivateList ? [{ marker: 'private-identifiers-unchecked', file: privateRedactionsPath(), line: 0, text: 'private redaction list missing' }] : []),
456
495
  ];
496
+ const { leaks: hits, codeLiterals } = splitCodeLiteralCeoMarks(scanned, transformed.contents, rawHits);
457
497
  const advisory = scanRuntimePaths(root, files, tracked, transformed.contents).filter((h) => inScope(h.file));
458
498
  const summary = summarizeLeaks(hits);
459
499
  const advisorySummary = summarizeLeaks(advisory);
@@ -464,6 +504,7 @@ export function run(argv: readonly string[], root = resolve(import.meta.dir, '..
464
504
  if (json) {
465
505
  console.log(JSON.stringify({
466
506
  files: scanned.length, leaks: hits.length, summary, before: { leaks: before.length, summary: beforeSummary }, transforms: transformed.counts, privateRedactions,
507
+ codeLiterals: { hits: codeLiterals.length, summary: summarizeLeaks(codeLiterals), items: all ? codeLiterals : codeLiterals.slice(0, limit) },
467
508
  shownHits: shown.length, truncated, omittedHits: hits.length - shown.length,
468
509
  ...(pathPrefix ? { pathPrefix } : {}), hits: shown,
469
510
  advisory: { hits: advisory.length, summary: advisorySummary, judge: RUNTIME_PATH_JUDGE, items: all ? advisory : advisory.slice(0, limit) },
@@ -473,6 +514,7 @@ export function run(argv: readonly string[], root = resolve(import.meta.dir, '..
473
514
  console.log(`leak check — ${scanned.length} files${pathPrefix ? ` under ${pathPrefix}` : ''} · ${hits.length} hits`);
474
515
  for (const [marker, s] of Object.entries(summary)) console.log(` ${marker.padEnd(20)} ${String(s.files).padStart(5)} files ${String(s.hits).padStart(6)} lines`);
475
516
  for (const hit of shown) console.log(` ${hit.marker} ${hit.file}:${hit.line} ${hit.text}`);
517
+ if (codeLiterals.length) console.log(`code literals (not document/comment leakage) — ceo-mark ${codeLiterals.length} lines`);
476
518
  if (truncated) console.log(` … ${hits.length - shown.length} more hits not shown — use --all, or narrow with --path <prefix> (⛔ «not in this list» ≠ «no leak»)`);
477
519
  if (advisory.length) console.log(`advisory (not counted) — runtime-path-outside-export ${advisory.length} lines · ${advisorySummary['runtime-path-outside-export']?.files ?? 0} files · judge = ${RUNTIME_PATH_JUDGE}`);
478
520
  }
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env bash
2
+ # Train-side sentinel for the eight real HARD 0.2.32 regressions. Run on the
3
+ # merged side tree before the changed-file gate; never interpret a missing test
4
+ # or an incomplete run as a pass.
5
+ set -u
6
+
7
+ files=(
8
+ scripts/ratchets/test-interference-patterns.test.ts
9
+ src/domains/finance-cli.test.ts
10
+ src/instance/state-dir-provenance-ratchet.test.ts
11
+ src/self-implement/graph-yaml.test.ts
12
+ src/self-implement/self-cli-sink-surface.test.ts
13
+ test/identity-env.test.ts
14
+ test/no-absolute-path-imports.test.ts
15
+ test/scenarios/integration.test.ts
16
+ )
17
+
18
+ if [[ ${1:-} == --list ]]; then
19
+ printf '%s\n' "${files[@]}"
20
+ exit 0
21
+ fi
22
+ if [[ $# -gt 1 ]]; then
23
+ echo 'TRAIN_INVARIANTS_UNMEASURED invalid-arguments'
24
+ exit 2
25
+ fi
26
+ cd "${1:-.}" || { echo 'TRAIN_INVARIANTS_UNMEASURED repo-unreadable'; exit 2; }
27
+ command -v bun >/dev/null 2>&1 || { echo 'TRAIN_INVARIANTS_UNMEASURED bun-missing'; exit 2; }
28
+
29
+ for file in "${files[@]}"; do
30
+ if [[ ! -f $file ]]; then
31
+ echo "TRAIN_INVARIANTS_UNMEASURED missing-file=$file"
32
+ exit 2
33
+ fi
34
+ done
35
+
36
+ for file in "${files[@]}"; do
37
+ echo "TRAIN_INVARIANTS_START $file"
38
+ bun test "$file"
39
+ rc=$?
40
+ if [[ $rc -ne 0 ]]; then
41
+ echo "TRAIN_INVARIANTS_FAIL file=$file rc=$rc"
42
+ exit 1
43
+ fi
44
+ done
45
+ echo "TRAIN_INVARIANTS_PASS files=${#files[@]}"
@@ -15,8 +15,12 @@ const outcomeMetric = (name: string, node: Record<string, unknown> | undefined):
15
15
  verdict: node?.outcome === undefined ? 'unmeasured' : node.outcome === 'ok' ? 'pass' : 'fail',
16
16
  });
17
17
 
18
- /** Rows shown in auto-approval.md but never counted toward the 8 blocking metrics. */
18
+ /** Rows outside the original eight fixed metrics. TUI regressions have their own HITL gate below. */
19
19
  export const WARNING_ONLY = new Set(['tui-regress', 'mac-smoke']);
20
+ export const BLOCKING_METRIC_NAMES = [
21
+ 'gate regressions and measurement', 'bun version', 'upgrade', 'tui', 'notes-check',
22
+ 'public leak and prepare completeness', 'docs notes page', 'installation files',
23
+ ] as const;
20
24
 
21
25
  /** `ok` · `warn` (a failure) · `unmeasured` (error or no output) — the macOS smoke never blocks publishing. */
22
26
  function macSmokeLevel(node: Record<string, unknown> | undefined): 'ok' | 'warn' | 'unmeasured' {
@@ -42,40 +46,50 @@ export function runAutoApprove(context: GraphContext = readGraphContext(), deps:
42
46
  catch { distCount = undefined; }
43
47
  }
44
48
  const gateErrorAbsent = gate && !Object.hasOwn(gate, 'error');
45
- const regressStatus = regressWarning(validatedTuiRegress(context.outputs.tui?.regress));
49
+ const regress = validatedTuiRegress(context.outputs.tui?.regress);
50
+ const regressStatus = regressWarning(regress);
51
+ const failedCheckIds = 'unmeasured' in regress ? null : regress.results.filter((result) => !result.ok).map((result) => result.id);
52
+ const failedLabel = failedCheckIds === null ? 'unmeasured' : `${failedCheckIds.length} [${failedCheckIds.join(', ') || '-'}]`;
53
+ const regressNeedsApproval = regressStatus.level !== 'ok';
46
54
  const macSmoke = context.outputs['mac-smoke'];
47
55
  const metrics: ApprovalMetric[] = [
48
- { name: 'gate regressions and measurement', value: JSON.stringify({ outcome: gate?.outcome ?? null, introduced: gate?.introduced ?? null, error: gate?.error ?? null }),
56
+ { name: BLOCKING_METRIC_NAMES[0], value: JSON.stringify({ outcome: gate?.outcome ?? null, introduced: gate?.introduced ?? null, error: gate?.error ?? null }),
49
57
  verdict: !gate || gate.outcome === undefined || !Array.isArray(gate.introduced) ? 'unmeasured'
50
58
  : gate.outcome === 'ok' && gate.introduced.length === 0 && gateErrorAbsent ? 'pass' : 'fail' },
51
- { name: 'bun version', value: `running=${bunVersion}; pinned=${pinned ?? 'missing'}`,
59
+ { name: BLOCKING_METRIC_NAMES[1], value: `running=${bunVersion}; pinned=${pinned ?? 'missing'}`,
52
60
  verdict: !pinned ? 'unmeasured' : bunVersion === pinned ? 'pass' : 'fail' },
53
- outcomeMetric('upgrade', context.outputs.upgrade),
54
- outcomeMetric('tui', context.outputs.tui),
55
- outcomeMetric('notes-check', context.outputs['notes-check']),
56
- { name: 'public leak and prepare completeness', value: `prepare=${prepare?.outcome ?? 'missing'}`,
61
+ outcomeMetric(BLOCKING_METRIC_NAMES[2], context.outputs.upgrade),
62
+ outcomeMetric(BLOCKING_METRIC_NAMES[3], context.outputs.tui),
63
+ outcomeMetric(BLOCKING_METRIC_NAMES[4], context.outputs['notes-check']),
64
+ { name: BLOCKING_METRIC_NAMES[5], value: `prepare=${prepare?.outcome ?? 'missing'}`,
57
65
  verdict: prepare?.outcome === undefined ? 'unmeasured' : prepare.outcome === 'ok' ? 'pass' : 'fail' },
58
- { name: 'docs notes page', value: `docs=${context.outputs.docs?.outcome ?? 'missing'}; notes=${String(context.outputs.docs?.notes ?? 'missing')}`,
66
+ { name: BLOCKING_METRIC_NAMES[6], value: `docs=${context.outputs.docs?.outcome ?? 'missing'}; notes=${String(context.outputs.docs?.notes ?? 'missing')}`,
59
67
  verdict: context.outputs.docs?.outcome === undefined || context.outputs.docs.notes === undefined ? 'unmeasured'
60
68
  : context.outputs.docs.outcome === 'ok' && typeof context.outputs.docs.notes === 'string' && context.outputs.docs.notes.trim() ? 'pass' : 'fail' },
61
- { name: 'installation files', value: `dist files=${distCount ?? 'missing'}; prepare.out=${String(out ?? 'missing')}`,
69
+ { name: BLOCKING_METRIC_NAMES[7], value: `dist files=${distCount ?? 'missing'}; prepare.out=${String(out ?? 'missing')}`,
62
70
  verdict: prepare?.outcome !== 'ok' ? prepare?.outcome === undefined ? 'unmeasured' : 'fail'
63
71
  : distCount === undefined ? 'unmeasured' : distCount === 5 ? 'pass' : 'fail' },
64
- // Warning-only and last, so the numbered rows 1–8 keep their places in auto-approval.md (V1g follow-up).
65
- { name: 'tui-regress', value: regressStatus.level, reason: regressStatus.line, verdict: 'pass' },
72
+ // Kept after the eight fixed metrics; a failed or unmeasured subcheck requires the existing approve-publish HITL node.
73
+ { name: 'tui-regress', value: regressStatus.level, reason: regressStatus.line,
74
+ verdict: regressStatus.level === 'ok' ? 'pass' : regressStatus.level === 'warn' ? 'fail' : 'unmeasured' },
66
75
  // MAC1: the macOS smoke is warning-only too (ship with known issues) — shown, never counted.
67
76
  { name: 'mac-smoke', value: macSmokeLevel(macSmoke), reason: typeof macSmoke?.summary === 'string' ? macSmoke.summary : undefined, verdict: 'pass' },
68
77
  ];
69
- const outcome = metrics.filter((metric) => !WARNING_ONLY.has(metric.name)).every((metric) => metric.verdict === 'pass') ? 'ok' as const : 'fail' as const;
78
+ const outcome = metrics.filter((metric) => !WARNING_ONLY.has(metric.name)).every((metric) => metric.verdict === 'pass')
79
+ && !regressNeedsApproval ? 'ok' as const : 'fail' as const;
70
80
  const report = join(root, 'release', version, 'auto-approval.md');
71
81
  const lines = [`# v${version} auto-approval`, '', `Outcome: ${outcome}`, '', '| # | Metric | Value | Verdict |', '|---|---|---|---|',
72
82
  ...metrics.map((metric, i) => `| ${i + 1} | ${metric.name} | ${[metric.value, metric.reason].filter(Boolean).join(' — ').replaceAll('|', '\\|').replace(/[\r\n]/g, ' ')} | ${metric.verdict} |`),
83
+ '', `TUI subcheck: ${regressStatus.level} · failed ${failedLabel} · ${regressNeedsApproval ? 'HITL 수용/정지 필요' : '자동 판정 가능'}`,
73
84
  '', '## 되돌리는 법', `gh release edit v${version} --draft`, `git tag -d v${version} && git push origin :refs/tags/v${version}`, '해당 docs PR revert', ''];
74
85
  mkdirSync(dirname(report), { recursive: true });
75
86
  writeFileSync(report, lines.join('\n'));
76
- debug.log('release-loop.approve', 'auto-decision', { version, outcome, metrics });
77
- return { outcome, verdict: outcome === 'ok' ? 'pass' as const : 'fail' as const, summary: `auto approval ${outcome}: ${metrics.filter((metric) => !WARNING_ONLY.has(metric.name) && metric.verdict === 'pass').length}/8`,
78
- ...(outcome === 'ok' ? { decidedBy: 'release-loop metrics' as const } : {}), metrics, report };
87
+ const tuiSubcheck = { runId: context.runId ?? null, level: regressStatus.level,
88
+ fail: failedCheckIds?.length ?? null, failedCheckIds, approvalRequired: regressNeedsApproval };
89
+ debug.log('release-loop.approve', 'auto-decision', { version, outcome, metrics, tuiSubcheck });
90
+ return { outcome, verdict: outcome === 'ok' ? 'pass' as const : 'fail' as const,
91
+ summary: `auto approval ${outcome}: ${metrics.filter((metric) => !WARNING_ONLY.has(metric.name) && metric.verdict === 'pass').length}/8${regressNeedsApproval ? ` · tui-regress ${regressStatus.level} failed ${failedLabel} → HITL` : ''}`,
92
+ runId: context.runId ?? null, tuiSubcheck, ...(outcome === 'ok' ? { decidedBy: 'release-loop metrics' as const } : {}), metrics, report };
79
93
  }
80
94
 
81
95
  if (import.meta.main) {
@@ -1,14 +1,28 @@
1
1
  #!/usr/bin/env bun
2
- import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
2
+ import { existsSync, mkdtempSync, readFileSync, realpathSync, rmSync } from 'node:fs';
3
3
  import { effectiveInstanceRoot, releaseLedgerRoot } from '../../src/instance/resolve.js';
4
4
  import { listChecklist } from '../../src/release-loop/checklist.js';
5
5
  import type { ReleaseManifest } from '../../src/release-loop/manifest.js';
6
6
  import { recordDocsFollow, type DocsFollowItem } from './release-docs.js';
7
- import { dirname, join } from 'node:path';
7
+ import { basename, dirname, join } from 'node:path';
8
8
  import { tmpdir } from 'node:os';
9
- import { errorResult, finishNode, nodeOutput, readGraphContext, runCommand, type CommandRunner } from './node-verdict.js';
9
+ import { errorResult, finishNode, nodeOutput, readGraphContext, runCommand, type CommandRunner, type GraphContext } from './node-verdict.js';
10
10
  import { prereleaseKind } from './release-version.js';
11
11
 
12
+ function isRunOwnedDocsPrefetchTree(worktree: string, context: GraphContext, ledgerRoot: string): boolean {
13
+ const runId = context.runId;
14
+ if (!runId || !/^[A-Za-z0-9._-]+$/.test(runId)) return false;
15
+ const prefetchRoot = join(ledgerRoot, 'graph-runs', 'release-loop', `${runId}.json.contexts`, 'docs-prefetch');
16
+ try {
17
+ // Resolve symlinks too: an in-run path that points outside this run does not establish ownership.
18
+ const owner = realpathSync(prefetchRoot);
19
+ const tree = realpathSync(worktree);
20
+ return dirname(tree) === owner && /^tree(?:-[0-9a-f-]{36})?$/.test(basename(tree));
21
+ } catch {
22
+ return false;
23
+ }
24
+ }
25
+
12
26
  export function runDocsLand(run: CommandRunner = runCommand, stateRoot = effectiveInstanceRoot(), ledgerRoot = releaseLedgerRoot()) {
13
27
  const context = readGraphContext();
14
28
  const version = context.input.version;
@@ -18,7 +32,9 @@ export function runDocsLand(run: CommandRunner = runCommand, stateRoot = effecti
18
32
  if (branch !== `release-docs/${version}`) throw new Error('docs branch/version mismatch');
19
33
  const worktree = nodeOutput(context, 'docs', 'worktree');
20
34
  const scratch = dirname(worktree);
21
- if (dirname(scratch) !== tmpdir() || !/^release-docs-[A-Za-z0-9]+$/.test(scratch.split('/').at(-1) ?? '') || worktree !== join(scratch, 'tree')) throw new Error('invalid docs worktree');
35
+ const tmpWorktree = dirname(scratch) === tmpdir() && /^release-docs-[A-Za-z0-9]+$/.test(basename(scratch))
36
+ && worktree === join(scratch, 'tree');
37
+ if (!tmpWorktree && !isRunOwnedDocsPrefetchTree(worktree, context, ledgerRoot)) throw new Error('invalid docs worktree');
22
38
  const recordFollow = (deployed: boolean) => {
23
39
  const releaseDir = join(stateRoot, 'release', version);
24
40
  const manifest: ReleaseManifest = JSON.parse(readFileSync(join(releaseDir, 'manifest.json'), 'utf8'));
@@ -88,7 +104,7 @@ export function runDocsLand(run: CommandRunner = runCommand, stateRoot = effecti
88
104
  const remove = run('git', ['worktree', 'remove', '--force', worktree]);
89
105
  if (remove.status !== 0) throw new Error(`docs worktree cleanup failed: ${remove.stderr}`);
90
106
  }
91
- rmSync(scratch, { recursive: true, force: true });
107
+ if (tmpWorktree) rmSync(scratch, { recursive: true, force: true });
92
108
  // 배포 성공 — 후속 기록 실패(manifest 없음 등)는 결과를 «실패»로 바꾸지 않는다. 알리고 넘어간다.
93
109
  let follow: ReturnType<typeof recordFollow> | undefined;
94
110
  try { follow = recordFollow(true); }
@@ -0,0 +1,155 @@
1
+ /** A full gate's reusable identity. Missing evidence is recorded, never promoted to a clean baseline. */
2
+ import { createHash } from 'node:crypto';
3
+ import { spawnSync } from 'node:child_process';
4
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { gateTestBaseline } from '../lib/gate-test-env.js';
7
+
8
+ const SHA256 = /^[0-9a-f]{64}$/i;
9
+ const IMAGE_DIGEST = /^sha256:[0-9a-f]{64}$/i;
10
+ export const POD_SWEEP_INTEGRATION_ONLY: readonly string[] = ['scripts/install.test.ts', 'scripts/review-model-ab.test.ts'];
11
+
12
+ /** Reconstruct the producer's tracked test selection at its pinned commit. Missing Git evidence is not a smaller set. */
13
+ export function gateAssignableTestsAtCommit(repo: string, commit: string): string[] | null {
14
+ if (!/^[0-9a-f]{40}$/i.test(commit)) return null;
15
+ const tree = spawnSync('git', ['ls-tree', '-r', '--name-only', commit], { cwd: repo, encoding: 'utf8', maxBuffer: 32 * 1024 * 1024 });
16
+ const cdp = spawnSync('git', ['grep', '-l', '-e', 'requireCdpBase', '-e', '9333', commit, '--', 'test', 'scripts'],
17
+ { cwd: repo, encoding: 'utf8', maxBuffer: 32 * 1024 * 1024 });
18
+ if (tree.status !== 0 || tree.error || (cdp.status !== 0 && cdp.status !== 1) || cdp.error) return null;
19
+ const cdpFiles = new Set(cdp.stdout.split(/\r?\n/).filter(Boolean).map((line) => line.slice(commit.length + 1))
20
+ .filter((file) => file.endsWith('.test.ts')));
21
+ return tree.stdout.split(/\r?\n/).filter((file) => /\.test\.(?:tsx?|jsx?|mts|cts)$/.test(file)
22
+ && !cdpFiles.has(file) && !POD_SWEEP_INTEGRATION_ONLY.includes(file)
23
+ && !file.split('/').some((part) => part.startsWith('.'))).sort();
24
+ }
25
+
26
+ export interface GateBaselineReceipt {
27
+ schema: 1;
28
+ valid: boolean;
29
+ reason: string;
30
+ version: string;
31
+ commit: string;
32
+ graphSha: string | null;
33
+ recipeSha: string | null;
34
+ envFingerprint: string;
35
+ imageDigest: string | null;
36
+ files: number;
37
+ shards: number;
38
+ }
39
+
40
+ /** A direct hard rehearsal has no graph run state. Pin the graph and recipe bytes at its Git SHA. */
41
+ export function gateSourcePins(repo: string, commit: string): { graphSha: string; recipeSha: string } | null {
42
+ if (!/^[0-9a-f]{40}$/i.test(commit)) return null;
43
+ const read = (file: string): string | null => {
44
+ const result = spawnSync('git', ['show', `${commit}:${file}`], { cwd: repo, encoding: 'utf8', maxBuffer: 8 * 1024 * 1024 });
45
+ return result.status === 0 && !result.error ? result.stdout : null;
46
+ };
47
+ const graph = read('graphs/release/release-loop.yaml');
48
+ const recipe = read('graphs/release/recipes.yaml');
49
+ return graph === null || recipe === null ? null : {
50
+ graphSha: createHash('sha256').update(graph).digest('hex'),
51
+ recipeSha: createHash('sha256').update(recipe).digest('hex'),
52
+ };
53
+ }
54
+
55
+ /** Only Kubernetes' observed child container imageID is evidence; the requested image tag is not. */
56
+ export function actualGatePodImageDigest(podJson: string): string | null {
57
+ try {
58
+ const pods = JSON.parse(podJson) as { items?: Array<{ status?: { containerStatuses?: Array<{ name?: string; imageID?: string }> } }> };
59
+ // A retry can create more than one Pod; collected test bytes are not bound to one of their UIDs.
60
+ if (pods.items?.length !== 1) return null;
61
+ const id = pods.items[0]?.status?.containerStatuses?.find((row) => row.name === 'child')?.imageID;
62
+ const digest = typeof id === 'string' ? /(?:^|@|:\/\/)(sha256:[0-9a-f]{64})$/i.exec(id)?.[1] : undefined;
63
+ return digest && IMAGE_DIGEST.test(digest) ? digest.toLowerCase() : null;
64
+ } catch { return null; }
65
+ }
66
+
67
+ export function gateEnvFingerprint(env: NodeJS.ProcessEnv): string {
68
+ const baseline = gateTestBaseline(env);
69
+ return createHash('sha256').update(JSON.stringify(Object.fromEntries(Object.entries(baseline).sort(([a], [b]) => a.localeCompare(b))))).digest('hex');
70
+ }
71
+
72
+ /** Graph runner pins these bytes in its run state. A direct gate without that state cannot mint a reusable receipt. */
73
+ export function gateGraphPins(root: string, runId: string | undefined): { graphSha: string; recipeSha: string } | null {
74
+ if (!runId || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(runId)) return null;
75
+ try {
76
+ const state = JSON.parse(readFileSync(join(root, 'graph-runs', 'release-loop', `${runId}.json`), 'utf8')) as
77
+ { graphId?: string; runId?: string; graphSnapshot?: { graphSha?: string; recipesSha?: string } };
78
+ const graphSha = state.graphSnapshot?.graphSha;
79
+ const recipeSha = state.graphSnapshot?.recipesSha;
80
+ return state.graphId === 'release-loop' && state.runId === runId && graphSha && recipeSha
81
+ && SHA256.test(graphSha) && SHA256.test(recipeSha) ? { graphSha, recipeSha } : null;
82
+ } catch { return null; }
83
+ }
84
+
85
+ export function gateBaselineReceipt(input: { root: string; version: string; commit: string; fullSweep: boolean;
86
+ graphPins: { graphSha: string; recipeSha: string } | null; envFingerprint: string }): GateBaselineReceipt {
87
+ const { root, version, commit, graphPins, envFingerprint } = input;
88
+ const base = { schema: 1 as const, version, commit, graphSha: graphPins?.graphSha ?? null,
89
+ recipeSha: graphPins?.recipeSha ?? null, envFingerprint, imageDigest: null as string | null, files: 0, shards: 0 };
90
+ const invalid = (reason: string): GateBaselineReceipt => ({ ...base, valid: false, reason });
91
+ if (!input.fullSweep) return invalid('gate was not a complete clean full sweep');
92
+ if (!graphPins) return invalid('pinned graph or recipe SHA absent');
93
+ if (!SHA256.test(envFingerprint)) return invalid('gate environment fingerprint absent');
94
+ try {
95
+ const dir = join(root, 'release', version, 'gate-logs', 'cut');
96
+ if (!existsSync(dir)) return invalid('cut Pod logs absent');
97
+ const names = readdirSync(dir).filter((name) => /^pod-\d+(?:-[\w-]+)?\.json$/.test(name));
98
+ const roots = new Map<number, { files: string[]; shardCount: number; sweepId: string; attemptId: string }>();
99
+ const descendants: Array<{ name: string; commit?: string; imageDigest?: string; sweepId?: string; parentAttempt?: string; attemptId?: string }> = [];
100
+ const images = new Set<string>();
101
+ for (const name of names) {
102
+ const row = JSON.parse(readFileSync(join(dir, name), 'utf8')) as
103
+ { commit?: string; files?: unknown; shardCount?: number; sweepId?: string; imageDigest?: string; parentAttempt?: string; attemptId?: string };
104
+ const match = /^pod-(\d+)\.json$/.exec(name);
105
+ if (match) {
106
+ if (row.commit !== commit) return invalid(`root cut Pod ${name} belongs to another commit`);
107
+ if (!Array.isArray(row.files) || !row.files.length || !row.files.every((file) => typeof file === 'string'))
108
+ return invalid(`root cut Pod ${name} has no file list`);
109
+ if (!row.attemptId) return invalid(`root cut Pod ${name} has no attempt`);
110
+ if (!row.sweepId) return invalid(`root cut Pod ${name} has no sweep identity`);
111
+ roots.set(Number(match[1]), { files: row.files as string[], shardCount: row.shardCount ?? 0, sweepId: row.sweepId, attemptId: row.attemptId });
112
+ } else descendants.push({ name, commit: row.commit, imageDigest: row.imageDigest, sweepId: row.sweepId,
113
+ parentAttempt: row.parentAttempt, attemptId: row.attemptId });
114
+ if (match) {
115
+ if (!row.imageDigest || !IMAGE_DIGEST.test(row.imageDigest)) return invalid(`actual Pod image digest absent: ${name}`);
116
+ images.add(row.imageDigest.toLowerCase());
117
+ }
118
+ }
119
+ if (!roots.size) return invalid('root cut shards absent');
120
+ const count = roots.get(0)?.shardCount;
121
+ if (!count || !Number.isSafeInteger(count) || count !== roots.size
122
+ || [...roots.keys()].some((index) => index < 0 || index >= count)) return invalid('root cut shard set incomplete');
123
+ const sweepId = roots.get(0)!.sweepId;
124
+ if ([...roots.values()].some((row) => row.shardCount !== count || row.sweepId !== sweepId))
125
+ return invalid('root cut shards belong to different sweeps');
126
+ const files = [...roots.values()].flatMap((row) => row.files);
127
+ if (new Set(files).size !== files.length) return invalid('root cut file lists overlap');
128
+ // A new cut can leave older split descendants in the same directory. Bind only the current roots' attempt tree.
129
+ const attempts = new Set([...roots.values()].map((row) => row.attemptId));
130
+ let pending = descendants;
131
+ for (; pending.length;) {
132
+ const next = pending.filter((row) => !row.parentAttempt || !attempts.has(row.parentAttempt));
133
+ if (next.length === pending.length) break;
134
+ for (const row of pending) {
135
+ if (!row.parentAttempt || !attempts.has(row.parentAttempt)) continue;
136
+ if (row.commit !== commit) return invalid(`cut Pod ${row.name} belongs to another commit`);
137
+ if (row.sweepId !== sweepId) return invalid(`cut Pod ${row.name} belongs to another sweep`);
138
+ if (!row.imageDigest || !IMAGE_DIGEST.test(row.imageDigest)) return invalid(`actual Pod image digest absent: ${row.name}`);
139
+ if (!row.attemptId) return invalid(`cut Pod ${row.name} has no attempt`);
140
+ images.add(row.imageDigest.toLowerCase());
141
+ attempts.add(row.attemptId);
142
+ }
143
+ pending = next;
144
+ }
145
+ // A child carrying this sweep's identity must be connected to a root,
146
+ // even when its parentAttempt is missing or corrupt. Otherwise its image
147
+ // evidence is silently omitted and a mixed-image receipt can look valid.
148
+ for (const row of pending) {
149
+ if (row.sweepId === sweepId) return invalid(`cut Pod ${row.name} has no connected parent attempt`);
150
+ if (row.commit === commit && !row.sweepId) return invalid(`cut Pod ${row.name} has no sweep identity`);
151
+ }
152
+ if (images.size !== 1) return invalid('cut Pods used different image digests');
153
+ return { ...base, valid: true, reason: 'complete clean full sweep', imageDigest: [...images][0]!, files: files.length, shards: count };
154
+ } catch (error) { return invalid(`cut Pod evidence unreadable: ${String(error)}`); }
155
+ }
@@ -11,6 +11,9 @@ import { sourceCandidates } from '../../src/self-implement/importer-test-index.j
11
11
 
12
12
  /** Files the closure follows (code). Changing anything else that is not a test or inert Markdown is a full gate. */
13
13
  export const CODE_FILE = /\.(?:[cm]?[jt]sx?)$/;
14
+ /** One release input whose readers use a literal basename in readFileSync(join(import.meta.dir, ...)).
15
+ * Other JSON stays a full gate until its dependency edge is proved. */
16
+ export const TRACEABLE_RELEASE_JSON = 'scripts/release-loop/known-issues-0.2.33-approved.json';
14
17
  const TEST_FILE = /^(?:[\w.-]+\/)*[\w.-]+\.test\.(?:tsx?|jsx?|mts|cts)$/;
15
18
  /** Test-side helpers: their filesystem scans and unresolved code paths make a test opaque (production code is trusted to
16
19
  * reach code only through imports and the literal paths below). */
@@ -159,7 +162,8 @@ export function buildClosureGraph(tree: ClosureTree, options: ClosureOptions = {
159
162
  for (const match of code.matchAll(LITERAL)) {
160
163
  const value = match[2]!;
161
164
  if (!value || value.length > 300 || value.includes('${') || /\s/.test(value) || /^[a-z]+:/i.test(value)) continue;
162
- const pathLike = value.startsWith('./') || value.startsWith('../') || (value.includes('/') && /^[\w@.-]+(?:\/[\w@.-]+)+\/?$/.test(value)) || CODE_FILE.test(value);
165
+ const pathLike = value.startsWith('./') || value.startsWith('../') || (value.includes('/') && /^[\w@.-]+(?:\/[\w@.-]+)+\/?$/.test(value)) || CODE_FILE.test(value)
166
+ || value === TRACEABLE_RELEASE_JSON.split('/').at(-1);
163
167
  if (!pathLike) continue;
164
168
  const plain = value.replace(/\/$/, '');
165
169
  const hit = resolveLiteral(file, plain);
@@ -12,7 +12,7 @@ export function parseFailures(output: string): string[] {
12
12
  const line = raw.trim();
13
13
  const header = /^(?:\.\/)?((?:[\w.-]+\/)+[\w.-]+\.test\.tsx?):(?:\s|$)/.exec(line);
14
14
  if (header) { file = header[1]; continue; }
15
- const failed = /^\(fail\)[ \t]+(.+?)(?:[ \t]+\[[\d.]+(?:ms|s)\])?$/.exec(line);
15
+ const failed = /^\(fail\)[ \t]+(.+?)(?:[ \t]+\[[\d.]+(?:ms|s)\])?[ \t]*$/.exec(raw);
16
16
  if (failed && file) failures.add(`${file} > ${failed[1]!.trim()}`);
17
17
  }
18
18
  return [...failures].sort();