Przejdź do głównej zawartości

Labelowanie AI-PR — odróżniaj + nakładaj dodatkowe gates

Pytanie ze scorecardu (Q11 · Quality gates): Czy odróżniasz PR-y AI-authored od human-authored (label, check, signing)? Odpowiedź na maks (3 pkt): Label + dodatkowe gates (pełny test suite + security scan + 2× reviewer) na PR-ach AI. Dlaczego to ważne: Nie zarządzisz tym, czego nie widzisz. PR-y AI zasługują na inną skalę kontroli — ale tylko jeśli umiesz je zidentyfikować.

W połowie 2026 udział PR-ów AI-authored w realnych organizacjach inżynierskich oscyluje między 30% a 60% — a w greenfieldowych zespołach agresywnie używających Claude Code, Cursora i Codex Cloud regularnie przekracza 70%. Profil bugów PR-ów AI-authored jest strukturalnie inny niż ludzkich: raport CodeRabbit State of AI vs Human Code Generation (grudzień 2025) wykazał, że PR-y AI-co-authored dowożą 1,7× więcej issues (10,83 vs 6,45 na PR), przy 1,4× więcej critical findings, 2,74× więcej luk bezpieczeństwa i mniej więcej 2× więcej luk w error handlingu. Telemetria branżowa z 2026: incydenty na pull request wzrosły o 23,5%, a change failure rate podskoczył o 30%, mimo że 75% developerów twierdzi, że ręcznie review-uje kod AI. Problem nie polega na “AI pisze zły kod”. To, że AI pisze kod na tyle szybko, że dowolny pojedynczy reviewer staje się wąskim gardłem — a jeśli nie odróżnisz PR-ów AI od PR-ów ludzkich na bramce, nie zeskalujesz różnicy w kontroli, której one potrzebują. Microsoft włączył trailery Co-authored-by: Copilot domyślnie w rozszerzeniu Git VS Code w kwietniu 2026 (PR zmergowany do microsoft/vscode:main 16 kwietnia), bo branża doszła do wniosku, że atrybucja przestała być opcjonalna. Claude Code dokleja Co-Authored-By: Claude <noreply@anthropic.com> do każdego commita autorstwa agenta. Sygnały są. Q11 pyta, czy wpiąłeś je w CI.

Jak naprawdę wygląda maksymalny wynik (auto-label + 4 dodatkowe gates)

Dział zatytułowany „Jak naprawdę wygląda maksymalny wynik (auto-label + 4 dodatkowe gates)”

Maksymalny setup Q11 jest mechaniczny i nudny. Otwiera się PR AI-authored. W ciągu 30 sekund GitHub Action sprawdza trailery commitów, nazwę brancha i body PR-a, i aplikuje label ai-authored. Branch protection na main prowadzi każdego zalabelowanego PR-a przez cztery dodatkowe gates poza standardowym pipeline:

  1. Pełny test suite, nie smoke subset. Tam, gdzie PR ludzki może odpalić tylko subset zmienionego pakietu dla szybkości, PR AI odpala unit + integration + e2e, bo tryby porażki zhalucynowanego kodu nie respektują granic pakietów.
  2. Skan SAST + SCA z twardą bramką severity. Semgrep/CodeQL/Snyk Code plus SCA Snyk/Socket odpalają się z progiem fail-the-build na HIGH. Zhalucynowane zależności i skopiowane podatne wzorce to tryby porażki, dla których ta bramka istnieje.
  3. Wymagane dwie ludzkie aprobaty. Branch protection wymusza required_approving_review_count: 2 ograniczoną do labela ai-authored. Drugi reviewer to strukturalna obrona przed “pierwszy reviewer zaufał AI, AI zaufało sobie, nikt nie przeczytał diff-a.”
  4. AI-aware reviewer w stacku. Claude Code Action z subagentem code-reviewer, albo dedykowany slash command /ai-review, który odpala twardsze checki (security patterns, hallucination detection, edge-case probing) niż domyślny /review.

