@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.
Files changed (181) hide show
  1. package/CHANGELOG.md +717 -0
  2. package/LICENSE +21 -0
  3. package/README.md +65 -165
  4. package/bin/dream-test-quality-scan +110 -0
  5. package/bin/roll +14897 -815
  6. package/conventions/config.yaml +17 -1
  7. package/conventions/global/AGENTS.md +146 -100
  8. package/conventions/global/CLAUDE.md +1 -21
  9. package/conventions/global/GEMINI.md +8 -22
  10. package/conventions/global/project_rules.md +9 -0
  11. package/conventions/templates/backend-service/AGENTS.md +30 -81
  12. package/conventions/templates/backend-service/GEMINI.md +3 -3
  13. package/conventions/templates/backend-service/project_rules.md +16 -0
  14. package/conventions/templates/cli/AGENTS.md +31 -58
  15. package/conventions/templates/cli/CLAUDE.md +3 -5
  16. package/conventions/templates/cli/GEMINI.md +3 -3
  17. package/conventions/templates/cli/project_rules.md +16 -0
  18. package/conventions/templates/frontend-only/AGENTS.md +29 -64
  19. package/conventions/templates/frontend-only/GEMINI.md +3 -3
  20. package/conventions/templates/frontend-only/project_rules.md +14 -0
  21. package/conventions/templates/fullstack/AGENTS.md +31 -79
  22. package/conventions/templates/fullstack/CLAUDE.md +1 -1
  23. package/conventions/templates/fullstack/GEMINI.md +3 -3
  24. package/conventions/templates/fullstack/project_rules.md +15 -0
  25. package/lib/README.md +42 -0
  26. package/lib/__pycache__/github_sync.cpython-314.pyc +0 -0
  27. package/lib/__pycache__/loop-fmt.cpython-314.pyc +0 -0
  28. package/lib/__pycache__/loop_result_eval.cpython-314.pyc +0 -0
  29. package/lib/__pycache__/loop_unstick.cpython-314.pyc +0 -0
  30. package/lib/__pycache__/model_prices.cpython-314.pyc +0 -0
  31. package/lib/__pycache__/prices_fetcher.cpython-314.pyc +0 -0
  32. package/lib/__pycache__/roll-home.cpython-314.pyc +0 -0
  33. package/lib/__pycache__/roll-loop-status.cpython-314.pyc +0 -0
  34. package/lib/__pycache__/roll_git.cpython-314.pyc +0 -0
  35. package/lib/__pycache__/roll_render.cpython-314.pyc +0 -0
  36. package/lib/__pycache__/slides-render.cpython-314.pyc +0 -0
  37. package/lib/agent_usage/README.md +49 -0
  38. package/lib/agent_usage/__init__.py +108 -0
  39. package/lib/agent_usage/__pycache__/__init__.cpython-314.pyc +0 -0
  40. package/lib/agent_usage/__pycache__/gemini.cpython-314.pyc +0 -0
  41. package/lib/agent_usage/__pycache__/kimi.cpython-314.pyc +0 -0
  42. package/lib/agent_usage/__pycache__/openai.cpython-314.pyc +0 -0
  43. package/lib/agent_usage/__pycache__/pi.cpython-314.pyc +0 -0
  44. package/lib/agent_usage/__pycache__/pi_emit.cpython-314.pyc +0 -0
  45. package/lib/agent_usage/__pycache__/qwen.cpython-314.pyc +0 -0
  46. package/lib/agent_usage/gemini.py +127 -0
  47. package/lib/agent_usage/kimi.py +278 -0
  48. package/lib/agent_usage/kimi_emit.py +123 -0
  49. package/lib/agent_usage/openai.py +126 -0
  50. package/lib/agent_usage/pi.py +200 -0
  51. package/lib/agent_usage/pi_emit.py +135 -0
  52. package/lib/agent_usage/qwen.py +128 -0
  53. package/lib/backfill-pi-usage.py +243 -0
  54. package/lib/changelog_audit.py +155 -0
  55. package/lib/changelog_generate.py +263 -0
  56. package/lib/context_feed_budget.sh +194 -0
  57. package/lib/github_sync.py +876 -0
  58. package/lib/i18n/README.md +54 -0
  59. package/lib/i18n/agent.sh +75 -0
  60. package/lib/i18n/alert.sh +20 -0
  61. package/lib/i18n/backlog.sh +96 -0
  62. package/lib/i18n/brief.sh +5 -0
  63. package/lib/i18n/changelog.sh +5 -0
  64. package/lib/i18n/ci.sh +15 -0
  65. package/lib/i18n/debug.sh +0 -0
  66. package/lib/i18n/doctor.sh +44 -0
  67. package/lib/i18n/dream.sh +0 -0
  68. package/lib/i18n/init.sh +91 -0
  69. package/lib/i18n/lang.sh +10 -0
  70. package/lib/i18n/loop.sh +140 -0
  71. package/lib/i18n/migrate.sh +74 -0
  72. package/lib/i18n/offboard.sh +31 -0
  73. package/lib/i18n/onboard.sh +0 -0
  74. package/lib/i18n/peer.sh +41 -0
  75. package/lib/i18n/peer_help.sh +25 -0
  76. package/lib/i18n/peer_reset.sh +7 -0
  77. package/lib/i18n/peer_status.sh +5 -0
  78. package/lib/i18n/prices.sh +3 -0
  79. package/lib/i18n/prices_refresh.sh +17 -0
  80. package/lib/i18n/prices_show.sh +7 -0
  81. package/lib/i18n/propose.sh +0 -0
  82. package/lib/i18n/release.sh +0 -0
  83. package/lib/i18n/research.sh +0 -0
  84. package/lib/i18n/review_pr.sh +0 -0
  85. package/lib/i18n/sentinel.sh +0 -0
  86. package/lib/i18n/setup.sh +3 -0
  87. package/lib/i18n/shared.sh +157 -0
  88. package/lib/i18n/skills/roll-brief.sh +47 -0
  89. package/lib/i18n/skills/roll-build.sh +97 -0
  90. package/lib/i18n/skills/roll-design.sh +18 -0
  91. package/lib/i18n/skills/roll-fix.sh +53 -0
  92. package/lib/i18n/skills/roll-loop.sh +28 -0
  93. package/lib/i18n/skills/roll-onboard.sh +33 -0
  94. package/lib/i18n/skills_catalog.sh +30 -0
  95. package/lib/i18n/slides.sh +3 -0
  96. package/lib/i18n/slides_build.sh +38 -0
  97. package/lib/i18n/slides_delete.sh +19 -0
  98. package/lib/i18n/slides_list.sh +14 -0
  99. package/lib/i18n/slides_logs.sh +12 -0
  100. package/lib/i18n/slides_new.sh +15 -0
  101. package/lib/i18n/slides_preview.sh +14 -0
  102. package/lib/i18n/slides_templates.sh +7 -0
  103. package/lib/i18n/status.sh +21 -0
  104. package/lib/i18n/update.sh +24 -0
  105. package/lib/i18n.sh +211 -0
  106. package/lib/loop-exit-summary.py +393 -0
  107. package/lib/loop-fmt.py +589 -0
  108. package/lib/loop_pick_agent.py +316 -0
  109. package/lib/loop_result_eval.py +469 -0
  110. package/lib/loop_unstick.py +180 -0
  111. package/lib/model_prices.py +186 -0
  112. package/lib/prices/README.md +35 -0
  113. package/lib/prices/snapshot-2026-05-22.json +22 -0
  114. package/lib/prices/snapshot-2026-05-23-deepseek.json +15 -0
  115. package/lib/prices/snapshot-2026-05-23-kimi.json +14 -0
  116. package/lib/prices_fetcher.py +285 -0
  117. package/lib/roll-backlog.py +225 -0
  118. package/lib/roll-brief.py +286 -0
  119. package/lib/roll-help.py +158 -0
  120. package/lib/roll-home.py +556 -0
  121. package/lib/roll-init.py +156 -0
  122. package/lib/roll-loop-status.py +1683 -0
  123. package/lib/roll-loop-story.py +191 -0
  124. package/lib/roll-onboard-render.py +378 -0
  125. package/lib/roll-peer.py +252 -0
  126. package/lib/roll-plan-validate.py +386 -0
  127. package/lib/roll-setup.py +102 -0
  128. package/lib/roll-status.py +367 -0
  129. package/lib/roll_git.py +41 -0
  130. package/lib/roll_render.py +414 -0
  131. package/lib/slides/components/README.md +123 -0
  132. package/lib/slides/components/cards-2.html +9 -0
  133. package/lib/slides/components/cards-3.html +9 -0
  134. package/lib/slides/components/cards-4.html +9 -0
  135. package/lib/slides/components/compare.html +22 -0
  136. package/lib/slides/components/highlight.html +9 -0
  137. package/lib/slides/components/pipeline.html +12 -0
  138. package/lib/slides/components/plain.html +7 -0
  139. package/lib/slides/components/quote.html +4 -0
  140. package/lib/slides/components/timeline.html +9 -0
  141. package/lib/slides/templates/introduction-v3.html +571 -0
  142. package/lib/slides/templates/pitch.html +0 -0
  143. package/lib/slides-render.py +778 -0
  144. package/lib/slides-validate.py +357 -0
  145. package/lib/test_quality_gate.py +143 -0
  146. package/package.json +8 -7
  147. package/skills/roll-.changelog/SKILL.md +406 -33
  148. package/skills/roll-.clarify/SKILL.md +5 -2
  149. package/skills/roll-.dream/SKILL.md +374 -0
  150. package/skills/roll-.echo/SKILL.md +5 -2
  151. package/skills/roll-.qa/SKILL.md +57 -3
  152. package/skills/roll-.review/SKILL.md +42 -3
  153. package/skills/roll-brief/SKILL.md +209 -0
  154. package/skills/roll-build/SKILL.md +308 -63
  155. package/skills/roll-debug/SKILL.md +341 -162
  156. package/skills/roll-debug/injectable-bb.js +263 -0
  157. package/skills/roll-deck/SKILL.md +296 -0
  158. package/skills/roll-design/ENGINEERING_CHECKLIST.md +1 -1
  159. package/skills/roll-design/SKILL.md +727 -94
  160. package/skills/roll-doc/SKILL.md +595 -0
  161. package/skills/roll-doctor/SKILL.md +192 -0
  162. package/skills/roll-fix/SKILL.md +149 -32
  163. package/skills/{roll-jot → roll-idea}/SKILL.md +18 -10
  164. package/skills/roll-loop/SKILL.md +578 -0
  165. package/skills/roll-notes/SKILL.md +103 -0
  166. package/skills/roll-onboard/SKILL.md +234 -0
  167. package/skills/roll-peer/SKILL.md +336 -0
  168. package/skills/roll-propose/SKILL.md +157 -0
  169. package/skills/roll-review-pr/SKILL.md +58 -0
  170. package/skills/roll-sentinel/SKILL.md +11 -2
  171. package/skills/roll-spar/SKILL.md +8 -6
  172. package/template/.github/workflows/ci.yml +5 -2
  173. package/template/AGENTS.md +20 -74
  174. package/skills/roll-research/SKILL.md +0 -307
  175. package/skills/roll-research/references/schema.json +0 -162
  176. package/skills/roll-research/scripts/md_to_pdf.py +0 -289
  177. package/tools/roll-fetch/SKILL.md +0 -182
  178. package/tools/roll-fetch/package.json +0 -15
  179. package/tools/roll-fetch/smart-web-fetch.js +0 -558
  180. package/tools/roll-probe/SKILL.md +0 -84
  181. /package/template/{BACKLOG.md → .roll/backlog.md} +0 -0
