GENERATED VIEW · PRIVATE ARCHIVE · DO NOT SERVE
RobCo Industries · Archive Museum

DIEGETIC_AUDIT.md



RELEASE

planning/2.8.0/audits/DIEGETIC_AUDIT.md

sha256 a83871da54106bc8 · 12750 bytes · original held in the private archive

# RobCo U.O.S. — Site-Wide Diegetic Audit (Stage A0) > **FILED UNDER 2.8.0 — PRODUCED-BY, NOT MEASURED-VERSION.** This document *measures* an earlier codebase > (see its baseline stamp below), but it was *produced* as part of the audit/planning phase that became the > 2.8.0 overhaul. Planning artifacts are filed by the release whose work produced them, never by the version > they discuss. The version in the title or baseline is the code it examined, not the folder it belongs in. > (A 2.5.0 and 2.6.0 folder do exist, holding feature designs for features that shipped in those releases. There > is no 2.7.0 folder because no artifact has been identified as produced during 2.7.0.) > Plan-only. Measured against `HOUSE_STANDARD.md`. Targets `origin/main` @ `bc8c2eb` (v2.6.0, cache r1, 1078 tests). > Untracked planning doc — feeds later chain stages. **Nothing built.** ## House Standard summary (yardstick) Voice = `> ` prompt prefix · ALL-CAPS chrome · bracketed `[STATUS]` · period-leader progress · terse machine register · `⚠` faults. Palette = phosphor `#14fdce` / amber / red / blue on near-black, monospace, scanlines, no modern GUI chrome. Terminology locked (TERMINAL not "app", COMM-LINK not "chat", CAMPAIGN CONFIGURATION not "settings", UPLINK not "sign in", RETRIEVING… not "Loading…", VISUAL UPLOAD not "upload"). Guardrails: ARIA literal, AA contrast, ≥16px inputs, keyboard order preserved, **CRT motion must honor prefers-reduced-motion**. ## Coverage matrix (screens × states — provable enumeration) | Surface | Loading | Empty | Error | Offline | Auth | Success | Verdict | |---|---|---|---|---|---|---|---| | Boot / TERMLINK shell | ✅ canon | — | ⚠ BOOT DATA FAILED ✅ | n/a | n/a | ✅ | **canon** | | Header / status line | n/a | n/a | n/a | n/a | n/a | n/a | ✅ canon | | COMM-LINK (chat) | ✅ (typewriter) | ✅ sys init | ✅ SYS-ALERT/FATAL | local-ok | n/a | ✅ telemetry | mostly canon; error tails MN-9 | | STAT tab (BIO-METRICS/SKILL MATRIX/SPECIAL/BOOKS/MAGAZINES/PERKS) | n/a | MN-7 | n/a | n/a | n/a | n/a | placeholders MN-6, empties MN-7 | | INV tab (BACKPACK/AMMO/COLLECTIBLES/CRAFTING) | n/a | MN-7 | n/a | n/a | n/a | n/a | empties MN-7, VISUAL UPLOAD MN-8 | | DATA tab (QUEST/STATUS/SQUAD/FACTION/KARMA/NOTES/STATS/MAP/CROSSROADS/TIMELINE) | n/a | MN-7 | n/a | n/a | n/a | n/a | empties MN-7 | | CAMPG tab (CONFIGURATION) | n/a | n/a | n/a | n/a | n/a | n/a | ✅ mostly canon | | Security & Config (saves/key/audio/optics) | MJ-3 | n/a | ✅ SYS-ALERT | local-ok | n/a | ✅ | upload MN-8, key tail MJ-5 | | ACCOUNT / cloud archives | MJ-3 "Loading saves…" | MJ-3 "No saves found." | MJ-3 "Failed to load" | local-ok | **MJ-2** sign-in copy | ✅ SYNC COMPLETE | **MJ-2/MJ-3** | | Update modal | n/a | n/a | n/a | n/a | n/a | n/a | PO-10 | | Out-of-frame (manifest/shortcuts/title/icon) | — | — | — | — | — | — | **MJ-4** | | Motion / a11y (all tabs) | — | — | — | — | — | — | **CR-1** + TN-13 | --- ## CRITICAL ### CR-1 · [GUARDRAIL / INTERACTION] `css/terminal.css` (≈20 `@keyframes`: flicker, header-pulse, rad-pulse/shift/chaos, vats-scan, cursor-blink, phosphor-ghost, weight-sag/buckle, karma flashes, crit-hp-flash, badge-pop, refresh-bar) + boot type-out - **What:** Zero `prefers-reduced-motion` gating anywhere (`grep prefers-reduced-motion css/ = 0`). Every CRT animation + the boot type-out runs unconditionally. - **Why it breaks the lens:** The lens's own guardrail mandates CRT flicker/scanline/type-out honor reduced-motion. Unguarded flicker/flash is a vestibular/photosensitivity hazard — the one place immersion must yield to usability. - **In-world fix:** Add `@media (prefers-reduced-motion: reduce) { … }` that freezes the decorative loops (flicker/pulse/scan/ghost/sag/flash) to their resting phosphor state and reduces the boot type-out to an instant static panel. The *static* CRT look (scanlines, glow, monospace) stays — only motion is calmed. - **VERDICT:** SPEC-FIRST · `[TEST][CACHE]` (css served → bump; add a static guard that a `prefers-reduced-motion` block exists, both runners). - **Files:** `css/terminal.css` (+ `tests/check-persistence.{js,ps1}`). --- ## MAJOR ### MJ-2 · [VOICE / AUTH] `js/ui-account.js:41–53` - **What:** `NOT SIGNED IN — saves are local only.` / `> SIGN IN WITH GOOGLE (SYNC ACROSS DEVICES)` / `SIGNED IN`. - **Why:** "Sign in / signed in / sync across devices" is modern-web auth vocabulary on a primary panel. - **In-world fix (copy only — mechanic untouched):** `UPLINK OFFLINE — ARCHIVES STORED LOCALLY` / `> ESTABLISH GOOGLE UPLINK — SYNC TELEMETRY ACROSS TERMINALS` / `UPLINK ACTIVE`. The Google popup itself is NOT touched (frame copy *around* it). - **VERDICT:** SPEC-FIRST · `[AUTH][CACHE][TEST]` (popup-only; redirect stays banned; no mechanic change). - **Files:** `js/ui-account.js` (+ tests). ### MJ-3 · [SYSTEM STATES / VOICE] `js/ui-account.js:90,94,100` - **What:** `emptyState('Loading saves...')`, `'Failed to load cloud saves'`, `'No saves found.'` — sentence-case generic web states on the cloud-archive list. - **Why:** Breaks loading/empty/error register (§1, §4). - **In-world fix:** `RETRIEVING ARCHIVES…` / `⚠ ARCHIVE LINK FAILED` / `NO ARCHIVES ON FILE`. - **VERDICT:** BUILD-NOW (copy-only) · `[CACHE][TEST]`. - **Files:** `js/ui-account.js` (+ tests). ### MJ-4 · [TERMINOLOGY / OUT-OF-FRAME] `manifest.json:4,30,44,58,72` - **What:** description = `"… — Fallout: New Vegas tactical companion terminal."` surfaces the real game title to the install/store frame; shortcut descriptions = `"Open the Inventory tab"`, `"Wipe terminal and start a new campaign (confirmation required)"` (modern UI vocabulary). - **Why:** Out-of-frame surfaces (install prompt, OS app list) leak modern + real-world-IP framing. - **In-world fix:** Description → keep RobCo framing, drop the bare game name: e.g. `"RobCo Industries Unified Operating System — wasteland survival TERMINAL."` Shortcut descriptions → diegetic verbs (`"Access BACKPACK INVENTORY"`, `"PURGE terminal — begin new campaign"`). Names (`Comm-Link`) already fine. - **VERDICT:** SPEC-FIRST · `[CACHE][TEST]` (manifest is served → bump; Suite already checks manifest — extend). Sourcing note: no fallout.wiki data needed (pure copy). - **Files:** `manifest.json` (+ tests). ### MJ-5 · [TERMINOLOGY] `js/api.js:1211, 1328` (and surrounding narrative errors) - **What:** `⚠ [SYS] AI returned an unexpected response format…` and `⚠ AI KEY REJECTED — Your Gemini key was refused.` leak "AI" / "Gemini" into Courier-facing narrative (the in-world director is GEM / THE DIRECTOR). - **Why:** Terminology break — the narrative voice should never name the real model/vendor. - **In-world fix:** `⚠ [SYS-ALERT] DIRECTOR LINK RETURNED MALFORMED TELEMETRY — NOTHING APPLIED.` / `⚠ DIRECTOR ACCESS KEY REJECTED — RE-ENTER ACCESS KEY.` **TENSION:** the *config field label* must stay literal "Gemini API Key" (the user needs to paste their real Gemini key) — only the **narrative error** reframes; the input label stays in the LITERAL layer. - **VERDICT:** SPEC-FIRST · `[TEST][CACHE]`. - **Files:** `js/api.js` (+ tests). --- ## MINOR ### MN-6 · [MICROCOPY / CONSISTENCY] `index.html:602–865` (input placeholders) - **What:** `Item Name`, `Qty`, `lbs`, `val`, `Quest Name`, `Current objective (optional)`, `Perk Name`, `Rank`, `Lvl`, `Ticks`, `Filter traits...`, `Caliber (e.g. 5.56mm)` — mixed/lower-case. - **Why:** Breaks the ALL-CAPS terminal register; reads like a web form. - **In-world fix:** Uppercase + terse: `ITEM DESIGNATION`, `QTY`, `WT (LBS)`, `VAL`, `QUEST`, `OBJECTIVE (OPTIONAL)`, `PERK`, `RANK`, `LVL`, `TICKS`, `FILTER TRAITS…`, `CALIBER (E.G. 5.56MM)`. **TENSION:** keep them unambiguous — caps yes, cryptic no (don't rename "Qty" to something obscure). - **VERDICT:** SPEC-FIRST (batch) · `[CACHE][TEST]`. - **Files:** `index.html` (+ a static guard that no lower-case `placeholder=` remains on content inputs). ### MN-7 · [SYSTEM STATES / CONSISTENCY] empty-states across `index.html` (674,697,704,736,770,830,950,1140,1163) + render fns - **What:** `No collectibles loaded`, `No recipes loaded`, `No matching items in inventory.`, `No active quests`, `No perks acquired`, `No active effects`, `No notes recorded`, `No matches`, `No decisions recorded…`, `No timeline generated…`. - **Why:** Sentence-case + generic; inconsistent empty-state voice. - **In-world fix:** One canon empty-state vocabulary, ALL-CAPS: `ARCHIVE EMPTY` / `NO ENTRIES IN MEMORY` / `NO ACTIVE DIRECTIVES` / `NO TELEMETRY ON FILE`. (`emptyState()` is a shared helper — reframe centrally.) - **VERDICT:** SPEC-FIRST (batch) · `[CACHE][TEST]`. - **Files:** `js/ui-render.js` (`emptyState` callers), `index.html` static empties (+ tests). ### MN-8 · [MICROCOPY] image-upload control near `index.html:1748` (`triggerImageUpload`) - **What:** "Upload"-style optic-scan trigger. - **Why:** "Upload" is modern; the app already has the `[VISUAL UPLOAD]` command vocabulary. - **In-world fix:** `> VISUAL UPLOAD` / `OPTIC SCAN`. (Also audit IMPORT/EXPORT SAVE labels — "IMPORT/EXPORT" reads OK as TERMINAL ops; keep but ensure `> ` prefix consistency.) - **VERDICT:** BUILD-NOW (copy) · `[CACHE][TEST]`. - **Files:** `index.html` (+ tests). ### MN-9 · [VOICE] `js/api.js` error tails (1211, 1328, 1361, etc.) - **What:** In-world `⚠ [SYS]` wrappers with modern-polite tails: "…Please try again.", "Re-enter it in the API KEY field.", "Wait and try again later." - **Why:** Register cross — terse machine voice broken by polite phrasing. - **In-world fix:** `RETRY TRANSMISSION.`, `RE-ENTER ACCESS KEY.`, `AWAIT QUOTA RESET.` - **VERDICT:** SPEC-FIRST · `[CACHE][TEST]`. - **Files:** `js/api.js` (+ tests). --- ## POLISH ### PO-10 · [VOICE] `index.html:73` update-modal message - **What:** "A new version of RobCo U.O.S. is ready. Reboot to load it — the terminal must update to continue." - **Fix:** `FIRMWARE UPDATE STAGED — REBOOT REQUIRED TO APPLY.` (Button `> REBOOT TERMINAL` already canon.) - **VERDICT:** BUILD-NOW (copy) · `[CACHE][TEST]`. Files: `index.html`. ### PO-11 · [CONSISTENCY] `> ` prefix uniformity across panel `<h2>`/`<h3>` - **What:** Mix of `> ` and `&gt; ` (both render `>` — fine) and a few headers/buttons missing the prompt prefix. - **Fix:** Ensure every panel header + primary button carries the `> ` prompt prefix consistently. - **VERDICT:** SPEC-FIRST (batch) · `[CACHE][TEST]`. Files: `index.html`. ### PO-12 · [TERMINOLOGY] `index.html:1207` `> ACCOUNT` header - **What:** "ACCOUNT" is borderline-modern. - **Fix (optional):** `> OPERATOR UPLINK` / keep `ACCOUNT` (acceptable). Low priority. - **VERDICT:** SKIP-or-SPEC (owner call). Files: `index.html`, `js/ui-account.js`. --- ## TENSIONS (logged, NOT auto-applied — would trade usability/safety for immersion) - **TN-13 · A11Y on dynamic content:** `aria-label` = 8 in static HTML, **0 in JS-rendered rows** (inventory/skills/collectibles/recipes); `alt=` = 1. Not a diegetic break, but any copy reframe **must keep ARIA literal** and ideally *add* literal labels to rendered rows. Reframing must never move a screen-reader string into diegetic jargon (HOUSE_STANDARD §3/§5). → feed to a separate a11y pass; do not diegetic-ize. - **TN-MJ5 · Gemini key label:** narrative error reframes to "DIRECTOR ACCESS KEY", but the **config field label stays literal "Gemini API Key"** (user must paste the right value). Two registers, intentionally. - **TN-MN6 · placeholder clarity:** caps yes, obscurity no — don't sacrifice comprehension for register. - **TN-CR1 · reduced-motion is the resolution, not a tension:** calming motion *improves* usability and *preserves* the static CRT look — apply it. --- ## Counts **By severity:** CRITICAL 1 · MAJOR 4 · MINOR 4 · POLISH 3 · TENSIONS 4 (+ ~6 GOOD/canon anchors noted, no action). **By dimension:** Voice&copy 5 (MJ-2, MJ-5, MN-9, PO-10, MN-7) · Terminology 3 (MJ-4, MJ-5, PO-12) · Visual/chrome 0 (palette/chrome already clean) · Interaction/motion 1 (CR-1) · System states 3 (MJ-3, MN-7, CR-1) · Shell/boot 0 (canon) · Auth-as-diegesis 1 (MJ-2) · Out-of-frame 1 (MJ-4) · Microcopy 3 (MN-6, MN-8, PO-11) · Internal consistency 2 (MN-7, PO-11). **Build order suggestion for the synthesis stage:** CR-1 (a11y/safety, own push) → MJ-2/MJ-3 (account copy, one push) → MJ-4 (manifest, served + tests) → MJ-5/MN-9 (api error voice) → MN-6/MN-7/PO-11 (batched copy/register sweep) → MN-8/PO-10 (button copy). All copy-level fixes are `[CACHE][TEST]`, none touch `[AUTH]` mechanics or `[DATA]`/`[NET]` paths, none bump APP_VERSION.
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).