diff --git a/.github/release-notes.md b/.github/release-notes.md
index 216ba42c..c9f087d7 100644
--- a/.github/release-notes.md
+++ b/.github/release-notes.md
@@ -8,7 +8,7 @@
> The full single-player campaign runs at a steady 60 fps with audio (music +
> SFX) playing throughout, on Windows and Linux including Steam Deck, and it
> is completable end to end: the whole campaign has been playtested through
-> all 21 missions (Agent difficulty). It's an early public cut: all 21 solo
+> all 20 missions (Agent difficulty). It's an early public cut: all 20 solo
> missions load and run crash-free, but the known issues below are real;
> feedback is very welcome. **This is a pre-1.0 release, not a finished
> product** — expect rough edges and missing features until v1.0; see the
diff --git a/.github/social-preview.html b/.github/social-preview.html
index 4b6115e4..2050c42c 100644
--- a/.github/social-preview.html
+++ b/.github/social-preview.html
@@ -126,7 +126,7 @@
Status: RELEASED v0.3.0 — WINDOWS · LINUX · STEAM DECK
- Statistics:All 21 solo missions — full campaign completed in playtesting
+ Statistics:All 20 solo missions — full campaign completed in playtesting
~230 game-code units, compiled unmodified
~24k lines C/C++ · ~7k Python (port layer + tools)
199 findings root-caused · two coding agents, one human, part-time
diff --git a/.github/social-preview.png b/.github/social-preview.png
index 59a0844b..60ae6e0e 100644
Binary files a/.github/social-preview.png and b/.github/social-preview.png differ
diff --git a/AGENTS.md b/AGENTS.md
index 1c53f3bd..680ee103 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -51,8 +51,9 @@ Run `/linkcheck` for this sweep. Record new findings in `docs/dev/findings.md`
- **Phase 0–1.5:** done. Build system, boot chain, OS-shim layer, fast3d
integration, first frames, full intro rendering.
-- **Phase 2 (rendering):** in progress. All 21 solo levels load + render +
- survive an unattended window; front end (menu → mission select → briefing →
+- **Phase 2 (rendering):** in progress. All 20 solo missions (plus the
+ ending-credits sequence, `-level_54`) load + render + survive an
+ unattended window; front end (menu → mission select → briefing →
start) is functional; file-backed EEPROM saves work. Cosmetic defects are
parked in `docs/dev/GRAPHICS-BACKLOG.md`.
- **Phase 3 (audio + input):** input layer done (`port/src/input.c`); polish
diff --git a/README.md b/README.md
index 6afe004d..69febc4f 100644
--- a/README.md
+++ b/README.md
@@ -73,9 +73,10 @@ listed plainly there.
## Status
**v0.3.0 - playable, with known rough edges.** The full single-player
-campaign is completable end to end (all 21 missions, Agent difficulty,
-playtested), at a steady 60 fps; all 21 solo missions load, render and run
-crash-free, verified on Windows, Linux and real Steam Deck hardware. Feedback
+campaign is completable end to end (all 20 missions, Agent difficulty,
+playtested), at a steady 60 fps; all 20 solo missions — plus the
+end-of-campaign credits sequence — load, render and run crash-free, verified
+on Windows, Linux and real Steam Deck hardware. Feedback
is very welcome.
What a release actually installs (no networking, no telemetry, no ROM or
@@ -84,8 +85,8 @@ game's logic: [Security & fidelity status](docs/security-and-fidelity-status.md)
**Working:** boot sequence and front end (menu → mission select → briefing →
start), front-end menu navigation on the left stick to match the F10 overlay
-(D282); all 21 solo missions load, render and are crash-free (full campaign
-playtested end to end at Agent difficulty); steady 60 fps
+(D282); all 20 solo missions load, render and are crash-free (full campaign
+playtested end to end at Agent difficulty, including the ending sequence); steady 60 fps
(software RSP off the presentation critical path); full audio: in-level music and SFX; keyboard + mouse (click-to-lock, proportional aim mode, a single
simplified sensitivity control) and a modern dual-stick controller layout;
automatic widescreen FOV scaling; Bond is fixed in cutscenes (no more
diff --git a/docs/dev/LEVEL-PLAYTEST.md b/docs/dev/LEVEL-PLAYTEST.md
index 92754c3b..4753d680 100644
--- a/docs/dev/LEVEL-PLAYTEST.md
+++ b/docs/dev/LEVEL-PLAYTEST.md
@@ -47,7 +47,7 @@ Objective status: `src/game/objective_status.c`
- Notes / defects:
```
-## 21 solo levels (mission order — numbers = `-level_XX`)
+## The 20 solo missions (+ ending sequence; mission order — numbers = `-level_XX`)
| # | Level | -level | Briefing asset |
|---|---|---|---|
@@ -71,7 +71,14 @@ Objective status: `src/game/objective_status.c`
| 18 | Cradle | 41 | UbriefcradZ |
| 19 | Aztec | 28 | UbriefaztZ |
| 20 | Egypt | 32 | UbriefcrypZ |
-| 21 | Cuba | 54 | (post-Egypt unlock) |
+| — | *Ending sequence* ("Cuba") | 54 | not a playable mission — cast/credits stage (D129) |
-(Mission table: `front.c:433`. Cuba = `LEVELID_CUBA`, not in the standard
-folder list — unlocked after Egypt.)
+(Mission table: `front.c`, `mission_folder_setup_entries` — exactly 20
+playable missions; the game's own enum says it, `SP_LEVEL_MAX // 20` in
+`bondconstants.h`). "Cuba" (`-level_54`, `LEVELID_CUBA`) is **not** a
+selectable mission: after the final mission the front end jumps straight to
+it for the extended cast display + credits scroll
+(`front.c` `selected_stage = LEVELID_CUBA` → `do_extended_cast_display(TRUE)`;
+`bondviewRenderCredits`, D129). Older docs and sweep logs count it as a 21st
+"level" — the campaign is 20 missions; "21/21" sweep results mean 21 stage
+boots, of which 20 are missions.)
diff --git a/docs/dev/LEVEL-STATUS.md b/docs/dev/LEVEL-STATUS.md
index 1df06f67..bb217a57 100644
--- a/docs/dev/LEVEL-STATUS.md
+++ b/docs/dev/LEVEL-STATUS.md
@@ -1,4 +1,10 @@
-# LEVEL-STATUS — 21 solo-level load+render sweep (WS4)
+# LEVEL-STATUS — level load+render sweep (WS4) — 20 solo missions + ending sequence
+
+**Counting note:** the campaign is **20 playable missions** (`SP_LEVEL_MAX //
+20` in `bondconstants.h`; `mission_folder_setup_entries` in `front.c` has
+exactly 20 entries). The sweep's 21st boot target, "Cuba" (`-level_54`,
+`LEVELID_CUBA`), is the end-of-campaign cast/credits stage (D129), not a solo
+mission — so "21/21 PASS" below means *21 stage boots*, 20 of them missions.
Method: bare `./build-pc/ge007.x86_64.exe -level_XX` (per-level `-m*` pools
auto-injected, D121), `GE_PCDUMP="80-260:40"`, ~24 s watchdog then
diff --git a/docs/index.md b/docs/index.md
index f920a944..1fbb8b20 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -19,7 +19,7 @@ as the [Perfect Dark PC port](https://github.com/fgsfdsfgs/perfect_dark), the
same Rare "Indy" engine family, one hardware generation apart.
**Status: v0.3.0.** The full single-player campaign runs at a steady 60 fps
-and is completable end to end (all 21 missions playtested); all 21 missions
+and is completable end to end (all 20 missions playtested); all 20 missions
load and run clean on Windows, Linux and Steam Deck, and audio (music + SFX)
plays throughout. The known rough edges — mostly cosmetic rendering defects,
stretched-not-native widescreen, and missing features — are listed plainly
diff --git a/docs/security-and-fidelity-status.md b/docs/security-and-fidelity-status.md
index 560ccca3..47e61657 100644
--- a/docs/security-and-fidelity-status.md
+++ b/docs/security-and-fidelity-status.md
@@ -82,7 +82,8 @@ port of the N64's PRNG, but wasn't — a shift-operation helper didn't match
the real MIPS64 instruction semantics it was meant to mirror. This was
independently confirmed by hand-tracing the assembly against the C port,
tracked as finding D284, and fixed before the release (verified clean
-across a full 21-level sweep, no crashes). It affected loot placement, AI
+across a full level sweep — all 20 missions plus the ending sequence —
+no crashes). It affected loot placement, AI
behavior variance, and replay-state determinism from the very first random
draw, in every release before v0.3.0. Because of the fix, RNG-derived
output — including the save-file CRC — changed, which meant existing save