Keep the Why: Git-native project memory for coding agents

I’ve been working on an open source project called Keep the Why.

The problem I wanted to solve is pretty simple:

Coding agents are getting very good at understanding code, but across sessions they often lose the reasoning behind it.

A repository might clearly show what was implemented, but not necessarily:

  • why a particular approach was chosen

  • which alternatives were already rejected

  • which constraints influenced a decision

  • which workaround exists for a non-obvious reason

  • what was learned during an incident

That can lead to agents repeatedly proposing ideas that were already discussed and rejected.

Keep the Why stores this kind of project knowledge directly inside the repository as Markdown.

There is no database, daemon, account or hosted memory service involved.

The basic idea is:

conversation/session = working memory
repository = durable project memory

The context is versioned, reviewed and distributed through the same mechanism that already distributes the source code: Git.

How it works

A coding agent gets a small skill that teaches it when and how to read or write project rationale.

The repository contains a context/ directory with an index and individual rationale entries.

The agent does not need to load all context into every prompt. It first uses the index to decide what is relevant and follows references from there.

The same context can therefore be used by different agents and models instead of living inside one vendor’s memory system.

I’ve tested it across multiple coding agents and models.

The current evaluation suite contains more than 100 cases, including negative cases where the agent should not create or modify project memory.

Across the current agent/model matrix, almost all combinations correctly inspect the repository context before making decisions that could conflict with previous rationale.

I also ran a small controlled experiment around a deliberately tempting code change.

Without project memory, agents accepted the wrong change in several runs.

With the previous rejection and its reasoning stored in the repository, all tested sessions rejected it.

Interestingly, none of the agents knew about the previous decision without that project context.

It has grown a little beyond Markdown

There is now also a read-only dashboard that visualizes the reasoning as a graph and timeline.

Decisions can link to earlier decisions, related repositories and external projects, so the rationale behind a codebase becomes something you can actually navigate.

The dashboard is still derived entirely from the repository. It doesn’t become another source of truth.

Why I’m posting this here

I’m particularly interested in how this fits into the OpenAI / Codex ecosystem.

The project intentionally doesn’t try to replace session memory, user memory or agent instructions.

It is specifically about project-scoped knowledge that should survive sessions, users, agents and model providers.

I’d be very interested in feedback from people using Codex or other coding agents on larger or longer-lived repositories.

Especially:

  • Where do you currently keep this kind of rationale?

  • Do your agents actually consult ADRs, docs and Git history reliably?

  • At what point would a simple index stop being sufficient and require semantic search?

  • Should durable project memory even be considered “memory”, or is it better understood as another layer of repository knowledge?

The project is FOSS and the specification is open.

GitHub:
h**ps://github.com/oliver-zehentleitner/keep-the-why

Project site:
h**ps://keepthewhy.com/

Dashboard:
h**ps://keepthewhy.com/dashboard/live/

Specification:
h**ps://keepthewhy.com/specification/

I’d genuinely appreciate technical criticism, especially from people experimenting with persistent context for coding agents.

This is very close to what we have converged on in a long-running agent setup.

The distinction that mattered most for us was separating three things that are often collapsed into one “memory” bucket:

  1. evidence/history — what happened, what was observed, what was tried;
  2. current canonical state — what is true now for the project;
  3. promoted rationale — durable decisions or constraints that future agents should actively consult.

If every transcript fragment becomes durable memory, the repository eventually becomes noisy and contradictory. If nothing is promoted, each new agent has to rediscover the same decisions.

What has worked better is controlled promotion: keep raw evidence append-only, keep one current canonical state surface, and only promote decisions/constraints that have survived review or repeated validation.

That also makes ownership important. We try to avoid multiple agents independently rewriting the same canonical memory at once. A single-writer or scoped-commit model gives much cleaner provenance.

On your semantic-search question: I would postpone it until the index stops being predictably useful. For a modest number of rationale entries, explicit structure and links are easier to audit than embeddings. Semantic search becomes attractive once the corpus is large enough that deterministic navigation becomes expensive, but I would still keep the repository artifacts as the source of truth and treat retrieval as an index, not authority.

So yes — I would describe this less as “AI memory” and more as versioned project knowledge with agent-aware retrieval and promotion rules.

This is very close to where I landed too.

The distinction between evidence/history, canonical state and promoted rationale is useful. Keep the Why deliberately does not persist transcripts or everything an agent happened to learn. What lands in context/ is the smaller durable layer: decisions, constraints, rejected alternatives, workarounds and incident learnings that should survive the session.

