Create a bounded context

The second journey: from what your system is specified by to one durable spec per bounded context, with its business rules confirmed by a person, its architecture written as text, and its spec attacked before anyone plans against it. It covers a PRD, an API contract, a context you describe, and a spec your team wrote before Partition, each a source that enters the same way. Why bounded contexts come from a source is in Why Partition; where each document of this article lives is in the repository map; the configuration it adds to is the one of Set up a project.

Create a bounded context, always from a source, a context you describe included. When a document describes it (an API contract, a PRD, a spec written before Partition): A, you name the source, read where it lives, any file of the repository or a URL; a source pasted in the chat, or a contract at a URL, is saved first, validated by you and committed alone. When there is no document behind it, described in the chat: A, you describe the context, saved as a source under docs/sources/, validated by you and committed alone; it joins the same path at B. Then: B, the assistant decomposes it with partition-shape, from the source and the area you name, weighing every unit against the six criteria, and the architect picks the way, a workshop or a proposal; C, a hard stop where you validate the split, each new context by name; D, partition-shape writes one spec per context, pointing to its source, with the rules, invariants and decisions the source states copied under "TO VALIDATE"; E, you confirm and fill the business rules, and until the banner comes off the context is not fit for design; F, partition-attack attacks the spec before planning and writes its findings into it; G, partition-hexagon and partition-c4 choose its form and its container in the C4 model. Then design and deliver, in journey 3.

In the figure, a blue step is the assistant with the skill it uses; an amber step is yours.

The situation

Partition is installed and configured, and your repository has no durable spec yet, or not for the part you are about to build. Somewhere there is a document that says what the system must do: a PRD from the product owner, an API contract, a team’s notes, or a long specification written before Partition. You want the assistant to work from one spec per bounded context, true now, without it inventing a rule or drawing a boundary for you.

What you bring

A source, as a file, committed alone. A source is what the system is specified by: an API contract, a PRD, a spec written before Partition, or a context someone describes. It is read where it lives: any file of the repository, whatever its folder, or a URL. A source you write for Partition goes, by default, to docs/sources/, a contract to docs/contracts/, each under a stable name that every new version overwrites (the repository map says who puts what there). In the guide, [PO] brings the PRD. Commit the source alone, before the prompt that reads it: the decomposition records the commit of the source, and every later version is compared from it. A source decomposed uncommitted is recorded as uncommitted, and its next version has no base to be compared from.

You may paste the source in the chat instead. The assistant then never decomposes from the chat: it asks you for a file name, writes the source to docs/sources/ (a contract to docs/contracts/), shows it and waits for your validation. Commit it alone before you go on. A contract you give by its URL is saved the same way first; a document at a URL is read where it is, recorded with its version or the date it was read.

A context with no document behind it, described. When nothing is written yet, you describe the context in the chat. The assistant saves your description as a source under docs/sources/, under a name you give, shows it and waits for your validation; you commit it alone, and it is decomposed like any other source.

The area. The folder under docs/specs/ the bounded contexts go into, such as billing. It is mandatory and never inferred: not from the name of the source, its title or a heading, not even when one source is all there is. When you do not name it, the assistant asks, showing the areas that exist.

The architect’s choice of how to decide the boundary. Before a boundary is shown as a decision, the assistant asks the architect which way: a workshop, or a proposal. In the guide, [architect] answers a proposal.

The code path of each new bounded context. The assistant asks; it never guesses one from your folders. In the guide, [TL] gives it. Until it is given, the context is declared without it and the question stays open.

The confirmation of the business rules, and the language. A person confirms each rule the source states, writes the missing ones, and gives the meaning of each word, one meaning per word. In the guide, [BA] does it. When the source contradicts itself, the owner of the source says which requirement holds: in the guide, [PO].

For the architecture, when you describe it now. The team’s hand-drawn .drawio file if there is one, and the answers it leaves open: what each box is (a system, a container, a component) and what it belongs to. The form of each hexagon and its layer map, with the reason. In the guide, [architect] brings all three.

For a spec written before Partition: the file, where it lives, committed alone. A specification your team wrote before Partition, wherever it lives (the guide puts it in docs/legacy/, an example, not a convention), committed alone before you ask. It is not moved under docs/sources/. The person who owns it validates it as the source: it still describes what the system must do. In the guide, [BA]. How many bounded contexts it describes is the architect’s decision, as for any source.

