Files
gitea-agent/harness/agents/spec/skills/gitea-discovery-authoring/SKILL.md
T

12 KiB

name, description, version, author, license, platforms, metadata
name description version author license platforms metadata
gitea-discovery-authoring Gitea Issue의 Discovery 초안을 작성하고 게시한다. 0.4.1 genichin, Hermes Agent MIT
linux
hermes
tags related_skills
gitea
discovery
specification
authoring
gitea-repository-cache-bootstrap

Gitea Discovery Authoring

Gitea Issue 원본과 저장소 근거를 조사해 Discovery 초안을 작성하고 Issue 본문에 게시한다. Gitea 인증과 readback은 Gitea authenticated access 운영 지침, 작성 규칙은 Discovery 작성 방법, 문서 구조는 Discovery 템플릿만 정본으로 사용하며 이 스킬에 복제하거나 임의로 확장하지 않는다.

Managed-lock broker gate

Bootstrap 이후 Issue workflow는 canonical Repository cache 운영 지침의 공통 managed-lock broker 하나를 사용한다. Canonical Issue identity, role, workflow run-id와 TTL로 broker-generated runtime을 만들도록 serve를 실행하고 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가 token을 캡슐화한다. 같은 handle의 acquire_repository/release_repository로만 nested repository lock을 관리하고 TTL 전에 renew한다. 정상·오류·cancel 모두 repository release(보유 시), Issue release, broker wait/reap, probe free=true readback 순서가 검증돼야 완료·로그·보고할 수 있다. Raw flock ... sleep, lock-file unlink와 client-side lock holder는 금지한다.

사용 시점

다음과 같이 정확한 저장소와 Issue를 지정해 Discovery 초안 작성을 요청할 때 사용한다.

<owner>/<repository>의 이슈 #<number>에 대해 discovery 초안을 작성하라

이 요청은 원본 본문의 comment 보존과 Discovery 초안으로의 본문 교체를 승인한다. 다른 comment, label, assignee, title, state, milestone 또는 repository write는 승인하지 않는다.

요구사항 문서, 구현 계획 또는 PR review 작성에는 사용하지 않는다.

Repository cache admission gate

Repository cache의 구조와 운영 규칙은 Repository cache 운영 지침만 정본으로 사용한다. 작업할 때마다 이 문서를 새로 읽고 상세 규칙을 이 스킬에 복제하거나 완화하지 않는다.

Discovery 초안을 작성하기 전에 repository cache admission gate를 반드시 통과한다. 대상 cache가 없으면 broker Issue lease 확인 전에 gitea-repository-cache-bootstrap 스킬로 초기화하며, 기존 cache가 유효하지 않으면 자동 초기화하지 않고 중단한다. 초기화 여부와 관계없이 broker Issue lease 아래에서 같은 handle의 acquire_repository request로 canonical origin의 cache를 갱신하고, 갱신 후 다시 읽은 Gitea authoritative default-branch SHA와 local ref SHA가 정확히 일치해야 한다. 일치한 SHA를 pinned source revision으로 고정하며, gate가 실패하면 초안을 작성하지 않는다.

