AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Designing Contracts First

skill-lockp111-agent-ddd-engineering-designing-contracts-first · by lockp111

Use when two bounded contexts need to communicate, when defining cross-context APIs, or when tempted to directly import types from another context's package — even in a monorepo. Use when encountering cross-context coupling, missing anti-corruption layers, or shared domain models across boundaries. 契约优先, 防腐层, ACL, anti-corruption layer, port interface.

No reviews yet
0 installs
27 views
0.0% view→install

Install

$ agentstack add skill-lockp111-agent-ddd-engineering-designing-contracts-first

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-lockp111-agent-ddd-engineering-designing-contracts-first)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
5mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Designing Contracts First? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Designing Contracts First

Overview

This skill forces a "Contract-First" development approach. Before any internal business logic or database operations are written, you must define the strict, pure interfaces (Anti-Corruption Layers) that dictate how different Bounded Contexts communicate. This prevents tight coupling and ensures AI coding sessions do not hallucinate cross-domain dependencies.

Foundational Principle: All rules in this skill are mandatory constraints. ACL is mandatory for ALL cross-context communication, regardless of deployment topology (monorepo, monolith, microservices). Self-approval or async workarounds are violations. No business logic until contracts are explicitly approved by a human.

When to Use

  • When starting implementation of a newly mapped Bounded Context; when an entity in Context A needs data from or must trigger an action in Context B; before writing any Service, Repository, or internal Domain logic that relies on external boundaries; or in a monorepo — ACL applies equally there.

Do NOT use when: Communication is within the same Bounded Context (use [coding-isolated-domains](../coding-isolated-domains/SKILL.md) for intra-context work), or context boundaries have not yet been defined (REQUIRED PREREQUISITE: [mapping-bounded-contexts](../mapping-bounded-contexts/SKILL.md)). Single-context projects: If Phase 2 identified only one Bounded Context with zero cross-context interactions, this phase produces an empty contracts artifact — write docs/ddd/phase-3-contracts.md with a "No cross-context interactions" note, mark Phase 3 complete, and proceed directly to Phase 4. The Boundary Challenge and interface drafting steps do not apply when there are no boundaries to design.

Quick Reference

| Step | Action | Output | |:---|:---|:---| | 1 | Review Context Map | Relationship pattern confirmed | | 2 | Boundary Challenge | Pass / Roll back | | 3 | Draft Pure Interfaces & Boundary Structs | Interface definitions + boundary structs | | 4 | Human Review | Contract frozen | | 5 | Persist to Filesystem | docs/ddd/phase-3-contracts.md |

Ambiguity Handling

Follow the [Ambiguity Handling Protocol](../ddd-protocol/ambiguity-handling-reference.md) throughout this phase.

Phase 3 STOP triggers — confirm immediately:

| Ambiguity | Why STOP | |:----------|:---------| | Cross-context data fields (what crosses the boundary) | Wrong fields = wrong contract → Phase 3 must redo, Phase 4-7 cascade | | Sync vs async communication pattern | Wrong pattern = wrong interface type → Phase 4 technical decisions invalidated | | Error contract (which errors cross the boundary) | Missing error contracts create silent failures in production | | Contract leaks deep domain concepts across boundary | If domain-internal types, aggregate roots, or invariant-bearing entities are exposed in the contract, STOP — the contract has become a domain coupling channel, not a boundary |

Phase 3 ASSUME & RECORD — proceed with explicit assumption:

| Ambiguity | Default assumption | |:----------|:------------------| | Parameter naming in boundary structs | Use the most descriptive business term from the Ubiquitous Language | | Boundary struct field ordering | Alphabetical within logical groups | | Interface method granularity (one method vs split) | One method per business operation; split only if clearly distinct |

Orchestrator Mode Exception

When invoked by an orchestrator (full-ddd, iterating-ddd, piloting-ddd, restructuring-ddd, importing-technical-solution) in Autonomous Mode, the interactive Q&A steps (2, 4) are replaced by autonomous execution:

  • Skip the interactive Boundary Challenge and Human Review. Instead, the Boundary Challenge becomes an agent self-check (per [ambiguity-handling-reference.md](../ddd-protocol/ambiguity-handling-reference.md)): the agent evaluates whether contracts leak deep domain concepts and, if they do, triggers STOP rather than asking the human.
  • Autonomous Boundary Challenge self-check: The agent verifies each contract against: (1) Does the ACL exist as a pure interface? (2) Is cross-context communication going through the ACL, not direct import? (3) Would removing the contract break only the expected consumer context? If any check fails → STOP and ask the human. If all pass → record as ASSUME in docs/ddd/assumptions-draft.md.
  • Apply STOP/ASSUME protocol: STOP for Phase 3 STOP triggers (above), ASSUME & RECORD for Phase 3 ASSUME items (above).
  • Persist the interface contracts and boundary structs immediately (Step 5). Do NOT wait for human approval — the orchestrator manages the approval gate.
  • Return the interface contracts and boundary structs to the orchestrator. If STOP was triggered, return the STOP reason instead.

