Paul Welty, PhD AI, WORK, AND STAYING HUMAN

2026-03-08

What shipped today

Today was a cleanup and hardening session — eight issues closed across security, performance, reliability, and test coverage. No new features; instead, the focus was on making the existing pipeline more robust and correct.

The session started by picking up carry-over from yesterday: admin impersonation hardening (#80) added HMAC cookie signing with crypto.createHmac() and timingSafeEqual to prevent cookie forgery, composite indexes (#79) added five targeted indexes for the hottest query paths (commands polling, feed scanning, article listing), and article_fetch safety (#78) fixed a crash on NULL URLs and added cumulative timeout tracking so the scraper can’t spend more than 90 seconds total across HTTP escalation strategies.

Then a fresh /scout run identified five new issues. All five were executed in the same session: OPML parser tests (#94) extracted the parser into a shared module with 12 test cases, bounded admin usage (#93) added a 30-day window to prevent unbounded queries, deduplicated ratings context (#92) consolidated three copies of _build_ratings_context into one shared function in user_context.py, poller JSON guard (#91) added try/except around payload parsing to prevent a single malformed command from crashing the poller, and greedy JSON regex (#90) replaced fragile regex extraction with json.JSONDecoder.raw_decode() for correct handling of nested brackets and prose.

Completed

  • #80 — Harden admin impersonation — sign cookie, validate on each request
  • #79 — Add missing composite indexes for hot query paths
  • #78 — Fix article_fetch crash on NULL URL and add cumulative timeout
  • #94 — Add test coverage for OPML import parsing
  • #93 — Add pagination to admin usage query to prevent unbounded fetch
  • #92 — Extract duplicate _build_ratings_context into shared module
  • #91 — Guard against invalid JSON payload in poller command processing
  • #90 — Fix greedy regex in claude.py JSON extraction

Release progress

All four milestones (M1–M4) are closed. No open milestones. The project is in maintenance/iteration mode — all 36 issues shipped.

Carry-over

  • #77 — “possible vercel issue” (labeled backlog, may be closeable as informational)
  • PostHog and Sentry verification still pending (env vars, events firing, error capture)

Risks

  • The composite indexes (#79) migration hasn’t been applied to production Supabase yet — it will run automatically on next deploy but should be monitored for lock contention on large tables.

Flags and watch-outs

  • The _find_json helper in claude.py iterates through characters trying raw_decode() — on very large malformed responses this could be slow, but in practice Claude responses are <10KB so this is fine.
  • Three copies of ratings context logic were consolidated — any handler importing the old local _build_ratings_context would break, but all callers were updated.

Next session

  • Close #77 as informational if no Vercel issues remain, or investigate if there are symptoms
  • Verify PostHog events and Sentry error capture are working in production
  • Consider opening a new milestone for the next iteration — the backlog has decompose candidates (#72 feed discovery, #64 email inbox scanning, #47 integrations, #31 passkeys) that could be shaped
  • Run /scout again to surface any new issues after this round of changes

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 job you didn't know you were hiring for

Most organizations hire for tasks. The ones that survive hire for attention. And attention turns out to be the hardest thing to delegate.

The second project problem

Your system works. Then you try it somewhere else and it falls apart. The gap between 'works here' and 'works anywhere' is where most automation dies — and most organizations never look.

The smartest code you'll ever delete

The most dangerous kind of waste isn't the thing that doesn't work. It's the thing that works beautifully and shouldn't exist.