1281 Commits
Author SHA1 Message Date
a4331340ad fix(ci): skip main-failure issues for post-merge reruns (#15239) (#15250)
* fix(ci): skip main-failure issues for post-merge reruns (#15239)

A rerun re-executes the PR's pre-merge workflow. When it starts after the
PR merged, its failure describes a head that main has already replaced,
and the post-merge push run owns that signal. Compare the attempt's start
time with the merge time and skip filing for the stale head.

Run 39768204855's attempt 2 started after PR #15094 merged, hit the
pre-#15128 suite-wide host-lock hold, and filed #15239.

* fix(ci): discriminate post-merge reruns by attempt (#15239)

The clock proxy suppressed fresh manual dispatches and post-merge
approval runs while missing reruns dispatched before the merge. Use
run_attempt, which states rerun identity directly: attempt 1 still
files, later attempts on a merged PR keep the comment but open no
issue. Announce the empty-attempt fail-open path.

Preserve an existing tracking-issue link when a suppressed attempt
updates the PR comment, and sync the design docs and the contract
comments with the narrower scope.

* fix(ci): pin rerun guard scope and tracking-link recovery (#15239)

Drop the pre-loop body write that no publish path could read, and cover the
publish-retry truncate with a row that fails the first publish. Pin the
writer's tracking line against the recovery grep's anchored pattern, and pin
that the attempt guard never suppresses a main run. Scope the design doc's
exclusivity sentence to the infrastructure path in both languages.

The workflow size ratchet records the file's new size; the growth is the
attempt guard and tracking-link recovery this PR adds.

Co-authored-by: Qwen-Coder <[email protected]>

* test(ci): pin tracking-link precedence for PR failure comment (#15239)

Co-authored-by: Qwen-Coder <[email protected]>

* test(ci): pin tracking-link wiring and POST coverage (#15239)

* fix(ci): file dispatch reruns on merged PR branches (#15239)

* test(ci): pin merged-PR rerun event and lookup-failure publish guard (#15239)

Co-authored-by: Qwen-Coder <[email protected]>

* test(ci): pin approval-run suppression and merged-PR comment guard (#15239)

Co-authored-by: Qwen-Coder <[email protected]>

---------

Co-authored-by: qwen-code-dev-bot <[email protected]>
Co-authored-by: Qwen-Coder <[email protected]>
2026-10-25 09:49:49 +00:00
ba051f804a fix(ci): run the sdk-java suite before taking the host lock (#15254)
* fix(ci): run the sdk-java suite before taking the host lock (#15242)

Run 39771949573's fast-tier job spent both attempts' full 5400 s lock
budget waiting: the full-tier Java 21 leg of run 39754414693 ran for 89
minutes on the same host, and the fast job failed five seconds after that
leg ended. The MariaDB lane's #15128 fix scoped the lock to its cache
write-back, but the test job still held the host lock across the SDK and
Managed Agent Maven suites.

Seed the test job's Maven repository from the host cache, run its suite
from that job-local copy, and take the ticketed host lock only for the
cache write-back. The write-back children close fd 9 so a cancelled job's
survivor cannot retain the lock, and the workflow pins move with the new
order.

* fix(ci): keep the SDK Java gate green when the write-back lock expires (#15242)

The write-back lock acquisition could redden a job whose suite had already passed (CI run 39814549427). Treat it like the best-effort copy it guards: warn and skip on timeout in both the helper and fallback arms, while leaving the helper's pinned lock-not-acquired signature alone.

Tighten the workflow pins: assert the region below the lock instead of first-occurrence Maven indices, pin both write-back copies byte-equal, bind the job-local MAVEN_ARGS to its step, and include the write-back bound in the test job's ceiling model. Restate the hold-length derivations and record the concurrency blast radius in both design languages.

Co-authored-by: Qwen-Coder <[email protected]>

* fix(ci): keep the lock helper outside this PR's footprint (#15242)

Co-authored-by: Qwen-Coder <[email protected]>

* fix(ci): describe the sdk-java 89-minute leg as the leg, not the suite (#15242)

Co-authored-by: Qwen-Coder <[email protected]>

* fix(ci): keep tolerated sdk-java lock timeouts out of rerun classification (#15242)

The warn-and-skip downgrade left the helper's `lock not acquired within`
annotation on a step that now exits 0, so a later genuine failure in the
same job could be classified as infrastructure. Both call sites rewrite
the timeout line before it reaches the log, and probe flock plus the cache
directory first: bash suppresses errexit for a function on the left of
`||`, so without the probes a setup fault spun out the full wait green.

The skip test now plants a publishable delta, asserts nothing was
published, checks the captured annotations against the live
INFRA_FAILURE_SIGNATURES list, and adds a setup-fault arm. The workflow
size baseline is re-measured, and the design docs' classifier, promotion,
and budget claims are corrected in both languages.

---------

Co-authored-by: Qwen-Coder <[email protected]>
Co-authored-by: Qwen Autofix <[email protected]>
2026-10-25 09:45:34 +00:00
Shaojin Wen 1c9cdd234f feat(verify-pr): declare an argument hint for the command prompt (#15463)
* feat(verify-pr): declare an argument hint for the command prompt

Typing `/verify-pr` showed no parameter hint, unlike `/review`, because the
skill's frontmatter carried only `name` and `description`. The TUI renders
`argument-hint` beside the command name and `/review` relies on exactly that
field, so `/verify-pr` looked like it took no arguments at all.

The hint lists the PR number and every flag the skill accepts — `--publish`,
`--watch`, `--repo`, `--assets-repo`, `--assets-branch` — and a scripts
assertion pins it, so dropping a flag from the hint reddens the test.

* test(verify-pr): pin the parsed argument hint instead of its raw line

Assert the parsed frontmatter value so a requoted plain scalar stays green while a dropped value placeholder goes red, and record in the skill's environment contract that .qwen/** is the base commit's copy in the verify lane.
2026-10-25 16:55:21 +08:00
易良 5aeee2ceec fix(release): authenticate managed OSS preflight (#15504) 2026-10-25 16:51:21 +08:00
易良 cc49daa282 fix(ci): preserve independent validation for main push SHAs (#15508) 2026-10-25 16:51:04 +08:00
易良 10c036b655 fix(ci): keep the incremental lint history fetch blobless and visible (#15511)
Lint & Static can already hold a blobless merge base: Report test growth
fetches it with --filter=blob:none. A later plain depth-100 fetch then
fails resolving thin-pack deltas against blobs this checkout does not
have (fatal: missing blob object + remote did not send all necessary
objects), and continue-on-error turns that into a silent full scan:
4 of 8 sampled PR runs after #15381 merged, with 5 of 8 falling back to
full lint in total.

Fetch blobless too, and drop the recorded filter so later fetches in the
checkout stay ordinary. lint-scope reads only commits and trees.

Announce a history fallback as ::warning:: plus a step-summary line on
workflow runs, deduplicated across the seven lint.js invocations, so the
optimization can no longer stop working without a trace.
2026-10-25 16:31:34 +08:00
e9b09e1c82 fix(test): budget the standalone runtime suite for the release pool (#15102)
* fix(test): budget the standalone runtime suite for the release pool (#15091)

The new Node/Bun regression suite runs two sequential workers that each spawn hundreds of probes. Release run 39621619809 lost both attempts at the 300 s per-worker and 600 s total spawn caps on the release pool, even though the same suite completes in about five minutes on a developer machine.

Raise the per-worker budget to 600 s and the total budget to 1500 s so release validation can finish on the shared runner. The job's own 30-minute timeout remains the upper bound.

* fix(test): fit the runtime budget inside the release job (#15091)

The old caps were never both hit: in release run 39621619809 the node worker passed at 294 s while the bun worker was SIGTERM'd by the 300 s per-worker cap at 301 s, and the child exited before the 600 s outer cap. Correct that attribution in the budget comment.

Derive the outer cap from the two sequential workers plus setup, and pick a 540 s worker cap so the derived 1140 s spawn still fits the 30-minute quality_scripts job beside the measured ~295 s setup and ~288 s scripts suite. A release-workflow meta-test pins the derivation, the worker/outer ordering, and the job-budget fit.

Co-authored-by: Qwen-Coder <[email protected]>

* fix(test): classify the OpenTUI parity suites for the no-AK gate (#15091)

Main's OpenTUI migration added three interactive TUI parity suites, but the
no-AK membership guard requires every runnable integration test to be either
selected or explicitly exempted. The merged tree therefore failed the Test job
at no-ak-integration-ci.test.js:378.

The three suites are heavyweight interactive tests already covered by the
three-leg tui-parity workflow, so exempt them as "Runtime budget" alongside
the existing tui-migration and interactive-session-viewport entries.

* fix(ci): preserve enrolled parity suites in runtime budget repair

* test(scripts): pin standalone runtime timeout wiring and budget envelope

Cover the outer-margin floor, both spawnSync timeout bindings, and the package.json hop that places the spawn inside quality_scripts, so the release budget ratchet fails when any of them detaches.

Co-authored-by: Qwen-Coder <[email protected]>

* fix(test): close the standalone runtime budget over setup phases (#15091)

The budget ratchet counted only the child spawn plus a hand-picked reserve, leaving the parent's four downloads and two tar extractions and the child's five pre-worker probes outside the model. Bound each process's setup with a shared SETUP_TIMEOUT_MS, derive the outer cap from it, and assert the closed sum against quality_scripts' 30-minute budget.

Also pin the per-host failure diagnostic the margin protects and the package.json hop that reaches --ci, so removing either fails the ratchet.

Co-authored-by: Qwen-Coder <[email protected]>

* test(scripts): make the runtime cache fetch pin shape-insensitive (#15091)

Co-authored-by: Qwen-Coder <[email protected]>

* test(scripts): enforce the setup budget through one factory (#15091)

Co-authored-by: Qwen-Coder <[email protected]>

---------

Co-authored-by: Qwen Autofix <[email protected]>
Co-authored-by: Qwen-Coder <[email protected]>
Co-authored-by: 易良 <[email protected]>
Co-authored-by: qwen-code-dev-bot <[email protected]>
2026-10-25 15:47:18 +08:00
Barry 12c620e314 test(ci): pin JUnit report upload paths (#15502)
Guard the CI artifact contract by resolving each JUnit writer against its Vitest root and requiring the package-level upload location.

Tested: targeted Vitest, ESLint, Prettier, build, typecheck, diff check
2026-10-25 14:45:46 +08:00
Aling33 195029c12c ci(sdk-java): upload Surefire text reports on test failure (#14910)
* ci(sdk-java): upload Surefire text reports on test failure

* ci(sdk-java): quote if-no-files-found for yamllint
2026-10-25 06:38:25 +00:00
易良 32b1f12f75 fix(release): bound summary concurrency and refresh release PRs (#15500) 2026-10-25 13:58:22 +08:00
ChiGao 4339775208 fix(cli): preserve OpenTUI clipboard source across draft recovery (#15396)
* fix(cli): align OpenTUI cancellation and retry with Ink

* fix(cli): discard abandoned OpenTUI tool attempts

* feat(cli): preserve OpenTUI session replay and rewind

* fix(cli): preserve checkpoint restore ownership and cold continuation

* test(cli): cover committed conversation rewind across renderers

* feat(cli): capture and restore OpenTUI checkpoints

Candidate checkpoint before parent test integration; full normal and combined product validation are still pending.

* test(cli): remove duplicate checkpoint regression declarations

* fix(cli): preserve Ink compact tool summaries after restore

* fix(cli): preserve OpenTUI clipboard source through draft recovery

* test(cli): cover OpenTUI raw recall and framed Vim submissions

* fix(ci): register clipboard regression in TUI parity gate

* fix(cli): preserve logical restore identity across authorized edits

* test(cli): assert saved restore call identity in permanent acceptance

* test(cli): align native tool result provenance assertion
2026-10-25 13:51:23 +08:00
易良andQwen-Coder cf3ba47dfd fix(ci): file main CI failures whose successor has not settled (#15471)
* fix(ci): file main CI failures whose successor has not settled

The guard added in #15272 treats a queued or in-progress successor at
main's tip as owning the result, so the report is skipped. A successor
that later ends cancelled, timed_out or skipped never re-enters the
workflow — its gate admits only failures — so the failure is never
reported at all.

That is how 10 main-push failures between 14:00Z and 17:30Z on
2026-10-24 produced no issue (#15470), with 65 of the last 100 Qwen
Code CI push runs on main ending cancelled.

The reporter cannot wait for the successor either: it runs on
ubuntu-latest, and that pool queued it for 20-100 minutes in the same
window. Report instead, marked provisional, since the per-signature
route hands new issues to a human rather than to autofix: a stale
provisional report costs a close, a dropped one costs the regression.

* fix(ci): keep a provisional head off the infra rerun path

Four review findings on d98bc2d1ca:

- rerun_infra holds actions: write but was gated only on infra_only and
  file_issue. An unsettled successor now yields provisional=true instead
  of superseded=true, so destination runs and file_issue becomes true: an
  infra-only failure at a head main already replaced would dispatch
  rerun-failed-jobs onto the contended pool this PR cites (#15470), and a
  successful dispatch would then satisfy file_issue's
  `rerun_infra.result != 'success'` operand, so nothing was filed and no
  step summary was written either. Add the provisional operand; skipping
  the rerun is what makes file_issue record it instead.
- Only a settled successor can own the result, so invert the case arm:
  anything but `completed` (and `none`) is provisional. The enumeration
  covered queued and in_progress only, leaving waiting, requested and
  pending to file without the caveat and to warn falsely that the
  successor "does not report".
- The caveat heads the comment routes as well as the create routes, so
  "this issue can be closed" was advice to close a tracker belonging to a
  different occurrence. Reword to "this report can be dismissed".
- Pin both YAML hops of the provisional wire; retyping either left
  PROVISIONAL empty and the suite green.

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmvmwqg38tp

* test(ci): cover the provisional caveat on its two untested write sites

The caveat is prepended once ahead of the route split, so it reaches three
write sites: the per-signature certified-miss create, the per-signature
recurrence comment, and the aggregate route. Only the first was exercised
with provisional=true, so narrowing the prepend to a single branch would
drop the caveat from the other two unnoticed.

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmvn35xgdtw

---------

Co-authored-by: Qwen-Coder <[email protected]>
2026-10-25 12:51:30 +08:00
1a98854b76 test(ci): pin the disk-pressure collector revision and FULL_PAYLOAD run bodies (#15475)
* test(ci): pin the disk-pressure collector revision and FULL_PAYLOAD run bodies

Two deferred review findings from #10919 (issue #11032). Both are
assertion-only: no workflow file is touched.

The shared-prelude equality loop compares `test` and `lint_and_static` to
each other, so both jobs' disk-pressure collector moving to a different
`actions/upload-artifact` revision together leaves both serializations
equal and reports green. The SHA-format regex on `Upload Test Results
Artifact` is not a witness either: it accepts any 40-hex revision, on a
different step. Pin the literal revision instead, resolved per job
because the collector step carries the same name in both.

The FULL_PAYLOAD test pinned name, order and gate, but only the two
notices steps had a command body pinned: emptying `Run ESLint`'s `run:`
or repointing it at `true` left every suite green while a required check
stopped running the tool it is named for. Extend the existing loop with a
name -> load-bearing-substring map that is total over FULL_PAYLOAD, and
assert the substring rather than whitespace-exact text so reformatting
one of the multi-line blocks stays benign.

Verified by mutation in both directions. Against the pre-change suite,
moving the collector pin in both jobs, emptying `Run ESLint` and
repointing it at `true` all stayed green (44/44) -- that green was the
defect. With these assertions the same three mutations fail, and the
unmutated suite passes 45/45.

Refs #11032

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-issue-patrol/jmvmng32bjj

* test(ci): pin collector retention, payload gates and failure propagation

Addresses the four review findings on the pins this PR adds, all of them
the same class of gap: an assertion that proves a string is present but
not that the thing it guards still happens.

R1-1: `with.retention-days` was unpinned on both disk-pressure collectors,
so a coordinated edit reported green through the job-to-job equality loop
(the loop is blind to both sides moving together). Pinned per job as the
literal 14; the JUnit `Upload Test Results Artifact` step deliberately
retains 7, so no shared constant.

R1-2: map totality over FULL_PAYLOAD was only incidental — `toContain`
coerces a missing entry to the literal string "undefined", which a body
containing that word passes silently, and a stale key after a rename reads
as coverage that no longer exists. Asserted the key sets match instead.

R1-3: payload gates were filtered by a `ci_profile == 'full'` substring, so
appending any further `&&` clause dropped a step from the unattended
post-merge lane while every substring still matched. All 19 gates are
byte-identical, so pin the whole literal.

R1-4: containment proves the command is present, not that its failure
reaches the job status. Pinned `continue-on-error` absent and no
`|| true`/`|| :` in the body, plus `exit 1` in the settings-schema gate.
Both stay inside the loop: `Report test growth` and `Fetch incremental
lint history` set continue-on-error deliberately, and the helper-tests
retry legitimately uses `|| {`.

Each new assertion was shown to fail by mutating `.github/workflows/ci.yml`
one edit at a time: the six gap mutants pass 45/45 against the previous
head and each is killed by exactly the assertion added for it. The
one-sided retention control still trips the pre-existing equality loop, so
those greens were coordinated-edit blindness rather than a dead comparator.

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmvmwqg38tp

---------

Co-authored-by: yiliang114 <[email protected]>
Co-authored-by: Qwen-Coder <[email protected]>
2026-10-25 12:50:50 +08:00
ChiGao c7c9717d07 fix(cli): run OpenTUI on private Bun 1.4.4 (#15387)
* fix(cli): run OpenTUI on private Bun 1.4.4

* docs(cli): bind runtime acceptance to integrated main

* test(cli): add permanent installed npm runtime acceptance

* ci: record installed TUI workflow size

* ci: record installed TUI job budget

* ci: quote missing installed artifact failure mode

* fix(core): preserve encrypted storage identity across Bun handoff

* fix(test): retain installed command startup evidence

* fix(cli): reject Bun loader options during npm handoff
2026-10-25 11:50:17 +08:00
ChiGao f520bac55c fix(cli): preserve checkpoint restore ownership and cold continuation (#15386)
* fix(cli): align OpenTUI cancellation and retry with Ink

* fix(cli): discard abandoned OpenTUI tool attempts

* feat(cli): preserve OpenTUI session replay and rewind

* fix(cli): preserve checkpoint restore ownership and cold continuation

* test(cli): cover committed conversation rewind across renderers

* fix(cli): preserve logical restore identity across authorized edits

* test(cli): assert saved restore call identity in permanent acceptance

* test(cli): align native tool result provenance assertion
2026-10-25 08:50:52 +08:00
ChiGao d6102c04e1 fix(cli): align OpenTUI cancellation and retry with Ink (#15283)
* fix(cli): align OpenTUI cancellation and retry with Ink

* fix(cli): discard abandoned OpenTUI tool attempts
2026-10-24 23:46:45 +08:00
qqqys bafe530a84 feat(core): add an experimental shared agent loop and run headless on it (#15369)
* feat(core): add an experimental shared agent loop and run headless on it

Every surface implements its own send, run tools, repeat loop. This adds
runAgentLoop to core: one model round through LlmClient, the returned
tool calls as one batch on a single CoreToolScheduler, the results
finalized and recorded once in request order, then the next round. The
client's terminal events become typed stop reasons.

CoreToolScheduler gains an optional beforeToolLaunch callback that runs
serially in request order before each launch; a concurrent batch asks
for every call that fits in flight before launching any of them.
Without the callback the scheduler is unchanged.

With experimental.unifiedAgentLoop (or
QWEN_CODE_ENABLE_UNIFIED_AGENT_LOOP=1), headless runs its rounds and
drain items on the shared loop. With it off, headless runs the current
code, which only moved into an else branch. A no-AK parity suite runs
each scenario through the built CLI with the setting off and on and
requires the same requests, stream-json frames and exit code.

Part of #15327

* docs(design): update the unified agent loop design for PR 1

Record what implementing PR 1 settled: the launch hook asks a whole
in-flight window and every call of a batch once, results reach the
surface at batch end, the intended headless differences, how the design
relates to #8775, and the status.

Part of #15327
2026-10-24 15:21:54 +00:00
易良andQwen-Coder 6c3d84d361 fix(cua): sign Windows UIAccess workers before publishing (#12442)
* fix(cua): sign Windows UIAccess release workers

* fix(cua): select imported code-signing certificate correctly

* fix(ci): keep CUA signing within workflow size limit

* fix(cua): isolate dry-run signing credentials

Keep production certificate secrets out of branch dry runs and fall back to
PowerShell 7 only when the legacy signature module cannot load.

* fix(cua): select the release signing certificate by EKU extension

The production signing path filtered on `$_.EnhancedKeyUsageList.ObjectId`,
but `EnhancedKeyUsageList` elements are Certificate-provider display strings
and `Oid` exposes only FriendlyName and Value. Neither type has an `ObjectId`
member, so the filter matched nothing and every real release threw on a
correctly configured PFX. Match the raw EKU extension instead; that route does
not depend on provider script properties being attached to the object
`Import-PfxCertificate` returns.

Verified by execution on PowerShell 7.4.6 / .NET 8 against openssl-generated
PFX fixtures: the old predicate selects 0 for a genuine code-signing cert,
while the replacement selects it and rejects a serverAuth-only cert.

Also narrow the installer's powershell-to-pwsh retry to the non-localized
`CouldNotAutoloadMatchingModule` error id observed on the windows-2025 runner
during the release dry run. The previous `Microsoft.PowerShell.Security`
substring also appears in ordinary Get-AuthenticodeSignature errors, where the
retry hid the real result behind a shell users usually do not have.

Replace the test assertion that pinned the dead filter with assertions on the
EKU-extension mechanism, and forbid the removed member access.

Co-authored-by: Qwen-Coder <[email protected]>

* fix(cua): fail closed on half-configured cert pairs and clean up the imported key

Review follow-ups on the Windows UIAccess signing path:

- sign-cua-windows-worker.ps1: throw on a half-configured
  WINDOWS_CERTIFICATE / WIN_CSC_LINK pair (mirroring desktop-release.yml)
  instead of silently falling through to the other identity, and remove the
  imported leaf certificate from Cert:\CurrentUser\My in a finally after
  the sign + verify lines, so the key is not resident while the later
  scripts-enabled clean-install step runs under the same user.
- install-native.mjs: chain the original Windows PowerShell 5.1
  CouldNotAutoloadMatchingModule diagnostic into the pwsh retry failure
  (the entry renderer prints only error.message), and map EPERM/EACCES on
  the deploy mkdir to an elevation message naming the elevated install.ps1
  alternative. installUiAccessWorker is exported with the signature check
  and mkdir injectable so both are testable off Windows.
- computer-use SKILL.md / user guide: state the Windows elevation
  precondition where the install actually runs, with the elevated
  install.ps1 alternative and the already-installed short-circuit.
- release-workflow.test.js: pin the new guards, the whole clean-install
  signature verdict (comparison and throw, not just the cmdlet token), the
  Remove-Item-before-cargo-build ordering the `Valid` gate now depends on,
  and the retry guard's polarity — replacing the source-text ban on the
  Microsoft.PowerShell.Security module name that a deeper 5.1 fix needs.

Co-authored-by: Qwen-Coder <[email protected]>

* fix(cua): integrate SignPath signing and verify opt-in UIAccess install

* fix(cua): clarify UIAccess recovery and narrow signing scope

* fix(cua): test-sign the Windows worker through the SignPath API

The SignPath GitHub connector needs the SignPath GitHub App, which this
repository cannot install. Branch dry runs now submit the UIAccess worker
directly to the SignPath REST API with the configured token, verify the test
certificate, and install the signed worker. Release builds keep shipping the
unsigned worker so ordinary-mode Windows releases never depend on a
production certificate.

* fix(cua): supply the browser-use tarball to the Windows clean-install step

The clean-install step ran `npm install` with only the SDK tarball, so npm had
to resolve the SDK's exact-pinned `@qwen-code/browser-use@<version>` from the
public registry. `validate-version` forces that pin to equal the release
version, and the only publisher of it is `publish-browser`, which needs
`release`, which needs `build-windows`. The step carries no `if:`, so tag
releases run it too: cutting `cua-driver-rs-v0.27.0` would fail both Windows
legs with ETARGET before `upload-artifact` and skip every downstream publish
job, and a re-run fails identically because the only publisher sits behind the
job that just failed. It stays invisible today only because `0.26.0` already
happens to be on npm.

Mirror what `verify-sdk-package` already does in this same file: depend on
`verify-browser-package` (acyclic, it needs only `validate-version`), download
its `browser-use-npm-<version>` artifact, and pass both tarballs to one
`npm install`. Pin the fix with two assertions that go red if the sibling
tarball or the job edge is dropped.

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmvl4fms0ro

---------

Co-authored-by: Qwen-Coder <[email protected]>
2026-10-24 19:53:39 +08:00
d3f7eef1df fix(ci): skip stale main CI failure issues after main advances (#15272)
* fix(ci): skip stale main CI failure issues after main advances (#15259)

Run 39777472391's push run on 06e59666 failed on the sdk-java host-lock
timeout that #15128 had already fixed. The failure-issue analyzer then ran
after main had advanced to 3d65e23, whose own push run passed, and filed
#15259 asking for a repair main already contained.

Skip a push run whose head is no longer the tip of main: the newer push run
owns that result, exactly as a later attempt does. The tip read fails open,
and scheduled/manual runs keep reporting because they are the only signal
some lanes have.

* test(ci): pin the empty main-tip fail-open path (#15259)

Co-authored-by: Qwen-Coder <[email protected]>

* fix(ci): require a successor run before suppressing stale main failures (#15259)

Co-authored-by: Qwen-Coder <[email protected]>

* fix(ci): cover retried runs in the stale-head guard (#15259)

Co-authored-by: Qwen-Coder <[email protected]>

* fix(ci): suppress only successor runs that can report (#15259)

---------

Co-authored-by: Qwen Autofix <[email protected]>
Co-authored-by: Qwen-Coder <[email protected]>
Co-authored-by: qwen-code-dev-bot <[email protected]>
2026-10-24 19:46:24 +08:00
907de17fd7 feat(memory): add scoped external import jobs for CLI and HTTP (#14281)
* feat(memory): add scoped external import jobs for CLI and HTTP

* fix(memory): align import contracts and isolate runtime scope

* feat(memory): bound and batch external import consolidation

* test(cli): scope the mod-session mock to the test's own Config (#14281)

AppContainer mount effects from earlier tests can still be in flight
(the beforeEach leaves the real config.initialize() un-awaited), and an
unscoped getInteractiveModSession mockReturnValue lets those stale
effects call the current test's initialize() mock, intermittently
inflating the exact-once assertion to 51+ calls. Scoping the mock by
Config identity makes the stale calls a no-op, matching the real
function's behavior for unregistered configs.

* fix(cli): harden memory import auth, argv parsing, output flush, and recovery guards

- pass isInitialAuth to refreshAuth so a non-interactive confirmed import
  fails closed on missing credentials instead of starting a device flow
- pin the import positional to 'codex' and reject a repeated --source
  instead of silently importing the default directory
- flush the JSON result envelopes before exit so piped output is not
  truncated
- clear a failed item's stale reason on retry
- bound remark parsing with an over-approximate heading pre-scan
- enforce the no-Git-checkout runtime invariant on recovery, not only on
  admission
- key the publication ledger on section identity so identical text from
  distinct files no longer collapses onto one entry
- pin the memory fast-path member in the cli-entry wrapper test

* fix(cli): harden memory import bootstrap, auth, and batch recovery

- memory fast path prints help to stdout for bare/-h invocations
  instead of failing demandCommand (R4-1, R3-1)
- local import resolves auth through the config and enforces
  security.auth.enforcedType before any model spend (R4-28, R1-8)
- rollout_summaries admission matches the discovery class so a
  referenced but undiscoverable name is rejected up front (R4-26)
- section splitting uses the shallowest heading depth present rather
  than the constant 1 (R3-4)
- a moved linked worktree reaches the registration diagnostic instead
  of a raw ENOENT, and recall warns once with the repair hint (R4-27)
- the flushed result writer tolerates EPIPE from a departed reader
  (R3-2)
- retry() waits out a still-registered worker instead of losing the
  race (R1-1); recover()/list() isolate a damaged batch directory
  instead of failing the whole walk (R1-2)

* fix(cli): fence import lock loss and bound preview resources

* fix(cli): recover invalid import proposals and handle pipe closure

* test(web-shell): await return boot before asserting connection URL

* fix(cli): recover imports across groups and stale publication intents

* fix(cli): retry failed workspace memory import recovery

* fix(cli): preserve durable import receipts and classify HTTP failures

* test(cli): complete injected runtime storage fixture

* fix(cli): reject symlink import roots before model usage

* fix(build): allow CLI compilation beyond the 4 GiB heap cap

* fix(memory): revalidate cached repository identities

* fix(cli): bound the existing-memory context index (#14281)

Co-authored-by: Qwen-Coder <[email protected]>

* fix(memory): preserve native user index capacity during import

* test(managed-agent): fix hosted MCP checkstyle violations

* fix(memory): preserve relevant evidence and unpublished intent recovery

* fix(memory): keep CR sections, mid-document terms and admission budgets

* test(ci): account for TUI parity integration coverage

* test(cli): synchronize monitor stop observation

* test(cli): wait for the memory preview write in the flush test

Co-authored-by: Qwen-Coder <[email protected]>

* test(cli): scale Hosted budgets for contended gate hosts (#14281)

The review gate drops RUNNER_NAME and clamps vitest to 25% of the cores,
so the load-average fallback never reached the core count and the heavy
Hosted suites kept their fast-host ceilings. Halve the contention
threshold and scale the two budget tests' ceilings with it.

* test(ci): remove exemptions for enrolled no-AK tests

* fix(cli): harden memory import scopes and auth checks

Normalize setext and closed ATX heading titles before scope
classification, stop unquoted cwd captures at whitespace and reject
prose or trailing punctuation, demote imported documents regardless of
scan scope, and validate the auth method before paid import calls.

* fix(cli): close memory import review gaps (#14281)

---------

Co-authored-by: qwen-autofix <[email protected]>
Co-authored-by: Qwen-Coder <[email protected]>
Co-authored-by: qwen-code-dev-bot <[email protected]>
Co-authored-by: qwen-code-autofix <qwen-code-autofix@localhost>
Co-authored-by: qwen-code-dev-bot <[email protected]>
Co-authored-by: Shaojin Wen <[email protected]>
Co-authored-by: Qwen Autofix <qwen-autofix@localhost>
Co-authored-by: claudeethan <[email protected]>
Co-authored-by: qwen-code autofix <[email protected]>
2026-10-24 10:04:55 +00:00
Shaojin Wen 623572bd16 feat(verify-pr): add a watch mode backed by the PR probe gate (#15409)
* feat(verify-pr): add a watch mode backed by the PR probe gate

A maintainer round ends with the report; noticing the next push and starting
the next round is manual. The two halves of an automatic trigger already ship
(the PR probe that prints only transitions, and a scheduled task whose gate
runs a shell command outside the model), but nothing connects them, so each
maintainer rebuilds the same cron and re-learns its failure modes.

--watch composes them: a recurring gated task whose gate is
`autofix-pr snapshot <n> --gate`, so a fire costs one shell command and the
round runs only when the head actually moves. The contract adds the guardrails
the pieces do not enforce for each other — an absolute CLI path that carries
the probe, gh auth before scheduling, a state file written before the round so
a dead round does not replay the same head, and cron_delete on stop.

* fix(verify-pr): filter gate events and refuse a shared probe cursor

Two review findings on the watch mode, both composition defects rather than
wording.

The gate's output is what starts a turn: the scheduler hands any non-empty
output to the model, so a probe line for a new comment or a failed check
(`action: "fix"`) woke the watch while the head stood still — the prompt cannot
un-start a turn that already began. scripts/verify-pr-watch-gate.mjs now wraps
the probe and forwards only `resync` and `stop`; unparseable output is
forwarded rather than swallowed, and a failing probe still surfaces as a gate
failure.

The probe keeps one cursor per PR, so a second `snapshot --gate` watcher on the
same PR takes the head moves and `stop` the first one needs, and a prepared
`autofix-pr` watch suppresses heads through `knownHeads`. Verification-owned
state would need a probe flag that does not exist, so the wrapper's `--check`
refuses to install when the PR's gate cursor or prepared state already exists,
and the skill says coexistence is unsupported instead of letting two watchers
starve each other.

* fix(verify-pr): run the watch gate on encoded paths and reserve the PR atomically

Two review findings on the wrapper.

The entry-point check compared `import.meta.url` against `file://` + a raw
path. `import.meta.url` is percent-encoded, so a checkout containing a space or
non-ASCII characters never ran `main()` — the gate exited 0 with empty output,
which the scheduler reads as a quiet tick, for head moves, stops and probe
errors alike. Both sides are now resolved through `realpath`, which also covers
a symlinked checkout because Node resolves the entry module's symlinks while
`argv[1]` keeps the shell's path.

The setup check only read files. Two sessions sharing a clone could both pass it
before either probe created its cursor, and both install a watch on one cursor.
Setup now takes an atomic claim (`wx`) on
`.qwen/tmp/verify-pr-watch-<n>.owner.json`; a read-only check reports an
existing claim too, and a claim is never taken over from a timestamp — deciding
staleness that way is the same race — so a dead setup's claim is released with
`--release`, which the skill also runs when the task stops or creation fails.
2026-10-24 17:49:17 +08:00
54b662ff96 fix(ci): raise the sdk-java test-lane lock wait above the longest hold (#15257)
* fix(ci): raise the sdk-java test-lane lock wait above the longest hold (#15243)

Co-authored-by: Qwen-Coder <[email protected]>

* docs(ci): restate sdk-java lock wait sizing and lane budgets (#15243)

* fix(ci): pin the sdk-java lock fallback minutes and restate sizing (#15243)

The bare-lock fallbacks hand-write their timeout line, so raising
`flock --wait` could leave `160 minutes`/`90 minutes` stale with every
test green; pin both literals. The sizing comments also cited a
pre-#15128 run as evidence for a sibling-hold chain and repeated an
uncited 925 s hold; frame that run as the history it is, state that
9600 s is headroom sized from the hold length rather than an observed
chain, and keep the derivation in the design doc's Goals.

---------

Co-authored-by: Qwen Autofix <[email protected]>
Co-authored-by: Qwen-Coder <[email protected]>
2026-10-24 09:25:45 +00:00
ca30321e54 test(integration): give the skill-hook parity E2E the docker startup budget (#15226) (#15237)
* test(integration): give the skill-hook parity E2E the docker startup budget (#15226)

The parity suite hardcoded a 30s TUI-readiness wait, but the sandbox:docker
leg boots a fresh container and has stalled past that before the prompt
renders (#13552, #14191). The model-invoked case runs first in the file, so
its cold boot was the one that timed out while the second case started warm.

Use the measured readyPromptBudgetMs for the readiness wait (180s on the
self-hosted docker leg) and the harness wait default for the shared waitFor,
then size each case's inline ceiling to those budgets. No assertion or
gate-hit expectation changes.

* docs(integration): correct ready-prompt budget consumer note (#15226)

Co-authored-by: Qwen-Coder <[email protected]>

* test(integration): harden skill-hook parity startup waits (#15226)

* test(integration): stop abandoned polls and pin budget invariants (#15226)

Co-authored-by: Qwen-Coder <[email protected]>

* fix(integration-tests): re-arm a reused TestRig after cleanup (#15226)

---------

Co-authored-by: qwen-code-dev-bot <[email protected]>
Co-authored-by: Qwen-Coder <[email protected]>
Co-authored-by: 易良 <[email protected]>
2026-10-24 17:21:55 +08:00
易良 0b8af17b04 fix(ci): file new main CI failure signatures as their own issues (#15405)
* fix(ci): file new main CI failure signatures as their own issues

The aggregate comment stream hid new regressions: every failure, including
never-before-seen ones, landed as a comment on a month-old issue whose title
still named the first recorded failure.

A run that names its failing tests now files or reuses a per-signature issue,
deduped by the test markers embedded in the body; only a run without any test
identity shares the workflow's aggregate issue, whose title is refreshed with
the latest occurrence date on every record.

Resolves #15398

* fix(ci): close the aggregate hijack edge cases found in review

The closed-issue lookup's body filter crashed jq on any closed
per-signature body (pipe-into-not precedence), silently filing a
duplicate aggregate; the mixed closed population is now pinned by a
test that fails without the fix. Test-marker matches are also scoped
to the owning workflow: filings embed a main-ci-failure-scope key, the
retitled body scan requires it, and accretion back-fills it so a human
retitle can never drop an issue out of the scan. A matched-body
re-read failure now aborts loudly instead of under set -e silently.

* fix(ci): harden the adoption and regression paths found in round two

A transient body read on the true aggregate no longer skips ahead to the
next admissible per-commit filing; adoption now abandons the title list
for the read-free body-marker fallback. A regressed test reopens its
resolved per-signature issue (closed bodies are scanned for the test
markers, keyed by the workflow scope) instead of filing a duplicate, and
the accretion edit re-reads the tracking issue's live body before
replacing it so a concurrent human edit is appended to, never clobbered.
Also drops two empty-array guards bash 5 makes redundant, the redundant
first-line slice on the closed lookup, and one test that pinned an input
combination the helper cannot emit.

* fix(ci): prefer exact titles, retry writes, and accrete only unowned markers

An exact machine title now certifies the aggregate without a body read,
closing the window where a transient read failure on an unmarked
candidate manufactured a duplicate aggregate. Comment/create/reopen
writes share the lookups' three-attempt retry so a single transient no
longer loses the occurrence. Marker accretion consults the sibling
trackers' bodies first: a marker another per-signature issue owns is
never pulled into the oldest match, which would shadow the sibling for
every later run.

* fix(ci): drop the truncated candidate body a failed scan leaves behind

The accretion sibling corpus reuses candidate files with -f, so the
empty file a failed gh issue view leaves by redirection read as an
already-fetched empty body, silently defeating the ownership screen and
re-admitting a sibling-owned marker onto the matched issue. The scan now
removes the truncated file, forcing a refetch whose persistent failure
suppresses marker accretion as designed. Reopen and create retries gain
the same pins the comment retry already had.

* fix(ci): screen every adoption candidate and widen marker ownership

Machine titles sort first but no longer certify adoption on their own: a
human can retitle a per-signature issue into the exact shape, so every
candidate passes the same body screen, exact kind first. Marker
accretion now also consults scoped open bodies outside the title
family, so a human-retitled tracker keeps its markers too. Documents
why a create retry that mints a same-marker duplicate still beats
losing the record.
2026-10-24 16:47:13 +08:00
易良andQwen-Coder cdd5f1e027 ci: retain raw JUnit reports for same-repo runs (#15379)
* ci: retain raw JUnit reports for same-repo runs

* ci: keep the retained-report upload advisory and pin its guards

Review follow-up on e7f6f7ae45 (qwen-code-review-bot R1-1, R1-6, R1-4).

R1-1: widening this step from fork-only to every full-profile run also widened
its blast radius. A transient artifact-service failure now fails the step and
reddens Test (ubuntu-latest, Node 22.x) on a suite whose tests all passed, and
on a push to main that red also reaches main-ci-failure-issue.yml, which files
an issue about a failure that is not a test failure. The publisher two steps
above is already advisory for exactly this reason, so this matches the sibling
rather than inventing a policy. continue-on-error: true, asserted in the
existing advisory-vs-blocking case.

R1-6: the uses: guard accepted any ref, so relaxing the pin to a mutable tag
survived green. Tightened to a 40-hex SHA, the shape
main-ci-failure-issue-workflow.test.js already uses for actions/checkout. The
trailing "# v7.0.1" comment sits outside the parsed value, so anchoring the
regex to the value is sufficient.

R1-4: the new evaluate() injected hand-built stubs, so an unmodelled context
term read as undefined and compared silently -- github.event.pull_request.draft
!= true evaluates true and every row stays green while asserting nothing about
the new term. gateRunsOn and timeoutMinutesOn in this same file already throw
on residual context terms; evaluate now does too, reusing gateRunsOn's message
spelling rather than adding a third.

Each guard was mutation-checked separately on this branch, one mutant at a
time, with the files restored byte-identically afterwards:

  uses: -> actions/upload-artifact@v7   1 failed | 43 passed (44)
    AssertionError: expected 'actions/upload-artifact@v7' to match /^actions.../
  continue-on-error: true removed       1 failed | 43 passed (44)
    AssertionError: expected undefined to be true
  loud() neutered to identity           1 failed | 43 passed (44)
    AssertionError: expected [Function] to throw an error

Clean tree: Tests 44 passed (44), rc=0. check-ci-budget.mjs rc=0
("PR-stage CI budget holds") -- no timeout-minutes or workflow change here.

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmvlhalgps3

---------

Co-authored-by: Qwen-Coder <[email protected]>
2026-10-24 14:44:31 +08:00
易良 412c7c307d ci: start the web-shell smoke lane beside Test instead of behind it (#15408)
The lane has depended on the Test job since it was created, for exactly one value: the normalized CI profile. classify_pr produces that value itself (its classifier forces an unknown one to full), so the edge buys ordering rather than trust: Test takes ~34 minutes and the smoke lane ~35, and every full-profile PR pays that queueing twice in series.

Gate on the classifier's output instead and both lanes start together. The '|| full' fallback keeps the old behaviour when the classifier emitted nothing, and the meta-test that evaluates this gate now models the term it reads.
2026-10-24 14:18:44 +08:00
0fc513daf6 test(scripts): pin newline-bearing takeover round seed bodies (#15390)
* test(scripts): pin newline-bearing takeover round seed bodies

The takeover round seed harness replayed every documented body shape
except ones carrying a newline, so a trim regression in the route step
could flip a documented outcome while the whole suite stayed green.

Two fixtures close that gap:

- a leading-newline body must still fail closed: the line-oriented sed
  strips nothing from a blank first line and the surrounding command
  substitution strips only TRAILING newlines, so BODY_TRIMMED keeps the
  leading newline, the from-N regex still matches, and BASH_REMATCH[1]
  then misses the TAKEOVER_COMMAND comparison.
- a trailing-newline body must still engage: that newline is removed by
  the command substitution rather than by the sed, a different mechanism
  from the trailing-space case already pinned next to it.

Test-only. Production behavior is unchanged.

Refs #9644

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-issue-patrol/jmvlcajziij

* test(scripts): pin interior-newline takeover body, stabilize citations

Review follow-up on a4d2661fe9 (qwen-code-review-bot R1-1 and R1-2).

R1-1: the fail-closed loop replayed no body with an INTERIOR newline, so a
first-line-only trim at the BODY_TRIMMED sed would survive the whole suite
while flipping '@qwen-code /takeover from 4\nthanks' from fail-closed '|' to
engaging 'add|4'. Measured on this branch: that mutant keeps the suite green
(325 passed, rc=0) before this commit, and turns the harness red
(AssertionError: expected 'add|4' to be '|') after it.

Skipped the reviewer's '\n\n@qwen-code /takeover from 4' variant: under the
same mutant head -1 yields an empty first line, so it still returns '|' and
kills nothing. The existing single-'\n' pin already covers leading newlines,
and covers them more strongly, so the variant adds no discrimination.

R1-2: replaced the eight bare absolute line citations (qwen-autofix.yml:419,
:427, :432, :245 and qwen-autofix-round-seed.md:123, :120-122) with the
file's established stable af-NNN anchors. af-083, af-007 and af-004 each
resolve to exactly one <a id=...> target in qwen-autofix.md, and the workflow
already carries those same pointers beside the cited statements. Bare line
numbers rot silently: the cited sed sat at eight distinct lines in the eight
weeks before this PR, and no assertion in this suite reads the comment text.

Both comment blocks are also trimmed to the load-bearing why, per the
author's own self-review at a4d2661f. Net -5 comment lines.

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmvlhalgps3

---------

Co-authored-by: yiliang114 <[email protected]>
Co-authored-by: Qwen-Coder <[email protected]>
2026-10-24 13:49:20 +08:00
易良andQwen-Coder d008a925ec ci: reduce redundant TUI parity runs and build scope (#15383)
* ci: avoid redundant TUI parity work and build only CLI dependencies

* ci: record TUI workflow size after scheduling improvements

* ci: budget and lint the TUI impact-check job

The new `changes` job grew tui-parity.yml past its recorded PR-stage
budget (2 jobs -> 3), failing the budget gate before lint even ran.
Record the 3-job budget with a fixed 5-minute timeout on the gatekeeper
job, and quote the four bare scalars the job added so yamllint passes
once the lane reaches it.

* test(ci): pin the TUI parity classifier's dispatch, rename and trigger set

Address the three review Suggestions on scripts/tests/e2e-workflow.test.js:

- Build the workflow_dispatch fixture payload per event so the dispatch case
  models the real shape (no pull_request key). The suite now fails if the
  context.payload.pull_request read is ever hoisted above the eventName guard.
- Add a case pinning the negative arm of the rename clause: a
  previous_filename that is itself inside the unrelated subtrees must still
  skip, so weakening that arm to a presence check no longer passes.
- Replace arrayContaining with the exact 15-entry trigger set, so dropping a
  path is as visible as adding one. The no-negation assertion is kept.

Each fix is mutation-verified individually against the YAML-embedded
classifier; the workflow file itself is unchanged.

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmvlnq2qysa

---------

Co-authored-by: Qwen-Coder <[email protected]>
2026-10-24 12:44:00 +08:00
易良 1f7ed6b50a perf(ci): scope PR lint and reuse static build outputs (#15381)
* perf(ci): scope PR lint and reuse static build outputs

* fix(lint): keep incremental selection a superset of the full lane

- Select .mts/.cts: flat-config --ext is additive to the config's own
  files scope, so lint:ci checks them; the selector dropped them and a PR
  touching only such a file reported green without opening it.
- Stop escalating the whole-repository ShellCheck for terminal-bench
  paths the lane itself greps out.
- Report every failing Prettier directory in one run, since Prettier runs
  per directory with basename targets and the first failure aborted the
  rest.
- Pin RUNNER_TEMP/GITHUB_* in the subprocess fixture so its setup cannot
  rmSync the ambient runner linter temp directory.

* fix(ci): fetch incremental lint history after the shallow refetches

Both 'Check the API contract version advances' and 'Report test growth'
refetch shallow history below the old position; a depth-1 fetch of the
base ref grafts the commit LINT_BASE_SHA names, so merge-base fails and
every contract-document PR silently ran the full scan. Pin the binding
and the step order, correct the freshness header that still claimed the
lanes run repo-wide, and record the per-file selection backstop.

* chore(ci): record the ci.yml size ratchet bump

Lint & Static failed on the workflow-size ratchet: ci.yml is 151690 bytes
against a recorded 147136 with a 4096-byte allowance. The overage is this
PR's opt-in step plus ci.yml growth that landed on main without a same-PR
bump, which is the drift the ratchet exists to surface. The comment above
the fetch step was cut to four lines with the mechanism moved into the
design docs, and the recorded size now matches the file.
2026-10-24 12:42:37 +08:00
Shaojin Wen 7f91bc2f24 feat(verify-pr): configure the assets host and branch once (#15377)
* feat(verify-pr): configure the assets host and branch once

A publish round still had to confirm where the images go, even though the
branch already resolved from a flag, a variable, then the repository's
assets/pr<n>-validation convention. The host is the last coordinate that had
to be repeated per round.

settings.json gains verifyPr.assetsRepo and verifyPr.assetsBranch. At
startup they fill QWEN_VERIFY_ASSETS_REPO and QWEN_VERIFY_ASSETS_BRANCH when
those are unset, so the skill keeps reading the variables it documents and a
one-off export still wins.

These values choose where a maintainer's evidence is published, so a cloned
repository must not be able to set them. Three paths are closed: verifyPr is a
workspace-restricted root (the merge strips it, the warnings channel reports
it ignored, and the daemon refuses a workspace write, including a nested
verifyPr.assetsRepo), and both variables are excluded from what a project
.env or settings.env may supply — the environment loader applies those before
the settings bridge, so without the exclusion a repository could set the
variable itself and the configured value would never win.

The skill also states that a published filename is spent: raw.githubusercontent
serves a URL from cache, so a republished image needs a new name and the body
and comments must move to it.

* fix(verify-pr): drop the unreachable guard and rewrap the settings table

Review found two mechanical blockers.

Prettier rejected the settings table: the two new rows were pasted with
padding that did not match the column widths, so Lint & Static failed before
"Generate settings schema" ran and the hand-edited schema was never checked.
Both rows are rewrapped against the table's own alignment; every other row is
byte-identical.

The daemon test asserted workspace_restricted_setting for verifyPr.assetsRepo,
but the route answers disallowed_key: the allowlist check runs first, and
verifyPr is not offered to workspace writes at all. That also made the new
root-segment branch unreachable for every restricted root today, so the guard
and its test are dropped. The merge strip and the env exclusion are what
protect the value.

The new shared-env-keys test also no longer separates the TLS trust-anchor
comment from the test it introduces.

* fix(verify-pr): warn on a rejected settings.env entry and name the branch call

Review R1-1: the hardcoded exclusion is key-based, so it also drops a
User-scope settings.env entry — a channel that worked before this PR, silently,
because reportRejectedSettingsEnv only reports loader-class keys. The rule
stays scope-blind: the merged env map cannot tell a workspace entry from an
operator one, and only the operator may choose a publishing target. It is no
longer silent: the rejection names verifyPr.* and the launch environment, and
an environment.test.ts case pins both the unset variable and the warning.

Review R1-2: the skill said the branch is "created when absent" while its only
upload was a contents PUT, which answers 422 Branch not found for a ref that
does not exist. The paragraph now names the GET ref / POST git/refs step (404
only) before the first upload, and the scripts assertion pins it.

The design doc and the PR description record the settings.env restriction, so
"breaking changes: none" is no longer claimed.

* test(cli): isolate the publishing-coordinate variables in environment tests

The new warning test asserts the variable stays unset, so the two names belong in TRACKED_ENV rather than depending on the runner's environment.

* docs(verify-pr): name the default-branch lookup the branch creation needs

Review R2-3: the creation step required "the default branch's head sha"
without saying where either comes from, and `default_branch` appeared nowhere
in the file. An executor would guess the PR checkout's origin/main, whose sha
need not exist in the assets repository — a fork behind upstream then answers
422 Object does not exist and every later upload fails after the round is
spent.

The paragraph now names both lookups (`.default_branch`, then `.object.sha`
of that repository) and the empty-repository 404, matching the in-repo
publisher. The scripts assertion pins `.object.sha` so the lookup cannot be
dropped again.

* fix(cli): fold case in the rejected-coordinate warning and read back from the assets repo

Review R2-1: the diagnostic looked the key up with its canonical spelling
while the gate folds case, so `qwen_verify_assets_branch` was dropped and never
reported — the silent loss this block exists to prevent. The lookup now folds
case and names the spelling that was actually written; the environment test
runs both spellings, and the lowercase case reds before this change.

Review R2-2: the post-upload read-back addressed `<owner>/<repo>`, which this
file uses for the PR repository, while the upload went to `<assets-repo>`. With
a fork as the image host the confirmation queried the wrong repository: a 404
over a correctly published file, or another blob's size and sha. It now reads
back from the repository it wrote to, and the scripts assertion pins the
placeholder.

* fix(cli): make the coordinate bridge refresh on reload and tighten its typing

Four of the deferred review items.

The bridge was add-only: a long-lived process kept the value it had written
even after the setting changed or disappeared, so the round published to the
old host. Writes are now tracked per environment object — a value this
function wrote is refreshed on change and removed when the settings drop it,
while an exported value is never touched. Three tests pin the three cases.

Both leaves used a bare `default: undefined`, so Settings['verifyPr'] inferred
as undefined; they now use the `as string | undefined` form the neighbouring
optional strings use.

The hardcoded project-exclusion list derives its two coordinate names from
VERIFY_PR_COORDINATE_ENV, so a third coordinate cannot be gated nowhere.

The workspace-restricted root membership is pinned by a test: deleting that
entry would let a cloned repository choose the publishing host, and nothing
noticed before.
2026-10-24 11:36:00 +08:00
Shaojin Wen 07835d248f fix(ci): pin and cache the standalone runtime archives (#15159)
* fix(ci): pin and cache the standalone runtime archives

The standalone runtime regression downloaded Node 24.19.0 and Bun 1.3.14
on every run, after first fetching Node's checksum list and Bun's npm
metadata, with no retry. That cost minutes per run on the shared runners
and turned an npm 502 into a red required check on an unrelated change.

Pin the published digests for the four supported platforms so archives
are verified without metadata requests, keep verified archives in a
cache directory when one is configured, and retry downloads. The
required Linux unit-test job points the cache at a host-wide directory
on persistent self-hosted runners.

* fix(ci): keep a verified runtime download when the cache is unusable

If the cache directory, or a directory on its path, cannot be searched,
writing the archive fails as intended, but removing the temporary file
then throws too (EACCES, or ENOTDIR when the path runs through a file):
`force` only ignores a missing file. The verified archive already in
memory was discarded, the regression never started, and the script
tests chained after it were skipped.

Make that cleanup best-effort like the rest of the cache write. The
download-and-cache logic moves unchanged into scripts/lib so it can be
tested; the tests cover cache reuse, replacing a copy that fails
verification, a cache path through a file, and an unsearchable cache
directory (skipped as root, where permissions do not apply).

* fix(scripts): retry unverified runtime downloads and sweep the host cache

Verify each download attempt, so a truncated or stale 200 body is retried
like a failed request, and name both digests when the pin never matches.
Retry logs now include the undici error cause, and cache hits and writes
each log a line. The CI step reports the cache path and size.

Entries no run has used for a week (previous pins, partial files left by
a killed run) are removed after each successful run; a run refreshes the
mtime of the archive it uses, so revisions still in flight keep theirs.

Tests cover retries, verification per attempt, the uncached path, the
sweep, the CI wiring, and gate the permission case on the shared
permission-bits probe so it also runs on root lanes with DAC caps dropped.

* fix(ci): sweep the runtime cache only after a run fetched both archives

The Node fetch swept every other entry unused for a week, so after a
quiet week it removed the Bun archive the same run was about to reuse
and Bun was downloaded again. Fetches now only mark their archive as
used; ci() sweeps once after both fetches, sparing the archives it used.
The sweep skips non-files and keeps going past an entry it cannot
remove, and a cached copy that fails verification is logged.

Also:
- export the same host-wide cache to release.yml's quality_scripts,
  which runs the same regression on a persistent host
- move the pinned versions and digests to
  scripts/lib/standalone-runtime-pins.js and check their shape
- pin the wiring itself: the export step's gate, its GITHUB_ENV write
  and its position before the consuming step, in both workflows
- cover the write-then-rename into the cache
2026-10-24 01:26:23 +08:00
jinyeandQwen-Coder a147c39712 feat(managed-agent): Add a shared Harness pool for Kubernetes (#15255)
Route sessions to durable instance and boot placements with fenced writer grants, resource-idle ownership release, EndpointSlice discovery, and private mTLS deployment templates.

Co-authored-by: Qwen-Coder <[email protected]>
2026-10-23 17:22:19 +00:00
易良 2b05c8bd99 fix(ci): route web shell smoke to ARM64 independently (#15364)
* fix(ci): route web shell smoke to ARM64 independently

* test(ci): pin the smoke lane's ARM64 routing in the meta-tests

The runs-on change left two scripts/tests assertions pinning the old
routing, so the Linux Test check and the nightly macOS/Windows lanes
would go red once dependency installation succeeded (AGENTS.md
guideline #3).

- ci-platform-lanes: evaluate the real runs-on expression and pin
  self-hosted -> ARM64 plus the hosted and missing-output fallbacks,
  instead of the old equality with the shared test lane.
- no-ak-integration-ci: replace the raw-YAML literal pin with a check
  that the lane still derives its runner from the classifier; the
  architecture override is pinned in ci-platform-lanes.
- ci.yml: restore the #11250 pool history the routing change deleted,
  marked as x64-specific rather than a verdict on ARM64.

* test: tolerate slow durable I/O in CI synchronization checks
2026-10-23 16:02:17 +00:00
易良andQwen-Coder 7c296dbe3c fix(ci): stabilize TUI attachment wait and allow full acceptance run (#15372)
* fix(ci): stabilize TUI attachment wait and allow full acceptance run

* fix(ci): record the tui-parity budget at its new 75-minute total

The parity job moved from 30 to 45 minutes, so the two jobs in the workflow
now declare 45 + 30 = 75. check-ci-budget.mjs treats a raised total as a
deliberate ratchet and refuses the ledger entry, so Lint & Static failed on
this PR's own change. Update the line it names; the workflow and the guard
test are unchanged.

Co-authored-by: Qwen-Coder <[email protected]>

---------

Co-authored-by: Qwen-Coder <[email protected]>
2026-10-23 23:15:19 +08:00
ac2c7ac93a fix(ci): annotate the temp short-alias guard's failing branches (#15366)
Both failing branches of the `Verify temp paths carry no short alias` step
emitted a bare console.error, so a real 8.3-alias regression reached the
check UI as only "Process completed with exit code 1" with no annotation
attached to the run. Prefix each message with '::error::', matching the
hosted-process-suite step in this same workflow and
configure-windows-runner/action.yml. The casing-only branch keeps its
deliberate '::warning::', and process.exitCode = 1 is unchanged.


Patrol-Run: qwen-issue-patrol/jmvkv59rei6

Co-authored-by: yiliang114 <[email protected]>
Co-authored-by: Qwen-Coder <[email protected]>
2026-10-23 22:54:16 +08:00
易良 6094ba8270 fix(release): skip cua-sdk publish dry-run when the version is already on npm (#15355)
The verify-sdk-package job's publish dry-run queries the live registry, so
every dispatch after a release fails with the npm 11 collision error
'You cannot publish over the previously published versions' until the next
version bump (observed on #12442's dry runs 39809916847 and 39921492569;
main's last green dispatch, 39555655699, predates the 0.26.0 publication
by three hours). Treat only that exact registry-collision message as a
skip with a notice; every other failure (auth, network, packaging) still
fails, and the real publish jobs stay untouched. Adds matcher unit tests,
including the bare-exit mutation that must not be masked.
2026-10-23 21:35:58 +08:00
Shaojin Wen 3af0cf174c docs(verify-pr): add a --publish shorthand for maintainer rounds (#15357)
* docs(verify-pr): add a --publish shorthand for maintainer rounds

A maintainer round that publishes its report had to restate the same five
clauses (English body, collapsed Chinese, screenshots, assets branch, merge
reference) every time to unlock the skill's opt-in publish path. Restating
drifts: a round that omitted one clause shipped a thinner report.

--publish now resolves the whole deliverable on its own and names the branch
order --assets-branch, $QWEN_VERIFY_ASSETS_BRANCH, assets/pr<n>-validation --
so a stable image host is configured once. Only coordinates default; posting
consent stays per-invocation, and the repo rule still forbids an origin
fallback. The local path keeps the guard and read-back, which the workflow
publisher does not cover.

* docs(verify-pr): keep the deliverable list in one place

Review pointed out that the new contract block restated the report format
already owned by the local publish rule, so a single list existed twice — the
drift this change set out to remove.

The block now names the four deliverables and points at the rule for their
shape; the rule states the shape once. The consent split, the branch order and
the untouched repo rule are unchanged.
2026-10-23 12:47:48 +00:00
jinye a98615bedb feat(managed-agent): Enable unified Shell session lifecycle (#15330) 2026-10-23 11:05:46 +00:00
Shaojin Wen 519bcdd596 fix(ci): install linters on linux/arm64 runners (#15350)
The Linux lanes now route to the ARM64 self-hosted fleet, but the linter
bootstrap only mapped linux/x64 (plus both macOS arches), so `--setup`
threw "Unsupported platform/architecture: linux/arm64" and every real lint
step after it was skipped — the lane was red having checked nothing.

Pin the ARM64 builds the two linter steps already know how to unpack:
actionlint 1.7.12 linux_arm64 and shellcheck 0.11.0 linux.aarch64, with
digests recomputed from the exact release URLs the installer builds.
2026-10-23 17:49:15 +08:00
Shaojin Wen 6a50ae80e3 fix(ci): refuse a partial jobs page list before reporting (#15174)
* fix(ci): refuse a partial jobs page list before reporting

`--paginate` prints one document per page and the step merges them with
`jq -s`, so a page 2 failure leaves a list holding only page 1. The exit
status cannot tell that apart from a complete read, and the partial file
reads exactly like a whole run to the failed-job projections and to the
infra classifier — which counts only the jobs present, turning a regression
parked on the missing page into a rerun instead of an issue.

Stage the merge in a temp file and promote it only when the merged job
count matches the payload's own total_count; otherwise report without the
job list. The receipt keeps the guard independent of the shell's pipefail
setting, which the meta-test now exercises by spawning the step without it.

* fix(ci): require the job-list receipt instead of skipping it

`$total == null or …` treated a response that carries no `total_count` as
complete, so a populated first page followed by an API error published its
partial list — the inverse of the contract the step's own comment states,
reproduced with jq: the predicate exits 0 and emits page 1 alone.

Make the receipt part of the pass condition: a page set is promoted only
when it declares a total and the merged jobs match it. No total means no
proof of completeness, so it takes the same fallback as a failed fetch —
empty list, staging file removed, warning. The new negative case feeds a
populated page without `total_count` and asserts that fallback.

* fix(ci): say when the job list could not be read in full

The reporter degraded to an empty list with only an annotation on its own
job, so the PR comment and the issue looked exactly like a run with no
identifiable failure — the readers who need the signal never saw it. Carry
a jobs_complete output onto both bodies: when it is false they say the
report may name fewer failing jobs than the run had, and the issue body
guards the sentence so a recurrence does not stack a second copy.

Also widen the meta-test pin back over the fetch's producer, so --paginate
and per_page=100 stay pinned: the earlier rewrite started the span at the
merge and left both unpinned while the comment still claimed they rode it.

* test(ci): name the receipt case for what it covers

The case now rejects both a truncated page set and a response carrying no
total_count, so a name that mentions only "stops short of total_count"
understates it. The flag's comment said "both reports" where the two
readers are the PR comment and the issue body.

* fix(ci): let a certified run clear the short-list note

The note added by the previous commit was append-only: once one degraded
run wrote it into a tracking issue, every later replan preserved it --
including runs whose job list was read in full and receipt-certified -- so
a rebuilt failure block sat under a permanent claim that the list might be
short, and the substring guard then refused a later degraded run a fresh
note of its own.

Strip the exact sentence before deciding whether to re-add it, so a
certified run clears a stale copy and a degraded run speaks for itself.

Pin the producer-to-consumer wiring (step id and both env mirrors), add the
plan path's negative control, and cover gh exiting 0 with a short list.
2026-10-23 16:01:39 +08:00
qwen-code-dev-botandqwen-code-dev-bot 416bed0e12 fix(ci): gate the Windows Hosted suite on a successful install (#15287) (#15290)
Co-authored-by: qwen-code-dev-bot <[email protected]>
2026-10-23 13:34:42 +08:00
易良andQwen-Coder 57f88a93e5 fix(ci): reuse open workflow failure issues (#15256)
* fix(ci): reuse open workflow failure issues

* fix(ci): single-quote the concurrency queue value

yamllint's quoted-strings rule (quote-type: single, required: true) rejects
the bare `max` scalar, which is what failed the Lint & Static lane at
.github/workflows/main-ci-failure-issue.yml:342:14.

The value is unchanged after parsing: `queue: max` and `queue: 'max'` both
yield the string "max", so the workflow semantics and the parsed-document
assertions in scripts/tests/main-ci-failure-issue-workflow.test.js are
unaffected.

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmvjvf9h5qa

* fix(ci): publish the tracking issue before the cosmetic label edit

A non-zero exit from the decorative `--remove-label` edit aborted the
writer step under the `set -euo pipefail` this branch adds, losing both
the recurrence comment and `issue_url`. report_pr is `always()`-gated and
reads `issue_url` unconditionally, so it posted the merged PR's failure
summary with the [Tracking issue] link silently omitted. Restore the
ordering the deleted comment documented: url and comment first, then the
retirement.

Also drop the `issues: read` grant the analyze job no longer uses now
that the plan step is gone, and pin the paginated lookup's page merge,
which no fixture exercised because every one fed a single JSON document.

Co-authored-by: Qwen-Coder <[email protected]>
Patrol-Run: qwen-pr-closeout/jmvk8a84dqp

* fix(ci): preserve provenance and lifecycle of failure aggregates

---------

Co-authored-by: Qwen-Coder <[email protected]>
2026-10-23 13:33:49 +08:00
Shaojin Wen 801826b524 fix(managed-agent): refuse ; comments in the Harness credentials file (#15236)
* fix(managed-agent): refuse `;` comments in the Harness credentials file

systemd skips a line starting with `;` as a comment, but a shell refuses
it and stops reading the file at that line. With such a line above the
two keys, the control plane read both credentials while a Harness
started through `set -a; . harness.env` got neither. The parser now
refuses the line wherever it falls, naming the file and line, so the two
readers agree again.

The design doc, READMEs and template now say to start comments with `#`,
and the design doc names the remaining shell-only stop: a line in
another key that a shell cannot parse, such as an unquoted `(`.

* test(managed-agent): pin the `;` refusal above the keys and correct the shell-stop note

Pin the reported shape: a `;` line above both credential keys, and one
between them, are refused at their own line without echoing the token.
The bootstrap test now also checks that the generated harness.env has
no `;` line, as the template test already does.

The design doc said a shell stop at an unparseable line always fails
the harness row's live probe. bash keeps the assignments above that
line, and the probe sends only the token, so --check notices only a
lost token. The doc now says so, and names the `KEY = value` shape a
shell runs as a command.
2026-10-23 04:14:43 +00:00
ChiGaoandgary.gq 32b4234b84 feat(cli): ship private Bun and preserve interpreter boundaries (#14959)
* fix(cli): restore bounded OpenTUI dialogs and add migration gates

* fix(cli): preserve runtime boundaries during standalone updates

Preserve Node/Bun archive flavor and validate actual CLI loading, package
identity, version and prepared installation identity before activation.
Keep Node npm transport and restrict Bun registry lookup to trusted config.

Integrates chiga0's update stack through ce67edaba5,
with isolated fixtures and real Node/Bun runtime regression coverage.

Co-authored-by: gary.gq <[email protected]>

* fix(cli): preserve OpenTUI input and attachment ownership

* test(cli): bound cancellation test waits and cleanup

* feat(cli): ship private Bun for opt-in npm OpenTUI sessions

* feat(cli): align OpenTUI status lines with Ink

* fix(cli): align OpenTUI editor and cancellation transactions

* fix(tui): harden migration cleanup and evidence after review

* test(tui): fail acceptance on unhandled errors

* fix(cli): validate standalone launchers and registry settings

* docs(cli): clarify consolidated OpenTUI delivery status

* test(cli): isolate system settings in TUI parity fixtures

* test(cli): isolate compile cache in standalone runtime checks

* test(cli): reduce standalone runtime fixture compression cost

* fix(cli): settle OpenTUI cancellation when replay resets a session

* feat(cli): align OpenTUI Vim, history and session output

Reuse the shared editing and history contracts, preserve cancellation ownership, and connect accepted interactive turns to the existing output bridge.

* style(cli): format merged OpenTUI test callbacks

* test(core): control terminal conversion in PTY parking regression

* test(cli): preserve visible input across session rotation

* test(cli): cover shell recall provenance and streaming search selection

* test(cli): await cancellation before releasing held response

* fix(cli): preserve imported history ownership and active search

* docs(cli): synchronize consolidated OpenTUI validation status

* test(cli): await AppContainer configuration cleanup

* test(cli): mock Vim clipboard imports before module loading

* test(cli): check standalone asset roots for npm subpaths

* test(cli): share clipboard mocks across module export views

* test(cli): verify finalized MOD parts and shared JSON projection

* fix(cli): reuse Ink editing history for OpenTUI Unicode input

* test(cli): keep native Vim input callbacks void

* test(cli): preserve Escape boundaries in Unicode Vim fixtures

* test(cli): read the current composer across Vim remounts

* test(cli): align Unicode deletion cursor with Ink oracle

* fix(cli): preserve completion and escape precedence and validate status colors

* fix(cli): use boundary selection for the OpenTUI composer

* fix(cli): preserve attachment navigation with one completion

* test(cli): preserve Shift in the native redo key sequence

* fix(cli): display session titles in the OpenTUI composer border

* fix(cli): discard generated command work after cancellation

* test(cli): align Unicode unit cursor with Ink oracle

* test(cli): model native selection key delegation

* fix(cli): preserve Vim Escape ownership across listeners

* fix(cli): preserve shared Vim command messages in OpenTUI

* test(cli): observe rendered Vim mode during parity checks

* docs(cli): record integrated OpenTUI validation checkpoint

* fix(ci): account for dedicated TUI parity coverage

* fix(cli): preserve collapsed paste payloads across Vim undo

* docs(cli): refresh OpenTUI distribution acceptance status

---------

Co-authored-by: gary.gq <[email protected]>
2026-10-23 10:27:53 +08:00
jinyeandQwen-Coder f0a47611ab refactor(managed-agent): Remove pre-release compatibility paths (#15263)
* refactor(managed-agent): Simplify first-release contracts

Remove unreleased compatibility paths across the managed runtime, Java control plane and WebShell. Keep one fresh V1 baseline and document that schema versions stay at V1 until the first formal release.

Co-authored-by: Qwen-Coder <[email protected]>

* test(managed-agent): Align remaining tool fixture with current contract

Restore schema rationale comments while retaining the V1 baseline.

Co-authored-by: Qwen-Coder <[email protected]>

* fix(managed-agent): Align CSI proof with current checkpoint encoding

Require the three current nullable checkpoint fields in the native proof, keep malformed and missing fields rejected, and synchronize retained fixture bytes and digest chains. Update tests that still expected retired pre-release state and replay compatibility.

Co-authored-by: Qwen-Coder <[email protected]>

---------

Co-authored-by: Qwen-Coder <[email protected]>
2026-10-23 02:09:21 +00:00
ytahdnand钉萁 f18decc7cc fix(web-shell): preserve composer draft attachments across views (#15025)
* fix(web-shell): preserve composer draft attachments across views

* fix(web-shell): preserve draft edits during restore and acceptance

* test: stabilize durable commit and standalone runtime checks

* revert: drop unrelated core extension test change

---------

Co-authored-by: 钉萁 <[email protected]>
2026-10-23 10:06:10 +08:00
jinyeandQwen-Coder c61044fae4 feat(managed-agent): Start daemon and Managed locally with one command (#14928)
* feat(managed-agent): add local serve and lightweight runtime packages

Co-authored-by: Qwen-Coder <[email protected]>

* feat(managed-agent): download local server runtime on first use

Require local Java 21, install the exact-version service JAR atomically from OSS or GitHub, and reuse verified runtime caches offline. Add protected signed Central publication and identical release distribution without bundling Java in the CLI.

Co-authored-by: Qwen-Coder <[email protected]>

* fix(ci): register managed runtime workflow size

Record the new release workflow in the repository size baseline so the static CI gate can track it.

Co-authored-by: Qwen-Coder <[email protected]>

* feat(managed-agent): Share the local daemon and Managed entry

Serve daemon APIs and the signed Managed proxy from one loopback listener. Keep workspace ownership explicit, enable authorized local directory import and preserve the daemon trust boundary.

Co-authored-by: Qwen-Coder <[email protected]>

* fix(cli): expose configured models in local Managed tasks

Co-authored-by: Qwen-Coder <[email protected]>

* test(web-shell): Cover Managed and local deep-link restoration

Co-authored-by: Qwen-Coder <[email protected]>

* test(managed-agent): Align local database expectation with main schema

Co-authored-by: Qwen-Coder <[email protected]>

* fix(managed): Keep local model and approval choices independent

Use native initial model selection for local model presets and persist it with the selected approval mode before admitting the first Turn. Preserve custom Agent definition policy pins and creation replay semantics.

Co-authored-by: Qwen-Coder <[email protected]>

---------

Co-authored-by: Qwen-Coder <[email protected]>
2026-10-22 16:25:18 +00:00
Shaojin Wen 2050db87ef test(managed-agent): replace the Runtime MCP connection mid-stream (FG12e) (#15198)
* test(managed-agent): replace the Runtime MCP connection mid-stream (FG12e)

FG12f's replacement case commits a new AgentDefinition revision while the
running Session stays pinned, so no Runtime MCP connection was ever replaced
under a stream gap; #14447 and #12380 still listed that boundary as open.

The new HostedMcpStreamGapIT cell holds a model-driven MCP tool call, cuts a
public and a WebShell observer, and sends the Harness-private configure
command for revision 2 under the attachment Spring holds for its own Session
(the Harness, not the Broker, mints that client id; the FG13 gates read it the
same way). It pins that the Runtime opens revision 2 beside revision 1 and
retires revision 1 only after its held call drains, that both streams resume
with no gap and no duplicate, that the held call is answered once by the
process it started on, and that the next call runs on the replacement.

awaitCompleted now stops at any terminal Turn state, so a failed Turn reddens
at once instead of after the minute-long wait.

Bundle witnesses: closing a retiring sibling with a pending call reddens at
the retiring assertion; keeping the first catalog after a replacement fails
the Turn. Measured 12.9-13.8 s in-class on JDK 21 + MySQL 8.4.6, budgeted at
28 s: healthy 10651 s, fork 11251 s, Verify stays 198 minutes.

* test(managed-agent): share the FG12e configuration read and note #15119

- Read the cell's mcp_configuration records through
  HostedGateTestSupport.extensionRecords, as the four sibling MCP letters
  do. The configRevision sort stays, because that helper orders by
  record_id.
- Rebase the design doc's budget on the FG11d queue-one cell: fork
  11264 s, with 16 s left in the 198-minute Verify step.
- Since #15119, Spring sends the Session MCP management route, which
  refuses while a Turn is active. Say so instead of claiming that
  HostedHarnessClient has no MCP route.
2026-10-22 15:46:28 +00:00
ChiGao a1b2d8596f feat(cli): align OpenTUI Vim, history and live output with Ink (#15067)
* fix(cli): restore bounded OpenTUI dialogs and add migration gates

* fix(cli): preserve OpenTUI input and attachment ownership

* feat(cli): align OpenTUI status lines with Ink

* fix(cli): align OpenTUI editor and cancellation transactions

* fix(tui): harden migration cleanup and evidence after review

* test(tui): fail acceptance on unhandled errors

* docs(cli): clarify consolidated OpenTUI delivery status

* test(cli): isolate system settings in TUI parity fixtures

* fix(cli): settle OpenTUI cancellation when replay resets a session

* feat(cli): align OpenTUI Vim, history and session output

Reuse the shared editing and history contracts, preserve cancellation ownership, and connect accepted interactive turns to the existing output bridge.

* style(cli): format merged OpenTUI test callbacks

* test(cli): preserve visible input across session rotation

* test(cli): cover shell recall provenance and streaming search selection

* test(cli): await cancellation before releasing held response

* fix(cli): preserve imported history ownership and active search

* docs(cli): synchronize consolidated OpenTUI validation status

* test(cli): await AppContainer configuration cleanup

* test(cli): mock Vim clipboard imports before module loading

* test(cli): share clipboard mocks across module export views

* test(cli): verify finalized MOD parts and shared JSON projection

* fix(cli): reuse Ink editing history for OpenTUI Unicode input

* test(cli): keep native Vim input callbacks void

* test(cli): preserve Escape boundaries in Unicode Vim fixtures

* test(cli): read the current composer across Vim remounts

* test(cli): align Unicode deletion cursor with Ink oracle

* fix(cli): preserve completion and escape precedence and validate status colors

* fix(cli): use boundary selection for the OpenTUI composer

* fix(cli): preserve attachment navigation with one completion

* test(cli): preserve Shift in the native redo key sequence

* fix(cli): display session titles in the OpenTUI composer border

* fix(cli): discard generated command work after cancellation

* test(cli): align Unicode unit cursor with Ink oracle

* test(cli): model native selection key delegation

* fix(cli): preserve Vim Escape ownership across listeners

* fix(cli): preserve shared Vim command messages in OpenTUI

* test(cli): observe rendered Vim mode during parity checks

* docs(cli): record integrated OpenTUI validation checkpoint

* fix(ci): account for dedicated TUI parity coverage

* fix(cli): preserve collapsed paste payloads across Vim undo
2026-10-22 14:52:40 +00:00
qqqysandqqqys 1477a3f8a2 fix(mods): exclude native waits from root execution budget (#14986)
* fix(mods): exclude native waits from root execution budget

* fix(cli): preserve cancelled tool results in Ink history

* fix(cli): keep cancelled tool finalization in its owning session

---------

Co-authored-by: qqqys <[email protected]>
2026-10-22 22:42:10 +08:00