feat: add DDD capability for vision-to-issues workflow

Add complete DDD capability set for breaking down product vision into
implementation issues using Domain-Driven Design principles.

Components:
- issue-writing skill: Enhanced with user story format and vertical slices
- ddd skill: Strategic and tactical DDD patterns (bounded contexts, aggregates, commands, events)
- ddd-breakdown skill: User-invocable workflow (/ddd-breakdown)
- ddd-analyst agent: Analyzes manifesto/vision/code, generates DDD-structured user stories

Workflow: Read manifesto + vision → analyze codebase → identify bounded contexts
→ map features to DDD patterns → generate user stories → create Gitea issues

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
2026-01-12 13:02:56 +01:00
parent dd9c1c0090
commit 6e4ff3af86
4 changed files with 875 additions and 0 deletions

View File

@@ -0,0 +1,136 @@
---
name: ddd-breakdown
description: >
Analyze product vision using DDD to identify bounded contexts and generate
implementation issues. Use when breaking down features into DDD-based vertical
slices, or when user says /ddd-breakdown.
model: haiku
argument-hint: [vision-file]
user-invocable: true
---
# DDD Breakdown
@~/.claude/skills/ddd/SKILL.md
@~/.claude/skills/issue-writing/SKILL.md
@~/.claude/skills/gitea/SKILL.md
Analyze product vision through a DDD lens to generate implementation issues.
## Process
1. **Locate manifesto and vision**:
**Manifesto** (organization-level):
```bash
# Always in architecture repo
cat ~/.claude/manifesto.md
# Or if in architecture repo:
cat ./manifesto.md
```
**Vision** (product-level):
```bash
# If argument provided: use that file
# Otherwise: look for vision.md in current repo
cat ./vision.md
```
Verify both files exist before proceeding.
2. **Spawn DDD analyst agent**:
Use Task tool to spawn `ddd-analyst` agent:
```
Analyze this product using DDD principles.
Manifesto: [path to manifesto.md]
Vision: [path to vision.md]
Codebase: [current working directory]
Identify bounded contexts, map features to DDD patterns, and generate
user stories with DDD implementation guidance.
```
The agent will:
- Analyze manifesto (personas, beliefs, domain language)
- Analyze vision (goals, features, milestones)
- Explore codebase (existing structure, boundaries, misalignments)
- Identify bounded contexts (intended vs actual)
- Map features to DDD patterns (aggregates, commands, events)
- Generate user stories with acceptance criteria and DDD guidance
3. **Review agent output**:
The agent returns structured analysis:
- Bounded contexts identified
- User stories per context
- Refactoring needs
- Suggested implementation order
Present this to the user for review.
4. **Confirm issue creation**:
Ask user:
- Create all issues?
- Select specific issues to create?
- Modify any stories before creating?
5. **Create issues in Gitea**:
For each approved user story:
```bash
tea issues create \
--title "[story title]" \
--description "[full story with DDD guidance]"
```
Apply labels:
- `feature` (or `refactor` for refactoring issues)
- `bounded-context/[context-name]`
- Any other relevant labels from the story
6. **Link dependencies**:
For stories with dependencies:
```bash
tea issues deps add <dependent-issue> <blocker-issue>
```
7. **Report results**:
Show created issues with links:
```
## Issues Created
### Context: [Context Name]
- #123: [Issue title]
- #124: [Issue title]
### Context: [Another Context]
- #125: [Issue title]
### Refactoring
- #126: [Issue title]
View all: [link to issues page]
```
## Guidelines
- **Manifesto is organization-wide**: Always read from architecture repo
- **Vision is product-specific**: Read from current repo or provided path
- **Let agent do the analysis**: Don't try to identify contexts yourself, spawn the agent
- **Review before creating**: Always show user the analysis before creating issues
- **Label by context**: Use `bounded-context/[name]` labels for filtering
- **Link dependencies**: Use `tea issues deps add` for blockers
- **Implementation order matters**: Create foundational issues (refactoring, core aggregates) first
## Tips
- Run this when starting a new product or major feature area
- Re-run periodically to identify drift between vision and code
- Use with `/vision` skill to manage product vision
- Combine with `/plan-issues` for additional breakdown
- Review with team before creating all issues

