[M-AI-06-01] 审计并冻结 Feynman ReviewCard 子 Job 契约 #312

Closed
opened 2026-06-21 18:09:49 +08:00 by wangdl · 1 comment
Owner

类型 / 标签

  • audit
  • architecture
  • review-card
  • child-job

风险等级

P0 — 契约错误将导致全量返工

依赖

  • M-AI-05 PASS

目标

完整审计现有 ReviewCard EventBus 链路、二次 AI 调用、卡片写入和失败语义,冻结 Child Job 迁移契约。

必须审计

当前触发链路

追踪:FeynmanProjector / AiAnalysisWorker → EventBus.publish → ReviewCardSubscriber → ReviewService.generateCards → ReviewCardGenerationWorkflow → AiGateway → ReviewRepository.insertCard

所有结论附:文件路径、类名、方法名、行号。

EventBus 行为

确认:EventBus 是进程内还是持久化、publish 是否 await、Subscriber 是否同步执行、异常是否传播、异常是否被 catch 吞掉、进程崩溃时事件是否丢失、重复 publish 是否去重、Worker 重启后是否重放。

ReviewCard 输入

列出实际二次模型调用使用的字段,分类为:进入 Child Snapshot、执行时查询、禁止进入 Snapshot。

卡片数量与 ReviewCard 字段

确认真实规则和写入字段,确认 ID 是否允许调用方指定。

幂等能力

检查 ReviewCard 表是否存在 jobId/sourceId/externalId/dedupeKey,是否允许 deterministic ID,是否有可利用的唯一约束,重复 EventBus 当前是否生成重复卡片。

Parent/Child 数据模型

确认现有 AiJob 已支持 parentJobId、children relation、idempotencyKey、snapshotId。确认删除策略和查询方式。

事务创建能力

检查 AiJobCreationService、AiJobSnapshotRepository、OutboxRepository 是否支持外部 Prisma.TransactionClient。

失败语义

冻结:Parent Projector 失败 / Child 创建失败 / Child Executor 失败 / Child Projector 失败 / Child 重试成功 各场景下的 Parent 状态、Child 状态、ReviewCard。

输出

新增 docs/architecture/m-ai-06-review-card-child-job-contract.md,包含:当前时序图、目标时序图、Parent/Child 状态机、Child Snapshot Schema、Child Output Schema、幂等契约、Feature Flag、失败隔离、回滚流程、不确定项。

非目标

不修改代码、不修改 Prisma、不创建 Migration、不切换 EventBus、不修改 Prompt。

验收标准

  • 当前 EventBus 行为完整记录(文件路径+行号)
  • ReviewCard 输入字段分类完成
  • 卡片数量规则确认真实代码
  • 幂等能力审计完成
  • Parent/Child 数据模型确认
  • 事务创建能力检查完成
  • 失败语义表冻结
  • 契约文档写入 docs/architecture/m-ai-06-review-card-child-job-contract.md
  • 契约文档包含所有必需章节

建议执行顺序

第 1 个执行(与 M-AI-06-02 可部分并行:审计事务能力的同时可以设计接口)

## 类型 / 标签 - audit - architecture - review-card - child-job ## 风险等级 P0 — 契约错误将导致全量返工 ## 依赖 - M-AI-05 PASS ## 目标 完整审计现有 ReviewCard EventBus 链路、二次 AI 调用、卡片写入和失败语义,冻结 Child Job 迁移契约。 ## 必须审计 ### 当前触发链路 追踪:FeynmanProjector / AiAnalysisWorker → EventBus.publish → ReviewCardSubscriber → ReviewService.generateCards → ReviewCardGenerationWorkflow → AiGateway → ReviewRepository.insertCard 所有结论附:文件路径、类名、方法名、行号。 ### EventBus 行为 确认:EventBus 是进程内还是持久化、publish 是否 await、Subscriber 是否同步执行、异常是否传播、异常是否被 catch 吞掉、进程崩溃时事件是否丢失、重复 publish 是否去重、Worker 重启后是否重放。 ### ReviewCard 输入 列出实际二次模型调用使用的字段,分类为:进入 Child Snapshot、执行时查询、禁止进入 Snapshot。 ### 卡片数量与 ReviewCard 字段 确认真实规则和写入字段,确认 ID 是否允许调用方指定。 ### 幂等能力 检查 ReviewCard 表是否存在 jobId/sourceId/externalId/dedupeKey,是否允许 deterministic ID,是否有可利用的唯一约束,重复 EventBus 当前是否生成重复卡片。 ### Parent/Child 数据模型 确认现有 AiJob 已支持 parentJobId、children relation、idempotencyKey、snapshotId。确认删除策略和查询方式。 ### 事务创建能力 检查 AiJobCreationService、AiJobSnapshotRepository、OutboxRepository 是否支持外部 Prisma.TransactionClient。 ### 失败语义 冻结:Parent Projector 失败 / Child 创建失败 / Child Executor 失败 / Child Projector 失败 / Child 重试成功 各场景下的 Parent 状态、Child 状态、ReviewCard。 ## 输出 新增 docs/architecture/m-ai-06-review-card-child-job-contract.md,包含:当前时序图、目标时序图、Parent/Child 状态机、Child Snapshot Schema、Child Output Schema、幂等契约、Feature Flag、失败隔离、回滚流程、不确定项。 ## 非目标 不修改代码、不修改 Prisma、不创建 Migration、不切换 EventBus、不修改 Prompt。 ## 验收标准 - [ ] 当前 EventBus 行为完整记录(文件路径+行号) - [ ] ReviewCard 输入字段分类完成 - [ ] 卡片数量规则确认真实代码 - [ ] 幂等能力审计完成 - [ ] Parent/Child 数据模型确认 - [ ] 事务创建能力检查完成 - [ ] 失败语义表冻结 - [ ] 契约文档写入 docs/architecture/m-ai-06-review-card-child-job-contract.md - [ ] 契约文档包含所有必需章节 ## 建议执行顺序 第 1 个执行(与 M-AI-06-02 可部分并行:审计事务能力的同时可以设计接口)
wangdl added this to the M-AI-06 Feynman ReviewCard 子 Job 与可靠生成 milestone 2026-06-21 18:09:49 +08:00
Author
Owner

