Blog
Writing on support, web ops, and internal tools. Filter by topic or search the archive.

Articles · Oct 18, 2026 · 3 min read
Enforcing roles in JED with Supabase row level security
Hiding a button isn't access control. In JED, roles live in Postgres and every table checks them, so the database says no even when the app forgets to.

Articles · Oct 18, 2026 · 4 min read
One token model for a REST API and an MCP server
JED ships a REST API and an MCP server for AI clients. I put both behind the same personal access tokens and the same handlers, so there's one set of rules to get right.

Articles · Oct 18, 2026 · 4 min read
Why JED is one fresh repository per client
I build a lot of client sites on the same base. I stopped trying to run them from one shared codebase and made JED a template you copy for each client instead.

Articles · Oct 18, 2026 · 4 min read
Running a Sunday service from a phone
The person who knows when the next slide should come is often not the person at the laptop. Kastr's phone clicker exists to close that gap.

Articles · Oct 18, 2026 · 4 min read
How Kastr turns pasted lyrics into slides
Making lyric slides by hand is slow and easy to get wrong. Here's how Kastr builds them from a block of pasted text, and why I kept the rules simple.

Articles · Oct 18, 2026 · 4 min read
Why Kastr runs in a browser tab instead of an installer
Most projection software starts with a download. I built Kastr to start with a URL, and that one decision shaped almost everything else about it.
Articles · Sep 12, 2026 · 1 min read
When an escalation is really a missing tool
The ticket is rarely the product. The queue is.
Articles · Aug 28, 2026 · 1 min read
Slow is a support ticket
Performance work is customer work when the page is the product.