Short Posts
A curated collection of bite-sized posts on state machines (agent visualization, UI modeling, team adoption), AI & agent workflows, alongside other short-form explorations in CSS, product design, leadership, and internet curiosities.
This section of my site is focused on small pieces of content that I want to share with you all about either ideas I have to things I see on the internet.
enjoy!
State Machines
- State machines to visualize the work of agents — LLM agent determinism through state machines
- State machines are great, but hard to establish — team adoption challenges
- Modeling resizable panels using State Machines — UI state machine example
- Notes about how the document machine should work — document lifecycle as state machine
- How to Background Agents — background agents made observable and predictable through state machine patterns
See the State Machines — Knowledge Map for the full cluster across accounts.
AI & Agent Workflows
- Vibe code like a PRO — Linear→background agent→PR pipeline concept
- How to Background Agents — practical Cursor background agent setup
- How I Built a Full Booking System as a Side Project — With Devin as My Engineering Partner — real-world case study validating the Linear→background agent→PR pipeline with 6 merged PRs on a production system
- Me uno al programa de Devin Ambassadors — Devin Ambassadors program announcement; the public commitment behind the case study (Spanish-language Devin content, Barcelona meetups)
Web & Hypermedia
- Remodeling the web — critique of the current state of the internet, with links to Seed Hypermedia's architectural response (7 See Also links across 4 accounts)
- What I want for the commenting experience to be — web UX fixes for commenting, including eliminating redirect-based flows
All Posts
- Jean Web Access behind Tailscale — self-hosting a tailnet-exposed AI server: Tailscale Serve vs direct IP
- Pure CSS Scroll Shadows
- Great product features in the wild: Canva Pause Subscription — UX-pattern observation that seeded a cross-account feature request and a product backlog/content pipeline (see its See Also section)
- This is Why Real Leaders Don't Give Orders — Seth Godin
- Why Are Beach Holes So Deadly?
- SR-71 BlackBird
- The Riddle That Seems Impossible Even If You Know The Answer by Veritasium
- Just press record 🔴
- Do you consider Luck in your Life?
- 10 (Profitable) Newsletter Business Ideas To Start In 2025 by Greg Isenberg
<!-- embed: hm://z6Mkvz9TgGtv9zsGsdrksfNk1ajbFancgHREJEz3Y2HsAVdk/short-posts/jean-web-access-behind-tailscale; title: Jean Web Access behind Tailscale --> If Jean Web Access works in a browser but the native Jean app, phone, or another tailnet device cannot connect, check whether Jean is being reached directly over HTTP or through Tailscale Serve. <!-- id:Za7Acojm -->
Recommended setup
Use Tailscale Serve as the tailnet entrypoint and bind jean-server to localhost:
# /etc/jean-server.env
JEAN_HOST=127.0.0.1
JEAN_PORT=3456
JEAN_TOKEN=<long-random-token>
JEAN_ALLOWED_ORIGINS=*Restart Jean and publish it through Tailscale Serve:
sudo systemctl restart jean-server.service
sudo tailscale serve --https=443 off
sudo tailscale serve --bg http://127.0.0.1:3456
tailscale serve statusUse the HTTPS Tailscale Serve URL everywhere, including phones and the native Jean desktop app:
https://<machine-name>.<tailnet-name>.ts.net/?token=<JEAN_TOKEN> <machine-name> is the device name in Tailscale. You can choose any name you want in Tailscale (for example, jean-server, build-box, or home-lab) and use that name in the URL.
For example, if you named the device jean-server in Tailscale:
https://jean-server.tail71152.ts.net/?token=<JEAN_TOKEN>Why the direct Tailscale IP may stop working
When JEAN_HOST=127.0.0.1, Jean only listens on the server itself. That is intentional for the recommended Tailscale Serve setup. Other tailnet devices cannot connect directly to:
http://100.x.y.z:3456They must use the Tailscale Serve HTTPS URL instead. Tailscale Serve receives the tailnet HTTPS request and proxies it locally to http://127.0.0.1:3456 on the server.
Quick checks
From any tailnet device, these should return 200 OK:
curl -i https://<machine-name>.<tailnet-name>.ts.net/readyz
curl -i 'https://<machine-name>.<tailnet-name>.ts.net/api/auth?token=<JEAN_TOKEN>' Expected /readyz body:
{"http":true,"ok":true,"websocket_broadcaster":true}If the HTTPS URL returns a proxy error, confirm jean-server is listening on 127.0.0.1:3456 and restart Tailscale Serve.
Is this a Jean issue?
This is mostly a deployment/configuration gotcha for Jean servers behind a tailnet, not a core Jean server bug. The confusing part is that there are two valid modes:
- Tailscale Serve mode (recommended):
JEAN_HOST=127.0.0.1, connect withhttps://...ts.net/?token=.... - Direct tailnet HTTP mode:
JEAN_HOST=100.x.y.zor0.0.0.0, connect withhttp://100.x.y.z:3456/?token=....
The modes are easy to mix up. If Jean binds to localhost, direct Tailscale IP access will fail. If Jean binds to the Tailscale IP, Tailscale Serve must proxy to that IP instead of 127.0.0.1, or it will fail. <!-- /embed: hm://z6Mkvz9TgGtv9zsGsdrksfNk1ajbFancgHREJEz3Y2HsAVdk/short-posts/jean-web-access-behind-tailscale -->