# Phase 0.8R offline remediation and evidence contract Decision: **READ_ONLY_PREFLIGHT_BLOCKED**. ## Scope Phase 0.8R is documentation, evidence-contract design, and host-only regression protection. It does not contact a PS5, observe hardware, implement a collector, build a target artifact, transfer a file, install a component, or execute code on a target. It grants no authority. `installation_authorized=false`, `lifecycle_authorized=false`, `execution_authorized=false`, `transfer_authorized=false`, and `automatic_retry=false`. The absolute read-only rule used by historical Phase 0.8 is unchanged. Possible future bounded observation would be a separate phase with a new name, effect budget, exact permission, and review. This document does not approve such a phase. ## Immutable historical identity The Phase-0.8 record is anchored to repository commit `2c944d6d65a08f7e1c02f518721cde061b999329`. | Immutable file | Role | SHA-256 | |---|---|---| | `docs/runtime/phase-0.8-read-only-preflight.md` | human-readable historical record | `3fbe086175a6048176075f447ec1482074928e3b5282db97ea2169395fe1d508` | | `manifests/runtime/phase-0.8-read-only-preflight.json` | machine-readable historical record | `47d7f452f8799979fe99b3e6d56859f03544112725bf7e5b349eba5ed81b3322` | | `tests/test_phase08_preflight.py` | original fail-closed regression | `8a4ad7c70de28ffe3148fd3fd1f68c36a872c53c691c9068e1ff163970863c48` | Historical reporting dated 2026-07-18 recorded 17/17 host tests passing, manifest and safety checks passing, and a secret scan passing across 558 text files. Those results are historical repository evidence. They are not current hardware observations or proof of firmware behavior. The immutable result remains `READ_ONLY_PREFLIGHT_BLOCKED`. Firmware 9.60 runtime behavior remains `UNPROVEN`. The stock elfldr and Payload Manager sizes and hashes remain reference values only; their current on-device identity is not established. ## Schema boundary The existing artifact schema describes built target artifacts, while the controlled-runtime schema describes the separate Phase-0.7 hardened runtime. Neither can represent an offline remediation dossier without implying inapplicable artifact or deployment semantics. No shared schema is widened. The remediation manifest therefore names the dedicated `chimera-gfx-phase-0.8-remediation-v1` contract and is validated semantically by `tools/validate_phase08_remediation.py`. ## Side-effect classification - **A — persistent mutation:** file create/write/delete/rename, configuration or autoload change, metadata change, or persistent platform-state change. - **B — process- or service-wide mutation:** functional global flags and counters, `server_active_flag`, `autoload_triggered`, process/service state, signals, or retry state. - **C — volatile technical effect:** socket acceptance, temporary buffers, allocations, scheduler activity, kernel counters, caches, audit or logging paths, and temporary process-local state. - **D — observation:** firmware fields, file metadata and hashes, process and listener lists, configuration, rollback identities, and storage conditions. No persistent write found is not equivalent to side-effect-free. Category C is not claimed absent. Missing observations are unknown, never evidence of safe absence. ## Pinned Payload Manager source The reviewed local source is public Payload Manager v0.3.1 commit `cfbc70f30f419b09bf2b52283f7409e2d3117ee1`. Relevant source identities are recorded in `manifests/runtime/phase-0.8-remediation.json`. The three confirmed root findings are: 1. `http_on_request()` returns early for `OPTIONS`, then calls `log_server_set_active()` for every other request at `work/upstream/pldmgr-v0.3.1/src/http_server.c:131-152`. `log_server_set_active()` writes the process-global `server_active_flag = 1` at `work/upstream/pldmgr-v0.3.1/src/log_server.c:20-23`. 2. `/autoload_status` calls `pldmgr_autoload_get_status()` at `work/upstream/pldmgr-v0.3.1/src/http_server.c:847-852`. That function writes `autoload_triggered = 1` at `work/upstream/pldmgr-v0.3.1/src/autoload.c:44-48`. The worker reads that flag when deciding whether to leave its frontend wait and begin the countdown at `src/autoload.c:78-93`. 3. The same handler opens `/data/pldmgr/autoload.txt` and calls `config_read()` at `src/http_server.c:854-871`. `config_read()` opens `/data/pldmgr/pldmgr_config.txt` at `src/config.c:12-49`. ### Request side-effect matrix All handlers below are rooted in `http_on_request()`. “Filesystem/config” means project source performs such a read; it does not assert that no other read or technical effect occurs. | Method | Endpoint | Handler path | `server_active_flag` | `autoload_triggered` | Filesystem/config | Other proven or unproven effects | Strict read-only | |---|---|---|---:|---:|---:|---|---:| | `OPTIONS` | `*` | `http_on_request` | no | no | no | response/transport allocations; network, cache, audit, scheduler and kernel effects unproven | **no** | | `GET` | `/version` | `http_on_request` | yes | no | no | B: global flag; C: transport effects | **no** | | `GET` | `/log` | `http_on_request -> log_build_json` | yes | no | no | B: global flag; C: allocation and mutex; D: ring observation | **no** | | `GET` | `/autoload_status` | `http_on_request -> pldmgr_autoload_get_status -> config_read` | yes | yes | yes | B: functional autoload change; C: read/transport effects; D: config observation | **no** | | `GET` | `/get_config` | `http_on_request -> config_read` | yes | no | yes | B: global flag; C: atime/audit/cache/metadata unproven; D: config observation | **no** | | `GET` | `/list_payloads` | `http_on_request -> payload_mgr_list_json` | yes | no | yes | directory and sidecar scans; possible USB enumeration; technical effects unproven | **no** | | `GET` | `/processes_list` | `http_on_request -> process_list_json` | yes | no | no | `sysctl` snapshot and allocation; kernel/audit/scheduler effects unproven | **no** | | `GET` | `/sources_list` | `http_on_request -> sources_list_json` | yes | no | yes | not excluded by `is_noisy_route`, so `pldmgr_log()` also writes stdout and the log ring | **no** | | `GET` | `/getip` | `http_on_request -> pldmgr_get_local_ip` | yes | no | no | network-interface query; kernel/cache/audit effects unproven | **no** | Supporting locations: - route constants: `include/pldmgr.h:7-44`; - noisy-route list and generic request entry: `src/http_server.c:108-152`; - non-noisy request logging: `src/http_server.c:479-481`; - payload and process lists: `src/http_server.c:601-616`; - sources list: `src/http_server.c:706-713`; - version, log, IP, autoload and config handlers: `src/http_server.c:826-954`; - ring and stdout mutation: `src/log_server.c:12-55`; - payload scan: `src/payload_mgr.c:114-153,196-238`; - sources file read: `src/sources.c:28-84,112-134`; - process snapshot: `src/process_mgr.c:43-88`. `OPTIONS` is not promoted merely because it returns before the two proven flag writes. It provides none of the required device evidence, and network, allocation, logging below the reviewed layer, cache, audit, scheduling, and kernel-counter effects are still unproven. ## Root-cause analysis The current HTTP interface is a frontend-control interface, not an evidence collector. A request is treated as evidence that the frontend is active, so the server deliberately changes functional process state. The autoload route goes further and changes a flag consumed by the autoload worker. This makes the interface incompatible with the historical absolute read-only contract even where the response body appears informational. A filesystem open using mode `"r"` prevents application-level content writes; it does not prove absence of atime, audit records, page-cache activity, metadata/cache updates, scheduling, kernel counters, or platform-specific effects. Those effects require an exact collector and environment contract. Unavailable data cannot be interpreted as a negative observation. No current firmware query, file identity, process/service inventory, listener inventory, autoload snapshot, or rollback identity exists in this dossier. A missing Payload Manager backup cannot be created in an absolute read-only phase. Creating it necessarily writes a new persistent object and may change filesystem allocation and metadata. Backup creation therefore belongs to a separate mutating rollback-preparation phase with separate authorization. ## Evidence contract for a possible future method No collector is selected. Every timeout below is deliberately unset until the collector implementation, transport, and cleanup contract are reviewed. An unset timeout, timeout expiry, unknown result, identity drift, or partial dataset yields `STOP`. | Observation | Needed fact | Possible source class | Confidence | Known mutations | Unknown effects | Required identity | Timeout | Reviewer return | |---|---|---|---|---|---|---|---|---| | firmware | two authoritative current values agree exactly | two independently reviewed authoritative sources | `UNPROVEN` | none established | UI/transport/audit/cache/platform query | tool/source/operation identity | unset → `STOP` | raw values, times, identities, agreement | | live paths | literal paths, mounts, types, no symlink | reviewed no-follow metadata operation | `UNPROVEN` | none established | atime/audit/cache/namespace | tool, source, no-follow and mount semantics | unset → `STOP` | raw paths, mounts, types, symlink decision | | object identities | stable pre/post object/device IDs and full metadata | same reviewed object collector | `UNPROVEN` | none established | cache/audit/race/concurrency | lookup, race, symlink policy | unset → `STOP` | complete pre/post records and errors | | file sizes | exact current live byte sizes | same bound object handles | `UNPROVEN` | none established | cache/audit/concurrent modification | same-object and race policy | unset → `STOP` | sizes, references, bindings | | SHA-256 | digest of exact current bytes | no-follow same-object streaming hash | `UNPROVEN` | none established | atime/audit/page cache/scheduling | implementation, version, commit, binary hash, open policy | unset → `STOP` | bytes, times, digest, identity, errors | | processes/services | all relevant owners, paths, parents, starts and startup modes | reviewed process/service snapshot | `UNPROVEN` | none established | counters/audit/scheduling/locks/cache | tool/API/source/snapshot semantics | unset → `STOP` | raw snapshot and unmapped entries | | listeners | owners and binding for 8084/8085/9021 | reviewed listener snapshot | `UNPROVEN` | none established | stack counters/audit/cache/locks/races | tool/API/source/owner mapping | unset → `STOP` | protocol/address/port/owner/exposure | | autoload/startup/retry | complete authoritative state; artifacts absent; retry off | collector distinct from stock `/autoload_status` | `UNPROVEN` | stock route mutates `autoload_triggered` | atime/audit/cache/metadata/service/race | tool/source plus complete source list and no-functional-mutation proof | unset → `STOP` | safe raw representations, identities, hashes, decisions | | rollback files | separate existing exact backups and restore mappings | same admissible object/hash collector | `UNPROVEN` | none established | atime/audit/cache/metadata/mount/race | hash, object and separation semantics | unset → `STOP` | paths, IDs, hashes, separation and mapping | | storage condition | separate target, 2447320 content bytes plus reserve | reviewed capacity/mount operation | `UNPROVEN` | none established | mount/audit/cache/accounting/concurrency | tool/API and capacity semantics | unset → `STOP` | IDs, available bytes, reserve and separation | Any code-bearing collector would additionally require its exact name, version, origin, source commit, byte size, SHA-256, complete operation set, imports, transitive effects, output channel, cleanup, and fail-closed timeout behavior. ## Architecture options — design only | Option | Can prove | Cannot prove | Transfer/execution needed | Persistent effects | Volatile effects | Required permission | Remaining blockers | |---|---|---|---|---|---|---|---| | A. Current Payload Manager endpoints | limited in-memory version/config/list responses | strict side-effect freedom, complete files/listeners/rollback identity | no new target transfer; requires a network request to an existing process | reads may affect metadata; no content write proven for selected GETs | proven global flags; autoload flag on status; sockets, allocation, logs, caches and audit | new bounded-observation permission would still be required | current interface violates the absolute read-only contract | | B. Future one-shot observation method | potentially a purpose-built complete bounded dataset | nothing until source, ABI, transport and cleanup are reviewed | likely transfer and execution, both currently unspecified and unauthorized | must be forbidden by contract but absence is unproven | startup, loader, transport, allocation, scheduling, cache, audit and logs | new exact artifact- and method-bound permission | no design, binary, hash, ABI, timeout or cleanup proof exists | | C. Manual/external firmware observation | one user-visible firmware value, possibly an independent second value | live files, processes, listeners, autoload and rollback state | no code transfer or execution if strictly manual | UI/platform persistence is unreviewed | UI, audit, cache and human transcription | new exact observation permission if used as formal evidence | insufficient for the complete preflight | | D. Split observation from rollback preparation | observation can be reviewed before any backup write; later backup phase can prove rollback objects | observation alone cannot create missing backups | observation method unknown; backup preparation necessarily performs writes | backup creation, allocation and metadata are expected persistent effects | tool, storage, cache, scheduling and audit effects | separate observation permission, then separate mutating rollback permission | exact live identity and admissible backup procedure remain absent | None of these options is implemented by Phase 0.8R. ## Hard gates The active blockers are: 1. `exact_permission_quote_absent` — `STOP-RO`; 2. `collector_identity_absent` — `STOP-RO`; 3. `collector_side_effect_contract_absent` — `STOP-RO`; 4. `two_current_firmware_sources_absent` — `STOP-GATE`; 5. `live_object_identities_absent` — `STOP-GATE`; 6. `listeners_absent` — `STOP-GATE`; 7. `autoload_status_absent` — `STOP-GATE`; 8. `rollback_backups_absent` — `STOP-GATE`; 9. `payload_manager_backup_not_byte_exact_on_device` — `HARD_STOP-GATE`; 10. `unknown_result_is_stop` — `STOP`; 11. `timeout_is_stop` — `STOP`; 12. `deviation_is_stop` — `STOP`; 13. `automatic_retry_forbidden` — `STOP`. No general `READY`, `COMPLETE`, or deployment status may override any one of these gates. The Payload Manager backup gate can be closed only by artifact-specific, current, on-device evidence gathered under a separately approved method, not by changing this manifest. ## Phase separation Authority never flows forward. Each step requires its own completed review and new permission where it involves a target: 1. this offline remediation; 2. a possible later bounded-observation design; 3. separate permission for any observation transfer or execution; 4. review of the returned observations; 5. separate mutating rollback preparation if a backup must be created; 6. separate installation approval for only hardened elfldr and controlled Payload Manager; 7. installation verification and complete rollback proof; 8. separate lifecycle approval; 9. non-graphical capability probes; 10. much later, a graphics backend and RetroArch. Installation permission does not grant lifecycle permission. Observation permission does not grant rollback preparation. No earlier wording may be reused for a later artifact, method, or phase. ## Relationship to RetroArch RetroArch is a long-term goal, not an active Phase-0.8R workstream. The dependency chain is: ```text offline evidence integrity -> admissible bounded observation -> verified rollback and installation boundary -> separately approved lifecycle -> non-graphical capability evidence -> later graphics/runtime contracts -> later adapters -> eventual RetroArch port ``` Phase 0.8R implements none of GNM, VideoOut, SDL, hardware acceleration, input, audio, RetroArch frontend behavior, cores, or content launching. ## Machine-readable consistency record The validator compares this block structurally with the remediation manifest. ```json { "status": "READ_ONLY_PREFLIGHT_BLOCKED", "authorization": { "authorized": false, "installation_authorized": false, "lifecycle_authorized": false, "execution_authorized": false, "transfer_authorized": false, "automatic_retry": false }, "blockers": [ "exact_permission_quote_absent", "collector_identity_absent", "collector_side_effect_contract_absent", "two_current_firmware_sources_absent", "live_object_identities_absent", "listeners_absent", "autoload_status_absent", "rollback_backups_absent", "payload_manager_backup_not_byte_exact_on_device", "unknown_result_is_stop", "timeout_is_stop", "deviation_is_stop", "automatic_retry_forbidden" ], "firmware_runtime_behavior": "UNPROVEN", "stock_identity_classification": "reference_only", "payload_manager_backup_classification": "hard_blocker", "retroarch_active_phase": false } ```