hides its implementation/a decision behind an interface. interface Study it without reading the rest. implementation e.g. a method, a class, a bounded context hschwentner.io hidden
a survey of what exists. Prescription, not description → The current architecture lives in ARCHITECTURE.md ## Style - Hexagonal, not layered. Adapters depend inward; the domain depends on nothing. [DependencyRulesTest] - Domain imports no framework types. [DomainPurityTest] - One module per bounded context; modules talk through published interfaces, never through each other's tables. [ModuleApiTest] Style, not domain. ## Choices, where others are also reasonable - Ports live beside the domain, not in their own package. [PortLocationTest] - Mapping is hand-written. No MapStruct. [no test] - Persistence returns domain types, not entities. [no test] The contexts and their language live in CONTEXT-MAP.md. ## Enforcement Every rule here is an ArchUnit test. Rules marked [no test] are not yet enforced: if you touch code they govern, write the test first. Make it fail, then fix the code. Where a test and this file disagree, the file wins — fix the test. Where code breaks a rule and the suite stays green, the test is missing. All can be referenced from AGENTS.md. ## Known deviations - sales reads risk tables directly (owner: HS, #412). Do not add to this. New code goes through the port. hschwentner.io
their How this system should be built. language live in CONTEXT## Style MAP.md. - Hexagonal, not layered. Adapters depend inward; the # Architecture Rules How this system is built. Not a survey of what exists. Not a survey of what exists. domain depends on nothing. [DependencyRulesTest] - Domain imports no framework types. [DomainPurityTest] - One module per bounded context; modules talk through published interfaces, never through each other's tables. [ModuleApiTest] Both referenced from AGENTS.md. ## Choices, where others are also reasonable - Ports live beside the domain, not in their own package. [PortLocationTest] - Mapping is hand-written. No MapStruct. [no test] - Persistence returns domain types, not entities. [no test] ## Enforcement Every rule here is an ArchUnit test. Rules marked [no test] are not yet enforced: if you touch code they govern, write the test first. Make it fail, then fix the code. Where a test and this file disagree, the file wins — fix the test. Where code breaks a rule and the suite stays green, the test is missing. ## Known deviations - sales reads risk tables directly (owner: HS, #412). Do not add to this. New code goes through the port. hschwentner.io
built. Not a survey of what exists. ## Style - Hexagonal, not layered. Adapters depend inward; the domain depends on nothing. [DependencyRulesTest] - Domain imports no framework types. [DomainPurityTest] - One module per bounded context; modules talk through published interfaces, never through each other's tables. [ModuleApiTest] Style, not domain. The contexts and their language live in CONTEXTdepend inward; the domain depends MAP.md. - Hexagonal, not layered. Adapters on nothing. ## Choices, where others are also reasonable - Ports live beside the domain, not in their own package. [PortLocationTest] - Mapping is hand-written. No MapStruct. [no test] - Persistence returns domain types, not entities. [no test] [DependencyRulesTest] Both referenced from AGENTS.md. - Domain imports no framework types. [DomainPurityTest] - One module per bounded context; ## Enforcement Every rule here is an ArchUnit test. Rules marked [no test] are not yet enforced: if you touch code they govern, write the test first. Make it fail, then fix the code. Where a test and this file disagree, the file wins — fix the test. Where code breaks a rule and the suite stays green, the test is missing. modules talk through published interfaces. [ModuleApiTest] ## Known deviations - sales reads risk tables directly (owner: HS, #412). Do not add to this. New code goes through the port. hschwentner.io
a survey of what exists. ## Choices, where others are also reasonable ## Style - Hexagonal, not layered. Adapters depend inward; the domain depends on nothing. [DependencyRulesTest] - Domain imports no framework types. [DomainPurityTest] - One module per bounded context; modules talk through published interfaces, never through each other's tables. [ModuleApiTest] Style, not domain. The contexts and their language live in CONTEXT- Ports live beside the domain.MAP.md. ## Choices, where others are also reasonable - Ports live beside the domain, not in their own package. [PortLocationTest] - Mapping is hand-written. No MapStruct. [no test] - Persistence returns domain types, not entities. [no test] [PortLocationTest] Both referenced from AGENTS.md. - Mapping is hand-written. No MapStruct. [no test] ## Enforcement Every rule here is an ArchUnit test. Rules marked [no test] are not yet enforced: if you touch code they govern, write the test first. Make it fail, then fix the code. Where a test and this file disagree, the file wins — fix the test. Where code breaks a rule and the suite stays green, the test is missing. - Persistence returns domain types. [no test] ## Known deviations What (owner: the model cannot - sales reads risk tables directly HS, #412). Do not add to this. New code goes through the port. guess. hschwentner.io
a survey of what exists. ## Style - Hexagonal, not layered. Adapters depend inward; the domain depends on nothing. [DependencyRulesTest] - Domain imports no framework types. [DomainPurityTest] - One module per bounded context; modules talk through published interfaces, never through each other's tables. [ModuleApiTest] ## Enforcement Style, not domain. The contexts and their language live in CONTEXT- Ports live beside the domain, not in their own Rules marked [no test] are not yet MAP.md. package. [PortLocationTest] Every rule here is an ArchUnit test. ## Choices, where others are also reasonable - Mapping is hand-written. No MapStruct. [no test] - Persistence returns domain types, not entities. [no test] enforced: if you touch code theyBoth referenced from govern, write the test first. ## Enforcement Every rule here is an ArchUnit test. Rules marked [no test] are not yet enforced: if you touch code they govern, write the test first. Make it fail, then fix the code. Where a test and this file disagree, the file wins — fix the test. Where code breaks a rule and the suite stays green, the test is missing. AGENTS.md. Make it fail, then fix the code. Where a test and this file disagree, ## Known deviations - sales reads risk tables directly (owner: HS, #412). Do not add to this. New code goes through the port. the file wins - fix the test. Suite green on broken rule? Test missing. hschwentner.io
a survey of what exists. ## Style - Hexagonal, not layered. Adapters depend inward; the domain depends on nothing. [DependencyRulesTest] - Domain imports no framework types. [DomainPurityTest] - One module per bounded context; modules talk through published interfaces, never through each other's tables. [ModuleApiTest] ## Known deviations ## Choices, where others are also reasonable - Ports live beside the domain, not in their own package. [PortLocationTest] - Mapping is hand-written. No MapStruct. [no test] - Persistence returns domain types, not entities. [no test] - sales reads risk tables directly. owner: HS, issue #412 ## Enforcement Every rule here is an ArchUnit test. Rules marked [no test] are not yet enforced: if you touch code they govern, write the test first. Make it fail, then fix the code. Where a test and this file disagree, the file wins — fix the test. Where code breaks a rule and the suite stays green, the test is missing. Do not add to this. New code goes through ## Known deviations - sales reads risk tables directly (owner: HS, #412). Do not add to this. New code goes through the port. the port. Honest about what is already broken. hschwentner.io
Edsger. “Go To Statement Considered Harmful.” Communications of the ACM 11, no. 3 (March 1968): 147–48. Evans, Eric. Domain-Driven Design: Tackling Complexity in the Heart of Software. Boston: Addison-Wesley, 2004. Lilienthal, Carola and Henning Schwentner. Domain-Driven Transformation: Modernize Legacy Software and Mitigate Risk. Santa Rosa, CA: O’Reilly, 2026. Parnas, David L. “On the Criteria To Be Used in Decomposing Systems into Modules.” Communications of the ACM 15, no. 12 (December 1972): 1053–58. Yourdon, Edward and Larry L. Constantine. Structured Design: Fundamentals of a Discipline of Computer Program and Systems Design. New York: Yourdon Press, 1979. hschwentner.io
model, model Predicts the next →token from those before it. No memory between runs. It knows nothing about your repository except what is in the →context window. e.g. Sonnet, GPT, Gemini—the model matters less than the codebase. hschwentner.io
in words, plus whatever the →harness attaches to it. It is the smallest part of the →context window. The files around it do most of the work. e.g. “Add VAT to the invoice total”—four words, and forty files of context. hschwentner.io
and writes—not a word, not a line. Roughly four characters of English. Limits and bills are counted in tokens. e.g. getCustomerById is about four tokens: get · Customer · By · Id. hschwentner.io
sees at once: →prompt, files, its own output. Measured in →tokens. Outside the context window nothing exists—it cannot look anything up. e.g. 200,000 tokens is roughly 15,000 lines of code, answer included. hschwentner.io
model attends most to the beginning and the end of its context. What sits in the middle is weighted least. So, a full →context window is not a well-read one. e.g. the rule it needed sat in file 30 of 60; it used the one from file 2. hschwentner.io
in a loop with tools. It reads, greps, edits, runs the tests—and picks what to read next. An assistant completes your line. An agent chooses its own context. e.g. “Add VAT to the invoice total”: it greps, opens three files, edits one. hschwentner.io
around the →model: it picks what enters the →context window. The model is fixed; the harness is not. Your repository is half of it. e.g. Claude Code and Cursor run the same models, and behave differently. hschwentner.io
get worse as the context window fills up. Stale plans, dead ends, and its own old output crowd the window. A long session degrades even inside the limit. e.g. hour three: it re-implements what it deleted in hour one. hschwentner.io
and not true. The model fills a gap with what usually follows. Missing context is the gap. e.g. a method name that should exist by every convention here, but doesn’t. hschwentner.io