diff --git a/CHANGELOG.md b/CHANGELOG.md index a456771..6fb79ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +- add three validated AnyCap explanatory diagrams and two deterministic contract diagrams; +- add text equivalents, visual provenance, integrity hashes, multi-size validation evidence, and + generated-image metadata scanning. + ## 0.1.0 - 2026-09-02 Initial public MVP: diff --git a/DOCS-INDEX.md b/DOCS-INDEX.md index e53466b..7a5df65 100644 --- a/DOCS-INDEX.md +++ b/DOCS-INDEX.md @@ -4,7 +4,7 @@ authority: canonical status: canonical title: Sandbox Runtime API documentation index genre: spec -last_verified: 2026-09-02 +last_verified: 2026-09-03 --- # Documentation Index @@ -36,6 +36,7 @@ network policy enforcement, snapshots, PTY, and port forwarding remain outside t - [Local Provider](docs/providers/local.md) - [Testing and conformance](docs/testing.md) - [Clean-room policy](docs/clean-room-policy.md) +- [Visual source and validation register](docs/visuals/README.md) ## Process and release evidence diff --git a/README.md b/README.md index ea25676..2408138 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,12 @@ tools. The project standardizes portable lifecycle and capability semantics. It is not a hosted sandbox platform, an agent framework, or an open-source distribution of any private system. +![统一 Sandbox 运行时:应用通过 SDK、HTTP/SSE 或 CLI 进入可移植核心,再由 Provider SPI 连接实现。](docs/assets/runtime-overview.png) + +The access methods converge on one portable runtime boundary. Provider implementations remain +replaceable behind a single SPI; the dashed future Provider is a roadmap extension, not part of the +v0.1 delivery. + ## Why Agent applications need similar execution primitives but encounter provider-specific APIs for @@ -27,19 +33,6 @@ This project separates those concerns into: - provider conformance checks; - future transport mappings and client SDKs. -```text -Application or Harness Runtime - | - Sandbox Runtime API - | - +--------+---------+----------+ - | | | - Local Mock Future custom - Provider Provider Provider - | - sandbox agent -``` - ## Relationship to Harness Runtime API [`harness-runtime-api`](https://github.com/capa-cloud/harness-runtime-api) standardizes how an diff --git a/README.zh-CN.md b/README.zh-CN.md index c922d7a..d2378a3 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -13,6 +13,11 @@ Sandbox Runtime API `v0.1` 是一个独立设计、Provider 中立的公共契 项目只标准化可移植的生命周期和能力语义。它不是托管 Sandbox 平台,不是 Agent 框架,也不是 任何私有系统的开源发行版。 +![统一 Sandbox 运行时:应用通过 SDK、HTTP/SSE 或 CLI 进入可移植核心,再由 Provider SPI 连接实现。](docs/assets/runtime-overview.png) + +SDK、HTTP/SSE 和 CLI 最终汇入同一个可移植 Runtime;具体实现隐藏在唯一 Provider SPI 后面。 +虚线的未来 Provider 只是扩展方向,不属于 v0.1 已交付能力。 + ## 解决什么问题 Agent 应用通常需要相似的执行能力,但不同 Provider 对生命周期、就绪、命令、文件、终端、 @@ -25,19 +30,6 @@ Agent 应用通常需要相似的执行能力,但不同 Provider 对生命周 - Provider 一致性测试; - 后续的传输协议映射和客户端 SDK。 -```text -应用或 Harness Runtime - | - Sandbox Runtime API - | - +-------+--------+----------+ - | | | -Local Mock Future custom -Provider Provider Provider - | - sandbox agent -``` - ## 与 Harness Runtime API 的关系 [`harness-runtime-api`](https://github.com/capa-cloud/harness-runtime-api) 规范应用如何控制 Agent diff --git a/docs/assets/capability-preflight.png b/docs/assets/capability-preflight.png new file mode 100644 index 0000000..6ce0111 Binary files /dev/null and b/docs/assets/capability-preflight.png differ diff --git a/docs/assets/lifecycle-state-machine.svg b/docs/assets/lifecycle-state-machine.svg new file mode 100644 index 0000000..a1d2fab --- /dev/null +++ b/docs/assets/lifecycle-state-machine.svg @@ -0,0 +1,77 @@ + + Sandbox 生命周期与代际隔离 + 主路径从 requested 到 ready,可暂停和恢复;非终态可终止;terminated 仅能通过 recreate 进入下一代 requested。 + + + + + + + + + + + Sandbox 生命周期与 generation fencing + 状态属于逻辑 Sandbox;generation 标识一次具体实例 + + 创建与运行 + + requested + + starting + + ready + + + + + + 暂停与恢复 + + pausing + + paused + + resuming + + + + + + + + + 恢复后回到 ready + + + failed + + + Provider 错误 + + + 可终止来源 + requested · starting · ready · pausing · paused · resuming · failed + 终止请求保持当前 generation + + terminating + + terminated + + + + + + + + recreate · generation + 1 + 不变量:旧 generation 的生命周期、命令与文件请求不能作用于新实例。 + diff --git a/docs/assets/local-provider-boundary.svg b/docs/assets/local-provider-boundary.svg new file mode 100644 index 0000000..6c3c39f --- /dev/null +++ b/docs/assets/local-provider-boundary.svg @@ -0,0 +1,65 @@ + + Local Provider 的文件边界与命令风险 + 文件 API 被限制在资源目录内,但命令进程继承当前操作系统用户权限,因此 Local Provider 不是安全 Sandbox。 + + + + + + + + + + + Local Provider:文件 API 有边界,命令执行没有安全隔离 + + + 宿主操作系统 · 当前用户权限 + + + Local Provider 资源目录 + + 文件 API + + 路径与大小校验 + 相对路径 · realpath · no-follow + + Sandbox 文件 + 每个 generation 独立目录 + + + + + 文件接口拒绝越界与符号链接目标 + + + 命令进程 + shell: false,但仍是宿主进程 + + + cwd + + + 宿主文件系统 + + 网络 + + 凭据与服务 + 若当前用户可访问 + + + + + + + + + Local Provider ≠ 安全 Sandbox:禁止执行不可信或 AI 生成代码 + diff --git a/docs/assets/provider-conformance.png b/docs/assets/provider-conformance.png new file mode 100644 index 0000000..4ccdf86 Binary files /dev/null and b/docs/assets/provider-conformance.png differ diff --git a/docs/assets/runtime-overview.png b/docs/assets/runtime-overview.png new file mode 100644 index 0000000..57fd2dc Binary files /dev/null and b/docs/assets/runtime-overview.png differ diff --git a/docs/providers/local.md b/docs/providers/local.md index 4dad476..fa5d61b 100644 --- a/docs/providers/local.md +++ b/docs/providers/local.md @@ -4,7 +4,7 @@ authority: reference status: active title: Local Provider boundary genre: primer -last_verified: 2026-09-02 +last_verified: 2026-09-03 --- # Local Provider @@ -23,6 +23,13 @@ working directory, but command arguments are not a kernel security boundary. Never run untrusted or AI-generated code with this Provider. +![Local Provider 安全边界:文件 API 受资源目录限制,但命令进程仍拥有当前宿主用户权限。](../assets/local-provider-boundary.svg) + +Text equivalent: file API requests pass sandbox-relative path, real-path, symbolic-link, and size +checks before reaching files inside one generation directory. Commands start with that directory as +their working directory but remain ordinary host processes and may access anything available to the +current OS user. + ## Implemented capability - bounded non-interactive command execution; diff --git a/docs/testing.md b/docs/testing.md index efc0518..8aa9435 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -4,7 +4,7 @@ authority: reference status: active title: Testing and provider conformance genre: how-to -last_verified: 2026-09-02 +last_verified: 2026-09-03 --- # Testing and Provider Conformance @@ -38,6 +38,8 @@ by the public-content scan and production dependency audit. ## Conformance runner +![Provider conformance:先验证清单与就绪,再并列检查命令和文件,校验结构并清理资源。](assets/provider-conformance.png) + `runProviderConformance(provider, options)` checks behavior declared by the Provider manifest. A Provider that declares `commandExecution` must supply `options.commandRequest` with a safe command known to exist in that runtime; the portable core does not assume POSIX utilities or a particular @@ -45,5 +47,9 @@ language runtime. Each invocation uses a unique synthetic resource identity and check means the Provider must not claim compatibility. Passing conformance does not certify isolation, production availability, or performance. +Text equivalent: each run uses a unique synthetic resource, validates `describe`, `provision`, and +bounded readiness, checks declared command and file behavior as independent cases, validates complete +result shapes, and calls `terminate` before reporting pass or fail. + Provider-specific real-account tests must be opt-in, use environment-provided credentials, and stay outside default CI. diff --git a/docs/visuals/README.md b/docs/visuals/README.md new file mode 100644 index 0000000..c4734b0 --- /dev/null +++ b/docs/visuals/README.md @@ -0,0 +1,92 @@ +--- +id: visual-source-register +authority: reference +status: active +title: Visual source and validation register +genre: reference +last_verified: 2026-09-03 +--- + +# Visual Source and Validation Register + +Images explain the public contract but do not replace the normative text, TypeScript types, or +OpenAPI document. All visuals use only concepts already present in this repository. + +## Generation receipt + +- producer: AnyCap CLI `0.6.1` with `gpt-image-2`; +- generated: 2026-09-03; +- assurance: T1 validated explanation; +- visible language: Simplified Chinese; +- style: flat white technical canvas, neutral gray, restrained blue, no logos or gradients; +- retained metadata: model and fact graph only; account metadata and request identifiers are omitted. + +## Runtime overview + +- viewer question: How do clients reach different Provider implementations through one portable API? +- takeaway: SDK, HTTP/SSE, and CLI converge on the portable runtime and cross one Provider SPI. +- nodes: application or Agent Harness; combined SDK/HTTP/SSE/CLI access layer; Sandbox Runtime API; + lifecycle, command, file, and event operations; Provider SPI; Mock Provider; Local Provider; future + Provider. +- edges: application to the access layer; access layer to the runtime; runtime to the Provider SPI; + SPI to peer Provider implementations. +- boundaries: portable core; Provider implementations. +- forbidden: cloud logos, private deployment topology, direct client-to-Provider calls, or presenting + a future Provider as shipped in v0.1. +- asset: [`runtime-overview.png`](../assets/runtime-overview.png). + +## Capability preflight + +- viewer question: Why must capability negotiation happen before allocation? +- takeaway: client requirements and the Provider manifest meet at preflight; unsupported requests + fail before allocation. +- nodes: client requirements; `requiredCapabilities`; runtime preflight; `Provider Manifest`; + supported branch; allocation; unsupported branch; `unsupported_capability`; pre-allocation failure. +- edges: requirements and manifest to preflight; supported branch to allocation; unsupported branch + to error and pre-allocation failure. +- forbidden: implying that a capability certifies security, health, SLO, or cross-Provider parity. +- asset: [`capability-preflight.png`](../assets/capability-preflight.png). + +## Provider conformance + +- viewer question: What evidence supports a Provider capability claim? +- takeaway: conformance checks manifest, bounded readiness, declared behaviors, cleanup, and complete + result shapes. The adjacent text owns the unique synthetic-resource requirement. +- nodes: Provider adapter; `describe`; `provision`; observe until `ready`; command probe; file + round-trip; complete-shape validation; bounded timeout; `terminate`; pass or fail. +- edges: setup flows through describe, provision, and readiness; command and file probes are peers; + both join shape validation; all paths reach cleanup before the result. +- forbidden: serializing the command and file probes, claiming production certification, real account + identifiers, or a universal probe command. +- asset: [`provider-conformance.png`](../assets/provider-conformance.png). + +## Exact deterministic visuals + +- [`lifecycle-state-machine.svg`](../assets/lifecycle-state-machine.svg) is generated from the state + transitions in [`spec/runtime-model.md`](../../spec/runtime-model.md). +- [`local-provider-boundary.svg`](../assets/local-provider-boundary.svg) is generated from the Local + Provider behavior and security warnings in [`docs/providers/local.md`](../providers/local.md). + +These two visuals are deterministic because state and security boundaries must not depend on +generative interpretation. + +## Acceptance evidence + +- both candidates for each AnyCap visual were inspected at original 2048×1152 resolution; +- the retained three images passed an independent AnyCap image-read audit for exact text, edges, + boundaries, and peer relationships with zero critical mismatch; +- rejected candidates are not retained because they contained misspellings, extra text, a wrong + boundary, or a missing cleanup step; +- generated PNG metadata was stripped before repository inclusion and scanned for request IDs, + account metadata, local paths, credentials, and internal identifiers; +- deterministic SVGs were rendered at 1600×900 and inspected for legibility and arrow direction. + +## Asset integrity + +| Asset | SHA-256 | +| --- | --- | +| `capability-preflight.png` | `b81e0b5bc1f1f7384abe4b1bd269e9f33542498631700bfa4bcde003959702a5` | +| `lifecycle-state-machine.svg` | `24226bd238c76efe4b1e5b59534dff71fdf6d9d6b99b41c33235e2260c112e65` | +| `local-provider-boundary.svg` | `a43e86f0dfe61f88273e7184a866512d1bd705d483828f8101dc2412ad247aa8` | +| `provider-conformance.png` | `c0b691c8c87f5da57de2db77c9dee7fba7426846a67bb91c024067e07de47fe8` | +| `runtime-overview.png` | `e78de10f7ab408f4b9c1b3e6ed2140ad04c13703e3f7e5c20da597779feec19e` | diff --git a/scripts/scan-public.sh b/scripts/scan-public.sh index c41e148..8a76530 100644 --- a/scripts/scan-public.sh +++ b/scripts/scan-public.sh @@ -37,6 +37,17 @@ scan 'credential-shaped content' \ scan 'local absolute path or private-network literal' \ '(/Users/[A-Za-z0-9._-]+|/home/[A-Za-z0-9._-]+|https?://[^/[:space:]]+\.(internal|local)(/|[[:space:]]|$)|(^|[^0-9])(10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}|192\.168\.[0-9]{1,3}\.[0-9]{1,3})([^0-9]|$))' +if [[ -d "$root/docs/assets" ]]; then + image_metadata=$(find "$root/docs/assets" -type f \( \ + -name '*.png' -o -name '*.jpg' -o -name '*.jpeg' -o -name '*.webp' \ + \) -print0 | xargs -0 strings 2>/dev/null | \ + rg -n -i '(trc_[a-z0-9]{16,}|atomic_[a-z0-9-]{16,}|/Users/[A-Za-z0-9._-]+|/home/[A-Za-z0-9._-]+)' || true) + if [[ -n "$image_metadata" ]]; then + printf 'sensitive-shaped image metadata found\n' + status=1 + fi +fi + if git -C "$root" rev-parse --is-inside-work-tree >/dev/null 2>&1; then history=$(git -C "$root" log --all -p -- . ':!pnpm-lock.yaml' ':!scripts/scan-public.sh' | \ rg -n -i '(BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY|authorization:[[:space:]]*bearer[[:space:]]+[A-Za-z0-9._-]{16,}|/Users/[A-Za-z0-9._-]+|/home/[A-Za-z0-9._-]+|https?://[^/[:space:]]+\.(internal|local)(/|[[:space:]]|$))' || true) diff --git a/spec/capabilities.md b/spec/capabilities.md index 8b631a0..8e1bceb 100644 --- a/spec/capabilities.md +++ b/spec/capabilities.md @@ -4,13 +4,19 @@ authority: canonical status: canonical title: Capability vocabulary genre: spec -last_verified: 2026-09-02 +last_verified: 2026-09-03 --- # Capabilities Capabilities let a client reject an unsuitable provider before allocating resources. +![能力预检:客户端需求和 Provider Manifest 汇入 Runtime,支持则分配,不支持则在分配前失败。](../docs/assets/capability-preflight.png) + +Text equivalent: the runtime compares `requiredCapabilities` with the `Provider Manifest` before +allocation. A supported request proceeds; an unsupported request returns +`unsupported_capability` without allocating a resource. + Initial vocabulary: | Capability | Meaning | diff --git a/spec/runtime-model.md b/spec/runtime-model.md index dabd079..5a0ba73 100644 --- a/spec/runtime-model.md +++ b/spec/runtime-model.md @@ -4,7 +4,7 @@ authority: canonical status: canonical title: Runtime model genre: spec -last_verified: 2026-09-02 +last_verified: 2026-09-03 --- # Runtime Model @@ -21,17 +21,14 @@ operations. A stale generation fails with `generation_conflict`. ## Lifecycle -The portable development states are: +The portable development states are shown below. -```text -requested -> starting -> ready - \-> failed +![Sandbox 生命周期与代际隔离:创建进入 ready,可暂停恢复;所有非终态可终止,重建产生下一代。](../docs/assets/lifecycle-state-machine.svg) -ready -> pausing -> paused -> resuming -> ready - -requested | starting | ready | paused | failed - -> terminating -> terminated -``` +Text equivalent: creation follows `requested -> starting -> ready`; pause and resume follow +`ready -> pausing -> paused -> resuming -> ready`; Provider failures may enter `failed`. Any +non-terminal operational state may enter `terminating -> terminated`. Only recreation moves a +terminated logical resource to `requested` with `generation + 1`. Allocation and readiness are separate observations. A provider may allocate a resource before its execution agent or health endpoint is ready.