[verified] Define fail-closed worktree creator-role compatibility

This commit is contained in:
2026-10-12 02:10:37 +00:00
parent 2ad836f332
commit aeab04289d
5 changed files with 62 additions and 4 deletions
@@ -77,7 +77,7 @@ Bootstrap 이후 code review는 canonical [Repository cache 운영 지침](../..
검증에는 위험에 맞게 대표적인 구버전 데이터를 사용한다. 실제 구버전 API·CLI 생성 데이터, 출처가 검증된 기존 fixture 등에서 적절한 방법을 선택하고 source revision·환경·데이터 출처·대표성과 한계를 기록한다. 특정 생성 방법을 모든 프로젝트에 강제하지 않는다. 영향을 받는 조회·소비자의 결과를 승인된 기대 동작과 대조하고, 필요한 검증·근거와 통과·실패·미검증·비적용 상태를 위험·검증 matrix에 연결한다. 프로젝트별 도메인 규칙과 전용 fixture·회귀 테스트는 해당 프로젝트에 둔다.
별도 워크트리는 만들지 않는다. 기존 impl Issue 워크트리는 다음 조건을 모두 만족할 때 **검증 전용으로 대여**한다. 구현 재개가 아니므로 `state.json`의 `created_by_role`은 impl role로 확인·보존하고 review role로 바꾸지 않는다.
별도 워크트리는 만들지 않는다. 기존 impl Issue 워크트리는 다음 조건을 모두 만족할 때 **검증 전용으로 대여**한다. 구현 재개가 아니므로 `state.json`의 `created_by_role`은 canonical producer literal `gitea-impl-agent` 또는 bounded read-only legacy literal `impl`로만 확인·보존하고 review role로 바꾸지 않는다. 이 두 exact 값 외의 missing/null/non-string/bool/list/dict/whitespace/case variant/role name은 거부하며, legacy literal은 login/authentication alias나 permission grant가 아니다. Admission은 state bytes/mode/mtime/inode를 rewrite/migrate하지 않는다.
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 변경이 없어야 한다.
@@ -1037,7 +1037,8 @@ def _validate_registered_source(plan, policy_path, deadline_monotonic):
if (type(state) is not dict or state.get('schema') != 'gitea-agent.worktree/v1' or state.get('owner') != t['owner']
or state.get('repository') != t['repository'] or type(state.get('issue')) is not int
or state['issue'] != t['issue'] or state.get('created_by_role') != 'gitea-impl-agent'
or state['issue'] != t['issue'] or type(state.get('created_by_role')) is not str
or state['created_by_role'] not in ('gitea-impl-agent', 'impl')
or state.get('mode') != 'detached'):
reject('worktree registration identity mismatch')