230 lines
12 KiB
Markdown
230 lines
12 KiB
Markdown
# v0.1 Runtime Assembly 规格
|
||
|
||
本文定义 AgentRun `v0.1` runner Job 启动前的四要素装配模型。`RuntimeAssembly` 是 manager 侧把 run intent 转换成可执行 runner/backend runtime 的权威视图;它只表达引用、hash、路径、权限、生命周期和脱敏策略,不携带 Secret value 或大文件正文。
|
||
|
||
## 设计目标
|
||
|
||
- 把 backend 镜像、provider profile、会话持久化和初始资源注入收敛为四个一等要素。
|
||
- 避免 runner 从隐式环境、host path、默认 home、可变 tag 或用户 payload 猜测运行时输入。
|
||
- 让 CI/CD、Secret、session、workspace 和 resource 注入各自有边界,但统一进入同一个装配计划。
|
||
- 把 identity、network、observability、GC、failureKind、provenance 等横切能力归并为四要素上的 policy、metadata、status 或 lifecycle 子项,不扩成并列的一等对象。
|
||
|
||
## 四要素模型
|
||
|
||
`RuntimeAssembly` 的一等要素固定为:
|
||
|
||
| 要素 | 职责 | v0.1 P0 边界 | 权威/引用 |
|
||
| --- | --- | --- | --- |
|
||
| `BackendImageRef` | 决定用什么 backend runtime image 和 command 能力。 | 使用 CI/CD 产出的 digest-pinned image;当前可复用 agentrun runner image,后续可拆独立 backend image。 | [spec-v01-cicd.md](spec-v01-cicd.md) |
|
||
| `ProfileRef` | 决定 provider/profile 配置和 API KEY SecretRef。 | `codex`、`deepseek` 使用 profile-scoped Kubernetes SecretRef;Secret value 不进 run payload。 | [spec-v01-secret-distribution.md](spec-v01-secret-distribution.md) |
|
||
| `SessionRef` | 决定是否恢复或保存 backend 会话状态。 | P0 可以为 `null`;只定义边界,不把完整 `CODEX_HOME` 持久化。 | 本文 |
|
||
| `ResourceBundleRef` | 决定 backend 启动前 materialize 哪份代码和非敏感 repo 文件。 | P0 收敛为 Git-only,由 Git URL、full commit id 和 checkout policy 决定内容身份。 | 本文 |
|
||
|
||
`executionPolicy` 和 `observabilityPolicy` 是装配规则,不是新的 runtime material。它们可以约束四要素如何被装配、观察和清理,但不得替代四要素本身。
|
||
|
||
最小形态:
|
||
|
||
```json
|
||
{
|
||
"backendImageRef": {},
|
||
"profileRef": {},
|
||
"sessionRef": null,
|
||
"resourceBundleRef": {},
|
||
"executionPolicy": {},
|
||
"observabilityPolicy": {}
|
||
}
|
||
```
|
||
|
||
## 装配顺序
|
||
|
||
Manager 创建或触发 runner Job 前必须按固定顺序解析装配计划:
|
||
|
||
1. 根据 run 的 `backendProfile` 解析 `backendKind` 和 `ProfileRef`。
|
||
2. 根据 `backendKind` 和 lane catalog 解析 `BackendImageRef`,得到 digest-pinned image。
|
||
3. 根据 run/session intent 解析 `SessionRef`;P0 无持久 session 时显式为 `null`。
|
||
4. 根据 run 的 workspace/resource intent 解析 `ResourceBundleRef`;P0 必须是 Git-only。
|
||
5. 合并 `executionPolicy` 与 allowlist,生成 Kubernetes Job 的 env、volume、init/prepare intent 和 resource limit。
|
||
6. 生成可写 runtime home、workspace 和可选 session mount;Secret projection 始终只读。
|
||
7. runner/backend 启动后把 image digest、profile name、SecretRef 名称/key、session id、resource commit/hash 和 redaction 状态写入 event metadata,但不写入 Secret value。
|
||
|
||
Runner 不得自行选择不同 image、Secret、PVC、host path 或 Git ref;任何缺失或不匹配都应按对应要素失败,而不是 fallback 到默认值。
|
||
|
||
## BackendImageRef
|
||
|
||
`BackendImageRef` 表达 backend runtime 能力和镜像身份。P0 允许 manager 和 runner/backend 共用同一镜像;即使共用,也必须在装配计划中把实际 image digest 作为 backend image identity 记录。
|
||
|
||
建议字段:
|
||
|
||
```json
|
||
{
|
||
"backendKind": "codex-app-server-stdio",
|
||
"image": "127.0.0.1:5000/agentrun/agentrun-mgr@sha256:...",
|
||
"sourceCommit": "<40-char source commit>",
|
||
"command": ["bun", "src/runner/main.ts"],
|
||
"backendCommand": ["codex", "app-server", "--listen", "stdio://"],
|
||
"resourceProfile": { "cpu": "2", "memory": "4Gi" },
|
||
"provenance": { "catalog": "deploy/artifact-catalog.v01.json" }
|
||
}
|
||
```
|
||
|
||
规则:
|
||
|
||
- image 必须来自 Tekton artifact catalog 或 manager allowlist;客户端 run payload 不得直接提供任意 image。
|
||
- 正式 runtime manifest 必须使用 digest pin,不以 mutable tag 作为执行身份。
|
||
- 镜像只表达 runtime 能力,不包含 API KEY、profile config、session 文件或用户 code。
|
||
- image pull、digest 缺失或 capability 不匹配应归类为 image/infra failure,不得被记录为 provider auth failure。
|
||
|
||
## ProfileRef
|
||
|
||
`ProfileRef` 表达 provider/profile 配置和 credential 边界。P0 中 `codex` 与 `deepseek` 都是 `codex-app-server-stdio` backend kind 的 profile/config/SecretRef 选择。
|
||
|
||
建议字段:
|
||
|
||
```json
|
||
{
|
||
"profile": "deepseek",
|
||
"backendKind": "codex-app-server-stdio",
|
||
"secretRefs": [
|
||
{ "name": "agentrun-v01-provider-deepseek", "keys": ["auth.json", "config.toml"] }
|
||
],
|
||
"runtimeHome": "/home/agentrun/.codex-deepseek",
|
||
"redactionPolicy": "provider-credential-v1"
|
||
}
|
||
```
|
||
|
||
规则:
|
||
|
||
- API KEY、Codex `auth.json`、Codex `config.toml` 和 provider token 只通过 SecretRef 注入。
|
||
- 非敏感 provider config 可以保存在 profile registry、ConfigMap 或 Postgres capability 中;credential value 不得进入 ConfigMap。
|
||
- Secret projection 是只读 credential source;需要 writable home 的 backend 必须复制到 per-run/profile runtime home。
|
||
- profile 缺失或 SecretRef 不匹配必须 `secret-unavailable`;`deepseek` 不得 fallback 到 `codex`。
|
||
- network、proxy、NO_PROXY、rate limit 和 provider readiness 默认归并到 `ProfileRef` 的 policy/status 子项。
|
||
|
||
## SessionRef
|
||
|
||
`SessionRef` 表达可恢复的 backend 会话状态,不等同于 Postgres durable facts。Postgres 保存 run、command、event、terminal status、lease 和 session metadata;backend session 文件应保存到 PVC 或后续对象存储。
|
||
|
||
P0 允许无持久 session:
|
||
|
||
```json
|
||
{
|
||
"sessionRef": null,
|
||
"persistence": "none"
|
||
}
|
||
```
|
||
|
||
后续建议字段:
|
||
|
||
```json
|
||
{
|
||
"sessionId": "sess_...",
|
||
"tenantId": "unidesk",
|
||
"projectId": "pikasTech/unidesk",
|
||
"backendKind": "codex-app-server-stdio",
|
||
"backendProfile": "codex",
|
||
"pvcRef": { "namespace": "agentrun-v01", "name": "agentrun-session-sess-..." },
|
||
"schemaVersion": "codex-stdio-session-v1",
|
||
"retentionPolicy": "debug-short"
|
||
}
|
||
```
|
||
|
||
规则:
|
||
|
||
- `SessionRef` 不保存 API KEY;每次 run 的 credential 仍从 `ProfileRef` 重新投影。
|
||
- 不直接持久化完整 `CODEX_HOME`,因为该目录可能混合 credential、config、session/cache。
|
||
- session 文件、workspace、profile credential 必须是不同目录或 volume。
|
||
- local-path/RWO PVC 会限制恢复节点;跨节点恢复需要 RWX 存储或对象存储,必须在后续 spec 中明确。
|
||
- session 挂载失败、版本不兼容或 restore 失败应归类为 session failure,不得归为 provider failure。
|
||
|
||
## ResourceBundleRef
|
||
|
||
`ResourceBundleRef` 表达 backend 启动前注入哪份代码和非敏感 repo 文件。P0 收敛为 Git-only,不支持上传文件、对象存储 artifact、inline env 或任意 ConfigMap/Secret 文件袋。
|
||
|
||
P0 字段:
|
||
|
||
```json
|
||
{
|
||
"type": "git",
|
||
"repoUrl": "git@github.com:pikasTech/unidesk.git",
|
||
"commitId": "<full commit sha>",
|
||
"subdir": ".",
|
||
"checkoutPolicy": {
|
||
"submodules": false,
|
||
"lfs": false,
|
||
"sparsePaths": []
|
||
},
|
||
"credentialRef": null,
|
||
"materializedTreeHash": null
|
||
}
|
||
```
|
||
|
||
规则:
|
||
|
||
- 内容身份由 `repoUrl + commitId + subdir + sparsePaths` 决定;commit id 必须是不可变 full commit sha。
|
||
- `credentialRef` 只用于拉取私有仓库,不参与内容身份,也不得暴露给 backend。
|
||
- `submodules` 和 `lfs` 默认 false;启用时必须进入验收和凭据边界。
|
||
- checkout 后应记录 `materializedTreeHash` 或等价摘要,确认实际 workspace 与期望 commit/subdir 一致。
|
||
- API KEY、provider token、Codex auth/config 属于 `ProfileRef`,不得放进 Git-only bundle。
|
||
- backend session/cache 属于 `SessionRef`,不得放进 Git-only bundle。
|
||
- 动态用户 env 属于 `executionPolicy` 的 allowlisted overlay,不作为 ResourceBundle 内容身份。
|
||
- 大型外部 artifact、上传文件、对象存储和任意 ConfigMap 文件注入都 deferred;后续必须显式扩展,不得把 P0 Git-only 模型变成万能资源袋。
|
||
|
||
## 横切能力归并
|
||
|
||
横切能力必须挂到四要素或 run policy 上:
|
||
|
||
| 横切能力 | 归并位置 |
|
||
| --- | --- |
|
||
| identity/tenant | run、session、resource 和 profile 的 owner/scope/grant 字段。 |
|
||
| scheduling/resource | `BackendImageRef.resourceProfile` 与 `executionPolicy`。 |
|
||
| network/egress | 主要属于 `ProfileRef`,少量属于 `ResourceBundleRef` fetch policy。 |
|
||
| observability | 四要素 materialization 的 event/status metadata。 |
|
||
| lifecycle/GC | session、resource、run/job 和 image artifact 各自的 retention policy。 |
|
||
| failureKind | 按失败发生在哪个要素归类。 |
|
||
| provenance | image digest、profile config hash、session snapshot version、resource commit/tree hash。 |
|
||
|
||
## FailureKind 归属
|
||
|
||
| 失败位置 | 建议 failureKind | 说明 |
|
||
| --- | --- | --- |
|
||
| Backend image pull/capability | `infra-failed` 或后续 `image-unavailable` | 镜像不存在、digest 不可拉取、backendKind 不匹配。 |
|
||
| Profile SecretRef | `secret-unavailable` | Secret 缺失、RBAC 拒绝、缺 `auth.json`/`config.toml`。 |
|
||
| Provider auth/upstream | `provider-auth-failed`、`provider-unavailable` | 已成功 materialize profile,但上游拒绝或不可用。 |
|
||
| Session mount/restore | `infra-failed` 或后续 `session-unavailable` | PVC 不可挂载、schema 不兼容、restore 失败。 |
|
||
| Resource checkout/materialization | `schema-invalid`、`infra-failed` 或后续 `resource-unavailable` | Git URL/commit 非法、checkout 失败、tree hash 不匹配。 |
|
||
|
||
新增细分 failureKind 前必须同步 manager、runner、backend、CLI、self-test 和 validation spec;P0 可以先用现有 failureKind 并在 event payload 中标明 `assemblyElement`。
|
||
|
||
## 测试规格
|
||
|
||
### T1 RuntimeAssembly 字段完整性
|
||
|
||
阅读本文和 [spec-v01-services.md](spec-v01-services.md),然后检查 run/runner Job 创建路径是否能明确追溯 `BackendImageRef`、`ProfileRef`、`SessionRef` 和 `ResourceBundleRef`。P0 中尚未实现的 `SessionRef` 和 Git-only `ResourceBundleRef` 必须显式为 `null` 或 deferred 状态,而不是由 runner 隐式猜测。
|
||
|
||
### T2 BackendImageRef digest 固定
|
||
|
||
阅读本文和 [spec-v01-cicd.md](spec-v01-cicd.md),然后检查 Tekton artifact catalog、GitOps runtime manifest 和实际 Deployment/Job image,确认 runner/backend 使用 digest-pinned image,并能追溯 source commit。
|
||
|
||
### T3 ProfileRef Secret 隔离
|
||
|
||
阅读本文、[spec-v01-secret-distribution.md](spec-v01-secret-distribution.md) 和 [spec-v01-backend-codex.md](spec-v01-backend-codex.md),然后分别执行 `backendProfile=codex` 与 `backendProfile=deepseek` 的真实 runner Job。确认当前 run 只挂载匹配 profile 的 SecretRef,runtime home 独立,缺失 profile SecretRef 不 fallback。
|
||
|
||
### T4 SessionRef 与 credential 分离
|
||
|
||
阅读本文,然后在引入 session 持久化前确认 P0 runner Job 不把完整 `CODEX_HOME` 持久化到 PVC 或 hostPath。后续实现 session PVC 时,必须证明 session 目录不包含 API KEY、Codex auth/config 或 provider token。
|
||
|
||
### T5 Git-only ResourceBundle
|
||
|
||
阅读本文,然后用 Git URL、full commit id 和 subdir 创建资源装配计划。确认 checkout 发生在允许 workspace 前缀内,记录 materialized tree 摘要,且 run payload 不携带文件正文、Secret value 或任意 env dump。
|
||
|
||
## 规格的实现情况
|
||
|
||
| 规格项 | 状态 | 说明 |
|
||
| --- | --- | --- |
|
||
| RuntimeAssembly 四要素模型 | 已定义 | 本文作为四要素装配模型权威;其他 spec 只引用,不重复定义。 |
|
||
| `BackendImageRef` | 部分实现 | 当前 runner/backend 复用 agentrun 镜像,CI/CD 已使用 digest-pinned runtime manifest;尚未拆独立 backend image registry。 |
|
||
| `ProfileRef` | 已实现/已通过主闭环 | `codex` 与 `deepseek` profile 已通过 Kubernetes SecretRef、writable runtime home 和真实 Codex stdio turn 验证。 |
|
||
| `SessionRef` | 已定义/P0 未持久化 | 当前 v0.1 只持久化 run facts,不持久化 backend session 文件;后续实现 PVC 或对象存储前必须保持 credential 分离。 |
|
||
| Git-only `ResourceBundleRef` | 已定义/待实现 | P0 规格收敛为 Git-only,尚未进入 runner Job materialization。 |
|
||
| 横切能力归并 | 已定义 | identity、network、observability、GC、failure 和 provenance 归并为四要素 policy/metadata/status/lifecycle 子项。 |
|