Add shared managed lock broker
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: gitea-implementation-spec-review
|
||||
description: 승인된 계약에 대해 Gitea 구현 PR 적합성을 검토한다.
|
||||
version: 0.2.2
|
||||
version: 0.2.3
|
||||
author: genichin, Hermes Agent
|
||||
license: MIT
|
||||
platforms: [linux]
|
||||
@@ -15,6 +15,11 @@ metadata:
|
||||
|
||||
`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는 수행하지 않는다.
|
||||
|
||||
|
||||
## Managed-lock broker gate
|
||||
|
||||
Cache와 Issue workflow의 lock은 canonical [Repository cache 운영 지침](../../../../operations/repository-cache.md)을 따른다. Bootstrap 이후에는 role-neutral broker 하나를 `serve`로 tracked background process로 시작하고 ready JSON을 기다린다. Checkout 밖 role-owned mode `0700` runtime directory와 unique handle/socket을 pre-create하며 client는 raw token을 inspect/log하지 않고 public `request` API가 이를 캡슐화한다. Nested repository lock은 같은 handle의 `acquire_repository`/`release_repository` request만 사용하고 TTL 전에 `renew`한다. 정상·no-op·검증 실패·API 오류·cancel을 포함한 모든 종료 경로는 `release_repository`(보유 시) → `release` → wait/reap → `probe`에서 `free=true` 확인을 거쳐야 하며, 그 전에는 completed/log/report를 주장하지 않는다. Raw `flock ... sleep`과 lock-file unlink는 금지한다.
|
||||
|
||||
## 사용 시점
|
||||
|
||||
다음과 같이 exact repository, source Issue와 PR을 지정해 구현 적합성 검토를 요청받았을 때 사용한다.
|
||||
@@ -211,15 +216,15 @@ terminal(command="python3 harness/agents/spec/skills/gitea-implementation-spec-r
|
||||
## 절차
|
||||
|
||||
1. Exact target identifiers를 검증하고 `operations/repository-cache.md`를 새로 읽는다.
|
||||
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한다.
|
||||
2. Cache가 없으면 broker Issue lease를 확인하기 전에 `gitea-repository-cache-bootstrap`으로 초기화한다. Bootstrap의 `bootstrap.lock → repository.lock`을 모두 역순으로 해제한 뒤 canonical path와 mode를 검증하고 broker `serve`의 ready 응답 및 public `request` API로 source Issue lease를 확인한다. 기존 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를 고정한다.
|
||||
실행 helper는 directory 종류별 canonical permission 계약과 authenticated repository metadata의 exact `clone_url`을 사용하며 bare directory에 임의 `0700` 조건을 추가하거나 `.git`을 제거하지 않는다. Close binding은 행 단위로 파싱하고 whitespace가 다음 행까지 매칭되지 않게 한다. Commit metadata의 실제 nested 필드와 collection의 declared count를 검증하며 `null` collection은 해당 wire 계약과 count가 empty를 증명할 때만 빈 배열로 처리한다. Hunk는 immutable base/head blob의 위치·내용으로 대조한다. 검증된 helper가 있으면 재사용하고, 임의 wire shape·문자열 재구성·diff 직렬화 일치로 gate를 대체하지 않는다.
|
||||
6. 검증된 기존 cache에 대해 `issue lock → repository lock` 순서로 repository lock을 획득한다. Issue lock 획득 후 cache가 없어졌거나 invalid해졌으면 bootstrap 또는 자동 복구하지 않고 중단한다.
|
||||
6. 검증된 기존 cache에 대해 Issue lease를 유지한 채 같은 broker handle로 `acquire_repository` request를 보낸다. Issue lease 확인 후 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를 대조한다. Diff 직렬화의 byte 차이만으로 실패시키지 않고 변경 경로와 exact base/head blob 및 hunk가 동일 변경을 나타내는지 검증한다. 임의 ref, checkout, clone 또는 worktree를 만들지 않는다.
|
||||
9. Repository lock을 해제하되 Issue lock은 유지한다.
|
||||
9. `release_repository` request를 보내되 Issue lease는 유지한다.
|
||||
10. Acceptance matrix 작성 전에 구현자 실행 보고와 상세 실행 기록의 출처 및 확인 범위를 구분한다. Revision이 식별된 기존 evidence는 source revision과 reviewed head 사이 전체 diff·실행 입력 변경을 확인하고, 필수 검증별 재사용 가능 범위와 현재 head에 새로 결합해야 할 근거를 먼저 요약한다. 상세 기록이나 revision 정보의 부재만으로 새 검증 gate를 만들지 않는다. 재사용 여부는 위 Acceptance matrix의 기존 evidence binding 기준으로 판단하며 새 gate나 일괄 재실행 요구를 추가하지 않는다. 재검토에서는 이전 finding별 승인 계약 근거와 최소 보완 요청을 새 구현·evidence의 확인 위치에 대응하고, 해소 또는 잔여 사유를 기존 criterion의 `evidence`와 `reason`에 기록한다. 이미 충족된 검증을 source revision 차이만으로 다시 요구하지 않되, 변경 영향으로 새로 판정할 수 없어진 필수 조건은 그 근거와 최소 보완 범위를 특정한다. 이 초기 요약만으로 검토를 끝내지 않고 Approved Discovery에서 acceptance matrix를 만들고 모든 changed file, 문서, source, test와 exact-head-bound status evidence를 대응시킨다.
|
||||
11. 문서 검토 입력과 구조·의미 분리 절차로 trusted 계약·산출물별 의무표를 준비하고 모든 문서 의무를 대조한다. 위임 시 해당 입력 전체를 제공한다. 독립 code-review worker 결과가 있으면 exact head에 바인딩됐고 authoritative하게 읽을 수 있을 때만 보조 evidence로 사용한다. 그 결과를 spec verdict로 그대로 복사하지 않는다.
|
||||
12. Verdict 규칙으로 하나의 strict result artifact와 canonical review body를 trusted workflow directory에 생성한다.
|
||||
@@ -236,9 +241,9 @@ terminal(command="python3 harness/agents/spec/skills/gitea-implementation-spec-r
|
||||
기존 review 대체 projection은 write 전에 authoritative provider 계약으로 대체 조건·대상·필드를 확인해 기록한 경우에만 허용한다. 동일 PR·동일 stable author의 baseline상 `official=true`, `dismissed=false`인 이전 review에서 `official: true→false`, `dismissed: false→true`, 해당 native create/submit event 시각으로의 `updated_at` 변경만 허용하며, 영향받은 모든 ID를 읽어 기존 ID·body·commit·state·author·stale와 나머지 필드 및 record 보존을 검증한다. 신규 review/event cardinality와 해당 write의 인과도 별도로 확인한다. Timestamp 일치나 과거 관측만으로 대체를 추정하지 않으며 다른 작성자·다른 필드 변경, 계약 미확인 또는 인과 불명은 `partial`/fail-closed로 기록하고 추가 write를 중단한다. 기존 flag를 직접 복원·dismiss하거나 과거 실행 결과를 소급 성공으로 바꾸지 않는다.
|
||||
별도로, 동일 PR·동일 stable author의 baseline상 이미 `dismissed=true`인 이전 approve/reject review는 서버 버전에 결합된 authoritative provider 계약으로 bulk-update 대상과 timestamp 동작을 write 전에 확인한 경우에만 해당 native create/submit event에 인과가 증명된 `updated_at` 갱신만 허용한다. 기존 `official`·`dismissed` 값과 ID·body·commit·state·author·stale 및 모든 나머지 필드·record는 그대로 보존하고 영향받은 모든 ID와 신규 review/event cardinality를 readback한다. Timestamp 일치만으로 인과를 추정하지 않으며 계약·인과가 미확인되면 write 전 차단하거나 write 후 `partial`/fail-closed로 중단한다.
|
||||
21. 동일 state를 read-only replay해 stable deduplication identity의 canonical review를 재사용하며 `writes=[]`인지 확인한다.
|
||||
22. Issue lock을 해제한 뒤 `repository.lock`과 `issue-<number>.lock`을 각각 non-blocking으로 획득·해제할 수 있는지 확인한다.
|
||||
22. Issue lease에 대해 `release_repository`(보유 시) → `release` request를 보내고 tracked broker process를 wait/reap한 뒤 `probe --resource issue` 응답의 `free=true`를 확인한다. Raw lock 파일이나 token을 직접 재획득·검사하지 않는다.
|
||||
|
||||
모든 종료 경로(정상·no-op·검증 실패·API 오류·예외)는 획득한 lock을 `finally`에서 역순 해제하고 non-blocking 재획득·해제를 확인한다. Write 후 응답과 authoritative readback snapshot은 판정 assertion 전에 credential 없이 먼저 보존하고, 검증 실패 사유는 별도로 기록한다. 불확실한 POST는 절차 19만 적용하고 후속 write를 중단한다. 종료 시 final report를 authoritative 결과로 확정하며 native review 제출 상태와 절차 전체 상태를 분리한다. Progress artifact를 사용했다면 최종 상태·review ID·잔여 오류를 갱신하거나 stage·timestamp·final report 참조를 갖춘 중간 snapshot임을 명시한다. Cleanup 실패도 final report에 남기고 완료로 보고하지 않는다.
|
||||
모든 종료 경로(정상·no-op·검증 실패·API 오류·예외·cancel)는 canonical broker cleanup을 `finally`에서 수행한다: 보유한 `release_repository`, `release`, tracked broker wait/reap, `probe`의 `free=true` readback 순서를 확인한다. Write 후 응답과 authoritative readback snapshot은 판정 assertion 전에 credential 없이 먼저 보존하고, 검증 실패 사유는 별도로 기록한다. 불확실한 POST는 절차 19만 적용하고 후속 write를 중단한다. 종료 시 final report를 authoritative 결과로 확정하며 native review 제출 상태와 절차 전체 상태를 분리한다. Progress artifact를 사용했다면 최종 상태·review ID·잔여 오류를 갱신하거나 stage·timestamp·final report 참조를 갖춘 중간 snapshot임을 명시한다. Cleanup 실패도 final report에 남기고 완료로 보고하지 않는다.
|
||||
|
||||
## 문서 검토 입력과 구조·의미 분리
|
||||
|
||||
|
||||
Reference in New Issue
Block a user