开发完成评论

完成内容

  • 审计 EventBus 链路:确认 EventBusService.publish() 为进程内 EventEmitter2.emit()(非持久化),位于 src/common/event-bus/event-bus.service.ts:19-23。Subscriber 异常被吞掉(review-card.subscriber.ts:48-49),Worker 崩溃后事件不可恢复。
  • 审计 ReviewCard 触发链路:完整追踪 AiAnalysisWorkerEventBus.publishReviewCardSubscriberReviewService.generateCardsReviewCardGenerationWorkflowAiGatewayReviewRepository.insertCard。附文件路径+行号。
  • 确认卡片数量规则Math.min(3, Math.max(1, (a.weaknesses?.length || 1)))review-card.subscriber.ts:42
  • 审计 ReviewCard 数据模型:不支持显式 ID 赋值(@default(cuid())),无 jobId/sourceId/dedupeKey 字段,无除 PK 外的唯一约束。
  • 确认 Parent/Child 数据模型:AiJob 已支持 parentJobIdschema.prisma:580)、idempotencyKey(:582)、children 自引用关系(:619)、@@unique([userId, jobType, idempotencyKey])(:636)。
  • 审计事务创建能力AiJobCreationService.createJob() 不支持外部 Prisma.TransactionClient(内部 $transaction — :158)。AiJobLifecycleRepository.createJob()OutboxRepository.createInTransaction() 已支持外部 tx。
  • 冻结失败语义表:定义了 Parent Projector 失败、Child 创建失败、Child Executor 失败、Child Projector 失败、Child 重试成功共 6 种场景的 Parent/Child/ReviewCard 状态。
  • 冻结 Prompt 兼容性promptKey='review-card-generation'promptVersion='1.0.0'tier='cheap'

产出文件

  • docs/architecture/m-ai-06-review-card-child-job-contract.md(676 行)
    • §1 当前链路审计(含时序图、EventBus 行为表、输入字段分类、幂等能力现状)
    • §2 目标链路(含时序图、差异对比表)
    • §3 Parent/Child 状态机(含 6 场景失败语义冻结表)
    • §4 Child Snapshot Schema(必须包含 / 禁止包含)
    • §5 Child Output Schema(验证规则表)
    • §6 幂等契约(Child Job 幂等 + ReviewCard 幂等方案 A/B 分析)
    • §7 Feature Flag(FEYNMAN_REVIEW_CARD_MODE: legacy_event | child_job
    • §8 失败隔离(隔离边界图 + 恢复操作表)
    • §9 回滚流程(child_job → legacy_event 步骤)
    • §10 实现约束与不确定项
    • 附录 A:关键文件索引(26 个文件路径+行号)
    • 附录 B:Prompt 兼容性确认

关键发现与风险提示

  1. ReviewCard 不支持显式 ID 赋值(CUID auto-generated)。确定性幂等需要方案 A(新增 @@unique([childJobId, ordinal]) Migration)或方案 B(通过 Artifact 间接保证)。需在 M-AI-06-05 前决定。
  2. AiJobCreationService 不支持外部事务。M-AI-06-02 需新增 createInTransaction(tx, input) 方法。
  3. Legacy 路径中 knowledgeItemId 从未写入 ReviewCardreview.service.ts:82-94)。Child Snapshot Builder 需从 Parent Snapshot 读取。
  4. ReviewCard 表当前无任何 jobId 关联。实现幂等需要最小 schema 变更。

