Engineering Notes

Greedy vs. Non-Greedy Regex: Why the Same Pattern Can Match Differently

A regex quantifier like * or + means “the preceding element can repeat any number of times,” but how much it actually matches depends on whether the engine tries to match as much as possible or as little as possible. That’s the greedy vs. non-greedy distinction, and adding a single ? to a quantifier can produce a completely different result. This post works through that distinction using real parsing code from this app’s WP-CLI output handling. Quantifiers Are Greedy by Default Note: a quantifier is the part of a regex pattern that says how many times the preceding element may repeat — * (zero or more), + (one or more), …

Read more
Engineering Notes

Log Level Design and Rotation: Why Apps Use DEBUG/INFO/WARNING/ERROR

Open any application log and you’ll see the same kind of message tagged with different labels: DEBUG, INFO, WARNING, ERROR. Why not just write down everything that happens, in one uniform stream? This post looks at what log levels actually do, and at the companion problem every long-running app eventually faces: keeping a log file from growing forever (rotation). A Log Level Is a Filtering Threshold Note: logging means recording what happened while a program runs, so it can be reviewed later in a file or on screen. Python’s standard logging module defines five levels: Level Numeric value Meaning DEBUG 10 Fine-grained detail for tracing exactly what the code did …

Read more
Engineering Notes

The Principle of Least Privilege: Why File Permissions Like 600/644/755 Exist

Anyone who has worked with SSH private keys has run into an instruction to “set it to 600.” Config files, by contrast, often get 644, and executable scripts get 755. What do these three-digit numbers actually mean, and why does the right number depend on what kind of file you’re dealing with? This post starts from the mechanics of Unix-style (Mac/Linux) file permissions and works up to the design principle behind them: least privilege. Permissions as a 2D grid of who and what Unix-family operating systems express file access as a grid: three kinds of “who” crossed with three kinds of “what.” “Who” breaks down into the file’s owner, the …

Read more
Engineering Notes

Unit Tests vs. Regression Tests: Why the Same Feature Gets Tested Twice

Look through a maintenance tool’s test suite long enough and you’ll run into a small puzzle: a function already has a test, so why does another file add a second one for what looks like the same behavior? Two tests that appear to cover the same ground can actually exist for entirely different reasons. This post walks through the distinction between “unit tests” and “regression tests,” using real test code from this project as the example. Unit tests: verifying a function in isolation Note: a unit test checks the smallest testable piece of a program — a function, class, or method — independently from the rest of the system. A …

Read more
Engineering Notes

How Desktop Apps Detect and Kill Stale Processes on Startup

You close a desktop app, but its process is still sitting there in the task manager or Activity Monitor. Many people have run into this. This article looks at the design behind a common fix: detecting a leftover process from a previous run at startup, cleaning it up safely, and only then starting fresh. Why a Process Can Fail to Exit A Python desktop app built with a Flask backend and a browser as its display, packaged into a single executable with PyInstaller, often relies on a hard-exit call like os._exit(0) to shut down. The catch: calling this from a background daemon thread doesn’t always terminate the process in a …

Read more
Engineering Notes

Semantic Versioning (SemVer): Why Version Numbers Have Three Parts

Most software version numbers look like 1.6.11 — three numbers separated by dots. This isn’t an arbitrary naming choice; it follows a widely adopted convention called Semantic Versioning, or SemVer. This article looks at why version numbers are split into three parts, and what it actually takes to implement that convention correctly in code. What MAJOR.MINOR.PATCH Each Mean SemVer formats a version as MAJOR.MINOR.PATCH (for example, 1.6.11), and each position carries a distinct meaning: MAJOR: incremented when you make a breaking change — something that could stop existing usage from working MINOR: incremented when you add functionality in a backward-compatible way — existing usage keeps working PATCH: incremented when you …

Read more
Engineering Notes

How Symmetric Encryption (Fernet) Keeps Local Credentials Safe on Disk

Desktop apps that talk to servers over SSH or an API often need to remember a password or key between launches. Asking the user to retype it every time isn’t realistic, but saving it as plain text in a config file is risky — the moment that file ends up in a backup, a sync folder, or gets shared with someone for debugging, the credential is exposed. This post looks at how symmetric encryption solves that specific problem, using Python’s cryptography library and its Fernet recipe as a concrete example. Note: Symmetric encryption uses the same key for both encrypting and decrypting. That’s different from the SSH keys covered in …

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