[M-AI-05-02] 注册 Feynman Job Definition 与输入 Snapshot #305

Closed
opened 2026-06-21 15:53:20 +08:00 by wangdl · 1 comment
Owner

类型 / 标签

  • backend
  • feynman
  • registry
  • snapshot

风险等级

P1(Definition 错误会导致 Job 无法执行;Snapshot 泄露敏感信息为 P0)

依赖

  • M-AI-05-01(契约冻结后开始)

目标

按照冻结契约注册 Feynman Definition,并实现输入验证和 Snapshot Builder,不修改生产入口。

Definition

最终值以 01 审计为准,至少包括:jobType、queueName、priority、attempts、timeoutMs、inputSchemaVersion、outputSchemaVersion、promptKey、promptVersion、modelTier、inputSchema、outputSchema、executor、businessValidator、referenceValidator、projector。

队列默认 ai-interactive,若改为 ai-background 必须有真实业务依据。

Snapshot Builder

新增 FeynmanSnapshotBuilder,职责:

  1. 校验用户权限
  2. 加载知识点
  3. 加载必要参考内容
  4. 接收用户解释
  5. 生成版本化 Snapshot
  6. 从 Definition 读取 Prompt/Model 元数据
  7. 脱敏
  8. 计算 contentHash

Snapshot 稳定性

相同业务输入必须产生相同规范化内容和 contentHash。规范化至少处理:字段顺序、null 与缺省值、不稳定时间字段、无关空格、数组顺序是否具有业务含义。不得把每次生成时间加入 hash 输入。

安全

必须扫描:token、apiKey、Authorization、cookie、password、DATABASE_URL、REDIS_URL、credential。

约束

  • 不修改原 Controller
  • 不修改原 Feynman Service
  • 不创建真实 Job
  • 不调用模型
  • 不写 FocusItem
  • 不写 ReviewCard
  • 不新增 Migration

影响范围

src/modules/ai-job/definitions/src/modules/ai-job/snapshot/src/modules/feynman/

验收标准

  • Registry 注册 feynman_evaluation 成功
  • 重复注册抛错
  • 非法输入拒绝(缺少必填字段、跨用户知识点)
  • Snapshot 包含完成 Feynman 评估所需的最小稳定输入
  • Snapshot 不含 JWT、Authorization Header、Cookie、明文 Key、数据库连接信息
  • contentHash 稳定(相同输入 → 相同 hash)
  • 字段规范化:字段顺序一致、null 与缺省值等价、时间字段归一化
  • Definition 元数据来自 Registry(不硬编码)
  • 生产环境可注册但默认不接流量
  • 单元测试通过

建议执行顺序

第 2 个执行(依赖 01 契约)

## 类型 / 标签 - backend - feynman - registry - snapshot ## 风险等级 P1(Definition 错误会导致 Job 无法执行;Snapshot 泄露敏感信息为 P0) ## 依赖 - M-AI-05-01(契约冻结后开始) ## 目标 按照冻结契约注册 Feynman Definition,并实现输入验证和 Snapshot Builder,不修改生产入口。 ## Definition 最终值以 01 审计为准,至少包括:jobType、queueName、priority、attempts、timeoutMs、inputSchemaVersion、outputSchemaVersion、promptKey、promptVersion、modelTier、inputSchema、outputSchema、executor、businessValidator、referenceValidator、projector。 队列默认 `ai-interactive`,若改为 `ai-background` 必须有真实业务依据。 ## Snapshot Builder 新增 `FeynmanSnapshotBuilder`,职责: 1. 校验用户权限 2. 加载知识点 3. 加载必要参考内容 4. 接收用户解释 5. 生成版本化 Snapshot 6. 从 Definition 读取 Prompt/Model 元数据 7. 脱敏 8. 计算 contentHash ## Snapshot 稳定性 相同业务输入必须产生相同规范化内容和 contentHash。规范化至少处理:字段顺序、null 与缺省值、不稳定时间字段、无关空格、数组顺序是否具有业务含义。不得把每次生成时间加入 hash 输入。 ## 安全 必须扫描:token、apiKey、Authorization、cookie、password、DATABASE_URL、REDIS_URL、credential。 ## 约束 - 不修改原 Controller - 不修改原 Feynman Service - 不创建真实 Job - 不调用模型 - 不写 FocusItem - 不写 ReviewCard - 不新增 Migration ## 影响范围 `src/modules/ai-job/definitions/`、`src/modules/ai-job/snapshot/`、`src/modules/feynman/` ## 验收标准 - [ ] Registry 注册 `feynman_evaluation` 成功 - [ ] 重复注册抛错 - [ ] 非法输入拒绝(缺少必填字段、跨用户知识点) - [ ] Snapshot 包含完成 Feynman 评估所需的最小稳定输入 - [ ] Snapshot 不含 JWT、Authorization Header、Cookie、明文 Key、数据库连接信息 - [ ] contentHash 稳定(相同输入 → 相同 hash) - [ ] 字段规范化:字段顺序一致、null 与缺省值等价、时间字段归一化 - [ ] Definition 元数据来自 Registry(不硬编码) - [ ] 生产环境可注册但默认不接流量 - [ ] 单元测试通过 ## 建议执行顺序 第 2 个执行(依赖 01 契约)
wangdl added this to the M-AI-05 Feynman 与 ReviewCard 可靠链路 milestone 2026-06-21 15:53:20 +08:00
wangdl added the
priority:p1
area:ai
backend
labels 2026-06-21 15:53:20 +08:00
Author
Owner