Równolegle publikujesz metrykę % autorstwa AI: cotygodniowy job odpytuje zmergowane PR-y po labelu ai-authored i zapisuje procent na dashboardzie obok DORA. Jeśli % autorstwa AI rośnie, a revert rate jest płaski, gates działają; jeśli oba rosną razem, masz problem z bramką.

Niższe tiery: 0 pkt każdy PR jest w CI identyczny. 1 pkt developerzy self-labelują ręcznie (niewiarygodnie). 2 pkt auto-label istnieje, ale brak różnicowych gates. 3 pkt auto-label + cztery gates + śledzona metryka.

Trzy rzeczy zmieniły się w 2025-2026, które sprawiają, że Q11 maks-score jest osiągalny bez customowej inżynierii: narzędzia AI ustandaryzowały atrybucję machine-readable, rulesets GitHuba dojrzały na tyle, by wymuszać label-conditional politykę, a skanery bezpieczeństwa dowiozły integracje z GitHub Actions pierwszej klasy, które gate’ują czysto na severity.

Sygnały detekcji (Co-Authored-By: Claude, ”🤖” w commicie, label z hooka)

Dział zatytułowany „Sygnały detekcji (Co-Authored-By: Claude, ”🤖” w commicie, label z hooka)”

Warstwa atrybucji jest teraz spójna w trzech głównych agentach. Claude Code dokleja Co-Authored-By: Claude <noreply@anthropic.com> do każdego commita agenta. GitHub Copilot (po domyślnej zmianie w VS Code z kwietnia 2026) wpisuje Co-authored-by: Copilot <copilot@github.com> zawsze, gdy feature Copilot wnosi wkład w zmianę. OpenAI Codex CLI / Codex Cloud wypełniają konfigurowalny trailer; zespoły standaryzują się na Co-Authored-By: Codex <codex@openai.com> przez pre-commit hook. Sygnały wtórne wzmacniają detekcję: workflow agentowe często zawierają emoji 🤖 i stopkę generated-with-Claude-Code w body PR-a, a równoległe agentowe backlogi typowo używają prefiksów branchy claude/<slug> albo codex/<slug>. Solidna reguła detekcji to unia: regex trailera (Co-Authored-By: (Claude|Copilot|Codex)) LUB match stopki body PR-a LUB match prefiksu brancha. False-positive rate bliski zera; false-negatives to realne ryzyko, mitygowane dodawaniem sygnałów w miarę pojawiania się nowych narzędzi.

Auto-labelowanie przez GitHub Actions albo pre-push hook

Dział zatytułowany „Auto-labelowanie przez GitHub Actions albo pre-push hook”

Samo labelowanie to 30-linijkowy GitHub Action na pull_request: [opened, synchronize]. Czyta commity przez gh api, regex-matchuje trailery, czyta body PR-a, czyta ref brancha i woła gh pr edit <PR#> --add-label ai-authored, jeśli odpalił się dowolny sygnał. Dwie uwagi: odpalaj go na synchronize (developer może amendować trailer po otwarciu human PR-a — chcesz, by label podążał za prawdą, nie stanem początkowym) i zrób go idempotentnym. Client-side hook pre-push może mirrorować logikę dla wczesnego sygnalizowania, ale traktuj GitHub Action jako source of truth — lokalne hooki mogą być wyłączone.

Wymagane dodatkowe checki (pełny test suite, skan SAST, 2× human review)

Dział zatytułowany „Wymagane dodatkowe checki (pełny test suite, skan SAST, 2× human review)”

API Rulesets GitHuba (GA w 2025) wspiera label-conditional required checks. Zdefiniuj ruleset na main:

  • Wymagane dla wszystkich PR-ów: lint, type-check, smoke tests, secret scan.
  • Wymagane, gdy ai-authored: pełny test suite, skan SAST (Semgrep/CodeQL) z severity: high failującym build, skan SCA (Snyk/Socket) z severity: high failującym build, required_approving_review_count: 2, co najmniej jeden status check od AI-aware reviewera.

