Skip to content

Credit agent-opened PRs to the person they name as co-author - #9

Merged
dhpwd merged 3 commits into
mainfrom
dhp-41-agent-credit
Oct 19, 2026
Merged

dhpwd merged 3 commits into
mainfrom
dhp-41-agent-credit

Conversation

@dhpwd

@dhpwd dhpwd commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Implements DHP-41

What changed

PRs that a coding agent opens under its own identity now count for the person the agent names as co-author, instead of for the agent.

  • Agent identity. An email, after .mailmap and ignoring case, that matches any GitHub App bot's no-reply address (<id>+<name>[bot]@users.noreply.github.com), or is one of three agent addresses that pattern misses: Copilot's coding agent and Cursor's two agent addresses. The pattern and list sit together at the top of src/scan.js
  • Credit. A PR whose author is an agent counts for the first Co-authored-by: trailer whose identity, after .mailmap, isn't an agent. Squash PRs read the squash commit's message, and merge PRs the branch tip's. Trailers are read from any line, ignoring case, CRLF and surrounding whitespace. They need a name and an email. Only the first person counts, so --all-authors counts each PR once. Crediting runs before the author filter, so the filter, the no-match warning and the JSON all see the credited person
  • Other bots. Dependency and automation bots match the same pattern, so a bot PR that names a person counts for them. That follows the groom decision and is in the spec's design decisions and known limits
  • JSON. PR rows gain agent_email after author_email. It holds the agent's email whenever the git author is an agent, whether or not a person took the credit, and is null otherwise. Nothing in the repo reads it
  • Warning. When the no-match warning lists a coding agent (the three addresses, or the Copilot, Devin, Cursor and Jules no-reply logins), it adds a hint on how to claim its PRs. Dependency bots never get the hint
  • Docs. The spec (design decision, Detecting PRs rule and known limits, JSON, Repo warnings, budget, Verification), README note, .claude/CLAUDE.md (budget line, PR attribution as a design decision) and docs/patterns/git.md describe this as current state

Also on this branch, from review:

  • Both check-mailmap calls now pass contacts on stdin through one helper (mapIdentities). With arguments, a repo with many distinct co-authors could pass the command-line limit, and git() throws on that, which would end the whole scan. That fix has no test, because the fixtures can't make a big enough message
  • tests/fixtures.js gains a verbatim commit option, so a test can keep CRLF line endings

Git process budget

Throwaway GIT_TRACE count: two fixture repos, each with 15 agent squash PRs (with trailers), 15 human squash PRs, 15 agent merge PRs and 15 direct commits. Processes per repo:

Scan log check-mailmap check-attr config for-each-ref
default author 2 2 1 1 1
--all-authors 2 1 1 0 1
--author other@… 2 2 1 0 1

That's the main log plus the branch-tip call, and at most two check-mailmap (the author filter's and the trailers'). Nothing runs per commit or per PR. The counted PRs (25 / 45 / 20) matched the fixture.

Verification

  • npm test (124 pass) and npm run typecheck
  • Each new test was checked by mutating the code it guards and watching it fail: trailer case, CRLF, agent-trailer skipping, the empty-email and no-name rules, .mailmap mapping by name and email, merge PRs reading the tip, the list addresses, and coding-agent-only hints
  • The report code is unchanged, so the browser report check doesn't apply

Held findings

None of these gate release.

  • No warning when agent PRs credit your no-reply address while your other PRs in the repo match. The hint's "pass --author with its email" also drops your own PRs elsewhere, since --author replaces the default filter. Both are decisions on settled warning behaviour – DHP-42
  • An AI tool's own trailer (e.g. Claude <noreply@anthropic.com>) before the person's takes an agent PR's credit. Skipping it would reopen the groom's agent-identity scope, so it's recorded as a known limit – DHP-43
  • Tip-only credit for merge PRs, backport bots counting for the original author, and ID-less bot addresses: these follow the ticket's settled rules. The first two are now in the spec's known limits
  • No version bump: settled at groom (0.x until DHP-34)
  • agent_email set on the failed-tip fallback when the merge commit's author is an agent: this matches the field's definition, so no change
  • No warning when the trailer check-mailmap fails, and the per-entry comments on AGENT_EMAILS: both are as the ticket specifies
  • copilot-swe-agent[bot] in the coding-agent list never matches a known address: the ticket lists it, and it does no harm
  • Direct commits by agents aren't credited to a co-author: direct commits are out of scope
  • A credited PR takes the trailer's name, so one email can show two names and a name-only --author can miss it. This follows the ticket's mapped-name rule, as for squash merges recorded under another name
  • A \x1f inside a tip message cuts it short, the same assumption LOG_FORMAT makes

Review

Cubic didn't review this branch. It isn't installed on this repo: none of PRs #1–#8 has a cubic review or check run, and #9 has none either. The branch had a structural review (spec and conventions) and a local /code-review at xhigh, and their findings were applied or triaged above.

Release readiness

Nothing beyond merging blocks release. The scan JSON gains agent_email, which nothing in the repo reads. No follow-on actions.

🤖 Generated with Claude Code

dhpwd and others added 3 commits October 19, 2026 20:36
- A PR whose git author is an agent (any GitHub App bot no-reply
  address, or Copilot's and Cursor's agent addresses) counts for the
  first Co-authored-by: trailer naming a person, read from the squash
  commit or the merge PR's branch tip, after .mailmap
- Trailer identities go through one batched git check-mailmap per repo,
  and the branch tip call now reads messages too
- PR rows gain agent_email, set whenever the git author is an agent
- The no-match warning adds a hint for coding agents it lists, never
  for dependency bots
- Spec, README, CLAUDE.md and the git pattern doc describe the rule,
  the field, the budget and the limits

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Pass check-mailmap contacts on stdin, so a long list of co-authors
  can't exceed the command-line limit and make git() throw, ending the
  scan. mapEmails now goes through the same mapIdentities call
- Count a Co-authored-by: trailer only with a name, so a nameless one
  can't give a PR an empty author_name
- Keep the hint's coding agents in their own constant, independent of
  the credit list
- Say in the branch-tip warning that those PRs get no co-author credit
- Test CRLF trailers (via a verbatim fixture commit option), a nameless
  trailer and a .mailmap entry keyed on name and email
- README: the warning only appears when none of a repo's PRs match,
  and the no-reply address goes alongside your own --author
- Spec known limits: unlisted agents' trailers, tip-only merge credit
  and backport bots. git.md describes the stdin batching and the
  branch-tip format

The command-line limit fix has no test: reaching the limit needs a
fixture message larger than the fixtures can pass to git commit -m.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- testing.md: a CRLF message test needs the verbatim commit option,
  since git's default cleanup strips trailing CRs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dhpwd
dhpwd marked this pull request as ready for review October 19, 2026 19:51
@dhpwd
dhpwd merged commit 375bae3 into main Oct 19, 2026
@dhpwd
dhpwd deleted the dhp-41-agent-credit branch October 19, 2026 19:59
Repository owner deleted a comment from linear-code Bot Oct 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant