WordPress Maintenance

wp db check / wp db optimize — the database health commands that get overlooked

A WordPress database doesn’t tidy itself up over time. Spam comments pile up, expired transients linger, post revisions accumulate, and tables left behind by uninstalled plugins never quite go away. All of that adds up to bloated tables, and occasionally to actual table corruption. This is territory the admin dashboard barely shows you — but WP-CLI reaches it directly with two short commands: wp db check and wp db optimize. Note: WP-CLI’s wp db subcommands operate directly on the MySQL (or MariaDB) database WordPress uses, without going through the admin dashboard. Connection details are read automatically from wp-config.php. wp db check — verifying table health wp db check Under the …

Read more
WordPress Maintenance

Using WP-CLI aliases to switch between multiple WordPress environments safely

Anyone managing several WordPress environments — production, staging, or separate installs for different languages — ends up re-typing SSH connection details and install paths every time they run a command. Building that connection string by hand each time invites mistakes: a copy-paste error, or reusing a stale path, can send a command to the wrong environment entirely. That risk matters most for write commands — bulk plugin updates or database operations — where hitting the wrong target has real consequences. WP-CLI has a built-in feature for exactly this problem: aliases. Note: A WP-CLI “alias” assigns a short name (like @production) to a set of connection details — an SSH target …

Read more
Engineering Notes

Placing corrections exactly where an LLM is tempted to sound plausible instead of right

Placing corrections exactly where an LLM is tempted to sound plausible instead of right Background The support chatbot on our landing page feeds the contents of a knowledge base to an LLM as its system prompt, then lets it answer whatever a user asks. Running it in practice surfaced something a generic instruction like “answer accurately” doesn’t cover: the same plausible-sounding mistake, repeated consistently, for certain specific kinds of questions. An LLM has absorbed a huge amount of general technical knowledge. That’s exactly why, the moment it’s asked something, it tends to combine that general knowledge into an answer that sounds thoroughly convincing. The tricky part is that the answer …

Read more
Engineering Notes

A support chatbot needs to be designed for what it won’t answer, not just what it will

A support chatbot needs to be designed for what it won’t answer, not just what it will Background The support chatbot on our landing page has a simple job: answer questions about the product’s features, pricing, and troubleshooting. But a conversational AI built to answer questions shares a common weakness. Left unguarded, it tends to comply with requests designed to surface its own system prompt verbatim, or with phrasing that falsely claims special authority to unlock a different kind of answer. The chatbot works by feeding a knowledge base file to the LLM as its system prompt, then letting it answer whatever the user asks. Rather than implementing this defense …

Read more
Engineering Notes

The free plan wasn’t actually “no registration required” — fixing a landing page claim that contradicted itself

The free plan wasn’t actually “no registration required” — fixing a landing page claim that contradicted itself Background An external marketing review flagged what looked like a contradiction in our landing page’s FAQ. Checking it against the actual code confirmed the claim was accurate. Two statements coexisted on the same page: Quick Start, step 2: “Register with your email to start for free” The FAQ answer: “The Free plan requires no registration and allows up to 1 site, 3 runs per month — completely free.” One says “please register.” The other says “no registration needed.” Checking the implementation confirmed that the Free plan requires an email address to be registered …

Read more
WordPress Maintenance

Comparing pricing models across four WordPress maintenance tools — what the shape of a price reveals about cost structure

Comparing pricing models across four WordPress maintenance tools — what the shape of a price reveals about cost structure Background While surveying the major WordPress maintenance tools (ManageWP, MainWP, WP Umbrella, and InfiniteWP), one thing stood out once their pricing was laid side by side: this isn’t just a matter of “cheaper vs. more expensive.” The shape of the pricing itself differs completely from company to company. And that shape isn’t arbitrary — it closely mirrors how each company actually delivers its service. Four companies, four pricing shapes ManageWP: free core, stacked per-site add-ons The core dashboard is free. Features like Backup, Security, Reports, and White-Label are sold separately as …

Read more
Engineering Notes

A tabbed form that silently refused to submit — required fields hidden behind another tab

A tabbed form that silently refused to submit — required fields hidden behind another tab Background The site edit modal kept accumulating fields — site name, category, SSH connection details, WordPress install location — until editing anything meant scrolling up and down a single long form to find the right field. To clean this up, we split it into three tabs: “Registration info,” “SSH,” and “WordPress info.” That change broke form submission itself, in a way that was hard to spot at first. What tabbing broke The tab implementation itself is straightforward. Each tab’s fields live in a <div class=”site-tab-content” data-tab=”…”>, and CSS toggles which one is visible. .site-tab-content { …

Read more
Engineering Notes

SPF, DKIM, and DMARC together — why the missing DMARC record was blocking registration emails

SPF, DKIM, and DMARC together — why the missing DMARC record was blocking registration emails Background Registration confirmation emails were not reliably reaching users on Gmail and Outlook outside Japan — sometimes landing in spam, sometimes not arriving at all. Investigation pointed to a single root cause: the wpmm.jp domain had SPF and DKIM configured, but no DMARC record. What each of the three does SPF (Sender Policy Framework) declares in DNS which IP addresses are authorized to send mail for a domain. Receiving servers check the sending IP against the SPF record to confirm the source is legitimate. DKIM (DomainKeys Identified Mail) adds a cryptographic signature to the message …

Read more
Engineering Notes

Resuming email verification after the app is closed — the pending_email state that prevents re-sending

Resuming email verification after the app is closed — the pending_email state that prevents re-sending Background On first launch, the desktop app asks the user for an email address, sends a confirmation email, and completes registration once the user clicks the link in that email. There was a trap here for anyone who closed the app before clicking the link. Email does not always arrive immediately. Closing the app with the intention of clicking the link once the email shows up, then reopening later, is a perfectly natural way to use it. But on restart the app decided that registration was still incomplete and showed the first-launch screen (the email …

Read more
Engineering Notes

The cp932 crash in the build gate that only happened on Windows — static detection, behavioral testing, and a negative check

The cp932 crash in the build gate that only happened on Windows — static detection, behavioral testing, and a negative check The symptom During the Windows build for v1.6.11, the build gate reported “version number consistency check failed.” But the version numbers were correct everywhere. The real cause was not a version mismatch. The build gate in build_app.py calls tools/bump_version.py via subprocess and checks its exit code. The success messages in bump_version.py contained emoji (✅ and similar). On Japanese Windows, the default code page is cp932, which cannot encode those characters. Python raised a UnicodeEncodeError on the very first write to stdout, the process exited non-zero, and the build gate …

Read more