From 5b17c8ba1ab30c63b8d1ee38f706d215154fdc17 Mon Sep 17 00:00:00 2001 From: Gunju Kim Date: Thu, 12 Feb 2026 12:07:48 +0000 Subject: [PATCH] Add three new example use cases: PR review, multi-repo migration, and security audit Add production-ready TaskSpawner examples that demonstrate Axon's versatility beyond basic bug fixing: - 05-pr-review-spawner: Label-driven PR review with AgentConfig and custom skills. Shows the githubIssues source with types: [pulls] and the excludeLabels feedback pattern. - 06-multi-repo-migration: Fleet-wide migration pattern with one TaskSpawner per repository sharing a common AgentConfig. Demonstrates Axon's parallel execution for cross-repo refactoring. - 07-security-audit-cron: Periodic security scanning with conditional output (only creates issues when findings exist). Shows cron-based TaskSpawner with AgentConfig for structured audit instructions. Co-Authored-By: Claude Opus 4.6 --- examples/05-pr-review-spawner/README.md | 40 +++++++ .../05-pr-review-spawner/agentconfig.yaml | 31 +++++ .../credentials-secret.yaml | 7 ++ .../github-token-secret.yaml | 7 ++ .../05-pr-review-spawner/taskspawner.yaml | 39 +++++++ examples/05-pr-review-spawner/workspace.yaml | 9 ++ examples/06-multi-repo-migration/README.md | 53 +++++++++ .../06-multi-repo-migration/agentconfig.yaml | 15 +++ .../credentials-secret.yaml | 7 ++ .../github-token-secret.yaml | 7 ++ .../06-multi-repo-migration/taskspawners.yaml | 106 ++++++++++++++++++ .../06-multi-repo-migration/workspaces.yaml | 29 +++++ examples/07-security-audit-cron/README.md | 47 ++++++++ .../07-security-audit-cron/agentconfig.yaml | 24 ++++ .../credentials-secret.yaml | 7 ++ .../github-token-secret.yaml | 7 ++ .../07-security-audit-cron/taskspawner.yaml | 41 +++++++ .../07-security-audit-cron/workspace.yaml | 9 ++ examples/README.md | 3 + 19 files changed, 488 insertions(+) create mode 100644 examples/05-pr-review-spawner/README.md create mode 100644 examples/05-pr-review-spawner/agentconfig.yaml create mode 100644 examples/05-pr-review-spawner/credentials-secret.yaml create mode 100644 examples/05-pr-review-spawner/github-token-secret.yaml create mode 100644 examples/05-pr-review-spawner/taskspawner.yaml create mode 100644 examples/05-pr-review-spawner/workspace.yaml create mode 100644 examples/06-multi-repo-migration/README.md create mode 100644 examples/06-multi-repo-migration/agentconfig.yaml create mode 100644 examples/06-multi-repo-migration/credentials-secret.yaml create mode 100644 examples/06-multi-repo-migration/github-token-secret.yaml create mode 100644 examples/06-multi-repo-migration/taskspawners.yaml create mode 100644 examples/06-multi-repo-migration/workspaces.yaml create mode 100644 examples/07-security-audit-cron/README.md create mode 100644 examples/07-security-audit-cron/agentconfig.yaml create mode 100644 examples/07-security-audit-cron/credentials-secret.yaml create mode 100644 examples/07-security-audit-cron/github-token-secret.yaml create mode 100644 examples/07-security-audit-cron/taskspawner.yaml create mode 100644 examples/07-security-audit-cron/workspace.yaml diff --git a/examples/05-pr-review-spawner/README.md b/examples/05-pr-review-spawner/README.md new file mode 100644 index 00000000..728527a7 --- /dev/null +++ b/examples/05-pr-review-spawner/README.md @@ -0,0 +1,40 @@ +# PR Review Spawner + +Automatically review open pull requests using an AI agent. The spawner +discovers PRs with a specific label and creates a Task for each one. The +agent reads the diff, checks for common issues, and posts a review comment. + +## How It Works + +1. A developer opens a PR and adds the `needs-ai-review` label. +2. TaskSpawner discovers the labeled PR and creates a Task. +3. The agent clones the repo, reads the PR diff and description, and posts + a review via the `gh` CLI. +4. After the review, the agent removes the trigger label and adds + `ai-reviewed` so it is not picked up again. + +## Resources + +| File | Description | +|------|-------------| +| `workspace.yaml` | Git repo the agent clones | +| `credentials-secret.yaml` | Agent credentials (OAuth token) | +| `github-token-secret.yaml` | GitHub token for cloning and `gh` CLI | +| `agentconfig.yaml` | Review instructions and skill | +| `taskspawner.yaml` | TaskSpawner watching for labeled PRs | + +## Setup + +1. Replace all `# TODO:` placeholders in the YAML files. +2. Create the GitHub labels `needs-ai-review` and `ai-reviewed` in your repo. +3. Apply all resources: + +```bash +kubectl apply -f examples/05-pr-review-spawner/ +``` + +4. Label a PR with `needs-ai-review` and watch the agent pick it up: + +```bash +axon get tasks -w +``` diff --git a/examples/05-pr-review-spawner/agentconfig.yaml b/examples/05-pr-review-spawner/agentconfig.yaml new file mode 100644 index 00000000..b23ed7cb --- /dev/null +++ b/examples/05-pr-review-spawner/agentconfig.yaml @@ -0,0 +1,31 @@ +apiVersion: axon.io/v1alpha1 +kind: AgentConfig +metadata: + name: pr-reviewer-config +spec: + agentsMD: | + You are a code reviewer. Your job is to review pull requests thoroughly + and leave constructive, actionable feedback. + + Guidelines: + - Focus on correctness, security, performance, and maintainability. + - Point out specific lines when suggesting changes. + - Acknowledge good patterns, not just problems. + - If the PR looks good, approve it with a short summary of what you checked. + - Do not nitpick style issues that a linter would catch. + plugins: + - name: reviewer + skills: + - name: review-pr + content: | + --- + name: review-pr + description: Review a pull request and post feedback + --- + To review a PR: + 1. Fetch the PR branch: `gh pr checkout ` + 2. Read the diff: `git diff main...HEAD` + 3. Read the PR description: `gh pr view ` + 4. Read any existing review comments: `gh api repos/{owner}/{repo}/pulls//comments` + 5. Post your review: `gh pr review --comment --body ""` + 6. Swap the labels: `gh pr edit --remove-label needs-ai-review --add-label ai-reviewed` diff --git a/examples/05-pr-review-spawner/credentials-secret.yaml b/examples/05-pr-review-spawner/credentials-secret.yaml new file mode 100644 index 00000000..0c6a74fb --- /dev/null +++ b/examples/05-pr-review-spawner/credentials-secret.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: claude-credentials +type: Opaque +stringData: + oauthToken: "" # TODO: replace with your Claude OAuth token diff --git a/examples/05-pr-review-spawner/github-token-secret.yaml b/examples/05-pr-review-spawner/github-token-secret.yaml new file mode 100644 index 00000000..33cadf72 --- /dev/null +++ b/examples/05-pr-review-spawner/github-token-secret.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: github-token +type: Opaque +stringData: + GITHUB_TOKEN: "" # TODO: replace with a GitHub token that has repo scope diff --git a/examples/05-pr-review-spawner/taskspawner.yaml b/examples/05-pr-review-spawner/taskspawner.yaml new file mode 100644 index 00000000..722e93c5 --- /dev/null +++ b/examples/05-pr-review-spawner/taskspawner.yaml @@ -0,0 +1,39 @@ +apiVersion: axon.io/v1alpha1 +kind: TaskSpawner +metadata: + name: pr-reviewer +spec: + when: + githubIssues: + types: + - pulls + labels: + - needs-ai-review + excludeLabels: + - ai-reviewed + state: open + taskTemplate: + type: claude-code + workspaceRef: + name: review-workspace + agentConfigRef: + name: pr-reviewer-config + credentials: + type: oauth + secretRef: + name: claude-credentials + promptTemplate: | + Review PR #{{.Number}}: {{.Title}} + + Description: + {{.Body}} + + Steps: + 1. Check out the PR branch and read the full diff against main. + 2. /review-pr {{.Number}} + + After reviewing, remove the "needs-ai-review" label and add "ai-reviewed": + gh pr edit {{.Number}} --remove-label needs-ai-review --add-label ai-reviewed + ttlSecondsAfterFinished: 3600 + pollInterval: 5m + maxConcurrency: 3 diff --git a/examples/05-pr-review-spawner/workspace.yaml b/examples/05-pr-review-spawner/workspace.yaml new file mode 100644 index 00000000..eea7d4b3 --- /dev/null +++ b/examples/05-pr-review-spawner/workspace.yaml @@ -0,0 +1,9 @@ +apiVersion: axon.io/v1alpha1 +kind: Workspace +metadata: + name: review-workspace +spec: + repo: https://github.com/your-org/your-repo.git # TODO: replace with your repo + ref: main + secretRef: + name: github-token diff --git a/examples/06-multi-repo-migration/README.md b/examples/06-multi-repo-migration/README.md new file mode 100644 index 00000000..e6bd8002 --- /dev/null +++ b/examples/06-multi-repo-migration/README.md @@ -0,0 +1,53 @@ +# Multi-Repo Migration + +Apply a repetitive change across multiple repositories using parallel agent +Tasks. This pattern is useful for fleet-wide refactoring, dependency bumps, +or API migration across microservices. + +## How It Works + +Each repository gets its own Workspace resource. A single TaskSpawner on +a cron schedule creates one Task per Workspace. Axon handles the +parallelism — all agents run concurrently in isolated Pods. + +This example shows three repos, but the pattern scales to any number. +Add more Workspace resources and corresponding TaskSpawner entries. + +Since TaskSpawner currently supports one Workspace per spawner, this +example uses one TaskSpawner per repository. A shared AgentConfig ensures +consistent behavior across all agents. + +## Resources + +| File | Description | +|------|-------------| +| `workspaces.yaml` | Workspace resources for each target repo | +| `credentials-secret.yaml` | Agent credentials (shared) | +| `github-token-secret.yaml` | GitHub token for cloning and pushing | +| `agentconfig.yaml` | Shared migration instructions | +| `taskspawners.yaml` | One TaskSpawner per repo, all on the same cron | + +## Setup + +1. Replace all `# TODO:` placeholders. +2. Add or remove Workspace/TaskSpawner pairs to match your repo list. +3. Apply: + +```bash +kubectl apply -f examples/06-multi-repo-migration/ +``` + +4. Monitor progress: + +```bash +axon get tasks -w +``` + +## Tips + +- Set `maxConcurrency: 1` on each TaskSpawner to ensure only one migration + attempt per repo at a time. +- Use `ttlSecondsAfterFinished: 0` if you want immediate cleanup after + each run. +- The cron schedule `"0 9 * * 1"` runs once a week (Monday 9 AM UTC). + Adjust to run once (`"0 9 12 2 *"`) for a one-time migration. diff --git a/examples/06-multi-repo-migration/agentconfig.yaml b/examples/06-multi-repo-migration/agentconfig.yaml new file mode 100644 index 00000000..dd22ce6b --- /dev/null +++ b/examples/06-multi-repo-migration/agentconfig.yaml @@ -0,0 +1,15 @@ +apiVersion: axon.io/v1alpha1 +kind: AgentConfig +metadata: + name: migration-config +spec: + agentsMD: | + You are performing a fleet-wide migration. Follow the migration + instructions exactly and do not make unrelated changes. If the + migration does not apply to this repo (e.g., the dependency is not + used), exit without creating a PR. + + After making changes: + 1. Run the project's test suite to verify nothing is broken. + 2. Create a PR with a clear title prefixed with "[Migration]". + 3. Include a summary of what changed and why in the PR description. diff --git a/examples/06-multi-repo-migration/credentials-secret.yaml b/examples/06-multi-repo-migration/credentials-secret.yaml new file mode 100644 index 00000000..0c6a74fb --- /dev/null +++ b/examples/06-multi-repo-migration/credentials-secret.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: claude-credentials +type: Opaque +stringData: + oauthToken: "" # TODO: replace with your Claude OAuth token diff --git a/examples/06-multi-repo-migration/github-token-secret.yaml b/examples/06-multi-repo-migration/github-token-secret.yaml new file mode 100644 index 00000000..33cadf72 --- /dev/null +++ b/examples/06-multi-repo-migration/github-token-secret.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: github-token +type: Opaque +stringData: + GITHUB_TOKEN: "" # TODO: replace with a GitHub token that has repo scope diff --git a/examples/06-multi-repo-migration/taskspawners.yaml b/examples/06-multi-repo-migration/taskspawners.yaml new file mode 100644 index 00000000..6f936be9 --- /dev/null +++ b/examples/06-multi-repo-migration/taskspawners.yaml @@ -0,0 +1,106 @@ +# One TaskSpawner per repository, all sharing the same migration prompt +# and AgentConfig. Add or remove entries to match your repo list. +apiVersion: axon.io/v1alpha1 +kind: TaskSpawner +metadata: + name: migrate-service-a +spec: + when: + cron: + schedule: "0 9 12 2 *" # TODO: adjust schedule (this runs Feb 12 at 9 AM UTC) + taskTemplate: + type: claude-code + workspaceRef: + name: service-a + agentConfigRef: + name: migration-config + credentials: + type: oauth + secretRef: + name: claude-credentials + promptTemplate: | + Migrate this repository from the deprecated `log/v1` package to `log/v2`. + + Steps: + 1. Find all imports of `github.com/your-org/log/v1`. # TODO: replace with actual migration + 2. Replace them with `github.com/your-org/log/v2`. + 3. Update any changed API calls (see migration guide below). + 4. Run tests and fix any compilation errors. + 5. Open a PR with the changes. + + Migration guide: + - `log.Info(msg)` -> `log.Info(msg, nil)` (second arg is now required attrs) + - `log.WithField(k, v)` -> `log.With(k, v)` + - `log.Fatal(msg)` is removed; use `log.Error(msg, nil); os.Exit(1)` + ttlSecondsAfterFinished: 3600 + maxConcurrency: 1 +--- +apiVersion: axon.io/v1alpha1 +kind: TaskSpawner +metadata: + name: migrate-service-b +spec: + when: + cron: + schedule: "0 9 12 2 *" # TODO: adjust schedule + taskTemplate: + type: claude-code + workspaceRef: + name: service-b + agentConfigRef: + name: migration-config + credentials: + type: oauth + secretRef: + name: claude-credentials + promptTemplate: | + Migrate this repository from the deprecated `log/v1` package to `log/v2`. + + Steps: + 1. Find all imports of `github.com/your-org/log/v1`. # TODO: replace with actual migration + 2. Replace them with `github.com/your-org/log/v2`. + 3. Update any changed API calls (see migration guide below). + 4. Run tests and fix any compilation errors. + 5. Open a PR with the changes. + + Migration guide: + - `log.Info(msg)` -> `log.Info(msg, nil)` (second arg is now required attrs) + - `log.WithField(k, v)` -> `log.With(k, v)` + - `log.Fatal(msg)` is removed; use `log.Error(msg, nil); os.Exit(1)` + ttlSecondsAfterFinished: 3600 + maxConcurrency: 1 +--- +apiVersion: axon.io/v1alpha1 +kind: TaskSpawner +metadata: + name: migrate-service-c +spec: + when: + cron: + schedule: "0 9 12 2 *" # TODO: adjust schedule + taskTemplate: + type: claude-code + workspaceRef: + name: service-c + agentConfigRef: + name: migration-config + credentials: + type: oauth + secretRef: + name: claude-credentials + promptTemplate: | + Migrate this repository from the deprecated `log/v1` package to `log/v2`. + + Steps: + 1. Find all imports of `github.com/your-org/log/v1`. # TODO: replace with actual migration + 2. Replace them with `github.com/your-org/log/v2`. + 3. Update any changed API calls (see migration guide below). + 4. Run tests and fix any compilation errors. + 5. Open a PR with the changes. + + Migration guide: + - `log.Info(msg)` -> `log.Info(msg, nil)` (second arg is now required attrs) + - `log.WithField(k, v)` -> `log.With(k, v)` + - `log.Fatal(msg)` is removed; use `log.Error(msg, nil); os.Exit(1)` + ttlSecondsAfterFinished: 3600 + maxConcurrency: 1 diff --git a/examples/06-multi-repo-migration/workspaces.yaml b/examples/06-multi-repo-migration/workspaces.yaml new file mode 100644 index 00000000..4f2ec9b6 --- /dev/null +++ b/examples/06-multi-repo-migration/workspaces.yaml @@ -0,0 +1,29 @@ +apiVersion: axon.io/v1alpha1 +kind: Workspace +metadata: + name: service-a +spec: + repo: https://github.com/your-org/service-a.git # TODO: replace + ref: main + secretRef: + name: github-token +--- +apiVersion: axon.io/v1alpha1 +kind: Workspace +metadata: + name: service-b +spec: + repo: https://github.com/your-org/service-b.git # TODO: replace + ref: main + secretRef: + name: github-token +--- +apiVersion: axon.io/v1alpha1 +kind: Workspace +metadata: + name: service-c +spec: + repo: https://github.com/your-org/service-c.git # TODO: replace + ref: main + secretRef: + name: github-token diff --git a/examples/07-security-audit-cron/README.md b/examples/07-security-audit-cron/README.md new file mode 100644 index 00000000..682d0c3b --- /dev/null +++ b/examples/07-security-audit-cron/README.md @@ -0,0 +1,47 @@ +# Security Audit Cron + +Run a periodic security audit of your codebase using an AI agent. The agent +checks for common vulnerabilities, outdated dependencies with known CVEs, +hardcoded secrets, and insecure patterns. Results are filed as GitHub issues. + +## How It Works + +1. A cron schedule triggers the audit (default: weekly on Monday mornings). +2. The agent clones the repo, scans for security issues, and checks + dependencies. +3. If issues are found, the agent creates a GitHub issue per finding (or one + summary issue) with remediation guidance. +4. If no issues are found, the agent exits without creating any output. + +## Resources + +| File | Description | +|------|-------------| +| `workspace.yaml` | Git repo to audit | +| `credentials-secret.yaml` | Agent credentials | +| `github-token-secret.yaml` | GitHub token for creating issues | +| `agentconfig.yaml` | Security audit instructions | +| `taskspawner.yaml` | Weekly cron TaskSpawner | + +## Setup + +1. Replace all `# TODO:` placeholders. +2. Apply: + +```bash +kubectl apply -f examples/07-security-audit-cron/ +``` + +3. Check results after the next cron tick: + +```bash +axon get tasks +axon logs +``` + +## Customization + +- Adjust the cron schedule in `taskspawner.yaml` to match your needs. +- Edit the audit checklist in `agentconfig.yaml` to add project-specific + security requirements. +- Set `maxConcurrency: 1` to prevent overlapping audit runs. diff --git a/examples/07-security-audit-cron/agentconfig.yaml b/examples/07-security-audit-cron/agentconfig.yaml new file mode 100644 index 00000000..98fe5f4b --- /dev/null +++ b/examples/07-security-audit-cron/agentconfig.yaml @@ -0,0 +1,24 @@ +apiVersion: axon.io/v1alpha1 +kind: AgentConfig +metadata: + name: security-audit-config +spec: + agentsMD: | + You are a security auditor. Scan the codebase methodically and report + only confirmed or high-confidence findings. Do not report speculative + or low-confidence issues. + + Audit checklist: + 1. Hardcoded secrets: API keys, passwords, tokens in source files. + 2. Dependency vulnerabilities: check for known CVEs in dependencies. + 3. Injection risks: SQL injection, command injection, XSS in web code. + 4. Authentication/authorization: missing auth checks, insecure defaults. + 5. Sensitive data exposure: logging of secrets, unencrypted storage. + 6. Insecure configuration: debug mode in production configs, permissive + CORS, disabled TLS verification. + + When reporting findings: + - Include the file path and line number. + - Explain the risk clearly. + - Provide a concrete remediation suggestion. + - Rate severity as Critical, High, Medium, or Low. diff --git a/examples/07-security-audit-cron/credentials-secret.yaml b/examples/07-security-audit-cron/credentials-secret.yaml new file mode 100644 index 00000000..0c6a74fb --- /dev/null +++ b/examples/07-security-audit-cron/credentials-secret.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: claude-credentials +type: Opaque +stringData: + oauthToken: "" # TODO: replace with your Claude OAuth token diff --git a/examples/07-security-audit-cron/github-token-secret.yaml b/examples/07-security-audit-cron/github-token-secret.yaml new file mode 100644 index 00000000..33cadf72 --- /dev/null +++ b/examples/07-security-audit-cron/github-token-secret.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: github-token +type: Opaque +stringData: + GITHUB_TOKEN: "" # TODO: replace with a GitHub token that has repo scope diff --git a/examples/07-security-audit-cron/taskspawner.yaml b/examples/07-security-audit-cron/taskspawner.yaml new file mode 100644 index 00000000..331d62e5 --- /dev/null +++ b/examples/07-security-audit-cron/taskspawner.yaml @@ -0,0 +1,41 @@ +apiVersion: axon.io/v1alpha1 +kind: TaskSpawner +metadata: + name: security-audit +spec: + when: + cron: + schedule: "0 9 * * 1" # Every Monday at 9:00 AM UTC + maxConcurrency: 1 + taskTemplate: + type: claude-code + workspaceRef: + name: audit-workspace + agentConfigRef: + name: security-audit-config + credentials: + type: oauth + secretRef: + name: claude-credentials + promptTemplate: | + Run a security audit of this repository. + + Steps: + 1. Check for hardcoded secrets (grep for patterns like API keys, tokens, + passwords in source files — not test fixtures or examples). + 2. Review dependency files (go.mod, package.json, requirements.txt, etc.) + for known vulnerabilities. Use available tools if present (e.g., + `go vuln check`, `npm audit`). + 3. Scan for injection vulnerabilities in code that handles user input. + 4. Check configuration files for insecure defaults. + + If you find issues: + - Create ONE summary GitHub issue titled "[Security Audit] Findings - {{.Time}}" + with all findings organized by severity. + - Label it with "security" and "audit". + - Example: gh issue create --title "[Security Audit] Findings - {{.Time}}" --body "" --label security --label audit + + If no issues are found: + - Exit cleanly without creating any issues. + - Do not create "all clear" issues. + ttlSecondsAfterFinished: 3600 diff --git a/examples/07-security-audit-cron/workspace.yaml b/examples/07-security-audit-cron/workspace.yaml new file mode 100644 index 00000000..8952a4f0 --- /dev/null +++ b/examples/07-security-audit-cron/workspace.yaml @@ -0,0 +1,9 @@ +apiVersion: axon.io/v1alpha1 +kind: Workspace +metadata: + name: audit-workspace +spec: + repo: https://github.com/your-org/your-repo.git # TODO: replace with your repo + ref: main + secretRef: + name: github-token diff --git a/examples/README.md b/examples/README.md index 997fa7e0..8e898b95 100644 --- a/examples/README.md +++ b/examples/README.md @@ -15,6 +15,9 @@ Ready-to-use patterns and YAML manifests for orchestrating AI agents with Axon. | [02-task-with-workspace](02-task-with-workspace/) | Run a Task that clones a git repo and can create PRs | | [03-taskspawner-github-issues](03-taskspawner-github-issues/) | Automatically create Tasks from labeled GitHub issues | | [04-taskspawner-cron](04-taskspawner-cron/) | Run agent tasks on a cron schedule | +| [05-pr-review-spawner](05-pr-review-spawner/) | Auto-review PRs with a label-driven TaskSpawner and AgentConfig | +| [06-multi-repo-migration](06-multi-repo-migration/) | Apply the same migration across multiple repos in parallel | +| [07-security-audit-cron](07-security-audit-cron/) | Run periodic security audits with findings filed as issues | ## How to Use