Branch-aware agent memory: what survives a merge or revert?

Branch-aware agent memory ties a claim to a repository, a revision and supporting evidence, then checks whether that evidence still supports the claim in the checkout where the agent is working.

An agent finishes a migration on a feature branch and records a useful finding: "The worker now uses the new queue." Another agent retrieves it while fixing the release branch. The sentence is accurate, recent and backed by a passing test. It is also wrong for the second agent's task.

This is a scope failure. Giving the note a newer timestamp, a better embedding or a higher retrieval score does not repair it. The missing question is: which version of the software does this claim describe?

Branch-aware memory needs an answer before it puts the sentence into an agent's working context. Here is a small way to make that requirement concrete.

A branch name is a useful label, but a revision is the reference

Suppose a fictional repository has two active lines of work:

main:                 queue = legacy
feature/new-queue:    queue = new

"The worker uses the new queue" belongs to the feature checkout. "The worker uses the legacy queue" belongs to main. Neither should silently replace the other in team memory.

A useful record would hold the repository identity, the commit inspected, the relevant configuration path, and the conclusion. Keep the branch name for people reading the record, but keep the revision as well: a moving branch label does not identify the exact tree someone examined.

For an agent working with uncommitted changes, even the commit is incomplete context. The working tree may already differ from it. Record that distinction, and inspect the current files before applying a claim about their behaviour.

Run the revert example

The following Bash example creates a temporary repository, changes one setting and reverts that change. It does not touch an existing project. It needs Git and Bash, and uses an example author only inside the temporary repository.

memory_demo_dir=$(mktemp -d)
cd "$memory_demo_dir"
git init -q -b main
git config user.name 'Memory Example'
git config user.email '[email protected]'
git config commit.gpgsign false

printf 'queue=legacy\n' > worker.conf
git add worker.conf
git commit -qm 'Use legacy queue'

printf 'queue=new\n' > worker.conf
git commit -qam 'Switch to new queue'
memory_change=$(git rev-parse HEAD)

git revert --no-edit "$memory_change" >/dev/null

if git merge-base --is-ancestor "$memory_change" HEAD; then
  printf 'The introducing commit is still an ancestor.\n'
fi
cat worker.conf

The output includes both facts:

The introducing commit is still an ancestor.
queue=legacy

Git's merge-base --is-ancestor tests reachability in history. git revert records a new commit that reverses an earlier change; it does not remove the earlier commit from history. That is why the ancestry check still succeeds.

For a memory system, the implication is direct: finding the commit that introduced a claim in the current history does not prove the claim is still true. In this example, reading the current configuration resolves the question. For a behavioural claim, the evidence may also include tests, calling code or deployment configuration.

What should happen at each checkpoint?

The table below is a proposed evaluation fixture, not a report of REM's measured performance. The claim under test is "the worker uses the new queue."

Repository eventEvidence to inspectAppropriate memory result
Change exists only on the feature branchFeature tree and its testSupported for that revision; do not apply it to main
Change is mergedResulting main tree, including conflict resolutionRecheck the claim against the merged result
Change is revertedCurrent configuration and relevant testPreserve the historical finding; withdraw it as current guidance
Configuration changes againCurrent value and affected behaviourReconcile the claim again rather than reuse the previous result
Agent edits the configuration locallyWorking-tree diff as well as HEADState that the checkout differs from the recorded revision

A merge is a reason to inspect the result. It is not a reason to copy every conclusion from every feature-branch session into main's current memory. Some of those sessions describe intermediate designs that never reached the merge.

Cherry-picks and squash merges need another link

Commit identifiers alone also struggle when the same work reaches another branch through a cherry-pick, or a set of development commits becomes one squash commit. The history may no longer contain the original identifier even though the relevant change is present.

Git documents cherry-picking as applying changes introduced by existing commits. Its merge documentation explains that a squash prepares the combined tree and index changes without recording the usual merge relationship.

For memory, treat the pull request, source commit and resulting commit as related evidence. Then check the target tree. Similar patches can help locate corresponding work, but they are not sufficient to establish equivalent behaviour: a release branch may have different dependencies or callers.

The useful unit is a claim with a traceable basis, not a sentence attached forever to one hash.

Keep historical reasoning available

Withdrawing a claim from current guidance should not erase the investigation that produced it. "We tried the new queue and reverted it" may be exactly the history the next migration needs.

Separate two retrieval questions:

  • What applies to this checkout? Return supported current guidance, with its scope and evidence.
  • Why did we make this decision? Return the historical sequence, including rejected approaches and the reason for the revert if it was recorded.

Do not invent that reason from the revert itself. A reverted patch establishes that the tree changed back; it does not establish whether the cause was performance, compatibility, timing or a product decision.

This distinction extends the problem in context rot in agent instructions. A memory can be stale because the code moved, or misplaced because it belongs to a different line of development.

A small acceptance test for any memory tool

Before evaluating how much a tool remembers, give it the same question at three checkpoints: before the queue change, after it, and after the revert. Then ask once more from a branch that never received the change.

Check the answer, the cited revision and whether historical information is presented as history. A useful failure report identifies which of those went wrong. "The agent remembered the queue migration" is too vague to tell whether it helped.

These fixtures test a narrower property than general agent intelligence: whether stored guidance follows the repository state. They complement retrieval tests rather than replace them, as discussed in agent memory and retrieval over a codebase.

REM, Reconciled Engineering Memory, is being built around this distinction. Its intended model keeps evidence immutable, versions claims, reconciles them against Git and other evidence, and compiles context for the task at hand. REM is in private beta; the example above is a reproducible Git demonstration, not a claim that every case is already solved by the product.

If your team works across long-lived release branches or related repositories, join the REM private beta with the cases where yesterday's useful finding became today's wrong instruction.