Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

13KB

FOCUS Architecture — Chapter-24: Ship Increments Without Chaos

  • Source: /library/FOCUS Architecture/source-file.pdf
  • PDF pages: 730–737
  • Pages without text: none

Ship Increments Without Chaos In this chapter, you’ll: state FOCUS in a hallway conversation, with the four pieces and the chapter number where each one got built; say who benefits from it and why, with one reason that covers both humans and AI; apply, to your own project, the ruler that keeps the drift between what the code does and what the project says it does in check. Rosie’s app has been running on your machine since chapter 22. You cloned the repository, generated the database, watched the 85 tests pass, and saw the window open with the menu loaded. What’s missing isn’t code. What’s missing is the pocket-sized version of the book, the one that fits in a hallway conversation, and the ruler for tomorrow, when the next change request lands. This chapter teaches nothing new, on purpose. It hands the book back in pocket size, and to do that it repeats definitions you already read: repeating the definition at the point of use has been this book’s decision since the start, because the rule against repeating yourself governs code, not teaching. If a term sounds newly invented, it isn’t. Each one carries the number of the chapter that paid for it with code, a test, and an answered critique.

FOCUS in a hallway conversation Someone asks in the hallway what you’ve been reading lately. You have thirty seconds. The answer fits in them. FOCUS is a four-piece architecture with flow in one direction only, and every piece in this list carries the number of the chapter that built it, so you can check any sentence of mine against the original. The View fires events and draws the state it receives; it decides nothing (chapter 12). The Orchestrator receives the event, fetches the data, calls the rule, and publishes the next state, with no business rule inside it (chapter 13). Use Cases are the only place for business rules: pure functions that take data and return a Result (chapter 14). Repositories fetch and save, and they’re the boundary where the exception exists and turns into a value exactly once (chapter 15). The direction of the flow never reverses, and the one-page table stating what each layer does and what each layer forbids lives in chapter 10; it’s still the only page in the book worth memorizing. Two terms from that conversation deserve a one-sentence definition, because whoever’s listening may not have read the book, and because you might be reading this conclusion standing in a bookstore. A slice is a complete feature inside a single folder: the view, the orchestrator, the use cases, and the data for the same feature live together, and the folder sets the blast radius of any change (chapter 11). A Result is a return value that carries success and every rejection as types the compiler forces you to handle, in place of an exception that crosses layers without warning (chapter 8). Under the four pieces sit three pillars. Business rules are pure functions: data goes in, a result comes out, no IO in between (chapter 7). Errors are values, and the branch you didn’t handle breaks the build instead of breaking production (chapter 8). Code organizes by feature, not by layer, so every change request opens

one folder instead of seven (chapter 11). The practical payoff is cheap testing: each piece gets tested the way it asks to be tested, the use case with no test double at all, the orchestrator by event- to-state flow, the repository against a fake (chapter 17). What’s it for, then? For the business app that’s going to be maintained: menu, tab, payment, and loyalty at Rosie’s Coffee Shop; sign-ups, invoices, and reports in the system that pays your salary. It’s the software that changes every week because the business changes, and whose rule needs a fixed address. And when should you skip it? In the weekend throwaway prototype, where four layers are pure cost: write it all in one file, show it to three people, and throw it away, as the book has already admitted twice (chapters 4 and 22). Who benefits (and it’s a single reason) Four agents edit or judge the code of a living project: whoever maintains it alone, whoever joins the team mid-story, whoever reviews code they didn’t write, and the language model asked to produce part of it. Their question is the same one. It isn’t “how do I write this?”; it’s “where does this live, and what breaks if I touch it?” That question costs you the size of the search space: how many files could hold the answer, how many places the change could reach. FOCUS shrinks that space, and it shrinks equally for all four. The rule has a single address, the slice’s use case. The side effect has a single boundary, the repository. The contract between the pieces is narrow, and the compiler collects on it: a new state in the sealed union breaks the build of every view that ignores it, a new Result variant breaks every caller that doesn’t handle it. For the solo maintainer, that means coming back six months later and knowing where to touch without rereading the project. For

whoever joins mid-story, it means opening the tab folder and understanding the whole tab without opening the payment one. For whoever reviews, it means receiving a diff that fits inside one slice. For the model, it means recovering the context of a single folder and synthesizing inside a space where a good share of the wrong outputs don’t even compile. Notice what didn’t change from one sentence to the next: the mechanism. Narrow contracts and isolated slices cut the cost of review and reasoning for any agent editing the code, whether it carries a keyboard or a context window. I stopped separating those two audiences in practice: I review a colleague’s code and a model’s code with the same slice checklist from chapter 21, and FOCUS is the reason that checklist is a single one. Architecture that’s good for AI and architecture that’s good for people were never two separate lists of requirements. This is where the line that started in chapter 1 closes, and the sentence from back there closes whole: architecture lowers the cost of change because it makes the intent of the system recoverable, navigable and predictable for humans and for models. What’s left of this chapter is the small version of that sentence, and it fits in a single gesture: if the next increment fits inside one slice, the intent is still in place; if it spreads across half a dozen folders, something stopped being predictable before it got expensive. The ruler against drift What’s missing is a name for the enemy. The name is drift: the gradual gap that opens between what the code does and what the project says it does. It’s a reused word, and a warning is due: chapter 22 uses “drift” as the proper name of the Dart package that generates database access. Unrelated. Here the word carries

