{
  "slug": "bw-dev",
  "name": "BW Dev",
  "version": "1.18.0",
  "download_url": "https://plugins.bowden.works/wp-content/uploads/plugin-updates/bw-dev-1.18.0.zip",
  "download_hash": "sha256:5e26cbade1165707e2a9506c36640d1c8630c154414988c6fda558f64a681682",
  "download_size": 500554,
  "requires": "6.0",
  "tested": "",
  "requires_php": "7.4",
  "last_updated": "2026-06-12",
  "homepage": "https://plugins.bowden.works/bw-dev/",
  "author": "Bowden Works",
  "description": "Bowden Works dev toolkit — admin columns, favicon, sticky elements, post-link blocks, YouTube embed, menu visibility, SVG uploads, admin notes, and Flywheel auto-update support in one actively-maintained plugin. Required for several site features. See Settings → BW Dev → About.",
  "changelog": "## [1.18.0] - 2026-06-11\n\n### Removed — Request Firewall (security/stability)\n- **The Request Firewall module is removed.** Its generated mu-plugin (`wp-content/mu-plugins/bw-request-firewall.php`) performed a **blocking `flock()`** on a file-backed store on every non-allowlisted request. On a managed host with a networked/overlay filesystem (Flywheel), that lock serializes PHP workers under real concurrency — the worker pool fills with processes blocked in `flock()` and the site goes down (the database is idle throughout; only a PHP-pool restart clears it). This caused a production outage on a live client site (aismartventures.com, 2026-06-11). It passed dev-container validation only because local-filesystem `flock()` is instant — a dev-vs-prod filesystem gap invisible except under real load on the real host. These sites also have no fast shared-memory store (the `memcached` extension is loaded but no server runs; APCu is absent), so the adaptive engine has no safe backend here regardless. The feature is gone, not paused.\n\n### Added — automatic decommission\n- **Every site that receives 1.18.0 neutralizes the firewall by itself**, with no per-site steps, no wp-admin visit, and even when the update arrives via SFTP/rsync (no WP upgrader hook). A one-time, idempotent, fail-safe routine runs early on `plugins_loaded` (before the module registry is built and regardless of the module-enabled setting) and: deletes the stub mu-plugin, deletes its data dir (`store.json`, `allowlist.json`), disables the `request_firewall` module in settings, and records a `bw_dev_request_firewall_decommissioned` marker. After it succeeds once it's a single autoloaded-option check that no-ops.\n  - The `request_firewall` module is now **inert** — it registers zero hooks, generates no files, and performs **zero per-request filesystem I/O**. Every regeneration path from 1.16.0–1.17.2 (the `admin_init` deploy, the front-end self-heal, `deploy_now`, the `upgrader_process_complete` gate, the cron rebuild, the `wp bw-dev firewall deploy` command) is **deleted**, so a stub can never be re-created.\n  - If `wp-content/mu-plugins` is not writable the routine backs off behind a 5-minute throttle (never loops, never fatals) and shows an admin notice telling you to delete the file manually.\n  - `wp bw-dev firewall status` / `wp bw-dev firewall decommission` (deletion-only — there is no `deploy`) let you verify/force the cleanup headlessly across a fleet.\n  - The module's settings tab now shows a short \"this feature was removed\" notice with the live removal status."
}
