typestrict.aidocs

PR Guard

Uma CLI open source que diz quantas pessoas devem revisar um pull request, com um modelo pequeno no runner do seu CI.

O pr-guard lê o diff e a descrição de um pull request, faz ao modelo TS-PRGuard cinco perguntas sobre ele, soma verificações determinísticas (segredos, SQL destrutivo, caminhos sensíveis, tamanho) e deixa uma política em YAML decidir: nenhum revisor, um ou dois, ou bloqueado. Ele comenta no pull request, aplica labels e define um status pr-guard, no GitHub, GitLab ou Bitbucket.

É open source (Apache-2.0): typestrict-lab/pr-guard. O TS-PRGuard é um modelo treinado na typestrict.ai (150M de parâmetros, um arquivo ONNX de 8 bits com 165 MB, também Apache-2.0). Num runner ubuntu-latest padrão, uma verificação levou de 11 a 71 segundos e de 460 MB a 1,9 GB de memória em pull requests de 48 a 1.937 linhas alteradas. A memória para de crescer quando o diff enche o que o modelo lê (5.000 caracteres por pergunta, 14.000 para breaking change).

Zero revisores não é merge: a política não pede aprovação humana extra. O pr-guard comenta, põe labels e define um status, e nunca faz merge; auto_merge: true só adiciona o label pr-guard:auto-merge para a sua própria automação.

Início rápido

# .github/workflows/pr-guard.yml
on: pull_request
permissions:
  contents: read
  pull-requests: write   # o comentário e as labels
  statuses: write        # o status pr-guard
jobs:
  pr-guard:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - uses: typestrict-lab/pr-guard@v1

@v1 é a versão major da action; o binário que ela instala é v0.1.0. A action instala um binário de release, guarda o modelo em cache e roda pr-guard check com o token do workflow. fetch-depth: 0 traz o histórico, para que exista a base comum com a branch de destino.

No notebook:

curl -fsSL https://raw.githubusercontent.com/typestrict-lab/pr-guard/main/install.sh | sh
pr-guard check                     # esta branch contra a base comum
pr-guard check --staged --no-model # as mudanças em stage, só as regras, na hora

Shadow e enforce

Ele começa em modo shadow: comenta em todo pull request, o status sempre passa e diz o que pediria. Quando as respostas parecerem certas no seu código, escreva mode: enforce em .github/pr-guard.yml e torne pr-guard um status obrigatório. No modo enforce o status falha quando a política bloqueia, e espera até o pull request ter as aprovações que o veredito pede.

As perguntas e a política padrão

O modelo responde cada pergunta com a probabilidade de cada resposta, numa passada só na CPU. Macro-F1 em exemplos separados do treino, do card do modelo:

O modelo respondeTS-PRGuardJevPadrão na política
Faz o que a descrição diz?0,9280,807avisa acima de 40% de que não faz, bloqueia acima de 70%
Qual o tamanho para revisar?0,6600,383avisa quando é muito grande
Quebra quem já usa?0,8700,910avisa acima de 50%
Os testes cobrem a mudança?0,9210,879avisa acima de 50% de que não cobrem
Introduz uma vulnerabilidade?0,9040,755avisa acima de 70%

Ele supera o Jev em 4 de 5 perguntas pelo Cálculo de reembolso; em compatibilidade o Jev fica à frente.

As respostas entram numa nota: 85% ou mais não precisa de revisor, 60% ou mais precisa de um, abaixo disso de dois. Um aviso pede pelo menos um revisor, um bloqueio pede dois. O comentário mostra a conta de cada pull request. Toda chave é opcional; pr-guard init imprime o padrão inteiro, comentado:

mode: shadow            # ou enforce
model: pr-guard:1

reviewers: { none: 85%, one: 60% }

questions:
  vulnerability: { weight: 3, warn: 70%, block: 90% }

rules:
  secrets: block
  sensitive_paths: { level: warn, paths: [infra/**, "**/auth/**"] }

Cada chave está explicada em docs/policy.md (em inglês).

Escolher o modelo

--model, senão $PR_GUARD_MODEL, senão model na política:

ValorO que é
pr-guard:1 (padrão)O TS-PRGuard v1 fixado: os arquivos exatos com que esta release do pr-guard foi testada, conferidos por SHA-256.
pr-guard:latestO TS-PRGuard mais novo publicado no Hugging Face, antes de uma release do pr-guard fixá-lo.
hf:<owner>/<repo>[@<revision>]Qualquer repositório do Hugging Face com os mesmos arquivos, como o seu próprio modelo. $HF_TOKEN para um privado.
https://…Uma URL base que serve decision_ai.json, tokenizer.json e onnx/model_8bit.onnx (uma CDN ou um espelho interno).
um diretórioUsado como está.

O modelo é baixado uma vez, conferido arquivo por arquivo contra o SHA-256 e guardado em ~/.cache/pr-guard.

O seu próprio modelo

O TS-PRGuard aprendeu com pull requests públicos. Para ter um que aprendeu com os seus, treine um modelo na typestrict.ai com os seus pull requests como dados (veja Treinos) e aponte a política para ele:

model: hf:sua-org/seu-modelo-de-pr

Publicar um modelo coloca o pacote num repositório do Hugging Face com exatamente os arquivos que o pr-guard lê. Para mantê-lo privado, baixe o pacote (typestrict pull <model>) e sirva de uma URL sua, ou use o diretório direto.

Outros CIs e hosts

A configuração completa de cada um está em docs/ci.md e docs/hosts.md (em inglês):

  • GitLab CI: um componente de CI/CD nos pipelines de merge request; os achados vão para o Code Quality e o relatório de testes.
  • Bitbucket Pipelines: um pipe sobre a imagem Docker; o relatório JUnit aparece no pull request.
  • CircleCI: um orb com install e check; passe a branch de destino como base.
  • Bitrise: um step que grava o relatório JUnit na aba Tests.
  • Jenkins: um exemplo de Jenkinsfile que roda a imagem Docker nos builds de pull request.
  • pre-commit: um hook que roda as regras nas mudanças em stage, sem o modelo.
  • Qualquer outro: o script de instalação, Homebrew, Docker (ghcr.io/typestrict-lab/pr-guard:0.1.0) ou Cargo, e depois pr-guard check.

No GitLab ele precisa de um GITLAB_TOKEN com o escopo api, no Bitbucket de um BITBUCKET_TOKEN; o Bitbucket não tem labels.

Privacidade

Sem API, sem chave, sem telemetria. O modelo roda no runner do CI, o código nunca sai dele, e as únicas chamadas que o pr-guard faz são o download do modelo e o comentário, as labels e o status no seu próprio host. A action nunca executa código do pull request: ela só lê o diff que o checkout trouxe.

Nesta página