What shipped today
Massive day — 16 issues closed across the entire stack. The morning started with a parallel grind session that knocked out a batch of mid-priority fixes and features: social queue sorting (GH-331), welcome email conditional copy (GH-318), team member email lookup batching (GH-320), admin last login column (GH-326), timezone bug in reschedule queue (GH-332), inline editing for social posts (GH-338), sources in content generations (GH-339), sources placeholder in admin prompts (GH-339), source management on content pieces (GH-340), historical metrics tracking for social posts (GH-304), error boundaries around server actions (GH-316), and migration backfill for article_ids/queued_for_ideas columns (GH-333).
The big feature work was the Resend email switchover (GH-344). Migrated from Brevo to Resend as the primary email provider — added Resend alongside Brevo first, then switched the inbound webhook to use Resend’s Svix-signed webhook format, standardized the app URL to www.authexis.app to avoid redirect issues, and fixed email signature stripping. Also fixed the unified Maya conversation pipeline (GH-305) so email replies have real clickable links, contextual CTA buttons, and proper markdown-to-HTML conversion. Cold emails now route through the chat.message pipeline with full tool access.
The afternoon was spent debugging the Resend inbound pipeline end-to-end. The webhook was returning 200 but silently failing to create maya.reply commands. After extensive debugging (Vercel CLI truncates function logs, which made this harder), the root cause turned out to be a restricted API key on Vercel production — the key could send emails but couldn’t read received emails via GET /emails/receiving/{id}. Once swapped to the full-access key, the pipeline worked.
Then came the email deliverability battle. Maya’s reply emails were landing in spam in Fastmail with a spam score of 7.2 (threshold ~5). Two issues: the root domain SPF record was missing include:amazonses.com (Resend sends via SES), and Resend’s click/open tracking domain resend-clicks-a.com was on URIBL spam blocklists contributing +11 to the spam score. Fixed SPF in Cloudflare, disabled tracking via Resend API, and emails started landing in inbox.
Also shipped GH-353 — three engine fixes for final stage content generation: essay stage label matching, intro field word count treatment, and image generation sort key.
GH-349 added copy/download for interview scripts and sources display in the script view.
Completed
- GH-304 — Historical metrics tracking for social posts
- GH-305 — Unified Maya conversation across email, SMS, and chat
- GH-316 — Error boundaries around server action calls
- GH-318 — Fix welcome email conditional copy
- GH-320 — Batch team member email lookup
- GH-326 — Add last login column to admin users page
- GH-331 — Add social queue sorting
- GH-332 — Fix timezone bug in rescheduleQueue
- GH-333 — Add missing migrations for article_ids and queued_for_ideas
- GH-338 — Inline editing for social posts
- GH-339 — Sources placeholder in admin prompts + include sources in generations
- GH-340 — Add, remove, and edit sources on content pieces
- GH-343 — Add Resend email provider alongside Brevo
- GH-344 — Full Resend switchover — inbound webhook, URL standardization, signature stripping
- GH-349 — Copy/download for interview script + show sources in script
- GH-353 — Fix final stage issues — intro word count, image generation order
Carry-over
- GH-354 — Evaluate email provider alternatives (Postmark, direct SES, SendGrid) — created today but not started. Resend’s click tracking domain being on blocklists is a concern.
- Onboarding pipeline plan exists (bootstrap handler, sidebar tracker, daily nudge emails) but implementation hasn’t started yet.
Risks
- Resend’s tracking domain
resend-clicks-a.comis on URIBL spam blocklists. We disabled tracking, but if Resend’s sending reputation degrades further, deliverability could become an issue again. GH-354 tracks evaluating alternatives. - SPF record now includes both
amazonses.comand_spf.mailersend.net— if we fully deprecate Brevo/MailerSend, we should clean up the SPF record.
Flags and watch-outs
- Vercel production
RESEND_API_KEYwas updated today to the full-access key. If anyone rotates this key, make sure the new key has full access (not send-only restricted). - The
RESEND_WEBHOOK_SECRETwas also regenerated today — both Vercel env var and.env.localare in sync. - Vercel CLI
vercel logstruncates function output to one line per invocation — not reliable for debugging. Return debug info in response body during debugging sessions instead.
Next session
- Review GH-354 — decide whether to evaluate Postmark/SES/SendGrid or keep Resend with tracking disabled. The user expressed frustration (“it’s just a SES wrapper”) so this may be a priority.
- Start the onboarding pipeline implementation — the plan is written and approved (bootstrap handler, sidebar tracker, daily nudge emails). Begin with the bootstrap handler that auto-generates search terms after wizard completion.
- Check the milestone queue via
/startfor any new high-priority issues that came in.
Why customer tools are organized wrong
This article reveals a fundamental flaw in how customer support tools are designed—organizing by interaction type instead of by customer—and explains why this fragmentation wastes time and obscures the full picture you need to help users effectively.
Infrastructure shapes thought
The tools you build determine what kinds of thinking become possible. On infrastructure, friction, and building deliberately for thought rather than just throughput.
Server-side dashboard architecture: Why moving data fetching off the browser changes everything
How choosing server-side rendering solved security, CORS, and credential management problems I didn't know I had.
The work of being available now
A book on AI, judgment, and staying human at work.
The practice of work in progress
Practical essays on how work actually gets done.
Dev reflection - February 21, 2026
I want to talk about invisible problems. Not the kind you ignore — the kind you literally cannot see until you change how you're looking.
Dev reflection - February 20, 2026
I want to talk about the difference between execution and verification. Because something happened this week that made the distinction painfully clear, and I think it matters far beyond software.
Dev reflection - February 18, 2026
There's a moment in any system—a team, a company, a workflow—where the thing you've been optimizing for stops being the constraint. And you don't notice right away. You keep pushing on the old bott...