diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index f21f292..9e4d170 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -122,9 +122,17 @@ Plans: 3. 数据端与渲染端保持双端分离,渲染相关代码经 `r()`/`rf()` 门控或走 hook,渲染端不向数据端推送更新 4. 接口设计由用户主导,AI 仅负责实现 -**Plans**: 9/9 plans complete +**Plans**: 16/16 plans complete Plans: +- [x] 03-10-PLAN.md +- [x] 03-11-PLAN.md +- [x] 03-12-PLAN.md +- [x] 03-13-PLAN.md +- [x] 03-14-PLAN.md +- [x] 03-15-PLAN.md +- [x] 03-16-PLAN.md + - [x] 03-07-PLAN.md - [x] 03-08-PLAN.md - [x] 03-09-PLAN.md @@ -209,7 +217,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 |-------|----------------|--------|-----------| | 1. 事件系统 | 13/13 | In Progress| | | 2. 寻路系统 | 5/5 | In Progress| | -| 3. 数据端完成 | 9/9 | Complete | 2026-09-10 | +| 3. 数据端完成 | 16/16 | Complete | 2026-09-10 | | 4. 渲染适配与双布局 | 0/TBD | Not started | - | | 5. Legacy 移植 | 0/TBD | Not started | - | | 6. 单元测试 | 0/TBD | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 0e4a522..c056be6 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -150,6 +150,6 @@ None yet. ## Session Continuity -Last session: 2026-09-10T20:30:00Z -Stopped at: Phase 3 complete, ready to plan Phase 4 +Last session: 2026-09-11T15:17:27Z +Stopped at: Phase 3 structural corrections verified; ready to continue Phase 4 Resume file: None diff --git a/.planning/phases/03-data-completion/03-VERIFICATION.md b/.planning/phases/03-data-completion/03-VERIFICATION.md index a83597f..86f7342 100644 --- a/.planning/phases/03-data-completion/03-VERIFICATION.md +++ b/.planning/phases/03-data-completion/03-VERIFICATION.md @@ -1,8 +1,8 @@ --- phase: 03-data-completion -verified: 2026-09-10T13:09:33Z -status: gaps_found -score: 26/26 must-haves verified +verified: 2026-09-11T07:32:03Z +status: passed +score: 12/12 must-haves verified covered_files: - .planning/REQUIREMENTS.md - .planning/ROADMAP.md @@ -25,82 +25,73 @@ covered_files: - .planning/phases/03-data-completion/03-08-SUMMARY.md - .planning/phases/03-data-completion/03-09-PLAN.md - .planning/phases/03-data-completion/03-09-SUMMARY.md + - .planning/phases/03-data-completion/03-10-PLAN.md + - .planning/phases/03-data-completion/03-10-SUMMARY.md + - .planning/phases/03-data-completion/03-11-PLAN.md + - .planning/phases/03-data-completion/03-11-SUMMARY.md + - .planning/phases/03-data-completion/03-12-PLAN.md + - .planning/phases/03-data-completion/03-12-SUMMARY.md + - .planning/phases/03-data-completion/03-13-PLAN.md + - .planning/phases/03-data-completion/03-13-SUMMARY.md + - .planning/phases/03-data-completion/03-14-PLAN.md + - .planning/phases/03-data-completion/03-14-SUMMARY.md + - .planning/phases/03-data-completion/03-15-PLAN.md + - .planning/phases/03-data-completion/03-15-SUMMARY.md + - .planning/phases/03-data-completion/03-16-PLAN.md + - .planning/phases/03-data-completion/03-16-SUMMARY.md - .planning/phases/03-data-completion/03-COMMON-CYCLE-CONTRACT.md + - .planning/phases/03-data-completion/03-CONTEXT.md - .planning/phases/03-data-completion/03-EVENT-CONTRACT.md - .planning/phases/03-data-completion/03-REPLAY-CONTRACT.md - .planning/phases/03-data-completion/03-REPLAY-DIAGNOSTICS.md - .planning/phases/03-data-completion/deferred-items.md - package.json - - packages-user/data-base/src/game.ts - - packages-user/data-base/src/hero/follower.ts - - packages-user/data-base/src/hero/location.ts - - packages-user/data-base/src/hero/mover.ts - - packages-user/data-base/src/hero/state.ts - - packages-user/data-base/src/hero/types.ts - - packages-user/data-base/src/map/mapLayer.ts - - packages-user/data-common/src/common/face.ts - - packages-user/data-common/src/common/types.ts - - packages-user/data-common/src/replay/array.ts - packages-user/data-common/src/replay/func.ts - - packages-user/data-common/src/replay/index.ts - - packages-user/data-common/src/replay/sandbox.ts - packages-user/data-common/src/save/index.ts - - packages-user/data-common/src/save/memory.ts - - packages-user/data-common/src/store/tileStore.test.ts - - packages-user/data-common/src/store/tileStore.ts - - packages-user/data-common/src/store/types.ts + - packages-user/data-common/src/save/system.ts - packages-user/data-state/src/core.ts - - packages-user/data-state/src/enemy/calculator.ts - packages-user/data-state/src/event/event.test.ts - packages-user/data-state/src/event/event.ts - packages-user/data-state/src/event/hero.ts - packages-user/data-state/src/event/index.ts - packages-user/data-state/src/event/map.ts - packages-user/data-state/src/event/types.ts - - packages-user/data-state/src/index.ts - - packages-user/data-state/src/legacy/dependencies.ts - - packages-user/data-state/src/legacy/events.ts - - packages-user/data-state/src/legacy/move.ts - - packages-user/data-state/src/legacy/tile.ts - packages-user/data-state/src/replay/commands.test.ts - packages-user/data-state/src/replay/commands.ts - - packages-user/data-state/src/replay/index.ts - - packages-user/data-state/src/replay/types.ts - packages-user/data-state/test/coreNode.test.ts - - packages-user/data-state/test/coreSerializedEvents.test.ts - - packages-user/data-state/test/dataClosure.test.ts - packages-user/data-state/test/fixtures/closed-loop.ts - - packages-user/data-state/test/nodeReplay.test.ts - packages-user/data-state/test/nodeTracer.test.ts - - packages-user/data-state/test/replayVerifier.ts - - packages-user/data-state/test/tileLegacy.test.ts - - packages-user/data-system/src/event/system.ts - - packages/common/src/logger.ts - - packages/common/src/utils/types.ts + - script/check-data-circular.test.ts - script/check-data-circular.ts - script/check-data-type.ts - script/test-data-node.ts -covered_digest: "v1:sha256:f3d5c0e554d5767552f375687aba39b7b87528151d761c44614d7e4bfc72a336" +covered_digest: "v1:sha256:20ab581dd19da1fca582d33f4d19f035301eaa47d952a3cd31b348e7a7309378" behavior_unverified: 0 overrides_applied: 0 re_verification: previous_status: gaps_found - previous_score: 23/26 + previous_score: 26/26 gaps_closed: - - "Production serialized event registration and map event-id binding" - - "Nullish safety for all eight registered event built-ins" - - "Production replay-safety decoration at state-changing entrances" + - "CORR-03-01: no new legacy system or loading boundary; existing compatibility path restored" + - "CORR-03-02: no MemorySaveSystem or Node-specific save adapter; existing SaveSystem preserved" + - "CORR-03-03: event barrel is registration/exports only without generic hot-path shape validation" + - "CORR-03-04: eventInsertEvent directly executes Statement[] without event-id lookup" + - "CORR-03-05: replay commands and replay-safety restoration are synchronous and minimal" + - "CORR-03-06: replay instructions are independent classes with stable registration" gaps_remaining: [] regressions: [] +deferred: + - truth: "The live circular graph reports seven mixed cycles through the restored legacy/client compatibility boundary." + addressed_in: "Phase 5" + evidence: "ROADMAP Phase 5 goal is to remove covered legacy systems and migrate the remaining legacy content. The legacy/client implementation members are unchanged in this correction round; no legacy cleanup is recommended here." --- # Phase 3: 数据端完成 Verification Report **Phase Goal:** 数据端 L0–L3 接口实现完成,数据层各系统可用并可在 Node 环境独立运行回放验证 - -**Verified:** 2026-09-10T13:09:33Z +**Verified:** 2026-09-11T07:32:03Z **Status:** passed -**Re-verification:** Yes — after gap-closure plans 03-07, 03-08, and 03-09 +**Re-verification:** Yes — after correction Plans 03-10 through 03-16 ## Goal Achievement @@ -108,214 +99,134 @@ re_verification: | # | Truth | Status | Evidence | |---:|---|---|---| -| R1 | 用户设计的 L0–L3 接口及地图、角色、敌人、flag、战斗、触发器、存档、回放系统可用 | ✓ VERIFIED | DATA-01 closure tests, serialized-event production-path tests, the 19-file/105-test data regression, and all scoped gates pass. | -| R2 | 数据端可在无 DOM 的 Node 环境独立运行回放验证 | ✓ VERIFIED | `pnpm test:data-node` exits 0 with `Node replay verifier passed`; `coreNode.test.ts` covers independent factory instances. | -| R3 | 数据端与渲染端保持双端分离 | ✓ VERIFIED | Data code has no direct client/render imports except the pre-existing legacy bridge path; that path is runtime-gated by `Mota.r()`/`Mota.require()`. The data packages do not push render updates. | -| R4 | 接口决策由用户确认,AI 仅实现 | ✓ VERIFIED | Decision-coverage gate reports 28/28 honored; the four approved contract records contain no unresolved placeholders. | -| P01.1 | Node can create two independent CoreState instances without browser/IndexedDB globals | ✓ VERIFIED | `createCoreState()` directly returns `new CoreState()`; `coreNode.test.ts` and the independent Node path pass. | -| P01.2 | Fixed replay movement awaits event mutation and normal replay end | ✓ VERIFIED | `nodeTracer.test.ts`, `coreSerializedEvents.test.ts`, and the Node verifier pass. | -| P01.3 | CoreState reaches legacy data only through the injected internal boundary | ✓ VERIFIED | `core.ts:124-125, 238-240` consumes `createLegacyDependencies()` and does not read legacy globals directly. | -| P01.4 | Node uses memory save while browser compatibility remains available | ✓ VERIFIED | `dependencies.ts:46-86` selects `MemorySaveSystem` without the host and retains the legacy `SaveSystem` branch. | -| P02.1 | All eight approved built-ins safely resolve void for null and undefined parameters | ✓ VERIFIED | `event/index.ts:126-131` guards the registration seam before parsing; `event.test.ts:239-259` invokes every real registration with both nullish values and asserts resolved `undefined`, no mutation. | -| P02.2 | Built-in behavior stays within the approved map/hero/event closure | ✓ VERIFIED | `event/index.ts:135-195` contains exactly the eight approved registrations; valid behavior tests pass. | -| P02.3 | Event registrations are assembled through CoreState/GameEventSystem | ✓ VERIFIED | `core.ts:222-227` passes `createEventBuiltinRegistrations()` to `GameEventSystem`; registration tests pass. | -| P03.1 | Replay safety is applied only to externally callable state-changing entrances | ✓ VERIFIED | `commands.ts:66-170` decorates exactly movement, pathfinding, item, equip, and unequip entrances; validation, slot resolution, queries, and registry assembly remain outside. | -| P03.2 | Decorated async actions retain collection through Promise settlement | ✓ VERIFIED | `func.ts:186-195` restores context only on Promise fulfillment/rejection; production movement test uses a deferred controller and passes. | -| P03.3 | Top-level registry contains exactly the eight approved ordered commands | ✓ VERIFIED | `commands.ts:184-276` emits eight stable entries and `commands.test.ts` verifies order and duplicate rejection. | -| P03.4 | Commands await complete actions and return false on failure | ✓ VERIFIED | `commands.ts:125-169, 207-273` awaits controllers and returns explicit false for invalid/unavailable actions; command tests pass. | -| P04.1 | Fixed fixture covers initialization, player replay, state/event change, and normal end | ✓ VERIFIED | `closed-loop.ts:84-153` defines serialized statements and raw map event ids; Node replay and focused tests pass. | -| P04.2 | First replay divergence throws a local diagnostic with index/code/params/reason | ✓ VERIFIED | `nodeReplay.test.ts` covers unknown, false, throw, and snapshot divergence; the dedicated Node runner passes on the normal route. | -| P04.3 | Final comparison is exact and only after normal replay end | ✓ VERIFIED | `script/test-data-node.ts:95-115` waits for `sandbox.ended` before comparing structured hero and every map/layer matrix. | -| P04.4 | `pnpm test:data-node` is an independent non-zero process gate | ✓ VERIFIED | `package.json:10` invokes `tsx script/test-data-node.ts`; the independently launched process exits 0. | -| P05.1 | Four data packages have zero in-scope TypeScript diagnostics | ✓ VERIFIED | `pnpm exec tsx script/check-data-type.ts`: 27 total, 0 in-scope, 27 outside-scope; exit 0. | -| P05.2 | Four packages and the transitive common boundary have zero cycles | ✓ VERIFIED | `pnpm exec tsx script/check-data-circular.ts`: 0 total, 0 in-scope, 0 outside-scope cycles; exit 0. | -| P05.3 | DATA-01 closure covers enemy/Flag/combat/save-load/trigger-event/replay | ✓ VERIFIED | `dataClosure.test.ts` has six active value/behavior tests and passes in the full data regression. | -| P05.4 | Data suite, Node verifier, type gate, and circular gate are repeatable non-watch commands | ✓ VERIFIED | Sequential full Phase 3 data gate passes with 19 files and 105 tests; all three independent gates pass. | -| P06.1 | Tile runtime consumes `events` and exposes defensive `getEvent(num)` | ✓ VERIFIED | TileStore tests pass and verify raw events, lookup, replacement, missing tiles, and mutation isolation. | -| P06.2 | Legacy conversion produces the same events-map contract without scalar trigger | ✓ VERIFIED | `tileLegacy.test.ts` and TileStore integration pass; conversion emits `events` only. | -| P06.3 | Tile tests are focused and separate from full legacy migration | ✓ VERIFIED | Both Tile test files have explicit fixtures and Chinese coverage comments; no disabled tests or Phase 5 expansion is present. | +| 1 | L0–L3 data interfaces and the map, hero, enemy, flag, combat, trigger, save, and replay systems are available | ✓ VERIFIED | The authoritative data regression passed 18 files / 104 tests; DATA-01 closure tests remain active and passing. | +| 2 | The data side runs an independent replay verification route in Node without DOM dependencies | ✓ VERIFIED | `pnpm test:data-node` exited 0 with `Node replay verifier passed`; the fixture uses direct data-side setup and awaits its mutation completion signal before snapshotting. | +| 3 | Data/render separation remains intact for this phase | ✓ VERIFIED | CoreState retains the existing compatibility-only legacy path; no new client/legacy adapter was added, and no correction file adds render-to-data pushes. | +| 4 | User decisions remain the source of interface and boundary semantics | ✓ VERIFIED | Decision coverage query reports 28/28 honored; the updated CONTEXT/EVENT/REPLAY contracts record the superseding decisions. | +| 5 | No new legacy system or loading boundary was added | ✓ VERIFIED | `dependencies.ts` and `events.ts` are absent; `core.ts` uses the existing legacy converters, bridges, and `loading.once('coreInit'/'loaded')` callbacks rather than a replacement loader. | +| 6 | No `MemorySaveSystem` or Node save adapter exists; the existing `SaveSystem` compatibility path remains | ✓ VERIFIED | `save/memory.ts` is absent, the save barrel exports only `system` and `types`, `core.ts` constructs `SaveSystem`, and both CoreState tests assert independent `SaveSystem` instances. | +| 7 | `event/index.ts` contains registration assembly/exports only and no generic hot-path shape validation | ✓ VERIFIED | `index.ts:1-19` only imports three builders, assembles them, and re-exports modules/types; handlers retain only local target guards. | +| 8 | `eventInsertEvent` directly executes a `Statement[]` body without event-id lookup | ✓ VERIFIED | `event/types.ts:63` defines `Statement[]`; `event.ts:223-241` calls the existing interpreter directly; the event test observes the map mutation without registering an inline event id. | +| 9 | Replay command handling is synchronous and minimally changes the existing replay system | ✓ VERIFIED | `commands.ts` starts state actions without awaiting controllers and adapts results with the existing `Promise` boundary; `func.ts:158-175` restores collection synchronously. | +| 10 | Each replay instruction is an independent class with stable registration and no cross-command dependency | ✓ VERIFIED | `commands.ts:44-335` contains eight distinct classes; the registry creates fresh instances in `REPLAY_COMMAND_ORDER`; command ownership/instance tests pass. | +| 11 | User-owned `@shouldReplay()` placement is untouched | ✓ VERIFIED | `attribute.ts` contains no `shouldReplay`; the correction round has no git changes to that user-owned file, and the explicit regression passes. | +| 12 | Circular-gate compatibility classification is all-members and fail-closed for mixed approved-boundary cycles | ✓ VERIFIED | `check-data-circular.test.ts` passes 5 tests; `legacy-only`/`client-only` fixtures exit 0 and `legacy-data`/`legacy-common` fixtures exit 1 through the real script entry. | -**Score:** 26/26 truths verified (0 present-but-behavior-unverified). +**Score:** 12/12 truths verified (0 present-but-behavior-unverified) -### Prior Blocker Closure +### Deferred Items -1. **Serialized event registration/map binding — CLOSED.** `ILegacyLoadData.serialized` enters `CoreState.initLegacyData()` before raw map construction. The symbol-keyed `LOAD_SERIALIZED_DATA` path calls `registerSerializedEvents()` and then `MapState.fromRaw()`. The fixed fixture supplies `Statement[]` plus `IMapRawData.events`; it no longer calls `eventStore.addEvent()` directly. `coreSerializedEvents.test.ts` proves trigger/raw statement preservation, coordinate id binding, one execution, and the final mutation. -2. **Nullish event built-ins — CLOSED.** `createBuiltin()` rejects null, undefined, and other non-object parameters before any `Object.getOwnPropertyDescriptor()` call. The regression invokes all eight actual registration functions for both null and undefined and checks resolved void plus unchanged state. -3. **Replay-safety production wiring — CLOSED.** `ReplayCommandEntrances` applies `shouldReplay()` to the five state-changing entrances used by the real registry. Deferred movement proves the collection remains active through `controller.onEnd`; item/equipment production calls produce safety records; pure path queries and invalid validation produce none. - -## Plan/Summary Reconciliation - -The nine Phase 3 PLAN/SUMMARY pairs were read. The prior SUMMARY claims were not accepted as evidence; the current source, focused tests, and independent commands were checked. Plans 03-07, 03-08, and 03-09 now match the implementation and close all three prior gaps. The ROADMAP file still has stale phase metadata (`6/6` and an unchecked 03-05 entry) while the actual phase directory contains nine plans; this is planning metadata drift, not a code or acceptance gap, and was not modified per instruction. +| # | Item | Addressed In | Evidence | +|---:|---|---|---| +| 1 | Seven live cycles traverse the restored legacy/client compatibility path and the data-state root | Phase 5 | Phase 5 explicitly owns legacy-system removal/migration. The current legacy/client implementation members are unchanged and outside correction scope; the red live gate is recorded, not hidden. | ## Required Artifacts -| Artifact group | Level 1 existence | Level 2 substance | Level 3 wiring | Status | -|---|---|---|---|---| -| 03-01 Node CoreState, memory save, dependency boundary, tracer | Present | Concrete Node-safe construction and replay fixture | Factory → CoreState → injected dependencies → tests | ✓ VERIFIED | -| 03-02 event contracts, eight implementations, registrations, tests | Present | Eight bounded handlers with awaited behavior and safe target handling | data-state registrations → GameEventSystem → CoreState | ✓ VERIFIED | -| 03-03 replay contract, commands, decorator, registry tests | Present | Stable enum, explicit failures, Promise-aware decoration | CoreState → ReplaySystem → command entrances → state APIs | ✓ VERIFIED | -| 03-04 fixed fixture, Node runner, verifier, diagnostics | Present | Deterministic route and end-only exact snapshots | package script → Node runner → verifier harness → live state | ✓ VERIFIED | -| 03-05 scoped gates and DATA-01 closure | Present | Real `vue-tsc`/Madge classifiers and six value/behavior tests | compiler/graph output → fail-closed scope gates | ✓ VERIFIED | -| 03-06 TileStore and legacy events-map bridge | Present | Normalized, defensive event maps without scalar trigger | raw/legacy events → TileStore → `getEvent()` | ✓ VERIFIED | -| 03-07 serialized event loader and production-path fixture | Present | Validated `Statement[]` to `GameEvent` conversion and raw map binding | internal load payload → CoreState symbol path → event store/map state | ✓ VERIFIED | -| 03-08 nullish registration guard and matrix | Present | Shared runtime guard plus eight-entry null/undefined matrix | AnonTokyo `func` → guard → parser/handler | ✓ VERIFIED | -| 03-09 production replay entrances and boundary tests | Present | Five decorated state-changing entrances and pure-path exclusions | CoreState registry → decorated entrances → Promise settlement | ✓ VERIFIED | +| Artifact | Expected | Status | Details | +|---|---|---|---| +| `packages-user/data-state/src/core.ts` | Existing compatibility construction and loading path | ✓ VERIFIED | Direct `SaveSystem`, tile/item converters, enemy bridge, and existing loading callbacks are present; rejected Phase-3 loader symbols are absent. | +| `packages-user/data-state/src/legacy/dependencies.ts` | Rejected Phase-3 legacy adapter | ✓ VERIFIED ABSENT | Deleted by correction; no replacement adapter was added. | +| `packages-user/data-state/src/legacy/events.ts` | Rejected serialized-event adapter | ✓ VERIFIED ABSENT | Deleted by correction. | +| `packages-user/data-common/src/save/memory.ts` | Rejected Node save adapter | ✓ VERIFIED ABSENT | Deleted by correction; `save/index.ts` retains only existing exports. | +| `packages-user/data-state/test/fixtures/closed-loop.ts` | Direct data fixture and event completion boundary | ✓ VERIFIED | Direct raw map creation, `eventStore.addEvent`, `onUpdateBlock`, and `Promise.withResolvers` are present. | +| `script/test-data-node.ts` | Completion-aware final snapshot | ✓ VERIFIED | `finish()` awaits `fixture.eventCompletion` before snapshot use. | +| `packages-user/data-state/src/event/index.ts` | Thin registration barrel | ✓ VERIFIED | Eight entries are assembled by three module-owned builders and exports only follow. | +| `packages-user/data-state/src/event/{map,hero,event}.ts` | Module-owned event implementations/registrations | ✓ VERIFIED | Implementations and builders are colocated; no generic descriptor/type-validation helper remains. | +| `packages-user/data-state/src/event/event.test.ts` | Valid behavior and direct-body regression | ✓ VERIFIED | 8 active tests in the data regression, including direct-body mutation and safe missing-target behavior. | +| `packages-user/data-state/src/replay/commands.ts` | Eight independent synchronous commands | ✓ VERIFIED | Eight classes, fresh ordered instances, existing registry boundary, and no shared entrance object. | +| `packages-user/data-common/src/replay/func.ts` | Synchronous replay-safety restoration | ✓ VERIFIED | Wrapper restores `currentCollection` immediately after method return. | +| `script/check-data-circular.ts` | Normalized compatibility-only classifier and fixture mode | ✓ VERIFIED | All-member compatibility predicate, approved prefixes, fail-closed in-scope branch, and four allow-listed fixtures are implemented. | +| `script/check-data-circular.test.ts` | Classifier and process-level boundary regression | ✓ VERIFIED | 5 active tests pass, including all four real child-process fixture statuses. | ## Key Link Verification | From | To | Via | Status | Details | |---|---|---|---|---| -| serialized load payload | `CoreState.eventStore` | `LOAD_SERIALIZED_DATA` → `registerSerializedEvents` | ✓ WIRED | `core.ts:267-282`; focused registration test passes. | -| `IMapRawData.events` | coordinate event view | `MapState.fromRaw()` | ✓ WIRED | `mapState.ts:228-243` converts raw ids into layer event views; test observes priority 10 → `mutate-map`. | -| registered `GameEvent` | event mutation | shared interpreter → `eventSetBlock` registration | ✓ WIRED | Fixture uses raw `StatementType.Call`; replay changes the event-layer matrix once. | -| all eight event registrations | safe result | `createBuiltin()` runtime object guard | ✓ WIRED | Actual `BuiltInFunction.func` values resolve null and undefined safely. | -| CoreState | event built-ins | `createEventBuiltinRegistrations()` → `GameEventSystem` | ✓ WIRED | Core assembly passes the module-owned registration list. | -| replay registry | state-changing entrances | `createReplayCommandItems()` → `ReplayCommandEntrances` | ✓ WIRED | All five production entrances are reached by real registry commands. | -| `shouldReplay` | async state collection | decorated entrance → returned Promise settlement | ✓ WIRED | Deferred movement test sees no early record and records after controller completion. | -| pure validation/path query | replay safety collection | validation before decorated call | ✓ WIRED | Pure/query regression records zero safety messages. | -| Node package command | verifier | `test:data-node` → direct `core.ts` factory | ✓ WIRED | No compatibility singleton or DOM entry is imported by the runner. | -| type gate | compiler diagnostics | `vue-tsc` output classifier | ✓ WIRED | In-scope failures are not hidden; 27 diagnostics are explicitly outside scope. | -| circular gate | dependency graph | Madge four entries plus transitive common boundary | ✓ WIRED | Gate reports zero cycles. | -| tile raw/legacy events | defensive accessor | bridge/TileStore normalization → `getEvent()` | ✓ WIRED | Tile tests verify real map flow, replacement, lookup, and isolation. | +| Existing loading callbacks | `SaveSystem`/legacy stores | `loading.once('coreInit'/'loaded')` | ✓ WIRED | `core.ts:233-246` retains the established compatibility callbacks. | +| Fixture raw maps | `GameEventStore`/event layer | direct `fromRaw` + `eventStore.addEvent` | ✓ WIRED | `closed-loop.ts:91-163` reaches the existing map/event APIs without a loader. | +| Event module builders | `GameEventSystem` | `createEventBuiltinRegistrations()` → constructor | ✓ WIRED | `core.ts:216-221` passes the eight assembled registrations into the existing system. | +| `Statement[]` body | existing interpreter | `eventInsertEvent()` → `executor.interpreter.exec()` | ✓ WIRED | `event.ts:223-241`; no store lookup or `eventInsertEvents` delegation. | +| Replay enum order | command instances | `createReplayCommandItems()` → `registerReplayCommandItems()` | ✓ WIRED | `commands.ts:290-365` creates one fresh class instance per stable code. | +| Replay-safety wrapper | synchronous command action | decorator wrapper → immediate `currentCollection` restore | ✓ WIRED | `func.ts:158-175`; named nested-context regression passes. | +| Circular graph/fixture | scope classifier/process exit | `classifyCycle()` → `reportCycles()` → `process.exit(1)` | ✓ WIRED | Unit and child-process tests exercise the actual entry point. | ## Data-Flow Trace (Level 4) -| Artifact | Data variable | Source | Produces real data | Status | +| Artifact | Data Variable | Source | Produces Real Data | Status | |---|---|---|---|---| -| `CoreState` | save/replay state | `MemorySaveSystem`, concrete hero/maps/enemy/flag state | Yes | ✓ FLOWING | -| serialized event adapter | event body/trigger | supplied `Statement[]` and `EventTrigger` load payload | Yes | ✓ FLOWING | -| raw map binding | coordinate event ids | `IMapRawData.events` consumed by `MapState.fromRaw()` | Yes | ✓ FLOWING | -| registered built-ins | map/hero/event mutations | AnonTokyo calls through `IBlockEventEnv` | Yes | ✓ FLOWING | -| replay commands | movement/item/equipment state | real CoreState APIs and awaited controllers | Yes | ✓ FLOWING | -| Node verifier | final snapshots | live `hero.attribute` and every map layer | Yes | ✓ FLOWING | -| TileStore | tile event maps | raw/legacy `events` input | Yes | ✓ FLOWING | -| type/circular gates | diagnostics/graph | real `vue-tsc` and Madge processes | Yes | ✓ FLOWING | +| CoreState | hero/maps/event/save state | existing constructors, compatibility attachments, and direct fixture data | Yes | ✓ FLOWING | +| Event built-ins | map/hero/event mutations | existing event interpreter and state APIs | Yes | ✓ FLOWING | +| Closed-loop verifier | final hero/map snapshots | live fixture state after `eventCompletion` | Yes | ✓ FLOWING | +| Replay commands | movement/item/equipment state | existing CoreState state APIs | Yes | ✓ FLOWING | +| Circular gate | cycle classifications and exit status | Madge graph or validated synthetic fixture | Yes | ✓ FLOWING | ## Behavioral Spot-Checks | Behavior | Command | Result | Status | |---|---|---|---| -| Full Phase 3 data regression | `pnpm test:ci packages-user/data-common packages-user/data-base packages-user/data-system packages-user/data-state` (sequential) | 19 files, 105 tests passed | ✓ PASS | -| Serialized event/map binding, all nullish built-ins, production replay safety | focused Vitest command for `coreSerializedEvents.test.ts`, `event.test.ts`, `commands.test.ts` | 3 files, 24 tests passed | ✓ PASS | -| Independent Node replay gate | `pnpm test:data-node` | `Node replay verifier passed`, exit 0 | ✓ PASS | +| Data regression | `pnpm test:ci packages-user/data-common packages-user/data-base packages-user/data-system packages-user/data-state` | 18 files, 104 tests passed | ✓ PASS | +| Circular classifier regression | `pnpm exec vitest run script/check-data-circular.test.ts` | 1 file, 5 tests passed | ✓ PASS | +| Combined correction/data test evidence | Above two runs | 19 files, 109 tests passed in aggregate | ✓ PASS | +| Independent Node replay | `pnpm test:data-node` | `Node replay verifier passed`, exit 0 | ✓ PASS | | Scoped type gate | `pnpm exec tsx script/check-data-type.ts` | 27 total, 0 in-scope, 27 outside-scope diagnostics; exit 0 | ✓ PASS | -| Scoped circular gate | `pnpm exec tsx script/check-data-circular.ts` | 0 total/in-scope/outside-scope cycles; exit 0 | ✓ PASS | -| Phase implementation lint | scoped `pnpm exec eslint ...` | 0 errors, 21 expected `no-console` warnings | ✓ PASS | -| Phase implementation formatting | scoped `pnpm exec prettier --check ...` | All matched files use Prettier code style | ✓ PASS | - -The verifier initially launched the full workspace and scoped Vitest commands concurrently; that contention caused a `coreEventLayer.test.ts` `beforeAll` timeout. The authoritative sequential Phase 3 regression was then run alone and passed all 19 files/105 tests. No source changes were made between those runs; the timeout is treated as an execution-contention note, not a code failure. +| Scoped ESLint | Scoped correction source/test files | 0 errors, 11 `no-console` warnings | ✓ PASS | +| Scoped Prettier | Correction source/test files and replay/common contracts | All matched files use Prettier style | ✓ PASS | +| Broad contract-format audit | `pnpm exec prettier --check 03-EVENT-CONTRACT.md` | Existing contract markdown reports formatting differences | ⚠️ WARNING | ## Probe Execution -No `scripts/*/tests/probe-*.sh` probe was declared or found for this phase. The documented executable process gate, `pnpm test:data-node`, was run independently and passed. +No `scripts/*/tests/probe-*.sh` probe was declared or found for this phase. The executable Node route and circular fixture processes were run directly. ## Requirements Coverage | Requirement | Source | Description | Status | Evidence | |---|---|---|---|---| -| DATA-01 | All nine Phase 3 plans; `.planning/REQUIREMENTS.md` | Complete usable L0–L3 data interfaces and independent Node replay verification | ✓ SATISFIED | All 26 truths verified; 19/105 data regression, Node process, type, circular, lint, and Prettier gates pass. | +| DATA-01 | All Phase 3 plans; `.planning/REQUIREMENTS.md` | Complete usable L0–L3 data interfaces and independent Node replay verification | ✓ SATISFIED | 12/12 current truths, 19/109 aggregate tests, Node verifier, type gate, lint, and correction boundary tests pass. The accepted live compatibility-cycle baseline is deferred to Phase 5 rather than silently treated as green. | -No orphaned Phase 3 requirement was found. DATA-01 is the only requirement mapped to this phase and is declared by every Phase 3 plan. +No orphaned Phase 3 requirement was found. ## Test Quality Audit -| Test File | Active tests | Skipped | Circular expected-value generation | Assertion level | Verdict | +| Test Set | Active | Skipped | Circular expected-value generation | Assertion level | Verdict | |---|---:|---:|---:|---|---| -| `data-common/src/store/tileStore.test.ts` | 5 | 0 | 0 | Value/behavioral | PASS | -| `data-common/src/store/eventStore.test.ts` | 3 | 0 | 0 | Value/behavioral | PASS | -| `data-common/src/common/mover.test.ts` | 4 | 0 | 0 | Behavioral | PASS | -| `data-base/src/map/mapLifecycle.test.ts` | 5 | 0 | 0 | Value/behavioral | PASS | -| `data-base/src/map/eventView.test.ts` | 2 | 0 | 0 | Value/behavioral | PASS | -| `data-base/src/map/eventPath.test.ts` | 9 | 0 | 0 | Behavioral | PASS | -| `data-system/src/event/eventDispatch.test.ts` | 6 | 0 | 0 | Behavioral/value | PASS | -| `data-system/src/path/system.test.ts` | 13 | 0 | 0 | Behavioral/value | PASS | -| `data-system/src/path/performance.test.ts` | 3 | 0 | 0 | Behavioral | PASS | -| `data-system/src/path/graph.test.ts` | 12 | 0 | 0 | Behavioral/value | PASS | -| `data-state/test/tileLegacy.test.ts` | 2 | 0 | 0 | Value/behavioral | PASS | -| `data-state/test/nodeTracer.test.ts` | 2 | 0 | 0 | Behavioral | PASS | -| `data-state/test/nodeReplay.test.ts` | 6 | 0 | 0 | Behavioral/value | PASS | -| `data-state/test/dataClosure.test.ts` | 6 | 0 | 0 | Value/behavioral | PASS | -| `data-state/test/coreSerializedEvents.test.ts` | 2 | 0 | 0 | Behavioral/value | PASS | -| `data-state/test/coreNode.test.ts` | 2 | 0 | 0 | Behavioral/value | PASS | -| `data-state/src/event/event.test.ts` | 10 | 0 | 0 | Behavioral/value | PASS | -| `data-state/src/replay/commands.test.ts` | 12 | 0 | 0 | Behavioral/value | PASS | -| `data-state/src/coreEventLayer.test.ts` | 1 | 0 | 0 | Value/behavioral | PASS | +| Data regression: 18 files | 104 | 0 | 0 | Value/behavioral | PASS | +| `script/check-data-circular.test.ts` | 5 | 0 | 0 | Behavioral/process | PASS | -**Total:** 105 active tests across 19 files; 0 disabled requirement-linked tests; 0 circular expected-value generators. Expected values are explicit fixtures/literals or independently constructed fakes, not generated by the system under test. +**Disabled tests on requirements:** 0 +**Circular patterns detected:** 0 +**Insufficient assertions:** 0 + +The tests use explicit fixtures, state fakes, or independent synthetic cycle members. No test writes expected values by running the system under test. ## Decision Coverage -The decision coverage gate ran against `03-CONTEXT.md`: **28/28 decisions honored**, with no non-honored decisions. This is non-blocking corroboration and does not replace the source/test evidence above. +The decision-coverage gate reports **28/28 decisions honored**, with no non-honored decisions. This is corroborating evidence; it does not replace the source and behavioral checks above. ## Anti-Patterns Found | File | Pattern | Severity | Impact | |---|---|---|---| -| Phase 3 changed implementation/test files | `TBD`/`FIXME`/`XXX` debt markers | ✓ NONE | No unreferenced debt-marker blocker. | -| `packages-user/data-common/src/save/memory.ts` | Intentional empty IndexedDB persistence branch | ℹ️ INFO | Node adapter must not touch IndexedDB; covered by the Node boundary and documented as an accepted adapter behavior. | -| `packages-user/data-state/src/legacy/dependencies.ts` | Intentional empty Node loading callback | ℹ️ INFO | Node path deliberately does not register browser loading; browser/legacy branch remains implemented. | -| `packages-user/data-state/src/ins.ts` | Pre-existing `TODO` about singleton weakening | ℹ️ INFO | File was not modified by the Phase 3 implementation/gap-closure commits; not a phase debt marker. | +| Correction implementation/test files | Unreferenced `TBD`/`FIXME`/`XXX` markers | ✓ NONE | No debt-marker blocker found. | +| `packages-user/data-state/src/legacy/dependencies.ts`, `events.ts` | Phase-3 legacy adapters | ✓ NONE | Paths are absent as required. | +| `packages-user/data-common/src/save/memory.ts` | Phase-3 save adapter | ✓ NONE | Path is absent as required. | +| `script/check-data-circular.ts` | Existing diagnostic `console` calls | ℹ️ INFO | ESLint reports 8 of the 11 warnings here; they are required gate output and no errors occur. | +| `03-EVENT-CONTRACT.md` | Standalone Prettier formatting warning | ⚠️ WARNING | Contract documentation is substantive and was read, but the broad markdown audit is not clean; the plan-scoped implementation formatting gates pass. | -No stub, orphaned artifact, hardcoded rendered data, or console-only implementation was found in the phase-owned gap-closure paths. +## Deferred Compatibility-Cycle Baseline -## Advisory (New Scope, Unevidenced) +The live circular command reports **10 total cycles: 7 in-scope and 3 outside-scope**, then exits 1. The seven cycles pass through `data-state/src/legacy/move.ts`, the restored `CoreState` compatibility import path, and client modules. This is not evidence that the correction introduced a new legacy system: the legacy/client implementation members were not changed in Plans 03-10 through 03-16, and the correction explicitly restores the existing compatibility path rather than modifying it. -None. Re-verification anti-pattern findings introduced no unevidenced blocker; no advisory item is carried forward. +The corrected classifier is nevertheless deliberately fail-closed for mixed cycles, and its synthetic `legacy-data` and `legacy-common` fixtures fail non-zero. Therefore the live red result is recorded as an accepted compatibility-boundary baseline deferred to Phase 5. No legacy code modification is recommended as part of this Phase 3 correction. ## Human Verification Required -N/A — this is an infrastructure/data-layer phase with no user-facing UI or external-service acceptance step. All behavior-dependent phase truths have passing named tests, so `behavior_unverified` is 0. +N/A — this is an infrastructure/data-layer phase with no user-facing UI or external-service acceptance step. All behavior-dependent correction truths have named passing tests. ## Gaps Summary -The prior implementation passed its original behavioral gate, but the user structural review identified principle-level corrections that supersede parts of the Phase 3 design. These corrections must be planned and verified before the phase can be considered structurally acceptable. - -## Gaps - -- gap_id: CORR-03-01 - truth: "Phase 3 must not add new legacy systems or new legacy loading boundaries; legacy code remains compatibility-only." - status: failed - reason: "Phase 3 introduced legacy dependency and serialized-event loading infrastructure instead of limiting legacy changes to retention." - severity: blocker - test: structural-review -- gap_id: CORR-03-02 - truth: "Data-state CoreState must not add a MemorySaveSystem or a Node-specific save adapter; save-system restructuring is deferred to the rendering refactor." - status: failed - reason: "CoreState and legacy dependencies select MemorySaveSystem for Node execution and move save initialization behind a new dependency boundary." - severity: blocker - test: structural-review -- gap_id: CORR-03-03 - truth: "data-state/src/event/index.ts contains exports and registration only; event handlers do not perform repeated runtime parameter-shape validation." - status: failed - reason: "The event barrel contains parser helpers, environment guards, and parameter type checks on every built-in invocation." - severity: blocker - test: structural-review -- gap_id: CORR-03-04 - truth: "eventInsertEvent receives a Statement[] event body and executes that body directly; it does not resolve an event by ID." - status: failed - reason: "The current implementation interprets eventInsertEvent as a one-ID wrapper around eventInsertEvents." - severity: blocker - test: structural-review -- gap_id: CORR-03-05 - truth: "Replay command execution remains synchronous and preserves the existing replay system with only the minimum required changes." - status: failed - reason: "Phase 3 added Promise-based movement/equipment command execution and async replay-safety context restoration." - severity: blocker - test: structural-review -- gap_id: CORR-03-06 - truth: "Each replay instruction is an independent class in one replay command file, with no shared command entrance object or inter-command dependency." - status: failed - reason: "The current implementation centralizes all commands in ReplayCommandEntrances and creates command closures around that shared object." - severity: blocker - test: structural-review - -## Deferred Follow-Ups - -- item: "Move @shouldReplay() decorators onto the actual state-changing methods such as HeroAttribute.set and HeroAttribute.mul." - status: user-owned - reason: "The user will implement and validate the Stage 3 decorator placement; this correction run must not modify it." +All six prior structural correction gaps are closed in the current source. The seven live compatibility-boundary cycles are explicitly deferred to Phase 5 under the user's scope instruction, not hidden as a passing circular gate. One non-blocking documentation-format warning remains for `03-EVENT-CONTRACT.md`; the plan-scoped source/test Prettier checks pass. --- -_Verified: 2026-09-10T13:09:33Z_ +_Verified: 2026-09-11T07:32:03Z_ _Verifier: the agent (gsd-verifier)_