ops: agent monikers (@heyVern / @sparkFlux) + high-perf continuous-ops rewrite - #161
Conversation
…stall bug) - Introduce creative monikers SSOT (docs/ops/AGENT-MONIKERS.md) - @jules → @HeyVern (primary ping) - @gemini-cli remains callable; alias @sparkflux also accepted - Per-role monikers for CodeRabbit, Devin, continuous-ops, OPERATOR - Rewrite agent-continuous-ops: no false 4-day on brand-new PRs, exclude self marker from loop/approval detectors, checks:read, tighter high-performance thresholds Signed-off-by: Grok (OPERATOR) session-2026-08-10
|
Mention Blocks like a regular teammate with your question or request: @blocks review this pull request Run |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThe pull request expands continuous agent sweeps, adds SHA-aware debounce and PR-state detection, updates Jules lane metadata, documents agent monikers, and adds case-insensitive Gemini trigger aliases. ChangesAgent orchestration
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant ScheduledSweep
participant GitHubPRAPI
participant Jules
ScheduledSweep->>GitHubPRAPI: Read PR state, checks, comments, and changed files
GitHubPRAPI-->>ScheduledSweep: Return sweep conditions
ScheduledSweep->>Jules: Post `@jules` remediation nudge
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
OPERATOR note: Once checks clear, prefer squash or merge of this over #160 (which carries the Infinity-age stall bug). Signed-off-by: Grok (OPERATOR) |
|
@jules Auto-resolve (GHA agent-review-auto-jules) — do not wait for a human ping. Feedback excerptInstructions
|
PR Summary by QodoOps: agent monikers SSOT + continuous-ops stall/check detection rewrite
AI Description
Diagram
High-Level Assessment
Files changed (4)
|
|
head_sha: f1897eb Peer review gate (ready for second-pass agents)External reviewers polled: CodeRabbit, Devin, Aikido, Sentry, Copilot. Peer activity (truncated): Downstream: |
🔀 OpenRouter review (
|
Code Review by Qodo
1.
|
…, case-insensitive aliases - Monikers as `heyVern` / `sparkFlux` code spans (NOT @mentions of real GH users) - Keep @jules / @gemini-cli as the only live triggers - Skip re-nudge when last ops comment already targeted same head SHA - Drop cancelled from failure conclusions; emptyDiff requires age > 30m - Restore github-actions in agentLogins (marker still filters self) - Case-insensitive @sparkflux / @gemini-cli matching in dispatch Signed-off-by: Grok (OPERATOR)
|
Deployment failed for project termux-monorepo with the following error: Learn More: https://vercel.com/timerloggedout-5184s-projects?upgradeToPro=build-rate-limit |
|
OPERATOR follow-up pushed (
#160 closed as superseded. Ready for merge once remaining conversation/threads clear. Signed-off-by: Grok (OPERATOR) / archW1z |
| # Agent Monikers (SSOT) | ||
|
|
||
| Creative **display** call-signs for high-performance agent orchestration. | ||
|
|
||
| **Critical:** Do **not** `@`-mention monikers that collide with real GitHub usernames. | ||
| Use backticks or plain text for display. Live triggers remain the original handles. |
There was a problem hiding this comment.
🟡 New ops work added without the required board row or work-item citation
The new monikers document and workflow rewrite are introduced (docs/ops/AGENT-MONIKERS.md:1) without first adding a row under docs/proposals/active/<id>/ITEMS.md and without an Implements: <ITEM-ID> citation on the PR/commits, which the repository's mandatory agent instructions require.
Impact: The change bypasses the project's tracking process, so this work is invisible on the active board and cannot be traced to an approved item.
Rule source and evidence
AGENTS.md hard rules: "Do not invent work outside docs/proposals/active/<id>/ITEMS.md — add a row first." and "Cite Implements: <ITEM-ID> on PRs/commits."
The PR touches only .github/workflows/agent-continuous-ops.yml, .github/workflows/agent-review-auto-jules.yml, .github/workflows/gemini-dispatch.yml, and the new docs/ops/AGENT-MONIKERS.md; no ITEMS.md row is added, and neither commit message (f1897eb, d52cc90) nor the PR body contains an Implements: line.
Prompt for agents
AGENTS.md requires that any new work be represented by a row in docs/proposals/active/<id>/ITEMS.md before implementation, and that PRs/commits cite Implements: <ITEM-ID>. This PR adds docs/ops/AGENT-MONIKERS.md and rewrites .github/workflows/agent-continuous-ops.yml without either. Add an ITEMS.md row under the appropriate active proposal (or create one) covering agent monikers / continuous-ops hardening, then amend the PR body and commit messages with the corresponding Implements: ID.
Was this helpful? React with 👍 or 👎 to provide feedback.
| const stale = lastAgentAge != null && lastAgentAge > staleMs; | ||
| const stale4Days = lastAgentAge != null && lastAgentAge > stallMs; |
There was a problem hiding this comment.
🔍 PRs with unresolved threads but no bot issue-comment lose the stale nudge path
Previously lastAgentAge defaulted to Infinity when no agent issue-comment existed, so stale && openThreads > 0 fired for PRs with unresolved review threads even if no bot had ever posted an issue-level comment. With lastAgentAge = null, both stale and stale4Days are now false in that case, so such PRs are only nudged if they are dirty, blocked with open threads, have failing checks, or have an empty diff. Note that inline review threads (CodeRabbit/Copilot suggestions) do not appear in issues.listComments, so a PR whose only bot feedback is inline and whose mergeable_state is clean will now be skipped indefinitely. This is a deliberate consequence of the #159 fix, but worth confirming the blocked branch really covers those PRs in this repo's branch-protection setup.
Was this helpful? React with 👍 or 👎 to provide feedback.
| const needsWork = dirty || | ||
| (blocked && openThreads > 0) || | ||
| (stale && openThreads > 0) || | ||
| stale4Days || | ||
| statusFailed || | ||
| requestingApproval || | ||
| loopDetected || | ||
| emptyDiff || | ||
| forceAll; |
There was a problem hiding this comment.
🔍 Permanently failing checks / lingering approval requests produce a nudge every 6 hours forever
statusFailed and requestingApproval are sticky conditions derived from state that a nudge cannot change: self-nudges are excluded from agentComments, so lastAgentComment (and thus requestingApproval) never ages out, and a permanently red check keeps statusFailed true. The only throttle is the sticky debounce (6h when head SHA is unchanged), so an unfixable PR will accumulate ~4 identical nudge comments per day indefinitely, with no per-PR nudge cap. Consider capping consecutive nudges per SHA (e.g. count prior self-nudges carrying the same sha: line and stop after N).
Was this helpful? React with 👍 or 👎 to provide feedback.
| const reasons = []; | ||
| if (dirty) reasons.push('merge conflict / dirty vs base'); | ||
| if (blocked && openThreads > 0) reasons.push(`${openThreads} unresolved review thread(s)`); | ||
| if (stale) reasons.push(`stale agent activity (${Math.round(lastAgentAge/3600000)}h)`); |
There was a problem hiding this comment.
📝 Info: Reason list can report 'stale agent activity' even when staleness didn't trigger the nudge
needsWork only uses stale when openThreads > 0, but the reason list pushes the stale reason whenever stale is true. A PR nudged solely because of a failing check will still say "stale agent activity (Nh)" in the Why line, which can mislead the agent that reads the comment. Same pattern existed before the rewrite, but the reason list now has many more entries so mismatches are more visible.
Was this helpful? React with 👍 or 👎 to provide feedback.
| // Do NOT treat cancelled as failure (concurrency cancel-in-progress is normal) | ||
| const failed = latest.filter(c => | ||
| ['failure', 'timed_out', 'action_required'].includes(c.conclusion) | ||
| ); |
There was a problem hiding this comment.
📝 Info: PR description and code disagree on cancelled checks and the ping text
The PR body claims checks counting includes cancelled and that the nudge pings @heyVern @jules; the final code deliberately excludes cancelled (comment at line 160) and pings only @jules. The code behavior is the safer one (concurrency cancellations are normal; heyVern may be a real GitHub user), but the description should be updated so future readers don't 'fix' it back.
Was this helpful? React with 👍 or 👎 to provide feedback.
| ( | ||
| startsWith(github.event.comment.body || github.event.review.body || '', '@gemini-cli') || | ||
| startsWith(github.event.comment.body || github.event.review.body || '', '@sparkFlux') || | ||
| startsWith(github.event.comment.body || github.event.review.body || '', '@sparkflux') | ||
| ) && |
There was a problem hiding this comment.
📝 Info: The extra '@sparkflux' lowercase alternative in the job condition is redundant
GitHub Actions expression string functions (startsWith, contains, endsWith) compare case-insensitively, so startsWith(body, '@sparkFlux') already matches @sparkflux, @SPARKFLUX, etc. The third alternative adds no behavior; the script-side matching correctly lowercases the body first, so the two layers agree.
Was this helpful? React with 👍 or 👎 to provide feedback.
|
head_sha: d52cc90 Peer review gate (ready for second-pass agents)External reviewers polled: CodeRabbit, Devin, Aikido, Sentry, Copilot. Peer activity (truncated): Downstream: |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/agent-continuous-ops.yml:
- Around line 37-42: Add a concise explanatory comment immediately above the
permissions block documenting the workflow’s need for Checks, Commit statuses,
Pull requests, and Issues access, while preserving the existing permission
values.
- Around line 142-170: The check evaluation around github.paginate must also
call github.rest.repos.getCombinedStatusForRef for pr.head.sha and treat a
returned state of failure as failed. Merge that result with the existing failed
Check Runs, ensuring statusFailed is set and failCount remains nonzero when
Commit Status is the only failure; add coverage for that scenario.
In `@docs/ops/AGENT-MONIKERS.md`:
- Around line 18-24: Add one blank line immediately after the “## Rules” heading
and another immediately after “## High-performance intent” in the documentation,
preserving the existing list and content.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 8fb62185-e6fd-4ae6-9568-e35f18f1f865
📒 Files selected for processing (4)
.github/workflows/agent-continuous-ops.yml.github/workflows/agent-review-auto-jules.yml.github/workflows/gemini-dispatch.ymldocs/ops/AGENT-MONIKERS.md
| permissions: | ||
| contents: read | ||
| pull-requests: write | ||
| issues: write | ||
| checks: read | ||
| statuses: read |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
Document the declared token permissions.
zizmor reports undocumented-permissions for this block. Add a concise comment that states why the workflow needs Checks, Commit statuses, Pull requests, and Issues permissions.
🧰 Tools
🪛 zizmor (1.29.0)
[warning] 39-39: permissions without explanatory comments (undocumented-permissions): needs an explanatory comment
(undocumented-permissions)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/agent-continuous-ops.yml around lines 37 - 42, Add a
concise explanatory comment immediately above the permissions block documenting
the workflow’s need for Checks, Commit statuses, Pull requests, and Issues
access, while preserving the existing permission values.
Source: Linters/SAST tools
| let statusFailed = false; | ||
| let failCount = 0; | ||
| try { | ||
| const checkRuns = await github.paginate(github.rest.checks.listForRef, { | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| ref: pr.head.sha, | ||
| per_page: 50, | ||
| }); | ||
| // Prefer latest run per check name | ||
| const byName = new Map(); | ||
| for (const c of (checkRuns || [])) { | ||
| const prev = byName.get(c.name); | ||
| if (!prev || new Date(c.completed_at || c.started_at || 0) > new Date(prev.completed_at || prev.started_at || 0)) { | ||
| byName.set(c.name, c); | ||
| } | ||
| } | ||
| const latest = [...byName.values()].filter(c => c.status === 'completed'); | ||
| // Do NOT treat cancelled as failure (concurrency cancel-in-progress is normal) | ||
| const failed = latest.filter(c => | ||
| ['failure', 'timed_out', 'action_required'].includes(c.conclusion) | ||
| ); | ||
| if (failed.length > 0) { | ||
| statusFailed = true; | ||
| failCount = failed.length; | ||
| } | ||
| } catch (e) { | ||
| core.info(`PR #${pr.number} checks skip: ${e.message}`); | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
file=".github/workflows/agent-continuous-ops.yml"
printf '%s\n' '--- workflow lines 120-185 ---'
sed -n '120,185p' "$file"
printf '%s\n' '--- status/checks references ---'
rg -n -C 3 'statuses|listCommitStatuses|checks\.|listForRef|statusFailed|failure|timed_out|action_required' "$file"Repository: timerloggedout-spec/termux-monorepo
Length of output: 6509
🏁 Script executed:
#!/bin/bash
set -eu
file=".github/workflows/agent-continuous-ops.yml"
printf '%s\n' '--- workflow header and setup ---'
sed -n '1,75p' "$file"
printf '%s\n' '--- all status API references in workflow ---'
rg -n -C 2 'getCombinedStatusForRef|listCommitStatusesForRef|repos\.getCommitStatus|statuses|checks' "$file"
printf '%s\n' '--- static verifier for the claimed gap ---'
python3 - <<'PY'
from pathlib import Path
p = Path(".github/workflows/agent-continuous-ops.yml")
text = p.read_text()
required = [
"github.paginate(github.rest.checks.listForRef",
"['failure', 'timed_out', 'action_required']",
"statuses: read",
]
for needle in required:
assert needle in text, needle
assert "github.rest.repos.getCombinedStatusForRef" not in text
assert "github.rest.repos.listCommitStatusesForRef" not in text
print("Check Runs logic and statuses: read permission present; no commit-status API call found")
PYRepository: timerloggedout-spec/termux-monorepo
Length of output: 4477
🌐 Web query:
site:docs.github.com/en/rest/commits/statuses combined status for a specific reference failure latest status context error failure
💡 Result:
In the context of the GitHub REST API, the combined status for a specific reference (such as a commit SHA, branch, or tag) is a summary state that aggregates all individual statuses reported by various external services or tools [1]. Each individual status includes a context—a label used to distinguish between different systems like continuous integration (CI) or security scanners—and a state of error, failure, pending, or success [1]. The combined state is determined by the following rules [1]: - failure: Reported if any of the individual contexts report a state of error or failure. - pending: Reported if there are no statuses for the reference or if at least one context is in a pending state. - success: Reported only if the latest status for every individual context is success. When retrieving the combined status, the API returns the full list of statuses in reverse chronological order, with the most recent status for each context listed first [1].
Citations:
Read the combined commit status before setting statusFailed.
checks.listForRef does not include Commit Statuses. Call github.rest.repos.getCombinedStatusForRef for pr.head.sha and set statusFailed when data.state === 'failure'. Merge this result with failed Check Runs, and keep failCount nonzero for the nudge reason. Add a test where a Commit Status is the only failed context.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/agent-continuous-ops.yml around lines 142 - 170, The check
evaluation around github.paginate must also call
github.rest.repos.getCombinedStatusForRef for pr.head.sha and treat a returned
state of failure as failed. Merge that result with the existing failed Check
Runs, ensuring statusFailed is set and failCount remains nonzero when Commit
Status is the only failure; add coverage for that scenario.
| ## Rules | ||
| 1. Automated comments: **display** moniker in backticks; **ping** only the live trigger (`@jules`, `@gemini-cli`). | ||
| 2. Workflows matching `@gemini-cli` **must** also accept `@sparkFlux` case-insensitively. | ||
| 3. Never put secrets or Class 3/4 material in moniker docs. | ||
| 4. If a moniker string is later registered as a GH username we do not control, keep it non-@ only. | ||
|
|
||
| ## High-performance intent |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Add blank lines below both headings.
markdownlint reports MD022 at Lines 18 and 24. Add one blank line after ## Rules and ## High-performance intent.
🧰 Tools
🪛 markdownlint-cli2 (0.23.2)
[warning] 18-18: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
[warning] 24-24: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/ops/AGENT-MONIKERS.md` around lines 18 - 24, Add one blank line
immediately after the “## Rules” heading and another immediately after “##
High-performance intent” in the documentation, preserving the existing list and
content.
Source: Linters/SAST tools
Summary
OPERATOR rewrite addressing #160 review (CHANGES_REQUESTED) and #159 4-day stall bug under high-performance constraints.
Monikers (creative, still callable)
@jules@gemini-cli@coderabbitaiSSOT:
docs/ops/AGENT-MONIKERS.mdContinuous-ops performance / correctness fixes
<!-- continuous-agent-ops -->self-nudges from loop + approval detectors (stops infinite re-nudge).checks: read+statuses: readso failing-check detection works with GITHUB_TOKEN.timed_out/cancelled/action_required.@heyVern @julesso Jules still fires while moniker lands.Gemini dispatch
@gemini-cliand@sparkFluxprefixes for /review, /triage, invoke.Supersedes / coordinates
Fixes intent of #159
Addresses review on #160
Signed-off-by: Grok (OPERATOR) session-2026-08-10
Summary by CodeRabbit
New Features
Documentation