test(ql3): audit plugin recovery evidence

This commit is contained in:
whyour
2026-08-14 14:24:29 +08:00
parent 2485d61e8a
commit 1c75ac0f45
9 changed files with 952 additions and 27 deletions
+1 -1
View File
@@ -35,7 +35,7 @@
- 2026-08-14 终态恢复更新:Secret Action controller 不再把所有终态 Job 仅计为瞬时 `recoveryRequired`。Job 到达 Complete/Failed 后已停止执行,controller 会用 started execution 的原 lease fence 复验不可变业务结果:首次 binding 必须与 approval plan、`startedAtMs` 推导出的 binding 完全一致;transition 必须与 plan、authority evidence、commit time 推导出的 receipt 完全一致。精确 durable result 存在时补写 `succeeded`,即使 Job 已被 TTL 清理也能收敛;Failed 且无 durable mutation 时写 `failed`Complete 但无 receipt 时以 `indeterminate``blocked`。Job 在 start barrier 前终态或审批过期且尚未创建时,controller 复用既有 claim→release fence 写 `blocked`,不让坏 Job 永久占据 reconciler 页首。任何 stored result 漂移继续抛出 conflict`executing + Job 缺失 + receipt 缺失` 继续要求人工处理,绝不自动重建可能已产生副作用的动作。该切片不修改共享 execution schema、PostgreSQL migration 或角色权限,不新增 package、连接与常驻进程;Cluster controller 复用现有 package-executor PoolEdge 零变化。controller/process 定向 21/21cluster-admin 全包 348 项为 345 pass/3 条件 skip/0 fail;完整 18-package 串行 build/test 退出 0backend 1196 项为 1194 pass/2 条件 skip/0 failpackage boundary、cluster dependency、edge import、cluster deployment 均无 finding,部署/包边界聚焦测试 61/61。PostgreSQL `18.4` arm64 physical HA 125 项、timeline `1→2` 通过,报告 SHA-256 为 `bec512767fbbd7774baa9366698f60c25c8b017ed66f459b154d143fe86293bc`,临时 Docker 资源已清理。
- 2026-08-14 人工恢复更新(ADR-0397,已接受):上述唯一保留的 `executing + Job/receipt 均缺失` 不确定窗口现在具有显式 Cluster 产品处置路径。既有 Approval management mTLS/OIDC endpoint 新增 `approval.recover.inspect|resolve`,只接受五分钟内 `multi_factor|hardware` User、独立 `approval.recover` 权限、二次认证、exact execution version/digest 和外部 evidence SHA-256。只允许 Secret binding/transition action`confirm_failed` 写 failed`abandon_unknown` 写 blocked,永远禁止人工 succeeded、Job 重建或 execution 重置。PostgreSQL `pg-0065`/capability v64 新增不可变 resolution ledger 与单个 SECURITY DEFINER resolver,在同一事务内锁 Policy/execution fence、写 allowed audit、推进终态并写 receiptApproval manager 只有 dispatch/execution/resolution SELECT 与函数 EXECUTE,没有 execution UPDATE。通用 execution repository 与 Worker Credential 调用链保持不变。真实 PostgreSQL 18.4 已从空库完成 65 migration,证明原子提交、exact replay 不重复审计和 direct UPDATE `42501`;实现不新增 package、依赖、Pod、Pool、daemon、timer、watcher 或 Edge/Standalone 负担。18-package clean build/test 退出 0backend 1,194 pass/2 skip/0 failpackage/dependency/edge/deployment 审计零 finding;新 migration 与 repository 内聚到 `approved-action` 领域,migration ledger 直属源码保持审定上限 65。PostgreSQL 18.4 arm64 physical HA 125 项 gate、timeline `1→2` 通过,报告 SHA-256 为 `6d4921cba74475d15722a13c6a8034793c0ee25681bc7dcaf91024927c5752fe`,临时 Docker 资源已清理。
- 2026-08-14 升级失败收口(ADR-0398,进行中):已存在旧 active 的 `upgrade|reinstall|rollback` 不再先切 active pointer 再物化 Package 资源。共享 activation prerequisite sequence 固定为 Secret binding/transition receipt 就绪后,从 staged install 与 immutable lock 构建候选 generation,按既有字节上限完成 Manifest、Task、Workflow、Prompt、Tool 语义物化,并以 generation digest 预发布 immutable revision;只有成功后才进入 active pointer CAS。确定性候选错误把本次 install 写为 `failed(activation_fact_conflict)``activeLockDigest` 保持 `previousActiveLockDigest` 且 publisher 不被调用;瞬时文件/OCI/数据库故障保持 staged 重试。generation 1 没有旧版本可保留,Secret-aware 首次安装继续使用 ADR-0395 的 post-activation B1 binding ceremony,不被候选门错误拒绝。激活后的 publication recovery 只复用 revision 做 generation-fenced reconciliation。实现复用既有 18 个 package、双方言 repository、Local 单 SQLite authority 与 Cluster caller-driven recovery Job/单 Pool,不新增 migration、表、依赖、daemon、timer、watcher、listener、连接池或常驻 cache。定向 Runtime Core 21/21、Runtime Core 全量 548/548、Local Application 47 pass/4 条件 skip、Cluster Admin 347 pass/3 条件 skip18-package clean build/test 退出 0backend 1196 项为 1194 pass/2 条件 skip/0 failpackage boundary、cluster dependency、cluster deployment 与 edge import 审计均通过。PostgreSQL `18.4` arm64 physical HA 125 项、timeline `1→2` 通过,报告 SHA-256 `75d7a52be75c22b2aacf32f2d7e2c432a467ebaab4d639668ff3a4b98767a17e`。真实 Kubernetes 失败升级未移动 active pointer/head 的现场门与固定物理低配设备证据仍待闭合。
- 2026-08-14 失败升级现场门更新:既有 PostgreSQL/OCI/Kubernetes recovery E2E 已升级为 report v2。门先激活 signed OCI generation 1,再排入包含合法 Task 与循环 Workflow 的 generation 2;第一次 recovery 必须因 transition receipt 缺失而失败并保持 staged,提交 content-free receipt 后,第二次 recovery 必须确定性写入 `failed(activation_fact_conflict)`,且 generation 2 materialized revision 数量为 0。门在升级前后逐字比较 active ConfigMap UID、`resourceVersion` 与完整 `active.json`,从而排除“先切 pointer、再补偿”的假安全;OCI v1 六路径各取一次、v2 六路径各取两次,全部要求 HTTPS、exact Basic authentication 与零 redirect。runtime rollout 只绑定最终成功 recovery JobConfigMap-only RBAC 与 runtime 数据库隔离保持不变。源码契约 7/7、18-package clean build/test、backend 1194 pass/2 skip/0 failpackage/dependency/deployment/edge 审计均通过;PostgreSQL 18.4 arm64 physical HA 125 gate、timeline `1→2` 通过,报告 SHA-256 `8560469694c67776e5e4c70977f8bde8d4f5635f8e7d1c293ef449dc6da59f72`。本机 admin/control 镜像构建成功,但固定 Kind 1.32.8 节点镜像不在缓存且受限网络无法取得,门在创建节点前中止并确认无遗留集群/容器;因此远端 Kubernetes 成功记录与固定物理低配设备证据仍阻断 ADR Accepted。
- 2026-08-14 失败升级现场门更新:既有 PostgreSQL/OCI/Kubernetes recovery E2E 已升级为 report v2。门先激活 signed OCI generation 1,再排入包含合法 Task 与循环 Workflow 的 generation 2;第一次 recovery 必须因 transition receipt 缺失而失败并保持 staged,提交 content-free receipt 后,第二次 recovery 必须确定性写入 `failed(activation_fact_conflict)`,且 generation 2 materialized revision 数量为 0。门在升级前后逐字比较 active ConfigMap UID、`resourceVersion` 与完整 `active.json`,从而排除“先切 pointer、再补偿”的假安全;OCI v1 六路径各取一次、v2 六路径各取两次,全部要求 HTTPS、exact Basic authentication 与零 redirect。runtime rollout 只绑定最终成功 recovery JobConfigMap-only RBAC 与 runtime 数据库隔离保持不变。证据链现强制使用 canonical absolute path 原子写入 `0600` no-replace 私有报告,绑定 40-hex source revision 与 admin/control OCI revision label;持久报告只保存 active JSON digest,不保存原始 pointer、credential、DSN、kubeconfig、证书或 Secret material。独立离线审计以 `O_NOFOLLOW` 和 inode/mode/size 复验文件,并 exact-shape 校验 provenance、ordering、数据库/OCI/RBAC/runtime 事实、11 个 gate 和 limitationCI 审计成功后上传固定 14 天的 evidence artifact。该链路只增加验收代码,不增加产品 package、依赖或低配/集群运行时常驻开销。本轮 producer/离线审计契约 14/14、18-package clean build/test 退出 0、backend 1201 pass/2 skip/0 failpackage/dependency/deployment/edge 审计均通过;PostgreSQL 18.4 arm64 physical HA 125 gate、timeline `1→2` 通过,报告 SHA-256 `8560469694c67776e5e4c70977f8bde8d4f5635f8e7d1c293ef449dc6da59f72`。本机 admin/control 镜像构建成功,但固定 Kind 1.32.8 节点镜像不在缓存且受限网络无法取得,门在创建节点前中止并确认无遗留集群/容器;因此远端 Kubernetes 成功记录与固定物理低配设备证据仍阻断 ADR Accepted。
- D-302/ADR-0390(已接受)
Cluster operator context 增加无网络、无 mutation 的内建 `ql3-cluster-admin context validate` 预检。它先复用 owner-private context
reader,再让每个 entry 经过与真实请求相同的 production HTTPS/Kubernetes configuration preparation,验证精确 route、hostname、CA、
@@ -70,12 +70,19 @@ ConfigMap 和数据库 head 之间会出现第二次分布式提交窗口,并
`resourceVersion` 与完整 `active.json`,因此不能用“错误切换后再补偿回来”冒充旧版本未移动;OCI v1 六个路径各读取一次,v2 六个路径
各读取两次,全部要求 HTTPS、exact Basic authentication、200 且无 redirect。最终 runtime rollout 仍只绑定最后一个成功 recovery Job
recovery ServiceAccount 继续只有 ConfigMap `get|create|update`,runtime 角色仍不能读取安装 authority。
- 18-package clean build/test 在允许 loopback TLS 的环境退出 0backend 1196 项为
1194 pass/2 条件 skip/0 fail。新增/更新的 recovery E2E 源码契约 7/7Runtime Core 定向 21/21。package boundary 保持 18 个 package 且
- v2 现场门现在强制接收 canonical absolute `--report`,以 `0600` 临时文件、`fsync` 与 no-replace hard link 原子发布
owner-private 报告;目标已存在、父目录为 symlink、缺少显式 opt-in 或缺少 40-hex `QL3_SOURCE_REVISION` 时,均在访问
Docker/Kind 前失败关闭。admin/control 镜像的 OCI revision label 必须与报告源码 revision 相同;报告只保存 active JSON 的
SHA-256,不保存原始 pointer、Registry credential、数据库 DSN、kubeconfig、证书或 Secret material。独立离线审计对 envelope、
镜像 provenance、六段单调 ordering、数据库精确计数、OCI 18 次认证请求、ConfigMap-only RBAC、双节点 runtime 绑定、全部
11 个 gate 与三项 limitation 做 exact-shape 校验,并以 `O_NOFOLLOW`/inode/mode/size 复验私有报告。CI 在独立 job 内先审计,
再上传固定 14 天的 source-bound evidence artifact;这一证据链只属于验收,不新增产品 package、依赖或运行时常驻开销。
- 18-package clean build/test 在允许 loopback TLS 的环境退出 0backend 1203 项为
1201 pass/2 条件 skip/0 fail。新增/更新的 recovery E2E producer/离线审计契约 14/14Runtime Core 定向 21/21。package boundary 保持 18 个 package 且
`singleSourcePackages=[]``shallowSourcePackages=[]`cluster dependency、cluster deployment
与 edge import 审计均无 finding。
- PostgreSQL `18.4` arm64 physical HA 通过 125 项门,timeline `1→2`,报告 SHA-256
`8560469694c67776e5e4c70977f8bde8d4f5635f8e7d1c293ef449dc6da59f72`,临时 Docker
资源已清理。本机已成功构建现场门所需 admin/control 镜像,但固定 `kindest/node:v1.32.8` 不在本地缓存,受限网络拉取数分钟无进度;
门在创建任何 Kind 节点前被中止,并确认没有遗留集群或容器。因此 v2 门的代码与离线契约已完成,但仍不能计为真实 Kubernetes
门在创建任何 Kind 节点前被中止,并确认没有遗留集群或容器。因此 v2 门、私有报告与离线审计代码已完成,但仍不能计为真实 Kubernetes
现场通过;远端 CI 成功记录与固定物理低配设备证据仍待完成,本 ADR 保持 Proposed。
+1 -1
View File
@@ -401,7 +401,7 @@
| [ADR-0395](./ADR-0395-owner-confirmed-plugin-package-secret-binding.md) | Owner 确认的 Plugin Package Secret 首次绑定 | Proposed |
| [ADR-0396](./ADR-0396-generation-transition-plugin-package-secret-binding.md) | 按 Package Generation 切换 Plugin Package Secret Binding | Proposed |
| [ADR-0397](./ADR-0397-explicit-cluster-secret-action-manual-recovery.md) | Cluster Secret Action 显式人工恢复 | Accepted(实现、单节点 PostgreSQL、完整 workspace/后端/边界与 physical HA 门完成) |
| [ADR-0398](./ADR-0398-pre-activation-plugin-package-candidate-qualification.md) | Plugin Package 激活前候选资格校验与自动保留旧版本 | Proposedv2 现场门已编排、全量/HA 门完成;远端 Kubernetes 成功记录与物理低配门待闭合) |
| [ADR-0398](./ADR-0398-pre-activation-plugin-package-candidate-qualification.md) | Plugin Package 激活前候选资格校验与自动保留旧版本 | Proposedv2 私有报告/离线审计已编排、全量/HA 门完成;远端 Kubernetes 成功记录与物理低配门待闭合) |
## 规则