fix(ql3): bind post-apply target baseline

This commit is contained in:
whyour
2026-08-30 21:11:47 +08:00
parent 419e1bc141
commit 784e77a971
10 changed files with 651 additions and 29 deletions
+2
View File
@@ -1,5 +1,7 @@
# QingLong 3.0 Architecture RFC
- D-426b2a/ADR-0523(源码候选,尚未形成新阶段实物):修复 D-426b 的真实架构矛盾:受认证 `local-data-directory.adoption.apply` 必然在 target 启动前改变 activation 中记录的 SQLite 内容摘要,因此旧 classifier 会把“apply 后未产生任何 target 写入”的合法停止错误判为 `reconciliation_required`。现仅为 `docker-target` adopted Application v4 发布 no-replace 私有 `service/adopted-target-baseline.json`,绑定 activation/legacy commitment、Application semantic digest、data application commit/receipt、target path/device/inode/SHA-256 和 sidecar-clear 事实;v4 target start/stop 必须闭合该基线,缺失或漂移进入 `manual_review`,启动后写入进入 `reconciliation_required`,未写入才得到 `rollback_candidate`。v3/fresh 与历史 journal shape/activation 语义保持不变;新停止证据同时保留真实 `targetMatchesActivation` 并增加 `baselineKind/baselineDigest/targetMatchesBaseline`。Local Owner CLI 完整包级门为 `308 total / 301 pass / 7 conditional skip / 0 fail`。没有新增 workspace package、依赖、daemon、listener、timer、watcher 或稳态资源。本切片仍不能冒充 D-426b2 阶段包:必须等 exact 上传 bundle 实跑 reviewed stage、transform/verify、Owner 强认证 apply/verify、真实 legacy stop、target start/stop 与 clean rollback,再生成同源双架构 artifact;当前可交付升级实物仍是 D-426a。
- D-426b1/ADR-0522(源码候选,尚未形成新阶段实物):D-426a 暴露出真实的离线切换缺口:Trial Kit archive 只有本地 image reference 与 Docker content ID,既有 target barrier 却只接受 registry `name@sha256:...`;伪造 GHCR RepoDigest 或 Alpha release catalog 会污染正式发布权威。现统一引入 `{authority,reference,imageId}` target image identity,正式部署保持 `registry-digest`,离线 Trial Kit 使用 `local-image-id`,两者都同时核对容器 `Config.Image``.Image` content ID,并把三项绑定进 cutover journal。adopted bundle 新增 `docker-target` service kind,生成 Application v4 与内容绑定的 `service/docker-target.json`,固定 numeric UID:GID、restart=no、network none、read-only rootfs、drop ALL、no-new-privileges、Profile memory/PID 和 exact read-write/read-only mountsdescriptor 不创建或启动容器。没有新增 package、依赖或稳态进程。该切片只有定向源码测试证据,不能替代已交付的 D-426a 双架构 artifact;必须等 D-426b2 在 exact 上传 bundle 上实跑受认证 transform/apply、target start/stop 和 clean `rollback_candidate`,才允许宣称新阶段产物。
- D-426a/ADR-0521(已交付同源双架构 headless Alpha 阶段实物):二十天研发的阶段产物继续从“只读盘点”推进到仍不触碰生产切换的 side-by-side 暂存。Trial Kit 新增 canonical `upgrade-rehearsal.sh`,只接受操作者从 D-425 完整 evidence 中审核并显式提交的 SQLite/data-directory plan digest;它核对整包与 exact Operator identity 后,在新的 `0700/0600` rehearsal root 内以 read-only legacy bind、无网络、只读 rootfs、drop-all、128 MiB/0.5 CPU/32 PID 顺序执行 SQLite stage/verify/activation 和完整目录 stage/verify。`stage-summary.json` 绑定 source/architecture、两个 reviewed plan、SQLite manifest/activation 与目录 manifest digest,并固定 `legacySource=read_only``cutover=not_authorized`。Trial Kit/verification/auditor 升为 `@v7/@v5/@v4`Local milestone 升为 `@v4` 并绑定双架构 `upgradeRehearsalSha256`;显式 artifact job 必须在将要上传的 exact bundle 上从 readiness plan 接续实跑 rehearsal。提交 `7a8acacb6cb49bda2116bf029fbbfe447ae5d911` 的普通 CI [run 33306005705](https://github.com/whyour/qinglong/actions/runs/33306005705) 为 41 success/3 expected scope skip/0 fail,同源 Kubernetes deployment [run 33306005706](https://github.com/whyour/qinglong/actions/runs/33306005706) 成功;显式 Local headless [run 33306650776](https://github.com/whyour/qinglong/actions/runs/33306650776) 为 42 success/2 Cluster scope skip/0 failexact 双架构 bundle 实跑 readiness 与 rehearsal 后生成 amd64 `187,554,547` bytes、arm64 `184,786,163` bytes 和 `6,206` bytes milestone v4,均保留至 2026-09-29。下载后的 milestone checksum 与离线 auditor 返回 `compatible=true`,并确认两个架构的 rehearsal digest 不同。没有 transform/apply、Owner/Secret authority、2.x stop、3.0 target start、cutover、rollback、migration、依赖、package、daemon、listener、timer 或稳态资源增量;D-426b/c 才分别闭合 adopted start/clean rollback 与 write-after reconciliation。
@@ -0,0 +1,52 @@
# ADR-0523Apply 后的 Adopted Target 启动前基线
- 状态:AcceptedD-426b2a 源码候选;阶段实物尚未闭合)
- 日期:2026-08-30
- 决策:D-426b2a
## 上下文
D-426b1 已生成 Application v4 与内容绑定的离线 `docker-target.json`,但既有 clean rollback 判定只把 SQLite activation 中的初始 target SHA-256 当成目标基线。受认证 `local-data-directory.adoption.apply` 必然在 target 启动前向同一 SQLite 写入 Project、加密 Secret、disabled model、audit 与 receipt;因此合法 apply 后的 target 与 activation 内容摘要必然不同。若继续使用旧判定,未产生任何 post-cutover 写入的 target 也会错误进入 `reconciliation_required`;若直接把 activation 基线全局替换,又会削弱 fresh、v3、service-manager 和历史回退语义。
同时,target controller 原先只接受 Application v3,不能消费 D-426b1 生成的 v4 配置。这个矛盾意味着仅靠绿色源码无法形成新的阶段升级产物。
## 决策
只有 `docker-target` adopted bundle 在受认证 apply 已提交、target 尚未启动时发布私有 `service/adopted-target-baseline.json`。基线固定绑定:
- Profile、instance、cutover、准备时间;
- activation 与 legacy-stopped commitment digest
- Application v4 semantic digest
- legacy data application commit/receipt digest
- target canonical path digest、device、inode、SHA-256
- `targetSidecarsClear=true`
- 上述 payload 的自摘要 `baselineDigest`
publication 使用现有 no-replace 私有文件协议。存在 SQLite WAL/SHM/journal、目标身份变化、配置/commit/receipt 漂移、基线缺失或自摘要不一致都 fail closed。
target controller 同时接受原有 Application v3 与 adopted Application v4
- v3/fresh 继续以 activation target SHA-256 判定,记录形状和旧语义不变;
- v4 必须读取并闭合 post-apply baseline;不得在缺失时退回 activation
- v4 停止证据新增 `baselineKind=adopted_target``baselineDigest``targetMatchesBaseline`,同时保留真实的 `targetMatchesActivation`
- baseline 未变且 legacy source/sidecar 未变才是 `rollback_candidate`target 启动后发生写入则为 `reconciliation_required`;基线无法证明则为 `manual_review`
旧 reconciliation journal 继续按原 exact shape 验证。新 shape 只对 adopted baseline 开放,并要求 disposition 与 `targetMatchesBaseline`、sidecar、source facts 一致。没有新增 workspace package、生产依赖、daemon、listener、timer、watcher 或稳态资源。
## 阶段实物门
本 ADR 只闭合此前不合理的 rollback 语义,仍不是新的可下载 Trial Kit。D-426a 双架构 headless bundle 仍是当前可交付的升级阶段实物。只有同源原生 amd64/arm64 artifact job 在将要上传的 exact bundle 上完成:
1. reviewed stage/verify
2. versioned transform/verify
3. Owner credential + `secret.manage` 认证的 apply/verify
4. exact offline image target 创建;
5. 真实 legacy stop、target start/stop
6. v4 baseline 绑定且最终为 clean `rollback_candidate`
7. bundle 与 milestone 离线审计;
才能把 D-426b2 升级为阶段实物。任何一步只在仓库测试 fixture 中通过都不能替代 exact 上传包演练。
## 后续
D-426b2b 实现并审计上述 exact bundle 用户旅程,随后显式生成新的双架构 artifact。D-426c 继续处理 target 产生业务写入后的 capture、review、reconciliation 与恢复。