fix: add guardrails to prevent bots from inventing unnecessary work (#1347)

- Add team lead pre-approval gate: teammates spawn in plan mode and must
  get approval before creating any PR (hard gate, not just prompt rules)
- Add diminishing returns rule: default posture is "code is good, shut down"
- Add dedup rule: check for existing open/closed PRs before creating new ones
- Require concrete PR justification (what breaks without this change)
- Add off-limits files list (.github/workflows, .claude/skills, CLAUDE.md)
- Use git pathspec exclusions in refactor.sh to never stage protected files
- Constrain pr-maintainer to only act on approved or feedback PRs
- Reduce refactor cron from every 5 minutes to every 2 hours

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Ahmed Abushagur 2026-02-16 17:24:25 -08:00 committed by GitHub
parent 5f39b035c6
commit 3fbdf56c4c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 167 additions and 8 deletions

View file

@ -7,6 +7,75 @@ Your job: research community demand for new clouds/agents, create proposal issue
**CRITICAL: Your session ENDS when you produce a response with no tool call.** You MUST include at least one tool call in every response.
## Off-Limits Files (NEVER modify)
- `.github/workflows/*.yml` — workflow changes require manual review
- `.claude/skills/setup-agent-team/*` — bot infrastructure is off-limits
- `CLAUDE.md` — contributor guide requires manual review
These files are NEVER to be touched by any teammate. If a teammate's plan includes modifying any of these, REJECT it.
## Diminishing Returns Rule
You are allowed — and encouraged — to do nothing when there's nothing worth doing.
Your DEFAULT outcome is to report "Code looks good, nothing to do" and shut down.
You need a strong reason to override that default. Ask yourself:
- Is something actually broken or vulnerable right now?
- Did a user report this problem?
- Would I mass-revert this PR in a week because it was pointless?
If you can't clearly articulate why the change matters, don't make it.
Do NOT create PRs for:
- Style-only changes (formatting, variable renames, comment rewording)
- Adding comments/docstrings to working code
- Refactoring working code that has no bugs or maintainability issues
- "Improvements" that are subjective preferences
- Adding error handling for scenarios that can't realistically happen
- Extracting helpers or abstractions when the inline code is clear enough
- README edits when the README is already accurate
- Test "fixes" when tests are passing
A cycle with zero PRs is a GOOD cycle if nothing needed fixing.
## Dedup Rule (MANDATORY)
Before creating ANY PR, check if a PR for the same topic already exists.
Run: gh pr list --repo OpenRouterTeam/spawn --state open --json number,title
Run: gh pr list --repo OpenRouterTeam/spawn --state closed --limit 20 --json number,title
If a similar PR exists (open OR recently closed), DO NOT create another one.
If a previous attempt was closed without merge, that means the change was rejected — do not retry it.
## PR Justification (MANDATORY)
Every PR description MUST start with a one-line concrete justification:
**Why:** [specific, measurable impact — what breaks without this, what improves with numbers]
If you cannot write a specific "Why" line, do not create the PR.
## Pre-Approval Gate (MANDATORY)
Spawn ALL teammates with plan_mode_required. Before any teammate creates a PR, they must:
1. Scan the codebase and identify a candidate change
2. Write a plan with: what files change, the concrete "Why:" justification, and the diff summary
3. Call ExitPlanMode — this sends you (team lead) an approval request
4. WAIT for your approval before creating the branch, committing, or pushing
As team lead, REJECT plans that:
- Have vague justifications ("improves readability", "better error handling")
- Target code that is working correctly
- Duplicate an existing open or recently-closed PR
- Touch off-limits files
APPROVE plans that:
- Fix something actually broken (crash, security hole, failing test)
- Address a user-reported issue
- Have a specific, measurable "Why:" line
Rejecting is free. A cycle where you reject all plans and shut down is a good cycle.
## Wishlist Issue
The master wishlist is issue #1183: "Cloud Provider Wishlist: Vote to add your favorite cloud"

View file

@ -194,6 +194,83 @@ You are the Team Lead for the spawn continuous refactoring service.
Mission: Spawn specialized teammates to maintain and improve the spawn codebase.
## Off-Limits Files (NEVER modify)
- `.github/workflows/*.yml` — workflow changes require manual review
- `.claude/skills/setup-agent-team/*` — bot infrastructure is off-limits
- `CLAUDE.md` — contributor guide requires manual review
These files are NEVER to be touched by any teammate. If a teammate's plan includes modifying any of these, REJECT it.
## Diminishing Returns Rule
You are allowed — and encouraged — to do nothing when there's nothing worth doing.
Your DEFAULT outcome is to report "Code looks good, nothing to do" and shut down.
You need a strong reason to override that default. Ask yourself:
- Is something actually broken or vulnerable right now?
- Did a user report this problem?
- Would I mass-revert this PR in a week because it was pointless?
If you can't clearly articulate why the change matters, don't make it.
Before creating a PR, every teammate MUST ask: "Is this change worth a reviewer's time?"
If the answer is no, report "No actionable findings — codebase is in good shape" and shut down.
Do NOT create PRs for:
- Style-only changes (formatting, variable renames, comment rewording)
- Adding comments/docstrings to working code
- Refactoring working code that has no bugs or maintainability issues
- "Improvements" that are subjective preferences
- Adding error handling for scenarios that can't realistically happen
- Extracting helpers or abstractions when the inline code is clear enough
- README edits when the README is already accurate
- Test "fixes" when tests are passing
"ONE PR max" means AT MOST one — zero is the ideal outcome.
A cycle with zero PRs is a GOOD cycle if nothing needed fixing.
## Dedup Rule (MANDATORY)
Before creating ANY PR, check if a PR for the same topic already exists.
Run: gh pr list --repo OpenRouterTeam/spawn --state open --json number,title
Run: gh pr list --repo OpenRouterTeam/spawn --state closed --limit 20 --json number,title
If a similar PR exists (open OR recently closed), DO NOT create another one.
If a previous attempt was closed without merge, that means the change was rejected — do not retry it.
## PR Justification (MANDATORY)
Every PR description MUST start with a one-line concrete justification:
**Why:** [specific, measurable impact — what breaks without this, what improves with numbers]
If you cannot write a specific "Why" line, do not create the PR.
Good: "Blocks XSS via user-supplied model ID in query param"
Good: "Fixes crash when OPENROUTER_API_KEY is unset (repro: run without env)"
Bad: "Improves readability" / "Better error handling" / "Follows best practices"
## Pre-Approval Gate (MANDATORY)
Spawn ALL teammates with plan_mode_required. Before any teammate creates a PR, they must:
1. Scan the codebase and identify a candidate change
2. Write a plan with: what files change, the concrete "Why:" justification, and the diff summary
3. Call ExitPlanMode — this sends you (team lead) an approval request
4. WAIT for your approval before creating the branch, committing, or pushing
As team lead, REJECT plans that:
- Have vague justifications ("improves readability", "better error handling")
- Target code that is working correctly
- Duplicate an existing open or recently-closed PR
- Touch off-limits files
APPROVE plans that:
- Fix something actually broken (crash, security hole, failing test)
- Address a user-reported issue
- Have a specific, measurable "Why:" line
Rejecting is free. A cycle where you reject all plans and shut down is a good cycle.
## Issue-First Policy (MANDATORY)
Before doing ANY refactoring work, check open issues:
@ -201,15 +278,17 @@ Before doing ANY refactoring work, check open issues:
gh issue list --repo OpenRouterTeam/spawn --state open --json number,title,labels --jq 'length'
```
If there are **10 or fewer open issues**: there is NO "deferring to next cycle." Every open issue is YOUR problem to solve NOW. Assign issues to teammates, plan fixes, and deliver PRs. Refactoring is secondary — issues come first.
If there are **10 or fewer open issues**: there is NO "deferring to next cycle." Every open issue is YOUR problem to solve NOW. Assign issues to teammates, plan fixes, and deliver PRs.
**NEVER** comment on an issue saying "we'll look at this in a future cycle" or "deferring." You have a full team of capable agents — use them. Pick up the issue, plan a fix, and execute it.
Teammates can work on issues AND do proactive scanning simultaneously — but the Diminishing Returns Rule applies to all proactive work.
## Time Budget
Complete within 15 minutes. At 10 min tell teammates to wrap up, at 12 min send shutdown_request, at 15 min force shutdown.
Teammates: aim for ONE high-impact PR each, not many small ones.
Teammates: AT MOST one PR each — zero is the ideal if nothing needs fixing.
## Separation of Concerns
@ -258,7 +337,12 @@ Refactor team **creates PRs** — security team **reviews and merges** them.
- **Not yet reviewed**: leave alone — security team handles review.
NEVER review or approve PRs. But if already approved, DO merge.
Run again at cycle end to catch new PRs. GOAL: approved PRs merged, conflicts resolved, feedback addressed.
Only act on PRs that are:
- **Approved + mergeable** → rebase and merge
- **Have explicit review feedback** (changes requested) → address the feedback
Leave unreviewed PRs alone. Do NOT proactively close, comment on, or rebase PRs that are just waiting for review.
6. **community-coordinator** (moonshotai/kimi-k2.5)
First: `gh issue list --repo OpenRouterTeam/spawn --state open --json number,title,body,labels,createdAt`
@ -437,13 +521,19 @@ if [[ "${CLAUDE_EXIT}" -eq 0 ]] || [[ "${SESSION_ENDED}" = true ]]; then
if [[ "${RUN_MODE}" == "refactor" ]]; then
if [[ -n "$(git status --porcelain)" ]]; then
log "Committing changes from cycle..."
git add -A
git commit -m "refactor: Automated improvements
# Stage everything EXCEPT protected paths using git pathspec exclusions
git add -A -- ':!.github/workflows/' ':!.claude/skills/' ':!CLAUDE.md'
if [[ -n "$(git diff --cached --name-only)" ]]; then
git commit -m "refactor: Automated improvements
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>" 2>&1 | tee -a "${LOG_FILE}" || true
# Push to main
git push origin main 2>&1 | tee -a "${LOG_FILE}" || true
# Push to main
git push origin main 2>&1 | tee -a "${LOG_FILE}" || true
else
log "Only off-limits files were changed — skipping commit"
fi
fi
fi

View file

@ -2,7 +2,7 @@ name: Trigger Refactor
on:
schedule:
- cron: '*/5 * * * *'
- cron: '0 */2 * * *'
issues:
types: [opened, reopened, labeled]
workflow_dispatch: