qwen-code/docs
jinye 2686cad25f
feat(sdk-java): Reconcile and adopt restored Runtime bindings (#12627)
* feat(sdk-java): Reconcile and adopt restored Runtime bindings

A persisted READY binding outlives the Broker process that provisioned
it, but until now a restarted Broker could only fail closed with
runtime_reconciliation_required: the lease was in no process's live set.

For bindings whose request carries a durable provisioner kind, the
Broker now persists a recoverable identity (provision seed encrypted at
rest, scheduler resource handle, attestation generation, last reconcile
time), claims the binding, observes the physical resource through the
new provisioner reconcile operation, re-attests the Runtime identity
through the transport, and only then admits sessions. UNKNOWN and
STARTING observations retry inside an operation deadline that fires
independently of loop progress; a timed-out operation releases its
claim, so a late write is fenced by the operation-generation CAS. A
NOT_FOUND observation marks the binding LOST, and an idle LOST slot is
reclaimed into a fresh generation while an active session keeps the
loss pinned. An identity conflict moves the binding to
RECOVERY_BLOCKED, which never transitions on its own.

Legacy (non-durable) provisioners keep the exact previous behavior:
their restored bindings still fail closed, their provisioning lifecycle
is unchanged, and their claims still lapse instead of being released.
LocalProcessRuntimeProvisioner keeps reporting the legacy kind until a
later slice teaches it ready-record adoption.

Related to #12380.

* fix(sdk-java): Release rejected durable runtimes

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

* fix(sdk-java): Block recovery on attestation conflicts

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

* fix(sdk-java): Release sessions from lost runtimes

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

* fix(sdk-java): Keep ensured resources and guard reconcile single-flight

- Persist the scheduler resource handle before provisioning so a
  retryable failure after ensureResource keeps the binding in
  PROVISIONING and the retry converges on the same resource instead
  of minting a replacement Runtime over an orphaned one.
- Wrap startReconciliation in safeStage so a synchronous claim failure
  removes the published single-flight future instead of hanging every
  later warm/acquire for the binding.

* fix(sdk-java): Bound provisioning and harden durable recovery identity

Durable provisioning now runs under the same operation deadline as
reconciliation, so a parked ensureResource, provision, or attestation call
releases the claim instead of holding the binding open forever, and LOST
reclamation is single-flighted on the binding key with reconciliation so
concurrent warms observe one new generation instead of one spurious
unavailable failure.

requireLiveBinding reads the live-binding map once again, so a concurrent
invalidate cannot turn the domain error into a bare NullPointerException.

The provision seed now also binds the runtime instance of the lease, the
resource handle compares by its canonical encoding so a JSON round trip stays
equal, and the JDBC update no longer re-encrypts the immutable seed on every
renewal tick. Encryption contexts derive from a fixed-width digest of the
binding id so a legal 512-character identifier fits the bound the protector
enforces, the reconciliation backoff can reach its documented 2s cap, the tool
execution table gains the index its binding query needs, and the
provisioner_kind columns match the identifier limit the Java API accepts.

* docs(design): Sync broker docs with durable recovery behavior

The core service design still described the pre-recovery world: an absolute
FAILED write, an unconditional runtime_reconciliation_required, a plaintext
token column, and restart adoption as a non-goal. Split each claim into its
legacy and durable cases, document the encrypted seed and the SecretProtector
key responsibility, add LOST and RECOVERY_BLOCKED to the state model as active
non-terminal states, and scope the reconcile-before-reuse duty of the embedding
service to bindings without durable identity.

* fix(sdk-java): Wait out transient attestation failures and free wedged sessions

Recovery blocked a restored binding on any non-retryable attestation error,
but the transport reports a throttled or incompatible route (429, 408, 404,
a malformed response) as a non-retryable incompatibility too. Only a failure
that is evidence about identity now blocks; anything else leaves the binding
READY so a later attempt adopts it once the transient condition passes,
instead of wedging the row behind an operator.

A Broker killed mid-acquire or mid-release left its Session ACQUIRING or
RELEASING. Both pin a LOST generation, and neither can ever be confirmed by a
Runtime that is proven gone, so the slot stayed wedged with no public API able
to move it. Local settlement now covers any still-active same-generation
session, and a session already RELEASING is settled without another state
transition. A session whose binding is not LOST still fails closed.

Also gives the two retry-count assertions in the recovery tests a 100 ms
operation lease: at 20 ms the deadline (four leases) sat only 30 ms clear of
the 50 ms first backoff, which a loaded macOS runner did not always make.

* docs(design): Correct text that merging main made inaccurate

Adoption re-registers the live binding, so the stale-route guard in the
execution lookup can fail on this base; its comment claimed it could not.

The service core doc still said that a generation which can no longer answer
never blocks its scope. That held only while FAILED was the end of the story:
a LOST generation stays active, so an UNKNOWN execution on one wedges the
scope, and the doc now says so in both languages.

The follow-up list pointed execution-level UNKNOWN reconciliation at #12380,
but reconcileExecution shipped in #12655. What remains is the LOST case.

* docs(design): Cover every unsettled execution in the LOST wedge

The description of a wedged scope named only an UNKNOWN execution, but a crash
leaves the row EXECUTING: nothing moves it to UNKNOWN without a same-key
retry, a cancel or a takeover scan, reconcileExecution answers IN_FLIGHT for
it, and both active-execution queries still count it because they exclude only
SETTLED. Whichever rule eventually settles these has to cover EXECUTING and
DISPATCHING as well, so both documents now say so.

---------

Co-authored-by: jinye.djy <jinye.djy@U-Y37CF7G3-1943.local>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-09-25 03:40:48 +00:00
..
assets feat: support workspace display names (#7179) 2026-07-20 15:16:44 +00:00
design feat(sdk-java): Reconcile and adopt restored Runtime bindings (#12627) 2026-09-25 03:40:48 +00:00
developers docs(tools): add Firecrawl to the web search MCP services (#12646) 2026-09-24 16:00:24 +00:00
e2e-tests refactor(core,cli): rename generic Gemini identifiers to Llm (#10124) 2026-08-28 03:05:49 +00:00
images fix(web-shell): render built-in tag icons (#7024) 2026-07-17 15:33:34 +00:00
plans docs(plans): record why CI test time is bound by module import, not scheduling (#10909) 2026-09-22 15:51:24 +00:00
superpowers feat(cli): reference prior sessions via @ and add completion tabs (#7302) 2026-07-24 06:11:48 +00:00
users docs(conversations-recovery): document non-graceful ACP writer recovery (#12268) 2026-09-24 13:05:05 +00:00
verification fix(core,docs): correct what the deferred-tool bridge made stale or untested (#12355) 2026-09-22 15:44:46 +00:00
_meta.ts feat: refactor docs 2025-12-05 10:51:57 +08:00
index.md fix: lint issues 2025-12-19 15:52:11 +08:00