@seanyao/roll 2026.507.3 → 2026.509.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/README.md CHANGED
@@ -192,7 +192,7 @@ For larger changes, open an issue first to discuss the approach.
192
192
 
193
193
  Roll builds on ideas and inspiration from the open-source community:
194
194
 
195
- - **[khazix-skills](https://github.com/KKKKhazix/khazix-skills)** by Digital Life Khazix — The HV Analysis (Horizontal-Vertical Analysis) deep research framework that powers `$roll-research` was adapted from this project.
195
+ - **[khazix-skills](https://github.com/KKKKhazix/khazix-skills)** by Digital Life Khazix — The HV Analysis (Horizontal-Vertical Analysis) deep research framework and schema used by `$roll-research` are derived from this project, used under the MIT License. Copyright (c) 2026 数字生命卡兹克.
196
196
  - **[superpowers](https://github.com/obra/superpowers)** by Jesse Vincent — A composable skills library for AI coding agents that informed several workflow patterns in Roll.
197
197
 
198
198
  ---
package/bin/roll CHANGED
@@ -4,7 +4,7 @@ set -euo pipefail
4
4
  # Roll — AI Agent Convention Manager
5
5
  # Single source of truth for how all AI coding agents behave.
6
6
 
7
- VERSION="2026.507.3"
7
+ VERSION="2026.509.1"
8
8
  ROLL_HOME="${ROLL_HOME:-${HOME}/.roll}"
9
9
  ROLL_CONFIG="${ROLL_HOME}/config.yaml"
10
10
  ROLL_GLOBAL="${ROLL_HOME}/conventions/global"
@@ -539,6 +539,11 @@ cmd_setup() {
539
539
  echo ""
540
540
  _sync_skills "$force"
541
541
 
542
+ echo ""
543
+ info "Setting up peer review state... 正在初始化 peer review 状态..."
544
+ _peer_ensure_state_dir
545
+ ok "Peer state directory ready. Peer 状态目录已就绪。"
546
+
542
547
  echo ""
543
548
  ok "Setup complete. 初始化完成。"
544
549
 
@@ -1220,6 +1225,416 @@ check_sync_status() {
1220
1225
  fi
1221
1226
  }
1222
1227
 
1228
+ # ═══════════════════════════════════════════════════════════════════════════════
1229
+ # PEER REVIEW
1230
+ # ═══════════════════════════════════════════════════════════════════════════════
1231
+
1232
+ _PEER_STATE_DIR="${ROLL_HOME}/.peer-state"
1233
+
1234
+ _peer_ensure_state_dir() {
1235
+ mkdir -p "$_PEER_STATE_DIR"
1236
+ mkdir -p "${_PEER_STATE_DIR}/logs"
1237
+ }
1238
+
1239
+ _peer_state_file() {
1240
+ local pair="$1"
1241
+ local key="$2"
1242
+ echo "${_PEER_STATE_DIR}/${pair}_${key}"
1243
+ }
1244
+
1245
+ _peer_get_state() {
1246
+ local pair="$1"
1247
+ local key="$2"
1248
+ local file
1249
+ file="$(_peer_state_file "$pair" "$key")"
1250
+ if [[ -f "$file" ]]; then
1251
+ cat "$file"
1252
+ else
1253
+ echo ""
1254
+ fi
1255
+ }
1256
+
1257
+ _peer_set_state() {
1258
+ local pair="$1"
1259
+ local key="$2"
1260
+ local val="$3"
1261
+ _peer_ensure_state_dir
1262
+ printf '%s\n' "$val" > "$(_peer_state_file "$pair" "$key")"
1263
+ }
1264
+
1265
+ _peer_normalize_pair() {
1266
+ local from="$1"
1267
+ local to="$2"
1268
+ printf '%s→%s\n' "$from" "$to"
1269
+ }
1270
+
1271
+ _peer_detect_peers() {
1272
+ local peers=""
1273
+ for tool in claude kimi pi codex opencode cursor; do
1274
+ if command -v "$tool" &>/dev/null; then
1275
+ peers="${peers}${peers:+ }${tool}"
1276
+ fi
1277
+ done
1278
+ printf '%s\n' "$peers"
1279
+ }
1280
+
1281
+ _peer_route() {
1282
+ local from="$1"
1283
+ local tag="${2:-default}"
1284
+
1285
+ local map_val
1286
+ map_val="$(config_get "peer_capability_map_${tag}" "")"
1287
+ if [[ -z "$map_val" ]]; then
1288
+ map_val="$(config_get "peer_capability_map_default" "kimi claude pi")"
1289
+ fi
1290
+
1291
+ local installed
1292
+ installed="$(_peer_detect_peers)"
1293
+
1294
+ local candidate
1295
+ for candidate in $map_val; do
1296
+ [[ "$candidate" == "$from" ]] && continue
1297
+ if echo "$installed" | grep -qw "$candidate"; then
1298
+ local pair status
1299
+ pair="$(_peer_normalize_pair "$from" "$candidate")"
1300
+ status="$(_peer_get_state "$pair" "status")"
1301
+ if [[ "$status" != "abandoned" ]]; then
1302
+ printf '%s\n' "$candidate"
1303
+ return 0
1304
+ fi
1305
+ fi
1306
+ done
1307
+
1308
+ printf '%s\n' ""
1309
+ return 1
1310
+ }
1311
+
1312
+ _peer_call() {
1313
+ local to="$1"
1314
+ local prompt="$2"
1315
+ local output=""
1316
+ local stderr_log
1317
+ stderr_log="${_PEER_STATE_DIR}/logs/.last_stderr.log"
1318
+ local call_timeout
1319
+ call_timeout="$(config_get "peer_call_timeout" "180")"
1320
+
1321
+ info "Peer call timeout: ${call_timeout}s Peer 调用超时: ${call_timeout}s"
1322
+
1323
+ case "$to" in
1324
+ claude)
1325
+ output="$(claude -p --output-format text "$prompt" 2>"$stderr_log" || true)"
1326
+ ;;
1327
+ kimi)
1328
+ output="$(kimi --quiet -p "$prompt" 2>"$stderr_log" || true)"
1329
+ ;;
1330
+ pi)
1331
+ output="$(pi -p --mode text "$prompt" 2>"$stderr_log" || true)"
1332
+ ;;
1333
+ *)
1334
+ err "Unsupported peer: $to 不支持的 peer: $to"
1335
+ return 1
1336
+ ;;
1337
+ esac
1338
+
1339
+ printf '%s\n' "$output"
1340
+ }
1341
+
1342
+ _peer_parse_resolution() {
1343
+ local output="$1"
1344
+ local resolution
1345
+ # Match AGREE/REFINE/OBJECT/ESCALATE near line start (only non-letters before it)
1346
+ # Covers: **AGREE**, ### 结论:AGREE, - AGREE:, * REFINE, OBJECT — ...
1347
+ resolution="$(printf '%s\n' "$output" | grep -oiE '^[^a-zA-Z]*\b(AGREE|REFINE|OBJECT|ESCALATE)\b' | head -1 | grep -oiE '\b(AGREE|REFINE|OBJECT|ESCALATE)\b' | tr '[:lower:]' '[:upper:]')"
1348
+ printf '%s\n' "$resolution"
1349
+ }
1350
+
1351
+ _peer_update_state() {
1352
+ local pair="$1"
1353
+ local outcome="$2"
1354
+ local streak=0
1355
+
1356
+ local prev_streak
1357
+ prev_streak="$(_peer_get_state "$pair" "streak")"
1358
+ if [[ "$prev_streak" =~ ^[0-9]+$ ]]; then
1359
+ streak="$prev_streak"
1360
+ fi
1361
+
1362
+ if [[ "$outcome" == "AGREE" ]]; then
1363
+ streak=0
1364
+ _peer_set_state "$pair" "status" "active"
1365
+ else
1366
+ streak=$((streak + 1))
1367
+ if [[ "$streak" -ge 3 ]]; then
1368
+ _peer_set_state "$pair" "status" "abandoned"
1369
+ else
1370
+ _peer_set_state "$pair" "status" "degraded"
1371
+ fi
1372
+ fi
1373
+
1374
+ _peer_set_state "$pair" "streak" "$streak"
1375
+ _peer_set_state "$pair" "last_outcome" "$outcome"
1376
+ _peer_set_state "$pair" "last_time" "$(date -Iseconds)"
1377
+ }
1378
+
1379
+ cmd_peer() {
1380
+ local from_tool=""
1381
+ local to_tool=""
1382
+ local round=1
1383
+ local tag="default"
1384
+ local context_file=""
1385
+ local yolo=false
1386
+ local subcmd=""
1387
+
1388
+ while [[ $# -gt 0 ]]; do
1389
+ case "$1" in
1390
+ --from) from_tool="$2"; shift 2 ;;
1391
+ --to) to_tool="$2"; shift 2 ;;
1392
+ --round) round="$2"; shift 2 ;;
1393
+ --tag) tag="$2"; shift 2 ;;
1394
+ --context) context_file="$2"; shift 2 ;;
1395
+ --yes|--yolo) yolo=true; shift ;;
1396
+ status) subcmd="status"; shift ;;
1397
+ reset) subcmd="reset"; shift; break ;;
1398
+ help|--help|-h) subcmd="help"; shift ;;
1399
+ *) err "Unknown option: $1 未知选项: $1"; exit 1 ;;
1400
+ esac
1401
+ done
1402
+
1403
+ case "$subcmd" in
1404
+ status) cmd_peer_status; return ;;
1405
+ reset) cmd_peer_reset "$@"; return ;;
1406
+ help) cmd_peer_help; return ;;
1407
+ esac
1408
+
1409
+ if [[ -z "$from_tool" ]]; then
1410
+ err "--from is required. 必须指定 --from。"
1411
+ echo ""
1412
+ cmd_peer_help
1413
+ exit 1
1414
+ fi
1415
+
1416
+ if [[ -z "$to_tool" ]]; then
1417
+ to_tool="$(_peer_route "$from_tool" "$tag")"
1418
+ if [[ -z "$to_tool" ]]; then
1419
+ err "No available peer found for tag '$tag'. 未找到 tag '$tag' 的可用 peer。"
1420
+ echo ""
1421
+ info "Installed peers: $(_peer_detect_peers)"
1422
+ info "Capability map: $(config_get "peer_capability_map_${tag}" "$(config_get "peer_capability_map_default" "kimi claude pi")")"
1423
+ exit 1
1424
+ fi
1425
+ info "Auto-selected peer: $to_tool 自动选择 peer: $to_tool"
1426
+ fi
1427
+
1428
+ local pair
1429
+ pair="$(_peer_normalize_pair "$from_tool" "$to_tool")"
1430
+
1431
+ local status
1432
+ status="$(_peer_get_state "$pair" "status")"
1433
+ if [[ "$status" == "abandoned" ]]; then
1434
+ err "Peer pair $pair is abandoned. Run 'roll peer reset $from_tool $to_tool' to restore. Peer 对 $pair 已废弃。运行 'roll peer reset $from_tool $to_tool' 恢复。"
1435
+ exit 1
1436
+ fi
1437
+
1438
+ if [[ "$yolo" != "true" ]]; then
1439
+ local opt_out
1440
+ opt_out="$(config_get "peer_opt_out_seconds" "10")"
1441
+ info "Launching peer review: $from_tool → $to_tool (round $round, tag: $tag)"
1442
+ info "Press Enter to proceed or type 'n' to abort. Auto-executing in ${opt_out}s..."
1443
+ info "启动 peer review: $from_tool → $to_tool (第 $round 轮, tag: $tag)"
1444
+ info "按 Enter 执行或输入 n 取消。${opt_out} 秒后自动执行..."
1445
+
1446
+ local answer=""
1447
+ if IFS= read -r -t "$opt_out" answer 2>/dev/null; then
1448
+ if [[ "$answer" == "n" || "$answer" == "N" ]]; then
1449
+ info "Peer review aborted by user. 用户取消 peer review。"
1450
+ exit 0
1451
+ fi
1452
+ fi
1453
+ fi
1454
+
1455
+ local context=""
1456
+ if [[ -n "$context_file" && -f "$context_file" ]]; then
1457
+ context="$(cat "$context_file")"
1458
+ fi
1459
+
1460
+ local prompt
1461
+ prompt="[PEER_REVIEW round=${round} tool=${from_tool}→${to_tool}]\n\n${context}"
1462
+
1463
+ _peer_ensure_state_dir
1464
+ local log_file
1465
+ log_file="${_PEER_STATE_DIR}/logs/$(date +%Y%m%d_%H%M%S)_${from_tool}_${to_tool}.md"
1466
+ {
1467
+ echo "# Peer Review Log"
1468
+ echo ""
1469
+ echo "- **From**: $from_tool"
1470
+ echo "- **To**: $to_tool"
1471
+ echo "- **Round**: $round"
1472
+ echo "- **Tag**: $tag"
1473
+ echo "- **Time**: $(date -Iseconds)"
1474
+ echo ""
1475
+ echo "## Prompt"
1476
+ echo ""
1477
+ echo '```'
1478
+ printf '%s\n' "$prompt"
1479
+ echo '```'
1480
+ echo ""
1481
+ echo "## Response"
1482
+ echo ""
1483
+ } > "$log_file"
1484
+
1485
+ info "Calling $to_tool... 调用 $to_tool..."
1486
+ local response
1487
+ response="$(_peer_call "$to_tool" "$prompt")"
1488
+
1489
+ local stderr_log
1490
+ stderr_log="${_PEER_STATE_DIR}/logs/.last_stderr.log"
1491
+ if [[ -f "$stderr_log" && -s "$stderr_log" ]]; then
1492
+ echo ""
1493
+ echo -e "${BOLD}Peer stderr Peer 标准错误:${NC}"
1494
+ cat "$stderr_log"
1495
+ echo ""
1496
+ fi
1497
+
1498
+ printf '%s\n' "$response" >> "$log_file"
1499
+
1500
+ local resolution
1501
+ resolution="$(_peer_parse_resolution "$response")"
1502
+
1503
+ if [[ -z "$resolution" ]]; then
1504
+ warn "Could not parse resolution from peer response. 无法解析 peer 响应中的决议状态。"
1505
+ resolution="UNKNOWN"
1506
+ fi
1507
+
1508
+ _peer_update_state "$pair" "$resolution"
1509
+
1510
+ echo ""
1511
+ echo -e "${BOLD}Peer Review Result Peer Review 结果${NC}"
1512
+ echo " Pair: $pair"
1513
+ echo " Round: $round"
1514
+ echo " Resolution: $resolution"
1515
+ echo ""
1516
+
1517
+ case "$resolution" in
1518
+ AGREE)
1519
+ ok "Consensus reached. Proceed with execution. 达成共识,继续执行。"
1520
+ ;;
1521
+ REFINE|OBJECT)
1522
+ if [[ "$round" -ge 3 ]]; then
1523
+ warn "Max rounds reached. Escalating to user. 达到最大轮数,升级给用户。"
1524
+ else
1525
+ info "Peer requests $resolution. Continue to round $((round + 1)). Peer 请求 $resolution,继续第 $((round + 1)) 轮。"
1526
+ fi
1527
+ ;;
1528
+ ESCALATE|UNKNOWN)
1529
+ warn "Peer review escalated or failed. Human decision required. Peer review 升级或失败,需要人类决策。"
1530
+ ;;
1531
+ esac
1532
+
1533
+ echo ""
1534
+ info "Log: $log_file"
1535
+
1536
+ case "$resolution" in
1537
+ AGREE) exit 0 ;;
1538
+ REFINE|OBJECT) exit 2 ;;
1539
+ *) exit 1 ;;
1540
+ esac
1541
+ }
1542
+
1543
+ cmd_peer_status() {
1544
+ _peer_ensure_state_dir
1545
+ echo -e "${BOLD}Peer Review Status Peer Review 状态${NC}"
1546
+ echo ""
1547
+
1548
+ local found=0
1549
+ local status_file
1550
+ for status_file in "$_PEER_STATE_DIR"/*_status; do
1551
+ [[ -f "$status_file" ]] || continue
1552
+ found=1
1553
+ local pair status streak last_outcome last_time
1554
+ pair="$(basename "$status_file" | sed 's/_status$//')"
1555
+ status="$(_peer_get_state "$pair" "status")"
1556
+ streak="$(_peer_get_state "$pair" "streak")"
1557
+ last_outcome="$(_peer_get_state "$pair" "last_outcome")"
1558
+ last_time="$(_peer_get_state "$pair" "last_time")"
1559
+
1560
+ local sc="$GREEN"
1561
+ [[ "$status" == "degraded" ]] && sc="$YELLOW"
1562
+ [[ "$status" == "abandoned" ]] && sc="$RED"
1563
+
1564
+ echo -e " ${sc}${pair}${NC}"
1565
+ echo " Status: ${status:-active}"
1566
+ echo " Streak: ${streak:-0}"
1567
+ echo " Last: ${last_outcome:-none} @ ${last_time:-never}"
1568
+ echo ""
1569
+ done
1570
+
1571
+ if [[ "$found" -eq 0 ]]; then
1572
+ info "No peer review history yet. 暂无 peer review 记录。"
1573
+ fi
1574
+
1575
+ echo ""
1576
+ info "Installed peers: $(_peer_detect_peers)"
1577
+ }
1578
+
1579
+ cmd_peer_reset() {
1580
+ local target_pair=""
1581
+ local reset_all=false
1582
+
1583
+ while [[ $# -gt 0 ]]; do
1584
+ case "$1" in
1585
+ --all) reset_all=true; shift ;;
1586
+ --from|--to|--round|--tag|--context|--yes|--yolo|status|reset|help|--help|-h) shift ;;
1587
+ *)
1588
+ if [[ -z "$target_pair" ]]; then
1589
+ target_pair="$1"
1590
+ fi
1591
+ shift
1592
+ ;;
1593
+ esac
1594
+ done
1595
+
1596
+ _peer_ensure_state_dir
1597
+
1598
+ if [[ "$reset_all" == "true" ]]; then
1599
+ rm -f "$_PEER_STATE_DIR"/*_status
1600
+ rm -f "$_PEER_STATE_DIR"/*_streak
1601
+ rm -f "$_PEER_STATE_DIR"/*_last_outcome
1602
+ rm -f "$_PEER_STATE_DIR"/*_last_time
1603
+ ok "All peer states reset. 所有 peer 状态已重置。"
1604
+ return
1605
+ fi
1606
+
1607
+ if [[ -z "$target_pair" ]]; then
1608
+ err "Usage: roll peer reset <from>→<to> | --all 用法: roll peer reset <from>→<to> | --all"
1609
+ exit 1
1610
+ fi
1611
+
1612
+ rm -f "$(_peer_state_file "$target_pair" "status")"
1613
+ rm -f "$(_peer_state_file "$target_pair" "streak")"
1614
+ rm -f "$(_peer_state_file "$target_pair" "last_outcome")"
1615
+ rm -f "$(_peer_state_file "$target_pair" "last_time")"
1616
+ ok "Peer state reset: $target_pair Peer 状态已重置: $target_pair"
1617
+ }
1618
+
1619
+ cmd_peer_help() {
1620
+ echo -e "${BOLD}roll peer — Cross-Agent Peer Review${NC}"
1621
+ echo ""
1622
+ echo "Usage: roll peer [options] 用法: roll peer [选项]"
1623
+ echo ""
1624
+ echo "Options:"
1625
+ echo " --from <tool> Originating agent (kimi, claude, pi) 发起方"
1626
+ echo " --to <tool> Target peer (auto-detected if omitted) 对端 peer(省略则自动选择)"
1627
+ echo " --round <N> Current round (default: 1) 当前轮数"
1628
+ echo " --tag <type> Task type for routing (architecture, security, test...) 任务类型"
1629
+ echo " --context <file> Context file to send to peer 上下文文件"
1630
+ echo " --yes, --yolo Skip opt-out prompt 跳过确认提示"
1631
+ echo ""
1632
+ echo "Subcommands:"
1633
+ echo " status Show peer review state 显示状态"
1634
+ echo " reset <pair|--all> Reset peer state 重置状态"
1635
+ echo " help Show this help 显示帮助"
1636
+ }
1637
+
1223
1638
  # ═══════════════════════════════════════════════════════════════════════════════
1224
1639
  # MAIN
1225
1640
  # ═══════════════════════════════════════════════════════════════════════════════
@@ -1241,6 +1656,7 @@ usage() {
1241
1656
  echo " update [Upgrade] npm install latest + re-sync 一键升级到最新版"
1242
1657
  echo " init [Project] Create AGENTS.md + BACKLOG.md + docs/ 初始化项目工作流文件"
1243
1658
  echo " status [Diagnostic] Show current state 显示当前状态"
1659
+ echo " peer [Peer Review] Cross-agent negotiation 跨 Agent 协商对审"
1244
1660
  echo ""
1245
1661
  echo "Examples / 示例:"
1246
1662
  echo " roll setup # New machine: first-time install 新机器首次安装"
@@ -1258,6 +1674,7 @@ main() {
1258
1674
  update) cmd_update "$@" ;;
1259
1675
  init) cmd_init "$@" ;;
1260
1676
  status) cmd_status "$@" ;;
1677
+ peer) cmd_peer "$@" ;;
1261
1678
  version|--version|-v) echo "roll v${VERSION}" ;;
1262
1679
  help|--help|-h|"") usage ;;
1263
1680
  *)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seanyao/roll",
3
- "version": "2026.507.3",
3
+ "version": "2026.509.1",
4
4
  "description": "Roll — Roll out features with AI agents",
5
5
  "scripts": {
6
6
  "test": "find tests/unit tests/integration -name '*.bats' | sort | xargs ./tests/helpers/bats-core/bin/bats"
@@ -2,7 +2,6 @@
2
2
  hidden: true
3
3
  name: roll-.changelog
4
4
  license: MIT
5
- model: haiku
6
5
  allowed-tools: "Read, Edit, Write, Bash(git:*)"
7
6
  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.
8
7
  ---
@@ -2,7 +2,6 @@
2
2
  hidden: true
3
3
  name: roll-.review
4
4
  license: MIT
5
- model: sonnet
6
5
  allowed-tools: "Read, Bash(git:*)"
7
6
  description: Self code review step in the TCR workflow. Runs after each micro-step is completed and before commit, checking code quality, security, and design issues.
8
7
  ---
@@ -173,6 +173,33 @@ Proceed to the **Shared TCR Workflow** (Phase 4 onward).
173
173
 
174
174
  The following phases apply to both Story mode and Fly mode after planning is complete.
175
175
 
176
+ ### Phase 3.5: Peer Review Gate
177
+
178
+ After planning is complete, before entering Test Design Review, assess whether the plan warrants peer review:
179
+
180
+ **Auto-trigger `$roll-peer` when any of the following is true:**
181
+ - Plan affects **>3 files** or **crosses modules**
182
+ - **Architecture decisions** or non-obvious trade-offs are involved
183
+ - **Destructive / irreversible operations** (deletions, migrations, production deploys)
184
+ - **High-risk signal words** detected in user request ("critical / important / don't break / 关键 / 别搞砸")
185
+ - User explicitly requests peer review ("/peer", "叫上 peer")
186
+
187
+ **With 10s opt-out:**
188
+ ```
189
+ Plan affects N files across M modules. Estimated peer review: 2–3 rounds, ~X tokens.
190
+ Press Enter to launch peer review, or type 'n' to skip. Auto-executing in 10s...
191
+ ```
192
+
193
+ **After peer review result:**
194
+ - **AGREE** → proceed to Phase 4 (Test Design Review)
195
+ - **REFINE** → incorporate feedback, regenerate plan, re-run Phase 3.5
196
+ - **OBJECT** → consider alternative plan, re-run Phase 3.5 with revised proposal
197
+ - **ESCALATE** → present both proposals to user for final decision before proceeding
198
+
199
+ **Never trigger:**
200
+ - Single-file changes or well-defined fixes
201
+ - Plans with no cross-module impact and no architecture decisions
202
+
176
203
  ### Phase 4: Test Design Review
177
204
 
178
205
  Before writing implementation code:
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: roll-design
3
3
  license: MIT
4
- model: sonnet
5
4
  allowed-tools: "Read, Edit, Write, Glob, Grep, Bash(git:*), WebSearch, WebFetch, Skill"
6
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 BACKLOG.md. Use when user wants to discuss approaches, design solutions, plan features, or create stories.
7
6
  ---
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: roll-doctor
3
3
  license: MIT
4
- model: haiku
5
4
  allowed-tools: "Read, Bash, Edit"
6
5
  description: "Diagnose Roll toolchain health. Checks skill files, YAML frontmatter, symlinks, conventions sync, template integrity, and config validity."
7
6
  ---
@@ -113,6 +112,30 @@ Check:
113
112
  - File exists and is valid YAML
114
113
  - Has required `ai_tool_name` or `ai_claude` entries
115
114
 
115
+ ### 7. Peer Review
116
+
117
+ ```bash
118
+ # Peer state directory
119
+ ls -la ~/.roll/.peer-state/ 2>/dev/null || echo "missing"
120
+
121
+ # Peer config in config.yaml
122
+ grep "peer_" ~/.roll/config.yaml 2>/dev/null || echo "no peer config"
123
+
124
+ # Available peer CLIs
125
+ for tool in claude kimi pi codex; do
126
+ command -v "$tool" &>/dev/null && echo "✓ $tool" || echo "✗ $tool"
127
+ done
128
+
129
+ # roll-peer skill
130
+ ls ~/.roll/skills/roll-peer/SKILL.md 2>/dev/null || echo "missing"
131
+ ```
132
+
133
+ Check:
134
+ - `~/.roll/.peer-state/` exists and is writable
135
+ - `~/.roll/config.yaml` contains `peer_call_timeout` (default: 180)
136
+ - At least one peer CLI (claude / kimi / pi) is installed
137
+ - `roll-peer` skill exists
138
+
116
139
  ## Report Format
117
140
 
118
141
  ```
@@ -124,6 +147,7 @@ Check:
124
147
  [✓/✗] Conventions sync
125
148
  [✓/✗] Templates integrity
126
149
  [✓/✗] Config
150
+ [✓/✗] Peer Review
127
151
 
128
152
  ---
129
153
  Issues found: N
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: roll-jot
3
3
  license: MIT
4
- model: haiku
5
4
  allowed-tools: "Read, Edit"
6
5
  description: "Fast backlog capture. Analyzes a short description, classifies it as bug or idea, and appends it to BACKLOG.md with an auto-incremented ID."
7
6
  ---
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: roll-notes
3
3
  license: MIT
4
- model: haiku
5
4
  allowed-tools: "Read, Edit, Write, Bash(date:*)"
6
5
  description: "Project diary skill. Records development moments — successes, failures, discoveries — appended chronologically to a daily notes file."
7
6
  ---
@@ -0,0 +1,219 @@
1
+ ---
2
+ name: roll-peer
3
+ license: MIT
4
+ allowed-tools: "Read, Bash, Write, Edit"
5
+ description: |
6
+ Cross-agent peer review skill. When a task enters a decision phase (planning,
7
+ high-risk, ambiguous, destructive), triggers a bidirectional negotiation with
8
+ another AI agent via a unified protocol. Up to 3 rounds. If consensus is not
9
+ reached, escalates to the human user. Includes adaptive peer routing based on
10
+ task type and historical success rate.
11
+ Trigger: /peer, "叫上 peer", "peer review", or auto-triggered at workflow gates.
12
+ ---
13
+
14
+ # Roll Peer (Cross-Agent Peer Review)
15
+
16
+ > Follows the Architecture Constraints, Development Discipline, and Engineering
17
+ > Common Sense defined in the project AGENTS.md.
18
+
19
+ ## Credits
20
+
21
+ Cross-agent consultation protocol inspired by
22
+ [friend-skill](https://github.com/fpyluck/friend-skill) (MIT) by fpyluck.
23
+ Independent implementation for the Roll toolchain.
24
+
25
+ ## Trigger
26
+
27
+ **Manual:**
28
+ - `/peer`
29
+ - "叫上 peer"
30
+ - "peer review 一下"
31
+ - "和 peer 商量"
32
+
33
+ **Auto-triggered (with 10s opt-out):**
34
+ - `roll-build` enters Plan Mode (executable plans / architecture decisions)
35
+ - `roll-spar` Attacker and Defender disagree
36
+ - High context pressure (large number of files read / tools executed)
37
+ - Destructive / irreversible operations (`rm -rf`, production deploy, global config changes)
38
+ - High-risk signal words ("重要 / 关键 / 别搞砸 / important / critical")
39
+ - Cross-repository / cross-toolchain / ambiguous permission boundaries
40
+
41
+ **Never trigger:**
42
+ - Single-file changes
43
+ - Clear, well-defined fixes
44
+ - Simple refactoring
45
+
46
+ ## Protocol: `[PEER_REVIEW]`
47
+
48
+ ### Marker Format
49
+
50
+ The marker **must** appear on the first non-empty line of the message:
51
+
52
+ ```markdown
53
+ [PEER_REVIEW round=N tool=<from>→<to>]
54
+ ```
55
+
56
+ - `round=N`: Current round number (1–3)
57
+ - `tool=<from>→<to>`: Direction of this message (e.g., `kimi→claude`)
58
+
59
+ ### Three-State Resolution + Escape
60
+
61
+ Allowed states only. No invented words.
62
+
63
+ - **AGREE**: Accept the current proposal. Proceed to execution.
64
+ - **REFINE**: Direction is correct, but specific changes are needed. Proceed to next round.
65
+ - **OBJECT**: The proposal is wrong. Provide an alternative. Proceed to next round.
66
+ - **ESCALATE**: Round 3 reached without AGREE, or a round fails due to API/token error. Hand off to the human user.
67
+
68
+ If information is insufficient:
69
+ ```
70
+ REFINE: Need to confirm X/Y/Z with the user first.
71
+ ```
72
+
73
+ ### Context Handoff Card (required for round=1)
74
+
75
+ When the task involves a local project, the first message must include:
76
+
77
+ ```markdown
78
+ ## Project Handoff (round=1 required)
79
+ - Project root: <absolute path>
80
+ - Execution environment: <shell / container / devcontainer / remote / N/A>
81
+ - Project type: <language + framework>
82
+ - Virtual environment: <absolute path / conda env / container name / N/A>
83
+ - Activation command: <one-line executable string, or N/A>
84
+ - Key tool calls:
85
+ - test: <one-line command or N/A>
86
+ - build: <one-line command or N/A>
87
+ - run: <one-line command or N/A>
88
+ - lint: <one-line command or N/A>
89
+ - Key conventions / constraints: <2–3 items, or N/A>
90
+ - Related file pointers: <absolute paths or @references, or N/A>
91
+ ```
92
+
93
+ Rules:
94
+ - Paths must be **absolute**.
95
+ - Commands must be **one-line executable strings**, not descriptions.
96
+ - Prefer commands that do **not** require an activated environment (absolute interpreter paths, `uv run`, `docker compose exec`).
97
+ - Do not copy README text. List file pointers only.
98
+ - Never include secrets, tokens, credentials, or `.env` content.
99
+ - Even if logically a continuation, treat as round=1 if the peer has **no prior context**.
100
+
101
+ ### Anti-Hallucination Rule
102
+
103
+ When mentioning specific paths, function names, commands, line numbers, or tool results, **must cite the source** ("I read X at line Y"). If unverified, state "unverified" explicitly.
104
+
105
+ ## State Machine
106
+
107
+ ### Per Negotiation (Single Task)
108
+
109
+ ```
110
+ Running
111
+ ├── AGREE (any round) → Execute proposal
112
+ ├── Round == 3, no AGREE → ESCALATE (failed_max_rounds)
113
+ ├── API/token error → ESCALATE (failed_api_error)
114
+ └── User aborts → ESCALATE (user_abort)
115
+ ```
116
+
117
+ ### Per Peer Pair (e.g., kimi→claude)
118
+
119
+ Stored in `~/.shared/roll/peer/state.yaml`:
120
+
121
+ ```yaml
122
+ kimi→claude:
123
+ status: active # active | degraded | abandoned
124
+ streak: 0 # consecutive failure count
125
+ last_outcome: agreed
126
+ history:
127
+ - { time: "2026-05-08T23:30:00+08:00", outcome: agreed, rounds: 2, tag: architecture }
128
+ ```
129
+
130
+ Rules:
131
+ - `streak >= 3` → automatically mark as `abandoned`
132
+ - `abandoned` peer pairs are skipped by the bridge script
133
+ - Human can reset via `roll peer reset <from> <to>` or `roll peer reset --all`
134
+ - If a peer pair is abandoned, the bridge falls back to the next candidate in the capability map
135
+
136
+ ## Peer Routing (Adaptive)
137
+
138
+ ### Capability Map (Task Type → Preferred Peer Order)
139
+
140
+ ```yaml
141
+ peer:
142
+ capability_map:
143
+ architecture: [claude, kimi, pi]
144
+ security: [claude, pi, kimi]
145
+ test: [codex, kimi, claude]
146
+ refactor: [kimi, claude, pi]
147
+ default: [kimi, claude, pi]
148
+ ```
149
+
150
+ ### Adaptive Adjustment
151
+
152
+ After each negotiation, record:
153
+ - `outcome`: agreed / failed_max_rounds / failed_api_error
154
+ - `rounds`: number of rounds consumed
155
+ - `tag`: task type
156
+
157
+ If `streak` for a peer pair reaches the configured threshold (default: 3 consecutive failures), mark as `abandoned`. The next task of the same type will try the next candidate in `capability_map`.
158
+
159
+ ### Peer Detection
160
+
161
+ The bridge script detects installed peers via `command -v <tool>`. Only installed tools are considered. The current running tool is excluded (`exclude_self: true`).
162
+
163
+ ## Workflow Integration
164
+
165
+ ### `roll-build` Plan Mode
166
+
167
+ After generating an executable plan, before proceeding to TCR:
168
+
169
+ 1. Assess plan complexity (file count, cross-module impact, risk level)
170
+ 2. If complexity > threshold, prompt user:
171
+ ```
172
+ This plan affects 5 files across 3 modules. Estimated peer review: 2–3 rounds, ~X tokens.
173
+ Press Enter to launch peer review, or type 'n' to skip. Auto-executing in 10s...
174
+ ```
175
+ 3. If user does not abort within 10s, invoke `roll peer` with `--tag architecture`
176
+ 4. Wait for result:
177
+ - AGREE → proceed to TCR
178
+ - REFINE/OBJECT → incorporate feedback and regenerate plan
179
+ - ESCALATE → present both proposals to user for final decision
180
+
181
+ ### `roll-spar`
182
+
183
+ When Attacker and Defender reach a stalemate (both tests pass but interpretations differ):
184
+
185
+ 1. Auto-invoke `roll peer` with `--tag test`
186
+ 2. Use the peer's verdict as tie-breaker
187
+
188
+ ## Output Artifacts
189
+
190
+ - **Negotiation log**: `~/.shared/roll/peer/logs/<timestamp>_<from>_<to>.md`
191
+ - **State file**: `~/.shared/roll/peer/state.yaml`
192
+ - **Decision record**: If AGREE, append summary to `docs/decisions/` or `BACKLOG.md` (optional)
193
+
194
+ ## Configuration
195
+
196
+ User overrides in `~/.roll/config.yaml`:
197
+
198
+ ```yaml
199
+ peer:
200
+ max_rounds: 3
201
+ opt_out_seconds: 10
202
+ call_timeout: 180 # seconds per round; configure based on your API latency
203
+ fallback: file_mailbox # direct_cli | file_mailbox | auto
204
+ capability_map:
205
+ architecture: [claude, kimi, pi]
206
+ security: [claude, pi, kimi]
207
+ test: [codex, kimi, claude]
208
+ default: [kimi, claude, pi]
209
+ adaptive:
210
+ streak_threshold: 3
211
+ min_samples: 3
212
+ ```
213
+
214
+ ## Limitations
215
+
216
+ 1. **Reverse link reliability**: Direct CLI calls (`claude -p`, `kimi --quiet`, `pi -p`) are preferred. If API gateways block non-interactive endpoints, fallback to file mailbox (`~/.shared/roll/peer/mailbox/`).
217
+ 2. **Cost**: Every peer review consumes tokens on both sides. Only trigger for tasks where the cost of a wrong decision exceeds the cost of peer review.
218
+ 3. **Context window**: Large project handoff cards may consume significant context. Keep file pointers concise.
219
+ 4. **Tool differences**: Kimi, Claude, and Pi handle skills and AGENTS.md differently. The peer may interpret the same protocol slightly differently. This is expected and acceptable.
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: roll-release
3
3
  license: MIT
4
- model: haiku
5
4
  allowed-tools: "Read, Edit, Bash(git:*), Bash(npm:*), Bash(sed:*), Bash(date:*)"
6
5
  description: "Release skill for roll maintainers. Calculates next version (YYYY.MMDD.N format, auto-increments N from today's git tags), updates VERSION in bin/roll and package.json, commits, tags, and pushes to trigger npm auto-publish via GitHub Actions. Trigger: release, publish, 发版, 发布新版本."
7
6
  ---
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: roll-research
3
3
  license: MIT
4
- model: opus
5
4
  allowed-tools: "WebFetch, WebSearch, Read, Write, Bash(python3:*), Bash(curl:*), Bash(pip:*), Agent"
6
5
  description: |
7
6
  HV (Horizontal-Vertical) Analysis deep research skill for products, companies, concepts, technologies, or people. Dual-axis: vertical traces full lifecycle narrative from origin to present; horizontal compares against competitors at current time; cross-axis produces new insights. Output: professionally formatted PDF report.
@@ -13,6 +12,13 @@ description: |
13
12
 
14
13
  > Follows the Architecture Constraints, Development Discipline, and Engineering Common Sense defined in the project AGENTS.md.
15
14
 
15
+ ## Credits
16
+
17
+ The HV (Horizontal-Vertical) Analysis framework and the `references/schema.json`
18
+ used by this skill are derived from **[khazix-skills](https://github.com/KKKKhazix/khazix-skills)**
19
+ by 数字生命卡兹克 (Digital Life Khazix), used under the MIT License.
20
+ Copyright (c) 2026 数字生命卡兹克.
21
+
16
22
  You are executing an HV Analysis deep research session. The final deliverable is a **professionally formatted PDF research report**.
17
23
 
18
24
  ## Prerequisites
@@ -1,3 +1,7 @@
1
+ // Copyright (c) 2026 数字生命卡兹克 (Digital Life Khazix)
2
+ // Released under the MIT License: https://github.com/KKKKhazix/khazix-skills/blob/main/LICENSE
3
+ // This file contains substantial portions of the Horizontal-Vertical Analysis Framework
4
+ // from khazix-skills (https://github.com/KKKKhazix/khazix-skills).
1
5
  {
2
6
  "$schema": "Horizontal-Vertical Analysis Framework",
3
7
  "version": "1.0",
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: roll-spar
3
3
  license: MIT
4
- model: sonnet
5
4
  allowed-tools: "Read, Edit, Write, Bash, Agent, Skill"
6
5
  description: Adversarial TDD mode with Attacker/Defender agents. Attacker writes tests to break the system, Defender writes minimal code to pass. Use for high-risk logic like auth, payments, data integrity, or complex state machines.
7
6
  ---