From c084661d0462ad1c358d61aae048951073d97e27 Mon Sep 17 00:00:00 2001 From: Anycodes <21079031+anycodes@users.noreply.github.com> Date: Sun, 18 Oct 2026 14:39:26 +0000 Subject: [PATCH 1/3] docs: record isolated provider and live storage acceptance --- .agents/README.md | 4 +- .agents/evidence/README.md | 4 +- ...026-10-18-provider-isolation-acceptance.md | 109 ++++++++++++++++++ ...2026-10-18-provider-portability-updates.md | 7 +- 4 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 .agents/evidence/verify/2026-10-18-provider-isolation-acceptance.md rename .agents/notes/{proposed => implemented}/architecture/2026-10-18-provider-portability-updates.md (91%) diff --git a/.agents/README.md b/.agents/README.md index e46fca1..a5d5f10 100644 --- a/.agents/README.md +++ b/.agents/README.md @@ -46,7 +46,7 @@ Move the file and edit `Status:` in the same commit. Required sections and the t - [Bounded MCP binary files](notes/implemented/feature/2026-10-16-mcp-binary-files.md) · [verification](evidence/verify/2026-10-16-mcp-binary-files.md) -- [Provider portability and updates](notes/proposed/architecture/2026-10-18-provider-portability-updates.md) · [verification](evidence/verify/2026-10-18-provider-portability-updates.md) +- [Provider portability and updates](notes/implemented/architecture/2026-10-18-provider-portability-updates.md) · [verification](evidence/verify/2026-10-18-provider-portability-updates.md) - [Independent template deployment metadata](notes/implemented/feature/2026-10-18-template-deploy-feature.md) · [verification](evidence/verify/2026-10-18-template-deploy-feature.md) - [Provider isolation verification](evidence/verify/2026-10-18-provider-complete-isolation.md) @@ -69,3 +69,5 @@ Builtin transport: [direct HTTP](notes/implemented/architecture/2026-10-18-nativ - [Current-host provider integration](evidence/verify/2026-10-18-provider-current-host-checkpoint.md) - [Provider port and file URL boundary checkpoint](evidence/verify/2026-10-18-provider-port-url-boundaries.md) + +- [Current provider isolation and Express acceptance](evidence/verify/2026-10-18-provider-isolation-acceptance.md) diff --git a/.agents/evidence/README.md b/.agents/evidence/README.md index 588732b..530dfe7 100644 --- a/.agents/evidence/README.md +++ b/.agents/evidence/README.md @@ -33,4 +33,6 @@ Evidence of the command-line interface lives in the - [`verify/2026-09-08-real-e2e-verification.md`](verify/2026-09-08-real-e2e-verification.md) - [`verify/2026-10-12-e2e-foundation.md`](verify/2026-10-12-e2e-foundation.md) -- [Provider portability and updates](../notes/proposed/architecture/2026-10-18-provider-portability-updates.md) · [verification](verify/2026-10-18-provider-portability-updates.md) +- [Provider portability and updates](../notes/implemented/architecture/2026-10-18-provider-portability-updates.md) · [verification](verify/2026-10-18-provider-portability-updates.md) + +- [Current provider isolation and Express acceptance](verify/2026-10-18-provider-isolation-acceptance.md) diff --git a/.agents/evidence/verify/2026-10-18-provider-isolation-acceptance.md b/.agents/evidence/verify/2026-10-18-provider-isolation-acceptance.md new file mode 100644 index 0000000..351c9bb --- /dev/null +++ b/.agents/evidence/verify/2026-10-18-provider-isolation-acceptance.md @@ -0,0 +1,109 @@ +# Verification: Provider isolation and current Express acceptance + +- Date: 2026-10-18 +- Result: PASS for the implemented host/adapter isolation and tested Express configuration. Other native backend feature acceptance remains explicitly outside this result. +- Tested implementation: `937eb5edc5330c9afe7577604c1078f22c17f079`; CLI `12f0d693da415e0e3827a319d29d669a83ac090d`, Python `937eb5edc5330c9afe7577604c1078f22c17f079`. +- Delivery: https://github.com/Alibaba-Agent-Sandbox/agent-sandbox/pull/35 and https://github.com/Alibaba-Agent-Sandbox/python-sdk/pull/38. Both were unmerged when this evidence snapshot was written; the final evidence-only head must also pass configured checks before merging. +- Environment: Linux, Node 22.22.2, Python 3.11.15, real Express cn-hangzhou with existing `base` template. Existing credentials stayed in the ignored environment; temporary key material was private and deleted. + +## Observable behavior + +Every lifecycle uses the selected Provider, including bundled Express. Authentication, +cloud SDK/API mapping, template deployment/polling, wire protocol choice, data-plane and +port/file URL formats, gateway headers, backend CLI/AI/configuration metadata remain in +owned adapters. Compatibility exports are explicit facades; neutral Python imports remain +lazy. Async-only providers get E8004 from synchronous URL helpers, and their asynchronous +resolver returns their own URL and headers. Missing hooks never fabricate native behavior. +Created-resource binding failures clean up owned resources; failed connects preserve borrowed ones. + +Bundled update reports the current host release, unknown latest version and matching +upgrade guidance. External Git-plugin update/ref/consent/integrity/rollback behavior is +preserved. Existing Express resources can be reused; replacing an SDK still requires the +documented import/API/configuration adjustments. This is not a zero-change migration claim. + +## Executed checks + +- Both-package Python lint/format/mypy: PASS, 101 client and 56 server modules. +- Latest full Python client: **2177 passed, 24 skipped**, 149.56 seconds. Skips identify optional build/CLI checkout/engine prerequisites; they are not passes. +- Latest local server: **853 passed, 2 failed, 1 skipped**. The two intentional malformed HTTP probes receive intermediary 501/502 responses locally; unchanged assertions pass in all hosted server jobs. Earlier failed attempts remain in separate immutable checkpoints. +- Latest full CLI in the temporary locked-dependency checkout: **3913 passed, 20 failed, 2 skipped**. All 20 failures reproduce against unchanged main after normalizing the Cube no-PTY test name; hosted Node 20/22 passes. No test timeout or malformed-response assertion was weakened. +- CLI source/test/script/E2E snapshot: **563 files, zero content differences**; SHA256 `7e49f73998ee51654f8bd2dd7846bdb051b987e4167012ef709f43eaf8177682`. This separates slow workspace module-scope I/O from execution without increasing test budgets. +- CLI parity ledger: **907 passed, zero failed/skipped, zero missing**; 11 previously moved SDK entries are reported separately. +- CLI strict typecheck/build: PASS. ESLint: zero errors, 248 warnings. npm 10 dry-run contents: PASS. +- Python wheel/sdist build, twine, py.typed and combined clean install/import: PASS. +- New offline CLI capture: **114 cases, zero skipped, 17 documents**, preserved alongside historical captures. +- Linux executable build/version smoke: PASS; SHA256 `8797dbe0bf6b1f3ecac8afb28c37aa2f9f1e38263cb26ac1e7cd50a8d65e34ed`. +- Repository health: CLI **105 pass / 11 historical warnings / zero failures**; SDK **106 pass / 1 historical warning / zero failures**. Hygiene and configured-secret scans: PASS. + +Hosted checks on this owner's tested implementation revision: + +- [Build packages](https://github.com/Alibaba-Agent-Sandbox/python-sdk/actions/runs/39135909258/job/117701432415): PASS +- [server-sdk (Python 3.11)](https://github.com/Alibaba-Agent-Sandbox/python-sdk/actions/runs/39135909258/job/117700250797): PASS +- [server-sdk (Python 3.12)](https://github.com/Alibaba-Agent-Sandbox/python-sdk/actions/runs/39135909258/job/117700250731): PASS +- [No local paths or secrets](https://github.com/Alibaba-Agent-Sandbox/python-sdk/actions/runs/39135909258/job/117700250700): PASS +- [Markdown links](https://github.com/Alibaba-Agent-Sandbox/python-sdk/actions/runs/39135909194/job/117700250688): PASS +- [client-sdk (Python 3.12)](https://github.com/Alibaba-Agent-Sandbox/python-sdk/actions/runs/39135909258/job/117700250674): PASS +- [client-sdk (Python 3.11)](https://github.com/Alibaba-Agent-Sandbox/python-sdk/actions/runs/39135909258/job/117700250659): PASS +- [client-sdk (Python 3.10)](https://github.com/Alibaba-Agent-Sandbox/python-sdk/actions/runs/39135909258/job/117700250629): PASS +- [server-sdk (Python 3.10)](https://github.com/Alibaba-Agent-Sandbox/python-sdk/actions/runs/39135909258/job/117700250482): PASS + +## Real Express acceptance + +Commands used the ignored environment in memory and sanitized output; placeholder values +below describe actual private inputs, not published credential/resource identifiers. + +```sh +python -m pytest -m 'e2e and not e2e_slow' -q -ra +ABX_BIN= node e2e/run.mjs --suite offline +ABX_BIN= node e2e/run.mjs --suite offline,cloud-readonly,cloud-lifecycle,provider-commands-offline,provider-management-cloud +ABX_E2E_VOLUME_MOUNT=1 E2E_VOLUME_TEMPLATE=base python -m pytest test_09_volume_mounts.py -q -ra +ABX_BIN= ABX_E2E_VOLUME_MOUNT=1 ABX_E2E_TEMPLATE=base node e2e/run.mjs --suite volume-mount-cloud +``` + +- Full configured Python E2E after the port changes: **116 passed, 6 skipped, 2 deselected, 1 documented platform xfail**, 422.92 seconds. +- Its skips were four unconfigured native backend environments and two separately gated storage cases. The latter then ran successfully with newly provisioned temporary storage as described below. +- The known xfail remains KI-009: this cloud's Jupyter endpoint returns HTTP 404, so shell fallback cannot return the value of a trailing expression. This is not relabeled as full interpreter parity. +- Combined executable acceptance initially had **142 passed, 2 failed, 1 guarded destructive skip**. Both failures were offline harness region inheritance. Cloud/management cases all passed, including real `/proc` process info and measured system metrics; two owned sandboxes deleted, zero leaked. +- After fixing harness environment isolation, offline acceptance: **61 passed, 1 no-resource leak-check skip**. A regression also proves cloud regions are passed only through the explicit credential map. + +### Fresh real storage and persistence + +Using the user's existing AK/SK authorization, the run created one private OSS Bucket, +one FC-trusted RAM role, one custom policy restricted to that Bucket, one Volume, and +one exclusive API key belonging to the same existing Team. It did not modify that Team +or existing credentials, roles, policies or storage. The temporary key file used mode 0600. + +- Volume reached AVAILABLE and its key's Team identity was checked. +- Current Python HTTP lifecycle formal storage suite: **2 passed in 13.52 seconds**. Both mount tables were checked. A sentinel survived destruction of the first sandbox and recreation in a different sandbox, then was read and removed. +- Current standalone executable formal mount suite: **2 passed** including leak check; one owned sandbox created and removed. The mount roundtrip case took 6557 ms. +- Independent OSS listing confirmed the new Bucket had no residual objects after the suites. +- Temporary infrastructure dependencies were isolated from product/test dependencies: oss2 2.19.1, alibabacloud-ram20150501 1.3.0, alibabacloud-sts20150401 1.2.0 and python-dotenv 1.2.4. An initial dependency install used an incorrect legacy package name; resolution failed before any cloud resource creation, then the correct locked package names installed. + +Official prerequisites were rechecked against [mounting](https://help.aliyun.com/zh/agent-sandbox/mount-oss-volume-1) and [FC role configuration](https://help.aliyun.com/zh/agent-sandbox/create-ram-role). The orchestration remains test tooling outside the product; provisioning is not core backend logic. + +## Cleanup + +The full Python acceptance was followed by an independent SDK listing showing **zero total +sandboxes**. Executable cloud and storage suites each reported zero leaked resources. +Storage tests released their three Python sandboxes and one binary sandbox. The temporary +key was made inactive, deleted and not-found verified; the Volume was deleted and not-found +verified; objects/multipart uploads and the Bucket were removed, with NoSuchBucket verified. + +The initial three RAM policy/role cleanup operations failed. A private recovery ledger +recorded only owned identifiers; a subsequent attempt detached the same owned policy, +deleted it and the role, then verified EntityNotExist for each. The ledger and generated +key file were removed. No failed cleanup is silently counted as a first-attempt pass. + +## Limits and remaining native work + +Native E2B credentials, an authorized CubeAPI, an ACS/ACK container sandbox-manager and +a working OpenSandbox runtime remain unavailable. No Docker or Podman executable is +installed in this restricted environment; the local OpenSandbox bootstrap requires +privileged system installation/mounts outside the writable workspace, which cannot be +performed under the current permissions. These prerequisites were requested and are +not inferred from Express credentials. + +No new native image-factory acceptance, publication, full-region/full-template feature +parity or zero-change SDK substitution is claimed. Optional image-factory PRs stay separate +and unactivated. Historical failures and earlier native gRPC acceptance are preserved as +history; this run verifies the current direct HTTP Express lifecycle. diff --git a/.agents/notes/proposed/architecture/2026-10-18-provider-portability-updates.md b/.agents/notes/implemented/architecture/2026-10-18-provider-portability-updates.md similarity index 91% rename from .agents/notes/proposed/architecture/2026-10-18-provider-portability-updates.md rename to .agents/notes/implemented/architecture/2026-10-18-provider-portability-updates.md index 8cd25a6..04da927 100644 --- a/.agents/notes/proposed/architecture/2026-10-18-provider-portability-updates.md +++ b/.agents/notes/implemented/architecture/2026-10-18-provider-portability-updates.md @@ -1,6 +1,6 @@ # Decision: Describe built-in provider updates and existing Express adoption -Status: proposed +Status: implemented ## Problem @@ -64,3 +64,8 @@ Asynchronous-only discovery fails closed in synchronous helpers. Neutral Python remain lazy; a fresh-process regression prevents built-in auth/wire loading. [Port and file URL boundary checkpoint](../../../evidence/verify/2026-10-18-provider-port-url-boundaries.md). + +Current host/adapter acceptance is complete for the tested Express configuration; see +[final verification](../../../evidence/verify/2026-10-18-provider-isolation-acceptance.md). Hosted checks pass on the tested +implementation revisions. The evidence-only PR head must pass its gates before merge. +Native image factories and unconfigured backend E2E remain separate acceptance work. From b409c6123e60085634c874f22ace078e78807379 Mon Sep 17 00:00:00 2001 From: Anycodes <21079031+anycodes@users.noreply.github.com> Date: Sun, 18 Oct 2026 14:53:19 +0000 Subject: [PATCH 2/3] fix: keep provider metadata and compatibility URLs adapter owned --- .agents/README.md | 2 + .agents/evidence/README.md | 2 + ...6-10-18-provider-convergence-acceptance.md | 74 +++++++++++++++++++ ...2026-10-18-provider-portability-updates.md | 3 + .../alicloud_express/config_metadata.py | 25 +++++++ .../providers/alicloud_express/metadata.py | 2 +- .../providers/config_distribution.py | 14 ++++ .../src/agent_sandbox/transport/config.py | 5 +- .../src/agent_sandbox/utils/bundled_config.py | 42 +++-------- .../test_providers/test_complete_isolation.py | 13 ++++ docs/en/design/provider-isolation.md | 5 ++ docs/zh/design/provider-isolation.md | 4 + 12 files changed, 159 insertions(+), 32 deletions(-) create mode 100644 .agents/evidence/verify/2026-10-18-provider-convergence-acceptance.md create mode 100644 client-sdk/src/agent_sandbox/providers/alicloud_express/config_metadata.py create mode 100644 client-sdk/src/agent_sandbox/providers/config_distribution.py diff --git a/.agents/README.md b/.agents/README.md index 4d527c6..0886684 100644 --- a/.agents/README.md +++ b/.agents/README.md @@ -73,3 +73,5 @@ Builtin transport: [direct HTTP](notes/implemented/architecture/2026-10-18-nativ - [Provider port and file URL boundary checkpoint](evidence/verify/2026-10-18-provider-port-url-boundaries.md) - [Current provider isolation and Express acceptance](evidence/verify/2026-10-18-provider-isolation-acceptance.md) + +- [Final provider convergence acceptance](evidence/verify/2026-10-18-provider-convergence-acceptance.md) diff --git a/.agents/evidence/README.md b/.agents/evidence/README.md index 530dfe7..daa7a6e 100644 --- a/.agents/evidence/README.md +++ b/.agents/evidence/README.md @@ -36,3 +36,5 @@ Evidence of the command-line interface lives in the - [Provider portability and updates](../notes/implemented/architecture/2026-10-18-provider-portability-updates.md) · [verification](verify/2026-10-18-provider-portability-updates.md) - [Current provider isolation and Express acceptance](verify/2026-10-18-provider-isolation-acceptance.md) + +- [Final provider convergence acceptance](verify/2026-10-18-provider-convergence-acceptance.md) diff --git a/.agents/evidence/verify/2026-10-18-provider-convergence-acceptance.md b/.agents/evidence/verify/2026-10-18-provider-convergence-acceptance.md new file mode 100644 index 0000000..d2e0f02 --- /dev/null +++ b/.agents/evidence/verify/2026-10-18-provider-convergence-acceptance.md @@ -0,0 +1,74 @@ +# Verification: Final provider convergence after concurrent branch updates + +- Date: 2026-10-18 +- Result: PASS for convergence regressions, packaging and tested real Express behavior. Latest-head hosted checks remain a separate mandatory merge gate. +- Scope: ordinary branch merge on `8a4c76c7dfaae9e9824c032a5d1683a001c612da` plus the accompanying owned metadata/configuration changes. Source/test snapshot: 233 files, SHA256 `00641b9b5f03b39e43299f1572ac165f6337d55a68890d0fd8065ae6841962bd`. +- Delivery: https://github.com/Alibaba-Agent-Sandbox/agent-sandbox/pull/35 and https://github.com/Alibaba-Agent-Sandbox/python-sdk/pull/38. +- Environment: same locked Linux/Node22/Python3.11 environment as the [earlier acceptance](2026-10-18-provider-isolation-acceptance.md). Secrets remain private; no cloud identifiers are published. + +## Integration and ownership + +A final record push was rejected because another contribution had advanced the shared +branch. Ordinary merges retain those commits, including the provider-owned Docker RUN +rewrite, authentication preflight, canonical auth exports, current native HTTP lifecycle +and independent engineering records. No force push or shared-history replacement occurred. + +The integration had reintroduced wire URL formatting and Express configuration/profile +data into lower utility implementations. The accompanying reconciliation keeps pure data +inside the Express provider; lower utility paths are compatibility exports and generic +distribution composition. Historical URL helpers delegate to owned factories or provider +declared templates. The explicitly selected shared E2B adapter owns its own wire builder. +Neutral image profile types are defined in the CLI model layer and re-exported from the +historical provider path; lower configuration does not import higher runtime types. + +A behavioral regression replaces the compatibility URL rule with an opaque provider-owned +path and proves the public helpers honor it, including literal dollar characters. Fresh +neutral Python import and async-only provider refusal regressions remain passing. + +## Executed verification + +- Merged Python full client: **2178 passed, 24 skipped**, 150.25 seconds. The appended owned-builder regression then passed in the **9-pass** isolation file; **40-pass** volume/isolation run also passed. +- Python package-scoped ruff/format/mypy: PASS, **104 client / 56 server** modules. Wheel/sdist build, twine, py.typed and combined clean install/import: PASS. +- CLI strict typecheck/build: PASS; ESLint zero errors, 250 warnings. Fresh convergence suite: **90 passed** across six actual collected files, including wheel structure, auth preflight, provider boundaries and command regressions. +- CLI final local aggregate: **3924 passed, 21 failed, 2 skipped**. Twenty failures reproduce the previously disclosed network-intermediary baseline. One extra failure was a test reading a compiled entry while a concurrent build removed it. Sequential build then the affected suite passed; the 90-pass convergence run includes this repair. This artifact race is not called a product or environment failure. +- CLI parity ledger: **907 passed, zero failed/skipped/missing**, 11 previously moved SDK entries reported separately. +- New CLI evidence capture: **114 cases, zero skipped, 17 documents**. Historical captures remain unchanged. +- Standalone build/version smoke: PASS; final executable SHA256 `b5b9fea2b33ca167424bb0d59c90ce6cbd62f0f7ca64c4f19a1cc9e5e1f7dca5`. Moving type-only declarations did not change the executable digest. +- npm10 dry-run content validation and both-owner health/hygiene are rerun with this commit; exact outcomes are exposed by its required checks. + +## Real Express rerun + +The merged Python source ran the published platform/lifecycle/commands/files/network/code +E2E files: **58 passed, 1 known xfailed, 1 non-strict xpassed** in 106.20 seconds. The xpass +is KI-008: a one-megabyte upload completed within the existing timeout in this run. It is +network dependent; no timeout changed. KI-009 still records the unavailable native Jupyter +trailing-expression behavior. The earlier 116-pass full run and fresh 2-pass OSS persistence +run remain separate evidence at their exact tested revisions, not relabeled as new runs. + +The merged executable cloud/management scenarios all passed, including real process info +and metrics; **two created sandboxes, zero leaked**. The combined run was **142 pass / 2 fail / +1 guarded skip** because another branch retained older Commander-error expectations while +the actual converter preserved the public `not one of` wording. The corrected assertions +require the complete emitted error, all permitted choices and exit2. Fresh offline rerun: +**61 pass / 1 no-resource leak-check skip**. Production parsing and snapshots were not relaxed. + +## Checkpoint failures and cleanup + +The first focused Python run exposed an ignored retired-engine bytecode directory as a +namespace package (66 pass / 1 fail); a second probe before cleanup had39 pass /1 fail. +Only obsolete ignored `.pyc` files were moved to a task-private temporary backup. No source, +test assertion or user output file was deleted. The unchanged retired-engine regression +then passed, as did the full client aggregate. A first cross-filesystem rename failed +before mutation; the subsequent guarded move succeeded. + +An independent current SDK query after all cloud reruns confirms no sandbox resources +remain. Storage/key/Volume/Bucket/policy/role deletion and not-found recovery from the earlier +same-day storage run are preserved in its immutable evidence. No new storage or key was +created by this convergence smoke. The pre-existing untracked server output remains untouched. + +## Remaining scope + +Latest-head hosted checks and mergeability must be inspected before merging. No required +review/check bypass or package publication is authorized by a local pass. Native E2B, Cube, +container and OpenSandbox prerequisites remain absent; optional native image factories stay +unactivated. This record does not claim all providers or all platform capabilities are live-tested. diff --git a/.agents/notes/implemented/architecture/2026-10-18-provider-portability-updates.md b/.agents/notes/implemented/architecture/2026-10-18-provider-portability-updates.md index 04da927..5c1b413 100644 --- a/.agents/notes/implemented/architecture/2026-10-18-provider-portability-updates.md +++ b/.agents/notes/implemented/architecture/2026-10-18-provider-portability-updates.md @@ -69,3 +69,6 @@ Current host/adapter acceptance is complete for the tested Express configuration [final verification](../../../evidence/verify/2026-10-18-provider-isolation-acceptance.md). Hosted checks pass on the tested implementation revisions. The evidence-only PR head must pass its gates before merge. Native image factories and unconfigured backend E2E remain separate acceptance work. + +[Convergence verification](../../../evidence/verify/2026-10-18-provider-convergence-acceptance.md) records the ordinary remote +merges, provider-owned pure metadata restoration and current Express smoke results. diff --git a/client-sdk/src/agent_sandbox/providers/alicloud_express/config_metadata.py b/client-sdk/src/agent_sandbox/providers/alicloud_express/config_metadata.py new file mode 100644 index 0000000..295e45c --- /dev/null +++ b/client-sdk/src/agent_sandbox/providers/alicloud_express/config_metadata.py @@ -0,0 +1,25 @@ +"""Pure Express configuration metadata. No SDK, engine or cloud calls.""" + +from typing import Any + +from agent_sandbox.utils.config_keys import ( + ALICLOUD_EXPRESS_KEYS, + BUILTIN_PROVIDER_ID, + GENERIC_ENDPOINT_KEYS, +) + +DEFAULT_CONFIG: dict[str, Any] = { + "id": BUILTIN_PROVIDER_ID, + "keys": ALICLOUD_EXPRESS_KEYS, + "inherit": frozenset(GENERIC_ENDPOINT_KEYS), + "derive": { + "sandbox_base_url": "https://api.{region}.e2b.fc.aliyuncs.com", + "sandbox_domain": "{region}.e2b.fc.aliyuncs.com", + }, + "endpoint_defaults": { + "sandbox_base_url": "https://api.cn-hangzhou.e2b.fc.aliyuncs.com", + "sandbox_domain": "cn-hangzhou.e2b.fc.aliyuncs.com", + }, + "legacy_fields": frozenset({"region", "access_key_id", "access_key_secret"}), + "omit_default_options": True, +} diff --git a/client-sdk/src/agent_sandbox/providers/alicloud_express/metadata.py b/client-sdk/src/agent_sandbox/providers/alicloud_express/metadata.py index 03941fd..201206d 100644 --- a/client-sdk/src/agent_sandbox/providers/alicloud_express/metadata.py +++ b/client-sdk/src/agent_sandbox/providers/alicloud_express/metadata.py @@ -2,8 +2,8 @@ from typing import Any +from agent_sandbox.providers.alicloud_express.config_metadata import DEFAULT_CONFIG from agent_sandbox.providers.shared.e2b.url import envd_url -from agent_sandbox.utils.bundled_config import DEFAULT_CONFIG def _legacy_ports(context: Any) -> Any: diff --git a/client-sdk/src/agent_sandbox/providers/config_distribution.py b/client-sdk/src/agent_sandbox/providers/config_distribution.py new file mode 100644 index 0000000..b576692 --- /dev/null +++ b/client-sdk/src/agent_sandbox/providers/config_distribution.py @@ -0,0 +1,14 @@ +"""Distribution composition of pure provider-owned L0 data; no runtime adapters.""" + +from typing import Any + +from agent_sandbox.providers.alicloud_express.config_metadata import ( + DEFAULT_CONFIG as DEFAULT_CONFIG, +) + +BUNDLED_CONFIGS: tuple[dict[str, Any], ...] = (DEFAULT_CONFIG,) +BUNDLED_KEYS = tuple(key for entry in BUNDLED_CONFIGS for key in entry["keys"]) + + +def bundled_config(provider_id: str) -> dict[str, Any] | None: + return next((entry for entry in BUNDLED_CONFIGS if entry["id"] == provider_id), None) diff --git a/client-sdk/src/agent_sandbox/transport/config.py b/client-sdk/src/agent_sandbox/transport/config.py index 6b88ccf..99d99e7 100644 --- a/client-sdk/src/agent_sandbox/transport/config.py +++ b/client-sdk/src/agent_sandbox/transport/config.py @@ -131,7 +131,10 @@ def build_envd_url(self, sandbox_id: str) -> str: 格式: https://{ENVD_PORT}-{sandbox_id}.{sandbox_domain} """ - return f"https://{ENVD_PORT}-{sandbox_id}.{self.sandbox_domain}" + builder = resolve_provider_schema(BUILTIN_PROVIDER_ID).legacy_url_builder + if builder is None: + raise RuntimeError("The distribution does not provide the legacy URL convention.") + return builder(sandbox_id, self.sandbox_domain) # --------------------------------------------------------------------------- diff --git a/client-sdk/src/agent_sandbox/utils/bundled_config.py b/client-sdk/src/agent_sandbox/utils/bundled_config.py index 5b16560..5e5e49d 100644 --- a/client-sdk/src/agent_sandbox/utils/bundled_config.py +++ b/client-sdk/src/agent_sandbox/utils/bundled_config.py @@ -1,32 +1,14 @@ -"""Pure Express configuration metadata. No SDK, engine or cloud calls.""" +"""Compatibility exports of the pure distribution metadata composition.""" -from typing import Any - -from agent_sandbox.utils.config_keys import ( - ALICLOUD_EXPRESS_KEYS, - BUILTIN_PROVIDER_ID, - GENERIC_ENDPOINT_KEYS, +from agent_sandbox.providers.config_distribution import ( + BUNDLED_CONFIGS as BUNDLED_CONFIGS, +) +from agent_sandbox.providers.config_distribution import ( + BUNDLED_KEYS as BUNDLED_KEYS, +) +from agent_sandbox.providers.config_distribution import ( + DEFAULT_CONFIG as DEFAULT_CONFIG, +) +from agent_sandbox.providers.config_distribution import ( + bundled_config as bundled_config, ) - -DEFAULT_CONFIG: dict[str, Any] = { - "id": BUILTIN_PROVIDER_ID, - "keys": ALICLOUD_EXPRESS_KEYS, - "inherit": frozenset(GENERIC_ENDPOINT_KEYS), - "derive": { - "sandbox_base_url": "https://api.{region}.e2b.fc.aliyuncs.com", - "sandbox_domain": "{region}.e2b.fc.aliyuncs.com", - }, - "endpoint_defaults": { - "sandbox_base_url": "https://api.cn-hangzhou.e2b.fc.aliyuncs.com", - "sandbox_domain": "cn-hangzhou.e2b.fc.aliyuncs.com", - }, - "legacy_fields": frozenset({"region", "access_key_id", "access_key_secret"}), - "omit_default_options": True, -} - -BUNDLED_CONFIGS: tuple[dict[str, Any], ...] = (DEFAULT_CONFIG,) -BUNDLED_KEYS = tuple(key for entry in BUNDLED_CONFIGS for key in entry["keys"]) - - -def bundled_config(provider_id: str) -> dict[str, Any] | None: - return next((entry for entry in BUNDLED_CONFIGS if entry["id"] == provider_id), None) diff --git a/client-sdk/tests/test_providers/test_complete_isolation.py b/client-sdk/tests/test_providers/test_complete_isolation.py index 883ef2a..a8b5dc5 100644 --- a/client-sdk/tests/test_providers/test_complete_isolation.py +++ b/client-sdk/tests/test_providers/test_complete_isolation.py @@ -197,3 +197,16 @@ async def build_infra(self, config): sandbox.server_at() finally: await sandbox.kill() + + +def test_legacy_config_url_uses_the_composed_owned_builder(monkeypatch): + from agent_sandbox.providers.alicloud_express.metadata import CONFIG_METADATA + + monkeypatch.setitem( + CONFIG_METADATA, + "legacy_url_builder", + lambda sandbox_id, domain: f"https://{domain}/owned/{sandbox_id}", + ) + assert TransportConfig(sandbox_domain="owned.example").build_envd_url("opaque") == ( + "https://owned.example/owned/opaque" + ) diff --git a/docs/en/design/provider-isolation.md b/docs/en/design/provider-isolation.md index c3c5237..d4d1172 100644 --- a/docs/en/design/provider-isolation.md +++ b/docs/en/design/provider-isolation.md @@ -59,3 +59,8 @@ URL happens to use HTTP. The core never constructs `/files` routes for foreign p Neutral Python transport/protocol imports do not load built-in authentication or wire adapters. Public compatibility imports resolve lazily when explicitly requested. + +Pure bundled configuration, image and legacy URL metadata remains provider-owned. +Lower configuration reads its declarative data through distribution composition and +compatibility exports; it does not import authentication or runtime adapters. Compatibility +URL helpers delegate to declared templates or the composed owned builder. diff --git a/docs/zh/design/provider-isolation.md b/docs/zh/design/provider-isolation.md index 3c4a63e..d7803f1 100644 --- a/docs/zh/design/provider-isolation.md +++ b/docs/zh/design/provider-isolation.md @@ -53,3 +53,7 @@ Provider 应调用 `await sandbox.network.resolve(port)`;同步辅助方法返 Python 中立传输和协议模块的导入不会加载内置认证或具体协议;显式请求历史兼容 导入时再延迟解析。 + +内置配置、镜像和历史 URL 规则的纯元数据仍由 Provider 维护。底层配置通过发行版 +组合与兼容导出读取声明数据,不导入认证或运行时适配器。兼容 URL 方法委托给声明的 +模板或已组合的 Provider 构造函数。 From 1a33b4c5816ad9fcf2a679a4842c56b4cee347c0 Mon Sep 17 00:00:00 2001 From: Anycodes <21079031+anycodes@users.noreply.github.com> Date: Sun, 18 Oct 2026 14:57:20 +0000 Subject: [PATCH 3/3] docs: verify provider ownership against merged main --- .agents/README.md | 2 + .agents/evidence/README.md | 2 + ...-10-18-provider-owned-metadata-followup.md | 44 +++++++++++++++++++ ...2026-10-18-provider-portability-updates.md | 4 ++ 4 files changed, 52 insertions(+) create mode 100644 .agents/evidence/verify/2026-10-18-provider-owned-metadata-followup.md diff --git a/.agents/README.md b/.agents/README.md index 0886684..50c0faa 100644 --- a/.agents/README.md +++ b/.agents/README.md @@ -75,3 +75,5 @@ Builtin transport: [direct HTTP](notes/implemented/architecture/2026-10-18-nativ - [Current provider isolation and Express acceptance](evidence/verify/2026-10-18-provider-isolation-acceptance.md) - [Final provider convergence acceptance](evidence/verify/2026-10-18-provider-convergence-acceptance.md) + +- [Provider-owned metadata follow-up](evidence/verify/2026-10-18-provider-owned-metadata-followup.md) diff --git a/.agents/evidence/README.md b/.agents/evidence/README.md index daa7a6e..ebda94a 100644 --- a/.agents/evidence/README.md +++ b/.agents/evidence/README.md @@ -38,3 +38,5 @@ Evidence of the command-line interface lives in the - [Current provider isolation and Express acceptance](verify/2026-10-18-provider-isolation-acceptance.md) - [Final provider convergence acceptance](verify/2026-10-18-provider-convergence-acceptance.md) + +- [Provider-owned metadata follow-up](verify/2026-10-18-provider-owned-metadata-followup.md) diff --git a/.agents/evidence/verify/2026-10-18-provider-owned-metadata-followup.md b/.agents/evidence/verify/2026-10-18-provider-owned-metadata-followup.md new file mode 100644 index 0000000..65c7761 --- /dev/null +++ b/.agents/evidence/verify/2026-10-18-provider-owned-metadata-followup.md @@ -0,0 +1,44 @@ +# Verification: Provider-owned metadata follow-up + +- Date: 2026-10-18 +- Result: PASS for failing-before/passing-after ownership regression and previously recorded convergence checks. Current-head hosted checks remain the merge gate. +- Tested implementation: `b3db77c1812c4d9a9accbdaa1afdf08f3e222ebd`. Negative-control merged main: `13b214b334b1dba26c46f94feea6f4699d5038cb`. +- Issue: https://github.com/Alibaba-Agent-Sandbox/python-sdk/issues/66 +- PR: https://github.com/Alibaba-Agent-Sandbox/python-sdk/pull/67 +- Environment: Linux, Node22.22.2 / Python3.11.15. The negative controls use no credentials or real network services. + +## Negative and positive controls + +Temporary shared clones checked out the actual merged main revisions. Each isolated +process replaced the provider-owned compatibility URL rule with an opaque path and +required the public TransportConfig helper to return that path. + +| Owner | Unchanged merged main | Fixed implementation | +| --- | --- | --- | +| CLI | Expected assertion failure, exit1 | PASS, exit0 | +| Python | Expected assertion failure, exit1 | PASS, exit0 | + +The probes exercise observable routing, not source-text matching. The committed CLI +regression also preserves literal dollar characters; the committed Python regression +patches the composed owned builder. Neutral-import and async-only port/file refusal +regressions remain unchanged. + +## Delivery context and checks + +The original isolation PRs #35/#38 merged during parallel completion work. A guarded push +had been rejected rather than replacing another contributor's history. Their source was +retained through ordinary merges; this follow-up uses its own branch/Issue/PR and includes +only the remaining metadata/rule ownership repair, typed neutral contract, translations +and exact dated records. No closed PR was reopened and no protected/default branch was pushed. + +Detailed executed checks and real Express acceptance are preserved in +[convergence acceptance](2026-10-18-provider-convergence-acceptance.md). Latest local +full client2178 pass/24 skip, CLI90-pass convergence,907-pass parity ledger, package +checks,114-case capture and cloud smoke are explicitly scoped there. Both-owner health +and hygiene checks were successful; configured-secret scanning ran before each commit. +The earlier fresh storage/persistence acceptance and full116-pass cloud suite remain +at their original tested revisions in [acceptance](2026-10-18-provider-isolation-acceptance.md). + +The only subsequent source change is documentation/evidence; required hosted checks must +pass on that final head before either follow-up merges. Native backend credentials/runtime +limitations and the known Jupyter xfail remain disclosed. No package release is claimed. diff --git a/.agents/notes/implemented/architecture/2026-10-18-provider-portability-updates.md b/.agents/notes/implemented/architecture/2026-10-18-provider-portability-updates.md index 5c1b413..c696f6b 100644 --- a/.agents/notes/implemented/architecture/2026-10-18-provider-portability-updates.md +++ b/.agents/notes/implemented/architecture/2026-10-18-provider-portability-updates.md @@ -72,3 +72,7 @@ Native image factories and unconfigured backend E2E remain separate acceptance w [Convergence verification](../../../evidence/verify/2026-10-18-provider-convergence-acceptance.md) records the ordinary remote merges, provider-owned pure metadata restoration and current Express smoke results. + +The final owner follow-up is tracked in https://github.com/Alibaba-Agent-Sandbox/python-sdk/issues/66 and +https://github.com/Alibaba-Agent-Sandbox/python-sdk/pull/67; [negative controls](../../../evidence/verify/2026-10-18-provider-owned-metadata-followup.md) +prove both merged-main failures and repaired adapter-rule delegation.