+```
+
+`--local` 只表示本地编排,仍允许网页证据;`--local-only`(也接受 `--offline`)
+会强制禁用网络,`--web` 会显式启用网页与工作区证据。自然语言中的 `no web`
+仅作为兼容性兜底。`--os` 当前禁用。无界面命令的所有阶段共同消耗
+一个 60 秒绝对时限,其中宿主直接执行最多使用 20 秒;失败后仅用剩余预算执行
+最多一轮兜底,并为取消与制品收尾保留最后 3 秒。若最终只能生成恢复报告,
+制品仍会落盘,但命令会以错误状态结束。
+
+## 相关页面
+
+1. [文件系统优先](/guide/filesystem-first)
+2. [会话](/guide/sessions)
+3. [命令](/guide/commands)
+4. [工具](/guide/tools)
+5. [安全](/guide/security)
diff --git a/website/docs/v8.5.1/zh/guide/verification.mdx b/website/docs/v8.5.1/zh/guide/verification.mdx
new file mode 100644
index 00000000..e133cbd4
--- /dev/null
+++ b/website/docs/v8.5.1/zh/guide/verification.mdx
@@ -0,0 +1,356 @@
+---
+title: '验证'
+description: '用验证命令和报告证明一个回合已完成,而不是轻信模型的声明'
+---
+
+import { Tab, Tabs } from '@rspress/core/theme';
+
+# 验证
+
+运行时将"完成"视为必须被**证明**的事实,而不仅仅是被声明的结果。当模型说某个任务已完成时,这句话本身毫无价值。验证把声明转化为证据:你声明一组*必须*成功的命令,运行时执行它们,结果会携带一份你可以检视、据以拦截或呈现给用户的报告。
+
+验证是会话级的。Rust 核心运行每条命令,记录其退出状态和输出,并将每份报告汇总为一份随回合结果一同返回的摘要。
+
+产品界面可以先展示交付摘要,再列出支持结论的命令输出和文件级改动。
+
+## 运行验证命令
+
+一条验证命令就是一个小而具名的检查:一个 `id`、一个 `kind`、一段可读的 `description`,以及要运行的 `command`。当某个失败应被视为硬失败而非警告时,将该检查标记为 `required`。
+
+
+
+
+```rust
+use a3s_code_core::verification::VerificationCommand;
+
+let commands = vec![
+ VerificationCommand::required(
+ "build",
+ "build",
+ "项目可以编译",
+ "cargo build --all-features",
+ )
+ .with_timeout_ms(120_000),
+ VerificationCommand::required(
+ "tests",
+ "test",
+ "单元测试通过",
+ "cargo test",
+ ),
+];
+let report = session
+ .verify_commands("release-readiness", &commands)
+ .await?;
+println!("{report:#?}");
+```
+
+
+
+
+```ts
+const report = await session.verifyCommands('release-readiness', [
+ {
+ id: 'build',
+ kind: 'build',
+ description: 'Project compiles',
+ command: 'cargo build --all-features',
+ required: true,
+ timeoutMs: 120000,
+ },
+ {
+ id: 'tests',
+ kind: 'test',
+ description: 'Unit tests pass',
+ command: 'cargo test',
+ required: true,
+ },
+]);
+
+console.log(report);
+```
+
+
+
+
+```python
+report = session.verify_commands('release-readiness', [
+ {
+ "id": "build",
+ "kind": "build",
+ "description": "Project compiles",
+ "command": "cargo build --all-features",
+ "required": True,
+ "timeout_ms": 120000,
+ },
+ {
+ "id": "tests",
+ "kind": "test",
+ "description": "Unit tests pass",
+ "command": "cargo test",
+ "required": True,
+ },
+])
+
+print(report)
+```
+
+
+
+
+```go
+report, err := session.VerifyCommands(ctx, "release-readiness", []code.VerificationCommand{
+ {
+ ID: "build",
+ Kind: "build",
+ Description: "项目可以编译",
+ Command: "cargo build --all-features",
+ Required: true,
+ TimeoutMS: code.Ptr(uint64(120000)),
+ },
+ {
+ ID: "tests",
+ Kind: "test",
+ Description: "单元测试通过",
+ Command: "cargo test",
+ Required: true,
+ },
+})
+if err != nil {
+ return err
+}
+fmt.Println(report)
+```
+
+
+
+
+`subject`(此处为 `release-readiness`)为这一批检查命名,使同一会话内的多次验证在报告中保持彼此独立。
+
+## 读取回合结束后的摘要
+
+每个回合的 `send()` 结果同样携带只读的验证字段,因此你无需单独发起一次验证调用即可据结果拦截。用这些字段判断该回合是否真正完成了它所声称的工作。
+
+
+
+
+```rust
+let result = session.send("应用修复并运行检查", None).await?;
+let summary = result.verification_summary();
+
+println!("{:?}", summary.status);
+println!("{}", summary.pending_required_check_count);
+println!("{}", summary.failed_check_count);
+println!("{}", summary.report_count);
+println!("{}", result.verification_summary_text());
+
+if summary.failed_check_count > 0 {
+ return Err(a3s_code_core::CodeError::Session(
+ "当前回合声称已完成,但验证失败".to_string(),
+ ));
+}
+```
+
+
+
+
+```ts
+const result = await session.send('Apply the fix and run the checks');
+
+console.log(result.verificationStatus);
+console.log(result.pendingVerificationCount);
+console.log(result.failedVerificationCount);
+console.log(result.verificationReportCount);
+console.log(result.verificationSummaryText);
+
+if (result.failedVerificationCount > 0) {
+ throw new Error('Turn reported done but verification failed');
+}
+```
+
+
+
+
+```python
+result = session.send('Apply the fix and run the checks')
+
+print(result.verification_status)
+print(result.pending_verification_count)
+print(result.failed_verification_count)
+print(result.verification_report_count)
+print(result.verification_summary_text)
+
+if result.failed_verification_count > 0:
+ raise RuntimeError('Turn reported done but verification failed')
+```
+
+
+
+
+```go
+result, err := session.Run(ctx, "应用修复并运行检查")
+if err != nil {
+ return err
+}
+
+summary := result.VerificationSummary
+fmt.Println(summary.Status)
+fmt.Println(summary.PendingRequiredCheckCount)
+fmt.Println(summary.FailedCheckCount)
+fmt.Println(summary.ReportCount)
+fmt.Println(result.VerificationSummaryText)
+
+if summary.FailedCheckCount > 0 {
+ return errors.New("回合声称完成,但验证失败")
+}
+```
+
+
+
+
+## 检视报告与摘要
+
+除了逐回合的字段之外,会话还暴露完整的报告集合、一份结构化摘要、可用的预设,以及一份可读的概要。该概要是向人展示某回合*为何*通过或失败的最快方式。
+
+
+
+
+```rust
+let reports = session.verification_reports();
+let summary = session.verification_summary();
+let presets = session.verification_presets();
+let text = session.verification_summary_text();
+
+println!(
+ "{} 份报告,状态 {:?},{} 个预设",
+ reports.len(),
+ summary.status,
+ presets.len()
+);
+println!("{text}");
+```
+
+
+
+
+```ts
+import { formatVerificationSummary } from '@a3s-lab/code';
+
+const reports = session.verificationReports();
+const summary = session.verificationSummary();
+const presets = session.verificationPresets();
+
+// 会话辅助方法和独立格式化函数都能生成可读文本。
+console.log(session.verificationSummaryText());
+console.log(formatVerificationSummary(summary));
+```
+
+
+
+
+```python
+reports = session.verification_reports()
+summary = session.verification_summary()
+presets = session.verification_presets()
+
+# 会话辅助方法返回可直接打印的可读摘要。
+print(session.verification_summary_text())
+```
+
+
+
+
+```go
+reports, err := session.VerificationReports(ctx)
+if err != nil {
+ return err
+}
+summary, err := session.VerificationSummary(ctx)
+if err != nil {
+ return err
+}
+presets, err := session.VerificationPresets(ctx)
+if err != nil {
+ return err
+}
+text, err := session.VerificationSummaryText(ctx)
+if err != nil {
+ return err
+}
+
+fmt.Println(len(reports), summary.Status, len(presets))
+fmt.Println(text)
+```
+
+
+
+
+`verificationPresets()` 返回根据 workspace 文件推断出的检查模板,例如
+`Cargo.toml`、`package.json`、`pyproject.toml` 和 `go.mod`。请把它们当作起点:
+在用来拦截发布或用户可见自动化之前,应审查命令、超时和 required 标记是否适合该项目。
+
+## A3S Code 自身如何完成资格认证
+
+回合验证回答的是一次智能体任务是否产生了它所声称的结果。仓库资格认证回答的是另一
+个问题,即每项公开的 A3S Code 能力是否仍然在 Core、各语言 SDK、资源上限和受支持的
+部署面上满足合同。仅有一次绿色编译无法回答这个问题。
+
+仓库把证据分成四类:
+
+| 证据类别 | 能证明什么 | 不能证明什么 |
+| -------------------- | ---------------------------------------------------------------------------------- | --------------------------------------- |
+| 确定性正确性 | 用固定 Oracle 检查启用条件、成功行为、非法输入、权限、取消、生命周期、顺序和清理 | 真实 Provider、浏览器或对象存储是否可用 |
+| 确定性资源门禁 | 限定调用、重试、记录、字节、队列、候选项、工具轮次与留存状态 | 每台机器上的绝对耗时 |
+| Release 性能资格认证 | 对稳定本地工作记录 Release Build 的 p50、p95、最大值、资源计量、负载参数和机器信息 | 远程模型或公共搜索服务的延迟 |
+| 外部资格认证 | 在已记录条件下验证指定真实模型、浏览器、Collector 或存储服务的兼容性 | Hermetic 可复现性或普遍性能结论 |
+
+能力台账把 README 宣称的 27 个产品领域逐项连接到可执行证据,并明确显示任何尚未解决
+的缺口。能力地图发生变化而台账没有同步时,CI 会直接失败。Node.js 和 Python 门禁会先
+构建并加载 Native Module,再通过公开 Wrapper 执行测试;仅通过 Rust `cargo check`
+不算 SDK Runtime 证据。Go 会通过带版本的 Bridge 并使用 Race Detector 运行。
+
+性能检查会区分工作放大和耗时。普通 CI 拦截 Provider Request、Vector Byte、Scratch
+Space、Retry 与关闭后留存等确定性上限。专用 Release Profile 工作流会预热并重复采样,
+输出 Machine-readable JSON,并将其作为 CI Artifact 保留。依赖网络的 DeepSeek 与浏览器
+耗时会单独报告,因为把这些时间混入本地执行后,就无法区分 Code Regression 与 Provider
+或网络波动。
+
+v8.5.1 的真实模型矩阵会运行资格 ACL 声明的每个模型,验证模型选择的工具与 Hook
+参数改写、有证据门禁的多文件编码任务、自动与显式 SubAgents、Skill 发现和执行、
+并发 PTC 读取、持久 A3S Flow 回放,以及公开 steer/interrupt。确定性 Fixture 还会
+独立覆盖相同控制路径,包括过期与幂等回执、拒绝、预算、取消和清理。
+
+### 最新受控资格认证
+
+2026-08-18 的 Release Profile 在四个逻辑 CPU 的 x86-64 Linux Runner 上运行,六份报告
+全部通过:
+
+| Profile | 固定负载 | 实测 p95 | 目标 |
+| ------------------- | -------------------------------------------- | ------------------------------: | ---------------: |
+| Agent 收敛 | 四个完成、Guard 与恢复 Case | 4/4 Case | 4/4 Case |
+| Workspace Retrieval | 25,000 × 384 Exact / Deterministic Hybrid | 15.590 / 38.506 ms | ≤ 30 / 100 ms |
+| Flow / State Graph | 1,000 Step Projection / 11,008 Record Replay | 130.067 / 125.526 ms | 均 ≤ 2,000 ms |
+| Code Intelligence | 5,000 File;Cold / Warm Workspace Symbol | Cold 754.397 ms / Warm 0.519 ms | ≤ 5,000 / 250 ms |
+| Context / Memory | 25,000 Context Input / 2,500 Memory | 136.740 / 0.123 ms | ≤ 500 / 250 ms |
+| File Persistence | 1,272,624 Byte 同步 Save / Load | 338.887 / 1.028 ms | ≤ 1,000 / 500 ms |
+
+Provider Request Amplification、Vector 与 Rerank Byte、RSS Delta、Serialized Graph Byte、
+Process Cleanup、无累积覆盖写入与删除清理等资源门禁也全部通过。配套 Hermetic CI 完成了
+MinIO Roundtrip、受控 HTTPS 上的生产 Chrome/CDP 与 Google Parser 路径,以及本地
+OpenTelemetry Collector 对指定 Service/Span 的精确接收。
+
+[性能资格认证记录](https://github.com/A3S-Lab/Code/blob/main/manual/PERFORMANCE_QUALIFICATION.md)
+包含 p50/p95/Max、精确包含规则、机器信息、资源计数、Workflow 链接与 Artifact SHA-256
+Digest。这些数据是锁定 Profile 的回归上限,不是所有硬件或远程服务的 SLA。
+
+当前证据台账、缺口关闭情况、外部边界、资格认证命令和完成规则见
+[能力验证与性能合同](https://github.com/A3S-Lab/Code/blob/main/manual/CAPABILITY_VERIFICATION.md)。
+只要台账中仍有未解决的 Code-owned Gap,就不能声称仓库级目标已经完成。
+
+## 为何重要
+
+没有验证,一次智能体运行止于模型的一面之词。有了验证,运行止于可观测的证据:编译通过的构建、跑通的测试套件、保持沉默的代码检查器。摘要文本提供审计轨迹;结果上的计数让你能在自动化中以失败为默认(fail closed)。
+
+## 相关
+
+- [遥测](/guide/telemetry) —— 将追踪事件和验证报告作为运行时证据进行检视。
+- [限制](/guide/limits) —— 在验证运行之前限定一个回合能完成多少工作量。
diff --git a/website/docs/v8.5.1/zh/guide/workspace-backends.mdx b/website/docs/v8.5.1/zh/guide/workspace-backends.mdx
new file mode 100644
index 00000000..81e61303
--- /dev/null
+++ b/website/docs/v8.5.1/zh/guide/workspace-backends.mdx
@@ -0,0 +1,528 @@
+---
+title: '工作区后端'
+description: '让 A3S Code 会话运行在本地文件、S3 兼容对象存储和远端 Git 服务之上。'
+---
+
+import { Tab, Tabs } from '@rspress/core/theme';
+
+# 工作区后端
+
+工作区后端决定内置工作区工具从哪里读写文件。默认后端是以会话工作区为根目录的
+本地文件系统。四种 SDK 都提供显式本地后端、S3 兼容对象存储后端,以及可选的
+HTTP/JSON 远端 Git 配置。Node.js 与 Python 使用后端对象,Go 使用值配置。
+
+当宿主负责工作区放置时使用这组能力:本地开发、浏览器或容器工作区、对象存储
+工作区、托管会话等。
+
+## 能力矩阵
+
+| 后端 | 文件工具 | 搜索工具 | 命令行与本地 Git |
+| ---------------------------------- | -------------------------------------------------- | --------------------------------------- | -------------------------------------- |
+| 默认本地工作区 | `read`、`write`、`edit`、`patch`、`download`、`ls` | `search`(`grep`、`glob`、`bm25` 模式) | `bash`、`git` |
+| `LocalWorkspaceBackend` | 与默认本地工作区相同 | 与默认本地工作区相同 | 与默认本地工作区相同 |
+| `S3WorkspaceBackend` | `read`、`write`、`edit`、`patch`、`ls` | 设置 `searchEnabled` 后可使用 `search` | 不注册 |
+| `S3WorkspaceBackend` + `remoteGit` | S3 文件工具 | 可选降级版 S3 搜索 | 通过远端 Git 提供 `git`,不提供 `bash` |
+
+对象存储不能执行本地进程。不要承诺 S3 工作区上可以直接运行命令,除非宿主通过
+MCP 或 A3S Box 额外提供隔离后的执行能力。
+
+## 本地后端
+
+显式本地后端适合宿主希望本地与远程会话都使用同一组选项接口的场景。
+
+
+
+
+```rust
+use a3s_code_core::{Agent, SessionOptions, WorkspaceServices};
+
+#[tokio::main]
+async fn main() -> a3s_code_core::Result<()> {
+ let agent = Agent::new("agent.acl").await?;
+ let backend = WorkspaceServices::local("/repo");
+ let session = agent
+ .session_builder("/repo")
+ .options(SessionOptions::new().with_workspace_backend(backend))
+ .build()
+ .await?;
+
+ println!("{}", session.read_file("Cargo.toml").await?);
+
+ session.close().await;
+ agent.close().await;
+ Ok(())
+}
+```
+
+
+
+
+```ts
+import { Agent, LocalWorkspaceBackend } from '@a3s-lab/code';
+
+const agent = await Agent.create('agent.acl');
+const session = agent.session('/repo', {
+ workspaceBackend: new LocalWorkspaceBackend('/repo'),
+});
+```
+
+
+
+
+```python
+from a3s_code import Agent, LocalWorkspaceBackend, SessionOptions
+
+agent = Agent.create("agent.acl")
+opts = SessionOptions()
+opts.workspace_backend = LocalWorkspaceBackend("/repo")
+session = agent.session("/repo", opts)
+```
+
+
+
+
+工作区路径本身会选择默认本地后端。当本地与远端会话需要共用同一种选项结构时,
+可使用 `WorkspaceBackendConfig`:
+
+```go
+package main
+
+import (
+ "context"
+ "fmt"
+ "log"
+
+ code "github.com/A3S-Lab/Code/sdk/go/v8"
+)
+
+func main() {
+ ctx := context.Background()
+ agent, err := code.Create(ctx, "agent.acl")
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer agent.Close(ctx)
+
+ session, err := agent.Session(ctx, "/repo", &code.SessionOptions{
+ WorkspaceBackend: &code.WorkspaceBackendConfig{
+ Kind: "local",
+ Root: "/repo",
+ },
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer session.Close(ctx)
+
+ content, err := session.ReadFile(ctx, "go.mod", nil)
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Println(content)
+}
+```
+
+
+
+
+### 本地下载目标
+
+可写的本地后端还会注册 `download`。工具接收公网 HTTP(S) `url`,并且只能写入工作区
+相对 `file_path`;省略路径时会推断并净化文件名。S3 和其他非本地后端不会注册它,因为
+相邻原子临时文件、取消清理、符号链接检查和最终提升都依赖本地文件系统语义。
+
+`overwrite` 默认 `false`。传输默认使用 512 MiB 的 `max_bytes` 上限和 300 秒
+`timeout`,硬上限分别是 8 GiB 与 3600 秒。Range 并发会自适应选择,也可以明确限制为
+1–4 个连接;`expected_sha256` 可要求在提升目标前匹配 64 位十六进制摘要。传输与元数据
+细节见[工具](/guide/tools#二进制安全的本地下载)。
+
+## S3 后端
+
+`S3WorkspaceBackend` 会把内置文件工具指向任意 S3 兼容服务,包括 AWS S3、MinIO、
+RustFS、Cloudflare R2 和 Backblaze B2。
+
+
+
+
+Rust crate 需要启用 `s3` feature。
+
+```rust
+use std::env;
+
+use a3s_code_core::{Agent, S3BackendConfig, SessionOptions, WorkspaceServices};
+
+#[tokio::main]
+async fn main() -> a3s_code_core::Result<()> {
+ let bucket = env::var("WORKSPACE_S3_BUCKET")
+ .map_err(|error| a3s_code_core::CodeError::Config(error.to_string()))?;
+ let access_key = env::var("S3_ACCESS_KEY_ID")
+ .map_err(|error| a3s_code_core::CodeError::Config(error.to_string()))?;
+ let secret_key = env::var("S3_SECRET_ACCESS_KEY")
+ .map_err(|error| a3s_code_core::CodeError::Config(error.to_string()))?;
+
+ let mut config =
+ S3BackendConfig::new(bucket, "sessions/example", access_key, secret_key)
+ .region(env::var("WORKSPACE_S3_REGION").unwrap_or_else(|_| "us-east-1".into()))
+ .force_path_style(true)
+ .enable_search(false);
+ if let Ok(endpoint) = env::var("WORKSPACE_S3_ENDPOINT") {
+ config = config.endpoint(endpoint);
+ }
+
+ let agent = Agent::new("agent.acl").await?;
+ let session = agent
+ .session_builder("s3://workspace-bucket/sessions/example")
+ .options(
+ SessionOptions::new().with_workspace_backend(WorkspaceServices::s3(config)),
+ )
+ .build()
+ .await?;
+
+ println!("{}", session.read_file("README.md").await?);
+
+ session.close().await;
+ agent.close().await;
+ Ok(())
+}
+```
+
+
+
+
+```ts
+import { Agent, S3WorkspaceBackend } from '@a3s-lab/code';
+
+const backend = new S3WorkspaceBackend({
+ endpoint: process.env.WORKSPACE_S3_ENDPOINT,
+ region: process.env.WORKSPACE_S3_REGION ?? 'us-east-1',
+ accessKeyId: process.env.S3_ACCESS_KEY_ID!,
+ secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
+ bucket: process.env.WORKSPACE_S3_BUCKET!,
+ prefix: 'sessions/example',
+ forcePathStyle: true,
+ searchEnabled: false,
+});
+
+const agent = await Agent.create('agent.acl');
+const session = agent.session('s3://workspace-bucket/sessions/example', {
+ workspaceBackend: backend,
+});
+```
+
+
+
+
+```python
+import os
+
+from a3s_code import Agent, S3WorkspaceBackend, SessionOptions
+
+agent = Agent.create("agent.acl")
+opts = SessionOptions()
+opts.workspace_backend = S3WorkspaceBackend(
+ bucket=os.environ["WORKSPACE_S3_BUCKET"],
+ prefix="sessions/example",
+ access_key_id=os.environ["S3_ACCESS_KEY_ID"],
+ secret_access_key=os.environ["S3_SECRET_ACCESS_KEY"],
+ endpoint=os.environ.get("WORKSPACE_S3_ENDPOINT"),
+ region=os.environ.get("WORKSPACE_S3_REGION", "us-east-1"),
+ force_path_style=True,
+ search_enabled=False,
+)
+session = agent.session("s3://workspace-bucket/sessions/example", opts)
+```
+
+
+
+
+```go
+package main
+
+import (
+ "context"
+ "fmt"
+ "log"
+ "os"
+
+ code "github.com/A3S-Lab/Code/sdk/go/v8"
+)
+
+func main() {
+ ctx := context.Background()
+ agent, err := code.Create(ctx, "agent.acl")
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer agent.Close(ctx)
+
+ forcePathStyle := true
+ searchEnabled := false
+ session, err := agent.Session(
+ ctx,
+ "s3://workspace-bucket/sessions/example",
+ &code.SessionOptions{
+ WorkspaceBackend: &code.WorkspaceBackendConfig{
+ Kind: "s3",
+ S3: &code.S3BackendConfig{
+ Endpoint: os.Getenv("WORKSPACE_S3_ENDPOINT"),
+ Region: os.Getenv("WORKSPACE_S3_REGION"),
+ AccessKeyID: os.Getenv("S3_ACCESS_KEY_ID"),
+ SecretAccessKey: os.Getenv("S3_SECRET_ACCESS_KEY"),
+ Bucket: os.Getenv("WORKSPACE_S3_BUCKET"),
+ Prefix: "sessions/example",
+ ForcePathStyle: &forcePathStyle,
+ SearchEnabled: &searchEnabled,
+ },
+ },
+ },
+ )
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer session.Close(ctx)
+
+ content, err := session.ReadFile(ctx, "README.md", nil)
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Println(content)
+}
+```
+
+
+
+
+S3 搜索需要显式启用。启用后,`grep` / `glob` 会降级为对象列表和有上限的下载。
+当存储桶较大或端点会限流时,应配置 `maxObjectsScanned`、
+`maxGrepBytesPerObject` 和 `searchConcurrency`。
+
+### S3 选项
+
+| Node.js 选项 | Python 选项 | 必填 | 作用 |
+| ----------------------- | --------------------------- | ---- | ------------------------------------------------ |
+| `bucket` | `bucket` | 是 | 存储工作区对象的 S3 存储桶。 |
+| `prefix` | `prefix` | 是 | 存储桶内的逻辑工作区根;使用 `""` 表示存储桶根。 |
+| `accessKeyId` | `access_key_id` | 是 | 访问密钥标识,通常从宿主环境读取。 |
+| `secretAccessKey` | `secret_access_key` | 是 | 访问密钥,通常从宿主环境或密钥管理系统读取。 |
+| `endpoint` | `endpoint` | 否 | 自定义 S3 兼容端点;AWS S3 默认端点可省略。 |
+| `region` | `region` | 否 | 区域;省略时默认为 `us-east-1`。 |
+| `sessionToken` | `session_token` | 否 | 使用临时凭据时的 STS 会话令牌。 |
+| `forcePathStyle` | `force_path_style` | 否 | MinIO、RustFS 和多数非 AWS 端点通常设为 `true`。 |
+| `maxReadBytes` | `max_read_bytes` | 否 | 单次读取的大小上限;默认 10 MiB。 |
+| `searchEnabled` | `search_enabled` | 否 | 启用降级版 S3 `grep` / `glob`;默认为 `false`。 |
+| `maxObjectsScanned` | `max_objects_scanned` | 否 | 单次搜索扫描对象数上限;仅启用搜索时使用。 |
+| `maxGrepBytesPerObject` | `max_grep_bytes_per_object` | 否 | `grep` 的单对象下载上限;仅启用搜索时使用。 |
+| `searchConcurrency` | `search_concurrency` | 否 | `grep` 时并发下载对象数;仅启用搜索时使用。 |
+
+Go 在 `S3BackendConfig` 上提供同一组字段:`Bucket`、`Prefix`、
+`AccessKeyID`、`SecretAccessKey`、`Endpoint`、`Region`、`SessionToken`、
+`ForcePathStyle`、`MaxReadBytes`、`SearchEnabled`、`MaxObjectsScanned`、
+`MaxGrepBytesPerObject` 与 `SearchConcurrency`。
+
+## 远端 Git
+
+`remoteGit` 会在 `workspaceBackend` 之上挂载 HTTP/JSON Git 提供程序。它用于没有
+本地 `.git` 目录的非本地工作区。
+
+`remoteGit` 必须和 `workspaceBackend` 一起传;单独传入会被拒绝。
+
+
+
+
+```rust
+use std::env;
+
+use a3s_code_core::{
+ Agent, RemoteGitBackendConfig, S3BackendConfig, SessionOptions, WorkspaceServices,
+};
+
+#[tokio::main]
+async fn main() -> a3s_code_core::Result<()> {
+ let bucket = env::var("WORKSPACE_S3_BUCKET")
+ .map_err(|error| a3s_code_core::CodeError::Config(error.to_string()))?;
+ let access_key = env::var("S3_ACCESS_KEY_ID")
+ .map_err(|error| a3s_code_core::CodeError::Config(error.to_string()))?;
+ let secret_key = env::var("S3_SECRET_ACCESS_KEY")
+ .map_err(|error| a3s_code_core::CodeError::Config(error.to_string()))?;
+ let base_url = env::var("REMOTE_GIT_BASE_URL")
+ .map_err(|error| a3s_code_core::CodeError::Config(error.to_string()))?;
+ let token = env::var("REMOTE_GIT_TOKEN")
+ .map_err(|error| a3s_code_core::CodeError::Config(error.to_string()))?;
+
+ let storage = WorkspaceServices::s3(S3BackendConfig::new(
+ bucket,
+ "sessions/example",
+ access_key,
+ secret_key,
+ ));
+ let backend = storage.with_remote_git(
+ RemoteGitBackendConfig::new(base_url, "sessions/example").bearer_token(token),
+ )?;
+
+ let agent = Agent::new("agent.acl").await?;
+ let session = agent
+ .session_builder("s3://workspace-bucket/sessions/example")
+ .options(SessionOptions::new().with_workspace_backend(backend))
+ .build()
+ .await?;
+
+ let status = session
+ .tool("git", serde_json::json!({ "command": "status" }))
+ .await?;
+ println!("{}", status.output);
+
+ session.close().await;
+ agent.close().await;
+ Ok(())
+}
+```
+
+
+
+
+```ts
+import { Agent, S3WorkspaceBackend } from '@a3s-lab/code';
+
+const backend = new S3WorkspaceBackend({
+ endpoint: process.env.WORKSPACE_S3_ENDPOINT,
+ region: process.env.WORKSPACE_S3_REGION ?? 'us-east-1',
+ accessKeyId: process.env.S3_ACCESS_KEY_ID!,
+ secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
+ bucket: process.env.WORKSPACE_S3_BUCKET!,
+ prefix: 'sessions/example',
+ forcePathStyle: true,
+});
+
+const agent = await Agent.create('agent.acl');
+const session = agent.session('s3://workspace-bucket/sessions/example', {
+ workspaceBackend: backend,
+ remoteGit: {
+ baseUrl: process.env.REMOTE_GIT_BASE_URL!,
+ repoId: 'sessions/example',
+ bearerToken: process.env.REMOTE_GIT_TOKEN,
+ },
+});
+```
+
+
+
+
+```python
+import os
+
+from a3s_code import (
+ Agent,
+ RemoteGitBackendConfig,
+ S3WorkspaceBackend,
+ SessionOptions,
+)
+
+agent = Agent.create("agent.acl")
+opts = SessionOptions()
+opts.workspace_backend = S3WorkspaceBackend(
+ bucket=os.environ["WORKSPACE_S3_BUCKET"],
+ prefix="sessions/example",
+ access_key_id=os.environ["S3_ACCESS_KEY_ID"],
+ secret_access_key=os.environ["S3_SECRET_ACCESS_KEY"],
+ endpoint=os.environ.get("WORKSPACE_S3_ENDPOINT"),
+ region=os.environ.get("WORKSPACE_S3_REGION", "us-east-1"),
+ force_path_style=True,
+)
+opts.remote_git = RemoteGitBackendConfig(
+ base_url=os.environ["REMOTE_GIT_BASE_URL"],
+ repo_id="sessions/example",
+ bearer_token=os.environ["REMOTE_GIT_TOKEN"],
+)
+session = agent.session("s3://workspace-bucket/sessions/example", opts)
+```
+
+
+
+
+```go
+package main
+
+import (
+ "context"
+ "fmt"
+ "log"
+ "os"
+
+ code "github.com/A3S-Lab/Code/sdk/go/v8"
+)
+
+func main() {
+ ctx := context.Background()
+ agent, err := code.Create(ctx, "agent.acl")
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer agent.Close(ctx)
+
+ forcePathStyle := true
+ session, err := agent.Session(
+ ctx,
+ "s3://workspace-bucket/sessions/example",
+ &code.SessionOptions{
+ WorkspaceBackend: &code.WorkspaceBackendConfig{
+ Kind: "s3",
+ S3: &code.S3BackendConfig{
+ Endpoint: os.Getenv("WORKSPACE_S3_ENDPOINT"),
+ Region: os.Getenv("WORKSPACE_S3_REGION"),
+ AccessKeyID: os.Getenv("S3_ACCESS_KEY_ID"),
+ SecretAccessKey: os.Getenv("S3_SECRET_ACCESS_KEY"),
+ Bucket: os.Getenv("WORKSPACE_S3_BUCKET"),
+ Prefix: "sessions/example",
+ ForcePathStyle: &forcePathStyle,
+ },
+ },
+ RemoteGit: &code.RemoteGitBackendConfig{
+ BaseURL: os.Getenv("REMOTE_GIT_BASE_URL"),
+ RepoID: "sessions/example",
+ BearerToken: os.Getenv("REMOTE_GIT_TOKEN"),
+ },
+ },
+ )
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer session.Close(ctx)
+
+ status, err := session.Git(ctx, code.GitOptions{Command: "status"})
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Println(status.Output)
+}
+```
+
+
+
+
+不要把远端 Git 凭据写入 `agent.acl` 或智能体目录。应由宿主通过环境变量或密钥
+管理系统注入。
+
+### 远端 Git 选项
+
+| Node.js 选项 | Python 选项 | 必填 | 作用 |
+| ------------------ | -------------------- | -------- | ------------------------------------------------------- |
+| `baseUrl` | `base_url` | 是 | 远端 Git 服务的基础 URL,不带末尾斜杠。 |
+| `repoId` | `repo_id` | 是 | 与远端 Git 服务约定的不透明仓库标识。 |
+| `bearerToken` | `bearer_token` | 生产环境 | 远端 Git 服务的持有者令牌;只应在受信任开发环境中省略。 |
+| `clientCertPem` | `client_cert_pem` | 否 | mTLS 客户端证书路径;必须与客户端密钥成对设置。 |
+| `clientKeyPem` | `client_key_pem` | 否 | mTLS 客户端密钥路径;必须与证书成对设置。 |
+| `requestTimeoutMs` | `request_timeout_ms` | 否 | 单次 HTTP 调用超时,单位毫秒;默认 30000。 |
+| `maxDiffBytes` | `max_diff_bytes` | 否 | `diff` 响应字节数客户端上限;默认 1 MiB。 |
+| `maxLogEntries` | `max_log_entries` | 否 | `log` 条目数客户端上限;默认 200。 |
+
+Go 在 `RemoteGitBackendConfig` 上提供同一组字段:`BaseURL`、`RepoID`、
+`BearerToken`、`ClientCertPEM`、`ClientKeyPEM`、`RequestTimeoutMS`、
+`MaxDiffBytes` 与 `MaxLogEntries`。
+
+## 选择后端
+
+- 普通开发机和 CI 检出使用默认本地工作区。
+- 宿主希望总是传入带类型的后端对象时,使用 `LocalWorkspaceBackend`。
+- 工作区状态必须落在对象存储中时,使用 `S3WorkspaceBackend`。
+- 非本地工作区仍需要内置 `git` 工具时,追加 `remoteGit`。
+- 当前后端不能直接运行命令时,通过 MCP 或 A3S Box 提供执行能力。
diff --git a/website/docs/v8.5.1/zh/index.mdx b/website/docs/v8.5.1/zh/index.mdx
new file mode 100644
index 00000000..23c7a7a6
--- /dev/null
+++ b/website/docs/v8.5.1/zh/index.mdx
@@ -0,0 +1,7 @@
+---
+pageType: home
+title: A3S Code
+description: 用 Rust 构建的受治理编码 Agent 运行时,支持异步工作区检索、模型边界证据、事件流与任务恢复,并提供 Rust、Node.js、Python、Go API。
+sidebar: false
+outline: false
+---
diff --git a/website/rspress.config.ts b/website/rspress.config.ts
index ea7e729e..4f496bbb 100644
--- a/website/rspress.config.ts
+++ b/website/rspress.config.ts
@@ -42,8 +42,9 @@ export default defineConfig({
],
},
multiVersion: {
- default: 'v8.4.0',
+ default: 'v8.5.1',
versions: [
+ 'v8.5.1',
'v8.4.0',
'v8.3.0',
'v8.2.0',
diff --git a/website/theme/components/TuiWelcomeBanner.tsx b/website/theme/components/TuiWelcomeBanner.tsx
index 98e3c8a3..2219e46d 100644
--- a/website/theme/components/TuiWelcomeBanner.tsx
+++ b/website/theme/components/TuiWelcomeBanner.tsx
@@ -72,7 +72,7 @@ export function TuiWelcomeBanner({
- a3s-code v8.4.0
+ a3s-code v8.5.1
·
openai/gpt-5
·
diff --git a/website/version-snapshots.json b/website/version-snapshots.json
index d139b768..1794f178 100644
--- a/website/version-snapshots.json
+++ b/website/version-snapshots.json
@@ -1,6 +1,13 @@
{
- "current": "v8.4.0",
+ "current": "v8.5.1",
"archives": [
+ {
+ "version": "v8.4.0",
+ "sourceTag": "v8.4.0",
+ "sourceTree": "5959d7f6637b65eee66490beb77980699b808aa8",
+ "files": 128,
+ "sha256": "876343663254b8f2b1c1908b7d530f255683b805eeda2c0194e771262d31b74e"
+ },
{
"version": "v8.3.0",
"sourceTag": "v8.3.0",