From e4288c4a449275ab608d378c3bf4ba85ae0c61e0 Mon Sep 17 00:00:00 2001 From: CleverThis Date: Wed, 8 Apr 2026 15:50:13 +0000 Subject: [PATCH] docs(spec): correct SandboxStrategy protocol name, write() return type, and registration config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix three inaccuracies in the Custom Sandbox Strategies section: 1. Rename SandboxStrategy to SandboxStrategyProtocol to match the implementation in sandbox_strategy.py (Protocol suffix is the correct Python convention for structural protocols) 2. Correct write() return type from Change to DiffEntry — Change does not exist in the sandbox strategy module; DiffEntry is the actual Pydantic model used 3. Replace vague registration description with concrete TOML config example showing sandbox.custom_strategies..module and .class keys, plus YAML resource type reference All corrections verified against: src/cleveragents/domain/models/core/sandbox_strategy.py ISSUES CLOSED: #4523 --- docs/specification.md | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/docs/specification.md b/docs/specification.md index dbe7bd381..2b99c7958 100644 --- a/docs/specification.md +++ b/docs/specification.md @@ -46531,11 +46531,11 @@ New backends are registered via configuration: The sandbox layer supports custom isolation strategies for specialized resource types: -
class SandboxStrategy(Protocol):
+
class SandboxStrategyProtocol(Protocol):
     """Interface for sandbox isolation strategies."""
     def create(self, plan_id: str, resource: Resource) -> SandboxRef: ...
     def read(self, ref: SandboxRef, path: str) -> bytes: ...
-    def write(self, ref: SandboxRef, path: str, content: bytes) -> Change: ...
+    def write(self, ref: SandboxRef, path: str, content: bytes) -> DiffEntry: ...
     def diff(self, ref: SandboxRef) -> DiffView: ...
     def commit(self, ref: SandboxRef) -> None: ...
     def rollback(self, ref: SandboxRef) -> None: ...
@@ -46544,7 +46544,31 @@ The sandbox layer supports custom isolation strategies for specialized resource
     def cleanup(self, ref: SandboxRef) -> None: ...
 
-Custom strategies are mapped to resource types via the resource type configuration's `sandbox_strategy` field, or globally via `sandbox.strategy` config. +Custom strategies are registered via configuration and then referenced by name in the resource type's `sandbox_strategy` field: + +```toml +# config.toml — register the custom strategy +[sandbox.custom_strategies.my-strategy] +module = "cleveragents.extensions.my_module" +class = "MySandboxClass" +``` + +!!! warning "Module prefix security guard" + The sandbox plugin loader only imports modules whose fully-qualified + name starts with an allowed prefix. The default allowlist is + `("cleveragents.",)`, so the example above uses a + `cleveragents.extensions.*` module. If you need to load strategies + from another namespace (for example, `mycompany.sandbox.*`), extend + the registry's `allowed_prefixes` configuration per + [Development › Custom Sandbox Strategy Registration](development/custom_sandbox_strategy.md). + Otherwise the loader raises a `PluginLoadError` at startup. + +```yaml +# resource-types/my-resource.yaml — reference the strategy by name +resource_type: + name: local/my-resource + sandbox_strategy: my-strategy +``` #### ACMS Extensions -- 2.52.0