Raw capture — raw/guides.md


url: https://eng-atlas.dev/guides date_fetched: 2026-08-21


content: 'EngineeringEngineering37 min10 chapters1,512 cardsHere is a trick that makes software quality much easier to think about: stop asking whether a system is good and start asking which property it is missing. Good is not a property. Fast, correct, cheap to run, hard to break into, easy to change, those are properties, and each one has its own body of practice built up over decades by people who got burned and wrote down what they learned. This guide walks ten of them: Correctness, Reliability, Performance, Scalability, Security, Maintainability, Operability, Usability, Cost, and Compliance.01Getting the right answerCorrectness02Staying up when things breakReliability03Where the time goesPerformance04Growing without hitting a wallScalability05Designing for an adversarySecurity06Keeping the system softMaintainability07Running it at three in the morningOperability08Being kind to the person on the other sideUsability09What it all costsCost10Proving you did the right thingCompliance'


content: '‹ EngineeringChapter 1 of 1001CorrectnessGetting the right answerDoes it do the right thing?Correctness is the property everything else stands on: the system computes the right answer and keeps the promises it made about its own state. It sounds like the most basic thing you could ask of software, and it is also the one you can never finish proving. Dijkstra''s old observation, the one behind testing shows the presence of bugs, never their absence, is not a counsel of despair. It is a design constraint. Since you cannot check every input and every interleaving, you have to build correctness in layers: requirements that say what right means, designs that make wrong states hard to reach, and tests that pin the behavior you care about so it cannot quietly drift.Start hereA short path into this chapterBrowse all 80 core practices ›Testing Shows the Presence of BugscoreDijkstra''s observation that tests can only demonstrate defects, never prove their absence, and what follows from taking it seriously.Whole-Team Approach to QualitycoreMake quality the whole team''s job, not a testing phase or a separate QA group you throw work over to.Testing PyramidcoreMany fast unit tests, fewer integration tests, fewest end-to-end tests.Trunk-Based DevelopmentcoreEveryone integrates small changes into one shared branch, many times a day.The word also gets bigger as your system does. For a single function, correct means the right return value. For a fleet of services sharing data, it means asking which reader is owed which consistency guarantee, and whether a crash halfway through a multi-service operation leaves the world coherent or subtly broken. This lane runs the whole distance, from null handling in one routine to the consistency model of a replicated store.What to watch forThe trap almost everyone falls into is trusting the green checkmark. A passing suite proves the behaviors you thought to check, and says nothing at all about the ones you did not. Coverage numbers make this worse when they become a target, because it is easy to execute a line without asserting anything meaningful about it. A suite can be 90 percent covered and nearly toothless.The deeper trap is that correctness does not compose once concurrency and distribution enter the picture. Two components that are each correct alone can produce garbage together when a message arrives twice, a replica lags, or two writers interleave. Teams reach for a database transaction and assume it saves them, without checking that the default isolation level actually forbids the anomaly they fear. These bugs are rare, non-deterministic, and brutal to debug in production, which is why the best distributed-correctness work happens in design, removing the possibility of the bug, rather than in test, hunting for its absence.The cheapest correctness work happens before there is any code, when the team agrees on what right behavior even means. That starts as a stance: Whole-Team Approach to Quality puts developers, testers, and product people on the hook together, instead of tossing builds over a wall to a QA group whose job is to catch what everyone else threw. It gets concrete when the examples you agreed on become the acceptance tests themselves, and when the domain''s own vocabulary flows into the code as a Ubiquitous Language, so the model in the conversation and the model in the repository stop drifting apart. A surprising number of bugs are really translation errors, and this closes the gap they live in.At the keyboard, the workhorse is Test-Driven Development: write a failing test, make it pass, tidy up, repeat. People argue endlessly about whether it is the one true way, but the mechanism is hard to argue with. It forces you to state each behavior before you build it, and it leaves a regression net behind as a side effect. Those tests want a shape, and the Testing Pyramid is the portfolio advice that keeps them fast: lots of unit tests, fewer integration tests, a handful of slow end-to-end runs. Example-based tests only reach the cases you imagined, though, which is where Property-Based Testing earns its keep. You state an invariant that must hold for whole classes of input and let the framework hunt for the counterexample you would never have typed by hand. And if you want to know whether your tests actually bite, Mutation Testing plants small deliberate bugs and checks that something goes red. It is the honest way to audit a safety net.Better than testing for bad states is making them impossible to write down. The design move behind Make Illegal States Unrepresentable is to shape your types so the invalid combination simply has no representation: an order cannot be both shipped and unpaid because no value of the type can say that. Every state you design out of existence is a whole family of tests you never need.Once your system spans services and teams, correctness becomes an agreement problem. Two services that agree today drift apart tomorrow unless the agreement is written down and checked, which is exactly what Contract Testing does, verifying each side against a shared contract without standing up the whole stack. The same idea applied to data flows is Data Contracts: every producer-consumer handoff gets a versioned, validated schema with a named owner, so a breaking change fails loudly at the source instead of silently poisoning a dashboard three teams downstream.The distributed core of the lane is about guarantees and partial failure. Picking from the menu of Consistency Models is a real engineering decision, not an academic one, because every step toward stronger consistency costs latency and availability you may not need to spend. Choose the guarantee your correctness actually requires, and no more. And for the sharp little problem of publishing an event and committing a state change without letting a crash split them, the Transactional Outbox writes the event into the same transaction as the business row and lets a relay ship it afterward. It is a small pattern that closes a gap teams rediscover the hard way over and over.The pattern across the whole lane: correctness is earned in small installments at every phase, and the highest-value cards are the ones that make a wrong state unreachable or a wrong answer impossible to ship unnoticed. If you only do one new thing after reading this, measure your tests with mutation testing. Most teams are surprised by what they find.Open the board for all 419 getting the right answer cards ›Next ›Staying up when things break'