6.4 KiB
id, title, phase, deps, status, created, vikunja_task_id, context_ref, work_branch, needs_device, needs_human_review, write_paths
| id | title | phase | deps | status | created | vikunja_task_id | context_ref | work_branch | needs_device | needs_human_review | write_paths | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| T-211 | claim wire 输出字段上限闭合 | 2 |
|
DOING | 2026-08-05 | 55 | cfb238d |
task/t-211-claim-wire-bounds | false | false |
|
问题 / 背景
claim 成功响应受 32 KiB 总 body 上限保护,但创建、授权快照、candidate 和重放链路尚未统一约束各自由文本字段,客户端也未冻结同一单字段合法域。异常或历史超长值可能让合法业务事实变成不可传输响应。
关联需求与交互
- 功能:F-005。
- 依赖:T-203、T-302、T-303。
- API:POST /api/v1/tasks/claim-next 及客户端 claim wire model。
- 本任务无 UI、真机或人工验收。
方案
- 统一 title 不超过 120 Unicode code points,sku_color 与 sku_size 各不超过 80 Unicode code points。
- goods_id 仅允许 1--32 位 ASCII 数字;canonical money 仅允许不超过 32 个 ASCII 字符,并保留既有正数、两位小数、无前导零与 int64 约束。
- 在创建、开始采购授权快照、claim candidate、持久化响应与幂等重放边界逐层 fail closed;不迁移、不截断或改写既有数据。
- 客户端 wire model 使用相同边界,漂移响应按协议错误拒绝。
- 增加最坏合法字段的 claim JSON 契约测试,明确编码后小于既有 32 KiB 响应上限。
- HTTP claim handler 在序列化前重验完整 service 响应并保持 32 KiB 上限;因此将精确文件 admin/internal/server/task_claims.go 纳入写路径,不扩大到其他 server 文件。
验收要点
- 边界值通过,超过一个 Unicode code point/ASCII 字符即拒绝;组合字符按 code point 而非字节计数。
- 创建、授权、candidate、首次 claim 与重放均覆盖畸形既有数据并失败闭合。
- 客户端 title/SKU/goods_id/money 与服务端同界。
- 最坏合法 claim JSON 明确小于 32768 字节,保持现有 HTTP body cap。
- handler 拒绝越界或畸形 service 输出,且不泄露响应内容。
- 两端完整测试、vet/build、compileall、根 init、上下文与 diff-check 通过。
执行记录
2026-08-04T17:10:26Z · ila
2026-08-05 开始 T-211:基于 main@cfb238d,在独立 worktree 收紧 claim wire 字段上限;不迁移或截断既有数据,不涉及设备页面、提交订单或付款。
2026-08-04T17:11:07Z · ila
2026-08-05 主脑预审收紧:Go 必须先 utf8.ValidString,再按既有 TrimSpace 后实际持久化值计算 code point;start/authorization 遇既有畸形 task 原子失败,claim replay 重验持久化响应快照;不增加迁移。
2026-08-04T17:18:04Z · ila
2026-08-05 实现范围收紧:HTTP handler 是 service 输出的最后边界,已获总控批准将精确文件 admin/internal/server/task_claims.go 纳入 write_paths;handler 序列化前重验 claim response 与 32 KiB 上限,不扩大到其他 server 文件。
2026-08-04T17:25:07Z · ila
2026-08-05 实现里程碑:服务端共享 validator 已覆盖创建持久化、start/authorization、candidate、claim snapshot/replay 和 handler 输出;客户端 wire 同界。最坏合法服务端 JSON 使用会被 escapeHTML 为 6 字节的 < 字符证明严格小于 32 KiB,客户端用 ensure_ascii=True 做保守预算证明。focused:Go tasks/taskclaim/server 全绿;client core 8/8、remote 15/15。
2026-08-04T17:38:44Z · ila
2026-08-05 审阅修复:统一 Go/Python 持久化文本域,客户端使用 Go Unicode White_Space 固定集,两端均拒绝任意位置 U+001C--U+001F,并补 NBSP/C0 回归。候选查询不再用 SQL 相等条件静默过滤:先读取 task 与 authorization 两侧快照并分别验证,单侧畸形立即回滚且不写 EMPTY/attempt;两侧均合法但不一致才按既有语义跳过。最坏合法 JSON 也覆盖 int64 版本编码上界。
边界
title最多 120 个 Unicode code point,sku_color/sku_size各最多 80 个 Unicode code point;边界以 Gostrings.TrimSpace的 Unicode White_Space 集处理后的实际持久化值为准。 客户端使用同一固定空白集,不依赖 Pythonstr.strip()默认语义;两端均拒绝任意位置的 U+001C--U+001F 四个 C0 分隔符。Go 必须先通过utf8.ValidString,不能把 非法 UTF-8 解码出的RuneError当成合法 code point;不按 UTF-8 字节、不按视觉 grapheme, 也不得为通过校验截断或规范化改写非空内容。goods_id只允许 1--32 位 ASCII 数字;canonical money 只允许 1--32 个 ASCII 字符,并继续 满足既有正数、恰好两位小数、无非法前导零的规范格式。数量、版本与 generation 的正 int64 边界保持不变,不能接受 bool、浮点数或字符串整数。- 创建任务、开始采购的授权快照、claim candidate、首次响应快照与幂等重放必须使用同一字段合法域。
candidate 必须先读取并分别校验 task 与 authorization 两侧字段;任一侧畸形立即回滚且不写
EMPTY, 只有两侧均合法但快照不一致时才跳过。start/authorization 遇到既有畸形 task 必须原子失败,claim replay 还必须重新校验持久化响应快照。任一层发现超限或畸形既有数据都失败闭合,不迁移、不截断、 不覆盖或修复历史行。 - claim 成功响应继续受既有 32 KiB HTTP body 上限约束;最坏合法字段组合的编码结果必须由契约测试 明确证明小于该上限。HTTP handler 在序列化前重验完整 claim response,并拒绝任何越界 service 输出;不得调高响应上限掩盖无界字段。
- 客户端 claim wire model 与服务端使用完全相同的上限;未知、缺失、超限或格式漂移响应必须拒绝, 不得静默接受后再截断入库。
- 本任务不修改数据库迁移或 schema,不连接设备,不改变授权、身份、租约、幂等、int64、金额或安全 边界,不实现事件、围栏、提交订单、付款或任何页面自动化能力。