Engineering Notes

What Is Visual Regression Testing? How Screenshot Diffing Catches Layout Breaks

Sometimes a WordPress plugin or theme update completes without a single PHP error, the admin screen reports success, and yet the live site looks broken the moment you open it. A changed CSS load order, an overwritten font declaration, a clashing class name — these can silently wreck the layout without ever touching an error log. Because nothing throws, nothing gets logged, and nobody notices until a visitor complains. Comparing a screenshot taken before an update against one taken after is one way to catch this “no error, but the page looks wrong” class of problem mechanically. This approach is generally known as visual regression testing. Note: “regression” in software …

Read more
Engineering Notes

What are PyInstaller “hidden imports” — and why do only dynamic imports break?

If you’ve ever packaged a Python desktop app with PyInstaller, you may have run into this: the app runs perfectly from source, but the frozen executable throws ModuleNotFoundError — and only when you exercise one particular feature. It doesn’t crash on startup. It crashes three clicks deep, in a code path nobody happened to test right after the build. This post breaks down why that happens and what “hidden imports” actually means. Note: PyInstaller is a tool that bundles a Python script together with its dependencies into a single platform-specific executable (a .exe on Windows, or a binary embedded in a .app on macOS), so end users don’t need a …

Read more
Engineering Notes

Code signing basics — what Apple Notarization and Windows Authenticode actually certify

When you build a desktop app for distribution, macOS may greet users with “cannot be opened because the developer cannot be verified,” and Windows SmartScreen may show “Windows protected your PC” for an unrecognized publisher. Signing and notarizing an app is how you avoid these warnings, but what exactly does that signature prove — and what does it not prove? The distinction is easy to get wrong. Here’s a breakdown of two systems that look similar on the surface but play different roles: Apple’s Notarization and Windows’ Authenticode. Note: Code signing is the umbrella term for attaching a cryptographic signature to an executable so that its author’s identity and the …

Read more
Engineering Notes

Running Flask’s dev server as a desktop app’s backend — what actually matters

Start a Flask app and the terminal prints a familiar line: “WARNING: This is a development server. Do not use it in a production deployment.” Yet plenty of desktop apps bundle that same local Flask server as their actual runtime and keep it running on the user’s machine for the life of the session. That looks like ignoring the warning outright, but the underlying assumptions have actually changed. This article works through what has to change for that warning to become safe to set aside — and what you still have to handle yourself, or it turns into a real bug. Note: WSGI (Web Server Gateway Interface) is the standard …

Read more
Engineering Notes

Atomic writes — how tempfile + os.replace prevent corrupted JSON

What happens if the power cuts out while a process is writing to a config file? Or if antivirus software on Windows briefly locks a file mid-write? If you naively overwrite a file with open(path, ‘w’), whatever partial content existed at the moment of interruption is what remains on disk. For JSON, that usually means broken syntax — json.load() throws on the next startup, and the entire configuration is effectively lost. This article walks through a standard technique for preventing that: writing to a temporary file first, then swapping it in atomically. Note: “Atomic” here means an operation either completes entirely or doesn’t happen at all — there’s no partial, …

Read more
Engineering Notes

Cross-platform file locking in Python — fcntl vs msvcrt from scratch

What happens when a GUI app and a separate background process both try to write to the same configuration file at the same time? If the timing is bad, one write clobbers the other, and in the worst case the file ends up corrupted. File locking is the standard answer to this “concurrent writes from multiple processes” problem. Trying to implement it in pure Python across both Unix-like systems and Windows runs straight into a wall: the two platforms expose completely different APIs. This article walks through that difference from the ground up. Note: “lock” here means inter-process locking — coordinating multiple separate processes on the same machine. That’s different …

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
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