mirror of
https://github.com/motajs/template.git
synced 2026-10-19 05:10:16 +08:00
docs(07-15): revise plan per checker feedback (collection type scope, tracking sync ownership)
This commit is contained in:
parent
495bf34b2f
commit
7b18784995
@ -33,10 +33,10 @@ must_haves:
|
||||
- "**WR-03 的外部可观测后果(克隆属性的可序列化面变化)**:`cloned.iterateModifiers()` 能列出全部克隆修饰器、`cloned.getModifierIndex(克隆修饰器)` 返回非负、克隆修饰器 `setValue(...)` 经 `owner` 通知克隆重算 `getFinalAttribute`、`cloned.saveState(...)` 的 `modifiers` 不再为空数组——修复前这四处全为退化行为(空遍历、-1、final 陈旧、`modifiers: []`)"
|
||||
- "本计划为修复计划(D-10 的授权例外 A1):4 条缺陷各有**正确预期**回归用例(共新增 5 条 `it`),每条在修复前失败、修复后通过;**既有断言一字不改**、不新增 `it.skip`、不删除既有用例、不为转绿弱化断言"
|
||||
- "`pnpm test:ci` 0 失败、跳过项仍恰为 1 条(`packages-user/data-base/src/hero/equipment.test.ts` 的码 147 用例,D-06);本计划不新增测试文件,故文件数不变、通过数按新增用例数上升(基线须在执行时重录,见 objective 的基线段)"
|
||||
- "四条缺陷各一次原子提交(D-13),提交一律按显式路径 `git add <file>`;本计划 `files_modified` 之外的任何工作树改动(含既有未暂存修改/删除与未跟踪文件)一律不触碰、不暂存、不提交"
|
||||
- "四条缺陷各一次原子提交(D-13),提交一律按显式路径 `git add <file>`;本计划**声明路径**(`files_modified` 的 6 个文件 + 本计划的 `07-15-SUMMARY.md`)之外的任何工作树改动(含既有未暂存修改/删除、未跟踪文件,以及 `.planning/ROADMAP.md`/`.planning/STATE.md`——后者的跟踪同步为 orchestrator 收尾步骤)一律不触碰、不暂存、不提交"
|
||||
artifacts:
|
||||
- path: packages-user/data-base/src/hero/equipment.ts
|
||||
provides: "`compareEquip`(`:255-331`)按 Q1=A 改为「克隆加入 / 按同一批克隆删除」:新增局部数组收集 `[name, copy]`,加入端 `const copy = modifier.clone()` 后 `clone.addModifier(name, copy)`,删除端遍历该数组 `clone.deleteModifier(name, copy)`;现役槽位删除块(`:274-290`)与方法返回值、146 早退分支、`:319` 注释零改动"
|
||||
provides: "`compareEquip`(`:255-331`)按 Q1=A 改为「克隆加入 / 按同一批克隆删除」:新增局部数组收集 `[name, copy]`(元素类型取自 `stateA.getModifiers()` 的自身元素类型,故零新增 import、不出现 `IHeroModifier` 类型名),加入端 `const copy = modifier.clone()` 后 `clone.addModifier(name, copy)`,删除端遍历该数组 `clone.deleteModifier(name, copy)`;现役槽位删除块(`:274-290`)与方法返回值、146 早退分支、`:319` 注释零改动"
|
||||
- path: packages-user/data-base/src/hero/equipment.test.ts
|
||||
provides: "CR-01 回归 1 条(现役装备参与比较的两个方向 + 无 108 见证 + 活属性原修饰器未被解绑)+ `:1` 文件头覆盖说明的追加同步"
|
||||
- path: packages-user/data-common/src/replay/array.ts
|
||||
@ -73,7 +73,7 @@ must_haves:
|
||||
- "不得触碰 `packages-user/data-common/src/replay/system.ts`、`packages-user/data-base/src/flag/**`、`packages-user/data-system/src/combat/mapDamage.ts`(用户的 IN-01..IN-04 修复已提交)"
|
||||
- "不得新增依赖、不得改 `package.json`/`pnpm-lock.yaml`;不得新建源码或测试文件(本计划零新增文件,只在既有 6 个文件内改动);不得使用 `try-catch-finally`(dev.md:121)"
|
||||
- "不得使用连续 `as` 断言(`as unknown as …`)、不得新增 `import type`、不得新增字符串特殊标识符、不得新增类/方法/字段/导出"
|
||||
- "不得暂存或提交 `files_modified` 之外的任何路径(含工作树中已存在的无关未暂存修改/删除与未跟踪文件):提交一律 `git add <显式路径>`;禁止 `git add -A`/`git add -a`、`git stash`、`git clean`、`git reset --hard`"
|
||||
- "不得暂存或提交本计划**声明路径**之外的任何路径(声明路径 = `files_modified` 的 6 个文件 + 本计划的 `07-15-SUMMARY.md`;`.planning/ROADMAP.md` 与 `.planning/STATE.md` 由 orchestrator 在本计划收尾后同步,本计划零编辑/零暂存/零提交);工作树中已存在的无关未暂存修改/删除与未跟踪文件同样不得被暂存或提交:提交一律 `git add <显式路径>`;禁止 `git add -A`/`git add -a`、`git stash`、`git clean`、`git reset --hard`"
|
||||
- "Task 0 的 `<record>` 为空时**不得**进行任何文件修改(未裁决即停);执行期若发现与裁决冲突,暂停并请用户澄清,不得自行改用任何【未选】分支或另辟他法(D-09)"
|
||||
---
|
||||
|
||||
@ -116,7 +116,7 @@ Phase 7 裁决对应(逐条引用):D-01: 本计划是 Phase 7 第 15 个
|
||||
|
||||
执行序:`depends_on: []`(Wave 15)。四条修复源码层面互不耦合(hero 侧两条、replay 侧两条),但不并波执行:本计划 `autonomous: false`,Task 0 是 D-09 的逐计划裁决关卡,且四条各自需要「文件级门禁 + 原子提交 + `pnpm test:ci` 基线核对」,与 07-13/07-14 同一节奏。
|
||||
|
||||
**隔离要求(执行前必读)**:用户正在本仓库并行工作,且工作树的改动集合在规划与执行之间会继续变化,故**不以任何固定清单为准**。**通用规则(唯一判据)**:凡是**不在**本计划 `files_modified` 六个路径内的改动,一律不触碰、不暂存、不提交;每次提交前后用 `git status --short` 核对暂存区只含本计划当次声明的文件;用户自己的改动(例如 `packages/common/src/logger.json`、`packages-user/data-*/**`、`.planning/milestone.lock` 等)无论内容如何都属用户所有,本计划只读不写,且**不得**以「工作树中某文件有改动」为由判定本计划越界——越界判定一律只看 `git diff BASE_SHA..HEAD -- <该路径>` 是否为空。计划期(2026-09-17 规划会话)最后一次观察到的无关改动为:`packages-user/data-common/src/types.ts`、`packages-user/data-system/src/path/finder.ts`、`packages-user/data-system/src/path/graph.ts`、`packages-user/data-system/src/path/graph.test.ts`、`packages-user/data-system/src/path/performance.test.ts`、`packages-user/data-system/src/path/types.ts`、`packages/common/src/logger.json`(均为修改),以及未跟踪的 `.planning/milestone.lock`——**仅作参考**,执行时以 `git status --short` 为准。
|
||||
**隔离要求(执行前必读)**:用户正在本仓库并行工作,且工作树的改动集合在规划与执行之间会继续变化,故**不以任何固定清单为准**。**通用规则(唯一判据)**:凡是**不在**本计划声明路径内的改动,一律不触碰、不暂存、不提交(声明路径 = `files_modified` 六个源/测试文件 + 本计划的 `07-15-SUMMARY.md`;`.planning/ROADMAP.md`/`.planning/STATE.md` 的跟踪同步属 orchestrator 的收尾步骤,不计入本计划的改动面);每次提交前后用 `git status --short` 核对暂存区只含本计划当次声明的文件;用户自己的改动(例如 `packages/common/src/logger.json`、`packages-user/data-*/**`、`.planning/milestone.lock` 等)无论内容如何都属用户所有,本计划只读不写,且**不得**以「工作树中某文件有改动」为由判定本计划越界——越界判定一律只看 `git diff BASE_SHA..HEAD -- <该路径>` 是否为空。计划期(2026-09-17 规划会话)最后一次观察到的无关改动为:`packages-user/data-common/src/types.ts`、`packages-user/data-system/src/path/finder.ts`、`packages-user/data-system/src/path/graph.ts`、`packages-user/data-system/src/path/graph.test.ts`、`packages-user/data-system/src/path/performance.test.ts`、`packages-user/data-system/src/path/types.ts`、`packages/common/src/logger.json`(均为修改),以及未跟踪的 `.planning/milestone.lock`——**仅作参考**,执行时以 `git status --short` 为准。
|
||||
|
||||
**基线(计划期记录,未经本次规划运行复测)**:`pnpm test:ci` = 66 文件 / 737 通过 / 0 失败 / 1 跳过;唯一跳过项是 `packages-user/data-base/src/hero/equipment.test.ts` 的码 147 用例(设计如此,D-06)。**执行前必须重录当日基线**并与本行对比:若文件数或跳过项与 737/1 的口径不符,先查明原因(本计划不新增文件、只新增用例,故文件数应不变、跳过数应仍为 1),基线异常即按 D-09 退出汇报。本计划新增 5 条 `it`,故通过数应 = 当日基线通过数 + 5,失败数必须为 0。
|
||||
</objective>
|
||||
@ -252,7 +252,7 @@ Phase 7 裁决对应(逐条引用):D-01: 本计划是 Phase 7 第 15 个
|
||||
空 —— **尚未裁决**。本块为空表示「未裁决:停止」。执行者在收到用户逐条裁决前**不得**修改任何文件、**不得**按任何【建议默认】或【未选】分支推进;裁决取得后由计划修订把 Q1..Q4 的结论(含每条选定的分支与由此产生的对外可观测后果)逐条写入本块,然后重新执行 Task 1..5。
|
||||
</record>
|
||||
<resume-signal>逐条给出 Q1..Q4 的裁决(例如「Q1=A, Q2=A, Q3=A, Q4=A」);若要修订方案,回复修订点,执行者退出并按 D-09 修订本 PLAN.md 后重新执行</resume-signal>
|
||||
<action>向用户汇报四处口径,逐条讲清取舍与**对外可观测后果**:Q1(CR-01)A 分支在比较克隆上克隆加入/克隆删除、活属性零扰动,B 分支会制造「修饰器暂时未绑定」的窗口且本仓库禁用 try-catch 无法兜底,C 分支等于把一个会算错差值的公开 API 留成调用约定,并给出实算对照(现役剑场景下 `-12` vs 契约要求的 `-7`);Q2(WR-01)A 分支丢弃该参数(命令参数计数、`get(i).params` 个数与后续字节偏移同时变化,与 bigint 溢出路径同口径),B 分支保留 2 字节占位并必须改写两处既有 jsDoc/注释;Q3(WR-02)A 分支把乘数 1 从「静默接受(随后栈溢出)」改为「告警 149 并回退为 2」(收紧被接受的配置范围,已核查无既有配置/用例受影响),B 分支保留乘数 1 但改为严格增大并顺带封口其它退化配置,代价是码 149 文案与实现永久不一致;Q4(WR-03)A 分支恢复四处簿记,后果是**克隆属性 `saveState()` 的 `modifiers` 不再为空**、克隆修饰器可遍历可定位且 `setValue` 能通知克隆重算,B 分支不继承存档开关(源上不入档的修饰器在克隆上会变回可存档),C 分支会破坏 `cloneModifier` 的既有语义与既有用例。同时转述 context 中标注为「未确认、不登记」的观察(乘数恰为 1 之外的退化配置),请用户决定是否在 Q3 选 B 一并封口。**不得在裁决前修改任何文件**;不得自行采纳任何建议默认值。另按 AGENTS.md 的命名要求一并提请批准:本计划**不新增任何公共/受保护/私有方法或字段**(生产代码零新增符号),只新增两个方法内局部变量名 `copy`(被比较修饰器的克隆副本)与 `addedA`(A 的克隆收集数组,见 Task 1),以及 5 条新用例的英文标题(见 objective 的「Artifacts this phase produces」);若用户对任一命名有异议,先修订本计划再执行。</action>
|
||||
<action>向用户汇报四处口径,逐条讲清取舍与**对外可观测后果**:Q1(CR-01)A 分支在比较克隆上克隆加入/克隆删除、活属性零扰动,B 分支会制造「修饰器暂时未绑定」的窗口且本仓库禁用 try-catch 无法兜底,C 分支等于把一个会算错差值的公开 API 留成调用约定,并给出实算对照(现役剑场景下 `-12` vs 契约要求的 `-7`);Q2(WR-01)A 分支丢弃该参数(命令参数计数、`get(i).params` 个数与后续字节偏移同时变化,与 bigint 溢出路径同口径),B 分支保留 2 字节占位并必须改写两处既有 jsDoc/注释;Q3(WR-02)A 分支把乘数 1 从「静默接受(随后栈溢出)」改为「告警 149 并回退为 2」(收紧被接受的配置范围,已核查无既有配置/用例受影响),B 分支保留乘数 1 但改为严格增大并顺带封口其它退化配置,代价是码 149 文案与实现永久不一致;Q4(WR-03)A 分支恢复四处簿记,后果是**克隆属性 `saveState()` 的 `modifiers` 不再为空**、克隆修饰器可遍历可定位且 `setValue` 能通知克隆重算,B 分支不继承存档开关(源上不入档的修饰器在克隆上会变回可存档),C 分支会破坏 `cloneModifier` 的既有语义与既有用例。同时转述 context 中标注为「未确认、不登记」的观察(乘数恰为 1 之外的退化配置),请用户决定是否在 Q3 选 B 一并封口。**不得在裁决前修改任何文件**;不得自行采纳任何建议默认值。另按 AGENTS.md 的命名要求一并提请批准:本计划**不新增任何公共/受保护/私有方法或字段**(生产代码零新增符号),只新增三个方法内局部变量名 `copy`(被比较修饰器的克隆副本)、`addedA`(A 的克隆收集数组)与 `modifiersA`(`[...stateA.getModifiers()]` 的展开副本,用于让 `addedA` 取得与源迭代器同型的元素类型,见 Task 1),以及 5 条新用例的英文标题(见 objective 的「Artifacts this phase produces」);若用户对任一命名有异议,先修订本计划再执行。</action>
|
||||
<verify>
|
||||
<human-check>`<record>` 中 Q1..Q4 均有用户明确裁决(含 Q2 对参数计数/字节布局的影响、Q3 对可接受配置范围的影响、Q4 对克隆属性序列化内容的影响均已被告知并确认),且与用户实际意图一致</human-check>
|
||||
<fails_when>`<record>` 仍为空(未裁决)—— 必须停在 Task 0、不得修改任何文件;或记录与用户实际意图不符 —— 必须暂停并请用户澄清,不得按「建议默认」或任何【未选】分支自行推进</fails_when>
|
||||
@ -262,7 +262,7 @@ Phase 7 裁决对应(逐条引用):D-01: 本计划是 Phase 7 第 15 个
|
||||
- 每条裁决都写明选定的分支与其对外可观测后果(Q2 的参数计数/字节偏移、Q3 的可接受配置范围、Q4 的克隆属性序列化内容),Q1 的裁决不得是「不改行为只写文档」以外的含糊表述
|
||||
- `<record>` 非空之前,工作树中本计划的 6 个目标文件**零改动**(可用 `git status --short` 核对这 6 个路径无新增改动)
|
||||
- context 中标注「未确认、不登记」的观察已如实转述给用户,且未在计划任何位置登记为新缺陷
|
||||
- 命名已按 AGENTS.md 提请批准:确认本计划不新增任何方法/字段,且局部变量名 `copy`/`addedA` 与 5 条新用例标题已获用户同意(或已按用户意见改写本计划)
|
||||
- 命名已按 AGENTS.md 提请批准:确认本计划不新增任何方法/字段,且局部变量名 `copy`/`addedA`/`modifiersA` 与 5 条新用例标题已获用户同意(或已按用户意见改写本计划)
|
||||
</acceptance_criteria>
|
||||
<done>Q1..Q4 的用户裁决(含每条的可观测后果)已完整写入 `<record>`;执行者据记录进入 Task 1,不再重复询问</done>
|
||||
</task>
|
||||
@ -274,15 +274,15 @@ Phase 7 裁决对应(逐条引用):D-01: 本计划是 Phase 7 第 15 个
|
||||
- packages-user/data-base/src/hero/equipment.ts(:74-86 `loadEquipEffect` 用 `addModifier(name, modifier, false)` 把装备修饰器绑定到活属性、:92-97 `unloadEquipEffect`、:255-331 `compareEquip` 全方法,尤其 :271 的比较克隆、:274-290 现役删除块、:297-308 A 的加入-采样-删除三段、:310-317 B 的加入-采样两段、:319 的既有注释)
|
||||
- packages-user/data-base/src/hero/attribute.ts(:190-211 `addModifier` 的 `if (modifier.owner)` 拒绝分支与告警 108、:213-228 `deleteModifier` 的 `indexOf` 定位与解绑、:169-188 `iterateModifiers`/`getModifierIndex`)
|
||||
- packages-user/data-base/src/hero/equipStore.ts(:43-61 `rebuildModifiers` 与 `getModifiers` 返回修饰器对象本身——证明加入克隆的正是活属性上那一批对象)
|
||||
- packages-user/data-base/src/hero/equipStore.ts(:57-61 `getModifiers` 的返回类型 `Iterable<[keyof SelectType<THero, number>, IHeroModifier<number>]>`,用于确定新增局部数组的元素类型)
|
||||
- packages-user/data-base/src/hero/types.ts(:671-674 `IEquipmentState.getModifiers(): Iterable<[SelectKey<THero, number>, IHeroModifier<number>]>` 与 :710-714 `IHeroEquipsStore.get(uid): IEquipmentState<THero> | null`——`stateA.getModifiers()` 的静态元素类型即新增收集数组的元素类型来源;**`equipment.ts:3-10` 的 `./types` 具名引入不含 `IHeroModifier`**,该类型在本文件不在作用域内,而本计划禁止新增引入,故收集数组一律以「源迭代器自身类型」标注、不写类型名)
|
||||
- packages-user/data-base/src/hero/types.ts(:824-834 `compareEquip` 的契约「输出装备 A 时的属性减装备 B 时的属性」;:199-231 `addModifier`/`deleteModifier`/`deleteModifierByIndex` 的声明)
|
||||
- packages-user/data-base/src/hero/equipment.test.ts(:1 文件头覆盖说明、:102-177 `createEnv`/`registerItem` 夹具、:417-467 既有两条 `compareEquip` 用例——修复后必须逐字保留且数值不变)
|
||||
- .planning/phases/07-data-fixes/07-REVIEW-recheck.md(CR-01 `:74-121`,含实算轨迹与建议修法)
|
||||
</read_first>
|
||||
<action>
|
||||
按 Task 0 `<record>` 的 Q1=A 落地(**无分支、无「建议默认」**)。本任务只改 `compareEquip` 的方法体内部,不改方法签名、返回值类型、146 早退分支与现役删除块。
|
||||
(1) **A 的加入端(`:297-300`)**:在循环前新增收集数组 `const addedA: [SelectKey<THero, number>, IHeroModifier<number>][] = [];`(`SelectKey` 在本文件已用于 `:295`,为全局类型;元素类型须与 `stateA.getModifiers()` 迭代出的元组一致,**不得**用 `any`)。循环体改为三行:`const copy = modifier.clone();` → 保留原有那一行 `// @ts-expect-error 泛型无法推导` 注释**逐字不动**(它仍对应下一行的类型错误) → `clone.addModifier(name, copy);` → `addedA.push([name, copy]);`。原 `modifier` 变量仍用于 `clone()`,不得被加入比较克隆。
|
||||
(2) **A 的删除端(`:305-308`)**:把「再次遍历 `stateA.getModifiers()` 并 `clone.deleteModifier(name, modifier)`」改为「遍历 `addedA` 并 `clone.deleteModifier(name, copy)`」;同样保留该处原有的 `// @ts-expect-error 泛型无法推导` 注释逐字不动。删除目标必须是**上一步加入的那个克隆对象**(`deleteModifier` 以 `indexOf` 定位,同一对象即可命中)。
|
||||
(1) **A 的加入端(`:297-300`)**:在循环前新增两行——`const modifiersA = [...stateA.getModifiers()];` 与 `const addedA: typeof modifiersA = [];`(收集数组的元素类型**取自源迭代器自身**,即 `IEquipmentState<THero>.getModifiers()` 的 `Iterable<[SelectKey<THero, number>, IHeroModifier<number>]>`,见 `hero/types.ts:671-674`)。**不得**把元素类型写成显式元组标注:`IHeroModifier` 在本文件**不在作用域内**(`equipment.ts:3-10` 的 `./types` 具名引入只绑定 `EquipStatus`/`IEquipmentState`/`IHeroAttribute`/`IHeroEquipment`/`IHeroEquipmentSave`/`IHeroEquipsStore`;只有 `SelectKey`/`SelectType` 是 `src/types/declaration/util.d.ts:917-924` 的全局环境类型),而本计划(A2 与 prohibitions)禁止新增引入,故**不写类型名、不新增 import、不用 `any`/`as`/`as const`**。循环体改为三行并遍历 `modifiersA`:`const copy = modifier.clone();` → 保留原有那一行 `// @ts-expect-error 泛型无法推导` 注释**逐字不动**(`copy` 的静态类型与今天的 `modifier` 完全相同——`clone()` 的签名是 `clone(): IHeroModifier<H, V>`、`H`/`V` 均取自 `modifier` 自身类型,该注释仍对应同一处类型错误) → `clone.addModifier(name, copy);` → `addedA.push([name, copy]);`。原 `modifier` 变量仍用于 `clone()`,不得被加入比较克隆。
|
||||
(2) **A 的删除端(`:305-308`)**:把「再次遍历 `stateA.getModifiers()` 并 `clone.deleteModifier(name, modifier)`」改为「遍历 `addedA` 并 `clone.deleteModifier(name, copy)`」;同样保留该处原有的 `// @ts-expect-error 泛型无法推导` 注释逐字不动(`copy` 与今天的 `modifier` 静态类型相同,故该注释仍是必要的)。删除目标必须是**上一步加入的那个克隆对象**(`deleteModifier` 以 `indexOf` 定位,同一对象即可命中)。
|
||||
(3) **A 的采样端(`:301-304`)逐字不改**:仍遍历 `stateA.getModifiers()` 的键名并对每个键取 `clone.getFinalAttribute(name)`、写入 `keys`。
|
||||
(4) **B(`:310-317`)只改加入端**:循环体同样先 `const copy = modifier.clone();` 再 `clone.addModifier(name, copy);`(保留该处既有的 `// @ts-expect-error 泛型无法推导` 注释逐字不动);**B 不做删除**——`:319` 的既有注释「第二次没必要再删除了,因为这个 clone 对象不会再被使用到」逐字保留,B 也不新增收集数组。
|
||||
(5) **逐字保留的部分**:`:255-269` 的两个 146 早退分支、`:271` 的 `this.attribute.clone()`、`:273-290` 的现役删除块(`this.attribute.getModifierIndex(modifier)` + `clone.getModifiers(name)[index]` + 跳过负索引与空对象的两个 `continue`,以及其 `:282-285` 注释)、`:322-330` 的差值收集与 `?? final` 回退。
|
||||
@ -299,10 +299,11 @@ Phase 7 裁决对应(逐条引用):D-01: 本计划是 Phase 7 第 15 个
|
||||
</action>
|
||||
<verify>
|
||||
<automated>pnpm exec vitest run packages-user/data-base/src/hero/equipment.test.ts packages-user/data-base/src/hero/state.test.ts</automated>
|
||||
<fails_when>现役装备参与比较时 `compareEquip(sword, axe, 0).atk` 不等于 -7(或对称方向不等于 7);或比较过程仍产生告警 108;或活属性上原修饰器的索引变为负 / 活属性 final 数值被改变;或既有 `diffs the final attributes of two equipment instances`、`keeps foreign modifiers when the equipped instance was rebuilt`、两条码 146 用例与 `state.test.ts` 出现回归 —— 按 D-09 退出并修订计划,不得改用「临时解绑活属性修饰器」「比较前先卸下现役装备」「只写文档」等未选分支</fails_when>
|
||||
<fails_when>现役装备参与比较时 `compareEquip(sword, axe, 0).atk` 不等于 -7(或对称方向不等于 7);或比较过程仍产生告警 108;或活属性上原修饰器的索引变为负 / 活属性 final 数值被改变;或 `pnpm exec vue-tsc --noEmit` 输出含本文件路径(收集数组的元素类型必须由 `stateA.getModifiers()` 推导,不得出现作用域外的类型名或新增 import);或既有 `diffs the final attributes of two equipment instances`、`keeps foreign modifiers when the equipped instance was rebuilt`、两条码 146 用例与 `state.test.ts` 出现回归 —— 按 D-09 退出并修订计划,不得改用「临时解绑活属性修饰器」「比较前先卸下现役装备」「只写文档」等未选分支</fails_when>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- `compareEquip` 加入端对每个被比较修饰器先 `clone()` 再加入(A 与 B 两处),A 的删除端遍历收集数组删除**同一批克隆对象**;`stateA`/`stateB` 的原修饰器对象从未被加入比较克隆、从未被 `bindAttribute(null)`
|
||||
- 收集数组的元素类型取自 `stateA.getModifiers()`(`const addedA: typeof modifiersA = []`),**未新增任何 import**、未出现类型名 `IHeroModifier`、未使用 `any`/`as`/`as const`/类型别名或接口;`vue-tsc --noEmit` 对本文件 0 命中(Task 5 门槛 (b) 必须在此前即为真,不得推迟到 Task 5 才暴露)
|
||||
- 两处既有的 `// @ts-expect-error 泛型无法推导` 注释行、`:282-285` 的现役删除块注释、`:319` 的「第二次没必要再删除」注释、两个 146 早退分支、`:322-330` 的差值回退逻辑逐字保留
|
||||
- 新增用例断言双向差值(`-7` 与 `+7`)、键集合、不含 108、活属性修饰器索引仍非负且 final 仍为 22
|
||||
- `equipment.test.ts:1` 的文件头覆盖说明为**追加**(既有文字一字未改);既有用例全部保持通过;无新增 `it.skip`
|
||||
@ -439,7 +440,7 @@ Phase 7 裁决对应(逐条引用):D-01: 本计划是 Phase 7 第 15 个
|
||||
- .planning/phases/07-data-fixes/07-REVIEW-recheck.md(CR-01 `:74-121`、WR-01 `:125-144`、WR-02 `:146-157`、WR-03 `:159-183` 的编号与标题)
|
||||
- .planning/phases/07-data-fixes/07-VERIFICATION.md(头部 `_Verified: 2026-09-17T10:42:49Z_`、`### Review-Recheck Gaps` `:335-363`、`## Recommended Fix Plans` `:365-378`)
|
||||
- .planning/phases/07-data-fixes/07-SECURITY.md(本阶段的威胁登记口径与 T-7-xx 编号现状:已用到 T-7-47)
|
||||
- .planning/ROADMAP.md(Phase 7 段的 Plans 列表与 Wave 分组——本计划只做**追加**:计划行与 Wave 15 段)
|
||||
- .planning/ROADMAP.md(Phase 7 段的 Plans 列表与 Wave 分组——**只读参照**:确认 Phase 7 的既有计划行与 Wave 段的现有形态,供 SUMMARY 写明「跟踪同步待 orchestrator 定点追加」的对照;本计划**不编辑**该文件)
|
||||
- .planning/WINDOWS.md(确认这 4 条评审发现**没有**账本条目;本计划不新建、不 `fixed`/`waive`)
|
||||
- .planning/codebase/TESTING.md(`pnpm test:ci` 口径、`logger.catch` 断言写法、无覆盖率工具)
|
||||
- .planning/phases/07-data-fixes/07-14-PLAN.md 的 Task 2(门禁/基线/SUMMARY 的既有写法参照)
|
||||
@ -448,25 +449,25 @@ Phase 7 裁决对应(逐条引用):D-01: 本计划是 Phase 7 第 15 个
|
||||
(1) **门禁(D-12 / D-44,文件级三步)**:对 `files_modified` 的 6 个文件执行——(a) `pnpm exec eslint --fix <6 个文件>` 后 `pnpm exec eslint <6 个文件>` **0 错误**(CRLF 与 Prettier 由 `--fix` 处理,不手工调换行);(b) **文件级类型门禁按 06-RESEARCH Pitfall 4 的判定方式**:`pnpm exec vue-tsc --noEmit 2>&1 | Select-String -Pattern "<改动文件相对路径>"` **无命中**(逐个文件过滤;**不得**用「退出码非 0」判定失败,仓库存在既有渲染/legacy 类型错误,不属本阶段);(c) `pnpm test:ci` **0 失败**、跳过项仍**恰为 1 条**(`packages-user/data-base/src/hero/equipment.test.ts` 的码 147 用例,D-06)。
|
||||
(2) **基线与增量核对**:执行前先重录当日基线;与本计划 objective 记录的参照(**计划期记录、未经本次规划运行复测**:66 文件 / 737 通过 / 0 失败 / 1 跳过)对比。本计划**不新增文件**,故文件数应不变(66);新增 5 条 `it`,故通过数应 = 当日基线通过数 + 5;失败数必须为 0;跳过数必须仍为 1。任何偏离先查明原因并按 D-09 退出汇报,**不得**通过删改用例或放宽断言来对齐数字。
|
||||
(3) **原子提交(D-13,按缺陷四条)**:Task 1 = `fix(07-15): compare equipment without rebinding the equipped modifiers`;Task 2 = `fix(07-15): drop unencodable replay params instead of a zero-length record`;Task 3 = `fix(07-15): reject an expand multiplier of exactly one`;Task 4 = `fix(07-15): restore modifier bookkeeping when cloning an attribute`。提交**一律按显式路径** `git add <显式路径>`;**禁止** `git add -A`/`git add -a`、`git stash`、`git clean`、`git reset --hard`。每次提交前后用 `git status --short` 核对暂存区只含本计划当次声明的文件。
|
||||
(4) **范围隔离核对(必做)**:用显式路径区间对比本计划起点 sha..HEAD——`git diff <BASE_SHA>..HEAD --stat -- packages-user/data-base/src/hero/equipment.ts packages-user/data-base/src/hero/equipment.test.ts packages-user/data-common/src/replay/array.ts packages-user/data-common/src/replay/array.test.ts packages-user/data-base/src/hero/attribute.ts packages-user/data-base/src/hero/attribute.test.ts`(`BASE_SHA` = 本计划开始执行时的 HEAD 显式 sha),并另跑一次不带路径的 `git diff <BASE_SHA>..HEAD --stat` 确认**没有**本计划之外的文件进入提交(工作树中既有的无关未暂存修改/删除与未跟踪文件不得被暂存或提交)。同时核对:未新建任何源码/测试文件、未改 `package.json`/`pnpm-lock.yaml`、未改 `hero/types.ts` 与 `replay/types.ts`、未改 `replay/system.ts`/`flag/**`/`combat/mapDamage.ts`、未新增/修改告警码;`packages/common/src/logger.json` 在 `git diff BASE_SHA..HEAD -- packages/common/src/logger.json` 下为空(即本计划未改动它——该文件已由用户自行修改,**不得**以工作树存在改动判定越界)。
|
||||
(4) **范围隔离核对(必做)**:本计划的**声明路径集合** = `files_modified` 的 6 个源/测试文件 + 本计划的产出物 `.planning/phases/07-data-fixes/07-15-SUMMARY.md`(按本阶段 07-12/07-13 先例,frontmatter `files_modified` 只列源/测试文件,SUMMARY 由本 Task 的 `<files>` 声明)。用显式路径区间对比本计划起点 sha..HEAD——`git diff <BASE_SHA>..HEAD --stat -- <上述 7 条路径>`(`BASE_SHA` = 本计划开始执行时的 HEAD 显式 sha),并另跑一次不带路径的 `git diff <BASE_SHA>..HEAD --stat`,断言**区间内出现的文件全部落在这 7 条声明路径内**:Phase 7 的跟踪同步(`.planning/ROADMAP.md`、`.planning/STATE.md`)由 orchestrator 在本计划收尾后**单独提交**(见 (7)),不在本计划的提交区间内;工作树中既有的无关未暂存修改/删除与未跟踪文件不得被暂存或提交。若区间内出现第 8 条路径,按 D-09 退出汇报。同时核对:未新建任何源码/测试文件、未改 `package.json`/`pnpm-lock.yaml`、未改 `hero/types.ts` 与 `replay/types.ts`、未改 `replay/system.ts`/`flag/**`/`combat/mapDamage.ts`、未新增/修改告警码;`packages/common/src/logger.json` 在 `git diff BASE_SHA..HEAD -- packages/common/src/logger.json` 下为空(即本计划未改动它——该文件已由用户自行修改,**不得**以工作树存在改动判定越界)。
|
||||
(5) **注释门槛核对(必做)**:对本计划 6 个文件的 diff 逐行确认——除「各测试文件 `:1` 文件头覆盖说明的**追加**」与「新增用例 `it` 前的单行中文注释」外,**没有任何** jsDoc/注释行被修改或删除;实现确需说明非显然「为什么」时只允许**新增**单行注释(dev.md:84)。核对结论写入 SUMMARY 的对照表。
|
||||
(6) **评审映射登记(SUMMARY 逐条,D-14)**:登记「`07-REVIEW-recheck.md` 发现 ID → 缺陷 → 修复提交 → 选定的裁决分支」,四条分别为 CR-01(Q1 分支)/ WR-01(Q2 分支)/ WR-02(Q3 分支)/ WR-03(Q4 分支);如实登记本计划对 `07-VERIFICATION.md` `### Review-Recheck Gaps` 四条的实际闭合状态。**`WINDOWS.md` 不新建条目、不做 `fixed`/`waive`**(这 4 条本来就没有账本条目)。SUMMARY 另须写明:A6 的既有 `compareEquip` 两条用例数值复算结果;A10 的 `clone()` 前提与其守卫断言;WR-02 的全仓影响面复核结论(149 仅两处写入点、测试仅 `:1030` 一条断言、乘数赋值点仅 1.2 与 2);WR-03 造成的**对外可观测序列化面变化**(克隆属性 `saveState().modifiers` 由空数组变为真实列表,属预期正确化);以及 A8 的 `FIX-01` 探针未决假设(specless 探针只给出 `unclassified — review manually`,本计划不以其判定结果替代人工确认,该未决状态保留在册)。
|
||||
(7) **Phase 7 验证失效与 ROADMAP 追加**:SUMMARY 明写 `07-VERIFICATION.md`(`_Verified: 2026-09-17T10:42:49Z_`)已被本批改动与更早的 07-09..07-14 失效,本计划执行完毕后**必须重跑 `/gsd-verify-work`(或 `gsd-verify-work 7`)**重新出具验证结论;`ROADMAP.md` 的 Phase 7 段以 **Edit 定点追加**方式同步(Plans 计数 + 新增 `07-15-PLAN.md` 计划行 + Wave 15 段),**不得**重排、删除或改写任何既有计划行与既有说明段。`STATE.md` 的同步(若有)同样只做定点追加。
|
||||
(7) **Phase 7 验证失效与跟踪同步(orchestrator 负责,本计划不落笔)**:SUMMARY 明写 `07-VERIFICATION.md`(`_Verified: 2026-09-17T10:42:49Z_`)已被本批改动与更早的 07-09..07-14 失效,本计划执行完毕后**必须重跑 `/gsd-verify-work`(或 `gsd-verify-work 7`)**重新出具验证结论。`.planning/ROADMAP.md` 的 Phase 7 段(Plans 计数 + `07-15-PLAN.md` 计划行 + Wave 15 段)与 `.planning/STATE.md` 的同步是**本计划之外的 orchestrator 收尾步骤**——本阶段先例:07-10/07-11 的 SUMMARY 均明写「`ROADMAP.md` / `STATE.md` 未由本计划更新(orchestrator owns those)」,git 记录中该同步是独立的 `docs(phase-07): update tracking after plan …` 提交,07-12 的计划亦明写「本计划**不改** `ROADMAP.md` 文本」。故本计划**不编辑、不暂存、不提交** `.planning/ROADMAP.md` 与 `.planning/STATE.md`;SUMMARY 只承担以下声明:跟踪同步待 orchestrator 以**定点追加**方式完成(既有计划行与既有说明段不得被重排/删除/改写),本计划的提交区间内这两个路径为空。
|
||||
</action>
|
||||
<verify>
|
||||
<automated>pnpm test:ci</automated>
|
||||
<fails_when>`pnpm test:ci` 出现任何失败;或跳过数不等于 1(新增了 `it.skip`,或 D-06 的码 147 用例被取消 skip);或文件数与「本计划不新增文件」不符;或 `vue-tsc --noEmit` 输出含本计划 6 个文件的任一路径;或某个提交的暂存内容含本计划之外的文件(含工作树中既有的无关改动);或 6 个文件的 diff 中出现被修改/删除的既有 jsDoc/注释行 —— 按 D-09 退出并修订计划,不得通过删改用例、放宽断言或撤回已提交改动来对齐门禁</fails_when>
|
||||
<fails_when>`pnpm test:ci` 出现任何失败;或跳过数不等于 1(新增了 `it.skip`,或 D-06 的码 147 用例被取消 skip);或文件数与「本计划不新增文件」不符;或 `vue-tsc --noEmit` 输出含本计划 6 个文件的任一路径;或某个提交的暂存内容含本计划**声明路径**(6 个源/测试文件 + `07-15-SUMMARY.md`)之外的文件(含工作树中既有的无关改动);或本计划提交区间内 `.planning/ROADMAP.md`、`.planning/STATE.md` 出现改动(跟踪同步属 orchestrator 收尾步骤);或 6 个文件的 diff 中出现被修改/删除的既有 jsDoc/注释行 —— 按 D-09 退出并修订计划,不得通过删改用例、放宽断言或撤回已提交改动来对齐门禁</fails_when>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- 6 个文件 `eslint` 0 错误、`vue-tsc --noEmit` 按文件路径过滤 0 命中、`pnpm test:ci` 0 失败且跳过项恰为 1 条
|
||||
- 基线增量与预期一致(文件数不变;通过数 = 当日基线 + 5;失败 0;跳过 1),偏离已查明原因或已按 D-09 退出
|
||||
- Task 1..4 各有独立原子提交(`fix(07-15): …`),暂存内容只含本计划声明的文件;`git diff BASE_SHA..HEAD --stat` 不含本计划之外的文件
|
||||
- Task 1..4 各有独立原子提交(`fix(07-15): …`),暂存内容只含本计划声明的文件;`git diff BASE_SHA..HEAD --stat` 不含本计划声明路径(6 个源/测试文件 + `07-15-SUMMARY.md`)之外的文件,且 `.planning/ROADMAP.md`/`.planning/STATE.md` 在本计划提交区间内为空
|
||||
- 注释门槛核对通过:除文件头覆盖说明的追加与新增用例的单行注释外,无任何 jsDoc/既有注释改动
|
||||
- SUMMARY 含四条评审映射、Q1..Q4 裁决对照、A6/A10/WR-02 影响面/WR-03 序列化面变化、A8 探针未决假设,以及「`WINDOWS.md` 未新建条目、未 `fixed`/`waive`」的明写
|
||||
- SUMMARY 含 Phase 7 验证失效与重跑要求;`ROADMAP.md` 为定点追加(既有行未被重排/删除/改写)
|
||||
- SUMMARY 含 Phase 7 验证失效与重跑要求,并明写 `.planning/ROADMAP.md`/`.planning/STATE.md` 的跟踪同步为本计划之外的 orchestrator 收尾步骤(本计划对这两个路径零编辑、零暂存、零提交;既有计划行与说明段不得被重排/删除/改写)
|
||||
- 未新建源码/测试文件、未新增依赖、未新增告警码、本计划提交区间内 `logger.json` 无改动(按区间判定,不看工作树)
|
||||
</acceptance_criteria>
|
||||
<done>D-44 三步门禁全绿、基线增量与预期一致、四条缺陷按缺陷原子提交且未牵连任何无关改动、评审映射与 Phase 7 验证失效说明写入 `07-15-SUMMARY.md`,`ROADMAP.md` 定点追加完成</done>
|
||||
<done>D-44 三步门禁全绿、基线增量与预期一致、四条缺陷按缺陷原子提交且未牵连任何无关改动、评审映射与 Phase 7 验证失效说明写入 `07-15-SUMMARY.md`;`.planning/ROADMAP.md`/`.planning/STATE.md` 的跟踪同步作为 orchestrator 的收尾步骤在 SUMMARY 中明写,本计划零触碰</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
@ -500,10 +501,10 @@ Phase 7 裁决对应(逐条引用):D-01: 本计划是 Phase 7 第 15 个
|
||||
2. `pnpm test:ci` **0 失败**、跳过项**恰为 1 条**(`packages-user/data-base/src/hero/equipment.test.ts` 码 147,D-06);文件数不变(本计划不新增文件),通过数 = 当日基线通过数 + 5,基线偏离已查明原因或已按 D-09 退出。
|
||||
3. `pnpm exec eslint` 对本计划 6 个文件 0 错误;`pnpm exec vue-tsc --noEmit` 按文件路径过滤 0 命中(不得用退出码判定)。
|
||||
4. Task 0 的 `<record>` 中 Q1..Q4 均有用户裁决,代码/用例与裁决逐条一致(SUMMARY 对照表):CR-01(Q1)、WR-01(Q2)、WR-02(Q3)、WR-03(Q4);未采纳任何【未选】分支。
|
||||
5. 只改动 `files_modified` 的 6 个文件;未新建源码/测试文件、未新增依赖、未改 `package.json`/`pnpm-lock.yaml`、未改 `hero/types.ts`/`replay/types.ts`/`replay/system.ts`/`flag/**`/`combat/mapDamage.ts`、未新增或修改告警码、本计划提交区间内 `logger.json` 无改动(按区间判定,不看工作树);工作树中与用户无关或属于用户的既有改动(未暂存修改/删除/未跟踪文件)未被触碰、未被暂存、未被提交。
|
||||
5. 只改动 `files_modified` 的 6 个文件与本计划产出物 `07-15-SUMMARY.md`(两者合称本计划声明路径);未新建源码/测试文件、未新增依赖、未改 `package.json`/`pnpm-lock.yaml`、未改 `hero/types.ts`/`replay/types.ts`/`replay/system.ts`/`flag/**`/`combat/mapDamage.ts`、未新增或修改告警码、本计划提交区间内 `logger.json` 无改动(按区间判定,不看工作树);`.planning/ROADMAP.md`/`.planning/STATE.md` 在本计划提交区间内为空(跟踪同步为 orchestrator 收尾步骤);工作树中与用户无关或属于用户的既有改动(未暂存修改/删除/未跟踪文件)未被触碰、未被暂存、未被提交。
|
||||
6. 除「各测试文件 `:1` 文件头覆盖说明的追加」与「新增用例 `it` 前单行中文注释」外,本计划 6 个文件无任何 jsDoc/既有注释改动(用户 2026-09-17 长期规则)。
|
||||
7. 无新增 `it.skip`、既有断言未被弱化、既有用例未被删除;D-06 的码 147 用例仍保留 skip。
|
||||
8. `07-15-SUMMARY.md` 含四条评审映射与闭合状态、`WINDOWS.md` 未新建/未 `fixed`/未 `waive` 的明写、Phase 7 验证失效与重跑要求;`ROADMAP.md` 已定点追加 Wave 15 与 `07-15-PLAN.md` 行。
|
||||
8. `07-15-SUMMARY.md` 含四条评审映射与闭合状态、`WINDOWS.md` 未新建/未 `fixed`/未 `waive` 的明写、Phase 7 验证失效与重跑要求,以及「`.planning/ROADMAP.md`/`.planning/STATE.md` 的跟踪同步为 orchestrator 收尾步骤、本计划零触碰」的明写;本计划提交区间内这两个路径为空。
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
@ -512,7 +513,7 @@ Phase 7 裁决对应(逐条引用):D-01: 本计划是 Phase 7 第 15 个
|
||||
- WR-02 按 Q3=A 闭合:扩容乘数为 1 时告警 149 并回退为倍率 2,扩容必然终止且步骤可完整读回;全仓复核确认无既有配置或用例使用乘数 1。
|
||||
- WR-03 按 Q4=A 闭合:克隆属性与源属性在「可遍历 / 可定位 / 可通知重算 / 可存档(含存档开关)」四个面上同构,且该序列化面的变化已在 SUMMARY 明写。
|
||||
- 每条缺陷各有正确预期回归用例(共 5 条),修复前失败、修复后通过;`pnpm test:ci` 0 失败、跳过项仍仅 1 条、无新增 `it.skip`、既有断言未弱化;D-44 三步门禁全绿;四条按缺陷原子提交且未牵连工作树中的无关改动。
|
||||
- Phase 7 验证失效与重跑要求已记录(须重跑 `/gsd-verify-work`),评审映射登记在 `07-15-SUMMARY.md`,`ROADMAP.md` 定点追加完成。
|
||||
- Phase 7 验证失效与重跑要求已记录(须重跑 `/gsd-verify-work`),评审映射登记在 `07-15-SUMMARY.md`;`.planning/ROADMAP.md`/`.planning/STATE.md` 的跟踪同步交由 orchestrator 收尾(本计划零编辑、零暂存、零提交)。
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user