5.3 KiB
ADR-0493:目标原生 Reconciliation 域分类与身份保留
- 状态:Accepted
- 日期:2026-08-24
- 决策:D-398
- 关联:ADR-0483、ADR-0484、ADR-0485、ADR-0488、ADR-0492
背景
Reconciliation 必须同时处理两类不同事实:从 2.x 迁入的数据,以及已经属于 QingLong 3.0 目标库的原生数据。此前实现把 identity_policy_audit 整域无条件标为 manual_required/identity_custody_required,因此即使 Legacy 完全没有 Auths/Users,fresh v52 目标库自带的 Project、RoleBinding、Credential、Pepper、SecurityAudit 与 LocalOwner 表也会阻止全局 completion。
同一盘点还发现 fresh v52 的六张已知表没有进入稳定领域,被误归为 unknown:
- Automation:
QingLong3LegacyAdoptions、QingLong3LegacyAdoptionTasks、QingLong3LocalExecutionContextRecipes、QingLong3LocalTaskExecutionRevisions; - Run History:
QingLong3RunAttemptLogArtifactTombstones、QingLong3RunAttemptLogRetentionState。
这不是缺少新 adapter,而是现有 planner 对目标原生 schema 的知识不完整。为绕过门禁而伪造 completion receipt 或把整个 QingLong3* 前缀视为可信都会破坏 fail-closed 边界。
决策
1. 已知目标表使用精确领域目录
上述六张表按精确表名分别归入 Automation 与 Run History。Schema object 继续按其 tableName 继承同一领域,因此相关 index/trigger 不需要单独的宽泛名称规则。
不引入 QingLong3*、LegacyAdoption* 或 Local* 的整体通配。未来新增但尚未登记的目标表仍进入 unknown,不读取行数,并要求人工外部处理。
2. 目标原生身份是保留事实,不是迁移事实
identity_policy_audit 的 disposition 改为按来源判定:
- Legacy 存在
Auths/Users时继续manual_required; - Legacy 没有身份事实、Target 有已知身份事实时为
target_only; - 两端都没有时为
aligned。
Target 身份诊断是 required/reviewable_fact,必须在 signed review 中逐事实选择 retain_target 才能形成 no_effect application action。它不能选择 adopt_legacy 或 exclude_legacy。Legacy 身份诊断仍是 blocked/identity_custody_required,只允许 defer|manual_external,本 ADR 不声明 2.x credential、session、password hash、token、Policy 或 Audit 已迁移。
3. Completion 只消费既有闭合证据
本 ADR 不增加 completion schema、adapter、instance state 或绕过规则。目标原生身份经过 canonical diagnostics、signed decision 和 application summary 后,以既有 no_effect/application_summary 进入 completion;真正未知表和任何 Legacy 身份事实仍阻止 completion。
完整 v52 + Legacy Secret/Config fixture 必须通过真实 v3 completion,而不是测试直接构造 receipt、推进 head 或调用 storage collector。只有 completed head durable 后,Secret/Config backup 才能由既有流程回收。
4. 部署与资源边界不变
实现只修改既有 Local Owner 一次性 reconciliation planner/reviewer,没有新增 workspace package、production dependency、SQL migration、daemon、listener、timer、Pool、容器或 Kubernetes workload。Edge/Standalone 常驻闭包、SQLite cache 上限和 artifact 预算不变;Cluster 仍使用自己的 PostgreSQL、Secret provider 与 HA authority。
被拒绝的替代方案
为目标原生身份增加 migration adapter
拒绝。没有 Legacy 身份输入时不存在要迁移的数据;额外 adapter 只会复制已经由目标数据库拥有的事实并扩大权限面。
信任全部 QingLong3 前缀
拒绝。名称前缀不是 schema ownership 证明,会让未来未知表自动越过人工审查。
自动跳过目标身份评审
拒绝。target_only 仍必须形成逐事实 signed retain_target 决策,不能仅凭分类器直接授权 completion。
放行 Legacy Auths/Users
拒绝。旧身份材料的 custody、hash/token 兼容、撤销、Policy 与 Audit 语义尚未建立独立 adapter;本 ADR 只消除目标原生数据被误当成迁移输入的问题。
验证
- 定向回归
4/4:fresh v52unknown=0、目标身份retain_target、Legacy 身份继续 blocked、真正未知表继续 row-free/manual; - Secret/Config completion v3 使用真实
complete → replay → verify链路,首调completed、重放existing,receipt 为 v3 且 Identity/Unknown 均为no_effect; - completed head durable 后 Secret/Config backup 被回收,加密 material 与 receipt 保持只读;
- Local Owner 受限沙箱为
301 total / 291 pass / 7 conditional skip / 3 loopback EPERM,两个 loopback 文件在沙箱外15/15,有效结果301/294/7/0; - 完整 backend 为
1567 total / 1565 pass / 2 conditional skip / 0 fail;18-package clean build 与逐包顺序测试除 Worker 三条 sandbox loopback 外全部通过,对应 Worker 文件在沙箱外8/8; - package boundary、精确 Cluster dependency、122-module Edge import、service-manager bridge import、本地镜像与
14/14Local artifact audit 全部 compatible;workspace 保持 18 packages,singleSourcePackages=[]、shallowSourcePackages=[]; - 基础 Edge/Standalone 保持
2,635,529 / 2,635,607 bytes、323 files、58 loaded modules,没有 Cluster/PostgreSQL 闭包。