What you say

From a source already in the repository, name the source and the area, as the README does:

Decompose docs/sources/<name>.md into bounded contexts, area <area>.

From a source pasted in the chat, as the guide does, after pasting it:

Here is our PRD. Find its bounded contexts.

Answer its questions: the file name, the area. Once the source is saved, commit it alone, then say “Go on.” When it asks how to decide the boundary, answer “A proposal.” or “A workshop.”. Validate the writing plan by name: “Create the bounded context <name>.”

To confirm the rules, once you have read them, in the guide’s words:

I confirm BR-1 to BR-6 as written; there is no other rule. Here is the language of <bounded-context>: (your table of terms and meanings).

To describe the architecture, one piece of planned work, as the guide does:

Open a plan for the architecture baseline: the C4 model from docs/architecture/<diagram>.drawio, the hexagon of <bounded-context>.

or one request at a time, from the README’s Day to day: “Turn our draw.io into the model.”, “Add a container.”

Before you plan, from the README’s Day to day:

Attack this spec before we plan.

From a spec written before Partition, as from any source, at its path, as the guide does:

Decompose docs/legacy/<file>.md, area <area>.

For a context with no document behind it, describe it in the chat and ask for its bounded contexts, as for a pasted source: partition-shape answers, and the steps are below.

What comes back

From a source: partition-shape, up to a hard stop

partition-shape reads the source restricted to its scope (the whole source unless you name one) and inventories its units: an operation of an API contract, or a requirement or story of a document under its anchor, or a section when the document identifies none. A part that only records decisions, defines terms or gives context is not a unit. For a contract, a script reads the file and prints only what the decision needs, so the assistant does not load tens of kilobytes; a document is read.

Each unit is weighed against the six written criteria. A bounded context is retained only when it has a root aggregate of its own and one more reason: its own language, its own life cycle, or its own named external dependencies. Shared data or shared business rules argue against a split. Three outcomes are legitimate: several bounded contexts, a single one, or a source too ambiguous to decide, in which case the assistant lists the ambiguities, asks, and writes nothing. A decision not to split is justified as explicitly as a split.

The architect decides the boundary. Before it shows a decision, the assistant tells you what is at stake (the units, the candidate aggregates, the zones the criteria leave open), says that the decision is the architect’s, and asks which way you want, unless your request already named it:

A point the architect keeps against a criterion is recorded with the criterion, the names, the date and the reason, and is not proposed again unless a later version of the source changes, for the units of that point, the criterion it was kept against.

Then the hard stop: the writing plan, before anything is written. For example:

Source             : docs/sources/billing.md
Version            : 1.0
Provenance         : <sha of the source's commit>
Scope              : whole source
Units read         : 5 in scope / 5 in the source
Out of scope       : none
Bounded contexts   : invoice (1 retained)
Decided            : proposal, option 1 · you, as [architect]

Writing plan:
  + docs/specs/billing/bounded-contexts.md
  + docs/specs/billing/invoice/spec.md
  ≈ docs/partition.yml                      (declares invoice: area billing, code paths to ask)

Copied from the source (word for word, to confirm):
  invoice  rules      : "An invoice is issued once per order" (REQ-1), ...

It waits for an explicit validation. A new bounded context is validated by name; a general “go ahead” does not cover it. With a proposal, its name is the assistant’s, from the naming rule of the criteria: you keep it or choose another when you decide the boundary. An answer that asks for another split sends it back to the decision.

What is written, once you validate

A rule the source states is never rewritten, and no rule is ever deduced: not from a field name, an example or the code. With none stated, Business rules keeps its “TO FILL” banner. A contradiction inside the source is not settled by the assistant: it asks the owner of the source which requirement holds and proposes no wording. A contradiction with what the repository already holds is reported to you as a gap, never settled. The closing report lists the files written, the sections whose banner is still up, with the explicit mention that these bounded contexts are not usable yet, the gaps to settle, the candidates for the invariant register with their verdict (“no candidate retained” is the normal outcome), and the open questions that block the design.

A context you describe: saved as a source first

When no document describes the context, partition-shape still creates it, from a source: your description. It asks you for a name, writes the description under docs/sources/, shows it and waits for your validation, then decomposes it as above, up to the same hard stop. partition-spec writes the spec of each context partition-shape retains; it never starts a bounded context on its own. When your description states no rule, Business rules keeps its “TO FILL” banner until a person writes them. The architect still decides where the boundary goes; the assistant never decides one.

