feat(local): publish secret config application atomically

This commit is contained in:
whyour
2026-08-24 00:11:48 +08:00
parent e261d4130d
commit f822e92b02
25 changed files with 2149 additions and 58 deletions
+18 -12
View File
@@ -6,10 +6,10 @@
- 目标版本:QingLong 3.x
- 作者:QingLong Maintainers
- 创建日期:2026-07-17
- 最后更新:2026-08-23
- 最后更新:2026-08-24
- 讨论范围:架构与演进路线,不包含最终 UI 视觉方案
最新增量证据(2026-08-23):
最新增量证据(2026-08-24):
- D-397/ADR-0491(进行中):Secret/Config reconciliation 已先冻结行为保持边界,不能把“密文已保存”冒充“任务已迁移”。2.x `Envs`
的 active 行必须按 `isPinned DESC、position DESC、createdAt ASC、id ASC` 重放旧顺序,同名值用 `&` 形成唯一 effective Secret;该
@@ -37,18 +37,24 @@
digest。Secret/Config planner 不再扫描 `legacy-cron:*` 或相信聚合计数,而是流式复算 provenance,并验证当前 Task/Trigger head、Trigger schedule 与非
Plugin ownership。旧记录缺少逐项 provenance 为 `missing`current revision/schedule/ownership 漂移为 `drifted`,两者都强制
`manual_required`;不得猜测或自动回填。聚合 adoption 记录仍只保留 Edge/Standalone 128/512 条有界 MapTask/Trigger 逐行读取,无目标规模 Set。
全部 evidence 不含原 Env name/value、目标 ciphertext/key ID 或 row body。Local SQLite、Local Admin 与 Local Owner 完整测试分别为 `241/241`
`96/96``296 total / 289 pass / 7 conditional skip / 0 fail`18-package clean build/test 在非沙箱环境全部通过。后端完整门在受限沙箱中为
`1544 total / 1531 pass / 11 loopback EPERM / 2 conditional skip`,四个受影响文件随后在非沙箱环境 `38/38` 通过,未发现代码失败。package
boundary、72 项 Cluster dependency/legacy boundary、Edge import、本地镜像与十四档 Local artifact audit 全部 compatible;基础 Edge/Standalone 为
`2,620,531 / 2,620,609 bytes`、321 files、58 loaded modulesOwner-only authority 没有进入低资源常驻制品。fresh Edge readiness 为 contract v51、
102 migrations、85 tables、SQLite 3.53.3、`DELETE` journalPostgreSQL 18.6 arm64 physical HA 以 timeline `1 → 2`、146 gates 通过。
Local Admin 保持 48/47Local Owner 因六个职责明确的 decision 嵌套文件增至 184/183,根目录仍只有一个 50 行 binary entryworkspace 仍为 18 packages、
`singleSourcePackages=[]``shallowSourcePackages=[]`,且只允许 exact Secret/Config row planner 导入 inspection subpath。
第六切片把原子 DML 下沉到既有 `@qinglong/local-sqlite/secret-config-application` 私有短生命周期 authority,不新增 package 或 Cluster 依赖。contract v52
增加 application/secret/task/trigger 四类 ledgerpublisher 在一个 `BEGIN IMMEDIATE` 内复验 Project/RoleBinding、两次外部 authority、逐项 provenance、当前
Task/Trigger head、Plugin ownership 与每 Task Trigger 数量,然后同时写入加密 Secret、content-free audit、Task rev2、local dispatch、Trigger rev2、schedule
和 receipt。item 使用 deferred parent FK 流式落库,最终 receipt 才关闭父引用,因此最多 100,000 Task/500,000 Trigger 不进入 JS 全集或 O(N×M) 扫描。
commit response-loss exact replay 会重验 Secret envelope、Task/Trigger durable head 与 scheduleSecret 占用、provenance 缺项和提交前 authority 漂移均回滚全部 DML。
全部 evidence 不含原 Env name/value、目标 ciphertext/key ID 或 row body。v52 Local SQLite 完整测试为 `247/247`publisher 定向回归 `6/6`fresh Edge
readiness 为 contract v52、104 migrations、89 required tables、SQLite 3.53.3、`DELETE` journal。Local Owner 为
`296 total / 289 pass / 7 conditional skip / 0 fail`18-package clean build 与逐包顺序测试单次退出 0,完整 backend 为
`1566 total / 1564 pass / 2 conditional skip / 0 fail`。package boundary、Cluster dependency/legacy boundary、122-module Edge import、本地镜像与
`14/14` Local artifact audit 全部 compatible;基础 Edge/Standalone 为 `2,635,529 / 2,635,607 bytes`、323 files、58 loaded modules,距 4 MiB
上限仍分别保留 `1,558,775 / 1,558,697 bytes`,且闭包只有 Local SQLite、runtime-core 与 SemVer,没有 Cluster/PostgreSQL 依赖。
Local SQLite 为 209 source / 208 nested / 1 root public exportLocal Owner 保持 184/183,根目录仍只有一个 50 行 binary entryworkspace 仍为
18 packages、`singleSourcePackages=[]``shallowSourcePackages=[]`。本切片不改 PostgreSQL schema、连接、role、Pool、容器或 Kubernetes 拓扑,
因而不重跑且不重新占有 PostgreSQL HA 证明;相邻已通过的 remote CI/HA 只作为基线。
D-385D-388 的 `config.sh`/Keyv/SSH data-directory lineage 与 SQLite `Envs` 保持分离;当前无稳定生产 schema 的历史 `Configs` 表继续 sealed+manual
不猜字段。后续切片必须完成 Secret envelope + audit + Task/Trigger/dispatch + receipt ledger 的单事务发布、prepared/apply/rollback
lineage、completion 下一 schema 与备份回收。D-397 apply 只声明 sealed source retained 且 `physicalErasureGuaranteed=false`;明文销毁必须在 restart/
不猜字段。后续切片必须完成 Owner prepared/apply/rollback、写前 backup、receipt/head/seal response-loss、completion 下一 schema 与备份回收。D-397 apply
只声明 sealed source retained 且 `physicalErasureGuaranteed=false`;明文销毁必须在 restart/
readiness、观察窗和 rollback retention 之后另行强认证。Cluster 必须使用 PostgreSQL SERIALIZABLE ledger、外部 KMS/Secret provider 与 HA evidence
不复用 Local SQLite/POSIX authority,也不得把明文写入 PostgreSQL、ConfigMap、Pod env 或 Job command。
@@ -1,6 +1,6 @@
# ADR-0491:有界 Secret/Config Reconciliation 与任务环境绑定
- 状态:ProposedD-397 已实现 Legacy Env inspection、私有有界 row plan、durable plan publication、独立 signed decision逐项 Automation adoption provenance;原子 application 尚未完成)
- 状态:ProposedD-397 已实现 Legacy Env inspection、私有有界 row plan、durable plan publication、独立 signed decision逐项 Automation adoption provenance 与 Local SQLite 原子 application publisherOwner prepared/apply/rollback 编排尚未完成)
- 日期:2026-08-23
- 决策:D-397
- 关联:ADR-0073、ADR-0074、ADR-0092、ADR-0094、ADR-0480、ADR-0482、ADR-0483、ADR-0484、ADR-0485、ADR-0486、ADR-0487、ADR-0488、ADR-0490
@@ -137,8 +137,8 @@ Cluster 不得把 Legacy Env 明文写入 PostgreSQL、ConfigMap、Job command
## 当前验证与后续门禁
D-397 当前切片已经实现:absent、unsupported、Edge over-budget、2.x 顺序、同名连接、disabled preservation、保留前缀、异常状态、effective overflow、candidate digest、content-free diagnostics、私有有界 row plan、目标 Secret 冲突、Automation adoption projection、no-effect/manual outcome、durable no-replace publication、terminal seal、head CAS、逐候选独立 signed decision、同一强认证 reviewer、decision/authorization byte bound、`skip → manual_required`、prepare/commit response-loss exact replay、只读 terminal verify,以及 v51 逐 Task/Trigger adoption provenance。新 provenance 与 Automation Task/Trigger/audit/ledger 在同一事务发布并在 replay 时完整流式复算;Secret/Config plan 对 complete、missing、current-revision drift 和 Plugin ownership 失败关闭
D-397 当前切片已经实现:absent、unsupported、Edge over-budget、2.x 顺序、同名连接、disabled preservation、保留前缀、异常状态、effective overflow、candidate digest、content-free diagnostics、私有有界 row plan、目标 Secret 冲突、Automation adoption projection、no-effect/manual outcome、durable no-replace publication、terminal seal、head CAS、逐候选独立 signed decision、同一强认证 reviewer、decision/authorization byte bound、`skip → manual_required`、prepare/commit response-loss exact replay、只读 terminal verifyv51 逐 Task/Trigger adoption provenance,以及 v52 Local SQLite 原子 application publisher。v52 在一个 `BEGIN IMMEDIATE` 内复验 Project/RoleBinding、外部 authority、逐 Task/Trigger provenance、当前 head、Plugin ownership 与 Trigger 数量,流式写入加密 Secret、content-free audit、Task rev2、dispatch、Trigger rev2、schedule 和四类 application ledgerdeferred parent FK 允许最多 100,000 Task/500,000 Trigger 逐项发布而不在 JS 堆保留全集。commit response-loss 通过 durable receipt exact replay,并重新验证 Secret envelope、Task/Trigger head 与 schedule;目标占用、provenance 缺项、提交前 authority 漂移均回滚全部 DML
本切片验证已闭合Local SQLite `241/241`、Local Admin `96/96`Local Owner `296 total / 289 pass / 7 conditional skip / 0 fail`Secret/Config 定向回归 `51/51`18-package clean build/test 在非沙箱环境全部通过。后端完整门在受限沙箱中仅有 11 个 loopback `listen EPERM`,四个受影响文件在非沙箱环境 `38/38` 通过。package boundary 保持 18 packages、`singleSourcePackages=[]``shallowSourcePackages=[]`72 项 Cluster dependency/legacy boundary、Edge import、本地镜像与十四档 artifact audit 全 compatible;基础 Edge/Standalone 为 `2,620,531 / 2,620,609 bytes`、321 files、58 modules。fresh Edge readiness 为 contract v51、102 migrations、85 tables、SQLite 3.53.3、`DELETE` journal。PostgreSQL 18.6 arm64 physical HA 以 146 gates、timeline `1 → 2` 通过;两次前置 `initdb` 超时均由本机 Docker 虚拟磁盘 100% 占满导致,释放可重建缓存后同一门成功
本切片当前验证:Local SQLite `247/247`,其中 Secret/Config application publisher 定向回归 `6/6`fresh Edge readiness 为 contract v52、104 migrations、89 required tables、SQLite 3.53.3、`DELETE` journal。Local Owner `296 total / 289 pass / 7 conditional skip / 0 fail`18-package clean build 与逐包顺序测试单次退出 0,完整 backend 为 `1566 total / 1564 pass / 2 conditional skip / 0 fail`。package boundary、Cluster dependency/legacy boundary、122-module Edge import、本地镜像与 `14/14` Local artifact audit 全 compatible;基础 Edge/Standalone 为 `2,635,529 / 2,635,607 bytes`、323 files、58 loaded modules,且没有 Cluster/PostgreSQL 闭包。本切片不改 PostgreSQL schema、连接、role、Pool、容器或 Kubernetes 拓扑,因此不重跑且不重新占有 PostgreSQL HA 证明
转为 Accepted 前仍必须完成:原子 Secret/Task/Trigger/dispatch publisher、prepared/apply/rollback response-loss、completion schema 演进、在后续原子 application 切片上重新执行 18-package/boundary/artifact gates、真实 Edge 空间预算与 Cluster Secret provider live gate;本切片的 PostgreSQL HA 证据不得冒充后续 Cluster 密钥托管证明
转为 Accepted 前仍必须完成:Owner prepared/apply/rollback 与写前 backup、application receipt/head/seal response-loss、completion schema 演进、真实 Edge 空间预算与 Cluster Secret provider live gate;本切片的 Local SQLite publisher 或 PostgreSQL HA 证据不得冒充 Owner 编排、外部密钥托管或跨领域 completion 已完成
+1 -1
View File
@@ -12,7 +12,7 @@
},
{
"kind": "ordered_ledger",
"maxDirectSourceFiles": 103,
"maxDirectSourceFiles": 105,
"path": "packages/ql3-local-sqlite/src/migrations",
"rationale": "SQLite migrations are an append-only version ledger whose ordering and discoverability are safer in one reviewed directory."
}