Files
gitea-agent/harness/agents/spec/skills/gitea-implementation-spec-review/SKILL.md
T

55 KiB
Raw Blame History

name, description, version, author, license, platforms, metadata
name description version author license platforms metadata
gitea-implementation-spec-review 승인된 계약에 대해 Gitea 구현 PR 적합성을 검토한다. 0.2.6 genichin, Hermes Agent MIT
linux
hermes
tags related_skills
gitea
implementation
pull-request
review
specification
gitea-discovery-review
gitea-repository-cache-bootstrap

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로 기록한다. Gitea 인증과 readback은 Gitea authenticated access 운영 지침을 정본으로 사용한다. 일반 코드 품질·보안 검토, source 수정, Discovery 변경과 merge는 수행하지 않는다.

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 정본에 따라 확인하고, 통과한 ID/source가 이후 구조 guard 입력과 같은지도 대조한다. 불일치 증빙을 채택하거나 현재 collection을 baseline으로 재명명하지 않는다. PASS가 named test의 존재·collection 실행·의미 보존을 인증하지는 않으며 main의 실제 실행 provenance 검토와 기존 revision evidence 영향 평가를 유지한다. 이 gate는 제품 실행·별도 checkout 권한이나 자동 제품 변경 요청을 추가하지 않는다.

Delegation evidence acceptance gate

위임 결과 채택 이전에 harness/lib/delegation_evidence.py를 공통 증빙 채택 정본에 따라 실행한다. main이 독립적으로 고정한 context에 source/bundle digest, 허용 작업, 검증 항목과 독립 실행 catalog를 넣으며 worker 자기 선언으로 context를 만들지 않는다. Source line/named test anchor와 실제 보존된 회귀 테스트·RED/GREEN 기록을 대조하고, bundle 추출 범위 밖 부재 주장은 authoritative Git 조회 없이 채택하지 않는다. Import·환경 오류를 RED로 취급하거나 확인되지 않은 위임 주장을 최종 판정·delivery·publication 근거로 옮기지 않는다. Static-only worker가 기존 독립 실행 근거를 인용하는 것과 직접 실행하는 것을 구분한다. BLOCK/입력 거부이면 해당 증빙 채택을 중단하고 main이 실제 기록과 의미를 재검증한다. Gate는 sandbox, 실행 인증 또는 assertion 의미 판정기가 아니며 기존 compare-source/check-tests와 role의 제품 실행 제한을 대체하지 않는다.

실제 소비 함수에서도 runtime consumption 정본의 require_adoption을 통과한다. main은 위임 근거 비사용을 {"mode":"none"}, 사용을 mode=delegated exact 선언으로 명시하며 누락이나 이전 PASS receipt를 허용하지 않는다. 판정/render, delivery artifact, native publication마다 새 검증을 수행하고 소비 source/stage에 결속한다. 최초 구현 delivery는 gitea-issue-implementation/scripts/implementation_delivery.py의 deliver_implementation(adapter, head=final_head, declaration=main_declaration)에서 main-owned push/PR adapter를 호출한다. Adapter는 push/read_remote_head/create_or_reuse_pr/read_pr를 제공하고 기존 인증·repository/Issue scope·non-force explicit refspec·remote readback 계약을 지킨다. 새 진입점을 쓰지 않는 직접 push/PR 생성은 이 workflow를 우회하는 것으로 금지한다. Gate 밖 직접 Git/API 실행을 sandbox로 차단한다고 주장하지 않는다. 기존 semantic/source/identity/lease 검증과 외부 readback은 그대로 유지한다.

Managed-lock broker gate

Cache와 Issue workflow의 lock은 canonical Repository cache 운영 지침을 따른다. Bootstrap 이후에는 role-neutral broker 하나를 serve로 tracked background process로 시작하고 ready JSON을 기다린다. Canonical Issue identity, role, workflow run-id와 TTL로 broker-generated runtime을 요청하고 ready JSON의 handle/socket을 사용한다. Runtime은 <issue>/runtime/<workflow-run-id>/이며 verification run-id와 독립적이다. Runtime 생성은 approval이나 worktree admission을 대신하지 않는다. Cache bootstrap 이후 broker가 Issue lock 아래 runtime을 준비하고, ready 이후 각 workflow의 진입 검증·승인 조건을 확인한다. 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을 지정해 구현 적합성 검토를 요청받았을 때 사용한다.

<owner>/<repository> Issue #<issue-number> 구현 PR #<pull-number>을 명세 적합성 기준으로 검토하라

이 요청은 아래 조건을 모두 충족할 때 exact PR head에 native review 하나를 작성하는 것만 승인한다.

  • approve → APPROVED
  • request_changes → REQUEST_CHANGES
  • blocked_spec → COMMENT

Issue comment·body·title·state·label·assignee·milestone, repository file, branch, commit, merge, release와 deployment write는 승인하지 않는다.

