fix: 修复 AgentRun provider 假活性与容量可见性

This commit is contained in:
Codex
2026-07-11 04:16:58 +02:00
parent ce5c20f627
commit 04cd3e5f12
21 changed files with 3063 additions and 214 deletions
+63 -4
View File
@@ -109,7 +109,52 @@ YAML-only lane 的 `trigger-current` 会先确保目标 branch 已同步到 k8s
Provider credential Secret 的 `auth.json``config.toml` 也必须按 NC01 lane 的 YAML `sourceRef` 下发,不能把指挥机全局 Codex 配置当成运行真相。lane 的模型、provider、endpoint 和 Codex runtime options 需要由 UniDesk YAML 拥有时,使用 `sourceMode: codex-config` 和同一 Secret spec 下的 `codexConfig` 渲染 `config.toml`;不要通过修改 `/root/.codex/config.toml``~/.codex/config.toml` 来改变 HWLAB/AgentRun 运行面模型。
AgentRun runtime provider profile 的标准在线配置入口是 `bun scripts/cli.ts agentrun provider-profile plan|status|apply|validate --node NC01 --lane nc01-v02 --profile <profile>``plan/status` 必须输出 YAML 声明的 profile、backendProfile、SecretRef/key、fingerprint、runner egress/NO_PROXY 和 `valuesPrinted=false``apply --confirm` 只同步选中 profile 的 Secret/config、复用当前 manager image 渲染 GitOps、刷新 Argo 并重启 manager,不触发 image rebuild 或 PipelineRun`validate` 只能作为配置和运行面可见性预检,不能替代 HWLAB Web/CLI 原入口真实 turn。需要确认某个 profile 已上线时,先跑 `provider-profile status` 看 live Secret fingerprint 和 manager env,再用 HWLAB Web dispatcher 等价入口创建新 session 并发送一轮真实 prompt。Web 入口验证优先使用 `web-probe observe start` + `observe command --type newSession` + `observe command --type sendPrompt --provider <profile>`,证据应包含 providerSelection、`/v1/agent/chat` 202、traceId、terminal turn 和 Final Response。
AgentRun runtime provider profile 的标准在线配置入口是
- `provider-profile plan`:检查 YAML 声明与 owner source
- `provider-profile runtime-status`:只检查 runtime Secret/key 与 YAML endpoint 对应的 Kubernetes Service/port,不读取 owner source,也不解码 Secret
- `provider-profile status`:读取 owner source,并对 YAML 期望与 runtime 的 Kubernetes Secret 编码态 fingerprint
- `provider-profile apply --confirm`provider Secret 编码态完全一致时跳过 Secret 写入,再复用当前 manager image 发布 GitOps、刷新 Argo 并重启 manager,不创建 image build 或 PipelineRun
- `provider-profile validate`:只做配置与运行面预检,不能替代 HWLAB Web/CLI 原入口真实 turn。
### Provider Secret 激活
- lane parser 必须拒绝重复 Secret `id` 或重复完整 `targetRef`
- 执行期必须按 `namespace/name/key` 完整 `targetRef` 分类 provider Secret
- 不得用 Secret `id` 作为 activation gate 的写入排除键;
- provider `targetRef` 命中的写入必须先经过同一个 activation gate
- Pod、Job 和 manager DB 观察只用于诊断,不能作为 Provider Secret 写授权;
- Provider Secret create、key add 或 key change 固定 fail-closed
- 异步 job 创建前阻断;
- worker Secret sync 前再次阻断;
- Kubernetes 编码态 fingerprint 完全一致时只允许 no-op,并跳过 provider Secret patch
- 继续激活前必须由 AgentRun manager 在同一个 authority 中完成:
- 阻断相关新 runner admission
- DB fence 与既有 runner 收敛;
- Secret UID/resourceVersion CAS 写入;
- 写后编码态 fingerprint 验证;
- manager fence 上线并经 NC01 验收后才能解除非 no-op 阻断;
- 依赖入口:
- pre-create retention 分类由 [AgentRun #280](https://github.com/pikasTech/agentrun/issues/280) 跟踪;
- 原子实现由 [PR #281](https://github.com/pikasTech/agentrun/pull/281) 跟踪;
- 无 incoming create 时的周期回收由 [AgentRun #282](https://github.com/pikasTech/agentrun/issues/282) 跟踪;
- Provider Secret admission fence 与 CAS 由 [AgentRun #284](https://github.com/pikasTech/agentrun/issues/284) 跟踪;
- #280/#281/#282 只解决 retention,不等于 Provider Secret 激活 fence。
### Provider profile 验收
- 先运行 `provider-profile status`
- 再通过 HWLAB Web dispatcher 等价入口创建 session 并发送真实 prompt
- Web 验收入口:
- `web-probe observe start`
- `observe command --type newSession`
- `observe command --type sendPrompt --provider <profile>`
- 证据必须包含:
- `providerSelection`
- `/v1/agent/chat` 202
- `traceId`
- terminal turn
- Final Response。
仅修改 UniDesk YAML 中的 manager env、Kafka 开关、runner egress 或 provider config 时,不一定需要重建 AgentRun image。若 AgentRun source commit 已经是目标版本,应优先使用 `agentrun provider-profile apply --node NC01 --lane nc01-v02 --profile <declared-profile> --confirm` 复用当前 image 发布最新 YAML-rendered GitOps、刷新 Argo 并 rollout manager,再用窄查询确认 Deployment env 和新建 runner Job env;不要只看 `control-plane status` 的 manager source commit 对齐就认定 YAML env 已进入 runtime。
@@ -117,15 +162,29 @@ HWLAB 通过 NC01 `agentrun-v02` 使用 Codex profile 时,`config.toml` 应只
AgentRun Kafka closeout 需要同时验证 manager 和 runner 两条生产链路。manager 侧至少创建一个短 run,并在 manager pod 内执行 `./scripts/agentrun kafka tail agentrun --run-id <runId>` 查到 `agentrun.event.v1``agentrun.run.created` 或后续 durable eventrunner 侧必须创建真实 runner Job,并确认 Job env 中存在 `AGENTRUN_KAFKA_ENABLED``AGENTRUN_KAFKA_BOOTSTRAP_SERVERS``AGENTRUN_KAFKA_STDIO_TOPIC``AGENTRUN_KAFKA_STDIO_CLIENT_ID``AGENTRUN_KAFKA_STDIO_PRODUCE_ENABLED`,再用 `./scripts/agentrun kafka tail stdio --run-id <runId>` 查到 `codex-stdio.raw.v1` 的 stdin/stdout/stderr frame。默认查询不得展开 raw value;需要排查裸帧时才显式加 `--values`,并避免把 Secret value 写入 issue 或日志。
如果 smoke runner 被 retention 挡住,先运行 `agentrun control-plane cleanup-runners --node NC01 --lane nc01-v02 --dry-run`只有 operator 明确接受中断旧 active runner 的风险时,才可按同参 `--force-active --dry-run` 确认 selected runner,再 `--force-active --confirm` 清理;不得为了验证 Kafka raw frame 直接裸删 Kubernetes Job/Pod。
如果 smoke runner 被 retention 挡住,先运行 `agentrun control-plane cleanup-runners --node NC01 --lane nc01-v02 --dry-run`该入口只做有界分类,不拥有删除 authority;必须由 AgentRun manager 在创建新 runner 前通过 DB fence 与 Kubernetes CAS 原子回收,UniDesk 不提供强杀参数,也不得为了验证 Kafka raw frame 直接裸删 Kubernetes Job/Pod。
AgentRun resource/session client policy 也由 `config/agentrun.yaml` 声明。`client.sessionPolicy` 是未显式选择 node/lane 时 `agentrun send session/...` 和相关 session payload 生成的默认 `tenantId``projectId``providerId``backendProfile``workspaceRef` 和 execution policy 来源;显式 `--node <node> --lane <lane>` 后,`explain session-policy``send session`、resource primitives 和 AipodSpec render 都必须改用目标 lane 的 YAML 事实。lane `secrets[].providerCredential.profile` 声明 provider credential Secret 归属,UniDesk CLI 只按 YAML 聚合 Secret name/key,不再用代码拼接 provider Secret 名称。只读入口 `bun scripts/cli.ts agentrun explain session-policy` 用于查看选中目标 lane、policy 来源、实际 executionPolicy payload 和 provider credential binding 来源;输出只能包含 Secret metadata、key 名和 `valuesPrinted=false`,不得打印 Secret value。
非默认 lane 的 session follow-up 必须证明 `send session` 使用的是选中 node/lane 的 run policy。使用短命令形态前,先用 `agentrun explain session-policy --node <node> --lane <lane> [--backend-profile <profile>]` 或等价 dry-run/describe 路径确认 `backendProfile``providerId``workspaceRef`、execution policy 和 provider credential SecretRef 都来自目标 lane`--prompt-stdin` 短命令形态和 `--json-stdin -o json` 显式 JSON 形态应披露同一份 `sessionPolicy` 摘要。渲染结果回退到全局默认 lane、显示错误的 default lane,或短命令与 JSON body 使用不同 policy,都是 lane policy 缺陷,应修复 YAML 目标解析或 CLI 渲染;不得通过手工创建默认 lane Secret、复制凭据、改写 JSON body 或修改 runtime namespace 来掩盖 policy 选错的问题。
`cleanup-runners` 是 AgentRun runtime runner retention 入口,只清理 YAML 选中 lane 的 runtime namespace 中匹配 `deployment.runner.retention.selectors` 的 runner Job/Pod。runner 上限、最后活跃排序策略、active heartbeat 窗口、Job name prefix 和是否启用 age-based cleanup 都以 `config/agentrun.yaml` 为唯一真相;命令行不得覆盖这些数值。dry-run 必须披露清理前 runner Job 数、runner 非终态 Pod 数、按最后活跃时间排序的 inactive 候选、selected runner Job、manager facts 可用性和 active run 风险;confirm 默认只删除 selected runner Job,并重新统计清理后 runner Job/Pod 数。manager facts 不可用时,只允许清理终态或无活动 Pod 的安全候选,并保留风险字段,不能把 Kubernetes 创建时间冒充为完整最后活跃事实。
`cleanup-runners` 是 AgentRun runtime runner retention 的只读观察入口:
`cleanup-runners --force-active` 只用于 operator 已明确决定“强杀 runner pod”的资源恢复场景,例如 runner Job 顶满单节点 pod 配额并阻塞 git-mirror、CI/CD 或其他控制面调度。使用前仍必须先执行同参 `--dry-run`,确认 `criteria.forceActive=true`、命中的 namespace/selector、`selectedRunnerJobs` 和预期一致;`--confirm` 会删除所有匹配 runner Job,包括 protected active runner,并会中断对应 run、command 或 session。该开关不得作为日常 retention、静默自愈或 over-limit 默认策略;需要强杀时也必须走这个受控入口,禁止回退到裸 `kubectl delete pod/job`
- 只对 YAML 选中 lane 的 runtime namespace 中匹配 `deployment.runner.retention.selectors` 的 runner Job/Pod 做有界分类;
- runner 上限、最后活跃排序策略、active heartbeat 窗口、stale Pending 窗口、Job name prefix 和 age-based cleanup 都以 `config/agentrun.yaml` 为唯一真相;
- 命令行不得覆盖这些数值;
- dry-run 必须分开披露 observation 与 capacity
- 默认 capacity 摘要必须显示:
- `<runnerJobCount>/<maxRunners>`
- `status`
- `availableSlots`
- typed blocker
- `degradedReason`
- manager facts 或 Warning Event 查询不完整时返回 observation degraded
- `runnerJobCount === maxRunners` 时返回 at-capacity degraded,不能在下一次创建已经依赖尚未验收的 manager retention 时继续显示健康;
- UniDesk 的 `--confirm` 固定 fail-closed,不按名称删除 Job/Pod
- 真正回收只能由 AgentRun manager 在 incoming runner 创建前通过 DB fence 与 Kubernetes CAS 原子完成;
- manager facts 不可用时继续保护,不能把 Kubernetes 创建时间冒充为完整最后活跃事实。
`cleanup-runs` 是 AgentRun `v0.2` 完成态 CI workspace retention 入口,只清理 `agentrun-ci` namespace 中超过 `--min-age-minutes``agentrun-v02-ci-*` PipelineRun,通过 Tekton ownerRef 释放临时 workspace PVC。dry-run 必须披露候选 PipelineRun、owned PVC、active mount 保护、local-path 实际估算 bytes 和 confirm 命令。默认保护最新完成的 PipelineRun,保留当前 CI/CD 状态证据。`cleanup-released-pvs` 是二次回收入口,只处理 `agentrun-ci``local-path``Delete` reclaim policy 的 `Released` PV;它不触碰 AgentRun runtime namespace、业务 PVC、Secret、registry storage 或 GitOps desired state。磁盘治理规则见 `docs/reference/gc.md`