mirror of
https://github.com/motajs/template.git
synced 2026-10-16 18:40:17 +08:00
fix(04-10): revise impact-inventory plan per checker feedback
This commit is contained in:
parent
c9bf0c63a8
commit
523d19417c
@ -222,7 +222,7 @@ Plans:
|
||||
|
||||
**Wave 9** *(blocked on Wave 8 completion)*
|
||||
|
||||
- [ ] 04-10-PLAN.md — 渲染端结构性重构影响范围清点(**只读**,D-51..D-57 第一步):把 `packages-user/client-modules/src/render/` 的通用内容(`render/components`、`render/elements`、`render/map` 三文件夹 + `render/utils/layout.ts`,规划日实测 **39** 文件)迁往渲染系统层 `packages-user/client-base/src/`(D-51/D-52),目标布局按 D-53(`client-base/src/{components,elements,map}/` + `client-base/src/layout/`,不新建 `render/`);不移植 `render/utils/` 其余(`index.ts`/`saves.ts`/`use.ts`)与 `ui`/`fx`/`weather`/`render` 顶层文件(D-54);legacy 只报告(D-55)、用户并发改动零触碰(D-56)。台账按 A 被移集合内部交叉引用(8 方向:`components→elements`、`elements→map`、→ `render/renderer`、→ `render/use.ts`、→ `client-modules/src/shared.ts`、→ `@user/client-base` 自包引用、`map/extension/*→map/types`、零命中机器证据)/ B 外部导入点(`client-modules/src/{client.ts,types.ts}`、`render/index.tsx`、`render/ui` 8 文件 10 处含深层导入、`render/utils/{saves.ts,index.ts}`、`fallback/ui.ts`,以及 `entry-client` / `entry-data` / `packages/legacy-ui` 经公共面的间接依赖)/ C barrel 与导出面(7 节点 + 断链判定)/ D 分层与循环依赖风险(`client-base` 不得反向依赖 `client-modules`;`client-base/package.json` 依赖缺口;`?raw` shader;`dev.md` 规则对照)/ E legacy 命中(仅报告)/ F 未确定 六类分组,每行 ≥2 个 `file:line` 锚点;产出 `04-STRUCTURE-MIGRATION-IMPACT.md`,生产代码零改动且零命名变更;门禁 = 只读基线逐条一致 + 11 节结构 / 39 文件清单 / 类别行数与双锚点 / 两处零命中机器证据 / CRLF / 既有产物保护与计划范围 + 人工复核;`autonomous: false`(Task 0 汇报关卡);第二步(移植实施)待用户审阅后另行规划;`REND-01` / `REND-02` 仍 Pending
|
||||
- [ ] 04-10-PLAN.md — 渲染端结构性重构影响范围清点(**只读**,D-51..D-57 第一步):把 `packages-user/client-modules/src/render/` 的通用内容(`render/components`、`render/elements`、`render/map` 三文件夹 + `render/utils/layout.ts`,规划日实测 **39** 文件)迁往渲染系统层 `packages-user/client-base/src/`(D-51/D-52),目标布局按 D-53(`client-base/src/{components,elements,map}/` + `client-base/src/layout/`,不新建 `render/`);不移植 `render/utils/` 其余(`index.ts`/`saves.ts`/`use.ts`)与 `ui`/`fx`/`weather`/`render` 顶层文件(D-54);legacy 只报告(D-55)、用户并发改动零触碰(D-56)。台账按 A 被移集合内部交叉引用(8 方向:`components→elements`、`elements→map`、→ `render/renderer`、→ `render/use.ts`、→ `client-modules/src/shared.ts`、→ `@user/client-base` 自包引用、`map/extension/*→map/types`、零命中机器证据)/ B 外部导入点(`client-modules/src/{client.ts,types.ts}`、`render/index.tsx`、`render/ui` 8 文件 11 处含深层导入、`render/utils/{saves.ts,index.ts}`、`fallback/ui.ts`,以及 `entry-client` / `entry-data` / `packages/legacy-ui` 经公共面的间接依赖)/ C barrel 与导出面(7 节点 + 断链判定)/ D 分层与循环依赖风险(`client-base` 不得反向依赖 `client-modules`;`client-base/package.json` 依赖缺口;`?raw` shader;`dev.md` 规则对照)/ E legacy 命中(仅报告)/ F 未确定 六类分组,每行 ≥2 个 `file:line` 锚点;产出 `04-STRUCTURE-MIGRATION-IMPACT.md`,生产代码零改动且零命名变更;门禁 = 只读基线逐条一致 + 10 节结构 / 39 文件清单 / 类别行数与双锚点 / 两处零命中机器证据 / CRLF / 既有产物保护与计划范围 + 人工复核;`autonomous: false`(Task 0 汇报关卡);第二步(移植实施)待用户审阅后另行规划;`REND-01` / `REND-02` 仍 Pending
|
||||
|
||||
**UI hint**: yes
|
||||
|
||||
|
||||
@ -4,15 +4,15 @@ milestone: v1.0
|
||||
current_phase: 04
|
||||
current_phase_name: 渲染适配与双布局
|
||||
status: executing
|
||||
stopped_at: "Completed 04-09-PLAN.md(TextureManager 新接口适应·第二步实施:render/map/{vertex,renderer,extension/hero}.ts 三文件按 D-43..D-50 改接新接口;范围内 texture 归属诊断 13→0、全仓错误 263→250;material/ 与加载面零改动;REND-01/REND-02 保持 Pending)"
|
||||
last_updated: "2026-09-23T07:10:00.000Z"
|
||||
last_activity: 2026-09-23
|
||||
last_activity_desc: Completed 04-09-PLAN.md(TextureManager 新接口适应·第二步)
|
||||
state_head: 50cf9a3
|
||||
stopped_at: Completed 04-09-PLAN.md(TextureManager 新接口适应·第二步实施:render/map/{vertex,renderer,extension/hero}.ts 三文件按 D-43..D-50 改接新接口;范围内 texture 归属诊断 13→0、全仓错误 263→250;material/ 与加载面零改动;REND-01/REND-02 保持 Pending)
|
||||
last_updated: "2026-09-24T06:31:01.419Z"
|
||||
last_activity: 2026-09-24
|
||||
last_activity_desc: Planned 04-10-PLAN.md(渲染端结构性重构·第一步只读清点;通过 checker)
|
||||
state_head: c9bf0c63a849d7d923106a9e3e9fbccd039fa5f2
|
||||
progress:
|
||||
total_phases: 7
|
||||
completed_phases: 1
|
||||
total_plans: 80
|
||||
total_plans: 81
|
||||
completed_plans: 79
|
||||
milestone_name: milestone
|
||||
---
|
||||
@ -28,10 +28,10 @@ See: .planning/PROJECT.md (updated 2026-09-17)
|
||||
|
||||
## Current Position
|
||||
|
||||
Phase: 04 (渲染适配与双布局) — IN PROGRESS
|
||||
Plan: 9/9 已执行(04-01..04-09)
|
||||
Status: 04-09 完成(TextureManager 新接口适应·第二步:三文件 texture 归属诊断 13→0);Phase 4 整体仍未完成 — REND-01/REND-02 保持 Pending,移动端/桌面端双布局与其余渲染适配未做
|
||||
Last activity: 2026-09-23 — Completed 04-09-PLAN.md(TextureManager 新接口适应·第二步)
|
||||
Phase: 04 (渲染适配与双布局) — READY TO EXECUTE
|
||||
Plan: 9/10 已执行(04-01..04-09);04-10(渲染端结构性重构·第一步只读清点)已规划待执行(Wave 9)
|
||||
Status: 04-10 已规划并通过 checker(0 blocker / 0 warning / 2 info-advisory);待用户回复「可以执行」后执行;Phase 4 整体仍未完成 — REND-01/REND-02 保持 Pending
|
||||
Last activity: 2026-09-24 — Planned 04-10-PLAN.md(渲染端结构性重构·第一步只读清点)
|
||||
|
||||
Progress: [█████░░░░░] 50%
|
||||
|
||||
|
||||
@ -26,27 +26,27 @@ estimate:
|
||||
confidence: low
|
||||
must_haves:
|
||||
truths:
|
||||
- "**本计划的第一个 block 点是 Task 0 的 `blocking-human` 汇报关卡(AGENTS.md 硬要求)**:Task 0 必须先向用户汇报「要解决的问题(`packages-user/client-modules/src/render/` 下的通用渲染内容放错层,须下沉到渲染系统层 `packages-user/client-base/src/`)、锁定裁定(D-51..D-57:移植集合 / 目标布局 / 不移植集合 / legacy 不考虑 / 用户并发改动不可触碰 / 第一步交付物)、大致解决方案(只读影响清点,唯一交付物 `04-STRUCTURE-MIGRATION-IMPACT.md`,10 节结构 / A–F 六类分列 / 每行 ≥2 个 `file:line` 锚点)、**本步为只读、不引入任何命名变更**(不新增 / 不改名任何公共、受保护、私有成员或字段,也不裁定 `client-base/src/{components,elements,map,layout}` 下的文件名 / barrel 名)、验证方式与只读证明」,然后必须**停下等待**用户明确回复「可以执行」四个字;收到该回复前不得执行任何任务、不得派发任何执行子代理。无论触发方式(`/gsd-execute-phase`、`/gsd-manager`、`/gsd-autonomous`、子代理/执行器派发)或配置模式(`.planning/config.json` 的 `mode: yolo`、`workflow.auto_advance`)如何,均不得自动放行。"
|
||||
- "**本计划的第一个 block 点是 Task 0 的 `blocking-human` 汇报关卡(AGENTS.md 硬要求)**:Task 0 必须先向用户汇报「要解决的问题(`packages-user/client-modules/src/render/` 下的通用渲染内容放错层,须下沉到渲染系统层 `packages-user/client-base/src/`)、锁定裁定(D-51..D-57:移植集合 / 目标布局 / 不移植集合 / legacy 不考虑 / 用户并发改动不可触碰 / 第一步交付物)、大致解决方案(只读影响清点,唯一交付物 `04-STRUCTURE-MIGRATION-IMPACT.md`,10 节结构 / A–F 六类分列 / 事实·基准行每行 ≥2 个完整 `文件:行` 锚点(`.json` / `.md` 基准也计为锚点)、零命中·对照扫描证据行(`A-09` / `B-09` / `E-01` / `E-04` / `E-05`)带 `[证据行]` 标记并附 `git grep` 机器证据)、**本步为只读、不引入任何命名变更**(不新增 / 不改名任何公共、受保护、私有成员或字段,也不裁定 `client-base/src/{components,elements,map,layout}` 下的文件名 / barrel 名)、验证方式与只读证明」,然后必须**停下等待**用户明确回复「可以执行」四个字;收到该回复前不得执行任何任务、不得派发任何执行子代理。无论触发方式(`/gsd-execute-phase`、`/gsd-manager`、`/gsd-autonomous`、子代理/执行器派发)或配置模式(`.planning/config.json` 的 `mode: yolo`、`workflow.auto_advance`)如何,均不得自动放行。"
|
||||
- "**只读硬约束(生产代码零改动)**:本 run 生产源码改动为 **0**——`git status --porcelain -- packages packages-user src` 在 Task 1 步骤 (0a) 起始逐行原样记录进 `## 方法`(规划日 2026-09-24 实测为 ` M packages-user/data-base/src/enemy/types.ts` 单条,属用户并发改动 D-56),Task 1 / Task 3 门禁断言其后**逐条一致**(不新增、不消失、状态码不变);`files_modified` 只含 `04-STRUCTURE-MIGRATION-IMPACT.md` 一个交付物;本 PLAN 与 `04-10-SUMMARY.md` 属计划/执行簿记,不算生产改动。"
|
||||
- "**被移集合清单完整(39 个文件,一个不少、一个不多)**:`## 被移集合清单(39 文件)` 必须逐条列出 D-52 明示的移植集合全部文件并给出各文件职责与 D-53 目标落点——`render/components/` **13** 个(`choices.tsx` / `floorSelect.tsx` / `icons.tsx` / `index.ts` / `input.tsx` / `list.tsx` / `misc.tsx` / `page.tsx` / `scroll.tsx` / `textbox.tsx` / `textboxTyper.ts` / `thumbnail.tsx` / `tip.tsx`)、`render/elements/` **5** 个(`cache.ts` / `index.ts` / `misc.ts` / `props.ts` / `types.ts`)、`render/map/` **20** 个(`block.ts` / `constant.ts` / `element.ts` / `index.ts` / `moving.ts` / `renderer.ts` / `status.ts` / `types.ts` / `vertex.ts` / `viewport.ts` + `extension/{door,hero,index,manager,text,types}.ts` **6** + `shader/{back.frag,back.vert,map.frag,map.vert}` **4**)、`render/utils/layout.ts` **1**;并写明目标落点(三个文件夹直接落 `client-base/src/{components,elements,map}/`,`layout.ts` 单独开 `client-base/src/layout/`,**不新建 `render/` 目录**),且明写本步**不移动、不复制、不预建**任何目标文件。"
|
||||
- "**A 类(被移集合内部交叉引用)逐条给两侧 `file:line` 锚点**:至少覆盖 ① `components → elements`(`tip.tsx:7` / `textbox.tsx:33` / `textboxTyper.ts:5`);② `elements → map`(`elements/index.ts:2` / `elements/props.ts:4`);③ 被移集合 → **留在 `render/` 顶层**的 `renderer`(`elements/index.ts:3` / `components/textboxTyper.ts:6` / `components/misc.tsx:14`);④ 被移集合 → **留在 `render/`** 的 `use.ts`(`components/choices.tsx:8` / `tip.tsx:4` / `scroll.tsx:31` / `input.tsx:14` / `misc.tsx:10`);⑤ 被移集合 → **`client-modules/src/shared.ts`**(`map/vertex.ts:25` / `map/element.ts:5` / `map/renderer.ts:53` / `map/extension/door.ts:9`);⑥ 被移集合 → **`@user/client-base`(自包引用)**(`map/extension/hero.ts:16` / `map/moving.ts:3` / `map/renderer.ts:13` / `map/types.ts:12` / `map/vertex.ts:28`);⑦ `map/extension/*` → `map/types`(`extension/{door.ts:7,hero.ts:13,manager.ts:8,types.ts:4,text.ts:8}`)。**每行须含「导入处 `file:line`」+「被导入符号的声明 / barrel `file:line`」两个锚点。**"
|
||||
- "**B 类(外部导入点)把移出集合之外的每一处 importer 枚举到 `file:line`**:至少覆盖 ① `client-modules/src/types.ts:2`(`./render/map`);② `client-modules/src/client.ts:25`(`./render/map`);③ `client-modules/src/render/index.tsx:5,45,46`(`./elements` / `./components`);④ `render/ui/` **8** 个文件的 **10** 处 `../components` 导入(`main.tsx:9` / `save.tsx:16` / `settings.tsx:16,21` / `statistics.tsx:8` / `statusBar.tsx:3` / `title.tsx:31` / `viewmap.tsx:26,29` / `toolbar.tsx:13,19`);⑤ `render/utils/saves.ts:2`(`../components`);⑥ `render/utils/index.ts:1`(`export * from './layout'`——barrel 引用被移文件);⑦ `fallback/ui.ts:2`(深层导入 `../render/components/tip`);⑧ 其它 monorepo 包经 `@user/client-modules` 公共面**间接**依赖(`entry-client/src/create.ts:10,27`、`entry-data/src/mota.ts:11,32`、`packages/legacy-ui/src/preset/ui.ts:86,96,105`);⑨ 对照扫描的机器证据:`git grep -n -F \"render/components\"` / `-F \"render/elements\"` / `-F \"render/map\"`(同限 `packages` 与 `src`)在 `packages-user` 之外**零命中**。"
|
||||
- "**A 类(被移集合内部交叉引用)逐条给两侧 `file:line` 锚点**:至少覆盖 ① `components → elements`(`tip.tsx:7` / `textbox.tsx:33` / `textboxTyper.ts:5`);② `elements → map`(`elements/index.ts:2` / `elements/props.ts:4`);③ 被移集合 → **留在 `render/` 顶层**的 `renderer`(`elements/index.ts:3` / `components/textboxTyper.ts:6` / `components/misc.tsx:14`);④ 被移集合 → **留在 `render/`** 的 `use.ts`(`components/choices.tsx:8` / `tip.tsx:4` / `scroll.tsx:31` / `input.tsx:14` / `misc.tsx:10`);⑤ 被移集合 → **`client-modules/src/shared.ts`**(`map/vertex.ts:25` / `map/element.ts:5` / `map/renderer.ts:53` / `map/extension/door.ts:9`);⑥ 被移集合 → **`@user/client-base`(自包引用)**(`map/extension/hero.ts:16` / `map/moving.ts:3` / `map/renderer.ts:13` / `map/types.ts:12` / `map/vertex.ts:28`);⑦ `map/extension/*` → `map/types`(`extension/{door.ts:7,hero.ts:13,manager.ts:8,types.ts:4,text.ts:8}`)。**每行须含「导入处 `文件:行`」+「被导入符号的声明 / barrel `文件:行`」两个锚点(`#04-10-A-09` 为零命中证据行,按行类型规则带 `[证据行]` 标记 + `git grep` 证据、豁免 ≥2 计数)。**"
|
||||
- "**B 类(外部导入点)把移出集合之外的每一处 importer 枚举到 `file:line`**:至少覆盖 ① `client-modules/src/types.ts:2`(`./render/map`);② `client-modules/src/client.ts:25`(`./render/map`);③ `client-modules/src/render/index.tsx:5,45,46`(`./elements` / `./components`);④ `render/ui/` **8** 个文件的 **11** 处 `../components` 导入(`main.tsx:9` / `save.tsx:16` / `settings.tsx:16,21` / `statistics.tsx:8` / `statusBar.tsx:3` / `title.tsx:31` / `viewmap.tsx:26,29` / `toolbar.tsx:13,19`);⑤ `render/utils/saves.ts:2`(`../components`);⑥ `render/utils/index.ts:1`(`export * from './layout'`——barrel 引用被移文件);⑦ `fallback/ui.ts:2`(深层导入 `../render/components/tip`);⑧ 其它 monorepo 包经 `@user/client-modules` 公共面**间接**依赖(`entry-client/src/create.ts:10,27`、`entry-data/src/mota.ts:11,32`、`packages/legacy-ui/src/preset/ui.ts:86,96,105`);⑨ 对照扫描的机器证据:`git grep -n -F \"render/components\"` / `-F \"render/elements\"` / `-F \"render/map\"`(同限 `packages` 与 `src`)在 `packages-user` 之外**零命中**。"
|
||||
- "**C 类(barrel 与导出面)逐个登记并给出「现状导出 → 移出后是否断链」的判定**:`render/components/index.ts`(12 条 `export *`)、`render/elements/index.ts`(`createElements()` + `export * from './cache' | './misc' | './props'`,同时 import `../map` 与 `../renderer`)、`render/map/index.ts`(`export * from './extension'` + 9 条)、`render/index.tsx:45,46,51`(`export * from './components' | './elements' | './renderer'`)、`render/utils/index.ts:1`(`export * from './layout'`,**移出即断链**)、`client-modules/src/index.ts:15`(`export * from './render'`——把被移集合再导出给 `@user/client-modules` 消费者)、`client-base/src/index.ts`(现行 `export * from './load' | './material' | './save' | './types'`)。**C 行不得把「是否新增 barrel / 如何补位」写成结论**(属 F 类、由用户裁定)。"
|
||||
- "**D 类(分层与循环依赖风险)非空且逐条给两个锚点**:① 移入后 `client-base` 反向依赖 `client-modules`——`client-modules/src/shared.ts`(A 类 4 处);② 同向——`render/renderer`(3 处);③ 同向——`render/use.ts`(5 处,且 `use.ts:2` 自身 import `../weather`);④ 同向——`render/utils`(1 处);⑤ 自包引用——`@user/client-base` 的 5 处;⑥ `package.json` 依赖缺口——`client-base/package.json:3-9` 现行只声明 `@motajs/audio` / `@motajs/render` / `@motajs/client-base` / `@user/data-base` / `@user/data-state`,而被移集合还用到 `@motajs/render-vue`(12 个组件 + `elements/props.ts:1`)、`@motajs/system`、`@motajs/common`(`elements/index.ts:1`)、`@user/data-common`(`map/renderer.ts:38` / `map/vertex.ts:2` / `map/extension/{hero.ts:11,manager.ts:1,types.ts:2}`);⑦ 反向依赖**现状**机器证据——`git grep -n \"client-modules\" -- packages-user/client-base` 规划日退出码 1(当前零命中),即该风险由本次移植**引入**;⑧ shader 的 `?raw` 导入(`map/renderer.ts:43-46`,`./shader/{map,back}.{vert,frag}?raw`)在换包后是否仍被构建链处理;⑨ `dev.md` 的单向依赖 / 双端分离规则对照。**D 类不得自拟解耦方案(不得写「应下沉 / 应抽类型 / 应保留跨包依赖」),只登记风险与机器证据。**"
|
||||
- "**D 类(分层与循环依赖风险)非空且逐条给两个锚点**:① 移入后 `client-base` 反向依赖 `client-modules`——`client-modules/src/shared.ts`(A 类 4 处);② 同向——`render/renderer`(3 处);③ 同向——`render/use.ts`(5 处;`render/use.ts` 自身**无**相对导入,只 import 外部包与 `@user/data-base` 的 `loading`);④ 同向——`render/utils`(1 处);另记 `render/utils/use.ts:2` 自身 import `../weather`(`../weather` 的实际导入处,**不在** `render/use.ts`);⑤ 自包引用——`@user/client-base` 的 5 处;⑥ `package.json` 依赖缺口——`client-base/package.json:3-9` 现行只声明 `@motajs/audio` / `@motajs/render` / `@motajs/client-base` / `@user/data-base` / `@user/data-state`,而被移集合还用到 `@motajs/render-vue`(12 个组件 + `elements/props.ts:1`)、`@motajs/system`、`@motajs/common`(`elements/index.ts:1`)、`@user/data-common`(`map/renderer.ts:38` / `map/vertex.ts:2` / `map/extension/{hero.ts:11,manager.ts:1,types.ts:2}`);⑦ 反向依赖**现状**机器证据——`git grep -n \"client-modules\" -- packages-user/client-base` 规划日退出码 1(当前零命中),即该风险由本次移植**引入**;⑧ shader 的 `?raw` 导入(`map/renderer.ts:43-46`,`./shader/{map,back}.{vert,frag}?raw`)在换包后是否仍被构建链处理;⑨ `dev.md` 的单向依赖 / 双端分离规则对照。**D 类不得自拟解耦方案(不得写「应下沉 / 应抽类型 / 应保留跨包依赖」),只登记风险与机器证据。**"
|
||||
- "**E 类(legacy 命中·仅报告)与 in-scope 严格分开**:标题下明写「本节仅报告:按 D-55 不考虑任何 legacy 内容,legacy 相关报错一律不管、不修、不登记为待办」。逐条登记被移集合内的 legacy 耦合事实——① `core.*` 命中(`components/choices.tsx:675,715,717,718,719,728,733,770,772,773,774,783,789`、`components/floorSelect.tsx:62,181`、`components/misc.tsx:312`、`components/textboxTyper.ts:906`、`components/thumbnail.tsx:75`、`components/tip.tsx:103`、`elements/cache.ts:11,87,89,131,151,202,206,393,469`、`elements/misc.ts:221,228`);② 全局 `loading` + `Mota.require('@user/data-base')`(`elements/cache.ts:491-492`、`elements/misc.ts:89-94,219-225`,D-14);③ `client.*` 在移出集合内 **0** 命中(须给机器证据命令与原样输出);④ `packages/` 与 `src/` 的对照扫描结论与命令;⑤ `render/elements/cache.ts` 的 legacy 贴图路径现状(对照 04-06 / 04-07 的 big-image 清退面)。"
|
||||
- "**F 类(未能从阅读确定·未猜测)非空且只登记不判定**,至少覆盖:① 目标文件名(`client-base/src/layout/layout.ts` 还是 `layout/index.ts`;`client-base/src/{components,elements,map}/index.ts` 是否沿用同名 barrel)——**命名须用户反馈并获同意后才能使用**(AGENTS.md);② `client-base/src/index.ts` 是否新增 `export * from './{components,elements,map,layout}'`(导出面是否扩张 / 如何补 `render/index.tsx` 的断链);③ 被移集合对留在 `client-modules` 的 `shared.ts` / `renderer` / `use.ts` / `render/utils` 的依赖如何解耦;④ `@user/client-base` 自包引用的改写方式;⑤ `render/utils/index.ts` 在 `layout.ts` 移出后的归属(D-54 明示 `utils/index.ts` 不移植 ⇒ 断链处置);⑥ `client-base/package.json` 的依赖缺口是否在第二步补齐(D-37 有先例,本步不裁定);⑦ shader `?raw` 在 `client-base` 构建链下是否仍可用;⑧ `packages/legacy-ui` 经 `Mota.require('@user/client-modules')` 运行时取 `mainRenderer` / `client` 的插件面影响(legacy);⑨ `render/elements/index.ts` 的 `createElements()` 注册点(`mainRenderer.registerElement(...)`)在 `client-base` 无渲染器实例时如何接线。**不得把本类任何一条写成错配、缺失、残留或待办。**"
|
||||
- "**第二步(移植实施)不被规划**:文档只清点、分类、定位、分组,**不含**移植方案、不含 import 重写方案、不含任何代码改动建议、不产出 `04-11-PLAN.md` 或任何新 `*-PLAN.md`;`## 处置` 明写「第一步只读清点完成;第二步(移植实施)待用户审阅本文件后另行规划」(D-51 / D-57)。"
|
||||
- "**REND-01 / REND-02 在本 run 后仍保持 Pending**:本计划只清点结构性重构(分层纠正)的影响面,既未实施移植,也未实施渲染端接口适配与移动端 / 桌面端双布局(见 assumptions 的两条 FLAGGED ASSUMPTION)。"
|
||||
- "**验证可运行且不臆造通过**:本计划的「运行结果」= 只读门禁(porcelain 基线逐条一致 + 用户 `04-CONTEXT.md` 未提交改动仍在)+ 静态内容门禁(10 节结构、被移集合 39 文件路径齐备、A–F 六类行数下限与关键词、每行 ≥2 个 `file:line` 锚点、F 类条数)+ 机器证据复验(`client-base` 对 `client-modules` 零反向引用、被移集合对 `ui`/`fx`/`weather` 零引用、`packages` / `src` 对 `render/(components|elements|map)` 零命中)+ 既有产物保护门禁(`04-01..04-09-*` 的 porcelain 为空)+ 计划文件范围门禁(phase 目录内不得出现 `04-11+`)+ CRLF 门禁 + 人工代码复核;本步为只读清点,**无运行时行为可观察**,故不得以任何无法运行的门禁冒充通过。"
|
||||
- "**验证可运行且不臆造通过**:本计划的「运行结果」= 只读门禁(porcelain 基线逐条一致 + 用户 `04-CONTEXT.md` 未提交改动仍在)+ 静态内容门禁(10 节结构、被移集合 39 文件路径齐备、A–F 六类行数下限与关键词、事实·基准行每行 ≥2 个完整 `文件:行` 锚点(`.json` / `.md` 基准也计)、证据行 `[证据行]` 标记与 `git grep` 机器证据、F 类条数)+ 机器证据复验(`client-base` 对 `client-modules` 零反向引用、被移集合对 `ui`/`fx`/`weather` 零引用、`packages` / `src` 对 `render/(components|elements|map)` 零命中)+ 既有产物保护门禁(`04-01..04-09-*` 的 porcelain 为空)+ 计划文件范围门禁(phase 目录内不得出现 `04-11+`)+ CRLF 门禁 + 人工代码复核;本步为只读清点,**无运行时行为可观察**,故不得以任何无法运行的门禁冒充通过。"
|
||||
artifacts:
|
||||
- path: .planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md
|
||||
provides: "渲染端结构性重构(通用内容由 `client-modules/src/render/` 迁往 `client-base/src/`,D-51..D-57)**第一步·只读影响台账**:元信息块 + 背景 / 方法 / 被移集合清单(39 文件,含各文件职责与目标落点)/ A 被移集合内部交叉引用 / B 外部导入点 / C barrel 与导出面 / D 分层与循环依赖风险 / E legacy 命中(仅报告)/ F 未能从阅读确定(未猜测)/ 处置;每行含文件或符号名 + 命中处 `file:line` + 目标锚点 `file:line` + 问题描述 + 影响 + 置信,供用户审阅后裁定第二步的移植方案与 import 重写集"
|
||||
provides: "渲染端结构性重构(通用内容由 `client-modules/src/render/` 迁往 `client-base/src/`,D-51..D-57)**第一步·只读影响台账**:元信息块 + 背景 / 方法 / 被移集合清单(39 文件,含各文件职责与目标落点)/ A 被移集合内部交叉引用 / B 外部导入点 / C barrel 与导出面 / D 分层与循环依赖风险 / E legacy 命中(仅报告)/ F 未能从阅读确定(未猜测)/ 处置;每行含文件或符号名 + 命中处 `文件:行` + 目标锚点 `文件:行` + 问题描述 + 影响 + 置信(事实·基准行 ≥2 个完整锚点;零命中 / 对照扫描证据行带 `[证据行]` 标记与 `git grep` 证据),供用户审阅后裁定第二步的移植方案与 import 重写集"
|
||||
key_links:
|
||||
- "`packages-user/client-modules/src/render/{components,elements,map}/` + `render/utils/layout.ts`(D-52 移植集合,规划日实测 **39** 文件)↔ `packages-user/client-base/src/{components,elements,map}/` + `packages-user/client-base/src/layout/`(D-53 目标布局,**不新建 `render/` 目录**)"
|
||||
- "`packages-user/client-modules/src/render/index.tsx:45,46,51`(留在 `client-modules` 的 `export * from './components' | './elements' | './renderer'`)↔ `packages-user/client-modules/src/index.ts:3,15`(`import { createGameRenderer, createRender } from './render'` 与 `export * from './render'`)↔ `@user/client-modules` 公共面的消费者(`entry-client/src/create.ts:10,27` / `entry-data/src/mota.ts:11,32` / `packages/legacy-ui/src/preset/ui.ts:86,96,105`)—— 移出后前两条断链,公共面收窄"
|
||||
- "`packages-user/client-modules/src/render/utils/index.ts:1`(`export * from './layout'`)↔ `packages-user/client-modules/src/render/utils/layout.ts`(唯一外部入口)—— `layout.ts` 移出而该 barrel 按 D-54 不移植 ⇒ 断链点,第二步必改"
|
||||
- "`packages-user/client-modules/src/shared.ts` ↔ `packages-user/client-modules/src/render/map/{vertex.ts:25,element.ts:5,renderer.ts:53}` 与 `render/map/extension/door.ts:9`(`../../shared` / `../../../shared`)—— 移入 `client-base` 后变成 `client-base` → `client-modules` **反向依赖**,违反 dev.md 单向依赖(D-57 明列的循环依赖风险)"
|
||||
- "`packages-user/client-modules/src/render/{renderer.ts,use.ts}` ↔ `render/elements/index.ts:3` / `render/components/{textboxTyper.ts:6,misc.tsx:14}` / `render/components/{choices.tsx:8,tip.tsx:4,scroll.tsx:31,input.tsx:14,misc.tsx:10}` —— 同上,反向依赖候选(共 8 处);`render/use.ts:2` 自身 import `../weather`,链条可能牵出 `ui` / `fx` / `weather`"
|
||||
- "`packages-user/client-modules/src/render/{renderer.ts,use.ts}` ↔ `render/elements/index.ts:3` / `render/components/{textboxTyper.ts:6,misc.tsx:14}` / `render/components/{choices.tsx:8,tip.tsx:4,scroll.tsx:31,input.tsx:14,misc.tsx:10}` —— 同上,反向依赖候选(共 8 处);`render/use.ts` 自身无相对导入(只 import 外部包与 `@user/data-base` 的 `loading`);`../weather` 的导入处为 `render/utils/use.ts:2`,与 `render/use.ts` 无关"
|
||||
- "`packages-user/client-base/package.json:3-9`(现行 deps:`@motajs/audio` / `@motajs/render` / `@motajs/client-base` / `@user/data-base` / `@user/data-state`)↔ 被移集合用到的 `@motajs/render-vue` / `@motajs/system` / `@motajs/common` / `@user/data-common` —— 依赖缺口,第二步若移植必须补声明(本步只登记,不得提出补声明或安装建议)"
|
||||
- "`packages-user/client-modules/src/render/map/renderer.ts:43-46`(`./shader/{map,back}.{vert,frag}?raw`)↔ `render/map/shader/*`(随集合移动,**相对路径不变**)—— `?raw` 由构建链处理,换包后是否仍成立属 F 类"
|
||||
- "`git status --porcelain -- packages packages-user src`(Task 1 步骤 (0a) 逐行记录,规划日实测 ` M packages-user/data-base/src/enemy/types.ts` 单条)↔ Task 1 / Task 3 门禁的逐条一致断言 + `.planning/phases/04-render-adaptation/04-CONTEXT.md` 未提交改动仍在的断言 ↔ 只读(生产代码零改动)与 D-56 证明"
|
||||
@ -54,7 +54,7 @@ must_haves:
|
||||
assumptions:
|
||||
- "**FLAGGED ASSUMPTION(specless fallback)— REND-01 edge unresolved:** 未提供 REND-01(渲染端适配新数据层接口)的验收边界;本计划**不发明**阈值,只交付结构性重构(分层纠正)第一步的只读影响台账(D-51 / D-57)。用户须在推进第二步与其余渲染适配前补齐 REND-01 的边界判据。"
|
||||
- "**FLAGGED ASSUMPTION(specless fallback)— REND-02 edge unresolved:** 未提供 REND-02(移动端与桌面端双布局)的验收边界;本计划不涉及双布局,也不发明其验收阈值。"
|
||||
- "**规划日实测数值与口径须用户在审阅时确认:** 规划日 2026-09-24 在 HEAD `3bc37b5 docs: 修正 types.ts 中关于录像参数的描述`(分支 `refine/data-client`)实测:移植集合共 **39** 文件(`components` 13 / `elements` 5 / `map` 20 = 顶层 10 + `extension` 6 + `shader` 4 / `utils/layout.ts` 1);A 类内部交叉引用 **8** 个方向 / 约 **30** 处 import;B 类外部导入点 **8** 个文件族(约 17 处)+ 3 个包间接依赖(`entry-client` / `entry-data` / `packages/legacy-ui`);C 类 barrel **7** 个节点;D 类风险 **9** 条;E 类 legacy 文件 **8** 个(`core.*` 约 **31** 处 + `loading` / `Mota.require` 3 处);F 类未确定 **9** 条。**执行日一律以当日实测为准**(行号可能因用户并发编辑漂移),任一与规划日不同即以当日实测写入文档并在 SUMMARY 说明差异,**不得按本计划的规划日数值硬写**。"
|
||||
- "**规划日实测数值与口径须用户在审阅时确认:** 规划日 2026-09-24 在 HEAD `3bc37b5 docs: 修正 types.ts 中关于录像参数的描述`(分支 `refine/data-client`)实测:移植集合共 **39** 文件(`components` 13 / `elements` 5 / `map` 20 = 顶层 10 + `extension` 6 + `shader` 4 / `utils/layout.ts` 1);A 类内部交叉引用 **8** 个方向 / 约 **30** 处 import;B 类外部导入点 **8** 个文件族(约 17 处)+ 3 个包间接依赖(`entry-client` / `entry-data` / `packages/legacy-ui`);C 类 barrel **7** 个节点;D 类风险 **9** 条;E 类 legacy 文件 **8** 个(`core.*` 约 **30** 处 + `loading` / `Mota.require` 3 处);F 类未确定 **9** 条。**执行日一律以当日实测为准**(行号可能因用户并发编辑漂移),任一与规划日不同即以当日实测写入文档并在 SUMMARY 说明差异,**不得按本计划的规划日数值硬写**。"
|
||||
- "**执行前必须复核(未确定项,不猜):** Task 1 步骤 (0a) 必须在动手前打开当日 HEAD 的工作树逐条核对:① `render/{components,elements,map}` 的三个目录文件清单与 `render/utils/layout.ts` 是否存在(数量与文件名,规划日 13 / 5 / 20 / 1);② A 类各方向的当日行号;③ B 类 importer 的当日行号与 `packages` / `src` 对照扫描结论;④ C 类各 barrel 的现行导出集合;⑤ D 类 `client-base/package.json` 现行 deps 与 `git grep -n \"client-modules\" -- packages-user/client-base` 的退出码;⑥ E 类 legacy 命中行号;⑦ `git status --porcelain -- packages packages-user src` 基线(含用户并发条目)。"
|
||||
- "**用户可能有执行日的并发未提交改动(D-56):** 规划日实测基线已含 ` M packages-user/data-base/src/enemy/types.ts`(用户正在改数据端 `data-base`);一律以 Task 1 步骤 (0a) 当日实测为基线(逐行原样记录,含 `.planning/phases/04-render-adaptation/04-CONTEXT.md` 的既有未提交改动——该路径不在集合内故不计入 porcellain 基线),**不得回滚 / 暂存 / 提交 / 修改**用户的任何未提交改动;若基线中出现其它 `packages` / `packages-user` / `src` 条目,属清点范围内的既有改动,须一并记录并原样保留。"
|
||||
- "**被移集合在清点期间可能继续变化:** 用户会同步修改其它文件(D-56),且 04-09 刚落地 `render/map/{vertex,renderer,extension/hero}.ts` 的 texture 适配;故行号与成员集合以**当日实测**为准,本计划的规划日行号仅作定位线索。"
|
||||
@ -83,11 +83,11 @@ Phase 4 第十个增量(用户裁定 2026-09-23 · D-51..D-57 **第一步**)
|
||||
1. **通用渲染内容放错层(D-51)**:`packages-user/client-modules/src/render/` 下的**通用内容**(`components` / `elements` / `map` 三个文件夹 + `utils/layout.ts`)本属渲染**系统层**,却放在实现层 / 交互层包 `client-modules` 中;`dev.md` 的双端分离要求 `@user/client-base`(系统层)承载渲染核心系统、`@user/client-modules`(实现层)只保留实现 / 交互内容。分层不纠正,后续 REND-01 / REND-02 的实现会持续往错误的一层堆。
|
||||
2. **移植面未知,不能直接动手(D-57)**:用户裁定走**两步**——第一步只读影响清点(产出影响台账文档),第二步移植实施待用户审阅后另行规划。没有第一手的范围台账就直接搬,会漏改外部导入点、漏发现「移入后反向依赖 `client-modules`」这类分层硬伤。
|
||||
3. **分层 / 循环依赖是硬红线(D-57)**:`client-base` 不得反向依赖 `client-modules`。规划日已实测到 4 个明确的反向依赖候选(`client-modules/src/shared.ts` 4 处、`render/renderer` 3 处、`render/use.ts` 5 处、`render/utils` 1 处)与 1 个自包引用(`@user/client-base` 5 处),必须在台账中逐条落到 `file:line`,让用户据以裁定第二步的解耦方式。
|
||||
4. **legacy 一律不考虑(D-55)**:本次大重构的目的就是删除 legacy。被移集合内仍有大量 `core.*`(约 31 处)与全局 `loading` / `Mota.require('@user/data-base')`(3 处)耦合;这些**只报告**,不得修复、不得登记为待办。
|
||||
4. **legacy 一律不考虑(D-55)**:本次大重构的目的就是删除 legacy。被移集合内仍有大量 `core.*`(约 30 处)与全局 `loading` / `Mota.require('@user/data-base')`(3 处)耦合;这些**只报告**,不得修复、不得登记为待办。
|
||||
5. **用户并发改动不可触碰(D-56)**:用户正在并发修改数据端(规划日基线已含 ` M packages-user/data-base/src/enemy/types.ts`);一律零触碰、零提交。
|
||||
6. **本步零命名变更**:只读清点不引入任何公共 / 受保护 / 私有成员或字段的命名变更,也不裁定目标文件名 / barrel 名(命名须先向用户反馈并获同意,AGENTS.md)。
|
||||
|
||||
**大致解决方案:** 只做**只读清点**,产出唯一交付物 `.planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md`。文档 10 节(外加 6 行元信息块):`## 背景` / `## 方法` / `## 被移集合清单(39 文件)` / `## A 被移集合内部交叉引用` / `## B 外部导入点` / `## C barrel 与导出面` / `## D 分层与循环依赖风险` / `## E legacy 命中(仅报告)` / `## F 未能从阅读确定(未猜测)` / `## 处置`。A–E 每节一张**固定列序**表 `| ID | 文件/符号 | 命中处(源) | 目标锚点 | 问题描述 | 影响 | 置信 |`,**每行至少两个 `file:line` 锚点**(源侧 + 目标 / 基准侧),一条记录只归一类、跨类拆条并互相引用;F 类逐条登记静态阅读无法定论项(只登记不判定)。
|
||||
**大致解决方案:** 只做**只读清点**,产出唯一交付物 `.planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md`。文档 10 节(外加 7 行元信息块):`## 背景` / `## 方法` / `## 被移集合清单(39 文件)` / `## A 被移集合内部交叉引用` / `## B 外部导入点` / `## C barrel 与导出面` / `## D 分层与循环依赖风险` / `## E legacy 命中(仅报告)` / `## F 未能从阅读确定(未猜测)` / `## 处置`。A–E 每节一张**固定列序**表 `| ID | 文件/符号 | 命中处(源) | 目标锚点 | 问题描述 | 影响 | 置信 |`,**锚点规则按行类型区分**:**事实行 / 基准行**每行 ≥2 个锚点,锚点写成 `文件:行`(续行 `:NN` 简写不计;识别正则接受 `.(tsx?|frag|vert|json|md):\d+`,故 `package.json` / `dev.md` / `04-CONTEXT.md` 等基准文件的 `文件:行` 同样计为锚点);**证据行**(零命中 / 对照扫描,仅 `#04-10-A-09` / `#04-10-B-09` / `#04-10-E-01` / `#04-10-E-04` / `#04-10-E-05` 五条)在其 ID 单元格后带 `[证据行]` 标记,改为必须携带机器证据命令(`git grep`)与原样结果、有真实锚点时至少 1 个,**豁免 ≥2 锚点计数**;一条记录只归一类、跨类拆条并互相引用;F 类逐条登记静态阅读无法定论项(只登记不判定)。
|
||||
|
||||
**分列规则(写死,防止类别互相冒充):**
|
||||
|
||||
@ -107,10 +107,10 @@ Phase 4 第十个增量(用户裁定 2026-09-23 · D-51..D-57 **第一步**)
|
||||
| 被移集合 | **39** 文件:`components` 13(含 `index.ts`)+ `elements` 5(含 `index.ts`)+ `map` 20(顶层 10 + `extension` 6 + `shader` 4)+ `utils/layout.ts` 1 |
|
||||
| 目标落点(D-53) | `client-base/src/{components,elements,map}/` + `client-base/src/layout/`;**不新建 `render/` 目录** |
|
||||
| A(内部交叉引用) | **8** 个方向 / 约 **30** 处:`components→elements` 3、`elements→map` 2、→`renderer` 3、→`use.ts` 5、→`client-modules/src/shared.ts` 4、→`@user/client-base`(自包)5、`extension/*→map/types` 5;另记「被移集合 → `ui`/`fx`/`weather` **0** 命中」的机器证据 |
|
||||
| B(外部导入点) | **8** 个文件族 / 约 **17** 处:`client.ts:25`、`types.ts:2`、`render/index.tsx:5,45,46`、`render/ui` 8 文件 10 处、`render/utils/saves.ts:2`、`render/utils/index.ts:1`、`fallback/ui.ts:2`;另 3 个包经 `@user/client-modules` 间接依赖(`entry-client/src/create.ts:10,27`、`entry-data/src/mota.ts:11,32`、`packages/legacy-ui/src/preset/ui.ts:86,96,105`);`packages` / `src` 对 `render/(components\|elements\|map)` **零命中** |
|
||||
| B(外部导入点) | **8** 个文件族 / 约 **17** 处:`client.ts:25`、`types.ts:2`、`render/index.tsx:5,45,46`、`render/ui` 8 文件 11 处、`render/utils/saves.ts:2`、`render/utils/index.ts:1`、`fallback/ui.ts:2`;另 3 个包经 `@user/client-modules` 间接依赖(`entry-client/src/create.ts:10,27`、`entry-data/src/mota.ts:11,32`、`packages/legacy-ui/src/preset/ui.ts:86,96,105`);`packages` / `src` 对 `render/(components\|elements\|map)` **零命中** |
|
||||
| C(barrel / 导出面) | **7** 个节点:`components/index.ts`(12 条)、`elements/index.ts`(`createElements` + 3 条)、`map/index.ts`(`extension` + 9 条)、`render/index.tsx:45,46,51`、`render/utils/index.ts:1`(**移出即断链**)、`client-modules/src/index.ts:15`、`client-base/src/index.ts`(4 条) |
|
||||
| D(分层 / 循环) | **9** 条:反向依赖候选 4 族(`shared.ts` / `renderer` / `use.ts` / `render/utils`,共 13 处)、自包引用 5 处、`client-base/package.json` 依赖缺口(缺 `@motajs/render-vue` / `@motajs/system` / `@motajs/common` / `@user/data-common`)、现状零反向引用机器证据(`git grep -n client-modules -- packages-user/client-base` 退出码 1)、`?raw` shader 4 处、`dev.md` 规则对照 |
|
||||
| E(legacy 仅报告) | **8** 个文件:`core.*` 约 **31** 处(`choices.tsx` 13 / `floorSelect.tsx` 2 / `misc.tsx` 1 / `textboxTyper.ts` 1 / `thumbnail.tsx` 1 / `tip.tsx` 1 / `elements/cache.ts` 9 / `elements/misc.ts` 2);`loading` + `Mota.require('@user/data-base')` 3 处(`elements/cache.ts:491`、`elements/misc.ts:89,219`);`client.*` 在移出集合内 **0** 命中(须给机器证据) |
|
||||
| E(legacy 仅报告) | **8** 个文件:`core.*` 约 **30** 处(`choices.tsx` 13 / `floorSelect.tsx` 2 / `misc.tsx` 1 / `textboxTyper.ts` 1 / `thumbnail.tsx` 1 / `tip.tsx` 1 / `elements/cache.ts` 9 / `elements/misc.ts` 2);`loading` + `Mota.require('@user/data-base')` 3 处(`elements/cache.ts:491`、`elements/misc.ts:89,219`);`client.*` 在移出集合内 **0** 命中(须给机器证据) |
|
||||
| F(未确定) | ≥ **9** 条(见 must_haves) |
|
||||
|
||||
**范围与硬边界:** 被查对象 = 移植集合(39 文件)与其全部 importer;基准 = 当日工作树(HEAD `3bc37b5`)与 `dev.md` 的单向依赖 / 双端分离规则、`packages-user/client-base/package.json`、`packages-user/client-modules/package.json`;`packages/` 与 `src/` **仅报告**;`client-base` 反向依赖 `client-modules` 的解耦方式由用户裁定(F 类);legacy 一律不考虑(D-55);用户并发改动零触碰(D-56)。生产源码零改动;本步不规划第二步。
|
||||
@ -134,7 +134,7 @@ Phase 4 第十个增量(用户裁定 2026-09-23 · D-51..D-57 **第一步**)
|
||||
| CONTEXT | D-57 | 第一步 = 只读影响清点,至少覆盖:被移文件清单 / 内部交叉引用 / 外部导入点(含其它 monorepo 包)/ barrel 导出现状 / `package.json` 依赖现状 / 分层与循环依赖风险(`client-base` 不得反向依赖 `client-modules`)/ legacy 命中 / 未确定项;生产代码零改动 | 04-10 | COVERED | 10 节结构与 A–F 六类一一对应:清单节 / A / B / C / D(含 `package.json`)/ E / F;Task 3 门禁逐项断言 |
|
||||
| CONTEXT | D-33 | 范围外一律不改;不追求解决全部类型错误 | 04-10 | COVERED(边界) | 本步零代码改动;`packages/` 与 `src/` 仅报告 |
|
||||
| CONTEXT | D-42 / D-49 | `client-base/src/material/` 归用户、AI 不得改;不考虑 legacy 兼容 | 04-10 | COVERED(边界) | 本步不触碰 `material/`;legacy 归 E 类只报告 |
|
||||
| CONTEXT | D-07 / D-09 | 记录精确到符号 + 所属文件;允许派只读子代理扫描 | 04-10 | COVERED(粒度) | 固定列序 + 每行 ≥2 个 `file:line` 锚点 + 门禁机器判定;Task 2 允许只读子代理回传事实表 |
|
||||
| CONTEXT | D-07 / D-09 | 记录精确到符号 + 所属文件;允许派只读子代理扫描 | 04-10 | COVERED(粒度) | 固定列序 + 事实·基准行每行 ≥2 个完整 `文件:行` 锚点(`.json` / `.md` 基准也计)+ 证据行 `[证据行]` 标记 + 门禁机器判定;Task 2 允许只读子代理回传事实表 |
|
||||
| CONTEXT | D-01..D-06, D-08, D-10..D-32, D-34..D-50 | 前序决策与已执行增量 | 04-01..04-09 | COVERED(前序计划) | 已由 04-01..04-09 落地;04-09 = texture 接口适应第二步(`status: complete`) |
|
||||
| CONTEXT | Deferred Ideas | 阶段 4 后续步骤(移植实施、适配实施、双布局);`packages` 全部、`entry-client`、`legacy-plugin-*`、`data-fallback` | — | DEFERRED | 未写入任何任务;`packages/` 仅作 E 类对照扫描 |
|
||||
|
||||
@ -191,9 +191,9 @@ Phase 4 第十个增量(用户裁定 2026-09-23 · D-51..D-57 **第一步**)
|
||||
- **D-56 用户并发改动**:不得触碰、不得提交用户的任何并发改动(规划日基线已含 ` M packages-user/data-base/src/enemy/types.ts`)。
|
||||
- **D-57 第一步交付物**:只读影响台账,至少覆盖被移文件清单 / 内部交叉引用 / 外部导入点(含其它 monorepo 包)/ barrel 导出现状 / `package.json` 依赖现状 / 分层与循环依赖风险(`client-base` 不得反向依赖 `client-modules`)/ legacy 命中 / 未确定项;生产代码零改动。
|
||||
|
||||
③ **规划日实测的影响面(2026-09-24,HEAD `3bc37b5`,分支 `refine/data-client`;执行日以当日实测为准)**:A 类内部交叉引用 **8** 个方向(约 30 处)——`components→elements` 3(`tip.tsx` / `textbox.tsx` / `textboxTyper.ts`)、`elements→map` 2(`elements/index.ts` / `elements/props.ts`)、→ 留在 `render/` 的 `renderer` 3、→ 留在 `render/` 的 `use.ts` 5、→ `client-modules/src/shared.ts` 4(`map/vertex.ts` / `map/element.ts` / `map/renderer.ts` / `map/extension/door.ts`)、→ `@user/client-base` 自包引用 5、`map/extension/*→map/types` 5;另记「被移集合 → `ui`/`fx`/`weather` **0** 命中」的机器证据。B 类外部导入点 **8** 个文件族(约 17 处)——`client-modules/src/{client.ts:25,types.ts:2}`、`render/index.tsx:5,45,46`、`render/ui` 8 文件 10 处、`render/utils/saves.ts:2`、`render/utils/index.ts:1`(barrel 引用被移文件)、`fallback/ui.ts:2`;另有 3 个包经 `@user/client-modules` 公共面间接依赖(`entry-client/src/create.ts:10,27`、`entry-data/src/mota.ts:11,32`、`packages/legacy-ui/src/preset/ui.ts:86,96,105`);`packages/` 与 `src/` 对 `render/components|elements|map` **零命中**。C 类 barrel **7** 个节点(`components/index.ts` 12 条 / `elements/index.ts` `createElements` + 3 条 / `map/index.ts` `extension` + 9 条 / `render/index.tsx:45,46,51` / `render/utils/index.ts:1` 移出即断链 / `client-modules/src/index.ts:15` / `client-base/src/index.ts` 4 条)。D 类风险 **9** 条(反向依赖候选 4 族共 13 处、自包引用 5 处、`client-base/package.json` 依赖缺口:缺 `@motajs/render-vue` / `@motajs/system` / `@motajs/common` / `@user/data-common`、现状零反向引用机器证据、`?raw` shader 4 处、`dev.md` 规则对照)。E 类 legacy **8** 个文件(`core.*` 约 31 处;`loading` / `Mota.require('@user/data-base')` 3 处;`client.*` 0 命中)。F 类未确定 ≥ **9** 条。
|
||||
③ **规划日实测的影响面(2026-09-24,HEAD `3bc37b5`,分支 `refine/data-client`;执行日以当日实测为准)**:A 类内部交叉引用 **8** 个方向(约 30 处)——`components→elements` 3(`tip.tsx` / `textbox.tsx` / `textboxTyper.ts`)、`elements→map` 2(`elements/index.ts` / `elements/props.ts`)、→ 留在 `render/` 的 `renderer` 3、→ 留在 `render/` 的 `use.ts` 5、→ `client-modules/src/shared.ts` 4(`map/vertex.ts` / `map/element.ts` / `map/renderer.ts` / `map/extension/door.ts`)、→ `@user/client-base` 自包引用 5、`map/extension/*→map/types` 5;另记「被移集合 → `ui`/`fx`/`weather` **0** 命中」的机器证据。B 类外部导入点 **8** 个文件族(约 17 处)——`client-modules/src/{client.ts:25,types.ts:2}`、`render/index.tsx:5,45,46`、`render/ui` 8 文件 11 处、`render/utils/saves.ts:2`、`render/utils/index.ts:1`(barrel 引用被移文件)、`fallback/ui.ts:2`;另有 3 个包经 `@user/client-modules` 公共面间接依赖(`entry-client/src/create.ts:10,27`、`entry-data/src/mota.ts:11,32`、`packages/legacy-ui/src/preset/ui.ts:86,96,105`);`packages/` 与 `src/` 对 `render/components|elements|map` **零命中**。C 类 barrel **7** 个节点(`components/index.ts` 12 条 / `elements/index.ts` `createElements` + 3 条 / `map/index.ts` `extension` + 9 条 / `render/index.tsx:45,46,51` / `render/utils/index.ts:1` 移出即断链 / `client-modules/src/index.ts:15` / `client-base/src/index.ts` 4 条)。D 类风险 **9** 条(反向依赖候选 4 族共 13 处、自包引用 5 处、`client-base/package.json` 依赖缺口:缺 `@motajs/render-vue` / `@motajs/system` / `@motajs/common` / `@user/data-common`、现状零反向引用机器证据、`?raw` shader 4 处、`dev.md` 规则对照)。E 类 legacy **8** 个文件(`core.*` 约 30 处;`loading` / `Mota.require('@user/data-base')` 3 处;`client.*` 0 命中)。F 类未确定 ≥ **9** 条。
|
||||
|
||||
④ **大致解决方案**:只读清点,唯一交付物 `.planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md`;10 节结构(`## 背景` / `## 方法` / `## 被移集合清单(39 文件)` / `## A 被移集合内部交叉引用` / `## B 外部导入点` / `## C barrel 与导出面` / `## D 分层与循环依赖风险` / `## E legacy 命中(仅报告)` / `## F 未能从阅读确定(未猜测)` / `## 处置`)+ 6 行元信息块;A–E 每节固定列序表(`ID | 文件/符号 | 命中处(源) | 目标锚点 | 问题描述 | 影响 | 置信`),**每行 ≥2 个 `file:line` 锚点**;**分列规则**:A = 被移集合内部交叉引用、B = 外部导入点、C = barrel 与导出面、D = 分层与循环依赖风险(含 `package.json` 依赖现状)、E = legacy 命中(仅报告)、F 类只登记不判定。重型整文件读取可按 **D-09** 派**只读**子代理(仅回传事实表,不得写文件)。
|
||||
④ **大致解决方案**:只读清点,唯一交付物 `.planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md`;10 节结构(`## 背景` / `## 方法` / `## 被移集合清单(39 文件)` / `## A 被移集合内部交叉引用` / `## B 外部导入点` / `## C barrel 与导出面` / `## D 分层与循环依赖风险` / `## E legacy 命中(仅报告)` / `## F 未能从阅读确定(未猜测)` / `## 处置`)+ 7 行元信息块;A–E 每节固定列序表(`ID | 文件/符号 | 命中处(源) | 目标锚点 | 问题描述 | 影响 | 置信`),**事实·基准行每行 ≥2 个完整 `文件:行` 锚点(`.json` / `.md` 基准也计),零命中 / 对照扫描证据行带 `[证据行]` 标记 + `git grep` 证据并豁免 ≥2 计数**;**分列规则**:A = 被移集合内部交叉引用、B = 外部导入点、C = barrel 与导出面、D = 分层与循环依赖风险(含 `package.json` 依赖现状)、E = legacy 命中(仅报告)、F 类只登记不判定。重型整文件读取可按 **D-09** 派**只读**子代理(仅回传事实表,不得写文件)。
|
||||
|
||||
⑤ **范围与硬边界**:被查 = 移植集合 39 文件与其全部 importer;基准 = 当日工作树 + `dev.md` 单向依赖 / 双端分离规则 + 两个包的 `package.json`;`packages/` 与 `src/` 命中**仅报告、不修改**;**D-55**:legacy 一律只报告,不修、不登记为待办;**D-56**:用户并发改动零触碰。**生产源码零改动**;唯一写入为上述交付文档(外加本 PLAN 与 `04-10-SUMMARY.md` 两份簿记)。
|
||||
|
||||
@ -201,7 +201,7 @@ Phase 4 第十个增量(用户裁定 2026-09-23 · D-51..D-57 **第一步**)
|
||||
|
||||
⑦ **计划号与 wave(须原样告知)**:本计划为 **04-10**(第十个增量),`wave: 9`,`depends_on` 列 `04-01`..`04-09`;phase 目录内既有 `04-01`..`04-09` 的 `*-PLAN.md` 与 `*-SUMMARY.md` **一律不得改写 / 覆盖 / 改号**。
|
||||
|
||||
⑧ **验证方式与只读证明(须原样告知)**:本步为只读清点,**无运行时行为可观察**。证明方式 = ①**只读门禁**:`git status --porcelain -- packages packages-user src` 在 Task 1 起始逐行记录(规划日实测单条 ` M packages-user/data-base/src/enemy/types.ts`),Task 1 / Task 3 断言其后逐条一致;②**静态内容门禁**:10 节结构、被移集合 **39** 文件路径逐条齐备、A–F 行数下限与关键词、每行 ≥2 个 `file:line` 锚点、F 类条数;③**机器证据复验**:`git grep -n -F "client-modules" -- packages-user/client-base` 零命中、`git grep -n -F "render/components"` / `-F "render/elements"` / `-F "render/map"`(同限 `packages` 与 `src`)在 `packages-user` 之外零命中、被移集合对 `ui`/`fx`/`weather` 零引用、`client.*` 在被移集合内零命中;④**既有产物保护 + 计划范围门禁**:`04-01`..`04-09` 的 `*-PLAN.md` / `*-SUMMARY.md` porcelain 为空;phase 目录内 `-PLAN.md` 仅 `04-01`..`04-10`;⑤**CRLF 门禁**;⑥**人工代码复核**。**不冒充任何无法运行的门禁。**
|
||||
⑧ **验证方式与只读证明(须原样告知)**:本步为只读清点,**无运行时行为可观察**。证明方式 = ①**只读门禁**:`git status --porcelain -- packages packages-user src` 在 Task 1 起始逐行记录(规划日实测单条 ` M packages-user/data-base/src/enemy/types.ts`),Task 1 / Task 3 断言其后逐条一致;②**静态内容门禁**:10 节结构、被移集合 **39** 文件路径逐条齐备、A–F 行数下限与关键词、事实·基准行每行 ≥2 个完整 `文件:行` 锚点(`.json` / `.md` 基准也计)、证据行 `[证据行]` 标记与 `git grep` 证据、F 类条数;③**机器证据复验**:`git grep -n -F "client-modules" -- packages-user/client-base` 零命中、`git grep -n -F "render/components"` / `-F "render/elements"` / `-F "render/map"`(同限 `packages` 与 `src`)在 `packages-user` 之外零命中、被移集合对 `ui`/`fx`/`weather` 零引用、`client.*` 在被移集合内零命中;④**既有产物保护 + 计划范围门禁**:`04-01`..`04-09` 的 `*-PLAN.md` / `*-SUMMARY.md` porcelain 为空;phase 目录内 `-PLAN.md` 仅 `04-01`..`04-10`;⑤**CRLF 门禁**;⑥**人工代码复核**。**不冒充任何无法运行的门禁。**
|
||||
|
||||
⑨ **第二步不被规划**:本 run **不含**移植方案、不含 import 重写方案、不产出 `04-11+`;第二步(移植实施)待用户审阅本清点文件后另行规划(D-57)。
|
||||
|
||||
@ -274,20 +274,20 @@ Phase 4 第十个增量(用户裁定 2026-09-23 · D-51..D-57 **第一步**)
|
||||
- **枚举面**:(a)**被移面** = 移植集合 39 文件(D-52);(b)**命中面** = 移出集合之外的全部 importer(`client-modules/src` 全量)与其它 monorepo 包(`entry-client` / `entry-data` / `packages/legacy-ui` 经 `@user/client-modules` 公共面的间接依赖),另对 `packages/` 与 `src/` 做**对照扫描**(只登记、不修改)。
|
||||
- **判定口径固定为六类**(A 被移集合内部交叉引用 / B 外部导入点 / C barrel 与导出面 / D 分层与循环依赖风险 / E legacy 命中(仅报告)/ F 未能从阅读确定),**一条记录只归一类**,跨类拆条并互相引用。
|
||||
- **分列规则写死**:A 记「集合内部互相 import + 集合 → 留在 `client-modules` 的模块(`shared.ts` / `render/renderer` / `render/use.ts` / `@user/client-base` 自包引用)」;B 记「集合之外的 importer(含其它 monorepo 包的间接依赖)」;C 记「barrel / 导出集合现状与移出后是否断链(**不裁定是否新增 barrel**)」;D 记「分层与循环依赖风险 + `package.json` 依赖现状(**只登记,不自拟解耦方案**)」;E 记「`core.*` / `loading` / `hook` / `Mota.require` 等 legacy 耦合(D-55 只报告)」;F 记「静态阅读不能定论(含全部命名问题)」。
|
||||
- **证据纪律**:每行含 `文件/符号 + 命中处 file:line + 目标锚点 file:line + 问题描述 + 影响 + 置信`,**每行至少两个锚点**;静态阅读不能定论者一律进 F 类,**不得写成错配 / 缺失 / 残留 / 待办**。
|
||||
- **证据纪律**:每行含 `文件/符号 + 命中处 file:line + 目标锚点 file:line + 问题描述 + 影响 + 置信`。**锚点规则按行类型区分**:**事实行 / 基准行**每行 ≥2 个 `文件:行`(必须写全文件名,续行 `:NN` 简写不计;识别正则接受 `.(tsx?|frag|vert|json|md):\d+`,因此 `packages-user/client-base/package.json:5`、`dev.md:10`、`04-CONTEXT.md:42` 这类基准锚点同样计数);**证据行**(仅限 `#04-10-A-09` / `#04-10-B-09` / `#04-10-E-01` / `#04-10-E-04` / `#04-10-E-05` 五条零命中 / 对照扫描行)在其 ID 单元格后带 `[证据行]` 标记,必须携带 `git grep` 命令与原样结果、有真实锚点时至少 1 个,豁免 ≥2 计数;**非上述五条的行带 `[证据行]` 标记即违规**(不得用它豁免事实行)。静态阅读不能定论者一律进 F 类,**不得写成错配 / 缺失 / 残留 / 待办**。
|
||||
- **只读子代理(D-09)**:重型整文件读取可派**只读**子代理(只回传事实表「文件 + `file:line` + 形态或签名」,**不得写文件、不得贴大段源码**),最终由主执行者按 `file:line` 切片复核。
|
||||
|
||||
(4) **写 `## 被移集合清单(39 文件)`**:四张子表 + 一行单文件 ——(i)`render/components/` **13** 个:`choices.tsx` / `floorSelect.tsx` / `icons.tsx` / `index.ts` / `input.tsx` / `list.tsx` / `misc.tsx` / `page.tsx` / `scroll.tsx` / `textbox.tsx` / `textboxTyper.ts` / `thumbnail.tsx` / `tip.tsx`;(ii)`render/elements/` **5** 个:`cache.ts` / `index.ts` / `misc.ts` / `props.ts` / `types.ts`;(iii)`render/map/` **20** 个:`block.ts` / `constant.ts` / `element.ts` / `index.ts` / `moving.ts` / `renderer.ts` / `status.ts` / `types.ts` / `vertex.ts` / `viewport.ts` + `extension/{door,hero,index,manager,text,types}.ts`(6)+ `shader/{back.frag,back.vert,map.frag,map.vert}`(4);(iv)`render/utils/layout.ts` **1**。每行含 `现路径 | 目标路径(按 D-53) | 职责(一句话,据当日阅读) | 备注`。**目标路径写法**:`components` / `elements` / `map` 三个文件夹内的文件按同名相对路径映射到 `packages-user/client-base/src/{components,elements,map}/…`;`layout.ts` 映射为 `packages-user/client-base/src/layout/…`(**具体文件名是否仍为 `layout.ts` 属 F 类,须写「命名待用户裁定」,不得拍板**)。同时写明「**不新建 `client-base/src/render/` 目录**」与「**本步不移动、不复制、不预建任何目标文件**」。
|
||||
|
||||
(5) **补齐 10 个二级标题**(`## 背景` / `## 方法` / `## 被移集合清单(39 文件)` 已在前几步写入,此处补齐其余 8 个占位,其后 Task 2 / Task 3 在同一骨架上横向补齐,不再改结构):`## A 被移集合内部交叉引用` / `## B 外部导入点` / `## C barrel 与导出面` / `## D 分层与循环依赖风险` / `## E legacy 命中(仅报告)` / `## F 未能从阅读确定(未猜测)` / `## 处置`。**每个类别标题下先写一行记录编号模板**(供后续横向补齐对齐):A 类 `#04-10-A-NN`、B 类 `#04-10-B-NN`、C 类 `#04-10-C-NN`、D 类 `#04-10-D-NN`、E 类 `#04-10-E-NN`,表头固定为 `| ID | 文件/符号 | 命中处(源) | 目标锚点 | 问题描述 | 影响 | 置信 |`;F 类条目形如 `- **#04-10-F-NN**:现象 + 为什么读不出来 + 需要用户裁决的点`。模板行用 `NN` 占位、不含数字,故不计入任何行数门禁。
|
||||
(5) **补齐至 10 个二级标题**(`## 背景` / `## 方法` / `## 被移集合清单(39 文件)` 已在前几步写入,此处补齐其余 7 个占位,其后 Task 2 / Task 3 在同一骨架上横向补齐,不再改结构):`## A 被移集合内部交叉引用` / `## B 外部导入点` / `## C barrel 与导出面` / `## D 分层与循环依赖风险` / `## E legacy 命中(仅报告)` / `## F 未能从阅读确定(未猜测)` / `## 处置`。**每个类别标题下先写一行记录编号模板**(供后续横向补齐对齐):A 类 `#04-10-A-NN`、B 类 `#04-10-B-NN`、C 类 `#04-10-C-NN`、D 类 `#04-10-D-NN`、E 类 `#04-10-E-NN`,表头固定为 `| ID | 文件/符号 | 命中处(源) | 目标锚点 | 问题描述 | 影响 | 置信 |`;F 类条目形如 `- **#04-10-F-NN**:现象 + 为什么读不出来 + 需要用户裁决的点`。模板行用 `NN` 占位、不含数字,故不计入任何行数门禁。**证据行的 ID 单元格写成 `#04-10-{A..E}-NN [证据行]`**(门禁据此跳过该行的 ≥2 锚点计数并改验 `git grep` 证据;仅 `#04-10-A-09` / `#04-10-B-09` / `#04-10-E-01` / `#04-10-E-04` / `#04-10-E-05` 五条可带此标记)。
|
||||
|
||||
(6) **端到端切片:`render/utils/layout.ts` 一条线贯穿 A–F 六节(本任务唯一实测清点对象)**——这是本 tracer 的「一条路径走通全部层」:
|
||||
- **清单节**:已在 (4) 中登记 `render/utils/layout.ts` → `client-base/src/layout/`(文件名待裁定)。
|
||||
- **A 类 `#04-10-A-01`**:集合**内部**无对 `layout.ts` 的 import(须给机器证据:`git grep -n "utils/layout" -- packages-user/client-modules/src` 的原样输出——规划日仅 `render/utils/index.ts:1`,即**集合之外**);锚点 = 命中处 `packages-user/client-modules/src/render/utils/index.ts:1` + 目标锚点 `packages-user/client-modules/src/render/utils/layout.ts:1`(文件首行)/ 其 `export` 声明行(按当日实测)。该行须明写「A 类本方向为 0 命中、证据如下」,**不得凭空造引用**。
|
||||
- **B 类 `#04-10-B-01`**:外部导入点 = `packages-user/client-modules/src/render/utils/index.ts:1`(`export * from './layout'`)—— `layout.ts` 的**唯一**外部入口;锚点 = 该行 + `layout.ts` 的声明行;影响 = 移出后该 barrel 断链(`render/utils/index.ts` 按 D-54 不移植,`render/ui/save.tsx:31` / `settings.tsx:20` / `title.tsx:35` 经 `../utils` 间接依赖它)。
|
||||
- **C 类 `#04-10-C-01`**:barrel 节点 = `render/utils/index.ts:1`(`export * from './layout'`)嵌在 `render/utils/index.ts:1-3`(另两条 `./saves` / `./use` 留在原地)中;现状 = 该 barrel 同时导出被移与非被移内容;判定 = **移出即断链**,第二步必须改指 `client-base`(**改指的具体写法属 F 类**)。该行与 B-01 交叉引用、不重复计数。
|
||||
- **D 类 `#04-10-D-01`**:分层风险 = `layout.ts` 自身只依赖 `@motajs/render`(`layout.ts:1`;`packages-user/client-base/package.json:5` 已声明该依赖)⇒ **本文件不引入新的依赖缺口**;但若 `render/utils/index.ts` 为保持导出面而反向 import `@user/client-base`,则该方向为 `client-modules → client-base`(与 D 类其它条目的反向风险相反,属合法方向);锚点 = `packages-user/client-modules/src/render/utils/layout.ts:1` + `packages-user/client-base/package.json:5`。
|
||||
- **E 类 `#04-10-E-01`**:legacy 命中 = `layout.ts` 内**零** legacy 命中(须给当日实测证据:打开整文件 + 执行 `git grep -n -F "core."` / `-F "hook"` / `-F "loading"` / `-F "Mota.require"`(同限 `packages-user/client-modules/src/render/utils/layout.ts`)四个**独立**检索与原样输出;规划日为无输出 / 退出码 1)。**只报告**(D-55)。
|
||||
- **A 类 `#04-10-A-01`**:集合**内部**无对 `layout.ts` 的 import(须给机器证据:`git grep -n -F "./layout" -- packages-user/client-modules/src` 的原样输出——规划日仅 `render/utils/index.ts:1`,即**集合之外**);锚点 = 命中处 `packages-user/client-modules/src/render/utils/index.ts:1` + 目标锚点 `packages-user/client-modules/src/render/utils/layout.ts:1`(文件首行)/ 其 `export` 声明行(按当日实测)。该行须明写「A 类本方向为 0 命中、证据如下」,**不得凭空造引用**。
|
||||
- **B 类 `#04-10-B-01`**:外部导入点 = `packages-user/client-modules/src/render/utils/index.ts:1`(`export * from './layout'`)—— `layout.ts` 的**唯一**外部入口;锚点 = `packages-user/client-modules/src/render/utils/index.ts:1` + `packages-user/client-modules/src/render/utils/layout.ts` 的声明行(写成完整 `文件:行`,如 `packages-user/client-modules/src/render/utils/layout.ts:3`);影响 = 移出后该 barrel 断链(`render/utils/index.ts` 按 D-54 不移植,`render/ui/save.tsx:31` / `settings.tsx:20` / `title.tsx:35` 经 `../utils` 间接依赖它)。
|
||||
- **C 类 `#04-10-C-01`**:barrel 节点 = `render/utils/index.ts:1`(`export * from './layout'`)嵌在 `render/utils/index.ts:1-3`(另两条 `./saves` / `./use` 留在原地)中;现状 = 该 barrel 同时导出被移与非被移内容;判定 = **移出即断链**,第二步必须改指 `client-base`(**改指的具体写法属 F 类**);目标锚点 = `packages-user/client-modules/src/render/utils/layout.ts` 的声明行(写成完整 `文件:行`)。该行与 B-01 交叉引用、不重复计数。
|
||||
- **D 类 `#04-10-D-01`**:分层风险 = `layout.ts` 自身只依赖 `@motajs/render`(`layout.ts:1`;`packages-user/client-base/package.json:5` 已声明该依赖)⇒ **本文件不引入新的依赖缺口**;但若 `render/utils/index.ts` 为保持导出面而反向 import `@user/client-base`,则该方向为 `client-modules → client-base`(与 D 类其它条目的反向风险相反,属合法方向);锚点 = `packages-user/client-modules/src/render/utils/layout.ts:1` + `packages-user/client-base/package.json:5`(本行为**基准行**:两个锚点均计入——`package.json` 的 `文件:行` 由锚点识别正则接受——满足 ≥2 锚点门禁)。
|
||||
- **E 类 `#04-10-E-01 [证据行]`**:legacy 命中 = `layout.ts` 内**零** legacy 命中(须给当日实测证据:打开整文件 + 执行 `git grep -n -F "core."` / `-F "hook"` / `-F "loading"` / `-F "Mota.require"`(同限 `packages-user/client-modules/src/render/utils/layout.ts`)四个**独立**检索与原样输出;规划日为无输出 / 退出码 1)。**本行为零命中证据行(带 `[证据行]` 标记,豁免 ≥2 锚点计数),唯一真实锚点 = `packages-user/client-modules/src/render/utils/layout.ts:1`;须携带上述 `git grep` 命令与原样结果。只报告**(D-55)。
|
||||
- **F 类 `#04-10-F-01`**:目标文件名未确定(`client-base/src/layout/layout.ts` 还是 `client-base/src/layout/index.ts`;D-53 只定「单独开 `layout/` 文件夹」);**命名须先向用户反馈并获同意后才可使用**(AGENTS.md)。另写 `#04-10-F-02`:`render/utils/index.ts` 在 `layout.ts` 移出后的归属(D-54 明示 `utils/index.ts` 不移植 ⇒ 断链处置未裁定)。
|
||||
- 其余 A–F 行由 Task 2 / Task 3 横向补齐;本任务的切片**必须六节各有一行**,以便门禁先验通结构。
|
||||
|
||||
@ -299,11 +299,11 @@ Phase 4 第十个增量(用户裁定 2026-09-23 · D-51..D-57 **第一步**)
|
||||
<!-- plan-criteria-allow: R4 - 本任务验证块内的竖线字符全部位于 node 程序的正则分支 / 数组字面量中,不是 shell 管道;所有 git 命令均由 node 的 execSync 调用并在 JS 内捕获 stdout 与 exit status 后自行判定,不经 shell 管道传递状态 -->
|
||||
<verify>
|
||||
<automated>node -e "const fs=require('fs');const p='.planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md';const t=fs.readFileSync(p,'utf8');const heads=(t.match(/^## /gm)||[]).length;if(heads!==10){console.error('HEADING COUNT '+heads);process.exit(1)}const need=['## A ','## B ','## C ','## D ','## E ','## F ','## \u5904\u7f6e'];const miss=need.filter(h=>t.indexOf(h)<0);if(miss.length>0){console.error('MISSING HEADINGS '+miss.join(' ; '));process.exit(1)}if(t.indexOf('\u53ea\u8bfb\u8d77\u59cb\u57fa\u7ebf')<0){console.error('MISSING READONLY BASELINE');process.exit(1)}if(!/\b[0-9a-f]{7,40}\b/i.test(t)){console.error('MISSING BASELINE COMMIT');process.exit(1)}console.log('OK headings '+heads)"</automated>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "HEADING COUNT" / "MISSING HEADINGS" / "MISSING READONLY BASELINE" / "MISSING BASELINE COMMIT"(二级标题数不等于 11,或 A–F 与 `## 处置` 任一缺失,或 `## 方法` 未记录只读起始基线 / 元信息块未登记基准 HEAD)</fails_when>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "HEADING COUNT" / "MISSING HEADINGS" / "MISSING READONLY BASELINE" / "MISSING BASELINE COMMIT"(二级标题数不等于 10,或 A–F 与 `## 处置` 任一缺失,或 `## 方法` 未记录只读起始基线 / 元信息块未登记基准 HEAD)</fails_when>
|
||||
<automated>node -e "const fs=require('fs');const t=fs.readFileSync('.planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md','utf8');const f=['components/choices.tsx','components/floorSelect.tsx','components/icons.tsx','components/index.ts','components/input.tsx','components/list.tsx','components/misc.tsx','components/page.tsx','components/scroll.tsx','components/textbox.tsx','components/textboxTyper.ts','components/thumbnail.tsx','components/tip.tsx','elements/cache.ts','elements/index.ts','elements/misc.ts','elements/props.ts','elements/types.ts','map/block.ts','map/constant.ts','map/element.ts','map/index.ts','map/moving.ts','map/renderer.ts','map/status.ts','map/types.ts','map/vertex.ts','map/viewport.ts','map/extension/door.ts','map/extension/hero.ts','map/extension/index.ts','map/extension/manager.ts','map/extension/text.ts','map/extension/types.ts','map/shader/back.frag','map/shader/back.vert','map/shader/map.frag','map/shader/map.vert','utils/layout.ts'];const miss=f.filter(x=>t.indexOf(x)<0);if(miss.length>0){console.error('MOVE-SET MISSING '+miss.length+' :: '+miss.join(' ; '));process.exit(1)}if(t.indexOf('client-base/src/')<0){console.error('MISSING TARGET LAYOUT');process.exit(1)}console.log('OK move-set files '+f.length)"</automated>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "MOVE-SET MISSING" / "MISSING TARGET LAYOUT"(39 个被移文件未逐条列出 D-52 的全部路径,或未写明 D-53 的目标落点)</fails_when>
|
||||
<automated>node -e "const fs=require('fs');const t=fs.readFileSync('.planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md','utf8');const seg=h=>{const i=t.indexOf(h);if(i<0)return '';const rest=t.slice(i+h.length);const j=rest.search(/\r?\n## /);return j<0?rest:rest.slice(0,j)};const p=[];for(const c of ['A','B','C','D','E']){const s=seg('## '+c+' ');if(!s){p.push('MISSING SECTION '+c);continue}const re=new RegExp('^\\|\\s*#04-10-'+c+'-\\d+\\s*\\|');const rows=s.split(/\r?\n/).filter(l=>re.test(l));if(rows.length<1)p.push('NO ROWS '+c);const bad=rows.filter(l=>((l.match(/[A-Za-z0-9_\-.\\/]+\.(tsx?|frag|vert):\d+/g)||[]).length<2));if(bad.length>0)p.push('ROW WITHOUT TWO-SIDED ANCHOR '+c+' '+bad.length)}const F=seg('## F ');if((F.match(/^- \*\*#04-10-F-\d+/gm)||[]).length<2)p.push('F ITEMS '+(F.match(/^- \*\*#04-10-F-\d+/gm)||[]).length);if(p.length>0){console.error('TRACER SLICE GATE FAILED :: '+p.join(' ;; '));process.exit(1)}console.log('OK tracer slice rows in A-E + F items')"</automated>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "TRACER SLICE GATE FAILED"(A–E 任一节无端到端切片行,或某行缺命中处 / 目标锚点之一(不足 2 个 `file:line` 锚点),或 F 类少于 2 条)</fails_when>
|
||||
<automated>node -e "const fs=require('fs');const t=fs.readFileSync('.planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md','utf8');const seg=h=>{const i=t.indexOf(h);if(i<0)return '';const rest=t.slice(i+h.length);const j=rest.search(/\r?\n## /);return j<0?rest:rest.slice(0,j)};const MK='\u8bc1\u636e\u884c';const EX={E:['01']};const p=[];for(const c of ['A','B','C','D','E']){const s=seg('## '+c+' ');if(!s){p.push('MISSING SECTION '+c);continue}const rows=s.split(/\r?\n/).filter(l=>new RegExp('^\\|\\s*#04-10-'+c+'-\\d+').test(l));if(rows.length<1)p.push('NO ROWS '+c);const ev=rows.filter(l=>l.indexOf(MK)>=0);const badEv=ev.filter(l=>!((EX[c]||[]).indexOf((l.match(/#04-10-[A-F]-(\d+)/)||[])[1])>=0)||l.indexOf('git grep')<0);if(badEv.length>0)p.push('BAD EVIDENCE ROW '+c+' '+badEv.length);const bad=rows.filter(l=>l.indexOf(MK)<0).filter(l=>((l.match(/[A-Za-z0-9_\-.\\/]+\.(tsx?|frag|vert|json|md):\d+/g)||[]).length<2));if(bad.length>0)p.push('ROW WITHOUT TWO-SIDED ANCHOR '+c+' '+bad.length)}const F=seg('## F ');if((F.match(/^- \*\*#04-10-F-\d+/gm)||[]).length<2)p.push('F ITEMS '+(F.match(/^- \*\*#04-10-F-\d+/gm)||[]).length);if(p.length>0){console.error('TRACER SLICE GATE FAILED :: '+p.join(' ;; '));process.exit(1)}console.log('OK tracer slice rows in A-E + F items')"</automated>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "TRACER SLICE GATE FAILED" / "BAD EVIDENCE ROW"(A–E 任一节无端到端切片行,或事实·基准行不足 2 个完整 `文件:行` 锚点(识别正则接受 `.(tsx?|frag|vert|json|md):\d+`),或证据行缺 `[证据行]` 标记 / `git grep` 机器证据,或五条白名单之外的 ID 带 `[证据行]` 标记,或 F 类少于 2 条)</fails_when>
|
||||
<automated>node -e "const fs=require('fs');const s=fs.readFileSync('.planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md','utf8');const lf=(s.match(/\n/g)||[]).length;const crlf=(s.match(/\r\n/g)||[]).length;if(lf!==crlf){console.error('NON-CRLF LINE ENDINGS '+(lf-crlf));process.exit(1)}console.log('OK CRLF lines '+crlf)"</automated>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "NON-CRLF LINE ENDINGS"(交付文档出现非 CRLF 换行,违反 dev.md「换行使用 CRLF 格式」)</fails_when>
|
||||
<automated>node -e "const fs=require('fs'),{execSync}=require('child_process');const t=fs.readFileSync('.planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md','utf8');const seg=h=>{const i=t.indexOf(h);if(i<0)return '';const rest=t.slice(i+h.length);const j=rest.search(/\r?\n## /);return j<0?rest:rest.slice(0,j)};const ms=seg('## \u65b9\u6cd5');if(ms.indexOf('\u53ea\u8bfb\u8d77\u59cb\u57fa\u7ebf')<0){console.error('READONLY BASELINE NOT RECORDED');process.exit(1)}const rec=(ms.match(/^[ MARCUD?!]{2} (?:packages|packages-user|src)[^\r\n]*/gm)||[]).map(s=>s.replace(/\s+$/,''));let raw='';try{raw=execSync('git status --porcelain -- packages packages-user src',{encoding:'utf8'})}catch(e){console.error('GIT STATUS FAILED '+(e.message||''));process.exit(1)}const out=raw.replace(/\s+$/,'');const cur=out.length>0?out.split(/\r?\n/).map(s=>s.replace(/\s+$/,'')):[];const extra=cur.filter(l=>rec.indexOf(l)<0);const gone=rec.filter(l=>cur.indexOf(l)<0);if(extra.length+gone.length>0){console.error('READONLY BASELINE CHANGED extra=['+extra.join(' ; ')+'] missing=['+gone.join(' ; ')+']');process.exit(1)}const actx=execSync('git status --porcelain -- .planning/phases/04-render-adaptation/04-CONTEXT.md',{encoding:'utf8'}).replace(/\s+$/,'');if(actx.length===0){console.error('USER CONTEXT EDIT DISAPPEARED (D-56)');process.exit(1)}console.log('OK read-only baseline verbatim entries '+cur.length)"</automated>
|
||||
@ -312,12 +312,12 @@ Phase 4 第十个增量(用户裁定 2026-09-23 · D-51..D-57 **第一步**)
|
||||
<fails_when>non-zero exit, 或 stderr 含 "LAYERING BASELINE NOT ZERO"(被移集合已 import `ui` / `fx` / `weather`,或 `client-base` 已引用 `client-modules`,或 `packages/` / `src/`(排除已登记的 `client-modules/src/fallback/ui.ts`)已命中被移集合目录 —— 说明移植已提前发生或清点范围判断有误)</fails_when>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- 交付文档存在于 `.planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md`,恰好 **11** 个二级标题,且含 `## A ` / `## B ` / `## C ` / `## D ` / `## E ` / `## F ` 与 `## 处置`
|
||||
- 交付文档存在于 `.planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md`,恰好 **10** 个二级标题,且含 `## A ` / `## B ` / `## C ` / `## D ` / `## E ` / `## F ` 与 `## 处置`
|
||||
- 元信息块齐备(日期 / 范围 / 性质 / 移植集合 / 目标布局 / 基准 / 下一步),且明写「只读、未修改生产代码、未引入命名变更」「不新建 `client-base/src/render/`」「本步不移动、不复制、不预建」
|
||||
- `## 方法` 含「只读起始基线」条目,**逐行原样**记录起始 `git status --porcelain -- packages packages-user src` 的输出(规划日单条 ` M packages-user/data-base/src/enemy/types.ts`);门禁断言记录条目与当前状态逐条一致,且用户的 `04-CONTEXT.md` 未提交改动仍在
|
||||
- `## 方法` 写死 A/B/C/D/E/F 六类判定口径与分列规则,并写明每行须含「命中处」与「目标锚点」两个 `file:line`
|
||||
- `## 方法` 写死 A/B/C/D/E/F 六类判定口径与分列规则,并写明行类型感知的锚点规则(事实·基准行 ≥2 个完整 `文件:行`,`.json` / `.md` 基准也计;证据行 `#04-10-A-09` / `B-09` / `E-01` / `E-04` / `E-05` 带 `[证据行]` 标记 + `git grep` 证据、豁免锚点计数;其余 ID 带标记即违规)
|
||||
- `## 被移集合清单(39 文件)` 逐条列出 D-52 的 **39** 个文件路径(`components` 13 / `elements` 5 / `map` 20 / `utils/layout.ts` 1),每条含目标路径与职责
|
||||
- A–F 六节各含至少 1 行 `render/utils/layout.ts` 端到端切片行(`#04-10-{A..E}-01` / `#04-10-F-01`),A–E 行各含 ≥2 个 `file:line` 锚点,F 类 ≥2 条
|
||||
- A–F 六节各含至少 1 行 `render/utils/layout.ts` 端到端切片行:`A-01` / `B-01` / `C-01` / `D-01` 各含 ≥2 个完整 `文件:行` 锚点(`D-01` 的第二锚点 `packages-user/client-base/package.json:5` 由锚点识别正则计入),`E-01` 为 `[证据行]` 证据行(带 `git grep` 证据、豁免 ≥2 计数),`F-01` / `F-02` ≥2 条
|
||||
- `## 处置` 初稿含「只读 / 零命名变更 / 第二步未规划 / legacy 仅报告 / 命名与解耦由用户裁定 / REND 保持 Pending」
|
||||
- 相对记录在 `## 方法` 的只读起始基线零变化;未修改任何生产源码;未预建 `client-base/src/{components,elements,map,layout}`;未新增计划文件;全文 CRLF;分层基线机器证据为零
|
||||
</acceptance_criteria>
|
||||
@ -337,7 +337,7 @@ Phase 4 第十个增量(用户裁定 2026-09-23 · D-51..D-57 **第一步**)
|
||||
- packages-user/client-modules/src/render/map/extension/{door.ts,hero.ts,manager.ts,types.ts,text.ts}(A 类:→ `../types`、→ `../../../shared`)
|
||||
- packages-user/client-modules/src/{client.ts,types.ts}(B 类:`./render/map` 的两处导入)
|
||||
- packages-user/client-modules/src/render/index.tsx(B / C 类:`:5` `./elements`、`:45,46,51` 的 `export *`)
|
||||
- packages-user/client-modules/src/render/ui/{main.tsx,save.tsx,settings.tsx,statistics.tsx,statusBar.tsx,title.tsx,toolbar.tsx,viewmap.tsx}(B 类:8 文件 10 处 `../components` 导入,含 `toolbar.tsx:13` 的 `../components/icons` 与 `:19` 的 `../components/misc` 深层导入)
|
||||
- packages-user/client-modules/src/render/ui/{main.tsx,save.tsx,settings.tsx,statistics.tsx,statusBar.tsx,title.tsx,toolbar.tsx,viewmap.tsx}(B 类:8 文件 11 处 `../components` 导入,含 `toolbar.tsx:13` 的 `../components/icons` 与 `:19` 的 `../components/misc` 深层导入)
|
||||
- packages-user/client-modules/src/render/utils/{saves.ts,index.ts}(B 类:`saves.ts:2` `../components`、`index.ts:1` `./layout`)
|
||||
- packages-user/client-modules/src/fallback/ui.ts:2(B 类:深层导入 `../render/components/tip` 的 `TipStore`)
|
||||
- packages-user/client-modules/src/index.ts(C 类:`:3` `import { createGameRenderer, createRender } from './render'`、`:15` `export * from './render'`)
|
||||
@ -346,36 +346,36 @@ Phase 4 第十个增量(用户裁定 2026-09-23 · D-51..D-57 **第一步**)
|
||||
- dev.md(「项目结构」单向依赖;barrel / 导出规则)
|
||||
</read_first>
|
||||
<action>
|
||||
(1) **A 类补齐(被移集合内部交叉引用)**:按固定列序表逐条写满,**每行含「导入处 `file:line`」+「被导入符号的声明 / barrel `file:line`」两个锚点;行内不得出现移植方案、import 重写写法或「应改为 X」**:
|
||||
(1) **A 类补齐(被移集合内部交叉引用)**:按固定列序表逐条写满,**事实行每行含「导入处 `文件:行`」+「被导入符号的声明 / barrel `文件:行`」两个完整锚点(`#04-10-A-09 [证据行]` 为零命中证据行,豁免 ≥2 计数);行内不得出现移植方案、import 重写写法或「应改为 X」**:
|
||||
- `#04-10-A-02`:`components → elements`(`../elements`)—— `tip.tsx:7`(`texture`)、`textbox.tsx:33`(`texture`)、`textboxTyper.ts:5`(`RenderableData` / `AutotileRenderable` / `texture`);目标锚点 = `render/elements/index.ts` 的 `export * from './cache' | './misc' | './props'`(规划日 `:45-47`,以当日实测为准)与各符号的声明文件行。
|
||||
- `#04-10-A-03`:`elements → map`(`../map`)—— `elements/index.ts:2`(`MapRenderItem`)、`elements/props.ts:4`(`IMapExtensionManager` / `IMapRenderer`);目标锚点 = `render/map/index.ts` 的 `export *` 行(规划日 `:1-11`)与 `render/map/types.ts` 的声明行。
|
||||
- `#04-10-A-04`:被移集合 → **留在 `render/` 顶层的 `renderer`**(`../renderer`)—— `elements/index.ts:3`(`mainRenderer` / `tagManager`)、`components/textboxTyper.ts:6`(`using`)、`components/misc.tsx:14`(`using`);目标锚点 = `render/renderer.ts` 的对应导出声明行(当日实测)。**须写明:该方向移入后即成为 `client-base` → `client-modules` 反向依赖候选**,并交叉引用 D 类同向条目。
|
||||
- `#04-10-A-05`:被移集合 → **留在 `render/` 的 `use.ts`**(`../use`)—— `components/choices.tsx:8`(`useKey`)、`components/tip.tsx:4`(`transitioned`)、`components/scroll.tsx:31`(`transitioned`)、`components/input.tsx:14`(`transitionedColor` / `useKey`)、`components/misc.tsx:10`(`transitioned`);目标锚点 = `render/use.ts` 的导出声明行(当日实测)。同上为反向依赖候选;`render/use.ts:2` 自身 import `../weather`,须一并登记(交叉引用 D 类)。
|
||||
- `#04-10-A-05`:被移集合 → **留在 `render/` 的 `use.ts`**(`../use`)—— `components/choices.tsx:8`(`useKey`)、`components/tip.tsx:4`(`transitioned`)、`components/scroll.tsx:31`(`transitioned`)、`components/input.tsx:14`(`transitionedColor` / `useKey`)、`components/misc.tsx:10`(`transitioned`);目标锚点 = `render/use.ts` 的导出声明行(当日实测)。同上为反向依赖候选;`render/use.ts` 自身**无**相对导入(实测只 import 外部包与 `@user/data-base` 的 `loading`);`../weather` 的导入处在 `render/utils/use.ts:2`(非本次移植集合),须一并登记(交叉引用 D 类)。
|
||||
- `#04-10-A-06`:被移集合 → **`client-modules/src/shared.ts`** —— `map/vertex.ts:25`、`map/element.ts:5`、`map/renderer.ts:53`(均 `../../shared`)、`map/extension/door.ts:9`(`../../../shared`);目标锚点 = `packages-user/client-modules/src/shared.ts` 的导出声明行(当日实测)。**该方向是 D 类反向依赖最硬的一条**(连包内常量都反向)。
|
||||
- `#04-10-A-07`:被移集合 → **`@user/client-base`(自包引用)** —— `map/extension/hero.ts:16`(`IMaterialFramedData`)、`map/moving.ts:3`(`IMaterialFramedData` / `ITextureManager`)、`map/renderer.ts:13`、`map/types.ts:12`、`map/vertex.ts:28`(均 `IMaterialFramedData`);目标锚点 = `packages-user/client-base/src/{material/types.ts,types.ts}` 的对应声明行与 `client-base/src/index.ts` 的 barrel(当日实测)。**移入后成为包内自引**,改写方式属 F 类(不得自拟)。
|
||||
- `#04-10-A-08`:`map/extension/* → map/types`(`../types`)—— `extension/door.ts:7`、`extension/hero.ts:13`、`extension/manager.ts:8`、`extension/types.ts:4`、`extension/text.ts:8`;目标锚点 = `render/map/types.ts` 的对应声明行(当日实测)。**集合内部引用,随集合整体移动、相对路径不变 ⇒ 无断链风险**(须写清这一判定)。
|
||||
- `#04-10-A-09`:**A 类零命中的机器证据(不许凭印象)** —— 被移集合内对 `ui` / `fx` / `weather` 的 import 为 **0** 处:分别执行 `git grep -n -F "../ui"`、`git grep -n -F "../fx"`、`git grep -n -F "../weather"`(限 `packages-user/client-modules/src/render/components`、`render/elements`、`render/map`、`render/utils/layout.ts`),逐条原样抄录输出(规划日三条均无输出 / 退出码 1)。**只登记命令与输出,不判定其含义。**
|
||||
- **A 类 `#04-10-A-09 [证据行]`**:**A 类零命中的机器证据(不许凭印象)** —— 被移集合内对 `ui` / `fx` / `weather` 的 import 为 **0** 处:分别执行 `git grep -n -F "../ui"`、`git grep -n -F "../fx"`、`git grep -n -F "../weather"`(限 `packages-user/client-modules/src/render/components`、`render/elements`、`render/map`、`render/utils/layout.ts`),逐条原样抄录输出(规划日三条均无输出 / 退出码 1)。**本行为零命中证据行(带 `[证据行]` 标记,豁免 ≥2 锚点计数),须携带上述 `git grep` 命令与原样结果;只登记命令与输出,不判定其含义。**
|
||||
- 每条 A 行只归 A 类;若同事实又属 B / C / D 类,**拆条并互相引用**(如 A-04 ↔ D 类、A-07 ↔ D 类),不得互相冒充。
|
||||
|
||||
(2) **B 类补齐(外部导入点)**:按固定列序表逐条写满,**每行含「importer `file:line`」+「被导入文件 / barrel `file:line` 或导出声明行」两个锚点;行内不得出现移植方案或重写写法**:
|
||||
(2) **B 类补齐(外部导入点)**:按固定列序表逐条写满,**事实行每行含「importer `文件:行`」+「被导入文件 / barrel `文件:行` 或导出声明行」两个完整锚点(`#04-10-B-09 [证据行]` 为对照扫描证据行,豁免 ≥2 计数);行内不得出现移植方案或重写写法**:
|
||||
- `#04-10-B-02`:`client-modules/src/types.ts:2`(`./render/map` 的 `IMapExtensionManager` / `IMapRenderer`)与 `client-modules/src/client.ts:25`(`./render/map`,多符号);目标锚点 = `render/map/index.ts` 的 `export *` 行与 `render/map/types.ts` 的声明行。
|
||||
- `#04-10-B-03`:`client-modules/src/render/index.tsx:5`(`import { createElements } from './elements'`)、`:45`(`export * from './components'`)、`:46`(`export * from './elements'`);目标锚点 = `render/components/index.ts:1-12` 与 `render/elements/index.ts`(`createElements` 声明行 + `:45-47`)。
|
||||
- `#04-10-B-04`:`render/ui/` **8** 文件 **10** 处 `../components` 导入 —— `main.tsx:9`(`Textbox` / `TextboxProps` / `Tip`)、`save.tsx:16`(`getConfirm` / `Page` / `PageExpose` / `Thumbnail`)、`settings.tsx:16`(多符号)与 `:21`(`getInput`)、`statistics.tsx:8`(`waitbox` / `ListPage` / `TextContent`)、`statusBar.tsx:3`(`TextContent`)、`title.tsx:31`(`ExitFullscreen` / `Fullscreen` / `SoundVolume`)、`viewmap.tsx:26`(`FloorSelector`)与 `:29`(`Tip` / `TipExpose`)、`toolbar.tsx:13`(`../components/icons`)与 `:19`(`../components/misc` 的 `Progress`);目标锚点 = 各符号的声明文件行(当日实测)。**深层导入(`components/icons` / `components/misc`)须单列标注**——浅层 barrel 改指覆盖不到深层路径。
|
||||
- `#04-10-B-04`:`render/ui/` **8** 文件 **11** 处 `../components` 导入 —— `main.tsx:9`(`Textbox` / `TextboxProps` / `Tip`)、`save.tsx:16`(`getConfirm` / `Page` / `PageExpose` / `Thumbnail`)、`settings.tsx:16`(多符号)与 `:21`(`getInput`)、`statistics.tsx:8`(`waitbox` / `ListPage` / `TextContent`)、`statusBar.tsx:3`(`TextContent`)、`title.tsx:31`(`ExitFullscreen` / `Fullscreen` / `SoundVolume`)、`viewmap.tsx:26`(`FloorSelector`)与 `:29`(`Tip` / `TipExpose`)、`toolbar.tsx:13`(`../components/icons`)与 `:19`(`../components/misc` 的 `Progress`);目标锚点 = 各符号的声明文件行(当日实测)。**深层导入(`components/icons` / `components/misc`)须单列标注**——浅层 barrel 改指覆盖不到深层路径。
|
||||
- `#04-10-B-05`:`render/utils/saves.ts:2`(`getConfirm` / `waitbox`,`../components`);目标锚点 = `render/components` 的导出集合行。**该文件按 D-54 不移植但依赖被移集合 ⇒ 第二步必改点**(须单列标注)。
|
||||
- `#04-10-B-06`:`render/utils/index.ts:1`(`export * from './layout'`);目标锚点 = `render/utils/layout.ts` 的声明行。**与 Task 1 已登记的 `#04-10-B-01` 为同一事实 ⇒ 本条只做交叉引用,不得重复计数 / 另起 ID**(若沿用 B-01 则在本行动写明「见 `#04-10-B-01`」)。
|
||||
- `#04-10-B-07`:`fallback/ui.ts:2`(深层导入 `../render/components/tip` 的 `TipStore`);目标锚点 = `render/components/tip.tsx` 的 `TipStore` 声明行。**该文件按 D-54 不移植(`fallback` 属实现层)⇒ 第二步必改点**(须单列标注)。
|
||||
- `#04-10-B-08`:**其它 monorepo 包经 `@user/client-modules` 公共面的间接依赖** —— `entry-client/src/create.ts:10`(`import * as ClientModules from '@user/client-modules'`)与 `:27`(`Mota.register('@user/client-modules', ClientModules)`)、`entry-data/src/mota.ts:11`(`import type * as ClientModules`)与 `:32`(类型映射)、`packages/legacy-ui/src/preset/ui.ts:86` / `:96`(`Mota.require('@user/client-modules').mainRenderer.setScale(...)`)/ `:105`(`Mota.require('@user/client-modules').client`);目标锚点 = `client-modules/src/index.ts:15`(`export * from './render'`)与被取符号的声明行。**须写明:这些包不直接 import 被移集合,但经 `render` 的再导出链间接暴露被移集合的公共符号;移出后该再导出链必须补位,否则公共面收窄**(是否属破坏、如何补位属 F 类 / 用户裁定)。
|
||||
- `#04-10-B-09`:**对照扫描(机器证据)** —— 分别执行 `git grep -n -F "render/components"`、`-F "render/elements"`、`-F "render/map"`(限 `packages` 与 `src`)并原样抄录输出;规划日仅 `packages-user/client-modules/src/fallback/ui.ts:2` 一条落在 `packages-user` 内,`packages/` 与 `src/` 对**被移集合源文件**零直接命中。**只登记输出与结论,不得为 `packages/` 与 `src/` 提修改建议。**
|
||||
- **B 类 `#04-10-B-09 [证据行]`**:**对照扫描(机器证据)** —— 分别执行 `git grep -n -F "render/components"`、`-F "render/elements"`、`-F "render/map"`(限 `packages` 与 `src`)并原样抄录输出;规划日仅 `packages-user/client-modules/src/fallback/ui.ts:2` 一条落在 `packages-user` 内,`packages/` 与 `src/` 对**被移集合源文件**零直接命中。**本行为对照扫描证据行(带 `[证据行]` 标记,豁免 ≥2 锚点计数),须携带上述 `git grep` 命令与原样结果(唯一真实锚点为输出中的 `packages-user/client-modules/src/fallback/ui.ts:2`);只登记输出与结论,不得为 `packages/` 与 `src/` 提修改建议。**
|
||||
- 深层导入、「不移植但被引用」的第二步必改点须逐条单列标注;**不得把 B 行写成待办或修复项**。
|
||||
|
||||
(3) **C 类补齐(barrel 与导出面)**:按固定列序表逐条写满,**每行含「barrel `file:line`」+「被导出文件的声明行 `file:line`」两个锚点**,并给出「现状导出集合 → 移出后是否断链」的判定(**只判定断链与否,不裁定如何补位,不裁定是否新增 barrel**):
|
||||
- `#04-10-C-02`:`render/components/index.ts:1-12`(12 条 `export *`,逐条抄录);判定 = **随集合整体移动**、集合内相对路径不变 ⇒ 自身不断链;但 `render/index.tsx:45` 与 `render/ui/*` 的 `../components` 路径需改指(属第二步)。
|
||||
- `#04-10-C-03`:`render/elements/index.ts`(`:1` import `@motajs/common`、`:2` import `../map`、`:3` import `../renderer`、`:4` / `:5` 本地 import、`createElements()` 声明行、`:45-47` 三条 `export *`);判定 = 移出后 `:2` 变为集合内引用(不断链)、**`:3` 变为 `client-base` → `client-modules` 反向依赖**(交叉引用 A-04 与 D 类);`createElements()` 的注册点接线属 F 类。
|
||||
- `#04-10-C-03`:`packages-user/client-modules/src/render/elements/index.ts` 的 `:1`(import `@motajs/common`)、`:2`(import `../map`)、`:3`(import `../renderer`)、`:4` / `:5`(本地 import)、`createElements()` 声明行、`:45-47`(三条 `export *`)——**锚点须写成完整 `文件:行`(如 `packages-user/client-modules/src/render/elements/index.ts:1`、`packages-user/client-modules/src/render/elements/index.ts:2`、`packages-user/client-modules/src/render/elements/index.ts:3`;续行 `:NN` 简写不计为锚点)**;判定 = 移出后 `:2` 变为集合内引用(不断链)、**`:3` 变为 `client-base` → `client-modules` 反向依赖**(交叉引用 A-04 与 D 类);`createElements()` 的注册点接线属 F 类。
|
||||
- `#04-10-C-04`:`render/map/index.ts:1-11`(`export * from './extension'` + `'./block'` / `'./constant'` / `'./element'` / `'./moving'` / `'./renderer'` / `'./status'` / `'./types'` / `'./vertex'` / `'./viewport'`);判定 = 随集合整体移动、自身不断链;`client.ts:25` 与 `types.ts:2` 的 `./render/map` 需改指。
|
||||
- `#04-10-C-05`:`render/index.tsx:45`(`export * from './components'`)、`:46`(`export * from './elements'`)、`:51`(`export * from './renderer'`);判定 = **移出后 `:45` / `:46` 断链**(`:51` 的 `./renderer` 留原地不断链),必须补位,否则 `@user/client-modules` 公共面收窄(交叉引用 B-08)。
|
||||
- `#04-10-C-05`:`packages-user/client-modules/src/render/index.tsx:45`(`export * from './components'`)、`packages-user/client-modules/src/render/index.tsx:46`(`export * from './elements'`)、`packages-user/client-modules/src/render/index.tsx:51`(`export * from './renderer'`);判定 = **移出后 `:45` / `:46` 断链**(`:51` 的 `./renderer` 留原地不断链),必须补位,否则 `@user/client-modules` 公共面收窄(交叉引用 B-08)。
|
||||
- `#04-10-C-06`:`render/utils/index.ts:1-3`(`export * from './layout' | './saves' | './use'`);判定 = **`:1` 移出即断链**(D-54 明示 `utils/index.ts` 不移植);`render/ui/{save,settings,title}.tsx` 经 `../utils` 间接消费该导出(`save.tsx:31` / `settings.tsx:20` / `title.tsx:35`)。
|
||||
- `#04-10-C-07`:`client-modules/src/index.ts:3`(`import { createGameRenderer, createRender } from './render'`)与 `:15`(`export * from './render'`);判定 = 再导出链的顶层出口,公共面收窄的最终承担点。
|
||||
- `#04-10-C-08`:`client-base/src/index.ts:1-5`(现行 `export * from './load' | './material' | './save' | './types'`);判定 = 目标侧 barrel **现状不含** `components` / `elements` / `map` / `layout`。**是否新增导出属 F 类,不得裁定。**
|
||||
- `#04-10-C-07`:`packages-user/client-modules/src/index.ts:3`(`import { createGameRenderer, createRender } from './render'`)与 `packages-user/client-modules/src/index.ts:15`(`export * from './render'`);判定 = 再导出链的顶层出口,公共面收窄的最终承担点。
|
||||
- `#04-10-C-08`:`packages-user/client-base/src/index.ts:1-5`(现行 `export * from './load' | './material' | './save' | './types'`);目标锚点 = 被导出文件 `packages-user/client-base/src/load/index.ts:1` 与 `packages-user/client-base/src/material/index.ts:1` 的声明行(当日实测,写成完整 `文件:行`);判定 = 目标侧 barrel **现状不含** `components` / `elements` / `map` / `layout`。**是否新增导出属 F 类,不得裁定。**
|
||||
- 另写一条 **导出面链条小结**(不新增独立事实,只把上面的链条串起来):`components/index.ts` + `elements/index.ts` + `map/index.ts` → `render/index.tsx:45,46,51` → `client-modules/src/index.ts:3,15` → `@user/client-modules` 消费者(`entry-client` / `entry-data` / `packages/legacy-ui`),供第二步据以补位。
|
||||
|
||||
(4) **重型整文件读取可按 D-09 委派只读子代理**(`render/ui/` 8 文件、`components/` 13 文件、`map/renderer.ts` 与 `map/vertex.ts` 两个较大文件):子代理只回传事实表(每行:文件 + `file:line` + 形态或签名),**不得写文件、不得贴大段源码**;主执行者按 `file:line` 切片复核后落笔。
|
||||
@ -384,8 +384,8 @@ Phase 4 第十个增量(用户裁定 2026-09-23 · D-51..D-57 **第一步**)
|
||||
</action>
|
||||
<!-- plan-criteria-allow: R4 - 本任务验证块内的竖线字符全部位于 node 程序的正则分支 / 数组字面量中,不是 shell 管道;所有 git 命令均由 node 的 execSync 调用并在 JS 内捕获 stdout 与 exit status 后自行判定,不经 shell 管道传递状态 -->
|
||||
<verify>
|
||||
<automated>node -e "const fs=require('fs');const t=fs.readFileSync('.planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md','utf8');const seg=h=>{const i=t.indexOf(h);if(i<0)return '';const rest=t.slice(i+h.length);const j=rest.search(/\r?\n## /);return j<0?rest:rest.slice(0,j)};const A=seg('## A '),B=seg('## B '),C=seg('## C ');const cnt=(s,re)=>(s.match(re)||[]).length;const rows=(s,c)=>cnt(s,new RegExp('^\\|\\s*#04-10-'+c+'-\\d+\\s*\\|','gm'));const anch=l=>cnt(l,/[A-Za-z0-9_\-.\\/]+\.(tsx?|frag|vert):\d+/g);const p=[];if(!A||!B||!C)p.push('MISSING SECTION');if(rows(A,'A')<8)p.push('A ROWS '+rows(A,'A'));if(rows(B,'B')<8)p.push('B ROWS '+rows(B,'B'));if(rows(C,'C')<7)p.push('C ROWS '+rows(C,'C'));const check=(s,c)=>{const re=new RegExp('^\\|\\s*#04-10-'+c+'-\\d+\\s*\\|');const bad=s.split(/\r?\n/).filter(l=>re.test(l)).filter(l=>anch(l)<2);if(bad.length>0)p.push(c+' ROWS WITHOUT TWO-SIDED ANCHOR '+bad.length)};check(A,'A');check(B,'B');check(C,'C');const needA=['tip.tsx','textbox.tsx','textboxTyper.ts','elements/index.ts','elements/props.ts','renderer','use.ts','shared.ts','@user/client-base','extension'];const mA=needA.filter(k=>A.indexOf(k)<0);if(mA.length>0)p.push('A MISSING '+mA.join('|'));const needB=['client.ts','types.ts','render/index.tsx','main.tsx','save.tsx','settings.tsx','statistics.tsx','statusBar.tsx','title.tsx','toolbar.tsx','viewmap.tsx','saves.ts','fallback/ui.ts','entry-client','entry-data','legacy-ui'];const mB=needB.filter(k=>B.indexOf(k)<0);if(mB.length>0)p.push('B MISSING '+mB.join('|'));const needC=['components/index.ts','elements/index.ts','map/index.ts','render/index.tsx','utils/index.ts','client-modules/src/index.ts','client-base/src/index.ts'];const mC=needC.filter(k=>C.indexOf(k)<0);if(mC.length>0)p.push('C MISSING '+mC.join('|'));if(p.length>0){console.error('ABC GATE FAILED :: '+p.join(' ;; '));process.exit(1)}console.log('OK A'+rows(A,'A')+' B'+rows(B,'B')+' C'+rows(C,'C'))"</automated>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "ABC GATE FAILED"(A 少于 8 行 / B 少于 8 行 / C 少于 7 行,或任一行缺「命中处」「目标锚点」两个 `file:line` 锚点,或 A 未覆盖 8 个内部引用方向、B 未覆盖 8 个外部导入点文件族与 3 个间接依赖包、C 未覆盖 7 个 barrel 节点)</fails_when>
|
||||
<automated>node -e "const fs=require('fs');const t=fs.readFileSync('.planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md','utf8');const seg=h=>{const i=t.indexOf(h);if(i<0)return '';const rest=t.slice(i+h.length);const j=rest.search(/\r?\n## /);return j<0?rest:rest.slice(0,j)};const A=seg('## A '),B=seg('## B '),C=seg('## C ');const cnt=(s,re)=>(s.match(re)||[]).length;const rows=(s,c)=>cnt(s,new RegExp('^\\|\\s*#04-10-'+c+'-\\d+','gm'));const anch=l=>cnt(l,/[A-Za-z0-9_\-.\\/]+\.(tsx?|frag|vert|json|md):\d+/g);const MK='\u8bc1\u636e\u884c';const EX={A:['09'],B:['09']};const p=[];if(!A||!B||!C)p.push('MISSING SECTION');if(rows(A,'A')<8)p.push('A ROWS '+rows(A,'A'));if(rows(B,'B')<8)p.push('B ROWS '+rows(B,'B'));if(rows(C,'C')<7)p.push('C ROWS '+rows(C,'C'));const check=(s,c)=>{const re=new RegExp('^\\|\\s*#04-10-'+c+'-\\d+');const rs=s.split(/\r?\n/).filter(l=>re.test(l));const ev=rs.filter(l=>l.indexOf(MK)>=0);const badEv=ev.filter(l=>!((EX[c]||[]).indexOf((l.match(/#04-10-[A-F]-(\d+)/)||[])[1])>=0)||l.indexOf('git grep')<0);if(badEv.length>0)p.push(c+' BAD EVIDENCE ROW '+badEv.length);const bad=rs.filter(l=>l.indexOf(MK)<0).filter(l=>anch(l)<2);if(bad.length>0)p.push(c+' ROWS WITHOUT TWO-SIDED ANCHOR '+bad.length)};check(A,'A');check(B,'B');check(C,'C');const needA=['tip.tsx','textbox.tsx','textboxTyper.ts','elements/index.ts','elements/props.ts','renderer','use.ts','shared.ts','@user/client-base','extension'];const mA=needA.filter(k=>A.indexOf(k)<0);if(mA.length>0)p.push('A MISSING '+mA.join('|'));const needB=['client.ts','types.ts','render/index.tsx','main.tsx','save.tsx','settings.tsx','statistics.tsx','statusBar.tsx','title.tsx','toolbar.tsx','viewmap.tsx','saves.ts','fallback/ui.ts','entry-client','entry-data','legacy-ui'];const mB=needB.filter(k=>B.indexOf(k)<0);if(mB.length>0)p.push('B MISSING '+mB.join('|'));const needC=['components/index.ts','elements/index.ts','map/index.ts','render/index.tsx','utils/index.ts','client-modules/src/index.ts','client-base/src/index.ts'];const mC=needC.filter(k=>C.indexOf(k)<0);if(mC.length>0)p.push('C MISSING '+mC.join('|'));if(p.length>0){console.error('ABC GATE FAILED :: '+p.join(' ;; '));process.exit(1)}console.log('OK A'+rows(A,'A')+' B'+rows(B,'B')+' C'+rows(C,'C'))"</automated>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "ABC GATE FAILED" / "BAD EVIDENCE ROW"(A 少于 8 行 / B 少于 8 行 / C 少于 7 行,或事实·基准行不足 2 个完整 `文件:行` 锚点(识别正则接受 `.(tsx?|frag|vert|json|md):\d+`),或证据行 `#04-10-A-09` / `#04-10-B-09` 缺 `[证据行]` 标记或 `git grep` 机器证据、或其它 ID 带标记,或 A 未覆盖 8 个内部引用方向、B 未覆盖 8 个外部导入点文件族与 3 个间接依赖包、C 未覆盖 7 个 barrel 节点)</fails_when>
|
||||
<automated>node -e "const{execSync}=require('child_process');const sets=[[['../ui','../fx','../weather'],'packages-user/client-modules/src/render/components packages-user/client-modules/src/render/elements packages-user/client-modules/src/render/map packages-user/client-modules/src/render/utils/layout.ts'],[['client-modules'],'packages-user/client-base']];const bad=[];for(const s of sets){for(const pat of s[0]){let o='',st=0;try{o=execSync('git grep -n -F \"'+pat+'\" -- '+s[1],{encoding:'utf8',stdio:['ignore','pipe','pipe']})}catch(e){o=(e.stdout||'')+(e.stderr||'');st=e.status}const lines=o.replace(/\s+$/,'').length>0?o.split(/\r?\n/):[];if(lines.length>0)bad.push(pat+' => '+lines.slice(0,3).join(' ; '));else if(st!==0&&st!==1)bad.push(pat+' grep status '+st)}}if(bad.length>0){console.error('ZERO-HIT CLAIM FALSIFIED: '+bad.join(' || '));process.exit(1)}console.log('OK zero-hit claims verified')"</automated>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "ZERO-HIT CLAIM FALSIFIED"(被移集合内仍存在对 `ui` / `fx` / `weather` 的 import,或 `client-base` 已出现对 `client-modules` 的引用 —— 即台账中的「零命中」结论为臆造,或移植已提前发生)
|
||||
</fails_when>
|
||||
@ -393,10 +393,10 @@ Phase 4 第十个增量(用户裁定 2026-09-23 · D-51..D-57 **第一步**)
|
||||
<fails_when>non-zero exit, 或 stderr 含 "NON-CRLF LINE ENDINGS"(追加内容未保持 CRLF)</fails_when>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- A 类 **≥ 8 行**,覆盖 8 个方向:`components→elements`、`elements→map`、→`render/renderer`、→`render/use.ts`、→`client-modules/src/shared.ts`、→`@user/client-base`(自包引用)、`map/extension/*→map/types`、A 类零命中机器证据;每行含导入处与目标锚点两个 `file:line`
|
||||
- B 类 **≥ 8 行**,覆盖 `client.ts:25` / `types.ts:2` / `render/index.tsx:5,45,46` / `render/ui` 8 文件 10 处(含 `toolbar.tsx` 的深层导入)/ `render/utils/saves.ts:2` / `render/utils/index.ts:1`(与 B-01 交叉引用而不重复计数)/ `fallback/ui.ts:2` / 其它 monorepo 包(`entry-client` / `entry-data` / `packages/legacy-ui`)的间接依赖 / 对照扫描机器证据;深层导入与「不移植但被引用」的第二步必改点单列标注
|
||||
- A 类 **≥ 8 行**,覆盖 8 个方向:`components→elements`、`elements→map`、→`render/renderer`、→`render/use.ts`、→`client-modules/src/shared.ts`、→`@user/client-base`(自包引用)、`map/extension/*→map/types`、A 类零命中机器证据;事实行每行含 ≥2 个完整 `文件:行` 锚点(`A-09` 为零命中证据行,带 `[证据行]` 标记 + `git grep` 证据)
|
||||
- B 类 **≥ 8 行**,覆盖 `client.ts:25` / `types.ts:2` / `render/index.tsx:5,45,46` / `render/ui` 8 文件 11 处(含 `toolbar.tsx` 的深层导入)/ `render/utils/saves.ts:2` / `render/utils/index.ts:1`(与 B-01 交叉引用而不重复计数)/ `fallback/ui.ts:2` / 其它 monorepo 包(`entry-client` / `entry-data` / `packages/legacy-ui`)的间接依赖 / 对照扫描机器证据;深层导入与「不移植但被引用」的第二步必改点单列标注
|
||||
- C 类 **≥ 7 行**,覆盖 7 个 barrel 节点(`components/index.ts` / `elements/index.ts` / `map/index.ts` / `render/index.tsx` / `render/utils/index.ts` / `client-modules/src/index.ts` / `client-base/src/index.ts`),逐条给出「现状导出集合 → 移出后是否断链」判定,并附导出面链条小结;未裁定「是否新增 barrel / 如何补位」
|
||||
- 所有 A–C 行含 ≥2 个 `file:line` 锚点;行内无移植方案、无 import 重写写法、无「应改为 X」
|
||||
- A–C 的事实·基准行各含 ≥2 个完整 `文件:行` 锚点(识别正则接受 `.(tsx?|frag|vert|json|md):\d+`,`.json` / `.md` 基准也计);`#04-10-A-09` / `#04-10-B-09` 为带 `[证据行]` 标记的证据行(携带 `git grep` 机器证据、豁免锚点计数);行内无移植方案、无 import 重写写法、无「应改为 X」
|
||||
- 相对记录在 `## 方法` 的只读起始基线零变化;未修改任何生产源码;未预建目标目录;全文 CRLF
|
||||
</acceptance_criteria>
|
||||
<done>A / B / C 三类横向补齐:8 个内部交叉引用方向(含零命中机器证据)/ 8 个外部导入点文件族与 3 个间接依赖包 / 7 个 barrel 节点与断链判定 + 导出面链条小结;行数 / 双锚点 / 关键词 / 零命中复验 / CRLF 门禁转绿</done>
|
||||
@ -415,35 +415,36 @@ Phase 4 第十个增量(用户裁定 2026-09-23 · D-51..D-57 **第一步**)
|
||||
- packages-user/client-modules/src/render/map/renderer.ts:43-46(D 类:`./shader/{map,back}.{vert,frag}?raw`)与 packages-user/client-modules/src/render/map/shader/(4 个 shader 文件)
|
||||
- packages-user/client-modules/src/render/elements/{cache.ts,misc.ts}(E 类:`core.*` / `loading` / `Mota.require('@user/data-base')` 命中)
|
||||
- packages-user/client-modules/src/render/components/{choices.tsx,floorSelect.tsx,misc.tsx,textboxTyper.ts,thumbnail.tsx,tip.tsx}(E 类:`core.*` 命中)
|
||||
- packages-user/client-modules/src/render/use.ts:2(D 类:`use.ts` 自身 import `../weather`)
|
||||
- packages-user/client-modules/src/render/use.ts(D 类:`render/use.ts` 的导出声明行;实测自身无相对导入)
|
||||
- packages-user/client-modules/src/render/utils/use.ts:2(D 类:`../weather` 的实际导入处,非 `render/use.ts`)
|
||||
- dev.md(「项目结构」单向依赖 `src → packages-user → packages`;「双端分离」;「其他要求」的 CRLF)
|
||||
</read_first>
|
||||
<action>
|
||||
(1) **D 类补齐(分层与循环依赖风险)**:按固定列序表逐条写满,**每行含「风险源 `file:line`」+「规则 / 依赖基准锚点 `file:line`」两个锚点**,**只登记风险与机器证据,不得自拟解耦方案**(不得写「应下沉 / 应抽类型 / 应保留跨包依赖 / 应改用 X」):
|
||||
- `#04-10-D-02`:移入后 `client-base` → `client-modules` 反向依赖(**常量 / 工具面**)—— `map/vertex.ts:25`、`map/element.ts:5`、`map/renderer.ts:53`、`map/extension/door.ts:9`(交叉引用 A-06,不重复计数);基准锚点 = `packages-user/client-modules/src/shared.ts` 的声明行 + `dev.md` 的单向依赖条目。
|
||||
- `#04-10-D-03`:同向(**渲染器面**)—— `elements/index.ts:3`、`components/textboxTyper.ts:6`、`components/misc.tsx:14`(交叉引用 A-04);基准锚点 = `render/renderer.ts` 的导出声明行 + `dev.md` 单向依赖条目。
|
||||
- `#04-10-D-04`:同向(**hooks 面**)—— `components/{choices.tsx:8,tip.tsx:4,scroll.tsx:31,input.tsx:14,misc.tsx:10}`(交叉引用 A-05);基准锚点 = `render/use.ts` 的导出声明行。**须写明 `render/use.ts:2` 自身 import `../weather`,即该链条可能牵出 `ui` / `fx` / `weather` 与 `client.*`,静态阅读不能判定是否必然成环 ⇒ 交叉引用 F 类。**
|
||||
- `#04-10-D-04`:同向(**hooks 面**)—— `components/{choices.tsx:8,tip.tsx:4,scroll.tsx:31,input.tsx:14,misc.tsx:10}`(交叉引用 A-05);基准锚点 = `render/use.ts` 的导出声明行。**须写明 `render/use.ts` 自身**无**相对导入(实测只 import 外部包与 `@user/data-base` 的 `loading`),故本方向不牵出 `ui` / `fx` / `weather`;`../weather` 的实际导入处在 `render/utils/use.ts:2`(非本次移植集合),与 `render/use.ts` 无关;静态阅读不能判定是否必然成环 ⇒ 交叉引用 F 类。**
|
||||
- `#04-10-D-05`:同向(**barrel 面**)—— `render/utils/index.ts:1`(交叉引用 `#04-10-C-01` / `#04-10-C-06`);基准锚点 = `render/utils/layout.ts` 的声明行。
|
||||
- `#04-10-D-06`:**自包引用** —— `@user/client-base` 的 5 处(`map/extension/hero.ts:16`、`map/moving.ts:3`、`map/renderer.ts:13`、`map/types.ts:12`、`map/vertex.ts:28`;交叉引用 A-07);基准锚点 = `packages-user/client-base/src/index.ts:1-5`(barrel)+ `packages-user/client-base/package.json:3-9`。**改写方式属 F 类。**
|
||||
- `#04-10-D-07`:**`package.json` 依赖缺口** —— `packages-user/client-base/package.json:3-9` 现行只声明 `@motajs/audio` / `@motajs/render` / `@motajs/client-base` / `@user/data-base` / `@user/data-state`;被移集合还用 `@motajs/render-vue`(12 个组件 + `elements/props.ts:1`)、`@motajs/system`(`choices.tsx:7` 等)、`@motajs/common`(`elements/index.ts:1`)、`@user/data-common`(`map/renderer.ts:38` / `map/vertex.ts:2` / `map/extension/{hero.ts:11,manager.ts:1,types.ts:2}`);基准锚点 = `packages-user/client-modules/package.json:4-17`(这些依赖当前都在实现层声明)。**只登记缺口事实,不得提出补声明、安装或改配置的建议。**
|
||||
- `#04-10-D-08`:**反向依赖现状的机器证据** —— 执行 `git grep -n -F "client-modules" -- packages-user/client-base` 并原样抄录输出(规划日无输出 / 退出码 1)⇒ 该风险由本次移植**引入**、非既有;基准锚点 = `packages-user/client-base/package.json:3-9`(deps 内无 `@user/client-modules`)。同条附 `git grep -n -F "from '@user/client-base'" -- packages-user/client-modules/src` 的原样输出(规划日 7 条命中,其中 5 条在被移集合内、另 2 条在 `client.ts:19` / `fallback/load.ts:6`)。
|
||||
- `#04-10-D-09`:**shader `?raw` 构建链** —— `render/map/renderer.ts:43-46`(`./shader/{map,back}.{vert,frag}?raw`)+ `render/map/shader/` 的 4 个文件;基准锚点 = `packages-user/client-modules/` 与 `packages-user/client-base/` 的构建 / 配置现状(只登记事实:`?raw` 由构建链处理,换包后是否仍成立属 F 类)。
|
||||
- `#04-10-D-10`:**规则基准对照** —— `dev.md` 的「依赖方向单向 `src → packages-user → packages`」「不得循环引用」「双端分离(`client-base` 系统层 / `client-modules` 实现层)」;逐条列出与本案的关系(哪些方向被违反、哪些仍合法)。**只对照,不裁定处置。**
|
||||
- `#04-10-D-09`:**shader `?raw` 构建链** —— `render/map/renderer.ts:43-46`(`./shader/{map,back}.{vert,frag}?raw`)+ `render/map/shader/` 的 4 个文件;基准锚点 = `packages-user/client-base/package.json:1-10` 与 `packages-user/client-modules/package.json:1-19`(构建 / 配置现状,行号按当日实测;`package.json` 的 `文件:行` 由锚点识别正则计入)—— 只登记事实:`?raw` 由构建链处理,换包后是否仍成立属 F 类。
|
||||
- `#04-10-D-10`:**规则基准对照** —— `dev.md` 的「依赖方向单向 `src → packages-user → packages`」(`dev.md:10`)、「不得循环引用」(`dev.md:53`)、「双端分离(`client-base` 系统层 / `client-modules` 实现层)」(`dev.md:137-139`);逐条列出与本案的关系(哪些方向被违反、哪些仍合法)。**只对照,不裁定处置**(三个 `dev.md:行` 基准锚点由锚点识别正则计入,满足 ≥2 锚点)。
|
||||
- **D 类每条不得写成待办 / 修复项 / 解耦方案。**
|
||||
|
||||
(2) **E 类补齐(legacy 命中·仅报告)**:标题下明写 `**本节仅报告:按 D-55 不考虑任何 legacy 内容,legacy 相关报错一律不管、不修、不登记为待办。**` 逐条登记事实与核对命令:
|
||||
- `#04-10-E-02`:`core.*` 命中的逐文件汇总 —— 规划日:`components/choices.tsx` 13 处(`:675,715,717,718,719,728,733,770,772,773,774,783,789`)、`components/floorSelect.tsx` 2 处(`:62,181`)、`components/misc.tsx` 1 处(`:312`)、`components/textboxTyper.ts` 1 处(`:906`)、`components/thumbnail.tsx` 1 处(`:75`)、`components/tip.tsx` 1 处(`:103`)、`render/elements/cache.ts` 9 处(`:11,87,89,131,151,202,206,393,469`)、`render/elements/misc.ts` 2 处(`:221,228`);须执行核对命令并原样抄录输出(`git grep -n -F "core." -- <被移集合四个路径>`,以当日实测为准,命中数不同即按实测写入);基准锚点 = `dev.md` 的 legacy 相关条目 + `04-CONTEXT.md` 的 D-12(`core.*` 属旧引擎适配,归第五阶段)。
|
||||
- `#04-10-E-03`:**全局 `loading` + `Mota.require('@user/data-base')`** —— `render/elements/cache.ts:491-492`(`const { loading } = Mota.require('@user/data-base'); loading.once('loaded', ...)`)与 `render/elements/misc.ts:89-94` / `:219-225`(同形);基准锚点 = `04-CONTEXT.md` 的 D-14(全局 `hook` / `loading` 属 legacy)。**只报告。**
|
||||
- `#04-10-E-04`:**`client.*` 在移出集合内 0 命中** —— 执行 `git grep -n -F "client." -- <被移集合四个路径>` 并原样抄录输出(规划日无输出 / 退出码 1);基准锚点 = `04-CONTEXT.md` 的 D-12 / D-23(`client.*` 属本阶段需处理内容,但本步零代码改动)。**只报告;不得由此提出 `client.*` 的清退方案。**
|
||||
- `#04-10-E-05`:**`packages/` 与 `src/` 的对照扫描** —— 执行 `git grep -n -F "render/components"`、`-F "render/elements"`、`-F "render/map"`(限 `packages` 与 `src`)并原样抄录输出(规划日 `packages/` 与 `src/` 零命中;`packages-user` 内仅 `client-modules/src/fallback/ui.ts:2`);基准锚点 = `04-CONTEXT.md` 的 D-33(范围外一律不改)。**只报告,不提修改建议。**
|
||||
- `#04-10-E-06`:**`render/elements/cache.ts` 的 legacy 贴图路径现状**(对照 04-06 / 04-07 的 big-image 清退面)—— 按当日阅读逐条登记该文件残存的 legacy 贴图访问点(`file:line`)与其形态;基准锚点 = `04-MATERIAL-INTERFACE-IMPACT.md` / `04-07-SUMMARY.md` 中关于 big-image 清退的记录行。**只报告,不登记为待办**(D-55)。
|
||||
- `#04-10-E-04 [证据行]`:**`client.*` 在移出集合内 0 命中** —— 执行 `git grep -n -F "client." -- <被移集合四个路径>` 并原样抄录输出(规划日无输出 / 退出码 1);基准锚点 = `04-CONTEXT.md:42`(D-12)与 `04-CONTEXT.md:57`(D-23)—— `client.*` 属本阶段需处理内容,但本步零代码改动。**本行为零命中证据行(带 `[证据行]` 标记,豁免 ≥2 锚点计数),须携带上述 `git grep` 命令与原样结果;只报告;不得由此提出 `client.*` 的清退方案。**
|
||||
- `#04-10-E-05 [证据行]`:**`packages/` 与 `src/` 的对照扫描** —— 执行 `git grep -n -F "render/components"`、`-F "render/elements"`、`-F "render/map"`(限 `packages` 与 `src`)并原样抄录输出(规划日 `packages/` 与 `src/` 零命中;`packages-user` 内仅 `client-modules/src/fallback/ui.ts:2`);唯一真实锚点 = `packages-user/client-modules/src/fallback/ui.ts:2`,基准锚点 = `04-CONTEXT.md:72`(D-33 范围外一律不改)。**本行为对照扫描证据行(带 `[证据行]` 标记,豁免 ≥2 锚点计数),须携带上述 `git grep` 命令与原样结果;只报告,不提修改建议。**
|
||||
- `#04-10-E-06`:**`render/elements/cache.ts` 的 legacy 贴图路径现状**(对照 04-06 / 04-07 的 big-image 清退面)—— 按当日阅读逐条登记该文件残存的 legacy 贴图访问点(`file:line`)与其形态;基准锚点 = `04-CONTEXT.md:75`(D-36:删除 `cache.ts` 的 legacy big-image 路径)与 `04-07-SUMMARY.md:174`(big-image 清退的运行时影响记录)——两个 `.md` 基准锚点由锚点识别正则计入,故本行即使 `cache.ts` 内零残存也满足 ≥2 锚点。**只报告,不登记为待办**(D-55)。
|
||||
- 全节**不得**出现针对被移集合、`packages/` 或 `src/` 的修改性措辞。
|
||||
|
||||
(3) **F 类补齐(未能从阅读确定·未猜测)**:每条以 `- **#04-10-F-NN**:` 开头,写「现象 + 为什么读不出来 + 需要用户裁决的点」,至少覆盖(F-01 / F-02 已在 Task 1 写下,此处续编):① 目标文件名未确定(`client-base/src/layout/layout.ts` 还是 `layout/index.ts`;`client-base/src/{components,elements,map}/index.ts` 是否沿用同名)——**命名须先向用户反馈并获同意后才可使用**;② `render/utils/index.ts` 在 `layout.ts` 移出后的归属(D-54 明示不移植 ⇒ 断链处置未裁定);③ `client-base/src/index.ts` 是否新增 `export * from './{components,elements,map,layout}'`,以及 `render/index.tsx:45,46` 的断链如何补位(导出面是否扩张 / 收窄的裁定权在用户);④ 被移集合对留在 `client-modules` 的 `shared.ts` / `renderer` / `use.ts` / `render/utils` 的依赖如何解耦(交叉引用 D 类各条);⑤ `@user/client-base` 自包引用的改写方式;⑥ `client-base/package.json` 的依赖缺口是否在第二步补齐(D-37 有先例,本步不裁定);⑦ shader `?raw` 在 `client-base` 构建链下是否仍可用;⑧ `packages/legacy-ui` 经 `Mota.require('@user/client-modules')` 运行时取 `mainRenderer` / `client` 的插件面影响(legacy,只登记);⑨ `render/elements/index.ts` 的 `createElements()` 注册点(`mainRenderer.registerElement(...)` / `tagManager.registerTag(...)`)在 `client-base` 无渲染器实例时如何接线。**不得把本节任何一条写成错配、缺失、残留或待办。**
|
||||
|
||||
(4) **`## 处置` 定稿**:明写 —— 本文件是渲染端结构性重构(D-51 / D-57)**第一步(只读清点)**的交付物;本步**未修改任何生产代码、未引入任何命名变更**、`files_modified` 仅本文件;相对 `## 方法` 记录的只读起始基线零变化;**第二步(移植实施)未规划**,待用户审阅本文件后另行规划(D-57);被查范围 = 移植集合 39 文件与其全部 importer(含其它 monorepo 包的间接依赖),`packages/` 与 `src/` 仅报告(D-33);A / B 是事实层、C 是桶与导出面事实与断链判定、**D 是风险登记(解耦方案由用户裁定)**、**E 类按 D-55 只报告、不修、不登记为待办**、F 类须用户裁决;**全部命名问题归用户**(AGENTS.md);第二步的候选工作集 = B 类外部导入点 + C 类的断链点 + D 类的解耦面 + F 类的裁决项(最终纳入范围由用户裁定);`REND-01` / `REND-02` 保持 Pending;若当日实测与规划日数值(39 文件 / A 8 方向 / B 8 文件族 + 3 包 / C 7 节点 / D 9 条 / E 8 文件 / F ≥9)不同,在本节说明差异与原因。
|
||||
|
||||
(5) **运行五道门禁并按实测结果如实记录**:① 只读门禁(`git status --porcelain -- packages packages-user src` 与 `## 方法` 记录逐条一致;并断言 `.planning/phases/04-render-adaptation/04-CONTEXT.md` 的未提交改动仍在、`.planning/REQUIREMENTS.md` 未被改动且 `REND-01` / `REND-02` 仍为 `Pending`);② 类别门禁(A ≥ 8 / B ≥ 8 / C ≥ 7 / D ≥ 9 / E ≥ 6 / F ≥ 9、每行 ≥2 个 `file:line` 锚点、关键词齐备、`## 处置` 存在);③ 机器证据复验(`client-base` 对 `client-modules` 零命中、被移集合对 `ui`/`fx`/`weather` 零命中);④ 既有产物保护 + 计划范围门禁(`04-01`..`04-09` 的 `*-PLAN.md` / `*-SUMMARY.md` porcelain 为空;phase 目录内 `-PLAN.md` 恰为 `04-01`..`04-10` 共 10 个;`04-10-SUMMARY.md` 已落盘);⑤ CRLF 门禁。任一门禁失败即停下修正文档后重跑,**不得**改门禁口径或伪造通过。
|
||||
(5) **运行五道门禁并按实测结果如实记录**:① 只读门禁(`git status --porcelain -- packages packages-user src` 与 `## 方法` 记录逐条一致;并断言 `.planning/phases/04-render-adaptation/04-CONTEXT.md` 的未提交改动仍在、`.planning/REQUIREMENTS.md` 未被改动且 `REND-01` / `REND-02` 仍为 `Pending`);② 类别门禁(A ≥ 8 / B ≥ 8 / C ≥ 7 / D ≥ 9 / E ≥ 6 / F ≥ 9、事实·基准行每行 ≥2 个完整 `文件:行` 锚点(`.json` / `.md` 基准也计)、五条证据行 `[证据行]` 标记与 `git grep` 证据、关键词齐备、`## 处置` 存在);③ 机器证据复验(`client-base` 对 `client-modules` 零命中、被移集合对 `ui`/`fx`/`weather` 零命中);④ 既有产物保护 + 计划范围门禁(`04-01`..`04-09` 的 `*-PLAN.md` / `*-SUMMARY.md` porcelain 为空;phase 目录内 `-PLAN.md` 恰为 `04-01`..`04-10` 共 10 个;`04-10-SUMMARY.md` 已落盘);⑤ CRLF 门禁。任一门禁失败即停下修正文档后重跑,**不得**改门禁口径或伪造通过。
|
||||
|
||||
(6) **人工代码复核(不可自动化,如实记录结论)**:抽查 A 类的 `render/components/tip.tsx:7` 与 `render/elements/index.ts:2` 与 `render/elements/index.ts:3` 与 `render/map/renderer.ts:53`、B 类的 `render/ui/toolbar.tsx:13` 与 `render/fallback/ui.ts:2`(深层导入)、C 类的 `render/index.tsx:45,46` 与 `render/utils/index.ts:1`、D 类的 `render/map/renderer.ts:43-46`(`?raw`)与 `packages-user/client-base/package.json` 依赖集合、E 类的 `render/elements/cache.ts:491-492`,逐条打开当日源码确认「命中处锚点指向的确实是该符号 / 成员的引用」「目标锚点指向的确实是该声明 / barrel 行」,并把复核结论(通过 / 发现偏差及修正)写入 SUMMARY。发现偏差即回到文档修正。
|
||||
|
||||
@ -455,8 +456,8 @@ Phase 4 第十个增量(用户裁定 2026-09-23 · D-51..D-57 **第一步**)
|
||||
<verify>
|
||||
<automated>node -e "const fs=require('fs'),{execSync}=require('child_process');const t=fs.readFileSync('.planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md','utf8');const seg=h=>{const i=t.indexOf(h);if(i<0)return '';const rest=t.slice(i+h.length);const j=rest.search(/\r?\n## /);return j<0?rest:rest.slice(0,j)};const ms=seg('## \u65b9\u6cd5');if(ms.indexOf('\u53ea\u8bfb\u8d77\u59cb\u57fa\u7ebf')<0){console.error('READONLY BASELINE NOT RECORDED');process.exit(1)}const rec=(ms.match(/^[ MARCUD?!]{2} (?:packages|packages-user|src)[^\r\n]*/gm)||[]).map(s=>s.replace(/\s+$/,''));let raw='';try{raw=execSync('git status --porcelain -- packages packages-user src',{encoding:'utf8'})}catch(e){console.error('GIT STATUS FAILED '+(e.message||''));process.exit(1)}const out=raw.replace(/\s+$/,'');const cur=out.length>0?out.split(/\r?\n/).map(s=>s.replace(/\s+$/,'')):[];const extra=cur.filter(l=>rec.indexOf(l)<0);const gone=rec.filter(l=>cur.indexOf(l)<0);if(extra.length+gone.length>0){console.error('READONLY BASELINE CHANGED extra=['+extra.join(' ; ')+'] missing=['+gone.join(' ; ')+']');process.exit(1)}if(execSync('git status --porcelain -- .planning/phases/04-render-adaptation/04-CONTEXT.md',{encoding:'utf8'}).replace(/\s+$/,'').length===0){console.error('USER CONTEXT EDIT DISAPPEARED (D-56)');process.exit(1)}const roReq=execSync('git status --porcelain -- .planning/REQUIREMENTS.md',{encoding:'utf8'}).replace(/\s+$/,'');if(roReq.length>0){console.error('READ-ONLY VIOLATION .planning/REQUIREMENTS.md: '+roReq);process.exit(1)}const req=fs.readFileSync('.planning/REQUIREMENTS.md','utf8').split(/\r?\n/);const notPending=[];for(const id of ['REND-01','REND-02']){const line=req.filter(l=>l.indexOf('| '+id+' |')>=0).join('')||req.filter(l=>l.indexOf(id)>=0).join('');if(!/\|\s*Pending\s*\|/.test(line))notPending.push(id)}if(notPending.length>0){console.error('REND STATUS NOT PENDING: '+notPending.join(','));process.exit(1)}console.log('OK read-only unchanged entries '+cur.length+'; REND-01/REND-02 still Pending')"</automated>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "READONLY BASELINE NOT RECORDED" / "READONLY BASELINE CHANGED" / "GIT STATUS FAILED" / "USER CONTEXT EDIT DISAPPEARED" / "READ-ONLY VIOLATION" / "REND STATUS NOT PENDING"(`packages` / `packages-user` / `src` 下出现新增 / 消失 / 状态码变化的条目,或用户的 `04-CONTEXT.md` 未提交改动消失,或 `.planning/REQUIREMENTS.md` 被改动,或 `REND-01` / `REND-02` 不再是 `Pending` —— 违反只读 / D-56 或「REND 保持 Pending」真值不成立)</fails_when>
|
||||
<automated>node -e "const fs=require('fs');const t=fs.readFileSync('.planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md','utf8');const seg=h=>{const i=t.indexOf(h);if(i<0)return '';const rest=t.slice(i+h.length);const j=rest.search(/\r?\n## /);return j<0?rest:rest.slice(0,j)};const sec={A:seg('## A '),B:seg('## B '),C:seg('## C '),D:seg('## D '),E:seg('## E '),F:seg('## F '),Z:seg('## \u5904\u7f6e')};const cnt=(s,re)=>(s.match(re)||[]).length;const rows=(s,c)=>cnt(s,new RegExp('^\\|\\s*#04-10-'+c+'-\\d+\\s*\\|','gm'));const anch=l=>cnt(l,/[A-Za-z0-9_\-.\\/]+\.(tsx?|frag|vert):\d+/g);const p=[];if(!sec.Z)p.push('MISSING DISPOSITION');const min={A:8,B:8,C:7,D:9,E:6};for(const c of ['A','B','C','D','E']){const n=rows(sec[c],c);if(n<min[c])p.push(c+' ROWS '+n);const re=new RegExp('^\\|\\s*#04-10-'+c+'-\\d+\\s*\\|');const bad=sec[c].split(/\r?\n/).filter(l=>re.test(l)).filter(l=>anch(l)<2);if(bad.length>0)p.push(c+' ROWS WITHOUT TWO-SIDED ANCHOR '+bad.length)}if(cnt(sec.F,/^- \*\*#04-10-F-\d+/gm)<9)p.push('F ITEMS '+cnt(sec.F,/^- \*\*#04-10-F-\d+/gm));const needD=['shared.ts','renderer','use.ts','@user/client-base','package.json','?raw','dev.md'];const mD=needD.filter(k=>sec.D.indexOf(k)<0);if(mD.length>0)p.push('D MISSING '+mD.join('|'));const needE=['core.','loading','Mota.require','cache.ts','packages/','src/'];const mE=needE.filter(k=>sec.E.indexOf(k)<0);if(mE.length>0)p.push('E MISSING '+mE.join('|'));if(cnt(sec.E,/\u4ec5\u62a5\u544a/g)<1)p.push('E REPORT-ONLY PHRASE');if(p.length>0){console.error('FINAL CATEGORY GATE FAILED :: '+p.join(' ;; '));process.exit(1)}console.log('OK A'+rows(sec.A,'A')+' B'+rows(sec.B,'B')+' C'+rows(sec.C,'C')+' D'+rows(sec.D,'D')+' E'+rows(sec.E,'E')+' F'+cnt(sec.F,/^- \*\*#04-10-F-\d+/gm))"</automated>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "FINAL CATEGORY GATE FAILED"(缺 `## 处置`;或 A < 8 / B < 8 / C < 7 / D < 9 / E < 6;或任一行缺两个 `file:line` 锚点;或 F 类少于 9 条;或 D 未覆盖反向依赖 / 自包引用 / `package.json` / `?raw` / `dev.md`;或 E 未覆盖 `core.` / `loading` / `Mota.require` / `cache.ts` / `packages/` / `src/` 或缺「仅报告」措辞)</fails_when>
|
||||
<automated>node -e "const fs=require('fs');const t=fs.readFileSync('.planning/phases/04-render-adaptation/04-STRUCTURE-MIGRATION-IMPACT.md','utf8');const seg=h=>{const i=t.indexOf(h);if(i<0)return '';const rest=t.slice(i+h.length);const j=rest.search(/\r?\n## /);return j<0?rest:rest.slice(0,j)};const sec={A:seg('## A '),B:seg('## B '),C:seg('## C '),D:seg('## D '),E:seg('## E '),F:seg('## F '),Z:seg('## \u5904\u7f6e')};const cnt=(s,re)=>(s.match(re)||[]).length;const rows=(s,c)=>cnt(s,new RegExp('^\\|\\s*#04-10-'+c+'-\\d+','gm'));const anch=l=>cnt(l,/[A-Za-z0-9_\-.\\/]+\.(tsx?|frag|vert|json|md):\d+/g);const MK='\u8bc1\u636e\u884c';const EX={A:['09'],B:['09'],E:['01','04','05']};const p=[];if(!sec.Z)p.push('MISSING DISPOSITION');const min={A:8,B:8,C:7,D:9,E:6};for(const c of ['A','B','C','D','E']){const n=rows(sec[c],c);if(n<min[c])p.push(c+' ROWS '+n);const re=new RegExp('^\\|\\s*#04-10-'+c+'-\\d+');const rs=sec[c].split(/\r?\n/).filter(l=>re.test(l));const ev=rs.filter(l=>l.indexOf(MK)>=0);const badEv=ev.filter(l=>!((EX[c]||[]).indexOf((l.match(/#04-10-[A-F]-(\d+)/)||[])[1])>=0)||l.indexOf('git grep')<0);if(badEv.length>0)p.push(c+' BAD EVIDENCE ROW '+badEv.length);const bad=rs.filter(l=>l.indexOf(MK)<0).filter(l=>anch(l)<2);if(bad.length>0)p.push(c+' ROWS WITHOUT TWO-SIDED ANCHOR '+bad.length)}if(cnt(sec.F,/^- \*\*#04-10-F-\d+/gm)<9)p.push('F ITEMS '+cnt(sec.F,/^- \*\*#04-10-F-\d+/gm));const needD=['shared.ts','renderer','use.ts','@user/client-base','package.json','?raw','dev.md'];const mD=needD.filter(k=>sec.D.indexOf(k)<0);if(mD.length>0)p.push('D MISSING '+mD.join('|'));const needE=['core.','loading','Mota.require','cache.ts','packages/','src/'];const mE=needE.filter(k=>sec.E.indexOf(k)<0);if(mE.length>0)p.push('E MISSING '+mE.join('|'));if(cnt(sec.E,/\u4ec5\u62a5\u544a/g)<1)p.push('E REPORT-ONLY PHRASE');if(p.length>0){console.error('FINAL CATEGORY GATE FAILED :: '+p.join(' ;; '));process.exit(1)}console.log('OK A'+rows(sec.A,'A')+' B'+rows(sec.B,'B')+' C'+rows(sec.C,'C')+' D'+rows(sec.D,'D')+' E'+rows(sec.E,'E')+' F'+cnt(sec.F,/^- \*\*#04-10-F-\d+/gm))"</automated>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "FINAL CATEGORY GATE FAILED" / "BAD EVIDENCE ROW"(缺 `## 处置`;或 A < 8 / B < 8 / C < 7 / D < 9 / E < 6;或事实·基准行不足 2 个完整 `文件:行` 锚点(识别正则接受 `.(tsx?|frag|vert|json|md):\d+`);或 `#04-10-A-09` / `#04-10-B-09` / `#04-10-E-01` / `#04-10-E-04` / `#04-10-E-05` 五条证据行缺 `[证据行]` 标记或 `git grep` 机器证据、或其它 ID 带标记;或 F 类少于 9 条;或 D 未覆盖反向依赖 / 自包引用 / `package.json` / `?raw` / `dev.md`;或 E 未覆盖 `core.` / `loading` / `Mota.require` / `cache.ts` / `packages/` / `src/` 或缺「仅报告」措辞)</fails_when>
|
||||
<automated>node -e "const{execSync}=require('child_process');const sets=[[['client-modules'],'packages-user/client-base'],[['../ui','../fx','../weather'],'packages-user/client-modules/src/render/components packages-user/client-modules/src/render/elements packages-user/client-modules/src/render/map packages-user/client-modules/src/render/utils/layout.ts']];const bad=[];for(const s of sets){for(const pat of s[0]){let o='',st=0;try{o=execSync('git grep -n -F \"'+pat+'\" -- '+s[1],{encoding:'utf8',stdio:['ignore','pipe','pipe']})}catch(e){o=(e.stdout||'')+(e.stderr||'');st=e.status}const lines=o.replace(/\s+$/,'').length>0?o.split(/\r?\n/):[];if(lines.length>0)bad.push(pat+' => '+lines.slice(0,3).join(' ; '));else if(st!==0&&st!==1)bad.push(pat+' grep status '+st)}}if(bad.length>0){console.error('ZERO-HIT CLAIM FALSIFIED: '+bad.join(' || '));process.exit(1)}console.log('OK zero-hit claims verified')"</automated>
|
||||
<fails_when>non-zero exit, 或 stderr 含 "ZERO-HIT CLAIM FALSIFIED"(`client-base` 已引用 `client-modules`,或被移集合已 import `ui` / `fx` / `weather` —— 台账中的「零命中」结论为臆造,或移植已提前发生)</fails_when>
|
||||
<automated>node -e "const fs=require('fs'),{execSync}=require('child_process');const dir='.planning/phases/04-render-adaptation';const ids=['04-01','04-02','04-03','04-04','04-05','04-06','04-07','04-08','04-09'];const prot=[];for(const n of ids){prot.push(dir+'/'+n+'-PLAN.md');prot.push(dir+'/'+n+'-SUMMARY.md')}const args=prot.filter(f=>fs.existsSync(f)).map(p=>'\"'+p+'\"').join(' ');const o=execSync('git status --porcelain -- '+args,{encoding:'utf8'}).replace(/\s+$/,'');if(o.length>0){console.error('EXISTING 04-01..04-09 ARTIFACTS MODIFIED: '+o);process.exit(1)}const plans=fs.readdirSync(dir).filter(f=>/-PLAN\.md$/.test(f)).sort();const extra=plans.filter(p=>!/^04-(0[1-9]|10)-PLAN\.md$/.test(p));if(extra.length>0){console.error('UNEXPECTED PLAN FILES '+extra.join(','));process.exit(1)}if(plans.length!==10){console.error('PLAN COUNT '+plans.length+' expected 10');process.exit(1)}if(!fs.readdirSync(dir).some(f=>f==='04-10-SUMMARY.md')){console.error('MISSING 04-10 SUMMARY');process.exit(1)}console.log('OK 04-01..04-09 untouched; plans '+plans.join(','))"</automated>
|
||||
@ -466,10 +467,10 @@ Phase 4 第十个增量(用户裁定 2026-09-23 · D-51..D-57 **第一步**)
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- `## 处置` 定稿,明写:本步只读、生产代码零改动、零命名变更、唯一交付物、相对只读起始基线零变化、**第二步未规划**(D-57)、被查范围含全部 importer 与其它 monorepo 包(`packages/` 与 `src/` 仅报告)、**D 类解耦方案由用户裁定**、**E 类按 D-55 只报告不修不登记待办**、**全部命名归用户**(AGENTS.md)、`REND-01` / `REND-02` 保持 Pending,并(如与规划日不同)说明实测差异
|
||||
- D 类 **≥ 9 行**,覆盖反向依赖候选 4 族(`shared.ts` / `renderer` / `use.ts` / `render/utils`)、自包引用 5 处、`client-base/package.json` 依赖缺口、反向依赖现状机器证据、shader `?raw`、`dev.md` 规则对照;每行含风险源与基准锚点两个 `file:line`;**无任何自拟解耦方案**
|
||||
- E 类 **≥ 6 行**,标题下明写「仅报告」边界,覆盖 `core.*` 逐文件汇总(含 `file:line` 与核对命令输出)、`loading` + `Mota.require`、`client.*` 0 命中机器证据、`packages/` 与 `src/` 对照扫描、`elements/cache.ts` legacy 贴图路径现状;**无任何修复性措辞**
|
||||
- D 类 **≥ 9 行**,覆盖反向依赖候选 4 族(`shared.ts` / `renderer` / `use.ts` / `render/utils`)、自包引用 5 处、`client-base/package.json` 依赖缺口、反向依赖现状机器证据、shader `?raw`、`dev.md` 规则对照;每行含风险源与基准锚点 ≥2 个完整 `文件:行`(`packages-user/client-base/package.json:…` 与 `dev.md:…` 基准锚点由识别正则计入);**无任何自拟解耦方案**
|
||||
- E 类 **≥ 6 行**,标题下明写「仅报告」边界,覆盖 `core.*` 逐文件汇总(含 `file:line` 与核对命令输出)、`loading` + `Mota.require`、`client.*` 0 命中机器证据(`#04-10-E-04 [证据行]`)、`packages/` 与 `src/` 对照扫描(`#04-10-E-05 [证据行]`)、`elements/cache.ts` legacy 贴图路径现状(`#04-10-E-06`,以 `04-CONTEXT.md:75` / `04-07-SUMMARY.md:174` 为基准锚点);`E-01` / `E-04` / `E-05` 三条证据行带 `[证据行]` 标记与 `git grep` 证据;**无任何修复性措辞**
|
||||
- F 类 **≥ 9 条** `#04-10-F-*` 未确定项,覆盖目标命名、`render/utils/index.ts` 归属、barrel 扩张 / 断链补位、反向依赖解耦、自包引用改写、依赖缺口补齐、`?raw` 可行性、legacy 插件面、`createElements()` 注册点接线;**均未写成错配 / 缺失 / 残留 / 待办**
|
||||
- 五道门禁全部转绿:只读门禁(porcelain 逐条一致 + `04-CONTEXT.md` 未提交改动仍在 + `REQUIREMENTS.md` 未改动且 `REND-01` / `REND-02` 仍 `Pending`)、类别门禁(A ≥ 8 / B ≥ 8 / C ≥ 7 / D ≥ 9 / E ≥ 6 / F ≥ 9 且每行双锚点与关键词齐备、`## 处置` 存在)、机器证据复验(两处零命中)、既有产物保护 + 计划范围门禁(`04-01..04-09-*` 未改写、无 `04-11+`、`04-10-SUMMARY.md` 已落盘)、CRLF 门禁
|
||||
- 五道门禁全部转绿:只读门禁(porcelain 逐条一致 + `04-CONTEXT.md` 未提交改动仍在 + `REQUIREMENTS.md` 未改动且 `REND-01` / `REND-02` 仍 `Pending`)、类别门禁(A ≥ 8 / B ≥ 8 / C ≥ 7 / D ≥ 9 / E ≥ 6 / F ≥ 9 且事实·基准行双锚点、证据行 `[证据行]` 标记与 `git grep` 证据、关键词齐备、`## 处置` 存在)、机器证据复验(两处零命中)、既有产物保护 + 计划范围门禁(`04-01..04-09-*` 未改写、无 `04-11+`、`04-10-SUMMARY.md` 已落盘)、CRLF 门禁
|
||||
- 人工代码复核结论已记录(抽查 A 类 4 处、B 类 2 处深层导入、C 类 2 处断链点、D 类 `?raw` 与 `client-base/package.json`、E 类 `cache.ts:491-492`),偏差均已修正
|
||||
- `04-10-SUMMARY.md` 已产出,如实记录当日实测值、A–F 实际行数与关键结论、五道门禁结果、人工复核结论、与规划日的差异说明、`REND-01` / `REND-02` 仍 Pending 与「第二步未规划」;**未写入任何移植方案 / import 重写方案 / 命名**
|
||||
- 提交仅含 `04-STRUCTURE-MIGRATION-IMPACT.md`、`04-10-PLAN.md`、`04-10-SUMMARY.md`(及属本次 ROADMAP 登记时的 ROADMAP 改动,若适用);未纳入任何生产源码改动与用户既有未提交改动;未改写 `04-01..04-09-*`
|
||||
@ -502,11 +503,11 @@ Phase 4 第十个增量(用户裁定 2026-09-23 · D-51..D-57 **第一步**)
|
||||
| T-04-10-01 | Tampering | 生产源码 `packages-user` / `packages` / `src` | high | mitigate | Task 1 步骤 (0a) 记录 `git status --porcelain -- packages packages-user src` 的逐行基线(规划日单条);Task 1 / Task 3 门禁断言其后逐条一致;Task 3 另断言 `.planning/REQUIREMENTS.md` 未改动;`files_modified` 仅含交付文档;prohibitions 明列生产文件零改动、不得预建 / 复制目标目录与文件 |
|
||||
| T-04-10-02 | Elevation of Privilege | 执行前置关卡(AGENTS.md 要求的第一处 block 点) | high | mitigate | Task 0 为 `checkpoint:decision` + `gate="blocking-human"` 且本计划 `autonomous: false`;Task 0 的 action ⑩ / ⑪ 与 acceptance_criteria 明示未收到用户「可以执行」四个字即必须停止、不派发执行子代理;`yolo` / `workflow.auto_advance` 不得自动放行 |
|
||||
| T-04-10-03 | Tampering | 用户并发改动(D-56) | high | mitigate | Task 1 / Task 3 门禁除 porcelain 逐条一致外,另断言 `.planning/phases/04-render-adaptation/04-CONTEXT.md` 的未提交改动仍在(消失即失败);prohibitions 明列不得回滚 / 暂存 / 提交用户改动;Task 3 提交仅列三个(或四个)白名单文件 |
|
||||
| T-04-10-04 | Spoofing | A / B / C / D / E 分类 | high | mitigate | 分列规则写死(A 集合内部交叉引用 / B 集合之外导入点 / C barrel 与断链 / D 分层风险 / E legacy 只报告 / F 未确定);每行强制两个 `file:line` 锚点;门禁机器判定行数下限、关键词与双锚点 |
|
||||
| T-04-10-04 | Spoofing | A / B / C / D / E 分类 | high | mitigate | 分列规则写死(A 集合内部交叉引用 / B 集合之外导入点 / C barrel 与断链 / D 分层风险 / E legacy 只报告 / F 未确定);事实·基准行强制 ≥2 个完整 `文件:行`(`.json` / `.md` 基准也计);零命中 / 对照扫描证据行(`A-09` / `B-09` / `E-01` / `E-04` / `E-05`)强制 `[证据行]` 标记 + `git grep` 证据;门禁机器判定行数下限、关键词、双锚点与证据行白名单 |
|
||||
| T-04-10-05 | Spoofing | 「零命中 / 零反向依赖」结论 | high | mitigate | 不以文档自述为准:Task 1 / Task 2 / Task 3 门禁直接运行 `git grep -n -F` 固定串检索(`client-modules` 于 `client-base`、`../ui` / `../fx` / `../weather` 于被移集合),非零输出即失败;`.planning/graphs/*` 的过期标签声明不计入源码命中 |
|
||||
| T-04-10-06 | Tampering | legacy 范围(D-55) | high | mitigate | `## E legacy 命中(仅报告)` 标题下明写「不修、不登记为待办」;Task 3 类别门禁要求 E 节含「仅报告」措辞与 `core.` / `loading` / `Mota.require` / `packages/` / `src/` 关键词;prohibitions 明列不得把 legacy 写成问题 / 待办 |
|
||||
| T-04-10-07 | Elevation of Privilege | 命名权(AGENTS.md) | high | mitigate | 全部命名问题强制归 F 类(Task 3 类别门禁要求 F 类含命名方向条目);prohibitions 明列「不得为目标文件 / 目录命名拍板」;`## 处置` 明写命名归用户 |
|
||||
| T-04-10-08 | Repudiation | A–E 各行条目不可追溯 | medium | mitigate | 固定列序(`ID | 文件/符号 | 命中处(源) | 目标锚点 | 问题描述 | 影响 | 置信`)+ 每行 ≥2 个 `file:line` 锚点 + 行数下限 + 关键词齐备 + 被移集合 39 文件逐条清单,由 Task 1 / Task 2 / Task 3 门禁机器判定 |
|
||||
| T-04-10-08 | Repudiation | A–E 各行条目不可追溯 | medium | mitigate | 固定列序(`ID | 文件/符号 | 命中处(源) | 目标锚点 | 问题描述 | 影响 | 置信`)+ 事实·基准行每行 ≥2 个完整 `文件:行` 锚点(`.json` / `.md` 基准也计)+ 证据行 `[证据行]` 标记与 `git grep` 证据 + 行数下限 + 关键词齐备 + 被移集合 39 文件逐条清单,由 Task 1 / Task 2 / Task 3 门禁机器判定 |
|
||||
| T-04-10-09 | Elevation of Privilege | 清点范围(纳入 `ui` / `fx` / `weather`、为 `packages/` 与 `src/` 提修改、提前规划第二步) | medium | mitigate | D-52 / D-54 / D-33 / D-57 为显式边界:清单节只列 39 文件并明写不移动不复制不预建;E 节只报告;prohibitions 禁提移植 / 重写方案;Task 3 门禁禁止出现 `04-11+` 计划文件与前序产物改写 |
|
||||
| T-04-10-10 | Denial of Service | 只读子代理越权写入(D-09) | low | mitigate | Task 2 步骤 (4) 明确子代理仅回传事实表、不得写文件、不得贴大段源码;最终由主执行者以只读门禁 + 类别门禁 + 机器证据复验统一验证 |
|
||||
| T-04-10-11 | Information Disclosure | 清点文档引用的源码行与符号名 | low | accept | 记录只含符号名、文件行号、成员签名与目录结构,不含凭据 / 密钥 / 个人数据 |
|
||||
@ -515,7 +516,7 @@ Phase 4 第十个增量(用户裁定 2026-09-23 · D-51..D-57 **第一步**)
|
||||
|
||||
<verification>
|
||||
- **只读门禁**:`git status --porcelain -- packages packages-user src` 的输出与交付文档 `## 方法` 的「只读起始基线」条目逐条一致(不新增、不消失、状态码不变);并断言 `.planning/phases/04-render-adaptation/04-CONTEXT.md` 的未提交改动仍在(D-56)、`.planning/REQUIREMENTS.md` 未被改动且 `REND-01` / `REND-02` 仍为 `Pending`。
|
||||
- **静态内容门禁**:交付文档恰好 10 个二级标题;被移集合 **39** 个文件路径逐条出现(`components` 13 / `elements` 5 / `map` 20 / `utils/layout.ts` 1);A ≥ 8 行 / B ≥ 8 行 / C ≥ 7 行 / D ≥ 9 行 / E ≥ 6 行 / F ≥ 9 条;A–E 每行 ≥2 个 `file:line` 锚点;A / B / C / D / E 覆盖各自关键词集合;E 含「仅报告」措辞;`## 处置` 存在。
|
||||
- **静态内容门禁**:交付文档恰好 10 个二级标题;被移集合 **39** 个文件路径逐条出现(`components` 13 / `elements` 5 / `map` 20 / `utils/layout.ts` 1);A ≥ 8 行 / B ≥ 8 行 / C ≥ 7 行 / D ≥ 9 行 / E ≥ 6 行 / F ≥ 9 条;A–E 的事实·基准行每行 ≥2 个完整 `文件:行` 锚点(识别正则接受 `.(tsx?|frag|vert|json|md):\d+`,故 `package.json` / `dev.md` / `04-CONTEXT.md` 基准也计);`#04-10-A-09` / `#04-10-B-09` / `#04-10-E-01` / `#04-10-E-04` / `#04-10-E-05` 五条证据行带 `[证据行]` 标记与 `git grep` 证据(豁免 ≥2 计数);A / B / C / D / E 覆盖各自关键词集合;E 含「仅报告」措辞;`## 处置` 存在。
|
||||
- **机器证据复验**:`git grep -n -F "client-modules" -- packages-user/client-base`,以及 `git grep -n -F "../ui"` / `-F "../fx"` / `-F "../weather"` 三个**独立**检索(同限被移集合四个路径),逐一无输出(退出码 1);`git grep -n -F "render/components"` / `-F "render/elements"` / `-F "render/map"` 三个**独立**检索(同限 `packages` 与 `src`)在 `packages/` 与 `src/` 零命中。
|
||||
- **既有产物保护 + 计划范围门禁**:`git status --porcelain -- <04-01..04-09 的 PLAN 与 SUMMARY>` 为空;phase 目录内 `-PLAN.md` 恰为 `04-01`..`04-10` 共 10 个;`04-10-SUMMARY.md` 已存在。
|
||||
- **CRLF 门禁**:交付文档的 `\n` 总数等于 `\r\n` 总数(无孤立 LF)。
|
||||
@ -535,5 +536,5 @@ Create `.planning/phases/04-render-adaptation/04-10-SUMMARY.md` when done
|
||||
| `.planning/phases/04-render-adaptation/04-10-PLAN.md` | 计划簿记 | 本计划(编号 04-10;`wave: 9`;`depends_on` 04-01..04-09;`autonomous: false`) |
|
||||
| `.planning/phases/04-render-adaptation/04-10-SUMMARY.md` | 执行簿记 | 当日实测值(porcelain 基线、被移集合实际文件数)、A–F 实际行数与关键结论、五道门禁结果、人工复核结论、与规划日的差异说明、`REND-01` / `REND-02` 仍 Pending 与「第二步未规划」 |
|
||||
| `.planning/ROADMAP.md`(Phase 4 的 Wave 9 登记 + register note) | 计划簿记 | 登记第十个增量 `04-10`(只读影响清点)与执行前置关卡要求 |
|
||||
| 门禁结果(会话内可复跑) | 验证证据 | 只读门禁(porcelain 逐条一致 + 用户改动仍在 + `REQUIREMENTS.md` 未改动且 REND 仍 Pending)、静态内容门禁(10 节 / 39 文件 / A–F 行数与双锚点)、机器证据复验(两处零命中)、既有产物保护 + 计划范围门禁(`04-01..04-09-*` 未改写、无 `04-11+`、SUMMARY 已落盘)、CRLF 门禁 |
|
||||
| 门禁结果(会话内可复跑) | 验证证据 | 只读门禁(porcelain 逐条一致 + 用户改动仍在 + `REQUIREMENTS.md` 未改动且 REND 仍 Pending)、静态内容门禁(10 节 / 39 文件 / A–F 行数与事实·基准行双锚点 + 证据行 `[证据行]` 标记)、机器证据复验(两处零命中)、既有产物保护 + 计划范围门禁(`04-01..04-09-*` 未改写、无 `04-11+`、SUMMARY 已落盘)、CRLF 门禁 |
|
||||
| 显式**不**产出 | 边界声明 | 任何生产代码改动、任何文件移动 / 复制 / 预建、任何测试文件、任何依赖变更(含 `package.json` 补声明)、任何命名、任何移植方案或 import 重写方案(D-57:第二步待用户审阅本文件后另行规划)、任何针对 legacy 的修复方案(D-55) |
|
||||
|
||||
@ -44,5 +44,5 @@
|
||||
"label": "Advance to the next step",
|
||||
"reason": "Phase 04 of 7 · executing"
|
||||
},
|
||||
"updated_at": "2026-09-23T06:46:17.246Z"
|
||||
"updated_at": "2026-09-24T06:31:01.495Z"
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user