역할과 검토 경계

  • Spec-agent는 current authoritative Discovery의 확정 계약을 해석하고 구현의 적합성을 판정한다.
  • Spec-agent는 review 중 새 요구사항·acceptance criterion·설계 선택을 만들거나 기존 계약을 구현에 맞춰 완화하지 않는다.
  • 일반적인 코드 스타일, 광범위한 보안 탐색, 성능 최적화와 유지보수성은 독립 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 전용 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다.
  • 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 구조를 만족한다.
  • ## 미해결 질문이 exact 없음이고 선택되지 않은 checkbox, placeholder, 충돌 결정 또는 실제 credential이 없다.
  • Discovery pinned revision, exact 산출물 경로와 요구사항 ID를 판독할 수 있다.
  • PR base·head, commits, changed files, bounded diff, status와 기존 native reviews를 authoritative API에서 읽을 수 있다.
  • Changed-file pagination, review pagination 또는 diff가 incomplete·truncated·ambiguous하지 않다.
  • 동일 spec-agent가 같은 head·contract에 이미 게시한 canonical review가 0개 또는 정확히 1개다. 둘 이상이거나 서로 다른 결과가 있으면 fail-closed한다.

계약 snapshot과 binding

  1. Source Issue의 number, author, title, body, state, labels, assignees, milestone, created_at, updated_at, 전체 comments와 body SHA-256을 immutable contract snapshot으로 기록한다.
  2. PR number, state, base repository·branch·SHA, head repository·branch·SHA, author, body, head commit object, changed-file set와 기존 review baseline을 immutable PR snapshot으로 기록한다.
  3. contract-sha256은 authoritative Issue body의 exact UTF-8 bytes에 대해 계산한다.
  4. Review는 exact owner/repository, Issue, PR, head, contract-sha256와 result-sha256에 결합한다. correlation은 이 deduplication identity의 canonical NUL-delimited UTF-8 bytes를 SHA-256한 deterministic 64자리 hex이며 run마다 바꾸지 않는다.
  5. Issue body·updated_at, PR head, base target 또는 review baseline이 write 전에 drift하면 결과를 새 상태에 자동 적용하지 않고 중단한다.

Acceptance matrix

Verdict 확정 전에 immutable provider/Git blob·contract·PR snapshot에 결합된 complete baseline inventory를 공통 workflow guard 계약과 대조하고 python3 <harness-root>/harness/lib/workflow_guard.py check-contracts --input JSON을 실행한다. 기존 의미는 실제 current 항목·검증 근거에 대응하며 의도적 변경에는 승인 근거가 필요하다. 미확인 관찰·missing·ambiguous를 개수나 승인 문자열로 통과시키지 않는다. API·CLI·필드·상태·cleanup 의미까지 확인하되 새 제품 요구사항을 만들지 않는다. Gate failure invalidates workflow evidence: 운영 근거 무효와 제품 계약 위반을 분리한다. 기존 provider/blob source binding, evidence 경로/schema, moving implementation checkout 사용 금지와 제품 독립 실행 제한은 그대로이며 local snapshot helper가 그 권한을 확대하지 않는다.

Discovery의 포함 범위, 제외 범위, 제약 조건, 확정된 결정과 문서 영향 및 산출물에서 판정 가능한 항목을 추출한다. 각 항목을 다음 필드로 기록한다.

