ddkc://swarm

DREAM.OS · OPERATOR LOG ·

I Gave My AI Agents a Delete Button...
Then GitHub Said No.

A Dream.OS devlog about branch cleanup, GitHub Architect, stale CI evidence, and why safe autonomy needs the ability to stop.

Victor Dixon · September 7, 2026

I’ve been trying to get my repositories under control.

Not in the “make everything look pretty on GitHub” sense. I mean actually knowing what work is finished, what is still active, what needs to be salvaged, and what can safely disappear.

Because at one point, I had branches everywhere.

A branch for an audit. Another branch to reconcile the audit. A recovery branch for the reconciliation. A temporary branch that was somehow still alive three weeks later. Then another agent would come along, see a branch name that looked important, and start building on top of it.

You can probably see where this goes lol.

The problem wasn’t just the branch count. It was that I was becoming the only person who could remember what all of those branches meant.

And that is exactly what Dream.OS is supposed to fix.

The cleanup was actually working

We had already been doing a lot of repository reconciliation. Useful code was getting promoted, duplicate implementations were being compared, and old branches were being classified instead of blindly deleted.

The earlier audits were ugly. Agent_Cellphone had 28 branches at one point. DreamVault and TradingRobotPlug both had large piles of old work. There were also branches that looked stale but contained unique code, so deleting everything older than 30 days was never going to be a real solution.

This time, I wanted to look at the current remote state and figure out where the worst violations actually were.

The first big finding was that the portfolio had improved more than the old reports made it look.

Dream.os-Core was down to just master. Agent_Cellphone had gone from 28 branches to four. TradingRobotPlug still had a bunch of refs, but most of them had already been merged or proven contained.

That changed the problem.

We weren’t dealing with 100 different implementation decisions anymore. A lot of the remaining mess was just the final cleanup step.

The permission bottleneck

For a while, the workflow looked like this:

An agent would audit a branch, prove it was merged, check the SHA, prepare the cleanup request, and then tell me to run the actual delete command.

Which is safe, but it also means I’m still the last-mile executor for something the system already knows how to verify.

So we worked on the GitHub Architect remote branch executor.

The request is SHA-locked. It checks branch protection, PR ownership, whether the work was actually merged or contained, and whether the branch changed since the audit. Then it deletes the ref, verifies that GitHub no longer has it, and publishes a durable receipt.

That is a much better contract than “the AI thinks this branch is old, so delete it.”

We finally got a real end-to-end proof. A merged GitHub Architect branch was deleted through the VPS executor, GitHub returned 404 for the deleted ref, and the receipt was committed to master at 74c9b4b.

The deletion itself worked.

Naturally, the receipt had a bug. =p

Its receipt_publish.ok field still said false because it had captured the first failed commit attempt, before the VPS Git identity was configured. The retry succeeded and the receipt was durable, but the final status field never caught up.

That is a useful distinction: the operation succeeded; the reporting layer was wrong. We do not need to redo the deletion or rewrite history. We need to preserve the failed attempt and record the final publication result correctly.

Then TradingRobotPlug was suddenly clean

With the executor proven, I wanted to go after TradingRobotPlug’s 11 already-contained branches.

This seemed like the perfect demonstration: take a known-safe batch, revalidate everything, let Architect delete the refs, and verify the receipts.

But when we checked GitHub again, TradingRobotPlug had already moved on.

It was down to just master.

So we did not submit another deletion batch just because that had been the original plan.

That is an important behavior I want Dream.OS to have: reality wins over the task list.

If the task says “delete these 11 branches,” but the live repository says they are already gone, the correct action is to close the task—not try to execute the old plan anyway.

DreamVault was a different kind of mess

Next was DreamVault.

The live census showed 17 refs, including master, with 12 open PRs. Once we classified them, most belonged to active HQ, planner, or salvage work. Three were active or unique-work holds. One was a recently merged branch still inside the retention window.

There was also the captain-governance branch, which had a huge divergent history. We had already selectively promoted useful hygiene capabilities from it, but that did not mean the entire original branch was safe to delete.

That one stays in forensic review.

I do not want a cleanup agent looking at a 2,590-commit branch and deciding, “Well, some of this was merged, so I guess we’re done here.”

