Context DAG: Version-Controlled Reasoning for AI Agents
Code has Git. Agent reasoning usually has a disappearing chat window. h5i gives Claude Code, Codex, and teammates a shared context graph that can be restored, searched, branched, merged, and attached to commits.
- A flat markdown memory file is the wrong shape for volatile, per-commit reasoning — no ancestry, no branchable experiments.
- A DAG of typed nodes (with a MERGE node recording both parents) is queryable and mergeable like code.
- Snapshots pin to commit SHAs, so reasoning gets the same restore-and-diff time travel Git gives code.
Every AI coding session throws away its most useful artifact. The diff survives; the
path to it does not. Which files did the agent read before it edited? Which
assumption did it test and reject? What did it leave as a TODO, and why did it pick this
design over the obvious alternative? Those answers live in a chat window that closes — so
the next session re-discovers the project from scratch, and the reviewer is left reading
a diff with no idea how it was reached. The usual patch is a markdown memory file
(CLAUDE.md, AGENTS.md, a notes doc). It helps, and it also rots:
one mutable blob, no ancestry, no way to branch an experiment, no link from a note to the
commit it describes.
h5i treats reasoning as versionable project state instead. It records a context DAG under
the Git ref refs/h5i/context — the reasoning layer of an
auditable workspace, separate from your
working tree but shareable through Git. Each unit of work becomes a typed node with
ancestry; reasoning can branch and merge like code; and snapshots pin to the commit SHAs
they produced, so the next agent (or the next reviewer) can recall the goal, the
milestones, the decisions, the open risks, and the file-specific prior reasoning before
touching a line.
What goes into the DAG
h5i's context entries use a small vocabulary that maps cleanly to agent work:
| Entry | Meaning | Typical source |
|---|---|---|
OBSERVE | What the agent inspected. | File reads, searches, listings. |
THINK | A design choice, hypothesis, or rejected alternative. | Agent reasoning or explicit trace. |
ACT | What changed. | Patches, writes, generated files. |
NOTE | What future sessions should not miss. | TODOs, limitations, risks. |
MERGE | Reasoning from another context branch joined back. | Context branch merge. |
This is intentionally simpler than a full transcript. h5i is not trying to preserve every token. It preserves the shape of the work: what was known, what was decided, what changed, and what still matters.
Daily workflow
The honest daily workflow is: you just work. A human wires the hooks once
per runtime, and from then on capture is automatic — nobody types h5i hook … by hand:
$ h5i hook setup --write --target claude # wires SessionStart · UserPromptSubmit · PostToolUse · Stop $ h5i hook setup --write --target codex # wires SessionStart · Stop
With Claude Code all four handlers fire on their own: h5i hook session-start injects
prior context, h5i hook claude prompt records the verbatim prompt,
h5i hook claude sync writes OBSERVE and ACT as files are read and edited, and
h5i hook claude finish mines THINK and NOTE and checkpoints the milestone when the
turn ends. Codex has no per-prompt or per-edit hook, so it wires just two
(h5i hook session-start and h5i hook codex finish --quiet); the finish step
parses Codex's own session JSONL via h5i hook codex prelude/sync/finish
to reconstruct the prompts and OBSERVE/ACT entries it had no event hook for. Either way, both
agents write to the same shared context workspace.
The only entries emitted explicitly — by the agent at a task boundary, not typed by you each day — are the goal at the start of a task and the occasional flag left for a future reviewer:
$ h5i recall context init --goal "ship OAuth login safely" $ h5i recall context trace --kind NOTE \ "RISK: refresh-token rotation untested across deploys"
Branching reasoning, not just code
Agent work often includes experiments: try a lock-free design, compare two caching strategies, inspect whether a bug is in the parser or the caller. Those investigations are valuable even when you abandon them. h5i lets you branch context to isolate the experiment, then merge the useful conclusion back.
$ h5i recall context branch experiment/cache-layer \ --purpose "compare Redis cache against local LRU" # inspect, test, decide — OBSERVE/THINK/ACT land on the branch, not on main $ h5i recall context checkout main $ h5i recall context merge experiment/cache-layer
The merge is what makes this a graph and not a list. It writes a MERGE node that
records both parent IDs — the tip of main and the tip of the experiment —
so the conclusion ("LRU won; Redis added a network hop we did not need") arrives on
main carrying a pointer back to the investigation that produced it. A teammate who
later asks "did anyone try Redis here?" follows that edge instead of guessing. You can render
the whole shape, parents and all, in the terminal:
$ h5i recall context dag # coloured DAG: kind, 8-hex id, time; MERGE shows both parents $ h5i recall context relevant src/cache.rs # prior reasoning for one file $ h5i recall context knowledge # every THINK across all branches — the decision log $ h5i recall context todo # open NOTE/THINK items: TODO / FIXME / BLOCKED
A flat file cannot answer those questions because it has no edges to follow and no per-entry type to filter on. The DAG is queryable precisely because the structure is in the data, not in prose you have to skim.
Snapshots pinned to commit SHAs
Reasoning is most useful when it is anchored to the code it explains. Every
h5i capture commit automatically snapshots the context workspace and links it to
the resulting Git commit SHA. That gives you two operations a plain memory file can never
offer:
$ h5i recall context restore a1b2c3d # reasoning state as of that commit $ h5i recall context diff a1b2c3d HEAD # how the reasoning evolved since
restore answers "what did we know when we shipped this?" — useful when a commit
from three weeks ago turns out to be wrong and you need the assumptions behind it.
diff answers "what changed in our thinking between these two points?" — the
reasoning counterpart of git diff. Because the snapshot is keyed by SHA, the
reasoning and the code can never drift apart: checking out an old commit and restoring its
context gives you a coherent picture of that moment, not today's notes pasted over yesterday's
code.
How it compares to memory files and vendor memory
A flat memory file is easy to append and hard to trust. It has no ancestry, no branch boundary, no commit linkage, and no clear line between durable knowledge and scratch notes. A DAG gives context a structure close to the work itself. The alternatives each get something right — here is the honest tradeoff:
| Approach | Good | Gap |
|---|---|---|
Markdown memory file (CLAUDE.md, AGENTS.md) |
Simple, human-readable, lives in the repo, loaded into every prompt. | One mutable blob: no per-entry ancestry, can't branch an experiment, no link from a note to its commit, grows unbounded and goes stale; conflicts are textual, not semantic. |
| Vendor "memory" features | Automatic recall across sessions with near-zero friction. | Provider-hosted and opaque: not in your repo, not in code review, not portable across tools or teammates, not pinned to a commit, and not diffable in a PR. |
| Session transcript / scrollback | Complete — every token of the reasoning is there. | Ephemeral and unstructured: too large to reuse, not shared, gone when the window closes. |
| Git commit messages | Durable, in-repo, already part of review. | Only the final decision, written after the fact — no observations, no rejected paths, no open risks. |
| h5i context DAG | In-repo and Git-versioned; typed nodes; branch/merge with both parents recorded; snapshots pinned to commit SHAs; queryable by file, kind, or decision. | Needs the one-time hook wiring, and lives in refs/h5i/* — shared with h5i share push, not plain git push. |
The point is not that markdown memory is useless — it is a fine place for stable, hand-curated project rules. The point is that a single file is the wrong shape for the volatile, branching, per-commit reasoning of an active session, and that is exactly where a DAG earns its keep.
What this changes for review
A context DAG gives reviewers a way to audit the path to the diff, not only the diff itself. If an agent changed authentication code, the reviewer can ask whether it observed the login tests, whether it recorded a risky assumption, and whether another context branch already investigated the same failure. That turns review from transcript archaeology into targeted verification.
The DAG also makes handoff cleaner. A second agent can inherit the current goal, relevant observations and unresolved notes without rereading the whole repository. Humans get the same benefit when a branch sits for a week and the original conversation is gone.
The bottom line
Agent reasoning is project state, and like any state worth keeping it wants the affordances Git already gives code: history, branches, merges, and a way to look at any past moment. A flat memory file gives you none of those; it gives you an append-only blob that drifts from the code and loses the structure of the work. A context DAG keeps the in-repo, version-controlled virtues of that file and adds the parts that make it trustworthy — typed nodes, ancestry, merges that record both parents, and snapshots pinned to the commit SHAs they explain.
The practical test is simple: when a branch sits untouched for a week, can the next session —
or the next reviewer — recover not just what changed but how it was reached?
With a chat window, no. With a DAG you can restore, diff, and follow
the merge edges, the answer is yes, and review stops being archaeology.
FAQ
What is a context DAG? A versioned graph of an AI agent's reasoning, stored by h5i in the Git ref refs/h5i/context. Instead of one mutable memory file, each unit of work is a typed node — OBSERVE, THINK, ACT, NOTE, or MERGE — with ancestry, branch boundaries, and links to the commit SHAs the work produced.
How is it different from a CLAUDE.md memory file? A markdown memory file is a single mutable blob: no per-entry ancestry, no way to branch an experiment in isolation, no link from a note to the commit it describes, and it grows unbounded and goes stale. A context DAG keeps the same Git-versioned, in-repo property but adds typed nodes, branches you can merge (with a MERGE node carrying both parents), and snapshots pinned to commit SHAs you can restore and diff.
Are reasoning snapshots tied to specific commits? Yes. Every h5i capture commit snapshots the context workspace and links it to the resulting commit SHA. Use h5i recall context restore <sha> to recover the reasoning as of that commit, or h5i recall context diff <from> <to> to see how it evolved between two commits.
Can two agents merge their reasoning? Yes. Branch with h5i recall context branch <name>, explore without disturbing the main thread, then h5i recall context merge <name> to fold the conclusion back. The merge produces a MERGE node recording both parent IDs, so the graph is a true DAG, not a linear log.
Where is it stored, and does git push share it? In the Git ref refs/h5i/context, separate from your working tree. Plain git push does not move refs/h5i/* — use h5i share push and h5i share pull to share the reasoning DAG alongside the code.
What to read next
Use the workflow guide for day-to-day commands, or read how h5i renders the same context into a PR body when a branch is ready for review.
Version your agent's reasoning, not just its code
Try h5i on your next AI-assisted branch: create a sandboxed workspace, capture the run, and post a review-ready PR brief.
Star on GitHub Read the workflow guide