[verified] docs: harden Gitea access and release contracts

This commit is contained in:
2026-09-30 16:39:33 +09:00
parent c05b4226bf
commit c50440b81b
8 changed files with 191 additions and 61 deletions
@@ -1,7 +1,7 @@
---
name: gitea-implementation-spec-review
description: 승인된 계약에 대해 Gitea 구현 PR 적합성을 검토한다.
version: 0.1.0
version: 0.2.0
author: genichin, Hermes Agent
license: MIT
platforms: [linux]
@@ -13,7 +13,7 @@ metadata:
# Gitea Implementation Specification Review
`gitea-impl-agent`가 만든 Gitea PR을 승인된 Discovery 계약과 대조해 요구사항 충족, 범위 누락·초과, acceptance criteria와 test evidence의 대응을 판정한다. 검토 결과는 구현 branch의 Git commit이나 Issue comment가 아니라 검토한 immutable PR head commit에 바인딩된 native Gitea review로 기록한다. 일반 코드 품질·보안 검토, source 수정, Discovery 변경과 merge는 수행하지 않는다.
`gitea-impl-agent`가 만든 Gitea PR을 승인된 Discovery 계약과 대조해 요구사항 충족, 범위 누락·초과, acceptance criteria와 test evidence의 대응을 판정한다. 검토 결과는 구현 branch의 Git commit이나 Issue comment가 아니라 검토한 immutable PR head commit에 바인딩된 native Gitea review로 기록한다. Gitea 인증과 readback은 [Gitea authenticated access 운영 지침](../../../../operations/gitea-access.md)을 정본으로 사용한다. 일반 코드 품질·보안 검토, source 수정, Discovery 변경과 merge는 수행하지 않는다.
## 사용 시점
@@ -38,15 +38,15 @@ Issue comment·body·title·state·label·assignee·milestone, repository file,
- 일반적인 코드 스타일, 광범위한 보안 탐색, 성능 최적화와 유지보수성은 독립 code-review worker의 책임이다. 다만 계약 위반으로 이어지는 논리·보안 문제는 spec finding으로 다룬다.
- 구현 결함과 명세 결함을 분리한다. 명확한 계약 위반은 `request_changes`, 계약 자체의 모순·누락 때문에 판정할 수 없으면 `blocked_spec`이다.
- Review worker를 위임하더라도 main spec-agent가 authoritative evidence, 최종 verdict, native review write와 readback에 책임을 진다.
- Native review는 spec-agent 전용 Gitea MCP connection으로만 작성한다. 해당 connection의 `get_me` stable account ID를 snapshot에 기록하고 ambient REST token, impl-agent credential 또는 다른 profile credential로 fallback하지 않는다.
- 전용 MCP connection이나 expected stable account identity를 검증할 수 없으면 read-only 분석과 native review write를 모두 완료로 보고하지 않는다.
- Native review는 spec-agent 전용 authenticated Gitea API adapter로만 작성한다. MCP connection 또는 spec-agent role token을 사용하는 직접 REST client의 stable account ID와 credential provenance를 snapshot에 기록하고 ambient token, impl-agent credential 또는 다른 profile credential로 fallback하지 않는다.
- 전용 adapter나 expected stable account identity를 검증할 수 없으면 read-only 분석과 native review write를 모두 완료로 보고하지 않는다.
## 입력 승인 gate
다음 조건을 모두 충족하지 않으면 native review를 작성하지 않는다.
- `owner`, `repository`, Issue 번호와 PR 번호가 각각 안전한 canonical identifier다.
- Gitea MCP `get_me`로 확인한 stable account ID가 spec review role이며 PR author·implementation role의 stable account ID와 다르다. Transport별 login 표시가 달라도 account ID가 같으면 같은 identity로 판정한다.
- Authenticated adapter로 확인한 stable account ID가 spec review role이며 PR author·implementation role의 stable account ID와 다르다. Transport별 login 표시가 달라도 account ID가 같으면 같은 identity로 판정한다.
- PR이 open이고 exact target repository의 default branch를 base로 하며 head repository·branch와 40자리 full head SHA를 authoritative하게 식별할 수 있다. Fork PR이면 head repository metadata와 branch SHA를 별도로 읽어 PR head와 일치시킨다.
- PR body에 source Issue와 결합되는 exact `Closes #<issue-number>`가 하나만 있고 다른 close directive가 없다.
- Source Issue body 첫 줄이 exact `<!-- gitea-agent:discovery-draft/v2 -->`이며 canonical H2 구조를 만족한다.
@@ -188,7 +188,7 @@ Canonical body를 렌더링하기 전에 trusted workflow directory에 JSON obje
1. Exact target identifiers를 검증하고 `operations/repository-cache.md`를 새로 읽는다.
2. Canonical path와 mode를 검증한 source Issue lock을 획득한다.
3. Gitea MCP `get_me`로 spec-agent stable account ID를 확인하고 PR author와 분리됐는지 검증한다.
3. Canonical authenticated Gitea API adapter로 spec-agent stable account ID를 확인하고 PR author와 분리됐는지 검증한다.
4. Exact repository metadata, default branch, source Issue 전체 필드·comments, PR details·head commit·status·changed files·diff와 전체 review baseline을 읽는다. Fork PR이면 exact head repository metadata와 head branch SHA도 읽는다.
5. 입력 승인 gate를 적용하고 Issue contract snapshot, PR snapshot, `contract-sha256`, initial head SHA를 고정한다.
6. Cache가 없으면 Issue lock을 유지한 채 `gitea-repository-cache-bootstrap`을 적용해 `issue lock → bootstrap lock → repository lock` 순서를 지킨다. 기존 cache면 `issue lock → repository lock` 순서로 repository lock을 획득한다.
@@ -202,7 +202,7 @@ Canonical body를 렌더링하기 전에 trusted workflow directory에 JSON obje
14. 여기까지는 read-only preflight다. Exact review 요청이 native review write 권한을 부여하지 않았거나 preflight가 완전하지 않으면 종료하며 review create 또는 다른 mutation을 수행하지 않는다.
15. Write 직전에 Issue 전체 필드·comments, PR details·base·head·changed files와 전체 review baseline을 다시 읽는다. Contract snapshot, base target, head SHA, changed-file set 또는 baseline이 drift하면 native review를 쓰지 않는다.
16. Stable reviewer account ID, head, contract digest와 result digest가 모두 같은 canonical review가 정확히 하나 이미 있으면 exact review와 review comments를 authoritative하게 readback하고 write 없는 no-op으로 종료한다. 같은 binding의 다른 결과 또는 중복 review가 있으면 fail-closed한다.
17. Gitea MCP `pull_request_review_write(method=create)`를 `body=<canonical body>`, `comments=[]`, `commit_id=<exact head SHA>`, `state=<APPROVED|REQUEST_CHANGES|COMMENT>`로 정확히 한 번 호출한다. `state`는 verdict mapping과 exact-match해야 한다.
17. Authenticated adapter의 native review create operation을 `body=<canonical body>`, `comments=[]`, `commit_id=<exact head SHA>`, `state=<APPROVED|REQUEST_CHANGES|COMMENT>`로 정확히 한 번 호출한다. MCP는 동등한 review-create method를, 직접 REST는 exact target PR의 review create endpoint를 사용하며 `state`는 verdict mapping과 exact-match해야 한다.
18. Create 응답 성공만 신뢰하지 않는다. `get_review`, complete `get_reviews` pagination과 exact review의 `get_review_comments`를 다시 읽어 baseline 보존과 exact 신규 review 하나, stable author account ID·body·state·commit·timestamp·stale/dismissed 상태 및 inline comment가 0개임을 검증한다.
19. Review create가 timeout·오류 또는 malformed response이면 blind retry하지 않는다. Complete review collection과 candidate review comments를 한 번 authoritative reconciliation해 baseline 대비 exact result가 하나이고 inline comment가 없을 때만 committed로 판정한다. 없거나 여러 개·경쟁 review가 있으면 uncertain/partial로 중단한다.
20. Source Issue와 PR을 다시 읽는다. Body·title·state·labels·assignees·milestone·comments, PR base·head·changed files·merge state와 source content는 불변이어야 한다. 단, Gitea가 exact native review 생성의 파생 projection으로만 다음을 변경한 경우는 허용하고 별도 mutation으로 보고하지 않는다: Issue와 PR `updated_at`이 verified review `submitted_at`으로 갱신됨, PR `review_comments`가 top-level review를 포함해 baseline보다 정확히 1 증가함, `requested_reviewers`에 verified review author stable account ID가 정확히 추가됨. `comments: []` 계약은 이 projection count와 별개로 authoritative `get_review_comments`가 0개여야 한다. 이 세 파생 변경은 create 전후 snapshot과 exact review ID·author·timestamp로 인과를 증명해야 하며 다른 field 변경, 기존 reviewer 제거, 추가 account 또는 별도 write call이 있으면 fail-closed한다.