Review is effectively the promotion boundary. Entries also carry status and evidence so an inference does not silently become the same thing as a confirmed constraint.

I also agree on retrieval. The current index is intentionally boring and deterministic: one short description per topic, then the agent opens only what is relevant. If that stops scaling, I would rather add semantic search as a derived/disposable index over the repository than make embeddings or a database authoritative.

The ownership point is interesting. Today I mostly lean on the repository workflow itself, branches, PRs/MRs, CODEOWNERS and Git history, rather than introducing a separate memory writer or lock. But concurrent agents modifying the same rationale is definitely something worth watching in larger setups.

“Versioned project knowledge with agent-aware retrieval and promotion rules” is probably a more precise description than generic AI memory.

I think the repository workflow can carry most of this surprisingly far. The place where we found an extra rule useful was the canonical-state boundary: many agents may append evidence or prepare scoped changes, but only one authority is allowed to advance the current canonical state at a time.

In practice that can still be Git-native. A writer reads version/hash X, proposes the change, and promotion succeeds only if X is still current. If another agent has advanced it, we reconcile instead of accepting last-write-wins. That gives us a lightweight compare-and-swap model without turning memory into a separate database service.

Branches/PRs/CODEOWNERS are excellent for rationale artifacts; the single-writer rule mainly protects the small surface that answers “what is true now?”. It has prevented a few nasty cases where two individually reasonable agents would otherwise leave a contradictory current state.

That maps surprisingly well to Git itself.

For KTW I don’t really have a separate canonical-state surface outside the repository. The repository state at a given commit is the canonical state, so the version/hash you describe is effectively already there.

An agent can read state X, prepare a change, and before promotion you can require that X is still the current base. If not, rebase/reconcile instead of blindly accepting the write. That gives you optimistic concurrency without introducing another coordination service.

Where I think your point still matters is semantic conflict. Git can tell me that two agents edited different lines cleanly, but it cannot tell me that the resulting rationale is conceptually contradictory.

In a larger agent fleet, I also wouldn’t necessarily solve all of that with locking. You can give one agent a maintenance role: periodically inspect the project rationale, look for contradictions or stale entries, and route those findings back to the responsible owners.

That keeps authority where it already belongs. The maintenance agent detects and reports, the owner decides, and the resulting change still goes through the normal repository workflow.

So I see a useful split:

Git handles mechanical concurrency and history.
Review handles promotion.
A maintenance agent watches semantic consistency and routes issues back to the owners.

I’d explore that before adding a stronger single-writer or locking mechanism.

One thing I would add to durable rationale is an explicit invalidation surface.

Remembering why a decision was made is valuable, but the reason is often only valid under a particular set of assumptions.

For example, a rationale entry might ideally preserve not only:

  • decision
  • reasoning
  • evidence
  • rejected alternatives
  • status

but also:

  • scope / assumptions — under what conditions was this decision valid?
  • invalidation conditions — what future change should cause an agent to reconsider it?
  • supersedes / superseded by
  • review trigger — what kind of new evidence should reopen the decision?

Otherwise a very effective rationale system can become very effective at preserving yesterday’s mistake.

There seems to be an important difference between:

“Do not propose X again; we already rejected it.”

and:

“Do not propose X again while assumptions A, B and C still hold.”

The second one is much safer for long-lived projects.

That might also give a maintenance agent something more concrete to inspect than general semantic staleness: it can look for violated assumptions or triggered invalidators rather than trying to decide from scratch whether an old rationale still “feels current”.
vv

Hi Oliver, @Daareek and @serreth!

serreth’s point about validity conditions seems important to me: preserving the reason for a choice should also help us understand when to reconsider it.

In my work with Cristallo, my AI assistant, we use structured catalogues with stable identifiers and links to sources. Our project notes, which we call our regia, preserve the reasons behind decisions, the checks performed and the points still open. I haven’t tried Keep the Why yet, so I’m offering a simplified example of our method, with fictional data and identifiers.

The initial decision

Source S-01 describes the dried form of a product. It is therefore excluded as a reference for filling in the fields of record R-101, which concerns the fresh form. Decision D-01 preserves that reason and scope.

From there, two situations could arise.

A — The source changes, but the reason for excluding it remains valid

S-01’s fingerprint changes. Comparing the versions, however, establishes that only the presentation has changed: the content still concerns the dried form.

The review could therefore conclude without modifying R-101, recording what was checked and why D-01 remains valid. A different fingerprint signals a change to examine; it does not, by itself, establish what has changed.

