clawsweeper-issue-triage

SkillAI & models

ClawSweeper is a conservative AI-powered GitHub maintainer bot that reviews every open issue and PR in a target repository, writes a regenerated markdown record per item, and closes only when evidence is strong.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the clawsweeper-issue-triage skill

About this capability

Trending Claude Code skills

What this skill tells your AI

The instructions your AI receives, as published by reason-machines/trending-skills in skills/clawsweeper-issue-triage/SKILL.md and read by ahel’s review.

---
name: clawsweeper-issue-triage
description: ClawSweeper is a conservative GitHub maintainer bot that scans all open issues and PRs, writes per-item markdown review records, and closes only when evidence meets strict criteria.
triggers:
  - set up clawsweeper for my repo
  - automate issue triage with clawsweeper
  - how do I run clawsweeper locally
  - configure clawsweeper to close stale issues
  - apply clawsweeper closures to my repository
  - review open PRs with clawsweeper
  - clawsweeper dashboard not updating
  - how does clawsweeper decide what to close
---

# ClawSweeper Issue Triage Bot

> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection.

ClawSweeper is a conservative AI-powered GitHub maintainer bot that reviews every open issue and PR in a target repository, writes a regenerated markdown record per item, and closes only when evidence is strong. It runs on a weekly cadence per item and uses Codex (`gpt-5.5`) to evaluate each item against a strict set of allowed close reasons.

## What ClawSweeper Does

- Scans all open issues and PRs in a target repo (e.g. `openclaw/openclaw`)
- Writes one markdown file per item under `items/<number>.md`
- Proposes closes only for items that match allowed reasons
- Actually closes items only when `apply_closures=true` is explicitly set
- Archives closed item records to `closed/<number>.md`
- Updates a live dashboard in the README after each run
- Never auto-closes items authored by `OWNER`, `MEMBER`, or `COLLABORATOR`

### Allowed Close Reasons

1. Already implemented on `main`
2. Cannot reproduce on current `main`
3. Belongs on a plugin/skill hub, not in core
4. Too incoherent to be actionable
5. Stale issue older than 60 days with insufficient data to verify the bug

## Installation

Requires **Node 24**.

