Files

13 KiB

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:

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:

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 passes with the exact fifteen runtime artifacts from five-addon packaging 111731. 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.

Current packed Chat refresh

Packed Chat 131942 consumes the fifteen exact 1317 artifacts, whose 151 PAK entries match the current 183 authored addon files. All five successor and two vanilla addons load without loose successor source, the regular Game module admits a real canonical prisoner, and the fifteen-second ready interval completes without captured errors. Input hashes remain unchanged and owned cleanup is confirmed. The package build verdict remains failed because of its retained UI shutdown errors. This evidence establishes ordinary startup only.