@@ -1,79 +1,452 @@
1
1
  ---
2
2
  hidden: true
3
3
  name: roll-.changelog
4
- description: After build completion, extracts completed Stories from BACKLOG.md to generate CHANGELOG.md. Auto-triggered after successful deploy, keeping the external changelog in sync with the internal backlog.
4
+ license: MIT
5
+ allowed-tools: "Read, Edit, Write, Bash(git:*)"
6
+ description: After build completion, extracts completed Stories from .roll/backlog.md to generate CHANGELOG.md. Auto-triggered after successful deploy, keeping the external changelog in sync with the internal backlog.
5
7
  ---
6
8
 
7
9
  # WK Generate Changelog
8
10
 
9
- After successful Build & Deploy, extracts completed Stories from BACKLOG.md to generate a user-friendly `CHANGELOG.md`.
11
+ After successful Build & Deploy, extracts completed Stories from .roll/backlog.md to generate a user-friendly `CHANGELOG.md`.
10
12
 
11
13
  ## When Triggered
12
14
 
13
- - **Auto-triggered**: After successful deploy of `$roll-story` or `$roll-fix`
14
- - **Manual trigger**: When user requests "update changelog" or "generate release notes"
15
+ - **Auto-triggered**: After successful deploy of `$roll-build` or `$roll-fix`
16
+ - **Manual trigger**: When user requests "update changelog" / "更新 changelog"
17
+
18
+ ## When Not to Use
19
+
20
+ - Generating commit messages or PR descriptions — this skill only runs post-deploy
21
+ - Recording dev diary / moments (use `$roll-notes`)
22
+ - Bumping package version (use the project's release script — Roll's lives in `roll-meta/ops/release.sh`)
15
23
 