开发完成评论

完成内容

  • 创建 FEYNMAN_JOB_DEFINITION 常量(jobType=feynman_evaluation,queue=ai-interactive,timeout=180s,retries=3)
  • 实现 FeynmanRegistrationService(onModuleInit 注册 Definition,容忍重复注册)
  • 实现 FeynmanSnapshotBuilder
    • 加载 KnowledgeItem 并验证所有权(ForbiddenException 跨用户拒绝)
    • 加载关联知识库参考材料摘要(最多 5 条,仅 id/title/summary)
    • 从 JobDefinitionRegistry 读取 prompt/model 配置(单一事实来源)
    • 构建版本化、最小化、脱敏的快照
    • computeHash() — SHA256 前 16 字符,字段顺序无关(稳定序列化)
    • 扫描禁止敏感字段(JWT/apiKey/password/DATABASE_URL 等)
  • 更新 AiJobModule:注册 FeynmanRegistrationService + FeynmanSnapshotBuilder

Snapshot Schema(feynman-evaluation-v1)

{
  userId, knowledgeItemId, knowledgeItemTitle, knowledgeItemContent,
  userExplanation, submissionId, knowledgeBaseId,
  referenceMaterials: [{id, title, summary}],
  promptKey, promptVersion, modelTier,
  inputSchemaVersion, outputSchemaVersion, createdAt (normalized to second)
}

修改文件

  • src/modules/ai-job/feynman-job-definition.ts(新增,75 行)
  • src/modules/ai-job/feynman-snapshot-builder.ts(新增,153 行)
  • src/modules/ai-job/feynman-registration.service.ts(新增,44 行)
  • src/modules/ai-job/feynman-job-definition.spec.ts(新增,299 行)
  • src/modules/ai-job/ai-job.module.ts(修改,+5 行:3 imports + 2 providers)

代码证据

  • feynman-job-definition.ts:18-75 — Definition 冻结(jobType/prompt/model/execution/credential/projectorKey)
  • feynman-snapshot-builder.ts:92-130 — build() 核心逻辑(KnowledgeItem 加载 + 所有权验证 + 参考材料 + 快照构建)
  • feynman-snapshot-builder.ts:138-146 — computeHash()(SHA256 + JSON 稳定序列化)
  • feynman-snapshot-builder.ts:155-178 — loadReferenceMaterials()(最多 5 条,仅摘要)
  • feynman-registration.service.ts:21-40 — onModuleInit 注册 + DuplicateJobTypeError 容忍

测试情况

  • 已运行命令:
    • npx jest --testPathPatterns="feynman-job-definition"
    • npx jest --testPathPatterns="ai-job"
  • 结果:
    • 新增 26 tests,全部通过
    • 全 ai-job 套件:14 suites passed, 281 passed, 18 skipped, 0 failed
    • TypeScript 编译:新文件零错误

