DEV Community

Francis Marzynski
Francis Marzynski

Posted on

Keeping Markdown as the source of truth once decisions start referencing each other

A few people who reached out about Operating Memory this month are all building some version of the same thing: decisions or ADRs kept as files in git, read by hand for a while, until the files start referencing each other. This one supersedes that one. This one only applies if the other one holds. This one contradicts a decision from three months ago that nobody remembered to update.

At that point the question is always the same. Keep reading the files by hand, or reach for a graph or triple store to hold the relationships.

Operating Memory's answer so far is neither, and I want to write down why rather than just ship an opinion.

The files stay canonical. Every import is a revision, not an overwrite, so supersession is explicit: a new decision can say what it replaces, and the old one does not disappear, it becomes historical. That's stored relationally, in plain SQL, because supersession, applicability, and "what is current right now" are exactly the kind of question a relational model answers well, and it means nothing has to leave the files to be true.

What that doesn't solve is the harder version of the question: not "what's current" but "what else changes if this one does." Cross-references, multi-hop chains, the reasoning graph between decisions rather than just their sequence. That's the part a graph model is actually built for, and it's also the part I don't think should be added by default, because a graph is one more structure to keep in sync with the files, and "keep it in sync" is the exact problem this project exists to avoid creating a second version of.

So the current approach is to test it against real cases instead of assuming the answer. Pick a handful of actual cross-referencing, multi-hop questions people have, and see whether a graph read on top of the relational core answers them meaningfully faster or more accurately than walking the relational links by hand. If it doesn't earn its keep on real questions, it doesn't go in.

I don't have a clean verdict yet. What I do have is a relational core that already tracks revisions and supersession without a second database, and a short list of real questions to test the graph idea against before building it.

If you've built something similar: did a graph or triple store end up worth the sync cost for you, or did it become one more thing to maintain?

Repo, if useful: github.com/FrancisMarzynski/operating-memory-public

Top comments (2)

Collapse
 
jo-do profile image
Jo Do

Keeping files canonical while deriving relational indexes is a good boundary if every derived row carries the source revision hash. Then a stale index can fail closed instead of becoming a second truth. For graph experiments, I would start with a rebuildable projection and measure whether it improves specific impact questions; if it cannot be regenerated deterministically from the files, the sync cost has already won.

Collapse
 
raknaos profile image
Raknaos

Refusing to add the graph by default is the right call, and I'd frame the reason more bluntly: a derived index is only safe if it can fail closed. If every relational row carries the revision hash of the file it came from, a stale index is detectable and ignorable. Without that, the graph becomes a second truth that people trust more precisely because it's quicker to query than the files.

On measuring it: the questions that break a hand-walk are usually the ones with no path shortcut - "which decisions are still load-bearing for something shipped" and "what did this supersede indirectly". Both are reachability, and both stay cheap in a relational core with a recursive CTE. I'd only reach for a graph store once a question needs edge properties or confidence weights, because that's the point where the extra structure pays for its own sync cost. Did the supersession chain already get long enough to hurt?