12 KiB
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 |
ProfileRef |
决定 provider/profile 配置和 API KEY SecretRef。 | codex、deepseek 使用 profile-scoped Kubernetes SecretRef;Secret value 不进 run payload。 |
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。它们可以约束四要素如何被装配、观察和清理,但不得替代四要素本身。
最小形态:
{
"backendImageRef": {},
"profileRef": {},
"sessionRef": null,
"resourceBundleRef": {},
"executionPolicy": {},
"observabilityPolicy": {}
}
装配顺序
Manager 创建或触发 runner Job 前必须按固定顺序解析装配计划:
- 根据 run 的
backendProfile解析backendKind和ProfileRef。 - 根据
backendKind和 lane catalog 解析BackendImageRef,得到 digest-pinned image。 - 根据 run/session intent 解析
SessionRef;P0 无持久 session 时显式为null。 - 根据 run 的 workspace/resource intent 解析
ResourceBundleRef;P0 必须是 Git-only。 - 合并
executionPolicy与 allowlist,生成 Kubernetes Job 的 env、volume、init/prepare intent 和 resource limit。 - 生成可写 runtime home、workspace 和可选 session mount;Secret projection 始终只读。
- 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 记录。
建议字段:
{
"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 选择。
建议字段:
{
"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、Codexconfig.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:
{
"sessionRef": null,
"persistence": "none"
}
后续建议字段:
{
"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 字段:
{
"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,然后检查 run/runner Job 创建路径是否能明确追溯 BackendImageRef、ProfileRef、SessionRef 和 ResourceBundleRef。P0 中尚未实现的 SessionRef 和 Git-only ResourceBundleRef 必须显式为 null 或 deferred 状态,而不是由 runner 隐式猜测。
T2 BackendImageRef digest 固定
阅读本文和 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-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 子项。 |