@seanyao/roll 3.0.0 → 3.606.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 +25 -0
- package/README.md +26 -9
- package/dist/roll.mjs +2911 -1993
- package/package.json +1 -1
- package/skills/README.md +51 -0
- package/skills/roll-.changelog/SKILL.md +13 -0
- package/skills/roll-build/SKILL.md +21 -1
- package/skills/roll-fix/SKILL.md +21 -1
- package/bin/dream-test-quality-scan +0 -110
package/package.json
CHANGED
package/skills/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# roll-skills
|
|
2
|
+
|
|
3
|
+
The **skill contracts** for [roll](https://github.com/seanyao/roll) — markdown
|
|
4
|
+
playbooks that AI agents (Claude, Cursor, Kimi, Pi, …) load and follow when
|
|
5
|
+
they work inside a roll-managed project. This repo is mounted into the main
|
|
6
|
+
repo as the `skills/` git submodule and ships inside the
|
|
7
|
+
[`@seanyao/roll`](https://www.npmjs.com/package/@seanyao/roll) npm package;
|
|
8
|
+
`roll setup` syncs the contracts into each installed AI client.
|
|
9
|
+
|
|
10
|
+
roll 的**技能契约**仓——AI agent 在 roll 项目里工作时加载并遵循的 markdown
|
|
11
|
+
工作流手册。以 `skills/` 子模块挂载进主仓、随 npm 包发布,`roll setup`
|
|
12
|
+
负责同步到各 AI 客户端。
|
|
13
|
+
|
|
14
|
+
## Skills · 技能清单
|
|
15
|
+
|
|
16
|
+
**Delivery · 交付主链**
|
|
17
|
+
- `roll-design` — 讨论/设计/拆卡入口(DDD 建模 + INVEST 拆分落 backlog)
|
|
18
|
+
- `roll-build` — 万能交付:US 卡经 TCR 全流程(含验证门与验收证据)
|
|
19
|
+
- `roll-fix` — 缺陷修复轻量链路(FIX 卡专用)
|
|
20
|
+
- `roll-idea` — 一句话快速捕获 → 自动分类编号落 backlog
|
|
21
|
+
- `roll-loop` — 无人值守 BACKLOG 执行器的工作流契约
|
|
22
|
+
|
|
23
|
+
**Quality · 质量与评审**
|
|
24
|
+
- `roll-peer` — 跨 agent 协商评审(三态协议 + 时间盒)
|
|
25
|
+
- `roll-review-pr` — PR 评审,输出 APPROVE / REQUEST_CHANGES / UNCERTAIN
|
|
26
|
+
- `roll-spar` — 攻防 TDD(高危逻辑双 agent 对抗)
|
|
27
|
+
- `roll-.review` / `roll-.qa` — TCR 内嵌自审与测试金字塔基准
|
|
28
|
+
|
|
29
|
+
**Observation · 观察与汇报**
|
|
30
|
+
- `roll-brief` — owner 简报;`roll-notes` — 项目日记
|
|
31
|
+
- `roll-sentinel` — 生产抽查巡检;`roll-.dream` — 夜间架构/文档健康扫描
|
|
32
|
+
- `roll-doctor` — 工具链体检;`roll-doc` — 存量文档自动化
|
|
33
|
+
|
|
34
|
+
**Lifecycle & misc · 生命周期与杂项**
|
|
35
|
+
- `roll-onboard` — 存量项目交互式接入
|
|
36
|
+
- `roll-propose` — 产品视角提案生成(只进 proposals,不直写 backlog)
|
|
37
|
+
- `roll-.changelog` — Done 卡 → 用户 changelog(含验收证据 marker 约定)
|
|
38
|
+
- `roll-deck` — 双语 18 页 deck 生成
|
|
39
|
+
- `roll-debug` — 网页黑盒诊断探针
|
|
40
|
+
- `roll-.clarify` / `roll-.echo` — 模糊输入的被动澄清
|
|
41
|
+
|
|
42
|
+
> Each skill's full contract lives in `<skill>/SKILL.md`. Dot-prefixed skills
|
|
43
|
+
> (`roll-.x`) are passive/auto-triggered. 每个技能的完整契约在各自的
|
|
44
|
+
> `SKILL.md`;带点前缀的为被动技能,自动触发。
|
|
45
|
+
|
|
46
|
+
## Editing · 修改约定
|
|
47
|
+
|
|
48
|
+
Skills are prose contracts — edit the markdown, PR to `main`, then bump the
|
|
49
|
+
`skills/` submodule pointer in the main repo. Conventions (bilingual output,
|
|
50
|
+
backlog write-back rules, evidence chain) are defined by the main repo's
|
|
51
|
+
AGENTS.md and enforced there.
|
|
@@ -10,6 +10,19 @@ description: After build completion, extracts completed Stories from .roll/backl
|
|
|
10
10
|
|
|
11
11
|
After successful Build & Deploy, extracts completed Stories from .roll/backlog.md to generate a user-friendly `CHANGELOG.md`.
|
|
12
12
|
|
|
13
|
+
## Evidence marker(US-ATTEST-008 约定)
|
|
14
|
+
|
|
15
|
+
写入 CHANGELOG 的每个条目,若对应 story 存在验收报告
|
|
16
|
+
(`.roll/verification/<id>/latest/report.html`),在该 bullet 行的下一行追加
|
|
17
|
+
不可见注释 marker(GitHub Release body 不渲染,grep 可追溯):
|
|
18
|
+
|
|
19
|
+
```markdown
|
|
20
|
+
- 修复导出报表时间区间偏移(FIX-200)
|
|
21
|
+
<!-- evidence: .roll/verification/FIX-200/latest/report.html -->
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
报告不存在则不加(deletion-not-placeholder,与报告渲染同一契约)。
|
|
25
|
+
|
|
13
26
|
## When Triggered
|
|
14
27
|
|
|
15
28
|
- **Auto-triggered**: After successful deploy of `$roll-build` or `$roll-fix`
|
|
@@ -572,14 +572,34 @@ Follow the repo's deployment path (Vercel / Railway / etc.) and record the deplo
|
|
|
572
572
|
|
|
573
573
|
**Hard Rule**: "I confirmed the tests passed" does not count as evidence. Must be **freshly run** command output from this session.
|
|
574
574
|
|
|
575
|
+
### Phase 10.6: Acceptance Evidence (after Gate PASS)
|
|
576
|
+
|
|
577
|
+
Runs ONLY on a ✅ Gate PASS (a FAIL retry must not mint a misleading report). Non-blocking: any failure here → WARN, continue to Phase 11.
|
|
578
|
+
|
|
579
|
+
1. **Dump raw evidence** produced in this session to story-level dirs:
|
|
580
|
+
`.roll/verification/{ID}/evidence/*.txt` (command outputs, curl, logs) and
|
|
581
|
+
`.roll/verification/{ID}/screenshots/*.png` (when the story has a UI surface — web/iOS/Android per project type).
|
|
582
|
+
2. **Write the intent map** `.roll/verification/{ID}/ac-map.json` — for EVERY AC (ids `{ID}:AC1..n`) pick `pass|readonly|partial|claimed|missing` and reference only evidence that exists (paths relative to the run dir; story-level dirs are reachable as `../evidence/...` / `../screenshots/...`):
|
|
583
|
+
|
|
584
|
+
```json
|
|
585
|
+
[{ "ac": "{ID}:AC1", "status": "pass",
|
|
586
|
+
"evidence": [{ "kind": "text", "label": "vitest", "textFile": "../evidence/vitest.txt" }] }]
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
No evidence for an AC → say `claimed` yourself; the renderer enforces that downgrade anyway (red line) and lists it under Discrepancies.
|
|
590
|
+
3. **Run** `roll attest {ID}` (add `--deploy-url <url>` when one exists). The report lands at `.roll/verification/{ID}/latest/report.html`.
|
|
591
|
+
|
|
575
592
|
### Phase 11: Write Back Status (REQUIRED)
|
|
576
593
|
|
|
577
594
|
Both locations must be updated — neither can be skipped:
|
|
578
595
|
|
|
579
596
|
**① Update .roll/backlog.md index row (Status column):**
|
|
580
597
|
|
|
598
|
+
**Location rule (FIX-198)**: edit the MAIN project's backlog by ABSOLUTE path — `${ROLL_MAIN_PROJECT:-$PWD}/.roll/backlog.md`. In ordinary projects the cycle worktree has NO `.roll/` (gitignored, never checked out): a relative `.roll/backlog.md` edit writes into the void and the flip silently vanishes.
|
|
599
|
+
|
|
600
|
+
|
|
581
601
|
```markdown
|
|
582
|
-
| [US-{ID}](.roll/features/<feature>.md#us-{id}) | {Title} | ✅ Done |
|
|
602
|
+
| [US-{ID}](.roll/features/<feature>.md#us-{id}) | {Title} | ✅ Done · [evidence](.roll/verification/US-{ID}/latest/report.html) |
|
|
583
603
|
```
|
|
584
604
|
|
|
585
605
|
Change the Status from `📋 Todo` or `🔨 In Progress` (whichever the row currently shows) to `✅ Done`. When invoked by `roll-loop`, the row will already be `🔨 In Progress` — that is the expected starting state, and the transition is the same Edit operation.
|
package/skills/roll-fix/SKILL.md
CHANGED
|
@@ -339,6 +339,23 @@ Verify the shipped fix on the deployed target:
|
|
|
339
339
|
|
|
340
340
|
**Hard Rule**: "I confirm tests passed" does not count as evidence. It must be **freshly run** command output from this session.
|
|
341
341
|
|
|
342
|
+
### 10.6: Acceptance Evidence (after Gate PASS)
|
|
343
|
+
|
|
344
|
+
Runs ONLY on a ✅ Gate PASS (a FAIL retry must not mint a misleading report). Non-blocking: any failure here → WARN, continue to Step 11.
|
|
345
|
+
|
|
346
|
+
1. **Dump raw evidence** produced in this session to story-level dirs:
|
|
347
|
+
`.roll/verification/{ID}/evidence/*.txt` (command outputs, curl, logs) and
|
|
348
|
+
`.roll/verification/{ID}/screenshots/*.png` (when the story has a UI surface — web/iOS/Android per project type).
|
|
349
|
+
2. **Write the intent map** `.roll/verification/{ID}/ac-map.json` — for EVERY AC (ids `{ID}:AC1..n`) pick `pass|readonly|partial|claimed|missing` and reference only evidence that exists (paths relative to the run dir; story-level dirs are reachable as `../evidence/...` / `../screenshots/...`):
|
|
350
|
+
|
|
351
|
+
```json
|
|
352
|
+
[{ "ac": "{ID}:AC1", "status": "pass",
|
|
353
|
+
"evidence": [{ "kind": "text", "label": "vitest", "textFile": "../evidence/vitest.txt" }] }]
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
No evidence for an AC → say `claimed` yourself; the renderer enforces that downgrade anyway (red line) and lists it under Discrepancies.
|
|
357
|
+
3. **Run** `roll attest {ID}` (add `--deploy-url <url>` when one exists). The report lands at `.roll/verification/{ID}/latest/report.html`.
|
|
358
|
+
|
|
342
359
|
### 11. Write Back Status (when tracking is needed)
|
|
343
360
|
|
|
344
361
|
Only update when Hard Rule #6 conditions are met (user requested, affects roadmap-visible behavior, or needs follow-up tracking).
|
|
@@ -347,8 +364,11 @@ Both locations must be updated — neither can be skipped:
|
|
|
347
364
|
|
|
348
365
|
**① Update .roll/backlog.md index row (Status column):**
|
|
349
366
|
|
|
367
|
+
**Location rule (FIX-198)**: edit the MAIN project's backlog by ABSOLUTE path — `${ROLL_MAIN_PROJECT:-$PWD}/.roll/backlog.md`. In ordinary projects the cycle worktree has NO `.roll/` (gitignored, never checked out): a relative `.roll/backlog.md` edit writes into the void and the flip silently vanishes.
|
|
368
|
+
|
|
369
|
+
|
|
350
370
|
```markdown
|
|
351
|
-
| [FIX-{ID}](.roll/features/<feature>.md#fix-{id}) | {Title} | ✅ Done |
|
|
371
|
+
| [FIX-{ID}](.roll/features/<feature>.md#fix-{id}) | {Title} | ✅ Done · [evidence](.roll/verification/FIX-{ID}/latest/report.html) |
|
|
352
372
|
```
|
|
353
373
|
|
|
354
374
|
Change the Status of the corresponding row from `📋 Todo` or `🔨 In Progress` (whichever the row currently shows) to `✅ Done`. When invoked by `roll-loop`, the row will already be `🔨 In Progress` — that is the expected starting state.
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# dream-test-quality-scan — ad-hoc helper for roll-.dream Scan 7.
|
|
3
|
-
#
|
|
4
|
-
# Walks bats files and flags ❶-class anti-patterns (hardcoded business data
|
|
5
|
-
# in assertion bodies). Emits structured REFACTOR-shaped lines so the
|
|
6
|
-
# maintainer can sanity-check the rubric against the current suite without
|
|
7
|
-
# waiting for the nightly dream cycle.
|
|
8
|
-
#
|
|
9
|
-
# Usage:
|
|
10
|
-
# dream-test-quality-scan [--category N] [--path PATH] [--max N]
|
|
11
|
-
# dream-test-quality-scan --help
|
|
12
|
-
#
|
|
13
|
-
# Only category 1 (❶ hardcoded business data) is implemented as a deterministic
|
|
14
|
-
# heuristic; categories ❷..❻ stay with the dream skill (AI agent applies the
|
|
15
|
-
# rubric). The helper exists so a smoke test and a maintainer dry-run can
|
|
16
|
-
# confirm ❶ detection keeps working as the suite evolves.
|
|
17
|
-
|
|
18
|
-
set -euo pipefail
|
|
19
|
-
|
|
20
|
-
CATEGORY=1
|
|
21
|
-
TARGET=""
|
|
22
|
-
MAX=5
|
|
23
|
-
|
|
24
|
-
usage() {
|
|
25
|
-
cat <<'EOF'
|
|
26
|
-
dream-test-quality-scan — Scan 7 ❶ dry-run helper
|
|
27
|
-
|
|
28
|
-
Usage:
|
|
29
|
-
dream-test-quality-scan [--category N] [--path PATH] [--max N]
|
|
30
|
-
dream-test-quality-scan --help
|
|
31
|
-
|
|
32
|
-
Options:
|
|
33
|
-
--category N Anti-pattern category (only 1 is implemented; default 1)
|
|
34
|
-
--path PATH File or directory to scan (default: tests/)
|
|
35
|
-
--max N Maximum entries to emit (default: 5; matches dream skill cap)
|
|
36
|
-
--help Show this message
|
|
37
|
-
|
|
38
|
-
Output:
|
|
39
|
-
One line per finding:
|
|
40
|
-
[test-quality:❶] <file>:<line> — <one-line description>
|
|
41
|
-
Exit code is 0 even when nothing is found (dry-run is informational).
|
|
42
|
-
EOF
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
while [[ $# -gt 0 ]]; do
|
|
46
|
-
case "$1" in
|
|
47
|
-
--category) CATEGORY="${2:-1}"; shift 2 ;;
|
|
48
|
-
--path) TARGET="${2:-}"; shift 2 ;;
|
|
49
|
-
--max) MAX="${2:-5}"; shift 2 ;;
|
|
50
|
-
--help|-h) usage; exit 0 ;;
|
|
51
|
-
*) echo "unknown flag: $1" >&2; usage >&2; exit 2 ;;
|
|
52
|
-
esac
|
|
53
|
-
done
|
|
54
|
-
|
|
55
|
-
if [[ "$CATEGORY" -ne 1 ]]; then
|
|
56
|
-
echo "category $CATEGORY not yet implemented — only ❶ is mechanical" >&2
|
|
57
|
-
exit 0
|
|
58
|
-
fi
|
|
59
|
-
|
|
60
|
-
# Default scan root.
|
|
61
|
-
if [[ -z "$TARGET" ]]; then
|
|
62
|
-
repo_root=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
63
|
-
TARGET="${repo_root}/tests"
|
|
64
|
-
fi
|
|
65
|
-
|
|
66
|
-
if [[ ! -e "$TARGET" ]]; then
|
|
67
|
-
echo "path not found: $TARGET" >&2
|
|
68
|
-
exit 2
|
|
69
|
-
fi
|
|
70
|
-
|
|
71
|
-
scan_file() {
|
|
72
|
-
local file="$1"
|
|
73
|
-
# ❶ heuristic — assertion lines whose RHS contains a numeric literal:
|
|
74
|
-
# - lines containing `[[` or `[ ` (bats assertion syntax)
|
|
75
|
-
# - AND containing `==` or `=` (equality)
|
|
76
|
-
# - AND containing a decimal/integer literal of length ≥ 1 inside quotes
|
|
77
|
-
# Emits one entry per file (not per line) to stay under the rate cap.
|
|
78
|
-
local first_hit
|
|
79
|
-
first_hit=$(grep -nE '\[\[.*"[^"]*[0-9]+(\.[0-9]+)?[^"]*"' "$file" 2>/dev/null \
|
|
80
|
-
| head -1 || true)
|
|
81
|
-
[[ -z "$first_hit" ]] && return 1
|
|
82
|
-
|
|
83
|
-
local lineno
|
|
84
|
-
lineno=$(echo "$first_hit" | cut -d: -f1)
|
|
85
|
-
local rel
|
|
86
|
-
rel=$(python3 -c "import os,sys; print(os.path.relpath(sys.argv[1]))" "$file" 2>/dev/null || echo "$file")
|
|
87
|
-
printf '[test-quality:❶] %s:%s — assertion body hardcodes a numeric literal that likely owns its value elsewhere\n' \
|
|
88
|
-
"$rel" "$lineno"
|
|
89
|
-
return 0
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
emitted=0
|
|
93
|
-
if [[ -d "$TARGET" ]]; then
|
|
94
|
-
# Iterate over .bats files under TARGET; stop after MAX hits.
|
|
95
|
-
# Exclude vendored bats-core helpers — those are framework tests, not ours.
|
|
96
|
-
while IFS= read -r f; do
|
|
97
|
-
case "$f" in
|
|
98
|
-
*/tests/helpers/bats-*/*) continue ;;
|
|
99
|
-
esac
|
|
100
|
-
if scan_file "$f"; then
|
|
101
|
-
emitted=$((emitted + 1))
|
|
102
|
-
[[ "$emitted" -ge "$MAX" ]] && break
|
|
103
|
-
fi
|
|
104
|
-
done < <(find "$TARGET" -type f -name '*.bats' | sort)
|
|
105
|
-
else
|
|
106
|
-
scan_file "$TARGET" && emitted=1 || true
|
|
107
|
-
fi
|
|
108
|
-
|
|
109
|
-
# Always succeed — dry-run is informational, the dream cycle decides what to do.
|
|
110
|
-
exit 0
|