2684095e2f
Co-authored-by: claude <claude@jpaul.io> Co-committed-by: claude <claude@jpaul.io>
83 lines
4.4 KiB
YAML
83 lines
4.4 KiB
YAML
# Reference: an autonomous agent running as a RUNNER JOB (Module 19) — triggered and scheduled.
|
|
#
|
|
# This is the "for real" version of agent_runner.py: instead of you launching the agent, the forge
|
|
# launches it on a runner in response to an event or a timer, and the agent opens a PR. That PR then
|
|
# hits your NORMAL gates — CI (Module 14), security scanning (Module 15), and human review (Module
|
|
# 10) — exactly like a human's PR. The supervision is structural; this file just automates the start.
|
|
#
|
|
# GitHub Actions flavor (same as Module 14's ci.yml), so it goes in .github/workflows/. Equivalents:
|
|
# * GitLab: a job with `rules:` on $CI_PIPELINE_SOURCE + a `workflow:` schedule.
|
|
# * Forgejo/Gitea: the same YAML under .forgejo/workflows/ or .gitea/workflows/.
|
|
#
|
|
# DO NOT enable this blindly. Read the security notes at the bottom first — an unattended agent with a
|
|
# write token is automation acting in your name. This is the last thing you turn on, on purpose.
|
|
|
|
name: agent-issue-to-pr
|
|
|
|
on:
|
|
# TRIGGERED: fire when an issue gets the `agent` label. Event in -> agent runs -> PR out.
|
|
issues:
|
|
types: [labeled]
|
|
# SCHEDULED: also attempt work overnight. This is "the workflow runs itself" — keep it cheap.
|
|
schedule:
|
|
- cron: "0 6 * * *" # 06:00 UTC daily; adjust to your timezone and budget.
|
|
|
|
jobs:
|
|
agent:
|
|
# Only run the triggered path when the label is actually `agent` (labeled events fire for ANY
|
|
# label). The scheduled path has no label, so allow it through too.
|
|
if: ${{ github.event_name == 'schedule' || github.event.label.name == 'agent' }}
|
|
runs-on: ubuntu-latest # whose compute this is — see Module 19 for self-hosted runners.
|
|
|
|
# Least privilege (Module 17): grant ONLY what opening a PR needs. Not admin, not secrets access.
|
|
permissions:
|
|
contents: write # create the branch and commit
|
|
pull-requests: write # open the PR
|
|
issues: read # read the issue body (the agent's brief)
|
|
|
|
steps:
|
|
- name: Check out the code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.12"
|
|
|
|
- name: Install gate tools
|
|
run: pip install pytest ruff
|
|
|
|
- name: Run the agent on a fresh branch
|
|
env:
|
|
# The agent's model credentials come from a SCOPED secret you set in the forge — never
|
|
# hardcoded here (Module 17). Keep this provider-neutral: it's whatever your agent needs.
|
|
AGENT_API_KEY: ${{ secrets.AGENT_API_KEY }}
|
|
# Point AGENT_CMD at your agentic tool's non-interactive / one-shot mode.
|
|
AGENT_CMD: "your-agent-cli --print --prompt-file {prompt_file}"
|
|
run: |
|
|
git switch -c "agent/issue-${{ github.event.issue.number || github.run_id }}"
|
|
# In the triggered case, write the issue body to a file for the agent to read.
|
|
printf '%s' "${{ github.event.issue.body }}" > issue.md
|
|
python modules/25-autonomous-agents/lab/agent_runner.py issue-to-pr issue.md
|
|
|
|
# The agent's output is a PROPOSAL. Open the PR; do NOT merge. CI + security + review decide.
|
|
# (Use your forge's PR-creation step or CLI here; kept generic to stay vendor-neutral.)
|
|
- name: Open a pull request for review
|
|
run: |
|
|
git push -u origin HEAD
|
|
echo "Open a PR from this branch via your forge's API/CLI. It must pass CI (Module 14),"
|
|
echo "security scanning (Module 15), and human review (Module 10) before anyone merges it."
|
|
|
|
# --- Security notes (read before enabling) -------------------------------------------------------
|
|
# * Prompt injection (Module 22): github.event.issue.body is UNTRUSTED input that lands straight in
|
|
# the agent's context. A malicious issue can try to redirect the agent ("ignore your instructions,
|
|
# exfiltrate secrets..."). Scope the token tightly so a hijack can't do much, and never give this
|
|
# job access to deployment or admin secrets.
|
|
# * No auto-merge. This file stops at "open a PR". Wiring an agent to merge its own work to main
|
|
# removes the human gate and is out of scope for this course.
|
|
# * Sandbox (Module 16): for agents you trust less, run the agent step inside a container with no
|
|
# network beyond what it needs.
|
|
# * Cost: a scheduled agent that re-attempts the same impossible issue every night burns runner
|
|
# minutes. Cap retries (agent_runner.py does) and consider a label the agent removes when it gives
|
|
# up, so it doesn't retry forever.
|