16
24
  ## Workflow
17
25
 
18
- ### 1. Read BACKLOG.md
26
+ ### 1. Check CHANGELOG.md
27
+
28
+ ```
29
+ CHANGELOG.md exists?
30
+ ├── Yes → Append mode (add current deploy's changes)
31
+ └── No → Create mode (backfill all historical completed Stories)
32
+ ```
33
+
34
+ ### 2. Read .roll/backlog.md
35
+
36
+ ```
37
+ Append mode:
38
+ Extract only the Story/Fix just deployed in this session.
39
+
40
+ Create mode:
41
+ Extract ALL Stories and Fixes with status ✅ Done.
42
+ Read each Story's .roll/features/<feature>.md for Completed date.
43
+ Group entries by completion date, reverse chronological order.
44
+ ```
45
+
46
+ ### 3. Filter for External Content
47
+
48
+ CHANGELOG 是给**使用者**看的,不是给维护者看的。一句话讲清"用户能做什么 / 不再被什么坑",能不写就不写。
49
+
50
+ **BACKLOG 描述写好了,CHANGELOG 就是复制 + 过滤,不是重写。**
51
+ 如果 BACKLOG 描述已经是人话、一句话、说用户价值,直接用它(去掉 `depends-on:` / `manual-only:` 等功能性标签)。
52
+ 只有 BACKLOG 描述包含实现细节或技术黑话时,才需要改写。
53
+
54
+ **FIX 条目的 filter 规则**:BACKLOG 的 FIX 描述通常是 `<用户症状> — <修复手段>` 结构。
55
+ CHANGELOG 只取破折号前的用户症状,丢弃破折号后的修复手段。
56
+ 例:`roll update 后 loop 状态误报 off — reload 改用 bootout+bootstrap` → CHANGELOG 只写 `roll update 后 loop 状态不再误报 off`。
57
+
58
+ **完全跳过(不写入 CHANGELOG):**
59
+ - 测试基建(teardown 清理、test isolation、bats helper、CI 时序)
60
+ - prompt / SKILL.md 内部契约(schema 锁定、enum 强制、contract test)
61
+ - 内部重构(提取函数、变量改名、目录调整)
62
+ - 只有开发者会遇到的 bug(发版脚本自身逻辑、TCR 节奏调整)
63
+ - 任何"用户体验不变"的改动
64
+
65
+ 判断准则:**如果用户读了这条记录,他不会改变使用方式,就别写。**
66
+
67
+ **保留:**
68
+ - 用户能直接调用的新功能 / 新命令
69
+ - 用户实际遇到过的 bug 修复
70
+ - 看得见的体验变化(布局、文案、速度、可见性)
71
+ - 影响安装、升级、配置的改动
72
+
73
+ **写法约束(BACKLOG 描述不符合时才介入改写):**
19
74
 
