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

2026-03-20

What shipped today

Today was a massive cleanup and quality sprint — 20 issues closed across the full stack, from database indexes to UI components to dead code removal. The session ran the automated scout → triage → prep → exec pipeline end-to-end multiple times, proving the pipeline can reliably chew through a backlog of mixed-complexity issues without human intervention.

The most impactful work fell into three themes. First, performance and reliability: composite database indexes for the most frequent query patterns (votes by user+article, articles by user+status, votes by user+updated_at), fixing an N+1 query in the admin engagement signals page, and fixing silent failures in server actions that were swallowing errors instead of surfacing them. Second, user experience: downvoted articles now get archived and hidden from the feed (instead of lingering with a red thumb), users can add optional notes to their votes explaining why they liked or disliked something, and the newsletter detail page now shows full interactive article cards with voting, bookmarking, and score explanations — matching the main articles page experience. Third, codebase health: dead code removal (orphaned dashboard route, unused JSON-LD component, dead Python text utilities), build warning fixes (Next.js 16 proxy convention, Sentry instrumentation-client rename), and Sentry environment variables properly configured in Vercel production.

A notable false positive was caught: scout flagged that “learned preferences aren’t used in scoring,” but tracing through the code confirmed the feedback loop is intact — article_score.py calls get_user_context() which reads learned_preferences from user profiles. The indirection through a shared module confused the scan. Issue #354 was closed with an explanation.

Completed

  • #329 — Reject articles when prescore fails instead of silently accepting
  • #330 — Raise exception when ScrapingBee circuit is open instead of returning empty
  • #331 — Use position() instead of LIKE for domain dedup to avoid wildcard injection
  • #333 — Add state-aware aria-labels to vote buttons
  • #334 — Add missing RLS INSERT/UPDATE/DELETE policies
  • #335 — Add pricing comparison table to landing page
  • #336 — Add /health endpoint to engine for Railway monitoring
  • #337 — Add time-decayed ranking to articles page
  • #338 — Add Ranked sort option on articles page
  • #339 — Add podcast detail page at /podcasts/[id]
  • #340 — Verify feedback loop and create living feature doc
  • #342 — Archive downvoted articles and hide from articles page
  • #343 — Show toast with link when website URL is added as RSS feed
  • #345 — Add admin signals log page and user detail signals section
  • #346 — Fix build warnings (middleware→proxy, Sentry config)
  • #348 — Add optional note to votes (up and down)
  • #351 — Show newsletter articles as full article cards
  • #354 — Learned preferences false positive (closed as not-a-bug)
  • #355 — Fix silent failures in server actions
  • #356 — Fix N+1 queries in admin actions
  • #357 — Add missing composite database indexes
  • #358 — Remove dead code

Carry-over

  • Verify PostHog and Sentry are configured correctly (env vars added, need to confirm events are actually firing and errors are being captured)

Risks

  • None identified. All milestones are closed. The backlog is down to 3 parked items.

Flags and watch-outs

  • Sentry org/project env vars were added to Vercel production today — first deploy with those should be monitored to confirm source maps upload correctly
  • The proxy.ts rename is a Next.js 16 convention — if Next.js version changes or we hit middleware issues, check this file first

Next session

  • Run /scout to find new improvements now that the grind queue is empty
  • Consider promoting backlog items (#344 confusing sort/filters, #77 Vercel issue, #64 email inbox scanning) if there’s appetite for new work
  • Confirm Sentry source maps are uploading on Vercel deploys
  • Confirm PostHog events are firing in production

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 product changed its mind

A product pivoted its entire philosophy mid-session — from 'here's your list' to 'here's your next thing.' The code shipped in the same conversation as the idea. That's not iteration. That's something else.

Your project management tool was made for a non-human (AI) factory, not for you

Every project or task management tool on the market descends from Frederick Taylor's factory floor. The assumptions were wrong then. They're catastrophic in the Age of AI.

The last mile is all the miles

Building the product is the fun part. Deploying it, configuring auth, pasting email templates into dashboards, rotating leaked API keys — that's where the work actually lives.