name: awesome-triage
description: Triage new issues and PRs on awesome-list repos by applying curation criteria distilled from past decisions.
model: opus
disable-model-invocation: true
allowed-tools: Bash, Read, Grep, Glob, WebFetch, WebSearch
argument-hint:
Context
!gh api repos/{owner}/{repo} --jq '.description' 2>/dev/null
!cat .github/contributing.md 2>/dev/null | head -20
Instructions
You help the maintainer triage incoming issues and PRs on awesome-list repositories (awesome-billing, awesome-iam, awesome-falsehood, awesome-engineering-team-management) by applying curation criteria distilled from historical accept/reject decisions across all four lists.
Prerequisites
Read .github/contributing.md in the current repo before triaging. It is the canonical source of truth for formatting rules, editorial line, section ordering, content candidates, and rejection reasons. This skill does not restate those rules — it adds the analytical layer on top: structured evaluation, signals the guide does not codify, and comment/label recommendations.
Argument handling
$ARGUMENTS should be a GitHub issue or PR URL (e.g., https://github.com/kdeldycke/awesome-billing/issues/42 or #42). If empty, list the 10 most recent open issues and PRs and ask the user which to triage.
Fetch the submission
- Use
gh issue vieworgh pr viewto get the title, body, labels, and author. - For PRs, also fetch the diff with
gh pr diff. - Fetch all comments with
gh issue view --commentsorgh pr view --comments. - If the submission proposes a URL, fetch that URL to inspect the linked resource.
Triage checklist
Evaluate the submission against each criterion below. For each, state PASS, FAIL, or NEEDS REVIEW with a one-line explanation.
1. Template compliance
- Issues: Must use the new-link issue template (URL field filled, motivation provided, affiliation disclosed, self-checks completed).
- PRs: Must fill the PR template (motivation section explaining what the link adds, affiliation checkboxes, self-checks completed).
- PRs that skip the template entirely or leave placeholder text ("This new link is special because...") fail this check.
2. Duplicate detection
- Search existing list entries (
readme.mdand allreadme.*.md) for the proposed URL or domain. - Search closed issues and PRs for the same URL:
gh issue list --state closed --search "<url>"andgh pr list --state closed --search "<url>". - Domain cap: Two links to the same commercial domain is the soft maximum (see
contributing.mdFAQ "Why my link was rejected?"). A second link to the same domain in the same section already looks like content stuffing. - The same URL must not appear in multiple sections (awesome-list guidelines prohibit duplicate links across sections).
3. AI slop detection
This is not covered by contributing.md. Look for these signals (any two together, or combined with §9 provenance signals, warrant the AI slop label):
- The PR body or issue text reads as LLM output (generic phrasing, no specific knowledge of the list's content, template-like structure beyond the actual template).
- The PR explicitly discloses AI generation (e.g., "Generated with Claude Code", "Created by Copilot").
- The linked resource's content appears auto-generated (generic copy, placeholder text, stock descriptions, no voice or editorial specificity).
- The product is not launched (coming soon pages, empty repos, placeholder domains on Vercel/Netlify).
- The proposed description is a rewrite of the resource's meta description or first paragraph without editorial judgment.
See also §9 for contributor and repo provenance signals — these often reinforce the surface-level slop tells above.
4. Competitive context
- Identify the proposed resource's direct competitors or comparable tools (check the resource's own comparison page, "alternatives to" sections, or npm/PyPI "related packages").
- Check whether any of those comparables are already in the list.
- If none of the resource's peer group is featured, the resource likely falls outside the list's scope. This is a strong rejection signal. (Pattern from awesome-billing PRs #175, #176 and awesome-iam PR #158.)
5. Section saturation
- Count the entries in the target section. Is it already well-served?
- The lists are in a curation phase, not an accumulation phase (contributing.md § Status). Overcrowded sections need curation (removing weaker entries), not more links. The maintainer has rejected well-written, relevant content purely because the section was full enough (awesome-iam PRs #131, #158; awesome-iam PR #76).
- If an existing link already "tells the story" of the concept, a second article on the same ground is rejected.
6. Affiliation and commercial signals
- Check which affiliation box the contributor ticked: author, employee, or unaffiliated.
- Cross-reference with the contributor's GitHub profile, the resource's domain, and commit history.
- Self-promotion is allowed but must be disclosed. Undisclosed affiliation is a trust signal.
- Author submissions get more scrutiny on the "marketing vs. genuine content" axis but are not automatically penalized. Many accepted PRs across all four lists are author self-submissions.
- For commercial content, apply
contributing.mdFAQ "Why my commercial project is not in the list?": prefer open-source repository links over commercial landing pages. - When a commercial brand or vendor sits behind the submission (product site, paid SaaS, or a lead-gen funnel pointing at a commercial domain), record the exact brand and domain. A declined commercial submission must close its comment with the sponsorship offer: see § Drafting comments.
7. Formatting and editorial compliance
Check the diff (for PRs) against contributing.md §§ Formatting and Editorial line. Flag deviations but do not restate the rules here: read the guide.
8. Resource quality
- Launched and functional: The product or article must exist and be accessible.
- Maintained: For GitHub repos, check if the project is archived, when the last commit was. Archived or abandoned projects are candidates for removal (contributing.md FAQ "Why removes inactive GitHub projects?"). Check for forks or reboots before recommending deletion.
- Generic, not product-specific: Articles applicable to only one product are not generic enough for inclusion (contributing.md "Why my link was rejected?" + awesome-falsehood PR #31).
9. Contributor and repo provenance
This is not covered by contributing.md. Use to filter vibe-coded throwaway projects that pass surface-level checks but lack real-world traction. Signals here reinforce §3 (AI slop): two from §9, or one from §9 plus one from §3, warrant the AI slop label.
PR/issue author (the GitHub user):
- Account age:
gh api users/<login> --jq '.created_at'. Accounts < 6 months old are suspect for self-promotion of a brand-new project. - Profile completeness: a burst of recent repos with 0 followers, no bio, no company, no blog is the bulk-content-account pattern.
- Co-submission cadence: the same author opening multiple borderline submissions within a short window (hours, same day) is a content-stuffing signal. Cross-check with
gh issue list --author <login>andgh pr list --author <login>.
Proposed resource repo (when the URL is a GitHub project):
- Stars, forks, watchers, contributor count:
gh api repos/<owner>/<name>. A single-author repo with 0 outside contributors is suspect for anything claiming production use. - Created vs. pushed dates: same-day creation and push means no iteration history. Combined with the 50-star baseline failure, this is decisive.
- Repo size and language composition: 100% HTML often means it's a marketing/lead-gen static site, not software. A 22 KB project claiming feature parity with mature tools is a tell.
- License file actually present: do not trust README license claims. Check
gh api repos/<owner>/<name> --jq '.license'and inspect for an actualLICENSEfile. Repos claiming "MIT licensed" in the PR body with no LICENSE file are a trust failure. - Commit cadence and authorship:
gh api repos/<owner>/<name>/commits --jq '[.[] | {sha: .sha[:7], date: .commit.author.date, author: .commit.author.name, message: .commit.message | split("\n")[0]}]'. Real projects show varied commit messages, refactors, fixes, and time spread. AI-generated commits cluster in a short window with uniformfeat:/chore:patterns, all by one author, with no follow-up fixes. - Issues, PRs, and contributors from anyone other than the author: their absence in a project claiming to be useful is a signal.
- Bot-coauthor pattern: AI coding agents in the contributors list (
claude[bot],copilot[bot],devin[bot], etc.) alongside a single human and no other human contributors mean the project is one person plus tooling, not collaborative work. Distinct from human-with-AI-assist development, where the human commits under their own name. Infrastructure bots (dependabot[bot],renovate[bot],github-actions[bot]) don't count: those are normal hygiene. Check viagh api repos/<owner>/<name>/contributors --jq '[.[] | {login, type, contributions}]'. - Solo contributor humanness: when the repo has exactly one human contributor, vet that account against the same PR/issue author checks above (account age, profile completeness, follower/following counts, repo portfolio depth, contribution graph activity). A < 6-month-old account with 0 followers, no bio, a thin or burst-pattern repo portfolio, and a sparse contribution graph signals a throwaway identity. Particularly weighty when the solo contributor is not the PR submitter: PR opened by account B promoting account A's one-person repo is the alt-account self-promotion pattern. Check via
gh api users/<login>for profile fields andgh api users/<login>/repos --jq '[.[] | {name, stars: .stargazers_count, pushed: .pushed_at, fork: .fork}] | sort_by(.pushed) | reverse'for portfolio shape.
Cross-checks:
- Demo URLs on disposable hosts (
*.surge.sh,*.vercel.app,*.netlify.app, GitHub Pages) as the product domain itself, not just a docs deploy. - Future-dated "verified" / "as of" stamps in the resource content that don't match the git history.
- Numerical claims in the PR body (counts of supported items, languages, integrations) that don't match the actual product page — inconsistencies are a generation-time tell, not a copywriting choice.
Strong-rejection patterns (any one is sufficient on its own):
- Resource repo < 30 days old + 0 stars + single-author commit burst on creation day.
- LICENSE file missing despite a license claim in the PR body.
- Author account < 6 months old + ≥ 10 repos + 0 followers + 0 bio/company/blog.
- Author opens multiple submissions across awesome lists for newly-created same-day projects.
- Resource repo contributors are 1 human + AI coding agent bot accounts only (no other human collaborators), and repo is under 6 months old.
Verdict
After running all checks, provide one of:
- ACCEPT: All checks pass. Suggest merging (possibly with minor formatting fixes).
- ACCEPT WITH CHANGES: Value is there but formatting, description, or placement needs work. List the specific changes needed.
- REJECT: Fails one or more hard criteria (duplicate, AI slop, not launched, paywalled, no value-add, section saturation, competitive context mismatch). Draft a rejection comment.
- NEEDS DISCUSSION: Borderline case where maintainer judgment is required. Summarize the arguments for and against.
After the verdict, propose 2-3 short, ready-to-post comments (one line each) that the maintainer can copy-paste to explain the decision to the author. Each comment should reference the specific reason (criterion name, contributing.md section, or precedent PR) so the author understands the rationale without needing to read the full triage analysis.
Drafting comments
When drafting a rejection or request-for-changes comment:
- Be specific about which criteria were not met.
- Reference
contributing.mdsections where applicable. - Stay polite and constructive. Contributors may improve and resubmit (e.g., awesome-iam PR #179 was rejected, contributor revised and PR #182 was merged).
- For AI slop: keep it brief. State the specific tells (e.g., "the site content appears auto-generated", "the product does not appear to be launched yet").
- When a section is saturated, suggest the contributor identify weaker existing entries that could be replaced, turning an addition into a curation improvement.
- For commercially affiliated submissions: always close the comment with a sponsorship offer, whether or not the affiliation was disclosed. Name the specific brand or website in backticks so the call-out is explicit, then point to the sponsorship link as the paid way to get featured: https://github.com/sponsors/kdeldycke. This mirrors
contributing.mdFAQ "How can I force a link into the list?". Example close, for a submission promotingacme-billing.com: "If you want to promoteacme-billing.com, you can purchase a sponsorship to this repository: https://github.com/sponsors/kdeldycke".
Broken link triage
For issues reporting broken links (typically automated by the lychee link checker):
- 403 from Medium/Substack: Bot-blocking responses, not genuine dead links. Ignore unless the content is confirmed gone.
- 404 confirmed dead: Replace with archive.org/archive.ph/sci-hub.st per
contributing.md§ URL. Replacing a broken URL is maintenance; removing the entry is a curation decision. - Archived GitHub repos: Check for forks or reboots. If none exist and the section has other entries covering the same ground, the entry can be removed. Leave the door open for re-inclusion if the project revives.
Label recommendations
Suggest applying these labels based on findings:
| Label | When to apply |
|---|---|
AI slop |
Two or more §3 signals, or one §3 plus one §9 provenance signal. |
curation |
Involves removing, replacing, or reorganizing existing entries. |
new link |
Proposes adding a new resource to the list. |
duplicate |
The resource or a near-equivalent is already in the list. |
fix link |
Reports or fixes a broken URL. |
wont do/fix |
Maintainer decision to not act on the request. |
Next steps
Suggest the user:
- Apply the recommended labels.
- Post the drafted comment if rejecting or requesting changes.
- For accepted PRs, check that translations in
readme.*.mdare updated before merging.