diff --git a/AGENTS.md b/AGENTS.md index 176d83c..36e5592 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -45,7 +45,13 @@ AgentRun 是面向 UniDesk 与 HWLAB 的共享 Agent 执行基础设施。本仓 - `docs/reference/spec-v01-services.md`:v0.1 服务总览、保留对象、deferred 对象和单服务规格索引。 - `docs/reference/spec-v01-cicd.md`:v0.1 分支、workspace、namespace、GitOps、registry、CI/CD 和发布验收规格。 - `docs/reference/spec-v01-postgres.md`:v0.1 Postgres durable store、schema migration 和 SecretRef 规格。 -- `docs/reference/spec-v01-secret-distribution.md`:v0.1 Code Agent API Key 和运行时 Secret 分发规格。 +- `docs/reference/spec-v01-secret-distribution.md`:v0.1 Code Agent provider credential 和运行时 Secret 分发规格。 - `docs/reference/spec-v01-validation.md`:v0.1 两层验证模型,自测试允许 mock,综合联调必须 100% 真实。 +- `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-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 模型和数据模型。 -- `docs/reference/cli.md`:按 `cli-spec` 固化的 CLI 与服务 API 约束。 +- `docs/reference/cli.md`:CLI 与服务 API 辅助参考;`v0.1` CLI 权威以 `spec-v01-cli.md` 为准。 diff --git a/docs/reference/architecture.md b/docs/reference/architecture.md index e6c4130..93085ba 100644 --- a/docs/reference/architecture.md +++ b/docs/reference/architecture.md @@ -200,7 +200,7 @@ Event 是 append-only,并按 seq 分页: - `agentrun_backends`:backend profile、capabilities、capacity 和 health; - `agentrun_leases`:当前 ownership 和 expiry。 -Postgres DSN、provider API Key 和未来 tenant credential 的分发边界见 [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md);source、GitOps、event、trace、日志和 CLI 输出都不得保存 Secret 明文。 +Postgres DSN、provider credential 和未来 tenant credential 的分发边界见 [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md);Codex 测试凭据通过 Kubernetes Secret projection 注入 `~/.codex/auth.json` 与 `~/.codex/config.toml`,source、GitOps、event、trace、日志和 CLI 输出都不得保存 Secret 明文。 ## 部署方向 diff --git a/docs/reference/cli.md b/docs/reference/cli.md index f2a95f0..d7f14e0 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -1,5 +1,7 @@ # AgentRun CLI 与服务 API 参考 +`v0.1` CLI 的权威规格是 [spec-v01-cli.md](spec-v01-cli.md)。本文保留为 CLI 与服务 API 的辅助参考;如果命令、测试规格或实现状态与 `spec-v01-cli.md` 冲突,以 `spec-v01-cli.md` 为准。 + AgentRun CLI 与服务 API 遵循 UniDesk `cli-spec` 原则。本文在 CLI 实现前先固化期望形态,避免实现漂移成长阻塞命令或隐藏状态。 ## CLI 形态 diff --git a/docs/reference/spec-v01-agentrun-mgr.md b/docs/reference/spec-v01-agentrun-mgr.md new file mode 100644 index 0000000..cd7ed16 --- /dev/null +++ b/docs/reference/spec-v01-agentrun-mgr.md @@ -0,0 +1,114 @@ +# v0.1 agentrun-mgr 服务规格 + +`agentrun-mgr` 是 AgentRun `v0.1` 的长驻管理服务。它是公共 RESTful API、durable facts、tenant policy boundary、runner claim、event append 和 terminal status 的 authority;业务客户端、CLI 和 runner 都不能绕过它直接写 Postgres。 + +## 在系统中的职责划分 + +- 提供 Manager 公共 API:创建和查询 run、提交 command、分页读取 events、查询 backend capability。 +- 提供 Runner 私有 API:runner register、claim run、lease heartbeat、poll commands、append events、ack command、上报 status。 +- 校验并持久化 `tenantId`、`projectId`、`workspaceRef`、`providerId`、`backendProfile`、`executionPolicy` 和 `traceSink`。 +- 执行最小 tenant policy boundary:只做 schema、allowlist、idempotency、secret scope 和 executionPolicy 范围检查;不内建 UniDesk/HWLAB 的业务授权。 +- 使用 Postgres 保存 runs、commands、events、runners、backends、leases 和 migration ledger。 +- 输出结构化 health/readiness、failureKind、redacted SecretRef 和 trace correlation。 + +## 内部架构 + +`agentrun-mgr` 运行在 `agentrun-v01` namespace,长驻 Deployment/Service 名称使用 `agentrun-mgr`。服务实现可以按语言和框架演进,但必须保持以下边界: + +- HTTP JSON API 是稳定跨服务边界;不使用 SSE、WebSocket、long-polling 或长同步 `turn` 请求作为 `v0.1` 必备能力。 +- Postgres adapter 是唯一 durable store adapter;file、sqlite、JSONL 或内存状态只能用于自测试。 +- Migration 必须在 readiness 前完成或显式 fail fast,不能以空 schema 静默启动。 +- Provider credential、Codex auth/config、Postgres DSN 明文不进数据库、event、trace、日志或 CLI 输出。 +- Manager 可以保存 SecretRef 和 credential source reference,但不得读取 provider Secret 值后存库。 + +## API 接口说明 + +公共 API 的 `v0.1` 范围: + +```http +GET /health +GET /health/live +GET /health/readiness +POST /api/v1/runs +GET /api/v1/runs/:runId +GET /api/v1/runs/:runId/events?afterSeq=0&limit=100 +POST /api/v1/runs/:runId/commands +GET /api/v1/runs/:runId/commands/:commandId +GET /api/v1/backends +``` + +Runner 私有 API 的 `v0.1` 范围: + +```http +POST /api/v1/runners/register +POST /api/v1/runs/:runId/claim +PATCH /api/v1/runs/:runId/lease +GET /api/v1/runs/:runId/commands?afterSeq=0&limit=20 +POST /api/v1/runs/:runId/events +PATCH /api/v1/runs/:runId/status +POST /api/v1/commands/:commandId/ack +``` + +所有 API 成功和失败响应都必须是 JSON。失败响应至少包含 `failureKind`、`message` 和 trace correlation;不得出现空 stdout/空 response 被误判为成功的情况。 + +## Run 与 Command 合同 + +`POST /api/v1/runs` 必须持久化以下字段: + +| 字段 | v0.1 规则 | +| --- | --- | +| `tenantId` | 必填,只做 allowlist/schema 校验,默认候选为 `unidesk`、`hwlab`。 | +| `projectId` | 必填,例如 `pikasTech/unidesk`、`pikasTech/HWLAB`。 | +| `workspaceRef` | 必填,描述 source/worktree/workspace,不由 runner 猜测。 | +| `providerId` | 必填,例如 `G14`、`D601`;只表示目标 provider,不直接授予业务权限。 | +| `backendProfile` | 必填,`v0.1` 默认真实 backend 为 `codex`。 | +| `executionPolicy` | 必填或由 manager 显式补齐默认值,至少包含 sandbox、approval、timeout、network 和 secretScope。 | +| `traceSink` | 字段必须存在;可以为 `null` 或显式 sink。 | + +`POST /api/v1/runs/:runId/commands` 必须支持 idempotency key。相同 key 且 payload hash 相同应返回既有 command;相同 key 但 payload hash 不同必须结构化失败。 + +## Tenant Policy Boundary + +`v0.1` 不实现独立 policy engine。Manager 只做基础边界收敛: + +- 校验 tenant/project/provider/backend 是否在 `v0.1` 允许集合内。 +- 校验 workspaceRef 形态存在且与 tenant 请求一致;不替 tenant 判断某个 repo 操作是否业务授权。 +- 校验 executionPolicy 不扩大 sandbox、network、approval、timeout 和 secretScope。 +- 校验 secretScope 只引用 [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md) 中允许的 SecretRef。 +- 对 HWLAB live device mutation、UniDesk production deploy、GitHub issue/PR 写入等业务授权,Manager 只记录字段和审计事件,不把业务规则硬编码成通用门禁。 + +## 最小 Observability 合同 + +- events append-only,单 run 内 `seq` 单调递增。 +- 每个 run 必须最终出现 `terminal_status`,或保持明确 non-terminal status 并可查询 lease/heartbeat。 +- failureKind 至少能区分 `schema-invalid`、`tenant-policy-denied`、`secret-unavailable`、`runner-lease-conflict`、`backend-failed`、`provider-auth-failed`、`infra-failed`、`cancelled`。 +- health/readiness 必须返回 Postgres reachable、schema migration ready、SecretRef redacted 状态和 build/source metadata。 +- 日志、event、trace、health 和 diagnostics 不得输出 provider credential、Codex auth/config 内容、DSN password、token 或 URL credential。 + +## 测试规格 + +### T1 Manager health/readiness + +阅读 `AGENTS.md`、本文和 [spec-v01-postgres.md](spec-v01-postgres.md),然后用 RESTful API 手动测试 `agentrun-mgr` 的 `/health/live` 和 `/health/readiness`。确认响应为 JSON,包含 serviceId、Postgres readiness、migration 状态、source commit、SecretRef redacted 状态;不得输出任何 Secret value。 + +### 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` 查询。 + +### T3 Command idempotency + +阅读本文,然后对同一个 run 使用相同 idempotency key 提交相同 command 两次,再提交 payload hash 不同的第三次。确认前两次返回同一个 command,第三次结构化失败,且所有响应为 JSON。 + +### T4 Runner claim 与 event pagination + +阅读本文和 [spec-v01-agentrun-runner.md](spec-v01-agentrun-runner.md),然后让两个真实 runner 尝试 claim 同一个 run。确认只有一个 owner 成功,另一个返回 `runner-lease-conflict` 或等价 failureKind;随后分页读取 events,确认 `seq` 单调、不重复、不丢失。 + +## 规格的实现情况 + +| 规格项 | 状态 | 说明 | +| --- | --- | --- | +| `agentrun-mgr` 服务规格 | 已定义 | 本文为 v0.1 manager 权威。 | +| Manager REST API | 未实现 | 需要后续代码实现。 | +| Tenant policy boundary | 已定义/未实现 | v0.1 只做最小 schema/allowlist/secretScope 边界。 | +| Postgres durable adapter | 未实现 | 见 [spec-v01-postgres.md](spec-v01-postgres.md)。 | +| Observability 最小合同 | 已定义/未实现 | event、terminal status、failureKind 和 redaction 需要代码实现。 | diff --git a/docs/reference/spec-v01-agentrun-runner.md b/docs/reference/spec-v01-agentrun-runner.md new file mode 100644 index 0000000..f5be9b1 --- /dev/null +++ b/docs/reference/spec-v01-agentrun-runner.md @@ -0,0 +1,103 @@ +# v0.1 agentrun-runner 服务规格 + +`agentrun-runner` 是 AgentRun `v0.1` 的短生命周期执行入口。它以 per-run 或 per-attempt 方式运行,必须从 `agentrun-mgr` claim run,调用一个 backend adapter,并把 events、heartbeat、command ack 和 terminal status 写回 manager。 + +## 在系统中的职责划分 + +- 作为 Kubernetes Job 或受控 host process 启动;不作为普通业务客户端直接调用的长驻公共服务。 +- 从 manager register、claim run、续租 lease、poll commands、ack command、append events、patch status。 +- 根据 run 中的 `backendProfile` 和 `executionPolicy.secretScope` 调用 backend adapter。 +- 将 backend stdout/stderr、assistant message、tool call、error 和 terminal status 归一化为 manager event。 +- 提供可定位的 job/process identity、logPath、attempt id 和 failureKind。 +- 不直连 Postgres,不扩大 workspace、network、approval 或 secret scope。 + +## 内部架构 + +`v0.1` 默认 runner 形态是 `agentrun-v01` namespace 中的短生命周期 Job,Job 名称建议使用 `agentrun-v01-runner--`。MVP 允许 CLI 启动受控本地 process,但该 process 仍必须通过 manager API claim/report。 + +Runner 启动参数必须显式包含: + +- manager API base URL。 +- runId 和 attemptId。 +- backendProfile。 +- logPath 或 Kubernetes job/pod identity。 +- source commit/build metadata。 + +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)。 + +## Runner 生命周期 + +标准状态方向: + +```text +starting -> registered -> claimed -> running -> terminal +starting -> registered -> claim_failed +claimed -> running -> backend_failed +claimed -> running -> cancelled +claimed -> lease_lost +``` + +规则: + +- runner 必须先 register,再 claim run;claim 失败不能继续调用 backend。 +- lease heartbeat 必须可观察;过期或冲突时写入 failure event 或明确退出原因。 +- command 只能从 manager poll;不得从本地文件或临时参数伪造正式 command。 +- backend 产生的所有可见输出必须先经过 adapter normalization 和 redaction,再 append 到 manager。 +- terminal status 上报后 runner 可以退出;退出码与 terminal status 必须一致或在日志中可解释。 + +## Manager API 交互 + +Runner 只使用 manager 私有 API: + +```http +POST /api/v1/runners/register +POST /api/v1/runs/:runId/claim +PATCH /api/v1/runs/:runId/lease +GET /api/v1/runs/:runId/commands?afterSeq=0&limit=20 +POST /api/v1/runs/:runId/events +PATCH /api/v1/runs/:runId/status +POST /api/v1/commands/:commandId/ack +``` + +Runner inbound HTTP 不是业务 API。若实现本地诊断端点,只允许 `GET /health` 或 `GET /debug/status`,并且只能暴露在本地或 pod 内部调试面。 + +## Failure 与 Redaction + +Runner 必须把以下失败归类为结构化 failureKind: + +- `secret-unavailable`:SecretRef 缺失、RBAC 拒绝或 Secret projection 不完整。 +- `provider-auth-failed`:上游 provider 鉴权失败。 +- `backend-failed`:backend 进程退出、协议错误或返回 terminal error。 +- `runner-lease-conflict`:claim/lease 被其他 runner 持有。 +- `infra-failed`:Job 启动、网络、manager API 或文件系统基础设施失败。 +- `cancelled`:收到 interrupt/cancel 且已停止执行。 + +Runner 日志必须实时 flush 到文件或 pod log,CLI 启动 runner 时必须返回 logPath 或 job/pod identity。日志、event、trace 和 CLI 输出不得出现 provider credential、`auth.json`、`config.toml` 内容、DSN password、token 或 URL credential。 + +## 测试规格 + +### T1 Runner 启动可见性 + +阅读 `AGENTS.md`、本文和 [spec-v01-cli.md](spec-v01-cli.md),然后用正式 AgentRun CLI 为一个真实 run 启动 runner。确认 CLI 立即返回 JSON,包含 runId、attemptId、job/process identity、logPath 和后续 poll command;不得等待完整模型 turn。 + +### T2 Claim 与 lease 冲突 + +阅读本文和 [spec-v01-agentrun-mgr.md](spec-v01-agentrun-mgr.md),然后对同一个 run 启动两个 runner。确认只有一个 runner claim 成功,失败方输出结构化 failureKind,并且 manager events 中能看到冲突或拒绝原因。 + +### T3 Backend event round-trip + +阅读本文和 [spec-v01-backend-adapter.md](spec-v01-backend-adapter.md),然后用真实 backend 执行一个最短 turn。确认 runner append assistant/output/error/backend_status/terminal_status 中的必要 events,event seq 单调,terminal status 可通过 manager 查询。 + +### T4 Missing Secret failure + +阅读本文和 [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md),然后用缺失 Codex SecretRef 的 run 启动 runner。确认 runner 不调用 provider,run 失败为 `secret-unavailable` 或等价 failureKind,日志和事件不泄露 Secret 值。 + +## 规格的实现情况 + +| 规格项 | 状态 | 说明 | +| --- | --- | --- | +| `agentrun-runner` 服务规格 | 已定义 | 本文为 v0.1 runner 权威。 | +| Kubernetes Job runner | 未实现 | 需要后续 runtime/GitOps 实现。 | +| host process runner | 未实现 | 可作为 MVP 手动 dispatch,但仍必须走 manager API。 | +| claim/lease/report client | 未实现 | 需要后续代码实现。 | +| runner redaction | 已定义/未实现 | 需与 backend adapter 共同实现。 | diff --git a/docs/reference/spec-v01-backend-adapter.md b/docs/reference/spec-v01-backend-adapter.md new file mode 100644 index 0000000..05b4b66 --- /dev/null +++ b/docs/reference/spec-v01-backend-adapter.md @@ -0,0 +1,86 @@ +# v0.1 Backend Adapter 规格 + +Backend adapter 是 runner 与具体 Code Agent 工具之间的适配层。它隐藏 Codex、OpenCode、Claude Code、host-native 或 Windows-native 的内部协议,把输入、事件、错误和 terminal status 归一化为 AgentRun 公共模型。 + +## 在系统中的职责划分 + +- 根据 `backendProfile` 选择具体 backend 实现;`v0.1` 必须至少证明一个真实 Agent backend,默认是 `codex`。 +- 接收 manager 持久化后的 run、command 和 executionPolicy;不得自行扩大 workspace、network、approval 或 secret scope。 +- 调用具体 backend,并把 backend 输出归一化为 AgentRun events。 +- 负责 provider/auth/backend/protocol 错误到 failureKind 的映射。 +- 负责 backend 输出和错误中的 credential redaction。 +- 暴露 backend capability 给 manager,用于 `GET /api/v1/backends`。 + +## Adapter 合同 + +第一版可以把 adapter 实现为 runner 进程内模块,不要求独立 Deployment。无论实现形态如何,对 runner 的逻辑合同必须稳定: + +```text +resolveProfile(profile) -> capability +prepare(run, command, secretProjection) -> executionContext +startTurn(executionContext) -> normalized event stream +interrupt(executionContext, command) -> backend interrupt attempt +finalize(executionContext) -> terminal status +redact(value) -> redacted value +``` + +Adapter 输入必须来自 manager 保存的 run/command 和 Kubernetes Secret projection;不得从 CLI 参数、临时环境变量或 Git 文件读取 provider credential 明文。 + +## 标准事件 + +Adapter 输出给 runner 的 event 类型至少包括: + +- `backend_status`:backend 启动、模型/profile、能力和阶段状态,不包含 Secret 值。 +- `assistant_message`:模型回复的用户可见文本。 +- `tool_call`:工具调用摘要和 redacted 参数。 +- `command_output`:stdout/stderr 或命令输出摘要。 +- `diff`:代码变更摘要或 patch 片段;必须受长度限制。 +- `error`:结构化错误和 failureKind。 +- `terminal_status`:completed、failed、cancelled、blocked 等终态。 + +事件必须有上限和分页友好形态。大型日志、完整 stdout 或完整 trace 应进入 logPath 或后续 artifact,不得一次性塞入单个 event 造成输出爆炸。 + +## Failure Mapping + +Adapter 必须把 backend 错误映射为稳定 failureKind: + +| failureKind | 典型来源 | +| --- | --- | +| `secret-unavailable` | Secret projection 缺失、文件不存在、权限不可读。 | +| `provider-auth-failed` | provider credential 或 auth file 无效、上游返回 401/403。 | +| `provider-rate-limited` | 上游限流或 quota 错误。 | +| `backend-protocol-error` | backend 输出无法解析、协议字段缺失。 | +| `backend-failed` | backend 进程非零退出或 terminal error。 | +| `backend-timeout` | executionPolicy timeout 触发。 | +| `cancelled` | interrupt/cancel 生效。 | + +## Credential Boundary + +- Adapter 只能看到运行时投影出来的最小 Secret 文件或 env;不得枚举整个 namespace Secret。 +- Adapter 不得把 Secret 值写入 event、trace、日志、CLI 输出、health 或 Postgres。 +- Codex backend 的 `auth.json` 和 `config.toml` 整体按敏感文件处理,即使其中包含非敏感配置,也不得输出原文。 +- Provider base URL、model 名称和 profile 名称可以输出,但 URL credential、Authorization header、token、api_key、password 必须 redacted。 + +## 测试规格 + +### T1 Adapter 自测试 + +阅读本文,然后用 mock backend 做组件自测试,确认 adapter 能把 assistant/output/error/terminal 输出归一化为标准 events,并能对 token、Authorization header、URL credential 和 Secret 文件内容做 redaction。该测试属于自测试,不作为综合联调通过证据。 + +### T2 Failure mapping 自测试 + +阅读本文,然后用 mock 错误覆盖 missing secret、provider auth failure、rate limit、protocol error、timeout 和 cancel。确认每类错误都映射到稳定 failureKind,且输出为 JSON 或结构化 event。 + +### 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 泄露。 + +## 规格的实现情况 + +| 规格项 | 状态 | 说明 | +| --- | --- | --- | +| Backend adapter 合同 | 已定义 | 本文为 v0.1 adapter 权威。 | +| 通用 adapter 模块 | 未实现 | 需要后续代码实现。 | +| event normalization | 已定义/未实现 | 需后续实现和测试。 | +| failure mapping | 已定义/未实现 | 需后续实现和测试。 | +| 多 backend 路由 | Deferred | v0.1 只要求一个真实 backend 闭环。 | diff --git a/docs/reference/spec-v01-backend-codex.md b/docs/reference/spec-v01-backend-codex.md new file mode 100644 index 0000000..6477f80 --- /dev/null +++ b/docs/reference/spec-v01-backend-codex.md @@ -0,0 +1,78 @@ +# v0.1 Codex Backend 规格 + +Codex backend 是 AgentRun `v0.1` 的第一真实 Code Agent backend 候选。它用于证明 runner、backend adapter、Kubernetes Secret projection、真实 provider 调用、event normalization 和 terminal status 的完整闭环。 + +## 在系统中的职责划分 + +- 作为 `backendProfile=codex` 的具体实现。 +- 使用真实 Codex/Codex-compatible 配置执行最短 turn,不使用 fake provider 作为综合联调通过证据。 +- 消费 Kubernetes Secret projection 提供的 Codex 凭据文件。 +- 把 Codex 输出归一化为 AgentRun 标准 events 和 terminal status。 +- 将 provider/auth/protocol/timeout/cancel 错误映射为 [spec-v01-backend-adapter.md](spec-v01-backend-adapter.md) 定义的 failureKind。 + +## 测试凭据来源 + +`v0.1` 综合联调用的 Codex 测试凭据源固定为 operator 环境中的以下两个文件: + +```text +~/.codex/auth.json +~/.codex/config.toml +``` + +这两个文件只能作为 Kubernetes Secret 创建或轮换的输入源,不能通过 hostPath 挂载进 Pod,不能复制进镜像,不能提交到 source branch、GitOps branch、artifact catalog、issue、PR、event、trace、日志或 CLI 输出。 + +`v0.1` 默认 Kubernetes Secret: + +| 对象 | v0.1 规格 | +| --- | --- | +| Namespace | `agentrun-v01` | +| Secret name | `agentrun-v01-provider-codex` | +| 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` | +| File mode | 只读,建议 `0400` 或等价最小权限 | + +Kubernetes Secret 的创建、轮换和权限控制属于集群密钥管理流程;source branch 只声明 SecretRef 名称、key 和 mount intent。`deploy/deploy.json` 和 rendered GitOps manifest 不得包含 Secret data。 + +## Runtime 行为 + +- Adapter 必须在调用 Codex 前验证 `auth.json` 和 `config.toml` 均存在且可读;缺失时返回 `secret-unavailable`。 +- Codex 运行时必须使用被投影的 `.codex` 目录;不得 fallback 到镜像内默认凭据或节点宿主机 `~/.codex`。 +- 若 `config.toml` 指向 hyueapi 或其他 OpenAI-compatible upstream,runner/backend Pod 的 proxy 与 `NO_PROXY` 必须保持该配置可用;不得在日志中打印完整 auth/config 内容。 +- 模型名、provider profile、upstream host 可以作为 redacted metadata 输出;provider credential、token、Authorization header 和文件内容不得输出。 +- 一个最短 turn 至少要产生 `backend_status`、一个 assistant 或 error event、以及 `terminal_status`。 + +## 与 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 或文件内容。 + +## 测试规格 + +### T1 Codex Secret projection + +阅读 `AGENTS.md`、本文和 [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md),然后在 `agentrun-v01` 中通过 Kubernetes Secret 管理把 operator 的 `~/.codex/auth.json` 与 `~/.codex/config.toml` 注入为 `agentrun-v01-provider-codex`。确认 runner/backend Pod 只能看到投影后的 `~/.codex/auth.json` 和 `~/.codex/config.toml`,没有 hostPath,日志和 event 不显示文件内容。 + +### T2 真实 Codex 最短 turn + +阅读本文和 [spec-v01-validation.md](spec-v01-validation.md),然后用 `backendProfile=codex` 创建真实 run 并提交一个最短 `turn` command。确认 runner 调用真实 Codex provider,manager 可查询 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。 + +### T4 Provider auth failure + +阅读本文,然后使用无效的 Codex Secret 创建 run。确认 backend 返回 `provider-auth-failed` 或等价 failureKind,记录上游状态分类和 trace correlation,但不打印 Authorization header、token 或 auth/config 文件内容。 + +## 规格的实现情况 + +| 规格项 | 状态 | 说明 | +| --- | --- | --- | +| Codex backend 规格 | 已定义 | 本文为 v0.1 第一真实 backend 权威。 | +| Codex Secret projection | 未实现 | 需要后续 Kubernetes Secret 和 runner/backend manifest。 | +| Codex adapter | 未实现 | 需要后续代码实现。 | +| 真实 provider turn | 未实现 | 综合联调必须真实完成后才能发布通过。 | +| hostPath `~/.codex` | 不采用 | 只能通过 Kubernetes Secret projection 注入。 | diff --git a/docs/reference/spec-v01-cicd.md b/docs/reference/spec-v01-cicd.md index fccd922..73b7f93 100644 --- a/docs/reference/spec-v01-cicd.md +++ b/docs/reference/spec-v01-cicd.md @@ -115,7 +115,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 和 Code Agent API Key,不得从 `deploy/deploy.json`、artifact catalog 或 generated manifest 中读取明文。 +- `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_dev` 和 `agentrun_prod` 不得作为 `v0.1` namespace、Argo destination、Pipeline target 或验收目标。 ## 手动和热修边界 diff --git a/docs/reference/spec-v01-cli.md b/docs/reference/spec-v01-cli.md new file mode 100644 index 0000000..02bfd98 --- /dev/null +++ b/docs/reference/spec-v01-cli.md @@ -0,0 +1,78 @@ +# v0.1 AgentRun CLI 规格 + +AgentRun CLI 是 `v0.1` 的受控人工操作和验收入口。它必须遵循 UniDesk `cli-spec` 原则:默认 JSON 输出、禁止空输出伪成功、禁止长阻塞、日志可见、配置显式校验,并优先通过 `agentrun-mgr` RESTful API 完成跨服务操作。 + +## 在系统中的职责划分 + +- 创建 run、查询 run、提交 command、查询 command、分页读取 events。 +- 手动启动 runner,本地 process 或 Kubernetes Job 均必须快速返回 job/process identity 和 logPath。 +- 查询 backend capability 和 manager health。 +- 为综合联调提供 CLI 交互面;不得替代 RESTful API 合同测试。 +- 不直连 Postgres,不读取 provider Secret 值,不把 debug/mock 路径伪装成正式验收。 + +## CLI 入口 + +`v0.1` 固定规划入口: + +```text +scripts/agentrun-cli.ts +scripts/src/*.ts +``` + +入口文件只负责参数解析和路由,具体实现拆到 `scripts/src/`。CLI 命令默认输出 JSON;任何命令无 stdout 都是失败。单次 CLI 调用必须在 60 秒内返回,长时间模型 turn 通过 status/events 后续命令观察。 + +## 初始命令族 + +```bash +bun scripts/agentrun-cli.ts runs create --json-file +bun scripts/agentrun-cli.ts runs show +bun scripts/agentrun-cli.ts runs events --after-seq --limit +bun scripts/agentrun-cli.ts commands create --type turn --json-file +bun scripts/agentrun-cli.ts commands show +bun scripts/agentrun-cli.ts runner start --run-id --backend +bun scripts/agentrun-cli.ts backends list +bun scripts/agentrun-cli.ts server start|status|stop|logs +``` + +具体参数可以在实现时按代码结构微调,但行为必须保持: + +- 创建类命令返回 `runId`、`commandId`、status 和下一步 poll command。 +- `runner start` 返回 attemptId、job/process identity、logPath 和后续 status/events 命令。 +- 查询类命令返回当前 state、terminal_status、failureKind、event cursor 或 logPath。 +- `events` 默认分页且有界,必须支持 `afterSeq` 和 `limit`。 +- `server logs` 返回有界日志摘要,并指向完整日志文件或 Kubernetes pod identity。 + +## 配置与 Secret 边界 + +- CLI 配置必须显式校验;部署关键值不得静默 fallback。 +- CLI 调用 manager REST API;不得直接连 Postgres 或读 Kubernetes Secret value。 +- CLI 可以显示 SecretRef 名称、key、credential source 和 readiness,但不得显示 Secret value、Codex `auth.json`、Codex `config.toml`、DSN password、token 或 URL credential。 +- Debug 子命令可以用于开发,但综合联调和测试规格不得用 debug 子命令作为通过证据。 + +## 测试规格 + +### T1 CLI run 生命周期 + +阅读 `AGENTS.md`、本文和 [spec-v01-validation.md](spec-v01-validation.md),然后用正式 AgentRun CLI 创建 run、提交 `turn` command、启动 runner、轮询 command 和 events 直到 terminal_status。确认每个命令输出非空 JSON,60 秒内返回,并给出下一步可执行命令或 logPath。 + +### T2 CLI 错误可见性 + +阅读本文,然后用非法 backendProfile、缺失 SecretRef 和无效 runId 分别调用正式 CLI。确认每次失败都有 JSON 输出、failureKind、message、trace correlation 和 logPath 或诊断入口;不得空输出或只输出布尔值。 + +### T3 CLI 日志可见性 + +阅读本文,然后启动一个会失败的 runner,并通过 CLI 返回的 logPath 或 pod identity 读取实际日志。确认日志包含足够定位失败原因的信息、异常 trace 或错误分类,同时没有 Secret value。 + +### T4 CLI 与 RESTful 一致性 + +阅读本文和 [spec-v01-agentrun-mgr.md](spec-v01-agentrun-mgr.md),然后对同一个 run 分别使用 CLI 和 RESTful API 查询 run、command、events 和 terminal_status。确认 CLI 不维护独立状态,两种交互面观察结果一致。 + +## 规格的实现情况 + +| 规格项 | 状态 | 说明 | +| --- | --- | --- | +| AgentRun CLI 规格 | 已定义 | 本文为 v0.1 CLI 权威。 | +| `scripts/agentrun-cli.ts` | 未实现 | 需要后续代码实现。 | +| CLI 调 manager REST | 未实现 | 需随 manager API 实现。 | +| runner start | 未实现 | 需随 runner Job/host process 实现。 | +| CLI 测试规格 | 已定义 | 综合联调见 [spec-v01-validation.md](spec-v01-validation.md)。 | diff --git a/docs/reference/spec-v01-documentation-governance.md b/docs/reference/spec-v01-documentation-governance.md index 0ecde4a..b139b87 100644 --- a/docs/reference/spec-v01-documentation-governance.md +++ b/docs/reference/spec-v01-documentation-governance.md @@ -28,9 +28,15 @@ - `spec-v01-services.md`:服务总览、保留和 deferred 对象。 - `spec-v01-cicd.md`:版本 lane、GitOps、namespace、registry 和发布验收。 - `spec-v01-postgres.md`:Postgres durable store、schema migration 和 DB SecretRef。 -- `spec-v01-secret-distribution.md`:Code Agent API Key、Postgres DSN 和运行时 Secret 分发。 +- `spec-v01-secret-distribution.md`:Code Agent provider credential、Postgres DSN 和运行时 Secret 分发。 - `spec-v01-validation.md`:两层验证模型、自测试和综合联调验收。 -- 未来新增单服务规格必须使用 `spec-v01-.md`,例如 `spec-v01-agentrun-mgr.md`、`spec-v01-agentrun-runner.md`。 +- `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-cli.md`:AgentRun CLI 命令族、JSON 输出、短返回、日志可见和测试规格。 +- `spec-v01-scheduler.md`:自动 scheduler 的 deferred 边界。 +- 未来新增单服务规格必须使用 `spec-v01-.md`。 - `v0.2` 或更高版本的规格不得写入 `spec-v01-*`;只能在对应版本 lane 中创建自己的 `spec-v02-*`、`spec-v03-*`。 - 每个可实现规格应包含“测试规格”小节;测试编号写在对应 spec 内,不创建或恢复根目录 `TEST.md`。 @@ -52,13 +58,19 @@ - 发布和验收规格:[spec-v01-cicd.md](spec-v01-cicd.md)。 - 服务总览规格:[spec-v01-services.md](spec-v01-services.md)。 - Postgres durable store 规格:[spec-v01-postgres.md](spec-v01-postgres.md)。 -- Secret/API Key 分发规格:[spec-v01-secret-distribution.md](spec-v01-secret-distribution.md)。 +- Secret/provider credential 分发规格:[spec-v01-secret-distribution.md](spec-v01-secret-distribution.md)。 - 验证模型规格:[spec-v01-validation.md](spec-v01-validation.md)。 +- 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)。 +- CLI 规格:[spec-v01-cli.md](spec-v01-cli.md)。 +- Scheduler deferred 规格:[spec-v01-scheduler.md](spec-v01-scheduler.md)。 ## 验收标准 - `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-validation.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-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` 写成当前工作区、namespace、发布目标或验收目标;只允许在废弃说明和历史背景中提及。 - `docs/` 根目录不新增临时 Markdown 报告或 JSON dump。 - 仓库根目录不存在 `TEST.md`;测试场景维护在对应 `spec-v01-*.md` 的“测试规格”小节。 diff --git a/docs/reference/spec-v01-scheduler.md b/docs/reference/spec-v01-scheduler.md new file mode 100644 index 0000000..220b498 --- /dev/null +++ b/docs/reference/spec-v01-scheduler.md @@ -0,0 +1,55 @@ +# v0.1 Scheduler Deferred 规格 + +`agentrun-scheduler` 是 AgentRun 后续自动调度器。它扫描 pending runs,选择 backend/profile/capacity,创建 runner Jobs,并处理 stale lease recovery。`v0.1` 保留该规格用于边界收敛,但自动 scheduler 不作为第一阶段交付和发布通过条件。 + +## 在系统中的职责划分 + +- 只在 M1-M3 稳定后进入实现;MVP 先通过 CLI/manual dispatch 启动 runner。 +- 未来负责 pending run scan、capacity selection、runner Job creation、stale lease recovery 和 scheduler restart recovery。 +- 不直接执行 backend,不直接写 provider events,不绕过 `agentrun-mgr` claim/report。 +- 不替代 tenant 业务授权;只能消费 manager 已保存的 run policy。 + +## Deferred 边界 + +`v0.1` 第一阶段不得因为 scheduler 未实现而阻塞最小真实闭环。发布候选可以在 scheduler 未实现时通过,但必须满足: + +- CLI/manual dispatch 能启动真实 runner。 +- manager durable facts、runner claim、backend turn、events 和 terminal status 全部真实可用。 +- scheduler 相关字段或状态不会被误报为 active runtime 通过证据。 + +若后续在 `v0.1` lane 内启用 scheduler,必须更新本文并补齐测试规格,不得把一次性 poller、自定义 runner 或手工脚本伪装成 scheduler。 + +## 未来 API 与运行形态 + +Scheduler 未来应运行在 `agentrun-v01` namespace,作为独立 Deployment 或 manager 内受控 loop 二选一;选择前必须重新评估 HA、leader election、lease recovery 和 rollout 风险。 + +未来 scheduler 只能通过 manager API 观察和改变 run 调度状态,不能直接写 Postgres 或直接调用 backend: + +```text +scheduler -> agentrun-mgr -> durable facts +scheduler -> Kubernetes API -> runner Job +runner -> agentrun-mgr -> events/status +``` + +## 测试规格 + +### T1 Deferred 状态检查 + +阅读本文和 [spec-v01-services.md](spec-v01-services.md),然后检查 `v0.1` 发布验收材料。确认 scheduler 未实现时被明确标记为 Deferred,且发布通过证据来自 CLI/manual dispatch 的真实 runner 闭环,而不是 scheduler 占位。 + +### T2 未来 scheduler 启用前检查 + +阅读本文,然后在实现 scheduler 前检查设计是否包含 pending scan、capacity selection、runner Job creation、stale lease recovery、leader/restart 行为和 failureKind。缺少这些内容时不得启用自动 scheduler。 + +### T3 不接受自定义 poller + +阅读本文和 [spec-v01-cicd.md](spec-v01-cicd.md),然后检查 runtime 与 CI/CD 链路。确认没有长期自定义 runner、CI.json runner、自研 poller 或手工脚本承担 scheduler 职责。 + +## 规格的实现情况 + +| 规格项 | 状态 | 说明 | +| --- | --- | --- | +| Scheduler 边界规格 | 已定义 | 本文定义 deferred 边界。 | +| 自动 pending scan | Deferred | 不作为 v0.1 第一阶段验收目标。 | +| runner Job 自动创建 | Deferred | 先使用 CLI/manual dispatch。 | +| stale lease recovery | Deferred | 未来实现前需补齐详细测试。 | diff --git a/docs/reference/spec-v01-secret-distribution.md b/docs/reference/spec-v01-secret-distribution.md index 7a76979..58d68ce 100644 --- a/docs/reference/spec-v01-secret-distribution.md +++ b/docs/reference/spec-v01-secret-distribution.md @@ -1,10 +1,10 @@ -# v0.1 Secret 与 API Key 分发规格 +# v0.1 Secret 与 provider credential 分发规格 -本文定义 AgentRun `v0.1` 的 Secret 和 Code Agent API Key 分发边界。Code Agent 一定需要上游模型 API Key,但这些值不得进入 Git source、GitOps branch、artifact catalog、event、trace、日志或 CLI 输出。 +本文定义 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 输出。 ## 设计目标 -- API Key 只通过 Kubernetes SecretRef 分发到需要它的 manager、runner 或 backend adapter。 +- API Key、Codex auth/config 等 provider credential 只通过 Kubernetes SecretRef 分发到需要它的 manager、runner 或 backend adapter。 - `deploy/deploy.json` 只记录 SecretRef 名称、key 名称、mount/env intent 和 secret scope,不记录 Secret 值。 - `v0.1-gitops` 的 rendered manifests 只能引用 Secret 名称和 key,不包含 Secret data。 - `agentrun-mgr` 保存 run 的 `executionPolicy.secretScope`,但保存的是 credential source reference,不是 credential value。 @@ -15,7 +15,7 @@ | Secret 类别 | 用途 | 默认消费者 | v0.1 规则 | | --- | --- | --- | --- | | Postgres DSN | manager 连接 durable store | `agentrun-mgr` | 只通过 `agentrun-v01-mgr-db/DATABASE_URL` 注入。 | -| Codex/OpenAI-compatible API Key | 真实 Code Agent backend 调上游模型 | runner 或 backend adapter | 只通过 provider profile SecretRef 注入,不写入 run payload。 | +| Codex 测试凭据文件 | 真实 Code Agent backend 调上游模型 | runner 或 backend adapter | 测试来源固定为 `~/.codex/auth.json` 与 `~/.codex/config.toml`,只通过 Kubernetes SecretRef 文件投影注入,不写入 run payload。 | | Git SSH deploy key | Tekton checkout source/GitOps promotion,Argo 读取 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,14 +25,39 @@ | 对象 | v0.1 建议 | | --- | --- | | Manager DB Secret | `agentrun-v01-mgr-db` key `DATABASE_URL` | -| Provider Secret | `agentrun-v01-provider-codex` key `API_KEY` | -| Provider config Secret | `agentrun-v01-provider-codex` key `BASE_URL` 或 ConfigMap 中非敏感 base URL | +| Provider Secret | `agentrun-v01-provider-codex` keys `auth.json`、`config.toml` | +| Provider projection target | runner/backend 容器用户的 `~/.codex/auth.json`、`~/.codex/config.toml` | +| Provider config | 非敏感 base URL/model 可以来自 `config.toml` 或 ConfigMap;credential value 不得放入 ConfigMap。 | | Tekton Git SSH Secret | `agentrun-ci/agentrun-git-ssh` | | Argo Git SSH Secret | `argocd/agentrun-git-ssh` | | Runtime ServiceAccount | `agentrun-v01-mgr`、`agentrun-v01-runner` | 命名可以在实现时因集群约束调整,但必须满足 lane 独立、用途单一、最小 RBAC 和不跨 `v0.1`/`v0.2` 复用的原则。 +## Codex 测试凭据注入 + +`v0.1` 综合联调使用的 Codex 测试凭据源固定为 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 输出。 + +默认 Secret projection 规则: + +| 项目 | v0.1 规格 | +| --- | --- | +| Kubernetes Secret | `agentrun-v01/agentrun-v01-provider-codex` | +| Secret key | `auth.json`,来自 `~/.codex/auth.json` | +| Secret key | `config.toml`,来自 `~/.codex/config.toml` | +| Projection path | runner/backend 容器用户的 `~/.codex/auth.json`、`~/.codex/config.toml` | +| Projection mode | 只读,建议 `0400` 或等价最小权限 | +| Runtime env | 如 backend 需要,可设置 `HOME` 或等价 Codex config root 指向投影后的 home;不得 fallback 到节点宿主机 home。 | + +Secret 创建和轮换必须通过 Kubernetes 密钥管理完成。`deploy/deploy.json` 只写 SecretRef 名称、key 和 mount intent;`v0.1-gitops` rendered manifests 只引用 Secret,不包含 Secret data。 + ## Run secretScope 合同 Run 的 `executionPolicy.secretScope` 只能包含引用,不包含值。示例形态: @@ -45,7 +70,8 @@ Run 的 `executionPolicy.secretScope` 只能包含引用,不包含值。示例 "secretRef": { "namespace": "agentrun-v01", "name": "agentrun-v01-provider-codex", - "key": "API_KEY" + "keys": ["auth.json", "config.toml"], + "mountPath": "~/.codex" } } ], @@ -58,7 +84,7 @@ Run 的 `executionPolicy.secretScope` 只能包含引用,不包含值。示例 - `allowCredentialEcho` 必须固定为 `false`。 - `secretRef.namespace` 默认只能是 run 所在 lane namespace 或明确批准的 platform namespace。 - manager 可以保存 `secretRef`,但不得读取 Secret 值后存库。 -- runner/backend adapter 获得 Secret 的方式必须来自 Kubernetes env/file projection 或受限 Secret API 读取;不得通过 run payload、event、CLI 参数或日志传递。 +- runner/backend adapter 获得 Secret 的方式必须来自 Kubernetes env/file projection 或受限 Secret API 读取;Codex 默认使用文件 projection 到 `~/.codex/auth.json` 和 `~/.codex/config.toml`,不得通过 run payload、event、CLI 参数或日志传递。 - SecretRef 不存在或 RBAC 不允许时,run 必须失败为结构化 `failureKind=secret-unavailable` 或等价错误,不得降级成无凭证重试风暴。 ## 分发路径 @@ -73,9 +99,9 @@ Tekton promotion Argo CD -> syncs workload references to agentrun-v01 Kubernetes Secret - -> created out-of-band by operator or approved secret-management flow + -> created from ~/.codex/auth.json and ~/.codex/config.toml by operator or approved secret-management flow runner/backend Pod - -> receives API Key via env/file projection + -> receives Codex auth/config via read-only file projection ``` Secret 创建和轮换不由 source branch 自动生成;source branch 只声明需要哪个 SecretRef。后续如果接入 External Secrets、Vault、SealedSecrets 或 SOPS,必须新增或更新本 spec,明确 controller、source of truth、rotation 和 redaction 规则。 @@ -83,7 +109,7 @@ Secret 创建和轮换不由 source branch 自动生成;source branch 只声 ## 日志与事件 Redaction - event、trace、日志、CLI 输出、health 和 diagnostics 不得打印 Secret 值。 -- `Authorization`、`api_key`、`token`、`password`、URL credential、DSN password 必须 redacted。 +- `Authorization`、`api_key`、`token`、`password`、URL credential、DSN password、Codex `auth.json` 和 `config.toml` 文件内容必须 redacted。 - 可以打印 SecretRef 名称、key 名称、credential source、是否存在、是否被挂载、是否通过 readiness 检查。 - provider auth 失败只能报告 failure kind、HTTP status 分类和 request id;不得打印请求 header 或 body 中的凭据。 @@ -95,7 +121,7 @@ Secret 创建和轮换不由 source branch 自动生成;source branch 只声 ### T2 Runner credential projection -阅读本文,然后启动一个最小 backend runner dry-run,确认 Pod env/file projection 能看到 provider credential,但 event、日志和 CLI 输出只显示 redacted credential source。 +阅读本文,然后启动一个最小 backend runner dry-run,确认 Pod file projection 能看到 `~/.codex/auth.json` 和 `~/.codex/config.toml`,但 event、日志和 CLI 输出只显示 redacted credential source,不显示文件内容。 ### T3 Missing secret failure @@ -105,8 +131,8 @@ Secret 创建和轮换不由 source branch 自动生成;source branch 只声 | 规格项 | 状态 | 说明 | | --- | --- | --- | -| Secret 分发规格 | 已定义 | 本文为 v0.1 API Key 分发权威。 | +| Secret 分发规格 | 已定义 | 本文为 v0.1 provider credential 分发权威。 | | Kubernetes SecretRef 注入 | 未实现 | 需要后续 GitOps/runtime 实现。 | -| provider API Key projection | 未实现 | 需要后续 runner/backend adapter 实现。 | +| Codex auth/config file projection | 未实现 | 需要后续 runner/backend adapter 实现,测试来源为 `~/.codex/auth.json` 和 `~/.codex/config.toml`。 | | redaction 最小规则 | 已定义 | 需要后续代码实现和测试。 | | 外部 secret manager | 未采用 | 如需 Vault/ExternalSecrets/SOPS,后续单独更新规格。 | diff --git a/docs/reference/spec-v01-services.md b/docs/reference/spec-v01-services.md index 02283b5..048f56b 100644 --- a/docs/reference/spec-v01-services.md +++ b/docs/reference/spec-v01-services.md @@ -41,9 +41,9 @@ Runner inbound API 只允许本地或私有诊断,不作为业务客户端入 | First real backend | 具体 Agent backend | 保留,P0 | `v0.1` 必须至少证明一个真实 Agent backend;默认候选是 Codex。 | `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 | API Key 只通过 Kubernetes SecretRef、ServiceAccount/RBAC 和 runner env/file projection 分发;source、GitOps、logs 和 events 不保存明文。 | `spec-v01-secret-distribution.md` | +| Secret distribution | 系统能力 | 保留,P0 | Provider credential 只通过 Kubernetes SecretRef、ServiceAccount/RBAC 和 runner env/file projection 分发;Codex 测试凭据使用 `~/.codex/auth.json` 与 `~/.codex/config.toml` 生成 Secret projection;source、GitOps、logs 和 events 不保存明文。 | `spec-v01-secret-distribution.md` | | Tenant policy boundary | Run schema 合同 | 保留,P0 | 作为 `Run` 的必填字段和最小校验存在,不做独立 policy engine;tenant 的业务授权仍由 UniDesk/HWLAB 判定。 | 并入 `spec-v01-agentrun-mgr.md` | -| Observability | 最小事件/日志合同 | 保留,P0 子项 | 作为 manager/runner 的 event、terminal status、failureKind、logPath 和 redaction 最小合同,不拆独立观测系统。 | 并入 `spec-v01-agentrun-mgr.md`、`spec-v01-agentrun-runner.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 | | UI | 前端 | Deferred | `v0.1` 不要求独立 UI;UniDesk/HWLAB canary 可通过 CLI/API 验证。 | 后续版本 spec | @@ -92,11 +92,11 @@ Run create 的最小字段合同: | `executionPolicy` | 必填或由 manager 显式写入默认值,至少包含 sandbox、approval、timeout、network 和 secret scope。 | | `traceSink` | 字段必须存在;可以为 `null` 或显式 sink,表示标准事件是否需要镜像给 tenant。 | -Manager 负责校验、保存和返回这些字段;runner 只能消费已保存的 run policy,不能自行扩大 workspace、network 或 secret scope。`executionPolicy.secretScope` 只能引用 [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md) 定义的 SecretRef 或 credential source,不能携带 API Key 明文。HWLAB live device mutation、UniDesk production deploy、GitHub issue/PR 写入等业务授权仍由 tenant 自己的入口判定,AgentRun 不把这些业务规则内建成通用门禁。 +Manager 负责校验、保存和返回这些字段;runner 只能消费已保存的 run policy,不能自行扩大 workspace、network 或 secret scope。`executionPolicy.secretScope` 只能引用 [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md) 定义的 SecretRef 或 credential source,不能携带 provider credential 明文。HWLAB live device mutation、UniDesk production deploy、GitHub issue/PR 写入等业务授权仍由 tenant 自己的入口判定,AgentRun 不把这些业务规则内建成通用门禁。 ## 最小 Observability 合同 -`v0.1` 不拆出独立 `spec-v01-observability.md`,也不建设通用日志平台。可观察性只作为 run 生命周期的一部分: +`v0.1` 不拆出独立观测规格文件,也不建设通用日志平台。可观察性只作为 run 生命周期的一部分: - `events` 必须 append-only,并按 `seq` 分页读取。 - 每个 run 必须最终写出 `terminal_status` 或明确的 non-terminal status。 @@ -140,7 +140,13 @@ Manager 负责校验、保存和返回这些字段;runner 只能消费已保 | Postgres durable store 规格 | 已定义 | 见 [spec-v01-postgres.md](spec-v01-postgres.md)。 | | Secret 分发规格 | 已定义 | 见 [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md)。 | | 两层验证规格 | 已定义 | 见 [spec-v01-validation.md](spec-v01-validation.md)。 | -| `agentrun-mgr` 实现 | 未实现 | 需后续单服务 spec 和代码实现。 | -| `agentrun-runner` 实现 | 未实现 | 需后续单服务 spec 和代码实现。 | -| 第一真实 backend | 未实现 | 默认候选 Codex,需后续 backend spec。 | +| `agentrun-mgr` 服务规格 | 已定义 | 见 [spec-v01-agentrun-mgr.md](spec-v01-agentrun-mgr.md)。 | +| `agentrun-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)。 | +| AgentRun CLI 规格 | 已定义 | 见 [spec-v01-cli.md](spec-v01-cli.md)。 | +| Scheduler deferred 规格 | 已定义 | 见 [spec-v01-scheduler.md](spec-v01-scheduler.md)。 | +| `agentrun-mgr` 实现 | 未实现 | 需后续代码实现。 | +| `agentrun-runner` 实现 | 未实现 | 需后续代码实现。 | +| 第一真实 backend | 未实现 | 默认候选 Codex。 | | 自动 scheduler | Deferred | 不作为 `v0.1` 第一阶段验收目标。 | diff --git a/docs/reference/spec-v01-validation.md b/docs/reference/spec-v01-validation.md index 15ebe15..a134560 100644 --- a/docs/reference/spec-v01-validation.md +++ b/docs/reference/spec-v01-validation.md @@ -19,7 +19,7 @@ - `agentrun-mgr`:Run schema、tenant fields、idempotency、command 状态机、event seq、claim/lease 冲突、failureKind。 - `agentrun-runner`:claim/poll/report client、heartbeat、backend event normalization、interrupt/cancel、logPath、Secret redaction。 -- backend adapter:输入输出转换、assistant/tool/error/terminal event、provider auth failure 分类、API Key 不进 event/log。 +- backend adapter:输入输出转换、assistant/tool/error/terminal event、provider auth failure 分类、provider credential 不进 event/log。 - CLI:默认 JSON、空 stdout 失败、长操作短返回、错误结构化。 - Postgres adapter:migration、事务、run/command/event round-trip、重启后可查询。 - Secret 分发:SecretRef schema、missing secret failure、redaction。 @@ -37,9 +37,9 @@ - 真实 `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 API Key。 +- 真实 Kubernetes SecretRef 注入 Postgres DSN 和 Code Agent provider credential;Codex 测试凭据必须来自 `~/.codex/auth.json` 与 `~/.codex/config.toml` 的 Kubernetes Secret projection。 - 真实 `agentrun-mgr`、runner Job 或受控 runner process、真实 backend adapter。 -- 至少一个真实 Code Agent provider turn;如果 API Key SecretRef 缺失,综合联调必须标记 blocked,不能降级为 mock pass。 +- 至少一个真实 Code Agent provider turn;如果 provider credential SecretRef 缺失,综合联调必须标记 blocked,不能降级为 mock pass。 综合联调最小闭环: @@ -50,7 +50,7 @@ 5. runner 使用真实 SecretRef 调用真实 backend provider,完成一个最短 turn。 6. manager 可查询 command state、append-only events、terminal_status 和 redacted logPath/job identity。 7. 重启 `agentrun-mgr` 后,run、command、events 和 terminal_status 仍可从 Postgres 查询。 -8. 日志、event、CLI 输出和 health 中没有 API Key、DSN password、token 或 URL credential 明文。 +8. 日志、event、CLI 输出和 health 中没有 provider credential、DSN password、token 或 URL credential 明文。 ### CLI 交互联调标准 @@ -62,12 +62,12 @@ CLI 交互联调必须满足: - 每个 CLI 调用默认输出 JSON,stdout 不为空,且 60 秒内返回;长时间模型 turn 必须通过后续 status/events 命令观察。 - 创建类命令必须返回 `runId`、`commandId`、status、job/process identity、logPath 和下一步 poll command;查询类命令必须返回当前 state、terminal_status、failureKind 和 event cursor。 - CLI 输出、日志摘要和错误信息必须保留可观测性,不能只返回成功/失败布尔值;错误必须能区分 missing SecretRef、provider auth failure、runner lease conflict、backend failure 和 infra failure。 -- CLI 不得输出 API Key、Postgres DSN password、token、URL credential 或 Secret value;只能输出 redacted value 或 SecretRef。 +- CLI 不得输出 provider credential、Postgres DSN password、token、URL credential 或 Secret value;只能输出 redacted value 或 SecretRef。 - 重启或滚动 `agentrun-mgr` 后,CLI 仍能查询同一 run、command、events 和 terminal_status,证明结果来自 Postgres 而不是进程内存。 ### RESTful API 交互联调标准 -RESTful API 交互联调验证 `agentrun-mgr` 对外 HTTP JSON 合同,而不是 CLI wrapper。它必须直接访问真实 `agentrun-v01` runtime 中的 manager API,且使用同一个真实 runner、backend adapter 和 provider API Key 完成一个 run 生命周期。 +RESTful API 交互联调验证 `agentrun-mgr` 对外 HTTP JSON 合同,而不是 CLI wrapper。它必须直接访问真实 `agentrun-v01` runtime 中的 manager API,且使用同一个真实 runner、backend adapter 和 provider credential 完成一个 run 生命周期。 RESTful API 交互联调必须满足: @@ -94,7 +94,7 @@ CLI 与 RESTful API 可以复用同一个真实 run 做联调。若两者观察 - 本地临时 Postgres 或 sqlite 测试成功。 - GitOps branch 已推送但 Argo 未同步。 - Argo Synced 但没有真实 run terminal_status。 -- provider API Key 缺失时的跳过结果。 +- provider credential 缺失时的跳过结果。 - 只读 health 成功但没有完成真实 Code Agent turn。 ## 测试规格 @@ -105,7 +105,7 @@ CLI 与 RESTful API 可以复用同一个真实 run 做联调。若两者观察 ### T2 综合联调真实性 -阅读本文,然后执行一次综合联调,确认所有关键依赖均为真实 `agentrun-v01` runtime、Postgres、SecretRef、runner、backend 和 provider API Key;任何缺失必须返回 blocked 或 failed。 +阅读本文,然后执行一次综合联调,确认所有关键依赖均为真实 `agentrun-v01` runtime、Postgres、SecretRef、runner、backend 和 provider credential;Codex 测试凭据必须通过 Kubernetes Secret projection 注入 `~/.codex/auth.json` 与 `~/.codex/config.toml`。任何缺失必须返回 blocked 或 failed。 ### T3 发布判定 @@ -113,7 +113,7 @@ CLI 与 RESTful API 可以复用同一个真实 run 做联调。若两者观察 ### T4 CLI 交互联调 -阅读 `AGENTS.md`、本文和 [cli.md](cli.md),然后用 AgentRun CLI 手动测试以下内容:在真实 `agentrun-v01` 运行面创建 run,提交一个 `turn` command,启动或触发真实 runner,并轮询 command status 与 run events 直到出现 terminal_status。确认每个步骤只使用正式 CLI 命令,不使用 debug 子命令或 mock/fake backend;每次调用 60 秒内返回非空 JSON,包含 runId、commandId、status、job/process identity、logPath 或下一步 poll command;日志、event 和 CLI 输出不得出现 API Key、DSN password、token 或 URL credential 明文。最后重启或滚动 `agentrun-mgr`,再用 CLI 查询同一个 run,确认 command state、events 和 terminal_status 仍可见。 +阅读 `AGENTS.md`、本文和 [cli.md](cli.md),然后用 AgentRun CLI 手动测试以下内容:在真实 `agentrun-v01` 运行面创建 run,提交一个 `turn` command,启动或触发真实 runner,并轮询 command status 与 run events 直到出现 terminal_status。确认每个步骤只使用正式 CLI 命令,不使用 debug 子命令或 mock/fake backend;每次调用 60 秒内返回非空 JSON,包含 runId、commandId、status、job/process identity、logPath 或下一步 poll command;日志、event 和 CLI 输出不得出现 provider credential、DSN password、token 或 URL credential 明文。最后重启或滚动 `agentrun-mgr`,再用 CLI 查询同一个 run,确认 command state、events 和 terminal_status 仍可见。 ### T5 RESTful API 交互联调