feat: 根目录文档、脚本、gitignore

This commit is contained in:
2026-10-08 16:15:33 +08:00
commit e98660ce4e
284 changed files with 26838 additions and 0 deletions
@@ -0,0 +1,40 @@
# 架构设计摘要
> 摘自 PRD 第 5 章(prd_final.md),为归档速查版;完整论证见 01_input/prd_final.md。
## 总体方案
最大复用现有 zt_* 功能,缺口分三类补齐:
1. **数值指标加列**:zt_story_expand.ai_participation_rate(一期唯一 DDL);任务级 AI 工时直接入 zt_task.estimate(zt_task_extend 已砍,CHG-019)
2. **AI 文档走 MD 文件流**(CHG-014 用户拍板):审查报告/工作日志/测试报告/纪要 = MD 附件,不建结构化表
3. **绩效统计接入**:IZtCountService 消费 zt_story_expand 指标(三期)
## 核心机制
| 机制 | 决策 | 依据 |
|---|---|---|
| 扩展表模式(数值) | ✅ 采用 | zt_story_expand 先例;不碰老表 |
| MD 文件流(文档) | ✅ 采用(CHG-014) | 不建表、人可直接阅读;弱结构化用 MD 头部约定补偿 |
| zt_task 直接加列 | ❌ 放弃 | 污染禅道老表 |
| 验收指标结构化新表 | ❌ 放弃 | 富文本够用,过度设计 |
## 三通道上传架构
| 通道 | 接口 | 模式 | 鉴权(CHG-061) |
|---|---|---|---|
| 数值指标 | /zt-story-expand saveOrUpdate | 幂等(业务键有则更新) | 限 ai 账户 |
| 任务批量 | /zt-task aiBatchAdd | 双通道(AI 框架 + 人工保留) | 限 ai 账户 |
| MD 文档 | /common/upload + uploadBind | 文件+绑定两步 | 需登录 |
## ID 流转约定(5.6)
1. storyId:zentao 建单分配 → 回填 PRD「关联需求ID」→ 上传以此为键
2. taskId:aiBatchAdd 响应返回,框架记录
3. MD 关联:zt_file.objectID=storyId,objectType 区分类型
4. 共享载体 = PRD 文档(非个人工作区);ai 账户与使用者解耦
## 关键卡点
- code_review_status(pass/reject)未 pass → 禁提测试报告(CHG-023)
- FileTypes 扩展:aiCodeReview / aiWorkLog / testCase / testReport / testReportSubmit / testOther
@@ -0,0 +1,38 @@
# 数据模型
> 摘自 PRD 5.4 字段表 + 7.1 一期 DDL。完整口径见 prd_final.md 第 7 章。
## 一期 DDL(已交付)
```sql
ALTER TABLE `zt_story_expand`
ADD COLUMN `ai_participation_rate` VARCHAR(16) DEFAULT NULL
COMMENT 'AI参与率(只存不算,口径待定)' AFTER `ai_efficiency_coefficient`;
```
## 二期 DDL/字段(已设计,随版本交付)
| 字段 | 表 | 类型 | 说明 | 决策 |
|---|---|---|---|---|
| url | zt_file | varchar(512) | 附件访问链接(pathname=存储路径,url=可访问地址) | CHG-018 |
| url | zt_meeting | varchar(512) | 会议纪要 MD 链接,存最新一份 | CHG-020 |
| prd_url / code_review_url / work_log_url / test_case_url / test_report_download_url / test_report_submit_url / test_other_url | zt_story | varchar(512)×7 | 研发需求 7 类文档链接,各存最新一份 | CHG-021/022/025 用户拍板 |
| code_review_status | zt_story | varchar(16) | pass/reject/NULL;上传时解析写入 | CHG-023 |
## FileTypes 枚举扩展
aiCodeReview / aiWorkLog / testCase(下载)/ testReport(供下载)/ testReportSubmit(提交)/ testOther
## 已否决的表(决策留痕)
| 表 | 否决原因 | 决策 |
|---|---|---|
| zt_ai_code_review / zt_ai_work_log | MD 文件流替代 | CHG-014 |
| zt_task_extend | evaluation_time 与 zt_task.estimate 冗余;指数无消费方 | CHG-019 |
## 关键口径(7.3 节选)
- 大型需求判定:workloadIndex > 20 → 五类文档强制
- 月度达标工时 =(工作天数×人数 − 团队请假天数)×5÷人数(CHG-034 全团队平摊)
- 普通/重大 Bug:severity 1=重大、2/3/4=普通(2026-08-04 已决)
- 待确认 5 项见 03_plan/risks.md
@@ -0,0 +1,344 @@
# AI 交互接口文档 —— 禅道 AI SOP 改造(二期)
> **版本**:v1.0 | **日期**:2026-08-06 | **关联改动**:CHG-039 ~ CHG-070(鉴权落地 CHG-061)
> **验证状态**:✅ 已验证(全部字段/分支/错误文案均取自运行代码实证,非推测)
> **证据位置**:见文末「证据映射表」;单测 24 绿、8086 三×三鉴权矩阵实测通过(dev_log CHG-061)
> **适用范围**:AI 框架通道(demand-assessor / pmassist / tgassist 等技能脚本)与 zentao 后端的全部交互接口
---
## 1. 通用约定
### 1.1 Base URL
| 环境 | Base URL | 说明 |
|---|---|---|
| 本地测试 | `http://127.0.0.1:8085/zentao` | 框架脚本(submit_assessment.py / upload_md.py)默认地址(CHG-061 拍板"别用正线的 url") |
| 测试库直连验证 | `192.168.1.161:3306/zentao_dev` | DB 回读校验用,非接口地址 |
| 生产 | `http://192.168.1.105:8015/zentao` | ⚠️ [ASSUMPTION] 端口 8015 见 dev_log CHG-070"发布 8015 即可生效";主机地址以部署实为准 |
- 所有路径均含上下文根 `/zentao`(部署于域名根路径)。
- 字符集 UTF-8;JSON 接口 `produces = application/json; charset=UTF-8`。
### 1.2 鉴权(CHG-061 落地)
- 请求头:**`Authorization: {token}`**(JWT,由 `JwtAuthenticationFilter` 解析,写入 `RiskUserThreadLocal`)。
- token 获取(人工/调试用):
```
POST /zentao/zt-user/login
Content-Type: application/json
{"account":"admin","password":"<md5(密码)>"}
→ 响应 data 即 token
```
- **AI 通道使用 ai 账户永久 token**(生成于 `.claude/ai_token.txt`,框架两脚本自动携带,无需手工管理)。
- token 缺失或无效:过滤器直接返回 `{"code":-1,"message":"请登录"}`,不进入业务层。
**接口级权限矩阵**:
| 接口 | 权限要求 | 越权响应 |
|---|---|---|
| `/zt-story-expand/saveOrUpdate` | **仅 ai 账户 token** | `code:-1` "该接口仅AI框架通道可用(需ai账户token)" |
| `/zt-task/aiBatchAdd` | **仅 ai 账户 token** | `code:-1` "aiBatchAdd仅AI框架通道可用(需ai账户token)" |
| `/common/uploadBind` | **任意登录态**(AI 带 ai token;UI 带用户 token) | `code:-1` "请登录(上传需携带有效token)" |
### 1.3 统一响应结构
```json
{ "code": 0, "message": "成功", "data": { } }
```
| code | 含义 | 触发 |
|---|---|---|
| `0` | 成功 | 正常返回(data 可为 null) |
| `-1` | 失败 | 业务校验失败(BusinessException,message 为具体原因);文件为空;未登录 |
| `-2` | 重复添加 | 框架保留码,本三接口未使用 |
| `401` | 请登录 | 框架保留码;实际未登录返回 `-1` + "请登录"(过滤器写死) |
### 1.4 AI 框架典型调用时序
```mermaid
sequenceDiagram
participant Skill as AI 技能脚本<br/>(demand-assessor/tgassist)
participant ZT as zentao 后端
participant DB as MySQL (zt_*)
Note over Skill: .claude/ai_token.txt<br/>自动读 ai 永久 token
Skill->>ZT: ① POST /zt-story-expand/saveOrUpdate<br/>(W 指标 + 验收标准 MD)
ZT->>DB: upsert zt_story_expand(按 story_id)
Skill->>ZT: ② POST /zt-task/aiBatchAdd<br/>(拆分 devel/test 任务)
ZT->>DB: insert zt_task × N(跳过重复)<br/>+ zt_action 留痕(任务级+需求级)
Skill->>ZT: ③ POST /common/uploadBind<br/>(PRD/审查报告/日志等 MD 文件)
ZT->>DB: 刷新主表 url 字段 → 插 zt_file<br/>+ zt_action 动态
ZT-->>Skill: {"code":0,"data":zt_file 记录}
```
---
## 2. 接口一览
| # | 接口 | 方法 | 路径 | Content-Type | 鉴权 | 用途 | 关联 FR |
|---|---|---|---|---|---|---|---|
| 1 | AI 评估指标与验收标准提交 | POST | `/zentao/zt-story-expand/saveOrUpdate` | application/json | 仅 ai token | 七步评估结果(S/B/F(T)/G(A)/W)+ 验收标准 MD 落库 | FR-004 |
| 2 | AI 批量拆分任务 | POST | `/zentao/zt-task/aiBatchAdd` | application/json | 仅 ai token | 按任务清单批量建 devel/test 任务,防重跳过 | FR-006 |
| 3 | 文件上传并绑定业务对象 | POST | `/zentao/common/uploadBind` | multipart/form-data | 任意登录态 | 上传 MD 等文件,同步刷新主表 url 字段 | FR-002/005/008/010/011 |
---
## 3. 接口 1:AI 评估指标与验收标准提交
```
POST /zentao/zt-story-expand/saveOrUpdate
Content-Type: application/json
Authorization: {ai token}
```
**用途**:demand-assessor 七步评估完成后,将工作量指标与 AI 框架验收标准写入 `zt_story_expand`(按 `story_id` upsert)。生产侧由 `submit_assessment.py` 调用。
### 3.1 请求体字段(ZtStoryExpand)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `storyId` | Integer | ✅ | 需求 ID(zt_story.id)。**为空时服务端静默返回成功、不处理**(见 3.2 分支②) |
| `numberUnits` | Integer | 评估时✅ | 单元数量 S |
| `unitBusinessComplexity` | String | 评估时✅ | 单元业务复杂度 B(如 `"2.2"`) |
| `technicalComplexityCoefficient` | String | 评估时✅ | 技术复杂度系数 F(T)(如 `"1.4"`) |
| `aiEfficiencyCoefficient` | String | 评估时✅ | AI 效率系数 G(A)(如 `"0.55"`) |
| `evaluationTime` | BigDecimal | 评估时✅ | 评估工时 W(人日,如 `5.1`) |
| `workloadIndex` | String | 否 | 工作量指数(finished 结算时优先取库内已有值) |
| `aiParticipationRate` | String | 否 | AI 参与率(只存不算,口径待定) |
| `requirementStatus` | String | 否 | `inProgress`(默认)/ `finished`;**finished 触发月度工作量结算** |
| `requirementCompletionDegree` | String | 否 | 需求完成度 `"0"~"100"`;finished 时被强制置 `"100"` |
| `acceptanceCriteria` | String | 否 | AI 框架验收指标(Given/When/Then,MD 文本)。与老验收标准 `zt_storyspec.verify` 互不干扰(CHG-022) |
| `productPerson` / `developPerson` / `testPerson` | String | 否 | 产品/开发/测试人员(中文名) |
| `id` / `createTime` / `updateTime` / `createUser` / `updateUser` | — | 无需传 | 服务端维护(id 自增,时间戳自动写) |
| `storyTitle` / `createUserNickname` / `month` / `monthEvaluationTime` | — | 无需传 | 非数据库字段(查询展示/内部结算用) |
### 3.2 业务规则与分支
| # | 分支 | 行为 |
|---|---|---|
| ① | token 非 ai 账户 | 拒绝:`-1` "该接口仅AI框架通道可用(需ai账户token)" |
| ② | `storyId` 为空 | **静默返回 `code:0`**,不建不改(注意:不等于参数报错) |
| ③ | 该 storyId 无记录 | insert;`requirementStatus` 未传时默认 `inProgress`;create/updateTime=now |
| ④ | 已有记录且其状态为 `finished` | **拒绝**:"该需求已完成,不可再修改"(守卫:定稿后不可覆写) |
| ⑤ | 已有记录(非 finished) | update by id,updateTime=now |
| ⑥ | 本次提交 `requirementStatus=finished` | 强制完成度 `"100"`;写当月 `zt_story_month_workload`:增量 = 100 − 历史最高完成度;折算工时 = 工作量指数 × 增量 ÷ 100(2 位小数 HALF_UP);增量 ≤ 0 记 0 |
| ⑦ | 幂等性 | 同 storyId 重复提交 = 覆盖更新,不产生重复行 |
### 3.3 报文示例
```json
{
"storyId": 9130,
"numberUnits": 3,
"unitBusinessComplexity": "2.2",
"technicalComplexityCoefficient": "1.4",
"aiEfficiencyCoefficient": "0.55",
"evaluationTime": 5.1,
"workloadIndex": "5.1",
"developPerson": "魏冬霞",
"testPerson": "罗勇",
"acceptanceCriteria": "## AC-001\n- Given ...\n- When ...\n- Then ..."
}
```
### 3.4 响应
```json
{ "code": 0, "message": "成功", "data": null }
```
失败:`{ "code": -1, "message": "该接口仅AI框架通道可用(需ai账户token)" }` / `{ "code": -1, "message": "该需求已完成,不可再修改" }`
---
## 4. 接口 2:AI 批量拆分任务
```
POST /zentao/zt-task/aiBatchAdd
Content-Type: application/json
Authorization: {ai token}
```
**用途**:按任务清单为指定需求批量创建研发/测试任务;同需求下重名同类型任务自动跳过。生产侧由任务拆分流程(tasks.md → zentao)调用。
### 4.1 请求体字段(ZtTaskAiBatchDTO)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `storyId` | Integer | ✅ | 需求 ID;不存在则整批拒绝 |
| `tasks` | Array | ✅ 非空 | 任务项列表 |
| `tasks[].name` | String | ✅ | 任务名称(空则整批拒绝) |
| `tasks[].type` | String | ✅ | 仅 `devel`(开发)/ `test`(测试);其他值**整批拒绝** |
| `tasks[].assignedTo` | String | 否 | 指派人账号(zt_user.account);留痕时转中文昵称显示 |
| `tasks[].aiEvaluationTime` | Float | 否 | AI 评估工时 → 同时写入 `estimate` 与 `left`,`consumed=0` |
| `tasks[].planStartDate` | String | 否 | 预计开始 `yyyy-MM-dd` → `estStarted` |
| `tasks[].deadline` | String | 否 | 预计完成 `yyyy-MM-dd` → `deadline`,并写 `deadlineTime`(秒级时间戳) |
### 4.2 业务规则与分支
| # | 分支 | 行为 |
|---|---|---|
| ① | token 非 ai 账户 | 拒绝:`-1` "aiBatchAdd仅AI框架通道可用(需ai账户token)" |
| ② | `storyId` 空 / 需求不存在 / `tasks` 空 / 任一 name 空 / 任一 type 非 devel\|test / 日期格式错 | **整批拒绝**(BusinessException,事务回滚,一个都不建) |
| ③ | 防重 | 同需求下已存在 `name#type`(未删除)→ 跳过并记入 `skipped`;**批内重复同样防重**(建过的 key 即时入集合) |
| ④ | 创建字段 | `status=wait`、`openedby=ai`(token 身份)、`openeddate=now`、`estimate=left=aiEvaluationTime` |
| ⑤ | 留痕(CHG-059/060/062) | 任务级:`zt_action`(RW+XJ)每任务一条,与手工建任务同形状;需求级:**一批合并一条**(XQ+BJ),文案含个数、序号、各任务名称/类型/工时/指派中文名、跳过数 |
| ⑥ | 日期格式 | 非法日期整批拒绝:"日期格式错误,应为yyyy-MM-dd:{任务名}" |
### 4.3 报文示例
```json
{
"storyId": 9130,
"tasks": [
{"name": "二期 DDL×3 + 自测", "type": "devel", "assignedTo": "guoqibing",
"aiEvaluationTime": 8, "planStartDate": "2026-08-10", "deadline": "2026-08-11"},
{"name": "后端接口测试:uploadBind/aiBatchAdd", "type": "test", "assignedTo": "zhangfubin",
"aiEvaluationTime": 8, "planStartDate": "2026-08-12", "deadline": "2026-08-12"}
]
}
```
### 4.4 响应
```json
{
"code": 0,
"message": "成功",
"data": {
"created": 2,
"taskIds": [18565, 18566],
"skipped": ["二期 DDL×3 + 自测"]
}
}
```
- `created`:本次实际新建数;`taskIds`:新建任务 ID 列表;`skipped`:因重名同类型跳过的任务名列表。
- 全部重复时:`created:0`、`taskIds:[]`、`skipped` 全量 —— 仍返回 `code:0`(跳过不算失败)。
---
## 5. 接口 3:文件上传并绑定业务对象
```
POST /zentao/common/uploadBind
Content-Type: multipart/form-data
Authorization: {任意登录态 token}
```
**用途**:上传文件(AI 框架场景为 MD 文档)并一步绑定到业务对象:写磁盘 + 插 `zt_file` + **按 objectType 刷新主表访问链接字段** + 写动态留痕。生产侧由 `upload_md.py` 调用(默认本地 8085、自动带 ai token)。
### 5.1 表单字段(UploadDTO)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `file` | File | ✅ | 上传文件(空文件拒绝);服务端仅保留原扩展名,文件名为 `yyyyMMddHHmmss + UUID` |
| `objectType` | String | ✅ | 业务对象类型,**白名单 9 类**(见 5.2);不在白名单整体拒绝 |
| `objectId` | Integer | ✅ | 主表记录 ID(需求/会议);记录不存在则拒绝 |
| `title` | String | 否 | 文件标题;缺省取原始文件名(中文标题落库正确,CHG-061 已验证) |
| `reviewResult` | String | 否 | **仅 `objectType=aiCodeReview` 有效**:`pass` / `reject`,非空时同步写 `zt_story.code_review_status` |
### 5.2 objectType → 主表字段刷新映射(白名单)
| objectType | 含义 | 刷新主表字段 | 动态留痕 |
|---|---|---|---|
| `story` | PRD/需求文档 | `zt_story.prd_url` | XQ+BJ |
| `aiCodeReview` | 代码审查报告 | `zt_story.code_review_url`(+`code_review_status`,若传 reviewResult) | XQ+BJ |
| `aiWorkLog` | 工作日志 | `zt_story.work_log_url` | XQ+BJ |
| `aiDocUpdate` | AI 项目文档更新记录 | `zt_story.ai_doc_update_url` | XQ+BJ |
| `testCase` | 测试用例 | `zt_story.test_case_url` | XQ+BJ |
| `testReport` | 测试报告模版 | `zt_story.test_report_download_url` | XQ+BJ |
| `testReportSubmit` | 测试报告提交 | `zt_story.test_report_submit_url` | XQ+BJ |
| `testOther` | 其他测试文档 | `zt_story.test_other_url` | XQ+BJ |
| `meeting` | 会议纪要 | `zt_meeting.url` | MEET+BJ |
> FileTypes 枚举另有 task/bug/userStory 等 6 个 code,但 **uploadBind 不支持**——传入会拒绝:"uploadBind不支持的objectType:{type}"。
### 5.3 业务规则与分支
| # | 分支 | 行为 |
|---|---|---|
| ① | 无登录态 | `-1` "请登录(上传需携带有效token)" |
| ② | file 为空 | `-1` "失败" |
| ③ | objectType/objectId 为空 | `-1` "objectType/objectId不能为空" |
| ④ | objectType 非枚举值 | "不支持的objectType:{type}";是枚举但非白名单 → "uploadBind不支持的objectType:{type}" |
| ⑤ | objectId 记录不存在 | "需求不存在:{id}" / "会议不存在:{id}" |
| ⑥ | 执行顺序(事务) | **先校验并刷新主表 → 失败整体回滚不落盘**;再写磁盘 → 插 `zt_file` → 写 `zt_action`(文案含完整可访问 URL) |
| ⑦ | 落库字段 | `zt_file.addedby` = token 身份;`pathname`/`url` = 相对路径 `/zentao/img/{文件名}`(经前端源/代理可达,规避跨域);`size` 字节数;`extension` 原扩展名 |
| ⑧ | 多文件 | 同一 (objectType, objectId) 可多次上传,形成多份列表;主表 url 字段记录**最新一份**,前端列表取 `zt_file` 全集 |
### 5.4 调用示例
```bash
curl -X POST "http://127.0.0.1:8085/zentao/common/uploadBind" \
-H "Authorization: {ai token}" \
-F "file=@代码审查报告.md" \
-F "objectType=aiCodeReview" \
-F "objectId=9130" \
-F "title=代码审查报告-v1" \
-F "reviewResult=pass"
```
### 5.5 响应
```json
{
"code": 0,
"message": "成功",
"data": {
"id": 1234,
"title": "代码审查报告-v1",
"extension": ".md",
"size": 5321,
"pathname": "/zentao/img/20260806170215a1b2c3....md",
"url": "/zentao/img/20260806170215a1b2c3....md",
"objecttype": "aiCodeReview",
"objectid": 9130,
"addedby": "ai",
"addeddate": "2026-08-06 17:02:15",
"deleted": "0"
}
}
```
---
## 6. 失败分支汇总(排障速查)
| 现象 | code | message | 排查 |
|---|---|---|---|
| 未带 token / token 失效 | -1 | 请登录 | 检查 `Authorization` 头;ai token 见 `.claude/ai_token.txt` |
| 用人工 token 调 saveOrUpdate / aiBatchAdd | -1 | 仅AI框架通道可用(需ai账户token) | 换 ai token;这是设计守卫,非缺陷 |
| 需求已 finished 再提交指标 | -1 | 该需求已完成,不可再修改 | 生产 itsm 已有 finished 记录被此守卫拒绝(summary 2026-08-06),属按设计拦截 |
| saveOrUpdate 返回 0 但库里没数据 | 0 | 成功 | 检查是否漏传 `storyId`(分支 3.2② 静默成功) |
| aiBatchAdd 一个任务都没建 | -1 | (任一校验消息) | 整批拒绝机制:任一任务非法全部回滚;先修非法项 |
| aiBatchAdd 成功但 created=0 | 0 | 成功 | 全部命中防重,看 `skipped` |
| uploadBind 报类型不支持 | -1 | (uploadBind)不支持的objectType | 对照 5.2 白名单(9 类) |
| uploadBind 成功但页面看不到 | 0 | 成功 | 前端列表读 `zt_file`;检查 objectType/objectId 是否传对、前端是否按类型渲染 |
---
## 7. 证据映射表
| 章节 | 关键结论 | 证据来源 |
|---|---|---|
| 1.2 鉴权 | Authorization 头 JWT 解析、越权文案 | [CODE:codes/zentao/src/main/java/com/sa/zentao/conf/JwtAuthenticationFilter.java:41-66] [CODE:ZtStoryExpandServiceImpl.java:41-45] [CODE:ZtTaskServiceImpl.java:1360-1364] [CODE:CommonsController.java:129-132] |
| 1.3 响应结构 | Result/Code 枚举值 | [CODE:codes/zentao/src/main/java/com/sa/zentao/dao/Result.java] [CODE:codes/zentao/src/main/java/com/sa/zentao/dao/Code.java] [CODE:conf/GlobalExceptionHandler.java:28-32] |
| 3. 接口1 | 字段集/upsert/finished 守卫与结算 | [CODE:entity/ZtStoryExpand.java] [CODE:ZtStoryExpandServiceImpl.java:40-79,120-150] |
| 4. 接口2 | 字段/整批拒绝/防重/留痕形状 | [CODE:dao/ZtTaskAiBatchDTO.java] [CODE:ZtTaskServiceImpl.java:1357-1470] |
| 5. 接口3 | 白名单映射/事务顺序/落库字段 | [CODE:CommonsController.java:120-187] [CODE:ZtFileServiceImpl.java:74-154] [CODE:enums/FileTypes.java] [CODE:dao/UploadDTO.java] |
| 1.1/运行实证 | 8085 默认地址、token 自动携带、中文标题正确 | [RUNTIME:dev_log CHG-061 闭环记录] [RUNTIME:summary.md 2026-08-06] |
## 8. 假设与缺口
| 项 | 状态 | 说明 |
|---|---|---|
| 生产 Base URL | ⚠️ [ASSUMPTION] | 8015 端口见于 dev_log CHG-070;生产主机/域名以部署实为准,发布时确认 |
| `evaluationTime` 单位 | ✅ 已确认 | 人日(demand-assessor W 定义,summary 附录口径一致) |
| `deadlineTime` 精度 | ✅ 已验证 | 秒级时间戳(ZtTaskServiceImpl.java:1425) |
| ai 永久 token 过期策略 | ✅ 已确认 | 永久 token(CHG-061 决策,存 `.claude/ai_token.txt`) |
---
> 下一步(Check):本文档与 `outputs/dev_plan.md`、`06_test_docs/test_cases.md` §0 环境约定一致;如发现不一致以运行代码为准修正本文档(Runtime 事实优先)。