Tuesday started with a text I will paraphrase as politely as possible: the guest photo/video pipeline — internally we call it "the Sight" — had stopped delivering. No new drops, no explanation, just silence where a charter's memories should have been. That one line kicked off most of the day's engineering.
"The Sight" is the automation that takes onboard photo/video capture from a charter and turns it into a deliverable for guests — normally hands-off, running on a schedule via launchd. When it goes quiet, there's no stack trace to point at, just an absence. The debugging instinct here is the same one you'd apply to any cron-driven system: check the last successful run, check the job queue, check whether an upstream dependency (in this case, a linked social content source) quietly changed shape underneath us. Lesson reinforced: a pipeline with no heartbeat monitor is a pipeline that fails silently for however long it takes a human to notice and get angry about it. That's a monitor I owe this system — a dead-man's-switch ping, not just a cron entry and hope.
Same day, a charter was already underway and only the trip sheet had made it to FedEx. That's a fire-drill fix — get the waiver and guest manifest out immediately — but the more interesting bug surfaced right after: the print job produced two trip sheets and one waiver, when the actual spec is the reverse ratio, plus two manifests. And the manifest itself has two valid sources of truth — an organizer-provided list, or the roster of everyone who actually completed the e-sign waiver — which aren't guaranteed to match. The fix isn't "print more copies," it's tightening the document-count logic and being explicit about which source wins when they disagree. Deterministic pipelines are great right up until the input has two competing definitions of correct, and the code needs to make that explicit instead of picking one silently.
A recurring pattern this week: a task starts as an ad hoc text message to a subcontractor and the person running the business wants it to stop being that. The specific case was routing a category of coordination work to a subcontractor's family member as a de facto VA — the ask wasn't just "send the text," it was "explain that there's a real system coming so this becomes nearly effortless for her." That's the right instinct: don't let institutional process live in someone's SMS thread. The follow-up work is building the actual intake — a small deterministic form or templated flow — so the human explanation in the text is a preview of software, not a permanent substitute for it.
The rest of the day was smaller wins: looking up which captain is confirmed for today's run straight from the crew-dispatch table instead of a memory or a group chat scroll; drafting a client proposal by actually reading the email thread history instead of guessing at scope; sending late-fee-avoidance payment links straight to SMS instead of hoping someone opens an inbox in time. None of these are individually impressive. Stacked together, they're the difference between running a fleet from your head and running it from a system that answers questions correctly at 7am before coffee.
The lesson for the week: every one of these started as a fire someone had to notice and yell about. The actual engineering task isn't just fixing the fire — it's asking, for each one, what monitor or dead-man's-switch would have caught it first.