Padrões de Design
Fluxo de TrabalhoIntermediário

Governança Baseada em Gates

Como implementar gates de qualidade automatizados e human-in-the-loop para código gerado por agentes.

Visão Geral

A Governança Baseada em Gates é um padrão de controle de qualidade que direciona o código gerado por agentes através de um sistema em camadas de verificações automatizadas e pontos de revisão humana antes que ele chegue à base de código principal. Em vez de revisar toda a saída do agente com o mesmo escrutínio, este padrão separa as validações rotineiras (que as máquinas lidam bem) das decisões que exigem julgamento (que requerem atenção humana), direcionando cada uma ao gate apropriado.

O padrão implementa o pilar de Governança Baseada em Gates do Agentic Development Handbook. Gates automatizados — alimentados por um Eval Harness — capturam violações de formatação, falhas de teste, erros de tipo e problemas de conformidade arquitetônica. Gates Human In The Loop capturam compensações de design, implicações de segurança e decisões que exigem contexto de negócio. Juntos, eles garantem qualidade consistente sem criar gargalos.

Problema

Equipes que introduzem agentes de IA em seu fluxo de trabalho de desenvolvimento enfrentam um dilema de governança:

  • Sem gates de forma alguma. O código do agente vai diretamente para pull requests. Os revisores ficam sobrecarregados pelo volume e pela qualidade inconsistente. Violações arquitetônicas, problemas de segurança e erros de lógica sutis passam despercebidos porque os revisores humanos não conseguem escalar para acompanhar a velocidade de saída do agente.
  • Revisão padronizada para tudo. Cada alteração gerada por um agente passa pelo mesmo processo de revisão manual. Correções de formatação triviais consomem a mesma atenção do revisor que alterações de autenticação críticas para a segurança. Os revisores sofrem burnout e começam a aprovar sem critério.
  • Apenas revisão após o fato. As verificações de qualidade ocorrem depois que o agente terminou. Nesse ponto, uma violação arquitetônica pode estar profundamente enraizada na implementação. O retrabalho é caro. O agente pode ter construído cinco componentes sobre uma base falha.
  • Sem caminho de escalonamento. Quando uma verificação automatizada falha, não há um processo definido para o que acontece em seguida. O agente tenta novamente? Um humano intervém? A tarefa é reatribuída? Sem uma escada de escalonamento clara, as falhas paralisam o fluxo de trabalho.

Solução

Implemente um sistema de gates em camadas com quatro componentes:

  1. Gates automatizados — Verificações rápidas e determinísticas executadas em cada saída do agente. Elas incluem linting, verificação de tipos, execução de testes, varredura de segurança e validação de conformidade arquitetônica. Configure-os como parte do Eval Harness com critérios de aprovação/reprovação extraídos dos critérios de aceitação do Live Spec.

  2. Loop de tentativa do agente — Quando um gate automatizado falha, o agente recebe o diagnóstico da falha e tenta corrigir o problema. Defina um limite de tentativas (geralmente 2 a 3) para evitar loops infinitos.

  3. Gates Human In The Loop — Alterações que passam pelos gates automatizados, mas atendem a certos critérios (caminhos críticos de segurança, decisões arquitetônicas, alto raio de impacto), são sinalizadas para revisão humana antes do merge. Esses gates focam a atenção humana onde ela tem mais impacto.

  4. Escada de escalonamento — Um processo definido de quatro fases para lidar com falhas que as tentativas automatizadas não conseguem resolver. Isso segue a Escada de Escalonamento de Quatro Fases do manual: tentativa automatizada, ajuste de parâmetros, Blocker Flag e pausa, Rescue Mission com intervenção humana.

O Eval Harness é o motor por trás dos gates automatizados. Ele lê os critérios de aceitação do Live Spec, executa as verificações configuradas e produz um relatório de aprovação/reprovação. O Context Architect e o Engenheiro de Avaliação colaboram para definir quais verificações são executadas em cada gate.

Implementação

1

2

3

4

5

Exemplos de Código

CI/CD Gate Configuration (GitHub Actions)
# .github/workflows/agent-gates.yml
name: Agent Output Gates

on:
  pull_request:
    branches: [main]
    # Only run on PRs labeled as agent-generated
    types: [labeled]

jobs:
  automated-gates:
    if: contains(github.event.pull_request.labels.*.name, 'agent-generated')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Gate 1 — Lint and Format
        run: |
          npm run lint
          npm run format:check

      - name: Gate 2 — Type Check
        run: npm run typecheck

      - name: Gate 3 — Unit Tests
        run: npm run test:unit -- --coverage

      - name: Gate 4 — Security Scan
        run: |
          npm audit --audit-level=high
          npx semgrep --config p/typescript src/

      - name: Gate 5 — Architecture Conformance
        run: node scripts/check-architecture.js

  hitl-gate-triage:
    needs: automated-gates
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Check HITL triggers
        id: hitl
        run: |
          node scripts/check-hitl-triggers.js \
            --pr=${{ github.event.pull_request.number }}

      - name: Request human review
        if: steps.hitl.outputs.required == 'true'
        uses: actions/github-script@v7
        with:
          script: |
            await github.rest.pulls.requestReviewers({
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: ${{ github.event.pull_request.number }},
              reviewers: ${{ steps.hitl.outputs.reviewers }}
            });