This exception applies ONLY when dispatched as a subagent by an orchestrator. When invoked standalone (user directly asks for contract design), the full interactive Q&A session with Boundary Challenge and human approval gate is mandatory.

Implementation (Interactive Q&A Session)

CRITICAL RULE: Do NOT just generate the contract files and stop. Guide the user through an interactive, step-by-step API design process.

  1. Review Context Map: Confirm the relationship pattern from mapping-bounded-contexts and explain it to the user.
  2. Boundary Challenge: Verify each contract against three criteria: (1) Does the ACL exist as a pure interface? (2) Is cross-context communication going through the ACL, not direct import? (3) Would removing the contract break only the expected consumer context? Then ask the user: "Does this contract require sharing deep domain concepts (e.g. a massive God object) tightly across boundaries? Or is it passing minimal needed data?" If any criterion fails or sharing too much → STOP. Advise reverting to mapping-bounded-contexts to redraw boundaries.
  3. Draft Pure Interfaces & Boundary Structs: Define logic-less interfaces, interface types, and validation boundary structs mapped only for the external boundary — not the domain core.

Logic-less criteria: Interface method signatures contain no if/switch/for branching or business rule evaluation. Boundary structs perform format-level validation only (type conversion, nil checks, range limits) — business rule validation belongs to the consuming domain layer, not the contract boundary.

  1. Human Review: Present types, interfaces, schemas. Ask: "Does this API contract fulfill both contexts without leaking internal business rules? Do you approve?" Do NOT write business logic until explicit approval.
  2. Persist to Filesystem: After user approval, write all approved contracts to docs/ddd/phase-3-contracts.md. Include: context map reference for each contract, Boundary Challenge result and assessment, full interface definitions, and boundary struct code. Use the template from ../full-ddd/templates/phase-3-contracts.md (read the template file; populate fields from session output). Update docs/ddd/ddd-progress.md Phase 3 status to complete. Append key decisions to docs/ddd/decisions-log.md. This step is mandatory — do not skip even if contracts are already visible in the conversation.

> 语言约定: 本技能的接口设计原则是语言无关的。语言专属的项目结构和接口定义惯用约定请参阅 [language-conventions](../language-conventions/SKILL.md)。

Example (Go)

// ✅ Correct: Pure contract definition acting as ACL
// Defined in the Order context's domain layer — zero infrastructure imports

// Boundary structs for cross-context data
type ReservedItem struct {
	SKU      string
	Quantity int
}

type InventoryReservedEvent struct {
	ReservationID string
	CartID        string
	ReservedItems []ReservedItem
}

// Port interface for the external dependency
type InventoryServicePort interface {
	Reserve(cartID string, items []CartItem) (*InventoryReservedEvent, error)
}

NEXT STEP: → [architecting-technical-solution](../architecting-technical-solution/SKILL.md)

Loading Guidance

This skill references supporting files on demand — do not load them all upfront:

  • Before Step 1: Read docs/ddd/phase-2-context-map.md (Bounded Context map + ubiquitous language). This is the mandatory input for contract design.
  • Before Step 2: Read docs/ddd/phase-1-domain-events.md for event definitions used in async contracts.
  • Step 2 (Boundary Challenge): Read [contract-design-reference.md](./contract-design-reference.md) § Boundary Challenge Checklist and § Sync vs Async Decision for assessment methodology.
  • Step 3 (Draft Interfaces): Read [contract-design-reference.md](./contract-design-reference.md) § Port Interface Structure and § Common Contract Mistakes for interface patterns and anti-patterns.
  • Step 3 (Worked Example): Read [example-contract-walkthrough.md](./example-contract-walkthrough.md) § Step 3 for Go code examples of boundary structs and error contracts.
  • Before Step 4 (Go): Read ../language-conventions/SKILL.md to detect project language, then load the language-specific convention file for naming rules and interface patterns.
  • On first STOP/ASSUME decision: Read ../ddd-protocol/ambiguity-handling-reference.md.

Self-Check Protocol

Follow the [Persistence Defense Reference](../ddd-protocol/persistence-defense-reference.md) after Step 5, with this context-specific item 4:

  1. Phase 3 Artifact Exists: Verify docs/ddd/phase-3-contracts.md exists and contains interface contracts and boundary structs for all cross-context interactions. Single-context exception: If Phase 2 identified only one Bounded Context, the file should exist with a "No cross-context interactions" note — this is a valid pass.

