# Full Contract Reference

This file preserves the detailed contract extracted from SKILL.md. Read it when the hub points here for exact workflow steps, templates, rubrics, or recovery branches.

---

# Design

> Follows the Architecture Constraints, Development Discipline, and Engineering Common Sense defined in the project AGENTS.md.

Discuss approaches, design architecture, plan requirements, and write to `.roll/backlog.md`. DDD modeling depth scales automatically with input scope.

## When to Use

- Requirements or approach are uncertain and multiple options need to be compared
- Requirements have not yet entered the backlog
- A solution needs to be designed before splitting into Stories
- An existing plan needs to be written into `.roll/backlog.md`

> **Doc-refresh discipline**: When splitting stories that change user-visible behavior, always append a closing "doc-refresh" story.
> **文档刷新纪律**：拆出的 story 只要改变了用户可见行为，最后必须追加一张"文档刷新"收尾 story。
> See [Doc Update Discipline](#doc-update-discipline) at the bottom of this file for the full rule.

## Use This Skill For

- Approach exploration and comparison (discuss phase)
- New project domain modeling (Event Storming → Context Map → Tactical Model)
- New requirement planning with domain context
- Solution design
- Splitting into Stories
- Creating US / FIX entries

## When Not to Use

- One-liner capture of ideas or bugs (use `$roll-idea`)
- Executing an already-split US-XXX (use `$roll-build`)
- Fixing a well-defined FIX-XXX (use `$roll-fix`)

## Quick Start

```bash
# New project from scratch → full DDD modeling
$roll-design "design an e-commerce order system from scratch"

# Approach is uncertain → discuss first, then plan
$roll-design "What approach should we use for search? Postgres FTS or Meilisearch?"

# Plan new requirement → domain slice + Stories → write to BACKLOG
$roll-design "user system design"

# Split Stories from an existing Plan
$roll-design --from-plan .roll/features/auth-plan.md

# Directly create a Story (auto-detected as User Story → Slice DDD)
$roll-design "user login feature"

# Non-interactive: read structured input file, skip Clarify/Discuss, write BACKLOG
$roll-design --from-file docs/requirements/auth-req.md

# Promote IDEA to Story: read BACKLOG IDEA-NNN, produce US-XXX, annotate IDEA
$roll-design --from-idea IDEA-009
```

## DDD Depth Scale

DDD modeling depth is determined automatically. It is not a switch — it is a dial.

```
输入范围              DDD 深度        产出物
─────────────────────────────────────────────────────────────
新项目 / greenfield   Full            Event Storming (对话引导)
                                      Context Map + UL 词汇表
                                      每个 Context 的 Tactical Model
                                      → .roll/domain/

User Story / 新特性   Slice           定位所属 Bounded Context
                                      关键 Aggregate + 触碰的 Entity/VO
                                      触发的 Domain Event + 跨域影响
                                      → 写入 US 的 Domain Model 段

Bug Fix               Tag             Context > Aggregate > Entity 定位
                                      → 写入 FIX 描述行
```

**深度自动判断逻辑**（在 Step 2 Analyze 阶段评估）：

```
Greenfield 信号（满足任意一条）:
  - 无 .roll/backlog.md / .roll/domain/ 目录
  - 输入含 "从零" / "新项目" / "建模" / "设计整个系统" 关键词
  - complexity = large AND 无已有 Bounded Context 文档

User Story 信号:
  - 输入是功能需求 / US-XXX 引用
  - complexity = medium or small AND 业务逻辑可见

Bug Fix 信号:
  - 输入是 FIX-XXX / 错误描述 / 明确的问题定位
  - 无需建模，只需定位上下文
```

## Workspace Configuration

Document structure (story-first layout, US-META-005):

```
.roll/backlog.md                          # story index (status + one-liner)
.roll/features/
  <epic>/                                 # epic folder
    <feature>.md                          # feature design doc (optional, multi-story overview)
    <feature>-plan.md                     # design plan (optional)
    <story>/                              # individual story folder (one per card)
      spec.md                             # story definition (AC, depends-on, etc.)
      index.html                          # auto-generated story portal
      delivery/                           # attest evidence (auto-generated on Done)
.roll/domain/                             # DDD domain model
  context-map.md
  ubiquitous-language.md
```

**Important rules:**
1. **Every story card gets its own folder**: `features/<epic>/<story>/`
2. **spec.md is the single definition file** — contains full AC, Files, Dependencies
3. **FIX / IDEA / US all follow the same folder layout** — `features/<epic>/FIX-097/spec.md`
4. **Feature design docs stay at epic root** — `<feature>.md` and `<feature>-plan.md` are optional, multi-story design overviews
5. **index.html is auto-generated** by `roll idea` (skeleton) and updated by `roll attest` (delivery section)
6. **delivery/ is auto-created** by `roll attest` on Done — do not create manually
7. .roll/backlog.md only contains index rows (one row per story), **do not write** AC / Files there
8. Domain model files go in `.roll/domain/`
9. **Do not** write to `~/.kimi/`, `~/.kimi-code/`, or any global config directory

**File path resolution:**
1. Determine epic from story ID prefix (e.g., US-META-* → backlog-lifecycle, FIX-* → query index.json)
2. Mint the card via the single channel (US-META-009 — never hand-create the folder):
   `roll story new <ID> --title "<one-line title>" --epic <epic>`
3. Then EDIT the minted spec.md to add the full AC / Files / Dependencies / Agent profile
4. Backlog row links to: `.roll/features/<epic>/<story>/spec.md`
5. Design / plan docs (when needed): `.roll/features/<epic>/<feature>.md` + `<feature>-plan.md`

## Non-Interactive Mode

Activated by explicit flags or auto-detected high-confidence input. Skips Clarify and Discuss, writes stories directly to BACKLOG as `📋 Todo`, no confirm gate.

### `--from-file <path>`

```
Input: structured requirement file (plain text or markdown)

Expected file contents (minimum viable):
  - Description: what to build (1–3 sentences)
  - Expected AC: measurable outcomes (bullet list)
  - [Optional] Domain hint, priority, dependencies

Execution path:
  [Read file] → [Analyze] → [DDD Slice] → [Solution Design] → [Split Stories]
      → [Write BACKLOG 📋 Todo] → Done (no Clarify, no Discuss, no confirm gate)
```

Input file example (`docs/requirements/auth-req.md`):
```markdown
## Requirement: session timeout warning

Description: Show a countdown modal 60 seconds before session expires.
Users can click "Stay logged in" to extend, or let it expire naturally.

Expected AC:
- Modal appears at T-60s with countdown timer
- "Stay logged in" sends a keepalive and dismisses modal
- Expiry after countdown logs user out and redirects to /login
- Works across all authenticated pages
```

### `--from-idea IDEA-NNN`

```
Input: IDEA-NNN identifier from .roll/backlog.md

Execution path:
  [Read .roll/backlog.md IDEA-NNN row] → [Analyze] → [DDD Slice] → [Solution Design] → [Split Stories]
      → [Write BACKLOG 📋 Todo] → [Annotate IDEA row: → US-XXX] → Done

IDEA annotation: append `→ US-XXX` to the IDEA row's Description column.
Example: | IDEA-009 | ... | ✅ Done → US-AUTO-021 |
```

### High-Confidence Auto-Detection

When input is not a flag-based mode but already contains all three of: **clear verb**, **explicit scope**, and **verifiable acceptance signal**, skip Clarify automatically. At most retain Discuss (only if approach has genuine divergence).

High-confidence signals (all three must be present):
- Clear verb: add / remove / fix / rename / migrate / split / extract / support ...
- Explicit scope: named file, command, module, endpoint, or UI element
- Acceptance signal: "so that X", "when Y then Z", measurable outcome described

Examples:
```bash
# High confidence — skip Clarify:
$roll-design "add --dry-run flag to roll loop go that prints the plan without running"
$roll-design "rename cmd_status() to cmd_overview() in bin/roll and update all callers"

# Low confidence — enter Clarify:
$roll-design "improve the status command"
$roll-design "make loop better"
```

---

## Workflow

```
User Input
    │
    ├── --from-file <path>  ──→  [Read file] → Step 2 (Analyze) → Steps 3–5 → BACKLOG 📋 → Done
    ├── --from-idea IDEA-N  ──→  [Read BACKLOG IDEA] → Step 2 → Steps 3–5 → BACKLOG 📋 → Annotate IDEA → Done
    ├── high-confidence str ──→  Step 2 (Analyze) directly (skip Clarify, keep Discuss if divergence)
    │
    ▼
┌─────────────────────────────┐
│ 0. Clarify (when vague)     │  ← Automatically triggered when input is under-specified
│    - Summarize intent        │
│    - Assess complexity       │
│    - Ask 3–5 targeted Qs    │
│    - Wait for user reply     │
└─────────────┬───────────────┘
              │ Intent clear
              ▼
┌─────────────────────────────┐
│ 1. Discuss (when uncertain) │  ← Automatically triggered when approach is uncertain
│    - List 2-4 viable options │
│    - Each: approach + pros/cons │
│    - Comparison matrix       │
│    - Recommendation + rationale │
│    - Human makes final decision │
└─────────────┬───────────────┘
              │ Approach confirmed
              ▼
┌─────────────────────────────┐
│ [peer] Direction Review     │  ← if complexity=medium/large or cross-context; 10s opt-out
│    Skill("roll-peer",       │
│      tag="architecture")    │
└─────────────┬───────────────┘
              │ AGREE / skipped
              ▼
┌─────────────────────────────┐
│ 2. Analyze + DDD Depth      │  ← Detect scope: Greenfield / Story / Fix
│    - Requirement analysis    │
│    - Feasibility assessment  │
│    - DDD depth determination │
└──────┬──────────────────────┘
       │
       ├── Greenfield ──→ ┌─────────────────────────────┐
       │                  │ 2a. Event Storming (对话引导) │
       │                  │  Big Picture:                │
       │                  │    - 发现 Domain Events       │
       │                  │    - 识别 Actors / Commands  │
       │                  │    - 标记 Hot Spots           │
       │                  │  Process Level:              │
       │                  │    - Command→Event→Policy 链 │
       │                  │    - 识别 Bounded Context 边界│
       │                  │  Design Level:               │
       │                  │    - Aggregate 候选           │
       │                  │    - Entity vs Value Object  │
       │                  └──────────────┬──────────────┘
       │                                 │
       │                  ┌──────────────▼──────────────┐
       │                  │ 2b. Strategic Design         │
       │                  │  - Bounded Contexts 定义     │
       │                  │  - Context Map (关系类型)    │
       │                  │  - Ubiquitous Language 词汇表│
       │                  │  → .roll/domain/context-map.md│
       │                  │  → .roll/domain/ubiquitous-   │
       │                  │      language.md             │
       │                  └──────────────┬──────────────┘
       │                                 │
       ├── User Story ──→ ┌──────────────▼──────────────┐
       │                  │ 2c. Domain Slice             │
       │                  │  - 定位所属 Bounded Context  │
       │                  │  - 识别关键 Aggregate        │
       │                  │  - 触碰的 Entity / VO        │
       │                  │  - 触发的 Domain Events      │
       │                  │  - 跨域影响（如有）          │
       │                  └──────────────┬──────────────┘
       │                                 │
       └── Bug Fix ─────→ ┌──────────────▼──────────────┐
                          │ 2d. Domain Tag               │
                          │  - Context > Aggregate >     │
                          │    Entity 定位               │
                          └──────────────┬──────────────┘
                                         │
                                         ▼
              ┌─────────────────────────────────────────┐
              │ 3. Detailed (Solution) Design  ★MANDATORY│
              │    Before ANY decomposition, for         │
              │    non-trivial work produce a concrete,  │
              │    implementable artifact (depth scales  │
              │    with risk/novelty):                   │
              │    - Architecture / module decomposition │
              │    - Dependency analysis                 │
              │    Required artifacts (all of):          │
              │      (a) data/contract schema            │
              │      (b) ≥1 COMPLETE worked sample of    │
              │          the intended output/behavior    │
              │      (c) key interface signatures        │
              │      (d) mapping/normalization rules     │
              │      (e) edge cases & failure modes      │
              │    Rule: if you cannot show a complete   │
              │    worked sample, the design is NOT done.│
              │    [Greenfield] Tactical Model per Context:
              │      - Aggregate Root + Entities + VOs  │
              │      - Invariants (业务不变式)           │
              │      - Domain Events (触发条件 + 消费方) │
              │      - Repository interfaces            │
              │      - Domain Services (跨 Aggregate)  │
              │    → .roll/features/<feature>-plan.md    │
              │    [Greenfield] → .roll/domain/<ctx>-    │
              │      model.md                           │
              └──────────────────┬──────────────────────┘
                                 │
                                 ▼
              ┌─────────────────────────────────────────┐
              │ [peer] Plan Review                       │  ← if complexity=medium/large; 10s opt-out
              │    Skill("roll-peer", tag="architecture")│
              └──────────────────┬──────────────────────┘
                                 │ AGREE / skipped
                                 ▼
              ┌─────────────────────────────────────────┐
              │ [gate] Owner Sign-off on Detailed Design │  ← REQUIRED before decomposition
              │    Decomposition slices an AGREED design;│
              │    it does NOT replace designing. Get    │
              │    owner sign-off (proportional to risk) │
              │    before splitting into stories.        │
              └──────────────────┬──────────────────────┘
                                 │ Signed off
                                 ▼
              ┌─────────────────────────────────────────┐
              │ 4. Split into Stories                    │
              │    - INVEST principles                   │
              │    - Bounded Context → US domain prefix  │
              │    - Priority ordering                   │
              │    - **强制检查**: 若本批次任一 US 改了    │
              │      用户可见行为（CLI 输出 / 命令参数 /  │
              │      状态语义 / 错误提示），必须在末尾追加 │
              │      一张 doc-refresh 收尾 story         │
              │      （详见 Doc Update Discipline 一节）│
              └──────────────────┬──────────────────────┘
                                 │
                                 ▼
              ┌─────────────────────────────────────────┐
              │ 5. Write to .roll/backlog.md                   │
              │    - Create US-XXX                       │
              │    - Define AC                           │
              │    - Link design documents               │
              └──────────────────┬──────────────────────┘
                                 │
                                 ▼
                       "Confirm and execute?"
                       │
                       ├── Yes ──→ $roll-build US-XXX
                       │
                       └── No  ──→ Story 已写入 BACKLOG 为 📋 Todo
                                   loop 下轮将自动执行
                                   （选 No 仅跳过立即执行）
```

**Gate 语义澄清**：选 `No` 不是放弃，story 已经入 BACKLOG,下一个驱动会话跑
`roll loop go` 时会领到它。若想完全搁置，请显式把状态改为 🚫 Hold。

---

## DDD Output Formats

### Event Storming — Big Picture (对话引导)

AI 扮演引导人，按顺序提问，不跳步骤：

```
Step 1 - 发现 Domain Events:
  "请描述这个系统里会发生的重要事情，用过去式动词短语
   （例如：订单已创建、支付已完成、库存已扣减）"

Step 2 - 识别触发者:
  "每个事件是谁/什么触发的？
   （用户操作 / 系统自动 / 定时任务 / 外部系统）"

Step 3 - 标记 Hot Spots:
  "哪些地方你还不确定？有哪些业务规则有争议？
   （标记为 ⚠️ Hot Spot，后续重点讨论）"
```

输出格式（Big Picture 阶段结果）：

```
Domain Events discovered:
  [OrderPlaced] ← Customer (user action)
  [PaymentCompleted] ← Payment Gateway (external)
  [InventoryReserved] ← System (automatic, after OrderPlaced)
  [OrderShipped] ← Warehouse Staff (user action)

Hot Spots ⚠️:
  - 支付失败后如何回滚库存预留？
  - 同一商品多仓库时库存扣减策略？
```

### Event Storming — Process Level

```
Step 4 - Command→Event 链:
  "把事件串成流程：什么命令触发了它？
   触发后系统自动做什么（Policy）？"

Step 5 - 识别 Bounded Context 边界:
  "哪些事件自然聚集在一起？
   哪些事件之间有明显的组织边界或团队边界？"
```

输出格式（Process Level 阶段结果）：

```
Flow: Order Lifecycle
  [PlaceOrder] ──→ (Order) ──→ [OrderPlaced]
                                    │ Policy: reserve inventory
                                    ▼
                              (Inventory) ──→ [InventoryReserved]
                                    │ Policy: request payment
                                    ▼
                              (Payment) ──→ [PaymentCompleted]

Candidate Bounded Contexts:
  - Order Context    (OrderPlaced, OrderShipped, OrderCancelled)
  - Inventory Context (InventoryReserved, InventoryReleased)
  - Payment Context  (PaymentCompleted, PaymentFailed)
```

### Strategic Design Output

写入 `.roll/domain/context-map.md`：

```markdown
## Bounded Contexts

| Context | 职责边界 | 核心概念 |
|---------|---------|---------|
| Order | 订单生命周期管理 | Order, OrderItem, Customer |
| Inventory | 库存预留与释放 | Stock, Reservation, Warehouse |
| Payment | 支付处理与退款 | Payment, Refund, Transaction |

## Context Map

Order ═══U/D═══→ Inventory   (Customer-Supplier: Order 下游消费库存事件)
Order ═══U/D═══→ Payment     (Customer-Supplier: Order 发起支付请求)
Payment ──ACL──→ Alipay      (Anti-Corruption Layer: 防腐层隔离第三方)
```

写入 `.roll/domain/ubiquitous-language.md`：

```markdown
| 术语 | 定义 | 所属 Context | 注意事项 |
|-----|------|-------------|---------|
| Order | 买家提交的购买意向，包含商品列表和配送信息 | Order | 不等于"交易"，交易在 Payment Context |
| Reservation | 为订单锁定的库存数量，有时效 | Inventory | 区别于 Allocation（正式分配） |
```

Context Map 关系类型说明：

```
═══U/D═══→  Customer-Supplier (上下游依赖)
───ACL───→  Anti-Corruption Layer (防腐层)
═══PL════   Partnership (平等协作)
───SK───    Shared Kernel (共享内核)
───CF───→  Conformist (顺从者)
───OHS──→  Open Host Service (开放主机)
```

### Tactical Model Output

写入 `.roll/domain/<context>-model.md`：

```markdown
## Tactical Model: Order Context

### Aggregates

**Order** (Aggregate Root)
  Entities:   OrderItem
  Value Objects: Address, Money, OrderStatus
  Invariants:
    - 订单金额 = sum(OrderItem.price × quantity)
    - 已支付订单不可修改商品列表
    - OrderItem 数量必须 > 0

### Domain Events

| Event | 触发条件 | 消费方 | Payload |
|-------|---------|-------|---------|
| OrderPlaced | Order.place() 成功 | Inventory Context | orderId, items, customerId |
| OrderCancelled | Order.cancel() | Inventory Context, Payment Context | orderId, reason |

### Repository Interfaces

IOrderRepository:
  - findById(orderId): Order
  - save(order): void
  - findByCustomer(customerId, page): Order[]

### Domain Services

OrderPricingService:
  - 职责: 跨 PriceRule Aggregate 计算最终价格（含优惠券、会员折扣）
  - 原因: 定价逻辑跨越多个 Aggregate，不归属任何单一 Root
```

### Domain Slice Output（User Story 级别）

插入 US 的 Domain Model 段（见 Story Format）：

```markdown
**Domain Model:**
- Context: Order
- Aggregate: Order (Root) owns [OrderItem, Address]
- Entities touched: OrderItem (新增/修改)
- Events raised: [OrderItemUpdated] → Inventory Context
- Cross-context: Inventory Context 需同步更新预留数量
```

### Domain Tag Output（Bug Fix 级别）

写入 FIX 描述的第一行：

```
Domain: Order Context > Order Aggregate > OrderItem Entity
```

### AGENTS.md Where to Look — 指针维护

After completing any Domain Slice (User Story level), check if the project's `AGENTS.md` has a `## Where to Look` section with a `.roll/domain/` pointer. If missing, append one line:

```markdown
- **Domain model**: `.roll/domain/context-map.md` — Bounded Contexts and relationships
```

Rules:
- Idempotent: only append if the pointer line is not already present
- Do not modify any other content in AGENTS.md
- Skip silently if `.roll/domain/` does not yet exist for this project

---

## Clarify Phase

**Skip conditions** — silently skip Clarify when any of these hold:
- Input uses `--from-file` or `--from-idea` flag (non-interactive mode)
- Input is high-confidence (clear verb + explicit scope + acceptance signal — see Non-Interactive Mode)

**Trigger conditions** — automatically enters if none of the skip conditions hold AND any of these are met:
- Input is a single vague sentence without clear scope
- Missing clear boundaries (what / who / when / where)
- Contains ambiguous terms like "优化一下", "改一下", "加个东西", "做个设计"
- Could be interpreted in multiple ways

**Pre-Clarify: three-step product localization (always run first, silently)**

Before listing questions, internally determine:
1. **产品端 (product end)**: web / mobile / API / CLI / other — which surface does this touch?
2. **角色 (role)**: who initiates this action? (end user / admin / system / external)
3. **业务域 (domain)**: which business domain does this belong to?

Already-localized dimensions become context prefix in the output, not open questions.

**Output format:**

```
🎯 Clarified Intent: {1-2 sentences}
🗺  Context: {product end} · {role} · {domain}   ← omit if all three are unknown

📏 Complexity: {small|medium|large}

❓ Open Questions:
1. {question 1}
2. {question 2}
3. {question 3}
...

➡️  Please answer the questions above and I'll proceed to design.
```

**Rules:**
- Do **not** start designing until the user replies.
- Never announce "I'm using clarify." Just do it naturally.
- If the input is already clear enough, skip silently and proceed to Discuss or Analyze.

---

## Discuss Phase

**Trigger conditions** — automatically enters if any of these are met:
- User is explicitly asking "how to choose" or "what approach to use"
- More than 2 viable technical paths exist
- Requirement involves an unfamiliar tech stack or new domain

### How to Conduct the Discussion

Discuss is **multi-turn by default**. The goal is to reach clarity together, not to produce a complete comparison matrix in one shot.

**Step 1 — Understand before proposing**

Before listing options, make sure the core problem is clear. If context is thin, ask 1–2 focused questions first:

```
Before I lay out the options — can you tell me [specific constraint / scale / existing system boundary]?
```

Only skip this if the context is already rich enough to reason from.

**Step 2 — Offer an opinionated starting point, not a menu**

Don't dump 4 options at once. Lead with a concrete recommendation and the key tradeoff:

```
My read: go with X. The main tradeoff is [Y vs Z]. Want me to walk through why, or should I compare against [alternative] first?
```

Then wait. Let the user redirect.

**Step 3 — Follow the thread**

If the user wants to dig into a specific option or challenge an assumption, stay on that thread. Don't pivot back to the full comparison until the current thread is resolved.

**Step 4 — Surface hidden assumptions explicitly**

When a direction starts to crystallize, name the assumptions holding it up:

```
This only holds if [assumption]. Is that true for your situation?
```

**Step 5 — Name convergence before triggering the gate**

When the discussion reaches a clear conclusion, summarize it explicitly before asking to proceed:

```
Looks like we've landed on: [decision]. The key reasons: [1–2 points].
```

Then trigger the gate.

**Gate rule** — after convergence is named, always end with this explicit prompt and **wait for user reply before proceeding**:

```
➡️  Continue to solution design, or keep exploring?
```

Do **not** infer "approach confirmed" from the user's reaction to the comparison. Only proceed to Step 2 (Analyze) when the user explicitly says to continue (e.g., "yes", "proceed", "go ahead", "design it").

**Can stop at any time** — if after discussion the user says "let's not do it" or "let me think about it", there's no need to continue to the planning phase.

---

## Operation Sequence for Creating a New Story

```bash
# 1. Determine Feature ownership (e.g., compiler / ingest / qa)
FEATURE="compiler"

# 2. Write Plan document (if there is a solution design)
PLAN_FILE=".roll/features/${EPIC}/${FEATURE}-plan.md"

# 3. Write story spec: .roll/features/<epic>/<story>/spec.md (full AC)
# Story specs: .roll/features/<epic>/<story>/spec.md

# 4. Append index row under the corresponding Epic > Feature group in .roll/backlog.md
# | [US-XXX](.roll/features/compiler.md#us-xxx) | One-line description | 📋 Todo |

# 5. [Greenfield only] Write domain model files
DOMAIN_DIR=".roll/domain/"
# .roll/domain/context-map.md
# .roll/domain/ubiquitous-language.md
# .roll/domain/<context>-model.md
```

---

## Story Format

**.roll/backlog.md index row (only write this one line):**

```markdown
| [US-{DOMAIN}-{N}](.roll/features/<epic>/US-{DOMAIN}-{N}/spec.md) | {one-line description} | 📋 Todo |
```

`{one-line description}` 写法：用户能读懂的一句话，说清楚"能做什么"或"解决了什么麻烦"。不写实现细节、文件路径、函数名。细节和 AC 写在 `.roll/features/` 里。写好了可以直接当 CHANGELOG 条目用。

Note: `{DOMAIN}` maps to the Bounded Context name identified in DDD analysis.

**US section in .roll/features/\<feature\>.md (full details):**

```markdown
<a id="us-{domain}-{n}"></a>
## US-{DOMAIN}-{N} {Story Title} 📋

**Created**: {YYYY-MM-DD}
**Plan**: [{feature}-plan.md]({feature}-plan.md)  ← if a design document exists

- As a {role}
- I want {action}
- So that {benefit}

**Domain Model:**
- Context: {Bounded Context name}
- Aggregate: {Root} owns [{entities}]
- Events raised: [{EventName}] → {consumer context}
- Cross-context: {if touches another context, otherwise omit}

**Agent profile:**
- est_min: {1-30 整数;一个 Story ≈ 一个 AI cycle 闭环,目标 5-10 min。这是**唯一的 loop 路由输入**——`lib/loop_pick_agent.py` 把 est_min 映射到复杂度档：≤8 → easy,8<x≤20 → default,>20 → hard;缺失/非法值 → default。est > ~15 是"再拆"信号——除非原子不可分(见 INVEST 的 S/I 校准)}
- risk_zone: {low / medium / high — 改文档 low,改用户可见行为 medium,改 loop infra 或安全/隔离基建 high。**不参与 loop 路由**(路由只看 est_min);仅供 roll-build / roll-fix 的 pre-flight 自评(US-AGENT-007)做能力匹配参考}
- chain_depth: 0  {若是自降级产出的子 story 则 +1,累计 ≥2 时第 3 次拒拆}

**AC:**
- [ ] {measurable criteria 1}
- [ ] {measurable criteria 2}
- [ ] {measurable criteria 3}
- [ ] {visual-evidence AC — REQUIRED by default: a captured screenshot of this story's user-visible surface (web/CLI/TUI). For a web/visual card this is "screenshot of <the deliverable page> is captured", paired with the `deliverable_url:` frontmatter below. Omit this AC ONLY when the card is `screenshot_exempt:` (see frontmatter).}

**Evaluation contract:**
- expected_evidence:
  - kind: test | command | screenshot | document | diff | ci | manual
    target: {file/command/surface/report expected to prove an AC}
    proves: {AC id or short AC phrase this evidence proves}
- scorer_focus:
  - {what the peer Review Score should judge beyond generic code quality}
- builder_notes:
  - {bounded implementation/evidence hints; no hidden requirements}

> **强制规则 — Evaluation contract 必须填**：每张新 story 必须带 `**Evaluation contract:**` 块（expected_evidence + scorer_focus）。这是 Designer 写给 Builder 和 Evaluator 的验收契约——Builder 编码前读 contract、交付后把 ac-map 项映射回 contract 的 expected_evidence；Evaluator（peer score / attest gate）读 contract 对账。不是固定三 agent 协同模型，是 artifact-based 契约。真正 trivial/internal 故事可放一项 minimal block，但不许省略。
>
> **MUST fill** the `**Evaluation contract:**` block on every newly split story. This is an artifact contract authored by roll-design as the Designer, consumed by Builder (read before coding, map delivered evidence back) and Evaluator (peer score prompt includes it, attest surfaces design-contract-vs-delivered). Genuinely trivial/internal stories may use a one-item minimal block, never omit it.

**Spec frontmatter (visual-evidence contract — FIX-311):**
- A web/visual card MUST declare the real product surface it delivers:
  ```yaml
  ---
  deliverable_url: https://app.example.test/casting#board   # alias: screenshot_url. The actual deliverable page, NEVER the card's own dossier/report/archive page.
  ---
  ```
- **Pin down the deliverable surface — locate it, don't guess** (`deliverable_url` MUST be the EXACT page + anchor the story lands on):
  - *Existing surface* → cite the real tab/anchor and VERIFY it exists (grep the generated page for the `#anchor`); never a parent or plausible-but-wrong page.
  - *New feature* → DECIDE and NAME where it lands (which page / tab / route it is added to); that landing point IS the `deliverable_url` (it may not exist until this story builds it — that is expected; FIX-309 will require a real capture of it at attest, so a wrong/empty target fails loud).
  - Never the card's dossier; never a generic page when the story changes a specific sub-surface.
- A card with genuinely NO user-visible surface (pure data-migration, infra, …) instead records:
  ```yaml
  ---
  screenshot_exempt: pure data-migration — no user-visible surface   # a naked `true`/`yes` is NOT valid; the reason is mandatory.
  ---
  ```

**Files:**
- `{file1}`
- `{file2}`

**Dependencies:**
- Depends on: {prerequisite US-XXX}
- Depended on by: {subsequent US-XXX}

**Data Flow (if applicable):**
- Producer: {which module writes data}
- Consumer: {which module reads data}
- Integration test: `tests/integration/{flow}.test.ts`
```

> **强制规则 — Agent profile 必须填**：Split into Stories 步骤产出的每个 US 都必须带 `**Agent profile:**` 子段。`est_min` 是 **loop 路由唯一输入**（`lib/loop_pick_agent.py` 的四槽复杂度路由 easy/default/hard/fallback，按 est_min 单轴决档；缺失/非法 → default 档）——务必填准。`risk_zone` 仍要填，但**不参与路由**，只供 roll-build / roll-fix 的 pre-flight 自评（US-AGENT-007）参考；`chain_depth` 默认 0。历史 US 不强制回填。
>
> **MUST fill** the `**Agent profile:**` block on every newly split US. `est_min` is the **sole loop-routing input** — `lib/loop_pick_agent.py` maps it onto a four-slot complexity tier (easy/default/hard/fallback) on the est_min axis alone (missing/illegal → default). Fill `risk_zone` too, but note it does NOT feed routing; it only informs the roll-build / roll-fix pre-flight self-eval (US-AGENT-007).

> **强制规则 — Evaluation contract 必须填（US-SKILL-030）**：每张新 story spec 都必须包含 `**Evaluation contract:**` 块，明确列出 `expected_evidence`（每项 kind/target/proves 三字段）和 `scorer_focus`（peer scorer 评分口径）。纯内部/无可见面的 trivial story 可使用 one-item 最小块，但不可省略。该块由 Designer（`roll-design`）撰写，供 Builder 和 Evaluator 作为共享证据契约消费，不触发三 agent 协同会话。

> **Evaluation contract is required (US-SKILL-030)**: every newly split story spec MUST carry an `**Evaluation contract:**` block with `expected_evidence` (each item: `kind`, `target`, `proves`) and `scorer_focus` (scorer rubric). Genuinely trivial/internal stories may use a one-item minimal block but must not omit the section entirely. This block is authored by the Designer (`roll-design`) and consumed as a shared artifact contract by Builder (`roll-build`/`roll-fix`) and Evaluator (peer scorer, attest gate) — no three-agent chat pipeline is introduced.
>
> **Block template:**
> ```markdown
> **Evaluation contract:**
> - expected_evidence:
>   - kind: test | command | screenshot | document | diff | ci | manual
>     target: <file/command/surface/report that proves an AC>
>     proves: <AC id or short AC phrase>
> - scorer_focus:
>   - <what the peer Review Score should judge beyond generic code quality>
> - builder_notes:
>   - <bounded implementation/evidence hints; no hidden requirements>
> ```
>
> **Rules**: (1) `expected_evidence` items are **binding for evidence expectations** — if an item becomes impossible, the builder updates the spec or explains the deviation in the report/ac-map. (2) `scorer_focus` items extend, not replace, the generic scoring rubric. (3) This block complements the visual-evidence contract; `deliverable_url`/`screenshot_exempt` rules are unchanged. (4) Legacy specs without the block degrade gracefully — builder and scorer fall back to the generic rubric with no behavior change.

### Closing Doc-Refresh Story Template — Phase N.M Documentation Refresh

When any preceding US in the batch changes user-visible behavior, append this template story at the end of the batch. Wire it as `depends-on:` against every preceding user-facing US so it runs last.

```markdown
<a id="us-{domain}-{n}"></a>
## US-{DOMAIN}-{N} Phase {N.M} documentation refresh 📋

**Created**: {YYYY-MM-DD}

- As a roll user reading the docs
- I want the user-facing documentation to match the new behavior shipped in this Phase
- So that the next person reading the guide / README / `--help` does not hit a stale version

**AC:**
- [ ] Update each affected doc file listed below; each rendered page is single-language for its locale
- [ ] `roll <cmd> --help` output reflects new flags / commands / status semantics (paste verified output)
- [ ] README index links to any new guide pages
- [ ] Error-message changes are mirrored in troubleshooting / FAQ sections
- [ ] Verified: no doc page still describes the pre-Phase behavior
- [ ] Locale resources/catalog entries stay consistent across affected `en` and `zh` surfaces

**Files:**
- `guide/en/{topic}.md`
- `guide/zh/{topic}.md`
- `README.md` (index entry)
- `{any other user-facing doc touched by the Phase}`

**Dependencies:**
- Depends on: {every preceding user-facing US in this batch}
- Worked example: 参考 `features/authoring/slide-deck-generator.md` 的 US-DECK-015 ——
  roll slides Phase 1.5 把 6 张 user-visible US 末尾合并成一张 doc-refresh story 的范例。
```

---

## INVEST Principles

> **颗粒度校准（按 AI cycle 量纲）**：Roll 的 Story 不是"几天的活"，而是
> **一个 AI cycle 闭环（目标 5–10 min）**。下面的 S 和 I 按这个量纲重定义，
> 别套用传统敏捷"一个 sprint 装几个 story"的尺度。

Each story must be:
- **Independent**: 不强求完全独立。有先后依赖就用 `depends-on:` 串成链（配合
  `chain_depth ≤ 2` 防无限套娃）。真正要避免的是"改同一文件的并行冲突"，
  而不是"禁止依赖"——为追求独立硬把一个 cycle 的活摊成几个反而更糟。
- **Negotiable**: Scope is negotiable
- **Valuable**: Provides value to the user
- **Estimable**: Effort can be estimated
- **Small**: **一个 Story ≈ 一个 AI cycle 闭环（目标 5–10 min）**。S 是 cycle 量纲，
  装不进一个 cycle 就拆；`est_min > ~15` 是"再拆"信号——除非原子不可分。
- **Testable**: Can be tested and verified

## Backlog Structure

```markdown
# Project Backlog

## Epic Name
### Feature Name
| Story | Description | Status |
|-------|-------------|--------|
| [US-XXX](.roll/features/<epic>/<story>/spec.md#us-xxx) | One-line description | 📋 Todo |
| [US-YYY](.roll/features/<epic>/<story>/spec.md#us-yyy) | One-line description | ✅ Done |
```

**Note**: .roll/backlog.md only contains index rows; full AC / Files / Dependencies go in `.roll/features/<epic>/<story>/spec.md`.

---

## Review Score (FIX-343)

The design session is **not** self-scored. The designing agent **does NOT
self-score**. A design Review Score — when one is produced — comes SOLELY from
a Reviewer running in a FRESH, separate session (never a sub-agent of the
designer's session), the same independence rule as build/fix.

The design-side peer Review Score path is tracked by **FIX-344** (the runner's
score stage does not yet cover `roll-design`). Until FIX-344 lands, this skill
emits no quality score; the agent just delivers the split + specs and stops.

### The 3-stage shape (subjective deliverable)

A design has **no executable pass/fail test** — correctness is judgment. So it is
the canonical **3-stage loop**, and naming the stages keeps the roles honest:

- **Designer = this design session.** Besides the split + specs, it must
  emit **explicit evaluation criteria for the design itself** — the prose
  equivalent of a test contract: what would make this design wrong or incomplete
  (e.g. "every Bounded Context boundary is justified", "the worked sample covers
  the hardest edge case", "no story depends on a parked parent", "each
  user-facing story carries a visual-evidence AC"). Write these down so the
  Evaluator has something concrete to check against rather than a vibe.
- **Evaluator = an ISOLATED reviewer.** It receives the design artifact + the
  criteria, and **must not be seeded with the designer's reasoning** (roll-peer's
  Independent Judgment Rule already enforces exactly this — see the two
  `[peer]` checkpoints in the Workflow: Direction Review and Plan Review). A
  fresh same-vendor session is the minimum; a different agent+model is a ranking
  preference unless the owner explicitly requested strict diversity.

Until the runner's FIX-344 stage lands, the isolated Evaluator is the
`$roll-peer` Plan Review checkpoint, not an automated score — but the criteria
above are what it should grade against either way. Emitting the criteria now is
cheap and makes the future automated Evaluator a drop-in.

---

## Integration

### With roll-build

```
$roll-design "login feature" → Create US-AUTH-001
User: "Execute US-AUTH-001"
    ↓
$roll-build US-AUTH-001 → TCR → CI/CD → Deploy
```

### With roll-fix

```
$roll-debug discovers issue → Suggest creating FIX
$roll-design "fix login API 404" → Create FIX-AUTH-001  ← auto-detected as Bug Fix
$roll-fix FIX-AUTH-001 → Quick fix
```

### With roll-peer

Two checkpoints, both with 10s opt-out:

```
1. After Discuss — Direction Review
   Approach confirmed → [peer, tag=architecture] → challenge the direction before DDD
   Trigger: complexity=medium OR complexity=large OR requirement touches multiple Bounded Contexts

2. After Solution Design — Plan Review
   Plan written → [peer, tag=architecture] → full plan review before story split
   Trigger: complexity=medium OR complexity=large (greenfield always qualifies)
```

Rationale (US-SKILL-018): medium-complexity designs also routinely carry
direction/plan risks worth one independent challenge before story split — the
cost of one bounded peer pass is small next to reworking a misaimed design after
it ships. So peer now triggers at medium as well as large; the 10s opt-out
stays, so you can always skip when you're confident.

On AGREE or user skip → continue to the next step normally.
On REFINE/OBJECT → incorporate feedback, regenerate the relevant output, re-trigger peer.
On ESCALATE → present both proposals to user for final call.

---

## Project Context Rule

Before creating any file or directory:

1. **Read existing project structure** — check for `package.json`, `go.mod`, `Cargo.toml`, `pyproject.toml`, existing `src/`, `api/`, `cmd/` directories
2. **Check existing domain model** — if `.roll/domain/` exists, read `context-map.md` before adding new Bounded Contexts
3. **Infer conventions from evidence** — don't assume a project type; observe what already exists
4. **Follow what already exists** — introduce new patterns only when the current structure has no precedent

> `roll init` no longer asks for project type. Skills are responsible for reading context and acting accordingly.

---

<a id="doc-update-discipline"></a>
## Doc Update Discipline

When `$roll-design` splits a feature into stories, **the closing tasking step is
always a doc-refresh story whenever any preceding US changes user-visible
behavior**. This is mandatory, not optional — without it, code ships and the
docs silently drift to the previous version, and only the next user to read the
guide notices.

**When a separate doc-refresh story IS required (任一为真即触发)：**
- 任一 US 改了 **CLI 输出**（新增/修改输出行、表头、颜色、emoji 语义）
- 任一 US 改了 **命令参数**（新增/重命名 flag、改变 default、收紧/放宽校验）
- 任一 US 改了 **状态语义**（backlog 状态、cycle 状态机、退出码含义）
- 任一 US 改了 **错误提示** / 用户可读日志文案
- 任一 US 新增/删除/重命名一个用户能直接调用的命令

**When it can be skipped (纯内部变更，用户感知不到)：**
- 纯内部重构（内部函数改名、模块边界调整、测试沙箱化）
- CI / hooks / 工具链修复
- 安全 / 隔离基础设施（沙箱配置、权限矩阵内部调整）
- 测试基础设施 / fixture 数据更新

**Checklist for the doc-refresh story (locale consistency required):**
- [ ] `guide/en/<topic>.md` — English guide updated
- [ ] `guide/zh/<topic>.md` — Chinese guide updated
- [ ] `README.md` index links to any new doc page
- [ ] `--help` output snapshot matches new flags / commands / status semantics
- [ ] Error-message strings reflected in troubleshooting / FAQ
- [ ] **Language surface rule**: each rendered page/output uses exactly one
      locale; multilingual source resources stay behind `guide/en`, `guide/zh`,
      or catalog boundaries

**How to wire the doc-refresh story:**
1. Place it **last** in the batch
2. `depends-on:` lists **every** preceding user-facing US in the batch
3. Use the "Phase N.M documentation refresh" title template from
   [Story Format](#story-format)
4. Cite a worked example in its Dependencies note — current best reference is
   `features/authoring/slide-deck-generator.md` US-DECK-015 (roll slides Phase 1.5)

> Self-validation: this very skill was strengthened via US-SKILL-009; the
> roll slides Phase 1.5 tasking (US-DECK-015) is the canonical worked example
> of the discipline in action.
