Files
qwen-code/packages/sdk-java
Shaojin Wenandgithub-actions[bot] 186193e250 fix(managed-agent): settle worktree child runs after their merge (#13753 I2 follow-up) (#13872)
* fix(managed-agent): settle worktree child runs after their merge (#13753 I2 follow-up)

Follows up the review deferrals of #13841.

A stopped worktree run kept its child Workspace. The stop arm (H4f)
settled the run cancelled without a finish request, so the row stayed
ready with the worktree on disk. It now asks for the discard before
its close_scope, or for the merge when the child's task Turn had
completed before the stop.

A failure was told before the merge landed. The over-bound, give-up
and later-failed-Turn arms settled the run failed while the merge they
asked for ran afterwards. A merge the relay asked for now holds every
settlement of the run (a failure, a stop or a give-up, not only the
result) until the row records its outcome. A child whose task Turn
completed keeps its work when a later message turn fails, its message
wait runs out or a stop cancels it, and the relay records that merge
as soon as it sees the task Turn of a bound child completed, so a
parent's close meanwhile pins the work. The foreground answer and the
recovery gap fill of a started worktree run that failed or was
cancelled end with a line telling the parent's model to inspect its
Workspace and where unlanded work is kept: the record has no receipt
to carry the outcome.

A merge waited on every heartbeat on a host that runs no child
Workspace steps. It now waits at the close-debt cadence there, as on a
host without the close capability, and the merge is asked even where
the child cannot be closed yet.

A parent's close discarded a completed child's work unpinned when its
discard replaced a merge that had not started, or one that ended
blocked before its pin. Such a discard is recorded as discard_pinned
and pins the child's result before removing the worktree. The pin
never holds the discard back: when no result can be taken (a
non-retryable refusal, or a failure on the last retry) the discard
goes on as it did before.

No contract change and no migration: discard_pinned is a new value of
the existing finish_request column.

* fix(managed-agent): settle lost-creation worktree runs without an unbound finish (#13872)

Review follow-ups for the child workspace settlement round:

- stopChild and the give-up chain never record a child Workspace finish
  on a row whose child was never bound (a lost creation answer): the stop
  binds the lineage-named child first, and the give-up discards instead
  of asking for a merge it cannot wait for without re-entering itself.
- The ended-run workspace line claims the merge's ordering, never its
  landing (a conflicted, blocked or pinned-away merge means the work did
  not land); both render sites now share childRunEndedText.
- The owed-merge wait logs what it holds for and no longer re-reads the
  child result text or re-asks the merge on every pass.
- One isDiscard predicate for the two discard spellings, one pinResult
  for the two take-and-pin sites, a witness for capable(), and the
  discard-pin fallback now logs the full key set and records last_error.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-11 11:58:52 +00:00
..