@seanyao/roll 2026.529.5 → 2026.601.2
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 +57 -25
- package/README.md +10 -7
- package/bin/roll +3952 -317
- package/conventions/config.yaml +7 -0
- package/lib/__pycache__/github_sync.cpython-314.pyc +0 -0
- package/lib/__pycache__/loop_result_eval.cpython-314.pyc +0 -0
- package/lib/__pycache__/model_prices.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__/slides-render.cpython-314.pyc +0 -0
- package/lib/agent_usage/__init__.py +4 -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__/qwen.cpython-314.pyc +0 -0
- package/lib/agent_usage/gemini.py +127 -0
- package/lib/agent_usage/kimi.py +127 -0
- package/lib/agent_usage/openai.py +126 -0
- package/lib/agent_usage/qwen.py +128 -0
- package/lib/context_feed_budget.sh +194 -0
- package/lib/github_sync.py +876 -0
- package/lib/i18n/agent.sh +54 -0
- package/lib/i18n/init.sh +22 -0
- package/lib/i18n/peer.sh +7 -0
- package/lib/i18n/peer_help.sh +4 -0
- package/lib/i18n/skills_catalog.sh +30 -0
- package/lib/loop-exit-summary.py +393 -0
- package/lib/loop-fmt.py +93 -75
- package/lib/loop_pick_agent.py +241 -170
- package/lib/loop_result_eval.py +469 -0
- package/lib/model_prices.py +0 -10
- package/lib/roll-home.py +1 -28
- package/lib/roll-loop-status.py +330 -40
- package/lib/roll-onboard-render.py +378 -0
- package/lib/roll-peer.py +1 -1
- package/lib/roll-plan-validate.py +165 -0
- package/lib/roll_git.py +41 -0
- package/lib/slides/components/README.md +8 -2
- package/lib/slides/templates/introduction-v3.html +1 -6
- package/lib/slides-render.py +305 -15
- package/lib/slides-validate.py +195 -7
- package/package.json +1 -1
- package/skills/roll-.changelog/SKILL.md +67 -56
- package/skills/roll-brief/SKILL.md +1 -1
- package/skills/roll-build/SKILL.md +14 -12
- package/skills/roll-deck/SKILL.md +152 -0
- package/skills/roll-design/SKILL.md +13 -6
- package/skills/roll-doc/SKILL.md +269 -6
- package/skills/roll-fix/SKILL.md +15 -9
- package/skills/roll-loop/SKILL.md +9 -7
- package/skills/roll-notes/SKILL.md +1 -1
- package/skills/roll-onboard/SKILL.md +85 -0
- package/skills/roll-peer/SKILL.md +6 -5
- package/lib/agent_routes_lint.py +0 -203
- package/skills/roll-research/SKILL.md +0 -316
- package/skills/roll-research/references/schema.json +0 -166
- package/skills/roll-research/scripts/md_to_pdf.py +0 -289
|
@@ -13,7 +13,7 @@ After successful Build & Deploy, extracts completed Stories from .roll/backlog.m
|
|
|
13
13
|
## When Triggered
|
|
14
14
|
|
|
15
15
|
- **Auto-triggered**: After successful deploy of `$roll-build` or `$roll-fix`
|
|
16
|
-
- **Manual trigger**: When user requests "update changelog"
|
|
16
|
+
- **Manual trigger**: When user requests "update changelog" / "更新 changelog"
|
|
17
17
|
|
|
18
18
|
## When Not to Use
|
|
19
19
|
|
|
@@ -122,6 +122,8 @@ CHANGELOG 只取破折号前的用户症状,丢弃破折号后的修复手段
|
|
|
122
122
|
|
|
123
123
|
Fix 类句式参考:`<命令/功能> 不再 <之前的坏现象>`,或 `<命令/功能> 现在 <正常表现>`。内部有几个 bug 导致这一个现象,合并成一条。
|
|
124
124
|
|
|
125
|
+
**归因标签**:每条 bullet 末尾加来源标签——`[loop]`(对应 `US-AUTO-*` / `FIX-*` / `US-CL-*` 等由 Loop 自动执行的故事)、`[dream]`(对应 `REFACTOR-*`,Dream 夜间扫描推入 Backlog)、无标签(人工提交或来源不明)。同一来源的多条不必重复标。
|
|
126
|
+
|
|
125
127
|
### 4. Section Header — Always `## Unreleased`
|
|
126
128
|
|
|
127
129
|
**⚠️ do NOT guess version numbers.** Only the release script (maintainer-private
|
|
@@ -131,10 +133,17 @@ the moment of a real release. Until then, every new bullet goes under
|
|
|
131
133
|
|
|
132
134
|
```
|
|
133
135
|
## Unreleased
|
|
134
|
-
|
|
135
|
-
|
|
136
|
+
|
|
137
|
+
### 新功能
|
|
138
|
+
- ...new entries here...
|
|
139
|
+
|
|
140
|
+
### 稳定性
|
|
141
|
+
- ...
|
|
136
142
|
```
|
|
137
143
|
|
|
144
|
+
新条目按**感知分组**(`### 标题`)归类,不写 `**Added**` / `**Fixed**` 前缀——
|
|
145
|
+
分组规则见 **Section 7**(版本段落 = GitHub Release 正文,分组结构是 changelog 自己的格式)。
|
|
146
|
+
|
|
138
147
|
When the release script runs, it renames `## Unreleased` to `## v{N}` (where N
|
|
139
148
|
is computed from git tags) — that's the single moment a version label gets
|
|
140
149
|
assigned.
|
|
@@ -232,29 +241,37 @@ its own first draft. Set `ROLL_CHANGELOG_AUDIT_LOG` to redirect (tests only).
|
|
|
232
241
|
|
|
233
242
|
### 5. Generate CHANGELOG.md
|
|
234
243
|
|
|
244
|
+
条目结构按 **Section 7** 的感知分组(`### 新功能` / `### 自动化流水线` / …),不用 `Added`/`Fixed`。
|
|
245
|
+
|
|
235
246
|
**Create mode** (first time, no CHANGELOG.md yet):
|
|
236
247
|
```markdown
|
|
237
248
|
# Changelog
|
|
238
249
|
|
|
239
250
|
## Unreleased
|
|
240
|
-
|
|
251
|
+
|
|
252
|
+
### 新功能
|
|
253
|
+
- ...current deploy's entries...
|
|
241
254
|
|
|
242
255
|
## 2026.05.10
|
|
243
|
-
-
|
|
256
|
+
- ...historical entries from completed Stories before today...
|
|
244
257
|
```
|
|
245
258
|
|
|
246
259
|
**Append mode** (most common — CHANGELOG.md exists):
|
|
247
260
|
|
|
248
261
|
1. Find `## Unreleased` heading at the top of CHANGELOG.md.
|
|
249
|
-
2. If it exists → append new
|
|
250
|
-
3. If it doesn't exist → insert a fresh `## Unreleased` at the very top (right after the `# Changelog` title) with the
|
|
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.
|
|
251
264
|
|
|
252
265
|
```markdown
|
|
253
266
|
# Changelog
|
|
254
267
|
|
|
255
268
|
## Unreleased
|
|
256
|
-
|
|
257
|
-
|
|
269
|
+
|
|
270
|
+
### 自动化流水线
|
|
271
|
+
- ...just-deployed entry appended here... `[loop]`
|
|
272
|
+
|
|
273
|
+
### 稳定性
|
|
274
|
+
- ...another just-deployed entry...
|
|
258
275
|
|
|
259
276
|
## v2026.05.07 ← previous releases left untouched
|
|
260
277
|
- ...
|
|
@@ -290,85 +307,79 @@ After successful deploy in `$roll-build` / `$roll-fix`:
|
|
|
290
307
|
|
|
291
308
|
---
|
|
292
309
|
|
|
293
|
-
## 7.
|
|
294
|
-
|
|
295
|
-
`CHANGELOG.md` 里的 `## Unreleased` 条目是**原始数据**,每条对应一个故事或修复。
|
|
296
|
-
发版时(release script 打 tag 前,或手动 `roll release notes`),把这些散装 bullet 整理成**给人读的 Release 正文**。
|
|
297
|
-
|
|
298
|
-
这是两个不同的产物:
|
|
299
|
-
- `CHANGELOG.md` — 机器写、给 `roll update` 之后展示用,条目可以多
|
|
300
|
-
- GitHub Release 正文 — 给用户 / 关注者读,要分组、要有温度、要简洁
|
|
310
|
+
## 7. 版本段落 = GitHub Release 正文(分组 + 措辞)
|
|
301
311
|
|
|
302
|
-
|
|
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`)、不在发版关键路径上现场生成。
|
|
303
317
|
|
|
304
|
-
|
|
305
|
-
|
|
318
|
+
所以**版本段落本身就要长成 Release 正文该有的样子**。下面的分组 / 合并 / 措辞 / hard
|
|
319
|
+
rules 不是"另一种格式",就是 changelog 段落的写法——把它写好 = 同时写好了 changelog
|
|
320
|
+
和"发布说明"。
|
|
306
321
|
|
|
307
|
-
### 7.
|
|
322
|
+
### 7.1 分组(取代 Added/Fixed)
|
|
308
323
|
|
|
309
|
-
|
|
324
|
+
每条 bullet 按**用户感知**归入下列分组,分组用 `###` 标题,每组最多 5 条,超出的合并:
|
|
310
325
|
|
|
311
|
-
|
|
|
326
|
+
| 分组(`### 标题`) | 归入条件 |
|
|
312
327
|
|---|---|
|
|
328
|
+
| 新功能 | 全新命令或用户可感知的新能力 |
|
|
313
329
|
| 自动化流水线 | PR 自动化、Auto-merge、CI 触发、分支管理 |
|
|
314
330
|
| 可见性 | Dashboard、弹窗、实时输出、状态显示 |
|
|
315
331
|
| 稳定性 | 崩溃修复、并发问题、状态误报 |
|
|
316
332
|
| 工程和测试 | CI 速度、测试并行、文档工作流 |
|
|
317
|
-
| 新功能 | 全新命令或用户可感知的新能力 |
|
|
318
|
-
|
|
319
|
-
分组顺序:**影响日常使用的放前面**,纯工程改进放后面。
|
|
320
|
-
分组少于 2 条时可以合并到相邻组,不强制保留空组。
|
|
321
333
|
|
|
322
|
-
|
|
334
|
+
分组顺序:**影响日常使用的放前面**,纯工程改进放后面。某组少于 2 条可并入相邻组,不强留空组。
|
|
335
|
+
**不写 `**Added**` / `**Fixed**` 前缀**——分组标题已经承担语义分类。
|
|
323
336
|
|
|
324
|
-
|
|
337
|
+
### 7.2 合并相似条目(dedup)
|
|
325
338
|
|
|
326
|
-
|
|
339
|
+
同一功能点的多个 bullet(如"开 PR"和"Auto-merge"都在描述同一条流水线)合并成一条,
|
|
340
|
+
一句话说清整体效果。判断标准:**用户感知到的是同一件事,就合并。**
|
|
327
341
|
|
|
328
|
-
### 7.
|
|
342
|
+
### 7.3 措辞:第二人称 + 有温度
|
|
329
343
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
| `[dream]` | 对应 `REFACTOR-*` 故事,由 Dream 夜间扫描发现并推入 Backlog |
|
|
336
|
-
| (无标签) | 人工提交,或无法确定来源 |
|
|
344
|
+
- 用**第二人称**("你不用再盯着"、"你可以随时查看")
|
|
345
|
+
- **主语是用户的感受**,不是系统行为("不再误报" > "修复了误报逻辑")
|
|
346
|
+
- **故意模糊实现细节**:不写函数名、文件名、Phase 编号(Section 3 的过滤规则同样适用)
|
|
347
|
+
- **有温度**:可以用"真的很急"、"不再越来越乱"这种口语表达
|
|
348
|
+
- 每条一行,简洁优先
|
|
337
349
|
|
|
338
|
-
### 7.
|
|
350
|
+
### 7.4 Hard rules
|
|
339
351
|
|
|
340
|
-
-
|
|
341
|
-
-
|
|
342
|
-
-
|
|
343
|
-
-
|
|
344
|
-
|
|
352
|
+
- **不杜撰**:每条都能追溯到一个真实的已完成 Story / FIX / 合并 PR;CHANGELOG 里没有的改动不写。
|
|
353
|
+
- **不猜版本号**:只写 `## Unreleased`(见 Section 4),版本号由发版脚本赋。
|
|
354
|
+
- **不 bump / tag / 发布**:那是人执行的发版步骤,本 skill 只写 changelog。
|
|
355
|
+
- **可审阅**:CHANGELOG 是提交进仓库的文件,owner 随时(尤其发版前)可直接审阅 / 编辑——
|
|
356
|
+
无需为审阅单独生成什么。
|
|
345
357
|
|
|
346
|
-
### 7.
|
|
358
|
+
### 7.5 示例
|
|
347
359
|
|
|
348
360
|
```markdown
|
|
349
|
-
##
|
|
361
|
+
## Unreleased
|
|
350
362
|
|
|
351
|
-
|
|
352
|
-
-
|
|
353
|
-
- <条目>
|
|
363
|
+
### 自动化流水线
|
|
364
|
+
- 你不用再盯着 PR,开完自动合并 `[loop]`
|
|
354
365
|
|
|
355
|
-
|
|
366
|
+
### 稳定性
|
|
367
|
+
- 多个 loop 不再互相打架 `[loop]`
|
|
356
368
|
|
|
357
|
-
|
|
369
|
+
### 新功能
|
|
370
|
+
- `roll loop runs` 随时回看最近几次跑了啥 `[loop]`
|
|
358
371
|
```
|
|
359
372
|
|
|
360
|
-
不需要 `**Added**` / `**Fixed**` 前缀,分组标题已经承担了语义分类的职责。
|
|
361
|
-
|
|
362
373
|
## 8. features.md 重写模式(产品 SOT)
|
|
363
374
|
|
|
364
375
|
US-DOC-008 — 发版脚本(maintainer-private,位于 `roll-meta/ops/release.sh`)
|
|
365
|
-
在 changelog
|
|
366
|
-
`.roll/features.md`"
|
|
376
|
+
在 changelog 写盘后会再调一次本 skill,请求"整体重写
|
|
377
|
+
`.roll/features.md`"。这次调用的语义和上面完全不同:**不是基于本版
|
|
367
378
|
Story 增量**,而是基于**项目整体当前状态**。
|
|
368
379
|
|
|
369
380
|
### 8.1 何时触发
|
|
370
381
|
|
|
371
|
-
发版脚本完成 changelog
|
|
382
|
+
发版脚本完成 changelog 写盘后,喂一段以
|
|
372
383
|
`## 当前任务:重写 .roll/features.md(Section 8)` 开头的 prompt。
|
|
373
384
|
|
|
374
385
|
### 8.2 输入
|
|
@@ -8,7 +8,7 @@ description: |
|
|
|
8
8
|
status, escalations requiring human attention, and a release-readiness verdict.
|
|
9
9
|
Three trigger modes: auto on Feature completion, daily morning schedule,
|
|
10
10
|
or manual $roll-brief invocation. Distinct from roll-.changelog (user-facing
|
|
11
|
-
|
|
11
|
+
changelog) — this is an internal digest for the product owner.
|
|
12
12
|
---
|
|
13
13
|
|
|
14
14
|
# Roll Brief
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: roll-build
|
|
3
3
|
license: MIT
|
|
4
|
+
allowed-tools: "Read, Edit, Write, Glob, Grep, Bash, Skill, Agent"
|
|
4
5
|
description: "Universal delivery skill. Handles any input: a US-XXX ID executes from BACKLOG via TCR; a FIX-XXX redirects to roll-fix; any other text auto-clarifies, designs, and ships as a new Story."
|
|
5
6
|
---
|
|
6
7
|
|
|
@@ -54,24 +55,25 @@ Activate when input is a `US-[A-Z]+-[0-9]+` identifier.
|
|
|
54
55
|
|
|
55
56
|
### Step 0: Pre-flight self-check (US-AGENT-007)
|
|
56
57
|
|
|
57
|
-
Before reading the Story in depth or splitting actions, **read the Agent profile** from the story's feature md and decide whether this cycle can realistically deliver it. The check is mechanical:
|
|
58
|
+
Before reading the Story in depth or splitting actions, **read the Agent profile** from the story's feature md and decide whether this cycle can realistically deliver it. The check is mechanical and turns on a single axis — the story's `est_min` estimate (US-AGENT-022 retired the old three-dimension type/est/risk routing; there is no per-agent capacity range, risk zone, or history threshold anymore):
|
|
58
59
|
|
|
59
60
|
```
|
|
60
61
|
inputs:
|
|
61
62
|
story.est_min (from **Agent profile:** block, US-AGENT-001)
|
|
62
|
-
story.risk_zone (low / medium / high)
|
|
63
63
|
story.chain_depth (0 unless already a downgrade product)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
|
|
65
|
+
complexity tier (lib/loop_pick_agent.py, single source of truth):
|
|
66
|
+
est_min <= 8 → easy
|
|
67
|
+
8 < est_min <= 20 → default
|
|
68
|
+
est_min > 20 → hard
|
|
69
|
+
missing / illegal → default
|
|
67
70
|
|
|
68
71
|
verdict:
|
|
69
|
-
too_big when
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
and we still have downgrade budget — don't burn a cycle)
|
|
72
|
+
too_big when:
|
|
73
|
+
story.est_min is large enough that even the `hard` tier won't fit one
|
|
74
|
+
cycle — i.e. the work plainly composes too many files / behaviours to
|
|
75
|
+
land green in a single cycle — AND story.chain_depth == 0
|
|
76
|
+
(still have downgrade budget; don't burn a cycle on a guaranteed miss).
|
|
75
77
|
ok otherwise
|
|
76
78
|
```
|
|
77
79
|
|
|
@@ -110,7 +112,7 @@ exit 0
|
|
|
110
112
|
|
|
111
113
|
If `roll-design` cannot produce ≥2 sub-stories (story is already irreducible), fall through to **US-AGENT-009 cap-hit path** by invoking `_loop_split_cap_hit` directly. The cap is purely about stopping infinite split chains; even on the first re-split, if the design step gives up, the cap-hit handler raises ALERT for human triage.
|
|
112
114
|
|
|
113
|
-
> Pre-flight is honest, not paranoid: a small story (est_min ≤
|
|
115
|
+
> Pre-flight is honest, not paranoid: a small story (est_min ≤ 8 — the `easy` tier — with chain_depth=0) should almost always go `ok`. The check pays off on the long tail — stories with a large `est_min` that, on inspection, plainly compose far more files and behaviours than one cycle can land green.
|
|
114
116
|
|
|
115
117
|
### Step 1: Read the Story
|
|
116
118
|
|
|
@@ -34,6 +34,8 @@ $roll-deck "How TCR keeps us honest"
|
|
|
34
34
|
- You MUST NOT edit any other file: no README, no AGENTS.md, no backlog, no source code, no `.roll/slides/*.html`.
|
|
35
35
|
- HTML rendering is `roll slides build <slug>` — never produce HTML here.
|
|
36
36
|
- If `.roll/slides/<slug>/deck.md` already exists, ask the user before overwriting.
|
|
37
|
+
- **Layout must come from the whitelist**: `plain`, `cards-2`, `cards-3`, `cards-4`, `compare`, `pipeline`, `timeline`, `quote`, `highlight`. Inventing a layout name makes `roll slides build` fail with `Unknown layout`.
|
|
38
|
+
**layout 必须从白名单选**:`plain` / `cards-2` / `cards-3` / `cards-4` / `compare` / `pipeline` / `timeline` / `quote` / `highlight`。自创 layout 名渲染会失败。
|
|
37
39
|
|
|
38
40
|
## Inputs
|
|
39
41
|
|
|
@@ -68,6 +70,7 @@ Stop reading when you have enough to write 18 slides with concrete evidence.
|
|
|
68
70
|
|
|
69
71
|
Default count is `18` (or the count the template prescribes). Each slide MUST contain:
|
|
70
72
|
|
|
73
|
+
- `layout` — one of the whitelist layouts (see "Layout 选择手册" below). **You MUST declare `layout:` explicitly on every slide, before `evidence:`** — this forces a deliberate choice and stops every slide collapsing to `plain`.
|
|
71
74
|
- `title_en` — short English title (≤ 8 words).
|
|
72
75
|
- `title_zh` — short Chinese title (≤ 16 chars).
|
|
73
76
|
- `body_en` — markdown body, concise, ≤ 200 words.
|
|
@@ -86,6 +89,149 @@ Default count is `18` (or the count the template prescribes). Each slide MUST co
|
|
|
86
89
|
|
|
87
90
|
Bilingual rule: English and Chinese MUST be on separate lines in the rendered body — never inline on the same line.
|
|
88
91
|
|
|
92
|
+
## Layout 选择手册 Layout Selection Playbook
|
|
93
|
+
|
|
94
|
+
Pick the layout from the **shape of the content**, not from a wish to look fancy.
|
|
95
|
+
按**内容形态**选 layout,而不是为了好看硬凑。
|
|
96
|
+
|
|
97
|
+
### Decision matrix 决策矩阵
|
|
98
|
+
|
|
99
|
+
| Content shape 内容形态 | Pick 推荐 layout | Anti-pattern 反例(不要用) |
|
|
100
|
+
|---|---|---|
|
|
101
|
+
| Before/after, old vs new, "what we did vs didn't" 前后对比 / 旧 vs 新 | `compare` | `cards-2` — loses the contrast semantics 缺失对比语义 |
|
|
102
|
+
| Multi-step process, pipeline, staged flow 多步骤流程 / 阶段流转 | `pipeline` | `cards-N` — order is invisible 看不出顺序 |
|
|
103
|
+
| Time series, evolution, changelog 时间序列 / 演进 / changelog | `timeline` | `pipeline` — pipeline = steps, timeline = time pipeline 表步骤、timeline 表时间 |
|
|
104
|
+
| 2/3/4 parallel concepts, no internal order 2/3/4 个并列概念,无顺序 | `cards-2` / `cards-3` / `cards-4` | ≥5 items crammed in — split the slide ≥5 项硬塞,请拆 slide |
|
|
105
|
+
| A line, a testimonial, the user's own words 引言 / 金句 / 用户原话 | `quote` | `highlight` — quote has attribution, highlight is a conclusion quote 有归属,highlight 是结论 |
|
|
106
|
+
| The one key takeaway / one-line conclusion 关键结论 / 一句话总结 | `highlight` | `plain` — drowns in the paragraph 淹没在段落里 |
|
|
107
|
+
| Ordinary prose, explanation, plain list 普通段落 / 解释 / 列表 | `plain` | — |
|
|
108
|
+
|
|
109
|
+
**At most one layout per slide.** Do not stack layouts. And do not force a rich
|
|
110
|
+
component when the content is genuinely just a paragraph — **if the content is
|
|
111
|
+
really one block of prose, `plain` is the correct choice**, not a failure.
|
|
112
|
+
**每张 slide 最多 1 个 layout。** 不要为了用富组件硬凑;内容真就是一段话时,`plain` 是正确答案,不是偷懒。
|
|
113
|
+
|
|
114
|
+
### Worked examples 真实示例
|
|
115
|
+
|
|
116
|
+
Five examples, drawn from real `site/slides/roll-introduction-v5.html` slides.
|
|
117
|
+
五个示例,取自 v5 实际 slide。
|
|
118
|
+
|
|
119
|
+
**1. "TCR before vs after" → `compare`**
|
|
120
|
+
内容是"用 TCR 之前 vs 之后" → 选 `compare`:
|
|
121
|
+
|
|
122
|
+
```markdown
|
|
123
|
+
## Slide 4
|
|
124
|
+
layout: compare
|
|
125
|
+
title_en: "Why TCR"
|
|
126
|
+
title_zh: "为什么用 TCR"
|
|
127
|
+
left_title_en: "Before"
|
|
128
|
+
left_title_zh: "之前"
|
|
129
|
+
right_title_en: "After"
|
|
130
|
+
right_title_zh: "之后"
|
|
131
|
+
left_items:
|
|
132
|
+
- text_en: "Broken commits land on main"
|
|
133
|
+
text_zh: "坏提交直接进 main"
|
|
134
|
+
right_items:
|
|
135
|
+
- text_en: "Every commit is green or reverted"
|
|
136
|
+
text_zh: "每个提交要么绿要么回滚"
|
|
137
|
+
evidence:
|
|
138
|
+
- AGENTS.md:42
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**2. "The Roll loop pipeline" → `pipeline`**
|
|
142
|
+
内容是"idea → backlog → build → verify → release 流转" → 选 `pipeline`:
|
|
143
|
+
|
|
144
|
+
```markdown
|
|
145
|
+
## Slide 7
|
|
146
|
+
layout: pipeline
|
|
147
|
+
title_en: "The Roll Loop"
|
|
148
|
+
title_zh: "Roll 循环"
|
|
149
|
+
stages:
|
|
150
|
+
- title_en: "Idea"
|
|
151
|
+
title_zh: "想法"
|
|
152
|
+
desc_en: "Capture in backlog"
|
|
153
|
+
desc_zh: "落到 backlog"
|
|
154
|
+
css_class: "pipe-idea"
|
|
155
|
+
- title_en: "Build"
|
|
156
|
+
title_zh: "构建"
|
|
157
|
+
desc_en: "TCR micro-commits"
|
|
158
|
+
desc_zh: "TCR 微提交"
|
|
159
|
+
css_class: "pipe-build"
|
|
160
|
+
evidence:
|
|
161
|
+
- skills/roll-loop/SKILL.md:1
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**3. "How Roll grew over releases" → `timeline`**
|
|
165
|
+
内容是"v1 → v2 → 现在的演进" → 选 `timeline`:
|
|
166
|
+
|
|
167
|
+
```markdown
|
|
168
|
+
## Slide 12
|
|
169
|
+
layout: timeline
|
|
170
|
+
title_en: "How Roll Grew"
|
|
171
|
+
title_zh: "Roll 的演进"
|
|
172
|
+
items:
|
|
173
|
+
- title_en: "First loop"
|
|
174
|
+
title_zh: "第一版 loop"
|
|
175
|
+
body_en: "Hourly cron executor."
|
|
176
|
+
body_zh: "每小时 cron 执行器。"
|
|
177
|
+
evidence:
|
|
178
|
+
- CHANGELOG.md:1
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**4. "Three pillars of Roll" → `cards-3`**
|
|
182
|
+
内容是"三个并列支柱,无先后" → 选 `cards-3`:
|
|
183
|
+
|
|
184
|
+
```markdown
|
|
185
|
+
## Slide 5
|
|
186
|
+
layout: cards-3
|
|
187
|
+
title_en: "Three Pillars"
|
|
188
|
+
title_zh: "三大支柱"
|
|
189
|
+
cards:
|
|
190
|
+
- title_en: "Skills"
|
|
191
|
+
title_zh: "技能"
|
|
192
|
+
body_en: "Composable AI workflows."
|
|
193
|
+
body_zh: "可组合的 AI 工作流。"
|
|
194
|
+
- title_en: "Loop"
|
|
195
|
+
title_zh: "循环"
|
|
196
|
+
body_en: "Autonomous backlog executor."
|
|
197
|
+
body_zh: "自主 backlog 执行器。"
|
|
198
|
+
- title_en: "TCR"
|
|
199
|
+
title_zh: "TCR"
|
|
200
|
+
body_en: "Test && commit || revert."
|
|
201
|
+
body_zh: "测试通过则提交,否则回滚。"
|
|
202
|
+
evidence:
|
|
203
|
+
- README.md:1
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**5. "Kimi's verdict" → `quote`**
|
|
207
|
+
内容是带归属的一句用户原话 → 选 `quote`:
|
|
208
|
+
|
|
209
|
+
```markdown
|
|
210
|
+
## Slide 16
|
|
211
|
+
layout: quote
|
|
212
|
+
title_en: "Peer Verdict"
|
|
213
|
+
title_zh: "评审结论"
|
|
214
|
+
text_en: "AGREE with refinement."
|
|
215
|
+
text_zh: "同意,附细化意见。"
|
|
216
|
+
evidence:
|
|
217
|
+
- .roll/features/authoring/slide-deck-generator.md:919
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Whitelist field names match `lib/slides/components/README.md` — copy them
|
|
221
|
+
verbatim (`left_items` / `right_items` / `stages[].css_class` / `text_en` …).
|
|
222
|
+
字段名以 `lib/slides/components/README.md` 为准,原样照抄。
|
|
223
|
+
|
|
224
|
+
## Known agent limitations 已知 agent 局限
|
|
225
|
+
|
|
226
|
+
The layout playbook is loadable by any agent (mechanism is agent-agnostic), but
|
|
227
|
+
whether the model actually *applies* the decision matrix scales with model
|
|
228
|
+
strength. Claude Opus / Sonnet are the most reliable. If an agent degrades to
|
|
229
|
+
"all `plain` placeholders" and ignores the matrix, note it here rather than
|
|
230
|
+
blocking — quality, not mechanism, is the variable.
|
|
231
|
+
layout 手册任何 agent 都读得到(机制 agnostic),但是否真按矩阵挑 layout 跟模型强度相关。Claude Opus / Sonnet 最稳;某 agent 退化成全 plain 时记到此处,不阻塞。
|
|
232
|
+
|
|
233
|
+
- (No degradations recorded yet. 暂无记录。)
|
|
234
|
+
|
|
89
235
|
### 4. Write deck.md 写文件
|
|
90
236
|
|
|
91
237
|
Write to `.roll/slides/<slug>/deck.md` with this structure:
|
|
@@ -105,6 +251,7 @@ author: "<from package.json author>"
|
|
|
105
251
|
---
|
|
106
252
|
|
|
107
253
|
## Slide 1
|
|
254
|
+
layout: plain
|
|
108
255
|
title_en: "..."
|
|
109
256
|
title_zh: "..."
|
|
110
257
|
body_en: |
|
|
@@ -119,6 +266,11 @@ evidence:
|
|
|
119
266
|
...
|
|
120
267
|
```
|
|
121
268
|
|
|
269
|
+
Every slide declares `layout:` first (see "Layout 选择手册"); rich layouts add
|
|
270
|
+
their own structured fields (e.g. `cards`, `left_items`, `stages`) in place of
|
|
271
|
+
`body_en` / `body_zh`.
|
|
272
|
+
每张 slide 先声明 `layout:`;富 layout 用各自的结构化字段取代 `body_en` / `body_zh`。
|
|
273
|
+
|
|
122
274
|
`total_slides` MUST match the number of `## Slide N` blocks. The validator (run by `roll slides build`) will reject mismatches.
|
|
123
275
|
|
|
124
276
|
Project identity fields (`pkg_name`, `repo_url`, `site_url`, `author`) are copied verbatim from `package.json` — never infer or guess these values. `roll slides build` injects them into the HTML template (cover, back cover, footer).
|
|
@@ -682,8 +682,8 @@ Note: `{DOMAIN}` maps to the Bounded Context name identified in DDD analysis.
|
|
|
682
682
|
- Cross-context: {if touches another context, otherwise omit}
|
|
683
683
|
|
|
684
684
|
**Agent profile:**
|
|
685
|
-
- est_min: {1-30
|
|
686
|
-
- risk_zone: {low / medium / high — 改文档 low,改用户可见行为 medium,改 loop infra 或安全/隔离基建 high}
|
|
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
687
|
- chain_depth: 0 {若是自降级产出的子 story 则 +1,累计 ≥2 时第 3 次拒拆}
|
|
688
688
|
|
|
689
689
|
**AC:**
|
|
@@ -705,9 +705,9 @@ Note: `{DOMAIN}` maps to the Bounded Context name identified in DDD analysis.
|
|
|
705
705
|
- Integration test: `tests/integration/{flow}.test.ts`
|
|
706
706
|
```
|
|
707
707
|
|
|
708
|
-
> **强制规则 — Agent profile 必须填**:Split into Stories 步骤产出的每个 US 都必须带 `**Agent profile:**`
|
|
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
709
|
>
|
|
710
|
-
> **MUST fill** the `**Agent profile:**` block on every newly split US
|
|
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).
|
|
711
711
|
|
|
712
712
|
### Closing Doc-Refresh Story Template — Phase N.M 收尾文档
|
|
713
713
|
|
|
@@ -746,12 +746,19 @@ When any preceding US in the batch changes user-visible behavior, append this te
|
|
|
746
746
|
|
|
747
747
|
## INVEST Principles
|
|
748
748
|
|
|
749
|
+
> **颗粒度校准(按 AI cycle 量纲)**:Roll 的 Story 不是"几天的活",而是
|
|
750
|
+
> **一个 AI cycle 闭环(目标 5–10 min)**。下面的 S 和 I 按这个量纲重定义,
|
|
751
|
+
> 别套用传统敏捷"一个 sprint 装几个 story"的尺度。
|
|
752
|
+
|
|
749
753
|
Each story must be:
|
|
750
|
-
- **Independent**:
|
|
754
|
+
- **Independent**: 不强求完全独立。有先后依赖就用 `depends-on:` 串成链(配合
|
|
755
|
+
`chain_depth ≤ 2` 防无限套娃)。真正要避免的是"改同一文件的并行冲突",
|
|
756
|
+
而不是"禁止依赖"——为追求独立硬把一个 cycle 的活摊成几个反而更糟。
|
|
751
757
|
- **Negotiable**: Scope is negotiable
|
|
752
758
|
- **Valuable**: Provides value to the user
|
|
753
759
|
- **Estimable**: Effort can be estimated
|
|
754
|
-
- **Small**:
|
|
760
|
+
- **Small**: **一个 Story ≈ 一个 AI cycle 闭环(目标 5–10 min)**。S 是 cycle 量纲,
|
|
761
|
+
装不进一个 cycle 就拆;`est_min > ~15` 是"再拆"信号——除非原子不可分。
|
|
755
762
|
- **Testable**: Can be tested and verified
|
|
756
763
|
|
|
757
764
|
## Backlog Structure
|