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

2026-03-23 — Scout, triage, and hardening sweep

What shipped

A full scout-triage-execute cycle cleared 10 issues in a single session — 5 from the previous day’s hardening wave (#197-#201) and 5 new issues discovered and resolved by today’s scout run (#207-#211).

The scout run explored the codebase across six dimensions (error handling, dead code, security, UX, feature gaps, performance) and surfaced findings ranked by impact. Two security vulnerabilities were fixed: completeSourceTask was missing user_id verification, allowing cross-user source task manipulation (#207), and the WebAuthn challenges table had an overly permissive RLS policy (using (true)) that let any authenticated user access all challenges (#208). The RLS fix replaced the permissive policy with using (false) since all challenge access goes through the admin client.

A performance fix moved defer re-ingestion from synchronous (blocking the user 1-3 seconds during Claude API calls) to background execution using Next.js 16’s after() API (#209). The EOD wrap-up carryover re-ingestion was similarly made non-blocking with fire-and-forget promise chaining. Error handling was added to the completeTask cascade — the energy RPC call now checks its result and logs failures instead of silently dropping them (#210).

The biggest UX change was redirecting post-login from /dashboard to /today (#211), aligning the entry point with the serve-don’t-show model. All 5 auth flows (email, passkey, signup, OAuth callback, password reset) now land on the serve experience. The logo and nav bar were updated to make /today the primary destination. Dashboard stays reachable as the admin/escape-hatch surface. Decision logged in DECISIONS.md.

Completed

  • #197 — Fix energy tracking race condition in completeTask
  • #198 — Prevent EOD capture from overwriting energy tracking data
  • #199 — Add res.ok checks to client-side fetch calls (5 components)
  • #200 — Clean up minor dead code: unused import, config values, and export
  • #201 — Re-ingest carryover notes from wrap-up through parse pipeline
  • #207 — completeSourceTask missing user_id verification
  • #208 — WebAuthn challenges RLS policy fix
  • #209 — Defer re-ingestion moved to background
  • #210 — completeTask cascade error handling
  • #211 — Post-login redirects to /today

Release progress

March 2026: 0 open / 0 closed (milestone exists but no issues assigned)

Carry-over

  • #86 — Replace in-memory rate limiter with persistent solution (backlog)
  • #101 — Branded emails (blocked)
  • #108 — BCC founder on transactional emails (backlog)
  • Source system integration (Asana/Jira/Notion outbound sync) — PRODUCT.md’s biggest unfulfilled promise
  • Learning model runs nowhere automatically — wrap-up doesn’t trigger it
  • Check-in feedback (done path) never re-ingested through parse pipeline

Risks

  • 10 PRs merged to main in one session — deploy to production and smoke-test the serve flow and auth flows
  • The /today redirect change affects every auth flow — if /today has a bug, new users hit it immediately after signup

Flags and watch-outs

  • The after() API for background re-ingestion works on Vercel but may not fire in local dev (Next.js dev server behavior differs) — test defer re-ingestion in production
  • WebAuthn RLS migration applied to remote Supabase — passkey flows should be smoke-tested in production
  • Only 3 open issues remain (#86, #101, #108), all backlog/blocked — the active queue is clear

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.

When the queue goes empty

Most products don't fail at building. They fail at the handoff between building and becoming real. What happens when the code is done and the only things left are judgment calls?

When your agents start breaking each other's code

Two agents modified the same file independently and created database locks. The fleet hit 135 issues in one day — and the coordination problem that comes with it.

The removal tax

The most productive thing you can do with a product is take features away. Eighty-nine issues closed across eight projects, and the hardest lesson came from a pipeline that ran perfectly and produced nothing.