Architectural Conformance Check
// scripts/check-architecture.ts
import { readFileSync, readdirSync } from "fs";
import { join } from "path";

interface ConformanceRule {
  name: string;
  check: (filePath: string, content: string) => string | null;
}

const rules: ConformanceRule[] = [
  {
    name: "no-direct-db-access-in-components",
    check: (filePath, content) => {
      if (filePath.includes("/components/") && content.includes("prisma")) {
        return `Components must not access the database directly. Use a service layer. Found in ${filePath}`;
      }
      return null;
    },
  },
  {
    name: "no-circular-imports",
    check: (filePath, content) => {
      if (
        filePath.includes("/services/") &&
        content.includes("from '../components/")
      ) {
        return `Services must not import from components. Found in ${filePath}`;
      }
      return null;
    },
  },
  {
    name: "test-co-location",
    check: (filePath, content) => {
      if (
        filePath.endsWith(".tsx") &&
        !filePath.endsWith(".test.tsx") &&
        filePath.includes("/components/")
      ) {
        const testPath = filePath.replace(".tsx", ".test.tsx");
        try {
          readFileSync(testPath);
        } catch {
          return `Missing co-located test file for ${filePath}`;
        }
      }
      return null;
    },
  },
];

function checkConformance(directory: string): string[] {
  const violations: string[] = [];

  function walk(dir: string) {
    for (const entry of readdirSync(dir, { withFileTypes: true })) {
      const fullPath = join(dir, entry.name);
      if (entry.isDirectory() && entry.name !== "node_modules") {
        walk(fullPath);
      } else if (entry.name.endsWith(".ts") || entry.name.endsWith(".tsx")) {
        const content = readFileSync(fullPath, "utf-8");
        for (const rule of rules) {
          const violation = rule.check(fullPath, content);
          if (violation) violations.push(`[${rule.name}] ${violation}`);
        }
      }
    }
  }

  walk(directory);
  return violations;
}

const violations = checkConformance("src/");
if (violations.length > 0) {
  console.error("Architectural conformance violations found:");
  violations.forEach((v) => console.error(`  - ${v}`));
  process.exit(1);
} else {
  console.log("All architectural conformance checks passed.");
}
HITL Gate Trigger Detection
// scripts/check-hitl-triggers.ts
interface HITLTrigger {
  condition: string;
  reason: string;
  reviewer: string;
}

const triggers: HITLTrigger[] = [
  {
    condition: "auth",
    reason: "Security-critical path modified",
    reviewer: "security-lead",
  },
  {
    condition: "migration",
    reason: "Database migration detected",
    reviewer: "dba-team",
  },
  {
    condition: "package.json",
    reason: "Dependencies modified",
    reviewer: "tech-lead",
  },
];

function evaluateTriggers(changedFiles: string[]): HITLTrigger[] {
  return triggers.filter((trigger) =>
    changedFiles.some((file) => file.includes(trigger.condition))
  );
}

Considerações

Benefícios
  • **Consistent quality at scale.** Automated gates catch the same classes of issues every time, regardless of how many agents are producing code. Human reviewers do not need to check for formatting, type errors, or known security patterns.
  • **Focused human attention.** [[human-in-the-loop]] gates direct reviewer effort to decisions that genuinely require human judgment — architectural trade-offs, security implications, business logic correctness. This reduces reviewer fatigue and improves review quality.
  • **Measurable governance.** Gate pass rates, retry success rates, and escalation rates provide concrete data on agent output quality and governance effectiveness. Teams can identify systemic issues and track improvement over time.
  • **Clear escalation path.** The Four-Phase Escalation Ladder eliminates ambiguity about what happens when something fails. Every team member knows the process, reducing ad-hoc interventions and blocked work.
  • **Early failure detection.** Gates catch issues before they compound. An architectural violation caught at the gate level is far cheaper to fix than one discovered after five dependent components have been built on top of it.
Desafios
  • **Initial gate configuration effort.** Defining which checks run, what thresholds to set, and which HITL triggers to configure requires upfront investment. Start with a minimal set and expand based on data from the first few weeks.
  • **False positive management.** Overly strict automated gates produce false positives that slow the workflow and erode trust. Monitor the false positive rate and tune thresholds regularly. An advisory (non-blocking) tier helps identify where gates are too aggressive.
  • **Balancing speed and thoroughness.** Too many gates slow the development loop. Too few gates let quality issues through. The right balance depends on the codebase, the team's risk tolerance, and the maturity of the agents. Review gate configuration monthly.
  • **Escalation culture.** The escalation ladder only works if the team uses it consistently. If engineers bypass gates or skip phases, the system degrades. Leadership must reinforce that escalation is a normal part of the workflow, not a sign of failure.
  • **Gate maintenance.** As the codebase evolves, gates must evolve with it. New architectural rules need new conformance checks. New security patterns need new scanning rules. Assign ownership of gate maintenance to the Evaluation Engineer role.