@seanyao/roll 2026.517.2 → 2026.517.4

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.
@@ -302,6 +302,13 @@ When any signal appears, **do not stop — flag it**:
302
302
 
303
303
  Then continue implementing the current Story normally.
304
304
 
305
+ **Event emission** — after all TCR micro-steps for a Story complete, emit a `build` event so the cycle event stream reflects the work done:
306
+
307
+ ```bash
308
+ # _tcr_count = number of "tcr:" prefix commits made during this Story
309
+ _loop_event build "$US_ID" "${_tcr_count} commits" "" 2>/dev/null || true
310
+ ```
311
+
305
312
  ### Phase 5.5: E2E Deposit
306
313
 
307
314
  After TCR micro-steps pass, deposit an E2E test for this Story's core user flow.
@@ -371,33 +378,51 @@ EOF
371
378
  chmod +x .git/hooks/pre-push
372
379
  ```
373
380
 
374
- ### Phase 7: Pre-Push Code Review
381
+ ### Phase 7: Pre-Push Code Review (Three-Axis Deep Review)
382
+
383
+ This phase runs **once per Story** (not per micro-step) on the full accumulated diff.
384
+ Per-micro-step review uses `$roll-.review staged` inline checklist (zero extra cost).
385
+
386
+ **Phase 3.5 vs Phase 7 split**: Phase 3.5 (Peer Review) focuses on architectural direction
387
+ and approach before coding begins. Phase 7 focuses on implementation quality after all
388
+ micro-steps are done — catching issues that only appear at diff scale (parameter sprawl
389
+ across files, copy-paste patterns, cross-file N+1, etc.).
375
390
 
376
391
  ```bash
377
- $roll-.review staged
392
+ # Capture full Story diff
393
+ git diff main...HEAD
378
394
  ```
379
395
 
380
- **Review output:**
396
+ **Launch three review agents in parallel** (each receives the full diff):
397
+
381
398
  ```
382
- 🔍 Self Review Report
383
- ├── Scope: X files (+Y/-Z lines)
384
- ├── 🔴 Critical: N issues (must fix)
385
- ├── 🟡 Warnings: N issues (should fix)
386
- ├── 🟢 Suggestions: N items (optional)
387
- └── ✅ Passed dimensions: [Quality, Design, Scope, ...]
399
+ Agent 1: Reuse Review
400
+ Search for existing utilities / helpers the new code could use instead
401
+ Flag any new function that duplicates existing functionality
402
+ Flag inline logic replaceable by existing tools
403
+
404
+ Agent 2: Quality Review
405
+ → Redundant state, Parameter sprawl, Copy-paste near-duplicate,
406
+ Leaky abstraction, Stringly-typed, JSX nesting,
407
+ Nested conditionals ≥3 deep, Unnecessary comments
408
+
409
+ Agent 3: Efficiency Review
410
+ → Redundant computation / N+1, Missed concurrency,
411
+ Hot-path bloat, Loop no-op updates, TOCTOU existence pre-check,
412
+ Memory leaks, Overly broad operations
388
413
  ```
389
414
 
390
- **Review dimensions** (correctness guaranteed by TCR):
391
- - 🎯 **Quality**: Naming clarity, DRY, function size, readability
392
- - 📐 **Design**: Architecture, abstraction level, separation of concerns
393
- - ⚠️ **Scope**: No opportunistic changes
394
- - 📝 **Documentation**: Comments where needed
415
+ Wait for all three agents to complete. Aggregate findings → fix each issue
416
+ (false positives: note and skip, no debate) summarize what was fixed.
417
+
418
+ **Fallback**: If parallel agent invocation fails, run `$roll-.review staged` on
419
+ the full diff as a single-pass fallback do not skip review entirely.
395
420
 
396
421
  **Decision:**
397
422
  ```
398
423
  🔴 Critical > 0 → Fix via new TCR cycle → Re-review
399
424
  🟡 Warnings > 0 → Fix if quick (< 5 min) or document
