Good — I know this system's failure modes intimately (I've been fixing them all session), and your friend's doc is genuinely strong on breadth but light on exactly the things that broke us in practice. Here's my read, then a prompt you can forward. My quick assessment (for you) The doc is a faithful, well-organized parity spec — the architecture (PlatformAdapter/ChatSiteDriver interfaces, port protocol, Zod boundaries, phased build) is sound, and his stakes routing table already nails the thing we just added (public writes → strongest backend). Where it's dangerously optimistic is the two-brain web-chat driver and everything around it: it describes "detect error banners → failover" in one line, but that single area is where ~80% of our session's bugs lived. It also misses several silent-failure landmines (reasoning-model empties, MV3 worker death, CSS-specificity UI breakage, discovery-vocabulary pollution, the r/undefined escape bug) that he will hit because they're not obvious until you ship. The prompt below front-loads those. Here's the copy-paste prompt to send him: --- You are helping me harden a Chrome-extension design doc ("Social Copilot" — a Reddit+X social agent with a linked web-chat brain + a direct-API brain). The doc is attached. It's modeled on a working tool ("Reddit Copilot") whose author gave the following field notes — every item below is a bug or gotcha they actually hit and fixed in production. Revise my design doc to address ALL of these concretely (add sections/sub-sections, acceptance tests, and interface changes as needed). Don't just append a list — integrate each into the relevant section and flag any of my current choices they contradict. 1. THE WEB-CHAT DRIVER IS THE HARD PART — spec it like it's 80% of the work, not one bullet. Required robustness: • Whole-session throttles, not just "error banners": ChatGPT parks the entire chat with copy like "We're doing a quick check to keep ChatGPT reliable. Try again in 7 minutes.", usage-limit notices, "you're sending messages too quickly", and a generic "Something went wrong … help.openai.com". Build a robust "try again in N" parser (digits AND number-words; m/s/h; mm:ss / h:mm:ss; "a few / half an hour / an hour"; absolute "after 7:25 PM" vs relative "in 1:30"). Detect these and park the web backend cross-store, rerouting to API. • CRITICAL false-positive rule: NEVER scan the model's OWN answer text for these phrases — only the site's notice/toast UI. A model writing about "rate limits" (very common for streaming/API topics) must not be mistaken for BEING rate- limited. In our tool this false match halted the whole agent for 30 min. • Send-button readiness: ChatGPT marks the submit button disabled via aria-disabled="true" AND data-visually-disabled="", NOT the HTML `disabled` property. A ready-to-send message whose button never enables = a wedged session (treat as a throttle signal), but an empty composer's disabled button is NORMAL — gate that check on the composer actually having text. • Composer hygiene: reset the composer (clear text AND remove leftover file attachments) BEFORE and AFTER every turn. Leftover attachments pile up and permanently jam the send button after a few turns. • Persistent-thread vs fresh-chat trade-off: you propose "fresh chat every N turns." That loses conversation context and re-pays the controller-prompt cost. Consider a persistent thread with rolling summary folding instead whichever you pick. 2. REASONING MODELS SILENTLY RETURN EMPTY (this WILL bite your "cheap Ollama" default). OpenAI reasoning models (gpt-5*, o-series) spend budget on hidden reasoning first and need BOTH max_completion_token max_tokens) AND an explicit low reasoning_effort ('minimal'). Witho flag they return blank text and every decision fails over pointlessly. Same for the vision model. Specify per-model-family request shaping + a retr low effort rather than dropping it. 3. FAILOVER / COOLDOWN STATE CORRECTNESS: • When the throttled backend is ALSO the only/strong one (web down, API over budget), you can't "just fail over" — define graceful degradation (pause + wait out the window; never hammer a throttled endpoint). • Any cross-store "backend is parked" flag MUST be version-stamped and cleared on extension reload/update — a stale cooldown from a previous versio tool after every upgrade. Reloading should always be a reliable "unstick." 4. MV3 SERVICE-WORKER LIFECYCLE (your doc runs the loop + all LLM call background worker but never addresses this): MV3 workers are killed after ~30s idle and can die mid-decision. Specify keepalive (chrome.alarms tic the content script holds open), fully-persisted loop state so a kil RESUMES the exact pending decision, and idempotent action execution so a resumed turn can't double-post. 5. CROSS-CONTEXT WRITE OWNERSHIP: with multiple tabs/contexts touching storage you get lost-write races (our sessions showed "0 steps" while actively working because two tabs wrote the same blob). Make ONE context the of each store; others publish deltas it applies. State this in the 6. DISCOVERY QUALITY (your "score each candidate by a cheap decision" is exactly where we struggled): • Don't use the raw goal sentence as the discovery vocabulary — a r pollutes scoring (a streaming-outreach task discovered r/SpaceXLo r/redditracing at "perfect" scores). Distill 4–8 concise keywords • Your harvester will pick up USERNAMES and off-topic links as "com (we promoted r/Andromeda321 — a person). Filter hard; require real community signals (subscriber count, activity recency). • Navigation escape target: when the whitelist is empty and you must "return to the home community," NEVER build a URL from an empty value — we shipped an infinite loop navigating to `/r/undefined/`. Fall back to a disco community or don't navigate and keep discovering. 7. RATE-LIMIT / BUDGET ENFORCEMENT FOOTGUNS: enforcement must read the config, not a stale global mirror (we hit "hourly cap reached (40)" while the user had set 600, because a clamp ceiling silently capped it and a mirro Define 0 = unlimited explicitly, avoid hidden clamp ceilings, and every "you're capped" message should name which task/limit caused it and what still works (read-only tools). 8. UI RELIABILITY (Preact-in-Shadow-DOM doesn't save you from these): • A ~1 Hz status re-render WILL wipe the user's half-typed message