This directory holds Architecture Decision Records (ADRs) — short documents that capture a significant architectural or design decision, the context that forced it, and the consequences we accept by making it.
5thPlanet is an accuracy-first emulator built one chip at a time, and a
lot of its design is load-bearing in non-obvious ways (the Bus stall
contract, the queue-and-drain pattern, why the SCU-DSP is a separate
crate, why we keep a local Yabause build around). CLAUDE.md documents
what the architecture is; ADRs record why it is that way, so a future
contributor (or a future us) doesn't relitigate a settled choice or
quietly undo it.
We use Michael Nygard's lightweight format — see
template.md. Each ADR has:
- Status —
Proposed→Accepted→ (later)Superseded by NNNN/Deprecated. - Context — the forces at play; what made a decision necessary.
- Decision — what we chose, stated in active voice ("We will …").
- Consequences — what becomes easier and what becomes harder.
- Alternatives considered — options weighed and why they lost.
- One file per decision:
NNNN-kebab-case-title.md,NNNNzero-padded and monotonically increasing. Never renumber. - ADRs are append-only: once
Accepted, don't rewrite the decision. If it changes, write a new ADR that supersedes the old one and flip the old one's status toSuperseded by NNNN. - Keep them short (a screen or two). Link to code,
CLAUDE.mdsections, anddoc/glossary.mdterms rather than duplicating them. - A new ADR lands in its own
docs(adr): …commit.
| ADR | Title | Status |
|---|---|---|
| 0001 | Record architecture decisions | Accepted |
| 0002 | Accuracy over performance (no JIT/dynarec) | Accepted |
| 0003 | Bus returns stall cycles; host owns wait-state math |
Accepted |
| 0004 | Event-driven scheduler with deterministic "smallest deadline wins" | Accepted |
| 0005 | Queue a side effect, drain it at the aggregate | Accepted |
| 0006 | SCU-DSP is a standalone crate, not a saturn module |
Accepted |
| 0007 | Workspace-wide unsafe_code = "forbid" |
Accepted |
| 0008 | Hand-rolled, software-composited frontend OSD | Accepted |
| 0009 | Live physical-disc reads via a feature-gated libcdio FFI crate | Accepted |
| 0010 | Optional HLE direct boot (load the 1st-read program, bypass the BIOS CD loader) | Superseded |
| 0011 | HLE the BIOS system-call library for cold direct boot | Superseded |
| 0012 | HLE the SCSP 68k sound driver (synthesis stays LLE) | Rejected / Removed |
| 0013 | Render-pipeline worker thread (offload only the read-only render edge) | Accepted |
| 0014 | Audio-paced emulation loop: real-time clock, reserve buffer, prebuffer | Accepted |
| 0015 | The CD-block is high-level-emulated — the one LLE exception | Accepted |
| 0016 | The live SH-2 pair is stepped master-leads-slave, not by the generic scheduler | Accepted |
| 0017 | Reference emulators are local, never-committed oracles — no code derived | Accepted |
| 0018 | Whole-machine bincode save states; external media referenced, not embedded | Accepted |
| 0019 | Frontend graphics are software-composited; the GPU is for presentation only | Accepted |
| 0020 | Migrate the SDL frontend from SDL2 to SDL3 | Accepted |
| 0021 | Per-access BSC bus-timing model (faithful Mednafen port) | Accepted (DMA-halt part superseded by 0025) |
| 0022 | Event-driven SH-2 on-chip FRT/WDT timers + INTC (lazy materialize) | Accepted |
| 0023 | Save-file keying: save states per game disc, internal backup RAM per BIOS | Accepted |
| 0024 | PGO is the one sanctioned performance lever (build-time only, bit-identical) | Accepted |
| 0025 | The SCU DMA halts neither SH-2 (synchronous copy at the trigger) | Accepted |
| 0026 | Processor cores are no_std, library-shaped, dependency-free |
Accepted |
| 0027 | Regression correctness pinned to deterministic golden fingerprints | Accepted |
| 0028 | Backup-RAM cartridge as multiple virtual memory cards (OSD-managed .crtbup files) |
Accepted |
Significant choices already made in code/CLAUDE.md that are good
candidates for retroactive ADRs:
- Config file location is portable-first — a
jupiter.tomlbeside the executable wins over$XDG_CONFIG_HOME(for self-contained release archives;jupiter/src/config.rs,Config::path). A real distribution-strategy decision with a clear undo risk (a contributor preferring XDG-only or Windows-AppData-first), but lower-stakes than the core ADRs — promote it to a full ADR if the precedence is ever questioned.