Files
qinglong/docs/adr/ADR-0323-local-sqlite-adoption-domain-ownership.md
T

114 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-0323Local SQLite Adoption 领域归属
- 状态:Accepted
- 日期:2026-08-10
- 关联 RFCQL-RFC-0001 D-05、D-06、D-17、D-64、D-87、D-257
- 关联 ADRADR-0064、ADR-0095、ADR-0312、ADR-0321、ADR-0322
## 背景
ADR-0321/0322 已区分 workspace package 与 package-private modulepackage 表达部署、authority、依赖、adapter、
multi-consumer 或供应链边界,包内领域目录表达共同变化的 ownership。继续审计 `@qinglong/local-admin` 时发现,
`legacy-adoption/localSqliteAdoption.ts` 以 1,940 行同时拥有:
1. Legacy SQLite read-only 打开、catalog 证据与 crontab inventory/diagnostic
2. reviewed decision receipt、authorization file、issuer 与 publisher bridge
3. migration staging、backup、manifest 与 snapshot verification
4. SQLite source `BEGIN IMMEDIATE` write fence
5. activation document、prepare 与 acquire。
这不是“包太细”,而是同一 Local Admin 运行单元内的五类 ownership 被平铺在一个文件中。把这些职责各自发布成
workspace package 会制造部署和依赖噪声;继续维持单文件则会让 inspection、review、staging 与 activation 的安全边界
难以独立评审。
编辑前已对原文件内全部 49 个 function、class 和 method 执行 GitNexus upstream impact。稳定错误
`LocalSqliteAdoptionError` 为 CRITICAL35 direct/55 total/0 flows);共享 path/file/hash helper 与
`inspectLegacySqlitePath` 主要为 MEDIUM,其余多数为 LOW。CRITICAL 风险已先告警,本轮只移动实现归属和维持同一
export identity,不改变 SQLite、文件系统或 adoption 协议。
## 决策
保持一个 `@qinglong/local-admin` package、一个既有 public subpath 和 66 行稳定 facade,在
`legacy-adoption/local-sqlite-adoption/` 下形成以下 package-private ownership
```text
localSqliteAdoption.ts # stable public facade
local-sqlite-adoption/
├── contracts.ts # schemas, types and stable error identity
├── filesystem.ts # path, file identity, hashing and atomic private writes
├── inspection.ts # legacy catalog and task inventory
├── staging.ts # backup, migration, manifest and verification
├── sourceFence.ts # shared SQLite source write fence
├── review.ts # reviewed receipt/authorization/publication bridge
└── activation.ts # activation prepare and acquire
```
内部依赖保持有向无环。`contracts.ts` 不取得文件系统或 SQLite authority`filesystem.ts` 只拥有通用的严格文件证据;
`inspection.ts` 保持 legacy adoption module 的 lazy load`staging.ts` 唯一拥有备份、migration 与 manifest
`sourceFence.ts` 是 review 和 activation 共同依赖的安全 primitive,单独放置以避免二者形成循环;`review.ts` 保持
reviewed authorization/publisher bridge 的 lazy load`activation.ts` 唯一拥有 activation 生命周期。
原 facade 只显式 re-export 既有公共类型和 13 个 runtime object。所有 runtime export 与 owner module 保持同一个
class/function identity`instanceof`、错误 code/message、package export 与调用路径不变;package-private
`FileIdentity`、hash、atomic write 和 fence helper 不扩展为公共 API。没有新增 public subpath、workspace package、
dependency 或部署单元。
本轮不修改:SQLite read-only inspection、catalog/schema evidence、任务分类、decision receipt/authorization、source
file identity、hash、backup、migration、manifest、原子写入、no-follow/realpath fence、`BEGIN IMMEDIATE`、snapshot
verification、activation fence、错误映射或返回结构。
## 包与目录粒度规则
`packages/*/src` 不应长期用大量无领域归属的平铺实现文件承载系统,但修复方式也不是“一目录一 package”。后续统一采用:
1. 只有独立 deployable、authority、dependency、adapter、multi-consumer 或供应链边界才能新建 workspace package
2. 同一 package 内按业务领域和共同变化原因建立私有目录,根 `src` 只保留受审 public facade、composition root 或 bin
3. 一个领域允许多个内聚文件,也允许一个纯 schema/codec 文件较大;不按 LOC、函数数或单文件 package 机械拆合;
4. 共享 helper 只有在具有稳定语义和两个以上真实 owner 时才提取,禁止建立 `utils/` 杂物层;
5. 拆分必须保持依赖 DAG、公共 export identity、Profile closure、制品预算与部署拓扑。
## 小设备与集群影响
本轮只影响包含 Local Admin adoption 能力的六档制品,分别增加 10,417 bytes/7 physical files,实际 loaded module 数
不变:Adopted 为 50、Application 为 116、Application AI 为 115。最小 Edge/Standalone 和基础 AI Profile 不包含
Local Admin,因此低配路由设备不会因为包内目录化增加其安装闭包或常驻模块。
六档 pack/install/import/RSS 门全部 compatible;本机 RSS 样本保持在现有 Profile 门限内。物理文件增加用于源码和
制品 ownership,不等于增加进程、线程、listener、timer、数据库连接或服务发现。
Cluster 继续通过原 Local Admin/Runtime contract 组合集群能力;本轮没有 SQL、migration、PostgreSQL、Cluster
runtime、Kubernetes resource 或部署拓扑变化,因此不重复 PostgreSQL HA Docker 门。
## 被否决方案
1. **七个 owner 各建 workspace package**:不存在七个独立部署或消费者闭包,拒绝。
2. **维持 1,940 行平铺文件**inspection、review、staging、fence 与 activation 无法独立评审,拒绝。
3. **每个 function 一个文件**:破坏同一协议的内聚性并增加导航成本,拒绝。
4. **把所有 helper 放进 `utils.ts`**:隐藏 file identity 与安全 fence 的真实 ownership,拒绝。
5. **把 source fence 归 review 或 activation**:另一侧会反向依赖并可能形成循环,拒绝。
6. **趁拆分重写 adoption 协议**CRITICAL blast radius 下无法区分 ownership 回归与语义回归,拒绝。
## 验收证据
- facade 1,940→66 行;contracts 229、filesystem 172、inspection 290、review 446、staging 504、sourceFence 117、
activation 311 行。
- facade 与 owner 的 13 个 runtime export identity 全部相同;Local Admin 91/91。
- 完整 16-package clean topology build/test 在允许 loopback TLS 与 crash 子进程的门环境退出 0。
- package boundary 为 16 package、830 source、25 root、805 nested`singleSourcePackages=[]`
`shallowSourcePackages=[]`、findings 为空;Local Admin 为 43 source、1 root/42 nested。Edge import、Cluster
dependency 与 Cluster deployment 全部 compatible。
- Adopted Edge/Standalone 为 4,265,052/4,265,112 bytes、394 files、50 loaded modulesApplication 为
4,762,901/4,763,021 bytes、453 files、116 modulesApplication AI 为 6,158,278/6,158,410 bytes、532 files、
115 modules。相对 ADR-0322 各增加 10,417 bytes/7 filesloaded module 数不变,六档均 compatible。
- 最终强制索引为 44,038 nodes/100,277 edges/1,729 clusters/274 flows。post-impact 中稳定错误保持 CRITICAL
40 direct/54 total/0 flows),`sha256Text` 与 inspection 保持 MEDIUM7/24、8/13),source fence 为 LOW
3/3),staging/review/activation 代表 coordinator 为 LOW0/0);高风险调用关系没有因 facade re-export 被隐藏。
- `detect_changes` all/compare `develop` 仍只映射已跟踪 Legacy baseline 的 12/31 与 14/34、low/0 process;当前
QL3 孵化树尚未完整进入 Git baseline,因此该结果只作补充,不能替代强制全索引、完整测试和六档制品门。
## 后续约束
Local SQLite Adoption 后续修改必须落入明确 owner,并继续保持 source fence 为共享安全 primitive、公共 facade identity
和现有 adoption contract tests。下一轮仍只处理确有多个变化原因的实现;纯 schema、normalizer 或单一 repository
authority 不因文件较大机械拆分,也不因包内文件较少机械合并 workspace package。