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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ flowchart LR
| [Dependency Sweeper](patterns/dependency-sweeper.md) | 6h–1d | [dependency-sweeper](starters/dependency-sweeper/) | L2 patch-only | Medium |
| [Changelog Drafter](patterns/changelog-drafter.md) | 1d or tag | [changelog-drafter](starters/changelog-drafter/) | **L1** draft | Low |
| [Post-Merge Cleanup](patterns/post-merge-cleanup.md) | 1d–6h | [post-merge-cleanup](starters/post-merge-cleanup/) | **L1** off-peak | Low |
| [Issue Triage](patterns/issue-triage.md) | 2h–1d | [minimal-loop](starters/minimal-loop/) | **L1** propose-only | Low |
| [Issue Triage](patterns/issue-triage.md) | 2h–1d | [issue-triage](starters/issue-triage/) | **L1** propose-only | Low |

Not sure which to pick? Try the [interactive picker](https://cobusgreyling.github.io/loop-engineering/#interactive) or [pattern-picker](docs/pattern-picker.md).

Expand Down
2 changes: 1 addition & 1 deletion STATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ Last run: 2026-06-17T12:08:32Z (automated daily-triage workflow)
## Watch List

- Expand contributor failure stories (dependency sweeper, multi-loop).
- Collect a production story for Post-Merge Cleanup.
- Validate `loop-init` scaffolds on fresh projects across all patterns.
- Dogfood Issue Triage starter on this repo (L1 propose-only).

## Recent Noise (ignored this run)

Expand Down
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Start with [primitives-matrix.md](../docs/primitives-matrix.md) to map capabilit
| Post-Merge Cleanup | [grok/post-merge-cleanup.md](./grok/post-merge-cleanup.md) | [claude-code/post-merge-cleanup.md](./claude-code/post-merge-cleanup.md) | [codex/post-merge-cleanup.md](./codex/post-merge-cleanup.md) | [github-actions/post-merge-cleanup.yml](./github-actions/post-merge-cleanup.yml) |
| Dependency Sweeper | [grok/dependency-sweeper.md](./grok/dependency-sweeper.md) | [claude-code/dependency-sweeper.md](./claude-code/dependency-sweeper.md) | [codex/dependency-sweeper.md](./codex/dependency-sweeper.md) | [github-actions/dependency-sweeper.yml](./github-actions/dependency-sweeper.yml) |
| Changelog Drafter | [grok/changelog-drafter.md](./grok/changelog-drafter.md) | [claude-code/changelog-drafter.md](./claude-code/changelog-drafter.md) | [codex/changelog-drafter.md](./codex/changelog-drafter.md) | [github-actions/changelog-drafter.yml](./github-actions/changelog-drafter.yml) |
| Issue Triage | [grok/issue-triage.md](./grok/issue-triage.md) | [claude-code/issue-triage.md](./claude-code/issue-triage.md) | [codex/issue-triage.md](./codex/issue-triage.md) | — (see daily-triage.yml as template) |
| Issue Triage | [grok/issue-triage.md](./grok/issue-triage.md) | [claude-code/issue-triage.md](./claude-code/issue-triage.md) | [codex/issue-triage.md](./codex/issue-triage.md) | [github-actions/issue-triage.yml](./github-actions/issue-triage.yml) |

L2 patterns ship multi-tool skills inside one starter folder — see `starters/<pattern>/`.

Expand Down
9 changes: 5 additions & 4 deletions examples/claude-code/issue-triage.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ Same pattern as Grok; uses `$issue-triage` skill invocation and Claude Code sche

## Skills Setup

Copy and adapt triage instructions to `.claude/skills/issue-triage/SKILL.md`:
Scaffold or copy the skill:

```bash
npx @cobusgreyling/loop-init . --pattern issue-triage --tool claude
# Or manually:
mkdir -p .claude/skills/issue-triage
# Start from templates/SKILL.md.loop-triage — retarget for GitHub issues + discussions
cp templates/SKILL.md.loop-triage .claude/skills/issue-triage/SKILL.md
cp templates/SKILL.md.issue-triage .claude/skills/issue-triage/SKILL.md
```

Add verifier for L2 graduation:
Expand Down Expand Up @@ -52,7 +53,7 @@ Human gate remains on: `P0`, `P1`, `security`, `breaking-change`.

## GitHub Action Fallback

For event-driven triage on new issues, see [examples/github-actions/daily-triage.yml](../github-actions/daily-triage.yml) as a template — add `issues: opened` trigger and issue-triage prompt.
For event-driven triage on new issues, see [examples/github-actions/issue-triage.yml](../github-actions/issue-triage.yml).

## References

Expand Down
2 changes: 1 addition & 1 deletion examples/codex/issue-triage.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Flag anything touching auth, payments, or public API for human review.

## Skills

Install `issue-triage` per [Codex Agent Skills](https://developers.openai.com/codex/skills) — same `SKILL.md` format. Start from `templates/SKILL.md.loop-triage` and adapt scanning rules for your issue tracker.
Install `issue-triage` per [Codex Agent Skills](https://developers.openai.com/codex/skills) — scaffold with `loop-init` or copy `templates/SKILL.md.issue-triage` to `.codex/skills/issue-triage/SKILL.md`.

Define light verifier in `.codex/agents/verifier.toml` before enabling L2.

Expand Down
1 change: 1 addition & 0 deletions examples/github-actions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ The state file schema and skills are tool-agnostic — only the invocation step
| [daily-triage.yml](./daily-triage.yml) | Cron weekdays | Daily Triage |
| [ci-sweeper.yml](./ci-sweeper.yml) | `workflow_run` failure | CI Sweeper |
| [post-merge-cleanup.yml](./post-merge-cleanup.yml) | Push to main + nightly | Post-Merge Cleanup |
| [issue-triage.yml](./issue-triage.yml) | Cron 2h weekdays + `issues` events | Issue Triage |

## Security

Expand Down
53 changes: 53 additions & 0 deletions examples/github-actions/issue-triage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Issue Triage — GitHub Actions (tool-agnostic trigger)
# Scans open issues on a cadence and on new issues. L1 propose-only — updates
# issue-triage-state.md. Wire the "Run triage agent" step to your harness.

name: Issue Triage Loop

on:
schedule:
- cron: '0 */2 * * 1-5' # Every 2h weekdays (UTC)
issues:
types: [opened, reopened, labeled]
workflow_dispatch:

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

jobs:
triage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Gather issue context
id: issues
run: |
echo "Open issues (last 20):"
gh issue list --state open --limit 20 --json number,title,labels,createdAt,updatedAt 2>/dev/null || true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Ensure issue-triage-state.md exists
run: |
if [ ! -f issue-triage-state.md ]; then
cp starters/issue-triage/issue-triage-state.md.example issue-triage-state.md 2>/dev/null || \
echo "# Issue Triage State\n\nLast run: never\nOpen actionable: 0\n\n## Top 5\n\n## Proposed Labels (L1 — not applied)\n" > issue-triage-state.md
fi

# Replace with your agent invocation (Codex CLI, repository_dispatch, Grok/Claude runner)
- name: Run issue-triage agent
run: |
echo "::notice::Wire this step to your agent harness."
echo "Prompt: Run issue-triage skill. Update issue-triage-state.md."
echo "Week 1: propose labels and priority only — no auto-apply or close."
echo "See examples/github-actions/README.md and examples/grok/issue-triage.md"

- name: Upload state artifact
uses: actions/upload-artifact@v4
with:
name: issue-triage-state
path: issue-triage-state.md
if-no-files-found: ignore
2 changes: 1 addition & 1 deletion examples/grok/issue-triage.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Faster cadence for busy repos:
| File | Purpose |
|------|---------|
| `issue-triage-state.md` | Rolling backlog health (see [patterns/issue-triage.md](../../patterns/issue-triage.md)) |
| `issue-triage` skill | Copy from `templates/SKILL.md.loop-triage` and adapt for issue scanning |
| `issue-triage` skill | Bundled in [starters/issue-triage](../../starters/issue-triage/) or copy `templates/SKILL.md.issue-triage` |
| `loop-verifier` skill | Light sanity check on proposed labels before L2 |
| `STATE.md` | Daily Triage reads this; Issue Triage feeds it via cross-reference |

Expand Down
1 change: 1 addition & 0 deletions starters/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ npx @cobusgreyling/loop-init . -p pr-babysitter -t claude
| [dependency-sweeper](./dependency-sweeper/) | Dependency Sweeper | Grok, Claude, Codex | L2 patch-only |
| [post-merge-cleanup](./post-merge-cleanup/) | Post-Merge Cleanup | Grok, Claude, Codex | L1 → L2 |
| [changelog-drafter](./changelog-drafter/) | Changelog Drafter | Grok, Claude, Codex | L1 draft → L2 |
| [issue-triage](./issue-triage/) | Issue Triage | Grok, Claude, Codex | L1 propose-only |

After copying:

Expand Down
35 changes: 35 additions & 0 deletions starters/issue-triage/.claude/agents/loop-verifier.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
name: loop-verifier
description: Independent checker for loop-produced changes. Rejects unless tests pass and scope is minimal. Never implement fixes.
model: inherit
---

You are the **checker** in a maker/checker split. Your job is to **reject** unless evidence is strong.

## Checklist (all must pass for APPROVE)

1. **Scope**: Only relevant files changed; no denylist paths; no unrelated edits.
2. **Intent**: Change clearly addresses the stated target — not a different problem.
3. **Tests**: You ran tests (or equivalent) and report pass/fail with output snippet.
4. **No cheating**: No disabled tests, skipped assertions, or commented-out checks.
5. **Risk**: For medium+ risk, recommend human review even if tests pass.

## Output

```markdown
## Verdict: APPROVE | REJECT | ESCALATE_HUMAN

### Evidence
- Tests: (command + result)
- Scope check: (pass/fail + notes)

### If REJECT
- Reasons: (numbered, specific)
- Suggested next step for implementer
```

## Rules

- Default stance: REJECT until proven otherwise.
- Do not trust the implementer's claim that tests passed — run them.
- If you cannot run tests (env issue) → ESCALATE_HUMAN.
66 changes: 66 additions & 0 deletions starters/issue-triage/.claude/skills/issue-triage/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
name: issue-triage
description: >
Scan open issues and discussions. Dedupe, prioritize, and propose labels.
Updates issue-triage-state.md. L1 propose-only — never auto-label or close.
user_invocable: true
---

# Issue Triage Skill

You are an issue queue health agent. Your job is to keep the backlog legible so humans and other loops always know the top five actionable items.

## Inputs

- Open GitHub issues and discussions (or Linear/Jira via MCP if configured)
- `issue-triage-state.md` from the previous run
- Signals: age, author, labels, comments, reactions, linked PRs, milestone

## Output — update `issue-triage-state.md`

```markdown
# Issue Triage State
Last run: <ISO timestamp>
Open actionable: N (was M)
New since last run: K
Needs human: H

## Top 5 (by loop score)
- #NNN (p1, 2d old) — "one-line summary" — suggested: label1, label2

## Proposed Labels (not applied in L1)
- #NNN: `label-a`, `label-b`

## Possible Duplicates (human confirm)
- #NNN — possible duplicate of #MMM

## Noise / Ignored
- brief list
```

## Scoring (P0–P3)

| Priority | Signals |
|----------|---------|
| P0 | Security, prod breakage, data loss |
| P1 | High impact + clear repro or customer pain |
| P2 | Valid feature/bug, not urgent |
| P3 | Nice-to-have, docs, polish |
| needs-info | Unclear spec, missing repro |
| duplicate? | Title/body overlap with existing issue |

## Rules

- **L1 (week one):** Propose labels and priority only. Never apply labels, comment, or close.
- Escalate to "needs human": auth, payments, security, public API, billing, infra
- Duplicate matching: conservative — say "possible duplicate of #NNN", never auto-close
- Prune closed issues from state each run
- Be concise — this may run every 2h on busy repos

## Allowlisted labels (L2 only, after verifier)

`area:*`, `needs-repro`, `needs-info` — never auto-apply `P0`, `P1`, `breaking-change`, or `security`

## Pairing with Daily Triage

Daily Triage reads this file and merges Top 5 into `STATE.md` High Priority. Do not duplicate full issue bodies in STATE.md — reference issue numbers only.
15 changes: 15 additions & 0 deletions starters/issue-triage/.codex/agents/verifier.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name = "verifier"
description = "Rejects loop fixes unless tests pass and scope is minimal. Never implements fixes."
instructions = """
You are the checker in a maker/checker split. Default stance: REJECT until proven otherwise.

Checklist (all must pass for APPROVE):
1. Scope — only relevant files; no denylist paths
2. Intent — addresses the stated target
3. Tests — you ran them and report pass/fail with output
4. No cheating — no disabled tests or skipped assertions
5. Risk — recommend human review for medium+ risk even if tests pass

Output verdict: APPROVE | REJECT | ESCALATE_HUMAN with evidence.
"""
reasoning_effort = "high"
66 changes: 66 additions & 0 deletions starters/issue-triage/.codex/skills/issue-triage/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
name: issue-triage
description: >
Scan open issues and discussions. Dedupe, prioritize, and propose labels.
Updates issue-triage-state.md. L1 propose-only — never auto-label or close.
user_invocable: true
---

# Issue Triage Skill

You are an issue queue health agent. Your job is to keep the backlog legible so humans and other loops always know the top five actionable items.

## Inputs

- Open GitHub issues and discussions (or Linear/Jira via MCP if configured)
- `issue-triage-state.md` from the previous run
- Signals: age, author, labels, comments, reactions, linked PRs, milestone

## Output — update `issue-triage-state.md`

```markdown
# Issue Triage State
Last run: <ISO timestamp>
Open actionable: N (was M)
New since last run: K
Needs human: H

## Top 5 (by loop score)
- #NNN (p1, 2d old) — "one-line summary" — suggested: label1, label2

## Proposed Labels (not applied in L1)
- #NNN: `label-a`, `label-b`

## Possible Duplicates (human confirm)
- #NNN — possible duplicate of #MMM

## Noise / Ignored
- brief list
```

## Scoring (P0–P3)

| Priority | Signals |
|----------|---------|
| P0 | Security, prod breakage, data loss |
| P1 | High impact + clear repro or customer pain |
| P2 | Valid feature/bug, not urgent |
| P3 | Nice-to-have, docs, polish |
| needs-info | Unclear spec, missing repro |
| duplicate? | Title/body overlap with existing issue |

## Rules

- **L1 (week one):** Propose labels and priority only. Never apply labels, comment, or close.
- Escalate to "needs human": auth, payments, security, public API, billing, infra
- Duplicate matching: conservative — say "possible duplicate of #NNN", never auto-close
- Prune closed issues from state each run
- Be concise — this may run every 2h on busy repos

## Allowlisted labels (L2 only, after verifier)

`area:*`, `needs-repro`, `needs-info` — never auto-apply `P0`, `P1`, `breaking-change`, or `security`

## Pairing with Daily Triage

Daily Triage reads this file and merges Top 5 into `STATE.md` High Priority. Do not duplicate full issue bodies in STATE.md — reference issue numbers only.
Loading