{"course":{"slug":"how-software-changed","title":"How Software Development Changed","url":"https://addaly.com/learn/how-software-changed","level":"intermediate","track":"work"},"lesson":{"slug":"orienting-in-an-unfamiliar-system","title":"Orienting in a system you have never seen","url":"https://addaly.com/learn/how-software-changed/orienting-in-an-unfamiliar-system","position":12,"of":87,"minutes":10,"answer":"Understand an unfamiliar system by reading its schema, tracing one request end to end and asking git which files really change.","keyIdea":"Understand an unfamiliar system by reading its schema, tracing one request end to end and asking git which files really change, because the data model and the commit history are the two artefacts that cannot lie about what the system does."},"body":{"format":"markdown","text":"## The skill that quietly became the most valuable one\n\nIf review is the constraint, then the ability to understand an unfamiliar system quickly is the thing that relieves it. It is also the skill almost nobody is taught deliberately. People pick it up by accident over ten years, and the accident used to be reliable because everyone spent years in one codebase. That is less true now, and it is worth doing on purpose.\n\nHere is a procedure. It takes about ninety minutes on a medium-sized service and it works whether the system was written by a person or generated last Tuesday.\n\n## 1. Find the data model first, not the code\n\nBefore any source file, read the schema. `\\d+` in psql, the migrations directory, the ORM model files, the protobuf definitions, whichever exists.\n\nThe data model is the most honest document in any system. Code lies about intent, comments rot, README files describe the system somebody hoped to build. The schema describes what is actually stored, and every behaviour has to be expressible in terms of it. If there is a `status` column with five values, there are five states and somebody has to move rows between them. If there is a nullable `deleted_at`, deletion is soft and something must be filtering on it.\n\nWrite down, in five lines, what the main entities are and how they relate. If you cannot, you are not ready to read code yet.\n\n## 2. Follow exactly one request end to end\n\nPick the most representative operation the system performs. Not the simplest, the representative one. Then trace it, by hand, from the outside in.\n\nRoute definition → handler → validation → the service or domain layer → the query → the response. Write down every file it touches, in order. Ten to fifteen files is normal; if it is fifty, that is itself the most important thing you have learned today.\n\nThis single trace gives you the architecture more reliably than any diagram, because a diagram shows the design and the trace shows the system.\n\n## 3. Ask git where the system actually lives\n\nCode is not uniformly important, and the repository knows which parts are.\n\n```bash\n# files changed most often in the last year\ngit log --since=1.year --name-only --pretty=format: \\\n  | sort | uniq -c | sort -rn | head -30\n```\n\nThe top of that list is where the behaviour is, where the bugs are, and where your attention belongs. A file touched two hundred times in a year is either the core of the domain or a source of pain, and either way it is what you should read.\n\nThe inverse is also informative. A file untouched for four years is either stable or completely abandoned, and `git log -1` on it usually tells you which.\n\n## 4. Read the tests as documentation, with a caveat\n\nTest names are the closest thing most systems have to a specification, and reading them in order is often faster than reading the code.\n\nThe caveat is new and it matters. In a codebase where tests were largely generated, the test names describe what the code does rather than what it should do, because that is what they were derived from. They are still worth reading (they tell you the intended shape), but they are no longer independent evidence of intent. Weight them accordingly: a test written before the code is testimony, a test written from the code is a summary.\n\n## 5. Find the seams and the scary parts\n\nGrep for the places where this system touches something it does not control:\n\n```bash\nrg -n 'http[s]?://|requests\\.|fetch\\(|boto3|stripe|kafka|redis' --type-add 'src:*.{py,ts,go,java}' -tsrc\n```\n\nEvery external call is a place the system can be surprised. Then find the parts nobody wants to touch: `git blame` on the oldest untouched file, the module with a comment beginning \"do not\", the function with a \"# TODO: this is wrong but\" attached.\n\n## The question that ends the exercise\n\nWhen you think you understand the system, test it with one question, and answer it out loud before you check:\n\n> If I deleted this file, what would break, and how would I find out?\n\nPick three files: one you think is central, one you think is peripheral, one you are unsure about. Answer for each, then verify by searching for the imports. Being wrong here is the useful outcome: the file you thought was peripheral and turns out to be imported by forty modules is exactly the misunderstanding that would have made your next review worthless.\n\n## Doing this with a model, safely\n\nThis is a good use of a model and there is one rule. Ask it to describe, not to conclude. \"Trace how a payment request flows through this repository and list the files in order\" is verifiable in thirty seconds against the actual files. \"Is this architecture good\" is not verifiable at all and you will believe the answer anyway.\n\nCheck every file it names actually exists before you build anything on the answer. An invented module in an architectural summary is much harder to notice than an invented function in code, because nothing runs it."},"check":{"question":"A reviewer new to a service reads its README, its architecture diagram and its test names, then approves a change to the ordering logic. What is the strongest reason this preparation was insufficient?","options":[{"text":"All three describe the intended system, not the running one, and generated test names may be derived from the code itself.","correct":true},{"text":"Test names are unreliable in general and should never be used to understand a system, since they only describe individual cases and not the whole.","correct":false,"tempting":"Over-corrects into discarding a genuinely useful source; the problem is their independence in this setting, not their existence."},{"text":"READMEs and diagrams go stale, so the reviewer should have asked the original author to walk them through the design instead.","correct":false,"tempting":"Right about staleness but substitutes another person's recollection, which is the source that decayed fastest and may no longer exist."},{"text":"Ordering logic is domain-specific, so no amount of code reading substitutes for business knowledge of how orders work.","correct":false,"tempting":"True but unfalsifiable as stated; it would make every review by a newcomer impossible rather than pointing at what preparation was missing."}]},"prev":{"slug":"plausible-but-wrong","title":"The new failure mode: plausible and wrong","url":"https://addaly.com/learn/how-software-changed/plausible-but-wrong"},"next":{"slug":"the-review-budget","title":"Spending a review budget","url":"https://addaly.com/learn/how-software-changed/the-review-budget"},"authorship":"Founder and series editor: Dr Mustafa Mun. Written by AI models to a written standard. Exam keys checked blind by a second model: 3,665 of 3,666 agreed. Academic review invited.","review":{"status":"Draft, open for academic review"},"cite":"Addaly (2026) 'Orienting in a system you have never seen', in How Software Development Changed. Edited by M. Mun. Addaly. Available at: https://addaly.com/learn/how-software-changed/orienting-in-an-unfamiliar-system (Accessed: 13 October 2026).","licence":{"name":"CC BY-NC-SA 4.0","url":"https://creativecommons.org/licenses/by-nc-sa/4.0/"},"reader":{"schema":1,"title":"Orienting in a system you have never seen","courseTitle":"How Software Development Changed","module":{"index":2,"slug":"reading-what-you-did-not-write","title":"Reading what you did not write"},"answer":null,"keyIdea":"Understand an unfamiliar system by reading its schema, tracing one request end to end and asking git which files really change, because the data model and the commit history are the two artefacts that cannot lie about what the system does.","hero":{"kind":"plate","image":null,"alt":null,"caption":null},"blocks":[{"t":"h2","id":"the-skill-that-quietly-became-the-most-valuable-one","runs":[{"text":"The skill that quietly became the most valuable one"}]},{"t":"p","runs":[{"text":"If review is the constraint, then the ability to understand an unfamiliar system quickly is the thing that relieves it. It is also the skill almost nobody is taught deliberately. People pick it up by accident over ten years, and the accident used to be reliable because everyone spent years in one codebase. That is less true now, and it is worth doing on purpose."}]},{"t":"p","runs":[{"text":"Here is a procedure. It takes about ninety minutes on a medium-sized service and it works whether the system was written by a person or generated last Tuesday."}]},{"t":"h2","id":"1-find-the-data-model-first-not-the-code","runs":[{"text":"1. Find the data model first, not the code"}]},{"t":"p","runs":[{"text":"Before any source file, read the schema. "},{"text":"\\d+","code":true},{"text":" in psql, the migrations directory, the ORM model files, the protobuf definitions, whichever exists."}]},{"t":"p","runs":[{"text":"The data model is the most honest document in any system. Code lies about intent, comments rot, README files describe the system somebody hoped to build. The schema describes what is actually stored, and every behaviour has to be expressible in terms of it. If there is a "},{"text":"status","code":true},{"text":" column with five values, there are five states and somebody has to move rows between them. If there is a nullable "},{"text":"deleted_at","code":true},{"text":", deletion is soft and something must be filtering on it."}]},{"t":"p","runs":[{"text":"Write down, in five lines, what the main entities are and how they relate. If you cannot, you are not ready to read code yet."}]},{"t":"h2","id":"2-follow-exactly-one-request-end-to-end","runs":[{"text":"2. Follow exactly one request end to end"}]},{"t":"p","runs":[{"text":"Pick the most representative operation the system performs. Not the simplest, the representative one. Then trace it, by hand, from the outside in."}]},{"t":"p","runs":[{"text":"Route definition → handler → validation → the service or domain layer → the query → the response. Write down every file it touches, in order. Ten to fifteen files is normal; if it is fifty, that is itself the most important thing you have learned today."}]},{"t":"p","runs":[{"text":"This single trace gives you the architecture more reliably than any diagram, because a diagram shows the design and the trace shows the system."}]},{"t":"h2","id":"3-ask-git-where-the-system-actually-lives","runs":[{"text":"3. Ask git where the system actually lives"}]},{"t":"p","runs":[{"text":"Code is not uniformly important, and the repository knows which parts are."}]},{"t":"code","lang":"bash","label":"Bash","text":"# files changed most often in the last year\ngit log --since=1.year --name-only --pretty=format: \\\n  | sort | uniq -c | sort -rn | head -30"},{"t":"p","runs":[{"text":"The top of that list is where the behaviour is, where the bugs are, and where your attention belongs. A file touched two hundred times in a year is either the core of the domain or a source of pain, and either way it is what you should read."}]},{"t":"p","runs":[{"text":"The inverse is also informative. A file untouched for four years is either stable or completely abandoned, and "},{"text":"git log -1","code":true},{"text":" on it usually tells you which."}]},{"t":"h2","id":"4-read-the-tests-as-documentation-with-a-caveat","runs":[{"text":"4. Read the tests as documentation, with a caveat"}]},{"t":"p","runs":[{"text":"Test names are the closest thing most systems have to a specification, and reading them in order is often faster than reading the code."}]},{"t":"p","runs":[{"text":"The caveat is new and it matters. In a codebase where tests were largely generated, the test names describe what the code does rather than what it should do, because that is what they were derived from. They are still worth reading (they tell you the intended shape), but they are no longer independent evidence of intent. Weight them accordingly: a test written before the code is testimony, a test written from the code is a summary."}]},{"t":"h2","id":"5-find-the-seams-and-the-scary-parts","runs":[{"text":"5. Find the seams and the scary parts"}]},{"t":"p","runs":[{"text":"Grep for the places where this system touches something it does not control:"}]},{"t":"code","lang":"bash","label":"Bash","text":"rg -n 'http[s]?://|requests\\.|fetch\\(|boto3|stripe|kafka|redis' --type-add 'src:*.{py,ts,go,java}' -tsrc"},{"t":"p","runs":[{"text":"Every external call is a place the system can be surprised. Then find the parts nobody wants to touch: "},{"text":"git blame","code":true},{"text":" on the oldest untouched file, the module with a comment beginning “do not”, the function with a “# TODO: this is wrong but” attached."}]},{"t":"h2","id":"the-question-that-ends-the-exercise","runs":[{"text":"The question that ends the exercise"}]},{"t":"p","runs":[{"text":"When you think you understand the system, test it with one question, and answer it out loud before you check:"}]},{"t":"quote","runs":[{"text":"If I deleted this file, what would break, and how would I find out?"}]},{"t":"p","runs":[{"text":"Pick three files: one you think is central, one you think is peripheral, one you are unsure about. Answer for each, then verify by searching for the imports. Being wrong here is the useful outcome: the file you thought was peripheral and turns out to be imported by forty modules is exactly the misunderstanding that would have made your next review worthless."}]},{"t":"h2","id":"doing-this-with-a-model-safely","runs":[{"text":"Doing this with a model, safely"}]},{"t":"p","runs":[{"text":"This is a good use of a model and there is one rule. Ask it to describe, not to conclude. “Trace how a payment request flows through this repository and list the files in order” is verifiable in thirty seconds against the actual files. “Is this architecture good” is not verifiable at all and you will believe the answer anyway."}]},{"t":"p","runs":[{"text":"Check every file it names actually exists before you build anything on the answer. An invented module in an architectural summary is much harder to notice than an invented function in code, because nothing runs it."}]}],"check":{"question":[{"text":"A reviewer new to a service reads its README, its architecture diagram and its test names, then approves a change to the ordering logic. What is the strongest reason this preparation was insufficient?"}],"options":[{"text":[{"text":"All three describe the intended system, not the running one, and generated test names may be derived from the code itself."}],"correct":true,"tempting":null},{"text":[{"text":"Test names are unreliable in general and should never be used to understand a system, since they only describe individual cases and not the whole."}],"correct":false,"tempting":[{"text":"Over-corrects into discarding a genuinely useful source; the problem is their independence in this setting, not their existence."}]},{"text":[{"text":"READMEs and diagrams go stale, so the reviewer should have asked the original author to walk them through the design instead."}],"correct":false,"tempting":[{"text":"Right about staleness but substitutes another person’s recollection, which is the source that decayed fastest and may no longer exist."}]},{"text":[{"text":"Ordering logic is domain-specific, so no amount of code reading substitutes for business knowledge of how orders work."}],"correct":false,"tempting":[{"text":"True but unfalsifiable as stated; it would make every review by a newcomer impossible rather than pointing at what preparation was missing."}]}],"order":[3,1,2,0],"why":null},"prev":{"slug":"plausible-but-wrong","title":"The new failure mode: plausible and wrong","minutes":9},"next":{"slug":"the-review-budget","title":"Spending a review budget","minutes":9}}}