--- name: gitea-code-review description: Spec pass된 Gitea PR의 코드 품질과 안전성을 검토한다. version: 0.1.3 author: genichin, Hermes Agent license: MIT platforms: [linux] metadata: hermes: tags: [gitea, review, security, testing] related_skills: [gitea-implementation-spec-review, gitea-issue-rework] --- # Gitea Code Review `구현 → spec pass → code review`의 독립 2차 리뷰를 수행한다. 승인된 요구사항을 바꾸거나 직접 구현하지 않고, 코드 결함과 검증 부족을 근거로 판정한다. ## Test inventory source-binding gate Baseline/current inventory를 생성·전달·채택할 때 `check-tests 이전`에 `harness/lib/test_inventory_binding.py`를 실행한다. Inventory의 자기 선언을 신뢰하지 않고 독립적으로 고정한 revision과 stage를 expected 입력으로 제공한다. Exact Git blob의 파일 존재·SHA-256 및 collection scope 결속을 [공통 source-binding 정본](../../../../operations/repository-cache.md#test-inventory-git-source-binding-preflight)에 따라 확인하고, 통과한 ID/source가 이후 구조 guard 입력과 같은지도 대조한다. 불일치 증빙을 채택하거나 현재 collection을 baseline으로 재명명하지 않는다. PASS가 named test의 존재·collection 실행·의미 보존을 인증하지는 않으며 main의 실제 실행 provenance 검토와 기존 revision evidence 영향 평가를 유지한다. 이 gate는 제품 실행·별도 checkout 권한이나 자동 제품 변경 요청을 추가하지 않는다. ## Managed-lock broker gate Bootstrap 이후 code review는 canonical [Repository cache 운영 지침](../../../../operations/repository-cache.md)의 공통 managed-lock broker 하나를 사용한다. Canonical Issue identity, role, workflow run-id와 TTL로 broker-generated runtime을 요청하고 ready JSON의 `handle`/`socket`을 사용한다. Runtime은 `/runtime//`이며 verification run-id와 독립적이다. Runtime 생성은 approval이나 worktree admission을 대신하지 않는다. Cache bootstrap 이후 broker가 Issue lock 아래 runtime을 준비하고, ready 이후 각 workflow의 진입 검증·승인 조건을 확인한다. Client는 raw token을 inspect/log하지 않으며 public `request` API가 token을 캡슐화한다. Nested repository lease는 같은 handle의 `acquire_repository`/`release_repository` request로만 관리하고 TTL 전에 `renew`한다. 정상·오류·cancel에서 repository release(보유 시) → Issue `release` → broker wait/reap → `probe` `free=true` 확인을 검증하기 전에는 완료·로그·보고하지 않는다. Raw `flock ... sleep`, lock-file unlink와 client-side lock holder는 금지한다. Native publication은 이 broker lease를 사용하며 adapter의 compatibility bridge는 canonical protocol을 우회하지 않는다. Reviewer의 persistent harness/.runtime repository-local storage는 role/workflow runtime 경로와 별개이며 이 예외를 유지한다. ## 사용 시점과 정본 - Exact `owner/repository`, source Issue와 PR을 지정해 코드 리뷰 또는 재리뷰를 요청받았을 때 사용한다. - 작업마다 `read_file`로 [Gitea access](../../../../operations/gitea-access.md)와 [Repository cache](../../../../operations/repository-cache.md)를 읽는다. 인증·경로·권한·잠금은 이 공통 지침을 따른다. - 현재 Issue의 승인된 Discovery가 계약 정본이다. 필요한 문서 규칙만 harness의 `docs/`에서 읽는다. - 구현, Discovery 수정, merge와 release에는 사용하지 않는다. ## 진입 조건 1. 식별자와 review role의 인증 출처·stable account ID를 검증한다. Impl 및 spec role과 다른 identity여야 하며 다른 role credential로 fallback하지 않는다. 2. PR이 open이고 source Issue에 exact `Closes #` 하나로 연결되며 default branch를 base로 하는지 확인한다. 3. 현재 계약 digest와 PR full head SHA에 결합된 spec-agent의 `approve/APPROVED` native review를 확인한다. Author, body binding, stale·dismissed 상태를 검증한다. 이전 head의 pass나 구현자의 pass 주장은 인정하지 않는다. 4. Issue 계약, PR base·head, 전체 changed files·diff·reviews·review comments와 CI/status를 snapshot으로 보존한다. Pagination 누락, truncated diff, 계약 모순 또는 identity 불명은 차단한다. 완료 조건: 현재 head와 계약에 대한 유효한 spec pass 및 완전한 리뷰 입력이 있다. 실패하면 read-only blocker를 보고하고 native review를 게시하지 않는다. ## 리뷰 관점 읽기 전용 위임과 최종 결과 채택에는 [공통 workflow guard 계약](../../../../operations/repository-cache.md#shared-workflow-guard-gates)을 적용한다. 사용이 허용된 source에서 위임 전 보호 범위를 snapshot하고 채택 전 compare-source를 완료한다. 최종 독립 검토 중 보호 범위 mutator를 병렬 실행하지 않는다. `check-tests --input JSON`으로 기존 ID·status·finding 연결을 확인하고 변경된 assertion·fixture·mock의 의미 검출력을 직접 검토한다. API·CLI·필드·상태·cleanup 보존과 실제 public-response 관찰을 대조한다. 기록은 제품 checkout 밖 허용된 정본 artifact에 보존하고 시작 baseline 누락·source drift이면 PASS를 채택하거나 자동 복구하지 않는다. 운영 근거 실패와 제품 finding을 구분한다. - **정확성·회귀:** 조건 분기, 경계값, 상태 전이, 데이터 처리와 기존 호출자에 대한 부작용. - **보안:** 인증·인가, 입력 검증, injection·경로 탈출, secret 노출, cookie·origin·proxy trust와 fail-closed/no-call/no-write 경계. - **동시성·복구:** race, 원자성, 잠금 순서, timeout·retry·중복 처리, 부분 실패와 자원 정리. - **테스트·근거:** 정상·실패·경계·회귀 검출력, mock의 한계, 실제 runtime 경로와 실행 provenance. - **성능·구조:** 과도한 I/O·반복 호출·무제한 자원 사용, 책임·의존 방향, dependency·lockfile·설치 설정과 문서 정합성. `terminal`로 Git diff를 확인하고 `read_file`로 모든 변경 파일과 필요한 주변 코드·테스트를 읽는다. 스타일 취향이나 승인 범위 밖의 기능을 필수 변경 요청으로 만들지 않는다. 계약 위반과 명세 자체의 결함을 구분한다. **위험·검증 matrix:** 실행 검증 전에 승인된 계약과 변경·영향 경계에서 위험·검증 matrix를 작성한다. 파일 목록을 완료 checklist로 대신하지 않는다. 각 행에는 다음을 기록하며, 검토 중 새로 확인한 중요한 경계는 추가한다. - **경계:** 관련 요구사항과 변경 로직·호출자. - **위험·기대 동작:** 무엇이 잘못될 수 있고 무엇을 보장해야 하는가. - **검증:** 필요한 정상·실패·경계·상태 전이 사례와 확인 방법. - **승인 전 필수 여부:** 승인 전에 확인해야 하는지와 그 이유. 승인된 계약과 위험 분석으로 정하며, 결과가 불편하다는 이유로 사후에 필수 여부를 낮추지 않는다. - **상태:** `통과 / 실패 / 미검증 / 비적용` 중 하나. - **근거:** 코드 위치, 테스트·probe 결과 또는 재사용 근거의 참조. 정적 확인, CI·구현자 실행, reviewer 직접 실행과 재사용 근거를 구분하고 reviewed head·계약에 대한 적용 가능성과 한계를 명시한다. `통과`는 기대 동작을 뒷받침하는 충분한 근거가 있음, `실패`는 기대 동작 위반이 확인됨, `미검증`은 미실행 또는 환경 오류·timeout 등으로 근거가 불충분함, `비적용`은 해당 경계가 적용되지 않는 구체적 이유가 있음을 뜻한다. 모든 행에 runtime test를 강제하지 않으며 위험에 따라 정적 확인이나 검증된 기존 근거를 사용할 수 있다. 환경·runner 오류를 제품 결함인 `실패`로 세지 않는다. ## 실행 검증과 기존 워크트리 사용 전체 테스트를 매번 재실행할 필요는 없다. Exact-head CI와 신뢰 가능한 실행 기록을 평가하고, 위험하거나 근거가 부족한 부분을 직접 검증한다. Command evidence에는 명령, exit code, 관련 출력, 환경과 source revision이 있어야 한다. 다른 revision의 기록은 전체 후속 diff와 실행 입력의 동일성을 증명한 경우에만 재사용하며 독립 실행과 구분한다. **영속 데이터의 의미적 호환성:** 변경이 지원 대상 구버전 데이터의 저장 형식·해석·조회·소비 동작에 영향을 줄 수 있으면, 프로젝트의 승인된 계약에서 지원 범위와 기대 동작을 먼저 식별한다. 승인된 migration은 동작을 의도적으로 바꿀 수 있으므로, 구버전 출력의 무조건적인 동일성이나 새로운 불변성·호환성 요구를 추가하지 않는다. 행·schema 보존만으로 동작 호환성을 인정하지 않는다. 검증에는 위험에 맞게 대표적인 구버전 데이터를 사용한다. 실제 구버전 API·CLI 생성 데이터, 출처가 검증된 기존 fixture 등에서 적절한 방법을 선택하고 source revision·환경·데이터 출처·대표성과 한계를 기록한다. 특정 생성 방법을 모든 프로젝트에 강제하지 않는다. 영향을 받는 조회·소비자의 결과를 승인된 기대 동작과 대조하고, 필요한 검증·근거와 통과·실패·미검증·비적용 상태를 위험·검증 matrix에 연결한다. 프로젝트별 도메인 규칙과 전용 fixture·회귀 테스트는 해당 프로젝트에 둔다. 별도 워크트리는 만들지 않는다. 기존 impl Issue 워크트리는 다음 조건을 모두 만족할 때 **검증 전용으로 대여**한다. 구현 재개가 아니므로 `state.json`의 `created_by_role`은 impl role로 확인·보존하고 review role로 바꾸지 않는다. 1. Workflow 동안 broker가 관리하는 exact Issue lease를 유지한다. Cache·registration 검증에는 같은 handle의 `acquire_repository` request를 사용하고, 테스트 전에 `release_repository` request를 보낸다. 2. Canonical path·권한·state identity·common Git directory·detached/locked registration을 검증한다. HEAD는 현재 PR head와 같고 미완료 Git operation과 tracked 변경이 없어야 한다. 3. Untracked 파일, dependency 환경과 설정이 검증을 오염시키지 않는지 확인한다. 설명할 수 없는 상태는 reset·clean·stash·checkout으로 복구하지 않고 중단한다. 4. Source·test·Git refs·state는 수정하지 않는다. 테스트 출력·fixture·DB는 격리된 임시 경로를 사용하고 운영 데이터·credential을 사용하지 않는다. 파일 수정이나 위험한 외부 쓰기가 필요한 명령은 실행하지 않는다. 5. 실행 전후 HEAD와 tracked/untracked 상태를 비교한다. 정상 종료 시 source에 영향을 줄 수 있는 실행 작업의 실제 종료를 확인하고, 유효한 Issue lease 아래 필요한 최종 HEAD·Git 상태·source digest 검증을 끝내어 기존 결과 artifact에 근거를 보존한 뒤 canonical broker cleanup(보유한 `release_repository` → `release` → tracked broker wait/reap → Issue `probe` `free=true`)을 수행한다. 최종 검증과 Issue `release`를 독립 병렬 작업으로 배치하지 않는다. 검증 실패·취소에서도 현재 실행이 만든 자원만 정리하고 cleanup을 시도하되 검증 성공이나 workflow 완료로 기록하지 않는다. Cleanup이 미확인이라는 이유로 완료한 검토·전체 테스트·Native POST를 자동 반복하지 않는다. 추가 자동 재시도 루프나 heartbeat를 도입하지 않고 기존 명령 timeout과 tracked process의 유한한 wait를 사용한다. Cleanup이 끝나지 않으면 기존 결과 artifact에 마지막 확인 단계와 미확인 원인을 남기고 workflow를 `partial`로 보고한다. 재개 시 이미 확인된 `release`를 다시 강제하지 않고, 보존된 근거와 현재 프로세스 상태를 대조하여 미완료 cleanup 확인만 수행한다. Issue probe `busy`만으로 현재 실행의 lock 누수를 단정하지 않으며, 현행 `free=true` 완료 조건은 유지한다. 정상 해제 뒤 terminal handle 상태가 `released`로 남아 있어야 한다는 조건을 추가하지 않는다. 재개가 source 검증이나 게시 작업으로 확장되면 기존 유효 lease·head·계약 검사를 다시 적용한다. 안전한 대여가 불가능하면 CI·기존 근거를 사용하고 직접 실행 불가 사유를 보고한다. 필수 검증 근거가 부족하면 승인하지 않는다. 독립성은 reviewer의 판단과 직접 확인에 있으며 별도 checkout 자체가 필수는 아니다. ## 판정과 기록 - `approve`: 전체 diff, 관련 코드·테스트와 필요한 실행 근거를 검토했고 미해결 중요 결함이나 필수 검증 공백이 없다. 승인 전 필수로 분류한 matrix 행은 모두 통과하거나 근거 있는 비적용이어야 한다. 필수 행에 실패·미검증 또는 설명 없는 비적용이 남으면 승인하지 않는다. 전체 파일 열람이나 전체 테스트 통과만으로 이 조건을 충족했다고 간주하지 않는다. 선택적 검증의 미완료는 한계로 보고하며 자동으로 변경 요청하지 않는다. - `request_changes`: 승인된 범위 안의 미해결 중요 결함 또는 승인에 필요한 필수 검증 공백이 있다. 경미한 비차단 결함·무관한 기존 기술부채·선택적 개선만으로는 변경 요청하지 않는다. - `blocked`: spec pass 부재·drift, 명세 모순 또는 안전한 검토를 막는 조건이 있다. 승인하지 않고 blocker를 보고한다. Finding마다 `F-001` 같은 ID, 파일·행, 발생 조건, 영향·심각도, 확인 근거, 계약과의 관계 및 제한된 수정·재검증 방향을 기록한다. 확정 결함, 질문, 잔여 위험과 비차단 제안은 분리한다. 위임 시 exact head·계약 subset·파일 범위와 read-only 조건을 주고, main reviewer가 중요 지적을 직접 검증하며 최종 판정을 책임진다. 결과는 checkout 밖의 trusted workflow artifact에 한국어로 보존한다. Target, reviewed head, contract digest, spec review ID, findings, 실행 결과·한계와 verdict를 포함한다. 기존 결과 artifact에 위험·검증 matrix와 미검증 범위를 포함하며 별도 파일은 필수가 아니다. 최종 findings 게시 전에 계획된 검토 결과와 판정에 필요한 worker 결과를 main reviewer가 대조·통합하고 각 행의 상태를 확정한다. 일부 검토가 중단됐다면 partial/blocked 범위를 명시하고 전체 검토 완료로 표현하지 않는다. SHA·path·명령은 원문을 유지하고 secret은 기록하지 않는다. ## Native review 게시와 재검토 게시 단계는 [공통 Native review adapter](references/native-review.md)와 canonical `scripts/native_review.py`의 검증된 API를 사용한다. 매 실행마다 gate·게시·검증 bootstrap을 다시 생성하거나 지원하지 않는 CLI·legacy JSON schema를 추정하지 않는다. 기존 role-authenticated transport와 현재 보유한 Issue lease를 연결하고, durable journal을 유지해 timeout·partial 이후에는 POST 재시도 없이 readback만 수행한다. `provider_contract`는 확인된 Gitea 자동 supersession/retouch 및 commit `files` 순서 변화만 제한적으로 허용하며 head·본문·기존 리뷰 내용을 비교에서 제외하지 않는다. Snapshot/plan schema, 실제 지원 interface 및 read-only replay와 live 게시의 차이는 참조 문서대로 확인한다. 1. Exact PR 리뷰 요청은 진입 조건을 충족한 native review 하나의 게시만 승인한다. 단순 조사·역할 보고 요청은 write를 승인하지 않는다. `approve → APPROVED`, `request_changes → REQUEST_CHANGES`로 매핑하고 `blocked`는 게시 없이 보고한다. 2. 게시 직전 Issue 계약, PR base·head, spec pass와 review baseline을 재확인한다. Drift면 중단한다. Body에는 결과 artifact의 요약과 아래 marker를 넣는다. `` 3. 같은 author·head·계약의 canonical review가 하나 있고 body·최종 state가 같으면 readback 후 write 없는 no-op으로 종료한다. 중복·상충 결과 또는 PENDING이면 추가 게시하지 않는다. 4. 실제 adapter schema를 확인하고 exact head의 `commit_id`, body, verdict-compatible state/event와 `comments: []`를 명시해 한 번 게시한다. Exact review와 complete collection을 다시 읽어 ID·author·body·head·state·stale/dismissed·inline comments 부재를 검증한다. Timeout·오류는 blind retry하지 않고 readback으로 조정하며 불확실하면 partial로 보고한다. 5. 게시 후 계약·PR head·source Issue 내용이 보존됐는지 확인한다. Native review에 인과가 확인되는 provider 파생 변경과 무관한 mutation을 구분한다. 검증 실패를 성공으로 보고하지 않는다. 6. 변경 요청은 기존 PR의 `gitea-issue-rework`로 전달한다. 새 head가 생성되면 **재작업 → 새 head의 spec pass → code 재리뷰**를 수행한다. 이전 지적과 근거는 활용하되 해결 여부·영향·회귀를 새 snapshot에서 확인한다. 동일 현재 head와 계약의 두 pass가 최종 승인 조건이며 merge 승인은 아니다. 재리뷰에서 새 차단 finding을 추가할 때는 계약·변경 경로와의 관계 및 이번 승인 전에 해결해야 하는 이유를 입증한다. 발견 시점이나 severity만으로 차단하지 않는다. ## 주의 및 완료 보고 - Source·test·Discovery 수정, commit·push·merge, Issue 변경, review dismiss, release·deployment를 하지 않는다. - PR의 성공 주장, delegate 요약, process exit 또는 native state만으로 완료를 주장하지 않는다. HTTP/framework test를 실제 browser 검증으로 표현하지 않는다. - 보고에는 exact target·head·contract·spec review ID, 검토 범위, findings·verdict, 실제 실행과 재사용 근거, 미검증 범위, native review ID/state/readback 또는 미게시 이유, cleanup·partial 상태를 포함한다. - clean review는 검토 범위에서 중요 결함을 발견하지 못했다는 의미이며 무결함의 증명은 아니다.