Files
cmbuyer/docs/tasks/T-211.md
T

93 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: T-211
title: claim wire 输出字段上限闭合
phase: 2
deps: [T-203, T-302, T-303]
status: DOING
created: 2026-08-05
vikunja_task_id: 55
context_ref: cfb238d
work_branch: task/t-211-claim-wire-bounds
needs_device: false
needs_human_review: false
write_paths:
- docs/tasks/T-211.md
- docs/api.md
- admin/internal/tasks/**
- admin/internal/taskclaim/**
- admin/internal/server/task_claims.go
- admin/internal/server/task_claims_test.go
- client/src/cmbuyer_client/core/**
- client/tests/core/**
- client/tests/remote/**
---
<!-- BEGIN VIKUNJA EXPORT id=55 synced=2026-08-04T17:25:11Z sha256=7fd613a5a64643deb5601136241868717a00cc9e7739c6f6a5bb2295e2a9210d -->
## 问题 / 背景
claim 成功响应受 32 KiB 总 body 上限保护,但创建、授权快照、candidate 和重放链路尚未统一约束各自由文本字段,客户端也未冻结同一单字段合法域。异常或历史超长值可能让合法业务事实变成不可传输响应。
## 关联需求与交互
- 功能:F-005。
- 依赖:T-203、T-302、T-303。
- API:POST /api/v1/tasks/claim-next 及客户端 claim wire model。
- 本任务无 UI、真机或人工验收。
## 方案
1. 统一 title 不超过 120 Unicode code points,sku_color 与 sku_size 各不超过 80 Unicode code points。
2. goods_id 仅允许 1--32 位 ASCII 数字;canonical money 仅允许不超过 32 个 ASCII 字符,并保留既有正数、两位小数、无前导零与 int64 约束。
3. 在创建、开始采购授权快照、claim candidate、持久化响应与幂等重放边界逐层 fail closed;不迁移、不截断或改写既有数据。
4. 客户端 wire model 使用相同边界,漂移响应按协议错误拒绝。
5. 增加最坏合法字段的 claim JSON 契约测试,明确编码后小于既有 32 KiB 响应上限。
6. 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。
<!-- END VIKUNJA EXPORT -->
## 边界
- `title` 最多 120 个 Unicode code point,`sku_color` / `sku_size` 各最多 80 个 Unicode
code point;边界以既有 `TrimSpace` 后实际持久化值为准。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、首次响应快照与幂等重放必须使用同一字段合法域;
start/authorization 遇到既有畸形 task 必须原子失败,claim replay 还必须重新校验持久化响应快照。
任一层发现超限或畸形既有数据都失败闭合,不迁移、不截断、不覆盖或修复历史行。
- claim 成功响应继续受既有 32 KiB HTTP body 上限约束;最坏合法字段组合的编码结果必须由契约测试
明确证明小于该上限。HTTP handler 在序列化前重验完整 claim response,并拒绝任何越界 service
输出;不得调高响应上限掩盖无界字段。
- 客户端 claim wire model 与服务端使用完全相同的上限;未知、缺失、超限或格式漂移响应必须拒绝,
不得静默接受后再截断入库。
- 本任务不修改数据库迁移或 schema,不连接设备,不改变授权、身份、租约、幂等、int64、金额或安全
边界,不实现事件、围栏、提交订单、付款或任何页面自动化能力。