Tree-of-Life and Evolution of Code

gritzko1 pts0 comments

Tree-of-life and evolution of code

Beagle SCM

Tree-of-life and evolution of code

Darwin's First Notebook on Transmutation of Species, 1837

Beagle is a git-compatible SCM for modern workflows. Fundamentally, it is the same commit-tree-blob model, but the higher order constructs are tuned and rebalanced to make it a useful tool in coordinating a swarm of LLMs and steering their activity towards an objective.

My current workflow is aimed at mercilessly discarding unsuccessful tries, never losing track of useful changes. That was difficult with git. That is in general difficult: some lines of thought lead nowhere, some bugs get totally fixed several times and still appear, this list can go on. Some things you have to put aside till you have a solution, others are waiting for a blocker to resolve -- it gets Gantt complicated.

In general, running an LLM as a single-thread chat avoids these issues, but in that mode of work the LLM may or may not pay off. It tends to think slowly, may go off the rails, and either you reset the context or it gets progressively dumber after 200K tokens or so. Serializing things would probably help to keep it all orderly, but those gains were not x10. The interesting part is how to run it in parallel. Easy to start, but then you start losing track of things happening. This is exacerbated in a complex project with libraries and submodules.

Imagine a dozen LLMs poking into a large C codebase and rebuilding it all the time. In fact, I tried running Claude on a 10-year-old 2-core 4GB ThinkCentre. As most of the LLM work happens on cloud GPUs, why not? Got a dozen sessions running, everything worked till they started to build. I also have a 32 core 128GB Ryzen, but building a larger project still takes time and tests take even more. But each larger project consists of smaller parts.

The x100 improvement is to task LLM workers with a particular library or submodule. But then it blows up in a different place: you now have a zoo of submodule revisions and their web of dependencies. It multiplies further if you practice agent role separation: investigators, test writers, code writers, reviewers. Any step failing must be a transient issue. A bad coding run must not wreck the process. A coding agent must not be able to sneak in test changes. A reviewer agent declaring bug is "fixed" does not mean we rush a celebratory commit into the trunk. We have to mark that revision and actually try working with it. How? It all screams "revision control". But remember, we already had quite a sprawl. Now, how do we evolve this zoo?

That is the core idea, as you may see: managing lots of trees in parallel, mutating them towards the goal, discarding some, putting more attention on others. You may read the code, or you may not. You may have a huge test set, or you may not. You may practice role separation, or you may not. You may test your new medical code on yourself. Either way, you have some way of differentiating good from bad. Real-world evolution uses very blunt tools, as we know. The question is how to track a wide front of efforts, turning your attention to where it pays off the most.

So, this is how it now looks in Beagle:

`$ be work`

What is the model here?

It is all worktree-centric, but beagle worktrees qualify as refs, like branches or tags.

Beagle worktrees track other worktrees or branches.

If some worktree makes an interesting change, we may start forking child worktrees off it. So far, it did not exceed 3 levels here, but who knows.

Successful child worktrees get merged back. It may need several merge-backs to reach the trunk.

Merges across the tree branches are possible, most often even trivial, but so far working along the lines was more natural.

Can always postpone things, if some blocker is encountered, or there is some doubt, or need to check if it works.

How this UI works:

Each line is a worktree. The tree reflects upstream/downstream relationships.

Can click on any, navigate to the tree. Diffs, blames, all is there.

The shade of the line actually reflects the staleness of the tree's commit.

[-2] markers are ahead/behind counts, relative to the upstream (which is the parent in this tree). Clicking on [-2] updates the tree. Clicking on [+2] sends the changes upstream.

Beagle merges are token-level with some CRDT features, so false conflicts happen less often.

Worktrees are ticket-named for the most part. Tickets are one-click away, see the [?] button. In fact, Beagle does not use commit message body at all; commit subject references a ticket instead.

Discarding a tree is one button too: [done].

One may say, this tree is somewhat similar to the Linux "lieutenant" change filtering system git emerged from. Linus takes changes from his subsystem lieutenants, they aggregate changes from their downstream contacts, which in turn may take input from elsewhere. Maybe, maybe. Then, we made an interesting circle.

RSS feed<br>Beagle SCM GitHub<br>JAB runtime GitHub<br>BlueSky

tree beagle code worktrees commit changes

Related Articles