절차

  1. 요청에서 exact owner, repository, Issue 번호를 추출하고 형식을 검증한다. read_file로 operations/repository-cache.md를 새로 읽고 canonical cache 경로를 계산·검증한다.
  2. Canonical authenticated Gitea API adapter로 spec-agent의 stable account identity와 exact repository metadata를 확인한다.
  3. 대상 cache가 없으면 gitea-repository-cache-bootstrap 스킬로 초기화하고 관련 lock이 해제됐는지 확인한다. 기존 cache가 있으면 자동 초기화하지 않고 canonical 검증 절차를 따른다.
  4. Cache와 lock 경로의 안전성을 검증한 뒤 broker serve의 ready 응답과 public request API로 canonical Issue lease를 확인한다. 같은 adapter로 Issue 전체 내용과 전체 comment baseline을 새로 읽고, Issue title, body, state, labels, assignees, milestone과 updated_at을 immutable pre-write snapshot으로 보존한다.
  5. Issue lease를 유지한 채 같은 broker handle로 acquire_repository request를 보낸다. path, bare 상태와 remote identity를 검증한 뒤 authoritative origin에서 prune/fetch한다. fetch 후 Gitea default branch와 SHA를 다시 읽고 local ref가 exact SHA와 일치하는지 확인하여 pinned source revision으로 기록한다. 어느 단계든 실패하면 보유 lease에 release_repository/release request를 보내고 외부 write와 Discovery 작성을 수행하지 않는다.
  6. read_file로 docs/discovery/README.md와 docs/discovery/TEMPLATE.md를 새로 읽는다.
  7. repository lease를 유지한 채 Issue 원본과 pinned repository SHA의 tree 및 파일을 조사한다. 움직이는 branch 이름 대신 exact pinned SHA를 사용하고, git --git-dir=<path>/repository.git의 read-only 명령 또는 이에 상응하는 안전한 reader만 사용하며 조사한 경로와 SHA를 기록한다. README가 정한 후속 문서의 exact 경로 존재 여부와 기존 요구사항명세서의 ID·파일명을 함께 조사한다.
  8. 조사 종료 시 Gitea default-branch SHA와 local ref를 다시 읽어 pinned SHA와 모두 일치하는지 확인하고 release_repository request를 보낸다. Issue lease는 전체 Issue workflow가 끝날 때까지 유지한다.
  9. README의 작성 규칙과 TEMPLATE의 visible 구조를 그대로 적용해 Discovery body artifact를 작성한다. 문서 영향 및 산출물은 README가 정한 모든 문서 유형을 빠짐없이 판정하고 문서별 필수 내용을 구현 에이전트가 추가 설계 없이 작성할 수 있을 정도로 구체화한다. 요구사항명세서는 pinned SHA에서 충돌 여부를 확인한 exact 문서 ID·경로·제목·포함할 내용·제외할 내용을 기록한다. 모든 ${...} placeholder를 교체하고 TEMPLATE에 없는 hidden state, marker 또는 metadata를 추가하지 않는다.
  10. README의 작성 후 검증에 따라 형식 검증과 내용 검토를 각각 수행한다. body artifact의 첫 marker, 섹션 순서·제목, placeholder 부재, 문서 영향 및 산출물의 문서 유형·순서·조치·경로·변경 내용·근거와 문서별 필수 내용 및 모든 저장소 근거가 pinned SHA에서 확인됐는지 검증한다. 신규 요구사항명세서의 경로에 NNN, <slug> 또는 다른 미확정 값이 남아 있거나 ID 충돌·형식 오류를 해소할 수 없으면 외부 write 없이 중단한다.
  11. write 직전에 Issue와 comments를 다시 읽는다. pre-write snapshot의 body와 updated_at이 달라졌거나 comment baseline이 drift했으면 중단한다.
  12. 아래의 단순 원본 보존 comment 형식으로 exact comment artifact를 만들고 한 번 작성한 뒤, 곧바로 comment 목록에서 authoritative readback한다.
  13. comment readback 직후 Issue와 comments를 다시 읽어 post-comment snapshot을 만든다. body와 비본문 필드가 pre-write snapshot과 같고 comments가 baseline과 exact 신규 comment 하나로만 구성돼야 한다. 다르면 body를 변경하지 않고 partial 상태로 중단한다.
  14. 보존 comment가 정확히 확인된 경우에만 Issue body 하나만 Discovery 초안으로 교체한다. provider가 조건부 update를 지원하면 post-comment updated_at 또는 ETag를 precondition으로 사용한다. 지원하지 않으면 broker-managed Issue lease 아래에서 13번 read 직후 write하며 title, state, labels, assignees, milestone 등 다른 필드는 write payload에 포함하지 않는다.
  15. 동일 Issue를 다시 읽어 body가 초안과 정확히 일치하고 다른 snapshot 필드가 변경되지 않았는지 확인한다. comments도 다시 읽어 보존 comment가 정확히 하나인지 확인한다.

원본 보존 comment

comment는 다음 형식을 사용한다. <original-body>에는 write 직전 Gitea에서 읽은 원본 body를 변형 없이 넣는다.

<!-- gitea-agent:discovery-origin/v1 owner=<owner> repository=<repository> issue=<number> body-sha256=<sha256> -->
## Discovery 작성 전 이슈 원본

<original-body>

