-
-- **OpenAI と同じ API。** `OPENAI_BASE_URL` を設定すれば、[公式 OpenAI SDK](https://developers.openai.com/api/docs/libraries)または直接の HTTP リクエストがそのまま動作します。
-- **自分のエージェント、自分のモデル。** 各 Session は Codex、Claude Code、MiniMax Code のいずれかを手元のマシンと同じようにネイティブに実行し、設定したモデルプロバイダーを使用します。詳しくは [Harness の機能](https://openagentcore.dev/contracts/agents-api/harness-capabilities)をご覧ください。
-- **計算資源は休止し、ワークスペースは残る。** microsandbox と独立したワークスペースストレージの組み合わせでは、アイドル状態のサンドボックスが計算資源を解放し、互換性のあるノードでファイルをそのまま再開します。E2B、Docker、自分の Linux、macOS、Windows マシンでも Session を実行できます。詳しくは[Sandbox Provider protocol](https://openagentcore.dev/docs/sandbox-provider)をご覧ください。
-- **置き換え可能なコンポーネント。** サンドボックスプロバイダー、ワークスペースファイルシステム、Harness、モデルプロバイダーは、[定義されたプロトコル](AGENTS.md#protocols-at-every-boundary)を通じて接続されます。
-
-
-
-## クイックスタート
-
-[前提条件](https://openagentcore.dev/docs/getting-started/install#prerequisites)に従って Docker をセットアップした Linux または macOS で、Core、Web、PostgreSQL をインストールします。
-
-```sh
-curl -fsSL https://openagentcore.dev/install.sh | bash
-```
-
-Windows では PowerShell で実行します。
-
-```powershell
-irm https://github.com/MiniMax-AI/OpenAgentCore/releases/latest/download/install.ps1 | iex
-```
-
-Web で、インストーラーが表示する Core key でサインインし、パブリックアドレスを設定し、デフォルトモデルを設定し、Project API key を発行して、サンドボックスの容量(ノードまたは E2B)を追加します。各手順は[Core と Web のインストール](https://openagentcore.dev/docs/getting-started/install)をご覧ください。
-
-続いて OpenAI SDK から呼び出します。`OPENAI_BASE_URL` に API のベース URL(`https://core.example/v1`)、`OPENAI_API_KEY` に Project API key を設定してください。
-
-```python
-from openai import OpenAI
-
-client = OpenAI() # reads OPENAI_BASE_URL and OPENAI_API_KEY
-session = client.beta.agents.sessions.create(
- environment={"type": "openai_hosted"},
- input="Create /workspace/hello.txt with a short greeting, then describe it.",
- extra_body={"agent": {"x_agents_core": {"harness": "codex"}}},
-)
-print(session.id)
-```
-
-[最初の Session を実行](https://openagentcore.dev/docs/getting-started/quickstart)では、結果を待って読み戻します。
-
-## 仕組み
-
-
-
-
-
-
-アプリケーションと管理者は、次の Core API を使用します。
-
-| API | パス | 利用者 |
-| --- | --- | --- |
-| **[Agents API](https://openagentcore.dev/docs/api/public-agent-api)** | `/v1` | アプリケーション。[OpenAI の Agents API](https://developers.openai.com/api/docs/guides/agents-api/overview) と同じプロトコルを使用 |
-| **[Core API](https://openagentcore.dev/contracts/agents-api/admin-api)** | `/core/v1` | 管理者。Web 経由で利用 |
-
-Core は実行状態を永続化し、Runtime は Environment 内で選択した Harness を実行します。各コンポーネントは定義されたプロトコルで接続されているため、個別に置き換えられます。詳しくは[アーキテクチャ](https://openagentcore.dev/docs/architecture)をご覧ください。
-
-## ドキュメント
-
-| 目的 | 参照先 |
-| --- | --- |
-| インストールと運用 | [Core と Web のインストール](https://openagentcore.dev/docs/getting-started/install)、続いて[運用](https://openagentcore.dev/docs/getting-started/operations) |
-| API を使ったアプリケーション開発 | [最初の Session を実行](https://openagentcore.dev/docs/getting-started/quickstart)、続いて [Agents API ガイド](https://openagentcore.dev/docs/api/public-agent-api) |
-| 完成したアプリケーションの確認 | [サンプル](https://openagentcore.dev/docs/examples) |
-| 自分のマシンでエージェントを実行 | [セルフホスト実行](https://openagentcore.dev/docs/getting-started/self-hosted) |
-| Harness の機能と制限の確認 | [Harness の機能](https://openagentcore.dev/contracts/agents-api/harness-capabilities) |
-| 設計の理解 | [アーキテクチャ](https://openagentcore.dev/docs/architecture) |
-| 新しいサンドボックス、Harness などのコンポーネントの追加 | [OpenAgentCore の開発](https://openagentcore.dev/docs/development) |
-
-## コントリビューションとライセンス
-
-コードを変更する前に [CONTRIBUTING.md](CONTRIBUTING.md) をお読みください。バグ報告と質問は [GitHub Issues](https://github.com/MiniMax-AI/OpenAgentCore/issues) へお寄せください。[MIT License](LICENSE) で公開しています。
diff --git a/README.md b/README.md
index 83ef3704b..070d59327 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ The OpenAI Agents API, open source and self-hosted. Run Codex, Claude Code or Mi
[Website](https://openagentcore.dev/) · [Documentation](https://openagentcore.dev/docs/getting-started/) · [Quickstart](#quickstart) · [Contributing](CONTRIBUTING.md)
-**English** · [简体中文](README.zh-CN.md) · [日本語](README.ja.md)
+**English** · [简体中文](README.zh-CN.md)
diff --git a/README.zh-CN.md b/README.zh-CN.md
index 535f2252e..e4cb85dbd 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -11,7 +11,7 @@
[官网](https://openagentcore.dev/zh/) · [文档](https://openagentcore.dev/zh/docs/getting-started/) · [快速开始](#快速开始) · [参与贡献](CONTRIBUTING.md)
-[English](README.md) · **简体中文** · [日本語](README.ja.md)
+[English](README.md) · **简体中文**
diff --git a/apps/web/DESIGN.md b/apps/web/DESIGN.md
index 4ce53087f..f288d1905 100644
--- a/apps/web/DESIGN.md
+++ b/apps/web/DESIGN.md
@@ -227,7 +227,7 @@ The data contract is part of the look. Core reports only what it observes, so th
- One list grammar on every resource page: project filter, search, count, name with compact ID, creator, row actions.
- Tabular numerals everywhere a number can line up.
- Status is always a dot plus a plain-language label.
-- Task instructions and empty-state next steps stay visible. Supplementary definitions belong in help tips. Errors, warnings and safety notices stay visible.
+- Task instructions and empty-state next steps stay visible. Errors, warnings and safety notices stay visible.
## Colors
@@ -419,14 +419,14 @@ A single rollout row opens a details dialog for Core's target generation, previo
A generation-only update within the same installation/backend lifecycle retains compatible previous node/allocation evidence while refreshing. Failed or pending reads visibly qualify those observations; never replace them with fabricated zeros. Reset, backend and installation lifecycle changes discard incompatible data. The shared deployment query and write ownership below govern navigation, late reads, explicit retries and login isolation.
### Sandbox reset
-Sandbox configuration offers an explicit reset through its panels and confirmation dialogs. The confirmation keeps to one concise consequence paragraph, two mode choices, the auto deadline and footer actions. Put cleanup sequencing and preservation details in help tips. Auto clear is selected first, with a one-hour deadline editable from 5 minutes to 24 hours; Force clear and escalation require destructive confirmation. State directly that hosted work is archived, remaining active work may be cancelled, archived Sessions cannot resume and unpersisted workspace contents may be lost. Details about preserved histories, Files/Artifacts and unaffected self-hosted execution live behind the reset impact help tip. Cancelling an active reset stops further clearing but cannot undo completed archives.
+Sandbox configuration offers an explicit reset ([semantics](../../contracts/agents-api/sandbox-deployment.md#reset)) through its panels and confirmation dialogs. The confirmation keeps to one concise consequence paragraph, two mode choices, the auto deadline and footer actions. Put cleanup sequencing and preservation details in help tips. Auto clear is selected first, with a one-hour deadline editable from 5 minutes to 24 hours; Force clear and escalation require destructive confirmation. State directly that hosted work is archived, remaining active work may be cancelled, archived Sessions cannot resume and unpersisted workspace contents may be lost. Further consequences live behind the reset impact help tip.
A persistent progress panel uses Core's busy, idle and cleanup counts, deadline and named offline-node blockers. Bring blocked nodes online for confirmed cleanup; never offer a browser-side force-release shortcut. Poll the deployment every five seconds only while its reset is non-null. A passed deadline does not establish force or completion; only a Core response does. Completion opens the setup flow, with a new explicit save using the generation read from Core, including zero on a fresh install. Reset and online configuration rollout have independent authoritative progress; neither automatically replays configuration.
Read deployment progress independently of node details. Partial failures retain successful facts with a visible stale/unavailable notice. An uncertain write opens the recovery dialog and requires a new authoritative read before another mutation; refresh reads state and never resubmits the write. The connection's QueryClient owns both the authoritative deployment and pending or uncertain writes across route transitions. Leaving Sandbox configuration cannot cancel or forget a submitted reset, and a cached node snapshot cannot replace a newer reset or completion learned on Overview. Returning to Nodes or Sandbox configuration reads the shared deployment immediately and refreshes node evidence separately. Only a successful authoritative read begun after the write settles can release the mutation block; an earlier or still-pending read cannot. Submitting consumes the reset confirmation even if its outcome is uncertain; recovery uses the separate read-and-review dialog. Observation retries preserve applicable non-secret configuration drafts. A changed installation, owner epoch, backend, mode or generation discards the prior draft and confirmation. Logout clears this connection-scoped state.
### Settings page
-Settings is the single platform configuration entry, with four tabs: Sandbox and scheduling, Workspace storage, Models and credentials, and Service and deployment. Each tab has a stable address; links from Nodes and metrics open the owning tab, and the Sandbox and scheduling header links back to Nodes. Forms save independently through their resource APIs, never through one cross-resource Save all action.
+Settings is the single platform configuration entry, with one tab per [group](../../docs/configuration.md#runtime-settings-web). Each tab has a stable address; links from Nodes and metrics open the owning tab, and the Sandbox and scheduling header links back to Nodes. Forms save independently through their resource APIs, never through one cross-resource Save all action.
The hierarchy is page, tab, section, row. The page header loses its rule to an underline tab row: 40px text tabs in Graphite 13px/500, the current one Ink with a 2px Ink underline. Below 640px the tabs wrap onto a second row rather than scroll out of sight. The body is a left-aligned column at most 880px wide with 32px between sections. A section is the shared Section heading (14px/600, help tip, section-wide outline actions on the right) over one card of label/value rows (`settings.css`): a 200px Graphite label column with its help tip and an Ink value column, 8px by 16px padding, 32px minimum line height, Faint Rules between rows; below 640px the label sits above the value. An action that changes one value sits at the end of its row (Edit tenant capacity; Save beside the idle-seconds field, whose error appears beneath it). Read-only status is a row too (Configuration rollout, Snapshot retention); tables sit in one framed card. Settings never repeats the KPI strips of Nodes or the metrics pages. The irreversible operation closes the page in its own section: a red-ringed card with one Ink line stating the consequence and a red-text outline button.
@@ -434,12 +434,12 @@ Sandbox and scheduling contains sandbox setup or Deployment provider (Provider,
Workspace storage shows the selected configuration's adapter and tenant capacity (in bytes units, or No tenant capacity limit) under Storage configuration, with Select new configuration in the section header and Edit tenant capacity on the capacity row. The configuration ID and parameters JSON sit in a closed Configuration details disclosure at the end of the card. Select new configuration accepts an adapter identifier, configuration ID, parameters JSON object and optional write-only credential JSON object. Edit tenant capacity keeps the current configuration identity. Explain adapter preparation and existing-workspace behavior behind help tips, with a link to the owning configuration document; keep required form labels and validation visible. Never prefill credentials or persist their drafts across navigation. A failed read is not an unconfigured filesystem, and an uncertain write is not a safe automatic retry.
-Models and credentials stacks one default-model card per Harness. Its header carries the Harness name, its readiness (Ready in green; Model provider not set in amber, with Set as the primary button; Disabled in neutral, with a View startup settings text action), a Default pill, a help tip and the Set, Replace and Clear actions; rows hold model ID, provider protocol, base URL, key presence, token limits when set and update time, and a foot holds Usage details. Set and Replace open one form dialog. The adapter declaration supplies supported protocols and native JSON support without harness-specific branches. Native settings use an optional JSON object editor with formatting and inline syntax errors. Changing model identity clears native JSON; replacing only the required write-only API key does not. Keys are never prefilled and are forgotten when the form closes. Core rejections remain visible in the form; Clear uses ConfirmDialog. Usage details opens Core's observations separately.
+Models and credentials stacks one default-model card per Harness. Its header carries the Harness name, its [readiness](../../docs/configuration.md#runtime-settings-web) (Ready in green; Model provider not set in amber, with Set as the primary button; Disabled in neutral, with a View startup settings text action), a Default pill, a help tip and the Set, Replace and Clear actions; rows hold model ID, provider protocol, base URL, key presence, token limits when set and update time, and a foot holds Usage details. Set and Replace open one form dialog. The adapter declaration supplies supported protocols and native JSON support without harness-specific branches. Native settings use an optional JSON object editor with formatting and inline syntax errors. Changing model identity clears native JSON; replacing only the required write-only API key does not. Keys are never prefilled and are forgotten when the form closes. Core rejections remain visible in the form; Clear uses ConfirmDialog. Usage details opens Core's observations separately.
-Service and deployment shows installation addresses, an Installation details disclosure, closed by default, with the installation ID and source commit, existing Domain and HTTPS actions, and the startup settings Core loaded. Process settings remain read-only here; their source stays the installation configuration. Each row's label is the setting's environment variable in code style (OAC_LOG_LEVEL), as Core reports it, wrapping after an underscore so a phone keeps all three columns; values show as is, with arrays joined, On or Off for booleans and None for an empty list. How to change a setting in the section header links to the configuration guide. Sensitive settings show only Configured or Not set. Default uses a neutral pill.
+Service and deployment shows installation addresses, an Installation details disclosure, closed by default, with the installation ID and source commit, Domain and HTTPS actions, and the startup settings Core loaded. Process settings remain read-only here; their source stays the installation configuration. Each row's label is the setting's environment variable in code style (OAC_LOG_LEVEL), as Core reports it, wrapping after an underscore so a phone keeps all three columns; values show as is, with arrays joined, On or Off for booleans and None for an empty list. How to change a setting in the section header links to the configuration guide. Sensitive settings show only Configured or Not set. Default uses a neutral pill.
### One place for each task
-Each configuration has exactly one editor in Settings; other pages link to it. Resource operations such as Project keys, Session executor credentials and node removal stay on their resource pages. Keep the configuration page flat: resource editors are dialogs and rollout is one status row with a details action. Explanations belong in question-mark help tips, not small-print helper paragraphs. Errors, uncertain outcomes and current usage exceeding a new limit remain visible without duplicating the workflow.
+Each configuration has exactly one editor in Settings; other pages link to it. Resource operations such as Project keys, Session executor credentials and node removal stay on their resource pages. Keep the configuration page flat: resource editors are dialogs and rollout is one status row with a details action. Explanations go in help tips, not small-print helper paragraphs. Errors, uncertain outcomes and current usage exceeding a new limit remain visible without duplicating the workflow.
### Diagnostic observations
Failure reasons belong beside the failed Session or Turn status. On the Session page the Status fact stays short, and the reason and its next step read as one block under the facts, at reading width. Their first read uses a skeleton; an unavailable reason names that state and puts the read retry beside its help tip. Technical classifications are translated through one catalogue, not shown as raw error codes. Trace Timing labels Core receipt times separately from tool-reported duration; explanations of batched delivery, clock differences and historical gaps live in help tips.
@@ -454,7 +454,7 @@ Motion reports state and never makes anyone wait: the navigation chip and segmen
## Do's and Don'ts
### Do:
-- **Do** keep next steps visible and put supplementary definitions behind a circled "?" help tip; report errors in a dialog or a toast; keep warnings and safety notices (deletion consequences, a key shown once) visible.
+- **Do** keep next steps visible; report errors in a dialog or a toast; keep warnings and safety notices (deletion consequences, a key shown once) visible.
- **Do** start every project-scoped toolbar with the project filter, then search, with the count on the right.
- **Do** end every resource table with the Creator column and then the row actions.
- **Do** confirm every deletion in ConfirmDialog.
@@ -482,6 +482,6 @@ Motion reports state and never makes anyone wait: the navigation chip and segmen
Use Lucide throughout. Navigation icons are 18px with a 1.75px stroke; shared tool icons use the same stroke at their existing compact sizes. Default navigation icons use secondary ink, selected icons use primary ink. The selected row has a neutral background and a narrow indigo marker.
-Getting started emphasizes the first confirmed incomplete step with the primary button while leaving every step independently available. Only authoritative, successful zero-Session reads replace the activity chart with first-use guidance. Missing and failed reads retain their existing uncertainty and recovery controls.
+Getting started emphasizes the first confirmed incomplete step with the primary button while leaving every step independently available. Only authoritative, successful zero-Session reads replace the activity chart with first-use guidance. Missing and failed reads retain their uncertainty and recovery controls.
-Configuration controls show concise labels, values and actions. Put necessary explanatory policy text behind a `HelpTip` question mark; do not add persistent small-print helper text or note paragraphs. Validation and request failures remain visible beside the affected action or field.
+Configuration controls show concise labels, values and actions. Validation and request failures remain visible beside the affected action or field.
diff --git a/apps/web/PRODUCT.md b/apps/web/PRODUCT.md
index e7320e85a..98a0c9709 100644
--- a/apps/web/PRODUCT.md
+++ b/apps/web/PRODUCT.md
@@ -31,22 +31,22 @@ The console runs beside the administrator's own Core, with execution, files and
- **Monitor**: Overview (service status, running Sessions, sandbox slots, the Needs attention count for the last 24 hours, 24-hour Session activity, a compact inventory of Core and up to four nodes, prioritizing offline and degraded nodes when the list is full, where Core opens Core metrics, a node opens its page on Nodes and E2B opens Sandbox metrics, the Needs attention table, whose rows name each Session, its project, its one-line reason and last activity and open it, with older ones left to the Session log, usage by project), Core metrics (whether Core can run Turns: execution slots, the Turn queue, its p95 wait and interrupted Turns, connected daemons, database latency, the Core process's CPU and memory, and background jobs; Go heap, goroutines and the database pool sit in a collapsed Diagnostics area), Agent metrics (requests, errors, duration, tokens, models, tools, Agents and API keys for 1 h / 6 h / 24 h / 7 d), Sandbox metrics (hosted Runtimes across projects over time, active against total; a sandbox opens in a dialog with its figures and CPU and memory charts; an E2B deployment adds what Core holds in E2B's cloud), Request log (recent public or administration HTTP requests, status, duration, safe error code and correlation IDs; bounded to the serving Core instance, with manual refresh and no body capture), Session log (every Session, read-only, with a failed Session's reason under its status, opening one Session's history, which jumps to its failed Turns; a self-hosted Session's page also has its environment's executor credentials). Session facts and Agent metrics link to an Agent's page only when that saved resource exists; inline snapshots and snapshots of deleted Agents remain readable without a broken resource link. Agent metrics' failed Turns open the Agent's Sessions in the Session log.
- **Resources**: Agents, Environment templates, Skills, Files, Vaults. Each list shows one project or all projects, with a Project column when all are shown and a Creator column naming the creating key. Detail pages show the resource's facts and offer Delete. An empty list says, in one sentence, that applications create these resources through the Agents API, and links to that resource's section of the API guide; Agent metrics does the same for Sessions.
-- **Platform**: Projects and keys (projects, their assets and usage, named keys, write history), Nodes (the node list, each node's capacity and limits, host figures and charts, allocations, Add node, Edit node and individual removal operations), and Settings, the single entry for platform configuration. Settings has four groups: Sandbox and scheduling, Workspace storage, Models and credentials, and Service and deployment. Sandbox and scheduling owns setup, resource edits, rollout, reset and the idle policy, and links to Nodes for nodes and their capacity. Add node on Nodes offers Recommended or Custom limits before issuing its one-time command; installers use Core's public URL and require supported node artifacts. Edit node changes a node's name and limits; removal stays on the node page and offers the host's uninstall command. Models and credentials owns each Harness's default model and shows whether each Harness is ready: Ready when it is enabled and has a default model provider, otherwise the missing step, Model provider not set (with Set as the primary action) or Disabled (with a link to the startup settings). Getting started uses the same readiness. Service and deployment owns installation facts (the public and API base URLs, with the installation ID and source commit behind Installation details), Domain and HTTPS actions and read-only startup settings, each named by its environment variable, with a link to the configuration guide's section on changing them.
+- **Platform**: Projects and keys (projects, their assets and usage, named keys, write history), Nodes (the node list, each node's capacity and limits, host figures and charts, allocations, Add node, Edit node and individual removal operations), and Settings, the single entry for platform configuration. Sandbox and scheduling owns setup, resource edits, rollout, reset and the idle policy, and links to Nodes for nodes and their capacity. Add node on Nodes offers Recommended or Custom limits before issuing its one-time command; installers use Core's public URL and require supported node artifacts. Edit node changes a node's name and limits; removal stays on the node page and offers the host's uninstall command. Models and credentials owns each Harness's default model and shows its [readiness](../../docs/configuration.md#runtime-settings-web), with Set as the primary action when the model provider is not set and a link to the startup settings when it is disabled. Getting started uses the same readiness. Service and deployment owns installation facts (the public and API base URLs, with the installation ID and source commit behind Installation details), Domain and HTTPS actions and read-only startup settings, each named by its environment variable, with a link to the configuration guide's section on changing them.
- A node whose provider is not ready names the reason as one Provider-neutral readiness class (provider unavailable, host unsupported, provider files or Runtime image missing, a host too small) and its fix in the help tip beside its status, wherever that status shows.
- A node enrolled with an earlier Core address gets no new sandboxes, so on the Nodes list and its page its status is Old address, with "Remove and add again", never Available.
-- **Sandbox reset** is an explicit administrator operation in Settings → Sandbox and scheduling. Auto clear is the default, with a one-hour deadline (5 minutes–24 hours); Force clear requires destructive confirmation. Reset stops new hosted Session admission, clears idle, suspended and pending hosted work, and waits for busy Turns and file writes until Core forces the remaining work. It does not affect self-hosted execution. Histories and persisted Files/Artifacts remain; archived Sessions cannot resume, and unpersisted workspace contents may be lost. Cancel stops further clearing without undoing archives. Core alone reports progress and completion, including resources blocked on named offline nodes; force does not bypass their cleanup. Completion clears the backend configuration and retires old nodes/enrollment credentials. A new configuration is then a separate deliberate save.
+- **Sandbox reset** is an explicit administrator operation in Settings → Sandbox and scheduling. Auto clear is the default, with a one-hour deadline (5 minutes–24 hours); Force clear requires destructive confirmation. Its semantics are defined in [Reset](../../contracts/agents-api/sandbox-deployment.md#reset); Web shows only Core's progress and completion, and a new configuration is a separate deliberate save.
- **Online sandbox configuration** changes the same backend's resources or E2B template without retiring existing nodes or changing existing Sessions' resource ownership. New placement follows Core's qualified capacity; saving a target does not promise immediate placement on it. Configuration rollout shows Core's target preparation and retained previous-generation sandbox count. A settled rollout can still have failed or unknown nodes and old resources. An offline node stays offline even when it has a recorded serving generation. Node and allocation detail distinguish the serving pin, target preparation and each resource's configuration generation.
- **E2B credential replacement** uses the same configuration form. Setup requires a key; leaving it blank during an update keeps the saved key. An explicit key, even the same value, is verified as a replacement and advances the target generation after successful verification. Another backend or E2B team requires a deliberate reset. A rejected or uncertain replacement never clears the committed configuration or replays the write.
- **E2B deployments** have no machines: Nodes offers a link to Settings → Sandbox and scheduling. Overview and Sandbox metrics show the sandboxes Core holds in E2B's cloud (running, starting, size, template build) instead of node capacity, with no Add node action; a sandbox's dialog adds its disk use.
-- **Automatic suspension** appears when the deployment declares a suspension policy. Nodes shows each node's suspended count and retained limit, the most sandboxes it keeps running and suspended together, with Edit node for its limits; Overview adds the suspended total of all registered nodes under its sandbox slots. Settings → Sandbox and scheduling owns **Automatic suspension**: deployment-wide idle seconds are editable there; snapshot retention remains read-only. Necessary policy explanations belong in help tips, not persistent helper paragraphs. These are Core records, not measured CPU or memory savings. Node allocations show the recorded compute phase and elapsed phase time, never an inferred snapshot-expiry countdown. Sandbox metrics' Hosted Runtimes has one Status column: Core's lifecycle record of each sandbox (Active, Suspended, Changing state, Waiting for allocation or Stopped), which Core derives from the allocation's recorded phase. The Session page's Runtime state reads the same way. When an active sandbox has no sample, its CPU and Memory cells name why. Independent workspace persistence is explained only when the deployment declares it. Nodes refreshes its inventory every 30 seconds while visible; reset and active preparation retain their faster polling.
+- **Automatic suspension** appears when the deployment declares a suspension policy. Nodes shows each node's suspended count and retained limit, the most sandboxes it keeps running and suspended together, with Edit node for its limits; Overview adds the suspended total of all registered nodes under its sandbox slots. Settings → Sandbox and scheduling owns **Automatic suspension**: deployment-wide idle seconds are editable there; snapshot retention remains read-only. These are Core records, not measured CPU or memory savings. Node allocations show the recorded compute phase and elapsed phase time, never an inferred snapshot-expiry countdown. Sandbox metrics' Hosted Runtimes has one Status column: Core's lifecycle record of each sandbox (Active, Suspended, Changing state, Waiting for allocation or Stopped), which Core derives from the allocation's recorded phase. The Session page's Runtime state reads the same way. When an active sandbox has no sample, its CPU and Memory cells name why. Independent workspace persistence is explained only when the deployment declares it. Nodes refreshes its inventory every 30 seconds while visible; reset and active preparation retain their faster polling.
- **Getting started**: signing in opens the console on the Overview; nothing is forced first. While a step is to do, a Getting started checklist on the Overview shows four steps, in any order, each with its state and one action: sandboxes ready (a saved deployment and a node online and ready, or a saved E2B deployment whose template build is not reported as not ready), a default model provider on the default Harness (on any enabled Harness when none is default), a project with an active key, and a first Session, whose action opens the call samples of the newest active project, preferring one with an active key. Completion comes from reads the console already makes. It can be hidden; Show Getting started in the sidebar opens it again, and it ends with a brief "You're set". While it is open, Add node ends with the next step once its node is ready: the default model provider while that is to do, otherwise back to the checklist. The optional three-chapter tour of the console (Monitor, Resources, Platform) opens from it, on the sign-in stage.
- Terminology: API terms stay in English in the Chinese UI and docs (Agent, Session, Turn, Item, Runtime, Environment, Skill, Vault, Credential, Harness); providers are 提供商 (沙箱提供商, 模型提供商). The sign-in credential is the Core key ("Core 密钥"); keys issued in a project for applications are project API keys ("项目 API 密钥"). Empty lists read "No … yet" ("还没有…"). Sandbox provider readiness is "Provider not ready / 沙箱提供商未就绪"; revoked credentials and keys use "Revoked / 已撤销". A default model provider is a service address and write-only key; the application's Agent `model` chooses the provider-supported model name. A sandbox is Core-managed compute; Runtime names Core's execution observations, and Environment is the Session's API execution environment. These are distinct counts and resources, not synonyms.
## Capabilities and Constraints
- **Projects and keys.** A project owns an isolated set of assets shared by all of its named API keys; projects do not see each other's assets. Issuing or revoking a key never touches assets. The list shows active projects by default; the Archived filter, with its count, shows the rest. Archiving a project revokes every key and keeps its assets viewable and deletable; it can't be undone, so its confirmation says so, counts the active keys it revokes and, when there are any, asks for the project's name. Key plaintext is shown once, at issuance, and never stored by the console. Beside it, and without the key on an active project's page, the console tells developers to set `OPENAI_BASE_URL` (the installation's API base URL) and `OPENAI_API_KEY` (a key of the project), with curl and Python samples that list Agents and create a Session.
-- **One home for each setting.** Settings owns each platform configuration editor. Overview, Nodes, metrics and onboarding navigate to its relevant group rather than duplicating forms. Each resource saves through its existing API independently; there is no cross-resource save. Process settings remain file-owned and read-only in Web. Projects, API keys and Session executor credentials remain on their resource pages. Capacity is node-owned, idle policy is deployment-wide, and sandbox specifications are independent of node limits. Resource editing uses a dialog; rollout counts and generations appear in its details dialog. Settings shows configuration and the status that qualifies it, not capacity figures. Each fact has one page: Nodes owns the node list, per-node capacity and host figures; Overview summarizes capacity and links to Nodes; Sandbox metrics owns Runtime time series and activity; Core metrics owns the Core process. Reset sits apart at the end of Sandbox and scheduling, and leads it while a reset runs.
-- **Workspace storage.** Settings → Workspace storage owns selecting an immutable configuration and editing tenant capacity through the existing storage API. It shows the adapter and tenant capacity; the configuration ID and adapter parameters stay under Configuration details. Adapter parameters and optional write-only credentials are JSON objects validated by Core, with no vendor-specific Web fields or capability discovery by name. Selecting a new configuration does not migrate existing workspaces; changing tenant capacity does not resize them. Credentials are never prefilled, stored in browser persistence or included in error output. Uncertain writes require an authoritative read before another save.
+- **One home for each setting.** Settings owns each platform configuration editor. Overview, Nodes, metrics and onboarding navigate to its relevant group rather than duplicating forms. Each resource saves through its API independently; there is no cross-resource save. Process settings remain file-owned and read-only in Web. Projects, API keys and Session executor credentials remain on their resource pages. Capacity is node-owned, idle policy is deployment-wide, and sandbox specifications are independent of node limits. Resource editing uses a dialog; rollout counts and generations appear in its details dialog. Settings shows configuration and the status that qualifies it, not capacity figures. Each fact has one page: Nodes owns the node list, per-node capacity and host figures; Overview summarizes capacity and links to Nodes; Sandbox metrics owns Runtime time series and activity; Core metrics owns the Core process. Reset sits apart at the end of Sandbox and scheduling, and leads it while a reset runs.
+- **Workspace storage.** Settings → Workspace storage owns selecting an immutable configuration and editing tenant capacity through the storage API. It shows the adapter and tenant capacity; the configuration ID and adapter parameters stay under Configuration details. Adapter parameters and optional write-only credentials are JSON objects validated by Core, with no vendor-specific Web fields or capability discovery by name. Selecting a new configuration does not migrate existing workspaces; changing tenant capacity does not resize them. Credentials are never prefilled, stored in browser persistence or included in error output. Uncertain writes require an authoritative read before another save.
- **Web API only.** Every read and write goes through `/core/v1/**`. The console holds no API key and sends nothing to `/v1`.
- **No asset writes except delete.** Assets are created and changed only by a project's keys through the Agents API. The console does not create or edit Agents or Templates, upload Skills or Files, create or replace Credentials, start Sessions, send input or cancel work. Deletion follows the public deletion rules; a busy Session is not deletable and the console never cancels work to make it so.
- **Secrets stay write-only.** Credential tokens, Template environment variables and setup commands are never returned, to the administrator included. An Agent's saved model provider shows its protocol, base URL, limits and whether a key is configured, never the key.
@@ -62,7 +62,7 @@ The console runs beside the administrator's own Core, with execution, files and
- **Typed errors.** Every failure the console shows, read or write, follows one rule. Known Core codes use shared bilingual copy and safe typed details. Exact Core field paths attach definite refusals to the relevant input. Other codes show Core's own message in English and name the code in Chinese, since Core's messages are English; a failure without a code names its HTTP status, and one that never reached Core says so. Uncertain write outcomes stay form-level and are never retried automatically.
- **Read failures.** A read is tried again once after a 5xx answer or a failed connection, never after a 4xx answer. Overview and Session log distinguish unavailable reads from successful empty results. Failed reads have a visible retry; a first read that fails never mentions earlier data; retained or partial data says it may be incomplete or out of date, and Session filter totals stay missing while any required read has failed. Only successful empty reads show zero.
- **Local-only address.** Overview, Nodes and Settings warn when Core reports `local_only` and lead to Settings → Service and deployment to review the public address. Add node is unavailable with a reason; Getting started keeps the first step to do until the public address is fixed. An unread installation address cannot complete that step, and a failed read offers Retry.
-- **Figures.** Project, Agent and key usage comes from Core's summary; Agent run, tool and activity figures are still assembled in the browser from bounded reads and state their coverage. Metrics that would need new Core endpoints are not simulated. Usage is cumulative per Session and is not billing.
+- **Figures.** Project, Agent and key usage comes from Core's summary; Agent run, tool and activity figures are assembled in the browser from bounded reads and state their coverage. Metrics that would need new Core endpoints are not simulated. Usage is cumulative per Session and is not billing.
- Runtime CPU and memory exist only for Core-managed hosted sandboxes.
- Preserve workflow safety: confirmed deletion, no automatic retry of uncertain writes, no secrets in browser storage.
@@ -87,4 +87,4 @@ The console runs beside the administrator's own Core, with execution, files and
## Accessibility & Inclusion
-Keyboard navigation with visible focus, reduced-motion support, and bilingual Chinese/English copy through the existing i18n modules.
+Keyboard navigation with visible focus, reduced-motion support, and bilingual Chinese/English copy through the i18n modules.
diff --git a/contracts/agents-api/admin-api.md b/contracts/agents-api/admin-api.md
index 907d9e989..6a8bb075c 100644
--- a/contracts/agents-api/admin-api.md
+++ b/contracts/agents-api/admin-api.md
@@ -63,7 +63,7 @@ A sensitive setting has null `value` and `default` and a boolean `configured` in
| `address_bindings` field | Meaning |
| --- | --- |
| `nodes` | Enrolled nodes that are not removed |
-| `nodes_on_other_address` | Nodes enrolled with an address other than `public_url`. They receive no new sandboxes; remove and add them again. At most `nodes` |
+| `nodes_on_other_address` | Nodes enrolled with an address other than `public_url`. They receive no new sandboxes; see [Change the public URL](../../docs/getting-started/public-address.md#changing-the-public-url). At most `nodes` |
| `hosted_sandboxes` | Retained and pending hosted sandboxes, which run with the address current when they started |
| `self_hosted_executors` | Unrevoked executor credentials, whose executors were installed with the `remote_url` then advertised |
@@ -223,13 +223,13 @@ The response is `{data, has_more, next_cursor}`. Each row has `project_id`, null
`GET /core/v1/request-logs` is a Core-key-only diagnostic read for Web's **Request log** and operator scripts. It observes HTTP requests that reach Core's `/v1` and `/core/v1` APIs, including rejected authentication and unsuccessful responses. The log read itself, health and documentation endpoints, Web sign-in/proxy failures before Core, machine transports and background execution are outside this view. It is not an audit archive or a distributed execution trace.
-Each API instance retains the most recent 1,000 started requests for each surface independently: `public` for `/v1`, `admin` for `/core/v1`. Administration polling cannot evict application requests. Older entries, including long-lived requests, are overwritten when their surface fills. Restart clears the rings. `instance_id` and `instance_started_at` identify the serving API instance; a load balancer can return another instance's window. Core also emits each request's completion metadata through its existing structured logger; retention of that output belongs to the operator's log system, not this endpoint.
+Each API instance retains the most recent 1,000 started requests for each surface independently: `public` for `/v1`, `admin` for `/core/v1`. Administration polling cannot evict application requests. Older entries, including long-lived requests, are overwritten when their surface fills. Restart clears the rings. `instance_id` and `instance_started_at` identify the serving API instance; a load balancer can return another instance's window. Core also emits each request's completion metadata through its structured logger; retention of that output belongs to the operator's log system, not this endpoint.
Query parameters are `surface=public|admin` (default `public`), `limit` (1–200, default 100), optional exact `request_id`, `outcome=all|errors|active` (default `all`) and optional `method`. Supported method values are `GET`, `HEAD`, `POST`, `PUT`, `PATCH`, `DELETE`, `OPTIONS`, `CONNECT`, `TRACE` and `OTHER`; other incoming methods are recorded as `OTHER`. Unsupported, repeated or malformed query parameters return 400. `errors` includes HTTP status 400 or above and aborted requests. Filtering scans only the retained window and returns newest-started first. `retained_count` describes that surface's retained window, `total_matching` counts retained matches, and `has_more` means the response limit omitted matches; it does not promise older evicted history is available.
The response has `object: "core.request_log.list"`, instance identity, `surface`, `capacity`, coverage counts and `data`. Each entry contains `request_id`, `trace_id`, `started_at`, `method`, `route`, `state`, `status`, `duration_ms`, `response_bytes` and nullable `error_code`. `route` is a registered route template, a partially matched authentication prefix or `(unmatched)`, never the raw resource path or query. `status` is null until final response headers are committed. `state` distinguishes `active`, `completed` and `aborted`; duration and bytes describe the observation so far for active requests. `response_bytes` counts bytes accepted by the response writer, excluding headers and transport framing; it is not a network transfer measurement. An SSE response remains active until its handler ends. HTTP status and completion do not establish the outcome of an asynchronous Agent Turn; use [Session diagnostics](./session-diagnostics.md) and the Session's recorded history for that outcome.
-Bodies, header values, credentials, prompts, file contents, raw paths, query values and error messages are not captured. Only the API's safe error code is retained. The returned request ID corresponds to `X-Request-Id` and can be used to find related existing process log entries. Trace IDs are correlation metadata, not proof of a complete component trace.
+Bodies, header values, credentials, prompts, file contents, raw paths, query values and error messages are not captured. Only the API's safe error code is retained. The returned request ID corresponds to `X-Request-Id` and can be used to find related process log entries. Trace IDs are correlation metadata, not proof of a complete component trace.
## Audit log
diff --git a/contracts/agents-api/core-metrics.md b/contracts/agents-api/core-metrics.md
index dba1d1b7e..088ae46e9 100644
--- a/contracts/agents-api/core-metrics.md
+++ b/contracts/agents-api/core-metrics.md
@@ -33,7 +33,7 @@ The response has `object: "core.metrics"`, `range`, `service`, `execution`, `dat
| `service.revision` | The full source commit injected at build time; null for builds without one |
| `service.started_at` | When the process initialized |
| `service.execution_owner` | Whether this process holds the execution worker's database lease |
-| `execution.slots_in_use`, `execution.slots_total` | Active Session reservations of the execution worker, and its capacity: [`OAC_EXECUTION_CONCURRENCY`](../../docs/configuration.md#settings), 4 by default. Environment input, Turns and file work share the slots; native Harness subprocesses are not counted |
+| `execution.slots_in_use`, `execution.slots_total` | Active Session reservations of the execution worker, and its capacity: [`OAC_EXECUTION_CONCURRENCY`](../../docs/configuration.md#settings). Environment input, Turns and file work share the slots; native Harness subprocesses are not counted |
| `execution.queued_turns`, `execution.in_progress_turns` | Root Turns in those states, including Turns of deleted Sessions. Subagent Turns and input reserved for a preparing Environment are not counted |
| `execution.waiting_for_daemon` | Queued Turns whose Session's device is not connected |
| `execution.oldest_queued_seconds` | Age of the oldest queued Turn, from its `created_at` |
diff --git a/contracts/agents-api/environment-executor-credentials.md b/contracts/agents-api/environment-executor-credentials.md
index 06863c4e4..cf0febd48 100644
--- a/contracts/agents-api/environment-executor-credentials.md
+++ b/contracts/agents-api/environment-executor-credentials.md
@@ -73,7 +73,7 @@ Issue, rotate and revoke each record an administrator audit entry (`resource_typ
## Connection status
-The list's required `connection` object contains `status` (`never_enrolled`, `connected` or `disconnected`), `bound_key_id`, `enrolled_at` and `last_seen_at`. All three binding fields are null before enrollment. Once enrolled, the bound key and enrollment time describe the existing device; a null `last_seen_at` means no authenticated heartbeat has been recorded. Issuing another key does not change the binding. Rotation or revocation can make the binding disconnected while its history remains visible. Expired Environments remain readable under the existing list rules but cannot have current executor authority.
+The list's required `connection` object contains `status` (`never_enrolled`, `connected` or `disconnected`), `bound_key_id`, `enrolled_at` and `last_seen_at`. All three binding fields are null before enrollment. Once enrolled, the bound key and enrollment time describe the device; a null `last_seen_at` means no authenticated heartbeat has been recorded. Issuing another key does not change the binding. Rotation or revocation can make the binding disconnected while its history remains visible. Expired Environments remain readable under the existing list rules but cannot have current executor authority.
Connected means the Environment is connected, its device and executor key still have current Core authority, and the process-local gateway has an open peer that authenticated with that current key. Core rechecks authority after observing the peer. A former key's live socket, a device timestamp or a ready-looking Environment alone is insufficient; without a gateway, Core never returns connected. These facts are an observation, not a reservation of connectivity or of native or model readiness. `last_seen_at` may lag by a heartbeat interval.
diff --git a/contracts/agents-api/environment-files.md b/contracts/agents-api/environment-files.md
index 20ef28246..67fcc1345 100644
--- a/contracts/agents-api/environment-files.md
+++ b/contracts/agents-api/environment-files.md
@@ -12,7 +12,7 @@ The routes follow the SDK pinned in [upstream.json](https://github.com/MiniMax-A
- Public paths start at `/workspace`, which stands for the Environment's workspace directory wherever it is on the machine.
- The Environment is looked up in the caller's Project first; a missing or foreign ID returns 404.
- On an `openai_hosted` Environment that is still `pending`, both operations return 400 `the hosted environment is still provisioning; wait until it is connected before accessing files`. This check runs after request validation and before any source File lookup. Any other state proceeds, and an unreachable Runtime returns 503.
-- File operations wait within their existing request deadline for Environment initialization to complete; `connected` alone does not imply readiness, and failed initialization or exhausted execution capacity still returns 503.
+- File operations wait within their request deadline for Environment initialization to complete; `connected` alone does not imply readiness, and failed initialization or exhausted execution capacity still returns 503.
- Listing and writing never start a Turn or send input to the model.
## List files
@@ -78,7 +78,7 @@ Unless the table names a code, the 400 errors have type and code `invalid_reques
- Before sending any bytes, Core records the write under the Session lock. While input is pending, a Turn is running or an earlier write is unsettled, a new write returns 409 `turn_conflict`. An unsettled write also makes new messages to the Session return 409.
- The Runtime checks the complete body against its digest before creating anything, so incomplete input creates nothing. A write that fails later can leave newly created empty parent directories.
-- Only a definite receipt from the Runtime settles a write, as committed or rejected. A rejected write publishes no destination file and releases the Session; newly created empty parent directories can remain. Storage or quota exhaustion confirmed before publication returns 503, while malformed input and destination conflicts retain their existing errors. If the connection drops, the request times out or no receipt arrives, the request returns 503 and the write stays unsettled, across Core restarts. Core never resends it and has no automatic recovery, so the Session accepts no further writes or messages. Reads still work.
+- Only a definite receipt from the Runtime settles a write, as committed or rejected. A rejected write publishes no destination file and releases the Session; newly created empty parent directories can remain. Storage or quota exhaustion confirmed before publication returns 503, while malformed input and destination conflicts retain their errors. If the connection drops, the request times out or no receipt arrives, the request returns 503 and the write stays unsettled, across Core restarts. Core never resends it and has no automatic recovery, so the Session accepts no further writes or messages. Reads still work.
- Deleting the source File after its bytes were read does not affect the copy.
## Artifacts
diff --git a/contracts/agents-api/environments.md b/contracts/agents-api/environments.md
index 03dc68551..267de102c 100644
--- a/contracts/agents-api/environments.md
+++ b/contracts/agents-api/environments.md
@@ -318,7 +318,7 @@ For comparison, an inline `openai_hosted` Session without a Template treats omit
### Preparation reuse
-Core may start a hosted Environment from the result of an earlier preparation in the same Project whose effective configuration, after Template composition, is identical, for up to 24 hours after that preparation. Each Session still gets its own copy. Setup commands and package installation then do not run again for this Session. Only `/environment` is reused (see the workspace filesystem scope); HOME and other compute-local changes are not. Setup must not create per-Session unique values, perform external side effects that must happen per Session, or fetch credentials that expire within 24 hours; configurations that need this must differ, for example in `env` or `files`. A Provider that does not declare the [preparation cache](../../docs/sandbox-provider.md#explicit-operation-contracts) always prepares in full.
+Core may start a hosted Environment from the result of an earlier preparation in the same Project whose effective configuration, after Template composition, is identical, for up to 24 hours after that preparation. Each Session still gets its own copy. Setup commands and package installation then do not run again for this Session. Only `/environment` is reused (see [Lifetime and filesystem scope](../../docs/workspace-provider.md#lifetime-and-filesystem-scope)); HOME and other compute-local changes are not. Setup must not create per-Session unique values, perform external side effects that must happen per Session, or fetch credentials that expire within 24 hours; configurations that need this must differ, for example in `env` or `files`. A Provider that does not declare the [preparation cache](../../docs/sandbox-provider.md#explicit-operation-contracts) always prepares in full.
### Restricted network
@@ -357,7 +357,7 @@ template = client.beta.agents.environments.templates.create(
)
```
-The pinned `/v1/skills` resource, version and content routes use the Project API key without the Agents beta header. ZIP uploads use `files` and directory uploads repeated `files[]`. The pinned SDK 3.13.0 drops a single file tuple during multipart extraction, so upload a single ZIP with raw HTTP. An upload holds at most 500 regular files and exactly one `SKILL.md`, 5 MiB compressed and 20 MiB expanded. [File resource semantics](./source-files.md#versions-and-metadata) owns default-version and deletion rules.
+The pinned `/v1/skills` resource, version and content routes use the Project API key without the Agents beta header. ZIP uploads use `files` and directory uploads repeated `files[]`. [Upload a bundle](./source-files.md#upload-a-bundle) owns the bundle format, upload limits and the SDK single-file limitation; [versions and metadata](./source-files.md#versions-and-metadata) owns default-version and deletion rules.
A reference with an omitted or null version selects the default at Session creation, `"latest"` the latest version, and a positive version string that version. Template responses keep the unresolved selector (`version: null` for the default); Session metadata shows `{type, skill_id, version, name, description}` with a concrete version. A Session freezes the selected version's bytes and metadata in its creation transaction; later default changes, source deletion or Template updates cannot change it.
@@ -380,8 +380,7 @@ A Plugin is an inline ZIP with type, name and description whose single archive r
Skills and their immutable versions are Project resources, independent of Sessions and native installations.
-- Version allocation and pointer changes serialize on the owning Skill row. The top-level name and description follow the default version in the same transaction; non-default uploads keep them. Version identities stay unique across concurrent uploads and deletion.
-- Bundles are encrypted with the service cipher, bound to Project, Skill and version. Metadata reads never load or decrypt bundles. Deleting a Skill reclaims its versions without affecting frozen Sessions.
+- Version allocation, default-version changes and serialization are defined in [Versions and metadata](./source-files.md#versions-and-metadata), and bundle encryption in [Upload a bundle](./source-files.md#upload-a-bundle). Metadata reads never load or decrypt bundles. Deleting a Skill reclaims its versions without affecting frozen Sessions.
- References resolve inside the Session creation transaction, after the upsert establishes ownership. Referenced resources are locked in a stable order, and the version, metadata and bytes freeze together. Public reference metadata, unresolved Template intent and the resolved Runtime bundle stay distinct; a reference is never reported as inline.
Inline and referenced Skills use the same confidential snapshot and installer. The Runtime installs them under `skills/` in its capability root before setup and native execution. Adapters register only the selected Skill roots: Codex as explicit extra roots, MiniMax Code through its native catalog, and Claude as user Skills under its private state path, so native lists the bare names a local `~/.claude/skills` gives. Claude rejects a Skill that contains `.claude-plugin`, because native would load it as a plugin with its hooks and MCP servers. Skill roots activate no MCP servers; only [Plugin MCP](#plugin-mcp) does. Codex scans each Skill root recursively as it does locally, so a nested `SKILL.md` registers another native Skill. Native Harness configuration is never passed through wholesale.
diff --git a/contracts/agents-api/harness-capabilities.md b/contracts/agents-api/harness-capabilities.md
index 9385052b6..ad446300e 100644
--- a/contracts/agents-api/harness-capabilities.md
+++ b/contracts/agents-api/harness-capabilities.md
@@ -24,7 +24,7 @@ Placements are `none` (no Environment), hosted (`openai_hosted`) and self-hosted
| [Message images](./message-content.md#images) | PNG and JPEG data URLs: verified on all placements; other data URLs: admitted; remote URLs: rejected | PNG and JPEG data URLs: verified on all placements; remote URLs and GIF and WebP data URLs: admitted | Rejected |
| `reasoning.effort` | `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`: admitted | `low`, `medium`, `high`, `xhigh`, `max`: admitted | `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`: admitted |
| `reasoning.summary` | `concise`, `detailed`, `auto`: admitted | `auto`: admitted | Rejected |
-| `service_tier` other than `auto` | `default`, `flex`, `priority`: admitted | Rejected | Rejected |
+| `service_tier` other than `auto` | `default`, `flex`, `priority`, `fast`: admitted | Rejected | Rejected |
| `text.verbosity` other than `medium` | Admitted; the native model decides | Rejected | Rejected |
| [Public token usage](./sessions-events.md) | Measured counters | Null | Null |
@@ -39,7 +39,7 @@ Native model parameters and provider protocols per Harness are in [model executi
| [Structured output](./execution-tools.md#structured-output) | Admitted on all placements | Verified on all placements | Rejected |
| [Deferred function discovery](./execution-tools.md#deferred-function-discovery) | Rejected | Verified: `none`, self-hosted; admitted: hosted | Rejected |
| [Disabled web search and programmatic tool calling](./execution-tools.md#web-search-and-programmatic-tool-calling) | Verified: `none`; admitted: hosted, self-hosted | Verified: `none`; admitted: hosted, self-hosted | Verified: `none`; admitted: hosted, self-hosted |
-| Web search `cached` or `live` and programmatic tool calling `enabled` | Admitted on all placements | `live` admitted on all placements; `cached` and `enabled` rejected | Rejected |
+| Web search `cached` or `live` and programmatic tool calling `enabled` | Admitted on all placements; `enabled` is rejected together with `multi_agent` | `live` admitted on all placements; `cached` and `enabled` rejected | Rejected |
| [Service-origin HTTP MCP](./environments.md#public-mcp-connection-origin) | Verified: `none`; rejected elsewhere | Verified: `none`; rejected elsewhere | Verified: `none`, with `allowed_tools` null and `required` false only; rejected elsewhere |
| [Environment-origin HTTP MCP](./environments.md#public-mcp-connection-origin) | Verified: hosted, self-hosted | Verified: hosted, self-hosted | Verified: hosted, self-hosted; `allowed_tools` null and `required` false only |
| [Stdio MCP](./execution-tools.md#mcp) | Admitted: hosted, self-hosted | Admitted: hosted, self-hosted; `cwd` must be the workspace directory and `allowed_tools` null | Rejected |
diff --git a/contracts/agents-api/harness-onboarding.md b/contracts/agents-api/harness-onboarding.md
index df391130f..a90b8b86e 100644
--- a/contracts/agents-api/harness-onboarding.md
+++ b/contracts/agents-api/harness-onboarding.md
@@ -190,7 +190,7 @@ The declaration holds:
- `Execution`, the official execution option values the adapter maps to native settings: web search modes and whether search settings are accepted, reasoning efforts and summaries, service tiers, programmatic-tool-calling values and text verbosities. Core admission and the Runtime reject an undeclared value with the same check ([tool policy](./execution-tools.md#web-search-and-programmatic-tool-calling)). Core always sends the official default text verbosity, so `TextVerbosities` must include `medium`;
- optional pure restrictions, `ValidateConfiguration`, `ValidateTools`, `ValidateMessageInput` and `ValidateFunctionResult`, that add native limits to the common checks. `ValidateMessageInput` runs only for messages that carry images, after the `MessageImages` capability check and before anything is stored, and decides which `image_url` values the Harness accepts; Core checks only that the reference is not blank. A nil validator means the common checks suffice. They cannot query business data, decrypt credentials or control native processes. Configuration restrictions run first, and a tool-decoding error precedes `ValidateTools`.
-`harnessconfig.NewRegistry` validates every declaration and panics on an invalid or duplicate one: kinds and labels must be nonempty, placements must list at least one supported placement, MCP origins must be a non-nil list, unknown or duplicate choices and origins without a corresponding placement are rejected, and bearer support requires an MCP origin, and `Execution` must declare text verbosity `medium`. Shared dispatch checks capability combinations, never engine names.
+`harnessconfig.NewRegistry` validates every declaration and panics on an invalid or duplicate one: kinds and labels must be nonempty, placements must list at least one supported placement, MCP origins must be a non-nil list, unknown or duplicate choices and origins without a corresponding placement are rejected, bearer support requires an MCP origin, and `Execution` must declare text verbosity `medium`. Shared dispatch checks capability combinations, never engine names.
The Runtime binding in `apps/daemon/internal/agent//declaration.go` embeds the same declaration and adds `Discover`, which owns native availability probes and factories and only narrows the declared capabilities to what the installation verified. The binding test `TestDiscoveryOnlyNarrowsDeclaration` checks that discovery never exceeds the declaration. `harnessconfig/harnesstest.Declaration` builds a synthetic declaration for tests.
diff --git a/contracts/agents-api/index.md b/contracts/agents-api/index.md
index 69e35d493..f0ef5ea4b 100644
--- a/contracts/agents-api/index.md
+++ b/contracts/agents-api/index.md
@@ -36,7 +36,7 @@ Evidence for a status comes from the pinned official SDK and raw HTTP against th
| Environments | retrieve | Implemented; Session-scoped ([ownership](./environments.md#resources-and-states)). The pinned contract rejects `environment.environment_id`; existing hosted Environments cannot be attached across Sessions. Workspaces shared across Sessions belong to the application ([Projects own assets](../../docs/concepts.md#projects-own-assets)) | [Environments](./environments.md) |
| Environment files | create, list | Implemented; the list is not recursive | [Environment files and Artifacts](./environment-files.md) |
| Environment Templates | create, retrieve, update, list, delete | Implemented; execution limits are listed under [known gaps](#known-gaps) | [Environment Templates](./environments.md#templates) |
-| Vaults | create, retrieve, list, delete | Implemented; no archive operation | [Vaults and Credentials](./vaults.md) |
+| Vaults | create, retrieve, list, delete | Implemented | [Vaults and Credentials](./vaults.md) |
| Vault Credentials | create, retrieve, update, list, delete | Implemented for `static_bearer` and `mcp_oauth` | [Vaults and Credentials](./vaults.md) |
| Files | create, retrieve, list, delete, content | Implemented for `purpose=user_data`; content download is rejected | [Files and Skills](./source-files.md) |
| Skills and Skill versions | create, retrieve, update, list, delete, content | Implemented | [Files and Skills](./source-files.md) |
@@ -80,7 +80,7 @@ Each item is Core's deliberate or native behavior where the official service beh
- Core rejects an inline `authorization` on a Session MCP transport, an `Authorization` entry in `headers` and a nonempty stdio `env`: credentials come only from Vaults (`credential_id`) and environment values only from the Environment (`env_vars`) ([MCP](./execution-tools.md#mcp)).
- A `stdio` MCP server needs a workspace placement and the origin `environment`. Claude Code starts the server in its workspace directory, so `cwd` must equal it, with its whole process environment, which also holds the model provider key and other servers' Vault bearer tokens, and it needs `allowed_tools` null. MiniMax Code starts the server in its private home directory, so it rejects every `stdio` server ([MCP](./execution-tools.md#mcp)).
- Claude rejects an MCP `server_url` or `headers` value containing `${`, because the native client expands `${VAR}` in both from a process environment that holds Core-held credentials.
-- Deleting a Session right after an events 202 returns 409, because Core admits the Turn in the same transaction; the official service returned 200.
+- Deleting a Session right after an events 202 returns 409, because Core admits the Turn in the same transaction; the official service returns 200.
**Input, events and history** ([Sessions, events and history](./sessions-events.md), [message content](./message-content.md))
@@ -98,7 +98,7 @@ Each item is Core's deliberate or native behavior where the official service beh
**Files, Skills, Environment files and Artifacts** ([Files and Skills](./source-files.md), [Environment files and Artifacts](./environment-files.md))
-- File uploads hold up to 512 MiB; the official limit is 512 MB. The Files list returns up to 10,000 Files by default, and a `purpose` filter other than `user_data` returns an empty page.
+- File uploads hold up to 512 MiB; the official limit is 512 MB. A `purpose` filter other than `user_data` returns an empty page.
- Skill version numbers are never reused, and uploads and deletions of one Skill run one at a time.
- Environment files work on `self_hosted` Environments, which the official service refuses.
- Creating an Environment file over an existing regular file returns the "must not traverse symlinks or overwrite existing files" message. A parent symbolic link that stays inside the workspace is followed, and a parent that escapes the workspace or is a regular file gets a generic 400; the official service rejects symbolic-link parents.
@@ -118,7 +118,7 @@ Each item is Core's deliberate or native behavior where the official service beh
**Configuration and tools**
-- A `reasoning.effort`, `reasoning.summary`, `service_tier`, `web_search` mode or setting or `programmatic_tool_calling` value that the selected Harness does not declare is saved but rejected at Session admission ([Harness capabilities](./harness-capabilities.md#execution-and-input)).
+- A `reasoning.effort`, `reasoning.summary`, `service_tier`, `text.verbosity`, `web_search` mode or setting or `programmatic_tool_calling` value that the selected Harness does not declare is saved but rejected at Session admission ([Harness capabilities](./harness-capabilities.md#execution-and-input)).
- Harness support for tools, structured output, deferred discovery, subagents and MCP differs by Harness and placement; see the [Harness capabilities](./harness-capabilities.md). MiniMax Code has no image input.
- Model-derived reasoning defaults are not resolved.
@@ -135,7 +135,7 @@ Each item is Core's deliberate or native behavior where the official service beh
**Environments and Templates**
-- Hosted workspace admission is limited by the [tenant capacity policy](../../docs/configuration.md#tenant-capacity) and the existing [input reservation deadline](./environments.md#reservations).
+- Hosted workspace admission is limited by the [tenant capacity policy](../../docs/configuration.md#tenant-capacity) and the [input reservation deadline](./environments.md#reservations).
- MiniMax Code does not declare `retained_native_history`, so it cannot run on microsandbox, which keeps every Environment on workspace storage; Core rejects the Session ([Harness capabilities](./harness-capabilities.md)).
- Only `enabled` networking runs, so Sessions that need `disabled` or `restricted` are rejected ([restricted network policy](./environments.md#restricted-network)).
- `packages.system` is rejected; system packages must be preinstalled.
@@ -148,7 +148,7 @@ Each item is Core's deliberate or native behavior where the official service beh
**Vaults and Credentials**
-- There is no archive lifecycle, storage-key rotation or re-encryption.
+- There is no storage-key rotation or re-encryption.
- OAuth refresh happens only at dispatch: there is no refresh on a provider 401, no mid-Turn replacement and no withdrawal of a token already sent to a Runtime.
- Input sent to a Session whose selected Credential was deleted is admitted and then fails at dispatch.
- Credential creation takes no `Idempotency-Key`.
diff --git a/contracts/agents-api/sandbox-deployment.md b/contracts/agents-api/sandbox-deployment.md
index 26db1bfd2..2068ea9d6 100644
--- a/contracts/agents-api/sandbox-deployment.md
+++ b/contracts/agents-api/sandbox-deployment.md
@@ -39,7 +39,7 @@ POST and PUT take the same complete selection and require `expected_generation`
| `configuration` | The provider's public selectors. E2B: the immutable `template` build and the optional paired `api_url` and `domain`. Docker and microsandbox accept only `{}` or omission |
| `credential` | The provider's write-only credential. E2B: `{api_key}`, required at first setup and omitted on PUT to keep the current key; a null or empty key is invalid. Docker and microsandbox reject it |
-The request has no Core address. Core derives the deployment's `core_url` from the installation public URL (`public_url` in `config.json`, `OAC_PUBLIC_URL` for Core): the origin nodes and sandbox guests use to reach Core. A request that contains `core_url` is rejected with 400 `invalid_request` like any other unknown member. E2B guests reach Core from E2B's cloud, so an E2B selection is rejected with 409 `sandbox_configuration_error` while the public URL is loopback. Docker and microsandbox selections accept a loopback public URL, which serves only local development because a guest's loopback address does not reach its host. Changing the public URL is an installation change: nodes enrolled with the old address receive no new sandboxes and must be removed and added again.
+The request has no Core address. Core derives the deployment's `core_url` from the installation public URL (`public_url` in `config.json`, `OAC_PUBLIC_URL` for Core): the origin nodes and sandbox guests use to reach Core. A request that contains `core_url` is rejected with 400 `invalid_request` like any other unknown member. E2B guests reach Core from E2B's cloud, so an E2B selection is rejected with 409 `sandbox_configuration_error` while the public URL is loopback. Docker and microsandbox selections accept a loopback public URL, which serves only local development because a guest's loopback address does not reach its host. Changing the public URL is an installation change; see [Change the public URL](../../docs/getting-started/public-address.md#changing-the-public-url).
### Resources
@@ -192,7 +192,7 @@ One mutation gate serializes setup, PUT, reset, cancellation and finalization. A
Node capacity is set separately from the deployment specification. `POST /core/v1/sandbox/enrollment-tokens` accepts optional `max_active` and `max_retained` and returns `{token, expires_at, enrollment_id}`; `enrollment_id` is a public handle of that command, never a credential. Core stores the token with the limits as sent, and an omitted limit stays unset. When the node enrolls, Core copies each explicit limit to it unchanged and sets each unset limit to the [recommended capacity](#recommended-capacity) of the host measurements in the enrollment request and the current specification; an unset limit with no host measurements fails with 409 `sandbox_node_host_unmeasured` and leaves the token unused. When only `max_retained` is set, the derived `max_active` never exceeds it; when only `max_active` is set, the derived `max_retained` is raised to at least `max_active`. microsandbox uses both limits. Docker never suspends, so Core replaces its `max_retained` with `max_active`, here and in PATCH. E2B has no nodes and answers 409 `sandbox_deployment_conflict`. A node cannot submit limits, but an unset limit follows the host measurements the node reports at enrollment, bounded by 1 and 1000000. Its local checks may refuse a deployment it cannot run but never raise the limits. Explicit values and later PATCH edits bind: once a node is enrolled, Core derives nothing again. [Node capacity](../../docs/configuration.md#node-capacity) explains the limits for operators.
-`GET /core/v1/sandbox/nodes` returns `{data: [...]}` with, for each node: `id`, `name`, `provider`, `online`, `last_seen_at`, `created_at`, `max_active`, `max_retained`, the counts `active`, `reserved`, `running`, `retained`, `snapshots` and `cleanup_pending`, `provider_ready`, the host measurements `cpu_count`, `available_memory_bytes` and `available_disk_bytes`, `rollout`, `recommended_capacity`, `enrollment_id` and `core_url`. `recommended_capacity` is `{max_active, max_retained}`, the [recommended capacity](#recommended-capacity) of the node's latest health and the current specification, or null until the node has reported a CPU count or effective cores and its total memory, and while the current specification does not validate. `enrollment_id` is the handle of the command that registered the node, or null when Core has none. `core_url` is the installation public URL at enrollment; a node whose `core_url` differs from the current public URL receives no new placements. Work already placed on it finishes there, including a placed Environment that has no allocation yet, and its retained sandboxes can still resume while the old address reaches Core. Remove it and add it again.
+`GET /core/v1/sandbox/nodes` returns `{data: [...]}` with, for each node: `id`, `name`, `provider`, `online`, `last_seen_at`, `created_at`, `max_active`, `max_retained`, the counts `active`, `reserved`, `running`, `retained`, `snapshots` and `cleanup_pending`, `provider_ready`, the host measurements `cpu_count`, `available_memory_bytes` and `available_disk_bytes`, `rollout`, `recommended_capacity`, `enrollment_id` and `core_url`. `recommended_capacity` is `{max_active, max_retained}`, the [recommended capacity](#recommended-capacity) of the node's latest health and the current specification, or null until the node has reported a CPU count or effective cores and its total memory, and while the current specification does not validate. `enrollment_id` is the handle of the command that registered the node, or null when Core has none. `core_url` is the installation public URL at enrollment; a node whose `core_url` differs from the current public URL receives no new placements. Work already placed on it finishes there, including a placed Environment that has no allocation yet, and its retained sandboxes can still resume while the old address reaches Core. See [Change the public URL](../../docs/getting-started/public-address.md#changing-the-public-url).
A node manages generations, so its `provider_ready` follows its serving generation and its fixed code for the target generation appears in `rollout.diagnostic`. The node classifies the first failed readiness check and sends only its code; a frame with any other value is invalid, and Core never stores or returns probe text or host paths. The codes are Provider-neutral classes: `provider_unavailable`, `host_unsupported`, `artifacts_unavailable`, `runtime_image_unavailable` and `capacity_insufficient`. [Readiness codes](../../docs/getting-started/nodes.md#readiness-codes) gives causes and operator actions. Core and nodes must come from the same distribution.
diff --git a/contracts/agents-api/subagents.md b/contracts/agents-api/subagents.md
index 7fb2bd8e4..54eafb74e 100644
--- a/contracts/agents-api/subagents.md
+++ b/contracts/agents-api/subagents.md
@@ -32,7 +32,7 @@ Active includes idle. A successful close records the native time; a successful r
## Adapter contract
-Adapters report Subagent facts through `internal/agentdaemon/proto/subagents.go` over the existing authenticated Run and execution journal. There is no separate transport, scheduler or model and tool loop.
+Adapters report Subagent facts through `internal/agentdaemon/proto/subagents.go` over the authenticated Run and execution journal. There is no separate transport, scheduler or model and tool loop.
| Fact | Adapter obligation |
| --- | --- |
diff --git a/contracts/agents-api/wire-semantics.md b/contracts/agents-api/wire-semantics.md
index 1520547ee..5b961639e 100644
--- a/contracts/agents-api/wire-semantics.md
+++ b/contracts/agents-api/wire-semantics.md
@@ -38,7 +38,7 @@ Every Agents API response, including errors and event streams, carries:
### Authentication
-`/v1` accepts only a Project API key as `Authorization: Bearer `. All keys of one Project act as the same caller: they share its resources and its Session creation retries. Core resolves the key and its Project in the database on every request, with no credential cache and a five-second timeout. Revoking a key or archiving its Project takes effect on the next request. All keys of a Project act as subject `service_account/project:`. [Projects and keys](./admin-api.md#projects-and-keys) describes key management.
+`/v1` accepts only a Project API key as `Authorization: Bearer `. Core resolves the key and its Project in the database on every request, with no credential cache and a five-second timeout. Revoking a key or archiving its Project takes effect on the next request. All keys of a Project act as subject `service_account/project:`. [Projects and keys](./admin-api.md#projects-and-keys) describes key management.
The optional `OpenAI-Organization` and `OpenAI-Project` headers must, when sent, appear once and equal `core` and `proj_`; any other value rejects the key.
diff --git a/contracts/agents-api/zh/admin-api.md b/contracts/agents-api/zh/admin-api.md
index 9e550d491..66d71c265 100644
--- a/contracts/agents-api/zh/admin-api.md
+++ b/contracts/agents-api/zh/admin-api.md
@@ -1,7 +1,7 @@
---
title: "Core 管理 API"
source: contracts/agents-api/admin-api.md
-source_hash: da7f631aea81c3b934e61e8749de577f2dc458d5b45ede3f5492a3f184affe08
+source_hash: 0b0be1a0a0d85119e047330c178258481e71f645d577554b5619d3a9b201a794
---
Core 管理 API(`/core/v1`)用于管理安装实例:项目及其 API 密钥、项目资源的读取和删除、执行器凭据、部署默认模型、沙箱部署及其节点、监控和审计。Web 的[控制台服务器](../../../docs/zh/web/console-server.md#forwarding-to-core)会为已登录的管理员调用它;运维人员则从 Core 主机上的脚本调用它([编写 Core API 脚本](../../../docs/zh/getting-started/operations.md#script-the-core-api))。生成的架构是 [core.openapi.yaml](../core.openapi.yaml),所有错误都使用 [Core 错误封装](core-errors.md)。
@@ -65,7 +65,7 @@ Core 管理 API(`/core/v1`)用于管理安装实例:项目及其 API 密
| `address_bindings` 字段 | 含义 |
| --- | --- |
| `nodes` | 已注册且未移除的节点 |
-| `nodes_on_other_address` | 使用了 `public_url` 以外地址注册的节点。它们不会获得新的沙箱;请移除后重新添加。最多为 `nodes` 个 |
+| `nodes_on_other_address` | 使用了 `public_url` 以外地址注册的节点。它们不会获得新的沙箱;参见[更改公开 URL](../../../docs/zh/getting-started/public-address.md#changing-the-public-url)。最多为 `nodes` 个 |
| `hosted_sandboxes` | 保留的待处理托管沙箱;它们启动时使用当时有效的地址运行 |
| `self_hosted_executors` | 未吊销的执行器凭据;对应执行器安装时使用的是当时公布的 `remote_url` |
diff --git a/contracts/agents-api/zh/core-metrics.md b/contracts/agents-api/zh/core-metrics.md
index 0bf738757..1921f3526 100644
--- a/contracts/agents-api/zh/core-metrics.md
+++ b/contracts/agents-api/zh/core-metrics.md
@@ -1,7 +1,7 @@
---
title: "Core 指标"
source: contracts/agents-api/core-metrics.md
-source_hash: 5843b943903b0a288e941998d365ed1d01fd282ea71feacadb3fe5f1bbb576a7
+source_hash: bb6125b122a9cb46664db9d9536c0e799a3e1b789daed0f62941c0bc2bed6405
---
`GET /core/v1/metrics?range=1h|6h|24h|7d` 报告 Core 自身的健康状况:进程、执行队列与槽位、PostgreSQL 和后台任务。它要求 Core 密钥([Core 管理 API](admin-api.md))。
@@ -35,7 +35,7 @@ source_hash: 5843b943903b0a288e941998d365ed1d01fd282ea71feacadb3fe5f1bbb576a7
| `service.revision` | 构建时注入的完整源代码提交;未注入时为 null |
| `service.started_at` | 进程初始化时间 |
| `service.execution_owner` | 此进程是否持有执行 worker 的数据库租约 |
-| `execution.slots_in_use`, `execution.slots_total` | 执行 worker 的活动 Session 预留数量及容量:[`OAC_EXECUTION_CONCURRENCY`](../../../docs/zh/configuration.md#settings),默认为 4。Environment 输入、Turn 和文件工作共享槽位;不统计原生 Harness 子进程 |
+| `execution.slots_in_use`, `execution.slots_total` | 执行 worker 的活动 Session 预留数量及容量:[`OAC_EXECUTION_CONCURRENCY`](../../../docs/zh/configuration.md#settings)。Environment 输入、Turn 和文件工作共享槽位;不统计原生 Harness 子进程 |
| `execution.queued_turns`, `execution.in_progress_turns` | 处于相应状态的根 Turn,包括已删除 Session 的 Turn。不统计 Subagent Turn 和为准备中 Environment 预留的输入 |
| `execution.waiting_for_daemon` | Session 设备未连接的排队 Turn |
| `execution.oldest_queued_seconds` | 最早排队 Turn 自 `created_at` 起的年龄 |
diff --git a/contracts/agents-api/zh/environment-executor-credentials.md b/contracts/agents-api/zh/environment-executor-credentials.md
index b711a247f..c7449e9f7 100644
--- a/contracts/agents-api/zh/environment-executor-credentials.md
+++ b/contracts/agents-api/zh/environment-executor-credentials.md
@@ -1,7 +1,7 @@
---
title: "执行器凭据"
source: contracts/agents-api/environment-executor-credentials.md
-source_hash: bd7758cbe88d35995dcdffafc381f4a1d6b36ef70f9d0932f88d4d3b67ec1ab6
+source_hash: bc6bfa4cdaa4a82694fc3b2936aa50f1e00ae7feecea05f7c67401bb5816f185
---
执行器凭据允许 `oac-daemon` 为一个 `self_hosted` Environment 注册并连接。它只授权该 Environment 的私有 daemon 传输(`/api/v1/agent-daemon/*`),不授权 `/v1`、`/core/v1`、sandbox node 注册或项目资源。项目的 principal 是其执行 principal。Core 只保存密钥摘要。
diff --git a/contracts/agents-api/zh/environment-files.md b/contracts/agents-api/zh/environment-files.md
index bff81f7cc..e9264a806 100644
--- a/contracts/agents-api/zh/environment-files.md
+++ b/contracts/agents-api/zh/environment-files.md
@@ -1,7 +1,7 @@
---
title: "Environment 文件与 Artifact"
source: contracts/agents-api/environment-files.md
-source_hash: 957cca18ef63a95a01ff682ff8adffb0d63d34e520c197ed9f6c8d08c4fd6c5d
+source_hash: b6c51bd066cf70b6cce4c38ba1403dc3463574fcbc254bf64f8c98b6aeca9b93
---
Session 工作区保存由 agent 及其工具修改的实时文件。`/agents/environments/{environment_id}/files` 列出一个工作区目录,并在其中创建文件。Turn 完成时,Core 将工作区 `outputs/` 目录中的文件复制为不可变 Artifact,通过 `/agents/sessions/{session_id}/artifacts` 读取。Artifact 的生命周期长于 Environment;工作区文件则不是。
diff --git a/contracts/agents-api/zh/environments.md b/contracts/agents-api/zh/environments.md
index 3c0fd8c29..a663bb140 100644
--- a/contracts/agents-api/zh/environments.md
+++ b/contracts/agents-api/zh/environments.md
@@ -1,7 +1,7 @@
---
title: "Environment 与模板"
source: contracts/agents-api/environments.md
-source_hash: f50217dd1fc465626ac7135a46b69cea0ee40fc14fd30141e23813018192cb5c
+source_hash: 6b609956acde1748bfc1762ba5428959a88de8b42cbcaa9297fb89c1c2c013bb
---
Environment 是 Session 的执行资源,包括 Harness 运行所在的机器、工作区以及已完成准备的能力。Session 通过其 `environment` 配置创建 Environment;不存在独立的 create 调用。Environment 模板是 Session 创建时解析的可复用准备配置。本契约涵盖这两类资源、两种放置方式、输入接纳、能力准备、Skills、Plugins 和 MCP 连接来源。
@@ -320,7 +320,7 @@ Session 会先应用模板,然后应用自身字段。组合仅在加密 Sessi
### 准备复用 {#preparation-reuse}
-Core 可以用同一 Project 中较早一次准备的结果启动托管 Environment,前提是两者在 Template 组合之后的有效配置完全相同,且距该次准备不超过 24 小时。每个 Session 仍然得到自己的副本。此时设置命令和包安装不会为该 Session 再次运行。只复用 `/environment`(见工作区文件系统范围),HOME 和其他与计算实例本地相关的改动不会复用。设置过程不得产生每个 Session 唯一的值,不得执行必须按 Session 发生的外部副作用,也不得获取 24 小时内就会过期的凭据;需要这些行为的配置必须有所不同,例如在 `env` 或 `files` 上。未声明[准备缓存](../../../docs/zh/sandbox-provider.md#explicit-operation-contracts)的提供商始终完整准备。
+Core 可以用同一 Project 中较早一次准备的结果启动托管 Environment,前提是两者在 Template 组合之后的有效配置完全相同,且距该次准备不超过 24 小时。每个 Session 仍然得到自己的副本。此时设置命令和包安装不会为该 Session 再次运行。只复用 `/environment`(见[生命周期与文件系统范围](../../../docs/zh/workspace-provider.md#lifetime-and-filesystem-scope)),HOME 和其他与计算实例本地相关的改动不会复用。设置过程不得产生每个 Session 唯一的值,不得执行必须按 Session 发生的外部副作用,也不得获取 24 小时内就会过期的凭据;需要这些行为的配置必须有所不同,例如在 `env` 或 `files` 上。未声明[准备缓存](../../../docs/zh/sandbox-provider.md#explicit-operation-contracts)的提供商始终完整准备。
### 受限网络 {#restricted-network}
@@ -359,7 +359,7 @@ template = client.beta.agents.environments.templates.create(
)
```
-固定版本的 `/v1/skills` 资源、版本及内容路由使用项目 API 密钥,且不使用 Agents beta 标头。ZIP 上传使用 `files`,目录上传则重复使用 `files[]`。固定版本 SDK 3.13.0 在多部分内容提取过程中会丢弃单文件 tuple,因此应使用原始 HTTP 上传单个 ZIP。一次上传最多包含 500 个常规文件,并且必须恰好包含一个 `SKILL.md`;压缩后为 5 MiB,展开后为 20 MiB。[File resource semantics](source-files.md#versions-and-metadata) 负责默认版本和删除规则。
+固定版本的 `/v1/skills` 资源、版本及内容路由使用项目 API 密钥,且不使用 Agents beta 标头。ZIP 上传使用 `files`,目录上传则重复使用 `files[]`。[Upload a bundle](source-files.md#upload-a-bundle) 负责 bundle 格式、上传限制和 SDK 单文件限制;[versions and metadata](source-files.md#versions-and-metadata) 负责默认版本和删除规则。
省略或传入 null 版本的引用会在 Session 创建时选择默认版本,`"latest"` 会选择最新版本,正版本号字符串则选择该版本。模板响应会保留未解析的选择器(默认版本为 `version: null`);Session 元数据会显示 `{type, skill_id, version, name, description}`,其中版本为具体值。Session 会在其创建事务中冻结所选版本的字节和元数据;之后默认版本发生变化、源被删除或模板被更新,都无法改变这些内容。
@@ -382,8 +382,7 @@ Plugin 是带有 type、name 和 description 的内联 ZIP,其单个归档根
Skills 及其不可变版本是项目资源,独立于 Session 和原生安装。
-- 版本分配和指针变更会在所属 Skill 行上串行化。顶层 name 和 description 在同一事务中跟随默认版本;非默认上传不会更改它们。在并发上传和删除过程中,版本身份始终唯一。
-- Bundle 使用服务密码进行加密,并绑定到项目、Skill 和版本。元数据读取绝不会加载或解密 Bundle。删除 Skill 会回收其版本,但不会影响已冻结的 Session。
+- 版本分配、默认版本变更和串行化由 [Versions and metadata](source-files.md#versions-and-metadata) 定义,Bundle 加密由 [Upload a bundle](source-files.md#upload-a-bundle) 定义。元数据读取绝不会加载或解密 Bundle。删除 Skill 会回收其版本,但不会影响已冻结的 Session。
- 引用会在 Session 创建事务中、upsert 建立所有权之后解析。被引用的资源按稳定顺序锁定,版本、元数据和字节会一并冻结。公开引用元数据、未解析的模板意图和已解析的 Runtime Bundle 始终彼此独立;引用绝不会报告为内联内容。
内联和引用的 Skills 使用相同的机密快照与安装程序。Runtime 会在设置和原生执行之前,将它们安装到能力根目录下的 `skills/`。适配器只注册所选的 Skill 根目录:Codex 将其注册为显式额外根目录,MiniMax Code 通过其原生目录进行注册,Claude 则将其作为私有状态路径下的用户 Skills,使原生列出与本地 `~/.claude/skills` 相同的裸名称。Claude 拒绝包含 `.claude-plugin` 的 Skill,因为原生会将其作为插件加载,连同其 hooks 和 MCP 服务器。Skill 根目录不会启用 MCP 服务器,只有 [Plugin MCP](#plugin-mcp) 会启用。Codex 与本地运行一样递归扫描每个 Skill 根目录,因此嵌套的 `SKILL.md` 会注册另一个原生 Skill。原生 Harness 配置绝不会整体透传。
diff --git a/contracts/agents-api/zh/harness-capabilities.md b/contracts/agents-api/zh/harness-capabilities.md
index 2cb49062e..0470a3c18 100644
--- a/contracts/agents-api/zh/harness-capabilities.md
+++ b/contracts/agents-api/zh/harness-capabilities.md
@@ -1,7 +1,7 @@
---
title: "Harness 能力"
source: contracts/agents-api/harness-capabilities.md
-source_hash: d79690e618d82c6b858dc40342198fc5b091ee56505816f551da80d100ef2c2e
+source_hash: 507c77c74145cac386ac8dd0e231d5701821c00490c0c5db2d25f052911a3107
---
本页列出每个 Harness 在每种部署位置支持的能力。Core 根据 `internal/harnessconfig//declaration.go` 中 Harness 的声明决定准入,运行 Session 的 Runtime 也必须声明操作。所链接契约定义各操作;[Harness 接入](harness-onboarding.md#qualify-the-adapter)说明资格验证方法。
@@ -26,7 +26,7 @@ source_hash: d79690e618d82c6b858dc40342198fc5b091ee56505816f551da80d100ef2c2e
| [消息图像](message-content.md#images) | PNG、JPEG data URL:所有位置已验证;其他 data URL:已准入;远程 URL:已拒绝 | PNG、JPEG data URL:所有位置已验证;远程 URL 及 GIF、WebP data URL:已准入 | 已拒绝 |
| `reasoning.effort` | `none`、`minimal`、`low`、`medium`、`high`、`xhigh`、`max`:已准入 | `low`、`medium`、`high`、`xhigh`、`max`:已准入 | `none`、`minimal`、`low`、`medium`、`high`、`xhigh`、`max`:已准入 |
| `reasoning.summary` | `concise`、`detailed`、`auto`:已准入 | `auto`:已准入 | 已拒绝 |
-| 非 `auto` 的 `service_tier` | `default`、`flex`、`priority`:已准入 | 已拒绝 | 已拒绝 |
+| 非 `auto` 的 `service_tier` | `default`、`flex`、`priority`、`fast`:已准入 | 已拒绝 | 已拒绝 |
| 非 `medium` 的 `text.verbosity` | 已准入;由原生模型决定 | 已拒绝 | 已拒绝 |
| [公开 token 用量](sessions-events.md) | 测量计数器 | Null | Null |
@@ -41,7 +41,7 @@ source_hash: d79690e618d82c6b858dc40342198fc5b091ee56505816f551da80d100ef2c2e
| [结构化输出](execution-tools.md#structured-output) | 所有位置已准入 | 所有位置已验证 | 已拒绝 |
| [延迟函数发现](execution-tools.md#deferred-function-discovery) | 已拒绝 | 已验证:`none`、自托管;已准入:托管 | 已拒绝 |
| [禁用 Web 搜索与程序化工具调用](execution-tools.md#web-search-and-programmatic-tool-calling) | 已验证:`none`;已准入:托管、自托管 | 已验证:`none`;已准入:托管、自托管 | 已验证:`none`;已准入:托管、自托管 |
-| Web 搜索 `cached` 或 `live`,以及程序化工具调用 `enabled` | 所有位置已准入 | `live` 在所有位置已准入;`cached` 和 `enabled` 已拒绝 | 已拒绝 |
+| Web 搜索 `cached` 或 `live`,以及程序化工具调用 `enabled` | 所有位置已准入;`enabled` 与 `multi_agent` 同时出现时被拒绝 | `live` 在所有位置已准入;`cached` 和 `enabled` 已拒绝 | 已拒绝 |
| [服务端来源 HTTP MCP](environments.md#public-mcp-connection-origin) | 已验证:`none`;其他位置拒绝 | 已验证:`none`;其他位置拒绝 | 已验证:`none`,仅 `allowed_tools` null、`required` false;其他位置拒绝 |
| [Environment 来源 HTTP MCP](environments.md#public-mcp-connection-origin) | 已验证:托管、自托管 | 已验证:托管、自托管 | 已验证:托管、自托管;仅 `allowed_tools` null、`required` false |
| [stdio MCP](execution-tools.md#mcp) | 已准入:托管、自托管 | 已准入:托管、自托管;`cwd` 须为工作区目录,`allowed_tools` 须为 null | 已拒绝 |
diff --git a/contracts/agents-api/zh/harness-onboarding.md b/contracts/agents-api/zh/harness-onboarding.md
index 3d7db2da5..2bc0770c5 100644
--- a/contracts/agents-api/zh/harness-onboarding.md
+++ b/contracts/agents-api/zh/harness-onboarding.md
@@ -1,7 +1,7 @@
---
title: "Harness 协议"
source: contracts/agents-api/harness-onboarding.md
-source_hash: 8beb6af27e99a4bf25a2e828d1b2c1c51adcd7b597f3cd64a211396a506a09c0
+source_hash: 735078df56cfbe89dc569d36a87d31c7eccd69848f19465d3bf66ac55e5f2238
---
**Harness** 是一种运行模型和工具循环的原生代理引擎(Codex、Claude Code、MiniMax Code);**Harness 适配器**将 Runtime 的 Executor 和 Turn 契约转换到该引擎的 SDK 或协议。Harness 协议是 Runtime 与适配器之间的契约:适配器接口及其生命周期义务、声明、注册和验收。本文面向添加或维护 Harness 的开发者。
diff --git a/contracts/agents-api/zh/index.md b/contracts/agents-api/zh/index.md
index a5017f184..7cb9b2d1c 100644
--- a/contracts/agents-api/zh/index.md
+++ b/contracts/agents-api/zh/index.md
@@ -1,7 +1,7 @@
---
title: "OpenAI 兼容性"
source: contracts/agents-api/index.md
-source_hash: 2936067de4c8baa0ff06ff5175d23d3c92a65de758bd656f4bbffd60529f41b6
+source_hash: 4431b17e74c51ece10dc606c8c2078aeb5e974259cf954868f79b797c91d63a7
---
Core 实现下方固定版本的 OpenAI Agents API。本台账列出各项资源的覆盖情况、相对于官方服务的所有差异以及已知缺口。
@@ -39,7 +39,7 @@ Core 实现下方固定版本的 OpenAI Agents API。本台账列出各项资源
| Environments | retrieve | 已实现;以 Session 为范围([归属](environments.md#resources-and-states))。固定版本契约会拒绝 `environment.environment_id`;已有 hosted Environment 无法跨 Session 关联。跨 Session 共享的工作区属于应用([项目拥有资产](../../../docs/zh/concepts.md#projects-own-assets)) | [Environments](environments.md) |
| Environment files | create, list | 已实现;列表不会递归 | [Environment files and Artifacts](environment-files.md) |
| Environment 模板 | create, retrieve, update, list, delete | 已实现;执行限制列于 [known gaps](#known-gaps) | [Environment 模板](environments.md#templates) |
-| Vaults | create, retrieve, list, delete | 已实现;没有归档操作 | [Vaults and Credentials](vaults.md) |
+| Vaults | create, retrieve, list, delete | 已实现 | [Vaults and Credentials](vaults.md) |
| Vault Credentials | create, retrieve, update, list, delete | 已支持 `static_bearer` 和 `mcp_oauth` | [Vaults and Credentials](vaults.md) |
| Files | create, retrieve, list, delete, content | 已支持 `purpose=user_data`;内容下载会被拒绝 | [Files and Skills](source-files.md) |
| Skills and Skill versions | create, retrieve, update, list, delete, content | 已实现 | [Files and Skills](source-files.md) |
@@ -101,7 +101,7 @@ Core 自身字段位于 `x_agents_core` 中([Core extensions](../../../docs/zh
**Files、Skills、Environment files 和 Artifacts**([Files and Skills](source-files.md)、[Environment files and Artifacts](environment-files.md))
-- 文件上传上限为 512 MiB;官方上限为 512 MB。Files 列表默认最多返回 10,000 个 Files,`purpose` 过滤值不是 `user_data` 时会返回空页面。
+- 文件上传上限为 512 MiB;官方上限为 512 MB。`purpose` 过滤值不是 `user_data` 时会返回空页面。
- Skill 版本号绝不复用,并且针对某个 Skill 的上传和删除会串行执行。
- Environment files 可用于 `self_hosted` Environments,而官方服务会拒绝。
- 在已有常规文件上创建 Environment file 会返回 "must not traverse symlinks or overwrite existing files" 消息。若父级符号链接仍位于工作区内,则会跟随该链接;若父级逸出工作区或父级本身是常规文件,则会返回通用 400;官方服务会拒绝父级符号链接。
@@ -121,7 +121,7 @@ Core 自身字段位于 `x_agents_core` 中([Core extensions](../../../docs/zh
**配置和工具**
-- 所选 Harness 未声明的 `reasoning.effort`、`reasoning.summary`、`service_tier`、`web_search` 模式或设置、`programmatic_tool_calling` 取值,会被保存,但在 Session 准入时被拒绝([Harness 能力](harness-capabilities.md#execution-and-input))。
+- 所选 Harness 未声明的 `reasoning.effort`、`reasoning.summary`、`service_tier`、`text.verbosity`、`web_search` 模式或设置、`programmatic_tool_calling` 取值,会被保存,但在 Session 准入时被拒绝([Harness 能力](harness-capabilities.md#execution-and-input))。
- Harness 对工具、结构化输出、延迟发现、subagents 和 MCP 的支持因 Harness 和部署位置而异;请参阅 [Harness capabilities](harness-capabilities.md)。MiniMax Code 不支持图像输入。
- 由模型推导出的推理默认值不会被解析确定。
@@ -151,7 +151,7 @@ Core 自身字段位于 `x_agents_core` 中([Core extensions](../../../docs/zh
**Vaults 和 Credentials**
-- 没有归档生命周期、存储密钥轮换或重新加密。
+- 没有存储密钥轮换或重新加密。
- OAuth 刷新仅在派发时执行:提供商返回 401 时不会刷新,不会在 Turn 中途替换令牌,也不会撤回已发送给 Runtime 的令牌。
- 发送到所选 Credential 已被删除的 Session 的输入会先通过准入,随后在派发时失败。
- 创建 Credential 时不接受 `Idempotency-Key`。
diff --git a/contracts/agents-api/zh/sandbox-deployment.md b/contracts/agents-api/zh/sandbox-deployment.md
index 72ecae899..4596ede7e 100644
--- a/contracts/agents-api/zh/sandbox-deployment.md
+++ b/contracts/agents-api/zh/sandbox-deployment.md
@@ -1,7 +1,7 @@
---
title: "沙箱部署"
source: contracts/agents-api/sandbox-deployment.md
-source_hash: 385786135904715e0b92b5978cade8a4313d4004610b4ea5a1310d0b6ff30900
+source_hash: 57d2c630e22ee6e6b7333c36bb042af74e820c1205bb9fb6d41cb8f54acd605d
---
沙箱部署为 Core 管理的 `openai_hosted` 执行选择沙箱提供商和每个沙箱的资源。PostgreSQL 为每个安装维护一个当前有效选择;Web 和 Core API 写入同一配置。节点文件保存其已安装副本和特定于主机的路径,且不能覆盖其资源。Runtime 不属于该选择:每个节点运行其所属安装验证过的 Runtime。该选择独立于 Harness。部署可以保持未配置状态,没有节点;此时它拒绝托管准入。
@@ -41,7 +41,7 @@ POST 和 PUT 接受相同的完整选择,并要求提供先前 GET 返回的 `
| `configuration` | 提供商的公开选择器。E2B:不可变的 `template` 构建以及可选且配套的 `api_url` 和 `domain`。Docker 和 microsandbox 仅接受 `{}` 或省略 |
| `credential` | 提供商的只写凭据。E2B:`{api_key}`,首次设置时必填,在 PUT 中省略以保留当前密钥;null 或空密钥无效。Docker 和 microsandbox 拒绝该字段 |
-请求中没有 Core 地址。Core 根据安装公开 URL(`config.json` 中的 `public_url`,Core 对应 `OAC_PUBLIC_URL`)派生部署的 `core_url`:这是节点和沙箱客户机访问 Core 时使用的源地址。包含 `core_url` 的请求会像包含任何其他未知成员一样被拒绝,并返回 400 `invalid_request`。E2B 客户机从 E2B 云访问 Core,因此当公开 URL 为回环地址时,E2B 选择会被拒绝,并返回 409 `sandbox_configuration_error`。Docker 和 microsandbox 选择接受回环公开 URL,但这仅适用于本地开发,因为客户机的回环地址无法访问其主机。更改公开 URL 属于安装变更:使用旧地址注册的节点不会收到新沙箱,必须移除后重新添加。
+请求中没有 Core 地址。Core 根据安装公开 URL(`config.json` 中的 `public_url`,Core 对应 `OAC_PUBLIC_URL`)派生部署的 `core_url`:这是节点和沙箱客户机访问 Core 时使用的源地址。包含 `core_url` 的请求会像包含任何其他未知成员一样被拒绝,并返回 400 `invalid_request`。E2B 客户机从 E2B 云访问 Core,因此当公开 URL 为回环地址时,E2B 选择会被拒绝,并返回 409 `sandbox_configuration_error`。Docker 和 microsandbox 选择接受回环公开 URL,但这仅适用于本地开发,因为客户机的回环地址无法访问其主机。更改公开 URL 属于安装变更;参见[更改公开 URL](../../../docs/zh/getting-started/public-address.md#changing-the-public-url)。
### 资源 {#resources}
@@ -197,7 +197,7 @@ stateDiagram-v2
节点容量独立于部署 specification 设置。`POST /core/v1/sandbox/enrollment-tokens` 接受可选的 `max_active` 和 `max_retained`,并返回 `{token, expires_at, enrollment_id}`;`enrollment_id` 是该命令的公共句柄,绝不是凭据。Core 将令牌与发送的限制一同存储,省略的限制保持未设置。节点注册时,Core 把每个显式限制原样复制给节点,并把每个未设置的限制设为注册请求中的主机测量值与当前 specification 的[推荐容量](#recommended-capacity);限制未设置且没有主机测量值时,返回 409 `sandbox_node_host_unmeasured`,令牌保持未使用。只设置 `max_retained` 时,推导出的 `max_active` 不会超过它;只设置 `max_active` 时,推导出的 `max_retained` 会被提高到至少等于 `max_active`。microsandbox 会使用两个限制。Docker 绝不暂停,因此 Core 会在此处和 PATCH 中用 `max_active` 替换其 `max_retained`。E2B 没有节点,并返回 409 `sandbox_deployment_conflict`。节点不能提交限制,但未设置的限制取决于节点在注册时报告的主机测量值,范围限定在 1 到 1000000。其本地检查可以拒绝其无法运行的部署,但绝不会提高限制。显式值和之后的 PATCH 修改具有约束力:节点注册之后,Core 不再推导。[节点容量](../../../docs/zh/configuration.md#node-capacity)为操作员说明了这些限制。
-`GET /core/v1/sandbox/nodes` 返回 `{data: [...]}`,其中每个节点包含 `id`、`name`、`provider`、`online`、`last_seen_at`、`created_at`、`max_active`、`max_retained`,计数项 `active`、`reserved`、`running`、`retained`、`snapshots` 和 `cleanup_pending`,以及 `provider_ready`、主机测量值 `cpu_count`、`available_memory_bytes` 和 `available_disk_bytes`、`rollout`、`recommended_capacity`、`enrollment_id` 和 `core_url`。`recommended_capacity` 是 `{max_active, max_retained}`,即节点最新健康状态与当前 specification 的[推荐容量](#recommended-capacity);在节点报告 CPU 数量或有效核数以及总内存之前,以及当前 specification 未通过校验时,为 null。`enrollment_id` 是注册该节点的命令的句柄;如果 Core 没有该句柄,则为 null。`core_url` 是注册时的安装公开 URL;`core_url` 与当前公开 URL 不同的节点不会收到新放置。已放置到该节点的工作会继续在那里完成,包括已放置但尚未获得分配的 Environment;只要旧地址仍能访问 Core,其保留沙箱仍可恢复。请移除该节点并重新添加。
+`GET /core/v1/sandbox/nodes` 返回 `{data: [...]}`,其中每个节点包含 `id`、`name`、`provider`、`online`、`last_seen_at`、`created_at`、`max_active`、`max_retained`,计数项 `active`、`reserved`、`running`、`retained`、`snapshots` 和 `cleanup_pending`,以及 `provider_ready`、主机测量值 `cpu_count`、`available_memory_bytes` 和 `available_disk_bytes`、`rollout`、`recommended_capacity`、`enrollment_id` 和 `core_url`。`recommended_capacity` 是 `{max_active, max_retained}`,即节点最新健康状态与当前 specification 的[推荐容量](#recommended-capacity);在节点报告 CPU 数量或有效核数以及总内存之前,以及当前 specification 未通过校验时,为 null。`enrollment_id` 是注册该节点的命令的句柄;如果 Core 没有该句柄,则为 null。`core_url` 是注册时的安装公开 URL;`core_url` 与当前公开 URL 不同的节点不会收到新放置。已放置到该节点的工作会继续在那里完成,包括已放置但尚未获得分配的 Environment;只要旧地址仍能访问 Core,其保留沙箱仍可恢复。参见[更改公开 URL](../../../docs/zh/getting-started/public-address.md#changing-the-public-url)。
节点管理代次,因此其 `provider_ready` 取决于服务代次,目标代次的固定代码会出现在 `rollout.diagnostic` 中。节点会对首次失败的就绪检查进行分类,并且只发送代码;携带任何其他值的帧均无效,且 Core 绝不存储或返回探测文本或主机路径。这些代码是与提供商无关的类别:`provider_unavailable`、`host_unsupported`、`artifacts_unavailable`、`runtime_image_unavailable` 和 `capacity_insufficient`。[就绪代码](../../../docs/zh/getting-started/nodes.md#readiness-codes)给出了原因和操作员应采取的措施。Core 和节点必须来自同一发行包。
diff --git a/contracts/agents-api/zh/subagents.md b/contracts/agents-api/zh/subagents.md
index c4346f1aa..761b4fc9e 100644
--- a/contracts/agents-api/zh/subagents.md
+++ b/contracts/agents-api/zh/subagents.md
@@ -1,7 +1,7 @@
---
title: "子 Agent"
source: contracts/agents-api/subagents.md
-source_hash: 6c4fe5212d8473ff319fea4a6abf30d8038b75dd663dd9612ddad023adb918c7
+source_hash: d8341bfd7747152dea23afc930cf5fe07ff1ac4a58f503cb0e2ec5fe86060cb9
---
启用 `multi_agent.enabled` 后,Harness 可以启动原生子 Agent。Core 通过锁定版本的 SDK(见 [`upstream.json`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/contracts/agents-api/upstream.json))中的六项 Subagent 读取操作公开它们,并根据适配器观察结果记录它们。当 `multi_agent.enabled=false` 时,Runtime 会移除原生子 Agent 工具。[Harness capabilities](harness-capabilities.md) 列出各 Harness 在哪些组合中支持子 Agent。
diff --git a/contracts/agents-api/zh/wire-semantics.md b/contracts/agents-api/zh/wire-semantics.md
index b9c0810c5..2c6c53efe 100644
--- a/contracts/agents-api/zh/wire-semantics.md
+++ b/contracts/agents-api/zh/wire-semantics.md
@@ -1,7 +1,7 @@
---
title: "API 行为"
source: contracts/agents-api/wire-semantics.md
-source_hash: 1f374322fcfd4a9fda8162004342162b1c3b8e3b5f12c2f2871f68bd593751da
+source_hash: ba9c6565567c1b4dcffb0c8f18731372b9e3c95e25f84dc0c3c2782c94161eb2
---
已锁定版本的 OpenAI Python SDK([upstream.json](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/contracts/agents-api/upstream.json))定义了 `/v1` 路由、字段和类型。本页面说明这些类型未作规定之处 Core 的行为,例如状态码、错误字段、默认值和列表边界,以及 Core 与官方服务存在差异的地方。[OpenAI 兼容性](index.md) 列出了这些差异和尚存缺口;[Sessions, events and history](sessions-events.md)、[message content](message-content.md)、[Vaults](vaults.md)、[source Files and Skills](source-files.md) 和 [Environment files and Artifacts](environment-files.md) 分别负责各自资源的规则。
@@ -40,7 +40,7 @@ Beta 路由要求 `OpenAI-Beta` 标头中恰好有一个值,且该值必须等
### 身份验证 {#authentication}
-`/v1` 仅接受项目 API 密钥,形式为 `Authorization: Bearer `。同一项目的所有密钥都视为同一调用方:它们共享该项目的资源和 Session 创建重试。Core 在每次请求时都在数据库中解析密钥及其项目,不缓存凭据,超时时间为五秒。撤销密钥或归档其项目会在下一次请求时生效。项目的所有密钥都使用主体 `service_account/project:`。[项目与密钥](admin-api.md#projects-and-keys) 介绍了密钥管理。
+`/v1` 仅接受项目 API 密钥,形式为 `Authorization: Bearer `。Core 在每次请求时都在数据库中解析密钥及其项目,不缓存凭据,超时时间为五秒。撤销密钥或归档其项目会在下一次请求时生效。项目的所有密钥都使用主体 `service_account/project:`。[项目与密钥](admin-api.md#projects-and-keys) 介绍了密钥管理。
可选的 `OpenAI-Organization` 和 `OpenAI-Project` 标头在发送时必须各出现一次,并分别等于 `core` 和 `proj_`;任何其他值都会导致密钥被拒绝。
diff --git a/deploy/README.md b/deploy/README.md
index 642beaee9..397a74409 100644
--- a/deploy/README.md
+++ b/deploy/README.md
@@ -12,17 +12,17 @@
`install.sh` and `install.ps1` select a native `oac` release binary, verify its checksum and invoke `oac install`. That Go command owns the same installation lifecycle on Linux, macOS and Windows: validate Docker, verify release configuration, prepare `.env` and the host command, pull images, publish the installation directory, initialize the data volume and start Compose. [Installation](../docs/getting-started/install.md#prerequisites) owns platform prerequisites; [Configuration](../docs/configuration.md) owns settings and storage.
-Preparation happens in `.staging`. On entry, the installer removes an empty stage or one with the empty ownership directory `.oac-installer-`; it preserves unrecognized directories. Ordinary failures remove owned staging immediately. The ownership marker is created atomically before downloading files. A killed process leaves staging for the next attempt. The release's `compose.yaml` is verified against its published checksum in the stage and must name the installer's own release in `OAC_REVISION`. Publication happens only after downloads, checks and pulls succeed. Later failures preserve saved configuration, containers and the Docker data volume. `.lock` is a persistent lock directory shared by installation and mutating operator commands; the existing `runtimefs` platform adapter owns locking.
+Preparation happens in `.staging`. On entry, the installer removes an empty stage or one with the empty ownership directory `.oac-installer-`; it preserves unrecognized directories. Ordinary failures remove owned staging immediately. The ownership marker is created atomically before downloading files. A killed process leaves staging for the next attempt. The release's `compose.yaml` is verified against its published checksum in the stage and must name the installer's own release in `OAC_REVISION`. Publication happens only after downloads, checks and pulls succeed. Later failures preserve saved configuration, containers and the Docker data volume. `.lock` is a persistent lock directory shared by installation and mutating operator commands; the `runtimefs` platform adapter owns locking.
An existing directory runs the release named by `OAC_REVISION` in its `compose.yaml`. When that is the installer's release, the installer resumes: it keeps the saved settings, pulls only missing images and starts the services the way `oac apply` does. The port check applies only to new directories. Another release is refused.
-`install.py` resumes a source-bundle installation of its own release under the same lock; another release is refused, and `--public-url` is required only for a new directory.
+`install.py` resumes a source-bundle installation of its own release under the same lock; another release is refused, and `--public-url` is required only for a new directory ([Offline hosts](../docs/getting-started/install-options.md#offline-hosts)).
-`install.py` prepares a new installation in a `.staging-*` directory inside the installation directory: the node payload, `.env`, `oac` and both Compose files. After `docker compose config` accepts them, it moves them into place, `compose.yaml` last. An earlier failure removes the stage, and the directory too when the run created it, so the same command can be rerun; the next run also removes a stage left by a killed run. A directory with other contents but no `compose.yaml` is refused.
+`install.py` prepares a new installation in a `.staging-*` directory inside the installation directory: the node payload, `.env`, `oac` and both Compose files. After `docker compose config` accepts them, it moves them into place, `compose.yaml` last. A failed or killed run leaves nothing to clean up by hand; rerun the same command ([Offline hosts](../docs/getting-started/install-options.md#offline-hosts)). A directory with other contents but no `compose.yaml` is refused.
-The host `oac` command also implements `apply`, `core-key`, `rotate-core-key` and `uninstall`. `apply` runs init, which finishes a first start that stopped before it and refuses a data volume committed to another release, then checks Core configuration before starting services and recreating those that changed. Reading the key executes `oac-web core-key` in Web. Rotation runs in the initialization container, where Linux file ownership is identical on every host, then restarts Core and Web. Start, stop and logs use `docker compose`; `oac uninstall` removes the installation, its data volume, the lock and the sidecar. The initialization image verifies and copies bundled node metadata without network access. Its receipt authenticates immutable metadata and credentials; the operator-rotatable Core key and its digest remain mutable. No service receives a Docker socket. Initialization emits structured step logs without credential values; view them with `docker compose logs --timestamps init`.
+The host `oac` command also implements `apply`, `core-key`, `rotate-core-key` and `uninstall`. `apply` runs init, which finishes a first start that stopped before it and refuses a data volume committed to another release, then checks Core configuration before starting services and recreating those that changed. Reading the key executes `oac-web core-key` in Web. Rotation runs in the initialization container, where Linux file ownership is identical on every host, then restarts Core and Web. Start, stop and logs use `docker compose`; `oac uninstall` removes the installation, its data volume, the lock and, on Windows, the lock file beside the removed directory. The initialization image verifies and copies bundled node metadata without network access. Its receipt authenticates immutable metadata and credentials; the operator-rotatable Core key and its digest remain mutable. No service receives a Docker socket. Initialization emits structured step logs without credential values; view them with `docker compose logs --timestamps init`.
-Web serves the console and forwards `/v1` and `/api/v1` to Core, so it is the only published service. HTTPS is terminated by the operator's reverse proxy or hosting platform, which routes to `web:8080`; `OAC_PUBLIC_URL` records that origin.
+Web is the only published service; [Web server](../docs/web/console-server.md#forwarding-to-core) defines what it serves and forwards. HTTPS is terminated by the operator's reverse proxy or hosting platform, which routes to `web:8080`; `OAC_PUBLIC_URL` records that origin.
## Native daemon installer
diff --git a/deploy/node/README.md b/deploy/node/README.md
index 5307ff177..28ceb9616 100644
--- a/deploy/node/README.md
+++ b/deploy/node/README.md
@@ -23,7 +23,7 @@ The node installer runs as root and prepares the host for one node per installat
- Root never runs a file the service account can write, opens a URL it wrote, or follows a link in its home. Capture the trusted bootstrap bytes before dropping to the service account and pass them through the fork; the service account writes its own retained generation helper. Never open the caller's private download directory to it or let root write into service-owned state.
- The generated bootstrap passes only the six standard HTTP/HTTPS proxy and bypass variables through sudo and gives both spellings the lowercase value when present, even if empty, so curl, urllib and the Go registration command follow the same rules. The installation child keeps just those names beside its fixed environment. Proxy values stay out of arguments, unit files and diagnostics; never use broad sudo environment inheritance. The installation child uses them for downloads. The node service keeps the settings of the latest run in `/etc/oac-node/.env` (root, mode 0600, read through `EnvironmentFile=`; removed when a run has no proxy and by uninstall), with loopback added to `NO_PROXY`.
- `--uninstall` removes a node only after Core rejects its credential, except for a node that never registered and with `--force`, which Web offers when the old Core address no longer responds. It never touches sandboxes, volumes or Docker images (the Runtime image stays, with the command that removes it). Once Core confirmed the removal it also deletes the node's microsandbox store, which `--force` never does (it prints the command instead). It deletes the account only when the installer created it and no node remains, and otherwise removes only the groups it added.
-- Refuse resources of an older product name for the same installation ID; never adopt them or remove another installation's resources.
+- Never adopt or remove another installation's resources.
## Download contract
diff --git a/docs/concepts.md b/docs/concepts.md
index da0cf2866..51cc6d65a 100644
--- a/docs/concepts.md
+++ b/docs/concepts.md
@@ -18,7 +18,7 @@ Application reads, writes and references are scoped to the key's Project. A reso
## What administrators can and cannot do
-Administrators manage Projects and keys, sandbox deployments, nodes, executor credentials and deployment default models. They inspect resources, execution history, operational counts and usage, and delete resources under their deletion rules. Archiving a hosted Session requests cancellation and sandbox reclamation; see [Session archive](../contracts/agents-api/admin-api.md#session-archive).
+Administrators manage Projects and keys, sandbox deployments, nodes, executor credentials and deployment default models. They inspect resources, execution history, operational counts and usage, and delete resources under their deletion rules. Archiving a hosted Session is defined in [Session archive](../contracts/agents-api/admin-api.md#session-archive).
Creating or editing application assets, starting Sessions and submitting input require a Project API key. The Core key gives no application identity and cannot read stored secrets. The [Core administration API](../contracts/agents-api/admin-api.md) defines its operations; the [Console server](./web/console-server.md) owns Web sign-in and credential handling.
diff --git a/docs/configuration.md b/docs/configuration.md
index 5d84f9394..b8d89e049 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -130,7 +130,7 @@ The installer creates `~/.oac/core` by default (`$HOME/.oac/core` on Windows). I
| `compose.override.yaml` | Optional local Compose entries. For a source bundle it is JSON and also holds Web's `/node-payload` bind and Core's native installer bind | You. `install.py` replaces only its own entries and requires JSON |
| `oac` (`oac.exe` on Windows) | Native management command | The installer |
-The sibling `.lock` directory remains for synchronization; `.staging` holds unpublished installation files. Neither contains service data. On Unix the installer creates private directories with mode `0700` and configuration files with mode `0600`.
+The sibling `.lock` directory is for synchronization; `.staging` holds unpublished installation files. Neither contains service data. On Unix the installer creates private directories with mode `0700` and configuration files with mode `0600`.
The Compose project is named `oac-<10 hex digits>`. Its services are `init`, `database`, `core` and `web`. Core applies database migrations when it starts. Web serves the console and is the only service with a published port, `OAC_WEB_PORT`; see [Request boundary](./web/console-server.md#request-boundary) for what it forwards. No service receives a Docker socket, and Web and Core have no KVM access.
@@ -167,7 +167,7 @@ Compose sets these for Web. Set them yourself only when you run the console with
| `OAC_WEB_ADDR` | `:8080` | Listener address. `oac-web healthcheck` probes its `/healthz` on `127.0.0.1` when its host is empty or unspecified |
| `OAC_PUBLIC_URL` | Required | The [public URL](#settings): the exact browser-facing origin, HTTP or HTTPS, without a path. Host and origin checks use it; HTTPS makes the session cookie `Secure` |
| `OAC_WEB_UPSTREAM` | `http://core:8091` | Core's origin, HTTP or HTTPS, without credentials, query or path |
-| `OAC_WEB_CORE_KEY_FILE` | Required | Absolute path of a regular file with no group or other permissions, holding the Core key: at least 32 characters, no whitespace, at most 4 KiB |
+| `OAC_WEB_CORE_KEY_FILE` | Required | Absolute path of a regular file with no group or other permissions, holding the [Core key](getting-started/operations.md#core-key), at most 4 KiB |
| `OAC_WEB_DIST` | `/www` | Absolute directory of the built console; must contain `index.html` |
| `OAC_WEB_NODE_PAYLOAD_DIR` | unset | Absolute path of the matched distribution's node payload (the installer's `node-payload/`). Unset, `/node-install/*` is not served and Add node is unavailable |
diff --git a/docs/getting-started/install.md b/docs/getting-started/install.md
index ca7401a54..17b8b6dc2 100644
--- a/docs/getting-started/install.md
+++ b/docs/getting-started/install.md
@@ -91,7 +91,7 @@ Core-hosted Sessions that bring no model provider use their Harness's default mo
1. On **Projects and keys**, choose **Create project**, then **Issue key**. The dialog shows the key once: copy it and keep it safe. Its **How to call** card shows the API base URL and sample requests.
2. Give the key and the API base URL to the application developer. They continue with [Run your first Session](./quickstart.md).
-## Reach Core from other machines {#configure-the-domain-and-https}
+## Reach Core from other machines
This step is optional for a trial on one machine. Applications, nodes and sandboxes reach Core at one address, the public URL. HTTP is enough on the local network; beyond it, put a reverse proxy in front and set the public URL to the HTTPS origin it serves. [Configure the public address](./public-address.md) covers the reverse proxy, ports and changing the address later.
diff --git a/docs/getting-started/nodes.md b/docs/getting-started/nodes.md
index 5e2b12f69..32f6c51e6 100644
--- a/docs/getting-started/nodes.md
+++ b/docs/getting-started/nodes.md
@@ -110,7 +110,7 @@ The [reset contract](../../contracts/agents-api/sandbox-deployment.md#generation
## Checkpoint recovery across nodes
-For microsandbox checkpoint recovery across nodes, add `--checkpoint-root /absolute/private/shared-store` to the installer command on each participating node. Mount the same private store at those paths before installation and grant only the node service account access. The default is a private node-local store and supports recovery on that node. The checkpoint store is separate from workspace storage and must never be guest-accessible; the [checkpoint transfer contract](../sandbox-provider.md#checkpoint-transfer) owns compatibility and retention requirements.
+For microsandbox checkpoint recovery across nodes, add `--checkpoint-root /absolute/private/shared-store` to the installer command on each participating node. Mount the same private store at those paths before installation and grant only the node service account access. The default is a private node-local store and supports recovery on that node. The [checkpoint transfer contract](../sandbox-provider.md#checkpoint-transfer) owns the store's isolation, compatibility and retention requirements.
microsandbox includes the host kernel and CPU profile in its checkpoint execution compatibility. An OS or CPU-profile change can therefore make retained checkpoints incompatible even on their original node. Before maintenance, keep a node with the matching execution class and the same ready generation available for those checkpoints; otherwise their requests wait under the [checkpoint retention policy](../sandbox-provider.md#checkpoint-transfer).
diff --git a/docs/getting-started/operations.md b/docs/getting-started/operations.md
index 5ebee95a7..3a97bcb7f 100644
--- a/docs/getting-started/operations.md
+++ b/docs/getting-started/operations.md
@@ -127,7 +127,7 @@ Core records which key made each public resource write; the retention of that hi
A recoverable backup contains one consistent, stopped-write set. A database dump or Core volume export alone does not include independent workspace storage or node compute state. Restore the data volume together with the installation directory from the same backup, which holds the release that wrote it.
-### Single-host backup and restore {#single-host-backup}
+### Single-host backup and restore
For an installation whose data all lives in its Docker volume, with no independent workspace storage and no node state to keep, the data volume and the installation directory are the whole backup. This recipe uses a Unix shell and the PostgreSQL image the installation already pulled.
@@ -164,8 +164,7 @@ An installation with independent workspace storage or nodes needs the full proce
- Every independent workspace namespace selected by current or retained objects, even when it is outside the installation volume. Back up its entire root, including `.oac-storage-root`, object identities, staging, live data, trash and deletion markers. Preserve numeric ownership, modes, links and extended attributes, including every `user.*` attribute. Copying only `live/data` loses lifecycle evidence and can resurrect deleted identities. [Workspace storage](../workspace-provider.md#kernel-nfs-adapter) owns the layout and ownership requirements.
- For a [quota mode](../workspace-provider.md#quota-mode) namespace, the entire XFS filesystem holding the export as one block-level copy: a storage or LVM snapshot, or an image of the frozen or unmounted device. Only such a copy keeps project IDs, quota limits, inode identities, the filesystem UUID and the `oac-workspace-quota` journal consistent. A file-level copy, `tar`, `rsync` or `xfsdump` loses them; the command then refuses the restored objects instead of serving them unbounded.
- Each node's state directory, `/var/lib/oac-node/.oac/nodes//`, and its provider storage: Docker volumes or microsandbox's store. Include all compute and snapshot resources still referenced by the database. See [when a node host fails](./nodes.md#when-a-node-host-fails).
-
-- Each private `checkpoint_root` in its entirety, including `.oac-checkpoint-store`, checkpoints, operation journals, lock files and tombstones, together with the matching Core database. It is separate from the native SDK store and independent workspace namespace. Preserve its identity and private ownership; the [checkpoint transfer contract](../sandbox-provider.md#checkpoint-transfer) owns its lifecycle.
+- Each private `checkpoint_root` in its entirety, including `.oac-checkpoint-store`, checkpoints, operation journals, lock files and tombstones, together with the matching Core database. The [checkpoint transfer contract](../sandbox-provider.md#checkpoint-transfer) owns its identity, ownership and lifecycle.
### Establish a stopped-write window
@@ -192,7 +191,7 @@ Keep application ingress and Core/node services stopped while restoring. Fence o
Restore matching secrets and database state, the complete independent filesystem namespaces and any required node identities/provider stores before starting Core. Preserve the database's configuration and namespace UUIDs, object identities and deletion markers; do not run first-time namespace initialization over restored storage. Restore a quota mode filesystem by writing its block-level copy to the backing device and mounting it with `prjquota` at the configured mount point; never run `oac-workspace-quota init` over it, and do not mount the copy beside the original, which has the same filesystem UUID. Reestablish the configured mount paths and service UIDs, then validate the mounted filesystem, ownership and xattrs from each participating service context. [Set up workspace storage](./workspace-storage.md) owns deployment setup.
-The cold released baseline resumes only qualified native history after new compute admission. A backup containing retained checkpoints also depends on the matching native runtime, node identity, provider store and external filesystem identities. File-level restore can change inode identity and prevent strict checkpoint restore even when file bytes match. This procedure does not promise portable memory snapshots or restoration onto an arbitrary replacement node; preserve unresolved ownership rather than substituting a new sandbox.
+A cold restore resumes only qualified native history after new compute admission. A backup containing retained checkpoints also depends on the matching native runtime, node identity, provider store and external filesystem identities. File-level restore can change inode identity and prevent strict checkpoint restore even when file bytes match. Memory snapshots are not portable and restoration onto an arbitrary replacement node is unsupported; preserve unresolved ownership rather than substituting a new sandbox.
Start the database, Core and node services only after their restored dependencies are complete; keep ingress restricted while checking them. In an isolated rehearsal, verify a retained Session's files and native continuation on fresh compute where qualified, confirm that deleted objects cannot be reopened, and check that no old writer can access the restored namespace. Record the results before relying on the backup for recovery.
diff --git a/docs/getting-started/public-address.md b/docs/getting-started/public-address.md
index f4defced5..e7e3fa61b 100644
--- a/docs/getting-started/public-address.md
+++ b/docs/getting-started/public-address.md
@@ -6,7 +6,7 @@ Set the one origin that browsers, nodes, sandboxes and applications use to reach
## Choose the public URL
-`OAC_PUBLIC_URL` is the origin applications, nodes, sandboxes and self-hosted executors use. Web accepts only its host. Core derives the daemon WebSocket URL, the self-hosted `remote_url` and each sandbox's connection address from it. It is an http or https origin without a path.
+`OAC_PUBLIC_URL` is the origin applications, nodes, sandboxes and self-hosted executors use. Web accepts only its host. Core derives its other addresses from it, listed under [`OAC_PUBLIC_URL`](../configuration.md#appendix-core-environment-without-the-installer). It is an http or https origin without a path.
| Situation | Public URL |
| --- | --- |
diff --git a/docs/maintainers.md b/docs/maintainers.md
index 74a1a22ef..3a9090c3b 100644
--- a/docs/maintainers.md
+++ b/docs/maintainers.md
@@ -10,7 +10,6 @@ A distribution is a matched set of release assets built from one commit: the con
Core, Web and ingress images are published as verified Linux amd64/arm64 indexes. The arm64 control archive contains those three images; Node, hosted Runtime and offline payloads use Linux amd64. Release builders use QEMU for ARM image steps, including the E2B helper. Host `oac` binaries are built from the same command for Linux amd64/arm64, macOS amd64/arm64 and Windows amd64; launchers only select, verify and invoke them. Each version index is checked against its platform archives before floating tags move.
-
Build on Linux x86_64 with a glibc compatible with Debian 12, Docker, the Go version in `go.mod`, a C compiler (the microsandbox helper is a CGO build), Node, pnpm, Python 3.9 or newer, curl, tar, pigz and sha256sum. The source must be clean and committed. First prepare the pinned Codex package and MiniMax Code companion, then build:
```sh
@@ -62,7 +61,7 @@ The catalog records the commit, the Runtime protocol version, each artifact's SH
`make build-core-distribution` builds all of these. Build one on its own to test a Harness image or a helper. Run every command from the repository root; default outputs go under `${OAC_DEV_HOME:-$HOME/.oac}/build`.
-The three maintained Runtime images share a build-time adjustment to the pinned Debian login profile: an inherited, exported `PATH` is preserved, while an unset `PATH` receives Debian’s defaults. This keeps the Runtime’s initialized package and user paths available in login and non-login tools without another package-path setting. The combined image inherits the same profile. A changed upstream profile fails the build for review; custom shell startup files can still explicitly change `PATH`.
+The three maintained Runtime images share the digest-pinned base `node:22.23.1-bookworm-slim` with `ca-certificates`, `bash`, `git`, `python3`, `python3-pip` and `ripgrep`, and a build-time adjustment to the pinned Debian login profile: an inherited, exported `PATH` is preserved, while an unset `PATH` receives Debian’s defaults. This keeps the Runtime’s initialized package and user paths available in login and non-login tools without another package-path setting. The combined image inherits the same profile. A changed upstream profile fails the build for review; custom shell startup files can still explicitly change `PATH`.
**Codex Runtime image.** Extract the official npm package `@openai/codex@0.153.4-linux-x64` under `~/.oac` (for example with `npm pack --ignore-scripts` and `tar -xzf`), then:
@@ -119,7 +118,7 @@ The helper is written to `~/.oac/build/microsandbox-provider/oac-microsandbox-pr
### Standalone Core builds
-`make build-core` builds `oac-core`, `oac-core-device`, `oac-core-environment-key` `oac-node` and `oac` into `${OAC_DEV_HOME:-$HOME/.oac}/build/oac-core` (`OAC_DEV_CORE_BUILD_DIR` selects another absolute directory). The build copies only the source set listed in `scripts/build-core.sh` (the Core service, its contracts, the shared packages it needs and the root Go module files) into a temporary context and builds with CGO disabled, read-only modules and trimmed paths. It needs no Node, Docker or other application. When Core gains a shared dependency, add that package to the list; never copy the whole repository to make it compile.
+`make build-core` builds `oac-core`, `oac-core-device`, `oac-core-environment-key`, `oac-node` and `oac` into `${OAC_DEV_HOME:-$HOME/.oac}/build/oac-core` (`OAC_DEV_CORE_BUILD_DIR` selects another absolute directory). The build copies only the source set listed in `scripts/build-core.sh` (the Core service, its contracts, the shared packages it needs and the root Go module files) into a temporary context and builds with CGO disabled, read-only modules and trimmed paths. It needs no Node, Docker or other application. When Core gains a shared dependency, add that package to the list; never copy the whole repository to make it compile.
`make docker-build-core` builds the image `oac-core:dev` (`OAC_DEV_CORE_IMAGE` selects another name) from those five commands and the E2B helper. The base is the digest-pinned `debian:bookworm-slim` with CA certificates and the glibc runtime the helper needs; the default user is UID/GID 65532 and Core listens on `:8091`. This local target builds Linux amd64; the [distribution build](#build-a-distribution) builds both architectures. Changes to the image or its build need `make check-core-container` in addition to the relevant source checks: it runs the official-client suite against the image with a read-only root filesystem and needs Linux Docker, a non-root user, and the [test database and pinned SDK](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/services/core/README.md#official-client-verification) of the service checks (`OAC_TEST_DATABASE_URL` naming an `oac_*_tests` database with the migrations applied, and `OAC_TEST_OFFICIAL_SDK_PYTHON`).
@@ -224,9 +223,9 @@ Use **Actions → core-check → Run workflow** for a manual full check. For a t
The `CI review and Feishu notification` workflow runs once after a PR merges into main. It checks out the merged commit, reads that PR's existing checks and logs, and sends one Feishu card through `FEISHU_WEBHOOK_URL` that summarizes the change, its fit with the repository rules and the actual CI status. It does not trigger another test run, and a failed review or delivery never fails the job or blocks merges. Closing an unmerged PR does not invoke the review. The workflow uses `pull_request_target` only for the merged event and never checks out an unmerged PR head with notification credentials.
-Browser jobs own separate fixtures and servers; increasing workers against the shared mutable fixture is unsafe. Failed browser jobs retain reports/traces for seven days. Native failure phase summaries are retained for seven days and detailed output stays in the Actions logs; credentials and temporary installation trees are not uploaded. Native archives are built and uploaded only for explicit manual packaging or releases, without recompressing the compressed archive. Release distribution artifacts retain their existing recovery policy; failed publication can reuse the original build as described above.
+Browser jobs own separate fixtures and servers; increasing workers against the shared mutable fixture is unsafe. Failed browser jobs retain reports/traces for seven days. Native failure phase summaries are retained for seven days and detailed output stays in the Actions logs; credentials and temporary installation trees are not uploaded. Native archives are built and uploaded only for explicit manual packaging or releases, without recompressing the compressed archive. Release distribution artifacts retain their recovery policy; failed publication can reuse the original build as described above.
-The local Node composite action installs the pinned pnpm and caches its package store by lockfile, OS, architecture, Node version and pnpm version. It caches downloaded packages, not `node_modules`; installs remain frozen. Go partitions retain the existing module/compiler caches described under [publication](#publish-a-version). Cache hits seed work and never replace tests. The three native platforms run independently; parallel execution reduces elapsed time without reducing total machine time.
+The local Node composite action installs the pinned pnpm and caches its package store by lockfile, OS, architecture, Node version and pnpm version. It caches downloaded packages, not `node_modules`; installs remain frozen. Go partitions retain the module/compiler caches described under [publication](#publish-a-version). Cache hits seed work and never replace tests. The three native platforms run independently; parallel execution reduces elapsed time without reducing total machine time.
For a local change, inspect the selected groups and choose focused checks according to [Checks for a change](../CONTRIBUTING.md#checks-for-a-change):
@@ -237,7 +236,7 @@ make check-ci
`make check` remains the full local entry point with an unsharded Web suite and an unsharded Core integration test package. `make check-web-unit` and `make check-web-acceptance OAC_WEB_TEST_SHARD=1/4` expose the Web parts; `make check-core-packages` and `make check-core-integration OAC_CORE_INTEGRATION_SHARD=1/3` expose the Core parts, with integration tests assigned to shards by a stable hash of their names. The selection tests cover mixed changes, shared consumers, renames/deletions, unknown inputs, shallow merge checkouts and failed/cancelled/missing results. For changes to the selection map, replay representative diffs for the affected rules. For workflow changes, run actionlint and validate the changed scheduling or partition behavior. Use real component runs only when needed to validate behavior affected by the change.
-Measure completed runs with `python3 scripts/ci_metrics.py RUN_ID ...`. It reports the latest attempt's summed runner minutes, elapsed time and initial queue delay from that attempt's start, peak concurrent jobs, platform breakdown and job outcomes/failure fraction. Only jobs assigned a runner in that attempt contribute machine time and execution concurrency; jobs cancelled while queued retain their outcome and wall time. Earlier attempts are not included. Failed-job reruns can carry earlier successful results: their outcomes appear separately and their old execution time is excluded. A missing rerun start timestamp stops measurement because reused jobs cannot be separated reliably. Keep run/head/attempt identities with comparisons, and report cancellations and unfinished runs separately. Raw runner minutes are not billed minutes; use each platform's published conversion and allowance rules before estimating cost. A small successful sample is not a long-term failure-rate estimate. Scheduled full runs are outside this policy.
+Measure completed runs with `python3 scripts/ci_metrics.py RUN_ID ...`. It reports the latest attempt's summed runner minutes, elapsed time and initial queue delay from that attempt's start, peak concurrent jobs, platform breakdown and job outcomes/failure fraction. Only jobs assigned a runner in that attempt contribute machine time and execution concurrency; jobs cancelled while queued retain their outcome and wall time. Earlier attempts are not included. Failed-job reruns can carry earlier successful results: their outcomes appear separately and their old execution time is excluded. A missing rerun start timestamp stops measurement because reused jobs cannot be separated reliably. Keep run/head/attempt identities with comparisons, and report cancellations and unfinished runs separately. Raw runner minutes are not billed minutes; use each platform's published conversion and allowance rules before estimating cost. A small successful sample is not a long-term failure-rate estimate.
### CI runners and free allowance
diff --git a/docs/sandbox-provider.md b/docs/sandbox-provider.md
index b8db55b7e..a46638a76 100644
--- a/docs/sandbox-provider.md
+++ b/docs/sandbox-provider.md
@@ -136,7 +136,6 @@ A new provider takes these steps:
6. Supply the distribution artifacts for the adapter and its helper, and offer the provider to operators through the registered configuration contract.
7. Web's setup step, deployment summary and client projection name each provider. Add the new provider to `apps/web` until the protocol declares configuration fields.
-
A node configuration, `sandbox.NodeConfig`, holds `provider`, `generation`, `installation_id`, `core_url`, `specification` and the adapter's opaque `native` object. `providers.Build` validates `provider`, `generation`, `installation_id` and `specification`, and passes the configuration with ephemeral `sandbox.LocalOptions` to `BuildLocal`, which decodes `native` strictly. The caller explicitly selects standalone registration or single-provider execution with `Standalone`, or generation-owned execution with a canonical absolute node state directory in `GenerationStateDirectory`. Missing or mixed contexts are rejected. The adapter owns generation-specific native preparation and readiness checks. Microsandbox binds helper leases to the installation, generation and specification digest, then checks the pinned image after platform, capacity and artifact readiness.
### Registration validation
@@ -252,6 +251,7 @@ A Provider relies on these rules:
- A retained checkpoint resumes on its original node when it is eligible, or on another eligible node through [checkpoint transfer](#checkpoint-transfer). Core owns the snapshot's retention deadline, and the daemon has no timer for it.
- A consumed snapshot never rolls a running generation back. Consumed artifacts and old compute are deleted, so suspension cycles never build a chain of writable disks.
- Deletion, revocation and retention expiry win over wake, up to the final database compare-and-swap. Unknown cleanup identities are kept until owned resources are confirmed absent.
+
### Checkpoint transfer
A checkpoint-capable generation reports `CheckpointCompatibility`: opaque `ArtifactDomain` and `ExecutionClass` tokens. Every verified `SnapshotIdentity` carries the same qualification. Core compares these values without interpreting CPU features, filesystem paths or storage implementations. A restore destination must be online and ready for the allocation's immutable deployment generation, match both tokens, and have active capacity plus a retained slot when moving from another node. The allocation, Device and Session identities remain unchanged. The Session and deployment transaction commits the destination route, placement and exact restore intent before target-side native work. No capacity or compatible destination leaves the retained snapshot owned until its configured deadline. The target must already hold that exact generation; Core does not automatically prepare historical generations on new nodes. A node keeps a superseded generation's provider until its checkpoint retention obligations end.
diff --git a/docs/web/console-api-usage.md b/docs/web/console-api-usage.md
index 97a29c595..49103e848 100644
--- a/docs/web/console-api-usage.md
+++ b/docs/web/console-api-usage.md
@@ -73,7 +73,7 @@ In an archived project the section hides **Issue credential** and **Rotate** beh
| Write operations | `GET /core/v1/projects/{project_id}/write-operations` | A project's write history, newest first, filtered by key and resource type, 50 per page |
| Summary | `GET /core/v1/summary` | Overview (per project), the Agents list (`group_by=agent`), a project's page (per project and `group_by=key`), Agent metrics (to skip idle projects, and usage by creating key since the start of the range), the Projects list (last activity) |
| Installation | `GET /core/v1/installation` | Settings → Service and deployment installation facts (`public_url`, `api_base_url`, `installation_id`, `source_commit`) and read-only Startup settings (`configuration.settings`; a sensitive setting shows only whether it is `configured`); `api_base_url` in the call samples; `public_url` as the download origin and `--source-url` of the node install and uninstall commands (and the install command's `--core-url`). A sensitive setting with a value, or an unknown member, fails the read |
-| Core metrics | `GET /core/v1/metrics?range=` | Core metrics page. A Core without the route (404) is shown as not reporting. [Core metrics](../../contracts/agents-api/core-metrics.md) defines every measurement |
+| Core metrics | `GET /core/v1/metrics?range=` | Core metrics page. [Core metrics](../../contracts/agents-api/core-metrics.md) defines every measurement |
`local_only`, or no `public_url`, stops Add node from issuing a command and Clean up the host from giving one. Overview, Nodes and Settings then show a visible warning, with Review the public address leading to Settings → Service and deployment. Nodes disables Add node with a visible reason, and Getting started leaves its sandbox step to do.
@@ -89,7 +89,7 @@ Summary figures are cumulative per Session and are not billing records. Sessions
| Operation | Route | Console use |
| --- | --- | --- |
-| List Harnesses | `GET /core/v1/harnesses` | Settings → Models and credentials default model cards: each Harness's readiness (Ready when `enabled` and its model configuration is set, otherwise Model provider not set or Disabled), `default`, its model configuration without the key, and Usage details from the configuration's `last_used_at`, `last_error_code` and `last_error_at`; the Overview's Getting started (the default Harness is Ready, or any Harness when none is default) |
+| List Harnesses | `GET /core/v1/harnesses` | Settings → Models and credentials default model cards: each Harness's readiness ([readiness](../configuration.md#runtime-settings-web)), `default`, its model configuration without the key, and Usage details from the configuration's `last_used_at`, `last_error_code` and `last_error_at`; the Overview's Getting started (the default Harness is Ready, or any Harness when none is default) |
| Set or replace | `PUT /core/v1/harnesses/{harness}/model-configuration` | **Set** or **Replace**: the complete model configuration with its write-only provider key, never prefilled and never retried; a 400 shows Core's message in the form; then the list is read again |
| Clear | `DELETE /core/v1/harnesses/{harness}/model-configuration` | **Clear**, confirmed, then the list is read again |
diff --git a/docs/web/console-server.md b/docs/web/console-server.md
index 50f096fa5..8ecd5beee 100644
--- a/docs/web/console-server.md
+++ b/docs/web/console-server.md
@@ -80,7 +80,7 @@ The administrator signs in with the deployment's [Core key](../getting-started/o
- The session cookie `core_console_session` is HttpOnly, `SameSite=Strict`, and `Secure` when `OAC_PUBLIC_URL` is HTTPS. It lasts 12 hours.
- Sessions live only in the console's memory, at most 64 at a time; the oldest is dropped first. A console restart or a Core key rotation signs everyone out.
- At most two sign-in checks run at once; another attempt gets 429 with `Retry-After: 1`.
-- Failed attempts share a budget of 10 per minute; beyond it, a wrong key gets 429 with `Retry-After: 60`. The correct key always signs in, which is why the console refuses to start with a Core key shorter than 32 characters.
+- Failed attempts share a budget of 10 per minute; beyond it, a wrong key gets 429 with `Retry-After: 60`. The correct key always signs in, which is why the console refuses to start with a Core key that breaks the [key format](../getting-started/operations.md#core-key).
Sign-in errors: 400 for a malformed body, 401 `Invalid Core key`, 405 for a method other than `POST`, 415 for a body that is not JSON, 429 as above, and 503 when the console cannot create a session.
diff --git a/docs/web/index.md b/docs/web/index.md
index df57f68d5..80887254d 100644
--- a/docs/web/index.md
+++ b/docs/web/index.md
@@ -27,7 +27,7 @@ Signing in opens the Overview. While any step is still to do, its **Getting star
| Resources | Agents, Environment templates, Skills, Files, Vaults | Inspection and permitted deletion, with the Project and the creating key of each resource |
| Platform | Projects and keys | Create, rename and archive Projects; issue and revoke keys; each Project's usage, write history and how to call the API |
| Platform | Nodes | Add, edit and remove microsandbox or Docker nodes; each node's readiness, active and retained limits, host CPU and memory with their history, free disk, and allocations with elapsed time in each compute phase |
-| Platform | Settings | **Sandbox and scheduling**, **Workspace storage**, **Models and credentials**, and **Service and deployment**; see [configuration](../configuration.md#runtime-settings-web) |
+| Platform | Settings | Platform configuration, one group per [runtime setting](../configuration.md#runtime-settings-web) |
Missing data is shown as missing (—), never as zero. [Console API usage](./console-api-usage.md) lists what each page reads and how its figures are bounded.
@@ -42,7 +42,7 @@ Missing data is shown as missing (—), never as zero. [Console API usage](./con
| Issue, rotate or revoke a self-hosted executor's credential, or copy its install command | The Session's page in the **Session log**; see [Run self-hosted Sessions](../getting-started/self-hosted.md) |
| Delete a resource, for example a leaked Credential | The resource's row in its list, or its page; Files are deleted from the Files list. The public deletion rules apply |
-Web observes and administers the installation. It never starts a Session or sends input; agents run only when applications call `/v1`. Archiving a hosted Session requests cancellation and sandbox reclamation. [Concepts](../concepts.md#what-administrators-can-and-cannot-do) defines what administrators can do.
+Web observes and administers the installation. It never starts a Session or sends input; agents run only when applications call `/v1`. Archiving a hosted Session is defined in [Session archive](../../contracts/agents-api/admin-api.md#session-archive). [Concepts](../concepts.md#what-administrators-can-and-cannot-do) defines what administrators can do.
A new Project key is shown once, together with the calls that use it:
diff --git a/docs/zh/concepts.md b/docs/zh/concepts.md
index 457ec541b..03d1bce5e 100644
--- a/docs/zh/concepts.md
+++ b/docs/zh/concepts.md
@@ -1,7 +1,7 @@
---
title: "概念"
source: docs/concepts.md
-source_hash: 378b3621d64bbe1d70057c048c5bac457361dea628a30c5e60704d69d17277ca
+source_hash: a0749db928e9f8767f5547dec2e6fb4887d1ace214c6fb8a08fe2e7fd5667af0
---
项目是 OpenAgentCore 的执行租户。应用使用其 API 密钥;运维人员使用独立的 Core 密钥管理安装实例。[API 命名空间和凭据](api/index.md)将每类调用方映射到对应命名空间和凭据。
@@ -20,7 +20,7 @@ source_hash: 378b3621d64bbe1d70057c048c5bac457361dea628a30c5e60704d69d17277ca
## 管理员可以做什么 {#what-administrators-can-and-cannot-do}
-管理员管理项目和密钥、沙箱部署、节点、执行器凭据及部署默认模型。他们可以检查资源、执行历史、运行计数与用量,并按删除规则删除资源。归档托管 Session 会请求取消和沙箱回收;参见 [Session 归档](../../contracts/agents-api/zh/admin-api.md#session-archive)。
+管理员管理项目和密钥、沙箱部署、节点、执行器凭据及部署默认模型。他们可以检查资源、执行历史、运行计数与用量,并按删除规则删除资源。归档托管 Session 的行为由 [Session 归档](../../contracts/agents-api/zh/admin-api.md#session-archive)定义。
创建或编辑应用资产、启动 Session 和提交输入都需要项目 API 密钥。Core 密钥不提供应用身份,不能读取已保存的秘密。[Core 管理 API](../../contracts/agents-api/zh/admin-api.md) 定义其操作;[控制台服务器](web/console-server.md) 负责 Web 登录与凭据处理。
diff --git a/docs/zh/configuration.md b/docs/zh/configuration.md
index d68e58b04..c33e626cb 100644
--- a/docs/zh/configuration.md
+++ b/docs/zh/configuration.md
@@ -1,7 +1,7 @@
---
title: "配置参考"
source: docs/configuration.md
-source_hash: 5519609be1b60dbd8c1b3aaac6aa8500f3907bebdba50a9e2ce6cb4ebf928b13
+source_hash: e9ca5912f98f2acb49373b42e256a7343ea086bb195cccb3d3612085f8aee2de
---
Core 安装的每项设置、其归属位置以及修改方式。安装程序写入初始值;之后请使用本参考。每项设置都恰好只有一个归属位置,分属以下三类:
@@ -171,7 +171,7 @@ Compose 为 Web 设置这些变量。仅在不使用 Compose 运行控制台时
| `OAC_WEB_ADDR` | `:8080` | 监听地址。主机部分为空或未指定时,`oac-web healthcheck` 在 `127.0.0.1` 上探测其 `/healthz` |
| `OAC_PUBLIC_URL` | 必填 | [公共 URL](#settings):面向浏览器的准确源地址,可以使用 HTTP 或 HTTPS,且不得包含路径。Host 和源地址检查使用此值;HTTPS 会使 Session Cookie 具备 `Secure` 属性 |
| `OAC_WEB_UPSTREAM` | `http://core:8091` | Core 的源地址,可以使用 HTTP 或 HTTPS,且不得包含凭据、查询参数或路径 |
-| `OAC_WEB_CORE_KEY_FILE` | 必填 | 常规文件的绝对路径,该文件没有组或其他用户权限,并保存 Core 密钥:至少 32 个字符、不含空白字符、最大 4 KiB |
+| `OAC_WEB_CORE_KEY_FILE` | 必填 | 常规文件的绝对路径,该文件没有组或其他用户权限,并保存 [Core 密钥](getting-started/operations.md#core-key),最大 4 KiB |
| `OAC_WEB_DIST` | `/www` | 已构建控制台的绝对目录;必须包含 `index.html` |
| `OAC_WEB_NODE_PAYLOAD_DIR` | 未设置 | 所匹配发行版的节点载荷(即安装程序的 `node-payload/`)的绝对路径。未设置时,不提供 `/node-install/*`,且 **添加节点** 不可用 |
diff --git a/docs/zh/getting-started/install.md b/docs/zh/getting-started/install.md
index ec3f614c2..46a9f1f17 100644
--- a/docs/zh/getting-started/install.md
+++ b/docs/zh/getting-started/install.md
@@ -1,7 +1,7 @@
---
title: "安装 Core 和 Web"
source: docs/getting-started/install.md
-source_hash: ec59f9762d21e486cf84108e4dda087c9640095196527bb8059c6833279df8ec
+source_hash: 6f5dbf881566fe1be1c4ae0ae998066f8b6df43b6d489eb88a328a6868ab7706
---
本指南带运维人员从一台空主机到可用的安装:在 Docker 下运行的 Core、Web 控制台和 PostgreSQL,一个沙箱提供商,一个默认模型和第一个项目 API 密钥。Web 的 **概览** 通过 **新手引导** 清单跟踪同样的步骤。
@@ -93,7 +93,7 @@ curl -fsSL https://openagentcore.dev/install.sh | bash -s -- --public-url https:
1. 在 **项目与密钥** 中选择 **创建项目**,然后选择 **签发密钥**。对话框只显示一次密钥:复制并妥善保存。**如何调用** 卡片展示 API 基础 URL 和示例请求。
2. 将密钥和 API 基础 URL 交给应用开发者,他们可以继续阅读[运行第一个 Session](./quickstart.md)。
-## 从其他机器访问 Core {#configure-the-domain-and-https}
+## 从其他机器访问 Core {#reach-core-from-other-machines}
在一台机器上试用时,此步骤可选。应用、节点和沙箱通过同一个地址访问 Core,即公开 URL。局域网上用 HTTP 即可;超出局域网时,在前面放反向代理,并把公开 URL 设为它提供的 HTTPS 源地址。反向代理、端口以及之后如何修改地址,见[配置公开地址](./public-address.md)。
diff --git a/docs/zh/getting-started/nodes.md b/docs/zh/getting-started/nodes.md
index e59860b63..0863c5a6d 100644
--- a/docs/zh/getting-started/nodes.md
+++ b/docs/zh/getting-started/nodes.md
@@ -1,7 +1,7 @@
---
title: "添加和管理节点"
source: docs/getting-started/nodes.md
-source_hash: fef6bd64da44efaa4ab1943901667c68c749790c36974ffb15b1b2845d62a7eb
+source_hash: 16211a07449e565b8b6ad8856c0060140cd0a18ee16d16300ba969193afede74
---
节点是一台 Linux 主机,为 Core 托管 Session 运行沙箱。本指南面向在沙箱提供商(参阅[选择沙箱提供商](./sandbox-backends.md))为 microsandbox 或 Docker 时添加、修改和移除节点的运维人员;E2B 不需要节点。
@@ -112,7 +112,7 @@ root 只准备账号、组和服务单元;其他操作(包括 Docker 网络
## 跨节点的检查点恢复 {#checkpoint-recovery-across-nodes}
-microsandbox 跨节点检查点恢复要求在每个参与节点的安装命令加入 `--checkpoint-root /absolute/private/shared-store`。安装前将同一个私有 store 挂载到这些路径,并只允许 node 服务账户访问。默认使用节点本地私有 store,只支持在该节点恢复。检查点 store 独立于 workspace 存储,绝不能允许 guest 访问;[检查点转移契约](../sandbox-provider.md#checkpoint-transfer) 定义兼容性和保留要求。
+microsandbox 跨节点检查点恢复要求在每个参与节点的安装命令加入 `--checkpoint-root /absolute/private/shared-store`。安装前将同一个私有 store 挂载到这些路径,并只允许 node 服务账户访问。默认使用节点本地私有 store,只支持在该节点恢复。[检查点转移契约](../sandbox-provider.md#checkpoint-transfer) 定义 store 的隔离、兼容性和保留要求。
microsandbox 的检查点执行兼容性包含主机内核和 CPU profile。因此,操作系统或 CPU profile 变化可能使保留的检查点不再兼容,甚至无法在原节点恢复。维护前,应为这些检查点保留具有匹配 execution class 且已就绪同一 generation 的节点;否则,相关请求会按[检查点保留策略](../sandbox-provider.md#checkpoint-transfer)等待。
diff --git a/docs/zh/getting-started/operations.md b/docs/zh/getting-started/operations.md
index 2c3171110..6467c2309 100644
--- a/docs/zh/getting-started/operations.md
+++ b/docs/zh/getting-started/operations.md
@@ -1,7 +1,7 @@
---
title: "运维"
source: docs/getting-started/operations.md
-source_hash: c61c4d11097be8e0718c6c095c55b10a47020e5a2f83f24c504eb6753ca00b5c
+source_hash: 4fd70597517560cfab44ba9b10adedf7713c3a9c5441f0babd07531330174fdc
---
Core 安装运维人员的日常任务:`oac` 命令、服务健康状态、Core 密钥、备份和卸载。节点有[专门的指南](./nodes.md),[故障排查](./troubleshooting.md)列出了安装程序和访问方面的提示信息。设置见[配置参考](../configuration.md)。
@@ -129,7 +129,7 @@ Core 记录每次公开资源写入所使用的密钥;历史保留策略为 [`
可恢复的备份必须是一组在停止写入期间取得的一致数据。仅数据库转储或 Core 卷导出不包含独立工作区存储及节点计算状态。恢复数据卷时,同时恢复同一份备份中的安装目录,其中保存着写入该数据的版本。
-### 单机备份与恢复 {#single-host-backup}
+### 单机备份与恢复 {#single-host-backup-and-restore}
如果安装的全部数据都在其 Docker 数据卷中,没有独立工作区存储,也没有需要保留的节点状态,那么数据卷加安装目录就是完整备份。以下流程使用 Unix shell,以及该安装已拉取的 PostgreSQL 镜像。
@@ -166,8 +166,7 @@ docker run --rm -v "${project}_data:/data" -v ~/oac-backup:/backup:ro --entrypoi
- 当前或保留对象所使用的每个独立工作区命名空间,即使其位于安装卷之外。备份整个根目录,包括 `.oac-storage-root`、对象标识、staging、live 数据、trash 和删除标记。保留数值所有者、权限、链接及扩展属性,包括全部 `user.*` 属性。仅复制 `live/data` 会丢失生命周期证据,并可能使已删除标识复活。[工作区存储](../workspace-provider.md#kernel-nfs-adapter)负责定义布局与所有权要求。
- 对于[配额模式](../workspace-provider.md#quota-mode)命名空间,将承载导出的整个 XFS 文件系统作为一份块级副本备份:存储或 LVM 快照,或已冻结或已卸载设备的镜像。只有这样的副本能保持 project ID、配额限制、inode 标识、文件系统 UUID 和 `oac-workspace-quota` 日志库的一致。文件级复制、`tar`、`rsync` 或 `xfsdump` 会丢失这些信息;此时该命令会拒绝恢复后的对象,而不是在无上限状态下提供它们。
- 各节点状态目录 `/var/lib/oac-node/.oac/nodes//` 及其提供商存储:Docker 卷或 microsandbox 存储。包含数据库仍然引用的全部计算资源和快照。参见[节点主机故障时](./nodes.md#when-a-node-host-fails)。
-
-- 每个私有 `checkpoint_root` 的全部内容,包括 `.oac-checkpoint-store`、检查点、operation journal、lock 文件与 tombstone,并与匹配的 Core 数据库一起保留。它独立于原生 SDK store 和工作区 namespace。保留其身份和私有所有权;[检查点转移契约](../sandbox-provider.md#checkpoint-transfer)定义其生命周期。
+- 每个私有 `checkpoint_root` 的全部内容,包括 `.oac-checkpoint-store`、检查点、operation journal、lock 文件与 tombstone,并与匹配的 Core 数据库一起保留。[检查点转移契约](../sandbox-provider.md#checkpoint-transfer)定义其身份、所有权和生命周期。
### 建立停止写入窗口 {#establish-a-stopped-write-window}
@@ -194,7 +193,7 @@ docker compose -f "$HOME/.oac/core/compose.yaml" exec -T database \
启动 Core 前,恢复相匹配的 secrets 和数据库状态、完整的独立文件系统命名空间,以及任何所需的节点标识和提供商存储。保留数据库中的配置和命名空间 UUID、对象标识及删除标记;不要对恢复后的存储执行首次命名空间初始化。恢复配额模式文件系统时,将其块级副本写入后备设备,并以 `prjquota` 挂载到配置的挂载点;绝不要对其运行 `oac-workspace-quota init`,也不要将副本与原文件系统同时挂载,二者具有相同的文件系统 UUID。重新建立配置中的挂载路径和服务 UID,然后从每个参与服务的上下文验证所挂载文件系统、所有权及 xattr。[设置工作区存储](./workspace-storage.md)负责定义部署设置。
-已释放计算资源的冷恢复基线仅在新计算资源准入后续接具备资格的原生历史。包含保留检查点的备份还依赖匹配的原生 Runtime、节点标识、提供商存储和外部文件系统标识。文件级恢复可能改变 inode 标识,即使文件字节一致,也可能阻止严格检查点恢复。此流程不承诺可移植内存快照,也不承诺恢复到任意替代节点;应保留未解决的归属,而不是替换为新沙箱。
+冷恢复仅在新计算资源准入后续接具备资格的原生历史。包含保留检查点的备份还依赖匹配的原生 Runtime、节点标识、提供商存储和外部文件系统标识。文件级恢复可能改变 inode 标识,即使文件字节一致,也可能阻止严格检查点恢复。内存快照不可移植,也不支持恢复到任意替代节点;应保留未解决的归属,而不是替换为新沙箱。
恢复依赖全部完整后才启动 database、Core 和节点服务;检查期间保持入口受限。在隔离演练中,验证保留 Session 的文件和具备资格时在新计算资源上的原生续接,确认已删除对象无法重新打开,并检查旧写入方均无法访问恢复后的命名空间。在依赖备份进行恢复前记录结果。
diff --git a/docs/zh/getting-started/public-address.md b/docs/zh/getting-started/public-address.md
index d85986ecc..755afd06f 100644
--- a/docs/zh/getting-started/public-address.md
+++ b/docs/zh/getting-started/public-address.md
@@ -1,14 +1,14 @@
---
title: "配置公开地址"
source: docs/getting-started/public-address.md
-source_hash: 18cf3655776a7bd22a09023a7764abf17461570371b846ef5ce4d1caa3d13a6f
+source_hash: 02eb5d34fb53a65e4cadb60ada04c98c5667e083141e56b8c5169683926a8249
---
设置浏览器、节点、沙箱和应用访问 Core 所用的唯一源地址,并在其前面放置带 HTTPS 的反向代理。本指南面向将 Core 暴露到其所在机器之外的运维人员。
## 选择公开 URL {#choose-the-public-url}
-`OAC_PUBLIC_URL` 是应用、节点、沙箱和自托管执行器使用的源地址。Web 只接受其中的主机。Core 从中派生守护进程 WebSocket URL、自托管 `remote_url` 和每个沙箱的连接地址。它是不含路径的 http 或 https 源地址。
+`OAC_PUBLIC_URL` 是应用、节点、沙箱和自托管执行器使用的源地址。Web 只接受其中的主机。Core 从中派生其他地址,列在[`OAC_PUBLIC_URL`](../configuration.md#appendix-core-environment-without-the-installer)下。它是不含路径的 http 或 https 源地址。
| 场景 | 公开 URL |
| --- | --- |
diff --git a/docs/zh/maintainers.md b/docs/zh/maintainers.md
index 013a1cc94..7fbf7b40d 100644
--- a/docs/zh/maintainers.md
+++ b/docs/zh/maintainers.md
@@ -1,7 +1,7 @@
---
title: "构建并发布 OpenAgentCore"
source: docs/maintainers.md
-source_hash: f66f608093cc824add3215a9df520082b1679af1852ee213b7a6adfca40221ed
+source_hash: c0ce961c1457daffdada461892d2e75a44efa15efce814f535c60b98b0b7a6fc
---
本指南面向负责构建和发布 OpenAgentCore 的维护者。要安装 Core 和 Web,请按 [安装 Core 和 Web](getting-started/install.md) 操作。安装程序代码遵循的规则见 [部署](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/deploy/README.md) 和 [节点安装程序](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/deploy/node/README.md);必需检查见 [CONTRIBUTING](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/CONTRIBUTING.md#required-checks)。
@@ -12,7 +12,6 @@ source_hash: f66f608093cc824add3215a9df520082b1679af1852ee213b7a6adfca40221ed
Core、Web 和 ingress 镜像发布为经过校验的 Linux amd64/arm64 多架构索引。arm64 控制归档包含这三个镜像;Node、托管 Runtime 和离线包使用 Linux amd64。发行构建使用 QEMU 执行 ARM 镜像步骤,包括 E2B helper。主机 `oac` 从同一份实现构建为 Linux amd64/arm64、macOS amd64/arm64 和 Windows amd64 二进制;启动脚本只选择、校验并运行它们。所有版本索引校验通过后才更新浮动标签。
-
请在 Linux x86_64 上构建,所需环境包括与 Debian 12 兼容的 glibc、Docker、`go.mod` 中指定的 Go 版本、C 编译器(microsandbox 辅助程序使用 CGO 构建)、Node、pnpm、Python 3.9 或更高版本、curl、tar、pigz 和 sha256sum。源代码必须保持干净并已提交。请先准备固定版本的 Codex 包和 MiniMax Code 配套程序,然后执行构建:
```sh
@@ -64,7 +63,7 @@ export OAC_NATIVE_INSTALLER_BUILD_DIR=OUTPUT_DIR
`make build-core-distribution` 会构建以下全部内容。也可以单独构建其中一项,以测试某个 Harness 镜像或辅助程序。所有命令都必须从仓库根目录运行;默认输出位于 `${OAC_DEV_HOME:-$HOME/.oac}/build` 下。
-三个维护的 Runtime 镜像共用一个构建期调整:固定 Debian 登录 profile 会保留继承且已导出的 `PATH`,未设置 `PATH` 时仍使用 Debian 默认值。这样,登录和非登录工具都能使用 Runtime 初始化的包路径与用户路径,无需另一份包路径设置。组合镜像继承同一 profile。上游 profile 结构变化会使构建失败以便审查;自定义 shell 启动文件仍可以显式更改 `PATH`。
+三个维护的 Runtime 镜像共用固定摘要的基础镜像 `node:22.23.1-bookworm-slim`(含 `ca-certificates`、`bash`、`git`、`python3`、`python3-pip` 和 `ripgrep`),以及一个构建期调整:固定 Debian 登录 profile 会保留继承且已导出的 `PATH`,未设置 `PATH` 时仍使用 Debian 默认值。这样,登录和非登录工具都能使用 Runtime 初始化的包路径与用户路径,无需另一份包路径设置。组合镜像继承同一 profile。上游 profile 结构变化会使构建失败以便审查;自定义 shell 启动文件仍可以显式更改 `PATH`。
**Codex Runtime 镜像。** 在 `~/.oac` 下解压官方 npm 包 `@openai/codex@0.153.4-linux-x64`(例如使用 `npm pack --ignore-scripts` 和 `tar -xzf`),然后执行:
@@ -239,7 +238,7 @@ make check-ci
`make check` 仍是完整的本地入口,使用未分片的 Web 测试套件和未分片的 Core 集成测试包。`make check-web-unit` 和 `make check-web-acceptance OAC_WEB_TEST_SHARD=1/4` 用于分别运行 Web 部分;`make check-core-packages` 和 `make check-core-integration OAC_CORE_INTEGRATION_SHARD=1/3` 用于分别运行 Core 部分,其中集成测试按名称的稳定哈希分配到分片。选择测试涵盖混合变更、共享使用方、重命名/删除、未知输入、浅合并检出以及失败/取消/缺失结果。对于选择映射的更改,请针对受影响的规则重放具有代表性的差异。对于工作流更改,请运行 actionlint,并验证更改后的调度或分区行为。仅在需要验证受变更影响的行为时,才运行真实组件测试。
-使用 `python3 scripts/ci_metrics.py RUN_ID ...` 衡量已完成的运行。它会报告最近一次尝试的运行器分钟数总和、耗时、从该次尝试开始计算的初始排队延迟、并发作业峰值、平台明细以及作业结果/失败比例。只有在该次尝试中被分配了运行器的作业才计入机器时间和执行并发;排队期间被取消的作业仍保留其结果和实际耗时。更早的尝试不计入其中。失败作业的重新运行可能沿用更早的成功结果:这些结果会单独显示,且其原有执行时间会被排除。如果缺少重新运行的开始时间戳,测量会停止,因为无法可靠区分复用的作业。比较时应保留 run/head/attempt 标识,并分别报告取消和未完成的运行。原始运行器分钟数并非计费分钟数;估算成本前,应使用各平台公布的转换和配额规则。较小的成功样本不能作为长期失败率估计。定时完整运行不在此策略范围内。
+使用 `python3 scripts/ci_metrics.py RUN_ID ...` 衡量已完成的运行。它会报告最近一次尝试的运行器分钟数总和、耗时、从该次尝试开始计算的初始排队延迟、并发作业峰值、平台明细以及作业结果/失败比例。只有在该次尝试中被分配了运行器的作业才计入机器时间和执行并发;排队期间被取消的作业仍保留其结果和实际耗时。更早的尝试不计入其中。失败作业的重新运行可能沿用更早的成功结果:这些结果会单独显示,且其原有执行时间会被排除。如果缺少重新运行的开始时间戳,测量会停止,因为无法可靠区分复用的作业。比较时应保留 run/head/attempt 标识,并分别报告取消和未完成的运行。原始运行器分钟数并非计费分钟数;估算成本前,应使用各平台公布的转换和配额规则。较小的成功样本不能作为长期失败率估计。
### CI 运行器和免费配额 {#ci-runners-and-free-allowance}
diff --git a/docs/zh/sandbox-provider.md b/docs/zh/sandbox-provider.md
index 99173c5b2..2aae07456 100644
--- a/docs/zh/sandbox-provider.md
+++ b/docs/zh/sandbox-provider.md
@@ -1,7 +1,7 @@
---
title: "沙箱提供商协议"
source: docs/sandbox-provider.md
-source_hash: 2e359fb0bd99974bd1077f15b3a529c80a4ff19b3d9c2f7a3882fe125aa9f8c8
+source_hash: 5cb1e7a7139fceaf0e9efb1833959b067d6a7b313484b1d6c9c652e3ab9191f5
---
沙箱提供商协议连接 Core 与为 Core 管理的(`openai_hosted`)Environment 提供计算资源的 adapter,并由该 adapter 运行启动 Runtime daemon 的有界引导流程。本页面向 adapter 作者:说明提供商必须实现什么,以及可以依赖 Core 做什么。Docker、microsandbox 和 E2B 实现了该协议。
diff --git a/docs/zh/web/console-api-usage.md b/docs/zh/web/console-api-usage.md
index 19f1330f1..54fafc2c6 100644
--- a/docs/zh/web/console-api-usage.md
+++ b/docs/zh/web/console-api-usage.md
@@ -1,7 +1,7 @@
---
title: "控制台 API 使用"
source: docs/web/console-api-usage.md
-source_hash: d14848610e56678c0de35ed6796b4631c5cd42b8a1f0d25366e224a4ff878e44
+source_hash: fb035e336b49105be6cc6fb4ec72e2f62e98b7ca6ea696a907cdce2fd8824e9e
---
本页列出各控制台页面调用的 Core 路由,以及控制台如何限定读取范围。本页面向控制台开发者;运维人员请阅读 [Web 控制台](index.md)。[Core 管理 API](../../../contracts/agents-api/zh/admin-api.md) 定义了路由、响应结构、分页和审计记录;[API 命名空间和凭据](../api/index.md) 定义了本文使用的术语。
@@ -91,7 +91,7 @@ source_hash: d14848610e56678c0de35ed6796b4631c5cd42b8a1f0d25366e224a4ff878e44
| 操作 | 路由 | 控制台用途 |
| --- | --- | --- |
-| 列出 Harnesses | `GET /core/v1/harnesses` | **设置 → 模型与凭据** 的 **默认模型配置** 卡片:每个 Harness 的就绪状态(`enabled` 且已设置模型配置时为 **就绪**,否则为 **未设置模型提供商** 或 **已禁用**)、`default`、不含密钥的模型配置,以及来自配置中 `last_used_at`、`last_error_code` 和 `last_error_at` 的 **使用详情**;**概览** 的 **新手引导**(默认 Harness 为 **就绪**;没有默认 Harness 时,任意 Harness 为 **就绪**) |
+| 列出 Harnesses | `GET /core/v1/harnesses` | **设置 → 模型与凭据** 的 **默认模型配置** 卡片:每个 Harness 的就绪状态([就绪状态](../configuration.md#runtime-settings-web))、`default`、不含密钥的模型配置,以及来自配置中 `last_used_at`、`last_error_code` 和 `last_error_at` 的 **使用详情**;**概览** 的 **新手引导**(默认 Harness 为 **就绪**;没有默认 Harness 时,任意 Harness 为 **就绪**) |
| 设置或替换 | `PUT /core/v1/harnesses/{harness}/model-configuration` | **设置** 或 **替换**:提交包含只写提供商密钥的完整模型配置;该密钥绝不预填,写入也绝不重试;400 会在表单中显示 Core 的消息;随后再次读取列表 |
| 清除 | `DELETE /core/v1/harnesses/{harness}/model-configuration` | **清除**,需确认,随后再次读取列表 |
diff --git a/docs/zh/web/console-server.md b/docs/zh/web/console-server.md
index dd2518afa..614b67ca5 100644
--- a/docs/zh/web/console-server.md
+++ b/docs/zh/web/console-server.md
@@ -1,7 +1,7 @@
---
title: "控制台服务器"
source: docs/web/console-server.md
-source_hash: 2c8b3bfed09d29c70cfee4b3381a248befd722c8336c4964a079e20c073f1a4a
+source_hash: 927c27a14bbcc394d7218053937eaea8eaf95258cfbe035d48d298568c97caa5
---
控制台服务器(`oac-web`)提供 Web,使用 Core 密钥认证管理员,并将浏览器的 `/core/v1` 请求转发到 Core。本参考面向不使用安装程序运行 Web 的运维人员,以及评审其安全边界的人员。
@@ -82,7 +82,7 @@ flowchart LR
- 会话 cookie `core_console_session` 为 HttpOnly、`SameSite=Strict`,`OAC_PUBLIC_URL` 为 HTTPS 时还设置 `Secure`。有效期 12 小时。
- 会话仅存在控制台内存中,最多同时 64 个,先移除最旧的。重启控制台或轮换 Core 密钥会让所有用户退出登录。
- 同时最多执行两次登录检查;额外尝试返回 429 和 `Retry-After: 1`。
-- 失败尝试共享每分钟 10 次预算;超出后,错误密钥返回 429 和 `Retry-After: 60`。正确密钥始终可以登录,因此控制台拒绝使用少于 32 字符的 Core 密钥启动。
+- 失败尝试共享每分钟 10 次预算;超出后,错误密钥返回 429 和 `Retry-After: 60`。正确密钥始终可以登录,因此控制台拒绝使用不符合[密钥格式](../getting-started/operations.md#core-key)的 Core 密钥启动。
登录错误:请求体格式错误为 400,错误密钥为 401 `Invalid Core key`,非 `POST` 方法为 405,非 JSON 请求体为 415,上述频率限制为 429,无法创建会话为 503。
diff --git a/docs/zh/web/index.md b/docs/zh/web/index.md
index 5b40a5c41..703063f8d 100644
--- a/docs/zh/web/index.md
+++ b/docs/zh/web/index.md
@@ -1,7 +1,7 @@
---
title: "Web 控制台"
source: docs/web/index.md
-source_hash: fed3544a6fb993db8fb8a4f6c4dc3f64894ff2a587cd6d2deb3b49b9b74d082f
+source_hash: d8f267f45ad305a3c7280d98333aaa1fdfdf4d5cc5082a5781d5de7ab1bd56b4
---
Web 是 OpenAgentCore 安装的管理员控制台:运维人员用 Core 密钥登录,查看健康状态和用量,检查应用创建的内容,并管理项目、密钥、节点和设置。应用使用项目 API 密钥调用 `/v1`,不使用 Web。
@@ -29,7 +29,7 @@ Web 是 OpenAgentCore 安装的管理员控制台:运维人员用 Core 密钥
| 资源 | Agent、Environment 模板、Skills、文件、Vault | 检查和允许的删除操作,显示各资源所属项目及创建密钥 |
| 平台 | 项目与密钥 | 创建、重命名和归档项目;签发与撤销密钥;各项目的用量、写入历史和 API 调用方法 |
| 平台 | 节点 | 添加、编辑和移除 microsandbox 或 Docker 节点;各节点的就绪状态、活跃与保留上限、主机 CPU 与内存及其历史、可用磁盘,以及分配及其在各计算阶段的已用时间 |
-| 平台 | 设置 | **沙箱与调度**、**工作区存储**、**模型与凭据** 和 **服务与部署**;参阅[配置](../configuration.md#runtime-settings-web) |
+| 平台 | 设置 | 平台配置,每个[运行时设置](../configuration.md#runtime-settings-web)一组 |
缺失数据展示为缺失(—),不会当作零。[控制台 API 使用](console-api-usage.md)列出各页面读取内容及统计边界。
@@ -44,7 +44,7 @@ Web 是 OpenAgentCore 安装的管理员控制台:运维人员用 Core 密钥
| 签发、轮换或撤销自托管执行器凭据,或复制安装命令 | **Session 日志** 中的 Session 页面;参阅[运行自托管 Session](../getting-started/self-hosted.md) |
| 删除资源,例如泄露的 Credential | 资源列表行或资源页面;文件从 **文件** 列表删除。适用公开删除规则 |
-Web 观察并管理安装。它从不启动 Session,也不发送输入;只有应用调用 `/v1` 时 Agent 才会运行。归档托管 Session 会请求取消并回收沙箱。[概念](../concepts.md#what-administrators-can-and-cannot-do)定义了管理员能做什么。
+Web 观察并管理安装。它从不启动 Session,也不发送输入;只有应用调用 `/v1` 时 Agent 才会运行。归档托管 Session 的行为由 [Session 归档](../../../contracts/agents-api/zh/admin-api.md#session-archive)定义。[概念](../concepts.md#what-administrators-can-and-cannot-do)定义了管理员能做什么。
新项目密钥只显示一次,并附带使用它的调用示例:
diff --git a/example/parsar/README.md b/example/parsar/README.md
index 72eead840..309cdf499 100644
--- a/example/parsar/README.md
+++ b/example/parsar/README.md
@@ -37,7 +37,7 @@ Use one server process and a dedicated Project for this local single-user exampl
A few more implementation details:
- **Providers and models** are saved together in one SQLite transaction. Editing reads a Provider and its models as one snapshot; changing a model advances the Provider's revision.
-- **Browser calls** use `OpenAIAgentsClient`, with a small public HTTP reader for Artifacts (not yet exposed by that client); only Session creation goes through a small server adapter. Closing the browser aborts the upstream stream, never the running Session.
+- **Browser calls** use `OpenAIAgentsClient`, with a small public HTTP reader for Artifacts (the client has no Artifact method); only Session creation goes through a small server adapter. Closing the browser aborts the upstream stream, never the running Session.
- **Workspaces:** hosted Sessions each get their own. User-machine Sessions use the selected host directory, so the same path means shared files.
- **Skills on a user machine** come only from local capability directories in this example; it rejects Agents bound to managed Skills instead of ignoring them. Core itself can deliver managed Skills to user machines through `x_agents_core.environment`.
@@ -66,6 +66,6 @@ Create a user-machine runtime and start a Session with an Agent using Codex or C
The selected model Provider needs an HTTPS Base URL and API key. Its protocol is Responses for Codex and Anthropic for Claude Code and MiniMax Code. Core freezes and delivers the configuration to the enrolled executor. Local pending creation requests contain that configuration but browser Session responses omit the entire pending request.
-Self-hosted capability sources are local directories under the current Core API. Managed Skill bindings fail explicitly; configure local Skills/Plugins in the runtime's capability directory before connecting. Bound HTTP MCP services also fail explicitly for self-hosted Sessions; configure them in local Plugins instead.
+Self-hosted capability sources are local directories under the Core API. Managed Skill bindings fail explicitly; configure local Skills/Plugins in the runtime's capability directory before connecting. Bound HTTP MCP services also fail explicitly for self-hosted Sessions; configure them in local Plugins instead.
The daemon runs with the starting user's permissions and adds no sandbox. Runtime home is separate per Session; stopping it preserves local files. Credential rotation and revocation remain Core console operations. Reuse the original installation directory when reconnecting.
diff --git a/packages/claude-sdk-adapter/README.md b/packages/claude-sdk-adapter/README.md
index ce6fa2535..ac28cf5ae 100644
--- a/packages/claude-sdk-adapter/README.md
+++ b/packages/claude-sdk-adapter/README.md
@@ -66,7 +66,7 @@ Workspace deferred-function discovery uses native ToolSearch alongside the norma
For unmanaged bootstrap, daemon `connect` optionally registers this adapter as `claude_sdk` when the operator sets `OAC_RUNTIME_CLAUDE_SDK_ENTRYPOINT` to the absolute packaged `dist/main.js`. `OAC_RUNTIME_CLAUDE_SDK_NODE` selects Node (default: `node` on PATH). Discovery resolves Node once and checks that exact configuration before connecting; the SDK's bounded runtime check is independent of CLI version probes. A ready SDK alone is sufficient to start the daemon. No configuration means no SDK probe or descriptor; failed readiness reports an unavailable descriptor without factories. Runtime checks establish local readiness, not provider authentication. Installed daemons use `start` and their verified installation manifest for adapter selection and activation; ambient activation variables cannot extend that selection. See [the native installation contract](../../deploy/README.md#native-daemon-installer).
-SDK state lives under `paths.ProfileDir(profile)/runtime/claude-sdk`, independently of the replaceable runtime bundle. Both the entrypoint and managed state root must be absolute. Background re-execution inherits operator configuration; it does not persist provider credentials in credential profiles. It accepts no caller-supplied environment variables or business write authority.
+The SDK state paths are in the [Claude Runtime](../../services/core/deploy/claude/README.md) guide. Both the entrypoint and managed state root must be absolute. Background re-execution inherits operator configuration; it does not persist provider credentials in credential profiles. It accepts no caller-supplied environment variables or business write authority.
### Descriptor and execution profile
@@ -90,7 +90,7 @@ Each SDK result supplies one native usage snapshot, including reported failures.
Active text uses the SDK's `AsyncIterable` input, with a fresh native UUID mapped to each daemon input ID. A native query may fold text into its current native turn or queue another; one daemon Run can therefore contain several native turns. Never promise Codex's same-native-turn semantics. Writes, queued notifications and user-message echoes do not confirm consumption. Only matching root assistant/partial/result `user_message_uuids` (or the singular fallback) confirm applied input. Typed mid-turn folds may appear only on the native result. Preserve that receipt even when the result reports failure. Check pending functions after the query drains: the SDK may dispatch later-turn callbacks before the earlier result handler finishes. Keep Turn input admission open until every submitted input has a consuming result, even when an earlier result reports an empty native queue. Close admission before releasing final receipt waiters. The outer SDK iterator remains open across Turns. Cancellation resolves unconfirmed pending receipts as unknown and interrupts the exact native Turn. Successful Cancel requires confirmed Turn settlement; process exit alone cannot establish a successful cancellation. Reuse also requires an empty confirmed native queue and settled child work. Otherwise close the Executor. The settled CancellationOutcome retains verified native identity, partial text and observed Usage; a requested resume identity alone is not evidence. Caller wait expiry reports failure/unknown while cleanup retains ownership. Output backpressure cannot turn missing native facts into confirmed settlement. Closed Turn output precedes successful AwaitSettlement; the settled outcome remains readable when connection loss prevents publication. A receipt timeout after a full write preserves the process and pending identity without redelivery; a blocked write is cancelled and released. The private adapter permits one input awaiting consumption and at most 63 extra inputs per Run, preserving the native 64-UUID receipt bound. Durable receipt opt-in separates bounded writes from native consumption waits; calls without it keep the router's ten-second deadline. Larger input capacity and recovery of interrupted input are not supported. Daemon registration alone does not establish public acceptance.
-[Harness capabilities](../../contracts/agents-api/harness-capabilities.md) and its linked operation contracts record current public qualification. Keep native execution evidence separate from local registration and packaging checks. Live adapter acceptance uses a real provider with private credentials; fixture tests cannot substitute for it.
+Keep native execution evidence separate from local registration and packaging checks. Live adapter acceptance uses a real provider with private credentials; fixture tests cannot substitute for it.
## Subagents
@@ -112,6 +112,6 @@ Cancellation uses an adapter-owned effect receipt only after the query owner con
The build validates source manifests with the repository-pinned pnpm frozen install and compiles into fresh managed staging, never exporting incremental checkout output. It then uses `pnpm deploy` from the adapter workspace with its dedicated frozen lock. The adapter has no workspace dependencies; keep that boundary explicit. Workspace injection is configured only in this adapter project for its frozen export; do not enable it in the Web/client workspace or replace export with a custom dependency copier. Export only compiled `dist` and production dependencies; retain their package metadata, lockfile and licenses. Check dependency links stay inside the export, pinned SDK/MCP/native versions, native `--version`, and bridge startup before publishing the archive. Startup with stdin EOF is an import check, not model execution acceptance. `make check-claude-sdk` includes this artifact check.
-Extract the archive into a fresh managed runtime directory on a matching host and use its absolute `dist/main.js` as the private factory entrypoint. Validate relocation and real provider cancellation/continuation before accepting an artifact. Linux x64/glibc with Node22 is the currently exercised platform; other hosts require their own native acceptance. Do not reuse a bundle across platforms or libc variants. The native installer bundles Node and owns user-managed activation; release publication remains separate. Operator-configured discovery and registration remain available for unmanaged bootstrap as specified above.
+Extract the archive into a fresh managed runtime directory on a matching host and use its absolute `dist/main.js` as the private factory entrypoint. Validate relocation and real provider cancellation/continuation before accepting an artifact. Linux x64/glibc with Node22 is the tested platform; other hosts require their own native acceptance. Do not reuse a bundle across platforms or libc variants. The native installer bundles Node and owns user-managed activation; release publication remains separate. Operator-configured discovery and registration remain available for unmanaged bootstrap as specified above.
The exported `dist/runtime_check.js` companion is the local readiness contract. It checks the Node version, installed SDK/MCP/native versions against the package manifest, contained dependency resolution, native startup, and the exact `dist/main.js` bridge with stdin EOF. It emits one versioned JSON report without calling a model or creating Session state. The artifact check reuses this companion and separately checks all exported links, the lockfile and source pins. `claudesdk.CheckRuntime` uses the same Node, entrypoint and environment as execution, with shared process-group ownership, bounded output and a 15-second deadline plus bounded cleanup. Both native and bridge probes have five-second limits. Return unavailable on failed or malformed probes; never forward native diagnostics or treat local readiness as provider authentication, public capability acceptance or filesystem isolation. The native installer reuses this readiness check after copying its release components.
diff --git a/services/core/deploy/claude/README.md b/services/core/deploy/claude/README.md
index e81d42594..73447e9d3 100644
--- a/services/core/deploy/claude/README.md
+++ b/services/core/deploy/claude/README.md
@@ -43,7 +43,7 @@ Claude Code `2.1.269` reports both a request that got no HTTP response, such as
| Item | Value |
| --- | --- |
-| Base | Digest-pinned `node:22.23.1-bookworm-slim` with `ca-certificates`, `bash`, `git`, `python3`, `python3-pip` and `ripgrep` |
+| Base | The [shared Runtime base](../../../../docs/maintainers.md#runtime-images-and-helpers) |
| Programs | `/usr/local/bin/oac-daemon` and the SDK bundle at `/opt/claude-sdk` |
| User | UID/GID 1000 with `HOME=/home/runtime` |
| Environment | `OAC_RUNTIME_HOME=/home/runtime/.oac`, `OAC_RUNTIME_CLAUDE_SDK_NODE=/usr/local/bin/node`, `OAC_RUNTIME_CLAUDE_SDK_ENTRYPOINT=/opt/claude-sdk/dist/main.js`, `OAC_RUNTIME_WORKSPACE=/environment/workspace`, `OAC_RUNTIME_INITIALIZATION_DIRECTORY=/environment/initialization`, `OAC_RUNTIME_PACKAGE_DIRECTORY=/environment/packages`, `OAC_RUNTIME_STATE_DIRECTORY=/environment/runtime-state` |
diff --git a/services/core/deploy/codex/README.md b/services/core/deploy/codex/README.md
index 72c7d2af6..43e776ac9 100644
--- a/services/core/deploy/codex/README.md
+++ b/services/core/deploy/codex/README.md
@@ -1,6 +1,6 @@
# Codex Runtime
-The Codex adapter ([`agent/codex`](../../../../apps/daemon/internal/agent/codex)) runs the native Codex CLI through its app-server protocol inside the daemon. This page holds the Codex-specific adapter rules, the Codex Runtime image and the Docker sandbox settings that every Docker Runtime uses. [Harness protocol](../../../../contracts/agents-api/harness-onboarding.md) owns the obligations shared by all adapters.
+The Codex adapter ([`agent/codex`](../../../../apps/daemon/internal/agent/codex)) runs the native Codex CLI through its app-server protocol inside the daemon. This page holds the Codex-specific adapter rules, and the Codex Runtime image. [Harness protocol](../../../../contracts/agents-api/harness-onboarding.md) owns the obligations shared by all adapters.
Native tools run with the daemon user's permissions; the outer sandbox provides isolation ([Runtime and outer isolation](../../../../docs/concepts.md#runtime-and-outer-isolation)).
@@ -66,7 +66,7 @@ Codex `0.153.4` reports a provider HTTP 400 as `other` and puts the provider's e
| Item | Value |
| --- | --- |
-| Base | Digest-pinned `node:22.23.1-bookworm-slim` with `ca-certificates`, `bash`, `git`, `python3`, `python3-pip` and `ripgrep`, the same base and package layer as the Claude and MiniMax images |
+| Base | The [shared Runtime base](../../../../docs/maintainers.md#runtime-images-and-helpers) |
| Programs | `/usr/local/bin/oac-daemon`, `/usr/local/bin/codex` (mode 0555) and `/usr/local/codex-resources` |
| User | UID/GID 1000 with `HOME=/home/runtime` |
| Environment | `OAC_RUNTIME_HOME=/home/runtime/.oac`, `OAC_RUNTIME_CODEX_BIN=/usr/local/bin/codex`, `OAC_RUNTIME_WORKSPACE=/environment/workspace`, `OAC_RUNTIME_INITIALIZATION_DIRECTORY=/environment/initialization`, `OAC_RUNTIME_PACKAGE_DIRECTORY=/environment/packages`, `OAC_RUNTIME_STATE_DIRECTORY=/environment/runtime-state` |
diff --git a/services/core/deploy/mcode/README.md b/services/core/deploy/mcode/README.md
index c8c7f2cba..81ac8ea2a 100644
--- a/services/core/deploy/mcode/README.md
+++ b/services/core/deploy/mcode/README.md
@@ -45,7 +45,7 @@ In the workspace profile, the frozen installation's Skills are linked into the S
| Item | Value |
| --- | --- |
-| Base | Digest-pinned `node:22.23.1-bookworm-slim` with `ca-certificates`, `bash`, `git`, `python3`, `python3-pip` and `ripgrep` |
+| Base | The [shared Runtime base](../../../../docs/maintainers.md#runtime-images-and-helpers) |
| Programs | `/usr/local/bin/oac-daemon` and the companion at `/opt/mcode-harness` (native CLI at `native/cli.js`) |
| User | UID/GID 1000 with `HOME=/home/runtime` |
| Environment | `OAC_RUNTIME_HOME=/home/runtime/.oac`, `OAC_RUNTIME_MCODE_NODE`, `OAC_RUNTIME_MCODE_BIN`, `OAC_RUNTIME_MCODE_COMPANION`, `OAC_RUNTIME_WORKSPACE=/environment/workspace`, `OAC_RUNTIME_INITIALIZATION_DIRECTORY=/environment/initialization`, `OAC_RUNTIME_PACKAGE_DIRECTORY=/environment/packages`, `OAC_RUNTIME_STATE_DIRECTORY=/environment/runtime-state` |
diff --git a/services/core/tools/e2b-provider/README.md b/services/core/tools/e2b-provider/README.md
index b872e1f84..07243a1cb 100644
--- a/services/core/tools/e2b-provider/README.md
+++ b/services/core/tools/e2b-provider/README.md
@@ -34,7 +34,7 @@ The boundary has version 1. The request and credentials arrive on standard input
## Receipts and state directory
-`OAC_E2B_STATE_DIR` ([configuration](../../../../docs/configuration.md#appendix-core-environment-without-the-installer)) must already exist, be owned by the helper's user and grant no group or other access. Keep it on durable private storage across Core restarts. Its receipts hold SDK connection material, ownership identities and one-shot creation claims; they are not Core execution state. Losing the directory cannot authorize recreation or successful cleanup; never delete receipts after an uncertain call.
+The state directory is the fixed `/state/e2b` ([private Provider state](../../../../docs/configuration.md#compose-installations)). It must be owned by the helper's user and grant no group or other access, and it lives on durable private storage across Core restarts. Its receipts hold SDK connection material, ownership identities and one-shot creation claims; they are not Core execution state. Losing the directory cannot authorize recreation or successful cleanup; never delete receipts after an uncertain call.
A helper holds its allocation's lock until the SDK operation returns, even after Core's caller times out. Core tracks the helper's actual exit, and a credential change waits for running helpers without killing them. Helper exit never proves that a remote Create settled. Core serializes lifecycle requests per allocation and never replays Create.
diff --git a/services/core/tools/microsandbox-provider/README.md b/services/core/tools/microsandbox-provider/README.md
index a7cb64a30..e8dec91df 100644
--- a/services/core/tools/microsandbox-provider/README.md
+++ b/services/core/tools/microsandbox-provider/README.md
@@ -1,6 +1,6 @@
# microsandbox Sandbox Provider helper
-microsandbox runs each hosted Session in its own microVM on a Linux amd64 node with KVM, and it is the Sandbox Provider that supports idle suspension. Core forwards provider operations to the node over the [node protocol](../../../../contracts/agents-api/node-generation-protocol.md); the node's adapter ([`sandbox/microsandbox`](../../internal/sandbox/microsandbox)) runs this helper once per operation. The private helper wire version is 7; mismatches are rejected. The helper links the microsandbox Go SDK v0.7.8 with its FFI library, so Core and the node program stay CGO-free Go binaries. It implements the checkpoint operations of the provider-neutral `sandbox.SandboxProvider` with full snapshots. It has no daemon, lifecycle database, scheduler or network control plane.
+microsandbox runs each hosted Session in its own microVM on a Linux amd64 node with KVM. Core forwards provider operations to the node over the [node protocol](../../../../contracts/agents-api/node-generation-protocol.md); the node's adapter ([`sandbox/microsandbox`](../../internal/sandbox/microsandbox)) runs this helper once per operation. The private helper wire version is 7; mismatches are rejected. The helper links the microsandbox Go SDK v0.7.8 with its FFI library, so Core and the node program stay CGO-free Go binaries. It implements the checkpoint operations of the provider-neutral `sandbox.SandboxProvider` with full snapshots. It has no daemon, lifecycle database, scheduler or network control plane.
[Sandbox Provider protocol](../../../../docs/sandbox-provider.md) owns the provider contract. [Sandbox deployment](../../../../contracts/agents-api/sandbox-deployment.md) owns the resources and suspension policy; the [nodes guide](../../../../docs/getting-started/nodes.md) owns node installation, host requirements, the node's directories and its network policy.
diff --git a/website/README.md b/website/README.md
index 0b6a74f88..6fe19efa3 100644
--- a/website/README.md
+++ b/website/README.md
@@ -1,6 +1,6 @@
# OpenAgentCore website
-The website is the landing page plus the published documentation, built with [VitePress](https://vitepress.dev) and deployed to GitHub Pages. It reads the repository's existing `docs/`, `contracts/` and `docs.json` in place: no page is copied, moved or rewritten.
+The website is the landing page plus the published documentation, built with [VitePress](https://vitepress.dev) and deployed to GitHub Pages. It reads the repository's `docs/`, `contracts/` and `docs.json` in place: no page is copied, moved or rewritten.
## Run it
@@ -58,6 +58,4 @@ Pull request checks build under the published `/OpenAgentCore/` path. Output tes
## Maintain bilingual documentation
-English documentation owns technical facts. Translate each authored page in `docs/` and `contracts/agents-api/` into its mirrored `zh/` path in the same change. Keep code blocks, API identifiers and exact Web action names unchanged; translate explanatory prose and preserve the English heading ID with an explicit `{#id}` anchor. Resolve relative links from the Chinese file to the corresponding Chinese document or shared original asset. The Harness catalog generator produces both language editions. Extend other generators before translating their output; preserve generated regions in otherwise authored pages byte for byte, with a Chinese explanation before the region.
-
-Each Chinese frontmatter records `source` as the repository-relative English path and `source_hash` as its SHA-256 digest. Update that digest only after reconciling the complete translation with the source. `pnpm --dir website check-translations` checks coverage and freshness before the build. `docs.json` remains the single navigation order; titles are read from the selected language's source.
+The translation rules are in [Documentation](../AGENTS.md#documentation). Resolve relative links from the Chinese file to the corresponding Chinese document or shared original asset. The Harness catalog generator produces both language editions. Extend other generators before translating their output; preserve generated regions in otherwise authored pages byte for byte, with a Chinese explanation before the region. Update `source_hash` only after reconciling the complete translation with the source. `pnpm --dir website check-translations` checks coverage and freshness before the build. `docs.json` remains the single navigation order; titles are read from the selected language's source.