its ordinary sense of drifting apart, and what drifts apart are the document and the code, one moving away from the other. The spec promises one rule, the code delivers a similar one, the screen explains a third version, and nobody decided that in any meeting. Drift never arrives as an accident. It arrives as a rush: one patch at a time, each one too small to deserve a discussion, until the day the document and the code describe different systems. This book’s anti-drift ruler fits in one sentence: in a FOCUS project with specs, every increment has one place to be born in, a contract the compiler collects on, and a pure test that rejects the wrong rule. When the increment is generated by a model, the sentence holds word for word: the single place becomes an instruction in the prompt, the contract becomes code pasted into the prompt, and the pure test becomes an acceptance criterion that runs in seconds. The evidence lives where it always has. Chapter 3 measures the damage of code generated with no structure: GitClear’s reports and the vibe coding Karpathy named are the evidence, and chapter 21 shows the opposite movement: specs and FOCUS narrowing the generator’s search space before the search even starts. No number got reprinted on this page, and that’s deliberate. A number ages; a chapter with a named source doesn’t. The material proof is public. The repository github.com/JCKodel/focus- coffee is chapter 22 in code: four slices, each one born from a spec committed before its code, with the defects the app had printed in that chapter right next to the fixes. Clone it, run the tests, read a spec, then read the slice it describes. The distance between what the document promises and what the code delivers is the measure that matters, and you measure it yourself, with no need to take my word for it. Q&A

Does FOCUS work for a small project? It works for a small, living project, and Rosie’s Coffee Shop is the proof: four slices, a database in a single file, and a simulated card reader. It doesn’t work for a small, dead project, the prototype that exists to answer one question and get thrown away; chapter 4 calls that cost speculative functionality, and I agree with it. When AI gets better, will architecture still matter? Models got better year over year while this book was being written, and the degradation measured in chapter 3 grew over the same period. A better model searches a bigger space, and faster. What architecture does is shrink the space where the search happens, and that math doesn’t change with the quality of the searcher. My bet: the better the generator, the more valuable the contract that decides what it’s allowed to generate. Do I need to adopt all four pieces at once? No. Extract one rule into a pure function that returns a Result (chapter 14). Push the exception to the boundary in the next repository you touch (chapter 15). Group by feature the next time a folder gets born (chapter 11). Each step pays for itself, with no need to wait for the others, and that’s exactly how FOCUS was born in my own code: distilled, not decreed. Quick reference Situation Fix New business rule pure function returning a Result (ch. 14) A rejection the screen needs to explain Result variant (ch. 8)

Database, network, or disk in play repository; the exception dies there (ch. 15) An event just left the screen, now what orchestrator publishes the state (ch. 13) The screen wants to decide something it doesn’t decide (ch. 12) Not sure which folder this belongs in the feature’s slice (ch. 11) The change opens three slices stop; talk before you code (ch. 11) Generating the slice with a model paste the contract and spec into the prompt (ch. 21) The code contradicts the spec that’s drift; fix the spec before the patch Legacy code with no tests ahead characterize, then strangle it (ch. 20) A throwaway prototype one file, no layers (chs. 4 and 22) Exercises

  1. Somewhere in your own backlog sits a deferred change request, the one you keep pushing back because you don’t know what it breaks. Write its spec in five lines: what the change must do and what it must refuse. Then answer which

slice it belongs in. If the honest answer is “three,” you just found the boundary that leaked, and the exercise paid off more than it would have if the answer had been a single one. 2. Take the oldest slice in one of your own projects and read what its documentation promises, a README, a card, or a comment at the top of the file. Mark every sentence the code no longer keeps. The count is your drift measurement, and it tends to surprise you. Could you bring that count down to zero by touching only the document, without changing a single line of code? Tip 23 Spec first, slice second, pure test in between: the increment born that way has an address, a contract, and a judge. The tip describes tomorrow morning’s routine, not a new ceremony. Before you open the editor, write what the change must do and what it must refuse; that’s the spec, even at five lines. Decide which slice the change belongs in; if the answer is “three,” the design is asking for a conversation before the code. Write the rule’s test as a pure function, and only then write the rule, with your own hands or with a model in the editor. The judge is the same one in both cases, and that’s why the routine doesn’t change when the tool does. This book started with a week spent hunting for a business rule with no address. It ends with the address. What it can’t hand you is the proof: that one is born in your own repository, on the day a change request you would have deferred opens a single folder and closes the same day. When that happens, you won’t need me to know it worked.

Powered by TurnKey Linux.