# Archiving packed-only startup evidence `tools/archive_packed.py` archives a **stopped packed-Core ordinary startup session** separately from source-based Workbench evidence. It performs no native launch, process operation, package build, publication or acceptance-ledger update. Existing `archive_native.py` behavior is unchanged. ```sh python3 tools/archive_packed.py \ /tmp/erri-packed-core-20260919-1102 \ packed-core-2026-09-19-1102 ``` The first argument is the packed session root, not its nested native log directory. The second is a new, single ASCII filename component under this repository's `docs/evidence`; traversal, symlink redirects and overwrites are refused. Use the actual repository's tool when archiving into actual repository evidence; the staged tool writes only staged evidence. The command does not commit or force-add files itself. ## What is checked Before creating the destination, the helper requires the original packed provenance schema, Core identity and three-artifact hash inventory. Runtime `.gproj`, `.pak` and `.rdb` bytes must still match the prelaunch manifest exactly. The root and native-session copies of provenance, runner report and raw startup report must agree. Snapshot/start/stop chronology, launch ID, manifest hash and exact sealed console hash must validate. Confirmed owned cleanup is required; active/unsealed sessions are refused. Missing or replaced package bytes cannot be reconstructed from today's sources and therefore cause refusal. The recorded native command is reconstructed and compared against the packed-only ordinary Core command: installed regular executable and Proton, hidden display, private copied addon directory and profile, Core GUID, explicit ordinary launcher/noSplash and existing nonbackend/muted diagnostic flags. Unexpected flags, loose-source paths or an external native log directory are refused. No source-launch manifest is accepted as substitute provenance. The helper independently calls `packed_evidence` on the sealed raw console using **recorded** runtime/profile/Steam paths, so loaded identities, PAK mounts, resource database, ordinary GameLib/Game defines, authored header, real participant and PRISON readiness are checked again. It does not trust a saved `ready` flag. Auxiliary script/error/crash/launcher logs are also retained and checked for actual error/fatal or runtime-failure patterns; warnings in `error.log` do not become invented errors. Success additionally requires the sealed runner's `packed-core-started` result, unchanged-input flag, clean polling latch, consumption flag, no input error and at least 15 seconds between start and stop. **The full continuous 15-second polling history was not recorded by the runner.** The archive independently recomputes native readiness but relies on the sealed runner verdict for continuous settling; it explicitly records this limit. A future parser correction cannot turn the first run's latched monitor failure into a pass. Nor can a current successful raw-log parse erase a failed runner result, package mutation, incomplete readiness or auxiliary error. The native alias `$profile:../addons/` is recognized only in addon-search-directory records and only as the recorded CLI profile's `addons` directory, consistent with the observed native `$profile:` mapping to `/profile`. Unknown aliases and traversal variants remain unresolved and fail. This correction leaves the earlier raw failure report intact. ## Files and exit status The new archive contains: - `package/addon.gproj`, `package/data.pak`, `package/resourceDatabase.rdb`: byte-identical original runtime artifacts, rechecked after writing. - `packed-input-provenance.json`, `runner.json.txt`, `raw-startup-report.json` and exact `console.log.txt`, plus available auxiliary raw logs. - `report.json`: independently recomputed result, original runner failure latch, explicit qualification limits and hashes of the verifier implementations. - `archive-kind.json`: distinct `packed-core-consumption` identity with build/release qualification false. - `archive-sha256.json`: hashes of every preceding archived file, including the PAK and reports. A valid failed run is preserved and exits **1**. A verified packed startup exits **0**. Invalid provenance, unconfirmed cleanup, changed runtime bytes, unsafe paths or an existing destination are refused before creating the destination and exit through argparse. The tool never deletes or overwrites a prior archive. An I/O error during destination writing can leave a partial new directory; preserve that diagnosis and choose a new name after resolving the error. The repository ignores generated PAK/RDB files globally. When intentionally committing this evidence, explicitly include these **successor-owned** archived artifacts with `git add -f` using their exact archive paths, after normal review. The archiver neither stages files nor copies installed vanilla packages. Do not use the source archiver's legacy override or create `source-sha256.json` from the current checkout: that would misidentify the runtime payload. A packed startup pass still does not qualify the build process, visible splash/UI/input, complete escape, multiplayer, performance, publication or current-source release. Packaging attempts and current acceptance remain separate. Keep the original packaging report and any native shutdown errors as their own evidence. ## Integration checks New files: `tools/archive_packed.py`, `tests/test_archive_packed.py`, this document. Add `test_archive_packed.py` to `tools/check.py`'s explicit test list. `python3 tests/test_archive_packed.py` exercises 17 archive-specific checks: exact-byte preservation, successful/failed verdicts, parser corrections retaining failure latches, native and auxiliary errors, forged ready reports, incomplete settling, mutated input/console, mismatched duplicate evidence, malformed metadata/commands, unsafe paths, cleanup and source-relabel refusals, no overwrite and symlink handling. These tests use temporary fixtures and never start an engine.