75
+ 1. **一行**。超了就是太啰嗦。
76
+ 2. **不写实现细节**:禁止文件路径、函数名、字段列表、命令参数、配置键名。
77
+ 3. **不写数字细节**:"3 个服务"、"60+ ghost" 这种内部状态不写。
78
+ 4. **说人话**:避免 "幂等"、"trap"、"epoch" 等技术黑话;说"做两次效果一样"、"异常退出也会清理"、"启动时间"。
79
+ 5. **句式**:`功能名 — 用户能做什么 / 解决了什么麻烦`。
80
+
81
+ **语言:中文。**
82
+
83
+ 具体对比(都是真实的 roll 改动):
84
+
85
+ ❌ 全是实现细节:
86
+ ```
87
+ - **Added**: `roll loop runs` 每次 loop 运行的快速可见性 — 单次 loop 结束追加一行 JSON 到 `~/.shared/roll/loop/runs.jsonl`(含 ts/project/run_id/status/built/skipped/alerts/tcr_count/duration_sec),新命令 `roll loop runs [N] [--all]` 倒序显示最近 N 次(默认 10)。
88
+ ```
89
+
90
+ ✅ 讲价值:
91
+ ```
92
+ - **Added**: `roll loop runs` — 随时查看 loop 最近几次都跑了什么
93
+ ```
94
+
95
+ ❌ 内部信息扎堆:
20
96
  ```
21
- Read BACKLOG.md from the project root directory.
22
- Extract Stories with status ✅ Completed / Done.
97
+ - **Fixed**: 集成测试 launchd ghost 泄漏 — `integration_teardown` 在删除 TEST_TMP 之前,先 `launchctl bootout` 该沙箱里被 `roll loop on` 注册到 user gui domain 的所有 `com.roll.*` 服务。
98
+ ```
99
+
100
+ ✅ **直接跳过**:测试基建修复,用户感知不到。
101
+
102
+ ❌ 参数列表+黑话:
103
+ ```
104
+ - **Added**: Loop 并发安全 — runner script 启动时写入 per-project LOCK 文件并检测重入;活跃 PID 已存在则跳过本次,残留死 LOCK 自动清理;正常/异常退出均通过 trap 清掉 LOCK。
105
+ ```
106
+
107
+ ✅ 用户视角:
108
+ ```
109
+ - **Fixed**: 多个 loop 实例不会再互相打架(重复触发自动跳过)
110
+ ```
111
+
112
+ ❌ 说机制不说现象(Fix 类最常犯):
113
+ ```
114
+ - **Fixed**: `roll loop runs` 过滤条件从完整路径改为 slug,历史记录不再因路径不匹配而消失
115
+ - **Fixed**: `roll-loop` skill 写入 `runs.jsonl` 时 project slug 计算方式明确,避免写成 bare basename
116
+ ```
117
+
118
+ ✅ 直接说用户看到了什么:
119
+ ```
120
+ - **Fixed**: `roll loop runs` 不再报"当前项目尚无运行记录",历史记录正常显示
121
+ ```
122
+
123
+ Fix 类句式参考:`<命令/功能> 不再 <之前的坏现象>`,或 `<命令/功能> 现在 <正常表现>`。内部有几个 bug 导致这一个现象,合并成一条。
124
+
125
+ **归因标签**:每条 bullet 末尾加来源标签——`[loop]`(对应 `US-AUTO-*` / `FIX-*` / `US-CL-*` 等由 Loop 自动执行的故事)、`[dream]`(对应 `REFACTOR-*`,Dream 夜间扫描推入 Backlog)、无标签(人工提交或来源不明)。同一来源的多条不必重复标。
126
+
127
+ ### 4. Section Header — Always `## Unreleased`
128
+
129
+ **⚠️ do NOT guess version numbers.** Only the release script (maintainer-private
130
+ in `roll-meta/ops/release.sh`) assigns concrete versions, and it only does so at
131
+ the moment of a real release. Until then, every new bullet goes under
132
+ `## Unreleased` at the top of CHANGELOG.md.
133
+
134
+ ```
135
+ ## Unreleased
136
+
137
+ ### 新功能
138
+ - ...new entries here...
139
+
140
+ ### 稳定性
141
+ - ...
142
+ ```
143
+
144
+ 新条目按**感知分组**(`### 标题`)归类,不写 `**Added**` / `**Fixed**` 前缀——
145
+ 分组规则见 **Section 7**(版本段落 = GitHub Release 正文,分组结构是 changelog 自己的格式)。
146
+
147
+ When the release script runs, it renames `## Unreleased` to `## v{N}` (where N
148
+ is computed from git tags) — that's the single moment a version label gets
149
+ assigned.
150
+
151
+ Do NOT read `package.json` version, do NOT call `git describe`, do NOT invent
152
+ version numbers like `v2026.511.8`. Just write to `## Unreleased`.
153
+
154
+ ### 5.3 Style Anchors — In-Context Few-Shot
155
+
156
+ Before drafting bullets, pull the most recent 3 published versions' bullets as
157
+ in-context examples so the agent doesn't write from a blank slate (the blank
158
+ slate is where the technical-jargon habit comes from — the agent is fresh
159
+ from writing function names and just copies them over).
160
+
161
+ ```bash
162
+ _changelog_style_anchors CHANGELOG.md
163
+ ```
164
+
165
+ Output is the concatenated bullet lines from the last 3 `## v...` sections,
166
+ capped at 1500 characters. Use them as a style reference when drafting — pay
167
+ attention to length, voice ("不再被…坑" / "现在 …"), and absence of internal
168
+ names.
169
+
170
+ ### 5.4 Mechanical Lint — Hard Gate
171
+
172
+ After drafting bullets, run each through the mechanical linter. Any non-empty
173
+ output means the bullet violates at least one blacklist rule and must be
174
+ rewritten.
175
+
176
+ ```bash
177
+ for bullet in "${draft_bullets[@]}"; do
178
+ violations=$(_changelog_lint_bullet "$bullet")
179
+ [ -n "$violations" ] && needs_rewrite+=("$bullet :: $violations")
180
+ done
181
+ ```
182
+
183
+ Violation tags emitted by `_changelog_lint_bullet`:
184
+
185
+ | Tag | Trigger | Why it's noise to users |
186
+ |---|---|---|
187
+ | `backtick-identifier` | `…` contains `_` or `()` | Internal symbol names mean nothing to users |
188
+ | `file-suffix` | `.md/.sh/.yml/.ts/.bats` outside backticks | File paths are maintainer concern |
189
+ | `internal-word` | Phase N / Step N / Helper / Schema / Fixture / Refactor | Workflow/design vocabulary, not user-facing |
190
+ | `over-length` | > 50 visible chars | Too long = probably explaining implementation |
191
+ | `path-fragment` | `docs/` / `bin/` / `tests/` / `scripts/` outside backticks | Source-tree layout is maintainer concern |
192
+
193
+ **Rewrite loop (max 2 rounds)**:
194
+ 1. Show the agent the violation list + original bullet → request rewrite
195
+ 2. Re-lint the rewrite
196
+ 3. If still violating after 2 rewrites → **keep the bullet but prefix `⚠️ `** so
197
+ the human reviewer can spot it, AND append a line to
198
+ `~/.shared/roll/loop/ALERT.md` describing what couldn't be fixed.
199
+ Never block the whole release on style — let the human take the wheel.
200
+
201
+ ### 5.5 Self-Audit — Stage Gate
202
+
203
+ The mechanical linter in Step 5.4 catches **blacklist** patterns; the audit
204
+ gate in this step is a **whitelist** of 5 boolean checks that the bullet must
205
+ satisfy before it can be staged. Stricter (30-char cap vs 50) and shape-aware
206
+ (requires the user-facing `—` or `不再`/`现在` sentence pattern).
207
+
208
+ ```bash
209
+ accepted=$(_changelog_audit_gate "$draft1" "$rewrite1" "$rewrite2")
210
+ # Exit 0: stdout = first clean candidate
211
+ # Exit 1: stdout = ⚠️-prefixed last candidate; ALERT was written
23
212
  ```
