BugLens v3.2.0 — Rescue Mode + Atomic Batch + Diagnostics
Released 2026-05-28. PR #1.
Motivation
Real incident on chapas.hr 2026-05-28: a partial deploy of a custom MU plugin (loader file uploaded before module files) caused WordPress to fatal-error on every request. BugLens Bridge API became unavailable because it relies on the same WP boot sequence that was failing. Recovery required manual cPanel File Manager intervention.
v3.2.0 ensures AI agents can recover from such situations programmatically, and adds atomic batch-write to prevent the partial-deploy scenario in the first place.
⭐ New Features
🆘 Rescue Mode — standalone PHP endpoint that survives WP fatal errors
- New file
rescue-template.php(ships with plugin) — copied towp-content/buglens-rescue-{random32}.phpon activation - Zero WordPress dependency — no
wp-load.php, no database, no plugin loading - Provides 7 fs operations:
read,write,delete,list,info,mkdir,rename - New class
BugLens_Bridge_Rescue_Securitymanages install, secret hashing (SHA256), random URL slug generation - Default DISABLED — returns HTTP 503 until secret configured via:
BugLens_Bridge_Rescue_Security::set_rescue_secret()(programmatic), orBUGLENS_RESCUE_KEYconstant inwp-config.php(override)
- Auto-lockout — 5 failed auth attempts per minute → 1 hour IP ban (file-based counter)
- Audit log — JSON Lines at
wp-content/buglens-rescue-state/audit.jsonl - State directory auto-creates with
.htaccessDeny (Apache 2.4 + 2.2 fallback)
🔁 Atomic Batch + Verify endpoints
POST /fs/batch-write— all-or-nothing N-file write. Max 50 files, 10 MB total, 2 MB per file- Pipeline: validate → stage to
wp-content/uploads/_buglens-batch-staging/{nonce}/→ verify sha256 → atomic rename → cleanup - Mid-rename failure returns
partial_commitwith list of already-committed files (recoverable state info for client)
- Pipeline: validate → stage to
POST /fs/verify— bulk sha256 verification. Returns per-file{path, exists, size, sha256, matches_expected?}
🩺 Health + Preflight diagnostics
GET /fs/health(public, no auth) — WP boot status snapshot: versions (WP/PHP/MySQL), memory used/peak/limit, plugin counts, last 5 error_log lines, rescue mode status, request time. Cache headers ensure always-fresh (LSCWPnocacheaction +Cache-Control: no-store)POST /fs/preflight— dry-run path validation (parent_exists, writable, blocked) without filesystem changes
🤖 MCP server v3.2.0
5 new tools:
batch_write— atomic multi-file deployverify_files— bulk sha256 assertionshealth_check— WP boot diagnosticspreflight_paths— dry-run validationrescue_call— bypass WP REST entirely via rescue.php (usesBUGLENS_RESCUE_URL+BUGLENS_RESCUE_KEYenv vars)
rescue_call sends secret in X-BugLens-Rescue-Key header only (not body) to minimize logging exposure.
🔐 Security fix (CVE-class)
Discovered during v3.2.0 testing on chapas.hr: when DB option buglens_bridge_settings has blocked_paths = '' (empty string), the ?? operator does NOT fall back to default (?? only fires on null). Result: blocked patterns list becomes empty → wp-config.php, .htaccess, .htpasswd ALL readable via /fs/read with any valid API key.
Affected versions: v3.0.0 through v3.1.0.
Fix: defensive empty-string check forces baseline blocked patterns when DB has empty value. Admin can still explicitly customize.
If you're upgrading from v3.0.0–v3.1.0 and used Bridge in production, please verify your buglens_bridge_settings option and rotate any credentials that may have been exposed.
🔄 Changed
uninstall.php— explicitly preserves rescue artifacts (buglens-rescue-{slug}.php,buglens-rescue-state/) on plugin delete. Reason: user installed rescue specifically for emergency recovery; removing plugin should not lose that capability. Manual delete via cPanel/FTP if full cleanup desired.
📦 Files
- 4 new PHP class files in
includes/ - 1 new template at root (
rescue-template.php) - 1 new MCP tools module (
mcp-server/src/tools-v320.js) - New docs:
docs/rescue-mode.md - Updated:
buglens.php,mcp-server/src/index.js,mcp-server/src/client.js,mcp-server/package.json,CHANGELOG.md,uninstall.php - 1 fix to
includes/class-buglens-bridge-security.php
✅ Tested
Live tested on chapas.hr (Plus Hosting Grupa cPanel + CloudLinux + LiteSpeed, WordPress 7.0, PHP 8.3.31):
- ✓ Rescue endpoint install via
set_rescue_secret() - ✓ Auth: 403 without key, 200 with valid key
- ✓ Auto-lockout: 5×wrong key → 5×403, 6th onwards → 429
- ✓ Atomic batch-write 3 files with sha256 verification
- ✓
/fs/verifyreturns per-file existence + matches_expected - ✓
/fs/healthreturns WP boot status, no longer cached by LSCWP - ✓
/fs/preflightvalidates paths without writing - ✓ Security hardening confirmed (wp-config.php blocked when defaults active)
Upgrade notes
- Download
buglens-3.2.0.zip(attached below) → upload via WP Admin → Plugins → Add New → Upload Plugin → Replace. - Plugin activation hook will install rescue endpoint at
wp-content/buglens-rescue-{random}.php. Default state: returns 503 (no secret configured). - To enable Rescue Mode, run (via wp-cli or
wp eval):Save the returned plain secret to your password manager (shown once).echo BugLens_Bridge_Rescue_Security::set_rescue_secret();
- Update MCP server:
npm install -g buglens-mcp@3.2.0(when published to npm).
Rollback
If anything fails:
- Restore from v3.1.0 ZIP (re-upload + replace)
- Delete rescue artifacts (optional):
rm wp-content/buglens-rescue-*.php && rm -rf wp-content/buglens-rescue-state/
🤖 v3.2.0 designed and implemented with Claude Code (Opus 4.7).