I've been utilizing LLMs heavy successful the past years successful coding, aliases much generally, successful software engineering. I watched galore times what productivity boost I could summation from it, and I utilized LLMs successful much and much of my projects. It useful good successful greenfield projects, and mini ones. The reality is that successful time to time activity we request to present agents into bequest codebases pinch dense dependency trees, beardown coupling, and a tech indebtedness backlog afloat of everything we ne'er sewage to. We quickly announcement that the value of activity LLMs tin present drops sharply.
The nonaccomplishment has a circumstantial shape. Ask for a "job connection status" section successful a greenfield repo and you get one. Ask for it successful a strategy that has been shipping for 4 years and the exemplary invents a 4th pronunciation of a conception that already exists 3 times, because the codebase itself ne'er decided which 1 was real. It writes an adapter wherever a telephone was fine, aliases calls consecutive done wherever an adapter was the full point. Every 1 of those is a question astir the strategy that the strategy does not reply anywhere. The exemplary guesses, and often guesses wrong.
So brownfield projects are deep, and method extent is only the first layer. Underneath sits a second one: confusion, missing meaning, and nary shared connection to resoluteness it in. That is the furniture the exemplary falls into. The exemplary is not what needs upgrading. The codification is not ready, and readiness is thing we tin build. Incrementally. Piece by piece. Let maine show you really I do it.
It is easier than before#
At the opening of package engineering location was the 1 and only: tech debt. It's a natural consequence of what we, arsenic devs, are trying to achieve. We're not fresh for business decisions from the early shifting our existent position of the code. We request to deliver, and present fast, paying immoderate tradeoffs. As a consequence, codification smell grows bigger and bigger. The accustomed answer is to walk portion of the engineering fund connected cleanups: earmark 10-20% of the exertion fund for resolving tech debt. In theory... In the adjacent quarter...
A 5th of the fund is the toll connected deciding what should alteration and past typing it out, and those 2 halves person ne'er had the aforesaid price. Deciding stayed astir arsenic costly arsenic it was. Typing it retired collapsed. An LLM will do the mechanical half of a cleanup (the extracted module, a refactor crossed 2 packages, much trial coverage) at a costs that nary longer resembles 2020. Paying tech indebtedness still takes time. It takes significantly little of it, and what is near for maine is the deciding part.
Strategic vs tactical#
I divided the activity successful two, and I'll get the words from John Ousterhout's A Philosophy of Software Design while being honorable that I'm bending them. He uses tactical and strategic for 2 attitudes you tin clasp while coding: tactical programming is getting-it-working-now, strategical programming is investing successful the creation arsenic you go. I usage the same brace for a divided of authorship, because the economics supra trim on that line. Strategic activity is deciding: reference the system, moving retired what has to alteration and why, and whether the alteration really serves the feature. Tactical activity is carrying that decision into the files. The first is the portion that needs the strategy successful your head. The 2nd is the part that sewage cheap.
What I do#
In the first 1 I'm afloat progressive and in the 2nd 1 I'm alternatively a reviewer than an implementer. In the first way I analyse the codebase successful a much generic way, assessing the changes that request to beryllium implemented and their alignment to the features I want to deliver. The effect of those approaches is GitHub issues I create successful each repository.
The issues are past addressed by my AI strategy based connected skills and sub-agents. A skill is a written procedure: a markdown record of instructions the exemplary loads erstwhile the task matches it, truthful "address an issue" aliases "regenerate the discourse map" runs the aforesaid measurement each clip instead of the measurement I happened to building it that morning. A sub-agent is simply a abstracted exemplary convention with its ain caller discourse and its ain constrictive occupation (implement, reappraisal for security, reappraisal against the spec), reporting backmost a consequence alternatively than dumping its full transcript into mine.
When they are implemented, PRs are fresh to jump into. I spell done the reappraisal sessions, accepting the changes aliases asking for immoderate improvements. I tin do that incrementally, caring about the trial sum and astir who breaks: earlier a alteration lands I request to cognize which other parts of the strategy devour the point I'm touching, and whether the alteration is 1 they can survive. Now, arsenic a package engineer, I coordinate, I plan, and I create a way for the improvements. But astatine that constituent I don't request to instrumentality that by myself. The clip is saved.
DDD arsenic a fundament#
That leaves the strategical half, and it is worthy precisely arsenic overmuch arsenic the connection it is written in. This is wherever DDD comes in.
DDD was ever 1 of my choices for package I could still alteration a twelvemonth later. The approach presented by Eric Evans gave america a measurement to shrink the connection spread betwixt the business and the method side. Domain-driven design, based connected ubiquitous connection and bounded contexts, translates what the business needs straight into the method part. Both sides talk in the aforesaid language. With agents successful the loop, that nexus matters moreover more: it is really we state our needs to the exemplary and really we publication its reasoning back. That is why I build connected it truthful heavily.
What I do#
Every repository I ain carries a .workflow.json astatine its root. It is my ain manifest, the spot a repo tells my tooling what it is: which languages it holds, which directories an supplier should publication first, which checks person to walk earlier activity successful it tin ship. One artifact successful it is astir the domain, and declaring that artifact is the only registration a repo needs. There is nary 2nd registry to drift retired of sync.
The artifact names the project, its bounded contexts, wherever each context's glossary lives, its subdomain type, and each separator to a neighbouring context. The illustration comes from a task of mine, job-offer-box, a occupation exertion locator built arsenic two repositories, a Rust backend I support nether the hyperion task and a web frontend. Here is the frontend's manifest, trimmed to a azygous edge:
Read it successful order. to is the address: which discourse connected the different end. guidance says who's calling whom; the web repo calls the backend, truthful outbound (the backend's ain manifest declares the aforesaid separator inbound). proprietor says whose exemplary wins if the 2 sides ever disagree: the backend's, truthful supplier. shape is the narration itself, picked from a closed vocabulary; here it's unclassified, because the web repo does 2 different things astatine once. It accepts the backend's style as-is erstwhile penning and translates it into its ain style erstwhile reading. The note spells that out; a azygous explanation would beryllium correct astir 1 lawsuit and incorrect astir the other.
Beside the manifest sits a CONTEXT.md per context, the surviving glossary pinch the precise meaning of each word and the deliberately rejected synonyms. Two files per context, some owned by the repo that owns the code. Nothing above them is authored: the discourse representation (the 1 archive showing each discourse successful the portfolio and each separator betwixt them) is derived. A generator, a book that walks each repo on disk, unions the domain blocks and emits it arsenic a azygous CONTEXT-MAP.md. The representation is disposable and regenerable.
Back to job-offer-box. hyperion/job-offer-backend owns the merchandise language. It persists Job Offer, Profile, Profile Variant, Resume, Cover Letter, nether the rule that wherever 2 contexts writer the aforesaid term, the 1 holding the durable authorities owns it. job-offer-box/job-box-web owns only the surface vocabulary (View Model, Filter State, Facet Stats) and marks everything other [published], arriving verbatim arsenic generated TypeScript from the backend's OpenAPI document. That is the level of precision an supplier needs. Point it astatine the web repo and it knows that renaming Job Offer location belongs to the backend, that the adapters connected the publication way beryllium connected purpose, and which words it is allowed to invent. With the representation the exemplary knows which discourse it is in, and pinch the glossary it knows the words utilized there.
Both sides declare, truthful disagreement is mechanical#
Every separator is declared twice, erstwhile from each side, and that plagiarism is the full point. The generator cross-checks the pairs, and it is observant astir what counts arsenic a disagreement: a supplier names its ain stance (published-language), a user names its ain (conformist, anticorruption-layer), truthful the cheque is simply a pairing table.
I tally it arsenic a skill, astatine 3 moments: erstwhile I person touched a manifest, erstwhile I americium onboarding a repo, and earlier I alteration thing different discourse depends on. Each disagreement it reports is a finding: 1 edge, 1 measurement the 2 declarations neglect to fit. With 1 flag, the accomplishment files each 1 arsenic a DDD rumor connected the repo that owns the incorrect side. The rumor carries a fingerprint (the benignant of uncovering positive the 2 addresses), truthful a re-run aft a half-fix updates the aforesaid issue instead of opening a 2nd one, and a uncovering that nary longer appears closes its issue. From there it follows the aforesaid spine arsenic everything other here: an issue, an agent, a PR, my review.
What comes next#
That is the strategical layer, and it is already successful place. It settles wherever a discourse ends and really it talks to its neighbours: the style of the map. The wrong of immoderate azygous discourse is still mean codification that lets you build a delirium entity and prevention it.
With the discourse representation successful spot and the glossary defined, I tin attraction connected the codebase itself: taking 1 discourse astatine a clip and migrating it to a existent domain exemplary built from DDD primitives (value objects, aggregates, domain services and others). That process makes the codebase answer the questions the exemplary was guessing at: what this connection means, who owns it, wherever this context stops. I'll stock the full strategy shortly, pinch the skills fresh to use. Subscribe truthful you don't miss it.
English (US) ·
Indonesian (ID) ·