first cycle lab release

This commit is contained in:
2026-10-04 00:30:09 +07:00
parent 85f6897365
commit d134daafd8
92 changed files with 5623 additions and 9 deletions
+237
View File
@@ -0,0 +1,237 @@
# Phase 0 — integration spike
Дата: 2026-10-03. Статус: **предварительный Fabric-эксперимент проверен; целевой Phase 0 должен проверить NeoForge/Forge без аккаунтов**.
GUI-проверки не заменяются проверкой ZIP или Minecraft status query.
## Окружение и версии
Arch Linux x86_64 в WSL2, kernel `6.18.40.1-microsoft-standard-WSL2`.
Изначально отсутствовали Linux packwiz, Docker, Compose, Go и Java.
В Windows обнаружен каталог PrismLauncher; аккаунты и существующие instances
не читались и не изменялись.
| Компонент | Зафиксированное значение |
| --- | --- |
| Minecraft | 1.21.1 |
| Fabric Loader | 0.19.5 |
| Fabric installer/launcher | 1.1.2, наблюдаемое значение в .fabric-manifest.json |
| Fabric API | 0.116.17+1.21.1, Modrinth `Mys3P7lK`, both |
| Mod Menu | 11.0.5, Modrinth `6lgOkclV`, client |
| Text Placeholder API | 2.4.2+1.21, Modrinth `U5bhVym2`, client в этой сборке |
| packwiz commit | `ef87d964f8cbd52b3b13ea42453ef322290e2b9e` |
| packwiz GitHub Actions run | `34043101039`, Linux 64-bit x86 |
| packwiz binary SHA-256 | `7f8ed641be0c28988895651e3270cc9ad4b40c436e3d5cf9b3bcdb718b4369c6` |
| Prism Launcher | 11.0.3-main, commit d393323fdc52ef645c48a04ca73aff2bbe24ffc9 (из локального лога) |
| JVM сервера | Temurin 21.0.12.1+1-LTS |
| Docker Engine | 29.8.2, storage driver overlayfs |
| Compose | v5.6.0, локальный официальный binary |
| itzg image digest | `sha256:99dc8b37f97c3b95915452180bbedf29a7ac8252932e372ce6e5b6e383a5d1e2` |
| itzg source revision | `beed693663b4c963d1bb4af1101855eccbc6a37b` |
| itzg image creation | 2026-10-02T12:03:38.864Z |
Образ первоначально скачан по тегу java21; Compose использует только digest.
JVM проверена без запуска Minecraft: Temurin OpenJDK 21.0.12.1+1-LTS.
Команда: `docker run --rm --entrypoint java <закреплённый-image> -version`.
## Фактически выполнено
1. Получены точные версии из официальных GitHub, Fabric и Modrinth API.
2. Скачан официальный packwiz из привязанного к commit workflow run;
SHA-256 архива и binary закреплены в `toolchain.lock.env`.
3. Установлен Docker в WSL (`pacman -S --needed --noconfirm docker`),
daemon запущен командой `systemctl start docker`, без enable при загрузке.
4. Скачан и проверен SHA-256 официального Compose v5.6.0 в `.tools/`.
5. Создан source pack и добавлены закреплённые моды через packwiz.
6. Для Text Placeholder API сторона явно изменена с both на client:
здесь библиотека нужна только client-only Mod Menu.
7. Обновлён source index, выполнен export в временной копии source.
8. Проверены содержимое ZIP, версии dependencies и env каждой записи.
9. `scripts/spike-server.sh config --quiet` и `bash -n scripts/*.sh` успешны.
10. После явного принятия EULA пользователем выставлен MC_EULA=TRUE в игнорируемом server/.env.
11. Первый запуск, status healthcheck, side filtering и bind mounts проверены на реальном сервере.
12. Проверены recreate, смена версии мода, удаление модов, конфиги и datapack на существующем мире.
13. Startup с отсутствующим mrpack вернул 1; hash level.dat при ошибке не изменился.
14. Исходный snapshot восстановлен в отдельный каталог; world/config совпали до запуска, сервер 0.0.1 снова healthy.
15. `git diff --check` успешен; .tools, артефакты, world, backups и .env игнорируются Git.
Артефакт:
```text
dist/minecraft-lab-spike-0.0.1/minecraft-lab-spike-0.0.1.mrpack
SHA-256: 923fa6e5b54921b7b19925bbe634d91e09b113ccd512f1edaaeab818de3a9338
```
ZIP содержит `modrinth.index.json` и `overrides/config/spike-marker.txt`.
Fabric API помечен required на обеих сторонах; Mod Menu и Text Placeholder API
имеют `server: unsupported`. На установленном сервере подтверждено отсутствие обоих client-only JAR.
Маркер проверяет копирование произвольного конфига; его не читает игровой мод.
## Команды создания и воспроизведения
Первоначальный init из `pack/`:
```bash
../.tools/packwiz/packwiz --cache ../.tools/packwiz/cache --config ../.tools/packwiz/config.toml init \
--name minecraft-lab-spike --version 0.0.1 --author minecraft-lab \
--mc-version 1.21.1 --modloader fabric --fabric-version 0.19.5 -y
../.tools/packwiz/packwiz --cache ../.tools/packwiz/cache --config ../.tools/packwiz/config.toml modrinth add --project-id P7dR8mSH --version-id Mys3P7lK -y
../.tools/packwiz/packwiz --cache ../.tools/packwiz/cache --config ../.tools/packwiz/config.toml modrinth add --project-id mOgUt4GM --version-id 6lgOkclV -y
# Явно изменить side в placeholder-api.pw.toml на client.
../.tools/packwiz/packwiz --cache ../.tools/packwiz/cache --config ../.tools/packwiz/config.toml refresh
```
В новом checkout достаточно уже закоммиченного source:
```bash
scripts/spike-tools.sh
scripts/spike-build.sh
scripts/spike-server.sh config --quiet
bsdtar -xOf dist/minecraft-lab-spike-0.0.1/minecraft-lab-spike-0.0.1.mrpack modrinth.index.json
```
Для изменения source packwiz запускается из `pack/` с локальными cache/config,
как в командах выше. Проверка SHA-256 артефакта выполняется из его каталога:
```bash
cd dist/minecraft-lab-spike-0.0.1
sha256sum -c SHA256SUMS
```
Build v0 не создаёт production release manifest, Git tags или удалённый deployment.
Игровые версии читаются из pack.toml; выбор MC_PACK — ссылка на готовый артефакт.
## Матрица проверки
| Проверка | Статус |
| --- | --- |
| packwiz описывает и экспортирует сборку | PASS |
| ZIP содержит закреплённые dependencies и side metadata | PASS |
| Compose config валиден | PASS |
| Prism импортирует и запускает pack | PASS: instance 0.0.1, Minecraft/Fabric и три JAR подтверждены |
| Сервер устанавливает локальный mrpack и становится healthy | PASS: mc-health, 1.21.1, online=0 |
| На сервере нет client-only JAR | PASS: только fabric-api JAR |
| World и config находятся в host bind mount | PASS |
| World переживает recreation контейнера | PASS: level.dat hash до запуска совпал |
| Обновление удаляет старый mod JAR | PASS: 0.116.17 → 0.116.16; затем удалены все JAR |
| Конфиги: pack defaults, server override, ручная правка | PASS: override победил; update перезаписал ручную правку |
| Backup/restore возвращает world и прежний release | PASS: восстановлен baseline и pack 0.0.1 |
| Startup failure возвращает non-zero | PASS: отсутствующий mrpack, exit 1; world не изменён |
| Клиент Prism подключается к offline-серверу | PENDING: повторная попытка после online-mode=false |
| Datapack на существующем мире | PASS: file/phase0 автоматически загружен в 0.0.2 |
| NeoForge/Forge defaultconfigs | НЕ ПРОВЕРЕНО: другой loader |
## Порядок серверных проверок
После принятия EULA скопировать `.env.example` в `.env` и выставить MC_EULA=TRUE.
Сервер изолирован локальным адресом, без публикации RCON. Первоначально ошибочно требовался online-mode=true; по уточнению пользователя переключён на online-mode=false и enforce-secure-profile=false. Microsoft/Mojang-аккаунт не требуется.
```bash
scripts/spike-server.sh up -d --wait --wait-timeout 600
scripts/spike-server.sh ps
scripts/spike-server.sh logs --tail 100
scripts/spike-server.sh exec -T minecraft java -version
scripts/spike-server.sh exec -T minecraft mc-health
ls runtime/mods runtime/config runtime/world
```
Затем остановить сервер и записать hash `runtime/world/level.dat`.
Recreate выполняется при остановленном сервере:
```bash
scripts/spike-server.sh stop
sha256sum runtime/world/level.dat
scripts/spike-server.sh create --force-recreate
sha256sum runtime/world/level.dat
scripts/spike-server.sh start
```
Два hash до запуска должны совпасть. После старта world может штатно измениться;
это не потеря данных. Дополнительно проверить UUID/seed и игровой маркер из клиента.
Для воспроизведения вариантов на новом checkout после исходного build выполнить `scripts/spike-variants.sh`. Скрипт создаёт source-копии в .tools/repro-variants и артефакты 0.0.2/0.0.3; runtime не меняет. Повторный запуск при существующих каталогах прекращается без перезаписи.
0.0.2: Fabric API fpB2VatZ (0.116.16+1.21.1), marker v2, статический datapack из testdata/spike-datapack. 0.0.3: удалены Mod Menu, Text Placeholder API и Fabric API, остаётся loader и config marker. Исходный pack/ всё время оставался на 0.0.1.
Перед сменой MC_PACK обязательно остановить сервер и создать snapshot.
Проверить удаление прежнего JAR и фактическое состояние marker.
Возврат старого pack выполнять вместе с соответствующим snapshot.
Минимальная ручная процедура backup (в корне, после stop):
```bash
mkdir -p backups
task_snapshot="backups/$(date -u +%Y%m%dT%H%M%SZ)-$(date +%s%N).tar.zst"
tar --exclude=./.gitkeep -C runtime -I zstd -cf "$task_snapshot" .
tar -I zstd -tf "$task_snapshot" > /dev/null
sha256sum "$task_snapshot" > "$task_snapshot.sha256"
# Записать рядом исходный MC_PACK и SHA256SUMS релиза.
```
Restore: сервер остановлен; сначала сохранить текущее состояние. Проверить hash
архива, распаковать в новый каталог рядом с runtime и проверить файлы.
Переименовать текущий runtime в сохранённый каталог, новый — в runtime;
выбрать исходный MC_PACK и запустить с healthcheck. Не распаковывать поверх мира.
Этот ручной сценарий проверен: snapshot phase0-before-update восстановлен в отдельный каталог, исходный runtime сохранён в .tools/runtime-before-restore, затем запущен pack 0.0.1.
Prism: импортировать исходный .mrpack, запустить Minecraft, проверить Mod Menu,
зайти на localhost:25565, поставить различимый игровой маркер и проверить его
после recreation. Записать версию Prism, JVM клиента и фактический результат.
## Фактические результаты переходов
- Первый запуск: Minecraft 1.21.1, Fabric 0.19.5, JVM Temurin 21.0.12.1+1; mc-health отвечает version=1.21.1 online=0 max=20.
- Docker inspect: /data — rw bind на runtime/, /modpacks — ro bind на dist/. Named volumes отсутствуют.
- Recreate: до повторного запуска SHA-256 level.dat остался `32832255e84e2d8b4e324527d21b233b0b0cc4615ae17ee0296e7e8c5d4d9728`.
- Update 0.0.1 → 0.0.2: только fabric-api-0.116.16+1.21.1.jar, старый 0.116.17 удалён; manual-runtime-v1 заменён на pack-default-v2.
- Datapack: лог «Found new data pack file/phase0, loading it automatically», затем «[Phase0] datapack-v2-loaded».
- Optional override: `MC_PACK=minecraft-lab-spike-0.0.2/minecraft-lab-spike-0.0.2.mrpack scripts/spike-server.sh -f server/compose.spike-override.yaml up -d --wait --wait-timeout 120`; marker стал server-override-v1.
- Update → 0.0.3 без override: runtime/mods пуст, управляемые файлы прежнего datapack удалены, unmanaged-probe.txt сохранился.
- Failure: MC_PACK=missing-phase0.mrpack, Compose --wait вернул 1; контейнер exited(1), hash мира остался прежним.
- Restore: sha256sum snapshot проверен, распаковка в .tools/runtime-restored, сравнение world/config с baseline успешно; прежний runtime сохранён, восстановленный переименован в runtime. После запуска исходного pack 0.0.1 сервер healthy.
Каждый изменяющий тест предварялся корректной остановкой и snapshot. Пять архивов в backups/ имеют SHA-256 и JSON metadata: исходный артефакт, image digest, server override и время; исключений нет. Имена phase0-* относятся к однократному запуску этого эксперимента. Для обычных backups использовать уникальные ID из примера выше.
Артефакты тестовых переходов (ZIP timestamps могут отличаться при повторном export):
| Релиз | SHA-256 |
| --- | --- |
| 0.0.2 | ca10d1faffa8a71ee58431f7f3f2ee88be4c7572e035cac8824331129b701fab |
| 0.0.3 | ced6fe830055ce3f0ae2d1c4c14e0fb41b5a8580bdaf5cac3010b0bdc8a9ceba |
Финальное состояние: сервер запущен с исходным pack 0.0.1 и восстановленным baseline, optional override выключен. Импорт и запуск Prism подтверждены локальными instance metadata и client log. Подключение не завершилось: Failed to log in: The authentication servers are currently not reachable. В client log sessionHost/servicesHost=https://nope.invalid и UnknownHostException: nope.invalid; launcher log содержит четыре -Dminecraft.api.*.host с этим адресом. В pack и instance/global JvmArgs такого override нет, переменные JAVA_TOOL_OPTIONS/JDK_JAVA_OPTIONS/_JAVA_OPTIONS Windows этих overrides не содержат. Для offline-клиента эти параметры не являются ошибкой настройки: изначальное требование online-mode=true противоречило цели пользователя. Требование аккаунта снято; нужен offline-server login. Account files и токены не читались.
## Обнаруженные ограничения и изменения архитектуры
- packwiz автоматически добавил Text Placeholder API и выставил both, хотя он
нужен этой сборке только на клиенте. Metadata проекта не заменяет проверку
конкретного состава зависимостей. Свой resolver не нужен.
- В Arch package index Compose 5.5.1 ссылался на отсутствующий файл (HTTP 404).
Не обновлялась вся система: Docker установлен отдельно, Compose скачан локально.
- В минимальном окружении отсутствует cmp; build сравнивает SHA-256 source и
refresh-копии вместо дополнительной системной зависимости.
- Network-вызовы sandbox требуют разрешения. Подстановка latest не используется
в воспроизводимых командах; закреплены результаты первоначального выбора.
- GitHub Actions artifacts имеют ограниченный срок хранения. Bootstrap по run ID
пригоден для spike, но не для долговременного release tooling. Для него нужен
build packwiz из закреплённого commit или сохранённый binary с checksum.
- Пакет содержит ссылки на Modrinth downloads, а не все JAR; offline install
не доказан. Образ также загружает Minecraft и loader при первом старте.
- Windows Test-NetConnection 127.0.0.1:25565 вернул TcpTestSucceeded=True после восстановления. GET sessionserver hasJoined без сессии возвращает 204 из Windows, WSL и контейнера; GET api.minecraftservices.com/publickeys возвращает 200 из Windows и контейнера. Эти пробы не передавали токены и не подтверждают login, но исключают общую недоступность этих endpoints.
- Минимальная сборка использует Fabric API, не добавляя новые блоки/предметы. Она доказывает установку loader и модов; сетевую совместимость content-модов понадобится проверить на реальной сборке.
- Fabric был неверно выбран вместо целевых NeoForge/Forge. Его результаты сохраняются только как предварительный эксперимент. Целевой Phase 0 ещё требует modpack на NeoForge/Forge, defaultconfigs и подключения offline-клиента.
- При смене mrpack управляемый config заменяется, включая ручную правку. Неуправляемый файл сохраняется. Требуется проверка drift в будущей платформе до применения пакета.
- Server override через /config с SYNC_SKIP_NEWER_IN_DESTINATION=false применяется после modpack defaults и побеждает их. Это намеренная политика теста, не универсальная политика production.
- Datapacks нужны в world/datapacks, а не в корневом /data/datapacks. В варианте 0.0.2 проверен путь overrides/world/datapacks/phase0. Это статические исходники datapack, не snapshot мира. Если сохранить предложенный pack/datapacks layout, нужен явный перенос в целевой world path; world name должен учитываться.
- Важное ограничение воспроизводимости: local mrpack закрепляет loader, но не версию Fabric installer/launcher. В runtime наблюдается 1.1.2. В закреплённом образе TYPE=MODRINTH вызывает install-modrinth-modpack напрямую, не передавая FABRIC_LAUNCHER_VERSION; в help этого helper нет соответствующего параметра. Поэтому простое добавление Fabric env в Compose не доказывает фиксацию installer. Перед production release нужно выбрать проверенный способ фиксировать/сохранять launcher или явно ограничить обещание воспроизводимости. Собственный mod resolver для этого не нужен.
- Production deployment и автоматический rollback остаются вне scope Phase 0.
Официальные источники:
- [packwiz installation](https://packwiz.infra.link/installation/)
- [packwiz Modrinth export](https://packwiz.infra.link/tutorials/hosting/modrinth/)
- [itzg local mrpack](https://docker-minecraft-server.readthedocs.io/en/latest/types-and-platforms/mod-platforms/modrinth-modpacks/)
- [itzg healthcheck](https://docker-minecraft-server.readthedocs.io/en/latest/misc/healthcheck/)
- [Modrinth format](https://support.modrinth.com/en/articles/8802351-modrinth-modpack-format-mrpack)
## Уточнение цели пользователем
Собирать пользовательские модпаки NeoForge/Forge, распространять клиентский артефакт и запускать сервер без проверки аккаунтов. ONLINE_MODE=false, ENFORCE_SECURE_PROFILE=false. Смена auth режима предварена backup phase0-before-offline-mode. Проверка Microsoft login не входит в acceptance criteria.