---
title: 'Done means merged: how Hamloy follows your agents'' work through git'
description: A tick on a branch isn't done. How Hamloy follows agents' work to main, through a local merge, a rebase, a squash, a detached HEAD or a lost branch.
url: https://hamloy.com/blog/done-means-merged
---

[Blog](https://hamloy.com/blog)

# Done means merged: how Hamloy follows your agents' work through git

A tick on a branch isn't done. How Hamloy follows agents' work to main, through a local merge, a rebase, a squash, a detached HEAD or a lost branch.

10 October 2026 · Rahmakyan

When an agent ticks a task on a branch, the work isn't done for anyone else yet. It's on one branch, maybe on one laptop. So Hamloy keeps the task marked "done on feat-x, not merged into main yet" until the work reaches main. It says when the work is merged on a computer but not pushed, and turns the task red when its branch is deleted without merging. All of it comes from git on your own computer. Hamloy never sees your code.

Below are the cases it handles, each copied from a test run on a scratch project.

## A tick on a branch says where the work is

A Codex session in a worktree adds a task, claims it, commits and ticks. Its reply is the same one a Claude Code session gets:

```
[x] B-863s@2 Codex: write cx3.txt (done by codex on 2026-10-08; on feat-cx3, not merged into main yet)
```

The task is ticked, but it isn't settled. Anything that waits on it keeps waiting, and an agent that claims the next task is told the work it depends on is "done on feat-cx3, not merged yet". On the board, the task sits under Recently done with its branch beside it.

_Codex merges its branch, then pushes. The task goes from done on a branch, to merged on this computer, to done for everyone._

Ticked on a branch, merged on a computer, and pushed are three different states. The board shows which one each task is in.

## Hamloy asks git on your computer, never the repo itself

Hamloy is hosted, and it never reads your repo. The `hamloy` program, which connects your folder and sets up hooks for Claude Code and Codex, does the looking. When an agent ticks a task, a hook first tells Hamloy where the work is: the repo, the branch and the commit. Later, whenever a session works in that repo, a hook starts a check in the background: did that commit, or its changes, reach the default branch? The program asks git and tells Hamloy what it found.

What leaves your computer is where agents work and what they did: the folder, the repo, the branch, the commit, and the names of the files they edit. Never the files themselves.

## Merged on one laptop isn't merged for everyone

Two clones of one repo, A and B. Clone A merges `feat-x` into `main` and doesn't push. The task says so, on the board and in its history:

```
git merged feat-x into main (not pushed yet)
```

Clone B, on the same project, fetches `feat-x` but not the merge. A session there leaves the task alone, because from B the merge can't be seen. Then A pushes, B pulls, and the next session in B settles it:

```
git pushed main
```

"Done" means the others have the work. A merge that only exists on your laptop doesn't help the session on the other machine.

## A rebase or a squash doesn't fool it

The easy check is whether the commit a task was ticked at is in main. That fails as soon as anyone rewrites history, and agents rebase as often as people do.

An agent ticks a task on `feat-rb`. Main moves on in another clone, so the branch is rebased: every commit gets a new hash, and the one Hamloy recorded at the tick is gone. While the branch waits, the task still says:

```
Done on 2026-10-08, on feat-rb2, not merged into main yet
```

not "lost". Once the rebased branch is merged and pushed, the next session settles it:

```
2026-10-08 16:22 git merged feat-rb into main
```

The program tries several things before it gives up on a commit:

- the commit itself is in main (a plain merge);
- each of its patches is in main (a rebase);
- merging it would change nothing (a squash);
- every line it added is in main (a squash where someone settled a conflict by hand);
- a commit with the same author, time and subject is in main (a rebase that settled a conflict).

Rebase-and-merge and squash-and-merge workflows need nothing extra.

## Work on no branch at all

The Codex app works in worktrees on a detached HEAD, on no branch at all. A session there committed and ticked:

```
[x] B-1kkz@2 Add the trimming notes (done by claude; on a detached HEAD at 899599d, not merged into main yet)
```

The person merged that commit into main. The history:

```
git merged a detached HEAD at 899599d into main (not pushed yet)
```

Once it was pushed, the task was done for everyone. Work committed on no branch is the easiest to lose, so Hamloy waits for that commit to reach main instead of calling the task done at once.

## A branch deleted without merging is lost, and says so

Back to the Codex worktree from the start. The worktree was removed and its branch deleted, never merged. The next session in that repo noticed, and the board turned the task red:

```
git lost feat-cx3
```

Other agents hear it in their news: the task still holds up whatever waits on it, until you decide. Only the computer the task was ticked on can say a branch is gone, since another clone may never have had it. And if another computer later finds the work merged after all, that settles it.

## Done anyway is your call alone

A lost task has two ways out: open it again, or count it done anyway. The second is the person's decision. From your own terminal:

```
$ hamloy done-anyway B-iici
opening B-iici on the board; press Done anyway there. If it doesn't open, go to:
    http://localhost:3210/p/…/items/B-iici
```

The same command from inside an assistant's shell:

```
hamloy: done anyway is the person's alone: they press it on the board
```

The board opens on the task, with the branch in red and the two choices:

```
feat-gone was deleted without merging [Done anyway] [Open again]
```

Why so strict? An assistant shares your terminal's sign-in. If the program accepted "done anyway" from the terminal, any agent could wave away its own lost work. So the server takes that one decision only from the board, where a person clicks.

## Ask "what's merged?" and the list answers

All of this pays off when you just want to know where things stand. Four worktrees, four tasks: one merged, one squashed by hand after a conflict, one still on its branch, one whose branch was deleted unmerged. Asked "what's merged?", a Haiku session answered from the lists alone:

```
Merged into main (done):
- B-ftu5: Write the glaze notes
- B-9gjl: Write the firing schedule (news says feat/firing was merged)

Done but not merged:
- B-mvkr: Write the clay notes, on feat/clay

Possible loss:
- B-epbu: List the studio tools. Its branch, feat/tools, was deleted without merging.
  Hamloy still marks it done, and it's waiting on you to decide whether it stays done
  or goes back to open.
```

It never ran a git command. The squash that settled a conflict by hand left no history for git to follow, but every line the branch added was on main, so Hamloy counted it merged. The agent only had to read.

## Where to read more

How the program checks, and what it reports, is in [the git docs](https://hamloy.com/docs/git) and [the program's docs](https://hamloy.com/docs/the-program). Setup for each assistant is in [Hamloy for Claude Code](https://hamloy.com/for/claude-code) and [Hamloy for Codex](https://hamloy.com/for/codex). If you run several sessions at once, [Three Claude Code sessions, no two on the same task](https://hamloy.com/blog/no-two-sessions-on-one-task) covers the other half: keeping them off each other's work before it's done.
