elanous 0.2.37 → 0.2.38

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 (588) 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/{8kITumG9GAZ1LwT9POrAR → RrjXTwz-urRAbChP1bX02}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{2002-a43a3f380df873ec.js → 1026-44010f405704050c.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/1118.a8a74ea29aac3e46.js +27 -0
  6. package/apps/pwa/out/_next/static/chunks/1204-2aa830479adf80f4.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1341-43b7d2dc77d45c9d.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1440-c3ea8882badfd9bf.js +1 -0
  9. package/apps/pwa/out/_next/static/chunks/{7424.c0fe2a595d4232b5.js → 1632.7d87f998e714bede.js} +1 -1
  10. package/apps/pwa/out/_next/static/chunks/1698-9c11cbf97f13717e.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1770-3b1fc92253ef9f2f.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/{4937-28d437999b77c9dd.js → 1923-5c1695332240246a.js} +1 -1
  13. package/apps/pwa/out/_next/static/chunks/1938.0e6c60ee91c4d7f5.js +148 -0
  14. package/apps/pwa/out/_next/static/chunks/2104.70e086d5174a4736.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/213-20675f20673ba22a.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/214.186a430da28338f1.js +1 -0
  17. package/apps/pwa/out/_next/static/chunks/2277.3bd4c0ac7f1b5996.js +93 -0
  18. package/apps/pwa/out/_next/static/chunks/240.e09f433f71c78ff4.js +104 -0
  19. package/apps/pwa/out/_next/static/chunks/{3199.6a1a9b0e6cd01dc6.js → 2415.738b777642a02233.js} +1 -1
  20. package/apps/pwa/out/_next/static/chunks/2417.02151393605a7cd0.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2463.cd2641a76daaa9ff.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2576.b9e9c629c4b84c52.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/265-c021de53f0865bd9.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2998-b1cc13956cd6a6e7.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2e4782d3.ba2f0ab2b63a53e7.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/{1262.a89bb27a5b2f844e.js → 3086.fb14b60ce98b53d3.js} +1 -1
  27. package/apps/pwa/out/_next/static/chunks/3124-561f7f037943cde2.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/3130.626b54382b4dc379.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/3221-1bb3f99a55088613.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/3280.24edb1ffd03a7f3f.js +24 -0
  31. package/apps/pwa/out/_next/static/chunks/3288-eb3c22a1cbf2ae68.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{2283.edd9627b7bdfb546.js → 3291.f6c1005387d514bd.js} +2 -2
  33. package/apps/pwa/out/_next/static/chunks/33.ef99e8374f96c6c4.js +36 -0
  34. package/apps/pwa/out/_next/static/chunks/{6877-84d47b7e85d0c41e.js → 3341-f09b9efbd7a82f70.js} +1 -1
  35. package/apps/pwa/out/_next/static/chunks/3389.012c70767a872f9b.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3410-d7c0f14b329d6fda.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3421.c87d6313a7d670f7.js +287 -0
  38. package/apps/pwa/out/_next/static/chunks/3422-83a3953f9bd67e26.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/{6680.6a693c28aae4cd19.js → 3528.e4b8ab70d339f965.js} +1 -1
  40. package/apps/pwa/out/_next/static/chunks/3587-002e24e368c515a9.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/3644.f12a7d821ab940af.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/3660.d7516588e2d875c3.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/3695.b82e2610f4cd4ea9.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/3858.ca1f5bc0f577eac9.js +94 -0
  45. package/apps/pwa/out/_next/static/chunks/3959-e6ac4a139d9d4bcc.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/3f0de3de-2340c532c00395db.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4032.53f62176514ec0ea.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4199-f7c6eb40cd0322f8.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4204-ef8484cbecd5d62f.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4259-163129ca79913c4b.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/428-eaa77df3d0c85969.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4432-97e400ffa1e161f5.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/449-aa427cf2cbb75f50.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/4491-39a0fd32bbaf3840.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/4588.b7cf06d382953979.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/4690.70ec8060825366ab.js +32 -0
  57. package/apps/pwa/out/_next/static/chunks/{4036.d54e55e1ebf5acdc.js → 4804.6012b5cd33c22792.js} +2 -2
  58. package/apps/pwa/out/_next/static/chunks/4881.e4d22d730e3b9df5.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/4937.ce2e340dc29cad3e.js +79 -0
  60. package/apps/pwa/out/_next/static/chunks/5-bb1c08d84bd71df3.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5005.de98df23b37cdf3c.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5035.dc64a89cad5573cc.js +74 -0
  63. package/apps/pwa/out/_next/static/chunks/5041-5aada92ca215ffdd.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/{6819.be5c9c4d67f22922.js → 5203.51e5d8b5f1dcfe53.js} +16 -16
  65. package/apps/pwa/out/_next/static/chunks/5207.1a224035455790fd.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/{757-4fbaf50942b8c424.js → 5255-1b60d50eabe9f057.js} +1 -1
  67. package/apps/pwa/out/_next/static/chunks/5269.d0436ee6d773382a.js +286 -0
  68. package/apps/pwa/out/_next/static/chunks/5300.677c97e0393742e6.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/{7867.e8725745ddd1d940.js → 5307.d7328020227880c2.js} +4 -4
  70. package/apps/pwa/out/_next/static/chunks/5309.3367c4d50f52b489.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/552-689827d49780fa00.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/5539.34cc9d60622cb69b.js +8 -0
  73. package/apps/pwa/out/_next/static/chunks/5568.218dea0c00ca2ec7.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/{5046.7fd5cbd859299448.js → 5638.107314dc479e2f37.js} +1 -1
  75. package/apps/pwa/out/_next/static/chunks/5645.b7e3b055455a04ea.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/5662.18cc0f30353cbd96.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/5671.da24fc9dc5e98325.js +1 -0
  78. package/apps/pwa/out/_next/static/chunks/5b141171.324c40fd49cb6821.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6142.913b44e260a3f925.js +64 -0
  80. package/apps/pwa/out/_next/static/chunks/6175-d4621f6a10b0cfab.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6290.3eb53a20746b72ce.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6415-9307f3eafa90837f.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6493.27ad77de7aac7966.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/6579-3de35d00aacd71b5.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/680-2f324c4e039a5b67.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/6845-331b3c7481da3ba3.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/{1224.2ceca6c180d5130b.js → 7000.28157393caaf5343.js} +1 -1
  88. package/apps/pwa/out/_next/static/chunks/{6745-5a63492933959dd9.js → 7161-8f22db3ec5ed005e.js} +3 -3
  89. package/apps/pwa/out/_next/static/chunks/{2479-fe7e188bd9402d14.js → 7311-60a7ea80d23c7521.js} +1 -1
  90. package/apps/pwa/out/_next/static/chunks/7401.525d0a12f7d02c06.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7438.c2cf72b66dca6aa4.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{5952.294fc574a8625184.js → 7488.966b116789f3d41a.js} +1 -1
  93. package/apps/pwa/out/_next/static/chunks/7524.ce973525d30b3d52.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7573.2376e13c9c21f1f8.js +77 -0
  95. package/apps/pwa/out/_next/static/chunks/7577.ea6e9ac72e035520.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/{6252.240578f10952e091.js → 7628.6b16863ac3972333.js} +1 -1
  97. package/apps/pwa/out/_next/static/chunks/7657.8d1fb3d2f7ebe273.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7903-1435d5d2f0dd7807.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/{1746.3563617ea64023a3.js → 7954.4f7a8832663ee979.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/7978-30a91192c5dbe3c2.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/{4931.95cc6dbd230774ca.js → 8019.21ca554a821dad01.js} +16 -16
  102. package/apps/pwa/out/_next/static/chunks/8025-8795821525cf1a07.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8191.3674a00f0b565c23.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8217-604955d8885c5ef2.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8298-eed6f5f2585a63f4.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/{2375.bf364c85dbb6f085.js → 8487.291666583bebe640.js} +1 -1
  107. package/apps/pwa/out/_next/static/chunks/8509.3a54d4e61893d7cb.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/8758.ac421f726a189125.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/{4383.18e5c54db3a22c88.js → 8879.ac06755bcf3e44a1.js} +1 -1
  110. package/apps/pwa/out/_next/static/chunks/891.d6c723a51a067b36.js +149 -0
  111. package/apps/pwa/out/_next/static/chunks/{9151.a2c51e93f9156dae.js → 8911.bf5e712acb25fb6c.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/{58edce7d.f1b0c72acf13b123.js → 8994d93e.33ba491f95345fc2.js} +1 -1
  113. package/apps/pwa/out/_next/static/chunks/{5f6af561-f90b7a67f4f75d13.js → 89d6c04f-6b8ab341748e468a.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/9223.cbcc88e0e9950426.js +41 -0
  115. package/apps/pwa/out/_next/static/chunks/9299.24e2a7d9b6d1f91b.js +226 -0
  116. package/apps/pwa/out/_next/static/chunks/9317.6a9869039c231bb3.js +24 -0
  117. package/apps/pwa/out/_next/static/chunks/9383.e4755f275b3c11ff.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9581.da63ddf41acfad46.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9715.8c5529a0a5c41a36.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9817.3009d65f0889ef1f.js +2 -0
  121. package/apps/pwa/out/_next/static/chunks/{de8446d3.31b73eb239fecd7b.js → 9fe1b809.738da85c8b17e3fb.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76873dd80da4f715.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed32b6ec5dea8f23.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-fdd40e15babf3d25.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-384efc78e85e400b.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-866aac5ff226a7f3.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-d91809c5aeed319a.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-128f3522f89a81ab.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-595961abf3b43ad1.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-f41dccb76d8c0263.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-a3205c2e28b7d0d9.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-c39a80277814a3f4.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-1ab3f98194513195.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-a5246f7e254d77d0.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-0f92287bdb81217d.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-5a37131ff63793ef.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-76873dd80da4f715.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-ac4bd14bb2348bfd.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/{page-5c112c6d7c33656e.js → page-c348a3959c5b5fc6.js} +1 -1
  140. package/apps/pwa/out/_next/static/chunks/app/layout-2addd81c0d3e2906.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-da6b765f58a3eefb.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-0661e40f8780c32c.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-b89af1b1c8e4875b.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-da8aeb82ba751cdb.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-cc71317b239439db.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-bde7fc1d64ffe369.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-e2797214f713fa58.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-2a35bcda70defaf6.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3af03deedde45032.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/{page-88a1edbff62eaf1d.js → page-d1d1210f99f620ae.js} +1 -1
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-46d1b5500885861d.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-291ab19fe2acb173.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/{page-b9af2ac1c4737ce8.js → page-7f569e533ddeecba.js} +1 -1
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-990129c9fee46d8f.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-7737f785ebb1cdaf.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9f3c73a4f7ffd2f8.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-03be7fb347f01058.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-96b0280625e4df2b.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-56855545049eb56d.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-76873dd80da4f715.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-79a909c9981f0338.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/{page-fb9e639c107f5f72.js → page-a9d9a3e66459c1e0.js} +1 -1
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c383cbf2013f7069.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f57c6a2e54dbdca4.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-6b140f77593576eb.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-6b767ae2d9d0adfc.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-116d6198d5da0e3d.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-b9c9b778c7501370.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-a6c78392ab8f6335.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-455183deb4ed0cfe.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6a63e99526bd63d0.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-31c22caafe788c08.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{709a918c.4fd3b4e2a32cb4e3.js → b7459770.6539b11860eb8a9c.js} +7 -7
  174. package/apps/pwa/out/_next/static/chunks/{d9815f84.4918f682a45a8502.js → b7478fef.5917716286213fcc.js} +3 -3
  175. package/apps/pwa/out/_next/static/chunks/{4337e36d.f42c3b391b3d8f20.js → bb6987f9.3647e1a23b0e3217.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/de8b930d.d94c0f42acf807fc.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/{8c58d09b.e8724a299658d86f.js → eaad0cba.771200940c529df7.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/framework-4b12a946f352cee2.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-941155250ed2644b.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-f8b6765abed6d149.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-78432194c85388f9.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-cdf7390829512b1b.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-d5f0964a9c2e92d2.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/graphs/release/recipes.yaml +9 -0
  278. package/graphs/release/release-loop.yaml +26 -18
  279. package/package.json +1 -1
  280. package/scripts/ask-op-inbox-once.ts +17 -0
  281. package/scripts/brand/check.ts +13 -4
  282. package/scripts/gate-0226-accepted-remaining-90.txt +91 -0
  283. package/scripts/gate-0226-failure-census.ts +39 -0
  284. package/scripts/intake-collect-telegram-saved-stage.ts +48 -0
  285. package/scripts/provision-export-redactions.ts +15 -0
  286. package/scripts/public-copy-lint.ts +122 -0
  287. package/scripts/public-export.ts +69 -2
  288. package/scripts/ratchets/next-tui-entry-budget.ts +124 -0
  289. package/scripts/ratchets/train-side-invariants.sh +7 -1
  290. package/scripts/release-loop/cut-branch.ts +61 -12
  291. package/scripts/release-loop/gate-node.ts +161 -25
  292. package/scripts/release-loop/gate-partial.ts +82 -3
  293. package/scripts/release-loop/gate-prewarm-plan.ts +35 -0
  294. package/scripts/release-loop/gate-radius-live.ts +4 -2
  295. package/scripts/release-loop/resume-cap.ts +2 -1
  296. package/scripts/release-loop/resume-release.ts +297 -8
  297. package/scripts/release-loop/resume.ts +13 -5
  298. package/scripts/release-loop/traffic-node.ts +12 -4
  299. package/scripts/release-loop/traffic-transition.ts +53 -13
  300. package/scripts/release-loop/version-node.ts +29 -4
  301. package/scripts/ux-sim.ts +1 -1
  302. package/scripts/video-pipeline.ts +2 -2
  303. package/src/acp/core-turn-bridge.ts +6 -1
  304. package/src/agent/run-context.ts +1 -1
  305. package/src/agent/task-notification.ts +3 -1
  306. package/src/agent-substrate/review-observation.ts +10 -0
  307. package/src/agent-substrate/self-review-cli.ts +195 -27
  308. package/src/auto-research/question-ladder-contract.ts +137 -0
  309. package/src/auto-research/research-turn.ts +134 -0
  310. package/src/autopilot/discovery/doc-lint.ts +1 -1
  311. package/src/bots/screen-probe.ts +1 -1
  312. package/src/capture/tui-self-report.ts +10 -2
  313. package/src/chat/index.ts +1 -0
  314. package/src/chat/tool-render/dispatch.ts +8 -1
  315. package/src/cli/guardian-cli.ts +3 -1
  316. package/src/cli/intake-cli.ts +48 -12
  317. package/src/cli/lesson-cli.ts +69 -9
  318. package/src/cli/pr-land-overlap-evidence.ts +38 -5
  319. package/src/cli/pr-land-refusal.ts +1 -1
  320. package/src/cli/pty-takeover-cli.ts +58 -5
  321. package/src/cli/release-checklist-read-cli.ts +5 -2
  322. package/src/cli/release-cli.ts +47 -9
  323. package/src/cli/review-carry.ts +77 -0
  324. package/src/cli/self-update.ts +1 -1
  325. package/src/cli/tasks-card-show.ts +31 -1
  326. package/src/cli/tasks-cli.ts +62 -23
  327. package/src/cli/tasks-read-cli.ts +13 -5
  328. package/src/context-bus/context-now.ts +86 -2
  329. package/src/core-turn/run-core-turn.ts +9 -2
  330. package/src/core-turn/types.ts +3 -0
  331. package/src/dashboard/index.ts +18 -17
  332. package/src/dashboard/input/terminal-modal-router.ts +8 -159
  333. package/src/dashboard/side-basic-runtime.ts +61 -0
  334. package/src/dashboard/slash-runtime/dashboard-handlers.ts +2 -0
  335. package/src/dashboard/term-slash-runtime.ts +2 -0
  336. package/src/dashboard/turn-preamble.ts +28 -4
  337. package/src/domains/guardian-tick.ts +9 -0
  338. package/src/git-fs/watcher.ts +27 -22
  339. package/src/git-fs/worktree.ts +19 -3
  340. package/src/graph-runner/graph-grow.ts +37 -9
  341. package/src/graph-runner/runner.ts +17 -2
  342. package/src/grok/credential.ts +107 -36
  343. package/src/hq/fence-wrapper.ts +1 -1
  344. package/src/hq/transfer.ts +1 -1
  345. package/src/index.ts +44 -14
  346. package/src/intake-plane/collect-telegram-saved.ts +54 -5
  347. package/src/interactive-terminal-modal.ts +3 -0
  348. package/src/keybindings.ts +17 -22
  349. package/src/llm/provider-credentials.ts +1 -1
  350. package/src/llm-tool-schema.ts +20 -0
  351. package/src/llm.ts +81 -11
  352. package/src/loops/orchestrator/inbox-once.ts +28 -0
  353. package/src/loops/orchestrator/inbox.ts +130 -1
  354. package/src/loops/orchestrator/tick.ts +6 -3
  355. package/src/maturity/feature-maturity.ts +1 -0
  356. package/src/nexus/api/channel-ask-op.ts +96 -0
  357. package/src/nexus/api/discord-trigger-bot.ts +28 -1
  358. package/src/nexus/api/telegram-trigger-bot.ts +24 -0
  359. package/src/nexus/api/terminals.ts +28 -6
  360. package/src/patents/ledger.ts +18 -1
  361. package/src/preview/terminal.ts +4 -2
  362. package/src/prompt-cache/anthropic.ts +2 -0
  363. package/src/prompt-enhance/enhance.ts +5 -0
  364. package/src/pty-shell/pty-manifest.ts +16 -2
  365. package/src/release-loop/gate-shards.ts +61 -0
  366. package/src/release-loop/light-rc.ts +7 -4
  367. package/src/release-loop/rehearsal.ts +1 -1
  368. package/src/repl/index.ts +10 -0
  369. package/src/research/axis-fanout.ts +133 -0
  370. package/src/research/edge-decision.ts +88 -0
  371. package/src/research/output-router.ts +127 -0
  372. package/src/research-bridge/format.ts +16 -1
  373. package/src/research-bridge/index.ts +1 -0
  374. package/src/research-bridge/invoke.ts +41 -5
  375. package/src/self-dev/decompose.ts +45 -9
  376. package/src/self-dev/draft-residue.ts +221 -2
  377. package/src/self-dev/draft-sweep.ts +29 -16
  378. package/src/self-dev/orchestrate.ts +1 -0
  379. package/src/self-dev/run-supervisor.ts +22 -7
  380. package/src/self-dev/shard-run.ts +260 -3
  381. package/src/self-implement/comment-only-source.ts +54 -0
  382. package/src/self-implement/doctor-visit.ts +25 -0
  383. package/src/self-implement/gate-artifacts.ts +2 -2
  384. package/src/self-implement/gate-baseline.ts +44 -9
  385. package/src/self-implement/gate-cli.ts +151 -86
  386. package/src/self-implement/gate-failure-signature.ts +44 -0
  387. package/src/self-implement/gate-remote.ts +2 -0
  388. package/src/self-implement/goal-author.ts +74 -3
  389. package/src/self-implement/goal-doc/section.ts +22 -0
  390. package/src/self-implement/goal-supervisor-fill.ts +38 -4
  391. package/src/self-implement/knowhow-pack.ts +120 -7
  392. package/src/self-implement/l8-merge-queue.ts +198 -32
  393. package/src/self-implement/off-diff-evidence.ts +23 -0
  394. package/src/self-implement/orchestrator.ts +55 -12
  395. package/src/self-implement/pod-inplace-worktree.ts +82 -0
  396. package/src/self-implement/pod-warm-pool-profile.ts +2 -2
  397. package/src/self-implement/premise-review.ts +7 -5
  398. package/src/self-implement/run-ledger.ts +258 -0
  399. package/src/self-implement/seams.ts +33 -10
  400. package/src/self-implement/self-implement-cli.ts +26 -2
  401. package/src/session/channel-ask-op-envelope.ts +36 -0
  402. package/src/session/channel-op-reply-route.ts +200 -0
  403. package/src/session/chat.ts +3 -0
  404. package/src/session/index.ts +2 -0
  405. package/src/session-runtime/index.ts +9 -22
  406. package/src/skills/runner.ts +7 -3
  407. package/src/skills/tools/dev-harness.ts +2 -2
  408. package/src/skills/tools/schedule-wakeup.ts +1 -6
  409. package/src/status/bar.ts +3 -3
  410. package/src/storage/file-lock.ts +17 -4
  411. package/src/task-agent/adopt-pr.ts +63 -2
  412. package/src/task-agent/evidence-command-normalize.ts +42 -0
  413. package/src/task-agent/export-redactions-provision.ts +43 -0
  414. package/src/task-agent/parent-host.ts +59 -12
  415. package/src/task-agent/repair-cycle.ts +67 -8
  416. package/src/task-agent/repair-worker.ts +37 -1
  417. package/src/task-agent/task-hand.ts +98 -10
  418. package/src/task-agent/tier-split.ts +37 -3
  419. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +31 -4
  420. package/src/task-orchestrator/surfaces/pod-pool.ts +27 -4
  421. package/src/task-orchestrator/surfaces/self-implement-pod.ts +126 -48
  422. package/src/task-orchestrator/surfaces/self-implement.ts +33 -2
  423. package/src/terminal/session-registry.ts +1 -0
  424. package/src/terminal/terminal-modal-router.ts +156 -0
  425. package/src/tool-hints/gate.ts +6 -4
  426. package/src/tool-hints/signals.ts +33 -1
  427. package/src/tui/chat/background-job-status.ts +8 -2
  428. package/src/tui/entry.ts +469 -31
  429. package/src/tui/sidetab/attach.ts +304 -0
  430. package/src/tui/sidetab/list.ts +176 -0
  431. package/src/tui/sidetab/nl-tool.ts +136 -0
  432. package/src/tui/slash/resume-command.ts +23 -0
  433. package/src/tui/slash/resume.ts +3 -23
  434. package/src/tui/slash/term-next.ts +2 -1
  435. package/src/tui-client/local-chat-turn.ts +29 -8
  436. package/src/user-config.ts +11 -2
  437. package/src/ux-sim/fake-llm.ts +11 -5
  438. package/src/ux-sim/next-tui-seat-scenarios.ts +53 -1
  439. package/src/version/packed-revision.json +1 -1
  440. package/apps/pwa/out/_next/static/chunks/1041-5841aae848fb6403.js +0 -1
  441. package/apps/pwa/out/_next/static/chunks/1087.3177e54f672dc526.js +0 -1
  442. package/apps/pwa/out/_next/static/chunks/1105.efe1e13503ac7a33.js +0 -1
  443. package/apps/pwa/out/_next/static/chunks/1417-1768233ac92f8a5d.js +0 -1
  444. package/apps/pwa/out/_next/static/chunks/1612.81bbc19af06af16c.js +0 -1
  445. package/apps/pwa/out/_next/static/chunks/1766.728d42053070bb2d.js +0 -1
  446. package/apps/pwa/out/_next/static/chunks/1773.d38e945481e04125.js +0 -1
  447. package/apps/pwa/out/_next/static/chunks/1974-c12f9600da3d3c26.js +0 -1
  448. package/apps/pwa/out/_next/static/chunks/1ed5e8af.cf424815c7c0efad.js +0 -1
  449. package/apps/pwa/out/_next/static/chunks/2061.7232dc9dc058417f.js +0 -1
  450. package/apps/pwa/out/_next/static/chunks/210.90b2cbd64926cf34.js +0 -32
  451. package/apps/pwa/out/_next/static/chunks/2318-450e75d07605b8fe.js +0 -1
  452. package/apps/pwa/out/_next/static/chunks/244-a810d282a20f1783.js +0 -1
  453. package/apps/pwa/out/_next/static/chunks/2514.03b60f266531a015.js +0 -148
  454. package/apps/pwa/out/_next/static/chunks/2526-a657538869888604.js +0 -1
  455. package/apps/pwa/out/_next/static/chunks/2533-6f0341ff075809e9.js +0 -1
  456. package/apps/pwa/out/_next/static/chunks/2676.e7994c695ef0f30d.js +0 -1
  457. package/apps/pwa/out/_next/static/chunks/2734.3ffdf54254fb6f99.js +0 -27
  458. package/apps/pwa/out/_next/static/chunks/2770-23252bf3a37880b9.js +0 -1
  459. package/apps/pwa/out/_next/static/chunks/2969.66b8b545139d1544.js +0 -1
  460. package/apps/pwa/out/_next/static/chunks/3128.a9210d08800ea6a8.js +0 -1
  461. package/apps/pwa/out/_next/static/chunks/3212.12179fd3eee8cef1.js +0 -1
  462. package/apps/pwa/out/_next/static/chunks/3578.4e9f9948a9a6f2f4.js +0 -2
  463. package/apps/pwa/out/_next/static/chunks/3760-2909ddb9279281cd.js +0 -1
  464. package/apps/pwa/out/_next/static/chunks/3825.1921b5901bf33dce.js +0 -36
  465. package/apps/pwa/out/_next/static/chunks/3994-63eb884ed0547011.js +0 -1
  466. package/apps/pwa/out/_next/static/chunks/4115.5b438b99f0ae729f.js +0 -226
  467. package/apps/pwa/out/_next/static/chunks/4269.d8f9f34bb0fc6c43.js +0 -287
  468. package/apps/pwa/out/_next/static/chunks/431-4eed5bd2c5fe1719.js +0 -1
  469. package/apps/pwa/out/_next/static/chunks/4313.76f232c304a15bde.js +0 -1
  470. package/apps/pwa/out/_next/static/chunks/4324.c99ba3e83eb1b691.js +0 -1
  471. package/apps/pwa/out/_next/static/chunks/4599-96eff3f2a9c242c1.js +0 -1
  472. package/apps/pwa/out/_next/static/chunks/4725-34bed25720cc326b.js +0 -1
  473. package/apps/pwa/out/_next/static/chunks/4825-a9d9d4e9f5892309.js +0 -1
  474. package/apps/pwa/out/_next/static/chunks/4833-7934c592c5569f00.js +0 -1
  475. package/apps/pwa/out/_next/static/chunks/4879-68518f547a207aff.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/4896.f9b70285363b27b2.js +0 -24
  477. package/apps/pwa/out/_next/static/chunks/49aa54ab.80f39398e0ed0f30.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/5056.482687319b82638e.js +0 -104
  479. package/apps/pwa/out/_next/static/chunks/506.16b83d56a437a9ee.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/5260-20593b0a25d0afbc.js +0 -1
  481. package/apps/pwa/out/_next/static/chunks/5404.cc4e9fec26fd5925.js +0 -1
  482. package/apps/pwa/out/_next/static/chunks/576.485e83e3f3dec19a.js +0 -1
  483. package/apps/pwa/out/_next/static/chunks/5832-a6be14e663f65726.js +0 -1
  484. package/apps/pwa/out/_next/static/chunks/5854-56648a9fe646b9a0.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/5925.3b1f8b135710249b.js +0 -93
  486. package/apps/pwa/out/_next/static/chunks/6168.17749aa3905fa073.js +0 -74
  487. package/apps/pwa/out/_next/static/chunks/6416.5d50b8ec9986ca98.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/6758.e7fbf532953c0783.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/6795.0cb8a59730d99703.js +0 -149
  490. package/apps/pwa/out/_next/static/chunks/6971-fb5f9dc0a2cb5d2d.js +0 -1
  491. package/apps/pwa/out/_next/static/chunks/717.522b08685979b814.js +0 -1
  492. package/apps/pwa/out/_next/static/chunks/7191.e41eb8f455c7f089.js +0 -41
  493. package/apps/pwa/out/_next/static/chunks/7233.8e744b7513119409.js +0 -1
  494. package/apps/pwa/out/_next/static/chunks/7238-97c2226f80504bd8.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/7285.307963afcf7e7660.js +0 -24
  496. package/apps/pwa/out/_next/static/chunks/7299-fbe4b8c47a87614a.js +0 -1
  497. package/apps/pwa/out/_next/static/chunks/7314.df0d95930b0c3f50.js +0 -1
  498. package/apps/pwa/out/_next/static/chunks/7406.c0589fdf2ee66629.js +0 -1
  499. package/apps/pwa/out/_next/static/chunks/752-90e3e7daad3d8e39.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/7524-bcd3d9928c6842d9.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/7549.9a4de3bf231cfc52.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/765.76ae970ceb597b5b.js +0 -1
  503. package/apps/pwa/out/_next/static/chunks/7893-e444a1b0809cd1e4.js +0 -1
  504. package/apps/pwa/out/_next/static/chunks/7956-33748cabb3a05562.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/7c5ed21f-f286708e57cf88f7.js +0 -1
  506. package/apps/pwa/out/_next/static/chunks/8030-aa66b478b53dbfca.js +0 -1
  507. package/apps/pwa/out/_next/static/chunks/8051.c88c07dacbbc5f21.js +0 -8
  508. package/apps/pwa/out/_next/static/chunks/8080-40d781e7704d3671.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/8149.80e402d4345e8dae.js +0 -77
  510. package/apps/pwa/out/_next/static/chunks/8205.50a5268f4e12ba0b.js +0 -1
  511. package/apps/pwa/out/_next/static/chunks/8231.a128feaa6f8b6079.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/85.4ddb1dda2ea3ffa2.js +0 -286
  513. package/apps/pwa/out/_next/static/chunks/8537.26517a09e8247beb.js +0 -1
  514. package/apps/pwa/out/_next/static/chunks/8595-e9b7081ab773a61f.js +0 -1
  515. package/apps/pwa/out/_next/static/chunks/8821-30cc65a61a60951f.js +0 -1
  516. package/apps/pwa/out/_next/static/chunks/8905.b3385aadb7b133e6.js +0 -79
  517. package/apps/pwa/out/_next/static/chunks/8983.246bb3a1ac38f50f.js +0 -1
  518. package/apps/pwa/out/_next/static/chunks/9072.18342f5941a1f3ec.js +0 -1
  519. package/apps/pwa/out/_next/static/chunks/9123.9df04866b2d6e00f.js +0 -1
  520. package/apps/pwa/out/_next/static/chunks/9175-7d383df15a82e2be.js +0 -1
  521. package/apps/pwa/out/_next/static/chunks/9181-bf89c07ce5b8f599.js +0 -1
  522. package/apps/pwa/out/_next/static/chunks/920-429bbc4504b45f71.js +0 -1
  523. package/apps/pwa/out/_next/static/chunks/9207.625edf45d656151c.js +0 -1
  524. package/apps/pwa/out/_next/static/chunks/9378.d2575c6ffd6dd756.js +0 -94
  525. package/apps/pwa/out/_next/static/chunks/957.db5b5c4d32a35240.js +0 -1
  526. package/apps/pwa/out/_next/static/chunks/958.53a8dcf4729e6997.js +0 -64
  527. package/apps/pwa/out/_next/static/chunks/9647.8f0cd0898c592a29.js +0 -1
  528. package/apps/pwa/out/_next/static/chunks/9665-26abb02665704c2c.js +0 -1
  529. package/apps/pwa/out/_next/static/chunks/9703.e7d81b6faef1050a.js +0 -1
  530. package/apps/pwa/out/_next/static/chunks/9882-7a9164b3c2dacbe5.js +0 -1
  531. package/apps/pwa/out/_next/static/chunks/9998.b74e033efadecd10.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c604fb980a634d88.js +0 -1
  533. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ec2d8a4979ca9075.js +0 -1
  534. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-cb6add08ad3c7660.js +0 -1
  535. package/apps/pwa/out/_next/static/chunks/app/board/page-e2eaa321ec223fe6.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/app/botlab/page-5b8a09c475b5f844.js +0 -1
  537. package/apps/pwa/out/_next/static/chunks/app/bots/page-91a77daedfbac191.js +0 -1
  538. package/apps/pwa/out/_next/static/chunks/app/ceo/page-f37fc5e974bda39b.js +0 -1
  539. package/apps/pwa/out/_next/static/chunks/app/chat/page-91429a0b78415a94.js +0 -1
  540. package/apps/pwa/out/_next/static/chunks/app/consult/page-b95798b58263b910.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/app/control/page-763d53e175e17aa1.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/app/decisions/page-d55023204055b12f.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/app/design-check/page-89d2140d78abc810.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/app/editor/page-82dc069abfe27f55.js +0 -1
  545. package/apps/pwa/out/_next/static/chunks/app/exec/page-25d9eee7beb552c0.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/app/field/page-770b4594c713ee97.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/app/healthz/route-c604fb980a634d88.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/app/inside/page-ba8e0dcae4f83985.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/app/layout-09788e1aa9a87db6.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/app/live/page-3337c6a1328c2674.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/app/live-run/page-89acd5d68c0bc560.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/app/loops/page-5c13e2c76371d797.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/app/market/page-653a9f18642825c6.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-fe986fe79b107546.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/app/morning/page-1e5da297557d2354.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/app/not-found-91ea9f5869a40943.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/app/observatory/page-7824e21b999962e2.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-53d00a60cc75a922.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e931248b3f9574b.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/app/outputs/page-443364c9e4a23b31.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/app/reflection/page-25ab9c614c14129b.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-dbcdcfac0a395a8a.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/app/sessions/page-bf1de6645089ec58.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c4201761a5e839c9.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/app/settings/page-c304f469ea5d70e4.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8e5a238cf5e50c9c.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/app/setup/layout-c604fb980a634d88.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/app/setup/page-32b526069ee50b3c.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/app/showroom/page-84220c776608cedc.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/app/tasks/page-e475618cbfd5ca2b.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/app/term/page-ac2c1e6169cfce57.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/app/today/page-fccd3020af2f8806.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/app/trace/page-9c0d7198ff7b5a91.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/app/vault/page-d54b1ec9b9c6430d.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8c4bef1791d732ca.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/app/workflows/page-46fcc0b0bbc6fbfe.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/app/workspace/page-c1c80e345fa9d6f5.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7dfda00afd172f5b.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/f21fd540.63ac75328926ed30.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/framework-77fdcc873519a6cd.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/main-app-d0d620d2ce235713.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/main-e0ef79c79337ba90.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/pages/_app-84b1bc71e3f9ce6a.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/pages/_error-2acb61f1363128cb.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/webpack-462ff5727ceb7824.js +0 -1
  586. package/scripts/migrate-monad-to-elanous.ts +0 -195
  587. package/scripts/rebrand-elanous.ts +0 -242
  588. /package/apps/pwa/out/_next/static/{8kITumG9GAZ1LwT9POrAR → RrjXTwz-urRAbChP1bX02}/_ssgManifest.js +0 -0
@@ -4,6 +4,7 @@ import { tmpdir } from 'node:os';
4
4
  import { spawnSync } from 'node:child_process';
5
5
  import { join } from 'node:path/posix';
6
6
  import { prepareDeterministicChildEnvironment } from '../../scripts/lib/deterministic-env.js';
7
+ import { audit as auditEntryBudget, entryBudgetAffected } from '../../scripts/ratchets/next-tui-entry-budget.js';
7
8
  import { withGateTestEnv } from '../../scripts/lib/gate-test-env.js';
8
9
  import { runIsolationHardcodeGate } from '../../scripts/ci-isolation-hardcode-gate.js';
9
10
  import { runModelHardcodeGate } from '../../scripts/ci-model-hardcode-gate.js';
@@ -20,6 +21,7 @@ import { getUserConfig } from '../user-config.js';
20
21
  import { debug, redactSecretText } from '../debug/log.js';
21
22
  import { buildDocumentGuardianIndex, formatDocumentGuardians } from './document-guardian-index.js';
22
23
  import { buildImporterTestIndex, importerTestsNotInRunSet, isTestPath, type ImporterTestIndex } from './importer-test-index.js';
24
+ import { isCommentOnlySourceChange } from './comment-only-source.js';
23
25
  import { buildRouteConsumerTestIndex } from './route-consumer-test-index.js';
24
26
  import { gitChangedFiles, observeGateBaselineLocation } from './seams.js';
25
27
  import {
@@ -27,7 +29,7 @@ import {
27
29
  overlapWithCurrentChanges,
28
30
  } from '../cli/pr-granularity.js';
29
31
  import { listWorktrees } from '../git-fs/worktree.js';
30
- import { runShardedGateTests, writeShardFailureEvidence, remoteShardArgv, type ShardRunProgress } from '../self-dev/shard-run.js';
32
+ import { runShardedGateTests, runShardedGateTestsAsync, writeShardFailureEvidence, remoteShardArgv, type ShardRunProgress, type ShardRunResult } from '../self-dev/shard-run.js';
31
33
  import { planGateRemoteShards, shardPlanOrchestrationId, type GateRemoteShard } from '../self-dev/shard-plan.js';
32
34
  import { parseGateScenario, readGateScenarioFile } from './gate-scenario.js';
33
35
  import { isGateSpawnLaneFile } from '../self-dev/spawn-lane-files.js';
@@ -37,6 +39,8 @@ export interface SelfGateCliOptions {
37
39
  base?: string;
38
40
  pr?: string;
39
41
  shards?: number;
42
+ /** Live shard bundle concurrency; default three, bounded to one through four. */
43
+ shardConcurrency?: number;
40
44
  /** OP FU (LAND-TRAIN-LIVE side) — opt-in with `shards`: sorted round-robin into exactly that N, no RSS pre-measurement.
41
45
  * Every other output (shardsDetail · baseline · artifacts · exit) keeps its shape; absent = measured planner unchanged. */
42
46
  fixedShardDistribution?: boolean;
@@ -103,6 +107,7 @@ interface SelfGateCliDeps {
103
107
  runBaseline?: (cwd: string, files: readonly string[], baseRef: string) => BaselineProcessResult;
104
108
  runTimeoutRecheck?: (cwd: string, file: string, name: string, timeoutMs: number) => { observation?: TimeoutRerunObservation; elapsedMs: number; output: string };
105
109
  runShards?: typeof runShardedGateTests;
110
+ runShardsAsync?: typeof runShardedGateTestsAsync;
106
111
  /** Test seam for the live progress line. */
107
112
  writeProgressStderr?: (line: string) => void;
108
113
  now?: () => number;
@@ -117,6 +122,7 @@ interface SelfGateCliDeps {
117
122
  /** iOS 순수-로직 시험 게이트 심(시험 주입용). */
118
123
  runIosGate?: (out: GateOutput) => number;
119
124
  runPwaGate?: (out: GateOutput) => number;
125
+ runEntryBudgetGate?: (cwd: string, changedFiles: readonly string[]) => { affected: boolean; errors: string[] };
120
126
  listPrWorktrees?: (cwd: string) => PrWorktreeListEntry[] | { lookupFailed: string };
121
127
  inspectWorktreeDirtiness?: (path: string) => { dirty: boolean } | { lookupFailed: string };
122
128
  /** `--artifact-dir` 전용 심 — 커밋 sha 해석(실패 = null) · 환경 키. */
@@ -675,6 +681,30 @@ function logGateCliBaseline(cwd: string, payload: GateCliBaselinePayload): void
675
681
  type GateSelectionOptions = Pick<SelfGateCliOptions, 'base' | 'pr' | 'alwaysInclude' | 'includeImporterTests' | 'scenario' | 'scenarioFile'>;
676
682
  type GateSelectionDeps = Pick<SelfGateCliDeps, 'changedFiles' | 'exists' | 'isRegularFile' | 'runCommand'>;
677
683
 
684
+ function commentOnlyChangedSources(selection: ChangedFileSelection, cwd: string, runCommand: SelfGateCliDeps['runCommand']): string[] {
685
+ const run = runCommand ?? defaultRunCommand;
686
+ // Fail closed: an unreadable base, source or Git command keeps the normal importer set.
687
+ const base = selection.baseRef === 'HEAD'
688
+ ? 'HEAD'
689
+ : (() => {
690
+ try {
691
+ const result = run('git', ['merge-base', selection.baseRef, 'HEAD'], cwd);
692
+ return result.status === 0 && !result.error ? result.stdout?.trim() : undefined;
693
+ } catch { return undefined; }
694
+ })();
695
+ if (!base) return [];
696
+ const commentOnly: string[] = [];
697
+ for (const path of selection.files) {
698
+ if (!/^(?:src|scripts)\/.+\.(?:[cm]?[jt]sx?)$/.test(path) || isTestPath(path)) continue;
699
+ try {
700
+ const prior = run('git', ['show', `${base}:${path}`], cwd);
701
+ if (prior.status !== 0 || prior.error || prior.stdout === undefined) continue;
702
+ if (isCommentOnlySourceChange(prior.stdout, readFileSync(join(cwd, path), 'utf8'), path)) commentOnly.push(path);
703
+ } catch { /* A failed comparison must retain importer coverage. */ }
704
+ }
705
+ return commentOnly;
706
+ }
707
+
678
708
  function prepareGateTestSelection(cwd: string, options: GateSelectionOptions, deps: GateSelectionDeps) {
679
709
  const selection = (deps.changedFiles ?? ((dir, input) => defaultChangedFiles(dir, input, deps.runCommand)))(cwd, options);
680
710
  const exists = deps.exists ?? ((path) => existsSync(`${cwd}/${path}`));
@@ -683,16 +713,23 @@ function prepareGateTestSelection(cwd: string, options: GateSelectionOptions, de
683
713
  const importerIndex = buildGateImporterTestIndex(options.includeImporterTests
684
714
  ? selection.files : selection.files.filter((path) => !SCRIPT_SOURCE_PATH_RE.test(path)), cwd, deps.runCommand);
685
715
  const lookupFailed = importerIndex && 'lookupFailed' in importerIndex ? importerIndex.lookupFailed : undefined;
686
- const availableIndex = importerIndex && !('lookupFailed' in importerIndex) ? importerIndex : undefined;
716
+ const originalIndex = importerIndex && !('lookupFailed' in importerIndex) ? importerIndex : undefined;
717
+ const commentOnlySources = options.includeImporterTests && originalIndex
718
+ ? commentOnlyChangedSources(selection, cwd, deps.runCommand) : [];
719
+ // testPaths is the independent full tracked-test inventory; only the changed-source
720
+ // reverse edges are filtered. Other consumers still need that complete inventory.
721
+ const availableIndex = originalIndex && commentOnlySources.length
722
+ ? { ...originalIndex, testsBySource: new Map([...originalIndex.testsBySource].filter(([source]) => !commentOnlySources.includes(source))) }
723
+ : originalIndex;
687
724
  const routeIndex = availableIndex?.testPaths
688
- ? buildRouteConsumerTestIndex(cwd, availableIndex.testPaths, selection.files, selection.baseRef) : null;
725
+ ? buildRouteConsumerTestIndex(cwd, availableIndex.testPaths, selection.files.filter((path) => !commentOnlySources.includes(path)), selection.baseRef) : null;
689
726
  const scope = resolveGateScope(selection.files, exists, availableIndex,
690
727
  { routeConsumerTestIndex: routeIndex ?? undefined });
691
- return { selection, exists, lookupFailed, availableIndex, routeIndex, scope };
728
+ return { selection, exists, lookupFailed, availableIndex, commentOnlySources, routeIndex, scope };
692
729
  }
693
730
 
694
731
  function finishGateTestSelection(prepared: ReturnType<typeof prepareGateTestSelection>, options: GateSelectionOptions, cwd: string, deps: GateSelectionDeps) {
695
- const { selection, exists, lookupFailed, availableIndex, routeIndex, scope } = prepared;
732
+ const { selection, exists, lookupFailed, availableIndex, commentOnlySources, routeIndex, scope } = prepared;
696
733
  const alwaysInclude = [...new Set((options.alwaysInclude ?? []).map(normalizeGatePath).filter(Boolean))];
697
734
  const alwaysIncludeMissing = alwaysInclude.filter((path) => !exists(path));
698
735
  const scopedTests = scope.testArgs ?? [];
@@ -720,20 +757,21 @@ function finishGateTestSelection(prepared: ReturnType<typeof prepareGateTestSele
720
757
  // RELEASE-DAILY-LIGHT-RC ② — the scope already runs importer tests as callers, but capped (GATE_CALLER_TEST_LIMIT);
721
758
  // a day of landings overflows that cap and source-only regressions went unrun (0.2.24: 20). Opt-in: every importer.
722
759
  const changedSources = selection.files.filter((path) => !isTestPath(path));
760
+ const importerSources = changedSources.filter((path) => !commentOnlySources.includes(path));
723
761
  const importerTestsAdded = options.includeImporterTests && availableIndex
724
- ? [...new Set(changedSources.flatMap((source) => availableIndex.testsBySource.get(source) ?? []))]
762
+ ? [...new Set(importerSources.flatMap((source) => availableIndex.testsBySource.get(source) ?? []))]
725
763
  .filter((path) => exists(path) && !scopedTests.includes(path) && !alwaysIncludeExtra.includes(path)).sort()
726
764
  : [];
727
765
  const defaultTests = [...scopedTests, ...alwaysIncludeExtra, ...importerTestsAdded];
728
766
  const testFiles = scenarioTests.length ? [...new Set([...defaultTests, ...scenarioTests])] : defaultTests;
729
767
  const skipTestStep = scope.skipTestStep && alwaysIncludeExtra.length === 0 && importerTestsAdded.length === 0 && scenarioTests.length === 0;
730
768
  const importerTestsNotRun = (options.includeImporterTests || scenarioTests.length > 0) && availableIndex
731
- ? importerTestsNotInRunSet(availableIndex, changedSources, testFiles) : scope.importerTestsNotRun;
769
+ ? importerTestsNotInRunSet(availableIndex, importerSources, testFiles) : scope.importerTestsNotRun;
732
770
  const unrunImporterTotal = lookupFailed ? null : (importerTestsNotRun?.total ?? 0);
733
771
  // Overflowed callers that ② ran anyway are not «not run».
734
772
  const callerTestsOverflow = scope.callerTestsOverflow.filter(({ file }) => !importerTestsAdded.includes(file) && !scenarioTests.includes(file));
735
773
  const importerLookupFailed = Boolean(lookupFailed);
736
- return { ...prepared, alwaysInclude, alwaysIncludeMissing, alwaysIncludeExtra, importerTestsAdded, scenarioTests,
774
+ return { ...prepared, alwaysInclude, alwaysIncludeMissing, alwaysIncludeExtra, importerTestsAdded, commentOnlySources, scenarioTests,
737
775
  testFiles, skipTestStep, importerTestsNotRun, unrunImporterTotal, callerTestsOverflow, importerLookupFailed };
738
776
  }
739
777
 
@@ -760,7 +798,15 @@ export function selectGateTestFiles(cwd: string, options: GateSelectionOptions =
760
798
 
761
799
  export function runSelfGateCli(cwd: string, options: SelfGateCliOptions = {}, deps: SelfGateCliDeps = {}): SelfGateCliResult {
762
800
  const capture: GateArtifactCapture = {};
763
- const result = runSelfGateCliCore(cwd, options, deps, capture);
801
+ const result = runSelfGateCliCore(cwd, options, deps, capture, false) as SelfGateCliResult;
802
+ if (options.artifactDir !== undefined) emitGateArtifacts(cwd, options.artifactDir, result, capture, deps);
803
+ return result;
804
+ }
805
+
806
+ /** Production path: shard bundles use async Bun children; all non-shard policy and timeout logic is shared. */
807
+ export async function runSelfGateCliAsync(cwd: string, options: SelfGateCliOptions = {}, deps: SelfGateCliDeps = {}): Promise<SelfGateCliResult> {
808
+ const capture: GateArtifactCapture = {};
809
+ const result = await runSelfGateCliCore(cwd, options, deps, capture, true);
764
810
  if (options.artifactDir !== undefined) emitGateArtifacts(cwd, options.artifactDir, result, capture, deps);
765
811
  return result;
766
812
  }
@@ -823,16 +869,17 @@ function shardProgressObserver(cwd: string, options: SelfGateCliOptions, deps: S
823
869
  };
824
870
  }
825
871
 
826
- function runSelfGateCliCore(cwd: string, options: SelfGateCliOptions, deps: SelfGateCliDeps, capture: GateArtifactCapture): SelfGateCliResult {
872
+ function runSelfGateCliCore(cwd: string, options: SelfGateCliOptions, deps: SelfGateCliDeps, capture: GateArtifactCapture, asyncShards: boolean): SelfGateCliResult | Promise<SelfGateCliResult> {
827
873
  if (options.base && options.pr) throw new Error('use either --base <ref> or --pr <number>, not both');
828
874
  if (options.shards !== undefined && (!Number.isSafeInteger(options.shards) || options.shards < 1)) throw new Error('invalid --shards count');
875
+ if (options.shardConcurrency !== undefined && (!Number.isSafeInteger(options.shardConcurrency) || options.shardConcurrency < 1 || options.shardConcurrency > 4)) throw new Error('invalid shard concurrency (expected 1–4)');
829
876
  if (options.fixedShardDistribution && options.shards === undefined) throw new Error('--fixed-shard-distribution requires --shards <n>');
830
877
  const prepared = prepareGateTestSelection(cwd, options, deps);
831
878
  const { selection, lookupFailed, routeIndex, scope } = prepared;
832
879
  const expose = publicExposureFiles(selection.files).length > 0
833
880
  ? runExposeGate(cwd, selection.files, getUserConfig().harness?.exposeGate === 'strict' ? 'strict' : 'warn', deps.runCommand)
834
881
  : { passed: true, log: '' };
835
- const { alwaysInclude, alwaysIncludeMissing, alwaysIncludeExtra, importerTestsAdded, scenarioTests, testFiles,
882
+ const { alwaysInclude, alwaysIncludeMissing, alwaysIncludeExtra, importerTestsAdded, commentOnlySources, scenarioTests, testFiles,
836
883
  skipTestStep, importerTestsNotRun, unrunImporterTotal, callerTestsOverflow, importerLookupFailed } = finishGateTestSelection(prepared, options, cwd, deps);
837
884
  const lines = [
838
885
  // ⛔⭐ 「changed=0」을 «초록»으로 읽는 사고가 났다(2026-09-02 · 🅕 보고 · 🅣 재현).
@@ -870,6 +917,7 @@ function runSelfGateCliCore(cwd: string, options: SelfGateCliOptions, deps: Self
870
917
  ...(options.includeImporterTests
871
918
  ? [`importer tests added: ${lookupFailed ? `lookup failed (${lookupFailed})` : `${importerTestsAdded.length} (reason=changed-source-importer${importerTestsAdded.length ? ` · ${importerTestsAdded.join(', ')}` : ''})`}`]
872
919
  : []),
920
+ ...(commentOnlySources.length ? [`comment-only importer expansion excluded: ${commentOnlySources.join(', ')}`] : []),
873
921
  ...(options.scenario !== undefined || options.scenarioFile !== undefined ? [`scenario tests: ${scenarioTests.length} (${scenarioTests.join(', ')})`] : []),
874
922
  ];
875
923
  if (expose.log) lines.push(expose.log);
@@ -896,12 +944,25 @@ function runSelfGateCliCore(cwd: string, options: SelfGateCliOptions, deps: Self
896
944
  // 🍎 iOS 축 — 안드로이드와 «같은 자리»에 둔다(skipTestStep 앞). Swift 만 바뀐 PR 도 여기서 조기 리턴한다.
897
945
  const iosPassed = runAdditionalGate('ios-gate', deps.runIosGate ?? runIosUnitTestGate, selection.files, cwd, lines);
898
946
  const pwaPassed = runAdditionalGate('pwa-gate', deps.runPwaGate ?? runPwaBuildGate, selection.files, cwd, lines);
947
+ let entryBudgetPassed = false;
948
+ try {
949
+ const budget = (deps.runEntryBudgetGate ?? ((dir, files) => {
950
+ const affected = entryBudgetAffected(files);
951
+ return { affected, errors: affected ? auditEntryBudget(dir).errors : [] };
952
+ }))(cwd, selection.files);
953
+ entryBudgetPassed = budget.errors.length === 0;
954
+ lines.push(budget.affected
955
+ ? `next-tui-entry-budget: ${entryBudgetPassed ? 'pass' : `FAIL ${budget.errors.join('; ')}`}`
956
+ : 'next-tui-entry-budget: skip (unrelated changes)');
957
+ } catch (error) {
958
+ lines.push(`next-tui-entry-budget: UNMEASURED ${error instanceof Error ? error.message : String(error)}`);
959
+ }
899
960
 
900
961
  if (skipTestStep) {
901
962
  const policyPassed = runPolicyGates(selection.files, cwd, lines, deps);
902
963
  logGateCliBaseline(cwd, { ...ZERO_GATE_BASELINE, unrunImporterTotal, lookupFailed: importerLookupFailed });
903
964
  Object.assign(capture, { verdict: 'skipped', artifactsUnavailable: 'no-tests' } satisfies GateArtifactCapture);
904
- return { exitCode: androidPassed && iosPassed && pwaPassed && policyPassed && expose.passed ? 0 : 1, lines, changedFiles: selection.files, testFiles: [], unverified: scope.unverified, documentPaths: scope.documentPaths, documentsWithoutDerivedTests: scope.documentsWithoutDerivedTests, alwaysIncludeMissing, importerTestsAdded, baseline: { introduced: 0, preexisting: 0, unknown: 0, preconditionUnmet: 0 } };
965
+ return { exitCode: androidPassed && iosPassed && pwaPassed && entryBudgetPassed && policyPassed && expose.passed ? 0 : 1, lines, changedFiles: selection.files, testFiles: [], unverified: scope.unverified, documentPaths: scope.documentPaths, documentsWithoutDerivedTests: scope.documentsWithoutDerivedTests, alwaysIncludeMissing, importerTestsAdded, baseline: { introduced: 0, preexisting: 0, unknown: 0, preconditionUnmet: 0 } };
905
966
  }
906
967
 
907
968
  // The default direct Bun path has one process and one 300s limit. Route real child/PTY tests through
@@ -909,82 +970,86 @@ function runSelfGateCliCore(cwd: string, options: SelfGateCliOptions, deps: Self
909
970
  if (options.shards !== undefined || testFiles.some(isGateSpawnLaneFile)) {
910
971
  const spawnFileCount = testFiles.filter(isGateSpawnLaneFile).length;
911
972
  const shardCount = options.shards ?? (Math.min(3, spawnFileCount) + Number(testFiles.length > spawnFileCount));
912
- const runShards = deps.runShards ?? runShardedGateTests;
913
973
  const onShardComplete = shardProgressObserver(cwd, options, deps);
914
- const sharded = options.fixedShardDistribution
915
- ? runShards(cwd, testFiles, selection.baseRef, shardCount, undefined, undefined, undefined, { fixedDistribution: true, onShardComplete })
916
- : runShards(cwd, testFiles, selection.baseRef, shardCount, undefined, undefined, undefined, { onShardComplete });
917
- capture.sharded = sharded;
918
- capture.verdict = sharded.aggregate.status;
919
- lines.push(`shards: ${sharded.shards.length} (${sharded.shards.map((shard) => `${shard.id}=${shard.files.join(',')}`).join('; ')})${sharded.expandedFrom !== undefined ? ` · RSS 예산상 ${sharded.expandedFrom}→${sharded.shards.length} 자동 확장` : ''}${sharded.measurementFailures ? ` · 측정 실패 ${sharded.measurementFailures}` : ''}${options.fixedShardDistribution ? ' · 고정 분배(사전 측정 없음)' : ''}${sharded.distribution === 'fixed-cap-fallback' ? ` · 호스트 상한 자동 고정 분배(${sharded.fallbackReason})` : ''}`);
920
- // 조각이 «못 쟀다»일 때 이유가 줄에 없으면 자리·시간 초과·죽음을 가를 수 없다(OP 10-09 light RC) — 종료 코드·신호를 같이 싣는다.
921
- const side = (code: number | null, signal: string | null | undefined, junit: string | undefined) => signal ? `signal ${signal}` : code === null ? 'exit ?' : `exit ${code}${junit === undefined ? ' · junit 없음' : ''}`;
922
- for (const attempt of sharded.attempts) {
923
- const plannedFiles = sharded.shards.find((shard) => shard.id === attempt.shardId)?.files;
924
- const baselineFiles = attempt.baselineFiles;
925
- const baselineDifference = baselineFiles && plannedFiles && (baselineFiles.length !== plannedFiles.length || baselineFiles.some((file, index) => file !== plannedFiles[index]))
926
- ? ` · 기준 파일 ${baselineFiles.join(',') || '(none)'}` : '';
927
- lines.push(`shard attempt: ${attempt.shardId} #${attempt.attempt} · 지금 ${side(attempt.currentExitCode, attempt.currentSignal, attempt.currentJUnit)} · 기준 ${side(attempt.baselineExitCode, attempt.baselineSignal, attempt.baselineJUnit)} · 파일 ${plannedFiles?.join(',') ?? '(unknown)'}${baselineDifference}`);
928
- const renderDiagnostic = (value: string): string => redactSecretText(value).replace(/[\r\n\t\x00-\x1f\x7f]+/g, ' ').slice(0, 500);
929
- if (attempt.currentJUnit === undefined && attempt.currentDiagnostic) lines.push(`shard diagnostic: ${attempt.shardId} #${attempt.attempt} 지금 · ${renderDiagnostic(attempt.currentDiagnostic)}`);
930
- if (attempt.baselineJUnit === undefined && attempt.baselineDiagnostic) lines.push(`shard diagnostic: ${attempt.shardId} #${attempt.attempt} 기준 · ${renderDiagnostic(attempt.baselineDiagnostic)}`);
931
- }
932
- // OP FU (MK #8178 shard-9) — 실패 조각의 자식 출력 꼬리 ⊕ exit/signal 을 파일로 남긴다(관측만 · 판정·exit 불변).
933
- // --artifact-dir 이 있으면 그 아래, 없으면 임시 디렉토리(JUnit 임시 디렉토리 옆 tmpdir)에.
934
- if (sharded.failureEvidence?.length) {
935
- try {
936
- const evidenceDir = options.artifactDir?.trim() ? resolveArtifactDir(options.artifactDir, cwd) : mkdtempSync(join(tmpdir(), 'elanous-shard-failure-'));
937
- for (const path of writeShardFailureEvidence(evidenceDir, sharded.failureEvidence)) lines.push(`shard failure evidence: ${path}`);
938
- } catch (error) {
939
- lines.push(`⚠ shard failure evidence: 못 썼다 — ${error instanceof Error ? error.message : String(error)} (판정은 그대로다)`);
974
+ const mode = { ...(options.fixedShardDistribution ? { fixedDistribution: true } : {}), onShardComplete,
975
+ ...(options.shardConcurrency !== undefined ? { concurrency: options.shardConcurrency } : {}) };
976
+ const runResult = asyncShards
977
+ ? (deps.runShardsAsync ?? runShardedGateTestsAsync)(cwd, testFiles, selection.baseRef, shardCount, undefined, undefined, undefined, mode)
978
+ : (deps.runShards ?? runShardedGateTests)(cwd, testFiles, selection.baseRef, shardCount, undefined, undefined, undefined, mode);
979
+ const finishShardedGate = (sharded: ShardRunResult): SelfGateCliResult => {
980
+ capture.sharded = sharded;
981
+ capture.verdict = sharded.aggregate.status;
982
+ lines.push(`shards: ${sharded.shards.length} (${sharded.shards.map((shard) => `${shard.id}=${shard.files.join(',')}`).join('; ')})${sharded.expandedFrom !== undefined ? ` · RSS 예산상 ${sharded.expandedFrom}→${sharded.shards.length} 자동 확장` : ''}${sharded.measurementFailures ? ` · 측정 실패 ${sharded.measurementFailures}` : ''}${options.fixedShardDistribution ? ' · 고정 분배(사전 측정 없음)' : ''}${sharded.distribution === 'fixed-cap-fallback' ? ` · 호스트 상한 자동 고정 분배(${sharded.fallbackReason})` : ''}${sharded.concurrency !== undefined ? ` · 동시성 ${sharded.concurrency} (${sharded.concurrencyReason ?? 'reason unavailable'})` : ''}${sharded.measurementMs !== undefined ? ` · RSS 사전 측정 ${(sharded.measurementMs / 1000).toFixed(1)}s · 묶음 ${((sharded.bundleMs ?? 0) / 1000).toFixed(1)}s · currentΣ ${((sharded.currentProcessMs ?? 0) / 1000).toFixed(1)}s · baselineΣ ${((sharded.baselineProcessMs ?? 0) / 1000).toFixed(1)}s` : ''}`);
983
+ // 조각이 «못 쟀다»일 때 이유가 줄에 없으면 자리·시간 초과·죽음을 가를 수 없다(OP 10-09 light RC) — 종료 코드·신호를 같이 싣는다.
984
+ const side = (code: number | null, signal: string | null | undefined, junit: string | undefined) => signal ? `signal ${signal}` : code === null ? 'exit ?' : `exit ${code}${junit === undefined ? ' · junit 없음' : ''}`;
985
+ for (const attempt of sharded.attempts) {
986
+ const plannedFiles = sharded.shards.find((shard) => shard.id === attempt.shardId)?.files;
987
+ const baselineFiles = attempt.baselineFiles;
988
+ const baselineDifference = baselineFiles && plannedFiles && (baselineFiles.length !== plannedFiles.length || baselineFiles.some((file, index) => file !== plannedFiles[index]))
989
+ ? ` · 기준 파일 ${baselineFiles.join(',') || '(none)'}` : '';
990
+ lines.push(`shard attempt: ${attempt.shardId} #${attempt.attempt} · 지금 ${side(attempt.currentExitCode, attempt.currentSignal, attempt.currentJUnit)} · 기준 ${side(attempt.baselineExitCode, attempt.baselineSignal, attempt.baselineJUnit)} · 파일 ${plannedFiles?.join(',') ?? '(unknown)'}${baselineDifference}`);
991
+ const renderDiagnostic = (value: string): string => redactSecretText(value).replace(/[\r\n\t\x00-\x1f\x7f]+/g, ' ').slice(0, 500);
992
+ if (attempt.currentJUnit === undefined && attempt.currentDiagnostic) lines.push(`shard diagnostic: ${attempt.shardId} #${attempt.attempt} 지금 · ${renderDiagnostic(attempt.currentDiagnostic)}`);
993
+ if (attempt.baselineJUnit === undefined && attempt.baselineDiagnostic) lines.push(`shard diagnostic: ${attempt.shardId} #${attempt.attempt} 기준 · ${renderDiagnostic(attempt.baselineDiagnostic)}`);
940
994
  }
941
- }
942
- const { aggregate } = sharded;
943
- let shardBaseline: SelfGateCliResult['baseline'];
944
- let unmeasuredReason: string | undefined;
945
- if (aggregate.status === 'unmeasured') {
946
- unmeasuredReason = sharded.reason
947
- ? redactSecretText(sharded.reason).replace(/[\r\n\t\x00-\x1f\x7f]+/g, ' ').slice(0, 500)
948
- : aggregate.retryShardIds.join(', ') || 'no complete JUnit';
949
- for (const shardId of aggregate.retryShardIds) {
950
- lines.push(`shard unmeasured: ${shardId} · ${sharded.unmeasuredByShard?.[shardId] ?? sharded.reason ?? 'cause unavailable'}`);
995
+ // OP FU (MK #8178 shard-9) — 실패 조각의 자식 출력 꼬리 ⊕ exit/signal 을 파일로 남긴다(관측만 · 판정·exit 불변).
996
+ // --artifact-dir 이 있으면 그 아래, 없으면 임시 디렉토리(JUnit 임시 디렉토리 옆 tmpdir)에.
997
+ if (sharded.failureEvidence?.length) {
998
+ try {
999
+ const evidenceDir = options.artifactDir?.trim() ? resolveArtifactDir(options.artifactDir, cwd) : mkdtempSync(join(tmpdir(), 'elanous-shard-failure-'));
1000
+ for (const path of writeShardFailureEvidence(evidenceDir, sharded.failureEvidence)) lines.push(`shard failure evidence: ${path}`);
1001
+ } catch (error) {
1002
+ lines.push(`⚠ shard failure evidence: 못 썼다 — ${error instanceof Error ? error.message : String(error)} (판정은 그대로다)`);
1003
+ }
951
1004
  }
952
- lines.push(`shards: unmeasured (${unmeasuredReason})`);
953
- if (sharded.baselineStderrTail) lines.push(`baseline worktree-add git stderr: ${sharded.baselineStderrTail}`);
954
- capture.unmeasuredReason = unmeasuredReason;
955
- }
956
- else if (aggregate.report) {
957
- const report = recheckTimeoutOnlyIntroducedFailures(cwd, aggregate.report, deps.runTimeoutRecheck);
958
- capture.timeoutRechecks = report.timeoutRechecks;
959
- const timeoutRecheckResolvedFailure = aggregate.status === 'failed'
960
- && (report.timeoutRecheckPassed ?? 0) > 0
961
- && report.introduced === 0 && report.unknown === 0 && report.preconditionUnmet === 0
962
- && report.timedOut === 0 && report.flakyRerun === 0 && report.worktreeFailuresParsed
963
- && report.baselineStatus !== 'unknown';
964
- const effectiveStatus = timeoutRecheckResolvedFailure ? 'passed' : aggregate.status;
965
- capture.verdict = effectiveStatus;
966
- logGateCliBaseline(cwd, {
967
- introduced: report.introduced, preexisting: report.preexisting, unknown: report.unknown,
968
- preconditionUnmet: report.preconditionUnmet, timedOut: report.timedOut,
969
- timeoutPassedAtBase: report.timeoutPassedAtBase, failures: report.failures.slice(0, 20),
970
- baselineFiles: report.files, baselineStatus: report.baselineStatus, unrunImporterTotal, lookupFailed: importerLookupFailed,
971
- });
972
- lines.push(formatPartialObservationNote(unrunImporterTotal ?? 0, formatGateBaselineNote(report, unrunImporterTotal ?? 0)));
973
- shardBaseline = { introduced: report.introduced, preexisting: report.preexisting, unknown: report.unknown, preconditionUnmet: report.preconditionUnmet };
974
- } else {
975
- lines.push(formatPartialObservationNote(unrunImporterTotal ?? 0, `tests: pass (${testFiles.length} files)`));
976
- logGateCliBaseline(cwd, { ...ZERO_GATE_BASELINE, unrunImporterTotal, lookupFailed: importerLookupFailed });
977
- shardBaseline = { introduced: 0, preexisting: 0, unknown: 0, preconditionUnmet: 0 };
978
- }
979
- capture.verdictLine = lines[lines.length - 1];
980
- const policyPassed = runPolicyGates(selection.files, cwd, lines, deps);
981
- return {
982
- exitCode: capture.verdict !== 'passed' || !policyPassed || !androidPassed || !iosPassed || !pwaPassed || !expose.passed ? 1 : 0,
983
- lines, changedFiles: selection.files, testFiles, unverified: scope.unverified,
984
- documentPaths: scope.documentPaths, documentsWithoutDerivedTests: scope.documentsWithoutDerivedTests,
985
- alwaysIncludeMissing, importerTestsAdded, ...(shardBaseline ? { baseline: shardBaseline } : {}),
986
- ...(unmeasuredReason !== undefined ? { unmeasuredReason } : {}),
1005
+ const { aggregate } = sharded;
1006
+ let shardBaseline: SelfGateCliResult['baseline'];
1007
+ let unmeasuredReason: string | undefined;
1008
+ if (aggregate.status === 'unmeasured') {
1009
+ unmeasuredReason = sharded.reason
1010
+ ? redactSecretText(sharded.reason).replace(/[\r\n\t\x00-\x1f\x7f]+/g, ' ').slice(0, 500)
1011
+ : aggregate.retryShardIds.join(', ') || 'no complete JUnit';
1012
+ for (const shardId of aggregate.retryShardIds) {
1013
+ lines.push(`shard unmeasured: ${shardId} · ${sharded.unmeasuredByShard?.[shardId] ?? sharded.reason ?? 'cause unavailable'}`);
1014
+ }
1015
+ lines.push(`shards: unmeasured (${unmeasuredReason})`);
1016
+ if (sharded.baselineStderrTail) lines.push(`baseline worktree-add git stderr: ${sharded.baselineStderrTail}`);
1017
+ capture.unmeasuredReason = unmeasuredReason;
1018
+ }
1019
+ else if (aggregate.report) {
1020
+ const report = recheckTimeoutOnlyIntroducedFailures(cwd, aggregate.report, deps.runTimeoutRecheck);
1021
+ capture.timeoutRechecks = report.timeoutRechecks;
1022
+ const timeoutRecheckResolvedFailure = aggregate.status === 'failed'
1023
+ && (report.loadTimeout ?? 0) > 0
1024
+ && report.introduced === 0 && report.unknown === 0 && report.preconditionUnmet === 0
1025
+ && report.timedOut === 0 && report.flakyRerun === 0 && report.worktreeFailuresParsed
1026
+ && report.baselineStatus !== 'unknown';
1027
+ const effectiveStatus = timeoutRecheckResolvedFailure ? 'passed' : aggregate.status;
1028
+ capture.verdict = effectiveStatus;
1029
+ logGateCliBaseline(cwd, {
1030
+ introduced: report.introduced, preexisting: report.preexisting, unknown: report.unknown,
1031
+ preconditionUnmet: report.preconditionUnmet, timedOut: report.timedOut,
1032
+ timeoutPassedAtBase: report.timeoutPassedAtBase, failures: report.failures.slice(0, 20),
1033
+ baselineFiles: report.files, baselineStatus: report.baselineStatus, unrunImporterTotal, lookupFailed: importerLookupFailed,
1034
+ });
1035
+ lines.push(formatPartialObservationNote(unrunImporterTotal ?? 0, formatGateBaselineNote(report, unrunImporterTotal ?? 0)));
1036
+ shardBaseline = { introduced: report.introduced, preexisting: report.preexisting, unknown: report.unknown, preconditionUnmet: report.preconditionUnmet };
1037
+ } else {
1038
+ lines.push(formatPartialObservationNote(unrunImporterTotal ?? 0, `tests: pass (${testFiles.length} files)`));
1039
+ logGateCliBaseline(cwd, { ...ZERO_GATE_BASELINE, unrunImporterTotal, lookupFailed: importerLookupFailed });
1040
+ shardBaseline = { introduced: 0, preexisting: 0, unknown: 0, preconditionUnmet: 0 };
1041
+ }
1042
+ capture.verdictLine = lines[lines.length - 1];
1043
+ const policyPassed = runPolicyGates(selection.files, cwd, lines, deps);
1044
+ return {
1045
+ exitCode: capture.verdict !== 'passed' || !policyPassed || !androidPassed || !iosPassed || !pwaPassed || !entryBudgetPassed || !expose.passed ? 1 : 0,
1046
+ lines, changedFiles: selection.files, testFiles, unverified: scope.unverified,
1047
+ documentPaths: scope.documentPaths, documentsWithoutDerivedTests: scope.documentsWithoutDerivedTests,
1048
+ alwaysIncludeMissing, importerTestsAdded, ...(shardBaseline ? { baseline: shardBaseline } : {}),
1049
+ ...(unmeasuredReason !== undefined ? { unmeasuredReason } : {}),
1050
+ };
987
1051
  };
1052
+ return runResult instanceof Promise ? runResult.then(finishShardedGate) : finishShardedGate(runResult);
988
1053
  }
989
1054
 
990
1055
  const test = (deps.runTests ?? ((dir, files) => (deps.runCommand ?? defaultRunCommand)('bun', ['test', ...files], dir)))(cwd, testFiles);
@@ -995,7 +1060,7 @@ function runSelfGateCliCore(cwd: string, options: SelfGateCliOptions, deps: Self
995
1060
  Object.assign(capture, { verdict: 'passed', verdictLine: lines[lines.length - 1] } satisfies GateArtifactCapture);
996
1061
  const policyPassed = runPolicyGates(selection.files, cwd, lines, deps);
997
1062
  logGateCliBaseline(cwd, { ...ZERO_GATE_BASELINE, unrunImporterTotal, lookupFailed: importerLookupFailed });
998
- return { exitCode: policyPassed && androidPassed && iosPassed && pwaPassed && expose.passed ? 0 : 1, lines, changedFiles: selection.files, testFiles, unverified: scope.unverified, documentPaths: scope.documentPaths, documentsWithoutDerivedTests: scope.documentsWithoutDerivedTests, alwaysIncludeMissing, importerTestsAdded, baseline: { introduced: 0, preexisting: 0, unknown: 0, preconditionUnmet: 0 } };
1063
+ return { exitCode: policyPassed && androidPassed && iosPassed && pwaPassed && entryBudgetPassed && expose.passed ? 0 : 1, lines, changedFiles: selection.files, testFiles, unverified: scope.unverified, documentPaths: scope.documentPaths, documentsWithoutDerivedTests: scope.documentsWithoutDerivedTests, alwaysIncludeMissing, importerTestsAdded, baseline: { introduced: 0, preexisting: 0, unknown: 0, preconditionUnmet: 0 } };
999
1064
  }
1000
1065
 
1001
1066
  if (worktreeLog.includes('deterministic environment setup failed')) lines.push(worktreeLog);
@@ -1021,7 +1086,7 @@ function runSelfGateCliCore(cwd: string, options: SelfGateCliOptions, deps: Self
1021
1086
  verdictLine: lines[lines.length - 1],
1022
1087
  } satisfies GateArtifactCapture);
1023
1088
  const policyPassed = runPolicyGates(selection.files, cwd, lines, deps);
1024
- const exitCode = !androidPassed || !iosPassed || !pwaPassed || !policyPassed || !expose.passed || report.introduced > 0 || report.unknown > 0 || report.preconditionUnmet > 0 ? 1 : 0;
1089
+ const exitCode = !androidPassed || !iosPassed || !pwaPassed || !entryBudgetPassed || !policyPassed || !expose.passed || report.introduced > 0 || report.unknown > 0 || report.preconditionUnmet > 0 ? 1 : 0;
1025
1090
  return { exitCode, lines, changedFiles: selection.files, testFiles, unverified: scope.unverified, documentPaths: scope.documentPaths, documentsWithoutDerivedTests: scope.documentsWithoutDerivedTests, alwaysIncludeMissing, importerTestsAdded, baseline: { introduced: report.introduced, preexisting: report.preexisting, unknown: report.unknown, preconditionUnmet: report.preconditionUnmet } };
1026
1091
  }
1027
1092
 
@@ -0,0 +1,44 @@
1
+ import { createHash } from 'node:crypto';
2
+ import type { SelfImplementGateResult } from './orchestrator.js';
3
+
4
+ export interface GateFailureReceipt {
5
+ signature: `sha256:${string}`;
6
+ tests: string[];
7
+ }
8
+
9
+ /** Only measured, introduced, non-timeout test failures are stable enough to stop a repeated repair. */
10
+ export function gateFailureReceipt(gate: SelfImplementGateResult | undefined): GateFailureReceipt | null {
11
+ if (!gate || gate.passed || gate.testStepExecuted !== true || !gate.baselineFailures
12
+ || !gate.reflectGateFacts || gate.reflectGateFacts.unknown !== 0
13
+ || (gate.reflectGateFacts.timedOut ?? 0) > 0 || (gate.reflectGateFacts.rerunNotRun ?? 0) > 0
14
+ || (gate.reflectGateFacts.mayVaryNonTimeout ?? 0) > 0) return null;
15
+ const introduced = gate.baselineFailures.filter((failure) => failure.attribution === 'introduced');
16
+ if (!introduced.length || introduced.length !== gate.reflectGateFacts.introduced) return null;
17
+ const normalized: Array<{ file: string; name: string; kind: string }> = [];
18
+ for (const failure of introduced) {
19
+ const file = failure.file?.replace(/\\/g, '/').trim();
20
+ const name = failure.name.normalize('NFC').replace(/\s+/g, ' ').trim();
21
+ if (!file || file.startsWith('/') || /^[A-Za-z]:\//.test(file) || file.split('/').includes('..')
22
+ || !name || /[\r\n]/.test(name)
23
+ || failure.timeoutRegression || /\btimed out\b|\btimeout\b/i.test(failure.diagnostic ?? '')) return null;
24
+ const diagnostic = failure.diagnostic ?? '';
25
+ const kind = /module not found|cannot find module|ERR_MODULE_NOT_FOUND/i.test(diagnostic) ? 'module-load'
26
+ : /expect\(|AssertionError|Expected:/i.test(diagnostic) ? 'assertion'
27
+ : /\berror:/i.test(diagnostic) ? 'runtime-error' : 'test-failure';
28
+ normalized.push({ file, name, kind });
29
+ }
30
+ normalized.sort((a, b) => {
31
+ const left = JSON.stringify(a);
32
+ const right = JSON.stringify(b);
33
+ return left < right ? -1 : left > right ? 1 : 0;
34
+ });
35
+ const unique = [...new Map(normalized.map((entry) => [JSON.stringify(entry), entry])).values()];
36
+ if (unique.length !== introduced.length) return null;
37
+ const signature = `sha256:${createHash('sha256').update(JSON.stringify(unique)).digest('hex')}` as const;
38
+ return { signature, tests: unique.map(({ file, name, kind }) => `${file} > ${name} (${kind})`) };
39
+ }
40
+
41
+ /** The worker reads these exact lines from harness stdout and persists the receipt. */
42
+ export function gateFailureReceiptLines(receipt: GateFailureReceipt): string[] {
43
+ return [`GATE_FAILURE_SIGNATURE=${receipt.signature}`, `GATE_FAILURE_TESTS=${JSON.stringify(receipt.tests)}`];
44
+ }
@@ -94,6 +94,7 @@ export function remoteSelfGateArgv(input: {
94
94
  changed?: boolean;
95
95
  base?: string;
96
96
  shards?: number;
97
+ shardConcurrency?: number;
97
98
  fixedShardDistribution?: boolean;
98
99
  includeImporters?: boolean;
99
100
  artifactDir?: string;
@@ -102,6 +103,7 @@ export function remoteSelfGateArgv(input: {
102
103
  return ['bun', 'bin/elanous.mjs', 'self', 'gate', '--local', ...(input.changed ? ['--changed'] : []),
103
104
  ...(input.base ? ['--base', input.base === 'origin/main' ? input.base : sha(input.base)] : []),
104
105
  ...(shards !== undefined ? ['--shards', String(shards)] : []),
106
+ ...(input.shardConcurrency !== undefined ? ['--shard-concurrency', String(input.shardConcurrency)] : []),
105
107
  ...(input.fixedShardDistribution ? ['--fixed-shard-distribution'] : []),
106
108
  ...(input.includeImporters ? ['--include-importers'] : []),
107
109
  ...(input.artifactDir ? ['--artifact-dir', input.artifactDir] : [])];
@@ -58,6 +58,8 @@ import { parseReleaseNoteSection } from '../release-loop/release-note.js';
58
58
  import { declaredNewFilePaths } from './goal-new-paths.js';
59
59
  import { classifyGoalCommandExecution, type GoalCommandExecutionResult } from './goal-command-execution.js';
60
60
  import { identityLines, repositoryIdentifiers } from './goal-author-identity.js';
61
+ import { selectRelevantAuthoringLessons } from './knowhow-pack.js';
62
+ export { selectRelevantAuthoringLessons } from './knowhow-pack.js';
61
63
  export { formatSubmittedAt } from './goal-author-identity.js';
62
64
  import { hasUnmetRequirementOutsidePreservationClause } from './goal-author-preservation-obligation.js';
63
65
  export { hasUnmetRequirementOutsidePreservationClause } from './goal-author-preservation-obligation.js';
@@ -121,6 +123,10 @@ export interface GoalAuthorDeps {
121
123
  onProgress?: (phase: GoalAuthorPhase, event: 'start' | 'end') => void;
122
124
  /** AUTHOR-TIMEBOX: budget for the `ground` phase. Omitted means `GOAL_AUTHOR_GROUND_TIMEBOX_MS`. */
123
125
  groundTimeboxMs?: number;
126
+ /** Stable IDs of bounded lessons carried as goal-head provenance. */
127
+ authoringLessonIds?: readonly string[];
128
+ /** Bounded prior lessons rendered as explicitly non-normative authoring context. */
129
+ authoringLessons?: string;
124
130
  }
125
131
 
126
132
  export type GoalAuthorGroundingPath = 'groundMissionInCodebase';
@@ -501,7 +507,7 @@ export function linesOutsideFencedCode(document: string): GoalDocSourceLine[] {
501
507
  return outside;
502
508
  }
503
509
 
504
- /** TA 완료 경계는 기존 정식 절 안의 세 독립 행이다. 원문에 없는 값을 저작기가 만들지 않는다. */
510
+ /** TA 완료 경계는 정식 절 안의 세 독립 행이다. 명시 행은 보존하고 누락 행은 태스크 넘김이 범위 기반 초안으로 보충한다. */
505
511
  export const GOAL_DONE_BOUNDARY_LABELS = ['완료 경계 코드', '완료 경계 실물', '완료 경계 증거 명령'] as const;
506
512
  export type GoalDoneBoundaryLabel = typeof GOAL_DONE_BOUNDARY_LABELS[number];
507
513
  // This is a declaration check, not a judgement of whether the proposed work
@@ -603,6 +609,39 @@ export function explicitGoalDoneBoundaryLines(ask: string): string[] {
603
609
  return GOAL_DONE_BOUNDARY_LABELS.flatMap((label) => values[label] ? [`- ${label}: ${values[label]}`] : []);
604
610
  }
605
611
 
612
+ /**
613
+ * A live hand must not silently drop a cell just because its prose omitted the three
614
+ * completion lines. Preserve explicit values and draft only the missing lines from
615
+ * declared target paths; the child can refine this visible draft against the ask.
616
+ */
617
+ export function draftMissingGoalDoneBoundary(document: string, targetPaths: readonly string[]): {
618
+ document: string;
619
+ added: GoalDoneBoundaryLabel[];
620
+ } {
621
+ const { values, missing } = inspectGoalDoneBoundary(document);
622
+ if (missing.length === 0) return { document, added: [] };
623
+
624
+ const scope = targetPaths.length > 0 ? targetPaths.join(' · ') : '요청 문면에 적힌 범위';
625
+ const explicitTests = targetPaths.filter((path) => /\.(?:test|spec)\.[cm]?[jt]sx?$/i.test(path));
626
+ const inferredTests = targetPaths.flatMap((path) => {
627
+ const match = /^(.*)\.([cm]?[jt]sx?)$/i.exec(path);
628
+ return match && !/\.(?:test|spec)$/i.test(match[1]!) ? [`${match[1]}.test.${match[2]}`] : [];
629
+ });
630
+ const evidencePaths = explicitTests.length > 0 ? explicitTests : inferredTests;
631
+ const quotePath = (path: string): string => /^[A-Za-z0-9_./:=@%+-]+$/.test(path) ? path : `'${path.replaceAll("'", `'\\''`)}'`;
632
+ const evidenceCommand = evidencePaths.length > 0
633
+ ? `bun test ${evidencePaths.map(quotePath).join(' ')}`
634
+ : 'bun test';
635
+ const drafts: Record<GoalDoneBoundaryLabel, string> = {
636
+ '완료 경계 코드': `자동 초안: ${scope}에 문면의 요청 동작을 구현하고 대상 밖의 기본 동작은 보존한다.`,
637
+ '완료 경계 실물': `자동 초안: 격리 시험에서 ${scope}의 생산 경로를 지나 요청 동작과 기존 동작을 함께 관측한다.`,
638
+ '완료 경계 증거 명령': evidenceCommand,
639
+ };
640
+ const lines = missing.map((label) => `- ${label}: ${drafts[label]}`);
641
+ const separator = document.length === 0 || document.endsWith('\n') ? '' : '\n';
642
+ return { document: `${document}${separator}${lines.join('\n')}`, added: missing };
643
+ }
644
+
606
645
  // CommonMark 펜스는 **한 종류의 문자**가 3개 이상 이어진 런이다 — `[`~]{3,}` 는 혼합(백틱+틸드)까지
607
646
  // 펜스로 인정해 진짜 진양성을 펜스 안으로 숨긴다(리뷰 must-fix). 열기/닫기 모두 이 하나를 쓴다.
608
647
  const FENCE_RUN = /^ {0,3}(`{3,}|~{3,})(.*)$/;
@@ -2908,6 +2947,21 @@ const INJECTION_LADDER: Record<InjectionLadderLevel, string> = {
2908
2947
  const VERIFICATION_MENU_DOC = join('docs', 'goal-context', '03-verification-menu.md');
2909
2948
  const MOCK_CATALOG_DOC = join('docs', 'goal-context', '04-mock-scenarios.md');
2910
2949
 
2950
+ /**
2951
+ * 새 무대의 식별자 — 카탈로그 `MS-xx` 가 없는 골도 «어느 무대인지»를 원장에 남긴다.
2952
+ *
2953
+ * ⛔ 0.2.38 실측(`GOAL-TDD-PLAN-REACHES-CHILD`): 카탈로그가 맞지 않는 골(표본 대부분)에서
2954
+ * `stage.id` 가 `null` 이었고, 그래서 `verification-plan` 이벤트의 `stageId` 칸이 비어
2955
+ * 원장만 보고는 ***「무대가 없었다」와 「무대를 안 적었다」를 가를 수 없었다.***
2956
+ * ⭐ 값은 «실제로 고른 갈래»에서 나온다 — 화면 무대(L2) · 기록된 실제 입력 fixture(L1) · 문서 문구 대조(L1).
2957
+ * ⇒ 같은 골을 두 번 저작하면 같은 id 가 나오고, 다른 갈래는 다른 id 를 갖는다.
2958
+ */
2959
+ const NEW_STAGE_IDS = {
2960
+ 'ux-sim': 'new-stage:ux-sim',
2961
+ fixture: 'new-stage:fixture',
2962
+ 'doc-phrase': 'new-stage:doc-phrase',
2963
+ } as const;
2964
+
2911
2965
  /** 저장소 안의 검증 메뉴·무대 카탈로그를 읽는다. 없으면 null(저작은 «새 무대»로 내려간다). */
2912
2966
  export function readVerificationMenuDocs(root: string | undefined): { menu: string | null; catalog: string | null } {
2913
2967
  const read = (relativePath: string): string | null => {
@@ -3064,7 +3118,7 @@ export function authorVerificationPlan(input: VerificationPlanInput): Verificati
3064
3118
  : `bun test ${testFile}`;
3065
3119
  const base = (input.targetPaths.find((path) => !/\.test\./u.test(path)) ?? testFile).split('/').pop()!.replace(/\.[^.]+$/u, '');
3066
3120
  const name = screen ? `${base} ux-sim 고정 입력` : `${base} 기록된 실제 입력 fixture`;
3067
- stage = { source: 'new-stage', id: null, level };
3121
+ stage = { source: 'new-stage', id: screen ? NEW_STAGE_IDS['ux-sim'] : NEW_STAGE_IDS.fixture, level };
3068
3122
  stageLine = `- ② 무대: 새 무대: ${name} — \`${command}\` · ${level} (${INJECTION_LADDER[level]})${input.catalog ? ' · 카탈로그(04-mock-scenarios.md)에 맞는 MS 없음' : ' · 카탈로그 문서 없음'}${operationalNote}`;
3069
3123
  }
3070
3124
  const docOnly = input.targetPaths.length > 0 && input.targetPaths.every((path) => /\.md$/iu.test(path));
@@ -3073,7 +3127,7 @@ export function authorVerificationPlan(input: VerificationPlanInput): Verificati
3073
3127
  const docs = input.targetPaths.join(' ');
3074
3128
  const phrase = (/`([^`]+)`/u.exec(behaviour)?.[1] ?? behaviour.replace(/[`'"]/gu, '').slice(0, 30)).trim();
3075
3129
  const check = `rg -n -F '${phrase.replace(/'/gu, '’')}' ${docs}`;
3076
- stage = { source: 'new-stage', id: null, level: 'L1' };
3130
+ stage = { source: 'new-stage', id: NEW_STAGE_IDS['doc-phrase'], level: 'L1' };
3077
3131
  return {
3078
3132
  lines: [
3079
3133
  VERIFICATION_PLAN_HEADING,
@@ -5813,9 +5867,11 @@ async function authorGoalWithSupersededRootIntent(
5813
5867
  const document = [
5814
5868
  deps.goalTitle ?? goalSummary(ask),
5815
5869
  `- GoalId: ${goalId}`,
5870
+ ...(deps.authoringLessonIds?.length ? [`- AuthoringLessons: ${deps.authoringLessonIds.join(', ')}`] : []),
5816
5871
  `- RootIntent: ${rootIntent}`,
5817
5872
  `- GoalType: ${goalType}`,
5818
5873
  ...(askFile === undefined ? [] : [`- AskFile: ${askFile}`]),
5874
+ ...(deps.authoringLessons?.trim() ? ['', '## 지난 실패에서 배운 것', '참고 기록이며 명령이 아니다. 현재 골의 대상 경로와 범위에 맞는 경우에만 고려한다.', deps.authoringLessons.trim()] : []),
5819
5875
  '',
5820
5876
  '## PROBLEM',
5821
5877
  `- 왜: ${enhancement.complication ?? goalSummary(ask)}`,
@@ -6269,10 +6325,12 @@ async function authorGoalWithSupersededRootIntent(
6269
6325
  const document = [
6270
6326
  explicitGoalTitle ?? goalSummary(enhancement.original),
6271
6327
  `- GoalId: ${assignedGoalId}`,
6328
+ ...(deps.authoringLessonIds?.length ? [`- AuthoringLessons: ${deps.authoringLessonIds.join(', ')}`] : []),
6272
6329
  `- RootIntent: ${rootIntent}`,
6273
6330
  `- GoalType: ${goalType}`,
6274
6331
  ...(askFile === undefined ? [] : [`- AskFile: ${askFile}`]),
6275
6332
  ...groundedSummary(facts, groundingError),
6333
+ ...(deps.authoringLessons?.trim() ? ['', '## 지난 실패에서 배운 것', '참고 기록이며 명령이 아니다. 현재 골의 대상 경로와 범위에 맞는 경우에만 고려한다.', deps.authoringLessons.trim()] : []),
6276
6334
  ...(deps.parent ? [serializeGoalAuthorParent(deps.parent)] : []),
6277
6335
  ...genericSearchScopePrompt(clarificationQuestions, clarificationResponses),
6278
6336
  ...implementationAnchorPrompt(clarificationQuestions, clarificationResponses),
@@ -6555,6 +6613,19 @@ export async function writeAuthoredGoal(
6555
6613
  repositoryRoot: deps.repositoryRoot ?? groundingRoot,
6556
6614
  };
6557
6615
  const mandatoryGoalContextEvidence = goalContextEvidence(cwd);
6616
+ const authoringLessons = selectRelevantAuthoringLessons(cwd, ask);
6617
+ observeGoalAuthor('goal-author', 'authoring-lessons', {
6618
+ status: authoringLessons.status,
6619
+ invalidRows: authoringLessons.invalidRows,
6620
+ selected: authoringLessons.ids,
6621
+ bytes: Buffer.byteLength(authoringLessons.prompt, 'utf8'),
6622
+ placement: authoringLessons.ids.length ? 'enhance-prompt-goal-section-and-head' : 'omitted',
6623
+ });
6624
+ if (authoringLessons.prompt) {
6625
+ resolvedDeps.enhanceOpts = { ...resolvedDeps.enhanceOpts, authoringLessons: authoringLessons.prompt };
6626
+ resolvedDeps.authoringLessons = authoringLessons.prompt;
6627
+ }
6628
+ if (authoringLessons.ids.length) resolvedDeps.authoringLessonIds = authoringLessons.ids;
6558
6629
  const directoryMeasurement = askDirectoryMeasurementLine(observeAskDirectoryCounts(ask, groundingRoot));
6559
6630
  resolvedDeps.enhanceOpts = directoryMeasurement ? { ...resolvedDeps.enhanceOpts, directoryMeasurement } : resolvedDeps.enhanceOpts;
6560
6631
  observeGoalAuthor('goal-author', 'ask-directory-measurement-forwarded', { count: directoryMeasurement ? 1 : 0 });