feat: add aipod spec Artificer assembly

This commit is contained in:
Codex
2026-06-10 17:46:45 +08:00
parent 45df61bd02
commit 6989dc18ef
22 changed files with 2103 additions and 56 deletions
+125
View File
@@ -0,0 +1,125 @@
# v0.1 AipodSpec 规格
`AipodSpec` 是 AgentRun `v0.1` 的声明式 agent 装配规格。它把已有的 `backendProfile``executionPolicy.secretScope``ResourceBundleRef.kind="gitbundle"`、Queue task 和 Session turn 装配入口集中到 YAML 文件中,避免把某个 agent 的模型、SecretRef、gitbundle、skill 或 tool 写死在 manager、runner 或 CLI 源码里。
## 设计边界
- `AipodSpec` 只声明装配意图,不保存 API key、SSH private key、token、`auth.json``config.toml` 或其他 Secret 明文。
- manager 通过 `/api/v1/aipod-specs` 对 YAML 做增删改查;默认目录为仓库 `config/aipods/`,可用 `AGENTRUN_AIPOD_SPEC_DIR` 覆盖。
- CLI 通过 `aipod-specs list|show|render|apply|delete` 管理规格,通过 `queue submit --aipod <name>``sessions turn --aipod <name>` 使用规格。
- `render` 只把规格展开为标准 Queue task / Session turn 输入,输出必须脱敏,只显示 SecretRef 名称、key、projection、gitbundle 摘要和 `valuesPrinted=false`
- `AipodSpec` 不引入第二套 scheduler、runner、backend adapter 或 Code Queue;最终执行仍走 AgentRun Queue、Sessions、runner Job 和 Codex app-server stdio backend。
## YAML 结构
最小结构:
```yaml
apiVersion: agentrun.pikastech.local/v0.1
kind: AipodSpec
metadata:
name: Artificer
spec:
backendProfile: sub2api
executionPolicy:
sandbox: workspace-write
approval: never
timeoutMs: 1800000
network: enabled
secretScope:
allowCredentialEcho: false
providerCredentials:
- profile: sub2api
secretRef:
name: agentrun-v01-provider-sub2api
keys: [auth.json, config.toml]
resourceBundleRef:
kind: gitbundle
repoUrl: git@github.com:pikasTech/unidesk.git
ref: master
bundles:
- subpath: .agents/skills
targetPath: .agents/skills
```
字段规则:
- `apiVersion` 固定为 `agentrun.pikastech.local/v0.1``kind` 固定为 `AipodSpec`
- `metadata.name` 是 CLI/API 查找名,允许大小写,但文件落盘名会归一为安全 YAML 文件名。
- `spec.backendProfile` 使用 AgentRun 已注册或动态的 Codex-compatible profile slug,例如 `codex``deepseek``minimax-m3``dsflash-go``sub2api`
- `spec.model.model` 会展开为 command payload 的 `model` 字段;完整 `spec.model` 同时进入 `payload.modelConfig`,用于保留 `reasoningEffort` 等声明但不作为 Secret 输出。
- `spec.executionPolicy` 复用 run 的执行策略校验,且必须恰好包含一个匹配 `backendProfile` 的 provider credential SecretRef。
- `spec.resourceBundleRef` 复用 RuntimeAssembly 的 gitbundle 规则,可为 `null`,但需要注入 skill/tool 时必须使用 gitbundle。
- `spec.payloadDefaults` 与 CLI render 输入合并;用户 prompt 通过 `--prompt``--prompt-file``--prompt-stdin` 覆盖或补充。
## Artificer 默认规格
仓库内置 `config/aipods/artificer.yaml`,名称为 `Artificer`。它的长期目标是承接 UniDesk 分布式开发任务:
- 使用 `backendProfile=sub2api`,模型声明为 `gpt-5.5`reasoning effort 为 `xhigh`
- 通过 provider SecretRef `agentrun-v01-provider-sub2api` 获取 `auth.json``config.toml`
- 通过 `toolCredentials` 获取 UniDesk SSH 透传 token`agentrun-v01-tool-unidesk-ssh` -> env `UNIDESK_SSH_CLIENT_TOKEN`
- 通过 `toolCredentials` 获取 GitHub SSH 凭据:`agentrun-v01-tool-github-ssh` -> volume `/home/agentrun/.ssh`
- 通过 gitbundle 装配 UniDesk repo 中的 `unidesk-*` skills、AgentRun repo 中的 `tools/trans``tools/tran``tools/apply_patch`,以及 `agent_skills` repo 中的 `dad-dev``cli-spec``docs-spec``git-spec`
- 通过 `requiredSkills[]` 在 runner 启动 backend 前校验 `dad-dev` 与 UniDesk 关键 skills 已被 materialize;缺失时必须 `required-skill-unavailable`,不得使用模型默认 skill 猜测。
## Git mirror
`resourceBundleRef.gitMirror` 用于把 GitHub repo URL 改写为 G14 git mirror read URL,提高 runner checkout 的稳定性和速度。
规则:
- `enabled` 缺省为 `true`;显式 `false` 时不改写。
- `baseUrl` 必须是无 credentials、query、fragment 的 HTTP(S) URL;未设置时 runner 使用 `AGENTRUN_GIT_MIRROR_BASE_URL`,再缺省为 `http://git-mirror-http.devops-infra.svc.cluster.local`
- 支持 `git@github.com:owner/repo.git``ssh://git@github.com/owner/repo.git``ssh://git@ssh.github.com:443/owner/repo.git``https://github.com/owner/repo.git`
- 非 GitHub URL 不改写,仍按原 `repoUrl` fetch。
- materialization event 必须输出 `repoUrl``fetchRepoUrl``mirrorUsed``mirrorBaseUrl`、requested ref/commit 和实际 commit;不得输出 credential 值。
## Tool credential projection
`toolCredentials[]` 支持两类 projection
- `env`:把 Secret key 作为环境变量注入 runner,例如 `UNIDESK_SSH_CLIENT_TOKEN`
- `volume`:把 Secret keys 作为只读文件挂载到 `/home/agentrun/` 下,例如 GitHub SSH 的 `/home/agentrun/.ssh`
约束:
- `unidesk-ssh` 必须使用 env projection,且 env/key 都必须是 `UNIDESK_SSH_CLIENT_TOKEN`
- volume projection 的 `mountPath` 必须位于 `/home/agentrun/` 下,不能包含 `..`
- runner Job response、dry-run manifest、event 和日志只能显示 SecretRef 名称、key、projection kind 与 mount path,不得显示 Secret value。
## API 与 CLI
REST API
- `GET /api/v1/aipod-specs`:列出可用规格。
- `POST /api/v1/aipod-specs`:从 `{ yaml }``{ spec }` 创建/更新规格。
- `GET /api/v1/aipod-specs/:name`:查看规格和摘要。
- `PUT /api/v1/aipod-specs/:name`:按 URL 名称更新规格,URL name 必须匹配 `metadata.name`
- `DELETE /api/v1/aipod-specs/:name`:删除规格文件。
- `POST /api/v1/aipod-specs/:name/render`:把规格和本次输入展开为 Queue task。
Artificer 依赖的 GitHub SSH Secret 由 `tool-credentials set-github-ssh` 单独 bootstrap。`AipodSpec` 只引用 SecretRef,不读取或保存 SSH private key。
CLI
```bash
./scripts/agentrun aipod-specs list
./scripts/agentrun aipod-specs show Artificer
./scripts/agentrun aipod-specs render Artificer --prompt-stdin
./scripts/agentrun aipod-specs apply --yaml-stdin
./scripts/agentrun aipod-specs delete Artificer
./scripts/agentrun queue submit --aipod Artificer --prompt-stdin --idempotency-key <key>
./scripts/agentrun sessions turn --aipod Artificer --prompt-stdin
./scripts/agentrun tool-credentials set-github-ssh --private-key-file <id_ed25519> --known-hosts-file <known_hosts> [--config-file <ssh_config>]
```
所有 mutating CLI 必须短返回 JSON`--dry-run` 只输出 mutation plan 和确认命令,不写 manager。
## 测试规格
- A1`config/aipods/artificer.yaml` 能被 manager list/show/renderrender 结果包含 `backendProfile=sub2api``model=gpt-5.5``reasoningEffort=xhigh`、provider SecretRef、UniDesk SSH env projection、GitHub SSH volume projection、AgentRun runner tools gitbundle 和 gitbundle requiredSkills。
- A2`queue submit --aipod Artificer --dry-run` 输出标准 `queue-submit-plan`,且 `idempotencyKey`、prompt 与 metadata 被保留。
- A3GitHub URL 在启用 `gitMirror` 后改写到 mirror base URL;非 GitHub URL 不改写。
- A4runner Job dry-run 支持 tool credential volume mount,并且 response/manifest/event 不泄漏 Secret 明文。
- A5`bun run check``bun run self-test` 必须覆盖 A1-A4。
+15
View File
@@ -54,12 +54,16 @@ CLI 官方 TypeScript 入口固定为 `scripts/agentrun-cli.ts`。在 G14 非交
./scripts/agentrun provider-profiles remove <profile>
./scripts/agentrun provider-profiles set-key <profile> --key-stdin
./scripts/agentrun provider-profiles validate <profile> [--wait] [--timeout-ms <ms>]
./scripts/agentrun tool-credentials list
./scripts/agentrun tool-credentials show github-ssh|unidesk-ssh
./scripts/agentrun tool-credentials set-github-ssh --private-key-file <id_ed25519> --known-hosts-file <known_hosts> [--config-file <ssh_config>] [--dry-run]
./scripts/agentrun backends list
./scripts/agentrun server start [--port <port>] [--host <host>] [--foreground]
./scripts/agentrun server status [--port <port>]
./scripts/agentrun server logs [--port <port>] [--tail-bytes <bytes>] [--log-file <path>]
./scripts/agentrun server stop [--port <port>]
./scripts/agentrun queue submit --json-stdin|--json-file <task.json> [--dry-run]
./scripts/agentrun queue submit --aipod <name> [--prompt-stdin|--prompt-file <file>|--prompt <text>] [--idempotency-key <key>] [--dry-run]
./scripts/agentrun queue list [--queue <queue>] [--state <state>] [--cursor <cursor>] [--limit <limit>] [--full|--raw]
./scripts/agentrun queue show <taskId> [--full|--raw]
./scripts/agentrun queue stats [--queue <queue>]
@@ -71,11 +75,17 @@ CLI 官方 TypeScript 入口固定为 `scripts/agentrun-cli.ts`。在 G14 非交
./scripts/agentrun sessions ps [--state default|running|unread|terminal|idle|all] [--profile codex|deepseek|minimax-m3|dsflash-go|M3] [--reader-id <reader>]
./scripts/agentrun sessions show <sessionId> [--reader-id <reader>]
./scripts/agentrun sessions turn [sessionId] [--json-stdin|--json-file <run-base.json>] [--prompt-stdin|--prompt-file <file>|--prompt <text>] [--profile codex|deepseek|minimax-m3|dsflash-go|M3] [--runner-json-stdin|--runner-json-file <job.json>] [--no-runner-job]
./scripts/agentrun sessions turn [sessionId] --aipod <name> [--prompt-stdin|--prompt-file <file>|--prompt <text>] [--runner-json-stdin|--runner-json-file <job.json>] [--no-runner-job]
./scripts/agentrun sessions steer <sessionId> [--prompt-stdin|--prompt-file <file>|--prompt <text>]
./scripts/agentrun sessions cancel <sessionId> [--reason <text>]
./scripts/agentrun sessions trace <sessionId> [--after-seq <n>] [--limit <limit>] [--run-id <runId>] [--include-output] [--seq <n>|--event-id <id>|--item-id <id>] [--detail-scan-pages <n>] [--full|--raw]
./scripts/agentrun sessions output <sessionId> [--after-seq <n>] [--limit <limit>] [--run-id <runId>] [--include-output] [--seq <n>|--event-id <id>|--item-id <id>] [--detail-scan-pages <n>] [--full|--raw]
./scripts/agentrun sessions read <sessionId> [--reader-id <reader>]
./scripts/agentrun aipod-specs list
./scripts/agentrun aipod-specs show <name>
./scripts/agentrun aipod-specs render <name> [--json-stdin|--json-file <input.json>] [--prompt-stdin|--prompt-file <file>|--prompt <text>]
./scripts/agentrun aipod-specs apply [name] --yaml-stdin|--yaml-file <spec.yaml> [--dry-run]
./scripts/agentrun aipod-specs delete <name>
```
具体参数可以在实现时按代码结构微调,但行为必须保持:
@@ -83,6 +93,8 @@ CLI 官方 TypeScript 入口固定为 `scripts/agentrun-cli.ts`。在 G14 非交
- 创建类命令返回 `runId``commandId`、status 和下一步 poll command。
- `runner start` 返回 attemptId、job/process identity、logPath 和后续 status/events 命令。
- `runner jobs` / `runner job-status` 返回 manager 持久化的 runner Job 最小状态摘要,包括 attemptId、runnerId、namespace、jobName、phase、terminalStatus、logPath、retention 和 redacted Kubernetes identity;业务方不需要直连 Kubernetes 才能定位当前 attempt。
- `aipod-specs render``queue submit --aipod` 必须调用同一 manager `/api/v1/aipod-specs/:name/render` 路径,把 YAML 展开为标准 Queue taskCLI 不得在本地复制一套 render 逻辑。
- `queue submit --aipod <name>` 只接受本次任务输入(prompt、idempotencyKey、tenant/project/queue/lane/provider 覆盖等),模型、provider credential、tool credential、gitbundle 和 requiredSkills 由 [spec-v01-aipod-spec.md](spec-v01-aipod-spec.md) 定义。
- 查询类命令返回当前 state、terminal_status、failureKind、event cursor 或 logPath。
- `events` 默认分页且有界,必须支持 `afterSeq``limit`;默认输出保持 manager raw JSON。
- `events --summary` 返回低噪声 JSON summary,单条至少包含 `seq``type``method``status``command``text``exitCode``durationMs``outputTruncated``outputBytes``outputSummary``summary`;summary 文本必须压缩换行并继续沿用 redaction,不能泄漏 Secret/env value。
@@ -94,6 +106,8 @@ CLI 官方 TypeScript 入口固定为 `scripts/agentrun-cli.ts`。在 G14 非交
- `server stop` 必须按 pidFile 与端口进程清理本地 manager,并返回 before/after 状态;不得要求人工用 `ps/kill/ss` 组合命令清理常见临时服务。
- `secrets codex render --dry-run` 返回 Codex stdio profile Secret 创建计划、输入文件 bytes/hash、SecretRef、manifest 摘要和 apply 命令形状;`--profile codex` 默认 Secret name 为 `agentrun-v01-provider-codex``--profile deepseek` 默认 Secret name 为 `agentrun-v01-provider-deepseek``--profile minimax-m3` 默认 Secret name 为 `agentrun-v01-provider-minimax-m3``--profile dsflash-go` 默认 Secret name 为 `agentrun-v01-provider-dsflash-go` 并包含 `model-catalog.json`;它不得输出 Secret value 或执行 Kubernetes 写操作。
- `provider-profiles` 命令族调用 manager REST 管理 API,覆盖 profile status、删除、API Key 写入和 canary 验证。`set-key --key-stdin` 从 stdin 读取 API Key,响应只显示 SecretRef、resourceVersion、hash 后缀和 failureKind;不得输出 key、Codex auth/config 或 Secret data。
- `tool-credentials list|show` 调用 manager REST 读取固定 tool credential 状态,只显示 SecretRef、key presence 和 hash 后缀;不得输出 Secret data。
- `tool-credentials set-github-ssh` 是 GitHub SSH runtime Secret 的受控 bootstrap 入口;输入只能来自本地文件,CLI/manager response 只能显示 bytes、hash suffix、SecretRef 和 `valuesPrinted=false`,不得输出 private key、known_hosts 或 ssh config 内容。
- `backends list` 必须显示 `codex``deepseek``minimax-m3``dsflash-go` profile 的 backendKind、protocol、transport、command、requiredSecretKeys 和状态;`dsflash-go``requiredSecretKeys` 必须包含 `model-catalog.json`;已配置的动态 provider profile(例如 `hy`)必须同样可见,并带动态 discovery 状态;不得因为某个 provider Secret 尚未配置就隐藏 capability。
- `queue submit/read/cancel/dispatch/refresh --dry-run` 必须只返回 non-mutating plan,固定 `dryRun=true``mutation=false`,不得创建 task、mark read、cancel、dispatch、refresh 或启动 runner job。
- `queue dispatch` 是 Q2 的受控手动调度入口,只对单个 task 显式创建 attempt 和 Core run/command/runner job;不得伪装成自动 scheduler;带 `--dry-run` 时只读取 task 并展示将要 POST 的路径和有界 request 摘要。
@@ -162,5 +176,6 @@ CLI 官方 TypeScript 入口固定为 `scripts/agentrun-cli.ts`。在 G14 非交
| CLI 测试规格 | 已定义/已验证主闭环 | 综合联调见 [spec-v01-validation.md](spec-v01-validation.md);每次发布仍按手动交互验收复跑。 |
| `deepseek` profile CLI | 已实现/已通过主闭环 | `secrets codex render --profile deepseek``backends list``runner start --backend``runner job` 和 JSON 错误可见性已实现;真实 CLI/RESTful 联调已通过 `codex -> deepseek -> codex` 切换主闭环。 |
| Provider profile 管理 CLI | 已实现 | `provider-profiles list/show/remove/set-key/validate` 调用 manager REST API,用于 HWLAB 委托和 operator 验收;输出必须持续保持 Secret/API Key 脱敏。 |
| Tool credential 管理 CLI | 已实现 | `tool-credentials list/show/set-github-ssh` 调用 manager REST API,用于 Artificer GitHub SSH Secret bootstrap;输出只包含 SecretRef、key presence、bytes 和 hash suffix。 |
| `minimax-m3` profile CLI | 已实现/待真实主闭环 | `secrets codex render --profile minimax-m3``backends list``runner start --backend``runner job``sessions turn --profile minimax-m3|M3` 和 JSON 错误可见性已实现;真实 CLI/RESTful 联调需要按 `codex -> deepseek -> minimax-m3 -> codex` 手动验收。 |
| `dsflash-go` profile CLI | 已实现/待真实主闭环 | `secrets codex render --profile dsflash-go --model-catalog-file``backends list``runner start --backend``runner job``sessions turn --profile dsflash-go` 和 JSON 错误可见性已实现;真实 CLI/RESTful 联调需要按 `codex -> deepseek -> minimax-m3 -> dsflash-go -> codex` 手动验收,并确认 compact 404 分类为 `provider-compact-unsupported`。 |
@@ -31,6 +31,7 @@
- `spec-v01-postgres.md`Postgres durable store、schema migration 和 DB SecretRef。
- `spec-v01-secret-distribution.md`Code Agent provider credential、Postgres DSN 和运行时 Secret 分发。
- `spec-v01-runtime-assembly.md`runner/backend 启动前的四要素 RuntimeAssembly 装配模型;其他 spec 只交叉引用,不重复定义四要素字段。
- `spec-v01-aipod-spec.md`:声明式 AipodSpec YAML、Artificer 默认规格、git mirror、tool credential projection、manager API 和 `--aipod` CLI。
- `spec-v01-queue.md`AgentRun Queue 直接吸收 UniDesk Code Queue 的 RESTful API、CLI、数据模型、Session 分层和验收规格。
- `spec-v01-validation.md`:两层验证模型、自测试和综合联调验收。
- `spec-v01-agentrun-mgr.md`manager REST API、tenant boundary、runner claim、event/status authority。
@@ -63,6 +64,7 @@
- 服务总览规格:[spec-v01-services.md](spec-v01-services.md)。
- Postgres durable store 规格:[spec-v01-postgres.md](spec-v01-postgres.md)。
- Secret/provider credential 分发规格:[spec-v01-secret-distribution.md](spec-v01-secret-distribution.md)。
- AipodSpec 声明式装配规格:[spec-v01-aipod-spec.md](spec-v01-aipod-spec.md)。
- Queue 吸收规格:[spec-v01-queue.md](spec-v01-queue.md)。
- 验证模型规格:[spec-v01-validation.md](spec-v01-validation.md)。
- Manager 服务规格:[spec-v01-agentrun-mgr.md](spec-v01-agentrun-mgr.md)。
@@ -75,7 +77,7 @@
## 验收标准
- `AGENTS.md` 索引本文和其他 `spec-v01-*` 规格。
- `docs/reference/` 中存在 `spec-v01-documentation-governance.md``spec-v01-services.md``spec-v01-cicd.md``spec-v01-postgres.md``spec-v01-secret-distribution.md``spec-v01-runtime-assembly.md``spec-v01-queue.md``spec-v01-validation.md``spec-v01-agentrun-mgr.md``spec-v01-agentrun-runner.md``spec-v01-backend-adapter.md``spec-v01-backend-codex.md``spec-v01-cli.md``spec-v01-scheduler.md`
- `docs/reference/` 中存在 `spec-v01-documentation-governance.md``spec-v01-services.md``spec-v01-cicd.md``spec-v01-postgres.md``spec-v01-secret-distribution.md``spec-v01-runtime-assembly.md``spec-v01-aipod-spec.md``spec-v01-queue.md``spec-v01-validation.md``spec-v01-agentrun-mgr.md``spec-v01-agentrun-runner.md``spec-v01-backend-adapter.md``spec-v01-backend-codex.md``spec-v01-cli.md``spec-v01-scheduler.md`
- `AGENTS.md``docs/reference/` 不得把旧 `agentrun_dev``agentrun_prod``G14:/root/agentrun``/root/agentrun` 写成当前 source worktree、namespace、发布目标或验收目标;只允许在废弃说明和历史背景中提及。
- `docs/` 根目录不新增临时 Markdown 报告或 JSON dump。
- 仓库根目录不存在 `TEST.md`;测试场景维护在对应 `spec-v01-*.md` 的“测试规格”小节。
+19 -4
View File
@@ -53,7 +53,7 @@ P0 最小 JSON 形态:
| Tool credential | `executionPolicy.secretScope.toolCredentials[]` | 由 runner 按 tool scope 投影为文件或 env,并只暴露给当前 run/command 允许的工具 | 用于 GitHub PR、issue、UniDesk SSH passthrough、artifact registry 等 agent shell 工具能力;不等同于 AgentRun integration,不触发 GitHub sink/OA/Event 之类外部动作记录。 |
| Short-lived execution context | runner-job `transientEnv` | 单次 Job envresponse/dry-run/event 只显示 name/hash | 只用于业务 dispatcher 生成的短期或 owner-scoped runtime context,以及 manager 受控默认值补齐的非敏感服务地址;不得承载 provider credential、GitHub token、UniDesk SSH client token 或长期 SSH key。 |
`toolCredentials` 是装配 SPEC 中的受控扩展槽位,用于把 agent 运行时需要的外部工具授权从“临时 env”收敛为 SecretRef。`v0.1` 支持 GitHub PR/issue 与 UniDesk SSH passthrough 所需的最小 env projection例如:
`toolCredentials` 是装配 SPEC 中的受控扩展槽位,用于把 agent 运行时需要的外部工具授权从“临时 env”收敛为 SecretRef。`v0.1` 支持 env projection 与只读 volume projectionenv 用于 `GH_TOKEN``UNIDESK_SSH_CLIENT_TOKEN` 这类单 key 工具变量,volume 用于 GitHub SSH 目录等文件型凭据。例如:
```json
{
@@ -77,6 +77,16 @@ P0 最小 JSON 形态:
"keys": ["UNIDESK_SSH_CLIENT_TOKEN"]
},
"projection": { "kind": "env", "envName": "UNIDESK_SSH_CLIENT_TOKEN" }
},
{
"tool": "github",
"purpose": "github-ssh",
"secretRef": {
"namespace": "agentrun-v01",
"name": "agentrun-v01-tool-github-ssh",
"keys": ["id_ed25519", "known_hosts", "config"]
},
"projection": { "kind": "volume", "mountPath": "/home/agentrun/.ssh" }
}
]
}
@@ -90,6 +100,8 @@ P0 最小 JSON 形态:
- dry-run manifest、runner job record、event、trace、日志和 CLI 输出只能显示 tool、purpose、SecretRef 名称/key、projection kind 和 `valuesPrinted=false`
- GitHub PR 能力属于 agent shell/tool 运行能力,不是 AgentRun Queue integration,也不要求新增 GitHub sink、OA sink、notification 或 Event Flow。
- `tool=unidesk-ssh` 只允许投影 Secret key `UNIDESK_SSH_CLIENT_TOKEN` 到同名 env。该 token 是 UniDesk frontend `/ws/ssh` 的 scoped client tokenroute allowlist 由 UniDesk frontend 配置约束;它不得携带 provider token、主 server SSH key 或完整 frontend 登录态。
- `projection.kind="volume"` 只能挂载到 `/home/agentrun/` 下的路径,不能包含 `..`runner Job 必须用只读 Secret volume mount,不得把文件型凭据复制进 event、logs 或 Queue task。
- GitHub SSH 能力应使用文件型 SecretRef,例如 `id_ed25519``known_hosts``config` 投影到 `/home/agentrun/.ssh`;它仍只属于当前 run/command 的工具能力,不是 manager 自身 GitHub 写入权限。
- `tool=unidesk-ssh` 所需的 UniDesk endpoint 不属于 SecretRef。runner-job env 必须具备 `UNIDESK_MAIN_SERVER_IP``UNIDESK_MAIN_SERVER_HOST``UNIDESK_FRONTEND_URL` 三者之一;调用方可以通过 `transientEnv` 显式传入,若未传入,manager 可以从受控默认配置自动补齐非敏感 endpoint env。
- manager 自动补齐 endpoint 时只追加 env name/value 到本次 runner Job,不把 value 写入 run、command、event 或 result 明文;trace/response 只能显示 env name、count、hash 和 `valuesPrinted=false`。若 run 请求了 `tool=unidesk-ssh`,但调用方和 manager 默认都没有 endpointrunner-job 创建必须在装配阶段返回结构化 `schema-invalid`,不能让 agent 进入 turn 后靠 prompt 猜 endpoint。
- 发现 agent shell 缺少 `gh``curl`、UniDesk SSH passthrough token 或其他工具凭证时,只能记录为装配能力缺口;不得用 `transientEnv` 或 issue 评论里的明文 token 绕过。
@@ -162,6 +174,7 @@ HWLAB Workbench 的 project/workspace 不属于 RuntimeAssembly 四要素,也
- P0 固定 `kind="gitbundle"`,输入只依赖 Git repo/ref 与 `bundles[]`runner 从 `resourceBundleRef.ref`、run 的 `workspaceRef.branch``HEAD` 解析实际 commit,再用该 materialized commit 作为内容身份。
- `commitId` 是可选 pin 或历史请求 hint;提供时必须是 full commit sha,但 HWLAB gitbundle 默认不得依赖 cloud-api/CI/CD rollout 注入的 commitId。
- `bundles[]` 每一项只允许 `{ name?, repoUrl?, ref?, commitId?, subpath, target_path }`;缺省 repo/ref/commit 继承顶层解析结果。
- `gitMirror` 可把 GitHub repo URL 改写到受控 mirror read URLevent/result 必须同时记录原始 `repoUrl`、实际 `fetchRepoUrl``mirrorUsed``mirrorBaseUrl`,不能只显示理论 repo。
- `subpath` 必须留在 checkout 内,`target_path` 必须留在 runner workspace 内;runner 按 `subpath -> target_path` 复制文件或目录。
- `credentialRef` 只用于拉取私有 Git repo,不等同于 backend API KEY。
- 不支持上传文件、对象存储 artifact、任意 ConfigMap 文件袋、inline seed 或旧字段;旧 `toolAliases``skillRefs``workspaceFiles``subdir``sparsePaths` 输入必须直接 schema-invalid。
@@ -172,7 +185,7 @@ HWLAB Workbench 的 project/workspace 不属于 RuntimeAssembly 四要素,也
runner 对 workspace `tools/` 做统一装配:顶层带 shebang 的脚本会被 `chmod +x``tools/` 会暴露到 `PATH`。如果 runtime 配置了单独的 `AGENTRUN_RESOURCE_BIN_PATH`,runner 只能在该目录写入执行原始 workspace tool 的 shim,不能复制 tool 文件导致 `dirname "$0"`、相对 import 或辅助源码解析到 bin 目录。非 shebang 文件是随 bundle 复制的源码、测试或辅助文件,不作为可执行工具发现,也不触发 schema-invalid。短命令名称来自 repo 内真实文件,例如 `tools/hwpod`repo tool 本身承担业务 wrapper 语义。
AgentRun 自身仓库必须提供 `tools/tran``tools/trans`,用于承接 UniDesk frontend `/ws/ssh` 的 scoped client-token 透传。runner 只通过 `executionPolicy.secretScope.toolCredentials[]` 投影 `UNIDESK_SSH_CLIENT_TOKEN`,并通过调用方 `transientEnv` 或 manager 受控默认值注入非敏感 `UNIDESK_MAIN_SERVER_IP``UNIDESK_MAIN_SERVER_HOST``UNIDESK_FRONTEND_URL`;工具不得读取 provider token、主 server SSH key 或完整 frontend 登录态。`tran --help` 必须输出 JSON,并列出当前支持的最小开发面:host/host workspace `script``argv`、普通 ssh-like 命令、`k3s kubectl``k3s script`k3s workload `argv/script`。未实现的 `apply-patch``upload``download` 和 Windows route 必须显式 `unsupported-operation`,不能静默改走不受控 shell 拼接或 token fallback。
AgentRun 自身仓库必须提供 `tools/tran``tools/trans``tools/apply_patch`,用于承接 UniDesk frontend `/ws/ssh` 的 scoped client-token 透传。runner 只通过 `executionPolicy.secretScope.toolCredentials[]` 投影 `UNIDESK_SSH_CLIENT_TOKEN`,并通过调用方 `transientEnv` 或 manager 受控默认值注入非敏感 `UNIDESK_MAIN_SERVER_IP``UNIDESK_MAIN_SERVER_HOST``UNIDESK_FRONTEND_URL`;工具不得读取 provider token、主 server SSH key 或完整 frontend 登录态。`tran --help` 必须输出 JSON,并列出当前支持的最小开发面:host/host workspace `script``argv`、普通 ssh-like 命令、host workspace `apply-patch``k3s kubectl``k3s script`k3s workload `argv/script` 和 k3s workload `apply-patch`。runner 侧 `apply-patch` 只把 stdin patch 和相邻 `tools/apply_patch` helper 传到目标 route 执行,不接触或回显 Secret 值;`upload``download` 和 Windows route 未实现时必须显式 `unsupported-operation`,不能静默改走不受控 shell 拼接或 token fallback。
#### promptRefs
@@ -243,6 +256,7 @@ skill 只来自 gitbundle 复制进 workspace 的 `.agents/skills/<name>/SKILL.m
- GitHub PR、issue、UniDesk SSH passthrough 或其他 shell/tool 授权只能通过 `executionPolicy.secretScope.toolCredentials[]` 的 SecretRef 装配进入 runner。
- CLI、Queue task、runner job response、dry-run manifest、event 和日志不得输出 token、SSH private key 或 credential 文件正文。
- env projection 和 volume projection 都必须能在 runner Job dry-run 中看到 SecretRef 名称/key 和 projection kindvolume projection 必须显示只读 mount path。
- 缺少 tool credential 时,run/command 必须返回可判定的 `secret-unavailable``tenant-policy-denied` 或明确 blocker,不能伪装成 agent 业务失败。
- `transientEnv` 不得用于 GitHub token、UniDesk SSH client token、长期 SSH key、provider API key 或其他 provider/tool 可复用 credential。HWLAB dispatcher 生成并限定 owner/HWPOD/runtime scope 的 `HWLAB_API_KEY` 可以作为单次 runner Job runtime context 进入 `transientEnv`,但正式 Kubernetes Job 必须通过 per-job Secret 和 `valueFrom.secretKeyRef` 投影,不能作为 pod spec plain env valueAgentRun 不保存、不解释、不回显其明文。
@@ -259,6 +273,7 @@ skill 只来自 gitbundle 复制进 workspace 的 `.agents/skills/<name>/SKILL.m
- checkout 只能进入允许 workspace 前缀,不能覆盖 `/app`、Secret projection、profile runtime home 或 session 目录。
- run payload 不携带文件正文、env dump、Secret value 或大型 artifact。
- 若提供 `bundles[]`,必须能看到每个 `subpath -> target_path` 的复制摘要;旧字段输入必须 schema-invalid。
- 若启用 `gitMirror`,必须能看到 GitHub URL 被改写到 mirror `fetchRepoUrl`;非 GitHub URL 必须保留原 fetch URL 并显示 `mirrorUsed=false`
- 若提供 `promptRefs`,必须能看到每个 prompt 的 `name/path/sha256/bytes/inject`,新 thread 首轮 `initialPromptInjected=true`resume turn `initialPromptInjected=false`
- 若 bundle 复制了 `.agents/skills`,必须能看到 skillDirs 聚合摘要、skill 名称、manifest hash/bytes 和来源 bundle;若提供 `requiredSkills`,必须看到成功路径的 requiredSkills hash/bytes,以及缺失路径的 `required-skill-unavailable` blocker。不能显示模型默认 skill 列表当作业务 skill。
@@ -281,6 +296,6 @@ skill 只来自 gitbundle 复制进 workspace 的 `.agents/skills/<name>/SKILL.m
| `ProfileRef` | 已实现/待 dsflash-go 真实主闭环 | `codex``deepseek``minimax-m3` 已通过 SecretRef、writable runtime home 和真实 stdio turn 验证;MiniMax-M3 已通过 HWLAB 显式 session 原入口复测。`dsflash-go` 已补齐 SecretRef/model catalog 装配、自测试和 legacy key 归一,仍需完成真实 runtime 与 HWLAB 原入口复测;后续只允许作为 profile/config/SecretRef/model catalog 选择,不新增直连 backend。 |
| `SessionRef` | 已实现最小持久化 | manager 持久化 `sessionId/conversationId/threadId`run 创建会解析既有 sessionrunner 按 threadId resumesession 不保存 credential 文件,TTL/GC 后续细化。 |
| `SessionRef` | v0.1.1 已实现/已通过 HWLAB v0.2 原入口复测 | manager 持久化 `sessionId/conversationId/threadId` + 每个 session 绑 RWO PVC`agentrun-v01-session-<sessionId>`),runner Job 把 PVC 直接挂到 `${CODEX_HOME}/<codex_rollout_subdir>`codex app-server 自己落盘;runner pod 删除后 replacement runner 仍复用同一 SessionRef/PVC/thread,禁止 copy/restore、replacement threadId 和 fake resume。 |
| `ResourceBundleRef` | 已实现 `kind="gitbundle"` materialization/promptRefs/tools/skillDirs/requiredSkills 装配 | `repoUrl + ref/materialized commit + bundles[]` 已进入 run schema 和 runner checkoutworkspace 受 `AGENTRUN_WORKSPACE_ROOT` 限制,event/result 记录 requested ref/commit、actual commit、tree/workspace/bundles 摘要;`tools/` PATH、`promptRefs` thread-start 注入、`.agents/skills` 目录发现和 required skill 校验已实现。 |
| `toolCredentials` | 已实现最小 env projection | GitHub PR 和 UniDesk SSH passthrough 等 agent shell/tool 授权通过装配 SPEC 的 SecretRef 进入 runnerv0.1 支持 `tool=github``tool=unidesk-ssh``projection.kind=env`runner Job 使用 `valueFrom.secretKeyRef` 注入,不用 `transientEnv` 绕过。 |
| `ResourceBundleRef` | 已实现 `kind="gitbundle"` materialization/promptRefs/tools/skillDirs/requiredSkills 装配 | `repoUrl + ref/materialized commit + bundles[]` 已进入 run schema 和 runner checkoutworkspace 受 `AGENTRUN_WORKSPACE_ROOT` 限制,event/result 记录 requested ref/commit、actual commit、tree/workspace/bundles 摘要;`gitMirror` 会把 GitHub URL 改写到受控 mirror 并记录 `fetchRepoUrl/mirrorUsed``tools/` PATH、`promptRefs` thread-start 注入、`.agents/skills` 目录发现和 required skill 校验已实现。 |
| `toolCredentials` | 已实现 env 与 volume projection | GitHub PR、GitHub SSH 和 UniDesk SSH passthrough 等 agent shell/tool 授权通过装配 SPEC 的 SecretRef 进入 runnerv0.1 支持 `tool=github``tool=unidesk-ssh``projection.kind=env|volume`runner Job 使用 `valueFrom.secretKeyRef` 或只读 Secret volume 注入,不用 `transientEnv` 绕过。 |
| `transientEnv` | 已实现 per-job SecretRef 投影 | Queue dispatch 和 runner-job API 支持短期 runtime env;正式 Kubernetes Job 先创建本次 Job 专属 Secret,再用 `valueFrom.secretKeyRef` 注入 runner envresponse/event/trace 只显示 env names、Secret metadata 和 `valuesPrinted=false`。 |
+23 -2
View File
@@ -36,7 +36,8 @@
| Provider config | 非敏感 base URL/model 可以来自 `config.toml` 或 ConfigMapcredential value 不得放入 ConfigMap。 |
| Tekton Git SSH Secret | `agentrun-ci/agentrun-git-ssh` |
| Argo Git SSH Secret | `argocd/agentrun-git-ssh` |
| GitHub Tool Secret | `agentrun-v01-tool-github-pr` key `GH_TOKEN` |
| GitHub PR Tool Secret | `agentrun-v01-tool-github-pr` key `GH_TOKEN` |
| GitHub SSH Tool Secret | `agentrun-v01-tool-github-ssh` keys `id_ed25519``known_hosts``config` |
| UniDesk SSH Tool Secret | `agentrun-v01-tool-unidesk-ssh` key `UNIDESK_SSH_CLIENT_TOKEN` |
| Runtime ServiceAccount | `agentrun-v01-mgr``agentrun-v01-runner` |
@@ -187,6 +188,25 @@ Secret 创建和轮换不由 source branch 自动生成;source branch 只声
失败必须结构化返回 `failureKind`:缺文件、不可读文件或空 credential 归类为 `secret-unavailable`;非法 JSON/TOML 归类为 `schema-invalid`
## GitHub SSH Tool Secret bootstrap
`Artificer` 需要 GitHub SSH 权限时,长期 credential 不进入 Queue payload、`transientEnv`、Git source 或 GitOps Secret data。v0.1 提供受控 manager/CLI 入口把 operator 已有 SSH 文件写入 runtime namespace Secret
```bash
./scripts/agentrun tool-credentials set-github-ssh \
--private-key-file ~/.ssh/id_ed25519_github \
--known-hosts-file ~/.ssh/known_hosts \
--config-file ~/.ssh/config
```
规则:
- 写入对象固定为 `agentrun-v01/agentrun-v01-tool-github-ssh`keys 固定为 `id_ed25519``known_hosts``config`
- CLI dry-run 只显示输入文件 bytes、SecretRef、key 列表和确认命令,不输出文件内容。
- manager upsert Secret 只返回 resourceVersion、hash suffix、SecretRef 和 redaction 状态,不输出 `data``stringData`、private key、known_hosts 或 config 明文。
- `config` 缺省为只允许 `github.com``ssh.github.com:443``IdentityFile ~/.ssh/id_ed25519``StrictHostKeyChecking yes``UserKnownHostsFile ~/.ssh/known_hosts` 的最小配置;若传入自定义 config,必须包含 `Host``IdentityFile`
- runtime 消费仍必须通过 `executionPolicy.secretScope.toolCredentials[]` 的 volume projection 挂载到 `/home/agentrun/.ssh`;不得把同一 SSH private key 复制到镜像、ConfigMap、payload 或 transient env。
## 日志与事件 Redaction
- event、trace、日志、CLI 输出、health 和 diagnostics 不得打印 Secret 值。
@@ -223,6 +243,7 @@ Secret 创建和轮换不由 source branch 自动生成;source branch 只声
| DeepSeek profile SecretRef | 已实现/已通过主闭环 | 已新增 `agentrun-v01-provider-deepseek` render、GitOps/RBAC 引用、Job projection、profile 选择和负向 missing-secret 自测试;真实 Secret 创建与 Kubernetes Job projection 已通过主闭环,轮换仍由 Kubernetes 密钥管理流程完成。 |
| MiniMax-M3 profile SecretRef | 已实现/待真实主闭环 | 已新增 `agentrun-v01-provider-minimax-m3` render、GitOps/RBAC 引用、Job projection、profile 选择和负向 missing-secret 自测试;真实 Secret 创建使用 HWLAB Code Queue 现有 MiniMax API key,轮换仍由 Kubernetes 密钥管理流程完成。 |
| dsflash-go profile SecretRef | 已实现/待真实主闭环 | 已新增 `agentrun-v01-provider-dsflash-go``model-catalog.json` required key、Secret render、Job projection、writable `CODEX_HOME` 复制和负向 readiness;真实 profile turn 仍需按 provider 管理 canary 和 HWLAB 原入口复测。 |
| Tool credential SecretRef | 已实现最小 env projection | `executionPolicy.secretScope.toolCredentials[]` 已支持 `tool=github``tool=unidesk-ssh``projection.kind=env`runner Job 通过 Kubernetes `secretKeyRef` 注入 envCLI、event、runner job response 和 dry-run 只显示 SecretRef/projection 元数据,不输出值。 |
| Tool credential SecretRef | 已实现 env + volume projection | `executionPolicy.secretScope.toolCredentials[]` 已支持 `tool=github``tool=unidesk-ssh``projection.kind=env|volume`runner Job 通过 Kubernetes `secretKeyRef` 注入 env,或通过只读 Secret volume 挂载到 `/home/agentrun/*`CLI、event、runner job response 和 dry-run 只显示 SecretRef/projection 元数据,不输出值。 |
| GitHub SSH Tool Secret bootstrap | 已实现 | `tool-credentials set-github-ssh` 通过 manager 受控 upsert runtime Secretlist/show 只展示 SecretRef、key presence 和 hash suffixSecret value 不进入输出。 |
| redaction 最小规则 | 已实现主路径 | Secret dry-run 工具、event、Job dry-run 输出、self-test 和真实主闭环均不打印 Secret value;复杂审计按 [spec-v01-validation.md](spec-v01-validation.md) 人工抽查。 |
| 外部 secret manager | 未采用 | 如需 Vault/ExternalSecrets/SOPS,后续单独更新规格。 |