Skip to content

fix(agents): document write-path commit attribution and gate on it (BLO-21416) - #1087

Closed
allyblockcast[bot] wants to merge 1 commit into
masterfrom
platformsre/blo-21416-commit-author-attribution
Closed

fix(agents): document write-path commit attribution and gate on it (BLO-21416)#1087
allyblockcast[bot] wants to merge 1 commit into
masterfrom
platformsre/blo-21416-commit-author-attribution

Conversation

@allyblockcast

@allyblockcast allyblockcast Bot commented Aug 6, 2026

Copy link
Copy Markdown

Thinking Path

  • Paperclip is the open source app people use to manage AI agents for work
  • Agents write to GitHub through two paths: git push (per-agent git config identity) and the REST/MCP API (contents API, merge API, create_or_update_file/push_files)
  • Every agent pod shares one credential — the allyblockcast[bot] GitHub App installation (id 290875700) — and REST commit-creation endpoints default commit.author to the authenticated identity when none is supplied
  • So every agent's API-path commit is silently stamped allyblockcast[bot], not the acting agent — authorship becomes unrecoverable from GitHub, which already manufactured one false governance finding (BLO-19528)
  • This pull request documents the rule where agents will actually hit it (AGENTS.md §9), gives the one call site we control (gh api ... -f author[name]= -f author[email]=) an explicit-author workaround, and ships an automated verifying signal: a CI gate on every future paperclip PR plus an on-demand cross-repo audit script
  • The benefit is that non-merge commit authorship becomes recoverable going forward, and the finding is documented once instead of being re-derived or re-filed by a future run

Linked Issues or Issue Description

Fixes: BLO-21416
Refs: BLO-19528 (blocked by BLO-21416; unaffected by this PR's scope)

What Changed

  • AGENTS.md §9: new subsection documenting that commit attribution is write-path dependent, not agent dependent — git push is already correct, the MCP create_or_update_file/push_files tools have no author field and must not be used to land commits, and gh api (the one API call site agents control) must pass an explicit author[name]/author[email] when a raw API write is unavoidable.
  • scripts/check-commit-author-attribution.mjs (+ test): shared assertion findAttributionOffenses (flags a non-merge commit's commit.author.email == "290875700+allyblockcast[bot]@users.noreply.github.com") with two front-ends:
    • local mode: git log --no-merges over a base..head range — no network, no new secret.
    • --audit-merged mode: for the last N merged PRs of one or more repos (default Blockcast/trafficcontrol,Blockcast/paperclip), fetch each PR's own commit list via gh api and apply the same assertion — the AC's "automated verifying signal."
    • Merge/squash-merge commits (2+ parents) are excluded everywhere — they're legitimately App-attributed via the merge API, per BLO-21416's scope boundary.
  • .github/workflows/pr.yml: wires the local mode into the existing policy job as a new required step on every PR, using the branch's already-checked-out history (no new secret needed). Exempts bot/graphify-reindex (that automation is genuinely App-authored end-to-end).

Verification

  • node --test scripts/check-commit-author-attribution.test.mjs — 8/8 passing, including a real local git-range fixture and a merge-commit-exclusion fixture.
  • Ran --audit-merged against real history as evidence:
  • This PR's own commit was pushed via git push with agent git config identity and confirmed via gh api repos/Blockcast/paperclip/commits/{sha}: commit.author.email = platformsreengineer@paperclip.blockcast.net, not the App — i.e., the documented correct path, demonstrated in the PR that documents it.

Risks

  • Low risk: new CI step only reads local git history already fetched by the existing actions/checkout step (fetch-depth: 0); no new secret or external call in the per-PR gate.
  • The --audit-merged mode makes live gh api calls (rate-limit exposure) but is not wired into any scheduled workflow yet — it's a manually-invoked audit tool for now, documented as the AC's verifying signal. Wiring it to a schedule would need a cross-repo-capable token (COMMITPERCLIP_KEY is unprovisioned on Blockcast) — flagged as a follow-up, not done here to avoid unilaterally provisioning new CI credentials.
  • Residual gap (documented, not silently left): the MCP create_or_update_file/push_files tools still have no author field — they're a third-party binary (github/github-mcp-server, pulled from ghcr.io, not vendored/patchable in this repo). The fix here is a hard ban-by-policy (AGENTS.md + PR gate) on using them for commits, not a patch to the tool itself.
  • Trafficcontrol repo does not yet have the equivalent CI gate — this PR only covers paperclip (the repo this session has write access to). Filed as a follow-up; the audit script already covers trafficcontrol read-only today via --audit-merged.

Model Used

Claude Sonnet 5 (claude-sonnet-5[1m]), Anthropic — extended reasoning, tool use (Bash, Read/Write/Edit, GitHub MCP), 1M context window.

Checklist

  • I have included a thinking path that traces from project context to this change
  • I have specified the model used (with version and capability details)
  • I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work
  • I have searched GitHub for duplicate or related PRs and linked them above
  • I have either (a) linked existing issues with Fixes: # / Closes # / Refs # OR (b) described the issue in-PR following the relevant issue template
  • I have run tests locally and they pass
  • I have added or updated tests where applicable
  • If this change affects the UI, I have included before/after screenshots (N/A — no UI change)
  • I have updated relevant documentation to reflect my changes
  • I have considered and documented any risks above
  • All Paperclip CI gates are green (pending this PR's own CI run)
  • Greptile is 5/5 with no open P2s, recommendations, or follow-ups (pending review)
  • I will address all Greptile and reviewer comments before requesting merge

…LO-21416)

allyblockcast[bot] is one shared GitHub App credential every agent pod uses.
REST commit-creation endpoints (contents/merge API, MCP create_or_update_file
/push_files) default commit.author to that authenticated identity, so any
agent writing via the API path gets stamped with the App instead of itself —
git push is unaffected since git already reads per-agent user.name/user.email
from local config. Reproduced via controlled probe and an internal control
(one agent, one PR, three author identities by write path alone); see the
BLO-21416 issue for the full evidence.

- Document the rule and the gh api author[] workaround in AGENTS.md §9, so no
  future agent re-derives this or re-files it as a fresh misattribution
  report (it already was once, as BLO-19528).
- Add scripts/check-commit-author-attribution.mjs: a local git-log mode
  (--no-merges over base..head, wired into pr.yml as a going-forward gate on
  every paperclip PR) and a --audit-merged mode (gh api across the last N
  merged PRs of one or more repos) for the AC's automated verifying signal.
  Verified against the documented Blockcast/trafficcontrol#1326 baseline
  (reproduces its exact 4 violations) and against Blockcast/paperclip's own
  live history (4 violations in the last 10 merged PRs: #1051, #1018).
- Merge/squash-merge commits are excluded everywhere (legitimately
  App-attributed via the merge API) and the graphify-reindex bot branch is
  exempted from the new PR gate (its PRs are genuinely App-authored
  end-to-end, unlike an agent's branch merely opened via the API).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@allyblockcast

allyblockcast Bot commented Aug 6, 2026

Copy link
Copy Markdown
Author

🔗 Paperclip issue: BLO-19528
🔗 Paperclip issue: BLO-21416

@kkroo

kkroo commented Aug 6, 2026

Copy link
Copy Markdown

Superseded by #1097, which carries the exact same head under independent PR author kkroo so Ally can provide the required App approval.

@kkroo kkroo closed this Aug 6, 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