body-sha256은 Gitea가 반환한 원본 body의 UTF-8 bytes에 대해 terminal로 계산한다. 게시 후 comment의 author, target marker, body digest와 <original-body> exact bytes를 모두 검증한다. 이 comment metadata를 Issue body에 포함하지 않는다.

  • 원본 comment와 Discovery body는 trusted workflow directory에 artifact로 먼저 작성하고 실제 write payload와 exact-match하는지 확인한다.
  • Discovery body는 TEMPLATE에서 만든 artifact의 exact bytes를 전송하고 즉시 같은 authenticated adapter의 readback으로 검증한다.
  • 다른 checkout, workspace, installed package 또는 외부 renderer를 import하지 않는다.
  • credential 값은 출력하거나 artifact에 기록하지 않는다.

재실행과 부분 실패

  • 동일 target에 유효한 원본 보존 comment가 이미 있고 현재 body가 유효한 Discovery 초안이면 새 comment나 body write 없이 완료 상태를 readback한다.
  • comment write 응답이 timeout 또는 오류이면 재시도하지 않는다. comment 목록을 한 번 조정해 baseline 대비 exact 신규 comment 하나만 확인될 때만 계속한다.
  • 원본 comment는 게시됐지만 Issue body가 아직 원본과 같다면 partial 상태로 간주한다. exact marker, digest, author와 원본 일치를 검증한 뒤 기존 comment를 재사용하여 body 교체만 재개한다.
  • 원본 comment가 여러 개이거나 marker/digest가 잘못됐거나 현재 body가 원본 및 유효한 Discovery 어느 쪽과도 일치하지 않으면 자동 복구하지 않는다.
  • Issue body update가 불확실하면 다시 update하지 않고 exact Issue를 한 번 readback해 결과를 판정한다.

금지 사항

  • 현재 README와 TEMPLATE의 규칙을 이 스킬에서 재정의하지 않는다.
  • repository cache의 dirty, malformed 또는 drift 상태를 자동 삭제·초기화·덮어쓰기하지 않는다.
  • stale하거나 Gitea authoritative SHA와 일치하지 않는 cache를 Discovery 근거로 사용하지 않는다.
  • 읽지 않은 파일이나 실행하지 않은 검증을 저장소 근거로 제시하지 않는다.
  • 추천안을 사용자의 확정된 결정으로 표현하지 않는다.
  • credential, token 또는 환경변수 값을 출력하거나 산출물에 포함하지 않는다.
  • 원본 보존 comment 확인 전에 Issue body를 교체하지 않는다.
  • 성공 여부가 불확실한 외부 write를 blind retry하지 않는다.

검증 및 보고

완료 전에 다음을 모두 확인하고 구분해 보고한다.

  • authenticated stable account identity와 adapter provenance
  • repository cache 경로, 신규 초기화 또는 기존 재사용 여부, fetch 결과, bare 상태, pinned branch와 Gitea/local SHA 일치
  • 원본 Issue snapshot과 comment baseline
  • 조사한 repository evidence
  • Discovery 문서의 형식 검증·내용 검토 결과와 미해결 질문 여부
  • 문서 영향 및 산출물의 문서별 조치와 검증 결과
  • 원본 보존 comment ID, author, marker와 digest readback
  • Issue body exact readback과 비본문 필드 불변성
  • 최종 comment cardinality와 중복 원본 comment 부재
  • dry-run/local 검증과 실제 Gitea write 결과

프로세스 exit나 API write 응답만으로 성공을 주장하지 않는다. Authoritative readback이 하나라도 실패하면 partial 또는 failure로 보고한다.

Issue body 교체에는 공통 access 지침의 Issue body update의 provider-derived readback을 적용한다. 13번의 post-comment snapshot을 body update 직전 baseline으로 사용한다. Comment 작성의 정상 파생 변경은 해당 comment operation의 확인된 계약으로 별도 대조하며 body update의 revision 증가 규칙을 comment write에 적용하지 않는다. content_version의 노출·matching provider contract 근거를 기록하고 15번의 다른 snapshot 필드 비교는 보호 필드 보존과 확인된 operation별 provider-derived 변경 검증으로 구분한다. Write 전 drift 검사는 유지하며 불확실한 결과를 완료로 추정하거나 자동 재write하지 않는다.