oh-my-muse/docs/agent-specs/2026-06-17-meta-schema用量投影-review.md
lili 329db944ff docs: 进度口径收敛到机械唯一源——修正三套矛盾数字(147/100→233/233) + 现状基线降级
排查发现进度数字三套互相矛盾:总览/现状基线/主台账历史段=147/86、agent-specs=100/127、module-reality=233/0。核机械真值:覆盖 JSON summary=233/233 completed/0 needs(每 op 带 testFiles 证据 + P1rApiCoverageReportTest 校验 summary 自算防手工拨)。⚠️ JSON generatedAt=2026-05-25 未随内容刷新(手工维护痕迹),已在文档标注以 summary+testFiles 为准。

修正:① 总览(我上轮新建,误抄过时台账)147/233→233/233、各域 full、接口门≠端到端两口径分清、定位为人读封面(权威以台账/JSON为准);② 主台账 头部加机械源口径声明(233/0)+门禁中→满+验收债标已清零;③ 现状基线降级为 2026-06-13 历史快照(顶部时效横幅+性质去SSOT);④ AGENTS序2/module-reality 改引用;⑤ agent-specs/.agent 注记历史数字;⑥ meta-schema review 回指 execution v0.2 已证伪地基(待决策提案);⑦ design-docs/00 加'设计≠进度';⑧ dev-baseline 申明旧 SSOT 自称失效。

确立单一真实源:设计=design-docs;进度=进度总账(叙述)+覆盖JSON(机械);人读=项目功能与进度总览(封面)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 05:32:32 -07:00

163 lines
14 KiB
Markdown