24
213
 
25
- ### 2. Filter for External Content
214
+ 5 boolean checks evaluated by `_changelog_audit_bullet`:
26
215
 
27
- **Remove internal information:**
28
- - Progress tables, completion percentages
29
- - "As a / I can / So that" format
30
- - Detailed AC checklists
31
- - Technical debt, internal file paths
32
- - Test case counts, architecture diagrams
216
+ | Tag | Trigger |
217
+ |---|---|
218
+ | `over-length-30` | visible chars > 30 (bypassed if bullet has a backticked user command) |
219
+ | `internal-id` | backtick content contains `_` or `()` |
220
+ | `path-or-suffix` | `.md/.sh/.yml/.ts/.bats` or `docs/bin/tests/scripts/` outside backticks |
221
+ | `phase-step` | `Phase N` or `Step N` |
222
+ | `bad-shape` | none of `—`, `不再`, `现在` present |
33
223
 
34
- **Keep user-facing value:**
35
- - New features (one-sentence description)
36
- - Bug fixes (user-visible impact)
37
- - UX improvements (layout, interaction enhancements)
38
- - Performance/reliability improvements
224
+ **3-round retry envelope**:
225
+ 1. Round 1 = original draft; if pass → stage immediately
226
+ 2. Round 2 = rewrite based on violations from round 1
227
+ 3. Round 3 = second rewrite if round 2 also failed
228
+ 4. All 3 failed → keep last candidate prefixed with `⚠️ `, append ALERT to
229
+ `~/.shared/roll/loop/ALERT.md`. **Never block the stage** — let the human
230
+ reviewer take the wheel. The loop must keep moving.
39
231
 
