 qiaoqichaoandClaude Code
|
669e969c41
|
feat(v2): T03 来源定位接上契约,并锁定跨项目引用拒绝
T03 卡的要求是"复用上传/确认入口,增加导入清单、定位和冲突候选"。核对后:
导入清单与冲突候选已由 T02/S1 交付,但**"定位"只定义了契约、没有接上**——
parse() 仍只产出自由字符串 locator,SourceLocator 类型化投影是空的。
本次补上这条链路(契约与实现不一致是我的遗留)。
- assistant_materials.parse():每条 chunk 增加 source_locator(kind + 坐标),
按 T00/04 §5.3 的映射:pdf→page、xlsx 单元格/行与 csv/txt/docx 表格→sheet+cell_range、
docx 正文段→manual(note)
- material() 补 document_id/document_version 后**按契约校验**;漏了定位或定位不合法
直接抛错,不落半成品进库
- **locator 自由字符串保留**:enqueue() 依赖它算证据 ID 的稳定哈希,改它会破坏 BR-13
实现中修掉一个自己引入的 bug:类型化定位的辅助函数初版命名为 table,与 docx 分支里
的表格计数器 table 同名,该分支内 helper 被整数遮蔽('int' object is not callable)。
已改名 sheet_loc。
AC-08 补测:跨项目候选引用被 supplement 拒("不属于项目"),同项目可用作对照,
未知 candidate_id 同样被拒。既有 test_project_assistant 只覆盖了跨项目文档下载。
测试:新增 test_sourcelocator.py 13 项,含真实 XLSX/DOCX fixture(zipfile 构造),
覆盖五种格式的定位派生与契约校验。全量 248 项 OK(235 → 248);verify.py 10/10 PASS。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-09-29 18:21:51 +08:00 |
|
 qiaoqichaoandClaude Code
|
fcf4d8c948
|
feat(v2): S1 接口层——材料导入与事实冲突的 8 个端点
T02 第三个子卡。命名空间按 T00/04 §1 定案 P1 挂 project-assistant 之下,
复用现有鉴权与同源代理,鉴权/代理代码零改动。
新增 backend/api/prescreen.py(7 路径 / 8 操作)+ test_prescreen_api.py(27 项)。
app.py 仅新增 1 个 include_router 与 1 个异常处理器注册。
落实:
- 404 统一口径(03 §2):不存在与无访问权一律 404,不泄露对象存在性。
既有 check_project 抛 403 且被 5 个模块共用,故不改它,由本模块 scope() 包装。
实测:无权项目返回 404 NOT_FOUND 而非 403。
- 错误信封(D2):只在新路由输出 {error:{code,message,retryable,request_id}}。
- E-09 与 E-05 精确区分:新增 store.IdempotencyConflict,不再靠字符串比对猜码。
- 客户端清单只接受 4 个字段;id/status/received_at 由服务端生成——
状态机写权不下放。manifest 校验因此从"整对象"改为"4 字段 + 服务端补全"。
**实测发现的缺口并已修复**:Input(extra="forbid") 的校验错误由 FastAPI 校验层在
进入端点前抛出,不经过 run(),导致同一命名空间出现两种错误形状。现注册
RequestValidationError 处理器,但**只在 prescreen 路径生效**,其它路径交回
FastAPI 默认实现——既有端点形状经实测确认未变(含校验错误的形状)。
验证:
- scripts/verify.py 9/9 PASS(exit 0);全量单测 225 项 OK(196 → 225)
- claude_use/T02/smoke_s1.py 在真实 app.py 上 10/10 PASS:覆盖路由注册、
真实前缀下的 manager 鉴权放行、404 统一、信封形状、以及既有端点未被污染
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-09-29 16:45:07 +08:00 |
|
 qiaoqichaoandClaude Code
|
c59fff68d3
|
feat(v2): S1 存储层——材料导入批次与事实冲突检测
T02 第二个子卡。复用 assistant_objects(新 kind),**未新建表**;旧库结构不变。
新增服务:
- services/material_import.py 批次生命周期:create/load/listing/mark_item/
retry/cancel;状态由逐项状态派生(ready/partial/failed/parsing)
- services/fact_conflict.py 冲突检测/阻断/裁定;FactConflictUnresolved(E-17)
解决的**真实缺口**(BR-23 / AC-24):既有 apply_candidate 对 values/facts 是
后写覆盖,sources 虽累积多来源但无人检测分歧、无人阻断。本层在**新路径**前置
检测:冲突时证据仍入 sources(BR-22 留痕)但值不采用(BR-23),已确认值不被覆盖。
增量改动(均为可加性,未改既有语义与调用方行为):
- assistant_store.py:新增 idempotent_lookup / idempotent_remember 共享 helper。
既有 enqueue 与 create_report 的内联实现**未改写**。用 INSERT OR REPLACE 而非
裸 INSERT:重试路径上裸 INSERT 会抛 sqlite3.IntegrityError(非 Conflict,
translate() 无法映射为 409)。
- assistant_materials.apply_candidate 新增 adopt=True 形参。adopt=False 只记证据
不改值;既有调用方不传参,行为完全不变(有回归测试)。
设计决定:
- T00/04 曾提 3 个 kind;实现时发现契约中 ImportItem 无 revision 且内嵌于批次,
items 是值对象,故收敛为 2 个 kind(import_batch / fact_conflict)
- E-17 有两个面:确认动作被拒 = 422;运行级结果 = HTTP 200 且冲突存于
degradations。契约映射与注释均已写明,并有测试锁定
测试:新增 test_prescreen_storage.py(33 项)。全量 196 项 OK(124 → 196)。
scripts/verify.py 9/9 PASS(exit 0)。
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-09-29 14:49:03 +08:00 |
|
 qiaoqichaoandClaude Code
|
d56c699ce6
|
chore(v2): 从兴邦预审v2白名单抽取独立可运行基座
按 docs/v2/05-implementation-plan.md §1 候选迁移表与 claude_use/T00 白名单,
从 55e2cdb 抽取 224 个文件(2.48 MB)到独立目录 F:/mini-OpenClaw-v2。
- 排除:凭据(.env/server-deploy.conf/旧DELIVERY.md)、运行数据(xingbang_data 等
4 个 SQLite)、依赖(venv/node_modules 符号链接)、归档(_backup*/test-evidence/
ori_file)、Office 临时文件
- 目标目录独立 git 仓库,初始恢复点;Gitea 远程与分支待 OQ-06 Q2 定案
- 未部署、未启动服务、未调用模型
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
2026-09-29 12:58:26 +08:00 |
|