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
|
@@ -5,6 +5,7 @@ import { createHash } from 'node:crypto';
|
|
|
5
5
|
import { appendFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
|
|
6
6
|
import { constants as osConstants, hostname } from 'node:os';
|
|
7
7
|
import { basename, dirname, join, resolve, sep } from 'node:path';
|
|
8
|
+
import { HarnessCliInputError } from '../cli/cli-user-error.js';
|
|
8
9
|
import { findGitDir } from '../git-fs/locate.js';
|
|
9
10
|
import { LogStore, logsDbPath } from '../mss/logging/log-store.js';
|
|
10
11
|
import { loadSelfDevRun } from '../self-dev/run-store.js';
|
|
@@ -20,12 +21,15 @@ import { GOAL_TYPES, lintGoalFile, parseGoalId, parseGoalType, resolveGoalAuthor
|
|
|
20
21
|
import { templateForGoalType } from '../self-implement/graph-templates.js';
|
|
21
22
|
import { listRunLedgers, loadFederatedRunLedger, loadRunLedger, queryRunScreenKey, runLedgerDir, type RunLedgerMatch } from '../self-implement/run-ledger.js';
|
|
22
23
|
import { classifyPodExitStop, recordRunStop, runStopRecorded, RUN_STOP_EVENT } from '../self-implement/run-stop.js';
|
|
23
|
-
import { resolveChildLlmEffort, resolveImplementationChildModel } from '../self-dev/dev-cli.js';
|
|
24
|
+
import { ensureOpenRouterChildModelLive, resolveChildLlmEffort, resolveImplementationChildModel } from '../self-dev/dev-cli.js';
|
|
24
25
|
import { resolveHarnessTarget } from '../self-implement/harness-target-options.js';
|
|
25
26
|
import { queryRunningRuns } from '../self-implement/running-runs.js';
|
|
26
27
|
import { DevPipelineError } from '../self-dev/dev-pipeline.js';
|
|
27
28
|
import { collectDraftMetrics, collectOverlapMetrics, DRAFT_SWEEP_CONCURRENCY, mapBounded, resolveDraftSweepCloseCap, runDraftSweep, sweepFailureReason, type DraftSweepAdapters, type DraftSweepResult, type OverlapMetricAdapters, type SweepDraft, type SweepMergedPr, type SweepReviewGate } from '../self-dev/draft-sweep.js';
|
|
28
29
|
import { readAskPreflightRowsSince, readSalvagedRowsSince } from '../self-dev/ask-launch-io.js';
|
|
30
|
+
import { replayPodTerminals, type DraftResidueReplayOptions, type PrTerminalRecord } from '../self-dev/draft-residue.js';
|
|
31
|
+
import { draftClaimComment, draftReleaseComment } from '../self-dev/draft-triage-rules.js';
|
|
32
|
+
import { readTaskAgentState, taskAgentStatePath, type TaskCard } from '../task-agent/task-hand.js';
|
|
29
33
|
import { debug } from '../debug/log.js';
|
|
30
34
|
import { installHarnessSalvageCommand, installHarnessSalvageRetentionCommand } from './harness-salvage-cli.js';
|
|
31
35
|
import { decideNestedElanousLaunch, readNestedElanousDepth } from './nested-elanous-policy.js';
|
|
@@ -44,8 +48,10 @@ import { resolveRepositoryName } from './repository-name.js';
|
|
|
44
48
|
import { installHarnessCliSinkHook } from './harness-cli-sink.js';
|
|
45
49
|
import { addHarnessQueue, HarnessQueueDuplicateError, harnessQueueReceiptPath, listHarnessQueue, queueSeatForCwd, reconcileHarnessQueue, removeHarnessQueue, setHarnessQueuePriority, tickHarnessQueue, type HarnessQueueDeps, type QueueItem, type QueueSeat } from './harness-queue.js';
|
|
46
50
|
import { writeHarnessQueueReceipt } from './harness-queue-child.js';
|
|
51
|
+
import { decideBackpressure, readBackpressureSignals, type BackpressureReadDeps } from './dispatch-backpressure.js';
|
|
47
52
|
import { parseDoorSince, queryLaunchDoors, renderLaunchDoors, type DoorTable } from './launch-stamp.js';
|
|
48
53
|
import { resolveHarnessSubstrate, type ResolvedHarnessSubstrate } from './harness-substrate-default.js';
|
|
54
|
+
import { podChildProviderRefusal } from '../task-orchestrator/surfaces/pod-child-providers.js';
|
|
49
55
|
import { runHarnessPlanRfc } from './harness-plan-rfc.js';
|
|
50
56
|
import { classifyGarbage, isGarbageProcessTarget, type GarbageProcess } from './process-garbage.js';
|
|
51
57
|
import type { MissionSolveOutcome } from './mission-solve-loop.js';
|
|
@@ -97,16 +103,9 @@ export function setHarnessPlanRfcForTesting(fn: typeof runHarnessPlanRfc | undef
|
|
|
97
103
|
harnessPlanRfcForTesting = fn;
|
|
98
104
|
}
|
|
99
105
|
|
|
100
|
-
export
|
|
106
|
+
export { HarnessCliInputError } from '../cli/cli-user-error.js';
|
|
101
107
|
|
|
102
|
-
|
|
103
|
-
export class HarnessCliInputError extends Error {
|
|
104
|
-
constructor(message: string) {
|
|
105
|
-
super(message);
|
|
106
|
-
this.name = 'HarnessCliInputError';
|
|
107
|
-
Object.defineProperty(this, Symbol.for('elanous.cli.HarnessCliInputError'), { value: true });
|
|
108
|
-
}
|
|
109
|
-
}
|
|
108
|
+
export type HarnessSupervisorSource = 'flag' | 'default';
|
|
110
109
|
|
|
111
110
|
export interface HarnessAskSayOptions {
|
|
112
111
|
seat?: QueueSeat;
|
|
@@ -427,6 +426,7 @@ export function classifyHarnessPodExit(
|
|
|
427
426
|
): { lines: string[]; reason: PodExitReason | 'pod-failure' } {
|
|
428
427
|
let podFailure: string | undefined;
|
|
429
428
|
let podJobFailed = false;
|
|
429
|
+
let podChildFailed = false;
|
|
430
430
|
for (const line of output.split('\n').reverse()) {
|
|
431
431
|
if (!line.trimStart().startsWith('[{') || !line.includes('"error"')) continue;
|
|
432
432
|
try {
|
|
@@ -438,6 +438,7 @@ export function classifyHarnessPodExit(
|
|
|
438
438
|
if (typeof error?.code !== 'string' || typeof error.message !== 'string' || !error.code.startsWith('pod-')) continue;
|
|
439
439
|
podFailure = error.message;
|
|
440
440
|
podJobFailed = error.code === 'pod-job-failed';
|
|
441
|
+
podChildFailed = error.code === 'pod-child-failed';
|
|
441
442
|
break;
|
|
442
443
|
}
|
|
443
444
|
} catch { /* Non-result stdout cannot establish that a Pod child ran. */ }
|
|
@@ -447,6 +448,8 @@ export function classifyHarnessPodExit(
|
|
|
447
448
|
const summary = output.split('\n').find((line) => /\s❌\sfailed · .* — pod-[\w-]+: /.test(line));
|
|
448
449
|
podFailure = summary?.split(/\s❌\sfailed · .* — pod-[\w-]+: /)[1];
|
|
449
450
|
podJobFailed = summary?.includes(' — pod-job-failed: ') ?? false;
|
|
451
|
+
// src/self-dev/orchestrate-summary-line.ts prints the pod-child-failed message (the Pod reason) on this line.
|
|
452
|
+
podChildFailed = summary?.includes(' — pod-child-failed: ') ?? false;
|
|
450
453
|
}
|
|
451
454
|
// Only the run announced at launch — another run id quoted in the output is not this run (review round 3).
|
|
452
455
|
const observedRunId = deps.runId ?? harnessPodRunId(output);
|
|
@@ -454,9 +457,11 @@ export function classifyHarnessPodExit(
|
|
|
454
457
|
if (podFailure) {
|
|
455
458
|
const childError = podJobFailed ? podFailure.split('childError=')[1]?.split('\\n', 1)[0]?.split('\n', 1)[0] : undefined;
|
|
456
459
|
try { debug.log('harness.pod', 'exit-classified', { runId, reason: 'pod-failure', status: exit.status, signal: exit.signal ?? null }); } catch { /* observation is fail-soft */ }
|
|
457
|
-
return { reason: 'pod-failure', lines: [
|
|
458
|
-
? `Pod 안 자식이 실패했다 — ${
|
|
459
|
-
:
|
|
460
|
+
return { reason: 'pod-failure', lines: [podChildFailed
|
|
461
|
+
? `Pod 안 자식이 실패했다 — ${podFailure.split('\\n', 1)[0]}`
|
|
462
|
+
: podJobFailed && childError && childError !== 'no-result-line'
|
|
463
|
+
? `Pod 안 자식이 실패했다 — ${childError}`
|
|
464
|
+
: `Pod 실행이 실패했다 — ${podFailure.split('\\n', 1)[0]}`] };
|
|
460
465
|
}
|
|
461
466
|
let ledger: ReturnType<typeof loadRunLedger> = null;
|
|
462
467
|
let ledgerReadable = false;
|
|
@@ -677,6 +682,7 @@ async function onPod(opts: unknown, entrance: 'cli-harness-ask' | 'cli-harness-s
|
|
|
677
682
|
output = (output + text).slice(-16_000);
|
|
678
683
|
} });
|
|
679
684
|
if (status !== 0) {
|
|
685
|
+
// onPod is the existing ask/say caller: classify the dispatchHarnessOnPod output for both entrances.
|
|
680
686
|
const classified = classifyHarnessPodExit({ status }, output, { ...(runId ? { runId } : {}) });
|
|
681
687
|
recordClassifiedHarnessPodExit(runId ?? harnessPodRunId(output), classified.reason, status,
|
|
682
688
|
{ entrance, seat: o.seat, output });
|
|
@@ -714,6 +720,25 @@ export function recordHarnessPodStop(
|
|
|
714
720
|
} catch { return false; /* ledger observation cannot change Pod output or exit */ }
|
|
715
721
|
}
|
|
716
722
|
|
|
723
|
+
/**
|
|
724
|
+
* POD-ANTHROPIC-PROVIDER ⓓ — 발사 관문과 Pod 가 «한 목록»(`POD_CHILD_PROVIDERS`)을 본다.
|
|
725
|
+
* 🩸 10-10: 관문은 anthropic 을 «예산 판정 밖» 으로 통과시켰고 Pod 단계가 rc=2 로 죽었다(관문·Pod 목록 엇갈림).
|
|
726
|
+
* Pod 기질에서 목록 밖 provider 는 발사 «전»에 Pod 와 같은 문면으로 거부한다 — 로컬 기질은 판정하지 않는다.
|
|
727
|
+
*/
|
|
728
|
+
export function podChildProviderLaunchRefusal(substrate: ResolvedHarnessSubstrate['substrate'], childLlmProvider: string | undefined): string | undefined {
|
|
729
|
+
return substrate === 'pod' ? podChildProviderRefusal(childLlmProvider) : undefined;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
function refusePodChildProviderBeforeLaunch(resolved: ResolvedHarnessSubstrate, opts: { readonly childLlmProvider?: string }): boolean {
|
|
733
|
+
const refusal = podChildProviderLaunchRefusal(resolved.substrate, opts.childLlmProvider);
|
|
734
|
+
if (!refusal) return false;
|
|
735
|
+
console.error(`❌ launch gate: ${refusal}`);
|
|
736
|
+
try { debug.log('execution-loop.launch-gate', 'pod-child-provider-refused', { provider: opts.childLlmProvider?.trim() ?? null, substrate: resolved.substrate }); }
|
|
737
|
+
catch { /* observation is fail-soft */ }
|
|
738
|
+
process.exitCode = 2;
|
|
739
|
+
return true;
|
|
740
|
+
}
|
|
741
|
+
|
|
717
742
|
const LAUNCH_BUDGET_PROVIDER: Readonly<Record<string, string>> = { 'codex-rotate': CODEX_PROVIDER, grok: GROK_PROVIDER };
|
|
718
743
|
|
|
719
744
|
/**
|
|
@@ -785,6 +810,10 @@ async function dispatchHarnessAskSay(
|
|
|
785
810
|
// HARNESS-FULL-GRAPH — 여정 조인 키는 이 발사 동안만 환경에 싣는다(자식은 그동안 물려받는다).
|
|
786
811
|
const journeyPreset = Boolean(process.env[JOURNEY_KEY_ENV]?.trim());
|
|
787
812
|
try { await runInjectedHarnessHandler(async () => {
|
|
813
|
+
// POD-ANTHROPIC-PROVIDER ⓓ — Pod 가 못 받는 provider 는 모델 검사·대기열·관문 «전»에(그리고 `--dry-run` 머리 줄보다 먼저) 거부한다 —
|
|
814
|
+
// Pod 와 같은 목록·같은 문면. 기질 판정은 아래 resolveLaunchSubstrate 와 같은 리졸버(같은 입력)다.
|
|
815
|
+
if (refusePodChildProviderBeforeLaunch(resolveHarnessSubstrate({ flag: opts as HarnessSubstrateOpts, config: getUserConfig(), env: process.env }), opts)) return;
|
|
816
|
+
if (opts.childLlmModel !== undefined) await ensureOpenRouterChildModelLive(opts.childLlmProvider, opts.childLlmModel, { persist: !isHarnessDryRun(opts) });
|
|
788
817
|
assertHarnessChildLlmModel(opts);
|
|
789
818
|
if (isHarnessDryRun(opts)) {
|
|
790
819
|
resolveLaunchSubstrate(opts);
|
|
@@ -2392,6 +2421,16 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
|
|
|
2392
2421
|
...(gatePass && !gateFail ? { gate: 'pass' as const } : gateFail ? { gate: 'fail' as const } : {}),
|
|
2393
2422
|
};
|
|
2394
2423
|
};
|
|
2424
|
+
const claimCommentsFor = async (repository: string, number: number): Promise<string[]> => {
|
|
2425
|
+
const batched = (await detailFor(repository, number))?.comments;
|
|
2426
|
+
if (batched) return batched;
|
|
2427
|
+
const pages = ghJson<Array<Array<{ body: string; created_at: string }>>>(['api', '--paginate', '--slurp',
|
|
2428
|
+
`repos/${repository}/issues/${number}/comments?per_page=100`], execute);
|
|
2429
|
+
if (!Array.isArray(pages) || pages.some((page) => !Array.isArray(page)
|
|
2430
|
+
|| page.some((comment) => typeof comment.body !== 'string' || !Number.isFinite(Date.parse(comment.created_at)))))
|
|
2431
|
+
throw new Error('Incomplete claim comments');
|
|
2432
|
+
return pages.flat().sort((a, b) => Date.parse(a.created_at) - Date.parse(b.created_at)).map((comment) => comment.body);
|
|
2433
|
+
};
|
|
2395
2434
|
const landingCommentsFor = async (repository: string, number: number): Promise<string[]> =>
|
|
2396
2435
|
((await detailFor(repository, number))?.comments ?? await issueCommentsFor(repository, number, 'landing'))
|
|
2397
2436
|
.filter((body) => /\blanding-verified\b/i.test(body));
|
|
@@ -2520,18 +2559,14 @@ export function githubDraftSweepAdapters(execute: GhExecute = executeGh, git: Dr
|
|
|
2520
2559
|
execute(['pr', 'close', String(number), '--repo', repository, '--comment', comment]);
|
|
2521
2560
|
},
|
|
2522
2561
|
getClaimOwner: async (repository, number) => claimCommentOwner(repository, number, execute),
|
|
2523
|
-
getActiveClaimOwner: async (repository, number) =>
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
throw new Error('Incomplete claim comments');
|
|
2532
|
-
return activeClaimOwnerFromBodies(pages.flat().sort((a, b) => Date.parse(a.created_at) - Date.parse(b.created_at))
|
|
2533
|
-
.map((comment) => comment.body));
|
|
2534
|
-
},
|
|
2562
|
+
getActiveClaimOwner: async (repository, number) => activeClaimOwnerFromBodies(await claimCommentsFor(repository, number)),
|
|
2563
|
+
getActiveClaimRunId: async (repository, number) => activeClaimRunIdFromBodies(await claimCommentsFor(repository, number)),
|
|
2564
|
+
getLastClaimReleaseAt: async (repository, number) => lastClaimReleaseAtFromBodies(await claimCommentsFor(repository, number)),
|
|
2565
|
+
listTaskCards: async () => Object.values(readTaskAgentState<{ tasks?: Record<string, TaskCard> }>(taskAgentStatePath()).tasks ?? {}),
|
|
2566
|
+
listPrTerminals: async () => listRunLedgers().matches.flatMap((match) => match.entries.filter((entry) => entry.event === 'pr-terminal')
|
|
2567
|
+
.map((entry) => entry.data as unknown as PrTerminalRecord)),
|
|
2568
|
+
commentDraft: async (repository, number, body) => { execute(['pr', 'comment', String(number), '--repo', repository, '--body', body]); },
|
|
2569
|
+
removeLabel: async (repository, number, name) => { execute(['pr', 'edit', String(number), '--repo', repository, '--remove-label', name]); },
|
|
2535
2570
|
getReviewGate: async (draft, repository) => reviewGateForDraft(draft, repository),
|
|
2536
2571
|
};
|
|
2537
2572
|
}
|
|
@@ -2548,6 +2583,8 @@ export interface HarnessDraftSweepDeps {
|
|
|
2548
2583
|
readonly runTtl?: RunTtlAdapters;
|
|
2549
2584
|
/** Test seam for `tools.selfImplement.draftSweepCloseCap`; omitted ⇒ the user config. */
|
|
2550
2585
|
readonly closeCapConfig?: () => unknown;
|
|
2586
|
+
/** Replay test seam; production reads this instance's host run-ledger directory. */
|
|
2587
|
+
readonly residueReplay?: DraftResidueReplayOptions;
|
|
2551
2588
|
}
|
|
2552
2589
|
|
|
2553
2590
|
/** RUN-TTL step inside the draft sweep — fail-soft: its failure never changes the sweep verdict. */
|
|
@@ -2576,6 +2613,18 @@ export function activeClaimOwnerFromBodies(bodies: readonly string[]): string |
|
|
|
2576
2613
|
return last ? draftClaimOwner(last) : undefined;
|
|
2577
2614
|
}
|
|
2578
2615
|
|
|
2616
|
+
export function activeClaimRunIdFromBodies(bodies: readonly string[]): string | undefined {
|
|
2617
|
+
const last = [...bodies].reverse().find((body) => draftClaimOwner(body) !== undefined || body.startsWith('🔧 처리 끝 —'));
|
|
2618
|
+
return last && draftClaimOwner(last) ? / · run (\S+)/.exec(last)?.[1] : undefined;
|
|
2619
|
+
}
|
|
2620
|
+
|
|
2621
|
+
/** Timestamp of the latest marker when it is a release ('' when its time is unreadable); undefined otherwise. */
|
|
2622
|
+
export function lastClaimReleaseAtFromBodies(bodies: readonly string[]): string | undefined {
|
|
2623
|
+
const last = [...bodies].reverse().find((body) => draftClaimOwner(body) !== undefined || body.startsWith('🔧 처리 끝 —'));
|
|
2624
|
+
if (!last || draftClaimOwner(last) !== undefined) return undefined;
|
|
2625
|
+
return /^🔧 처리 끝 — (\S+)/.exec(last)?.[1] ?? '';
|
|
2626
|
+
}
|
|
2627
|
+
|
|
2579
2628
|
function draftClaimOwner(body: string): string | undefined {
|
|
2580
2629
|
return /^🔧 처리 중 — owner ([^\n·]+?) · /m.exec(body)?.[1]?.trim();
|
|
2581
2630
|
}
|
|
@@ -2619,12 +2668,12 @@ function installHarnessDraftSweepCommand(harnessCmd: Command, deps: HarnessDraft
|
|
|
2619
2668
|
}
|
|
2620
2669
|
const stalled = PR_LABELS.find((label) => label.axis === 'state' && label.sweep.action === 'close' && label.name.endsWith(':stalled'))!.name;
|
|
2621
2670
|
execute(['pr', 'edit', number, '--repo', repository, '--add-label', stalled, '--remove-label', running]);
|
|
2622
|
-
execute(['pr', 'comment', number, '--repo', repository, '--body',
|
|
2671
|
+
execute(['pr', 'comment', number, '--repo', repository, '--body', draftReleaseComment(deps.now?.() ?? new Date())]);
|
|
2623
2672
|
} else {
|
|
2624
2673
|
execute(['pr', 'edit', number, '--repo', repository, '--add-label', running,
|
|
2625
2674
|
...otherStates.flatMap((item) => ['--remove-label', item.name])]);
|
|
2626
2675
|
execute(['pr', 'comment', number, '--repo', repository, '--body',
|
|
2627
|
-
|
|
2676
|
+
draftClaimComment(owner!, deps.now?.() ?? new Date(), opts.note)]);
|
|
2628
2677
|
}
|
|
2629
2678
|
(deps.write ?? console.log)(`#${number} ${opts.release ? 'release' : 'claim'}: ${repository}`);
|
|
2630
2679
|
} catch (error) {
|
|
@@ -2689,8 +2738,19 @@ function installHarnessDraftSweepCommand(harnessCmd: Command, deps: HarnessDraft
|
|
|
2689
2738
|
console.error(`⚠ ${warning}`);
|
|
2690
2739
|
try { debug.log('self-dev.draft-sweep', 'close-cap-rejected', { warning, closeCap: cap.closeCap, closeCapSource: cap.closeCapSource }); } catch { /* fail-soft */ }
|
|
2691
2740
|
}
|
|
2741
|
+
let replayClosed = 0;
|
|
2742
|
+
if (opts.apply && (!deps.adapters || deps.residueReplay)) {
|
|
2743
|
+
try {
|
|
2744
|
+
replayClosed = (await replayPodTerminals({ ...deps.residueReplay, repository, closeCap: cap.closeCap })).closed;
|
|
2745
|
+
} catch (error) {
|
|
2746
|
+
// Review r5: a replay that throws may already have closed PRs — spend the whole cap so this tick cannot exceed it.
|
|
2747
|
+
replayClosed = cap.closeCap;
|
|
2748
|
+
debug.log('draft.residue', 'failed', { childRunId: null, prNumber: null, terminalClass: null,
|
|
2749
|
+
owner: 'unknown', ownerSource: 'unknown', step: 'replay', reason: sweepFailureReason(error) });
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2692
2752
|
const result: DraftSweepResult = await runDraftSweep({ repository, apply: opts.apply === true, adapters: deps.adapters ?? github!,
|
|
2693
|
-
closeCap: cap.closeCap, closeCapSource: cap.closeCapSource });
|
|
2753
|
+
closeCap: cap.closeCap, closeCapSource: cap.closeCapSource, alreadyClosed: replayClosed });
|
|
2694
2754
|
const reason = result.error ? sweepFailureReason(result.error) : undefined;
|
|
2695
2755
|
const ttlStarted = Date.now();
|
|
2696
2756
|
const runTtl = await draftSweepRunTtl(repository, deps, github);
|
|
@@ -2955,6 +3015,7 @@ export interface HarnessCliCommandDeps {
|
|
|
2955
3015
|
processObservation?: HarnessProcessObservationDeps;
|
|
2956
3016
|
draftSweep?: HarnessDraftSweepDeps;
|
|
2957
3017
|
queue?: HarnessQueueDeps;
|
|
3018
|
+
backpressure?: BackpressureReadDeps;
|
|
2958
3019
|
goalLookup?: GoalLookupOptions;
|
|
2959
3020
|
goalArchive?: GoalArchiveOptions;
|
|
2960
3021
|
ask?: HarnessAskHandler;
|
|
@@ -3034,6 +3095,24 @@ export function installHarnessCliCommand(program: Command, deps: HarnessCliComma
|
|
|
3034
3095
|
installHarnessGoalCommand(harnessCmd, deps.goalLookup, deps.goalArchive);
|
|
3035
3096
|
installHarnessDraftSweepCommand(harnessCmd, deps.draftSweep);
|
|
3036
3097
|
const queue = harnessCmd.command('queue').description('자리별 영속 발사 대기열');
|
|
3098
|
+
queue.command('backpressure').description('읽기 전용 발사 역압 판정')
|
|
3099
|
+
.option('--json', '판정 객체 JSON 한 줄').option('--max <n>', '주기당 발사 상한 (기본 6)')
|
|
3100
|
+
.action((opts: { json?: boolean; max?: string }) => {
|
|
3101
|
+
if (opts.max !== undefined && (!/^(0|[1-9][0-9]*)$/.test(opts.max) || !Number.isSafeInteger(Number(opts.max)))) {
|
|
3102
|
+
console.error('❌ --max 는 0 이상의 정수여야 합니다');
|
|
3103
|
+
process.exitCode = 2;
|
|
3104
|
+
return;
|
|
3105
|
+
}
|
|
3106
|
+
try {
|
|
3107
|
+
const signals = readBackpressureSignals(deps.backpressure);
|
|
3108
|
+
const verdict = decideBackpressure(signals, { maxPerCycle: opts.max === undefined ? 6 : Number(opts.max) });
|
|
3109
|
+
debug.log('traffic.backpressure', 'verdict', { launchBudget: verdict.launchBudget, reasons: verdict.reasons, signals: verdict.signals });
|
|
3110
|
+
console.log(opts.json ? JSON.stringify(verdict) : `발사 예산 ${verdict.launchBudget} · 이유 ${verdict.reasons.join(', ') || '없음'}`);
|
|
3111
|
+
} catch (error) {
|
|
3112
|
+
console.error(`❌ backpressure: ${error instanceof Error ? error.message : String(error)}`);
|
|
3113
|
+
process.exitCode = 1;
|
|
3114
|
+
}
|
|
3115
|
+
});
|
|
3037
3116
|
const queueDeps = deps.queue ?? {};
|
|
3038
3117
|
let launchedExit: Promise<number> | undefined;
|
|
3039
3118
|
const immediateLaunch: NonNullable<HarnessQueueDeps['launch']> = queueDeps.launch ?? (async (item: QueueItem, args: string[], root: string) => {
|
|
@@ -34,7 +34,8 @@ import { getHarnessSpace, resolveRunIdentity } from './harness-space.js';
|
|
|
34
34
|
import type { AutonomyRiskHit, HarnessGroundingRef } from '../self-implement/context-capsule.js';
|
|
35
35
|
import { AUTO_REVIEW_LABEL, resolveAutoReviewLabels } from '../self-implement/context-capsule.js';
|
|
36
36
|
import { verbatimOriginalAsk } from '../self-implement/goal-author.js';
|
|
37
|
-
import {
|
|
37
|
+
import { extractHarnessReviewAcceptance } from '../self-implement/goal-digest.js';
|
|
38
|
+
export { extractHarnessReviewAcceptance } from '../self-implement/goal-digest.js';
|
|
38
39
|
|
|
39
40
|
const AUTOREVIEW_SENTENCE_LIMIT = 240;
|
|
40
41
|
const SECURITY_RISK_REASON = '보안/인증 정보';
|
|
@@ -222,25 +223,6 @@ async function buildPrBody(
|
|
|
222
223
|
} catch { return heuristic(); }
|
|
223
224
|
}
|
|
224
225
|
|
|
225
|
-
/** 골 문서에서 `판정 신호` 절만 뽑아 리뷰 acceptance 로 쓴다. 계보 = self-implement seams. */
|
|
226
|
-
export function extractHarnessReviewAcceptance(goalDocument: string | undefined): { goal: string | undefined; acceptance: string | undefined } {
|
|
227
|
-
let goal: string | undefined;
|
|
228
|
-
try {
|
|
229
|
-
goal = goalDocument?.trim() || undefined;
|
|
230
|
-
} catch {
|
|
231
|
-
return { goal: undefined, acceptance: undefined };
|
|
232
|
-
}
|
|
233
|
-
if (!goal) return { goal: undefined, acceptance: undefined };
|
|
234
|
-
try {
|
|
235
|
-
const acceptance = splitGoalSections(supervisorGoalDigest(goal, 3000).text)
|
|
236
|
-
.find((section) => isSupervisorDecisionSection(section.title) && section.title.includes('판정 신호'))
|
|
237
|
-
?.body.trim() || undefined;
|
|
238
|
-
return { goal, acceptance };
|
|
239
|
-
} catch {
|
|
240
|
-
return { goal, acceptance: undefined };
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
226
|
function reviewAcceptanceObservation(goal: string | undefined, acceptance: string | undefined): { goalLoaded: boolean; acceptanceChars: number } {
|
|
245
227
|
return { goalLoaded: Boolean(goal), acceptanceChars: acceptance?.length ?? 0 };
|
|
246
228
|
}
|
|
@@ -1,5 +1,76 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
|
-
import
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { effectiveInstanceRoot, prodInstanceRoot, treeDerivedRootFor } from '../instance/resolve.js';
|
|
5
|
+
import { getElanousConfigDirOverride } from '../elanous-config-dir.js';
|
|
6
|
+
import { buildUserConfig, getUserConfig, type UserConfig } from '../user-config.js';
|
|
7
|
+
import { resolveCodexQuotaPolicy } from '../oauth/codex-quota-policy.js';
|
|
8
|
+
|
|
9
|
+
/** Key-order-insensitive JSON so equal per-account caps written in another order do not warn. */
|
|
10
|
+
function stableJson(value: unknown): string {
|
|
11
|
+
return JSON.stringify(value, (_key, v: unknown) => v && typeof v === 'object' && !Array.isArray(v)
|
|
12
|
+
? Object.fromEntries(Object.entries(v as Record<string, unknown>).sort(([a], [b]) => a.localeCompare(b)))
|
|
13
|
+
: v);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function readOperationalLaunchConfig(path: string): UserConfig | null {
|
|
17
|
+
let text: string;
|
|
18
|
+
try { text = readFileSync(path, 'utf8'); }
|
|
19
|
+
catch (err) {
|
|
20
|
+
// Only a missing file (fresh install, CI, isolated fixtures) means «no operational policy»; permission or I/O errors refuse.
|
|
21
|
+
if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;
|
|
22
|
+
throw new Error(`launch policy: 운영 config 를 읽을 수 없다 — ${path}`);
|
|
23
|
+
}
|
|
24
|
+
let raw: unknown;
|
|
25
|
+
try { raw = JSON.parse(text); }
|
|
26
|
+
catch { throw new Error(`launch policy: 운영 config 를 읽을 수 없다 — ${path}`); }
|
|
27
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) throw new Error(`launch policy: 운영 config 형식이 잘못됐다 — ${path}`);
|
|
28
|
+
return buildUserConfig(path);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Launch policy belongs to the host, not to the materialized config in a derived worktree.
|
|
32
|
+
* Explicit test/config universes remain isolated; this only applies to tree-derived launches. */
|
|
33
|
+
export function harnessLaunchPolicyConfig(options: {
|
|
34
|
+
derived?: UserConfig;
|
|
35
|
+
operationalRoot?: string;
|
|
36
|
+
derivedRoot?: string;
|
|
37
|
+
warn?: (line: string) => void;
|
|
38
|
+
/** Reads the operational config at `path`; injected by tests so they never touch the host's real config. */
|
|
39
|
+
readOperational?: (path: string) => UserConfig | null;
|
|
40
|
+
} = {}): UserConfig {
|
|
41
|
+
const derived = options.derived ?? getUserConfig();
|
|
42
|
+
const operationalRoot = options.operationalRoot ?? prodInstanceRoot();
|
|
43
|
+
const derivedRoot = options.derivedRoot ?? effectiveInstanceRoot();
|
|
44
|
+
const isDerived = options.derivedRoot !== undefined
|
|
45
|
+
? derivedRoot !== operationalRoot
|
|
46
|
+
: derivedRoot !== operationalRoot && !getElanousConfigDirOverride() && (
|
|
47
|
+
process.env.ELANOUS_STATE_DIR_SOURCE === 'derived'
|
|
48
|
+
|| derivedRoot === treeDerivedRootFor(process.cwd())
|
|
49
|
+
);
|
|
50
|
+
if (!isDerived) return derived;
|
|
51
|
+
const path = join(operationalRoot, 'config.json');
|
|
52
|
+
const operational = (options.readOperational ?? readOperationalLaunchConfig)(path);
|
|
53
|
+
if (!operational) {
|
|
54
|
+
(options.warn ?? console.error)(`⚠️ launch policy: 운영 config 가 없다 (${path}) — 이 우주의 정책으로 발사`);
|
|
55
|
+
return derived;
|
|
56
|
+
}
|
|
57
|
+
const policy = (config: UserConfig) => ({
|
|
58
|
+
quota: resolveCodexQuotaPolicy(config.llm).policy,
|
|
59
|
+
accountLimits: config.llm?.codexAccountRotationThresholdPercentByAccount,
|
|
60
|
+
fallbackChain: config.llm?.fallbackChain,
|
|
61
|
+
childLlm: config.tools?.selfImplement?.childLlm,
|
|
62
|
+
budgetGate: config.harness?.budgetGate,
|
|
63
|
+
podPool: config.harness?.podPool ?? config.pod?.pool,
|
|
64
|
+
grokApiKeyOptIn: config.harness?.pod?.grokApiKeyOptIn === true,
|
|
65
|
+
});
|
|
66
|
+
const actual = policy(derived);
|
|
67
|
+
const expected = policy(operational);
|
|
68
|
+
if (derived.llm?.codexQuotaPolicy === undefined && derived.llm?.codexCreditsAllowed === undefined
|
|
69
|
+
|| stableJson(actual) !== stableJson(expected)) {
|
|
70
|
+
(options.warn ?? console.error)('⚠️ launch policy: 파생 시험 우주 정책이 없거나 운영과 다르다 — 운영 정책으로 발사');
|
|
71
|
+
}
|
|
72
|
+
return operational;
|
|
73
|
+
}
|
|
3
74
|
|
|
4
75
|
export type HarnessSubstrate = 'local' | 'pod';
|
|
5
76
|
export interface ResolvedHarnessSubstrate {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
//
|
|
3
3
|
// Codex children drop parent env under shell_environment_policy inherit=core, so a
|
|
4
4
|
// depth marker that only lives in the environment never arrives. Depth is therefore
|
|
5
|
-
// carried on the codex argv (`-c shell_environment_policy.set.ELANOUS_NESTED_DEPTH
|
|
5
|
+
// carried on the codex argv (`-c shell_environment_policy.set.ELANOUS_NESTED_DEPTH="<n>"` — TOML 문자열).
|
|
6
6
|
//
|
|
7
7
|
// Unset ELANOUS_NESTED_DEPTH is depth 0 (the outer launcher). A missing marker is
|
|
8
8
|
// not "depth unknown" and does not refuse an ordinary mission spawn.
|
|
@@ -50,7 +50,9 @@ export function backendCarriesNestedDepth(backendName: string): boolean {
|
|
|
50
50
|
export function nestedDepthCodexArgs(backendName: string, childDepth: number): string[] {
|
|
51
51
|
if (backendName !== 'codex') return [];
|
|
52
52
|
if (!Number.isInteger(childDepth) || childDepth < 0) return [];
|
|
53
|
-
|
|
53
|
+
// 🩸 CODEX-NESTED-DEPTH-QUOTE(2026-10-09): `-c` 값은 TOML 이고 shell_environment_policy.set 은 «문자열» 맵이다.
|
|
54
|
+
// 맨 정수(`=1`)는 codex 0.159.3 에서 «failed to load bootstrap configuration» 으로 자식을 바로 죽인다 → 따옴표로 문자열.
|
|
55
|
+
return ['-c', `${CODEX_NESTED_DEPTH_CONFIG_KEY}="${childDepth}"`];
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
/**
|
package/src/hq/fence-wrapper.ts
CHANGED
|
@@ -69,6 +69,13 @@ if [ $# -lt 1 ] || [ -z "$1" ]; then
|
|
|
69
69
|
fi
|
|
70
70
|
ROLE=$1
|
|
71
71
|
shift
|
|
72
|
+
# FENCE-LIGHT: only when this host's heartbeat left a lease-cache file and the installed package ships the light fence.
|
|
73
|
+
# No cache file = exactly the CLI path below. The sourced script always exits; returning is a fail-closed error.
|
|
74
|
+
if [ -f "$CONFIG_DIR/hq/lease-cache" ] && [ -f scripts/hq/hq-fence-wrapper.sh ]; then
|
|
75
|
+
. scripts/hq/hq-fence-wrapper.sh
|
|
76
|
+
log_line "light fence returned without a decision (role=$ROLE)"
|
|
77
|
+
exit 1
|
|
78
|
+
fi
|
|
72
79
|
"$BUN" "$ENTRY" --config-dir "$CONFIG_DIR" hq fence --role "$ROLE" -- /bin/sh -c "$*"
|
|
73
80
|
rc=$?
|
|
74
81
|
if [ "$rc" -ne 0 ]; then alert "hq-fence: fence failed (rc=$rc, role=$ROLE)"; fi
|
package/src/hq/hq.ts
CHANGED
|
@@ -14,8 +14,8 @@ import { fenceOutcomeDir, recordFenceOutcome } from './fence-outcomes.js';
|
|
|
14
14
|
import { promoteHq, proposeHqPromotion, writeOpSeatRequest } from './promote.js';
|
|
15
15
|
import type { HqOpRequestWriter, PromoteResult } from './promote.js';
|
|
16
16
|
import {
|
|
17
|
-
DEFAULT_TTL_SECONDS, decideAcquire, decideArbiterCheck, decideFence, decideRelease, decideRenew, defaultSshRunner,
|
|
18
|
-
fileLeaseStore, leaseExpired, parseLease, probeReachable, recordView, serializeLease, sshLeaseStore, sshReachable, localShellRunner,
|
|
17
|
+
DEFAULT_TTL_SECONDS, LOCAL_LEASE_CACHE_SECONDS, decideAcquire, decideArbiterCheck, decideFence, decideRelease, decideRenew, defaultSshRunner,
|
|
18
|
+
fileLeaseStore, leaseExpired, parseLease, probeReachable, recordView, serializeLease, serializeLocalLeaseCache, sshLeaseStore, sshReachable, localShellRunner,
|
|
19
19
|
type HostProbe, type LeaseRecord, type LeaseStore, type LocalHqState, type SshRunner,
|
|
20
20
|
} from './lease.js';
|
|
21
21
|
|
|
@@ -163,6 +163,30 @@ function writeLocal(path: string, state: LocalHqState): void {
|
|
|
163
163
|
renameSync(tmp, path);
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
+
/** FENCE-LIGHT host-local hint (`<config>/hq/lease-cache`), not authority: only a successful holder renewal writes it. */
|
|
167
|
+
const leaseCachePath = (r: Resolved): string => join(dirname(r.localPath), 'lease-cache');
|
|
168
|
+
function dropHeartbeatCache(r: Resolved): void {
|
|
169
|
+
try { rmSync(leaseCachePath(r), { force: true }); }
|
|
170
|
+
catch (error) { observe(r, 'hq.lease', 'cache-invalidate-failed', { error: String(error).slice(0, 200) }); }
|
|
171
|
+
}
|
|
172
|
+
function writeHeartbeatCache(r: Resolved, record: LeaseRecord): void {
|
|
173
|
+
const path = leaseCachePath(r);
|
|
174
|
+
try {
|
|
175
|
+
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
|
176
|
+
const confirmedAt = r.now();
|
|
177
|
+
const expiresAt = Math.min(confirmedAt + LOCAL_LEASE_CACHE_SECONDS, record.renewedAt + record.ttlSeconds);
|
|
178
|
+
if (expiresAt <= confirmedAt) return;
|
|
179
|
+
const tempDir = mkdtempSync(`${path}.`);
|
|
180
|
+
try {
|
|
181
|
+
const tmp = join(tempDir, 'cache');
|
|
182
|
+
writeFileSync(tmp, serializeLocalLeaseCache({ holder: record.holder, generation: record.generation, expiresAt, host: r.me, machine: hostname().replace(/\.local$/, ''), confirmedAt }), { mode: 0o600 });
|
|
183
|
+
renameSync(tmp, path);
|
|
184
|
+
} finally { rmSync(tempDir, { recursive: true, force: true }); }
|
|
185
|
+
} catch (error) {
|
|
186
|
+
observe(r, 'hq.lease', 'cache-write-failed', { error: String(error).slice(0, 200) });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
166
190
|
/** Highest lease generation this host ever observed (null = never). */
|
|
167
191
|
/** The seen-generation marker this host keeps (hq.seenGenerationFile · default ~/.elanous-hq/seen-generation). */
|
|
168
192
|
export function hqSeenGenerationPath(config: Pick<HqConfig, 'seenGenerationFile'>): string {
|
|
@@ -241,6 +265,7 @@ export function hqLease(action: LeaseAction, deps: HqDeps = {}, opts: { host?: s
|
|
|
241
265
|
const result = mutate(r, (record, now) => action === 'acquire' ? decideAcquire(record, r.me, now, r.ttl)
|
|
242
266
|
: action === 'renew' ? decideRenew(record, r.me, local.generation, now) : decideRelease(record, r.me, expected));
|
|
243
267
|
noteSeen(r, result.record);
|
|
268
|
+
if (result.ok) dropHeartbeatCache(r);
|
|
244
269
|
if (result.ok && action !== 'release') writeLocal(r.localPath, { holder: result.record.holder, generation: result.record.generation, confirmedAt: r.now(), ttlSeconds: result.record.ttlSeconds });
|
|
245
270
|
if (result.ok && action === 'release') writeLocal(r.localPath, { ...local, holder: undefined, confirmedAt: undefined });
|
|
246
271
|
observe(r, 'hq.lease', result.ok ? (action === 'acquire' ? 'acquired' : action === 'renew' ? 'renewed' : 'released') : `${action}-refused`,
|
|
@@ -255,6 +280,8 @@ export function hqLease(action: LeaseAction, deps: HqDeps = {}, opts: { host?: s
|
|
|
255
280
|
export function hqHeartbeat(deps: HqDeps = {}) {
|
|
256
281
|
const r = resolve(deps);
|
|
257
282
|
const local = readLocal(r.localPath);
|
|
283
|
+
// Never extend a prior positive hint through an unreachable/refused heartbeat.
|
|
284
|
+
dropHeartbeatCache(r);
|
|
258
285
|
let read: { now: number; raw: string | null };
|
|
259
286
|
try { read = r.store.read(); } catch (error) {
|
|
260
287
|
const standbyUp = local.holder === r.me ? sshReachable(r.standby, r.ssh) : false;
|
|
@@ -273,6 +300,7 @@ export function hqHeartbeat(deps: HqDeps = {}) {
|
|
|
273
300
|
if (renewed.ok) {
|
|
274
301
|
noteSeen(r, renewed.record);
|
|
275
302
|
writeLocal(r.localPath, { holder: r.me, generation: renewed.record.generation, confirmedAt: r.now(), ttlSeconds: renewed.record.ttlSeconds });
|
|
303
|
+
if (record.renewedAt !== 0 && !leaseExpired(renewed.record, r.now())) writeHeartbeatCache(r, renewed.record);
|
|
276
304
|
observe(r, 'hq.lease', 'renewed', { generation: renewed.record.generation });
|
|
277
305
|
return { outcome: 'renewed' as const, generation: renewed.record.generation };
|
|
278
306
|
}
|
|
@@ -282,6 +310,7 @@ export function hqHeartbeat(deps: HqDeps = {}) {
|
|
|
282
310
|
// Not the holder: report the view, keep the granted generation, stay standby.
|
|
283
311
|
const seen = probeReachable(record.holder, r.probe);
|
|
284
312
|
const reachable = seen.reachable;
|
|
313
|
+
// FENCE-LIGHT: a standby never writes the cache (the shell fence only fast-paths a fresh «this host holds» line).
|
|
285
314
|
mutate(r, (current) => current ? { ok: true, next: recordView(current, r.me, reachable, read.now) } : { ok: false, reason: 'no lease' });
|
|
286
315
|
if (leaseExpired(record, read.now)) observe(r, 'hq.lease', 'expired-seen', { holder: record.holder, generation: record.generation });
|
|
287
316
|
writeLocal(r.localPath, { holder: record.holder, generation: record.generation, ttlSeconds: record.ttlSeconds });
|
|
@@ -365,6 +394,8 @@ export function hqFenceDecision(role: HqFenceRole, deps: HqDeps = {}) {
|
|
|
365
394
|
failOpen: role !== 'ledger-cli' && r.failOpen.has(role),
|
|
366
395
|
...(seenGeneration !== null ? { seenGeneration } : {}),
|
|
367
396
|
});
|
|
397
|
+
// FENCE-LIGHT: any CLI «do not run» on this host retires a lingering fast-path hint at once.
|
|
398
|
+
if (!decided.run) dropHeartbeatCache(r);
|
|
368
399
|
if (decided.run && record !== 'unreachable' && record) writeLocal(r.localPath, { holder: r.me, generation: record.generation, confirmedAt: r.now(), ttlSeconds: record.ttlSeconds });
|
|
369
400
|
observe(r, 'hq.fence', decided.run ? 'allowed' : 'skipped', { role, reason: decided.reason, holder: decided.holder, generation: decided.generation });
|
|
370
401
|
return decided;
|
package/src/hq/lease.ts
CHANGED
|
@@ -36,6 +36,19 @@ export function parseLease(raw: string | null): LeaseRecord | null {
|
|
|
36
36
|
export const serializeLease = (record: LeaseRecord): string => `${JSON.stringify(record)}\n`;
|
|
37
37
|
export const leaseExpired = (record: LeaseRecord, now: number): boolean => record.renewedAt + record.ttlSeconds < now;
|
|
38
38
|
|
|
39
|
+
/** Host-local, short-lived shell fence snapshot; never the arbiter's CAS lease ledger. */
|
|
40
|
+
export interface LocalLeaseCache { holder: string; generation: number; expiresAt: number; host: string; machine: string; confirmedAt: number }
|
|
41
|
+
export const LOCAL_LEASE_CACHE_SECONDS = 660; // heartbeat cadence 600s + 60s scheduling slack; still below the 1500s lease TTL
|
|
42
|
+
/** A single whitespace-delimited line so /bin/sh can read it without bun or JSON tools. */
|
|
43
|
+
export function serializeLocalLeaseCache(cache: LocalLeaseCache): string {
|
|
44
|
+
if (![cache.holder, cache.host, cache.machine].every(value => /^[A-Za-z0-9_.-]+$/.test(value))
|
|
45
|
+
|| !Number.isSafeInteger(cache.generation) || cache.generation < 1
|
|
46
|
+
|| !Number.isSafeInteger(cache.expiresAt) || cache.expiresAt < 1
|
|
47
|
+
|| !Number.isSafeInteger(cache.confirmedAt) || cache.confirmedAt < 1
|
|
48
|
+
|| cache.expiresAt <= cache.confirmedAt || cache.expiresAt - cache.confirmedAt > LOCAL_LEASE_CACHE_SECONDS) throw new Error('invalid local lease cache');
|
|
49
|
+
return `${cache.holder} ${cache.generation} ${cache.expiresAt} ${cache.host} ${cache.machine} ${cache.confirmedAt}\n`;
|
|
50
|
+
}
|
|
51
|
+
|
|
39
52
|
/** acquire: only when there is no lease or it has expired; a new holder gets the next generation. */
|
|
40
53
|
export function decideAcquire(record: LeaseRecord | null, me: string, now: number, ttlSeconds = DEFAULT_TTL_SECONDS):
|
|
41
54
|
{ ok: true; next: LeaseRecord } | { ok: false; reason: string } {
|