feat: 根目录文档、脚本、gitignore
This commit is contained in:
@@ -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 事实优先)。
|
||||
Reference in New Issue
Block a user