Engineering Notes

Git’s Staging Area — What Actually Happens Between `git add` and `git commit`

Edit a file, run git add ., then git commit -m “…” — for most people these two commands feel like a single operation performed in two keystrokes. But why are they separate commands at all? What happens if you edit the file again after git add but before git commit? Many developers who use Git daily can’t answer either question cleanly. This article walks through the staging area, the mechanism sitting between those two commands. The three-area mental model Note: A common way to understand Git is the three-layer model — the working directory, the staging area (also called the index), and the repository. A change has to pass …

Read more
Engineering Notes

pip Version Specifiers — What `==`, `>=`, and `~=` Actually Commit You To

Anyone who has written a requirements.txt file has probably paused at the line after the package name. Leave it blank, pin it with ==3.0.0, set a floor with >=3.0.0, or split the difference with ~=3.0.0 — they look similar, but each one makes a completely different promise about what gets installed in the future. This post walks through pip’s version specifier syntax, then looks at why our own tool’s requirements.txt picked one particular style, and what that choice trades away. The question a version specifier is answering Note: pip’s version specifiers follow PEP 440. Writing an operator and a version number after a package name tells pip which range of …

Read more
Engineering Notes

UTF-8 vs. cp932: Why Some Bugs Only Show Up on Japanese Windows

“It works fine on my Mac, but it crashes the moment we hand it to Windows” is a report a lot of developers eventually hear. More often than not, the culprit is a character encoding mismatch. This post walks through the basics of text encoding, then looks at a real build-pipeline crash this project ran into, and the test written to make sure it never happens again. What an Encoding Actually Is Note: a character encoding is the lookup table a computer uses to convert characters into bytes for storage or transmission. The same character can turn into a completely different byte sequence depending on which encoding is used. When …

Read more
Engineering Notes

Exponential Backoff vs. Fixed-Interval Retries: When Growing Wait Times Actually Help

How to retry a failed operation is a design question every network-facing piece of code eventually has to answer. The textbook technique is exponential backoff — doubling the wait time on each retry — but it isn’t automatically the right answer everywhere. This post works through what problem exponential backoff actually solves, then looks at three real retry paths in this app’s own code where fixed intervals were chosen instead, and why. The Problem Exponential Backoff Solves Note: exponential backoff is a retry strategy where the wait time between attempts grows exponentially — 1s, 2s, 4s, 8s, and so on — instead of staying constant. base = 1 for attempt …

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