mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-08-02 04:44:49 +00:00
* fix(autofix): stop repeat-timeout PRs with a cumulative breaker and narrow the retry prompt The consecutive-failure cap resets on every pushed round, so it never fires on the observed failure shape: timeouts interleaved with successes. #7929 burned three 50-minute agent timeouts (with pushed rounds in between) and #7846 two — each a full agent budget with nothing to show, invisible to the breaker by construction. Three changes: - Cumulative timeout breaker (TIMEOUT_WINDOW_CAP=3): time-budget exhaustions are counted over the whole counting window, successes in between included. At the cap the PR goes terminal with a skip-until-/retry headline, exactly like the consecutive breaker. The census reuses PRIOR_HEADS, so it is window-scoped and a re-arm clears it. - Prompt narrowing from the second attempt: when the current window already contains a timeout marker, the prepare step appends a budget warning to feedback.md — smallest blocking subset first, commit early, defer the rest explicitly — instead of re-running the identical address-everything prompt into the same wall. - Truthful gate-rejection handoff: 'A human should take over this PR' read as a full release, but the loop keeps managing the PR (new feedback, base conflicts) — #7929 posted it and then kept pushing rounds. The headline now says exactly which half is over: this item will not be retried automatically, management continues. * fix(autofix): timeout-breaker review follow-ups All six review findings addressed: - The narrowing prompt now restates the SKILL deferral contract instead of pointing at 'your summary': deferred findings stay out of resolved-comments.txt and get a comment-replies.json entry so every open thread carries its reason — the summary-only shortcut is exactly what a budget-pressured agent would otherwise take. 'skip refactors entirely' became 'decline with a one-line reason' for the same never-drop-silently rule. - The narrowing census counts timeouts SINCE THE LAST SUCCESSFUL ROUND, not cumulatively: a push falsifies 'not converging', and one old timeout must not degrade every later round of a 100-round window. The breaker stays cumulative (a push does not make the next timeout cheaper in budget terms). - The breaker headline states what the census measured ('this counting window now contains N time-budget exhaustions') instead of 'stopped after N' — the tripping round can itself be a gate rejection, which is the exact rollout state of #7929/#7846. - Both census needles anchor on the verbatim emitted headline ('AutoFix ran out of time before finishing') — first lines can embed provider error text, so the loose phrase could count a model error as a timeout. - The precedence assertion got teeth: 'consecutive' alone matched both branches; it now asserts the consecutive breaker's own phrase and the absence of the timeout one (the if-true guard mutation now fails). - The narrowing census got a behavioral replay over fixture ic.json: push-resets, trailing counts, legacy no-win markers under 'none', old-window exclusion, author filtering — plus a pin on the -ge 1 trigger so a threshold mutation cannot leave the feature inert. * fix(autofix): state what the timeout breaker measured, pin the inherited guarantees Second-round review follow-ups: - The breaker headline no longer infers 'is not converging' — a window can carry 40 pushes and still trip the (deliberately cumulative) cap, so the sentence now states only what the census measured: N full agent runs that pushed nothing. - Two guardrail tests pin behavior that held only by construction: a non-timeout failure landing on an already-capped window still trips the breaker (the documented rollout state — an 'only count when this round timed out' cleanup would silently delete it), and the transient-API-error exemption inherited from the outer guard (a refactor hoisting the block out of it must not mass-terminate every in-flight PR during a provider outage). * fix(autofix): name a gate rejection only when the gate ran; pin the timeout breaker's stale-base exemption Third-round review follow-ups: - The handoff headline no longer claims 'the verification gate rejected the attempt' for every outcome=failed verdict: that branch is reached for five distinct failures (failure.md abort, dirty tree, unchanged branch, missing summary, and a real gate rejection), only one of which is a gate decision. The clause is now gated on gate-rejection.md, which reject_fix is the sole writer of — so the other four paths keep the neutral framing instead of repeating the very wording-doesn't-match-behaviour bug this PR fixes. A replay test pins both halves: the clause appears when gate-rejection.md exists and is absent when it does not. - The timeout breaker's stale-base exemption is now pinned by a replay (five in-window timeouts plus a stale-base retry current round stays retryable), matching the existing transient-API-error pin: a refactor hoisting the timeout block out of the outer guard would otherwise delete this exemption silently. - The prepare-step narrowing census jq now fails open (2> /dev/null || true) like its report-step sibling, so a malformed ic.json drops the budget warning instead of aborting prepare under errexit and turning the round into a terminal 'could not start evaluation' handoff. - The decay comment now matches the code: the warning resets on a push/no-op round but fires on every failing round until then (gate rejections included), which is correct since nothing has converged. * fix(autofix): clear stale gate-rejection.md in repair cleanup and pin headline template (#8044) * test(autofix): cover no-op reset branch in timeout census (#8044) --------- Co-authored-by: verify <verify@local> Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com> |
||
|---|---|---|
| .. | ||
| installation | ||
| lib | ||
| tests | ||
| acp-http-smoke.mjs | ||
| audit-runtime-critical.js | ||
| benchmark-api-latency.mjs | ||
| build-hosted-installation-assets.js | ||
| build-standalone-release.js | ||
| build.js | ||
| build_package.js | ||
| build_sandbox.js | ||
| build_vscode_companion.js | ||
| check-build-status.js | ||
| check-desktop-isolation.js | ||
| check-i18n.ts | ||
| check-lockfile.js | ||
| check-serve-fast-path-bundle.js | ||
| clean-package-build-artifacts.js | ||
| clean.js | ||
| cli-entry.js | ||
| copy_bundle_assets.js | ||
| copy_files.js | ||
| create-standalone-package.js | ||
| create_alias.sh | ||
| daemon-dev.js | ||
| desktop-openwork-sync.ts | ||
| dev.js | ||
| esbuild-shims.js | ||
| generate-changelog.js | ||
| generate-git-commit-info.js | ||
| generate-release-notes.js | ||
| generate-settings-schema.ts | ||
| get-release-version.js | ||
| lint.js | ||
| local_telemetry.js | ||
| measure-flicker.mjs | ||
| pre-commit.js | ||
| prepare-package.js | ||
| prepare.js | ||
| release-script-utils.js | ||
| run-java-daemon-sdk-e2e.ts | ||
| sandbox_command.js | ||
| sdk-node-exporter-stub.js | ||
| sign-release.sh | ||
| start.js | ||
| sync-computer-use-schemas.ts | ||
| telemetry.js | ||
| telemetry_gcp.js | ||
| telemetry_utils.js | ||
| test-rewind-e2e.sh | ||
| test-windows-paths.js | ||
| unused-keys-only-in-locales.json | ||
| upload-aliyun-oss-assets.js | ||
| verify-installation-release.js | ||
| version.js | ||
| workspaces.js | ||