RELEASE
planning/2.8.5/audits/FO3/AUDIT_FO3_U7.md
sha256 9b134221070685a5 · 14873 bytes ·
original held in the private archive
# FO3 PIP-BOY — UNIT U7 · PROTOCOL 8 STAGE 3 (INDEPENDENT AUDIT)
**Auditor:** Opus (stage 3 — independent audit). **No code changed. No commit. No push.**
**Commits audited:** `954476c` + `d52299f` on `dev` (the `01093bf` CI commit was excluded — I
re-ran the diff as `01093bf..d52299f` to isolate U7's real work from the CI/Node-pin changes).
**Predecessor checklist:** `planning/AUDIT_FO3_U6.md`.
**Method:** started from the diff and the pixels, not the implementer's report. Read every line of
`tests/render-integrity.mjs` and every allowlist entry. Ran the guard four ways (normal, raw
`RI_NO_ALLOWLIST`, and two `--only` red-then-green breaks I introduced myself and reverted).
Captured my own Playwright screenshots of all six FO3 landscape boards + FO3 desktop + FO3
portrait + NV at 360/412/desktop, and opened and looked at every one. Ran the 3187-test Node gate
myself.
**Verdict: PASS.** Both headline risks from U6 are genuinely fixed and now honest; the
render-integrity guard genuinely asserts more (proven, not assumed); the one real remaining defect
is honestly flagged in three places, not silenced. A short non-blocking punch-list is at the bottom.
---
## THE ONE-LINE ANSWER (for the phone)
**Yes — the glass reads as a real Pip-Boy now, honestly.** The top-of-screen label finally tells
the truth about which screen you're on (it says ITEMS on the cargo screen, STATS on the character
screen — I checked every board with my own eyes). Health, radiation, and status effects now sit
together on the character screen without scrolling. S.P.E.C.I.A.L. fits all seven. There's no red
left on the Fallout 3 glass. And — the big one this review existed to check — the automated
screen-check now genuinely tests twelve setups instead of one, it really did find and fix several
long-standing bugs on both games, and the one bug it found that wasn't fixed is loudly written down
as a to-do in three places instead of being quietly swept under a rug. This is the clean, honest
version of the unit. Ship it.
---
## THE U6 DEFECT LIST — VERIFIED EACH, INDEPENDENTLY
### 1 · Top-strip stuck on STATS + the false changelog line — ✅ FIXED (both halves)
- **Code:** `_syncBezelNav()` — the one choke point every subsystem switch funnels through — now
calls `_renderFo3TopStrip()` (js/ui/ui-core-nav.js). Confirmed by reading the diff.
- **Pixels:** my own screenshots show the name chip reads **STATS** on STATUS/SPECIAL/SKILLS/PERKS/
GENERAL (all under the `operator` subsystem — correct) and flips to **ITEMS** on MANIFEST (the
`operations` subsystem). The exact bug U6 caught is gone.
- **Changelog:** the false line is corrected and now *true* — "the top readout strip now leads with
the name of whichever screen you're currently on, **updating correctly the moment you switch
screens**." Not softened, not deleted — made accurate.
- **Regression test:** Suite 224.12b runs the real extracted `_renderFo3TopStrip()` against two
subsystem values and asserts the chip renders "STATS" for `operator` and "ITEMS" (not still
"STATS") for `operations` — it asserts the **value**, not merely the presence, which is exactly
the blind spot U6 named. 224.12a statically locks the `_syncBezelNav()` call. Genuine strengthening.
### 2 · render-integrity claimed 12 setups, ran 1 — ✅ FIXED (now genuinely runs 12)
- `buildMatrix()` returns **12** entries: {FO3 landscape, FO3 portrait, FO3 desktop} × {populated,
empty} + {NV 360, NV 412, NV desktop} × {populated, empty}. I counted them and ran the full
matrix — it exercised all twelve (≈60s wall-clock, matching the "~61s" claim; the old "~85s/12-load"
header is replaced with an accurate description).
- The stale "(FO3 landscape)" label in `tests/render-check.mjs`'s gate call is also corrected to
name the full matrix.
- The guard **is** wired into the push gate: `render-check.mjs` calls `runRenderIntegrity(browser)`
and adds its failures to the gate's `failed` total, so a red here fails `npm run gate`. Not orphaned.
### 3 · STATUS right vitals column stacked tall, RAD/EFFECTS off the bottom — ✅ FIXED
- Rebuilt in css/60-fo3-pipboy.css as a compact, independently-scrolling `#opVitalPanel` with
CONDITION and RAD ordered first via CSS `order` (a pure reflow — no DOM move, so every id/handler
stays put).
- **Pixels:** on my 780×360 STATUS screenshot, CONDITION (HP 22/100, CRITICAL), RAD (RADS 780
slider) **and** the "Well Rested" active effect are all visible at once without scrolling — the
exact thing U6 said was pushed off the bottom. GRADE/level/XP/RAD-AWAY/EQUIPPED are still present,
one scroll down (Protocol 26 — nothing deleted).
### 4 · Density (SPECIAL 6/7, MANIFEST 2–3 rows) — ⚠️ MOSTLY FIXED (SPECIAL fully; MANIFEST partial)
- **SPECIAL: fully fixed.** My screenshot shows all seven rows (STRENGTH→LUCK) on screen with fill
bar + stepper each. The changelog's "fits all seven attributes" is true.
- **MANIFEST: improved but still short of the mockup's 6.** A real box-sizing bug was fixed (the
base row had no `box-sizing:border-box`, so a 28px min-height row was actually rendering ~36px);
the redundant "WEAPONS DRAWER" title and a dead empty-action wrapper were dropped. But the
full-width **"FILTER DRAWER (OPTIONAL)…"** row is still present, leaving ~4–5 item rows visible,
not 6. The changelog does not overclaim here (it says "dropped its redundant drawer label and
tightened its spacing" — both true — and does not promise 6 rows). Honest partial progress, not a
false claim. Non-blocking; see punch-list.
### 5 · CRIP vs CRIPPLED wording — ⚠️ LEFT AS-IS, DELIBERATELY, DISCLOSED
The limb box still says "CRIP" while the Vault Boy figure says "CRIPPLED." The commit states this is
deliberate — the box abbreviation is shared code with New Vegas. Reasonable and disclosed; the owner
may still want it unified. Minor.
### 6 · Red on the glass — ✅ FIXED (and correctly scoped)
- **Pixels:** on FO3 landscape the crippled limb is dashed "CRIP" with **no red**; the HP bar is
green even at 22/100; "CRITICAL" is green; S.P.E.C.I.A.L. rad-debuffed inputs are green with a
dashed border. All-green discipline holds.
- Every red-removal rule is scoped `[data-game='FO3']` inside the landscape media block, so FO3
**portrait** (the legacy flat view) correctly still shows its red HP bar — "portrait untouched"
is respected. The `.rad-debuffed` class (js/ui/ui-core.js) adds a non-color dashed signal so
meaning never rides on color alone (Protocol 17).
---
## ⭐⭐ THE HIGHEST-RISK THING — THE RENDER-INTEGRITY GUARD — AUDITED HARDEST
### Does it genuinely assert MORE, or just look bigger? — **It genuinely asserts more.**
This was the whole question, and the answer is favorable, with one precision caveat.
- **It runs 12 configs, not 1** (counted + executed).
- **It found real, previously-invisible bugs that were then FIXED** — I proved two of them myself
with red-then-green demonstrations in **newly-covered** configs:
- **NV (new coverage):** reverting the U7 `.cyc`/`.del` fix turned the guard **red** on the NV
quest board with contrast **1.33:1 and 2.91:1** — matching the commit's claimed "~1.3–2.9:1"
exactly. Restored → green.
- **FO3 desktop (a config U6 could not see at all):** reverting the U7 `.stlamp-purge` fix turned
it **red** on STATUS at **1.40:1** — matching the claimed "~1.4:1." Restored → green.
These prove both that the new configs are really being asserted against, and that the fixes are
real (removing them reproduces the bug the commit says it found).
- **On the FO3 rail boards (the real design target), nothing is filtered at all** — full strictness.
The three assertions that caught the real bugs (contrast, clip, truncation) run **unfiltered on
all 12 configs.**
### The allowlist — read every entry. Is anything real being silenced? — **No, not today.**
- The allowlist (`filterKnownPreexisting`) only touches the **`occluded`** finding type, and only on
the **flat view** (NV + FO3 portrait — labels with no "/"). On the FO3 rail boards it does nothing.
- I ran the full matrix with `RI_NO_ALLOWLIST=1`. It surfaces **14 occlusion failures, every single
one a bezel-dock element** (`#bezelTelemetry`, the six `#navkey-*` keycaps, the dock's `<nav>`, and
the dock's own id-less `<div>`/`<span>` decoration layers). Nothing non-dock is being suppressed.
The commit's "84 → 14, all one root cause" endpoint is **verified true** (I can't reproduce the
historical intermediate 84→54→26→15 counts — those were pre-fix states — but the endpoint is exactly
what I observe).
- The remaining defect is **honestly flagged, not silenced** — the fixed dock covering scrolled
content is documented loudly in the guard's own header, in a purpose-named
`CONFIRMED_PREEXISTING_DEFECT_BEZEL_DOCK_OCCLUSION_HITS` set (not a vague allowlist), in
`QUEUE.md`, and in the commit message. I confirmed all three. This is the correct handling of a
real-but-out-of-scope defect, and it is the exact opposite of the U6-era antipattern (adding real
defects to an allowlist to reach green) — the follow-up commit `d52299f` was written specifically
to undo that antipattern, and it does.
### The one precision caveat (non-blocking, but flag it)
The allowlist matches occluders by **bare tag name** — the set contains literal `'DIV'`, `'SPAN'`,
`'NAV'` alongside the specific `#bezelTelemetry`/`#navkey-*` ids. Those bare entries mean a **future**
occlusion whose hit target is *any* id-less `<div>`/`<span>`/`<nav>` on the flat view would be
silently filtered — which contradicts the file's own claim that "a NEW occlusion finding whose hit
target is NOT one of these exact bezel-dock elements still fails the gate normally." Today this masks
nothing (verified: every id-less div/span/nav occluder currently *is* the dock). But it is exactly
the kind of over-broad filter that can rot into a real silenced bug later. **Recommend tightening** to
scope by `hit.closest('.bezel')` rather than tag name, in a follow-up. Not a reason to bounce U7 — no
real defect is hidden now — but it should not be left indefinitely.
---
## WEAKENED / NARROWED ASSERTIONS — THE HUNT
- **Suite 224.2 was genuinely NARROWED** from "all 12 pre-existing CSS files are byte-identical" to
"8 of them are" — the four U7 touched (`10-chrome`, `25-toolbar`, `35-operator-boards`,
`45-databank`) were removed from the byte-identical check. **This is real narrowing of an existing
assertion** — the single most important thing this stage hunts for. My verdict: it is **honest and
justified, not covert.** Each of the four changes is a small, disclosed, cross-game bug fix (a
contrast background, a padding reserve, two spinner-strips), each carries its own comment at the fix
site, and the narrowing is documented in 224.2's own expanded comment. I independently confirmed NV
still renders correctly at 360/412/desktop with my own screenshots, and the broadened
render-integrity NV coverage now guards those files instead. So the strong "NV byte-identical"
proof is legitimately weaker for four files, but NV-correct is still proven, by pixels.
- **No covert loosening anywhere else.** The entire test diff across both commits is confined to
Suite 224: the 224.2 narrowing (disclosed) and the 224.12 additions (value-correctness —
strengthening). No regex was quietly loosened; I read every changed hunk. Count moved 3185 → 3187
(the two new 224.12 checks), and I ran the runner myself: **ALL 3187 TESTS PASSED.**
## PROTOCOL / HYGIENE CHECKS
- **Protocol 38:** every FO3-specific rule (red-removal, vitals reflow, density) is scoped
`[data-game='FO3']`; the four cross-game fixes are deliberately unscoped because they fix both
games — correct and disclosed. No hardcoded game literals introduced.
- **Nothing became read-only.** MANIFEST item actions moved into the detail pane (one extra tap the
first time you act on a freshly-selected item — disclosed in the changelog); no control was lost.
Perk delete stays one-tap, STATUS steppers present. Verified against screenshots.
- **Protocol 1:** cache bumped r20 → r22. **Protocol 2/2a:** counts synced to 3187 everywhere,
CHANGELOG header shows `3187/3187 | Cache …-r22`, no stale 3185 remains. **Protocol 13:** top-strip
bug → 224.12; the cross-game CSS fixes → guarded by the broadened render-integrity gate; the dock
defect is deferred, so no test is owed. **Protocol 41:** clean tree (I removed my own scratch
harness; the audit PNGs live under gitignored `planning/`).
- **Deploy:** `d52299f` is on **origin/dev** (local `dev` == `origin/dev`). Landed, not just local.
## CHANGELOG ACCURACY — every claim checked against the running app
All verified true: "fits all seven attributes" (✓), "updating correctly the moment you switch
screens" (✓), "radiation exposure and active status effects visible without scrolling" (✓), "no
longer flash red … stay the same green" (✓), "dropped its redundant drawer label and tightened its
spacing" (✓ — the label is gone; it does not claim 6 rows), and the three Fixed-section items
(narrow number fields clipping, dock reserve a few px short, quest buttons unreadable) — all
reproduced and confirmed. **No false or overstated line found** — the exact failure this stage
exists to catch, and this time there isn't one.
---
## PUNCH-LIST (all non-blocking — for a future polish/cleanup unit, not a Stage-2 bounce)
1. **Tighten the render-integrity allowlist** to match the dock by `hit.closest('.bezel')` instead
of bare `'DIV'`/`'SPAN'`/`'NAV'` tag names, so a future non-dock occlusion on the flat view can't
slip through. (Highest-value item — closes a latent false-confidence gap.)
2. **MANIFEST density:** drop or inline the "FILTER DRAWER (OPTIONAL)…" row to reach the mockup's ~6
visible item rows; consider the short drawer labels (WPN/APP/AID) and an ALL drawer from U6's
finding E.
3. **CRIP / CRIPPLED wording** — unify if the owner wants it (currently deliberate, disclosed).
4. **FO3 desktop** still squeezes the glass above the AI channel — the known, explicitly-deferred
desktop-stack gap (not U7's job; noted only so it isn't forgotten).
5. Minor residual red: the perk-slot delete "✕" buttons on the FO3 landscape glass are still
red-bordered — outside U7's stated red-removal scope (HP/SPECIAL/CRITICAL), but worth a look if
"single green screen" is meant to be absolute.
---
*End of Stage 3. No code was changed, no commit made, no push. My two temporary red-then-green
edits were reverted (working tree clean). Evidence screenshots saved as
`planning/mockups/fo3/audit-u7-*.png` (gitignored).*
STAMP · generated for RELEASE v2.8.5 commit 06e5180 (06e51801b38a) · archive input-tree hash c07fbfbdd2e1ddeb · 754 files · no wall-clock timestamp (regenerates identically when nothing changed).