diff --git a/skills/configuring-compute/CHANGELOG.md b/skills/configuring-compute/CHANGELOG.md
index eb7151a..0583b7e 100644
--- a/skills/configuring-compute/CHANGELOG.md
+++ b/skills/configuring-compute/CHANGELOG.md
@@ -1,5 +1,12 @@
# Changelog
+## [1.1.0] - 2026-08-30
+
+- 改用 `ManageCompute` 与 `ComputeCredential(action='set')` 完成受治理的 Provider 启停、模型同步和密钥只写
+- 补充 `ControlDesireCoreGui` 的 control 模式回退及旧客户端升级路径
+- 禁止 Agent 绕过 renderer Origin/token 边界调用本机算力管理 HTTP 端点
+- 明确敏感输入在审批、事件、回执和会话持久化中的统一脱敏契约
+
## [1.0.3] - 2026-07-29
- 市场图标统一为纯白,确保各市场消费端视觉一致
diff --git a/skills/configuring-compute/SKILL.md b/skills/configuring-compute/SKILL.md
index cf23439..bee3e2b 100644
--- a/skills/configuring-compute/SKILL.md
+++ b/skills/configuring-compute/SKILL.md
@@ -1,12 +1,12 @@
---
name: configuring-compute
description: >-
- Configure compute providers (model API endpoints and API keys) for the user
- via the Agent Service HTTP API: create/update providers, write API keys
- (write-only), verify them, and reload the configuration. Use when the user
- asks to add or configure a model provider, set an API key, or fix compute
- configuration. 用户要求配置算力、添加模型供应商或设置 API Key 时使用。
-version: 1.0.3
+ Configure DesireCore compute providers through governed tools: inspect,
+ enable or disable providers, sync models, and set API keys without reading
+ them back. Use the dedicated DesireCore GUI tool for fields not yet covered
+ by ManageCompute. Never call renderer-only /api/compute management endpoints
+ from Bash or HttpRequest. 用户要求配置算力、同步模型或设置 API Key 时使用。
+version: 1.1.0
type: meta
risk_level: medium
status: enabled
@@ -18,7 +18,7 @@ tags:
- meta
metadata:
author: desirecore
- updated_at: '2026-07-29'
+ updated_at: '2026-08-30'
i18n:
default_locale: en-US
source_locale: zh-CN
@@ -29,22 +29,23 @@ metadata:
name: 配置算力
short_desc: 帮用户配置模型供应商与 API Key(密钥只写不读)
description: >-
- 通过 Agent Service HTTP API 为用户配置算力供应商(模型 API 端点与 API Key):
- 创建/更新 provider、写入 API Key(只写)、验证密钥、刷新配置。
- Use when 用户要求添加或配置模型供应商、设置 API Key、修复算力配置。
+ 通过受治理工具配置 DesireCore 算力:查看和启停 provider、同步模型、只写 API Key;
+ ManageCompute 尚未覆盖的字段使用专用 DesireCore GUI 工具。禁止从 Bash 或 HttpRequest
+ 调用仅供可信渲染器使用的 /api/compute 管理端点。
body: ./SKILL.zh-CN.md
translated_by: human
+ source_hash: sha256:b37d5baa849e88e9
en-US:
name: Configure Compute
short_desc: Configure model providers and API keys for the user (keys are write-only)
description: >-
- Configure compute providers (model API endpoints and API keys) for the user
- via the Agent Service HTTP API: create/update providers, write API keys
- (write-only), verify them, and reload the configuration. Use when the user
- asks to add or configure a model provider, set an API key, or fix compute configuration.
+ Configure DesireCore compute through governed tools: inspect and enable providers,
+ sync models, and write API keys without reading them back. Use the dedicated
+ DesireCore GUI tool for fields not covered by ManageCompute; never call renderer-only
+ /api/compute management endpoints from Bash or HttpRequest.
body: ./SKILL.md
translated_by: human
- source_hash: sha256:15e9247a2c27edf7
+ source_hash: sha256:b37d5baa849e88e9
market:
icon: >-
@@ -57,140 +58,76 @@ market:
# Configure Compute
-Help the user configure compute providers — model API endpoints and API keys —
-through the Agent Service HTTP API.
+Configure DesireCore compute through governed tools. Do not call the local
+`/api/compute/*` management endpoints from Bash, HttpRequest, or scripts: those
+endpoints intentionally require a trusted renderer Origin and instance token.
-## Security model (read this first, non-negotiable)
+## Security contract
-- **API keys are write-only.** You can create and overwrite keys; you can NEVER
- read an existing key back. There is no API that returns key plaintext to you,
- `GET /api/compute/config` returns masked values only, and the runtime blocks
- file reads of `secrets.json` (Read/Grep tools and shell commands alike).
-- **Do not try to work around this.** Never attempt to read
- `~/.desirecore/config/secrets.json`, never echo a key the user gave you back
- into chat more than necessary, never store keys anywhere except via
- `POST /api/compute/secrets`.
-- If the user asks "what is my current key", answer: keys cannot be read back;
- they can only be replaced. Point them to the provider settings UI, which has
- a user-only reveal control.
+- API keys are write-only for agents. Never read `secrets.json`, request
+ `ComputeCredential(action='get', raw=true)`, or repeat a key in tool results or chat.
+- Use `ComputeCredential(action='set')` to create or replace the key of an
+ existing user-managed provider. If the provider has no credential reference,
+ the tool creates and attaches one without returning the plaintext. This path
+ is approval-gated and audited; approval cards, tool events, receipts, and
+ session history redact the sensitive value. System-managed credentials are
+ not writable.
+- Pass a value to `ComputeCredential(action='set')` only when the user already supplied the
+ replacement key in the current request. If the agent must never handle the
+ plaintext, use the GUI to focus the password field, let the user type into it
+ directly, then continue the save flow. Never ask for the key in ordinary chat
+ or read the masked field back into the model.
+- `credentialMode=none` means the provider needs no key. Ollama is treated as
+ `none` even when an older config does not declare the field.
+- If the user asks for the current key, explain that the agent can replace it but
+ cannot read it back. The human-only UI reveal flow remains separate.
-## How to call the API
+## Workflow for an existing provider
-- Prefer the `Bash` tool with `curl`. The API base URL is already injected into
- the "Local API" section of the system prompt; reference it directly.
-- On Windows without Git Bash, use the `HttpRequest` tool with the same URLs.
+First confirm `ManageCompute` is available through the current tool catalog. If
+it is absent (for example on an older installed client), use the governed GUI
+workflow below for the whole task; do not fall back to local HTTP.
-## Workflow
+1. Call `ManageCompute(action='list')`. Record the exact provider ID,
+ enabled state, credential mode, status, and model count.
+2. If credential mode is `required` and the user supplied a new key in the
+ current request, call `ComputeCredential(action='set', providerId=..., value=...)`.
+ Do not echo the value. If the agent must not handle plaintext,
+ use the human-entry GUI flow below. For `none`, skip this step.
+3. Call `ManageCompute(action='set_enabled', providerId=..., enabled=true)`.
+4. Call `ManageCompute(action='sync_models', providerId=...)`. For Ollama
+ this discovers locally installed models; for supported cloud providers it
+ merges the built-in model list.
+5. Call `InspectModels` to verify the intended model is selectable. When the
+ user asked for a real test, run one short fixed-model conversation and verify
+ the run receipt names the requested provider/model.
-### 1. Inspect current configuration
+Mutating ManageCompute and ComputeCredential operations use the platform's
+approval policy. Do not add a second confirmation in prose unless information
+is missing or the user requested a destructive replacement.
-```bash
-curl -s $BASE/api/compute/config
-```
+## Fields not yet covered by ManageCompute
-Response contains `providers[]` where `apiKey` is a **masked display value**
-(first 4 chars + bullets) and `hasApiKey: boolean` tells you whether a key is
-configured. Use this to decide between creating a new provider and updating an
-existing one. Never treat the masked `apiKey` as a real key.
+Creating a new custom provider, changing base URL/API format, deleting a
+provider, and interactive key verification currently remain GUI operations.
+Use `ControlDesireCoreGui`, not a generic browser/CUA tool:
-### 2. Create a provider (if needed)
+1. `list_instances`, then `begin(instance=, mode=control, reason=...)` for
+ the intended DesireCore instance. The default `observe` mode is read-only and
+ cannot modify compute settings.
+2. Use the governed CDP methods to open Resources → Compute and make the change.
+3. Finish with `end`. If `ManageCompute` exists, call `ManageCompute(action='list')`; on
+ an older client, verify the saved state in the GUI instead. Call
+ `InspectModels` when available to confirm model selection.
-```bash
-curl -s -X POST $BASE/api/compute/providers \
- -H 'Content-Type: application/json' \
- -d '{
- "provider": "deepseek",
- "label": "DeepSeek",
- "baseUrl": "https://api.deepseek.com",
- "services": ["chat"],
- "apiFormat": "openai-completions",
- "priceCurrency": "CNY"
- }'
-```
+If the installed version includes `ControlDesireCoreGui` but reports that GUI
+control is disabled, the owner must set
+`config/security.json#desktopGuiControl.enabled=true` and restart that instance.
+If the tool is absent from the catalog entirely, the client is too old and must
+be upgraded; changing the switch cannot add a missing tool. Do not bypass the
+renderer HTTP boundary.
-Required fields: `provider`, `label`, `baseUrl`, `services`. The response
-returns the created provider with its generated `id` — keep it for later steps.
-Known provider presets and model lists are available via
-`GET /api/compute/pi-providers` and `GET /api/compute/pi-models/:provider`.
+## Completion report
-### 3. Set the API key (write-only)
-
-Ask the user for the key. Reuse the provider's existing `apiKeyRef` if set;
-otherwise generate one like `key-` and attach it to the provider:
-
-```bash
-# Write the secret (write-only endpoint; there is no GET counterpart)
-curl -s -X POST $BASE/api/compute/secrets \
- -H 'Content-Type: application/json' \
- -d '{"ref": "key-abc123", "value": ""}'
-
-# Attach the ref to the provider if it was not set yet
-curl -s -X PUT $BASE/api/compute/providers/ \
- -H 'Content-Type: application/json' \
- -d '{"apiKeyRef": "key-abc123"}'
-```
-
-### 4. Verify the key
-
-```bash
-curl -s -X POST $BASE/api/compute/verify-key \
- -H 'Content-Type: application/json' \
- -d '{"provider": "deepseek", "baseUrl": "https://api.deepseek.com", "apiKeyRef": "key-abc123", "apiFormat": "openai-completions"}'
-```
-
-Returns `{ valid, latencyMs, errorMessage?, suggestedBaseUrl? }`. If
-`suggestedBaseUrl` is present, offer to update the provider's `baseUrl`.
-
-### 5. Enable and populate models
-
-```bash
-curl -s -X PUT $BASE/api/compute/providers/ \
- -H 'Content-Type: application/json' -d '{"enabled": true}'
-
-# Optional: sync the model list from the built-in registry
-curl -s -X POST $BASE/api/compute/sync-models/
-```
-
-### 6. Reload so the UI reflects the change
-
-Always finish with:
-
-```bash
-curl -s -X POST $BASE/api/compute/reload
-```
-
-This re-validates the configuration and broadcasts a refresh event to the
-client UI. Report the returned `providerCount` / `enabledProviderCount` /
-`modelCount` to the user as confirmation.
-
-## Endpoint reference
-
-| Method | Path | Purpose |
-| ------ | ---- | ------- |
-| GET | `/api/compute/config` | Full config; `apiKey` masked + `hasApiKey` |
-| POST | `/api/compute/providers` | Create provider |
-| PUT | `/api/compute/providers/:id` | Patch provider (label/baseUrl/enabled/apiFormat/apiKeyRef/...) |
-| DELETE | `/api/compute/providers/:id` | Remove provider |
-| POST | `/api/compute/secrets` | Write key `{ref, value}` — **write-only** |
-| DELETE | `/api/compute/secrets/:ref` | Delete key |
-| POST | `/api/compute/verify-key` | Probe a key end-to-end |
-| POST | `/api/compute/sync-models/:id` | Sync model list from registry |
-| POST | `/api/compute/reload` | Re-validate config + broadcast UI refresh |
-| GET | `/api/compute/pi-providers` | Known provider presets |
-| GET | `/api/compute/pi-models/:provider` | Known models for a preset |
-
-## Error handling
-
-| Symptom | Cause | Action |
-| ------- | ----- | ------ |
-| 400 on create | Missing required field / unknown field | Fix the request body (schema is strict, `additionalProperties: false`) |
-| 404 on PUT | Wrong provider id | Re-list via GET config |
-| `valid: false` on verify | Wrong key / wrong baseUrl / wrong apiFormat | Show `errorMessage` to the user; try `suggestedBaseUrl` if present |
-| 403 anywhere | You tried a credential-gated endpoint (key reveal) | Stop — that endpoint is for the human user's UI only |
-
-## Confirmation etiquette
-
-- Before overwriting an existing key (`hasApiKey: true`), confirm with the user.
-- Before deleting a provider or key, confirm with the user.
-- After finishing, summarize what changed (provider, enabled state, model count)
- without repeating the key value.
+Report the provider ID, enabled state, synchronized model count, and model test
+result. Never include the key, its encrypted storage, or a plaintext fingerprint.
diff --git a/skills/configuring-compute/SKILL.zh-CN.md b/skills/configuring-compute/SKILL.zh-CN.md
index fddd3c2..8c1d765 100644
--- a/skills/configuring-compute/SKILL.zh-CN.md
+++ b/skills/configuring-compute/SKILL.zh-CN.md
@@ -1,130 +1,57 @@
# 配置算力
-通过 Agent Service HTTP API 帮用户配置算力供应商——模型 API 端点与 API Key。
+通过受治理工具配置 DesireCore 算力。禁止从 Bash、HttpRequest 或脚本调用本机
+`/api/compute/*` 管理端点;这些端点有意要求可信渲染器 Origin 和实例令牌。
-## 安全模型(先读这里,不可协商)
+## 安全契约
-- **API Key 只写不读。** 你可以创建和覆盖密钥,但**永远无法**读回已有密钥。
- 没有任何 API 会向你返回密钥明文:`GET /api/compute/config` 只返回掩码值,
- 运行时同时拦截对 `secrets.json` 的文件读取(Read/Grep 工具与 shell 命令一律拒绝)。
-- **不要尝试绕过。** 不要读取 `~/.desirecore/config/secrets.json`,不要在对话中
- 超出必要地回显用户提供的密钥,除 `POST /api/compute/secrets` 外不要在任何地方存放密钥。
-- 如果用户问「我现在的 key 是什么」,回答:密钥无法读回,只能替换;
- 可引导用户到供应商设置页,那里有仅限用户本人的明文查看控件。
+- 对 Agent 而言 API Key 只写不读。不得读取 `secrets.json`、请求
+ `ComputeCredential(action='get', raw=true)`,也不得在工具结果或聊天中复述密钥。
+- 使用 `ComputeCredential(action='set')` 为已有的用户自管 Provider 创建或替换密钥。若该
+ Provider 尚无凭据引用,工具会创建并挂载专属引用,但不会把明文返回给 Agent。此路径
+ 受审批、留审计;敏感值在审批卡、工具事件、回执和会话历史中统一脱敏,系统托管凭据
+ 不可由该操作覆盖。
+- 只有当用户已经在当前请求中主动提供了替换密钥时,才把该值传给
+ `ComputeCredential(action='set')`;若要求
+ Agent 从未接触明文,则用 GUI 聚焦密码输入框,让用户直接输入后再继续保存。不得让用户
+ 把密钥发到普通聊天,也不得把掩码字段读回模型。
+- `credentialMode=none` 表示 Provider 无需密钥。旧配置未声明时,Ollama 也按 `none` 处理。
+- 用户询问当前 Key 时,说明 Agent 只能替换、不能读回;人类 UI 的明文查看流程保持独立。
-## 如何调用 API
+## 已有 Provider 的工作流程
-- 优先使用 `Bash` 工具 + `curl`。API 基础地址已注入到 system prompt 的
- 「本机 API」小节,直接引用即可。
-- Windows 无 Git Bash 时,用 `HttpRequest` 工具调用相同 URL。
+先通过当前工具目录确认 `ManageCompute` 可用。若工具不存在(例如安装版客户端较旧),
+整项任务改走下方受治理 GUI 流程;不得回退到本地 HTTP。
-## 工作流程
+1. 调用 `ManageCompute(action='list')`,记录准确的 Provider ID、启用状态、凭据模式、状态和模型数。
+2. 若凭据模式为 `required` 且用户已在当前请求中提供新密钥,调用
+ `ComputeCredential(action='set', providerId=..., value=...)`;不得回显。若用户要求 Agent 不接触明文,改走
+ 下方 GUI 人工直填密码框。凭据模式为 `none` 时跳过。
+3. 调用 `ManageCompute(action='set_enabled', providerId=..., enabled=true)`。
+4. 调用 `ManageCompute(action='sync_models', providerId=...)`。Ollama 会发现本机已安装模型;
+ 支持的云 Provider 会合并内置模型清单。
+5. 调用 `InspectModels` 确认目标模型可选。若用户要求真实测试,发起一次简短固定模型对话,
+ 并核对运行回执中的 Provider/模型就是目标项。
-### 1. 查看当前配置
+ManageCompute 和 ComputeCredential 的变更操作会走平台审批策略。除非信息缺失或用户要求
+破坏性替换,不要在文字里再加一层重复确认。
-```bash
-curl -s $BASE/api/compute/config
-```
+## ManageCompute 尚未覆盖的字段
-响应中的 `providers[]` 里 `apiKey` 是**掩码展示值**(前 4 位 + 圆点),
-`hasApiKey: boolean` 表示是否已配置密钥。据此决定是新建 provider 还是更新现有的。
-掩码 `apiKey` 不是真实密钥,不要当作密钥使用。
+新建自定义 Provider、修改 Base URL/API 格式、删除 Provider、交互式验证密钥目前仍走 GUI。
+使用 `ControlDesireCoreGui`,不要使用通用浏览器/CUA 工具:
-### 2. 创建 provider(如需要)
+1. `list_instances`,再对目标 DesireCore 实例执行
+ `begin(instance=, mode=control, reason=...)`。默认 `observe` 只能读取界面,不能修改算力。
+2. 用受治理 CDP 方法进入“资源 → 算力”完成修改。
+3. 执行 `end`。若当前版本有 `ManageCompute`,再调用 `ManageCompute(action='list')`;旧客户端则在 GUI
+ 内复核保存状态。`InspectModels` 可用时再用它确认模型可选。
-```bash
-curl -s -X POST $BASE/api/compute/providers \
- -H 'Content-Type: application/json' \
- -d '{
- "provider": "deepseek",
- "label": "DeepSeek",
- "baseUrl": "https://api.deepseek.com",
- "services": ["chat"],
- "apiFormat": "openai-completions",
- "priceCurrency": "CNY"
- }'
-```
+若当前版本包含 `ControlDesireCoreGui`,但工具报告 GUI 控制已关闭,实例所有者需设置
+`config/security.json#desktopGuiControl.enabled=true` 并重启该实例。若工具目录里完全没有该工具,
+说明客户端版本过旧,必须升级;修改开关不能补出旧版本不存在的工具。不得绕过渲染器 HTTP 边界。
-必填字段:`provider`、`label`、`baseUrl`、`services`。响应返回创建的 provider
-及其生成的 `id`——后续步骤要用。已知供应商预设与模型列表可通过
-`GET /api/compute/pi-providers` 和 `GET /api/compute/pi-models/:provider` 获取。
+## 完成交付
-### 3. 设置 API Key(只写)
-
-向用户索取密钥。provider 已有 `apiKeyRef` 则复用;否则生成一个形如
-`key-<随机串>` 的引用名并挂到 provider 上:
-
-```bash
-# 写入密钥(只写端点,没有对应的 GET)
-curl -s -X POST $BASE/api/compute/secrets \
- -H 'Content-Type: application/json' \
- -d '{"ref": "key-abc123", "value": "<用户提供的API_KEY>"}'
-
-# 如果 provider 还没有 apiKeyRef,补挂上去
-curl -s -X PUT $BASE/api/compute/providers/ \
- -H 'Content-Type: application/json' \
- -d '{"apiKeyRef": "key-abc123"}'
-```
-
-### 4. 验证密钥
-
-```bash
-curl -s -X POST $BASE/api/compute/verify-key \
- -H 'Content-Type: application/json' \
- -d '{"provider": "deepseek", "baseUrl": "https://api.deepseek.com", "apiKeyRef": "key-abc123", "apiFormat": "openai-completions"}'
-```
-
-返回 `{ valid, latencyMs, errorMessage?, suggestedBaseUrl? }`。若返回
-`suggestedBaseUrl`,主动提议更新 provider 的 `baseUrl`。
-
-### 5. 启用并填充模型
-
-```bash
-curl -s -X PUT $BASE/api/compute/providers/ \
- -H 'Content-Type: application/json' -d '{"enabled": true}'
-
-# 可选:从内置注册表同步模型列表
-curl -s -X POST $BASE/api/compute/sync-models/
-```
-
-### 6. 刷新配置让 UI 生效
-
-收尾必做:
-
-```bash
-curl -s -X POST $BASE/api/compute/reload
-```
-
-该端点重新校验配置并向客户端 UI 广播刷新事件。把返回的 `providerCount` /
-`enabledProviderCount` / `modelCount` 报告给用户作为完成确认。
-
-## 端点速查
-
-| 方法 | 路径 | 用途 |
-| ---- | ---- | ---- |
-| GET | `/api/compute/config` | 完整配置;`apiKey` 为掩码 + `hasApiKey` |
-| POST | `/api/compute/providers` | 创建 provider |
-| PUT | `/api/compute/providers/:id` | 局部更新(label/baseUrl/enabled/apiFormat/apiKeyRef/...) |
-| DELETE | `/api/compute/providers/:id` | 删除 provider |
-| POST | `/api/compute/secrets` | 写入密钥 `{ref, value}` —— **只写** |
-| DELETE | `/api/compute/secrets/:ref` | 删除密钥 |
-| POST | `/api/compute/verify-key` | 端到端验证密钥 |
-| POST | `/api/compute/sync-models/:id` | 从注册表同步模型列表 |
-| POST | `/api/compute/reload` | 重新校验配置 + 广播 UI 刷新 |
-| GET | `/api/compute/pi-providers` | 已知供应商预设 |
-| GET | `/api/compute/pi-models/:provider` | 预设供应商的已知模型 |
-
-## 错误处理
-
-| 现象 | 原因 | 处理 |
-| ---- | ---- | ---- |
-| 创建时 400 | 缺必填字段 / 携带未知字段 | 修正请求体(schema 严格,`additionalProperties: false`) |
-| PUT 时 404 | provider id 错误 | 重新 GET config 拿列表 |
-| 验证 `valid: false` | 密钥错 / baseUrl 错 / apiFormat 错 | 把 `errorMessage` 转告用户;有 `suggestedBaseUrl` 则尝试 |
-| 任何端点 403 | 误触凭证门控端点(明文查看) | 立即停止——该端点仅供人类用户的 UI 使用 |
-
-## 确认礼仪
-
-- 覆盖已有密钥(`hasApiKey: true`)前,先向用户确认。
-- 删除 provider 或密钥前,先向用户确认。
-- 完成后向用户总结变更内容(provider、启用状态、模型数量),不要复述密钥值。
+报告 Provider ID、启用状态、同步后的模型数量和真实模型测试结果。不要包含密钥、加密存储内容
+或明文指纹。