From b577bb1ef7bfdd5881f046c1d80ecdec439a1af0 Mon Sep 17 00:00:00 2001
From: unanmed <1319491857@qq.com>
Date: Mon, 12 Oct 2026 18:29:19 +0800
Subject: [PATCH] docs(09): revise 09-14/09-15 per D-54 (defer
save-system-related entries)
---
.../09-minimum-browser-runnable/09-14-PLAN.md | 226 +++++++-----------
.../09-minimum-browser-runnable/09-15-PLAN.md | 211 ++++++----------
2 files changed, 166 insertions(+), 271 deletions(-)
diff --git a/.planning/phases/09-minimum-browser-runnable/09-14-PLAN.md b/.planning/phases/09-minimum-browser-runnable/09-14-PLAN.md
index 49d61f3..92d7427 100644
--- a/.planning/phases/09-minimum-browser-runnable/09-14-PLAN.md
+++ b/.planning/phases/09-minimum-browser-runnable/09-14-PLAN.md
@@ -5,31 +5,29 @@ type: execute
wave: 11
depends_on: [09-13]
files_modified:
- - packages-user/client-modules/src/action/hotkey.ts
- .planning/phases/09-minimum-browser-runnable/09-14-SUMMARY.md
autonomous: false
requirements: []
estimate:
- tokens: 20000
- raw_tokens: 22000
- tasks: 2
+ tokens: 6000
+ raw_tokens: 7000
+ tasks: 1
confidence: low
must_haves:
truths:
- - "**本计划的第一个 block 点是 Task 0 的 `blocking-human` 汇报关卡(AGENTS.md 硬要求,D-03)**:Task 0 必须先汇报「本计划 = 任务 7 · 第一批改造(ALT)· 4 个计划中的第 2 个 —— 裁剪后范围:跨包 legacy 依赖 `GameStorage` → `SaveSystem`(A-1-1)+ A-2-1 umbrella 记录;`Mota.require` / `loading`(A-6-1/2/3)按用户决定 **DEFERRED(用户自行处理)**」的要做什么 / 为什么 / 大致怎么做 / 影响范围,**必须列明:逐条 ALT 条目表(ID / 原接口成员 / 替代方案 / 涉及文件:行 / 编辑要点);逐文件影响表;执行日必须核实的风险点(R2:`GameStorage` → `SaveSystem` 的实例获取路径与语义差异);命名影响;开放项 OI-1 / OI-3 / OI-4;以及 A-6 DEFERRED(用户自行处理 `loading`)的范围裁剪说明**,然后必须**停下等待**用户明确回复「可以执行」四个字;未收到前不得执行本计划任何一步、不得派发执行子代理,且不因触发方式或 `mode: yolo` / `workflow.auto_advance` 自动放行。"
- - "**D-50 / D-52(范围 / 依据):** 实现本批 ALT 之**第 2 组剩余部分**(A-1-1 / A-2-1);`Mota.require('@user/data-base')` 三处(A-6-1 / A-6-2 / A-6-3)**按用户决定 DEFERRED,用户自行处理 `loading`**,本计划**不修改** `cache.ts` / `misc.ts`。替代严格依据 `09-LEGACY-REPLACEMENT-AUDIT.md` 的替代方案与 `file:line` 锚点,**不 invent**。"
- - "**D-53(其它分类不在本批):** 不触碰 `可直接替换` / `有替代但需适配` / `无替代` / `待定`;本组只改 ALT 条目。"
- - "**R2(替代可行性核实):** A-1-1 审计替代为 `SaveSystem`(`save/system.ts:41`);`GameStorage` 为 localStorage 键值存储、`SaveSystem` 为 Dexie 存档 / 全局存储(语义与实例获取路径不同)。执行日必须核实 `hotkey.ts` 取得 `SaveSystem` 实例的**合规路径**(D-11:不得引入 `client` 单例);若无法合规取得,**记录并 STOP 请示**。"
- - "**A-2-1(umbrella)部分收口:** 全局 `core`(`src/types/declaration/core.d.ts:1302`)的替代为 `CoreState`(`packages-user/data-state/src/core.ts:76`);本计划只收口本组 ALT 用法,**不删除 `core` 全局声明**;全量收口须待其余分类(ADAPT / NONE / TBD)完成后另行规划。**`09-14-SUMMARY.md` 必须逐条列明本计划 REPLACED(已收口)的对象与 DEFERRED(未收口 / 待其它批次)的对象**——含 `client-modules/src/core.ts:6` 的 `core` 单例定义如何处置(本计划未编辑该文件、未改其定义),以及 **A-6-1/2/3(`Mota.require` / `loading`)DEFERRED(用户自行处理)**——使 40 条 ALT 的整体覆盖可审计。"
- - "**范围零外溢 + 静态门禁:** 只改 `files_modified`(本计划仅 `action/hotkey.ts`);不改既有注释 / JSDoc;不用 `import type`;源码 CRLF;验证一律静态断言(legacy 用法消失 + 替代符号出现 + CRLF + 范围 / `git status` 守卫),**不使用** `pnpm check:type` / `pnpm build` / 全仓 TS 诊断数。"
+ - "**本计划为延后记录(DEFERRAL RECORD,D-54),无 active work task;第一个 block 点仍为 Task 0 的 `blocking-human` 汇报关卡(AGENTS.md 硬要求,D-03)**:Task 0 必须先汇报「本计划 = 任务 7 · 第一批改造(ALT)· 4 个计划中的第 2 个 —— 依 D-54,A-1-1(`GameStorage` → `SaveSystem`)已 DEFERRED(存档相关适配暂时忽略 / 延后);A-6(`Mota.require` / `loading`)按用户决定 DEFERRED(用户自行处理);A-2-1 仅作 umbrella 记录;本计划无源码改造」的要做什么 / 为什么 / 大致怎么做 / 影响范围,**必须列明:ALT 条目表(A-1-1 DEFERRED / A-2-1 记录 / A-6 用户自行处理);无逐文件改动(`files_modified` 仅本计划 SUMMARY);40 条 ALT 覆盖承接关系;开放项 OI-1 / OI-2 / OI-3 / OI-4**,然后必须**停下等待**用户明确回复「可以执行」四个字;未收到前不得执行本计划任何一步、不得派发执行子代理,且不因触发方式或 `mode: yolo` / `workflow.auto_advance` 自动放行。"
+ - "**D-54(存档相关适配延后):** 新存档系统与旧设计完全不同、适配难度大,故**存档相关** legacy 适配**暂时忽略 / 延后**(含 `GameStorage`、`SaveSystem`、`localForage`)。据此 **A-1-1(`GameStorage` → `SaveSystem`)标记为 DEFERRED(D-54)**;本计划**不修改** `packages-user/client-modules/src/action/hotkey.ts`,后续另行规划。"
+ - "**D-50 / D-52(范围 / 依据):** 第一批 = 40 条 ALT;替代严格依据 `09-LEGACY-REPLACEMENT-AUDIT.md` 的替代方案与 `file:line` 锚点,**不 invent**。"
+ - "**D-53(其它分类不在本批):** 不触碰 `可直接替换` / `有替代但需适配` / `无替代` / `待定`;本计划为延后记录,不改任何条目。"
+ - "**A-2-1(umbrella,仅记录):** 全局 `core`(`src/types/declaration/core.d.ts:1302`)的替代为 `CoreState`(`packages-user/data-state/src/core.ts:76`);本计划**仅记录**,**不删除 `core` 全局声明**、**不编辑** `client-modules/src/core.ts:6` 的 `core` 单例定义、不做源码改造。"
+ - "**A-6(用户自行处理):** `Mota.require('@user/data-base')` 三处(A-6-1 cache.ts:491 / A-6-2 misc.ts:89 / A-6-3 misc.ts:219)及其 `loading` 承载**按用户决定 DEFERRED,用户自行处理**;本计划**不修改** `cache.ts` / `misc.ts`。"
+ - "**范围零外溢 + 静态门禁:** 本计划**不修改任何源码**(`files_modified` 仅本计划 SUMMARY);不改既有注释 / JSDoc;不用 `import type`;验证一律静态断言(范围 / `git status` 守卫),**不使用** `pnpm check:type` / `pnpm build` / 全仓 TS 诊断数。"
artifacts:
- - path: packages-user/client-modules/src/action/hotkey.ts
- provides: "`GameStorage` 用法替换为 `SaveSystem` 全局存储(实例路径按执行日核实,R2)。"
- path: .planning/phases/09-minimum-browser-runnable/09-14-SUMMARY.md
- provides: "本计划执行摘要:本组 ALT 条目(A-1-1 / A-2-1)、逐文件改动、R2 核实结论、**A-2-1 收口覆盖(REPLACED vs DEFERRED 逐条,含 `core.ts:6` 单例定义处置与 A-6-1/2/3 DEFERRED 用户自行处理)**、命名影响、门禁结果。"
+ provides: "本计划延后记录:A-1-1 DEFERRED(D-54)、A-2-1 umbrella 记录、A-6 用户自行处理、40 条 ALT 整体覆盖的可审计承接关系。"
key_links:
- - "`packages-user/client-modules/src/action/hotkey.ts:3,518-522`(`GameStorage`)↔ `packages-user/client-base/src/save/system.ts:41`(`SaveSystem` 全局存储)—— A-1-1"
- - "`src/types/declaration/core.d.ts:1302`(全局 `core`)↔ `packages-user/data-state/src/core.ts:76`(`CoreState`)—— A-2-1"
+ - "`src/types/declaration/core.d.ts:1302`(全局 `core`)↔ `packages-user/data-state/src/core.ts:76`(`CoreState`)—— A-2-1(仅记录,不改源码)"
+ - "`packages-user/client-modules/src/action/hotkey.ts:3,518-522`(`GameStorage`)— **A-1-1 DEFERRED(D-54)**;参 `packages-user/client-base/src/save/system.ts:41`(`SaveSystem`,仅审计引用)。"
assumptions:
- "**执行日行号可能漂移**:引用行号为 2026-10-11 规划日实测;门禁以执行日实测为准。"
- "**A-6 已由用户决定 DEFERRED(用户自行处理 `loading`)**:本计划不修改 `cache.ts` / `misc.ts`,亦不核实 / 改写 `Mota.require('@user/data-base')`;`loading` 承载由用户自行处置。"
@@ -37,28 +35,30 @@ must_haves:
- "**Markdown 使用 LF,源码使用 CRLF**。"
prohibitions:
- "不得在用户明确回复「可以执行」四个字之前执行本计划任何一步、或派发任何执行子代理。"
- - "**不得触碰 A-6(DEFERRED)**:本计划**不得**修改 `packages-user/client-base/src/elements/cache.ts` / `misc.ts`,不得处理 `Mota.require('@user/data-base')` / `loading`(用户自行处理)。"
- - "**不得 invent 替代**:替代只取自审计;无等价替代时记录并 STOP,不得造出未存在的符号。"
- - "**不得引入 `client` 单例**;不得为取得实例而新增未批准命名(D-04)。"
+ - "**不得将 A-1-1 作为 active 任务执行**:A-1-1 已 DEFERRED(D-54);本计划**不得**修改 `packages-user/client-modules/src/action/hotkey.ts`,不得引入 `SaveSystem` 或 `client` 单例。"
+ - "**不得触碰 A-6(用户自行处理)**:本计划**不得**修改 `packages-user/client-base/src/elements/cache.ts` / `misc.ts`,不得处理 `Mota.require('@user/data-base')` / `loading`。"
+ - "**不得 invent 替代**;不得为取得实例而新增未批准命名(D-04);不得引入 `client` 单例(D-11)。"
- "不得触碰非 ALT 分类用法;不得改 09-01..09-13 任何文件;不得改既有注释 / JSDoc;不得用 `import type`;不得新增 `?.`(dev.md 允许场景除外)。"
- "不得把门禁建立在「全仓 TS 诊断数」「`pnpm check:type`」「`pnpm build`」之上;不得为「验证」改动源码。"
open_items:
- "**OI-1(批次拆分):** 本计划为任务 7 批次 4 计划中的第 2 个;**待用户确认**(可合并 / 重排)。"
- - "**OI-2(A-6 已 DEFERRED):** `Mota.require('@user/data-base')` / `loading`(A-6-1/2/3)**按用户决定 DEFERRED,用户自行处理**;本计划不核实、不改写、不记录锚点失效结论,仅在本计划范围 / 覆盖审计中标注为 DEFERRED。"
- - "**OI-3(A-1-1 实例路径,R2):** `hotkey.ts` 为模块级(非组件),取得 `SaveSystem` 实例的合规路径未定(D-11 禁 `client` 单例)。**待用户裁定接入口径**;若无法合规取得则本条目暂缓。"
- - "**OI-4(命名影响):** 预期不新增公共命名;若执行日不可避免需新增,须呈报批准。**待用户确认。**"
+ - "**OI-2(A-1-1 DEFERRED,D-54):** `GameStorage` → `SaveSystem` 属**存档相关适配**,已 **DEFERRED(D-54)**,后续另行规划;本计划不实施、不核实接入口径。"
+ - "**OI-3(A-6 用户自行处理):** `Mota.require('@user/data-base')` / `loading`(A-6-1/2/3)按用户决定 DEFERRED(用户自行处理);本计划不核实、不改写、不记录锚点失效结论。"
+ - "**OI-4(命名影响):** 本计划为延后记录,**不新增任何命名**。"
---
-Phase 9 · 任务 7 · 第一批改造(ALT 条目)· **第 2 组 / 共 4 组**(裁剪后范围)—— **跨包 legacy 依赖:`GameStorage` 收口 + 全局 `core` umbrella 部分收口**。
+Phase 9 · 任务 7 · 第一批改造(ALT 条目)· **第 2 组 / 共 4 组 —— 延后记录(DEFERRAL RECORD,D-54)**。
-**要解决的问题(D-50..D-53):** 本组处理 `client-modules` 中跨包 legacy 依赖:`@motajs/legacy-system` 的 `GameStorage`(`hotkey.ts` 热键配置持久化);以及全局 `core` 的 ALT 用法收口(umbrella)。**注:原第 2 组中的 `Mota.require('@user/data-base')` 三处(A-6-1/2/3)已由用户决定 DEFERRED(用户自行处理 `loading`),不在本计划范围。**
+**本计划性质:** 本计划**不进行源码改造、无 active work task**。原第 2 组的 `GameStorage` → `SaveSystem`(**A-1-1**)依 **D-54** 属**存档相关适配**,**已 DEFERRED(暂时忽略 / 延后)**;原第 2 组的 `Mota.require('@user/data-base')` / `loading`(**A-6-1/2/3**)按用户决定 **DEFERRED(用户自行处理)**;**A-2-1**(全局 `core` umbrella)**仅作记录**。本计划作为**延后记录**保留 40 条 ALT 的覆盖承接关系,便于后续审阅。
+
+**要解决的问题(D-50..D-54):** 如实登记第 2 组在 **D-54** 与用户决定下的**延后处置**,避免将已延后的 `GameStorage` → `SaveSystem`(A-1-1)改造成 active 任务,并保留 ALT 覆盖的可审计性。
**大致解决方案(本计划 = 09-14):**
-- **Task 0(`blocking-human`)= 预执行汇报关卡**:汇报本组裁剪后范围、逐条 ALT 表(A-1-1 / A-2-1)、逐文件影响表、**R2(`SaveSystem` 实例路径风险)**、命名影响、OI-1 / OI-3 / OI-4、A-6 DEFERRED 说明,等待「可以执行」。
-- **Task 1 = `GameStorage` → `SaveSystem`(A-1-1)+ A-2-1 umbrella 记录**:`hotkey.ts` 热键配置持久化改用新存档 / 全局存储;执行日核实实例路径(R2);无法合规取得则 STOP;A-2-1 作为 umbrella 在 SUMMARY 记录部分收口。
+- **Task 0(`blocking-human`)= 预执行汇报关卡**:汇报本计划为延后记录(A-1-1 DEFERRED per D-54;A-6 用户自行处理;A-2-1 仅记录;无源码改动),等待「可以执行」。
+- **本计划无 active work task**:A-1-1 **不在本计划实施**;**无任何源码文件改动**。
-**API coverage:** `detected:false`。**`No external API integration: 本计划仅为源码改造,不涉及任何外部 API。`**
+**API coverage:** `detected:false`。**`No external API integration: 本计划仅为延后记录,不涉及任何外部 API。`**
@C:/Users/13194/.config/opencode/gsd-core/workflows/execute-plan.md
@@ -76,133 +76,88 @@ Phase 9 · 任务 7 · 第一批改造(ALT 条目)· **第 2 组 / 共 4 组
@dev.md
-## ALT 条目清单与影响表(本组裁剪后 2 条;原第 2 组 5 条,A-6-1/2/3 已 DEFERRED)
+## ALT 条目清单与影响表(本组裁剪后;A-1-1 DEFERRED(D-54),无 active 改造)
-| ID | 原接口/成员(锚点) | 替代方案(锚点) | 涉及文件:行 | 编辑要点 |
+| ID | 原接口/成员(锚点) | 替代方案(锚点) | 涉及文件:行 | 状态 / 编辑要点 |
| --- | --- | --- | --- | --- |
-| A-1-1 | `GameStorage`(hotkey.ts:3) | `SaveSystem`(save/system.ts:41) | client-modules/src/action/hotkey.ts:3,518-522 | 热键配置持久化改新存档 / 全局存储;核实实例路径(R2) |
-| A-2-1 | 全局 `core`(core.d.ts:1302) | `CoreState`(data-state/core.ts:76) | client-modules/src/core.ts:6(umbrella) | 只收口本组 ALT 用法;不删 `core` 全局声明 |
+| A-1-1 | `GameStorage`(hotkey.ts:3) | `SaveSystem`(save/system.ts:41) | (无;不改 `hotkey.ts`) | **DEFERRED(D-54)** —— 存档相关适配暂时忽略 / 延后,后续另行规划;本计划不实施 |
+| A-2-1 | 全局 `core`(core.d.ts:1302) | `CoreState`(data-state/core.ts:76) | (无;仅记录) | **记录(umbrella)** —— 不删 `core` 全局声明、不改 `core.ts:6` 单例定义;不做源码改造 |
+| A-6-1/2/3 | `Mota.require('@user/data-base')`(cache.ts:491 / misc.ts:89 / misc.ts:219) | 直接 ESM 导入 `@user/data-base` | (无;不改 `cache.ts` / `misc.ts`) | **DEFERRED(用户自行处理 `loading`)** |
-> **DEFERRED(用户自行处理):** A-6-1(cache.ts:491)/ A-6-2(misc.ts:89)/ A-6-3(misc.ts:219)—— `Mota.require('@user/data-base')` → 静态导入(`loading` 承载)。**用户决定本计划不改**,由用户自行处理;本计划不修改 `cache.ts` / `misc.ts`。
+> **本计划无 active work task:** A-1-1(D-54)与 A-6(用户自行处理)均已 DEFERRED;A-2-1 仅作记录。本计划**不修改任何源码文件**。
## 逐文件影响表(本组裁剪后)
| 文件 | 动作 | 改动内容 | 关联 ALT |
| --- | --- | --- | --- |
-| `packages-user/client-modules/src/action/hotkey.ts` | 修改 | `GameStorage` → 新存档 / 全局存储(`SaveSystem`) | A-1-1 |
+| (无) | 不修改 | 本计划为延后记录,**无源码文件改动** | — |
- Task 0: 预执行汇报关卡 —— 汇报「任务 7 · 第一批改造(ALT)· 第 2 组(裁剪后):跨包 legacy 依赖 `GameStorage` → `SaveSystem` + A-2-1 umbrella」的范围、逐条 ALT 表、逐文件影响表、R2 风险、A-6 DEFERRED 说明与 OI,等待用户回复「可以执行」
- `packages-user/client-modules/src/action/hotkey.ts` 存在;`packages-user/client-base/src/save/system.ts` 存在;审计文档 `09-LEGACY-REPLACEMENT-AUDIT.md` 已存在。
+ Task 0: 预执行汇报关卡 —— 汇报「任务 7 · 第一批改造(ALT)· 第 2 组:延后记录(D-54)」:A-1-1 DEFERRED、A-6 用户自行处理、A-2-1 仅记录、本计划无 active work task,等待用户回复「可以执行」
+ 审计文档 `.planning/phases/09-minimum-browser-runnable/09-LEGACY-REPLACEMENT-AUDIT.md` 存在;`.planning/phases/09-minimum-browser-runnable/09-CONTEXT.md` 含 D-54。
(只读汇报,不修改任何文件)
- - .planning/phases/09-minimum-browser-runnable/09-CONTEXT.md(D-03 / D-04 / **D-50 / D-52 / D-53**)
+ - .planning/phases/09-minimum-browser-runnable/09-CONTEXT.md(D-03 / D-04 / **D-50 / D-52 / D-53 / D-54**)
- .planning/phases/09-minimum-browser-runnable/09-LEGACY-REPLACEMENT-AUDIT.md(A-1-1 / A-2-1;A-6-* 仅作 DEFERRED 标注)
- - .planning/phases/09-minimum-browser-runnable/09-14-PLAN.md(本计划全文,含「ALT 条目清单与影响表」「逐文件影响表」与 R2)
- - packages-user/client-base/src/save/system.ts(`SaveSystem` 全局存储 `getGlobal` / `setGlobal`,R2)
+ - .planning/phases/09-minimum-browser-runnable/09-14-PLAN.md(本计划全文,含「ALT 条目清单与影响表」「逐文件影响表」)
- AGENTS.md(执行前须获批、命名须先反馈、问题须先确认);dev.md(命名、注释、依赖单向、CRLF)
- **停下并向用户汇报,等待明确回复「可以执行」后才继续;汇报本身只读。**
+ **停下并向用户汇报,等待明确回复「可以执行」后才继续;汇报本身只读;本计划不修改任何源码。**
- ① **要解决的问题:** 任务 7 · 第一批改造(ALT)第 2 组(裁剪后):`client-modules` 中跨包 legacy 依赖 `GameStorage`(`hotkey.ts` 热键配置持久化),以及全局 `core` 的 ALT 用法 umbrella 部分收口,共 2 条。**原第 2 组的 A-6(`Mota.require('@user/data-base')` / `loading`,三处)已按用户决定 DEFERRED(用户自行处理),不在本计划范围。**
+ ① **本计划性质(须用户知悉):** 本计划为**延后记录(deferral record)**,**无 active work task**、**不修改任何源码文件**。原第 2 组已按 **D-54** 及用户决定裁剪,记于下。
- ② **逐条 ALT 条目表:** 原样呈现本计划「ALT 条目清单与影响表」的 2 行(A-1-1 / A-2-1),并说明 A-6-1/2/3 的 DEFERRED 处置。
+ ② **A-1-1 DEFERRED(D-54):** `GameStorage`(`@motajs/legacy-system`,hotkey.ts:3)→ `SaveSystem`(`save/system.ts:41`)属**存档相关适配**,依 **D-54 暂时忽略 / 延后**,后续另行规划;本计划**不修改** `packages-user/client-modules/src/action/hotkey.ts`。
- ③ **逐文件影响表:** 原样呈现本计划「逐文件影响表」的 1 行,并说明 `files_modified` 精确为 1 个源文件(`client-modules/src/action/hotkey.ts`)。
+ ③ **A-2-1(umbrella,仅记录):** 全局 `core`(core.d.ts:1302)→ `CoreState`(data-state/core.ts:76);本计划**仅记录**(不删 `core` 全局声明、不改 `core.ts:6` 单例定义、不做源码改造)。
- ④ **A-6 DEFERRED(范围裁剪,须用户知悉):** `Mota.require('@user/data-base')` 三处(A-6-1 cache.ts:491 / A-6-2 misc.ts:89 / A-6-3 misc.ts:219)及其 `loading` 承载**按用户决定 DEFERRED,用户自行处理**;本计划**不修改** `cache.ts` / `misc.ts`,不核实 / 不改写 `loading`。
+ ④ **A-6(用户自行处理):** `Mota.require('@user/data-base')` 三处(A-6-1 cache.ts:491 / A-6-2 misc.ts:89 / A-6-3 misc.ts:219)及 `loading` 承载**按用户决定 DEFERRED,用户自行处理**;本计划**不修改** `cache.ts` / `misc.ts`。
- ⑤ **R2(A-1-1 实例路径,须用户知悉):** `hotkey.ts` 为模块级,替代 `SaveSystem` 需要实例;`GameStorage`(localStorage 键值)与 `SaveSystem`(Dexie 存档 / 全局存储)语义不同。执行日核实合规取得路径(D-11 禁 `client` 单例);无法合规取得则记录并 STOP。**OI-3。**
+ ⑤ **逐条 ALT 条目表:** 原样呈现本计划「ALT 条目清单与影响表」的 3 行(A-1-1 DEFERRED / A-2-1 记录 / A-6 DEFERRED)。
- ⑥ **A-2-1(umbrella):** 全局 `core` → `CoreState`;本计划只收口本组 ALT 用法,**不删 `core` 全局声明**;全量收口待其它分类批次。
+ ⑥ **逐文件影响表:** 本计划**无源码文件改动**——`files_modified` 仅本计划 SUMMARY。
- ⑦ **编辑策略:** 本计划只有 Task 1——改 `hotkey.ts` 的 `GameStorage`(A-1-1)+ 记录 A-2-1 umbrella。**本计划无 A-6 编辑任务。**
+ ⑦ **40 条 ALT 覆盖承接(可审计):** 12(09-13 回退层组)+ **A-1-1 及 7 条存档簇(DEFERRED per D-54)** + 7(09-15 UI 打开 / 控制)+ 9(09-16 输入 / 绘制 / 素材 / 杂项)+ A-2-1(本记录)+ A-6×3(用户自行处理)= **40**。
- ⑧ **范围与禁止:** 只改 ALT 条目相关用法;不触碰其它分类;不改 09-01..09-13;不改既有注释;不用 `import type`;不引入 `client` 单例;源码 CRLF;**不触碰 A-6(`cache.ts` / `misc.ts`)**。
+ ⑧ **范围与禁止:** 不触碰非 ALT 分类;不改 09-01..09-13;不改既有注释;不用 `import type`;不引入 `client` 单例;**不修改任何源码**。
- ⑨ **验证方式:** 静态断言——`hotkey.ts` 无 `GameStorage` / `@motajs/legacy-system` 且出现替代符号;CRLF;范围 / `git status` 守卫。**不设全仓类型 / 构建门禁。** 若 R2 触发 STOP,则相应条目标记为「待裁定」,门禁对未改文件不作强制。
+ ⑨ **验证方式:** 静态断言——范围 / `git status` 守卫(确认无源码改动)。**不设全仓类型 / 构建门禁。**
- ⑩ **开放项:** OI-1(批次拆分)、OI-2(A-6 DEFERRED,用户自行处理)、OI-3(A-1-1 实例路径 / R2)、OI-4(命名影响)。**无论触发方式或 `mode: yolo` / `workflow.auto_advance`,执行者 / 子代理必须停下等待用户明确回复「可以执行」四个字**;回复其它内容视为未通过。
+ ⑩ **开放项:** OI-1(批次拆分)、OI-2(A-1-1 DEFERRED per D-54)、OI-3(A-6 用户自行处理)、OI-4(命名——本计划不新增)。**无论触发方式或 `mode: yolo` / `workflow.auto_advance`,执行者 / 子代理必须停下等待用户明确回复「可以执行」四个字**;回复其它内容视为未通过。
- 是否按本计划(09-14,裁剪后范围)执行任务 7 · 第一批改造 · 第 2 组:跨包 legacy 依赖替换(`GameStorage` → `SaveSystem`、A-2-1 部分收口),并在 R2 无法满足时按 STOP 处置;A-6(`Mota.require` / `loading`)保持 DEFERRED(用户自行处理)
+ 是否确认本计划(09-14)为**延后记录**:A-1-1(`GameStorage` → `SaveSystem`)依 D-54 DEFERRED、A-6(`Mota.require` / `loading`)用户自行处理、A-2-1 仅记录,本计划**无源码改造、无 active work task**
- AGENTS.md / D-03 / D-04 要求执行前与命名先获批;`.planning/config.json` 为 `mode: yolo`,故本关卡显式 `blocking-human` 且 `autonomous: false`。本次核心 = 裁剪后 ALT 范围确认(A-1-1 / A-2-1;A-6 DEFERRED)+ R2(A-1-1 实例路径)+ 命名影响确认。行号为规划日实测,以执行日为准。
+ AGENTS.md / D-03 / D-04 要求执行前与命名先获批;`.planning/config.json` 为 `mode: yolo`,故本关卡显式 `blocking-human` 且 `autonomous: false`。本次核心 = 确认**延后记录性质**(A-1-1 DEFERRED per D-54;A-6 用户自行处理;A-2-1 仅记录)。行号为规划日实测,以执行日为准。
-
- 回复「可以执行」四个字(如需指定 R2 的处置或调整 OI,请在回复中指明)
+ 回复「可以执行」四个字(如需调整 OI 或承接关系,请在回复中指明)
- node -e "const fs=require('fs');const bad=[];for(const p of ['packages-user/client-modules/src/action/hotkey.ts','packages-user/client-base/src/save/system.ts']){if(!fs.existsSync(p))bad.push('missing: '+p)}const audit='.planning/phases/09-minimum-browser-runnable/09-LEGACY-REPLACEMENT-AUDIT.md';if(!fs.existsSync(audit))bad.push('missing audit');if(bad.length){console.error('PRESTATE FAILED :: '+bad.join(' ; '));process.exit(1)}console.log('OK prestate intact (hotkey.ts + save/system.ts + audit)')"
- non-zero exit, 或 stderr 含 "PRESTATE FAILED"(输入文件或审计文档缺失)
- 用户在对话中明确回复「可以执行」四个字(人工核对回复原文;用户若指定 R2 的处置,须在汇报与后续任务中据其指定执行)
+ node -e "const fs=require('fs');const bad=[];const audit='.planning/phases/09-minimum-browser-runnable/09-LEGACY-REPLACEMENT-AUDIT.md';const ctx='.planning/phases/09-minimum-browser-runnable/09-CONTEXT.md';if(!fs.existsSync(audit))bad.push('missing audit');if(!fs.existsSync(ctx))bad.push('missing context');if(bad.length){console.error('PRESTATE FAILED :: '+bad.join(' ; '));process.exit(1)}console.log('OK prestate intact (audit + context present)')"
+ non-zero exit, 或 stderr 含 "PRESTATE FAILED"(审计文档或 CONTEXT 缺失)
+ 用户在对话中明确回复「可以执行」四个字(人工核对回复原文)
- 用户回复中明确包含「可以执行」四个字
- - 汇报内容涵盖:D-50 / D-52 / D-53、本组裁剪后 2 条 ALT 条目表(A-1-1 / A-2-1)、逐文件影响表、R2(A-1-1 实例路径)、A-6-1/2/3 DEFERRED(用户自行处理)、编辑策略、命名影响、OI-1 / OI-2 / OI-3 / OI-4
- - 汇报中已原样告知:不触碰 A-6(`cache.ts` / `misc.ts`)、不 invent 替代、不引入 `client` 单例、只改 ALT、CRLF 与范围零外溢
+ - 汇报内容涵盖:本计划为延后记录(D-54)、A-1-1 DEFERRED、A-6 用户自行处理、A-2-1 仅记录、无源码改动、40 条 ALT 覆盖承接关系、OI-1 / OI-2 / OI-3 / OI-4
+ - 汇报中已原样告知:不触碰 A-6(`cache.ts` / `misc.ts`)、不改 `hotkey.ts`、不 invent 替代、不引入 `client` 单例、不修改任何源码
- 汇报中已原样告知**关卡性质**(必须停下等待,不因触发方式或 `yolo` / `auto_advance` 自动放行)
用户明确回复「可以执行」;在此之前未执行任何任务、未修改任何文件、未派发任何执行子代理
-
- Task 1: 替换 `GameStorage` 为 `SaveSystem` 全局存储(A-1-1)并记录 A-2-1 umbrella(部分收口)
- Task 0 已闭环:用户明确回复「可以执行」四个字(若用户就 R2 / OI 另有指定,按指定执行)。
- packages-user/client-modules/src/action/hotkey.ts
-
- - packages-user/client-modules/src/action/hotkey.ts:1-6,510-526(`GameStorage` 导入与热键配置持久化)
- - packages-user/client-base/src/save/system.ts:28-45,197-222(`SaveSystem` / `GlobalTransaction` / `getGlobal` / `setGlobal`)
- - .planning/phases/09-minimum-browser-runnable/09-CONTEXT.md(D-11 主对象经 props 获取、禁 `client` 单例)
- - .planning/phases/09-minimum-browser-runnable/09-LEGACY-REPLACEMENT-AUDIT.md(A-1-1 / A-2-1)
-
-
- (1) **核实实例路径(先于编辑,R2):** `hotkey.ts` 为模块级(非组件)。确认取得 `SaveSystem`(或等价的全局存储)实例的**合规路径**:不得引入 `client` 单例;若只能经未批准的机制取得,则本条目**记录并 STOP 请示**(OI-3)。
- - 若存在合规路径:将热键配置持久化从 `GameStorage`(`keyStorage.data` / `read()` / `setValue()` / `toJSON()`)改为经 `SaveSystem` 的全局存储(`getGlobal` / `setGlobal` 或审计等价方案),保持「读入 → 反序列化到 `gameKey` → 变更时写回」的行为等价。
- - 若无法合规取得:**记录 R2 阻断 + STOP**,不得引入 `client` 单例,也不得保留 `GameStorage` 视作完成。
-
- (2) **A-2-1(umbrella,部分收口):** 不删 `src/types/declaration/core.d.ts` 的全局 `core` 声明,也不改 `client-modules/src/core.ts` 的单例定义(其属 ADAPT 分类 / 其它批次)。在 `09-14-SUMMARY.md` 记录 A-2-1 的**部分收口**状态(本组 ALT 用法已改;全量收口待其余分类批次),并**逐条列明 REPLACED(已收口)与 DEFERRED(未收口 / 待其它批次)的对象**:至少含 `GameStorage`(已 REPLACED,`hotkey.ts`),以及 DEFERRED 的 A-6-1/2/3(`Mota.require('@user/data-base')` / `loading`,**用户自行处理**)、`client-modules/src/core.ts:6` 单例定义 / 全局 `core` 声明与其它分类(ADAPT / NONE / TBD)成员,使 40 条 ALT 的整体覆盖可审计。
-
- (3) **不 invent / 不越界:** 只改 `hotkey.ts` 中与 A-1-1 相关的用法;`hotkey.ts` 内 `core.*` 其它用法(`core.status` / `core.isMoving` / `core.isReplaying` / `core.doSL` / `core.turnHero` / `core.getNextItem` / `core.confirmRestart` / `core.actions` / `core.openBook` 等)属其它分类或其它组,**本任务不改**(`core.debug` 属 09-16)。**不得触碰 A-6(`cache.ts` / `misc.ts`)。**
-
- (4) **命名 / 行尾 / 注释:** 预期不新增命名;如必须新增须呈报批准(D-04)。保持 CRLF;不改既有注释 / JSDoc;不使用 `import type`;不新增 `?.`(dev.md 允许场景除外)。
-
- 单文件替换;`git revert` 可回退。
-
- node -e "const fs=require('fs');const bad=[];const p='packages-user/client-modules/src/action/hotkey.ts';const t=fs.readFileSync(p,'utf8').split(/\r?\n/).filter(l=>!/^\s*(\/\/|\*|\/\*)/.test(l)).join('\n');if(/GameStorage/.test(t))bad.push('hotkey.ts still uses GameStorage');if(!/\bSaveSystem\b/.test(t))bad.push('hotkey.ts: no SaveSystem replacement (expected audit symbol)');if(/\bfrom '@motajs\/legacy-system'/.test(t))bad.push('hotkey.ts still imports @motajs/legacy-system');if(bad.length){console.error('GAMESTORAGE GATE FAILED :: '+bad.join(' ; '));process.exit(1)}console.log('OK GameStorage replaced (or recorded STOP) in hotkey.ts')"
- non-zero exit, 或 stderr 含 "GAMESTORAGE GATE FAILED"(仍用 `GameStorage`、无替代符号,或仍导入 `@motajs/legacy-system`)
- node -e "const fs=require('fs');const b=fs.readFileSync('packages-user/client-modules/src/action/hotkey.ts','utf8');const bad=[];if(b.indexOf('\r\n')<0)bad.push('not CRLF');if(/\bimport\s+type\b/.test(b))bad.push('import type');if(bad.length){console.error('CRLF/IMPORT FAILED :: '+bad.join(' ; '));process.exit(1)}console.log('OK hotkey.ts CRLF and no import type')"
- non-zero exit, 或 stderr 含 "CRLF/IMPORT FAILED"(非 CRLF 或出现 `import type`)
- git status --porcelain
- 输出包含本计划 `files_modified` 之外、且非用户既有并发改动(`packages-user/data-state/**`)的生产文件改动
-
-
- - `hotkey.ts` 已去除 `GameStorage`(及 `@motajs/legacy-system` 导入)并改用合规的 `SaveSystem` / 全局存储;或记录 R2 阻断并 STOP
- - 未引入 `client` 单例;未新增未批准命名;未触碰其它分类用法
- - **未触碰 A-6**:`packages-user/client-base/src/elements/cache.ts` / `misc.ts` 未被本计划修改
- - A-2-1 部分收口状态已写入 SUMMARY(不删 `core` 全局声明),且 SUMMARY **逐条列明 REPLACED vs DEFERRED 对象**(含 `client-modules/src/core.ts:6` 单例定义未编辑/未改的处置、A-6-1/2/3 DEFERRED 用户自行处理),使 40 条 ALT 覆盖可审计
- - 被改文件 CRLF、无 `import type`;未改 `files_modified` 外文件(用户并发改动除外)
-
- `GameStorage` 替换到位(或记录阻断 STOP);A-2-1 部分收口记录完成(含 A-6 DEFERRED 标注);门禁全绿
-
-
@@ -210,65 +165,64 @@ Phase 9 · 任务 7 · 第一批改造(ALT 条目)· **第 2 组 / 共 4 组
| Boundary | Description |
|----------|-------------|
-| 范围边界 | 只改 ALT 条目相关用法;不触碰 DIRECT / ADAPT / NONE / TBD(D-53) |
+| 范围边界 | 本计划只记录、不改源码;不触碰 DIRECT / ADAPT / NONE / TBD(D-53) |
+| 存档边界 | **A-1-1 已 DEFERRED(D-54):不得修改 `hotkey.ts`、不得引入 `SaveSystem` 或 `client` 单例** |
| A-6 边界 | **不触碰 A-6(`Mota.require` / `loading`):用户自行处理,本计划禁改 `cache.ts` / `misc.ts`** |
-| 替代依据边界 | 替代方案只取自审计;锚点失效时记录并 STOP,**不猜**(D-52 / R2) |
-| 单例边界 | 不得引入 `client` 单例取得实例(D-11 / R2) |
-| 命名边界 | 未经批准不得新增命名(D-04) |
-| 文件 / 提交边界 | 仅改 `files_modified`;不把用户并发改动(`data-state/**`)纳入提交 |
+| 命名边界 | 本计划为延后记录,未经批准不得新增命名(D-04) |
+| 文件 / 提交边界 | 本计划无源码改动;不把用户并发改动(`data-state/**`)纳入提交 |
## STRIDE Threat Register
| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |
|-----------|----------|-----------|----------|-------------|-----------------|
-| T-09-14-01 | Tampering | 越界改动 A-6(`cache.ts` / `misc.ts` / `Mota.require` / `loading`) | high | mitigate | prohibitions 禁改 A-6;`files_modified` 不含这两文件;`git status` 守卫 |
-| T-09-14-02 | Elevation of Privilege | 为取得实例而引入 `client` 单例 / 使用未批准命名 | high | mitigate | R2 前置核实;prohibitions;D-04 / D-11 |
-| T-09-14-03 | Tampering | 越界改动非 ALT 用法(`core.status` 等) | high | mitigate | 范围门禁 + `` 明列不改项 + `git status` 守卫 |
-| T-09-14-04 | Repudiation | 保留 `GameStorage` 却视作完成 | medium | mitigate | GAMESTORAGE 门禁强制 legacy 用法消失(本计划不再设 MOTA-REQUIRE 门禁,A-6 已 DEFERRED) |
-| T-09-14-05 | Information Disclosure | 把用户并发改动(`data-state/**`)误纳入提交 | medium | mitigate | `git status` 守卫豁免既有并发改动 |
-| T-09-14-06 | Repudiation | 未跑静态门禁即提交 | medium | mitigate | Task 1 有自动化门禁 + SUMMARY |
+| T-09-14-01 | Tampering | 将已 DEFERRED 的 A-1-1 当作 active 任务执行(改 `hotkey.ts`) | high | mitigate | prohibitions 明列「不得将 A-1-1 作为 active 任务」;`files_modified` 不含 `hotkey.ts`;`git status` 守卫 |
+| T-09-14-02 | Tampering | 越界改动 A-6(`cache.ts` / `misc.ts` / `Mota.require` / `loading`) | high | mitigate | prohibitions 禁改 A-6;`files_modified` 不含这两文件;`git status` 守卫 |
+| T-09-14-03 | Elevation of Privilege | 为接入而引入 `client` 单例 / 使用未批准命名 | medium | mitigate | prohibitions;D-04 / D-11 |
+| T-09-14-04 | Information Disclosure | 把用户并发改动(`data-state/**`)误纳入提交 | medium | mitigate | `git status` 守卫豁免既有并发改动 |
+| T-09-14-05 | Repudiation | 把未落地的 A-1-1 记作 REPLACED | medium | mitigate | SUMMARY 逐条列明 DEFERRED;本计划无源码改动如实记录 |
| T-09-14-SC | Tampering | npm/pip/cargo installs | low | accept | 无第三方包安装 |
-- **Task 1**:`hotkey.ts` 无 `GameStorage` / `@motajs/legacy-system`,有 `SaveSystem`;A-2-1 部分收口记录(含 REPLACED vs DEFERRED 逐条、`core.ts:6` 单例定义处置、A-6-1/2/3 DEFERRED 用户自行处理);CRLF / import type 检查;范围门禁。
-- **A-6(DEFERRED)**:`cache.ts` / `misc.ts` **不在本计划范围**,不修改、不核实、不改写 `loading`。
-- **R2 触发时**:记录阻断并 STOP,相应条目标记「待裁定」。
+- **本计划无源码改动**:`git status --porcelain` 仅含本计划 SUMMARY(若有)与用户既有并发改动(`packages-user/data-state/**`)。
+- **A-1-1(DEFERRED,D-54)**:`hotkey.ts` **不在本计划范围**,不修改、不核实接入口径。
+- **A-6(DEFERRED,用户自行处理)**:`cache.ts` / `misc.ts` **不在本计划范围**,不修改、不核实、不改写 `loading`。
- **无全仓门禁**:不使用 `pnpm check:type` / `pnpm build` / 全仓 TS 诊断数。
-- **人工复核**:结论写入 `09-14-SUMMARY.md`。
+- **人工复核**:延后记录写入 `09-14-SUMMARY.md`。
-- 本组裁剪后 2 条 ALT:A-1-1(`GameStorage` → `SaveSystem`)按审计落地;A-2-1 umbrella 部分收口并记录(SUMMARY 含 REPLACED vs DEFERRED 逐条,覆盖可审计)。
-- A-6-1/2/3(`Mota.require` / `loading`)保持 **DEFERRED(用户自行处理)**,本计划未触碰 `cache.ts` / `misc.ts`。
-- R2 若成立,**如实记录并 STOP**,不猜测、不保留 `GameStorage` 冒充完成。
-- 零越界:不触碰其它分类、不触碰 A-6、不引入 `client` 单例、不新增未批准命名。
-- 静态门禁(GAMESTORAGE / CRLF / 范围)全绿(或按 STOP 分支记录)。
+- 本计划如实作为**延后记录**:A-1-1(`GameStorage` → `SaveSystem`)标 **DEFERRED(D-54)**;A-6-1/2/3 标 **DEFERRED(用户自行处理)**;A-2-1 仅记录。
+- 本计划**未修改任何源码文件**(尤其 `hotkey.ts` / `cache.ts` / `misc.ts`)。
+- 40 条 ALT 覆盖承接关系记录在案,可审计。
+- 零越界:不触碰其它分类、不引入 `client` 单例、不新增命名。
## Artifacts this phase produces
| 符号 / 路径 | 类型 | 说明 |
|---|---|---|
-| `packages-user/client-modules/src/action/hotkey.ts`(修改) | 源码 | `GameStorage` → `SaveSystem` 全局存储 |
-| `.planning/phases/09-minimum-browser-runnable/09-14-SUMMARY.md`(新增) | 执行摘要 | 本组 ALT(A-1-1 / A-2-1)、逐文件改动、R2 结论、**A-2-1 REPLACED vs DEFERRED 逐条(含 A-6 DEFERRED 用户自行处理)**、命名影响、门禁结果 |
+| `.planning/phases/09-minimum-browser-runnable/09-14-SUMMARY.md` | 延后记录 | A-1-1 DEFERRED(D-54)、A-2-1 umbrella 记录、A-6 用户自行处理、40 条 ALT 覆盖承接表 |
-**命名说明:** 预期**不新增源码命名**;如需新增须先获用户批准。
+**命名说明:** 本计划为延后记录,**不新增任何源码命名**。
## Source Coverage Audit
| 来源 | 项 | 处置 |
|------|----|------|
-| GOAL | Phase 9(ROADMAP) | COVERED(去 legacy 跨包依赖子切片) |
+| GOAL | Phase 9(ROADMAP) | COVERED(记录去 legacy 跨包依赖子切片的延后承接) |
| REQ | 「Requirements: TBD」 | N/A(`requirements: []`) |
| RESEARCH | 无 RESEARCH.md | N/A |
-| CONTEXT | D-50(第一批 = 40 条 ALT) | COVERED(本组 2/40;A-6-1/2/3 DEFERRED) |
-| CONTEXT | D-51(准确记录源文件清单) | COVERED(`files_modified` + 逐文件影响表) |
-| CONTEXT | D-52(依据审计,不 invent) | COVERED(prohibitions + R2 STOP) |
-| CONTEXT | D-53(其它分类不在本批) | COVERED(范围门禁) |
+| CONTEXT | D-50(第一批 = 40 条 ALT) | COVERED(本计划记录承接关系,非 active 改造) |
+| CONTEXT | D-51(准确记录源文件清单) | COVERED(本计划无源码改动) |
+| CONTEXT | D-52(依据审计,不 invent) | COVERED(prohibitions) |
+| CONTEXT | D-53(其它分类不在本批) | COVERED(范围守卫) |
+| CONTEXT | **D-54(存档相关适配延后)** | COVERED(**A-1-1 DEFERRED**) |
| CONTEXT | D-03 / D-04(执行前获批 / 命名获批) | COVERED(Task 0 + prohibitions) |
-| ALT | A-6-1 / A-6-2 / A-6-3(`Mota.require` / `loading`) | **DEFERRED(用户自行处理)** —— 用户决定本计划不改;不修改 `cache.ts` / `misc.ts` |
-| 缺口 | R2(A-1-1 实例路径) | OPEN(Task 0 OI-3,待用户裁定) |
+| ALT | **A-1-1(`GameStorage` → `SaveSystem`)** | **DEFERRED(D-54)** —— 存档相关适配暂时忽略 / 延后 |
+| ALT | A-2-1(全局 `core` umbrella) | 记录(本计划,非源码改造) |
+| ALT | A-6-1 / A-6-2 / A-6-3(`Mota.require` / `loading`) | **DEFERRED(用户自行处理)** —— 不修改 `cache.ts` / `misc.ts` |
+| ALT | 其余 ALT(12 已 REPLACED 于 09-13;7 于 09-15;9 于 09-16) | COVERED(其它计划承接;本计划仅记录) |