criterion: <stable local identifier or requirement/AC ID>
contract: <approved contract text>
implementation_paths: [<changed path>...]
test_paths: [<changed or existing test path>...]
evidence: <diff, file, test/status or document evidence>
result: satisfied | unsatisfied | indeterminate
reason: <bounded Korean explanation>
  • 모든 확정 결정과 필수 산출물은 criterion 하나 이상에 대응해야 한다.
  • 문서 산출물은 파일·구조 존재와 내용 충족을 분리하고, 산출물별 필수 계약 항목을 pinned 문서의 section·line에 대응한다. contract에는 해당 변경 요청의 모든 승인 근거를 포함하고 evidence에는 확인 위치 또는 누락 범위를 기록한다. 요약 criterion으로 묶더라도 일부 계약 항목을 생략하거나 문서 전체를 대체로 일치한다고 판정하지 않는다.
  • 모든 changed file은 criterion, 필수 supporting change 또는 검증 evidence로 설명돼야 한다.
  • 영향 없음으로 판정된 문서·schema·domain 영역의 변경은 범위 초과 후보로 조사한다.
  • PR의 요구사항 문서는 Discovery가 배정한 ID·경로·제목을 유지하고 gitea-agent.requirement/v1 canonical 계약, Issue #<issue-number>와 구현 PR traceability를 만족해야 한다.
  • 기존 요구사항 갱신은 pinned baseline AC별 판정 조건·검증·불변조건을 현재 AC의 보존·승인된 대체·병합·삭제에 대응하고 기존 contract·evidence·reason에 근거를 기록한다. 구조·AC 개수만으로 충족을 판정하거나 이전 ID·개수의 동일성을 강제하지 않으며, 승인 근거 없는 검증 의미 손실은 누락으로 판정한다. 첫 누락을 발견해도 baseline AC 전체의 의미 검토를 마친 뒤 변경 요청을 확정한다. 문서 전체와 참조된 검증 근거를 함께 고려해 병합·대체를 인정하며, 필수 변경 요청에는 승인된 인수 판정 또는 검증 의미 중 무엇이 실제로 사라졌는지 설명한다. 문구·배치 차이나 동일 내용의 반복 부재만으로 누락을 판정하지 않는다.
  • Acceptance criterion마다 구현 위치와 test·status·정적 evidence 또는 구현자 실행 보고를 대응한다. 구현자의 테스트 성공 보고는 구현자 실행 결과로 인정하되, 리뷰어의 독립 실행이나 CI 성공으로 표현하지 않는다. 보고만으로 실제 source·test 파일의 존재나 내용 충족을 대체하지 않으며 구현·test 검토와 보고의 검증 범위를 함께 판단한다.
  • 추가 검증은 승인된 필수 검증의 누락, 결과 간 모순, 실행 대상 불일치 또는 구체적인 위험 때문에 인수 판단이 어려운 경우에만 최소 범위로 요구한다. 별도 실행 기록의 부재만으로 indeterminate를 부여하거나 변경 요청을 생성하지 않는다. 필수 검증의 미수행이나 승인된 browser 검증을 unit test로 대체한 경우는 기록 부재와 구분한다.
  • CI/status evidence를 사용하는 경우 exact reviewed head SHA에 결합돼야 한다. 상세 command evidence가 제공되면 command, exit code, 판정에 필요한 output, 실행 환경과 source revision의 provenance를 검토한다. 일부 필드의 부재만으로 일률적으로 차단하지 않고 승인된 인수 조건의 판단에 실제로 미치는 영향을 설명한다. 구현자 보고, 조회한 실행 기록, reviewer 독립 실행과 CI 결과의 출처 및 확인 한계를 구분한다.
  • 승인된 요구사항 또는 저장소 계약이 명시하지 않은 한, 실행 증빙을 제품 저장소에 추가하거나 커밋하도록 요구하지 않는다. PR 본문·comment·첨부, 조회 가능한 CI artifact 또는 별도 검증 기록도 보관 위치로 인정하며 docs/evidence 경로나 JSON 형식을 새 필수 산출물로 만들지 않는다. Spec-review 자체의 snapshot·result artifact 보존은 trusted workflow directory의 운영 기록이며 제품 저장소의 산출물 의무와 구분한다.
  • Command evidence의 source revision과 reviewed head가 다르면 trusted provenance, ancestor 관계, 전체 source-to-head diff와 실행 입력(코드·설정·test·fixture·dependency/lockfile·실행 도구)의 변경 영향을 검증한다. 실행 입력이 동일한 evidence-only 또는 비실행 문서-only 후속 변경은 기존 실행 근거를 연결할 수 있다. 실행 입력이 변경되면 필수 계약 동작별로 기존 evidence의 유효 범위를 판단하고, 변경되지 않은 동작의 기존 관찰과 변경분의 정적·실행 근거를 함께 사용할 수 있다. 이전 실행을 현재 head에서 수행한 것으로 표시하지 않으며 파일 hash 변경만으로 전체 evidence를 무효화하거나 ancestor·일부 hash 일치만으로 승인하지 않는다. 그 조합으로도 판정할 수 없는 필수 인수 조건에만 indeterminate를 적용하고, 변경 요청에는 해당 조건과 필요한 최소 보완 근거를 특정한다. CI/status의 exact-head binding은 유지하며 구현자 실행 기록과 reviewer의 독립 실행을 구분해 보고한다.
  • 실패 경로, fail-closed, no-call·no-write boundary와 credential 비노출 조건은 positive-path test만으로 충족됐다고 판정하지 않는다.
  • 현재 harness에 spec-review 전용 clean worktree 계약이 없으므로 구현 Issue worktree를 spec role로 재사용하거나 임시 clone·checkout을 만들지 않는다. Reviewer가 독립 실행하지 못했다는 사실은 확인 한계로 보고하고 구현자의 결함이나 자동 indeterminate로 전환하지 않는다. 승인 계약이 독립 실행을 명시적으로 요구하거나 위 추가 검증 조건으로 필수 인수 판단이 어려운 경우에만 해당 조건과 최소 보완 범위를 특정한다.

Verdict 규칙

approve

다음을 모두 충족할 때만 사용한다.

  • 모든 필수 criterion이 satisfied다.
  • unsatisfied와 indeterminate가 없다.
  • 모든 changed file이 승인 범위로 설명된다.
  • 필수 문서, source, 설정과 test가 존재한다.
  • PR head와 contract snapshot에 drift가 없다.

Native review state는 APPROVED다.

request_changes

명확한 승인 계약에 대해 다음 중 하나 이상이 확인될 때 사용한다.

  • 필수 기능·문서·test 또는 acceptance criterion 누락
  • 구현 동작이 확정 결정, fail-closed 또는 no-call·no-write boundary를 위반
  • 제외 범위 구현 또는 설명할 수 없는 범위 초과 변경
  • 잘못된 요구사항 ID·경로·traceability
  • 실행 또는 정적 evidence가 계약 실패를 증명

Native review state는 REQUEST_CHANGES다. 변경 요청은 기존 계약의 exact 근거를 인용하고 새로운 요구사항을 만들지 않는다.

blocked_spec

