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

Work log: Textorium TUI — March 20, 2026

What shipped today

This was a quality-and-hardening session — six issues closed across smart typography, security, performance, test coverage, and dead code removal. Everything came from either triage or a scout pass run earlier in the session.

The feature addition was smart quotes (#98): pressing Q in the content pane converts straight quotes to curly quotes, -- to em dashes, and ... to ellipses. The implementation tracks backtick-delimited code spans to avoid mangling inline code. An opening/closing quote heuristic checks the preceding character — whitespace or opening punctuation means opening quote, anything else means closing. Seven new tests cover double quotes, contractions, nested quotes, code span skipping, and round-trip fidelity via a straightquotes() reverse function.

The security fix (#101) addressed two vulnerabilities in create_post(): a path traversal where category input like ../../../tmp could write files outside the content directory, and a YAML injection where unescaped tags or categories could corrupt frontmatter. Categories are now validated against .., /, and \; tag and category values are quoted in the YAML output. Two new tests verify both fixes.

The cleanup pass removed tokio and its ~150 transitive crates from the dependency tree (#100) — the async runtime was never actually used (zero .await expressions in the codebase). The empty widgets/ module and the unused crossterm event-stream feature were also removed. straightquotes() was moved behind #[cfg(test)] since it was only used in tests.

The performance work (#103) cached the visual line count computation that was running on every scroll keystroke, and replaced get_filtered_posts() calls that only needed a length or single-post access with direct filtered_indices lookups, eliminating Vec allocations in the hot path.

The error handling fix (#104) replaced filter_map(|e| e.ok()) in the WalkDir scanning loop with explicit error collection, so permission errors and broken symlinks now surface in the status bar instead of silently hiding posts.

Finally, config.rs got its first test module (#102) — 16 tests covering SSG detection priority, content directory detection for all three SSGs, preview URL construction, and the content_path helper. Test count went from 28 to 47.

Completed

  • #98 — Feature: add smart quotes conversion with Q keybinding (PR #99)
  • #100 — Refactor: remove dead tokio dependency and unused code (PR #105)
  • #101 — Fix: path traversal and YAML injection in create_post() (PR #107)
  • #102 — Feature: add config.rs test module with 16 tests (PR #108)
  • #103 — Perf: cache visual line count, use filtered_indices directly (PR #109)
  • #104 — Fix: surface WalkDir IO errors instead of silently discarding (PR #106)

Release progress

  • TUI on Homebrew: 5/6 closed (1 remaining: #8, backlog — email signature, unrelated to TUI)
  • CLI essentials: 3/3 closed
  • First external user: 0/0 — empty, due 2026-03-30
  • Several stale milestones with 0 open/0 closed still exist (Visual overhaul, Bulletproof editing) — should be closed

Carry-over

  • v1.0.1 GitHub release notes are still auto-generated PR noise — needs a human-written changelog (flagged March 17 and 18)
  • Stale milestones need cleanup (TUI on Homebrew, Visual overhaul, Bulletproof editing, CLI essentials)
  • CLAUDE.md still claims CLI commands are “stubbed” when they’re all fully implemented — docs need updating

Risks

  • The HOMEBREW_TAP_TOKEN PAT has repo scope and no expiration (flagged March 17, still open)
  • Node.js 20 deprecation warnings in GitHub Actions — deadline June 2, 2026

Flags and watch-outs

  • Test count is 47, covering config.rs (16 tests) and posts.rs (31 tests). Still no TUI-specific tests — app.rs logic is only manually verifiable.
  • The visual line computation in #91/#103 uses character-level division, not word-wrap-aware calculation. This is an approximation — ratatui’s actual wrapping may differ slightly.
  • Many open milestones have zero issues and are past due dates. Worth cleaning up.
  • Only 3 open issues remain: #1 (homebrew-core, backlog), #8 (email signature, backlog), #56 (frontmatter macros, backlog). The active issue queue is empty.

Next session

  • Update CLAUDE.md to remove “stubbed” claims about CLI commands — they’re all implemented
  • Close stale milestones (Visual overhaul, Bulletproof editing, CLI essentials, duplicate TUI on Homebrew)
  • Clean up v1.0.1 GitHub release notes
  • Consider a v1.0.2 release to ship the security fix, performance improvements, and smart quotes to Homebrew users
  • #56 (frontmatter macros) is the next feature if there’s appetite — needs prep
  • Scout for issues under the “First external user” milestone — what’s needed to attract the first user?

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.