Source Criticism and Code Review: Two Faces of the Same Craft
The historian knows how to trust a document, the engineer how to trust code. At the heart of both disciplines lies the same question: who left this trace, when and why?
Translated from the Turkish original: Türkçesini oku
IN SHORT
The historian's source criticism and the developer's code review ask the same questions: who left this trace, when and why? Both disciplines teach us not to trust the narrative blindly and to question the trace.
In the software world, the picture that comes to mind with debugging is always the same: someone trying to reconstruct “what really happened” from log records scrolling across a screen. That picture is surprisingly similar to the attitude of a historian reading a document. Both try to reconstruct “what really happened” from the traces of the past. Both have to deal with the reliability of those traces: who left them, when, and for what purpose.
The similarity is no accident. The two disciplines are different faces of the same basic problem: you have unreliable narratives and you want a reliable reconstruction.
What is source criticism?
In the 19th century, Leopold von Ranke placed Quellenkritik (source criticism) at the centre of history writing. At the end of the century, Ernst Bernheim (1889) and Langlois and Seignobos (1898) turned the method into a two-stage system in their handbooks. The first stage is external criticism: is the document authentic, who wrote it and when, was it altered later? The second stage is internal criticism: is what the document says reliable, and what were the author’s interests, point of view and access to information?
In the preface to his first book, published in 1824, Ranke set a more modest goal against those who gave history the task of judging the past:
(This work) merely wants to show how it actually was.1
The sentence can be read as an ideal of pure neutrality. But at its core it carries a solid principle: separate the narrative from the trace, and question the trace every time.
Code review asks the same questions
How is code review similar to source criticism?
When you look at a pull request, what you do is no different from external and internal criticism:
| The question in source criticism | Its equivalent in code review |
|---|---|
| Who wrote the document? | git blame, the PR author |
| When was it written? | The commit date, the architecture of the time |
| Why was it written? (the author’s interest) | The issue number, the commit message |
| Is it original or altered later? | Rebase history, traces of cherry-picks |
| What was its context? | Architecture decision records, RFCs, design documents |
Understanding what a line of code does is usually easy; understanding why it was written that way requires going down to the documentation, the history and the author’s intention. “It works, but why like this?” comes from the same place as the historian’s “why does the source tell it like this?”
Primary source, secondary source
What is the difference between a primary and a secondary source?
In history writing the distinction is clear: a primary source is a trace from the time of the event (a document, a letter, a record); a secondary source is an interpretation written about those traces later. In software, the equivalent is the code itself and everything written about it: documentation, blog posts, Stack Overflow answers.
This is the essence of the “outdated documentation” problem: when a secondary source contradicts the primary one, the engineer does what the historian does and goes back to the primary. Documentation is an interpretation; code is testimony. (Code can lie too, of course; then you run it. This is the historian’s equivalent of an experiment: reading what a document says against the other traces it can be combined with.)
Logs are the chronicles of our time
Why can server logs be read like a chronicle?
A server’s logs are a chronicle in the full sense: event-driven, incomplete, biased and often compiled after the fact. Debugging is source criticism itself. You move forward by thinking about what a log line records, what it does not record (absences stay silent!) and under what conditions the record was produced.
When I realised that the effort spent on observability tools is at heart a problem of archival science, my view of logging strategies changed: good logging is like writing a good chronicle. The recording party must be known, the timestamp reliable and the context intact.
Trust, but by reading the trace
When can we trust a source?
Both crafts arrive at the same place: not “trust, but verify”, but “to trust, first verify the traces themselves”. A historian who trusts a document unconditionally goes wrong just like an engineer who trusts code unconditionally; both are caught by the pull of the narrative.
Perhaps that is why these two fields can learn so much from each other: history writing can tell software something about the silences and biases of traces; software can tell history something about version control and reproducibility. That is why I want this blog to stand right on that border.
Notes
-
In the German original: “er will bloß zeigen, wie es eigentlich gewesen.” From the preface to the first edition (1824) of Ranke’s Geschichten der romanischen und germanischen Völker von 1494 bis 1514. ↩
References
- Bacchelli, A., & Bird, C. (2013). Expectations, outcomes, and challenges of modern code review. In Proceedings of the 35th International Conference on Software Engineering (ICSE) (pp. 712–721). IEEE. https://doi.org/10.1109/ICSE.2013.6606617
- Bernheim, E. (1903). Lehrbuch der historischen Methode und der Geschichtsphilosophie (Rev. ed.). Duncker & Humblot. (Original work published 1889)
- Grafton, A. (1997). The footnote: A curious history. Harvard University Press.
- Langlois, C.-V., & Seignobos, C. (1898). Introduction aux études historiques. Hachette.
- Ranke, L. von. (1885). Geschichten der romanischen und germanischen Völker von 1494 bis 1514. Duncker & Humblot. (Original work published 1824)