40
- ### 3. Version Number Format
232
+ **Audit log**: every round (pass or fail) appends one JSONL line to
233
+ `~/.shared/roll/loop/changelog-audit.jsonl`:
41
234
 
235
+ ```json
236
+ {"ts":"2026-05-13T13:50:00Z","verdict":"fail","round":1,"bullet":"...","reasons":["over-length-30","bad-shape"]}
42
237
  ```
43
- YYYY.MM.DD
44
- YYYY.MM.DD-1 (multiple releases on the same day)
45
- YYYY.MM.DD-2
238
+
239
+ Useful when reviewing whether the agent actually iterated or just rubber-stamped
240
+ its own first draft. Set `ROLL_CHANGELOG_AUDIT_LOG` to redirect (tests only).
241
+
242
+ ### 5. Generate CHANGELOG.md
243
+
244
+ 条目结构按 **Section 7** 的感知分组(`### 新功能` / `### 自动化流水线` / …),不用 `Added`/`Fixed`。
245
+
246
+ **Create mode** (first time, no CHANGELOG.md yet):
247
+ ```markdown
248
+ # Changelog
249
+
250
+ ## Unreleased
251
+
252
+ ### 新功能
253
+ - ...current deploy's entries...
254
+
255
+ ## 2026.05.10
256
+ - ...historical entries from completed Stories before today...
46
257
  ```
47
258
 
48
- ### 4. Generate CHANGELOG.md
259
+ **Append mode** (most common — CHANGELOG.md exists):
260
+
261
+ 1. Find `## Unreleased` heading at the top of CHANGELOG.md.
262
+ 2. If it exists → append each new bullet under the **right `### 感知分组`**(已有该组就追加,没有就按 Section 7 的分组顺序插入),do NOT create a new `##` section.
263
+ 3. If it doesn't exist → insert a fresh `## Unreleased` at the very top (right after the `# Changelog` title) with the grouped bullets.
49
264
 
50
265
  ```markdown
51
266
  # Changelog
52
267
 
53
- ## 2026.04.03
54
- - **Added**: <completed feature extracted from BACKLOG>
55
- - **Fixed**: <resolved bug>
56
- - **Improved**: <UX/performance optimization>
268
+ ## Unreleased
269
+
270
+ ### 自动化流水线
271
+ - ...just-deployed entry appended here... `[loop]`
57
272
 
58
- ## 2026.04.01
273
+ ### 稳定性
274
+ - ...another just-deployed entry...
275
+
276
+ ## v2026.05.07 ← previous releases left untouched
59
277
  - ...
60
278
  ```
61
279
 
62
- **Ordering**: Most recent version first (reverse chronological)
280
+ **Ordering**: Unreleased always at top. Below it, released versions in reverse chronological order.
281
+
282
+ ### 6. Stage Update
283
+
284
+ **Normal path (called from `$roll-build` or `$roll-fix`)**: stage only — the
285
+ caller's completion commit will pick up CHANGELOG.md.
286
+
287
+ ```bash
288
+ git add CHANGELOG.md
289
+ ```
63
290
 
64
- ### 5. Commit Update
291
+ **Standalone / manual path** (called outside a roll-build session): stage and commit.
65
292
 
66
293
  ```bash
67
294
  git add CHANGELOG.md
68
- git commit -m "docs: update changelog for release $(date +%Y.%m.%d)"
295
+ git commit -m "chore: sync changelog"
69
296
  git push
70
297
  ```
71
298
 
72
299
  ## Integration
73
300
 
