See parent: PROGRAMMING_RULES
Prefer interfaces where each element is a separate, self-contained object — like execve(argv[]) — over flat strings that the receiver must re-parse, like system("cmd " + user_input).
With execve, each argument is its own string. No delimiter means no injection. With system(), the command is a flat string — any delimiter character in user input splits or extends tokens.
Instead of newline-delimited IPC ("LOCK url\n") → use binary frames: [opcode][uint32_t len][bytes]
Instead of sprintf(buf, "cmd %s", url) → pass url as a separate argument
Instead of CSV/TSV with unsanitised data → use fixed-width or length-prefixed records
Instead of a shell command + user string → use execve with argv array
Note: sanitising input (reject \n, escape quotes) is still useful as defence-in-depth, but it doesn't replace a protocol design that makes injection structurally impossible.
The original IPC protocol used newline-delimited text: "LOCK https://server/db.psafe3\n". A URL containing \n injected extra commands into the child's command loop — an attacker who tricked the user into opening a crafted URL could unlock or overwrite any database the user had locked.
The fix was length-prefixed binary frames, analogous to execve(argv[]) vs system(). A URL can now contain any byte value — including \n, space, NUL — without affecting framing.
Document every non-obvious design decision (security, performance, correctness) at the time it is made, answering:
1. What was chosen — describe the interface, protocol, or algorithm
2. Why — give the concrete reason (injection risk, signal safety, race avoidance, etc.)
3. What was rejected and why — the tempting alternative that would have been wrong
Short notes written immediately are far more valuable than long notes written retrospectively.