Skip to main content
Paul Welty, PhD AI, WORK, AND STAYING HUMAN

2026-03-11

What shipped today

Today was a hardening session — seven issues closed, all focused on resilience, security, and correctness rather than new features. The one user-facing addition was passkey registration in settings, completing the full WebAuthn flow that started in the previous session.

Passkey registration UI landed in the settings page (#130), completing the passkey authentication chain. Users can now register passkeys from settings (with WebAuthn feature detection, inline rename, delete) and sign in with them from the login page. The full flow is: register in settings → login on login page. This was the last piece from the #31 decomposition.

Infrastructure hardening covered five issues discovered by the /scout run. Expired webauthn challenges now get purged hourly via pg_cron (#135). The engine validates database connectivity at startup with a SELECT 1 health check (#139). The Brevo inbound webhook now returns 503 when the webhook secret isn’t configured, closing a security gap where all requests were silently accepted (#136). Engine batch handlers (article.batch_fetch and google_search.scan) now raise errors when all operations fail instead of reporting success with zero results (#137). And server actions gained input length limits across interests, search countries, briefing hour, feed URL, and feed name fields (#138).

Completed

  • #130 — Add passkey registration UI in settings
  • #135 — Purge expired webauthn_challenges rows on schedule
  • #139 — Add database health check on engine startup
  • #138 — Add input length limits on user-controlled text fields
  • #137 — Engine batch handlers report success when all fetches fail
  • #136 — Brevo webhook accepts all requests when secret is unconfigured

Carry-over

  • #122 — Integrate feed discovery into add-feed UX — labeled blocked, but dependencies #120 and #121 shipped in the previous session. Needs relabeling to ready-for-dev and a spec update.
  • #126, #127 — Raindrop/Readwise push integrationsblocked, waiting on engine-side command handler pattern.
  • Vercel build rate limiting — hit the Vercel deployment rate limit repeatedly today. All PRs were engine-only changes so it didn’t affect correctness, but web PRs may need CI patience.
  • posthog-node module — pre-existing TypeScript check error; needs npm install posthog-node in web/.

Risks

  • Vercel rate limiting could block future web-facing PRs from getting CI verification. Worth monitoring — may need to space out merges or upgrade the Vercel plan.

Flags and watch-outs

  • All milestones are closed. The remaining open issues (#122, #126, #127, #77, #64) are either blocked or backlogged with no milestone. Consider creating a new milestone to organize the next batch of work.
  • The pg_cron migration (#135) requires the pg_cron extension to be enabled in Supabase. Verify it’s available in the production environment before deploying.

Next session

  1. Unblock #122 — relabel from blocked to ready-for-dev, update spec if needed, then exec. This wires feed discovery into the add-feed UX.
  2. Create a new milestone — all four milestones are closed. Group the remaining work (#122, #126, #127, and any new issues) into a milestone.
  3. Fix posthog-node — install the missing dependency in web/ to clear the pre-existing TypeScript error.
  4. Check #126/#127 blockers — determine if the engine command handler pattern is ready for Raindrop/Readwise integrations.

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.

The machine is eating faster than you can feed it

Sixty-three issues closed across thirteen projects in one day. Four milestones completed. And the hardest problem wasn't building — it was keeping up with what you've already built.

The proxy problem

Every organization has this problem: knowledge locked inside one person's head. Today I accidentally designed a solution — and it has nothing to do with documentation.

True 1-to-1 outreach is finally possible with AI

The 1-to-1 personalization promise is thirty years old. It never worked because understanding each person was too expensive. AI changed the economics.