Commit Graph
3 Commits
Author SHA1 Message Date
qiaoqichaoandClaude Code 2e7e19471c 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>
2026-10-01 00:31:42 +08:00
qiaoqichaoandClaude Code d18c147076 feat(v2): T05-c 运行补充说明只能形成草稿(AC-26)
运行时的"本次预审补充说明"只影响本次运行(run_instruction 落在运行对象上,
属 T07 的 ScreeningRun 字段)。要变成持久知识只有一条路:显式提议为草稿,
且走正常审核。本批实现卡片侧的那一半。

新增 knowledge_cards.draft_from_run_instruction(),三条约束:
1. 只产草稿——运行中说过的话绝不直接生效(有测试断言无已发布版本产生)
2. **不得携带工具/权限/引擎字段**:allowed_tools / tools / permissions / engine /
   run_instruction 出现即拒,扩大工具授权必须走独立提议与审核
3. 记录 derived_from_run,便于回溯知识来自哪次运行
另:运行指令不能声明为 history_derived(历史提炼须提供来源事件或证据),
hard 门禁对运行衍生的卡片同样生效。

未完成:运行对象上的 run_instruction 字段与"只影响本次运行"的服务端实现属 T07,
本批只交付卡片侧,不宣称 AC-26 已整体闭环。

测试:test_knowledge_cards.py 增至 25 项(新增 5 项)。
全量 315 项 OK(310 → 315);verify.py 10/10 PASS。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-29 18:51:12 +08:00
qiaoqichaoandClaude Code f8c4ba9e1d feat(v2): T05-b 知识卡片与硬规则依据门禁
T05 第二步:候选与治理。设计明令"复用卡片治理、不新建第二套发布库",
故本模块**只做投影**,状态机与发布完全委托 component_registry。

新增 contracts:Origin / GovernanceStatus / RuleEffect / Condition /
RuleContent / KnowledgeCard。Condition 只允许字段+有限算子,**不执行表达式**。
RuleContent 在契约层就要求 hard 必须带 policy_ref 或 authorization_ref 且附依据证据。

新增 services/knowledge_cards.py:
- propose():投影字段(origin/谱系/范围/条件)后委托 registry.draft(),**只产草稿**
- publish():发布时**再查一次** hard 门禁——草稿可能在提议后被改,不能只信提议时的校验
- effective():按数据域/有效期/范围过滤已发布版本(BR-04)

既有治理的保证原样生效,有测试锁定:自批被 release() 拒绝、无评测不能发布、
已发布需新版本号、提议不产生已发布版本。

三处必须点明的边界与映射:
1. **同键不同义**:本设计的 data_domain ↔ 注册表的 scope(demo/production),
   而本设计的 scope 是 project/team。投影层显式互换并存为 card_scope,绝不混用;
   调用方私传 data_domain 会被拒
2. **条件形状不同**:注册表条件是 {code,field,operator,threshold,title,suggestion},
   本设计是 {field,operator,value}。做**翻译**而非强加;算子只映射注册表实际
   会产出的 5 个(gt/lt/eq/gte/lte),出现其它取值即报错而非当作已支持
3. **内置种子组件是全局的**,没有 project_id/edited_by,**不是项目知识卡片**。
   投影时明确报错,避免把内置 Skill 误当项目卡片

测试:新增 test_knowledge_cards.py 20 项(门禁 6 + 来源谱系 6 + 治理复用 5 + 有效过滤 3)。
全量 310 项 OK(290 → 310);verify.py 10/10 PASS。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-29 18:47:59 +08:00