272
skills/ddd/SKILL.md Normal file
View File

@@ -0,0 +1,272 @@
---
name: ddd
description: >
Domain-Driven Design concepts: bounded contexts, aggregates, commands, events,
and tactical patterns. Use when analyzing domain models, identifying bounded
contexts, or mapping features to DDD patterns.
user-invocable: false
---
# Domain-Driven Design (DDD)
Strategic and tactical patterns for modeling complex domains.
## Strategic DDD: Bounded Contexts
### What is a Bounded Context?
A **bounded context** is a boundary within which a domain model is consistent. Same terms can mean different things in different contexts.
**Example:** "Order" means different things in different contexts:
- **Sales Context**: Order = customer purchase with payment and shipping
- **Fulfillment Context**: Order = pick list for warehouse
- **Accounting Context**: Order = revenue transaction
### Identifying Bounded Contexts
Look for:
1. **Different language**: Same term means different things
2. **Different models**: Same concept has different attributes/behavior
3. **Different teams**: Natural organizational boundaries
4. **Different lifecycles**: Entities created/destroyed at different times
5. **Different rate of change**: Some areas evolve faster than others
**From vision/manifesto:**
- Identify personas → each persona likely interacts with different contexts
- Identify core domain concepts → group related concepts into contexts
- Identify capabilities → capabilities often align with contexts
**From existing code:**
- Look for packages/modules that cluster related concepts
- Identify seams where code is loosely coupled
- Look for translation layers between subsystems
- Identify areas where same terms mean different things
### Context Boundaries
**Good boundaries:**
- Clear interfaces between contexts
- Each context owns its data
- Contexts communicate via events or APIs
- Minimal coupling between contexts
**Bad boundaries:**
- Shared database tables across contexts
- Direct object references across contexts
- Mixed concerns within a context
### Common Context Patterns
| Pattern | Description | Example |
|---------|-------------|---------|
| **Core Domain** | Your unique competitive advantage | Custom business logic |
| **Supporting Subdomain** | Necessary but not differentiating | User management |
| **Generic Subdomain** | Common problems, use off-the-shelf | Email sending, file storage |
## Tactical DDD: Building Blocks
### Aggregates
An **aggregate** is a cluster of entities and value objects treated as a unit for data changes.
**Rules:**
- One entity is the **aggregate root** (only entity referenced from outside)
- All changes go through the root
- Enforce business invariants within the aggregate
- Keep aggregates small (2-3 entities max when possible)
**Example:**
```
Order (root)
├── OrderLine
├── ShippingAddress
└── Payment
```
External code only references `Order`, never `OrderLine` directly.
**Identifying aggregates:**
- What entities always change together?
- What invariants must be enforced?
- What is the transactional boundary?
### Commands
**Commands** represent intent to change state. Named with imperative verbs.
**Format:** `[Verb][AggregateRoot]` or `[AggregateRoot][Verb]`
**Examples:**
- `PlaceOrder` or `OrderPlace`
- `CancelSubscription` or `SubscriptionCancel`
- `ApproveInvoice` or `InvoiceApprove`
**Commands:**
- Are handled by the aggregate root
- Either succeed completely or fail
- Can be rejected (return error)
- Represent user intent or system action
### Events
**Events** represent facts that happened in the past. Named in past tense.
**Format:** `[AggregateRoot][PastVerb]` or `[Something]Happened`
**Examples:**
- `OrderPlaced`
- `SubscriptionCancelled`
- `InvoiceApproved`
- `PaymentFailed`
**Events:**
- Are immutable (already happened)
- Can be published to other contexts
- Enable eventual consistency
- Create audit trail
### Value Objects
**Value Objects** are immutable objects defined by their attributes, not identity.
**Examples:**
- `Money` (amount + currency)
- `EmailAddress`
- `DateRange`
- `Address`
**Characteristics:**
- No identity (two with same values are equal)
- Immutable (cannot change, create new instance)
- Can contain validation logic
- Can contain behavior
**When to use:**
- Concept has no lifecycle (no create/update/delete)
- Equality is based on attributes, not identity
- Can be shared/reused
### Entities
**Entities** have identity that persists over time, even if attributes change.
**Examples:**
- `User` (ID remains same even if name/email changes)
- `Order` (ID remains same through lifecycle)
- `Product` (ID remains same even if price changes)
**Characteristics:**
- Has unique identifier
- Can change over time
- Identity matters more than attributes
## Mapping Features to DDD Patterns
### Process
For each feature from vision:
1. **Identify the bounded context**: Which context does this belong to?
2. **Identify the aggregate(s)**: What entities/value objects are involved?
3. **Identify commands**: What actions can users/systems take?
4. **Identify events**: What facts should be recorded when commands succeed?
5. **Identify value objects**: What concepts are attribute-defined, not identity-defined?
### Example: "User can place an order"
**Bounded Context:** Sales
**Aggregate:** `Order` (root)
- `OrderLine` (entity)
- `ShippingAddress` (value object)
- `Money` (value object)
**Commands:**
- `PlaceOrder`
- `AddOrderLine`
- `RemoveOrderLine`
- `UpdateShippingAddress`
**Events:**
- `OrderPlaced`
- `OrderLineAdded`
- `OrderLineRemoved`
- `ShippingAddressUpdated`
**Value Objects:**
- `Money` (amount, currency)
- `Address` (street, city, zip, country)
- `Quantity`
## Refactoring to DDD
When existing code doesn't follow DDD patterns:
### Identify Misalignments
**Anemic domain model:**
- Entities with only getters/setters
- Business logic in services, not entities
- **Fix:** Move behavior into aggregates
**God objects:**
- One entity doing too much
- **Fix:** Split into multiple aggregates or value objects
**Context leakage:**
- Same model shared across contexts
- **Fix:** Create context-specific models with translation layers
**Missing boundaries:**
- Everything in one module/package
- **Fix:** Identify bounded contexts, separate into modules
### Refactoring Strategies
**Extract bounded context:**
```markdown
As a developer, I want to extract [Context] into a separate module,
so that it has clear boundaries and can evolve independently
```
**Extract aggregate:**
```markdown
As a developer, I want to extract [Aggregate] from [GodObject],
so that it enforces its own invariants
```
**Introduce value object:**
```markdown
As a developer, I want to replace [primitive] with [ValueObject],
so that validation is centralized and the domain model is clearer
```
**Introduce event:**
```markdown
As a developer, I want to publish [Event] when [Command] succeeds,
so that other contexts can react to state changes
```
## Anti-Patterns
**Avoid:**
- Aggregates spanning multiple bounded contexts
- Shared mutable state across contexts
- Direct database access across contexts
- Aggregates with dozens of entities (too large)
- Value objects with identity
- Commands without clear aggregate ownership
- Events that imply future actions (use commands)
## Tips
- Start with strategic DDD (bounded contexts) before tactical patterns
- Bounded contexts align with team/organizational boundaries
- Keep aggregates small (single entity when possible)
- Use events for cross-context communication
- Value objects make impossible states impossible
- Refactor incrementally - don't rewrite everything at once

