The Price of Being the Platform Binary
The last lesson put Delta on Apple's /usr/bin/python3, because that interpreter is allowed through the local network gate. That choice has a bill attached. Apple's python3 is Python 3.9, and you cannot pip install into it the way you would into an environment you own. So Delta is written for Python 3.9 with the standard library only. No requests, no aiohttp, no FastAPI, no third-party TLS. Everything a data channel needs, Delta builds from parts that ship with the interpreter:
| Need | Standard library piece |
|---|---|
| Two HTTP listeners, one thread per connection | http.server.HTTPServer with socketserver.ThreadingMixIn |
| Keep-alive client connections to each peer | http.client.HTTPConnection, pooled by Delta itself |
| TLS on the shared LAN, with a pinned certificate | ssl |
| Tickets, cache index, hash records, jobs | sqlite3 |
| Per-chunk and whole-file checksums | hashlib (SHA-256) |
| Constant-time token comparison | hmac.compare_digest |
The few family helpers Delta needs (reading the registry and port ledger, finding interfaces, judging free disk space, knowing which folders macOS guards) are vendored as single standard-library files from the family's shared kit, not installed. The installer's only dependency check is one line: can /usr/bin/python3 import ssl, sqlite3 and http.server? If not, install the Xcode Command Line Tools.
The LaunchAgent even starts the interpreter defensively: /usr/bin/python3 -B -E -s -m delta serve. -B writes no bytecode files beside the code, -E ignores every PYTHON* environment variable, and -s leaves the user's own site-packages off the path. Whatever someone installed for themselves cannot leak into the family's data channel.
How a 3.10 Construct Is Kept Out
A rule like "stay 3.9-compatible" is easy to break by accident. You write a match statement, an isinstance(x, int | str), a zip(..., strict=True), and it runs fine on your 3.12. So Delta does not rely on discipline. Its test suite runs in a named Conda environment (cwk-delta, Python 3.12 and pytest), but the end-to-end tests do not import Delta into that interpreter. They start two real daemons on /usr/bin/python3, each with its own fake home, state folder, ports and fleet label, and talk to them over loopback. Syntax that 3.9 lacks, such as a match statement, stops the module from importing, so the daemon never starts and every test fails. A call that 3.9 lacks, such as isinstance(x, int | str) or zip(..., strict=True), is different: it raises only when that line runs, so the suite catches it when a test drives the path that reaches it. That is why the end-to-end tests walk the real verbs, not just the start-up.
Note what is allowed. Delta's code has from __future__ import annotations at the top of every module but the package's two tiny entry files, so it can write dict | None in a function signature: under that import, annotations are stored as strings and never evaluated, so 3.9 never sees the |. The same | inside an isinstance call is evaluated, and 3.9 would reject it. The test that matters is not "does it look modern" but "does the real interpreter run it".
The Clock That Starts at Zero
Running on a different interpreter surfaces differences nobody documents. Delta's first day found one. On Apple's python3, time.monotonic() starts near zero when the process starts. On the Conda python3.12 most of the family uses, it reports something like the machine's uptime, often hundreds of thousands of seconds. Both are correct: a monotonic clock promises only that it never goes backward, not where it starts.
The bug came from a common idiom. A memo is initialized as (0.0, value), meaning "last checked at time zero", and refreshed when monotonic() - checked_at exceeds a limit. On a clock that starts at uptime, zero is ancient and the first call refreshes. On a clock that starts near zero, zero is a moment ago, and the memo looks fresh. In Delta that meant the identity document advertised no LAN addresses for the first 30 seconds after a start, and the tailnet roster refused callers for the first 5 seconds. The fix is a sentinel that is older than any clock reading: float("-inf"). Every "last checked" field in Delta now starts there.
The lesson generalizes: whenever you subtract a stored time from a clock, ask what the stored value means before the first real reading. If the answer is "zero", you are assuming where the clock starts.