Paul Welty, PhD AI, WORK, AND STAYING HUMAN

2026-03-04 — Eclectis

What shipped today

The biggest theme was pipeline hardening and intelligence. Four engine issues were ground in parallel: HTML stripping (#54), URL normalization (#55), title cleanup (#57), and admin impersonation (#49). These cleaned up the data quality foundation — articles now arrive with stripped HTML, normalized URLs, truncated titles, and clean text. The URL normalization was later extended in #56 by extracting normalize_url into a shared module and adding title+domain dedup, so the same article from multiple feeds no longer appears twice.

The self-improving scoring loop (#41) was the marquee feature. Engagement events (clicks, votes, bookmarks, feed changes) are now tracked in a new engagement_events table. A user.learn handler analyzes these signals with Claude Haiku and writes a learned_preferences text field on the user profile. The article scoring prompt now includes these learned preferences, closing the feedback loop: user behavior → learning → better scores → better briefings. The scheduler was rewritten to match the pipeline doc — 5-minute tick, scans at a fixed UTC hour, briefings at each user’s chosen hour, with user.learn running alongside briefings.

Observability rounded out the day. PostHog (#60) is fully wired — provider in root layout, user identification in the authenticated layout, an edge proxy at /ingest to bypass ad blockers. Sentry was configured by the wizard with client/server/edge configs, user identification via SentryIdentify component, and DSN set on Vercel. The briefing email template was also improved with the Eclectis logo icon and section summaries with explicit article links.

Completed

  • #54 — Strip HTML tags from RSS article summaries and content
  • #55 — Normalize and validate feed URLs on import
  • #57 — Clean and truncate long article titles and summaries
  • #49 — Admin impersonation — pose as any user
  • #41 — Build telemetry/engagement tracking for self-improving scoring
  • #59 — Add pre-score gate to article.add pipeline
  • #60 — Fully instrument PostHog and Sentry
  • #61 — Do we need Better Stack? (closed: no, PostHog + Sentry sufficient)
  • #58 — Handle feed encoding issues (UTF-8, Latin-1, etc.)
  • #56 — Deduplicate articles by content similarity
  • #53 — Strip HTML from RSS article summaries (closed as duplicate of #54)
  • #50, #51, #52 — Search, sort, filter on articles + tag filters on feeds

Carry-over

  • #62 — Learned search terms: Auto-generate Google scan queries from the engagement feedback loop. Designed but not yet implemented.
  • #47 — Integrations: Feedly, Inoreader, Feedbin, Raindrop connectors. Backlog.
  • #31 — Passkey authentication: Backlog.

Risks

  • PostHog pageviews: Configured with capture_pageview: true but only in production. Need to verify events are actually flowing after next Vercel deploy.
  • Sentry source maps: withSentryConfig is set to delete source maps after upload, but we haven’t confirmed the upload is working (needs SENTRY_AUTH_TOKEN on Vercel for build-time upload).
  • Scheduler in production: The rewritten scheduler now ticks every 5 minutes. Need to confirm it’s running correctly on Railway after deploy.

Flags and watch-outs

  • The normalize_url shared module now strips www. — this is an improvement but means existing articles with www. in their URL won’t match new normalized URLs. Not a data integrity issue (old articles stay, new ones dedup correctly) but something to be aware of.
  • user.learn runs alongside briefings. If a user has no engagement events, it skips gracefully. But the first real run will be interesting — watch logs.

Next session

  1. Verify PostHog events flowing — check the PostHog dashboard after the Vercel deploy goes live. Confirm pageviews and user identification are working.
  2. Add SENTRY_AUTH_TOKEN to Vercel — needed for source map uploads during build. Get from Sentry org settings.
  3. Prep and grind #62 (learned search terms) — the feedback loop design is done, this extends it to auto-generate Google scan queries.
  4. Monitor first user.learn run — check Railway logs around briefing time to confirm the handler processes engagement events correctly.
  5. Consider milestoning — all current milestones are closed. The 3 remaining issues are unmilestoned backlog. May want to create an M5 milestone for the next batch.

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 loop nobody bothers to close

Most systems observe. Almost none learn. The difference is a feedback loop — and the boring cleanup work that makes it possible.

Your process was built for a different speed

When work changes velocity, governance systems don't just fall behind. They become theater. And theater is worse than nothing—it gives you the feeling of control without any of the substance.

The difference between shipping and finishing

Shipping is mechanical. Finishing is a judgment call. And most organizations have quietly made it impossible to tell the difference.