与 Legacy 的差异说明

  • SnapshotBuilder 需要 knowledgeItemId(当前 Feynman HTTP 请求体不含此字段)
  • 该字段的获取方式留待 M-AI-05-05(入口路由)解决:客户端传入 或 服务端通过标题+内容匹配
  • submissionId 由调用方(M-AI-05-05)传入,用于幂等键构建

未完成 / 风险

  • knowledgeItemId 来源待 M-AI-05-05 解决(契约 U-2)
  • ReferenceValidator 和 BusinessValidator 留待 M-AI-05-03 实现
  • Projector 留待 M-AI-05-04 实现

是否建议进入 Review

  • 是 — Definition 注册 + Snapshot Builder 已完成,建议审核后启动 M-AI-05-03
## 开发完成评论 ### 完成内容 - 创建 `FEYNMAN_JOB_DEFINITION` 常量(jobType=`feynman_evaluation`,queue=`ai-interactive`,timeout=180s,retries=3) - 实现 `FeynmanRegistrationService`(onModuleInit 注册 Definition,容忍重复注册) - 实现 `FeynmanSnapshotBuilder`: - 加载 KnowledgeItem 并验证所有权(ForbiddenException 跨用户拒绝) - 加载关联知识库参考材料摘要(最多 5 条,仅 id/title/summary) - 从 JobDefinitionRegistry 读取 prompt/model 配置(单一事实来源) - 构建版本化、最小化、脱敏的快照 - `computeHash()` — SHA256 前 16 字符,字段顺序无关(稳定序列化) - 扫描禁止敏感字段(JWT/apiKey/password/DATABASE_URL 等) - 更新 `AiJobModule`:注册 FeynmanRegistrationService + FeynmanSnapshotBuilder ### Snapshot Schema(feynman-evaluation-v1) ```typescript { userId, knowledgeItemId, knowledgeItemTitle, knowledgeItemContent, userExplanation, submissionId, knowledgeBaseId, referenceMaterials: [{id, title, summary}], promptKey, promptVersion, modelTier, inputSchemaVersion, outputSchemaVersion, createdAt (normalized to second) } ``` ### 修改文件 - `src/modules/ai-job/feynman-job-definition.ts`(新增,75 行) - `src/modules/ai-job/feynman-snapshot-builder.ts`(新增,153 行) - `src/modules/ai-job/feynman-registration.service.ts`(新增,44 行) - `src/modules/ai-job/feynman-job-definition.spec.ts`(新增,299 行) - `src/modules/ai-job/ai-job.module.ts`(修改,+5 行:3 imports + 2 providers) ### 代码证据 - `feynman-job-definition.ts:18-75` — Definition 冻结(jobType/prompt/model/execution/credential/projectorKey) - `feynman-snapshot-builder.ts:92-130` — build() 核心逻辑(KnowledgeItem 加载 + 所有权验证 + 参考材料 + 快照构建) - `feynman-snapshot-builder.ts:138-146` — computeHash()(SHA256 + JSON 稳定序列化) - `feynman-snapshot-builder.ts:155-178` — loadReferenceMaterials()(最多 5 条,仅摘要) - `feynman-registration.service.ts:21-40` — onModuleInit 注册 + DuplicateJobTypeError 容忍 ### 测试情况 - 已运行命令: - `npx jest --testPathPatterns="feynman-job-definition"` - `npx jest --testPathPatterns="ai-job"` - 结果: - 新增 26 tests,全部通过 - 全 ai-job 套件:14 suites passed, 281 passed, 18 skipped, 0 failed - TypeScript 编译:新文件零错误 ### 与 Legacy 的差异说明 - SnapshotBuilder 需要 `knowledgeItemId`(当前 Feynman HTTP 请求体不含此字段) - 该字段的获取方式留待 M-AI-05-05(入口路由)解决:客户端传入 或 服务端通过标题+内容匹配 - `submissionId` 由调用方(M-AI-05-05)传入,用于幂等键构建 ### 未完成 / 风险 - `knowledgeItemId` 来源待 M-AI-05-05 解决(契约 U-2) - ReferenceValidator 和 BusinessValidator 留待 M-AI-05-03 实现 - Projector 留待 M-AI-05-04 实现 ### 是否建议进入 Review - 是 — Definition 注册 + Snapshot Builder 已完成,建议审核后启动 M-AI-05-03
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

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