docs: describe installation recovery and coordinated proof rollout

This commit is contained in:
Codex
2026-09-09 18:59:21 +03:00
parent 189068be63
commit 7c0eb20894
5 changed files with 154 additions and 15 deletions
+22
View File
@@ -90,3 +90,25 @@ URL — cannot redirect a download to an attacker-controlled host in any of
these domains. When adding a new game-related download, verify its host is
one of the ones above (or add a new hardcoded constant following the same
pattern) rather than accepting a URL from anywhere else.
## Generated NeoForge artifacts and Java selection
NeoForge 21.1.248's actual installer does not publish processor-output hashes.
The launcher therefore validates the installer SHA-256, extracts its expected
version JSON and a scoped processor recipe, verifies the vanilla input against
Mojang, and runs that installer in a fresh staging tree. Generated JARs must
be readable ZIPs with valid entries. A receipt commits the generated hashes,
installer digest and recipe identity only after successful verified promotion.
This is provenance from a trusted computation, not independent publisher
checksums for generated files. Later corruption invalidates the receipt and
triggers clean reconstruction; a nonempty old file is never enough. Interrupted
promotion has no valid receipt and is repaired on the next preparation.
Only recipe-scoped generated artifacts are promoted; user profile files are
outside this tree. Staging can remain after an abrupt kill and is never trusted
as an installation. The receipt currently lives under the shared game cache.
Java discovery evaluates JAVA_HOME and PATH candidates independently for the
exact required major. A wrong-major JAVA_HOME no longer hides a valid PATH
installation. Only if no matching candidate exists is a managed runtime
provisioned. The UI reads required versions from verified profile metadata.
+94 -4
View File
@@ -6,7 +6,7 @@ The launcher persists local settings, synchronises Aeronautics mod/config
files from the signed ShaCraft v2 manifest, installs the exact Minecraft +
NeoForge version the manifest specifies, and launches the game. A player
signs in with the same local ShaCraft account used on the website. The game
identity is derived only from that account's verified Aeronautics nickname;
identity for ordinary Play is derived only from that account's verified Aeronautics nickname;
the legacy editable nickname setting is not trusted at launch.
The interface also shows a live Aeronautics player count from the fixed,
@@ -19,13 +19,16 @@ launcher itself. Do not represent these as completed in UI or release notes.
## Data flow
Two independent pipelines feed one launch:
One verified ShaCraft snapshot is fetched inside the installation lock for
each Play/Repair operation. Every stage, the displayed completion metadata and
the spawn use that snapshot; a newly published manifest is used next time.
Two independent trust pipelines feed one launch:
```text
ShaCraft manifest (mods/config + which MC/loader/Java version to use)
signed-manifest endpoint -> Ed25519 verification (remote.rs)
-> manifest schema + URL/path validation (manifest.rs)
-> temporary download, SHA-256 verification, atomic replacement (profile.rs)
-> inventory reconciliation, verified staging, durable apply journal (profile.rs)
Game itself (never controlled by the manifest above)
Mojang version manifest -> SHA-1-verified version JSON (mojang.rs)
@@ -88,7 +91,10 @@ Browser preview cannot install/launch and does not simulate download progress.
Rust `lib.rs` registers commands from `commands/`. Installation and account
permits in `operations.rs` stay owned by blocking workers until completion.
ShaCraft sessions have a separate gate from the retained Microsoft module.
These are process-local guards, not cross-process locks or cancellation.
An additional OS file lock in `installation_lock.rs` covers all profiles and
the shared game installation across processes. It remains held by the child
watcher; a durable PID/start-time lease also protects a game that outlives its
launcher. This is exclusion, not cancellation.
`storage.rs` provides unique temporary files and atomic replacement; Unix
session files are created owner-only. Windows keeps a recoverable replacement
fallback if the OS refuses direct replacement. `trusted_http.rs` constrains provider
@@ -105,3 +111,87 @@ The package workflow runs on main pushes or manually and builds Windows
x64, Linux x64 and both macOS architectures with named artifacts.
Packages are not yet signed release artifacts. Native cold-install and
launch tests are required before calling a platform release-ready.
## Reconciliation and recovery
`profiles/.<profile-id>.shacraft-state/` is outside the payload root. It stores
`inventory.json`, `pending.json`, transaction staging/backups/receipts and
explicit legacy-mod backups. The inventory records only files the launcher
actually wrote, with size/hash/policy and signed snapshot digest. An existing
file that already matches is usable, but is not silently claimed as owned.
Seed files are never owned for later removal.
All required downloads are staged and verified before apply. A write-ahead
journal records old/new states. Interrupted apply resumes by checking hashes;
readiness stays false while a journal, stale owned files or conflicts remain.
Old owned files are moved to a backup only when their current contents still
match the recorded version. Changed files remain conflicts; unrelated files
and player worlds, screenshots, options and resourcepacks are preserved.
A manifest is not authority to overwrite an unknown colliding local file.
“Разобрать моды” lists legacy/changed JAR candidates without selecting any.
The user explicitly chooses paths; native code rechecks each selected hash
and safe path before moving it to a recoverable backup with a receipt. Unknown
extra mods are informational, not automatically removed or adopted. Readiness
means the declared pack files were checked; it does not certify arbitrary
additional user mods. Afterwards rerun Repair or Play.
`game/cache/neoforge-receipts/<version>.json` records provenance for generated
NeoForge outputs. The verified installer recipe and its embedded version JSON
scope which files can be rebuilt. Missing/invalid receipts, corrupt JSON or a
mismatched generated JAR cause a clean isolated rebuild. No local legacy hash
is accepted as the first baseline. See `game-trust-boundary.md`.
## First entry and account proof v1
The account settings offer “Установить и войти для подтверждения” separately
from ordinary Play. The launcher prepares the exact signed pack first, then
requests and validates an authenticated grant at the fixed ShaCraft origin:
`POST /api/launcher/onboarding/start` and `/validate`. It requires an approved
managed `mods/shacraft-game-bridge-*.jar` entry in that signed snapshot. Until
that payload and server bridge are deployed, this action fails with an explicit
message; ordinary linked Play keeps its existing account gate.
The grant binds account, `aoc`, exact nickname/offline UUID, challenge and TTL
(10 minutes). Only the game child gets `SHACRAFT_ONBOARDING_TOKEN` in its
environment; normal launches remove inherited tokens. The frontend receives
only the explicit proof challenge. The client bridge sends the token once to
the fixed Aeronautics socket. The server bridge holds that connection until
LoginSystem succeeds and the player enters `/shacraft link <id> <code>`.
The bridge uses a server-only bearer secret for fixed HTTPS callbacks. A grant
is not a whitelist grant, password replacement or completed web link.
New nicknames keep the established operator-whitelist → first `/register`
policy; registered names must use their existing `/login` password. Prism can
still perform the explicit proof command without a launcher grant. Existing
account links stay valid with legacy provenance and optional re-verification;
no bulk revocation occurs. GET link status is read-only. Backend implementation,
migrations, game adapter and rollout procedure are in the companion server
repository, `docs/account-proof-v1.md` and `docs/access-delivery.md`.
## Interrupted spawn recovery
`installation-state/writer.lock` is an OS lock file, not a stale-lock sentinel;
never delete it while any launcher/game is running. `game-lease.json` records
`Starting` before spawn and `Running` with PID/start time before releasing the
worker. A known exited child is cleared automatically. A crash in the narrow
spawn/record interval or malformed lease fails closed because the child cannot
be proven absent.
For that explicit error only: close all ShaCraft Launcher and Minecraft
processes (or reboot), verify none remain, and rename `game-lease.json` to a
backup outside `installation-state`. Then open one launcher and run Repair.
Do not remove game/profile trees or an active lock file as a recovery shortcut.
The application data root is shown in settings; it is not system `.minecraft`.
## Local live preparation check
`cargo test --locked --manifest-path src-tauri/Cargo.toml
commands::game::tests::live_cold_install_and_corruption_repair -- --ignored --nocapture`
uses a fresh temporary application directory, real signed/provider downloads
and the official installer. It corrupts generated NeoForge JSON/JAR, repairs
both and repeats a healthy check. It never logs into a game server. It requires
network access and sufficient disk space; the printed directory is retained
for diagnosis. This does not replace Tauri IPC, graphical gameplay or the
client/server proof matrix on each supported OS.