Skip to content
Open
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
2 changes: 1 addition & 1 deletion .github/aw/gh-aw-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@

v0.86.2
10 changes: 10 additions & 0 deletions .github/workflows/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Workflow authoring checklist

When adding or modifying an agentic workflow:

- Agents run in a sandbox. Use `bash: ["*"]`; do not try to duplicate that
boundary with a command allowlist.
- Assume the agent may need ordinary inspection and data-processing tools such
as `jq`, even when the authored prompt does not predict every command.
- Do not replace `bash: ["*"]` with a narrower list during security or cleanup
review unless a maintainer explicitly requests that restriction.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
gh aw compile drafter review fix queue-triage ci-triage --approve
gh aw compile drafter review fix queue-triage ci-triage retro --approve

- name: Check for lock drift
run: |
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/install-labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
{ name: 'agent/fix-working', description: 'The fix agent is actively working on this PR', color: 'FBCA04' },
{ name: 'agent/workflow-edits-allowed', description: 'Pre-authorizes agent runs to edit protected files without the request_review gate', color: '5319E7' },
{ name: 'agent/flake-tracker', description: 'Marks the CI flake tracker issue the merge queue analyzer maintains', color: '1D76DB' },
{ name: 'agent/retro', description: 'Marks improvement issues filed by the retrospective analyzer', color: '1D76DB' },
];

const { owner, repo } = context.repo;
Expand Down
1,798 changes: 1,798 additions & 0 deletions .github/workflows/retro.lock.yml

Large diffs are not rendered by default.

260 changes: 260 additions & 0 deletions .github/workflows/retro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
---
# Retro — retrospective analysis of workflow runs across bootc-dev repos.
# Standalone in this host repository: deliberately excluded from aw.yml, so
# downstream gh aw add installations do not deploy or schedule it.
#
# Trigger: schedule (every 6 hours) or workflow_dispatch
# Reads: workflow runs from target repositories, existing issues
# Writes: new issues with improvement suggestions (via create-issue safe-output)
# Next: nothing automated - issue triage and implementation are left to humans
# Docs: README.md, "Retrospective analyzer"
#
# YAML comments like this one are stripped at compile time and never reach
# the agent; the markdown body below is the prompt. See README.md,
# "Where to document a workflow".
description: |
Retrospective analyzer. Runs in this repository on a schedule, analyzes
workflow runs in active bootc-dev repositories, identifies patterns, and
files improvement issues here where appropriate (avoiding duplicates).

on:
schedule:
# Every 6 hours at :17 past the hour — avoids the :00 stampede while
# spreading load across the day. Runs at 00:17, 06:17, 12:17, 18:17 UTC.
- cron: "17 */6 * * *"
workflow_dispatch:
inputs:
target_repos:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should scan the whole bootc-dev org by default

description: "Comma-separated list of repos to analyze (owner/repo format)"
required: false
type: string
lookback_days:
description: "Number of days of history to analyze"
required: false
type: string
default: "7"

# A retrospective can take longer than its schedule interval. Keep one active
# run without canceling its useful analysis when the next schedule fires.
concurrency:
group: "gh-aw-${{ github.workflow }}"
cancel-in-progress: false

permissions:
contents: read
actions: read
issues: read
pull-requests: read

model: claude-sonnet-4-5-20250929
engine:
id: claude
network: defaults

tools:
bash: ["*"]
github:
toolsets: [default, actions]
min-integrity: approved
trusted-users: ["${{ vars.GH_AW_APP_BOT_SLUG }}"]

safe-outputs:
github-app:
client-id: ${{ vars.GH_AW_APP_CLIENT_ID }}
private-key: ${{ secrets.GH_AW_APP_PRIVATE_KEY }}
create-issue:
# Cap at a reasonable number per retro run — if the agent finds more than
# this many distinct improvement opportunities in one pass, batch them or
# prioritize the most impactful ones.
max: 5
labels: ["agent/retro"]
noop:
missing-data:

timeout-minutes: 20

# Pre-fetch and validate the target list before the agent starts. This does not
# fetch run data; the agent reads runs with GitHub MCP after receiving a bounded,
# deterministic list of repositories and a validated lookback window.
steps:
- name: Pre-fetch retro data
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
INPUT_REPOS: ${{ github.event.inputs.target_repos }}
LOOKBACK_DAYS: ${{ github.event.inputs.lookback_days || '7' }}
REPO: ${{ github.repository }}
OWNER: ${{ github.repository_owner }}
run: |
set -euo pipefail

