Merge pull request #24 from pikasTech/docs/v01-profile-deepseek-spec

docs: 同步 v0.1 backend profile 规格
This commit is contained in:
Lyon
2026-05-29 18:05:54 +08:00
committed by GitHub
12 changed files with 161 additions and 62 deletions
+4 -3
View File
@@ -42,8 +42,9 @@ AgentRun 是面向 UniDesk 与 HWLAB 的共享 Agent 执行基础设施。本仓
## Critical v0.1 Implementation Stack Rule
- P0: AgentRun `v0.1` 自研 runtime、CLI、manager、runner、backend adapter、Codex backend 和后续 scheduler 的优先实现语言是 Bun + TypeScript;官方 TypeScript CLI 入口是 `scripts/agentrun-cli.ts`G14/CI/人工非交互命令使用 `./scripts/agentrun` 启动同一入口,复杂逻辑拆入 `scripts/src/``src/`
- P0: `backendProfile=codex` 必须通过 Codex CLI app-server stdio 协议执行,启动受控 `codex app-server --listen stdio://`,使用 JSON-RPC 方法 `initialize``thread/start``thread/resume``turn/start`不得在 `v0.1` 把 Codex backend 实现为直接 Responses HTTP 代理、文本 fallback 或 fake provider。
- P0: 实现 Codex backend 前必须参考 UniDesk Code Queue 的 `src/components/microservices/code-queue/src/code-agent/codex.ts``common.ts`,以及 HWLAB 的 `internal/cloud/codex-stdio-session.mjs``scripts/code-agent-chat-smoke.mjs`;复用协议、redaction、trace、failure 分类和 Secret projection 经验,不复制环境专用路径或明文密钥
- P0: `backendProfile=codex` `backendProfile=deepseek`必须通过同一个 Codex CLI app-server stdio backend kind 执行,启动受控 `codex app-server --listen stdio://`,使用 JSON-RPC 方法 `initialize``thread/start``thread/resume``turn/start`DeepSeek 是 profile/config/SecretRef 选择,不是直接 Responses HTTP 代理、独立 fake provider 或文本 fallback
- P0: `codex``deepseek` profile 必须使用 profile-scoped SecretRef 和 writable `CODEX_HOME`,不得互相 fallback、复用运行态文件或污染默认 `codex` profile;切换顺序必须可验证为 `codex -> deepseek -> codex` 均独立
- P0: 实现 Codex stdio backend/profile 前必须参考 UniDesk Code Queue 的 `src/components/microservices/code-queue/src/code-agent/codex.ts``common.ts`,以及 HWLAB 的 `internal/cloud/codex-stdio-session.mjs``scripts/code-agent-chat-smoke.mjs``docs/reference/spec-v02-deepseek-proxy.md``docs/reference/code-agent-chat-readiness.md`;复用协议、redaction、trace、failure 分类、profile overlay 和 Secret projection 经验,不复制环境专用路径或明文密钥。
## 长期参考文档
@@ -56,7 +57,7 @@ AgentRun 是面向 UniDesk 与 HWLAB 的共享 Agent 执行基础设施。本仓
- `docs/reference/spec-v01-agentrun-mgr.md`v0.1 manager REST API、tenant boundary、runner claim 和 event/status authority。
- `docs/reference/spec-v01-agentrun-runner.md`v0.1 短生命周期 runner、claim/poll/report、日志和 failureKind。
- `docs/reference/spec-v01-backend-adapter.md`v0.1 backend adapter 合同、event normalization、failure mapping 和 redaction。
- `docs/reference/spec-v01-backend-codex.md`v0.1 第一真实 Codex backend`~/.codex` 测试凭据 Secret projection 和真实 turn 验收。
- `docs/reference/spec-v01-backend-codex.md`v0.1 Codex app-server stdio backend、`codex`/`deepseek` profile`~/.codex` 测试凭据 Secret projection 和真实 turn 验收。
- `docs/reference/spec-v01-cli.md`v0.1 AgentRun CLI 命令族、JSON 输出、短返回和日志可见。
- `docs/reference/spec-v01-scheduler.md`v0.1 自动 scheduler 的 deferred 边界。
- `docs/reference/architecture.md`:AgentRun 产品边界、服务架构、MVP 阶段、RESTful API 模型和数据模型。
+5 -5
View File
@@ -21,7 +21,7 @@ UniDesk 与 HWLAB 是 tenant/client。UniDesk 负责平台入口、provider 清
- `projectId`,例如 `pikasTech/unidesk``pikasTech/HWLAB`
- `workspaceRef`,用于定位 source/worktree/workspace
- `providerId`,例如 `G14``D601`
- `backendProfile`例如 `codex``opencode``claudecode``host-native``windows-native`
- `backendProfile``v0.1` allowlist 为 `codex``deepseek`;后续可以扩展 `opencode``claudecode``host-native``windows-native`
- `executionPolicy`,包含 sandbox、approval、timeout、network 和 secret scope
- `traceSink`,说明标准化 event 镜像到哪里。
@@ -51,9 +51,9 @@ Backend adapter 隐藏具体工具协议。Codex stdio JSON-RPC、OpenCode JSON
AgentRun `v0.1` 自研 runtime 优先使用 Bun + TypeScriptmanager、runner、backend adapter、Codex backend、CLI 和后续 scheduler 都按这一技术栈实现。`scripts/agentrun-cli.ts` 是官方 CLI 入口;复杂 CLI 逻辑进入 `scripts/src/`,服务和 runner 逻辑进入 `src/`。YAML manifest、Tekton/Argo CD 配置、Postgres 和 Kubernetes 仍按各自原生生态管理。
Codex backend 固定采用 Codex CLI app-server JSON-RPC over stdio。实现必须启动受控 `codex app-server --listen stdio://`,执行 `initialize``thread/start``thread/resume``turn/start`,并把 stdout/stderr、notification、tool lifecycle、assistant output 和 terminal/error 状态归一化为 AgentRun events。直接 Responses HTTP、OpenAI SDK wrapper、`codex exec` 一次性输出或文本 fallback 不能作为 `v0.1` Codex backend 的正式执行路径。
Codex stdio backend 固定采用 Codex CLI app-server JSON-RPC over stdio。实现必须启动受控 `codex app-server --listen stdio://`,执行 `initialize``thread/start``thread/resume``turn/start`,并把 stdout/stderr、notification、tool lifecycle、assistant output 和 terminal/error 状态归一化为 AgentRun events。`codex``deepseek` 是同一个 backend kind 下的 profile/config/SecretRef 选择;直接 Responses HTTP、OpenAI SDK wrapper、`codex exec` 一次性输出或文本 fallback 不能作为 `v0.1` Codex backend 的正式执行路径。
实现参考优先级:UniDesk Code Queue 的 `src/components/microservices/code-queue/src/code-agent/codex.ts``common.ts`,以及 HWLAB v0.2 的 `internal/cloud/codex-stdio-session.mjs``scripts/code-agent-chat-smoke.mjs`。AgentRun 复用其协议、trace、redaction、Secret projection 和 failure 分类经验,但不复制 tenant 业务规则、环境专用路径或密钥材料。
实现参考优先级:UniDesk Code Queue 的 `src/components/microservices/code-queue/src/code-agent/codex.ts``common.ts`,以及 HWLAB v0.2 的 `internal/cloud/codex-stdio-session.mjs``scripts/code-agent-chat-smoke.mjs``docs/reference/spec-v02-deepseek-proxy.md``docs/reference/code-agent-chat-readiness.md`。AgentRun 复用其协议、trace、redaction、Secret projection、profile overlay、DeepSeek/Moon Bridge 分层诊断和 failure 分类经验,但不复制 tenant 业务规则、环境专用路径、bridge host、namespace 或密钥材料。
## MVP 顺序
@@ -69,7 +69,7 @@ AgentRun 必须按纵向切片推进,不要一开始大规模并行开发。
- `Runner`
- `Backend`
第一切片只要求 `turn``interrupt``status` 和分页 `events`。不要一开始就做 `steer``resume`、judge/retry、UI、 backend 路由或自动调度
第一切片只要求 `turn``interrupt``status` 和分页 `events`。不要一开始就做 `steer``resume`、judge/retry、UI、 backend kind 的自动路由或自动调度。`v0.1` 可做同一 Codex stdio backend kind 下的显式 profile 选择
### M1: 最小 Runner 加一个 Backend
@@ -224,7 +224,7 @@ Control-plane service 应是长驻服务;runner 应是短生命周期 Job 或
- 迁移 UniDesk Code Queue
- 全局替换 HWLAB Code Agent
- 多 backend 路由;
- 跨 backend kind 的自动多 backend 路由;
- 最小诊断之外的 UI
- judge/retry 自动化;
- 自动扩缩容;
+5 -4
View File
@@ -61,7 +61,7 @@ POST /api/v1/commands/:commandId/ack
| `projectId` | 必填,例如 `pikasTech/unidesk``pikasTech/HWLAB`。 |
| `workspaceRef` | 必填,描述 source/worktree/workspace,不由 runner 猜测。 |
| `providerId` | 必填,例如 `G14``D601`;只表示目标 provider,不直接授予业务权限。 |
| `backendProfile` | 必填,`v0.1` 默认真实 backend 为 `codex`。 |
| `backendProfile` | 必填,`v0.1` allowlist 为 `codex``deepseek`;两者共享 Codex stdio backend kind。 |
| `executionPolicy` | 必填或由 manager 显式补齐默认值,至少包含 sandbox、approval、timeout、network 和 secretScope。 |
| `traceSink` | 字段必须存在;可以为 `null` 或显式 sink。 |
@@ -71,10 +71,10 @@ POST /api/v1/commands/:commandId/ack
`v0.1` 不实现独立 policy engine。Manager 只做基础边界收敛:
- 校验 tenant/project/provider/backend 是否在 `v0.1` 允许集合内。
- 校验 tenant/project/provider/backendProfile 是否在 `v0.1` 允许集合内;当前 backendProfile 允许 `codex``deepseek`
- 校验 workspaceRef 形态存在且与 tenant 请求一致;不替 tenant 判断某个 repo 操作是否业务授权。
- 校验 executionPolicy 不扩大 sandbox、network、approval、timeout 和 secretScope。
- 校验 secretScope 只引用 [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md) 中允许的 SecretRef。
- 校验 secretScope 只引用 [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md) 中允许的 SecretRef,且存在与 `backendProfile` 同名的 provider credentialmanager 只校验引用形态,不读取 Secret 值
- 对 HWLAB live device mutation、UniDesk production deploy、GitHub issue/PR 写入等业务授权,Manager 只记录字段和审计事件,不把业务规则硬编码成通用门禁。
## 最小 Observability 合同
@@ -93,7 +93,7 @@ POST /api/v1/commands/:commandId/ack
### T2 Run schema 与 tenant boundary
阅读本文和 [spec-v01-services.md](spec-v01-services.md),然后调用 `POST /api/v1/runs` 创建包含 tenant/project/workspace/provider/backend/execution/trace 字段的 run。确认缺失字段、非法 tenant、非法 backend 或扩大 secretScope 都返回结构化 failureKind,合法请求持久化后可用 `GET /api/v1/runs/:runId` 查询。
阅读本文和 [spec-v01-services.md](spec-v01-services.md),然后调用 `POST /api/v1/runs` 创建包含 tenant/project/workspace/provider/backend/execution/trace 字段的 run。确认缺失字段、非法 tenant、非法 backend`backendProfile=deepseek` 但缺少 matching provider credential、或扩大 secretScope 都返回结构化 failureKind,合法请求持久化后可用 `GET /api/v1/runs/:runId` 查询。
### T3 Command idempotency
@@ -110,5 +110,6 @@ POST /api/v1/commands/:commandId/ack
| `agentrun-mgr` 服务规格 | 已定义 | 本文为 v0.1 manager 权威。 |
| Manager REST API | 已实现/已通过主闭环 | 已有 run、command、event、backends、runner register、claim、lease heartbeat、poll、ack、status、runner Job 创建和 health/readiness 的 HTTP JSON API;真实 runtime 已通过 RESTful API 主闭环。 |
| Tenant policy boundary | 已实现最小边界 | v0.1 已做 schema、tenant/backend allowlist、executionPolicy 和 secretScope 结构校验;业务授权仍由 UniDesk/HWLAB 自己判定。 |
| `deepseek` backendProfile allowlist | 已定义/待实现 | 需要扩展 manager validation、backend capability 和 matching SecretRef 校验。 |
| Postgres durable adapter | 已实现/已通过主闭环 | live runtime 通过 `DATABASE_URL` 使用 Postgres durable storememory store 仅用于显式 self-test/dev。见 [spec-v01-postgres.md](spec-v01-postgres.md)。 |
| Observability 最小合同 | 已实现主路径 | events append-only、terminal status、failureKind、health/readiness store 状态、runner claim/lease/backend events 和 Secret/DSN redaction 已进入 manager;集中 trace 和部署级观测仍属后续工作。 |
+8 -3
View File
@@ -27,7 +27,7 @@ Runner 启动参数必须显式包含:
Runner Secret 只能通过 Kubernetes Secret projection、ServiceAccount/RBAC 或受控 Secret API 读取获得。Codex 测试凭据投影规则见 [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md) 和 [spec-v01-backend-codex.md](spec-v01-backend-codex.md)。
Kubernetes Job runner 必须把 credential source 与 runtime home 分开:Secret volume 只读挂在 `/var/run/agentrun/secrets/...``/home/agentrun``emptyDir` 提供可写空间,`CODEX_HOME` 指向 `/home/agentrun/.codex``AGENTRUN_CODEX_SECRET_HOME` 指向只读 projection。runner/backend 在启动 provider 前只复制授权文件,不打印内容。
Kubernetes Job runner 必须把 credential source 与 runtime home 分开:Secret volume 只读挂在 `/var/run/agentrun/secrets/...``/home/agentrun``emptyDir` 提供可写空间,`CODEX_HOME` 指向当前 run/profile 的 writable runtime home`AGENTRUN_CODEX_SECRET_HOME` 指向当前 `backendProfile` 对应的只读 projection。runner/backend 在启动 provider 前只复制授权文件,不打印内容。`codex``deepseek` profile 不得共享同一个可写 runtime home,除非它们运行在不同的 per-run Kubernetes Job 且该目录由 Job 独占 emptyDir 提供。
Kubernetes Job runner 必须设置有限保留时间。`v0.1` 默认 `ttlSecondsAfterFinished=86400`,用于保留最近完成 Job 的调试窗口,同时避免长期堆积 `Completed` runner Job 污染运行面观察。该 TTL 是 Job manifest 的运行面属性,不是 CI/CD 门禁;需要延长保留时间时必须通过受控 Job render/input 显式覆盖,并在 issue 或 PR 中说明原因。
@@ -48,7 +48,7 @@ claimed -> lease_lost
- runner 必须先 register,再 claim runclaim 失败不能继续调用 backend。
- lease heartbeat 必须可观察;过期或冲突时写入 failure event 或明确退出原因。
- command 只能从 manager poll;不得从本地文件或临时参数伪造正式 command。
- backend 产生的所有可见输出必须先经过 adapter normalization 和 redaction,再 append 到 manager。
- backend 产生的所有可见输出必须先经过 adapter normalization 和 redaction,再 append 到 managerbackend_status 至少包含 redacted profile/backendKind/protocol 摘要
- terminal status 上报后 runner 可以退出;退出码与 terminal status 必须一致或在日志中可解释。
## Manager API 交互
@@ -97,7 +97,11 @@ Runner 日志必须实时 flush 到文件或 pod logCLI 启动 runner 时必
### T4 Missing Secret failure
阅读本文和 [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md),然后用缺失 Codex SecretRef 的 run 启动 runner。确认 runner 不调用 providerrun 失败为 `secret-unavailable` 或等价 failureKind,日志和事件不泄露 Secret 值。
阅读本文和 [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md),然后分别用缺失 `codex` SecretRef 与缺失 `deepseek` SecretRef 的 run 启动 runner。确认 runner 不调用 providerrun 失败为 `secret-unavailable` 或等价 failureKind不 fallback 到另一个 profile日志和事件不泄露 Secret 值。
### T5 Profile switching
阅读本文和 [spec-v01-backend-codex.md](spec-v01-backend-codex.md),然后按 `codex -> deepseek -> codex` 顺序启动三个真实 runner Job。确认每个 Job 只挂载和复制当前 profile 的 SecretRef`CODEX_HOME` 互相隔离,且前后两个 `codex` run 不受 `deepseek` run 的 config/model/upstream 影响。
## 规格的实现情况
@@ -108,3 +112,4 @@ Runner 日志必须实时 flush 到文件或 pod logCLI 启动 runner 时必
| host process runner | 已实现 | `runner start``src/runner/main.ts` 进入同一套 `runOnce`,可通过 manager register/claim/poll/report 执行自测试。 |
| claim/lease/report client | 已实现 | 已拆出 runner manager API client,覆盖 register、claim、lease heartbeat、poll command、ack、append event 和 terminal statuslive runtime 通过 manager 写入 Postgres durable store。 |
| runner redaction | 已实现主路径 | runner/backend event 和 Job 输出使用 redaction;复杂审计仍按 [spec-v01-validation.md](spec-v01-validation.md) 的人工验收抽查。 |
| `deepseek` profile runner selection | 已定义/待实现 | 需要按 run `backendProfile` 选择 matching SecretRef、projection、`CODEX_HOME` 和 backend metadata。 |
+22 -6
View File
@@ -4,7 +4,7 @@ Backend adapter 是 runner 与具体 Code Agent 工具之间的适配层。它
## 在系统中的职责划分
- 根据 `backendProfile` 选择具体 backend 实现`v0.1` 必须至少证明一个真实 Agent backend,默认是 `codex`
- 根据 `backendProfile` 选择具体 backend profile`v0.1` 必须支持 `codex``deepseek`,两者共享同一个 `codex-app-server-stdio` backend kind
- 接收 manager 持久化后的 run、command 和 executionPolicy;不得自行扩大 workspace、network、approval 或 secret scope。
- 调用具体 backend,并把 backend 输出归一化为 AgentRun events。
- 负责 provider/auth/backend/protocol 错误到 failureKind 的映射。
@@ -24,9 +24,20 @@ finalize(executionContext) -> terminal status
redact(value) -> redacted value
```
Adapter 输入必须来自 manager 保存的 run/command 和 Kubernetes Secret projection;不得从 CLI 参数、临时环境变量或 Git 文件读取 provider credential 明文。
Adapter 输入必须来自 manager 保存的 run/command 和 Kubernetes Secret projection;不得从 CLI 参数、临时环境变量或 Git 文件读取 provider credential 明文。`resolveProfile(profile)` 必须返回 profile、backendKind、protocol、transport、command、requiredSecretKeys 和 isolation policy;不得把 unknown profile 静默映射到默认 `codex`
`v0.1` 的第一真实 adapter 是 Codex adapter。它必须走 Codex CLI app-server JSON-RPC over stdioadapter 合同把 Codex 的 thread、turn、notification、tool lifecycle 和 stderr/exit 信息归一化为 AgentRun 标准 events。
`v0.1` 的第一真实 adapter 是 Codex stdio adapter。它必须走 Codex CLI app-server JSON-RPC over stdioadapter 合同把 Codex 的 thread、turn、notification、tool lifecycle 和 stderr/exit 信息归一化为 AgentRun 标准 events。`codex``deepseek` 只是该 adapter 的 profile/config/SecretRef 选择,不允许复制两套协议实现。
## Backend Profile Registry
`GET /api/v1/backends` 和 adapter 内部 registry 至少报告以下 profile
| profile | backendKind | protocol | transport | command | v0.1 状态 |
| --- | --- | --- | --- | --- | --- |
| `codex` | `codex-app-server-stdio` | `codex-app-server-jsonrpc-stdio` | `stdio` | `codex app-server --listen stdio://` | 已有主闭环,必须保持默认兼容。 |
| `deepseek` | `codex-app-server-stdio` | `codex-app-server-jsonrpc-stdio` | `stdio` | `codex app-server --listen stdio://` | 待实现 profile;实现后必须用独立 SecretRef 和 `CODEX_HOME` 真实联调。 |
Registry 只表达能力和选择边界,不读取 Secret 值。Manager 负责校验 `backendProfile` 是否在 allowlist 内,并校验 `executionPolicy.secretScope.providerCredentials` 是否存在匹配 profile 的 SecretRefrunner 只为当前 run 选择的 profile 准备 Secret projection 和 runtime home。
## 标准事件
@@ -79,14 +90,19 @@ Adapter 必须把 backend 错误映射为稳定 failureKind
### T3 真实 backend 联调
阅读本文、[spec-v01-backend-codex.md](spec-v01-backend-codex.md) 和 [spec-v01-validation.md](spec-v01-validation.md),然后用真实 Codex backend 完成一个最短 turn。确认 adapter 输出真实 assistant/backend_status/terminal_status events,且没有 Secret 泄露。
阅读本文、[spec-v01-backend-codex.md](spec-v01-backend-codex.md) 和 [spec-v01-validation.md](spec-v01-validation.md),然后分别用 `backendProfile=codex``backendProfile=deepseek` 完成真实最短 turn。确认 adapter 输出真实 assistant/backend_status/terminal_status events事件中包含 profile/backendKind/protocol 摘要,且没有 Secret 泄露。
### T4 Profile isolation 自测试
阅读本文,然后用 fake Codex app-server 和两个不同的 profile Secret fixture 做自测试。确认 adapter 只选择 run 指定 profile 的 SecretRef 和 `CODEX_HOME``deepseek` 缺失时失败为 `secret-unavailable`,不会 fallback 到 `codex`
## 规格的实现情况
| 规格项 | 状态 | 说明 |
| --- | --- | --- |
| Backend adapter 合同 | 已定义 | 本文为 v0.1 adapter 权威。 |
| 通用 adapter 模块 | 已实现最小形态 | `src/backend/adapter.ts` 作为 runner 进程内 adapter 入口`v0.1`路由真实 `codex` profile;多 backend 路由仍 deferred。 |
| 通用 adapter 模块 | 已实现最小形态/待扩展 profile | `src/backend/adapter.ts` 作为 runner 进程内 adapter 入口;当前已路由真实 `codex` profile,仍需扩展 `deepseek` profile 但不应复制第二套 stdio 协议实现。 |
| event normalization | 已实现主路径 | Codex backend 已把 backend_status、assistant_message、tool_call、command_output、error 和 terminal_status 归一化为 manager events;复杂事件审计按人工验收抽查。 |
| failure mapping | 已实现主路径 | Codex backend 已覆盖 missing secret、auth/rate/availability、protocol、JSON parse、invalid response、spawn、timeout 和 cancel 分类;真实负向场景按 [spec-v01-validation.md](spec-v01-validation.md) T7 手动验收。 |
| 多 backend 路由 | Deferred | v0.1 要求一个真实 backend 闭环。 |
| `deepseek` profile | 已定义/待实现 | v0.1 要求作为同一 Codex stdio backend kind 的 profile 进入 registry、validation、runner secret selection 和综合联调。 |
| 多 backend 路由 | Deferred | 跨 backend kind 的自动路由和 scheduler capacity selection 不进入 v0.1。 |
+40 -12
View File
@@ -1,18 +1,18 @@
# v0.1 Codex Backend 规格
# v0.1 Codex Stdio Backend/Profile 规格
Codex backend 是 AgentRun `v0.1` 的第一真实 Code Agent backend 候选。它用于证明 runner、backend adapter、Kubernetes Secret projection、真实 provider 调用、event normalization 和 terminal status 的完整闭环。
Codex stdio backend 是 AgentRun `v0.1` 的第一真实 Code Agent backend kind。它用于证明 runner、backend adapter、Kubernetes Secret projection、真实 provider 调用、event normalization 和 terminal status 的完整闭环。`v0.1` 在同一个 backend kind 下支持 `codex``deepseek` 两个 profile;两者共享 Codex CLI app-server stdio 协议,只通过 profile/config/SecretRef 隔离上游和模型。
## 在系统中的职责划分
- 作为 `backendProfile=codex` 具体实现。
- 作为 `backendProfile=codex` `backendProfile=deepseek` 的共同具体实现。
- 使用真实 Codex/Codex-compatible 配置执行最短 turn,不使用 fake provider 作为综合联调通过证据。
- 消费 Kubernetes Secret projection 提供的 Codex 凭据文件
- 消费 Kubernetes Secret projection 提供的 profile 专属 Codex `auth.json``config.toml`
- 把 Codex 输出归一化为 AgentRun 标准 events 和 terminal status。
- 将 provider/auth/protocol/timeout/cancel 错误映射为 [spec-v01-backend-adapter.md](spec-v01-backend-adapter.md) 定义的 failureKind。
## 协议选型与实现参考
`v0.1` Codex backend 的协议固定为 Codex CLI app-server JSON-RPC over stdio。Backend adapter 必须启动受控子进程:
`v0.1` Codex stdio backend 的协议固定为 Codex CLI app-server JSON-RPC over stdio。Backend adapter 必须启动受控子进程:
```bash
codex app-server --listen stdio://
@@ -20,7 +20,7 @@ codex app-server --listen stdio://
Adapter 通过 stdin 写入换行分隔 JSON-RPC 请求,通过 stdout 逐行读取 JSON-RPC response 和 notificationstderr 只作为有界诊断日志。最小请求序列是 `initialize``thread/start``thread/resume``turn/start`response 中必须提取 thread/turn identitynotification 和后续输出必须归一化为 `backend_status``assistant_message``tool_call``command_output``error``terminal_status` events。
不得把以下路径作为 `v0.1` Codex backend 的正式实现或综合联调通过证据:直接 Responses HTTP 代理、OpenAI SDK wrapper、`codex exec` 一次性命令输出、fake provider、固定文本回复、只读 shortcut 或本地 shell 模拟。裸 HTTP 或 `codex exec --json` 可以作为 provider/upstream 诊断,但最终通过必须来自 app-server stdio turn。
不得把以下路径作为 `v0.1` Codex stdio backend 的正式实现或综合联调通过证据:直接 Responses HTTP 代理、OpenAI SDK wrapper、`codex exec` 一次性命令输出、fake provider、固定文本回复、只读 shortcut 或本地 shell 模拟。裸 HTTP 或 `codex exec --json` 可以作为 provider/upstream 诊断,但最终通过必须来自 app-server stdio turn。
实现必须参考成熟代码:
@@ -30,30 +30,49 @@ Adapter 通过 stdin 写入换行分隔 JSON-RPC 请求,通过 stdout 逐行
| UniDesk `src/components/microservices/code-queue/src/code-agent/common.ts` | backend port/capability、model/profile 边界、文本 input shape、Git/proxy env 处理和 provider 端口归一化。 |
| HWLAB `internal/cloud/codex-stdio-session.mjs` | long-lived stdio session readiness、Codex home/workspace/protocol gate、child env redaction、trace recorder、cancel/timeout/failure kind。 |
| HWLAB `scripts/code-agent-chat-smoke.mjs` | fake app-server 自测试方式、`thread/start` + `turn/start` 调用顺序、session reuse、tool trace 和 Secret 不泄露断言。 |
| HWLAB `docs/reference/spec-v02-deepseek-proxy.md` | DeepSeek profile 通过稳定 bridge/Responses-compatible 入口接入,而不是把 DeepSeek 做成绕过 Codex stdio 的直接 HTTP backend。 |
| HWLAB `docs/reference/code-agent-chat-readiness.md` | provider/profile 切换时按 profile overlay、认证、网络、模型、Codex CLI/app-server 分层验证,并防止一个 profile 的成功掩盖另一个 profile 的退化。 |
这些参考用于协议和质量标准,不复制 UniDesk/HWLAB 的业务 prompt、硬件路径、tenant policy、hostPath Secret 做法或任何明文密钥。
## v0.1 Profile 定义
| backendProfile | SecretRef | 配置来源 | 规则 |
| --- | --- | --- | --- |
| `codex` | `agentrun-v01-provider-codex` | operator 当前 Codex `auth.json`/`config.toml` | 现有默认 profile;实现 DeepSeek 时不得改变其默认模型、config authority 或真实联调路径。 |
| `deepseek` | `agentrun-v01-provider-deepseek` | operator 准备的 DeepSeek-compatible Codex `auth.json`/`config.toml` | 使用同一 `codex app-server --listen stdio://` 协议,通过 `config.toml` 或等价 profile overlay 指向 DeepSeek-compatible upstream/model。 |
`deepseek` 的上游形态借鉴 HWLAB v0.2DeepSeek 是 provider profile,通过 Responses-compatible bridge、Moon Bridge 或等价稳定服务暴露给 Codex CLIAgentRun 不在 backend adapter 里手写 DeepSeek HTTP 转换器,也不把 DeepSeek 作为绕过 Codex app-server 的独立 backend kind。上游 base URL、模型和 provider 名称可以作为 redacted metadata 输出;API Key 和 `auth.json`/`config.toml` 原文不得输出。
Profile 切换规则:
- `backendProfile` 是 run 的显式字段,manager 不得静默改写。
- runner/backend 只读取与 `backendProfile` 同名的 provider credential;缺失则 `secret-unavailable`
- 每次 run 必须使用 profile-scoped writable `CODEX_HOME`。Kubernetes Job 可以把选中 profile 的 Secret projection 复制到该 Job 独占的 `/home/agentrun/.codex`host process 或复用进程必须使用 run/profile 独占目录,避免 `codex``deepseek` 互相污染。
- `deepseek` 不得 fallback 到 `codex` Secret、模型或 upstream`codex` 也不得读取 `deepseek` Secret。
- command payload 中显式提供 model 时可以透传给 Codex turn;未显式提供时以 profile `config.toml` 为 authority,不在 adapter 中写死默认模型。
## 测试凭据来源
`v0.1` 综合联调用的 Codex 测试凭据源固定为 operator 环境中的以下两个文件:
`v0.1` 综合联调用的 Codex stdio profile 测试凭据源固定为 operator 环境中的以下两个文件形态
```text
~/.codex/auth.json
~/.codex/config.toml
```
这两个文件只能作为 Kubernetes Secret 创建或轮换的输入源,不能通过 hostPath 挂载进 Pod,不能复制进镜像,不能提交到 source branch、GitOps branch、artifact catalog、issue、PR、event、trace、日志或 CLI 输出。
这两个文件只能作为 Kubernetes Secret 创建或轮换的输入源,不能通过 hostPath 挂载进 Pod,不能复制进镜像,不能提交到 source branch、GitOps branch、artifact catalog、issue、PR、event、trace、日志或 CLI 输出。`codex``deepseek` 可以来自不同 operator profile 目录或显式文件参数,但进入 Kubernetes 后必须是不同 SecretRef,除非后续规格明确批准某个共享 SecretRef 场景。
`v0.1` 默认 Kubernetes Secret
| 对象 | v0.1 规格 |
| --- | --- |
| Namespace | `agentrun-v01` |
| Secret name | `agentrun-v01-provider-codex` |
| Secret name | `agentrun-v01-provider-codex``agentrun-v01-provider-deepseek` |
| Secret key | `auth.json`,来自 `~/.codex/auth.json` |
| Secret key | `config.toml`,来自 `~/.codex/config.toml` |
| Consumer | runner 或 backend adapter Pod |
| Projection target | 容器用户的 `~/.codex/auth.json``~/.codex/config.toml` |
| Projection target | 只读 projection,再复制到当前 run/profile 的 writable `CODEX_HOME/auth.json``CODEX_HOME/config.toml` |
| File mode | 只读,建议 `0400` 或等价最小权限 |
Kubernetes Secret 的创建、轮换和权限控制属于集群密钥管理流程;source branch 只声明 SecretRef 名称、key 和 mount intent。`deploy/deploy.json` 和 rendered GitOps manifest 不得包含 Secret data。
@@ -70,7 +89,7 @@ Kubernetes Secret 的创建、轮换和权限控制属于集群密钥管理流
[spec-v01-secret-distribution.md](spec-v01-secret-distribution.md) 是 SecretRef、Kubernetes projection、redaction 和 missing secret failure 的权威。本文件只定义 Codex backend 对测试凭据文件的消费方式。
Run 的 `executionPolicy.secretScope` 应引用 `agentrun-v01-provider-codex``auth.json``config.toml`,而不是携带 provider credential 或文件内容。
Run 的 `executionPolicy.secretScope` 应引用 `backendProfile` 匹配的 provider SecretRef`auth.json``config.toml`,而不是携带 provider credential 或文件内容。
## 测试规格
@@ -82,6 +101,10 @@ Run 的 `executionPolicy.secretScope` 应引用 `agentrun-v01-provider-codex`
阅读本文和 [spec-v01-validation.md](spec-v01-validation.md),然后用 `backendProfile=codex` 创建真实 run 并提交一个最短 `turn` command。确认 runner 调用真实 Codex providermanager 可查询 backend_status、assistant 或 error event、terminal_status,且 Secret value 未泄露。
### T2b 真实 DeepSeek profile 最短 turn
阅读本文、HWLAB v0.2 DeepSeek profile 参考和 [spec-v01-validation.md](spec-v01-validation.md),然后用 `backendProfile=deepseek` 创建真实 run 并提交一个最短 `turn` command。确认 runner 仍调用 `codex app-server --listen stdio://`,但使用 `agentrun-v01-provider-deepseek` 的 profile SecretRef 和独立 `CODEX_HOME`manager 可查询 profile 为 `deepseek` 的 backend_status、assistant 或 error event、terminal_status,且 Secret value 未泄露。
### T3 Missing auth/config failure
阅读本文,然后分别移除或改名 Secret 中的 `auth.json``config.toml` key,启动真实 run。确认 adapter 在调用 provider 前失败为 `secret-unavailable`failure response 为 JSON,日志不包含 Secret value。
@@ -94,13 +117,18 @@ Run 的 `executionPolicy.secretScope` 应引用 `agentrun-v01-provider-codex`
阅读本文,然后用 mock/fake Codex app-server 自测试 HTTP 503 `Service Unavailable`、携带 5xx 的 `responseStreamDisconnected``method=error` retry notification 中 `willRetry=true` 且嵌套 `codexErrorInfo.responseStreamDisconnected.httpStatusCode=503` 的结构,或明确 temporary/provider unavailable 文案。确认 Codex adapter 返回 `provider-unavailable`,不会落到 `backend-failed`;综合联调若真实 provider 返回同类错误,应记录为外部 provider blocker,而不是本地 runner/backend 执行面 blocker。
### T6 Profile switching isolation
阅读本文,然后在真实 `agentrun-v01` 运行面按顺序执行 `backendProfile=codex``backendProfile=deepseek``backendProfile=codex` 三个最短 turn。确认第二个 run 使用 DeepSeek profile,前后两个 `codex` run 仍使用原 Codex profile;三者的 event、log、backend_status、model/upstream metadata 和 failureKind 不互相污染,且任何一个 profile SecretRef 缺失都不会 fallback 到另一个 profile。
## 规格的实现情况
| 规格项 | 状态 | 说明 |
| --- | --- | --- |
| Codex backend 规格 | 已定义 | 本文为 v0.1 第一真实 backend 权威。 |
| Codex stdio backend/profile 规格 | 已定义 | 本文为 v0.1 Codex app-server stdio backend kind 和 profile 权威。 |
| Codex Secret projection | 已实现/已通过主闭环 | runner Job 使用只读 Secret projection 和 writable `CODEX_HOME`Codex 测试凭据来自 `agentrun-v01-provider-codex``auth.json`/`config.toml`。 |
| Codex adapter | 已实现/已通过主闭环 | 当前代码已实现受控 `codex app-server --listen stdio://``initialize`/`thread/start`/`thread/resume`/`turn/start` response 校验、stderr 有界诊断、spawn/JSON parse/response invalid/timeout/provider 5xx availability failureKind,以及包含 retry error notification 的 fake app-server 自测试。 |
| 错误可观测与脱敏 | 已实现主路径 | child env、cwd、workspace 和 Codex home 只输出摘要;stderr tail 有界且标记截断;事件和 failure 统一走 redaction。 |
| 真实 provider turn | 已通过主闭环 | 真实 Codex provider turn 已经通过 RESTful API 和 CLI 综合联调;每次发布仍按 [spec-v01-validation.md](spec-v01-validation.md) 手动复验。 |
| `deepseek` profile | 已定义/待实现 | 需要作为同一 Codex stdio backend kind 的 profile 实现,使用 `agentrun-v01-provider-deepseek` 和独立 `CODEX_HOME` 完成真实联调。 |
| hostPath `~/.codex` | 不采用 | 只能通过 Kubernetes Secret projection 注入。 |
+1 -1
View File
@@ -130,7 +130,7 @@ Tekton promotion 可以读取 `deploy/deploy.json` 来 render runtime desired st
- `argocd/agentrun-v01` AppProject destination 只能包含 `agentrun-v01`
- `argocd/agentrun-g14-v01` source 必须指向 `v0.1-gitops:deploy/gitops/g14/runtime-v01`destination 必须是 `agentrun-v01`
- `v0.1` Secret、ServiceAccount、RBAC、PVC、ConfigMap 和 runtime config 必须独立命名或 namespace scope;文档、issue、trace 和 report 只记录 SecretRef 名称与 key,不记录值。
- `agentrun-mgr` 和 runner Job 只能通过 `spec-v01-secret-distribution.md` 定义的 SecretRef 注入 Postgres DSN 和 Codex auth/config 文件;测试 Codex 凭据来自 `~/.codex/auth.json``~/.codex/config.toml` 的 Kubernetes Secret projection,不得从 `deploy/deploy.json`、artifact catalog 或 generated manifest 中读取明文。
- `agentrun-mgr` 和 runner Job 只能通过 `spec-v01-secret-distribution.md` 定义的 SecretRef 注入 Postgres DSN 和 Codex stdio profile auth/config 文件;`codex` 默认 SecretRef 为 `agentrun-v01-provider-codex``deepseek` 默认 SecretRef 为 `agentrun-v01-provider-deepseek`。测试凭据来自 profile 专属 `auth.json``config.toml` 的 Kubernetes Secret projection,不得从 `deploy/deploy.json`、artifact catalog 或 generated manifest 中读取明文。
- Postgres `DATABASE_URL` Secret 必须使用实际创建的数据库名,v0.1 默认为 `agentrun_v01`;密码或其他 URL credential 必须 URL encode 后写入 DSN。Secret 值不进入 source/GitOpsruntime bootstrap 或 secret-management 流程负责创建与轮换。
- Codex provider Secret 在 GitOps manifest 中只能表现为 SecretRef 和只读 volume projectionrunner Job manifest 还必须包含 writable runtime home,用于把 Secret projection 复制到 `CODEX_HOME` 后运行 Codex。
- `agentrun_dev``agentrun_prod` 不得作为 `v0.1` namespace、Argo destination、Pipeline target 或验收目标。
+8 -2
View File
@@ -40,7 +40,7 @@ CLI 官方 TypeScript 入口固定为 `scripts/agentrun-cli.ts`。在 G14 非交
./scripts/agentrun runner start --run-id <runId> --backend <backendProfile>
./scripts/agentrun runner job --run-id <runId> --command-id <commandId>
./scripts/agentrun runner job --dry-run --run-id <runId> --command-id <commandId> --image <image>
./scripts/agentrun secrets codex render --dry-run [--codex-home <dir>]
./scripts/agentrun secrets codex render --dry-run [--profile codex|deepseek] [--codex-home <dir>]
./scripts/agentrun backends list
./scripts/agentrun server start|status
```
@@ -52,7 +52,8 @@ CLI 官方 TypeScript 入口固定为 `scripts/agentrun-cli.ts`。在 G14 非交
- 查询类命令返回当前 state、terminal_status、failureKind、event cursor 或 logPath。
- `events` 默认分页且有界,必须支持 `afterSeq``limit`
- `server logs` 返回有界日志摘要,并指向完整日志文件或 Kubernetes pod identity。
- `secrets codex render --dry-run` 返回 Codex provider Secret 创建计划、输入文件 bytes/hash、SecretRef、manifest 摘要和 apply 命令形状;它不得输出 Secret value 或执行 Kubernetes 写操作。
- `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`它不得输出 Secret value 或执行 Kubernetes 写操作。
- `backends list` 必须显示 `codex``deepseek` profile 的 backendKind、protocol、transport、command、requiredSecretKeys 和状态;不得因为 `deepseek` 尚未配置 Secret 就隐藏 capability。
## 配置与 Secret 边界
@@ -79,6 +80,10 @@ CLI 官方 TypeScript 入口固定为 `scripts/agentrun-cli.ts`。在 G14 非交
阅读本文和 [spec-v01-agentrun-mgr.md](spec-v01-agentrun-mgr.md),然后对同一个 run 分别使用 CLI 和 RESTful API 查询 run、command、events 和 terminal_status。确认 CLI 不维护独立状态,两种交互面观察结果一致。
### T5 Backend profile CLI 切换
阅读本文、[spec-v01-backend-codex.md](spec-v01-backend-codex.md) 和 [spec-v01-validation.md](spec-v01-validation.md),然后用正式 CLI 分别创建 `backendProfile=codex``backendProfile=deepseek` 的 run,按 `codex -> deepseek -> codex` 顺序执行真实 runner。确认 CLI 输出非空 JSONbackend_status 显示正确 profile/backendKind/protocol,缺失 `deepseek` SecretRef 时返回 `secret-unavailable`,不会 fallback 到 `codex`
## 规格的实现情况
| 规格项 | 状态 | 说明 |
@@ -88,3 +93,4 @@ CLI 官方 TypeScript 入口固定为 `scripts/agentrun-cli.ts`。在 G14 非交
| CLI 调 manager REST | 已实现 | CLI 通过 `ManagerClient` 调 manager REST;自测试可用内存 manager,综合联调必须指向真实 `agentrun-v01` manager。 |
| runner start/job | 已实现 | `runner start` 可执行 host process runner`runner job --dry-run` 可渲染 Kubernetes Job JSON`runner job` 正式路径通过 manager REST 创建 Kubernetes Job 并快速返回 job identity、SecretRef、retention 和轮询命令。 |
| CLI 测试规格 | 已定义/已验证主闭环 | 综合联调见 [spec-v01-validation.md](spec-v01-validation.md);每次发布仍按手动交互验收复跑。 |
| `deepseek` profile CLI | 已定义/待实现 | 需要扩展 secret render、backends list、run create examples 和 runner start/job 的 profile 可见性。 |
@@ -33,7 +33,7 @@
- `spec-v01-agentrun-mgr.md`manager REST API、tenant boundary、runner claim、event/status authority。
- `spec-v01-agentrun-runner.md`:短生命周期 runner、claim/poll/report、日志和 failureKind。
- `spec-v01-backend-adapter.md`backend adapter 合同、event normalization、failure mapping 和 redaction。
- `spec-v01-backend-codex.md`:第一真实 Codex backend`~/.codex` 测试凭据 Secret projection 和真实 turn 验收。
- `spec-v01-backend-codex.md`:第一真实 Codex app-server stdio backend、`codex`/`deepseek` profile`~/.codex` 测试凭据 Secret projection 和真实 turn 验收。
- `spec-v01-cli.md`AgentRun CLI 命令族、JSON 输出、短返回、日志可见和测试规格。
- `spec-v01-scheduler.md`:自动 scheduler 的 deferred 边界。
- 未来新增单服务规格必须使用 `spec-v01-<service-or-capability>.md`
@@ -63,7 +63,7 @@
- Manager 服务规格:[spec-v01-agentrun-mgr.md](spec-v01-agentrun-mgr.md)。
- Runner 服务规格:[spec-v01-agentrun-runner.md](spec-v01-agentrun-runner.md)。
- Backend adapter 规格:[spec-v01-backend-adapter.md](spec-v01-backend-adapter.md)。
- Codex backend 规格:[spec-v01-backend-codex.md](spec-v01-backend-codex.md)。
- Codex stdio backend/profile 规格:[spec-v01-backend-codex.md](spec-v01-backend-codex.md)。
- CLI 规格:[spec-v01-cli.md](spec-v01-cli.md)。
- Scheduler deferred 规格:[spec-v01-scheduler.md](spec-v01-scheduler.md)。
+26 -13
View File
@@ -1,6 +1,6 @@
# v0.1 Secret 与 provider credential 分发规格
本文定义 AgentRun `v0.1` 的 Secret 和 Code Agent provider credential 分发边界。真实 Code Agent backend 需要上游模型凭据;Codex 测试凭据以 `~/.codex/auth.json``~/.codex/config.toml` 为输入源,通过 Kubernetes Secret 投影进入 runner/backend Pod。这些值不得进入 Git source、GitOps branch、artifact catalog、event、trace、日志或 CLI 输出。
本文定义 AgentRun `v0.1` 的 Secret 和 Code Agent provider credential 分发边界。真实 Code Agent backend 需要上游模型凭据;Codex stdio profile 测试凭据以 `~/.codex/auth.json``~/.codex/config.toml` 形态为输入源,通过 Kubernetes Secret 投影进入 runner/backend Pod。这些值不得进入 Git source、GitOps branch、artifact catalog、event、trace、日志或 CLI 输出。
## 设计目标
@@ -15,7 +15,7 @@
| Secret 类别 | 用途 | 默认消费者 | v0.1 规则 |
| --- | --- | --- | --- |
| Postgres DSN | manager 连接 durable store | `agentrun-mgr` | 只通过 `agentrun-v01-mgr-db/DATABASE_URL` 注入。 |
| Codex 测试凭据文件 | 真实 Code Agent backend 调上游模型 | runner 或 backend adapter | 测试来源固定为 `~/.codex/auth.json``~/.codex/config.toml`,只通过 Kubernetes SecretRef 文件投影注入,不写入 run payload。 |
| Codex stdio profile 凭据文件 | 真实 Code Agent backend 调上游模型 | runner 或 backend adapter | `codex``deepseek` 均使用 `auth.json`/`config.toml` 文件形态,只通过 profile-scoped Kubernetes SecretRef 文件投影注入,不写入 run payload。 |
| Git SSH deploy key | Tekton checkout source/GitOps promotionArgo 读取 GitOps branch | Tekton、Argo CD | 只存在于 `agentrun-ci``argocd` Secret;不进入 runtime Pod。 |
| Registry credential | push/pull private registry | Tekton、runtime imagePullSecret | 只作为 ServiceAccount/imagePullSecret 引用。 |
| Future tenant credential | tenant 专属工具或外部服务 | runner/backend adapter | 必须先定义 SecretRef 和 secret scope,再允许 run 引用。 |
@@ -25,8 +25,9 @@
| 对象 | v0.1 建议 |
| --- | --- |
| Manager DB Secret | `agentrun-v01-mgr-db` key `DATABASE_URL` |
| Provider Secret | `agentrun-v01-provider-codex` keys `auth.json``config.toml` |
| Provider projection target | runner/backend 容器用户的 `~/.codex/auth.json``~/.codex/config.toml` |
| Codex Provider Secret | `agentrun-v01-provider-codex` keys `auth.json``config.toml` |
| DeepSeek Provider Secret | `agentrun-v01-provider-deepseek` keys `auth.json``config.toml` |
| Provider projection target | 只读 `/var/run/agentrun/secrets/<profile>-<index>/auth.json``config.toml`,再复制到当前 run/profile 的 writable `CODEX_HOME` |
| 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` |
@@ -36,24 +37,24 @@
## Codex 测试凭据注入
`v0.1` 综合联调使用的 Codex 测试凭据源固定为 operator 环境中的:
`v0.1` 综合联调使用的 Codex stdio profile 测试凭据源固定为 operator 环境中的文件形态
```text
~/.codex/auth.json
~/.codex/config.toml
```
这两个文件只能作为 Kubernetes Secret 创建或轮换的输入源。禁止把宿主机 `~/.codex` 以 hostPath 挂入 runner/backend Pod,禁止复制进镜像,禁止提交到 source branch、GitOps branch、artifact catalog、issue、PR、event、trace、日志或 CLI 输出。
这两个文件只能作为 Kubernetes Secret 创建或轮换的输入源。`codex` profile 默认使用 operator 当前 Codex 配置;`deepseek` profile 使用 operator 准备的 DeepSeek-compatible Codex 配置,可以来自另一个 `--codex-home` 或显式 `--auth-file`/`--config-file`禁止把宿主机 `~/.codex` 以 hostPath 挂入 runner/backend Pod,禁止复制进镜像,禁止提交到 source branch、GitOps branch、artifact catalog、issue、PR、event、trace、日志或 CLI 输出。
默认 Secret projection 规则:
| 项目 | v0.1 规格 |
| --- | --- |
| Kubernetes Secret | `agentrun-v01/agentrun-v01-provider-codex` |
| Kubernetes Secret | `agentrun-v01/agentrun-v01-provider-codex``agentrun-v01/agentrun-v01-provider-deepseek` |
| Secret key | `auth.json`,来自 `~/.codex/auth.json` |
| Secret key | `config.toml`,来自 `~/.codex/config.toml` |
| Projection path | 只读 Secret projection 挂到 `/var/run/agentrun/secrets/<profile>-<index>/auth.json``config.toml`;该路径只作为 credential source。 |
| Runtime config path | runner 启动时把授权的 Secret projection 复制到 writable `CODEX_HOME`默认 `/home/agentrun/.codex/auth.json``config.toml`。 |
| Runtime config path | runner 启动时把当前 `backendProfile` 授权的 Secret projection 复制到 writable `CODEX_HOME`Kubernetes Job 默认可以使用该 Job 独占的 `/home/agentrun/.codex/auth.json``config.toml`;复用进程必须使用 run/profile 独占目录。 |
| Projection mode | 只读,建议 `0400` 或等价最小权限 |
| Runtime env | `HOME=/home/agentrun``CODEX_HOME=/home/agentrun/.codex``AGENTRUN_CODEX_SECRET_HOME=<projection path>`;不得 fallback 到节点宿主机 home。 |
@@ -74,6 +75,15 @@ Run 的 `executionPolicy.secretScope` 只能包含引用,不包含值。示例
"keys": ["auth.json", "config.toml"],
"mountPath": "~/.codex"
}
},
{
"profile": "deepseek",
"secretRef": {
"namespace": "agentrun-v01",
"name": "agentrun-v01-provider-deepseek",
"keys": ["auth.json", "config.toml"],
"mountPath": "~/.codex"
}
}
],
"allowCredentialEcho": false
@@ -86,6 +96,7 @@ Run 的 `executionPolicy.secretScope` 只能包含引用,不包含值。示例
- `secretRef.namespace` 默认只能是 run 所在 lane namespace 或明确批准的 platform namespace。
- manager 可以保存 `secretRef`,但不得读取 Secret 值后存库。
- runner/backend adapter 获得 Secret 的方式必须来自 Kubernetes env/file projection 或受限 Secret API 读取;Codex 默认从只读 Secret projection 复制 `auth.json``config.toml` 到 writable `CODEX_HOME` 后启动 app-server,不得通过 run payload、event、CLI 参数或日志传递。
- runner/backend adapter 只能选择与 run `backendProfile` 同名的 provider credential`backendProfile=deepseek` 缺少 `deepseek` SecretRef 时必须 `secret-unavailable`,不得 fallback 到 `codex`
- Secret projection 不能直接作为 `CODEX_HOME`。Codex app-server 会读取并可能维护默认配置、PATH 或运行态文件;把只读 Secret volume 直接挂到 `CODEX_HOME` 会造成启动期写入失败。v0.1 的固定边界是:Secret volume 只读、`/home/agentrun``emptyDir` 提供可写 runtime home、复制动作只发生在 runner/backend 容器内且不打印文件内容。
- SecretRef 不存在或 RBAC 不允许时,run 必须失败为结构化 `failureKind=secret-unavailable` 或等价错误,不得降级成无凭证重试风暴。
@@ -101,7 +112,7 @@ Tekton promotion
Argo CD
-> syncs workload references to agentrun-v01
Kubernetes Secret
-> created from ~/.codex/auth.json and ~/.codex/config.toml by operator or approved secret-management flow
-> created from profile-specific auth.json and config.toml by operator or approved secret-management flow
runner/backend Pod
-> receives Codex auth/config via read-only file projection
-> copies authorized files into writable CODEX_HOME before starting Codex app-server
@@ -111,18 +122,19 @@ Secret 创建和轮换不由 source branch 自动生成;source branch 只声
## Codex Secret dry-run 工具
`v0.1` 提供只读 CLI 工具,用 operator 本地 `~/.codex/auth.json``~/.codex/config.toml` 构造 Kubernetes Secret 创建计划:
`v0.1` 提供只读 CLI 工具,用 operator 本地 `~/.codex/auth.json``~/.codex/config.toml` 形态的文件构造 Kubernetes Secret 创建计划:
```bash
./scripts/agentrun secrets codex render --dry-run
./scripts/agentrun secrets codex render --dry-run [--profile codex|deepseek]
```
可选参数:
- `--codex-home <dir>`:覆盖默认 `~/.codex` 输入目录。
- `--profile <name>`:默认 `codex``deepseek` 使用同一文件形态但默认 Secret name 为 `agentrun-v01-provider-deepseek`
- `--auth-file <path>` / `--config-file <path>`:分别覆盖输入文件路径。
- `--namespace <name>`:默认 `agentrun-v01`
- `--secret-name <name>`:默认 `agentrun-v01-provider-codex`
- `--secret-name <name>`:默认随 profile 变化,`codex` `agentrun-v01-provider-codex``deepseek``agentrun-v01-provider-deepseek`
输出必须是 JSON,并且只包含 `namespace``secretName``keys`、每个输入文件的 `bytes``sha256`/`contentHash`、整体 hash、redaction 状态、apply 命令形状和 Secret manifest 摘要。输出不得包含 Secret value、`auth.json` 明文、`config.toml` 明文、base64 `data` 字段或可直接恢复 credential 的内容。工具只支持 `--dry-run`;不得执行 `kubectl apply`
@@ -143,7 +155,7 @@ Secret 创建和轮换不由 source branch 自动生成;source branch 只声
### T2 Runner credential projection
阅读本文,然后启动一个最小 backend runner dry-run,确认 Pod file projection 挂在 `/var/run/agentrun/secrets/...` 且只读,`/home/agentrun` 是 writable runtime home`CODEX_HOME=/home/agentrun/.codex`runner/backend 会把授权文件复制到 `CODEX_HOME` 后再启动 Codex;event、日志和 CLI 输出只显示 redacted credential source,不显示文件内容。
阅读本文,然后分别启动 `backendProfile=codex``backendProfile=deepseek`最小 backend runner dry-run,确认 Pod file projection 挂在 `/var/run/agentrun/secrets/...` 且只读,`/home/agentrun` 是 writable runtime homerunner/backend 只把当前 profile 授权文件复制到 `CODEX_HOME` 后再启动 Codex;event、日志和 CLI 输出只显示 redacted credential source,不显示文件内容。
### T3 Missing secret failure
@@ -157,5 +169,6 @@ Secret 创建和轮换不由 source branch 自动生成;source branch 只声
| Kubernetes SecretRef 注入 | 已实现/已通过主闭环 | runner Job dry-run 和正式 Job 创建路径已按 run `executionPolicy.secretScope.providerCredentials` 生成 Secret volume projection、writable runtime home 和 `AGENTRUN_CODEX_SECRET_HOME`;真实 Secret 与 Codex turn 已通过主闭环。 |
| Codex Secret dry-run 工具 | 已实现 | `./scripts/agentrun secrets codex render --dry-run` 只输出 Secret 创建计划、hash 和 redacted manifest 摘要,不执行 apply。 |
| Codex auth/config file projection | 已实现主路径 | backend readiness 检查 `auth.json`/`config.toml` 可读性,缺失时返回 `secret-unavailable`;真实 runner Job 将只读 projection 复制到 writable `CODEX_HOME`。 |
| DeepSeek profile SecretRef | 已定义/待实现 | 需要新增 `agentrun-v01-provider-deepseek` render、Job projection、profile 选择和负向 missing-secret 验收。 |
| 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,后续单独更新规格。 |
+21 -7
View File
@@ -10,7 +10,7 @@ AgentRun 是面向 UniDesk 与 HWLAB 的共享 Code Agent 执行基础设施。`
- `agentrun-mgr` 是公共 RESTful API 和 durable facts authority,负责 run、command、event、runner、backend、lease 的持久状态和鉴权前置边界。
- `agentrun-runner` 是短生命周期 per-run 或 per-attempt 执行者,必须从 manager claim run,并把 event、heartbeat 和 terminal status 写回 manager。
- Backend adapter 隐藏具体 Agent 工具协议,`v0.1` 只要求一个真实 Agent backend 形成闭环;其他 backend 不进入第一波实现。
- Backend adapter 隐藏具体 Agent 工具协议,`v0.1` 使用一个真实 Codex stdio backend kind 形成闭环,并在该 kind 下支持 `codex``deepseek` profile;其他 backend kind 不进入第一波实现。
- AgentRun CLI 是受控操作入口,负责创建 run、提交 command、轮询 events、手动启动 runner 和查看 backend capabilityCLI 不等待完整模型 turn。
- Scheduler 是后续自动派发能力;`v0.1` 可以保留规格和状态字段,但不把自动调度作为第一阶段验收目标。
@@ -18,9 +18,22 @@ AgentRun 是面向 UniDesk 与 HWLAB 的共享 Code Agent 执行基础设施。`
AgentRun `v0.1` 的自研组件优先使用 Bun + TypeScript 实现:`agentrun-mgr``agentrun-runner`、backend adapter、Codex backend、AgentRun CLI 和后续 scheduler 都属于该边界。官方 TypeScript CLI 入口固定为 `scripts/agentrun-cli.ts`,入口只做参数解析和路由,复杂逻辑拆到 `scripts/src/``src/`G14/CI/人工非交互命令使用 `./scripts/agentrun` launcher 启动同一入口。Postgres、Kubernetes、Tekton、Argo CD、YAML manifest 和 shell 级容器启动命令属于外部运行面或部署面,不受“必须 TypeScript 实现”的约束。
`backendProfile=codex``v0.1` 协议固定为 Codex CLI app-server JSON-RPC over stdiorunner/backend adapter 启动受控 `codex app-server --listen stdio://` 子进程,经 stdin/stdout 发送换行分隔 JSON-RPC,请求顺序至少覆盖 `initialize``thread/start``thread/resume``turn/start`。直接调用 Responses HTTP、OpenAI SDK、`codex exec` 一次性输出或文本 fallback 只能作为诊断/自测试辅助,不能作为 Codex backend 综合联调通过证据。
`backendProfile=codex``backendProfile=deepseek``v0.1` 协议固定为同一个 Codex CLI app-server JSON-RPC over stdio backend kindrunner/backend adapter 启动受控 `codex app-server --listen stdio://` 子进程,经 stdin/stdout 发送换行分隔 JSON-RPC,请求顺序至少覆盖 `initialize``thread/start``thread/resume``turn/start``backendProfile` 只选择 profile/config/SecretRef`backendKind``protocol` 和进程生命周期仍是 `codex-app-server-stdio`直接调用 Responses HTTP、OpenAI SDK、`codex exec` 一次性输出或文本 fallback 只能作为诊断/自测试辅助,不能作为 Codex backend 综合联调通过证据。
实现参考必须优先读取并吸收两个成熟代码路径:UniDesk Code Queue 的 Bun/TS `src/components/microservices/code-queue/src/code-agent/codex.ts``common.ts`,以及 HWLAB v0.2 的 `internal/cloud/codex-stdio-session.mjs``scripts/code-agent-chat-smoke.mjs`。AgentRun 复用的是 stdio JSON-RPC、session/turn 生命周期、trace、redaction、Secret projection 和 failureKind 经验,不复制 UniDesk/HWLAB 的环境专用路径、业务 prompt 或明文凭据。
实现参考必须优先读取并吸收两个成熟代码路径:UniDesk Code Queue 的 Bun/TS `src/components/microservices/code-queue/src/code-agent/codex.ts``common.ts`,以及 HWLAB v0.2 的 `internal/cloud/codex-stdio-session.mjs``scripts/code-agent-chat-smoke.mjs``docs/reference/spec-v02-deepseek-proxy.md``docs/reference/code-agent-chat-readiness.md`。AgentRun 复用的是 stdio JSON-RPC、session/turn 生命周期、trace、redaction、Secret projection、profile overlay、DeepSeek/Moon Bridge 分层诊断和 failureKind 经验,不复制 UniDesk/HWLAB 的环境专用路径、业务 prompt、bridge host、namespace 或明文凭据。
## Backend Profile 边界
`v0.1` 需要支持两个可手动选择的 backend profile,但不引入完整多 backend 调度:
| backendProfile | backendKind | v0.1 处理 | SecretRef | 说明 |
| --- | --- | --- | --- | --- |
| `codex` | `codex-app-server-stdio` | 保留,P0 | `agentrun-v01-provider-codex` | 现有 GPT/Codex profile,必须保持默认行为不回归。 |
| `deepseek` | `codex-app-server-stdio` | 新增,P0 | `agentrun-v01-provider-deepseek` | DeepSeek-compatible Codex profile;通过 profile 专属 `auth.json`/`config.toml` 或等价 SecretRef 配置上游、模型和 base URL。 |
完整多 backend 路由仍然 deferred,含 OpenCode、Claude Code、host-native、Windows-native、scheduler capacity selection 和跨 backend 自动选择。`v0.1` 只允许 manager/runner 按 run 中的 `backendProfile` 显式选择 `codex``deepseek`,并在 capability 中报告两者共享同一个 `protocol=codex-app-server-jsonrpc-stdio``transport=stdio`
`codex``deepseek` 之间不得隐式 fallback:缺少 `deepseek` SecretRef 时必须失败为 `secret-unavailable`,不能改用 `codex` Secret`deepseek` 运行失败也不能重试到 `codex`。同一轮发布的综合联调必须证明 `codex -> deepseek -> codex` 的切换不会污染彼此的 SecretRef、`CODEX_HOME`、模型或 upstream 配置。
## 内部架构
@@ -59,14 +72,14 @@ Runner inbound API 只允许本地或私有诊断,不作为业务客户端入
| `agentrun-mgr` | 长驻服务 | 保留,P0 | 公共 RESTful API、durable facts、idempotency、runner claim、event append 和 status authority。 | `spec-v01-agentrun-mgr.md` |
| `agentrun-runner` | 短生命周期执行入口 | 保留,P0 | per-run/per-attempt executorclaim run、poll command、调用 backend、写回 events/status。 | `spec-v01-agentrun-runner.md` |
| Backend adapter | 执行适配层 | 保留,P0 | 统一 backend capability、event normalization、error mapping 和 credential boundary。 | `spec-v01-backend-adapter.md` |
| First real backend | 具体 Agent backend | 保留,P0 | `v0.1` 必须至少证明一个真实 Agent backend;默认候选是 Codex。 | `spec-v01-backend-codex.md` |
| Codex stdio backend profiles | 具体 Agent backend | 保留,P0 | `v0.1` 使用一个真实 Codex app-server stdio backend kind,必须支持 `codex``deepseek` 两个 profile;完整多 backend 路由仍 deferred。 | `spec-v01-backend-codex.md` |
| AgentRun CLI | CLI/Job 工具 | 保留,P0 | JSON 输出、短返回、run/command/event/runner/backend 操作入口。 | `spec-v01-cli.md` |
| Postgres durable store | 稳定外部服务 | 保留,P0 | 使用 `agentrun-v01-postgres` 保存 runs、commands、events、runners、backends、leases 和 migration ledger;不使用 file/sqlite 作为 v0.1 durable store。 | `spec-v01-postgres.md` |
| Secret distribution | 系统能力 | 保留,P0 | Provider credential 只通过 Kubernetes SecretRef、ServiceAccount/RBAC 和 runner env/file projection 分发;Codex 测试凭据使用 `~/.codex/auth.json``~/.codex/config.toml` 生成 Secret projectionsource、GitOps、logs 和 events 不保存明文。 | `spec-v01-secret-distribution.md` |
| Tenant policy boundary | Run schema 合同 | 保留,P0 | 作为 `Run` 的必填字段和最小校验存在,不做独立 policy enginetenant 的业务授权仍由 UniDesk/HWLAB 判定。 | 并入 `spec-v01-agentrun-mgr.md` |
| Observability | 最小事件/日志合同 | 保留,P1 子项 | 作为 manager/runner 的 event、terminal status、failureKind、logPath 和 redaction 最小合同,不拆独立观测系统。 | 并入 `spec-v01-agentrun-mgr.md``spec-v01-agentrun-runner.md` |
| `agentrun-scheduler` | 长驻调度器 | Deferred | M1-M3 稳定后再实现自动 pending scan、capacity selection 和 runner Job 创建。 | `spec-v01-scheduler.md` |
| 多 backend 路由 | 系统能力 | Deferred | `v0.1` 不做完整多 backend 调度,只保留 capability 模型。 | 后续版本 spec |
| 多 backend 路由 | 系统能力 | Deferred | `v0.1` 不做 backend kind 的自动路由和调度;仅支持同一 Codex stdio backend kind 下的 `codex`/`deepseek` profile 手动选择。 | 后续版本 spec |
| UI | 前端 | Deferred | `v0.1` 不要求独立 UIUniDesk/HWLAB canary 可通过 CLI/API 验证。 | 后续版本 spec |
| judge/retry 自动化 | 系统能力 | Deferred | `v0.1` 只定义基础 terminal 和 failure visibility,不实现复杂 judge。 | 后续版本 spec |
@@ -109,7 +122,7 @@ Run create 的最小字段合同:
| `projectId` | 必填,例如 `pikasTech/unidesk``pikasTech/HWLAB`。 |
| `workspaceRef` | 必填,描述 source/worktree/workspace,不由 runner 猜测。 |
| `providerId` | 必填,例如 `G14``D601`;只表示目标 provider,不直接授予权限。 |
| `backendProfile` | 必填,例如 `codex``v0.1` 只要求一个真实 backend 闭环。 |
| `backendProfile` | 必填,`v0.1` allowlist 为 `codex``deepseek`;两者共享 `codex-app-server-stdio` backend kind。 |
| `executionPolicy` | 必填或由 manager 显式写入默认值,至少包含 sandbox、approval、timeout、network 和 secret scope。 |
| `traceSink` | 字段必须存在;可以为 `null` 或显式 sink,表示标准事件是否需要镜像给 tenant。 |
@@ -169,5 +182,6 @@ Manager 负责校验、保存和返回这些字段;runner 只能消费已保
| Scheduler deferred 规格 | 已定义 | 见 [spec-v01-scheduler.md](spec-v01-scheduler.md)。 |
| `agentrun-mgr` 实现 | 已实现/已通过主闭环 | 已有 REST API、Postgres durable store、migration ledger、runner claim/lease/report、health/readiness 和 self-test memory 模式;真实 `agentrun-v01` runtime 已通过 Postgres/GitOps/readiness 和 run lifecycle 主闭环。 |
| `agentrun-runner` 实现 | 已实现/已通过主闭环 | host process runner 与 Kubernetes Job 共用 `runOnce`runner 通过 manager API claim/poll/report,不直连 Postgres;真实 Kubernetes Job 已完成 Codex turn。 |
| 第一真实 backend | 已实现/已通过主闭环 | Codex app-server stdio backend 已有协议、失败分类、脱敏和 fake self-test;真实 Codex provider turn 已通过 RESTful API 与 CLI 主闭环。 |
| `codex` profile | 已实现/已通过主闭环 | Codex app-server stdio backend 已有协议、失败分类、脱敏和 fake self-test;真实 Codex provider turn 已通过 RESTful API 与 CLI 主闭环。 |
| `deepseek` profile | 已定义/待实现 | 规格要求 DeepSeek 作为同一 Codex stdio backend kind 的 profile/config/SecretRef 选择进入 v0.1;实现和真实联调尚未完成。 |
| 自动 scheduler | Deferred | 不作为 `v0.1` 第一阶段验收目标。 |
+19 -4
View File
@@ -41,10 +41,11 @@
- 真实 `v0.1-gitops` artifact catalog 与 `deploy/gitops/g14/runtime-v01/**`
- 真实 Argo CD Application `agentrun-g14-v01` 同步到 `agentrun-v01`
- 真实 `agentrun-v01-postgres` StatefulSet、PVC、Service 和 migration ledger。
- 真实 Kubernetes SecretRef 注入 Postgres DSN 和 Code Agent provider credentialCodex 测试凭据必须来自 `~/.codex/auth.json``~/.codex/config.toml` 的 Kubernetes Secret projection。
- 真实 Kubernetes SecretRef 注入 Postgres DSN 和 Code Agent provider credentialCodex stdio profile 测试凭据必须来自 profile 专属 `auth.json``config.toml` 的 Kubernetes Secret projection。
- Codex Secret projection 必须先保持只读,再复制到 writable `CODEX_HOME` 后启动 app-server;综合联调不得把只读 Secret volume 直接当作 `CODEX_HOME` 的通过证据。
- 真实 `agentrun-mgr`、runner Job 或受控 runner process、真实 backend adapter。
- 至少一个真实 Code Agent provider turnCodex backend 必须通过 `codex app-server --listen stdio://` 的 JSON-RPC stdio turn 完成,mock、fixture、source-only、dry-run、fake provider、直接 Responses HTTP 或 `codex exec` 一次性输出不能作为通过证据。如果 provider credential SecretRef 缺失,综合联调必须标记 blocked,不能降级为 mock pass。
- 至少一个真实 Code Agent provider turnCodex stdio backend 必须通过 `codex app-server --listen stdio://` 的 JSON-RPC stdio turn 完成,mock、fixture、source-only、dry-run、fake provider、直接 Responses HTTP 或 `codex exec` 一次性输出不能作为通过证据。如果 provider credential SecretRef 缺失,综合联调必须标记 blocked,不能降级为 mock pass。
- 若变更涉及 backend profile,综合联调必须分别覆盖 `backendProfile=codex``backendProfile=deepseek`,并按 `codex -> deepseek -> codex` 顺序证明 profile 切换不互相污染。
综合联调最小闭环:
@@ -112,7 +113,7 @@ CLI 与 RESTful API 可以复用同一个真实 run 做联调。若两者观察
### T2 综合联调真实性
阅读本文,然后执行一次综合联调,确认所有关键依赖均为真实 `agentrun-v01` runtime、Postgres、SecretRef、runner、backend 和 provider credentialCodex 测试凭据必须通过 Kubernetes Secret projection 注入 `~/.codex/auth.json``~/.codex/config.toml`。任何缺失必须返回 blocked 或 failed。
阅读本文,然后执行一次综合联调,确认所有关键依赖均为真实 `agentrun-v01` runtime、Postgres、SecretRef、runner、backend 和 provider credentialCodex stdio profile 测试凭据必须通过 Kubernetes Secret projection 注入当前 profile 的 `auth.json``config.toml`。任何缺失必须返回 blocked 或 failed。
### T3 发布判定
@@ -138,18 +139,32 @@ CLI 与 RESTful API 可以复用同一个真实 run 做联调。若两者观察
- 对同一 run 使用相同 idempotency key 提交相同 command 两次,再用相同 key 提交不同 payload,确认前两次返回同一个 command,第三次结构化失败。
- 对同一 pending run 启动两个真实 runner 或重复 claim,确认只有一个 owner 成功,失败方为 `runner-lease-conflict` 或等价 failureKind,且不继续调用 backend。
- 用不存在的 provider SecretRef 创建 run 并启动 runner,确认失败为 `secret-unavailable`,不会降级为 mock pass,也不会打印 Secret value。
-`backendProfile=deepseek` 但只提供 `codex` SecretRef 的 run 启动 runner,确认失败为 `secret-unavailable`,不会 fallback 到 `codex`
- 对同一 run 分页读取 events,确认 `seq` 单调、`afterSeq` 翻页无重复、重复读取同一页不会改变 durable facts。
T7 只定义人工验收的检查面和判定口径。若后续为减少人工操作引入 helper 命令,它只能输出手动步骤、当前证据或 dry-run 计划,不能把这些负向场景改造成阻断发布的自动门禁。
### T8 Backend profile 真实切换验收
阅读本文、[spec-v01-services.md](spec-v01-services.md)、[spec-v01-backend-codex.md](spec-v01-backend-codex.md) 和 [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md),然后在真实 `agentrun-v01` 运行面用正式 CLI 和 RESTful API 手动验证以下内容:
- `GET /api/v1/backends``./scripts/agentrun backends list` 同时列出 `codex``deepseek`,并显示两者共享 `backendKind=codex-app-server-stdio``protocol=codex-app-server-jsonrpc-stdio``transport=stdio`
-`backendProfile=codex` 完成一个真实 app-server stdio turn,记录 runId、commandId、terminal_status 和 redacted backend_status。
-`backendProfile=deepseek` 完成一个真实 app-server stdio turn,确认 SecretRef 为 `agentrun-v01-provider-deepseek`runtime `CODEX_HOME``codex` run 隔离,assistant 回复非空或失败被正确归类为 provider blocker。
- 再次用 `backendProfile=codex` 完成真实 turn,确认没有继承 DeepSeek model/base URL/config。
- 删除或替换 `deepseek` SecretRef 后复测,必须 `secret-unavailable`,不能使用 `codex` SecretRef 或默认 Codex config。
T8 是涉及 backend profile 变更时的综合联调标准;不涉及 backend profile 的普通发布仍至少执行已有真实主闭环。
## 规格的实现情况
| 规格项 | 状态 | 说明 |
| --- | --- | --- |
| 两层验证模型 | 已定义 | 本文为 v0.1 验证权威。 |
| 自测试 task | 已实现 | `src/selftest/run.ts` 自动发现 `src/selftest/cases/*.ts`;覆盖 redaction/Postgres contract、manager memory、runner Job render/create、Codex fake app-server stdio 和 Secret render。 |
| 综合联调验收规格 | 已增强 | 本文保留人工交互验收模型;T4-T7 定义 CLI、RESTful、一致性负向场景的手动验收标准,不新增自动脚本或门禁。 |
| 综合联调验收规格 | 已增强 | 本文保留人工交互验收模型;T4-T8 定义 CLI、RESTful、一致性负向场景和 backend profile 切换的手动验收标准,不新增自动脚本或门禁。 |
| CLI 交互联调标准 | 已定义 | 必须只使用正式 CLI,验证真实 run 生命周期和可观测输出。 |
| RESTful API 交互联调标准 | 已定义 | 必须直连真实 manager HTTP JSON API,验证服务合同和 durable facts。 |
| 真实主闭环 | 已通过 | 当前 v0.1 已通过真实 Tekton/Argo、Postgres、SecretRef、Kubernetes runner Job、Codex stdio turn、RESTful API 和 CLI 主闭环;每次发布仍需按本文手动复验。 |
| `deepseek` profile 切换验收 | 已定义/待执行 | 实现 deepseek profile 后必须按 T8 做 100% 真实综合联调。 |
| mock 作为发布证据 | 不采用 | mock 只能证明自测试通过。 |