# Solution: Node-first strict TypeScript with npm-only installs ## Выбранный подход Прототип использует Node.js 24 как основной runtime и TypeScript 7.0.2 как отдельный static gate. Bun запускает тот же source только как compatibility smoke. Корневой npm manifest и `package-lock.json` — единственные package metadata; отдельного manifest/lock внутри исследования намеренно нет. Главный риск — ложное объединение трёх разных гарантий. Выбранный pipeline разделяет их: - `npm ci` гарантирует lock-based install; - `tsc --noEmit` гарантирует type checking; - Node/Bun CLI run гарантирует только runtime execution данного сценария. ## Обязательный toolchain contract 1. Все установки выполняются `npm ci`/`npm install`; изменение зависимостей — только npm. 2. Не запускать `bun install`, `bun add`, `bun remove`, `bun update` или `bun ci`. Эти команды выходят за runtime-only lane и могут создать `bun.lock`. 3. Source ограничен erasable TypeScript syntax: - type aliases/interfaces/type annotations допустимы; - enums, parameter properties, runtime namespaces и другие конструкции, требующие TypeScript transform, не используются; - type-only imports пишутся как `import type`. 4. ESM relative imports содержат расширение `.ts`. 5. Не использовать `tsconfig paths` как runtime resolution contract: Node игнорирует `tsconfig.json`. 6. Runtime code не обращается к `Bun.*`; общий слой использует проверенные `node:` APIs или platform-neutral ECMAScript. 7. Любой provider output проходит два независимых слоя: JSON Schema/Ajv, затем authoritative domain reducer. ## Архитектура и поток данных ```text package.json + package-lock.json | npm ci | root node_modules / \ tsc --noEmit runtime smoke strict / \ Node 24 Bun 1.3 \ / same .ts entry | package/lock invariant report ``` Для будущего game kernel: ```text provider structured output -> JSON parse/schema constraint -> Ajv 8.20.0 revalidation -> pure typed authoritative reducer -> append-only event -> narration/projection ``` XState, JSON rules, graph libraries, external event stores и managed eval platforms не входят в этот minimal runtime proof. ## Структура прототипа - `prototype/tsconfig.json` — strict NodeNext/erasable-syntax compiler gate. - `prototype/verify-toolchain.ts` — pure evaluator + CLI inspection root manifest/lock/runtime. - `prototype/verify-toolchain.test.ts` — acceptance и competing-lock regression cases. - `prototype/README.md` — краткий runnable contract. ## Требования Фактически проверенная конфигурация: - macOS 26.4, Apple arm64; - Node.js 24.14.0; - npm 11.9.0; - Bun 1.3.6 — только для optional smoke; - TypeScript 7.0.2 и `@types/node` 24.13.3; - Ajv 8.20.0 и fast-check 4.9.0 зафиксированы root lock, хотя metadata verifier намеренно не импортирует их; - внешние сервисы и secrets: none. Поддерживаемый вывод ограничен Node major 24 и измеренной Bun 1.3.6. Другие patch/minor версии требуют повторного запуска, а не предположения. ## Установка Из корня репозитория: ```bash npm ci ``` Не выполнять `bun install`: Bun использует уже установленный npm `node_modules` только во время runtime smoke. ## Запуск Основной runtime: ```bash node RnD/technical/2026-07-25-typescript-runtime-toolchain/prototype/verify-toolchain.ts --expect-runtime=node ``` Ожидается JSON с `"ok": true`, runtime `node`, Node major 24, npm `packageManager`, lockfile v3, совпадающими pins и отсутствующими Bun lockfiles. Optional Bun smoke: ```bash bun run RnD/technical/2026-07-25-typescript-runtime-toolchain/prototype/verify-toolchain.ts --expect-runtime=bun ``` ## Тестирование Из корня репозитория: ```bash ./node_modules/.bin/tsc -p RnD/technical/2026-07-25-typescript-runtime-toolchain/prototype/tsconfig.json node --test RnD/technical/2026-07-25-typescript-runtime-toolchain/prototype/verify-toolchain.test.ts bun test RnD/technical/2026-07-25-typescript-runtime-toolchain/prototype/verify-toolchain.test.ts ``` Full repository check: ```bash npm run check npm run check:bun # или оба последовательно npm run check:all ``` Фактический результат общего gate записан в `VALIDATION.md`. ## Конфигурация Environment variables отсутствуют. CLI принимает один необязательный параметр: - `--expect-runtime=node` - `--expect-runtime=bun` Без параметра verifier ожидает фактически обнаруженный runtime. Pinned baseline находится в `EXPECTED_PACKAGE_MANAGER` и `EXPECTED_PACKAGES`. Его изменение должно идти вместе с root manifest/lock, документацией и повторной валидацией. ## Ограничения и безопасность - Verifier только читает local JSON и проверяет наличие lockfiles; он не изменяет package metadata и не запускает installers. - Никакие API keys не читаются, сетевые запросы и LLM calls не выполняются. - `JSON.parse` обёрнут object-boundary check, но это исследовательский metadata reader, не универсальный untrusted-file parser. - Пройденный Bun smoke не доказывает совместимость native addons, filesystem edge cases, workers, streams или будущих provider SDK. - Provider schema-constrained output нельзя сразу commit-ить в game state: schema проверяет shape, domain reducer — допустимость действия. ## Условия переноса в production - Выполнить `npm ci && npm run check` на clean Linux CI. - Добавить Bun smoke только на реальные public entry points. - Зафиксировать Node patch через deployment image/version manager. - Ввести dependency compatibility inventory до обещания Bun support. - Для event store определить idempotency, optimistic concurrency, backup, migration и replay SLO. - Для LLM выбрать provider/data policy, затем провести versioned, budget-capped eval с raw usage и cache counters. - Подключить OpenTelemetry/exporter только когда появится multi-process trace path; не добавлять SDK ради неиспользуемой абстракции.