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...
Installs into .claude/skills of the current project.
Are you the author of Context Map?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/gbourgeat-context-map)
---
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.