@seanyao/roll 4.714.2 → 4.717.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/guide/zh/faq.md CHANGED
@@ -557,6 +557,46 @@ roll loop reset
557
557
  更细的操作话题(pause/resume、切换 agent、gh scope 等)见
558
558
  [loop.md](loop.md) 和 [configuration.md](configuration.md)。
559
559
 
560
+ ### C5b. `roll loop on` 报 launchd bootstrap 错误怎么办?
561
+
562
+ **简答:** 此时排程未激活。优先修复 launchd;实在修不好再使用 owner
563
+ 明示确认的进程 fallback。
564
+
565
+ **原因:** macOS launchd 有时会以 `Bootstrap failed: 5: Input/output error`
566
+ (或类似域错误)拒绝 bootstrap。Roll 会重试一次、用 `launchctl print`
567
+ 验证挂载,若仍失败就以非零码退出,不会假装调度器已启用。
568
+
569
+ **先修 launchd:**
570
+
571
+ ```bash
572
+ UID=$(id -u)
573
+ LABEL=$(launchctl list | awk '$3 ~ /^com\.roll\.loop\./ {print $3; exit}')
574
+ # 如果 launchctl list 没有输出,请使用错误信息里的精确 label。
575
+ launchctl bootout gui/$UID/$LABEL
576
+ launchctl bootstrap gui/$UID ~/Library/LaunchAgents/$LABEL.plist
577
+ launchctl print gui/$UID/$LABEL
578
+ roll loop on
579
+ roll loop status
580
+ ```
581
+
582
+ **如果 launchd 无法修复:**
583
+
584
+ ```bash
585
+ roll loop fallback start --confirm
586
+ roll loop fallback status
587
+ ```
588
+
589
+ fallback 不是 launchd 的等价替代,不会跨过重启/登出。重启或重新登录后
590
+ 必须重新确认:
591
+
592
+ ```bash
593
+ roll loop fallback stop
594
+ roll loop fallback start --confirm
595
+ ```
596
+
597
+ 脱敏、无需 root 的现场验证流程见
598
+ [从 launchd bootstrap 失败中恢复](loop.md#从-launchd-bootstrap-失败中恢复)。
599
+
560
600
  ### C7. 改了 loop_schedule 但 loop 还是按旧频次跑
561
601
 
562
602
  **症状:** 更新了 `.roll/local.yaml` 的 `loop_schedule`,但 `roll loop status`
@@ -772,3 +812,25 @@ gh issue create --title "Safari 上登录失败" --body "复现步骤: ..."
772
812
  这些控制只影响用户可见表面。Agent 契约、代码、git 元数据和 schema 保持英文;
773
813
  与 owner 的对话跟随当前任务里 owner 使用的语言。发版前可运行
774
814
  `roll doctor language` 审计文档、约定、skills 与生成表面的语言漂移。
815
+
816
+ ### C12. `roll browser interactive` 有什么限制?
817
+
818
+ **短答:** 它是一个面向本地 Chrome 调试端点的前台、owner 运行、单次操作工具——
819
+ 不是后台自动化,也不是远程浏览器。
820
+
821
+ **细节:** `roll browser interactive` 要求:
822
+
823
+ - 已连接的 TTY 和每次操作的显式 owner 批准。
824
+ - 你自己用 loopback 调试端口启动的 Chrome,例如 `127.0.0.1` 上的
825
+ `--remote-debugging-port=9222`。
826
+
827
+ 它**永远不会**:
828
+
829
+ - 从后台调度器或 CI 作业中运行。
830
+ - 连接远程或非 loopback 端点。
831
+ - 导出 cookie、storage 或 network bodies。
832
+ - 自动启动 Chrome。
833
+ - 独自让 CI 通过——结果仅用于 **owner-run manual-attest**。
834
+
835
+ 租约最多 15 分钟,操作结束后立即释放。无人值守诊断请用受管通道
836
+ (`roll browser run`)。
package/guide/zh/loop.md CHANGED
@@ -31,7 +31,7 @@ Loop 在名为 **`roll-loop-<project-slug>`** 的 **tmux session** 里运行。
31
31
 
32
32
  | 指标 | 目标 | 防应试口径 | `null` 含义 |
33
33
  |------|------|------------|-------------|
34
- | 自主运行时长 | ≥72 小时 | 有效自主日需要至少 6 次非 idle 尝试;backlog 空的日期只停表,不计为未达标时间。 | 暂无足够合格运行历史,或窗口内 backlog 为空。 |
34
+ | 自主运行时长 | ≥72 小时 | `current` 是声明的 14 天窗口内合格每日小时之和,而不是最近一段未中断时长。有效自主日需要至少 6 次非 idle 尝试;backlog 空的日期只停表,不计为未达标时间。 | 暂无足够合格运行历史,或窗口内 backlog 为空。 |
35
35
  | 交付率 | ≥60% | 交付按 merge truth 统计,不按 cycle 自报退出码。 | 暂无可作为分母的交付样本。 |
36
36
  | 修复税 | <1x | 分母仅统计 US 卡;FIX 工作不能改善自己的比值。 | 窗口内没有 US 卡分母。 |
37
37
  | 归因错误 | =0 | `unknown` 不猜成 env、harness 或 card;缺失 envelope 保持可见。 | 暂无归因样本。 |
@@ -97,6 +97,77 @@ Loop 通过 **launchd**(macOS)调度。默认每小时在一个根据项目
97
97
  验证任务确实存活。如果 launchd 仍拒绝任务,命令会以非零码退出,并打印准确的
98
98
  域、标签、plist 路径和可直接执行的诊断命令;bootstrap 失败不会再伪装成已启用。
99
99
 
100
+ ### 从 launchd bootstrap 失败中恢复
101
+
102
+ `roll loop on` 失败后,排程处于**未激活**状态。`~/Library/LaunchAgents/`
103
+ 里的 plist 文件存在并**不**代表自主排程已启用——只有 `launchctl list`
104
+ 显示对应 label 已加载,loop 才是真正就绪的。请用 `roll loop status` 查看
105
+ 当前生效后端(`launchd`、`process-fallback` 或 `none`)。
106
+
107
+ **优先修复 launchd。** 错误输出已经打印了精确命令,通用形式使用
108
+ `launchctl list` 返回的 label:
109
+
110
+ ```bash
111
+ UID=$(id -u)
112
+ LABEL=$(launchctl list | awk '$3 ~ /^com\.roll\.loop\./ {print $3; exit}')
113
+ # 如果 launchctl list 没有输出,请使用 roll loop on 错误信息里的精确 label。
114
+ launchctl bootout gui/$UID/$LABEL
115
+ launchctl bootstrap gui/$UID ~/Library/LaunchAgents/$LABEL.plist
116
+ launchctl print gui/$UID/$LABEL
117
+ roll loop status
118
+ ```
119
+
120
+ 如果 `launchctl bootstrap` 成功且 `print` 显示任务存活,再次运行
121
+ `roll loop on` 以重新生成当前 runner 并确认调度。
122
+
123
+ **如果 launchd 实在无法修复**,Roll 提供一个需要 owner 明示确认的进程
124
+ fallback,只有显式确认时才会启动:
125
+
126
+ ```bash
127
+ roll loop fallback start --confirm
128
+ roll loop fallback status
129
+ roll loop fallback stop # 不再需要时停止
130
+ ```
131
+
132
+ 该 fallback **不是** launchd 的等价替代:它不会跨过重启或登出会话。
133
+ 重启或重新登录后,必须先停止旧 lease 再重新确认:
134
+
135
+ ```bash
136
+ roll loop fallback stop
137
+ roll loop fallback start --confirm
138
+ ```
139
+
140
+ 优先修复 launchd;仅在 launchd 不可用时使用 fallback。
141
+
142
+ #### macOS 现场验证流程(Bootstrap failed: 5)
143
+
144
+ 当 `roll loop on` 报 `Bootstrap failed: 5: Input/output error` 这类错误时,
145
+ 记录一份已脱敏、无需 root 的诊断包:
146
+
147
+ ```bash
148
+ mkdir -p .roll/loop
149
+ TS=$(date +%Y%m%d-%H%M%S)
150
+ OUT=.roll/loop/launchd-verify-$TS.log
151
+ {
152
+ echo "roll version: $(roll version)"
153
+ echo "uid: $(id -u)"
154
+ echo "---"
155
+ echo "roll loop status:"
156
+ roll loop status
157
+ echo "---"
158
+ echo "launchctl list(roll lane):"
159
+ launchctl list | grep com.roll\. || true
160
+ echo "---"
161
+ echo "磁盘上的 plist:"
162
+ ls -1 ~/Library/LaunchAgents/com.roll.loop.*.plist 2>/dev/null || true
163
+ } > "$OUT"
164
+ # 分享前脱敏:把真实 home 路径替换为 ~。
165
+ sed -i.bak "s|$HOME|~|g" "$OUT" && rm -f "$OUT".bak
166
+ ```
167
+
168
+ 该流程只使用用户级(`gui/<uid>`)launchctl 命令,不需要 `sudo`,也不依赖
169
+ `launchctl dumpstate` 等仅限 root 的诊断。
170
+
100
171
  ## 配置调度(Configuring the schedule)
101
172
 
102
173
  不用再手工编辑 `~/.roll/config.yaml` 和 `.roll/local.yaml` 再祈祷 launchd plist 能 reload 上。改用 `roll config` 命令族:每次写入都落到正确的 yaml 文件,**并且**自动重生 runner、重 bootstrap launchd plist、立刻在 `roll loop status` 反映——没有手工 reload 这一步。
@@ -235,7 +306,7 @@ roll loop gc --keep-days 14 # 覆盖保留天数(也可用 .roll/local.yaml
235
306
  roll loop events # 显示最近 20 条 cycle 事件
236
307
  roll loop events 50 # 显示最近 50 条
237
308
 
238
- roll agent # 查看 scope、role、agent pool 与 legacy 输入
309
+ roll agent # 查看 scope、有效项目能力与 agent pool
239
310
  roll agent list # 查看本机已装的 agent
240
311
  ```
241
312
 
@@ -275,8 +346,10 @@ paused 状态时不建议直接启动:`PAUSE-<slug>` 标记仍会在 cycle 边
275
346
  预算与运行上限每次 `roll loop go` 都是显式的。`--budget`、`--max-cycles`、`--for`
276
347
  只对本次调用生效;省略某项即代表本轮不设该限制——Roll 绝不从上一次会话持久化的
277
348
  goal 静默沿用预算或上限,因此一条不带 flag 的 `roll loop go` 既不会被几天前设的
278
- 上限封顶,也不会被它卡死。范围(`--epic`/`--cards`)与 `--review` 在省略时仍沿用,
279
- 因为它们是 goal 的身份,而不是每次运行的安全旋钮。
349
+ 上限封顶,也不会被它卡死。范围(`--epic`/`--cards`)与 `--review` 只会在 goal 尚未
350
+ 结束时于省略 flag 后沿用。goal 已 `complete` 时,下一次 `roll loop go` 会将它归档到
351
+ `.roll/loop/goal-archive/`、记录 `goal:archived`,并完全按本次 flags 新建 goal;不带
352
+ scope flag 则覆盖全部合格 backlog 卡,绝不会静默沿用已完成 goal 的范围。
280
353
 
281
354
  `roll loop go` 的安全闸只在 cycle 边界生效。`--budget <usd>` 使用有效成本账本;
282
355
  达到预算时 goal 进入 `budget_limited`。未执行 agent 的 idle 或 aborted 周期记为
@@ -365,9 +438,11 @@ defaults:
365
438
  strategy: health-aware
366
439
  ```
367
440
 
368
- `roll agent` 会显示 Machine ScopeProject Scope、已解析角色、候选池、运行时健康说明,
369
- 以及 legacy compatibility 输入。用 `roll agent migrate --dry-run` 预览旧 agent
370
- 文件迁移。
441
+ `roll agent` 会显示 Machine Scope 和有效 Project Scope,包括继承后的 agent 与已配置的
442
+ route model;它不会预测下一次角色分配。dispatch 会在 spawn 时依据运行时健康和
443
+ least-recent 状态决策。需要诊断快照时使用
444
+ `roll supervisor route --role builder|evaluator`。用 `roll agent migrate --dry-run`
445
+ 预览一次性迁移;正常执行不会读取旧 agent 配置。
371
446
 
372
447
  运行时健康不是静态策略。quota、auth、网络、VPN、账号、stall 或 binary 缺失只会
373
448
  挂起运行态 rig,并记录为运行时事实;Roll 不回写 `agents.yaml`。挂起 rig 按恢复窗口
@@ -564,6 +639,10 @@ Gate 或 owner 需要介入,因为普通接力没有干净完成。`terminus`
564
639
 
565
640
  `roll loop status` 输出一个紧凑的仪表盘,包含每个 cycle 的行记录和每日汇总。
566
641
 
642
+ 当当前所有可派工卡都需要物理终端截图且 macOS 已锁屏时,状态行会显示“等待屏幕解锁”。
643
+ 这属于等待态,不是 idle 失败:下一次探测到解锁的 tick 会清除提示并正常派工,且不会消耗
644
+ no-progress 熔断次数。
645
+
567
646
  ### Token 列
568
647
 
569
648
  每条 cycle 行的 token 用量以 4 分量格式显示:
@@ -1270,3 +1349,7 @@ Since Phase 2.0, loop state lives inside the project at `<project>/.roll/loop/`.
1270
1349
  plist——旧版本退役的形态(ci/alert/brief)曾以僵尸身份指着已删除的引擎存活数周。
1271
1350
  `roll doctor` 列出本机全部 `com.roll.*` 任务及其目标目录与加载状态;目标目录
1272
1351
  已不存在的 lane 标红 STALE。
1352
+
1353
+ bootstrap 失败后留在磁盘上的 plist,或者手动 `bootout` 后残留的 plist,
1354
+ **不**等于 loop 已激活。请始终依据 `roll loop status`(有效后端)和
1355
+ `launchctl list` 来判断,而不是仅看 `.plist` 文件是否存在。
@@ -15,7 +15,7 @@ Roll 把评审指派看成 scoped Agent 模型里的 `evaluate` 角色:
15
15
 
16
16
  ```bash
17
17
  roll agent # 查看 story.evaluate
18
- roll agent migrate --dry-run # 如有旧 pairing.yaml,预览迁移
18
+ roll agent migrate --dry-run # 预览旧 agent 配置的一次性迁移
19
19
  ```
20
20
 
21
21
  新项目应在 `.roll/agents.yaml` 里声明 evaluator pool:
@@ -34,9 +34,8 @@ defaults:
34
34
  strategy: health-aware
35
35
  ```
36
36
 
37
- `.roll/pairing.yaml` 仍是 legacy compatibility 输入;两者同时存在时优先使用 scoped
38
- `evaluate` role。静态配置列公平候选,auth/network/VPN/account 等运行时失败只在本次
39
- resolution 中跳过候选。
37
+ `.roll/pairing.yaml` 不再是运行时输入;scoped `evaluate` role 是结对候选的唯一来源。
38
+ 静态配置列公平候选,auth/network/VPN/account 等运行时失败只在本次 resolution 中跳过候选。
40
39
 
41
40
  ## 看它做了什么 —— 可观测性
42
41
 
package/guide/zh/tools.md CHANGED
@@ -79,6 +79,17 @@ tools:
79
79
 
80
80
  未知字段会告警但不会拒绝整个 policy 文件,方便新旧版本之间前向兼容。
81
81
 
82
+ ## Owner Chrome:手动交互通道
83
+
84
+ `roll browser interactive` 是一次性的、owner 手动运行边界:它只会连接已经开启的 loopback Chrome DevTools 端点,执行一个 typed 低风险动作。每次运行都必须附着 TTY,并重新输入 `y` 批准;提示会列出故事、批准的 origin、动作摘要、最长 15 分钟的过期时间和“禁止凭据导出”。
85
+
86
+ ```text
87
+ roll browser interactive --story US-BROW-008b --origin https://app.example.test \
88
+ --action navigate --url https://app.example.test/account
89
+ ```
90
+
91
+ 它只连接 origin 与 `--origin` 匹配的 tab,并会在批准过期、取消、错误或进程退出时断开 DevTools。Roll 不会启动或关闭 owner 的 Chrome。封闭动作词表只有 `navigate`、`click`、`fill` 和 `press_key`;cookie、storage 和 network body 没有 CLI 或 adapter 表面。交互成功只是手动证据,不会让 CI 通过,也不会变成后台自动化。
92
+
82
93
  ## CLI
83
94
 
84
95
  用 `roll doctor tools status` 查看当前项目已注册工具、输入契约、依赖就绪度和合成后的有效 policy 状态。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seanyao/roll",
3
- "version": "4.714.2",
3
+ "version": "4.717.2",
4
4
  "description": "Roll — Roll out features with AI agents",
5
5
  "packageManager": "pnpm@11.1.3",
6
6
  "scripts": {
@@ -8,6 +8,7 @@
8
8
  "lint:story-ids": "node scripts/lint-story-ids.mjs",
9
9
  "lint:role-taxonomy": "node scripts/audit-role-taxonomy.mjs",
10
10
  "test:e2e": "pnpm -r build && pnpm --filter @roll/cli exec vitest run test/critical-flows.e2e.test.ts",
11
+ "test:browser-live": "pnpm -r build && ROLL_BROWSER_LIVE=1 pnpm --filter @roll/cli exec vitest run --config vitest.live.config.ts",
11
12
  "test:cov": "pnpm -r exec vitest run --coverage.enabled --coverage.provider=v8 --coverage.include='src/**' --coverage.reporter=text-summary --coverage.reporter=text",
12
13
  "bundle": "node scripts/bundle.mjs",
13
14
  "postinstall": "node scripts/postinstall-roll-capture.mjs",
@@ -34,7 +34,7 @@ same TCR, evidence, Evaluator, and release gates apply in both modes.
34
34
  2. Read backlog/spec and decide if the story fits one cycle.
35
35
  3. Split into small TCR actions; per Action route objective work to the 4-stage TCR loop and judgment-dependent work to a 3-stage criteria+Evaluator loop, then define verification.
36
36
  4. Run test-first implementation, self-review, evidence, and write-back.
37
- 5. Commit on green, open PR, and leave remote evidence.
37
+ 5. Commit green TCR work, then hand off publishing and remote evidence to the Runner.
38
38
 
39
39
  ## Hard Gates
40
40
 
@@ -42,6 +42,7 @@ same TCR, evidence, Evaluator, and release gates apply in both modes.
42
42
  - No WIP commits or bypassed verification.
43
43
  - In the test-gated loop the tests are the weakest link: an isolated Test Adequacy reviewer (Phase 6 Agent 4) audits the tests against the AC, seeing only AC + test files — never the implementation diff or builder reasoning. Self-review of one's own tests (Phase 2) is necessary but not isolation.
44
44
  - Self-review, attest, and E2E evidence remain required. The Review Score is produced by the runner's fresh-session peer Reviewer — the agent does NOT self-score.
45
+ - Inside a `roll-loop` cycle, never run `git push` or `gh pr create`; the Runner owns branch publication and PR creation after the gates pass.
45
46
  - Docs/code/product alignment is a DoD gate: user-visible behavior, command, output-copy, site, or delivery-view changes update the touched README/docs/guide/site/help in the same delivery.
46
47
  - Done ≡ merged to `main`. After publish the cycle is `awaiting_merge`; the Delivery Reconciler (no daemon) self-drives the merge and reconciles truth from `main` — manual merges are first-class (`delivered_external`). Never pre-flip a card to Done on an open PR.
47
48
 
@@ -579,15 +579,17 @@ the full diff as a single-pass fallback — do not skip review entirely.
579
579
  🟢 Suggestions / ✅ All clear → Proceed to Phase 7
580
580
  ```
581
581
 
582
- ### Phase 7: Commit & Push (branch + PR — NEVER direct to main)
582
+ ### Phase 7: Commit & Publish Handoff
583
583
 
584
- `main` is PR-protected. Push the worktree's branch and open a PR — never
585
- `git push origin main`. (When invoked by `roll-loop`, the runner already
586
- created the worktree + branch and opens the PR; this is the manual-path
587
- equivalent.)
584
+ `main` is PR-protected. In a standalone guided session, push the worktree's
585
+ branch and open a PR — never `git push origin main`. Inside a `roll-loop`
586
+ cycle, stop after the green commits and evidence: the Runner publishes the
587
+ branch and opens the PR after its gates pass. Do not run `git push` or
588
+ `gh pr create` inside the Builder session.
588
589
 
589
590
  ```bash
590
- # All TCR micro-commits are already made on the worktree's branch (step A3.1).
591
+ # Standalone guided session only. All TCR micro-commits are already made on
592
+ # the worktree's branch (step A3.1).
591
593
  git log --oneline -{n} # Review TCR commits
592
594
  git push -u origin <branch> # the dispatch/<id> branch from step A3.1
593
595
  gh pr create --title "{story-id}: …" --body "…"
@@ -761,12 +763,13 @@ delivered. Consequences you can rely on:
761
763
  PR-state (L1) / patch-id (L2) and flips the cycle to `delivered` — manual /
762
764
  external merges included (`delivered_external` is first-class).
763
765
 
764
- So on the manual path, flip the row to Done **after** the PR merges; under
765
- `roll-loop` the cycle ends at publish (`awaiting_merge`) and the reconciler
766
+ So on the manual path, flip the row to Done **after** the PR merges. Under
767
+ `roll-loop`, the Builder must not edit shared `.roll` completion status at
768
+ all: the cycle ends at publish (`awaiting_merge`) and the reconciler
766
769
  self-drives the merge (`gh pr merge --squash` on green CI) and flips the row
767
770
  once the merge lands on `main` — do not pre-flip on a still-open PR.
768
771
 
769
- Both locations must be updated — neither can be skipped:
772
+ On the manual path, both locations must be updated — neither can be skipped:
770
773
 
771
774
  **① Update .roll/backlog.md index row (Status column):**
772
775
 
@@ -777,7 +780,7 @@ Both locations must be updated — neither can be skipped:
777
780
  | [US-{ID}](.roll/features/<epic>/US-{ID}/spec.md) | {Title} | ✅ Done · [evidence](.roll/features/<epic>/US-{ID}/latest/US-{ID}-report.html) |
778
781
  ```
779
782
 
780
- 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.
783
+ Change the Status from `📋 Todo` or `🔨 In Progress` (whichever the row currently shows) to `✅ Done`.
781
784
  For Fly mode: first append an index row under the appropriate Epic > Feature group, then mark it done.
782
785
 
783
786
  **② Update `.roll/features/<epic>/<story>/spec.md`:**
@@ -804,7 +807,9 @@ For Fly mode: first append an index row under the appropriate Epic > Feature gro
804
807
  If the US section does not yet exist, create the full section (AC / Files / Dependencies).
805
808
 
806
809
  **Before committing, run `$roll-.changelog`** to stage CHANGELOG.md — then include
807
- it in the completion commit so no separate changelog commit is created.
810
+ it in the completion commit so no separate changelog commit is created. This
811
+ manual-path section does not apply inside `roll-loop`; its Runner owns
812
+ metadata reconciliation after merge.
808
813
 
809
814
  ```bash
810
815
  # 1. Stage changelog (roll-.changelog stages CHANGELOG.md only, does not commit)
@@ -857,11 +862,10 @@ Before creating any file or directory:
857
862
  0. **Worktree-first, PR-at-end (ALWAYS)**
858
863
  Before writing any code, work in a dedicated git worktree on its own
859
864
  branch (`git worktree add ../wt-<id> -b <branch>`), never in the shared
860
- checkout — so concurrent cycles / sessions never collide. Finish by
861
- pushing the branch and opening a PR; `main` is PR-protected — NEVER
862
- `git push origin main`. (Under `roll-loop` the runner creates the
863
- worktree + branch and opens the PR; this rule is the manual-path
864
- equivalent and must hold either way.)
865
+ checkout — so concurrent cycles / sessions never collide. In a standalone
866
+ session, finish by pushing the branch and opening a PR; `main` is
867
+ PR-protected — NEVER `git push origin main`. Under `roll-loop`, finish
868
+ green commits and evidence only: the Runner creates the PR.
865
869
 
866
870
  1. **No local-only "done" — Done ≡ merged (FIX-322/323)**
867
871
  Work is not complete until it reaches: