gatefile
Por Rene Turcios. Extrai os portões de contribuição ocultos de um repositório (atribuição primeiro, reivindicação primeiro, DCO, aval) de sua documentação para um contribution-gates.json legível por máquina. CLI e servidor MCP com ferramentas extract_gates, validate_gates, gates_badge.
Documentação
gatefile
Portões de contribuição ocultos, extraídos para um arquivo que máquinas podem ler.
Todo repositório esconde suas regras reais para contribuidores externos: comente antes de começar, aguarde ser designado, assine seus commits, seja referendado, assine um CLA. Hoje você descobre essas regras ao ter seu PR fechado automaticamente. O gatefile as extrai da documentação do próprio repositório para contribution-gates.json, um formato legível por máquinas que ferramentas (como Greenlight) e CI podem consumir.
O problema
Um contribuidor escolhe uma issue, escreve o código, abre o PR, e um bot o fecha: "você não foi designado", "autores sem referendo são fechados automaticamente", "Signed-off-by ausente". As regras sempre estiveram no CONTRIBUTING.md, enterradas em prosa, diferentes em cada repositório. Mantenedores repetem as mesmas correções; contribuidores desperdiçam as mesmas noites.
O que o gatefile faz
- extrair: lê CONTRIBUTING.md, templates de PR e issue, arquivos de fluxo DCO/CLA, hooks do lefthook e arquivos de CLA (da API do GitHub ou de um diretório local) e emite os portões encontrados, cada um com uma linha real citada como evidência.
- validar: compara um
contribution-gates.jsoncommitado contra uma extração nova e relata divergências (STALE, MISSING, SEVERITY_CHANGED). Código de saída 1 em caso de divergência, para que o CI possa aplicá-lo. - badge: renderiza um trecho de README que informa aos humanos os portões em linguagem simples.
O formato contribution-gates.json
{
"version": 1,
"repo": "shadcn-labs/pdfcn",
"generatedFrom": ["CONTRIBUTING.md"],
"gates": [
{
"id": "claim_first",
"kind": "claim_first",
"severity": "blocker",
"evidence": "Comment before starting work, and check the thread first in case someone else is already working on it.",
"source": "CONTRIBUTING.md"
}
],
"conventions": {
"branchNaming": "Name your branch feat/block-name",
"prTitleFormat": "PR titles should follow Conventional Commits",
"requiredChecks": []
}
}
Tipos de portão
| tipo | severidade | significado |
|---|---|---|
claim_first | bloqueador | Comente na issue antes de começar o trabalho |
assignment_required | bloqueador | Aguarde ser designado antes de abrir um PR |
discuss_first | bloqueador | Abra uma discussão ou issue antes de codificar |
issue_first | bloqueador | Todo PR deve estar vinculado a uma issue |
vouch_required | bloqueador | Um membro existente deve referendar você |
collaborators_only | bloqueador | Somente colaboradores do repositório podem abrir PRs |
no_direct_prs | bloqueador | PRs diretos não são aceitos |
dco_required | aviso | Commits precisam de um trailer Signed-off-by (DCO) |
cla_required | aviso | Um Contrato de Licença de Contribuidor deve ser assinado |
Severidade: portões blocker podem fazer um PR ser fechado ou rejeitado antes da revisão. Portões warn podem ser corrigidos após a abertura do PR. A evidência é sempre uma citação real do arquivo de origem, reduzida a cerca de 140 caracteres, nunca inventada.
Uso
CLI
# Extract gates from a repo (GitHub API, GITHUB_TOKEN optional)
gatefile extract shadcn-labs/pdfcn
# Extract from a local clone instead (fully offline)
gatefile extract local --local ./pdfcn --out contribution-gates.json
# Validate the committed file against fresh docs, exit 1 on drift
gatefile validate shadcn-labs/pdfcn --file contribution-gates.json
# Print a README snippet for humans
gatefile badge shadcn-labs/pdfcn
Servidor MCP
Adicione à configuração do seu cliente MCP:
{
"mcpServers": {
"gatefile": {
"command": "node",
"args": ["/path/to/gatefile/dist/mcp.js"]
}
}
}
Ferramentas:
| ferramenta | entradas | o que retorna |
|---|---|---|
extract_gates | repo ou localPath | o objeto contribution-gates.json completo |
validate_gates | recorded, repo ou localPath | { ok, drift[] } |
gates_badge | repo ou localPath | trecho de markdown para README |
Exemplo de CI
Mantenha o arquivo de portões íntegro em um fluxo de trabalho do GitHub Actions:
name: gates
on:
pull_request:
paths: ["CONTRIBUTING.md", ".github/**", "contribution-gates.json"]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npx -y gatefile extract ${{ github.repository }} --out /tmp/fresh.json
- run: npx -y gatefile validate ${{ github.repository }} --file contribution-gates.json
Desenvolvimento
npm install
npm test # tsx --test, offline, 23 tests
npm run build # tsc to dist/
npm run dev -- extract owner/repo --json
TypeScript ESM, Node 20+, zod para esquemas, fetch nativo para a API do GitHub. Os testes usam fixtures do mundo real em test/fixtures/ modelados em casos documentados (comentar antes de começar mais DCO mais issue-primeiro; designação-primeiro; somente referendo; permissivo).
Licença
MIT, Rene Turcios 2026.