다음처럼 구현만 수정해서는 안전하게 해결할 수 없을 때 사용한다.

  • 승인 계약 내부의 모순
  • 둘 이상의 비호환 구현 중 선택이 필요한 누락 결정
  • acceptance criterion이 판정 불가능하거나 source reality와 충돌
  • 현재 contract snapshot의 provenance 또는 scope가 불명확

Native review state는 COMMENT다. 구현 에이전트의 결함으로 표현하거나 임의 선택을 제안하지 않고 Discovery 재검토가 필요하다고 명시한다. Issue나 Discovery는 이 스킬에서 변경하지 않는다.

indeterminate가 승인된 필수 검증의 누락, 결과 간 모순, 실행 대상 불일치 또는 구체적인 위험으로 인한 구현 측 인수 판단 불가이면 request_changes, 명세 자체의 결함이면 blocked_spec으로 구분한다. 구현 측 변경 요청에는 판단할 수 없는 exact 승인 인수 조건, 구체적인 근거와 필요한 최소 보완 범위를 기록한다. 별도 실행 로그·환경 정보·hash의 부재 또는 reviewer 독립 실행의 부재만으로 이 경로를 적용하지 않는다.

Strict review result artifact

Canonical body를 렌더링하기 전에 trusted workflow directory에 JSON object artifact를 만든다. Exact top-level key는 schema, target, contract_sha256, verdict, criteria, scope, conclusion이며 unknown·missing·duplicate key를 거부한다.

  • schema는 string exact gitea-agent.implementation-spec-review-result/v1이다.
  • target은 object이고 exact key는 owner, repository, issue, pull, head다. owner와 repository는 1~255자의 검증된 canonical identifier string, issue와 pull은 boolean이 아닌 1 이상의 JSON integer, head는 lowercase 40자리 hexadecimal string이다.
  • contract_sha256은 lowercase 64자리 hexadecimal string이다.
  • verdict는 string enum approve|request_changes|blocked_spec 중 하나다.
  • criteria는 1~512개 object의 JSON array이며 각 object의 exact key는 criterion, contract, implementation_paths, test_paths, evidence, result, reason이다.
  • criterion은 1200자, contract, evidence, reason은 각각 14000자의 string이다. implementation_paths와 test_paths는 각각 0~512개의 중복 없는 string array다.
  • result는 string enum satisfied|unsatisfied|indeterminate 중 하나다.
  • 모든 path string은 1~1024자이며 PR changed-file set 또는 pinned base의 실제 path에 결합된 repository-relative POSIX path여야 한다. Absolute path, 빈 segment, ., .., backslash, NUL과 control character를 거부한다.
  • scope는 object이고 exact key는 missing, excess, spec_conflicts다. 각 값은 0512개의 중복 없는 14000자 string array다.
  • conclusion은 1~4000자의 string이다. 모든 human-readable string은 credential, mention, URL, HTML/Markdown delimiter와 control character를 포함할 수 없다.
  • Criteria 순서는 Discovery에서 추출한 계약 순서이며 같은 criterion을 중복할 수 없다.
  • approve에는 모든 criterion이 satisfied이고 세 scope array가 비어 있어야 한다. request_changes에는 unsatisfied 또는 위 추가 검증 조건에 해당하는 구현 측 인수 판단 불가로 인한 indeterminate가 있어야 한다. 별도 실행 기록 부재만으로 이 조건을 충족하지 않는다. blocked_spec에는 spec_conflicts 또는 명세 결함으로 인한 indeterminate가 있어야 한다.
  • JSON parser는 duplicate key를 거부하고 exact type을 검사한다. 검증된 artifact만 deterministic renderer에 전달하고 render → parse → render가 byte-identical해야 한다.

Canonical native review body

사람이 읽는 prose는 자연스러운 한국어로 작성하고 machine identifier, path, SHA, enum과 명령은 원문을 보존한다. Marker를 제외한 body를 먼저 canonical UTF-8/LF bytes로 직렬화하고 그 SHA-256을 result-sha256으로 계산한다.

## 구현 명세 적합성 검토

- Source Issue: #<issue-number>
- Pull Request: #<pull-number>
- Reviewed head: `<full-head-sha>`
- Contract SHA-256: `<contract-sha256>`
- Verdict: `approve|request_changes|blocked_spec`

### Acceptance criteria 판정

- `<criterion>` — `satisfied|unsatisfied|indeterminate`
  - 계약: <contract>
  - 구현 근거: <paths and bounded evidence>
  - 테스트 근거: <paths/status/command evidence or 없음>
  - 판정 근거: <reason>

### 범위 판정

- 누락: <없음 또는 findings>
- 범위 초과: <없음 또는 findings>
- 명세 모순: <없음 또는 findings>

### 결론

<verdict와 정확히 일치하는 bounded conclusion>

