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
@@ -10,6 +10,28 @@ export interface GoalDocSourceLine {
10
10
  readonly start: number;
11
11
  }
12
12
 
13
+ /** Parse the command on a goal's authored decision-signal Condition line. */
14
+ function authoredSignalCommandFromCondition(condition: string | undefined): string | undefined {
15
+ if (!condition?.trim()) return undefined;
16
+ return condition.trim()
17
+ .replace(/^`([^`]+)`(?=\s|를|$)/, '$1')
18
+ .replace(/\s*를\s*실행한다[.。]?$/, '')
19
+ .replace(/[.。]$/, '')
20
+ .trim();
21
+ }
22
+
23
+ export function authoredSignalCommandFromBody(value: string): string | undefined {
24
+ return authoredSignalCommandFromCondition(value.match(/^\s*- Condition:\s*(.+?)\s*$/m)?.[1]);
25
+ }
26
+
27
+ export function authoredSignalCommandFromGoal(goal: string): string | undefined {
28
+ const lines = goal.split(/\r?\n/);
29
+ const start = lines.findIndex((line) => line.trim() === '## 판정 신호');
30
+ if (start < 0) return undefined;
31
+ const next = lines.findIndex((line, index) => index > start && /^##\s/.test(line));
32
+ return authoredSignalCommandFromBody(lines.slice(start + 1, next < 0 ? lines.length : next).join('\n'));
33
+ }
34
+
13
35
  type GoalDocSectionOptions =
14
36
  | {
15
37
  readonly search: 'exact-trimmed-line';
@@ -1,7 +1,7 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import { readFileSync, renameSync, writeFileSync } from 'node:fs';
3
3
  import { dirname, join } from 'node:path';
4
- import { extractGoalDocSections } from './goal-doc/section.js';
4
+ import { authoredSignalCommandFromBody, extractGoalDocSections } from './goal-doc/section.js';
5
5
 
6
6
  export interface SupervisorGoalFillEvidence {
7
7
  round: number;
@@ -13,6 +13,7 @@ export interface SupervisorGoalFillEvidence {
13
13
  baselineLine?: string;
14
14
  /** ⭐ **원천 그대로** — 독립 검사기가 writer 의 파싱 결과가 아니라 **로그를 직접** 다시 읽는다. */
15
15
  gateLog: string;
16
+ authoredSignal?: { command: string; exitCode: number | null; stdout: string; stderr: string };
16
17
  }
17
18
 
18
19
  export interface SupervisorGoalFillInput {
@@ -20,6 +21,7 @@ export interface SupervisorGoalFillInput {
20
21
  round: number;
21
22
  gate: { passed: boolean; log?: string; testStepExecuted?: boolean; scopeReason?: string };
22
23
  review?: { verdict: 'pass' | 'warn' | 'fail' };
24
+ authoredSignal?: SupervisorGoalFillEvidence['authoredSignal'];
23
25
  /** An external checker, deliberately separate from this writer/parser. */
24
26
  independentlyCheck: (document: string, evidence: SupervisorGoalFillEvidence) => Promise<boolean>;
25
27
  wiring?: 'wired' | 'unwired';
@@ -34,6 +36,8 @@ export interface SupervisorGoalDeficit {
34
36
  gateLog?: string;
35
37
  /** Decision branch, without gate log or goal text. */
36
38
  reason?: 'missing-section' | 'missing-invariant-slot' | 'missing-signal-slot' | 'gate-evidence-unverified' | 'review-unavailable' | 'goal-unwired' | 'slot-format' | 'authored-signal-command-mismatch' | 'independent-check-failed';
39
+ /** Safe, bounded detail for a decision branch (for example, the authored test files absent from the measured command). */
40
+ reasonDetail?: string;
37
41
  inputSummary?: { gatePassed: boolean; hasGateLog: boolean; hasReview: boolean; invariantSlot: boolean; signalSlot: boolean };
38
42
  gateLogRef?: string;
39
43
  }
@@ -85,6 +89,15 @@ function section(document: string, heading: string): { start: number; end: numbe
85
89
  })[0];
86
90
  }
87
91
 
92
+ /** Accept only explicit Bun test-file lists; never interpret shell syntax or options as file coverage. */
93
+ function testFiles(command: string): string[] | undefined {
94
+ const match = command.trim().match(/^bun\s+test\s+(.+)$/);
95
+ if (!match) return undefined;
96
+ const files = match[1].trim().split(/\s+/);
97
+ if (!files.length || files.some((file) => !/^[A-Za-z0-9_./-]+\.test\.(?:ts|tsx|js|jsx|mjs|cjs)$/.test(file))) return undefined;
98
+ return [...new Set(files)];
99
+ }
100
+
88
101
  /**
89
102
  * ⛔ **두 절은 서로 다른 것을 말한다** — 같은 문자열을 양쪽에 넣으면 무엇도 검증하지 않는다(리뷰 must-fix).
90
103
  * `불변식` = 이 골이 **지켜야 할 조건** · `판정 신호` = 그것을 **어떻게 관측하나**.
@@ -95,6 +108,10 @@ function invariantReplacement(evidence: SupervisorGoalFillEvidence): string {
95
108
  }
96
109
 
97
110
  function signalReplacement(evidence: SupervisorGoalFillEvidence): string {
111
+ if (evidence.authoredSignal) {
112
+ const output = `${evidence.authoredSignal.stdout}\n${evidence.authoredSignal.stderr}`.trim().slice(-1200) || '(출력 없음)';
113
+ return `- filled-by: supervisor@round-${evidence.round}\n 관측 — \`${evidence.authoredSignal.command}\` 실행 결과\n 이번 라운드 관측값 — exit ${evidence.authoredSignal.exitCode}\n 원문 출력 — ${output.replace(/\r?\n/g, ' ⏎ ')}\n gate 검증 — ${evidence.command} · fail ${evidence.observedFail} · ${evidence.baselineLine ?? 'baseline not run (test PASS)'}\n 근거 — authored signal command executed in this run · review ${evidence.reviewVerdict}`;
114
+ }
98
115
  return `- filled-by: supervisor@round-${evidence.round}\n 관측 — \`${evidence.command}\` 요약 줄의 fail 수\n 이번 라운드 관측값 — fail ${evidence.observedFail}\n 근거 — round-${evidence.round} review ${evidence.reviewVerdict} · ${evidence.baselineLine ?? 'baseline not run (test PASS)'}`;