测试情况

  • 本次审计为纯文档产出,无代码变更
  • 运行相关模块测试确认未影响已有代码:
    npx jest --testPathPatterns="review-card|feynman-projector|ai-job-creation|event-bus"
    
  • 结果:32 passed, 2 suites, 0 failed

是否建议进入 Review

  • — 契约已冻结,建议进入 M-AI-06-02
## 开发完成评论 ### 完成内容 - **审计 EventBus 链路**:确认 `EventBusService.publish()` 为进程内 `EventEmitter2.emit()`(非持久化),位于 `src/common/event-bus/event-bus.service.ts:19-23`。Subscriber 异常被吞掉(`review-card.subscriber.ts:48-49`),Worker 崩溃后事件不可恢复。 - **审计 ReviewCard 触发链路**:完整追踪 `AiAnalysisWorker` → `EventBus.publish` → `ReviewCardSubscriber` → `ReviewService.generateCards` → `ReviewCardGenerationWorkflow` → `AiGateway` → `ReviewRepository.insertCard`。附文件路径+行号。 - **确认卡片数量规则**:`Math.min(3, Math.max(1, (a.weaknesses?.length || 1)))` — `review-card.subscriber.ts:42`。 - **审计 ReviewCard 数据模型**:不支持显式 ID 赋值(`@default(cuid())`),无 `jobId`/`sourceId`/`dedupeKey` 字段,无除 PK 外的唯一约束。 - **确认 Parent/Child 数据模型**:AiJob 已支持 `parentJobId`(`schema.prisma:580`)、`idempotencyKey`(:582)、`children` 自引用关系(:619)、`@@unique([userId, jobType, idempotencyKey])`(:636)。 - **审计事务创建能力**:`AiJobCreationService.createJob()` 不支持外部 `Prisma.TransactionClient`(内部 `$transaction` — :158)。`AiJobLifecycleRepository.createJob()` 和 `OutboxRepository.createInTransaction()` 已支持外部 tx。 - **冻结失败语义表**:定义了 Parent Projector 失败、Child 创建失败、Child Executor 失败、Child Projector 失败、Child 重试成功共 6 种场景的 Parent/Child/ReviewCard 状态。 - **冻结 Prompt 兼容性**:`promptKey='review-card-generation'`,`promptVersion='1.0.0'`,`tier='cheap'`。 ### 产出文件 - `docs/architecture/m-ai-06-review-card-child-job-contract.md`(676 行) - §1 当前链路审计(含时序图、EventBus 行为表、输入字段分类、幂等能力现状) - §2 目标链路(含时序图、差异对比表) - §3 Parent/Child 状态机(含 6 场景失败语义冻结表) - §4 Child Snapshot Schema(必须包含 / 禁止包含) - §5 Child Output Schema(验证规则表) - §6 幂等契约(Child Job 幂等 + ReviewCard 幂等方案 A/B 分析) - §7 Feature Flag(`FEYNMAN_REVIEW_CARD_MODE: legacy_event | child_job`) - §8 失败隔离(隔离边界图 + 恢复操作表) - §9 回滚流程(child_job → legacy_event 步骤) - §10 实现约束与不确定项 - 附录 A:关键文件索引(26 个文件路径+行号) - 附录 B:Prompt 兼容性确认 ### 关键发现与风险提示 1. **ReviewCard 不支持显式 ID 赋值**(CUID auto-generated)。确定性幂等需要方案 A(新增 `@@unique([childJobId, ordinal])` Migration)或方案 B(通过 Artifact 间接保证)。需在 M-AI-06-05 前决定。 2. **`AiJobCreationService` 不支持外部事务**。M-AI-06-02 需新增 `createInTransaction(tx, input)` 方法。 3. **Legacy 路径中 `knowledgeItemId` 从未写入 ReviewCard**(`review.service.ts:82-94`)。Child Snapshot Builder 需从 Parent Snapshot 读取。 4. **ReviewCard 表当前无任何 jobId 关联**。实现幂等需要最小 schema 变更。 ### 测试情况 - 本次审计为纯文档产出,无代码变更 - 运行相关模块测试确认未影响已有代码: ``` npx jest --testPathPatterns="review-card|feynman-projector|ai-job-creation|event-bus" ``` - 结果:32 passed, 2 suites, 0 failed ### 是否建议进入 Review - **是** — 契约已冻结,建议进入 M-AI-06-02
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: wangdl/api-server#312
No description provided.