# Development and analysis environment: Ghidra, green-eye and the Open-IOV toolchain > The single front door to the environment an Open-IOV developer works in: > the host stack, the guest diagnostics, the CUDA userspace and GSP firmware > Ghidra corpora, the host RM tooling, green-eye, CI and MCP. Each component > links to the document that specifies it; this page is the map, not a > duplicate of the manuals. ## 1. Scope and benefit Open-IOV spans a host kernel module, a QEMU/KVM guest stack, a CUDA userspace binary, GSP firmware, a host resource manager and a growing analysis toolchain. The pieces were built by different workstreams and each has its own manual; the cost of a new contributor (or a returning one) has been re-learning where to start for a given question. This document exists to remove that cost: it is the **one map** of the environment — what every tool is for, when to use it, where it lives, and which document explains it — plus the two reverse-engineering loops that tie static and dynamic analysis together. In scope: the developer-facing analysis environment. Out of scope: end-user installation (see [`02-getting-started/01-install-and-first-run.md`](../02-getting-started/01-install-and-first-run.md)), the emulation architecture itself (see [`03-architecture/01-system-overview.md`](../03-architecture/01-system-overview.md)) and product roadmaps. The green-eye toolchain is **in development and not ready yet** — status, limits and flag-removal criteria are in [`05-operations/03-risc-v-gsp-rm-vm.md`](../05-operations/03-risc-v-gsp-rm-vm.md) and the tool's own [`docs/00-OVERVIEW.md`](../../debug/risc-v-gsp-rm-vm/docs/00-OVERVIEW.md). ## 2. The environment at a glance ```mermaid flowchart TB subgraph HOST["Lab host - x86_64 or aarch64"] SM["scripts/stack_manager.sh
build / load / status / test / unload"] MOD["open-iov-vfio.ko
virtual device + GSP-RM emulation + backend"] QEMU["QEMU / KVM
scripts/vgpu_vm.py, launch_qemu_*.sh"] VFIO["VFIO mdev + IOMMU isolation"] RMTOOLS["tools/rmtool, rmtop, rmq
read-only host RM oracle"] subgraph GUEST["Guest VM - stock driver, no Open-IOV code"] WORK["CUDA workload + tools/cuda-ab"] GDIAG["tools/guest-diag
ioctl tracer, engines, pmap, probes"] end subgraph STATIC["Static analysis"] GHFW["tools/ghidra + firmware/57X-GSP/<ver>
GSP firmware Ghidra projects"] GHCUDA["userspace/cuda Ghidra corpus
+ analysis tools"] end subgraph DYN["Dynamic firmware analysis - green-eye"] GE["Session: hooks, watchpoints, memory,
call, run_until, record"] GEB["Backends: QEMU-RSP + native RV64IMAC"] GEH["harness/, injection SDK,
Ghidra bridges, device maps"] RMH["rmharness host captures"] end subgraph AUTO["Automation"] CI[".github/workflows/ci.yml
.github/workflows/greeneye.yml"] MCP["plugins/mcp_server.py
agent tool surface"] end end SM --> MOD --> QEMU --> VFIO --> GUEST MOD --> RMTOOLS WORK --> GDIAG RMTOOLS --> RMH GHFW --> GE GHCUDA --> GE GE --> RMH GE --> CI GE --> MCP GE -->|"export_hits + symbol DB"| GHFW GHFW -->|"names + addresses"| GE ``` | Layer | What it answers | Entry point | |---|---|---| | Host stack | does the device load, boot and serve the guest? | `scripts/stack_manager.sh`, `scripts/vgpu_vm.py` | | Guest diagnostics | what did the stock driver request and receive? | `tools/guest-diag/` | | CUDA static corpus | what is `libcuda` doing, and what changed? | `userspace/cuda/READ-ME-FIRST.md` | | GSP firmware static | what does the firmware image contain? | `tools/ghidra/`, `firmware/57X-GSP//` | | Host RM oracle | what does real RM report on this GPU? | `tools/rmtool`, `tools/rmtop`, `rmharness/` | | Dynamic firmware | what did the firmware server actually do? | `debug/risc-v-gsp-rm-vm/greeneye.sh` | | CI / agent | did the broad suite pass; can an agent drive it? | `.github/workflows/`, `plugins/mcp_server.py` | ## 3. Host stack: KVM, QEMU, VFIO and the module The reference path is KVM + QEMU with the VFIO mdev transport. `open-iov-vfio.ko` emulates the device interface and GSP-RM behaviour (or drives the physical backend, per the chosen execution mode); the guest runs stock drivers only. ```bash ./install.sh deps nvidia firmware build # full host setup (stages selectable) make kernel # or: ./scripts/stack_manager.sh build-kernel ./scripts/stack_manager.sh load-open-iov # load open-iov-vfio.ko ./scripts/stack_manager.sh mdev-create # create the mediated device ./scripts/vgpu_vm.py start vgpu-linux # guest lifecycle + guest-agent exec/shell ./scripts/stack_manager.sh test # host test suite ./scripts/stack_manager.sh dmesg # live filtered trace ``` Module load order matters on the optional OpenRM path: build `kernel/` first (it generates `kernel/Module.symvers`), then build the OpenRM modules with `KBUILD_EXTRA_SYMBOLS`, then load Open-IOV, then OpenRM, then firmware. On a typical single-GPU developer host the distribution driver owns the GPU and the emulated QEMU path runs without the OpenRM modules. The full contract is [`03-architecture/06-host-module-and-hybrid-model.md` §7](../03-architecture/06-host-module-and-hybrid-model.md). Guest virtual-memory inspection uses the QEMU gdbstub (`scripts/qemu_gdb_attach.sh`, `-gdb tcp::1234`); host-side guest-RAM scans and pokes use the module debug parameters (`scan_guest_ram`, `scan_seq`, `poke_guest`) documented in [`05-operations/02-debugging-and-maintenance-workflows.md`](../05-operations/02-debugging-and-maintenance-workflows.md) §3.1–3.3. VM access from tooling goes through `scripts/vgpu_vm.py`; scripts never reboot or change system state without explicit operator action (project hard rule). ## 4. Guest diagnostics The stock guest driver is the best oracle for driver-side behaviour. These tools read it out without modifying it: | Tool | Purpose | Location | |---|---|---| | `ioctl_trace.c` | ptrace-based syscall/ioctl tracer (`LD_PRELOAD` cannot see `libcuda`'s raw syscalls) | `tools/guest-diag/ioctl_trace.c` | | `guest_engines.c` | guest engine/class inventory, virtualization mode, CE caps | `tools/guest-diag/guest_engines.c` | | `guest_pmap*.py`, `pmap_va.sh` | guest page-map walks (Linux and Windows samples) | `tools/guest-diag/` | | `push_guest_tools.sh` | stage diagnostics into the guest | `tools/guest-diag/push_guest_tools.sh` | | UVM debug prints | `echo 1 > /sys/module/nvidia_uvm/parameters/uvm_debug_prints` | guest sysfs | Standard captures for a bug report (host log, status, guest dmesg, `lspci -vvv`, `nvidia-smi -q`) are listed in [`05-operations/02` §2](../05-operations/02-debugging-and-maintenance-workflows.md). ## 5. CUDA userspace: the Ghidra corpus and its tools `userspace/cuda/` holds the decompiled corpus and name map for the guest `libcuda` (570.144) plus reusable tooling. Start at [`userspace/cuda/READ-ME-FIRST.md`](../../userspace/cuda/READ-ME-FIRST.md); the five core documents are `docs/01-architecture.md` through `docs/05-570.144-decompilation.md`, with `docs/07-version-upgrade-playbook.md` for version bumps and `docs/06-tooling.md` for recipes. **Address convention (the one rule that bites):** public offsets are file virtual addresses (`libcuda+0x...`); Ghidra loads the library at image base `0x100000`, so decompilations produced without translation point 0x100000 too low. Current tooling translates; re-derive old conclusions ([`docs/05` §1.1](../../userspace/cuda/docs/05-570.144-decompilation.md)). | Tool | Purpose | |---|---| | `tools/cudatool.py` | exports/FDEs/wrappers, `info`, `nearest`, `crash`, `delta`, `fdematch` | | `tools/callwalk.py` | callers/callees/chains over `callgraph.tsv` | | `tools/diff_corpus.py` | corpus diff across driver versions (match discipline reused by green-eye version diffs) | | `tools/name_candidates.py`, `subsystem_digest.py` | name candidates and per-subsystem call-tree digests | | `tools/ghidra_*.sh`, `tools/ghidra/` | headless analysis, decompile-at, index/name-map export, merge | | `tools/annotate_corpus.py` | apply the name map to the corpus | | `570.144/annotations/names.tsv`, `subsystems.tsv` | tracked name map (659 exports, verified internals) and subsystem index | | `tools/cuda-ab/ab.sh` + `vector_add.cu` | host-vs-guest A/B workload; `RESULT`/`STATUS` lines must match | | `tools/test/cuda_drv_test.c` | driver-API smoke test (prints `ALL OK`) | ## 6. GSP firmware: Ghidra projects and images Firmware images are versioned and never overwritten: `firmware/-GSP//gsp-.fwimage.bin` (currently 570.144). The firmware analysis pipeline is driven from `tools/ghidra/`: | Tool / artifact | Purpose | |---|---| | `tools/ghidra/analyze_fwimage.py` | headless project creation + analysis for a `.fwimage` | | `tools/ghidra/create_gsp_project.py` | build the GSP Ghidra project layout | | `tools/ghidra/diff_gsp_firmware.py`, `analyze_gsp_firmware.sh` | cross-version firmware diff / batch analysis | | `firmware/57X-GSP/570.144/analyze_firmware.py` | version-local extraction and reporting scripts | | `firmware/57X-GSP/570.144/decompiled*`, `RPC_HANDLER_MAP.md`, `FINAL_REPORT.md` | per-version decompiled handlers and maps | | `kernel/firmware_analyzer.c` (`known_signatures[]`) | runtime firmware identification used by the module | The upgrade procedure — acquire, version, decompile, diff the RPC dispatcher, update the version surface, validate, roll back safely — is [`05-operations/02` §4.1](../05-operations/02-debugging-and-maintenance-workflows.md); green-eye adds a runtime layer on top in [`debug/risc-v-gsp-rm-vm/docs/22-PORTING-CUDA-AND-DEVICES.md`](../../debug/risc-v-gsp-rm-vm/docs/22-PORTING-CUDA-AND-DEVICES.md). ## 7. Host RM oracle: rmtool, rmtop, rmq and rmharness `tools/rmtool` and `tools/rmtop` are new, read-only host-RM clients sharing one ioctl layer (`tools/rmtool/src/rm_api.c`, `query.c`); `tools/rmq` is the pre-existing device-info oracle. They allocate only an RM client/device/ subdevice handle and never create engine, channel or memory objects; write paths are refused in code. Green-eye's `rmharness/` wrappers locate, build and capture them into sessions. ```bash make -C tools/rmtool && make -C tools/rmtop tools/rmtool/rmtool gpu list --format=json tools/rmtool/rmtool engine list && tools/rmtool/rmtool mem stats ./rmharness/harness.sh --session dumps/real-rm -- rmtool engine list --format=json ``` Details: `tools/rmtool/` sources, [`rmharness/README.md`](../../debug/risc-v-gsp-rm-vm/rmharness/README.md), the tool doc [`17-RM-HARNESS.md`](../../debug/risc-v-gsp-rm-vm/docs/17-RM-HARNESS.md), and the metric use (M1/M6) in `docs/06-ACCURACY.md`. ## 8. green-eye and its subsystems `debug/risc-v-gsp-rm-vm/` is the dynamic firmware environment. Its subsystem map: `greeneye/` (Session, memory, symbols, structs, probes, record, analyze, plugins, Ghidra bridges, injection, device map, native backend), `sim/` (deterministic RV64IMAC interpreter + trace), `sdk/` (injection ABI), `qemu/` (launch helper + TCG trace plugin), `ghidra/` (Java bridge scripts), `plugins/` (example, rmharness, MCP), `harness/` (automation), `rmharness/`, `firmware/uproc_demo/` and `tests/`. ```bash cd debug/risc-v-gsp-rm-vm make demo sdk ./greeneye.sh info && ./greeneye.sh demo ./greeneye.sh probe # real fwimage: first divergence, honestly bounded ./greeneye.sh analyze dumps/ ``` The full architecture and API surfaces are [`26-ARCHITECTURE.md`](../../debug/risc-v-gsp-rm-vm/docs/26-ARCHITECTURE.md); purpose/status is [`05-operations/03-risc-v-gsp-rm-vm.md`](../05-operations/03-risc-v-gsp-rm-vm.md); the long-term program is [`GREEN-EYE-ROADMAP.md`](../../debug/risc-v-gsp-rm-vm/GREEN-EYE-ROADMAP.md). ## 9. CI and MCP * **Project CI**: `.github/workflows/ci.yml` builds the kernel module, userspace and host tests on the main tree. * **Tool CI**: `.github/workflows/greeneye.yml` installs `qemu-system-misc clang lld-18`, builds `sdk`/`demo`, and runs the tool unit tests (`python3 -m unittest discover -s tests -t .`) on pushes/PRs touching `debug/risc-v-gsp-rm-vm/**` or `tools/rm*/**`. No secrets, hardware or guest. * **Release pipelines**: `harness/version_diff.py` and `harness/ci_release.py` produce a hashed evidence bundle; the RM 610 gate is enforced before any target file is opened (`docs/21`, `docs/23`). * **MCP**: `plugins/mcp_server.py` exposes the active session as 24 JSON-RPC tools over stdio for Claude Code/opencode; read/observe by default, writes and injection explicitly gated, sessions as the audit trail (`docs/20`). ## 10. Tool table | Tool | Purpose | When to use it | Where it lives | Doc | |---|---|---|---|---| | `stack_manager.sh` | build/load/status/test/unload with correct ordering | every host-stack change or bring-up | `scripts/stack_manager.sh` | [`03-architecture/06` §7](../03-architecture/06-host-module-and-hybrid-model.md) | | `vgpu_vm.py` | VM lifecycle + guest-agent exec/shell | booting/inspecting the guest | `scripts/vgpu_vm.py` | [`05-operations/02`](../05-operations/02-debugging-and-maintenance-workflows.md) | | QEMU launch/gdb helpers | direct QEMU launches, QMP/gdbstub access | gdbstub triage, direct QEMU runs | `scripts/launch_qemu_*.sh`, `qemu_*.sh/py` | [`05-operations/02` §3.3/§3.7](../05-operations/02-debugging-and-maintenance-workflows.md) | | module debug parameters | guest-RAM scan/poke, live trace | memory-state debugging in kernel context | `/sys/module/open_iov_vfio/parameters/` | [`05-operations/02` §3.1–3.2](../05-operations/02-debugging-and-maintenance-workflows.md) | | `guest-diag` | ioctl trace, engine list, pmap | driver-side oracle for a guest failure | `tools/guest-diag/` | [`05-operations/02` §3.4](../05-operations/02-debugging-and-maintenance-workflows.md) | | `cudatool.py` | CUDA binary info/delta/crash/fdematch | every `libcuda` version bump or crash | `userspace/cuda/tools/` | [`READ-ME-FIRST` §3](../../userspace/cuda/READ-ME-FIRST.md) | | `callwalk.py` | caller/callee/path walks | tracing a crash path through the corpus | `userspace/cuda/tools/` | [`READ-ME-FIRST` §3](../../userspace/cuda/READ-ME-FIRST.md) | | `diff_corpus.py` | corpus cross-version diff | deciding port class (patch/feature/reshuffle) | `userspace/cuda/tools/` | [`docs/07`](../../userspace/cuda/docs/07-version-upgrade-playbook.md) | | CUDA Ghidra scripts | headless analysis, decompile-at, name map | building/extending the corpus | `userspace/cuda/tools/ghidra*` | [`docs/06-tooling.md`](../../userspace/cuda/docs/06-tooling.md) | | `cuda-ab/ab.sh` | deterministic host-vs-guest workload A/B | validating an emulation change end-to-end | `tools/cuda-ab/` | [`05-operations/01`](../05-operations/01-performance-correctness-security.md) | | GSP Ghidra pipeline | firmware project creation + diff | new GSP version or new firmware question | `tools/ghidra/` | [`05-operations/02` §4.1](../05-operations/02-debugging-and-maintenance-workflows.md) | | `firmware_analyzer.c` | runtime firmware signatures | registering a new image for identification | `kernel/firmware_analyzer.c` | [`05-operations/02` §4.1](../05-operations/02-debugging-and-maintenance-workflows.md) | | `rmtool` | read-only RM inventory/mem/timer oracle | ground truth for M1/M6 metrics | `tools/rmtool/` | [`17`](../../debug/risc-v-gsp-rm-vm/docs/17-RM-HARNESS.md) | | `rmtop` | ncurses dashboard; `--once` for capture | human overview / session capture | `tools/rmtop/` | [`17`](../../debug/risc-v-gsp-rm-vm/docs/17-RM-HARNESS.md) | | `rmq` | device-info tables (unmodified) | TU104 static data queries | `tools/rmq/` | [`17`](../../debug/risc-v-gsp-rm-vm/docs/17-RM-HARNESS.md) | | `rmharness` | capture host oracle runs into sessions | pairing real RM data with a sim session | `debug/risc-v-gsp-rm-vm/rmharness/` | [`rmharness/README`](../../debug/risc-v-gsp-rm-vm/rmharness/README.md) | | green-eye CLI | session lifecycle, probe, record, analyze, compare, inject, Ghidra | all dynamic firmware questions | `debug/risc-v-gsp-rm-vm/greeneye.sh` | [`00`](../../debug/risc-v-gsp-rm-vm/docs/00-OVERVIEW.md), [`02`](../../debug/risc-v-gsp-rm-vm/docs/02-USAGE.md) | | green-eye Python API | scripted instrumentation and injection | repeatable/CI-able experiments | `greeneye/`, `examples/` | [`03`](../../debug/risc-v-gsp-rm-vm/docs/03-SCRIPTING.md) | | green-eye Ghidra bridge | run-until/breakpoints from the decompiler | static↔dynamic address joins | `ghidra/`, `greeneye/gdbridge.py` | [`05`](../../debug/risc-v-gsp-rm-vm/docs/05-GHIDRA-BRIDGE.md), [`13`](../../debug/risc-v-gsp-rm-vm/docs/13-GHIDRA-CONTROL.md) | | injection SDK | PIC RV64 service blobs + ABI | prototyping a service or engine | `sdk/`, `greeneye/inject.py` | [`12`](../../debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md) | | green-eye harness | matrix, mutation, discovery, reach, version diff, release bundle, demos | porting, regression, evidence packs | `debug/risc-v-gsp-rm-vm/harness/` | [`18`](../../debug/risc-v-gsp-rm-vm/docs/18-HARNESS-AUTOMATION.md), [`19`](../../debug/risc-v-gsp-rm-vm/docs/19-CONTROL-DISCOVERY.md), [`21`](../../debug/risc-v-gsp-rm-vm/docs/21-CI-RELEASE-PIPELINE.md) | | native simulator + trace | deterministic RV64IMAC + exec/access trace | speed/determinism experiments | `sim/`, `greeneye/sim_backend.py` | [`16`](../../debug/risc-v-gsp-rm-vm/docs/16-CUSTOM-SIMULATOR.md) | | device map | first-touch MMIO data + lenient mode | device-model bring-up | `greeneye/device_map.py` | [`24`](../../debug/risc-v-gsp-rm-vm/docs/24-DEVICE-MAP.md) | | TCG trace plugin | full instruction/memory JSONL trace | coverage map when hooks are not enough | `qemu/greeneye_trace.c` | [`qemu/README.md`](../../debug/risc-v-gsp-rm-vm/qemu/README.md) | | MCP server | agent tool surface over a live session | agentic analysis/monitoring | `plugins/mcp_server.py` | [`20`](../../debug/risc-v-gsp-rm-vm/docs/20-MCP-SERVER.md) | | CI workflows | project and tool suites | every PR touching the covered paths | `.github/workflows/` | [`21` §5](../../debug/risc-v-gsp-rm-vm/docs/21-CI-RELEASE-PIPELINE.md) | ## 11. The two reverse-engineering loops Static analysis answers *what is the code*; dynamic analysis answers *what did it do*. They interlock through addresses, symbols and recorded evidence. ```mermaid flowchart LR subgraph STATIC["Static loop (Ghidra)"] A1["CUDA corpus + GSP firmware projects"] --> A2["name transfer, corpus diff,
symbol inventory diff"] A2 --> A3["hypothesis: dispatch tables,
call paths, data layouts"] end subgraph DYN["Dynamic loop (green-eye)"] B1["Session + injection on the firmware"] --> B2["observe, record, compare
sessions"] B2 --> B3["evidence: hits, watch PCs,
written pages, reply values"] end A2 -->|"symbol DB with bias
(symbols export)"| B1 B3 -->|"export_hits, fault PC,
corpus bucket:line"| A1 A3 --> C["emulation change in open-iov-vfio"] B3 --> C C --> D["physical confirmation +
regression with the same stimulus"] ``` * **Static loop**: import the binary/version into Ghidra, transfer the name map (`cudatool.py delta`/`fdematch` for CUDA; `diff_gsp_firmware.py` and the RPC map for firmware), diff the corpus, and read the changed functions. * **Dynamic loop**: boot the firmware in green-eye, instrument it, record a session, compare against a reference, and attach the session as evidence. * **Interlock**: a Ghidra symbol/address is resolved into the runtime through a symbol DB with the right bias; a runtime hit or fault PC is exported back (`export_hits`) and annotated into the project (`MarkGreenEyeHits.java`); `corpus_location()` maps a hit to its decompiled body when the index carried `bucket:line`. See the green-eye [`05`](../../debug/risc-v-gsp-rm-vm/docs/05-GHIDRA-BRIDGE.md), [`13`](../../debug/risc-v-gsp-rm-vm/docs/13-GHIDRA-CONTROL.md) and [`26` §7](../../debug/risc-v-gsp-rm-vm/docs/26-ARCHITECTURE.md). ## 12. Porting workflows at a map level Three independent churn axes; a port is a claim with evidence, not a patch. Detailed procedures are not duplicated here. | Axis | Static triage | Dynamic confirmation | Full procedure | |---|---|---|---| | New CUDA userspace (`libcuda` bump) | `cudatool.py info/delta`, `fdematch`, `diff_corpus.py`, name-map apply | guest smoke (`cuda_drv_test.c`), `cuda-ab`, symbol spot-checks | [`userspace/cuda/docs/07`](../../userspace/cuda/docs/07-version-upgrade-playbook.md); green-eye [`22`](../../debug/risc-v-gsp-rm-vm/docs/22-PORTING-CUDA-AND-DEVICES.md) §2 | | New GSP/RM firmware version | decompile + diff RPC dispatcher/controls; Ghidra symbol inventory | `greeneye probe` first-touch, scripted/re-hosted `record`, `compare`, `version_diff.py` | [`05-operations/02` §4.1](../05-operations/02-debugging-and-maintenance-workflows.md) (upgrade runbook); green-eye [`07 P1`](../../debug/risc-v-gsp-rm-vm/docs/07-PORTABILITY-PLAYBOOKS.md), [`21`](../../debug/risc-v-gsp-rm-vm/docs/21-CI-RELEASE-PIPELINE.md), [`22`](../../debug/risc-v-gsp-rm-vm/docs/22-PORTING-CUDA-AND-DEVICES.md) §3 | | New device / architecture | device profile data, ISA/image shape, PMU/SOE deltas | portability matrix, probe first-touch on the new image | [`06-portability/hardware-software-matrix.md`](../06-portability/hardware-software-matrix.md); green-eye [`07 P2/P3`](../../debug/risc-v-gsp-rm-vm/docs/07-PORTABILITY-PLAYBOOKS.md), [`18`](../../debug/risc-v-gsp-rm-vm/docs/18-HARNESS-AUTOMATION.md) | | A/B accuracy ritual (real vs emulated) | M1–M6 metric definition | hardware/VFIO reference capture vs green-eye session | [`05-operations/01`](../05-operations/01-performance-correctness-security.md); green-eye [`06`](../../debug/risc-v-gsp-rm-vm/docs/06-ACCURACY.md), [`07 P4`](../../debug/risc-v-gsp-rm-vm/docs/07-PORTABILITY-PLAYBOOKS.md), [`25`](../../debug/risc-v-gsp-rm-vm/docs/25-VALUE-VALIDATION.md) | | RM 610 family | — | gate first; nothing opened before approval | green-eye [`23`](../../debug/risc-v-gsp-rm-vm/docs/23-RM610-READINESS.md) (hard gate), [`21` §3](../../debug/risc-v-gsp-rm-vm/docs/21-CI-RELEASE-PIPELINE.md) | The fast pipeline for a GSP version is: `harness/version_diff.py` → `harness/portability_matrix.py` → `harness/mutation_harness.py`, wrapped by `harness/ci_release.py --dry-run` first, with the resulting bundle attached to the change. The diagonal rule holds everywhere: static analysis proposes, the dynamic session disposes, and physical confirmation gates any product change. ## 13. Environment invariants 1. **The guest is stock**: no Open-IOV code, agent, driver patch or extra kernel parameters in the guest, ever. 2. **Tools are in-tree**: no tools in `/tmp`; artifacts survive reboots and are reviewable. 3. **Read-only host tools stay read-only**: `rmtool`/`rmtop`/`rmq`/`rmharness` refuse write operations in code; no module load/unload, mdev churn or `/sys/fs/pstore` access. 4. **No unattended physical-GPU cycles**; physical confirmation is supervised and explicit. 5. **Simulator/re-hosted code is a study environment**: never shipped, never a dependency, no confidentiality/isolation/timing claims. 6. **Evidence or it did not happen**: sessions, hashes and the M1–M6 table accompany any portability or accuracy claim. 7. **Versioned, parallel directories**: firmware, CUDA versions and profiles are added, never overwritten; rollback never destroys a working anchor. 8. **Provenance discipline**: tracked docs describe components and behaviour; conclusions cite recorded evidence. ## 14. Reading paths * **New contributor**: [`onboarding-and-standards.md`](onboarding-and-standards.md) → this document → the subsystem doc for what you will touch. * **CUDA bring-up**: [`../../userspace/cuda/READ-ME-FIRST.md`](../../userspace/cuda/READ-ME-FIRST.md) → `docs/01`, `docs/03`, `docs/05` → `docs/22` for porting. * **Firmware/green-eye**: [`05-operations/03-risc-v-gsp-rm-vm.md`](../05-operations/03-risc-v-gsp-rm-vm.md) → tool [`00`](../../debug/risc-v-gsp-rm-vm/docs/00-OVERVIEW.md), [`26`](../../debug/risc-v-gsp-rm-vm/docs/26-ARCHITECTURE.md), then [`03`](../../debug/risc-v-gsp-rm-vm/docs/03-SCRIPTING.md), [`19`](../../debug/risc-v-gsp-rm-vm/docs/19-CONTROL-DISCOVERY.md) and [`21`](../../debug/risc-v-gsp-rm-vm/docs/21-CI-RELEASE-PIPELINE.md) as needed. * **Host stack / VM**: [`03-architecture/06-host-module-and-hybrid-model.md`](../03-architecture/06-host-module-and-hybrid-model.md) and [`05-operations/02-debugging-and-maintenance-workflows.md`](../05-operations/02-debugging-and-maintenance-workflows.md). * **Portability**: [`06-portability/hardware-software-matrix.md`](../06-portability/hardware-software-matrix.md) plus green-eye `docs/07` and `docs/22`. Every path in this document was verified at the time of writing; when a tool moves, update this table first — it is the front door.