Sign in

iiinova is part of the Atmosphere — an open, public network where you own your identity.

Adron 🤘🏻

@adron.metalhead.club.ap.brid.gy
7 followers 0 following 239 posts

Shredder, metal head, bikey cyclist, coder, databases, shooter of projectile launchers, tree hugger, peace hippy & war monger, but ya know, it all just depends on so […] 🌉 bridged from ⁂ metalhead.club/@adron, follow @ap.brid.gy to interact

PostsRepliesMedia
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 14/10/2026
Weekend views! Thanks Pacific Northwest!
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 14/10/2026
Shroomies! Rather smurfy like eh! 🧵
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 09/10/2026
Essential Context Management for AI Agents in Development Explore the importance of context management and precise prompts for effective AI interaction in project workflows using Herdr […]
metalhead.club
Original post on metalhead.club
110 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 09/10/2026
I'm not sure about everybody else. But having an "AI Bot" that attempts to sound human - EVEN WHEN SELF-IDENTIFYING AS AN AI - is the absolute worst red flag you can put forward when attempting to recruit me or follow up with me about anything. Just don't have robots call me. Any other method […]
metalhead.club
Original post on metalhead.club
001 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 09/10/2026
Optimize Your Workflow with Herdr: AI Coding Agent Manager Discover Herdr, the terminal workspace manager that transforms how AI coding agents communicate and operate within your terminal. compositecode.blog/2026/10/09/herdi…
compositecode.blog
Herding Agents: How I Actually Use Herdr (on a Ridiculously Wide Screen)
One coding agent is a tool. Two is a pair. Six is a zoo, and somebody has to know which animal is chewing on the fence. For most of this year that somebody was me, armed with a pile of terminal windows, a couple of tmux sessions I half remembered setting up, and the nagging feeling that some agent somewhere had been politely waiting on a yes/no question for twenty minutes. Agents don’t tap you on the shoulder. They sit there, cursor blinking, and burn the most expensive thing in the whole setup, which is wall-clock time. Herdr fixed most of that for me. This post covers what it is, how it works, and how I lay it out day to day. There’s a companion post **(TBD)** on _why_ I split things up the way I do and how I prompt inside the panes. This one is the tour. ## What Herdr is Herdr bills itself as “the runtime your coding agents live on.” Less marketing, more mechanics: it’s a **terminal workspace manager built for AI coding agents**. If you’ve used tmux, you already have about 70% of the mental model. It’s: * **A single Rust binary.** No Electron and no browser tab pretending to be a terminal. `brew install herdr`, or `curl -fsSL https://herdr.dev/install.sh | sh`, and you’re done. * **Something that runs _inside_ your terminal.** iTerm, Ghostty, WezTerm, kitty, Alacritty, even inside tmux if you enjoy nesting dolls. It doesn’t replace your terminal. It organizes what’s in it. * **A client/server pair.** A background server owns the terminal sessions. The thing you look at is just a client. Close the window, detach, drop SSH, and the agents keep working. Reattach and they’re right where you left them. (I learned this the fun way while building the screenshots for this post: the demo window got closed out from under me mid-run, and every agent was still sitting there when I reattached.) * **Agent-aware.** This is the actual point. Herdr detects Claude Code, Codex, Cursor’s agent, Copilot CLI, OpenCode, Devin and a pile of others, then classifies each one’s state so you don’t have to go look. ## The model: session › space › tab › pane Herdr’s concepts page lays out four nouns. The precision matters, so here they are the way I think about them. Noun| What Herdr says it is| What I use it for ---|---|--- **Session**| A persistent server namespace. `herdr` attaches to the default one; `herdr --session <name>` gives you an isolated one.| My one long-lived “everything” session, plus throwaway named sessions when I’m experimenting (like the demo session for this post’s screenshots). **Workspace** (the sidebar calls them _spaces_)| “The top-level project container. Use one workspace per repo, task, or investigation.”| **One space per folder I’m working in.** Full stop. **Tab**| “A layout inside a workspace.”| **One tab per kind of work:** `pr-reviews`, `domain-modeling`, `implementation`. **Pane**| “A real terminal.”| One agent, or one shell, or one thing I’m watching. Arranged in vertical or horizontal splits. Then there are the **agent states** , which make the whole thing worth it: * **Blocked:** the agent needs input, approval, or a decision. _This is the one you care about._ * **Working:** it’s chewing. * **Done:** it finished and you haven’t looked yet. * **Idle:** it finished and you have looked. * **Unknown:** Herdr can’t tell, usually because it’s a plain shell. Those states roll up into the sidebar. Each space gets a dot, and there’s an **agents** list underneath that shows every agent across every space. One glance and I know who’s blocked, who’s working, and who’s done and quietly waiting for me to read their output. That’s the shoulder tap agents never gave me. ## How it works (enough to be dangerous) ### Keyboard The default prefix is `ctrl+b`, deliberately tmux-flavored, and the keymap is “prefix-first” so Herdr doesn’t steal keystrokes from your shell, editor, or the agent. The ones I actually use: Keys| Does ---|--- `prefix` `v`| Split vertical: new pane to the right, side by side `prefix` `-`| Split horizontal: new pane below, stacked `prefix` `h` / `j` / `k` / `l`| Move focus left / down / up / right `prefix` `z`| Zoom the current pane (and again to unzoom) `prefix` `r`| Resize mode `prefix` `c`| New tab `prefix` `shift+t`| Rename tab `prefix` `1`…`9`| Jump to tab N `prefix` `shift+n`| New workspace (space) `prefix` `w`| Workspace picker `prefix` `b`| Toggle the sidebar `prefix` `q`| Detach (everything keeps running) `prefix` `?`| Help, for when you forget all of the above Run `herdr --default-config` to see the full annotated config, including how to remap any of it. Mouse works too: click, drag, split. I won’t judge. ### The CLI and socket API Here’s where it stops being “tmux with a status light.” Everything you can do with a keystroke you can also do from the command line over Herdr’s socket API. That includes the agents themselves, since they’re running in panes Herdr owns. Every screenshot in this post came from a layout I scripted like this, in an isolated session so my real one never got touched: # a space per folder herdr workspace create --cwd ~/Codez/ledger-service --label ledger-service # name the first tab for the kind of work happening in it herdr tab rename w3:t1 domain-modeling # agent on the left, reference material on the right, split again downward herdr pane split w3:p1 --direction right --ratio 0.5 herdr pane split w3:p2 --direction down --ratio 0.5 # start an agent and hand it a scoped prompt herdr pane run w3:p1 "claude --permission-mode plan" herdr agent prompt w3:p1 "Read docs/domain.md and internal/ledger/entry.go. Using only the domain terms Account, Entry, Journal, and Posting (never 'transaction'), describe a Posting aggregate..." # and then, the good part herdr agent list # who is working / blocked / done herdr agent wait w3:p1 --until blocked --until done # block until it needs me herdr pane read w3:p1 # read what it said, without switching to it That’s enough rope for agents to spawn panes, prompt _each other_ , and notice when a sibling is blocked. I’ll admit that’s both very cool and the setup for a future post titled something like “How My Agents Unionized.” ### Integrations `herdr integration install claude` (or `codex`, `copilot`, `opencode`, and so on) drops a small hook into each agent so it reports its lifecycle to Herdr directly, rather than Herdr inferring state by watching the screen. `herdr integration status` shows what’s wired up. Do this. The state dots get noticeably more accurate. ### The rest of the toolbox * **Worktrees:** `herdr worktree create` makes a git worktree and opens it as its own space. It fits the one-branch-per-agent pattern I wrote about in Giving Every Agent Its Own Branch: Git Worktrees for Parallel AI Work. * **Remote machines:** `herdr --remote <ssh-target>` puts panes on other boxes in the same sidebar, and they reconnect independently. See Connecting machines. * **Session state:** layouts persist and restore. Processes don’t survive a server restart (nothing does, that’s physics), but the shape of your workspace does. See Session state. ## How I actually use it That’s the brochure. Here’s what my screen looks like. ### One space per folder Every folder I’m actively working in gets its own space, named after the folder. As I type this, my sidebar has ten of them: `interlinedlist`, then `interlinedlist-ios`, `interlinedlist-macos-native`, `interlinedlist-windows-app`, `interlinedlist-android`, `interlinedlist-architecture-migration`, a couple of client and side projects, and the repo this post lives in. Is that a lot? Sure. Is it more than what’s actually in my head? No. It’s _exactly_ what’s in my head, and that’s the point. The sidebar is a direct readout of my working memory. If it isn’t a folder I’m working in, it doesn’t get a space. When I stop working in a folder, the space goes away. My `config.toml` even sorts the agent list by space (`agent_panel_sort = "spaces"`) so the agents group the same way my brain does. It’s mostly for my own mental organization, and I’m fine with that. The agents don’t care what the sidebar looks like. I do. ### One tab per kind of work Inside a space, tabs aren’t “more room.” Tabs are **modes**. I name them for the kind of work being done: * **`domain-modeling`** : one agent, plus the glossary, domain notes, and recent history open next to it. The agent’s job is to think, not type. * **`implementation`** : one or more agents, each scoped to a slice of the code, with a diffstat or test runner and a plain shell beside them. * **`pr-reviews`** : a reviewing agent next to the actual diff, so I can check its claims against the code without switching windows. Most spaces have just one tab, whichever mode that folder is in today. The busy ones have all three. Switching tabs is switching hats, and the tab label tells me which hat is on before I’ve read a single line. ### One or more terminals, split vertically or horizontally Within a tab I keep a simple rule: **agents get tall columns, shells get short stacks.** Agents produce long, scrolling output: plans, numbered findings, diffs they want to show me. That wants height. So agents get vertical splits (`prefix v`), side by side, full height. Shells, test runners, `git log`, diffstats and log tails are glanceable. They get horizontal splits (`prefix -`) stacked in the right-hand column. ### The ultrawide changes the math Here’s the cheat. I run all of this on a **5120×1440, 32:9 ultrawide** : two 2560×1440 monitors fused into one with no bezel down the middle. At normal terminal font sizes, that’s room for **three or four full-height agent columns _plus_ a stacked utility column and the sidebar**, all visible at once, nobody squished. On a regular 16:9 screen, that same implementation tab looks like this: Workable. Tight. Add a third agent and you’re zooming panes in and out all day. On the ultrawide it’s this: The difference isn’t really “more stuff.” It’s that **nothing is hidden**. When an agent goes blocked, I don’t need to find it. It’s already on screen, in my peripheral vision, with a red dot in the sidebar to back it up. Herdr tells me _who_ needs attention. The ultrawide means I can _see_ why without changing anything. That screenshot is an agent I’d told to touch `cmd/main.go` _only_. It found the repo had no `go.mod`, which meant staying in scope required a decision. So it stopped, went **blocked** , and asked. Herdr flagged it, and I could see the question without switching anything. Total cost: one keystroke. The alternative, an agent “helpfully” adding a module file and rewiring imports across a package I’d explicitly fenced off, costs a lot more than one keystroke. Why that worked, and how I write prompts so it keeps working, is the next post **(TBD)**. ## The short version * **Herdr** is a terminal workspace manager for coding agents: one Rust binary, runs in your terminal, background server, agent-state detection. * **Spaces are folders.** One per folder you’re working in. It’s a mirror of your head, not a filing cabinet. * **Tabs are modes of work.** `pr-reviews`, `domain-modeling`, `implementation`. * **Panes:** agents tall, shells short. * **The sidebar** tells you who’s blocked. The **ultrawide** lets you see why without moving. Install it, run `herdr`, hit `ctrl+b ?`, and give it a day. Worst case, you’ve got a nice tmux. Best case, you stop finding agents that have been patiently blocked since lunch. ### References * Herdr: herdr.dev · Docs · Concepts · Configuration & keybindings · Agents · Socket API · Source on GitHub * Related on Composite Code: * Giving Every Agent Its Own Branch: Git Worktrees for Parallel AI Work * Ask, Plan, Confirm: Making Agents Stop Before They Start * Twenty-ish Terminal Commands for Getting Around the File System * Screenshots were captured on Herdr 0.8.0 in an isolated `--session`, against throwaway demo repos, with Claude Code in plan mode (nothing was written to disk by the agents). ### Share this: * Share on X (Opens in new window) X * Share on Facebook (Opens in new window) Facebook * Share on LinkedIn (Opens in new window) LinkedIn * Share on Reddit (Opens in new window) Reddit * Share on Tumblr (Opens in new window) Tumblr * ### Like this: Like Loading…
010 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 29/09/2026
Transport Fever 3 released! It has begun!
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 24/09/2026
Streamline Coding Agent Setup for Maximum Productivity Unlock your coding agent's potential with a repeatable setup process. Learn key strategies for efficient local environments and collaboration. compositecode.blog/2026/09/24/agent…
compositecode.blog
Agent-Ready Local Environments and MCP
Getting a coding agent productive is less about the prompt and more about whether the machine in front of it can actually build, run, and reach the systems the work depends on. Cursor, Claude, Codex, and the rest are fast when the local world is already honest: dependencies install, the app boots, tests can run, and the external surfaces (GitHub, GitLab, Slack, Outlook, Teams, whatever is in play) are reachable through clear, permissioned paths. When those pieces are missing, the agent spends its tokens rediscovering your laptop instead of doing the job. This post is about making that setup cheap and repeatable. ## The real prerequisite is a bootable story Every repo should answer, in files the agent can read, a small set of questions: 1. What do I need installed on this machine? 2. How do I get from clone to a running local system? 3. Which services does this project talk to, and which of those am I expected to use locally? 4. Where do secrets live, and what is _not_ allowed? 5. How do I know the setup worked? If those answers only exist in your head, the agent will invent something almost right. Almost right is expensive. I keep this in the product repo as first-class docs and scripts: `README`, `CONTRIBUTING`, `docs/setup`, `scripts/bootstrap`, `.env.example`. When the work spans more than one codebase, I also mirror the “where the rest of the world lives” map in the project notes repo. ## Make setup mechanical Agents are excellent at following a checklist. They are mediocre at inferring your undocumented brew taps and tribal knowledge. What works well right now: **A single bootstrap path.** One script or documented sequence: install language runtimes, install dependencies, copy env templates, start local dependencies, run a smoke check. Prefer boring and explicit over clever. **Pinned, discoverable tooling.** Version files (`.nvmrc`, `.node-version`, `mise.toml`, `asdf` configs, `rust-toolchain`, etc.) beat README poetry. The agent should be able to detect the toolchain without asking you which Node major you meant last quarter. **`.env.example` that matches reality.** Every required variable named. No secret values. Short comments for where to get each one. If a variable is only for production, say so. **Smoke tests for the environment.** A command that proves the local stack is alive: `npm run doctor`, `make verify`, a compose healthcheck, a migration status call. Green means “safe to start feature work.” Red means “fix the machine, not the feature.” **Dev containers or explicit host setup. Pick one and document it.** Either the agent works inside a known container, or it works on the host with a known bootstrap. Mixing both without saying which is canonical creates two slightly broken worlds. This is the same instinct as my old `dev-setup-osx` habit, updated for a world where the “new developer” might be an agent that showed up thirty seconds ago. ## Tell the agent where the working systems are Local build is only half the map. Most real work touches other systems: source hosts, chat, mail, issue trackers, cloud consoles, internal APIs. Write down the topology. * Product repos and their remotes (GitHub, GitLab, both, mirrors). * Which environments exist: local, staging, production, preview apps. * Which human collaboration surfaces matter: Slack channels, Teams teams, Outlook lists, Linear/Jira projects. * Which of those the agent is allowed to read or write. * How authentication is supposed to happen for each. Do not make the agent guess that “the deploy” means GitHub Actions in one repo and a GitLab pipeline in another. Put the pointers in markdown next to the code or in the notes repo. Ambiguity here turns into the wrong PR opened against the wrong remote, or a “fix” that never lands where humans look. ## MCP is how agents reach the rest of the desk Model Context Protocol servers are the practical bridge between the coding agent and the tools already on your desk. Used well, they turn “go check the thread / issue / inbox / pipeline” into a first-class action instead of a copy-paste scavenger hunt. The useful pattern is not “connect everything.” It is “connect the systems this project actually depends on, with the least privilege that still helps.” A sane MCP layout for project work often includes: * **Source control:** GitHub and/or GitLab for issues, PRs, checks, and releases. * **Chat:** Slack or Teams for the channels where decisions and unblockers live. * **Mail/calendar:** Outlook or similar when the work is genuinely gated on threads or meetings, not because it is fun to give an agent your inbox. * **Project tracking:** whatever holds the tickets, if that is not already the git host. * **Docs and runbooks:** if they live outside the repo and agents keep asking for them. Wire these at the user or project level in Cursor (and equivalents elsewhere), then document in the repo which MCP servers are expected for this project and what they are for. An agent that knows “Teams is available for the eng channel, GitHub is available for PRs, Outlook is not in scope for this repo” wastes less time and takes fewer weird actions. Authentication matters. Prefer the product’s normal OAuth/device flows. Keep tokens out of the notes repo and out of prompts. If a server needs auth, say so in setup docs and stop there. Do not paste credentials into markdown “for convenience.” ## Boundaries beat cleverness An agent with broad access and no rules will eventually do something technically impressive and socially awful: comment in the wrong channel, open a PR against the wrong fork, or dig through mail that was never part of the task. Give it clear limits: * Read-only by default where write access is not required. * Explicit allow-lists of repos, channels, and projects. * Repo instructions that say when to use MCP versus when to stay local. * The same ask-plan-confirm gate you use for code changes when the action leaves the laptop (posting, labeling, merging, emailing). Local environment setup gets the agent building. MCP gets the agent collaborating. Boundaries keep both from becoming a mess you have to unwind. ## A minimal checklist I actually use When I stand up a project for agent-assisted work, I want at least this: 1. Clone, bootstrap, and smoke test documented and scripted. 2. Toolchain versions pinned in-repo. 3. `.env.example` complete; real secrets elsewhere. 4. Notes/brief that name the remotes, environments, and collaboration surfaces. 5. MCP servers configured for the systems in play, with purpose notes in the project docs. 6. Clear write/read expectations for each integration. 7. A first prompt that points the agent at setup docs before feature work. None of that is fancy. All of it is what makes Cursor, Claude, Codex, and friends look brilliant on day one instead of lost in your `PATH`. The goal is simple: when an agent sits down at the project, the local world boots, the surrounding systems are findable, and the rules of engagement are already written down. ### Share this: * Share on X (Opens in new window) X * Share on Facebook (Opens in new window) Facebook * Share on LinkedIn (Opens in new window) LinkedIn * Share on Reddit (Opens in new window) Reddit * Share on Tumblr (Opens in new window) Tumblr * ### Like this: Like Loading…
210 2
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 12/09/2026
BrickCon 2026! So much going on in this cityscape! 🧵
200 2
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 12/09/2026
BrickCon GI Joe! 🧐🤓 🧵
110 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 12/09/2026
Also so many folks riding the light rail to BrickCon! 💙 to see that! Good job Seattle!
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 12/09/2026
BrickCon 2026! Ships! Sailing! Pirates! 🧵
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 12/09/2026
BrickCon 2026! The railroads! 🚆 🧵
101 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 12/09/2026
BrickCon 2026! USS Iowa 👀 🧵
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 11/09/2026
Ever feel like some videos should just default to 2x? Some just seem - and maybe this is just me - seem so unbelievably slow.
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 10/09/2026
Biscuits are such a great buttery delivery mechanism!
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 10/09/2026
HELP! I've asked Chat GPT. It spiraled off into other grids. I've done some search engine magic myself... and so far I've not found what I'd like to find. I'm trying to find data grids, especially datagrids with rows that have nested rows or are multiple rows themselves. Basically that wrap […]
metalhead.club
Original post on metalhead.club
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 10/09/2026
A big list eventually becomes a monster. Nesting is how you break it into parts without losing the whole. interlinedlist.com/blog/lists-insid…
interlinedlist.com
Lists Inside Lists
A big list eventually becomes a monster. Nesting is how you break it into parts without losing the whole.
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 09/09/2026
Just shoved a USB 2, as it did fit, into a RJ45 connection. That's how my Tuesday like a Monday is going. or wait... as I typed that I realize it's Wednesday. weeeeehoooo THAT kind of deliriousness. Hell yeah!
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 09/09/2026
The same lists, shown as cards, a grid, a tree, and a full entity diagram. Different views answer different questions. interlinedlist.com/blog/four-ways-t…
interlinedlist.com
Four Ways to See the Same Data
The same lists, shown as cards, a grid, a tree, and a full entity diagram. Different views answer different questions.
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 08/09/2026
Every list you build by clicking is really a small schema. Once you can see it, you understand what a list is capable of. interlinedlist.com/blog/the-schema-…
interlinedlist.com
The Schema Underneath
Every list you build by clicking is really a small schema. Once you can see it, you understand what a list is capable of.
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 07/09/2026
The best data entry is the kind you don't do. Defaults are how a new row shows up already half-finished. interlinedlist.com/blog/fields-that…
interlinedlist.com
Fields That Fill Themselves In
The best data entry is the kind you don't do. Defaults are how a new row shows up already half-finished.
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 04/09/2026
I quote from Claude, "Just let me know when you or I can commit, Github is down again and unreachable."
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 03/09/2026
Alright Seattle... I need tacos. What do I do?
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 03/09/2026
Have y'all had Visual Studio Code, of late, just start up like this? Just ends up hung there sometimes doing nothing.
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 03/09/2026
Anybody else got thoughts on this? metalhead.club/@adron/1172087956452…
metalhead.club
Adron 🤘🏻 (@adron@metalhead.club)
Dear Github, Here''s your list of things we need in this, the year of 2026, with the dawn of LLMs now past us and the full bore weight of the Gen AI spectre forced on us. Please fix: 1. Issues need to be about 100x faster to create, manage, log, read, and respond to in a more intuitive way. Intuitive for both us, the engineers working them and responsible for them, but also the Gen AI LLMs we bring the focus to work those issues. 2. Uptime. Nuff' said. 3. 🧵 1/2
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 03/09/2026
The follow up to that rant is, anyone using any type of reasoning system, just like when you're using deterministic systems, you're responsible for nondeterministic systems use. At least you should be. 100%. I'm sure our legal system might be twisted to allow some people - ya know like the rich […]
metalhead.club
Original post on metalhead.club
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 03/09/2026
I love AI training when it's like... "AI can make mistakes and introduce security bugs..." yeah, cuz it's trained to do what people have already done. "AI can count things wrong sometimes..." yeah, cuz it's trained on humans and they do that too. "AI can... " yeah, it's trained on human data […]
metalhead.club
Original post on metalhead.club
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 01/09/2026
With monorepos how do you manage the massiveness of context needed for LLMs? or do you just not? would you advise not going with monorepos?
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 01/09/2026
Kind of cringe walking around thinking someone around me could work for ICE or that someone in the vicinity is a Neo-Nazi or child rapist. Yet I repeat myself. 😬 Strange and uncomfortable days we live in.
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 01/09/2026
Experience Real-Time Transit with Dashing Arrivals Map Explore Dashing Arrivals, a live transit map for the Puget Sound region, showing real-time bus, train, and ferry updates at your fingertips. compositecode.blog/2026/08/31/dashi…
compositecode.blog
Dashing Arrivals: Watch Every Bus, Train, and Ferry in Puget Sound Move in Real Time
There’s a particular kind of magic in watching a whole city move at once. Not one bus, not one train — _all_ of them, gliding across the map in real time, each one a little rectangle of somebody’s commute home. That’s **Dashing Arrivals** — a live transit map for the Puget Sound region. Open it up and you’re looking at every active bus, train, and ferry in service right now, from a King County Metro coach on Rainier Avenue to a Sound Transit Link train sliding through the Rainier Valley to a Washington State Ferry crossing to Bainbridge. On a typical weekday afternoon that’s **over 1,100 vehicles** on screen, all updating live. This post is a tour of what it is and what you can do with it. ## The whole region at a glance The default view drops you over Puget Sound with everything turned on. A quick legend does a lot of work here: **color tells you the agency** and **shape tells you the type** (bus, train, or ferry), and every icon is rotated to face the direction it’s actually traveling. Green is King County Metro, blue/indigo is Sound Transit, red is Pierce Transit, purple is Kitsap, and so on — seven agencies in all, plus the ferries. Pan, zoom, and the icons resize smoothly so trains read a little larger than buses, which read a little larger than ferries. Between updates, vehicles don’t teleport — they **animate from their last position to the next one** , so the whole map has a calm, continuous, living quality instead of a jumpy refresh. ## Click any vehicle for the details Tap a vehicle and it tells you who it is: the route, the agency, the fleet number, its heading (as a compass direction _and_ degrees), its speed, and when it last reported in. Here’s a **1 Line** Link train in the Rainier Valley, heading south at 159°. See that **Show route ▸** link at the top of the popup? That’s where it gets fun. ## See the entire route Click **Show route** and the map draws the vehicle’s full line — the shape it follows and every stop along the way — right under the live vehicles still moving on it. Here’s the **1 Line** , Link light rail’s spine, threading from the north down through downtown, Beacon Hill, and the Rainier Valley. The blue train icons strung along the highlighted line are the actual trains in service on it right now. And the newer **2 Line** , running across Lake Washington on I‑90 to Bellevue and up to Downtown Redmond. (Fun bit of local history: the 2 Line effectively replaced the old ST Express 550 bus between Seattle and Bellevue — which is why you won’t find a 550 on the map anymore.) ## Rail beyond Link: the Sounder Light rail isn’t the only train out there. Pick a **Sounder** commuter-rail train and you get the full BNSF corridor. This is the **S Line** , running from King Street Station in Seattle south through Tukwila, Kent, Auburn, and on toward Tacoma and Lakewood. Sounder only runs during peak commute windows, so catching one on the map is a small, satisfying reward for looking at the right time — and down in Tacoma you can see Pierce Transit’s red buses fill in the local network. ## Buses, of course — every route The same trick works for any bus. Click one, hit **Show route** , and the corridor lights up in that agency’s color. The **RapidRide C Line** from West Seattle into downtown, in Metro green. And the **RapidRide E Line** , a ruler-straight shot down Aurora Avenue from Shoreline to downtown — one of the busiest bus corridors in the state. Whether it’s a lettered RapidRide line, a numbered local route, or a Community Transit Swift line, the route overlay works the same way. ## Filter the firehose Eleven-hundred vehicles is a lot. The **Show** and **Agencies** panel lets you dial it in — toggle whole modes or individual agencies on and off. Here I’ve switched **off buses** to leave just trains and ferries. Suddenly the shape of the rail network jumps out — the Link lines tracing north–south and across the lake — alongside the ferries stitching the Sound together to Bainbridge, Bremerton, Kingston, and Vashon. It’s the whole regional rail-and-water map, drawn entirely by the vehicles themselves. ## When’s my ride? Live arrivals at any stop Zoom in and the stops appear. Click one to get a live arrivals board. This is the **Symphony** stop downtown, with real-time predictions counting down — _Due, Due, 1 min, 4 min, 6 min…_ — for 1 Line and 2 Line trains toward Lynnwood City Center. Each prediction carries a live indicator, and any alerts that affect this specific stop are pinned right at the top. ## Know before you go: service alerts The pill at the top of the screen keeps a running count of active **service alerts** across the region — detours, stop relocations, reduced service, construction. Open it and you can read them all: each card shows the agency, the affected routes, the reroute instructions, and a link out to the agency’s own detail page. It’s the regional “what’s disrupted right now” board in one place. ## Light or dark, your call Prefer a bright map? A theme toggle switches between a sleek dark basemap and a clean light one (with a **System** option that follows your OS). Same live data, different mood. ## Under the hood For the curious, Dashing Arrivals is a modern, open-source web app: * **Live data** comes from the **OneBusAway** Puget Sound regional API, decoded from **GTFS‑realtime** vehicle-position feeds. A single regional feed covers King County Metro, Sound Transit, Community Transit, Pierce Transit, Kitsap Transit, and Everett Transit. * **Ferries** come from a separate source — the **WSDOT** Washington State Ferries vessel-location API — and are normalized in alongside everything else. * The map is **MapLibre GL** on an open **OpenFreeMap** basemap (no proprietary map key required), with the app built on **Next.js** and **React** and deployed on **Vercel**. * Vehicle positions are fetched on a short polling loop and cached server-side, then **eased between updates** on the client so motion looks smooth. Icons are tinted per agency, sized by zoom, and rotated to the reported heading. Eventually the GTFS feed is going to have some changes, and I plan to put those fixes in then, but in the meantime this is a solid way to explore the Seattle and Puget Sound area’s transit options! ## Go watch the city move That’s the whole pitch: one map, every vehicle, in real time, with routes, stops, arrivals, and alerts a click away. It’s genuinely useful for catching a bus — and, if you’re the type who likes watching systems work, it’s a little bit hypnotic. **Try it for yourself atdashingarrivals.com.** * * * _Screenshots captured live from dashingarrivals.com. Basemap © OpenFreeMap / OpenMapTiles, data © OpenStreetMap contributors. Real-time transit data via OneBusAway and WSDOT._ ### Share this: * Share on X (Opens in new window) X * Share on Facebook (Opens in new window) Facebook * Share on LinkedIn (Opens in new window) LinkedIn * Share on Reddit (Opens in new window) Reddit * Share on Tumblr (Opens in new window) Tumblr * ### Like this: Like Loading…
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 30/08/2026
Slava Ukraini. ✊🏻
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 27/08/2026
I've gotta say, in some ways I'm ok with Starbucks and in other ways Starbucks just pisses me off to no end. One of my biggest complaints is how they do such a shit job training their baristas and don't teach them anything sane about coffee or espresso. They just teach them this made up […]
metalhead.club
Original post on metalhead.club
110 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 27/08/2026
A column type is a promise about what goes in it. Pick the wrong one and every row after fights you. Here's how to pick right. interlinedlist.com/blog/picking-the…
interlinedlist.com
Picking the Right Column
A column type is a promise about what goes in it. Pick the wrong one and every row after fights you. Here's how to pick right.
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 27/08/2026
I'm in the process of building out a new dev workflow via LLM and I've decided it's not even going to include Github. Github has become a brick wall of problems and an overall bottleneck. Something has to change so I'm going to start creating that change. Wish me luck!
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 26/08/2026
The fastest working list you'll ever build starts with someone else's homework. Pick a template, tweak two things, done. interlinedlist.com/blog/the-60-seco…
interlinedlist.com
The 60-Second List
The fastest working list you'll ever build starts with someone else's homework. Pick a template, tweak two things, done.
010 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 25/08/2026
Maximize Git Efficiency with Parallel Agents and Worktrees Discover how to overcome Git's one-tree problem by leveraging worktrees for parallel AI execution, enhancing your agents' efficiency. compositecode.blog/2026/08/19/workt…
compositecode.blog
Giving Every Agent Its Own Branch: Git Worktrees for Parallel AI Work
Run two coding agents against a single working tree and they will fight. One is halfway through editing `app/api/messages/route.ts` while the other checks out a different branch underneath it. The index lock flickers. A `git stash` from one session swallows the other’s uncommitted work. I have lost real edits this way, and every time the root cause was the same: one working tree, one `HEAD`, two writers. The InterlinedList repo already had matching agents for the jobs I hand off most: a Next.js implementer, a migrations specialist, unit and e2e testers, a docs writer, security and UX reviewers. They are good at their lanes. What they were missing was a lane in the literal sense. They all drove on one road. I found the pattern I wanted written up in Augment’s guide to git worktrees for parallel AI execution, and it maps almost one to one onto how I already think about agents. This is the writeup of what I built on top of it for this repo: the directory convention, the seven scripts that manage the lifecycle, and the wiring that makes every agent use them without being reminded. ## The one-tree problem A normal clone gives you a single working directory backed by one `.git`. That is fine for one person doing one thing. The moment you parallelize, the shared mutable state (the working files, the index, the current branch) becomes the bottleneck. You cannot have the migrations agent on `agent/add-webhooks` and the docs agent on `agent/help-refresh` at the same instant, because “the branch” is a property of the whole checkout. _Two writers, one mutable checkout. The collisions have nothing to do with the work: an index lock flickers, a`git stash` swallows the other session’s edits, `HEAD` thrashes between branches._ Git solved this in 2015 with `git worktree`. A worktree is a second (third, fourth) working directory attached to the same repository. Each one has its own files, its own index, and its own checked-out branch, while sharing one object store on disk. The object store is the expensive part, so you share it. A directory of files is cheap, so you duplicate it per task. That is exactly the tradeoff you want for parallel agents. _Share the expensive part, duplicate the cheap part. The object store lives on disk once; the working files, the index, the checked-out branch, and even the dev-server port are private to each worktree._ ## The convention Every agent works in `.trees/<task-id>` on a branch named `agent/<task-id>`, cut from `origin/develop` (this repo integrates on `develop`, not `main`). So a task called `add-list-webhooks` lives at `.trees/add-list-webhooks` on branch `agent/add-list-webhooks`. The directory name and the branch name always agree because both are derived from the same sanitized slug. The `.trees/` container is gitignored. Worktrees are workspace, not history: # .gitignore # Agent worktrees (see scripts/worktrees/) .trees/ That single ignore line is the whole footprint the pattern leaves in the tracked tree. Everything else is scripts and instructions. ## The scripts I did not want agents (or me) typing raw `git worktree` incantations and getting the branch name wrong, or forgetting to copy `.env.local`, or leaving stale metadata behind. So the lifecycle lives in `scripts/worktrees/` as a small set of focused shell scripts. Here is every one of them. _The whole lifecycle before the per-script detail. Create, inspect while working, remove when it lands, sweep the merged trees on a schedule._ **`_lib.sh`** is the shared library the others source. It holds the functions that keep conventions consistent: `wt_repo_root` resolves the primary checkout even when you call it from inside a linked worktree (it reads `git rev-parse --git-common-dir` and walks up), `wt_sanitize` lowercases a task id and strips it to `[a-z0-9._-]`, `wt_resolve_base` fetches and prefers `origin/<base>` over a local branch, `wt_port_for` hashes a branch name into a stable dev port, and `wt_is_locked` reads the porcelain worktree list to check lock state. Nothing in it is clever. It exists so the clever bits are written once. **`wt-create.sh<task-id> [base]`** is the one agents call first. It creates the worktree and makes it ready to work in, in one shot: scripts/worktrees/wt-create.sh add-list-webhooks Under the hood it resolves the base ref (default `develop`), ensures `.trees/` is in `.gitignore`, turns on `git rerere` so repeated conflict resolutions replay across parallel merges, runs `git worktree add -b agent/<slug> .trees/<slug> origin/<base>`, copies the root `.env.local` into the worktree, appends a deterministic `DEV_PORT` derived from the branch name, runs `npm ci --prefer-offline`, and finally locks the worktree so other sessions can see it is in use. Flags let you opt out where it makes sense: `--no-install` skips the dependency install for a quick plumbing check, `--no-lock` leaves it unlocked, and `--baseline` runs the test suite right after setup so a green baseline proves any later failure came from the agent’s change rather than a pre-existing break. The port assignment is worth a sentence. Two agents both running `next dev` on 3000 is another collision, a quieter one. `wt_port_for` runs the branch name through `cksum` and maps it into the 3100 to 9998 range, so each worktree gets a stable, distinct port written into its own `.env.local`. Start the server with `npm run dev -- -p "$DEV_PORT"` and two dev servers coexist. **`wt-list.sh`** answers “what is running right now.” It prunes stale metadata, then prints one row per worktree with path, branch, lock state, and short HEAD: PATH BRANCH LOCKED HEAD /Users/adron/Codez/interlinedlist feature/fix-blog-image - 58afa91562 /Users/adron/Codez/interlinedlist/.trees/add-list-webhooks agent/add-list-webhooks yes b78faf9e21 Before an agent touches a shared file, it can look here and see who else is holding what. Git will not warn you about two branches editing the same file, so this list plus discipline about non-overlapping file domains is the actual safety mechanism. **`wt-lock.sh<task-id> [reason]`** and **`wt-unlock.sh<task-id>`** are thin wrappers over `git worktree lock`/`unlock`. A lock is advisory: it resists prune and move, and it is the signal in `wt-list.sh` that says “an agent is live in here, do not reap this.” **`wt-remove.sh<task-id>`** is the teardown. It unlocks if needed, runs `git worktree remove`, and prunes. This matters more than it looks: deleting a worktree with `rm -rf` leaves dangling metadata in `.git/worktrees/` that haunts you until the next prune. The script never does that. `--force` discards uncommitted changes on purpose, and `--delete-branch` drops `agent/<task-id>` in the same step when the work has landed. **`wt-cleanup.sh [base]`** is the bulk sweep. It walks every worktree physically under `.trees/`, and for each one whose branch is already an ancestor of `origin/develop` (in other words, merged), it removes the worktree and deletes the branch. It deliberately skips anything outside `.trees/`, so the primary checkout and any sibling worktrees I keep elsewhere on disk are never touched. This is the script you point a daily cron or a post-merge hook at. Each of these is also exposed as an npm script, so `npm run wt:create -- add-list-webhooks`, `npm run wt:list`, and `npm run wt:remove -- add-list-webhooks` all work if you prefer that entry point. There is a `scripts/worktrees/README.md` documenting the whole set alongside the code. ## Wiring it into the agents Scripts nobody runs are decoration. The point was to make every agent reach for a worktree by default, so I added the instruction in three places at three levels of specificity. At the top, `CLAUDE.md` now states the standing rule: every agent works in an isolated worktree, torn down with the lifecycle scripts. That is the repo-wide contract. In the middle, two shared protocol docs under `.claude/workflows/` hold the full detail: `worktrees.md` spells out the create-work-remove lifecycle, the boundaries (shared object store, non-overlapping files, and the important caveat that the database is shared even though the files are not), and `plan-first.md` covers the companion habit I wrote about separately. Every agent and skill links to these rather than repeating them. At the leaf, each of the eight agent definitions in `.claude/agents/` got a “Work in an isolated git worktree (required)” section written for its job. The implementers (Next.js, migrations, tests, docs, blog) get the full create-work-remove flow. The two read-only reviewers (security, UX) get a variant that tells them to `cd` into the worktree under review and read its diff, and explicitly not to create, lock, or remove anything. The migrations agent gets an extra warning in bold, because the worktree isolates `schema.prisma` and the migration files but not the Postgres instance: `db:migrate` still hits localhost and `db:migrate:deploy` still hits production from any worktree. That is the one place the isolation is a lie, and the agent needs to know it. The five paired skills in `.claude/skills/` (the ones that back the implementer agents) got a short “Worktree-first, plan-first” block near the top pointing at the same protocol docs, so whether the work comes in through the agent or the skill, the instruction is there. ## Proving it works I ran the whole lifecycle before committing any of it. Create a worktree from `develop`, confirm it is locked and has its port, unlock and re-lock it, remove it with the branch, and verify the cleanup pass leaves the sibling worktrees alone: scripts/worktrees/wt-create.sh wt-smoke-test --no-install scripts/worktrees/wt-list.sh # shows agent/wt-smoke-test, LOCKED yes scripts/worktrees/wt-unlock.sh wt-smoke-test scripts/worktrees/wt-lock.sh wt-smoke-test "smoke re-lock" scripts/worktrees/wt-remove.sh wt-smoke-test --delete-branch scripts/worktrees/wt-cleanup.sh develop # safe no-op, siblings untouched Every step did what it said, the `.gitignore` guard refused to duplicate the `.trees/` line it found already present, and the sibling worktree I keep for feed-perf work was never in scope for cleanup. That last part was the thing I most wanted to confirm, because a cleanup script that reaches outside its sandbox is worse than no cleanup script. ## Where agents still get confused Isolating the filesystem fixes the filesystem. It does nothing about the fact that the work itself overlaps, and there are a handful of ways an agent still gets lost. **The database is one instance, and every worktree writes to it.** I flagged this to the migrations agent in bold, but it deserves more than a warning. If the migrations agent adds a column on `agent/add-webhooks`, that column now exists in the same localhost Postgres every other worktree points at. The docs agent three trees over never sees the changed `schema.prisma`, yet its queries hit the mutated database anyway. Additive-only migrations keep this survivable most of the time, since an extra column nobody reads is harmless. But the moment two agents touch the same table, or one runs `db:migrate:deploy` and reaches production from what looked like a sandbox, the isolation is a fiction. The files are private. The database is not. **Green in isolation, red on merge.** This is the one that bites. Agent A changes a function signature in `lib/lists/queries.ts`. Agent B, on its own branch, calls that function from a route it owns. Their files never overlap, so `wt-list.sh` shows no conflict and git stays quiet. Both test suites pass, because A’s worktree still holds B’s old caller and B’s worktree still holds A’s old signature. It’s all green right up until both branches land on `develop`, and then the integration is broken in a way neither agent could see from inside its own tree. Worktrees convert a loud, immediate collision into a quiet one that surfaces later. Often a fair trade, but a trade. **Stale base drift.** Every worktree is cut from `origin/develop` the moment it’s created. Agents aren’t always short-lived. Let one run for a few hours while three others merge back, and it’s now building on a `develop` that no longer exists. It will reintroduce a helper that got deleted upstream, or write against an API another agent already reshaped. The worktree has no idea the ground moved under it. Nothing in the create-work-remove loop forces a re-fetch, so a long-running agent drifts out of date without noticing. **“Does this already exist?” stops having one answer.** With five branches in flight, whether feature X is “already built” depends on which tree you grep. An agent that checks the primary checkout won’t see work-in-progress on another branch, and it will happily build a second copy. I’ve watched two sessions independently implement overlapping halves of the same feature, each sure it was first, because neither branch was visible to the other and neither said up front what it was about to touch. `wt-list.sh` tells you which branches exist. It says nothing about what each one intends to change. **The lock is a suggestion.** `wt-lock` resists prune and move, and it flags a tree as live in the list, but it will not stop another agent from opening the same file on its own branch and editing away. The real guard against two agents clobbering one file is the up-front decomposition plus the discipline to run `wt-list.sh` and honor what it shows. An agent that skips the check has no seatbelt, just the shape of one. **Abandoned trees pile up.** `wt-cleanup.sh` only sweeps branches already merged into `develop`. A worktree from a crashed or cancelled session is unmerged, still locked, and invisible to the sweep. It sits on disk with a full `node_modules` until someone removes it by hand. And an agent resuming a task can trip over a half-finished tree from an earlier run and read its stale state as current work. **Losing the current directory.** The workflow says `cd .trees/<task-id>` and do everything there. Shell state doesn’t always survive between tool calls, and an absolute path into the primary checkout looks identical to one into a worktree. An agent that loses track of where it is can read the main checkout’s copy of a file, reason about it as though it were its branch’s version, and edit the wrong tree. The isolation holds only as long as the agent keeps its bearings. ## What this buys The honest version: worktrees do not make independent tasks independent. If two agents both need to edit the same route, isolating their filesystems just delays the merge conflict, it does not prevent it. The decomposition still has to be real. What the pattern removes is the accidental collision, the kind that has nothing to do with the work and everything to do with sharing one mutable checkout. Those were most of my pain, and now they are gone by construction. ## Advantages and disadvantages **Advantages** * Accidental collisions disappear. Each agent gets its own files, index, and `HEAD`, so index-lock flicker, a stray `git stash` eating another session’s edits, and checkout thrash stop happening. * Every task lands on its own `agent/<task-id>` branch, which keeps review and merge clean and stops one task’s half-finished mess from bleeding into another’s diff. * The object store is shared, so the costly part of the repo lives on disk once and spinning up another tree is cheap. * Each worktree gets a deterministic `DEV_PORT`, so several `next dev` servers run side by side instead of fighting over 3000. * The lifecycle is scripted and wired into every agent definition, so the right setup and teardown happen without anyone remembering the incantation. * `git rerere` is on by default, so a conflict you resolve once replays across the parallel merges that hit it again. * Cleanup is fenced to `.trees/`, so the bulk sweep never reaches the primary checkout or the sibling worktrees I keep elsewhere. **Disadvantages** * The database isn’t isolated, and neither is anything else global (production through `db:migrate:deploy`, OAuth apps, third-party rate limits). File isolation quietly implies an isolation that isn’t there. * Overlapping edits on separate branches turn into silent, deferred conflicts and semantic breakage that pass every isolated test and only show up at integration. * A long-running worktree drifts from a moving `develop`, and nothing in the loop forces the re-fetch that would catch it up. * Locks are advisory, so the actual protection against two agents editing one file is decomposition plus discipline, not anything git enforces. * With several branches live, “does this already exist” has no single answer, and agents duplicate each other’s work when branches can’t see one another. * Every worktree carries a full `node_modules`, so disk use and `npm ci` time multiply with each active task. * Crashed or abandoned sessions leave locked, unmerged trees that the merged-only cleanup won’t reap, so someone clears them by hand. * Coordination is still manual: the tooling shows which branches exist, not which files each agent means to touch. The next habit I want in every agent sits upstream of all of this: stop and plan before touching a single file. That one is worth its own post. More solutions to the confusion above are coming in the next few posts. Subscribe so you don’t miss ’em: drop your email into the box just below this post, or grab the RSS feed. _I’mAdron, brainstorming and building InterlinedList._ ### Share this: * Share on X (Opens in new window) X * Share on Facebook (Opens in new window) Facebook * Share on LinkedIn (Opens in new window) LinkedIn * Share on Reddit (Opens in new window) Reddit * Share on Tumblr (Opens in new window) Tumblr * ### Like this: Like Loading…
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 25/08/2026
The Importance of Planning Before Coding: A Workflow Solution Learn how to prevent coding mishaps by implementing a structured planning process before AI agents make changes to your codebase. compositecode.blog/2026/08/20/plan-…
compositecode.blog
Ask, Plan, Confirm: Making Agents Stop Before They Start
The scariest thing about a genuinely capable coding agent is how quickly it commits. You type two sentences, and forty seconds later there are changes across nine files, half of which you did not want and one of which quietly changed a query you spent a week hardening. The agent was not wrong about how to implement the thing. It was wrong about what the thing was, and it never stopped to check. I have watched this happen enough times that I stopped treating it as a prompting problem and started treating it as a workflow problem. A better one-shot prompt is not the fix. A gate is: the agent is not allowed to edit files until it has asked what it needs to ask, shown me a plan, and gotten a yes. ## Why speed is the problem Human engineers have a built-in pause. Before a senior developer touches your codebase they ask a couple of questions, sketch the approach, maybe drop a comment on the ticket. That pause is where the wrong-work gets caught, cheaply, in a sentence, instead of expensively, in a diff you have to read and reject. Agents removed the pause. That is most of their value and most of their danger in the same motion. An agent that implements immediately optimizes for the wrong thing: it treats “produce a diff” as the goal, when the goal was “produce the diff we agreed on.” The gap between those two is where the deleted work and the silent scope creep live. That gap is not a knowledge problem. The agent knows how to write the code. It just never checked that it was writing the right code. _The same task, gated and ungated. Skipping the pause trades a small, predictable cost for a large, unpredictable one._ So I gave the pause back, deliberately, as a standing instruction on every agent in the InterlinedList repo. ## The three beats The workflow is written down in `.claude/workflows/plan-first.md` and every agent links to it. It is three beats, in order, and implementation is gated behind all three. _The three beats, in order. Nothing is edited until all three pass, and work that grows past the approved plan loops back to re-plan rather than quietly expanding._ **Ask.** Surface what the prompt left open before committing to an approach. Ambiguous scope, unstated edge cases, a product decision hiding inside a technical request, whether a feature should be tier-gated. The migrations agent asks about column types and nullability and whether anything destructive is implied. The Next.js agent asks which surfaces are in and out. The rule has an escape hatch, because asking three questions about a one-line copy fix is its own kind of annoying: skip the questions only when the request is genuinely unambiguous and low-risk. When in doubt, ask. A pointed question is cheaper than a wrong build every single time. **Plan.** Before touching files, lay out the shape of the change: the files and routes and components you will touch, the ones you will deliberately leave alone, the approach, any migration (additive, always), the tests the change needs, and anything risky. In this repo “risky” has a specific meaning: auth, IDOR, subscription gating, SSRF, secret handling, anything destructive or hard to reverse. The plan is a decision aid, not a document. It should be short enough to read in one breath and specific enough that approving it means something. **Confirm.** Implement only after an explicit yes. If the plan changes in the back-and-forth, restate the revised version and get the yes again. And the part that actually matters over a long session: approval is scoped to the plan that was approved. If the work grows past it, the agent stops and re-plans instead of quietly expanding. That last clause is what keeps a “small fix” from turning into an afternoon of changes I never signed off on. ## What it looks like per agent I did not want one generic paragraph pasted eight times. The gate is the same, but what you ask about depends on the job, so each agent got the beats written for its lane. _One gate, written for each lane. The two read-only reviewers pick the full gate back up the moment they move from finding to fixing._ The **migrations** agent plans the exact idempotent `migration.sql` and confirms it is purely additive before it applies anything. The **unit-testing** agent asks which behaviors to lock in and which boundaries to mock, then lists the cases each test file will assert. The **e2e** agent names the flows, the auth and seed prerequisites, and the breakpoints that matter. The **docs** agent confirms which of the three docs is in scope and whether a new page is needed. The **blog** agent (yes, this one) settles the angle and the section arc and which real code it will verify claims against before drafting a word. The two read-only reviewers are the interesting edge. Security and UX do not implement, so there is no edit to gate. For them the gate degrades to its first beat: confirm the review scope if it is ambiguous (which routes, how deep, which breakpoints), then produce findings. But the moment the user says “now fix what you found,” they are implementers, and the full ask-plan-confirm gate snaps back on before they touch code. The reviewer does not get to slide from “here is a finding” into “and I fixed it” without crossing the same line everyone else crosses. ## The obvious objection This is slower. That is the point, and it is also not as true as it sounds. The plan step costs you a few seconds and one read. Rejecting a forty-second nine-file diff that went the wrong direction costs you the read plus the reject plus the re-prompt plus the nagging worry about what it touched that you did not catch. The gate front-loads a small, predictable cost to avoid a larger, unpredictable one. Over a day of handoffs it is not close. It also composes with the other habit I built into these agents: every one of them does its work in an isolated git worktree, on its own branch, torn down when the task lands. Plan first, then do the approved work in a sandbox that cannot collide with anyone else. The worktree contains the blast radius. The plan makes sure there is not supposed to be a blast in the first place. The pause was always the expensive part of good engineering. Worth teaching the machines to keep it. _I’mAdron, brainstorming and building InterlinedList._ ### Share this: * Share on X (Opens in new window) X * Share on Facebook (Opens in new window) Facebook * Share on LinkedIn (Opens in new window) LinkedIn * Share on Reddit (Opens in new window) Reddit * Share on Tumblr (Opens in new window) Tumblr * ### Like this: Like Loading…
010 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 25/08/2026
Considering where things are, know anybody working on a Github/heavy source management replacement? Ya know, something that is super lean? I'm switching up my architecture now for some projects but it seems like - as some have already pointed out - Github is just not really that reliable for […]
metalhead.club
Original post on metalhead.club
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 24/08/2026
A blur of train travel.
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 23/08/2026
Even wooden frames and more! 😃 🧵
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 23/08/2026
Drool. 🤤 🧵
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 21/08/2026
When multiple agents on a machine are running, do you use worktrees (like this compositecode.blog/2026/08/19/workt…) or do you use another method to split out your work? I've been pondering some new ideas, but wanted to ask the general community how you all are getting greater work […]
metalhead.club
Original post on metalhead.club
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 20/08/2026
Imagine you're starting work on an existing repo. It's been around for a while and has had a lot of people working in that repo over time. It takes a long - LONG - time to get up to speed on that repo. Let's say you point Claude or Cursor at it instead to get up to speed. But - and I'm […]
metalhead.club
Original post on metalhead.club
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 19/08/2026
Giving Every Agent Its Own Branch: Git Worktrees for Parallel AI Work To note, I've written this post and at this time... it's kind of a *halfway* solution and really only fixes part of the problems of multiple agents running on a singular machine workspace. Give it a read and I'll have some […]
metalhead.club
Original post on metalhead.club
010 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 19/08/2026
Did a reaction vid to this years ago too... youtu.be/9T1y-DNgYY0?si=IBf6oOxW5_4… metalhead.club/@thrashing/117119972…
metalhead.club
Adron's Metal Recommendation & Rambling (@thrashing@metalhead.club)
Here is Fervence's song that got me hooked. The Artistry here is some next level. Hezekiah https://youtu.be/H2yRAsmqgZc?si=Qc_qRMPN8ng8Ig4S
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 19/08/2026
A Research Agent on a Budget Leash, and How I’d Sequence the Whole Build compositecode.blog/2026/08/18/a-res…
compositecode.blog
A Research Agent on a Budget Leash, and How I’d Sequence the Whole Build
**Part 8 of 8: Durable AI for InterlinedList** * * * Back in Part 1, I said the whole series was one argument dressed up as eight posts. LLM tokens are the expensive thing, Temporal is not, and Temporal’s mechanics structurally push the token bill down. I also said the way I’d _build_ it was to brainstorm against the real code first, then hand the agent structure instead of hope. This is where those two threads tie together. The capstone I keep circling back to is the one that sounds the most like science fiction and is actually the most dangerous to ship carelessly: “research topic X from my saved links and draft a document with citations.” The agent retrieves. It reasons. It drafts. And if I’m not careful, it also burns through a month of my inference budget in one runaway loop while I’m asleep. So this post is two things. The agent itself, and the playbook for building everything that came before it. The agent is the thing you build last, and the order it sits on top of is the part I actually want to argue for. ## The Capstone Is Just the Earlier Pieces, Composed This part should feel earned by now. The agentic-research-to-draft phase, the last of the proposals, doesn’t invent anything. It _composes_. The link content from Part 5 (the crawl-and-cache that turns your saved URLs into readable text) is the agent’s source material. The retrieval from Part 5’s second half, the pgvector search over your own docs, lists, and messages, is how the agent finds the relevant three paragraphs instead of stuffing forty links into context. And the durable generation from Part 3, the workflow that survives a timeout and asks before it writes, is the drafting step. Compose those three and you get an agent loop: retrieve, reason, retrieve again, draft, cite. Each of those steps is already an activity I’d have built and tested for its own feature. The agent is a workflow that calls them in a loop the model steers. Which is exactly where it gets scary. A loop the _model_ steers has no natural stopping point. It’ll keep deciding it needs one more search, one more fetch, one more pass at the draft. That’s not a bug in the model. That’s what an agent _is_. The bug would be letting it run unsupervised. ## Temporal Supervising an LLM Agent Is a Nice Recursion I like this framing because it’s a little bit funny. Temporal is an orchestrator whose entire job is supervising unreliable, long-running, retry-heavy work. An LLM agent is unreliable, long-running, retry-heavy work. So the agent runs _inside_ a Temporal workflow, and the workflow is the adult in the room. Three guardrails, all first-class workflow logic, none of them prompt-hope: A **hard token budget.** Before every model call, the workflow calls `assertBudget`, the same primitive from Part 7 that reads the `AiGeneration` ledger and throws a non-retryable `BudgetExceeded` when the user’s daily or monthly ceiling is hit. The agent can _want_ another search all it likes. If the budget’s gone, the call never fires. A **max-step cap.** The loop counts its own iterations. Twelve steps, or whatever I tune it to, and it’s done. It drafts with what it has rather than spiraling. A **wall-clock timeout.** Temporal’s workflow timeout means even a wedged agent eventually stops, cleanly, with whatever it produced so far. And here’s the piece that makes the whole thing cost-sane instead of terrifying: **every step is memoized.** If the agent fails at step 9 of a 12-step loop (provider hiccup, worker restart, whatever) the workflow _resumes_ at step 9. It does not re-run steps 1 through 8. It does not re-pay for the eight model calls it already made. In a serverless handler, a mid-loop failure means starting the whole expensive agent over. Here it means retrying one step. Sketching the loop, this is the shape I’d hand Claude to fill in: // Proposed: the supervised agent loop as a Temporal workflow. export async function researchAgentWorkflow(input: ResearchInput): Promise<Draft> { const MAX_STEPS = 12; const context: Snippet[] = []; for (let step = 0; step < MAX_STEPS; step++) { // Governor first: a hard ceiling the agent cannot talk past. await assertBudget(input.userId); // Cheap model plans the next move over the small retrieved context. const move = await planNextStep({ model: "claude-haiku-4-5", goal: input.topic, context, }); if (move.type === "done") break; // Retrieval is mechanical and nearly free. No expensive tier here. const hits = await retrieveFromLinks(input.userId, move.query); context.push(...hits); // stays small: top-k snippets, not whole pages } // Expensive tier runs exactly once, on the final synthesis. return await draftWithCitations({ model: "claude-opus-4-8", topic: input.topic, context, }); } The cost story lives in the model choices, not the prose. Retrieval and planning run on a cheap tier: Haiku for the “what should I look for next” decisions, which are frequent and small. Opus 4.8, the expensive tier, runs once, on the final synthesis, over a retrieval-augmented context that stayed deliberately small the whole way through. I’m not paying Opus prices to decide which link to read next. I pay them for the draft, and that’s the one thing in the loop I think is worth it. No clever prompt is doing that. The structure is. ## How I’d Sequence the Whole Build If you’ve read the series straight through, you might be tempted to build the shiniest thing first. Don’t. The agent ships _last_ , and the ordering underneath it is the real deliverable of this post, because every step ships value on its own and nothing is a big-bang. Here’s the order I’d hand myself: **1. The foundation phase: the Temporal worker and the cost primitives.** The worker, the client wiring, the `llmCall` activity with the model cascade, `assertBudget`, the response cache. This is the groundwork everything else stands on, and nothing works without it. Mostly infra, not code, and it’s a week. **2. The durable publish and idempotency fix, pure win, no LLM.** This is the one from Part 4: the every-minute cron that can double-publish because a partial failure re-runs on the next tick. Rebuild it as a Temporal Schedule with the message id as the workflow id, so a given message can never be published twice. Zero model tokens. It fixes a _current_ production hazard. If I could only ship one thing from this whole series, it’d be this. **3. Durable Generate plus confirm.** Part 3. Long docs stop blowing the function budget, and a wrong list schema never gets silently written because the workflow pauses on a signal and waits for a human. This is the in-product generate button, on solid footing. **4. Link crawl, then retrieval.** Part 5. Crawl the links into a cache (the cheapest, highest-cache-value piece in the set) then layer pgvector retrieval on top. This is “where did I save that article?” **5. Batch enrichment, then prompt-to-list.** Part 6. The fan-out that tags everything and expands anything without re-billing completed calls, then the “build a list from a sentence” flow composed on top of it. **6. The AI calendar and digests.** Part 4’s second half. Now that publishing is durable, the calendar planner and the scheduled digests have solid ground to schedule onto. **7. The cost dashboard, then the agent.** Part 7’s dashboard makes “cheap” _visible_ : tokens, cache-hit rate, budget remaining. I want that governor on-screen _before_ I ship the most token-hungry feature in the whole set. Then, and only then, the agentic capstone. The rule underneath the whole ordering is that value ships at every step. The publish fix helps users who never touch AI. The link cache is useful before any retrieval sits on it. The dashboard is useful before the agent exists. I’m never in a state where I’ve spent three weeks and have nothing a user can hold. ## The Verification Is Where the Trust Actually Lives The meta-point of the whole series is this one, so I’ll say it flat. You do not trust an autonomous agent because the prompt was good. You trust it because it runs inside guardrails, and because tests prove the properties you care about are there. So the verification for the agentic capstone, and everything under it, is not an afterthought. It’s the thing that makes any of this shippable: **Vitest unit tests** for the activity logic and the cost math. Does the cascade pick the cheap model for planning? Does `assertBudget` throw at the right ledger sum? Pure functions, no DB, fast. **Temporal replay tests** that prove a workflow resumes correctly after a simulated worker crash. This is how I _prove_ , not hope, that a retry doesn’t restart the expensive agent from step zero. **An idempotency test** that starts two publish workflows with the same message id and asserts exactly one publish. That’s the double-post race, closed and locked. **Cost-assertion tests** , the ones I care about most for the agent. Fail an activity mid-pipeline and assert the already-completed model calls are _not_ re-invoked on retry. Memoization is money, and this test is how I know the money’s saved. **Playwright E2E** for the generate to confirm to write flow, so the human-in-the-loop gate works in a real browser and not just in my head. **A security pass** before any PR: SSRF on the crawler (everything through `safeFetch`), IDOR on every workflow write (`where: { id, userId }`), prompt-injection defaults (artifacts private by default so a poisoned link can’t publish on your behalf), and budget-bypass attempts. And every schema change (the `LinkContent` table, the pgvector column, the response cache) goes through the strict additive migration workflow. Hand-written, idempotent, applied to both databases. No `prisma db push`, no shortcuts. That workflow has broken production before, precisely when someone skipped it. ## What I Actually Learned Working With Claude The lesson closes the loop the series opened. Supervise the agent with structure, let the tests carry the trust, and it turns out that’s also how I’ve been building _with_ Claude the whole time. You don’t hand an agent a vague goal and hope. You hand it constraints: a budget it can’t exceed, a step count it can’t blow past, a timeout it can’t outlast. Then you make it write the tests that prove those constraints hold, the replay test, the idempotency test, the cost-assertion test. What makes the agent trustworthy is the wall around it, not how nicely I phrased the ask. And that’s true one level up too, which I didn’t expect going in. Sequencing the build so each step is independently verifiable (the publish fix before the calendar, the cache before retrieval, the dashboard before the agent) is the same move as capping the agent’s steps. Give the work boundaries, make the boundaries checkable, prove them before moving on. Whether the thing on the leash is a research agent or my own plan to build one, the leash is what I trust. I’ve been brainstorming this out loud for eight posts. The pieces are grounded in code that already exists: the `safeFetch` guards, the DSL, the crosspost fan-out, the cron that really does risk a double-post. None of it is shipped. All of it is buildable, in the order above, with value at every step. So I’m going to start at step one and build the durable publish fix, because it’s a pure win with no model tokens and it closes a real hazard. I’d love for you to follow along, as I am going to move forward now and implement this. If you’re interested, subscribe! _Adron brainstorming and working on InterlinedList._ ### Share this: * Share on X (Opens in new window) X * Share on Facebook (Opens in new window) Facebook * Share on LinkedIn (Opens in new window) LinkedIn * Share on Reddit (Opens in new window) Reddit * Share on Tumblr (Opens in new window) Tumblr * ### Like this: Like Loading…
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 19/08/2026
Cost-Effective AI Strategies for InterlinedList Development compositecode.blog/2026/08/17/makin…
compositecode.blog
Making LLM Features Cheap Enough to Actually Ship
**Part 7 of 8: Durable AI for InterlinedList** * * * Six posts in, and I’ve been dancing around a number. Every proposal I’ve sketched (durable generate, the calendar planner, the link crawler, batch enrichment) carries a cost, and the expensive part is never Temporal. It’s the tokens. A worker box and a managed Temporal namespace run me on the order of tens of dollars a month (obviously at this time), flat, whether they process ten jobs or ten thousand. The model bill is the one that scales with usage. _It’s also the one that decides whether an AI feature is worth shipping or is a slow-motion budget fire_. So this post is the payoff. Durability isn’t just nice, durability is _money_. The mechanics I keep reaching for aren’t in the plan because they’re clever. They’re there because each one structurally drives the token bill down, and does it in a way I can measure instead of squint at and hope for. Keeping this cheap relative to the Claude and ChatGPT APIs was never a footnote I tacked onto the series. It’s been the point the whole way through. None of this is live yet. AI assistance in the product is still marked Coming Soon. This is me brainstorming the cost layer I’d build, and how I’d hand it to Claude to build with me. ## The Single Biggest Saver Is Not Re-Paying for Work You Already Did Start with the one that matters most. Durable memoization. When a Temporal workflow runs an activity (say, an `llmCall` that generates a document section) the result gets persisted the moment it completes. If the workflow later fails and retries, it does not re-run that activity. It replays the history, sees the completed result, and moves on. Think about what that means on a six-step generation pipeline that dies at step five. Without durability, a retry starts over: steps one through four re-invoke the model, and you pay for all four again just to get back to where you already were. With Temporal, the retry re-runs step five and _only_ step five. Steps one through four are already-billed calls that never happen twice. That’s the difference between retries as a cost multiplier and retries that are free. On a batch enrichment job that fails at item 47 of 50, you re-bill item 47, not items 1 through 46. I wrote a whole post about that in Part 6, and it’s the same mechanic every proposal here leans on. Memoization is why a flaky provider or a worker restart doesn’t torch the budget. ## Cheapest Model First, Escalate Only on Demand The next lever is refusing to reach for the expensive tier by default. The `llmCall` activity would run a **model cascade** : cheapest capable tier first (Haiku-class, Flash-class), escalating only when the task actually needs it. Most of what these features do is mechanical. Tagging a message. Summarizing a row. Extracting a field. That work does not need a frontier model, and paying frontier rates for it is just lighting money on fire. So the cascade defaults to cheap, and it reserves the Opus-class tier for the thing the user explicitly asked for: long-form synthesis, a research draft, a document they told me they want written well. Paired with that: per-target `max_tokens` ceilings, so a runaway generation can’t balloon. A message caps around 1k, a list around 4k, a document around 16k. The ceiling isn’t a polite suggestion the model is vaguely aware of. The activity enforces it as a hard cap. So you get the cheap tier by default, a small ceiling per target, and the expensive model only shows up when you asked for it. ## A Gate That Throws Before It Spends Cascades and ceilings keep individual calls cheap. But the scenario that scares me is unbounded spend: a runaway agent loop, or a leaked user key someone else is now happily burning. So the plan puts a budget gate _before_ every call, not after. An `assertBudget` activity reads accumulated spend from the `AiGeneration` ledger and throws a **non-retryable** `BudgetExceeded` when the user is over their ceiling. Non-retryable is the important word. A normal failure retries; this one halts the workflow cold, because retrying a budget breach just tries again to spend money you’ve already said no to. Roughly what I’d hand to Claude as the shape: // activity: runs on the worker, before any billable llmCall export async function assertBudget(userId: string, estimate: TokenEstimate): Promise<void> { const spent = await getSpendThisPeriod(userId); // counts only, from AiGeneration const remaining = budgetFor(userId) - spent; if (estimate.maxTokens > remaining) { // non-retryable: a budget breach must not loop and re-attempt the spend throw ApplicationFailure.nonRetryable( `Budget exceeded: need ${estimate.maxTokens}, have ${remaining}`, "BudgetExceeded", ); } } A workflow calls `assertBudget` and then `llmCall`, in that order, every time. Worst case is a bounded overspend of one call, never an open tap. ## Never Bill the Same Request Twice Then there’s the plain-dumb-obvious saver: caching. A response cache keyed by `hash(system + prompt + model)`. If an identical request comes through (same system prompt, same user prompt, same model) it’s served from cache and never re-billed. Regenerate the same summary twice, pay once. Same idea one layer down for link work: URL-hash dedup. When the crawler from Part 5 fetches and embeds a link, it keys on a hash of the URL. A link shared across ten messages, three docs, and a list row gets fetched, extracted, and embedded exactly once, ever. Embeddings are already orders of magnitude cheaper than generation, so computing them once and caching forever makes the cheapest part of the pipeline round down to nothing. And to keep from wasting tokens on _retries you caused yourself_ : worker concurrency and task-queue rate caps tuned to stay under provider limits. Blow past a rate limit and you get a 429 storm, and every retry in that storm is wall-clock and, on some providers, tokens down the drain. Obeying the limit is cheaper than fighting it. One more, because it’s the most satisfying: confirm-before-spend. For the prompt-to-list flow, the workflow generates the schema, then pauses on a Signal and waits. It does not spend a single row-generation token until the user confirms the schema is right. Get the schema wrong and you’ve spent one cheap schema call, not fifty row calls against a shape nobody wanted. That pause is impossible in a serverless handler and native in Temporal. ## The Ledger Counts, It Doesn’t Read Every one of these levers needs a source of truth, and that’s the `AiGeneration` ledger. Critical design decision: it records **counts and status only**. Tokens in, tokens out, which model, succeeded or failed. It never stores the prompt text or the model output. That’s not laziness. One table does three jobs. Privacy, because I’m not warehousing what people wrote or what the model said back. The quota counter, because `assertBudget` reads its sums off it. And the cost dashboard, because those same rows drive a per-user “AI usage and spend” view: tokens, calls, cache-hit rate, budget remaining. When something looks expensive, the ledger doubles as the debugging trail. You can see _that_ a workflow made forty calls without ever seeing _what_ it said. ## Build the Guardrails With Claude, Then Make It Prove Them Now the part I’ve been wanting to get to, because this is where working with an LLM changed how I’d approach any of it. Memoization and caching only save money if they’re in the _right places_. Put a cache breakpoint one step too early and you re-bill everything after it. Miss a memoization boundary and a retry quietly re-runs a paid call. The savings are entirely a function of where the boundaries land, and eyeballing a six-step pipeline for those boundaries is the kind of thing I get wrong. So the first move is a diagnostic question, not a code request. I’d point Claude at the actual workflow and ask: _“walk this pipeline and tell me exactly where a retry would re-bill the model.”_ Then let its answer drive placement. It reads the activity boundaries, traces the retry path, and tells me which calls are already durably memoized and which ones a mid-pipeline failure would re-invoke. That answer is the map. The caching and memoization go where the map says, not where I guessed. The second move matters more: make it prove the savings. Memoization you can’t prove is just a hope with good intentions. So I’d have Claude write a Temporal replay test (using `TestWorkflowEnvironment`) that fails an activity partway through the pipeline and then _asserts the already-completed LLM activities are not invoked again on retry_. it("does not re-bill completed LLM activities on retry", async () => { const llmCall = vi.fn() .mockResolvedValueOnce("step-1 result") .mockResolvedValueOnce("step-2 result") .mockRejectedValueOnce(new Error("provider blip at step 3")) // fail mid-pipeline .mockResolvedValue("step-3 result (retry)"); await worker.runUntil(client.workflow.execute(generatePipeline, { /* ... */ })); // steps 1 and 2 completed before the failure, so Temporal replays their // memoized results and MUST NOT call the model for them again. const stepsCalled = llmCall.mock.calls.map((c) => c[0].step); expect(stepsCalled.filter((s) => s === 1)).toHaveLength(1); expect(stepsCalled.filter((s) => s === 2)).toHaveLength(1); expect(stepsCalled.filter((s) => s === 3)).toHaveLength(2); // failed once, retried }); That test is the proof. It fails loudly the day someone refactors the pipeline in a way that breaks memoization and starts silently re-billing steps one and two. The savings stop being a story I tell about the architecture and start being a property CI enforces. Same loop for the response cache: a test that fires two identical requests and asserts the second one hits cache and never reaches the model. Ask the agent where the money leaks. Let its answer place the guardrails. Then make it write the test that locks them in. That loop works because a cost regression is invisible until the bill shows up weeks later, and a test drags it into the light on the exact commit that caused it, while you can still `git blame` your way back to it. ## Where This Lands Part 8 is the capstone: the agentic research-to-draft flow, the single most token-hungry thing in the whole set. It’s the reason every governor in this post has to exist before it ships. I’ll also lay out how I’d sequence the entire build, starting from the foundation phase (the Temporal wiring and the shared cost primitives everything else reuses) and working all the way up to the agent, and how I’d verify each piece as it lands. _Adron brainstorming and working on InterlinedList._ ### Share this: * Share on X (Opens in new window) X * Share on Facebook (Opens in new window) Facebook * Share on LinkedIn (Opens in new window) LinkedIn * Share on Reddit (Opens in new window) Reddit * Share on Tumblr (Opens in new window) Tumblr * ### Like this: Like Loading…
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 18/08/2026
A specifically interesting one! Trees on a tree stump in case you like trees on tree stumps!
000 0
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 18/08/2026
Some shots from a walk about (some people call em’ hikes) out to Franklin Falls. 🧵
100 1
Adron 🤘🏻 @adron.metalhead.club.ap.brid.gy · 18/08/2026
Just ole’ Seattle being beautiful in the sunlight!
000 0