test(architecture): govern complete host cycles

This commit is contained in:
jxxghp
2026-08-27 05:50:39 +08:00
parent 3bf94ffeda
commit a884ab5c2b
6 changed files with 244 additions and 126 deletions
+2 -2
View File
@@ -156,7 +156,7 @@ MoviePilot V3 已经形成较清晰的模块化单体:`foundation`、`domain`
与生产路径显式 UoW 规则冲突;该项已由 S0-L2.1 修复并增加文档门禁。
- `docs/rules/05-architecture.md:507` 禁止 `application -> concrete adapter`,但同一文档
`177-183` 又要求 RSS 消费 network adapter;当前测试没有形式化这类例外。
- 规则 `docs/rules/05-architecture.md:516` 禁止任意模块级环,实际 SCC 测试只覆盖特定根
- 审计时完整 SCC 只进入生成快照,语义测试只覆盖特定根;S0-L2.2 已增加完整宿主 SCC policy 门禁
- 架构总览此前仍记录 811 模块、6,572 条边和 1 个 SCC,已经落后于当前基线。
- Event consumer 扫描把任意名为 `.register()` 的调用都当成事件注册,存在明确误报。
@@ -165,7 +165,7 @@ MoviePilot V3 已经形成较清晰的模块化单体:`foundation`、`domain`
- [ ] 指定一个机器可读事实源,文档指标由 fixture 生成或只保留不易漂移的语义描述。
- [x] 修正 Oper 示例,分别展示宿主显式 UoW 与插件兼容 Facade,并以文档测试禁止回退。
- [ ] 对 Adapter 规则作出明确决策:允许哪些通用技术机制,哪些命名外部/持久化能力必须注入。
- [ ] 让 SCC 规则、精确 allowlist 和文档声明一致
- [x] 让 SCC 规则、精确 policy 和文档声明一致;Chain 临时债务与 TMDB vendor containment 分开治理
- [ ] Event 扫描只识别 EventManager 实例/别名和事件装饰器。
- [ ] CI 分开报告“快照一致”与“语义规则通过”,禁止把前者表述为架构完全正确。
+4 -1
View File
@@ -668,6 +668,9 @@ flowchart LR
物理遗留源码、禁止的上向依赖、SDK/compat 反向引用、包含迁移模块的强连通分量、
模块间/模块到 Chain 的 import、入口层对 `app.modules` 内部的 import、
Chain 直接 import 模块内部(必须走 `run_module` 分发)、`app/chain` 内的下载器 SDK 依赖。
- `tests/fixtures/architecture/dependency-baseline.json` 记录生成事实;人工审查的 SCC 分类单独存入
`dependency-policy.json`。完整宿主 SCC 必须精确匹配 policy,新增、扩大、变形和陈旧 policy 都失败;
`--write-host` 不会替代人工决策。
- 任何所有权迁移必须同步更新:canonical 导入、`app/runtime/compat/manifest.py`
SDK 导出(若公开)、`docs/rules/05-architecture.md` 与上述架构测试。
- 延迟导入不被接受为隐藏循环依赖的手段。
@@ -681,7 +684,7 @@ flowchart LR
|---|---:|
| Python 模块 | 835 |
| 内部导入边 | 6,810 |
| 非平凡 SCC | 2Chain 包根环与隔离的 TMDB 移植包环) |
| 非平凡 SCC | 2`ARCH-107` 临时 Chain 包根环;精确 containment 的 TMDB 移植包环) |
| Module Contract V2 spec | 215(其中 214 个进入 `run_module` 观察面) |
| Event Contract | 53 |
| Model/Oper 自动事务与自建 Session | 0 |
+19 -15
View File
@@ -73,8 +73,8 @@ G-ARCH 只有在以下条件全部满足后才可完成:
| Leaf | 状态 | 依赖 | 完成定义 |
|---|---|---|---|
| S0-L1 可信基线恢复 | `DELIVERED` | 无 | `5df388719`:交付架构审计/路线图,修复 `ARCH-001` 两个 mypy 增量错误;远端 `0/0` |
| S0-L2.1 Host Oper/UoW 规范 | `VERIFIED` | S0-L1 | 宿主规则中未标注兼容范围的无 Session Oper 示例归零,并由文档测试锁定 |
| S0-L2.2 完整宿主 SCC policy | `PLANNED` | S0-L2.1 | 完整宿主 SCC 全部精确分类;Chain 临时债务和 TMDB containment 分离 |
| S0-L2.1 Host Oper/UoW 规范 | `DELIVERED` | S0-L1 | `3bf94ffed`:宿主无 Session Oper 规范债务归零,远端 `0/0` |
| S0-L2.2 完整宿主 SCC policy | `VERIFIED` | S0-L2.1 | 完整宿主 SCC 全部精确分类;Chain 临时债务和 TMDB containment 分离 |
| S0-L2.3 Adapter 直连事实 | `PLANNED` | S0-L2.1 | 收集 Application/Chain 的原始 Adapter import,不因父包展开重复计数 |
| S0-L2.4 Adapter zero-growth | `PLANNED` | S0-L2.3 | 当前直连均登记迁移 owner,新增/替换失败,删除后要求清理陈旧 policy |
| S0-L2.5 Event consumer 识别 | `PLANNED` | S0-L2.1 | consumer 只识别可静态证明的 EventManager 注册,动态误报归零 |
@@ -153,38 +153,42 @@ G-ARCH 只有在以下条件全部满足后才可完成:
## 4. 当前活动叶子
### S0-L2.1 Host Oper/UoW 规范
### S0-L2.2 完整宿主 SCC policy
**Status:** `VERIFIED`(本地验收完成,等待提交、推送和远端一致性确认)
**Outcome**
宿主数据访问规范与已经建立的 Application Port、DB Adapter、显式 Session/UoW
边界一致;无 Session Oper 只作为明确标注的插件 Legacy/Compat ABI 出现
完整宿主静态依赖图中的每个 SCC 都有精确、人工审查的分类;生成快照只记录事实,
不能通过刷新 baseline 自动批准新环
**Ownership**
- `docs/rules/04-design-patterns.md` 的 Oper、SystemConfig、UserConfig 示例
- `docs/rules/10-data-and-persistent.md` 的对应交叉规则
- `tests/test_architecture_documentation.py` 的无 Session Oper 文档门禁
- `tests/test_architecture_dependencies.py` 的统一图算法和完整 SCC 语义门禁
- `tests/fixtures/architecture/dependency-policy.json` 的精确人工 policy
- `docs/rules/05-architecture.md``docs/architecture-overview.md` 的事实/policy 边界
- 本路线图的叶子状态和交付记录。
**Excluded**
-迁移当前 startup 注入的无 Session Oper;该债务由 ARCH-103 逐领域切换
-修改运行时代码、fixture、`app/plugins/**` 或独立插件仓
-以删除 Legacy/Compat ABI 伪装宿主规范收口
-在本叶消除 Chain SCC;由 `ARCH-107`/S2-L2 删除包根环和临时 policy
-拆分 TMDB 移植包,不把普通单向包外依赖误判为 SCC 成员扩张
-修改 `app/plugins/**`、运行时代码或独立插件仓
**Acceptance**
```bash
.venv/bin/python -m pytest tests/test_architecture_documentation.py -q
.venv/bin/python scripts/architecture/baseline.py --check-host
rg -n 'SubscribeOper\(\)|SystemConfigOper\(\)|UserConfigOper\(\)' docs/rules
.venv/bin/python -m pytest \
tests/test_architecture_dependencies.py \
tests/test_architecture_baseline_cli.py -q
.venv/bin/python scripts/architecture/baseline.py --check-host --diagnostics
.venv/bin/python scripts/architecture/ruff_ratchet.py
.venv/bin/python scripts/architecture/mypy_ratchet.py
.venv/bin/pylint tests/test_architecture_dependencies.py
git diff --check
```
**Delivery**
- 单一提交主题:统一宿主持久化规范并建立文档门禁。
- 单一提交主题:建立完整宿主 SCC policy 与 zero-growth 语义门禁。
- 推送 `origin/v3` 后确认提交祖先关系、远端 SHA 和 ahead/behind `0/0`
+25 -2
View File
@@ -493,6 +493,29 @@ Durable post-commit side effects have a separate boundary:
functional and emits one actionable warning per plugin and legacy module.
- Delayed imports are not accepted as a way to hide dependency cycles.
### Dependency facts and semantic policy
`tests/fixtures/architecture/dependency-baseline.json` is generated evidence: it
records the complete host module graph, edges and SCCs while excluding
`app/plugins/**`. It does not approve those facts. Human-reviewed classifications
live separately in `tests/fixtures/architecture/dependency-policy.json`, and
`scripts/architecture/baseline.py --write-host` must never create or update that
policy.
The semantic architecture test compares every SCC in the complete host graph with
the exact member sets in policy. A new SCC, member expansion, changed member set,
or stale policy entry fails. The current policy has only two classifications:
- `temporary_debt`: the three-module `app.chain` package-root cycle, owned by
`ARCH-107` and removed when `ChainBase` moves to `app.chain.base`.
- `contained_vendor`: the exact 29-module TMDB vendored SCC. It may have ordinary
one-way dependencies outside the package, but no outside module may join the SCC
and its member set may not grow.
The target remains zero canonical host cycles except the precisely contained
vendor component. A temporary policy entry is an executable migration obligation,
not precedent for approving another cycle.
## Permitted Call Directions
| Direction | Status |
@@ -513,7 +536,7 @@ Durable post-commit side effects have a separate boundary:
| `foundation -> other app packages` | Forbidden |
| `canonical implementation -> sdk / compat` | Forbidden |
| `compat -> canonical implementation at module import time` | Forbidden |
| Any import that creates a module-level cycle | Forbidden |
| Any import that creates a module-level cycle | Forbidden; the complete host graph must match the exact reviewed SCC policy, and temporary debt must have a removal owner |
## Key File Locations
@@ -592,4 +615,4 @@ imports, entrypoint (`api`/`agent`/`monitor`/`workflow`/`doctor`) imports of
modules only through `run_module` dispatch), and downloader SDK
(`qbittorrentapi`, `transmission_rpc`) imports inside `app/chain`.
*Last Updated: 2026-08-24*
*Last Updated: 2026-08-27*