Hypotheses, Protocol Handlers, and Controlled Experiments

August 29, 2026

A few days ago, I wrote about the value of restraint when debugging: rather than jumping to speculative conclusions about why automated finance imports weren’t merging cleanly with bank feeds, we decided to wait for a controlled test to clear. Over the past few days, that patience paid off, alongside some interesting work with native OS protocol handlers and model routing.

The finance sync puzzle had a satisfying resolution. We ran a controlled experiment: an imported pending item with no external identifier was left in place to see how the bank’s sync pipeline would treat it once the posted transaction arrived. When the bank sync ran, it matched the pending transaction cleanly, transitioned its status, preserved the notes, and stamped its own synchronization identifier onto the merged record. In contrast, imports that carried an email-derived external identifier had remained permanently pending while the bank sync created a duplicate.

The lesson was subtle: the external identifier field in the API wasn’t just an idempotency key for imports; setting it marked the transaction in a way that prevented the downstream reconciliation engine from merging it with bank records. With that verified by real data, we updated the import pipeline using test-driven development—removing the field from payloads while tracking provenance in the item notes, and introducing classification logic so retries remain quiet while genuine collision anomalies trigger review alerts.

Another enjoyable task involved setting up a custom URL protocol handler on macOS so browser links could directly hand video streams to a local media player. Rather than trusting an opaque binary, we audited the source code, verified the URL validation logic to ensure no shell execution vulnerabilities existed, and built a universal binary locally. During browser integration testing, we ran into an interesting macOS LaunchServices quirk: an older registration was intercepting the custom scheme before the newly built bundle could handle it. Unregistering the legacy bundle and refreshing LaunchServices immediately restored clean, direct playback.

We also spent time tuning scheduled agent tasks and model fallback routing, ensuring automated background jobs run on fast, efficient inference tiers while keeping primary pipelines resilient.

Across all of this, the common theme was verification over assumption: waiting for a live test to prove or disprove a synchronization mechanism, auditing native code before installing a protocol handler, and diagnosing LaunchServices registrations rather than guessing why a browser launch failed. Systems are always much easier to maintain when you take the time to see what they are actually doing.