Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions templates/consumer-repo/docs/LABELS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ This document describes all labels that trigger automated workflows or affect CI
| `autofix:clean` | PR labeled | Triggers clean-mode autofix (more aggressive)
| `agent:codex` | Issue or PR labeled | Routes the issue or PR to the Codex agent
| `agent:claude` | Issue or PR labeled | Routes the issue or PR to the Claude Code agent
| `agent:cursor` | Issue or PR labeled | Registered routing label; no consumer Gate-followup runner is currently wired
| `agent:gemini` | Issue or PR labeled | Registered routing label; no consumer Gate-followup runner is currently wired
| `agent:cursor` | Issue or PR labeled | Routes consumer Gate-followup keepalive to the Cursor runner
| `agent:gemini` | Issue or PR labeled | Routes consumer Gate-followup keepalive to the Gemini runner
| `agent:aider` | Issue or PR labeled | Routes the issue or PR to the Aider agent for cheap, low-complexity tasks — runner lands in a follow-up phase
| `agent:auto` | Issue or PR labeled | Delegates routing to the auto-delegation policy; do not combine with concrete `agent:<name>` labels
| `agent:retry` | PR labeled | Consolidated consumers require a manual Gate-followups dispatch; the root/non-consolidated keepalive workflow forces a retry and clears recovery labels
Expand Down Expand Up @@ -140,14 +140,14 @@ This document describes all labels that trigger automated workflows or affect CI

**Effect:**
1. Identifies Cursor as the intended route in registry-aware automation
2. Does **not** dispatch a consumer PR keepalive runner: `agents-81-gate-followups.yml` currently has runner jobs only for Codex and Claude
2. On PRs, dispatches the `run-cursor` consumer keepalive job in `agents-81-gate-followups.yml`
3. Branch prefix `cursor/issue-<number>` is reserved for Cursor work (see `.github/agents/registry.yml`)
Comment thread
stranske marked this conversation as resolved.

**Prerequisites:**
- Repository has a valid `CURSOR_API_KEY` secret (per `.github/agents/registry.yml`)
- Issue or PR should have clear requirements

**Workflow:** Registry-aware workflows may recognize the label, but the consumer Gate-followup workflow has no Cursor runner job. Do not use this label to promise PR keepalive execution until that job is delivered from the canonical Workflows source.
**Workflow:** On PRs, `agents-81-gate-followups.yml` dispatches `reusable-cursor-run.yml` after registry-backed routing and secret preflight succeed.

---

Expand All @@ -159,13 +159,13 @@ This document describes all labels that trigger automated workflows or affect CI

**Effect:**
1. Identifies Gemini as the intended route in registry-aware automation
2. Does **not** dispatch a consumer PR keepalive runner: `agents-81-gate-followups.yml` currently has runner jobs only for Codex and Claude
2. On PRs, dispatches the `run-gemini` consumer keepalive job in `agents-81-gate-followups.yml`
3. Branch prefix `gemini/issue-<number>` is reserved for Gemini work

**Prerequisites:**
- Repository has a valid `GEMINI_API_KEY` secret (per `.github/agents/registry.yml`)

**Workflow:** Registry-aware workflows may recognize the label, but the consumer Gate-followup workflow has no Gemini runner job. Do not use this label to promise PR keepalive execution until that job is delivered from the canonical Workflows source.
**Workflow:** On PRs, `agents-81-gate-followups.yml` dispatches `reusable-gemini-run.yml` after registry-backed routing and secret preflight succeed.

---

Expand Down
49 changes: 46 additions & 3 deletions tests/docs/test_consumer_ci_system_guide.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from pathlib import Path

import yaml
from scripts.sync_manifest_compiler import compile_manifest

GUIDE = Path("templates/consumer-repo/docs/CI_SYSTEM_GUIDE.md")


Expand Down Expand Up @@ -33,9 +36,25 @@ def test_consumer_ci_guide_matches_current_agent_entrypoints() -> None:


def test_consumer_operator_docs_match_gate_followup_topology() -> None:
repo_root = Path(__file__).resolve().parents[2]
root_labels = Path("docs/LABELS.md").read_text(encoding="utf-8")
labels = Path("templates/consumer-repo/docs/LABELS.md").read_text(encoding="utf-8")
setup = Path("templates/consumer-repo/docs/SETUP_CHECKLIST.md").read_text(encoding="utf-8")
compiled = compile_manifest(repo_root / ".github/sync-manifest.yml", repo_root=repo_root)
labels_entry = next(
entry for entry in compiled.section("docs") if entry.target == "docs/LABELS.md"
)
gate_followups_entry = next(
entry
for entry in compiled.section("workflows")
if entry.target == ".github/workflows/agents-81-gate-followups.yml"
)
assert labels_entry.source_tree == "template"
assert gate_followups_entry.source_tree == "template"
labels = (repo_root / labels_entry.resolved_source).read_text(encoding="utf-8")
gate_followups = yaml.safe_load(
(repo_root / gate_followups_entry.resolved_source).read_text(encoding="utf-8")
)
jobs = gate_followups["jobs"]

assert "Root/non-consolidated: sets `force_retry=true`" in root_labels
assert ".github/workflows/agents-keepalive-loop.yml" in root_labels
Expand All @@ -45,8 +64,32 @@ def test_consumer_operator_docs_match_gate_followup_topology() -> None:
):
assert retired_surface not in labels

assert "no Cursor runner job" in labels
assert "no Gemini runner job" in labels
for agent, display_name in (("cursor", "Cursor"), ("gemini", "Gemini")):
job_id = f"run-{agent}"
job = jobs[job_id]
assert job["uses"] == f"stranske/Workflows/.github/workflows/reusable-{agent}-run.yml@main"
expected_condition = " ".join(
(
f"needs.evaluate.outputs.agent_type == '{agent}' &&",
"needs.evaluate.outputs.dispatch_should_run == 'true' &&",
"(needs.evaluate.outputs.action == 'run' ||",
"needs.evaluate.outputs.action == 'fix' ||",
"needs.evaluate.outputs.action == 'conflict')",
)
)
assert " ".join(job["if"].split()) == expected_condition

section_start = labels.index(f"### `agent:{agent}`")
section_end = labels.index("\n---", section_start)
label_section = labels[section_start:section_end]
assert (
f"| `agent:{agent}` | Issue or PR labeled | "
f"Routes consumer Gate-followup keepalive to the {display_name} runner"
) in labels
assert f"On PRs, dispatches the `{job_id}` consumer keepalive job" in label_section
assert f"On PRs, `agents-81-gate-followups.yml` dispatches `reusable-{agent}-run.yml`" in (
label_section
)
assert "applying the label does not trigger a retry by itself" in labels
assert "Does not set `force_retry`" in labels
assert "agents-keepalive-loop.yml" not in labels
Expand Down
Loading