```bash
git clone https://github.com/openclaw/clawsweeper.git
cd clawsweeper
npm install
npm run build

Set required environment variables:

export GITHUB_TOKEN=$GITHUB_TOKEN          # read access to target repo
export OPENAI_API_KEY=$OPENAI_API_KEY      # Codex access
export CLAWSWEEPER_REPO="owner/repo"       # target repo to scan

Key CLI Commands

Plan a sweep

Scans open items and produces shard batches for review jobs.

npm run plan -- \
  --batch-size 5 \
  --shard-count 40 \
  --max-pages 250 \
  --codex-model gpt-5.5 \
  --codex-reasoning-effort medium \
  --codex-service-tier fast

Review items

Runs Codex on each planned item inside a local checkout of the target repo.

npm run review -- \
  --openclaw-dir ../openclaw \
  --batch-size 5 \
  --max-pages 250 \
  --artifact-dir artifacts/reviews \
  --codex-model gpt-5.5 \
  --codex-reasoning-effort medium \
  --codex-service-tier fast \
  --codex-timeout-ms 600000

Apply review artifacts to the repo

Merges shard artifacts and updates dashboard. Does not close anything yet.

npm run apply-artifacts -- --artifact-dir artifacts/reviews

Apply existing proposals (close issues/PRs)

Re-fetches issue context, recomputes snapshot hash, and closes if nothing changed since the proposal.

npm run apply-decisions -- --limit 20

Options:

FlagDefaultDescription
--limitunlimitedMax fresh closes in this run
--apply-kindissueissue, pr, or all
--apply-min-age-days0Minimum age of proposal before applying
--close-delay-ms5000Delay between close API calls

Reconcile items folder

Moves externally closed items from items/ to closed/ and reopened items back to items/ as stale.

npm run reconcile -- --dry-run   # preview only
npm run reconcile               # apply changes

GitHub Actions Workflow

ClawSweeper is designed to run as a scheduled GitHub Actions workflow on the clawsweeper repo itself. Key workflow inputs:

# Trigger a manual run with apply enabled
workflow_dispatch:
  inputs:
    apply_closures:
      description: "Set to true to actually close issues/PRs"
      default: "false"
    apply_existing:
      description: "Apply existing proposals without re-running Codex"
      default: "false"
    apply_kind:
      description: "issue | pr | all"
      default: "issue"
    apply_min_age_days:
      description: "Min age in days for a proposal to be applied"
      default: "0"

The normal scheduled run is proposal-only — it never comments or closes without explicit apply_closures=true.

Item Record Format

Each item is stored as items/<number>.md. Example structure:

# Issue #58150

**Title:** [Bug]: RISC-V64: OpenClaw fails with LLM request failed

**Outcome:** keep_open

**Reason:** Bug is reproducible and not fixed on main. Insufficient evidence
to close as cannot-reproduce.

**Snapshot hash:** abc123def456

**Reviewed:** Apr 25, 2026, 16:55 UTC

**Proposed close comment:** N/A

When outcome is proposed_close, the record includes the exact comment that will be posted before closing.

Review Cadence

Item typeCadence
All PRsDaily
Issues < 30 days oldDaily
Issues ≥ 30 days old with no recent activityWeekly
Items with new activity since last snapshotDaily (promoted)

The planner prioritizes: active items → PRs → new issues → older weekly issues when more items are due than fit in a run.

Configuration Reference

ClawSweeper reads configuration from environment variables and CLI flags. There is no separate config file — all settings are passed at invocation time.

Env VarPurpose
GITHUB_TOKENGitHub API access (read for review, write for apply)
OPENAI_API_KEYCodex API key
CLAWSWEEPER_REPOTarget repo in owner/repo format
CLI FlagCommandDescription
--batch-sizeplan, reviewItems per shard batch
--shard-countplanNumber of parallel review shards
--max-pagesplan, reviewMax GitHub API pages to scan
--codex-modelplan, reviewModel to use (default: gpt-5.5)
--codex-reasoning-effortplan, reviewlow, medium, high
--codex-service-tierplan, reviewdefault, fast
--codex-timeout-msreviewPer-item timeout (default: 600000)
--artifact-dirreview, apply-artifactsDirectory for shard output
--dry-runreconcilePreview without writing
--apply-closuresreviewActually close items (use carefully)

Code Examples

Reading an item record programmatically

import { readFileSync } from 'fs';
import { join } from 'path';

function loadItemRecord(itemNumber) {
  const filePath = join('items', `${itemNumber}.md`);
  const content = readFileSync(filePath, 'utf-8');

  const outcomeMatch = content.match(/\*\*Outcome:\*\*\s+(\S+)/);
  const snapshotMatch = content.match(/\*\*Snapshot hash:\*\*\s+(\S+)/);

  return {
    number: itemNumber,
    outcome: outcomeMatch?.[1] ?? 'unknown',
    snapshotHash: snapshotMatch?.[1] ?? null,
    raw: content,
  };
}

const record = loadItemRecord(58150);
console.log(record.outcome); // "keep_open" or "proposed_close"

Listing all proposed closes

import { readdirSync, readFileSync } from 'fs';
import { join } from 'path';

function getProposedCloses(itemsDir = 'items') {
  const files = readdirSync(itemsDir).filter(f => f.endsWith('.md'));

  return files
    .map(file => {
      const content = readFileSync(join(itemsDir, file), 'utf-8');
      const number = parseInt(file.replace('.md', ''), 10);
      const outcomeMatch = content.match(/\*\*Outcome:\*\*\s+(\S+)/);
      return { number, outcome: outcomeMatch?.[1] };
    })
    .filter(item => item.outcome === 'proposed_close')
    .map(item => item.number);
}

const toClose = getProposedCloses();
console.log(`Proposed closes: ${toClose.length}`);
console.log(toClose);

Checking dashboard metrics from the README

import { readFileSync } from 'fs';

function parseDashboard(readmePath = 'README.md') {
  const content = readFileSync(readmePath, 'utf-8');

  const stateMatch = content.match(/State:\s+(.+)/);
  const checkpointMatch = content.match(/Checkpoint (\d+) finished/);
  const totalClosesMatch = content.match(/Total fresh closes in this run:\s+(\d+)\/(\d+)/);

  return {
    state: stateMatch?.[1]?.trim(),
    checkpoint: checkpointMatch ? parseInt(checkpointMatch[1], 10) : null,
    closesApplied: totalClosesMatch ? parseInt(totalClosesMatch[1], 10) : null,
    closesLimit: totalClosesMatch ? parseInt(totalClosesMatch[2], 10) : null,
  };
}

const dashboard = parseDashboard();
console.log(dashboard);
// { state: 'Apply in progress', checkpoint: 7, closesApplied: 350, closesLimit: 500 }

Triggering a workflow dispatch via GitHub API

import { Octokit } from '@octokit/rest';

const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });

async function triggerApplyRun({ limit = 50, kind = 'issue', minAgeDays = 0 } = {}) {
  await octokit.actions.createWorkflowDispatch({
    owner: 'openclaw',
    repo: 'clawsweeper',
    workflow_id: 'sweep.yml',
    ref: 'main',
    inputs: {
      apply_existing: 'true',
      apply_closures: 'true',
      apply_kind: kind,
      apply_min_age_days: String(minAgeDays),
    },
  });
  console.log(`Apply run triggered: limit=${limit}, kind=${kind}`);
}

await triggerApplyRun({ limit: 100, kind: 'issue' });

Common Patterns

Safe incremental apply

Apply a small batch first to verify the bot is behaving correctly:

# Step 1: review only (default, no closes)
npm run plan -- --batch-size 5 --shard-count 10
npm run review -- --openclaw-dir ../myrepo --artifact-dir artifacts/reviews
npm run apply-artifacts -- --artifact-dir artifacts/reviews

# Step 2: inspect proposals
ls items/ | wc -l
grep -l "proposed_close" items/*.md

# Step 3: apply a small batch
npm run apply-decisions -- --limit 5 --apply-kind issue

Excluding PRs from apply runs

The default apply_kind=issue already excludes PRs. To explicitly target only issues:

npm run apply-decisions -- --limit 50 --apply-kind issue

Reviewing a single item manually

# Run plan with a targeted batch override (if supported by your build)
npm run review -- \
  --openclaw-dir ../myrepo \
  --batch-size 1 \
  --artifact-dir artifacts/manual \
  --codex-timeout-ms 600000

Then check artifacts/manual/ and items/<number>.md for the result.

Troubleshooting

Dashboard not updating

The dashboard is updated by the final publish job in the workflow. If it's stale:

  • Check the workflow run linked in the README status block
  • Look for a timed-out shard (shards time out at 75 minutes)
  • Re-run the publish job manually if shards completed but publish failed

Codex leaves changes in the checkout

ClawSweeper makes the target repo checkout read-only in CI and verifies it before and after each review. If Codex writes anything, the item is marked as failed. Locally, ensure the --openclaw-dir path is not the same repo you are actively editing.

GitHub secondary rate limiting during apply

Apply mode implements long retry backoff automatically. When throttled, it posts a heartbeat to the dashboard:

Throttle heartbeat: checkpoint 3, processed 120, retry in 65s

If you need to stop and resume, re-dispatch with apply_existing=true — already-closed items are skipped automatically.

Items reappearing after close

If an issue is reopened externally, reconcile moves it back from closed/ to items/ as stale so the planner re-reviews it:

npm run reconcile -- --dry-run  # check what would move
npm run reconcile               # apply

Maintainer items being proposed for close

ClawSweeper reads author_association from the GitHub API. Items authored by OWNER, MEMBER, or COLLABORATOR are excluded from automated close actions at both plan and apply time. If a maintainer item appears as proposed_close, verify that the GitHub token has sufficient scope to read association data, and re-run the review for that item.

Signals

GitHub stars
78
Forks
13
Last commit
Jul 2026
Advanced
Catalog kind
skill
Gateway key
clawsweeper-issue-triage-reason-machines
Source
github.com/reason-machines/trending-skills