# RPTP risks — baseline after Gate 0 spike

| ID | Risk | Likelihood / impact | Current mitigation | Trigger to revisit |
|---|---|---|---|---|
| R-001 | Writing the recompiler and runtime from scratch exceeds available engineering capacity. | High / Critical | Vertical slices; estimate in person-weeks; Gate Review required. | Three sessions without measurable progress or estimate range exceeded. |
| R-002 | The subset spike passes but does not generalize to R5900 quirks. | High / Critical | Explicitly label this as a generic MIPS subset; use permitted R5900-specific references and independent tests before claiming support. | First PS2-specific instruction family is added. |
| R-003 | Generated C++ and oracle share the same bug or the oracle is inaccurate. | Medium / High | Add independent test vectors and permitted reference checks; do not rely on self-comparison alone. | Any hardware-semantic instruction is promoted to supported. |
| R-004 | ELF parsing mishandles retail PS2 ELF variants or malicious input. | Medium / High | Validate lengths/offsets; fuzz parser in ISO Inspector; keep synthetic fixtures small and manifest-listed. | ISO Inspector is exposed to arbitrary user input. |
| R-005 | MSVC/Windows behavior differs from host toolchains. | Medium / High | The narrow generated-source differential spike has passed on MSVC; CI exists and is green. Do not infer full project or game compatibility. | CI fails or new instruction behavior is added. |
| R-006 | Missing EE syscalls, IOP services, DMA behavior or timing blocks the first game. | High / Critical | Runtime diagnostics for missing services; implement based on measured first-game requirements. | First-game boot vertical slice. |
| R-007 | VU/GS semantics, especially microprograms and pixel operations, consume most of the schedule. | High / Critical | Keep a renderer spike ADR; use pixel/state oracle tests; profile before optimizing. | Renderer/GPU prototype begins. |
| R-008 | Historical source exposure compromises the intended clean-room policy. | Medium / High | ADR-0003 sealed-source policy: preserve the explicit exposure record; do not access or use sealed projects; require independent provenance and tests for affected work; quarantine anything that cannot demonstrate it. | Any accidental access, any proposal to use a sealed project, or any implementation area without provenance evidence. |
| R-009 | License, dependency compatibility or publication policy is unclear. | Medium / High | GPL-3.0-or-later is the selected project license and is published. Audit every third-party dependency and keep prior-source exposure review separate. | Before adding/vendoring a dependency or redistributable asset. |
| R-010 | Generated C++ compilation time or code size becomes impractical. | Medium / High | Synthetic translation-unit sizing and compile-time evidence is recorded in `docs/research/performance-baseline.md` (single-block growth, the large-function collapse and split-block comparison); retail-scale shape remains unmeasured. | Gate 3 produces more than fixture-sized output, or a retail-scale translation unit is measured. |
| R-011 | CI workflow/toolchain drift creates false confidence or false failures. | Medium / Medium | Test Windows/MSVC and Linux/host separately; record runner/toolchain versions; do not equate CI green with game compatibility. | CI failure or runner image/toolchain change. |
| R-012 | Checklist statuses in `tools/rptp_progress.py` remain hand-maintained and can drift from test evidence; only README/badge numeric agreement is guarded. | Medium / Medium | Recheck every checklist status when evidence changes; the progress-consistency test guards the published numbers, not the statuses themselves. | Any checklist status edit or new evidence claim. |
| R-013 | `docs/COMPATIBILITY.md` and `docs/ISO_INSPECTOR.md` recorded 53 tests after the suite grew to 54; both files were outside the earlier integrity-pass allowed set. | High / Low | Resolved 2026-10-22: both files now state that the suites pass and point to `docs/VERIFICATION_LOG.md`. | Next documentation update. |
| R-014 | `AGENTS.md` was present in the working tree but untracked; repository clones did not receive the agent rules. | Medium / Medium | Resolved 2026-10-22: tracked and committed as `ce1c57c` with the owner-approved rules. | Closed. |
| R-015 | `docs/CLEAN_ROOM_AUDIT.md` and `docs/EXECUTION_CONTEXT.md` hard-coded test counts after Part 0 removed them from the allowed prose and progress tool. | High / Low | Resolved 2026-10-22: counts removed; both files now point to `docs/VERIFICATION_LOG.md`. | Closed. |
| R-016 | The 4 MiB default materialization cap is smaller than observed retail boot executables; the current local sample reaches 5,684,592 bytes, and four images exceed the cap. The current inspector streams hashes, but extraction/materialization may be blocked if the cap is reused. | Medium / Medium | Keep inspection streaming and the cap unchanged for now; boot sizes and outcomes are recorded in the game records; revisit the cap when a future extraction design is approved. | Extraction or boot-materialization design begins under a future ADR. |
| R-017 | Interleave field offsets were not verified against ECMA-119, and the zero-interleave retail sample did not validate the explicit rejection behavior. | Medium / High | Resolved 2026-10-22 for field mapping: ECMA-119 5th ed. Table 8 (p. 37) and §§10.1.8–10.1.9 (p. 40) confirm BP 27/28 map to zero-based bytes 26/27. Targeted tests reject each field independently and preserve input bytes. `INTERLEAVED_UNSUPPORTED` remains fail-closed; decoding interleaved data is not implemented. | Interleaved-layout support design begins. |
| R-018 | A PVD volume space can be smaller than the image file (`God of War II`); the second layer or remaining image data is not described by the PVD and is not inspected. | Medium / High | Re-verified 2026-10-22 at inspector `d51f0e7`: the PVD declares 2,083,888 blocks (4,267,802,624 bytes) in an 8,533,671,936-byte image, leaving 2,082,944 sectors outside the declared volume. All 15 reported files are inside it; the highest extent ends 32,768 bytes before the volume end. ECMA-119 §9.4.9 (p. 26) defines the field as the declared logical-block count. The inspector bounds extents to that volume and accepts a larger file; existing tests cover both directions. The extra data's purpose remains unexplained and no dual-layer claim is made. | Dual-layer or layered-media handling is designed. |
| R-019 | Gate 2's read-only scope could be mistaken for approval or safety of extraction; a write path would add traversal, overwrite, destination and proprietary-content risks. | Medium / High | ADR-0004 excludes extraction from Gate 2 and requires a separate ADR and threat model; no extraction API or output-directory option exists. | Any extraction proposal or write-capable inspector feature. |
| R-020 | The owner describes one San Andreas USA sample as original and the other as an Indonesian-language modification, but the modified file set, translation scope and method are not audited. The samples share boot and `SYSTEM.CNF` hashes, so those hashes cannot locate or prove the modifications, and a future record could confuse the samples or overstate what is known. | Medium / High | Keep separate game records with owner-provided provenance, actual whole-image hashes and PVD identifiers; do not infer modified files, revision or compatibility from filename labels or shared boot metadata. This is a provenance limitation, not a parser defect. | Any extraction, file comparison, boot or title-selection work involving these samples. |
| R-021 | The requested MIPS64 Revision 6.03 official PDF returned HTTP 403. The LUI wording was checked in Revision 5.04, while the available Rev 6.03 mirror exposed only identity and table-of-contents text. A reviewer could require the exact Rev 6.03 passage. | Low / Medium | Record both revisions and the access limit in `RPTP-REF-013`; use the checked generic MIPS64 LUI semantics only for the narrow synthetic model and make no R5900-specific claim. | Independent provenance review, a working official Rev 6.03 source becomes available, or LUI semantics are expanded. |
| R-022 | The synthetic 64-bit register model previously truncated ORI and XORI results to 32 bits, while register-logical operations and LUI modeled 64-bit registers. | Low / Low | Resolved 2026-10-26: finding F1 from the P1 audit was reproduced via `tests/test_instruction_logical_width.py`; `ORI` and `XORI` were corrected in `tools/rptp_gate0_spike.py` and `tools/rptp_lower.py` to perform full 64-bit logical OR/XOR preserving upper bits of `rs`. All other modeled instructions were audited and confirmed to conform to generic MIPS specifications. Full R5900-specific behavior is not cross-checked. | Closed. |