If the check fails → STOP. Write the missing file. Do NOT proceed to Phase 4.

Note: This skill has no platform hooks. When invoked by an orchestrator ([full-ddd](../full-ddd/SKILL.md), [iterating-ddd](../iterating-ddd/SKILL.md), [piloting-ddd](../piloting-ddd/SKILL.md), [restructuring-ddd](../restructuring-ddd/SKILL.md), [importing-technical-solution](../importing-technical-solution/SKILL.md)), the orchestrator's hooks provide Layer 1 defense. When invoked standalone, this Self-Check Protocol (Layer 2) is the primary defense.

Session Recovery

If a Phase 3 session is interrupted:

  1. Check docs/ddd/ddd-progress.md — read Phase 3 status.
  2. If docs/ddd/phase-3-contracts.md exists and is complete (contains interface contracts and boundary structs for all cross-context interactions): Phase 3 is done. Proceed to Phase 4.
  3. If phase-3-contracts.md exists but is partial: Read the file to determine which contracts were written. Resume from the first missing contract.
  4. If phase-3-contracts.md does not exist: Restart from Step 1. Re-read docs/ddd/phase-2-context-map.md for relationship patterns.
  5. Single-context exception: If Phase 2 identified only one Bounded Context, check if the file exists with a "No cross-context interactions" note — this is a valid completed state.

Run sh skills/full-ddd/scripts/session-recovery.sh for a quick status report.

Rationalization Table

If you catch yourself thinking any excuse in the left column — STOP and re-read the Reality column.

| Excuse | Reality | |:---|:---| | "ACL is for microservices, not monorepos" | ACL protects semantic boundaries; monorepo direct imports create the same tight coupling as shared DB in microservices. | | "Just import the type directly — it's the same repo" | Same repo ≠ same context; cross-context imports block refactoring, splitting, and independent evolution. | | "The contract is obviously clean — skip the Boundary Challenge" | Confidence bias is why the checkpoint exists; the user may spot domain leakage you cannot see. | | "Self-approve the Boundary Challenge — I can tell it passes" | Self-approval defeats the human checkpoint; noting "PASS" yourself is not a review. | | "Async approval — send contract on Slack while I start coding" | Async approval creates sunk cost bias; the gate must be synchronous. | | "Waiting for approval wastes productive time" | Waiting prevents building on unapproved foundations; implementation before approval = rework. | | "Can adjust implementation if contract changes later" | Implementation creates inertia; contract changes after code face resistance proportional to existing code. | | "Spirit vs. letter — the checkpoint is just formality" | The checkpoint prevents domain leakage; self-review, batched review, async review bypass it. | | "This contract ambiguity is minor, I'll resolve it during coding" | Contract ambiguities resolved during coding create implementation-first coupling. The contract gate exists to prevent this. | | "STOP is too disruptive, I'll finish the contract draft first" | A STOP-level wrong assumption in Phase 3 means redoing contracts and all downstream phases. Pausing costs nothing. | | "Events are fire-and-forget, ACL isn't needed for event consumers" | Events cross context boundaries just like synchronous calls. The consumer must translate the publisher's event schema into its own domain language through an ACL — otherwise the consumer's domain layer couples to the publisher's vocabulary. | | "The existing codebase doesn't use ACL, so I'll match the pattern" | Consistency with an anti-pattern compounds debt. ACL is mandatory for ALL cross-context communication regardless of existing code patterns. Every new contract following ACL is a working example for migration. | | "I'll start coding the happy path while waiting for contract approval" | Coding before approval means implementation assumptions become sunk cost. When the human revises the contract, you'll rationalize keeping the code instead of rewriting. The approval gate exists to prevent this trap. | | "Self-review satisfies the checkpoint's spirit — the intent is quality, not the literal gate" | Spirit compliance is not compliance. The checkpoint's letter IS its spirit — the process exists because developers are systematically wrong about when their own work is 'obviously fine.' |

Red Flags — STOP

If you catch yourself thinking "ACL is overhead", "just import directly", "I'll approve it myself", "this is essentially single-context", "contract ambiguity is minor — resolve during coding", "waiting for approval wastes time", "skip the Boundary Challenge — the contract is obviously clean", "async approval — start coding while waiting", "can adjust implementation if contract changes later", "the checkpoint is just formality", "combine fine-grained interfaces for simplicity", "STOP is too disruptive", "contracts are an internal implementation detail", "upstream context owns the contract definition", "boundary structs can reuse domain entity types", "contract direction is obvious — no need to specify", or "domain-internal types can appear in contracts if convenient" — STOP. Define the pure interface. Run the Boundary Challenge with the human. Wait for approval.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.