@qwen-code/qwen-code 0.23.0 → 0.23.1-preview.1
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/bundled/new-app/SKILL.md +1 -1
- package/bundled/qc-helper/docs/configuration/auth.md +84 -12
- package/bundled/qc-helper/docs/configuration/settings.md +76 -74
- package/bundled/qc-helper/docs/features/arena.md +15 -20
- package/bundled/qc-helper/docs/features/channels/overview.md +7 -2
- package/bundled/qc-helper/docs/features/code-review.md +22 -19
- package/bundled/qc-helper/docs/features/commands.md +51 -10
- package/bundled/qc-helper/docs/features/followup-suggestions.md +1 -1
- package/bundled/qc-helper/docs/features/goals.md +8 -0
- package/bundled/qc-helper/docs/features/headless.md +2 -2
- package/bundled/qc-helper/docs/features/hooks.md +19 -19
- package/bundled/qc-helper/docs/features/output-styles.md +35 -2
- package/bundled/qc-helper/docs/qwen-serve.md +67 -52
- package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +3 -1
- package/bundled/qc-helper/docs/support/troubleshooting.md +3 -3
- package/bundled/review/SKILL.md +45 -41
- package/bundled/review/references/aone.md +1 -1
- package/bundled/review/references/posting.md +1 -1
- package/bundled/workflow-creator/SKILL.md +48 -0
- package/bundled/zvec-grep-install/SKILL.md +57 -0
- package/chunks/MaxSizedBox-5ARLO5PR.js +116 -0
- package/chunks/{StandaloneSessionPicker-QUMO4LLQ.js → StandaloneSessionPicker-T6B322CB.js} +87 -82
- package/chunks/{acp-startup-profiler-M4X5F3VK.js → acp-startup-profiler-6ULXXQMS.js} +2 -2
- package/chunks/{acpAgent-2GTFCIEP.js → acpAgent-WTDEY5KD.js} +1041 -364
- package/chunks/{agent-XKF5SZWU.js → agent-NXPUXEVZ.js} +46 -43
- package/chunks/agent-headless-QQZTWOKO.js +88 -0
- package/chunks/{anthropicContentGenerator-L76MR5OR.js → anthropicContentGenerator-6XDHXIII.js} +16 -9
- package/chunks/{artifact-tool-MYCL2QCS.js → artifact-tool-DFVVJXL2.js} +3 -3
- package/chunks/askUserQuestion-GF7VQ44M.js +14 -0
- package/chunks/bridge-OHY5OGOZ.js +123 -0
- package/chunks/{ca-BNU7YNDE.js → ca-KC2AISNS.js} +1 -0
- package/chunks/{channel-management-service-4MTCEGJB.js → channel-management-service-ZDDG3G5S.js} +4 -4
- package/chunks/channel-settings-store-7BJAS2SU.js +126 -0
- package/chunks/{channel-worker-group-47F4ISUZ.js → channel-worker-group-2ISMRENV.js} +6 -6
- package/chunks/{channel-worker-manager-I5Y44GYR.js → channel-worker-manager-VSRPVPRH.js} +6 -6
- package/chunks/{channel-worker-supervisor-6VCLUXFE.js → channel-worker-supervisor-SRJBK72Z.js} +4 -4
- package/chunks/{chunk-5RTTI4GE.js → chunk-2RYWGYB3.js} +4 -3
- package/chunks/{chunk-FUO5V5KI.js → chunk-2UWQX4FP.js} +2 -2
- package/chunks/{chunk-L26ONV2Y.js → chunk-2WGJG2KW.js} +9 -8
- package/chunks/{chunk-JHN7UIDW.js → chunk-2XRE4KE4.js} +1 -1
- package/chunks/chunk-32CM56LO.js +20 -0
- package/chunks/{chunk-SI7WDR3U.js → chunk-32YDNYXP.js} +129 -14
- package/chunks/{chunk-ZHO2CW6D.js → chunk-3CZ2BQV6.js} +1 -1
- package/chunks/{chunk-FD5SJOWT.js → chunk-3K456UJF.js} +9 -4
- package/chunks/{chunk-5M6IDOMF.js → chunk-3K65MUKD.js} +105 -0
- package/chunks/chunk-3UMWOKJC.js +78 -0
- package/chunks/{chunk-UM2FFKXN.js → chunk-43JNQAHO.js} +3 -3
- package/chunks/{chunk-KM3XVTMO.js → chunk-43NOB5NM.js} +112 -12
- package/chunks/{chunk-G5PBOQWI.js → chunk-47BZVBTE.js} +3 -3
- package/chunks/{chunk-32LU3APX.js → chunk-4F2QRVW6.js} +1 -1
- package/chunks/{chunk-KMU3ZHH4.js → chunk-4HC4DYKN.js} +2 -2
- package/chunks/{chunk-22UH7VTP.js → chunk-4HOEU2OR.js} +1 -1
- package/chunks/{chunk-NXKOVOM5.js → chunk-4IQKBLTQ.js} +15 -9
- package/chunks/{chunk-M4KFODIP.js → chunk-4JAGXZR3.js} +1 -1
- package/chunks/{chunk-PDAKFU7M.js → chunk-4LIPOIXS.js} +1 -1
- package/chunks/{chunk-LEPCWS5A.js → chunk-4MCY33Y2.js} +3 -3
- package/chunks/{chunk-U6D2PPMN.js → chunk-4VUVBN3Y.js} +1 -1
- package/chunks/{chunk-37JFWFCD.js → chunk-4VZCORNT.js} +1 -1
- package/chunks/{daemon-RKDGBFLK.js → chunk-537SQ2AI.js} +2216 -1721
- package/chunks/{chunk-VNAYZAFX.js → chunk-54TF2ZIQ.js} +4 -4
- package/chunks/{chunk-OKTNXDVO.js → chunk-565U2ANU.js} +1 -1
- package/chunks/chunk-5ETULJLP.js +74 -0
- package/chunks/{chunk-ADYN7P2Y.js → chunk-5JLQWQK6.js} +8 -6
- package/chunks/{chunk-BFY33IB4.js → chunk-5MTARK4Y.js} +7 -7
- package/chunks/{chunk-BJXCYUGM.js → chunk-5YY5MZT6.js} +1 -1
- package/chunks/{chunk-4PSDSCW3.js → chunk-64MQTIX7.js} +3 -3
- package/chunks/{chunk-54C6PIGT.js → chunk-6UIACMGH.js} +3 -3
- package/chunks/{chunk-ALUYNJPM.js → chunk-7BZS4ZDV.js} +1362 -1140
- package/chunks/{chunk-LB3WQQJK.js → chunk-7OCIQNKX.js} +2 -2
- package/chunks/{chunk-QKDNS6FU.js → chunk-7VEYUF3N.js} +13 -2
- package/chunks/{chunk-AZJLY2XZ.js → chunk-AHBLRVD5.js} +5 -5
- package/chunks/{chunk-VWTSRH6C.js → chunk-AQ5NAGWI.js} +89 -17
- package/chunks/{chunk-MOF6VZN2.js → chunk-AXPOOQAW.js} +2 -2
- package/chunks/{chunk-CVX63TFJ.js → chunk-B44JBZBB.js} +3 -3
- package/chunks/{chunk-AI35S34R.js → chunk-B54PFQS5.js} +3 -3
- package/chunks/{chunk-373DQUVA.js → chunk-BF3RUIVP.js} +5 -4
- package/chunks/{chunk-RJUVTJEZ.js → chunk-BKNY7PDI.js} +1 -1
- package/chunks/{chunk-UKYXYWI2.js → chunk-BUQN5LTI.js} +2 -2
- package/chunks/{chunk-O5CD7T4T.js → chunk-BW4333PP.js} +0 -95
- package/chunks/{chunk-UPFRILIL.js → chunk-CWNC7M73.js} +2 -2
- package/chunks/{chunk-3L724BJ5.js → chunk-CZACBHAW.js} +6 -6
- package/chunks/{chunk-EBDGRBZX.js → chunk-D4CU6DKR.js} +6 -6
- package/chunks/{chunk-G7HBEEX7.js → chunk-D6PIMKY3.js} +9 -9
- package/chunks/{chunk-ENYUKMFK.js → chunk-DJXSOEFB.js} +1 -1
- package/chunks/{chunk-C2VWOXHS.js → chunk-DNPHKA72.js} +8 -8
- package/chunks/{chunk-UUASLXHW.js → chunk-E4L5BM2B.js} +5 -5
- package/chunks/{chunk-HT5S5TRQ.js → chunk-EDIDYZBT.js} +4 -11
- package/chunks/{chunk-5H5S4UY5.js → chunk-EFT7OMDN.js} +1 -1
- package/chunks/{chunk-GB4UKWY5.js → chunk-EJNYBDYC.js} +2 -2
- package/chunks/{chunk-NQ4L2CMD.js → chunk-ER273QE6.js} +53 -9
- package/chunks/{chunk-RKW36UWC.js → chunk-EWNKP4V4.js} +1 -1
- package/chunks/{chunk-UJ4DUYIH.js → chunk-F53KKZUD.js} +2 -2
- package/chunks/{chunk-EFTPIZIC.js → chunk-FDOGGKAA.js} +21 -0
- package/chunks/{chunk-AQ37AY7B.js → chunk-FKJM6JKY.js} +5 -0
- package/chunks/{chunk-KEVYJSI4.js → chunk-G34YLYCS.js} +13 -13
- package/chunks/{chunk-P6UIF2OW.js → chunk-GCFZ2LAX.js} +195 -10
- package/chunks/{chunk-VGHZT6JR.js → chunk-GELRJXE2.js} +1 -1
- package/chunks/{chunk-ZDFQGHZH.js → chunk-GMNLYQOS.js} +1 -1
- package/chunks/{chunk-KOGW3YWJ.js → chunk-GVVCLL2P.js} +12 -12
- package/chunks/{chunk-OSSTATJF.js → chunk-GXZHYPHZ.js} +428 -30
- package/chunks/{chunk-IPATA3T2.js → chunk-GZWW2QWR.js} +2 -2
- package/chunks/{chunk-C4TIXFDZ.js → chunk-H3UDNQLO.js} +6 -4
- package/chunks/chunk-HD7O6WLV.js +18 -0
- package/chunks/{chunk-4UANMABT.js → chunk-HFTB354P.js} +259 -49
- package/chunks/{chunk-LOBDDFYK.js → chunk-HJ34U5J4.js} +5 -5
- package/chunks/{chunk-M4LBBSVP.js → chunk-HY3DXYZK.js} +2 -2
- package/chunks/{chunk-4F7GQGXB.js → chunk-I72PHOKL.js} +1451 -415
- package/chunks/{chunk-YPWZTR7F.js → chunk-IFD3BTEA.js} +3 -3
- package/chunks/{chunk-EWRW2WQC.js → chunk-IKLFS6SC.js} +5 -5
- package/chunks/{chunk-VPSIC437.js → chunk-IQN2CCIE.js} +66 -6
- package/chunks/{chunk-F7NF2IOE.js → chunk-IXSGOSEG.js} +7 -7
- package/chunks/{chunk-ODZF64DM.js → chunk-IZ2U57NY.js} +1 -1
- package/chunks/{chunk-4BGDFKQE.js → chunk-J3O5I5ZD.js} +24 -7
- package/chunks/{chunk-DYTW3QVG.js → chunk-J6MB5ZHZ.js} +1 -1
- package/chunks/{chunk-HJBHMANB.js → chunk-JBTZUFR4.js} +11 -8
- package/chunks/{chunk-SRF4KTAG.js → chunk-JLWFGYXU.js} +4 -4
- package/chunks/{chunk-SX2QIMJV.js → chunk-JOPC3FND.js} +5 -5
- package/chunks/chunk-JPEAQJNS.js +2142 -0
- package/chunks/{chunk-ZTPGUFQV.js → chunk-JRYL3T2O.js} +24 -5
- package/chunks/{chunk-GXUTFQXK.js → chunk-KE3Q4JMY.js} +4 -4
- package/chunks/{chunk-LKODFJRD.js → chunk-KFFCDLKV.js} +1 -1
- package/chunks/{chunk-4M24B5J5.js → chunk-KJJPJYHI.js} +79 -30
- package/chunks/chunk-KK2GZGBK.js +21080 -0
- package/chunks/{chunk-64QH2UC6.js → chunk-KPXRFTT7.js} +12 -1
- package/chunks/{chunk-JZWOCUZ3.js → chunk-L4R7BCVV.js} +1 -1
- package/chunks/{chunk-IG4W5SJR.js → chunk-LDS57224.js} +3 -3
- package/chunks/{chunk-UAKRDON5.js → chunk-LK7S2D6V.js} +4 -4
- package/chunks/{chunk-4HVH57J3.js → chunk-LMJQSPWB.js} +21 -6
- package/chunks/{chunk-ANVG3BVV.js → chunk-LNYV4GXX.js} +13 -3
- package/chunks/{chunk-RM4WT2XB.js → chunk-LPBQODMR.js} +4 -4
- package/chunks/{chunk-XEAAO654.js → chunk-M3JGHRMQ.js} +1 -1
- package/chunks/{chunk-AMDSOFFV.js → chunk-MATEIJZF.js} +1 -0
- package/chunks/{chunk-LHBNR6EU.js → chunk-MNEYUNOE.js} +2 -2
- package/chunks/{chunk-I4NRYS6A.js → chunk-MUZCSTOO.js} +11 -11
- package/chunks/{chunk-I5N4EAS6.js → chunk-MWHY26G3.js} +1 -1
- package/chunks/{chunk-7XL4WRXM.js → chunk-N6VQ37ZZ.js} +2 -2
- package/chunks/{chunk-AHYTURFB.js → chunk-N7EYO2E7.js} +1 -1
- package/chunks/{chunk-LU77UT4D.js → chunk-N7VURC4O.js} +24 -26
- package/chunks/{chunk-DSX7KQPM.js → chunk-NAKALAL4.js} +227 -29
- package/chunks/{chunk-QQD2GART.js → chunk-NGX4NUNP.js} +3 -3
- package/chunks/{chunk-2M3EWQNG.js → chunk-NUQFUXOG.js} +17 -1
- package/chunks/{chunk-E4JNFXNI.js → chunk-NXWYCSPL.js} +3 -3
- package/chunks/{chunk-6A2D4QSO.js → chunk-O2GG7H4C.js} +4 -4
- package/chunks/{chunk-ZKFTS3OV.js → chunk-O45WBTNS.js} +6 -6
- package/chunks/{chunk-KGV55H53.js → chunk-OECNP26L.js} +1 -1
- package/chunks/{chunk-S6H3ELPG.js → chunk-P4RUUG64.js} +1 -1
- package/chunks/{chunk-GH2S4GD5.js → chunk-P5LDR7FI.js} +21 -68
- package/chunks/{chunk-RN3YGDCA.js → chunk-P6LATTDG.js} +4 -4
- package/chunks/{chunk-WP4AX3XD.js → chunk-PTFFWTTO.js} +3 -3
- package/chunks/{chunk-DTVQSSNM.js → chunk-PZUOHCWI.js} +3 -3
- package/chunks/{chunk-VYIUNFEA.js → chunk-PZV2FASB.js} +3 -3
- package/chunks/{chunk-XLXAZLDR.js → chunk-Q2SAQTEJ.js} +1 -1
- package/chunks/{chunk-47RYEQW5.js → chunk-QMFOYPGV.js} +2 -2
- package/chunks/{chunk-SULZPKTA.js → chunk-QSC5YOEC.js} +3 -3
- package/chunks/{chunk-F33GFWPR.js → chunk-QWZOOIR3.js} +58 -18
- package/chunks/{chunk-H43PSPYS.js → chunk-R355CUNQ.js} +4 -4
- package/chunks/{chunk-DQCKVAF5.js → chunk-RDKXZ2LS.js} +3 -3
- package/chunks/{chunk-7JMGTOH7.js → chunk-RPBMP6BN.js} +21 -1
- package/chunks/{chunk-5Q5RC2WE.js → chunk-RVNS7NWN.js} +2 -2
- package/chunks/{chunk-7RB56BRJ.js → chunk-SAZS4IWW.js} +6 -4
- package/chunks/{chunk-5EIOJGCR.js → chunk-SFMCYMVF.js} +4 -4
- package/chunks/{chunk-TMKTOTMQ.js → chunk-SN5FV4FY.js} +5 -5
- package/chunks/{chunk-QJGYU5PG.js → chunk-TDP7UULF.js} +1 -1
- package/chunks/{chunk-EIJT2PQ6.js → chunk-TIGXX4PA.js} +2 -2
- package/chunks/{chunk-PCRBLMIN.js → chunk-TMWB67LS.js} +21 -3
- package/chunks/{chunk-JUARRUMA.js → chunk-UEZOXZNI.js} +1358 -646
- package/chunks/{chunk-KFN2IZYR.js → chunk-UKADFFL2.js} +3 -3
- package/chunks/{chunk-TJYRTS4S.js → chunk-UKKYOIVT.js} +2 -2
- package/chunks/{chunk-EVFDRBUM.js → chunk-URSCX7S7.js} +12 -7
- package/chunks/{chunk-U4DJ5XB3.js → chunk-VDXYYVCD.js} +269 -70
- package/chunks/{chunk-4LIFGNI4.js → chunk-VEFRT7NX.js} +1 -1
- package/chunks/chunk-VFFQAOPR.js +18 -0
- package/chunks/{chunk-3AKCBZVW.js → chunk-VU7O7CGQ.js} +3 -3
- package/chunks/{chunk-RAFQIHN2.js → chunk-VUSSAGKI.js} +76 -5
- package/chunks/{chunk-TQHPVKO6.js → chunk-VY6UVU7G.js} +6 -6
- package/chunks/{chunk-S2T7H5MI.js → chunk-W4LL5RZO.js} +1 -1
- package/chunks/{chunk-ZGCKTAL5.js → chunk-WEXA2DNG.js} +2 -0
- package/chunks/{chunk-NVVJTUSL.js → chunk-WR3SH3EY.js} +136 -85
- package/chunks/{chunk-JR42V4UY.js → chunk-WTW36TJ3.js} +1 -1
- package/chunks/{chunk-TSZSGQ3N.js → chunk-WXC6OAWD.js} +1 -1
- package/chunks/{chunk-ZVP4PWBU.js → chunk-X35VIWWJ.js} +1 -1
- package/chunks/{chunk-KHP66DFN.js → chunk-XFFRI3WM.js} +1 -1
- package/chunks/{chunk-EIY7SUPZ.js → chunk-XHGGYCTA.js} +1 -1
- package/chunks/{chunk-BA4WJC4L.js → chunk-XOVVCGZX.js} +1 -1
- package/chunks/{chunk-VBWD6C27.js → chunk-XUSOYE2I.js} +1 -1
- package/chunks/{chunk-NUHOLAQ6.js → chunk-XWJFDJZK.js} +1 -1
- package/chunks/{chunk-65HWLGA7.js → chunk-XY3USGFE.js} +3 -3
- package/chunks/{chunk-STCVJXQB.js → chunk-Y3ZKI4RQ.js} +56 -26
- package/chunks/{chunk-QAK5475D.js → chunk-Y53DG2HA.js} +1 -1
- package/chunks/{chunk-3JQZVCBI.js → chunk-YCDL2SAS.js} +2 -2
- package/chunks/{chunk-NSUKQ4DN.js → chunk-YHDGABDC.js} +3 -3
- package/chunks/{chunk-FRICLXCZ.js → chunk-Z6WZPXQH.js} +3 -3
- package/chunks/{chunk-EAHOJF6V.js → chunk-ZAFYHRVY.js} +12 -0
- package/chunks/{chunk-MP6YZ4RK.js → chunk-ZAZ3NFL6.js} +852 -309
- package/chunks/{chunk-7TBU7PU2.js → chunk-ZSTCM3MX.js} +1 -1
- package/chunks/{chunk-NRL5CUZT.js → chunk-ZTAVGFKA.js} +1 -1
- package/chunks/config-utils-QXDOTXEQ.js +119 -0
- package/chunks/contextCommand-RN4KARWC.js +112 -0
- package/chunks/{core-runtime-B4UKKIAQ.js → core-runtime-NAZCOKHB.js} +63 -58
- package/chunks/{create-sub-session-NJ24B4US.js → create-sub-session-BCSM4WKB.js} +61 -56
- package/chunks/{create-sub-session-LUPWEUHR.js → create-sub-session-BQ3SE4TX.js} +3 -3
- package/chunks/{cron-create-CRSPET3H.js → cron-create-D6HQ7I7I.js} +4 -4
- package/chunks/{cron-delete-DB77SZTU.js → cron-delete-KK3D2SQV.js} +4 -4
- package/chunks/{cron-list-U2JNYWV6.js → cron-list-VBF3IZMF.js} +4 -4
- package/chunks/daemon-LCUELM6E.js +191 -0
- package/chunks/{daemon-git-worktree-guard-O2HPOBAB.js → daemon-git-worktree-guard-3K5CAU36.js} +62 -57
- package/chunks/daemon-status-provider-4X3ZZQTZ.js +122 -0
- package/chunks/daemon-trust-policy-R45CFUJA.js +118 -0
- package/chunks/{daemon-trust-policy-monitor-JL7F4Y4Q.js → daemon-trust-policy-monitor-DSSFCO3K.js} +69 -64
- package/chunks/{de-T4BLOKEC.js → de-UU2YTO37.js} +1 -0
- package/chunks/deferred-core-runtime-UO2M6WYI.js +120 -0
- package/chunks/{display-image-73C7XNRK.js → display-image-EVVTBVYE.js} +6 -6
- package/chunks/{dist-EDHQIBYD.js → dist-3T5MDUHP.js} +62 -20
- package/chunks/{dist-ZCJLKQSP.js → dist-AFH3BMZZ.js} +18 -10
- package/chunks/{dist-LXFYIJNG.js → dist-MK5PPBRF.js} +40 -9
- package/chunks/{dist-GT64AAUR.js → dist-PH5RSTEA.js} +56 -20
- package/chunks/{dist-62OZ7QXB.js → dist-QUU7TVE3.js} +35 -12
- package/chunks/{dist-JVXT4VUJ.js → dist-R5Y34V6T.js} +11 -2
- package/chunks/{dist-L6URO6CK.js → dist-SB2XRXZA.js} +5 -1
- package/chunks/{dist-QAF5DO3Y.js → dist-SIHF5MU2.js} +326 -131
- package/chunks/{dist-PDGNRVPY.js → dist-UVHW2U56.js} +20 -1
- package/chunks/earlyInputCapture-BXP7V2P3.js +22 -0
- package/chunks/{edit-SUGXY63Y.js → edit-VNBCTRWP.js} +48 -44
- package/chunks/{en-2RATMNX7.js → en-JMR535HP.js} +3 -1
- package/chunks/{enter-worktree-B6USKSIK.js → enter-worktree-CEVK7MQ2.js} +7 -7
- package/chunks/{enterPlanMode-MDX4RVVL.js → enterPlanMode-4KMZMUIA.js} +48 -45
- package/chunks/environment-S2HYQDON.js +135 -0
- package/chunks/errors-DAAN5TL7.js +119 -0
- package/chunks/{exit-worktree-DLQ73SJH.js → exit-worktree-D3YE6MUN.js} +7 -7
- package/chunks/exitPlanMode-HR36HG3D.js +86 -0
- package/chunks/{fast-path-Y73R42LV.js → fast-path-4IWSW3UV.js} +3 -3
- package/chunks/{fast-path-settings-MFUR3IWK.js → fast-path-settings-ISEJPRYE.js} +6 -4
- package/chunks/{fr-BGHGYX6A.js → fr-HKNWVXRJ.js} +1 -0
- package/chunks/{glob-DMGH7EZN.js → glob-IZYB2XH2.js} +46 -43
- package/chunks/{goal-tools-3RF3PXCL.js → goal-tools-VGUPKQDJ.js} +46 -43
- package/chunks/{grep-AJVLCVXC.js → grep-OUVLNXG7.js} +9 -8
- package/chunks/handleAutoUpdate-D56FMDTW.js +115 -0
- package/chunks/i18n-BKE5WO6T.js +130 -0
- package/chunks/{image-gen-VOIDOHOB.js → image-gen-SHVQ3XID.js} +8 -8
- package/chunks/initializer-MS4SGEHF.js +119 -0
- package/chunks/installationInfo-542MGC4S.js +113 -0
- package/chunks/{ja-G3FTD5XE.js → ja-GJS5RZGU.js} +1 -0
- package/chunks/{keychain-token-storage-REZVMJA6.js → keychain-token-storage-NQ5XWIPX.js} +2 -2
- package/chunks/list-H6XTKUWL.js +122 -0
- package/chunks/{list-agents-SBMONIUK.js → list-agents-ULYBGJXC.js} +6 -6
- package/chunks/{llm-K26SUDVK.js → llm-3NUC4EJY.js} +132 -113
- package/chunks/{llm-content-generator-TT6EAUD4.js → llm-content-generator-R4NL3OQN.js} +40 -13
- package/chunks/loadedSettingsAdapter-3XLKYDVT.js +116 -0
- package/chunks/{loggingContentGenerator-EYQBA4M4.js → loggingContentGenerator-ZYSWVNEO.js} +55 -52
- package/chunks/{loop-wakeup-QA6SHCZT.js → loop-wakeup-B27BEYRL.js} +5 -5
- package/chunks/{lowlight-J2OZNPCA.js → lowlight-BTE423KL.js} +3 -6
- package/chunks/{ls-HEJNCEYO.js → ls-3IIMMVKF.js} +5 -4
- package/chunks/{lsp-WOQKNZP6.js → lsp-VJAT7XKS.js} +2 -2
- package/chunks/{managed-npm-update-HIJTODQT.js → managed-npm-update-L2I53ZAI.js} +62 -57
- package/chunks/mcp-4PIXQASW.js +116 -0
- package/chunks/{monitor-DKNZQAB2.js → monitor-O2YQTOZZ.js} +50 -46
- package/chunks/{node-UETAYMMO.js → node-ISQAFKIS.js} +2 -2
- package/chunks/nonInteractiveCli-LV7CDBA2.js +198 -0
- package/chunks/{notebook-edit-MGHTRL2D.js → notebook-edit-4RE2ALH4.js} +48 -44
- package/chunks/{openaiContentGenerator-ZJIEQ3ZJ.js → openaiContentGenerator-7ND7K5CP.js} +30 -25
- package/chunks/pidfile-UFTLQ7NP.js +117 -0
- package/chunks/{processUtils-UY3SAJJZ.js → processUtils-3XBB4FYV.js} +2 -2
- package/chunks/prompt-terminal-ledger-2QASOGMM.js +111 -0
- package/chunks/{pt-D73IFYT7.js → pt-FXMYXEUV.js} +1 -0
- package/chunks/{qwenContentGenerator-VI4KATRY.js → qwenContentGenerator-AELTUTH6.js} +52 -49
- package/chunks/{qwenOAuth2-7AOCKSOQ.js → qwenOAuth2-BS5D2LYV.js} +7 -7
- package/chunks/{read-file-P7F4P7LV.js → read-file-PDWHZPHX.js} +13 -11
- package/chunks/{read-mcp-resource-GLAGB6R7.js → read-mcp-resource-YXJZ75UB.js} +2 -2
- package/chunks/{record-artifact-SWVR7NSU.js → record-artifact-WJDOV6XU.js} +4 -4
- package/chunks/{report-findings-AL5YW3KI.js → report-findings-Q4UACKWR.js} +5 -5
- package/chunks/{request-shutdown-5YK4IZ54.js → request-shutdown-2YZ3E3GH.js} +8 -8
- package/chunks/resumeHistoryUtils-QRXZEEBA.js +124 -0
- package/chunks/ripGrep-KSOOLE6H.js +39 -0
- package/chunks/{ru-QMISLKRH.js → ru-RMHURE5U.js} +1 -0
- package/chunks/{run-qwen-serve-OGTEEUR2.js → run-qwen-serve-RTAREPT6.js} +84 -70
- package/chunks/runtime-ESFSCJRZ.js +154 -0
- package/chunks/scheduled-tasks-6ZHRNBH6.js +133 -0
- package/chunks/{scheduler-73YXGUGW.js → scheduler-DQI6KV7T.js} +63 -58
- package/chunks/{sdk-exporters-http-3JO5TJNU.js → sdk-exporters-http-7R2ARBPV.js} +2 -2
- package/chunks/{sdk-impl-HZAUUTHJ.js → sdk-impl-YOLO7LV4.js} +4 -4
- package/chunks/{send-message-JC7NJTY6.js → send-message-PQCVSVMN.js} +24 -24
- package/chunks/serve-FY7ZEW52.js +124 -0
- package/chunks/{server-AOYZVVOM.js → server-KNDY6K5F.js} +1594 -273
- package/chunks/{session-UAWFNFGI.js → session-MCEPXAZP.js} +113 -105
- package/chunks/session-attachments-root-OLNAE6GF.js +109 -0
- package/chunks/{session-pr-refresh-CT2INROL.js → session-pr-refresh-HKJHQQQK.js} +67 -62
- package/chunks/{settings-BHRGDASJ.js → settings-VXO4WBMK.js} +68 -63
- package/chunks/shell-U263OTES.js +96 -0
- package/chunks/{skill-ZGBKNCHQ.js → skill-SDODGBKL.js} +19 -17
- package/chunks/skill-settings-YEIA22QJ.js +124 -0
- package/chunks/spawnChannel-4WJZVFPP.js +117 -0
- package/chunks/standalone-update-ZWVQUO64.js +124 -0
- package/chunks/{start-opentui-ui-FZ4USOU7.js → start-opentui-ui-BFYCJQRZ.js} +1199 -190
- package/chunks/{startInteractiveUI-E2WQJUOA.js → startInteractiveUI-JYAFCMHL.js} +2977 -2319
- package/chunks/{syntheticOutput-HJNZSEHN.js → syntheticOutput-AUAJBNXR.js} +3 -3
- package/chunks/{task-create-6RSD54S5.js → task-create-LD5ISM3E.js} +12 -12
- package/chunks/{task-list-IQSACPOM.js → task-list-YISJ4RJA.js} +5 -5
- package/chunks/{task-stop-HE2LRQNW.js → task-stop-65ZOVATJ.js} +2 -2
- package/chunks/{task-update-XAJ2NYOA.js → task-update-AAN4ZVEY.js} +15 -15
- package/chunks/{team-create-SOKMYSQU.js → team-create-KU7MABNO.js} +47 -44
- package/chunks/{team-delete-NGNNKGMG.js → team-delete-XFRRTJTT.js} +5 -5
- package/chunks/{team-plan-approval-U7ZWXYAY.js → team-plan-approval-DPB377A3.js} +46 -43
- package/chunks/terminal-image-renderer-WGWRENOF.js +124 -0
- package/chunks/theme-manager-GBUFULSO.js +108 -0
- package/chunks/{todoWrite-5UTVUXHA.js → todoWrite-G7NT4IFP.js} +5 -5
- package/chunks/{tool-search-IAI2RVWT.js → tool-search-6YUXHBPT.js} +19 -17
- package/chunks/total-session-admission-54R2JQ5L.js +118 -0
- package/chunks/trustedFolders-KAJIDJTH.js +128 -0
- package/chunks/{update-relaunch-5RWKZAL3.js → update-relaunch-XM4IWBFD.js} +5 -5
- package/chunks/updateCheck-W6UZFURI.js +124 -0
- package/chunks/useAutoAcceptIndicator-LAWYHY3U.js +126 -0
- package/chunks/{validateNonInterActiveAuth-QPFEKATS.js → validateNonInterActiveAuth-7WCKHRN2.js} +109 -101
- package/chunks/{version-JKNG7YDH.js → version-3ZU43RJ6.js} +1 -1
- package/chunks/{web-fetch-X3AHIIHW.js → web-fetch-QHI2SQL4.js} +16 -14
- package/chunks/{web-search-K2FMOGS5.js → web-search-3KZZKWNY.js} +9 -8
- package/chunks/{workflow-TOLPAK5G.js → workflow-HRW7Y2X4.js} +330 -1667
- package/chunks/workspace-providers-status-KTGCWCPC.js +120 -0
- package/chunks/{workspace-registration-store-KQWVVW4Y.js → workspace-registration-store-LHLPPWNE.js} +1 -1
- package/chunks/workspace-registry-X34MLN52.js +127 -0
- package/chunks/workspace-runtime-coordinator-U4PW4P7K.js +128 -0
- package/chunks/workspace-service-KD7BCGYL.js +132 -0
- package/chunks/workspace-skills-status-YJGO6Y3T.js +119 -0
- package/chunks/{workspace-trust-reconciler-IBDFQBQS.js → workspace-trust-reconciler-EUYHISCH.js} +74 -69
- package/chunks/write-file-EBSB34NJ.js +91 -0
- package/chunks/{zh-25DF7OGK.js → zh-DVFYHRK5.js} +3 -1
- package/chunks/{zh-TW-5EDMZVGK.js → zh-TW-W2GNP2IU.js} +3 -1
- package/chunks/{zoom-image-IFXSN74N.js → zoom-image-UJ5VKWKP.js} +13 -11
- package/cli.js +13 -13
- package/export-transcript-document.js +617 -0
- package/locales/ca.js +1 -0
- package/locales/de.js +1 -0
- package/locales/en.js +5 -2
- package/locales/fr.js +1 -0
- package/locales/ja.js +1 -0
- package/locales/pt.js +1 -0
- package/locales/ru.js +1 -0
- package/locales/zh-TW.js +5 -2
- package/locales/zh.js +5 -2
- package/package.json +5 -4
- package/web-shell/assets/{abnfDiagram-VCTEODGH-Cxf7xE_Z.js → abnfDiagram-VCTEODGH-Dur--luQ.js} +1 -1
- package/web-shell/assets/{arc-ESi1eNkE.js → arc-tYLobxFi.js} +1 -1
- package/web-shell/assets/{architectureDiagram-5GKGNRK7-D9l7-bDo.js → architectureDiagram-5GKGNRK7-IG6aXD03.js} +1 -1
- package/web-shell/assets/{blockDiagram-NRAW4CY4-Bc8DEasw.js → blockDiagram-NRAW4CY4-C6eBSkfA.js} +1 -1
- package/web-shell/assets/{c4Diagram-UCG6FXSJ-Dimb2Hmh.js → c4Diagram-UCG6FXSJ-BrX3HJqB.js} +1 -1
- package/web-shell/assets/channel-uEkvKckd.js +1 -0
- package/web-shell/assets/{chunk-2Q5K7J3B-jVDmOpAQ.js → chunk-2Q5K7J3B-B3fcJ8ee.js} +1 -1
- package/web-shell/assets/{chunk-5VM5RSS4-DbG_SwdB.js → chunk-5VM5RSS4-CeC90yKM.js} +1 -1
- package/web-shell/assets/{chunk-F27PBJKO-QEc4cY1v.js → chunk-F27PBJKO-CW44RVki.js} +1 -1
- package/web-shell/assets/{chunk-G27WJ6UU-iJ36lQ3X.js → chunk-G27WJ6UU-D1PAMukD.js} +1 -1
- package/web-shell/assets/{chunk-JWPE2WC7-DuArnVtF.js → chunk-JWPE2WC7-Dt3Y2Fvx.js} +1 -1
- package/web-shell/assets/{chunk-LCL6LL3I-DxOf1zwL.js → chunk-LCL6LL3I-CZHw2lLI.js} +1 -1
- package/web-shell/assets/{chunk-POPQ4Y6H-lVLu9Ild.js → chunk-POPQ4Y6H-ysNAdTGx.js} +1 -1
- package/web-shell/assets/{chunk-SVP7TREG-C6XYlIer.js → chunk-SVP7TREG-BdNXW6YQ.js} +1 -1
- package/web-shell/assets/{chunk-XXDRQBXY-CiG2j2Ji.js → chunk-XXDRQBXY-DgqQ9UA8.js} +1 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-DuPsnhWS.js +1 -0
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-DuPsnhWS.js +1 -0
- package/web-shell/assets/{cose-bilkent-JH36ORCC-DGVHMMVm.js → cose-bilkent-JH36ORCC-BILImXzJ.js} +1 -1
- package/web-shell/assets/{cynefin-OW5HDTMX-D6cgpCnH.js → cynefin-OW5HDTMX-DR88Pund.js} +1 -1
- package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-BKv4Z-UX.js → cynefinDiagram-5FMLGOSQ-BYFbfkA6.js} +1 -1
- package/web-shell/assets/{dagre-3AP2YEHR-B4ABMIG-.js → dagre-3AP2YEHR-rfpyc6sX.js} +1 -1
- package/web-shell/assets/{diagram-S7CK7UJ4-DgCkp_Lm.js → diagram-S7CK7UJ4-BJxLmEwH.js} +1 -1
- package/web-shell/assets/{diagram-UQ7AKVKN-FG0FNokz.js → diagram-UQ7AKVKN-H34xm7k3.js} +1 -1
- package/web-shell/assets/{diagram-VSXAHHWV-JgkP9qg-.js → diagram-VSXAHHWV-HYxhwNLx.js} +1 -1
- package/web-shell/assets/{diagram-VX7I27RA-ADh2x83l.js → diagram-VX7I27RA-BJazso8F.js} +1 -1
- package/web-shell/assets/{diagram-Z3DM3KII-yXqoYF1J.js → diagram-Z3DM3KII-Clje1aNy.js} +1 -1
- package/web-shell/assets/{ebnfDiagram-PWID7BFC-Duk83Ek_.js → ebnfDiagram-PWID7BFC-M93YBkFh.js} +1 -1
- package/web-shell/assets/{erDiagram-SSCWMZ5O-DMdvxySG.js → erDiagram-SSCWMZ5O-DY8XzSHU.js} +1 -1
- package/web-shell/assets/{flowDiagram-A5DVABFB-DHjVgSji.js → flowDiagram-A5DVABFB-CE6Aylcq.js} +1 -1
- package/web-shell/assets/{ganttDiagram-EL5Y4UJY-DMM9DkCE.js → ganttDiagram-EL5Y4UJY-DI-5LL22.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-t_ug9vO8.js → gitGraphDiagram-WWUBYQGX-C7BZWElk.js} +1 -1
- package/web-shell/assets/index-CVyqwW7y.js +2142 -0
- package/web-shell/assets/{index-zqvnpGHv.js → index-DclFHns9.js} +1 -1
- package/web-shell/assets/index-FO7JXPnH.css +36 -0
- package/web-shell/assets/{infoDiagram-RXCK75RN-eT1fANNm.js → infoDiagram-RXCK75RN-CGUSy4Pc.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-5VMMS53U-k3evzZNn.js → ishikawaDiagram-5VMMS53U-B5BVks9q.js} +1 -1
- package/web-shell/assets/{journeyDiagram-EYS64GPL-CGim3EAi.js → journeyDiagram-EYS64GPL-CFh6Tf7h.js} +1 -1
- package/web-shell/assets/{kanban-definition-3QL26DDD-WHfJo-22.js → kanban-definition-3QL26DDD-B7TlxP7c.js} +1 -1
- package/web-shell/assets/{layout-DkqIaFlJ.js → layout-Br_pZq2Q.js} +1 -1
- package/web-shell/assets/{linear-Bdkd3mCz.js → linear-BVlP6fte.js} +1 -1
- package/web-shell/assets/{mermaid.core-CGw0LkT_.js → mermaid.core-TrcYWoiF.js} +6 -6
- package/web-shell/assets/{mindmap-definition-FBJOCRG2-C9V4rBvo.js → mindmap-definition-FBJOCRG2-BJ4LzqjZ.js} +1 -1
- package/web-shell/assets/{pegDiagram-XKGWAZYB-CwoI2T5G.js → pegDiagram-XKGWAZYB-1b_MxlOl.js} +1 -1
- package/web-shell/assets/{pieDiagram-E7YTZNPT-DaTmBmPG.js → pieDiagram-E7YTZNPT-B8zl0YhY.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-AXDQQJYC-plh6MyGI.js → quadrantDiagram-AXDQQJYC-CIZO8ukl.js} +1 -1
- package/web-shell/assets/{railroadDiagram-O6MQD6OU-D_b-S0iK.js → railroadDiagram-O6MQD6OU-CepHSbCj.js} +1 -1
- package/web-shell/assets/{requirementDiagram-EFPCY7ZU-zUzTN7VE.js → requirementDiagram-EFPCY7ZU-BCgxkcSW.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-P5KCCOFB-m6AhoD0l.js → sankeyDiagram-P5KCCOFB-CE5CcoMM.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-Cwhzsine.js → sequenceDiagram-WJ2MYXX4-DvgHi-d5.js} +1 -1
- package/web-shell/assets/{sizeCapture-X5ZJPWSS-CcZuKIae.js → sizeCapture-X5ZJPWSS-T-fAsCPX.js} +1 -1
- package/web-shell/assets/{stateDiagram-HBIQ2CUA-CFoiJwD_.js → stateDiagram-HBIQ2CUA-DYHaul-5.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-BcYho9a4.js +1 -0
- package/web-shell/assets/{swimlanes-XN3QIQJK-CgS9hcaV.js → swimlanes-XN3QIQJK-Dbz3Qiej.js} +1 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-D6HsOIgX.js +8 -0
- package/web-shell/assets/{timeline-definition-24CTP7MA-Dzzc05t9.js → timeline-definition-24CTP7MA-9NVRts3N.js} +1 -1
- package/web-shell/assets/{vennDiagram-4TSXK5OY-DemK0f7Y.js → vennDiagram-4TSXK5OY-C7cb7vnH.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-VM6X3IG4-CquLxtMr.js → wardleyDiagram-VM6X3IG4-CG-8Ddjm.js} +1 -1
- package/web-shell/assets/{xychartDiagram-S5SC5T6Z-BTBKTM5g.js → xychartDiagram-S5SC5T6Z-iGeYAcP4.js} +1 -1
- package/web-shell/index.html +2 -2
- package/chunks/MaxSizedBox-B3D7545A.js +0 -111
- package/chunks/agent-headless-OC2IB55D.js +0 -85
- package/chunks/askUserQuestion-THQZMG44.js +0 -322
- package/chunks/bridge-IHSBI2YJ.js +0 -118
- package/chunks/channel-settings-store-BVKWAI2T.js +0 -121
- package/chunks/chunk-I2TMJPCV.js +0 -448
- package/chunks/chunk-QI27MKNQ.js +0 -4008
- package/chunks/config-utils-LVSYDLHZ.js +0 -114
- package/chunks/contextCommand-TZD7UAJK.js +0 -107
- package/chunks/daemon-status-provider-GRRVCJFW.js +0 -117
- package/chunks/daemon-trust-policy-YJL442BK.js +0 -113
- package/chunks/deferred-core-runtime-S32AYVZI.js +0 -115
- package/chunks/earlyInputCapture-BBPCIVZG.js +0 -108
- package/chunks/environment-VN6RXDVN.js +0 -130
- package/chunks/errors-UEY36PIT.js +0 -114
- package/chunks/exitPlanMode-EPHIEDAA.js +0 -83
- package/chunks/handleAutoUpdate-HVWQT2AU.js +0 -110
- package/chunks/i18n-5OR7NTRZ.js +0 -125
- package/chunks/initializer-JE5RQSOE.js +0 -114
- package/chunks/installationInfo-KO3CCSCK.js +0 -108
- package/chunks/list-3IORSFIY.js +0 -117
- package/chunks/loadedSettingsAdapter-KLLFZF3M.js +0 -111
- package/chunks/mcp-A2UEHETW.js +0 -111
- package/chunks/nonInteractiveCli-YA47F2F4.js +0 -190
- package/chunks/pidfile-ETHAZNMY.js +0 -112
- package/chunks/prompt-terminal-ledger-GZ747VYE.js +0 -106
- package/chunks/resumeHistoryUtils-DPZKFW24.js +0 -119
- package/chunks/ripGrep-C7LJKUPZ.js +0 -37
- package/chunks/runtime-LNBLEMZS.js +0 -149
- package/chunks/scheduled-tasks-FLDYZQOF.js +0 -128
- package/chunks/serve-3UR2H4CV.js +0 -119
- package/chunks/session-attachments-root-ZCGXQQTR.js +0 -104
- package/chunks/shell-YHOGC7TO.js +0 -93
- package/chunks/skill-settings-AKSP665O.js +0 -119
- package/chunks/spawnChannel-N25MBB6F.js +0 -112
- package/chunks/standalone-update-XGPWJDRN.js +0 -119
- package/chunks/terminal-image-renderer-KKM4OBLO.js +0 -117
- package/chunks/theme-manager-GQHF3A7T.js +0 -103
- package/chunks/total-session-admission-G4CGCSTG.js +0 -113
- package/chunks/trustedFolders-D2I3FDPB.js +0 -123
- package/chunks/updateCheck-ZXOQDFEI.js +0 -119
- package/chunks/useAutoAcceptIndicator-6EK4QGAH.js +0 -121
- package/chunks/workspace-providers-status-PCJK3RC7.js +0 -115
- package/chunks/workspace-registry-YNIOB6HJ.js +0 -122
- package/chunks/workspace-runtime-coordinator-WG2RNEN7.js +0 -123
- package/chunks/workspace-service-G4ZNBOFH.js +0 -127
- package/chunks/workspace-skills-status-FMTPPMWC.js +0 -114
- package/chunks/write-file-YTLFY2S5.js +0 -88
- package/web-shell/assets/channel-B7ohGDil.js +0 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-DdFpqpfD.js +0 -1
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-DdFpqpfD.js +0 -1
- package/web-shell/assets/index-BGZRqbRo.css +0 -36
- package/web-shell/assets/index-DRri_6_x.js +0 -2067
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V--H8HdEmk.js +0 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-ShE9OIgf.js +0 -8
package/bundled/review/SKILL.md
CHANGED
|
@@ -82,9 +82,9 @@ It prints a JSON verdict; use it **verbatim**:
|
|
|
82
82
|
|
|
83
83
|
What each level runs:
|
|
84
84
|
|
|
85
|
-
- **low** — quick pass. You read the diff yourself, walking it once per **angle** — `plan.budget.inlineAngles` directed angles (3-6, scaled by diff size) plus a gap sweep when the budget asks for one, all in this context — and report up to 10 unverified findings (Step 3C). No subagents, no build/test, no verification, no reverse audit, no PR posting, no incremental cache, no project rules. The angle rotation is what makes a subagent-free tier worth running: one undirected read converges on the most visibly suspicious hunk and leaves the rest of the diff unexamined, and that is the pass this replaces.
|
|
86
|
-
- **medium** — **balanced**: the high pipeline with its most expensive passes removed. It runs the parallel review agents (Step 3A/3B) over a **reduced dimension set** — issue fidelity (Agent 0, PR targets only), correctness (Agents 1a/1b/1c), **security (Agent 2)**, quality (Agents 3a/3b/3c), performance (Agent 4), **test coverage (Agent 5)**, and **build & test (Agent 7)** — followed by a **single verification pass** (Step 4). It loads and enforces project rules (Step 2) and runs `comment-status` like high. It **skips** the adversarial-persona agents (6a/6b/6c), the language-pitfall and wrapper/proxy specialists (Agents 1d/1e), the diff-specialist finders (Agent 8), the **reverse audit** (Step 5), the incremental cache, and PR posting (`--comment` still forces high). Findings are **verified** (Step 4 ran — they are not "unverified" the way low's are), but without the reverse-audit second pass. Reach for it when high is too slow/expensive but a real bug-catching review is still needed: it keeps the two things that reliably catch bugs cheaply — the finder fan-out and `build-test` (which mechanically catches compile/test failures) — and drops the depth passes with the lowest marginal yield. Measured against high on the same PR it lands at roughly **one-third to one-half** the time and tokens. It reliably catches mechanical defects (compile errors, failing tests) and obvious correctness bugs, but is **not an exhaustive correctness audit** — a subtle Critical that only the reverse audit or the adversarial personas would surface can slip; for a security-sensitive or pre-release review, use `--effort high`.
|
|
87
|
-
- **high** — the full pipeline: parallel review agents (Step 3A/3B — the full dimension set including security, test-coverage, the language-pitfall and wrapper/proxy specialists 1d/1e, the adversarial personas 6a/6b/6c, and Agent 8), verification (Step 4), iterative reverse audit (Step 5), PR submission (Step 7), incremental cache (Step 8).
|
|
85
|
+
- **low** — quick pass. You read the diff yourself, walking it once per **angle** — `plan.budget.inlineAngles` directed angles (3-6, scaled by diff size) plus a gap sweep when the budget asks for one, all in this context — and report up to 10 unverified findings (Step 3C). `plan.budget.candidateFloor` is the stopping signal: an under-floor pass owes one deterministic re-pass, not invented findings. No subagents, no build/test, no verification, no reverse audit, no PR posting, no incremental cache, no project rules. The angle rotation is what makes a subagent-free tier worth running: one undirected read converges on the most visibly suspicious hunk and leaves the rest of the diff unexamined, and that is the pass this replaces.
|
|
86
|
+
- **medium** — **balanced**: the high pipeline with its most expensive passes removed. It runs the parallel review agents (Step 3A/3B) over a **reduced dimension set** — issue fidelity (Agent 0, PR targets only), correctness (Agents 1a/1b/1c), **security (Agent 2)**, quality (Agents 3a/3b/3c), performance (Agent 4), **test coverage (Agent 5)**, and **build & test (Agent 7)** — plus the prose-execution audit (`prose-exec`) where the run owes it — a diff touching an instruction file, a plan whose file list is unknown, or a repository context requiring it, and only when the review has a tree (worktree mode; cross-repo lightweight never owes it); it is not effort-gated — followed by a **single verification pass** (Step 4). It loads and enforces project rules (Step 2) and runs `comment-status` like high. It **skips** the adversarial-persona agents (6a/6b/6c), the counter-frame audit (6d), the language-pitfall and wrapper/proxy specialists (Agents 1d/1e), the diff-specialist finders (Agent 8), the **reverse audit** (Step 5), the incremental cache, and PR posting (`--comment` still forces high). Findings are **verified** (Step 4 ran — they are not "unverified" the way low's are), but without the reverse-audit second pass. Reach for it when high is too slow/expensive but a real bug-catching review is still needed: it keeps the two things that reliably catch bugs cheaply — the finder fan-out and `build-test` (which mechanically catches compile/test failures) — and drops the depth passes with the lowest marginal yield. Measured against high on the same PR it lands at roughly **one-third to one-half** the time and tokens. It reliably catches mechanical defects (compile errors, failing tests) and obvious correctness bugs, but is **not an exhaustive correctness audit** — a subtle Critical that only the reverse audit or the adversarial personas would surface can slip; for a security-sensitive or pre-release review, use `--effort high`.
|
|
87
|
+
- **high** — the full pipeline: parallel review agents (Step 3A/3B — the full dimension set including security, test-coverage, the language-pitfall and wrapper/proxy specialists 1d/1e, the adversarial personas 6a/6b/6c, the counter-frame audit 6d (PR targets only), and Agent 8), verification (Step 4), iterative reverse audit (Step 5), PR submission (Step 7), incremental cache (Step 8).
|
|
88
88
|
|
|
89
89
|
The three levels above are the standing effort axis. **`--topology minimal` is a separate axis — a different _shape_ of review, not a depth of one — and it overrides the effort dispatch.** It is the A/B comparison arm from issue #9783: a single careful senior-engineer pass over the diff in this context, at most fifteen findings, each carrying a concrete failure scenario; no subagents, no build/test, no verification, no reverse audit, no posting, no incremental cache, no project rules. It exists so the full pipeline and this minimal prompt can be run over the same PR set and compared per model — the hypothesis being that the scaffolding's marginal value shrinks (even turns negative) as the model gets stronger. When the verdict's `topology` is `minimal`, capture the diff exactly as this step describes, then run **Step 3M** and skip everything else.
|
|
90
90
|
|
|
@@ -107,7 +107,7 @@ For **every** `pr-url` target — **`github.com` included** — **pass `--host <
|
|
|
107
107
|
|
|
108
108
|
For an **Aone Code** target — a `…/codereview/<id>` URL, a `pr-url` whose verdict `host` is `code.alibaba-inc.com` or `gitlab.alibaba-inc.com`, or a bare PR number where `review meta` reports `platform: "aone"` — **read `references/aone.md` from this skill's base directory now, before `match-remote` and `fetch-pr`**, and follow it: it owns the Aone clone requirement, the two-host-name rule, the a1-backed subcommand surface, and Aone's posting and dedup shapes. GitHub runs never read it.
|
|
109
109
|
|
|
110
|
-
3. If **no remote matches**, use **lightweight mode**: fetch the diff directly with `"${QWEN_CODE_CLI:-qwen}" review fetch-diff <number> --repo <owner>/<repo> --host <host> --out .qwen/tmp/qwen-review-pr-<number>-diff.txt` (the URL's host — `github.com` included, per the host rule above: without it the cwd clone's origin picks the platform). If `fetch-diff` fails here (auth, network), inform the user and stop — lightweight mode has no diff to review and no later step refetches it. Skip Step 2 (no local rules) and Step 8 (no local reports or cache). In Step 9, skip worktree removal (none was created) but still clean up temp files (`.qwen/tmp/qwen-review-{target}-*`). Also run `"${QWEN_CODE_CLI:-qwen}" review pr-context <number> <owner>/<repo> --host <host> --out .qwen/tmp/qwen-review-pr-<number>-context.md` — it is pure platform API and works cross-repo. Agent 0 and Step 6's open-Critical re-check depend on it: a `Refs #123`-style target issue is only discoverable from the PR body, and open Critical threads only from the context file, so skipping it lets a wrong-root fix sail through blocker-free. If `pr-context` fails here (auth, network), warn and continue with the diff alone — but skip Agent 0
|
|
110
|
+
3. If **no remote matches**, use **lightweight mode**: fetch the diff directly with `"${QWEN_CODE_CLI:-qwen}" review fetch-diff <number> --repo <owner>/<repo> --host <host> --out .qwen/tmp/qwen-review-pr-<number>-diff.txt` (the URL's host — `github.com` included, per the host rule above: without it the cwd clone's origin picks the platform). If `fetch-diff` fails here (auth, network), inform the user and stop — lightweight mode has no diff to review and no later step refetches it. Skip Step 2 (no local rules) and Step 8 (no local reports or cache). In Step 9, skip worktree removal (none was created) but still clean up temp files (`.qwen/tmp/qwen-review-{target}-*`). Also run `"${QWEN_CODE_CLI:-qwen}" review pr-context <number> <owner>/<repo> --host <host> --out .qwen/tmp/qwen-review-pr-<number>-context.md` — it is pure platform API and works cross-repo. Agent 0 and Step 6's open-Critical re-check depend on it: a `Refs #123`-style target issue is only discoverable from the PR body, and open Critical threads only from the context file, so skipping it lets a wrong-root fix sail through blocker-free. If `pr-context` fails here (auth, network), warn and continue with the diff alone — but skip Agent 0 and the counter-frame audit 6d (both work from the PR context, and the roster drops them with the missing PR identity) and treat every open-Critical re-check verdict as "cannot tell", which forbids an Approve. Carry this forward as the **context-unavailable** state: Step 7's invariant caps **every** `C=0` outcome of such a run at `COMMENT` with a diff-only body (both the would-be APPROVE and the Suggestion-only "no blockers" sentence), so a run that could not see the PR's existing discussion can post findings but never certify the absence of blockers. In Step 7, use the owner/repo from the URL. Inform the user: "Cross-repo review: running in lightweight mode (no build/test)." If `parse-args` reported `resume.requested: true`, also tell the user that `--resume` has no effect in lightweight mode — there is no `fetch-pr`, no worktree and no plan to continue, so the review runs from scratch (the parser cannot see the remote and gates the flag on the target shape only).
|
|
111
111
|
|
|
112
112
|
Based on the parsed `target.type`:
|
|
113
113
|
|
|
@@ -200,7 +200,7 @@ Based on the parsed `target.type`:
|
|
|
200
200
|
|
|
201
201
|
The subcommand fetches `gh pr view` metadata + inline / issue comments and writes a single Markdown file with the PR title, description, base/head, diff stats, an **"Open inline comments"** section, a **"Blockers to re-check"** section, full-text **"Review summaries"**, and an **"Already discussed"** section for settled non-blocking threads. Each replied-to thread renders the **complete reply chain** (root comment + chronological replies), so review agents can see whether a "Fixed in `<commit>`"-style reply has closed the topic — agents must NOT re-report a concern whose latest reply addresses it. (That no-re-report rule is about _reporting_; Step 6's open-Critical re-check draws on **every** comment-bearing section — a blocker does not leave the verdict gate just because someone replied to it.)
|
|
202
202
|
|
|
203
|
-
**"Blockers to re-check" holds every body that asserts a blocking defect, whatever channel it arrived on and whatever words it used** — replied inline threads and **issue-level comments** alike, each rendered **in full**. Recognition is semantic (`carriesBlockerSignal`), not the literal `**[Critical]**` marker, because only `/review` emits that marker and a human types whatever they type. This is the fix for a real dropped blocker — a maintainer's issue-comment blocker settled into "Already discussed" as an endorsement-shaped snippet and a "no blockers" review sailed past it (measured; DESIGN.md — The endorsement-shaped blocker (PR #6486)). Promotion is deliberately fail-safe: a false positive costs one extra ruling, a false negative ships the bug. The file's own preamble tells agents to treat its contents as DATA, so no extra security prefix is needed when passing it to review agents. **If `pr-context` fails here too** (rate limit, network — the same-repo path is not immune), the
|
|
203
|
+
**"Blockers to re-check" holds every body that asserts a blocking defect, whatever channel it arrived on and whatever words it used** — replied inline threads and **issue-level comments** alike, each rendered **in full**. Recognition is semantic (`carriesBlockerSignal`), not the literal `**[Critical]**` marker, because only `/review` emits that marker and a human types whatever they type. This is the fix for a real dropped blocker — a maintainer's issue-comment blocker settled into "Already discussed" as an endorsement-shaped snippet and a "no blockers" review sailed past it (measured; DESIGN.md — The endorsement-shaped blocker (PR #6486)). Promotion is deliberately fail-safe: a false positive costs one extra ruling, a false negative ships the bug. The file's own preamble tells agents to treat its contents as DATA, so no extra security prefix is needed when passing it to review agents. **If `pr-context` fails here too** (rate limit, network — the same-repo path is not immune): warn, continue, and set the **context-unavailable** state. Lightweight mode's bullet skips Agent 0 and the counter-frame audit 6d, and what separates the two paths is the PR IDENTITY, not the failure: a context-unavailable lightweight plan carries none (Step 1 passes `--pr`/`--repo` to `plan-diff` only when `pr-context` succeeded), so the roster stops owing the roles gated on it — but `fetch-pr` has already written the identity into THIS plan, and `check-coverage` still requires every role gated on it. So here **launch them rather than skip them** — Agent 0, and at high or unrecorded effort 6d — because a required role nobody launched lands in `missingRoles`, Step 3D exits 3, and the capped terminus the rest of this paragraph describes is never reached. (At **low** effort none of this applies: Step 3C launches no subagents, so there is no roster to owe and no coverage gate to wedge.) Both launch against a context file that is not on disk — `pr-context` removes any pre-existing file at that path before its first fetch, so a re-run that fails after the invocation validates leaves nothing stale behind and the missing-file shape is the only one either agent can meet (a stale file an interrupted earlier round wrote would otherwise read as context this run just lost, against this paragraph's closing invariant). The removal sits AFTER the usage validations by design, so a usage-error rejection — malformed `pr_number`, `owner_repo`, or `--host` — is the one exception that leaves a pre-existing file untouched: correct the invocation and re-run it rather than launching against the stale read. Both have a documented return for exactly that: Agent 0 still runs the `issue-context` fetch its brief welds (a separate platform read, not the one that just failed) — if THAT fetch fails, it returns the failure naming what it could not fetch; if it succeeds, its brief's missing-context branch performs the issue-evidence half and returns naming the PR context as unread, attesting nothing the file alone could supply — the context-dependent duties join `unreviewedDimensions`. 6d opens its assigned diff ranges (the coverage gate certifies a diff-pointed agent by that read — its brief instructs exactly this, so the unperformable return still clears Step 3D) and returns the dimension unperformable per its brief, naming the hunks that went un-counter-framed. A return that could perform nothing joins `unreviewedDimensions` like any other dimension nobody could review — Step 6 skips the re-check walk (every existing Critical is `cannot tell`) and Step 7 caps the event. A same-repo run that lost the context file must not behave as if it had read it.
|
|
204
204
|
|
|
205
205
|
**`read_file` returns the first `truncateToolOutputThreshold` characters (25 000 by default) and sets `isTruncated`. Read that flag.** On a PR with a long history the context file exceeds it — `pr-context` prints a `warning:` line naming the size and any headings past the cut. When it does, page the remainder with `offset`/`limit` before Step 3, and pass the _whole_ file's contents onward. A review that never reached the open-comment section will report "no blockers" without having seen a single one of them.
|
|
206
206
|
|
|
@@ -244,7 +244,7 @@ Read from it:
|
|
|
244
244
|
- `diffLines`, `diffChars`, and `srcDiffLines` / `testDiffLines` / `docsDiffLines` / `generatedDiffLines`
|
|
245
245
|
- `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.
|
|
246
246
|
- `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
|
|
247
|
-
- `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` and `
|
|
247
|
+
- `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 a deadline** (`QWEN_REVIEW_DEADLINE_EPOCH`); without a clock a huge diff is just a large 3B diff and gets 5. 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 ceiling 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 that has a 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 a deadline it reads 5, the same as the flat fallback.
|
|
248
248
|
A chunk is read with `read_file(file_path=diffPathAbsolute, offset=startLine - 1, limit=endLine - startLine + 1)` — `offset` is 0-based.
|
|
249
249
|
|
|
250
250
|
For **local-diff and file-path reviews**, capture and plan in one command:
|
|
@@ -334,7 +334,7 @@ For **cross-repo lightweight reviews**, do the same with the diff the platform h
|
|
|
334
334
|
# lightweight run has no fetch-pr to carry the host otherwise.
|
|
335
335
|
```
|
|
336
336
|
|
|
337
|
-
**Pass `--pr`/`--repo` only when the `pr-context` fetch above succeeded** — they put the PR identity into the plan, which makes the roster REQUIRE Agent 0 (`check-coverage` will name
|
|
337
|
+
**Pass `--pr`/`--repo` only when the `pr-context` fetch above succeeded** — they put the PR identity into the plan, which makes the roster REQUIRE Agent 0 — and, at high or unrecorded effort, the counter-frame audit 6d (`check-coverage` will name either if it never runs, exactly as in worktree mode). If `pr-context` failed, omit them: the run is in the context-unavailable state, and omitting the identity is what DROPS the requirement — the roster then stops owing the very roles this mode's bullet tells you to skip, so neither can land in `missingRoles`. Not because they are unbriefable: given the identity, `agent-prompt` builds both with no context file on disk (that is the same-repo failure path above, which keeps them on the roster and launches them for an unperformable return); the builder throws only when the identity is ABSENT.
|
|
338
338
|
|
|
339
339
|
`plan-diff` and `capture-local` emit the same `diffPathAbsolute`, `chunks[]`, `files[]` and topology counts as `fetch-pr`, so Steps 3A, 3B and 7 work identically on all four review paths. Neither can decide `heavy` — that needs a tree to read the post-change file from — so no invariant agents run on a bare diff.
|
|
340
340
|
|
|
@@ -347,9 +347,9 @@ If `diffPath` is `null` (merge-base could not be resolved), fall back to giving
|
|
|
347
347
|
|
|
348
348
|
This routing is yours to decide, but it is not silent if you decide against the plan's own numbers: the per-chunk builders check the same gate (`--all-chunks`, and a `--chunk` build of a round that has no admission stamp yet), and if the plan's `srcDiffLines`/`diffLines` say Step 3A while a per-chunk fan-out is built, they print a stderr note saying so and build anyway (#9242). They do not refuse — a legitimate 3A plan can carry chunks for read paging, and a `--chunk` rebuild of an already-admitted round is exempt — so when the note fires, say in the round whether the fan-out is deliberate before proceeding, rather than letting the mismatch ride unexplained.
|
|
349
349
|
|
|
350
|
-
Test code is where diff size lies. Across this repo's last 40 merged PRs the median diff is **41% test code**, and a third of them are more than half tests. Prose and lockfiles are excluded for the same reason — a translation PR carries no runtime risk. Markdown _inside a source tree_ still counts as source: this skill is one such file. A change of 173 production lines that ships 489 lines of new tests is a small change; carving it into territories spends most of the reviewers on test files and leaves the production code with **one** agent instead of the
|
|
350
|
+
Test code is where diff size lies. Across this repo's last 40 merged PRs the median diff is **41% test code**, and a third of them are more than half tests. Prose and lockfiles are excluded for the same reason — a translation PR carries no runtime risk. Markdown _inside a source tree_ still counts as source: this skill is one such file. A change of 173 production lines that ships 489 lines of new tests is a small change; carving it into territories spends most of the reviewers on test files and leaves the production code with **one** agent instead of the fifteen lenses it deserves ("lenses" = the diff-reading dimension agents: the seventeen minus Issue Fidelity and Build & Test, which read the issue and run commands rather than reviewing the diff). Territory fan-out earns its keep when there is a lot of _risky_ code to divide, not a lot of _lines_.
|
|
351
351
|
|
|
352
|
-
The second clause is an attention bound, not a risk one: past roughly 3200 diff lines, asking the
|
|
352
|
+
The second clause is an attention bound, not a risk one: past roughly 3200 diff lines, asking the sixteen diff-reading agents each to read the whole diff dilutes them all, and the chunk topology's base cost (`ceil(diffLines / 400) + 5` diff-reading agents on a PR review — 0, 1b, 1c, the test matrix and 6d, plus `prose-exec` when the run owes it — before invariant and specialized ones; Build & Test reads no diff) crosses that count nearer 4 400. The gate stays at 3 200 rather than moving with the roster: fanning out _before_ the crossover errs toward one accountable reader per line, which is the property 3B is bought for, and a gate that drifts every time a dimension is split or merged is a gate nobody can reason about. It is not a guarantee of fewer calls — a heavy file adds `3` invariant agents and a dominant domain up to `2` specialized finders, so a barely-over-the-line changeset can cost more under 3B than 3A; what 3B buys at that size is one accountable reader per line instead of sixteen diluted ones. It is the safety valve for a changeset dominated by tests or generated files.
|
|
353
353
|
|
|
354
354
|
Either way the chunk plan covers **every** line — tests and generated files included. What changes is how many reviewers are assigned and what each is asked to do, not what gets read.
|
|
355
355
|
|
|
@@ -381,7 +381,7 @@ Do NOT inject review rules into Agent 7 (Build & Test) — it runs deterministic
|
|
|
381
381
|
|
|
382
382
|
**If the verdict's `topology` is `minimal`, skip everything in this step and its sub-steps and run Step 3M instead** — the single-pass A/B arm defined after Step 3C. The rest of this dispatch applies only to `topology: auto`.
|
|
383
383
|
|
|
384
|
-
**Steps 3A/3B and 4 run at high and medium effort; Step 5 (reverse audit) is high only.** At **low** effort skip 3A/3B/4/5 and run **Step 3C** instead — an inline pass with no subagents, defined after the agent dimensions. **Medium** runs 3A/3B and Step 4 with the reductions the effort table names: a smaller dimension set (skip the adversarial personas 6a/6b/6c, the language-pitfall and wrapper/proxy specialists 1d/1e, and the Agent 8 diff-specialists), a capped territory fan-out on large diffs (Step 3B below), and **no reverse audit** — it stops after Step 4. The incremental cache and PR posting stay high-only at medium too.
|
|
384
|
+
**Steps 3A/3B and 4 run at high and medium effort; Step 5 (reverse audit) is high only.** At **low** effort skip 3A/3B/4/5 and run **Step 3C** instead — an inline pass with no subagents, defined after the agent dimensions. **Medium** runs 3A/3B and Step 4 with the reductions the effort table names: a smaller dimension set (skip the adversarial personas 6a/6b/6c, the counter-frame audit 6d, the language-pitfall and wrapper/proxy specialists 1d/1e, and the Agent 8 diff-specialists), a capped territory fan-out on large diffs (Step 3B below), and **no reverse audit** — it stops after Step 4. The incremental cache and PR posting stay high-only at medium too.
|
|
385
385
|
|
|
386
386
|
Launch review agents by invoking all `agent` tools in a **single response**. The runtime executes agent tools concurrently — they will run in parallel. You MUST include all tool calls in one response; do NOT send them one at a time.
|
|
387
387
|
|
|
@@ -389,9 +389,9 @@ Use **Step 3A** or **Step 3B** as the topology gate in Step 1 decided. The dimen
|
|
|
389
389
|
|
|
390
390
|
## Step 3A: Dimension fan-out (small source change)
|
|
391
391
|
|
|
392
|
-
Launch **
|
|
392
|
+
Launch **17 agents** for same-repo **PR** reviews (Agent 1 has three procedural variants 1a/1b/1c plus two dedicated angles 1d/1e — the language-pitfall scan and wrapper/proxy routing, Agent 3 has three checklist slices 3a/3b/3c, and Agent 6 has four variants — the three personas 6a/6b/6c and the counter-frame audit 6d — each variant counts as a separate parallel agent), plus up to 2 optional diff-specialized finders (Agent 8) when the diff's domain calls for them. **Agent 1e is conditional:** it is rostered only when the plan's `wrapperSignal` is true — the capture command's cheap signal that the diff touches a wrapping type (a path or added line matching the wrapper vocabulary: wrapper/proxy/decorator/adapter/delegate/facade/cached/caching) — and the gate fails safe, so an absent or ambiguous field rosters it too; a diff with no wrapping type costs one agent that returns an empty-scope receipt. For cross-repo lightweight **PR** mode launch **15 agents** — skip Agent 7 (Build & Test) and Agent 1c (Cross-file tracer), since there is no local codebase to build, test, or grep (6d stays: it reads the diff and the PR context, needing no tree — but, like Agent 0, only while the lightweight plan carries the PR identity, i.e. `pr-context` succeeded; a lightweight plan without it drops both and owes **13**). (Agent 8 finders need only the diff, so the up-to-2 option applies in every mode — lightweight and local included.) Lightweight mode also degrades Agents 1a, 1b and 1e, whose briefs assume a source tree: the builder tells them they have the diff ONLY — 1a reviews hunks without enclosing-function reads, and 1b and 1e, when the evidence they would need sits outside the diff (a deleted invariant's re-establishment, a wrapper's call sites), report the candidate at `Confidence: low` and say the check could not be made, instead of asserting the worst. Step 4's verifiers operate under the same limit, so lightweight-mode findings that depend on unseen source must stay low-confidence (terminal-only) rather than becoming public blockers. **Agent 0 (Issue Fidelity) and the counter-frame audit (6d) run only when the review target is a PR** — a local-diff or file-path review has no PR, no linked issue, and no description whose frame could be countered or incident replayed, so skip both and launch **15 agents** (Agents 1a–1e, 2–5, 6a/6b/6c, 7). Each agent should focus exclusively on its dimension. (Agent counts are maxima: on a diff with no removed or replaced lines, Agent 1b has nothing to audit and is skipped — one fewer agent — unless a repository context requires it back, and Agent 1e launches only when the plan's `wrapperSignal` is true — which the `--roster` output below shows. And the prose-execution audit (`prose-exec`) joins the roster when the diff touches an instruction file — the roster's `isPromptPath` detector is the authority and the `--roster` output is the list; the reserved shapes it recognises today: a `SKILL.md`, the root guidance files (`AGENTS.md`/`CLAUDE.md`/`QWEN.md`/`GEMINI.md`, `copilot-instructions.md`), agent and slash-command definitions under `.claude/` or `.qwen/` (`agents/`, `commands/`), a `prompts/` file, the pipeline's own `.qwen/review-rules.md`, or a prompt/brief-named source file — or when a repository context requires it back where the detector misses, or when the plan carries no file list at all (an older CLI's plan fails safe and rosters it, as it does 1b): one more agent on exactly those diffs, in both topologies and at every effort, whenever the review has a tree — its method is executing the repository's own tooling, and cross-repo lightweight mode has no tree, so it never joins there — because instruction prose is executed there, not read.)
|
|
393
393
|
|
|
394
|
-
**At medium effort, launch the reduced set:** skip the
|
|
394
|
+
**At medium effort, launch the reduced set:** skip the four undirected-audit agents (6a/6b/6c and the counter-frame audit 6d), the two dedicated angles (Agents 1d/1e), and the Agent 8 diff-specialists, launching Agents 0 (PR targets only), 1a, 1b, 1c, 2, 3a, 3b, 3c, 4, 5, and 7 (plus `prose-exec` when the diff owes it — it is not effort-gated) — **11 agents** for a same-repo PR, **10** for a local-diff or file-path review (no Agent 0), **9** for cross-repo lightweight (drop Agent 7 and 1c too, as above; **8** when the lightweight plan carries no PR identity, since Agent 0 drops with it). Everything else about 3A is identical — the briefs, the `working_dir` pin, the whiff check, coverage; medium changes only which dimensions launch, not how any agent runs. **Build the roster with `agent-prompt --roster`** — it reads the effort the plan recorded at Step 1 (`plan.effort`), so on a medium plan it omits 6a/6b/6c/6d and 1d/1e from the roster it prints (Agent 8 was never in it) and you launch exactly these agents. `check-coverage` (Step 3D) reads the **same** `plan.effort` and requires exactly these too — no flag to pass, and no way for the roster you launched and the gate that checks it to disagree. (The effort lives in the plan, not in a flag, on purpose: a roster a caller could shrink by omitting a flag is a roster that gets shrunk. If Step 1 recorded no effort, the full roster is required, personas included — the fail-safe, not a medium review.)
|
|
395
395
|
|
|
396
396
|
**Do not write these prompts, and do not ask for them one at a time. One call builds all of them:**
|
|
397
397
|
|
|
@@ -403,7 +403,7 @@ Launch **16 agents** for same-repo **PR** reviews (Agent 1 has three procedural
|
|
|
403
403
|
|
|
404
404
|
**Redirected to a file, then `read_file` it, paging until `isTruncated` is false** — the same rule as every other large output in this skill: shell output truncates at 30 000 characters, and a large plan's roster exceeds that, which would silently swallow the middle blocks. The output is self-checking: blocks are numbered `agent k of N` and the file ends with an `end of roster` line — if any `k` is missing or the end line is absent, rebuild just those blocks with `--chunk <id>` / `--role <r>` (every prompt is also recorded on disk regardless).
|
|
405
405
|
|
|
406
|
-
It prints one labelled block per required agent — which roles this review owes is read out of the plan, so the paragraph above is the _why_ and the roster is the _list_ — and **each block goes to its agent verbatim**, all launched in one response. To rebuild a single agent's prompt (a relaunch after Step 3D): `--role <role>` in place of `--roster`; the roles are `0`, `1a`, `1b`, `1c`, `1d`, `1e`, `2`, `3a`, `3b`, `3c`, `4`, `5`, `6a`, `6b`, `6c`, `7`.
|
|
406
|
+
It prints one labelled block per required agent — which roles this review owes is read out of the plan, so the paragraph above is the _why_ and the roster is the _list_ — and **each block goes to its agent verbatim**, all launched in one response. To rebuild a single agent's prompt (a relaunch after Step 3D): `--role <role>` in place of `--roster`; the roles are `0`, `1a`, `1b`, `1c`, `1d`, `1e`, `2`, `3a`, `3b`, `3c`, `4`, `5`, `6a`, `6b`, `6c`, `6d`, `7`, `prose-exec`.
|
|
407
407
|
|
|
408
408
|
**What it prints is short — a few hundred characters — and it is short on purpose.** It names the agent's role, points at the **brief file** the command just wrote, and lists the `read_file` calls for the diff. The brief itself — the dimension, the finding format, the severity definitions, the project rules — is on disk, and the agent reads it, exactly as it reads the diff. That is not an optimisation. A real run asked to paste twelve prompts cut nineteen hundred characters out of one and then talked its way past the check that caught it (measured; DESIGN.md — The paraphrased roster prompt). What you are asked to carry is now small enough that you will carry it. Copy it; do not retype it. (Agent 8, when you launch one, is the exception — its brief is the one you write, so give it `--whole-diff` and append your domain brief.)
|
|
409
409
|
|
|
@@ -413,9 +413,9 @@ Why: **the roles this command does not build are the roles that go missing.** Ha
|
|
|
413
413
|
|
|
414
414
|
## Step 3B: Territory × dimension fan-out (large source change)
|
|
415
415
|
|
|
416
|
-
|
|
416
|
+
Sixteen agents all reading the same diff (every 3A agent except Build & Test walks the whole chunk plan) multiplies redundant reading of the early hunks; it does not add coverage. Once there is enough production code to divide, fan out along **territory** as well: one agent per chunk, with the review dimensions folded into that agent's brief, plus a small set of whole-diff agents for the concerns that only exist at diff scale.
|
|
417
417
|
|
|
418
|
-
**At medium effort, drop the diff-specialists; keep the Step 1 plan as it is.** Do **not** re-run `plan-diff` to coarsen the territory. On a same-repo PR that feeds the diff back through the lightweight path, producing a plan with no `worktreePath` and none of `fetch-pr`'s per-file / heavy-file metadata — the roster then legitimately drops Agent 7 and
|
|
418
|
+
**At medium effort, drop the diff-specialists; keep the Step 1 plan as it is.** Do **not** re-run `plan-diff` to coarsen the territory. On a same-repo PR that feeds the diff back through the lightweight path, producing a plan with no `worktreePath` and none of `fetch-pr`'s per-file / heavy-file metadata — the roster then legitimately drops Agent 7, 1c, and the prose-execution audit — all three need a tree (and, writing to the same `--out`, clobbers the `worktreePath`/`prNumber`/`ownerRepo` that Steps 3D, 6 and 7 read; writing to a different path splits the prompt records so `check-coverage` finds none). `capture-local` has no coarsening option at all. The reverse audit medium already skips is the main saving; the extra chunk agents a finer plan launches are cheap beside it. Do **not** launch the Agent 8 diff-specialists. The whole-diff agents (Agent 0, 1b, 1c, Agent 7, the invariant agents, the test-coverage matrix, and `prose-exec` when the diff owes it — it is not effort-gated) run exactly as in high, minus the counter-frame audit 6d, which medium skips with the personas — they are the cross-chunk safety net medium keeps. Everything else about 3B is identical.
|
|
419
419
|
|
|
420
420
|
**Chunk agents — one per entry in `chunks[]`.** Each is a `review-agent` subagent. **Do not write their prompts, and do not ask for them one at a time — one call builds the whole 3B fan-out, chunk agents, whole-diff agents and invariant agents alike:**
|
|
421
421
|
|
|
@@ -441,13 +441,13 @@ Everything below still governs what the agent is asked to do; the command builds
|
|
|
441
441
|
- **An instruction to page.** Ordinary chunks are sized to fit one un-truncated read, but a chunk whose `oversized` flag is set is a single hunk that offered no safe place to cut, and its `chars` can exceed one read's ~25 000. Tell the agent: if the read comes back with `isTruncated`, keep calling `read_file` with a larger `offset` until it has the whole range. An agent that returns a `Covered:` receipt for a range it only half read makes the coverage guarantee a lie — which is worse than not having one.
|
|
442
442
|
- **What to do when paging cannot help.** A chunk whose `maxLineChars` exceeds ~25 000 contains a single line longer than one read returns — a minified bundle, a base64 blob. Paging starts every page at a line boundary, so the tail of that line is unreachable by any `offset`. Such a chunk MUST NOT be receipted as covered. Tell the agent to return, instead of the receipt: `Uncoverable: chunk <id> — line exceeds the read limit`. Report those chunks to the user in Step 6 and do not let the verdict be Approve on their strength.
|
|
443
443
|
- Permission to read the **full source files** it covers (via `read_file` on the worktree path) whenever a hunk's correctness depends on code outside the hunk. Diff context lines are three lines deep; state invariants are not. A source file over ~25 000 characters comes back with `isTruncated` set — page through it rather than reasoning from the first screenful.
|
|
444
|
-
- The review focus: it owns **all** of Agents 1a, 1b, 1d, 1e, and 2–6's dimensions (line-by-line correctness, the language-pitfall scan, wrapper/proxy routing, the removed-behavior audit of its own deleted lines, security, all three code-quality slices — reuse/duplication, altitude and abstraction fit, sibling consistency and clarity — performance, test coverage, and the three adversarial personas) **for its territory only**.
|
|
444
|
+
- The review focus: it owns **all** of Agents 1a, 1b, 1d, 1e, and 2–6's dimensions (line-by-line correctness, the language-pitfall scan, wrapper/proxy routing, the removed-behavior audit of its own deleted lines, security, all three code-quality slices — reuse/duplication, altitude and abstraction fit, sibling consistency and clarity — performance, test coverage, and the three adversarial personas) **for its territory only**. Some duties are whole-diff agents, not chunk duties, because a chunk agent is structurally blind to them: **cross-file tracing (Agent 1c)** — it cannot see a caller that lives in another chunk; the **cross-chunk half of removed-behavior (Agent 1b)** — it cannot see that its deleted export's replacement, three files away, quietly changed a default; the **counter-frame audit (6d)**, where the run owes it — the author's frame spans every territory, so no chunk can escape it from inside one (a review that owes no 6d — medium effort, or no PR target — carves nothing out here: the adversarial reading stays the chunk agent's, whole); and the **prose-execution audit (`prose-exec`)** when the diff owes it — a recipe's steps rarely respect chunk boundaries. Audit the deletions in your own territory; do not conclude a deletion is unreplaced merely because the replacement is not in your range.
|
|
445
445
|
- **The severity definitions from the finding format below, verbatim.** A chunk agent owns the test-coverage dimension with no dedicated agent to calibrate it, and an uncalibrated agent files "zero test coverage" as Critical. It has happened.
|
|
446
446
|
- Project-specific rules from Step 2 (if any).
|
|
447
447
|
|
|
448
448
|
**Whole-diff agents — launched alongside the chunk agents, in the same response.**
|
|
449
449
|
|
|
450
|
-
**Their blocks are already in the `--roster` output above — you have them.** Roles there: `0` (PR reviews), `1b` (when the diff removes anything, or a repository context requires it), `1c`, `test-matrix`, `7` (same-repo), and for a **heavy** file three more, one per checklist slice (their blocks are labelled `Invariant agent A|B|C: … — <path>`). Pass each **verbatim**. To rebuild one for a relaunch: `--role <role>` (an invariant agent adds `--file <path>`). `check-coverage` derives the same list from the plan and will name any role that did not run.
|
|
450
|
+
**Their blocks are already in the `--roster` output above — you have them.** 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>`). Pass each **verbatim**. To rebuild one for a relaunch: `--role <role>` (an invariant agent adds `--file <path>`). `check-coverage` derives the same list from the plan and will name any role that did not run.
|
|
451
451
|
|
|
452
452
|
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).
|
|
453
453
|
|
|
@@ -489,7 +489,7 @@ Three ranges exist in the report and they are not interchangeable, which is why
|
|
|
489
489
|
--out .qwen/tmp/qwen-review-{target}-coverage.json
|
|
490
490
|
```
|
|
491
491
|
|
|
492
|
-
The gate reads the effort from the plan (`plan.effort`, recorded at Step 1) — the same value `agent-prompt --roster` read — so on a medium plan it requires the balanced set (no 6a/6b/6c, no 1d/1e) automatically, and a medium review is not flagged for the agents it deliberately did not run. There is no flag to pass: the roster you launched and the gate that checks it read one field, so they cannot disagree. On a resumed run (Step 1's `--resume`) the gate also reads the interrupted attempt's transcripts itself and credits its certified agents — reported as `recoveredAgents`, with a continuity disclosure — so you neither vouch for the previous attempt's work nor relaunch what it demonstrably finished.
|
|
492
|
+
The gate reads the effort from the plan (`plan.effort`, recorded at Step 1) — the same value `agent-prompt --roster` read — so on a medium plan it requires the balanced set (no 6a/6b/6c, no 6d, no 1d/1e) automatically, and a medium review is not flagged for the agents it deliberately did not run. There is no flag to pass: the roster you launched and the gate that checks it read one field, so they cannot disagree. On a resumed run (Step 1's `--resume`) the gate also reads the interrupted attempt's transcripts itself and credits its certified agents — reported as `recoveredAgents`, with a continuity disclosure — so you neither vouch for the previous attempt's work nor relaunch what it demonstrably finished.
|
|
493
493
|
|
|
494
494
|
**This step runs on both topologies.** An earlier 3B-only model of coverage told a fully-covered 3A review that nobody had read it (measured; DESIGN.md — The 3A review told nobody read it). Coverage is now the intersection of two things the harness wrote down: the lines each agent was **pointed at** (its launch prompt) and the fact that it **opened the diff** (a successful tool call naming the diff file).
|
|
495
495
|
|
|
@@ -521,9 +521,9 @@ Agent 2 (Security) — WHIFF (returned "No issues found." with no evidence
|
|
|
521
521
|
|
|
522
522
|
A check you perform silently is a check you skip, and this one has been skipped (measured; DESIGN.md — The six-second Agent 0). The roll-call is what makes that impossible to miss — you cannot write the artifact line for an agent that named no artifact, and a `WHIFF` line you have written is a `WHIFF` you must then act on (relaunch once; on a second bare return, record the dimension in `unreviewedDimensions`, which forbids the Approve).
|
|
523
523
|
|
|
524
|
-
**The whole-diff agents have no receipt, so this is the only check they get: an agent that returns near-instantly with almost no output did not do its job, and its silence is indistinguishable from "found nothing".** This is not hypothetical (measured; DESIGN.md — The eleven-second invariant agent). Apply the check to **every agent that owes no receipt** — in 3B, the whole-diff agents (Agent 0, **1b**, 1c, Agent 7, the invariant agents, the test-coverage matrix, Agent 8); in 3A, **all of them**, since no 3A agent emits a receipt (Agents 0, 1a, 1b, 1c, 1d, 2, 3a, 3b, 3c, 4, 5, 6a, 6b, 6c, 7,
|
|
524
|
+
**The whole-diff agents have no receipt, so this is the only check they get: an agent that returns near-instantly with almost no output did not do its job, and its silence is indistinguishable from "found nothing".** This is not hypothetical (measured; DESIGN.md — The eleven-second invariant agent). Apply the check to **every agent that owes no receipt** — in 3B, the whole-diff agents (Agent 0, **1b**, 1c, Agent 7, the invariant agents, the test-coverage matrix, the counter-frame audit 6d, `prose-exec` when owed, Agent 8); in 3A, **all of them**, since no 3A agent emits a receipt (Agents 0, 1a, 1b, 1c, 1d, 1e when rostered, 2, 3a, 3b, 3c, 4, 5, 6a, 6b, 6c, 6d, 7, `prose-exec` when owed, and Agent 8 if launched). A whiffing 3A dimension agent is exactly as invisible as a whiffing invariant agent, and the same one-line fix applies. For each such agent, sanity-check that its return is substantive: it names the specific fields/callers/lines it walked, or it explicitly says "No issues found" **after** describing what it examined. For **Agent 7** the evidence is the build/test **commands it ran and their outcomes** — a Build & Test return that names no command whiffed even if it says "build passed", and after its second whiff record `build-and-test` in `unreviewedDimensions` like any other dimension: a zero-finding run whose deterministic verification never actually ran must not certify on its silence. **`prose-exec` is the other executor, and gets the same rule:** its evidence is the **recipe steps it executed and their observed outcomes** — a prose-exec return that names no executed step whiffed even if it says the prose is consistent (reading is exactly the evidence this role exists to distrust) — its one legitimate step-less return is the documented empty scope, `No issues found — scope empty` naming the files it read and why none of them holds executable guidance (pure description, naming, rationale), which is a complete answer exactly as Agent 0's below is; on a local-diff or file-path review, where no disposable copy is welded (the tree under review is the uncommitted checkout itself), a return that ran the read-only steps in place and quotes each write-producing step as `not executed — no disposable copy on a local review` is complete too — and after its second whiff record `prose-execution` in `unreviewedDimensions` the same way. A legitimately empty scope also passes — Agent 0 on a feature PR with no linked issue returns "No issues found — scope empty" plus the evidence it checked (empty `closingIssuesReferences`, no referenced issue, not a bugfix — plus, when the description narrates a motivating incident, the replay's outcome: the step the replay saw change, or, when it narrates none, an explicit statement of that; a replay that found NO step changed arrives as a Critical **finding**, never inside this receipt), and that is a complete answer, not a whiff; do not relaunch it. What fails the check is a bare "No issues found" with no evidence of any walk or scope determination, or a response conspicuously shorter and faster than its peers — relaunch that one agent before Step 4, **once**. The relaunch is capped at one attempt per agent: if the second return is also bare, do not spin — take it, and record that agent's dimension in an **`unreviewedDimensions`** list. (The finding format tells every agent to return `No issues found — <what you examined>`; an agent that ignores that twice is not going to comply on the third ask.) A silent whole-diff agent is the Step-3A/3B equivalent of a chunk with no receipt — **and it is treated like one**: `unreviewedDimensions` is carried into Step 6's "Not reviewed" section, it **forbids an Approve** (a dimension nobody reviewed cannot be certified clean, exactly as an uncoverable chunk cannot), and Step 7 serializes it in the review body (compose-review's `unreviewedDimensions` input), named alongside any uncoverable chunks. A run that silently drops Security or the cross-chunk removed-behavior audit and then posts LGTM is the failure this whole check exists to prevent; noting the gap in the terminal and approving anyway would only move it.
|
|
525
525
|
|
|
526
|
-
**Step 3A has no receipts, and must not.** There every dimension agent walks every chunk, so "exactly one receipt per chunk" would demand either none or one per diff-reading agent —
|
|
526
|
+
**Step 3A has no receipts, and must not.** There every dimension agent walks every chunk, so "exactly one receipt per chunk" would demand either none or one per diff-reading agent — sixteen, or up to eighteen when Agent 8 launches, plus one more when `prose-exec` is owed (every agent except Build & Test reads the diff). Territory ownership is a Step 3B idea. **What Step 3A does not lack is coverage** — that is Step 3D's job on both paths, and it needs no receipt from anyone: it reads the lines each agent was pointed at out of the prompt the CLI built, and the diff reads out of the harness's transcript. A receipt was only ever a sentence the agent typed. (For a while the two were confused, and 3A reviews were told nobody had read them. See Step 3D.) What Step 3A shares is the uncoverable rule, and that needs no agent at all: **a chunk is uncoverable iff its `maxLineChars` exceeds ~25 000**, which the orchestrator reads straight out of the plan before launching anything. Compute that list up front on both paths, carry it into Step 6, and let a Step 3B agent's `Uncoverable` receipt add to it rather than be the only source of it.
|
|
527
527
|
|
|
528
528
|
**Do not let precision suppress recall in this step.** The "if you're unsure, do NOT report it" rule in the Exclusion Criteria applies to **Suggestion** and **Nice to have** findings. A suspected **Critical** must always be reported, marked `low confidence` if uncertain — Step 4's verifier decides. A Critical dropped here is dropped irreversibly; a Critical dropped there is at least reviewed by a second agent.
|
|
529
529
|
|
|
@@ -556,24 +556,26 @@ An agent that finds nothing must say so **and say what it walked** — `No issue
|
|
|
556
556
|
|
|
557
557
|
**`qwen review agent-prompt --role <role>` builds every one of these.** What follows is what each agent is _for_ — so you can read a finding and know which lens produced it, and so you can tell when a run is missing one. It is **not** what the agent is _sent_: that is in the command, and the command's copy is the one that arrives. When the two disagree, the command is right.
|
|
558
558
|
|
|
559
|
-
| Role | What it owns
|
|
560
|
-
| ----------------------------------------- |
|
|
561
|
-
| `0` | **Issue fidelity & root-cause ownership** (PR reviews only). Does the change fix the thing it claims to fix — the _observed_ behaviour in the linked issue, not just the author's theory of it? Is the root cause the client's, or the upstream service's? A client-side workaround for malformed upstream data is a Critical unless a maintainer asked for it. An empty scope (feature PR, no linked issue) is a complete answer, with its evidence.
|
|
562
|
-
| `1a` | **Line-by-line correctness.** Walks every hunk, reading the _enclosing function_ so the change is judged in its real context. Off-by-ones, inverted conditions, missing `await`, swallowed errors. The language-pitfall checklist and wrapper/proxy routing used to ride here as bullets; they are dedicated agents at high (1d/1e).
|
|
563
|
-
| `1b` | **Removed-behavior audit.** Owns the `-` lines, which exist only in the diff — the post-change tree carries no trace of what was deleted. For each removal: what invariant did it enforce, and where is that re-established? Includes removed or renamed _exports_ (compared to their replacement as **behaviour, not names**), changed _literals_ a distant consumer matches on by shape (marker strings, keys, codes, regex text), and whether a rename/format/schema change handles the data that **already exists** (migration / split-brain).
|
|
564
|
-
| `1c` | **Cross-file tracer** (needs a local tree). Owns the whole cross-file walk. _Consumer direction_: grep every caller of every changed export and check it against the new contract. _Producer direction_: for every field the diff **adds**, grep its **read sites** — a live path reading a field the diff never populates is Critical, and nothing in the build will tell you.
|
|
565
|
-
| `1d` | **Language-pitfall scan** (high effort). Carries the classic-footgun checklist for the diff's language — JS/TS `==` coercion, falsy-value traps, loop-variable capture, floating promises; Python mutable defaults and late-binding closures; Go nil-map writes and range-variable capture; Java/Kotlin reference equality; any language's SQL concatenation, DST arithmetic, float equality — and pattern-matches every hunk against it.
|
|
566
|
-
| `1e` | **Wrapper/proxy routing** (high effort; rostered only when the plan's `wrapperSignal` is true). For every type the diff adds or modifies that wraps another — a cache, proxy, decorator, adapter — every method must route through the _wrapped instance_ (never back through a registry/session/global, which re-enters the wrapper), and the wrapper must forward every method its callers actually use, faithfully.
|
|
567
|
-
| `2` | **Security.** Injection, XSS, SSRF, path traversal, authn/authz bypass, secrets in logs, weak crypto, hardcoded credentials. Includes **option/argument injection into subprocess calls** — a user-controlled positional that starts with `-` or is `.`/`..` becomes a git/gh flag or pathspec (`--output=`, `-f`, `checkout .`); `execFile` does not stop it — validate the value against the subcommand grammar (a ref/name allowlist, reject a leading `-`); a `--` separator ends option parsing but does **not** neutralize a pathspec (`checkout -- .` still discards changes), so the value allowlist is the fix.
|
|
568
|
-
| `3a` | **Reuse & duplication.** Does the codebase already have this? Greps the shared/utility modules and adjacent files for the _behaviour_ (a literal, an error string, a regex — not a plausible function name), and **names the existing helper to call instead**; a duplication finding that names nothing is not a finding. Also owns **dead code the diff leaves behind**.
|
|
569
|
-
| `3b` | **Altitude & abstraction fit.** Is each change at the right depth — or a bandaid on shared infrastructure, a downstream compensation for an upstream bug, or a new abstraction serving a single call site? **Names the depth the change should live at**, and the blast radius on the other callers. Also flags the **enumeration trap** — a change that hand-rolls a surface whose entrance space is unbounded (untrusted input read a rendered format's way, a re-implemented grammar) instead of deferring to a real parser / authoritative output / a fail-closed decision is a class-closing finding, named once, not enumerated case-by-case.
|
|
570
|
-
| `3c` | **Consistency & clarity.** **Sibling consistency** — a guard/validation one member of a parallel family has but its twin lacks (asymmetric failure; if the missing guard is on untrusted input, a security bug, not a nit) — plus convention drift measured against a cited local example, misleading names and comments, and needless complexity in the added code.
|
|
571
|
-
| `4` | **Performance & efficiency.** N+1s, leaks, needless re-renders, bad data structures, bundle size. **Reproduces the PR's claimed numbers** rather than trusting them — confirms a cheap deterministic claim (bundle bytes, tree-shake) or flags an unreproducible/unsubstantiated benchmark as unverified.
|
|
572
|
-
| `5` | **Test coverage.** Specific untested paths in the diff, never "coverage is low"; a missing test is a Suggestion. **Mutation-tests the tests the diff adds/changes** — a test that stays green when the code under it is broken is vacuous — a Suggestion, Critical only when it asserts the opposite, was weakened in-diff, or lets a named incorrect behaviour ship (report the behaviour, not the gap).
|
|
573
|
-
| `6a` `6b` `6c` | **Undirected audit, three personas** — attacker, 3 AM oncall, six-months-later maintainer. The framings force diverse paths; the union of what they find is the point, so all three run.
|
|
574
|
-
| `
|
|
575
|
-
| `
|
|
576
|
-
| `
|
|
559
|
+
| Role | What it owns |
|
|
560
|
+
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
561
|
+
| `0` | **Issue fidelity & root-cause ownership** (PR reviews only). Does the change fix the thing it claims to fix — the _observed_ behaviour in the linked issue, not just the author's theory of it? Is the root cause the client's, or the upstream service's? A client-side workaround for malformed upstream data is a Critical unless a maintainer asked for it. An empty scope (feature PR, no linked issue) is a complete answer, with its evidence. |
|
|
562
|
+
| `1a` | **Line-by-line correctness.** Walks every hunk, reading the _enclosing function_ so the change is judged in its real context. Off-by-ones, inverted conditions, missing `await`, swallowed errors. The language-pitfall checklist and wrapper/proxy routing used to ride here as bullets; they are dedicated agents at high (1d/1e). |
|
|
563
|
+
| `1b` | **Removed-behavior audit.** Owns the `-` lines, which exist only in the diff — the post-change tree carries no trace of what was deleted. For each removal: what invariant did it enforce, and where is that re-established? Includes removed or renamed _exports_ (compared to their replacement as **behaviour, not names**), changed _literals_ a distant consumer matches on by shape (marker strings, keys, codes, regex text), and whether a rename/format/schema change handles the data that **already exists** (migration / split-brain). |
|
|
564
|
+
| `1c` | **Cross-file tracer** (needs a local tree). Owns the whole cross-file walk. _Consumer direction_: grep every caller of every changed export and check it against the new contract. _Producer direction_: for every field the diff **adds**, grep its **read sites** — a live path reading a field the diff never populates is Critical, and nothing in the build will tell you. |
|
|
565
|
+
| `1d` | **Language-pitfall scan** (high effort). Carries the classic-footgun checklist for the diff's language — JS/TS `==` coercion, falsy-value traps, loop-variable capture, floating promises; Python mutable defaults and late-binding closures; Go nil-map writes and range-variable capture; Java/Kotlin reference equality; any language's SQL concatenation, DST arithmetic, float equality — and pattern-matches every hunk against it. |
|
|
566
|
+
| `1e` | **Wrapper/proxy routing** (high effort; rostered only when the plan's `wrapperSignal` is true). For every type the diff adds or modifies that wraps another — a cache, proxy, decorator, adapter — every method must route through the _wrapped instance_ (never back through a registry/session/global, which re-enters the wrapper), and the wrapper must forward every method its callers actually use, faithfully. |
|
|
567
|
+
| `2` | **Security.** Injection, XSS, SSRF, path traversal, authn/authz bypass, secrets in logs, weak crypto, hardcoded credentials. Includes **option/argument injection into subprocess calls** — a user-controlled positional that starts with `-` or is `.`/`..` becomes a git/gh flag or pathspec (`--output=`, `-f`, `checkout .`); `execFile` does not stop it — validate the value against the subcommand grammar (a ref/name allowlist, reject a leading `-`); a `--` separator ends option parsing but does **not** neutralize a pathspec (`checkout -- .` still discards changes), so the value allowlist is the fix. |
|
|
568
|
+
| `3a` | **Reuse & duplication.** Does the codebase already have this? Greps the shared/utility modules and adjacent files for the _behaviour_ (a literal, an error string, a regex — not a plausible function name), and **names the existing helper to call instead**; a duplication finding that names nothing is not a finding. Also owns **dead code the diff leaves behind**. |
|
|
569
|
+
| `3b` | **Altitude & abstraction fit.** Is each change at the right depth — or a bandaid on shared infrastructure, a downstream compensation for an upstream bug, or a new abstraction serving a single call site? **Names the depth the change should live at**, and the blast radius on the other callers. Also flags the **enumeration trap** — a change that hand-rolls a surface whose entrance space is unbounded (untrusted input read a rendered format's way, a re-implemented grammar) instead of deferring to a real parser / authoritative output / a fail-closed decision is a class-closing finding, named once, not enumerated case-by-case. |
|
|
570
|
+
| `3c` | **Consistency & clarity.** **Sibling consistency** — a guard/validation one member of a parallel family has but its twin lacks (asymmetric failure; if the missing guard is on untrusted input, a security bug, not a nit) — plus convention drift measured against a cited local example, misleading names and comments, and needless complexity in the added code. |
|
|
571
|
+
| `4` | **Performance & efficiency.** N+1s, leaks, needless re-renders, bad data structures, bundle size. **Reproduces the PR's claimed numbers** rather than trusting them — confirms a cheap deterministic claim (bundle bytes, tree-shake) or flags an unreproducible/unsubstantiated benchmark as unverified. |
|
|
572
|
+
| `5` | **Test coverage.** Specific untested paths in the diff, never "coverage is low"; a missing test is a Suggestion. **Mutation-tests the tests the diff adds/changes** — a test that stays green when the code under it is broken is vacuous — a Suggestion, Critical only when it asserts the opposite, was weakened in-diff, or lets a named incorrect behaviour ship (report the behaviour, not the gap). |
|
|
573
|
+
| `6a` `6b` `6c` | **Undirected audit, three personas** — attacker, 3 AM oncall, six-months-later maintainer. The framings force diverse paths; the union of what they find is the point, so all three run. |
|
|
574
|
+
| `6d` | **Counter-frame audit** (whole-diff in both topologies; PR reviews at high or unrecorded effort — the roster gates it on the PR identity, like Agent 0, and on the personas' effort tier). The reviewer the author's narrative cannot steer: extracts the description's nominated "worth reviewing" topics as an EXCLUSION list and reviews what the description does not talk about; when the description narrates a motivating incident, replays it step by step against the merged world and files an unchanged outcome as a Critical with the replay as its witness. Measured motive: #9655's four review rounds produced 25 findings, all inside the author's four nominated decisions, while the blocking defect sat outside the frame (issue #9707). |
|
|
575
|
+
| `7` | **Build & test verification** (needs a local tree). Runs _one_ build and _one_ test command, and the **test-efficacy probe** — which reverts the diff's source, keeps its tests, and reports the ones that pass anyway, deletes individual added safety statements (mutants) to find the ones no test notices, and reverts individual **hunks** one at a time to find the changes no test turns on. Every one of those mutations happens in a disposable sibling worktree it discards afterwards, never in the shared review worktree the other agents are reading. Its evidence is the commands it ran. `Source: [build]` / `[test]`, never `[review]`. |
|
|
576
|
+
| `prose-exec` | **Prose-execution audit** (needs a local tree; joins the roster when the diff touches an instruction file — `isPromptPath` is the authority: skills, root guidance files, agent and slash-command definitions, `prompts/` files, the pipeline's `.qwen/review-rules.md`, prompt/brief-named sources — or when a repository context requires it back, or when the plan carries no file list, which fails safe and rosters it). Instruction prose is executed, not read: stands up the smallest honest scenario in its own temp directory, follows the changed instructions literally — no charity on ambiguity — and files the divergence between the executed outcome and what the prose promises, with the run's output as the witness. Measured motive: #9655's two prose defects each fall out of a single execution and fell out of none of twenty-five readings (issue #9707). |
|
|
577
|
+
| `test-matrix` | **Test coverage matrix** (Step 3B). Maps each behavioural change to the test that exercises it — the pairing a territory agent cannot see, because it holds either the implementation or the test, rarely both. |
|
|
578
|
+
| `invariant-a` `invariant-b` `invariant-c` | **Whole-file invariants** on a `heavy` file, one checklist slice each: (a) mutable fields, timers, collections; (b) retry counters, ignored return values, error taxonomies; (c) config fields, early returns. |
|
|
577
579
|
|
|
578
580
|
**Why code quality is three agents.** It was one, holding six unrelated checks — reuse, sibling symmetry, altitude, abstraction fit, conventions, dead code — which is the shape this skill already refuses two rows down. The invariant agents were split three ways on measured evidence (measured; DESIGN.md — The one-agent invariant checklist (PR #6457)), because a long checklist is not a task an agent does six times — it is a task it does once, well, and then stops. Nothing in that measurement was specific to invariants, and the quality checklist was the other place the same shape survived. The seam is where the questions genuinely differ: _does this already exist_ (3a), _is it at the right depth_ (3b), _does it match what surrounds it_ (3c). All three run at medium as well as high — dropping two slices would not save a lens, it would restore the failure the split fixed.
|
|
579
581
|
|
|
@@ -624,7 +626,9 @@ The angles below are the ones that pay at hunk-only depth — every one of them
|
|
|
624
626
|
|
|
625
627
|
**Do not read full source files, do not grep the codebase, do not run anything.** That restriction is what makes low cheap, and it is also why the angles above are the ones they are. Project rules are not loaded at low (Step 2 is skipped).
|
|
626
628
|
|
|
627
|
-
**Say which angles you walked.** End the pass with one line per angle walked, naming what it examined — `B — 3 deleted hunks in submit.ts and parse-args.ts; both guards re-established at the new call site` — the same evidence-bearing return every subagent owes in 3A. This is the only check low has: nothing here reads a transcript, so a pass that skipped four angles and reported two findings is indistinguishable from a clean diff unless it says so.
|
|
629
|
+
**Say which angles you walked.** End the pass with one line per angle walked, naming what it examined — `B — 3 deleted hunks in submit.ts and parse-args.ts; both guards re-established at the new call site` — the same evidence-bearing return every subagent owes in 3A. This is the only check low has: nothing here reads a transcript, so a pass that skipped four angles and reported two findings is indistinguishable from a clean diff unless it says so.
|
|
630
|
+
|
|
631
|
+
If the union of the passes you ran yields fewer than `plan.budget.candidateFloor` candidates (or `min(plan.files.length, 4)` when that field is absent), treat that as a signal you stopped early and run **one** deterministic re-pass. First mark every chunk whose `maxLineChars` exceeds the read cap as uncoverable. For target (a), use `plan.chunks[].files` to exclude files that appear in any uncoverable chunk and files that appear in no chunk; among the remaining files, prefer `kind: source`, falling back to every remaining kind only when there is no coverable source file, then choose the largest `changedLines` value (break a tie by lexical path) and re-read every diff hunk for that file. For target (b), re-read every deleted or replaced block in the coverable chunks. If no file is eligible for (a), still run (b) and disclose that there was no coverable target file. Stay inside the captured diff; this re-pass does not relax low effort's no-full-source rule. For a file-path review with no plan, use a floor of 1 and re-read the file; if paging cannot cover a line, mark it uncoverable instead of claiming it was read. **Do not invent findings to reach the floor**; it is a trigger for another look, not a quota. Keep any candidates the re-pass finds. Whenever the floor triggers, emit one receipt whether or not the re-pass finds anything: `Recall-floor re-pass: <target path or no coverable target>; <N> new candidates; uncoverable: <chunk ids and paths or none>`.
|
|
628
632
|
|
|
629
633
|
Low uses the standard finding format, including **Failure scenario**, and the reporting gate applies unchanged: a Suggestion with no concrete scenario or cost is dropped; a suspected Critical you cannot pin down is kept with `Confidence: low`. The recall rule the fan-out briefs carry applies to you here too — you are the finder, so file every candidate whose scenario you can name rather than withholding the half-believed ones.
|
|
630
634
|
|
|
@@ -701,7 +705,7 @@ Write this shard's findings to a file — each with its file, line, issue and fa
|
|
|
701
705
|
|
|
702
706
|
The brief holds the method the orchestrator used to spell out here and that a paraphrase kept dropping: trace the failure scenario through the real code rather than voting on the finding's prose; engage the diff's own documented intent before calling a documented change a regression (the rule a run skipped when it auto-posted a false "leaks tokens" Critical); the one-way, quote-the-contradiction bar on **rejecting a Critical**; the **falsify-not-verify asymmetry** governing every rejection — a rejection claims direct counter-evidence **constructible from the code** (the misread line quoted, a provable impossibility shown, the in-diff guard that covers the trigger cited, or pure style with no observable effect — or otherwise a matched Exclusion Criterion), and none of "I could not verify it", "its evidence is somewhere I did not look", or "it is too speculative" is one (the verifier is told to go read the claimed source first, and to floor at a low-confidence downgrade when it is genuinely unreachable). The third masquerade has a named list beside it: a finding whose failure scenario names a state the code does not exclude is **PLAUSIBLE by default** — a concurrency race, nil/undefined on a rare-but-reachable path, a falsy zero or empty collection treated as missing, an off-by-one on a boundary the code does not exclude, a retry storm or partial failure, a regex or allowlist that lost an anchor — and "I cannot construct that state from a read-through" refutes the trace, not the claim. A rejection that constructs none of the four grounds downgrades to `confirmed (low confidence)` rather than dropping, so it still reaches a human. The brief holds one more piece of method: when a finding's claim is **runnable** and the repo has a fast unit harness (`vitest`/`jest`/`pytest`), there is the option to **write and run a probe** — let the observed behaviour, not a re-reading, settle the verdict. That last one earns its place: the strongest model has read a live double-execute as correct until a probe ran the path and settled it (measured; DESIGN.md — The double-execute the probe caught). The brief makes the probe evidence rather than theatre with two hard rules — a mandatory self-check that the probe **flips** between buggy and correct, and (in worktree mode) running every write it makes in a tree of its own; a local or file-path review has no worktree and no scratch tree, so there the older rule is the whole rule and the brief says so: restore every line, delete every file, immediately. A finding a probe confirmed carries `Source: [probe]`, which `compose-review` treats as deterministic (a run produced it), exactly like `[build]`/`[test]`. Read the brief to know what a verdict means; do not re-derive it here.
|
|
703
707
|
|
|
704
|
-
**The brief also carries the scratch tree, which is what makes probing safe at all.** A probe writes: the probe file itself, and the one-line fix the flip-check applies. Until #9207 those writes landed in the shared review worktree — the tree `working_dir` pins every OTHER agent to as well — and the pipelined loop puts round _k_'s verifiers in the same response as round _k+1_'s auditors, so the writes are live exactly while the auditors read. Live, an auditor read a probe's mutant plus a leftover probe test, came within a step of filing a Critical against code no commit contains, and recovered only by improvising `git show HEAD:` — a fallback no brief mentioned (measured; DESIGN.md — The probe residue an auditor almost filed). "Leave the tree as you found it" could never close that window, because the exposure is _during_ the probe. So `qwen review scratch-tree --worktree <the worktree> --label <this shard's record key>` stands up a throwaway sibling at the commit under review — the worktree's `node_modules` linked in so a unit harness starts without an install — and the brief sends every probe, mutant and candidate fix there. Three properties make it more than a directory: every call hands back a PRISTINE tree — tracked files restored, untracked AND ignored state deleted, the dependency farm re-linked — because a previous finding's mutant surviving into the next probe would be a wrong verdict with a deterministic source tag on it; the label is per shard, because the shards of one round run concurrently and a shared scratch tree is the same race one level down; and the report carries `sharedTreeResidue`, the paths the REVIEW worktree holds that its commit does not, so a tree that got dirty anyway is caught by the pipeline instead of by a confused auditor. `cleanup` sweeps the family at Step 9. This is the isolation Agent 7's efficacy probe has had since #6832, extended to the last step that writes **in worktree mode** — a local-diff or file-path review has no worktree to sit a sibling beside (and its HEAD is not what is under review), so its verifier still writes in the tree it reviews, under the brief's older restore-immediately rule. That residue is the remaining exposure, and it is smaller only because the tree in question is the user's own rather than a shared one.
|
|
708
|
+
**The brief also carries the scratch tree, which is what makes probing safe at all.** A probe writes: the probe file itself, and the one-line fix the flip-check applies. Until #9207 those writes landed in the shared review worktree — the tree `working_dir` pins every OTHER agent to as well — and the pipelined loop puts round _k_'s verifiers in the same response as round _k+1_'s auditors, so the writes are live exactly while the auditors read. Live, an auditor read a probe's mutant plus a leftover probe test, came within a step of filing a Critical against code no commit contains, and recovered only by improvising `git show HEAD:` — a fallback no brief mentioned (measured; DESIGN.md — The probe residue an auditor almost filed). "Leave the tree as you found it" could never close that window, because the exposure is _during_ the probe. So `qwen review scratch-tree --worktree <the worktree> --label <this shard's record key>` stands up a throwaway sibling at the commit under review — the worktree's `node_modules` linked in so a unit harness starts without an install — and the brief sends every probe, mutant and candidate fix there. Three properties make it more than a directory: every call hands back a PRISTINE tree — tracked files restored, untracked AND ignored state deleted, the dependency farm re-linked — because a previous finding's mutant surviving into the next probe would be a wrong verdict with a deterministic source tag on it; the label is per shard, because the shards of one round run concurrently and a shared scratch tree is the same race one level down; and the report carries `sharedTreeResidue`, the paths the REVIEW worktree holds that its commit does not, so a tree that got dirty anyway is caught by the pipeline instead of by a confused auditor. `cleanup` sweeps the family at Step 9. The prose-execution audit gets the same command with `--standalone`: its tree is a repository of its own — a fresh `git init` whose object store is the user's through an alternates pointer, checked out at the reviewed head — because that agent executes instructions the PR author wrote: a `git config`, hook or ref write a recipe step makes lands in that tree and dies with it (the STATE does — a command-valued key written there, a `core.hooksPath` or a `filter.*`, runs at the tree's next git step as the reviewer, which the brief's reach rule judges: `git config --local --list --includes` before any git command there, and the step that writes such a key or trips it is judged by what it reaches), and the command runs nothing that could execute the user's repo-local config in their repository to build it (no clone, no `worktree add`, no checkout, no residue `status` — its report says the shared tree went unmeasured, never that it is clean). That is isolation of what the agent writes INSIDE the copy, not a sandbox against the agent: a `git push <path>` or a global-config write is a step the brief's never-execute classes quote instead of running. (No screen over a shared `.git` ever closed — the surface is git-defined, its inputs are same-user-writable, and it refused the config state CI checkouts write — so the untrusted-input shape shares nothing but the object store instead.) This is the isolation Agent 7's efficacy probe has had since #6832, extended to the last step that writes **in worktree mode** — a local-diff or file-path review has no worktree to sit a sibling beside (and its HEAD is not what is under review), so its verifier still writes in the tree it reviews, under the brief's older restore-immediately rule. That residue is the remaining exposure, and it is smaller only because the tree in question is the user's own rather than a shared one.
|
|
705
709
|
|
|
706
710
|
The brief also carries the **render-adjudication capability**: when the user has set `QWEN_REVIEW_SCRATCH_REPO` (an `owner/repo` designated for disposable test posts), a verifier facing a claim about GitHub's own rendering — mention defusal, tag stripping, fold behaviour — may post the minimal payload to that repo and read back GitHub's rendered HTML (`Accept: application/vnd.github.html+json`), because a local markdown library is only a model of GitHub and a claim about the authority cannot be settled against a model of it. Without the setting, such claims cap at low confidence / `cannot tell` rather than being "confirmed" off an approximation. This is the one narrowly-scoped exception to the no-writes rule, and Step 7 names it.
|
|
707
711
|
|
|
@@ -1086,7 +1090,7 @@ The three words are three different claims and are not interchangeable. `fixed`
|
|
|
1086
1090
|
|
|
1087
1091
|
Report the outcome counts in the terminal summary, and list each `skipped` finding with its reason. **Do not re-run Steps 1–6** to check your own work: a re-review of a tree you just edited is a new review of different code, and its verdict is not this review's.
|
|
1088
1092
|
|
|
1089
|
-
Append a follow-up tip after the verdict (high and medium effort — only a **low** quick pass and a `--topology minimal` pass emit no verdict and follow their own tip rules instead (Step 3C / Step 3M); their "post comments" follow-ups are declined per those steps). **Tip lines are user-facing terminal prose — translate them into your output language** (critical rule 2). The English templates below define the _content_ and the _command keywords_ (which stay verbatim — `post comments`, `fix these issues`, `commit` are trigger phrases the user types back); translate the surrounding sentence. With a Chinese output language, "Tip: type `post comments` to publish findings as PR inline comments." becomes "提示:输入 `post comments` 将发现作为 PR 行内评论发布。" At **medium**, also add: "Tip: run `/review <target> --effort high` for the full verified review (adds the reverse audit, the language-pitfall and wrapper/proxy specialists, the adversarial personas, and Agent 8 — and can certify Approve)." Choose the rest based on remaining state:
|
|
1093
|
+
Append a follow-up tip after the verdict (high and medium effort — only a **low** quick pass and a `--topology minimal` pass emit no verdict and follow their own tip rules instead (Step 3C / Step 3M); their "post comments" follow-ups are declined per those steps). **Tip lines are user-facing terminal prose — translate them into your output language** (critical rule 2). The English templates below define the _content_ and the _command keywords_ (which stay verbatim — `post comments`, `fix these issues`, `commit` are trigger phrases the user types back); translate the surrounding sentence. With a Chinese output language, "Tip: type `post comments` to publish findings as PR inline comments." becomes "提示:输入 `post comments` 将发现作为 PR 行内评论发布。" At **medium**, also add: "Tip: run `/review <target> --effort high` for the full verified review (adds the reverse audit, the language-pitfall and wrapper/proxy specialists, the adversarial personas, the counter-frame audit (PR reviews), and Agent 8 — and can certify Approve)." Choose the rest based on remaining state:
|
|
1090
1094
|
|
|
1091
1095
|
- **Local review with unfixed findings** (Step 6B did not run — `--fix` was not passed): "Tip: type `fix these issues` to apply fixes interactively, or re-run with `/review --fix` to have the review apply and account for them itself."
|
|
1092
1096
|
- **Local review where Step 6B ran**: offer no fix tip — the findings already carry outcomes. If any came back `skipped`, say so with their reasons instead.
|
|
@@ -13,6 +13,6 @@ For an **Aone Code** target, run `/review` **from inside a clone of that repo**
|
|
|
13
13
|
|
|
14
14
|
`pr-context` is Aone-backed — it runs like GitHub (same failure handling: warn, continue, **context-unavailable** state on failure) and reads the MR's metadata, discussion threads, and posted qwen summaries (the machine ledger recovers from them the same way GitHub's does from review bodies). Aone reports no diff stats, so the context file's Diff line degrades — that is expected, not an error. A few flows still must be skipped rather than allowed to hit github.com's same-named repo:
|
|
15
15
|
|
|
16
|
-
- Agent 0 (issue fidelity)
|
|
16
|
+
- Agent 0 (issue fidelity) — and, at high or unrecorded effort, the counter-frame audit 6d — run whenever the plan carries the MR identity, as on GitHub: a failed `pr-context` puts the run in the context-unavailable state and both still launch, for their documented unperformable returns (SKILL.md, Step 1). (`issue-context` is a1-backed too, and the fetch Agent 0's brief welds runs it for the MR's workitem evidence exactly as on GitHub.)
|
|
17
17
|
- Step 9's bypass audit is platform-aware: on an Aone target it lists the MR's comments through the `a1` CLI and flags any comment the authenticated account posted — or edited — inside the window that `submit`'s receipt does not vouch for. It never queries GitHub for an Aone report.
|
|
18
18
|
- `--comment` posts through `qwen review submit` exactly as on GitHub — it routes the write at the `a1` CLI itself (one comment per inline finding, then the summary comment). Aone has **no native request-changes state**: on that verdict the summary comment carries a blocking header, and any inline Criticals block the merge while their discussions stay unresolved — but they carry NO AI-comment flag (`a1` cannot set one), so the platform's dedicated `ai_comment` merge gate does not track them and the discussion gate is the only mechanical block. Relay the `Note:` line `submit` prints about this (it names whether inline Criticals actually posted — and, when they did, which gate they join). The native `a1 repo mr approve` fires for an APPROVE verdict exactly when the run read the MR's context (the same gate as GitHub; a context-unavailable run stays capped at COMMENT). Five failure/refusal shapes are Aone-specific: a **head-drift** refusal (the MR was amended between review and post — re-review the new head, do not re-submit the stale payload, but ONLY while the per-review head-movement restart bound is unspent; once spent, Aone has no submit-at-reviewed-SHA fallback (a1 comments carry no commit anchor), so report that the review cannot be posted against the moved head, leave the findings in the terminal output and the saved report, and leave further re-review/posting to the user); a **mid-batch failure** (stdout carries `"partial": true` with the landed counts/ids and an `ambiguous` flag — part of the review IS on the MR; never re-run `submit`; report what landed and what remains, and leave posting the remainder to the user; when `ambiguous` is true, the FAILED write itself may have reached the MR — a zero count is not proof nothing landed, so tell the user to inspect the MR before hand-posting anything); an **oversized-comment** refusal (a single comment or the summary exceeds a1's 131072-byte single-argument limit — the whole batch refuses before anything lands, there is nothing to re-run, and the user can post by hand); an **ordinary pre-write error** (auth expiry, a network blip — nothing landed, it surfaces as a normal command failure, and a re-run is safe); and the **anchor check** — Aone Code performs NO server-side anchor validation and cannot anchor the old side at all (a `--line` number that names a removed line posts silently on the same-numbered NEW-side line), so `submit` itself validates every inline anchor against the review's captured diff before anything posts: when that diff is not on disk it refuses the whole post (re-run the review so the diff is captured — nothing was written; a `--dry-run` preview is the exception — it writes nothing, so it skips the gate, discloses that anchors went unchecked, and reports `wouldPost: false` with `reason: 'aone-diff-missing'`), and any comment whose anchor it cannot vouch for degrades exactly like GitHub's 422 recovery — a Critical is relocated into the summary body, a Suggestion is discarded and counted — with each one named in the terminal (`Aone anchor check: …`); relay the disclosure. This is also the anchoring PROMISE for an Aone target: new-side only, and a finding on a removed line reaches the MR through the summary body or not at all — never on a wrong line. `submit` also discloses a head that moved DURING posting (`WARNING: the MR head MOVED during posting`) — relay it, and when the post-batch head re-read itself fails, `could not verify` is not `verified stable`: `submit` prints `WARNING: could not re-verify the MR head after posting` (a mid-batch failure prints the same warning naming the failed post) — relay that too. On a second-or-later Aone round, `presubmit`'s overlap dedup applies exactly as on GitHub — a finding already on the MR at the same `(path, line)` is dropped and logged, and only genuinely new findings post; self-PR detection works too (the MR author is matched against `a1 auth whoami`). Two Aone shape notes for that dedup: a1 comments carry no commit anchor, so every `comment-status` thread's code facts (`changedSinceComment`, `touchedBy`) read `unknown`, and a thread the platform marks `outdated` (its line no longer maps after an amend) buckets as stale — so a new finding at a rewritten line still posts — while a resolved (`closed`) thread buckets as `resolved`, exactly like a replied-to thread on GitHub. `publish-assets` stays skipped: the Contents-API write is not Aone-backed.
|
|
@@ -152,7 +152,7 @@ Read `.qwen/tmp/qwen-review-{target}-presubmit.json`. Schema:
|
|
|
152
152
|
|
|
153
153
|
- `blockOnExistingComments=true` → **an overlap is a duplicate; the disposal is deterministic — do not ask the user.** Drop each finding whose `(path, line)` appears in `existingComments.overlap` from your `comments` array — **except a finding whose `id` appears in `matchedIds` of an `existingComments.repost` entry at the same location**: that is a Step 6 ledger re-post, and re-posting under the original id is exactly how the id survives into the next round's marker — GitHub stacks it in the original thread, which is where it belongs. The inline counts follow automatically, because `submit` counts the comments you actually attach, so a dropped Critical is simply no longer there to count (and a dropped Critical that was already on the PR does not belong in `state.bodyCriticals` either). List each dropped finding in the terminal summary as "already reported at <path>:<line> — comment <id> (by <user>): <excerpt>", taking `<id>`, `<user>` (omit the `(by <user>)` slot when the entry carries no `user`), and the 80-char `<excerpt>` from the overlapping comment (`existingComments.overlap` entries carry all three), and submit the remainder without pausing. Naming the author is what makes an authorship-refused re-post exemption self-explanatory: the drop line then shows a DIFFERENT author next to the matching id. Name the comment on EVERY drop — that is what makes a same-line false positive visible to the operator instead of a bare location. This decision point has been improvised as an interactive question, which stalls a headless run forever (measured; DESIGN.md — The interactive overlap question); the Exclusion Criteria already forbid re-reporting discussed issues, so there is nothing to ask. (If dropping overlaps leaves zero findings, that is still not a question: submit with an empty `comments` array like any other run — `submit` composes the body from `state`, and a run with nothing to add posts whatever that computes. A recap like "all already reported, N resolved by `<sha>`, two still standing" goes in the **terminal summary**, not the PR: `compose-review` has no free-text body field to carry it (see Step 7 — you do not author PR-facing prose), and it is never a `gh pr comment` — a hand-posted issue comment bypasses the authorisation gate, the downgrade semantics, and the `posted` contract all at once.)
|
|
154
154
|
- `downgradeApprove` / `downgradeRequestChanges` / `downgradeReasons` → **do not apply these by hand.** Copy them into the `presubmit` field of the `compose-review` input (listed with the state fields in Step 6's Verdict section); the subcommand owns the semantics its tests pin — a downgrade fires only when the verdict it names is the one on the table (a Suggestion-only review is already Comment, so nothing is downgraded and no "Downgraded" sentence is emitted), the downgrade sentence carries the reasons, and a downgraded Request changes keeps its body Criticals after the sentence so the self-PR downgrade never erases the only copy of a blocker.
|
|
155
|
-
- `headDrift.drifted=true` → **commits nobody reviewed are on the PR; the verdict can no longer certify the pull request as it stands.** The Approve cap has already fired through the downgrade machinery (the reason names both SHAs — it rides into the body with the other reasons; never hand-apply). What happens to the _submission_ is decided by **`headDrift.anchorsAtRisk`, which presubmit computes — do not re-derive it by hand**: pass `--new-findings` so it has your anchors, and it rules fail-safe on every hole a hand intersection falls into (a truncated `filesTouched` list (measured; DESIGN.md — The 283-file drift cap), the compare API's own 300-file ceiling, a `diverged` force-push, an unavailable compare, or a missing findings list). **`--new-findings` must carry EVERY finding's file, not only the inline-anchored ones** — a body-only Critical (one that could not be mapped to a diff line) still names a file, and if that file is omitted a drift touching it reads as `anchorsAtRisk=false`; include one `{path, line}` per body Critical (any placeholder `line`, e.g. `1`, and NO `id` — the drift intersection keys on `path` only, but the carried-id re-post exemption intersects on `(path, line)` plus id, so a placeholder line carrying an id could alias an inline finding's location and corrupt its exemption; a body-only Critical is never posted inline and can never be a re-post target). **`anchorsAtRisk=true`**: the anchors themselves are at risk and the findings may already be fixed — apply the 422-recovery rule _proactively_: abandon this submission, say so, and restart at the new SHA from Step 1's `fetch-pr`. **`anchorsAtRisk=false`**: submit as planned — the review is of `fetchedSha` (`submit` posts that very SHA as `commit_id`), the body's downgrade sentence says so, and if GitHub still answers 422 the recovery path below takes over. Name the drift in the terminal summary either way.
|
|
155
|
+
- `headDrift.drifted=true` → **commits nobody reviewed are on the PR; the verdict can no longer certify the pull request as it stands.** The Approve cap has already fired through the downgrade machinery (the reason names both SHAs — it rides into the body with the other reasons; never hand-apply). What happens to the _submission_ is decided by **`headDrift.anchorsAtRisk`, which presubmit computes — do not re-derive it by hand**: pass `--new-findings` so it has your anchors, and it rules fail-safe on every hole a hand intersection falls into (a truncated `filesTouched` list (measured; DESIGN.md — The 283-file drift cap), the compare API's own 300-file ceiling, a `diverged` force-push, an unavailable compare, or a missing findings list). **`--new-findings` must carry EVERY finding's file, not only the inline-anchored ones** — a body-only Critical (one that could not be mapped to a diff line) still names a file, and if that file is omitted a drift touching it reads as `anchorsAtRisk=false`; include one `{path, line}` per body Critical (any placeholder `line`, e.g. `1`, and NO `id` — the drift intersection keys on `path` only, but the carried-id re-post exemption intersects on `(path, line)` plus id, so a placeholder line carrying an id could alias an inline finding's location and corrupt its exemption; a body-only Critical is never posted inline and can never be a re-post target). **`anchorsAtRisk=true`**: the anchors themselves are at risk and the findings may already be fixed — apply the 422-recovery rule _proactively_: abandon this submission, say so, and restart at the new SHA from Step 1's `fetch-pr`. **One exception — the CI salvage contract:** when the environment carries `QWEN_REVIEW_SALVAGE_POST=1` **and** the file named by `QWEN_CI_REVIEW_SALVAGE_OK_FILE` exists with content equal to `headDrift.reviewedSha`, the workflow's supersede watcher has already ruled this run salvage-eligible and a queued replacement run owns the new head — do **not** restart: submit as planned exactly as in the `anchorsAtRisk=false` branch (the review is of `fetchedSha`, the downgrade sentence names the drift, and the workflow's gh guard admits the post against that pinned head), and this consumes no restart. Either half missing — an explicit run exports no signal, and a marker alone is forgeable — and the rule above stands. **`anchorsAtRisk=false`**: submit as planned — the review is of `fetchedSha` (`submit` posts that very SHA as `commit_id`), the body's downgrade sentence says so, and if GitHub still answers 422 the recovery path below takes over. Name the drift in the terminal summary either way.
|
|
156
156
|
|
|
157
157
|
> **The restart bound is per-review and covers BOTH restart paths — this proactive drift restart AND the reactive 422 recovery below.** Track it as one fact: a review restarts **at most once** for head movement, whichever path triggers it. If a run that already restarted once reaches a drift restart _or_ a 422 again, do NOT restart a second time — submit at that run's reviewed SHA with the drift named (the Approve cap holds either way). A live PR that keeps moving must not be able to starve the review in an unbounded restart loop; one clean re-read is the review, a second is the PR outrunning it. One slice of this fact survives a resume: a `fetch-pr --resume` refused for `head-moved` records the restart beside the prompt records, and a later continuation reads it back as `restartsSpent` in the `resumed: true` line (Step 1) — arriving with `restartsSpent >= 1` means the bound is already spent. On a run that itself resumed, THIS restart's re-entry is such a refusal — Step 1's resume branch appends `--resume` to every Step 1 `fetch-pr`, so the re-entry sees the moved head, records the restart, and falls through to the fresh fetch the restart wants anyway. Only a never-resumed run's re-entry records nothing (a plain fresh `fetch-pr` rewrites the plan, which re-fences the marker) — within such a run the bound stays tracked here, in this transcript, exactly as before. Be aware of the one seam that leaves: a restart spent that way is invisible to a LATER attempt that resumes, which arrives with `restartsSpent: 0`. A fresh resuming process cannot know the earlier attempt restarted, so do not pretend it can — the on-disk bound is per-attempt, the per-REVIEW invariant is carried by the workflow's own MAX_ATTEMPTS ceiling, and the honest reading of `restartsSpent: 0` on a continuation is "no RECORDED restart", not "no restart".
|
|
158
158
|
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: workflow-creator
|
|
3
|
+
description: Create or update reusable Dynamic Workflow JavaScript files under .qwen/workflows. Use when the user asks to create, save, edit, or reuse a Dynamic Workflow, including requests started from the Web Shell Workflows page.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Workflow Creator
|
|
7
|
+
|
|
8
|
+
Create and maintain saved Dynamic Workflows for the current workspace.
|
|
9
|
+
|
|
10
|
+
## Boundary
|
|
11
|
+
|
|
12
|
+
- This skill manages `.qwen/workflows/<name>.js` files used by the `workflow` tool and exposed as `/<name>` slash commands.
|
|
13
|
+
- Do not create or edit `qwen-workflow-design/*.yaml`; those Task Flow definitions are a different feature.
|
|
14
|
+
- Use project scope by default. Write to `~/.qwen/workflows` only when the user explicitly asks for a workflow shared across projects.
|
|
15
|
+
|
|
16
|
+
## Workflow
|
|
17
|
+
|
|
18
|
+
1. Inspect the current task and any existing workflow with the requested name. Ask a question only when the goal, ordering, or write scope is materially ambiguous.
|
|
19
|
+
2. Choose a lower-case name containing only letters, digits, and hyphens. It must start with a letter and be at most 41 characters.
|
|
20
|
+
3. Create the smallest script that captures the requested phases, dependencies, and final result. Do not add speculative branches, retries, or agents.
|
|
21
|
+
4. Read the saved file back and verify its name, metadata, phase order, dependency flow, and final return value. Do not execute it unless the user also asks to run it.
|
|
22
|
+
5. Report the saved path and slash command. In Web Shell, tell the user to return to Workflows and refresh the Saved tab if it is already open.
|
|
23
|
+
|
|
24
|
+
## Script contract
|
|
25
|
+
|
|
26
|
+
- Start with a literal metadata declaration:
|
|
27
|
+
|
|
28
|
+
```js
|
|
29
|
+
export const meta = {
|
|
30
|
+
name: 'Release readiness',
|
|
31
|
+
description: 'Inspect, validate, and summarize a release candidate',
|
|
32
|
+
};
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
- Use the sandbox globals documented by the `workflow` tool: `phase(title)`, `log(message)`, `agent(prompt, options?)`, `parallel(thunks)`, `pipeline(items, ...stages)`, `workflow(nameOrRef, args?)`, `args`, and `budget`.
|
|
36
|
+
- Scripts cannot import modules or access the filesystem, shell, environment, or network directly. Put required reads and actions in explicit agent prompts.
|
|
37
|
+
- Give every agent a complete, scoped prompt and a concise `label`. State whether it may edit files.
|
|
38
|
+
- Express real concurrency as `parallel([() => agent(...), () => agent(...)])`. Do not pass already-started promises to `parallel`.
|
|
39
|
+
- Keep dependent work sequential and pass prior results explicitly.
|
|
40
|
+
- Put variable user input in `args` instead of hard-coding one-off values.
|
|
41
|
+
- End every successful path with an explicit `return` of the final result. A trailing expression is not a return value.
|
|
42
|
+
- Do not use `node --check` for validation: valid workflow scripts may contain top-level `await` and `return` because the runtime wraps them in an async function.
|
|
43
|
+
|
|
44
|
+
## Updates
|
|
45
|
+
|
|
46
|
+
- Preserve unrelated behavior and metadata when editing an existing workflow.
|
|
47
|
+
- Do not overwrite an existing workflow with a different design unless the user requested that update.
|
|
48
|
+
- Do not delete or rename a workflow unless the user explicitly asks.
|