| R-023 | The SLTI and SLTIU increments have CI-green literal-oracle and native differential tests, but the tests were not executed against the pre-feature parent in a separate failing run during this session. | Medium / Medium | Their tests assert fixed expected register values, immediate extension, boundary cases and fail-closed behavior; both supported CI jobs pass after implementation. For strict per-increment provenance closure, replay the focused tests against the pre-feature parent in a disposable checkout and record the expected unsupported-opcode failure. No clean-room or Gate disposition is inferred. | Next Gate 3 provenance review or when a local checkout is available. |
| R-024 | The original DADDIU oracle fixture did not distinguish 64-bit addition from ADDIU's sign-extended 32-bit result; its native boundary harness did not exercise the oracle. | Low / Medium | Resolved locally 2026-10-28: an in-memory ADDIU-dispatch mutation reproduced the gap, then positive and negative signed-32-bit crossings were added to the existing fixture with literal oracle/native assertions. The strengthened oracle test rejects the mutation; focused MSVC tests pass. Production semantics are unchanged. Evidence: `docs/VERIFICATION_LOG.md`, `tests/test_instruction_daddiu.py`. Published through PR #10 (`a1365b5`, run `40770223526`); independent review remains open. | New arithmetic oracle coverage or independent review. |
| R-025 | Inspection could misreport a displaced PVD, accept reserved/conflicting descriptors or malformed padding/identifiers, treat non-final file sections as regular data, or resolve an explicit BOOT version to a different version. | Medium / High | Resolved locally 2026-10-28 for the primary-only envelope: reproduced failures, checked ECMA-119 under RPTP-REF-006, and added descriptor inventory/bounds, explicit unsupported-layout errors, zero-sector padding, printable-ASCII identifier validation and exact versioned lookup. Named format/review regressions and deterministic read-only CLI cases are in `tests/test_iso_inspector.py`; evidence is in `docs/VERIFICATION_LOG.md`. Extension decoding remains unsupported; hosted exact-head CI passed via PR #10 (`a1365b5`, exact-head run `40769859822`, main run `40770223526`), and independent provenance review remains open. | New namespace/layout support or independent inspection review. |
| R-026 | Duplicate or repaired BOOT configuration could select an unintended executable; special records and directory aliases could evade intended parser-work or pending-directory bounds. | Medium / High | Resolved locally 2026-10-28: reject duplicate keys, embedded NUL/non-ASCII and malformed quotes; count raw records including special entries; bound directory/survey bytes including padding; deduplicate and limit directory extents before queueing; validate empty/negative read ranges. Exact/+1, early-rejection, fan-out, alias/cycle and large-file streaming tests pass locally. No materialization-cap increase or new dependency. Hosted exact-head CI passed via PR #10 (`a1365b5`, exact-head `40769859822`, main `40770223526`); independent provenance review remains open. | Changes to configuration syntax, parser budgets or traversal scheduling. |
| R-027 | A successful ELF metadata/load-map report could be mistaken for a validated native loader input; overlap precedence, physical-address mapping, relocations and PS2-specific loading conventions remain undefined. | Medium / High | Keep the inspector metadata-only. Locally addressed 2026-10-28 under RPTP-REF-003 and `ElfLoadMapTests`: reject ELF32 virtual-range overflow and decreasing PT_LOAD addresses; report file-backed/zero-fill bounds and all entry mappings, with overlap, permission and ambiguity warnings. The previously accepted `0xFFFFFFF0` plus memory size `0x100` now fails explicitly; exact exclusive end `2^32` remains valid. Alignment congruence remains tested. Bully and both San Andreas samples expose overlapping zero-fill ranges; do not collapse them or sum sizes into a validated memory footprint. The native `rptp_runtime` loader (PR #13) now validates alignment, ordering, bounds and entry executability under `RPTP-REF-003` and rejects overlaps by explicit RPTP policy ([RUNTIME.md](RUNTIME.md)); inspector warnings remain metadata only. Physical-address mapping, relocations and PS2-specific loading conventions remain undefined; the risk is still open. | Native ELF loading or inspector-to-analyzer integration design. |
| R-028 | Directory metadata strictness gaps: survey accepted a subdirectory whose data length was zero, did not require `.`/`..` entries, and ignored record-length slack beyond the identifier and padding. The 2026-10-29 review response also required a block-multiple directory length, which is stricter than ECMA-119 §7.4.5. | Low / Medium | Resolved locally 2026-10-29: both modes reject zero data lengths (`DIRECTORY_SIZE_INVALID`), odd record lengths, missing/swapped `.`/`..` records (`DIRECTORY_DOT_ENTRY_INVALID`), and records that do not fit the declared length. A 2026-10-30 read-only re-probe of the owner-authorized Downhill Domination (USA) image found all 15 directories non-aligned (216 to 44,464 bytes; root 990 bytes), and ECMA-119 §7.4.5 permits a file section shorter than its data space; the over-strict block-multiple requirement was removed and `test_accepts_non_block_aligned_directory_data_lengths` covers 114- and 990-byte directories. `IsoHardeningTests` encodes the review probes, and the findings are recorded in [ISO_INSPECTOR_REVIEW.md](ISO_INSPECTOR_REVIEW.md). No analyzer or native loader trust is implied; hosted CI and the owner's Gate 2 review decision remain pending. | Directory traversal integration or a stricter fail-closed policy. |
| R-029 | The eight-image census figures in `BOOT_CENSUS.md`, the acceptance range in `STATE.md`/`HANDOFF.md` and the per-game `docs/games/<slug>/STATUS.md` counts were measured with older decoders, so `SUBU`, branch-likely and later supported encodings still counted as unsupported there. | Low / Medium | Reopened 2026-10-31: the decoder set changed again with the four COP1 transfer forms, so the 2026-10-29 read-only measurement (142 supported mnemonics, set SHA-256 `ddc2559...`, 76.96%–86.30% acceptance) and the per-game counts are a lower bound relative to the current 146-mnemonic decoder. The measurement remains valid for the decoder it names; every whole-image SHA-256, size and mtime was unchanged before and after that run, and the earlier pre-`SUBU` 58.3%–69.2% rows and one-image 63.03% figure remain superseded. The figures are decoder acceptance, not runtime results. The COP1-transfer increment did not produce a census sub-breakdown, so no claim is made that the transfers dominate any raw-unsupported label. | Close only after a fresh read-only eight-image census with the current decoder set is recorded in `BOOT_CENSUS.md`, the per-game records and this table; reopen again whenever the decoder set changes or a new image is added. |
| R-030 | Status documents drifted from merged evidence: hard-coded PR/run pointers, dates, counts and fixture lists were stale across ROADMAP, COMPATIBILITY, RISKS, REFERENCES, INCREMENT_LEDGER, EXECUTION_CONTEXT, BUILD_PROVENANCE, ISO_INSPECTOR and game records while CI and tests were green. | Medium / Medium | Added `docs/README.md` as the document map, a mandatory freshness rule in `AGENTS.md`, and `tests/test_doc_freshness.py`, which fails when the map omits a document, when STATE's snapshot date is older than the newest VERIFICATION_LOG entry, or when the STATE/HANDOFF PR pointer lags the latest merge recorded in the log. Historical records stay preserved rather than rewritten. | Any new document, new log format or broader date/pointer claim. |
| R-031 | Implementation paths can diverge: the Gate 0 spike, the `tools/rptp` pipeline, the older `tools/rptp_ir.py`/`tools/rptp_lower.py` pipeline and the C++ `runtime/` harness model instructions separately, so an instruction tested on one path is not automatically supported or identically behaved on another. The eight branch-likely forms, the six ordinary branch forms (PR #51), the nine doubleword-shift forms (2026-10-31, `RPTP-REF-015`) and the 4-byte `LW`/`SW` plus 8-byte `LD`/`SD` alignment policy now agree across `tools/rptp`, the harness and the cross-path suite (PRs #41/#43/#51), and the 4-byte rejection was extended to the frozen Gate 0 spike and legacy lowering (`tests/test_fail_closed_alignment.py`) while 8-byte `LD`/`SD` stays canonical-only, so the paths still model separate subsets and no canonical product path is declared. The six byte/halfword memory forms `LB`/`LBU`/`LH`/`LHU`/`SB`/`SH` now execute in the harness and are compared with the canonical oracle in `tests/test_runtime_execution.py`, while the frozen legacy pipeline still rejects them. The eight HI/LO integer forms `MFHI`/`MFLO`/`MTHI`/`MTLO`/`MULT`/`MULTU`/`DIV`/`DIVU` now execute in the harness under an RPTP test-defined HI/LO model compared with the canonical oracle in the same module; the harness also rejects nonzero reserved fields on `MULT`/`MULTU`/`DIV`/`DIVU`, which the canonical decoder does not validate, a documented stricter-than-canonical policy rather than a semantic divergence. Resolved 2026-10-31: the canonical decoder now rejects a variable-form doubleword shift whose reserved `shamt` field is nonzero with `valid=False` and `supported=False`, matching the native harness's `EXEC_UNSUPPORTED_INSTRUCTION`; the parity is asserted in `tests/test_isa_encodings.py`, `tests/test_instruction_dshift.py` and `tests/test_runtime_execution.py`. The E4 umbrella remains open for the remaining failure classes. | Medium / Medium | Resolution proposed 2026-10-30 in [ADR-0005](DECISIONS/ADR-0005-canonical-execution-path.md): `tools/rptp` plus the native harness would be canonical, the legacy paths frozen and retirement gated on E1–E4. `tests/test_path_contract.py` pins the frozen legacy lowering set, its containment and the canonical-only branch forms (E1) and proves one shared synthetic program produces identical legacy and canonical oracle state (E2). `tests/test_native_legacy_equivalence.py` adds E3 (PR #61, merge `8def5a6`): the legacy generated C++, the canonical oracle, the canonical generated C++ and the native harness agree on the same shared 28-operation program after documented word-to-byte memory normalization; PR #60 pins fail-closed legacy branch rejection as an E4 slice. E4 (full fail-closed parity across the remaining failure classes) remains open; the reserved-`shamt` case within it is closed as of 2026-10-31, two delay-slot classes now reject equivalently across the canonical CFG/oracle, the frozen legacy IR and the native harness (`tests/test_fail_closed_parity.py`), three unsupported encodings reject equivalently (`tests/test_fail_closed_unsupported.py`), unaligned `LW`/`SW` now reject in the frozen legacy oracle and lowering, the canonical oracle and the native harness (`tests/test_fail_closed_alignment.py`), and the last two classes are mapped in `tests/test_fail_closed_memory_regions.py` as of 2026-10-31: unmapped/cross-region access rejects per model (canonical oracle `ExecutionError` and generated C++ exit 2 past the flat 32 MiB RAM model; `rptp-run` `EXEC_MEMORY_FAULT` outside one loaded segment) and link `rs = 31` rejects at decode/CFG, canonical oracle/lowering/codegen, frozen legacy IR and the harness. E4 now has evidence for every listed class but remains open for owner acceptance and hosted CI on one recorded commit. The ADR is Proposed (merged by PR #57 at `5326059`); no path is canonical and no cross-path result is semantic proof until the owner accepts it. | Any instruction added to one path, and before a first vertical slice is declared. |
| R-032 | The PR #51 independent review found residual test and lowering gaps outside that increment's claims: the taken ordinary-branch delay-slot memory case stores zero into already-zero memory (only the trace distinguishes it), link-before-delay-slot ordering is not directly exercised, and the branch lowerer used `control_instruction.target or next_pc`, which would lower a branch targeting address 0 to the fall-through; the oracle also carried a dead `and state.registers` guard. | Low / Medium | Resolved 2026-10-30 in PR #54: the lowerer distinguishes an absent target (`None`) from address 0, the dead guard is removed, the taken delay-slot store writes `0x5A`, a BLTZAL/BGEZAL delay slot consumes the updated `GPR[31]` on both outcomes, target-0 lowering is asserted directly, and the cross-path BGEZAL delay slot reads `$ra` across the oracle, generated C++ and `rptp-run`. Exact-head runs `41005061054` (push) and `41005075117` (pull request) on `5374828`, plus runs `41005626121` (push) and `41005630440` (pull request) on `3c4c6fe`, passed. An independent read-only agent review at `5374828` returned APPROVE (session record, not a GitHub formal review). | Re-open if branch lowering, delay-slot ordering or the synthetic branch fixtures change without equivalent coverage. |

## Gate 3 and Gate 4 effort ranges (initial, low confidence)

Assumptions: one experienced systems engineer working full time; no reuse of emulator/recompiler implementation code; only permitted public documentation and independently generated test inputs; first test title selected for measured simplicity; ranges express engineering effort, not calendar promises.

- **Gate 3 — recompiler MVP:** 20–60 person-weeks. Includes enough R5900 decode/semantics, reference interpreter, C++ code generation, analyzer, differential tests and failure diagnostics to satisfy the agreed project scope. Confidence is low because the current spike covers only 10 instruction mnemonics.
- **Gate 4 — first gameplay vertical slice after Gate 3:** 40–120 additional person-weeks. Includes a selected title's boot path, minimum kernel/IOP/CDVD path, necessary DMA/VU/GS behavior, input/audio/save support and cold-boot/gameplay verification. Confidence is very low because title complexity is not yet measured.

These are deliberately wide initial ranges. The current synthetic catalog in [INSTRUCTION_CATALOG.md](INSTRUCTION_CATALOG.md) is not evidence that the full work will fit within the lower bound. After ISO inspection and title selection exist, replace the assumptions with a workload-specific estimate.