99
116
  }
100
117
 
@@ -146,9 +163,25 @@ export async function fillUnverifiableGoalSlots(input: SupervisorGoalFillInput):
146
163
  if (input.wiring === 'unwired') { deficit('goal-unwired'); return 'unverifiable'; }
147
164
  // The authored completion signal must name the test we actually measured.
148
165
  if (!signalSlot) {
149
- const authoredCommand = signals.body.match(/^\s*- Condition:\s*(bun test\s+[^\r\n]+?)(?:\s+를 실행한다)?\s*$/m)?.[1]?.trim();
150
- if (!authoredCommand || authoredCommand !== gateEvidence.command) {
151
- deficit('authored-signal-command-mismatch'); return 'unverifiable';
166
+ const authoredCommand = authoredSignalCommandFromBody(signals.body);
167
+ const authoredFiles = authoredCommand ? testFiles(authoredCommand) : undefined;
168
+ const measuredFiles = testFiles(gateEvidence.command);
169
+ const missingFiles = authoredFiles && measuredFiles ? authoredFiles.filter((file) => !measuredFiles.includes(file)) : [];
170
+ const signalRun = input.authoredSignal;
171
+ const signalMeasured = authoredCommand && signalRun?.command === authoredCommand && signalRun.exitCode === 0;
172
+ if (!signalMeasured) {
173
+ const observation: SupervisorGoalDeficit = {
174
+ evidenceId: createHash('sha256').update(JSON.stringify([input.path, input.round, original])).digest('hex').slice(0, 16),
175
+ kind: 'unverified', previousEvidence: original, round: input.round,
176
+ ...(input.gate.log !== undefined ? { gateLog: input.gate.log } : {}),
177
+ reason: 'authored-signal-command-mismatch',
178
+ reasonDetail: missingFiles.length ? `authored test file(s) absent from passing gate command: ${missingFiles.join(', ')}`
179
+ : 'authored command has no matching successful execution evidence',
180
+ inputSummary: { gatePassed: input.gate.passed, hasGateLog: Boolean(input.gate.log), hasReview: Boolean(input.review), invariantSlot, signalSlot },
181
+ ...(input.gate.log ? { gateLogRef: `sha256:${createHash('sha256').update(input.gate.log).digest('hex').slice(0, 16)}` } : {}),
182
+ };
183
+ input.observeDeficit?.(observation);
184
+ return 'unverifiable';
152
185
  }
153
186
  }
154
187
 
@@ -159,6 +192,7 @@ export async function fillUnverifiableGoalSlots(input: SupervisorGoalFillInput):
159
192
  observedFail: gateEvidence.observedFail,
160
193
  ...(gateEvidence.baselineLine ? { baselineLine: gateEvidence.baselineLine } : {}),
161
194
  gateLog: input.gate.log ?? '',
195
+ ...(input.authoredSignal ? { authoredSignal: input.authoredSignal } : {}),
162
196
  };
163
197
  const invariantBody = replaceUnverifiableSlot(invariant.body, invariantReplacement(evidence));
164
198
  const signalBody = signalSlot ? replaceUnverifiableSlot(signals.body, signalReplacement(evidence))
@@ -1,5 +1,6 @@
1
1
  /** Bounded, read-only context from promoted repository knowhow. */
2
2
  import { lstatSync, readFileSync, realpathSync, readdirSync, statSync } from 'node:fs';
3
+ import { createHash } from 'node:crypto';
3
4
  import { join, relative, resolve, sep } from 'node:path';
4
5
 
5
6
  export const KNOWHOW_PACK_MAX_BYTES = 4096;