The language: one meaning per word

When you give the language, partition-spec writes each word with one meaning. A word you give two meanings inside one bounded context is not written: the assistant asks which meaning holds there and whether the other belongs to another bounded context, recalls that a word meaning something else in a neighbour marks a boundary, and records the question under Open questions until a person settles it. In the guide, “Cancelled” means “voided before any payment” for one invoice and “reversed within 24 hours” for another: the question stays open, and a later workshop answers it with a split.

The rules confirmed, and the banner removed

When you confirm the copied rules and fill the missing ones, the banner comes off. Until then the bounded context is not fit for design or implementation, and the assistant says so: asked for the form of the hexagon while the banner stands, partition-hexagon says the form cannot be chosen, and gives no reading of the copied rules.

The architecture: the C4 model as text, and the form of each hexagon

partition-c4 keeps the architecture in one text file, docs/architecture/model.yml: systems, containers, components, their relations and their views. When it does not exist, it starts from the template, or from your hand-drawn .drawio file, read once, from its boxes, nesting and arrows. A box whose kind or parent the drawing leaves open is a question to you, never a guess, and an element enters only when a source establishes it: the code, a decision, the owner. It then validates the model and generates docs/architecture/c4.drawio, one page per view, and shows you both outputs. Your hand-drawn file stays untouched; from then on the model is the source, and the generated file is changed by hand only to move, resize or reroute, which the next generation keeps. Each container and component carries its bounded context; a relation between two bounded contexts is a contract, written in Contracts with neighbours of both specs.

With the banner gone, partition-hexagon chooses the form of each hexagon with you, reading the Business rules of the spec, not the code: thin (no domain layer, ports and adapters in full) or rich (a domain model that depends on nothing). In the guide, a status that moves under conditions, with forbidden transitions, makes invoice rich. The form, its reason and the layer map go under the bounded context in docs/partition.yml; a form with no reason is refused, and the layer map is the architect’s, never inferred from the folders. When the project has no check that fails the build on a forbidden dependency, it proposes one with the tool of your ecosystem, generated from the map, and lets you choose.

The attack: before anyone plans

partition-attack reads the spec as a reader who did not write it and wants it to fail now rather than in production. It reads the spec, the area file, the invariant register and the contracts the spec names, nothing else of the neighbours. It builds the sequences of events that break each rule, looks at the other entry points that must enforce it, the access, the data, the session, the inputs, the contract, the budget and the words, and says which attacks it skipped and why. Its findings, most severe first, each a scenario you can replay with its impact and the sentence that is missing, go into the spec, under Open questions; it changes nothing else and proposes no implementation. You settle each finding; then the spec moves, then the code. A finding left open blocks every task that implements what it reaches.

A spec written before Partition: decomposed as a source

A specification your team wrote before Partition cannot be used as is: it is a source like any other, and it takes the path above. partition-shape reads it where it lives, with its reader of a document, and never changes it: no line is added at its top, no annex is written. The decomposition records its path and the sha of its commit, so a later version of the old spec is followed by the delta, as any source is.

It is assessed by the decomposition itself, and the assistant decides none of it:

Three kinds of part an old spec often holds are read as the reader says, none copied whole:

A rule another spec already holds is reported, never moved by the assistant. When a spec of another area holds it, it spans two areas: it is quoted with its anchor under Applicable area rules and invariants of the new spec, as a candidate for the admission test, and listed among the gaps with the file and the identifier that hold it. When it fails the test, a person names its owner; then partition-spec writes it into the owner’s Business rules, sourced to the ruling and to that validation, and the others consume its result through the owner’s contract. A copy that another spec took from its own source stays there, reported as a duplicate, until that source is amended: a rule copied from a source changes only through its source.

In an existing codebase, once the rules of a new bounded context are confirmed, run the spec-auditor agent on it: it reports where the code and the spec disagree and which side is wrong, and the spec moves first (Change at any moment).

After the decomposition of an old spec, as of any source, what remains is a person’s confirmation of the business rules before any plan, the attack, and the form of each hexagon. The decomposition writes documents only: the code follows later, one bounded context at a time, each through a plan of its own.

What you decide

Then the bounded context is fit for design, and its work goes through a plan, in the next journey.

Go deeper

Back to the series.