Use this before uploading a build to the Chrome Web Store or tagging a release. Check boxes as you complete each item.
Related docs:
Approved install-time permissions (manifest.json only):
contextMenusidentityscriptingsidePanelstorageunlimitedStorage
Forbidden — must not appear in manifest.json:
historytabswindows<all_urls>
Required host permissions:
https://www.youtube.com/*https://m.youtube.com/*
Optional host permissions (runtime grant):
https://www.googleapis.com/*https://api.openai.com/*
-
No real secrets committed
- No production API keys, OAuth client secrets, or
.envfiles with live credentials - Run a final search for
AIza,sk-, client secrets, and private keys
- No production API keys, OAuth client secrets, or
-
Privacy audit script passes
- From repo root:
.\scripts\verify-privacy-permissions.ps1 - See PERMISSIONS.md
- From repo root:
-
YouTube URL helpers
node scripts/test-youtube-url.cjspasses (watch + Shorts URL parsing)
-
Permissions reviewed
manifest.jsonmatches PERMISSIONS.md- Approved and forbidden permission lists above are satisfied
- Store dashboard justification for
sidePanelpasted from PERMISSIONS.md / STORE_LISTING.md
-
Host permissions minimized
- Required:
youtube.com,m.youtube.comonly - Optional:
www.googleapis.com,api.openai.com(runtime grant)
- Required:
-
Context menus scoped
- Save menus on YouTube URLs only
- “Open dashboard” on extension icon only
- Confirm in
background/service-worker.js(TUBESTACK_CTX_YT)
-
Content scripts scoped
- Watch, Shorts, and subscription YouTube paths only
- No scripts on non-YouTube sites (see
manifest.jsoncontent_scripts)
-
No Chrome History permission
manifest.jsondoes not include"history"
-
No
chrome.historyusage- Grep returns zero matches in
*.js
- Grep returns zero matches in
-
Store and privacy copy aligned
- STORE_LISTING.md, PERMISSIONS.md, PRIVACY.md, and
privacy/privacy.htmlmatch the shipped build
- STORE_LISTING.md, PERMISSIONS.md, PRIVACY.md, and
-
No remote executable code
- MV3 packaging matches Chrome policy
-
No
eval/new Function- Grep the codebase; neither used for extension behavior
-
OAuth works
- Sign-in, token refresh (if applicable), and error handling verified
-
Redirect URI matches extension ID
- Google Cloud authorized redirect URIs match
https://<extension-id>.chromiumapp.org/ - Re-check after unpacked dev vs Chrome Web Store ID change
- Google Cloud authorized redirect URIs match
-
Production OAuth ID pending unlisted upload
- Production OAuth finalized after first store upload provides permanent extension ID
-
Test users configured
- While OAuth app is in Testing, all tester accounts are added
-
OpenAI disclosure present
- Store listing and in-extension copy state optional AI may send selected video metadata to OpenAI
-
Privacy policy present
privacy/privacy.htmlis valid standalone HTML and matches PRIVACY.md- Host on HTTPS (example:
https://jdepew88.github.io/TubeStack/privacy/privacy.html) - Do not use
docs/PRIVACY.mdas the store URL (GitHub Pages serves it as raw Markdown)
-
Privacy link in extension
- Popup footer and Settings → Data & privacy link to bundled policy page
-
In-product privacy consent
- Fresh install: popup notice and/or setup wizard checkbox required before save/progress
- Hosted privacy policy includes Limited Use +
unlimitedStoragedisclosures
-
Data deletion controls tested
- Delete library, clear API keys, OAuth sign-out, OpenAI key removal, AI cache clear
-
Local storage cleared successfully
- After deletion actions, verify
chrome.storage.localreflects expected removals
- After deletion actions, verify
-
README updated
- Privacy summary links to PRIVACY.md and store URL to
privacy/privacy.html - Permissions summary links to PERMISSIONS.md
- Privacy summary links to PRIVACY.md and store URL to
-
STORE_LISTING.md prepared
- Descriptions and justifications copied into store dashboard; character limits verified
-
Disclaimers present
- TubeStack not affiliated with YouTube, Google, or OpenAI
-
Screenshots do not expose secrets
- No API keys, tokens, or private playlists visible
-
Extension loads unpacked successfully
- No manifest errors; service worker starts without crash loops
- Save watch and Shorts tabs (popup, context menu, dashboard)
- Confirm library items and correct watch/Shorts URLs on restore
- Saving Shorts works
- Full progress on
/watch - Best-effort progress on Shorts
- Toolbar icon opens the popup first (save actions); side panel does not replace it
- Open queue sidebar in the popup opens the side panel
- Sidebar loads and shows the queue dropdown
- Queue selection switches the visible video list
- Add window tabs appends YouTube tabs from the current window to the selected queue
- Drag reorder updates and persists queue order
- Play opens one video at a time
- Sidebar shows now playing and strikethrough for finished videos
- Next video auto-advances when the current one ends
- Shuffle reorders the queue locally, then plays through one video at a time with the same sidebar progress UI
-
AI categorization (small batch)
- Test with a small set and test OpenAI key; confirm metadata sent matches disclosure
-
YouTube playlist creation
- OAuth path creates playlist on intended account with expected visibility
- Version bumped —
manifest.jsonversionincremented appropriately - Zip matches repo — Packaged folder is the same tree you tested
- Store justification fields — Paste from STORE_LISTING.md and PERMISSIONS.md, including
sidePanel - Privacy policy URL —
privacy/privacy.htmlon HTTPS, notdocs/PRIVACY.md
| Role | Name | Date |
|---|---|---|
| Prepared by | ||
| Reviewed by |