@@ -10,6 +11,109 @@ export interface KnowhowPack {
10
11
  text: string;
11
12
  ids: string[];
12
13
  bytes: number;
14
+ reason: 'selected' | 'marker-present' | 'source-unreadable' | 'no-promoted-section' | 'no-path-overlap' | 'over-budget';
15
+ }
16
+
17
+ export interface SelectedAuthoringLessons {
18
+ readonly ids: readonly string[];
19
+ readonly prompt: string;
20
+ readonly status: 'loaded' | 'missing' | 'malformed' | 'unreadable' | 'empty';
21
+ readonly invalidRows: number;
22
+ }
23
+
24
+ const AUTHORING_LESSONS_MAX_BYTES = 2_000;
25
+ const AUTHORING_LESSONS_MAX_ITEMS = 2;
26
+ const AUTHORING_LESSON_CLASSES = new Set([
27
+ 'a-missing-predecessor', 'b-stale-path', 'c-unbounded-goal', 'd-rigid-acceptance',
28
+ 'e-format-trap', 'f-unaware-of-code', 'g-umbrella-scope', 'env-provider',
29
+ 'env-capacity', 'env-stale-image',
30
+ ]);
31
+
32
+ function authoringLessonClassHints(ask: string, targetPaths: readonly string[]): Set<string> {
33
+ const hints = new Set<string>();
34
+ const rules: readonly [string, RegExp][] = [
35
+ ['a-missing-predecessor', /predecessor|prerequisite|depends on|dependency|선행|의존|먼저 완료/iu],
36
+ ['b-stale-path', /unsupported path|missing path|path does not exist|not exist|경로.{0,12}(?:없|존재하지)|없는 파일|대상 경로.{0,12}없/iu],
37
+ ['c-unbounded-goal', /unbounded|no scope boundary|scope is unclear|범위.{0,12}(?:무한|불명확|제한 없|경계 없)/iu],
38
+ ['d-rigid-acceptance', /acceptance criteria|acceptance test|검수 기준|수용 기준|판정 조건/iu],
39
+ ['e-format-trap', /format|schema|json|template|형식|스키마|문면/iu],
40
+ ['f-unaware-of-code', /already implemented|existing code|cli registration|entry point|이미 구현|기존 코드|등록 파일|진입점/iu],
41
+ ['g-umbrella-scope', /umbrella|over.?scope|too broad|too many targets|여러 목표|범위가 넓|너무 넓|한 골에|포괄 골/iu],
42
+ ['env-provider', /provider|model|llm|모델|프로바이더/iu],
43
+ ['env-capacity', /capacity|resource|oom|용량|부하|자원/iu],
44
+ ['env-stale-image', /stale image|image mismatch|오래된 이미지|이미지 불일치/iu],
45
+ ];
46
+ for (const [lessonClass, pattern] of rules) if (pattern.test(ask)) hints.add(lessonClass);
47
+ if (targetPaths.length > 5) hints.add('g-umbrella-scope');
48
+ return hints;
49
+ }
50
+
51
+ function authoringAskPaths(ask: string): string[] {
52
+ const paths = new Set<string>();
53
+ for (const match of ask.matchAll(/(?<![\w./~-])([\w.-]+(?:\/[\w.-]+)+)/gu)) {
54
+ const path = match[1].replace(/[.,;:!?]+$/u, '');
55
+ const parts = path.split('/');
56
+ if (parts.some((part) => !part || part === '.' || part === '..')) continue;
57
+ if (/\.[\w-]+$/u.test(parts.at(-1) ?? '')) paths.add(path);
58
+ }
59
+ return [...paths];
60
+ }
61
+
62
+ /** Select up to two relevant lessons, capped by rendered prompt size. Bad optional ledgers only emit observation. */
63
+ export function selectRelevantAuthoringLessons(root: string, ask: string): SelectedAuthoringLessons {
64
+ const path = join(root, 'docs', 'goal-context', '05-authoring-lessons.jsonl');
65
+ let source: string;
66
+ try { source = readFileSync(path, 'utf8'); }
67
+ catch (error) {
68
+ return { ids: [], prompt: '', status: (error as NodeJS.ErrnoException).code === 'ENOENT' ? 'missing' : 'unreadable', invalidRows: 0 };
69
+ }
70
+ const rows: Record<string, unknown>[] = [];
71
+ let invalidRows = 0;
72
+ for (const line of source.split(/\r?\n/u)) {
73
+ if (!line.trim()) continue;
74
+ try {
75
+ const value: unknown = JSON.parse(line);
76
+ if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('not an object');
77
+ const row = value as Record<string, unknown>;
78
+ if (typeof row.lesson !== 'string' || typeof row.class !== 'string') throw new Error('missing lesson/class');
79
+ // The canonical ledger predates the closed class vocabulary and contains three `other` rows.
80
+ // Ignore those rows individually so valid lessons remain usable; never inject an unknown class.
81
+ if (!AUTHORING_LESSON_CLASSES.has(row.class) && !/^env-[a-z0-9-]+$/u.test(row.class)) { invalidRows += 1; continue; }
82
+ rows.push(row);
83
+ } catch {
84
+ invalidRows += 1;
85
+ return { ids: [], prompt: '', status: 'malformed', invalidRows };
86
+ }
87
+ }
88
+ if (rows.length === 0) return { ids: [], prompt: '', status: 'empty', invalidRows };
89
+ const targetPaths = authoringAskPaths(ask);
90
+ const classHints = authoringLessonClassHints(ask, targetPaths);
91
+ const ranked = rows.map((row, index) => {
92
+ const lessonPaths = typeof row.paths === 'string' ? row.paths.split(/\s*[·,]\s*/u).filter(Boolean) : [];
93
+ const pathMatches = lessonPaths.some((lessonPath) => targetPaths.some((target) =>
94
+ target === lessonPath || target.startsWith(`${lessonPath}/`) || lessonPath.startsWith(`${target}/`)));
95
+ const classMatch = classHints.has(String(row.class));
96
+ const score = (pathMatches ? 4 : 0) + (classMatch ? 2 : 0);
97
+ const lesson = String(row.lesson).trim().replace(/\s+/gu, ' ');
98
+ const cell = typeof row.cell === 'string' ? row.cell.trim() : '';
99
+ const run = typeof row.run === 'string' && row.run.trim() ? row.run.trim() : '';
100
+ const suppliedId = typeof row.id === 'string' && /^[A-Za-z0-9._:-]{1,80}$/u.test(row.id) ? row.id : undefined;
101
+ const digest = createHash('sha256').update(JSON.stringify([row.ts ?? '', row.cell ?? '', row.class, row.lesson, row.paths ?? ''])).digest('hex').slice(0, 10);
102
+ const id = suppliedId ?? `AL-${digest}`;
103
+ const detail = [cell && `칸=${cell}`, `class=${row.class}`, `lesson=${lesson}`, run && `run=${run}`].filter(Boolean).join(' · ');
104
+ return { id, detail, score, index, timestamp: typeof row.ts === 'string' ? row.ts : '' };
105
+ }).filter((row) => row.score > 0)
106
+ .sort((left, right) => right.score - left.score || right.timestamp.localeCompare(left.timestamp) || left.index - right.index);
107
+ const selected: { id: string; detail: string }[] = [];
108
+ for (const candidate of ranked) {
109
+ if (selected.length >= AUTHORING_LESSONS_MAX_ITEMS) break;
110
+ const line = `- [${candidate.id}] ${candidate.detail}`;
111
+ const next = [...selected.map((entry) => `- [${entry.id}] ${entry.detail}`), line].join('\n');
112
+ if (Buffer.byteLength(next, 'utf8') > AUTHORING_LESSONS_MAX_BYTES) continue;
113
+ selected.push({ id: candidate.id, detail: candidate.detail });
114
+ }
115
+ const prompt = selected.map((entry) => `- [${entry.id}] ${entry.detail}`).join('\n');
116
+ return { ids: selected.map((entry) => entry.id), prompt, status: 'loaded', invalidRows };
13
117
  }
