@qwen-code/qwen-code 0.24.2-nightly.20260920.eceaede18e → 0.24.3
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/README.md +4 -0
- package/bundled/qc-helper/docs/configuration/settings.md +1 -1
- package/bundled/qc-helper/docs/features/channels/overview.md +1 -1
- package/bundled/qc-helper/docs/features/code-review.md +3 -1
- package/bundled/qc-helper/docs/qwen-serve.md +1 -1
- package/bundled/qc-helper/docs/support/tos-privacy.md +29 -1
- package/bundled/review/SKILL.md +8 -7
- package/chunks/{MaxSizedBox-RPKJTMSO.js → MaxSizedBox-PVOJQQE2.js} +56 -49
- package/chunks/{StandaloneSessionPicker-JJWVOU4L.js → StandaloneSessionPicker-RFTENTTJ.js} +74 -67
- package/chunks/{acp-subagent-executor-ZGHG2RMM.js → acp-subagent-executor-TQP6HLTE.js} +59 -52
- package/chunks/{acpAgent-WVCBVDBH.js → acpAgent-MHLAESGM.js} +203 -162
- package/chunks/{agent-FX7VEI4J.js → agent-XFGNPR4N.js} +38 -32
- package/chunks/{agent-headless-PK5GSC2O.js → agent-headless-HXOWC5DL.js} +38 -32
- package/chunks/{anthropicContentGenerator-UQH36DCN.js → anthropicContentGenerator-J22BAFBQ.js} +3 -3
- package/chunks/{artifact-tool-3B3YPLNI.js → artifact-tool-WR4WGBUS.js} +3 -2
- package/chunks/{askUserQuestion-YIK445UI.js → askUserQuestion-X4DR32XO.js} +3 -2
- package/chunks/{bridge-2TNSJGPK.js → bridge-GHWETITW.js} +59 -52
- package/chunks/bwrap-execution-LSZQILPP.js +34 -0
- package/chunks/{caption-audio-V6S7IOLZ.js → caption-audio-MORSEOKW.js} +5 -4
- package/chunks/{caption-image-LKRZR2BO.js → caption-image-XBQMQEWA.js} +5 -4
- package/chunks/{channel-management-service-B5JCH6G4.js → channel-management-service-DISO7Z3P.js} +2 -2
- package/chunks/{channel-settings-store-5I5ZIKGL.js → channel-settings-store-7BHSX2TC.js} +63 -56
- package/chunks/{channel-worker-group-M4MSCXVZ.js → channel-worker-group-EJEMLDPE.js} +5 -5
- package/chunks/{channel-worker-manager-UEAF66Y2.js → channel-worker-manager-GI3GMPHV.js} +5 -5
- package/chunks/{channel-worker-supervisor-KNSB6NQS.js → channel-worker-supervisor-GGTS6MM5.js} +4 -4
- package/chunks/{chunk-NEBGGUXA.js → chunk-24TLKGI4.js} +21 -19
- package/chunks/{chunk-MOWCV77B.js → chunk-2FZL7GEG.js} +1 -1
- package/chunks/{chunk-NOFTRBSY.js → chunk-2PZPYVGY.js} +61 -53
- package/chunks/chunk-2SENA3WV.js +2808 -0
- package/chunks/{chunk-WLEIIPES.js → chunk-33E234BQ.js} +2 -2
- package/chunks/{chunk-KGV3GKXW.js → chunk-3QXU5BXM.js} +6 -6
- package/chunks/{chunk-MR5FRME7.js → chunk-3RXCA7OA.js} +2 -2
- package/chunks/{chunk-ZUCNQFKN.js → chunk-4BKX4QZQ.js} +5 -5
- package/chunks/chunk-4M7RD5QQ.js +58 -0
- package/chunks/{chunk-DQAVDSA6.js → chunk-4TXKQWKL.js} +1 -1
- package/chunks/{chunk-LZJ52GXR.js → chunk-52TZ7P6X.js} +4 -4
- package/chunks/{chunk-JU5DOXQM.js → chunk-52YTEDEN.js} +1 -1
- package/chunks/{chunk-FIFG7A6M.js → chunk-5AMF3QJJ.js} +58 -32
- package/chunks/{chunk-QEPQKAUY.js → chunk-5E4BPDCX.js} +1 -1
- package/chunks/{chunk-Q7RY6UGQ.js → chunk-5GYRIOWK.js} +1 -1
- package/chunks/{chunk-RGKAK4PM.js → chunk-5HNRXVPC.js} +4 -4
- package/chunks/chunk-5R36APDE.js +70 -0
- package/chunks/{chunk-JUS63SDR.js → chunk-5VNH3GBD.js} +35 -5
- package/chunks/{chunk-TPDNW6O5.js → chunk-5XEZQQG3.js} +0 -8
- package/chunks/{chunk-TCFJID32.js → chunk-64T2EGVQ.js} +3 -3
- package/chunks/{chunk-3J43HE2J.js → chunk-6GI7NAZS.js} +1 -1
- package/chunks/{chunk-3BYQK4PV.js → chunk-6LXGKCPH.js} +2 -2
- package/chunks/{chunk-2MCP5CGP.js → chunk-6XGXRH2Q.js} +1 -1
- package/chunks/{chunk-EW2DALIG.js → chunk-73R6BAOK.js} +1 -1
- package/chunks/{chunk-XKLR5DV6.js → chunk-7GHC7XR7.js} +4 -4
- package/chunks/{chunk-OR6U6GEV.js → chunk-7HI22VYF.js} +1 -1
- package/chunks/{chunk-U5JK32FE.js → chunk-7JDVJX7A.js} +28 -5857
- package/chunks/{chunk-7YWYCOYQ.js → chunk-A5UPWU53.js} +2 -2
- package/chunks/{chunk-WREWSJDW.js → chunk-A5XFEBME.js} +3 -3
- package/chunks/{chunk-JG23BJ7Y.js → chunk-AJSG5SMC.js} +2 -2
- package/chunks/{chunk-3D5YPGYQ.js → chunk-AJTDW2YD.js} +6 -6
- package/chunks/{chunk-DE3XOM2J.js → chunk-AOYY54ZY.js} +1 -1
- package/chunks/{chunk-E6UTJIPI.js → chunk-ATZ4RQ6I.js} +1 -1
- package/chunks/{chunk-EG3OSBTA.js → chunk-AV3FOXNF.js} +1 -1
- package/chunks/{chunk-BBZYS2P7.js → chunk-B3UM2NWK.js} +1 -1
- package/chunks/{chunk-TJUFQF5I.js → chunk-BC2TGXIK.js} +2 -2
- package/chunks/{chunk-T4D3QLUZ.js → chunk-BHU5SD32.js} +1 -1
- package/chunks/{chunk-INOZDWT7.js → chunk-BTDQWQE7.js} +3 -3
- package/chunks/{chunk-42QJ7NLB.js → chunk-BVNEEYJM.js} +4 -55
- package/chunks/{chunk-XXXA63AB.js → chunk-CEG3V62N.js} +1 -1
- package/chunks/{chunk-2STEZJOP.js → chunk-CGIKEQFI.js} +6 -6
- package/chunks/{chunk-65I7S4Z3.js → chunk-CHBZHMBA.js} +2 -35
- package/chunks/{chunk-5YBKCD66.js → chunk-CJ2NHFIU.js} +8 -8
- package/chunks/{chunk-M64HFJ3A.js → chunk-D42TSQKU.js} +1 -1
- package/chunks/{chunk-NRWMNRBC.js → chunk-D4K23BD4.js} +1 -1
- package/chunks/{chunk-6TTVHPUO.js → chunk-DACSVV23.js} +1 -1
- package/chunks/{chunk-UEXMPRI2.js → chunk-DBYIRDFG.js} +4 -4
- package/chunks/{chunk-7PESUTO2.js → chunk-DEY4A6ZJ.js} +1 -1
- package/chunks/{chunk-ES2Y3FEA.js → chunk-EJUVYCCB.js} +1 -1
- package/chunks/chunk-ELYIK7SN.js +47 -0
- package/chunks/{chunk-SNRUMQB6.js → chunk-EPBR5TO4.js} +2 -2
- package/chunks/{chunk-UKK3BCPV.js → chunk-EVNJAS37.js} +10 -7
- package/chunks/{chunk-OYZPJG3W.js → chunk-F2VBZ6LC.js} +4 -4
- package/chunks/{chunk-B24DTVKI.js → chunk-F3JJ5TAQ.js} +9 -7
- package/chunks/{chunk-CK267TVO.js → chunk-FPFIAK47.js} +2 -2
- package/chunks/{chunk-2VVMAC3W.js → chunk-FRC4RVRG.js} +1 -1
- package/chunks/{chunk-37YML7SK.js → chunk-FS5KMPLT.js} +1 -1
- package/chunks/{chunk-CKHUCWYE.js → chunk-FTJYHKI7.js} +1 -1
- package/chunks/{chunk-K2DKGZ7Z.js → chunk-FVACI3OI.js} +3 -3
- package/chunks/{chunk-WQ3SH63I.js → chunk-G4DQHGSF.js} +3 -3
- package/chunks/{chunk-3SQIYYDQ.js → chunk-G7CUNATW.js} +1 -1
- package/chunks/{chunk-INLMCZR4.js → chunk-GKFEDGAE.js} +2 -2
- package/chunks/{chunk-MYXULCXF.js → chunk-GNGQGEZD.js} +1 -1
- package/chunks/{chunk-R5XRSVEV.js → chunk-H5VUUFVD.js} +1 -1
- package/chunks/{chunk-RFVQJSIW.js → chunk-HDRYBFLF.js} +2 -2
- package/chunks/{chunk-W3QIIMA2.js → chunk-HZ5VA3H3.js} +5 -5
- package/chunks/{chunk-AYMFGIB4.js → chunk-HZU2DMPO.js} +12 -12
- package/chunks/{chunk-FDW5VK44.js → chunk-I3K2QRZ5.js} +1 -1
- package/chunks/{chunk-OMHE7I7L.js → chunk-IODSADQ4.js} +1 -1
- package/chunks/{chunk-ANKISCKU.js → chunk-JBUMBQAO.js} +12 -2
- package/chunks/{chunk-7MPPSFT6.js → chunk-JCTHL2AB.js} +2 -2
- package/chunks/{chunk-D5CQQYBC.js → chunk-JXNPH2EP.js} +2 -2
- package/chunks/{chunk-SA4UQS3Y.js → chunk-KEIOGBLQ.js} +1 -1
- package/chunks/{chunk-LUSRTUFX.js → chunk-KL2BAPK7.js} +2180 -594
- package/chunks/{chunk-GKKWPORM.js → chunk-KORAYUXN.js} +16 -14
- package/chunks/{chunk-7SJ6E2OM.js → chunk-KTKMSEN2.js} +5 -5
- package/chunks/{chunk-TAANUOHC.js → chunk-LFIKUSEE.js} +1 -1
- package/chunks/{chunk-F5QRYAIR.js → chunk-LWQKWO5I.js} +1710 -3754
- package/chunks/{chunk-YYZ2OPLH.js → chunk-MHDXEHU5.js} +1 -1
- package/chunks/{chunk-MFKZWV2C.js → chunk-MJY6NCQF.js} +19 -17
- package/chunks/{chunk-DYGOUAKK.js → chunk-MNM5AZTY.js} +1 -1
- package/chunks/{chunk-GWZMA542.js → chunk-MSX7BUUO.js} +2 -2
- package/chunks/{chunk-REXIMUUM.js → chunk-N6APTOMX.js} +1 -1
- package/chunks/{chunk-D2YL5NNA.js → chunk-NAH3EHAD.js} +4 -4
- package/chunks/{chunk-INAOJPGP.js → chunk-NBAZASOT.js} +16 -16
- package/chunks/{chunk-5DLIBYWE.js → chunk-NL5EDW4G.js} +3 -3
- package/chunks/{chunk-CXSUL6I6.js → chunk-NOTDB3KX.js} +34 -21
- package/chunks/{chunk-SYMSPEVW.js → chunk-NSQYCACH.js} +2 -2
- package/chunks/chunk-NXRQI7RF.js +5861 -0
- package/chunks/{chunk-BFRE6C2T.js → chunk-O4OOA2XB.js} +4 -4
- package/chunks/{chunk-CALTYCK3.js → chunk-ONVXBTN3.js} +4 -4
- package/chunks/{chunk-LL3WR3KQ.js → chunk-OOBJCVOC.js} +11 -11
- package/chunks/{chunk-BDUAP5PL.js → chunk-OOGQBSTQ.js} +99 -55
- package/chunks/{chunk-LRY6H2UX.js → chunk-OTKB5NBZ.js} +8 -8
- package/chunks/{chunk-TDWH5KJE.js → chunk-OU26ZZOL.js} +1 -1
- package/chunks/{chunk-5YJEHFWB.js → chunk-OUKL6WIM.js} +2 -2
- package/chunks/{chunk-YSUL7CDZ.js → chunk-PI3663GU.js} +3 -3
- package/chunks/{chunk-E5JQUFYU.js → chunk-PPLSJANE.js} +2 -2
- package/chunks/{chunk-KUYUYZX5.js → chunk-PYFGVKPR.js} +2 -2
- package/chunks/{chunk-XHUNBYDE.js → chunk-Q2TJZRNE.js} +2 -2
- package/chunks/{chunk-OKD67U3D.js → chunk-QQSN6DYY.js} +2 -2
- package/chunks/{chunk-6QCC55HM.js → chunk-SCCA4KIA.js} +8 -8
- package/chunks/{chunk-JVF74JD5.js → chunk-T4EEDGIV.js} +8 -8
- package/chunks/{chunk-OTGK5C6F.js → chunk-TEFMMDNL.js} +11 -11
- package/chunks/{chunk-BCZUD33S.js → chunk-TK5X3N6Z.js} +1 -1
- package/chunks/{chunk-DQXGEF2O.js → chunk-TNANUFVW.js} +33 -27
- package/chunks/{chunk-MXOOWEZK.js → chunk-TTAC3FUB.js} +1 -1
- package/chunks/{chunk-IKZUMUHV.js → chunk-TULCOWNT.js} +8 -8
- package/chunks/{chunk-BJEZBTUO.js → chunk-TUYJ6S3L.js} +1 -1
- package/chunks/{chunk-A27BXP6Y.js → chunk-TW7KLLRI.js} +46 -21
- package/chunks/{chunk-AK35QRVW.js → chunk-U5P7R5TF.js} +2 -2
- package/chunks/{chunk-PGYKW4PY.js → chunk-UI5A24EA.js} +1 -1
- package/chunks/{chunk-RBRYQJVR.js → chunk-URFKH5UA.js} +50 -29
- package/chunks/{chunk-OKGR3ZEF.js → chunk-UYW4ZR6P.js} +5 -5
- package/chunks/{chunk-FOVMGIL4.js → chunk-V4VSJQKD.js} +2 -2
- package/chunks/{chunk-3CL7ZDMT.js → chunk-VBEEYWD5.js} +3 -3
- package/chunks/{chunk-J7M66DXO.js → chunk-VD66W3RA.js} +3 -3
- package/chunks/{chunk-5XWVWTLB.js → chunk-VM3RQNIN.js} +2 -2
- package/chunks/{chunk-HYLPVFWL.js → chunk-VT3MGD7H.js} +1 -1
- package/chunks/{chunk-JYTZDB56.js → chunk-VZ6YDHDV.js} +1 -1
- package/chunks/{chunk-BIQXRY5B.js → chunk-W4T4DHDJ.js} +86 -5
- package/chunks/{chunk-DH73F6SW.js → chunk-WJ4NNSW7.js} +6 -6
- package/chunks/{chunk-GFEGVB2H.js → chunk-WJ6HMAU7.js} +3 -3
- package/chunks/{chunk-KVMLTZTU.js → chunk-WK5KFFP6.js} +1 -1
- package/chunks/{chunk-MOTCWW3N.js → chunk-WMHO25KU.js} +2 -2
- package/chunks/{chunk-TBVO3WMD.js → chunk-WQ7QSGFJ.js} +1 -1
- package/chunks/{chunk-4ZYD4QI5.js → chunk-WXHBA2D3.js} +1 -1
- package/chunks/{chunk-AQQIJ6ML.js → chunk-X4ILFHRH.js} +1 -1
- package/chunks/{chunk-SNYM2GZV.js → chunk-XLN46XQ2.js} +11 -11
- package/chunks/{chunk-CXXHL3XJ.js → chunk-XPXMRRG3.js} +1 -1
- package/chunks/{chunk-T5VJRBGJ.js → chunk-Y62EC3SO.js} +7 -7
- package/chunks/{chunk-S564PKIP.js → chunk-YAQ6GGRB.js} +1 -1
- package/chunks/{chunk-QHRGNK26.js → chunk-YDX2EK5J.js} +4 -4
- package/chunks/{chunk-UONYP6TM.js → chunk-YIVRT5RA.js} +1 -1
- package/chunks/chunk-YPKYQHFS.js +25 -0
- package/chunks/{chunk-W3N7NLN2.js → chunk-YWRTS5OJ.js} +3 -3
- package/chunks/{chunk-WWQGEPFA.js → chunk-YYNQG3JO.js} +1 -1
- package/chunks/{chunk-VTKMLJBN.js → chunk-Z6Y6SFX7.js} +1 -1
- package/chunks/chunk-ZWMLPCLV.js +168 -0
- package/chunks/{clip-audio-OL5ZHBOH.js → clip-audio-4GTC7XXJ.js} +3 -2
- package/chunks/{clip-image-GKDHKWSA.js → clip-image-CVP6R7WG.js} +3 -2
- package/chunks/{clip-video-OE4GBBS2.js → clip-video-RMIOCVAT.js} +3 -2
- package/chunks/{codex-subagent-executor-CGICTSU2.js → codex-subagent-executor-JQPB5UH6.js} +61 -54
- package/chunks/{config-utils-RIQGWIFI.js → config-utils-3PL3OQOI.js} +57 -50
- package/chunks/{container-execution-environment-XS6X47MH.js → container-execution-environment-RPXKL3HT.js} +9 -0
- package/chunks/{contextCommand-JWP7XI4S.js → contextCommand-Z6ZTWN7F.js} +57 -50
- package/chunks/{convert-image-JT75DK5E.js → convert-image-24SLHDCH.js} +3 -2
- package/chunks/{core-runtime-TZ543CAV.js → core-runtime-5KHWEMVQ.js} +55 -48
- package/chunks/{create-sub-session-MNPEQ4J2.js → create-sub-session-3RVVDCXG.js} +3 -2
- package/chunks/{create-sub-session-F5JY7FAS.js → create-sub-session-FB5YJFI5.js} +56 -49
- package/chunks/{cron-create-RHRWMLNX.js → cron-create-NXQ27MQQ.js} +2 -1
- package/chunks/{cron-delete-CTZBKOT2.js → cron-delete-2F75IAB5.js} +2 -1
- package/chunks/{cron-list-SGNRBA52.js → cron-list-7IEDSU4D.js} +2 -1
- package/chunks/{daemon-BPTR7VCR.js → daemon-25CH5S3X.js} +4 -1
- package/chunks/{daemon-git-worktree-guard-3MZT6TKC.js → daemon-git-worktree-guard-LQ3XGSBU.js} +57 -50
- package/chunks/{daemon-status-provider-I2P667AW.js → daemon-status-provider-PCJP7L7Z.js} +64 -57
- package/chunks/{daemon-trust-policy-BSYFPYI2.js → daemon-trust-policy-KXZY6JQN.js} +61 -54
- package/chunks/{daemon-trust-policy-monitor-5DIISOLI.js → daemon-trust-policy-monitor-QAZ4KXVK.js} +61 -54
- package/chunks/{deferred-core-runtime-4S3CQTNI.js → deferred-core-runtime-UCXREDYD.js} +55 -48
- package/chunks/{display-image-XBM4DXNT.js → display-image-WYMDGOWV.js} +3 -2
- package/chunks/{downsample-audio-ZVH75DNJ.js → downsample-audio-T5P5IEPZ.js} +3 -2
- package/chunks/{downsample-image-4D6XYIRR.js → downsample-image-6L67FEII.js} +3 -2
- package/chunks/{downscale-video-CPSH7IDV.js → downscale-video-RYVKNSAU.js} +3 -2
- package/chunks/{edit-4IEI5P3G.js → edit-VPPFWFX7.js} +40 -33
- package/chunks/{enter-worktree-4TWVSLRD.js → enter-worktree-UF4HQH7B.js} +7 -5
- package/chunks/{enterPlanMode-CROB26VM.js → enterPlanMode-6TDM4B6A.js} +38 -32
- package/chunks/{environment-DNXWCPTQ.js → environment-FXLJ7ENW.js} +57 -50
- package/chunks/{errors-PWOY7YFG.js → errors-S6CL7DPU.js} +57 -50
- package/chunks/{exec-YFYZG5FI.js → exec-G6SFU4KT.js} +2 -1
- package/chunks/{execution-tool-X34J6HBS.js → execution-tool-5OEN4XN4.js} +41 -34
- package/chunks/{execution-worker-OSXEA473.js → execution-worker-SNHQA7RC.js} +49 -42
- package/chunks/{exit-worktree-X5TWEER7.js → exit-worktree-KGKIHZF7.js} +7 -5
- package/chunks/{exitPlanMode-OXR5JZTZ.js → exitPlanMode-ZCPQQO2Q.js} +38 -32
- package/chunks/{extract-audio-WMI3JVZW.js → extract-audio-5YD7BSS3.js} +3 -2
- package/chunks/{extract-keyframes-XWYFKXJY.js → extract-keyframes-6SMSQOK5.js} +3 -2
- package/chunks/{fast-path-TT4F42BI.js → fast-path-VTQRLIDS.js} +6 -6
- package/chunks/{fast-path-settings-TLOSL5ML.js → fast-path-settings-4BKAJEUA.js} +3 -2
- package/chunks/{glob-QX7OC2CG.js → glob-WUNZEBU7.js} +39 -33
- package/chunks/{goal-tools-D43E7SJP.js → goal-tools-FWW63AA2.js} +38 -32
- package/chunks/{grep-AXABIEJD.js → grep-AIFXREQI.js} +4 -3
- package/chunks/{handleAutoUpdate-ZLV26LZU.js → handleAutoUpdate-H5X5JCSF.js} +58 -51
- package/chunks/{i18n-XB2KCRPE.js → i18n-BRMNE6B6.js} +56 -49
- package/chunks/{image-gen-JK7PLS5E.js → image-gen-F4QUJLNV.js} +2 -1
- package/chunks/{initializer-Q64NYQ22.js → initializer-ZUO7ORBA.js} +61 -54
- package/chunks/{installationInfo-7XQMMKEP.js → installationInfo-DTMVU7BI.js} +55 -48
- package/chunks/{list-JW5KDV23.js → list-EEGHEIRM.js} +64 -57
- package/chunks/{list-agents-6EQJPTZS.js → list-agents-QYEGD7BM.js} +2 -1
- package/chunks/{llm-SJHEVAEC.js → llm-5E4HK3VQ.js} +144 -118
- package/chunks/{llm-content-generator-F2XDQRIR.js → llm-content-generator-Z772NKES.js} +3 -3
- package/chunks/{loadedSettingsAdapter-KUYCWJTG.js → loadedSettingsAdapter-BCWAHAEI.js} +61 -54
- package/chunks/{local-execution-environment-JGUKY3V2.js → local-execution-environment-W6LZ7CUB.js} +49 -42
- package/chunks/{loggingContentGenerator-ZX7ZDLVS.js → loggingContentGenerator-OOHXYIMS.js} +40 -34
- package/chunks/{loop-wakeup-RF3XTGKT.js → loop-wakeup-76JNT4WU.js} +2 -1
- package/chunks/{ls-FDTLJBRV.js → ls-D7KTHDNN.js} +3 -2
- package/chunks/{lsp-DFJWXIPB.js → lsp-6UUCOSFX.js} +2 -1
- package/chunks/{managed-npm-update-USE35QXP.js → managed-npm-update-TDTR2CXP.js} +55 -48
- package/chunks/{mcp-VA6VU2R6.js → mcp-H7KOGB3R.js} +61 -54
- package/chunks/{model-call-collection-7UF4SHX3.js → model-call-collection-6XWFC7TH.js} +4 -3
- package/chunks/{model-configuration-IHYJASLW.js → model-configuration-LQV2CJZZ.js} +61 -54
- package/chunks/{modelConfigUtils-JDZGRJSS.js → modelConfigUtils-3MJ6OTIS.js} +56 -49
- package/chunks/{monitor-IWNEM673.js → monitor-SXFWYHEN.js} +147 -80
- package/chunks/{nonInteractiveCli-QP6KVMKR.js → nonInteractiveCli-JUWSNYL2.js} +100 -93
- package/chunks/{nonInteractiveToolExecutor-FPQU72UW.js → nonInteractiveToolExecutor-3M2TJ5RN.js} +39 -33
- package/chunks/{notebook-edit-NBOXSYAB.js → notebook-edit-BSQYYXUQ.js} +39 -33
- package/chunks/{ocr-image-2PSF2IAR.js → ocr-image-5S3CK7CF.js} +5 -4
- package/chunks/{omni-3FFUFXRI.js → omni-VT3TTIHP.js} +13 -12
- package/chunks/{openaiContentGenerator-MP5MUZNA.js → openaiContentGenerator-4QM3346J.js} +17 -14
- package/chunks/{openaiResponsesContentGenerator-WCC2OSDW.js → openaiResponsesContentGenerator-KNBUZDP3.js} +2 -2
- package/chunks/{pidfile-U4ZZDKJN.js → pidfile-3HRF6UJA.js} +55 -48
- package/chunks/{processUtils-GLDKNBCP.js → processUtils-V56V4PBU.js} +2 -2
- package/chunks/{prompt-terminal-ledger-V2Y2UXAT.js → prompt-terminal-ledger-WOPLWLBQ.js} +56 -49
- package/chunks/{qwenContentGenerator-DSEVNVCY.js → qwenContentGenerator-VQ7N3TOC.js} +41 -35
- package/chunks/{reactive-degrade-NUBYT2D4.js → reactive-degrade-FPODY2BC.js} +10 -9
- package/chunks/{read-file-KHTRORJE.js → read-file-GQLJ3M7Z.js} +10 -7
- package/chunks/{read-mcp-resource-B2GMAZPJ.js → read-mcp-resource-5LHGYLKO.js} +2 -1
- package/chunks/{recall-media-memory-tool-LV4MEI4V.js → recall-media-memory-tool-KJSYTPWC.js} +2 -1
- package/chunks/{record-artifact-YZC2JO6M.js → record-artifact-HBLFENQR.js} +5 -3
- package/chunks/{record-source-UD4VB654.js → record-source-R573ATSB.js} +6 -5
- package/chunks/{report-findings-3VDQHUWI.js → report-findings-KJ4TYZ36.js} +6 -4
- package/chunks/{request-shutdown-IIQL6AP6.js → request-shutdown-NO5ZWADD.js} +5 -4
- package/chunks/{resumeHistoryUtils-DK63N5ZK.js → resumeHistoryUtils-7LZ5SWKC.js} +61 -54
- package/chunks/{ripGrep-MJ62THL2.js → ripGrep-TBN4ADUY.js} +13 -10
- package/chunks/{run-qwen-serve-CZZACWCC.js → run-qwen-serve-6GXQP7DD.js} +345 -122
- package/chunks/{runtime-HU5LC3BD.js → runtime-PBC4QVLS.js} +64 -57
- package/chunks/{sandbox-BDA35KGS.js → sandbox-SXY2ZJDN.js} +63 -56
- package/chunks/{sandboxConfig-ICZ7YJLS.js → sandboxConfig-WZHAEK3H.js} +56 -49
- package/chunks/{scheduled-tasks-LCSY65QR.js → scheduled-tasks-WEC66H2D.js} +62 -55
- package/chunks/{scheduler-WOGXK3KY.js → scheduler-MPMBQKNN.js} +57 -50
- package/chunks/{sdk-exporters-http-33ZUNG6F.js → sdk-exporters-http-LOJRQMTP.js} +2 -1
- package/chunks/{sdk-impl-UDJ5SKN5.js → sdk-impl-GRYEDRD7.js} +4 -3
- package/chunks/{send-message-5VICTSBX.js → send-message-POBGHN4M.js} +5 -4
- package/chunks/{serve-JIBZCUQG.js → serve-EV4HTTAM.js} +61 -54
- package/chunks/{server-H6SKUR4R.js → server-KQJAQD55.js} +322 -189
- package/chunks/{session-SMRD5XG7.js → session-IRBWRKQX.js} +101 -94
- package/chunks/{session-attachments-root-TWN5KR7M.js → session-attachments-root-L75Y47VK.js} +55 -48
- package/chunks/{session-pr-refresh-XRWF6RT3.js → session-pr-refresh-5MHLCSC2.js} +61 -54
- package/chunks/{settings-GZCTLIZ4.js → settings-MI63DAKE.js} +60 -53
- package/chunks/{shell-W2NWMLCM.js → shell-AQVVGISM.js} +38 -32
- package/chunks/{skill-NTXYKRIW.js → skill-VBSS653C.js} +12 -9
- package/chunks/{skill-settings-54NKWE7G.js → skill-settings-MNLFQXDX.js} +61 -54
- package/chunks/{spawnChannel-B3IYZTA7.js → spawnChannel-DMP56IUE.js} +58 -51
- package/chunks/{standalone-update-4XMPXOCF.js → standalone-update-I3RV7IE7.js} +57 -50
- package/chunks/{start-opentui-ui-OFFJIY4W.js → start-opentui-ui-GJOXXN5L.js} +133 -124
- package/chunks/{startInteractiveUI-PGOVVKBW.js → startInteractiveUI-TBIQDZLE.js} +139 -131
- package/chunks/{syntheticOutput-IBR4IZUU.js → syntheticOutput-DTUQ3N3J.js} +3 -2
- package/chunks/{task-create-LTAMU773.js → task-create-2LMS6ZFJ.js} +6 -5
- package/chunks/{task-list-JROVWKLY.js → task-list-D22BRKR6.js} +2 -1
- package/chunks/{task-stop-MHQKQDFQ.js → task-stop-UZDE2G5W.js} +3 -2
- package/chunks/{task-update-RMYMZM6A.js → task-update-RHBIB6YU.js} +6 -5
- package/chunks/{team-create-NLMRMACD.js → team-create-K7QPZ6P2.js} +40 -34
- package/chunks/{team-delete-EX7BR2LA.js → team-delete-WG4S3QD4.js} +2 -1
- package/chunks/{team-plan-approval-C4EVV5TW.js → team-plan-approval-LMMXJ44D.js} +38 -32
- package/chunks/{terminal-image-renderer-6KXNSOF4.js → terminal-image-renderer-SU2YYNAJ.js} +57 -50
- package/chunks/{theme-manager-DRRMX5MS.js → theme-manager-BC6DCE6C.js} +55 -48
- package/chunks/{todoWrite-BF3INMCU.js → todoWrite-2DRDC5EG.js} +2 -1
- package/chunks/{tool-call-ZVU2G5XX.js → tool-call-WBTV7ZZW.js} +6 -5
- package/chunks/{tool-result-media-OKDGMAXP.js → tool-result-media-DACFNH2O.js} +10 -9
- package/chunks/{tool-search-XXWSTVIE.js → tool-search-Y3NA5GTO.js} +13 -10
- package/chunks/{total-session-admission-ZLQ3ZV4B.js → total-session-admission-VXAFAHGR.js} +59 -52
- package/chunks/{transcribe-audio-AQZWRIF5.js → transcribe-audio-HGBJBFP4.js} +4 -3
- package/chunks/{trustedFolders-UCZJ3EDI.js → trustedFolders-PGLKXLUG.js} +56 -49
- package/chunks/{understand-video-segments-R2UXRHKY.js → understand-video-segments-5NFKV5QK.js} +5 -4
- package/chunks/{update-relaunch-DZQJAVMN.js → update-relaunch-35THHY6N.js} +5 -5
- package/chunks/{updateCheck-AIDWX3P3.js → updateCheck-AU6FFINN.js} +57 -50
- package/chunks/{upload-config-KJAT3Y73.js → upload-config-2DB2HD4X.js} +4 -4
- package/chunks/{useAutoAcceptIndicator-7RJZ2TKU.js → useAutoAcceptIndicator-K3M2TEIO.js} +62 -55
- package/chunks/{validateNonInterActiveAuth-UAUX4LUJ.js → validateNonInterActiveAuth-KTKBE2G4.js} +97 -90
- package/chunks/{version-SSQEEKQM.js → version-SGFPFOBG.js} +1 -1
- package/chunks/{web-fetch-C5NSSMKK.js → web-fetch-ME4GDH77.js} +12 -9
- package/chunks/{web-search-QG6Y6ONB.js → web-search-7EZABURD.js} +6 -5
- package/chunks/{web-shell-static-G654DFN2.js → web-shell-static-4SY6HOTM.js} +4 -3
- package/chunks/{workflow-KAUM62P5.js → workflow-IZZNKNON.js} +41 -35
- package/chunks/{workspace-providers-status-BVNDL5LO.js → workspace-providers-status-AA7TXXGS.js} +66 -59
- package/chunks/{workspace-registration-store-TBFZIQ5Z.js → workspace-registration-store-OLL5737M.js} +1 -1
- package/chunks/{workspace-registry-3QSR7FBW.js → workspace-registry-7M2GJXVY.js} +59 -52
- package/chunks/{workspace-runtime-coordinator-H4MDHCO4.js → workspace-runtime-coordinator-644IZPWD.js} +60 -53
- package/chunks/{workspace-service-U5755TOW.js → workspace-service-RJOV7URE.js} +65 -58
- package/chunks/{workspace-skills-status-ERAQBNHV.js → workspace-skills-status-TYYFTIPU.js} +64 -57
- package/chunks/{workspace-trust-reconciler-FTNIOADU.js → workspace-trust-reconciler-64FF3I3X.js} +65 -58
- package/chunks/{write-file-PNZVMMF7.js → write-file-GWRXJDPC.js} +41 -34
- package/chunks/{zoom-image-IR4EQWO5.js → zoom-image-CNMQP3QF.js} +12 -9
- package/cli.js +12 -12
- package/execution-worker.js +1 -1
- package/export-transcript-document.css +1 -1
- package/export-transcript-document.js +105 -101
- package/package.json +3 -3
- package/sandboxBwrapRelay.js +29 -3
- package/web-shell/assets/{abnfDiagram-VCTEODGH-si5XoYhr.js → abnfDiagram-VCTEODGH-DjZkVYSo.js} +1 -1
- package/web-shell/assets/{arc-C9SFQeVy.js → arc-BVsUeysQ.js} +1 -1
- package/web-shell/assets/{architectureDiagram-5GKGNRK7-CSGhcRJM.js → architectureDiagram-5GKGNRK7-Ctfncb9S.js} +1 -1
- package/web-shell/assets/{blockDiagram-NRAW4CY4-DCh9-fRJ.js → blockDiagram-NRAW4CY4-jFV9xKqs.js} +1 -1
- package/web-shell/assets/{c4Diagram-UCG6FXSJ-K99eKrEq.js → c4Diagram-UCG6FXSJ-CU_A3x5O.js} +1 -1
- package/web-shell/assets/channel-CE8bZRZ2.js +1 -0
- package/web-shell/assets/{chunk-2Q5K7J3B-Bpx9SkvV.js → chunk-2Q5K7J3B-CDlmNk5p.js} +1 -1
- package/web-shell/assets/{chunk-5VM5RSS4-BHEUfiuB.js → chunk-5VM5RSS4-BMiAkn3U.js} +1 -1
- package/web-shell/assets/{chunk-F27PBJKO-DS3N9kPD.js → chunk-F27PBJKO-Bvz9m7YM.js} +1 -1
- package/web-shell/assets/{chunk-G27WJ6UU-QZQJ6TCM.js → chunk-G27WJ6UU-CGs4AxN_.js} +1 -1
- package/web-shell/assets/{chunk-JWPE2WC7-CxTculvz.js → chunk-JWPE2WC7-CKPFVJ7h.js} +1 -1
- package/web-shell/assets/{chunk-LCL6LL3I-DE6ZKu-d.js → chunk-LCL6LL3I-Dt_Ff67h.js} +1 -1
- package/web-shell/assets/{chunk-POPQ4Y6H-jZnArKnE.js → chunk-POPQ4Y6H-D3wHu3Ch.js} +1 -1
- package/web-shell/assets/{chunk-SVP7TREG-DW5NIaNB.js → chunk-SVP7TREG-NFtvrgz1.js} +1 -1
- package/web-shell/assets/{chunk-XXDRQBXY-VIFMMxAG.js → chunk-XXDRQBXY-Cw03Ej3w.js} +1 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-1hCsbRjl.js +1 -0
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-1hCsbRjl.js +1 -0
- package/web-shell/assets/{cose-bilkent-JH36ORCC-n5FdZVB_.js → cose-bilkent-JH36ORCC-DFD3DmsV.js} +1 -1
- package/web-shell/assets/{cynefin-OW5HDTMX-NsjTjmEN.js → cynefin-OW5HDTMX-Daym82U1.js} +1 -1
- package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-acPtxq_e.js → cynefinDiagram-5FMLGOSQ-CTa5PgQ3.js} +1 -1
- package/web-shell/assets/{dagre-3AP2YEHR-zLg3OCGx.js → dagre-3AP2YEHR-CuORvpUv.js} +1 -1
- package/web-shell/assets/{diagram-S7CK7UJ4-Dh0dYZx3.js → diagram-S7CK7UJ4-Ds71He45.js} +1 -1
- package/web-shell/assets/{diagram-UQ7AKVKN-BBP_F_r6.js → diagram-UQ7AKVKN-DEWbfBhf.js} +1 -1
- package/web-shell/assets/{diagram-VSXAHHWV-DmOjZG99.js → diagram-VSXAHHWV-moxkWVTb.js} +1 -1
- package/web-shell/assets/{diagram-VX7I27RA-BygnZc2g.js → diagram-VX7I27RA-DMtWByXT.js} +1 -1
- package/web-shell/assets/{diagram-Z3DM3KII-Bo_HoYug.js → diagram-Z3DM3KII-D8csrww3.js} +1 -1
- package/web-shell/assets/{ebnfDiagram-PWID7BFC-BfD6WTFx.js → ebnfDiagram-PWID7BFC-CijCPSwq.js} +1 -1
- package/web-shell/assets/{erDiagram-SSCWMZ5O-SCiFfZko.js → erDiagram-SSCWMZ5O-Bz0f1Ytn.js} +1 -1
- package/web-shell/assets/{flowDiagram-A5DVABFB-DTUVze91.js → flowDiagram-A5DVABFB-BjN3xBgP.js} +1 -1
- package/web-shell/assets/{ganttDiagram-EL5Y4UJY-Bz07u3VP.js → ganttDiagram-EL5Y4UJY-CossRCD9.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-BkObm1JO.js → gitGraphDiagram-WWUBYQGX-BCpZDwQX.js} +1 -1
- package/web-shell/assets/{index-D7CL14ju.js → index-C-WVh8Fm.js} +1 -1
- package/web-shell/assets/{index-BDhC9c4h.js → index-CIE7rUer.js} +524 -489
- package/web-shell/assets/index-LyplXTTk.css +36 -0
- package/web-shell/assets/{infoDiagram-RXCK75RN-Cwux0FC0.js → infoDiagram-RXCK75RN-C2Vwsw4Z.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-5VMMS53U-afgJ_o93.js → ishikawaDiagram-5VMMS53U-DkDEBYFn.js} +1 -1
- package/web-shell/assets/{journeyDiagram-EYS64GPL-Bsl_tspF.js → journeyDiagram-EYS64GPL-DCTEMRE3.js} +1 -1
- package/web-shell/assets/{kanban-definition-3QL26DDD-zX2hAAHO.js → kanban-definition-3QL26DDD-D1r1XE8n.js} +1 -1
- package/web-shell/assets/{layout-xUZBFycu.js → layout-CX0-JUt4.js} +1 -1
- package/web-shell/assets/{linear-B3ItWh1T.js → linear-Bg6PoA8B.js} +1 -1
- package/web-shell/assets/{mermaid.core-P8DktIkt.js → mermaid.core-q6WTQapr.js} +6 -6
- package/web-shell/assets/{mindmap-definition-FBJOCRG2-B9QzKp5i.js → mindmap-definition-FBJOCRG2-CsQVNPfK.js} +1 -1
- package/web-shell/assets/{pegDiagram-XKGWAZYB-D-4CP9Rv.js → pegDiagram-XKGWAZYB-CvJB7Sma.js} +1 -1
- package/web-shell/assets/{pieDiagram-E7YTZNPT-DwTFY08l.js → pieDiagram-E7YTZNPT-CBLnv-fW.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-AXDQQJYC-Cj1LYw08.js → quadrantDiagram-AXDQQJYC-B9u2xeJG.js} +1 -1
- package/web-shell/assets/{railroadDiagram-O6MQD6OU-D5XiqaH2.js → railroadDiagram-O6MQD6OU-DLTUxIOO.js} +1 -1
- package/web-shell/assets/{requirementDiagram-EFPCY7ZU-CRgDiMC3.js → requirementDiagram-EFPCY7ZU-Dfl6QlBf.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-P5KCCOFB-Dsij8etD.js → sankeyDiagram-P5KCCOFB-CGw1J6DR.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-CBlG9uqU.js → sequenceDiagram-WJ2MYXX4-DNaPdQin.js} +1 -1
- package/web-shell/assets/{sizeCapture-X5ZJPWSS-Cl8fYoQY.js → sizeCapture-X5ZJPWSS-C0lEm8df.js} +1 -1
- package/web-shell/assets/{stateDiagram-HBIQ2CUA-DIkZfiwB.js → stateDiagram-HBIQ2CUA-DPzGUm1p.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-jD2z0tDM.js +1 -0
- package/web-shell/assets/{swimlanes-XN3QIQJK-CPbzO1G3.js → swimlanes-XN3QIQJK-BQiJmDZ1.js} +1 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-BdBIJlun.js +8 -0
- package/web-shell/assets/{timeline-definition-24CTP7MA-Bqexz8wQ.js → timeline-definition-24CTP7MA-K5AxZP5Q.js} +1 -1
- package/web-shell/assets/{vennDiagram-4TSXK5OY-x6Xzy9yp.js → vennDiagram-4TSXK5OY-EBtlVIkN.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-VM6X3IG4-BpSRWMul.js → wardleyDiagram-VM6X3IG4-DVFZJsSs.js} +1 -1
- package/web-shell/assets/{xychartDiagram-S5SC5T6Z-D11oaY-b.js → xychartDiagram-S5SC5T6Z-BVdZgHjH.js} +1 -1
- package/web-shell/index.html +2 -2
- package/web-shell/sw.js +1 -1
- package/web-shell/assets/channel-D6PXhDuI.js +0 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-Cvt3vHAz.js +0 -1
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-Cvt3vHAz.js +0 -1
- package/web-shell/assets/index-iUOVxoEW.css +0 -36
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-vHYrFcre.js +0 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-nGOLNHMW.js +0 -8
- package/chunks/{chunk-I2GU2HMQ.js → chunk-M6SELBSG.js} +5 -5
- /package/chunks/{chunk-JRP4GQAF.js → chunk-S5SS7OXV.js} +0 -0
- /package/chunks/{chunk-KA72THKQ.js → chunk-TOLTIUAR.js} +0 -0
package/README.md
CHANGED
|
@@ -201,6 +201,10 @@ Then follow the instructions inside to install, authenticate, and use Qwen Code
|
|
|
201
201
|
|
|
202
202
|
- [**Aliyun Model Studio CLI**](https://github.com/modelstudioai/cli) — Official CLI for Aliyun's AI platform (`bailian-cli`). Extends Qwen Code with image/video generation, knowledge retrieval, app orchestration, and model deployment
|
|
203
203
|
|
|
204
|
+
## Privacy
|
|
205
|
+
|
|
206
|
+
See the [Terms of Service and Privacy Notice](./docs/users/support/tos-privacy.md), including [Chrome extension and Browser Use data handling](./docs/users/support/tos-privacy.md#chrome-extension-and-browser-use).
|
|
207
|
+
|
|
204
208
|
## Contributing
|
|
205
209
|
|
|
206
210
|
Contributions are welcome! See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
|
|
@@ -376,7 +376,7 @@ The bridge-availability and missing-bridge warning rules below describe direct t
|
|
|
376
376
|
| ------------------------------------ | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
377
377
|
| `tools.sandbox` | boolean or string | Sandbox execution environment (can be a boolean or a path string). | `undefined` | |
|
|
378
378
|
| `tools.sandboxImage` | string | Sandbox image URI used by Docker/Podman when `--sandbox-image` and `QWEN_SANDBOX_IMAGE` are not set. | `undefined` | |
|
|
379
|
-
| `tools.shell.enableInteractiveShell` | boolean | Use `node-pty` for an interactive shell experience.
|
|
379
|
+
| `tools.shell.enableInteractiveShell` | boolean | Use `node-pty` for an interactive shell experience. When unset, explicit one-shot prompts use `child_process`; interactive TUI, ACP, stream-json input, stdin-only, and file-input sessions use PTY. Platform and availability fallbacks to `child_process` still apply. | mode-based | |
|
|
380
380
|
| `tools.shell.defaultTimeoutMs` | number | Default timeout, in milliseconds, for foreground shell commands started by the agent. A per-call timeout on the shell tool overrides this. When unset, foreground commands time out after 120000 ms (2 minutes). Set to 0 to disable the timeout. | `undefined` | |
|
|
381
381
|
| `tools.shell.heartbeatIntervalMs` | number | Interval, in milliseconds, between liveness heartbeats emitted while a foreground shell command produces no output. Heartbeats are forwarded to ACP clients and stream-json consumers so they can tell a silent command from a dead session. When unset, heartbeats fire every 10000 ms (10 seconds). Set to 0 to disable heartbeats. | `undefined` | |
|
|
382
382
|
| `tools.core` | array of strings | **Deprecated.** Will be removed in next version. A non-empty list restricts the core tool set (file, shell, search and related built-ins) to an allowlist: core tools not in the list are disabled (fail-closed). Tools outside that set — dynamically discovered tools (MCP, skill) and synthetic/system built-ins such as `agent`, `list_agents`, plan-mode lifecycle tools, goal tools, `task_stop`, `send_message`, `tool_search` and `tool_call` — bypass the allowlist by design; use `permissions.deny` to block a tool's calls (for MCP tools it stays listed and is rejected at runtime), or `tools.disabled` / the per-server `excludeTools` filter to remove it from the registry outright. An empty list (`[]`) is treated as unset and disables nothing. `permissions.allow` cannot reproduce this restriction — it is pure auto-approval (#10075). Use `tools.eager` to restrict which eager-by-default tool schemas are sent initially (unlisted tools are deferred, not disabled — they stay reachable through `tool_search` + `tool_call` while both bridge tools are registered), and `permissions.deny` to block tools outright. | `undefined` | |
|
|
@@ -531,7 +531,7 @@ qwen channel status --daemon-url http://127.0.0.1:4170 --token secret
|
|
|
531
531
|
qwen channel stop --daemon-url http://127.0.0.1:4170 --token secret
|
|
532
532
|
```
|
|
533
533
|
|
|
534
|
-
This mode starts workspace-grouped channel worker processes owned by `qwen serve`. Workers connect back to the daemon through the SDK and use the same channel adapters. They are separate from the daemon process, so a channel adapter crash does not crash the daemon. An explicit `--channel` selection takes precedence and fails daemon startup if it cannot become ready. On a flagless boot,
|
|
534
|
+
This mode starts workspace-grouped channel worker processes owned by `qwen serve`. Workers connect back to the daemon through the SDK and use the same channel adapters. They are separate from the daemon process, so a channel adapter crash does not crash the daemon. An explicit `--channel` selection takes precedence and fails daemon startup if it cannot become ready. On a flagless boot, every trusted registered workspace's own `serve.channels` setting is restored, and a name that cannot be hosted is skipped with a log instead of stopping the others. `all` remains primary-workspace only. Without either source, the daemon does not load channel adapters or reserve the lease until the first `qwen channel set`.
|
|
535
535
|
|
|
536
536
|
Automatic restore skips invalid startup settings and validation or lease failures that occur before workers start, while preserving unrelated settings. After a worker startup fails, the daemon continues only once cleanup succeeds. A global runtime startup timeout or an unconfirmed worker stop still follows the normal startup-failure path; the service lease remains held while worker termination is unconfirmed. Check the daemon log for messages identifying `serve.channels` when a channel does not restore.
|
|
537
537
|
|
|
@@ -369,6 +369,8 @@ If you switch models (via `/model`) and re-review the same PR, `/review` detects
|
|
|
369
369
|
|
|
370
370
|
The model match also gates incremental scoping, not just the skip: "clean up to the cached commit" is the previous model's verdict, so when new commits have landed since the cached review, a model mismatch never scopes to `lastCommitSha..HEAD` — the range is the full diff, noting "Previous round was reviewed by qwen3-coder. Running full review with gpt-4o." — unless an anchor certified by the model now running is recovered from the last posted review (below), which scopes the range instead. The previous round's findings still carry over to be re-ruled; only the anchor does not. The same gate binds the anchor recovered from the last posted review's machine-ledger marker when the cache is absent or its anchor is unusable (CI, another clone): it scopes the incremental range only if the model now running certified it — a marker certified by a different model, or carrying no model (a review posted with `review.attribution` off, or one from before the field), falls back to the full diff. A round that did not close cleanly posts its marker without an anchor (it cannot certify a range), but that loss is not sticky when the round's work list survived whole: recovery grafts the anchor forward from the most recent earlier marker your own account posted with one, so a single non-clean round no longer forces every later round to re-read the full diff — the next round scopes `anchor..HEAD`, which re-covers the range the non-clean round could not certify. A size-capped round's graft is refused (dropped findings would fall outside the grafted scope and retire silently), so later rounds keep re-reading the full diff until a complete marker lands.
|
|
371
371
|
|
|
372
|
+
**Critical-posture re-reviews run a narrower round (fix-audit shape).** Once a PR's re-review resolves the round-adaptive posting floor to critical-only (from round 6, or earlier when the flat first-time-finding trend latches — see the convergence posture) _and_ a usable incremental anchor exists, the round stops re-running round 1's shape. The capture command predicts the floor from the previous round's posted marker and records `incremental.posture: "critical"` in the plan, and the round then: fans out one territory agent per chunk of the delta (whatever its size — no 3A dimension set, but keeping the issue-fidelity agent: it re-checks head against the issue whatever the delta displays, and is the one auditor that can see a fix commit removing behaviour the issue required when the removal appears on neither side of the narrowed range); re-enters each still-clean _interaction_ file with its own full-range hunks, exactly as any other incremental round does; and narrows the reverse-audit waves instead of capping them — from wave 3, a chunk holding no delta file leaves the schedule after one substantive dry audit (a launch every member of which the record certifies dry — rounds 1 and 2 are launched together and count as one launch, so a dry receipt beside a yielding or uncertified partner or sibling is not one), while delta territories keep the full retirement rules and any non-delta chunk the waves could not certify dry falls back to those same rules (so does one whose dry receipt was built on the very same findings list as an earlier round with a yielding or uncertified member, was built before an earlier return that was not dry came back, or ran in a different session from an earlier return that was not dry or beside one no session stamped, as the resumed half of an interrupted review does), so the late waves (where fix-induced Criticals measurably surface) keep running over a shrinking front. Severities are unchanged — the posture governs what posts, never what is found — and every reduction is disclosed: in the plan, in the round's `posture narrowing:` note (which names every chunk the narrowing costs, and the rules that keep one in the wave), and as a one-sentence "Round shape" disclosure in the posted review body. The plan's posture record is itself an arm of the compose-time floor resolution, so a fix-audit round's posting bar cannot disagree with the shape it ran (sub-Critical findings defer even if the floor's usual inputs are unavailable at compose time). An explicit `--severity-floor suggestion` turns the shape off along with the posture (and outranks a stale plan record at posting time); an explicit `--severity-floor critical` enables it from the first anchored re-review.
|
|
373
|
+
|
|
372
374
|
Cache is stored in `.qwen/review-cache/` and tracks both the commit SHA and model ID. Make sure this directory is in your `.gitignore` (a broader rule like `.qwen/*` also works). On GitHub, if the cached commit was rebased or force-pushed away, it falls back to a full review; Aone rules the cached anchor differently — see its paragraph below. Only high-effort reviews consult or write the cache — a `--effort low|medium` quick pass never counts as "already reviewed".
|
|
373
375
|
|
|
374
376
|
## Review Reports
|
|
@@ -414,7 +416,7 @@ The exit code is the contract a gate should read:
|
|
|
414
416
|
|
|
415
417
|
`--resume` continues an interrupted review of the same PR instead of starting over — when a long local run dies part-way (a dropped connection, a timeout, a killed terminal), the retry would otherwise re-fetch, re-chunk and re-launch agents whose work is already on disk. It is safe to pass unconditionally on a retry: `fetch-pr` rules on the on-disk state itself (worktree still at the fetched SHA and clean, diff bytes unchanged, PR head unmoved, resume cap unspent) and silently falls back to a fresh review whenever anything no longer matches, so the flag never fails a run that could start over. When the current invocation has only the built-in target default, a continuation stays pinned to the interrupted run's recorded effort. An explicit `--effort`, a project-remembered level, the operator `review.effort` setting, or an effective `--comment` supplies a required level; a mismatch refuses the resume and runs fresh at that level. PR targets only (a local review's diff is captured from a live working tree, which has no stable interrupted state to continue). Resume is a **local convenience**: the repository's own CI review workflow does **not** resume — each retry re-runs fresh, because a CI attempt runs no-sandbox and its worktree is deleted on exit, leaving no interrupted state to continue.
|
|
416
418
|
|
|
417
|
-
A time-budgeted run can also export a **soft** deadline so the review stops its open-ended reverse-audit loop while there is still time to verify, compose and post: `QWEN_REVIEW_DEADLINE_EPOCH` is the Unix-seconds moment the run will be killed, and `QWEN_REVIEW_DEADLINE_RESERVE_SECONDS` (default 4800; `0` keeps only the round estimate) is the tail that must remain for the last round's verification, `compose-review` and submission. When the remaining budget no longer fits another round plus that tail, the round builder refuses to build it, and the composed verdict discloses the truncated audit (an otherwise-Approve verdict is capped at Comment). Without that variable the review uses the wall its plan recorded at capture: `--deadline <minutes>` on `qwen review fetch-pr` / `capture-local` / `plan-diff`, or by default **8 hours** on a small (Step 3A) diff, **12** on a large (3B) one and **16** on a huge one. That default is a liveness bound — sized above what a healthy run at the round cap spends — so it ends a loop that has stopped converging and leaves a run that keeps working untouched; it is charged in elapsed time, idle included, so a session left overnight spends it, and because the next round is priced from the previous round's admission, a multi-hour pause between rounds can stop a run with time still on the wall (a `--resume` from a new session restarts both the wall and the pricing; **Review Deadline** below gives the ceilings). It stops the loop at the next round admission or verify build; it does not interrupt a build already running. A plan-recorded wall keeps a third of itself (capped at 4800 seconds, floored at the compose floor) as the tail reserve unless the reserve variable is set; a `--deadline` that cannot hold a convergence (two rounds plus that reserve — at or under ninety minutes, or more when the shell's reserve or compose-floor overrides raise the bar; that second leg is skipped while the environment exports a well-formed epoch, since the flag is inert then, and the wall it records is priced again in whatever shell a later env-less `--resume` runs in) is refused up front, and a wall just above it can still stop before round 1 once the fan-out and verification have spent it. When the wall can no longer admit a rebuild the coverage check would otherwise prescribe (a reverse-audit round, or a verifier shard under the compose floor), `compose-review` withholds that `FIX:` line and prints a `NOTE:` line saying so, with the gate's arithmetic; the gap is still disclosed in the posted body. The plan wall bounds the round builder and the verifier; two readers stay on the environment alone — the generated review workflow's launch allowance, and `qwen review run`'s own `--timeout-minutes` kill, which is not exported as a deadline. The plan stores the wall as a duration from the attempt's start, so a `--resume` from a new session renews it (a same-session resume continues the attempt and its wall; the flag itself is ignored on a resumed run — only its grammar and the default rule are checked — and the run says what wall the plan holds and how much of it is left, or that it has run out, and which builds the gates will now refuse; a wall can only run out on a same-session resume, or when the ledger failed to record the attempt, so the cheapest way past it is to resume from a new session, which renews the wall and keeps the worktree; a fresh review without `--resume` records a new wall too, and `--deadline none` on that fresh capture records none). `--deadline none` records no wall and leaves the loop bounded by the round cap alone — unless the environment exports an epoch, which clocks the run regardless. The `/review` slash command does not take the flag: it warns and drops it together with a value that could be one (whole minutes, or `none` — so a PR number typed right after it is dropped too), while any other value after it is disposed of like an invalid `--effort` value (a PR URL becomes the target; a typo is reported, and survives only as a sole file-shaped token), and a skill-driven run always uses the default. The huge tier's round reduction (3 rounds instead of 5) keys on an explicit deadline only — the environment's or the flag's — never on the default. A malformed environment deadline falls through to the plan's wall; a malformed plan field leaves the review ungated — the outer timeout still bounds the run.
|
|
419
|
+
A time-budgeted run can also export a **soft** deadline so the review stops its open-ended reverse-audit loop while there is still time to verify, compose and post: `QWEN_REVIEW_DEADLINE_EPOCH` is the Unix-seconds moment the run will be killed, and `QWEN_REVIEW_DEADLINE_RESERVE_SECONDS` (default 4800; `0` keeps only the round estimate) is the tail that must remain for the last round's verification, `compose-review` and submission. When the remaining budget no longer fits another round plus that tail, the round builder refuses to build it, and the composed verdict discloses the truncated audit (an otherwise-Approve verdict is capped at Comment). Without that variable the review uses the wall its plan recorded at capture: `--deadline <minutes>` on `qwen review fetch-pr` / `capture-local` / `plan-diff`, or by default **8 hours** on a small (Step 3A) diff, **12** on a large (3B) one and **16** on a huge one — sized by the diff's own lines, so a critical-posture fix-audit round keeps the wall its delta's size earns even though it fans out per territory and takes the chunked round cap. That default is a liveness bound — sized above what a healthy run at the round cap spends — so it ends a loop that has stopped converging and leaves a run that keeps working untouched; it is charged in elapsed time, idle included, so a session left overnight spends it, and because the next round is priced from the previous round's admission, a multi-hour pause between rounds can stop a run with time still on the wall (a `--resume` from a new session restarts both the wall and the pricing; **Review Deadline** below gives the ceilings). It stops the loop at the next round admission or verify build; it does not interrupt a build already running. A plan-recorded wall keeps a third of itself (capped at 4800 seconds, floored at the compose floor) as the tail reserve unless the reserve variable is set; a `--deadline` that cannot hold a convergence (two rounds plus that reserve — at or under ninety minutes, or more when the shell's reserve or compose-floor overrides raise the bar; that second leg is skipped while the environment exports a well-formed epoch, since the flag is inert then, and the wall it records is priced again in whatever shell a later env-less `--resume` runs in) is refused up front, and a wall just above it can still stop before round 1 once the fan-out and verification have spent it. When the wall can no longer admit a rebuild the coverage check would otherwise prescribe (a reverse-audit round, or a verifier shard under the compose floor), `compose-review` withholds that `FIX:` line and prints a `NOTE:` line saying so, with the gate's arithmetic; the gap is still disclosed in the posted body. The plan wall bounds the round builder and the verifier; two readers stay on the environment alone — the generated review workflow's launch allowance, and `qwen review run`'s own `--timeout-minutes` kill, which is not exported as a deadline. The plan stores the wall as a duration from the attempt's start, so a `--resume` from a new session renews it (a same-session resume continues the attempt and its wall; the flag itself is ignored on a resumed run — only its grammar and the default rule are checked — and the run says what wall the plan holds and how much of it is left, or that it has run out, and which builds the gates will now refuse; a wall can only run out on a same-session resume, or when the ledger failed to record the attempt, so the cheapest way past it is to resume from a new session, which renews the wall and keeps the worktree; a fresh review without `--resume` records a new wall too, and `--deadline none` on that fresh capture records none). `--deadline none` records no wall and leaves the loop bounded by the round cap alone — unless the environment exports an epoch, which clocks the run regardless. The `/review` slash command does not take the flag: it warns and drops it together with a value that could be one (whole minutes, or `none` — so a PR number typed right after it is dropped too), while any other value after it is disposed of like an invalid `--effort` value (a PR URL becomes the target; a typo is reported, and survives only as a sole file-shaped token), and a skill-driven run always uses the default. The huge tier's round reduction (3 rounds instead of 5) keys on an explicit deadline only — the environment's or the flag's — never on the default. A malformed environment deadline falls through to the plan's wall; a malformed plan field leaves the review ungated — the outer timeout still bounds the run.
|
|
418
420
|
|
|
419
421
|
Nested inside that reserve is a smaller **compose floor**, `QWEN_REVIEW_DEADLINE_COMPOSE_FLOOR_SECONDS` (default 1200; `0` disables this gate entirely, at every point including past the deadline). The reserve is one number covering "verify the last round **plus** compose **plus** submit", which fits a normal per-finding re-trace but not a security review whose verification re-runs real filesystem/git workloads without bound. So the verifier — not the round builder — is gated on this floor: once the floor or less remains, `agent-prompt --role verify` refuses to build (a `VERIFY BUDGET:` line, exit **4**), the findings in hand keep their unverified tag (which caps the verdict), and `compose-review` and submission run. Under the plan's own rule the floor never exceeds the reserve (a plan-recorded wall's reserve can sit exactly on it), and the round gate prices the round on top of the reserve, so a healthy run hits the reverse-audit gate first and never reaches it (an explicit `QWEN_REVIEW_DEADLINE_RESERVE_SECONDS` below the floor — `0` is the documented escape hatch — is the operator's choice, and then the verifier's gate can fire first); it is the cover for the one span the reserve cannot bound.
|
|
420
422
|
|
|
@@ -168,7 +168,7 @@ qwen channel status --daemon-url http://127.0.0.1:4170 --token secret
|
|
|
168
168
|
qwen channel stop --daemon-url http://127.0.0.1:4170 --token secret
|
|
169
169
|
```
|
|
170
170
|
|
|
171
|
-
This mode is experimental and daemon-managed. It does not replace the standalone `qwen channel start` command: without `--daemon-url`, existing `qwen channel start`, `stop`, and `status` behavior remains standalone. With `qwen serve --channel`, the explicit selection wins, the daemon reserves the channel-service lease before listening, and startup fails if the initial worker cannot become ready. On a flagless boot, the daemon restores `serve.channels` from
|
|
171
|
+
This mode is experimental and daemon-managed. It does not replace the standalone `qwen channel start` command: without `--daemon-url`, existing `qwen channel start`, `stop`, and `status` behavior remains standalone. With `qwen serve --channel`, the explicit selection wins, the daemon reserves the channel-service lease before listening, and startup fails if the initial worker cannot become ready. On a flagless boot, the daemon restores `serve.channels` from every trusted registered workspace, so a channel a non-primary workspace is configured to start comes back with the daemon instead of needing a runtime API call. If neither source selects channels, the heavy channel runtime remains unloaded and no channel-service lease is reserved until the first runtime PUT. A channel name listed by a workspace that cannot host it is skipped with a log, leaving the other workspaces' channels running; `all` still applies only to the primary workspace. If a ready worker later crashes, the daemon keeps running, relaunches it under a bounded restart policy, and reports its state (including `channel_worker_exited` warnings) in `GET /daemon/status`.
|
|
172
172
|
|
|
173
173
|
Automatic restore skips an invalid startup field or a validation or lease error before workers start, logs its `serve.channels` source, and keeps unrelated settings in effect. After a worker startup fails, the daemon continues only once cleanup succeeds. Global runtime startup timeouts and unconfirmed worker stops retain the normal startup-failure behavior; the service lease remains held while worker termination is unconfirmed. Check the daemon log for skipped or failed restores.
|
|
174
174
|
|
|
@@ -60,6 +60,34 @@ When you authenticate with Google Cloud Vertex AI, the applicable Terms of Servi
|
|
|
60
60
|
>
|
|
61
61
|
> When using Vertex AI, you are subject to [Google Cloud's Terms of Service](https://cloud.google.com/terms) and [Google Cloud Privacy Notice](https://cloud.google.com/privacy), not Qwen Code's terms. Please review Google Cloud's documentation for specific details about data usage, retention, and privacy practices.
|
|
62
62
|
|
|
63
|
+
## Chrome extension and Browser Use
|
|
64
|
+
|
|
65
|
+
The Qwen Code Chrome extension connects Chrome to Qwen Code running on your computer. Its side panel displays the local Qwen Code web application, and Browser Use exchanges browser commands and results through a local Native Messaging host. The following describes data handled for browser tasks, separately from the optional usage statistics described below.
|
|
66
|
+
|
|
67
|
+
### Browser data used for your tasks
|
|
68
|
+
|
|
69
|
+
Browser tools can access open HTTP(S) tab titles and URLs, page text and structure, screenshots, browser interaction results, and debugging information such as console messages, network activity, and cookies. Explicit browser-history searches return matching URLs, page titles, and visit times within the requested query limits. Depending on the pages and tasks you choose, these results may contain personal identifiers, health information, financial or payment information, authentication information, personal communications, and location information. The extension also uses navigation-source information to associate new pages opened by a recent assistant action with the same browser session.
|
|
70
|
+
|
|
71
|
+
These capabilities support the browser tasks and web development work you request from Qwen Code. Browser tools operate in your Chrome profile, including pages where you are signed in. Choose the pages and tasks you share with the assistant accordingly.
|
|
72
|
+
|
|
73
|
+
### Local processing and AI providers
|
|
74
|
+
|
|
75
|
+
The extension sends browser commands and results to Qwen Code on the same computer. Qwen Code may include those results in conversation context and transmit them to the AI provider configured for that session. The provider's privacy, retention, and model-training terms apply as described elsewhere in this notice. The extension's local connection is one part of this data flow; subsequent processing may take place at your chosen AI provider.
|
|
76
|
+
|
|
77
|
+
### Stored data and user controls
|
|
78
|
+
|
|
79
|
+
The extension stores connection preferences, an optional local daemon authentication token, and a persistent browser-instance identifier in Chrome extension local storage. It also stores tab and session ownership state in Chrome session storage to support cleanup after its background service worker restarts.
|
|
80
|
+
|
|
81
|
+
Browser results included in Qwen Code conversations or saved by browser tools may remain in local conversation records, screenshots, downloads, or other output files. Manage these records using the applicable Qwen Code and filesystem controls. AI-provider retention is governed separately by the selected provider.
|
|
82
|
+
|
|
83
|
+
You can disable or uninstall the Chrome extension in Chrome's extension manager to stop its browser integration. Clearing extension storage removes its saved preferences, token, and instance identifier. Removing the extension leaves the separately installed Qwen Code application, its Native Messaging host, local conversations and files, and copies already sent to an AI provider to be managed separately.
|
|
84
|
+
|
|
85
|
+
### Limited use of browser data
|
|
86
|
+
|
|
87
|
+
Qwen Code's use and transfer of data received through the Chrome extension adhere to the [Chrome Web Store User Data Policy](https://developer.chrome.com/docs/webstore/program-policies/user-data), including its Limited Use requirements. Browser data is used to provide the extension's single purpose: connecting Chrome to Qwen Code for user-requested browser assistance. It is not sold, used for advertising, or used to determine creditworthiness or lending eligibility. Transfers are limited to providing that functionality, including processing by the AI provider you configure, and other uses permitted by that policy.
|
|
88
|
+
|
|
89
|
+
For questions about browser data handling, contact the team through the [Qwen Code issue tracker](https://github.com/QwenLM/qwen-code/issues). Share only the details needed to explain the question; remove credentials and private page content from public reports.
|
|
90
|
+
|
|
63
91
|
## Usage Statistics and Telemetry
|
|
64
92
|
|
|
65
93
|
Qwen Code may collect anonymous usage statistics and [telemetry](../../developers/development/telemetry) data to improve the user experience and product quality. This data collection is optional and can be controlled through configuration settings.
|
|
@@ -105,7 +133,7 @@ When enabled, Qwen Code may collect:
|
|
|
105
133
|
- Error reports and crash data
|
|
106
134
|
- General usage patterns
|
|
107
135
|
|
|
108
|
-
**What is NOT collected
|
|
136
|
+
**What is NOT collected as usage statistics:**
|
|
109
137
|
|
|
110
138
|
- Your code content
|
|
111
139
|
- Prompts sent to AI models
|
package/bundled/review/SKILL.md
CHANGED
|
@@ -169,7 +169,7 @@ Based on the parsed `target.type`:
|
|
|
169
169
|
Worktree isolation: all subsequent steps (agents, build/test) operate inside `worktreePath`, not the user's working tree. Cache and reports (Step 8) are written to the **main project directory**, not the worktree.
|
|
170
170
|
|
|
171
171
|
- **Incremental review check** (high effort only — neither low nor medium consults or updates the cache): read `.qwen/review-cache/pr-<n>.json` **before** `fetch-pr` (it is a local file; nothing about it needs the fetch) and, when it holds a `lastCommitSha`, pass BOTH fields to the fetch verbatim: `--since <lastCommitSha> --since-model <lastModelId>` (omit `--since-model` when the cache has no `lastModelId`; do not substitute anything for it). **Copy them; do not compare them to anything.** The same-model gate is ruled inside `fetch-pr`, over the identity the runtime published — "clean up to `lastCommitSha`" is the recorded identity's verdict, and the command validates an anchor against the HISTORY, never against who certified it, so an anchor from another identity is ancestrally perfect and would scope this round past code it never reviewed. A hand-applied version of that gate was wrong every time it was written, because `{{model}}` interpolates the BARE model id while every identity the CLI records is provider-qualified: two provider configurations exposing one model name compared equal and passed each other's gate. When the gate refuses, the report says `cross-model-anchor` and the round reviews the full diff. Read the cache's `findings` ledger either way (Step 6 owes each entry a ruling; the work list carries across models, only the anchor does not). **You never run `git` against an anchor yourself** — no `git diff <sha>..HEAD`, no `cat-file`, no `merge-base --is-ancestor`: the command validates the anchor against the fetched history and computes the scoped diff and chunk plan in one pass, because a hand-run check is one a run can skip, and the hand-computed delta was exactly the shape this skill forbids everywhere else (the diff is a file the CLI writes, never a command you run). The report's `incremental` field is the decision; act on it with `lastModelId` from the cache and the current model ID (`{{model}}`):
|
|
172
|
-
- `effective: true` (no `upToDate`) → the report's diff and plan ARE the incremental scope (`since..head`); continue with them exactly as with a full plan. The file set is **widened by one import hop**: a still-clean source file that imports a changed one re-enters the scope with its own full-range hunks, because the round before cleared it against the callee's OLD shape. `incremental.scope` names each file's class — `deltaFiles` (touched since the anchor), `interaction[]` (widened back in, each with the edges that did it), `contextFileCount` (weighed and passed over) — and a chunk brief built for an interaction file points its agent at that seam instead of a from-scratch re-review. **Also read the cache's `findings` ledger** (older caches have none — then there is nothing to track): these are the previous round's findings with their ids, and Step 6 owes each of them a ruling this round. (Reachable only under a matching identity: the gate inside the command is what keeps a cross-model anchor from scoping anything.)
|
|
172
|
+
- `effective: true` (no `upToDate`) → the report's diff and plan ARE the incremental scope (`since..head`); continue with them exactly as with a full plan. The file set is **widened by one import hop**: a still-clean source file that imports a changed one re-enters the scope with its own full-range hunks, because the round before cleared it against the callee's OLD shape. `incremental.scope` names each file's class — `deltaFiles` (touched since the anchor), `interaction[]` (widened back in, each with the edges that did it), `contextFileCount` (weighed and passed over) — and a chunk brief built for an interaction file points its agent at that seam instead of a from-scratch re-review. On a round the capture resolved to the **critical posting posture** the report also carries `incremental.posture: "critical"` with its `postureCause` (`round`, `flat-trend`, or `explicit` — the same facts Step 6's floor resolution reads, predicted from the side file and the CLI-recorded invocation), and the round runs the **fix-audit shape**: see Step 1's topology note and Step 5's posture narrowing. **Also read the cache's `findings` ledger** (older caches have none — then there is nothing to track): these are the previous round's findings with their ids, and Step 6 owes each of them a ruling this round. (Reachable only under a matching identity: the gate inside the command is what keeps a cross-model anchor from scoping anything.)
|
|
173
173
|
- `upToDate: true` **and** `comment.effective` is false (no `--comment` flag, and `review.comment` not enabled in settings) → inform the user "No new changes since last review" (this branch consumes no plan, so it holds even when `diffPath` is null). **Before the cleanup, write the stop sidecar** so `qwen review run` reads the round as DECIDED instead of exiting 1 "Review did not complete" over it: when the environment carries `QWEN_REVIEW_RUN_ID`, write `.qwen/tmp/qwen-review-pr-<n>-stop.json` containing exactly `{"reason": "<up-to-date|empty-diff>", "runId": "<the QWEN_REVIEW_RUN_ID value>"}` — the same reason+runId contract `capture-local` writes for local stops, runId copied verbatim (the parent's reader is nonce-fenced and discards any other stamp); without that variable no parent is reading and the file is not written. `cleanup` deliberately KEEPS this run's sidecar (it spares a `stop.json` whose `runId` matches the environment) so the parent can still read the decision after the child exits — do not remove it by hand; the next run's cleanup collects it. Then run `"${QWEN_CODE_CLI:-qwen}" review cleanup pr-<n>` to remove the worktree just created, and stop. **This branch does not apply on a resumed run** (`resumed: true` from the resume branch below): a continuation's `incremental` field is the interrupted attempt's history, not this run's decision, and taking the stop/cleanup here would destroy the very state `--resume` reused.
|
|
174
174
|
- `upToDate: true` **but** `comment.effective` is true (the `--comment` flag or the `review.comment` setting) → run the full review anyway — the report already holds the full-range diff and plan for exactly this flow, unless `diffPath` is null, which is the ordinary degraded state (partial coverage, disclosed) rather than a scoping fact. Inform the user: "No new code changes. Running review to post inline comments."
|
|
175
175
|
- `reason: cross-model-anchor` → the cached anchor was certified by another identity, so it was not used. Continue on the full-range plan (or, when `diffPath` is null, on the degraded state its siblings name). The command already said which identity certified it and which is running; repeat that to the user rather than restating it from the cache.
|
|
@@ -245,7 +245,7 @@ Read from it:
|
|
|
245
245
|
- `diffLines`, `diffChars`, and `srcDiffLines` / `testDiffLines` / `docsDiffLines` / `generatedDiffLines`
|
|
246
246
|
- `chunks[]` — contiguous, non-overlapping line ranges tiling the whole diff. Each entry has `id`, `startLine`, `endLine` (1-based, inclusive), `lines`, `chars`, an `oversized` flag, and `files[]` naming the source files and new-side line ranges it covers. A chunk with `oversized: true` may exceed what one `read_file` call returns.
|
|
247
247
|
- `files[]` — per-file `kind` (`source` / `test` / `generated`), `hunks[]` new-side ranges (Step 7 validates comment anchors against these), `addedRanges[]` and `diffRange` (present only on `heavy` files — the exact lines the PR wrote, and where that file's own diff lives, so an invariant agent can see what was deleted), change counts, and the `heavy` flag
|
|
248
|
-
- `budget` — how much walking the **size-elastic** parts of this run owe, sized from `srcDiffLines` except that an all-non-source diff (docs, lockfiles) counts its total lines at an eighth rate, so the size these tiers read is `effective = max(srcDiffLines, floor(diffLines / 8))`; recorded here rather than passed as a flag so every reader sees one number. `inlineAngles`, `sweep`, and `candidateFloor` scope Step 3C's low pass; `candidateFloor` is `min(changed files, 4)` and triggers one deterministic re-pass rather than forcing findings. `specialistCap` is the Agent 8 ceiling (**0** below 80 source lines — "one domain dominates the diff" is a judgement, and a judgement made about forty lines finds a dominant domain every time, because forty lines are usually all one thing — **and 0 again for a huge diff (effective ≥ 3000)**, where an Agent 8 whole-diff pass on top of the base fan-out is the marginal cost that tips a review too big to finish into posting nothing); `verifyShard` is Step 4's findings-per-verifier; `reverseAuditRounds` is the reverse-audit loop's round cap, **one value per topology**: **10** on a Step 3A diff, **5** on a Step 3B one, **3 for a huge diff** (effective ≥ 3000 lines) — but the huge reduction applies **only when the run has an explicit deadline** (`QWEN_REVIEW_DEADLINE_EPOCH` from CI, or `--deadline <minutes>` at capture); under the plan's default wall a huge diff is just a large 3B diff and gets 5. Capture prices the tier from the clock it sees and records it; a reader honours a recorded value inside its own band `[3, tier]` and may only lower it (a plan captured under CI's epoch keeps 3 in a continuation resumed without that epoch; a plan captured with no clock is cut to 3 if the run later gains one), while a value outside the band — below 3, or above the tier — falls back to the tier. One number cannot price all three, because what is being capped is a _round_ and a round costs one auditor on 3A, one auditor per non-retired chunk on 3B, and ~90 minutes on a 4,000-line PR — where five rounds (450 min) alone exceed the six-hour ceiling before the fan-out and tail are counted, and the 6-hour timeouts that posted nothing were 4,000-5,300-line PRs (measured; DESIGN.md — The six-hour timeouts). Ten on 3A because the marginal round there is a single agent against a whole review of 20-31 calls: five was the 3B arithmetic applied where it does not hold, and it stopped loops that were still confirming Criticals to save ~5 calls. Three when huge is not a claim that a huge diff converges sooner — it plainly does not, and on recall it deserves more rounds than a small one, not fewer; it is a claim that five ~90-minute rounds do not fit a six-hour ceiling, and a review killed mid-flight posts nothing at all. Where there is no such ceiling — the plan's default wall is a liveness bound sized above a healthy run, not a ceiling to fit inside — the premise is absent and so is the reduction. Three is one audit round above the convergence floor of two — the all-dry rounds-1-and-2 shape converges under any cap of two or more, since the convergence check runs before the cap gate; the extra round buys hot chunks one more pass. An operator may LOWER the tier for every review through the `review.reverseAuditRounds` setting (honoured from the User, System and SystemDefaults scopes — never from the repository's own `.qwen/settings.json`; a value below 3, or above the tier, is ignored rather than clamped, so it leaves the tier alone) — the capture command resolves it into this field, so you read one number here either way and never learn that a setting was involved; it can never RAISE a tier. The `agent-prompt` builder enforces the cap itself (a `ROUND CAP:` refusal, exit 4, that writes a marker `compose-review` caps on — same contract as the deadline gate below), so you never count rounds yourself. `agentToolBudget` is the base rate of the soft tool-call ceiling `agent-prompt` bakes into every finder and auditor brief — not the verifier's, not Agent 7's, and not Agent 0's (whose mandatory work scales with the linked issues rather than the diff), not the counter-frame audit 6d's (its mandated PR-context read is discussion-sized) and not the prose-execution audit's (its work is recipe-sized) — five exemptions, the set `agent-prompt` computes from the briefs' own `budgetExempt`. The ceiling is per **launch**: a scoped agent (a chunk, a heavy file) gets an allowance derived from its own territory — never above the plan's recorded allowance, which is clamped into the budget's own band in both directions, so the plan stays the one number every launch answers to — and every launch's assigned reads ride on top of the allowance rather than inside it, so a huge diff's mandatory chunk reads can never exhaust the exploration a whole-diff role owes — because a wave's wall clock is its slowest agent and the slowest agent is reliably one that kept exploring past any recall gain: the same 14-agent fan-out has measured 11.7 and 41 minutes on comparable diffs, the difference being individual agents spending 40-100 calls walking the tree (measured; DESIGN.md — The forty-one minute wave). The ceiling is soft and the briefs restate the recall rule beside it: at the budget an agent stops **exploring**, never reporting — findings in hand are filed, and each stopped check is disclosed on its own line in the fixed form `Budget gap: <the check>`, which `check-coverage` parses out of the transcripts (its report's `budgetGaps`) — see Step 3D for the ruling each gap is owed. **It never scales a dimension away** — which agents a review owes is the roster's answer and the roster reads `effort`, so a size input cannot become a back door into shrinking coverage. Nothing here is yours to override: a budget the caller can inflate is a budget that gets inflated. A plan whose `budget` predates `candidateFloor` uses `min(plan.files.length, 4)` for that field. **A plan with no `budget` field** (written by an older CLI — the version-skew this skill has already measured once) falls back to the pre-budget flat behaviour: walk all six angles, run the sweep, use that same candidate-floor fallback, cap Agent 8 at 2, shard verification at 8. Those five err toward more coverage, never less. The round cap is the one exception and is worth naming rather than lumping in: **in a run with an explicit deadline**, a field-less **huge** plan reads 3 where the flat fallback read 5 — deliberately _less_, because that tier is a finishability ruling and the reviews it exists for are the ones that ran six hours and posted nothing. Without one it reads 5, the same as the flat fallback.
|
|
248
|
+
- `budget` — how much walking the **size-elastic** parts of this run owe, sized from `srcDiffLines` except that an all-non-source diff (docs, lockfiles) counts its total lines at an eighth rate, so the size these tiers read is `effective = max(srcDiffLines, floor(diffLines / 8))`; recorded here rather than passed as a flag so every reader sees one number. `inlineAngles`, `sweep`, and `candidateFloor` scope Step 3C's low pass; `candidateFloor` is `min(changed files, 4)` and triggers one deterministic re-pass rather than forcing findings. `specialistCap` is the Agent 8 ceiling (**0** below 80 source lines — "one domain dominates the diff" is a judgement, and a judgement made about forty lines finds a dominant domain every time, because forty lines are usually all one thing — **and 0 again for a huge diff (effective ≥ 3000)**, where an Agent 8 whole-diff pass on top of the base fan-out is the marginal cost that tips a review too big to finish into posting nothing); `verifyShard` is Step 4's findings-per-verifier; `reverseAuditRounds` is the reverse-audit loop's round cap, **one value per topology**: **10** on a Step 3A diff, **5** on a Step 3B one (a fix-audit round below the huge floor reads this tier whatever its narrowed sizes say — the tier reads the same posture that flips the topology gate — but the huge finishability ruling below still wins under an explicit deadline; the plan's default wall stays sized by the delta's own size, since a posture is not a size), **3 for a huge diff** (effective ≥ 3000 lines) — but the huge reduction applies **only when the run has an explicit deadline** (`QWEN_REVIEW_DEADLINE_EPOCH` from CI, or `--deadline <minutes>` at capture); under the plan's default wall a huge diff is just a large 3B diff and gets 5. Capture prices the tier from the clock it sees and records it; a reader honours a recorded value inside its own band `[3, tier]` and may only lower it (a plan captured under CI's epoch keeps 3 in a continuation resumed without that epoch; a plan captured with no clock is cut to 3 if the run later gains one), while a value outside the band — below 3, or above the tier — falls back to the tier. One number cannot price all three, because what is being capped is a _round_ and a round costs one auditor on 3A, one auditor per non-retired chunk on 3B, and ~90 minutes on a 4,000-line PR — where five rounds (450 min) alone exceed the six-hour ceiling before the fan-out and tail are counted, and the 6-hour timeouts that posted nothing were 4,000-5,300-line PRs (measured; DESIGN.md — The six-hour timeouts). Ten on 3A because the marginal round there is a single agent against a whole review of 20-31 calls: five was the 3B arithmetic applied where it does not hold, and it stopped loops that were still confirming Criticals to save ~5 calls. Three when huge is not a claim that a huge diff converges sooner — it plainly does not, and on recall it deserves more rounds than a small one, not fewer; it is a claim that five ~90-minute rounds do not fit a six-hour ceiling, and a review killed mid-flight posts nothing at all. Where there is no such ceiling — the plan's default wall is a liveness bound sized above a healthy run, not a ceiling to fit inside — the premise is absent and so is the reduction. Three is one audit round above the convergence floor of two — the all-dry rounds-1-and-2 shape converges under any cap of two or more, since the convergence check runs before the cap gate; the extra round buys hot chunks one more pass. An operator may LOWER the tier for every review through the `review.reverseAuditRounds` setting (honoured from the User, System and SystemDefaults scopes — never from the repository's own `.qwen/settings.json`; a value below 3, or above the tier, is ignored rather than clamped, so it leaves the tier alone) — the capture command resolves it into this field, so you read one number here either way and never learn that a setting was involved; it can never RAISE a tier. The `agent-prompt` builder enforces the cap itself (a `ROUND CAP:` refusal, exit 4, that writes a marker `compose-review` caps on — same contract as the deadline gate below), so you never count rounds yourself. `agentToolBudget` is the base rate of the soft tool-call ceiling `agent-prompt` bakes into every finder and auditor brief — not the verifier's, not Agent 7's, and not Agent 0's (whose mandatory work scales with the linked issues rather than the diff), not the counter-frame audit 6d's (its mandated PR-context read is discussion-sized) and not the prose-execution audit's (its work is recipe-sized) — five exemptions, the set `agent-prompt` computes from the briefs' own `budgetExempt`. The ceiling is per **launch**: a scoped agent (a chunk, a heavy file) gets an allowance derived from its own territory — never above the plan's recorded allowance, which is clamped into the budget's own band in both directions, so the plan stays the one number every launch answers to — and every launch's assigned reads ride on top of the allowance rather than inside it, so a huge diff's mandatory chunk reads can never exhaust the exploration a whole-diff role owes — because a wave's wall clock is its slowest agent and the slowest agent is reliably one that kept exploring past any recall gain: the same 14-agent fan-out has measured 11.7 and 41 minutes on comparable diffs, the difference being individual agents spending 40-100 calls walking the tree (measured; DESIGN.md — The forty-one minute wave). The ceiling is soft and the briefs restate the recall rule beside it: at the budget an agent stops **exploring**, never reporting — findings in hand are filed, and each stopped check is disclosed on its own line in the fixed form `Budget gap: <the check>`, which `check-coverage` parses out of the transcripts (its report's `budgetGaps`) — see Step 3D for the ruling each gap is owed. **It never scales a dimension away** — which agents a review owes is the roster's answer and the roster reads `effort`, so a size input cannot become a back door into shrinking coverage. Nothing here is yours to override: a budget the caller can inflate is a budget that gets inflated. A plan whose `budget` predates `candidateFloor` uses `min(plan.files.length, 4)` for that field. **A plan with no `budget` field** (written by an older CLI — the version-skew this skill has already measured once) falls back to the pre-budget flat behaviour: walk all six angles, run the sweep, use that same candidate-floor fallback, cap Agent 8 at 2, shard verification at 8. Those five err toward more coverage, never less. The round cap is the one exception and is worth naming rather than lumping in: **in a run with an explicit deadline**, a field-less **huge** plan reads 3 where the flat fallback read 5 — deliberately _less_, because that tier is a finishability ruling and the reviews it exists for are the ones that ran six hours and posted nothing. Without one it reads 5, the same as the flat fallback.
|
|
249
249
|
A chunk is read with `read_file(file_path=diffPathAbsolute, offset=startLine - 1, limit=endLine - startLine + 1)` — `offset` is 0-based.
|
|
250
250
|
|
|
251
251
|
For **local-diff and file-path reviews**, capture and plan in one command:
|
|
@@ -343,6 +343,7 @@ If `diffPath` is `null` (merge-base could not be resolved), fall back to giving
|
|
|
343
343
|
|
|
344
344
|
**Choose the topology from `srcDiffLines`, not from `diffLines`.**
|
|
345
345
|
|
|
346
|
+
- **the plan carries `incremental.posture: "critical"`** beside `effective: true` and a well-formed `scope` (a non-empty `anchor` and a `deltaFiles` list — the same `isFixAuditRound` bar every CLI reader applies; a posture beside a malformed scope is the ordinary full round) — a **fix-audit round** (#10104): use Step 3B whatever the sizes say. The narrowed delta is usually 3A-sized, but the posture defers everything below Critical that the floor takes — deterministic `[build]`/`[test]`/`[probe]` findings are excluded from the floor by the tag on their claim line (the fact a typed deferral entry carries as its `source` field) and post as usual — so the round owes one accountable reader per territory of the fix commits, not fourteen dimension lenses re-walking a delta whose sub-Critical yield is deferred. The CLI's own gate reads the same plan field, so the roster, the round-cap tier (the 3B tier of 5, or the huge tier's 3 where a run under an explicit deadline has a delta that is itself huge — the huge gate is checked first) and the #9242 stderr note all agree with this routing; the roster the plan builds already reflects the shape. Tell the user: "Critical posture (<postureCause>): fix-audit round over the commits since the last round."
|
|
346
347
|
- **`srcDiffLines` ≤ 500 and `diffLines` ≤ 3200** — use the dimension fan-out in Step 3A.
|
|
347
348
|
- **otherwise** — use the territory × dimension fan-out in Step 3B, and inform the user: "This is a large changeset (N source lines of M total, K chunks). The review may take a few minutes."
|
|
348
349
|
|
|
@@ -448,7 +449,7 @@ Everything below still governs what the agent is asked to do; the command builds
|
|
|
448
449
|
|
|
449
450
|
**Whole-diff agents — dispatched alongside the chunk agents by the same workflow.**
|
|
450
451
|
|
|
451
|
-
**Their prompts are already in the generated workflow above.** Roles there: `0` (PR reviews), `1b` (when the diff removes anything, or a repository context requires it), `1c`, `test-matrix`, `6d` (PR reviews, high effort), `prose-exec` (when the diff touches an instruction file, when the plan's file list is unknown, or a repository context requires it — same-repo only, like `7`: it needs a tree), `7` (same-repo), and for a **heavy** file three more, one per checklist slice (their blocks are labelled `Invariant agent A|B|C: … — <path>`). To rebuild one for a relaunch: `--role <role> --batch` (an invariant agent adds `--file <path>`), then combine the repair manifests with `emit-workflow --batch`. `check-coverage` derives the same list from the plan and will name any role that did not run.
|
|
452
|
+
**Their prompts are already in the generated workflow above.** Roles there: `0` (PR reviews — kept on a fix-audit round too: issue fidelity re-checks head against the issue whatever the diff displays, and it is the one auditor that can see a fix commit removing behaviour the issue required when the removal appears on neither side of `base..head`), `1b` (when the diff removes anything, or a repository context requires it), `1c`, `test-matrix`, `6d` (PR reviews, high effort), `prose-exec` (when the diff touches an instruction file, when the plan's file list is unknown, or a repository context requires it — same-repo only, like `7`: it needs a tree), `7` (same-repo), and for a **heavy** file three more, one per checklist slice (their blocks are labelled `Invariant agent A|B|C: … — <path>`). To rebuild one for a relaunch: `--role <role> --batch` (an invariant agent adds `--file <path>`), then combine the repair manifests with `emit-workflow --batch`. `check-coverage` derives the same list from the plan and will name any role that did not run.
|
|
452
453
|
|
|
453
454
|
Why: **the chunk agents got the diff and these did not.** In one real 3B run every one of them was launched with no diff path — and these own exactly the classes a chunk agent is structurally blind to (measured; DESIGN.md — The whole-diff agents launched without the diff).
|
|
454
455
|
|
|
@@ -783,7 +784,7 @@ After deduplication, run reverse audit **iteratively** — the first launch ride
|
|
|
783
784
|
|
|
784
785
|
- **Small diffs (Step 3A path):** one reverse audit agent per round, reading the whole diff — except rounds 1 and 2, which are **the convergence pair** and launch together (below).
|
|
785
786
|
- **Large diffs (Step 3B path):** one reverse audit agent **per chunk** per round, dispatched together by one workflow — and rounds 1 and 2 are **the convergence pair** here too, their per-chunk auditors launched together (below). A single agent asked to re-read a 5 800-line diff with a growing finding list appended is the most context-starved agent in the pipeline — precisely on the PRs where the reverse audit matters most. Each per-chunk auditor gets the same territory as its Step 3B counterpart, plus the cumulative finding list for the **whole** diff (so it knows what is already covered elsewhere).
|
|
786
|
-
- **The builder schedules the 3B fan-out; you do not.** Rounds 1 and 2 audit every chunk — they are what establishes each territory's record. From round 3 on, `--all-chunks` reads the harness transcripts and **retires** any chunk whose own last two audits were substantively dry (the receipt named what it examined AND the transcript shows the diff was opened): a retired chunk is cold-checked on alternating rounds instead of every round, and a cold check that yields anything returns it to every-round auditing. The savings land on the odd rounds — every retired chunk cold-checks together on the even ones, so an even round's fan-out is unchanged; expect the odd rounds to shrink, not the even ones (under the 3-round huge-diff cap — the reduction a run earns only when it has an explicit deadline — only round 3 can shrink, because the cap ends the loop before round 5). The manifest's recorded keys are the round; the `retirement:` note on stderr names each skipped chunk and its certificate — relay that note in your narration, and do not hand-build an auditor for a chunk the builder skipped. Why, measured: on a real 6-chunk run, two chunks were dry in **all five rounds** — a third of the loop's auditors re-certifying territories that had already converged, while the three hot chunks were where every finding came from. Attention follows evidence; the certificate a retired chunk holds (two consecutive substantive dry audits) is exactly the one the whole loop used to end on.
|
|
787
|
+
- **The builder schedules the 3B fan-out; you do not.** Rounds 1 and 2 audit every chunk — they are what establishes each territory's record. From round 3 on, `--all-chunks` reads the harness transcripts and **retires** any chunk whose own last two audits were substantively dry (the receipt named what it examined AND the transcript shows the diff was opened): a retired chunk is cold-checked on alternating rounds instead of every round, and a cold check that yields anything returns it to every-round auditing. The savings land on the odd rounds — every retired chunk cold-checks together on the even ones, so an even round's fan-out is unchanged; expect the odd rounds to shrink, not the even ones (under the 3-round huge-diff cap — the reduction a run earns only when it has an explicit deadline — only round 3 can shrink, because the cap ends the loop before round 5). The manifest's recorded keys are the round; the `retirement:` note on stderr names each skipped chunk and its certificate — relay that note in your narration, and do not hand-build an auditor for a chunk the builder skipped. On a **fix-audit round** the schedule additionally narrows the wave (#10104): from round 3, a chunk holding no delta file leaves the schedule after **one** substantive dry launch (every member of it dry — rounds 1 and 2, the convergence pair, are one launch, so a dry pair member never counts beside a yielding or uncertified partner whose findings it was built before — and not built on the same findings-list bytes as an earlier round with a yielding or uncertified member, nor built before an earlier return that was not dry came back, nor run in a different session from any return on record that was not dry, or beside one no session stamped — across a `--resume` only recovery carries such a return onto the list) and takes no cold checks — the wave re-launches the delta territories under the ordinary retirement rules (a twice-dry one only on its cold-check rounds) and every non-delta chunk the previous waves could not certify dry (one that yielded, one whose latest receipt is uncertified, or one with no audit history stays in the wave; one whose dry receipt shares its launch or its list bytes with a yield or uncertified receipt, was built before one came back, or ran in a different session from one, returns to the ordinary retirement rules), which trades the cold-check recall the posture has already priced (everything below Critical defers, except the pre-confirmed deterministic findings the floor leaves inline by the tag on their claim line) for waves that keep running to the same cap over a shrinking front; on such a round the even-round parity claim above holds for delta territories only — a narrowed non-delta chunk never returns, on any parity. The `posture narrowing:` note on stderr names each narrowed chunk; relay it exactly as you relay the retirement note, and hand-build nothing it skipped. Why, measured: on a real 6-chunk run, two chunks were dry in **all five rounds** — a third of the loop's auditors re-certifying territories that had already converged, while the three hot chunks were where every finding came from. Attention follows evidence; the certificate a retired chunk holds (two consecutive substantive dry audits) is exactly the one the whole loop used to end on.
|
|
787
788
|
|
|
788
789
|
One anomaly the builder flags but does not refuse (#9242): a per-chunk build on a plan whose own `srcDiffLines`/`diffLines` say Step 3A prints a stderr note — the plan's numbers price one whole-diff auditor per round (the reverse-audit round cap reads them), yet per-chunk auditors were built. It fires on `--all-chunks` and on a `--chunk` build of a round that has no admission stamp yet; a stamped round's `--chunk` rebuilds are exempt — their fan-out was ruled on at admission. If the note fires and the fan-out is deliberate — you decided against the plan's numbers (the routing is yours, as Step 1 says), or this is a whole-round `--all-chunks` rebuild of an already-admitted round on a hand-maintained plan — say so in the round; if it was not deliberate, stop and re-derive the topology from Step 1 instead of spending a fan-out the plan never owed.
|
|
789
790
|
|
|
@@ -831,12 +832,12 @@ On a resumed run (Step 1's `--resume`), the loop re-enters at `latestReverseAudi
|
|
|
831
832
|
- A round is **dry** only when _every_ agent in it returned zero new findings **with** the evidence-bearing receipt (`No issues found — <what it re-examined>`). A round containing a twice-whiffed agent is **not dry** — silence is not convergence evidence — so the loop continues (the hard cap below still bounds it).
|
|
832
833
|
- **When the loop ends with any scope still outstanding** (by cap, or by dry rounds elsewhere), terminal prose is not enough: add one self-explained entry per scope to `unreviewedDimensions` — e.g. `reverse audit of chunk 3 — the auditor returned nothing substantive twice` — so compose-review serializes it and caps a would-be Approve at `COMMENT`. The primary Step 3 pass did read that scope (its receipt stands), but this run's contract includes the reverse audit, and a verdict must not silently claim an audit that never ran.
|
|
833
834
|
- Stop after **two consecutive dry rounds** (the 3A criterion — one auditor, so round-dry and territory-dry are the same thing). One dry round is not evidence of convergence: on PR #6457 the review returned "no blockers" twice and the very next round surfaced five Criticals, three of them in code that had been in the diff since the first commit. A single lazy agent must not be able to end the loop. A dry convergence pair satisfies this rule in one launch — its two members are exactly the two independent audits the rule demands; what the pair removes is the wall clock between them, not either audit. When the loop ends on this rule, the last reporting round's verifiers are already in flight (they launched with the next round's auditors) — wait for their verdicts and apply them in the final merge before Step 6.
|
|
834
|
-
- **On the 3B path the builder is also the convergence ledger**: when every chunk holds two consecutive substantive dry audits and none is due a cold check, `--all-chunks` builds nothing, prints a `CONVERGED` explanation to stderr and exits **5**. Stop the loop and proceed to Step 6 — this is a **clean** convergence, not a gap: no `unreviewedDimensions` entry is owed, because each chunk holds the two-dry rule's evidence chunk by chunk — two consecutive dry **audits**, though not necessarily in consecutive rounds (a chunk dry in rounds 1 and 2 skips round 3 and cold-checks dry in round 4, holding rounds 2 and 4). If an earlier round-cap or budget refusal told you to add its stop entry to `unreviewedDimensions`, remove it now — this convergence supersedes that stop (the marker on disk is cleared the same way). Exit 5 is mainly the CLI enforcing the stop the two-dry-rounds rule above used to leave to orchestrator discretion; the new savings are the odd-round skips and a convergence at the cap round (round 5 on a 3B diff, round 3 under the huge-diff cap when the run has an explicit deadline and round 5 when it does not — this ledger is 3B's, so the 3A tier's ten never applies here). (It cannot owe a verification launch: a reporting round makes its chunk hot, so every verifier launched with a later round that did run.)
|
|
835
|
+
- **On the 3B path the builder is also the convergence ledger**: when every chunk holds two consecutive substantive dry audits and none is due a cold check — or, on a fix-audit round, when every non-delta chunk has been posture-narrowed out on its single dry launch or retired under the ordinary rules, every delta chunk is retired, and none is due a cold check — `--all-chunks` builds nothing, prints a `CONVERGED` explanation to stderr (naming any chunk narrowed out that round, since no round output carries the `posture narrowing:` note for it) and exits **5**. Stop the loop and proceed to Step 6 — this is a **clean** convergence, not a gap: no `unreviewedDimensions` entry is owed, because each retired chunk holds the two-dry rule's evidence chunk by chunk — two consecutive dry **audits**, though not necessarily in consecutive rounds (a chunk dry in rounds 1 and 2 skips round 3 and cold-checks dry in round 4, holding rounds 2 and 4) — and each posture-narrowed chunk holds its one dry launch, the recall trade the posture already discloses in its `posture narrowing:` note and the posted round-shape paragraph. If an earlier round-cap or budget refusal told you to add its stop entry to `unreviewedDimensions`, remove it now — this convergence supersedes that stop (the marker on disk is cleared the same way). Exit 5 is mainly the CLI enforcing the stop the two-dry-rounds rule above used to leave to orchestrator discretion; the new savings are the odd-round skips and a convergence at the cap round (round 5 on a 3B diff, round 3 under the huge-diff cap when the run has an explicit deadline and round 5 when it does not — this ledger is 3B's, so the 3A tier's ten never applies here). (It cannot owe a verification launch: a reporting round makes its chunk hot, so every verifier launched with a later round that did run.)
|
|
835
836
|
- Stop at the plan's **`reverseAuditRounds` cap** — 10 on a 3A diff, 5 on a 3B one, and 3 for a huge diff (effective ≥ 3000 lines) **when the run has an explicit deadline** (CI's, or `--deadline` at capture), 5 under the plan's default wall (the huge reduction answers a six-hour ceiling, so it applies only where there is one; the default wall is a liveness bound, not a ceiling) — and say so in the output rather than implying convergence. The cap is per topology because it prices a round, and a 3A round is one auditor where a huge-diff round is ~90 minutes; you never work this out yourself, the builder reads the plan's tier. The builder enforces this itself: a round past the cap gets a `ROUND CAP:` refusal on stderr and exit **4**, and — like the time-budget gate — writes a marker `compose-review` caps the verdict on whether or not you relay anything; still add the entry the message names to `unreviewedDimensions` so the terminal report agrees. If the cap round reported findings, its verifiers have NOT launched — that launch rides the next round's build, which the cap forbids — so verify them before Step 6 through `agent-prompt --role verify` **only** (never a hand-rolled agent), under the same bounded tail as the budget stop below: that builder is gated on the compose floor and refuses once too little time remains, and the generated workflow bounds its launch-time allowance by the remaining deadline (the environment's epoch) minus that floor; when it ends, compose with the tags in hand — no fresh re-verification pass, and nothing already confirmed re-verified. This matters most on exactly the huge diffs the cap targets: a time-budgeted CI run that stops at the cap with ~30-90 minutes left must not spend it on an unbounded tail and die before compose. The tag backstop below (and `compose-review`'s machine-read of it) is what catches a miss.
|
|
836
837
|
- Findings **reported** by each round are merged into the cumulative list **before** the next round begins, so each round sees an updated baseline. **The merge runs unconditionally — before every round build and before Step 6, whether or not the previous round reported findings**: under the pipelined loop below, round _k_'s verdicts land during round _k+1_, and every termination mode (two dry rounds, CONVERGED, budget stop, the round cap) can arrive with the final rounds dry — a merge keyed to "some round reported something" would never apply the last verdicts that landed. Each merge applies every Step 4 verdict that has landed: confirmed removes the tag, rejected removes the entry. Verification status does not gate the merge — the list exists so auditors do not re-report what is already filed, and an unverified entry serves that purpose exactly as well as a confirmed one. The trade, named: an entry a verifier later rejects will have suppressed one round of rediscovery in its neighbourhood — the window is one round in one location, and the plan's round cap still bounds the loop. The tag is what keeps this mechanical rather than remembered: an entry enters the list tagged `— [unverified]`; the merge after its Step 4 verdict removes the tag (confirmed) or the entry (rejected). Step 6's confirmed-only read then has something to key on — anything still tagged is left out of the confirmed set — instead of a memory of which round each entry arrived in. The tag rides inside the findings file, which is hashed into the record key and copied to the digest-named list file each block points at — so a launch that drops the pointer matches no record, and the delivery floor counts the agent's read of that file exactly as it counts the brief's.
|
|
837
838
|
- **A reporting round whose every finding the verifier rejected is retroactively dry.** The merge already removes a rejected entry from the cumulative list; from the merge that applies the last of a round's rejections, the round also stops counting as a reporting round, and the two-consecutive-dry rule reads rounds' **effective** status. Rejected means rejected — an entry confirmed at low confidence keeps its round a reporting round. Under the pipelined loop a round's verdicts land while the next round runs, so the upgrade usually arrives one round late, and that is still one round saved: a measured run held round 2 dry, watched round 3's sole finding be rejected, and then ran rounds 4 **and 5** — round 4's dry return plus the rejection already in hand was the two-dry evidence, and the fifth round audited nothing the loop had not already answered (measured; DESIGN.md — The rounds a rejected finding bought (PR #8353)). The rule leans on the rejection bar the verifier's brief already enforces — a rejection claims direct counter-evidence, never mere unverifiability — so a round retired by rejections is retired on evidence, not on doubt. **It pairs forward only, and is consulted when a round returns**: on round _k_'s dry return, first apply every verdict that has landed (the unconditional merge — the retirement takes effect at this application, not at some earlier moment), then end the loop if round _k−1_ was dry or is now retired. Round _k−1_ counts **launches, not labels**: the convergence pair is one round here — a pair member is never round _k−1_ on its own (the pair bullet's not-carried-forward rule stands), and a reporting pair retires only when every finding from **both** members is rejected. The upgrade never ends the loop by itself — a preceding dry round plus a freshly-retired round stops nothing while the next round is already in flight: that round was launched, and its return is taken whatever it says, because a launched auditor can be carrying a real Critical. This is the measured shape (round 4's return is where the loop closes under this rule — the measured run, which predates it, ran a fifth round; a cap-5 shape — under the 3-round huge-diff tier, which a run only gets when it has an explicit deadline, the upgrade can only ever retire rounds 1–2, since the cap round's verdicts land during its solo verification, after the loop has already ended) and the only pairing licensed here. It softens nothing else: a whiffed scope stays not-audited whatever the verdicts say, and on 3B the retirement ledger's per-chunk certificates are untouched — this rule reads at the level the round counter reads.
|
|
838
839
|
- **Verification rides alongside the next round, not ahead of it.** When round _k_ returns with new findings, one generated workflow launches BOTH round _k_'s verifiers (Step 4, `--role verify --round k` with that round's new findings) AND round _k+1_'s auditors — build the two sets with `--batch`, combine their successful manifests with `emit-workflow --batch`, then invoke ONE foreground workflow. (Step 4's initial verification is the k=0 case of the same rule: its shards ride with the first reverse-audit launch — the convergence pair, whole-diff on 3A and per-chunk rounds 1 and 2 on 3B. The convergence pair is the one exception on the LAUNCH side: a pair member's return never triggers this rule per member — round 2's auditors are already in flight — and the pair bullets above define the one transition; the pair's findings still verify as the k=2 case, riding round 3.) The serial shape (audit → wait for verification → next round) spent 5-8 minutes per round waiting for verifiers whose results the next round's auditors never needed. The overlap is what puts a verifier's writes and an auditor's reads in the same tree at the same moment, which is why the verifier's probes run in its own scratch tree (Step 4) rather than in the worktree the auditors are reading (#9207). Two orderings still hold: the **last** round's verification must complete before Step 6 (that ordering is what keeps unverified entries out of the report and the PR, backed by the tag backstop at the end of this step — which `compose-review` machine-checks from `findingsPath`, Step 6), and a rejected finding leaves the cumulative list at the next merge.
|
|
839
|
-
- **The round builder is also the loop's clock.** Every run has one: CI exports `QWEN_REVIEW_DEADLINE_EPOCH`, and a capture without it records the plan's own wall — an operator's `--deadline <minutes>` on the capture command (not a flag for you to add), or the
|
|
840
|
+
- **The round builder is also the loop's clock.** Every run has one: CI exports `QWEN_REVIEW_DEADLINE_EPOCH`, and a capture without it records the plan's own wall — an operator's `--deadline <minutes>` on the capture command (not a flag for you to add), or the size tier's default (8h on a 3A-sized diff, 12h on a 3B-sized one, 16h when huge — keyed on the diff's lines, so a fix-audit round's territory fan-out keeps the wall its delta's size earns) — as a duration from the current attempt's start, so a `--resume` that starts a new session renews it; only `--deadline none` records no plan wall — and even that run stays clocked, explicitly so, wherever the environment exports an epoch (CI's wins over both). The default is sized above what a healthy run at the round cap spends, so it bounds a loop that has stopped converging and never a healthy one. Against whichever wall resolved, `agent-prompt --role reverse-audit` refuses to build a round that no longer fits: the remaining time must cover **the round itself** (estimated from the costliest round's measured cost so far — a repair relaunch can make one round the expensive one, and the gate prices the worst case the run has proved, not the newest dip — or a conservative constant for round 1) **plus** the reserve kept for its verification, compose-review and submission. On refusal it prints a `BUDGET:` line to stderr and exits **4**. That refusal is a termination rule, not an error — do not rebuild the round, do not relaunch auditors, and do not retry the command. The builder also records a budget-stop marker that `compose-review` reads directly, so the verdict is capped whether or not you relay anything; still add the exact entry the message names (`reverse audit — stopped before round <k> by the review time budget`) to `unreviewedDimensions` so the terminal report and the body agree, and proceed to Step 6. **The tail after a budget stop is bounded, and its order is load-bearing.** Verify the last round's findings — the ones whose verifiers would have ridden the round the gate just refused — **only through `agent-prompt --role verify`, never a hand-rolled `agent`**: that builder is gated on a **compose floor** and prints a `VERIFY BUDGET:` refusal (exit 4) once too little time remains, at which point you stop verifying and compose **immediately** — findings still carrying `— [unverified]` keep the tag, and `compose-review` caps the verdict on it and never treats an unverified finding as a confirmed blocker; everything earlier rounds confirmed still posts. **The workflow bounds the wait as well as the launch:** generated review workflows cap their launch-time allowance at the remaining deadline minus the compose floor — reading the environment's epoch; under a plan-recorded wall the allowance is the workflow's own default, and the wall bounds the round builder and the verifier. Keep the call foreground; after a timeout or partial failure, recover any completed verifier results from the ordinary transcripts before the final merge. Findings without a verdict retain `— [unverified]`, exactly as after a refused build. Do not abandon a running workflow or clean its worktree while children still use it. Interactive pauses can extend elapsed time; the outer CI timeout remains the final wall. Do **not** re-verify findings already confirmed in earlier rounds, and do **not** invent a fresh re-verification pass — that is the unbounded work a wall runs into. Compose and submit are non-negotiable; they always run. Why this exists, measured twice: a +1699-line PR's CI review ran the audit loop to the 5-round cap and was killed while round 5's findings were still being verified (#8368); and a 4,269-line cross-worktree git guard stopped the audit correctly with ~110 minutes left, then a single hand-rolled agent re-running a 15-family shell/git bypass battery with real filesystem E2E consumed all of it — the wall hit mid-verification, compose never ran, and ~20 E2E-confirmed Critical bypasses were never posted (measured; DESIGN.md — The killed-before-compose tail (PR #8687)). A review that stops on the budget still reports everything it proved; one that runs past it reports nothing.
|
|
840
841
|
|
|
841
842
|
**Reverse audit findings go through Step 4 verification like any other finding.** They used to skip it on the theory that the auditor "already has full context." That premise fails exactly when the diff is large — the auditor with the least room to think was the one whose output nobody checked.
|
|
842
843
|
|
|
@@ -921,7 +922,7 @@ Render the rulings as a short table at the top of the Findings section — id, o
|
|
|
921
922
|
|
|
922
923
|
**A re-review that keeps posting new non-Critical findings is the motor of a feedback loop this pipeline has measured from the outside**: every push triggers a fresh review, the review files findings on code the previous round just added, the next push implements them, and the diff widens — which allocates more agents, which file more findings. One managed PR rode that loop to +13k lines across 8 rounds with its per-round Critical count flat, and was closed unmerged; the growth was 78–86% test lines. Bug-finding never converges a loop — only the **posting bar** can, and it must rise as rounds accumulate, exactly the discipline a senior reviewer applies by hand ("after ~5 rounds, only blockers; defer the rest, on the record"). This posture is that discipline, made the default. It governs **what posts to the PR**, never what is found, verified, or reported in the terminal: `RECALL` still binds every finder, Step 4 still verifies, the artifact and the terminal report still carry everything.
|
|
923
924
|
|
|
924
|
-
**Resolve the floor first.** The Step 1 verdict's `severityFloor` is `critical`, `suggestion`, or `auto`. Explicit values are the operator's call: `critical` applies the Critical-only posture from round 1; `suggestion` turns the posture **off** — every round posts Suggestions, and the code-age rule below does not run. `auto` — the default — resolves here, where the round is known: **this review is round `prev ledger round + 1`**, and the round that decides the posture is the SIDE FILE's — the same read `compose-review` stamps into the marker and the deferral clause; the local cache's round scopes the diff but never decides the posture, or the body and the marker would disagree about which round ran (no recovered ledger → round 1 → no posture). Through round 5 the floor is `suggestion`; **from round 6 it is `critical`** — **and it is `critical` from ANY round once the side file's `flatRounds` is at its bar of 2**. That streak is the signal-driven early trigger: `compose-review` measures each round's first-time-finding rate against the previous round's, stamps the consecutive not-falling count into the marker as `flatRounds`, and engages the floor ahead of schedule when the count reaches 2 — acting on the convergence paragraph's own "drop to `--severity-floor critical`" advice instead of only printing it. You cannot evaluate that trend yourself (it is a deterministic join over the ledger, which is exactly why the module owns it), so your routing follows the **marker**: `flatRounds >= 2` in the side file means the floor is `critical` for this round and every later round of this PR — route Suggestions to the deferral channel accordingly. On the round the streak first reaches the bar you will usually have drafted under the open posture; the enforcement backstop below moves those Suggestions mechanically and the posted body discloses the move with the streak that armed it — that is the trigger working, not a lost finding. Once engaged the trigger **latches**: the streak is pinned in the marker rather than re-measured (the floor itself quiets the posted-set trend it reads), so it does not release on a quiet round — an explicit `--severity-floor suggestion` remains the only way back to full posting. In the **context-unavailable** state the round is unknowable — the ledger this rule counts from could not be recovered by a run that could not read the PR — so treat `auto` as round 1: no posture, full posting, and say so in the terminal report (the deterministic marker still stamps its own count from the side file; a posting bar in doubt fails open, bookkeeping does not). Carry the **verdict's `severityFloor` into the compose state UNRESOLVED** — explicit values as they are, and `auto` as the literal string `auto`, never as the level it resolved to this round: the module licenses `auto` by the round it derives itself, and a round-resolved `suggestion` is indistinguishable from the operator's explicit posture-off override — passing it would turn every legal rounds-2–5 age-rule deferral into an unlicensed one. The resolution in this paragraph decides what YOU post; the state field carries the policy. **The module also enforces the floor itself**: a Suggestion still drafted inline past a resolved `critical` floor is moved into the deferral list mechanically by `compose-review`/`submit` (the composed result's `floorEnforced` names the moved indices, the posted body discloses the move, and `submit` drops those comments from the write). Your Step 6 routing stays the primary path — the enforcement is the backstop that keeps the posted set lawful when the routing drifts, so a submit report showing fewer inline comments than you drafted under a critical floor is the floor working, not a lost finding. Three consequences of it being mechanical: the backstop classifies by the drafted severity MARKER alone — it cannot re-derive confidence or a Nice-to-have, so keeping low-confidence and Nice-to-have findings OUT of the drafted comments (as this step already mandates) is what keeps them out of the published deferral list too; **leave moved comments IN the comments file and the submit payload** — the CLI removes them from the write itself, and hand-removing them "to match" makes both boundaries recompute over the reduced set and erases the deferral record the move exists to keep; and the floor it enforces is the RESOLVED one (an explicit `critical`, `auto` from round 6,
|
|
925
|
+
**Resolve the floor first.** The Step 1 verdict's `severityFloor` is `critical`, `suggestion`, or `auto`. Explicit values are the operator's call: `critical` applies the Critical-only posture from round 1; `suggestion` turns the posture **off** — every round posts Suggestions, and the code-age rule below does not run. `auto` — the default — resolves here, where the round is known: **this review is round `prev ledger round + 1`**, and the round that decides the posture is the SIDE FILE's — the same read `compose-review` stamps into the marker and the deferral clause; the local cache's round scopes the diff but never decides the posture, or the body and the marker would disagree about which round ran (no recovered ledger → round 1 → no posture — unless the plan's own fix-audit record resolves it; see the plan-time half below). Through round 5 the floor is `suggestion`; **from round 6 it is `critical`** — **and it is `critical` from ANY round once the side file's `flatRounds` is at its bar of 2**. Since #10104 this resolution also has a **plan-time half**: `fetch-pr` predicts it from the same facts (the side file's round and `flatRounds`, or the invocation's recorded explicit floor — only the monotone arms) and, when it resolves critical beside a usable anchor, runs the round in the fix-audit shape and records `incremental.posture` in the plan. The plan record is then itself an arm of THIS resolution — a fix-audit plan resolves the `auto` floor to critical even where the two arms above cannot re-derive it (a context-unavailable compose, a rewritten side file), so the posting bar can never disagree with the shape the round already ran; an explicit `suggestion` floor still wins. `compose-review` discloses the reduced shape (and, on the explicit-suggestion divergence, the open floor) in the posted body on its own — you never write that sentence by hand. That streak is the signal-driven early trigger: `compose-review` measures each round's first-time-finding rate against the previous round's, stamps the consecutive not-falling count into the marker as `flatRounds`, and engages the floor ahead of schedule when the count reaches 2 — acting on the convergence paragraph's own "drop to `--severity-floor critical`" advice instead of only printing it. You cannot evaluate that trend yourself (it is a deterministic join over the ledger, which is exactly why the module owns it), so your routing follows the **marker**: `flatRounds >= 2` in the side file means the floor is `critical` for this round and every later round of this PR — route Suggestions to the deferral channel accordingly. On the round the streak first reaches the bar you will usually have drafted under the open posture; the enforcement backstop below moves those Suggestions mechanically and the posted body discloses the move with the streak that armed it — that is the trigger working, not a lost finding. Once engaged the trigger **latches**: the streak is pinned in the marker rather than re-measured (the floor itself quiets the posted-set trend it reads), so it does not release on a quiet round — an explicit `--severity-floor suggestion` remains the only way back to full posting. In the **context-unavailable** state the round is unknowable — the ledger this rule counts from could not be recovered by a run that could not read the PR — so treat `auto` as round 1: no posture, full posting, and say so in the terminal report — unless the plan carries its own fix-audit record, which resolves the floor to critical even here (the deterministic marker still stamps its own count from the side file; a posting bar in doubt fails open, bookkeeping does not). Carry the **verdict's `severityFloor` into the compose state UNRESOLVED** — explicit values as they are, and `auto` as the literal string `auto`, never as the level it resolved to this round: the module licenses `auto` by the round it derives itself, and a round-resolved `suggestion` is indistinguishable from the operator's explicit posture-off override — passing it would turn every legal rounds-2–5 age-rule deferral into an unlicensed one. The resolution in this paragraph decides what YOU post; the state field carries the policy. **The module also enforces the floor itself**: a Suggestion still drafted inline past a resolved `critical` floor is moved into the deferral list mechanically by `compose-review`/`submit` (the composed result's `floorEnforced` names the moved indices, the posted body discloses the move, and `submit` drops those comments from the write). Your Step 6 routing stays the primary path — the enforcement is the backstop that keeps the posted set lawful when the routing drifts, so a submit report showing fewer inline comments than you drafted under a critical floor is the floor working, not a lost finding. Three consequences of it being mechanical: the backstop classifies by the drafted severity MARKER alone — it cannot re-derive confidence or a Nice-to-have, so keeping low-confidence and Nice-to-have findings OUT of the drafted comments (as this step already mandates) is what keeps them out of the published deferral list too; **leave moved comments IN the comments file and the submit payload** — the CLI removes them from the write itself, and hand-removing them "to match" makes both boundaries recompute over the reduced set and erases the deferral record the move exists to keep; and the floor it enforces is the RESOLVED one (an explicit `critical`, `auto` from round 6, `auto` with the `flatRounds` streak at its bar, or a literal `auto` beside the plan's fix-audit record — the enforcement reading fails open on an ABSENT floor field even beside that record, and the posted body then says the floor resolved open while the plan record alone still licenses the deferral list), recovered where possible from the CLI's own record of the invocation rather than the state field alone.
|
|
925
926
|
|
|
926
927
|
**At floor `critical`, a non-Critical finding that would otherwise post is recorded, not requested.** The deferrable set is exactly the set the floor takes away: **high-confidence Suggestions** — the findings a `suggestion`-floor round would have drafted inline — plus, at floor `critical` only, the fails-closed/new-surface Criticals described below. Low-confidence findings and Nice-to-haves were never posted at any floor and **stay terminal-only exactly as before**: routing them through the deferral list would _publish_ to the PR what the review contract keeps out of it, and inflate the list the posture exists to keep small. A deferred finding has been through Step 4 like any posted one — the deferral list publishes its one-line claims in the body, so `compose-review`'s verifier-delivery floor counts deferred findings exactly as posted ones; an unverified claim does not become publishable by being deferred. (Deterministic findings are the exception on the verifier's side, and for Suggestions on the floor's side too: a `[build]`/`[test]`/`[probe]` finding is pre-confirmed, Step 4 launches no verifier for it, and the floor's source exclusion leaves a deterministic Suggestion inline — by its `source` field; a deterministic Critical the axes classify defers like any other axes-Critical, its source riding the entry.) Each deferred finding stays in the findings artifact and the terminal report under its own grouping — "Deferred (convergence posture)" — and enters the compose state's `deferredSuggestions` as a **TYPED entry, one object per finding, copied from the artifact's own fields**: `{"file": "src/a.ts", "line": 42, "source": "test", "severity": "Suggestion", "title": "mutation survivor on the retry guard"}` (`line` optional; a pattern aggregate adds `"locations": N` for its further locations). This is a data field, not a sentence: `compose-review` derives deterministic from `source`, relocates a `severity: "Critical"` entry into the body Criticals unless it is the fails-closed, new-surface shape at floor `critical` (below), refuses a `"Nice to have"` (terminal-only) or any malformed entry, and RENDERS the human line `file:line — [source] title` itself — never write that line into the state, and never re-type the fields: read them out of the findings artifact you just wrote. It is **not** drafted into the `comments` array, **not** counted toward `S`, and casts no vote on the event: `compose-review` renders the list as a disclosed, non-capping paragraph — up to 20 entries, each capped at 240 characters, with an overflow count pointing at the run report — so the deferral is on the PR record without opening a thread that regenerates a round, and anything past the rendered cap survives in full in the findings artifact and the terminal report (say so there when the cap trims the list). A previous-round **non-Critical** ledger entry that still stands is ruled in the status table as `still stands — deferred (convergence posture)` and is likewise not re-posted; it leaves the machine ledger (`buildLedger` ingests only posted findings), and the deferral list plus the original round's thread remain its record. **A Critical is deferred by its axes, never by its severity — and only at floor `critical`.** The severity bit alone carried three decisions in one — which way the defect fails, what it is measured against, how often it triggers — and past the convergence rounds everything that mattered still landed on the floor, so the floor filtered nothing and the loop oscillated instead of settling (measured; DESIGN.md — The floor that could not floor (#9659)). Two of those axes now travel with the finding (Step 4's verifier states them off its witness; the artifact carries them as `direction` and `baseline`), and the floor reads them: a Critical whose artifact entry carries `direction: fails-closed` AND `baseline: new-surface` — the change narrows what works, in a surface the merge base never had, so merging it certifies nothing false and regresses nothing — is recorded, not requested, exactly like a Suggestion: a typed `deferredSuggestions` entry with `severity: "Critical"` and both axes copied from the artifact, under its own `D<round>-<n>` artifact id, its `title` opening with the original `R<round>-<n>` id when it carries a still-standing entry forward (the closure mint reads the id there — an id-less re-post silences that round's lineage). Every other Critical posts: `certifies-falsely` at either baseline (the code lies — that is the core promise broken, whatever surface it lives in), `regression` in either direction (the merge base did it right, and a merge gate grades against the merge base), a Critical with either axis missing or self-contradicting (the floor cannot classify it, and a blocker in doubt posts), and every Critical at any floor below `critical` — the rounds-2–5 code-age rule never touches a Critical. `compose-review` holds the same rule in code: a `Critical` entry that is not both `fails-closed` and `new-surface`, or that arrives when the floor is not in effect, is relocated into the body Criticals and posts; and the enforcement backstop moves a drafted `**[Critical]**` comment whose claim line carries both the `[fails-closed]` and `[new-surface]` tags (Step 7 puts them there from the artifact) exactly as it moves a Suggestion, naming the move by severity in the disclosure. The deferred Critical's record is the same as a deferred Suggestion's — the posted deferral line (which names it `Critical` and shows its tags), the findings artifact entry, the terminal report — and it is follow-up work the author files as an issue, not work this round requests; no issue is filed by the review. Everything else about Criticals is unchanged: new Criticals that post still post, still-standing ledger Criticals re-post under their original ids, and every Critical ruling above runs unchanged — with one addition to the routing: the side file's work-list table shows a carried Critical's recorded axes beside its severity (`Critical (fails-closed, new-surface)`), so a still-standing entry of that shape at a `critical` floor goes to the deferral channel rather than being re-posted. An APPROVE composed over a non-empty deferral list opens "No blocking issues" instead of "No issues found" — `compose-review` owns that wording.
|
|
927
928
|
|
|
@@ -7,89 +7,93 @@ import {
|
|
|
7
7
|
} from "./chunk-ABCG62RK.js";
|
|
8
8
|
import "./chunk-4EHHWHWX.js";
|
|
9
9
|
import "./chunk-SV5PQVQE.js";
|
|
10
|
+
import "./chunk-GDNW7RE4.js";
|
|
10
11
|
import "./chunk-4GG4IOFX.js";
|
|
11
12
|
import "./chunk-5QWWOFGG.js";
|
|
12
|
-
import "./chunk-GDNW7RE4.js";
|
|
13
13
|
import "./chunk-47ECGEJC.js";
|
|
14
14
|
import "./chunk-2MIN6GRR.js";
|
|
15
15
|
import "./chunk-QHTIBUWB.js";
|
|
16
16
|
import "./chunk-RKUWKYED.js";
|
|
17
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-5AMF3QJJ.js";
|
|
18
18
|
import "./chunk-GELRJXE2.js";
|
|
19
19
|
import "./chunk-32CM56LO.js";
|
|
20
|
-
import "./chunk-
|
|
20
|
+
import "./chunk-O4OOA2XB.js";
|
|
21
|
+
import "./chunk-MNM5AZTY.js";
|
|
21
22
|
import "./chunk-LJZSMWOH.js";
|
|
22
|
-
import "./chunk-
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-
|
|
23
|
+
import "./chunk-G4DQHGSF.js";
|
|
24
|
+
import "./chunk-WMHO25KU.js";
|
|
25
|
+
import "./chunk-IODSADQ4.js";
|
|
25
26
|
import "./chunk-ZPJWUGCS.js";
|
|
26
27
|
import "./chunk-N7RPJIQD.js";
|
|
27
|
-
import "./chunk-WQ3SH63I.js";
|
|
28
|
-
import "./chunk-A27BXP6Y.js";
|
|
29
|
-
import "./chunk-CK267TVO.js";
|
|
30
|
-
import "./chunk-BDUAP5PL.js";
|
|
31
|
-
import "./chunk-E5JQUFYU.js";
|
|
32
|
-
import "./chunk-UEILASYG.js";
|
|
33
28
|
import "./chunk-W6VNPRE2.js";
|
|
34
|
-
import "./chunk-
|
|
35
|
-
import "./chunk-
|
|
29
|
+
import "./chunk-TW7KLLRI.js";
|
|
30
|
+
import "./chunk-FPFIAK47.js";
|
|
31
|
+
import "./chunk-OOGQBSTQ.js";
|
|
32
|
+
import "./chunk-PPLSJANE.js";
|
|
33
|
+
import "./chunk-ZWMLPCLV.js";
|
|
34
|
+
import "./chunk-UEILASYG.js";
|
|
35
|
+
import "./chunk-AV3FOXNF.js";
|
|
36
|
+
import "./chunk-WJ6HMAU7.js";
|
|
36
37
|
import "./chunk-V2XJJTAB.js";
|
|
38
|
+
import "./chunk-V4VSJQKD.js";
|
|
39
|
+
import "./chunk-BHU5SD32.js";
|
|
37
40
|
import "./chunk-ZNU4EOFS.js";
|
|
38
|
-
import "./chunk-FOVMGIL4.js";
|
|
39
|
-
import "./chunk-T4D3QLUZ.js";
|
|
40
41
|
import "./chunk-BVKUGIV3.js";
|
|
41
42
|
import "./chunk-YDERQ7ZV.js";
|
|
42
43
|
import "./chunk-TV2CMWO3.js";
|
|
43
44
|
import "./chunk-ORREOG2Q.js";
|
|
44
|
-
import "./chunk-
|
|
45
|
-
import "./chunk-
|
|
45
|
+
import "./chunk-Z6Y6SFX7.js";
|
|
46
|
+
import "./chunk-LWQKWO5I.js";
|
|
46
47
|
import "./chunk-27CVFKVI.js";
|
|
47
48
|
import "./chunk-GOFAQQZA.js";
|
|
48
|
-
import "./chunk-
|
|
49
|
+
import "./chunk-CHBZHMBA.js";
|
|
50
|
+
import "./chunk-4M7RD5QQ.js";
|
|
49
51
|
import "./chunk-HEOH7JZY.js";
|
|
50
|
-
import "./chunk-TWPJO254.js";
|
|
51
52
|
import "./chunk-XIOVKC72.js";
|
|
53
|
+
import "./chunk-W3RO6OK2.js";
|
|
52
54
|
import "./chunk-MHXRBBKA.js";
|
|
55
|
+
import "./chunk-L3KJT4ZZ.js";
|
|
56
|
+
import "./chunk-JBUMBQAO.js";
|
|
53
57
|
import "./chunk-GMYY5C2E.js";
|
|
54
58
|
import "./chunk-5EZRLTLQ.js";
|
|
55
59
|
import "./chunk-QHWCP53L.js";
|
|
56
60
|
import "./chunk-DTAGMOBI.js";
|
|
57
|
-
import "./chunk-
|
|
58
|
-
import "./chunk-
|
|
61
|
+
import "./chunk-U5P7R5TF.js";
|
|
62
|
+
import "./chunk-AJSG5SMC.js";
|
|
59
63
|
import "./chunk-6PVPNMXU.js";
|
|
60
|
-
import "./chunk-L3KJT4ZZ.js";
|
|
61
|
-
import "./chunk-ANKISCKU.js";
|
|
62
64
|
import "./chunk-U6H3XTFA.js";
|
|
63
65
|
import "./chunk-AO66AVEJ.js";
|
|
64
66
|
import "./chunk-3RCEJIII.js";
|
|
65
|
-
import "./chunk-
|
|
66
|
-
import "./chunk-
|
|
67
|
-
import "./chunk-
|
|
68
|
-
import "./chunk-O6GEWCJA.js";
|
|
69
|
-
import "./chunk-CHEIIBT3.js";
|
|
67
|
+
import "./chunk-JXNPH2EP.js";
|
|
68
|
+
import "./chunk-IQQRNRQV.js";
|
|
69
|
+
import "./chunk-QBLHSEIA.js";
|
|
70
70
|
import "./chunk-ADN5KESB.js";
|
|
71
71
|
import "./chunk-SK3RZOPS.js";
|
|
72
72
|
import "./chunk-GO3DNGM3.js";
|
|
73
73
|
import "./chunk-ELRMZTPF.js";
|
|
74
|
-
import "./chunk-
|
|
75
|
-
import "./chunk-
|
|
76
|
-
import "./chunk-
|
|
74
|
+
import "./chunk-2SENA3WV.js";
|
|
75
|
+
import "./chunk-ELYIK7SN.js";
|
|
76
|
+
import "./chunk-TWPJO254.js";
|
|
77
|
+
import "./chunk-O6GEWCJA.js";
|
|
78
|
+
import "./chunk-CHEIIBT3.js";
|
|
79
|
+
import "./chunk-ACHCT36C.js";
|
|
80
|
+
import "./chunk-I3K2QRZ5.js";
|
|
77
81
|
import "./chunk-6C3D7BKK.js";
|
|
78
|
-
import "./chunk-
|
|
79
|
-
import "./chunk-BBZYS2P7.js";
|
|
82
|
+
import "./chunk-VZ6YDHDV.js";
|
|
80
83
|
import "./chunk-MNU36NGH.js";
|
|
84
|
+
import "./chunk-B3UM2NWK.js";
|
|
81
85
|
import "./chunk-VNTJJ4WQ.js";
|
|
82
86
|
import "./chunk-BQMSZSG6.js";
|
|
83
|
-
import "./chunk-
|
|
84
|
-
import "./chunk-
|
|
87
|
+
import "./chunk-VM3RQNIN.js";
|
|
88
|
+
import "./chunk-OU26ZZOL.js";
|
|
85
89
|
import "./chunk-JX6XHPTX.js";
|
|
86
90
|
import "./chunk-QCG3JVIW.js";
|
|
87
|
-
import "./chunk-
|
|
91
|
+
import "./chunk-XPXMRRG3.js";
|
|
88
92
|
import "./chunk-IOISNXQ2.js";
|
|
89
93
|
import "./chunk-QKXZOHHQ.js";
|
|
90
94
|
import "./chunk-BKVPLSEI.js";
|
|
91
|
-
import "./chunk-
|
|
92
|
-
import "./chunk-
|
|
95
|
+
import "./chunk-6LXGKCPH.js";
|
|
96
|
+
import "./chunk-6GI7NAZS.js";
|
|
93
97
|
import "./chunk-S6LOFUVP.js";
|
|
94
98
|
import "./chunk-Z72PLR74.js";
|
|
95
99
|
import "./chunk-GC3J5W2O.js";
|
|
@@ -103,29 +107,31 @@ import "./chunk-DJ2GSRLV.js";
|
|
|
103
107
|
import "./chunk-5YA6VPM3.js";
|
|
104
108
|
import "./chunk-AKXWS6ON.js";
|
|
105
109
|
import "./chunk-KP2FHIFR.js";
|
|
106
|
-
import "./chunk-
|
|
107
|
-
import "./chunk-
|
|
108
|
-
import "./chunk-
|
|
109
|
-
import "./chunk-5ETULJLP.js";
|
|
110
|
+
import "./chunk-73R6BAOK.js";
|
|
111
|
+
import "./chunk-WQ7QSGFJ.js";
|
|
112
|
+
import "./chunk-HZU2DMPO.js";
|
|
110
113
|
import "./chunk-VBT4BMCQ.js";
|
|
111
114
|
import "./chunk-CFMZLE3L.js";
|
|
112
|
-
import "./chunk-U5JK32FE.js";
|
|
113
115
|
import "./chunk-UEYDN2YO.js";
|
|
114
116
|
import "./chunk-HD7O6WLV.js";
|
|
117
|
+
import "./chunk-7JDVJX7A.js";
|
|
115
118
|
import "./chunk-EAJHTQOM.js";
|
|
119
|
+
import "./chunk-5ETULJLP.js";
|
|
120
|
+
import "./chunk-NXRQI7RF.js";
|
|
116
121
|
import "./chunk-WZAD4ZNJ.js";
|
|
117
122
|
import "./chunk-IC63SGIX.js";
|
|
118
|
-
import "./chunk-
|
|
123
|
+
import "./chunk-CGIKEQFI.js";
|
|
119
124
|
import "./chunk-XZA32HII.js";
|
|
120
125
|
import "./chunk-J5LUMSAZ.js";
|
|
121
126
|
import "./chunk-HHJLM3WQ.js";
|
|
122
|
-
import "./chunk-
|
|
123
|
-
import "./chunk-
|
|
127
|
+
import "./chunk-LFIKUSEE.js";
|
|
128
|
+
import "./chunk-GNGQGEZD.js";
|
|
124
129
|
import "./chunk-WFNJIZ4G.js";
|
|
125
130
|
import "./chunk-MF436P6L.js";
|
|
126
131
|
import "./chunk-HDDAI7GZ.js";
|
|
127
132
|
import "./chunk-RYSJNY4B.js";
|
|
128
|
-
import "./chunk-
|
|
133
|
+
import "./chunk-5XEZQQG3.js";
|
|
134
|
+
import "./chunk-YPKYQHFS.js";
|
|
129
135
|
import "./chunk-YDWJUBSY.js";
|
|
130
136
|
import "./chunk-RSWOFJBY.js";
|
|
131
137
|
import "./chunk-MDWQFUV4.js";
|
|
@@ -135,7 +141,8 @@ import "./chunk-FTKXJMQV.js";
|
|
|
135
141
|
import "./chunk-S5BHLTHK.js";
|
|
136
142
|
import "./chunk-KSEKRQJO.js";
|
|
137
143
|
import "./chunk-QFIRVSJL.js";
|
|
138
|
-
import "./chunk-
|
|
144
|
+
import "./chunk-BVNEEYJM.js";
|
|
145
|
+
import "./chunk-5R36APDE.js";
|
|
139
146
|
import "./chunk-GYAL5QAR.js";
|
|
140
147
|
import "./chunk-S34QJ6IR.js";
|
|
141
148
|
import "./chunk-MORSIWAC.js";
|