feat(v0.1): add per-session RWO PVC foundation for true session state persistence
PR A for #770: docs + migration 007 + RBAC + types foundation. - 新增 failureKind session-store-evicted,用于区分 PVC 缺失与真协议错误 - 新增 migration 007_v01_session_state_storage:sessions 表增加 storage_* 列 + 索引 - mgr SA RBAC 增量:persistentvolumeclaims: [create, get, list, watch, delete] - 6 份 SPEC 升级(runtime-assembly / hwlab-manual-dispatch / backend-codex T7b / agentrun-runner / agentrun-mgr / services) - 显式禁止:fake app-server mock、replacement threadId、runner 启动后 copy/restore、idleTimeoutMs 拉永驻 - selftest 断言更新到 007_v01_session_state_storage 后续 PR B/C 在此基础上接入 mgr 端 PVC 生命周期 + runner 端 mount + backend 端 observability。
This commit is contained in:
@@ -121,6 +121,26 @@ AgentRun 需要提供 durable cancel 能力,建议形态为 `POST /api/v1/runs
|
||||
|
||||
`SessionRef` 需要从 `null/deferred` 升级为可选持久会话引用,支持 HWLAB `conversationId/sessionId/threadId` 到 AgentRun session identity 的映射。session 只能保存 backend thread/session/cache,不保存 API KEY、`auth.json`、`config.toml` 或完整 `CODEX_HOME`。session store 必须与 Secret projection、writable runtime home、Git workspace 分离。runner 启动时,只按 command `payload.threadId` 或 `SessionRef.threadId` 执行 `thread/resume`,没有标准 `threadId` 则执行 `thread/start`;events、result 和 session record 都以 `threadId` 为唯一 thread identity;profile 隔离、TTL、GC 和跨 profile 污染防护必须可见。
|
||||
|
||||
### v0.1.1 Session state 真正持久化(per-session RWO PVC 直接挂载)
|
||||
|
||||
`P1 SessionRef 持久化` 把「持久化」从「metadata-only」升级为「真实持久化」:每个 session 绑一个 RWO PVC,runner Job 把 PVC **直接挂载**到 `${CODEX_HOME}/<codex_rollout_subdir>`,codex app-server 自己管落盘,不引入 copy 钩子。
|
||||
|
||||
#### 关键边界
|
||||
|
||||
1. **不引入 copy 路径**:PR #78 已回退 replacement 逻辑(v0.1 不接受 stale `thread/resume` 蒙混)。本节同样禁止「runner Started 后 copy/restore」「热补丁写入 PVC」「伪造 `thread/resume:completed`」等任何变体;只能 PVC 直接挂载,codex 自己读写。
|
||||
2. **硬验收 = 「PVC 不删就随时 resume」**:跨 runner pod 重建 / 跨 runner Job 重建 / 7 天长跨度(场景 D)都必须 `thread/resume:completed`,不能用 `idleTimeoutMs` 拉成永驻或 runner 不退蒙混。
|
||||
3. **profile 隔离 + 永不复用**:每个 session 一个 PVC,PVC 内容只服务当前 `backendProfile` 的 codex rollout;profile 切换必须新 sessionId + 新 PVC。
|
||||
4. **写后即一致**:`codex-rollout-storage-mounted` 是 backend adapter 在 `initialize` 之后发出的事件,含 `pvcName` / `mountPath` / `codexRolloutSubdir`;runner 通过 `POST /api/v1/sessions/:id/storage/refresh` 写回摘要。
|
||||
5. **eviction 显式化**:只有 `AGENTRUN_SESSION_PVC_NAME` 已设 + codex 返回 `no rollout found for thread id` 时升级为 `session-store-evicted`;其他 `thread/resume` 失败按 T7 走 `thread-resume-failed`。
|
||||
|
||||
#### 行为约束
|
||||
|
||||
- `POST /api/v1/runs/:runId/commands` 在 `storage_kind='evicted'` 时直接短路返回 `session-store-evicted`,不创建 runner Job。
|
||||
- runner Job manifest 必须含 `volumes: [{ name: agentrun-sessions, persistentVolumeClaim: { claimName: ... } }]` 与对应 `volumeMounts`;PVC `Phase=Bound` 才允许启动 turn。
|
||||
- codex 写 `${CODEX_HOME}/<subdir>/YYYY/MM/DD/rollout-<timestamp>-<threadId>.jsonl`;其他路径不进入 PVC。
|
||||
- GC 在 `expires_at` 过期且无 active run 时删 PVC;删 PVC 同时把 `storage_kind` 置为 `evicted`。
|
||||
- HWLAB Cloud Web Workbench(PR D)收到 `session-store-evicted` 时走「同 conversationId + 新 sessionId + `threadId=null`」的 reset UX,不假装续接;新 session 走 `POST /api/v1/sessions` 重新创建 PVC。
|
||||
|
||||
### P1 ResourceBundleRef / bundle materialization
|
||||
|
||||
`ResourceBundleRef` 必须按 Git-only 模型落地:`repoUrl + full commitId` 是唯一内容身份。runner 只能 checkout 到允许 workspace 前缀,不能覆盖 `/app`、Secret projection、profile runtime home 或 session 目录。第一阶段支持 `subdir`、`sparsePaths`、`submodules=false`、`lfs=false`、`credentialRef` 的最小字段即可。HWLAB canary 只需要 `pikasTech/HWLAB` 固定 full commit 的普通 checkout;用户上传文件和对象存储 artifact 不进入 `v0.1`。
|
||||
@@ -213,6 +233,7 @@ HWLAB 旧 Code Agent 的业务 prompt 和 skill 注入必须迁移为 `ResourceB
|
||||
| trace/result 元语 | 已实现最小合同 | 新增 run/command result envelope,聚合 terminal status、reply、failureKind、event cursor、artifact summary、attempt、SessionRef 和 ResourceBundleRef 摘要。 |
|
||||
| cancel | 已实现最小闭环 | 已提供 run/command cancel API;pending cancel 会阻止新 runner Job,running runner 通过轮询触发 backend abort,终态写入 event、command state 和 run status。 |
|
||||
| SessionRef | 已实现最小持久化 | run 可携带 `sessionRef`,manager 保存 session/thread,runner 会按 threadId resume,result envelope 暴露脱敏 session 摘要;TTL/GC 仍按后续运维策略细化。 |
|
||||
| SessionRef | v0.1.1 实现中/未发布 | 在「metadata-only 最小持久化」基础上把 session 真实持久化:每个 session 绑 RWO PVC(`agentrun-v01-session-<sessionId>`),runner Job 把 PVC 直接挂到 `${CODEX_HOME}/<codex_rollout_subdir>`,codex app-server 自己落盘;HWLAB Cloud Web Workbench 收到 `session-store-evicted` 走 reset UX,**不**写 fake 续接。 |
|
||||
| ResourceBundleRef | 已实现 Git-only materialization/待 promptRefs 与 skillRefs | run 可携带 `repoUrl + full commitId`,runner checkout 到 `AGENTRUN_WORKSPACE_ROOT` 下的隔离目录并记录 commit/tree/workspace 摘要;`toolAliases` 已实现;上传文件和对象存储仍不进入 v0.1;HWLAB 初始 prompt 与 skill 注入按本规格待补齐。 |
|
||||
| 同 run/runner 多 turn | 已实现最小闭环 | runner Job 在 idle timeout 内持续 poll 同一 run 的后续 command;普通 turn completed 不终结 run,bundle 只 materialize 一次,command result 按 commandId 独立聚合。 |
|
||||
| HWLAB v0.2 canary | 待实现 | 需要 HWLAB dispatcher adapter 调 AgentRun 手动调度 API,并转换 result/trace。 |
|
||||
|
||||
Reference in New Issue
Block a user