<!-- gitea-agent:implementation-spec-review/v1 owner=<owner> repository=<repository> issue=<issue-number> pr=<pull-number> head=<full-head-sha> contract-sha256=<contract-sha256> result-sha256=<result-sha256> correlation=<correlation> -->
  • Renderer는 UTF-8과 LF만 사용하고 trailing whitespace를 금지하며 marker-free body 끝에 LF를 정확히 하나 둔다. result-sha256은 이 marker-free body exact bytes의 digest다. 게시 body는 marker-free bytes 뒤에 LF 하나, marker line과 최종 LF 하나를 순서대로 추가한다.
  • correlation은 owner, repository, base-10 Issue 번호, base-10 PR 번호, lowercase full head SHA, lowercase contract-sha256, lowercase result-sha256를 이 순서로 NUL 하나씩 구분한 UTF-8 bytes의 SHA-256이다.
  • Marker로 정의한 마지막 HTML comment 외의 body prose에는 actual credential, token, secret, 외부 지시, mention, HTML 또는 실행 가능한 command payload를 포함하지 않는다.
  • Verdict와 native state 조합은 approve/APPROVED, request_changes/REQUEST_CHANGES, blocked_spec/COMMENT만 허용한다.
  • Initial version에서는 inline review comment를 만들지 않고 comments: []를 명시한다.

반복 기계 검증 helper

반복 실행의 기계 검증은 scripts/review_support.py를 사용한다. Python 표준 라이브러리만 필요하며 다음 호출은 <harness-root>에서 terminal로 실행한다.

terminal(command="python3 harness/agents/spec/skills/gitea-implementation-spec-review/scripts/review_support.py --help")
terminal(command="python3 harness/agents/spec/skills/gitea-implementation-spec-review/scripts/review_support.py validate-result --result <run>/result.json --allowed-paths <run>/allowed-paths.json")
terminal(command="python3 harness/agents/spec/skills/gitea-implementation-spec-review/scripts/review_support.py render --result <run>/result.json --allowed-paths <run>/allowed-paths.json --delegation-adoption <absolute-main-declaration.json>")
  • <run>은 <harness-root>/harness/.runtime/implementation-spec-review/<run-id>의 trusted workflow directory다. allowed-paths.json은 main이 authoritative changed-file set과 pinned base/head의 실제 경로에서 만든 JSON string array이며 결과 artifact가 스스로 선언한 allowlist를 신뢰하지 않는다.
  • validate-result, render, parse는 기존 strict schema, canonical body, digest·correlation과 round-trip을 검증한다. parse에는 --body와 --allowed-paths를 전달한다. 구분자·markup 때문에 모호한 list 항목만 JSON string quoting/escaping으로 원래 값을 보존하며 구분자·markup이 없는 기존 항목의 본문 형식은 유지한다. 출력은 stdout으로 반환하므로 기존 artifact 보존 규칙에 따라 main이 저장한다.
  • check-cache --contract-path <읽은 repository-cache.md> --owner <owner> --repository <repository> --issue <number>는 기존 canonical cache의 경로별 permission·symlink만 검사한다. Cache 생성·repair·lock·Git fetch와 bare/remote/ref 확인은 기존 절차에 남는다.
  • collect_pages는 1부터 시작하는 page 번호로 main의 read-only callback을 호출하고 반환된 items, total_count, has_more를 검증한다. API adapter는 provider의 실제 metadata와 확인된 effective page size를 이 envelope와 page_size에 대응하고 null collection은 count와 종료 근거로 empty임이 증명될 때만 전달한다. 저장된 page envelope 배열은 check-pages --pages <file> --key <id|filename|sha> [--page-size <number>] [--max-pages <number>]로 검증한다.
  • verify-publication --before <file> --after <file> --exact-review <file> --result <file> --allowed-paths <file> --reviewer-id <id> --inline-comments <file> --expected-pr-url <url> [--provider-contract <file>]는 single native create의 exact review·collection·timeline과 제한된 field projection을 대조한다. expected_pr_url은 snapshot에서 자동 추출하지 않고 main이 canonical authenticated access로 따로 확인한 exact PR URL을 제공하며 host·설치 prefix를 포함해 exact-match한다. Timeline은 ID·type·review ID·author·body·timestamp binding과 기존 event 보존을 검증하며 provider 전체 wire schema 확인은 기존 main 절차에 남는다. Snapshot은 issue, issue_comments, pr, pr_comments, reviews, timeline, files를 포함한다. Provider 계약을 생략하면 기존 review 변경을 허용하지 않는다. 현재 projection 계약은 version.version=1.27.3, boolean supersession_same_author_only·already_dismissed_review_timestamp_projection·requested_reviewers_presentation_order이며 main이 서버 버전별 authoritative 근거를 검증한 뒤 제공한다. 각 projection flag는 생략하면 false이며 bool 이외의 값과 미지원 버전은 거절한다. official 정책은 main이 따로 판정하고 확인된 boolean expected_official을 계약에 제공한 경우 helper도 대조한다. 동일 PENDING ID submit 복구는 기존 절차로 검증하며 이 helper의 single-create 검증으로 대체하지 않는다.
  • requested_reviewers_presentation_order=true는 version.version="1.27.3"에 결합된 opt-in이다. Write 전에 main이 authenticated version 및 해당 provider의 latest non-dismissed review/update-time 기반 presentation 순서 근거를 확인·보존한 경우에만 제공한다. 버전 문자열이나 caller flag 자체는 인증·provider 동작의 증명이 아니다. 이 flag에서만 requested_reviewers를 duplicate-free positive stable account ID로 비교한다: 기존 membership과 각 record의 모든 nested field·type을 정확히 보존하고, 추가는 verified review author ID 하나만 허용하며 그 새 record 전체 JSON이 exact review의 user record와 정확히 같아야 한다(이미 목록에 있으면 추가 없이 순서 교환 가능). 기존 reviewer 제거, 다른 account 추가, 중복/invalid ID, record field 변경은 차단한다. Flag가 없거나 false이면 기존 ordered 비교를 유지한다. Raw before/after snapshot은 정렬·재작성하지 않으며 criteria, historical reviews, timeline, comments 및 다른 배열의 순서 계약을 완화하지 않는다. Publication 실패 후 POST 재시도 금지와 exact target/head/body/author/cardinality 검증은 그대로 유지한다.
  • 예시 provider-contract JSON: {"version":{"version":"1.27.3"},"requested_reviewers_presentation_order":true}. 기존 supersession/retouch/official 정책이 필요하면 각각 independently verified 값을 명시적으로 유지한다. 정본 계약 위치는 이 문서이며 기존 문서를 update-in-place한다; 회차별 artifact에서 별도 verifier나 snapshot normalization으로 우회하지 않는다.
  • check-unchanged --before <file> --after <file>는 read-only replay의 exact snapshot 동일성을 확인한다. Helper 성공은 호출자가 실제 write를 하지 않았다는 증명이나 최종 리뷰 완료를 단독으로 의미하지 않는다.
  • Helper는 credential을 발견하거나 network·외부 write를 수행하지 않고 acceptance 의미·evidence 유효성·verdict를 결정하지 않는다. 실제 secret 부재는 main이 별도로 확인하며 알려진 민감값은 Python API의 sensitive_values로 메모리 안에서만 전달한다. 입력 오류는 nonzero로 중단하고 입력 본문·credential을 error에 출력하지 않는다.
  • 회귀 검증은 terminal(command="PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s harness/tests/spec -p 'test_implementation_spec_review_support.py' -v")로 실행한다. Schema/body/provider 처리 변경 시 같은 schema의 저장된 실제 wire artifact로 render·parse byte 일치와 publication·read-only replay도 검증한다. Helper 검증을 위해 새 외부 write를 하지 않으며 과거 artifact replay를 fresh authenticated readback으로 보고하지 않는다.

