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

audit-completeness-gaps-2026-07-14.md



MEMORY

memory/localmode-1060dea9-0dc3-42b4-958d-2a6f7a6c0c58/audit-completeness-gaps-2026-07-14.md

sha256 cc10262b696671ca · 8215 bytes · original held in the private archive

--- name: audit-completeness-gaps-2026-07-14 description: "The blind GPT+Gemini audit-completeness review (2026-07-14). CLOSED — do not reopen. The keepers: what was REJECTED and why, the durable invariants and acceptance criteria it produced, and the meta-lesson that a finding you can grep is worth more than a finding that sounds right." metadata: node_type: memory type: project originSessionId: 0b7c5f41-bb34-4ab4-93be-fdb363f5eb40 --- **The owner sent the full planned-audits list, blind, to GPT and Gemini, asking only "what's genuinely MISSING" with a hard anti-bloat bar — "nothing to add" explicitly acceptable.** Both converged, which by the [[reframing-review-2026-07-13]] rule should count for LESS. **But they converged AGAINST the incentive to agree** (both were told "complete is fine," both refused), and — the decisive part — **when Dispatch checked their claims against the actual code, two were verified true and one partly true.** Grounded, not hand-waving. *Note 2026-07-20: the four gaps were all folded in and the work has since shipped. The gap list is history; what follows is what does not expire.* ## THE FOUR GAPS — the reasoning, not the status **1. Storage persistence was never requested from the browser.** Only **Gemini** saw it; GPT missed it. The argument: mobile-primary + offline-first + saves-are-sacred, and yet the app simply *trusted* the browser not to evict. **iOS Safari quietly evicts local storage** on low space or after a stretch unopened. **Cost = a lost campaign, silently, with the gate green throughout.** The cleanest and most clearly real find of the exercise. Fix shape: request persistence at boot; **on denial, show a diegetic warning** ("memory core unstable"). **2. An external CDN dependency in a supposedly offline app.** Both models raised it. The real risk is not today's dependency — it is that a **no-build, easy-paste** codebase makes it trivially easy for a NEW external reference to sneak into a core offline path and hang the UI on a cache-cleared offline load. ⭐ **THE DURABLE INVARIANT (GPT's sharpened wording — this is the keeper):** ***"No external network resource may become NECESSARY for the core app's install, boot, offline reload, or local-save."*** That permits a deliberately online-only module and blocks a future accidental one. **A crude "no external URLs" guard would have been wrong** — it would ban the intentional dependency along with the accidental. **3. Old-save survival was only partly covered.** Migration *was* tested, but the read was that those are "did we map the keys" checks — **not "a real, fully-populated OLD save boots to READY without silently dropping a field."** Silent field-drop was the exact bug fixed twice the previous day. **GPT's framing, worth keeping: test the durable FIELDS, not serialized text** — comparing serialized output is brittle. Fixture shapes worth reusing: current · mature/high-density · oldest-supported · malformed · divergent local/cloud. Paths worth reusing: save→reload · export→import→reload · legacy→migrate→reload · installed→update→offline-reload · failed-import-leaves-original-intact · cloud conflict without silent loss. **4. A trust-boundary audit** (GPT) — real, broader, lower urgency. A one-off inventory of *"what crosses in and out, and what authority it gets"*: imported saves, user-typed text reaching HTML sinks, AI/OCR output, external links, the user-supplied API token, service-worker fetches. Ranked below the others **because several are already guarded** — the job is finding the UNMAPPED ones. **Sharpest concrete piece: where and how the user-supplied API key is stored — plaintext local storage? A decision worth making on purpose.** Scoped one-off, **NOT a standing process**; encode any reusable chokepoint as a guard and discard the scaffold. ## ⛔ REJECTED — and why (Dispatch agreed with GPT's own rejections) - A separate **privacy** audit — it is the egress slice of the trust-boundary audit. - A separate **dependency/supply-chain** audit — tiny surface; one section of trust-boundary. - A **maintainability** audit — already covered several times over by the health passes and hardening work. - **Dead-code**, **disaster-recovery**, **release-rollback** audits — each folds into an existing item. - **Cross-browser** as a new audit → instead, one line added to the mobile audit: **write down the supported browser/PWA boundary.** ⭐ **The pattern in every rejection: fold into an existing home. NO second roadmap.** ## ⭐⭐ THE CROSS-FIRE ROUND — models saw each other's answers plus Dispatch's code-checks Given the union and the verification, both models **refined rather than added a fifth gap** — the shut-door result. They disagreed on exactly one thing, and the disagreement was the signal: - **Where the external-resource guard belongs.** Gemini: fold it into the trust-boundary audit (an external link IS a trust-boundary violation; don't double-track). GPT: keep audit and guard as a *parent-control pair* — the audit is a one-off human sweep, the guard is a permanent enforcer; different lifecycles. **Adjudication (both half-right): the guard is its own permanent artifact (GPT), but its correct SPEC depends on the audit's judgment (Gemini).** ⇒ the guard became a *deliverable of* the audit rather than a separate near-term item. - **CONVERGENCE (both, independently) — the keeper distinction:** storage persistence and the save-contract work are **two LAYERS of one problem, not siblings** — **semantic survival** (the app doesn't drop or corrupt fields) and **storage survival** (the platform was actually asked to keep the bytes). ⭐ **GPT's sharp point: requesting persistence ≠ proving durable storage.** A *denied* request leaves you volatile, so the work must test the denied state, not just the happy path. ## ⭐ THE SILENT-FAILURE LENS — asked last, CLOSED. "Fail loudly, never silently" is an ACCEPTANCE CRITERION inside existing items, NOT a new audit. ⭐ **GPT's keeper distinction: DETECTION ≠ GRACEFUL DEGRADATION.** Post-deploy verification tells *you* it failed; a **separate** criterion decides what the *USER* sees. The woven-in criteria (deliberately **not** new work items): - A failed, interrupted, or quota-blocked save write fails **LOUD**, with the original left intact — never swallowed. - Bad AI output is surfaced, not silently dropped. - A detected service-worker install/update failure is shown to the **user**. - A thrown boot phase or event handler is isolated and **classified fatal-vs-degradable** — degradable → unrelated functions stay usable plus one persistent notice; fatal → **stop pretending ready**, show recovery. **A thrown handler must not kill unrelated handlers.** Global error/unhandledrejection hooks are a last-resort alarm, **never a substitute for chokepoint handling.** ⇒ **THE AUDIT-COMPLETENESS QUESTION IS CLOSED. Do not reopen it.** Every category has an owner; the refinements plus the silent-failure criteria are the last word. ## ⭐ THE META-LESSON — the reason this file survives The exercise worked **because it was checkable.** The models earned trust by being verifiable — most of their concrete claims held up when Dispatch actually looked, and the one place Dispatch stayed cautious ("partly covered, not absent") is exactly where checking mattered. **That is the line between this and cargo-cult advice: a finding you can grep is worth more than a finding that sounds right.** Same discipline as [[local-ai-delegation-verdict]] (mechanically enforce honesty about EVIDENCE) and [[reframing-review-2026-07-13]]. *Correction 2026-07-20: this file previously asserted live code facts — that a persistence call was absent, an exact count of CDN imports and their pinned version, a match count for a legacy save key, and commit hashes and queue placement. All were true when written and are now stale or shipped. Current state: `QUEUE.md`, `CHANGELOG.md` + git log, and the code itself.* Related: [[deep-systems-review-2026-07-13]], [[reframing-review-2026-07-13]], [[fo3-karma-rebuild]], [[project-must-stay-free]], [[changelog-rules]].
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).