Najczystsze integracje z GitHub Actions w 2026: Semgrep (rulepacks OSS + Pro rules), CodeQL (darmowy dla publicznych repo, Advanced Security dla prywatnych), Snyk Code (płatne, szerokie pokrycie języków), Socket (wyspecjalizowane w supply-chain npm/PyPI). Action Anthropic claude-code-security-review (wydany 2025) warto stackować z deterministycznym skanerem — łapie semantyczne kwestie bezpieczeństwa (bypass autoryzacji przez złą kolejność middleware, brak filtracji tenanta), które omijają skanery oparte na wzorcach. Reguła 2× reviewer łapie tryb porażki, w którym pierwszy reviewer rubber-stampuje PR AI, bo “wyglądał czysto” — świeża druga para oczu wymusza ponowne czytanie.

Metryką, która czyni Q11 czytelnym dla leadership, jest % autorstwa AI zmergowanych PR-ów, tydzień do tygodnia. Jeden call gh api graphql pobiera zmergowane PR-y i ich labele; filtruj do ostatnich 7 dni, klasyfikuj po ai-authored, dziel. Wpisz do PostHog/Grafany/JSON i trenduj obok czwórki DORA. Interpretacja: % autorstwa AI rośnie ze stabilnym DORA = gates działają. Rośnie z degradującym się change failure rate = problem z bramką. Płaski przy wysokim raportowanym użyciu AI = false-negative detekcji, audytuj labelowanie. Ta metryka zasila Q22 · panel metryk AI.

Krok po kroku: budowa detekcji i bramkowania PR-ów AI