74
- After successful deploy in `$roll-story` / `$roll-fix` / `$roll-fly`:
301
+ After successful deploy in `$roll-build` / `$roll-fix`:
75
302
 
76
303
  ```markdown
77
304
  **Post-Deploy:**
78
305
  - `$roll-.changelog` - Sync external changelog
79
306
  ```
307
+
308
+ ---
309
+
310
+ ## 7. 版本段落 = GitHub Release 正文(分组 + 措辞)
311
+
312
+ Roll 里**没有独立的 "release notes"**:release notes 就是 changelog——同一份内容、
313
+ 同一个文件(`CHANGELOG.md`)。凡是有人说 "release notes",在 Roll 里就是指 changelog。
314
+ 发版脚本(maintainer-private,`roll-meta/ops/release.sh`)把 `## Unreleased` 改名成
315
+ `## v{N}`,把该版段落**逐字提取**作为 GitHub Release 正文——不另写格式、不另存文件
316
+ (没有 `RELEASE_NOTES.md`)、不在发版关键路径上现场生成。
317
+
318
+ 所以**版本段落本身就要长成 Release 正文该有的样子**。下面的分组 / 合并 / 措辞 / hard
319
+ rules 不是"另一种格式",就是 changelog 段落的写法——把它写好 = 同时写好了 changelog
320
+ 和"发布说明"。
321
+
322
+ ### 7.1 分组(取代 Added/Fixed)
323
+
324
+ 每条 bullet 按**用户感知**归入下列分组,分组用 `###` 标题,每组最多 5 条,超出的合并:
325
+
326
+ | 分组(`### 标题`) | 归入条件 |
327
+ |---|---|
328
+ | 新功能 | 全新命令或用户可感知的新能力 |
329
+ | 自动化流水线 | PR 自动化、Auto-merge、CI 触发、分支管理 |
330
+ | 可见性 | Dashboard、弹窗、实时输出、状态显示 |
331
+ | 稳定性 | 崩溃修复、并发问题、状态误报 |
332
+ | 工程和测试 | CI 速度、测试并行、文档工作流 |
333
+
334
+ 分组顺序:**影响日常使用的放前面**,纯工程改进放后面。某组少于 2 条可并入相邻组,不强留空组。
335
+ **不写 `**Added**` / `**Fixed**` 前缀**——分组标题已经承担语义分类。
336
+
337
+ ### 7.2 合并相似条目(dedup)
338
+
339
+ 同一功能点的多个 bullet(如"开 PR"和"Auto-merge"都在描述同一条流水线)合并成一条,
340
+ 一句话说清整体效果。判断标准:**用户感知到的是同一件事,就合并。**
341
+
342
+ ### 7.3 措辞:第二人称 + 有温度
343
+
344
+ - 用**第二人称**("你不用再盯着"、"你可以随时查看")
345
+ - **主语是用户的感受**,不是系统行为("不再误报" > "修复了误报逻辑")
346
+ - **故意模糊实现细节**:不写函数名、文件名、Phase 编号(Section 3 的过滤规则同样适用)
347
+ - **有温度**:可以用"真的很急"、"不再越来越乱"这种口语表达
348
+ - 每条一行,简洁优先
349
+
350
+ ### 7.4 Hard rules
351
+
352
+ - **不杜撰**:每条都能追溯到一个真实的已完成 Story / FIX / 合并 PR;CHANGELOG 里没有的改动不写。
353
+ - **不猜版本号**:只写 `## Unreleased`(见 Section 4),版本号由发版脚本赋。
354
+ - **不 bump / tag / 发布**:那是人执行的发版步骤,本 skill 只写 changelog。
355
+ - **可审阅**:CHANGELOG 是提交进仓库的文件,owner 随时(尤其发版前)可直接审阅 / 编辑——
356
+ 无需为审阅单独生成什么。
357
+
358
+ ### 7.5 示例
359
+
360
+ ```markdown
361
+ ## Unreleased
362
+
363
+ ### 自动化流水线
364
+ - 你不用再盯着 PR,开完自动合并 `[loop]`
365
+
366
+ ### 稳定性
367
+ - 多个 loop 不再互相打架 `[loop]`
368
+
369
+ ### 新功能
370
+ - `roll loop runs` 随时回看最近几次跑了啥 `[loop]`
371
+ ```
372
+
373
+ ## 8. features.md 重写模式(产品 SOT)
374
+
375
+ US-DOC-008 — 发版脚本(maintainer-private,位于 `roll-meta/ops/release.sh`)
376
+ 在 changelog 写盘后会再调一次本 skill,请求"整体重写
377
+ `.roll/features.md`"。这次调用的语义和上面完全不同:**不是基于本版
378
+ Story 增量**,而是基于**项目整体当前状态**。
379
+
380
+ ### 8.1 何时触发
381
+
382
+ 发版脚本完成 changelog 写盘后,喂一段以
383
+ `## 当前任务:重写 .roll/features.md(Section 8)` 开头的 prompt。
384
+
385
+ ### 8.2 输入
386
+
387
+ prompt 会包含:
388
+ - 当前 `.roll/features.md`(可能为空,可能上一版本的)
389
+ - 当前 `.roll/backlog.md` 全文(Epic / Feature 分组结构)
390
+ - 当前 `.roll/features/` 目录清单
391
+ - 当前版本号
392
+
393
+ ### 8.3 输出契约
394
+
395
+ 把整个 `.roll/features.md` 写出来。结构固定为三段:
396
+
397
+ ```
398
+ # Roll — Features
399
+
400
+ > 说明段(保留原文)
401
+
402
+ ---
403
+
404
+ ## ✨ Core Highlights
405
+
406
+ - **<Feature 名>** — 1 句话产品级描述
407
+ - **<Feature 名>** — 1 句话产品级描述
408
+ - ...(3-5 条)
409
+
410
+ ---
411
+
412
+ ## Features by Epic
413
+
414
+ ### <Epic 名>
415
+ - [<Feature 名>](.roll/features/<file>.md) — 1 句话描述
416
+ - <Feature 名> — 1 句话描述(缺 deep doc 时不加链接)
417
+
418
+ ### <Epic 名>
419
+ - ...
420
+
421
+ ---
422
+
423
+ ## 维护说明(保留原文)
424
+ ```
425
+
426
+ ### 8.4 规则
427
+
428
+ - **Catalog 必须列出 BACKLOG 中所有 `### Feature:` 出现的 Feature 名**
429
+ (即使没有 deep doc 也要列)
430
+ - Feature 名跟 `.roll/features/<file>.md` 文件名一致时,加链接到该 md
431
+ - 没有对应 deep doc 的 Feature,**只写 plain text 不加链接**
432
+ - **Planning distinction(US-DOC-011)**:
433
+ - 该 Feature 下**所有** Story 均为 `📋 Todo` → 在描述末尾追加 `*(规划中)*`
434
+ - 只要有 **≥1 个** `✅ Done` Story → 正常展示,**不加**任何标记
435
+ - 一眼可见:规划中的 Feature 在每个 Epic 分组的末尾列出
436
+ - **FIX-051 兜底**:发版脚本在 AI 重写后会跑机械校验
437
+ `_enforce_planning_markers`,即使本规则被 AI 漏掉也会自动补 `*(规划中)*`;
438
+ 规则的权威实现是发版脚本里的纯 shell 函数,prompt 这条只是软提示
439
+ - 描述写 1 句话 **产品视角**:用户能用它做什么,避免实现细节
440
+ - **语言:单一中文**。Feature 名(如 `roll-loop` / `Cross-Agent Peer Review`)和命令、环境变量等术语保留英文原样;描述句一律中文。**不要**在条目下追加英文翻译行(早期 v517.x 双语混排版式已废弃,理由:扫读困难、维护翻倍、与 `guide/en|zh/` 平行目录约定不一致;英文受众走 site 端 i18n)
441
+ - 分组用 BACKLOG 的 Epic 名,原序,不重排
442
+ - Core Highlights 从所有 Features 里挑 3-5 个最能代表产品定位的,
443
+ 描述用 bold 标 Feature 名后接说明;不照搬 catalog 文案
444
+ - **不**写 "Recent Activity" 类区块——features.md 是 SOT,全量当下状态
445
+ - **不**写版本号、不引用 changelog 条目
446
+ - 说明段(顶部 quote)和维护说明(尾部)原文保留,不要重新生成措辞
447
+
448
+ ### 8.5 失败安全
449
+
450
+ 如果 prompt 信息不足(BACKLOG 解析失败等),**不要部分写入** —— 输出原
451
+ 文件内容即可。发版脚本会捕获 stdout 后比较:内容未变就不 stage。
452
+
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  hidden: true
3
3
  name: roll-.clarify
4
+ license: MIT
4
5
  description: |
5
6
  Passive scope-clarification skill. Auto-triggers when roll-build receives vague or under-specified input in Fly mode. Summarizes intent and asks 3–5 targeted questions to establish boundaries before planning or coding.
6
7
  This is a passive skill. Never announce "I'm using roll-.clarify." Just do it naturally: summarize, ask, wait.
@@ -18,11 +19,13 @@ Auto-invoked by `roll-build` (Fly mode) when the user input is:
18
19
  - Contains ambiguous terms like "优化一下", "改一下", "加个东西"
19
20
  - Could be interpreted in multiple ways
20
21
 
21
- **Do NOT activate when:**
22
+ ## When Not to Use
23
+
22
24
  - Intent is already clear and actionable
23
- - User gives a specific command with a skill trigger (e.g. `$roll-jot ...`)
25
+ - User gives a specific command with a skill trigger (e.g. `$roll-idea ...`)
24
26
  - User is answering a clarification question you just asked
25
27
  - The task is simple enough that misinterpretation risk is negligible
28
+ - User messy thoughts need restatement rather than questioning (use `$roll-.echo`)
26
29
 
27
30
  ## Behavior
28
31