View File

@@ -0,0 +1,212 @@
---
name: issue-writing
description: >
Write clear, actionable issues with user stories, vertical slices, and acceptance
criteria. Use when creating issues, writing bug reports, feature requests, or when
the user needs help structuring an issue.
user-invocable: false
---
# Issue Writing
How to write clear, actionable issues that deliver user value.
## Primary Format: User Story
Frame issues as user capabilities, not technical tasks:
```markdown
Title: As a [persona], I want to [action], so that [benefit]
## User Story
As a [persona], I want to [action], so that [benefit]
## Acceptance Criteria
- [ ] Specific, testable requirement
- [ ] Another requirement
- [ ] User can verify this works
## Context
Additional background, links, or references.
## Technical Notes (optional)
Implementation hints or constraints.
```
**Example:**
```markdown
Title: As a domain expert, I want to save my diagram, so that I can resume work later
## User Story
As a domain expert, I want to save my diagram to the cloud, so that I can resume
work later from any device.
## Acceptance Criteria
- [ ] User can click "Save" button in toolbar
- [ ] Diagram persists to cloud storage
- [ ] User sees confirmation message on successful save
- [ ] Saved diagram appears in recent files list
## Context
Users currently lose work when closing the browser. This is the #1 requested feature.
```
## Vertical Slices
Issues should be **vertical slices** that deliver user-visible value.
### The Demo Test
Before writing an issue, ask: **Can a user demo or test this independently?**
- **Yes** → Good issue scope
- **No** → Rethink the breakdown
### Good vs Bad Issue Titles
| Good (Vertical) | Bad (Horizontal) |
|-----------------|------------------|
| "As a user, I want to save my diagram" | "Add persistence layer" |
| "As a user, I want to see errors when login fails" | "Add error handling" |
| "As a domain expert, I want to list orders" | "Add query syntax to ADL" |
The technical work is the same, but vertical slices make success criteria clear and deliver demonstrable value.
## Writing User Stories
### Format
```
As a [persona], I want [capability], so that [benefit]
```
**Persona:** From manifesto or product vision (e.g., domain expert, developer, product owner)
**Capability:** What the user can do (not how it's implemented)
**Benefit:** Why this matters to the user
### Examples
```markdown
✓ As a developer, I want to run tests locally, so that I can verify changes before pushing
✓ As a product owner, I want to view open issues, so that I can prioritize work
✓ As a domain expert, I want to export my model as JSON, so that I can share it with my team
✗ As a developer, I want a test runner (missing benefit)
✗ I want to add authentication (missing persona and benefit)
✗ As a user, I want the system to be fast (not specific/testable)
```
## Acceptance Criteria
Good criteria are:
- **Specific**: "User sees error message" not "Handle errors"
- **Testable**: Can verify pass/fail
- **User-focused**: What the user experiences
- **Independent**: Each stands alone
**Examples:**
```markdown
- [ ] Login form validates email format before submission
- [ ] Invalid credentials show "Invalid email or password" message
- [ ] Successful login redirects to dashboard
- [ ] Session persists across browser refresh
```
## Alternative Formats
### Bug Report
```markdown
Title: Fix [specific problem] in [area]
## Summary
Description of the bug.
## Steps to Reproduce
1. Go to...
2. Click...
3. Observe...
## Expected Behavior
What should happen.
## Actual Behavior
What happens instead.
## Environment
- Browser/OS/Version
```
### Technical Task
Use sparingly - prefer user stories when possible.
```markdown
Title: [Action] [component/area]
## Summary
What technical work needs to be done and why.
## Scope
- Include: ...
- Exclude: ...
## Acceptance Criteria
- [ ] Measurable technical outcome
- [ ] Another measurable outcome
```
## Issue Sizing
Issues should be **small enough to complete in 1-3 days**.
**Too large?** Split into smaller vertical slices:
```markdown
# Too large
As a user, I want full authentication, so that my data is secure
# Better: Split into slices
1. As a user, I want to register with email/password, so that I can create an account
2. As a user, I want to log in with my credentials, so that I can access my data
3. As a user, I want to reset my password, so that I can regain access if I forget it
```
## Labels
Use labels to categorize:
- Type: `bug`, `feature`, `enhancement`, `refactor`
- Priority: `priority/high`, `priority/medium`, `priority/low`
- Component: Project-specific (e.g., `auth`, `api`, `ui`)
- DDD: `bounded-context/[name]`, `aggregate`, `command`, `event` (when applicable)
## Dependencies
Identify and link dependencies when creating issues:
1. **In the description**, document dependencies:
```markdown
## Dependencies
- Depends on #12 (must complete first)
- Related to #15 (informational)
```
2. **After creating the issue**, formally link blockers using tea CLI:
```bash
tea issues deps add <this-issue> <blocker-issue>
tea issues deps add 5 3 # Issue #5 is blocked by #3
```
This creates a formal dependency graph that tools can query.
## Anti-Patterns
**Avoid:**
- Generic titles: "Fix bugs", "Improve performance"
- Technical jargon without context: "Refactor service layer"
- Missing acceptance criteria
- Horizontal slices: "Build API", "Add database tables"
- Vague criteria: "Make it better", "Improve UX"
- Issues too large to complete in a sprint