Nope.

We recorded the actual branch dispositions in DreamVault’s planner instead. No deletion was needed, and no new cleanup branch was created just to describe the cleanup.

Websites sent us down the CI rabbit hole

Then we moved to the websites repo.

This one needed more care because it backs actual production sites. A branch can be contained in Git and still matter because a live deployment, local-only source, or dirty worktree depends on it.

The audit found 11 refs: master plus 10 branches. Seven were ancestry-contained, while three still had unique work.

One was the heart-to-heart blog PR. Another contained the infrastructure journal. The third was a divergent production-preservation branch.

The heart-to-heart PR had another problem: its description said GitHub Actions could not start because of the old hosted-runner billing/quota issue.

That reminded me of something we had already planned.

Weren’t GitHub Actions supposed to be moving to the VPS?

Turns out, yes—but websites had not actually completed that migration.

The primary workflow was still using ubuntu-latest for validation and deployment. DreamVault had a VPS runner configuration, but that did not prove websites was registered or isolated correctly to use it.

So the migration gap was real.

The CI outage claim, though, was stale.

We checked the actual runs and found that websites main CI had succeeded on September 7 with all 16 validation steps passing. PR #135’s exact head also had successful main CI and blog-style checks from September 5.

That meant the old “CI cannot start” explanation was no longer valid.

It did not mean the PR was automatically safe to merge.

The part where I asked Architect to merge it

At that point, I wanted to see the actual governed merge-and-delete path in action.

The goal was straightforward: resolve the websites PR, merge it, and retire the source branch through GitHub Architect.

We checked the current PR state, reviewed the content scope, and attempted a SHA-locked merge.

GitHub rejected it.

HTTP 405: merge conflicts.

Which, honestly, is exactly the kind of thing the governance system is supposed to catch.

The correct response is not to force the merge, ignore the conflict, or delete the branch because the user said “proceed.”

The correct response is to preserve the branch, identify the conflict, resolve it against the current canonical source, run the required checks, and only then merge.

We recorded that work in GitHub Architect issue #7, including the merge and branch-retirement contract.

We also connected the Dream.OS Control Plane integration, which exposes the governed GitHub Architect branch-operation tools.

That is where this session closes: the Control Plane is connected, the remediation task exists, the PR is still conflicted, and no one should be claiming that the merge or deletion happened yet.

What I’m actually trying to build

The bigger lesson from all of this is that autonomy is not just giving an AI more permissions.

It is giving it a way to know what it is allowed to do, what evidence it needs, and when it should stop.

I want Dream.OS to be able to look across my repositories and say:

“This branch is merged and past retention. I can prove its SHA is unchanged. No active PR or worktree depends on it. GitHub Architect authorizes deletion. I’ll execute it, verify the ref is gone, and record the receipt.”

And I also want it to say:

“This branch has unique work.”

“This PR is conflicted.”

“This deployment source is not reconstructable from master.”

“This CI failure is historical, not current.”

“This task is already complete.”

Those are all useful outcomes.

A system that only knows how to say GO is not autonomous. It is just dangerous with a scheduler.

The goal is to make the boring operational work reliable enough that I do not have to keep carrying the entire state of the system around in my head.

What comes next

The immediate next step is to finish websites PR #135 conflict remediation through the connected Control Plane, verify the new exact head, and let GitHub Architect handle the merge and eventual branch retirement under its policy.

Separately, websites still needs the VPS CI migration completed. That should reduce hosted Actions dependence without weakening checks or exposing production credentials to untrusted code.

And the larger branch-cleanup campaign continues with the same rule: classify first, salvage unique work, promote what belongs in canonical, and delete only when the evidence actually supports it.

We have made real progress. TradingRobotPlug is clean. Dream.os-Core is clean. Agent_Cellphone is dramatically better than it was. DreamVault and websites are no longer just mysterious piles of branches; they have explicit dispositions and next actions.

There is still work left, but the shape of the problem is changing.

I am spending less time asking, “What the hell is this branch?”

And more time asking, “What evidence does the system need to close this safely?”

That feels like the right direction.

Now I just need the agents to stop creating three new branches every time we clean up one. lol