pair-capability-map-contexts
Maps subdomains to DDD bounded contexts and derives the integration pattern between them (integration strength, socio-technical distance, volatility), scoped to items just touched. Composed by /pair-p
SKILL.md.claude/skills/pair-capability-map-contexts/SKILL.md
GitHub/pair-capability-map-contexts — Bounded Context Placement (Capability)
Map subdomains to bounded context boundaries and assess each relationship between contexts on three dimensions — integration strength, socio-technical distance, volatility — to derive the integration pattern. A capability, not a standalone lifecycle step: always invoked scoped to the contexts/services the caller just touched, never as a full re-mapping outside /pair-process-bootstrap.
Process Profile
<!-- process-step: id=define-bounded-contexts -->Executable form of the define-bounded-contexts step. A direct invocation while a step is disabled by the project's profile warns and asks for confirmation; under $approval: auto there is nobody to answer, so the run HALTs. <!-- approval-round: kind=gate; auto=halt -->
A composed invocation never prompts — it degrades exactly as a step that is not installed. No section ⇒ no-op. See process-profile gate.
Arguments
| Argument | Required | Description |
|---|---|---|
$scope |
Yes | Contexts/services touched by the caller (e.g. a context name, a service, the contexts implicated by a task). all — full re-mapping, allowed only when composed by /pair-process-bootstrap. |
$approval |
No | Approval-round mode: interactive (default — the Step 4 round runs as written) or auto (ask nothing: the proposed delta is accepted as-is, a conflict keeps the existing entry, both reported). auto does not lift the Step 3 gate — an unbalanced + volatile relationship with neither mitigation nor acceptance still HALTs. See approval rounds. |
Composed Skills
| Caller | When |
|---|---|
/pair-process-refine-story |
Technical analysis phase — identifies touched contexts/services. |
/pair-process-plan-tasks |
Identifies touched contexts/services for the task breakdown. |
/pair-process-brainstorm |
Punctual/technical discovery (phase 2) touching one or a few contexts. |
/pair-process-bootstrap |
Initial full-catalog mapping — the only caller allowed $scope: all. |
Invocable independently with an explicit $scope for ad hoc placement.
Algorithm
Step 0: Resolve Scope and DDD Adoption State
- Check: Does
adoption/tech/boundedcontext/contain.mdfiles beyond README.md (DDD already adopted)? - Check: If not adopted, are subdomains defined (
adoption/product/subdomain/has.mdfiles beyond README.md)? - Act: Resolve the working mode:
- DDD mode — bounded context catalog exists, or a subdomain catalog is available to map from.
- System-areas fallback — no context catalog AND no subdomain catalog. No DDD prerequisite is enforced; do not HALT. Proceed to Step 1 in fallback mode, treating existing services/modules as the context boundary.
- Check: Does
$scoperesolve to any context/service in the current codebase or catalog? - Skip: If
$scoperesolves to nothing → report "no domain impact" and return control to the caller. No file changes. - Verify: Mode and non-empty scope determined. When in DDD mode, also load (best-effort, warn if missing): architecture.md, tech-stack.md, way-of-working.md.
Step 1: Detect Existing Bounded Contexts
Check: Scan
adoption/tech/boundedcontext/for existing.mdfiles (excluding README.md).Act: Build a registry of existing contexts:
EXISTING CONTEXTS: ├── [filename.md]: [Title] (Type: [Core/Supporting/Infrastructure]) └── ...Verify: Registry built. Only entries touched by
$scopeare candidates for creation/update.
Step 2: Context Boundary Analysis (DDD mode)
Skip if in system-areas fallback — go to Step 2b.
- Act: Synthesize context boundaries for the in-scope items from multiple inputs:
- Subdomains: group related in-scope subdomains based on business cohesion, and read their
Volatilityrating. - Architecture: service decomposition patterns, consistency requirements.
- Tech stack: database choices, communication protocols.
- Way of working: team structure, ownership model.
- Subdomains: group related in-scope subdomains based on business cohesion, and read their
- Act: For each in-scope context, determine Type — Core (high autonomy), Supporting (medium autonomy), Infrastructure (shared services) — and subdomain grouping rationale.
- Verify: In-scope context boundaries identified.
Step 2b: System-Areas Fallback (no-DDD projects)
- Act: Treat each existing service/module touched by
$scopeas a provisional context boundary — Type inferred from its role (an entry point/API service reads as Core or Supporting; a shared library reads as Infrastructure). - Act: Relationship assessment (Step 3) still applies between system areas — the three dimensions do not require a DDD catalog to be meaningful.
- Verify: Placement resolved to system area(s). Note in output that this is a fallback, not a DDD classification.
Step 3: Relationship Assessment (3 Dimensions)
For each relationship between an in-scope context and another context it touches:
Act: Assess integration strength — how tightly coupled the two contexts are at the code/data level:
intrusive— shared database/schema or direct internal access.functional— synchronous call dependency (must respond to operate).model— shared domain model/types without a formal contract.contract— explicit interface (API/event schema) between independently deployable contexts.
Act: Assess socio-technical distance — team/organizational distance between the owning teams (same team = low; different team, same org = medium; different org/vendor = high).
Act: Assess volatility — read from the subdomain(s) underlying each side of the relationship (
Volatilityfield from subdomain-template.md); for generic subdomains, factor in the recorded implementation volatility.Act: Derive the balanced/unbalanced outcome:
- High socio-technical distance ⇒ pattern should be
contract(or an anti-corruption layer). If the current/proposed strength isintrusive/functional/modeldespite high distance → unbalanced. - High integration strength with low distance ⇒ co-location in the same context is appropriate; keeping them as separate contexts despite high strength → unbalanced.
- Otherwise → balanced.
- High socio-technical distance ⇒ pattern should be
Act: Annotate contract-coupled relationships (
contractstrength) as "contract tests expected" — downstream story validation strategies touching this relationship inherit the contract/boundary test categories (coupling-balance guideline, see Notes).Check: Is the relationship unbalanced AND volatile (either side rated
Volatility: High)?Act: If unbalanced + volatile → gate at approval: proceed only once one of the following is recorded:
- A mitigation (e.g. introduce an ACL, renegotiate the pattern toward
contract), or - An explicit developer acceptance of the risk (recorded in the context file).
This gate is not an approval round and
$approval: autodoes not lift it — it is the judgement kind (approval rounds): with neither a mitigation nor an acceptance on the table there is no proposal to auto-accept, and Step 5 would write a domain model recording a coupling risk nobody judged. So it HALTs under every value of$approval, and it is the one place a non-interactive run of this skill can still stop for a human. <!-- approval-round: kind=gate; auto=halt -->- A mitigation (e.g. introduce an ACL, renegotiate the pattern toward
Verify: Every in-scope relationship has strength, distance, volatility, outcome, and (if gated) a mitigation/acceptance recorded.
Step 4: Context Catalog Delta Proposal
Check: Does an in-scope context already exist in the registry with a different Type/relationship set (catalog conflict)?
Act: If a conflict exists → propose the delta only (not a full re-map). Under
$approval: autoa conflicting delta is not applied: the existing entry is kept and the delta is reported unapplied, since overwriting a recorded placement nobody was asked about is the one outcomeautomust not produce.Act: Present the scoped catalog delta to the developer (
$approval: interactive; underautoit is reported in the Output Format instead of asked):Proposed bounded context placement (scope: [$scope]): [Type]: [Name] — subdomains: [list]
Relationships:
- [Context A] ↔ [Context B]: strength=[intrusive/functional/model/contract], distance=[low/medium/high], volatility=[from subdomains], outcome=[balanced/unbalanced] [if gated] ⚠ unbalanced + volatile — mitigation: [...] or accepted: [...]
Approve or adjust? <!-- approval-round: kind=confirm; auto=accept -->
Verify (
$approval: interactive): Developer approves the delta, including any gated relationships' resolution. Underautothe delta is accepted as-is (already reported in item 3) — but a gated relationship is never auto-resolved: Step 3 item 7 has already HALTed unless a mitigation or an acceptance was recorded. <!-- approval-round: kind=confirm; auto=accept -->
Step 5: Context Specification
For each approved context in scope:
- Check: Does this context already exist as a file?
- Act: If exists and no conflict was raised → leave untouched; pre-existing relationships without the 3-dimension assessment remain valid as-is (no forced migration — assessed the next time that relationship falls inside a
$scope). - Act: If new, or an approved delta applies → create/update the context file following bounded-context-template.md (resolve override-first — template resolution):
- Fill all template sections: Type, Subdomains Covered, Business Scope, Relationships (with the 3-dimension assessment per relationship), Integration Patterns, Data Ownership, Team Alignment, Ubiquitous Language, Quality Attributes, Encapsulated Knowledge, Change Vectors.
- File path:
adoption/tech/boundedcontext/[kebab-case-name].md
- Verify: File created/updated and parseable. Entries outside
$scopeare untouched.
Step 6: Update Catalog README
- Act: Update
adoption/tech/boundedcontext/README.mdfor the entries touched by this run:- List all contexts with subdomain mappings.
- Include integration overview, flagging gated (unbalanced + volatile) relationships.
- Link to individual context files.
- Verify: README reflects the current catalog.
Output Format
CONTEXT PLACEMENT COMPLETE:
├── Scope: [$scope]
├── Mode: [DDD | System-areas fallback]
├── Touched: [N contexts]
├── Created: [X new files]
├── Updated: [Y existing files]
├── Relationships: [balanced: A, unbalanced: B, gated: C]
├── Approval: [interactive — approved | auto — accepted as-is, D conflict(s) kept unapplied]
├── Location: adoption/tech/boundedcontext/
└── Next: /plan-epics (scoped) or back to the calling process skill
The Next: line names only steps enabled by the project's process profile: a disabled one is dropped, and when none is left the line names no skill.
Edge Cases and Error Handling
- Scope resolves to nothing — report "no domain impact", caller proceeds without HALT.
- Existing catalog conflicts with scoped update — always propose the delta and require human approval before writing (idempotent behavior preserved). Under
$approval: autothe write does not happen either: the existing entry is kept and the delta is reported unapplied (Step 4 item 2). <!-- approval-round: kind=keep-or-redo; auto=keep --> - Pre-existing relationships without the 3-dimension assessment — treated as valid; assessed only when that relationship falls inside a future
$scope. - No
subdomain/orboundedcontext/artifacts at all — system-areas fallback (Step 2b); no error, no DDD prerequisite. - Unbalanced + volatile relationship, no mitigation/acceptance offered — HALT at Step 3 item 7, where the gate is raised (before Step 4's delta round, which never sees the relationship). This is the one case where the capability blocks, under every value of
$approval: a judgement gate is not suppressible by a non-interactive signal. $scope: allrequested by a caller other than/pair-process-bootstrap— warn and downgrade to the caller's actual touched items; full re-mapping stays bootstrap-only.
Graceful Degradation
See graceful degradation (adoption files missing → warn, proceed with what's available rather than halting) for the standard scenarios. Additional cases:
- If architecture or tech-stack adoption files are missing, warn and infer boundaries from subdomains alone.
- If subdomains have no
Volatilityfield yet, treat volatility as unknown/Medium for the assessment and note it as provisional. - If neither a subdomain nor a bounded-context catalog exists, use the system-areas fallback (Step 2b) rather than halting.
- If the adoption directory doesn't exist, create it.
- If README.md doesn't exist, create it from scratch.
Notes
- This skill creates/updates adoption files — not PM tool issues. Bounded contexts are design artifacts.
- Idempotent — see idempotency convention. This skill's check: detects existing files by filename; only entries inside
$scopeare evaluated for changes. - The 3-dimension relationship assessment (strength, distance, volatility) is the input to the coupling-balance guideline — see
.pair/knowledge/guidelines/architecture/design-patterns/coupling-balance.md(introduced by #209); until that guideline lands, apply the heuristics in Step 3 directly. - Contract-coupled (
contractstrength) relationships are annotated "contract tests expected" —/pair-capability-design-manual-testsand story-level validation strategies should pick up the contract/boundary test category for that relationship. - Migration: this skill was reclassified from a process skill (
process/map-contexts) to a capability (capability/map-contexts) — see skills-guide.md for the rename and new invocation paths.