# Serdar Doğrubakar — Full Content > Backend engineer and builder in İzmir, Türkiye. Full text of every project and note on dogrubakar.com. # Projects ## context-bridge URL: https://dogrubakar.com/projects/context-bridge Tagline: Switch agents. Not context. You work in more than one coding agent, and every switch normally costs you the conversation: copy a summary, hunt a session id, start over. context-bridge connects the native sessions of Claude Code, Codex, Grok, Antigravity and OpenCode. Each agent keeps its own real session; the bridge computes what the other one is missing and delivers exactly that. ### State, not transcripts Per project the bridge keeps .bridge/state.json: session references, sync watermarks, a git checkpoint and pending markers. Never transcripts, gitignored automatically, migrated forward across versions with the original kept as a backup. Delta checkpoints are delivery artifacts with a pruning schedule, not an archive; canonical memory stays in each agent's own session files. ### Lanes, not branches One project directory can hold more than one line of work. Each lane keeps its own agent links, switch history and checkpoints, and lanes cannot see each other, so two sessions run in two terminals without their state colliding. A bare bridge resumes the last lane, so a project with one lane never has to know lanes exist. What they isolate is context, not the working tree: every lane shares one checkout. That is parallel conversation, not parallel code, and worktree-backed lanes are a later feature rather than a hidden one. ### Doctor checks what others skip Beyond install and auth, bridge doctor verifies that each vendor's session files still parse with this version of the bridge. Session formats are internal, a renamed field ships silently in a point release, and without this check every handoff would return an empty delta while everything still looked installed. ### Local and private No SaaS, no telemetry, no database. No API keys are read or stored; auth detection checks that credentials exist and never touches their values. Deltas travel only between the CLIs on your machine, inside their normal subscription-authenticated calls. ## multi-agent URL: https://dogrubakar.com/projects/multi-agent Tagline: Independent second opinions, natively. You already have an agent defined for one coding CLI, a plain .claude/agents/*.md file. multi-agent runs that same agent on other model CLIs: grok, codex, claude. Each target executes it natively through its own agent runtime, no API keys and no re-implementation. When independent models converge on a finding you get confidence. When they diverge you get coverage. ### One core, one adapter per CLI core.py never learns about a specific model: it normalizes your agent into a portable form, maps its tools onto a neutral capability vocabulary, and each adapter maps those onto its CLI's own tool names. Tools with no mapping are reported, never silently dropped. Adding a CLI is one adapter file; the core changes only for new features. Every spawned process starts in its own group and dies as a tree, no orphans. ### Findings are a contract Whatever a model produces is normalized into findings-v1: file, line, severity from critical to low, category, description and a proposed fix. Cross-model findings stay unverified claims until the judge confirms them against the real files, and the scoreboard only counts what survived that check. ### Costs, stated plainly A full adversarial run is heavy: many model turns, several rounds, minutes to tens of minutes, real token spend. Each round waits for the slowest model. For quick work use fewer models and rounds, or the single-model /multi-agent. Roadmap: Codex and Grok native wrappers, and an MCP server exposing the arena to any MCP-capable CLI. # Blog ## The AI coding war is becoming a code hosting war URL: https://dogrubakar.com/blog/code-hosting-war Google put GitHub deeper inside its AI environment the same week Cursor launched a code host of its own. One integrates with the stack; the other asks whether the stack should be rebuilt around agents. For the last few years the AI coding race has been easy to describe. Who has the best model? Then the question changed. Who has the best coding agent? Then it changed again. Who has the best harness around that agent? This week two announcements suggest the next layer of the competition is already forming. Google AI Studio added two-way GitHub sync to AI Studio Build: start from an existing repository, pull changes in, push changes back, and move between environments without treating AI Studio as an isolated playground. At almost the same time, Cursor launched Origin, its own code hosting platform. Those sound like two versions of the same feature. They aren't. Google is integrating GitHub deeper into its AI development environment. Cursor is beginning to ask whether GitHub needs to sit in the middle at all. That difference may tell us where AI coding goes next. The repository is becoming part of the agent Google's move makes immediate sense. AI Studio Build has been moving from "generate me an app" toward something closer to a real development environment, and there was an obvious boundary: serious software does not live inside a temporary AI session. It lives in repositories. Developers change code locally. Other developers change it somewhere else. CI runs against it. Branches diverge. Commits accumulate. Production ultimately needs some canonical version of the project. Until now that boundary was friction. Google's own developer forum has months of requests for better pull support and bidirectional sync — people making changes outside AI Studio and then struggling to bring the current repository state back in. Two-way sync attacks exactly that problem. But look at the architecture. The repository still belongs to GitHub. AI Studio becomes another environment operating on it. That is a real improvement, and it preserves the existing centre of gravity. Origin goes after the centre of gravity itself. Cursor is no longer building only an editor Origin describes itself as: A git forge for the agentic era. That wording matters. Cursor is not presenting it as a nicer GitHub client; it is positioning code hosting infrastructure as something that may need redesigning around agents. The argument is essentially that code now moves faster than the infrastructure built to manage it. Origin is in early beta on paid plans, with repositories, pull requests and GitHub synchronization, and the ecosystem around it is already being wired in — Vercel, Buildkite, Depot appearing alongside the launch. The GitHub sync is the interesting part, because it means nobody has to make a binary decision. You don't start with move your company off GitHub. You start with sync your GitHub repositories. That is a much smaller decision. But once the repository lives in the same system as the agent, something structurally different becomes possible. Follow the stack Look at what Cursor has been assembling: the editor, its own models, model routing, codebase indexing, cloud agents in isolated development environments. Those agents build, test and produce merge-ready pull requests, and they run from desktop, web, mobile, Slack and GitHub. There are automations that work across several repositories. Now add repository hosting, and the pieces connect. Repository Context Agent Runtime Code change Test Review Pull request, merge Previously several companies owned different parts of that chain. The repository on GitHub. The developer in Cursor. The model from another provider. The agent somewhere else. CI in a fifth system. The AI tool had to cross a system boundary at every step. Origin gives Cursor the option to collapse more of that loop into one environment. That is a more interesting story than "Cursor built a GitHub competitor". GitHub understands the same thing There is another reason not to dismiss Origin as feature expansion: GitHub is moving in the opposite direction. It already owns the repository, the pull request, the issue, identity and much of CI. Now it is pulling agents into that environment — an Agents tab inside repositories, putting agent sessions alongside code, issues and pull requests, and a cloud agent that works in its own environment, modifies branches and opens pull requests. More importantly, it has been opening that layer beyond Copilot. Claude and Codex can operate inside GitHub workflows with shared history and context. So the movement is happening from both ends. GitHub's bet The code already lives here Bring the agents to it Be the layer under all of them Cursor's bet The agents already work here Bring the code to them Own the whole loop That is the competition worth watching. Why code hosting suddenly matters to AI companies For a human, a repository is a collaboration and version-control object. For an agent it is more than that. It is memory. It is state. It is history. It is provenance. It holds the current implementation, previous decisions, branches, diffs, reviews, failures, ownership boundaries and the evidence of how a codebase got this way. The better an agent understands that environment, the less often it has to reconstruct reality from scratch. That is why repository access became so important to coding agents in the first place. And once agents move from answering questions to working autonomously for minutes, hours or continuously, the relationship gets deeper still. An autonomous coding system needs somewhere to start. Somewhere to branch. Somewhere to keep intermediate work. Somewhere to coordinate with other agents. Somewhere to run checks, attach artifacts, request review, merge. The repository stops being a folder the AI reads. It becomes part of the agent runtime. This is not a GitHub death story It would be easy to turn this into Cursor is coming for GitHub. That is premature. GitHub has distribution, enterprise adoption, identity, permissions, Actions, pull requests, issues, integrations and years of workflow gravity. Origin is early. A code host is also much harder to replace than a text editor — enterprises do not move repositories because a new interface looks better. And GitHub is not standing still. Its strongest position may actually be neutrality: if developers want Copilot today, Claude tomorrow and Codex for the next task, GitHub can be the common execution and coordination layer beneath all of them. That is a powerful place to stand. It also reveals the threat. If AI coding products become the primary place where software work happens, GitHub risks becoming infrastructure underneath an interface developers visit less often. The danger isn't losing the repository. It's losing the workflow around the repository. The next moat may not be the model Models are increasingly interchangeable inside coding products. A developer can already switch between frontier models without switching development environment. That weakens the model as the permanent centre of the product. What is harder to replace is everything that accumulates around it. Swapped in an afternoon the modelthe editorthe extension Accumulated over years your repositoriesyour agent historyyour codebase indexyour rulesyour permissionsyour review workflowyour automationsyour CI contextyour deployment integrationsthe record of what agents did, and why That is where switching costs begin. And that is why code hosting matters: owning the repository gives an AI platform a persistent anchor underneath models that may change every few months. Two possible futures Google's approach currently looks interoperable. Bring an existing GitHub repository into the AI environment, work with Gemini, push and pull, continue somewhere else. GitHub remains the source of truth. Cursor's direction is vertically integrated. Bring the repository closer to the agent environment itself. Neither has won. But they are two very different bets. One says the AI development environment should integrate with the existing software stack. The other asks whether the stack itself should be rebuilt around agents. That distinction matters more the more autonomous agents become. Watch who owns the loop For years GitHub owned the durable object and coding tools came and went around it. Editors changed. Models changed. Extensions changed. The repository remained. Agentic development creates the first serious reason to ask whether those layers should stay separate. If an agent understands the repository, edits it, runs the software, tests the result, opens the pull request, reviews other changes and eventually watches what happens after deployment, then splitting that work across five independent systems starts to look less inevitable. That is what makes these two announcements interesting. Not the Git sync. Not another code host. The boundary of the AI coding product is expanding. Autocomplete The editor The terminal The development environment The coding workflow The repository The next AI coding war may not be about who writes the best code. It may be about who owns the place where software gets built. ## Same model, 30 points apart URL: https://dogrubakar.com/blog/same-model-30-points-apart Eleven teams, one benchmark, the same model families. The best and worst systems running identical models finished 30.4 points apart, and everything that opened that gap sat outside the weights. Same model. 30.4 points apart. That is the number I care about most in Databricks' Grounded Reasoning Cup results. Not Stanford winning. Not the frontier-agent baselines. The 30.4-point average gap between the highest- and lowest-scoring teams using the same model. Because the model was the same. What changed was everything around it: parsing, retrieval, tools, skills, verification, parallelism, retry logic, operational infrastructure. We have spent the last few years talking about AI capability largely through model names. Which model is better? Which one scores higher? Which one reasons better? Once models start operating inside agent systems, that question becomes incomplete. Model capability is no longer system capability. It is one of its inputs. This wasn't a normal benchmark The Grounded Reasoning Cup brought together 11 academic teams from the US and Canada. For roughly two months they developed agent systems using OfficeQA, Databricks' benchmark for grounded reasoning over complex enterprise-style documents. Each team was paired with OpenAI, Anthropic or Google DeepMind and restricted to models from its assigned lab's family. Then Databricks moved the ground underneath them. 36 hours before the live competition, teams received a new benchmark built around the US Treasury's Accounts of Receipts and Expenditures — roughly 120,000 pages of historical Treasury documents. The competition ran across six increasingly difficult 15-minute rounds, 15 questions per round. That matters because the teams were not being tested on the environment they had spent months optimizing against. They had to transfer what they had built to a new corpus, under time pressure. And the corpus was ugly in exactly the way real enterprise data is ugly. Historical documents. Changing representations. Tables. Financial terminology. Different structures across different periods. Questions needing evidence scattered across several documents. This was not: Find this sentence in a PDF. It was closer to: Find the right evidence across a messy document collection, reconcile it, calculate what needs calculating, verify it, and return the answer before everyone else does. That is a much more interesting agent problem. Stanford won, and that is not the interesting result Score Stanford 63.3% Team average ~41% Out-of-the-box frontier agents (offline) below 30% There is an obvious headline hiding in that table: Stanford's custom agent system beat frontier agents by more than 30 points. I wouldn't use it. Databricks explicitly warns these conditions are not comparable. The baseline agents ran offline with frozen configurations across the test set. Competition teams operated in rounds — they could observe failures, change strategies and modify their systems between rounds. So 63.3 against sub-30 is not a clean measurement of harness uplift. Fortunately there is a much more interesting number. Databricks reports that the average gap between the highest- and lowest-scoring teams using the same model was 30.4 points. One caveat worth stating plainly: that is a best-to-worst range, not an average uplift. It does not mean a better harness hands a model 30.4 points. What it does tell us is arguably more important: The same model can produce radically different capability depending on the system built around it. Three top teams, three different systems Stanford, UMass Amherst and Yale finished at the top — and did not converge on one architecture. What the model decides how well it reasonshow it uses a tool it is handedhow it behaves over long context What the system decides what the model sees at allwhich representation it readswhich tools existwhat it rememberswhen it verifieswhen it retrieswhen it stops Stanford built around reusable skills and adaptive verification. UMass optimized heavily for speed and parallelism. Yale built multiple independent reasoning paths with a meta-verifier selecting among their answers. There is no single agent loop explaining the leaderboard. Stanford built 100+ skills During development Stanford repeatedly traced incorrect answers back to the exact point where its agent failed. Did it fail to locate the right table? Misinterpret financial terminology? Format the answer incorrectly? Lose context in the parsed representation? Handle unit scaling wrongly? Instead of adding more instructions to one giant prompt, the team converted recurring failure patterns into reusable skills. By competition day Stanford had a playbook of roughly 100+ skills. "Skill library" is technically correct, and it undersells what they built. I would call it compiled failure memory. The agent fails Trace the root cause Extract the pattern Write it down as a skill The next run starts with it That is memory, whether the artifact is called a memory, a rule, a skill or a procedure. And Stanford didn't only teach the agent what to look for. Some skills helped it decide how to look — search the parsed corpus text, use a Markdown-style document representation, or fall back to the source PDF when parsing had lost important context. A strong agent system does not just contain more knowledge. It knows which representation and which tool suit the problem in front of it. But memory has a scope problem The competition also exposed the uncomfortable half of that story. Techniques the teams developed on OfficeQA did not always transfer reliably to the new corpus. That should matter to anyone building agent memory, because storing knowledge is the easy problem. The hard one is knowing where that knowledge applies. A skill can be useful in one corpus and harmful in another. A decision can be right for one repository and wrong for another. A procedure can work under one tool environment and be obsolete when the environment changes. A lesson learned yesterday does not automatically remain true tomorrow. This is where a lot of current agent-memory thinking feels incomplete to me. We focus on remembering: what did the agent learn, what did we decide, what happened last session, what should persist. But persistence alone is not enough. Memory needs applicability. It needs scope. Eventually it probably needs some notion of validity decaying as the environment changes. The Grounded Reasoning Cup demonstrated this almost accidentally. Teams spent months learning. Then Databricks changed the distribution, and some of that learning stopped transferring. An agent that remembers everything but does not know where its memories apply can become confidently wrong because of its own experience. That is a much harder problem than storing another vector. UMass optimized for something else entirely Its primary model was Claude Opus 4.8 Fast. The team preprocessed the corpus into a metadata catalog built for rapid search and filtering. For every question, three agents ran in parallel, and a final Opus call selected the best answer. The result was speed. UMass Field Average time on correct submissions ~4 min ~8 min 30 s Speed bonuses earned 36 Stanford: 16 By halftime UMass led Stanford by 10.25 points, and entered the final round still 3.75 ahead. Then the scoring environment changed: the final round held the hardest questions and was worth double. Stanford's slower, accuracy-oriented system caught up, and UMass held the lead until the final 56 seconds. Stanford won by 1.75 points. There is an agent-engineering lesson inside that finish. There is no universally optimal architecture. There is an objective function. Optimize for latency Preprocess into a catalog Three agents in parallel Four minutes Optimize for accuracy Skills for known failures A second agent verifies Fewer wrong answers In a benchmark that objective function is the scoring system. In production it is your SLA, your cost structure and your risk profile. Stanford won partly by turning verification off This is my favourite detail of the whole competition. For the first three rounds Stanford ran a second Claude Code agent as a verifier: independently checking intermediate values, tracing revised values through data lineage, catching unit-scaling problems, patching calculations when it found inconsistencies. That sounds like an obvious improvement. It was. It was also slow — Stanford earned only two speed bonuses across those rounds. So they did something that sounds wrong if you think of an agent as a static system. They turned verification off. For the final three rounds the extra pass was gone, latency dropped, and the team earned speed bonuses on 14 questions. Then came the hardest part of the competition, and Stanford turned the verifier back on. In the final round it helped correct an answer through one of the resubmissions. The lesson is not that verification is good, nor that it is too expensive. The value of verification depends on the task. On easy questions the chance of catching an important error may not justify the latency. On hard ones that trade-off reverses. So verification does not have to be a permanent layer in the pipeline. It can be a runtime decision. Which points at something broader. Maybe the next generation of agent systems will not only have better tools, retrieval, memory and verification. Maybe they will get better at deciding when those capabilities are worth using. Retrieval tells the same story The strongest systems did not dump documents into embeddings and do generic top-k chunk retrieval. Databricks specifically notes lexical retrieval such as grep, often combined with dense retrieval in hybrid approaches. That sounds boring next to the rest of modern AI infrastructure. It shouldn't. If an agent is looking for an exact historical account name, an identifier, a date, a financial term or an unusual phrase, semantic similarity is not automatically the right abstraction. Sometimes grep is better. This exposes a recurring mistake in agent architecture: we choose the abstraction first — vector database, RAG, knowledge graph, long context, whatever the current default is — and then force every problem through it. The strongest systems here did something more practical. They used different mechanisms for different problems. Parsing when parsing was enough. Lexical retrieval when exact search mattered. Dense retrieval when semantic similarity helped. Source PDFs when the transformed representation had lost information. Specialized tools for calculation and comparison. The harness was not just connecting the model to data. It was deciding how the model should interact with that data. The boring parts were capability too Databricks also calls out something that disappears from agent demos: operational infrastructure. Retry logic. Parallelism. Preprocessing. Submission scaffolding. In a live competition a correct answer that does not arrive on time is not a correct answer. A reasoning chain that dies because one operation failed is not useful capability. A system that knows the answer but cannot reliably submit it has still failed. This is where the boundary between "AI capability" and "engineering" gets fuzzy. If retry logic determines whether the task succeeds, retry logic is capability. If parsing determines whether the model receives the evidence it needs, parsing is capability. If retrieval determines what the model knows at inference time, retrieval is capability. If verification determines whether a wrong answer escapes, verification is capability. If memory keeps yesterday's mistake from repeating, memory is capability. These are not infrastructure surrounding the intelligence any more. Together they determine how much of the model's intelligence becomes usable. Distribution shift may be the more important benchmark Two months to optimize on OfficeQA. A new corpus 36 hours before the live event. And techniques that did not always transfer. That is exactly the failure a normal leaderboard hides. A system can become extremely good at a benchmark without becoming equally good at the underlying class of problems. So when I look at an agent benchmark now, I care about a second question. Not only how high did it score, but: What happens when the ground moves? Change the corpus. Change the document structure. Change the available tools. Change the task distribution. Change the latency budget. Do the learned strategies survive? Does retrieval still work? Do stored memories still apply? Does the harness know some of its previous assumptions are no longer valid? That is much closer to what happens when an agent leaves a benchmark and enters a real company. Production is one giant distribution shift. "Which model?" is becoming an incomplete question Agent leaderboards still push us to think in model names. Agent A uses model X, agent B uses model Y, and we compare scores. But agent A may have different parsing, retrieval, tools, context construction, verification, retry policies, parallelism, memory, stopping rules — even a different number of model calls per task. At that point, what exactly are we benchmarking? The model, or the system? The Grounded Reasoning Cup does not prove harness engineering is "worth 30 points" — that would be an abuse of the result. What it shows is that 30.4 points of separation can exist even when the model is held constant. That is a very different claim, and a much more interesting one. Model capability is an input. System capability is the result. None of this means models stopped mattering. A stronger model raises the ceiling. Better reasoning matters, better tool use matters, better long-context behaviour matters. But choosing the model no longer finishes the capability discussion. It starts it. After that choice you still decide what the model sees, what it can search, which representation it uses, which tools it can call, what it remembers, where that memory applies, when it verifies itself, when it retries, when several agents should run in parallel, when the system should choose speed over confidence, and what happens when the environment changes. Those decisions do not live in the model weights. They live in the system. So if two agent systems using the same model can still end up 30.4 points apart, asking only which model it uses is no longer enough. The more interesting question is: What did you build around it? Model capability is an input. System capability is the result. Sources Databricks — Evaluating AI Agents Live at the Grounded Reasoning Cup (August 18, 2026). Primary source for the competition setup, the 30.4-point same-model gap, Stanford's 63.3% result, the 100+ skills, Stanford's adaptive verification strategy, UMass parallelism and latency, Yale's multi-arm system, the retrieval findings, and the warning that offline baselines are not directly comparable with the live competition. OfficeQA on GitHub — the public evaluation repository: benchmark documentation, scoring code, corpus tooling and evaluation setup. OfficeQA on Hugging Face — the public benchmark and corpus. Access to the benchmark files is gated to reduce contamination and artificial score inflation. ## Grok 4.6: from the intelligence race to turn economics URL: https://dogrubakar.com/blog/grok-4-6-turn-economics A model launch is usually three bars on a chart. This one is more interesting for where the improvement comes from — and for what it costs to finish a job rather than to answer a prompt. Grok 4.6 is out. Normally this is where the familiar model-launch script begins. Smarter. Faster. Better at coding. Three bars on a chart slightly longer than the other three bars. Grok 4.6 has all of that. None of it is the interesting part. What matters is where the improvement is starting to come from. Start with what they are actually building Grok 4.6 was released on August 12, 2026, roughly a month after Grok 4.5. SpaceXAI describes the focus as long-running agents, and more ambitious interactive and visual work. Researching a topic. Analyzing information. Working across a codebase. Turning an idea into a functioning application. But there is another detail in this launch that I find more interesting. Cursor opens its announcement with: Today we are releasing Grok 4.6 together with SpaceXAI. Not "Grok 4.6 is now available in Cursor." Releasing it together. A model company and an agent product jointly releasing a model is basically the subject of this entire article. Because the question at the frontier is changing. It used to be: How difficult a problem can this model solve? The more useful question is becoming: How long can this model continue doing useful work? That sounds like a small distinction. What a benchmark used to ask Hard problem One answer Score What the work now asks Open-ended task Fifty turns Recover from three dead ends Still going the right way It isn't a small distinction at all. A large part of the agent race is hiding inside it. Back at the frontier, not above everyone else Grok 4.6 High scores 61 on the Artificial Analysis Intelligence Index. Grok 4.5 scored 56. GPT-5.6 Sol Max is also at 61. Fable 5 Max is at 62. So the right headline isn't "Grok beat everyone." It's that Grok is back at the frontier. The Intelligence Index isn't the part I find most interesting anyway. Things get much more interesting when the model is placed inside an environment. Benchmark Grok 4.5 Grok 4.6 GPT-5.6 Sol Max Fable 5 Max CursorBench 3.2 66.7% 69.9% 67.2% 70.5% DeepSWE 1.1 54.0% 65.9% 73.0% 70.0% FrontierCode 1.1 Ext. 56.6% 61.3% 60.6% 63.6% APEX-Agents 47.1% 57.5% 56.7% 59.2% Terminal-Bench 3.0 15.7% 26.0% 34.6% 34.1% AA-Briefcase 1313 1577 1502 1574 GDPVal-AA v2 1526 1753 1728 1741 There are two stories in that grid. First, the jump from 4.5 to 4.6 is substantial. Second, Grok does not win everywhere. In fact one result is particularly uncomfortable given the way the model is being positioned. That is exactly why it is interesting. The Terminal-Bench problem Look at Terminal-Bench 3.0. Grok 4.6: 26%. GPT-5.6 Sol Max: 34.6%. Fable 5 Max: 34.1%. This is a model explicitly built around long-running agents, and it trails its main competitors on a benchmark centred on sustained terminal work. If we hide that row and show only CursorBench, we are not reviewing the model. We are doing marketing. But that result does not end the Grok 4.6 story either. Different benchmark versions and different agent scaffolds can produce very different pictures of the same model. Artificial Analysis, for example, gets a much stronger Grok 4.6 result on Terminal-Bench v2.1. It would be wrong to describe that as "26% in one place and 88% in the same test somewhere else." They are not the same test. The benchmark version, the task set and the evaluation setup all differ. The more interesting conclusion is this: Knowing the model name is no longer enough to predict agent performance. Change the benchmark version. Change the harness. Change the tool definitions. Change context management. Change the execution loop. And the result can move dramatically. Which brings us to the most interesting part of Grok 4.6. Models are learning to live inside the harness There is an easy-to-miss detail in how SpaceXAI describes training Grok 4.6. The model received a longer supplemental training run than Grok 4.5, using curated model-generated reasoning data, high-quality engineering data, and an improved optimizer and recipe. Then Grok 4.5 was used to regenerate SFT trajectories. Not only across different reasoning efforts. Across different agent harnesses. The reinforcement learning stage also included environments for general coding, kernel optimization, web development and CAD. That matters. Models are not only learning to produce better answers anymore. They are learning how to operate inside a harness. Call a tool Inspect the result Decide again Recover when it breaks Hold the task across the trajectory Verify before declaring success The transition from chatbot to agent is not happening only in the product interface. It is reaching all the way down into the training pipeline. Then CursorBench updated After the release, Cursor's live CursorBench 3.2 leaderboard was updated with Grok 4.6. This is where it gets genuinely interesting. Model Score Cost/task Tokens/task Steps/task Grok 4.6 Extra High 70.8% $2.81 41,136 46 Fable 5 Max 70.5% $17.32 103,525 72 Opus 5 Max 70.0% $8.23 61,838 78 Grok 4.6 High 69.9% $2.34 32,449 39 GPT-5.6 Sol Max 67.2% $5.69 28,320 48 Grok 4.6 Medium 67.1% $1.28 17,942 29 You can look at the score column and say Grok won. I think that is the wrong column. Look at steps and cost. Fable 5 Max gets 70.5% in 72 steps at $17.32 per task. Grok 4.6 Extra High gets 70.8% in 46 steps at $2.81. Grok 4.6 High gets 69.9% in 39 steps at $2.34. GPT-5.6 Sol Max reaches 67.2% in 48 steps at $5.69. None of this means Grok is universally six times cheaper for real work. It is one benchmark, one harness, one task distribution. But it demonstrates something important. Price per token is becoming an insufficient way to think about agent economics. From token economics to turn economics A coding agent does not answer one prompt. Read a file Search Write code Run the tests Read the error Realize an assumption was wrong Backtrack Run the tests again Maybe it does this fifty times. So putting two models' input-token prices side by side tells us a fraction of the real cost. What the pricing page compares price per million input tokensprice per million output tokens What the bill is actually made of model pricecontext growthnumber of turnsrecovery cost An expensive model that finishes in twenty turns can be cheap. A cheap model that needs 150 tool calls, three dead ends and a giant context window can be expensive. One of the important metrics of the next phase will be cost per successful task, not cost per token. And even that will not be enough. We will want turns per successful task, tokens per successful task, recovery rate, verification rate, wall-clock time. Because an agent's cost does not end with the inference bill. It burns time. It produces bad work. Sometimes it puts the human back into the loop. AA-Briefcase makes the same point Artificial Analysis' AA-Briefcase evaluation is interesting here because it measures longer-running knowledge work. Grok 4.6 scores 1577 Elo. That is roughly Fable 5 territory, and ahead of GPT-5.6 Sol Max. But the Elo number is not the interesting part. Artificial Analysis reports Grok 4.6 completing tasks in roughly 53 turns and 0.5 billion input tokens, against roughly 103 turns and 2 billion input tokens for Claude Opus 5 Max. It would be irresponsible to turn one benchmark into "Grok is twice as efficient." But the underlying problem is real. We need to evaluate an agent not only on whether it eventually reaches the right answer, but on how much nonsense it produces on the way there. That is where a large part of the next model economy will be decided. $2 / $6 is attractive, with three asterisks Standard Grok 4.6 API pricing starts at $2 per million input tokens and $6 per million output tokens. The model has a 500K context window and configurable reasoning effort from low through xhigh. For a frontier model, that is aggressive. But the headline price has three details underneath it. 1. Fast costs twice as much There is a lower-latency fast variant. It costs twice the standard rate. So $2 / $6 becomes $4 / $12. 2. Pricing changes at 200K context Once the prompt reaches 200K tokens, long-context pricing takes over. Input becomes $4, output becomes $12, cached input becomes $1. Charging only the tokens above 200K at the higher rate would be the intuitive implementation. That is not how it works. Once the threshold is reached, every token in the request is billed at long-context rates. That is rather important for something positioned as a long-running agent model. As the session grows, the number on the pricing page may stop being your real price. 3. Cache got more expensive This is my favourite detail. Grok 4.5 Grok 4.6 Cached input $0.30 $0.50 Long-context cached input $0.60 $1.00 Roughly a 67% increase, easy to miss while the headline input and output prices stay unchanged. For long-running agents, cache is not a footnote. Persistent sessions, large system prompts, tool definitions and reused context make it part of the economics of the product. So some long-running workloads may not be as cheap on 4.6 as the headline suggests. Which brings us back to the same point. A cheaper model does not make bad context architecture cheap. Compaction, selective retrieval, state management and what you resend on every turn are becoming product-economics decisions. Is the model getting better, or is the harness? This is one of the biggest problems with model comparisons in 2026. We see Grok in CursorBench. GPT inside Codex. Claude inside Claude Code. Then we put the scores next to each other and ask which model is better. But an agent's output is no longer just model output. It is closer to the whole system: model, system prompt, tools, context management, retry strategy, compaction, execution environment, verification loop. One model Harness AOwn toolsOwn context rules Harness BOwn retry policyOwn compaction Harness COwn verificationOwn environment Three different scores There is research pointing in the same direction. ISO-Bench, published in February 2026, evaluated coding agents on 54 real inference-optimization tasks taken from vLLM and SGLang. One of its most interesting findings was that agents using the same underlying model could perform substantially differently. The researchers' conclusion is hard to ignore: scaffolding can be as important as the model itself. Grok 4.6 is a nice real-world example. Cursor is not a neutral frontend sitting on top of the model. Grok 4.5 was already jointly trained with Cursor, using trillions of tokens of Cursor data including developer-agent interactions. With 4.6 the relationship goes further. SFT trajectories are generated across agent harnesses. Cursor and SpaceXAI release the model together. Cursor observes and tunes around its long-trajectory behaviour. These are no longer the same question: Which model is better? and Which model is better inside this harness? That distinction is going to matter more and more. Model companies will move closer to harnesses. Harness companies will move closer to model training. Agent runtimes will become RL environments. The boundary between model and product will keep blurring. Self-verification isn't a small feature One of the most interesting lines in Cursor's announcement is not in the benchmark table. Cursor says that on longer trajectories they started seeing more self-testing and verification, with the model checking its own work before moving on. We should not overstate this. It is an observation from Cursor, not an independent benchmark. But the direction matters. The next major improvement in coding agents may not come from writing better code. It may come from getting better at rejecting their own bad work. Run the test. Inspect the result. Check the requirement again. Notice that something doesn't work. Don't say "completed" until the task is complete. The most frustrating thing about today's coding agents isn't that they can't write code. They often write perfectly decent code. The problem is that they don't know when to stop. They declare partially completed work finished. They move on with broken tests. They implement something adjacent to the requirement and decide the job is done. That is why self-verification could be worth more than another few benchmark points. But 26% on Terminal-Bench 3.0 is a useful reminder: this problem is nowhere near solved. So, is Grok 4.6 the best model? I don't know. More importantly, I am not convinced that is a useful question anymore. CursorBench currently puts Grok 4.6 at the top. GPT-5.6 Sol Max is significantly ahead on DeepSWE. Grok trails on Terminal-Bench 3.0. It is very strong on GDPVal-AA. It is around Fable 5 territory on AA-Briefcase. Change the harness and the ranking may move again. Change reasoning effort. Change the tools. Change the task distribution. It moves again. In 2026, opening one leaderboard and declaring this is the best AI model in the world is becoming increasingly meaningless. What I want to know is the workload. What are you asking it to do? Inside which harness? For how many hours? How much context will it carry? How many turns does it need? Can it recover from a bad path? Does it verify its own work? And after all of that: How much does a successfully completed task actually cost me? My takeaway The interesting thing about Grok 4.6 isn't its 70.8% on CursorBench. It isn't the 61 on the Intelligence Index either. The real signal is this: As frontier models converge, competition is moving from raw intelligence toward economically sustainable work. I don't need an agent to produce the world's smartest answer at every step. If it is going to work for hours, I need it to use the right tools, avoid bloating its context, recover from mistakes, verify its work, and do all of that economically. Grok 4.6 looks very strong in that race. Does it win? On some workloads, yes. On others, clearly not. That is exactly how these models should be evaluated. Because models aren't competing only for chatbot subscriptions anymore. Routers select models per task. Coding agents make dozens of inference calls. Background agents run for hours. Multi-agent systems can turn one request into several model sessions. In that world, model selection will increasingly be done not by brand loyalty, but by accounting. And that accounting will not be as simple as asking how much a million tokens costs. The question will be: How much does it cost me to complete the same job reliably? Grok 4.6's most interesting contribution is forcing that question into the foreground. Another model may take the top spot on CursorBench in a few weeks. It probably will. That part isn't very important. The more durable shift is this: The model race is slowly becoming a race in turn economics. And the winner may not be the model that gives the most impressive answer once. It may be the one that can keep moving in the right direction for the longest. ## The next learning layer for AI agents may not be the model URL: https://dogrubakar.com/blog/the-next-learning-layer When a coding agent fails we rarely change the model. We change the harness around it — and the agent works better next time. So where does an agent's experience actually accumulate? What do we do when a coding agent performs badly? We can change the model. But in practice, that is often not what we do. We add an AGENTS.md. We write a skill. We fix the tool. We change what gets into context and what does not. We add tests. We leave a new rule in the repository so the agent does not make the same mistake again. The model stays the same. But the agent works better the next time. That has been making me think about one of the more interesting questions in the agent space: Where does an agent's experience actually accumulate? The obvious answer is the model. That is how we have thought about machine learning for years. If the system needs to improve, we improve the model. Better data, fine-tuning, reinforcement learning, post-training. But once you start working seriously with coding agents, another layer becomes visible. The software around the model. Same model, better system Today it is increasingly difficult to attribute what Claude Code, Codex, or another coding agent does purely to the model behind it. The model reasons. But something still has to explore the repository, decide what enters context, run the shell, call tools, manage permissions, verify results, handle context pressure, and recover when something goes wrong. We increasingly use one word for that surrounding system: Harness. Model Harness Tools Environment Software And here is the interesting part: We can improve the agent by changing the layers around the model without changing the model itself. This is not a new observation, and it is not just something developers are noticing in day-to-day use. Researchers have been exploring different versions of this idea for several years. In 2024, Automated Design of Agentic Systems (ADAS) proposed treating agent design itself as a search problem. Agents were represented not only as prompts, but as code, and new agent designs could be generated by another agent. Then work such as Gödel Agent and Darwin Gödel Machine pushed the idea further into self-modification. Darwin Gödel Machine was particularly interesting because it allowed a coding agent to modify its own implementation, evaluate the new version on coding benchmarks, and preserve useful changes for future iterations. The improvements it discovered were not science fiction. Better code editing. Better long-context management. Peer review mechanisms. In other words, familiar engineering. The model itself had not been retrained. The system the model operated inside had been changed. And according to the evaluations in the paper, some of those changes made it perform better on the tasks being measured. That distinction matters. There may be another place for experience to persist One of the strongest ways for machine-learning systems to retain what they learn is through model parameters. The system is trained. Weights change. The resulting model behaves differently. Agents introduce another possibility. If an agent repeatedly makes the same mistake, the solution does not necessarily have to be encoded in the model weights. Maybe the solution is a new tool. Maybe it is a skill. Maybe it is three lines in AGENTS.md. Maybe it is a new verification step. Maybe context selection needs to change. Maybe the repository needs a map that makes it easier for the agent to understand. Maybe the workflow used in a specific situation should be redesigned completely. So another kind of persistence becomes possible: Experience Engineering change Executable behaviour This is not "learning" in the same technical sense as updating model parameters. That distinction is important. But the operational result can still persist. The model was not retrained. Yet the next execution inherits something from what happened before. That is the part I find interesting. Research is now targeting the harness directly In 2026, Agentic Harness Engineering made this idea much more explicit. The researchers keep the model fixed. What they optimize is the harness around it. Tools can change. Middleware can change. Long-term memory can change. The system prompt can change. Then the resulting system is evaluated again. To me, the most interesting result is not simply the benchmark score. The paper's ablation analysis attributes much of the reported improvement to changes in tools, middleware, and long-term memory, rather than to the system prompt alone. That matters. For years, when people talked about agent optimization, the reflex was often to look at prompting. This work is another reason to look more carefully at the rest of the system. The authors also report that evolved harnesses can transfer across different model families. That raises an odd but useful question: If the model changes and some of the improvement survives... where does that improvement live? Not entirely in the model. At least some of it appears to be encoded in the surrounding system. Then failure logs stop being just logs A paper published in August, Harness-R1, pushes this in another direction. Today's agents generate an enormous amount of operational evidence. A tool call fails. A plan breaks. Context is insufficient. A file is misunderstood. A solution is attempted and does not work. Another path succeeds. Then the session ends. In many systems, the next agent starts again with essentially the same harness. Harness-R1 explores a different possibility: What if failure trajectories were used to modify the harness itself? The system examines failures and produces executable patches for the harness the target agent runs inside. Then the modified system is evaluated again. Run Fail Inspect why Modify harness Run again Evaluate From a backend engineering perspective, there is nothing particularly exotic about the shape of this loop. This is how we have improved production systems for years. Read the logs. Find the failure mode. Change the system. Deploy. Observe. Rollback if necessary. What is new is the attempt to automate more of that loop using agents themselves. That is a much narrower claim than saying the agent has somehow "learned to improve itself." But I think it is also the more interesting one. This gets even more interesting when the experience is distributed A paper published on August 5, EvolveNet, asks another question: Can adaptations discovered in different environments be combined? There is an obvious problem. You cannot simply send Company A's repository to Company B. You cannot freely share internal workloads. You cannot assume user data can be moved into a centralized training system. EvolveNet explores sharing not the raw experience, but program adaptations produced from local experience. Shared harness ALocal workloadLocal adaptation BLocal workloadLocal adaptation CLocal workloadLocal adaptation Updated harness There is a resemblance to federated learning, but the mechanism is importantly different. The system is not simply averaging gradients. It is attempting to compose software adaptations. If approaches like this prove practical beyond experimental settings, they could create an interesting way of distributing operational knowledge. An agent might eventually inherit an engineering solution produced elsewhere without receiving the original workload that led to it. There are many hard problems between the research prototype and that outcome. But the possibility itself is worth following. The repository is already storing more than code This is where the software engineering implications become particularly interesting to me. A repository used to hold sourcetestsconfig In agent-heavy work it also holds AGENTS.mdCLAUDE.mdskillsMCP configtool definitionsarchitecture rulesverification scriptsrepository mapsagent instructions What do all of these things have in common? They help determine how an agent works on the software. The repository no longer only describes the software. It can also describe how an agent should perform engineering work on that software. And this knowledge has very different properties from model weights. You can diff it. Review it. Version it. Test it. Roll it back. Move parts of it between models. Fork it. Git is already starting to manage more than source code in agent-heavy projects. It is too early to know how far this goes. But one possibility is that repositories gradually accumulate a new kind of asset: operational knowledge about how humans and agents successfully work on that system. What OpenAI described looks like a manual version of this loop This is why something OpenAI described in its own Codex development experience stood out to me. When an agent fails at something, the response is not always simply "write a better prompt." The missing capability can be encoded back into the environment. Documentation. A tool. A guardrail. A test. Repository structure. A feedback loop. The next agent arriving in the same environment can then inherit that change. Humans can already create a loop like this: Agent fails Engineer learns Repository changes Next agent inherits it The research discussed above makes the next question fairly natural: How much of this loop can be automated safely? That "safely" matters. A lot. Because the system can preserve the wrong lesson too It is easy to call all of this "self-improving agents" and move on. But from a production perspective, a more uncomfortable question appears: What if the system preserves the wrong adaptation? The agent sees a failure. It changes the harness. That problem disappears. But three other workflows break. Or worse: What if the easiest way to improve the metric is to weaken verification? If a test does not pass, removing the test can technically improve a naive pass-rate metric. If a permission system slows the agent down, loosening permissions can make the agent appear more effective. Once software modifications become persistent, mistakes can become persistent too. At that point, this stops looking primarily like an AI problem. It starts looking like a very familiar production engineering problem. You need versioning. Regression testing. Audit. Provenance. Sandboxing. Rollback. You need to know which change caused which outcome. You need evaluation that the system itself cannot trivially game. So there is an irony here: If agents begin modifying more of the software around themselves, software engineering may become more important, not less. Maybe we should think about two improvement loops I find it useful to separate two different mechanisms. The loop we know Data Training Weights Capability The loop being added Experience Observation Software change Validation Operational capability These are not the same kind of learning. And one does not need to replace the other. They can interact. A stronger model may create better tools. A better harness may extract more useful behavior from the same model. Better verification may produce better feedback. Better memory may prevent the same operational problem from being solved repeatedly. The model learns through training. The surrounding system can accumulate experience through software changes. I think that is the more precise distinction. This is the layer worth watching ADAS explored automated discovery of agent designs. Gödel Agent explored self-modification. Darwin Gödel Machine experimented with evolving coding-agent implementations. Hyperagents made parts of the improvement mechanism itself editable. Agentic Harness Engineering focused directly on harness optimization. Harness-R1 explored generating executable harness patches from failure trajectories. EvolveNet is exploring how program adaptations from different environments might be combined. These are different projects, with different mechanisms, assumptions and evaluation setups. They should not be treated as evidence of one inevitable future. Some may remain benchmark experiments. Some may not survive contact with production. Some approaches may simply turn out to be wrong. But together they make one question increasingly worth paying attention to: Where will an AI agent's operational experience accumulate? Only in model weights? Inside the context window? In a memory database? Or also in tools, skills, rules, tests, middleware, and repository structures that change over time? I don't think we know the answer yet. But I suspect the last category will become much more important than we currently assume. Model weights give us capability. Maybe software can carry something else: experience. And if agents really become long-lived systems, what makes them interesting may not only be how intelligent they are. It may be what they are able to make permanent from what they have lived through. ## The wrong OpenCode session URL: https://dogrubakar.com/blog/context-bridge-0-12-2 One SQLite store holds every OpenCode session, and anything can leave one behind. When the bridge had to find its own session again, it took the newest. Usually that was someone else's. Yesterday's fix was about having nowhere to write. Today's is the opposite problem. Too many places. And the bridge kept choosing the wrong one. Every agent except OpenCode keeps its sessions as files. One conversation, one file, in a directory only that agent writes to. OpenCode keeps all of them in a single SQLite store. That's a better design in most ways. It also means the directory isn't yours. Any opencode run from a project folder leaves a session filed under it. An app that makes its own model calls in your working directory will quietly fill it with two-message remnants. Most of the time this never surfaces. The bridge links a session once and keeps using it. But sometimes it has to find that session again. After an unlink. After a seed. When doctor relinks a project. The rule it used was simple. Take the newest session in this directory. In a clean project, the newest session is your conversation. In a busy one, the newest session is whatever ran last. Usually a remnant. --adopt bound to it, and the bridge went on carrying handoffs into a two-message shell while the real conversation sat untouched a few rows away. Recency was standing in for ownership. It's a reasonable proxy right up until something else shares the namespace. The fix is to stop guessing and start recognising. The bridge already leaves marks. A handoff it delivers writes a message with a msg_bridge_* id. A session it fabricates gets a ses_bridge* id. Both were already there. Neither was being read. Discovery now looks for them. Exactly one marked session in the directory is provably the right one, and it is adopted silently. Several narrow to the newest of those, behind --adopt. None keeps the old newest-wins guess, which is correct for a genuine first adoption. The extra store read only happens when a directory is actually ambiguous. One candidate, or none, never pays for it. The verification is the part I like. A real directory. Twenty-seven OpenCode sessions. The newest was a two-message remnant. The bridge's own session was a ninety-message conversation. Before: the two-message remnant. After: the ninety-message conversation. 343 tests. The litter case is bite-proven — the old rule was put back, and the test failed. Worth knowing where this bites hardest. It has nothing to do with git. It's worst in directories that aren't git repositories, because OpenCode files all of those together under one global project. Upgrading npm i -g @serdardb/context-bridge Only OpenCode is affected, and only when a directory holds more than one of its sessions. If yours holds one, nothing changed for you. ## The first switch into OpenCode URL: https://dogrubakar.com/blog/context-bridge-0-12-1 I described OpenCode's delivery path accurately enough to expose the bug, and did not notice. The first switch into OpenCode never delivered anything. The bug wasn't in the code. It was in the release notes. While writing about the last release, I described OpenCode's delivery path like this: context-bridge now writes the handoff directly into OpenCode's database when resuming a session. That sentence is correct. It also quietly explains why the first switch into OpenCode never worked. ...when resuming a session. On a first switch, there is nothing to resume. I had described the implementation accurately enough to expose the bug without noticing it. context-bridge moves an active coding session from one terminal agent to another. Not a pasted summary. Not a fresh conversation. The receiving agent continues inside its own native session with the decisions, the open questions and the current Git state already there. Claude Code, Codex, Grok and Antigravity all expose a place where the bridge can inject a handoff. OpenCode doesn't. There is no hook. There is no resumable prompt. The bridge writes directly into OpenCode's SQLite database instead. That works perfectly. As long as a session already exists. On the first switch, it doesn't. Every message in OpenCode belongs to a session. A message cannot exist on its own. If there is no session row, there is nowhere to attach the handoff. The write cannot happen. The delta stays pending. The launcher's recovery path couldn't help either. Normally it waits for an OpenCode session to appear, then links it automatically. But there was no session to discover, because OpenCode hadn't created one yet. And the bridge couldn't write one, because writing wasn't its job. Not a deadlock. A gap. The handoff arrived at the one moment nothing existed to receive it. OpenCode launched. The bridge reported it as unlinked. None of the transferred context appeared. The important part is what didn't happen. Nothing was lost. A delivery is committed only after the destination has accepted it. Not when a process starts. That rule exists because an earlier Claude → Codex bug failed the other way. Back then, spawning a process counted as delivery. The delta was renamed .consumed. The process failed. The handoff disappeared. There was nothing left to retry. That bug changed the delivery model. Since then, "started" and "delivered" have never meant the same thing. Because of that decision, this bug delayed the handoff. It never destroyed it. I would rather ship a bridge that is occasionally late than one that silently loses work. The fix is almost embarrassingly simple. If there is no session... Create one. fabricateSession() inserts the session, the handoff message and its first part inside a single SQLite transaction. The launcher resumes that session by id, links it, and from that point onward the flow is identical to every subsequent switch. Two implementation details turned out to matter. The project isn't guessed. It is resolved from OpenCode's own database. COALESCE( (SELECT id FROM project WHERE worktree = ?), 'global' ) If the worktree already belongs to a project, the fabricated session joins it. Otherwise it falls back to the global project, exactly as OpenCode itself does. Guessing either value would have placed half of all first sessions under the wrong project. The session id isn't random either. It is derived from the worktree and the delta. If the command is rebuilt before delivery is committed, the same id is produced, the insert becomes a no-op, and no duplicate session appears. A random identifier would quietly create another ghost session every time. The implementation was reviewed twice. First by OpenCode, to verify the database model. Then by Codex, to review the code itself. Finally, the bridge fabricated a session into a real OpenCode store, resumed it, linked it, and verified the result through OpenCode's own session list. 337 tests pass. The first-switch regression is now covered. The original bug was reintroduced deliberately. The new test failed. Then the fix went back. The test passed. That's the one I trust. If you're on 0.12.0 0.12.0 was available for less than two days. If you installed it and use OpenCode, update: npm i -g @serdardb/context-bridge Only the very first switch into OpenCode inside a project was affected. Every other agent behaved correctly. Every later OpenCode switch behaved correctly. Only the first one had nowhere to land. ## The day an agent ran clean in the wrong directory URL: https://dogrubakar.com/blog/clean-in-the-wrong-directory It deleted 131 checkpoint groups. Every guard in the code held — the command was correct, and it was pointed at the wrong place. While reviewing the lane-scoped clean command in 0.12.0, an agent ran it from the repository instead of the temporary fixture it was supposed to test against. It deleted 131 old checkpoint groups. .bridge/checkpoints was left with three files — the handoff that was live at that moment. No source was touched. Git was untouched. Nothing pending was lost. There was no backup, and the groups could not be recovered. The command did exactly what it should have This is the part worth being precise about, because it is the opposite of the usual story. clean prunes old checkpoints. It refuses to delete anything another lane still depends on, it validates every lane before removing anything, and it will not touch a pending injection. Every one of those guards held. Judged by its contents, the operation was correct: those 131 groups were old, ignored, and exactly what clean exists to remove. Running it again today would produce the same list. The failure was not in what the command deleted. It was in which directory it was pointed at. A destructive command was being tested. Testing it means running it. The fixture existed precisely so it could be run without consequences, and the fixture was not where it ran. Why the guards could not have saved it The trust-boundary work in 0.12.0 is real: every checkpoint read, write, list and delete rejects paths that escape .bridge or pass through a symlinked directory, and pruning validates every lane first. None of that is aimed at this. Those guards answer "is this path allowed?" The question here was "is this the repository you meant?" — and from inside the process, the repository is a perfectly legitimate target. It is the normal one. You cannot write a guard against a correct operation performed in the wrong place. That is what a fixture is for, and what --dry-run is for. What it actually cost Objectively, very little. The groups were ephemeral delivery artifacts that retention prunes anyway. They had already served their purpose. What was lost is the record. Each checkpoint was a small artifact of a real handoff — who passed to whom, what was decided, what carried over. That history is cheap to keep and impossible to reconstruct. Some of the writing on this site came out of those files. The ones that are gone cannot produce any more of it. What I took from it Not "add more guards" — the guards were not the gap. A destructive command has two arguments, and only one of them is visible. There is what to delete, and there is where. Every safety mechanism in the tool was pointed at the first. Nothing in the tool, and nothing in my own habits, was pointed at the second. So: test destructive commands against a fixture, and confirm you are in it before you run. Run clean --dry-run first — the dry run is the difference between deciding what to delete and finding out what was deleted. And the honest part: an agent did this, but an agent will run whatever it is pointed at, in whatever directory it happens to be standing in. It felt nothing afterwards. The cost of losing context only ever reaches a person. ## context-bridge 0.11 and 0.12: OpenCode, safer handoffs, and lanes URL: https://dogrubakar.com/blog/context-bridge-0-11-and-0-12 Adding OpenCode exposed several problems in how context-bridge delivered a handoff. Then lanes made it possible to keep more than one independent conversation inside the same project. context-bridge lets terminal coding agents hand an active session to one another. It does not create a new chat and paste in a summary. It carries the conversation, decisions, open questions, and current Git state into the receiving agent’s own native session. Versions 0.11 and 0.12 were released close together. One added a fifth agent and forced me to rethink parts of the delivery system. The other changed a basic assumption: one project directory no longer has to mean one line of work. 0.11.0: OpenCode and the problems it exposed OpenCode is now supported alongside Claude Code, Codex, Grok, and Antigravity. It was also the agent that did not fit the existing handoff model. OpenCode stores its sessions in a local SQLite database and does not provide a hook for delivering a message into an already running TUI. My first implementation used opencode run. It worked, but I removed it. That path can require authentication and trigger a paid model call. A local session switch that can stop at a login prompt is not a reliable switch. It also makes no sense to call a model just to place context into a session. context-bridge now writes the delta directly into OpenCode’s database when resuming a session. The operation is transactional, idempotent, requires no authentication, and makes no model call. When context-bridge needs to read the session for the next delta, it uses opencode export. The only external dependency is the sqlite3 CLI, and bridge doctor now reports whether it is installed. Supporting OpenCode was the planned feature. The more interesting work came from everything it exposed. Delivering context is not the same as starting a turn Claude Code and Codex receive their delta through a SessionStart hook. That is the cleanest way to deliver context because nothing has to be pasted in front of the conversation. The receiving agent starts with the missing context already available. But there was a problem. The agent received everything it needed and had nothing to answer. It simply waited until I typed something. Claude Code and Codex now receive a short opening prompt when delivery happens through a hook. That prompt does not contain the delta. It only starts the turn, which means the actual handoff cannot be delivered twice. The first switch was the only unbounded one Later handoffs were already clipped to fit within safe limits. The first handoff was not. It attempted to inline the entire conversation into a single CLI argument. With a large enough session, that becomes a multi-megabyte argument and the process fails with E2BIG before the agent even starts. That is exactly what happened during my first real switch to OpenCode. The first handoff is now bounded like every other handoff. It includes a summary first, then as much recent conversation as safely fits. The remaining context is stored in a full-context checkpoint referenced by the delta. The receiving agent still has access to everything without requiring the entire session to fit inside one process argument. A handoff is not delivered just because the process started context-bridge previously recorded delivery as soon as the target process spawned. That turned out to be the wrong boundary. A CLI that receives and processes its prompt looks exactly like one that starts but ignores it. Both processes launch successfully. I lost a real Claude-to-Codex handoff this way. context-bridge marked the delta as delivered, but Codex never saw it. Delivery now commits only after the target shows its first activity. If the agent starts and does nothing, the delta remains pending and can be retried. Starting a process is no longer treated as proof that the context reached the agent. OpenCode session discovery was leaking servers The original OpenCode session discovery started opencode serve, listed the sessions, then stopped the server. That worked until discovery timed out. A timeout could leave the server running in the background. The TUI could later connect to the stale server and confidently display old session state. Discovery no longer requires a server. The fallback path also guarantees that its temporary server is stopped, including when the operation times out. Agent flags now come from one source Grok declares seven flags that cannot be used while resuming a session. Antigravity declares four. The filter responsible for removing those flags read from a separate table. Over time, that table drifted away from the adapters that actually declared the rules. The filter now reads each adapter’s own conflictFlags value, and a test verifies that a flag declared by an adapter is the same flag removed during launch. If a rule is declared in one place and enforced from another, those two places will eventually disagree. 0.12.0: lanes Before 0.12.0, one project directory effectively meant one active line of work. Lanes remove that restriction. Each lane has its own agent links, switch history, checkpoints, and pending context. Lanes cannot see one another, so I can keep two sessions open in separate terminals without their conversation state colliding. The basic commands are: bridge lane lists lanes, with the most recently active one first. bridge lane new <name> creates an empty lane and switches to it. bridge lane switch <name> moves to another lane. bridge lane rm <name> --yes removes a lane. bridge lane rm <name> --dry-run shows what would be removed first. Running bridge without a lane argument resumes the last active lane. That keeps the feature out of the way when it is not needed. A project with only one lane can continue working exactly as before. What lanes isolate, and what they do not Lanes isolate context. They do not isolate the working tree. Every lane still uses the same checkout and sees the same files. This means lanes support parallel conversations, not parallel code changes. Two agents editing the same working tree can still interfere with one another. Worktree-backed lanes may come later. They are not part of this release, and context-bridge does not pretend otherwise. Resuming and seeding lanes bridge <agent> --resume can now open a lane directly. Without an argument, it shows a lane picker. A new lane can also start with context from an existing one: bridge lane new <name> --seed <source> A seed is a briefing, not a copied session. It carries the source lane’s decisions, open questions, Git state, and touched files. It does not carry the conversation or any agent session links. The seed is delivered to the first agent that opens the new lane. If that launch fails, the seed remains available for the next agent instead of being lost. Cleaning one lane without damaging another The --lane option now scopes clean and inspect to a specific lane. Protection still checks every lane before removing shared checkpoints. A checkpoint cannot be pruned while another lane still depends on it. This distinction matters because lane-local cleanup still operates inside project-level storage. Unlinking one agent safely Previously, relinking could mean removing the entire .bridge/ directory and starting again. Version 0.12 adds: bridge unlink <agent> This removes one agent’s link without affecting the others. Unlinking also leaves a tombstone behind. If that agent is later started directly, its stale hooks become complete no-ops. They cannot silently reconnect the old session or consume a delta intended for an active one. The tombstones are cumulative. That detail came from a bug found during the final review. Storing only one tombstone meant unlinking a new session could erase the marker for an older one, allowing the older session to become active again. Unlinking one session must never revive another session that was unlinked earlier. Reviewing the trust boundaries The final review focused heavily on file and lifecycle safety. Every place that reads, writes, lists, or deletes a checkpoint now rejects paths that escape .bridge. The same checks reject paths that pass through symlinked directories. Pruning validates every lane before deleting anything. The lane seed and unlink flows received the same treatment, including: Concurrent binding attempts Partially created lanes Oversized seeds Failed agent launches Seed recovery after a launch failure Stale hooks from unlinked agents Cumulative tombstones across multiple sessions Most of this work was not visible in the original feature list. I planned to add OpenCode. Supporting it under real usage exposed assumptions that had survived because the first four agents happened to fit them. The fifth agent did more than expand compatibility. It forced the handoff machinery to become safer for every agent already supported. ## Building context-bridge with context-bridge URL: https://dogrubakar.com/blog/building-context-bridge-with-context-bridge Version 0.12.0 was built and reviewed by five coding agents passing the same session between them through context-bridge. Claude Code, Codex, Grok, Antigravity, and OpenCode all worked on the release. They implemented changes, reviewed one another’s work, challenged findings, and verified the fixes. This was not a staged demo. It was the actual development process, and when a handoff failed, it interrupted my own work. That was the point. Why pass the review between agents? The usual way to get a second opinion from another model is to open a new session and explain the problem again. That sounds simple, but a summary rarely contains everything that matters. The new agent does not know which ideas were already considered, which constraints cannot be changed, or why an obvious solution was rejected two hours earlier. It reviews your description of the work, not the work as it actually happened. With context-bridge, I could hand over the active session instead. The next agent received the decisions, failed attempts, unresolved questions, and current state of the repository. It could disagree with the work from inside the same context rather than reacting to a condensed version of it. The difference was obvious. Reviews became more specific. Agents stopped recommending tests that already existed. They did not repeatedly suggest designs that had already been rejected, because the reasons behind those decisions travelled with the session. That made their disagreements much more useful. The final bug The last important issue was found in the tombstone logic. Tombstones are what make bridge unlink safe. When an agent is unlinked, context-bridge leaves a marker behind so stale hooks from that agent become complete no-ops. If this goes wrong, an agent started directly outside the bridge can silently adopt an old session again. It can also consume a delta intended for a session that is still active. The implementation stored a single tombstone marker. That was the bug. Unlinking one session could overwrite the marker for another session that had been unlinked earlier. Under the right conditions, the older session could then become eligible for adoption again. What we actually needed was a cumulative set of tombstones. All five agents flagged the same problem independently during the final holistic review. That mattered more to me than any individual finding. One model saying something looks wrong can still be noise. Five independent agents pointing to the same failure mode deserves immediate attention. The bug was fixed, then reviewed again by all five agents before the release. What I would not claim I would not claim that five models are automatically smarter than one. Many of the reviews overlapped. Some findings were wrong. Others were technically possible but irrelevant in practice. A few were delivered with much more confidence than they deserved. The value did not come from collecting more opinions. It came from giving each agent enough context to form a useful opinion, then comparing where they agreed, where they disagreed, and how they failed differently. Independent agreement increased confidence. Disagreement increased coverage. Human judgment was still required throughout the process. It was not free either Every switch has a cost. Another CLI has to launch. The session has to move. The next agent needs time to inspect the current state. A complete review round across five agents is slower than reading a small diff yourself. For a simple change, I would not do it. Version 0.12.0 touched trust boundaries where failures could remain silent and affect someone else’s repository. In that case, the extra review time was worth it. The bugs that unit tests did not find The most valuable failures appeared only because I was using context-bridge for real work. The first handoff to OpenCode hit E2BIG. One Claude-to-Codex handoff was recorded as delivered even though Codex never received it. An orphaned discovery server left a TUI connected to stale state. These were not missing assertions in a unit test. They were failures at the boundaries between processes, CLIs, session state, and real usage. They appeared when I was in the middle of a task, switched agents, and discovered that the context I needed was not there. Using the tool to build the tool forced those failures into the open. That is still the review pass I trust most: the one where I am the user, and the cost of the bug reaches me before it reaches anyone else. # Notes ## Newest is not mine URL: https://dogrubakar.com/notes/newest-is-not-mine The bridge picked the wrong OpenCode session. It picked the newest one. That was the bug. OpenCode keeps every session in one SQLite store, filed by directory. Anything can leave a session there. An app making its own model calls in your working folder leaves dozens. So "the newest session in this directory" stopped meaning "my conversation" and started meaning "whatever ran last". Recency was standing in for ownership. It works until something else shares the namespace. Then it fails silently, and it fails toward the most recently active wrong answer — which is the one that looks most alive. Newest is a proxy for mine. It is only ever a proxy. The fix wasn't a better heuristic. It was reading a mark that already existed. Every handoff the bridge delivers writes a message with a msg_bridge_* id. Every session it creates carries a ses_bridge* id. Both had been there for weeks. Nothing had ever looked at them. If you write into a store you don't own, stamp what you create. Then, when you need it back, don't ask which one is newest. Ask which one is yours. ## Late is not lost URL: https://dogrubakar.com/notes/late-is-not-lost The first handoff into OpenCode didn't arrive. It waited until a session existed. That's a real bug. It's fixed. But it was never a data loss bug. Only a delivery bug. That distinction wasn't luck. Weeks earlier, I broke a Claude → Codex handoff in exactly the opposite direction. The launcher treated a spawned process as a successful delivery. The delta was immediately marked .consumed. The prompt never reached the model. There was nothing left to retry. No state to recover. No way to know the handoff had failed. That bug changed one rule. A delivery is committed when the destination accepts it. Not when something starts. That single decision changed how every future failure behaves. The OpenCode write couldn't succeed. So nothing was committed. The delta stayed pending. The handoff was late. Not lost. One bug decided the fix. The previous bug decided the failure mode. That's why commit points matter. They don't prevent the next bug. They decide whether the next bug costs a retry — or costs the work. ## No session, no message URL: https://dogrubakar.com/notes/no-session-no-message I was writing into someone else's database. I read the schema. I understood the tables. I made the insert. It worked. What I missed wasn't how to write. It was when writing was actually possible. In OpenCode, a message doesn't simply reference a session. It depends on one existing first. That's more than a foreign key. It's a timing constraint. There is no first message without a conversation to belong to. Every test I ran already had a session. Every manual switch I'd done already had a session. The one scenario I hadn't exercised was the one every new user would hit first. The very first switch. That was enough. If you're writing directly into another tool's database, don't stop after understanding the schema. List every foreign key. Then ask a different question. Can this relationship be unsatisfied at the exact moment I need to write? Those answers are where first-run bugs usually live. The schema tells you what the data looks like. The first run tells you whether it can exist at all. ## Use the real tool, not the side door URL: https://dogrubakar.com/notes/the-real-tool-not-the-rescue-path Mid-flow, it is tempting to reach for whatever glue moves the work instead of the tool you are building. While building the review chain for 0.12.0, my agent handed a review to Codex through a rescue path — a separate mechanism that got the context across. It worked. It was faster. I stopped it immediately and made every round go through bridge handoff codex instead. The side door was not the bridge. It skipped the machinery that picks the right session, computes the delta and records delivery honestly — which is the entire product. Two things follow. The tool you ship is the tool you should run: if my own reviews never performed a real handoff, a broken handoff would first appear in a stranger's repository. And the shortcut lies. It makes the demo smooth by avoiding the fragile parts, and the fragile parts are where the bugs live. Use it even when it is slower. Especially then. ## Why tombstones have no age cap URL: https://dogrubakar.com/notes/why-tombstones-have-no-age-cap Unlinking an agent leaves a tombstone, so that agent's stale hooks become no-ops and a session started outside the bridge can never silently revive. Every unlinked session id joins the set and stays. The obvious objection is that the set grows forever. Cap it — drop the oldest, or prune anything older than a day. I decided against a cap, and the reason is not tidiness. A cap has to decide that a tombstone is dead, and it cannot know that. It knows an id was rejected once. It does not know whether the agent behind that id is still running, still listening. Prune a live one and the exact failure the tombstone exists to prevent comes back, silently, at the worst moment. A tombstone is not memory waiting to be reclaimed. It is a lock. Growth is one id per deliberate unlink, and a deliberate relink retires it — linear with slow, careful human actions. A lock you forget to shut is not a lock. ## A code fix goes back for review URL: https://dogrubakar.com/notes/a-code-fix-goes-back-for-review My review chain runs on one rule. If a reviewer's finding is about a test or a comment, I fix it and move on. If it is about code, I do not commit — it goes back for another review. A review is only a statement about the code the reviewer last saw. The moment the implementation changes, the verdict stops applying: they approved something that no longer exists. Skipping the re-read is how an approved commit ships a bug nobody looked at. This is not ceremony. Codex approved the first tombstone fix, then found a hole in the other direction: in legacy state a deliberately relinked session would not clear its old marker, so a legitimate session stayed blocked. I changed the code, added two regression tests, bit the first one — and handed it back. Codex re-read it and returned clean. A review is a promise about reviewed code. Do not let the code move underneath the promise. ## Make the test bite URL: https://dogrubakar.com/notes/make-the-test-bite A test that cannot fail proves nothing. Before I trust a regression test, I put the bug back, run the suite, and watch the test fail. Then I restore the fix and watch it pass. A green suite only tells me the code and the test agree right now. Making the test bite tells me they hold together under attack: remove the fix, and the assertion falls. The tombstone fix in context-bridge is the one I keep coming back to. It turned a single marker into a cumulative set, and the test was the exact failure: unlink A, link B, unlink B, and both must stay rejected. I reverted the fix, and the test dropped — A was forgotten, precisely as the bug described. If step two does not fail, stop. Usually it means the test was written against my idea of the fix rather than the behaviour that broke. That is a different bug, and the bite catches it too. ## Enforce the rule where it is declared URL: https://dogrubakar.com/notes/enforce-the-rule-where-it-is-declared Each agent adapter in context-bridge declares the CLI flags that would break a resumed session — seven for Grok, four for Antigravity. Declaring them was the easy part. The filter that dropped those flags read from its own list somewhere else in the codebase. Two sources for one fact, and only one of them was updated when an adapter changed. The declarations were right, the enforcement was stale, and nothing complained: the flags were still listed, still documented, still wrong. The filter now reads each adapter's own conflictFlags, with a test proving the flag an agent declares is the flag that gets dropped. A rule enforced somewhere other than where it is declared is not a rule, it is a copy — and copies drift silently, because nothing is watching the gap between them. ## The first one is the unbounded one URL: https://dogrubakar.com/notes/the-first-one-is-the-unbounded-one Every delta context-bridge sends is clipped to fit: summary first, as much conversation as there is room for, the rest parked in a checkpoint the delta points at. I was careful about that budget. Except on the first switch, which had no previous watermark and therefore inlined the whole conversation. On a small session you never see it. On a large one it becomes a multi-megabyte string passed as a single command line argument, spawn throws E2BIG, and the agent simply never starts. That is how the first live switch to OpenCode died. The first case is the one that skips the machinery, because when you write it the machinery does not exist yet. Now the first switch is bounded like every other. Worth asking of any pipeline: what does the empty-state path skip that the steady-state path does? ## A hook delivers context, not a turn URL: https://dogrubakar.com/notes/a-hook-delivers-context-not-a-turn Claude Code and Codex both take their handoff through a SessionStart hook. It is the cleanest road in — the delta arrives inside the conversation, with nothing pasted in front of it, and I was pleased with how quiet it was. Too quiet. The agent came up holding the entire context and with nothing to answer, so it sat there. Every switch ended with a human staring at an idle prompt, typing something like "go on" to wake it up. The context had arrived perfectly and the work had stopped. Both agents now get a one-line opening prompt whenever delivery went by hook. It carries no delta of its own, so a handoff can never land twice. Loading the state and starting the turn are two different jobs, and I had only built the first one. ## Delivered means answered, not started URL: https://dogrubakar.com/notes/delivered-means-answered context-bridge used to record a handoff as delivered the moment the target agent's process started. That is the obvious place to put it: the spawn either works or it throws, and if it worked the agent is running. But a CLI that ignores its prompt spawns exactly like a CLI that reads it. Same exit code, same timing, same everything. I lost a real Claude to Codex handoff that way. The bridge had marked the delta consumed, the watermark moved, and Codex opened knowing nothing. Nothing failed loudly enough to notice. Delivery now commits on the target's first activity, not its first breath. An agent that starts and says nothing leaves the delta pending and retryable. The general shape: if the receipt you record is the one you can observe rather than the one that matters, you will eventually record a lie. ## The third time, a script does it URL: https://dogrubakar.com/notes/the-third-time-a-script-does-it I have one rule for automation, and it is a counter, not a philosophy. Do it once by hand: fine. Twice: annoying, still fine. The third time, a script is already doing it, because by the third repetition I know the task's real shape, its edge cases, and whether it deserves to exist at all. Automating on the first repetition is how you end up maintaining scripts for tasks that never came back. Waiting past the third is how you become the script. The counter also decides how much to invest: a third-time task gets a shell one-liner, a weekly task gets error handling, a daily task gets logging and a place in the scheduler. Most of my projects started as this counter hitting three. The mail radar, the deploy scripts, the content pipeline, both open source tools. None of them began as an idea for a product. They began as the third repetition of something I was tired of doing. ## Constraints are a feature URL: https://dogrubakar.com/notes/constraints-are-a-feature The content pipeline behind my daughter's story brand runs on a single MacBook. Local image generation, local TTS, local orchestration. Cloud GPUs would work fine. I keep it local because the constraint forces discipline. When every render costs disk, RAM and minutes on your own machine, you stop generating fifty variations to pick one. You write the scene description properly the first time. You build a keyframe engine that carries character identity across scenes instead of re-rolling and praying. That zero-cost constraint produced better engineering than an unlimited budget would have. There is a second benefit. Everything about the pipeline is inspectable. No API changed under me overnight, no model got deprecated, no bill arrived. For a side project that has to survive being ignored for three weeks, boring and local beats powerful and rented. ## Watch-only by design URL: https://dogrubakar.com/notes/watch-only-by-design para-radar collects Turkish lira yield opportunities: money market funds, deposit campaigns, daily interest accounts. It compares everything net of tax and pings me when idle cash could be doing better. The most important feature is missing by design. It cannot move money. Not "does not yet", cannot. There is no execution path, no credentials with write scope, nothing to fat-finger at 2am. That is a deliberate line. The value is in the watching: normalize messy rates from a dozen sources, apply the right tax treatment, compare like with like. The moment a personal tool can also act, every bug becomes a financial incident and every refactor needs a risk review. Read-only keeps the blast radius at zero and the development speed at maximum. ## Shadow mode first, always URL: https://dogrubakar.com/notes/shadow-mode-first-always I run an autonomous agent that posts market commentary to X. Before it was allowed to publish anything, it ran for weeks in shadow mode: full pipeline, real data, real generated posts, and a dead switch at the end so nothing left the machine. That period paid for itself. It caught repetitive phrasing that would have read as spam, a stats source that went stale on weekends, and a tone drift problem that only showed up across dozens of consecutive drafts. None of that is visible in a single manual test run. The rule I keep now: any system that acts in public earns that right by first producing output nobody sees, at production volume, for long enough that the boring failure modes show up. The boring ones are the ones that get you. ## Moving 15 years of email without a gap URL: https://dogrubakar.com/notes/moving-15-years-of-email-without-a-gap dogrubakar.com lived on free Yandex mail for years, until it went read-only behind a paywall. The move to Google Workspace had one hard requirement: not a single lost email, not an hour of downtime. Order matters more than tooling here. First the identity: create the mailbox on the new provider and confirm it accepts mail. Only then the MX cutover, because pointing MX at a server that does not know your address yet bounces real mail. Then SPF in the same breath, DKIM as soon as the provider allows it, and only after all of that, the old mailbox import over IMAP, which is a background job that can take days and does not care. The part nobody tells you: the old provider will throttle your IMAP export to a few hundred messages an hour. Plan for the copy to take days, not minutes, and let it. New mail is already flowing to the new home; the archive can walk. ## One agent file, many opinions URL: https://dogrubakar.com/notes/one-agent-file-many-opinions I did not want three review agents for three CLIs. I wanted the agent I already tuned for Claude Code to run everywhere. That one constraint shaped multi-agent's architecture. The core normalizes an agent definition into a portable form and maps its tools onto a neutral capability vocabulary: read_files, search_repository, run_shell. Each adapter maps those capabilities onto its own CLI's native tool names. Tools that cannot be mapped are reported, never silently dropped. The core never learns about a specific model, so every quirk lives in one adapter file. The payoff is that diversity comes free. Same agent, same instructions, three different models reading the same code. When they converge on a finding, I trust it more. When they diverge, I have coverage I would not have had alone. ## Score the models, but do not tell them URL: https://dogrubakar.com/notes/score-the-models-but-do-not-tell-them multi-agent's arena ends with a scoreboard: which model found real bugs, which one hallucinated, which one conceded gracefully. The design decision that matters is that the models never know they are being scored. Once a model knows it is in a competition, the incentives rot. It defends a weak finding because withdrawing looks like losing. It nitpicks rivals to farm points. The debate stops being about the code. So the scoring happens afterwards, from the judge's confirmed results: confirmed findings add points weighted by severity and false positives subtract. Unique real catches add extra, and an honest concession the judge agreed with counts too. The models argue about truth; the ranking is computed behind their backs. Goodhart's law hits language models as hard as it hits people. ## Let the debate stop itself URL: https://dogrubakar.com/notes/let-the-debate-stop-itself The first version of multi-agent's arena ran a fixed number of rounds. Three models, four rounds, every time. Half of those rounds were theater. By round two nobody was changing position, they were just saying the same thing with more tokens. Now the rounds are convergence gated. You set a minimum and a maximum, and the arena adds another round only while positions keep moving: someone withdraws a claim, adopts a rival's finding, or raises a new one. The moment the debate freezes, it ends and the judge takes over. Fixed iteration counts are a smell in any adversarial process. If nothing changed in the last round, the next one is a waste of tokens. Measure movement, not laps. ## Send the delta, not the transcript URL: https://dogrubakar.com/notes/send-the-delta-not-the-transcript The lazy way to move context between two coding agents is to copy the whole conversation. It is also the wrong way. A transcript is large, it repeats what the target already knows, and it buries the two sentences that matter. context-bridge keeps a small knownBy matrix: for every pair of agents, how far into each agent's stream the other one has been told. A handoff sends only the missing part, in four bounded sections: Conversation, Decisions, Work, Next. The receiving agent spends one short sentence acknowledging it. That is the entire overhead. Reconciliation is my day job, and those systems do not resend the ledger. They send the diff since the last watermark. Agent handoff has the same shape. ## Vendor session formats break silently URL: https://dogrubakar.com/notes/vendor-session-formats-break-silently The worst bug in context-bridge was not in my code. Every handoff reported success and carried an empty delta. Claude Code, Codex and Grok keep their sessions in internal files. Nobody documents them and nobody owes you stability. Fair enough, they are internal files, not a public API. But context-bridge reads them anyway. Then a point release renames one field and nothing looks broken: the binary still runs, auth still works, and bridge handoff reports success. That is the failure mode I hate most, because everything looks alive from the outside. So bridge doctor got a check nobody asked for. It does not check whether Claude is installed or Codex is logged in. It opens each vendor's session files and confirms that this version of the bridge can still parse them. It exists because this failure stays invisible until you notice that a week of handoffs carried nothing. What I keep from it: when you build on another product's internal files, "installed and logged in" tells you nothing. Test the data you depend on, not the binary that writes it.