feat(v2): 纠偏第二批——接通历史经验加工闭环
覆盖 AC-50/51/52(BR-48/49、E-28)。审计确认的 P1-3 缺口"历史提炼与卡片 不在实时 API 调用图上"由此关闭:提炼、候选治理、卡片进方案全部有真实调用方。 后端: - contracts:新增 E-28 EXTRACTION_UNAVAILABLE(运行级,不进 HTTP 信封)与 KnowledgeExtraction 记录类型。契约层强制"失败不得带候选", AC-50「模型不可用⇒不产生候选」是类型约束而不是文档约定。 - services/experience_extraction.py(新):真实提炼入口。模型不可用或调用失败 → 记 E-28 且 candidate_id 为空;不产半成品候选。传输纪律同 assistant_model (禁进程内代理、零重试),且 tools=[] 使"越权读材料"在结构上不可能。 自然语言修订同样必须真实调用模型,没有"把中文猜成条件"的回退路径。 - services/knowledge_cards.py:新增 current_draft/revise/list_cards 与 registry_conditions。修订只产草稿、保留 origin 与来源、升版本记 parent_version; test_cases 纳入可改字段——它是 component_evaluation 对自定义 Skill 的发布门禁, 不开放则提炼出的候选永远卡在评测门外。 - services/project_assistant.py:enqueue 改用 review_plan.assemble(), 让 T06-b 的依赖预检(E-19 可定位文案)与维度解析不再被绕过。 - api/prescreen.py:case-timeline、knowledge-extractions、knowledge-candidates (创建/修订/状态机)、review-plans(装配/状态机)。角色门禁与既有 /components 入口一致;id 与数据域由服务端生成;按 id 的路由一律在 run() 内 查归属,否则 KeyError 会变成 500 而不是 404。 - component_registry/review_plan:下沉 current_draft/version_key 与 list_plans。 前端: - 新增 /experience-center 独立入口(BR-50)与 ExperienceCenter 组件; AgentNav 增加「历史经验加工」。 - originBadge 此前零调用方、.origin-* 无任何 CSS——守卫只 grep 库文件字符串, 于是"测试通过但功能不存在"。本批补齐消费方与样式,并用左边框样式区分四种来源, 保证去色仍可区分(AC-42/BR-48)。 - 守卫语义按 AC-55 调整:由"禁止新建路由"改为"禁止重复页面" (面板不得搬到独立路由、已合并页必须保持重定向),并新增 experience-center-ui 守卫(已登记 verify.py,共 12 项检查)。 测试:新增 36 项(提炼 15 / 候选治理 15 / 卡片到运行 6),全量 unittest 无回归; 两次同项目运行对照证明卡片确实改变了核查结果,且 basis_ids 指向 卡片id@版本。 未闭合(记录在 17 的剩余缺口):真实模型提炼尚未实测(需端点); 界面未经浏览器点击验证;例外边界未进入可求值语言;规则类候选不在本批。 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -170,3 +170,30 @@ TrajectoryStep 的输入/输出正文通过授权存储引用访问;cost 缺
|
||||
导入/冲突→AC-23/24;来源与治理→AC-25/26/27/43;方案/维度→AC-28/29/44;概率/沙盘→AC-30/31;轨迹/结果→AC-22/32/33;改进→AC-34/41;数据集→AC-35/36;业务指标→AC-37;专项准入/冻结/预算→AC-38/39/40;卡片UI→AC-42;建议边界→AC-45。
|
||||
|
||||
本节明确了候选类型和写路径,但读接口完整清单、DDL、生产角色映射、容量/模型时延及实际目录尚未定案。T00先关闭首个实施切片的缺口,不能以“文档写完”宣布全部Contract gate通过。
|
||||
|
||||
### 9.7 已实现接口(纠偏第二批,2026-09-30)
|
||||
|
||||
§9.4 要求"拟新增请求参数必须在契约定案及对应 OpenAPI 中完整列出,未定案不开始接口实现"。
|
||||
以下为**已落地**的接口,路径与字段以本节为准(实现见 `backend/api/prescreen.py`):
|
||||
|
||||
| 接口 | 输入 / 输出 | 权限 / 错误 |
|
||||
|---|---|---|
|
||||
| GET/POST `/projects/{project_id}/case-timeline` | 无输入;输出 CaseTimeline。POST 从项目材料重算,同项目 revision 递增 | 项目查看/材料编辑;POST 后 201;未重建过 GET 返回 404 |
|
||||
| GET `/projects/{project_id}/knowledge-extractions` | 输出 `{items: KnowledgeExtraction[]}`;失败记录照常返回 | 项目查看;404 |
|
||||
| GET `/projects/{project_id}/knowledge-extractions/{id}` | 输出 KnowledgeExtraction | 项目查看;404 |
|
||||
| POST `/projects/{project_id}/knowledge-extractions` | `event_ids:string[]`(空=全部事件)、`requirement:string[0..2000]`;201 KnowledgeExtraction | 提议者;E-28 记在记录里而**非** HTTP 错误;两者都空 → 422 |
|
||||
| GET `/projects/{project_id}/knowledge-candidates` | 输出 `{items: KnowledgeCard[]}`(草稿与已发布) | 项目查看;404 |
|
||||
| POST `/projects/{project_id}/knowledge-candidates` | `kind,title,content,origin,version,source_event_ids,source_evidence_ids,card_scope,team_id,expires_at`;201 草稿。**id 与数据域由服务端生成** | 提议者;E-03/04/07/18 |
|
||||
| PATCH `/knowledge-candidates/{card_id}` | `requirement`(自然语言)**或** `changes`(`conditions`/`exception_note`/`test_cases`)、`note`(必填)、`expected_revision`;200 新草稿修订 | 编辑者;E-03/05/07。自然语言修订需已配置模型,否则 422 并提示改用结构化修改 |
|
||||
| POST `/knowledge-candidates/{card_id}/transitions` | `action:evaluate\|publish`、`expected_revision`、`reason` | evaluate 角色 admin/reviewer;publish 角色 reviewer 且不得自批(E-03);未过评测 → 409 |
|
||||
| GET `/projects/{project_id}/review-plans` | 输出项目自建方案(草稿与已发布);内置种子方案不在此列 | 项目查看;404 |
|
||||
| POST `/projects/{project_id}/review-plans` | 方案字段(`name,skills,rules,template,budget,audience,run_kind,dimensions,version`);201 草稿。**id 与数据域由服务端生成** | 方案编辑;E-03/07/19/20;拒绝 `tools/allowed_tools` 等工具配置面(ADR-11) |
|
||||
| POST `/review-plans/{plan_ref}/transitions` | `action:evaluate\|publish`、`expected_revision` | 同候选状态机;依赖未发布 → 评测不通过、发布 409 |
|
||||
|
||||
**字段口径补充**:
|
||||
- `KnowledgeExtraction.status=failed` 时 `candidate_id` 必须为空,`degradations` 必须非空(契约层强制,见 `contracts/prescreen.py`)。
|
||||
- `KnowledgeCard` 的**例外边界**在本批保存为文本 `exception_note`,不进入可求值条件语言:
|
||||
注册表条件只支持数值阈值算子,`present/absent` 被既有断言锁定拒绝。这是已记录缺口,不是已实现能力。
|
||||
- 卡片"适用条件"在运行时**不参与**逐项判定;它经 `knowledge_cards.effective()` 用于域/范围/有效期过滤,
|
||||
运行内条件求值仍需独立设计。
|
||||
- 运行装配已改用 `review_plan.assemble()`(依赖预检 + 维度解析),此前该模块在生产被绕过。
|
||||
|
||||
Reference in New Issue
Block a user