Commit graph

1098 commits

Author SHA1 Message Date
易良
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 <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
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 ':⚠️:', and process.exitCode = 1 is unchanged.


Patrol-Run: qwen-issue-patrol/jmvkv59rei6

Co-authored-by: yiliang114 <yiliang114@users.noreply.github.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
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-bot
416bed0e12
fix(ci): gate the Windows Hosted suite on a successful install (#15287) (#15290)
Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
2026-10-23 13:34:42 +08:00
易良
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 <qwen-coder@alibabacloud.com>
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 <qwen-coder@alibabacloud.com>
Patrol-Run: qwen-pr-closeout/jmvk8a84dqp

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

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
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
ChiGao
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 <gary.gq@alibaba-inc.com>

* 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 <gary.gq@alibaba-inc.com>
2026-10-23 10:27:53 +08:00
jinye
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 <qwen-coder@alibabacloud.com>

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

Restore schema rationale comments while retaining the V1 baseline.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* 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 <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-10-23 02:09:21 +00:00
ytahdn
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: 钉萁 <dingqi.jww@alibaba-inc.com>
2026-10-23 10:06:10 +08:00
jinye
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 <qwen-coder@alibabacloud.com>

* 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 <qwen-coder@alibabacloud.com>

* 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 <qwen-coder@alibabacloud.com>

* 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 <qwen-coder@alibabacloud.com>

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

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

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

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

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

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* 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 <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
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)
Some checks are pending
Qwen Code CI / Classify PR (push) Waiting to run
Qwen Code CI / Test (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Lint & Static (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / web-shell E2E Smoke (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (macos-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (windows-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Integration Tests (no-AK, No Sandbox) (push) Blocked by required conditions
Qwen Code CI / Integration Tests (CLI, No Sandbox) (push) Blocked by required conditions
E2E Tests / Build for E2E (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker - shard 1/1 (push) Blocked by required conditions
E2E Tests / E2E Test (Linux) - sandbox:none - shard 1/1 (push) Blocked by required conditions
E2E Tests / E2E Test - macOS - shard 1/2 (push) Blocked by required conditions
E2E Tests / E2E Test - macOS - shard 2/2 (push) Blocked by required conditions
E2E Tests / E2E Interactive - OpenTUI renderer (bun) (push) Blocked by required conditions
E2E Tests / channel-plugin E2E (nightly) (push) Blocked by required conditions
E2E Tests / cron-interactive E2E (nightly) (push) Blocked by required conditions
E2E Tests / web-shell Browser Regression (push) Waiting to run
Managed Agent gate / Select the Managed Agent tier (push) Waiting to run
Managed Agent gate / SDK Java () (push) Blocked by required conditions
Managed Agent gate / Managed Agent gate (push) Blocked by required conditions
SDK Java Contract Open PRs / Re-check open PRs against main (push) Waiting to run
Verify Landlock helper / Native Linux CLI boundary (push) Waiting to run
Verify Landlock helper / Native Windows settings and streams (push) Waiting to run
Verify Landlock helper / arm64 (push) Waiting to run
Verify Landlock helper / x64 (push) Waiting to run
verify Maven repo producer / Save verify Maven repo (push) Waiting to run
* 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
qqqys
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 <266654365+qqqys@users.noreply.github.com>
2026-10-22 22:42:10 +08:00
Shaojin Wen
6c8d1e0f70
test(managed-agent): pin the queue_one reachability (FG11d) (#15187)
* test(managed-agent): pin the queue_one reachability (FG11d)

The design record claims the queued-input arm is reachable under queue_one; this
cell is the witness. A second manual fire is admitted at one active run, its run
commits, and no prompt for its occurrence ever appears. The cancel half stays
open: measured here, a task cancel on that queued run is accepted and the run
stays running, because the queue is settled by the turn.

* test(managed-agent): align the queue_one assertions and mark the cancel half ungated (FG11d)

The active-run half of the reachability cell excluded one settled state fewer
than the queued half, so a run that had failed would still read as untouched.
Both halves now exclude the same three settled states.

The design record called the un-gated cancel half "(measured)", which reads as
if a witness exists in the tree. It now says "measured locally, not gated", the
same claim the PR body makes.

* test(managed-agent): observe the queue_one dwell and scope the record to what it proves (FG11d)

The negative rested on a single `isEmpty()` sampled one poll after the run row
committed, so an asynchronous dispatch of the queued input would land after the
assertion had already returned green. It now runs as a bounded dwell through
`waiting()`, keeping the failFast and lock-exception guard.

Both records cited the cell as pinning that no prompt appears, which attributes
the absence to the overlap arm. The first turn is parked, so the wake pump
cannot start the queued input under any policy; the records now say the cell
pins admission (its own run id and a `fired` occurrence) and only observes the
absence over a dwell.
2026-10-22 14:24:10 +00:00
Shaojin Wen
480b4d341a
feat(managed-agent): read the Harness credentials from one file (#15063)
* feat(managed-agent): read the Harness credentials from one file

The Hosted Harness and the control plane share a bearer token and a
capability digest, which the reference distribution stored twice, in
harness.env and server.env, so every rotation or hand edit had to change
both files identically.

QWEN_MANAGED_AGENT_HARNESS_CREDENTIALS_FILE now names the Harness's own
environment file. The control plane reads QWEN_SERVER_TOKEN and
QWEN_HOSTED_HARNESS_CAPABILITY_DIGEST from it into its configuration,
never into its process environment, and refuses to start when the file
is combined with a direct token or digest, or lacks either key.
Preflight reports the file's permissions and points credential fixes at
it. The bootstrap, templates, systemd instructions and guide store the
credentials once.

* fix(managed-agent): refuse credential lines the Harness reads differently

The credentials parser accepted a subset of the environment-file grammar
and silently mis-read the rest. A continuation, an escape, an
unterminated quote, text after a closing quote or a `$` expansion gave
the control plane a different value than systemd or a shell gave the
Harness, while preflight passed. Such lines now fail startup, naming
the file and line but never the content.

The file is now read once and only while the Harness is enabled, and an
unreadable file reports its exception type in the validation row.
Preflight shares one secret-file permission policy between the config
and credentials rows. The credentials row also fails an unreadable file
and reports an unusable path instead of aborting, and the harness row
fails the shipped placeholder token.

Tests now pin the run order, values containing `=`, world-readable
files, the file-aware 401 fix and the shipped harness.env.example keys.
The systemd READMEs describe the warning as a warning.

* fix(managed-agent): accept only credential lines both readers take literally

Credential values in the Harness credentials file may now contain only
letters, digits and ._:/+=-, and whitespace around `=` or a carriage
return is refused: a shell runs `KEY = value` as a command and keeps a
trailing \r, so the control plane and the Harness could hold different
digests while every preflight row passed.

When startup refuses the file, the harness row now skips its probe
instead of sending whatever credentials are left bound, and the file is
applied atomically. run() delegates to checks(args) so a test can pin
the credentials row after the harness row.
2026-10-22 14:07:39 +00:00
qwen-code-dev-bot
cfd95f6abb
fix(ci): scope the sdk-java host lock to the cache write-back (#15128)
* fix(ci): scope the sdk-java host lock to the cache write-back (#15117)

Run 39627609266's fast-tier job arrived at 17:38, stayed head of the
sdk-java host-lock queue, and failed at 19:15 without starting Maven.
The MariaDB integration lane held the same lock across its install and
full MySQL clean verify; under pool contention that hold ran from 15:54
to 18:57 (run 39628985638), past the fast tier's 90-minute budget.

Both MariaDB Maven runs already resolve from a job-local repository, so
they touch no host-shared state. Seed that repository before the lock,
run both Maven commands unlocked, and take the host lock only for the
cache write-back, the sole remaining host-shared mutation. Drop fd 9 on
the write-back children so a cancelled job's survivor cannot retain the
lock. Raise the lane ceiling to 300 minutes for the ~3-hour verify plus
one lock wait and setup, and pin the new order and fd closes.

Fixes #15117

* test(ci): exempt the OpenTUI parity suites from the no-AK gate (#15117)

The main merge brought three interactive suites from #14964. The no-AK gate requires every runnable integration test to be selected or explicitly exempted, so the Test job fails until they are listed.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen Autofix <qwen-code-assistant@users.noreply.github.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: jinjing.zzj <jinjing.zzj@alibaba-inc.com>
Co-authored-by: 易良 <1204183885@qq.com>
2026-10-22 21:44:45 +08:00
qwen-code-dev-bot
06e59666df
fix(ci): skip the duplicate prepare build in the daemon E2E lane (#14884)
* fix(ci): skip the duplicate prepare build in the daemon E2E lane (#14870)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(ci): pin the daemon E2E prepare-skip premises (Refs #14870)

* test(ci): keep the daemon E2E step commands pinned (Refs #14870)

* test(ci): pin the daemon E2E step and its install warning (#14870)

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen Autofix <autofix@qwen-code.dev>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
2026-10-22 12:19:59 +00:00
jinye
288e4c481d
perf(ci): Optimize MySQL integration verification (#15200)
Close Spring contexts before fixture database cleanup, run integration classes in isolated reusable forks, and remove redundant fixture validation and duplicate load-test execution. Document bounded local validation and preserve full CI gates.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-10-22 12:03:13 +00:00
易良
0b3c2f816a
feat(ci): restore a MariaDB leg for the non-Hosted IT family (#15003)
* fix(ci): align Java integration database and lock lifetime

* test(ci): re-pin the sdk-java lock and MySQL probe after the single-step merge

The merge commit staged the conflict resolution before these two re-pins were
written, so they land as a follow-up in the same push:

- `keeps the host lock out of every Maven child` counted three lock-bearing
  steps; #14903 collapsed the MariaDB lane's two Maven steps into one, so the
  count is now two (test job + mysql-integration).
- The MySQL startup probe took the step's first `mvn` line, which is now the
  `-DskipTests install` staging command; select the `-Pmysql-integration`
  command instead so the probe still exercises the consumer.

Verified: vitest sdk-java-workflow.test.js 96 passed; prettier --check clean.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Patrol-Run: qwen-pr-conflict/jmvgz448zlp

* fix(ci): skip the MySQL binlog, drop the unused database, correct the reaper bound

Three independent corrections to the mysql-integration lane this PR reworks.

1. MySQL 8 enables the binary log by default (MariaDB 10.11 did not in the
   configuration this lane replaced), and the datadir is an uncapped tmpfs.
   Nothing in packages/managed-agent-server/src or packages/sdk-java reads a
   binlog (0 hits for binlog|log_bin|GTID|SHOW MASTER STATUS), and the
   container is disposable with no replica, so `--skip-log-bin` is appended
   after the image name beside --innodb-use-native-aio=0. Without it the
   ~67 MiB hex-encoded LONGBLOB query this lane already raises
   max_allowed_packet for is serialized a second time into host RAM.

2. `--env MYSQL_DATABASE='runtime_broker_test'` had no consumer: the lane's
   only connection is -Dmysql.url=.../managed_agent_test?createDatabaseIfNotExist=true.
   The declaration invited a cleanup that drops createDatabaseIfNotExist and
   dies at first connect with Unknown database. Dropping it lets the JDBC URL
   own the schema and shrinks the diff.

3. The cleanup comment and removal-failure warning said the host reaper
   reclaims a stranded container "after a 24h age gate" / "up to a day".
   The real bound is ~48h: qwen-docker-cleanup.sh:31 gates on a strict
   `now - created_at > 86400` (exactly 24h is SKIPPED) and
   qwen-docker-cleanup.timer fires once a day, so a container created just
   after a fire is skipped at the next one and reaped at the one after.

Test pins updated in the same change: the start-step assertion, the exact
docker-run trace literal, and the cleanup warning literal. All three were
mutant-verified red (drop --skip-log-bin / re-add MYSQL_DATABASE / restore
"after 24h") and restored byte-identical.

Only this PR's own copy of the reaper wording is corrected; the two
pre-existing copies (sdk-java.yml's event-transport-multi-node job and
release-managed-agent-reference.yml) are untouched to keep this diff scoped.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Patrol-Run: qwen-pr-closeout/jmvhb9cysmc

* feat(ci): restore a MariaDB leg for the non-Hosted IT family

#14936 moved the mysql-integration lane onto MySQL 8.4 and removed the last
real MariaDB server, leaving the published MariaDB-only V12 repair (RTRIM,
error 1901) and the schema catalog's MariaDB branches without a falsifier.
Both engines now run the same non-Hosted *IT family as two matrix legs of one
job: the container image, its startup arguments, its client, and its readiness
signal come from the leg, and the container name carries the engine so two
legs on one pool host cannot collide.

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-10-22 11:24:34 +00:00
callmeYe
aaec411379
fix(web-shell): show actionable skill installation errors (#15013)
* fix(web-shell): show actionable skill installation errors

* test(cli): synchronize hosted monitor shutdown requests

* test(ci): seed Java lock queue fixture

---------

Co-authored-by: Ethan Ye <ethanye@U-463KXYWL-1938.local>
Co-authored-by: claudeethan <claudecodeethan@gmail.com>
2026-10-22 17:36:15 +08:00
jinye
605fd5ee17
feat(managed-agent): Add session lifecycle UI and reading exports (#15100)
* feat(managed-agent): Add session lifecycle UI and reading exports

Expose durable lifecycle actions and archive navigation in Managed Web Shell, with identity-scoped browser recovery and immutable HTML/Markdown reading exports.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(managed-agent): Resolve lifecycle review and smoke regressions

Use the host React DOM server renderer, announce global errors once, and advance the OpenAPI version. Keep smoke selectors specific to session navigation and align the Workspace expectation with its existing Managed label.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(managed-agent): Preserve schema bindings in channel race fixture

Reuse the production schema-aware JDBC template so repeated H2 queries keep binary identity parameters. Preserve the existing ownership race and its assertions.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(managed-agent): Correct lifecycle retry and export handling

Keep failed unadmitted archive intents idle until explicit retry, scope approval capability to each session profile, and preserve public export semantics and embedded downloads.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-10-22 16:37:26 +08:00
Shaojin Wen
ec82cac361
test(managed-agent): keep a sibling run alive past a cancel (FG11d) (#14999)
* test(managed-agent): keep a settled run's outcome (FG11d)

* test(managed-agent): reuse a same-key cancel (FG11d)

* test(managed-agent): refuse a second fire while the turn runs (FG11d)

* revert: move the second-fire cell onto its own branch

The cell belongs to the next PR in the chain, which bases on this branch, so
it cannot also live here: the next PR's diff would be empty. Content of this
branch is unchanged from acdab642b7.

* test(managed-agent): refuse a second fire while the turn runs (FG11d)

* test(managed-agent): keep a sibling run alive past a cancel (FG11d)

* docs(managed-agent): name the settled run's real refusal code

The cell's own comment still said task_already_settled while the assertions
and both design docs record 409 task_action_unavailable, which is the code the
measured behaviour actually answers.

* test(managed-agent): assert the replayed cancel operation's identity

The cell discarded both cancel responses, so "reuses its operation" rested on
the run state alone — which a second operation could also have produced. It now
compares the two operation ids, pins task_id to the cancelled task, and asserts
the replay flag flips false then true.

* docs(managed-agent): separate the queued-input claim from the settled one

The bullet ran the two claims together with no separator, so a reader could not
tell whether "a queued input cancelled before any attempt" was delivered too.
Both language versions now take the same form as the neighbouring bullets, and
the Chinese continuation line gets its indentation back.

* test(managed-agent): pin the occurrence ledger in the isolation cell

Review R1-1 and R1-2: the cell's comment claimed the schedule's future fires
survive, which nothing in it observes, and it was the only cancel cell that
never read ma_schedule_occurrence. The comment now says what the cell proves
(the definition stays live; a scheduled slot is outside the arm) and the cell
pins both keys fired exactly once with no re-drive. The workflow comment's
wrap figure follows the fork to 11781.

* docs(managed-agent): leave the queued-input arm open and fix its carriers

Review round 2. R1-1: the queued-input criterion is reachable, so the bullet
no longer books it delivered — under queue_one (and allow below quota) a second
manual fire is admitted while the first run is active, because hasOpenTurn reads
only public ma_turn rows. The cell pins the default-skip refusal, not that arm.
R1-10: the cell's comment now names the count arm instead of the open-Turn arm.
R2-1/R2-2: the workflow's two budget comments and both derivation ledgers record
this cell's 25 s (fork 11212, healthy 10612).

* test(managed-agent): catch a re-drive by attempts, not by row count

Review R1-2 on this PR: the count assertion cannot witness a re-drive, because
the occurrence primary key makes a re-drive an UPDATE that bumps attempts rather
than an INSERT. Both keys now pin attempts == 0, and the count assertion is
labelled for what it does catch - a spurious third key. Re-ran the cell on
JDK 21 + MySQL 8.0.46: 6.204 s, green.

---------

Co-authored-by: 易良 <1204183885@qq.com>
2026-10-22 16:17:56 +08:00
callmeYe
240eecf617
feat(web-shell): allow hosts to inject disabled catalog models (#15015)
* feat(web-shell): allow hosts to inject disabled catalog models

Hosts can show product models that are not currently usable in the composer picker, with a framework-neutral hover slot for text or authorize actions.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs(web-shell): add unavailable-model picker screenshots

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(web-shell): polish unavailable-model tooltip card

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(web-shell): make unavailable models look disabled

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(ci): isolate script fixtures and reuse runtime archives

* test(cli): bound command budget fixture work and drain timed-out writes

---------

Co-authored-by: Ethan Ye <ethanye@U-463KXYWL-1938.local>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-22 07:09:59 +00:00
易良
54a56f30ce
fix(ci): write back only the MariaDB lane's Maven delta and size its ceiling (#15000) (#15064)
Some checks failed
Qwen Code CI / Test (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Lint & Static (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / web-shell E2E Smoke (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (macos-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (windows-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Integration Tests (no-AK, No Sandbox) (push) Blocked by required conditions
Qwen Code CI / Integration Tests (CLI, No Sandbox) (push) Blocked by required conditions
E2E Tests / Build for E2E (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker - shard 1/1 (push) Blocked by required conditions
E2E Tests / E2E Test (Linux) - sandbox:none - shard 1/1 (push) Blocked by required conditions
E2E Tests / E2E Test - macOS - shard 1/2 (push) Blocked by required conditions
E2E Tests / E2E Test - macOS - shard 2/2 (push) Blocked by required conditions
E2E Tests / E2E Interactive - OpenTUI renderer (bun) (push) Blocked by required conditions
E2E Tests / channel-plugin E2E (nightly) (push) Blocked by required conditions
E2E Tests / cron-interactive E2E (nightly) (push) Blocked by required conditions
E2E Tests / web-shell Browser Regression (push) Waiting to run
Managed Agent gate / Select the Managed Agent tier (push) Waiting to run
Managed Agent gate / SDK Java () (push) Blocked by required conditions
Managed Agent gate / Managed Agent gate (push) Blocked by required conditions
pnpm Worktree Smoke / Install (macos-latest) (push) Waiting to run
pnpm Worktree Smoke / Install (ubuntu-latest) (push) Waiting to run
pnpm Worktree Smoke / Install (windows-latest) (push) Waiting to run
SDK Java Contract Open PRs / Re-check open PRs against main (push) Waiting to run
SDK Java Flyway Open PRs / Re-check open PRs against main (push) Waiting to run
Verify Landlock helper / Native Linux CLI boundary (push) Waiting to run
Verify Landlock helper / Native Windows settings and streams (push) Waiting to run
Verify Landlock helper / arm64 (push) Waiting to run
Verify Landlock helper / x64 (push) Waiting to run
verify Maven repo producer / Save verify Maven repo (push) Waiting to run
pnpm store producer / Save pnpm store (push) Has been cancelled
* fix(ci): bound the MariaDB lane's cache write-back and size its ceiling (#15000)

Run 39563394993's mysql-integration job was cancelled at the 200-minute ceiling: 54 minutes queued for the host lock, 75 minutes of Maven work, then a 60-minute unbounded tar of the host-shared ~/.m2. The cache is an optimization, so skip it after five minutes; the ceiling now covers the 90-minute wait, the measured Maven pass, the bounded write-back and setup headroom.

* fix(ci): write back only the MariaDB lane's Maven delta by hardlink

The bounded tar pipeline extracted straight into the host-shared ~/.m2,
so a timeout mid-member left a truncated artifact that --skip-old-files
never repaired and the next seed hardlinked into its job. Its 300 s cap
was also below the measured 26-61 minute whole-tree cost, so it would
have tripped on every run.

Publish only the files Maven fetched in this job (nlink == 1 after the
hardlink seed) with per-file cp -ln, keeping the two in-house excludes.
Each link is atomic and never replaces a host file, so the 300 s
backstop can only leave artifacts missing. Distinguish the timeout from
other failures, and fold the backstop into the derived ceiling floor
instead of a second hardcoded one.

* ci: record sdk-java.yml's real size in the workflow ratchet

This PR grows .github/workflows/sdk-java.yml from 113473 to 114180 bytes:
the MariaDB lane's timeout ceiling moves 200 -> 280 with the arithmetic
that justifies it, and the Maven write-back is rewritten to publish only
this job's own downloads (nlink == 1) under a 300 s backstop instead of
taring the whole tree. The growth is the change, so record it rather than
move the step out.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Patrol-Run: qwen-pr-conflict/jmvj37bcsp8

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-10-22 14:48:11 +08:00
qwen-code-dev-bot
438bcb2a8f
fix(ci): let the fast Java tier overtake waiting full-tier lock tickets (#15035)
* fix(ci): serve the fast Java tier before full-tier lock holds (#15032)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(ci): keep a parked lock head's ticket alive under fast priority

A head blocked in `flock --wait` could not touch its ticket, so once a
hold outlasted the 1800s mtime arm another waiter reaped a live head and
the next ticket, whatever its class, parked in the kernel too. With two
classes that lets normal tickets take kernel positions ahead of fast
tickets that arrive later during a long hold. A keepalive now refreshes
the parked head's ticket at the waiters' two-second cadence; it closes
the lock fd and uses `touch -c`, so it can neither hold the lock nor
recreate a removed ticket.

The ordering and promotion cases used a stub whose `--wait` returned
every 200 ms, so they exercised a head that loops, which production never
does. They now park `--wait` until release and assert the reachable
paths: a fast ticket overtaking a normal ticket that is still waiting,
and a promoted waiting normal ticket preceding a later fast ticket.

The comments and design docs no longer claim a fast job waits at most
the hold already running (a parked head still goes first) or cite
#14962/#15032 as fast-behind-full evidence; they state what priority
removes and that a single hold longer than the budget is outside it.

---------

Co-authored-by: Qwen Autofix <qwen-code-assistant@users.noreply.github.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: wenshao <shaojin.wensj@alibaba-inc.com>
2026-10-22 03:54:27 +00:00
易良
7091697f00
fix(ci): enroll the OpenTUI parity tests in the no-AK lane (#15142) 2026-10-22 11:16:42 +08:00
Shaojin Wen
f773580e13
test(managed-agent): refuse a second fire while the turn runs (FG11d) (#14998)
* test(managed-agent): keep a settled run's outcome (FG11d)

* test(managed-agent): reuse a same-key cancel (FG11d)

* test(managed-agent): refuse a second fire while the turn runs (FG11d)

* revert: move the second-fire cell onto its own branch

The cell belongs to the next PR in the chain, which bases on this branch, so
it cannot also live here: the next PR's diff would be empty. Content of this
branch is unchanged from acdab642b7.

* test(managed-agent): refuse a second fire while the turn runs (FG11d)

* docs(managed-agent): name the settled run's real refusal code

The cell's own comment still said task_already_settled while the assertions
and both design docs record 409 task_action_unavailable, which is the code the
measured behaviour actually answers.

* test(managed-agent): assert the replayed cancel operation's identity

The cell discarded both cancel responses, so "reuses its operation" rested on
the run state alone — which a second operation could also have produced. It now
compares the two operation ids, pins task_id to the cancelled task, and asserts
the replay flag flips false then true.

* docs(managed-agent): separate the queued-input claim from the settled one

The bullet ran the two claims together with no separator, so a reader could not
tell whether "a queued input cancelled before any attempt" was delivered too.
Both language versions now take the same form as the neighbouring bullets, and
the Chinese continuation line gets its indentation back.

* docs(managed-agent): leave the queued-input arm open and fix its carriers

Review round 2. R1-1: the queued-input criterion is reachable, so the bullet
no longer books it delivered — under queue_one (and allow below quota) a second
manual fire is admitted while the first run is active, because hasOpenTurn reads
only public ma_turn rows. The cell pins the default-skip refusal, not that arm.
R1-10: the cell's comment now names the count arm instead of the open-Turn arm.
R2-1/R2-2: the workflow's two budget comments and both derivation ledgers record
this cell's 25 s (fork 11212, healthy 10612).

---------

Co-authored-by: 易良 <1204183885@qq.com>
2026-10-22 03:16:14 +00:00
ChiGao
0ac1fcca91
feat(cli): align OpenTUI input, editing and status lines with Ink (#14964)
* 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

* style(cli): format merged OpenTUI test callbacks

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

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

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

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

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

* fix(cli): discard generated command work after cancellation
2026-10-22 08:22:04 +08:00
烽宁
79242671bb
test(ci): guard no-AK membership and filter resolution (#14989)
Some checks are pending
Qwen Code CI / Classify PR (push) Waiting to run
Qwen Code CI / Test (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Lint & Static (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / web-shell E2E Smoke (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (macos-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (windows-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Integration Tests (no-AK, No Sandbox) (push) Blocked by required conditions
Qwen Code CI / Integration Tests (CLI, No Sandbox) (push) Blocked by required conditions
E2E Tests / Build for E2E (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker - shard 1/1 (push) Blocked by required conditions
E2E Tests / E2E Test (Linux) - sandbox:none - shard 1/1 (push) Blocked by required conditions
E2E Tests / E2E Test - macOS - shard 1/2 (push) Blocked by required conditions
E2E Tests / E2E Test - macOS - shard 2/2 (push) Blocked by required conditions
E2E Tests / E2E Interactive - OpenTUI renderer (bun) (push) Blocked by required conditions
E2E Tests / channel-plugin E2E (nightly) (push) Blocked by required conditions
E2E Tests / cron-interactive E2E (nightly) (push) Blocked by required conditions
E2E Tests / web-shell Browser Regression (push) Waiting to run
Managed Agent gate / Select the Managed Agent tier (push) Waiting to run
Managed Agent gate / SDK Java () (push) Blocked by required conditions
Managed Agent gate / Managed Agent gate (push) Blocked by required conditions
Verify Landlock helper / x64 (push) Waiting to run
Verify Landlock helper / Native Linux CLI boundary (push) Waiting to run
Verify Landlock helper / Native Windows settings and streams (push) Waiting to run
Verify Landlock helper / arm64 (push) Waiting to run
verify Maven repo producer / Save verify Maven repo (push) Waiting to run
* test(ci): guard no-AK membership and filter resolution

* test(ci): require non-blank no-AK exemption reasons

---------

Co-authored-by: 易良 <1204183885@qq.com>
2026-10-22 05:06:15 +08:00
Shaojin Wen
fbeb188b16
test(managed-agent): reuse a same-key cancel (FG11d) (#14997)
* test(managed-agent): keep a settled run's outcome (FG11d)

* test(managed-agent): reuse a same-key cancel (FG11d)

* test(managed-agent): refuse a second fire while the turn runs (FG11d)

* revert: move the second-fire cell onto its own branch

The cell belongs to the next PR in the chain, which bases on this branch, so
it cannot also live here: the next PR's diff would be empty. Content of this
branch is unchanged from acdab642b7.

* docs(managed-agent): name the settled run's real refusal code

The cell's own comment still said task_already_settled while the assertions
and both design docs record 409 task_action_unavailable, which is the code the
measured behaviour actually answers.

* test(managed-agent): assert the replayed cancel operation's identity

The cell discarded both cancel responses, so "reuses its operation" rested on
the run state alone — which a second operation could also have produced. It now
compares the two operation ids, pins task_id to the cancelled task, and asserts
the replay flag flips false then true.

* docs(managed-agent): separate the queued-input claim from the settled one

The bullet ran the two claims together with no separator, so a reader could not
tell whether "a queued input cancelled before any attempt" was delivered too.
Both language versions now take the same form as the neighbouring bullets, and
the Chinese continuation line gets its indentation back.
2026-10-21 16:15:54 +00:00
易良
21337f0e51
fix(release): cover every spawned vendored binary in the tarball exec-bit gate (#15008)
* fix(release): cover every spawned vendored binary in the tarball exec-bit gate

The gate matched only vendor/ripgrep/*/rg, but the tarball spawns a second
vendored executable: vendor/landlock-run/<arch>-linux/qwen-landlock-run. Its
own runtime heal shares the ripgrep heal's hard limit — it can only chmod an
install the running user owns, so a root-owned sudo install degrades the
same silent way. Widen the expected set with a small spec list keyed on the
leaf binary's presence (the landlock-run/src source directory falls out
structurally), parse every regular-file tar entry instead of a single
ripgrep regex, and extend the fixture tests to cover both trees with
pass/reject cases.

Also correct the stale comment above the landlock heal: it claimed npm
archives strip non-bin exec bits, which is the inverse of what #12668
established — pnpm's packer wrote 0644 for every non-bin entry from 0.24.4
to 0.25.3; npm keeps working-tree modes.

Refs #12668

* fix(release): keep missing-binary strictness in the widened exec-bit gate

Deriving the expected set from the leaf binary's presence meant a platform
directory whose binary was dropped during staging silently shrank the
expected set: a dist without vendor/ripgrep/x64-linux/rg but with the
directory would pass with five entries. Platform membership now comes from
the directory name alone — ripgrep skips '-win32', landlock-run skips the
'src' source directory — so a missing binary fails as 'missing from the
packed tarball' again, matching the pre-widening strictness. Also update the
function doc block, which still claimed the gate covered ripgrep only.

Regression test: an empty ripgrep platform directory fails with the
missing-entry diagnostic even when every other binary passes.
2026-10-21 15:39:07 +00:00
易良
a4562edb67
fix(ci): align Java integration database and lock lifetime (#14936)
* fix(ci): align Java integration database and lock lifetime

* test(ci): re-pin the sdk-java lock and MySQL probe after the single-step merge

The merge commit staged the conflict resolution before these two re-pins were
written, so they land as a follow-up in the same push:

- `keeps the host lock out of every Maven child` counted three lock-bearing
  steps; #14903 collapsed the MariaDB lane's two Maven steps into one, so the
  count is now two (test job + mysql-integration).
- The MySQL startup probe took the step's first `mvn` line, which is now the
  `-DskipTests install` staging command; select the `-Pmysql-integration`
  command instead so the probe still exercises the consumer.

Verified: vitest sdk-java-workflow.test.js 96 passed; prettier --check clean.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Patrol-Run: qwen-pr-conflict/jmvgz448zlp

* fix(ci): skip the MySQL binlog, drop the unused database, correct the reaper bound

Three independent corrections to the mysql-integration lane this PR reworks.

1. MySQL 8 enables the binary log by default (MariaDB 10.11 did not in the
   configuration this lane replaced), and the datadir is an uncapped tmpfs.
   Nothing in packages/managed-agent-server/src or packages/sdk-java reads a
   binlog (0 hits for binlog|log_bin|GTID|SHOW MASTER STATUS), and the
   container is disposable with no replica, so `--skip-log-bin` is appended
   after the image name beside --innodb-use-native-aio=0. Without it the
   ~67 MiB hex-encoded LONGBLOB query this lane already raises
   max_allowed_packet for is serialized a second time into host RAM.

2. `--env MYSQL_DATABASE='runtime_broker_test'` had no consumer: the lane's
   only connection is -Dmysql.url=.../managed_agent_test?createDatabaseIfNotExist=true.
   The declaration invited a cleanup that drops createDatabaseIfNotExist and
   dies at first connect with Unknown database. Dropping it lets the JDBC URL
   own the schema and shrinks the diff.

3. The cleanup comment and removal-failure warning said the host reaper
   reclaims a stranded container "after a 24h age gate" / "up to a day".
   The real bound is ~48h: qwen-docker-cleanup.sh:31 gates on a strict
   `now - created_at > 86400` (exactly 24h is SKIPPED) and
   qwen-docker-cleanup.timer fires once a day, so a container created just
   after a fire is skipped at the next one and reaped at the one after.

Test pins updated in the same change: the start-step assertion, the exact
docker-run trace literal, and the cleanup warning literal. All three were
mutant-verified red (drop --skip-log-bin / re-add MYSQL_DATABASE / restore
"after 24h") and restored byte-identical.

Only this PR's own copy of the reaper wording is corrected; the two
pre-existing copies (sdk-java.yml's event-transport-multi-node job and
release-managed-agent-reference.yml) are untouched to keep this diff scoped.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Patrol-Run: qwen-pr-closeout/jmvhb9cysmc

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-10-21 14:39:26 +00:00
Shaojin Wen
96953853fd
test(managed-agent): resume the automation streams across a settle (FG11e) (#15017)
* test(managed-agent): resume the automation streams across a settle (FG11e)

Gate the FG11e row of #14446 with two cells in the FG11 automation class.
One cuts a run's task event feed and a public Session stream while the
wake Turn is held between its fire and its settle, and resumes both from
their last positions; the other pages the run list across an insert. The
Session arm asserts today's precondition that a run adds no event to the
Session stream, so it gates the resume across that window rather than
automation content.

The cells book 39 s on the shared Hosted fork (healthy 10272 s, fork
10872 s, so the Verify step moves to 192 minutes and the job ceiling to
295), and the FG11e design record moves to partly delivered in both
languages.

* test(managed-agent): decode the FG11e task cursor independently

The stream cell built each expected task cursor with the store's own
encoder, so the cursor format was never witnessed apart from the code
that writes it. The served cursor is now decoded in the test and must
name its row's sequence. The Session comparison trims the ledger with a
limit instead of subList, so a stream that served more frames than the
journal holds fails as an assertion rather than an IndexOutOfBounds.

* test(managed-agent): count each run's settle in the FG11e list cell

The run-list cell counted model Turns for the automation but never read
the settle commands, so a run settled twice without a second model call
would pass it, while both design records say each cell checks one settle
per occurrence. It now asserts the journal holds exactly one settleRun
per run, in the order the runs settled.

* test(managed-agent): fail an FG11e task cursor outside its format

The independent cursor check fell back to the decoded text when it did
not match the cursor format, so a cursor that decodes to a bare number
became a valid-looking sequence and matched the ledger. A cursor outside
the format now fails the check outright.

* test(managed-agent): rebook the FG11e cells at their slower samples

Two later runs measured the stream cell at 14.1 s and the run-list cell
at 5.6 s, above the 13.8 s and 5.2 s the ledger was booked against. At 2x
the slower samples the cells take 41 s: healthy 10424 s, fork 11024 s,
which the 194-minute Verify step still wraps with 16 s of margin.
2026-10-21 12:40:20 +00:00
Shaojin Wen
9efdca76d3
feat(managed-agent): derive Session Store wiring on a single host (#15005)
* feat(managed-agent): derive Session Store wiring on a single host

An enabled Hosted Harness requires the Managed Session Store, yet the
store's switch, base URL and workspace ID all had to be configured by
hand, and the shipped templates set a workspace ID that the documented
local-process tool path then rejects.

The store now follows the Harness switch, takes its base URL from this
server's loopback or wildcard listener, and shares the Runtime Broker's
workspace identity, derived from the Workspace directory when no ID is
set. Explicit values keep precedence. Preflight reports the effective
store wiring, and the templates, bootstrap and deployment guide name the
Workspace directory instead of a conflicting ID.

* fix(managed-agent): derive no plaintext Store URL for a TLS listener

When the public listener serves TLS through server.ssl and no
dedicated internal listener exists, the derived http:// loopback URL
reached the TLS connector, so every Store call failed while preflight
reported PASS. Such a listener now derives nothing and the existing
refusal asks for an explicit URL. The internal listener is always
plaintext, so it still derives behind a TLS public listener.

* test(managed-agent): pin the dual-path entry to the derived Store wiring

The dual-path README contract still required the explicit store switch
that the entry no longer exports, and its ordering check would pass
vacuously once the name was gone. It now checks that the store follows
the Harness by default, that Prerequisites exports the workspace ID,
and that the Harness base-url export precedes the restart cue, with
both positions required.
2026-10-21 20:34:12 +08:00
Shaojin Wen
86875ee18b
test(managed-agent): reuse the pinned registration after a lost ack (FG13a) (#14993)
* test(managed-agent): lose the store ack after the result commit (FG13a)

StoreFaultGate's existing seam rejects a commit before it applies, so the
whole commit rolls back. This layer adds the opposite failure: the commit
lands and the caller never sees its acknowledgement. The faulting store
calls afterApply only after super.apply succeeds; the new cell proves one
physical Hook call, a durable settled result, and a status read that
returns it without a second call.

Adds the bilingual design note. One cell adds 150 s to the shared fork:
healthy 10189 s, fork 10789 s, Verify 190 minutes, job 293 minutes.

* test(managed-agent): keep the durable dispatch after a lost ack (FG13a)

* test(managed-agent): reuse the pinned registration after a lost ack (FG13a)

* test(managed-agent): report the lost ack after the commit lands (FG13a)

* test(managed-agent): let the dispatch ack-loss cell call its Hook (FG13a)

* docs(managed-agent): describe the ack seam without overclaiming (FG13a)

* test(managed-agent): bound the dispatch recovery instead of guessing (FG13a)

* docs(managed-agent): carry the audit fixes into the registration slice (FG13a)

* docs(managed-agent): align the Chinese dispatch slice with its cell (FG13a)

* docs(managed-agent): drop the model-request claim from the Chinese slice (FG13a)

* docs(managed-agent): align the Chinese registration slice budget (FG13a)

* test(managed-agent): witness the replay instead of a transient phase (FG13a)

* test(managed-agent): witness the replay on the registration ack loss (FG13a)
2026-10-21 19:34:56 +08:00
Shaojin Wen
644dfcf68b
test(managed-agent): keep the durable dispatch after a lost ack (FG13a) (#14992)
* test(managed-agent): lose the store ack after the result commit (FG13a)

StoreFaultGate's existing seam rejects a commit before it applies, so the
whole commit rolls back. This layer adds the opposite failure: the commit
lands and the caller never sees its acknowledgement. The faulting store
calls afterApply only after super.apply succeeds; the new cell proves one
physical Hook call, a durable settled result, and a status read that
returns it without a second call.

Adds the bilingual design note. One cell adds 150 s to the shared fork:
healthy 10189 s, fork 10789 s, Verify 190 minutes, job 293 minutes.

* test(managed-agent): keep the durable dispatch after a lost ack (FG13a)

* test(managed-agent): report the lost ack after the commit lands (FG13a)

* test(managed-agent): let the dispatch ack-loss cell call its Hook (FG13a)

* docs(managed-agent): describe the ack seam without overclaiming (FG13a)

* test(managed-agent): bound the dispatch recovery instead of guessing (FG13a)

* docs(managed-agent): align the Chinese dispatch slice with its cell (FG13a)

* docs(managed-agent): drop the model-request claim from the Chinese slice (FG13a)

* test(managed-agent): witness the replay instead of a transient phase (FG13a)
2026-10-21 17:43:00 +08:00
Shaojin Wen
021dc1fdd6
test(managed-agent): lose the store ack after the result commit (FG13a) (#14991)
* test(managed-agent): lose the store ack after the result commit (FG13a)

StoreFaultGate's existing seam rejects a commit before it applies, so the
whole commit rolls back. This layer adds the opposite failure: the commit
lands and the caller never sees its acknowledgement. The faulting store
calls afterApply only after super.apply succeeds; the new cell proves one
physical Hook call, a durable settled result, and a status read that
returns it without a second call.

Adds the bilingual design note. One cell adds 150 s to the shared fork:
healthy 10189 s, fork 10789 s, Verify 190 minutes, job 293 minutes.

* test(managed-agent): report the lost ack after the commit lands (FG13a)

* docs(managed-agent): describe the ack seam without overclaiming (FG13a)

* docs(managed-agent): drop the model-request claim from the Chinese slice (FG13a)
2026-10-21 08:41:23 +00:00
Shaojin Wen
8545558a25
test(managed-agent): keep a settled run's outcome (FG11d) (#14996)
* test(managed-agent): keep a settled run's outcome (FG11d)

* docs(managed-agent): name the settled run's real refusal code

The cell's own comment still said task_already_settled while the assertions
and both design docs record 409 task_action_unavailable, which is the code the
measured behaviour actually answers.
2026-10-21 07:27:27 +00:00
ChiGao
97567d5dd7
feat(core): add a real PTY backend for the Bun runtime (#14046)
* feat(core): separate app launcher and JS interpreter runtime boundary

Establishes the runtime boundary the Bun migration (MYWO-8 S1) needs
before workers, hooks, sandbox helpers and the code-mode host spawn
JavaScript children under a future compiled-app flavor: arbitrary-JS
child processes resolve their interpreter through one accessor (package
manifest first, process.execPath fallback) instead of reading
process.execPath directly, Bun detection has a single seam, and the
app-launcher contract is documented alongside the full call-site
inventory in a bilingual design doc. Adds the same-fixture Node/Bun
regression matrix (stdio framing, exit codes, SIGTERM, IPC channel,
--expose-gc, --input-type=commonjs --eval).

* fix(core): anchor interpreter resolution to the trusted install root

Arbitrary-JS child resolution no longer walks upward looking for a
manifest: the only trusted location is the standalone package root —
the parent of the caller's bundle directory, which must hold both a
manifest.json and the standalone entry marker lib/cli-entry.js — so an
unrelated ancestor manifest in npm, source or SDK layouts can never be
read. Declarations are validated before use: runtime must be exactly
'bun' or 'node', and the interpreter must be an existing executable
regular file; any invalid or missing declaration falls back to
process.execPath without throwing (non-string interpreter, directory,
non-executable file, unknown runtime, absent binary, missing marker).

Adds the regression matrix for unrelated ancestor manifests (npm
bundle and deep SDK layouts), object/number/directory interpreters,
unknown runtime, missing and non-executable interpreters, and the
trust anchor; syncs both design-doc language versions with the
validated contract.

* docs(design): complete the migration inventory handoff

Adds the three interpreter-identity call sites the re-review found
missing from the call-site inventory (hook-command-cgroup launcher,
bwrap-execution and landlock-execution allowlist staging), marks the
unwired rows as owned by the S3 migration sweep, and notes platform
applicability: the cgroup/bwrap/landlock rows are Linux-only
mechanisms validated against the Linux targets of the platform
matrix, while the mem0 and pem rows apply on every platform. Both
design-doc language versions are updated; no product or test code
changes.

* feat(core): add a real PTY backend for the Bun runtime

Under Bun, @lydell/node-pty's wrapper pumps the PTY master fd through a
tty.ReadStream, and Bun surfaces the nonblocking fd's EAGAIN as an error
event instead of "no data yet", destroying the stream and closing the
master: onData never fires, resize fails with EBADF, and the shell tool
and web terminal hang. Reproduced on Bun 1.3.14 and 1.4.0.

getPty() now loads a qwen-bun-pty backend under Bun (non-Windows) that
drives the same native addon directly with a main-thread async fs.read
pump: EAGAIN retries on a short timer instead of erroring, EIO/EBADF end
the pump and close the fd, writes queue through an async fs.write with
EAGAIN retries, and exit waits briefly for the drained fd so data is
never truncated behind onExit. The wrapper's observable contract (env
sanitizing, flow-control bytes, encoding, resize validation, IPty
lifecycle) is mirrored, and the pump starts in the constructor so an
unpumped fd can never hold the event loop open.

Packaging stages the node-pty addon for both runtime flavors, since Bun
installs now load it through this backend. The Windows-under-Bun gate
stays honest (explicit load error), and the runtime-boundary design docs
point at the new backend doc for the mechanism and evidence.

Tests: unit coverage for the backend lifecycle (output, write, resize,
kill, pause/resume, flow control, raw encoding), getPty selection under
Bun/Windows, and a cross-runtime regression that runs the same fixture
through the real getPty() seam under both Node and Bun when a bun binary
is present.

* fix(core): keep PTY exit detection alive while paused

The pinned node-pty addon fires its native exit callback only around
master-fd read activity (isolated-probe evidence, identical on Node and
Bun), so the old pause() that stopped the pump lost onExit entirely:
pause then child exit left the master fd open and the host unable to
drain — the same mechanism behind the XOFF-then-cancel FD residue under
handleFlowControl.

pause() now buffers output into a bounded hold (1 MiB) that resume()
flushes, while reads continue so exit detection rides on the pump.
On end of life the hold is discarded for wrapper parity: onExit arrives
exactly once and the fd is released, but resume-after-exit replays
nothing, matching the wrapper's destroyed paused socket. Docs are
synced to the actual main-thread async fs.read pump (the earlier
worker-threads/blocking-read sketch is documented as abandoned), and
regressions cover pause-at-exit, hold overflow, and XOFF-cancel on both
runtimes.

* fix(core): make the Bun PTY pause hold lossless and exits leak-free

Serializes master-fd reads behind an in-flight guard (a resume chaining
into a read that is still outstanding would cross-observe the shared
64 KiB buffer), holds paused output without a cap so nothing is ever
silently dropped, and routes every end-of-life path through one cleanup
that flushes the decoder, stops the retry timer, closes the master fd
and fires onExit exactly once — including the 500 ms fallback, which is
now ref'd so exit delivery cannot depend on a droppable timer. Pins all
of it with byte/line-exact regressions: no-gap pause/resume storms and
a ~1.9 MB flood resumed byte-for-byte, cross-runtime.

* fix(core): cap the Bun PTY pause hold and terminate on overflow

The lossless pause hold could grow without bound while a consumer
stays paused. The hold now copies chunks into fixed 64 KiB blocks
under a per-pty byte ledger (4 MiB default) inside a process-wide
budget (32 MiB total hold, 8 active ptys, 1 MiB write queue), so the
bound holds for any producer chunk pattern.

Reaching a cap terminates that pty (SIGTERM then SIGKILL) and emits
one structured PtyLimitError — never a success result and never a
fabricated native exit; the real signal death lands only in
stats.nativeExitRecord. Shell executions converge the error into
{error, exitCode: null, signal: null}; web terminals mark the session
failed and the /terminal route sends an error control frame followed
by close 4001. Node behavior is unchanged.

Design docs corrected per review: the drip "kernel corruption" claim
is withdrawn, and exit detection wording no longer overstates when
exits are observed.

* fix(core): harden post-termination pty edges per review

Dual-review follow-ups on the bounded hold: resize() joins write() in
treating a terminated/closed pty as a no-op instead of throwing EBADF
from the addon; a read that was in flight when the limit termination
closed the fd no longer delivers or re-charges its late bytes; and a
resume() replay stops at the first data listener that terminates the
pty, so no held bytes flow after the structured error.

* fix(core): detach pty error subscriptions by observed shape, not assumed Disposable

node-pty's Terminal.prototype.on proxies the listener to its master socket
and returns undefined, while an EventEmitter-based pty (the Bun backend)
returns the emitter itself. The registry stored that return value as a
Disposable and called dispose() on release, so every Bun release, natural
exit, or backend failure path threw TypeError from the route/registry and
could take the whole serve process down (server exit 1, client saw 1006
instead of the explicit close).

Store the subscription return as unknown and detach by observed shape: a
real { dispose } is used as-is, otherwise off/removeListener removes the
listener, and undefined (node-pty's actual return) keeps the previous
no-dispose behavior unchanged.

Covered by two registry unit tests on the mocked shapes plus a real-serve
lifecycle probe (release 4004 / exit 4000 / backend over-limit 4001 with
failed-session reconnect replay, server alive throughout) run under Bun
1.3.14, Bun 1.4.0, and Node.

* fix(core): close Bun PTY fds only after in-flight ops settle

Review round on #14046:

- bun-pty closeFd() ran closeSync() while libuv fs.read/fs.write ops could
  still own the master fd, so the recycled descriptor number could take a
  queued write into an unrelated session. fdClosed now flips and the
  process-wide admission slot is released immediately, but the real close
  is deferred until the last outstanding op settles, with witnesses for
  both the read-held and write-held arms.
- A write-side EIO/EBADF (child already gone) is the expected teardown
  race and is no longer reported, matching the wrapper's swallowed EIO;
  other write errors keep their errno code so the entry classifier and
  getPtyLimitMessage can recognize them instead of escaping as an
  uncaught exception. The pump's emit dispatch runs under try/finally so
  a throwing error listener can never strand the pump.
- The web-terminal registry's pty error subscription no longer re-throws:
  a throw there leaves the backend's fs callback as an uncaught exception
  and kills the serve daemon. EIO/EAGAIN races are swallowed and other
  non-limit errors go to the diagnostic sink.
- Failed sessions no longer count against the web-terminal admission cap,
  and release() no longer fabricates a 143/15 exit frame for them.
- processPtyBudget.maxActivePtys is 64 (headroom over the eight-slot
  web-terminal cap so a full house cannot starve the shell tool), with
  the per-pty vs process-wide cap relationship documented.
- ShellExecutionResult.executionMethod declares 'qwen-bun-pty', its
  error-field contract documents resource-limit termination, and the two
  casts that hid the Bun backend name are dropped.
- getPty tests that assert the Bun arm loads now pin a POSIX platform so
  they pass on Windows hosts; docs and the packaging help text are
  aligned (correct smoke-runtime.js path, boundary-doc PTY row now cites
  the bun-pty fixture, node-pty staging applies to both runtimes).

* chore: re-verify S1 boundary test-file merge resolution with recorded evidence

Empty commit: no code change is warranted by the deterministic gate's
test-weakening rejection. The merge ddc7666b9f resolved
packages/core/src/utils/runtime-info.test.ts and
packages/core/src/utils/runtime-boundary.node-bun.test.ts to main's
reviewed versions from #14036 (2eab3cc431), replacing the older
stacked draft copies this branch carried while the prerequisite was
unmerged. Both files are byte-identical to origin/main (empty merge-
base diff: this PR no longer modifies them), and main's versions are
strictly richer (19/16 vs 16/15 expect() calls), so no assertion
coverage is lost. The per-file evidence is recorded in the round's
test-weakening.json; restoring the drafts would revert the reviewed
suites and re-introduce the stacked duplicates the merge correctly
eliminated.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(core): preserve PTY failure output and bounded settlement

* fix(core): deliver reaped PTY exits on limit trips, replay failed scrollback

Review round on the Bun PTY backend:

- terminateResourceFailure no longer signals a pid it already reaped
  (pendingExit parked): the real exit is delivered and the structured
  limit error reported, instead of SIGTERM/SIGKILL at a recycled pid.
- The failed-reconnect branch of the terminal WS route replays the
  retained scrollback through the backpressure guard before the error
  frame, matching the exited path.
- QWEN_PTY_ACTIVE_LIMIT no longer claims a termination that never
  happened, and acceptedBytes stays a byte count (0 at refusal).
- sanitizeEnv also applies when options.env is omitted, matching the
  wrapper's resolved-env rule.
- The arithmetically unreachable paused-hold-segments cap is deleted.
- Tests: the live-failure route test now reaches a live session; the
  registry limit test is parametrized over both limit codes; the
  paused-exit fixture gains a withheld-tail oracle so it cannot pass
  without a real pause; the bounded-hold tests get afterEach failure
  isolation; the process-wide write-queue budget is exercised; and the
  stale throw-propagation assertion is reconciled with the deliberate
  reportListenerError containment (un-breaks the core test lane).

* docs(core): clarify pending PTY close validation

* docs(core): fix PTY validation checklist indentation

* fix(pty): make resource failures the terminal event

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(cli): raise ps maxBuffer for loaded CI shards

The managed-runtime process probe lists the whole process table with execFileSync. On a loaded CI shard that output exceeds the 1 MiB default and the probe fails with ENOBUFS; raise the cap to 16 MiB.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* docs(core): name the PTY fd-lifetime tests

Point the deferred-close validation entry at the two exact fd-lifetime tests in both design languages.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(cli): release failed terminal replay sessions safely

* test(web-shell): verify failed terminal replay protocol

* test(cli): pin failure listener cleanup on terminal exit

* fix(core): preserve failure precedence across terminal exits

* fix(core): isolate terminal failure notifications and verify release

* fix(core): preserve PTY write and admission failure diagnostics

* test(core): assert PTY cleanup drains every budget

* test(core): verify production PTY refunds start with charged budgets

* fix(core): stop late PTY signals and integrate cleanup refund tests

* test(core): witness PTY subscriber delivery and document native loading

* test(core): reclaim captured PTYs when fd race assertions fail

* test(core): verify exit diagnostics with a real PTY child

* fix(core): avoid signalling reaped PTY leaders during fallback

* test(core): pin paused PTY boundaries and isolate loader probes

* fix(core): verify PTY ownership and target-specific packaging

* fix(core): refuse oversized terminal input before the pty cap

* fix(core): park paused PTY reads at the hold cap instead of killing the tree

Under the Bun backend the shell tool passes handleFlowControl: true, so a
single Ctrl+S (XOFF) byte calls pause(). The pump kept reading into the
paused hold and, once the 4 MiB per-pty (or 32 MiB process-wide) hold was
full, terminated the child process tree with QWEN_PTY_OUTPUT_LIMIT. During
a flood that killed the command about a second after one keystroke.

Size each paused read to the room left in the hold and, once there is
none, stop issuing reads until resume(). The kernel pty buffer then fills
and the child blocks on write, which is the backpressure the node-pty
wrapper's paused socket applies. Nothing is dropped or killed, and
resume() replays the hold and restarts the reads; pty.stats.readParked
exposes the state. QWEN_PTY_OUTPUT_LIMIT and the paused-hold limit kinds
are removed together with the consumer branches that handled them. The
write-queue and admission limits are unchanged.

While parked, a child that dies with output undrained may only finish
exiting on macOS once the master is read again, so the shell tool's
cancel now calls resume() before it signals the process group.

The design docs also get the live-pty cap right (64, not 8) and no longer
describe a block-count cap that the hold never had.

* test(core): run the PTY drain-window witness on Linux only

The real-child test for a write-limit trip after the native exit relies
on a HUP-ignoring grandchild keeping the pty slave open after the session
leader exits. macOS ends the master side right away (a plain-pty probe on
Darwin reads EOF about 70 ms after the leader exits), so the pump closes
the fd before the write and the case failed 3/3 there. Skip it off Linux;
bun-pty-failure-order.test.ts still pins the same guard on every platform
with a mocked native exit.

* fix(core): reap a PTY's whole session on a resource-limit termination

terminateResourceFailure signalled only the leader and the leader's
process group. An interactive shell runs each foreground job in its own
group, so a job that ignores SIGTERM and SIGHUP outlived the termination:
the failure was reported and the budgets refunded while the job kept
running, reparented to init. Reproduced on Linux and macOS.

List what the pty owns with ps while the leader is still unreaped: its
descendants, plus every process in its session (Linux sid) or on its
controlling tty (macOS tdev). Signal each of them as well as the group.
The SIGKILL pass after the grace period lists the tree again. It keeps
an earlier member only while that member's start time still matches, so
a recycled pid is never signalled. It reuses the scope only where the
scope still names the session: macOS drops the tty with the leader, and
Linux keeps the sid unless the pid now leads a new process.

The web terminal registry's killPtyTree already walked the same ps
listing; both now share collectPtyProcessTree.

* test(core): tolerate the pty's CR jitter in paused-flood oracles

macOS's pty driver occasionally inserts an extra CR before LF; a plain script(1) probe reproduces it without this project's code. The paused-flood tests compared the stream byte-for-byte and waited for pausedBytes to equal the logical byte count, so a jittered stream could never satisfy the predicate.

Wait for pausedBytes >= the logical size, derive the process-wide case's expected hold from the observed hold, and compare the resumed stream with runs of CR before LF collapsed. Every line's content, order and count is still asserted, so loss and duplication remain caught.

---------

Co-authored-by: gary.gq <gary.gq@alibaba-inc.com>
Co-authored-by: qwen-code-autofix <qwen-code-autofix@localhost>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev@service.alibaba.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
Co-authored-by: Qwen Autofix <qwen-autofix@users.noreply.github.com>
Co-authored-by: wenshao <shaojin.wensj@alibaba-inc.com>
2026-10-21 07:14:43 +00:00
qqqys
b51ce2c305
feat(workflow): add per-turn human-origin workflow hints (#14876)
* feat(workflow): add per-turn human-origin workflow hints

* fix(workflow): preserve intent across recall and cached submissions

---------

Co-authored-by: qqqys <266654365+qqqys@users.noreply.github.com>
2026-10-21 06:54:24 +00:00
Shaojin Wen
15ab745f1e
test(managed-agent): gate R1-1 owner-release recovery across a Spring restart (FG12d) (#14990)
Cover #14880 item 3. During a lifecycle v2 close the Broker proxy refuses
the owner release after every configuration is drained, then the test
replaces Spring and its embedded Broker. Detach must recover with exactly
one forwarded owner release (no acquire, no MCP control), clear the
storage holder, and leave the Runtime Session RELEASED.

The recorded blocker was the rig, not WorkspaceStorageGuard:
startSpring() registered the storage and inserted the Workspace rows on
every boot, and the guard refuses a second registration while the holder
is booked. Production never re-registers on start, so seed only on the
first boot and restart in the JVM; the Broker's close writes nothing and
the durable provisioner keeps the worker alive, which is the state R1-1
needs.

R1-1 does not reproduce on main: the replaced Broker reaches the
persisted-Session release path, and #13673's managed-context branch
releases the saved Session while the Harness drains. Disabling that
branch turns the case red 3 of 3 times with the original symptom (every
retry answers 503 and the holder stays booked).

Budget the cell at 24 s (2x its measured 11.9 s): healthy 10039 -> 10063,
fork 10639 -> 10663, Verify stays 188 minutes.
2026-10-21 06:40:34 +00:00
顾盼
a791e47a54
feat(cua): streamline computer use and port native reliability fixes (#14846)
* feat(cua): preload the JavaScript computer use runtime

* refactor(cua): remove the native Wayland backend

* feat(cua): move app computer use into the driver

* feat(cua): preserve background delivery and port platform fixes

* feat(cua): add explicit desktop input and browser runtime facade

* feat(cua): package the unified 0.26.0 computer use runtime

* fix(cua): finalize cross-platform native reliability

* fix(cua): isolate runtime releases from CLI versioning

* fix(cua): keep Electron out of root workspace installs

* fix(cua): synchronize consumers and async cleanup tests

* fix(browser): migrate smoke to preloaded cua runtime

* docs(cua): document MCP setup for Qwen Code Claude Code and Codex
2026-10-21 14:03:31 +08:00
Shaojin Wen
e17380e6ef
test(managed-agent): reuse the run on a same-key retry (FG11d) (#14981) 2026-10-21 13:41:54 +08:00
ChiGao
8f3c7e15e4
fix(cli): preserve runtime boundaries during standalone updates (#14934)
Some checks are pending
E2E Tests / E2E Test (Linux) - sandbox:docker - shard 1/1 (push) Blocked by required conditions
Qwen Code CI / Classify PR (push) Waiting to run
Qwen Code CI / Test (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Lint & Static (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / web-shell E2E Smoke (ubuntu-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (macos-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Test (windows-latest, Node 22.x) (push) Blocked by required conditions
Qwen Code CI / Integration Tests (no-AK, No Sandbox) (push) Blocked by required conditions
Qwen Code CI / Integration Tests (CLI, No Sandbox) (push) Blocked by required conditions
E2E Tests / Build for E2E (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none - shard 1/1 (push) Blocked by required conditions
E2E Tests / cron-interactive E2E (nightly) (push) Blocked by required conditions
E2E Tests / E2E Test - macOS - shard 1/2 (push) Blocked by required conditions
E2E Tests / E2E Test - macOS - shard 2/2 (push) Blocked by required conditions
E2E Tests / E2E Interactive - OpenTUI renderer (bun) (push) Blocked by required conditions
E2E Tests / channel-plugin E2E (nightly) (push) Blocked by required conditions
E2E Tests / web-shell Browser Regression (push) Waiting to run
Managed Agent gate / Select the Managed Agent tier (push) Waiting to run
Managed Agent gate / SDK Java () (push) Blocked by required conditions
Managed Agent gate / Managed Agent gate (push) Blocked by required conditions
pnpm store producer / Save pnpm store (push) Waiting to run
pnpm Worktree Smoke / Install (macos-latest) (push) Waiting to run
pnpm Worktree Smoke / Install (ubuntu-latest) (push) Waiting to run
pnpm Worktree Smoke / Install (windows-latest) (push) Waiting to run
SDK Java Contract Open PRs / Re-check open PRs against main (push) Waiting to run
Verify Landlock helper / Native Windows settings and streams (push) Waiting to run
Verify Landlock helper / arm64 (push) Waiting to run
Verify Landlock helper / x64 (push) Waiting to run
Verify Landlock helper / Native Linux CLI boundary (push) Waiting to run
verify Maven repo producer / Save verify Maven repo (push) Waiting to run
* 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 <gary.gq@alibaba-inc.com>

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

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

---------

Co-authored-by: gary.gq <gary.gq@alibaba-inc.com>
2026-10-21 05:34:26 +00:00
Shaojin Wen
7d27f475be
test(managed-agent): keep a suppressed reply suppressed across a reload (FG13f) (#14978)
A MessageDisplay command Hook suppresses the streamed reply; the public
ledger must not carry its text, and after a Harness restart the next model
request's history must not carry it either. The fixture gains a
hook-suppress mode that records the Hook input and answers
{suppressOutput:true}.

Adds the bilingual design note. One cell adds 150 s to the shared fork:
healthy 10012 s, fork 10612 s, Verify 187 minutes, job 290 minutes.
2026-10-21 04:41:03 +00:00
易良
976425cdb9
fix(ci): queue the sdk-java host lock first-come-first-serve (#14743) (#14912)
* fix(ci): queue the sdk-java host lock first-come-first-serve (#14743)

flock(2) does not order its wakeups, so under continuous arrivals one waiter can lose every release and die at the wait budget — repeatedly burning 40, then 60, then 90 minutes per starved lane across at least three hosts. Replace the inline flock --wait at all three acquisition sites with a ticketed queue: every acquirer takes the next sequence number atomically, only the head of line retries the lock, dead owners are reaped, and the lock still releases at the step boundary. The pinned infrastructure-signature error text is preserved.

The .size-baseline records the workflow's new size (smaller than main's, but main itself already exceeds its recorded baseline).

* fix(ci): block the queue head instead of polling the lock

The first live run starved its full 5400 s budget as queue ticket 1: the head polled flock --nonblock while main and older branches still run blocking flock --wait, so every release went to a legacy waiter's kernel wakeup. The head now blocks in five-second slices, re-entering the same wake race on even terms; tickets still order every run that uses this helper.

* fix(ci): serve the fast tier before full-tier holds

The queue bounded the wait by position but a fast-tier PR job still queued behind every full-tier hold ahead of it. Give the fast tier its own class: the head is the first sorted ticket and fast tickets sort first, so a PR job waits at most the hold already running. A normal ticket ages into the fast class after 20 minutes, so continuous PR traffic cannot starve the full tier.

* refactor(ci): keep the lock queue plain FIFO.

Drops the priority/aging classes: a single first-come-first-serve line is simpler to review and reason about. The head still blocks in five-second slices so it re-enters the kernel wake race on even terms with legacy waiters, and dead owners are still reaped. The tradeoff is explicit: a fast-tier job waits its turn behind full-tier holds instead of jumping them.

* fix(ci): stop leaking the host-lock ticket and reap stale orphans

Three bounded defects in the fair-lock helper, all confirmed by executing
it rather than by reading alone:

- The EXIT/TERM/INT traps quoted `${ticket}`, a `local` that is already out
  of scope once the sourcing step's shell exits, so every trap ran
  `rm -f ''` and each successful acquisition left its head ticket behind.
  Drop the traps and leave the queue at acquisition instead: a holder needs
  no place in line once the kernel holds the lock, and SIGKILL runs no trap.
- The ticket was published after `exec 8>&-` released the counter lock, so
  a later arrival could take seq+1, see an empty queue, name itself head and
  win the lock out of arrival order. Publish inside the critical section.
- Orphan liveness was decided solely by `kill -0`, so a ticket whose PID had
  been recycled to a live process was never aged out and, being head, made
  an idle lock unreachable for every job on the host. Age a ticket out on
  mtime alone above 1800s; a live waiter re-touches every ~7s.

Measured on a free lock with a live-PID, 2h-old orphan head ticket:
base burns its full 6023ms budget and exits 1 with the orphan intact;
this commit acquires in 19ms and reaps it.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Patrol-Run: qwen-pr-closeout/jmvhb9cysmc

* style(ci): keep only the load-bearing why in the lock helper comments

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Patrol-Run: qwen-pr-closeout/jmvhb9cysmc

* fix(ci): keep the lock queue head in one blocking wait

The head re-entered the kernel wait queue every five seconds, so a release
reached waiters that stayed blocked first; the head could lose every
release and starve to its budget. Run 39472038337 still burned the full
5400 s as queue ticket 2. Wait once for the remaining budget and log the
remaining time at most once a minute.

A resumed release tag can predate the helper, so both acquisition sites
fall back to the bare lock instead of dying before Maven and wedging the
release. Pin the emitted ::error:: annotation prefix rather than a file
substring a comment can satisfy, and observe the real acquisition order in
the stub.

* fix(ci): name the blocking ticket in the sdk-java lock timeout

The timeout line reported only the dying waiter's own ticket, so a deep
queue and a wedged one produced the same message and neither could be
acted on from the log. Name the head of line, which separates a real
sibling hold from an orphan ticket.

Bring both design docs back to the shipped mechanism: two acquisition
sites, the flock'd counter with no aging path, the 1800 s mtime arm and
the ticket removed at acquisition, plus the operator recovery command.
Refresh the stale .size-baseline entry for sdk-java.yml.

* test(ci): wait for the first ticket instead of a fixed sleep

The FIFO case started the second acquirer 800 ms after the first and relied
on that being enough for A to take sequence 1. On a loaded runner it is not,
and B wins sequence 1, so the case fails on timing rather than behavior.
Poll for A's published ticket instead.

* fix(ci): print the lock wait line before blocking

The wait line was emitted only after `flock` returned, so a head parked
behind a sibling hold printed nothing for its whole budget: run
39528681869's step sat in flock for 40 minutes and was cancelled with an
empty log, which is the opposite of the attribution this change exists to
add. Probe with --nonblock, print the ticket line, then block.

The observability bullet in both design docs now states what the code does.

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Shaojin Wen <szujobs@gmail.com>
2026-10-21 12:21:44 +08:00