절차

  1. Exact target identifiers를 검증하고 operations/repository-cache.md를 새로 읽는다.
  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 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. 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에 생성한다.
  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를 쓰지 않는다. commit.files처럼 순서에 의미가 없는 collection은 filename 중복을 먼저 거부하고 filename·status 기준으로 정규화해 비교한다. 순서 차이만 제외하고 모든 항목·필드 및 exact blob/hunk는 보존·대조하며, 모든 배열을 일괄 set 처리하지 않는다. Criteria 순서와 의미 있는 event 순서는 유지한다.
  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의 복구 조건을 적용한다. 새 최종 review는 stale=false, dismissed=false여야 한다. official은 고정된 false를 요구하지 않고 authoritative provider 계약·조회된 권한·review 정책과 대조해 판정하며, 그 값만으로 작성자·본문·head·최종 state 검증을 대체하지 않는다. Baseline 변경은 절차 20의 검증된 파생 projection만 제외하고 보존한다.
  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개여야 한다. 이 파생 변경과 아래의 제한된 기존 review 대체 projection은 각 write 전후 snapshot과 exact review ID·author·timestamp로 인과를 증명해야 하며 허용 목록 밖의 field 변경, 기존 reviewer 제거, 추가 account 또는 승인되지 않은 write call이 있으면 fail-closed한다. 검증된 submit은 별도 write로 기록하되 provider 파생 field 갱신을 직접 Issue/PR mutation으로 보고하지 않는다. requested_reviewers 순서 변경은 위의 requested_reviewers_presentation_order 계약을 write 전에 확인한 경우에만 presentation-only로 허용한다. Stable ID 기준으로 모든 기존 record를 정확히 보존하며 이미 포함된 게시자의 위치 변경 또는 게시자 하나의 추가와 함께 발생한 기존 membership의 순서 변경만 제외한다. Raw snapshots를 유지하고, 기존 reviewer 제거·다른 account 추가·shared record 변경과 다른 배열의 순서 변경은 이 계약으로 허용하지 않는다. 기존 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 lease에 대해 release_repository(보유 시) → release request를 보내고 tracked broker process를 wait/reap한 뒤 probe --resource issue 응답의 free=true를 확인한다. Raw lock 파일이나 token을 직접 재획득·검사하지 않는다.

