docs(09): add plan 09-11 for task 5 legacy interface read-only audit

Task 5 (D-42..D-45): produce a read-only statistics doc covering exactly packages-user/client-base and packages-user/client-modules. Categories: A residual legacy interfaces, B @deprecated, C core.* call sites. Zero source edits.
This commit is contained in:
unanmed 2026-10-11 16:18:29 +08:00
parent 00379e1861
commit 741e8e09ce
2 changed files with 323 additions and 2 deletions

View File

@ -481,7 +481,7 @@ Plans:
**Goal**: 在已完成的数据端(可在 Node 环境独立运行/回放验证)之上完成渲染端框架,产出可在浏览器中运行并验证的最小版本
**Requirements**: TBD
**Depends on**: Phase 8
**Plans**: 10/10 plans executed (任务 1·UI 接口适配,D-10..D-14 已闭环;任务 2·迁移后 UI 修复,D-15..D-17 已闭环;任务 3·legacy UI 移植,book/equipbox/toolbox 已规划(09-06..09-08)并已按用户补齐的数据端接口修订——裸怪物临界 `calculateEnemyCritical`、与空装备对比 `compareEquip(-1)`、道具枚举 `iterateItems`、`@user/data-system` 依赖已声明;shop 已规划(09-09,D-38..D-41)并已按用户补齐的接口修订——价格 `IShopState.getPrice`/`setPrice`(GAP-S1 闭合)、交易 `IShopSystem.buyItem`/`sellItem`(GAP-S2 闭合)、支付资源 `money`(GAP-S3 闭合)、`IShopState` 已从 `@user/data-base` 导出(GAP-S0 闭合),**GAP-S4 已闭合(用户补齐 `@user/data-system` 的 `shop` 导出:`data-system/src/index.ts` `export * from './shop'` + `data-system/src/shop/index.ts`,`IShopSystem` / `IShopHeroAttr` 现可导入)**;本阶段增量派发,其余任务待用户再派发)
**Plans**: 10/10 plans executed (任务 1·UI 接口适配,D-10..D-14 已闭环;任务 2·迁移后 UI 修复,D-15..D-17 已闭环;任务 3·legacy UI 移植,book/equipbox/toolbox 已规划(09-06..09-08)并已按用户补齐的数据端接口修订——裸怪物临界 `calculateEnemyCritical`、与空装备对比 `compareEquip(-1)`、道具枚举 `iterateItems`、`@user/data-system` 依赖已声明;shop 已规划(09-09,D-38..D-41)并已按用户补齐的接口修订——价格 `IShopState.getPrice`/`setPrice`(GAP-S1 闭合)、交易 `IShopSystem.buyItem`/`sellItem`(GAP-S2 闭合)、支付资源 `money`(GAP-S3 闭合)、`IShopState` 已从 `@user/data-base` 导出(GAP-S0 闭合),**GAP-S4 已闭合(用户补齐 `@user/data-system` 的 `shop` 导出:`data-system/src/index.ts` `export * from './shop'` + `data-system/src/shop/index.ts`,`IShopSystem` / `IShopHeroAttr` 现可导入)**;本阶段增量派发,其余任务待用户再派发;**任务 5(09-11·legacy 接口只读统计)已规划、待用户派发后执行(只读产物,wave 8)**)
Plans:
**Wave 1**
@ -515,6 +515,10 @@ Plans:
- [x] 09-10-PLAN.md — 任务 3·复查修正(R-1..R-8):对 `book.tsx`/`bookDetail.tsx`/`equipbox.tsx`/`toolbox.tsx`/`shop.tsx` 统一应用——R-1 移除自绘背景、R-2 长文本改 `TextContent`、R-3 顶层 jsDoc、R-4 JSX 分段注释、R-5 取消 `IShopItemEntry`/`IHeroAttrItem` 导出、R-6 非空判断(字面量 `isNil`/对象 `!`,去 `=== null`/`=== undefined`)、R-7 `shop` 的 `openShop` 移入 `onMounted`、R-8 `bookDetail` 改 `instanceof EnemyView`(已核实 `EnemyView` 为运行期类)
**Wave 8** *(独立于 Wave 6/7 · 任务 5·legacy 接口只读统计,只读产物)*
- [ ] 09-11-PLAN.md — 任务 5·legacy 接口只读统计(D-42..D-45):只读扫描 `packages-user/client-base` + `packages-user/client-modules` 两包,产出统计文档 `.planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md`(第 0 节分类口径 A-1..A-7 + A 残余 legacy 接口 + B `@deprecated` + C `core.*` 调用点 + 汇总表 + 每类计数);**全程只读,零 `.ts`/`.tsx` 改动**
## Progress
**Execution Order:**
@ -530,4 +534,4 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 →
| 6. 单元测试 | 18/18 | Obsolete(由 Phase 9 承接) | - |
| 7. 数据端缺陷修复 | 15/16 | Complete(07-16 superseded) | - |
| 8. 测试重构与接口对齐 | 11/11 | Complete | 2026-10-08 |
| 9. 最小浏览器可运行版本 | 10/10 | In Progress| |
| 9. 最小浏览器可运行版本 | 10/11 | In Progress| |

View File