14
118
 
15
119
  function inside(root: string, path: string): boolean {
@@ -60,16 +164,19 @@ function relevance(goal: string, section: string, targetPaths?: readonly string[
60
164
 
61
165
  /** Reads only 내부 문서 `KNOWHOW` inside the supplied repository. Verified target paths narrow relevance when supplied. */
62
166
  export function selectKnowhowPack(repo: string, goal: string, targetPaths?: readonly string[]): KnowhowPack {
63
- if (goal.includes(MARKER)) return { text: '', ids: [], bytes: 0 };
167
+ const empty = (reason: KnowhowPack['reason']): KnowhowPack => ({ text: '', ids: [], bytes: 0, reason });
168
+ if (goal.includes(MARKER)) return empty('marker-present');
64
169
  const rolesDir = resolve(repo, 'docs/roles');
65
170
  let realRoles: string;
66
171
  try {
67
172
  realRoles = realpathSync(rolesDir);
68
- if (!inside(realpathSync(repo), realRoles)) return { text: '', ids: [], bytes: 0 };
69
- } catch { return { text: '', ids: [], bytes: 0 }; }
173
+ if (!inside(realpathSync(repo), realRoles)) return empty('source-unreadable');
174
+ } catch { return empty('source-unreadable'); }
70
175
  const candidates: Array<{ id: string; text: string; score: number }> = [];
71
176
  let seatDirs: string[];
72
- try { seatDirs = readdirSync(rolesDir).sort(); } catch { return { text: '', ids: [], bytes: 0 }; }
177
+ try { seatDirs = readdirSync(rolesDir).sort(); } catch { return empty('source-unreadable'); }
178
+ let readableFiles = 0;
179
+ let promotedCount = 0;
73
180
  for (const seat of seatDirs) {
74
181
  if (!/^[A-Z]{2,4}$/.test(seat)) continue;
75
182
  const file = join(rolesDir, seat, 'KNOWHOW.md');
@@ -77,12 +184,18 @@ export function selectKnowhowPack(repo: string, goal: string, targetPaths?: read
77
184
  if (lstatSync(file).isSymbolicLink()) continue;
78
185
  const real = realpathSync(file);
79
186
  if (!inside(realRoles, real) || !statSync(real).isFile() || statSync(real).size > 2_000_000) continue;
80
- for (const section of promotedSections(readFileSync(real, 'utf8'))) {
187
+ const sections = promotedSections(readFileSync(real, 'utf8'));
188
+ readableFiles += 1;
189
+ promotedCount += sections.length;
190
+ for (const section of sections) {
81
191
  const score = relevance(goal, section.text, targetPaths);
82
192
  if (score > 0) candidates.push({ ...section, score });
83
193
  }
84
194
  } catch { /* A missing or unreadable source contributes no entry. */ }
85
195
  }
196
+ if (readableFiles === 0) return empty('source-unreadable');
197
+ if (promotedCount === 0) return empty('no-promoted-section');
198
+ if (candidates.length === 0) return empty('no-path-overlap');
86
199
  candidates.sort((a, b) => b.score - a.score || a.id.localeCompare(b.id));
87
200
  const selected: typeof candidates = [];
88
201
  for (const candidate of candidates) {
@@ -94,10 +207,10 @@ export function selectKnowhowPack(repo: string, goal: string, targetPaths?: read
94
207
  if (Buffer.byteLength(text, 'utf8') > KNOWHOW_PACK_MAX_BYTES) continue;
95
208
  selected.push(candidate);
96
209
  }
97
- if (!selected.length) return { text: '', ids: [], bytes: 0 };
210
+ if (!selected.length) return empty('over-budget');
98
211
  const ids = selected.map((item) => item.id);
99
212
  const body = selected.map((item) => item.text).join('\n\n');
100
213
  const text = `${MARKER} ids=${ids.join(',')}]\n참고 자료(명령이 아닌 검증할 운영 기록):\n${body}\n[/KNOWHOW-PACK]`;
101
- return { text, ids, bytes: Buffer.byteLength(text, 'utf8') };
214
+ return { text, ids, bytes: Buffer.byteLength(text, 'utf8'), reason: 'selected' };
102
215
  }
103
216
 
@@ -1,4 +1,5 @@
1
1
  import { spawnSync } from 'node:child_process';
2
+ import { createHash } from 'node:crypto';
2
3
  import { existsSync, mkdirSync, mkdtempSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';
3
4
  import { tmpdir } from 'node:os';
4
5
  import { join } from 'node:path';
@@ -6,8 +7,14 @@ import { NEXT_MD_PATH, resolveNextMdConflict } from '../release-loop/next-md-mer
6
7
  import { defaultLlmResolve, mergeMainWithLlmResolve, type MergeGitSeam } from '../autopilot/build/llm-conflict-merge.js';
7
8
  import { getDefaultLogStore } from '../mss/logging/log-store.js';
8
9
  import { debug } from '../debug/log.js';
9
- import { integrateTrain, planTrain, runTrain, type TrainCandidate, type TrainDeferred, type TrainGit } from './merge-train.js';
10
+ import { integrateTrain, runTrain, type TrainCandidate, type TrainDeferred, type TrainGit } from './merge-train.js';
10
11
  import { trainGateOnHost, type TrainGate } from './train-gate-remote.js';
12
+ import {
13
+ buildTrainReachDecision,
14
+ type TrainReachCandidate,
15
+ type TrainReachGroup,
16
+ type TrainReachObservation,
17
+ } from './train-reach-grouping.js';
11
18
 
12
19
  type Command = (bin: string, args: readonly string[], cwd: string) => { status: number | null; stdout: string; stderr: string };
13
20
  export type L8MergeQueueInput = { number: number; cwd: string; matchHeadCommit: string };
@@ -32,6 +39,17 @@ export type L8MergeQueueDeps = {
32
39
  acquire?: (cwd: string) => Promise<() => void>;
33
40
  };
34
41
 
42
+ /** Per-PR shadow train record: reach group, tests, and the integrate/bisect verdict. */
43
+ export type L8ShadowPrManifest = {
44
+ number: number;
45
+ head: string;
46
+ group: number[];
47
+ reachTests: string[];
48
+ interactionTests: string[];
49
+ queueSig: string;
50
+ gatesRun: number;
51
+ verdict: L8ShadowVerdict['verdict'];
52
+ };
35
53
  export type L8ShadowVerdict = {
36
54
  number: number;
37
55
  head: string;
@@ -41,6 +59,8 @@ export type L8ShadowVerdict = {
41
59
  detail?: string;
42
60
  tests: string[];
43
61
  at: string;
62
+ /** Present when this verdict came from a reach-grouped shadow train. */
63
+ manifest?: L8ShadowPrManifest;
44
64
  };
45
65
  export type L8ShadowQueueItem = {
46
66
  number: number;
@@ -50,7 +70,9 @@ export type L8ShadowQueueItem = {
50
70
  overlapsWith?: number[];
51
71
  overlapsUnknownWith?: number[];
52
72
  };
53
- export type L8ShadowQueueState = { pending: L8ShadowQueueItem[]; verdicts: L8ShadowVerdict[] };
73
+ /** Reach precheck outcome for a queued PR this run could not pin (stale view, changed head, or worktree failure). */
74
+ export type L8ShadowDeferred = { number: number; head: string; reason: string; at: string };
75
+ export type L8ShadowQueueState = { pending: L8ShadowQueueItem[]; verdicts: L8ShadowVerdict[]; deferred?: L8ShadowDeferred[] };
54
76
  export type L8ShadowEnqueueObservation = {
55
77
  number: number;
56
78
  head: string;
@@ -68,8 +90,10 @@ export type L8ShadowQueueDeps = L8MergeQueueDeps & {
68
90
  trainGate?: (repo: string, baseSha: string) => TrainGate;
69
91
  /** Shadow merge train integration git seam (default: the queue's own command executor). */
70
92
  trainGit?: TrainGit;
71
- /** Maximum PRs per shadow train batch (default 2). */
93
+ /** Maximum PRs per shadow train batch (default 5, the reach-group capacity). */
72
94
  trainMaxBatch?: number;
95
+ /** Reach observation seam (default: inspect each fetched PR worktree via buildTrainReachDecision). */
96
+ trainReachInspect?: (candidate: TrainReachCandidate, baseSha: string) => TrainReachObservation;
73
97
  };
74
98
 
75
99
  function shadowCommand(execute: Command, bin: string, args: string[], cwd: string): string {
@@ -89,7 +113,8 @@ function readShadowQueue(path: string): L8ShadowQueueState {
89
113
  const value: unknown = JSON.parse(readFileSync(path, 'utf8'));
90
114
  if (!value || typeof value !== 'object' || !('pending' in value) || !Array.isArray(value.pending)
91
115
  || !value.pending.every((p: { number?: number; head?: string }) => Number.isSafeInteger(p?.number) && p.number! > 0 && typeof p.head === 'string' && /^[0-9a-f]{40}$/i.test(p.head))
92
- || !('verdicts' in value) || !Array.isArray(value.verdicts)) throw new Error('invalid shadow queue ledger');
116
+ || !('verdicts' in value) || !Array.isArray(value.verdicts)
117
+ || !('deferred' in value ? Array.isArray(value.deferred) : true)) throw new Error('invalid shadow queue ledger');
93
118
  return value as L8ShadowQueueState;
94
119
  }
95
120
 
@@ -180,10 +205,94 @@ export async function enqueueL8ShadowQueue(cwd: string, number: number, deps: L8
180
205
  });
181
206
  }
182
207
 
183
- /** LAND-QUEUE — shadow merge train: planTrain → integrateTrain → runTrain(trainGateOnHost) when the queue holds
184
- * two or more measured, non-overlapping PRs. Per-PR verdicts (pass · culprit · unmeasured) land in the queue
185
- * ledger and in debug.log ('self-implement.merge-train' · 'shadow-verdict'). Shadow only: no push, no merge API;
186
- * the single-PR evaluation path in runL8ShadowQueue stays untouched for every queue this train cannot take. */
208
+ function shadowQueueSig(base: string, pending: readonly L8ShadowQueueItem[]): string {
209
+ return createHash('sha256').update(`${base}\0${pending.map((item) => `${item.number}:${item.head}`).join('\0')}`).digest('hex');
210
+ }
211
+
212
+ function shadowReachWorktree(cwd: string, run: (bin: string, args: string[], where?: string) => string, item: L8ShadowQueueItem, base: string): string {
213
+ const tree = mkdtempSync(join(tmpdir(), `elanous-l8-reach-${item.number}-`));
214
+ try {
215
+ run('git', ['worktree', 'add', '--detach', tree, item.head], cwd);
216
+ if (run('git', ['rev-parse', 'HEAD'], tree) !== item.head) throw new Error(`reach worktree HEAD changed: #${item.number}`);
217
+ run('git', ['cat-file', '-e', `${base}^{commit}`], tree);
218
+ return tree;
219
+ } catch (error) {
220
+ try { run('git', ['worktree', 'remove', '--force', tree], cwd); } catch { /* still delete the directory */ }
221
+ rmSync(tree, { recursive: true, force: true });
222
+ throw error;
223
+ }
224
+ }
225
+
226
+ function pinShadowReachCandidates(
227
+ cwd: string,
228
+ run: (bin: string, args: string[], where?: string) => string,
229
+ pending: readonly L8ShadowQueueItem[],
230
+ base: string,
231
+ skip: ReadonlySet<number>,
232
+ ): { candidates: TrainReachCandidate[]; trees: string[]; failures: { number: number; head: string; reason: string }[] } {
233
+ const candidates: TrainReachCandidate[] = [];
234
+ const trees: string[] = [];
235
+ const failures: { number: number; head: string; reason: string }[] = [];
236
+ for (const item of pending) {
237
+ if (skip.has(item.number) || item.filesUnmeasured || !item.files?.length) continue;
238
+ try {
239
+ const tree = shadowReachWorktree(cwd, run, item, base);
240
+ trees.push(tree);
241
+ candidates.push({ pr: String(item.number), headSha: item.head, tree, changedFiles: [...item.files] });
242
+ } catch (error) {
243
+ // shadowReachWorktree cleans up its own tree; this PR only leaves the reach candidate set.
244
+ failures.push({ number: item.number, head: item.head, reason: String(error) });
245
+ }
246
+ }
247
+ return { candidates, trees, failures };
248
+ }
249
+
250
+ /** Keep one deferred record per queued PR (latest reason wins) so the ledger stays bounded. */
251
+ function recordShadowDeferred(state: L8ShadowQueueState, entries: readonly L8ShadowDeferred[]): void {
252
+ const rest = (state.deferred ?? []).filter((entry) => !entries.some((current) => current.number === entry.number));
253
+ state.deferred = [...rest, ...entries];
254
+ }
255
+
256
+ function planShadowReachTrain(
257
+ pending: readonly L8ShadowQueueItem[],
258
+ group: TrainReachGroup,
259
+ { maxBatch }: { maxBatch: number },
260
+ ): { batch: TrainCandidate[]; deferred: TrainDeferred[] } {
261
+ const byNumber = new Map(pending.map((item) => [item.number, item]));
262
+ const numbers = group.prs.map((pr) => Number(pr)).filter((number) => byNumber.has(number));
263
+ const batch: TrainCandidate[] = [];
264
+ const deferred: TrainDeferred[] = [];
265
+ for (const number of numbers) {
266
+ const item = byNumber.get(number)!;
267
+ const candidate: TrainCandidate = { number: item.number, head: item.head, files: item.files, filesUnmeasured: item.filesUnmeasured };
268
+ if (batch.length < maxBatch) batch.push(candidate);
269
+ else deferred.push({ number, reason: 'overlap', with: batch.map((entry) => entry.number) });
270
+ }
271
+ return { batch, deferred };
272
+ }
273
+
274
+ function shadowPrManifest(
275
+ item: TrainCandidate,
276
+ group: TrainReachGroup,
277
+ queueSig: string,
278
+ gatesRun: number,
279
+ verdict: L8ShadowVerdict['verdict'],
280
+ ): L8ShadowPrManifest {
281
+ return {
282
+ number: item.number,
283
+ head: item.head,
284
+ group: group.prs.map((pr) => Number(pr)),
285
+ reachTests: [...group.reachTests],
286
+ interactionTests: [...group.interactionTests],
287
+ queueSig,
288
+ gatesRun,
289
+ verdict,
290
+ };
291
+ }
292
+
293
+ /** LAND-QUEUE — shadow merge train: pinned queue → buildTrainReachDecision → integrateTrain → runTrain.
294
+ * Per-PR verdicts (pass · culprit · unmeasured) land in the queue ledger with a reach-group manifest.
295
+ * Shadow only: no push, no merge API; the single-PR evaluation path stays for every queue this train cannot take. */
187
296
  async function runShadowMergeTrain(
188
297
  state: L8ShadowQueueState,
189
298
  path: string,
@@ -191,6 +300,9 @@ async function runShadowMergeTrain(
191
300
  run: (bin: string, args: string[], where?: string) => string,
192
301
  execute: Command,
193
302
  plan: { batch: TrainCandidate[]; deferred: TrainDeferred[] },
303
+ group: TrainReachGroup,
304
+ queueSig: string,
305
+ base: string,
194
306
  deps: L8ShadowQueueDeps,
195
307
  ): Promise<L8ShadowVerdict | null> {
196
308
  for (const item of plan.batch) {
@@ -200,9 +312,6 @@ async function runShadowMergeTrain(
200
312
  if (view.headRefOid !== item.head || view.baseRefName !== 'main' || view.state !== 'OPEN'
201
313
  || view.isDraft !== false || view.isCrossRepository !== false) throw new Error(`queued PR #${item.number} changed or is not ready`);
202
314
  }
203
- run('git', ['fetch', 'origin', 'refs/heads/main'], cwd);
204
- const base = run('git', ['rev-parse', 'FETCH_HEAD'], cwd);
205
- if (!/^[0-9a-f]{40}$/i.test(base)) throw new Error('main commit unavailable');
206
315
  for (const item of plan.batch) {
207
316
  run('git', ['fetch', 'origin', `refs/pull/${item.number}/head`], cwd);
208
317
  if (run('git', ['rev-parse', 'FETCH_HEAD'], cwd) !== item.head) throw new Error(`fetched PR head changed: #${item.number}`);
@@ -213,49 +322,106 @@ async function runShadowMergeTrain(
213
322
  integrate: (batch) => integrateTrain(cwd, base, batch, trainGit),
214
323
  gate,
215
324
  deferred: plan.deferred,
216
- // The train's observation channel is debug.log (LAND-QUEUE); the ledger below carries the authoritative state.
217
325
  observe: (data) => { debug.log('self-implement.merge-train', 'shadow-verdict', data); },
218
326
  });
219
327
  const at = new Date().toISOString();
220
328
  const batchNumbers = plan.batch.map((item) => item.number);
221
- const verdicts: L8ShadowVerdict[] = result.verdicts.map((entry) => ({
222
- number: entry.number,
223
- head: plan.batch.find((item) => item.number === entry.number)!.head,
224
- base,
225
- verdict: entry.verdict,
226
- detail: `merge train shadow · batch [${batchNumbers.join(',')}] · gatesRun ${result.gatesRun}`,
227
- tests: [],
228
- at,
229
- }));
329
+ const verdicts: L8ShadowVerdict[] = result.verdicts.map((entry) => {
330
+ const item = plan.batch.find((candidate) => candidate.number === entry.number)!;
331
+ const manifest = shadowPrManifest(item, group, queueSig, result.gatesRun, entry.verdict);
332
+ return {
333
+ number: entry.number,
334
+ head: item.head,
335
+ base,
336
+ verdict: entry.verdict,
337
+ detail: `merge train shadow · reach [${group.prs.join(',')}] · batch [${batchNumbers.join(',')}] · gatesRun ${result.gatesRun}`,
338
+ tests: [...group.reachTests],
339
+ at,
340
+ manifest,
341
+ };
342
+ });
230
343
  state.pending = state.pending.filter((item) => !batchNumbers.includes(item.number));
231
344
  state.verdicts.push(...verdicts);
232
345
  writeShadowQueue(path, state);
233
346
  return verdicts[0] ?? null;
234
347
  }
235
348
 
236
- /** Evaluate one pinned queue head against freshly fetched main — or, when the queue holds two or more measured,
237
- * non-overlapping PRs, one shadow merge train. Never push or call a merge API. */
349
+ /** Evaluate one pinned queue head against freshly fetched main — or, when reach grouping finds a measured
350
+ * two-or-more-PR component, one shadow merge train. Never push or call a merge API. */
238
351
  export async function runL8ShadowQueue(cwd: string, deps: L8ShadowQueueDeps = {}): Promise<L8ShadowVerdict | null> {
239
352
  return withShadowQueue(cwd, deps, async (state, path) => {
240
353
  const item = state.pending[0];
241
354
  if (!item) return null;
242
355
  const execute = deps.command ?? command;
243
356
  const run = (bin: string, args: string[], where = cwd) => shadowCommand(execute, bin, args, where);
244
- // LAND-QUEUE — two or more measured, non-overlapping queued PRs evaluate as one shadow merge train first.
245
- const trainPlan = planTrain(
246
- state.pending.map((pending) => ({ number: pending.number, head: pending.head, files: pending.files, filesUnmeasured: pending.filesUnmeasured })),
247
- { maxBatch: deps.trainMaxBatch ?? 2 },
248
- );
249
- if (trainPlan.batch.length >= 2) return runShadowMergeTrain(state, path, cwd, run, execute, trainPlan, deps);
357
+ run('git', ['fetch', 'origin', 'refs/heads/main']);
358
+ const base = run('git', ['rev-parse', 'FETCH_HEAD']);
359
+ if (!/^[0-9a-f]{40}$/i.test(base)) throw new Error('main commit unavailable');
360
+ const queueSig = shadowQueueSig(base, state.pending);
361
+ let trees: string[] = [];
362
+ // Preservation contract: a reach failure on any non-head queued PR defers only that PR; the queue head keeps
363
+ // both its shadow-train chance and the single-PR evaluation path. Only the head's own failure throws.
364
+ const reachDeferred: L8ShadowDeferred[] = [];
365
+ const reachSkip = new Set<number>();
366
+ try {
367
+ for (const pending of state.pending) {
368
+ if (pending.filesUnmeasured || !pending.files?.length) continue;
369
+ const isHead = pending === item;
370
+ try {
371
+ const view = JSON.parse(run('gh', ['pr', 'view', String(pending.number), '--json', 'headRefOid,baseRefName,state,isDraft,isCrossRepository'])) as {
372
+ headRefOid?: string; baseRefName?: string; state?: string; isDraft?: boolean; isCrossRepository?: boolean;
373
+ };
374
+ if (view.headRefOid !== pending.head || view.baseRefName !== 'main' || view.state !== 'OPEN'
375
+ || view.isDraft !== false || view.isCrossRepository !== false) {
376
+ throw new Error(`queued PR #${pending.number} changed or is not ready`);
377
+ }
378
+ run('git', ['fetch', 'origin', `refs/pull/${pending.number}/head`]);
379
+ if (run('git', ['rev-parse', 'FETCH_HEAD']) !== pending.head) {
380
+ throw new Error(`fetched PR head changed: #${pending.number}`);
381
+ }
382
+ } catch (error) {
383
+ if (isHead) throw error;
384
+ reachDeferred.push({ number: pending.number, head: pending.head, reason: String(error), at: new Date().toISOString() });
385
+ reachSkip.add(pending.number);
386
+ }
387
+ }
388
+ const pinned = pinShadowReachCandidates(cwd, run, state.pending, base, reachSkip);
389
+ trees = pinned.trees;
390
+ for (const failure of pinned.failures) {
391
+ const reason = `reach worktree failed: #${failure.number}: ${failure.reason}`;
392
+ if (failure.number === item.number) throw new Error(reason);
393
+ reachDeferred.push({ number: failure.number, head: failure.head, reason, at: new Date().toISOString() });
394
+ }
395
+ if (reachDeferred.length) {
396
+ recordShadowDeferred(state, reachDeferred);
397
+ writeShadowQueue(path, state);
398
+ }
399
+ if (pinned.candidates.length >= 2) {
400
+ const decision = buildTrainReachDecision(
401
+ { version: 1, baseSha: base, queueSig, prs: pinned.candidates },
402
+ deps.trainReachInspect,
403
+ );
404
+ const group = decision.groups.find((entry) => entry.status === 'measured' && !entry.capacityBlocked && entry.prs.length >= 2
405
+ && entry.prs.includes(String(item.number)));
406
+ if (group) {
407
+ const trainPlan = planShadowReachTrain(state.pending, group, { maxBatch: deps.trainMaxBatch ?? 5 });
408
+ if (trainPlan.batch.length >= 2) {
409
+ return await runShadowMergeTrain(state, path, cwd, run, execute, trainPlan, group, queueSig, base, deps);
410
+ }
411
+ }
412
+ }
413
+ } finally {
414
+ for (const tree of trees) {
415
+ try { run('git', ['worktree', 'remove', '--force', tree]); } catch { /* still delete the directory */ }
416
+ rmSync(tree, { recursive: true, force: true });
417
+ }
418
+ }
250
419
  const verdict: L8ShadowVerdict = { number: item.number, head: item.head, verdict: 'fail', tests: [], at: new Date().toISOString() };
251
420
  const view = JSON.parse(run('gh', ['pr', 'view', String(item.number), '--json', 'headRefOid,baseRefName,state,isDraft,isCrossRepository'])) as {
252
421
  headRefOid?: string; baseRefName?: string; state?: string; isDraft?: boolean; isCrossRepository?: boolean;
253
422
  };
254
423
  if (view.headRefOid !== item.head || view.baseRefName !== 'main' || view.state !== 'OPEN'
255
424
  || view.isDraft !== false || view.isCrossRepository !== false) throw new Error('queued PR changed or is not ready');
256
- run('git', ['fetch', 'origin', 'refs/heads/main']);
257
- const base = run('git', ['rev-parse', 'FETCH_HEAD']);
258
- if (!/^[0-9a-f]{40}$/i.test(base)) throw new Error('main commit unavailable');
259
425
  verdict.base = base;
260
426
  run('git', ['fetch', 'origin', `refs/pull/${item.number}/head`]);
261
427
  if (run('git', ['rev-parse', 'FETCH_HEAD']) !== item.head) throw new Error('fetched PR head changed');