@seanyao/roll 0.5.0 → 2.602.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +717 -0
- package/LICENSE +21 -0
- package/README.md +65 -165
- package/bin/dream-test-quality-scan +110 -0
- package/bin/roll +14897 -815
- package/conventions/config.yaml +17 -1
- package/conventions/global/AGENTS.md +146 -100
- package/conventions/global/CLAUDE.md +1 -21
- package/conventions/global/GEMINI.md +8 -22
- package/conventions/global/project_rules.md +9 -0
- package/conventions/templates/backend-service/AGENTS.md +30 -81
- package/conventions/templates/backend-service/GEMINI.md +3 -3
- package/conventions/templates/backend-service/project_rules.md +16 -0
- package/conventions/templates/cli/AGENTS.md +31 -58
- package/conventions/templates/cli/CLAUDE.md +3 -5
- package/conventions/templates/cli/GEMINI.md +3 -3
- package/conventions/templates/cli/project_rules.md +16 -0
- package/conventions/templates/frontend-only/AGENTS.md +29 -64
- package/conventions/templates/frontend-only/GEMINI.md +3 -3
- package/conventions/templates/frontend-only/project_rules.md +14 -0
- package/conventions/templates/fullstack/AGENTS.md +31 -79
- package/conventions/templates/fullstack/CLAUDE.md +1 -1
- package/conventions/templates/fullstack/GEMINI.md +3 -3
- package/conventions/templates/fullstack/project_rules.md +15 -0
- package/lib/README.md +42 -0
- package/lib/__pycache__/github_sync.cpython-314.pyc +0 -0
- package/lib/__pycache__/loop-fmt.cpython-314.pyc +0 -0
- package/lib/__pycache__/loop_result_eval.cpython-314.pyc +0 -0
- package/lib/__pycache__/loop_unstick.cpython-314.pyc +0 -0
- package/lib/__pycache__/model_prices.cpython-314.pyc +0 -0
- package/lib/__pycache__/prices_fetcher.cpython-314.pyc +0 -0
- package/lib/__pycache__/roll-home.cpython-314.pyc +0 -0
- package/lib/__pycache__/roll-loop-status.cpython-314.pyc +0 -0
- package/lib/__pycache__/roll_git.cpython-314.pyc +0 -0
- package/lib/__pycache__/roll_render.cpython-314.pyc +0 -0
- package/lib/__pycache__/slides-render.cpython-314.pyc +0 -0
- package/lib/agent_usage/README.md +49 -0
- package/lib/agent_usage/__init__.py +108 -0
- package/lib/agent_usage/__pycache__/__init__.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/gemini.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/kimi.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/openai.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/pi.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/pi_emit.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/qwen.cpython-314.pyc +0 -0
- package/lib/agent_usage/gemini.py +127 -0
- package/lib/agent_usage/kimi.py +278 -0
- package/lib/agent_usage/kimi_emit.py +123 -0
- package/lib/agent_usage/openai.py +126 -0
- package/lib/agent_usage/pi.py +200 -0
- package/lib/agent_usage/pi_emit.py +135 -0
- package/lib/agent_usage/qwen.py +128 -0
- package/lib/backfill-pi-usage.py +243 -0
- package/lib/changelog_audit.py +155 -0
- package/lib/changelog_generate.py +263 -0
- package/lib/context_feed_budget.sh +194 -0
- package/lib/github_sync.py +876 -0
- package/lib/i18n/README.md +54 -0
- package/lib/i18n/agent.sh +75 -0
- package/lib/i18n/alert.sh +20 -0
- package/lib/i18n/backlog.sh +96 -0
- package/lib/i18n/brief.sh +5 -0
- package/lib/i18n/changelog.sh +5 -0
- package/lib/i18n/ci.sh +15 -0
- package/lib/i18n/debug.sh +0 -0
- package/lib/i18n/doctor.sh +44 -0
- package/lib/i18n/dream.sh +0 -0
- package/lib/i18n/init.sh +91 -0
- package/lib/i18n/lang.sh +10 -0
- package/lib/i18n/loop.sh +140 -0
- package/lib/i18n/migrate.sh +74 -0
- package/lib/i18n/offboard.sh +31 -0
- package/lib/i18n/onboard.sh +0 -0
- package/lib/i18n/peer.sh +41 -0
- package/lib/i18n/peer_help.sh +25 -0
- package/lib/i18n/peer_reset.sh +7 -0
- package/lib/i18n/peer_status.sh +5 -0
- package/lib/i18n/prices.sh +3 -0
- package/lib/i18n/prices_refresh.sh +17 -0
- package/lib/i18n/prices_show.sh +7 -0
- package/lib/i18n/propose.sh +0 -0
- package/lib/i18n/release.sh +0 -0
- package/lib/i18n/research.sh +0 -0
- package/lib/i18n/review_pr.sh +0 -0
- package/lib/i18n/sentinel.sh +0 -0
- package/lib/i18n/setup.sh +3 -0
- package/lib/i18n/shared.sh +157 -0
- package/lib/i18n/skills/roll-brief.sh +47 -0
- package/lib/i18n/skills/roll-build.sh +97 -0
- package/lib/i18n/skills/roll-design.sh +18 -0
- package/lib/i18n/skills/roll-fix.sh +53 -0
- package/lib/i18n/skills/roll-loop.sh +28 -0
- package/lib/i18n/skills/roll-onboard.sh +33 -0
- package/lib/i18n/skills_catalog.sh +30 -0
- package/lib/i18n/slides.sh +3 -0
- package/lib/i18n/slides_build.sh +38 -0
- package/lib/i18n/slides_delete.sh +19 -0
- package/lib/i18n/slides_list.sh +14 -0
- package/lib/i18n/slides_logs.sh +12 -0
- package/lib/i18n/slides_new.sh +15 -0
- package/lib/i18n/slides_preview.sh +14 -0
- package/lib/i18n/slides_templates.sh +7 -0
- package/lib/i18n/status.sh +21 -0
- package/lib/i18n/update.sh +24 -0
- package/lib/i18n.sh +211 -0
- package/lib/loop-exit-summary.py +393 -0
- package/lib/loop-fmt.py +589 -0
- package/lib/loop_pick_agent.py +316 -0
- package/lib/loop_result_eval.py +469 -0
- package/lib/loop_unstick.py +180 -0
- package/lib/model_prices.py +186 -0
- package/lib/prices/README.md +35 -0
- package/lib/prices/snapshot-2026-05-22.json +22 -0
- package/lib/prices/snapshot-2026-05-23-deepseek.json +15 -0
- package/lib/prices/snapshot-2026-05-23-kimi.json +14 -0
- package/lib/prices_fetcher.py +285 -0
- package/lib/roll-backlog.py +225 -0
- package/lib/roll-brief.py +286 -0
- package/lib/roll-help.py +158 -0
- package/lib/roll-home.py +556 -0
- package/lib/roll-init.py +156 -0
- package/lib/roll-loop-status.py +1683 -0
- package/lib/roll-loop-story.py +191 -0
- package/lib/roll-onboard-render.py +378 -0
- package/lib/roll-peer.py +252 -0
- package/lib/roll-plan-validate.py +386 -0
- package/lib/roll-setup.py +102 -0
- package/lib/roll-status.py +367 -0
- package/lib/roll_git.py +41 -0
- package/lib/roll_render.py +414 -0
- package/lib/slides/components/README.md +123 -0
- package/lib/slides/components/cards-2.html +9 -0
- package/lib/slides/components/cards-3.html +9 -0
- package/lib/slides/components/cards-4.html +9 -0
- package/lib/slides/components/compare.html +22 -0
- package/lib/slides/components/highlight.html +9 -0
- package/lib/slides/components/pipeline.html +12 -0
- package/lib/slides/components/plain.html +7 -0
- package/lib/slides/components/quote.html +4 -0
- package/lib/slides/components/timeline.html +9 -0
- package/lib/slides/templates/introduction-v3.html +571 -0
- package/lib/slides/templates/pitch.html +0 -0
- package/lib/slides-render.py +778 -0
- package/lib/slides-validate.py +357 -0
- package/lib/test_quality_gate.py +143 -0
- package/package.json +8 -7
- package/skills/roll-.changelog/SKILL.md +406 -33
- package/skills/roll-.clarify/SKILL.md +5 -2
- package/skills/roll-.dream/SKILL.md +374 -0
- package/skills/roll-.echo/SKILL.md +5 -2
- package/skills/roll-.qa/SKILL.md +57 -3
- package/skills/roll-.review/SKILL.md +42 -3
- package/skills/roll-brief/SKILL.md +209 -0
- package/skills/roll-build/SKILL.md +308 -63
- package/skills/roll-debug/SKILL.md +341 -162
- package/skills/roll-debug/injectable-bb.js +263 -0
- package/skills/roll-deck/SKILL.md +296 -0
- package/skills/roll-design/ENGINEERING_CHECKLIST.md +1 -1
- package/skills/roll-design/SKILL.md +727 -94
- package/skills/roll-doc/SKILL.md +595 -0
- package/skills/roll-doctor/SKILL.md +192 -0
- package/skills/roll-fix/SKILL.md +149 -32
- package/skills/{roll-jot → roll-idea}/SKILL.md +18 -10
- package/skills/roll-loop/SKILL.md +578 -0
- package/skills/roll-notes/SKILL.md +103 -0
- package/skills/roll-onboard/SKILL.md +234 -0
- package/skills/roll-peer/SKILL.md +336 -0
- package/skills/roll-propose/SKILL.md +157 -0
- package/skills/roll-review-pr/SKILL.md +58 -0
- package/skills/roll-sentinel/SKILL.md +11 -2
- package/skills/roll-spar/SKILL.md +8 -6
- package/template/.github/workflows/ci.yml +5 -2
- package/template/AGENTS.md +20 -74
- package/skills/roll-research/SKILL.md +0 -307
- package/skills/roll-research/references/schema.json +0 -162
- package/skills/roll-research/scripts/md_to_pdf.py +0 -289
- package/tools/roll-fetch/SKILL.md +0 -182
- package/tools/roll-fetch/package.json +0 -15
- package/tools/roll-fetch/smart-web-fetch.js +0 -558
- package/tools/roll-probe/SKILL.md +0 -84
- /package/template/{BACKLOG.md → .roll/backlog.md} +0 -0
|
@@ -1,43 +1,103 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: roll-design
|
|
3
|
-
|
|
3
|
+
license: MIT
|
|
4
|
+
allowed-tools: "Read, Edit, Write, Glob, Grep, Bash(git:*), WebSearch, WebFetch, Skill"
|
|
5
|
+
description: Unified entry for discussion, design and planning. Explores options when uncertain, designs solutions with DDD modeling, splits into INVEST-compliant user stories, and writes to .roll/backlog.md. Use when user wants to discuss approaches, design solutions, plan features, or create stories.
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Design
|
|
7
9
|
|
|
8
10
|
> Follows the Architecture Constraints, Development Discipline, and Engineering Common Sense defined in the project AGENTS.md.
|
|
9
11
|
|
|
10
|
-
Discuss approaches, design architecture, plan requirements, and write to
|
|
12
|
+
Discuss approaches, design architecture, plan requirements, and write to `.roll/backlog.md`. DDD modeling depth scales automatically with input scope.
|
|
11
13
|
|
|
12
14
|
## When to Use
|
|
13
15
|
|
|
14
16
|
- Requirements or approach are uncertain and multiple options need to be compared
|
|
15
17
|
- Requirements have not yet entered the backlog
|
|
16
18
|
- A solution needs to be designed before splitting into Stories
|
|
17
|
-
- An existing plan needs to be written into
|
|
19
|
+
- An existing plan needs to be written into `.roll/backlog.md`
|
|
20
|
+
|
|
21
|
+
> **Doc-refresh discipline**: When splitting stories that change user-visible behavior, always append a closing "doc-refresh" story.
|
|
22
|
+
> **文档刷新纪律**:拆出的 story 只要改变了用户可见行为,最后必须追加一张"文档刷新"收尾 story。
|
|
23
|
+
> See [Doc Update Discipline](#doc-update-discipline) at the bottom of this file for the full rule.
|
|
18
24
|
|
|
19
25
|
## Use This Skill For
|
|
20
26
|
|
|
21
27
|
- Approach exploration and comparison (discuss phase)
|
|
22
|
-
- New
|
|
28
|
+
- New project domain modeling (Event Storming → Context Map → Tactical Model)
|
|
29
|
+
- New requirement planning with domain context
|
|
23
30
|
- Solution design
|
|
24
31
|
- Splitting into Stories
|
|
25
32
|
- Creating US / FIX entries
|
|
26
33
|
|
|
34
|
+
## When Not to Use
|
|
35
|
+
|
|
36
|
+
- One-liner capture of ideas or bugs (use `$roll-idea`)
|
|
37
|
+
- Executing an already-split US-XXX (use `$roll-build`)
|
|
38
|
+
- Fixing a well-defined FIX-XXX (use `$roll-fix`)
|
|
39
|
+
|
|
27
40
|
## Quick Start
|
|
28
41
|
|
|
29
42
|
```bash
|
|
43
|
+
# New project from scratch → full DDD modeling
|
|
44
|
+
$roll-design "design an e-commerce order system from scratch"
|
|
45
|
+
|
|
30
46
|
# Approach is uncertain → discuss first, then plan
|
|
31
47
|
$roll-design "What approach should we use for search? Postgres FTS or Meilisearch?"
|
|
32
48
|
|
|
33
|
-
# Plan new requirement →
|
|
49
|
+
# Plan new requirement → domain slice + Stories → write to BACKLOG
|
|
34
50
|
$roll-design "user system design"
|
|
35
51
|
|
|
36
52
|
# Split Stories from an existing Plan
|
|
37
|
-
$roll-design --from-plan
|
|
53
|
+
$roll-design --from-plan .roll/features/auth-plan.md
|
|
54
|
+
|
|
55
|
+
# Directly create a Story (auto-detected as User Story → Slice DDD)
|
|
56
|
+
$roll-design "user login feature"
|
|
57
|
+
|
|
58
|
+
# Non-interactive: read structured input file, skip Clarify/Discuss, write BACKLOG
|
|
59
|
+
$roll-design --from-file docs/requirements/auth-req.md
|
|
60
|
+
|
|
61
|
+
# Promote IDEA to Story: read BACKLOG IDEA-NNN, produce US-XXX, annotate IDEA
|
|
62
|
+
$roll-design --from-idea IDEA-009
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## DDD Depth Scale
|
|
66
|
+
|
|
67
|
+
DDD modeling depth is determined automatically. It is not a switch — it is a dial.
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
输入范围 DDD 深度 产出物
|
|
71
|
+
─────────────────────────────────────────────────────────────
|
|
72
|
+
新项目 / greenfield Full Event Storming (对话引导)
|
|
73
|
+
Context Map + UL 词汇表
|
|
74
|
+
每个 Context 的 Tactical Model
|
|
75
|
+
→ .roll/domain/
|
|
76
|
+
|
|
77
|
+
User Story / 新特性 Slice 定位所属 Bounded Context
|
|
78
|
+
关键 Aggregate + 触碰的 Entity/VO
|
|
79
|
+
触发的 Domain Event + 跨域影响
|
|
80
|
+
→ 写入 US 的 Domain Model 段
|
|
81
|
+
|
|
82
|
+
Bug Fix Tag Context > Aggregate > Entity 定位
|
|
83
|
+
→ 写入 FIX 描述行
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**深度自动判断逻辑**(在 Step 2 Analyze 阶段评估):
|
|
38
87
|
|
|
39
|
-
|
|
40
|
-
|
|
88
|
+
```
|
|
89
|
+
Greenfield 信号(满足任意一条):
|
|
90
|
+
- 无 .roll/backlog.md / .roll/domain/ 目录
|
|
91
|
+
- 输入含 "从零" / "新项目" / "建模" / "设计整个系统" 关键词
|
|
92
|
+
- complexity = large AND 无已有 Bounded Context 文档
|
|
93
|
+
|
|
94
|
+
User Story 信号:
|
|
95
|
+
- 输入是功能需求 / US-XXX 引用
|
|
96
|
+
- complexity = medium or small AND 业务逻辑可见
|
|
97
|
+
|
|
98
|
+
Bug Fix 信号:
|
|
99
|
+
- 输入是 FIX-XXX / 错误描述 / 明确的问题定位
|
|
100
|
+
- 无需建模,只需定位上下文
|
|
41
101
|
```
|
|
42
102
|
|
|
43
103
|
## Workspace Configuration
|
|
@@ -45,28 +105,106 @@ $roll-design --story "user login feature"
|
|
|
45
105
|
Document structure (two-layer separation):
|
|
46
106
|
|
|
47
107
|
```
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
<feature>.md
|
|
51
|
-
<feature>-plan.md
|
|
108
|
+
.roll/backlog.md # US index page (status + one-liner + link)
|
|
109
|
+
.roll/features/
|
|
110
|
+
<feature>.md # US details (AC / Files / Dependencies)
|
|
111
|
+
<feature>-plan.md # Design document (why / how)
|
|
112
|
+
.roll/domain/ # DDD domain model (greenfield / cross-feature)
|
|
113
|
+
context-map.md # Bounded Contexts + 关系图
|
|
114
|
+
ubiquitous-language.md # 统一语言词汇表
|
|
115
|
+
<context>-model.md # 每个 Context 的 Tactical Model
|
|
52
116
|
```
|
|
53
117
|
|
|
54
118
|
**Important rules:**
|
|
55
|
-
1. Plan files go in
|
|
56
|
-
2. US details go in the corresponding
|
|
57
|
-
3.
|
|
58
|
-
4. **
|
|
119
|
+
1. Plan files go in `.roll/features/<feature>-plan.md` (**no longer using** `docs/plans/`)
|
|
120
|
+
2. US details go in the corresponding `.roll/features/<feature>.md`
|
|
121
|
+
3. **FIX / IDEA detail files use ID-prefixed filenames**: `.roll/features/<epic>/FIX-097.md`, not `.roll/features/<epic>/some-descriptive-slug.md`. Reason: a single FIX is one card, not a long-lived feature; the ID is the most stable handle, descriptive slugs date quickly and break links. US can keep feature-slug naming (US lives inside a multi-Story feature file). Quick lookup: `ls .roll/features/<epic>/FIX-*.md` finds all bugs in that area without grepping content.
|
|
122
|
+
4. .roll/backlog.md only contains index rows (one row per US), **do not write** AC / Files / Notes
|
|
123
|
+
5. Domain model files go in `.roll/domain/` — create on first greenfield design, update incrementally
|
|
124
|
+
6. **Do not** write to `~/.kimi/`, `~/.kimi-code/`, or any global config directory
|
|
59
125
|
|
|
60
126
|
**File path resolution order:**
|
|
61
127
|
1. Determine Feature ownership (based on the requirement domain: compiler / ingest / qa / ...)
|
|
62
|
-
2. Feature file:
|
|
63
|
-
3. Plan file:
|
|
64
|
-
4.
|
|
128
|
+
2. Feature file: `.roll/features/<feature>.md` (create if it doesn't exist)
|
|
129
|
+
3. Plan file: `.roll/features/<feature>-plan.md` (create if it doesn't exist)
|
|
130
|
+
4. .roll/backlog.md index row goes under the corresponding Epic > Feature group
|
|
131
|
+
|
|
132
|
+
## Non-Interactive Mode
|
|
133
|
+
|
|
134
|
+
Activated by explicit flags or auto-detected high-confidence input. Skips Clarify and Discuss, writes stories directly to BACKLOG as `📋 Todo`, no confirm gate.
|
|
135
|
+
|
|
136
|
+
### `--from-file <path>`
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
Input: structured requirement file (plain text or markdown)
|
|
140
|
+
|
|
141
|
+
Expected file contents (minimum viable):
|
|
142
|
+
- Description: what to build (1–3 sentences)
|
|
143
|
+
- Expected AC: measurable outcomes (bullet list)
|
|
144
|
+
- [Optional] Domain hint, priority, dependencies
|
|
145
|
+
|
|
146
|
+
Execution path:
|
|
147
|
+
[Read file] → [Analyze] → [DDD Slice] → [Solution Design] → [Split Stories]
|
|
148
|
+
→ [Write BACKLOG 📋 Todo] → Done (no Clarify, no Discuss, no confirm gate)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Input file example (`docs/requirements/auth-req.md`):
|
|
152
|
+
```markdown
|
|
153
|
+
## Requirement: session timeout warning
|
|
154
|
+
|
|
155
|
+
Description: Show a countdown modal 60 seconds before session expires.
|
|
156
|
+
Users can click "Stay logged in" to extend, or let it expire naturally.
|
|
157
|
+
|
|
158
|
+
Expected AC:
|
|
159
|
+
- Modal appears at T-60s with countdown timer
|
|
160
|
+
- "Stay logged in" sends a keepalive and dismisses modal
|
|
161
|
+
- Expiry after countdown logs user out and redirects to /login
|
|
162
|
+
- Works across all authenticated pages
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### `--from-idea IDEA-NNN`
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
Input: IDEA-NNN identifier from .roll/backlog.md
|
|
169
|
+
|
|
170
|
+
Execution path:
|
|
171
|
+
[Read .roll/backlog.md IDEA-NNN row] → [Analyze] → [DDD Slice] → [Split Stories]
|
|
172
|
+
→ [Write BACKLOG 📋 Todo] → [Annotate IDEA row: → US-XXX] → Done
|
|
173
|
+
|
|
174
|
+
IDEA annotation: append `→ US-XXX` to the IDEA row's Description column.
|
|
175
|
+
Example: | IDEA-009 | ... | ✅ Done → US-AUTO-021 |
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### High-Confidence Auto-Detection
|
|
179
|
+
|
|
180
|
+
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).
|
|
181
|
+
|
|
182
|
+
High-confidence signals (all three must be present):
|
|
183
|
+
- Clear verb: add / remove / fix / rename / migrate / split / extract / support ...
|
|
184
|
+
- Explicit scope: named file, command, module, endpoint, or UI element
|
|
185
|
+
- Acceptance signal: "so that X", "when Y then Z", measurable outcome described
|
|
186
|
+
|
|
187
|
+
Examples:
|
|
188
|
+
```bash
|
|
189
|
+
# High confidence — skip Clarify:
|
|
190
|
+
$roll-design "add --dry-run flag to roll loop on that prints plist without installing"
|
|
191
|
+
$roll-design "rename cmd_status() to cmd_overview() in bin/roll and update all callers"
|
|
192
|
+
|
|
193
|
+
# Low confidence — enter Clarify:
|
|
194
|
+
$roll-design "improve the status command"
|
|
195
|
+
$roll-design "make loop better"
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
65
199
|
|
|
66
200
|
## Workflow
|
|
67
201
|
|
|
68
202
|
```
|
|
69
|
-
User
|
|
203
|
+
User Input
|
|
204
|
+
│
|
|
205
|
+
├── --from-file <path> ──→ [Read file] → Step 2 (Analyze) → Steps 3–5 → BACKLOG 📋 → Done
|
|
206
|
+
├── --from-idea IDEA-N ──→ [Read BACKLOG IDEA] → Step 2 → Steps 3–5 → BACKLOG 📋 → Annotate IDEA → Done
|
|
207
|
+
├── high-confidence str ──→ Step 2 (Analyze) directly (skip Clarify, keep Discuss if divergence)
|
|
70
208
|
│
|
|
71
209
|
▼
|
|
72
210
|
┌─────────────────────────────┐
|
|
@@ -89,56 +227,321 @@ User: "Help me design the user system" / "What approach should we use for search
|
|
|
89
227
|
│ Approach confirmed
|
|
90
228
|
▼
|
|
91
229
|
┌─────────────────────────────┐
|
|
92
|
-
│
|
|
93
|
-
│ -
|
|
94
|
-
│
|
|
95
|
-
│ - Technical solution design │
|
|
230
|
+
│ [peer] Direction Review │ ← if complexity=large or cross-context; 10s opt-out
|
|
231
|
+
│ Skill("roll-peer", │
|
|
232
|
+
│ tag="architecture") │
|
|
96
233
|
└─────────────┬───────────────┘
|
|
97
|
-
│
|
|
234
|
+
│ AGREE / skipped
|
|
98
235
|
▼
|
|
99
236
|
┌─────────────────────────────┐
|
|
100
|
-
│
|
|
101
|
-
│ -
|
|
102
|
-
│ -
|
|
103
|
-
│ -
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
│
|
|
111
|
-
│ -
|
|
112
|
-
│
|
|
113
|
-
│ -
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
│
|
|
119
|
-
│
|
|
120
|
-
│
|
|
121
|
-
│
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
237
|
+
│ 2. Analyze + DDD Depth │ ← Detect scope: Greenfield / Story / Fix
|
|
238
|
+
│ - Requirement analysis │
|
|
239
|
+
│ - Feasibility assessment │
|
|
240
|
+
│ - DDD depth determination │
|
|
241
|
+
└──────┬──────────────────────┘
|
|
242
|
+
│
|
|
243
|
+
├── Greenfield ──→ ┌─────────────────────────────┐
|
|
244
|
+
│ │ 2a. Event Storming (对话引导) │
|
|
245
|
+
│ │ Big Picture: │
|
|
246
|
+
│ │ - 发现 Domain Events │
|
|
247
|
+
│ │ - 识别 Actors / Commands │
|
|
248
|
+
│ │ - 标记 Hot Spots │
|
|
249
|
+
│ │ Process Level: │
|
|
250
|
+
│ │ - Command→Event→Policy 链 │
|
|
251
|
+
│ │ - 识别 Bounded Context 边界│
|
|
252
|
+
│ │ Design Level: │
|
|
253
|
+
│ │ - Aggregate 候选 │
|
|
254
|
+
│ │ - Entity vs Value Object │
|
|
255
|
+
│ └──────────────┬──────────────┘
|
|
256
|
+
│ │
|
|
257
|
+
│ ┌──────────────▼──────────────┐
|
|
258
|
+
│ │ 2b. Strategic Design │
|
|
259
|
+
│ │ - Bounded Contexts 定义 │
|
|
260
|
+
│ │ - Context Map (关系类型) │
|
|
261
|
+
│ │ - Ubiquitous Language 词汇表│
|
|
262
|
+
│ │ → .roll/domain/context-map.md│
|
|
263
|
+
│ │ → .roll/domain/ubiquitous- │
|
|
264
|
+
│ │ language.md │
|
|
265
|
+
│ └──────────────┬──────────────┘
|
|
266
|
+
│ │
|
|
267
|
+
├── User Story ──→ ┌──────────────▼──────────────┐
|
|
268
|
+
│ │ 2c. Domain Slice │
|
|
269
|
+
│ │ - 定位所属 Bounded Context │
|
|
270
|
+
│ │ - 识别关键 Aggregate │
|
|
271
|
+
│ │ - 触碰的 Entity / VO │
|
|
272
|
+
│ │ - 触发的 Domain Events │
|
|
273
|
+
│ │ - 跨域影响(如有) │
|
|
274
|
+
│ └──────────────┬──────────────┘
|
|
275
|
+
│ │
|
|
276
|
+
└── Bug Fix ─────→ ┌──────────────▼──────────────┐
|
|
277
|
+
│ 2d. Domain Tag │
|
|
278
|
+
│ - Context > Aggregate > │
|
|
279
|
+
│ Entity 定位 │
|
|
280
|
+
└──────────────┬──────────────┘
|
|
281
|
+
│
|
|
282
|
+
▼
|
|
283
|
+
┌─────────────────────────────────────────┐
|
|
284
|
+
│ 3. Solution Design │
|
|
285
|
+
│ - Architecture design │
|
|
286
|
+
│ - Module decomposition │
|
|
287
|
+
│ - Dependency analysis │
|
|
288
|
+
│ [Greenfield] Tactical Model per Context:
|
|
289
|
+
│ - Aggregate Root + Entities + VOs │
|
|
290
|
+
│ - Invariants (业务不变式) │
|
|
291
|
+
│ - Domain Events (触发条件 + 消费方) │
|
|
292
|
+
│ - Repository interfaces │
|
|
293
|
+
│ - Domain Services (跨 Aggregate) │
|
|
294
|
+
│ → .roll/features/<feature>-plan.md │
|
|
295
|
+
│ [Greenfield] → .roll/domain/<ctx>- │
|
|
296
|
+
│ model.md │
|
|
297
|
+
└──────────────────┬──────────────────────┘
|
|
298
|
+
│
|
|
299
|
+
▼
|
|
300
|
+
┌─────────────────────────────────────────┐
|
|
301
|
+
│ [peer] Plan Review │ ← if complexity=large; 10s opt-out
|
|
302
|
+
│ Skill("roll-peer", tag="architecture")│
|
|
303
|
+
└──────────────────┬──────────────────────┘
|
|
304
|
+
│ AGREE / skipped
|
|
305
|
+
▼
|
|
306
|
+
┌─────────────────────────────────────────┐
|
|
307
|
+
│ 4. Split into Stories │
|
|
308
|
+
│ - INVEST principles │
|
|
309
|
+
│ - Bounded Context → US domain prefix │
|
|
310
|
+
│ - Priority ordering │
|
|
311
|
+
│ - **强制检查**: 若本批次任一 US 改了 │
|
|
312
|
+
│ 用户可见行为(CLI 输出 / 命令参数 / │
|
|
313
|
+
│ 状态语义 / 错误提示),必须在末尾追加 │
|
|
314
|
+
│ 一张 doc-refresh 收尾 story │
|
|
315
|
+
│ (详见 Doc Update Discipline 一节)│
|
|
316
|
+
└──────────────────┬──────────────────────┘
|
|
317
|
+
│
|
|
318
|
+
▼
|
|
319
|
+
┌─────────────────────────────────────────┐
|
|
320
|
+
│ 5. Write to .roll/backlog.md │
|
|
321
|
+
│ - Create US-XXX │
|
|
322
|
+
│ - Define AC │
|
|
323
|
+
│ - Link design documents │
|
|
324
|
+
└──────────────────┬──────────────────────┘
|
|
325
|
+
│
|
|
326
|
+
▼
|
|
327
|
+
"Confirm and execute?"
|
|
328
|
+
│
|
|
329
|
+
├── Yes ──→ $roll-build US-XXX
|
|
330
|
+
│
|
|
331
|
+
└── No ──→ Story 已写入 BACKLOG 为 📋 Todo
|
|
332
|
+
loop 下轮将自动执行
|
|
333
|
+
(选 No 仅跳过立即执行)
|
|
130
334
|
```
|
|
131
335
|
|
|
132
|
-
**
|
|
336
|
+
**Gate 语义澄清**:选 `No` 不是放弃,story 已经入 BACKLOG,下轮 loop 会自动 pickup
|
|
337
|
+
(次日 / `roll loop now`)。若想完全搁置,请显式把状态改为 🚫 Hold。
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## DDD Output Formats
|
|
342
|
+
|
|
343
|
+
### Event Storming — Big Picture (对话引导)
|
|
344
|
+
|
|
345
|
+
AI 扮演引导人,按顺序提问,不跳步骤:
|
|
346
|
+
|
|
347
|
+
```
|
|
348
|
+
Step 1 - 发现 Domain Events:
|
|
349
|
+
"请描述这个系统里会发生的重要事情,用过去式动词短语
|
|
350
|
+
(例如:订单已创建、支付已完成、库存已扣减)"
|
|
351
|
+
|
|
352
|
+
Step 2 - 识别触发者:
|
|
353
|
+
"每个事件是谁/什么触发的?
|
|
354
|
+
(用户操作 / 系统自动 / 定时任务 / 外部系统)"
|
|
355
|
+
|
|
356
|
+
Step 3 - 标记 Hot Spots:
|
|
357
|
+
"哪些地方你还不确定?有哪些业务规则有争议?
|
|
358
|
+
(标记为 ⚠️ Hot Spot,后续重点讨论)"
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
输出格式(Big Picture 阶段结果):
|
|
362
|
+
|
|
363
|
+
```
|
|
364
|
+
Domain Events discovered:
|
|
365
|
+
[OrderPlaced] ← Customer (user action)
|
|
366
|
+
[PaymentCompleted] ← Payment Gateway (external)
|
|
367
|
+
[InventoryReserved] ← System (automatic, after OrderPlaced)
|
|
368
|
+
[OrderShipped] ← Warehouse Staff (user action)
|
|
369
|
+
|
|
370
|
+
Hot Spots ⚠️:
|
|
371
|
+
- 支付失败后如何回滚库存预留?
|
|
372
|
+
- 同一商品多仓库时库存扣减策略?
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Event Storming — Process Level
|
|
376
|
+
|
|
377
|
+
```
|
|
378
|
+
Step 4 - Command→Event 链:
|
|
379
|
+
"把事件串成流程:什么命令触发了它?
|
|
380
|
+
触发后系统自动做什么(Policy)?"
|
|
381
|
+
|
|
382
|
+
Step 5 - 识别 Bounded Context 边界:
|
|
383
|
+
"哪些事件自然聚集在一起?
|
|
384
|
+
哪些事件之间有明显的组织边界或团队边界?"
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
输出格式(Process Level 阶段结果):
|
|
388
|
+
|
|
389
|
+
```
|
|
390
|
+
Flow: Order Lifecycle
|
|
391
|
+
[PlaceOrder] ──→ (Order) ──→ [OrderPlaced]
|
|
392
|
+
│ Policy: reserve inventory
|
|
393
|
+
▼
|
|
394
|
+
(Inventory) ──→ [InventoryReserved]
|
|
395
|
+
│ Policy: request payment
|
|
396
|
+
▼
|
|
397
|
+
(Payment) ──→ [PaymentCompleted]
|
|
398
|
+
|
|
399
|
+
Candidate Bounded Contexts:
|
|
400
|
+
- Order Context (OrderPlaced, OrderShipped, OrderCancelled)
|
|
401
|
+
- Inventory Context (InventoryReserved, InventoryReleased)
|
|
402
|
+
- Payment Context (PaymentCompleted, PaymentFailed)
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### Strategic Design Output
|
|
406
|
+
|
|
407
|
+
写入 `.roll/domain/context-map.md`:
|
|
408
|
+
|
|
409
|
+
```markdown
|
|
410
|
+
## Bounded Contexts
|
|
411
|
+
|
|
412
|
+
| Context | 职责边界 | 核心概念 |
|
|
413
|
+
|---------|---------|---------|
|
|
414
|
+
| Order | 订单生命周期管理 | Order, OrderItem, Customer |
|
|
415
|
+
| Inventory | 库存预留与释放 | Stock, Reservation, Warehouse |
|
|
416
|
+
| Payment | 支付处理与退款 | Payment, Refund, Transaction |
|
|
417
|
+
|
|
418
|
+
## Context Map
|
|
419
|
+
|
|
420
|
+
Order ═══U/D═══→ Inventory (Customer-Supplier: Order 下游消费库存事件)
|
|
421
|
+
Order ═══U/D═══→ Payment (Customer-Supplier: Order 发起支付请求)
|
|
422
|
+
Payment ──ACL──→ Alipay (Anti-Corruption Layer: 防腐层隔离第三方)
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
写入 `.roll/domain/ubiquitous-language.md`:
|
|
426
|
+
|
|
427
|
+
```markdown
|
|
428
|
+
| 术语 | 定义 | 所属 Context | 注意事项 |
|
|
429
|
+
|-----|------|-------------|---------|
|
|
430
|
+
| Order | 买家提交的购买意向,包含商品列表和配送信息 | Order | 不等于"交易",交易在 Payment Context |
|
|
431
|
+
| Reservation | 为订单锁定的库存数量,有时效 | Inventory | 区别于 Allocation(正式分配) |
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
Context Map 关系类型说明:
|
|
435
|
+
|
|
436
|
+
```
|
|
437
|
+
═══U/D═══→ Customer-Supplier (上下游依赖)
|
|
438
|
+
───ACL───→ Anti-Corruption Layer (防腐层)
|
|
439
|
+
═══PL════ Partnership (平等协作)
|
|
440
|
+
───SK─── Shared Kernel (共享内核)
|
|
441
|
+
───CF───→ Conformist (顺从者)
|
|
442
|
+
───OHS──→ Open Host Service (开放主机)
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### Tactical Model Output
|
|
446
|
+
|
|
447
|
+
写入 `.roll/domain/<context>-model.md`:
|
|
448
|
+
|
|
449
|
+
```markdown
|
|
450
|
+
## Tactical Model: Order Context
|
|
451
|
+
|
|
452
|
+
### Aggregates
|
|
453
|
+
|
|
454
|
+
**Order** (Aggregate Root)
|
|
455
|
+
Entities: OrderItem
|
|
456
|
+
Value Objects: Address, Money, OrderStatus
|
|
457
|
+
Invariants:
|
|
458
|
+
- 订单金额 = sum(OrderItem.price × quantity)
|
|
459
|
+
- 已支付订单不可修改商品列表
|
|
460
|
+
- OrderItem 数量必须 > 0
|
|
461
|
+
|
|
462
|
+
### Domain Events
|
|
463
|
+
|
|
464
|
+
| Event | 触发条件 | 消费方 | Payload |
|
|
465
|
+
|-------|---------|-------|---------|
|
|
466
|
+
| OrderPlaced | Order.place() 成功 | Inventory Context | orderId, items, customerId |
|
|
467
|
+
| OrderCancelled | Order.cancel() | Inventory Context, Payment Context | orderId, reason |
|
|
468
|
+
|
|
469
|
+
### Repository Interfaces
|
|
470
|
+
|
|
471
|
+
IOrderRepository:
|
|
472
|
+
- findById(orderId): Order
|
|
473
|
+
- save(order): void
|
|
474
|
+
- findByCustomer(customerId, page): Order[]
|
|
475
|
+
|
|
476
|
+
### Domain Services
|
|
477
|
+
|
|
478
|
+
OrderPricingService:
|
|
479
|
+
- 职责: 跨 PriceRule Aggregate 计算最终价格(含优惠券、会员折扣)
|
|
480
|
+
- 原因: 定价逻辑跨越多个 Aggregate,不归属任何单一 Root
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
### Domain Slice Output(User Story 级别)
|
|
484
|
+
|
|
485
|
+
插入 US 的 Domain Model 段(见 Story Format):
|
|
486
|
+
|
|
487
|
+
```markdown
|
|
488
|
+
**Domain Model:**
|
|
489
|
+
- Context: Order
|
|
490
|
+
- Aggregate: Order (Root) owns [OrderItem, Address]
|
|
491
|
+
- Entities touched: OrderItem (新增/修改)
|
|
492
|
+
- Events raised: [OrderItemUpdated] → Inventory Context
|
|
493
|
+
- Cross-context: Inventory Context 需同步更新预留数量
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### Domain Tag Output(Bug Fix 级别)
|
|
497
|
+
|
|
498
|
+
写入 FIX 描述的第一行:
|
|
499
|
+
|
|
500
|
+
```
|
|
501
|
+
Domain: Order Context > Order Aggregate > OrderItem Entity
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
### AGENTS.md Where to Look — 指针维护
|
|
505
|
+
|
|
506
|
+
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:
|
|
507
|
+
|
|
508
|
+
```markdown
|
|
509
|
+
- **Domain model**: `.roll/domain/context-map.md` — Bounded Contexts and relationships
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
Rules:
|
|
513
|
+
- Idempotent: only append if the pointer line is not already present
|
|
514
|
+
- Do not modify any other content in AGENTS.md
|
|
515
|
+
- Skip silently if `.roll/domain/` does not yet exist for this project
|
|
516
|
+
|
|
517
|
+
---
|
|
518
|
+
|
|
519
|
+
## Clarify Phase
|
|
520
|
+
|
|
521
|
+
**Skip conditions** — silently skip Clarify when any of these hold:
|
|
522
|
+
- Input uses `--from-file` or `--from-idea` flag (non-interactive mode)
|
|
523
|
+
- Input is high-confidence (clear verb + explicit scope + acceptance signal — see Non-Interactive Mode)
|
|
524
|
+
|
|
525
|
+
**Trigger conditions** — automatically enters if none of the skip conditions hold AND any of these are met:
|
|
133
526
|
- Input is a single vague sentence without clear scope
|
|
134
527
|
- Missing clear boundaries (what / who / when / where)
|
|
135
528
|
- Contains ambiguous terms like "优化一下", "改一下", "加个东西", "做个设计"
|
|
136
529
|
- Could be interpreted in multiple ways
|
|
137
530
|
|
|
138
|
-
**Clarify
|
|
531
|
+
**Pre-Clarify: three-step product localization (always run first, silently)**
|
|
532
|
+
|
|
533
|
+
Before listing questions, internally determine:
|
|
534
|
+
1. **产品端 (product end)**: web / mobile / API / CLI / other — which surface does this touch?
|
|
535
|
+
2. **角色 (role)**: who initiates this action? (end user / admin / system / external)
|
|
536
|
+
3. **业务域 (domain)**: which business domain does this belong to?
|
|
537
|
+
|
|
538
|
+
Already-localized dimensions become context prefix in the output, not open questions.
|
|
539
|
+
|
|
540
|
+
**Output format:**
|
|
139
541
|
|
|
140
542
|
```
|
|
141
543
|
🎯 Clarified Intent: {1-2 sentences}
|
|
544
|
+
🗺 Context: {product end} · {role} · {domain} ← omit if all three are unknown
|
|
142
545
|
|
|
143
546
|
📏 Complexity: {small|medium|large}
|
|
144
547
|
|
|
@@ -151,43 +554,115 @@ User: "Help me design the user system" / "What approach should we use for search
|
|
|
151
554
|
➡️ Please answer the questions above and I'll proceed to design.
|
|
152
555
|
```
|
|
153
556
|
|
|
154
|
-
**
|
|
557
|
+
**Rules:**
|
|
155
558
|
- Do **not** start designing until the user replies.
|
|
156
559
|
- Never announce "I'm using clarify." Just do it naturally.
|
|
157
560
|
- If the input is already clear enough, skip silently and proceed to Discuss or Analyze.
|
|
158
561
|
|
|
159
|
-
|
|
562
|
+
---
|
|
563
|
+
|
|
564
|
+
## Discuss Phase
|
|
565
|
+
|
|
566
|
+
**Trigger conditions** — automatically enters if any of these are met:
|
|
160
567
|
- User is explicitly asking "how to choose" or "what approach to use"
|
|
161
568
|
- More than 2 viable technical paths exist
|
|
162
569
|
- Requirement involves an unfamiliar tech stack or new domain
|
|
163
570
|
|
|
164
|
-
|
|
571
|
+
### How to Conduct the Discussion
|
|
572
|
+
|
|
573
|
+
Discuss is **multi-turn by default**. The goal is to reach clarity together, not to produce a complete comparison matrix in one shot.
|
|
574
|
+
|
|
575
|
+
**Step 1 — Understand before proposing**
|
|
165
576
|
|
|
166
|
-
|
|
577
|
+
Before listing options, make sure the core problem is clear. If context is thin, ask 1–2 focused questions first:
|
|
578
|
+
|
|
579
|
+
```
|
|
580
|
+
Before I lay out the options — can you tell me [specific constraint / scale / existing system boundary]?
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
Only skip this if the context is already rich enough to reason from.
|
|
584
|
+
|
|
585
|
+
**Step 2 — Offer an opinionated starting point, not a menu**
|
|
586
|
+
|
|
587
|
+
Don't dump 4 options at once. Lead with a concrete recommendation and the key tradeoff:
|
|
588
|
+
|
|
589
|
+
```
|
|
590
|
+
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?
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
Then wait. Let the user redirect.
|
|
594
|
+
|
|
595
|
+
**Step 3 — Follow the thread**
|
|
596
|
+
|
|
597
|
+
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.
|
|
598
|
+
|
|
599
|
+
**Step 4 — Surface hidden assumptions explicitly**
|
|
600
|
+
|
|
601
|
+
When a direction starts to crystallize, name the assumptions holding it up:
|
|
602
|
+
|
|
603
|
+
```
|
|
604
|
+
This only holds if [assumption]. Is that true for your situation?
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
**Step 5 — Name convergence before triggering the gate**
|
|
608
|
+
|
|
609
|
+
When the discussion reaches a clear conclusion, summarize it explicitly before asking to proceed:
|
|
610
|
+
|
|
611
|
+
```
|
|
612
|
+
Looks like we've landed on: [decision]. The key reasons: [1–2 points].
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
Then trigger the gate.
|
|
616
|
+
|
|
617
|
+
**Gate rule** — after convergence is named, always end with this explicit prompt and **wait for user reply before proceeding**:
|
|
618
|
+
|
|
619
|
+
```
|
|
620
|
+
➡️ Continue to solution design, or keep exploring?
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
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").
|
|
624
|
+
|
|
625
|
+
**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.
|
|
626
|
+
|
|
627
|
+
---
|
|
628
|
+
|
|
629
|
+
## Operation Sequence for Creating a New Story
|
|
167
630
|
|
|
168
631
|
```bash
|
|
169
632
|
# 1. Determine Feature ownership (e.g., compiler / ingest / qa)
|
|
170
633
|
FEATURE="compiler"
|
|
171
634
|
|
|
172
635
|
# 2. Write Plan document (if there is a solution design)
|
|
173
|
-
PLAN_FILE="
|
|
636
|
+
PLAN_FILE=".roll/features/${FEATURE}-plan.md"
|
|
174
637
|
|
|
175
|
-
# 3. Append US section in
|
|
176
|
-
FEATURE_FILE="
|
|
638
|
+
# 3. Append US section in .roll/features/<feature>.md (with full AC)
|
|
639
|
+
FEATURE_FILE=".roll/features/${FEATURE}.md"
|
|
177
640
|
|
|
178
|
-
# 4. Append index row under the corresponding Epic > Feature group in
|
|
179
|
-
# | [US-XXX](
|
|
641
|
+
# 4. Append index row under the corresponding Epic > Feature group in .roll/backlog.md
|
|
642
|
+
# | [US-XXX](.roll/features/compiler.md#us-xxx) | One-line description | 📋 Todo |
|
|
643
|
+
|
|
644
|
+
# 5. [Greenfield only] Write domain model files
|
|
645
|
+
DOMAIN_DIR=".roll/domain/"
|
|
646
|
+
# .roll/domain/context-map.md
|
|
647
|
+
# .roll/domain/ubiquitous-language.md
|
|
648
|
+
# .roll/domain/<context>-model.md
|
|
180
649
|
```
|
|
181
650
|
|
|
651
|
+
---
|
|
652
|
+
|
|
182
653
|
## Story Format
|
|
183
654
|
|
|
184
|
-
|
|
655
|
+
**.roll/backlog.md index row (only write this one line):**
|
|
185
656
|
|
|
186
657
|
```markdown
|
|
187
|
-
| [US-{DOMAIN}-{N}](
|
|
658
|
+
| [US-{DOMAIN}-{N}](.roll/features/<feature>.md#us-{domain}-{n}) | {one-line description} | 📋 Todo |
|
|
188
659
|
```
|
|
189
660
|
|
|
190
|
-
|
|
661
|
+
`{one-line description}` 写法:用户能读懂的一句话,说清楚"能做什么"或"解决了什么麻烦"。不写实现细节、文件路径、函数名。细节和 AC 写在 `.roll/features/` 里。写好了可以直接当 CHANGELOG 条目用。
|
|
662
|
+
|
|
663
|
+
Note: `{DOMAIN}` maps to the Bounded Context name identified in DDD analysis.
|
|
664
|
+
|
|
665
|
+
**US section in .roll/features/\<feature\>.md (full details):**
|
|
191
666
|
|
|
192
667
|
```markdown
|
|
193
668
|
<a id="us-{domain}-{n}"></a>
|
|
@@ -200,6 +675,17 @@ FEATURE_FILE="docs/features/${FEATURE}.md"
|
|
|
200
675
|
- I want {action}
|
|
201
676
|
- So that {benefit}
|
|
202
677
|
|
|
678
|
+
**Domain Model:**
|
|
679
|
+
- Context: {Bounded Context name}
|
|
680
|
+
- Aggregate: {Root} owns [{entities}]
|
|
681
|
+
- Events raised: [{EventName}] → {consumer context}
|
|
682
|
+
- Cross-context: {if touches another context, otherwise omit}
|
|
683
|
+
|
|
684
|
+
**Agent profile:**
|
|
685
|
+
- 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 校准)}
|
|
686
|
+
- risk_zone: {low / medium / high — 改文档 low,改用户可见行为 medium,改 loop infra 或安全/隔离基建 high。**不参与 loop 路由**(路由只看 est_min);仅供 roll-build / roll-fix 的 pre-flight 自评(US-AGENT-007)做能力匹配参考}
|
|
687
|
+
- chain_depth: 0 {若是自降级产出的子 story 则 +1,累计 ≥2 时第 3 次拒拆}
|
|
688
|
+
|
|
203
689
|
**AC:**
|
|
204
690
|
- [ ] {measurable criteria 1}
|
|
205
691
|
- [ ] {measurable criteria 2}
|
|
@@ -219,45 +705,60 @@ FEATURE_FILE="docs/features/${FEATURE}.md"
|
|
|
219
705
|
- Integration test: `tests/integration/{flow}.test.ts`
|
|
220
706
|
```
|
|
221
707
|
|
|
222
|
-
|
|
708
|
+
> **强制规则 — 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 不强制回填。
|
|
709
|
+
>
|
|
710
|
+
> **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).
|
|
223
711
|
|
|
224
|
-
###
|
|
712
|
+
### Closing Doc-Refresh Story Template — Phase N.M 收尾文档
|
|
225
713
|
|
|
226
|
-
|
|
227
|
-
$roll-design "login feature" → Create US-AUTH-001
|
|
228
|
-
User: "Execute US-AUTH-001"
|
|
229
|
-
↓
|
|
230
|
-
$roll-story US-AUTH-001 → TCR → CI/CD → Deploy
|
|
231
|
-
```
|
|
714
|
+
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.
|
|
232
715
|
|
|
233
|
-
|
|
716
|
+
```markdown
|
|
717
|
+
<a id="us-{domain}-{n}"></a>
|
|
718
|
+
## US-{DOMAIN}-{N} Phase {N.M} 用户文档刷新(中英双轨) 📋
|
|
234
719
|
|
|
235
|
-
|
|
236
|
-
$roll-debug discovers issue → Suggest creating FIX
|
|
237
|
-
$roll-design --fix "fix login API 404" → Create FIX-AUTH-001
|
|
238
|
-
$roll-fix FIX-AUTH-001 → Quick fix
|
|
239
|
-
```
|
|
720
|
+
**Created**: {YYYY-MM-DD}
|
|
240
721
|
|
|
241
|
-
|
|
722
|
+
- As a roll user reading the docs
|
|
723
|
+
- I want the user-facing documentation to match the new behavior shipped in this Phase
|
|
724
|
+
- So that the next person reading the guide / README / `--help` does not hit a stale version
|
|
242
725
|
|
|
243
|
-
|
|
726
|
+
**AC:**
|
|
727
|
+
- [ ] Update each affected doc file listed below; **English line and Chinese line on separate lines**, never inline
|
|
728
|
+
- [ ] `roll <cmd> --help` output reflects new flags / commands / status semantics (paste verified output)
|
|
729
|
+
- [ ] README index links to any new guide pages
|
|
730
|
+
- [ ] Error-message changes are mirrored in troubleshooting / FAQ sections
|
|
731
|
+
- [ ] Verified: no doc page still describes the pre-Phase behavior
|
|
244
732
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
733
|
+
**Files:**
|
|
734
|
+
- `guide/en/{topic}.md`
|
|
735
|
+
- `guide/zh/{topic}.md`
|
|
736
|
+
- `README.md` (index entry)
|
|
737
|
+
- `{any other user-facing doc touched by the Phase}`
|
|
248
738
|
|
|
249
|
-
|
|
739
|
+
**Dependencies:**
|
|
740
|
+
- Depends on: {every preceding user-facing US in this batch}
|
|
741
|
+
- Worked example: 参考 `features/authoring/slide-deck-generator.md` 的 US-DECK-015 ——
|
|
742
|
+
roll slides Phase 1.5 把 6 张 user-visible US 末尾合并成一张 doc-refresh story 的范例。
|
|
743
|
+
```
|
|
250
744
|
|
|
251
745
|
---
|
|
252
746
|
|
|
253
747
|
## INVEST Principles
|
|
254
748
|
|
|
749
|
+
> **颗粒度校准(按 AI cycle 量纲)**:Roll 的 Story 不是"几天的活",而是
|
|
750
|
+
> **一个 AI cycle 闭环(目标 5–10 min)**。下面的 S 和 I 按这个量纲重定义,
|
|
751
|
+
> 别套用传统敏捷"一个 sprint 装几个 story"的尺度。
|
|
752
|
+
|
|
255
753
|
Each story must be:
|
|
256
|
-
- **Independent**:
|
|
754
|
+
- **Independent**: 不强求完全独立。有先后依赖就用 `depends-on:` 串成链(配合
|
|
755
|
+
`chain_depth ≤ 2` 防无限套娃)。真正要避免的是"改同一文件的并行冲突",
|
|
756
|
+
而不是"禁止依赖"——为追求独立硬把一个 cycle 的活摊成几个反而更糟。
|
|
257
757
|
- **Negotiable**: Scope is negotiable
|
|
258
758
|
- **Valuable**: Provides value to the user
|
|
259
759
|
- **Estimable**: Effort can be estimated
|
|
260
|
-
- **Small**:
|
|
760
|
+
- **Small**: **一个 Story ≈ 一个 AI cycle 闭环(目标 5–10 min)**。S 是 cycle 量纲,
|
|
761
|
+
装不进一个 cycle 就拆;`est_min > ~15` 是"再拆"信号——除非原子不可分。
|
|
261
762
|
- **Testable**: Can be tested and verified
|
|
262
763
|
|
|
263
764
|
## Backlog Structure
|
|
@@ -269,8 +770,140 @@ Each story must be:
|
|
|
269
770
|
### Feature Name
|
|
270
771
|
| Story | Description | Status |
|
|
271
772
|
|-------|-------------|--------|
|
|
272
|
-
| [US-XXX](
|
|
273
|
-
| [US-YYY](
|
|
773
|
+
| [US-XXX](.roll/features/<feature>.md#us-xxx) | One-line description | 📋 Todo |
|
|
774
|
+
| [US-YYY](.roll/features/<feature>.md#us-yyy) | One-line description | ✅ Done |
|
|
274
775
|
```
|
|
275
776
|
|
|
276
|
-
**Note**:
|
|
777
|
+
**Note**: .roll/backlog.md only contains index rows; full AC / Files / Dependencies go in `.roll/features/<feature>.md`.
|
|
778
|
+
|
|
779
|
+
---
|
|
780
|
+
|
|
781
|
+
## Self-score (US-SKILL-010 / 013)
|
|
782
|
+
|
|
783
|
+
After Step 5 (Write to BACKLOG) completes — i.e. once the new US rows are
|
|
784
|
+
landed and the user has either confirmed or chosen `No` (story still
|
|
785
|
+
queued) — write a single self-score note covering the design session:
|
|
786
|
+
|
|
787
|
+
```bash
|
|
788
|
+
bash -c 'source "$(command -v roll)"; \
|
|
789
|
+
_skill_write_self_score roll-design US-XXX-NNN <score 1..10> <good|ok|regression> "<rationale>"'
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
Use the **first** US-id of the batch as the story handle (or the
|
|
793
|
+
representative story when splitting). The note lands under
|
|
794
|
+
`.roll/notes/<date>-roll-design-<id>-<epoch>.md` so US-SKILL-014 can
|
|
795
|
+
read trend data.
|
|
796
|
+
|
|
797
|
+
Score guidance for design quality (integer 1..10):
|
|
798
|
+
- **9..10** — clean split: every US is INVEST-compliant, profile
|
|
799
|
+
(est_min / risk_zone / chain_depth) filled, doc-refresh closer wired
|
|
800
|
+
when user-visible behaviour changed, peer-review unnecessary or
|
|
801
|
+
reached AGREE quickly.
|
|
802
|
+
- **6..8** — split shipped but with caveats: one US borderline on
|
|
803
|
+
INVEST (e.g. shared file conflict), or Discuss had ESCALATE before
|
|
804
|
+
settling, or profile was partial.
|
|
805
|
+
- **1..5** — split shipped but rough: missing doc-refresh closer,
|
|
806
|
+
profile fields skipped, USer story too coarse for AI cycle; flag a
|
|
807
|
+
follow-up `roll-design` pass.
|
|
808
|
+
|
|
809
|
+
Verdict values:
|
|
810
|
+
- `good` — design + split are clean.
|
|
811
|
+
- `ok` — design is acceptable with one or two trade-offs noted.
|
|
812
|
+
- `regression` — the split visibly broke something earlier (rare; e.g.
|
|
813
|
+
invalidated a previously-stable depends-on chain).
|
|
814
|
+
|
|
815
|
+
---
|
|
816
|
+
|
|
817
|
+
## Integration
|
|
818
|
+
|
|
819
|
+
### With roll-build
|
|
820
|
+
|
|
821
|
+
```
|
|
822
|
+
$roll-design "login feature" → Create US-AUTH-001
|
|
823
|
+
User: "Execute US-AUTH-001"
|
|
824
|
+
↓
|
|
825
|
+
$roll-build US-AUTH-001 → TCR → CI/CD → Deploy
|
|
826
|
+
```
|
|
827
|
+
|
|
828
|
+
### With roll-fix
|
|
829
|
+
|
|
830
|
+
```
|
|
831
|
+
$roll-debug discovers issue → Suggest creating FIX
|
|
832
|
+
$roll-design "fix login API 404" → Create FIX-AUTH-001 ← auto-detected as Bug Fix
|
|
833
|
+
$roll-fix FIX-AUTH-001 → Quick fix
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
### With roll-peer
|
|
837
|
+
|
|
838
|
+
Two checkpoints, both with 10s opt-out:
|
|
839
|
+
|
|
840
|
+
```
|
|
841
|
+
1. After Discuss — Direction Review
|
|
842
|
+
Approach confirmed → [peer, tag=architecture] → challenge the direction before DDD
|
|
843
|
+
Trigger: complexity=large OR requirement touches multiple Bounded Contexts
|
|
844
|
+
|
|
845
|
+
2. After Solution Design — Plan Review
|
|
846
|
+
Plan written → [peer, tag=architecture] → full plan review before story split
|
|
847
|
+
Trigger: complexity=large (greenfield always qualifies)
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
On AGREE or user skip → continue to the next step normally.
|
|
851
|
+
On REFINE/OBJECT → incorporate feedback, regenerate the relevant output, re-trigger peer.
|
|
852
|
+
On ESCALATE → present both proposals to user for final call.
|
|
853
|
+
|
|
854
|
+
---
|
|
855
|
+
|
|
856
|
+
## Project Context Rule
|
|
857
|
+
|
|
858
|
+
Before creating any file or directory:
|
|
859
|
+
|
|
860
|
+
1. **Read existing project structure** — check for `package.json`, `go.mod`, `Cargo.toml`, `pyproject.toml`, existing `src/`, `api/`, `cmd/` directories
|
|
861
|
+
2. **Check existing domain model** — if `.roll/domain/` exists, read `context-map.md` before adding new Bounded Contexts
|
|
862
|
+
3. **Infer conventions from evidence** — don't assume a project type; observe what already exists
|
|
863
|
+
4. **Follow what already exists** — introduce new patterns only when the current structure has no precedent
|
|
864
|
+
|
|
865
|
+
> `roll init` no longer asks for project type. Skills are responsible for reading context and acting accordingly.
|
|
866
|
+
|
|
867
|
+
---
|
|
868
|
+
|
|
869
|
+
<a id="doc-update-discipline"></a>
|
|
870
|
+
## Doc Update Discipline
|
|
871
|
+
|
|
872
|
+
When `$roll-design` splits a feature into stories, **the closing tasking step is
|
|
873
|
+
always a doc-refresh story whenever any preceding US changes user-visible
|
|
874
|
+
behavior**. This is mandatory, not optional — without it, code ships and the
|
|
875
|
+
docs silently drift to the previous version, and only the next user to read the
|
|
876
|
+
guide notices.
|
|
877
|
+
|
|
878
|
+
**When a separate doc-refresh story IS required (任一为真即触发):**
|
|
879
|
+
- 任一 US 改了 **CLI 输出**(新增/修改输出行、表头、颜色、emoji 语义)
|
|
880
|
+
- 任一 US 改了 **命令参数**(新增/重命名 flag、改变 default、收紧/放宽校验)
|
|
881
|
+
- 任一 US 改了 **状态语义**(backlog 状态、cycle 状态机、退出码含义)
|
|
882
|
+
- 任一 US 改了 **错误提示** / 用户可读日志文案
|
|
883
|
+
- 任一 US 新增/删除/重命名一个用户能直接调用的命令
|
|
884
|
+
|
|
885
|
+
**When it can be skipped (纯内部变更,用户感知不到):**
|
|
886
|
+
- 纯内部重构(内部函数改名、模块边界调整、测试沙箱化)
|
|
887
|
+
- CI / hooks / 工具链修复
|
|
888
|
+
- 安全 / 隔离基础设施(沙箱配置、权限矩阵内部调整)
|
|
889
|
+
- 测试基础设施 / fixture 数据更新
|
|
890
|
+
|
|
891
|
+
**Checklist for the doc-refresh story (中英双语必需):**
|
|
892
|
+
- [ ] `guide/en/<topic>.md` — English guide updated
|
|
893
|
+
- [ ] `guide/zh/<topic>.md` — Chinese guide updated
|
|
894
|
+
- [ ] `README.md` index links to any new doc page
|
|
895
|
+
- [ ] `--help` output snapshot matches new flags / commands / status semantics
|
|
896
|
+
- [ ] Error-message strings reflected in troubleshooting / FAQ
|
|
897
|
+
- [ ] **Bilingual rule**: English and Chinese on **separate lines**, never inline
|
|
898
|
+
(遵循 project CLAUDE.md 中 Bilingual Output Convention)
|
|
899
|
+
|
|
900
|
+
**How to wire the doc-refresh story:**
|
|
901
|
+
1. Place it **last** in the batch
|
|
902
|
+
2. `depends-on:` lists **every** preceding user-facing US in the batch
|
|
903
|
+
3. Title 用 "Phase N.M 用户文档刷新(中英双轨)" 模板(见 [Story Format](#story-format) 中的模板)
|
|
904
|
+
4. Cite a worked example in its Dependencies note — current best reference is
|
|
905
|
+
`features/authoring/slide-deck-generator.md` US-DECK-015 (roll slides Phase 1.5)
|
|
906
|
+
|
|
907
|
+
> Self-validation: this very skill was strengthened via US-SKILL-009; the
|
|
908
|
+
> roll slides Phase 1.5 tasking (US-DECK-015) is the canonical worked example
|
|
909
|
+
> of the discipline in action.
|