400
- 🟢 Suggestions / ✅ All clear → Proceed to push
425
+ 🟢 Suggestions / ✅ All clear → Proceed to Phase 8
401
426
  ```
402
427
 
403
428
  ### Phase 8: Commit & Push
@@ -96,7 +96,7 @@ fi
96
96
 
97
97
  ### Step 1.5 — Pre-run CI Health Check
98
98
 
99
- Call `_loop_precheck_ci` before scanning BACKLOG. This is a **defensive gate**
99
+ Call `roll loop precheck-ci` before scanning BACKLOG. This is a **defensive gate**
100
100
  against building on a broken base — if the most recent commit on the branch
101
101
  has red CI, the loop must not stack new commits on top (which would create the
102
102
  exact stuck-red state FIX-026 traces to).
@@ -105,7 +105,7 @@ exact stuck-red state FIX-026 traces to).
105
105
  - HEAD CI red → write ALERT, **do not pick up any stories this cycle**,
106
106
  exit cleanly. The next cycle will retry; the human must fix CI manually
107
107
  (typically by reverting or pushing a green commit) before the loop resumes.
108
- - `gh` missing or repo unparseable → graceful skip (`_loop_precheck_ci`
108
+ - `gh` missing or repo unparseable → graceful skip (`roll loop precheck-ci`
109
109
  returns 0); the post-build `_loop_enforce_ci` remains the strict gate.
110
110
 
111
111
  ### Step 1.6 — PR Inbox (US-AUTO-034)
@@ -195,6 +195,13 @@ For each item, **before invoking the executor skill**, mark the story 🔨 In Pr
195
195
 
196
196
  This commit is what makes the work visible — without it, tcr micro-commits during execution are invisible to `roll-brief`.
197
197
 
198
+ 选定故事后,调用 `_loop_event` 发出 story 事件,让 monitor 和 attach 能渲染当前进度:
199
+
200
+ ```bash
201
+ # 选定故事后立即 emit(在调用 executor skill 之前)
202
+ _loop_event story "$US_ID" "$story_title" ""
203
+ ```
204
+
198
205
  Then invoke the executor:
199
206
 
200
207
  ```
@@ -222,7 +229,7 @@ run_id: loop-20260510-0200
222
229
 
223
230
  After each item completes:
224
231
 
225
- 1. **TCR 硬校验** — call `_loop_enforce_tcr <story_id> <started_at>`:
232
+ 1. **TCR 硬校验** — call `roll loop enforce-tcr <story_id> <started_at>`:
226
233
  - Count `tcr:` prefix commits since `started_at` via `git log --oneline --since=<started_at>`
227
234
  - Count == 0 → revert story status in BACKLOG.md from ✅ Done → 📋 Todo; write ALERT to `~/.shared/roll/loop/ALERT.md` with story ID, time, reason "zero tcr: commits since story start", and suggested actions (`roll loop now` / `$roll-build <id>` / `roll loop reset`)
228
235
  - Count > 0 → continue normally
@@ -239,34 +246,36 @@ After each item completes:
239
246
  (return 0). Any other `gh` error is **not** "gh unavailable" — it is a
240
247
  hard failure and must block the gate.
241
248
 
