Paul Welty, PhD AI, WORK, AND STAYING HUMAN

What shipped today

Massive day — closed 37 issues across four grind rounds plus significant manual work. The theme was “make it real for Stacy”: testing the full onboarding-to-daily-value pipeline with a real user (Stacy Sutton) and fixing everything that broke along the way.

Parallel grind execution. Ran four grind rounds using 3-agent teams, burning through the Web app milestone backlog. Round 1 shipped the re-engagement flow (GH-296) and SMS channel via Brevo (GH-306). Round 2 added social post metrics collection for Bluesky and Mastodon (GH-291). Round 3 built notification channel preferences (GH-307), an admin tool to reset user onboarding (GH-317), and a pre-onboarding invite email from Maya (GH-319). Round 4 implemented the feedback signals table with full UI instrumentation — vote, bookmark, dismiss, and edit signals now logged to a dedicated table for future flywheel analysis (GH-264).

Engine pipeline overhaul. Replaced the three separate scheduler crons (RSS scan every 6h, Google search daily 07:00, idea generation daily 08:00) with a single daily.pipeline orchestrator that runs the full intake-to-briefing flow sequentially: RSS scan, Google search scan, then briefing.generate which auto-selects top articles by min_relevance_score from workspace settings and auto-chains idea.generate. Also killed the broken monitor.check_content cron that had no handler — it was silently failing every day.

Production bug fixes discovered via Stacy testing. The workspace switcher silently failed when switching (server action threw but client had no try-catch) — fixed by returning result objects and adding toast notifications. The team settings page showed truncated UUIDs instead of emails for non-current users because it only fetched email for the current user — fixed by using the admin client to fetch all member emails from auth.users. Feed discovery failed because the scan_logs_scanner_type_check constraint didn’t include 'feed_discovery' — the GH-287 grinder had created the handler but missed the DB constraint. Fixed with a migration.

User presence tracking. Built a login notification system: web app fires a server action on mount, deduplicates via activity_logs (2hr cooldown), then inserts an admin.notify_login command. Engine handler picks it up and emails Paul via Brevo. No Discord code in authexis — uses existing notification infrastructure.

Earlier in the day (prior session): shipped Maya identity centralization (GH-300), interaction style preferences (GH-298), content type icons/colors (GH-295), onboarding bootstrap auto-generation (GH-309), global BCC monitoring, onboarding wizard pre-population from website data, Stripe build fix (GH-314), deploy alert workflow (GH-313), and several content action refinements (GH-288, GH-289, GH-290).

Completed

  • GH-264 — Feedback signals table + UI instrumentation
  • GH-291 — Social post metrics Phase 1 (Bluesky + Mastodon)
  • GH-294 — Fix bold claim not populated for article reactions
  • GH-295 — Add icon and color for content types
  • GH-296 — Re-engagement flow
  • GH-297 — Fix onboarding tracker showing incomplete after wizard
  • GH-298 — Interaction style in profile settings and engine context
  • GH-299 — Fix silent publish failure + LinkedIn API update
  • GH-300 — Centralize Maya identity constants
  • GH-301 — Drop position column from blog queue
  • GH-306 — SMS channel via Brevo
  • GH-307 — Notification channel preferences
  • GH-309 — Onboarding bootstrap auto-generate search terms
  • GH-313 — Fix deploy alert workflow permissions
  • GH-314 — Fix Vercel build (lazy-init Stripe)
  • GH-317 — Admin tool to reset user onboarding
  • GH-319 — Pre-onboarding invite email from Maya
  • Plus: workspace switcher fix, team page emails fix, feed discovery constraint fix, daily pipeline orchestrator, presence tracking, global BCC, onboarding wizard pre-population, content action refinements (GH-288, GH-289, GH-290)

Carry-over

  • GH-302, GH-303, GH-304 — LinkedIn, Threads, and historical metrics (Phase 2, depends on GH-291 which shipped today)
  • GH-305 — Verify cold inbound email to Maya (manual test needed)
  • GH-315 — Harden workspace switcher (loading states, validation)
  • GH-316 — Error boundaries on server action calls (audit)
  • GH-318 — Welcome email copy assumes wizard completed (edge case for re-onboarding)
  • GH-320 — Team page email N+1 query optimization
  • GH-326 — Add last login to admin users page

Risks

  • Production database shared with dev — the Stacy onboarding reset and manual command inserts were done directly on prod data. No issues, but worth noting.

Flags and watch-outs

  • DISCORD_PAULOS_WEBHOOK is not configured anywhere yet — paulos Discord notifications silently skip. Not blocking, but login presence notifications won’t reach Discord until this is set up.
  • The daily pipeline runs at 07:00 UTC. If a workspace has no feeds or search terms, the pipeline still runs but scans return empty. No harm, but wasted cycles.
  • ADMIN_NOTIFY_EMAIL env var not explicitly set on Railway — falls back to EMAIL_BCC which is [email protected]. Works fine, but should be explicit if the BCC ever changes.

Next session

  • Test the daily pipeline end-to-end: manually queue a daily.pipeline command for Stacy’s workspace and verify the full flow (scan → articles → briefing → ideas)
  • GH-305: Verify cold inbound email to Maya — send a test email to [email protected] from an external address
  • Grind the remaining Web app milestone issues: GH-302 (LinkedIn analytics), GH-303 (Threads analytics), GH-304 (historical metrics)
  • GH-326: Add last login timestamp to admin users page — now trivially possible since activity_logs tracks session_start
  • Consider wiring up DISCORD_PAULOS_WEBHOOK so login pings also reach Discord alongside email
  • Web app milestone is at 93.5% — a few more grind rounds should close it out

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 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...

Dev reflection - February 17, 2026

I want to talk about staging areas. Not the technical kind—the human kind. The places where work goes to sit. The inbox you check before forwarding. The draft folder. The approval queue. The meetin...