<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>ai.bjg.llc — AI notebook</title><description>The working notebook of BJGLLC — how a one-person practice runs on AI agents. Field notes, overnight runs, and receipts.</description><link>https://ai.bjg.llc/</link><language>en-us</language><item><title>16 tasks, 47 subagents, zero humans: the overnight build</title><link>https://ai.bjg.llc/writing/the-overnight-build/</link><guid isPermaLink="true">https://ai.bjg.llc/writing/the-overnight-build/</guid><description>A 16-task plan, 47 subagents, and two models from two vendors adversarially reviewing each other overnight — what the structure caught while I slept.</description><pubDate>Sat, 18 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;At 1:03am on July 18 I started a Claude Code session inside herdr, pointed it at a 16-task implementation plan, and went to bed. At 9:36am the plugin was live on my machine: a daemon sweeping my real fleet under systemd, a working board TUI, 118 passing tests, 58 commits, and a review log showing roughly 70 findings caught and resolved while I slept. Every one of the 16 tasks shipped.&lt;/p&gt;
&lt;p&gt;I want to write down how, because the interesting part isn&apos;t that agents can write code overnight. Everyone knows that by now. The interesting part is the structure that let them do it without me, and what that structure caught.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;16&lt;/strong&gt; Tasks planned — all 16 shipped&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;47&lt;/strong&gt; Subagents dispatched — implement · review · fix · re-review&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;118&lt;/strong&gt; Tests passing — by morning&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;~70&lt;/strong&gt; Review findings — fixed or dismissed with reasons&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;The mission doc&lt;/h2&gt;
&lt;p&gt;You don&apos;t hand an agent eight unsupervised hours with vibes. The kickoff was a one-page mission doc that Claude and I wrote together before I went to bed, and in hindsight every paragraph of it earned its place.&lt;/p&gt;
&lt;p&gt;It named the source of truth: a 16-task plan, reviewed and approved in advance, copied into the repo as its first commit. It pre-granted the plan&apos;s checkpoints, the specific spots where the plan said &quot;stop and ask Blake,&quot; each with its own conditions, because I wouldn&apos;t be there to ask. It set standing rails that no grant could override: no deletes, ever, stage removals into a folder instead; never force-push; never touch main of any repo except the new one; no secrets outside the password manager; subscription-lane model calls only. And it set a blocker policy: three genuinely different attempts on a stuck task, then write the full state to a blockers file, commit it, and move on to the next task that doesn&apos;t depend on it. Never wait for a human who isn&apos;t coming.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A subagent saying &quot;done&quot; counts for nothing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The doc also encoded distrust, which is the part I&apos;d underline. Every task&apos;s completion had to be verified by the orchestrator against the plan&apos;s acceptance criteria. A subagent saying &quot;done&quot; counts for nothing.&lt;/p&gt;
&lt;h2&gt;The shape of the night&lt;/h2&gt;
&lt;p&gt;The orchestrator ran subagent-driven development: a fresh subagent per task, so no task inherits the previous task&apos;s context rot. Over the night it dispatched 47 of them. The rhythm for each task was implement, review, fix, re-review, and the dispatch log reads like a wave pattern: &quot;Implement Task 5: scrape floor.&quot; &quot;Review Task 5.&quot; &quot;Fix Task 5 findings.&quot; &quot;Re-review Task 5 fix.&quot;&lt;/p&gt;
&lt;p&gt;Model routing followed a rule from my global setup: cheaper models for mechanical work, the expensive one only where judgment matters. Most implementation dispatches ran on Sonnet. The reviews of the trickiest tasks, the event reducer and the daemon, ran on Opus. The whole night cost about 1.37 million output tokens on a subscription plan. I&apos;ve had cheaper nights of sleep, but not many more productive ones.&lt;/p&gt;
&lt;p&gt;Then there&apos;s my favorite structural detail: the second reviewer wasn&apos;t Claude at all. In a sibling herdr pane, a Codex CLI session sat as an independent review gate. After each task passed its own tests, the orchestrator messaged the Codex pane with the commit range, and Codex reviewed the diff cold: re-running the test suite itself, probing edge cases, checking the work against the plan text. Two different models from two different vendors, adversarially reviewing the same diff, coordinated through a terminal multiplexer. The mission doc had specced a simpler review lane; we upgraded it to the live sibling-pane arrangement right before I went to bed, and it turned out to be the best decision of the night.&lt;/p&gt;
&lt;h2&gt;What the gates actually caught&lt;/h2&gt;
&lt;p&gt;The review log is the artifact I&apos;d show a skeptic — though for now it lives in a private archive with the raw transcripts, so what follows is my summary of it, and you&apos;re right to discount what you can&apos;t inspect. Publishing redacted excerpts is an open decision on my list. Roughly 70 findings across the night, every one either fixed with a commit reference or dismissed with a written reason. A sample:&lt;/p&gt;
&lt;p&gt;The append-only feed had a rotation bug where two rotations in the same second would silently destroy an archive. That&apos;s the exact invariant the whole design rests on, replayability, and it was in code copied verbatim from the approved plan. Codex reproduced the history loss and it was fixed with microsecond-precision naming and a regression test.&lt;/p&gt;
&lt;p&gt;The herdr CLI wrapper assumed pane reads returned JSON. On the live system they return plain text. The entire scrape path, the floor the product stands on, was dead on arrival, and no planned test covered it. Caught because the reviewer ran against the real fleet instead of trusting the mocks.&lt;/p&gt;
&lt;p&gt;The board&apos;s headline feature, pressing enter to jump to an item&apos;s source pane, was unreachable: a widget&apos;s built-in binding shadowed the app-level one. Severity Critical, found by an automated UI test the reviewer wrote, fixed, then verified with a real keypress moving real focus.&lt;/p&gt;
&lt;p&gt;A worker subagent deserves its own mention. Its instructions said to implement the plan verbatim and never deviate silently. Partway through, the plan&apos;s own regex fixture failed: the plan had a subtle owner-classification bug in it. The worker stopped and flagged BLOCKED rather than quietly patching around it, the coordinator confirmed the plan itself was wrong, authorized a one-line deviation, and logged it. That&apos;s the discipline I most doubted an agent chain could hold overnight, and it held.&lt;/p&gt;
&lt;p&gt;There&apos;s an honest lesson in the log too: three findings in the daemon&apos;s later review rounds were introduced by earlier review fixes. Reviews generate code, code carries risk. The cross-reviewer setup caught each one within a round, but &quot;the fix broke something adjacent&quot; doesn&apos;t stop being true just because everyone involved is a model.&lt;/p&gt;
&lt;h2&gt;What didn&apos;t work&lt;/h2&gt;
&lt;p&gt;The night hit real walls, and the blocker policy handled them the way it was written. The Claude Code Stop hook, one of the two hooks that let sessions self-report, never fired on this machine. Three distinct diagnostic approaches, all documented, all ruled out the script itself; the trail went into a blockers file with a note that impact is low because the scrape floor exists precisely to cover sessions that don&apos;t self-report. The phone-push lane assumed a CLI verb that turned out not to exist, so the daemon shipped with a desktop-notification interim and the phone decision was left in my court. And the daemon spent part of the night sweeping my main fleet instead of the build sandbox, which sounds like a bug until you realize the env-less binary binds the default herdr instance. The main fleet is the actual product target; the behavior was kept and documented.&lt;/p&gt;
&lt;p&gt;I woke up to all of this already triaged: Linear tickets moved with commit SHAs in the comments, a project status update posted, and a morning-reads list of exactly the decisions that needed a human.&lt;/p&gt;
&lt;h2&gt;The epilogue the roadmap wrote itself&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Dogfood day one&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;My palm brushed my new keyboard and acked nine items off the board. Because every ack is just an appended event and nothing ever rewrites history, recovery was clean: append one snooze event per victim with a wake time already in the past, and the reducer flipped each item back to exactly its prior state. My favorite bug report I&apos;ve ever filed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The palm also exposed a genuine gap, no undo and no archive view, which became the project&apos;s first post-launch ticket within ten minutes.&lt;/p&gt;
&lt;p&gt;That loop, from accident to recovery to roadmap item, ran on the same append-only design the agents had spent the night defending against each other. I went to bed with a spec and woke up with a product that could already survive my keyboard. We&apos;re on the dogfood clock now; when the seven days are up, muster goes public.&lt;/p&gt;
</content:encoded><category>muster</category><category>agents</category><category>code-review</category><category>herdr</category></item><item><title>Private-first, public-shaped: designing our first public product</title><link>https://ai.bjg.llc/writing/private-first-public-shaped/</link><guid isPermaLink="true">https://ai.bjg.llc/writing/private-first-public-shaped/</guid><description>Two days between a manual fleet sweep and a buildable spec: the market check, the four design decisions that mattered, and the dogfood gate behind muster.</description><pubDate>Sat, 18 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The last post ended with a manual experiment: Claude sweeping sixteen live agent sessions and handing me one owner-tagged list of everything waiting on someone. This post is about the two days between that sweep and a buildable spec, because the decisions made in those two days are the reason the thing exists as a product and not another private script in my dotfiles.&lt;/p&gt;
&lt;h2&gt;The decision to go public at all&lt;/h2&gt;
&lt;p&gt;My ecosystem is full of internal tooling. Skills, hooks, daemons, sync machinery. None of it is published, and that&apos;s deliberate; most of it is shaped like me. The fleet sweep felt different for one reason: the problem isn&apos;t shaped like me. Anyone running multiple agent sessions has follow-ups rotting in scrollback. The herd is getting bigger everywhere.&lt;/p&gt;
&lt;p&gt;So the first move after the sweep wasn&apos;t code, it was a market check. We swept the herdr plugin marketplace for prior art. A PR tracker validated the poll-and-scrape pattern. A telemetry bridge validated the append-only feed shape. A todo plugin handled capture, but in-session and single-session only. A status pane showed which agents were alive but nothing about what they were carrying. Nothing did fleet-wide follow-up extraction. The niche was open, and adjacent plugins had already proven every mechanism we&apos;d need. That&apos;s about as inviting as a market check gets.&lt;/p&gt;
&lt;p&gt;The posture we settled on has a name I keep reusing: private-first, public-shaped. The repo was born with a plugin manifest, a real README, MIT license, and secret scanning wired in, exactly as if it were public. But it stays private until it survives at least seven consecutive days of real use on my own fleet. The publish step is a gate with written criteria, not a mood. If it can&apos;t survive my own daily use for a week, nobody else should be running it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The name&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;And the name: muster. Claude coined it during the greenlight session and I ratified it the next day. Mustering is gathering the herd; a muster is also the roll-call report. For a plugin that gathers herdr sessions and reports who&apos;s waiting on whom, I have yet to find a word that works harder.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;The design session&lt;/h2&gt;
&lt;p&gt;The spec came out of a brainstorming session the next evening, and I can compress it to the four decisions that mattered.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;4&lt;/strong&gt; Decisions that mattered — out of a full design evening&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;0&lt;/strong&gt; LLM calls required — the floor is deterministic&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;7days&lt;/strong&gt; Dogfood gate — before anyone else runs it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;An event log is the only source of truth.&lt;/strong&gt; Every capture, every ack, every snooze is one appended line of NDJSON. A reducer folds the log into the current board state, and that derived file is disposable: delete it and it rebuilds from the log. Nothing ever mutates state directly, including me. When I dismiss an item, that&apos;s just another event, stamped as human. This one decision quietly bought us most of the product: the board, replay-based testing, an audit trail, and safe recovery from mistakes. It also cost us something real, and a later post about our first dogfood day covers the accidental-ack story that exposed the tradeoff.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The floor must work with no LLM and no cooperation.&lt;/strong&gt; This is the decision I&apos;d defend hardest. Capture is tiered. Sessions that cooperate can self-report through a hook, which is the highest-trust lane. But the floor underneath is a deterministic parser over pane scrollback: no model calls, no API keys, no requirement that a session do anything at all. A public plugin cannot assume its users have a frontier model on tap, and a follow-up tracker that silently misses sessions is worse than none. The optional model-assisted lane exists in the design, off by default. The floor is the product; everything above it is enrichment.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The feed is the truth; Todoist gets a photograph of it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;One feed, many sinks.&lt;/strong&gt; The feed doesn&apos;t care who consumes it. The herdr sidebar shows each session&apos;s headline: owner tag, open count, top item. A board TUI shows the full fleet list, grouped by court, and enter jumps you to the source pane. A notify hook pushes to whatever you wire it to. And Todoist gets snapshots on demand, never a live mirror. That last clause is a scar from years of tool-sync pain: two systems that both claim to be current are a lie waiting to happen. The feed is the truth; Todoist gets a photograph of it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Trust is a document, not a vibe.&lt;/strong&gt; A plugin that reads your terminal scrollback deserves suspicion. So the repo — still private until the gate clears — carries a TRUST.md that states exactly what muster reads, what it writes, and what it never does, including the unflattering parts: captured text is stored verbatim, so if a secret is on your screen it&apos;s in the feed. No network calls of its own. No LLM calls, period, until you explicitly opt in to a lane that doesn&apos;t ship yet. Writing the limits down honestly felt like the price of asking strangers to run this next to their work.&lt;/p&gt;
&lt;h2&gt;Success criteria, in advance&lt;/h2&gt;
&lt;p&gt;The spec closes with the test the product has to pass, written before any code existed: the sidebar shows per-session state with zero manual effort; the board answers &quot;what&apos;s waiting on whom&quot; fleet-wide in under five seconds; the phone buzzes on exactly three classes of event and never repeats itself; the floor works with zero LLM configured; and it publishes only after the seven-day dogfood gate.&lt;/p&gt;
&lt;p&gt;Writing that list before building turned out to matter more than I expected, because the build didn&apos;t happen the way builds normally happen. Sixteen tasks, a plan on disk, and a decision that felt slightly reckless at 1am: let the agents build the whole thing overnight while I slept. That&apos;s the next post.&lt;/p&gt;
</content:encoded><category>muster</category><category>product-design</category><category>herdr</category><category>agents</category></item><item><title>The task manager didn&apos;t fail. The task shape changed.</title><link>https://ai.bjg.llc/writing/the-task-shape-changed/</link><guid isPermaLink="true">https://ai.bjg.llc/writing/the-task-shape-changed/</guid><description>Agents invented a category of task that Todoist and Linear had no place for. The story of the gap, the manual sweep that named it, and the layer that grew underneath the stack.</description><pubDate>Sat, 18 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve been a personal knowledge management person for a long time. Todoist for tasks, Obsidian for notes, and eventually Linear for project work. That stack survived a lot: an agency, a DTC company, a day job, a moonlight CMO gig. It did not survive AI agents. Not because any tool broke, but because agents invented a category of task that none of them had a place for.&lt;/p&gt;
&lt;p&gt;Here&apos;s the short history, because the dead ends are the interesting part.&lt;/p&gt;
&lt;h2&gt;Round one: trying to leave Todoist&lt;/h2&gt;
&lt;p&gt;In June 2026 I exported everything out of Todoist and left. The logic felt clean at the time: Linear had become the system of record for anything project-shaped, and Apple Reminders could catch the personal residue, groceries and calls and errands. Two lanes, no overlap.&lt;/p&gt;
&lt;p&gt;Linear earned its half of that split. We run a rule in my setup that sounds simple and is actually load-bearing: Linear must always mirror the true state of the work. A ticket says In Progress only if the work is actually in progress. It goes to Done only after someone verifies the acceptance criteria against ground truth, not against a subagent claiming victory. Every ticket carries a surface code so a glance tells you which part of the ecosystem it touches. When AI does most of the executing, that glanceability is the whole game. I stopped reading commit logs to know where things stood. I read the board.&lt;/p&gt;
&lt;p&gt;Apple Reminders did not earn its half. A month later, in mid-July, Todoist came back as the personal task layer. My own note on that decision reads &quot;back, with a vengeance,&quot; which tells you how the experiment went. Some tools are good at being ambient. Reminders wasn&apos;t.&lt;/p&gt;
&lt;p&gt;So by July 2026 the stack was settled again: Todoist for my life, Linear for the work. Which is exactly when the real gap showed up, and it wasn&apos;t in either tool.&lt;/p&gt;
&lt;h2&gt;The thing neither tool could see&lt;/h2&gt;
&lt;p&gt;By then, my working day didn&apos;t look like a person using a computer. It looked like a fleet. I run herdr, a terminal multiplexer built for agent sessions, and on a normal day it holds a dozen or more live panes: Claude Code sessions building features, a Codex session reviewing them, long-running daemons, one-off experiments. Each session is competent on its own. Each one also, constantly, generates a very specific kind of item:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What agents generate&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&quot;I drafted the DECISIONS.md entry, awaiting your nod.&quot;
&quot;Blocked: waiting on your permission for this command.&quot;
&quot;You typed a prompt here four hours ago and never hit enter.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;None of these are tasks in the Todoist sense. I didn&apos;t create them and most die within the hour. They aren&apos;t tickets in the Linear sense either; there&apos;s no project, no acceptance criteria, just a small dangling thread with an owner. Some are in my court, some the agent could resolve itself if nudged, and some are pure hygiene, like the unsubmitted prompt.&lt;/p&gt;
&lt;p&gt;Individually, trivial. Across sixteen sessions, they compound into a real problem. Work stalls silently. An agent finishes something at 2pm and waits, politely, forever. A one-keystroke approval sits behind a pane I haven&apos;t looked at since morning. The cost isn&apos;t the size of any item; it&apos;s that no surface in my stack showed them together.&lt;/p&gt;
&lt;h2&gt;The sweep that named the problem&lt;/h2&gt;
&lt;p&gt;On July 16 I asked Claude to do it manually: read the scrollback of every live herdr session, all sixteen, and pull out the follow-ups, tagged by owner. Things in my court. Things an agent could execute. Pane hygiene. Then push the whole thing into a Todoist project as a structured hierarchy so I could work it like a checklist.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;16&lt;/strong&gt; Sessions swept — every live pane, read in full&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;3&lt;/strong&gt; Owner courts — mine · agent&apos;s · hygiene&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1afternoon&lt;/strong&gt; To clear the backlog — after days of silent rot&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It took a while. It was also, and I said this out loud at the time, the single most helpful thing we&apos;d done in a while. Sixteen sessions of ambient obligation collapsed into one owner-tagged list. I cleared in an afternoon what had been quietly rotting for days. Half the items I didn&apos;t even remember owning.&lt;/p&gt;
&lt;p&gt;Two things clicked after that sweep.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The follow-up feed isn&apos;t a task list or a ticket queue. It&apos;s telemetry with owners.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;First, Todoist and Linear were never going to grow this feature, and shouldn&apos;t. The follow-up feed isn&apos;t a task list or a ticket queue. It&apos;s telemetry with owners: born from session scrollback, resolved by sessions moving on, only occasionally graduating into a real task or ticket. It needed to be captured where it lives, at the terminal.&lt;/p&gt;
&lt;p&gt;Second, a manual sweep is a proof, not a product. It&apos;s only true for the minute it runs, and it costs a full agent pass every time. What I actually wanted was the sweep running continuously: a glance at the sidebar telling me what&apos;s in whose court across the fleet, a board one keybind away, my phone buzzing only when something genuinely needs me.&lt;/p&gt;
&lt;p&gt;That&apos;s the thing we ended up building, a herdr plugin called muster. The name is the pitch: mustering is what you do to a herd, and a muster is a roll call. Gather everyone, find out who&apos;s waiting on whom.&lt;/p&gt;
&lt;p&gt;The stack didn&apos;t get replaced this time. Todoist still holds my life and Linear still mirrors the work. What changed is that a third layer grew underneath them, for the class of task that agents create: small, perishable, owner-tagged, and previously invisible. How we designed that layer, and why we decided to make it our first public product, is the next post.&lt;/p&gt;
</content:encoded><category>muster</category><category>herdr</category><category>agents</category><category>task-management</category></item></channel></rss>