# Meta Schema 用量投影建模 —— 评审版设计
> 版本:v0.2(评审版) · 日期:2026-06-17(决策确认 2026-06-20) · 目标读者:架构决策者(人类) · 类型:评审版(结论先行,无代码细节)
> 状态:**待决策提案、非现行设计**。方向已确认(2026-06-20,见 §十),但 ⚠️ **本评审版的方案前提已被执行版证伪**——见 [执行版 v0.2](2026-06-20-meta-schema用量投影-execution.md) 顶部「评审修订摘要」(破坏字段集生产者 + schema_key 来源在代码中**不存在、须从零新建**)。落地细节与修正以执行版为准;本文件不实现任何代码。
> 关联:[进度总账 §五A](../mvp/进度总账.md)(MetaImpactFacade 置后判定)、[bc-boundaries](../../.agents/rules/bc-boundaries.md)(本设计须遵守的边界门)。
---
## 一、结论先行
1. **问题本质**:Meta 治理写链路(publish/activate/rollback/deprecate 4 端点)在 service 层**硬性前置**一条 `status=succeeded` 的 impact preview;而唯一实现 `UnavailableMetaImpactFacade` 恒抛 `META_EXTERNAL_OWNER_UNAVAILABLE`,故这 4 端点**运行期 100% 阻断**。这是**诚实 fail-closed**(拒绝伪造 impact 数量),非缺陷。
2. **根因**:impact preview 要回答"改这个 schema 版本影响哪些消费方实例、几个命中破坏性改动";但消费方**没持久化"谁在用哪个 schema"**——Content 的 `muse_content_planning_section` 仅存 `schema_version`(整数版本号、**无 `schema_key`**),Knowledge/AI **完全不存** schema 引用。**无数据可计数 → facade 只能 fail-closed**。
3. **推荐方向(待确认)**:**Pull(按需查询)+ 按 BC 拆分贡献者端口**,分阶段按消费 BC 落地。即:
- 消费方在写入实例时持久化其 schema 用量(至少 `schema_key + version`,Content 已有 version、补 key);
- Meta 定义 `MetaSchemaUsageContributorApi`(meta-api),**各消费 BC 实现自己维度的查询**(本域查本域 DAL),Meta 侧聚合器实现 `MetaImpactFacade` 扇出汇总;
- 现有 `MetaSchemaImpactPreviewServiceImpl` 调用方**不变**。
4. **关键架构订正**:现有 `MetaImpactFacade` 单接口返回全部 5 维度(Work/Planning/Knowledge/AI/Export),**隐含单一实现者要懂 5 个 BC 的数据 → 违反 BC 边界门**(`no_business_bc_may_depend_on_another_bc_*`)。本设计**必须**把它拆为"Meta 定义端口、各 owner BC 提供适配器"(与刚落地的 `MarketAccountProjectionFacade`/`MuseAccountRecordProjectionApi` 同范式)。
5. **为何不选 Push(事件投影)**:见 §五权衡。一句话:impact preview 是**低频 admin 操作 + 闸destructive 治理动作**,要求**准确**(不能用滞后的投影门destructive 操作),Pull 无投影漂移/无回填/无最终一致性窗口,且匹配现有同步 facade 契约;Push 的投影表+消费 worker+回填+一致性窗口在此场景是净负担。
---
## 二、背景(事实基线,均有代码出处)
> 详细出处见 grounding 调查(本次会话,只读)。下列为硬事实。
- **端口**:`MetaImpactFacade.previewMetaSchemaDraftImpact(schemaKey, draftVersion, draftHash)``MetaSchemaImpactSummary{workImpact, planningImpact, knowledgeProjectionImpact, aiContextImpact, exportImpact, totalAffectedProjectionCount}`,位于 `meta.application.facade`。唯一实现 `UnavailableMetaImpactFacade``META_EXTERNAL_OWNER_UNAVAILABLE(1_042_001_004)`
- **硬门禁**:`MetaSchemaServiceImpl` 的 publish/activate/rollback/deprecate 均前置 `requireImpactPreview`(需 `status=succeeded``muse_meta_impact_preview` 记录,否则 `META_IMPACT_PREVIEW_REQUIRED 1_042_001_002`)。
- **impact 语义**:每个消费维度的**定量快照**——受影响实例数 + 命中破坏性改动(字段移除/可见性改变/投影需重建)的实例数。
- **消费方持久化现状(根因)**:Content `muse_content_planning_section.schema_version`(INT,无 `schema_key` 列、无用量表);Knowledge/AI **无任何** schema 引用持久化。
- **已有数据模型**:`muse_meta_impact_preview`(JSONB 存 impact_summary/error/source_snapshot + status,**一次性预览快照、非累计用量**);无任何 usage/projection 累计表;无独立 usage/export 模块。
- **可复用事件基建**:Content 有成熟幂等 outbox(`ContentEventPublishOutboxServiceImpl`:insertIgnore + worker claim + 重试);AI/Knowledge 有 outbox 接口;`EventsPublishApi` 跨 BC 事件。
---
## 三、目标 / 非目标
**目标**
- 让 4 个 Meta 治理端点从"恒 fail-closed"变为"基于**真实**消费用量给出 impact preview 后可放行",且**绝不伪造** impact 数量。
- 真实化路径**遵守 BC 边界门**(Meta 不直连他域 DAL / application)。
- 可分阶段交付:每阶段一个消费维度真实化,未真实化维度保持**诚实 fail-closed 或显式 0/unknown**(不伪造)。
**非目标(本轮)**
- 不做实时/全量用量大盘或运营报表。
- 不引入独立 `muse-module-usage`/`export` 模块(除非评审认定必要)。
- 不改 `MetaSchemaImpactPreviewServiceImpl` 的对外语义与现有 4 端点的 API 契约。
- 不在前端做 admin 可视化(meta 治理属 admin 侧、用户价值低,排后)。
---
## 四、推荐方案(Pull + 按 BC 拆分贡献者端口)
### 4.1 架构总览
```mermaid
flowchart TD
A[AdminMetaSchemaController\npublish/activate/rollback/deprecate] --> B[MetaSchemaServiceImpl.requireImpactPreview]
B --> C[MetaSchemaImpactPreviewServiceImpl]
C --> D[MetaImpactFacade 聚合器实现\nmeta-server]
D -->|fan-out 查询| E1[Content 贡献者适配器\ncontent-server 查本域 DAL]
D -->|fan-out 查询| E2[Knowledge 贡献者适配器\nknowledge-server]
D -->|fan-out 查询| E3[AI 贡献者适配器\nai-server]
D -->|聚合| F[MetaSchemaImpactSummary]
F --> G[(muse_meta_impact_preview\n仍存快照)]
subgraph 端口契约 meta-api
P[MetaSchemaUsageContributorApi\nMeta 定义、各 owner BC 实现]
end
E1 -. implements .-> P
E2 -. implements .-> P
E3 -. implements .-> P
D -. 依赖 .-> P
```
### 4.2 两层改造
- **基础层(各消费 BC,特征工程)**:在实例写入时持久化其 schema 用量,使"哪些实例用了 schemaKey X 的哪些字段"可被**本域查询**。Content 已有 `schema_version`,补 `schema_key`(+必要时字段使用快照);Knowledge/AI 视其是否真消费 schema 决定是否纳入(见 open item 1)。
- **端口层(契约)**:meta-api 定义 `MetaSchemaUsageContributorApi`(本进程内 Bean 端口,参照 `MuseContentWorkOwnerApi` 先例,非 @FeignClient);各 owner BC 在 `*-server` 实现自己维度的计数/破坏性分析(只读本域 DAL);meta-server 的 `MetaImpactFacade` 真实聚合器扇出各贡献者、组装 `MetaSchemaImpactSummary`
### 4.3 分阶段(价值/可验证性优先)
| 阶段 | 内容 | 完成后效果 |
|---|---|---|
| P0 | meta-api 定义贡献者端口 + meta-server 聚合器(未接消费方时对各维度**显式 unknown/fail-closed**,绝不 0 伪装) | 端口就位,行为等价现状但架构可扩展 |
| P1 | Content(work + planning)真实化:补 `schema_key` 持久化 + Content 实现贡献者适配器 | Content 维度真实计数,治理端点对"仅 Content 受影响"可放行 |
| P2+ | Knowledge / AI / Export 逐维度真实化(各自 owner 出适配器) | 其余维度逐步真实 |
> 每阶段验收=该维度真实 PG IT(种真实消费实例→preview 返回真实计数;负路径未接入维度 fail-closed 不伪造)。
---
## 五、关键权衡:Pull vs Push
| 维度 | Pull(推荐:按需查询贡献者) | Push(事件投影:消费方发用量事件→Meta 投影表) |
|---|---|---|
| 准确性 | **实时准确**,直接查源 | 最终一致,有滞后窗口——**用滞后投影 gate destructive 治理动作有风险** |
| 新增数据模型 | 无新累计表(复用 impact_preview 快照) | 需 `muse_meta_schema_usage_projection` + 消费 worker |
| 历史数据 | 无需回填(直接扫源) | **需回填**既有实例,否则投影不全 |
| BC 边界 | 各 BC 查本域(合规) | 各 BC 发事件 + Meta 消费(合规),但组件更多 |
| 成本/复杂度 | 低(匹配现有同步 facade 契约) | 高(发布点+outbox+worker+回填+一致性) |
| 频率匹配 | impact preview 低频 admin,扫描成本可接受 | 投影适合高频读;此场景高频读不存在 |
| 共同前提 | **两者都需消费方持久化 schema 用量**(根因不可绕过) | 同 |
**结论**:在"低频、要准确、gate destructive 操作"的 impact preview 场景,Pull 显著优。Push 的优势(高频读、解耦)在此不构成价值,反引入投影漂移与回填负担。**故推荐 Pull**。(若未来出现"运营用量大盘"等高频读需求,可在 Pull 之上**另建**投影,不与本设计冲突。)
---
## 六、Blast Radius / 兼容性
- **meta**:新增 meta-api 端口 + meta-server 聚合器实现替换 `UnavailableMetaImpactFacade`(经 `@ConditionalOnMissingBean`/`@Primary` 平滑替换,参照 facade 替换先例)。`MetaSchemaImpactPreviewServiceImpl` 与 4 端点 API 契约**不变**。
- **content(P1)**:新增 `schema_key` 持久化=**Flyway 新增迁移(只增不改)** + 写入点补字段 + 贡献者适配器(只读本域)。对既有 planning 写链路低侵入。
- **knowledge/ai(P2+)**:仅在确属 schema 消费方时改;否则该维度贡献者返回 unknown(诚实)。
- **DB 迁移**:每阶段独立 `V<n>__*.sql`(只增列/表,不改历史);Content 既有行 `schema_key` 为空→该维度对"历史无 key 行"按 unknown 计(不伪造),随写入逐步补全。
- **回滚**:端口未接消费方时聚合器 fail-closed=回到现状(治理端点阻断),无数据损坏面。
---
## 七、风险
| 风险 | 说明 | 缓解 |
|---|---|---|
| 破坏性分析需字段级用量 | 仅计数不够,要判"字段被移除影响几个"需消费方记录用到哪些字段 | P1 评估 Content planning 的 content JSON 是否足以反推字段用量;不足则补字段使用快照 |
| 版本快照一致性 | 消费方仅记 version、不记 key/hash,Meta 版本变更后难追溯旧版影响 | 基础层补 `schema_key`(+可选 draft_hash 快照),使消费实例自证用的哪个 schema |
| 跨 BC 扇出延迟 | preview 同步扇出多 BC | 低频 admin 可接受;贡献者查询走本域索引;超时则该维度 unknown(不阻塞他维度、不伪造) |
| 维度归属不清 | Knowledge/AI 是否真消费 schema 未证实(grounding 显示其不持久化) | open item 1:先证实再决定是否纳入,避免给不消费 schema 的 BC 强加端口 |
| 特征工程蔓延 | 多 BC 改写入链路 | 严格分阶段、每阶段独立可验收;未做维度诚实 fail-closed |
---
## 八、验收标准(达成定义)
- 端口层:`MetaSchemaUsageContributorApi` 在 meta-api;聚合器替换 Unavailable 后 **BcBoundaryArchTest 仍 0 违例**(Meta 不直连他域 DAL/application)。
- P1(Content):真实 PG IT——种真实 planning/work 实例(带 schema_key)→ `previewMetaSchemaDraftImpact` 返回**真实 Content 计数**;无消费实例→0(真实 0,非伪造);未接入维度→unknown/fail-closed;治理端点在"仅 Content 受影响"下可走通 preview→publish。
- 反假绿:未持久化 schema_key 的历史行不被计入"已知用量"(按 unknown),杜绝把"没数据"伪装成"0 影响"。
---
## 九、Open Items(需人类/后续确认)
1. **Knowledge/AI/Export 是否真消费 MetaSchema?** grounding 显示三者均不持久化 schema 引用。需确认:impact summary 的这 3 维度是真实业务需求,还是 over-modeled 的 VO?若不消费,贡献者端口只需 Content(+视情况 Export),大幅缩小范围。
2. **破坏性分析的精度要求**:impact 只需"受影响实例数",还是必须"字段级破坏(移除/可见性)"?后者决定基础层是否要存字段使用快照(成本差异大)。
3. **是否接受分阶段期间"部分维度 unknown"的 preview 放行治理动作?** 即:只要已接入维度真实、未接入维度诚实 unknown,是否允许 admin 据此 publish?(关乎 fail-closed 的粒度策略。)
4. **`schema_key` 回填策略**:历史 planning 行无 key,是否需要一次性回填脚本(若 version→key 可推断),还是只对新写入生效、历史按 unknown。
5. 端口命名/归属与现有 `MetaImpactFacade` 的关系(保留 facade 作聚合门面 vs 直接重构)。
---
## 十、决策确认(2026-06-20,人类拍板)
| 议题 | 决策 | 影响 |
|---|---|---|
| 方向(§一.3 / §五) | **Pull 按需查询** | 各 BC 查本域、Meta 聚合;无投影表/回填/一致性窗口 |
| 维度范围(open #1) | **保留全 5 维度**(Work/Planning/KnowledgeProjection/AIContext/Export) | 5 维度均须出**真实**贡献者;非 Content-only |
| 破坏分析精度(open #2) | **字段级破坏分析** | 基础层须持久化**每实例的字段使用快照**,能算"移除某字段影响 N 实例"——成本高 |
| fail-closed 粒度(open #3) | **要求全维度真实才放行** | 治理 4 端点须等**全 5 维度真实**(含非消费维度的"已验证真实 0")才解阻;不接受"部分 unknown 放行" |
**诚实张力(须在执行版厘清,不回避)**:本组合=**最大范围 + 最高成本 + 价值最晚兑现**。
- 实证(2026-06-19/20 复核):Content 仅存 `schemaVersion`(无 `schema_key`);Knowledge/AI/Export 的 DAL **零 schema 引用**。在"全 5 维度 + 字段级 + 全真实才放行"下,这意味着对每个维度必须二选一并给出**实证**:
- **真实消费建模**:该维度确消费 MetaSchema → 基础层补 `schema_key` + 字段使用快照,贡献者出真实计数;或
- **已验证 0 贡献者**:实证该维度确**不消费** MetaSchema → 贡献者返回**已验证真实 0**(非 unknown),并留实证注释。
- "全维度真实才放行"=治理端点在最后一个维度落地前**持续阻断**(分阶段建设、价值末期兑现);执行版须明确各维度归类(消费建模 vs 已验证 0)与落地顺序。
- 维度真实消费厘清正由 grounding(2026-06-20)调查中;执行版据其结论对 5 维度逐一定性。
> 下一步:据 grounding 结论写**执行版** `docs/agent-specs/2026-06-20-meta-schema用量投影-execution.md`(含各维度定性、数据契约=贡献者端口 API + 各 BC 用量/字段快照表、Flyway 迁移、分阶段步骤、每维度真实 PG IT 验收、回滚)。