elanous 0.2.22 → 0.2.23
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.
- package/NOTICE +7 -0
- package/README.md +32 -22
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/chunks/{119fc678.6f591cdb84ca5791.js → 0673cc54.8e2ef1c23e49e190.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{a9f2b54d-40c16bd0efdb04b8.js → 0a09e062-34f747a17d8d8c2e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{f8626309.a4e5d362b1d55e59.js → 0e3acd34.d42b2ef87fdf4234.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +77 -0
- package/apps/pwa/out/_next/static/chunks/{7175-350f4ce2873bc038.js → 1325-dc3f3c21eb181cb4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +34 -0
- package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +24 -0
- package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6767.8e6c5f6e744fcd9f.js → 1505.5826671109111e75.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7327-2d69fb321ba73389.js → 1669-da843ed73aa301f5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +36 -0
- package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +122 -0
- package/apps/pwa/out/_next/static/chunks/2528.0af5c0e1fad88df6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +62 -0
- package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/272-b23d2e92161d11fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7899.597af4a9996c907f.js → 2721.bc9a8f36bd85c07a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +149 -0
- package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3961-fbef064c213b2b18.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +309 -0
- package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{d70879db.c66c56a95a91efc6.js → 4c5e95ce.83e9b16add6fcd8c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6158.566c890adc06a459.js → 5313.1697309c532b9856.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{79b78388.663188133449d707.js → 53746282.1be36038d1abd949.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5578.ac963634373b28c6.js +286 -0
- package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5967-c0a80f8ffe5d4050.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1268.0840ff91e083fcbd.js → 5974.360f8441eb0ac1ec.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +74 -0
- package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6571-926ddf024a6ad5df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +64 -0
- package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9832.2ab2e818013574c7.js → 6702.ebbd165d5e4a4a14.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +32 -0
- package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +24 -0
- package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +93 -0
- package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6110.1297d4093fdfbb0d.js → 740.90b31555290236a9.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +148 -0
- package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +226 -0
- package/apps/pwa/out/_next/static/chunks/{9070.067c106528ec1ae6.js → 7518.49161e8f5814abdb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +27 -0
- package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +115 -0
- package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7905.b230b9d06cb4ad5d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8194.484f51e273d9abd2.js → 8264.00e434fbd02e9311.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +8 -0
- package/apps/pwa/out/_next/static/chunks/{088d8e8a.8069543d082bec12.js → 83cfc5c8.349535543c1548b6.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +23 -0
- package/apps/pwa/out/_next/static/chunks/{1948.5f35b39eef222a94.js → 8438.ee7f0df3b3f6fcb4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4588.ad3364cb7fb97ada.js → 8532.a86e99acf9b761cb.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/8569.b853a8daa8f31d12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +1 -0
- package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8925-2abfb48af477fb7f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{88729267.9c6c000157c83f2f.js → 89849432.9eaa2f4c9c010965.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +90 -0
- package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +94 -0
- package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +41 -0
- package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +287 -0
- package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +79 -0
- package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{3522-1de1319d028ac89c.js → 9502-32c5dc22e8f120f5.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +104 -0
- package/apps/pwa/out/_next/static/chunks/{7630.2b9a68659053ff4e.js → 9976.8f28864317639fe6.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-d5341ac96203a983.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-0160ab83c8685a12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-55c631c032dcc47e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-ad3bd8084048bee4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-e6784759a2531031.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-5c5d0e370f495ef6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-c325e21543cd48a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/{page-80ed511e02c81412.js → page-6168a7c43e6ef8f5.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-31417d3604154a6d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-e9606dc0bdec9305.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-a648bc464c9dc754.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-25bb425afdb27541.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-32d72fdef1afe11a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-d27b794c8ba76bbb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-2bd9ce9c020d02d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a34096245e63b9f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-22170f4f00a15496.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-4cc66d22ca4ec502.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-83b14c729fcea837.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-6e2781c523dad761.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-26dd415c8f13f341.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-ccdb83ed40c8d724.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-7ad3de8fa06fdea9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-015c02c4fec4023e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-6b0ae5b5c42f6d2f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-786111f30b6f0969.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-48fb31810693c357.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-4e17cce5e2ed0fee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-cb154acadb025414.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-16258e956ea93fc2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-c2dd2b19c93f90ab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-85f35dd1dd96ae87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-d3c007c8a0ddd7ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-7837ce2aacb97b04.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-7350ee93f4fe1033.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-00723458575f2b19.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-745d9b6c015076f8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-736d33c7414a8a1a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-119be9a0444d2482.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-fa806c018833e332.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-c782041b5f5199ba.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-d431fbdea6ad93dd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-0c056abff82b9891.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-242d668e4fbf72c4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-847c3de6ca8a4416.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-81dd0d8ae923ed72.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-74e69ba2c8e970d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-70038f41ae7cf931.js +1 -0
- package/apps/pwa/out/_next/static/chunks/b4e12462-5fab4a813a63dadd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{f6b7c9ba.64a895b8b2fedbdc.js → ce383d63.d2ede338788ed18e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{framework-5c169757551134ed.js → framework-b2763b10dc6b3836.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +1 -0
- package/apps/pwa/out/_next/static/css/5619d59e87eddf66.css +1 -0
- package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +1 -0
- package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → rfkMm4movqkqMebBrCXiR}/_buildManifest.js +1 -1
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +23 -23
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +24 -23
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +22 -22
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +23 -23
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +24 -23
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/catalog/models/anthropic/claude-haiku-5-5.yaml +32 -0
- package/catalog/models/anthropic/claude-opus-5-5.yaml +5 -0
- package/catalog/models/anthropic/claude-sonnet-5-5.yaml +31 -0
- package/catalog/models/anthropic/claude-sonnet-5.yaml +8 -2
- package/catalog/models/openai/gpt-6-astra.yaml +6 -0
- package/catalog/models/openai/gpt-6-luna.yaml +6 -0
- package/catalog/models/openai/gpt-6-sol.yaml +6 -0
- package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
- package/graphs/log-horizon/recipes.yaml +3 -0
- package/graphs/release/recipes.yaml +1 -1
- package/graphs/release/release-loop.yaml +6 -2
- package/graphs/release-rehearsal/recipes.yaml +12 -0
- package/graphs/release-rehearsal/release-rehearsal.yaml +17 -0
- package/package.json +4 -1
- package/scripts/bench-report.ts +82 -3
- package/scripts/ci-typecheck-changed.ts +10 -1
- package/scripts/hq/hq-fence-wrapper.sh +148 -0
- package/scripts/lib/typecheck-ratchet.ts +51 -0
- package/scripts/openai-relay-server.ts +5 -1
- package/scripts/release-loop/docs-node.ts +258 -43
- package/scripts/release-loop/gate-method.ts +59 -0
- package/scripts/release-loop/gate-node.ts +73 -7
- package/scripts/release-loop/gate-wall.ts +208 -0
- package/scripts/release-loop/known-issues-node.ts +53 -8
- package/scripts/release-loop/publish-at.ts +14 -0
- package/scripts/release-loop/publish-node.ts +17 -2
- package/scripts/release-loop/resume-release.ts +34 -4
- package/scripts/release-loop/resume.ts +53 -0
- package/scripts/release-loop/shard-plan.ts +3 -11
- package/scripts/release-loop/tui-node-checks.ts +22 -0
- package/scripts/release-loop/unattended-release.ts +8 -1
- package/scripts/rhythm/daily.ts +51 -2
- package/scripts/rhythm/weekly.ts +3 -2
- package/scripts/tsc-main-safety-net.ts +189 -0
- package/scripts/usage-rollup.ts +8 -4
- package/src/acp/codex-plugins.ts +48 -6
- package/src/agent/monad-agent-turn.ts +67 -5
- package/src/agent/run-context.ts +10 -0
- package/src/agent/tool-profile.ts +28 -2
- package/src/agent-mission/acp-judge.ts +8 -2
- package/src/agent-mission/capabilities-cli.ts +16 -1
- package/src/agent-mission/driver.ts +1 -1
- package/src/agent-mission/pr-review-watch.ts +6 -2
- package/src/agent-mission/review-loop.ts +33 -5
- package/src/agent-substrate/acp-reviewer.ts +17 -8
- package/src/agent-substrate/pr-reviewer.ts +164 -28
- package/src/agent-substrate/review-intent.ts +6 -4
- package/src/agent-substrate/self-review-cli.ts +111 -16
- package/src/agent-substrate/shard-boundary-intent.ts +92 -26
- package/src/ask-user-question/pending-questions.ts +8 -2
- package/src/autopilot/build/llm-conflict-merge.ts +216 -12
- package/src/autopilot/codebase-grounding.ts +44 -0
- package/src/autopilot/llm-control-brain.ts +13 -1
- package/src/autopilot/mission-codebase-gate.ts +8 -77
- package/src/autopilot/pr-manager.ts +12 -3
- package/src/boot/acp-server.ts +4 -7
- package/src/boot/acp-socket-path.ts +7 -0
- package/src/briefing/brief-items.ts +21 -13
- package/src/chat/index.ts +12 -3
- package/src/cli/agent-cli.ts +20 -0
- package/src/cli/brief-cli.ts +27 -21
- package/src/cli/cli-user-error.ts +9 -2
- package/src/cli/log-event-names.ts +3 -0
- package/src/cli/logs-cli.ts +1 -0
- package/src/cli/mcp-login.ts +111 -37
- package/src/cli/plugin-cli.ts +21 -1
- package/src/cli/pod-cli.ts +26 -0
- package/src/cli/pr-cli.ts +30 -2
- package/src/cli/pr-land-overlap-evidence.ts +131 -0
- package/src/cli/release-cli.ts +53 -11
- package/src/cli/self-update.ts +173 -10
- package/src/cli/skills-cli.ts +12 -3
- package/src/cli/tasks-cli.ts +133 -27
- package/src/context-bus/context-first.ts +51 -2
- package/src/context-bus/context-now-surfaces.ts +13 -2
- package/src/context-bus/long-term-memory.ts +3 -1
- package/src/context-bus/nightly-condense.ts +3 -2
- package/src/core-turn/run-goal-loop.ts +86 -2
- package/src/dashboard/chat-fold.ts +20 -0
- package/src/dashboard/first-screen-band.ts +151 -1
- package/src/dashboard/index.ts +27 -5
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +5 -3
- package/src/dashboard/stale-install-check.ts +13 -2
- package/src/dashboard/turn-stream-formatter.ts +25 -0
- package/src/debug/log-diet.ts +159 -0
- package/src/debug/log.ts +52 -17
- package/src/display/coordinator.ts +25 -2
- package/src/domains/coo-admin-tool.ts +27 -0
- package/src/domains/cron-match.ts +1 -0
- package/src/domains/outbound-alert.ts +17 -6
- package/src/domains/release-tool.ts +119 -10
- package/src/domains/schedule-registry.ts +10 -7
- package/src/domains/schedule-runner.ts +1 -0
- package/src/elanous-config-dir.ts +2 -2
- package/src/elanous-daemon.ts +3 -3
- package/src/execution-loop/launch-gate.ts +1 -1
- package/src/expression/i18n/messages.en.ts +5 -0
- package/src/expression/i18n/messages.ja.ts +5 -0
- package/src/expression/i18n/messages.ko.ts +5 -0
- package/src/expression/i18n/messages.zh.ts +5 -0
- package/src/expression/i18n/types.ts +8 -0
- package/src/github/pr-labels.ts +1 -0
- package/src/graph-runner/runner.ts +54 -5
- package/src/harness/dispatch-backpressure.ts +259 -0
- package/src/harness/harness-cli-command.ts +107 -28
- package/src/harness/harness-seams.ts +2 -20
- package/src/harness/harness-substrate-default.ts +72 -1
- package/src/harness/nested-elanous-policy.ts +4 -2
- package/src/hq/fence-wrapper.ts +7 -0
- package/src/hq/hq.ts +33 -2
- package/src/hq/lease.ts +13 -0
- package/src/hq/seats.ts +114 -18
- package/src/index.ts +163 -64
- package/src/intake-plane/collect-github.ts +19 -1
- package/src/intake-plane/digest.ts +45 -20
- package/src/intake-plane/lens.ts +36 -8
- package/src/intelligence-map/model-alias.ts +6 -0
- package/src/intelligence-map/model-catalog.ts +41 -0
- package/src/knowledge/kgs/pack.ts +5 -2
- package/src/knowledge/kgs/sqlite-store.ts +15 -0
- package/src/knowledge/tools/knowledge-query.ts +20 -2
- package/src/knowledge/write.ts +234 -2
- package/src/llm/bedrock-provider.ts +175 -0
- package/src/llm/bedrock.ts +345 -0
- package/src/llm/provider-credentials.ts +3 -1
- package/src/llm.ts +306 -35
- package/src/loops/budget.ts +150 -0
- package/src/loops/orchestrator/seat-share.ts +6 -49
- package/src/loops/orchestrator/traffic.ts +5 -81
- package/src/market/signed-index.ts +42 -0
- package/src/mcp/mcp-oauth.ts +136 -17
- package/src/model-tier/llm-tier-map.ts +48 -4
- package/src/models/prompts.ts +22 -1
- package/src/mss/logging/horizon-watch.ts +168 -0
- package/src/mss/logging/log-store.ts +204 -15
- package/src/native-tool-catalog.ts +1 -1
- package/src/nexus/api/consult-requests.ts +7 -10
- package/src/nexus/api/discord-trigger-bot.ts +6 -3
- package/src/nexus/api/error-reports.ts +30 -8
- package/src/nexus/api/http-server.ts +8 -0
- package/src/nexus/api/loop-resources.ts +42 -0
- package/src/nexus/api/outbound-report.ts +8 -3
- package/src/nexus/api/telegram-trigger-bot.ts +6 -3
- package/src/nexus/index.ts +10 -0
- package/src/nexus/outbound/format.ts +2 -0
- package/src/nexus/outbound/router.ts +198 -13
- package/src/oauth/codex-account-rotation.ts +16 -18
- package/src/oauth/codex-account-store.ts +134 -5
- package/src/oauth/fallback-chain.ts +28 -6
- package/src/onboarding.ts +2 -1
- package/src/plugins/adapters/claude-package.ts +4 -12
- package/src/plugins/core/capability-policy.ts +141 -0
- package/src/plugins/core/host.ts +21 -8
- package/src/plugins/core/manifest.ts +19 -2
- package/src/plugins/core/trust-store.ts +15 -0
- package/src/plugins/core/types.ts +12 -0
- package/src/plugins/install/market-fetch.ts +68 -16
- package/src/plugins/install/plugin-install.ts +187 -16
- package/src/plugins/maker/plugin-maker.ts +25 -20
- package/src/plugins/maker/wizard-generate.ts +16 -2
- package/src/policy/llm-policy.ts +14 -1
- package/src/process/pid-liveness.ts +1 -1
- package/src/prompt-cache/openai.ts +10 -6
- package/src/prompt-cache/openrouter.ts +94 -0
- package/src/prompt-enhance/enhance.ts +46 -5
- package/src/prompt-library/family-prompt-coverage.ts +1 -0
- package/src/prompt-library/universal-preamble.ts +2 -2
- package/src/registry/discovery/openrouter-live-resolve.ts +122 -0
- package/src/registry/loader.ts +6 -1
- package/src/release-loop/checklist.ts +24 -9
- package/src/release-loop/feature-store.ts +3 -0
- package/src/release-loop/gate-shards.ts +48 -4
- package/src/release-loop/landed-to-green.ts +81 -0
- package/src/release-loop/light-rc.ts +11 -1
- package/src/release-loop/merged-pr-checklist.ts +10 -0
- package/src/release-loop/placement.ts +91 -22
- package/src/release-loop/rehearsal.ts +317 -0
- package/src/release-loop/release-schedule.ts +13 -1
- package/src/release-loop/rubric-types.ts +1 -0
- package/src/release-loop/rubric.ts +2 -2
- package/src/retro/daily.ts +23 -9
- package/src/seat-loop/seat-loop.ts +34 -1
- package/src/seat-loop/traffic-signal.ts +44 -0
- package/src/self-dev/ask-launch-flow.ts +2 -2
- package/src/self-dev/dev-cli.ts +67 -3
- package/src/self-dev/dev-pipeline.ts +4 -6
- package/src/self-dev/draft-residue.ts +463 -0
- package/src/self-dev/draft-sweep.ts +151 -10
- package/src/self-dev/draft-triage-rules.ts +27 -1
- package/src/self-dev/launch-preflight-text.ts +549 -0
- package/src/self-dev/launch-preflight.ts +10 -545
- package/src/self-dev/orchestrate-cli.ts +57 -2
- package/src/self-dev/orchestrate-summary-line.ts +13 -0
- package/src/self-dev/orchestrate.ts +8 -135
- package/src/self-dev/review-provider-fallback.ts +115 -19
- package/src/self-dev/run-store.ts +1 -3
- package/src/self-dev/run-supervisor.ts +3 -22
- package/src/self-dev/run-types.ts +178 -0
- package/src/self-dev/shard-aggregate.ts +61 -13
- package/src/self-dev/shard-plan.ts +5 -1
- package/src/self-dev/shard-run.ts +23 -5
- package/src/self-dev/supervisor-verdict-edges.ts +2 -4
- package/src/self-implement/blocked-draft-policy.ts +3 -19
- package/src/self-implement/draft-on-stop-mode.ts +18 -0
- package/src/self-implement/follow-up-goals.ts +114 -38
- package/src/self-implement/gate-baseline-reap.ts +157 -0
- package/src/self-implement/gate-baseline.ts +78 -16
- package/src/self-implement/gate-cli.ts +12 -2
- package/src/self-implement/gate-remote.ts +17 -6
- package/src/self-implement/goal-author.ts +24 -4
- package/src/self-implement/goal-digest.ts +19 -0
- package/src/self-implement/graph-overlay-condition.ts +4 -0
- package/src/self-implement/headless-elanous-driver.ts +11 -9
- package/src/self-implement/host-regate.ts +120 -29
- package/src/self-implement/l8-merge-queue.ts +67 -5
- package/src/self-implement/merge-train.ts +131 -0
- package/src/self-implement/off-diff-evidence.ts +9 -0
- package/src/self-implement/orchestrator.ts +133 -16
- package/src/self-implement/review-finding-recurrence.ts +28 -0
- package/src/self-implement/rework-policy.ts +2 -1
- package/src/self-implement/round-summary-card.ts +63 -0
- package/src/self-implement/run-ledger.ts +4 -3
- package/src/self-implement/run-step-projection.ts +147 -0
- package/src/self-implement/run-stop.ts +1 -1
- package/src/self-implement/seams.ts +36 -3
- package/src/self-implement/self-implement-cli.ts +3 -1
- package/src/self-implement/train-gate-remote.ts +158 -0
- package/src/session-runtime/index.ts +10 -1
- package/src/session-runtime/retry-api.ts +11 -1
- package/src/skills/gift-install.ts +119 -0
- package/src/skills/runner.ts +59 -2
- package/src/skills/skill-feedback.ts +31 -1
- package/src/skills/skill-tier.ts +1 -0
- package/src/smart-wizard/capability-index.ts +231 -0
- package/src/smart-wizard/rung.ts +74 -0
- package/src/steward/launch.ts +20 -9
- package/src/steward/triage.ts +4 -2
- package/src/storage/file-lock.ts +8 -1
- package/src/task-agent/actions.ts +4 -0
- package/src/task-agent/card-evidence.ts +59 -13
- package/src/task-agent/judge.ts +4 -3
- package/src/task-agent/land-worktree.ts +201 -0
- package/src/task-agent/live-move-history.ts +133 -0
- package/src/task-agent/live-moves.ts +106 -19
- package/src/task-agent/parent-host.ts +117 -8
- package/src/task-agent/rejudge-on-head.ts +297 -0
- package/src/task-agent/review-result-capture.ts +218 -0
- package/src/task-agent/shadow.ts +103 -7
- package/src/task-agent/task-hand.ts +136 -11
- package/src/task-orchestrator/surfaces/pod-child-providers.ts +29 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +16 -2
- package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
- package/src/task-orchestrator/surfaces/pod-lease.ts +93 -12
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +25 -2
- package/src/task-orchestrator/surfaces/pod-pool.ts +66 -14
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +259 -36
- package/src/task-orchestrator/surfaces/self-implement.ts +6 -2
- package/src/telegram-service.ts +5 -1
- package/src/telegram.ts +17 -4
- package/src/time/format.ts +13 -4
- package/src/tool-runtime/goal-author-runtime.ts +1 -0
- package/src/tool-runtime/self-cognition-catalog.ts +23 -0
- package/src/tool-runtime/self-cognition-runtimes.ts +2 -24
- package/src/user-config.ts +132 -24
- package/src/ux-sim/slash-menu-frames.ts +168 -0
- package/src/version/packed-revision.json +1 -1
- package/src/web-terminal/preview-tap-registry.ts +5 -2
- package/src/workflow-runtime/triggers/scheduler.ts +1 -0
- package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +0 -148
- package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +0 -32
- package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +0 -309
- package/apps/pwa/out/_next/static/chunks/1307-08b716476f1d50af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +0 -122
- package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +0 -149
- package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +0 -79
- package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +0 -24
- package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +0 -27
- package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/211-9c9090c59e2c5907.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +0 -36
- package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +0 -286
- package/apps/pwa/out/_next/static/chunks/2489-d238d3e2eb5b2bf5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +0 -94
- package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3857-5985236d9307f676.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +0 -74
- package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +0 -34
- package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +0 -115
- package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +0 -77
- package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5633-d6852385000738ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +0 -90
- package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5977-5b9e8a45a5b0c823.js +0 -1
- package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +0 -8
- package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +0 -64
- package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +0 -287
- package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +0 -226
- package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +0 -41
- package/apps/pwa/out/_next/static/chunks/726.83532d69452ee24b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +0 -24
- package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +0 -104
- package/apps/pwa/out/_next/static/chunks/8857-aa1cc4ac90af4d40.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +0 -93
- package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9247-55bcfbb0e8057f59.js +0 -1
- package/apps/pwa/out/_next/static/chunks/935.4ddaa99fc1d1126c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +0 -23
- package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +0 -62
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-88459e0903da2803.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d85c43f46f58716b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-4e645600579ae952.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-87edbfd19117823b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-7f0c2b7801ac6a54.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-bf1f030a9d1adffd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-cbaf66b1e1804adf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-9f5610caaa06178c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-ec8f3575e339de74.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-86d753e460f1a989.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-4166a7d51cf0a57d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-2a19c5cd3b562580.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-b6a09cde2e07521a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-f7eae1518ca0c353.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-456a8573ad811381.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-8462d6a543cbb2d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-2974cdfb87c0f9c9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-f927ffa25f3c86d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-abd86cd832aaa011.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-79daf68f6256adaa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8c3f168fc3f91939.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-786fb4504d0f2fa9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-75209f14597dcb8f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-bf30affe3a85af7e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1187a44b7515434b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-3d0910185a66ed54.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f401ee1dd5a26e25.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-5dfe7604fd842784.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-76cf838050a8d681.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-7ec8e289b4c14df6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-8c8ac17d52be2a79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-d359ab048d63a9d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-b8b345c880bf78d1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-f151cc10ad026940.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-9875f103057da433.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-9789328af9a9aa62.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-bf495a1e284f4e00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-a263d94bca4be22a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-3962eab8ec58d16e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-9abcfac07e02a542.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-bee49f927c333abb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-bac2d56dcb02d955.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-937cbcc13176295c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-d09495594f7f480d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-69cb93d1a2e57e0e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-72ec543928d67c3e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-82906eeda0186a7b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/f6231284-45726550aba08fca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +0 -1
- package/apps/pwa/out/_next/static/css/f2bd5257e6af88d8.css +0 -1
- /package/apps/pwa/out/_next/static/{aBi6EyMtLsrl7J8eH4kF7 → rfkMm4movqkqMebBrCXiR}/_ssgManifest.js +0 -0
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import { chmodSync, existsSync, readdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
3
|
-
import { randomUUID } from 'node:crypto';
|
|
4
|
-
import { spawnSync } from 'node:child_process';
|
|
5
|
-
import {
|
|
2
|
+
import { chmodSync, existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
4
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
5
|
+
import { isAbsolute, basename, dirname, join, resolve } from 'node:path';
|
|
6
6
|
import { tmpdir } from 'node:os';
|
|
7
|
-
import { basename, dirname, join, resolve } from 'node:path';
|
|
8
7
|
import { debug } from '../../src/debug/log.js';
|
|
9
8
|
import { effectiveInstanceRoot } from '../../src/instance/resolve.js';
|
|
10
9
|
import type { ReleaseManifest } from '../../src/release-loop/manifest.js';
|
|
11
10
|
import { flipNextReleaseMarkers, foldPreLandedNotes, renderReleaseNotes } from './release-docs.js';
|
|
12
|
-
import { emitNodeResult, readGraphContext } from './node-verdict.js';
|
|
11
|
+
import { emitNodeResult, lastResult, nodeOutput, readGraphContext, type GraphContext } from './node-verdict.js';
|
|
12
|
+
import { reusableTui, withTuiOutcome } from './tui-node-checks.js';
|
|
13
13
|
|
|
14
14
|
interface DocsResult {
|
|
15
15
|
outcome: 'ok' | 'error';
|
|
@@ -126,47 +126,262 @@ export function runDocs(
|
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
// Prefetch artifacts live alongside THIS graph run's numbered context files, never in a global version cache.
|
|
130
|
+
const SHA = /^[0-9a-f]{40}$/i;
|
|
131
|
+
const PREFETCH_DEADLINE_MS = 15 * 60_000;
|
|
132
|
+
type Cut = { version: string; commit: string; manifestHash: string };
|
|
133
|
+
type PrefetchCache = Cut & { main: string; tree: string; docs: DocsResult; tui: Record<string, unknown> | null };
|
|
134
|
+
type Runner = (command: string, args: string[], cwd?: string, timeout?: number, env?: NodeJS.ProcessEnv) => string;
|
|
135
|
+
export const commandRunner: Runner = (command, args, cwd, timeout, env) => {
|
|
136
|
+
const output = spawnSync(command, args, { cwd, env: env ?? process.env, timeout: timeout ?? 15 * 60_000, encoding: 'utf8', maxBuffer: 16 * 1024 * 1024 });
|
|
137
|
+
if (output.status !== 0 || output.error) throw new Error(`${command} ${args[0]} failed: ${output.error ?? output.stderr ?? output.stdout}`);
|
|
138
|
+
return output.stdout.trim();
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
function runCacheDir(env: NodeJS.ProcessEnv): string {
|
|
142
|
+
const path = env.ELANOUS_GRAPH_CONTEXT;
|
|
143
|
+
if (!path || !isAbsolute(path) || !/^\d+\.json$/.test(basename(path)) || !dirname(path).endsWith('.json.contexts')) {
|
|
144
|
+
throw new Error('prefetch requires an absolute graph run context file');
|
|
145
|
+
}
|
|
146
|
+
return join(dirname(path), 'docs-prefetch');
|
|
147
|
+
}
|
|
148
|
+
function cutFor(context: GraphContext, stateRoot: string): Cut {
|
|
149
|
+
const version = context.input.version;
|
|
150
|
+
const commit = nodeOutput(context, 'version-release', 'commit');
|
|
151
|
+
if (context.outputs['version-release']?.outcome !== 'ok' || !SHA.test(commit)) throw new Error('invalid release commit');
|
|
152
|
+
const raw = readFileSync(join(stateRoot, 'release', version, 'manifest.json'));
|
|
153
|
+
const manifest = JSON.parse(raw.toString()) as ReleaseManifest;
|
|
154
|
+
if (manifest.version !== version || manifest.cutoff?.sha !== commit || !Array.isArray(manifest.in)) throw new Error('manifest cutoff differs from release commit');
|
|
155
|
+
return { version, commit, manifestHash: createHash('sha256').update(raw).digest('hex') };
|
|
156
|
+
}
|
|
157
|
+
/** Exclusive create — true iff this caller is the first to claim the run's prefetch slot. */
|
|
158
|
+
function claimPrefetch(dir: string, owner: 'worker' | 'docs'): boolean {
|
|
159
|
+
try { writeFileSync(join(dir, 'claim'), owner, { flag: 'wx' }); return true; }
|
|
160
|
+
catch (error) { if ((error as NodeJS.ErrnoException).code === 'EEXIST') return false; throw error; }
|
|
161
|
+
}
|
|
162
|
+
function cacheFile(dir: string, cut: Cut): string {
|
|
163
|
+
return join(dir, `${cut.commit}-${cut.manifestHash}.json`);
|
|
164
|
+
}
|
|
165
|
+
function loadCache(dir: string, cut: Cut): PrefetchCache | null {
|
|
166
|
+
try {
|
|
167
|
+
const value = JSON.parse(readFileSync(cacheFile(dir, cut), 'utf8')) as PrefetchCache;
|
|
168
|
+
if (value.version !== cut.version || value.commit !== cut.commit || value.manifestHash !== cut.manifestHash
|
|
169
|
+
|| !SHA.test(value.main) || value.tree !== join(dir, 'tree') || !existsSync(value.tree)
|
|
170
|
+
|| value.docs?.outcome !== 'ok' || value.docs.version !== cut.version
|
|
171
|
+
|| value.docs.notes !== join(value.tree, 'release/public/docs/releases', `${cut.version}.md`)
|
|
172
|
+
|| value.docs.pages !== join(value.tree, 'website/pages.json')
|
|
173
|
+
|| !existsSync(value.docs.notes) || !existsSync(value.docs.pages)) return null;
|
|
174
|
+
return value;
|
|
175
|
+
} catch { return null; }
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Worker performs ONLY local reads and temporary worktree writes; failure is a cache miss, not a gate failure. */
|
|
179
|
+
export function stagePrefetch(context: GraphContext, env: NodeJS.ProcessEnv = process.env, repo = process.cwd(),
|
|
180
|
+
runner: Runner = commandRunner, deps: { stateRoot?: string; tui?: (commit: string) => Record<string, unknown> | null; deadline?: number } = {}): PrefetchCache {
|
|
181
|
+
// One whole-worker deadline: every step gets at most the time left, and no step starts after it.
|
|
182
|
+
const deadline = deps.deadline ?? Date.now() + PREFETCH_DEADLINE_MS;
|
|
183
|
+
const left = () => {
|
|
184
|
+
const ms = deadline - Date.now();
|
|
185
|
+
if (ms <= 0) throw new Error('prefetch worker deadline exceeded');
|
|
186
|
+
return ms;
|
|
187
|
+
};
|
|
188
|
+
const run: Runner = (command, args, cwd, timeout, childEnv) => runner(command, args, cwd, Math.min(timeout ?? 15 * 60_000, left()), childEnv);
|
|
189
|
+
const dir = runCacheDir(env);
|
|
190
|
+
const stateRoot = deps.stateRoot ?? effectiveInstanceRoot();
|
|
191
|
+
const cut = cutFor(context, stateRoot);
|
|
192
|
+
mkdirSync(dir, { recursive: true });
|
|
193
|
+
const already = loadCache(dir, cut);
|
|
194
|
+
if (already) return already;
|
|
195
|
+
const tree = join(dir, 'tree');
|
|
196
|
+
let added = false;
|
|
133
197
|
try {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
198
|
+
const main = run('git', ['rev-parse', '--verify', 'origin/main^{commit}'], repo);
|
|
199
|
+
if (!SHA.test(main)) throw new Error('invalid origin/main commit');
|
|
200
|
+
// TUI runs against the cut, on its own isolated worktree, before touching the docs checkout.
|
|
201
|
+
// tui-sim-node.ts prints the RAW result (no `outcome`); judge it the way node-verdict.ts tui would before reuse.
|
|
202
|
+
const tuiData = deps.tui ? deps.tui(cut.commit) : (() => {
|
|
203
|
+
const tuiRun = spawnSync('bun', ['scripts/release-loop/tui-sim-node.ts', '--commit', cut.commit, '--json'], {
|
|
204
|
+
cwd: repo, timeout: Math.min(6 * 60_000, left()), encoding: 'utf8', maxBuffer: 16 * 1024 * 1024,
|
|
205
|
+
});
|
|
206
|
+
return tuiRun.status === 0 ? lastResult({ status: tuiRun.status, stdout: tuiRun.stdout ?? '', stderr: tuiRun.stderr ?? '' }) ?? null : null;
|
|
207
|
+
})();
|
|
208
|
+
const tui = reusableTui(withTuiOutcome(0, tuiData), cut.commit);
|
|
209
|
+
run('git', ['worktree', 'add', '--detach', tree, main], repo);
|
|
210
|
+
added = true;
|
|
211
|
+
run('bun', ['install', '--frozen-lockfile'], tree);
|
|
212
|
+
// Docs staging runs as its own process so the whole-worker deadline can stop it (an in-process call could not be).
|
|
213
|
+
const docsOut = run(process.execPath, [resolve(import.meta.filename), '--version', cut.version, '--base', tree, '--json'], repo, undefined,
|
|
214
|
+
{ ...process.env, ELANOUS_GRAPH_CONTEXT: '', ELANOUS_STATE_DIR: stateRoot });
|
|
215
|
+
const docs = JSON.parse(docsOut.trim().split('\n').at(-1) ?? 'null') as DocsResult;
|
|
216
|
+
if (!docs || typeof docs !== 'object') throw new Error('docs staging returned no result');
|
|
217
|
+
if (docs.outcome !== 'ok') throw new Error(docs.error ?? 'docs staging failed');
|
|
218
|
+
// Recheck the cut before publishing an atomic result; stale results are never reused.
|
|
219
|
+
left();
|
|
220
|
+
const finalCut = cutFor(context, stateRoot);
|
|
221
|
+
if (finalCut.manifestHash !== cut.manifestHash) throw new Error('manifest changed during prefetch');
|
|
222
|
+
const result: PrefetchCache = { ...cut, main, tree, docs, tui };
|
|
223
|
+
const final = cacheFile(dir, cut);
|
|
224
|
+
const staged = `${final}.${process.pid}.${randomUUID()}.tmp`;
|
|
225
|
+
writeFileSync(staged, JSON.stringify(result) + '\n');
|
|
226
|
+
// Publication handshake: whoever creates `claim` first (O_EXCL) wins. The docs node claims before it reads,
|
|
227
|
+
// so a worker that loses can never publish a cache that a docs attempt would consume.
|
|
228
|
+
if (!claimPrefetch(dir, 'worker')) {
|
|
229
|
+
rmSync(staged, { force: true });
|
|
230
|
+
throw new Error('docs node already ran; late prefetch is discarded');
|
|
137
231
|
}
|
|
232
|
+
renameSync(staged, final);
|
|
233
|
+
return result;
|
|
138
234
|
} catch (error) {
|
|
139
|
-
|
|
235
|
+
if (added) { try { runner('git', ['worktree', 'remove', '--force', tree], repo, 60_000); } catch { /* preserve original failure */ } }
|
|
236
|
+
throw error;
|
|
140
237
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/** TUI is measured against the cut commit, so reuse keys on commit ⊕ manifest hash only — origin/main is a docs-tree input, not a TUI input. */
|
|
241
|
+
export function joinTui(context: GraphContext, env: NodeJS.ProcessEnv, repo: string,
|
|
242
|
+
fallback: (commit: string) => { status: number | null; stdout: string; stderr: string } = (commit) => {
|
|
243
|
+
const output = spawnSync('bun', ['scripts/release-loop/node-verdict.ts', 'tui'], {
|
|
244
|
+
cwd: repo, env, encoding: 'utf8', timeout: 7 * 60_000, maxBuffer: 16 * 1024 * 1024,
|
|
245
|
+
});
|
|
246
|
+
return { status: output.status, stdout: output.stdout ?? '', stderr: output.stderr ?? '' };
|
|
247
|
+
}, stateRoot = effectiveInstanceRoot()): Record<string, unknown> {
|
|
248
|
+
if (context.outputs.upgrade?.outcome !== 'ok') throw new Error('upgrade did not pass');
|
|
249
|
+
// Any failure to key the cache (no manifest, cutoff mismatch, no run dir) is a cache miss → original TUI path.
|
|
250
|
+
let cut: Cut | null = null;
|
|
251
|
+
let cached: PrefetchCache | null = null;
|
|
252
|
+
try { cut = cutFor(context, stateRoot); cached = loadCache(runCacheDir(env), cut); } catch { /* cache miss */ }
|
|
253
|
+
const reused = cut && cached?.tui && reusableTui(cached.tui, cut.commit);
|
|
254
|
+
if (reused) return { ...reused, outcome: 'ok', summary: `tui ${reused.verdict}` };
|
|
255
|
+
// Preserve node-verdict.ts's exit convention and last-JSON output on a cache miss.
|
|
256
|
+
const output = fallback(cut?.commit ?? String(context.outputs['version-release']?.commit ?? ''));
|
|
257
|
+
const data = lastResult(output);
|
|
258
|
+
if (!data) throw new Error(`tui fallback returned no verdict: ${output.stderr}`);
|
|
259
|
+
// A timed-out or crashed fallback never passes on an earlier success line: exit status, outcome and verdict must agree.
|
|
260
|
+
// node-verdict.ts convention: ok ↔ exit 0 with pass|flaky · fail ↔ exit 1 with fail · error ↔ exit 2.
|
|
261
|
+
const agrees = output.status === 0 ? data.outcome === 'ok' && (data.verdict === 'pass' || data.verdict === 'flaky')
|
|
262
|
+
: output.status === 1 ? data.outcome === 'fail' && data.verdict === 'fail'
|
|
263
|
+
: output.status === 2 ? data.outcome === 'error' && data.verdict === 'fail' : false;
|
|
264
|
+
if (!agrees) {
|
|
265
|
+
throw new Error(`tui fallback exited ${output.status} with outcome ${String(data.outcome)} / verdict ${String(data.verdict)}`);
|
|
266
|
+
}
|
|
267
|
+
return data;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export function graphDocs(context: GraphContext, env: NodeJS.ProcessEnv, repo: string, run: Runner = commandRunner,
|
|
271
|
+
stateRoot = effectiveInstanceRoot()): DocsResult {
|
|
272
|
+
const version = context.input.version;
|
|
273
|
+
let tree: string | undefined;
|
|
274
|
+
// Before ANY check (and so also on every failure path): only the first docs attempt may consume a staged cache,
|
|
275
|
+
// and only when the worker won the claim; otherwise this attempt claims the slot so a late worker cannot publish.
|
|
276
|
+
let mayConsume = false;
|
|
277
|
+
let cacheDir: string | undefined;
|
|
278
|
+
try {
|
|
279
|
+
cacheDir = runCacheDir(env);
|
|
280
|
+
mkdirSync(cacheDir, { recursive: true });
|
|
281
|
+
const closed = join(cacheDir, 'docs-closed');
|
|
282
|
+
const firstAttempt = !existsSync(closed);
|
|
283
|
+
writeFileSync(closed, `${new Date().toISOString()}\n`);
|
|
284
|
+
const docsWon = claimPrefetch(cacheDir, 'docs');
|
|
285
|
+
mayConsume = firstAttempt && !docsWon && readFileSync(join(cacheDir, 'claim'), 'utf8') === 'worker';
|
|
286
|
+
} catch { /* standalone/legacy graph — no prefetch */ }
|
|
287
|
+
try {
|
|
288
|
+
// No fetch (nor any write to remote) until every gate is verified.
|
|
289
|
+
for (const node of ['gate', 'prepare', 'upgrade', 'tui']) if (context.outputs[node]?.outcome !== 'ok') throw new Error(`${node} did not pass`);
|
|
290
|
+
let cached: PrefetchCache | null = null;
|
|
291
|
+
// A cache key that cannot be computed is a miss — the original fresh-worktree path runs.
|
|
292
|
+
if (mayConsume && cacheDir) { try { const cut = cutFor(context, stateRoot); cached = loadCache(cacheDir, cut); } catch { cached = null; } }
|
|
293
|
+
const branch = `release-docs/${version}`;
|
|
294
|
+
run('git', ['fetch', 'origin', 'main'], repo);
|
|
295
|
+
const main = run('git', ['rev-parse', '--verify', 'origin/main^{commit}'], repo);
|
|
296
|
+
if (cached && cached.main === main && SHA.test(main)) {
|
|
297
|
+
tree = cached.tree;
|
|
298
|
+
// Attach the staged detached checkout to the branch only at the late docs node.
|
|
299
|
+
run('git', ['-C', tree, 'switch', '-c', branch], repo);
|
|
300
|
+
// Consumed: a resumed run must not reuse a tree that is now on the branch (fresh path instead).
|
|
301
|
+
rmSync(cacheFile(cacheDir!, cached), { force: true });
|
|
302
|
+
} else {
|
|
303
|
+
const root = mkdtempSync(join(tmpdir(), 'release-docs-'));
|
|
304
|
+
tree = join(root, 'tree');
|
|
305
|
+
run('git', ['worktree', 'add', '-b', branch, tree, 'origin/main'], repo);
|
|
306
|
+
run('bun', ['install', '--frozen-lockfile'], tree);
|
|
307
|
+
}
|
|
308
|
+
const result = cached && cached.main === main ? cached.docs : runDocs(['--version', version, '--base', tree, '--json'], repo, env, { stateRoot });
|
|
309
|
+
if (result.outcome !== 'ok') throw new Error(result.error ?? 'docs generation failed');
|
|
310
|
+
run('git', ['add', 'release/public/docs', 'website/pages.json'], tree);
|
|
311
|
+
run('git', ['commit', '-m', `docs: release ${version}`], tree);
|
|
312
|
+
run('git', ['push', '-u', 'origin', branch], tree);
|
|
313
|
+
return { ...result, branch, worktree: tree };
|
|
314
|
+
} catch (error) {
|
|
315
|
+
return { outcome: 'error', version, error: error instanceof Error ? error.message : String(error), ...(tree ? { worktree: tree } : {}) };
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/** Detached prefetch worker; an asynchronous spawn failure is logged as a cache miss and never escapes the node. */
|
|
320
|
+
export function startPrefetchWorker(version: string, commit: string,
|
|
321
|
+
spawnWorker: () => ReturnType<typeof spawn> = () => spawn(process.execPath, [resolve(import.meta.filename), '--prefetch-worker'], {
|
|
322
|
+
cwd: process.cwd(), env: process.env, detached: true, stdio: ['ignore', 'ignore', 'ignore'],
|
|
323
|
+
})): number {
|
|
324
|
+
const child = spawnWorker();
|
|
325
|
+
child.on('error', (error) => debug.log('release-loop.docs', 'prefetch-skipped', { version, commit, reason: `worker spawn error: ${error.message}` }));
|
|
326
|
+
if (!child.pid) throw new Error('prefetch worker did not start');
|
|
327
|
+
child.unref();
|
|
328
|
+
return child.pid;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
function graphNodeId(env: NodeJS.ProcessEnv): string | null {
|
|
332
|
+
const location = env.ELANOUS_GRAPH_CONTEXT;
|
|
333
|
+
if (!location) return null;
|
|
334
|
+
const context = JSON.parse(location.trimStart().startsWith('{') ? location : readFileSync(location, 'utf8')) as { nodeId?: unknown; input?: { previousVersion?: unknown }; outputs?: unknown };
|
|
335
|
+
return typeof context.nodeId === 'string' ? context.nodeId : context.input?.previousVersion !== undefined || context.outputs !== undefined ? 'docs' : null;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (import.meta.main) {
|
|
339
|
+
let result: DocsResult | (Record<string, unknown> & { outcome: 'ok' | 'error' | 'fail'; version?: string | null; error?: string });
|
|
340
|
+
let node: string | null = null;
|
|
341
|
+
try {
|
|
342
|
+
node = graphNodeId(process.env);
|
|
343
|
+
if (process.argv.includes('--prefetch-worker')) {
|
|
344
|
+
if (node !== 'prefetch') throw new Error('prefetch worker requires prefetch node');
|
|
145
345
|
const context = readGraphContext();
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const run = (command: string, args: string[], cwd = process.cwd()) => {
|
|
150
|
-
const output = spawnSync(command, args, { cwd, encoding: 'utf8', maxBuffer: 16 * 1024 * 1024 });
|
|
151
|
-
if (output.status !== 0) throw new Error(`${command} ${args[0]} failed: ${output.stderr || output.stdout}`);
|
|
152
|
-
return output.stdout.trim();
|
|
153
|
-
};
|
|
154
|
-
run('git', ['fetch', 'origin', 'main']);
|
|
155
|
-
tree = mkdtempSync(join(tmpdir(), 'release-docs-'));
|
|
156
|
-
const worktree = join(tree, 'tree');
|
|
157
|
-
run('git', ['worktree', 'add', '-b', branch, worktree, 'origin/main']);
|
|
158
|
-
run('bun', ['install', '--frozen-lockfile'], worktree);
|
|
159
|
-
result = runDocs(['--version', version, '--base', worktree, '--json']);
|
|
160
|
-
if (result.outcome !== 'ok') throw new Error(result.error ?? 'docs generation failed');
|
|
161
|
-
run('git', ['add', 'release/public/docs', 'website/pages.json'], worktree);
|
|
162
|
-
run('git', ['commit', '-m', `docs: release ${version}`], worktree);
|
|
163
|
-
run('git', ['push', '-u', 'origin', branch], worktree);
|
|
164
|
-
result = { ...result, branch, worktree };
|
|
165
|
-
} catch (error) {
|
|
166
|
-
result = { outcome: 'error', version, error: error instanceof Error ? error.message : String(error), ...(tree ? { worktree: join(tree, 'tree') } : {}) };
|
|
346
|
+
stagePrefetch(context);
|
|
347
|
+
// Worker stdout is not a graph verdict; the initiating node has already returned.
|
|
348
|
+
process.exit(0);
|
|
167
349
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
350
|
+
if (node === 'prefetch') {
|
|
351
|
+
let version: string | null = null;
|
|
352
|
+
try {
|
|
353
|
+
const context = readGraphContext();
|
|
354
|
+
version = context.input.version;
|
|
355
|
+
const cut = cutFor(context, effectiveInstanceRoot());
|
|
356
|
+
const dir = runCacheDir(process.env);
|
|
357
|
+
mkdirSync(dir, { recursive: true });
|
|
358
|
+
if (!loadCache(dir, cut)) {
|
|
359
|
+
const pid = startPrefetchWorker(cut.version, cut.commit);
|
|
360
|
+
// This is not a gate: the late nodes validate the atomic artifact or run their original path.
|
|
361
|
+
debug.log('release-loop.docs', 'prefetch-start', { version: cut.version, commit: cut.commit, pid });
|
|
362
|
+
}
|
|
363
|
+
result = { outcome: 'ok', version: cut.version, summary: `prefetch v${cut.version} started` };
|
|
364
|
+
} catch (error) {
|
|
365
|
+
// Any pre-worker failure is a cache miss — the gate and the late nodes' original paths still run.
|
|
366
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
367
|
+
debug.log('release-loop.docs', 'prefetch-skipped', { version, reason });
|
|
368
|
+
result = { outcome: 'ok', version, summary: `prefetch skipped (cache miss): ${reason}` };
|
|
369
|
+
}
|
|
370
|
+
} else if (node === 'tui') {
|
|
371
|
+
const context = readGraphContext();
|
|
372
|
+
result = { ...joinTui(context, process.env, process.cwd()), version: context.input.version } as typeof result;
|
|
373
|
+
} else if (node === 'docs') {
|
|
374
|
+
result = graphDocs(readGraphContext(), process.env, process.cwd(), commandRunner);
|
|
375
|
+
} else if (node === null) result = runDocs(process.argv.slice(2));
|
|
376
|
+
else throw new Error(`unknown release docs node: ${node}`);
|
|
377
|
+
} catch (error) {
|
|
378
|
+
result = { outcome: 'error', version: null, error: error instanceof Error ? error.message : String(error) };
|
|
379
|
+
}
|
|
380
|
+
debug.log('release-loop.docs', 'result', { node, version: result.version, outcome: result.outcome });
|
|
381
|
+
const details = result as Record<string, unknown>;
|
|
382
|
+
const verdict = details.verdict;
|
|
383
|
+
emitNodeResult({ ...details, outcome: result.outcome, verdict: verdict === 'pass' || verdict === 'flaky' || verdict === 'fail' ? verdict : result.outcome === 'ok' ? 'pass' : 'fail',
|
|
384
|
+
summary: typeof details.summary === 'string' ? details.summary : result.outcome === 'ok'
|
|
385
|
+
? `docs v${result.version} · ${(details.flipped as string[] | undefined)?.length ?? 0} pages` : `docs: ${result.error ?? 'failed'}` });
|
|
386
|
+
if (result.outcome !== 'ok') process.exitCode = result.outcome === 'fail' ? 1 : node === 'tui' ? 2 : 1;
|
|
172
387
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** File seconds are recorded on the outer testsuite of each JUnit file, not its nested describe suites. */
|
|
2
|
+
export function readJunitFileSeconds(xml: string): Map<string, number> {
|
|
3
|
+
const secondsByFile = new Map<string, number>();
|
|
4
|
+
const entities: Record<string, string> = { '&': '&', '"': '"', ''': "'", '<': '<', '>': '>' };
|
|
5
|
+
let depth = 0;
|
|
6
|
+
let cursor = 0;
|
|
7
|
+
while (cursor < xml.length) {
|
|
8
|
+
const start = xml.indexOf('<', cursor);
|
|
9
|
+
if (start < 0) break;
|
|
10
|
+
if (xml.startsWith('<![CDATA[', start)) {
|
|
11
|
+
const end = xml.indexOf(']]>', start + 9);
|
|
12
|
+
if (end < 0) break;
|
|
13
|
+
cursor = end + 3;
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (xml.startsWith('<!--', start)) {
|
|
17
|
+
const end = xml.indexOf('-->', start + 4);
|
|
18
|
+
if (end < 0) break;
|
|
19
|
+
cursor = end + 3;
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (xml.startsWith('<?', start)) {
|
|
23
|
+
const end = xml.indexOf('?>', start + 2);
|
|
24
|
+
if (end < 0) break;
|
|
25
|
+
cursor = end + 2;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
let quote = '';
|
|
29
|
+
let brackets = 0;
|
|
30
|
+
let end = start + 1;
|
|
31
|
+
for (; end < xml.length; end++) {
|
|
32
|
+
const char = xml[end]!;
|
|
33
|
+
if (quote) { if (char === quote) quote = ''; }
|
|
34
|
+
else if (char === '"' || char === "'") quote = char;
|
|
35
|
+
else if (char === '[' && xml.startsWith('<!', start)) brackets++;
|
|
36
|
+
else if (char === ']' && brackets) brackets--;
|
|
37
|
+
else if (char === '>' && !brackets) break;
|
|
38
|
+
}
|
|
39
|
+
if (end === xml.length) break;
|
|
40
|
+
cursor = end + 1;
|
|
41
|
+
const tag = xml.slice(start + 1, end);
|
|
42
|
+
const suite = /^(\/?)testsuite(?=[\s/]|$)/.exec(tag);
|
|
43
|
+
if (!suite) continue;
|
|
44
|
+
if (suite[1]) { depth = Math.max(0, depth - 1); continue; }
|
|
45
|
+
if (depth === 0) {
|
|
46
|
+
const file = /\bfile="([^"]+)"/.exec(tag)?.[1];
|
|
47
|
+
const rawTime = /\btime="([^"]+)"/.exec(tag)?.[1];
|
|
48
|
+
if (file && rawTime !== undefined) {
|
|
49
|
+
const seconds = Number(rawTime);
|
|
50
|
+
if (Number.isFinite(seconds) && seconds >= 0) {
|
|
51
|
+
const path = file.replace(/&(?:amp|quot|apos|lt|gt);/g, (entity) => entities[entity]!);
|
|
52
|
+
secondsByFile.set(path, Math.max(secondsByFile.get(path) ?? 0, seconds));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (!/\/\s*$/.test(tag)) depth++;
|
|
57
|
+
}
|
|
58
|
+
return secondsByFile;
|
|
59
|
+
}
|
|
@@ -21,7 +21,7 @@ import { POD_BUN_CACHE_HOST_PATH, parseInstallSeconds, podBunCacheVolume } from
|
|
|
21
21
|
import { PodPoolScheduler, parsePodPool, checkPodPool } from '../../src/task-orchestrator/surfaces/pod-pool.js';
|
|
22
22
|
import { POD_INSTALL_SLOTS_DEFAULT, POD_INSTALL_SLOTS_HOST_PATH, installSlotScript } from '../../src/task-orchestrator/surfaces/pod-install-slots.js';
|
|
23
23
|
import { gateDepsInstallScript, parseGateDeps } from '../../src/task-orchestrator/surfaces/pod-gate-deps.js';
|
|
24
|
-
import { gateShardsPath, writeGateShards, type GateShard } from '../../src/release-loop/gate-shards.js';
|
|
24
|
+
import { gateShardsPath, recordGateShardsVerdict, writeGateShards, type GateShard } from '../../src/release-loop/gate-shards.js';
|
|
25
25
|
import { defaultKubectl } from '../../src/task-orchestrator/surfaces/self-implement-pod.js';
|
|
26
26
|
|
|
27
27
|
interface CommandResult { rc: number; output: string; passedIds?: string[]; stalledEnv?: Array<{ file: string; reason: 'no-output' }>; timedOut?: boolean }
|
|
@@ -75,6 +75,7 @@ export interface GateResult {
|
|
|
75
75
|
knownEnv: number;
|
|
76
76
|
knownEnvCleared: string[];
|
|
77
77
|
stalledEnv: Array<{ file: string; reason: 'no-output' | 'isolated-timeout'; local: 'passed' | 'failed' | 'timeout' }>;
|
|
78
|
+
rcNonzeroNoFailures: Array<{ file: string; rc: number; pass: number; baseline: 'same' | 'clean' | 'missing' }>;
|
|
78
79
|
baselineSource?: 'ledger' | 'instance' | 'cut-logs' | 'swept';
|
|
79
80
|
/** GATE-BASELINE-CACHE — isolated baseline files answered from the ledger (hits) or run now (misses). */
|
|
80
81
|
baselineCache?: { hits: number; misses: number };
|
|
@@ -460,6 +461,47 @@ function failuresOf(run: CommandResult, label: string): SweepFailures {
|
|
|
460
461
|
return { failures, errors: [...new Set(errors)].sort() };
|
|
461
462
|
}
|
|
462
463
|
|
|
464
|
+
/**
|
|
465
|
+
* «N pass · 0 fail · rc=1» from an isolated run is read as `rc-nonzero-no-failures` only when the summary is a complete,
|
|
466
|
+
* clean, single-file summary for the requested file (`Ran N≥1 tests across 1 file` · 0 fail · 0 error · no `(fail)` ·
|
|
467
|
+
* no unhandled error · pass = N · no other test-file header). Every other run is read exactly as before (`failuresOf`,
|
|
468
|
+
* which throws on the incomplete shapes, plus a failure-count/identified-name check).
|
|
469
|
+
*/
|
|
470
|
+
export function readIsolatedRun(run: CommandResult, label: string, file: string):
|
|
471
|
+
| { kind: 'read'; failures: string[]; errors: string[] }
|
|
472
|
+
| { kind: 'rc-nonzero-no-failures'; rc: number; pass: number } {
|
|
473
|
+
const output = stripPodRepoRoot(run.output.replace(/\x1b\[[0-9;]*[A-Za-z]/g, ''));
|
|
474
|
+
const ran = lastMatch(output, /Ran (\d+) tests? across (\d+) files?/);
|
|
475
|
+
// rc 1 only: other non-zero exits with a clean summary keep the established leaked-exit reading (clean) in failuresOf.
|
|
476
|
+
const cleanNonzero = run.rc === 1 && !!ran && Number(ran[1]) >= 1 && Number(ran[2]) === 1
|
|
477
|
+
&& summaryCount(output, 'fail') === 0
|
|
478
|
+
&& (Number.isNaN(summaryCount(output, 'error')) || summaryCount(output, 'error') === 0)
|
|
479
|
+
&& parseFailures(output).length === 0 && !/\(fail\)/.test(output)
|
|
480
|
+
&& !/Unhandled error between tests/.test(output);
|
|
481
|
+
if (!cleanNonzero) {
|
|
482
|
+
const read = failuresOf(run, label);
|
|
483
|
+
// Two (fail) lines folding into one id would undercount the file's failures: unreadable, not fewer.
|
|
484
|
+
const failCount = summaryCount(output, 'fail');
|
|
485
|
+
if (Number.isFinite(failCount) && read.failures.length !== failCount)
|
|
486
|
+
throw new Error(`${label} incomplete (rc=${run.rc}; failure attribution summary=${failCount}, identified=${read.failures.length})`);
|
|
487
|
+
return { kind: 'read', ...read };
|
|
488
|
+
}
|
|
489
|
+
// Bun's file headers, when present, must identify the requested file before the result is recorded or cached.
|
|
490
|
+
// Any test-file path counts: root-level (`other.test.ts:`), nested, or absolute (outside the stripped Pod root).
|
|
491
|
+
for (const raw of output.split(/\r?\n/)) {
|
|
492
|
+
// Any characters but `:` (unicode, spaces, @, +, …) — a header is `<path ending in .test/.spec.ts>:`.
|
|
493
|
+
const header = /^(?:\.\/)?([^\s:][^:]*?\.(?:test|spec)\.[cm]?[jt]sx?):/.exec(raw.trim());
|
|
494
|
+
if (header && header[1] !== file)
|
|
495
|
+
throw new Error(`${label} incomplete (rc=${run.rc}; isolated run attributed to another file: ${header[1]})`);
|
|
496
|
+
}
|
|
497
|
+
const pass = summaryCount(output, 'pass');
|
|
498
|
+
if (pass !== Number(ran![1]))
|
|
499
|
+
throw new Error(`${label} incomplete (rc=${run.rc}; pass=${Number.isNaN(pass) ? 'missing' : pass}; Ran=${ran![1]})`);
|
|
500
|
+
// Validate the requested file as well as the summary; only this one file can own the synthetic id.
|
|
501
|
+
fileOf(`${file} > [rc-nonzero]`);
|
|
502
|
+
return { kind: 'rc-nonzero-no-failures', rc: run.rc, pass };
|
|
503
|
+
}
|
|
504
|
+
|
|
463
505
|
class StalledPodShards extends Error {
|
|
464
506
|
constructor(readonly stalledShards: NonNullable<GateResult['stalledShards']>, readonly partialSummary: NonNullable<GateResult['partialSummary']>) {
|
|
465
507
|
super(`pod sweep incomplete: stalled shards ${stalledShards.map(({ shard }) => shard).join(', ')}`);
|
|
@@ -1149,7 +1191,7 @@ export async function judgeGate(opts: GateOptions, runner: GateRunner = createGa
|
|
|
1149
1191
|
return baselineCommit(root, version);
|
|
1150
1192
|
};
|
|
1151
1193
|
const repo = resolve(opts.repo ?? process.cwd());
|
|
1152
|
-
const result: GateResult = { outcome: 'error', commit: opts.commit, introduced: [], preexisting: 0, fixed: 0, knownEnv: 0, knownEnvCleared: [], stalledEnv: [], durationMs: 0 };
|
|
1194
|
+
const result: GateResult = { outcome: 'error', commit: opts.commit, introduced: [], preexisting: 0, fixed: 0, knownEnv: 0, knownEnvCleared: [], stalledEnv: [], rcNonzeroNoFailures: [], durationMs: 0 };
|
|
1153
1195
|
let work: string | undefined;
|
|
1154
1196
|
let baseSnapshot = false;
|
|
1155
1197
|
let cutFailures: SweepFailures | undefined;
|
|
@@ -1345,12 +1387,15 @@ export async function judgeGate(opts: GateOptions, runner: GateRunner = createGa
|
|
|
1345
1387
|
result.stalledEnv.push({ file, reason: 'isolated-timeout', local: 'timeout' });
|
|
1346
1388
|
continue;
|
|
1347
1389
|
}
|
|
1348
|
-
const
|
|
1390
|
+
const cutReading = cutCheck === undefined ? undefined : readIsolatedRun(cutCheck, `cut isolated ${file}`, file);
|
|
1391
|
+
const rcOnly = cutReading?.kind === 'rc-nonzero-no-failures' ? cutReading : undefined;
|
|
1392
|
+
const rcOnlyId = `${file} > [rc-nonzero]`;
|
|
1393
|
+
const isolatedCut: SweepFailures = cutReading === undefined
|
|
1349
1394
|
? { failures: cut.failures.filter((id) => fileOf(id) === file), errors: cut.errors.filter((id) => fileOf(id) === file) }
|
|
1350
|
-
:
|
|
1395
|
+
: cutReading.kind === 'read' ? cutReading : { failures: [], errors: [rcOnlyId] };
|
|
1351
1396
|
if (cutCheck !== undefined) remember({ commit: opts.commit, file, host: cacheHost, failures: isolatedCut.failures, errors: isolatedCut.errors, missing: false });
|
|
1352
1397
|
const reproduced = new Set([...isolatedCut.failures, ...isolatedCut.errors]);
|
|
1353
|
-
let candidates = diff.newFailures.filter((id) => fileOf(id) === file && reproduced.has(id));
|
|
1398
|
+
let candidates = rcOnly ? [rcOnlyId] : diff.newFailures.filter((id) => fileOf(id) === file && reproduced.has(id));
|
|
1354
1399
|
// GATE-INTRO-RECHECK — a new failure that is only bun's «timed out» shape gets one more isolated run with a generous
|
|
1355
1400
|
// per-test limit, on the same runner (node-b when the gate is remote). Passing there = flaky under load (warning);
|
|
1356
1401
|
// an assertion failure, a failure again, or a run that cannot be read stays introduced.
|
|
@@ -1382,7 +1427,9 @@ export async function judgeGate(opts: GateOptions, runner: GateRunner = createGa
|
|
|
1382
1427
|
}
|
|
1383
1428
|
if (candidates.length === 0) continue;
|
|
1384
1429
|
let oldFailures: Set<string>;
|
|
1430
|
+
let baselineMissing = false;
|
|
1385
1431
|
const hit = baseCache.get(`${file}\0${cacheHost}`);
|
|
1432
|
+
if (hit?.missing) baselineMissing = true;
|
|
1386
1433
|
if (hit) {
|
|
1387
1434
|
cacheStats.hits++;
|
|
1388
1435
|
oldFailures = new Set([...hit.failures, ...hit.errors]);
|
|
@@ -1399,13 +1446,22 @@ export async function judgeGate(opts: GateOptions, runner: GateRunner = createGa
|
|
|
1399
1446
|
const lookup = await runner.command('git', ['ls-tree', '--name-only', baseSha, '--', file], opts.remote ? baselineTree : repo);
|
|
1400
1447
|
if (lookup.rc !== 0 || lookup.output.trim()) throw new Error(`baseline isolated run incomplete: ${file}`);
|
|
1401
1448
|
oldFailures = new Set();
|
|
1449
|
+
baselineMissing = true;
|
|
1402
1450
|
remember({ commit: baseSha, file, host: cacheHost, failures: [], errors: [], missing: true });
|
|
1403
1451
|
} else {
|
|
1404
|
-
const
|
|
1452
|
+
const reading = readIsolatedRun(previous, `baseline isolated ${file}`, file);
|
|
1453
|
+
const prior: SweepFailures = reading.kind === 'read' ? reading : { failures: [], errors: [rcOnlyId] };
|
|
1454
|
+
if (reading.kind === 'rc-nonzero-no-failures') debug.log('release-loop.gate', 'isolated-rc-nonzero-no-failures',
|
|
1455
|
+
{ file, label: 'baseline isolated', rc: reading.rc, pass: reading.pass, baseline: 'same' });
|
|
1405
1456
|
oldFailures = new Set([...prior.failures, ...prior.errors]);
|
|
1406
1457
|
remember({ commit: baseSha, file, host: cacheHost, failures: prior.failures, errors: prior.errors, missing: false });
|
|
1407
1458
|
}
|
|
1408
1459
|
}
|
|
1460
|
+
if (rcOnly) {
|
|
1461
|
+
const baseline = oldFailures.has(rcOnlyId) ? 'same' : baselineMissing ? 'missing' : 'clean';
|
|
1462
|
+
result.rcNonzeroNoFailures.push({ file, rc: rcOnly.rc, pass: rcOnly.pass, baseline });
|
|
1463
|
+
debug.log('release-loop.gate', 'isolated-rc-nonzero-no-failures', { file, label: 'cut isolated', rc: rcOnly.rc, pass: rcOnly.pass, baseline });
|
|
1464
|
+
}
|
|
1409
1465
|
for (const id of candidates) {
|
|
1410
1466
|
if (oldFailures.has(id)) result.preexisting++;
|
|
1411
1467
|
else result.introduced.push(id);
|
|
@@ -1456,6 +1512,15 @@ export async function judgeGate(opts: GateOptions, runner: GateRunner = createGa
|
|
|
1456
1512
|
}
|
|
1457
1513
|
}
|
|
1458
1514
|
if (result.outcome !== 'error') debug.log('release-loop.gate', 'judged', { version: opts.version, commit: opts.commit, introduced: result.introduced.length, preexisting: result.preexisting });
|
|
1515
|
+
// GATE-LIVE-OBS-RC-WORDING ⓒ — the shards board says «판정 전» until this lands; then «새 실패 N» only (UX · gate-shards.ts).
|
|
1516
|
+
// Same ledger as the board's own writes (sweep's shardsFile). A write failure is logged and never changes the verdict.
|
|
1517
|
+
if (result.outcome !== 'error' && opts.pod) {
|
|
1518
|
+
const path = opts.ledgerRoot ? gateShardsPath(opts.version, opts.ledgerRoot) : gateShardsPath(opts.version);
|
|
1519
|
+
try {
|
|
1520
|
+
const written = recordGateShardsVerdict(path, { introduced: result.introduced.length, preexisting: result.preexisting });
|
|
1521
|
+
debug.log('release-loop.gate', 'shards-verdict', { version: opts.version, path, written, introduced: result.introduced.length, preexisting: result.preexisting });
|
|
1522
|
+
} catch (error) { debug.log('release-loop.gate', 'shards-verdict-write-failed', { path, error: String(error) }); }
|
|
1523
|
+
}
|
|
1459
1524
|
return result;
|
|
1460
1525
|
}
|
|
1461
1526
|
|
|
@@ -1464,6 +1529,7 @@ export function graphGateResult(result: GateResult, graph: boolean) {
|
|
|
1464
1529
|
verdict: result.outcome === 'ok' ? 'pass' as const : 'fail' as const,
|
|
1465
1530
|
summary: (result.partial ? `부분 재검 ${result.partial.files}파일(앞 게이트 ${result.partial.priorCommit.slice(0, 9)} 결과 이음) · ` : '')
|
|
1466
1531
|
+ (result.outcome === 'ok' ? `새 회귀 ${result.introduced.length} · 기존 ${result.preexisting} · 고침 ${result.fixed ?? '못 셈(기준선 미루기)'}` : `게이트 ${result.outcome}: ${result.error ?? result.introduced.length + ' new regressions'}`) + ` · 환경 알려진 실패 ${result.knownEnv}`
|
|
1532
|
+
+ (result.rcNonzeroNoFailures.length ? ` · ⚠ 종료코드만 비영 ${result.rcNonzeroNoFailures.length}` : '')
|
|
1467
1533
|
+ (result.loadFlaky?.length ? ` · ⚠ 부하 흔들림 ${result.loadFlaky.length}(시간 초과 꼴 · ${GATE_TIMEOUT_RECHECK_MS / 1000}s 재실행 통과 · 막지 않음)` : '')
|
|
1468
1534
|
+ (result.stalledEnv.length ? ` · 환경 멈춤 ${result.stalledEnv.length} (Pod 밖 통과 ${result.stalledEnv.filter((item) => item.local === 'passed').length})` : '') };
|
|
1469
1535
|
}
|
|
@@ -1535,7 +1601,7 @@ if (import.meta.main) {
|
|
|
1535
1601
|
version = opts.version;
|
|
1536
1602
|
result = await judgeGate(opts);
|
|
1537
1603
|
} catch (error) {
|
|
1538
|
-
result = { outcome: 'error', commit: '', introduced: [], preexisting: 0, fixed: 0, knownEnv: 0, knownEnvCleared: [], stalledEnv: [], durationMs: Date.now() - start, error: String(error) };
|
|
1604
|
+
result = { outcome: 'error', commit: '', introduced: [], preexisting: 0, fixed: 0, knownEnv: 0, knownEnvCleared: [], stalledEnv: [], rcNonzeroNoFailures: [], durationMs: Date.now() - start, error: String(error) };
|
|
1539
1605
|
}
|
|
1540
1606
|
if (result.error) console.error(result.error);
|
|
1541
1607
|
debug.log('release-loop.gate', 'result', { version, outcome: result.outcome });
|