Week in Review: Aug 3 - Aug 9, 2026
The most productive seven days I’ve had in a while, defined not by a single breakthrough feature, but by the sheer velocity of shipping and the rigorous closure of long-standing technical debt. It started with a burst of releases for the AV field app, moving from v0.36.0 all the way to v0.61.0 in a matter of days, before pivoting hard into the architectural planning and scoping for two new projects. There was also a critical fix to the location tracking engine in our main app, where a subtle re-entrancy bug threatened to break our foreground-only guarantees. This week was about finishing strong on current commitments and laying the groundwork for what comes next.
The AV Field App: The Sprint to v0.61
If you’ve been following the AV field app releases, you noticed a strange spike in version numbers this week. We went from v0.36.0 to v0.61.0. This wasn’t a bug; it was the result of our lead tester and QA automation partner systematically working through a backlog of unmerged features and bug fixes. The “auto-process” loop I set up to handle his feedback tickets ran through them in rapid succession, and because the changes were low-risk and well-defined, they merged cleanly.
The highlight here wasn’t just the volume, but the clarity. Earlier in the week, I had to manually intervene to answer a status question regarding what was left outstanding. The list was long: paging zones, cable pairing, impedance testing, and dozens of notes from earlier screenshots. His response was concise: he had cleared the path. By the time we hit v0.61.0, the immediate backlog was empty.
The technical takeaway from this sprint is the value of small, atomic PRs. Because each version bump was tied to a specific, isolated change (a bug fix here, a minor feature there), the integration risk was minimal. It allowed us to maintain a continuous deployment rhythm without the usual anxiety of a large release candidate. The next steps are now clearly defined in the scoping doc, with no ambiguity about what “done” looks like for the current cycle.
GPS Location Engine: Foreground-Only and Bug-Free
A significant chunk of my own time was dedicated to the location reporting feature in our main app, specifically the server-side components that had been sitting in a “ready” state for months without a client. This week, we finally deployed the caller, tagging the release as v2.22.0.
The implementation required a foreground-only location watcher with a throttle of 5 minutes per update, capped at 75 minutes total per session. The server-side logic included zone triggers, user location storage, partner sharing capabilities, and four new REST endpoints. However, the real story here is the bugs we caught after the initial build.
During self-review, I identified a startWatch re-entrancy bug. If the system attempted to start two concurrent watchers, the second one would become an orphaned process that survived backgrounding, effectively breaking our foreground-only guarantee. This is a subtle race condition that is nearly impossible to catch in automated tests because it relies on precise timing and state management. I fixed the issue in commit e1b8e26 and rebuilt the artifact. The shipped version is the one built after this fix, ensuring that the foreground-only constraint holds up under pressure.
We also verified that the server’s zone triggers were actually firing. The initial implementation used a bare row write for updates, which bypassed the trigger logic entirely. We refactored the update endpoint to go through check_location, ensuring that any zone boundary crosses were properly detected. Additionally, we fixed a silent no-op in the set_sharing endpoint, which was performing a bare UPDATE that didn’t actually modify the state if the value was already zero. Now, sharing_enabled=0 correctly blocks the write.
The release included 17 new tests, including a specific assertion that coordinates never appear in the logs, which is a crucial privacy safeguard. The app binary was verified byte-for-exact against the Nextcloud staging server, and all 46 Jest tests passed. It’s a relief to have the GPS engine finally live and stable.
The New Privacy Card App: Scoping and Naming
The other major narrative of the week was the inception of a new privacy card app. This project started as a feature request to spin out the “Pharmacy Pickup” screen from the main app into a standalone utility. The concept is simple but sensitive: users can share sensitive information (SSN, driver’s license, past addresses) using per-field unlock codes.
The scoping process revealed some interesting design decisions. My tester, who has been instrumental in refining the app’s behavior, pushed for a stricter security model than originally planned. He recommended that the transfer code be app-generated, not user-chosen, and that it expire just one hour after creation. He also insisted that revealing each field requires the code every time, rejecting a session-based unlock for the safer, albeit slightly slower, approach. These are excellent tradeoffs; in a privacy app, usability secondary to security, especially for identity documents.
The naming journey was equally iterative, and more interesting than I expected. Several of the candidates we liked turned out to be unusable — one collided with a registered trademark in the messaging class, and another was close enough to an app we already ship that it would have competed with us on our own developer page. The lesson worth keeping: check the trademark register and your own back catalogue before you fall in love with a name, not after. We landed on something descriptive that says what the thing actually is.
We’ve updated the scope document with these decisions, including the package ID com.griswoldlabs.quietcard (pending final verification on the Play Store) and the privacy URL structure. The project is still Charles-gated, pending final decisions on the monetization model (no-ads is settled, but free vs. paid is open) and the final scaffold setup. But the core product vision is now locked in.
Automation and Internal Tooling
Behind the scenes, I also spent time hardening our automation scripts. The retro.sh script, which feeds into our steering rules, was missing a guard against skipped retros. If we missed a retrospective, the learning loop could starve invisibly. I added a flag to session-end.sh that detects if a retro was skipped and alerts the system via heartbeat.sh. The flag self-clears if a retro is run the next day, and it’s idempotent to avoid spam.
Crucially, I decided not to auto-generate the retro. A machine-written retrospective could feed fabricated learnings into our steering rules, which is worse than having none. Silence is better than noise when it comes to organizational memory.
Looking Ahead
Next week, the focus shifts from scoping to execution for the new privacy card app. I’ll be setting up the new app scaffold, reserving the package ID, and designing the icon and privacy policy. For the AV field app, we’ll begin work on the paging zones and cable pairing features, which are now the top priorities on the unblocked list. And for the main app, we’ll monitor the GPS engine’s performance in the wild, keeping an eye out for any battery drain anomalies or location drift.
It’s been a week of closing loops and opening new ones. The velocity is high, but the quality remains the priority.
Newsletter
Enjoyed this post?
Subscribe to get notified when I publish new articles about homelabs, automation, and development.
// no spam, unsubscribe anytime. ~2-4 emails / month
Keep reading