Files
EscapistsReintroduced/docs/packed-core-startup.md
T

82 lines
12 KiB
Markdown

# Packed-only Core ordinary startup
`tools/headless_game.py --packed-core ... --packed-session ... --project core` is an explicit, bounded consumption test for an **unqualified** native Core package candidate. It uses the installed regular `ArmaReforgerSteam.exe`, the existing private prefix lock, a headless Gamescope display and only its own muted audio sink. It never launches Workbench, modifies the candidate, loads a loose successor project, changes the original Escapists missions or publishes anything.
This runner extension has passed source/unit checks; it has not yet launched the native packed test. A native package file's existence is not consumption evidence. The 2026-09-19 10:46 package attempt's shutdown/resource errors remain failed build evidence even if these bytes later run successfully.
## Explicit invocation
Choose a nonexistent direct `/tmp` child with the required prefix:
```sh
python3 tools/headless_game.py --project core \
--packed-core /tmp/erri-native-package-core-20260919-1046/packages/core \
--packed-session /tmp/erri-packed-core-NEW \
--compat /tmp/erri-headless-compat --timeout 180
```
The runner requires exactly 15 seconds of continuous readiness (`--settle 15`, the default), refuses another settle value, and uses its existing bounded timeout/error-latching rules. Existing game/prefix process refusals and `.erri-workbench.lock` ownership remain unchanged. Do not pass `--profile`: this case owns a fresh `--packed-session/profile`. Reusing any session, including a failed one, is refused. Ordinary Core/Chat and vanilla-control invocations without these flags retain their existing commands, profiles and evidence format.
Preflight requires a canonical, nonsymlink candidate directory containing exactly three nonempty regular files: `addon.gproj`, `data.pak`, `resourceDatabase.rdb`. The project must identify `ERR_Core` / `2528466DE220D91C`, with only vanilla `58D0FB3206B6F859` as its dependency. Extra files, directories, symlinks or changed identity fail. The strict project parser deliberately accepts the packer's existing simple project format, rather than trying to understand arbitrary project extensions.
Under the existing prefix lock, the runner creates a byte-identical **copy**, not a link, at `session/input/addons/core`. Candidate and copy hashes must agree before launch and after cleanup. No source scripts, companion addons, build cache or packaging source directories are copied. The profile's only addon link is the existing read-only installed vanilla discovery link. The actual CLI selects `-addonsDir Z:<session>/input/addons -addons 2528466DE220D91C`, plus the existing ordinary flags; it never references the source repository in its addon search paths.
The package itself must supply the existing ordinary scenario launcher, explicit diagnostic `noSplash` behavior and normal single-player admission. No loose helper is injected. Read-only inspection found those scripts and the scenario/world in the current candidate PAK; its three helper script payloads match the packaging snapshot. This does not establish native compilation or startup. Explicit noSplash does not qualify the ordinary visible splash path, and the local-round roster key does not qualify remote authentication.
## Native evidence and provenance
Readiness requires the same Core header/systems, real local participant and PRISON transition as the ordinary runner, plus:
- Native GameLib and Game modules without WORKBENCH/ENF_WB and no smoke fixture execution.
- The latest native `Loaded addons` block contains exactly engine Core (`5614BBCCBB55ED1C`), installed ArmaReforger and successor Core. Every observed loaded entry must use its expected installed or private-copy `.gproj` path, without duplicates or foreign identities.
- Native package mounts for both installed vanilla projects and exactly one PAK at the private Core copy. A loose `ERR_*` directory mount or any unexpected package mount fails.
- Core's native resource database path points to that same private copy. Logged addon search directories are limited to the private input parent, installed game addons and private profile addons.
- All raw engine/script failures remain failures and stay latched even if a later poll appears ready. Changed/deleted package inputs or unconfirmed cleanup prevent consumption success.
Path matching normalizes native `Z:`/backslash spellings and trailing separators without accepting a different path. Missing evidence never becomes a pass. Initial/incomplete log output can remain pending; actual foreign paths or errors fail immediately under the ordinary failure policy. `--failure-grace` remains a bounded diagnostic drain and never turns a failed run into success.
The fresh session contains `packed-input-provenance.json` captured before launch, the exact copied runtime payload, `packed-runner.json` and `packed-startup-report.json`. The provenance records candidate/copy paths, command, timestamp, launch ID, file sizes and SHA-256 for **all three** files. Native log sessions receive the identical manifest bytes, runner/startup reports and launcher output. After cleanup, the report binds the exact console hash, manifest hash, unchanged candidate/copy result and `packed_launch_id`.
The dedicated verdict is `packed-core-started`, with `packed_only=true` and `packed_consumption_verified=true` only for a clean, settled, path-verified run with confirmed cleanup and unchanged inputs. `build_qualified` and `release_qualified` remain false. The existing source manifest excludes PAK/RDB files; packed mode therefore does **not** emit `launch-source-*` files or source-provenance claims. It must not be presented as a current source build qualification.
## Integration and archival
Files owned by this change are `tools/headless_game.py`, `tests/test_packed_core_game.py` and this document. Add `test_packed_core_game.py` to the explicit `tools/check.py` test list when integrating. Run it directly with `python3 tests/test_packed_core_game.py`; it covers exact payload validation, private copying, command separation, native path/module/error gates, input hash mutation, 15-second settling, latched errors and a mocked failed launch retaining evidence without source provenance. Existing ordinary and vanilla runner suites must also remain green.
Keep the entire fresh packed session, including `input`, the provenance JSON and raw `profile/logs` directory. The existing `archive_native.py` expects source-launch provenance and is intentionally **not** taught to relabel this packed run. Do not use its legacy override: that would attach unrelated loose source hashes. A later packed-aware archive integration must preserve these artifact hashes and copied bytes, independently recheck native path/readiness evidence, and retain the separate packaging attempt verdict. Until then, link the private complete session as diagnostic evidence; do not add a passed release-ledger entry.
## Complete packed Chat closure
The separate explicit `--packed-addons` option accepts the parent directory containing exactly `core`, `ai`, `intel`, `map` and `chat`. It is mutually exclusive with `--packed-core`, requires `--project chat`, and owns a new canonical `/tmp/erri-packed-chat-<name>` session. For an unqualified diagnostic candidate already produced by the packaging runner:
```sh
python3 tools/headless_game.py --project chat \
--packed-addons /tmp/erri-native-package-all-20260919-1115/packages \
--packed-session /tmp/erri-packed-chat-NEW \
--compat /tmp/erri-headless-compat --timeout 180
```
Each of the five directories must contain exactly three nonempty regular files (`addon.gproj`, `data.pak`, `resourceDatabase.rdb`), with no symlinks, additional directories or loose scripts. The strict project parser requires the following identities and the exact dependency sets, rejecting missing, foreign and duplicate dependency declarations:
| Folder | Project ID | GUID | Successor dependencies, in addition to vanilla `58D0FB3206B6F859` |
| --- | --- | --- | --- |
| core | ERR_Core | 2528466DE220D91C | none |
| ai | ERR_Ai | 5192138CB9D5B911 | Core |
| intel | ERR_Intel | D31039C7C53E348A | Core |
| map | ERR_Map | 9AAEE9041D79809E | Core |
| chat | ERR_Chat | FA804F411BDDF2C6 | Core, AI, Intel, Map |
Under the existing prefix lock, all fifteen files are copied independently into `session/input/addons/<folder>`. The ordinary command selects only that parent addon directory and Chat GUID `FA804F411BDDF2C6`, and requests the existing packaged Chat scenario launcher. No source-based helper, original mod or loose dependency is inserted. The same profile isolation, muted hidden display, process ownership, 15-second readiness settling, raw error latch and cleanup rules apply. Reading the existing candidate with the new preflight found exactly fifteen valid artifacts totaling 292,361 bytes; that read-only inventory is not a native launch or package-consumption result.
Readiness additionally requires the actual Chat header and local participant, exactly seven loaded addon identities (the two installed vanilla projects plus all five successors), all five private successor PAK mounts with count one, and every successor's resource database loaded from its matching private folder. Missing evidence remains pending; redirected, duplicate or foreign loaded identities, wrong mounts, loose successor directory mounts, extra addon search paths, foreign databases, native errors, or WORKBENCH definitions fail. A later correct loaded block cannot erase a previous contradictory entry. The ordinary build/phase markers alone cannot qualify the closure.
Chat provenance uses **schema version 2**, kind `packed-chat-runtime-input`, `project: "chat"`, and `addon_order: ["core", "ai", "intel", "map", "chat"]`. `candidate_directory` and `runtime_directory` point to the respective five-folder parents. `artifacts` is an exact flat fifteen-entry map keyed by `core/addon.gproj`, `core/data.pak`, `core/resourceDatabase.rdb`, and the corresponding three paths for each companion. Every entry records bytes and SHA-256; candidate and copied payload are verified before launch and after cleanup. The manifest filename and seal/console bindings remain `packed-input-provenance.json` and the existing `packed_*` fields.
Existing `--packed-core` calls and Core's **schema version 1** / `packed-core-runtime-input` manifest retain their original three-entry map and fields. Default helper calls still mean Core; `packed_payload_inventory(folder, project="chat")` explicitly validates a complete Chat closure. A clean, settled Chat run would return `packed-chat-started` and set `packed_consumption_verified=true`, while retaining `build_qualified=false` and `release_qualified=false`. These flags do not forgive packaging errors, establish current source parity, or qualify full gameplay, multiplayer or performance.
The packed-aware `tools/archive_packed.py` integration preserves these separate artifact-based schemas; source-based `archive_native.py` and legacy overrides remain inappropriate for packed runs. The new offline `tests/test_packed_chat_game.py` covers the exact closure, identities/dependencies, safe copy/provenance, mutation of every one of the fifteen files, command separation, seven-addon/five-PAK/five-database evidence, raw failures and a mocked launch failure retaining artifact evidence. It must run alongside the existing Core, ordinary-game, vanilla-control and packed archive regressions. No native Chat consumption claim is made by these synthetic tests.
## Native packed Chat consumption
The [113315 ordinary run](evidence/packed-chat-2026-09-19-113315/report.json) passes with the exact fifteen runtime artifacts from [five-addon packaging 111731](native-companion-packaging.md). Loaded-addon, package-mount and resource-database paths identify only all five successor addons and installed vanilla, with no loose successor source. The native Game modules compile without Workbench, the scenario creates a real canonical prisoner and the 15-second ready interval completes with zero captured errors. All input hashes remain unchanged; owned cleanup is confirmed. The archive retains all fifteen artifact bytes and separate v2 packed provenance. This successful consumption check does not erase the packaging UI errors, qualify current later source changes, or establish manual play, multiplayer or release readiness.