docs(spec): tighten implementation review execution contract
This commit is contained in:
@@ -187,25 +187,25 @@ Canonical body를 렌더링하기 전에 trusted workflow directory에 JSON obje
|
||||
## 절차
|
||||
|
||||
1. Exact target identifiers를 검증하고 `operations/repository-cache.md`를 새로 읽는다.
|
||||
2. Canonical path와 mode를 검증한 source Issue lock을 획득한다.
|
||||
2. Cache가 없으면 Issue lock 획득 전에 `gitea-repository-cache-bootstrap`으로 초기화한다. Bootstrap의 `bootstrap.lock → repository.lock`을 모두 역순으로 해제한 뒤 canonical path와 mode를 검증한 source Issue lock을 획득한다. 기존 cache의 path·ownership·permission이 invalid하면 자동 복구하지 않고 fail-closed한다.
|
||||
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을 획득한다.
|
||||
6. 검증된 기존 cache에 대해 `issue lock → repository lock` 순서로 repository lock을 획득한다. Issue lock 획득 후 cache가 없어졌거나 invalid해졌으면 bootstrap 또는 자동 복구하지 않고 중단한다.
|
||||
7. Cache path·ownership·permission·bare·remote를 검증하고 canonical base repository origin에서 prune/fetch한다. Gitea default branch SHA와 local ref를 일치시키고 PR base commit object가 cache에 존재하는지 검증한다.
|
||||
8. Same-repository PR이면 head object도 cache에서 검증하고 exact base-to-head tree를 Gitea changed-file set·diff와 대조한다. Fork PR이면 target cache에 head object가 있다고 가정하지 않고 authoritative head repository·branch SHA와 Gitea changed-file set·diff를 대조한다. 임의 ref, checkout, clone 또는 worktree를 만들지 않는다.
|
||||
9. Repository lock과 bootstrap lock을 획득한 경우 역순으로 해제하되 Issue lock은 유지한다.
|
||||
8. Same-repository PR이면 head object도 cache에서 검증하고 exact base-to-head tree를 Gitea changed-file set·diff와 대조한다. Fork PR이면 target cache에 head object가 있다고 가정하지 않고 authoritative head repository·branch SHA와 Gitea changed-file set·diff를 대조한다. Diff 직렬화의 byte 차이만으로 실패시키지 않고 변경 경로와 exact base/head blob 및 hunk가 동일 변경을 나타내는지 검증한다. 임의 ref, checkout, clone 또는 worktree를 만들지 않는다.
|
||||
9. Repository lock을 해제하되 Issue lock은 유지한다.
|
||||
10. Approved Discovery에서 acceptance matrix를 만들고 모든 changed file, 문서, source, test와 exact-head-bound status evidence를 대응시킨다.
|
||||
11. 독립 code-review worker 결과가 있으면 exact head에 바인딩됐고 authoritative하게 읽을 수 있을 때만 보조 evidence로 사용한다. 그 결과를 spec verdict로 그대로 복사하지 않는다.
|
||||
12. Verdict 규칙으로 하나의 strict result artifact와 canonical review body를 trusted workflow directory에 생성한다.
|
||||
13. Exact key/type, duplicate key, marker field, digest, deterministic correlation, criterion cardinality, path binding, verdict/state 조합, credential 부재와 render → parse → render byte equality를 검증한다.
|
||||
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. 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한다.
|
||||
16. Stable reviewer account ID, head, contract digest와 result digest가 모두 같은 canonical review가 정확히 하나 이미 있으면 exact review와 review comments를 authoritative하게 readback한다. Verdict-compatible 최종 state와 stale/dismissed 상태까지 검증된 경우에만 write 없는 no-op으로 종료한다. `PENDING`이면 완료나 새 create로 진행하지 않고 절차 19의 복구 조건을 적용한다. 같은 binding의 다른 결과 또는 중복 review가 있으면 fail-closed한다.
|
||||
17. 호출 전에 선택한 adapter의 실제 요청 schema와 endpoint별 성공 status를 검증하며 확인할 수 없으면 게시하지 않는다. Native review create를 `body=<canonical body>`, `comments=[]`, `commit_id=<exact head SHA>`와 명시적 verdict-compatible 요청 필드로 정확히 한 번 호출한다. MCP는 tool schema의 `state` 등 실제 인자를 사용하고, 직접 REST는 서버 schema의 `event=<APPROVED|REQUEST_CHANGES|COMMENT>`를 사용한다. MCP 인자를 REST payload에 복사하거나 모든 POST의 성공 status를 `201`로 가정하지 않는다. REST review endpoint의 `200` 등 확인된 성공 status만 인정하고 authoritative 응답의 `state`는 기존 verdict mapping과 exact-match해야 한다.
|
||||
18. Create 응답 성공만 신뢰하지 않는다. `get_review`, complete `get_reviews` pagination과 exact review의 `get_review_comments`를 다시 읽어 baseline 보존과 exact 대상 review record 하나(새 create면 신규 ID 하나, 기존 `PENDING` 복구면 같은 ID 유지), stable author account ID·body·state·commit·timestamp·stale/dismissed 상태 및 inline comment가 0개임을 검증한다. `PENDING`은 제출 완료가 아니며 절차 19의 복구 조건을 적용한다.
|
||||
19. Review create가 timeout·오류 또는 malformed response이면 blind retry하지 않는다. Complete review collection과 candidate review comments를 한 번 authoritative reconciliation해 baseline 대비 exact result가 하나이고 verdict-compatible 최종 state와 inline comment 부재가 확인될 때만 제출 완료로 판정한다. Exact owned `PENDING` review 하나가 확인되면 그 ID를 보존하고 partial publication으로 기록한다. 같은 review 제출이 승인된 경우에만, submit schema·성공 status 및 identity·Issue contract·PR base/head·changed files·review baseline·canonical body를 새로 검증하고(이미 인과가 증명된 해당 review의 파생 projection만 제외), 동일 ID를 명시적 verdict로 한 번 submit한 뒤 절차 18과 20의 readback을 적용한다. 새 create는 하지 않으며 submit 응답이 불확실하면 동일 ID를 authoritative readback해 최종 제출을 확인하거나 uncertain/partial로 중단한다. Candidate가 없거나 여러 개·경쟁 review·drift가 있으면 복구 write 없이 중단한다.
|
||||
20. Source Issue와 PR을 다시 읽는다. Body·title·state·labels·assignees·milestone·comments, PR base·head·changed files·merge state와 source content는 불변이어야 한다. 새 create는 baseline 대비 신규 review record가 정확히 하나여야 하고 기존 `PENDING` 복구는 추가 record 없이 같은 ID를 유지해야 하며, record 수와 timeline event 수를 구분한다. 단, Gitea가 exact native review create 또는 승인된 동일 ID submit의 파생 projection으로만 다음을 변경한 경우는 허용한다: Issue와 PR `updated_at`이 verified review `submitted_at` 또는 동일 review ID·author의 verified create/submit timeline event timestamp로 갱신됨, PR `review_comments`가 top-level review 생성으로 baseline보다 정확히 1 증가함(동일 ID submit 복구 시 추가 증가는 확인된 provider 계약과 해당 review timeline event로 인과가 증명된 경우에만 허용), `requested_reviewers`에 verified review author stable account ID가 정확히 추가됨. `submitted_at`이 draft 생성 시각을 유지할 수 있으므로 최종 state와 submit event를 별도로 검증한다. `comments: []` 계약은 projection count와 별개로 authoritative `get_review_comments`가 0개여야 한다. 이 파생 변경은 각 write 전후 snapshot과 exact review ID·author·timestamp로 인과를 증명해야 하며 다른 field 변경, 기존 reviewer 제거, 추가 account 또는 승인되지 않은 write call이 있으면 fail-closed한다. 검증된 submit은 별도 write로 기록하되 provider 파생 field 갱신을 직접 Issue/PR mutation으로 보고하지 않는다.
|
||||
21. 동일 state를 read-only replay해 stable deduplication identity의 canonical review를 재사용하며 `writes=[]`인지 확인한다.
|
||||
22. Issue lock을 해제한 뒤 `repository.lock`과 `issue-<number>.lock`을 각각 non-blocking으로 획득·해제할 수 있는지 확인한다.
|
||||
|
||||
@@ -213,7 +213,7 @@ Canonical body를 렌더링하기 전에 trusted workflow directory에 JSON obje
|
||||
|
||||
- Main spec-agent는 contract extraction, acceptance matrix, verdict와 외부 write에 책임을 진다.
|
||||
- Bounded diff 분할, criterion별 evidence 수집과 일반 코드 품질 검토는 독립 delegate에 병렬 위임할 수 있다.
|
||||
- Delegate에는 exact PR head, approved contract subset, changed-file allowlist와 read-only 범위를 제공한다.
|
||||
- Delegate에는 exact PR head, approved contract subset, changed-file allowlist와 read-only 범위를 제공한다. 적용되는 계약의 초기 작성·PR 생성 후 갱신 시점과 특정 구현 수단의 강제 여부를 함께 전달하며, 계약을 충족하는 구현 세부를 새로운 요구사항·범위 초과로 오인하지 않도록 한다.
|
||||
- Delegate가 Gitea write, source 수정, Git commit·push·merge, lock·cache·worktree 변경을 수행하지 못하게 한다.
|
||||
- Delegate summary는 evidence가 아니다. Main agent가 cited path, diff, status와 test evidence를 직접 확인한다.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user