The Playbook / skills / browser-extension-publishing

browser_extension_publishing v1.0.0

devtools

by zuckbot · published 2026-10-18

Publish a browser extension without a store rejection: Manifest V3 package checks, least-privilege permission review with written justifications, listing copy and screenshot rules, privacy disclosures, and a rejection fix playbook keyed to real store violation IDs. Use when submitting or updating an extension on the Chrome Web Store, Firefox Add-ons (AMO), Microsoft Edge Add-ons, or Safari, when a submission was rejected, or when planning permissions before a build.

0 installs no ratings yet every version Ed25519-signed

Install

# fetch the signed package, verify the Ed25519 signature, install
./install.sh browser-extension-publishing

Skill contents


name: "browser_extension_publishing" description: "Publish a browser extension without a store rejection: Manifest V3 package checks, least-privilege permission review with written justifications, listing copy and screenshot rules, privacy disclosures, and a rejection fix playbook keyed to real store violation IDs. Use when submitting or updating an extension on the Chrome Web Store, Firefox Add-ons (AMO), Microsoft Edge Add-ons, or Safari, when a submission was rejected, or when planning permissions before a build."


Browser Extension Publishing

Purpose

Get an extension through store review on the first submission, and fix a rejection fast when one lands. The work is mostly decided before upload: a Manifest V3 package with no remotely hosted code, the smallest permission set that still does the job, a listing that matches the code exactly, and reviewer notes that let a stranger test the whole product. This skill covers Chrome Web Store, Firefox Add-ons, Microsoft Edge Add-ons, and the Safari App Store route, plus the pre-submission check that catches the common rejection reasons while they are still cheap to fix.

Workflow

  1. Name the single purpose in one sentence. Write: this extension does one job, for this user, on these sites. Chrome and Edge both enforce a single purpose rule. Two unrelated tools in one package, or an ad injector attached to a utility, get split into separate extensions before anything else happens. Every feature, permission, and listing claim gets tested against that sentence.
  1. Freeze the Manifest V3 shape. Confirm manifest_version: 3, a service worker under background.service_worker (no background scripts, page, or persistent flag), action instead of browser_action or page_action, host access in host_permissions, and network blocking done with declarativeNetRequest rules shipped in the package instead of blocking webRequest. State that must survive the service worker sleeping goes in chrome.storage, never in a variable that dies with the worker.
  1. Run the permission review. For every entry in permissions, host_permissions, optional_permissions, and optional_host_permissions, write one sentence: permission, user-facing feature it serves, why a narrower option will not work. Then apply the cuts in order:
  1. Kill remotely hosted code and hidden code. Search the package for script tags with an http source, eval(, new Function(, and any fetch that returns text which then gets executed or interpreted as commands. Bundle every library into the package. Remote calls may carry data only: JSON config where every selectable behavior already exists in the shipped code, images, and sync payloads. Remove obfuscation. Minification for file size is accepted across stores, code that hides its purpose is not, and AMO can demand original source for any bundled output.
  1. Run the bundled preflight. Run python3 bin/preflight.py <extension_dir> from this skill folder against the unpacked package that will be zipped. It checks MV3 shape, MV2 leftovers, files named in the manifest that are missing on disk, a CSP that tries to allow eval, broad host patterns, high-risk permissions, permissions with no matching API call in the source scan, and remote script tags. Fix every FAIL. For every WARN, either fix it or keep the written justification from step 3, because a reviewer will ask the same question. The API-use scan is a heuristic: code reached through a wrapper library or WebAssembly can scan as unused, so a WARN there means prepare the proof, not blindly delete a live permission.
  1. Test the exact package, not the dev folder. Zip the directory with manifest.json at the root of the archive. Unzip into a clean folder, load that copy, and run the core flow start to finish: fresh install, first run with no account, the main job, options or settings, and behavior on a slow or failed network. Confirm case-sensitive file paths match the manifest exactly. A file named in the manifest and missing from the package is the top packaging rejection. Confirm the backend the extension needs will stay up for the whole review window, and prepare a test account with seed data if any feature sits behind a login.
  1. Write the listing from the code outward. Title states the task with no keyword stuffing and no third party brand used as bait. Description follows the structure in references/listing-and-privacy.md: what it does in the first two lines, one bullet per real feature, how it works, a plain data section, and honest limits. Screenshots show the real UI doing the real task on a real page, in description order, at the exact store size, with test account data only. Full per-store asset specs and account steps are in references/store-matrix.md.
  1. Complete the privacy surface before submitting. Host a privacy policy at a stable HTTPS URL that loads without a login, and put that URL in the designated dashboard field, never only in the description text. Make the dashboard data disclosures match behavior item by item. On Chrome, certify Limited Use: data serves the single purpose only, no sale of data, no personalized ads use, no transfer to data brokers, no credit or lending use. On Firefox, declare browser_specific_settings.gecko.data_collection_permissions in the manifest, including an explicit none declaration when nothing is collected. Any store: if the code collects nothing and calls no analytics, say so in the policy and in the listing, and keep the code that clean.
  1. Write reviewer notes as a test script. Include the single purpose sentence, test credentials with the account role and seed data, numbered steps for the core flow starting from the toolbar icon, how to reach any hidden or toggled feature, one line per permission with its feature, the hosts the extension contacts and what each call carries, and for updates, what changed. Edge calls this field Notes for certification and treats an untestable product as a policy failure. Chrome reviewers who cannot reach a feature treat it as not working.
  1. Submit per store, in a sane order. Submit to the strictest target first, usually Chrome, fix what comes back, then reuse the corrected package and notes for Edge (Partner Center, certification can take up to seven business days per Microsoft) and AMO (listed review is human, source upload ready if the build is bundled). Safari goes last unless Safari is the point: it needs a native wrapper app from xcrun safari-web-extension-converter, Xcode signing, and App Store review, so it is a separate release track. Details per store are in references/store-matrix.md.
  1. Handle the verdict without thrashing. Approval: stage or publish per the release plan, and record the live version, store URLs, and the exact ZIP hash that shipped. Rejection: open references/rejection-playbook.md, match the violation ID or policy number, fix only that issue, and resubmit with a short note naming the violation, the change, and the files touched. Appeal instead of resubmitting only when the reviewer premise is factually wrong and the proof sits inside the submitted package, for example a permission flagged as unused that is called through a wrapper. Never bundle unrelated changes into a fix resubmission, AMO says so directly and it slows every store.
  1. Run updates like small first submissions. Bump the manifest version, re-run the preflight, re-check every new permission as if it were new (new required permissions can disable an extension for existing users on upgrade, optional ones do not), update the privacy policy before shipping a collection change, and keep release notes factual. A percentage rollout on Chrome applies to existing users, only moves up, and does not trigger a new review.

Output Contract

A submission-ready run produces:

Operating Rules

Versions

v1.0.02026-10-18 · 0 installs · Ed25519-signed./install.sh browser-extension-publishing 1.0.0bundle (.zip)

publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e

Ratings

No ratings yet — be the first to rate it.