242
- **CI self-heal (US-AUTO-041)** — bounded auto-fix before ALERT:
243
-
244
- ```
245
- shell: _loop_self_heal_ci <story_id>
246
- ├── exit 0 → heal attempt allowed (counter incremented)
247
- │ 1. Capture failure summary:
248
- │ gh run view --log-failed --repo <slug> $(gh run list --commit HEAD \
249
- │ --json databaseId,conclusion -L 5 | jq -r '.[] | select(.conclusion=="failure") | .databaseId' | head -1) \
250
- │ 2>/dev/null | head -200 > /tmp/roll-heal-<story_id>.log
251
- │ 2. Invoke Skill("roll-fix") with brief:
252
- │ "CI red after <story_id>. Failing run logs at /tmp/roll-heal-<story_id>.log.
253
- │ Diagnose root cause, fix via TCR, commit, push. Do NOT change <story_id>'s
254
- │ BACKLOG status — it stays ✅ Done. The fix is a follow-up."
255
- 3. After roll-fix completes, return to step 2 (CI Gate) re-run
256
- `roll ci --wait`. The counter prevents infinite loops.
257
-
258
- └── exit 1 heal exhausted (>=ROLL_LOOP_HEAL_MAX, default 2) or disabled
259
- (ROLL_LOOP_NO_HEAL=1):
260
- 1. Keep story as Done (commits are already on main — CI red is a
261
- follow-up problem, not a story-failure)
262
- 2. Write ALERT to `~/.shared/roll/loop/ALERT.md` with:
263
- - story ID, time, commit SHA
264
- - heal attempts made (read counter from
265
- `${ROLL_LOOP_DIR:-~/.shared/roll/loop}/heal/<story_id>.count`)
266
- - last failure summary (head of /tmp/roll-heal-<story_id>.log)
267
- - suggested actions: `$roll-fix` manually / inspect CI / `roll loop reset`
268
- 3. Skip to next story.
269
- ```
249
+ **CI self-heal (US-AUTO-041)** — bounded auto-fix before ALERT.
250
+
251
+ Call `_loop_self_heal_ci <story_id>` to check if another attempt is permitted.
252
+
253
+ **Path A attempt allowed (exit 0, counter incremented in `state.yaml`):**
254
+
255
+ 1. Capture failure summary:
256
+ ```
257
+ gh run view --log-failed --repo <slug> \
258
+ $(gh run list --commit HEAD --json databaseId,conclusion -L 5 \
259
+ | jq -r '.[] | select(.conclusion=="failure") | .databaseId' | head -1) \
260
+ 2>/dev/null | head -200 > /tmp/roll-heal-<story_id>.log
261
+ ```
262
+ 2. Invoke `Skill("roll-fix")` with brief:
263
+ `"CI red after <story_id>. Failing run logs at /tmp/roll-heal-<story_id>.log.
264
+ Diagnose root cause, fix via TCR, commit, push. Do NOT change <story_id>'s
265
+ BACKLOG status it stays Done. The fix is a follow-up."`
266
+ 3. After `roll-fix` completes, return to step 2 (CI Gate) — re-run `roll ci --wait`.
267
+ The counter in `state.yaml` prevents infinite loops.
268
+
269
+ **Path B — heal exhausted (≥`ROLL_LOOP_HEAL_MAX`, default 2) or disabled (`ROLL_LOOP_NO_HEAL=1`) (exit 1):**
270
+
271
+ 1. Keep story as Done — commits are already on main; CI red is a follow-up
272
+ problem, not a story failure.
273
+ 2. Write ALERT to `~/.shared/roll/loop/ALERT.md` with:
274
+ - story ID, time, commit SHA
275
+ - heal attempts made (read `heal_count:` from `state.yaml`)
276
+ - last failure summary (head of `/tmp/roll-heal-<story_id>.log`)
277
+ - suggested actions: `$roll-fix` manually / inspect CI / `roll loop reset`
278
+ 3. Skip to next story.
270
279
 
271
280
  **Bypass for debugging / cost control:** set `ROLL_LOOP_NO_HEAL=1` to restore
272
281
  pre-US-AUTO-041 fail-fast behaviour.
@@ -276,6 +285,11 @@ After each item completes:
276
285
 
277
286
  ### Step 5 — Write Run Summary
278
287
 
288
+ > **FIX-044**: The inner runner script (`_write_loop_runner_script` in `bin/roll`)
289
+ > now appends this record deterministically at cycle end. The shell write is the
290
+ > authoritative record; the agent should still emit a run summary in the cycle's
291
+ > final report for `cron.log` visibility.
292
+
279
293
  After all items in this cycle:
280
294
 
281
295
  ```yaml
@@ -65,6 +65,14 @@ Allowed states only. No invented words.
65
65
  - **OBJECT**: The proposal is wrong. Provide an alternative. Proceed to next round.
66
66
  - **ESCALATE**: Round 3 reached without AGREE, or a round fails due to API/token error. Hand off to the human user.
67
67
 
68
+ After each round decision, emit a `peer` event to the cycle event stream:
69
+
70
+ ```bash
71
+ # $round = current round number, $total = max rounds, $verdict = AGREE/REFINE/OBJECT/ESCALATE
72
+ # $agents = e.g. "claude→deepseek"
73
+ _loop_event peer "${round}/${total}" "$verdict" "$agents" 2>/dev/null || true
74
+ ```
75
+
68
76
  If information is insufficient:
69
77
  ```
70
78
  REFINE: Need to confirm X/Y/Z with the user first.