context-map · git:20261010.c6c87e0 · 2026-10-10 · sha256 c4f0bbc85b29f44f

context-map git:20261010.c6c87e0A

Immutable. This exact content never changes and is served at /api/v1/blob/c4f0bbc85b29f44f.

---
name: context-map
description: >-
  Draws and maintains the context map of a ddd-ts-kit project. For every pair of contexts
  that collaborate, names the upstream, the downstream, the relationship pattern
  (published-language, customer-supplier, conformist, anti-corruption-layer,
  open-host-service, shared-kernel) and the contract exchanged, with no cycle. Use when two
  contexts start depending on each other, when a context needs data or a reaction from
  another, when choosing or changing a relationship pattern, when context/no-cycle or
  context/declared-relationship is reported, or as the context map step of a new project.
  To implement the exchange use integration-event.
argument-hint: "[downstream upstream]"
allowed-tools:
  - Read
  - Write
  - Edit
  - Bash(npx ddd-ts-kit list *)
  - Bash(npx ddd-ts-kit docs)
  - Bash(npx ddd-ts-kit docs --check)
  - Bash(npx ddd-ts-kit check *)
---

# Context map

Relationship under discussion: `$ARGUMENTS`

A relationship is declared, never implied by an import. The pattern is the owner's decision:
it says who adapts to whom, which is a matter of teams as much as of code.

## 1. List the collaborations

From the policies and read models of the discovery ("whenever X happened, then Y"; "needs to
see Z"), or from `npx ddd-ts-kit list --json`. For each: who knows a fact first (the
**upstream**), who needs it (the **downstream**), and what crosses.

| Need of the downstream | What crosses | Built later with |
|---|---|---|
| react to something that happened | an integration event | `generate integration-event`, `generate integration-handler` |
| data to decide, often | a local projection fed by events | the same, plus a read model |
| an answer now | a read contract behind a port of the caller | `generate gateway` |
| change the other's state in one transaction | nothing can: one context, or a process in steps | back to `ddd-ts-kit:bounded-contexts` |

## 2. Choose the pattern

| Pattern | Choose when | Cost |
|---|---|---|
| `published-language` | default: the upstream publishes contracts made for its consumers | the upstream keeps them stable and versioned |
| `customer-supplier` | the downstream's needs are planned into the upstream's work | coordination between the two owners |
| `conformist` | the downstream accepts the upstream model as it is | the downstream moves when the upstream does |
| `anti-corruption-layer` | the upstream model is foreign, legacy or generic: the downstream translates it | a translator to maintain in `infrastructure/anti-corruption/` |
| `open-host-service` | the upstream serves many consumers through one protocol | a public contract, hard to change |
| `shared-kernel` | two contexts co-own a small model | joint ownership of every change; justify it |

No cycle. If A needs B and B needs A: they are one context, or one direction becomes an
event, or a third context is missing. A `generic` context is upstream of the others, behind an
anti-corruption layer when its model is not yours.

## 3. Write it

Before the bootstrap, `docs/architecture/context-map.md`:

```markdown
# Context map (draft)
| Downstream | Upstream | Pattern | What crosses | Why this pattern |
|---|---|---|---|---|
| billing | ordering | published-language | event `ordering.order.placed` | billing reacts, ordering knows nothing of invoices |
```

The bootstrap turns each row into `--upstream <upstream>:<pattern>` and moves the last column
to `docs/context-map.md`, then deletes the draft.

After the bootstrap, the relationships live in `contexts.<downstream>.upstreams` of
`ddd-ts-kit.config.json` (the owner confirms the edit; a new context takes
`--upstream <ctx>:<pattern>` at creation). Then `npx ddd-ts-kit docs` redraws the diagram and
the table between the markers of `docs/context-map.md`. Write outside the markers, and only
what the diagram cannot say: the reading guide (three lines on the main flow), why each
debated boundary, why each pattern other than `published-language` and what it costs, known
tensions with the signal that would trigger a split or a merge.

Finish with
`npx ddd-ts-kit check --rule context/no-cycle --rule context/declared-relationship --rule config/valid`.

## Done when

Put this to the owner: **does every arrow have a pattern, a named contract and a reason,
and is there no cycle?** On a yes, the next step is `ddd-ts-kit:bootstrap`, which the user
starts.