Pakiet dowodów: co musi udowodnić pull request agenta
Pakiet dowodów (evidence bundle) to ustrukturyzowany blok w pull requeście agenta, który dowodzi zmiany: link do specyfikacji i zmiana zachowania, każde kryterium akceptacji przypisane do sprawdzenia, które się wykonało, wyniki poleceń, dowody z działania lub ewaluacji, klasa ryzyka, wrażliwe ścieżki, zmiany wyroczni i pochodzenie. Check w CI parsuje pakiet i blokuje merge, gdy jest niekompletny.
Agenci twojego zespołu otwierają kilkanaście pull requestów dziennie, a każdy opis brzmi tak samo: „Zaimplementowałem paginację, dodałem testy, wszystkie checki przechodzą”. Trzy z nich po cichu zmieniły fixture testowe, jeden dotknął webhooka płatności, a żaden nie mówi, którego kryterium akceptacji dowodzi który test. Nie odróżnisz bezpiecznych od ryzykownych bez czytania każdego diffa, a właśnie tę pracę agenci mieli ci oszczędzić.
Ta strona jest dla programistów, którzy konfigurują agentów, tech leadów, którzy odpowiadają za zasady review, i CTO, którzy potrzebują jednego zapisu audytowego na każdą zmianę. To kanoniczny schemat manifestu zmiany w całym serwisie: pochodzenie zmian i routing według ryzyka kieruje zmiany na podstawie tych pól, a czytanie dowodów zamiast kodu wyjaśnia, jak recenzent je czyta.
Co daje ci pakiet dowodów
Dział zatytułowany „Co daje ci pakiet dowodów”- Schemat pole po polu, z informacją, kto wypełnia każde pole i jak CI je weryfikuje.
- Szablon pull requesta, który agenci i ludzie wypełniają tak samo.
- Przetestowany check CI (około 80 linii Node), który oblewa niekompletny pakiet i przelicza klasę ryzyka z diffa.
- Tabelę routingu, która zamienia klasę ryzyka w odpowiedź na pytania, kto zatwierdza i kto musi czytać kod.
- Trzy prompty do skopiowania: przygotuj pakiet, zaudytuj pakiet względem diffa, napraw oblany check.
- Tryby awarii bramki opartej na pakiecie i sposób wyjścia z każdego z nich.
Dlaczego opis pull requesta nie jest dowodem
Dział zatytułowany „Dlaczego opis pull requesta nie jest dowodem”Opis to proza, którą agent napisał o własnej pracy. Może być błędny w sposób, którego nikt nie zauważy aż do produkcji. Skala, przy której ma to znaczenie, została zmierzona: raport Acceleration Whiplash firmy Faros AI (kwiecień 2026; telemetria z 22 000 programistów i ponad 4000 zespołów; telemetria dostawcy z bazy klientów Faros) pokazał wzrost mediany czasu w review o 441,5% i o 31,3% więcej pull requestów scalanych bez żadnego review. Generowanie się przeskalowało, czytanie nie.
Rozwiązaniem jest wymaganie wyników sprawdzeń zamiast deklaracji o nich. Jak ujął to jeden z praktyków: „Model może przekonywać, że jego praca jest skończona. Deterministyczny walidator może udowodnić, że brakuje wymaganego pola” (tłum. własne; oryginał: „A model can argue that its work is complete. A deterministic validator can prove that a required field is missing.”; NARESH, Graph Engineering for AI Coding Agents, DEV Community, 30 lipca 2025). Pakiet jest tym, co taki walidator czyta.
Co zawiera pakiet dowodów?
Dział zatytułowany „Co zawiera pakiet dowodów?”Pakiet ma siedem sekcji. Sednem projektu jest kolumna Weryfikacja w CI: każde pole, w którym agent mógłby pomylić się na swoją korzyść, jest albo przeliczane z diffa, albo sprawdzane względem gałęzi.
| Sekcja | Pola | Kto wypełnia | Weryfikacja w CI | Kiedy wymagana |
|---|---|---|---|---|
| Specyfikacja | spec.link, spec.delta (zmiany zachowania prostymi zdaniami), spec.unrequested | Agent, na podstawie zgłoszenia lub spec.md | Link to URL albo plik istniejący w gałęzi; delta nie jest pusta | Zawsze |
| Akceptacja | Jeden wpis na kryterium: criterion, check (plik:linia albo polecenie), result | Agent, po uruchomieniu sprawdzeń | Każdy result to pass; każdy cytowany plik istnieje | Zawsze |
| Sprawdzenia | command, exit_code, opcjonalnie summary (np. wynik testów mutacyjnych) | Agent | Każdy exit_code to 0. CI uruchamia też własne wymagane joby; pakiet nigdy ich nie zastępuje | Zawsze |
| Działanie | kind (screenshot, trace, video, preview-url), ref, covers (identyfikatory kryteriów) | Agent, z podglądu lub przebiegu w przeglądarce | Obecne, gdy zmieniły się ścieżki UI | Gdy pasują globy z polityki |
| Ewaluacje | suite, score, baseline | Agent albo job ewaluacyjny w CI | score ≥ baseline | Gdy zmieniły się prompty, konfiguracja modelu lub harness agenta |
| Ryzyko | class (low, standard, high), touches (klasy wrażliwe), oracle_changes (ścieżka, kierunek, powód), rollback | Agent proponuje | CI przelicza klasy wrażliwe i pliki wyroczni z diffa, ustala próg i oblewa niższą deklarację | Zawsze |
| Pochodzenie | agent (narzędzie i wersja), model, session, task, human_owner | Agent oraz człowiek, który odpowiada za zmianę | agent, model i human_owner są wypełnione | Zawsze |
Trzy zasady pilnują uczciwości schematu:
- Zadeklarowana klasa ryzyka może tylko podnieść wyliczony próg. Agent, który wpisze
class: lowprzy zmianie w płatnościach, obleje check; człowiek, który oznaczy nieszkodliwą zmianę jakohigh, dostanie surowsze review i to jest dozwolone. - Zmiana wyroczni nigdy nie jest domyślnie neutralna. Każdy edytowany test, snapshot, workflow CI, konfiguracja lintera lub typów musi trafić na listę z kierunkiem (
direction)stricter,looseralboneutral. Wpislooserwymuszahigh, bo zmienia znaczenie „zielonego” dla każdej innej zmiany. - Pochodzenie się zapisuje, ale nie steruje routingiem. Zmiany ludzi, zmiany wspierane przez AI i zmiany agentów używają tego samego pakietu i tego samego routingu. Strona o pochodzeniu i routingu wyjaśnia, dlaczego autorstwo jest słabym wskaźnikiem ryzyka.
Jak skonfigurować bramkę pakietu dowodów?
Dział zatytułowany „Jak skonfigurować bramkę pakietu dowodów?”Konfiguracja to pięć plików. Dodaj je w jednym pull requeście, scal go, a dopiero potem ustaw check jako wymagany. Kolejność ma znaczenie, co wyjaśnia sekcja o trybach awarii.
-
Dodaj szablon pull requesta. GitHub wypełnia opis pull requestów otwieranych w interfejsie webowym treścią
.github/pull_request_template.md. Agenci, którzy otwierają pull requesty z wiersza poleceń, dostają tę samą strukturę z promptu do pakietu niżej, który wskazuje im ten plik..github/pull_request_template.md ## What changed and why<!-- Two or three sentences for a human. The bundle below is the evidence. -->## Evidence bundle~~~yamlevidence_bundle: 1spec:link: docs/specs/orders-pagination.md # or the issue URLdelta:- GET /orders returns 50 items per page and a next_cursor- The old page parameter returns 400unrequested: [] # behavior nobody asked foracceptance:- criterion: "AC1: first page has 50 items and a next_cursor"check: tests/orders.contract.test.ts:42result: pass # pass | fail | unverified- criterion: "AC2: the page parameter returns 400"check: tests/orders.contract.test.ts:88result: passchecks:- command: npm testexit_code: 0- command: npx stryker run --mutate "src/orders/**/*.ts"exit_code: 0summary: 81% mutation score on changed filesevals: [] # suite, score, baselineruntime: [] # kind, ref, coversrisk:class: standard # low | standard | hightouches: [] # auth, money, schema, migrations, infraoracle_changes:- path: tests/orders.contract.test.tsdirection: stricter # stricter | looser | neutralreason: new contract cases for AC1 and AC2rollback: revert the merge commit; no migration, no flagprovenance:agent: Claude Code 2.1.283model: claude-opus-5-5session: https://claude.ai/code/session_EXAMPLEtask: https://github.com/acme/shop/issues/412human_owner: "@anna"~~~ -
Napisz plik polityki. Nazywa klasy wrażliwe z ich minimalnym ryzykiem, ścieżki wyroczni oraz ścieżki, które wymagają dowodów z działania lub ewaluacji. Dopasuj globy do swojego repozytorium; te odpowiadają klasom eskalacji, których używa reszta serwisu.
# .github/evidence-policy.yml (owned by CODEOWNERS; editing it is an oracle change)sensitive:auth: { globs: ['**/auth/**', '**/middleware/**', '**/*permission*'], min_risk: high }money: { globs: ['**/billing/**', '**/payments/**', '**/pricing/**'], min_risk: high }schema: { globs: ['**/*.sql', '**/openapi*', '**/*.proto'], min_risk: high }migrations: { globs: ['**/migrations/**'], min_risk: high }infra: { globs: ['infra/**', '**/*.tf', '.github/workflows/**'], min_risk: standard }oracle:- '**/*.test.*'- '**/__snapshots__/**'- '.github/workflows/**'- '.github/evidence-policy.yml'- '.github/CODEOWNERS'- 'scripts/check-evidence.mjs'- 'tsconfig*.json'- 'eslint.config.*'runtime_required:- 'src/components/**'- 'src/pages/**'evals_required:- 'prompts/**' -
Dodaj skrypt sprawdzający. Czyta treść pull requesta ze zdarzenia GitHuba, parsuje pierwszy blok
yamlzaczynający się odevidence_bundle:i porównuje go z diffem. Zależy odyaml(2.9.1 w npm) iminimatch(10.2.6 w npm); obie wersje sprawdzone 2026-09-26.// scripts/check-evidence.mjs: fails a pull request whose evidence bundle is// missing, incomplete, or contradicted by the diff. Usage:// node check-evidence.mjs <policy.yml>import { appendFileSync, existsSync, readFileSync } from 'node:fs';import { execFileSync } from 'node:child_process';import { parse } from 'yaml';import { minimatch } from 'minimatch';const RANK = { low: 0, standard: 1, high: 2 };const policy = parse(readFileSync(process.argv[2], 'utf8'));const pr = JSON.parse(readFileSync(process.env.GITHUB_EVENT_PATH, 'utf8')).pull_request;const errors = [];const fail = (msg) => errors.push(msg);// 1. What CI knows without asking the agent: the changed files.const changed = (process.env.EVIDENCE_CHANGED_FILES ??execFileSync('git', ['diff', '--name-only', `${pr.base.sha}...HEAD`], { encoding: 'utf8' })).split('\n').filter(Boolean);const touching = (globs) => changed.filter((f) => globs.some((g) => minimatch(f, g, { dot: true })));// 2. The bundle: the first yaml fence (backticks or tildes) that starts with evidence_bundle:const block = (pr.body ?? '').match(/(`{3}|~{3})ya?ml\r?\n(evidence_bundle:[\s\S]*?)\1/);if (!block) {console.error('No evidence bundle found. Fill in the template from .github/pull_request_template.md.');process.exit(1);}const b = parse(block[2]) ?? {};// 3. Spec link and deltaif (!b.spec?.link) fail('spec.link is empty');else if (!/^https?:\/\//.test(b.spec.link) && !existsSync(b.spec.link)) fail(`spec.link ${b.spec.link} does not exist`);if (!b.spec?.delta?.length) fail('spec.delta lists no behavior change');// 4. Acceptance: every criterion names a check that exists and passedif (!b.acceptance?.length) fail('acceptance is empty');for (const a of b.acceptance ?? []) {if (a.result !== 'pass') fail(`acceptance "${a.criterion}" is ${a.result ?? 'missing a result'}`);const ref = /^([^\s:]+):(\d+)$/.exec(a.check ?? '');if (!a.check) fail(`acceptance "${a.criterion}" names no check`);else if (ref && !existsSync(ref[1])) fail(`acceptance "${a.criterion}" cites ${ref[1]}, which is not in the branch`);}for (const c of b.checks ?? []) if (c.exit_code !== 0) fail(`check "${c.command}" exited ${c.exit_code}`);if (!b.checks?.length) fail('checks lists no command that ran');// 5. Sensitive paths: CI recomputes them and sets the risk floorlet floor = 'low';const declared = new Set(b.risk?.touches ?? []);for (const [name, rule] of Object.entries(policy.sensitive)) {const hits = touching(rule.globs);if (!hits.length) continue;if (!declared.has(name)) fail(`diff touches ${name} (${hits.join(', ')}) but risk.touches omits it`);if (RANK[rule.min_risk] > RANK[floor]) floor = rule.min_risk;}// 6. Oracle changes: every edited test, CI or lint file is declared with a directionconst listed = new Map((b.risk?.oracle_changes ?? []).map((o) => [o.path, o.direction]));for (const f of touching(policy.oracle)) {const dir = listed.get(f);if (!dir) fail(`oracle file ${f} changed but is not in risk.oracle_changes`);else if (!['stricter', 'looser', 'neutral'].includes(dir)) fail(`oracle change ${f} has direction ${dir}; use stricter, looser or neutral`);if (RANK[floor] < RANK.standard) floor = 'standard';if (dir === 'looser') floor = 'high';}// 7. Runtime evidence and evals, where the policy requires themif (touching(policy.runtime_required).length && !b.runtime?.length) fail('UI paths changed but runtime lists no screenshot or trace');if (touching(policy.evals_required).length) {if (!b.evals?.length) fail('prompt or model paths changed but evals is empty');for (const e of b.evals ?? []) if (!(e.score >= e.baseline)) fail(`eval ${e.suite} scored ${e.score} against baseline ${e.baseline}`);}// 8. Risk class and provenanceif (!Object.hasOwn(RANK, b.risk?.class ?? '')) fail('risk.class must be low, standard or high');else if (RANK[b.risk.class] < RANK[floor]) fail(`risk.class is ${b.risk.class}, but the diff requires at least ${floor}`);if (!b.risk?.rollback) fail('risk.rollback is empty');for (const k of ['agent', 'model', 'human_owner']) if (!b.provenance?.[k]) fail(`provenance.${k} is empty`);const risk = RANK[b.risk?.class] > RANK[floor] ? b.risk.class : floor;if (process.env.GITHUB_OUTPUT) appendFileSync(process.env.GITHUB_OUTPUT, `risk=${risk}\n`);console.log(`Changed files: ${changed.length}. Risk class: ${risk}.`);if (errors.length) {console.error(`Evidence bundle incomplete (${errors.length}):\n- ${errors.join('\n- ')}`);process.exit(1);}console.log('Evidence bundle complete.'); -
Dodaj workflow. Dwa szczegóły sprawiają, że można mu ufać. Ładuje skrypt i politykę z commita bazowego, więc pull request nie osłabi skryptu ani polityki, które go oceniają. Sam plik workflow uruchamia się jednak z pull requesta, dlatego krok 5 daje katalogowi
.github/workflows/właściciela kodu i wymaga review od właścicieli kodu (albo robisz z niego workflow wymagany przez ruleset). Checkout ustawiapersist-credentials: false, więc token nie trafia do.git/config;gh pr editczytaGH_TOKENz własnego kroku. Uruchamia się też naedited, więc poprawienie opisu ponownie uruchamia check bez nowego pusha..github/workflows/evidence-bundle.yml name: evidence-bundleon:pull_request:types: [opened, edited, synchronize, reopened, ready_for_review]permissions:contents: readpull-requests: writejobs:evidence:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v7with:fetch-depth: 0persist-credentials: false- uses: actions/setup-node@v7with:node-version: 24- name: Load the checker and policy from the base branchrun: |mkdir -p /tmp/evidencegit show "${{ github.event.pull_request.base.sha }}:scripts/check-evidence.mjs" > /tmp/evidence/check.mjsgit show "${{ github.event.pull_request.base.sha }}:.github/evidence-policy.yml" > /tmp/evidence/policy.ymlnpm install --prefix /tmp/evidence --no-save yaml@2.9.1 minimatch@10.2.6- name: Check the evidence bundleid: checkrun: node /tmp/evidence/check.mjs /tmp/evidence/policy.yml- name: Label the risk classif: always() && steps.check.outputs.risk != ''env:GH_TOKEN: ${{ github.token }}run: |RISK="${{ steps.check.outputs.risk }}"STALE=$(printf 'risk:%s\n' low standard high | grep -vx "risk:$RISK" | paste -sd, -)gh pr edit "${{ github.event.pull_request.number }}" --remove-label "$STALE" --add-label "risk:$RISK"Utwórz raz etykiety
risk:low,risk:standardirisk:high;gh pr edit --add-labelnie tworzy brakujących etykiet. Krok zdejmuje też dwie pozostałe etykietyrisk:*, bo samo--add-labelnigdy żadnej nie usuwa: pull request, który po pushu przechodzi zestandarddohigh, miałby inaczej obie, a wszystko, co kieruje zmiany według etykiet, odczytałoby nieaktualną klasę. -
Ustaw check jako wymagany i chroń bramkę. W rulesecie gałęzi
mainwymagaj statusuevidencei review od właścicieli kodu. Potem daj właściciela, który nie jest agentem, trzem grupom ścieżek: plikom samej bramki (łącznie z samymCODEOWNERS, promptami i szablonem pull requesta, bo GitHub stosujeCODEOWNERSz gałęzi bazowej, więc pull request, który go edytuje, mógłby inaczej bez review usunąć własnego właściciela), każdemu globowi zmin_risk: highoraz chronionym wyroczniom: testom akceptacyjnym lub kontraktowym, które kodują specyfikację, i konfiguracji typów oraz lintera dla całego repozytorium. To właśnie egzekwuje wierszhighw tabeli routingu dla tych ścieżek: wymagane review właściciela kodu obejmuje każdy pull request, który ich dotyka, niezależnie od etykiety.Nie dawaj właściciela każdej ścieżce
**/*.test.*ani snapshotom. Zwykłe testy zmieniają się w większości pull requestówstandard, więc objęcie ich własnością postawiłoby każdy z nich przed właścicielem kodu i zlikwidowało ścieżkę z jednym recenzentem. Takie zmiany nadal trafiają dorisk.oracle_changesi czyta je recenzentstandard. Jedno ograniczenie: zmianalooserw teście bez właściciela podnosi klasę dohigh, a etykietę dorisk:high, aleCODEOWNERSnie widzi etykiet, więc nic nie wymusza na niej właściciela kodu. Recenzent eskaluje ją ręcznie, a test, którego osłabienie byłoby kosztowne, powinien leżeć na chronionej ścieżce.# .github/CODEOWNERS.github/evidence-policy.yml @acme/platform.github/workflows/ @acme/platformscripts/check-evidence.mjs @acme/platform.github/CODEOWNERS @acme/platform.github/prompts/ @acme/platform.github/pull_request_template.md @acme/platform# Every min_risk: high glob in the policy**/auth/** @acme/security**/middleware/** @acme/security**/*permission* @acme/security**/billing/** @acme/payments**/payments/** @acme/payments**/pricing/** @acme/payments**/*.sql @acme/data**/openapi* @acme/data**/*.proto @acme/data**/migrations/** @acme/data# Protected oracles only: spec-level tests and repo-wide config**/*.contract.test.* @acme/platformtsconfig*.json @acme/platformeslint.config.* @acme/platform
Skąd wiesz, że sam skrypt sprawdzający działa?
Dział zatytułowany „Skąd wiesz, że sam skrypt sprawdzający działa?”Testuj bramkę tak jak każdą wyrocznię: fixture’ami, które muszą przejść, i fixture’ami, które muszą oblać. Zmienna EVIDENCE_CHANGED_FILES zastępuje git diff, więc fixture potrzebuje tylko sztucznego pliku zdarzenia i listy ścieżek:
# Terminal, repository root. ev-billing.json holds {"pull_request":{"base":{"sha":"x"},"body":"..."}}GITHUB_EVENT_PATH=fixtures/ev-billing.json \EVIDENCE_CHANGED_FILES=$'src/billing/refund.ts\nsrc/pages/orders.astro' \node scripts/check-evidence.mjs .github/evidence-policy.ymlUruchomiony na szablonie z góry, ze zmienionym plikiem płatności i stroną UI oraz z cytowanymi plikami specyfikacji i testu (docs/specs/orders-pagination.md, tests/orders.contract.test.ts) obecnymi w gałęzi, skrypt kończy się kodem 1 i trzema błędami: risk.touches pomija money, runtime jest puste oraz risk.class is standard, but the diff requires at least high. Trzymaj jeden fixture na każdą regułę (brak pakietu, niezweryfikowane kryterium, brak cytowanego pliku testu, niezadeklarowana zmiana wyroczni, zmiana wyroczni looser, brak ewaluacji) i uruchamiaj je w zwykłym jobie testowym. Zmiana bramki, która psuje fixture, zostanie wyłapana, zanim trafi do main.
Kto zatwierdza każdą klasę ryzyka?
Dział zatytułowany „Kto zatwierdza każdą klasę ryzyka?”Pakiet rozstrzyga, kto robi review i co czyta. Ta tabela to polityka na start; wersja dla całej organizacji należy do polityki autonomii i klas ryzyka.
| Klasa ryzyka | Typowy wyzwalacz | Zatwierdzenie | Kto czyta kod | Po merge’u |
|---|---|---|---|---|
low | Dokumentacja, teksty, izolowany UI z dowodami z działania, bez zmian wyroczni | Jeden recenzent na podstawie pakietu albo reguła zatwierdzania (zob. zakładkę Cursor) | Domyślnie nikt; próbkowanie według dziennika zaufania | Zwykły deploy |
standard | Zmiana zachowania w pokrytym kodzie; zmiany wyroczni stricter lub neutral; infrastruktura | Jeden recenzent na podstawie pakietu plus ustalenia agenta recenzującego | Recenzent czyta zmiany wyroczni i każde zachowanie z unrequested | Canary lub flaga, jeśli są dostępne |
high | Uwierzytelnianie, pieniądze, schematy, migracje, zmiana wyroczni looser | Właściciel kodu z CODEOWNERS | Wskazany właściciel czyta kod, oprócz pakietu | Stopniowe wdrożenie i bramka zatwierdzenia produkcyjnego |
Ścieżki wpisane do CODEOWNERS (pliki samej bramki, wrażliwe globy i chronione wyrocznie) wymagają swojego właściciela kodu niezależnie od klasy. Zmiana zwykłego testu lub snapshotu w kierunku stricter albo neutral zostaje na ścieżce z jednym recenzentem; zmiana looser dostaje etykietę risk:high, a recenzent musi ręcznie przekazać ją właścicielowi kodu, bo CODEOWNERS nie widzi etykiet.
standard odpowiada klasie medium w polityce organizacji; zmiany critical to tutaj high plus bramka zatwierdzenia produkcyjnego.
Przy low i standard zadaniem recenzenta jest przeczytanie pakietu w kolejności: zmiana specyfikacji, linie akceptacji, zmiany wyroczni, dowody z działania. Kolejność czytania i klasy eskalacji opisuje czytanie dowodów zamiast kodu, a protokół triage’u — code review PR-a agenta.
Jak Claude Code, Codex i Cursor przygotowują pakiet?
Dział zatytułowany „Jak Claude Code, Codex i Cursor przygotowują pakiet?”Format pakietu i check w CI są identyczne dla wszystkich trzech narzędzi. Różni się miejsce, w którym agent działa, gdy wypełnia pakiet. W każdym narzędziu najpierw dodaj ten fragment do pliku instrukcji, który agent czyta (CLAUDE.md w Claude Code, AGENTS.md w Codeksie, reguła projektu w Cursorze):
## Pull requestsEvery pull request body contains the evidence bundle from.github/pull_request_template.md. Run every check you cite and paste real exitcodes. Never mark a criterion `pass` without running its check. List everytest, snapshot, CI or lint file you changed under risk.oracle_changes. Neveredit .github/evidence-policy.yml or scripts/check-evidence.mjs.Z terminala, na własnej gałęzi funkcji, uruchom prompt do pakietu w trybie headless i otwórz pull request z jego wynikiem. dontAsk z dokładną allowlistą to udokumentowany wzorzec dla przebiegów bez nadzoru: wszystko spoza listy zostaje odrzucone, zamiast czekać na potwierdzenie:
# Terminal, feature branch checked out (Claude Code 2.1.283, `latest` channel)claude -p "$(cat .github/prompts/evidence-bundle.md)" --permission-mode dontAsk \ --allowedTools "Read,Grep,Glob,Bash(git diff:*),Bash(git log:*),Bash(npm test:*),Bash(npx stryker run:*)" \ > pr-body.mdgh pr create --title "Cursor pagination for GET /orders" --body-file pr-body.mdW GitHub Actions anthropics/claude-code-action@v1 przyjmuje --json-schema w claude_args i udostępnia zwalidowany wynik jako wyjście kroku structured_output. Przydaje się, gdy chcesz mieć pakiet jako dane, a nie jako komentarz. W CI na gałęzi, której nie ufasz, dodaj --bare --setting-sources "" --strict-mcp-config i nie przekazuj żadnych sekretów poza kluczem API.
Claude Code może dodawać atrybucję do commitów i pull requestów; zostaw ją włączoną: to darmowy zapis pochodzenia, zgodny z polem provenance.agent w pakiecie.
codex exec uruchamia ten sam prompt nieinteraktywnie. -o zapisuje ostatnią wiadomość agenta do pliku, który staje się treścią pull requesta:
# Terminal, feature branch checked out (Codex CLI 0.157.1)codex exec -c default_permissions=":workspace" \ -o pr-body.md "$(cat .github/prompts/evidence-bundle.md)"gh pr create --title "Cursor pagination for GET /orders" --body-file pr-body.mdProfil uprawnień :workspace (beta) pozwala przebiegowi uruchamiać testy wewnątrz repozytorium. Jeśli chcesz drugiej opinii przed otwarciem pull requesta, masz dwa osobne polecenia, bo codex exec review odrzuca --base razem z własnymi instrukcjami (sprawdzone w Codex CLI 0.157.1):
# Plain branch review against main, no custom instructionscodex exec review --base main
# The audit prompt below, saved as .github/prompts/evidence-audit.mdcodex exec -c default_permissions=":read-only" \ -o audit.md "$(cat .github/prompts/evidence-audit.md)"W profilu :read-only audyt może otwierać pliki, ale może nie móc ponownie uruchomić testów, które zapisują na dysk; jeśli chcesz ponownych uruchomień, użyj :workspace.
W CI polecenie codex exec uruchamia openai/codex-action@v1; zob. GitHub Action dla Codeksa.
Wklej prompt do pakietu do agenta przed otwarciem pull requesta i użyj jego wyniku jako opisu. Umieść blok instrukcji z góry w regule projektu, żeby Cloud Agents stosowały go w pull requestach, które otwierają.
Na pull requeście Bugbot według Cursora przegląda pull requesty i wykrywa błędy, problemy bezpieczeństwa i jakości kodu, a PR Routing & Approval przydziela recenzentów na podstawie własności kodu i historii commitów oraz może zatwierdzać pull requesty niskiego ryzyka, gdy spełnione są twoje kryteria (opisy produktów na cursor.com, sprawdzone 2026-08-28). Zapisz te kryteria tak, by odpowiadały wierszowi low w tabeli routingu, a zanim oprzesz się na etykietach risk:*, sprawdź w dokumentacji Cursora, jakie sygnały kryteria potrafią odczytać. Zob. Rollouts oraz PR Routing & Approval w Cursorze.
Dowody z działania zbierzesz skillem agent-browser: każdy z trzech agentów może nim sterować działającą aplikacją i zapisywać zrzuty ekranu. Zainstaluj CLI poleceniem npm install -g agent-browser && agent-browser install, a skill poleceniem npx skills add vercel-labs/agent-browser (flagi dla poszczególnych agentów i przypinanie wersji opisuje podlinkowana strona). Wgraj zrzuty jako artefakty workflow i podaj URL artefaktu w runtime.ref.
Prompty do skopiowania dla pakietu dowodów
Dział zatytułowany „Prompty do skopiowania dla pakietu dowodów”Zapisz pierwszy prompt jako .github/prompts/evidence-bundle.md, żeby polecenia powyżej mogły go wczytać.
Co się psuje, gdy wymuszasz pakiet dowodów?
Dział zatytułowany „Co się psuje, gdy wymuszasz pakiet dowodów?”Check nie znajduje skryptu przy pierwszym pull requeście. Workflow czyta scripts/check-evidence.mjs z commita bazowego, a w pull requeście, który go dodaje, baza jeszcze go nie ma. Wyjście: najpierw scal pięć plików bez wymaganego checka, potem dodaj wymagany check do rulesetu.
Pakiet podaje pass dla sprawdzeń, które nigdy się nie wykonały. Agent wkleja wiarygodnie wyglądające kody wyjścia. Wyjście: trzymaj prawdziwe joby testowe jako osobne wymagane checki, żeby sekcja checks była deklaracją, którą CI potwierdza niezależnie. Dodaj prompt audytowy jako krok agenta recenzującego dla pull requestów standard i high, a sprzeczny pakiet traktuj jak oblane review.
Linie akceptacji cytują testy, które nie testują kryterium. tests/orders.test.ts:1 istnieje i przechodzi, ale nie dowodzi niczego o paginacji. Skrypt widzi, że plik istnieje, a nie co sprawdza. Wyjście: przy zmianach standard recenzent otwiera każdą cytowaną linię, a miary siły wyroczni, takie jak wynik testów mutacyjnych na zmienionych plikach, trafiają do checks.
Agent osłabia test i nazywa to neutral. Skrypt ufa zadeklarowanemu kierunkowi. Wyjście: umieść testy kodujące specyfikację na chronionej ścieżce z właścicielem w CODEOWNERS, niech recenzent standard porówna zadeklarowany kierunek każdej innej zmiany wyroczni z jej diffem, a ochrona wyroczni pokazuje hooki, które w ogóle nie pozwalają agentowi edytować testów.
Globy polityki rozjeżdżają się z kodem. Nowy katalog src/checkout/ obsługuje pieniądze, ale nie pasuje do żadnego globu, więc zmiany w płatnościach przechodzą jako low. Wyjście: przeglądaj .github/evidence-policy.yml przy każdym nowym katalogu najwyższego poziomu i dodaj fixture dla każdego wrażliwego katalogu, żeby zmiana nazwy oblała test fixture’ów.
Każdy pull request staje się high. Jeśli globy polityki obejmują pół repozytorium, pakiet kieruje wszystko do właścicieli kodu i wracasz do czytania każdego diffa. Wyjście: zawęź globy do kodu, w którym błąd jest drogi i późno wykrywany, a resztę przenieś do standard z dowodami z działania.
Etykiety nie działają w pull requestach z forków. GITHUB_TOKEN w zdarzeniu pull_request z forka ma tylko prawo odczytu, więc gh pr edit się nie powiedzie. Wyjście: uruchamiaj agentów na gałęziach w tym samym repozytorium albo pomiń krok etykietowania dla forków i kieruj zmiany na podstawie wyniku checka.
Pakiet staje się formalnością wypełnianą ręcznie. Wyjście: śledź jedną liczbę na zespół, kompletność dowodów: scalone pull requesty, których pakiet przeszedł check za pierwszym podejściem, podzielone przez wszystkie scalone pull requesty, miesięcznie. Spadający trend oznacza, że agenci albo ludzie zgadują. Definicja i wartości bazowe są w ramach metryk.
Dokąd dalej po pakiecie dowodów
Dział zatytułowany „Dokąd dalej po pakiecie dowodów”Najczęstsze pytania
Czym jest pakiet dowodów?
Ustrukturyzowanym blokiem w pull requeście agenta, który podaje link do specyfikacji i zmianę zachowania, przypisuje każdemu kryterium akceptacji sprawdzenie, które się wykonało, wymienia polecenia i ich kody wyjścia, linkuje zrzuty ekranu, ślady lub ewaluacje, deklaruje klasę ryzyka, wrażliwe ścieżki i zmiany wyroczni oraz zapisuje pochodzenie zmiany. CI parsuje go i oblewa pull request, gdy pakiet jest niekompletny.
Po co CI przelicza pola, które agent już zadeklarował?
Bo pakiet napisał agent. CI wyznacza zmienione pliki, wrażliwe ścieżki i edytowane testy z samego diffa, a potem oblewa pakiet wszędzie tam, gdzie deklaracja jest uboższa niż diff. Zadeklarowana klasa ryzyka może podnieść próg wyliczony przez CI, nigdy go obniżyć.
Czy pakiet dowodów zastępuje code review?
Nie. Zmienia to, co recenzent czyta najpierw, i rozstrzyga, kto musi czytać kod. Zmiany o ryzyku low i standard są zatwierdzane na podstawie pakietu. CODEOWNERS wymusza, by zmiany w uwierzytelnianiu, pieniądzach, schematach, migracjach i chronionych wyroczniach czytał wskazany właściciel kodu; osłabiony zwykły test też ma ryzyko high, a recenzent ręcznie przekazuje go właścicielowi kodu.
Czy pakiet dotyczy tylko zmian pisanych przez agentów?
Nie. Ten sam pakiet i ten sam routing obowiązują zmiany ludzi, zmiany wspierane przez AI i zmiany agentów. Pochodzenie zapisuje się do pomiarów i audytu, nigdy nie służy jako sygnał ryzyka.