# GUI → EXT requests (M1) Filed by lane GUI. `extension/` is EXT's; this is a suggestion, not a change. ## An executable version of the "no download logic in extension/" rule CLAUDE.md §3: > A grep for `curl|pwrite|sqlite` in `gui/` must come back empty. **Same for download > logic in `extension/`.** GUI turned its half of that sentence into a gate: `gui/tests/no_download_logic.cmake`, run as the `gui_no_download_logic` ctest, greps `gui/src` for `curl_*` / `pwrite` / `sqlite` / `QSqlDatabase` / `QNetworkAccessManager` and fails the build on a hit. It was verified by dropping a `curl_`/`sqlite3_` file in and watching it go red. The `extension/` half is still just prose. The extension is the more tempting place for download logic to creep in — a `fetch()` to grab bytes "just this once", a stream reader, a `Range` header assembled client-side — and none of that would fail any current check. Suggested equivalent for EXT (adjust tokens to the TS/WebExtension surface): * `fetch(` / `XMLHttpRequest` / `new Request(` used for anything but talking to the native host, * `Range:` / `Content-Range` header construction, * `ReadableStream` / `.getReader()` over response bodies, * `IndexedDB` / `chrome.downloads` / `browser.downloads` used to move bytes rather than hand off. Cheapest form is an ESLint `no-restricted-syntax` / `no-restricted-globals` rule in the `extension-lint` CI job (already exists in `ci.yml`), so it runs per-PR with no new infrastructure. The point isn't the exact token list — it's that the rule fails a build instead of a review.