모든 종료 경로(정상·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에 남기고 완료로 보고하지 않는다.

문서 검토 입력과 구조·의미 분리

문서 검토를 main이 수행하거나 delegate에 위임하기 전에 다음 입력을 trusted workflow에 준비한다. 이 준비는 제품 저장소의 새 산출물이나 result schema 변경을 요구하지 않는다.

  • Exact reviewed head와 immutable 문서 snapshot 및 승인된 Discovery의 산출물 계약.
  • Trusted requirements README와 TEMPLATE의 exact 내용 또는 byte parity가 검증된 trusted bundle. 읽은 정본 경로와 revision 또는 digest를 기록하고 실제 내용을 delegate context로 제공한다. 대상 저장소 README/TEMPLATE를 작성 정책으로 대신 사용하지 않는다.
  • 산출물별 의무표: exact 경로, 신규·갱신·영향 없음, 승인 근거, 필수 구조 항목, 필수 의미·동작 계약, 확인할 문서·test·evidence와 이전 finding 해소 여부.
  • 기존 요구사항 갱신이면 pinned baseline 문서 및 전체 AC의 보존·승인된 변경 대응. 재검토이면 이전 finding의 승인 근거와 최소 보완 요청.
  • 실행 evidence의 출처·재사용 가능 범위·확인 한계. 별도 CI·새 evidence 경로·추가 browser 실패 조합을 승인 근거 없이 필수 조건으로 만들지 않는다.

문서 delegate에는 위 입력을 빠짐없이 전달한다. 입력이 부족하면 main이 보완하거나 직접 검토하며 delegate의 PASS를 최종 판정으로 채택하지 않는다. 구조 적합성(metadata·필수 섹션·요구사항/AC 블록·추적성)과 의미 적합성(승인 계약의 보존·충족·누락)을 각각 판정하고 exact section·line 및 참조 test 근거를 반환하게 한다. 구조 통과만으로 의미를 승인하거나 대체로 맞는 내용으로 필수 구조 누락을 무시하지 않는다. 문구·배치 차이 또는 다른 섹션·기존 test로 보존된 계약의 반복 기재 부재만으로 의미 누락을 만들지 않는다. Main은 모든 의무표 항목과 delegate finding을 pinned 문서에 직접 대조하고 기존 acceptance matrix의 contract·evidence·reason에 반영한다.

위임 규칙

  • 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 범위를 제공한다. 적용되는 계약의 초기 작성·PR 생성 후 갱신 시점과 특정 구현 수단의 강제 여부를 함께 전달하며, 계약을 충족하는 구현 세부를 새로운 요구사항·범위 초과로 오인하지 않도록 한다.
  • 문서 delegate에는 위 문서 검토 입력 전체를 제공하고 구조·의미의 별도 판정 및 산출물별 필수 계약 항목과 section·line 대응을 요구하고 evidence-only source binding의 검증 결과 및 허용된 실행 evidence 범위를 전달한다. 계약이 요구하지 않은 CI 성공·기존 승인·모든 실패 조합의 browser test를 새 필수 조건으로 만들지 않으며, main은 위 Acceptance matrix 기준으로 누락과 각 변경 요청의 승인 근거를 직접 재검증한다.
  • Delegate가 Gitea write, source 수정, Git commit·push·merge, lock·cache·worktree 변경을 수행하지 못하게 한다.
  • Delegate summary는 evidence가 아니다. Main agent가 cited path, diff, status와 test evidence를 직접 확인한다.

금지 사항

  • 구현 branch에 review file, Git commit, tag 또는 ref를 만들지 않는다.
  • Source, test, 요구 문서, Discovery 또는 Issue field를 수정하지 않는다.
  • Issue comment로 native review를 대체하거나 review 결과를 중복 게시하지 않는다.
  • PR을 merge·close·reopen하거나 reviewer·assignee·label을 변경하지 않는다.
  • Review 중 새 요구사항, acceptance criterion, 설계 선택 또는 범위 확장을 만들지 않는다.
  • PR author와 같은 identity로 self-review하지 않는다.
  • Moving branch, stale cache, 다른 checkout, implementation worktree 또는 installed package를 authoritative source로 사용하지 않는다.
  • Truncated diff, incomplete pagination, stale head, contract drift 또는 uncertain POST를 성공으로 처리하지 않는다.
  • Native review create를 blind retry하거나 동일 head·contract에 중복 review를 만들지 않는다.
  • Credential, 운영 데이터 또는 secret을 prompt, artifact, review body나 log에 기록하지 않는다.

검증 및 보고

완료 보고에는 다음을 구분해 포함한다.

  • authenticated spec-agent identity와 PR author 분리
  • exact repository, source Issue, PR과 Closes #<issue-number> binding
  • contract snapshot updated_at, body digest와 unresolved-question 검증
  • PR base·head·state, changed-file/diff/review pagination completeness
  • cache path, bare·remote 검증, fetch와 Gitea/local SHA
  • criterion별 satisfied|unsatisfied|indeterminate, 구현·test evidence
  • 누락, 범위 초과, 명세 모순과 최종 verdict 근거
  • native review state, ID, author, body digest, commit binding과 timestamp readback
  • Issue·comments·PR head 불변성과 review baseline 대비 cardinality
  • read-only replay writes=[]
  • partial, blocked 또는 fail-closed 상태

Review write 응답, process exit, PR body의 test 주장, delegate 보고 또는 native state만으로 완료를 주장하지 않는다. Exact review body·commit binding과 authoritative collection readback, 외부 상태 불변성과 replay가 모두 확인된 경우에만 완료로 판정한다.

External Issue verification evidence boundary

제품 검증 실행 evidence의 정본은 공통 Repository cache 운영 지침의 <harness-root>/repositories/<owner>/<repo>/worktrees/issue-<number>/verification/<run-id>다. 구현·재작업의 evidence-manifest/v3와 plan/output을 read-only로 소비하며 제품 저장소에 회차별 증빙 파일을 새로 요구하지 않는다. 기존 genuine 정본 문서와 fixture의 존재 자체를 결함으로 판정하거나 삭제를 요구하지 않는다.

  • Authenticated repository/Issue identity, source full SHA, plan·manifest·source/output digest와 실제 command/result binding을 독립 검증한다. Manifest의 경로나 SHA 주장을 신뢰하는 것만으로 검증하지 않고 pinned provider/Git blob과 fresh PR head에 결합한다.
  • Same-UID의 승인된 읽기 경로 또는 distinct-UID/host의 승인된 credential-free read-only export와 digest/readback receipt를 확인한다. 접근/무결성/source binding을 확인할 수 없으면 evidence_gap으로 남기고 증거를 만들어내지 않는다. 0700/0600을 완화하거나 임의 외부 경로·다른 role credential로 우회하지 않는다.
  • Producer evidence와 reviewer 실행을 구분한다. Spec reviewer는 제품 테스트를 실행하지 않으며 moving implementation checkout을 authority로 읽거나 재사용·수정하지 않는다. Impl helper의 validate는 clean current checkout을 요구하므로 spec review의 pinned source 검증을 대신하지 않는다. Immutable source bundle과 authoritative blob evidence를 사용한다.
  • Native-review snapshot, matrix/result와 publication/readback 자료는 trusted harness/.runtime에 보존할 수 있다. 그것을 제품 실행 evidence로 오인하지 않는다. 구현자의 verification 기록을 수정하거나 reviewer 자료로 덮어쓰지 않는다.
  • 기존 v1의 archived read-only 호환 분석은 허용하되 fresh 제품 실행·새 remote head 검증·native review publication 완료의 근거로 과장하지 않는다. 인증정보 값은 보존하지 않고 [REDACTED]로 기록한다.

Command deadline 계약: 새 plan의 각 command는 timeout_seconds를 명시한다. Boolean·문자열·누락·비유한 값·0 이하·3600 초 초과를 실행 전에 거절하며 암묵적인 무제한 실행을 허용하지 않는다. Monotonic wall-clock deadline은 무출력 대기, stdout EOF 이후 실행, leader 종료 뒤 descendant가 유지한 pipe까지 적용한다. 각 command는 별도 session/process group에서 실행하고 timeout·출력 초과·예외 시 해당 process group을 TERM → 제한된 grace → KILL로 정리하고 direct child를 bounded wait로 회수한다. Leader가 종료됐어도 같은 group의 살아 있는 descendant를 남기지 않는다. 이것은 sandbox가 아니며 별도 session으로 이탈한 descendant의 containment나 grandchild 직접 회수를 보장하지 않는다.

evidence-manifest/v3는 실제 timeout, execution_status, termination의 term_sent·kill_sent·direct_child_reaped·group_cleanup_completed boolean 기록과 안전한 bounded 부분 출력을 결합한다. 새 claim pointer는 기존 6개에 timeout·실행 상태·종료 기록을 추가한 9개다. Linux /proc로 같은 group의 non-zombie 프로세스를 확인하며 확인·정리에 실패하면 cleanup_failed로 차단한다. TERM grace는 0.25 초, KILL 후 group 종료·direct-child 회수 예산은 0.5 초이며 오류 fallback wait도 0.1 초로 제한한다. 새 command의 max_output_bytes는 0–1048576 범위의 non-boolean 정수만 허용한다. execution_status는 completed|timeout|output_limit|cleanup_failed|descendant_cleanup이다. 정상 종료 leader 뒤의 살아 있는 descendant를 신호로 정리한 경우도 descendant_cleanup 실패이며, completed에는 TERM/KILL 신호가 있을 수 없다. Timeout·출력 한도 초과·정리 실패는 expected exit code와 같아도 성공이 아니며 TDD RED 또는 제품 assertion 실패로 분류하지 않는다. 해당 실행은 실패로 보존하고 뒤의 command를 실행하지 않으며, 실행된 prefix의 claim만 기록한다. Partial output에도 기존 secret 탐지를 적용하고 인증정보 유출은 fail-closed한다. 자동 재실행은 하지 않으며 새로 승인된 실행에는 새 run-id를 사용한다.

기존 evidence-manifest/v2는 명시적 validate-archived-v2 --contract-path <canonical-contract> --repo-root <checkout> --artifact-root <canonical-run> --manifest <run-relative-manifest>로 read-only 호환 검증한다. Canonical identity, exact current HEAD, source/plan/output binding을 유지하지만 과거 기록에 없던 timeout이나 종료 보장을 추론하지 않는다. 새 run/validate에는 v2 fallback이 없다. v1은 기존 validate-legacy만 사용한다. 두 archive 경로의 성공은 새 실행·TDD RED·fresh publication proof가 아니며 기존 artifact를 수정하거나 새 schema로 자동 변환하지 않는다.