@ -0,0 +1,317 @@
---
phase: 09-minimum-browser-runnable
plan: 11
type: execute
wave: 8
depends_on: []
files_modified:
- .planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md
- .planning/phases/09-minimum-browser-runnable/09-11-SUMMARY.md
autonomous: false
requirements: []
estimate:
tokens: 52000
raw_tokens: 52000
tasks: 3
confidence: low
must_haves:
truths:
- "**本计划的第一个 block 点是 Task 0 的 `blocking-human` 汇报关卡(AGENTS.md 硬要求,D-03 / D-44)**:Task 0 必须先汇报「本计划 = 任务 5 · legacy 接口只读统计」的要做什么 / 为什么 / 大致怎么做 / 影响范围,**必须列明统计范围(恰好两个包)、`legacy` 分类口径(A-1..A-7)、三大统计类别(A/B/C)、每类计数与汇总表、产出文档路径(须用户批准)、只读保证与开放项**,然后必须**停下等待**用户明确回复「可以执行」四个字;未收到前不得执行本计划任何一步、不得派发执行子代理,且不因触发方式或 `mode: yolo` / `workflow.auto_advance` 自动放行。"
- "**D-42(范围):** 统计**恰好**覆盖 `packages-user/client-base` 与 `packages-user/client-modules` 两个包内的 `.ts` / `.tsx` 源码,**排除** `node_modules`、`dist` 与任何生成物;**不外扩**到其它包(`packages/**`、`packages-user/data-**`、`packages-user/client-system`、`entry-*`、`src/`)。"
- "**D-43①(A. 残余的 legacy 接口):** 按文档内**显式定义**的分类口径枚举残余 legacy 接口 / 构造,逐条给出精确 `file:line` 锚点。口径:A-1 跨包 legacy 依赖(`import ... from '@motajs/legacy-ui' | '@motajs/legacy-common' | '@motajs/legacy-system'`);A-2 legacy 全局 `core`(声明于 `src/types/declaration/core.d.ts`,调用点归 C 类并交叉引用);A-3 legacy 单例 `client`(`client-modules/src/core.ts` 导出及其使用点);A-4 legacy patch 机制(`Patch` / `PatchClass` 及其 `.add(...)`);A-5 legacy UI 运行时符号(`mainUi` / `mainSetting` / `getVitualKeyOnce` / `triggerFullscreen`);A-6 legacy `Mota` 全局(`Mota.require(...)`);A-7 legacy 兼容 / 回退层(`client-modules/src/fallback/**`,含用户所称 data-fallback)。"
- "**D-43②(B. 标注 `@deprecated` 的接口):** 在两包内扫描 `@deprecated` JSDoc 标注,逐条给出 `file:line` + 符号 + 说明;**若实测为 0 条,必须显式报告「0 条」并写明扫描范围与匹配方式**(不得省略该节)。**规划日实测两包内 `@deprecated` 命中为 0**(全仓其它位置有命中,但不在本统计范围内)。"
- "**D-43③(C. 所有经 `core.*` 调用的接口):** 枚举两包内**全部经 legacy 全局 `core.<member>` 的调用点**(仅代码,**排除注释与字符串字面量**),给出 (a) 去重后的成员清单 `core.<member>`,(b) 按文件的 `file:line` 调用点,(c) 每类计数。**规划日实测**:`client-base` 出现 `core.*` 的文件含 `components/choices.tsx`、`components/floorSelect.tsx`、`components/misc.tsx`、`components/textboxTyper.ts`、`components/thumbnail.tsx`、`components/tip.tsx`、`elements/cache.ts`、`elements/misc.ts`、`shared.ts`;`client-modules` 出现 `core.*` 的文件含 `action/hotkey.ts`、`action/move.ts`、`fallback/audio.ts`、`fallback/load.ts`、`render/utils/saves.ts`、`render/weather/presets/{cloud,fog,sun}.ts`、`ui/{book,bookDetail,main,save,settings,shop,statistics,statusBar,title,toolbar,toolbox,viewmap}.tsx`、`client.ts`、`shared.ts`。"
- "**D-44(产出):** 产出一份统计文档于 `.planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md`(**新命名产物,须 Task 0 呈报用户批准**),含第 0 节(口径与范围)、A/B/C 三节、**汇总表**与**每类计数**(机器可读行 `A-COUNT:` / `B-COUNT:` / `C-COUNT:`)。"
- "**D-45(只读):** 全程**只读**——**禁止**修改 / 删除 / 新增任何生产 `.ts` / `.tsx` 源码,**禁止**任何改造或修复;本计划**唯一允许写入**的文件是统计文档 `09-LEGACY-INTERFACES-AUDIT.md` 与 `09-11-SUMMARY.md`。"
- "**分类口径显式化 + 每条有据:** 「legacy」定义宽泛,文档第 0 节必须**显式定义**判定基准与 A-1..A-7 子类,**不得臆造条目**;文档中每个 `file:line` 锚点须指向真实存在且行号在范围内的行(门禁逐一校验)。"
- "**范围零外溢 + 静态门禁:** 仅新增上述两文档;**不修改** 09-01..09-10 任何文件、不修改任何 `.ts`/`.tsx`、不修改 `ROADMAP.md` 以外任何既有规划文件;验证一律为**静态断言**(文档存在 / 含 A·B·C 节 / 含每类计数 / 含汇总 / 锚点有效 / 两包均覆盖 / 只读守卫),**不使用** `pnpm check:type` / `pnpm build` / 全仓 TS 诊断数作门禁。"
artifacts:
- path: .planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md
provides: "任务 5 的只读统计文档:第 0 节分类口径 + A(残余 legacy 接口)+ B(`@deprecated`)+ C(`core.*` 调用点)+ 汇总表 + 每类计数。"
- path: .planning/phases/09-minimum-browser-runnable/09-11-SUMMARY.md
provides: "本计划的执行摘要:统计范围、分类口径、A/B/C 计数、产出路径、只读确认。"
key_links:
- "`packages-user/client-modules/src/action/hotkey.ts:3`、`fallback/audio.ts:1-2`、`fallback/ui.ts:1`、`fallback/weather.ts:1`、`ui/settings.tsx:13,15`、`ui/title.tsx:28`、`ui/toolbar.tsx:14,20` ↔ `@motajs/legacy-ui` / `@motajs/legacy-common` / `@motajs/legacy-system` —— A-1 / A-4 / A-5 的跨包 legacy 依赖来源"
- "`src/types/declaration/core.d.ts` ↔ legacy 全局 `core` 声明处 —— A-2(legacy 接口本体)与 C 类调用点的类型来源"
- "`packages-user/client-modules/src/core.ts:6`(`export const client = new ClientCore(...)`)↔ `fallback/audio.ts:5,11`(`import { client }` / `const { ... } = client`)—— A-3 legacy 单例 `client` 的定义与使用"
- "`packages-user/client-base/src/elements/misc.ts:89,219`、`elements/cache.ts:491` ↔ legacy 全局 `Mota`(`Mota.require('@user/data-base')`)—— A-6 legacy `Mota` 全局"
- "`packages-user/client-modules/src/fallback/**`(`index.ts` / `audio.ts` / `ui.ts` / `weather.ts` / `load.ts`)—— A-7 legacy 兼容 / 回退层(含 data-fallback)"
assumptions:
- "**执行日行号可能漂移**:本计划内引用行号为 2026-10-11 规划日实测;文档锚点与门禁以**执行日实测**为准,门禁按「文件存在 + 行号在范围内」校验,不硬编码任何行号。"
- "**`@deprecated` 两包内实测为 0**:规划日已用全量文件扫描(含 `.ts` / `.tsx`)确认两包内无 `@deprecated`;执行日须**复扫**并以实测为准,若出现则如实登记。"
- "**「data-fallback」无同名符号**:规划日在 `packages`、`packages-user`、`src`(排除 `node_modules`)中未检索到字面量 `data-fallback` / `dataFallback`;本计划将 A-7 定义为 `client-modules/src/fallback/**` 兼容 / 回退层及 `Mota.require('@user/data-*')` 式数据回退。若用户所指另有其事,据其指定补充。"
- "**Markdown 使用 LF**:仓库既有 phase 文档(`09-06-PLAN.md` / `09-10-PLAN.md` / `09-10-SUMMARY.md` / `ROADMAP.md`)均为裸 LF;新文档随此约定(**不**强制 CRLF)。"
- "**`core.*` 统计口径**:仅计**代码**中的 `core.<member>` 访问(含 `core.status.x` 这类取首成员 `status`),**排除**注释(`//` / `/* */`)与字符串字面量(如注释中的 `core.js` 不算)。"
prohibitions:
- "不得在用户明确回复「可以执行」四个字之前执行本计划的任何任务、或派发任何执行子代理。"
- "本计划**只做只读统计并产出文档**:**不得**修改 / 删除 / 新增任何生产 `.tsx` / `.ts` 源码;**不得**做任何改造、修复、迁移或接线(改造属后续另行规划,D-45)。"
- "**只读边界:** 除 `09-LEGACY-INTERFACES-AUDIT.md` 与 `09-11-SUMMARY.md` 两个文档外,**不得写入任何文件**;不得改 09-01..09-10 及其产物;不得改 `ROADMAP.md` 以外任何既有规划文件。"
- "**不得臆造条目:** 文档中每个 `file:line` 锚点必须指向真实存在且范围内的一行;不得凭印象编造成员名 / 调用点;分类口径须在第 0 节显式给出。"
- "不得把门禁建立在「全仓 TS 诊断数」「`pnpm check:type`」「`pnpm build`」之上;不得为了「验证」去改动源码。"
- "不得触碰、暂存、提交用户的并发改动(D-56):提交前 `git status` 逐条核对暂存面,只暂存本计划 `files_modified` 的条目。"
open_items:
- "**OI-1(产出文档命名 / 路径,D-44):** 提议 `.planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md`(连字符命名法,随仓库 Markdown 约定)。**待用户批准。**"
- "**OI-2(分类口径 A-1..A-7):** 提议以「legacy 包依赖 / legacy 全局 `core` / legacy 单例 `client` / legacy patch 机制 / legacy UI 运行时符号 / legacy `Mota` 全局 / legacy 兼容回退层」七子类界定。**待用户确认**;若用户要增删子类,据其指定。"
- "**OI-3(data-fallback 所指):** 规划日未检索到 `data-fallback` 同名符号;暂归 A-7(`client-modules/src/fallback/**` 及 `Mota.require('@user/data-*')`)。若用户所指另有其事,请指明。"
- "**OI-4(B 类为 0 的呈现):** 若执行日复扫仍为 0,文档 B 节**显式报告 0 条**并写明扫描范围与匹配方式(不省略该节)。请确认此呈现方式。"
- "**OI-5(C 类粒度):** 默认给出「去重成员清单 + 按文件 `file:line` 调用点 + 每文件计数」;是否需要额外按 `core.<member>` 维度汇总计数,请指明(默认一并给出)。"
---
<objective>
Phase 9 · 任务 5 · 第 11 个计划 —— **legacy 接口只读统计**(范围恰好 `packages-user/client-base` 与 `packages-user/client-modules`,产出**一份统计文档**)。
**要解决的问题(D-42..D-45):** 为后续「legacy 移植 / 去 legacy」改造提供一份**有据可查的只读台账**,精确枚举两包内 ① 残余 legacy 接口、② 标注 `@deprecated` 的接口、③ 所有经 `core.*` 调用的接口,逐条给出 `file:line` 锚点,并给出每类计数与汇总表。**本计划不做任何改造**(D-45 只读)。
**大致解决方案(本计划 = 09-11):**
- **Task 0(`blocking-human`)= 预执行汇报关卡**:汇报统计范围、`legacy` 分类口径(A-1..A-7)、三大类别 A/B/C、每类计数与汇总形式、产出文档路径(OI-1)、只读保证与开放项 OI-1..OI-5,并等待用户「可以执行」。
- **Task 1 = 扫描并撰写文档骨架 + A 节 + B 节**:建立第 0 节分类口径(含方法论与只读声明),枚举 A(残余 legacy 接口,含跨包 legacy 依赖 / 单例 / patch / UI 符号 / `Mota` / 回退层)与 B(`@deprecated`,实测若 0 则显式报告 0),给出 A / B 计数。
- **Task 2 = 扫描并撰写 C 节 + 汇总表 + 收口门禁**:枚举 C(`core.*` 调用点:去重成员清单 + 按文件 `file:line` + 每文件计数),补齐汇总表与机器可读计数(`A-COUNT:` / `B-COUNT:` / `C-COUNT:`),跑最终静态门禁(含锚点有效性与只读守卫),写 `09-11-SUMMARY.md`。
**为何先 A/B 后 C:** A/B 体量小、依赖分类口径先立;C 是重头(跨 ~28 个文件),单独成节并承载汇总与只读收口。三任务同属一个只读产物,无 `files_modified` 外扩。
**API coverage:** `detected:false`。**`No external API integration: 本计划仅为只读源码统计与文档撰写,不涉及任何外部 API。`**
</objective>
<execution_context>
@C:/Users/13194/.config/opencode/gsd-core/workflows/execute-plan.md
@C:/Users/13194/.config/opencode/gsd-core/templates/summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/09-minimum-browser-runnable/09-CONTEXT.md
@.planning/phases/09-minimum-browser-runnable/09-06-PLAN.md
@AGENTS.md
@dev.md
</context>
<tasks>
<task type="checkpoint:decision" gate="blocking-human">
<name>Task 0: 预执行汇报关卡 —— 汇报「任务 5 · legacy 接口只读统计」的范围、分类口径、A/B/C 类别与产出路径,等待用户回复「可以执行」</name>
<precondition>`packages-user/client-base/src` 与 `packages-user/client-modules/src` 均存在;两包内跨包 legacy 依赖(`@motajs/legacy-*`)仍在(如 `client-modules/src/action/hotkey.ts:3`);统计文档 `09-LEGACY-INTERFACES-AUDIT.md` 与 `09-11-SUMMARY.md` **尚不存在**。</precondition>
<files>(只读汇报,不修改任何文件)</files>
<read_first>
- .planning/phases/09-minimum-browser-runnable/09-CONTEXT.md(D-03 / D-04 / D-06 / **D-42 / D-43 / D-44 / D-45**)
- .planning/phases/09-minimum-browser-runnable/09-11-PLAN.md(本计划全文,含分类口径 A-1..A-7 与 OI-1..OI-5)
- AGENTS.md(执行前须获批、命名须先反馈、修改方式须预先声明);dev.md(命名规则、注释规范、Markdown 连字符命名、CRLF 约定)
</read_first>
<action>
**停下并向用户汇报,等待明确回复「可以执行」后才继续;汇报本身只读。**
① **要解决的问题:** 任务 5 · legacy 接口只读统计。为后续 legacy 改造提供有据可查的只读台账——精确枚举两包内 ① 残余 legacy 接口、② `@deprecated` 接口、③ `core.*` 调用点,逐条给出 `file:line` 锚点 + 每类计数 + 汇总表。**只读,不改造。**
② **统计范围(D-42):** 恰好 `packages-user/client-base` 与 `packages-user/client-modules` 两包内的 `.ts` / `.tsx`(排除 `node_modules` / `dist`);不外扩到 `packages/**`、`packages-user/data-**`、`client-system`、`entry-*`、`src/`。
③ **`legacy` 分类口径(D-43①,须用户确认,OI-2):** 显式定义七子类——**A-1** 跨包 legacy 依赖(`import ... from '@motajs/legacy-ui' | '@motajs/legacy-common' | '@motajs/legacy-system'`);**A-2** legacy 全局 `core`(声明于 `src/types/declaration/core.d.ts`;调用点归 C 类并交叉引用);**A-3** legacy 单例 `client`(`client-modules/src/core.ts:6` 导出及其使用点);**A-4** legacy patch 机制(`Patch` / `PatchClass` 及其 `.add(...)`);**A-5** legacy UI 运行时符号(`mainUi` / `mainSetting` / `getVitualKeyOnce` / `triggerFullscreen`);**A-6** legacy `Mota` 全局(`Mota.require(...)`);**A-7** legacy 兼容 / 回退层(`client-modules/src/fallback/**`,含用户所称 data-fallback,OI-3)。
④ **三大类别与形式(D-43):**
- **A(残余 legacy 接口):** 表 `file:line | 符号 | 来源包 / 子类 | 说明` + **A 计数**。
- **B(标注 `@deprecated` 的接口):** 表 `file:line | 符号 | 说明` + **B 计数**;**规划日实测两包内为 0 条**,执行日复扫;若为 0 则**显式报告 0** 并写明扫描范围与匹配方式(OI-4)。
- **C(经 `core.*` 调用的接口):** 去重成员清单 `core.<member>` + 按文件 `file:line` 调用点 + 每文件计数 + **C 计数**;仅计代码,排除注释与字符串字面量。
⑤ **产出文档(D-44,须批准,OI-1):** 提议路径 `.planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md`;含第 0 节(口径与范围)、A / B / C 三节、**汇总表**、**每类计数**(机器可读行 `A-COUNT:` / `B-COUNT:` / `C-COUNT:`)。
⑥ **只读保证(D-45):** 全程只读;**禁止**修改 / 删除 / 新增任何生产 `.ts` / `.tsx`;本计划**唯一允许写入**的文件是上述统计文档与 `09-11-SUMMARY.md`。
⑦ **验证方式(须用户确认):** 静态断言——文档存在;含 `## 0.` / `## A.` / `## B.` / `## C.` / `## 汇总`;含每类计数(`A-COUNT:` / `B-COUNT:` / `C-COUNT:`);A/B/C 锚点逐一校验「文件存在 + 行号在范围内」;两包均被 C 覆盖;**只读守卫**(`git status` 无任何 `.ts` / `.tsx` 改动)。**不设全仓类型 / 构建门禁。**
⑧ **开放项与关卡性质:** 呈报 OI-1(文档路径)、OI-2(分类口径)、OI-3(data-fallback 所指)、OI-4(B=0 呈现)、OI-5(C 粒度)。**无论触发方式或 `mode: yolo` / `workflow.auto_advance`,执行者 / 子代理必须停下等待用户明确回复「可以执行」四个字**;回复其它内容视为未通过;若用户给出修订意见,退出本计划、修订后重新汇报。
</action>
<decision>是否按本计划执行任务 5 · legacy 接口只读统计(范围恰好两个包,产出 `09-LEGACY-INTERFACES-AUDIT.md`),并按分类口径 A-1..A-7 与 OI-1..OI-5 的默认处置产出文档(只读,不改任何源码)</decision>
<context>
AGENTS.md / D-03 / D-04 要求执行前与命名先获批;`.planning/config.json` 为 `mode: yolo`,故本关卡显式 `blocking-human` 且 `autonomous: false`。本次核心 = 分类口径确认 + 产出文档命名批准 + 只读边界确认 + B=0 的呈现方式 + C 类粒度。行号为规划日实测、可能漂移,文档锚点与门禁以执行日实测为准。
</context>
<options>
<option id="execute-default">
<name>可以执行(采纳全部默认处置)</name>
<pros>只读、零源码改动;分类口径清晰;产出可复核台账;命名按提议路径</pros>
<cons>无</cons>
</option>
<option id="execute-narrow">
<name>可以执行 + 收窄 A 类口径(仅 A-1 跨包 legacy 依赖 + C 类 `core.*`,不含 A-3/A-4/A-5/A-6/A-7)</name>
<pros>台账更短</pros>
<cons>遗漏单例 / patch / `Mota` / 回退层等残余 legacy 构造,违背 D-43①「残余 legacy 接口」之完整枚举意图</cons>
</option>
<option id="revise">
<name>修订范围 / 分类口径 / 产出路径后重新汇报</name>
<pros>避免带着错误口径产出文档</pros>
<cons>须修订 PLAN.md 后重新汇报</cons>
</option>
</options>
<resume-signal>回复「可以执行」四个字(如需调整 OI-1..OI-5 的处置,请在回复中指明;修订意见请按 action ⑧ 处理)</resume-signal>
<verify>
<automated>node -e "const fs=require('fs');const has=p=>fs.existsSync(p);const read=p=>fs.readFileSync(p,'utf8').replace(/\r\n/g,'\n');const bad=[];const doc='.planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md';const sum='.planning/phases/09-minimum-browser-runnable/09-11-SUMMARY.md';if(has(doc))bad.push('post-state: audit doc already exists');if(has(sum))bad.push('post-state: 09-11-SUMMARY already exists');if(!has('packages-user/client-base/src'))bad.push('missing client-base/src');if(!has('packages-user/client-modules/src'))bad.push('missing client-modules/src');if(has('packages-user/client-modules/src/action/hotkey.ts')){if(read('packages-user/client-modules/src/action/hotkey.ts').indexOf('@motajs/legacy-system')<0)bad.push('pre-state changed: hotkey legacy-system import gone')}else{bad.push('pre-state changed: hotkey.ts missing')}if(has('packages-user/client-modules/src/core.ts')){if(read('packages-user/client-modules/src/core.ts').indexOf('export const client')<0)bad.push('pre-state changed: client singleton gone')}else{bad.push('pre-state changed: core.ts missing')}if(bad.length>0){console.error('PRESTATE FAILED :: '+bad.join(' ; '));process.exit(1)}console.log('OK pre-execution state intact (audit doc absent; both packages present; legacy import + client singleton present)')"</automated>
<fails_when>non-zero exit, 或 stderr 含 "PRESTATE FAILED"(汇报基线不成立,或产出文档已存在 / 关键 legacy 锚点已漂移)</fails_when>
<human-check>用户在对话中明确回复「可以执行」四个字(人工核对回复原文;用户若指定非默认的范围 / 分类口径 / 产出路径 / B=0 呈现,须在汇报与后续任务中据其指定执行)</human-check>
</verify>
<acceptance_criteria>
- 用户回复中明确包含「可以执行」四个字
- 汇报内容涵盖:D-42 范围、D-43 三大类别(A/B/C)、legacy 分类口径 A-1..A-7、D-44 产出路径、D-45 只读保证、OI-1..OI-5、验证方式(静态断言,无全仓门禁)
- 汇报中已原样告知:**全程只读、不改任何 `.ts`/`.tsx`、不做任何改造、B 若为 0 会显式报告 0、锚点不得臆造**
- 汇报中已原样告知**关卡性质**(必须停下等待,不因触发方式或 `yolo` / `auto_advance` 自动放行)
</acceptance_criteria>
<done>用户明确回复「可以执行」;在此之前未执行任何任务、未修改任何文件、未派发任何执行子代理</done>
</task>
<task type="auto">
<name>Task 1(口径 + A + B):建立统计文档骨架与分类口径,撰写 A 节(残余 legacy 接口)与 B 节(`@deprecated`)</name>
<precondition>Task 0 已闭环:用户明确回复「可以执行」四个字(若用户就 OI-1..OI-5 另有指定,按指定执行)。</precondition>
<files>.planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md</files>
<read_first>
- .planning/phases/09-minimum-browser-runnable/09-CONTEXT.md(D-42 / D-43 / D-44 / D-45)
- packages-user/client-modules/src/action/hotkey.ts:1-6(`import { GameStorage } from '@motajs/legacy-system';`)
- packages-user/client-modules/src/fallback/audio.ts:1-11(`Patch, PatchClass` ← legacy-common;`mainSetting` ← legacy-ui;`client` 单例)
- packages-user/client-modules/src/fallback/ui.ts:1-11、fallback/weather.ts:1-9、fallback/index.ts:1-9(`Patch` / `PatchClass` 使用与回退层入口)
- packages-user/client-modules/src/ui/settings.tsx:11-18(`mainUi` / `getVitualKeyOnce` ← legacy-ui)
- packages-user/client-modules/src/ui/title.tsx:26-32(`mainSetting` / `triggerFullscreen` ← legacy-ui)
- packages-user/client-modules/src/ui/toolbar.tsx:12-21(`getVitualKeyOnce` ← legacy-ui;`generateBinary` ← legacy-common)
- packages-user/client-modules/src/core.ts:1-11(`export const client = new ClientCore(...)`)
- packages-user/client-base/src/elements/misc.ts:85-95,215-223、elements/cache.ts:487-495(`Mota.require('@user/data-base')`)
- src/types/declaration/core.d.ts(legacy 全局 `core` 声明处;只读参考)
- dev.md(Markdown 连字符命名;注释 / 命名规范)
</read_first>
<action>
(1) **创建文档骨架 `09-LEGACY-INTERFACES-AUDIT.md`**(仅此文件;**不修改任何源码**;OI-1 命名须已在 Task 0 获批)。
(2) **第 0 节 `## 0. 统计口径与范围`:** 写明——统计范围(恰好两个包、`.ts`/`.tsx`、排除 `node_modules`/`dist`);`legacy` **判定基准**;`A-1..A-7` **子类定义**;扫描方法论(用 node 递归遍历两包源码、按正则匹配、**排除注释与字符串**);**只读声明**(本文件为唯一产物之一,未改动任何源码);Markdown 使用 LF。
(3) **A 节 `## A. 残余的 legacy 接口`:** 按 A-1..A-7 分小节,逐条以表格登记 `file:line | 符号 | 来源包 / 子类 | 说明`。**必须逐条实测**(不得臆造)。已知起步锚点(执行日复核行号):A-1/A-4/A-5 见 `client-modules/src/action/hotkey.ts`、`fallback/{audio,ui,weather}.ts`、`ui/{settings,title,toolbar}.tsx`;A-3 见 `client-modules/src/core.ts` 与 `fallback/audio.ts:5,11`;A-6 见 `client-base/src/elements/{misc.ts:89,219,cache.ts:491}`;A-7 = `client-modules/src/fallback/**`(`index.ts` / `audio.ts` / `ui.ts` / `weather.ts` / `load.ts`)。A-2 只列 legacy 全局 `core` 本体并交叉引用 C 节。**给出 A 计数**并写入机器可读行 `A-COUNT: <n>`。
(4) **B 节 `## B. 标注 @deprecated 的接口`:** 在两包内扫描 `@deprecated` JSDoc 标注,逐条登记 `file:line | 符号 | 说明`。**规划日实测为 0 条**;执行日**复扫**并如实登记。**若为 0,显式报告「0 条」**并写明扫描范围(两包全部 `.ts`/`.tsx`,排除 `node_modules`/`dist`)与匹配方式(`@deprecated` 字面量),不省略该节(OI-4)。**给出 B 计数**并写入机器可读行 `B-COUNT: <n>`。
(5) **收口:** 不改任何源码;不改任何既有注释;文档仅含第 0 节 + A 节 + B 节(C 节与汇总由 Task 2 补齐);LF。
</action>
<reversibility rating="reversible">纯新增只读文档;删除 / `git revert` 可整体回退;未触及任何源码。</reversibility>
<verify>
<automated>node -e "const fs=require('fs');const p='.planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md';const bad=[];if(!fs.existsSync(p)){bad.push('doc missing')}else{const t=fs.readFileSync(p,'utf8').replace(/\r\n/g,'\n');for(const s of ['## 0.','## A. 残余的 legacy 接口','## B. 标注 @deprecated 的接口']){if(t.indexOf(s)<0)bad.push('missing heading: '+s)}if(!/A-COUNT:\s*\d+/.test(t))bad.push('missing A-COUNT');if(!/B-COUNT:\s*\d+/.test(t))bad.push('missing B-COUNT');if(t.indexOf('@motajs/legacy-')<0)bad.push('no legacy import grounded (A)');if(t.indexOf('@deprecated')<0)bad.push('no @deprecated mention (B)');if(t.indexOf('core')<0)bad.push('no core cross-reference (A-2)');const anchors=[...t.matchAll(/(packages-user\/[^\s`|)]+\.(?:ts|tsx)):(\d+)/g)];if(anchors.length<1)bad.push('no file:line anchors');for(const m of anchors){const f=m[1];const ln=parseInt(m[2],10);if(!fs.existsSync(f)){bad.push('anchor to missing file: '+f);continue}const lines=fs.readFileSync(f,'utf8').split(/\r?\n/);if(ln<1||ln>lines.length)bad.push('anchor line out of range: '+f+':'+ln)}}if(bad.length>0){console.error('AUDIT-AB GATE FAILED :: '+bad.join(' ; '));process.exit(1)}console.log('OK audit A+B authored (sections 0/A/B, counts, grounded anchors)')"</automated>
<fails_when>non-zero exit, 或 stderr 含 "AUDIT-AB GATE FAILED"(文档缺失 / 缺第 0 节或 A·B 节 / 缺 A·B 计数 / 无 legacy 或 @deprecated 依据 / 锚点指向不存在的文件或越界行号)</fails_when>
<automated>node -e "const {execSync}=require('child_process');const out=execSync('git status --porcelain',{encoding:'utf8'});const bad=out.split(/\r?\n/).filter(Boolean).filter(l=>/packages-user\/.*\.(ts|tsx)\s*$/.test(l));if(bad.length){console.error('READONLY FAILED :: source touched :: '+bad.join(' | '));process.exit(1)}console.log('OK read-only after Task 1: no .ts/.tsx touched')"</automated>
<fails_when>non-zero exit, 或 stderr 含 "READONLY FAILED"(出现任何 `.ts`/`.tsx` 改动,违反 D-45 只读)</fails_when>
</verify>
<acceptance_criteria>
- 文档 `09-LEGACY-INTERFACES-AUDIT.md` 存在,含 `## 0. 统计口径与范围`(含 legacy 判定基准 + A-1..A-7 + 方法论 + 只读声明)、`## A. 残余的 legacy 接口`、`## B. 标注 @deprecated 的接口`
- A 节按 A-1..A-7 分小节登记,逐条 `file:line` 锚点;已知跨包 legacy 依赖与单例 / `Mota` / 回退层均已进入台账
- B 节如实登记;若实测为 0,显式报告「0 条」并写明扫描范围与匹配方式
- 含机器可读 `A-COUNT:` 与 `B-COUNT:`;所有锚点文件存在且行号在范围内
- 未改动任何 `.ts`/`.tsx`;未改任何既有注释;未改 `files_modified` 外文件
</acceptance_criteria>
<done>第 0 节与 A、B 两节撰写完成,A/B 计数写入;静态门禁与只读守卫全绿</done>
</task>
<task type="auto">
<name>Task 2(C + 汇总 + 收口):撰写 C 节(所有经 `core.*` 调用的接口)与汇总表,补齐每类计数并跑最终静态门禁与只读守卫,写 SUMMARY</name>
<precondition>Task 1 已完成(文档第 0 节与 A、B 两节已就位,C 节与汇总待补)。</precondition>
<files>.planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md, .planning/phases/09-minimum-browser-runnable/09-11-SUMMARY.md</files>
<read_first>
- .planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md(本文件现状:第 0 节 + A + B,待补 C 与汇总)
- src/types/declaration/core.d.ts(legacy 全局 `core` 的成员类型来源;只读参考)
- packages-user/client-base/src/components/choices.tsx、floorSelect.tsx、misc.tsx、textboxTyper.ts、thumbnail.tsx、tip.tsx;elements/cache.ts、elements/misc.ts;shared.ts(`core.*` 调用点)
- packages-user/client-modules/src/action/hotkey.ts、action/move.ts、fallback/audio.ts、fallback/load.ts、render/utils/saves.ts、render/weather/presets/{cloud,fog,sun}.ts、client.ts、shared.ts(`core.*` 调用点)
- packages-user/client-modules/src/ui/{book,bookDetail,main,save,settings,shop,statistics,statusBar,title,toolbar,toolbox,viewmap}.tsx(`core.*` 调用点)
</read_first>
<action>
(1) **C 节 `## C. 所有经 core.* 调用的接口`:** 用 node 递归遍历两包内 `.ts`/`.tsx`(排除 `node_modules`/`dist`),按正则匹配 `\bcore\.([A-Za-z_][A-Za-z0-9_]*)`,**排除注释(`//` / `/* */`)与字符串字面量**(如注释里的 `core.js` 不计)。产出:
- **C-1 去重成员清单:** 汇总所有被访问的 `core.<member>`(如 `core.status` / `core.formatBigNumber` / `core.material` / `core.floors` / `core.saves` / `core.formatDate2` / `core.playSound` / `core.openBook` …;以执行日实测为准)。
- **C-2 按文件调用点:** 表 `file:line | core.<member> | 上下文`,逐条 `file:line`。
- **C-3 每文件计数:** 表 `file | 调用点计数`。
- **C 计数:** 写入机器可读行 `C-COUNT: <n>`(n = 去重后调用点总数),并注明覆盖成员数 M。
(2) **汇总节 `## 汇总`:** 汇总表 `| 类别 | 计数 | 覆盖文件数 | 说明 |`,至少三行 A / B / C;并在表下重申三行机器可读计数 `A-COUNT:` / `B-COUNT:` / `C-COUNT:`(与各节一致)。
(3) **收口与门禁:** 不改任何源码;不改任何既有注释;文档 LF。本任务 `<verify>` 运行最终静态门禁(含 C 节与汇总、锚点有效性、两包均被 C 覆盖)与只读守卫。
(4) **写 `09-11-SUMMARY.md`:** 记录统计范围、分类口径(A-1..A-7)、A/B/C 计数、产出文档路径、只读确认、OI-1..OI-5 的最终裁定。
</action>
<reversibility rating="reversible">纯新增只读文档(统计文档 + SUMMARY);删除 / `git revert` 可整体回退;未触及任何源码。</reversibility>
<verify>
<automated>node -e "const fs=require('fs');const p='.planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md';const bad=[];if(!fs.existsSync(p)){bad.push('doc missing')}else{const t=fs.readFileSync(p,'utf8').replace(/\r\n/g,'\n');for(const s of ['## C. 所有经 core.* 调用的接口','## 汇总']){if(t.indexOf(s)<0)bad.push('missing heading: '+s)}for(const k of ['A-COUNT:','B-COUNT:','C-COUNT:']){if(!new RegExp(k+'\\s*\\d+').test(t))bad.push('missing '+k)}for(const m of ['core.status','core.formatBigNumber','core.material','core.floors']){if(t.indexOf(m)<0)bad.push('missing member: '+m)}if(!/packages-user\/client-base\/src[^\s`|)]*\.(?:ts|tsx):\d+/.test(t))bad.push('no client-base core anchor');if(!/packages-user\/client-modules\/src[^\s`|)]*\.(?:ts|tsx):\d+/.test(t))bad.push('no client-modules core anchor');const anchors=[...t.matchAll(/(packages-user\/[^\s`|)]+\.(?:ts|tsx)):(\d+)/g)];if(anchors.length<5)bad.push('too few anchors');for(const m of anchors){const f=m[1];const ln=parseInt(m[2],10);if(!fs.existsSync(f)){bad.push('anchor to missing file: '+f);continue}const lines=fs.readFileSync(f,'utf8').split(/\r?\n/);if(ln<1||ln>lines.length)bad.push('anchor out of range: '+f+':'+ln)}}if(bad.length>0){console.error('AUDIT-C GATE FAILED :: '+bad.join(' ; '));process.exit(1)}console.log('OK audit C + summary authored (sections C/summary, A/B/C counts, both packages covered, anchors valid)')"</automated>
<fails_when>non-zero exit, 或 stderr 含 "AUDIT-C GATE FAILED"(文档缺失 / 缺 C 节或汇总 / 缺某类计数 / 缺核心成员或某包锚点 / 锚点指向不存在的文件或越界行号)</fails_when>
<automated>node -e "const {execSync}=require('child_process');const out=execSync('git status --porcelain',{encoding:'utf8'});const bad=out.split(/\r?\n/).filter(Boolean).filter(l=>/packages-user\/.*\.(ts|tsx)\s*$/.test(l));if(bad.length){console.error('READONLY FAILED :: source touched :: '+bad.join(' | '));process.exit(1)}console.log('OK read-only final: no .ts/.tsx touched')"</automated>
<fails_when>non-zero exit, 或 stderr 含 "READONLY FAILED"(出现任何 `.ts`/`.tsx` 改动,违反 D-45 只读)</fails_when>
<automated>git -C . status --porcelain</automated>
<fails_when>输出包含本计划 `files_modified`(`09-LEGACY-INTERFACES-AUDIT.md` + `09-11-SUMMARY.md`)之外的生产文件改动(如 `packages-user/**` 的 `.ts`/`.tsx`、`packages/**`、数据端、`package.json`)</fails_when>
</verify>
<acceptance_criteria>
- 文档含 `## C. 所有经 core.* 调用的接口`:去重成员清单 + 按文件 `file:line` 调用点 + 每文件计数;仅计代码、排除注释与字符串
- 文档 `client-base` 与 `client-modules` 两包**均有** `core.*` 锚点
- 文档含 `## 汇总` 表(A/B/C 三行)与三行机器可读计数 `A-COUNT:` / `B-COUNT:` / `C-COUNT:`(与各节一致)
- 全部 `file:line` 锚点指向真实存在且行号在范围内的行(无臆造)
- 未改动任何 `.ts`/`.tsx`;未改任何既有注释;范围守卫无越界改动;`09-11-SUMMARY.md` 已写
</acceptance_criteria>
<done>C 节与汇总表完成、三类计数齐备;最终静态门禁 + 锚点校验 + 只读守卫全绿;SUMMARY 落盘</done>
</task>
</tasks>
<threat_model>
## Trust Boundaries
| Boundary | Description |
|----------|-------------|
| 只读边界 | 统计过程只读取两包源码;**禁止任何源码写入**(D-45) |
| 范围边界 | 统计范围恰好 `client-base` + `client-modules`;不外扩到其它包 / `src` |
| 分类口径边界 | 「legacy」定义须文档内显式给出(A-1..A-7);不得臆造条目 |
| 产出边界 | 仅允许写 `09-LEGACY-INTERFACES-AUDIT.md` 与 `09-11-SUMMARY.md` |
| 提交边界 | 不得把用户并发改动(D-56)纳入暂存/提交 |
## STRIDE Threat Register
| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |
|-----------|----------|-----------|----------|-------------|-----------------|
| T-09-11-01 | Tampering | 借「统计」之机修改 / 新增生产源码(`.ts`/`.tsx`) | high | mitigate | `files_modified` 白名单 + prohibitions + Task 1/2 `READONLY` 门禁(`git status` 无 `.ts`/`.tsx` 改动) |
| T-09-11-02 | Elevation of Privilege | 未经批准即执行 / 使用未批准的产出文档命名 | high | mitigate | Task 0 `blocking-human`;OI-1 命名呈报;prohibitions 禁未获批命名 |
| T-09-11-03 | Tampering | 臆造条目(不存在的文件 / 越界行号 / 编造成员名) | high | mitigate | `<action>` 要求逐条实测;Task 1/2 门禁逐一校验「文件存在 + 行号在范围内」 |
| T-09-11-04 | Information Disclosure | 统计范围外泄到其它包 / `src` | medium | mitigate | `<action>` 明确扫描范围(两包、排除 `node_modules`/`dist`);`<verification>` 复述 |
| T-09-11-05 | Tampering | `core.*` 统计误计注释 / 字符串(如 `core.js`)或漏计 | medium | mitigate | `<action>` 明确排除注释与字符串字面量;C 节给出方法论 |
| T-09-11-06 | Repudiation | 未跑静态门禁即提交 | medium | mitigate | Task 1/2 各有自动化门禁 + SUMMARY;未通过不得提交 |
| T-09-11-07 | Tampering | B 类为 0 被静默省略 | low | mitigate | `<action>`/`acceptance` 明列「若为 0 须显式报告 0 并写明范围与匹配方式」(OI-4) |
| T-09-11-SC | Tampering | npm/pip/cargo installs | low | accept | 无第三方包安装、无依赖安装(纯只读统计,不改 `package.json`) |
</threat_model>
<verification>
- **Task 1**:`09-LEGACY-INTERFACES-AUDIT.md` 存在,含 `## 0.` / `## A. 残余的 legacy 接口` / `## B. 标注 @deprecated 的接口`;含 `A-COUNT:` / `B-COUNT:`;有 `@motajs/legacy-` 与 `@deprecated` 依据;A/B 锚点文件存在且行号在范围内;只读(无 `.ts`/`.tsx` 改动)。
- **Task 2**:含 `## C. 所有经 core.* 调用的接口` / `## 汇总`;含 `A-COUNT:` / `B-COUNT:` / `C-COUNT:`;含核心成员 `core.status` / `core.formatBigNumber` / `core.material` / `core.floors`;`client-base` 与 `client-modules` 两包均有 `core.*` 锚点;全部锚点有效;只读。
- **只读守卫**:全程 `git status` 无任何 `.ts`/`.tsx` 改动;`files_modified` 外无生产文件改动。
- **无全仓门禁**:全程不使用 `pnpm check:type` / `pnpm build` / 全仓 TS 诊断数。
- **人工复核**:结论写入 `09-11-SUMMARY.md`(含 A/B/C 计数与 OI-1..OI-5 的最终裁定)。
</verification>
<success_criteria>
- 统计范围恰好 `packages-user/client-base` 与 `packages-user/client-modules` 两包(排除 `node_modules`/`dist`)。
- 文档显式定义 `legacy` 分类口径(A-1..A-7),并逐条给出精确 `file:line` 锚点,无臆造。
- A(残余 legacy 接口)、B(`@deprecated`,若 0 显式报告 0)、C(`core.*` 调用点)三类均已枚举;含每类计数与汇总表。
- 全程只读:零 `.ts`/`.tsx` 改动;唯一写入为统计文档 + `09-11-SUMMARY.md`。
- 产出文档路径经 Task 0 批准;静态门禁(文档结构 / 锚点有效性 / 两包覆盖 / 只读)全绿。
</success_criteria>
## Artifacts this phase produces
| 符号 / 路径 | 类型 | 说明 |
|---|---|---|
| `.planning/phases/09-minimum-browser-runnable/09-LEGACY-INTERFACES-AUDIT.md`(新增) | 统计文档 | 第 0 节口径与范围 + A 残余 legacy 接口 + B `@deprecated` + C `core.*` 调用点 + 汇总表 + `A-COUNT:`/`B-COUNT:`/`C-COUNT:`(命名待批准,OI-1) |
| `.planning/phases/09-minimum-browser-runnable/09-11-SUMMARY.md`(新增) | 执行摘要 | 统计范围、分类口径、A/B/C 计数、产出路径、只读确认、OI-1..OI-5 裁定 |
**命名说明:** 本计划**新增的唯一命名**是产出文档文件名 `09-LEGACY-INTERFACES-AUDIT.md`(连字符命名法);**不引入任何源码命名**,**不改任何既有文件命名**。
## Source Coverage Audit
| 来源 | 项 | 处置 |
|------|----|------|
| GOAL | Phase 9(ROADMAP)「完成渲染端框架,产出可在浏览器运行并验证的最小版本」 | COVERED(增量·任务 5 只读统计子切片:为 legacy 改造提供台账) |
| REQ | Phase 9 ROADMAP「Requirements: TBD」,无需求 ID | N/A(`requirements: []` 如实标注) |
| RESEARCH | 无 RESEARCH.md(本阶段为增量派发,无独立研究产物) | N/A |
| CONTEXT | D-42(范围:恰好两个包) | COVERED(Task 1/2 扫描范围;只读守卫) |
| CONTEXT | D-43①(残余 legacy 接口) | COVERED(Task 1:A 节 A-1..A-7) |
| CONTEXT | D-43②(`@deprecated` 接口) | COVERED(Task 1:B 节;0 则显式报告 0) |
| CONTEXT | D-43③(所有经 `core.*` 调用的接口) | COVERED(Task 2:C 节) |
| CONTEXT | D-44(产出统计文档;路径待批准) | COVERED(Task 0 OI-1 + Task 1/2 产出 `09-LEGACY-INTERFACES-AUDIT.md`) |
| CONTEXT | D-45(只读,不改造) | COVERED(prohibitions + Task 1/2 只读门禁) |
| CONTEXT | D-03 / D-04 / D-06(执行前获批 / 命名获批 / 不扩范围) | COVERED(Task 0 + prohibitions + 范围门禁) |
| CONTEXT | Deferred Ideas | DEFERRED(未纳入任何任务) |
| 缺口 | `data-fallback` 无同名符号 | OPEN(OI-3:归 A-7,待用户确认所指) |
<output>
Create `.planning/phases/09-minimum-browser-runnable/09-11-SUMMARY.md` when done
</output>