Research: Map Contract и пространственная согласованность
Baseline#
PRD требует branch/location contexts, private split-party visibility и authoritative location state, но не задаёт concrete world map. Tactical grid и map editor явно не нужны для первого validation outcome.
До prototype не существовало исполняемого spatial contract, поэтому нельзя было до старта автоматически доказать:
- что region/location/edge и content references существуют;
- что обязательный финальный location достижим;
- что one-way edge и obstacle нельзя обойти;
- что fog/private node не утечёт через projection или edge;
- что travel cost и line of sight читаются из authoritative data, а не из narration.
Метод#
- Зафиксировать MC-01–MC-08 до implementation.
- Выбрать минимальную модель: directed adjacency graph; coordinates только presentation hints.
- Создать original, non-canonical sci-fi comedy map fixture с public, hidden и player-private locations, open/conditional edges и one-way service route.
- Зафиксировать meaningful RED: tests должны упасть из-за отсутствующего
map.ts. - Реализовать runtime validation, static reachability, player projection, direct movement и direct-edge LOS без dependencies.
- Mutation tests разрывают region, endpoint, content refs и финальную достижимость.
- Две projections сравнивают visitor и authorized custodian.
- Demo выполняет validation, reachability и один blocked/allowed move.
Static reachability намеренно считает conditional edge потенциально проходимым и исключает permanently blocked edge. Это отвечает на вопрос «может ли contract вообще дать путь», но не «получит ли party нужный flag».
Реестр доказательств#
| ID | Тип | Описание | Источник, путь или команда | Дата или версия |
|---|---|---|---|---|
| E-001 | Fact | PRD требует branch/location authorization и исключает tactical grid из MVP | ../../docs/prd/2026-07-22-global-party-ai-rpg.md, строки 125–130 и 174 |
Updated 2026-07-24 |
| E-002 | Fact | Architecture требует visibility scope, global chronology и отсутствие cross-branch leakage | ../../research/06-product-mvp-and-ai-gm.md, строки 140–160 |
2026-07 corpus |
| E-003 | Measurement | Meaningful RED: отсутствует implementation module | node --experimental-strip-types --test prototype/map.test.ts → ERR_MODULE_NOT_FOUND: prototype/map.ts |
Node v22.14.0 |
| E-004 | Measurement | Behavioral suite: 6 tests, 6 pass, 0 fail | node --no-warnings --experimental-strip-types --test prototype/map.test.ts |
2026-07-25 |
| E-005 | Measurement | Demo: 5 structurally reachable nodes, visitor sees only one initial node, blocked/allowed move differ by flag, 0 issues | node --no-warnings --experimental-strip-types prototype/demo.ts |
2026-07-25 |
| E-006 | Fact | Fixture is original, borrowed-IP-free and non-canonical | prototype/fixtures/sci-fi-comedy-map.ts |
Fixture v1 |
| E-007 | Fact | Projection removes an edge unless viewer can see both endpoints and the edge itself | prototype/map.ts, projectMapForViewer |
Prototype v1 |
| E-008 | Inference | Directed graph is sufficient for researched room-scale topology and avoids premature tactical-grid complexity | E-004, E-005 | 2026-07-25 |
| E-009 | Measurement | Scoped strict TypeScript check завершился с exit 0 и без diagnostics | Root node_modules/.bin/tsc --ignoreConfig ... prototype/*.ts prototype/fixtures/*.ts |
TypeScript 7.0.2, @types/node 24.13.3 |
Журнал экспериментов#
| Время | Изменение или попытка | Наблюдение | Artifact или evidence ID | Вывод |
|---|---|---|---|---|
| 2026-07-24T18:17:59Z | Первый .ts test без strip flag |
ERR_UNKNOWN_FILE_EXTENSION на Node v22.14.0 |
Command log | Команда не достигла behavior; добавить explicit strip flag |
| 2026-07-24T18:17:59Z | RED с strip flag | ERR_MODULE_NOT_FOUND для map.ts |
E-003 | RED подтверждён по нужной причине |
| 2026-07-24T18:17:59Z | Реализованы validator/projection/move/LOS | 6/6 behavior tests прошли | E-004 | Основные spatial invariants подтверждены |
| 2026-07-24T18:17:59Z | Повреждены refs и финальные routes | Stable error codes включают missing refs и unreachable required location | E-004 | Invalid content/map package fail-closed |
| 2026-07-24T18:17:59Z | Выполнен demo | 0 issues; visitor projection не раскрыла hidden/private nodes; conditional move разрешён только с flag | E-005 | Execution path подтверждён |
| 2026-07-24T18:17:59Z | Выполнен scoped strict typecheck | Exit 0, diagnostics отсутствуют | E-009 | Erasable TS и strict signatures подтверждены |
Выводы#
- Measurement: MC-01–MC-08 проходят в одном reproducible suite; strict scoped typecheck чист. Основание: E-004, E-005, E-009.
- Inference: topology authoritative, coordinates optional; это позволяет менять rendering layout без изменения legal movement graph. Основание: E-004, E-008.
- Inference: authorization и discovery — разные gates. Даже явно
discoveredLocationIdsне раскрывает private node неавторизованному viewer. Основание: E-004, E-007. - Inference: content binding через opaque authoritative ID index сохраняет границу: map знает ссылки, но не переписывает scenes/triggers. Основание: E-004.
Рассмотренные альтернативы#
| Подход | Что проверили | Почему не выбран | Evidence |
|---|---|---|---|
| Tactical square/hex grid | Сопоставление с scope и нужными invariants | Добавляет combat geometry, не нужную для room/node movement | E-001, E-008 |
| Coordinates как movement authority | Наличие layout coordinates и graph edges | Euclidean distance не выражает locked doors, one-way routes или story transitions | E-004, E-005 |
| Narrator решает достижимость | Сопоставление с authoritative state | Нельзя детерминированно replay или запретить обход obstacle | E-002, E-004 |
| Отправлять полный map клиенту и скрывать CSS | Privacy projection test | Hidden/private IDs и content refs уже являются утечкой | E-004, E-007 |
| Полноценная graph library | Реализованы BFS и direct edge lookup stdlib | Новый dependency не снижает исследуемый риск для малого graph | E-004, E-005 |
Неизвестные#
- Unknown U-01: dynamic obstacles и конкурентные movement commands; нужен state-version/idempotency study.
- Unknown U-02: LOS для grid/polygons, высоты и moving occluders.
- Unknown U-03: оптимальный UX fog/frontier без утечки hidden IDs.
- Unknown U-04: масштабирование graph traversal на большие worlds.
- Unknown U-05: достижимость при комбинациях mutually exclusive flags; для этого нужен model checking/state-space exploration.