Skip to content

feat(agent-actions): add an account-age throttle for ban-evasion #2561

Description

@JSONbored

Parent: #1936

Problem

The contributor blacklist (src/settings/contributor-blacklist.ts) matches by exact login string; the contributor cap (contributorOpenPrCap/contributorOpenIssueCap) counts open items per repo. Neither has any signal for how OLD a GitHub account is or how fast it's opening PRs/issues. This is the classic ban-evasion gap: a banned login gets a fresh GitHub account created the same day, and because the blacklist matches by exact string and the cap is purely a per-repo open-item count, the new account gets FULL trust until it independently accumulates enough open items in ONE repo to trip the cap on its own. There is currently no cheaper, earlier signal available.

This is deliberately scoped as a much lower-risk first step than behavioral cross-account identity matching (a separate, much harder, higher-false-positive-risk problem not in scope here) — this is a simple, deterministic, GitHub-API-native signal (account creation date), not inference.

Requirements

  • Add an optional accountAgeDays threshold setting: PRs/issues from an account younger than the configured threshold get an advisory new-account label and/or a tighter effective open-item cap (e.g. half the configured contributorOpenPrCap), never an automatic close on account-age alone — this is a friction/visibility signal, not a ban.
  • Fetch account creation date via GitHub's existing users API (one additional, cacheable lookup — GitHub user.created_at on the GET /users/{username} endpoint).
  • Config-driven per repo, off by default.
  • Never fires for the repo owner, admin logins, or automation bots — same standing exemption as every other anti-abuse mechanism.

Deliverables

  • The accountAgeDays setting wired through the full config-as-code chain.
  • A cached account-creation-date lookup (reusing existing GitHub-API caching infra where possible).
  • The label/tighter-cap short-circuit logic in src/settings/agent-actions.ts, following the same zero-hallucination short-circuit shape as blacklistMatch/contributorCapMatch.
  • Tests covering: an account below the age threshold gets labeled/tighter-capped; an account above it is unaffected; the owner/admin/bot exemption holds.

Acceptance criteria

  • A PR/issue from an account younger than the configured accountAgeDays gets the new-account label and/or a tighter cap, per config.
  • Off by default — zero behavior change for repos that haven't opted in.
  • Never auto-closes on account age alone.

Expected outcome

A cheap, deterministic, false-positive-safe first line of defense against the "banned login gets a fresh account" evasion pattern — visibility and friction now, without the risk profile of behavioral cross-account matching.

Metadata

Metadata

Assignees

Labels

maintainer-onlyOwner-only work — yields no Gittensor points.roadmapOn the Wave-2 agent-layer roadmap board (project 9)

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions