This is how I work with agents: lineage trees, rules and building by talking
WORKFLOWRepeatable working flow.VOICEVoice-driven production.LINEAGEParent/child/relation lineage is required.AI-DEVELOPMENTAI development practice.
I want to show my own way of working. Everything on this page came out of roughly thirty minutes of live talking: I spoke while looking at my screen, copied and marked what I saw as I spoke, then pasted the whole talk into a fresh agent. This content itself was written by that agent — but from my speech.
This image shows one day's construction-site summary; the staged and changes counters in the Source Control panel were marked during the talk.
My usual loop is this: I look at what the agent wrote and I stage it. I do not commit — committing slows me down because I work with too many agents. I spin up commit agents instead; they commit what I staged, following my commit rules. I do not obsess over the staged and test counts, because I almost never go backwards; everything that happened only moved forward. I work forward-focused.
Refactor mode. I use Ghostty and right now I am in refactor mode. The systems are already built; everything I built is here, one agent per tab.
This image shows the agent tabs inside the Ghostty terminal; every tab is a refactor agent working autonomously inside its own responsibility area.
The energy cycle. While I have energy I build whatever I can. Even if it is broken, I try to turn everything in my head into something concrete — software, a working product — as fast as possible. When my energy runs out, and that burnout usually comes from working too much, my mind stays light: I want to work less, I feel like tidying the house. In that window I hand all the agents the work I call lineage trees. The theory in one line: while awake I push for growth, while asleep I focus on resilience. While I rest, the system should rest and be protected too.
What is a lineage tree? I try to map every project's dependency chain all the way down. I distribute files, split them, break them apart; at worst I end up with small files. What I mean by lineage is this: what breaks if I delete this? If deleting it breaks the system, it comes from the same lineage — there must be a dependency. If deleting it does not break the system, there must be no dependency. If I build this really well — and that is very hard — no agent ever collides with another, because none of them even touch each other. Even if the code, the core, the project are the same, collision becomes impossible. In theory this is very hard; as you keep developing you have to keep updating it. But past a certain ratio I can drive it verbally — and that is exactly what I am doing with the agents right now.
The refactor brief I give the agents. Every agent works autonomously; I give the rules and the brief up front. The essence of my refactor brief is the following — adapt it to your own project.
Redesign along the lineage. Redesign and split the system to match its lineage graphs; create packages when needed. Fix a system with the wrong lineage like a virus; lineage membership is measured with a delete-and-survive test — at runtime, not at build.
Build runtime visibility. Add dispatch tables and logs for accountability; every background job must leave a trace.
Remove impossible states. Use switch cases and discriminated unions when needed; but if there is no impossible state, do not touch it — never add them for their own sake.
Never give one duty to two owners. Design authorities and assigned duties along the lineage too; independently working actors must not live in the same lineage or the same files.
No build edge without a runtime edge. Split code and extract packages when needed.
Watch the boundaries between apps. A job used by two apps must not run in both; build a headless service if needed. Do not open user-visible surfaces for background jobs; if something has no reason to live on its own, do not define it as an app — let it close natively when it has no parent, and never allow duplicates.
Every user action must be accountable. Map the lineage of limited user actions too: permissions, storage, hotkeys. Even when the system works in the background it must talk to the user — through predefined rules for animation, motion, placeholders and sound.
No magic strings. Values that change with the machine or language must be manageable and visible in code.
Prefer native. But if a custom solution needs no maintenance and is much lighter, you may choose custom; the critical bar is being deterministic with zero false positives. If custom cannot guarantee that, delegate to native and drop the maintenance burden.
Remember you are on a construction site. Do not touch other agents' scopes. And no legacy support: cut over, leave no trace; the old path is deleted only after the behavior has been re-measured at runtime in the new lineage.
My rules are philosophical, not implementational. I already have my agent files — the AGENTS.md file. I also keep my own rules files. They are the singular rules I discovered while building the systems: the ones I tried and that worked are recorded — not the ones that failed. And they are not implementation rules, because those already live in the codebase; I did not write them down. My filter before writing any rule: without this rule, would the system definitely, absolutely be built broken? If yes, it can be a rule — and it must not be written in code. If it exists in code it cannot be built broken anyway; the compiler warns us and we fix it. So what remains are philosophical, principle-like rules. For example: if the system does something in the background it absolutely must show it to the user — and the way to show it must not be text, because text forces people to think; we have to use animation, motion or images. That is a principle rule. I try a rule like that in five places; once it works, I put it in its proper home. My rule-creation rule is also in the prompt — I am telling you this deliberately; so is the rule-reading rule. This is how rules accumulate inside the system.
A few rule examples — from the ones living in the system with the tried-and-required tag: [#agent:visibility-lifecycle-ancestor] visibility is the lifecycle ancestor of every below-surface job; when a panel hides, everything under it — render, disk IO, playback, timers — dies together with the visibility. [#agent:authority-read-order] a trimmable preview never counts as truth; the read order is durable authority first, projection only in its absence. [#agent:emit-refresh-edge] if a signal updates state, the consumer also gets a subscription to that signal; the root of the "event is logged but the UI does not update" class is the missing edge. [#agent:diff-field-completeness] a change-detection comparison must carry every decision-changing field; a missing field silently swallows the change in that field. [#agent:parallel-writer-discipline] concurrent writers in the same working tree keep edits small and regional; when a conflict zone appears, the other writer gets one boundary message — nobody silently fixes someone else's half-done work. The tokens in those headings are the anchors I will explain in a moment. That is my rule language: tagging, plus markers that say a rule has been tried. The tried part was actually for myself at first; but I noticed the agent reacts to it directly when it reads them — it says "you tried this and it is a required rule, we should do it." So I started giving it to the agents too.
The infrastructure took a year. The infrastructure is broad enough that I can actually do all this. I have about a year of work with AI — at least that is how I counted it with Claude Code; call it an intensive year with Claude Code. The last seven or eight months of it went into a Mac app I keep refactoring. I rewrote it from scratch again and again just to understand the rules.
Responsibility areas and the construction site. I give each agent a responsibility area: dictation, clipboard — a specific territory. While they run, problems come to my mind. Real example: say I hit a clipboard problem. I throw it at both agents I suspect — dictation and clipboard — because it is shared code. I say: "If this is in your scope we solve it, otherwise I hand it over; if it is not yours, keep working and report." The answers come back: clipboard says "this is my scope, I should fix it"; dictation says "not my scope, give it to clipboard." I manage that conversation myself, because agents erase too much context when they talk to each other and drift on long jobs. Since I hold the context, I can do the coordination. I also stumbled on the phrase construction site — I noticed it while working with Claude Fable. When I give agents that phrase, they can infer that other agents are working too. But it is not a magic word that changes everything; behind it there is a whole rule mechanism and rule documents about how agents must work with each other.
166 rule files. I have quite a lot of rule documents and I try to keep them in the universal-rules band. To give you a feel for the naming logic, here is a slice of the titles — not the contents; I want to show the quantity and the naming: action.policy.effect-preview.rules.md · adr.rules.md · agent.contract.attention-index.rules.md · agent.skill.closure.rules.md · carrier-generalization.rules.md · clipboard-app.rules.md · compose.contract.timeline-authority.rules.md · dictation.policy.hud-surface.rules.md · file.contract.filename-axis-grammar.rules.md · graph.contract.lineage-closed-universe.rules.md · hooks.contract.visible-output.rules.md · hotkey.rules.md · information.rules.md · markdown.contract.claim-status-grammar.rules.md · package.rules.md · preflight.rules.md · problem-solving.algorithm.structural-analogy.rules.md · runtime-proof.rules.md · security.macos.rules.md · service.contract.headless-lifecycle.rules.md · swift.contract.main-thread-dispatch.rules.md · term.registry.user-alias.rules.md · ui.contract.animation-motion.rules.md · whisper.policy.decoder-term-prompt.rules.md — and more; 166 files in total. Each one is indexed into the others.
Anchors. The index mechanism runs on anchors I put into Markdown headings: tokens like [#signal-carrier:local-preflight-name] or [#lineage-universe:edge-rule] — the first one, for example, comes from my preflight file; what I am trying to show is the relation these pieces have to each other. Though I do not put the # marker on quick commands — only on the non-quick rules. Every rule links to other rules, and inside one rule you call another; when agents read a rule they read the related rule too. I first tried this with the file system and noticed they did not always read it; also too many unrelated rules leaked into the context. Claude especially does not read them — its own harness prompts are heavier, so it follows my prompts less; Codex is a lighter terminal tool, so it follows the rules. That is an observation of mine. So instead of making agents read rule files, I give them my own rule mechanism:
This image shows a real invocation of the cos anchor command; the consumer, session and anchor arguments were marked one by one during the talk.
The logic here is the same as the lineage trees: every rule is bound to other rules, and I keep re-indexing the bound rules with agents — which rule depends on which, what relation exists between them. That produces a rule tree. When a rule is called, this command returns its entire downstream lineage; not upward — the children and grandchildren. This is how I make sure the agents receive the rules correctly. This cos command is one of my most critical commands — my non-negotiable system command.
Agent telemetry. Think of human analytics: we collect what the user clicked. I do the same for agents. Which agent used which rule, is the relation between rules built correctly — another agent audits this and updates the lineage; rules that keep being called without a real relation get found and cleaned.
Pre-flight: the session start hook. I have a session start hook for the agents: it runs the moment a conversation starts and hands the agent an instruction like "collect your first orders." I call this pre-flight. From there the agent proceeds by collecting the other rules in a chain, according to my intent.
This image shows the real output of the session start hook; CONTEXT_GATE does not let the agent proceed before collecting rules.
If it is a big job, the first 20-30 percent of the conversation's context goes to rules. Token usage goes up, but the quality of the work skyrockets. So I say: spend the tokens, but make it high quality — so that we do not burn tokens later on testing and hunting for context. You pay more in the short term and win more in the long term, because there is no quality problem. Also, the agent does not wander the whole project until it finds what it wants; an agent heading in the wrong direction is the single most expensive token cost. That is why the goal must be crystal clear at the start.
I tried handing rules out mid-flight; it failed. When I tried giving rules along the way I noticed the agent gets confused — it cannot do all of them, veers off course, forgets the original goal. It confused me too; things kept spawning, management was hard, catching it all was harder. So I delegated it to the agent: it collects everything only at the start. Then we freeze the work — like the mode people call plan; I do not use plan mode, I use my own structure, but in theory it still plans. The agent collects the rules, collects my intent and shows me the goal once: "Shall I do this, okay?" I say okay and send it. The key point: when I say okay, no new agent is opened — the same agent continues. Because what I value most is context; no matter how high the token usage, if the context is on-topic I never reset it.
The agent that ran for 12 hours. I try to make the agents goal-driven as much as possible: I give all the tasks and the goal up front and let them move toward it on their own. For example, one of my dictation agents has been running for 12 hours right now. It is a very long job — it is refactoring — and an agent that has been working for 12 hours must not drift off its goal.
This image shows the terminal of the dictation agent running for 12 hours; the counter at the bottom right was marked during the talk.
For the curious, the currently active agents' durations: one at ten hours, one at eleven, one at three, another at three, and one at twelve — all refactors, as you may have noticed. Some fall into the blocked column; I collect those.
This image shows the forge refactor agent's terminal; the bottom right reads Pursuing goal 10h 25m.
This image shows the clipboard refactor agent's terminal; the bottom right reads Pursuing goal 11h 59m.
This image shows the cockpit and terminal refactor agent at 3 hours 5 minutes; after a compaction it reopened its gates with cos anchor.
This image shows the cos refactor agent at 3 hours 17 minutes, running its own runtime judges.
This image shows the dictation agent at 12 hours 53 minutes, working on a real Swift diff.
Production is mine, uncertainty is theirs. The critical concept: if I am standing at their head, I use agents for production, for creating something new — I direct the production, I review it; I own all the intent and the creation. But if I will not be there, if they run autonomously or while I sleep, I turn production off and the agents only resolve uncertainties. In other words, we make the parts describing how the system behaves at runtime become explicit at build time, where the code is written.
Removing runtime uncertainty. Agents tend to put nil everywhere. With fifty nil-carrying objects you cannot understand how the thing behaves at runtime; unreachable states hide bugs from the code side because everything only shows up at runtime. The medicine is discriminated unions and the impossible-state concept. In TypeScript it looks like this: type PasteResult = { kind: "delivered"; at: Date } | { kind: "fault"; reason: string } — now an impossible state like "delivered but with a fault reason" cannot even be written. The consumer closes with a default-free switch (result.kind); add a new variant and the compiler warns you. Swift, same thing: enum PasteResult { case delivered(Date); case fault(reason: String) } with a default-free switch result — a value outside the cases does not even compile. Adding switch cases also surfaces other problems: say a value that does not belong to any case was used, the agent guessed a value — made it up. These get caught on the code side. The agent can do this without producing anything new, purely by understanding the code; the runtime has logs, so it can verify from the logs, or change, run and watch. Logs are critical.
Lineage work in code. The agents inspect dependencies: which source uses which, is it really used at runtime, does removing it break the code — they run their own tests. Picture one file: one package uses fifty percent of it, another uses forty, nobody uses all of it. The agent splits it in two. The goal is the lineage again: everyone imports exactly the code they use, and once part of the lineage exists, the infrastructure for several agents to work in parallel exists too. As they split, the agents notice some content is used twice or defined again and again — that is drift; like giving the same duty to two different people. The wrong distribution of responsibility surfaces by itself, and the agent binds it to a single responsibility chain. The questions we would otherwise catch at runtime — "why does this one move and that one does not?" — get answered at build time. This work is long and usually boring; it has no direct effect on the visible result, so people push it aside. But it raises quality, stability, durability. They do it while I sleep.
I review in the visual layer. Night work makes no runtime changes, so I do not review by reading code; I try not to code at all during review, because code makes me think and slows me down. I do it in the visual layer: the agents run the visual tests on my second computer.
This photo shows the desk; the laptop on the right is the second computer where agents run visual tests.
Since I use the app itself, I just continue my normal usage flow — think of me as permanently in testing. Whatever problem I hit, I fix immediately; if something broke it can be recovered from git history, I know what happened, I gather it fast. My concern is not "let me read all the source to build the perfect system"; it is: everything should be visual, pushed to the UI layer, there should be logs, it should be visible to a human. If work is flowing by, it should log and be accountable — I have rules for that. The agents already check themselves against those; if they escape, I see it on the usage side and say: "Something broke — check the logs. Who broke this?" They find it and fix it, or they look through Git.
The system that keeps context dynamic. Especially when the goal is long, the agent absolutely drifts off target; and if we do not use the thing I am about to describe, it can even forget the initial job we gave it. Because a goal by itself is a very flat thing: since the agent idles, the same prompt gets fed to it again and again — not very meaningful, more like nagging it to repeat. The real thing behind the 12-hour agent staying on target is my transcript system. Inside cos I have my own transcription method: you give it a chat's session ID and it produces a trimmed transcript carrying only my messages, the agent's replies to me and the paths of the files the agent edited. The logic: we take what changes the course of the conversation — the human's words, the agent's answer (because I react to it, it changes the thought process) and the changed files. In a 260k context window these take roughly 40k. The rest — file reads, rule reads — is disposable; the intermediate layers used to change behavior do not matter, the result matters. Out of a 240k window a 40k essence emerges, and I feed it back to the agent after every compaction. The compaction algorithm already produces a headline-like summary; the original conversation I inject gives it grounding and the agent continues where it left off — like getting double focus exactly where it should focus. As the conversation grows there is an accumulation risk; my system handles that too: past a certain limit it drops the old conversations. Think of every compaction as a new layer; it slowly discards the two or three oldest ones. An autonomous agent does not accumulate much anyway: we do not include source diffs, only file paths; the agent runs autonomously, edits files, talks to itself, and most of that is thrown away. This turns context from a static document into a dynamic form that keeps updating inside the conversation.
Rule harvest on waking. When the work is done I ask the agent: "Is there a rule discovered here that is not in our rules?" This is the lineage logic again: if this rule were missing, would the system break? It answers, and I audit — I audit these personally, because I believe they matter more than the source code. Then I redistribute those rules into my system; it keeps compounding. When two rules disagree I treat it like a mathematical formula: when a scenario arrives where the formula fails, you constrain the old formula. Same logic — I add a link saying "this rule applies only in this area, otherwise use that one." When working with agents I only feed them rules tagged tried-and-required, because agents fabricate too much; for myself I also keep try-this, useful-grade rules — my own ideas, which I check personally.
How this content was produced. This is my agentic way of working; I built the whole infrastructure and system around it, and I talk to my agents by speaking — because the context requirement is huge. Right now I am even narrating this very content to my agent by voice. I use every system I described, take their photos and outputs; while I talk, my agents keep working — ten agents are running and I am telling this to one of them. The content itself will have come out of an agent, but from my speech; and my talk is at roughly twenty-five, thirty minutes now. I deliver it like a presentation.
This image shows the layout I use while producing content by talking; the talk, transcript, captures and shortcuts are visible at once.
I said I annotate while talking; this is my annotation panel. I mostly use the rectangle — it sequences the things I annotate with my speech.
This image shows the annotation panel and the rectangle tool used during the talk.
And what happens next? I have an agent standing by — freshly opened, about to work next to the other eleven. I will paste the talk into it exactly as it is, and it will set its own goal fully autonomously and produce this content. For this I will try both Codex and Claude; I do not know which one will take it. Because a thirty-minute talk is never wasted.
This image shows the fresh agent terminal that will take over the conversation; the tab, the empty-context terminal and the prompt line are marked.
And as you may have noticed, the system can also show which app and which agent I copied each thing from. Finally, let me show the panel where I keep my conversation history. Look closely and you will see the parts showing my drawings — recorded as rectangle. At the moment I said anchor, I drew — and that also went to my AI. It was recording just now; you are watching the live talk. Because the talk is recorded continuously there is no risk of loss: computer dies, internet drops — a thirty-minute talk does not go to waste, it is backed up constantly. Because it is precious; human production is incredibly valuable. So it has to be collected fast and without friction.
This image shows the conversation history panel; the recording list, drawing traces and the total duration were marked during the talk.
optionOS completes this. I build every tool inside my own systems, and I have started sharing them all — step by step, the ones I am sure work, the ones that have become stable. And the first product was optionOS, the first speech product. Because context is the most critical element, and the most important context is the human's — the thing we call the idea in a person's mind. Writing is far too slow for extracting an idea; so instead of writing, you have to talk — that is one. Two, talking is not enough: a person needs to see something to remember — they must talk while looking. That is why I built an app that sequences whatever you copy while talking. Right now I am giving this talk by looking at the visuals on my computer, the agents' outputs, my own systems' outputs. I am not writing; I am not even reading text, because when a person looks at text they think, and thinking slows them down. We must escape text as much as possible and work more bodily, more intuitively. That is why all systems should be built image-first and animation-first. optionOS follows exactly this vision: as little text as possible, as much image and animation as possible — let the human look only at visual objects and never touch the source code. Remember the lineage concept on visual objects: you should be able to hand the agent the relation between source code and a visual object by taking a photo. I call this the inspector — like the DOM inspectors in Chrome; you look at source code from the visual side. I am building this for the Mac: one that works in Chrome, since we can reach Chrome's DOM, and one that works in my own Mac app, both feedable to the agent with a photo. So instead of telling the agent "change this code," I say "change this object, this one is broken, that one is broken" — and it happens inside the conversation. I only press keys; context comes out incredibly fast.
First you need to try this vision, this working style, and internalize that it is efficient; then you start realizing how important the requirement is. After that optionOS becomes your hands and feet — it is mine right now, I use every system through it. There are other players in the ecosystem too: my agent-driven Cockpit-style visual panels and the part I call Clipboard; I will cover them step by step in another talk. If you want to try the system or — more importantly — the working method I described, do not wait, start trying now. To use the optionOS systems you can reach me or join the invite list at optionos.app. If you write that you came from this content, I will try to prioritize you in the waitlist.