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ć.
Dlaczego to ważne w 2026
Dział zatytułowany „Dlaczego to ważne w 2026”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 znalezisk cross-site-scripting 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ą. Kwestia atrybucji jest dziś podstawą gry: Microsoft na krótko ustawił w VS Code domyślną wartość git.addAICoAuthor na on (chatAndAgent) pod koniec kwietnia 2026, po czym cofnął ją do off w maju 2026 (1.119), gdy wadliwy rollout błędnie przypisywał kod ludzi do Copilota — więc trailer Co-authored-by: Copilot <copilot@github.com> znów jest opt-in, ale jego format po włączeniu pozostaje niezmieniony. 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. Kluczowy szczegół mechaniczny: GitHub nie pozwala sprawić, by wymagany status check odpalał się tylko wtedy, gdy obecny jest label — wymagany check, by dało się go zaspokoić, musi odpalać się na każdym PR. Dlatego bramkowanie jest odwrócone. Rejestrujesz jeden zawsze-wymagany check na każdą bramkę w swoim rulesecie, a workflow stojący za każdym checkiem czyta label ai-authored i decyduje, czy odpalić ciężką wersję, czy zwarcie do przechodzącego no-opa. Ten pojedynczy wybór projektowy prowadzi każdego zalabelowanego PR-a przez cztery dodatkowe gates poza standardowym pipeline, jednocześnie utrzymując wymagane checki zawsze-raportowanymi:
- 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. Job
full-testsodpala się na każdym PR, ale natychmiast kończy się kodem 0, gdy labela nie ma. - Skan SAST + SCA z twardą bramką severity. Semgrep/CodeQL/Snyk Code plus SCA Snyk/Socket odpalają się z progiem fail-the-build na
HIGHwewnątrz workflowu — to tu żyje twarda bramka severity, bo deterministyczne skanery wspierają failowanie po severity, a semantyczny reviewer AI nie. Zhalucynowane zależności i skopiowane podatne wzorce to tryby porażki, dla których ta bramka istnieje. - Wymagane dwie ludzkie aprobaty. Wymagaj dwóch aprobat na
main(globalnie albo przez regułę CODEOWNERS/zespołu). Ponieważ GitHub stosujerequired_approving_review_countper target rulesetu brancha — nie per label — “drugi reviewer dla PR-ów AI” jest wymuszany przez workflow, który failuje wymagany status check, gdy zalabelowany PR ma mniej niż dwie aprobaty. Drugi reviewer to strukturalna obrona przed “pierwszy reviewer zaufał AI, AI zaufało sobie, nikt nie przeczytał diff-a.” - 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.
Aktualny krajobraz (zweryfikowany web-searchem)
Dział zatytułowany „Aktualny krajobraz (zweryfikowany web-searchem)”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, wzorzec “zawsze-wymagany check, który czyta label wewnątrz workflowu” stał się udokumentowanym sposobem na warunkowe bramkowanie w GitHubie, a skanery bezpieczeństwa dowiozły integracje z GitHub Actions pierwszej klasy, które gate’ują czysto na severity.
Sygnały detekcji (trailery Co-Authored-By, stopki w body PR-a, prefiksy branchy)
Dział zatytułowany „Sygnały detekcji (trailery Co-Authored-By, stopki w body PR-a, prefiksy branchy)”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 wpisuje Co-authored-by: Copilot <copilot@github.com>, gdy ustawienie git.addAICoAuthor jest włączone (od VS Code 1.119, po cofnięciu z maja 2026, jest domyślnie off — więc nie zakładaj, że PR-y Copilota niosą trailer, chyba że Twoja organizacja go włączyła). OpenAI Codex dokleja konfigurowalny trailer Co-authored-by — domyślnie Codex <noreply@openai.com> — sterowany kluczem commit_attribution w .codex/config.toml; zacommituj plik, żeby cały zespół miał spójną atrybucję (pusty string ją wyłącza). Sygnały wtórne wzmacniają detekcję: workflow agentowe często zawierają 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)”GitHub nie wspiera uzależniania wymaganego status checka od labela PR-a — nie ma w rulesetach ani branch protection przełącznika “odpalaj ten wymagany check tylko, gdy obecny jest ai-authored”. Wymagany check, by dało się go zaspokoić, musi zawsze odpalać. Udokumentowany wzorzec jest odwrotny: zarejestruj stały zestaw wymaganych checków na main, a logikę labela wepnij wewnątrz każdego workflowu.
- Zawsze-wymagane checki (odpalają na każdym PR): lint, type-check, smoke tests, secret scan, plus joby bramkowe
full-tests,sast-scan,sca-scaniai-reviewers. - Co joby bramkowe robią, gdy obecny jest
ai-authored:full-testsodpala unit + integration + e2e;sast-scanodpala Semgrep/CodeQL z progiem failuseverity: high;sca-scanodpala Snyk/Socket z progiem failuseverity: high;ai-reviewersfailuje, gdy obecne są mniej niż dwie aprobaty. Gdy labela nie ma, każdy job natychmiast kończy się kodem 0, więc wymagany check zawsze raportuje zielono, a bramka gryzie tylko na zalabelowanych PR-ach.
Każdy job bramkowy triggeruje się na pull_request, czyta label z kontekstu GitHub Actions (albo gh api repos/{owner}/{repo}/issues/{PR#}/labels) i rozgałęzia się na nim. Najczystsze integracje z GitHub Actions w 2026: Semgrep (odpalaj semgrep ci --config auto w oficjalnym kontenerze semgrep/semgrep, emitując SARIF — stary wrapper returntocorp/semgrep-action jest deprecated), 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 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 — ale zwróć uwagę, że jedynie komentuje znaleziska; nie ma inputu fail-po-severity, więc twardą bramkę severity trzymaj na deterministycznych skanerach, a action Anthropic traktuj jako nieblokującego semantycznego reviewera. 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.
Śledzenie % autorstwa AI w czasie
Dział zatytułowany „Śledzenie % autorstwa AI w czasie”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”- 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 trailerCo-Authored-By: (Claude|Copilot|Codex)w dowolnym commicie? Ile ma labelai-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. - Wybierz nazwę labela i udokumentuj go. Standaryzuj się na
ai-authored(lubai-assisted, jeśli wolisz łagodniejsze sformułowanie). Udokumentuj regułę wCONTRIBUTING.md: “PR-y z dowolnym commit-em AI-tool-authored są automatycznie labelowaneai-authored. Ten label uruchamia dodatkowe bramki CI. Nie usuwaj go ręcznie.” Pre-twórz label w każdym repo przezgh label create ai-authored --color C00000 --description "Zawiera commity AI-authored — obowiązują dodatkowe gates". - Napisz auto-labelujący GitHub Action. Stwórz
.github/workflows/ai-pr-label.ymltriggerowany napull_request: [opened, synchronize, reopened]. Job czyta commity przezgh 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. - Dodaj job AI security review. Wepnij
anthropics/claude-code-security-revieww job bramkowy. Przypnij go do SHA commita (anthropics/claude-code-security-review@<sha>) zamiast do taga — repo nie publikuje tagów release’owych, a jego README zaznacza, że nie jest zahardenowany przeciw prompt injection, więc pin po SHA to bezpieczna z punktu widzenia supply-chain referencja. Nie ma inputu fail-po-severity, więc skonfiguruj go na komentowanie findings (comment-pr: true) i traktuj jako nieblokującego semantycznego reviewera. Uruchamiaj go równolegle z deterministycznym skanerem SAST — łapią różne rzeczy, a twarda bramka żyje na skanerze, nie tutaj. - Dodaj deterministyczne skanery SAST + SCA. Wybierz jeden SAST (Semgrep to startowy punkt o najniższym tarciu — odpalaj
semgrep ci --config autow oficjalnym kontenerzesemgrep/semgrep; wrapperyreturntocorp/semgrep-action/semgrep/semgrep-actionsą deprecated) i jeden SCA (Snyk albo Socket). Każdy odpala wewnątrz swojego joba bramkowego, czyta labelai-authoredi odpala pełny skan, gdy jest obecny, jest skonfigurowany z progiem fail naseverity: highi wypisuje output SARIF, który zaczytuje tab GitHub Security. - Skonfiguruj branch protection z zawsze-wymaganymi checkami bramkowymi. Otwórz ustawienia Rulesets repo i stwórz ruleset targetujący
main. Pod “Required status checks” wymień każdy job bramkowy po jego nazwie checka: lint, type-check, smoke tests, secret scan,full-tests,sast-scan,sca-scaniai-reviewers. Nie szukaj opcji “conditional checks” — ona nie istnieje; warunkowość żyje wewnątrz każdego workflowu (ciężki run, gdy zalabelowany, natychmiastowe przejście, gdy nie). Ustawrequired_approving_review_countna 2 na poziomie brancha (albo wymuszaj drugiego reviewera dla zalabelowanych PR-ów przez jobai-reviewers). Zapisz i włącz. - Wepnij route do AI-aware human reviewera. Zaktualizuj CODEOWNERS tak, by PR-y zalabelowane
ai-authoredautomatycznie 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ł. - Dodaj customową komendę slash
/ai-review. Stwórz.claude/commands/ai-review.mdz 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-achai-authored. - 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.
- 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.
Typowe pułapki
Dział zatytułowany „Typowe pułapki”- 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-authoredjest 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ą. Zarejestruj joby bramkowe (full-tests,sast-scan,sca-scan,ai-reviewers) jako zawsze-wymagane checki w rulesecie namaini 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. --adminoverrides na PR-ach AI-authored. Symptom: senior nadpisuje failującą bramkę “żeby dowieźć piątkowy release”. Naprawa: cała polityka kolapsuje przy pierwszym--adminoverride. 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.
Jak zweryfikować, że dowiozłeś
Dział zatytułowany „Jak zweryfikować, że dowiozłeś”- Pre-egzystujący GitHub label
ai-authoredistnieje 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 branchyclaude//codex/. - Ruleset na
mainwymieniafull-tests,sast-scan,sca-scaniai-reviewersjako zawsze-wymagane status checki; każdy job odpala ciężką ścieżkę tylko, gdy obecny jestai-authored, a w przeciwnym razie przechodzi natychmiast, irequired_approving_review_countwynosi 2 (na poziomie brancha albo wymuszane dla zalabelowanych PR-ów przezai-reviewers). - Próba mergowania zalabelowanego PR-a z dowolnym jobem bramkowym raportującym czerwono (ciężka ścieżka padła) 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.mdistnieje 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
--adminoverrides na bramkach PR-ów AI-authored w ostatnich 30 dniach (lub każdy override jest revzewowany na cotygodniowym inżynierskim forum).