elanous 0.2.24 → 0.2.27
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/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/{Q-7iofoxOEv1WX18S35of → Ev2jivDMTSoEc-5rIXdcy}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/1027.a0f04663d24c2779.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1038.676007ae505822e7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1113.a37eadf7f740d955.js +1 -0
- package/apps/pwa/out/_next/static/chunks/112-fa7c526c20ce1405.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1144.5fa1fa1d48dbcd12.js +36 -0
- package/apps/pwa/out/_next/static/chunks/1146.80d15ea7c6e6ee95.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1157.f08bf2b70915e176.js +148 -0
- package/apps/pwa/out/_next/static/chunks/119b405e.8fdd0e44d1ff37aa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1296.04560d98e73fbf51.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1314-f604ba013ec535b0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1454-a9c338f5bb556f42.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1464.f3209af0d8ae4ff2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8532.a86e99acf9b761cb.js → 1516.83dd2c1b86b4e507.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{89849432.9eaa2f4c9c010965.js → 16e57f67.3ea19e893461e611.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/1729-d73dd25e564679d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{1505.5826671109111e75.js → 1743.563d3168e95825ef.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1843.5924c24295243261.js +27 -0
- package/apps/pwa/out/_next/static/chunks/1987.e28149724b92918b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2066-5ca18ffa5a4be68b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2240.d10a66695155fd93.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2391.e2cbc98d4abbb41a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2528.3868070ef1be69f9.js +24 -0
- package/apps/pwa/out/_next/static/chunks/2566-734cb83bbd405886.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2697.76ca2ac3efef6f3b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/275.0e6bad414729bfa0.js +32 -0
- package/apps/pwa/out/_next/static/chunks/2803-33bdae771855a8d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2846.d6a433b8663819a5.js +309 -0
- package/apps/pwa/out/_next/static/chunks/3143.257997a5f1ed79df.js +34 -0
- package/apps/pwa/out/_next/static/chunks/{5967-c0a80f8ffe5d4050.js → 3259-86f3be56e43eaf6a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/3280-e177c33bfbdcfb0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3294-2b6a6d45a46a6c1c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3309.364573ceedbdfd5f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3522.758840fc5e7fe630.js +287 -0
- package/apps/pwa/out/_next/static/chunks/3525-a7c989c1a661e880.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3694.b1a66387756458c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/370.124f9e678a76fc01.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3797-9643105335e660fe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5578.ac963634373b28c6.js → 4084.15ecaf4240bd9e77.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/4089-b3382b8843114eee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8438.ee7f0df3b3f6fcb4.js → 4204.a409ab6250c0f6a8.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4293.928a8d573c16aab7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4402.f9238a3b18a7bd43.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4490-9b090b0f9427f902.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4548.13502d0ca3b4f862.js +8 -0
- package/apps/pwa/out/_next/static/chunks/4565-67e4c620597965c8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7905.b230b9d06cb4ad5d.js → 4593.10f5b9bd702d4a6c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4599-548bc96cda44a5a7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4625.206574e33a9e7ae8.js +104 -0
- package/apps/pwa/out/_next/static/chunks/4862-392c9a71f0d8dfb4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5054.2906d1b02542edc5.js +149 -0
- package/apps/pwa/out/_next/static/chunks/{8569.b853a8daa8f31d12.js → 5081.a240b63fad28663a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5102-c822bbbee5a022a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5194-8c93f2e7e4b6f717.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5305-bacd7eca0b9a5848.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5311.9071ee3f44fd7ff5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5369.9f34353442daa421.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2528.0af5c0e1fad88df6.js → 5408.377c8c543635b81f.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9502-32c5dc22e8f120f5.js → 5492-e05e26a033ba80d2.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/5785-ea8d2c633b6688e3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/589-49d730cb8138b397.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5904-264a6412ae3c9028.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5980.728531d5c566535c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/599-a914cc0468f56143.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6011.f525002e21bef0ac.js +23 -0
- package/apps/pwa/out/_next/static/chunks/6132.4381ab93683f1acf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6149.2e698635e454d8f6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5974.360f8441eb0ac1ec.js → 6196.34d6b229079e9e28.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6356-0afafc4230cf9767.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6406.64756073f7df35b8.js +77 -0
- package/apps/pwa/out/_next/static/chunks/6479-16e62aedafa0e310.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6599.b5246b46a2453329.js +64 -0
- package/apps/pwa/out/_next/static/chunks/{ce383d63.d2ede338788ed18e.js → 65ebff95.081daeff622d238e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/6610.5c26eec011565acb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/666.37d18474edc1c552.js +2 -0
- package/apps/pwa/out/_next/static/chunks/6904.a0b5b1ed4f2d2c20.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{83cfc5c8.349535543c1548b6.js → 6def8a8e.c81f9ca41028eccf.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7247-1f4aba94aba50d9f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7274-e71a7c5b7760cd02.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7290.1fcaeef3adb5d0d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7477-2c64e42760f82f33.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2721.bc9a8f36bd85c07a.js → 7483.ba01c6c209b81bba.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7505-47002b76ff1aef6c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7600-11884ca4da68e5d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7607.40d8bb3689697ccb.js +62 -0
- package/apps/pwa/out/_next/static/chunks/{6702.ebbd165d5e4a4a14.js → 7752.5cbdd0b433c54af9.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7763.f51fcc19ca1414ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7785.846140c859b1adf6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7807-a0fdac6393e0bf36.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7837-20a63b4b7e9342b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/800.7815414cf280545d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8925-2abfb48af477fb7f.js → 8085-1e5fce59500a2cc2.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8100.415f2105faa63e97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8290.701aa42ed13aa767.js +226 -0
- package/apps/pwa/out/_next/static/chunks/{b4e12462-5fab4a813a63dadd.js → 83a80514-b897b64df43ce108.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8444.d9c74214a3145a43.js +93 -0
- package/apps/pwa/out/_next/static/chunks/8569.98c915534928c7f9.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{8264.00e434fbd02e9311.js → 8578.dff22d988cc2b106.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/8591.b1c7f876e5ec7cfb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8715-f63756021d3ab989.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8879.776c2ec7732aa114.js +115 -0
- package/apps/pwa/out/_next/static/chunks/8881.ddca15b3c82c490c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8946.5da5c87f32a2e1a8.js +41 -0
- package/apps/pwa/out/_next/static/chunks/9117.080b9b75be90e14d.js +74 -0
- package/apps/pwa/out/_next/static/chunks/9167.f3ecb28f367d6e69.js +94 -0
- package/apps/pwa/out/_next/static/chunks/9224.66095370ee28c93b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9238-0682b013c83d6449.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7518.49161e8f5814abdb.js → 9311.24c8f5ea793253dd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9976.8f28864317639fe6.js → 94.4cfed21c0b781a06.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/9449.d3ed795da4befb1c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/949.1e7d45ccb71580aa.js +90 -0
- package/apps/pwa/out/_next/static/chunks/9638-d268329f2c6f4f8d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{0e3acd34.d42b2ef87fdf4234.js → 973cbf1b.3bbcf2b41548eca7.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9842-d6644eb53d3dc6bf.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9863.94ca3263e760696e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6571-926ddf024a6ad5df.js → 9917-9e26abc5f7772735.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9938.b23e4d4dfa0114cd.js +79 -0
- package/apps/pwa/out/_next/static/chunks/{740.90b31555290236a9.js → 9974.e77b4ff4884557b3.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{4c5e95ce.83e9b16add6fcd8c.js → ab4d57c2.e90bc2cb31949045.js} +7 -7
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d9babd8795f396a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-a1ce306364f08da9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-07110da72c45e68f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-d2d76d4a7eae91bd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-30007380f2e2a3c1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-e5a9302c105725a3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-b93c04b5311c97ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-718a49e86bf25f9c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-20662900d6b4b455.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-f707a509515ac50c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-6a16a48d1aa6e91f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/{page-26345242e4049f55.js → page-fcb06e305f515527.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-6acf5ec4e6c6d1af.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-39f82acf619cca23.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-7c2c8f81b185f9c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-d9babd8795f396a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-ae7aff07e32676bb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-482c60c1bc540d0a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-7cb996c1aa08b6f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-623e08fe4477d606.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-db460cd8aecb8490.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-ff27902d0b11ef4f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-8397a5c6ca569bf4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1917ea87ea71ab6b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-25a302273b054fd7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-670510eda8b9443f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-d73c3f1e00d93986.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-65caacf54389081e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-4bb7556e2e97a750.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-77e04b4f8762c666.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/{page-b92caddb5c715f30.js → page-15c0a4095baddfba.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/page-4eb96fc7241c2456.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-63e272a4cd3b6634.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-0d64ff212dc55d03.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-7f096248993fc2d4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-e47fc72049149a38.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-f7d808e31e005895.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-5c2b24b5496dad73.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-d9babd8795f396a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-76cdb531668b5191.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-e2b63345bba1a11f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-d376e0c83edc041a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-d6db55fe2c04d128.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-87b88f551f421d8b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-dab163b338e3b966.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-08019efef111ed2e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-0260ffc7eda50db1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-980ce6fe36ad95eb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-99c4e6c7345a9156.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-0ab42e0f05823013.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-ad9220422d20ba33.js +1 -0
- package/apps/pwa/out/_next/static/chunks/dcf24383-2f82e35f2d827393.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{53746282.1be36038d1abd949.js → e117f801.e92bf10242653497.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/e87d89b9.2e71c0ae475d28a1.js +122 -0
- package/apps/pwa/out/_next/static/chunks/{0673cc54.8e2ef1c23e49e190.js → f4dfbfc0.a69fb12f854882aa.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/framework-bf135b997155e90e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-5571537543bea91c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-25c51c7df7f3a442.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-e3b2c1f5d82abd65.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-083f2e23e9bc3641.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-e94d22b7a028217b.js +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +22 -22
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +22 -22
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +22 -22
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +21 -21
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +21 -21
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +22 -22
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +21 -21
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +22 -22
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +22 -22
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +21 -21
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +22 -22
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +22 -22
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +22 -22
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +22 -22
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +21 -21
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +21 -21
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +22 -22
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +22 -22
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +22 -22
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +21 -21
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +21 -21
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +21 -21
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +22 -22
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +22 -22
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +21 -21
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +21 -21
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +21 -21
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +21 -21
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +22 -22
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +22 -22
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +21 -21
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +22 -22
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +22 -22
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +22 -22
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +22 -22
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +22 -22
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +21 -21
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +22 -22
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +22 -22
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +22 -22
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +22 -22
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +22 -22
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +22 -22
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +22 -22
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +22 -22
- package/graphs/release/release-loop.yaml +5 -5
- package/graphs/steward/recipes.yaml +4 -0
- package/graphs/steward/steward.yaml +10 -1
- package/package.json +1 -1
- package/scripts/bench-report.ts +46 -1
- package/scripts/ci-typecheck-changed.ts +88 -7
- package/scripts/coord-msg-bridge.ts +209 -0
- package/scripts/coord-post.sh +40 -7
- package/scripts/coord-requests-bridge.ts +10 -5
- package/scripts/expose-rubric-suggest.ts +1 -1
- package/scripts/measure-tsc-affected-roots.ts +10 -1
- package/scripts/release-loop/auto-approve-node.ts +6 -0
- package/scripts/release-loop/export-check-node.ts +8 -5
- package/scripts/release-loop/gate-closure.ts +286 -0
- package/scripts/release-loop/gate-node.ts +73 -13
- package/scripts/release-loop/gate-partial.ts +34 -6
- package/scripts/release-loop/node-verdict.ts +7 -2
- package/scripts/release-loop/ops-upgrade-node.ts +63 -42
- package/scripts/release-loop/publish-node.ts +6 -0
- package/scripts/release-loop/resume-release.ts +37 -10
- package/scripts/release-loop/resume.ts +69 -4
- package/scripts/tsc-baseline-cache.ts +28 -3
- package/scripts/usage-rollup.ts +27 -13
- package/scripts/ux-sim.ts +30 -1
- package/skills/youtube-master/scripts/main.ts +4 -1
- package/skills/youtube-master/src/obsidian.ts +9 -0
- package/src/agent/task-notification.ts +30 -1
- package/src/agent-substrate/acp-implementer.ts +14 -7
- package/src/agent-substrate/pr-reviewer.ts +30 -10
- package/src/agent-substrate/review-observation.ts +9 -2
- package/src/agent-substrate/self-review-cli.ts +154 -16
- package/src/boot/daemon-tools/self-implement.ts +72 -4
- package/src/budget/cost-tier-advisor.ts +91 -0
- package/src/budget/llm-cost.ts +5 -1
- package/src/budget/shadow-arms.ts +77 -0
- package/src/budget/types.ts +5 -3
- package/src/budget/unified-usage.ts +172 -8
- package/src/cli/control-cli.ts +29 -0
- package/src/cli/doctor-cli.ts +106 -3
- package/src/cli/friendly-errors.ts +113 -0
- package/src/cli/intake-cli.ts +3 -1
- package/src/cli/memory-cli.ts +182 -0
- package/src/cli/model-watch-cli.ts +4 -1
- package/src/cli/msg-cli.ts +15 -5
- package/src/cli/pr-cli.ts +53 -0
- package/src/cli/pr-land-overlap-evidence.ts +18 -10
- package/src/cli/pr-land-pod-shadow.ts +54 -0
- package/src/cli/release-cli.ts +41 -12
- package/src/cli/release-run-if-ready.ts +11 -0
- package/src/cli/resource-cli.ts +48 -0
- package/src/cli/retro-cli.ts +12 -3
- package/src/cli/seat-cli.ts +121 -0
- package/src/cli/seat-requests-cli.ts +25 -0
- package/src/cli/self-utterances-cli.ts +140 -0
- package/src/cli/tasks-cli.ts +168 -14
- package/src/cli/usage-cli.ts +3 -1
- package/src/compact/verify-probe.ts +23 -3
- package/src/context-card/cell.ts +40 -0
- package/src/context-card/index.ts +50 -0
- package/src/control/control-status.ts +30 -1
- package/src/dashboard/boot-timing.ts +35 -0
- package/src/dashboard/index.ts +86 -24
- package/src/dashboard/input/chat-main-plain-turn-runtime.ts +26 -0
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +10 -138
- package/src/dashboard/slash-runtime/shell-slash.ts +145 -0
- package/src/debug/log-diet.ts +16 -4
- package/src/debug/log.ts +1 -1
- package/src/domains/morning-essential.ts +18 -3
- package/src/domains/release-tool.ts +29 -8
- package/src/domains/surface-events.ts +16 -0
- package/src/elanous-config-dir.ts +2 -2
- package/src/execution-loop/launch-gate.ts +158 -2
- package/src/fleet/host-doctor.ts +446 -0
- package/src/goals/judge.ts +20 -6
- package/src/graph-runner/runner.ts +12 -6
- package/src/graph-wizard/archetypes.ts +14 -8
- package/src/graph-wizard/generate.ts +77 -1
- package/src/grok.ts +13 -7
- package/src/harness/harness-cli-command.ts +102 -51
- package/src/harness/harness-stop.ts +93 -19
- package/src/index.ts +52 -179
- package/src/instance/current.ts +2 -6
- package/src/instance/resolve.ts +5 -6
- package/src/intake-plane/collect-github.ts +7 -2
- package/src/intake-plane/lens.ts +46 -4
- package/src/intake-plane/requirement-funnel.ts +53 -1
- package/src/intelligence-map/catalog-feed.ts +119 -0
- package/src/intelligence-map/model-watch-intake.ts +40 -0
- package/src/intelligence-map/model-watch-mission.ts +14 -1
- package/src/llm/open-weight-discipline.ts +21 -0
- package/src/llm/openai-sampling-fields.ts +89 -0
- package/src/llm/runtime-model-family.ts +61 -0
- package/src/llm/zai-coding-plan.ts +27 -1
- package/src/llm.ts +17 -97
- package/src/machines/machine-ledger.ts +31 -3
- package/src/maturity/cli-maturity.ts +13 -3
- package/src/maturity/feature-maturity.ts +1 -1
- package/src/msg/msg-store.ts +69 -7
- package/src/nexus/api/http-server.ts +22 -0
- package/src/oauth/codex-account-rotation.ts +4 -1
- package/src/oauth/codex-account-store.ts +20 -7
- package/src/oauth/codex-quota-policy.ts +33 -4
- package/src/ops/overview-collect.ts +3 -2
- package/src/ops/overview-owner.ts +29 -0
- package/src/plugin-hooks/shell-hook.ts +17 -2
- package/src/plugin-missions/evaluator-runner.ts +18 -2
- package/src/plugins/install/plugin-install.ts +11 -1
- package/src/preview/terminal.ts +15 -5
- package/src/project/project-store.ts +20 -0
- package/src/prompt-enhance/enhance.ts +11 -0
- package/src/release-loop/auto-start.ts +7 -5
- package/src/release-loop/checklist.ts +52 -5
- package/src/release-loop/feature-store.ts +10 -9
- package/src/release-loop/gate-shards.ts +4 -0
- package/src/release-loop/light-rc.ts +84 -13
- package/src/release-loop/merged-pr-checklist.ts +35 -5
- package/src/release-loop/rehearsal.ts +1 -1
- package/src/seat-loop/duty-ledger.ts +64 -0
- package/src/seat-loop/seat-loop.ts +5 -1
- package/src/self-dev/decompose.ts +37 -3
- package/src/self-dev/dev-pipeline.ts +32 -7
- package/src/self-dev/draft-residue.ts +16 -6
- package/src/self-dev/draft-sweep.ts +75 -18
- package/src/self-dev/fabric-decompose-adapter.ts +9 -2
- package/src/self-dev/orchestrate.ts +6 -2
- package/src/self-dev/run-supervisor.ts +72 -8
- package/src/self-implement/gate-cli.ts +29 -10
- package/src/self-implement/gate-remote.ts +4 -1
- package/src/self-implement/goal-author.ts +15 -29
- package/src/self-implement/goal-command-execution.ts +26 -0
- package/src/self-implement/goal-new-paths.ts +42 -0
- package/src/self-implement/host-regate.ts +124 -30
- package/src/self-implement/importer-test-index.ts +3 -1
- package/src/self-implement/l8-merge-queue.ts +80 -2
- package/src/self-implement/merge-train.ts +19 -0
- package/src/self-implement/off-diff-evidence.ts +40 -1
- package/src/self-implement/orchestrator.ts +90 -20
- package/src/self-implement/premise-review.ts +159 -0
- package/src/self-implement/pwa-import-graph.ts +194 -7
- package/src/self-implement/regate-detail.ts +79 -0
- package/src/self-implement/review-deferred-to-host.ts +21 -0
- package/src/self-implement/rework-budget-judgment.ts +23 -3
- package/src/self-implement/running-runs.ts +2 -2
- package/src/self-implement/scope-adjacency.ts +23 -0
- package/src/self-implement/seams.ts +42 -7
- package/src/self-implement/self-implement-runtime.ts +126 -21
- package/src/session/index.ts +14 -4
- package/src/session-runtime/index.ts +55 -11
- package/src/skills/tools/agent.ts +16 -1
- package/src/skills/tools/persistent-grounding.ts +11 -1
- package/src/skills/tools/shell.ts +33 -1
- package/src/steward/rejudge-tick.ts +142 -0
- package/src/task-agent/board.ts +92 -3
- package/src/task-agent/card-evidence.ts +88 -1
- package/src/task-agent/cover.ts +85 -1
- package/src/task-agent/live-moves.ts +14 -6
- package/src/task-agent/parent-host.ts +27 -3
- package/src/task-agent/rejudge-on-head.ts +370 -29
- package/src/task-agent/review-result-capture.ts +67 -2
- package/src/task-agent/shadow.ts +148 -21
- package/src/task-agent/task-hand.ts +22 -3
- package/src/task-orchestrator/surfaces/pod-command-job.ts +14 -0
- package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +122 -0
- package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +23 -0
- package/src/task-orchestrator/surfaces/pod-pool.ts +53 -0
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +236 -28
- package/src/tool-runtime/tool-search-runtime.ts +25 -0
- package/src/tui.ts +20 -1
- package/src/user-config.ts +21 -63
- package/src/ux-sim/fault-cred-expiry.ts +100 -0
- package/src/ux-sim/fault-pod-death.ts +74 -0
- package/src/ux-sim/fault-pool-cap.ts +81 -0
- package/src/version/packed-revision.json +1 -1
- package/src/webclone/qa-table.ts +22 -0
- package/apps/pwa/out/_next/static/chunks/0a09e062-34f747a17d8d8c2e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +0 -77
- package/apps/pwa/out/_next/static/chunks/1325-dc3f3c21eb181cb4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +0 -34
- package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +0 -24
- package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1669-da843ed73aa301f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +0 -36
- package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +0 -122
- package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +0 -62
- package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/272-0eed0fb0aab716b6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +0 -149
- package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3961-aaae04ed1d32622f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +0 -309
- package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5313.1697309c532b9856.js +0 -2
- package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +0 -74
- package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +0 -64
- package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +0 -32
- package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +0 -24
- package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +0 -93
- package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +0 -148
- package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +0 -226
- package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +0 -27
- package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +0 -115
- package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +0 -8
- package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +0 -23
- package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +0 -90
- package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +0 -94
- package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +0 -41
- package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +0 -287
- package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +0 -79
- package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +0 -104
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-3b9fc39362473ae7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f2b62c19ca68fef8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-d7602d489edf5f37.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-24282bf9f90031a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-8b7c5ab6b5bc8d64.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-4eb84d454f8c3415.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-b2e494bdad57fcb5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-c0ab229673a8b0eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-3e2b45f3c36dbac4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-c22aa511b28743ad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-bf88c0f558d8ef54.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-52fec523e5b5d3ad.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-67723dfdcde92b31.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-22725e2570f1126b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-1891335950d68b70.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-3267af1ebdc73cf5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-c314b75c11234998.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-9f9c85415f61782b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-c1d4276059085587.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-833aab587f26ad4c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8526c17ae38e6a50.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-f998637a8402115c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-b7bb53828b17b335.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-1b1850de0257e46d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6f23159fedb41f67.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1d809a87139dd024.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-da9e570234d481fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-8ce3a38e210b810a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-57ffeeb6019440fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-abbb417bf514630b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-2c2b3f29cec1efa4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-9369279f72fc7b51.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-64861f14039499c3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ddc4c93efd8ab94b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-901a1391b81053bc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-68d9bbaac9841a58.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-b5c0c996f329371e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-89881ccbcf728978.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-0e87a803b3d7165e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-58d4e5cb30ef4871.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-02ce4c3b5f39e4d2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-e620d1bb8eadcec2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-acf868c64d77f950.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-54fa605fa6dba457.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-bc79f0833533fa84.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-d5c4398eea03d8f3.js +0 -1
- package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-b2763b10dc6b3836.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +0 -1
- /package/apps/pwa/out/_next/static/{Q-7iofoxOEv1WX18S35of → Ev2jivDMTSoEc-5rIXdcy}/_ssgManifest.js +0 -0
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
parseGateLogTestRuns,
|
|
19
19
|
type PrEvidenceInput,
|
|
20
20
|
} from './pr-evidence-artifact.js';
|
|
21
|
+
import { REVIEW_DEFERRED_TO_HOST_MERGE_REASON } from './review-deferred-to-host.js';
|
|
21
22
|
import { assessImplementationArtifactCompleteness } from './implementation-artifact-completeness.js';
|
|
22
23
|
import { runContractAtNode, type RunContract } from './graph-run-contract.js';
|
|
23
24
|
export {
|
|
@@ -91,6 +92,7 @@ import { classifyError } from '../session-runtime/retry-policy.js';
|
|
|
91
92
|
import { decomposeSelfDevGoal, inferHotPaths, type SelfDevDecomposeOptions } from '../self-dev/decompose.js';
|
|
92
93
|
import { boundaryGlobs, boundaryViolations } from './goal-boundary.js';
|
|
93
94
|
import { askAtExecution, type ExecutionClarificationResult } from './execution-clarification.js';
|
|
95
|
+
import { classifyOutOfScope } from './scope-adjacency.js';
|
|
94
96
|
import { targetScopedGoalText } from './goal-text-path-scope.js';
|
|
95
97
|
import { dropStaleReverts, type RevertGuardResult } from './revert-guard.js';
|
|
96
98
|
import type { SelfDevGoalType } from '../self-dev/orchestrate.js';
|
|
@@ -157,10 +159,11 @@ import { resolveAdaptiveMaxReworkDecision, resolveEscalateTier, resolveEscalateT
|
|
|
157
159
|
import type { SupervisionReworkSource } from './supervision-vocabulary.js';
|
|
158
160
|
import { classifyReworkBudgetShadow } from './classify-shadow.js';
|
|
159
161
|
import { createReworkBudgetJudgment, REWORK_BUDGET_JUDGMENT, reworkBudgetEvidenceForObservation, reworkBudgetWorkflow } from './rework-budget-judgment.js';
|
|
162
|
+
import { formatGateFailedId, type PremiseReviewCard, type PremiseReviewInput } from './premise-review.js';
|
|
160
163
|
import { runWorkflowToCompletion } from '../workflow-runtime/executor.js';
|
|
161
164
|
import { mapReworkVerdict, supervisionObservationFields } from './supervision-vocabulary.js';
|
|
162
165
|
import { resolveRunOutcome } from './run-outcome.js';
|
|
163
|
-
import { authorLimitationCountFromGoal, harvestEvidenceLines, harvestedEvidenceObservation, MAX_HARVESTED_EVIDENCE_CHARS, parseOffDiffEvidence, requiredEvidenceFromGoal, runRequiredEvidenceChecks, coverRequiredEvidence, formatUncoveredEvidenceFeedback, type OffDiffEvidenceParse } from './off-diff-evidence.js';
|
|
166
|
+
import { authorLimitationCountFromGoal, harvestEvidenceLines, harvestedEvidenceObservation, MAX_HARVESTED_EVIDENCE_CHARS, parseOffDiffEvidence, requiredEvidenceFromGoal, runRequiredEvidenceChecks, coverRequiredEvidence, settleUncoveredEvidence, formatUncoveredEvidenceFeedback, type OffDiffEvidenceParse } from './off-diff-evidence.js';
|
|
164
167
|
import { pressDecisionSignals, type DecisionSignalPressResult } from './decision-signal-press.js';
|
|
165
168
|
import { inspectDecisionObservations, inspectDecisionSignalKinds, inspectDecisionSignalObservations } from '../../scripts/ask-marker-check.js';
|
|
166
169
|
|
|
@@ -580,6 +583,8 @@ export interface SelfImplementReview {
|
|
|
580
583
|
reviewed: boolean;
|
|
581
584
|
/** 리뷰가 실행되지 않은 실패 사유. 리뷰 엔진이 제공한 경우에만 관측으로 전달한다. */
|
|
582
585
|
failureReason?: string;
|
|
586
|
+
/** REVIEW-ACP-POD ②-b — 리뷰를 발사 호스트(Claude ACP)로 미뤘다. `reviewed` 는 거짓 그대로다(통과가 아니다). */
|
|
587
|
+
deferredToHost?: true;
|
|
583
588
|
/** 리뷰 엔진이 실제로 사용한 diff 예산. 없는 값은 미검토/no-diff 등으로, 완전한 diff의 증거가 아니다. */
|
|
584
589
|
diffTruncated?: boolean;
|
|
585
590
|
diffShownChars?: number;
|
|
@@ -817,11 +822,20 @@ function declaredPathsFromGoalDocumentText(document: string): { readable: boolea
|
|
|
817
822
|
if (originalAsk === null) return { readable: false, paths: [] };
|
|
818
823
|
const declared = parseDeclaredTargetPathsFromAsk(originalAsk);
|
|
819
824
|
if (!declared.readable) return declared;
|
|
820
|
-
const newFiles = originalAsk
|
|
825
|
+
const newFiles = declaredNewFilePaths(originalAsk);
|
|
826
|
+
return newFiles.length > 0 ? { readable: true, paths: [...new Set([...declared.paths, ...newFiles])] } : declared;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
function declaredNewFilePaths(askText: string): readonly string[] {
|
|
830
|
+
return askText.split(/\r?\n/).flatMap((line) => {
|
|
821
831
|
const match = DECLARED_NEW_FILES_LINE.exec(line);
|
|
822
832
|
return match ? parseDeclaredTargetPathsFromAsk(`대상 경로: ${match[1]}`).paths : [];
|
|
823
833
|
});
|
|
824
|
-
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
/** P3 전제의 경계 — ask 머리줄 «대상 경로:» ⊕ «신설:» 줄의 합집합. 못 읽으면 빈 목록(그때 P3 는 unknown). */
|
|
837
|
+
function declaredPremiseScopePaths(askText: string): string[] {
|
|
838
|
+
return [...new Set([...parseDeclaredTargetPathsFromAsk(askText).paths, ...declaredNewFilePaths(askText)])];
|
|
825
839
|
}
|
|
826
840
|
|
|
827
841
|
/** Only paths explicitly designated as targets in the ask or piece text protect an intentional revert. */
|
|
@@ -3633,7 +3647,8 @@ export async function runSelfImplement(opts: SelfImplementOptions): Promise<Self
|
|
|
3633
3647
|
try {
|
|
3634
3648
|
// 10-05 PODPROVIDER: record which child provider this run uses — «default» when the launch named none.
|
|
3635
3649
|
const launch = opts.launch ?? resolveLaunchStamp();
|
|
3636
|
-
const origin = { ...runOriginData(), childProvider: opts.childLlm?.provider ?? 'default', ...(opts.childLlm?.model ? { childModel: opts.childLlm.model } : {}),
|
|
3650
|
+
const origin = { ...runOriginData(), childProvider: opts.childLlm?.provider ?? 'default', ...(opts.childLlm?.model ? { childModel: opts.childLlm.model } : {}),
|
|
3651
|
+
...(process.env.ELANOUS_TASK_CARD_ID ? { taskCardId: process.env.ELANOUS_TASK_CARD_ID } : {}), launch };
|
|
3637
3652
|
(opts.seams.writeRunLedger ?? appendRunLedgerEntry)({
|
|
3638
3653
|
timestamp: new Date().toISOString(), runId, event: 'run-origin', data: origin,
|
|
3639
3654
|
...(opts.goalId ? { goalId: opts.goalId } : {}), ...shardIdentity,
|
|
@@ -6446,7 +6461,21 @@ async function runSelfImplementInner(
|
|
|
6446
6461
|
judgmentStarted = true;
|
|
6447
6462
|
const judgmentCallLLM = s.judgmentCallLLM;
|
|
6448
6463
|
if (diagnosedDecision?.verdict !== 'CONTRACT-CONFLICT' && !judgmentCallLLM) throw new Error('rework-budget@v1 requires a judgment provider');
|
|
6449
|
-
|
|
6464
|
+
// FLEX-RFC §A-③ — UNCONVERGEABLE 직전의 전제 되짚기 입력. 이 루프 뒤쪽 «flex-signals» 관측(6895~)과 같은
|
|
6465
|
+
// 실제 런 값으로 조립한다. 이 생산 배선이 없으면 카드는 시험에서만 세워지고 원장에는 남지 않는다.
|
|
6466
|
+
const premiseLatestEntry = roundSummaryEntries[roundSummaryEntries.length - 1];
|
|
6467
|
+
const premiseInput: PremiseReviewInput = {
|
|
6468
|
+
runId,
|
|
6469
|
+
gateFailedIdsByRound: premiseLatestEntry?.kind === 'gate'
|
|
6470
|
+
? roundSummaryEntries.filter((entry) => entry.kind === 'gate').map((entry) => entry.failedIds)
|
|
6471
|
+
: [],
|
|
6472
|
+
failureAttributions: reworkKind === 'gate' && gate ? gate.baselineFailures?.map(({ attribution }) => attribution) : undefined,
|
|
6473
|
+
reviewRepeat,
|
|
6474
|
+
round,
|
|
6475
|
+
plannedRounds: effectiveMax,
|
|
6476
|
+
targetPaths: declaredPremiseScopePaths(opts.feature),
|
|
6477
|
+
};
|
|
6478
|
+
const judgmentProvider = judgmentCallLLM ? createReworkBudgetJudgment(judgmentCallLLM, { premiseInput }) : undefined;
|
|
6450
6479
|
try {
|
|
6451
6480
|
const result = diagnosedDecision?.verdict === 'CONTRACT-CONFLICT'
|
|
6452
6481
|
? undefined
|
|
@@ -6628,6 +6657,17 @@ async function runSelfImplementInner(
|
|
|
6628
6657
|
: { evidence: null };
|
|
6629
6658
|
observe('rework-budget', { round, verdict: parsedDecision.verdict, reason: parsedDecision.reason.slice(0, 240), effectiveMaxBefore: before, effectiveMaxAfter: effectiveMax, carriedBudgetBefore, carriedBudgetAfter: judgedEffectiveMax, historyRounds: priorHistory.length, kind: reworkKind, applied: budgetDecision.applied, stopped: budgetDecision.stop, exit: budgetDecision.exit, shadowed: budgetDecision.shadowed === true, repeatedBlockingFindingCount: repeatedBlockingIds?.length ?? null, repeatedBlockingFindingIds: repeatedBlockingIds ?? null, normalizedRepeatedReviewFindingCount: recurrence?.normalizedRepeatedReviewFindingCount ?? null, ordinaryRepeatedReviewFindingCount: recurrence?.ordinaryRepeatedReviewFindingCount ?? null, previouslyDismissedRepeatedReviewFindingCount: recurrence?.previouslyDismissedRepeatedReviewFindingCount ?? null, citedReviewSymbolRepeatCount: recurrence?.citedReviewSymbolRepeatCount ?? null, citedReviewSymbolBaseNameRepeatCount: recurrence?.citedReviewSymbolBaseNameRepeatCount ?? null, reviewFindingComparableCount: recurrence?.comparableFindings ?? null, reviewFindingKeyRepeatCount: recurrence?.reviewFindingKeyRepeatCount ?? null, ...recurrenceDisagreementObservation, ...evidenceObservation, judgePredictedBefore: predictionAccuracyForObservation.predicted, judgeFulfilledBefore: predictionAccuracyForObservation.fulfilled, judgeMissedBefore: predictionAccuracyForObservation.missed, judgePendingBefore: predictionAccuracyForObservation.pending, ...(budgetDecision.shadowed ? { wouldExit: budgetDecision.wouldExit } : {}), ...(budgetDecision.contractConflictDisposition ? { contractConflictDisposition: budgetDecision.contractConflictDisposition } : {}), ...(pendingPlanRevision?.relaxation ? { contractConflictRelaxation: { ...pendingPlanRevision.relaxation, reason: pendingPlanRevision.reason, application: pendingPlanRevision.application?.status ?? 'failed' } } : {}), ...supervisionObservation }, { ...(budgetDecision.exit === 'blocked' ? { level: 'warn' as const } : {}), compact: { stringMax: 256, arrayMax: 6, maxDepth: 5 } });
|
|
6630
6659
|
if (parsedDecision.verdict === 'UNCONVERGEABLE' && budgetDecision.stop && budgetDecision.exit === 'blocked') {
|
|
6660
|
+
// FLEX-RFC §A-③(0.2.25 FLEX-PREMISE-REVIEW) — 확정된 UNCONVERGEABLE 의 전제 되짚기 카드를
|
|
6661
|
+
// «별도 원장 사건»으로 남긴다. 카드는 판정 provider 가 UNCONVERGEABLE 을 «내기 전에» 세웠다
|
|
6662
|
+
// (createReworkBudgetJudgment 가 premiseInput 으로 buildPremiseCard 를 부른다) — 이 자리는 그
|
|
6663
|
+
// 카드를 원장에 옮기기만 한다. 카드가 없으면 사건도 없다.
|
|
6664
|
+
const evidenceRecord: unknown = evidenceObservation.evidence;
|
|
6665
|
+
const premiseReview = typeof evidenceRecord === 'object' && evidenceRecord !== null
|
|
6666
|
+
? (evidenceRecord as { premiseReview?: PremiseReviewCard }).premiseReview
|
|
6667
|
+
: undefined;
|
|
6668
|
+
if (premiseReview) {
|
|
6669
|
+
observe('premise-review', { round, runId: premiseReview.runId, findings: premiseReview.findings, proposal: premiseReview.proposal ?? null }, { level: 'warn' as const, compact: { stringMax: 256, arrayMax: 6, maxDepth: 5 } });
|
|
6670
|
+
}
|
|
6631
6671
|
try {
|
|
6632
6672
|
const shadow = inferDecompositionShadow(opts.feature);
|
|
6633
6673
|
observe('decomposition-shadow', { round, ...shadow });
|
|
@@ -7130,8 +7170,12 @@ async function runSelfImplementInner(
|
|
|
7130
7170
|
offDiffEvidence = parseOffDiffEvidence(evidenceText);
|
|
7131
7171
|
const requiredEvidence = requiredEvidenceFromGoal(opts.feature);
|
|
7132
7172
|
const limitationCount = authorLimitationCountFromGoal(opts.feature);
|
|
7133
|
-
runRequiredEvidenceChecks(opts.feature, wt.path, runId);
|
|
7134
|
-
const
|
|
7173
|
+
const evidenceChecks = runRequiredEvidenceChecks(opts.feature, wt.path, runId);
|
|
7174
|
+
const tagCoverage = coverRequiredEvidence(requiredEvidence, offDiffEvidence.items);
|
|
7175
|
+
// EVIDENCE-WIRING-EXEMPT — a requirement whose own `|| bun test …` check passed is covered by what the harness measured.
|
|
7176
|
+
const settledByCheck = settleUncoveredEvidence(tagCoverage.uncovered, { checks: evidenceChecks, required: requiredEvidence });
|
|
7177
|
+
if (settledByCheck.coveredByCheck.length) debug.log('self-implement.evidence', 'covered-by-check', { round, tags: settledByCheck.coveredByCheck });
|
|
7178
|
+
const coverage = { ...tagCoverage, uncovered: settledByCheck.uncovered, uncoveredCount: settledByCheck.uncovered.length };
|
|
7135
7179
|
evidenceCoverage = requiredEvidence.length || limitationCount
|
|
7136
7180
|
? {
|
|
7137
7181
|
required: requiredEvidence.length,
|
|
@@ -7226,21 +7270,35 @@ async function runSelfImplementInner(
|
|
|
7226
7270
|
// 🩸 10-09: 범위 타입검사 임시 tsconfig(.elanous-typecheck-scope-*.json · scoped-typecheck-config.ts)가 옛 가지에 커밋된 뒤 지워지면
|
|
7227
7271
|
// «추적 파일 삭제» 라 impact=critical → 결정 카드가 «irreversible» 로 대표에게 갔다(D-20·35·43·80). 하니스 임시물은 범위 판정 밖이다.
|
|
7228
7272
|
const scope = detectDeclaredScopeDiff({ goalDocument, changedFiles: gateRouteFiles?.filter(file => !harnessSeededPaths.includes(file) && !isHarnessTempArtifact(file)), nameCap: gateRouteFiles?.length });
|
|
7229
|
-
|
|
7230
|
-
|
|
7273
|
+
// SCOPE-HELD-DELIVER — no declared target means the declaration was unreadable (e.g. paths listed with spaces), not
|
|
7274
|
+
// that every edit is outside it: treat it like an unknown declaration and go on to the gate.
|
|
7275
|
+
if (scope.status === 'known' && scope.declaredCount === 0 && (scope.outsideCount ?? 0) > 0) {
|
|
7276
|
+
observe('execution-scope-undeclared', { outsideCount: scope.outsideCount });
|
|
7277
|
+
progress('implementing', `⚠️ 대상 경로를 하나도 못 읽었다 — 범위 밖 ${scope.outsideCount}개를 묻지 않고 게이트로 간다`);
|
|
7278
|
+
} else if (scope.status === 'known' && scope.outsideCount !== null && scope.outsideCount > 0) {
|
|
7279
|
+
const impact = scope.outsideNames.some(file => {
|
|
7280
|
+
if (existsSync(join(wt.path, file))) return false;
|
|
7281
|
+
const tracked = runGitCommand(wt.path, ['ls-files', '--error-unmatch', '--', file], { encoding: 'utf8', timeout: 20_000 });
|
|
7282
|
+
return tracked.status === 0;
|
|
7283
|
+
}) ? 'critical' : 'high';
|
|
7284
|
+
const declaredPaths = declaredPathsFromGoalDocumentText(goalDocument!).paths;
|
|
7285
|
+
const { adjacent, other } = classifyOutOfScope(scope.outsideNames, declaredPaths);
|
|
7286
|
+
// Only edits next to a declared file, none of them a deletion: the gate judges them — nobody has to answer first.
|
|
7287
|
+
const adjacentOnly = impact !== 'critical' && !scope.nameCapReached && other.length === 0 && adjacent.length === scope.outsideCount;
|
|
7288
|
+
if (adjacentOnly) {
|
|
7289
|
+
observe('execution-scope-adjacent-accepted', { outsideCount: scope.outsideCount, adjacent });
|
|
7290
|
+
progress('implementing', `범위 밖 인접 편집 ${adjacent.length}개(대상과 같은 폴더) — 묻지 않고 게이트로 간다: ${adjacent.join(' · ')}`);
|
|
7291
|
+
}
|
|
7292
|
+
const result: ExecutionClarificationResult = adjacentOnly ? { choice: 'Expand scope', by: 'assumed' } : await (s.askExecutionClarification ?? askAtExecution)({
|
|
7231
7293
|
id: 'execution_scope', decision: 'Changing files outside the authored target paths',
|
|
7232
7294
|
prompt: 'Implementation changed files outside the authored target paths. Keep the original scope or expand it?',
|
|
7233
7295
|
whyNow: 'Continuing to gate or publish these edits would expand the requested scope.',
|
|
7234
|
-
impact
|
|
7235
|
-
if (existsSync(join(wt.path, file))) return false;
|
|
7236
|
-
const tracked = runGitCommand(wt.path, ['ls-files', '--error-unmatch', '--', file], { encoding: 'utf8', timeout: 20_000 });
|
|
7237
|
-
return tracked.status === 0;
|
|
7238
|
-
}) ? 'critical' : 'high',
|
|
7296
|
+
impact,
|
|
7239
7297
|
options: [
|
|
7240
7298
|
{ label: 'Stay in scope', description: 'Do not accept out-of-scope changes.', recommended: true },
|
|
7241
7299
|
{ label: 'Expand scope', description: 'Accept the changed files outside the target paths.' },
|
|
7242
7300
|
],
|
|
7243
|
-
}, { runId, outsideFiles: scope.outsideNames, outsideCount: scope.outsideCount, declaredPaths
|
|
7301
|
+
}, { runId, outsideFiles: scope.outsideNames, outsideCount: scope.outsideCount, declaredPaths }, { writeRunLedger: s.writeRunLedger });
|
|
7244
7302
|
if ('parked' in result || 'deferred' in result || result.choice !== 'Expand scope') {
|
|
7245
7303
|
finalizeSupervisorDeliveries('execution-scope-not-approved');
|
|
7246
7304
|
observe('execution-scope-held', { outsideCount: scope.outsideCount, disposition: 'parked' in result ? 'parked' : 'in-scope-only' });
|
|
@@ -7487,7 +7545,7 @@ async function runSelfImplementInner(
|
|
|
7487
7545
|
}
|
|
7488
7546
|
lastGateUnverifiedKey = unverifiedRepeatKey(gate.unverified);
|
|
7489
7547
|
roundSummaryEntries.push({ round, kind: 'gate', tried: impl.summary.replace(/\s+/g, ' ').trim().slice(0, 200),
|
|
7490
|
-
failedIds: gate.baselineFailures?.map(
|
|
7548
|
+
failedIds: gate.baselineFailures?.map(formatGateFailedId),
|
|
7491
7549
|
filesTouched: gateRouteFiles,
|
|
7492
7550
|
});
|
|
7493
7551
|
round++;
|
|
@@ -7831,6 +7889,14 @@ async function runSelfImplementInner(
|
|
|
7831
7889
|
continue;
|
|
7832
7890
|
}
|
|
7833
7891
|
}
|
|
7892
|
+
// EVIDENCE-WIRING-EXEMPT — a commandless [preservation] is covered once the changed-file gate passed.
|
|
7893
|
+
if (gate.passed && evidenceCoverage?.uncoveredCount) {
|
|
7894
|
+
const settledByGate = settleUncoveredEvidence(evidenceCoverage.uncovered, { gatePassed: true, required: requiredEvidenceFromGoal(opts.feature) });
|
|
7895
|
+
if (settledByGate.coveredByGate.length) {
|
|
7896
|
+
debug.log('self-implement.evidence', 'covered-by-gate', { round, tags: settledByGate.coveredByGate });
|
|
7897
|
+
evidenceCoverage = { ...evidenceCoverage, uncovered: settledByGate.uncovered, uncoveredCount: settledByGate.uncovered.length };
|
|
7898
|
+
}
|
|
7899
|
+
}
|
|
7834
7900
|
if (gate.passed && autoMergeEnabled(opts) && evidenceCoverage?.uncoveredCount && !uncoveredFeedbackUsed && round < effectiveMax) {
|
|
7835
7901
|
const uncovered = [...evidenceCoverage.uncovered];
|
|
7836
7902
|
const nextRound = round + 1;
|
|
@@ -7869,8 +7935,11 @@ async function runSelfImplementInner(
|
|
|
7869
7935
|
? { completionDisposition }
|
|
7870
7936
|
: {};
|
|
7871
7937
|
const reviewReal = !!review?.reviewed;
|
|
7938
|
+
// REVIEW-ACP-POD ②-b — 호스트가 병합하는(mergeByHost) 런에서만 «미룬 리뷰»를 merge-ready 로 받는다. 판정은 호스트 ACP 리뷰가 한다.
|
|
7939
|
+
// ⛔ 그 밖의 런에선 종전 그대로 no-real-review(HITL) — 리뷰 없이 병합하는 길을 새로 열지 않는다.
|
|
7940
|
+
const reviewDeferredToHost = !reviewReal && review?.deferredToHost === true && opts.mergeByHost === true && review.mustFix.length === 0;
|
|
7872
7941
|
const reviewedHeadResult = reviewReal && reviewedHeadCommit ? { reviewedHeadCommit } : {};
|
|
7873
|
-
const reviewDiffComplete = review?.diffTruncated === false;
|
|
7942
|
+
const reviewDiffComplete = review?.diffTruncated === false || reviewDeferredToHost;
|
|
7874
7943
|
const requiredEvidenceMissing = evidenceCoverage !== undefined && evidenceCoverage.uncoveredCount > 0;
|
|
7875
7944
|
const { latestSignalIncomplete } = signalIncompleteState(roundClassifications);
|
|
7876
7945
|
const autoMerge = autoMergeEnabled(opts);
|
|
@@ -7880,7 +7949,7 @@ async function runSelfImplementInner(
|
|
|
7880
7949
|
// 종전 `verdict !== 'fail'` 만 보던 이 자리에서 auto 가 됐다(#25914 · #25934 · #25918 실물).
|
|
7881
7950
|
// ⭐ 반사가 must-fix 를 «전부» 기각하면 위에서 `review.mustFix = []` 로 비우므로 그 길은 종전 그대로다.
|
|
7882
7951
|
const reviewMustFixCount = review?.mustFix?.length ?? 0;
|
|
7883
|
-
let canAuto = !gateTimeoutUnmeasured && autoMerge && reviewReal && review!.verdict !== 'fail' && reviewMustFixCount === 0 && reviewDiffComplete && !requiredEvidenceMissing && !latestSignalIncomplete && !decisionSignalRed;
|
|
7952
|
+
let canAuto = !gateTimeoutUnmeasured && autoMerge && (reviewReal || reviewDeferredToHost) && review!.verdict !== 'fail' && reviewMustFixCount === 0 && reviewDiffComplete && !requiredEvidenceMissing && !latestSignalIncomplete && !decisionSignalRed;
|
|
7884
7953
|
// ⭐⭐ 통과의 «이유»를 둘로 가른다 — ⛔ 막지는 «않는다»(대표 판단 2026-08-11: ⓐ 문면만).
|
|
7885
7954
|
// 📏 근거(`JDG-T36` · merge-decision 300건 전수): `verifyByBreaking` 이 실린 8건의 auto 중 ***5건***이
|
|
7886
7955
|
// ***ran=true 인데 distinguishes=0***(아무것도 안 가르는 자기검증)이었고, 그 다섯이 «전부»
|
|
@@ -7891,7 +7960,8 @@ async function runSelfImplementInner(
|
|
|
7891
7960
|
// 그건 `skippedReason` 이 이미 가른다. 그래서 여기 조건에 넣지 않는다.
|
|
7892
7961
|
const verifyInconclusive = gate.verifyByBreaking?.ran === true && (gate.verifyByBreaking.distinguishes ?? 0) === 0;
|
|
7893
7962
|
const verifyNothingAtBase = verifyInconclusive && (gate.verifyByBreaking?.missingAtBase ?? 0) > 0;
|
|
7894
|
-
let mergeReason = canAuto
|
|
7963
|
+
let mergeReason = canAuto && reviewDeferredToHost ? REVIEW_DEFERRED_TO_HOST_MERGE_REASON
|
|
7964
|
+
: canAuto ? (verifyNothingAtBase ? 'review-clean-verify-nothing-at-base' : verifyInconclusive ? 'review-clean-verify-inconclusive' : 'review-clean-armed')
|
|
7895
7965
|
: gateTimeoutUnmeasured ? GATE_TIMEOUT_UNMEASURED_MERGE_REASON
|
|
7896
7966
|
: !autoMerge ? 'no-auto-flag'
|
|
7897
7967
|
: requiredEvidenceMissing ? 'required-evidence-uncovered'
|
|
@@ -8311,7 +8381,7 @@ async function runSelfImplementInner(
|
|
|
8311
8381
|
if (opts.mergeByHost) {
|
|
8312
8382
|
observe('merge-ready', { number: pr.number, checkedHeadCommit });
|
|
8313
8383
|
progress('pr-opened', `호스트 재게이트 대기 (#${pr.number})`);
|
|
8314
|
-
return { ok: true, stage: 'merge-ready', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, checkedHeadCommit: checkedHeadCommit!, prUrl: pr.url, prNumber: pr.number };
|
|
8384
|
+
return { ok: true, stage: 'merge-ready', node: 'open-pr', ...resolveRunOutcome({ termination: 'completed' }), ...decisionSignalResult, ...preservedCompletionResult, ...(completionStatus ? { completionStatus } : {}), sessionId, worktreePath: wt.path, branch: wt.branch, gate, ...(review ? { review } : {}), ...reviewedHeadResult, ...(reviewDeferredToHost ? { mergeReason } : {}), checkedHeadCommit: checkedHeadCommit!, prUrl: pr.url, prNumber: pr.number };
|
|
8315
8385
|
}
|
|
8316
8386
|
// Landing freeze: the in-flight marker is written before the freeze is read, so a `freeze on` racing this merge waits.
|
|
8317
8387
|
// The resume sweep merges from the repository that owns the run worktree (the worktree itself may be cleaned up).
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 전제 다섯 되짚기 — premise-review 카드 순수 계산(FLEX-RFC §A-③).
|
|
3
|
+
*
|
|
4
|
+
* P1 골 · P2 자(판정 시험) · P3 범위(대상 경로) · P4 쪼갬 · P5 환경.
|
|
5
|
+
* ⛔ LLM 없이 잴 수 있는 둘만 판정한다 — P3(범위) · P2(preexisting 자).
|
|
6
|
+
* ⛔ unknown 은 «맞다(ok)»가 아니다 — 못 잰 전제는 ok 로 지어내지 않는다.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { FlexSignalsInput } from './flex-signals.js';
|
|
10
|
+
|
|
11
|
+
/** 못 잰 근거의 표기 — P1·P4·P5 는 이 값으로 unknown 으로만 나간다. */
|
|
12
|
+
const UNMEASURED = '못 잼';
|
|
13
|
+
|
|
14
|
+
export type PremiseKey = 'P1' | 'P2' | 'P3' | 'P4' | 'P5';
|
|
15
|
+
export type PremiseVerdict = 'ok' | 'wrong' | 'unknown';
|
|
16
|
+
|
|
17
|
+
export interface PremiseFinding {
|
|
18
|
+
premise: PremiseKey;
|
|
19
|
+
verdict: PremiseVerdict;
|
|
20
|
+
evidence: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** `computeFlexSignals` 와 같은 꼴의 값 객체 + 카드가 가리킬 run 식별자와 P3 판정의 경계. */
|
|
24
|
+
export interface PremiseReviewInput extends FlexSignalsInput {
|
|
25
|
+
runId: string;
|
|
26
|
+
/** 이 골이 선언한 대상 경로 — 없으면 P3 는 unknown(경계를 못 잼). */
|
|
27
|
+
targetPaths?: readonly string[] | undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface PremiseReviewCard {
|
|
31
|
+
runId: string;
|
|
32
|
+
findings: PremiseFinding[];
|
|
33
|
+
/** wrong 이 있을 때만 «가장 좁은 것» 하나 — wrong 이 없으면 undefined. */
|
|
34
|
+
proposal: PremiseFinding | undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** 최신 라운드의 실패 id 목록 — `gateFailedIdsByRound` 의 마지막 칸이 최신(`computeFlexSignals` 와 같은 순서). */
|
|
38
|
+
function latestFailingIds(input: FlexSignalsInput): readonly string[] | undefined {
|
|
39
|
+
const latest = input.gateFailedIdsByRound.length === 0
|
|
40
|
+
? undefined
|
|
41
|
+
: input.gateFailedIdsByRound[input.gateFailedIdsByRound.length - 1];
|
|
42
|
+
return latest !== undefined && latest.length > 0 ? latest : undefined;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 게이트 실패 id — 생산자(orchestrator 의 roundSummaryEntries.failedIds)와 P3 파서가 «같은 꼴»을 쓰도록
|
|
47
|
+
* 둘 다 이 함수 짝을 거친다. 꼴: `${name}@${file ?? '?'} (${attribution})`.
|
|
48
|
+
*/
|
|
49
|
+
export function formatGateFailedId(failure: { name: string; file?: string | undefined; attribution: string }): string {
|
|
50
|
+
return `${failure.name}@${failure.file ?? '?'} (${failure.attribution})`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* 실패 id 에서 시험 파일을 뽑는다 — `name@` 접두와 ` (귀속)` 접미를 뗀다. 이름에 `@` 가 섞여도
|
|
55
|
+
* (`user@example.com`·`@scope/pkg`)·경로에 `@`(`src/@scope/x.ts`)가 있어도 가른다: 경로 안의 `@` 는
|
|
56
|
+
* 세그먼트 머리(맨 앞 또는 `/` 바로 뒤)에만 온다. 그래서 «공백 없고 · 확장자로 끝나고 · 안의 `@` 가 전부
|
|
57
|
+
* 세그먼트 머리인» 후보를 처음 주는 `@` 가 구분자다. 그런 `@` 가 없거나 파일이 `?`·빈 값이면 undefined
|
|
58
|
+
* (못 잼) — fail-closed. 남는 모호함: 이름이 `/` 로 끝나면(`a/@src/x.ts`) 구분자를 경로로 읽는다.
|
|
59
|
+
*/
|
|
60
|
+
export function gateFailedIdFile(id: string): string | undefined {
|
|
61
|
+
const withoutAttribution = id.replace(/\s*\([^)]*\)\s*$/, '');
|
|
62
|
+
for (let at = withoutAttribution.indexOf('@'); at >= 0; at = withoutAttribution.indexOf('@', at + 1)) {
|
|
63
|
+
const file = withoutAttribution.slice(at + 1);
|
|
64
|
+
if (file === '' || file === '?' || /\s/.test(file)) continue;
|
|
65
|
+
if (!/\.[A-Za-z0-9]+$/.test(file)) continue;
|
|
66
|
+
if (/[^/]@/.test(file)) continue;
|
|
67
|
+
return file;
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 시험 파일 → 짝 소스. `dir/x.test.ts` → `dir/x.ts`(같은 폴더). 시험 전용 폴더(`test/`·`__tests__/`)의 시험은
|
|
74
|
+
* 짝을 추측하지 않는다(undefined · fail-closed). 시험 꼴이 아닌 파일은 그 자신이 소스다.
|
|
75
|
+
*/
|
|
76
|
+
export function pairedSourceOf(file: string): string | undefined {
|
|
77
|
+
const normalized = file.replace(/^\.\//, '');
|
|
78
|
+
const testMatch = /^(.*)\.test\.([cm]?[jt]sx?)$/.exec(normalized);
|
|
79
|
+
if (!testMatch) return normalized;
|
|
80
|
+
if (/(^|\/)(test|tests|__tests__)\//.test(normalized)) return undefined;
|
|
81
|
+
return `${testMatch[1]}.${testMatch[2]}`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function insideTargets(path: string, targets: readonly string[]): boolean {
|
|
85
|
+
return targets.some((target) => {
|
|
86
|
+
const t = target.replace(/^\.\//, '').replace(/\/+$/, '');
|
|
87
|
+
return path === t || path.startsWith(`${t}/`);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** P2 자 — 판정 시험이 base 에서도 실패(preexisting)면 wrong. 귀속을 못 잼·하나라도 unknown 이면 unknown. */
|
|
92
|
+
function judgeP2(input: PremiseReviewInput): PremiseFinding {
|
|
93
|
+
const attributions = input.failureAttributions;
|
|
94
|
+
if (attributions === undefined || attributions.length === 0) {
|
|
95
|
+
return { premise: 'P2', verdict: 'unknown', evidence: UNMEASURED };
|
|
96
|
+
}
|
|
97
|
+
const preexistingIndex = attributions.indexOf('preexisting');
|
|
98
|
+
if (preexistingIndex >= 0) {
|
|
99
|
+
const latest = latestFailingIds(input);
|
|
100
|
+
const evidence = latest !== undefined && preexistingIndex < latest.length
|
|
101
|
+
? latest[preexistingIndex]!
|
|
102
|
+
: 'preexisting';
|
|
103
|
+
return { premise: 'P2', verdict: 'wrong', evidence };
|
|
104
|
+
}
|
|
105
|
+
if (attributions.includes('unknown')) {
|
|
106
|
+
return { premise: 'P2', verdict: 'unknown', evidence: UNMEASURED };
|
|
107
|
+
}
|
|
108
|
+
return { premise: 'P2', verdict: 'ok', evidence: `preexisting 0/${attributions.length}` };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* P3 범위 — 실패 시험 파일을 짝 소스로 옮겨 대상 경로와 견준다. 짝지은 소스(또는 시험 파일 자체)가
|
|
113
|
+
* 대상 경로 안이면 in · 짝은 지었는데 밖이면 wrong(그 시험 파일을 근거로). 파일을 못 읽거나 짝을 못 지은
|
|
114
|
+
* 실패가 하나라도 있고 wrong 이 없으면 unknown — 추측으로 ok 를 만들지 않는다.
|
|
115
|
+
*/
|
|
116
|
+
function judgeP3(input: PremiseReviewInput): PremiseFinding {
|
|
117
|
+
const latest = latestFailingIds(input);
|
|
118
|
+
const targets = input.targetPaths;
|
|
119
|
+
if (latest === undefined) return { premise: 'P3', verdict: 'unknown', evidence: UNMEASURED };
|
|
120
|
+
if (targets === undefined || targets.length === 0) return { premise: 'P3', verdict: 'unknown', evidence: UNMEASURED };
|
|
121
|
+
let unmeasured: string | undefined;
|
|
122
|
+
for (const id of latest) {
|
|
123
|
+
const file = gateFailedIdFile(id);
|
|
124
|
+
if (file === undefined) { unmeasured ??= `${UNMEASURED}: 실패 파일 없음 (${id})`; continue; }
|
|
125
|
+
if (insideTargets(file, targets)) continue;
|
|
126
|
+
const source = pairedSourceOf(file);
|
|
127
|
+
if (source === undefined) { unmeasured ??= `${UNMEASURED}: 짝 소스 없음 (${file})`; continue; }
|
|
128
|
+
if (!insideTargets(source, targets)) return { premise: 'P3', verdict: 'wrong', evidence: file };
|
|
129
|
+
}
|
|
130
|
+
if (unmeasured !== undefined) return { premise: 'P3', verdict: 'unknown', evidence: unmeasured };
|
|
131
|
+
return { premise: 'P3', verdict: 'ok', evidence: `failing files all inside target paths (${latest.length})` };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* wrong 이 여럿이면 «가장 좁은 것» 하나만 제안한다(RFC §A-③ — F6 카드 → F7 조치). 좁음 = 수정 폭:
|
|
136
|
+
* P2 자가 가장 좁다(판정 자만 고친다 · 골을 안 건드린다) → P5 환경(재무대) → P4 쪼갬 → P3 범위(경계를 넓힌다)
|
|
137
|
+
* → P1 골(요구 자체를 바꾼다)이 가장 넓다. findings 배열 순서에 우연히 맡기지 않고 이 rank 로 고른다.
|
|
138
|
+
*/
|
|
139
|
+
const NARROWEST_FIRST: readonly PremiseKey[] = ['P2', 'P5', 'P4', 'P3', 'P1'];
|
|
140
|
+
|
|
141
|
+
export function narrowestWrong(findings: readonly PremiseFinding[]): PremiseFinding | undefined {
|
|
142
|
+
for (const premise of NARROWEST_FIRST) {
|
|
143
|
+
const wrong = findings.find((finding) => finding.premise === premise && finding.verdict === 'wrong');
|
|
144
|
+
if (wrong !== undefined) return wrong;
|
|
145
|
+
}
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** 전제 다섯을 되짚어 카드를 세운다 — 순수 계산, LLM 을 부르지 않는다. */
|
|
150
|
+
export function buildPremiseCard(input: PremiseReviewInput): PremiseReviewCard {
|
|
151
|
+
const findings: PremiseFinding[] = [
|
|
152
|
+
{ premise: 'P1', verdict: 'unknown', evidence: UNMEASURED },
|
|
153
|
+
judgeP2(input),
|
|
154
|
+
judgeP3(input),
|
|
155
|
+
{ premise: 'P4', verdict: 'unknown', evidence: UNMEASURED },
|
|
156
|
+
{ premise: 'P5', verdict: 'unknown', evidence: UNMEASURED },
|
|
157
|
+
];
|
|
158
|
+
return { runId: input.runId, findings, proposal: narrowestWrong(findings) };
|
|
159
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { readdirSync, readFileSync } from 'node:fs';
|
|
1
|
+
import { readdirSync, readFileSync, statSync } from 'node:fs';
|
|
2
2
|
import { dirname, join, relative, resolve, sep } from 'node:path';
|
|
3
|
+
import ts from 'typescript';
|
|
4
|
+
import { debug } from '../debug/log.js';
|
|
3
5
|
|
|
4
6
|
type GraphFiles = {
|
|
5
7
|
readFile?: (path: string) => string;
|
|
@@ -24,6 +26,16 @@ function sourceFiles(cwd: string): string[] {
|
|
|
24
26
|
return files;
|
|
25
27
|
}
|
|
26
28
|
|
|
29
|
+
const IMPORT_SPECIFIER = /\b(?:import|export)\s+(?:[^;'"]*?\s+from\s*)?['"](\.[^'"]+)['"]|\bimport\s*\(\s*['"](\.[^'"]+)['"]\s*\)/g;
|
|
30
|
+
|
|
31
|
+
/** Repo-relative file candidates a relative import specifier (already joined to its importer's directory) can resolve to. */
|
|
32
|
+
function importCandidates(base: string): string[] {
|
|
33
|
+
return /\.js$/.test(base)
|
|
34
|
+
// A real .js file wins over a same-named .ts source (the actual resolution order).
|
|
35
|
+
? [base, base.replace(/\.js$/, '.ts'), base.replace(/\.js$/, '.tsx'), `${base.slice(0, -3)}/index.ts`, `${base.slice(0, -3)}/index.tsx`, `${base.slice(0, -3)}/index.js`]
|
|
36
|
+
: /\.tsx?$/.test(base) ? [base] : [base + '.ts', base + '.tsx', base + '.js', base + '/index.ts', base + '/index.tsx', base + '/index.js'];
|
|
37
|
+
}
|
|
38
|
+
|
|
27
39
|
/** PWA source entrypoints and the transitive relative imports they resolve inside repository src/. */
|
|
28
40
|
export function pwaReachableSrcFiles(cwd: string, { readFile = (path) => readFileSync(path, 'utf8'), listFiles = sourceFiles }: GraphFiles = {}): Set<string> {
|
|
29
41
|
const root = resolve(cwd);
|
|
@@ -33,7 +45,6 @@ export function pwaReachableSrcFiles(cwd: string, { readFile = (path) => readFil
|
|
|
33
45
|
// Start from everything apps/pwa/tsconfig.json `include`s — its `src/**/*.ts(x)` also matches *.test.* files, and the Next
|
|
34
46
|
// build type-checks them. Excluding tests hid the real entry (tool-result-chain.test.ts → src/nexus/api/meta-api → most of src).
|
|
35
47
|
const queue = [...available].filter((file) => /^apps\/pwa\/src\/.*\.tsx?$/.test(file));
|
|
36
|
-
const imports = /\b(?:import|export)\s+(?:[^;'"]*?\s+from\s*)?['"](\.[^'"]+)['"]|\bimport\s*\(\s*['"](\.[^'"]+)['"]\s*\)/g;
|
|
37
48
|
while (queue.length) {
|
|
38
49
|
const file = queue.pop()!;
|
|
39
50
|
if (visited.has(file)) continue;
|
|
@@ -42,16 +53,13 @@ export function pwaReachableSrcFiles(cwd: string, { readFile = (path) => readFil
|
|
|
42
53
|
let content: string;
|
|
43
54
|
try { content = readFile(join(root, file)); }
|
|
44
55
|
catch { continue; }
|
|
45
|
-
for (const match of content.matchAll(
|
|
56
|
+
for (const match of content.matchAll(IMPORT_SPECIFIER)) {
|
|
46
57
|
const specifier = match[1] ?? match[2];
|
|
47
58
|
if (!specifier) continue;
|
|
48
59
|
const target = resolve(root, dirname(file), specifier);
|
|
49
60
|
const base = relative(root, target).split(sep).join('/');
|
|
50
61
|
if (!base.startsWith('src/')) continue;
|
|
51
|
-
const candidates =
|
|
52
|
-
// A real .js file wins over a same-named .ts source (the actual resolution order).
|
|
53
|
-
? [base, base.replace(/\.js$/, '.ts'), base.replace(/\.js$/, '.tsx'), `${base.slice(0, -3)}/index.ts`, `${base.slice(0, -3)}/index.tsx`, `${base.slice(0, -3)}/index.js`]
|
|
54
|
-
: /\.tsx?$/.test(base) ? [base] : [base + '.ts', base + '.tsx', base + '.js', base + '/index.ts', base + '/index.tsx', base + '/index.js'];
|
|
62
|
+
const candidates = importCandidates(base);
|
|
55
63
|
const resolved = candidates.find((candidate) => available.has(candidate));
|
|
56
64
|
if (resolved) {
|
|
57
65
|
if (!visited.has(resolved)) queue.push(resolved);
|
|
@@ -63,3 +71,182 @@ export function pwaReachableSrcFiles(cwd: string, { readFile = (path) => readFil
|
|
|
63
71
|
}
|
|
64
72
|
return reached;
|
|
65
73
|
}
|
|
74
|
+
|
|
75
|
+
export type AffectedRoots = { roots: Set<string>; failure?: undefined } | { roots?: undefined; failure: string };
|
|
76
|
+
|
|
77
|
+
function astImportSpecifiers(source: ts.SourceFile): { imports: string[]; ignoredDynamic: number; failure?: string } {
|
|
78
|
+
const parseError = (source as ts.SourceFile & { parseDiagnostics?: readonly ts.Diagnostic[] }).parseDiagnostics?.[0];
|
|
79
|
+
if (parseError) return { imports: [], ignoredDynamic: 0, failure: `${source.fileName} AST 파싱 실패: ${ts.flattenDiagnosticMessageText(parseError.messageText, ' ')}` };
|
|
80
|
+
const imports: string[] = [];
|
|
81
|
+
let ignoredDynamic = 0;
|
|
82
|
+
const literal = (node: ts.Node | undefined): string | undefined => node && (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) ? node.text : undefined;
|
|
83
|
+
const visit = (node: ts.Node): void => {
|
|
84
|
+
if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {
|
|
85
|
+
const specifier = literal(node.moduleSpecifier);
|
|
86
|
+
if (specifier) imports.push(specifier);
|
|
87
|
+
} else if (ts.isImportEqualsDeclaration(node) && ts.isExternalModuleReference(node.moduleReference)) {
|
|
88
|
+
const specifier = literal(node.moduleReference.expression);
|
|
89
|
+
if (specifier) imports.push(specifier);
|
|
90
|
+
} else if (ts.isImportTypeNode(node) && ts.isLiteralTypeNode(node.argument)) {
|
|
91
|
+
const specifier = literal(node.argument.literal);
|
|
92
|
+
if (specifier) imports.push(specifier);
|
|
93
|
+
} else if (ts.isCallExpression(node) && (node.expression.kind === ts.SyntaxKind.ImportKeyword
|
|
94
|
+
|| (ts.isIdentifier(node.expression) && node.expression.text === 'require'))) {
|
|
95
|
+
const specifier = literal(node.arguments[0]);
|
|
96
|
+
if (specifier) imports.push(specifier);
|
|
97
|
+
else ignoredDynamic += 1;
|
|
98
|
+
}
|
|
99
|
+
ts.forEachChild(node, visit);
|
|
100
|
+
};
|
|
101
|
+
visit(source);
|
|
102
|
+
return { imports, ignoredDynamic };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function reExportSpecifiers(source: ts.SourceFile): string[] {
|
|
106
|
+
const importedLocals = new Map<string, string>();
|
|
107
|
+
for (const statement of source.statements) {
|
|
108
|
+
if (!ts.isImportDeclaration(statement) || !ts.isStringLiteral(statement.moduleSpecifier)) continue;
|
|
109
|
+
const from = statement.moduleSpecifier.text;
|
|
110
|
+
const clause = statement.importClause;
|
|
111
|
+
if (clause?.name) importedLocals.set(clause.name.text, from);
|
|
112
|
+
const bindings = clause?.namedBindings;
|
|
113
|
+
if (bindings && ts.isNamespaceImport(bindings)) importedLocals.set(bindings.name.text, from);
|
|
114
|
+
if (bindings && ts.isNamedImports(bindings)) {
|
|
115
|
+
for (const element of bindings.elements) importedLocals.set(element.name.text, from);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const specifiers: string[] = [];
|
|
119
|
+
for (const statement of source.statements) {
|
|
120
|
+
if (ts.isExportDeclaration(statement)) {
|
|
121
|
+
if (statement.moduleSpecifier && ts.isStringLiteral(statement.moduleSpecifier)) specifiers.push(statement.moduleSpecifier.text);
|
|
122
|
+
else if (statement.exportClause && ts.isNamedExports(statement.exportClause)) {
|
|
123
|
+
for (const element of statement.exportClause.elements) {
|
|
124
|
+
const from = importedLocals.get((element.propertyName ?? element.name).text);
|
|
125
|
+
if (from) specifiers.push(from);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
} else if (ts.isExportAssignment(statement) && ts.isIdentifier(statement.expression)) {
|
|
129
|
+
const from = importedLocals.get(statement.expression.text);
|
|
130
|
+
if (from) specifiers.push(from);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return specifiers;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** Declarations visible without an import edge must enter every scoped program. */
|
|
137
|
+
function suppliesAmbientTypes(source: ts.SourceFile): boolean {
|
|
138
|
+
if (source.fileName.endsWith('.d.ts') || !ts.isExternalModule(source)) return true;
|
|
139
|
+
const visit = (node: ts.Node): boolean => {
|
|
140
|
+
if (ts.isModuleDeclaration(node) && (node.name.text === 'global' || ts.isStringLiteral(node.name))) return true;
|
|
141
|
+
return ts.forEachChild(node, visit) ?? false;
|
|
142
|
+
};
|
|
143
|
+
return visit(source);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function gateTypeScriptSources(cwd: string): string[] {
|
|
147
|
+
const files: string[] = [];
|
|
148
|
+
const walk = (dir: string): void => {
|
|
149
|
+
// A partial directory walk is not a valid affected-root measurement: an
|
|
150
|
+
// unreadable subtree may contain the only importer of a changed file.
|
|
151
|
+
const entries = readdirSync(join(cwd, dir), { withFileTypes: true });
|
|
152
|
+
for (const entry of entries) {
|
|
153
|
+
const path = `${dir}/${entry.name}`;
|
|
154
|
+
if (entry.isDirectory() && entry.name !== 'node_modules' && !entry.name.startsWith('.')) walk(path);
|
|
155
|
+
else if (entry.isFile() && /\.ts$/.test(path)) files.push(path);
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
for (const root of ['src', 'scripts', 'test']) {
|
|
159
|
+
// An optional include glob may match no directory in a fixture. Only a
|
|
160
|
+
// confirmed ENOENT is empty; permission/I/O errors must fail closed.
|
|
161
|
+
try { statSync(join(cwd, root)); }
|
|
162
|
+
catch (cause) {
|
|
163
|
+
if ((cause as NodeJS.ErrnoException).code === 'ENOENT') continue;
|
|
164
|
+
throw cause;
|
|
165
|
+
}
|
|
166
|
+
walk(root);
|
|
167
|
+
}
|
|
168
|
+
return files;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Changed .ts files plus the listed files that import one of them directly (one reverse-import step).
|
|
173
|
+
* Every changed file and every listed file must be readable — an unreadable file could be a hidden importer, so the
|
|
174
|
+
* result is a failure the caller turns into a full-program run, never a smaller root set.
|
|
175
|
+
*/
|
|
176
|
+
export function reverseImportAffectedRoots(cwd: string, changed: ReadonlySet<string>, { readFile = (path) => readFileSync(path, 'utf8'), listFiles = gateTypeScriptSources }: GraphFiles = {}): AffectedRoots {
|
|
177
|
+
const root = resolve(cwd);
|
|
178
|
+
const normalize = (file: string): string => file.replaceAll('\\', '/').replace(/^\.\//, '');
|
|
179
|
+
const read = (file: string): string | { failure: string } => {
|
|
180
|
+
try { return readFile(join(root, file)); }
|
|
181
|
+
catch (cause) { return { failure: `${file} 을 읽지 못했다: ${cause instanceof Error ? cause.message : String(cause)}` }; }
|
|
182
|
+
};
|
|
183
|
+
let listed: string[];
|
|
184
|
+
try { listed = listFiles(cwd).map(normalize); }
|
|
185
|
+
catch (cause) { return { failure: `소스 목록을 읽지 못했다: ${cause instanceof Error ? cause.message : String(cause)}` }; }
|
|
186
|
+
const available = new Set(listed);
|
|
187
|
+
const targets = new Set([...changed].map(normalize));
|
|
188
|
+
for (const file of targets) {
|
|
189
|
+
const content = read(file);
|
|
190
|
+
if (typeof content !== 'string') return content;
|
|
191
|
+
}
|
|
192
|
+
const importsByFile = new Map<string, Set<string>>();
|
|
193
|
+
const barrelsByTarget = new Map<string, Set<string>>();
|
|
194
|
+
const ambientRoots = new Set<string>();
|
|
195
|
+
let ignoredDynamic = 0;
|
|
196
|
+
const resolveImport = (file: string, specifier: string): { target?: string; ignored?: true; unresolved?: true } => {
|
|
197
|
+
if (!specifier.startsWith('.')) return { ignored: true };
|
|
198
|
+
const base = relative(root, resolve(root, dirname(file), specifier)).split(sep).join('/');
|
|
199
|
+
// The gate's tsconfig includes these roots. A relative import outside them
|
|
200
|
+
// cannot lead back to a changed gate source; asset imports are not TS
|
|
201
|
+
// source edges either.
|
|
202
|
+
if (!/^(?:src|scripts|test)\//.test(base) || /\.(?:css|json|svg|png|jpg|jpeg|webp|wasm)$/.test(base)) return { ignored: true };
|
|
203
|
+
const target = importCandidates(base).find((candidate) => available.has(candidate));
|
|
204
|
+
return target ? { target } : { unresolved: true };
|
|
205
|
+
};
|
|
206
|
+
for (const file of listed) {
|
|
207
|
+
const content = read(file);
|
|
208
|
+
if (typeof content !== 'string') return content;
|
|
209
|
+
let source: ts.SourceFile;
|
|
210
|
+
try { source = ts.createSourceFile(file, content, ts.ScriptTarget.Latest, true); }
|
|
211
|
+
catch (cause) { return { failure: `${file} AST 파싱 실패: ${cause instanceof Error ? cause.message : String(cause)}` }; }
|
|
212
|
+
const scanned = astImportSpecifiers(source);
|
|
213
|
+
if (scanned.failure) return { failure: scanned.failure };
|
|
214
|
+
if (suppliesAmbientTypes(source)) ambientRoots.add(file);
|
|
215
|
+
ignoredDynamic += scanned.ignoredDynamic;
|
|
216
|
+
const imports = new Set<string>();
|
|
217
|
+
for (const specifier of scanned.imports) {
|
|
218
|
+
if (!specifier.startsWith('.')) continue;
|
|
219
|
+
const resolved = resolveImport(file, specifier);
|
|
220
|
+
if (resolved.unresolved) return { failure: `${file} 의 리터럴 import ${specifier} 해석 실패` };
|
|
221
|
+
if (resolved.target) imports.add(resolved.target);
|
|
222
|
+
}
|
|
223
|
+
importsByFile.set(file, imports);
|
|
224
|
+
for (const specifier of reExportSpecifiers(source)) {
|
|
225
|
+
const resolved = resolveImport(file, specifier);
|
|
226
|
+
if (resolved.unresolved) return { failure: `${file} 의 리터럴 re-export ${specifier} 해석 실패` };
|
|
227
|
+
if (!resolved.target) continue;
|
|
228
|
+
const barrels = barrelsByTarget.get(resolved.target) ?? new Set<string>();
|
|
229
|
+
barrels.add(file);
|
|
230
|
+
barrelsByTarget.set(resolved.target, barrels);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (ignoredDynamic) debug.log('typecheck.gate', 'nonliteral-import-ignored', { count: ignoredDynamic });
|
|
234
|
+
// A changed export can break an importer through any number of re-export
|
|
235
|
+
// barrels. Walk that chain to a fixed point, then include direct importers
|
|
236
|
+
// of each barrel. The visited set also terminates circular barrels.
|
|
237
|
+
const exported = new Set(targets);
|
|
238
|
+
const queue = [...targets];
|
|
239
|
+
while (queue.length) {
|
|
240
|
+
const target = queue.pop()!;
|
|
241
|
+
for (const barrel of barrelsByTarget.get(target) ?? []) {
|
|
242
|
+
if (exported.has(barrel)) continue;
|
|
243
|
+
exported.add(barrel);
|
|
244
|
+
queue.push(barrel);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
const roots = new Set([...exported, ...ambientRoots]);
|
|
248
|
+
for (const [file, imports] of importsByFile) {
|
|
249
|
+
if ([...imports].some((target) => exported.has(target))) roots.add(file);
|
|
250
|
+
}
|
|
251
|
+
return { roots };
|
|
252
|
+
}
|