Skip to content

fix(sandbox-kubernetes): make SandboxClaim ownership configurable so release can keep the pod alive - #2779

Open
Buktal wants to merge 2 commits into
agentscope-ai:mainfrom
Buktal:fix/sandbox-k8s-claim-owned-option
Open

fix(sandbox-kubernetes): make SandboxClaim ownership configurable so release can keep the pod alive#2779
Buktal wants to merge 2 commits into
agentscope-ai:mainfrom
Buktal:fix/sandbox-k8s-claim-owned-option

Conversation

@Buktal

@Buktal Buktal commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

AgentScope-Java Version

2.0.1 (developed against current main, bf7b7dae)

Description

Fixes #2778.

Background. KubernetesSandboxClient.create() hardcodes claimOwned = true, so KubernetesSandbox.shutdown() terminates the claim on every per-call release. With a shared isolation scope (USER / AGENT / GLOBAL) and the default no-op SandboxExecutionGuard, two concurrent calls resume the same live claim and share one pod; the first call's release then terminates that pod underneath the other in-flight call, whose subsequent exec / file operations all fail. There is currently no supported way to opt out: claimOwned is only ever set inside create().

Change. Claim ownership becomes a client option instead of a hardcoded constant — the existing claimOwned = false code path (shutdown() only closes the connection, pod stays alive) becomes reachable through configuration:

  • KubernetesSandboxClientOptions.claimOwned (Boolean, null = default true), merged like every other option (call-level overrides defaults)
  • KubernetesFilesystemSpec.claimOwned(boolean) fluent setter
  • create() seeds the state from the merged option (state init extracted into package-private initState(...) so the wiring is unit-testable without a cluster)
  • resume() applies an explicitly configured option to the resumed state (applyConfiguredClaimOwnership), so states persisted before the option existed — including slots shared through a distributed AgentStateStore — also honour an operator opting out; when unset, the persisted flag wins
  • IsolationScope's concurrency note previously claimed concurrent same-scope calls "each get their own running container", which is not what the implementation does; it now describes the actual behaviour and points at the two mitigations (execution guard, non-owned claims) — split into its own docs(harness) commit
  • v2 filesystem docs (en/zh): new claimOwned row in the KubernetesFilesystemSpec options table

Default behaviour is unchanged (claimOwned = true). Opting in to false moves claim deletion to the caller (e.g. an idle-eviction policy), which is what same-scope concurrent sharing needs.

How to test. New KubernetesSandboxClientTest (7 cases) covers default-owned, option-driven false, call-level override, resume-time ownership application in both directions, and the spec passthrough; KubernetesSandboxTest gains direct coverage of the shutdown branch (falsecloseConnection() only, trueterminate()); KubernetesSandboxStateSerdeTest gains a claimOwned = false round-trip. Module suite: mvn -pl agentscope-extensions/agentscope-extensions-sandbox/agentscope-extensions-sandbox-kubernetes test — all passing; full reactor mvn test also green.

Checklist

Please check the following items before code is ready to be reviewed.

  • Code has been formatted with mvn spotless:apply
  • All tests are passing (mvn test)
  • Javadoc comments are complete and follow project conventions
  • Related documentation has been updated (e.g. links, examples, etc.)
  • Code is ready for review

@codecov

codecov Bot commented Aug 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.78788% with 7 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ns/sandbox/kubernetes/KubernetesSandboxClient.java 75.00% 6 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant