SECTION 0x19·ARCHIVE
The Archive
Every post, newest first. 219 entries.
EverCV now emails you a weekly engineering report, automatically
Pro feature: enable scheduled weekly delivery in your dashboard. Every Sunday, EverCV generates a polished weekly status summary from your CV activity — highlights, deliverables, blockers, next week focus — and emails it to you. Markdown, HTML, or Slack format.
TicketScope can now draft your Microsoft Premier and Cisco TAC escalations
New Pro endpoint: POST /vendor-escalation generates a complete vendor support case from ConnectWise ticket notes. Covers Microsoft, Cisco, Datto, VMware, Fortinet, Meraki, Veeam, CrowdStrike, Sophos, and more. Chrome extension sidebar updated.
NightDesk can now tell you exactly how much money it saved you
New endpoint: GET /admin/tenants/{id}/roi?days=30 calculates ROI from real call data — calls handled, minutes saved, dollars saved vs plan cost, payback period. The number you need at a QBR.
NightDesk now accepts pilot requests directly from the landing page
The NightDesk landing page form is now wired to a real endpoint. POST /demo-request captures pilot interest (email, company, team size, notes), saves to DynamoDB, and pings Chester via SES. Zero friction for an MSP owner who wants in.
EverCV can now write your weekly engineering report
New Pro feature: POST /api/weekly-report generates a polished weekly status summary from your commit history, tickets, and time entries. Outputs Markdown, HTML, or Slack-formatted mrkdwn. Optional email delivery.
TicketScope drafts client-facing status update emails in one click
Three new buttons in the TicketScope sidebar: In Progress, Waiting on Client, Resolved. Each drafts a professional client-facing status email with a subject line. Copy, paste into CW, done.
My AI agent built five products while I slept
What it looks like when you hand a 5.5-hour autonomous window to an agent and come back to 806 tests passing and five code-complete SaaS products.
NightDesk now takes Stripe — from ROI calculator to live subscription in one click
NightDesk's billing layer is live: Stripe Checkout for three tiers, webhook handling for the full subscription lifecycle, and a /billing/status endpoint that drives plan enforcement. The ROI page now converts.
NightDesk now has a call analytics endpoint for MSP ROI reporting
A new GET /admin/tenants/{id}/stats endpoint gives MSP owners 7- and 30-day call stats: total calls, resolution rate, escalation counts, average turns, and per-customer volume. The number you need when someone asks if the AI is actually working.
EverCV writes your LinkedIn headline and About section
A new Pro endpoint reads your stored CV and generates a LinkedIn headline (≤220 chars, keyword-rich, human-readable) and an About section (200–400 words, first-person narrative). The two LinkedIn fields most recruiters read first.
EverCV now pulls from Jira, Linear, and Google Calendar
Most engineering work lives in tickets and meetings, not commits. EverCV's new Jira, Linear, and Google Calendar adapters pull your completed issues and calendar load into the same CV pipeline as your GitHub activity.
EverCV's JD analyzer tells you how well you fit before you apply
A new Pro endpoint reads the job description and cross-references it against your stored CV: must-haves, nice-to-haves, keywords to mirror, fit assessment, and red flags. Read it before writing the cover letter.
CostWatch now serves a public AWS cost badge for GitHub READMEs
New GET /badge/{user_id} endpoint returns a shields.io-compatible SVG showing your MTD AWS spend with green/yellow/red color coding — opt-in only, so you can't accidentally leak costs.
CostWatch now includes diagnostic hints for AWS cost anomalies
When CostWatch fires an anomaly alert, it now includes a one-line diagnostic checklist specific to the AWS service that spiked. No AI, no latency — pure heuristics that surface the most common causes first.
Brand Monitor now has a weekly mention badge you can embed anywhere
New GET /badge/{user_id} returns an SVG showing your weekly mention count with a trend indicator — green when flat or growing, yellow with a ↓ when you're down week-over-week.
Brand Monitor now filters mentions by context to cut false positives
New keyword context field: add 'ignore: word1, word2' and Brand Monitor skips any mention whose title or body contains those terms. The fix for brand names that appear in unrelated contexts.
TicketScope now drafts KB articles from resolved tickets
One click after resolving a CW ticket, TicketScope drafts a structured knowledge base article: symptom, root cause, numbered resolution steps, affected systems, and category tag. Copy to clipboard, paste into your KB.
One smart quote crashes an overnight pipeline
A non-ASCII em-dash in a job listing silently killed the HN scraper every night. The root cause: SQL_ASCII Postgres + a UTF-8 client_encoding that refused to talk to each other. Three lines fixed it.
OSS Pulse now pages PagerDuty when a critical CVE hits your dependencies
A critical CVE in a library you depend on is a security incident, not a notification. OSS Pulse Enterprise now fires a PagerDuty alert when CVSS ≥ 7.0 is found in your stack.
The thing blocking AI adoption in MSPs: nobody wants to write the configuration
The #1 reason MSPs don't adopt AI triage tools isn't cost or trust — it's the 2-hour setup task of writing a runbook from scratch. NightDesk's new auto-generator makes it a 20-second review instead.
The funnel math of automated job hunting
2,396 job listings in the pool. 391 with score ≥ 65. 80 applied. 192 queued for manual review. Here's what the data looks like when you build an automated apply pipeline and actually run it at scale.
Adding a warm intro request generator to the job application kit
EverCV's Pro tier now has five AI endpoints. The newest: given a job description and a mutual contact, draft the optimal referral ask message — subject line, message body, follow-up, and a connection value assessment.
The one feature that pays for a year of subscriptions in a single use
EverCV's new salary negotiation advisor generates a ready-to-send counter-offer email, talking points for the phone call, and a walk-away number — all from your offer details and market context.
EverCV's new salary estimator: know the range before you apply
EverCV Pro now has a salary estimator that gives you a market range (low/median/high) plus a negotiation floor before you enter a salary conversation — not after.
The math behind your job offer: why base salary is the worst number to compare
Two offers with the same base salary can be $200k apart over four years. EverCV's new offer comparison tool does the 4-year total comp math in Python — not AI estimates — so the numbers are trustworthy.
The last email you write before you become an employee
Most engineers send a sloppy 'sounds great, see you then' after accepting an offer. EverCV's new offer acceptance drafter writes a proper formal confirmation that starts the relationship right.
EverCV now drafts your post-interview thank-you email
A generic 'I enjoyed our conversation' does more harm than good. EverCV Pro drafts a specific thank-you that references what was actually discussed.
The feature that turns interview prep from 2 hours to 20 minutes
EverCV's new company research tool generates a pre-interview dossier from a job description: tech stack, culture signals, smart questions, and red flags. Here's why I built it and what it actually outputs.
EverCV now analyzes your application funnel
If you don't know where in the funnel you're dying, you can't fix it. EverCV Pro now tells you.
CW Bridge now fans out to Microsoft Teams
The ConnectWise → Slack bridge now delivers ticket events to Teams channels in parallel, opening the product to Teams-primary MSPs.
CostWatch can now tell you if you're on track to blow your AWS budget
CostWatch's new forecast endpoint computes your month-to-date AWS spend, daily run rate, and projected end-of-month total — then flags on_track, at_risk, or over_budget against your monthly budget.
CertWatch now pages PagerDuty when your cert is about to expire
Slack and Discord are great for low-urgency alerts. But if a cert expiring in 1 day doesn't wake someone up, it's not an alert — it's a notification nobody reads. CertWatch now supports PagerDuty via the Events API v2.
CertWatch now monitors HTTP uptime — not just cert and domain expiry
CertWatch has always warned you before a cert expires. Now it also alerts you the day your site stops returning 2xx/3xx — before you find out from a customer.
CertWatch Pro now lets you set custom alert thresholds per domain
Some domains need a 60-day heads-up. Others, you don't care until 7 days. CertWatch Pro's new per-domain alert ladder lets you configure exactly when you want to be notified, per domain.
Brand Monitor now alerts on Teams and PagerDuty
Brand Monitor's spike alerts now fan out to all four notification channels: Slack, Discord, Teams, and PagerDuty. So your brand mention hits Hacker News at 2 AM and your on-call rotation gets paged.
Brand Monitor now alerts on Discord — where indie hackers actually live
Slack is for enterprise teams. Discord is where indie hackers, OSS maintainers, and solopreneurs hang out. Brand Monitor now sends real-time spike alerts and weekly digests to Discord alongside Slack.
One JD, four AI outputs, one click
The EverCV Job Application Kit runs all four Pro AI features in parallel — cover letter, tailored summary, skills gap, and interview prep — from a single job description paste.
The cover letter is the last piece of the job application suite
Added a cover letter generator to EverCV. It's the fourth Pro AI endpoint — tailor, gap-analysis, interview-prep, and now cover-letter — and the one that ties the whole workflow together.
Five micro-SaaS products I built in 8 overnight passes
An AI agent writes code from midnight to 6 AM. I review in the morning. We've shipped 8 products this way. Here's what it unlocks — and what it doesn't.
OSS Pulse: tracking dependency health before your users notice
A package you depend on gets abandoned. No alert, no fanfare. Users hit a 5xx three months later when a transitive dep breaks. OSS Pulse watches for that.
NightDesk: voice triage for MSP after-hours calls
How I built a Twilio + Claude voice agent that handles MSP after-hours calls — covering stateless multi-turn conversation over GATHER, runbook injection, and CW ticket creation.
Adding Slack escalation to an AI MSP voice triage system
NightDesk already escalated P1 calls via SMS and Microsoft Teams. Adding Slack took 40 lines — including the Block Kit message, target URL resolution, and tests for all three failure modes.
How NightDesk decides whether to wake up an engineer at 2am
The triage kernel is a three-action loop with a deliberate bias toward escalation. False escalations are cheap — annoyed techs go back to sleep. False non-escalations lose clients. The architecture follows from that single principle.
Building a 4-step onboarding drip that actually teaches the product
Most onboarding emails just say 'welcome.' EverCV's 4-step drip at days 1, 3, 7, and 14 teaches the product in the order users are ready to hear it — with different copy for free vs. Pro.
Adding a job application tracker to EverCV
EverCV now has a job application tracker built in — POST to add applications, GET to list them, PUT to update status as you move through the pipeline. Color-coded badges in the dashboard (applied → interviewing → offer).
One curl command to check any cert and domain — CertWatch's public API
CertWatch has a public /check/public endpoint that returns cert expiry, chain validation, and DNS resolution for any domain in one HTTP call. No signup, no API key, rate-limited to 3/min. The paid-tier /check endpoint adds domain expiry and doesn't rate-limit.
The 8 minutes MSP techs spend writing the same time entry every day
Every resolved ticket needs a billable time entry with clean, client-facing notes. I added an AI draft endpoint to TicketScope that turns a messy ticket thread into professional billing notes in one click.
Closing the payment loop on 3 micro-SaaS products in one overnight pass
Every product had Stripe webhooks but no way to start a checkout. Here's the pattern I used to fix all three at once.
Checking open-source dependency health from your CI pipeline
I added an unauthenticated JSON endpoint to OSS Pulse so you can check whether a dependency is still actively maintained without leaving your terminal.
Two clicks to monitor your whole open-source stack
How I built package.json / requirements.txt import into OSS Pulse — from paste to watching 40 repos in under 10 seconds.
2,293 listings. 77 sent. The funnel nobody talks about.
A breakdown of where job applications actually die: dead links, misfiled status, truncated URLs, and the needs_manual graveyard.
Adding a team plan to EverCV: one owner, four teammates, shared Pro access
How I built EverCV's team tier — invite by email, inherited feature access via a single field, per-member usage counters with atomic DynamoDB increments, and a usage analytics dashboard.
Three endpoints that cover the whole job search
EverCV now has tailor, gap analysis, and interview prep. Here's why I built each one and what the system prompt looks like.
Your CV updates itself on every git push
I added a CI token endpoint to EverCV so you can trigger a CV rebuild from GitHub Actions. One curl step in your workflow and your CV rebuilds within 30 seconds of every push to main.
The work that never made it into the CV
Added a done-log endpoint to EverCV — a simple POST you can hit from a terminal alias to log work that isn't in any connected system. Client work, docs, research, anything without a commit.
I built a personal AI assistant. Here's what a year of daily use taught me.
I've been running an AI chief of staff for myself since late 2024. Here's what actually works, what doesn't, and why I'm now offering it to three other people.
Rendering a 30-day AWS cost chart with no charting library
How I built a per-account spend sparkline in the CostWatch dashboard using the HTML5 Canvas API and Cost Explorer's DAILY granularity — no Chart.js, no external dependencies.
Downloading your AWS cost history as a CSV
Added a CSV export endpoint to CostWatch. GET /account/{id}/export downloads per-day cost broken out by every AWS service — no top-5 cap, no console required.
I built a cheaper alternative to AWS Cost Anomaly Detection
AWS Cost Anomaly Detection costs $8/mo and sends you a report that requires navigating Cost Explorer to understand. CostWatch is $5/mo with a plain-English email.
Build Your Own Cass: the course
A year of building a personal AI agent, distilled into 8 modules. The architecture decisions, the production mistakes, and the code that actually runs.
Three endpoints that cover the whole job search
EverCV now has tailor, gap analysis, and interview prep. Here's why I built each one and what the system prompt looks like.
The three failure modes that kill personal AI agents
Every failed personal AI assistant project I've seen breaks down the same three ways. Here's what they are and how to avoid them.
Two scoring systems that never talked to each other
The job pipeline scraped 64 fresh listings and the apply cron found zero qualifying ones. The bug was a missing source bonus — 11 lines that had been out of sync for weeks.
Eight products, one night: what autonomous AI agents actually ship
I've been running Claude autonomously on my homelab from midnight to 6 AM. Here's an honest accounting of what it's actually produced.
Real-time voice triage with Twilio, Claude, and ConnectWise
How NightDesk's real-time triage kernel routes after-hours MSP calls — every turn of the conversation, not after the call ends.
The 6-hour window: why you need to know when your product appears on HN
A Hacker News thread about your product is the highest-leverage 30 minutes of your day — if you're there for it. Most founders aren't.
I automated my job search. Here's what actually works.
Six months of building a job application pipeline with Claude and AWS. The architecture, the failure modes, the current state of the system.
When the pool runs dry: scoring functions and the empty-pipeline problem
My auto-apply pipeline hit a wall: 971 job listings marked new, zero qualifying applications. Here's what the scoring distribution revealed and what to do about it.
Why TicketScope is a Chrome extension first, not a Marketplace app
The ConnectWise Manage app marketplace would take 6-8 weeks to review. A Chrome extension takes 60 seconds to install. Here's why I started with the extension.
The SQS FIFO queue that lets a Lambda run 50 overnight jobs without timing out
Lambda has a 15-minute execution limit. An overnight job that processes 50 items needs hours. The coordinator/worker/SQS FIFO pattern solves this — each item gets its own Lambda invocation and full timeout.
The one wrapper that makes LLM tool calls production-ready
An LLM agent that lets exceptions propagate from tool calls will silently stop working at 2 AM. One wrapper function prevents this — and it changes how you design every tool.
The OSS dependency that was unmaintained for two years before we noticed
A production service depended on a library whose last commit was 2019. No CVEs, no alerts — the library just quietly stopped being maintained. We noticed when it blocked a Node upgrade.
What happens when your MSP client calls at 11pm
Most MSPs have an after-hours number that goes to a human. One call center quote later, that answer becomes 'voicemail.' Here's what I built instead.
The resume that updates itself
Why resumes are always stale, and the GitHub-connected CV that patches itself overnight from your actual commit history.
The DynamoDB memory that survived 6 months of production
How to give a personal AI agent durable memory using DynamoDB — the four-table schema that handles conversations, facts, preferences, and tools without ever running a migration.
The Slack notification that would have posted 200 times on day one
How I learned that notification products have two failure modes: the day-one flood and the ongoing noise. A ConnectWise-to-Slack bridge built around both.
The cert that expired at midnight and nobody knew until 9 AM
A production TLS cert expired while everyone was asleep. Nine hours of quiet downtime before the on-call engineer caught it. This is why I built CertWatch.
The AWS bill that tripled (and how I didn't notice for six days)
How an EC2 instance I forgot to terminate ran for six days before I noticed — and the tool I built to make sure it doesn't happen again.
The AI chief of staff is a job title waiting to be invented
Founders pay $8k/month for a human EA who does scheduling and email triage. The same workflow runs on $25 of Claude API calls. Here's what's missing.
The agent wrote the course
I used an overnight autonomous agent to build a course about building overnight autonomous agents. The irony is useful.
The fallback that wasn't
A one-line bug in the apply pipeline: Firebase was labeled the primary source for HN listings, raw_context was the fallback. When primary returned empty, fallback never fired.
A live dashboard for an overnight coding agent
Autonomous agents are finally good enough to run unattended. The missing piece isn't capability — it's seeing what they're doing. Here's a ~120-line dashboard that streams an agent's progress and texts me only when it matters.
The other half of noise: digest mode for notification products
Quiet bootstrap fixes the day-one flood. Digest mode fixes the *ongoing* flood. A notification product has two failure modes; both have to be paid attention to, or the product feels broken.
The missing converter: how a single missing file blocked six nights of output
An overnight pipeline drafted a blog post six nights in a row and shipped zero of them. The blocker was two files that didn't exist on the host.
Quiet bootstrap: the day-one experience of a notification product
A notification product whose first tick is loud doesn't get a second tick. Build the silent-snapshot path before you build the alerting path.
Whitelist beats blacklist when the input variety is unbounded
A title filter that keeps falling behind doesn't need more reject tokens. It needs to flip into a whitelist.
When the URL outlives the job
Why fetching JD bodies at ingest beats lazy-fetching at apply time, learned 242 dead URLs at a time.
How to keep an LLM from sounding like an LLM (on a CV)
Specific bans beat vague style guidance. Prompt rules from the EverCV renderer.
The smoke test caught a real prod bug on the first run
I wrote a post-deploy smoke test for my SaaS the way you're supposed to: small, focused, fail-the-deploy-if-the-URL-doesn't-serve-what-you-just-uploaded. Then I ran it against production. The test failed. The bug had been live for four days.
Cass-failover: the Route 53 trick I should have used years ago
Route 53 has a failover routing policy that's been there forever and I've never used it for the obvious thing: keeping a homelab service answerable from the public cloud when a hurricane takes the house down.
The repo with the same name was the dead app
I spent a couple of hours one afternoon making changes to what I thought was the current iOS source tree for a side project, running builds, watching…
Draining a job queue before redeploying
A long-running service that does work in the background needs a deploy strategy that doesn't drop work on the floor. This is the rule I landed on after…
Generating a leather pattern as a tabloid-size PDF
I wanted a coffin-shaped wallet pattern I could print and saddle-stitch. Online templates are mostly rectangles. The interesting work was turning a…
A 7-day forward lens for the things I already track
I have a morning briefing that summarizes today (weather, todos, calendar, bills, sobriety counter). Useful. But it's only today, and it's spoken once on…
Hurricane failover for a homelab assistant without paying Bedrock prices
My homelab assistant lives on an LXC in the garage. Hurricane season runs June through November on the Gulf Coast. A two-week power loss takes my whole…
Brand-aware location reminders without a custom geocoder
I wanted to add
When every summer storm is a high-severity alert
A safety-monitoring side project I run paged me at 09:00 with
Gradle OOM on Android builds: just give the JVM more heap
Android build was failing partway through with a Gradle OutOfMemoryError. First few times I assumed it was a flaky CI worker. Then it failed locally too.
Three permission dialogs for a working safety app on Android
A safety app I shipped for personal use on Android needs three distinct runtime permissions to actually do its job. Walking a first-time user through…
A tiny garden sprinkler watcher that only texts when it matters
I turned the garden sprinkler off because rain was forecast for a week. The question is: when do I turn it back on? I do not want to check a weather app…
Routing 24 silent catches to a real error bus
The
Disk full on the staging dir at 01:14 in the morning
I run a small S3-compatible proxy that fans writes across several cloud accounts to dodge per-account upload caps. It went into
UI Automation beat my screenshot loop by 17x
I had built a Windows desktop agent around the obvious loop: take a screenshot, send the PNG to a vision LLM, ask where to click, click it, repeat. It…
A tiny S3 proxy in front of a pool of Drive accounts
I had ~50 TB of media I wanted to back up off-site. Synology HyperBackup can speak S3. Google Drive Workspace gives you generous per-user storage, but…
Never build new things inside the assistant
I built a small water-tracker for myself: pick a bottle preset, tap a button, get a daily total. First version landed as a few /water/* routes inside the…
Hanging the API at scale: SQLite was the wrong default
A custom backup engine I wrote was happily writing tens of thousands of chunk rows to SQLite. Then I bumped concurrency from two backup jobs to ten, and…
Recovering orphaned jobs after a worker restart
A backup service kept getting into a state where the worker queue showed
A dashboard deadlock from missing per-task timeouts
My homelab home page started returning 504 for its /api/dashboard route. Nothing else was obviously broken. The page just hung.
Why Google Drive eats HyperBackup, and what to do instead
I had 27 TB of stuff on my NAS that I wanted backed up to Google Drive. Synology HyperBackup ran for weeks, made it about a third of the way, and the…
Turning years of screenshots into a searchable journal
I have a Mac screenshots folder with thousands of files. Most of them are chat conversations — iMessage, Signal, Teams, email — captured because I wanted…
Moderate risk alert at midnight, awake at the desk
A side-project safety app generated a moderate-severity risk alert for me at 00:28 local time. I was at my desk, awake, trading messages with two…
The crontab edit that loaded a stale /tmp file
I wanted to bump the cadence of one cron job from every 15 minutes to every 10. Three minutes later, seven of my scheduled jobs were gone — replaced with…
OCRing the live screen was the wrong validator
I built a small nightly QA runner for my personal iOS apps. It builds each app, boots a simulator, installs and launches, takes a screenshot, and OCRs…
A wall-clock guard so cron jobs don't drift across DST
I wanted a nightly job to fire at exactly 00:00 Central, every night, forever. Debian's vixie-cron doesn't support CRON_TZ, and the host runs in UTC. The…
Driving a Windows VM install with qm sendkey
I needed to slipstream a Windows 11 install across a handful of VMs on Proxmox without sitting in front of a noVNC window pressing Enter for an hour. The…
Never let the test agent grade itself
I have a small nightly QA runner that exercises my personal apps — builds them, drives them, takes screenshots, asserts they actually work. The single…
Five cron jobs sharing one atomic-rename temp file
Five Python pollers, one per messaging source, all on *. Each one writes a shared cursors file to remember where it left off. The dashboard showed…
Date-scoped views on a todo list, with a sensible default
I migrated from Todoist to my own todo app a few weeks ago. The single biggest thing I missed: Todoist's Today / Upcoming views. So I built them.
When a ThinkPad disappears from the LAN after a NIC swap
Swapped a USB-to-Ethernet adapter on a ThinkPad to fix a flaky link. After the swap, the laptop dropped off the network entirely. No reservation hit in…
Tightening Radarr quality profiles to stop Emby transcode lag
Avengers playback was crawling on Emby. Not network, not the client — the Synology CPU was pinned, fan howling, every play.
qBittorrent was deleting files before Sonarr could import them
Sonarr's queue kept stalling. Episodes would show up as grabbed, sit in the queue, and then quietly fail to import. Re-grabbing the same release didn't…
My per-todo chat was a toy LLM in a tool-capable house
My web todo app has a little chat button on every todo row. The idea: open a todo, ask the assistant
Migrating from Todoist with an idempotent import
Migrated all my active Todoist tasks into my own todo backend. 27 tasks across 6 categories (birthdays, bills, dev backlog, groceries, issues for a…
How to survive AWS toll-free SMS registration
A toll-free SMS number for a personal safety project I run took several denial cycles before AWS approved it. The denials were all about wording in the…
Throttling doorbell notifications to the ones that matter
I rolled out face-recognition notifications on my front-door doorbell and got spammed with hundreds of pushes in a few hours. I killed the cron, audited…
Door unlock on iPhone SOS when Apple won't expose the event
I wanted my front door to unlock automatically when my iPhone or Watch triggered Emergency SOS or Fall Detection. The catch is that Apple does not expose…
Ring IR mode breaks face-distance thresholds
I have a small face-identification pipeline running against snapshots from my doorbell. It uses a fixed distance threshold to decide whether a face…
qBittorrent's auto-remove racing arr imports
Symptoms looked like the same old
Hyper Backup stuck in a scan loop over live LXC subvolumes
My Synology Hyper Backup job to Google Drive kept restarting and never finishing. It would run for hours, get most of the way through the scan, then bail…
A $25 bed occupancy sensor for Home Assistant
I wanted Home Assistant to know whether the bed was occupied, and by whom, so it could drive lighting, HVAC setbacks, and a few
Backfilling Signal history that the server doesn't have
I wanted my homelab assistant to have access to my Signal history the same way it has my iMessage and email. Signal's whole point is that the server…
Shipping an iOS build headlessly over SSH
I wanted to build and install my iOS app from a remote agent session — no Xcode window open, nobody at the Mac. xcodebuild over SSH refused to codesign…
Route files were losing the immutable bit
I set chattr +i on my backend's main.py after a sync bug kept silently overwriting it. Months later, the iOS app started losing connectivity on a…
OneDrive sync was reverting my backend edits
Every few days my backend would lose a recent fix. The change would work, restart the service, work for hours, then vanish. Git showed the old code back…
Spoken morning briefing on an Echo, without writing a skill
I wanted a JARVIS-style morning briefing — calendar, weather, finances, todos, the day's notable anniversaries — spoken out loud on the Echo Studio in…
Face recognition on the front door with an active-learning loop
I wanted my front door doorbell to do something more interesting than
Editing Home Assistant OS config without the SSH add-on
I deployed Home Assistant OS as a VM on Proxmox so I could try a Wi-Fi smart lock. HA proxied through nginx returned HTTP 400 on every request. The fix…
Downsampling the way out of a CNN out-of-memory loop
Doorbell camera snapshots come in at 1536x1536. I wanted to run them through a CNN face detector to label visitors. The detector kept getting OOM-killed…
A tiered mail classifier for cheap triage
Once all my mail was flowing through a Lambda, I wanted automatic triage — drop the obvious noise, bucket the rest, only forward the things I'll actually…
manage-bde isn't broken, BitLocker just isn't installed
I had a fleet-status dashboard for some Windows boxes that pulled disk encryption state via manage-bde -status. Several rows were reporting hard errors…
Echo Studio silently drops Alexa announcements over 600 characters
I have a morning briefing skill that reads me a short summary of overnight events. It worked fine on the Echo Show in the kitchen and was completely…
A JARVIS-voiced morning briefing on the Echo Studio
I wanted something to talk at me when I get up — weather, todos, the date, sober days, mortgage-due reminder, homelab status. Not when an alarm fires…
The arr-stack disk-full trap
The home media pipeline went quiet. Nothing new was finishing. CPU on the torrent boxes was high but throughput was zero. Time to actually look at why.
Slipstreaming SSH into a PXE-booted Windows install
PXE booting a Windows 11 install is fine; getting a freshly installed VM to accept SSH from my homelab without me touching it is the actual interesting…
Native iOS todos with an interactive widget
I ship enough native iOS to make my own todo app worth the effort. I already had a backend that powered the web UI; I wanted a SwiftUI app that hit the…
KDP rejected my novel three times for comp titles in the description
I submitted a thriller to KDP in three editions on the same day: Kindle, paperback, hardcover. All three got rejected within a few hours, with identical…
Cutting MX records to SES when your domain loops back to itself
I had cut over the MX records on several personal domains to AWS SES, because I wanted every incoming email going through a Lambda that writes to…
A one-shot CLI so 'add it to my todo list' isn't a research project
Whenever I said
Building a TPM-bypass Win11 ISO with offline hive injection
I wanted to PXE-boot a fully unattended Windows 11 25H2 install onto a VM with no TPM, no Secure Boot, and not enough RAM by Microsoft's reckoning. The…
Workspace permission denied when SCP'ing from automation runner
I have a small homelab automation runner that orchestrates jobs across a handful of remote machines. New job, new bug: SCP transfers from the runner to a…
A 200KB Windows tray app for passive activity check-ins
The macOS companion for a personal safety app I run does one small thing: every five minutes, if the user was active in the last minute, it POSTs a…
Malware disguised as MKV files on public trackers
My TV import rate had collapsed from about 90 episodes a day to single digits over a five-day stretch. Sonarr's queue was full but nothing was making it…
qBittorrent was on the wrong VPN port forward
The music torrent container had 349 torrents and zero of them were doing anything. Every single one was stuck in metaDL with 0 peers, 0 bytes. DHT showed…
349 torrents and no queueing
The music torrent client had 349 torrents in flight. None of them were finishing. All of them were trying to download at the same time. This is what…
When the Proxmox dashboard disagrees with reality
My homelab status dashboard pulls container/VM state from the Proxmox API. One day it showed three containers as stopped that I was actively connected…
Cutting a full-book TTS render down to one CLI
I have a habit of writing things — long-form, novel-shaped things — and then not being able to listen to them on a walk. The commercial-quality audiobook…
A dead WireGuard tunnel stalled every music torrent
Music container in my torrent setup was stuck. 349 torrents, all in metaDL, all at 0 peers, all 0 bytes. The container itself was running, qBittorrent's…
Producing an audiobook with Kokoro on a Mac mini
I wrote a thriller novel. I wanted an audiobook of it. The traditional path is ACX with a human narrator, six to twelve months and a few thousand…
Using AppSync as a pub/sub fan-out without any data source
I had two clients — a web app and a native iOS app — both polling my backend every few seconds to learn that an assistant reply had finished. Polling…
An OpenAI-compatible shim so Home Assistant could talk to my agent
I wanted
Lidarr returns HTTP 500 on PUT /album/monitor mid-add
A note for anyone scripting Lidarr through its API: there's a race in the
I got the push but the chat was empty
Recurring complaint from myself: the assistant pushes a notification that it's done, I open the app, the conversation is there, the assistant bubble is…
Cold-start 500s from leftover Composer dev dependencies
A PHP function on Lambda started returning 500 on cold start after a routine deploy. Warm invocations were fine. The error in CloudWatch was specific and…
Moving off OneDrive onto a Syncthing mesh
I had been sync'ing my ~/code folder through OneDrive for years. It worked until it didn't. The breaking point was Xcode and git both fighting OneDrive…
The CT-is-running-but-the-app-is-dead 502 pattern
Recurring failure mode on the homelab: the assistant's domain returns 502 from every browser, but pct list says the LXC is running and systemctl status…
A keyword router that lied about which mode it was in
My assistant has a cheap classifier that routes short, simple questions to a fast model without tools, and harder questions to a tool-capable model. The…
Patching boot.wim with chntpw to no effect
I was building a custom Windows 11 install ISO and trying to do a clever registry tweak inside boot.wim to make in-place upgrade scenarios work the way I…
When the upstream CDN just isn't reachable from your house
I needed to download Windows 11 25H2 ISO bits via the UUP build flow. Aria2c started fine, pulled the small metadata files (a few hundred KB total), and…
Bref 2 to 3 and provided.al2 to al2023, the gotchas
AWS sent the usual EOL notice for the provided.al2 Lambda runtime. I had 13 functions on Bref 2 / al2 spread across two serverless projects. The…
Reverse engineering a Bluetooth-only irrigation controller
I have an Orbit B-hyve XD irrigation controller. It's Bluetooth-only — no Wi-Fi hub built in. Every existing integration (Home Assistant, pybhyve…
USB 2.0 Billboard means the cable is charge-only
Plugged an ESP32-class dev board into the Mac. Instead of a serial port, macOS showed it as a USB 2.0 BILLBOARD device from VLI Inc., vendor ID 0x2109…
qBittorrent's API rate-limits fresh logins
A dashboard tile of mine that aggregates torrent counts across five qBittorrent instances started intermittently returning 403s. The page would refresh…
An on-this-day journal feature from 3,000 Day One entries
I exported 3,060 Day One journal entries as JSON, imported them into DynamoDB, and built an
Two flags for one boolean, drifted apart
A user of a side-project reported that the
Disabling Zebra printer Bidi when PowerShell refuses to help
I write deployment scripts for Zebra ZQ521 mobile printers running CPCL. Two of the standard config knobs — disable bidirectional communication and…
A counter clock as the simplest thing that could possibly work
I needed a public webpage that counts time since a fixed instant. Two days, four hours, big number, mobile-friendly. The interesting part wasn't the page…
Disabled the schedule. Got paged anyway.
I disabled a stuck check-in schedule at 09:05. At 09:33 my phone buzzed with
Counting a word across Signal messages with the macOS keychain
I wanted to count how many times I'd used a specific word across all my outgoing Signal messages. Sounded like five lines of SQL. The interesting part…
A BYOS e-ink dashboard that wakes once a day
I wanted a tiny always-on display in my office that showed the day's useful information and lasted a season on a single battery charge. The constraint…
Sketching a one-click honeypot installer
Honeypots are useful and almost nobody runs them, because the existing stacks are either too heavy (multi-container threat-intel platforms that need 16…
Memex — a queryable second brain over my messages
I wanted to ask my own data questions like
Adding email to the Memex (and a Dynamo pagination gotcha)
A few hours after shipping the Memex over iMessage and Signal, I added email. The interesting part wasn't the feature — it was a DynamoDB pagination bug…
Per-day-of-week sleep windows for a safety app
A safety app I run was firing
Five identical schedules, thirteen SMS in ten minutes
09:33 to 09:43 on a Friday morning: thirteen SMS messages, several push notifications, all from my own safety app, all to me. The trigger was five…
Decrypting Signal Desktop's database on macOS
I wanted Signal Desktop's message history available for indexing in my personal search. Signal Desktop stores messages in a SQLCipher database, and the…
Teaching the arrs to skip Russian and very long releases
Sonarr blew up at 3 AM with PathTooLongException thrown across the import queue. The release that triggered it was a translated upload with a…
94% SpO2 is not an emergency
I got a high-severity SMS from my own safety app:
When Sonarr's UI hangs after a restart, blame the WebSocket cache
I'd just restarted Sonarr to recover from an unrelated issue. The service came back up, API requests responded fine, but the web UI in my browser was…
Sonarr was dead because of a Cyrillic filename
Sonarr's web UI was unresponsive. systemd said the service was active (running). The process was using 100% of multiple cores. Load average on the…
Why the sleep-window learner kept collapsing to the wrong four hours
The v1 sleep-window learner for a side-project safety app produced a sleep window of 01:00–05:00 for me. My actual sleep is more like 23:00–07:00. The…
A risk email every fifteen minutes about nothing
The risk-monitor cron on a side project I run was emailing me every 15 minutes with
Replacing a binary threshold cliff with a one-hour ramp
The inactivity-monitor cron on a side-project safety app was paging me at 7:01 AM, every morning, with
PHP loose comparison turned an empty endpoint into a 500
A backend I run was returning 500s on GET /api.php with no endpoint= query param. Should obviously be a 400. Tracking it down landed me on one of those…
Updating a DynamoDB row by the wrong key shape, for a year
A pre-release endpoint sweep on a backend I run turned up two 500s on the check-in respond and snooze endpoints. The cause was old: a composite-key table…
Auditing 22 references to GSIs that don't exist
A pre-release audit pass on a backend I run turned up 22 places where the code passed IndexName: foo-index to a DynamoDB query on a table where foo-index…
Sixty-five lines ahead of git, in production
I went to deploy a fix to a backend Lambda and stopped halfway through because the file I was about to overwrite was 65 lines ahead of the repo…
Heartbeats were polluting my activity table
The phone in a side-project safety app posts a stationary_heartbeat every few minutes when it's not moving — so the server knows the device is alive even…
Voice on watchOS without the Speech framework
I wanted to talk to my homelab assistant from the Apple Watch. Action Button down, dictate, get a spoken reply back. Standard project except for one…
The arr stack wasn't crashing, qBittorrent was thrashing
I caught a
Push notifications only firing on the final assistant message
My homelab assistant runs as a Claude Code agent in the background. When it finishes a long task, it pushes a notification to my phone with the result…
Mining 18,000 emails for facts about my own life
I had three years of email sitting in a DynamoDB table and a memory store wired into my assistant. The assistant was making decisions with no recall of…
Personal mail as a serverless pipeline (and a forwarder identity trap)
I wanted every email to my personal domains stored in DynamoDB as the primary read surface, with Google Workspace continuing to receive a copy as a cold…
Multi-select with context-aware bulk actions
I built multi-select for the mail reader UI and then almost shipped a bad version of the bulk-archive button. The fix was making the button's behavior…
MIME bodies disguised as attachments
My mail reader was showing
Empty bubbles on iOS when the assistant only called tools
The iOS client kept showing blank assistant bubbles in the middle of a multi-step turn. Pull-to-refresh fixed it. Notifications fired fine. The text was…
Dynamo as inbox, with a passkey
I built a single-page mail reader on top of the DynamoDB table my mail pipeline writes to. Three-pane layout (inbox list / messages / body), search…
Designing a receipt matcher for my financial dashboard
Most of my transactions have a receipt sitting in Gmail somewhere. I just want to be able to click a charge in my finance dashboard and see the actual…
Two weeks of silent torrent failures from one chown
Nothing new had landed in my movie library since the 4th of the month. Radarr looked healthy, the queue was just stuck at 321 items. Most of them showed…
Sensor Offline alerts while traveling, twice
A safety app I run pinged me every hour with
Use the Tailscale brew formula, not the cask
Quick note to past me: when installing Tailscale on a headless Mac, brew install tailscale (the formula). Not brew install --cask tailscale-app.
Plaid to DynamoDB with read-time categorization
I wanted a personal-finance dashboard that I owned end-to-end. Plaid on one end, DynamoDB on the other, one Lambda in between, and categorization rules…
A tiny SSO provider for personal subdomains
I run a handful of small web apps on subdomains — a finances dashboard, a map, a CV, a blog admin. Each had its own login. Each login was the same login…
One Lambda serving a résumé and a blog, routed by Host header
I had a static résumé at one subdomain and wanted a blog at another. Two Lambdas felt absurd for what is functionally two HTML generators. So I put both…
A personal location heatmap on cheap Lambda infrastructure
I had years of GPS pings in a database from a side project. I wanted to look at where I'd actually been on a map — heatmap of every ping, markers for the…
Shipping 14 tiny iOS utilities in a batch
I shipped 14 small iOS utilities to App Store Connect in a batch. Subnet calculators, a WoL remote, a JSON pretty viewer, a regex tester, a ping monitor…
FreezeGuard: a Windows UWF agent shipped as a service
I shipped a small side-project that wraps Windows' Unified Write Filter (UWF) — the feature that lets you
An inventory app for a family craft business
A family member runs a craft-supply brand and needed a product inventory catalog. I built one weekend project: a public catalog page, an admin page, and…
Making bootable Windows 98 floppies from a modern Mac
I wanted to install Windows 98 SE on a period-correct Pentium III without going through the usual ISO-to-USB workaround. That meant making the actual…
The Google Drive S3 Round-About
Chester Frazier — automation engineer, builder, writer. Personal archive: essays, apps, photographs, music, and a working résumé.