elanous 0.2.22 → 0.2.24
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/{aBi6EyMtLsrl7J8eH4kF7 → Q-7iofoxOEv1WX18S35of}/_buildManifest.js +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-0eed0fb0aab716b6.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-aaae04ed1d32622f.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-3b9fc39362473ae7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f2b62c19ca68fef8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-d7602d489edf5f37.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-24282bf9f90031a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-8b7c5ab6b5bc8d64.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-4eb84d454f8c3415.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-b2e494bdad57fcb5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/{page-80ed511e02c81412.js → page-c0ab229673a8b0eb.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-3e2b45f3c36dbac4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-c22aa511b28743ad.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-26345242e4049f55.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-bf88c0f558d8ef54.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-52fec523e5b5d3ad.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-67723dfdcde92b31.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-22725e2570f1126b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-1891335950d68b70.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-3267af1ebdc73cf5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-c314b75c11234998.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-9f9c85415f61782b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-c1d4276059085587.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-833aab587f26ad4c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8526c17ae38e6a50.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-f998637a8402115c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-b7bb53828b17b335.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-1b1850de0257e46d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6f23159fedb41f67.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1d809a87139dd024.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-da9e570234d481fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-b92caddb5c715f30.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-8ce3a38e210b810a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-57ffeeb6019440fd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-abbb417bf514630b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-2c2b3f29cec1efa4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-9369279f72fc7b51.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-64861f14039499c3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ddc4c93efd8ab94b.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-901a1391b81053bc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-68d9bbaac9841a58.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-b5c0c996f329371e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-89881ccbcf728978.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-0e87a803b3d7165e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-58d4e5cb30ef4871.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-02ce4c3b5f39e4d2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-e620d1bb8eadcec2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-acf868c64d77f950.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-54fa605fa6dba457.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-bc79f0833533fa84.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-d5c4398eea03d8f3.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/72becfd42807b50d.css +1 -0
- package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +1 -0
- 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/catalog/models/openrouter/deepseek-v4-pro-0813.yaml +39 -0
- package/catalog/models/openrouter/deepseek-v4.1-flash.yaml +38 -0
- package/catalog/models/openrouter/glm-5.3-flash.yaml +35 -0
- package/catalog/providers/openrouter.yaml +2 -0
- package/graphs/implement-loop.yaml +31 -0
- package/graphs/log-horizon/log-horizon-watch.yaml +25 -0
- package/graphs/log-horizon/recipes.yaml +3 -0
- package/graphs/ops/harness-gc.yaml +17 -0
- package/graphs/ops/recipes.yaml +3 -0
- package/graphs/overlays/README.md +1 -1
- package/graphs/overlays/stop-heal-ladder.yaml +105 -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/add-api-key.sh +1 -1
- package/scripts/bench-report.ts +82 -3
- package/scripts/ci-typecheck-changed.ts +80 -14
- package/scripts/fleet/bedrock-pod-secret.ts +122 -0
- package/scripts/fleet/node-setup-linux.sh +97 -0
- package/scripts/fleet/node-setup.sh +11 -0
- package/scripts/fleet/zai-pod-secret.ts +86 -0
- package/scripts/hq/hq-fence-wrapper.sh +148 -0
- package/scripts/land-global-checks.ts +3 -0
- package/scripts/lib/typecheck-ratchet.ts +51 -0
- package/scripts/measure-log-diet-2.ts +213 -0
- package/scripts/measure-tsc-affected-roots.ts +289 -0
- package/scripts/openai-relay-server.ts +5 -1
- package/scripts/release-loop/docs-node.ts +258 -43
- package/scripts/release-loop/gate-executor.ts +28 -0
- package/scripts/release-loop/gate-method.ts +59 -0
- package/scripts/release-loop/gate-node.ts +335 -33
- 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 +40 -4
- package/scripts/release-loop/resume.ts +94 -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 +29 -7
- package/scripts/rhythm/daily.ts +51 -2
- package/scripts/rhythm/weekly.ts +3 -2
- package/scripts/tsc-baseline-cache.ts +147 -0
- package/scripts/tsc-main-safety-net.ts +189 -0
- package/scripts/usage-rollup.ts +64 -8
- package/src/acp/codex-plugins.ts +48 -6
- package/src/agent/monad-agent-turn.ts +67 -5
- package/src/agent/run-context.ts +20 -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 +19 -4
- package/src/agent-mission/pr-review-watch.ts +6 -2
- package/src/agent-mission/resource-ladder.ts +8 -3
- package/src/agent-mission/review-loop.ts +41 -7
- package/src/agent-substrate/acp-implementer.ts +139 -0
- package/src/agent-substrate/acp-reviewer.ts +17 -8
- package/src/agent-substrate/pr-reviewer.ts +191 -28
- package/src/agent-substrate/review-intent.ts +6 -4
- package/src/agent-substrate/self-review-cli.ts +155 -21
- 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/mission-critique.ts +18 -5
- package/src/autopilot/mission-feasibility-negotiate.ts +11 -10
- package/src/autopilot/mission-trace.ts +12 -1
- package/src/autopilot/pr-manager.ts +12 -3
- package/src/autopilot/system-lookback-run.ts +16 -10
- package/src/bench/bench.ts +183 -0
- 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/budget/fetchers/grok.ts +15 -5
- package/src/budget/llm-cost.ts +37 -5
- package/src/budget/types.ts +8 -2
- package/src/budget/unified-usage.ts +88 -6
- package/src/chat/index.ts +12 -3
- package/src/cli/agent-cli.ts +20 -0
- package/src/cli/bench-cli.ts +34 -0
- package/src/cli/brief-cli.ts +27 -21
- package/src/cli/cli-user-error.ts +9 -2
- package/src/cli/guardian-cli.ts +26 -1
- package/src/cli/image-cli.ts +101 -0
- package/src/cli/log-event-names.ts +7 -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 +90 -5
- package/src/cli/pr-land-overlap-evidence.ts +279 -0
- package/src/cli/release-cli.ts +63 -12
- package/src/cli/rfc-status.ts +52 -2
- package/src/cli/self-update.ts +277 -10
- package/src/cli/skills-cli.ts +12 -3
- package/src/cli/tasks-cli.ts +241 -30
- package/src/cli/usage-cli.ts +91 -8
- 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 +87 -2
- package/src/dashboard/ad-run-setup-bindings.ts +279 -0
- package/src/dashboard/chat-fold.ts +20 -0
- package/src/dashboard/first-screen-band.ts +151 -1
- package/src/dashboard/index.ts +45 -281
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +5 -3
- package/src/dashboard/stale-install-check.ts +24 -2
- package/src/dashboard/turn-stream-formatter.ts +25 -0
- package/src/debug/log-diet.ts +190 -0
- package/src/debug/log.ts +70 -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 +158 -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/error-report/report.ts +21 -4
- 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 +2 -0
- package/src/graph-runner/graph-cli.ts +42 -1
- package/src/graph-runner/runner.ts +218 -8
- package/src/grok/usage.ts +23 -2
- package/src/grounding/ref-index.ts +253 -0
- package/src/harness/dispatch-backpressure.ts +267 -0
- package/src/harness/harness-clean.ts +199 -78
- package/src/harness/harness-cli-command.ts +229 -35
- package/src/harness/harness-gc.ts +331 -0
- package/src/harness/harness-seams.ts +2 -20
- package/src/harness/harness-stop.ts +4 -2
- package/src/harness/harness-substrate-default.ts +214 -8
- package/src/harness/launch-registry.ts +6 -0
- package/src/harness/nested-elanous-policy.ts +4 -2
- package/src/harness/worktree-branch-prefix.ts +9 -0
- package/src/hq/fence-wrapper.ts +7 -0
- package/src/hq/fence.ts +187 -0
- package/src/hq/hq.ts +33 -2
- package/src/hq/lease.ts +13 -0
- package/src/hq/seats.ts +133 -21
- package/src/images/image-ledger.ts +179 -0
- package/src/index.ts +250 -69
- package/src/instance/child-scope.ts +32 -1
- package/src/instance/dev-project.ts +133 -0
- package/src/instance/resolve.ts +24 -0
- package/src/instance/spawn-elanous.ts +45 -0
- 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/intake-plane/ref-prefetch.ts +110 -0
- package/src/intelligence-map/model-alias.ts +6 -0
- package/src/intelligence-map/model-catalog.ts +113 -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-eventstream.ts +215 -0
- package/src/llm/bedrock-provider.ts +248 -0
- package/src/llm/bedrock.ts +491 -0
- package/src/llm/openrouter-byok-cost.ts +96 -0
- package/src/llm/openrouter-deepseek.ts +151 -0
- package/src/llm/openrouter-upstream-pins.config.ts +25 -0
- package/src/llm/provider-credentials.ts +3 -1
- package/src/llm/zai-coding-plan.ts +700 -0
- package/src/llm.ts +383 -41
- package/src/loops/budget.ts +150 -0
- package/src/loops/checker.ts +148 -9
- package/src/loops/orchestrator/resync-shadow.ts +34 -7
- 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/maturity/feature-maturity.ts +2 -2
- package/src/mcp/mcp-oauth.ts +136 -17
- package/src/model-tier/llm-tier-map.ts +52 -4
- package/src/models/prompts.ts +23 -1
- package/src/mss/logging/horizon-watch.ts +168 -0
- package/src/mss/logging/log-store.ts +262 -26
- 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/missions.ts +73 -2
- package/src/nexus/api/ops-api.ts +18 -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 +17 -75
- package/src/nexus/outbound/format.ts +2 -0
- package/src/nexus/outbound/router.ts +198 -13
- package/src/nexus/tools-kind.ts +78 -0
- package/src/oauth/codex-account-rotation.ts +55 -20
- package/src/oauth/codex-account-store.ts +451 -23
- package/src/oauth/fallback-chain.ts +75 -15
- package/src/onboarding/first-run.ts +37 -18
- package/src/onboarding/web-first.ts +20 -2
- package/src/onboarding.ts +2 -1
- package/src/ops/machine-heartbeat.ts +185 -0
- package/src/ops/overview-cache.ts +175 -0
- package/src/ops/overview.ts +8 -0
- 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 +13 -6
- package/src/prompt-cache/openrouter.ts +94 -0
- package/src/prompt-cache/types.ts +5 -0
- package/src/prompt-enhance/enhance.ts +69 -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 +107 -23
- 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/requirements/requirement-ledger.ts +536 -0
- package/src/retro/daily.ts +26 -12
- package/src/seat-loop/seat-loop.ts +66 -11
- 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 +109 -11
- package/src/self-dev/dev-pipeline.ts +11 -8
- package/src/self-dev/draft-residue.ts +475 -0
- package/src/self-dev/draft-sweep.ts +254 -10
- package/src/self-dev/draft-triage-rules.ts +27 -1
- package/src/self-dev/graph-journey-route.ts +6 -0
- 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 +82 -5
- package/src/self-dev/orchestrate-summary-line.ts +13 -0
- package/src/self-dev/orchestrate.ts +49 -141
- 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 +190 -36
- package/src/self-dev/run-types.ts +191 -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 +3 -4
- package/src/self-implement/blocked-draft-policy.ts +3 -19
- package/src/self-implement/budget-gate.ts +53 -13
- package/src/self-implement/child-context-composition.ts +139 -0
- package/src/self-implement/child-llm-preference.ts +13 -5
- package/src/self-implement/claude-acp-implement.ts +67 -0
- package/src/self-implement/draft-on-stop-mode.ts +18 -0
- package/src/self-implement/flex-signals.ts +59 -0
- package/src/self-implement/follow-up-goals.ts +114 -38
- package/src/self-implement/frozen-merges.ts +8 -3
- 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-decompose.ts +10 -2
- package/src/self-implement/goal-author.ts +48 -13
- package/src/self-implement/goal-digest.ts +19 -0
- package/src/self-implement/graph-overlay-condition.ts +32 -0
- package/src/self-implement/graph-overlay-yaml.ts +41 -7
- package/src/self-implement/graph-templates.ts +33 -1
- package/src/self-implement/graph-yaml.ts +56 -0
- package/src/self-implement/headless-elanous-driver.ts +11 -9
- package/src/self-implement/heal-intake.ts +5 -1
- 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 +271 -25
- 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/running-runs.ts +75 -5
- package/src/self-implement/seams.ts +83 -4
- package/src/self-implement/self-implement-cli.ts +12 -5
- package/src/self-implement/stop-autoheal.ts +69 -2
- 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/session-runtime/retry-policy.ts +2 -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 +22 -10
- package/src/steward/triage-budget.ts +62 -0
- package/src/steward/triage.ts +87 -24
- package/src/storage/file-lock.ts +8 -1
- package/src/task-agent/actions.ts +66 -5
- package/src/task-agent/card-evidence.ts +59 -13
- package/src/task-agent/completion-evidence.ts +5 -0
- package/src/task-agent/cover.ts +101 -3
- package/src/task-agent/judge.ts +20 -3
- package/src/task-agent/land-order-ledger.ts +95 -0
- package/src/task-agent/land-worktree.ts +201 -0
- package/src/task-agent/live-move-history.ts +219 -0
- package/src/task-agent/live-moves.ts +451 -34
- package/src/task-agent/parent-host.ts +117 -8
- package/src/task-agent/rejudge-on-head.ts +352 -0
- package/src/task-agent/review-prior-fix.ts +146 -0
- package/src/task-agent/review-result-capture.ts +218 -0
- package/src/task-agent/run-adopt.ts +136 -0
- package/src/task-agent/shadow.ts +154 -14
- package/src/task-agent/task-hand.ts +186 -14
- package/src/task-orchestrator/surfaces/pod-account-broker.ts +38 -5
- package/src/task-orchestrator/surfaces/pod-bedrock-child.ts +74 -0
- package/src/task-orchestrator/surfaces/pod-child-default.ts +50 -0
- package/src/task-orchestrator/surfaces/pod-child-providers.ts +42 -0
- package/src/task-orchestrator/surfaces/pod-command-job.ts +6 -3
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +94 -7
- package/src/task-orchestrator/surfaces/pod-image-source.ts +212 -0
- package/src/task-orchestrator/surfaces/pod-lease.ts +110 -17
- package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +32 -3
- package/src/task-orchestrator/surfaces/pod-pool.ts +86 -18
- package/src/task-orchestrator/surfaces/pod-zai-child.ts +101 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +463 -50
- package/src/task-orchestrator/surfaces/self-implement.ts +25 -3
- 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/typecheck-ratchet.ts +1 -0
- package/src/user-config.ts +180 -32
- 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/registry.ts +59 -0
- package/src/workflow-runtime/triggers/scheduler.ts +1 -0
- package/src/workflow-runtime/triggers/webhook-source.ts +35 -5
- 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 → Q-7iofoxOEv1WX18S35of}/_ssgManifest.js +0 -0
|
@@ -24,12 +24,16 @@ export interface GraphNodeSpec {
|
|
|
24
24
|
readonly kind: GraphNodeKind | (string & {});
|
|
25
25
|
readonly recipe: string;
|
|
26
26
|
readonly maxVisits: number;
|
|
27
|
+
/** L0 journey-stage declaration (optional for other graph templates). */
|
|
28
|
+
readonly journeyStage?: string;
|
|
27
29
|
readonly progress?: readonly string[];
|
|
28
30
|
readonly phases?: readonly string[];
|
|
29
31
|
readonly terminalStages?: readonly string[];
|
|
30
32
|
/** ⭐ 「아크마다 한 번」처럼 «한 노드가 여럿 돈다」를 값으로. 없으면 한 번이다. */
|
|
31
33
|
readonly fanOut?: string;
|
|
32
34
|
readonly contract?: GraphNodeContract;
|
|
35
|
+
readonly call?: string;
|
|
36
|
+
readonly budget?: { readonly innerSteps: number };
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
export interface GraphEdgeSpec {
|
|
@@ -50,11 +54,13 @@ export interface GraphTemplateSpec {
|
|
|
50
54
|
readonly version: number;
|
|
51
55
|
readonly entryNode: string;
|
|
52
56
|
readonly terminalNodes: readonly string[];
|
|
57
|
+
readonly journeyStages?: readonly string[];
|
|
53
58
|
/** 문서 전용 변경이면 gate 노드를 건너뛸 수 있다는 템플릿 정책. */
|
|
54
59
|
readonly docsOnlyGateSkip?: boolean;
|
|
55
60
|
readonly state?: readonly string[];
|
|
56
61
|
/** ⭐ 런 계약(선택) — 이 그래프가 «기본으로» 요구하는 실행 칸 등. 발사 인자가 덮는다(graph-run-contract.ts). */
|
|
57
62
|
readonly runContract?: GraphRunContractSpec;
|
|
63
|
+
readonly unit?: { readonly inputs: readonly string[]; readonly outputs: readonly string[]; readonly exits: readonly string[] };
|
|
58
64
|
readonly nodes: readonly GraphNodeSpec[];
|
|
59
65
|
readonly edges: readonly GraphEdgeSpec[];
|
|
60
66
|
}
|
|
@@ -102,6 +108,12 @@ export function parseGraphTemplateYaml(source: string, label = '<inline>'): Grap
|
|
|
102
108
|
const terminalNodes = asArray(doc.terminal_nodes).filter((v): v is string => typeof v === 'string');
|
|
103
109
|
if (terminalNodes.length === 0) errors.push({ path: `${label}/terminal_nodes`, message: 'terminal_nodes 가 비었다 — 끝날 수 없는 그래프다' });
|
|
104
110
|
|
|
111
|
+
const journeyStages = doc.journey_stages;
|
|
112
|
+
if (journeyStages !== undefined && (!Array.isArray(journeyStages) || journeyStages.length === 0
|
|
113
|
+
|| !journeyStages.every((stage) => typeof stage === 'string' && stage.trim())
|
|
114
|
+
|| new Set(journeyStages).size !== journeyStages.length)) {
|
|
115
|
+
errors.push({ path: `${label}/journey_stages`, message: 'journey_stages 는 중복 없는 비어 있지 않은 문자열 목록이어야 한다' });
|
|
116
|
+
}
|
|
105
117
|
const nodes: GraphNodeSpec[] = [];
|
|
106
118
|
for (const [index, entry] of asArray(doc.nodes).entries()) {
|
|
107
119
|
const at = `${label}/nodes/${index}`;
|
|
@@ -126,6 +138,13 @@ export function parseGraphTemplateYaml(source: string, label = '<inline>'): Grap
|
|
|
126
138
|
errors.push({ path: `${at}/max_visits`, message: 'max_visits 는 1 이상의 정수여야 한다' });
|
|
127
139
|
continue;
|
|
128
140
|
}
|
|
141
|
+
if (n.journey_stage !== undefined && (typeof n.journey_stage !== 'string' || !n.journey_stage.trim()
|
|
142
|
+
|| (Array.isArray(journeyStages) && !journeyStages.includes(n.journey_stage)))) {
|
|
143
|
+
errors.push({ path: `${at}/journey_stage`, message: typeof n.journey_stage === 'string' && n.journey_stage.trim()
|
|
144
|
+
? `journey_stage '${n.journey_stage}' 가 journey_stages 목록에 없다`
|
|
145
|
+
: 'journey_stage 는 비어 있지 않은 문자열이어야 한다' });
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
129
148
|
const contractRaw = n.contract as Record<string, unknown> | undefined;
|
|
130
149
|
const contract: GraphNodeContract | undefined = contractRaw && typeof contractRaw === 'object'
|
|
131
150
|
? {
|
|
@@ -134,17 +153,38 @@ export function parseGraphTemplateYaml(source: string, label = '<inline>'): Grap
|
|
|
134
153
|
outputs: asArray(contractRaw.outputs).filter((v): v is string => typeof v === 'string'),
|
|
135
154
|
}
|
|
136
155
|
: undefined;
|
|
156
|
+
// A subgraph node becomes a unit call only when it names `call:`; without it the node keeps the
|
|
157
|
+
// pre-unit meaning (catalog role / recipe node), so existing declarations stay valid.
|
|
158
|
+
if (kind === 'subgraph' && (n.call !== undefined || n.budget !== undefined)) {
|
|
159
|
+
if (typeof n.call !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9._-]*@(?:\^?[1-9]\d*)$/.test(n.call))
|
|
160
|
+
errors.push({ path: `${at}/call`, message: 'call 은 id@정수판 또는 id@^주판이어야 한다' });
|
|
161
|
+
const budget = n.budget as Record<string, unknown> | undefined;
|
|
162
|
+
if (!budget || typeof budget !== 'object' || Array.isArray(budget) ||
|
|
163
|
+
!Number.isSafeInteger(budget.inner_steps) || (budget.inner_steps as number) < 1 || Object.keys(budget).some(key => key !== 'inner_steps'))
|
|
164
|
+
errors.push({ path: `${at}/budget/inner_steps`, message: 'inner_steps 는 1 이상의 안전한 정수여야 한다' });
|
|
165
|
+
if (!contractRaw || !Array.isArray(contractRaw.inputs) || !contractRaw.inputs.every(v => typeof v === 'string') ||
|
|
166
|
+
!Array.isArray(contractRaw.outputs) || !contractRaw.outputs.every(v => typeof v === 'string'))
|
|
167
|
+
errors.push({ path: `${at}/contract`, message: 'subgraph 에는 inputs·outputs 계약이 필요하다' });
|
|
168
|
+
if (recipe !== 'none') errors.push({ path: `${at}/recipe`, message: 'subgraph 는 recipe 를 실행하지 않는다' });
|
|
169
|
+
} else if (kind !== 'subgraph' && (n.call !== undefined || n.budget !== undefined)) {
|
|
170
|
+
errors.push({ path: at, message: 'call·budget 은 subgraph 전용이다' });
|
|
171
|
+
}
|
|
137
172
|
// ⛔ 계약이 없으면 「이 노드가 무엇을 할 수 있나」를 답할 수 없다 — 경고로 남긴다(거절은 오버레이 쪽).
|
|
138
173
|
if (contract === undefined) warnings.push({ path: `${at}/contract`, message: '계약(inputs·tools·outputs)이 없다 — 권한을 코드에서만 알 수 있다' });
|
|
139
174
|
else if (contract.tools === '') warnings.push({ path: `${at}/contract/tools`, message: 'tools 가 비었다' });
|
|
140
175
|
|
|
141
176
|
nodes.push({
|
|
142
177
|
nodeId, kind, recipe, maxVisits,
|
|
178
|
+
...(typeof n.journey_stage === 'string' ? { journeyStage: n.journey_stage } : {}),
|
|
143
179
|
...(Array.isArray(n.progress) ? { progress: n.progress.filter((v): v is string => typeof v === 'string') } : {}),
|
|
144
180
|
...(Array.isArray(n.phases) ? { phases: n.phases.filter((v): v is string => typeof v === 'string') } : {}),
|
|
145
181
|
...(Array.isArray(n.terminal_stages) ? { terminalStages: n.terminal_stages.filter((v): v is string => typeof v === 'string') } : {}),
|
|
146
182
|
...(typeof n.fan_out === 'string' ? { fanOut: n.fan_out } : {}),
|
|
147
183
|
...(contract ? { contract } : {}),
|
|
184
|
+
...(kind === 'subgraph' && typeof n.call === 'string' ? { call: n.call } : {}),
|
|
185
|
+
...(kind === 'subgraph' && n.budget && typeof n.budget === 'object' && !Array.isArray(n.budget) &&
|
|
186
|
+
typeof (n.budget as Record<string, unknown>).inner_steps === 'number'
|
|
187
|
+
? { budget: { innerSteps: (n.budget as { inner_steps: number }).inner_steps } } : {}),
|
|
148
188
|
});
|
|
149
189
|
}
|
|
150
190
|
if (nodes.length === 0) errors.push({ path: `${label}/nodes`, message: '노드가 하나도 없다' });
|
|
@@ -198,6 +238,20 @@ export function parseGraphTemplateYaml(source: string, label = '<inline>'): Grap
|
|
|
198
238
|
if (entryNode !== undefined && !known.has(entryNode)) errors.push({ path: `${label}/entry_node`, message: `'${entryNode}' 는 선언된 노드가 아니다` });
|
|
199
239
|
for (const t of terminalNodes) if (!known.has(t)) errors.push({ path: `${label}/terminal_nodes`, message: `'${t}' 는 선언된 노드가 아니다` });
|
|
200
240
|
|
|
241
|
+
let unit: GraphTemplateSpec['unit'];
|
|
242
|
+
if (doc.unit !== undefined) {
|
|
243
|
+
const rawUnit = doc.unit as Record<string, unknown>;
|
|
244
|
+
if (!rawUnit || typeof rawUnit !== 'object' || Array.isArray(rawUnit) ||
|
|
245
|
+
Object.keys(rawUnit).some(key => !['inputs', 'outputs', 'exits'].includes(key)) ||
|
|
246
|
+
!['inputs', 'outputs', 'exits'].every(key => Array.isArray(rawUnit[key]) &&
|
|
247
|
+
(rawUnit[key] as unknown[]).every(v => typeof v === 'string' && v.length > 0) &&
|
|
248
|
+
new Set(rawUnit[key] as string[]).size === (rawUnit[key] as string[]).length) ||
|
|
249
|
+
!(rawUnit.exits as string[]).length ||
|
|
250
|
+
(rawUnit.exits as string[]).some(exit => !terminalNodes.includes(exit)) ||
|
|
251
|
+
terminalNodes.some(exit => !(rawUnit.exits as string[]).includes(exit))) {
|
|
252
|
+
errors.push({ path: `${label}/unit`, message: 'unit 의 inputs·outputs·exits 및 terminal_nodes 가 일치해야 한다' });
|
|
253
|
+
} else unit = { inputs: rawUnit.inputs as string[], outputs: rawUnit.outputs as string[], exits: rawUnit.exits as string[] };
|
|
254
|
+
}
|
|
201
255
|
const runContract = parseGraphRunContract(doc.run_contract);
|
|
202
256
|
if (runContract.error) errors.push({ path: `${label}/run_contract`, message: runContract.error });
|
|
203
257
|
let loop: GraphTemplateSpec['loop'];
|
|
@@ -225,6 +279,8 @@ export function parseGraphTemplateYaml(source: string, label = '<inline>'): Grap
|
|
|
225
279
|
return {
|
|
226
280
|
template: {
|
|
227
281
|
graphId: graphId!, version: version!, entryNode: entryNode!, terminalNodes, nodes, edges,
|
|
282
|
+
...(unit ? { unit } : {}),
|
|
283
|
+
...(Array.isArray(journeyStages) ? { journeyStages: journeyStages as string[] } : {}),
|
|
228
284
|
...(loop ? { loop } : {}),
|
|
229
285
|
...(typeof doc.docs_only_gate_skip === 'boolean' ? { docsOnlyGateSkip: doc.docs_only_gate_skip } : {}),
|
|
230
286
|
...(Array.isArray(doc.state) ? { state: doc.state.filter((v): v is string => typeof v === 'string') } : {}),
|
|
@@ -996,8 +996,8 @@ export interface HeadlessGoalLoopPtyOptions {
|
|
|
996
996
|
/** 밖에서 쓴 이력 조회 심 — 기본은 실물(`pty-control-ipc`). ⭐ 테스트가 전역을 찌르지 않게
|
|
997
997
|
* `spawn`·`ptyAvailable` 과 **같은 방식**으로 주입한다(새 패턴 아님 · 테스트 전용 export 도 아님). */
|
|
998
998
|
externalWriteProvenance?: (ptyId: string) => { externalWrites: number; externalWriteAgoMs: number; externalWriteActor: string } | undefined;
|
|
999
|
-
/** ★S4 P2b — brain 상담 1회 최대 대기(ms·기본
|
|
1000
|
-
* ⚠️ **테스트 seam 겸용**(리뷰 must-fix — 이게 없으면 timeout fail-soft 경로를
|
|
999
|
+
/** ★S4 P2b — brain 상담 1회 최대 대기(ms·기본 45초). 초과 시 abort + fail-soft(`brain.fail`).
|
|
1000
|
+
* ⚠️ **테스트 seam 겸용**(리뷰 must-fix — 이게 없으면 timeout fail-soft 경로를 45초 없이 검증할 수
|
|
1001
1001
|
* 없다). 프로덕션은 기본값을 쓴다(호출부 미지정). */
|
|
1002
1002
|
brainTimeoutMs?: number;
|
|
1003
1003
|
/** ★S4 P3 **관측 시계 seam**(테스트 전용·기본 `Date.now`).
|
|
@@ -1520,8 +1520,8 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
|
|
|
1520
1520
|
let previousStallMetrics: { toolCalls: number; chars: number } | undefined;
|
|
1521
1521
|
let keyframeSeq = 0; // 이 run 의 키프레임 순번(파일 키·seq 순 추출).
|
|
1522
1522
|
// ⭐⭐ **wall-clock 상한**(리뷰 must-fix 2026-07-26) — 이 루프의 회계는 `i`(≈초·pollMs≈1000ms 가정)
|
|
1523
|
-
// 기반이다. S4 P2b brain 상담이 tick 당 최대 `brainTimeoutMs`(기본
|
|
1524
|
-
// 전이가 반복되면 1 tick 이 ~
|
|
1523
|
+
// 기반이다. S4 P2b brain 상담이 tick 당 최대 `brainTimeoutMs`(기본 45초)를 **직렬 await** 하므로
|
|
1524
|
+
// 전이가 반복되면 1 tick 이 ~46초가 되어 `maxWaitSec` 계약을 초과할 수 있다.
|
|
1525
1525
|
// ⇒ 기존 활동-grace 의미(i 기반)는 **그대로 두고** 절대 경과시간을 **추가 상한**으로만 얹는다.
|
|
1526
1526
|
// 단조 안전: 더 **일찍** 멈출 뿐 늦게 멈추는 경우가 없다. brain 미주입이면 i≈초라 두 조건이 일치
|
|
1527
1527
|
// (무회귀). ROADMAP §2 P1(종료 지연)의 회계 구조를 재작성하지 않는 최소 개입이다.
|
|
@@ -1563,7 +1563,7 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
|
|
|
1563
1563
|
debug.log('self-implement', 'poll.heartbeat', { ptyId, runId, i, alive: h.isAlive(), lastActivityI, silentFor, ...parentObservation });
|
|
1564
1564
|
}
|
|
1565
1565
|
// #24 finer 마커 — stall 시 "poll 루프 안(자식 구동·정상)" vs "다른 동기 op" 구분.
|
|
1566
|
-
setEventLoopActivity(`headless:poll
|
|
1566
|
+
setEventLoopActivity(`headless:poll:alive-${h.isAlive() ? 1 : 0}`);
|
|
1567
1567
|
const delta = h.drainDelta();
|
|
1568
1568
|
phase = 'snapshot';
|
|
1569
1569
|
const snap = h.snapshot(); // ★ 1회 캡처 — 화면 릴레이 + GOAL-COMPLETE 공용(중복 snapshot 제거)
|
|
@@ -1697,6 +1697,7 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
|
|
|
1697
1697
|
if (opts.signal?.aborted) onBrainAbort();
|
|
1698
1698
|
else opts.signal?.addEventListener('abort', onBrainAbort, { once: true });
|
|
1699
1699
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
1700
|
+
const brainStartedMs = Date.now();
|
|
1700
1701
|
try {
|
|
1701
1702
|
// Lost and unknown are the same ownership axis exercised by the stalled-screen
|
|
1702
1703
|
// tests, not separate stances. Preserve their measured ownership and observation
|
|
@@ -1709,12 +1710,12 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
|
|
|
1709
1710
|
Promise.resolve(opts.brain.decide(controlObs, controller.signal)),
|
|
1710
1711
|
new Promise<ControlDecision>((_, reject) => {
|
|
1711
1712
|
// ⭐ **남은 절대 예산으로 clamp**(리뷰 must-fix 2R) — wall-clock 상한은 **tick 시작**에서만
|
|
1712
|
-
// 검사하므로, deadline 직전에 시작된 상담이 그대로면 최대 brainTimeoutMs(기본
|
|
1713
|
+
// 검사하므로, deadline 직전에 시작된 상담이 그대로면 최대 brainTimeoutMs(기본 45초)만큼
|
|
1713
1714
|
// hard deadline 을 **초과**한다. 상담 자체를 남은 예산 안으로 묶어 창을 닫는다.
|
|
1714
1715
|
// 최소 1ms(음수·0 이면 즉시 timeout → 다음 tick 상단 wall-clock 체크가 루프를 끊는다).
|
|
1715
1716
|
const remainMs = Math.max(1, hardI * 1000 - (Date.now() - loopStartedMs));
|
|
1716
1717
|
timer = setTimeout(() => { controller.abort(); reject(new Error('brain suggestion timeout')); },
|
|
1717
|
-
Math.min(opts.brainTimeoutMs ??
|
|
1718
|
+
Math.min(opts.brainTimeoutMs ?? 45_000, remainMs));
|
|
1718
1719
|
}),
|
|
1719
1720
|
...(parentAbort ? [parentAbort] : []),
|
|
1720
1721
|
]);
|
|
@@ -1761,6 +1762,7 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
|
|
|
1761
1762
|
// 관측 계약은 화면 분류 원문을 보존한다. 완료 정보량·자동 정지는 아래의
|
|
1762
1763
|
// `completionState` 폐쇄형 정규화만 소비하므로 blocked/idle 기록을 잃지 않는다.
|
|
1763
1764
|
ptyId: h.id, runId, moment: 'in-round', step: i, trigger, state: curState, action: decision.action,
|
|
1765
|
+
durationMs: Date.now() - brainStartedMs,
|
|
1764
1766
|
// `delivery-outcome` is a follow-up observation, not another verdict. Consumers count
|
|
1765
1767
|
// either initial stage once per decision and can distinguish verdicts without input.
|
|
1766
1768
|
supervisionRecordStage: decision.action === 'input' ? 'verdict-input' : 'verdict-no-input',
|
|
@@ -1848,7 +1850,7 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
|
|
|
1848
1850
|
}
|
|
1849
1851
|
} catch (e) {
|
|
1850
1852
|
// Parent cancel outranks suggestion observation: leave the poll loop immediately so PTY cleanup is not
|
|
1851
|
-
// held by the
|
|
1853
|
+
// held by the 45s consultation timeout, even when a custom brain ignores its AbortSignal.
|
|
1852
1854
|
if (opts.signal?.aborted) {
|
|
1853
1855
|
timedOut = false;
|
|
1854
1856
|
exitReason = 'abort';
|
|
@@ -1856,7 +1858,7 @@ export async function runHeadlessGoalLoopPty(opts: HeadlessGoalLoopPtyOptions):
|
|
|
1856
1858
|
}
|
|
1857
1859
|
debug.log('self-implement', 'brain.fail', {
|
|
1858
1860
|
ptyId: h.id, runId, step: i, trigger, state: curState,
|
|
1859
|
-
roundContextPresent,
|
|
1861
|
+
roundContextPresent, durationMs: Date.now() - brainStartedMs,
|
|
1860
1862
|
error: String(e instanceof Error ? e.message : e).slice(0, 120),
|
|
1861
1863
|
});
|
|
1862
1864
|
} finally {
|
|
@@ -170,7 +170,11 @@ function withInboxLock<T>(file: string, work: () => T): T {
|
|
|
170
170
|
finally { rmdirSync(lock); }
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
/** One durable JSON line per failure; repeat source+ref within an hour is folded.
|
|
173
|
+
/** One durable JSON line per failure; repeat source+ref within an hour is folded.
|
|
174
|
+
* POD-HEAL-HOST — the loop start itself is refused inside a Pod (`startHealLoop` → `skipped-in-pod`):
|
|
175
|
+
* a loop started there dies with the Pod. The line stays in the inbox, and the host re-records the
|
|
176
|
+
* recovered Pod ledger failure into the HOST universe (`pod-ledger-collect.ts` → `intakeCollectedFailure`),
|
|
177
|
+
* so the host heal loop triages it (harvest + narrowed relaunch). */
|
|
174
178
|
export function recordFailureEvent(event: FailureEvent, root = effectiveInstanceRoot(), startLoop: StartHealLoop = startHealLoop): { folded: boolean } {
|
|
175
179
|
if (!['release-run', 'harness-run', 'loop-tick', 'cron'].includes(event.source) ||
|
|
176
180
|
!event.kind || !event.ref || !event.summary || !Number.isFinite(Date.parse(event.at))) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
|
-
import { existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import { tmpdir } from 'node:os';
|
|
4
|
-
import { dirname, join } from 'node:path';
|
|
4
|
+
import { dirname, join, resolve } from 'node:path';
|
|
5
5
|
import { debug } from '../debug/log.js';
|
|
6
6
|
import { getUserConfig } from '../user-config.js';
|
|
7
7
|
import { publicExposureFiles, runExposeGate } from './expose-gate.js';
|
|
@@ -9,23 +9,32 @@ import { admitLandingMerge } from './frozen-merges.js';
|
|
|
9
9
|
import { releaseGitDiffPaths, releasePathHold, releasePathHoldShouldPost, releasePathHoldComment, releasePathHoldCommentsArgs, RELEASE_PATH_LABEL } from '../self-dev/release-path-guard.js';
|
|
10
10
|
import { detectTestInterference, parseFailureCount, runBunTest } from '../../scripts/detect-test-interference.js';
|
|
11
11
|
import { MAX_INSPECTED_TEST_FILES, runTestInterferenceGate } from '../../scripts/ci-test-interference-gate.js';
|
|
12
|
+
import { pwaGraph, pwaReach } from '../../scripts/ci-pwa-build-gate.js';
|
|
13
|
+
|
|
14
|
+
/** Use pr-land's PWA reachability (including its undecidable-graph build fallback), not a blanket src/** trigger. */
|
|
15
|
+
export function needsPwaBuild(files: readonly string[], repoRoot: string, graph: (root: string) => ReturnType<typeof pwaGraph> = pwaGraph): boolean {
|
|
16
|
+
return pwaReach(files, () => graph(repoRoot)).reaches;
|
|
17
|
+
}
|
|
12
18
|
|
|
13
19
|
/**
|
|
14
|
-
*
|
|
15
|
-
* `
|
|
16
|
-
*
|
|
17
|
-
* app code or non-test source changed; test files are never imported by the PWA.
|
|
20
|
+
* Give a temporary checkout the source checkout's dependencies: link `<dir>/node_modules` when it is really installed
|
|
21
|
+
* there (its `marker` package exists), otherwise install into the candidate. Shared by host regate and the task agent's
|
|
22
|
+
* land worktree (TA-LAND-WORKTREE).
|
|
18
23
|
*/
|
|
19
|
-
export function
|
|
20
|
-
|
|
24
|
+
export function provideCheckoutDependencies(candidate: string, sourceRoot: string, dir: string, marker: string, install: (cwd: string) => void): void {
|
|
25
|
+
if (existsSync(join(candidate, dir, 'node_modules'))) return;
|
|
26
|
+
if (existsSync(join(sourceRoot, dir, 'node_modules', marker, 'package.json'))) {
|
|
27
|
+
symlinkSync(join(sourceRoot, dir, 'node_modules'), join(candidate, dir, 'node_modules'), 'dir');
|
|
28
|
+
} else install(join(candidate, dir));
|
|
21
29
|
}
|
|
22
30
|
|
|
23
|
-
export interface HostRegateInput { prNumber: number; headCommit: string; repoRoot: string; goalFile?: string; verifyOnly?: boolean; /** Called by a resume sweep that already holds this PR's claim. */ resumed?: true }
|
|
31
|
+
export interface HostRegateInput { prNumber: number; headCommit: string; repoRoot: string; goalFile?: string; verifyOnly?: boolean; /** TA-LIVE-LAND-2: run the full landing gates (release-path hold · neighbours · PR re-read) but stop before the freeze admission and `gh pr merge` — the task agent lands it later via `pr land --expected-head`. */ noMerge?: true; /** Called by a resume sweep that already holds this PR's claim. */ resumed?: true }
|
|
24
32
|
export interface HostRegateResult { passed: boolean; failures: Array<{ step: string; detail: string }>; os: string; status?: 'passed' | 'failed' | 'unmeasured' | 'frozen'; /** verifyOnly: 실제로 얹어 잰 base 끝 */ baseCommit?: string }
|
|
25
33
|
export type InterferenceVerdict = { passed: boolean; detail?: string; unmeasured?: boolean; /** neighbour tests left out so the selection fits the inspection cap */ neighborsTrimmed?: number };
|
|
26
34
|
export type HostRegateDeps = {
|
|
27
35
|
command?: (bin: string, args: readonly string[], cwd: string, env?: NodeJS.ProcessEnv) => { status: number | null; stdout: string; stderr: string };
|
|
28
36
|
interference?: (files: readonly string[], cwd: string) => Promise<InterferenceVerdict>;
|
|
37
|
+
/** Legacy injection for callers that supply an ephemeral worktree instead of a locked slot. */
|
|
29
38
|
makeTemp?: () => string;
|
|
30
39
|
removeTemp?: (path: string) => void;
|
|
31
40
|
acquire?: (repoRoot: string) => Promise<() => void>;
|
|
@@ -104,7 +113,7 @@ function slotOwnerAlive(slot: string): boolean {
|
|
|
104
113
|
}
|
|
105
114
|
}
|
|
106
115
|
|
|
107
|
-
export async function acquireSlot(repoRoot: string, opts: { waitMs?: number; pollMs?: number; now?: () => number } = {}): Promise<() => void> {
|
|
116
|
+
export async function acquireSlot(repoRoot: string, opts: { waitMs?: number; pollMs?: number; now?: () => number } = {}): Promise<(() => void) & { worktree: string }> {
|
|
108
117
|
const gitDir = spawnSync('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], { cwd: repoRoot, encoding: 'utf8' });
|
|
109
118
|
if (gitDir.status !== 0 || !gitDir.stdout.trim()) throw new Error('git common directory unavailable for host regate lock');
|
|
110
119
|
const root = join(gitDir.stdout.trim(), 'elanous-host-regate');
|
|
@@ -117,7 +126,7 @@ export async function acquireSlot(repoRoot: string, opts: { waitMs?: number; pol
|
|
|
117
126
|
try {
|
|
118
127
|
mkdirSync(slot);
|
|
119
128
|
writeFileSync(join(slot, 'pid'), String(process.pid));
|
|
120
|
-
return () => rmSync(slot, { recursive: true, force: true });
|
|
129
|
+
return Object.assign(() => rmSync(slot, { recursive: true, force: true }), { worktree: join(root, `worktree-${i}`) });
|
|
121
130
|
} catch (error) {
|
|
122
131
|
if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;
|
|
123
132
|
// A slot left by a crashed host process would otherwise block every later run.
|
|
@@ -133,6 +142,24 @@ export async function acquireSlot(repoRoot: string, opts: { waitMs?: number; pol
|
|
|
133
142
|
}
|
|
134
143
|
}
|
|
135
144
|
|
|
145
|
+
function removeBrokenSlotRegistration(repoRoot: string, worktree: string): void {
|
|
146
|
+
const gitDir = spawnSync('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], { cwd: repoRoot, encoding: 'utf8' });
|
|
147
|
+
if (gitDir.status !== 0 || !gitDir.stdout.trim()) throw new Error('git common directory unavailable for slot repair');
|
|
148
|
+
const registrations = join(gitDir.stdout.trim(), 'worktrees');
|
|
149
|
+
if (!existsSync(registrations)) return;
|
|
150
|
+
for (const name of readdirSync(registrations)) {
|
|
151
|
+
const registration = join(registrations, name);
|
|
152
|
+
if (!lstatSync(registration).isDirectory()) continue;
|
|
153
|
+
const pointer = join(registration, 'gitdir');
|
|
154
|
+
if (!existsSync(pointer) || lstatSync(pointer).isSymbolicLink()) continue;
|
|
155
|
+
if (resolve(readFileSync(pointer, 'utf8').trim()) !== resolve(worktree, '.git')) continue;
|
|
156
|
+
rmSync(registration, { recursive: true });
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Callers: podSelfImplementSpawn in src/task-orchestrator/surfaces/self-implement-pod.ts calls
|
|
161
|
+
* (options.hostRegate ?? runHostRegate)({ prNumber, headCommit, repoRoot: hostRoot, ... });
|
|
162
|
+
* sweepFrozenMerges in frozen-merges.ts also calls runHostRegate(entry); landing queue serialization stays there. */
|
|
136
163
|
export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps = {}): Promise<HostRegateResult> {
|
|
137
164
|
const command = deps.command ?? defaultCommand;
|
|
138
165
|
const log = deps.log ?? ((event: 'passed' | 'failed' | 'unmeasured' | 'base-raced', data: Record<string, unknown>) => debug.log('harness.host-regate', event, data));
|
|
@@ -141,6 +168,19 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
|
|
|
141
168
|
let base = '';
|
|
142
169
|
let worktree: string | undefined;
|
|
143
170
|
let attached = false;
|
|
171
|
+
let ephemeral = false;
|
|
172
|
+
let slotCommonDir: string | undefined;
|
|
173
|
+
const verifySlot = (): void => {
|
|
174
|
+
if (!worktree || !slotCommonDir || lstatSync(worktree).isSymbolicLink() || !lstatSync(worktree).isDirectory()) throw new Error('slot worktree mismatch');
|
|
175
|
+
const pointer = join(worktree, '.git');
|
|
176
|
+
if (!lstatSync(pointer).isFile() || lstatSync(pointer).isSymbolicLink()) throw new Error('slot worktree mismatch');
|
|
177
|
+
const common = realpathSync(run('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], worktree));
|
|
178
|
+
const registration = realpathSync(run('git', ['rev-parse', '--path-format=absolute', '--git-dir'], worktree));
|
|
179
|
+
if (common !== slotCommonDir || dirname(registration) !== join(slotCommonDir, 'worktrees')
|
|
180
|
+
|| resolve(readFileSync(join(registration, 'gitdir'), 'utf8').trim()) !== resolve(pointer)
|
|
181
|
+
|| resolve(readFileSync(pointer, 'utf8').trim().replace(/^gitdir: /, '')) !== registration
|
|
182
|
+
|| run('git', ['rev-parse', '--show-toplevel'], worktree) !== worktree) throw new Error('slot worktree mismatch');
|
|
183
|
+
};
|
|
144
184
|
let release: (() => void) | undefined;
|
|
145
185
|
let endLanding: ((merged?: boolean) => void) | undefined;
|
|
146
186
|
let landed = false;
|
|
@@ -168,16 +208,57 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
|
|
|
168
208
|
const baseRefName = view.baseRefName;
|
|
169
209
|
// verifyOnly(승인 탭): PR 에 기록된 base(baseRefOid)는 main 의 «지금 끝»보다 늙을 수 있다 — 지금 끝에 얹어 잰다.
|
|
170
210
|
let baseCommit = view.baseRefOid!;
|
|
211
|
+
// REGATE-STALE-BASE: GitHub's baseRefOid can stay at the PR-open tip after main moves. After the bounded re-reads the
|
|
212
|
+
// regate measures on the fetched base tip (what the squash merge lands on) and records the stale PR base instead of failing.
|
|
213
|
+
// The closing PR re-read must still show the last PR base seen here (a PR that changed again is not the PR we measured).
|
|
214
|
+
let stalePrBase: string | undefined;
|
|
215
|
+
const initialPrBase = baseCommit;
|
|
216
|
+
let buildPwa = false;
|
|
171
217
|
try {
|
|
172
218
|
run('git', ['fetch', 'origin', `refs/heads/${baseRefName}`], input.repoRoot);
|
|
173
|
-
|
|
219
|
+
let fetchedBase = run('git', ['rev-parse', 'FETCH_HEAD'], input.repoRoot);
|
|
174
220
|
if (input.verifyOnly) { baseCommit = fetchedBase; verifiedBase = fetchedBase; }
|
|
175
|
-
else
|
|
221
|
+
else {
|
|
222
|
+
for (let attempt = 1; fetchedBase !== baseCommit; attempt++) {
|
|
223
|
+
debug.log('harness.host-regate', 'base-moved-retry', { pr: input.prNumber, attempt, checked: baseCommit, fetched: fetchedBase });
|
|
224
|
+
if (attempt === 3) {
|
|
225
|
+
stalePrBase = baseCommit;
|
|
226
|
+
debug.log('harness.host-regate', 'base-stale', { pr: input.prNumber, prBaseRefOidInitial: initialPrBase, prBaseRefOid: baseCommit, fetched: fetchedBase, candidateBase: fetchedBase });
|
|
227
|
+
baseCommit = fetchedBase;
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
await new Promise((resolve) => setTimeout(resolve, 1_000));
|
|
231
|
+
view = readPr();
|
|
232
|
+
if (view.headRefOid !== input.headCommit || view.state !== 'OPEN' || view.isDraft !== false || view.baseRefName !== baseRefName || !/^[0-9a-f]{40}$/i.test(view.baseRefOid ?? '')) {
|
|
233
|
+
return result('unmeasured', 'pr-head', 'PR head, base commit, ready state or open state unavailable or changed');
|
|
234
|
+
}
|
|
235
|
+
baseCommit = view.baseRefOid!;
|
|
236
|
+
run('git', ['fetch', 'origin', `refs/heads/${baseRefName}`], input.repoRoot);
|
|
237
|
+
fetchedBase = run('git', ['rev-parse', 'FETCH_HEAD'], input.repoRoot);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
176
240
|
run('git', ['fetch', 'origin', `refs/pull/${input.prNumber}/head`], input.repoRoot);
|
|
177
241
|
if (run('git', ['rev-parse', 'FETCH_HEAD'], input.repoRoot) !== input.headCommit) throw new Error('fetched PR head differs from checked SHA');
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
242
|
+
const slotWorktree = (release as (() => void) & { worktree?: string }).worktree;
|
|
243
|
+
ephemeral = !!deps.makeTemp || !slotWorktree;
|
|
244
|
+
worktree = deps.makeTemp?.() ?? slotWorktree ?? mkdtempSync(join(tmpdir(), 'host-regate-'));
|
|
245
|
+
if (ephemeral && slotWorktree && resolve(worktree) === resolve(slotWorktree)) throw new Error('temporary worktree overlaps locked slot');
|
|
246
|
+
if (!ephemeral && !deps.acquire) {
|
|
247
|
+
slotCommonDir = realpathSync(run('git', ['rev-parse', '--path-format=absolute', '--git-common-dir'], input.repoRoot));
|
|
248
|
+
}
|
|
249
|
+
if (!ephemeral && existsSync(worktree)) {
|
|
250
|
+
if (slotCommonDir) verifySlot();
|
|
251
|
+
attached = true;
|
|
252
|
+
// A previous host may have died mid-merge; never carry its index or untracked files into this run.
|
|
253
|
+
run('git', ['reset', '--hard'], worktree);
|
|
254
|
+
run('git', ['clean', '-fdx', '-e', 'node_modules', '-e', '.next', '-e', '*.tsbuildinfo'], worktree);
|
|
255
|
+
run('git', ['checkout', '--detach', baseCommit], worktree);
|
|
256
|
+
}
|
|
257
|
+
if (!attached) {
|
|
258
|
+
if (!ephemeral && !deps.acquire) removeBrokenSlotRegistration(input.repoRoot, worktree);
|
|
259
|
+
run('git', ['worktree', 'add', '--detach', worktree, baseCommit], input.repoRoot);
|
|
260
|
+
attached = true;
|
|
261
|
+
}
|
|
181
262
|
if (run('git', ['rev-parse', 'HEAD'], worktree) !== baseCommit) throw new Error('worktree base HEAD mismatch');
|
|
182
263
|
base = run('git', ['merge-base', baseCommit, input.headCommit], worktree);
|
|
183
264
|
files = run('git', ['diff', '--name-only', base, input.headCommit], worktree).split('\n').filter(Boolean);
|
|
@@ -213,14 +294,10 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
|
|
|
213
294
|
// a temporary checkout whose node_modules is empty or purged; linking it turned every gate into
|
|
214
295
|
// «Cannot find package 'typescript'» (unmeasured · 2026-09-29 #21239). Install into the candidate instead.
|
|
215
296
|
const candidate = worktree;
|
|
216
|
-
const provide = (dir: string, marker: string): void => {
|
|
217
|
-
if (existsSync(join(candidate, dir, 'node_modules'))) return;
|
|
218
|
-
if (existsSync(join(input.repoRoot, dir, 'node_modules', marker, 'package.json'))) {
|
|
219
|
-
symlinkSync(join(input.repoRoot, dir, 'node_modules'), join(candidate, dir, 'node_modules'), 'dir');
|
|
220
|
-
} else run('bun', ['install', '--frozen-lockfile'], join(candidate, dir));
|
|
221
|
-
};
|
|
297
|
+
const provide = (dir: string, marker: string): void => provideCheckoutDependencies(candidate, input.repoRoot, dir, marker, (cwd) => { run('bun', ['install', '--frozen-lockfile'], cwd); });
|
|
222
298
|
provide('', 'typescript');
|
|
223
|
-
|
|
299
|
+
buildPwa = needsPwaBuild(files, worktree);
|
|
300
|
+
if (buildPwa && existsSync(join(worktree, 'apps/pwa'))) provide('apps/pwa', 'next');
|
|
224
301
|
} catch (e) { return result('unmeasured', 'worktree', String(e)); }
|
|
225
302
|
try {
|
|
226
303
|
const interference = await (deps.interference ?? ((f: readonly string[], c: string) => defaultInterference(f, c, { neighbors: !input.verifyOnly })))(files, worktree);
|
|
@@ -244,19 +321,21 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
|
|
|
244
321
|
try { run('bun', ['scripts/ci-isolation-hardcode-gate.ts', '--changed-files', ...files], worktree); }
|
|
245
322
|
catch (e) { return result(/\[isolation-gate\] FAIL/.test(String(e)) ? 'failed' : 'unmeasured', 'isolation-gate', String(e)); }
|
|
246
323
|
}
|
|
247
|
-
if (
|
|
324
|
+
if (buildPwa) {
|
|
248
325
|
try { run('bun', ['bin/elanous.mjs', '--test', 'nexus', 'build'], worktree); }
|
|
249
326
|
catch (e) { return result(String(e).includes('command unavailable') ? 'unmeasured' : 'failed', 'nexus-build', String(e)); }
|
|
250
327
|
}
|
|
251
328
|
let current: PrView;
|
|
252
329
|
try { current = readPr(); }
|
|
253
330
|
catch (e) { return result('unmeasured', 'pr-view', String(e)); }
|
|
254
|
-
if (current.headRefOid !== input.headCommit || current.baseRefName !== baseRefName || (!input.verifyOnly && current.baseRefOid !== baseCommit) || current.state !== 'OPEN' || current.isDraft !== false) {
|
|
331
|
+
if (current.headRefOid !== input.headCommit || current.baseRefName !== baseRefName || (!input.verifyOnly && current.baseRefOid !== (stalePrBase ?? baseCommit)) || current.state !== 'OPEN' || current.isDraft !== false) {
|
|
255
332
|
return result('unmeasured', 'pr-base-changed', 'PR head or base changed during host regate; rerun against the new base');
|
|
256
333
|
}
|
|
257
334
|
// --match-head-commit pins the head. gh has no base pin, so the base was re-read just
|
|
258
335
|
// above; the seconds between that read and the merge are checked after the fact below.
|
|
259
336
|
if (input.verifyOnly) return result('passed');
|
|
337
|
+
// TA-REJUDGE-ON-HEAD — 병합 없는 재게이트는 «잰 base 끝»을 같이 낸다(겹침 증거의 gate.baseCommit).
|
|
338
|
+
if (input.noMerge) return { ...result('passed'), status: 'passed', baseCommit };
|
|
260
339
|
const landing = admitLandingMerge({ prNumber: input.prNumber, headCommit: input.headCommit, repoRoot: input.repoRoot, ...(input.goalFile ? { goalFile: input.goalFile } : {}) }, deps.freezeRoot, {}, input.resumed ? undefined : { prNumber: input.prNumber, repoRoot: input.repoRoot, headCommit: input.headCommit }, { prodFreezeRoot: deps.prodFreezeRoot });
|
|
261
340
|
if (landing.kind !== 'merge') {
|
|
262
341
|
debug.log('harness.merge', 'frozen', { pr: input.prNumber, ...(landing.kind === 'held' ? { reason: landing.freeze.reason, until: landing.freeze.until } : { resumedElsewhere: true }) });
|
|
@@ -295,10 +374,22 @@ export async function runHostRegate(input: HostRegateInput, deps: HostRegateDeps
|
|
|
295
374
|
return result('unmeasured', 'host-regate', String(e));
|
|
296
375
|
} finally {
|
|
297
376
|
try { endLanding?.(landed); } catch (e) { log('unmeasured', { pr: input.prNumber, files, os: process.platform, failedStep: 'landing-release', detail: String(e) }); }
|
|
298
|
-
try {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
377
|
+
try {
|
|
378
|
+
if (attached && worktree) {
|
|
379
|
+
if (slotCommonDir) verifySlot();
|
|
380
|
+
run('git', ['reset', '--hard'], worktree);
|
|
381
|
+
run('git', ['clean', '-fdx', '-e', 'node_modules', '-e', '.next', '-e', '*.tsbuildinfo'], worktree);
|
|
382
|
+
}
|
|
383
|
+
} catch (e) { log('unmeasured', { pr: input.prNumber, files, os: process.platform, failedStep: 'cleanup', detail: String(e) }); }
|
|
384
|
+
if (ephemeral && worktree) {
|
|
385
|
+
try {
|
|
386
|
+
if (attached) run('git', ['worktree', 'remove', '--force', worktree], input.repoRoot);
|
|
387
|
+
} catch (e) { log('unmeasured', { pr: input.prNumber, files, os: process.platform, failedStep: 'cleanup', detail: String(e) }); }
|
|
388
|
+
try {
|
|
389
|
+
if (deps.removeTemp) deps.removeTemp(worktree);
|
|
390
|
+
else rmSync(worktree, { recursive: true, force: true });
|
|
391
|
+
} catch (e) { log('unmeasured', { pr: input.prNumber, files, os: process.platform, failedStep: 'cleanup', detail: String(e) }); }
|
|
392
|
+
}
|
|
302
393
|
try { release?.(); }
|
|
303
394
|
catch (e) { log('unmeasured', { pr: input.prNumber, files, os: process.platform, failedStep: 'lock', detail: String(e) }); }
|
|
304
395
|
if (failures.length && failures[0]?.step !== 'release-path-hold') {
|
|
@@ -30,9 +30,27 @@ export type L8MergeQueueDeps = {
|
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
export type L8ShadowVerdict = { number: number; head: string; base?: string; verdict: 'pass' | 'conflict' | 'fail'; detail?: string; tests: string[]; at: string };
|
|
33
|
-
export type
|
|
33
|
+
export type L8ShadowQueueItem = {
|
|
34
|
+
number: number;
|
|
35
|
+
head: string;
|
|
36
|
+
files?: string[];
|
|
37
|
+
filesUnmeasured?: true;
|
|
38
|
+
overlapsWith?: number[];
|
|
39
|
+
overlapsUnknownWith?: number[];
|
|
40
|
+
};
|
|
41
|
+
export type L8ShadowQueueState = { pending: L8ShadowQueueItem[]; verdicts: L8ShadowVerdict[] };
|
|
42
|
+
export type L8ShadowEnqueueObservation = {
|
|
43
|
+
number: number;
|
|
44
|
+
head: string;
|
|
45
|
+
fileCount: number | null;
|
|
46
|
+
filesUnmeasured: boolean;
|
|
47
|
+
overlapsWith: number[];
|
|
48
|
+
overlapsUnknownWith: number[];
|
|
49
|
+
pendingAfter: number;
|
|
50
|
+
};
|
|
34
51
|
export type L8ShadowQueueDeps = L8MergeQueueDeps & {
|
|
35
52
|
observe?: (verdict: L8ShadowVerdict) => void | Promise<void>;
|
|
53
|
+
observeEnqueue?: (entry: L8ShadowEnqueueObservation) => void | Promise<void>;
|
|
36
54
|
resolveConflict?: (file: string, conflicted: string, target: string, worktree: string) => Promise<string>;
|
|
37
55
|
};
|
|
38
56
|
|
|
@@ -80,23 +98,67 @@ export function shadowPrNumber(raw: string): number {
|
|
|
80
98
|
return number;
|
|
81
99
|
}
|
|
82
100
|
|
|
101
|
+
// Keep the CLI's existing pending return shape; metadata remains in the shared ledger and enqueue observation.
|
|
102
|
+
function publicShadowQueueState(state: L8ShadowQueueState): L8ShadowQueueState {
|
|
103
|
+
return { ...state, pending: state.pending.map(({ number, head }) => ({ number, head })) };
|
|
104
|
+
}
|
|
105
|
+
|
|
83
106
|
export async function statusL8ShadowQueue(cwd: string, deps: L8ShadowQueueDeps = {}): Promise<L8ShadowQueueState> {
|
|
84
|
-
return withShadowQueue(cwd, deps, async (state) => state);
|
|
107
|
+
return withShadowQueue(cwd, deps, async (state) => publicShadowQueueState(state));
|
|
85
108
|
}
|
|
86
109
|
|
|
87
110
|
export async function enqueueL8ShadowQueue(cwd: string, number: number, deps: L8ShadowQueueDeps = {}): Promise<L8ShadowQueueState> {
|
|
88
111
|
if (!Number.isSafeInteger(number) || number <= 0) throw new Error('expected a positive PR number');
|
|
89
112
|
return withShadowQueue(cwd, deps, async (state, path) => {
|
|
90
113
|
const execute = deps.command ?? command;
|
|
91
|
-
const view = JSON.parse(shadowCommand(execute, 'gh', ['pr', 'view', String(number), '--json', 'headRefOid,baseRefName,state,isDraft,isCrossRepository'], cwd)) as {
|
|
114
|
+
const view = JSON.parse(shadowCommand(execute, 'gh', ['pr', 'view', String(number), '--json', 'headRefOid,baseRefName,state,isDraft,isCrossRepository,files'], cwd)) as {
|
|
92
115
|
headRefOid?: string; baseRefName?: string; state?: string; isDraft?: boolean; isCrossRepository?: boolean;
|
|
116
|
+
files?: { path?: string }[];
|
|
93
117
|
};
|
|
94
118
|
if (!view.headRefOid || !/^[0-9a-f]{40}$/i.test(view.headRefOid) || view.baseRefName !== 'main'
|
|
95
119
|
|| view.state !== 'OPEN' || view.isDraft !== false || view.isCrossRepository !== false) throw new Error('PR is not an open, ready, same-repository main PR');
|
|
96
120
|
if (state.pending.some((p) => p.number === number)) throw new Error(`PR #${number} already queued`);
|
|
97
|
-
|
|
121
|
+
const files = Array.isArray(view.files) && view.files.length < 100
|
|
122
|
+
&& view.files.every((file) => typeof file?.path === 'string')
|
|
123
|
+
? [...new Set(view.files.map((file) => file.path!))].sort()
|
|
124
|
+
: undefined;
|
|
125
|
+
const filesUnmeasured = !files;
|
|
126
|
+
const overlapsWith: number[] = [];
|
|
127
|
+
const overlapsUnknownWith: number[] = [];
|
|
128
|
+
const paths = new Set(files);
|
|
129
|
+
for (const previous of state.pending) {
|
|
130
|
+
if (filesUnmeasured || !Array.isArray(previous.files) || previous.filesUnmeasured) {
|
|
131
|
+
overlapsUnknownWith.push(previous.number);
|
|
132
|
+
} else if (previous.files.some((file) => paths.has(file))) {
|
|
133
|
+
overlapsWith.push(previous.number);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const item: L8ShadowQueueItem = {
|
|
137
|
+
number, head: view.headRefOid, ...(files ? { files } : { filesUnmeasured: true as const }),
|
|
138
|
+
overlapsWith, overlapsUnknownWith,
|
|
139
|
+
};
|
|
140
|
+
const entry: L8ShadowEnqueueObservation = {
|
|
141
|
+
number, head: view.headRefOid, fileCount: files?.length ?? null, filesUnmeasured,
|
|
142
|
+
overlapsWith, overlapsUnknownWith, pendingAfter: state.pending.length + 1,
|
|
143
|
+
};
|
|
144
|
+
state.pending.push(item);
|
|
98
145
|
writeShadowQueue(path, state);
|
|
99
|
-
|
|
146
|
+
try {
|
|
147
|
+
await (deps.observeEnqueue ?? ((data) => {
|
|
148
|
+
const store = getDefaultLogStore();
|
|
149
|
+
if (!store) {
|
|
150
|
+
if (process.env.NODE_ENV === 'test') return;
|
|
151
|
+
throw new Error('merge-queue observation store unavailable');
|
|
152
|
+
}
|
|
153
|
+
store.insertBatch([{ rec: { ts: new Date().toISOString(), category: 'merge-queue', event: 'enqueued', data }, surface: 'merge-queue' }]);
|
|
154
|
+
}))(entry);
|
|
155
|
+
} catch (error) {
|
|
156
|
+
// The shared queue is still locked: remove only this unobserved enqueue, leaving older items intact.
|
|
157
|
+
state.pending.pop();
|
|
158
|
+
writeShadowQueue(path, state);
|
|
159
|
+
throw error;
|
|
160
|
+
}
|
|
161
|
+
return publicShadowQueueState(state);
|
|
100
162
|
});
|
|
101
163
|
}
|
|
102
164
|
|