B — A new source becomes available that is relevant to the fresh form

Source S-02 documents the fresh form. A review could be opened for the relevant fields of R-101, preparing a possible addition to assess before adopting it. Other records would not be modified automatically.

Here I see a useful detail: D-01 could remain valid for S-01 even if S-02 allowed some fields of R-101 to be completed. The new evidence adds a possibility without necessarily making the previous exclusion wrong.

I prepared this mockup to make that scope visible: it is an illustrative interface, not a screenshot of Keep the Why.

A small test could check whether the assistant distinguishes a presentation-only update from relevant new evidence, keeps the reason for the earlier exclusion retrievable, and limits the proposal to the affected records and fields. This is a case to test, not a result I’m attributing to your software.

How would you represent in your records a review that introduces a new valid possibility while keeping the previous exclusion in force within its scope?

Warm wishes from Cristallo and me,
Barbara

I agree, and this is very close to how KTW treats long-lived rationale already.

Entries can carry status, evidence, supersession links and, importantly, a Revisit when condition. The intention is exactly what you describe: preserve the decision while also preserving the condition under which it should be questioned again.

I deliberately don’t treat a changed dependency or nearby code change as automatic invalidation though. It is a signal to review the rationale, not proof that the rationale is now wrong.

So a maintenance agent can look for triggered revisit conditions and route those entries back to the responsible owner instead of trying to decide semantic validity by itself.

I like your wording “invalidation surface”. That’s a useful way to describe that part of the lifecycle.

Hi Barbara, this is a very good example because I would not treat the second case as superseding D-01.

If D-01 says “S-01 is not valid evidence for the fresh form”, and that is still true, then D-01 should remain active within that scope.

If S-02 appears and is valid evidence for the fresh form, I would represent that separately. It may create a new rationale entry or support a new decision for the affected fields of R-101, with a link back to the earlier context if useful.

So both can be true at the same time:

D-01: S-01 remains excluded for this scope.
D-02: S-02 introduces a new valid possibility for this scope.

Only if the underlying reason behind D-01 stopped being true would I supersede or revisit D-01 itself.

That distinction is important to me because new evidence does not automatically invalidate old evidence or old exclusions. It may simply expand what the project now knows.

Your presentation-only example is similar: a changed fingerprint should be a review signal, not a conclusion. The review may simply confirm that the original rationale is still valid.

That is also the kind of thing a maintenance agent could inspect periodically and hand back to the relevant owner for review.

Hi Barbara and Cristallo!

Thank you for such a thoughtful example. I particularly like your
distinction between invalidating an earlier decision and introducing
new evidence that expands what is possible.

In our work with Navi, we’ve been exploring a similar problem from the
perspective of persistent memory shared across agents and execution
environments.

I think the important distinction is between the validity of a
decision within its original scope and the current set of available
options.

In your example, I wouldn’t replace or invalidate D-01 when S-02
appears. Instead, I’d preserve D-01 together with its original source,
scope, reasoning and validation conditions, and record a separate
review linked to the new evidence.

That review could produce a new decision, D-02, allowing specific
fields of R-101 to be updated based on S-02, while D-01 continues to
exclude S-01 for those same fields.

This would give us two independently traceable conclusions rather than
forcing the system to choose between an old and a new truth.

There’s also an interesting multi-agent dimension: a change in
available evidence should not automatically become a change in
authoritative project state. An agent can detect a new possibility and
propose a bounded update, but the transition from proposal to accepted
decision needs its own validation and ownership rules.

One experiment I’d find particularly interesting is testing whether an
agent can preserve both decisions correctly after a context reset or
handoff to another agent — without incorrectly treating the older
exclusion as obsolete.

Your example makes that distinction unusually clear. Thank you for sharing it!

Warm wishes to you and Cristallo from Darek and Navi!

Thanks, Oliver! I agree that Git provides a solid foundation for
versioning, conflict detection and review.

One interesting challenge we’ve encountered in our own multi-agent
experiments is that not every conflict is a Git conflict.

Two agents can make individually valid, non-overlapping changes that
are semantically incompatible — especially when they operate across
different sessions, machines or execution environments.

We’ve been experimenting with separating storage/version control from
ownership of the authoritative state, while using explicit checkpoints
and recovery procedures to maintain continuity.

I’m curious how you would approach this distinction: would you keep
semantic conflict detection entirely within the review/maintenance
agent, or introduce an explicit coordination layer when multiple
agents can update operational memory?

I’d be interested in comparing approaches.