mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-08-05 23:00:07 +00:00
* feat(ci): add repo-hygiene skill and weekly patrol workflow Add .qwen/skills/repo-hygiene (SKILL.md + scripts/run-agent.mjs) and the corresponding GitHub Actions workflow that runs a weekly scan-and-fix patrol every Monday 03:00 UTC. The skill defines a single scan-and-fix mode that scans the repo for small, certain docs/test/code hygiene issues (broken Markdown emphasis, test coverage truthfulness, contract mismatches, real boundary conditions), batches up to 8 fixes as individual Conventional Commits on ONE branch, and writes findings.json + bilingual report-only.md + PR body. High-risk paths (packages/core/src/**, auth/providers/models/config/tools/services) are report-only — they go to the PR comment, never the diff. The workflow implements the trust split: agent never holds GitHub credentials; only the workflow publishes. Includes dedup (skip when a hygiene PR is already open), PAT identity verification, an independent verification gate (build/typecheck/lint + per-package vitest --changed), and a structural gate (commit cap, total diff cap, report-only path assertion). Closes #7383. * docs(repo-hygiene): expand judgment scans to six parallel search angles Port the richer search-angle taxonomy from the operator's interactive loop-hygiene prompt into the SKILL.md. Section B (judgment scans) now enumerates six explicit angles — test-coverage truthfulness, implementation/contract mismatch, resource lifecycle, real boundary conditions, user-visible configuration/API, and docs-as-secondary-scan — each with a grep/code-reference evidence requirement. The previous three-bullet version collapsed resource lifecycle and user-visible config/API into adjacent items, which meant the agent under-scanned AbortController/finally/iterator-return/stream-cleanup gaps and config-vs-schema disagreements in practice. Also makes the subagent workflow explicit: subagents report candidates only and never touch the working tree; the main agent deduplicates and decides. This matches the operator prompt's 'retrieval subagent only reports, never modifies' constraint. * refactor(repo-hygiene): drop deterministic-docs section, fold its principles into the scan loop Section A (Deterministic docs patterns) was too narrow: it gave two specific rg commands that dated quickly and duplicated the docs-as-secondary-scan rule already present in the judgment-scan taxonomy. Remove the section and promote Section B to the only scan-targets list. Two of Section A's cross-cutting principles are preserved by folding them into the scan loop's opening paragraph and the Docs bullet: - 'a pattern hit is a lead, not a finding' — now applies to rg, grep, and any other scanner - 'broken-but-rendering-fine emphasis stays untouched' — now part of the Docs bullet's exclusion list * refactor(repo-hygiene): partition the scan into nine parallel subagents The previous Scan Targets section dispatched subagents by search angle (six parallel scans of the whole monorepo). Each subagent ended up with a shallow read of every file it touched — it couldn't hold a module's contract graph in context, so findings tended to be one-line-deep (docs-vs-code, rendering bugs, dead-code hints). Switch to partition-first dispatch: one subagent per of nine module boundaries (cli/config, cli/runtime, cli/ui, core, extensions, sdk-typescript, sdk-python-java, ui-apps, docs). Each subagent owns its partition, finds the package's own entry points/schemas/registries, then applies the six search angles inside that scope. The main agent deduplicates across partitions afterward. A subagent must stay inside its partition; cross-partition findings are marked crossPartition:true for the main agent to merge or drop. Reading lists are intentionally not prescribed — the subagent picks the partition's own sources of truth. * refactor(repo-hygiene): allow cross-partition tracing, drop anti-padding bullets Two simplifications: 1. Replace 'subagent must stay inside its partition; crossPartition:true' with 'partition is a starting boundary, not a fence'. A subagent may now follow a call chain, import graph, or contract reference into another partition to build evidence. When a finding's evidence lands in a report-only path (core/*, auth/*, providers, models, config, tools, services, cross-package contracts), it goes to reportOnly — never into fixes. This replaces the previous crossPartition handoff machinery with one uniform rule that already exists in Scope Limits. 2. Drop two anti-padding bullets from Scope Limits ('do not batch trivial fixes to reach quota', 'do not manufacture findings to fill the run'). The Shared Rules' 'no speculative edits / keep changes minimal and scoped' already covers the same behavior; restating it here was noise. * docs(repo-hygiene): fix stale 'scans A and B' reference in scan-and-fix mode The A/B section split was collapsed into a single Scan Targets section two commits ago, but step 1 of Mode: scan-and-fix still said 'Run scans A and B'. Reword to describe the actual dispatch: nine partition subagents, six angles inside each, collect and deduplicate across partitions. * refactor(repo-hygiene): switch report-only rule from path to impact scope Drop the path-based report-only whitelist (packages/core/src/**, */src/auth/**, providers/models/config/tools/services/**, cross-package contracts). The report-only trigger is now impact scope: a finding whose minimal fix touches more than three files or more than one hundred lines of production code is report-only. Rationale: the path list was a proxy for 'high-impact area' that over-blocked trivial, certain fixes inside those paths and under-blocked sprawling fixes outside them. The file/line threshold measures impact directly. Scope Limits already caps each fix at 20 lines of production diff, so anything past 100 lines is an order of magnitude beyond that — past the four-file mark is past the single-root-cause test. * docs(repo-hygiene): expand each partition with package layout and correctness criteria The previous Nine-partitions section was a one-line scope pointer per partition. Each partition is now a mini architecture block naming the package path, what the package does, its key subdirectories, and what 'correct' looks like inside the partition. Directory names verified against the current tree (cli/src/{commands,serve,acp-integration,services,remoteInput,dualOutput,startup,i18n,utils,core,export}, cli/src/ui/{agent-view,arena,extensions,mcp,hooks,subagents,background-view,shared,messages,contexts,themes,state,layouts,voice,selection,editors,daemon,models,noninteractive}, core/src/{agents,models,providers,tools,services,prompts,utils,hooks,memory,skills,subagents,permissions,confirmation-bus,mcp,lsp,ide,goals,resources,followup,extension,config,telemetry,output,qwen}, desktop/apps/{electron,viewer}, web-shell/client). * refactor(ci): replace path-based gate with per-commit impact-scope check The workflow gate previously rejected any branch touching core/src or auth/providers/models/config/tools/services paths. This conflicted with the SKILL.md's impact-scope rule (>3 files or >100 lines = report-only). Replace with a per-commit check: each commit must touch ≤3 files and have ≤100 diff lines. This aligns the deterministic gate with the agent's report-only threshold. * chore(ci): allow repo-hygiene workflow on fork for testing * refactor(repo-hygiene): remove fix cap, file report-only as consolidated issue - Remove MAX_FIXES (8) and MAX_TOTAL_DIFF_LINES (150) caps from workflow gate - SKILL.md: no limit on fixes per run, only per-commit scope threshold - Add workflow step to create single GitHub issue for all report-only findings - Issue is deduplicated against existing open hygiene issues - Per-commit impact-scope gate (≤3 files, ≤100 lines) remains unchanged * fix(repo-hygiene): per-fix typecheck prompt + auto-revert on verification failure - SKILL.md: require typecheck after each individual fix, not batched - Workflow: typecheck runs first with auto-revert loop; bad commits are dropped while good ones survive, then full build+lint+test runs - Prevents one bad fix from killing the entire patrol run * fix(repo-hygiene): forbid retrying failed fixes to avoid loop detection Agent got stuck retrying typecheck fixes repeatedly, hitting the per-turn tool-call cap. Explicitly instruct to accept failures as report-only and move on without retrying. * fix(repo-hygiene): use only existing labels, structured failure handling - Remove HYGIENE_LABEL env var; PR dedup by title+author search instead - Issue uses 'bug' label (always exists); dedup by title search - Remove label creation step - SKILL.md: give agent concrete 3-step failure protocol (checkout, move to reportOnly, continue) instead of vague 'don't retry' * fix(repo-hygiene): remove failure protocol, add anti-loop instruction - Remove 3-step failure handling protocol (was over-engineered) - Restore original 'write failure.md' behavior for failed verification - Add: never re-issue identical tool calls (prevents loop detection) * feat(repo-hygiene): add scan/fix split mode for two-phase execution - SKILL.md: add Mode: scan-only and Mode: fix-only sections - Workflow: add mode input (scan-and-fix/scan/fix) + scan_run_id input - run-agent.mjs: add scan and fix specs with proper inputs/outputs - Scan mode: only scans, uploads findings as artifact (~15min) - Fix mode: downloads previous scan findings, only fixes (~25min) - Gate/verify/push skipped for scan-only mode - Branch name resolution skipped for scan-only mode * refactor(repo-hygiene): split into scan + fix jobs in one workflow Two-phase design within single workflow run: - scan job: read-only, dispatches subagents, writes findings.json (~15min) - fix job: depends on scan, downloads findings, fixes + verifies + pushes (~25min) Benefits: - Each phase stays within model's tool-call budget - Scan failures don't waste fix-phase budget - Fix failures don't require re-scanning - phase input: both (default), scan, fix (with scan_run_id) * simplify(repo-hygiene): remove phase/mode inputs, always scan then fix Users just trigger the workflow. Scan and fix jobs run in sequence automatically. No need for phase selection or scan_run_id. * simplify(repo-hygiene): remove Mode sections from SKILL.md - Replace three Mode sections with single 'Execution Steps' heading - Step 1: scan phase (stop after findings.json) - Step 2: fix phase (read findings, fix, verify, write PR) - run-agent.mjs: invocation now tells agent which phase it's in using plain English instead of slash commands * fix(repo-hygiene): use plain expression in job-level if condition Remove ${{ }} wrapper from job-level if conditions to avoid potential YAML parsing issues. * fix(repo-hygiene): configure git remote with PAT before push Checkout uses persist-credentials: false, so git push needs explicit authentication via remote URL with x-access-token. * fix(repo-hygiene): use single quotes for all if conditions yamllint requires single-quoted strings. Changed all double-quoted ${{ }} expressions to single-quoted with escaped inner quotes. * feat(repo-hygiene): gate drops oversized commits instead of failing - Collect oversized commits during scan loop - Capture commit messages before rebase - Use git rebase -i to drop only the bad commits - Move dropped findings from fixes to reportOnly in findings.json - Continue with remaining commits instead of aborting the run * refactor(repo-hygiene): split SKILL.md into per-phase documents - SKILL.md keeps only shared content: rules, scope limits, findings.json format, output contract - scan.md: scan targets (9 partitions, 6 angles) + scan steps - fix.md: fix steps - run-agent.mjs concatenates SKILL.md + phase doc by mode, so each phase's prompt contains only what that phase needs - Drop the unused scan-and-fix mode * refactor(repo-hygiene): move phase docs into references/ per skill convention Match the triage/docs-audit skill layout: SKILL.md is the entry with shared rules and a Workflow routing section; phase details live in references/scan.md and references/fix.md. The CI runner still injects the right phase doc into the prompt; interactive invocations follow the routing section instead. * refactor(repo-hygiene): adopt references/ progressive-disclosure layout Match the triage skill convention: SKILL.md is the single entry with shared rules and a Workflow routing section; phase details live in references/scan.md and references/fix.md which the model reads itself. The runner now sends only SKILL.md plus a one-line phase invocation. * docs(repo-hygiene): drop redundant duplicate-tool-call rule Loop guard already covers real loop scenarios; forbidding same-arg calls at the SKILL layer added no value for a 9-subagent scan with independent budgets and a state-heavy fix phase. * fix(repo-hygiene): enable agent tool for scan and preserve partial findings Scan settings never whitelisted the agent tool, so the nine-subagent dispatch was impossible and the model scanned serially, blowing the 50-minute budget with zero output. Add agent to scan coreTools, teach the serial fallback to write findings.json incrementally after each partition, and upload agent.log/failure.md so failed scans can be diagnosed. * chore(repo-hygiene): drop fork-only repository guard * chore: drop unrelated advisor design draft from branch * fix(repo-hygiene): harden gate, dedup, and verification semantics - Zero-fix runs are now green: fix phase stops silently instead of writing failure.md when the fixes array is empty - PR dedup matches by hygiene/ branch prefix instead of trusting the agent-written title to contain 'repo-hygiene' - Gate drops oversized commits in one rebase, removing the implicit newest-first ordering dependency of sequential rebases - Dropped and reverted commits are appended as notes to pr-body.md so the PR description matches what is actually in the branch - Scan job timeout raised to 75min (agent 50min cap + ~10min setup left a negative margin); typecheck output no longer suppressed * fix(repo-hygiene): raise agent timeout for nine-partition scans The v4 local run timed out at the 50-minute default while the v5 run completed successfully but close to the limit. Nine parallel subagents need more headroom, especially on slower CI runners. - run-agent.mjs default: 50min → 70min - Scan phase explicit QWEN_TIMEOUT_MS: 65min (job limit 75min) - Fix phase explicit QWEN_TIMEOUT_MS: 75min (job limit 90min) * fix(ci): use full SHAs in gate rebase and document typecheck-only revert * fix(ci): skip push when verification reverts every hygiene commit * fix(ci): route dropped and reverted findings into reportOnly * fix(ci): correlate dropped commits to findings by bracketed id * fix(ci): label hygiene PRs with autofix/repo-hygiene * docs(skill): correct scan partition facts and skip empty report-only sentinel * fix(skill): stop requiring report-only.md as a run-agent output * fix(skill): settle the run-agent promise when the log stream errors * fix(ci): gate the fix job on a scan-phase failure.md and validate findings JSON * fix(ci): make the push gate's success dependency explicit * fix(ci): keep dry runs from filing real report-only issues * fix(ci): drop unregistered read_many_files and grant git clean for reverts * fix(ci): count only production files and lines in the size gate * perf(ci): skip the scan phase while a hygiene PR is still open * docs(skill): resolve failure-handling and schema-regen contradictions * fix(ci): apply review fixes to hygiene gates, runner signals, and skill docs * docs(skill): align scan paths, reportOnly schema, and drop dispositions - Document intentionally excluded packages in scan.md - Fix cli/ui subpackage paths to include components/ prefix - Add optional status field to reportOnly schema in SKILL.md - Carry status in workflow gate/verify node scripts - Give fix.md step 4b the same reportOnly drop path as 4a/4c * fix(ci): add fork guard to repo-hygiene dedup job (#7908) * fix(ci): surface surviving hygiene findings when verification fails (#7908) A post-typecheck failure (build/lint/settings-schema/test) exited the verify step non-zero without moving the surviving committed findings to reportOnly, so the consolidated report-only issue never listed them and a persistent failure silently discarded the same findings every week. Mirror the revert path: an ERR trap now moves every remaining fix to reportOnly (status failed-verify) before the step exits non-zero. Also resolve a Scope Limits contradiction in the skill docs: the <=20-line per-fix rule read as a hard cap while scan.md and the workflow gate enforce only the 100-line/3-file report-only threshold. Make <=20 an explicit target and document the new failed-verify status. * fix(ci): salvage committed findings on failure, append to existing report-only issue, and incremental parallel scan writes (#7908) * fix(ci): address review — contracts gate, sandbox image, gate salvage, revert labeling (#7908) * fix(ci): enforce shell allowlist via auto-edit and salvage rebase conflicts (#7908) * fix(ci): address review — scan mkdir allowlist, rg sandbox note, write deny rules (#7908) * fix(ci): deny write_file to .git and persistence vectors in fix agent (#7908) * fix(ci): deny write_file to executable configs and node_modules in fix agent (#7908) * fix(ci): sandbox verification execution and isolate the PAT-bearing push (#7908) * fix(ci): clarify verification sandbox flags harden, not mirror, the CLI defaults (#7908) * fix(ci): sandbox resolve-owning-packages, re-stage gates, deny lockfile writes (#7908) * fix(ci): make hygiene graceful-failure reachable, gate findings schema, scope artifacts (#7908) * fix(ci): disable core.fsmonitor in gate, deny vite.config writes, align scanner wording (#7908) * test(ci): add a repo-hygiene workflow test suite (#7908) * fix(ci): match test assertions to workflow YAML quoting style (#7908) * fix(ci): use double-quoted YAML if-conditions to match test assertions (#7908) * fix(ci): mount hygiene WORKDIR read-only during sandboxed verification (#7908) --------- Co-authored-by: 俊良 <zzj542558@alibaba-inc.com> Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com> Co-authored-by: qwen-code-ci-bot <qwen-code-ci-bot@users.noreply.github.com> Co-authored-by: qwen-code-dev-bot <qwen-code-dev@service.alibaba.com> |
||
|---|---|---|
| .. | ||
| ai-release-notes-workflow.test.js | ||
| audit-runtime-critical.test.js | ||
| build-and-publish-image-workflow.test.js | ||
| check-build-status.test.js | ||
| check-i18n.test.ts | ||
| chrome-extension-package.test.js | ||
| ci-flaky-rerun-workflow.test.js | ||
| ci-flaky-rerun.test.js | ||
| clean-package-build-artifacts.test.js | ||
| cli-entry.test.js | ||
| comment-attachment-guard-workflow.test.js | ||
| dev.test.js | ||
| e2e-workflow.test.js | ||
| generate-changelog.test.js | ||
| generate-release-notes.test.js | ||
| get-release-version-python-sdk.test.js | ||
| get-release-version.test.js | ||
| install-script.test.js | ||
| issue-triage-ownership-workflow.test.js | ||
| lint.test.js | ||
| main-ci-failure-issue-workflow.test.js | ||
| no-ak-integration-ci.test.js | ||
| package-assets.test.js | ||
| package-scripts.test.js | ||
| pr-force-push-reminder-workflow.test.js | ||
| pr-self-report-label.test.js | ||
| qwen-autofix-workflow.test.js | ||
| qwen-fleet-shepherd-workflow.test.js | ||
| qwen-pr-review-workflow.test.js | ||
| qwen-repo-hygiene-workflow.test.js | ||
| qwen-resolve-workflow.test.js | ||
| qwen-triage-finalize-workflow.test.js | ||
| qwen-triage-workflow.test.js | ||
| release-helpers.test.js | ||
| release-sdk-workflow.test.js | ||
| release-workflow.test.js | ||
| sandbox-command.test.js | ||
| sdk-node-exporter-stub.test.js | ||
| serve-fast-path-bundle-check.test.js | ||
| start.test.js | ||
| test-setup.ts | ||
| update-ecs-runner-qwen-workflow.test.js | ||
| upload-aliyun-oss-assets.test.js | ||
| verify-capture.test.js | ||
| vitest.config.ts | ||
| workspaces.test.js | ||