elanous 0.2.29 → 0.2.31

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 (709) 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/{cIpv5nU9AycwYWZI9H589 → LSXfY0u9QtfDbejY0Ukf_}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{058a98ba.7eb28d5e6dc03565.js → 0bb0ff36.b8d418980951e5ba.js} +7 -7
  5. package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +27 -0
  8. package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +287 -0
  9. package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +62 -0
  10. package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/{6013-2f769370d8b4c2c6.js → 1335-6731f392c35216eb.js} +3 -3
  12. package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/{8332.6f0f49df772e163b.js → 1654.32de4b324981a188.js} +1 -1
  15. package/apps/pwa/out/_next/static/chunks/1834-50625904996a8fa8.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +149 -0
  17. package/apps/pwa/out/_next/static/chunks/{8795.32573a185af18c7b.js → 1913.7cc6fb6055b1ed3f.js} +2 -2
  18. package/apps/pwa/out/_next/static/chunks/{419.736c0d6f426249a7.js → 2001.6c7e0fd02190886c.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/{6767.1fcfc9b8be83975f.js → 2213.2ccbada92c33ea0f.js} +16 -16
  24. package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/{4759.1f76713aefb87db5.js → 2871.0bca6137343b3f76.js} +1 -1
  28. package/apps/pwa/out/_next/static/chunks/{6776.06ff1e3b464cc607.js → 2898.fd781bc7cf01a7b7.js} +1 -1
  29. package/apps/pwa/out/_next/static/chunks/{1782-59db1b5aa06df38a.js → 2940-619bfd8ef337c611.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/{8471.8d2a8c74f09c36ff.js → 2985.39ccdecd36848b12.js} +4 -4
  31. package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +115 -0
  32. package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +64 -0
  33. package/apps/pwa/out/_next/static/chunks/{bc324b7c.02a09dd93f6a399b.js → 3267c0e6.d34854e7b3984a6e.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/3278.2e5d15b53a4091c8.js +2 -0
  35. package/apps/pwa/out/_next/static/chunks/{7725-4f83d5541fbdb81b.js → 3541-ce3a5424ed5ad7f1.js} +1 -1
  36. package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3902.e1e71aaac850a045.js +34 -0
  39. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/{46bd8bea.2f4b4099172fcdb7.js → 409f1e57.d0649fc47691ebfe.js} +1 -1
  41. package/apps/pwa/out/_next/static/chunks/4111.2bfedbb233ad206b.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/{1142.65d002789ab3af7d.js → 4174.92ed04922709ac9e.js} +2 -2
  43. package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +36 -0
  45. package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +286 -0
  49. package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +77 -0
  50. package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +226 -0
  51. package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +79 -0
  53. package/apps/pwa/out/_next/static/chunks/5173-233188df2f42c626.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +148 -0
  57. package/apps/pwa/out/_next/static/chunks/5307.60f2209e809bd627.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/{3396-97b97928c49190c9.js → 5458-16cd7a2b51b74c8c.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/{3403.7199205e65124486.js → 5525.86debf231e181813.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{9143.ff14585db1d275ff.js → 5543.a438b8ab5a13ea47.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +74 -0
  65. package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +94 -0
  67. package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/{8398.73a19b39715eda04.js → 6092.a7f99e68b188ca66.js} +1 -1
  70. package/apps/pwa/out/_next/static/chunks/60fb96c9.360b01d8d4927b7b.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/{5591.a35e7a217734a8b9.js → 6157.0c9af021de4fb31b.js} +2 -2
  72. package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/{7375.050ea0d72968e49f.js → 6433.fc573af22bbc9ab7.js} +17 -17
  75. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +90 -0
  77. package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +32 -0
  78. package/apps/pwa/out/_next/static/chunks/6544cb48.a87fe20ddf137be2.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +104 -0
  80. package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +24 -0
  85. package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +93 -0
  86. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/{1852.7f7b53991fcb99ef.js → 7502.ccd5b8065545edd0.js} +2 -2
  93. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +8 -0
  94. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{6534.1ab00f370db7b105.js → 7862.30a8d6482bb238eb.js} +1 -1
  96. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/{285adb1a.5654e605dddf86d2.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
  99. package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/8097-92f87bd108322f66.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +24 -0
  109. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{1516.dfaceff3fd2d0e0d.js → 9138.b6e80031afb1d973.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/{9907.49be0fcadaf214b5.js → 9221.7d22eaf353a2d4e7.js} +1 -1
  113. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/{8767-2f6a634f5abeaa01.js → 9279-d28c5b7754d010ae.js} +1 -1
  115. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +1 -0
  116. package/apps/pwa/out/_next/static/chunks/{3160-95c96f4d2a21dd26.js → 9398-6aed28f0a96d0d6f.js} +1 -1
  117. package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/{328bb3ab-6628a1114fe3fb3b.js → 997ce8a5-2ad501927003b41b.js} +1 -1
  121. package/apps/pwa/out/_next/static/chunks/{6853.cc5174a9dee59593.js → 9989.3694300e5f000b14.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-bf3634a117322df7.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-3535a4a69f1fafaa.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-b9f51447f757fbf2.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/{page-a5635eba0d73b84e.js → page-2ebb8fd59b9461f9.js} +1 -1
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-a2fc4e49a4fa4ba8.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-5a503541353e60a8.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-6025101384e361a5.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-f4b630cc8b5273cd.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-a645f00a06483e9a.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-61ac22cbab1ee4ec.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-e9bab7413b028b28.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-c992eafe028b642e.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-e547e6ce55f1fb33.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-d27e1b9850fd54bf.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-805ac2e137b7a121.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-0fec29c7ba01894b.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-339a07410cd6f36b.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-349f2752d8cd37ad.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-d5c6dcf31c25cecc.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-2fd93ed8c9f16580.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-9b564dbff0fefc35.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-62f4475d3c38fb9b.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-814ba51385225776.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-397d479626e5a459.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-af1bba4e3251b728.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-3ad3be5e7d3fdce9.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-f219ccdbc0bf27df.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4da93ad35d4a8d28.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-456666766e5ce6fc.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-7404e377e8adb8c5.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-14456240ed2a36ad.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-3a658d5fa6d16a25.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-0157de6e85f8bb6b.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-0a07363b130182a1.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-841d73d4ac44ed49.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6f43a3d1146e6377.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/{page-29900ed0011b2c83.js → page-521ee23ac8c0abfa.js} +1 -1
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-a9992ee285efaa83.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-3d48e85fa89ec04f.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d2ced71132fac9b2.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-f08358bdf251adb9.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-233c71cd5f68f0d7.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-70151d78de2f375e.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-dcac33a3e2cb72c0.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/{page-9f92737b8766009a.js → page-149dc1caba411bb9.js} +1 -1
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-0448145ccd5c45c1.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-9cb0c444903da65d.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-17e504c396e0e389.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{425cfc4d.fb91158e3971c39f.js → b313b242.cb1265eea908db61.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +122 -0
  175. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
  176. package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +1 -0
  183. package/apps/pwa/out/_next/static/css/{72becfd42807b50d.css → 3f5fc6f96e2cf7b2.css} +1 -1
  184. package/apps/pwa/out/approvals/index.html +1 -1
  185. package/apps/pwa/out/approvals/index.txt +23 -23
  186. package/apps/pwa/out/autopilot/index.html +1 -1
  187. package/apps/pwa/out/autopilot/index.txt +23 -23
  188. package/apps/pwa/out/board/index.html +1 -1
  189. package/apps/pwa/out/board/index.txt +23 -23
  190. package/apps/pwa/out/botlab/index.html +1 -1
  191. package/apps/pwa/out/botlab/index.txt +22 -22
  192. package/apps/pwa/out/bots/index.html +1 -1
  193. package/apps/pwa/out/bots/index.txt +22 -22
  194. package/apps/pwa/out/ceo/index.html +1 -1
  195. package/apps/pwa/out/ceo/index.txt +23 -23
  196. package/apps/pwa/out/chat/index.html +1 -1
  197. package/apps/pwa/out/chat/index.txt +22 -22
  198. package/apps/pwa/out/consult/index.html +1 -1
  199. package/apps/pwa/out/consult/index.txt +23 -23
  200. package/apps/pwa/out/control/index.html +1 -1
  201. package/apps/pwa/out/control/index.txt +23 -23
  202. package/apps/pwa/out/decisions/index.html +1 -1
  203. package/apps/pwa/out/decisions/index.txt +22 -22
  204. package/apps/pwa/out/design-check/index.html +1 -1
  205. package/apps/pwa/out/design-check/index.txt +23 -23
  206. package/apps/pwa/out/editor/index.html +1 -1
  207. package/apps/pwa/out/editor/index.txt +23 -23
  208. package/apps/pwa/out/exec/index.html +1 -1
  209. package/apps/pwa/out/exec/index.txt +23 -23
  210. package/apps/pwa/out/field/index.html +1 -1
  211. package/apps/pwa/out/field/index.txt +23 -23
  212. package/apps/pwa/out/healthz +1 -1
  213. package/apps/pwa/out/index.html +1 -1
  214. package/apps/pwa/out/index.txt +22 -22
  215. package/apps/pwa/out/inside/index.html +1 -1
  216. package/apps/pwa/out/inside/index.txt +22 -22
  217. package/apps/pwa/out/intake/index.html +1 -1
  218. package/apps/pwa/out/intake/index.txt +23 -23
  219. package/apps/pwa/out/live/index.html +1 -1
  220. package/apps/pwa/out/live/index.txt +23 -23
  221. package/apps/pwa/out/live-run/index.html +1 -1
  222. package/apps/pwa/out/live-run/index.txt +23 -23
  223. package/apps/pwa/out/loops/index.html +1 -1
  224. package/apps/pwa/out/loops/index.txt +22 -22
  225. package/apps/pwa/out/market/index.html +1 -1
  226. package/apps/pwa/out/market/index.txt +22 -22
  227. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  228. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  229. package/apps/pwa/out/morning/index.html +1 -1
  230. package/apps/pwa/out/morning/index.txt +23 -23
  231. package/apps/pwa/out/observatory/index.html +1 -1
  232. package/apps/pwa/out/observatory/index.txt +23 -23
  233. package/apps/pwa/out/ops/checklist/index.html +1 -1
  234. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  235. package/apps/pwa/out/ops/release/index.html +1 -1
  236. package/apps/pwa/out/ops/release/index.txt +22 -22
  237. package/apps/pwa/out/ops/seats/index.html +1 -1
  238. package/apps/pwa/out/ops/seats/index.txt +22 -22
  239. package/apps/pwa/out/outputs/index.html +1 -1
  240. package/apps/pwa/out/outputs/index.txt +22 -22
  241. package/apps/pwa/out/reflection/index.html +1 -1
  242. package/apps/pwa/out/reflection/index.txt +23 -23
  243. package/apps/pwa/out/scheduler/index.html +1 -1
  244. package/apps/pwa/out/scheduler/index.txt +23 -23
  245. package/apps/pwa/out/sessions/index.html +1 -1
  246. package/apps/pwa/out/sessions/index.txt +22 -22
  247. package/apps/pwa/out/settings/devices/index.html +1 -1
  248. package/apps/pwa/out/settings/devices/index.txt +23 -23
  249. package/apps/pwa/out/settings/index.html +1 -1
  250. package/apps/pwa/out/settings/index.txt +23 -23
  251. package/apps/pwa/out/setup/done/index.html +1 -1
  252. package/apps/pwa/out/setup/done/index.txt +23 -23
  253. package/apps/pwa/out/setup/index.html +1 -1
  254. package/apps/pwa/out/setup/index.txt +23 -23
  255. package/apps/pwa/out/share/index.html +1 -1
  256. package/apps/pwa/out/share/index.txt +23 -23
  257. package/apps/pwa/out/showroom/index.html +1 -1
  258. package/apps/pwa/out/showroom/index.txt +22 -22
  259. package/apps/pwa/out/tasks/index.html +1 -1
  260. package/apps/pwa/out/tasks/index.txt +23 -23
  261. package/apps/pwa/out/term/index.html +1 -1
  262. package/apps/pwa/out/term/index.txt +23 -23
  263. package/apps/pwa/out/today/index.html +1 -1
  264. package/apps/pwa/out/today/index.txt +23 -23
  265. package/apps/pwa/out/trace/index.html +1 -1
  266. package/apps/pwa/out/trace/index.txt +23 -23
  267. package/apps/pwa/out/vault/index.html +1 -1
  268. package/apps/pwa/out/vault/index.txt +23 -23
  269. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  270. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  271. package/apps/pwa/out/workflows/index.html +1 -1
  272. package/apps/pwa/out/workflows/index.txt +23 -23
  273. package/apps/pwa/out/workspace/index.html +1 -1
  274. package/apps/pwa/out/workspace/index.txt +23 -23
  275. package/apps/pwa/out/worktrees/index.html +1 -1
  276. package/apps/pwa/out/worktrees/index.txt +23 -23
  277. package/bin/elanous.mjs +7 -3
  278. package/graphs/context/nightly-condense.yaml +1 -0
  279. package/graphs/intake/intake-daily.yaml +8 -1
  280. package/graphs/intake/recipes.yaml +5 -0
  281. package/graphs/lecture/lecture-note.yaml +2 -2
  282. package/graphs/ops/harness-gc.yaml +1 -0
  283. package/graphs/release/recipes.yaml +3 -0
  284. package/graphs/release/release-loop.yaml +9 -5
  285. package/graphs/units/recipes.yaml +3 -0
  286. package/graphs/units/release-gate-recheck.yaml +15 -0
  287. package/package.json +2 -1
  288. package/scripts/check-native-tool-wiring.ts +3 -2
  289. package/scripts/ci-android-unit-tests.ts +16 -0
  290. package/scripts/ci-typecheck-changed.ts +37 -9
  291. package/scripts/coord-channel-watch.sh +22 -16
  292. package/scripts/coord-role-pack.ts +81 -2
  293. package/scripts/cron-run.ts +96 -3
  294. package/scripts/detect-test-interference.ts +38 -5
  295. package/scripts/gate-pr-cache.ts +65 -0
  296. package/scripts/gh-surface/capture.ts +126 -0
  297. package/scripts/gh-surface/gh +40 -0
  298. package/scripts/import-graph-scc.ts +38 -0
  299. package/scripts/install.ps1 +19 -0
  300. package/scripts/intake-social.ts +181 -0
  301. package/scripts/lecture-note/node.ts +71 -4
  302. package/scripts/lib/android-toolchain.ts +32 -0
  303. package/scripts/lib/deterministic-env.ts +62 -0
  304. package/scripts/lib/gate-test-env.ts +19 -0
  305. package/scripts/measure-goal-grounding-corpus.ts +2 -1
  306. package/scripts/ratchets/test-interference-patterns.allowlist.txt +257 -0
  307. package/scripts/ratchets/test-interference-patterns.ts +367 -0
  308. package/scripts/release-loop/cut-branch.ts +4 -3
  309. package/scripts/release-loop/export-check-node.ts +0 -1
  310. package/scripts/release-loop/fixtures/warm-failure-assertion/sample.junit.xml +8 -0
  311. package/scripts/release-loop/fixtures/warm-job-029/sample.json +1 -0
  312. package/scripts/release-loop/fixtures/warm-job-029/sample.junit.xml +10 -0
  313. package/scripts/release-loop/gate-closure.ts +12 -8
  314. package/scripts/release-loop/gate-diff.ts +1 -1
  315. package/scripts/release-loop/gate-host-mirror.ts +66 -0
  316. package/scripts/release-loop/gate-node.ts +523 -75
  317. package/scripts/release-loop/gate-partial.ts +106 -9
  318. package/scripts/release-loop/gate-pr-cache.ts +66 -0
  319. package/scripts/release-loop/gate-prewarm-plan.ts +66 -0
  320. package/scripts/release-loop/gate-r2-verdict.ts +189 -0
  321. package/scripts/release-loop/gate-recheck-plan-node.ts +52 -0
  322. package/scripts/release-loop/gate-warm-artifacts.ts +253 -0
  323. package/scripts/release-loop/import-graph-scc-run.ts +54 -0
  324. package/scripts/release-loop/import-graph-scc.ts +215 -0
  325. package/scripts/release-loop/node-verdict.ts +2 -0
  326. package/scripts/release-loop/probe-pod-host-dirs-live.ts +113 -0
  327. package/scripts/release-loop/resume-release.ts +33 -4
  328. package/scripts/release-loop/resume.ts +13 -5
  329. package/scripts/release-loop/spawn-lane.ts +2 -19
  330. package/scripts/release-loop/tui-sim-node.ts +3 -2
  331. package/scripts/release-loop/unattended-release.ts +16 -0
  332. package/scripts/test-deterministic.ts +5 -61
  333. package/scripts/train-reach-grouping.ts +48 -0
  334. package/scripts/tsc-incremental-cache.ts +86 -0
  335. package/scripts/tsc-incremental-diagnostics.ts +76 -0
  336. package/scripts/tsc-main-safety-net.ts +2 -2
  337. package/src/acp/client.ts +4 -1
  338. package/src/acp/core-turn-bridge.ts +50 -5
  339. package/src/ad-pipeline/run.ts +4 -2
  340. package/src/agent/runner.ts +169 -3
  341. package/src/agent/subagent-callable.ts +3 -2
  342. package/src/agent-mission/review-loop.ts +6 -3
  343. package/src/agent-substrate/acp-implementer.ts +14 -2
  344. package/src/agent-substrate/pr-reviewer.ts +12 -0
  345. package/src/agent-substrate/self-review-cli.ts +30 -4
  346. package/src/autopilot/pr-manager.ts +62 -7
  347. package/src/briefing/brief-items.ts +24 -22
  348. package/src/capture/tui-self-report.ts +15 -0
  349. package/src/chat/chat-cli.ts +10 -2
  350. package/src/chat/index.ts +77 -11
  351. package/src/chat/input-control-key.ts +5 -3
  352. package/src/chat/tool-interrupt-behavior.ts +38 -0
  353. package/src/chat/tool-render/dispatch.ts +5 -1
  354. package/src/chat/turn-typeahead.ts +75 -20
  355. package/src/cli/__fixtures__/agent-help-before/agent.txt +4 -2
  356. package/src/cli/agent-cli.ts +41 -13
  357. package/src/cli/config-audit.ts +123 -0
  358. package/src/cli/decisions-cli.ts +80 -6
  359. package/src/cli/log-event-names.ts +7 -0
  360. package/src/cli/mcp-login.ts +21 -5
  361. package/src/cli/msg-cli.ts +88 -0
  362. package/src/cli/pr-cli.ts +214 -57
  363. package/src/cli/pr-land-heavy-remote.ts +2 -2
  364. package/src/cli/pr-land-overlap-evidence.ts +63 -9
  365. package/src/cli/pr-land-pod-shadow-job.ts +83 -0
  366. package/src/cli/pr-land-pod-shadow.ts +16 -3
  367. package/src/cli/pr-land-virtual-rebase.ts +108 -0
  368. package/src/cli/release-cli.ts +80 -14
  369. package/src/cli/seat-cli.ts +138 -3
  370. package/src/cli/self-update.ts +5 -2
  371. package/src/cli/tasks-cli.ts +97 -19
  372. package/src/context-bus/context-first.ts +13 -0
  373. package/src/context-bus/context-now.ts +13 -2
  374. package/src/context-bus/ops-events.ts +75 -0
  375. package/src/control-plane/lease-holder.ts +12 -8
  376. package/src/control-plane/ledger.ts +163 -4
  377. package/src/control-plane/server.ts +91 -11
  378. package/src/core-turn/run-core-turn.ts +1 -0
  379. package/src/core-turn/run-goal-loop.ts +222 -3
  380. package/src/core-turn/seat-turn-cap.ts +79 -0
  381. package/src/core-turn/short-question.ts +38 -6
  382. package/src/core-turn/types.ts +3 -0
  383. package/src/dashboard/acp-boot.ts +3 -0
  384. package/src/dashboard/index.ts +224 -615
  385. package/src/dashboard/input/chat-main-entry-runtime.ts +1 -1
  386. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +4 -1
  387. package/src/dashboard/input/chat-main-session.ts +8 -1
  388. package/src/dashboard/input/chat-main-turn.ts +12 -3
  389. package/src/dashboard/input/compact-prepass-recovery.ts +33 -0
  390. package/src/dashboard/input/external-input-host.ts +26 -0
  391. package/src/dashboard/input/internal-turn.ts +261 -0
  392. package/src/dashboard/input/seat-autowake.ts +318 -0
  393. package/src/dashboard/input/turn-steer-bridge.ts +70 -0
  394. package/src/dashboard/loop-scheduler.ts +72 -0
  395. package/src/dashboard/seat-boot-preamble.ts +18 -0
  396. package/src/dashboard/skill-runtime.ts +2 -0
  397. package/src/dashboard/slash-runtime/dashboard-handlers.ts +126 -1181
  398. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
  399. package/src/dashboard/slash-runtime/index.ts +13 -0
  400. package/src/dashboard/turn-busy-teardown.ts +50 -0
  401. package/src/decisions/decision-ledger.ts +45 -4
  402. package/src/discord-self-message.ts +4 -4
  403. package/src/domains/release-tool.ts +18 -1
  404. package/src/field-note/transcribe.ts +17 -0
  405. package/src/github/remote-call.ts +81 -0
  406. package/src/goals/registry.ts +46 -6
  407. package/src/goals/types.ts +7 -1
  408. package/src/graph-runner/runner.ts +1 -0
  409. package/src/grok/credential.ts +26 -0
  410. package/src/harness/harness-clean.ts +2 -1
  411. package/src/harness/harness-cli-command.ts +52 -5
  412. package/src/harness/harness-gc.ts +2 -1
  413. package/src/harness/harness-incidents.ts +57 -20
  414. package/src/harness/harness-pod-dispatch.ts +87 -10
  415. package/src/harness/harness-queue.ts +53 -4
  416. package/src/harness/harness-stop.ts +4 -3
  417. package/src/harness/harness-substrate-default.ts +78 -7
  418. package/src/harness/harness-worktree-auto.ts +2 -1
  419. package/src/harness/harness-worktrees.ts +3 -2
  420. package/src/hooks/dispatch.ts +2 -1
  421. package/src/index.ts +152 -25
  422. package/src/input/external-input-queue.ts +33 -1
  423. package/src/intake-plane/slash.ts +14 -3
  424. package/src/keybindings.ts +4 -1
  425. package/src/llm/tool-loop-steered-rejection.ts +33 -0
  426. package/src/llm.ts +138 -19
  427. package/src/loops/consensus.ts +348 -0
  428. package/src/loops/msg-wake.ts +206 -4
  429. package/src/loops/observe.ts +19 -3
  430. package/src/loops/orchestrator/tick.ts +64 -10
  431. package/src/loops/orchestrator/traffic.ts +64 -1
  432. package/src/loops/registry.ts +30 -0
  433. package/src/market/signed-index.ts +14 -0
  434. package/src/mcp/mcp-oauth.ts +54 -5
  435. package/src/models/prompts.ts +28 -0
  436. package/src/msg/msg-sse-client.ts +223 -0
  437. package/src/msg/msg-store.ts +86 -2
  438. package/src/mss/logging/log-store.ts +225 -1
  439. package/src/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
  440. package/src/nexus/api/http-server.ts +54 -15
  441. package/src/nexus/api/loop-resources.ts +19 -3
  442. package/src/nexus/api/ops-api.ts +11 -0
  443. package/src/nexus/daemon-thin-inventory.md +37 -0
  444. package/src/nexus/index.ts +70 -0
  445. package/src/nexus/state/state.ts +1 -0
  446. package/src/oauth/store.ts +32 -7
  447. package/src/onboarding/first-run.ts +28 -3
  448. package/src/ops/overview-cache.ts +16 -4
  449. package/src/ops/resources.ts +82 -0
  450. package/src/plugins/maker/connector-maker.ts +41 -0
  451. package/src/plugins/maker/skill-maker.ts +42 -0
  452. package/src/pr-tool/census.ts +288 -0
  453. package/src/prompt-library/chat-conciseness.ts +13 -0
  454. package/src/prompt-library/universal-preamble.ts +10 -5
  455. package/src/release-loop/gate-host-reservation.ts +97 -0
  456. package/src/release-loop/landing-freeze.ts +5 -0
  457. package/src/release-loop/light-rc.ts +5 -2
  458. package/src/release-loop/placement.ts +92 -1
  459. package/src/release-loop/rehearsal-shard-plan.ts +149 -0
  460. package/src/release-loop/rehearsal.ts +73 -17
  461. package/src/repl/index.ts +20 -2
  462. package/src/seat-loop/seat-knowhow.ts +282 -0
  463. package/src/seat-loop/seat-loop.ts +41 -2
  464. package/src/seat-loop/traffic-signal.ts +3 -0
  465. package/src/self-dev/ask-launch-flow.ts +24 -3
  466. package/src/self-dev/decompose-compose-graph.ts +28 -27
  467. package/src/self-dev/decompose-proposal.ts +53 -38
  468. package/src/self-dev/decompose.ts +17 -0
  469. package/src/self-dev/dev-pipeline.ts +31 -2
  470. package/src/self-dev/draft-residue.ts +24 -9
  471. package/src/self-dev/draft-sweep.ts +59 -4
  472. package/src/self-dev/external-call-zero.ts +77 -0
  473. package/src/self-dev/launch-preflight-text.ts +6 -0
  474. package/src/self-dev/launch-preflight.ts +25 -3
  475. package/src/self-dev/local-supervisor-judge.ts +185 -0
  476. package/src/self-dev/run-supervisor.ts +229 -19
  477. package/src/self-dev/run-types.ts +20 -0
  478. package/src/self-dev/shard-aggregate.ts +13 -2
  479. package/src/self-dev/shard-plan.ts +47 -0
  480. package/src/self-dev/shard-run.ts +112 -10
  481. package/src/self-dev/spawn-lane-files.ts +19 -0
  482. package/src/self-implement/app-api-budget.ts +51 -11
  483. package/src/self-implement/config-gate.ts +2 -1
  484. package/src/self-implement/expose-gate.ts +2 -1
  485. package/src/self-implement/gate-artifacts.ts +405 -0
  486. package/src/self-implement/gate-cli.ts +201 -16
  487. package/src/self-implement/gate-remote.ts +110 -25
  488. package/src/self-implement/gate-scenario.ts +85 -0
  489. package/src/self-implement/goal-author.ts +160 -8
  490. package/src/self-implement/graph-authority.ts +38 -6
  491. package/src/self-implement/graph-overlay-condition.ts +92 -1
  492. package/src/self-implement/heal-triage.ts +79 -0
  493. package/src/self-implement/host-regate.ts +61 -3
  494. package/src/self-implement/orchestrator.ts +14 -123
  495. package/src/self-implement/pr-title.ts +123 -0
  496. package/src/self-implement/run-checkpoint.ts +235 -0
  497. package/src/self-implement/run-ledger.ts +155 -10
  498. package/src/self-implement/run-stop.ts +4 -3
  499. package/src/self-implement/run-ttl.ts +28 -4
  500. package/src/self-implement/seams.ts +2 -0
  501. package/src/self-implement/shadow-stage.ts +7 -6
  502. package/src/self-implement/stop-autoheal.ts +2 -1
  503. package/src/self-implement/train-gate-remote.ts +37 -8
  504. package/src/self-implement/train-reach-grouping.ts +157 -0
  505. package/src/self-implement/train-scenario-layers.ts +133 -0
  506. package/src/self-implement/uncommitted-work.ts +2 -0
  507. package/src/session/pending-input.ts +19 -0
  508. package/src/session/session-start.ts +224 -0
  509. package/src/session-runtime/parallel-dispatch.ts +22 -5
  510. package/src/skills/tools/dev-harness.ts +6 -4
  511. package/src/skills/tools/shell.ts +1 -1
  512. package/src/steward/resync-tick.ts +114 -23
  513. package/src/steward/ta-repair-event-collect.ts +158 -0
  514. package/src/task-agent/card-evidence.ts +25 -1
  515. package/src/task-agent/green-sweep.ts +8 -3
  516. package/src/task-agent/judge.ts +76 -0
  517. package/src/task-agent/land-queue.ts +79 -0
  518. package/src/task-agent/live-moves.ts +30 -9
  519. package/src/task-agent/postland-card.ts +5 -0
  520. package/src/task-agent/prelaunch-already-done.ts +98 -0
  521. package/src/task-agent/real-launch-guard.ts +37 -0
  522. package/src/task-agent/rejudge-on-head.ts +89 -12
  523. package/src/task-agent/remote-rejudge-bind.ts +28 -8
  524. package/src/task-agent/repair-cycle.ts +45 -7
  525. package/src/task-agent/repair-worker.ts +7 -0
  526. package/src/task-agent/run-identity.ts +200 -0
  527. package/src/task-agent/shadow.ts +50 -3
  528. package/src/task-agent/task-hand.ts +158 -5
  529. package/src/task-agent/train-landing.ts +77 -0
  530. package/src/task-agent/work-order.ts +104 -0
  531. package/src/task-orchestrator/surfaces/pod-command-job.ts +88 -28
  532. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +88 -19
  533. package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +2 -1
  534. package/src/task-orchestrator/surfaces/pod-image-source.ts +2 -1
  535. package/src/task-orchestrator/surfaces/pod-install-slots.ts +121 -9
  536. package/src/task-orchestrator/surfaces/pod-lease.ts +20 -6
  537. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +169 -0
  538. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +27 -0
  539. package/src/task-orchestrator/surfaces/pod-result-marker-wait.ts +33 -0
  540. package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +63 -0
  541. package/src/task-orchestrator/surfaces/pod-source-receive.ts +19 -3
  542. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +141 -0
  543. package/src/task-orchestrator/surfaces/pod-warm-ta-shadow.ts +85 -0
  544. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +153 -0
  545. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +208 -0
  546. package/src/task-orchestrator/surfaces/self-implement-pod.ts +132 -15
  547. package/src/telegram.ts +2 -4
  548. package/src/tui/input/pickers.ts +732 -0
  549. package/src/tui/slash/mission.ts +492 -0
  550. package/src/tui/slash/term.ts +877 -0
  551. package/src/tui-client/dashboard-session.ts +9 -0
  552. package/src/tui.ts +48 -0
  553. package/src/user-config/gemini-server-tools.ts +9 -0
  554. package/src/user-config.ts +53 -16
  555. package/src/util/spawn-sync-output.ts +7 -0
  556. package/src/ux-sim/fake-bin.ts +154 -0
  557. package/src/ux-sim/fake-clock.ts +36 -0
  558. package/src/ux-sim/headless-tui.ts +72 -0
  559. package/src/ux-sim/in-process-cli.ts +2 -1
  560. package/src/ux-sim/temp-git-remote.ts +82 -0
  561. package/src/version/packed-revision.json +1 -1
  562. package/src/video-pipeline/recipes/vlog.ts +25 -7
  563. package/apps/pwa/out/_next/static/chunks/1015-9cba22a5a4554797.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +0 -8
  567. package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +0 -34
  569. package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +0 -286
  572. package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +0 -24
  573. package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +0 -36
  576. package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +0 -64
  578. package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +0 -115
  584. package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +0 -90
  588. package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +0 -94
  599. package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +0 -1
  601. package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +0 -1
  602. package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +0 -1
  603. package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +0 -1
  604. package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +0 -62
  605. package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +0 -1
  606. package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +0 -1
  607. package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +0 -27
  608. package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +0 -104
  609. package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +0 -93
  610. package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +0 -1
  611. package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +0 -1
  612. package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +0 -24
  613. package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +0 -1
  614. package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +0 -2
  615. package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +0 -148
  616. package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +0 -149
  617. package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +0 -1
  618. package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +0 -79
  619. package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +0 -1
  620. package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +0 -1
  621. package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +0 -1
  622. package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +0 -1
  623. package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +0 -1
  624. package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +0 -287
  625. package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +0 -1
  626. package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +0 -1
  630. package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +0 -77
  632. package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +0 -74
  635. package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +0 -1
  636. package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +0 -1
  639. package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +0 -226
  640. package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +0 -1
  641. package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +0 -32
  642. package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +0 -1
  647. package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/a435ad95.577add051b4facb2.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/app/ceo/page-86feb08080261a2f.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +0 -1
  671. package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/app/loops/page-8aaa6dedc4c10dfb.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/app/morning/page-33bf667a5fb297bf.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +0 -1
  682. package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/app/term/page-9eb56166774eb256.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +0 -122
  703. package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +0 -1
  705. package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.js +0 -1
  709. /package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → LSXfY0u9QtfDbejY0Ukf_}/_ssgManifest.js +0 -0
@@ -11,6 +11,7 @@ import { releaseGitDiffPaths, releasePathHold, releasePathHoldShouldPost, releas
11
11
  import { detectTestInterference, failedNamesFromStreams, parseFailureCount, runBunTest, type MeasuredRun } from '../../scripts/detect-test-interference.js';
12
12
  import { MAX_INSPECTED_TEST_FILES, runTestInterferenceGate } from '../../scripts/ci-test-interference-gate.js';
13
13
  import { pwaGraph, pwaReach } from '../../scripts/ci-pwa-build-gate.js';
14
+ import { changedPathPairs, changedTsFiles, readGitFile, requiredExportFieldsInChanges } from '../../scripts/ci-typecheck-changed.js';
14
15
  import { classifyMergeFailure, clipRegateDetail, parseConflictFiles, type HostRegateFailure } from './regate-detail.js';
15
16
  import { buildImporterTestIndex, isTestPath } from './importer-test-index.js';
16
17
 
@@ -55,6 +56,48 @@ export type HostRegateDeps = {
55
56
  syncMergedChecklist?: typeof import('../release-loop/merged-pr-checklist.js').syncMergedPrChecklist;
56
57
  };
57
58
 
59
+ /**
60
+ * REGATE-PWA-DEPS-FOR-TSC (#26698 → #27484 must-fix): the typecheck gate requires apps/pwa dependencies for
61
+ * `runsPwa || wholeRepository` — present .ts/.tsx under apps/pwa/ in its own changed set, or any of its
62
+ * whole-repository promotion triggers (필수 export 필드 추가 · exported 심볼 삭제 · exported 함수 매개변수 증가,
63
+ * in ANY changed file). Decide it with the gate's own collectors — changedTsFiles ⊕ changedPathPairs ⊕
64
+ * requiredExportFieldsInChanges — against the candidate worktree and the same TSC_BASE_REF the gate receives,
65
+ * so dependency provision and restoration can never be narrower than the real typecheck scope. Git observation
66
+ * goes through the regate's injectable `command` seam (hermetic tests); changedTsFiles composes whitespace-token
67
+ * command strings, so its shell runner just splits them into (bin, args).
68
+ */
69
+ export function typecheckGateTouchesPwa(
70
+ worktree: string,
71
+ typecheckBase: string,
72
+ command: NonNullable<HostRegateDeps['command']>,
73
+ ): boolean {
74
+ const git = (bin: string, args: readonly string[]): unknown => {
75
+ const r = command(bin, args, worktree);
76
+ if (r.status !== 0) throw Object.assign(new Error((r.stderr || r.stdout || `${bin} exited ${String(r.status)}`).trim()), { status: r.status });
77
+ return r.stdout;
78
+ };
79
+ const changed = changedTsFiles((cmd) => {
80
+ const [bin, ...args] = cmd.split(' ');
81
+ return git(bin, args) as string;
82
+ }, { ...process.env, TSC_BASE_REF: typecheckBase }, worktree);
83
+ // Collection failures make the gate exit(1) before its dependency requirement; an empty changed set makes it
84
+ // pass without running tsc — neither path can demand apps/pwa dependencies.
85
+ if ((changed.failures?.length ?? 0) > 0 || changed.files.size === 0) return false;
86
+ // runsPwa: a present .ts/.tsx under apps/pwa/ in the gate's own changed set.
87
+ if ([...changed.files].some((file) => file.startsWith('apps/pwa/'))) return true;
88
+ const triggers = requiredExportFieldsInChanges(
89
+ changed.files,
90
+ changed.base,
91
+ changedPathPairs(changed.base, git),
92
+ (ref, path) => readGitFile(ref, path, git),
93
+ (file) => readFileSync(join(worktree, file), 'utf8'),
94
+ );
95
+ // A judgement failure makes the gate exit(1) before its dependency requirement, like the collection failures above.
96
+ if (triggers.failure) return false;
97
+ // wholeRepository: any promotion trigger widens the inspection to the whole repository, apps/pwa included.
98
+ return triggers.fields.length > 0 || triggers.removedSymbols.length > 0 || triggers.parameterIncreases.length > 0;
99
+ }
100
+
58
101
  const SPAWN_MAX_BUFFER = 256 * 1024 * 1024;
59
102
 
60
103
  const defaultCommand: NonNullable<HostRegateDeps['command']> = (bin, args, cwd, env) => {
@@ -271,7 +314,10 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
271
314
  const result = (event: 'passed' | 'failed' | 'unmeasured', step?: string, detail?: string, facts: Omit<HostRegateFailure, 'step' | 'detail'> = {}): HostRegateResult => {
272
315
  if (step) failures.push({ step, detail: clipRegateDetail(detail ?? 'unknown'), ...facts });
273
316
  log(event, { pr: input.prNumber, files, os: process.platform, ...interferenceNote, ...(step ? { failedStep: step, detail: clipRegateDetail(detail ?? 'unknown'), ...facts } : {}) });
274
- return { passed: event === 'passed', failures, os: process.platform, ...(input.verifyOnly ? { status: event, ...(verifiedBase ? { baseCommit: verifiedBase } : {}) } : {}) };
317
+ // TA-REGATE-UNMEASURED — noMerge(TA 재게이트) 도 status 를 싣는다: draft `pr-head` 거부 같은 «못 잼»을 «실패»와 가르게.
318
+ return { passed: event === 'passed', failures, os: process.platform,
319
+ ...(input.verifyOnly || input.noMerge ? { status: event } : {}),
320
+ ...(input.verifyOnly && verifiedBase ? { baseCommit: verifiedBase } : {}) };
275
321
  };
276
322
  const run = (bin: string, args: readonly string[], cwd: string, env?: NodeJS.ProcessEnv): string => {
277
323
  const r = command(bin, args, cwd, env);
@@ -305,6 +351,11 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
305
351
  let stalePrBase: string | undefined;
306
352
  const initialPrBase = baseCommit;
307
353
  let buildPwa = false;
354
+ // REGATE-PWA-DEPS-FOR-TSC (#26698 → #27484 must-fix): the typecheck gate picks its own changed set and its own
355
+ // whole-repository promotion triggers — TSC_BASE_REF..HEAD — which can carry apps/pwa files that landed on
356
+ // main after this PR branched, and root-file export changes that widen the inspection to the whole repository.
357
+ // Set in the worktree phase below.
358
+ let typecheckTouchesPwa = false;
308
359
  try {
309
360
  let fetchedBase = fetchRef(`refs/heads/${baseRefName}`, 'base');
310
361
  if (input.verifyOnly) { baseCommit = fetchedBase; verifiedBase = fetchedBase; }
@@ -406,7 +457,14 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
406
457
  const provide = (dir: string, marker: string): void => provideCheckoutDependencies(candidate, input.repoRoot, dir, marker, (cwd) => { run('bun', ['install', '--frozen-lockfile'], cwd); });
407
458
  provide('', 'typescript');
408
459
  buildPwa = needsPwaBuild(files, worktree);
409
- if (buildPwa && existsSync(join(worktree, 'apps/pwa'))) provide('apps/pwa', 'next');
460
+ // REGATE-PWA-DEPS-FOR-TSC (#26698 → #27484 must-fix): provide('apps/pwa') must also fire when the typecheck
461
+ // gate's own scope — the same TSC_BASE_REF..HEAD it receives below — holds present .ts/.tsx files under
462
+ // apps/pwa/ OR any of its whole-repository promotion triggers (필수 export 필드 추가 · exported 심볼 삭제 ·
463
+ // exported 함수 매개변수 증가, in ANY changed file), even when buildPwa never turns on: without app deps
464
+ // the gate fails such runs as «의존성 없음» for environment reasons, not code defects.
465
+ const typecheckBase = input.verifyOnly ? baseCommit : base;
466
+ typecheckTouchesPwa = typecheckGateTouchesPwa(worktree, typecheckBase, command);
467
+ if ((buildPwa || typecheckTouchesPwa) && existsSync(join(worktree, 'apps/pwa'))) provide('apps/pwa', 'next');
410
468
  } catch (e) { return result('unmeasured', 'worktree', String(e)); }
411
469
  try {
412
470
  const interferenceOptions = { neighbors: !input.verifyOnly };
@@ -427,7 +485,7 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
427
485
  }
428
486
  // The checked checkout is shared with interference/exposure gates. Verify dependencies at the
429
487
  // typecheck boundary as well: a missing PWA link here made #27414 fail as an unmeasured host regate.
430
- if (buildPwa && !existsSync(join(worktree, 'apps/pwa/node_modules'))) {
488
+ if ((buildPwa || typecheckTouchesPwa) && !existsSync(join(worktree, 'apps/pwa/node_modules'))) {
431
489
  let failure: string | null = null;
432
490
  try {
433
491
  if (existsSync(join(worktree, 'apps/pwa'))) {
@@ -86,7 +86,6 @@ import { LogStore, logsDbPath, type LogQuery, type LogStoreRow } from '../mss/lo
86
86
  import { refreshCodexQuotaSignals } from '../budget/codex-quota-refresh.js';
87
87
  import { inspectActiveProvider, type ActiveProviderInfo } from '../provider-summary.js';
88
88
  import { recordHitlEvent } from '../self-dev/hitl-log.js';
89
- import { parseAskProseTitle } from '../self-dev/launch-preflight.js';
90
89
  import { classifyReviewProviderFailure } from '../self-dev/review-provider-fallback.js';
91
90
  import { classifyError } from '../session-runtime/retry-policy.js';
92
91
  import { decomposeSelfDevGoal, inferHotPaths, type SelfDevDecomposeOptions } from '../self-dev/decompose.js';
@@ -154,6 +153,8 @@ import { plannedSelfImplBranch } from '../harness/worktree-branch-prefix.js';
154
153
  export { slugifyFeature } from '../harness/worktree-branch-prefix.js';
155
154
  import { AUTO_REVIEW_LABEL, resolveAutoReviewLabels } from './context-capsule.js';
156
155
  import { GOAL_TYPES, extractVerbatimOriginalAsk, leadingGoalMetadata, parseAskFile, parseGoalType, type GoalType } from './goal-author.js';
156
+ import { goalDocumentForReleaseNote, goalChecklistIds, prTitle } from './pr-title.js';
157
+ export { goalChecklistIds, prTitle } from './pr-title.js';
157
158
  import { renderRoundSummaryCard, type RoundSummaryEntry } from './round-summary-card.js';
158
159
  import { computeFlexSignals } from './flex-signals.js';
159
160
  import { resolveAdaptiveMaxReworkDecision, resolveEscalateTier, resolveEscalateTarget, buildReworkFeature, failIndicator, isRepeatedUnverifiedOnlyGateFailure, unverifiedRepeatKey, appendReworkHistory, truncateReworkHistoryByItem, applyReworkBudgetDecision, parseContractConflictRelaxation, parseReworkBudgetDecision, resolveReworkBudgetCarry, stripReworkBudgetHeaders, countConsecutiveMustFixIds, mergeReworkNotes, resolveReworkKind, type ReworkPlanRevision, type ReworkNotePart } from './rework-policy.js';
@@ -862,8 +863,15 @@ export function isHarnessTempArtifact(file: string): boolean {
862
863
  return /(^|\/)\.elanous-typecheck-scope-[^/]+\.json$/.test(file);
863
864
  }
864
865
 
866
+ /** Only this run's GOAL document is a harness artifact; unrelated GOAL edits remain in scope accounting. */
867
+ export function isHarnessGeneratedGoal(file: string, goalDocumentPath?: string): boolean {
868
+ const ownGoal = goalDocumentPath?.replace(/\\/g, '/').match(/(?:^|\/)(docs\/goals\/GOAL-[^/]+\.(?:md|txt))$/)?.[1];
869
+ return !!ownGoal && normalizeDeclaredScopePath(file) === ownGoal;
870
+ }
871
+
865
872
  export function detectDeclaredScopeDiff(input: {
866
873
  goalDocument?: string | null;
874
+ goalDocumentPath?: string;
867
875
  changedFiles?: readonly string[] | null;
868
876
  nameCap?: number;
869
877
  }): DeclaredScopeDiff {
@@ -879,7 +887,8 @@ export function detectDeclaredScopeDiff(input: {
879
887
  return { status: 'unknown-changed-files', outsideCount: null, outsideNames: [], nameCapReached: false, unmadeCount: null, unmadeNames: [], declaredCount: null };
880
888
  }
881
889
  const outside = [...new Set(input.changedFiles.map(normalizeDeclaredScopePath).filter(Boolean))]
882
- .filter((file) => !declared.paths.some((target) => changedFileIsInsideDeclaredTarget(file, target)));
890
+ .filter((file) => !isHarnessGeneratedGoal(file, input.goalDocumentPath)
891
+ && !declared.paths.some((target) => changedFileIsInsideDeclaredTarget(file, target)));
883
892
  // ⭐ 「선언했는데 «안 채워진»」 것 — `outside` 의 반대 방향이다.
884
893
  const changed = [...new Set(input.changedFiles.map(normalizeDeclaredScopePath).filter(Boolean))];
885
894
  const unmade = declared.paths.filter((target) => !changed.some((file) => changedFileIsInsideDeclaredTarget(file, target)));
@@ -914,6 +923,7 @@ function observeDeclaredScopeDiff(
914
923
  }
915
924
  const diff = detectDeclaredScopeDiff({
916
925
  goalDocument,
926
+ goalDocumentPath: input.goalFile,
917
927
  changedFiles: input.changedFiles,
918
928
  nameCap: input.nameCap,
919
929
  });
@@ -2357,120 +2367,6 @@ function addedDiffEvidence(diff: string): { text: string; truncated: boolean } {
2357
2367
  };
2358
2368
  }
2359
2369
 
2360
- function isRepositoryRelativePath(candidate: string): boolean {
2361
- if (/^(?:[A-Za-z][A-Za-z0-9+.-]*:\/\/|[\\/]|[A-Za-z]:[\\/])/.test(candidate)) return false;
2362
- const parts = candidate.split('/');
2363
- return parts.length > 1
2364
- && parts.every((part) => part !== '.' && part !== '..' && /^[A-Za-z0-9_.-]+$/.test(part))
2365
- && /\.[A-Za-z0-9]+$/.test(parts.at(-1)!);
2366
- }
2367
-
2368
- function extractRepositoryRelativePaths(first: string): string[] {
2369
- const candidates = first.split(/[\s,;()[\]{}"'`<>]+/).filter(Boolean);
2370
- return candidates.filter(isRepositoryRelativePath);
2371
- }
2372
-
2373
- function parseAskMarkdownH1(feature: string): string | undefined {
2374
- // ⛔ 펜스는 «문자»만이 아니라 «길이»로 닫힌다(CommonMark): 닫는 줄은 같은 문자 · 여는 줄 이상의 길이 · 뒤에 정보 문자열 없음.
2375
- // 🩸 2026-09-23(#20050 착지 직후 실물): GOAL 문서가 원래 ask 를 ```` 네 개 펜스로 싸고, 그 안에 ``` 블록이 있다.
2376
- // 문자만 보면 안쪽 ``` 이 바깥 ```` 를 «닫아» 안팎이 뒤집히고 ```bash 안의 `# 주석` 이 다시 제목이 됐다.
2377
- let fence: { marker: '`' | '~'; run: number } | undefined;
2378
- for (const line of feature.split(/\r?\n/)) {
2379
- const trimmed = line.trim();
2380
- const marker = trimmed[0] === '`' || trimmed[0] === '~' ? trimmed[0] : undefined;
2381
- let run = 0;
2382
- if (marker) {
2383
- while (run < trimmed.length && trimmed[run] === marker) run += 1;
2384
- }
2385
- if (marker && run >= 3) {
2386
- if (!fence) {
2387
- fence = { marker, run };
2388
- continue;
2389
- }
2390
- if (fence.marker === marker && run >= fence.run && trimmed.slice(run).trim() === '') {
2391
- fence = undefined;
2392
- continue;
2393
- }
2394
- }
2395
- if (fence) continue;
2396
- if (line[0] !== '#' || line[1] === '#') continue;
2397
- if (line.length < 2 || !/\s/.test(line[1]!)) continue;
2398
- const text = line.slice(1).trim();
2399
- if (text) return text;
2400
- }
2401
- return undefined;
2402
- }
2403
-
2404
- function prTitleCodePointCount(text: string): number {
2405
- return Array.from(text).length;
2406
- }
2407
-
2408
- function truncatePrTitle(text: string): string {
2409
- const points = Array.from(text);
2410
- return points.length <= 72 ? text : `${points.slice(0, 69).join('')}...`;
2411
- }
2412
-
2413
- export function goalChecklistIds(feature: string, goalFile?: string): string[] {
2414
- const document = goalFile ? goalDocumentForReleaseNote(goalFile) : feature;
2415
- const declaration = document.split(/\r?\n/).find((line) => line.startsWith('- 칸 id: '));
2416
- const declared = declaration?.slice('- 칸 id: '.length).trim();
2417
- if (declared && declared !== 'not declared') {
2418
- return [...new Set(declared.split(' · ').map((id) => id.trim()).filter(Boolean))];
2419
- }
2420
- const firstLine = feature.split(/\r?\n/, 1)[0] ?? '';
2421
- return [...new Set(Array.from(firstLine.matchAll(/\b[A-Z][A-Z0-9]+-[A-Z0-9]+\b/g), (match) => match[0]))];
2422
- }
2423
-
2424
- function prTitleWithoutChecklistId(feature: string): string {
2425
- const proseTitle = parseAskProseTitle(feature);
2426
- if (proseTitle) return truncatePrTitle(proseTitle);
2427
-
2428
- const headingTitle = parseAskMarkdownH1(feature);
2429
- if (headingTitle) return truncatePrTitle(headingTitle);
2430
-
2431
- // ⛔ GOAL 문서는 원래 ask 를 `Original ask (verbatim, unmodified):` 아래 ```` 펜스로 싣는다 — 그 안은 «코드»가 아니라 인용된 마크다운이다.
2432
- // 🩸 2026-09-23: #20051 이 펜스를 길이로 닫게 고치자 그 인용 블록 안의 H1 까지 «건너뛰어»,
2433
- // 첫 줄이 `대상 경로:` 인 GOAL 문서 대부분이 경로 요약 제목으로 떨어졌다(실물: #20055 `src/self-implement: gate-baseline.ts, …`).
2434
- // ⇒ 인용된 ask 를 꺼내 그 «안»에서 같은 규칙(제목: 줄 → 펜스 밖 H1)으로 한 번 더 찾는다.
2435
- // ⚠️ 정보 문자열이 붙은 펜스(```bash 등)로 싸였으면 그 안은 «코드»다 — 인용된 마크다운으로 보지 않는다.
2436
- const verbatim = extractVerbatimOriginalAsk(feature);
2437
- const opener = verbatim?.range ? feature.slice(0, verbatim.range.start).split(/\r?\n/).filter((line, i, all) => i === all.length - 2)[0] ?? '' : '';
2438
- const verbatimAsk = verbatim && /^\s*(`{3,}|~{3,})\s*$/.test(opener) ? verbatim.ask : undefined;
2439
- if (verbatimAsk) {
2440
- const askTitle = parseAskProseTitle(verbatimAsk) ?? parseAskMarkdownH1(verbatimAsk);
2441
- if (askTitle) return truncatePrTitle(askTitle);
2442
- }
2443
-
2444
- const first = feature.split('\n')[0]!.trim();
2445
- const paths = extractRepositoryRelativePaths(first);
2446
- if (!paths.length) return truncatePrTitle(first);
2447
-
2448
- const pathParts = paths.map((path) => path.split('/'));
2449
- const commonParts: string[] = [];
2450
- for (let index = 0; index < pathParts[0]!.length - 1; index++) {
2451
- const part = pathParts[0]![index]!;
2452
- if (!pathParts.every((parts) => parts[index] === part)) break;
2453
- commonParts.push(part);
2454
- }
2455
- const fileNames = pathParts.map((parts) => parts.at(-1)!);
2456
- const directoryPrefix = commonParts.length ? `${commonParts.join('/')}: ` : '';
2457
- const titlePrefix = prTitleCodePointCount(directoryPrefix) + prTitleCodePointCount(fileNames[0]!) <= 72 ? directoryPrefix : '';
2458
- const title = fileNames.reduce((result, fileName) => {
2459
- const next = result ? `${result}, ${fileName}` : fileName;
2460
- return prTitleCodePointCount(titlePrefix) + prTitleCodePointCount(next) <= 72 ? next : result;
2461
- }, '');
2462
- if (title) return `${titlePrefix}${title}`;
2463
- const firstFileName = fileNames[0]!;
2464
- return truncatePrTitle(firstFileName);
2465
- }
2466
-
2467
- export function prTitle(feature: string, goalFile?: string): string {
2468
- const title = prTitleWithoutChecklistId(feature);
2469
- const id = goalChecklistIds(feature, goalFile)[0];
2470
- if (!id) return title;
2471
- return truncatePrTitle(title.startsWith(`${id}: `) ? title : `${id}: ${title}`);
2472
- }
2473
-
2474
2370
  const BLOCKED_DRAFT_PR_HUMAN_JUDGMENT_ANCHOR = '## 사람 판단 필요';
2475
2371
 
2476
2372
  /** 사람이 읽는 중단 사유 상한. 관측 `reason.slice(0, 240)` 과 같은 길이라 표시가 앞부분을 버리지 않는다. */
@@ -2683,12 +2579,6 @@ export class MergedReleaseNoteWriteError extends Error {
2683
2579
  }
2684
2580
  }
2685
2581
 
2686
- function goalDocumentForReleaseNote(goalFile?: string): string {
2687
- if (!goalFile) return '';
2688
- try { return readFileSync(goalFile, 'utf8'); }
2689
- catch { return ''; }
2690
- }
2691
-
2692
2582
  function shardReleaseNote(feature: string): ReleaseNoteSection | undefined {
2693
2583
  const matches = [...feature.matchAll(/^## Shard identity\r?\n([^\r\n]+)/gm)];
2694
2584
  const identity = matches.at(-1)?.[1];
@@ -7261,7 +7151,8 @@ async function runSelfImplementInner(
7261
7151
  try { goalDocument = readFileSync(opts.goalFile, 'utf8'); } catch { /* unknown scope */ }
7262
7152
  // 🩸 10-09: 범위 타입검사 임시 tsconfig(.elanous-typecheck-scope-*.json · scoped-typecheck-config.ts)가 옛 가지에 커밋된 뒤 지워지면
7263
7153
  // «추적 파일 삭제» 라 impact=critical → 결정 카드가 «irreversible» 로 대표에게 갔다(D-20·35·43·80). 하니스 임시물은 범위 판정 밖이다.
7264
- const scope = detectDeclaredScopeDiff({ goalDocument, changedFiles: gateRouteFiles?.filter(file => !harnessSeededPaths.includes(file) && !isHarnessTempArtifact(file)), nameCap: gateRouteFiles?.length });
7154
+ const scope = detectDeclaredScopeDiff({ goalDocument, goalDocumentPath: opts.goalFile,
7155
+ changedFiles: gateRouteFiles?.filter(file => !harnessSeededPaths.includes(file) && !isHarnessTempArtifact(file)), nameCap: gateRouteFiles?.length });
7265
7156
  // SCOPE-HELD-DELIVER — no declared target means the declaration was unreadable (e.g. paths listed with spaces), not
7266
7157
  // that every edit is outside it: treat it like an unknown declaration and go on to the gate.
7267
7158
  if (scope.status === 'known' && scope.declaredCount === 0 && (scope.outsideCount ?? 0) > 0) {
@@ -0,0 +1,123 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { parseAskProseTitle } from '../self-dev/launch-preflight.js';
3
+ import { extractVerbatimOriginalAsk } from './goal-author.js';
4
+
5
+ export function goalDocumentForReleaseNote(goalFile?: string): string {
6
+ if (!goalFile) return '';
7
+ try { return readFileSync(goalFile, 'utf8'); }
8
+ catch { return ''; }
9
+ }
10
+
11
+ function isRepositoryRelativePath(candidate: string): boolean {
12
+ if (/^(?:[A-Za-z][A-Za-z0-9+.-]*:\/\/|[\\/]|[A-Za-z]:[\\/])/.test(candidate)) return false;
13
+ const parts = candidate.split('/');
14
+ return parts.length > 1
15
+ && parts.every((part) => part !== '.' && part !== '..' && /^[A-Za-z0-9_.-]+$/.test(part))
16
+ && /\.[A-Za-z0-9]+$/.test(parts.at(-1)!);
17
+ }
18
+
19
+ function extractRepositoryRelativePaths(first: string): string[] {
20
+ const candidates = first.split(/[\s,;()[\]{}"'`<>]+/).filter(Boolean);
21
+ return candidates.filter(isRepositoryRelativePath);
22
+ }
23
+
24
+ function parseAskMarkdownH1(feature: string): string | undefined {
25
+ // ⛔ 펜스는 «문자»만이 아니라 «길이»로 닫힌다(CommonMark): 닫는 줄은 같은 문자 · 여는 줄 이상의 길이 · 뒤에 정보 문자열 없음.
26
+ // 🩸 2026-09-23(#20050 착지 직후 실물): GOAL 문서가 원래 ask 를 ```` 네 개 펜스로 싸고, 그 안에 ``` 블록이 있다.
27
+ // 문자만 보면 안쪽 ``` 이 바깥 ```` 를 «닫아» 안팎이 뒤집히고 ```bash 안의 `# 주석` 이 다시 제목이 됐다.
28
+ let fence: { marker: '`' | '~'; run: number } | undefined;
29
+ for (const line of feature.split(/\r?\n/)) {
30
+ const trimmed = line.trim();
31
+ const marker = trimmed[0] === '`' || trimmed[0] === '~' ? trimmed[0] : undefined;
32
+ let run = 0;
33
+ if (marker) {
34
+ while (run < trimmed.length && trimmed[run] === marker) run += 1;
35
+ }
36
+ if (marker && run >= 3) {
37
+ if (!fence) {
38
+ fence = { marker, run };
39
+ continue;
40
+ }
41
+ if (fence.marker === marker && run >= fence.run && trimmed.slice(run).trim() === '') {
42
+ fence = undefined;
43
+ continue;
44
+ }
45
+ }
46
+ if (fence) continue;
47
+ if (line[0] !== '#' || line[1] === '#') continue;
48
+ if (line.length < 2 || !/\s/.test(line[1]!)) continue;
49
+ const text = line.slice(1).trim();
50
+ if (text) return text;
51
+ }
52
+ return undefined;
53
+ }
54
+
55
+ function prTitleCodePointCount(text: string): number {
56
+ return Array.from(text).length;
57
+ }
58
+
59
+ function truncatePrTitle(text: string): string {
60
+ const points = Array.from(text);
61
+ return points.length <= 72 ? text : `${points.slice(0, 69).join('')}...`;
62
+ }
63
+
64
+ export function goalChecklistIds(feature: string, goalFile?: string): string[] {
65
+ const document = goalFile ? goalDocumentForReleaseNote(goalFile) : feature;
66
+ const declaration = document.split(/\r?\n/).find((line) => line.startsWith('- 칸 id: '));
67
+ const declared = declaration?.slice('- 칸 id: '.length).trim();
68
+ if (declared && declared !== 'not declared') {
69
+ return [...new Set(declared.split(' · ').map((id) => id.trim()).filter(Boolean))];
70
+ }
71
+ const firstLine = feature.split(/\r?\n/, 1)[0] ?? '';
72
+ return [...new Set(Array.from(firstLine.matchAll(/\b[A-Z][A-Z0-9]+-[A-Z0-9]+\b/g), (match) => match[0]))];
73
+ }
74
+
75
+ function prTitleWithoutChecklistId(feature: string): string {
76
+ const proseTitle = parseAskProseTitle(feature);
77
+ if (proseTitle) return truncatePrTitle(proseTitle);
78
+
79
+ const headingTitle = parseAskMarkdownH1(feature);
80
+ if (headingTitle) return truncatePrTitle(headingTitle);
81
+
82
+ // ⛔ GOAL 문서는 원래 ask 를 `Original ask (verbatim, unmodified):` 아래 ```` 펜스로 싣는다 — 그 안은 «코드»가 아니라 인용된 마크다운이다.
83
+ // 🩸 2026-09-23: #20051 이 펜스를 길이로 닫게 고치자 그 인용 블록 안의 H1 까지 «건너뛰어»,
84
+ // 첫 줄이 `대상 경로:` 인 GOAL 문서 대부분이 경로 요약 제목으로 떨어졌다(실물: #20055 `src/self-implement: gate-baseline.ts, …`).
85
+ // ⇒ 인용된 ask 를 꺼내 그 «안»에서 같은 규칙(제목: 줄 → 펜스 밖 H1)으로 한 번 더 찾는다.
86
+ // ⚠️ 정보 문자열이 붙은 펜스(```bash 등)로 싸였으면 그 안은 «코드»다 — 인용된 마크다운으로 보지 않는다.
87
+ const verbatim = extractVerbatimOriginalAsk(feature);
88
+ const opener = verbatim?.range ? feature.slice(0, verbatim.range.start).split(/\r?\n/).filter((line, i, all) => i === all.length - 2)[0] ?? '' : '';
89
+ const verbatimAsk = verbatim && /^\s*(`{3,}|~{3,})\s*$/.test(opener) ? verbatim.ask : undefined;
90
+ if (verbatimAsk) {
91
+ const askTitle = parseAskProseTitle(verbatimAsk) ?? parseAskMarkdownH1(verbatimAsk);
92
+ if (askTitle) return truncatePrTitle(askTitle);
93
+ }
94
+
95
+ const first = feature.split('\n')[0]!.trim();
96
+ const paths = extractRepositoryRelativePaths(first);
97
+ if (!paths.length) return truncatePrTitle(first);
98
+
99
+ const pathParts = paths.map((path) => path.split('/'));
100
+ const commonParts: string[] = [];
101
+ for (let index = 0; index < pathParts[0]!.length - 1; index++) {
102
+ const part = pathParts[0]![index]!;
103
+ if (!pathParts.every((parts) => parts[index] === part)) break;
104
+ commonParts.push(part);
105
+ }
106
+ const fileNames = pathParts.map((parts) => parts.at(-1)!);
107
+ const directoryPrefix = commonParts.length ? `${commonParts.join('/')}: ` : '';
108
+ const titlePrefix = prTitleCodePointCount(directoryPrefix) + prTitleCodePointCount(fileNames[0]!) <= 72 ? directoryPrefix : '';
109
+ const title = fileNames.reduce((result, fileName) => {
110
+ const next = result ? `${result}, ${fileName}` : fileName;
111
+ return prTitleCodePointCount(titlePrefix) + prTitleCodePointCount(next) <= 72 ? next : result;
112
+ }, '');
113
+ if (title) return `${titlePrefix}${title}`;
114
+ const firstFileName = fileNames[0]!;
115
+ return truncatePrTitle(firstFileName);
116
+ }
117
+
118
+ export function prTitle(feature: string, goalFile?: string): string {
119
+ const title = prTitleWithoutChecklistId(feature);
120
+ const id = goalChecklistIds(feature, goalFile)[0];
121
+ if (!id) return title;
122
+ return truncatePrTitle(title.startsWith(`${id}: `) ? title : `${id}: ${title}`);
123
+ }
@@ -0,0 +1,235 @@
1
+ /**
2
+ * run-checkpoint/v1 묶음 스키마 — 런의 «체크포인트» 스냅샷을 판 번호 있는 타입으로 직렬화한다.
3
+ *
4
+ * ⛔ 이 판은 «묶음 정의 ⊕ 조립 ⊕ 디스크 기록»까지만 담는다. orchestrator 배선 · run-ledger
5
+ * additive 이벤트('checkpoint'/'resumed'/'checkpoint-failed') · salvage CLI 명령은
6
+ * 같은 골의 형제 조각이 담당한다(의도적 경계 — 분해 판 4조각의 1번).
7
+ *
8
+ * 📐 run-ledger 패턴을 «어느 것을 왜» 따르나(원문이 'writeCheckpoi'에서 끊겨 임의로 정하지 않는다):
9
+ * ① `runLedgerDir`(run-ledger.ts:205) — 상태 뿌리에서 «자기 저장소 이름»의 디렉터리를 여는 방식.
10
+ * 여기도 `elanousStateRoot()` 아래 `run-checkpoint/` 디렉터리로 열어, 저장 위치가 run-ledger 와
11
+ * 같은 축(state root)에 있게 한다. 원문이 저장 위치의 경로를 정하지 않았으므로 이 패턴을 따른다.
12
+ * ② `runLedgerPath`(run-ledger.ts:209) — runId 를 «normalizeRunId 의 산출 집합»으로 검증하고
13
+ * 거부는 유지하되 정규화는 «하지 않는다»(경로 탈출 방어). 여기도 같은 검사를 쓰되 파일은
14
+ * 스냅샷이므로 JSONL 추가가 아니라 «덮어쓰기» 하나로 `<runId>.checkpoint.json` 을 쓴다.
15
+ * JSONL 이 아닌 이유: 원장은 사건의 «추가», 체크포인트는 마지막 상태의 «스냅샷»이다 —
16
+ * appendRunLedgerEntry 가 줄을 «쌓는» 것과 달리 resume 은 «최신 하나»만 읽으면 된다.
17
+ * ③ `appendRunLedgerEntry`(run-ledger.ts:411) — 쓰기 전 ①`refuseProductionLedgerWriteInTest`
18
+ * 가드(테스트 중 운영 원장 쓰기 차단) ② `mkdirSync(dir, { recursive: true })` 순서를 그대로 따른다.
19
+ * «run-ledger 줄 하나»가 아니라 «JSON 파일 하나»이지만 쓰기 관문·디렉터리 보증은 같아야 한다.
20
+ */
21
+ import { createHash, randomUUID } from 'node:crypto';
22
+ import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
23
+ import { join } from 'node:path';
24
+ import { refuseProductionLedgerWriteInTest } from '../harness/ledger-write-guard.js';
25
+ import { normalizeRunId } from '../harness/harness-space.js';
26
+ import { elanousStateRoot } from '../autopilot/state-paths.js';
27
+
28
+ /** 판 번호 — 묶음 필드 구성이 바뀌면 이 값을 올리고 읽는 쪽은 판을 검사한다. */
29
+ export const CHECKPOINT_SCHEMA_VERSION = 1;
30
+
31
+ /** 판 번호가 문자열 표면(직렬화된 JSON 안)에 남는 형태. */
32
+ export const CHECKPOINT_SCHEMA_ID = 'run-checkpoint/v1';
33
+
34
+ /** 라운드 카드 — 조립 시점에 판을 정하지 않는다(원문이 카드의 필드를 정하지 않았다). */
35
+ export type CheckpointRoundCard = Record<string, unknown>;
36
+
37
+ /** 미배달 감독 지시 한 줄 — 조립자가 주는 문면 그대로. */
38
+ export type UndeliveredSupervisorDirective = string;
39
+
40
+ /**
41
+ * run-checkpoint/v1 묶음 — 전 필드의 원문 명세:
42
+ * runId · 골 문면(goalText) · 판정 상태(verdictStatus) · salvage 가지 sha(salvageBranchSha) ·
43
+ * 세션 대화 기록(sessionTranscript) · 라운드 카드(roundCards) · EVIDENCE/RESULT(evidenceResult) ·
44
+ * 미배달 감독 지시(undeliveredSupervisorDirectives) · 자식 모델(childModel) · 쓴 토큰(tokensUsed) ·
45
+ * sha256(«전 필드 포함» — sha256 자기 자신만 제외한 나머지 전 필드의 정규화 직렬화에 걸친다).
46
+ */
47
+ export interface RunCheckpointBundle {
48
+ /** 판이자 종류 표지 — 항상 `${CHECKPOINT_SCHEMA_ID}`. */
49
+ schema: typeof CHECKPOINT_SCHEMA_ID;
50
+ /** 판 번호(정수) — CHECKPOINT_SCHEMA_VERSION 과 같다. */
51
+ schemaVersion: typeof CHECKPOINT_SCHEMA_VERSION;
52
+ runId: string;
53
+ goalText: string;
54
+ verdictStatus: string;
55
+ /** 없으면 null — «모름»과 «없음»을 나눈다. */
56
+ salvageBranchSha: string | null;
57
+ /** null = «미확인»(조립자가 주지 않음) — 빈 문자열(«실제로 비어 있음»)과 구별한다. */
58
+ sessionTranscript: string | null;
59
+ /** null = «미확인» — 빈 배열(«카드 0장»)과 구별한다. */
60
+ roundCards: readonly CheckpointRoundCard[] | null;
61
+ /** null = «미확인» — 빈 문자열과 구별한다. */
62
+ evidenceResult: string | null;
63
+ /** null = «미확인» — 빈 배열(«미배달 지시 0건»)과 구별한다. */
64
+ undeliveredSupervisorDirectives: readonly UndeliveredSupervisorDirective[] | null;
65
+ childModel: string | null;
66
+ tokensUsed: number | null;
67
+ /** sha256 — 자기를 제외한 전 필드 정규화 직렬화에 대한 sha256 hex. */
68
+ sha256: string;
69
+ recordedAt: string;
70
+ }
71
+
72
+ /** 조립 재료 — run 사실 원형. `buildCheckpointBundle` 이 여기서 묶음을 만든다. */
73
+ export interface RunCheckpointFacts {
74
+ runId: string;
75
+ goalText: string;
76
+ verdictStatus: string;
77
+ salvageBranchSha?: string | null;
78
+ sessionTranscript?: string | null;
79
+ roundCards?: readonly CheckpointRoundCard[] | null;
80
+ evidenceResult?: string | null;
81
+ undeliveredSupervisorDirectives?: readonly UndeliveredSupervisorDirective[] | null;
82
+ childModel?: string | null;
83
+ tokensUsed?: number | null;
84
+ recordedAt?: string;
85
+ }
86
+
87
+ /** 정렬된 키 직렬화 — 입력은 이미 «JSON 값»(toJSON·undefined·NaN 이 풀린 뒤)이어야 한다. */
88
+ function sortedJson(value: unknown): string {
89
+ if (value === null || typeof value !== 'object') return JSON.stringify(value);
90
+ if (Array.isArray(value)) return `[${value.map((item) => sortedJson(item)).join(',')}]`;
91
+ const entries = Object.entries(value as Record<string, unknown>)
92
+ .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
93
+ return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${sortedJson(v)}`).join(',')}}`;
94
+ }
95
+
96
+ /**
97
+ * 객체 키를 «정렬된» 안정 직렬화로 — 같은 값이면 같은 문자열(sha256 재현성).
98
+ * ⭐ 해시와 저장이 «같은 직렬화»를 보도록 먼저 `JSON.stringify` 의미론(toJSON·Date→ISO ·
99
+ * 배열 속 undefined→null · 객체 속 undefined 제거 · NaN→null)으로 한 번 풀고 키만 정렬한다.
100
+ * 그래야 `writeCheckpoint` 가 쓴 파일을 `readCheckpoint` 가 다시 해시해도 같은 값이 나온다.
101
+ */
102
+ function canonicalJson(value: unknown): string {
103
+ const json = JSON.stringify(value);
104
+ if (json === undefined) return 'null';
105
+ return sortedJson(JSON.parse(json));
106
+ }
107
+
108
+ /** sha256 조수 — hex 문자열. 묶음의 sha256 필드에 넣는 값과 같은 계산이다. */
109
+ export function sha256Hex(value: unknown): string {
110
+ return createHash('sha256').update(canonicalJson(value), 'utf8').digest('hex');
111
+ }
112
+
113
+ /** sha256 자기 자신을 제외한 «전 필드»를 걸치는 다이제스트(원문: 'sha256 전 필드 포함'). */
114
+ export function bundleSha256(bundle: Omit<RunCheckpointBundle, 'sha256'>): string {
115
+ const { sha256: _omit, ...rest } = bundle as RunCheckpointBundle;
116
+ return sha256Hex(rest);
117
+ }
118
+
119
+ const isStringArray = (v: unknown): boolean => Array.isArray(v) && v.every((x) => typeof x === 'string');
120
+ const isNullableString = (v: unknown): boolean => v === null || typeof v === 'string';
121
+
122
+ /**
123
+ * 묶음의 판(schema ⊕ schemaVersion)과 필수 필드의 존재·타입을 검증한다 — 쓰기·읽기 공통 관문.
124
+ * 판 번호는 «지원하는 판»과 정확히 같아야 한다(다른 판을 v1 으로 받아들이지 않는다).
125
+ */
126
+ export function assertCheckpointShape(value: unknown): asserts value is RunCheckpointBundle {
127
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
128
+ throw new Error('invalid checkpoint: not an object');
129
+ }
130
+ const b = value as Record<string, unknown>;
131
+ if (b.schema !== CHECKPOINT_SCHEMA_ID) {
132
+ throw new Error(`unknown checkpoint schema: ${String(b.schema)}`);
133
+ }
134
+ if (b.schemaVersion !== CHECKPOINT_SCHEMA_VERSION) {
135
+ throw new Error(`unsupported checkpoint schemaVersion: ${String(b.schemaVersion)}`);
136
+ }
137
+ const bad: string[] = [];
138
+ for (const key of ['runId', 'goalText', 'verdictStatus', 'sha256', 'recordedAt']) {
139
+ if (typeof b[key] !== 'string') bad.push(key);
140
+ }
141
+ if (!isNullableString(b.salvageBranchSha)) bad.push('salvageBranchSha');
142
+ // null = «미확인» 을 받아들인다(빈 값과 다른 값) — 키 자체가 없으면(undefined) 거부한다.
143
+ if (!isNullableString(b.sessionTranscript)) bad.push('sessionTranscript');
144
+ if (!isNullableString(b.evidenceResult)) bad.push('evidenceResult');
145
+ if (!isNullableString(b.childModel)) bad.push('childModel');
146
+ if (!(b.tokensUsed === null || (typeof b.tokensUsed === 'number' && Number.isFinite(b.tokensUsed)))) {
147
+ bad.push('tokensUsed');
148
+ }
149
+ if (b.roundCards !== null && (!Array.isArray(b.roundCards) || !b.roundCards.every((c) => c !== null && typeof c === 'object' && !Array.isArray(c)))) {
150
+ bad.push('roundCards');
151
+ }
152
+ if (b.undeliveredSupervisorDirectives !== null && !isStringArray(b.undeliveredSupervisorDirectives)) bad.push('undeliveredSupervisorDirectives');
153
+ if (bad.length > 0) throw new Error(`invalid checkpoint fields: ${bad.join(', ')}`);
154
+ }
155
+
156
+ /** run 사실에서 run-checkpoint/v1 묶음을 조립한다 — sha256 도 이 안에서 계산해 넣는다. */
157
+ export function buildCheckpointBundle(facts: RunCheckpointFacts): RunCheckpointBundle {
158
+ const runId = facts.runId;
159
+ // runLedgerPath 패턴: 정규화는 하지 않고, normalizeRunId 의 «산출 집합»만 받아들인다.
160
+ if (!runId || runId !== normalizeRunId(runId)) throw new Error(`invalid runId: ${runId}`);
161
+ const partial: Omit<RunCheckpointBundle, 'sha256'> = {
162
+ schema: CHECKPOINT_SCHEMA_ID,
163
+ schemaVersion: CHECKPOINT_SCHEMA_VERSION,
164
+ runId,
165
+ goalText: facts.goalText,
166
+ verdictStatus: facts.verdictStatus,
167
+ salvageBranchSha: facts.salvageBranchSha ?? null,
168
+ // 생략 = «미확인»(null) — 빈 값으로 채워 «실제로 비어 있음»으로 위장하지 않는다.
169
+ sessionTranscript: facts.sessionTranscript ?? null,
170
+ roundCards: facts.roundCards ?? null,
171
+ evidenceResult: facts.evidenceResult ?? null,
172
+ undeliveredSupervisorDirectives: facts.undeliveredSupervisorDirectives ?? null,
173
+ childModel: facts.childModel ?? null,
174
+ tokensUsed: facts.tokensUsed ?? null,
175
+ recordedAt: facts.recordedAt ?? new Date().toISOString(),
176
+ };
177
+ // 저장될 꼴(JSON 값)로 한 번 풀어, 메모리 묶음 = 파일에서 읽은 묶음이 되게 한다(Date→ISO 등).
178
+ const stored = JSON.parse(JSON.stringify(partial)) as Omit<RunCheckpointBundle, 'sha256'>;
179
+ return { ...stored, sha256: bundleSha256(stored) };
180
+ }
181
+
182
+ /** runLedgerDir 패턴 — state root 아래 «자기 저장소 이름» 디렉터리. */
183
+ export function checkpointDir(stateDir?: string): string {
184
+ return join(stateDir ?? elanousStateRoot(), 'run-checkpoint');
185
+ }
186
+
187
+ /** runLedgerPath 패턴 — runId 검증(정규화 아님) 후 경로 결정. */
188
+ export function checkpointPath(runId: string, dir = checkpointDir()): string {
189
+ if (runId !== normalizeRunId(runId) || !runId) throw new Error(`invalid runId: ${runId}`);
190
+ return join(dir, `${runId}.checkpoint.json`);
191
+ }
192
+
193
+ /**
194
+ * 묶음을 디스크에 기록한다(appendRunLedgerEntry 의 쓰기 관문·디렉터리 보증을 따른다).
195
+ * 반환값은 기록한 파일 경로 — 형제 조각의 원장 이벤트 'checkpoint' {bundleRef} 가 여기 담긴다.
196
+ *
197
+ * ⛔ 스냅샷은 «최신 하나»라 덮어쓰기가 곧 이전 상태의 소실이다. 그래서
198
+ * ① 쓰기 «전»에 판·sha256 을 검증해 무효 묶음이면 던지고 기존 파일을 건드리지 않는다.
199
+ * ② 임시 파일에 쓴 뒤 rename 으로 원자 교체한다(쓰다 죽어도 반쪽 파일이 남지 않는다).
200
+ */
201
+ export function writeCheckpoint(bundle: RunCheckpointBundle, dir = checkpointDir()): string {
202
+ assertCheckpointShape(bundle);
203
+ const path = checkpointPath(bundle.runId, dir);
204
+ const body = `${JSON.stringify(bundle, null, 2)}\n`;
205
+ // 저장될 꼴 그대로를 다시 해시한다 — 읽기 쪽 검증과 같은 입력이다.
206
+ const expected = bundleSha256(JSON.parse(body) as RunCheckpointBundle);
207
+ if (bundle.sha256 !== expected) {
208
+ throw new Error(`checkpoint sha256 mismatch: ${bundle.sha256} != ${expected}`);
209
+ }
210
+ if (refuseProductionLedgerWriteInTest(dir, 'run-checkpoint')) return '';
211
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
212
+ const tmp = `${path}.${process.pid}.${randomUUID()}.tmp`;
213
+ try {
214
+ writeFileSync(tmp, body, 'utf8');
215
+ renameSync(tmp, path);
216
+ } catch (error) {
217
+ rmSync(tmp, { force: true });
218
+ throw error;
219
+ }
220
+ return path;
221
+ }
222
+
223
+ /** 기록된 묶음을 읽어 sha256 이 전 필드에 대해 아직 성립하는지 검증과 함께 돌려준다. */
224
+ export function readCheckpoint(runId: string, dir = checkpointDir()): RunCheckpointBundle {
225
+ const raw: unknown = JSON.parse(readFileSync(checkpointPath(runId, dir), 'utf8'));
226
+ assertCheckpointShape(raw);
227
+ if (raw.runId !== runId) {
228
+ throw new Error(`checkpoint runId mismatch: requested ${runId}, file has ${raw.runId}`);
229
+ }
230
+ const expected = bundleSha256(raw);
231
+ if (raw.sha256 !== expected) {
232
+ throw new Error(`checkpoint sha256 mismatch: ${raw.sha256} != ${expected}`);
233
+ }
234
+ return raw;
235
+ }