# Release checklist

A build is not a release. A release is a build that has passed these gates.

## 1. Static and unit gates

- [ ] `php bin/inspect.php` — zero errors (covers syntax, imports, view contracts, escaping, portability, SQL, RTL, i18n, contrast, docs and live renders)
- [ ] `php -l` over every PHP file — zero syntax failures
- [ ] `php bin/run-all-tests.php` on a MySQL-capable environment — zero failures, zero unexplained skips
- [ ] `php bin/doctor.php` — required checks pass
- [ ] `php bin/package.php --check` — passes
- [ ] Build the archive, extract into a clean directory, verify the manifest again

## 2. Upgrade gate

1. Restore a real or sanitised copy of the previous release's database.
2. Replace the application files with the candidate.
3. Run the admin database upgrade, or `php bin/migrate.php`.
4. Run `php bin/doctor.php`.
5. Verify questions, answers, comments, topics, users, taxonomy, menus, widgets, ads, custom code, theme and language settings all survived.
6. Run the migrations a second time and confirm they are idempotent.

- [ ] No content lost
- [ ] No perpetual "database upgrade required" loop

## 3. Browser matrix

Test Arabic RTL and English LTR, as guest, member, moderator and administrator:

- [ ] Home feed and its filters
- [ ] Ask a question; answer; comment; vote; follow; report; accept
- [ ] Topics: create, comment, follow, report, lock, pin
- [ ] Taxonomy pages and following
- [ ] Search
- [ ] Public profiles
- [ ] Sign-in, registration, recovery, verification
- [ ] Notifications
- [ ] Contact form
- [ ] Pagination and canonical tags
- [ ] Structured data validates
- [ ] Sitemap index and children
- [ ] Ads, custom code and widget placement
- [ ] The editor, including paste handling, at 360 px

## 4. Deployment matrix

- [ ] Local, root path
- [ ] Local, `/ask` base path
- [ ] Production-like shared hosting or LiteSpeed at `/ask`
- [ ] Custom administrator path (`/w-admin`) — sign-in, forms, assets and redirects all work **without** renaming the physical directory

## 5. Security gate

- [ ] CSRF on every write path, including new ones
- [ ] Server-side authorisation on every admin and moderator action
- [ ] Editorial accounts cannot sign in
- [ ] Every SQL parameter prepared
- [ ] Member Markdown cannot emit script or unsafe URLs
- [ ] Imported JSON/CSV and theme JSON are size- and format-constrained
- [ ] Themes and plugins cannot escape their filesystem roots
- [ ] No secret in the package, the manifest, or any log
- [ ] Rate limits still work after any trust or spam change

## 6. Performance gate

Measure on a representative dataset:

- [ ] Home feed query count and time
- [ ] A question with 50 answers and comments
- [ ] A topic with 50 comments
- [ ] Sitemap child generation
- [ ] Admin overview
- [ ] No N+1 introduced by the unified feed or trust labels

Add an index or memoisation only with a measurement behind it.

## 7. Package gate

- [ ] The archive contains every document the shipped README links to
- [ ] Internal planning, archived material, tests, logs and secrets are absent
- [ ] `run-all-tests.php` degrades gracefully when tests are not bundled

## 8. Only then

- [ ] `VERSION` bumped
- [ ] `CHANGELOG.md` updated
- [ ] Tag and publish
