diff --git a/.planning/phases/07-data-fixes/07-08-PLAN.md b/.planning/phases/07-data-fixes/07-08-PLAN.md
index 246128f..e1dbce1 100644
--- a/.planning/phases/07-data-fixes/07-08-PLAN.md
+++ b/.planning/phases/07-data-fixes/07-08-PLAN.md
@@ -10,49 +10,48 @@ files_modified:
autonomous: false
requirements:
- FIX-01
-user_setup:
- - service: "本地开发环境(无外部服务)"
- why: "D-07 规定 #06-07-1 的接线由用户亲自完成:CoreState 必须向 pathfinding.finder 注入 useMapState/useMapLayer/usePassPredicate"
- env_vars: []
- dashboard_config:
- - task: "在 packages-user/data-state/src/core.ts 中、地图可用之后(initMapState 之后或 loading.once('loaded') 钩子内)调用 state.pathfinding.finder.useMapState(this.maps)、useMapLayer(<当前 eventLayer>)、usePassPredicate(new DefaultPassPredicateImpl(this.maps))"
- location: "packages-user/data-state/src/core.ts(装配点参考 core.ts:248-264;等价注入逐字见 data-state/test/replayPlayback.test.ts:108-114);AI 不实现该接线"
estimate:
- tokens: 16000
- raw_tokens: 16000
+ tokens: 18000
+ raw_tokens: 18000
tasks: 3
confidence: low
must_haves:
truths:
- - "用户完成 CoreState → finder 注入后,取消 skip 的顶层录像瞬移用例转绿"
- - "顶层录像瞬移不再因 maps/layer 未注入而告警 173 并返回空路径(不再下发错误码 2005)"
+ - "core.ts 已提供 useMapState(this.maps) 与 usePassPredicate(new DefaultPassPredicateImpl(this.maps)),且 useMapLayer(null) 为有意设计(勇士初始不在任何楼层,待切层时再设置)"
+ - "测试在楼层激活后把 map.eventLayer 绑定到 finder,顶层录像瞬移可解析出路径并到达 (1,0)(不再告警 173、不再下发 2005)"
+ - "重命名后的用例不再以 it.skip 存在;wireFinder=true 的既有兄弟用例一字未改"
- "pnpm test:ci 全绿,且本计划不新增任何 it.skip"
- - "AI 未修改任何生产源码(D-07)"
+ - "AI 未修改任何生产源码;楼层切换重注入缺口作为用户负责项在 SUMMARY 登记,本阶段不修复"
artifacts:
- path: packages-user/data-state/test/replayPlayback.test.ts
- provides: "顶层录像瞬移回归见证(取消 skip 后覆盖真实 finder 装配)"
+ provides: "顶层录像瞬移回归见证(createSmallMapScene 返回 map、测试侧绑定 eventLayer、原 skip 用例重命名并转绿)"
+ - path: packages-user/data-state/src/core.ts
+ provides: "用户已产出的三处 finder 注入(:236 maps、:238 layer=null、:239-240 predicate)——本计划只读,不修改"
key_links:
+ - "测试侧 state.pathfinding.finder.useMapLayer(map.eventLayer) ↔ finder.find 的 layer 非空判定(finder.ts:210-215),使告警 173 早退分支不再命中"
- "data-state/src/core.ts 的 finder 注入点 ↔ data-system/src/path/finder.ts:117-131 的注入 API ↔ data-state/src/hero/predicate.ts 的 DefaultPassPredicateImpl"
- - "finder.find 在 maps/layer 为 null 时的告警 173 ↔ replayPlayback.test.ts:362-375 的期望行为"
+ - "createSmallMapScene 的返回值 ↔ 顶层录像瞬移用例的层绑定(对既有忽略返回值的调用方为加法式变更)"
assumptions:
- - "FIX-01 探针未分类:本计划以显式假设承接,即 FIX-01 = 「登记缺陷的正确预期 skip 用例转绿且不新增跳过」;#06-07-1 属 D-07 的用户负责项,AI 只在其后验证"
- - "用户接线属一次性注入;楼层切换时事件层会变化(gameMap.ts:146/152),是否需在切层时重新注入由用户设计决定,AI 不预设、不评价"
+ - "FIX-01 探针未分类:本计划以显式假设承接,即 FIX-01 = 「登记缺陷的正确预期 skip 用例转绿且不新增跳过」"
+ - "core.ts:238 useMapLayer(null) 属有意设计(源码注释:初始状态下勇士不在任何楼层,切换楼层后再具体设置);本计划保持 core.ts 原样,由测试侧显式绑定事件层来验证真实装配"
+ - "楼层切换时事件层会变化(gameMap.ts:43 的 eventLayer);仓库内除测试外没有任何生产调用点重新调用 useMapLayer。该重注入缺口是已登记的用户负责后续项,不在本阶段(AI 不实现、不评价其设计)"
prohibitions:
- - "AI 不修改 packages-user/data-state/src/core.ts 或任何生产源码(D-07);失败时退出并汇报,不得自行另辟他法"
- - "不新增测试用例(D-10);只取消 it.skip"
- - "不弱化断言,不改写为可跑绿假象"
+ - "AI 不修改 packages-user/data-state/src/core.ts 或任何生产源码;接线已是用户产出(提交 1ff22dd),本计划不追加、不调整、不重注入"
+ - "不新增测试用例(D-10):本次只取消一条既有 skip 并重命名,且只允许对 createSmallMapScene 做「返回 map」的加法式变更"
+ - "不弱化断言,不改写为可跑绿假象;不删除或跳过任何其它用例"
- "不修改渲染端 @user/client-* 与 legacy 渲染接线"
+ - "不为 #06-07-1 新建 WINDOWS.md 账本条目"
- "不引入新依赖、不新建文件"
---
-处置 path 系统的 `#06-07-1`(D-07 用户负责):`CoreState` 未向 `pathfinding.finder` 注入 `useMapState`/`useMapLayer`/`usePassPredicate`,导致顶层录像瞬移恒因 `maps`/`layer` 为 `null` 告警 173 并返回空路径,进而下发错误码 2005。用户完成接线后,由 AI 取消 `replayPlayback.test.ts:362-375` 的 skip 并验证转绿;AI **不实现**该接线。
+处置 path 系统的 `#06-07-1`(D-07 用户负责):接线已由用户落地——`core.ts:236` `pathfinding.finder.useMapState(this.maps)`、`core.ts:238` `pathfinding.finder.useMapLayer(null)`、`core.ts:239-240` `usePassPredicate(new DefaultPassPredicateImpl(this.maps))`,其中 `useMapLayer(null)` 是**有意设计**(勇士初始不在任何楼层,切层后再具体设置),不是遗漏。因此仅取消 skip 仍会命中 `finder.ts:212-215` 的告警 173 → 空路径 → 2005。本计划据此改为:**由测试侧在楼层激活后显式绑定 `map.eventLayer`**,并把用例**重命名**为反映该事实的名字,取消 skip 后验证转绿;AI **不修改** `core.ts`。
-Purpose: 这是 20 条中唯一的装配缺口(L3 顶层接线),属用户设计的接口装配范畴;完成它才能让顶层录像瞬移链路真实可用。
+Purpose: 这是 20 条中唯一的装配缺口(L3 顶层接线),其接线已由用户完成;测试侧的层绑定与重命名完成后,顶层录像瞬移链路才有一份真实、可跑的回归见证。
-Output: 用户接线完成的事实确认 + 顶层录像瞬移用例取消 skip 并转绿 + 未新建账本条目的处置记录。
+Output: 接线事实与「layer 有意为 null」的确认 + 测试侧绑定 `map.eventLayer` 并重命名用例后转绿 + 未新建账本条目的处置记录 + 楼层切换重注入缺口在 SUMMARY 登记为**用户负责后续项**(本阶段不修复)。
-执行序:本计划在 07-07(save)之后串行执行。`depends_on: 07-07` 是**真实**依赖——`core.ts` 同时是本计划的前置修改目标(07-07 改其 `loadState` 的 178 判定)与用户接线文件,两者必须串行以避免对同一文件并发编辑。
+执行序:本计划在 07-07(save)之后串行执行。`depends_on: 07-07` 是**真实**依赖——`core.ts` 同时是 07-07 的修改目标(`loadState` 的 178 判定)与用户接线文件,两者必须串行以避免对同一文件并发编辑。
@@ -72,95 +71,110 @@ Output: 用户接线完成的事实确认 + 顶层录像瞬移用例取消 skip
@.planning/WINDOWS.md
@dev.md
@packages-user/data-system/src/path/finder.ts
+@packages-user/data-base/src/map/gameMap.ts
@packages-user/data-state/src/hero/predicate.ts
- Task 0: D-07/D-09 确认 —— 用户已完成后端接线,并确认取消 skip
+ Task 0: D-07/D-09 确认 —— 接线已落地且 layer 有意为 null,用户授权测试侧绑定 + 重命名
(只读确认,不修改任何文件)
- - packages-user/data-state/src/core.ts(:240-270 装配区域;核对是否已出现 useMapState/useMapLayer/usePassPredicate)
- - packages-user/data-state/test/replayPlayback.test.ts(:100-120 等价注入逐字、:355-380 目标 skip)
- - packages-user/data-system/src/path/finder.ts(:98-131 注入 API、:205-233 maps/layer 为 null 时的告警 173)
+ - packages-user/data-state/src/core.ts(:232-241 装配区域::236 useMapState(this.maps)、:237-238 useMapLayer(null) 及其中文注释、:239-240 usePassPredicate(new DefaultPassPredicateImpl(this.maps)))
+ - packages-user/data-state/test/replayPlayback.test.ts(:80-116 createSmallMapScene 与 wireFinder 注入、:66-78 withReplayDisabled 返回值、:287/:302/:320 忽略返回值的既有调用方、:360-373 目标 skip 用例)
+ - packages-user/data-system/src/path/finder.ts(:117-131 注入 API、:205-233 maps/layer 为 null 时告警 173 并返回空数组)
+ - packages-user/data-base/src/map/gameMap.ts(:43 eventLayer 字段,楼层切换时会变化)
- .planning/phases/07-data-fixes/07-RESEARCH.md(§Per-Finding #06-07-1、§WINDOWS.md 收口映射)
-执行前置:先用只读方式核对用户是否已在 `core.ts` 的装配区域调用 `state.pathfinding.finder.useMapState(...)`、`useMapLayer(...)`、`usePassPredicate(...)`。若未出现,**必须停止本计划**并把缺失项与接线依据(`replayPlayback.test.ts:108-114` 的等价注入)汇报给用户,等待用户完成后再重新执行本计划;不得由 AI 代改 `core.ts`(D-07)。
+执行前置(只读核对,勿写):确认用户接线已在源码中落地——`core.ts:236` `pathfinding.finder.useMapState(this.maps)`、`core.ts:238` `pathfinding.finder.useMapLayer(null)`(其上中文注释:初始状态下勇士不在任何楼层,切换楼层后再具体设置)、`core.ts:239-240` `usePassPredicate(new DefaultPassPredicateImpl(this.maps))`。若三处中任一缺失,**必须停止本计划**并把缺失项与接线依据(`replayPlayback.test.ts:108-114` 的等价注入)汇报给用户;不得由 AI 代改 `core.ts`(D-07)。
-若已接线,向用户汇报以下内容并等待确认:
-① 接线事实:`core.ts` 中三处注入的调用位置与实参(`this.maps` / 具体 `eventLayer` / `new DefaultPassPredicateImpl(this.maps)`);注入时机是否在地图可用之后(`initMapState` 之后或 `loaded` 钩子内)。
-② 预期效果:`finder.find` 在 `maps`/`layer` 均可用时不再进入告警 173 早退分支,顶层录像瞬移可解析出路径,不再下发 2005。
-③ 验证方式:取消 `replayPlayback.test.ts:362-375`(`plays a teleport step without manual finder wiring`)的 skip,断言一字不改,运行该文件确认转绿。
-④ 已知设计边界(不作评价,仅陈述):`useMapLayer` 传入的是某个 `IGameMap.eventLayer`,而楼层切换时事件层会变化(`gameMap.ts:146/152`);若注入是一次性的,是否在切层时重新注入由用户决定(属用户设计范畴)。
-⑤ 失败纪律:若取消 skip 后用例仍红,AI 必须**退出本计划**、如实汇报观测到的告警码与路径结果,并等待用户修订接线或修订本计划;**不得**自行修改 `core.ts`、不得改断言(D-07/D-09)。
-⑥ 账本事实:`#06-07-1` 在 WINDOWS.md 中无对应条目,D-14 的 waive 没有可 waive 的对象;研究建议不新建条目(避免抬高 `open_count` 门禁),改为在本计划 SUMMARY 记录用户负责项与验证结果。请用户确认。
+核对通过后,向用户汇报以下内容并等待确认:
+① 已确认的接线事实:三处注入的调用位置与实参如上;`useMapLayer` 传入 `null` 是**有意设计**(勇士初始不在任何楼层),不是遗漏。
+② 由此的必然结果:`finder.find` 在 `layer` 为 `null` 时进入 `finder.ts:212-215` 的告警 173 早退分支并返回空数组,顶层录像瞬移随之下发 2005——仅取消 skip、不绑定事件层仍会红。
+③ 用户已确认的处置方式(本计划据此执行):**保持 `core.ts` 原样**;在**测试侧**于楼层激活后调用 `state.pathfinding.finder.useMapLayer(map.eventLayer)`,并把用例从 `plays a teleport step without manual finder wiring` **重命名为** `plays a teleport step after the event layer is bound on floor activation`(名字须反映其不再宣称「无需手动接线」)。
+④ 需要登记的用户负责项(本阶段**不修复**):`core.ts:238` 的 `useMapLayer(null)` 是一次性注入,楼层切换时事件层会变化(`gameMap.ts:43`),仓库内除测试外没有任何生产调用点在切层时重新注入;该缺口归用户所有,在 SUMMARY 登记为后续项,且不新建账本条目。
+⑤ 验证方式:取消 skip 后运行该文件确认转绿;断言一字不改(`x` 为 1、`y` 为 0)。
+⑥ 失败纪律:若绑定事件层后用例仍红,AI 必须**退出本计划**、如实汇报观测到的告警码与路径结果,并等待用户修订接线或修订本计划;**不得**自行修改 `core.ts`、不得改断言(D-07/D-09)。
+⑦ 账本事实:`#06-07-1` 在 WINDOWS.md 中无对应条目,D-14 的 waive 没有可 waive 的对象;按用户确认不新建条目(避免抬高 `open_count` 门禁),改为在本计划 SUMMARY 记录用户负责项与验证结果。请用户确认。
- 用户是否已完成 `CoreState` → `pathfinding.finder` 的三处注入(D-07),以及是否确认取消 `replayPlayback.test.ts:362-375` 的 skip 验证
+ 用户是否确认「保持 core.ts 原样(layer 有意为 null)、由测试侧绑定 map.eventLayer 并重命名用例、取消 skip 验证、不新建账本条目」
- `#06-07-1` 是唯一的顶层装配缺口,D-07 明确规定接线由用户完成、AI 只做接线后的验证。若接线尚未完成,本计划无法执行也必须停止——AI 不得代改 core.ts。接线采用一次性注入还是切层重注入,由用户设计决定。
+ `#06-07-1` 是唯一的顶层装配缺口,D-07 规定接线由用户完成。用户已完成接线并把事件层**有意**留为 `null`(勇士初始不在任何楼层),故「取消 skip」不再等价于「无需接线即可通过」:测试必须自己绑定事件层。楼层切换时的重注入是用户负责的后续缺口,本计划只登记、不实现、不评价。
-
+
- 回复 wired-approve / not-wired(并说明后重新执行)/ new-window-entry,或给出修订意见
+ 默认按已确认的 test-binds-layer 继续;如需改为 core-reinject-first / not-wired / new-window-entry,或给出修订意见,请直接回复
- 用户明确回复 wired-approve、not-wired 或 new-window-entry
- 用户回复 not-wired 或 revise;或未回复即继续 —— 必须停止执行
+ 用户确认按 test-binds-layer 执行(或给出其它明确指示)
+ 用户回复 not-wired / core-reinject-first / revise;或未回复即继续 —— 必须停止执行
- - `core.ts` 的装配区域存在 `useMapState`、`useMapLayer`、`usePassPredicate` 三处调用(源码断言)
- - 用户明确确认取消 skip 与账本条目处置
+ - `core.ts` 的装配区域存在 `useMapState`、`useMapLayer(null)`、`usePassPredicate` 三处调用(源码断言)
+ - `useMapLayer(null)` 被记录为有意设计,且用户确认测试侧绑定事件层 + 重命名用例
+ - 楼层切换重注入缺口被登记为用户负责后续项,且不新建账本条目
- 用户确认为 wired-approve 或 new-window-entry,且 `core.ts` 三处注入在源码中可见
+ 用户确认为 test-binds-layer,且 `core.ts` 三处注入在源码中可见(`:236`/`:238`/`:239-240`)
- Task 1: 取消 #06-07-1 的 skip 并验证顶层录像瞬移转绿
+ Task 1: 测试侧绑定事件层、重命名用例并验证顶层录像瞬移转绿
packages-user/data-state/test/replayPlayback.test.ts
- - packages-user/data-state/test/replayPlayback.test.ts(:100-120 等价注入、:355-380 目标 skip、文件内其余既有绿用例)
- - packages-user/data-state/src/core.ts(:240-270 用户接线后的装配)
+ - packages-user/data-state/test/replayPlayback.test.ts(:80-116 createSmallMapScene/wireFinder 注入、:66-78 withReplayDisabled 返回 action() 的返回值、:287/:302/:320 忽略返回值的既有调用方、:360-373 目标 skip 用例)
+ - packages-user/data-state/src/core.ts(:232-241 用户接线后的装配)
+ - packages-user/data-system/src/path/finder.ts(:121-123 useMapLayer 接受 IMapLayer | null、:209-215 layer 为 null 时告警 173 并返回空数组)
-把 `replayPlayback.test.ts:362-375`(`plays a teleport step without manual finder wiring`)的 `it.skip` 改为 `it`,断言一字不改,同步 it 前的中文注释(去掉「疑似 bug/待修复」措辞,改为中性描述该用例覆盖真实 finder 装配)。
+仅改 `replayPlayback.test.ts` 一个文件,做三处加法式/最小变更,不动生产源码(`core.ts` 为用户产出,保持原样):
+(a) 让 `createSmallMapScene`(:85)**返回 `map`**:在函数体末尾(`resetHero(state)` 之后,且仍在 `if (!map || !map.eventLayer) throw` 造成的非空收窄范围内)加 `return map;`。既有调用方 :287/:302/:320 忽略返回值,不受影响;`withReplayDisabled`(:71-78)返回 `action()` 的返回值,故返回值可穿透该包装器。
+(b) 在目标用例中捕获该 map 并在**楼层激活后**显式绑定事件层:把 `withReplayDisabled(state, () => createSmallMapScene(state, false));` 改为捕获返回值的形式(`const map = withReplayDisabled(state, () => createSmallMapScene(state, false));`),随后在 `runHeroStep`/`replay.record`/`playRoute` **之前**调用 `state.pathfinding.finder.useMapLayer(map.eventLayer);`。`wireFinder = false` 保持不变——该用例刻意不依赖 createSmallMapScene 内部的手动注入,只补上事件层。
+(c) 取消 skip 并重命名:`it.skip('plays a teleport step without manual finder wiring', ...)` 改为 `it('plays a teleport step after the event layer is bound on floor activation', ...)`;同步把 :360-361 的中文注释从「疑似缺陷 #06-07-1 …… 修复后取消 skip」改为中性描述(说明本用例在楼层激活后由测试侧绑定事件层、验证顶层录像瞬移仍可解析并到达目标),不得再出现「疑似 bug / 待修复」措辞。
-不改 `:108-114` 的 `wireFinder` 等价注入逻辑(该用例正是以 `wireFinder = false` 区分真实装配与测试注入);不改该文件任何其它用例;不新增用例;不改任何生产源码。
+断言保持一字不改(`expect(state.hero.location.x).toBe(1)` 与 `expect(state.hero.location.y).toBe(0)`);不改 :108-114 的 `wireFinder` 分支;不改该文件任何其它用例;不新增用例;不改任何生产源码;不引入新依赖、不新建文件。
-若用例仍红:立即停止并按 Task 0 的第 ⑤ 条退出汇报(记录实际告警码、找到的路径与首个分歧),不得改断言、不得改 `core.ts`。
+若用例仍红:立即停止并按 Task 0 的第 ⑥ 条退出汇报(记录实际告警码、找到的路径与首个分歧),不得改断言、不得改 `core.ts`。
-验证:`pnpm exec vitest run packages-user/data-state/test/replayPlayback.test.ts` 全绿 → D-44 门禁三步(本计划仅一个测试文件)。提交信息:`test(07-08): #06-07-1 verify the top-level teleport with the wired finder`。
+验证:`pnpm exec vitest run packages-user/data-state/test/replayPlayback.test.ts` 全绿 → D-44 门禁三步(本计划仅一个测试文件)。提交信息:`test(07-08): #06-07-1 bind the event layer in the teleport playback test`。
pnpm exec vitest run packages-user/data-state/test/replayPlayback.test.ts
非零退出,或摘要行出现 "1 failed" / "failed"(仍告警 173 / 路径为空 / 下发 2005),或输出出现 "no tests found"
- - `replayPlayback.test.ts` 的 `plays a teleport step without manual finder wiring` 不再以 `it.skip` 存在(源码断言:该行不含 `.skip`)
- - `pnpm exec vitest run packages-user/data-state/test/replayPlayback.test.ts` 全绿
+ - `replayPlayback.test.ts` 中 `plays a teleport step without manual finder wiring` 已不存在;`it('plays a teleport step after the event layer is bound on floor activation', ...)` 不以 `.skip` 存在(源码断言:该行不含 `.skip`)
+ - `createSmallMapScene` 返回 `map`,且目标用例在 `playRoute` 之前调用 `state.pathfinding.finder.useMapLayer(map.eventLayer)`
+ - `core.ts` 保持原样(`:236` 提供 `useMapState`、`:239-240` 提供 `usePassPredicate`、`:238` 的 `useMapLayer(null)` 不变)
+ - `pnpm exec vitest run packages-user/data-state/test/replayPlayback.test.ts` 全绿,且断言未被改写
- 本计划未修改任何生产源码(以本计划提交 sha 核验:`git show --name-only <本计划提交 sha>` 仅含该测试文件与 .planning 文档)
- 用例取消 skip 并转绿,且未触碰任何生产源码;已一个原子提交入库
+ 用例已重命名并在测试侧绑定事件层后转绿,三个 `wireFinder=true` 兄弟用例未改动,且未触碰任何生产源码;已一个原子提交入库
@@ -169,13 +183,18 @@ Output: 用户接线完成的事实确认 + 顶层录像瞬移用例取消 skip
- .planning/phases/07-data-fixes/07-VALIDATION.md(§Manual-Only Verifications 的 #06-07-1 行)
- .planning/phases/07-data-fixes/07-RESEARCH.md(§WINDOWS.md 收口映射「需澄清」、§Open Questions)
+ - packages-user/data-state/src/core.ts(:232-241,供 SUMMARY 逐字记录接线实参)
对唯一改动文件串行执行 D-12(沿用 D-44 的文件级判定)三步门禁:`pnpm exec eslint --fix` 后 `pnpm exec eslint` 0 错误;`pnpm exec vue-tsc --noEmit` 后按该文件相对路径过滤输出 0 类型错误(不以整仓退出码判定);`pnpm test:ci` 全绿。
-账本:`#06-07-1` 无对应条目,按 Task 0 的用户确认处置(默认不新建);若用户选择 `new-window-entry`,按用户指示执行 `windows` 的 append/waive 流程并在 SUMMARY 记录 `open_count` 变化。
+账本:`#06-07-1` 在 WINDOWS.md 中无对应条目,**不新建条目**(Task 0 已确认 test-binds-layer);若用户在 Task 0 改选 `new-window-entry`,则按用户指示执行 `windows` 的 append/waive 流程并在 SUMMARY 记录 `open_count` 变化。
-在 SUMMARY 中记录:用户接线的事实(三处注入的调用位置与实参)、验证命令与结果、用户负责项的边界说明(一次性注入 vs 切层重注入由用户决定)、以及 D-14 的账本处置结论。
+在 SUMMARY 中记录以下四类内容:
+① 已确认的接线事实(源码逐字):`core.ts:236 pathfinding.finder.useMapState(this.maps)`、`:238 pathfinding.finder.useMapLayer(null)`(含中文注释原意:初始状态下勇士不在任何楼层,切换楼层后再具体设置)、`:239-240 usePassPredicate(new DefaultPassPredicateImpl(this.maps))`;用户接线提交 `1ff22dd`。
+② `core.ts` 的 `layer` 为 `null` 是**有意设计**(非遗漏),因此单纯取消 skip 仍会命中 `finder.ts:212-215` 的告警 173 → 空路径 → 2005。
+③ 本计划的测试侧处置:`createSmallMapScene` 返回 `map`(加法式);目标用例在楼层激活后调用 `state.pathfinding.finder.useMapLayer(map.eventLayer)`;用例由 `plays a teleport step without manual finder wiring` 重命名为 `plays a teleport step after the event layer is bound on floor activation`;断言未改。
+④ 剩余的用户负责缺口(本阶段**不修复**):`core.ts:238` 的一次性 `useMapLayer(null)` 在楼层切换(`gameMap.ts:43` 的 `eventLayer` 变化)时不会被重新注入,仓库内无对应生产调用点;登记为用户负责后续项,D-14 账本无 `#06-07-1` 条目、不新建。
pnpm test:ci
@@ -185,9 +204,9 @@ Output: 用户接线完成的事实确认 + 顶层录像瞬移用例取消 skip
- `pnpm exec eslint` 对该文件 0 错误
- `pnpm exec vue-tsc --noEmit` 按该文件路径过滤后无命中
- `pnpm test:ci` 全绿,且本计划未新增 `it.skip`
- - SUMMARY 含用户接线事实、验证结果与账本处置结论
+ - SUMMARY 含①接线事实(`1ff22dd` 与三处实参)、②layer 有意为 null、③测试侧绑定与重命名、④楼层切换重注入的用户负责缺口登记
- D-44 三步全过、全量套件绿、用户负责项处置已登记于 SUMMARY(提交粒度按 D-13 一个缺陷一个原子提交)
+ D-44 三步全过、全量套件绿、四类登记内容均写入 SUMMARY(提交粒度按 D-13 一个缺陷一个原子提交)
@@ -197,39 +216,41 @@ Output: 用户接线完成的事实确认 + 顶层录像瞬移用例取消 skip
| Boundary | Description |
|----------|-------------|
-| 顶层装配 → finder | `maps`/`layer`/谓词未注入时 finder 返回空路径并依赖诊断码上报,属装配缺陷而非安全边界 |
-| 用户代码 → AI 范围 | D-07 明确接线属用户,AI 越界即违反协作边界 |
+| 顶层装配 → finder | `core.ts` 已注入 `maps` 与谓词,但 `layer` 有意为 `null`;测试必须自行绑定事件层,属装配边界而非安全边界 |
+| 用户代码 → AI 范围 | 接线已由用户落地(D-07);AI 只改测试侧,越界修改 `core.ts` 即违反协作边界 |
| 包管理器 → 仓库 | 本阶段无安装动作 |
## STRIDE Threat Register
| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |
|-----------|----------|-----------|----------|-------------|-----------------|
-| T-7-14 | DoS(功能性) | `path/finder.ts` 未注入时的早退路径(告警 173) | low | accept | 接线由用户完成(D-07);AI 只在接线后取消 skip 验证,失败即退出汇报,不修改生产代码 |
+| T-7-14 | DoS(功能性) | `path/finder.ts` 的 `layer = null` 早退路径(告警 173)与楼层切换重注入缺口 | low | accept | 接线由用户完成(D-07);`layer = null` 为有意设计,由测试侧显式绑定 `map.eventLayer` 规避;切层重注入属用户负责后续项,本阶段登记于 SUMMARY 而不修改生产代码 |
| T-7-SC | Tampering | npm/pip/cargo 安装 | high | accept | 本阶段不安装任何包(`package.json`/`pnpm-lock.yaml` 不变);若执行中出现安装需求,立即停止并汇报 |
-- `core.ts` 中存在 `useMapState`/`useMapLayer`/`usePassPredicate` 三处注入(用户产出,源码断言)
+- `core.ts` 中存在 `useMapState`(`:236`)/`useMapLayer(null)`(`:238`)/`usePassPredicate`(`:239-240`)三处注入(用户产出,本计划只读)
+- `replayPlayback.test.ts` 的目标用例已重命名为 `plays a teleport step after the event layer is bound on floor activation` 且不以 `it.skip` 存在
+- `createSmallMapScene` 返回 `map`;该用例在 `playRoute` 之前调用 `state.pathfinding.finder.useMapLayer(map.eventLayer)`
+- 改动文件仅 `replayPlayback.test.ts`(AI 未触碰生产源码;`git show --name-only <本计划提交 sha>` 可核验)
- `pnpm exec vitest run packages-user/data-state/test/replayPlayback.test.ts` 全绿
- `pnpm test:ci` 全绿且本计划不新增 `it.skip`
-- 改动文件仅 `replayPlayback.test.ts`(AI 未触碰生产源码)
-1. 用户完成 `CoreState` → `finder` 注入(D-07)
-2. `#06-07-1` 正确预期用例取消 skip 并转绿
+1. 确认 `core.ts` 的三处 finder 注入已由用户落地(D-07),且 `useMapLayer(null)` 为有意设计
+2. 测试侧在楼层激活后绑定 `map.eventLayer`,`#06-07-1` 用例重命名、取消 skip 后转绿
3. AI 未修改任何生产源码;失败时按 D-09 退出并汇报
-4. 用户负责项与账本处置在 SUMMARY 登记
+4. 用户负责的楼层切换重注入缺口与账本处置(不新建条目)在 SUMMARY 登记
## Artifacts this phase produces
| 类型 | 路径 | 内容 |
|------|------|------|
-| 用户产出(AI 不改) | `packages-user/data-state/src/core.ts` | `pathfinding.finder` 的三处注入 |
-| 测试(修改) | `packages-user/data-state/test/replayPlayback.test.ts` | 1 条 skip 取消 |
-| 摘要 | `.planning/phases/07-data-fixes/07-08-SUMMARY.md` | 用户接线事实、验证结果、账本处置 |
+| 用户产出(AI 只读) | `packages-user/data-state/src/core.ts` | `pathfinding.finder` 的三处注入(`:236`/`:238`/`:239-240`);`useMapLayer(null)` 有意为 null |
+| 测试(修改) | `packages-user/data-state/test/replayPlayback.test.ts` | `createSmallMapScene` 返回 `map`;目标用例测试侧绑定 `map.eventLayer`、重命名并取消 skip |
+| 摘要 | `.planning/phases/07-data-fixes/07-08-SUMMARY.md` | 接线事实、layer 有意为 null、测试侧绑定与重命名、切层重注入用户负责缺口登记、账本处置 |