Dział zatytułowany „Krok po kroku: budowa detekcji i bramkowania PR-ów AI”
  1. Zaaudytuj obecny stan. Pobierz ostatnie 50 zmergowanych PR-ów przez gh pr list --state merged --limit 50 --json number,labels,author,title,commits. Policz: ile ma trailer Co-Authored-By: (Claude|Copilot|Codex) w dowolnym commicie? Ile ma label ai-authored (lub podobny)? Luka między liczbą trailerów a liczbą labeli to Twój obecny wynik Q11. Jeśli labels = trailers, jesteś na 2 pkt. Jeśli labels = 0 a trailers > 0, jesteś na 0-1 pkt.
  2. Wybierz nazwę labela i udokumentuj go. Standaryzuj się na ai-authored (lub ai-assisted, jeśli wolisz łagodniejsze sformułowanie). Udokumentuj regułę w CONTRIBUTING.md: “PR-y z dowolnym commit-em AI-tool-authored są automatycznie labelowane ai-authored. Ten label uruchamia dodatkowe bramki CI. Nie usuwaj go ręcznie.” Pre-twórz label w każdym repo przez gh label create ai-authored --color C00000 --description "Zawiera commity AI-authored — obowiązują dodatkowe gates".
  3. Napisz auto-labelujący GitHub Action. Stwórz .github/workflows/ai-pr-label.yml triggerowany na pull_request: [opened, synchronize, reopened]. Job czyta commity przez gh api repos/{owner}/{repo}/pulls/{PR#}/commits, regex-matchuje trailery, czyta body PR-a w poszukiwaniu stopki agent-generated, czyta nazwę brancha i dodaje label, jeśli odpalił się dowolny sygnał. Zrób go idempotentnym. Przetestuj na draft PR-ze przed rolloutem.
  4. Dodaj job AI security review. Wepnij anthropics/claude-code-security-review@v1 (lub odpowiednik) w workflow, który odpala się tylko, gdy PR jest zalabelowany ai-authored. Ustaw go na komentowanie findings i failowanie joba na severity: high. Uruchamiaj go równolegle z deterministycznym skanerem SAST — łapią różne rzeczy.
  5. Dodaj deterministyczne skanery SAST + SCA. Wybierz jeden SAST (Semgrep to startowy punkt o najniższym tarciu — returntocorp/semgrep-action@v1 z rulepackiem auto) i jeden SCA (Snyk albo Socket). Obydwa powinny być triggerowane labelem, skonfigurowane z progiem fail na severity: high i wypisywać output SARIF, który zaczytuje tab GitHub Security.
  6. Skonfiguruj branch protection z warunkowymi checkami. Otwórz ustawienia Rulesets repo. Stwórz ruleset targetujący main. Pod “Required status checks” wymień joby always-on (lint, type-check, smoke tests, secret scan). Pod “Conditional checks” dodaj regułę: gdy obecny jest label ai-authored, dodatkowo wymagaj full-tests, sast-scan, sca-scan, claude-security-review i required_approving_review_count: 2. Zapisz i włącz.
  7. Wepnij route do AI-aware human reviewera. Zaktualizuj CODEOWNERS tak, by PR-y zalabelowane ai-authored automatycznie requestowały review od wyznaczonego zespołu “AI PR reviewers” — rotującego rosteru senior engineerów wyszkolonych do czytania diff-ów AI-authored pod konkretne tryby porażki (zhalucynowane API, skopiowane podatne wzorce, brak obsługi null/edge). Zespół może mieć minimum 3 osoby; rotuj tygodniowo, żeby nikt się nie wypalił.
  8. Dodaj customową komendę slash /ai-review. Stwórz .claude/commands/ai-review.md z promptem, który wprost mówi reviewerowi, że diff jest AI-authored i wymienia AI-specific tryby porażki do sprawdzenia (zhalucynowane sygnatury funkcji, zhalucynowane importy, brak walidacji wejścia, regresje bezpieczeństwa w zmienionym kodzie auth/DB, skopiowane podatne snippety). To staje się drugim AI-reviewer status checkiem na PR-ach ai-authored.
  9. Wepnij metrykę % autorstwa AI. Napisz cotygodniowy cron (GitHub Action na schedule albo mały Cloudflare Worker albo cron Vercela), który odpytuje GraphQL API, liczy % autorstwa AI i postuje do Twojego metric store (event PostHog, datasource Grafany albo plik JSON w repo metryk, który czyta Twój dashboard). Ustaw alert na Slacku, gdy % autorstwa AI przesunie się o więcej niż 10pp tydzień do tygodnia — sygnalizuje to albo przyspieszenie adopcji, albo regresję labelowania.
  10. Wytocz w jednym repo, potem rozszerzaj. Pilotuj pełny stack w repo o najwyższym wolumenie przez dwa tygodnie. Obserwuj dokładność labelowania, wpływ na CI runtime (dodatkowe gates dodają zwykle 3-8 minut) i zmęczenie reviewerów. Stroij. Potem wyeksportuj pliki workflow i konfig rulesetu jako reusable templates i wytocz na każde repo.
  • Poleganie na dyscyplinie developera w dodawaniu labela. Symptom: połowa Twoich PR-ów AI-authored jest niezalabelowana, bo developerzy zapomnieli. Naprawa: automatyzuj label przez Action z triggerami pull_request: [opened, synchronize]; nigdy nie ufaj ręcznemu labelowaniu w decyzjach policy-critical.
  • Brak branch protection wymuszającego dodatkowe gates. Symptom: label ai-authored jest poprawny, ale gates są “opcjonalne” — developerzy mogą mergować bez zielonego skanu SAST. Naprawa: cała wartość Q11 leży w branch protection. Bez niego label jest dekoracją. Przenieś warunkowe required checki do rulesetu na main i zweryfikuj próbując zmergować zalabelowanego PR-a z czerwoną bramką — powinien być zablokowany.
  • Brak metryk na % autorstwa AI. Symptom: masz label i gates, ale nie odpowiesz “jaki procent PR-ów z ostatniego kwartału był AI-authored?” Naprawa: time series % autorstwa AI to wskaźnik wyprzedzający łączący Q11 z Q22 i ostatecznie Q23 (ROI). Bez metryki nie pokażesz leadership, że gates skalują się z adopcją AI ani że adopcja rośnie.
  • Traktowanie trailerów Co-Authored-By jako jedynego sygnału. Symptom: developer wkleja output Claude w Cursor bez dodania trailera; PR ląduje niezalabelowany. Naprawa: unia sygnałów — trailer LUB stopka body PR-a LUB prefiks brancha. Pojawiają się nowe narzędzia; rewiduj sygnały detekcji co kwartał.
  • Karny framing labela. Symptom: developerzy zdejmują trailer, by uniknąć dodatkowych gates. Naprawa: framuj label jako higienę inżynierską, nie obwinianie. Dodatkowe gates to sposób, w jaki organizacja ufa pracy AI-authored, a nie sposób, w jaki karze autora. Roster reviewerów to rotujący senior engineerowie, a nie zespół quality-cop. Sparuj rollout polityki z jawnym komunikatem, że AI-authoring jest zachęcany — wymagana jest widoczność, a nie abstynencja.
  • Pojedyncze narzędzie SAST/SCA bez AI security reviewera. Symptom: deterministyczne skanery omijają semantyczne kwestie bezpieczeństwa (bypass autoryzacji, wyciek tenanta), które AI reviewer by złapał. Naprawa: stackuj Semgrep/CodeQL (pattern-based) z claude-code-security-review (semantyczny). Łapią inne klasy issues, a overlap false-positive jest niski.
  • --admin overrides na PR-ach AI-authored. Symptom: senior nadpisuje failującą bramkę “żeby dowieźć piątkowy release”. Naprawa: cała polityka kolapsuje przy pierwszym --admin override. Zrób override audit-logged i revzewowany tygodniowo. Proces wyjątku powinien być udokumentowaną eskalacją, a nie flagą, którą senior odpala z CLI.
  • Brak re-ewaluacji, gdy zmienia się tooling AI. Symptom: nowy agent dowozi inny format trailera, a Twoja detekcja go omija przez miesiąc. Naprawa: rewiduj sygnały detekcji co kwartał. Zasubskrybuj release notes Claude Code, Copilot, Codex CLI i Cursor. Aktualizuj regex.
  • Pre-egzystujący GitHub label ai-authored istnieje w każdym repo z udokumentowanym opisem.
  • .github/workflows/ai-pr-label.yml (lub odpowiednik) auto-aplikuje label na PR open + synchronize i jest idempotentny.
  • Label odpala się poprawnie dla PR-ów z trailerami Co-Authored-By: (Claude|Copilot|Codex), stopkami body PR-a generated-by-agent i prefiksami branchy claude//codex/.
  • Ruleset na main definiuje warunkowe required checki: gdy obecny jest ai-authored, full-tests, sast-scan, sca-scan, claude-security-review są wymagane i required_approving_review_count: 2.
  • Próba mergowania zalabelowanego PR-a z dowolną dodatkową bramką na czerwono jest blokowana na warstwie branch protection.
  • CODEOWNERS prowadzi zalabelowane PR-y do wyznaczonego zespołu AI-PR reviewerów (rotujący roster).
  • .claude/commands/ai-review.md istnieje i jest triggerowany na zalabelowanych PR-ach.
  • Cotygodniowa metryka % autorstwa AI jest publikowana w Twoim metric store i widoczna na inżynierskim dashboardzie obok czwórki DORA.
  • W ostatnim kwartale change failure rate na PR-ach AI-authored jest na poziomie human-authored baseline lub poniżej — mierzalny dowód, że gates działają.
  • Brak --admin overrides na bramkach PR-ów AI-authored w ostatnich 30 dniach (lub każdy override jest revzewowany na cotygodniowym inżynierskim forum).