platform teams
Standards that are checks, not wiki pages
Every engineering organisation has a document nobody reads describing how pull requests are supposed to look. Buddy turns that document into check runs — on your runners, with your keys, in a config you can template across every repository you own.
// shared across every repository
export default {
gates: {
titleFormat: 'error',
description: {
mode: 'error',
requireSections: ['Why', 'Testing', 'Rollback'],
},
dependencyGate: {
mode: 'error',
licenseAllowlist: [
'MIT', 'Apache-2.0', 'ISC', 'BSD-2-Clause', 'BSD-3-Clause',
],
blockVulnerable: true,
blockDeprecated: true,
blockEol: true,
},
linkedIssue: 'error',
custom: [
{
name: 'no-new-runtime-deps',
assertion: 'No new runtime dependency is added to packages/core.',
mode: 'error',
},
{
name: 'migrations-reversible',
assertion: 'Every database migration has a down migration.',
mode: 'error',
},
],
postMerge: {
changelog: { enabled: true },
commentOnIssues: true,
},
},
} satisfies BuddyConfig
buddy/gate — 2 failing
✔ title-format conventional commit
✔ description complete
✘ dependency-gate 1 violation
`[email protected]` → advisory
GHSA-xxxx-xxxx-xxxx
✔ linked-issue addresses #4021
✘ no-new-runtime-deps not satisfied
packages/core/package.json adds
`lodash` to dependencies
✔ migrations-reversible
merge blocked by branch protection.
Your infrastructure, full stop
There is no Buddy server. No OAuth app with read access to your source, no diffs traversing a vendor's infrastructure, no data-processing addendum to negotiate. It is a binary invoked by a workflow your team wrote, in a runner your team already operates.
Policy in English
custom assertions are natural-language rules evaluated per pull request — 'every migration has a down migration', 'no new runtime dependency in core'. Each is checked separately so one unanswerable rule cannot take the others down.
Rollout without a revolt
Every gate is off, warning or error. Ship the whole policy as warnings, watch the failure rate for a fortnight, then promote the ones that were right.
Licence and advisory control
An allowlist blocks anything not on it — an unknown licence is reported, never assumed acceptable. Advisories come from OSV, and base images past end of life are flagged as their own category.
Any git host
GitHub, GitLab and Bitbucket Cloud through one provider interface, self-hosted instances included via repository.apiUrl.
Bring your own model — even a private one
Anthropic, OpenAI, Google, OpenRouter, or any OpenAI-compatible endpoint, which includes a model served inside your own network. For an organisation that cannot send source to a third party, that is the difference between a pilot and a hard no.
Reports on a schedule
buddy report --period 30d --publish computes dependency health and update activity from scan results and PR history — no model required — and publishes it to a tracking issue.
Templating across repositories
Buddy reads buddy.config.ts, .json or .yaml. Most platform teams publish a package that exports the org defaults and let each repository extend it:
// buddy.config.ts in every repository
import { orgDefaults } from '@acme/buddy-config'
export default {
...orgDefaults,
repository: { provider: 'github', owner: 'acme', name: 'payments' },
gates: {
...orgDefaults.gates,
// payments needs a stricter licence policy than the rest
dependencyGate: { ...orgDefaults.gates.dependencyGate, licenseAllowlist: ['MIT', 'Apache-2.0'] },
},
} satisfies BuddyConfig
The workflows themselves are ordinary reusable workflows — nothing Buddy-specific about distributing them.
The security review, pre-answered
| Question | Answer |
|---|---|
| What has access to our source? | Your runner. Buddy is a CLI it invokes. |
| Where does the diff go? | To the model provider you configured, if you configured one. --light sends it nowhere. |
| What token does it use? | The one your workflow provides. Buddy never reads a token from a config file by default. |
| Can the AI change our code? | Only in fix-ci and implement modes, which are opt-in. Review and plan modes have no write tool available to request. |
| Can a command it runs reach our secrets? | No — commands start from an empty environment plus an allowlist, and a second check drops anything whose name looks like a credential. |
| Can it escape the workspace? | Paths are resolved and rejected if they escape, checked twice so a symlink cannot slip past. |
| Is contributor text trusted? | Never. It arrives as tool output inside an escaped <untrusted-content> block. |
| Is there telemetry? | No. |
The long version is in the agent runtime.
Related
Merge gates · Workflow security · Your CI, your keys · Security & compliance · Git providers