Skip to content

feat: open up external contributions, AI-reviewed (advisory only) - #19

Merged
ctopherwilliams merged 1 commit into
mainfrom
feat/external-contributions
Jul 5, 2026
Merged

feat: open up external contributions, AI-reviewed (advisory only)#19
ctopherwilliams merged 1 commit into
mainfrom
feat/external-contributions

Conversation

@ctopherwilliams

Copy link
Copy Markdown
Owner

Summary

  • Repo was already public with no merge-approval requirement -- external contributors could already fork+branch+PR. Added the missing piece: docs explaining the flow, and a review gate proportional to trusting non-collaborator code.
  • CONTRIBUTING.md: explicit fork β†’ branch β†’ PR walkthrough; fixed a stale checklist (predated tests/smoke.py, referenced a 3-file bandit scope instead of the whole repo).
  • pull_request_template.md: same checklist fix.
  • New external-pr-review.yml: posts one advisory AI review comment on PRs from non-collaborators (never Dependabot, which keeps its own separate auto-merge workflow). Never approves, merges, or modifies anything -- contents: read only.
  • Confirmed (and documented in the workflow's own comments) that only dependabot-auto-merge.yml can ever call gh pr merge, already actor-gated to dependabot[bot] -- external PRs cannot auto-merge through any path.

Security model (the part worth scrutinizing)

pull_request_target is normally dangerous for fork PRs -- secrets are available, and checking out + running the fork's code is the classic "pwn request." This workflow avoids that: no ref: override on checkout (stays on base main), and the PR's diff is fetched as text only via gh pr diff, handed to the model as clearly-labeled untrusted input -- the same treatment issue-autopilot.yml already gives untrusted issue bodies. The model is explicitly instructed never to check out, install, import, or execute anything from the PR.

Stacked on #18 (pellet/anomaly alerts) -- merge in order: #10 β†’ #11 β†’ #12 β†’ #13 β†’ #14 β†’ #15 β†’ #16 β†’ #17 β†’ #18 β†’ this one.

Test plan

  • Full smoke suite green, including a new test that parses every .github/workflows/*.yml file (caught and fixed a real YAML formatting issue in this PR's own new workflow while writing it)
  • bandit + pip-audit clean
  • Manually confirmed via gh api repos/.../branches/main/protection that no approval requirement exists today (matches "ours still auto-merge, not approvals") and that the repo is public

The repo was already public with no merge-approval requirement (branch
protection only requires the `audit` check) -- external contributors
could already fork+branch+PR with zero config changes. What was missing:
docs saying so, and a review gate proportional to trusting code from
people who aren't collaborators.

- CONTRIBUTING.md: explicit fork -> branch -> PR walkthrough, and fixed
  a stale pre-tests/smoke.py checklist (referenced an old one-line import
  check and a 3-file bandit scope; CI actually runs the full smoke suite
  and scans the whole repo).
- pull_request_template.md: same checklist fix.
- New external-pr-review.yml: posts ONE advisory AI review comment on
  PRs from non-collaborators (never dependabot, which has its own
  auto-merge workflow). Never approves, merges, or modifies anything --
  contents:read only, no contents:write.

  Security model: pull_request_target is normally dangerous for fork PRs
  (secrets exposed + if you check out and run the fork's code, that's a
  "pwn request"). This workflow never checks out or executes the fork's
  code -- checkout takes no `ref:` override (stays on base `main`), and
  the PR's diff is fetched as TEXT ONLY via `gh pr diff`, handed to the
  model as clearly-labeled untrusted input, exactly like issue-autopilot.yml
  already treats untrusted issue bodies. Confirmed no other workflow can
  auto-merge a non-dependabot PR (only dependabot-auto-merge.yml calls
  `gh pr merge`, already actor-gated).

- New test: parses every .github/workflows/*.yml file to catch a syntax
  mistake before it silently breaks a CI trigger (caught and fixed a
  YAML block-scalar formatting choice in the new workflow's own `if:`
  while writing this).
@ctopherwilliams
ctopherwilliams force-pushed the feat/external-contributions branch from 41c68c2 to 9272eb6 Compare July 5, 2026 01:57
@ctopherwilliams
ctopherwilliams merged commit 8ce2aec into main Jul 5, 2026
4 checks passed
@ctopherwilliams
ctopherwilliams deleted the feat/external-contributions branch July 5, 2026 01:57
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