BASE_DIR="/tmp/gh-aw/agent/retro"
mkdir -p "$BASE_DIR"

if ! [[ "$LOOKBACK_DAYS" =~ ^[0-9]+$ ]] || [ "$LOOKBACK_DAYS" -lt 1 ] || [ "$LOOKBACK_DAYS" -gt 90 ]; then
echo "::error::lookback_days must be a whole number from 1 through 90; got '$LOOKBACK_DAYS'."
exit 1
fi

WARNINGS="$BASE_DIR/inaccessible-repos.txt"
: > "$WARNINGS"
TARGETS="$BASE_DIR/target-repos.txt"
: > "$TARGETS"
TARGET_STATE="$BASE_DIR/target-state.txt"

# A dispatch override is intentionally limited to this organization and
# verified as active/non-fork. The host may be named explicitly, but the
# organization-wide default excludes it because retro runs from here and
# is intended to scan the other repositories.
if [ -n "${INPUT_REPOS:-}" ]; then
declare -A seen=()
while IFS= read -r target; do
target="${target#"${target%%[![:space:]]*}"}"
target="${target%"${target##*[![:space:]]}"}"
if ! [[ "$target" =~ ^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$ ]]; then
echo "::error::target_repos entry '$target' must use owner/repo format."
exit 1
fi
if [ "${target%%/*}" != "$OWNER" ]; then
echo "::error::target_repos entry '$target' is outside organization '$OWNER'."
exit 1
fi
if [ -n "${seen[$target]:-}" ]; then
continue
fi
seen[$target]=1
if metadata=$(gh api "repos/$target" 2>&1); then
if repo_name=$(jq -er 'select(.archived == false and .fork == false) | .full_name' <<<"$metadata"); then
printf '%s\n' "$repo_name" >> "$TARGETS"
else
printf '%s\n' "$target is archived or a fork and was skipped." >> "$WARNINGS"
fi
else
printf '%s\n' "$target could not be read and was skipped: $metadata" >> "$WARNINGS"
fi
done < <(printf '%s' "$INPUT_REPOS" | tr ',' '\n')
else
DISCOVERED="$BASE_DIR/discovered-repos.json"
DISCOVERY_ERROR="$BASE_DIR/discovery-error.txt"
if ! gh api --paginate "orgs/$OWNER/repos?type=all&per_page=100" > "$DISCOVERED" 2> "$DISCOVERY_ERROR"; then
{
echo "Could not list repositories for organization '$OWNER'."
cat "$DISCOVERY_ERROR"
} >> "$WARNINGS"
else
jq -sr --arg host "$REPO" '[.[][] | select(.archived == false and .fork == false and .full_name != $host) | .full_name] | sort | .[]' "$DISCOVERED" > "$TARGETS"
printf '%s\n' "Default discovery lists only repositories visible to this workflow's GITHUB_TOKEN; private or internal repositories without token access cannot be analyzed." >> "$WARNINGS"
fi
fi

if [ ! -s "$TARGETS" ]; then
printf '%s\n' "No accessible active, non-fork target repositories were found. Do not analyze runs; report this through missing-data." >> "$WARNINGS"
printf '%s\n' "empty" > "$TARGET_STATE"
else
printf '%s\n' "ready" > "$TARGET_STATE"
fi

CUTOFF_DATE=$(date -u -d "$LOOKBACK_DAYS days ago" '+%Y-%m-%dT%H:%M:%SZ' 2>/dev/null \
|| date -u "-v-${LOOKBACK_DAYS}d" '+%Y-%m-%dT%H:%M:%SZ')
echo "Lookback window: runs created after $CUTOFF_DATE"
echo "$CUTOFF_DATE" > "$BASE_DIR/cutoff-date.txt"

{
echo "=== Retro Pre-Analysis ==="
echo "Target repositories (from $TARGETS):"
cat "$TARGETS"
echo ""
echo "Target state (from $TARGET_STATE):"
cat "$TARGET_STATE"
echo ""
echo "Lookback window: $LOOKBACK_DAYS days (after $CUTOFF_DATE)"
echo ""
echo "Access limitations (from $WARNINGS):"
cat "$WARNINGS"
echo ""
echo "The agent should:"
echo "1. List and analyze workflow runs in these repos from the lookback window"
echo "2. Identify patterns: recurring failures, slow workflows, flaky tests, etc."
echo "3. Check existing issues (labeled 'agent/retro' or related) to avoid duplicates"
echo "4. File new issues for actionable improvements via create-issue safe-output"
echo "5. Call noop if no new issues are warranted this run"
} | tee "$BASE_DIR/summary.txt"

echo ""
echo "Pre-analysis complete. Agent should start with $BASE_DIR/summary.txt"
---

# Retro: Workflow Retrospective Analyzer

You're running from the host `gh-agentic-workflows` repository. You analyze
workflow runs in the target repositories selected by pre-fetch, but duplicate
searches and every new improvement issue are centralized in this host repository.

## Your task

1. **Read the pre-fetch summary** at `/tmp/gh-aw/agent/retro/summary.txt` to
see which repos to analyze and the lookback window.

2. **Stop on an empty target state**: Read
`/tmp/gh-aw/agent/retro/target-state.txt`. If it says `empty`, do not query
GitHub, analyze runs, or check duplicates. Call `missing-data` with the
relevant warnings from `inaccessible-repos.txt`, then stop.

3. **Analyze workflow runs** in each target repository:
- List workflow runs from the lookback window using GitHub MCP tools
- Identify patterns worth investigating:
- Recurring failures (same workflow/job failing repeatedly)
- Long-running workflows that could be optimized
- Flaky tests or intermittent issues
- Underutilized or overly complex workflows
- Error patterns in failed runs
- Look for opportunities to improve the agentic pipeline itself
(drafter/review/fix/merge) based on how it's performing in practice

4. **Check for duplicate issues**:
- List existing open issues in the host repository (`gh-agentic-workflows`)
labeled `agent/retro` or related to the patterns you've identified
- Don't file an issue if an open one already covers the same improvement
- If an existing issue is stale or incomplete, note that in your analysis
but don't create a duplicate

5. **File actionable issues**:
- For each distinct, actionable improvement you identify, create one issue
via the `create-issue` safe-output
- Each issue should include:
- Clear title describing the improvement opportunity
- Evidence from the analysis (which repos, which runs, frequency, etc.)
- Concrete suggested action (what should change and why)
- Links to example workflow runs demonstrating the pattern
- Label each issue `agent/retro` (done automatically by the safe-output config)
- Cap at 5 issues per run — if you find more, prioritize the highest-impact
ones and note in one issue that there are additional opportunities

6. **Output**:
- If you file any issues, you're done (create-issue safe-output called)
- If no new issues are warranted (everything looks good, or all relevant
issues already exist), call `noop` with a summary of what you checked
- If you can't complete the analysis (GitHub API errors, missing data, etc.),
call `missing-data` describing what went wrong

## Constraints

- Only analyze the repositories listed in `/tmp/gh-aw/agent/retro/target-repos.txt`
- Do not analyze anything when `target-state.txt` says `empty`; call
`missing-data` and stop instead
- Only look at runs within the lookback window (after the cutoff date in
`cutoff-date.txt`)
- Never create duplicate issues — always check existing open issues first
- Focus on actionable improvements with clear evidence, not vague hunches
- Each issue should stand alone and be immediately actionable by a human or
another agent
- Respect the 5-issue-per-run cap — quality over quantity
- Report inaccessible repositories from `inaccessible-repos.txt` via `missing-data`
when access prevents a useful organization-wide analysis; do not claim that
private or internal repositories were covered unless they appear in the target list

## Context

This repository contains the gh-agentic-workflows pipeline itself (drafter →
review → fix → merge), plus ci-triage, queue-triage, and other workflows. Look
for patterns that would improve the pipeline's effectiveness, reduce noise, or
make the agents more helpful to contributors.
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,24 @@ runs. The canonical authored workflow definitions are
and [`queue-triage.md`](.github/workflows/queue-triage.md). The `.md` files are the
canonical gh-aw sources; their matching `.lock.yml` files are generated artifacts.

## Retrospective analyzer

`retro.md` is a host-only scheduled workflow for this repository. It is deliberately
excluded from `aw.yml`, so `gh aw add` consumers do not install or run it. Every six
hours it runs from `bootc-dev/gh-agentic-workflows`, discovers active, non-archived,
non-fork repositories in its organization, and analyzes their recent workflow runs.
The host repository is excluded from the default target set because the intended scope
is the other organization repositories; a manual `target_repos` dispatch override may
include it. Duplicate searches and any new `agent/retro` improvement issues are always
performed in the host repository, not target repositories.

The workflow's `GITHUB_TOKEN` can only discover and analyze repositories it can read.
It reports this limitation in its pre-fetch data and does not claim coverage of private
or internal repositories that are inaccessible to that token. A manual dispatch accepts
comma-separated, whitespace-trimmed `owner/repo` targets from the host organization and
validates that each is active and not a fork; `lookback_days` must be an integer from 1
through 90.

## Design notes and gotchas

A few things here are non-obvious and were hard-won getting this to actually work:
Expand Down Expand Up @@ -230,9 +248,10 @@ now at least readable by the agent, but it was never the intended recovery path.

## Repository setup checklist

1. Create eight labels: `agent/code`, `agent/fixme`, `agent/lgtm`, `agent/drafter-working`,
1. Create nine labels: `agent/code`, `agent/fixme`, `agent/lgtm`, `agent/drafter-working`,
`agent/review-working`, `agent/fix-working`, `agent/workflow-edits-allowed`,
`agent/flake-tracker` (see "Letting the agent edit protected files" above). The three
`agent/flake-tracker`, `agent/retro` (see "Letting the agent edit protected files"
above). The three
`agent/*-working` labels just need to exist; their color is cosmetic (see "a per-workflow
`agent/*-working` label is added and removed via frontmatter `jobs:`" above).
`agent/flake-tracker` is only needed for merge-queue CI failure analysis (see
Expand All @@ -258,6 +277,8 @@ now at least readable by the agent, but it was never the intended recovery path.
--description "Pre-authorizes agent runs to edit protected files without the request_review gate"
gh label create "agent/flake-tracker" --color 1D76DB \
--description "Marks the CI flake tracker issue the merge queue analyzer maintains"
gh label create "agent/retro" --color 1D76DB \
--description "Marks improvement issues filed by the retrospective analyzer"
```

See [`scripts/README.md`](scripts/README.md) for more installation options.
Expand Down Expand Up @@ -458,6 +479,9 @@ standard pipeline across `bootc-dev`'s other active repos. Roughly in order:

Workflow sources live under `.github/workflows/`; see "Overview" above for the canonical
definitions. Matching `*.lock.yml` files are generated artifacts checked into the repo.
[`retro.md`](.github/workflows/retro.md) is a host-only retrospective analyzer, excluded
from `aw.yml`; it scans accessible organization repositories but centralizes issues in
this repository — see "Retrospective analyzer" above.
[`upgrade.yml`](.github/workflows/upgrade.yml) is a separate, plain maintenance workflow:
weekly, it self-upgrades the `gh-aw` CLI, refreshes `.github/aw/gh-aw-version` and
`.github/aw/actions-lock.json` to match, recompiles every `.md` workflow, and opens a PR
Expand Down
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ setup:

# Compile all gh-aw workflow .md sources to .lock.yml (run `just setup` first).
compile:
gh aw compile drafter review fix queue-triage ci-triage --approve
gh aw compile drafter review fix queue-triage ci-triage retro --approve

# Setup + compile in one step.
all: setup compile
5 changes: 5 additions & 0 deletions scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ The script creates or updates the following labels:

- **`agent/workflow-edits-allowed`** (purple) — Pre-authorizes an agent run to edit protected files (workflows, README, etc.) without triggering the request_review gate. Apply this to an issue before labeling it `agent/code`, or to a PR before applying `agent/fixme`.

- **`agent/retro`** (blue) — Marks improvement issues filed by this repository's host-only retrospective analyzer. It is not needed by downstream pipeline installations.

### Usage

#### Via GitHub Actions
Expand Down Expand Up @@ -77,6 +79,9 @@ gh label create "agent/fix-working" --color FBCA04 \

gh label create "agent/workflow-edits-allowed" --color 5319E7 \
--description "Pre-authorizes agent runs to edit protected files without the request_review gate"

gh label create "agent/retro" --color 1D76DB \
--description "Marks improvement issues filed by the retrospective analyzer"
```

Or via `gh api`, e.g. to update an existing label:
Expand Down
5 changes: 5 additions & 0 deletions scripts/install-labels.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ const LABELS = [
description: 'Marks the CI flake tracker issue the merge queue analyzer maintains',
color: '1D76DB', // blue
},
{
name: 'agent/retro',
description: 'Marks improvement issues filed by the retrospective analyzer',
color: '1D76DB', // blue
},
];

/**
Expand Down
Loading