| G1 | auto-feed is manual | cockpit fresh without anyone remembering | pnpm cockpit is human-run; dev-design Step 7 mentions it but no hook/pulse fires it | serious | S | spec.md v2-1; no PreCompact/Stop hook runs cockpit |
| G2 | manifest is not the review-identity SoT | verdicts keyed by run+gitHead; broken & capture-fails shown | verdict keyed by bare slug (stale approvals); 2xx→4xx hidden as "not built"; capture-fails vanish | serious | M | review-portal.mjs setv() keys riv-<slug>; spec.md v2-2 |
| G3 | no bless→baseline | "before" = the last state Cam blessed + its commit | "before" = whatever full set is adjacent by mtime; window floats | serious | S | review-portal.mjs beforeDir picker; spec.md v2-3 |
| G4 | route coverage is a hardcoded list | every real route (incl marketing/pSEO/dynamic) | ANON/AUTHED arrays hand-coded in webapp-shots.mjs; /compare,/use-cases,/p/[id] absent | minor | M | webapp-shots.mjs route arrays; spec.md v2-4 |
| G5 | no write-back server | verdicts.json agent-readable + reshoot + live-refresh | verdicts are browser-local localStorage only | serious | M | review-portal.mjs localStorage; spec.md v2-5 |
| G6 | no flow-proof | a Playwright happy-path asserts the surface WORKS | "Looks right" is a static screenshot only | serious | L | dev-design Step 6; spec.md v2-6 |
| G7 | esc() is HTML-safe not JS-string-safe | no inline-handler injection risk | onclick="zoom('...')" single-quotes unescaped (safe only by clean filenames) | minor | S | review-portal.mjs esc() + onclick |