Define CSV export behavior for issue activity #1

Closed
opened 2026-09-12 03:26:53 +00:00 by gitea-spec-agent · 6 comments
Collaborator

디스커버리 초안

원본 사용자 요청

배경

저장소 유지관리자는 오프라인 검토 및 감사를 위해 이슈의 활동 기록을 간단하게 내보낼 수 있는 방법이 필요합니다.

디스커버리 목표

구현 전에 다음을 포함한 예상 동작을 정의합니다.

  • 포함할 이벤트(댓글, 레이블 변경, 담당자 변경, 상태 전환)
  • CSV 열과 순서
  • 타임스탬프 및 시간대 표현
  • 삭제되거나 수정된 댓글의 처리
  • 권한 및 비공개 데이터 제약 사항
  • 활동량이 많은 이슈의 처리 방식

게이트 카나리

이 이슈는 의도적으로 열림 상태에서 **spec-agent**에게 할당되고 레이블이 없는 상태로 시작합니다. 결정론적 읽기 전용 게이트는 이를 초기 디스커버리 접수 후보로 인식하고, Gitea 상태를 변경하지 않은 채 wakeAgent=true를 반환해야 합니다.

이 테스트 이슈에서는 프로덕션 구현을 요청하지 않습니다.

요약

권한이 있는 사용자가 이슈 활동을 오프라인에서 검토하고 감사할 수 있도록 댓글, 레이블 변경, 담당자 변경 및 상태 전환을 하나의 고정된 와이드 CSV 스키마로 내보내는 동작 명세를 정의합니다. 이번 범위는 프로덕션 구현이 아닌 명세 작성입니다.

문제

이슈 활동을 오프라인 검토와 감사에 사용할 수 있도록 내보내기 범위와 CSV 표현 방식을 정의해야 합니다. 댓글, 레이블 변경, 담당자 변경 및 상태 전환만 포함하고, 공통 열 뒤에 이벤트별 열이 이어지는 하나의 고정된 와이드 스키마를 사용합니다. 열 순서는 `event_id`, `event_type`, `occurred_at`, `actor_id`, `actor_login`, `subject_type`, `old_value`, `new_value`, `comment_id`, `comment_body`로 고정합니다. 이벤트 정렬, 타임스탬프, 수정 및 삭제된 댓글, 권한, 비공개 데이터, 대규모 활동 기록 및 CSV 직렬화에 대한 일관된 계약도 정의해야 합니다.

포함 범위

  • 댓글, 레이블 변경, 담당자 변경 및 상태 전환 이벤트만 포함하는 내보내기 동작 정의
  • 공통 열 뒤에 이벤트별 열이 이어지는 하나의 고정된 와이드 CSV 스키마 정의
  • CSV 열 순서를 `event_id`, `event_type`, `occurred_at`, `actor_id`, `actor_login`, `subject_type`, `old_value`, `new_value`, `comment_id`, `comment_body`로 고정
  • 오래된 이벤트부터 정렬하고 타임스탬프가 같으면 안정적인 이벤트 식별자로 순서를 결정하는 방식 정의
  • UTC로 정규화하고 `Z` 접미사를 붙인 RFC 3339 타임스탬프 형식 정의
  • 수정된 댓글의 현재 본문과 `created_at`, `updated_at` 메타데이터 처리 방식 정의
  • 삭제된 댓글의 메타데이터와 본문 제외를 나타내는 툼스톤 행 처리 방식 정의
  • 현재 이슈 열람 권한과 현재 공개 범위 규칙을 적용하는 권한 모델 정의
  • 안정적인 내부 ID와 공개 가능한 표시 값을 사용하고 제한된 필드는 빈 값으로 유지하는 방식 정의
  • 활동 기록이 많은 이슈에서 완전한 CSV를 스트리밍하고 서버 제한 초과 시 명시적으로 실패하는 방식 정의
  • UTF-8, RFC 4180 호환 인용, CRLF 레코드, 헤더 행 및 빈 필드 표현 정의
  • 수식으로 해석될 수 있는 값에 접두사를 붙이고 변환 방식을 문서화하는 방식 정의

제외 범위

  • 내보내기 기능의 프로덕션 구현
  • 이슈 상태, 담당자, 레이블, 댓글 또는 기타 저장소 데이터의 변경
  • 저장소 전체, 조직 전체 또는 여러 저장소에 걸친 활동 내보내기
  • CSV로 필수 데이터를 표현할 수 없는 이유를 명확히 하는 데 필요한 경우를 제외한 비 CSV 내보내기 형식
  • 보존 정책 또는 감사 정책의 변경
  • 댓글, 레이블 변경, 담당자 변경 및 상태 전환 이외의 활동 이벤트 내보내기

제약 조건

  • 결과물은 프로덕션 코드가 아닌 동작 명세입니다.
  • 내보내기 형식은 CSV입니다.
  • 내보내기 생성 과정은 이슈와 저장소 상태에 대해 읽기 전용이어야 합니다.
  • 포함 이벤트는 댓글, 레이블 변경, 담당자 변경 및 상태 전환으로 제한합니다.
  • CSV는 공통 열 뒤에 이벤트별 열이 이어지는 하나의 고정된 와이드 스키마를 사용합니다.
  • CSV 열 순서는 `event_id`, `event_type`, `occurred_at`, `actor_id`, `actor_login`, `subject_type`, `old_value`, `new_value`, `comment_id`, `comment_body`로 고정합니다.
  • 이벤트는 오래된 순서로 정렬하고 타임스탬프가 같으면 안정적인 이벤트 식별자로 순서를 결정합니다.
  • 타임스탬프는 UTC로 정규화하고 `Z` 접미사를 붙인 RFC 3339 형식으로 표현합니다.
  • 수정된 댓글은 현재 본문과 `created_at`, `updated_at` 메타데이터를 포함합니다.
  • 삭제된 댓글은 메타데이터를 포함하되 삭제된 본문은 제외한 툼스톤 행으로 표현합니다.
  • 내보내기 접근에는 현재 이슈 열람 권한을 요구하고 모든 이벤트와 필드에 현재 공개 범위 규칙을 적용합니다.
  • 행위자 및 댓글 데이터는 안정적인 내부 ID와 공개 가능한 표시 값을 사용하며 제한된 필드는 빈 값으로 유지합니다.
  • 활동 기록이 많은 이슈에서는 완전한 CSV를 스트리밍하고 문서화된 서버 제한을 초과하면 명시적으로 실패합니다.
  • CSV는 UTF-8, RFC 4180 호환 인용, CRLF 레코드 및 헤더 행을 사용하며 값이 없으면 빈 필드로 표현합니다.
  • 수식으로 해석될 수 있는 문자로 시작하는 값에는 접두사를 붙이고 변환 방식을 문서화합니다.
  • 제공된 저장소 소스와 요구사항 인덱스에서는 저장소별 요구 사항이나 구현 규칙을 확인할 수 없습니다.

확정된 결정

  • OQ-001: CSV에 어떤 활동 이벤트를 포함해야 합니까? → 댓글, 레이블 변경, 담당자 변경 및 상태 전환만 포함
  • OQ-002: CSV 스키마에서 서로 다른 이벤트 유형을 어떻게 표현해야 합니까? → 공통 열 뒤에 이벤트별 열이 이어지는 하나의 고정된 와이드 스키마 사용
  • OQ-003: 내보내기에 사용할 공통 열과 순서는 무엇입니까? → 열 순서: `event_id`, `event_type`, `occurred_at`, `actor_id`, `actor_login`, `subject_type`, `old_value`, `new_value`, `comment_id`, `comment_body`
  • OQ-004: 내보낸 이벤트의 순서를 어떻게 정해야 합니까? → 오래된 이벤트부터 정렬하고, 타임스탬프가 같으면 안정적인 이벤트 식별자로 순서를 결정
  • OQ-005: 타임스탬프와 시간대를 어떻게 표현해야 합니까? → UTC로 정규화하고 `Z` 접미사를 붙인 RFC 3339 타임스탬프 사용
  • OQ-006: 수정된 댓글을 내보내기에 어떻게 표시해야 합니까? → 현재 본문만 내보내고 `created_at` 및 `updated_at` 메타데이터 포함
  • OQ-007: 삭제된 댓글을 내보내기에 어떻게 표시해야 합니까? → 메타데이터는 포함하되 삭제된 본문은 제외한 툼스톤 행 포함
  • OQ-008: 어떤 권한 모델로 내보내기 접근을 통제해야 합니까? → 현재 이슈 열람 권한을 요구하고, 모든 이벤트와 필드에 현재 공개 범위 규칙을 적용
  • OQ-009: 잠재적으로 비공개인 행위자 및 댓글 데이터를 어떻게 표현해야 합니까? → 안정적인 내부 ID와 공개 가능한 표시 값을 내보내고, 제한된 필드는 빈 값으로 유지
  • OQ-010: 활동 기록이 많은 이슈에는 어떤 동작을 적용해야 합니까? → 완전한 CSV를 스트리밍하고, 문서화된 서버 제한을 초과하면 명시적으로 실패
  • OQ-011: CSV 인코딩, 이스케이프 및 값이 없는 경우의 표현을 어떻게 정의해야 합니까? → UTF-8, RFC 4180 호환 인용, CRLF 레코드, 헤더 행 및 값이 없는 경우 빈 필드 사용
  • OQ-012: 텍스트 필드의 스프레드시트 수식 삽입 위험을 어떻게 처리해야 합니까? → 수식으로 해석될 수 있는 문자로 시작하는 값에 접두사를 붙이고 변환 방식을 문서화

저장소 근거

없음.

문서 영향 및 산출물

user-guide / none

  • 대상 유형: logical-area
  • 대상: 사용자 안내
  • 관련 미해결 질문: 없음
  • 독자: 기능 사용자
  • 핵심 내용: 없음
  • 검증: 프로덕션 기능이나 사용자용 사용 절차를 추가하지 않으므로 사용자 안내 문서 변경이 없는지 확인합니다.
  • 근거: 이번 이슈는 확정된 CSV 동작 명세 작성만을 범위로 하며 프로덕션 구현이나 사용자 기능 변경을 포함하지 않습니다.

operations-runbook / none

  • 대상 유형: logical-area
  • 대상: 운영 절차
  • 관련 미해결 질문: 없음
  • 독자: 저장소 운영자
  • 핵심 내용: 없음
  • 검증: 실행 가능한 운영 절차나 서버 설정 변경이 추가되지 않았는지 확인합니다.
  • 근거: 내보내기 기능의 운영 배포나 실행 절차를 정의하는 구현 작업은 범위 밖입니다.

cli-api-contract / none

  • 대상 유형: logical-area
  • 대상: 명령줄 및 API 계약
  • 관련 미해결 질문: 없음
  • 독자: 통합 개발자
  • 핵심 내용: 없음
  • 검증: 명령줄 또는 API의 구현 계약을 새로 만들거나 변경하지 않는지 확인합니다.
  • 근거: CSV 동작 규칙은 정의하지만 명령줄 또는 API 구현과 공개 인터페이스 변경은 범위에 포함하지 않습니다.

schema-configuration / none

  • 대상 유형: logical-area
  • 대상: 스키마 및 설정
  • 관련 미해결 질문: 없음
  • 독자: 구현 개발자
  • 핵심 내용: 없음
  • 검증: 확정된 CSV 열 순서와 직렬화 규칙이 구현 문서가 아닌 본 명세에만 반영되는지 확인합니다.
  • 근거: 고정된 CSV 스키마와 직렬화 제약은 동작 명세로 확정하지만 저장 형식이나 설정 파일 구현은 범위 밖입니다.

migration-compatibility / none

  • 대상 유형: logical-area
  • 대상: 마이그레이션 및 호환성
  • 관련 미해결 질문: 없음
  • 독자: 유지관리자
  • 핵심 내용: 없음
  • 검증: 기존 데이터, 저장소 구조 또는 공개 인터페이스의 마이그레이션이 요구되지 않는지 확인합니다.
  • 근거: 기존 데이터나 공개 인터페이스를 변경하는 구현이 없으므로 마이그레이션 및 호환성 문서 변경은 필요하지 않습니다.

release-notes / none

  • 대상 유형: logical-area
  • 대상: 릴리스 노트
  • 관련 미해결 질문: 없음
  • 독자: 프로젝트 사용자
  • 핵심 내용: 없음
  • 검증: 배포 가능한 기능 변경이나 릴리스 대상이 생성되지 않았는지 확인합니다.
  • 근거: 이번 결과물은 프로덕션 구현이 아닌 동작 명세이므로 릴리스 노트 변경 대상이 없습니다.

미해결 질문

없음.

<!-- gitea-agent:discovery-draft/v2 --> <!-- gitea-agent:discovery-state/v7 eyJjb25maXJtZWRfZGVjaXNpb25zIjpbeyJjaG9pY2UiOiLrjJPquIAsIOugiOydtOu4lCDrs4Dqsr0sIOuLtOuLueyekCDrs4Dqsr0g67CPIOyDge2DnCDsoITtmZjrp4wg7Y+s7ZWoIiwiaWQiOiJPUS0wMDEiLCJxdWVzdGlvbiI6IkNTVuyXkCDslrTrlqQg7Zmc64+ZIOydtOuypO2KuOulvCDtj6ztlajtlbTslbwg7ZWp64uI6rmMPyJ9LHsiY2hvaWNlIjoi6rO17Ya1IOyXtCDrkqTsl5Ag7J2067Kk7Yq467OEIOyXtOydtCDsnbTslrTsp4DripQg7ZWY64KY7J2YIOqzoOygleuQnCDsmYDsnbTrk5wg7Iqk7YKk66eIIOyCrOyaqSIsImlkIjoiT1EtMDAyIiwicXVlc3Rpb24iOiJDU1Yg7Iqk7YKk66eI7JeQ7IScIOyEnOuhnCDri6Trpbgg7J2067Kk7Yq4IOycoO2YleydhCDslrTrlrvqsowg7ZGc7ZiE7ZW07JW8IO2VqeuLiOq5jD8ifSx7ImNob2ljZSI6IuyXtCDsiJzshJw6IGBldmVudF9pZGAsIGBldmVudF90eXBlYCwgYG9jY3VycmVkX2F0YCwgYGFjdG9yX2lkYCwgYGFjdG9yX2xvZ2luYCwgYHN1YmplY3RfdHlwZWAsIGBvbGRfdmFsdWVgLCBgbmV3X3ZhbHVlYCwgYGNvbW1lbnRfaWRgLCBgY29tbWVudF9ib2R5YCIsImlkIjoiT1EtMDAzIiwicXVlc3Rpb24iOiLrgrTrs7TrgrTquLDsl5Ag7IKs7Jqp7ZWgIOqzte2GtSDsl7Tqs7wg7Iic7ISc64qUIOustOyXh+yeheuLiOq5jD8ifSx7ImNob2ljZSI6IuyYpOuemOuQnCDsnbTrsqTtirjrtoDthLAg7KCV66Cs7ZWY6rOgLCDtg4DsnoTsiqTtg6ztlITqsIAg6rCZ7Jy866m0IOyViOygleyggeyduCDsnbTrsqTtirgg7Iud67OE7J6Q66GcIOyInOyEnOulvCDqsrDsoJUiLCJpZCI6Ik9RLTAwNCIsInF1ZXN0aW9uIjoi64K067O064K4IOydtOuypO2KuOydmCDsiJzshJzrpbwg7Ja065a76rKMIOygle2VtOyVvCDtlanri4jquYw/In0seyJjaG9pY2UiOiJVVEProZwg7KCV6rec7ZmU7ZWY6rOgIGBaYCDsoJHrr7jsgqzrpbwg67aZ7J24IFJGQyAzMzM5IO2DgOyehOyKpO2DrO2UhCDsgqzsmqkiLCJpZCI6Ik9RLTAwNSIsInF1ZXN0aW9uIjoi7YOA7J6E7Iqk7YOs7ZSE7JmAIOyLnOqwhOuMgOulvCDslrTrlrvqsowg7ZGc7ZiE7ZW07JW8IO2VqeuLiOq5jD8ifSx7ImNob2ljZSI6Iu2YhOyerCDrs7jrrLjrp4wg64K067O064K06rOgIGBjcmVhdGVkX2F0YCDrsI8gYHVwZGF0ZWRfYXRgIOuplO2DgOuNsOydtO2EsCDtj6ztlagiLCJpZCI6Ik9RLTAwNiIsInF1ZXN0aW9uIjoi7IiY7KCV65CcIOuMk+q4gOydhCDrgrTrs7TrgrTquLDsl5Ag7Ja065a76rKMIO2RnOyLnO2VtOyVvCDtlanri4jquYw/In0seyJjaG9pY2UiOiLrqZTtg4DrjbDsnbTthLDripQg7Y+s7ZWo7ZWY65CYIOyCreygnOuQnCDrs7jrrLjsnYAg7KCc7Jm47ZWcIO2IvOyKpO2GpCDtlokg7Y+s7ZWoIiwiaWQiOiJPUS0wMDciLCJxdWVzdGlvbiI6IuyCreygnOuQnCDrjJPquIDsnYQg64K067O064K06riw7JeQIOyWtOuWu+qyjCDtkZzsi5ztlbTslbwg7ZWp64uI6rmMPyJ9LHsiY2hvaWNlIjoi7ZiE7J6sIOydtOyKiCDsl7Trnowg6raM7ZWc7J2EIOyalOq1rO2VmOqzoCwg66qo65OgIOydtOuypO2KuOyZgCDtlYTrk5zsl5Ag7ZiE7J6sIOqzteqwnCDrspTsnIQg6rec7LmZ7J2EIOyggeyaqSIsImlkIjoiT1EtMDA4IiwicXVlc3Rpb24iOiLslrTrlqQg6raM7ZWcIOuqqOuNuOuhnCDrgrTrs7TrgrTquLAg7KCR6re87J2EIO2GteygnO2VtOyVvCDtlanri4jquYw/In0seyJjaG9pY2UiOiLslYjsoJXsoIHsnbgg64K067aAIElE7JmAIOqzteqwnCDqsIDriqXtlZwg7ZGc7IucIOqwkuydhCDrgrTrs7TrgrTqs6AsIOygnO2VnOuQnCDtlYTrk5zripQg67mIIOqwkuycvOuhnCDsnKDsp4AiLCJpZCI6Ik9RLTAwOSIsInF1ZXN0aW9uIjoi7J6g7J6s7KCB7Jy866GcIOu5hOqzteqwnOyduCDtlonsnITsnpAg67CPIOuMk+q4gCDrjbDsnbTthLDrpbwg7Ja065a76rKMIO2RnO2YhO2VtOyVvCDtlanri4jquYw/In0seyJjaG9pY2UiOiLsmYTsoITtlZwgQ1NW66W8IOyKpO2KuOumrOuwje2VmOqzoCwg66y47ISc7ZmU65CcIOyEnOuyhCDsoJztlZzsnYQg7LSI6rO87ZWY66m0IOuqheyLnOyggeycvOuhnCDsi6TtjKgiLCJpZCI6Ik9RLTAxMCIsInF1ZXN0aW9uIjoi7Zmc64+ZIOq4sOuhneydtCDrp47snYAg7J207IqI7JeQ64qUIOyWtOuWpCDrj5nsnpHsnYQg7KCB7Jqp7ZW07JW8IO2VqeuLiOq5jD8ifSx7ImNob2ljZSI6IlVURi04LCBSRkMgNDE4MCDtmLjtmZgg7J247JqpLCBDUkxGIOugiOy9lOuTnCwg7Zek642UIO2WiSDrsI8g6rCS7J20IOyXhuuKlCDqsr3smrAg67mIIO2VhOuTnCDsgqzsmqkiLCJpZCI6Ik9RLTAxMSIsInF1ZXN0aW9uIjoiQ1NWIOyduOy9lOuUqSwg7J207Iqk7LyA7J207ZSEIOuwjyDqsJLsnbQg7JeG64qUIOqyveyasOydmCDtkZztmITsnYQg7Ja065a76rKMIOygleydmO2VtOyVvCDtlanri4jquYw/In0seyJjaG9pY2UiOiLsiJjsi53snLzroZwg7ZW07ISd65CgIOyImCDsnojripQg66y47J6Q66GcIOyLnOyeke2VmOuKlCDqsJLsl5Ag7KCR65GQ7IKs66W8IOu2meydtOqzoCDrs4DtmZgg67Cp7Iud7J2EIOusuOyEnO2ZlCIsImlkIjoiT1EtMDEyIiwicXVlc3Rpb24iOiLthY3siqTtirgg7ZWE65Oc7J2YIOyKpO2UhOugiOuTnOyLnO2KuCDsiJjsi50g7IK97J6FIOychO2XmOydhCDslrTrlrvqsowg7LKY66as7ZW07JW8IO2VqeuLiOq5jD8ifV0sImNvbnN0cmFpbnRzIjpbIuqysOqzvOusvOydgCDtlITroZzrjZXshZgg7L2U65Oc6rCAIOyVhOuLjCDrj5nsnpEg66qF7IS47J6F64uI64ukLiIsIuuCtOuztOuCtOq4sCDtmJXsi53snYAgQ1NW7J6F64uI64ukLiIsIuuCtOuztOuCtOq4sCDsg53shLEg6rO87KCV7J2AIOydtOyKiOyZgCDsoIDsnqXshowg7IOB7YOc7JeQIOuMgO2VtCDsnb3quLAg7KCE7Jqp7J207Ja07JW8IO2VqeuLiOuLpC4iLCLtj6ztlagg7J2067Kk7Yq464qUIOuMk+q4gCwg66CI7J2067iUIOuzgOqyvSwg64u064u57J6QIOuzgOqyvSDrsI8g7IOB7YOcIOyghO2ZmOycvOuhnCDsoJztlZztlanri4jri6QuIiwiQ1NW64qUIOqzte2GtSDsl7Qg65Kk7JeQIOydtOuypO2KuOuzhCDsl7TsnbQg7J207Ja07KeA64qUIO2VmOuCmOydmCDqs6DsoJXrkJwg7JmA7J2065OcIOyKpO2CpOuniOulvCDsgqzsmqntlanri4jri6QuIiwiQ1NWIOyXtCDsiJzshJzripQgYGV2ZW50X2lkYCwgYGV2ZW50X3R5cGVgLCBgb2NjdXJyZWRfYXRgLCBgYWN0b3JfaWRgLCBgYWN0b3JfbG9naW5gLCBgc3ViamVjdF90eXBlYCwgYG9sZF92YWx1ZWAsIGBuZXdfdmFsdWVgLCBgY29tbWVudF9pZGAsIGBjb21tZW50X2JvZHlg66GcIOqzoOygle2VqeuLiOuLpC4iLCLsnbTrsqTtirjripQg7Jik656Y65CcIOyInOyEnOuhnCDsoJXroKztlZjqs6Ag7YOA7J6E7Iqk7YOs7ZSE6rCAIOqwmeycvOuptCDslYjsoJXsoIHsnbgg7J2067Kk7Yq4IOyLneuzhOyekOuhnCDsiJzshJzrpbwg6rKw7KCV7ZWp64uI64ukLiIsIu2DgOyehOyKpO2DrO2UhOuKlCBVVEProZwg7KCV6rec7ZmU7ZWY6rOgIGBaYCDsoJHrr7jsgqzrpbwg67aZ7J24IFJGQyAzMzM5IO2YleyLneycvOuhnCDtkZztmITtlanri4jri6QuIiwi7IiY7KCV65CcIOuMk+q4gOydgCDtmITsnqwg67O466y46rO8IGBjcmVhdGVkX2F0YCwgYHVwZGF0ZWRfYXRgIOuplO2DgOuNsOydtO2EsOulvCDtj6ztlajtlanri4jri6QuIiwi7IKt7KCc65CcIOuMk+q4gOydgCDrqZTtg4DrjbDsnbTthLDrpbwg7Y+s7ZWo7ZWY65CYIOyCreygnOuQnCDrs7jrrLjsnYAg7KCc7Jm47ZWcIO2IvOyKpO2GpCDtlonsnLzroZwg7ZGc7ZiE7ZWp64uI64ukLiIsIuuCtOuztOuCtOq4sCDsoJHqt7zsl5DripQg7ZiE7J6sIOydtOyKiCDsl7Trnowg6raM7ZWc7J2EIOyalOq1rO2VmOqzoCDrqqjrk6Ag7J2067Kk7Yq47JmAIO2VhOuTnOyXkCDtmITsnqwg6rO16rCcIOuylOychCDqt5zsuZnsnYQg7KCB7Jqp7ZWp64uI64ukLiIsIu2WieychOyekCDrsI8g64yT6riAIOuNsOydtO2EsOuKlCDslYjsoJXsoIHsnbgg64K067aAIElE7JmAIOqzteqwnCDqsIDriqXtlZwg7ZGc7IucIOqwkuydhCDsgqzsmqntlZjrqbAg7KCc7ZWc65CcIO2VhOuTnOuKlCDruYgg6rCS7Jy866GcIOycoOyngO2VqeuLiOuLpC4iLCLtmZzrj5kg6riw66Gd7J20IOunjuydgCDsnbTsiojsl5DshJzripQg7JmE7KCE7ZWcIENTVuulvCDsiqTtirjrpqzrsI3tlZjqs6Ag66y47ISc7ZmU65CcIOyEnOuyhCDsoJztlZzsnYQg7LSI6rO87ZWY66m0IOuqheyLnOyggeycvOuhnCDsi6TtjKjtlanri4jri6QuIiwiQ1NW64qUIFVURi04LCBSRkMgNDE4MCDtmLjtmZgg7J247JqpLCBDUkxGIOugiOy9lOuTnCDrsI8g7Zek642UIO2WieydhCDsgqzsmqntlZjrqbAg6rCS7J20IOyXhuycvOuptCDruYgg7ZWE65Oc66GcIO2RnO2YhO2VqeuLiOuLpC4iLCLsiJjsi53snLzroZwg7ZW07ISd65CgIOyImCDsnojripQg66y47J6Q66GcIOyLnOyeke2VmOuKlCDqsJLsl5DripQg7KCR65GQ7IKs66W8IOu2meydtOqzoCDrs4DtmZgg67Cp7Iud7J2EIOusuOyEnO2ZlO2VqeuLiOuLpC4iLCLsoJzqs7XrkJwg7KCA7J6l7IaMIOyGjOyKpOyZgCDsmpTqtazsgqztla0g7J24642x7Iqk7JeQ7ISc64qUIOyggOyepeyGjOuzhCDsmpTqtawg7IKs7ZWt7J2064KYIOq1rO2YhCDqt5zsuZnsnYQg7ZmV7J247ZWgIOyImCDsl4bsirXri4jri6QuIl0sImNvbnRyYWN0X3ZlcnNpb24iOiJkaXNjb3Zlcnktc3RhdGUvdjciLCJkb2N1bWVudGF0aW9uX2ltcGFjdCI6W3siYWN0aW9uIjoibm9uZSIsImF1ZGllbmNlIjoi6riw64qlIOyCrOyaqeyekCIsImNhdGVnb3J5IjoidXNlci1ndWlkZSIsImtleV90b3BpY3MiOltdLCJvcGVuX3F1ZXN0aW9uIjpudWxsLCJyZWFzb24iOiLsnbTrsogg7J207IqI64qUIO2ZleygleuQnCBDU1Yg64+Z7J6RIOuqheyEuCDsnpHshLHrp4zsnYQg67KU7JyE66GcIO2VmOupsCDtlITroZzrjZXshZgg6rWs7ZiE7J2064KYIOyCrOyaqeyekCDquLDriqUg67OA6rK97J2EIO2PrO2VqO2VmOyngCDslYrsirXri4jri6QuIiwidGFyZ2V0Ijoi7IKs7Jqp7J6QIOyViOuCtCIsInRhcmdldF90eXBlIjoibG9naWNhbC1hcmVhIiwidmFsaWRhdGlvbiI6Iu2UhOuhnOuNleyFmCDquLDriqXsnbTrgpgg7IKs7Jqp7J6Q7JqpIOyCrOyaqSDsoIjssKjrpbwg7LaU6rCA7ZWY7KeAIOyViuycvOuvgOuhnCDsgqzsmqnsnpAg7JWI64K0IOusuOyEnCDrs4Dqsr3snbQg7JeG64qU7KeAIO2ZleyduO2VqeuLiOuLpC4ifSx7ImFjdGlvbiI6Im5vbmUiLCJhdWRpZW5jZSI6IuyggOyepeyGjCDsmrTsmIHsnpAiLCJjYXRlZ29yeSI6Im9wZXJhdGlvbnMtcnVuYm9vayIsImtleV90b3BpY3MiOltdLCJvcGVuX3F1ZXN0aW9uIjpudWxsLCJyZWFzb24iOiLrgrTrs7TrgrTquLAg6riw64ql7J2YIOyatOyYgSDrsLDtj6zrgpgg7Iuk7ZaJIOygiOywqOulvCDsoJXsnZjtlZjripQg6rWs7ZiEIOyekeyXheydgCDrspTsnIQg67CW7J6F64uI64ukLiIsInRhcmdldCI6IuyatOyYgSDsoIjssKgiLCJ0YXJnZXRfdHlwZSI6ImxvZ2ljYWwtYXJlYSIsInZhbGlkYXRpb24iOiLsi6Ttlokg6rCA64ql7ZWcIOyatOyYgSDsoIjssKjrgpgg7ISc67KEIOyEpOyglSDrs4Dqsr3snbQg7LaU6rCA65CY7KeAIOyViuyVmOuKlOyngCDtmZXsnbjtlanri4jri6QuIn0seyJhY3Rpb24iOiJub25lIiwiYXVkaWVuY2UiOiLthrXtlakg6rCc67Cc7J6QIiwiY2F0ZWdvcnkiOiJjbGktYXBpLWNvbnRyYWN0Iiwia2V5X3RvcGljcyI6W10sIm9wZW5fcXVlc3Rpb24iOm51bGwsInJlYXNvbiI6IkNTViDrj5nsnpEg6rec7LmZ7J2AIOygleydmO2VmOyngOunjCDrqoXroLnspIQg65iQ64qUIEFQSSDqtaztmITqs7wg6rO16rCcIOyduO2EsO2OmOydtOyKpCDrs4Dqsr3snYAg67KU7JyE7JeQIO2PrO2VqO2VmOyngCDslYrsirXri4jri6QuIiwidGFyZ2V0Ijoi66qF66C57KSEIOuwjyBBUEkg6rOE7JW9IiwidGFyZ2V0X3R5cGUiOiJsb2dpY2FsLWFyZWEiLCJ2YWxpZGF0aW9uIjoi66qF66C57KSEIOuYkOuKlCBBUEnsnZgg6rWs7ZiEIOqzhOyVveydhCDsg4jroZwg66eM65Ok6rGw64KYIOuzgOqyve2VmOyngCDslYrripTsp4Ag7ZmV7J247ZWp64uI64ukLiJ9LHsiYWN0aW9uIjoibm9uZSIsImF1ZGllbmNlIjoi6rWs7ZiEIOqwnOuwnOyekCIsImNhdGVnb3J5Ijoic2NoZW1hLWNvbmZpZ3VyYXRpb24iLCJrZXlfdG9waWNzIjpbXSwib3Blbl9xdWVzdGlvbiI6bnVsbCwicmVhc29uIjoi6rOg7KCV65CcIENTViDsiqTtgqTrp4jsmYAg7KeB66Cs7ZmUIOygnOyVveydgCDrj5nsnpEg66qF7IS466GcIO2Zleygle2VmOyngOunjCDsoIDsnqUg7ZiV7Iud7J2064KYIOyEpOyglSDtjIzsnbwg6rWs7ZiE7J2AIOuylOychCDrsJbsnoXri4jri6QuIiwidGFyZ2V0Ijoi7Iqk7YKk66eIIOuwjyDshKTsoJUiLCJ0YXJnZXRfdHlwZSI6ImxvZ2ljYWwtYXJlYSIsInZhbGlkYXRpb24iOiLtmZXsoJXrkJwgQ1NWIOyXtCDsiJzshJzsmYAg7KeB66Cs7ZmUIOq3nOy5meydtCDqtaztmIQg66y47ISc6rCAIOyVhOuLjCDrs7gg66qF7IS47JeQ66eMIOuwmOyYgeuQmOuKlOyngCDtmZXsnbjtlanri4jri6QuIn0seyJhY3Rpb24iOiJub25lIiwiYXVkaWVuY2UiOiLsnKDsp4DqtIDrpqzsnpAiLCJjYXRlZ29yeSI6Im1pZ3JhdGlvbi1jb21wYXRpYmlsaXR5Iiwia2V5X3RvcGljcyI6W10sIm9wZW5fcXVlc3Rpb24iOm51bGwsInJlYXNvbiI6Iuq4sOyhtCDrjbDsnbTthLDrgpgg6rO16rCcIOyduO2EsO2OmOydtOyKpOulvCDrs4Dqsr3tlZjripQg6rWs7ZiE7J20IOyXhuycvOuvgOuhnCDrp4jsnbTqt7jroIjsnbTshZgg67CPIO2YuO2ZmOyEsSDrrLjshJwg67OA6rK97J2AIO2VhOyalO2VmOyngCDslYrsirXri4jri6QuIiwidGFyZ2V0Ijoi66eI7J206re466CI7J207IWYIOuwjyDtmLjtmZjshLEiLCJ0YXJnZXRfdHlwZSI6ImxvZ2ljYWwtYXJlYSIsInZhbGlkYXRpb24iOiLquLDsobQg642w7J207YSwLCDsoIDsnqXshowg6rWs7KGwIOuYkOuKlCDqs7XqsJwg7J247YSw7Y6Y7J207Iqk7J2YIOuniOydtOq3uOugiOydtOyFmOydtCDsmpTqtazrkJjsp4Ag7JWK64qU7KeAIO2ZleyduO2VqeuLiOuLpC4ifSx7ImFjdGlvbiI6Im5vbmUiLCJhdWRpZW5jZSI6Iu2UhOuhnOygne2KuCDsgqzsmqnsnpAiLCJjYXRlZ29yeSI6InJlbGVhc2Utbm90ZXMiLCJrZXlfdG9waWNzIjpbXSwib3Blbl9xdWVzdGlvbiI6bnVsbCwicmVhc29uIjoi7J2067KIIOqysOqzvOusvOydgCDtlITroZzrjZXshZgg6rWs7ZiE7J20IOyVhOuLjCDrj5nsnpEg66qF7IS47J2066+A66GcIOumtOumrOyKpCDrhbjtirgg67OA6rK9IOuMgOyDgeydtCDsl4bsirXri4jri6QuIiwidGFyZ2V0Ijoi66a066as7IqkIOuFuO2KuCIsInRhcmdldF90eXBlIjoibG9naWNhbC1hcmVhIiwidmFsaWRhdGlvbiI6IuuwsO2PrCDqsIDriqXtlZwg6riw64qlIOuzgOqyveydtOuCmCDrprTrpqzsiqQg64yA7IOB7J20IOyDneyEseuQmOyngCDslYrslZjripTsp4Ag7ZmV7J247ZWp64uI64ukLiJ9XSwiaW5fc2NvcGUiOlsi64yT6riALCDroIjsnbTruJQg67OA6rK9LCDri7Tri7nsnpAg67OA6rK9IOuwjyDsg4Htg5wg7KCE7ZmYIOydtOuypO2KuOunjCDtj6ztlajtlZjripQg64K067O064K06riwIOuPmeyekSDsoJXsnZgiLCLqs7XthrUg7Je0IOuSpOyXkCDsnbTrsqTtirjrs4Qg7Je07J20IOydtOyWtOyngOuKlCDtlZjrgpjsnZgg6rOg7KCV65CcIOyZgOydtOuTnCBDU1Yg7Iqk7YKk66eIIOygleydmCIsIkNTViDsl7Qg7Iic7ISc66W8IGBldmVudF9pZGAsIGBldmVudF90eXBlYCwgYG9jY3VycmVkX2F0YCwgYGFjdG9yX2lkYCwgYGFjdG9yX2xvZ2luYCwgYHN1YmplY3RfdHlwZWAsIGBvbGRfdmFsdWVgLCBgbmV3X3ZhbHVlYCwgYGNvbW1lbnRfaWRgLCBgY29tbWVudF9ib2R5YOuhnCDqs6DsoJUiLCLsmKTrnpjrkJwg7J2067Kk7Yq467aA7YSwIOygleugrO2VmOqzoCDtg4DsnoTsiqTtg6ztlITqsIAg6rCZ7Jy866m0IOyViOygleyggeyduCDsnbTrsqTtirgg7Iud67OE7J6Q66GcIOyInOyEnOulvCDqsrDsoJXtlZjripQg67Cp7IudIOygleydmCIsIlVUQ+uhnCDsoJXqt5ztmZTtlZjqs6AgYFpgIOygkeuvuOyCrOulvCDrtpnsnbggUkZDIDMzMzkg7YOA7J6E7Iqk7YOs7ZSEIO2YleyLnSDsoJXsnZgiLCLsiJjsoJXrkJwg64yT6riA7J2YIO2YhOyerCDrs7jrrLjqs7wgYGNyZWF0ZWRfYXRgLCBgdXBkYXRlZF9hdGAg66mU7YOA642w7J207YSwIOyymOumrCDrsKnsi50g7KCV7J2YIiwi7IKt7KCc65CcIOuMk+q4gOydmCDrqZTtg4DrjbDsnbTthLDsmYAg67O466y4IOygnOyZuOulvCDrgpjtg4DrgrTripQg7Yi87Iqk7YakIO2WiSDsspjrpqwg67Cp7IudIOygleydmCIsIu2YhOyerCDsnbTsiogg7Je0656MIOq2jO2VnOqzvCDtmITsnqwg6rO16rCcIOuylOychCDqt5zsuZnsnYQg7KCB7Jqp7ZWY64qUIOq2jO2VnCDrqqjrjbgg7KCV7J2YIiwi7JWI7KCV7KCB7J24IOuCtOu2gCBJROyZgCDqs7XqsJwg6rCA64ql7ZWcIO2RnOyLnCDqsJLsnYQg7IKs7Jqp7ZWY6rOgIOygnO2VnOuQnCDtlYTrk5zripQg67mIIOqwkuycvOuhnCDsnKDsp4DtlZjripQg67Cp7IudIOygleydmCIsIu2ZnOuPmSDquLDroZ3snbQg66eO7J2AIOydtOyKiOyXkOyEnCDsmYTsoITtlZwgQ1NW66W8IOyKpO2KuOumrOuwje2VmOqzoCDshJzrsoQg7KCc7ZWcIOy0iOqzvCDsi5wg66qF7Iuc7KCB7Jy866GcIOyLpO2MqO2VmOuKlCDrsKnsi50g7KCV7J2YIiwiVVRGLTgsIFJGQyA0MTgwIO2YuO2ZmCDsnbjsmqksIENSTEYg66CI7L2U65OcLCDtl6TrjZQg7ZaJIOuwjyDruYgg7ZWE65OcIO2RnO2YhCDsoJXsnZgiLCLsiJjsi53snLzroZwg7ZW07ISd65CgIOyImCDsnojripQg6rCS7JeQIOygkeuRkOyCrOulvCDrtpnsnbTqs6Ag67OA7ZmYIOuwqeyLneydhCDrrLjshJztmZTtlZjripQg67Cp7IudIOygleydmCJdLCJvcGVuX3F1ZXN0aW9ucyI6W10sIm9yaWdpbmFsX3JlcXVlc3QiOiIjIyDrsLDqsr1cblxu7KCA7J6l7IaMIOycoOyngOq0gOumrOyekOuKlCDsmKTtlITrnbzsnbgg6rKA7YagIOuwjyDqsJDsgqzrpbwg7JyE7ZW0IOydtOyKiOydmCDtmZzrj5kg6riw66Gd7J2EIOqwhOuLqO2VmOqyjCDrgrTrs7Trgrwg7IiYIOyeiOuKlCDrsKnrspXsnbQg7ZWE7JqU7ZWp64uI64ukLlxuXG4jIyDrlJTsiqTsu6TrsoTrpqwg66qp7ZGcXG5cbuq1rO2YhCDsoITsl5Ag64uk7J2M7J2EIO2PrO2VqO2VnCDsmIjsg4Eg64+Z7J6R7J2EIOygleydmO2VqeuLiOuLpC5cblxuLSDtj6ztlajtlaAg7J2067Kk7Yq4KOuMk+q4gCwg66CI7J2067iUIOuzgOqyvSwg64u064u57J6QIOuzgOqyvSwg7IOB7YOcIOyghO2ZmClcbi0gQ1NWIOyXtOqzvCDsiJzshJxcbi0g7YOA7J6E7Iqk7YOs7ZSEIOuwjyDsi5zqsITrjIAg7ZGc7ZiEXG4tIOyCreygnOuQmOqxsOuCmCDsiJjsoJXrkJwg64yT6riA7J2YIOyymOumrFxuLSDqtoztlZwg67CPIOu5hOqzteqwnCDrjbDsnbTthLAg7KCc7JW9IOyCrO2VrVxuLSDtmZzrj5nrn4nsnbQg66eO7J2AIOydtOyKiOydmCDsspjrpqwg67Cp7IudXG5cbiMjIOqyjOydtO2KuCDsubTrgpjrpqxcblxu7J20IOydtOyKiOuKlCDsnZjrj4TsoIHsnLzroZwgKirsl7TrprwqKiDsg4Htg5zsl5DshJwgKipgc3BlYy1hZ2VudGAqKuyXkOqyjCDtlaDri7nrkJjqs6AgKirroIjsnbTruJTsnbQg7JeG64qUKiog7IOB7YOc66GcIOyLnOyeke2VqeuLiOuLpC4g6rKw7KCV66Gg7KCBIOydveq4sCDsoITsmqkg6rKM7J207Yq464qUIOydtOulvCDstIjquLAg65SU7Iqk7Luk67KE66asIOygkeyImCDtm4Trs7TroZwg7J247Iud7ZWY6rOgLCBHaXRlYSDsg4Htg5zrpbwg67OA6rK97ZWY7KeAIOyViuydgCDssYQgYHdha2VBZ2VudD10cnVlYOulvCDrsJjtmZjtlbTslbwg7ZWp64uI64ukLlxuXG7snbQg7YWM7Iqk7Yq4IOydtOyKiOyXkOyEnOuKlCDtlITroZzrjZXshZgg6rWs7ZiE7J2EIOyalOyyre2VmOyngCDslYrsirXri4jri6QuIiwib3V0X29mX3Njb3BlIjpbIuuCtOuztOuCtOq4sCDquLDriqXsnZgg7ZSE66Gc642V7IWYIOq1rO2YhCIsIuydtOyKiCDsg4Htg5wsIOuLtOuLueyekCwg66CI7J2067iULCDrjJPquIAg65iQ64qUIOq4sO2DgCDsoIDsnqXshowg642w7J207YSw7J2YIOuzgOqyvSIsIuyggOyepeyGjCDsoITssrQsIOyhsOyngSDsoITssrQg65iQ64qUIOyXrOufrCDsoIDsnqXshozsl5Ag6rG47LmcIO2ZnOuPmSDrgrTrs7TrgrTquLAiLCJDU1broZwg7ZWE7IiYIOuNsOydtO2EsOulvCDtkZztmITtlaAg7IiYIOyXhuuKlCDsnbTsnKDrpbwg66qF7ZmV7Z6IIO2VmOuKlCDrjbAg7ZWE7JqU7ZWcIOqyveyasOulvCDsoJzsmbjtlZwg67mEIENTViDrgrTrs7TrgrTquLAg7ZiV7IudIiwi67O07KG0IOygleyxhSDrmJDripQg6rCQ7IKsIOygleyxheydmCDrs4Dqsr0iLCLrjJPquIAsIOugiOydtOu4lCDrs4Dqsr0sIOuLtOuLueyekCDrs4Dqsr0g67CPIOyDge2DnCDsoITtmZgg7J207Jm47J2YIO2ZnOuPmSDsnbTrsqTtirgg64K067O064K06riwIl0sInByb2JsZW0iOiLsnbTsiogg7Zmc64+Z7J2EIOyYpO2UhOudvOyduCDqsoDthqDsmYAg6rCQ7IKs7JeQIOyCrOyaqe2VoCDsiJgg7J6I64+E66GdIOuCtOuztOuCtOq4sCDrspTsnITsmYAgQ1NWIO2RnO2YhCDrsKnsi53snYQg7KCV7J2Y7ZW07JW8IO2VqeuLiOuLpC4g64yT6riALCDroIjsnbTruJQg67OA6rK9LCDri7Tri7nsnpAg67OA6rK9IOuwjyDsg4Htg5wg7KCE7ZmY66eMIO2PrO2VqO2VmOqzoCwg6rO17Ya1IOyXtCDrkqTsl5Ag7J2067Kk7Yq467OEIOyXtOydtCDsnbTslrTsp4DripQg7ZWY64KY7J2YIOqzoOygleuQnCDsmYDsnbTrk5wg7Iqk7YKk66eI66W8IOyCrOyaqe2VqeuLiOuLpC4g7Je0IOyInOyEnOuKlCBgZXZlbnRfaWRgLCBgZXZlbnRfdHlwZWAsIGBvY2N1cnJlZF9hdGAsIGBhY3Rvcl9pZGAsIGBhY3Rvcl9sb2dpbmAsIGBzdWJqZWN0X3R5cGVgLCBgb2xkX3ZhbHVlYCwgYG5ld192YWx1ZWAsIGBjb21tZW50X2lkYCwgYGNvbW1lbnRfYm9keWDroZwg6rOg7KCV7ZWp64uI64ukLiDsnbTrsqTtirgg7KCV66CsLCDtg4DsnoTsiqTtg6ztlIQsIOyImOyglSDrsI8g7IKt7KCc65CcIOuMk+q4gCwg6raM7ZWcLCDruYTqs7XqsJwg642w7J207YSwLCDrjIDqt5zrqqgg7Zmc64+ZIOq4sOuhnSDrsI8gQ1NWIOyngeugrO2ZlOyXkCDrjIDtlZwg7J286rSA65CcIOqzhOyVveuPhCDsoJXsnZjtlbTslbwg7ZWp64uI64ukLiIsInJlY2VpcHRzIjpbeyJhZGRlZF9vcGVuX3F1ZXN0aW9uX2lkcyI6W10sImFwcHJvdmFsX2Fzc2lnbmVlcyI6W10sImFwcHJvdmVkX2Rpc2NvdmVyeV9zaGEyNTYiOm51bGwsImJhc2VfYm9keV9zaGEyNTYiOiI2NjQ0NTczMzc5ZGU3ODExNWQ3MzQwODI1MTlhNDcwYmYxMjM3ZTFjOGQ5NGZkYTJlMGYzZmMwYjYyZWY1MzlkIiwiYmFzZV9zdGF0ZV92ZXJzaW9uIjoiZGlzY292ZXJ5LXN0YXRlL3YzIiwiY29tbWVudF9pZCI6NzQ0LCJjb21tZW50X3NoYTI1NiI6IjBhMTNiZjEwZjI1OTJiOGQ3NzYwMDc3YzFkYmVhOTE2ODNiYmMwYmJiM2Y4MjZmZTA4OWFjMTEwMmU0YTk3ODYiLCJjb3JyZWxhdGlvbl9pZCI6ImZjOGNhOTVlYzRjODRkOTI5MTViMWJjNmIyYWNiZmViIiwiaGFuZG9mZl9tb2RlIjpudWxsLCJvcGVyYXRpb24iOiJjb25maXJtZWQtZGVjaXNpb24tcmVwYWlyL3YxIiwicmVwYWlyX2dyb3VwcyI6W3sia2VlcF9pZCI6Ik9RLTAwNCIsInJlbW92ZWRfZGVjaXNpb25zIjpbeyJjaG9pY2UiOiLsmKTrnpjrkJwg7J2067Kk7Yq467aA7YSwIOygleugrO2VmOqzoCwg7YOA7J6E7Iqk7YOs7ZSE6rCAIOqwmeycvOuptCDslYjsoJXsoIHsnbgg7J2067Kk7Yq4IOyLneuzhOyekOuhnCDsiJzshJzrpbwg6rKw7KCVIiwiaWQiOiJPUS0wMTMiLCJxdWVzdGlvbiI6IuuCtOuztOuCuCDsnbTrsqTtirjsnZgg7Iic7ISc66W8IOyWtOuWu+qyjCDsoJXtlbTslbwg7ZWp64uI6rmMPyJ9LHsiY2hvaWNlIjoi7Jik656Y65CcIOydtOuypO2KuOu2gO2EsCDsoJXroKztlZjqs6AsIO2DgOyehOyKpO2DrO2UhOqwgCDqsJnsnLzrqbQg7JWI7KCV7KCB7J24IOydtOuypO2KuCDsi53rs4TsnpDroZwg7Iic7ISc66W8IOqysOyglSIsImlkIjoiT1EtMDI4IiwicXVlc3Rpb24iOiLrgrTrs7Trgrgg7J2067Kk7Yq47J2YIOyInOyEnOulvCDslrTrlrvqsowg7KCV7ZW07JW8IO2VqeuLiOq5jD8ifV19LHsia2VlcF9pZCI6Ik9RLTAwNSIsInJlbW92ZWRfZGVjaXNpb25zIjpbeyJjaG9pY2UiOiJVVEProZwg7KCV6rec7ZmU7ZWY6rOgIGBaYCDsoJHrr7jsgqzrpbwg67aZ7J24IFJGQyAzMzM5IO2DgOyehOyKpO2DrO2UhCDsgqzsmqkiLCJpZCI6Ik9RLTAxNCIsInF1ZXN0aW9uIjoi7YOA7J6E7Iqk7YOs7ZSE7JmAIOyLnOqwhOuMgOulvCDslrTrlrvqsowg7ZGc7ZiE7ZW07JW8IO2VqeuLiOq5jD8ifSx7ImNob2ljZSI6IlVUQ+uhnCDsoJXqt5ztmZTtlZjqs6AgYFpgIOygkeuvuOyCrOulvCDrtpnsnbggUkZDIDMzMzkg7YOA7J6E7Iqk7YOs7ZSEIOyCrOyaqSIsImlkIjoiT1EtMDI5IiwicXVlc3Rpb24iOiLtg4DsnoTsiqTtg6ztlITsmYAg7Iuc6rCE64yA66W8IOyWtOuWu+qyjCDtkZztmITtlbTslbwg7ZWp64uI6rmMPyJ9XX0seyJrZWVwX2lkIjoiT1EtMDA2IiwicmVtb3ZlZF9kZWNpc2lvbnMiOlt7ImNob2ljZSI6Iu2YhOyerCDrs7jrrLjrp4wg64K067O064K06rOgIGBjcmVhdGVkX2F0YCDrsI8gYHVwZGF0ZWRfYXRgIOuplO2DgOuNsOydtO2EsCDtj6ztlagiLCJpZCI6Ik9RLTAxNSIsInF1ZXN0aW9uIjoi7IiY7KCV65CcIOuMk+q4gOydhCDrgrTrs7TrgrTquLDsl5Ag7Ja065a76rKMIO2RnOyLnO2VtOyVvCDtlanri4jquYw/In0seyJjaG9pY2UiOiLtmITsnqwg67O466y466eMIOuCtOuztOuCtOqzoCBgY3JlYXRlZF9hdGAg67CPIGB1cGRhdGVkX2F0YCDrqZTtg4DrjbDsnbTthLAg7Y+s7ZWoIiwiaWQiOiJPUS0wMzAiLCJxdWVzdGlvbiI6IuyImOygleuQnCDrjJPquIDsnYQg64K067O064K06riw7JeQIOyWtOuWu+qyjCDtkZzsi5ztlbTslbwg7ZWp64uI6rmMPyJ9XX0seyJrZWVwX2lkIjoiT1EtMDA3IiwicmVtb3ZlZF9kZWNpc2lvbnMiOlt7ImNob2ljZSI6IuuplO2DgOuNsOydtO2EsOuKlCDtj6ztlajtlZjrkJgg7IKt7KCc65CcIOuzuOusuOydgCDsoJzsmbjtlZwg7Yi87Iqk7YakIO2WiSDtj6ztlagiLCJpZCI6Ik9RLTAxNiIsInF1ZXN0aW9uIjoi7IKt7KCc65CcIOuMk+q4gOydhCDrgrTrs7TrgrTquLDsl5Ag7Ja065a76rKMIO2RnOyLnO2VtOyVvCDtlanri4jquYw/In0seyJjaG9pY2UiOiLrqZTtg4DrjbDsnbTthLDripQg7Y+s7ZWo7ZWY65CYIOyCreygnOuQnCDrs7jrrLjsnYAg7KCc7Jm47ZWcIO2IvOyKpO2GpCDtlokg7Y+s7ZWoIiwiaWQiOiJPUS0wMjIiLCJxdWVzdGlvbiI6IuyCreygnOuQnCDrjJPquIDsnYQg64K067O064K06riw7JeQIOyWtOuWu+qyjCDtkZzsi5ztlbTslbwg7ZWp64uI6rmMPyJ9LHsiY2hvaWNlIjoi66mU7YOA642w7J207YSw64qUIO2PrO2VqO2VmOuQmCDsgq3soJzrkJwg67O466y47J2AIOygnOyZuO2VnCDtiLzsiqTthqQg7ZaJIO2PrO2VqCIsImlkIjoiT1EtMDMxIiwicXVlc3Rpb24iOiLsgq3soJzrkJwg64yT6riA7J2EIOuCtOuztOuCtOq4sOyXkCDslrTrlrvqsowg7ZGc7Iuc7ZW07JW8IO2VqeuLiOq5jD8ifV19LHsia2VlcF9pZCI6Ik9RLTAwOCIsInJlbW92ZWRfZGVjaXNpb25zIjpbeyJjaG9pY2UiOiLtmITsnqwg7J207IqIIOyXtOuejCDqtoztlZzsnYQg7JqU6rWs7ZWY6rOgLCDrqqjrk6Ag7J2067Kk7Yq47JmAIO2VhOuTnOyXkCDtmITsnqwg6rO16rCcIOuylOychCDqt5zsuZnsnYQg7KCB7JqpIiwiaWQiOiJPUS0wMTciLCJxdWVzdGlvbiI6IuyWtOuWpCDqtoztlZwg66qo642466GcIOuCtOuztOuCtOq4sCDsoJHqt7zsnYQg7Ya17KCc7ZW07JW8IO2VqeuLiOq5jD8ifSx7ImNob2ljZSI6Iu2YhOyerCDsnbTsiogg7Je0656MIOq2jO2VnOydhCDsmpTqtaztlZjqs6AsIOuqqOuToCDsnbTrsqTtirjsmYAg7ZWE65Oc7JeQIO2YhOyerCDqs7XqsJwg67KU7JyEIOq3nOy5meydhCDsoIHsmqkiLCJpZCI6Ik9RLTAyMyIsInF1ZXN0aW9uIjoi7Ja065akIOq2jO2VnCDrqqjrjbjroZwg64K067O064K06riwIOygkeq3vOydhCDthrXsoJztlbTslbwg7ZWp64uI6rmMPyJ9LHsiY2hvaWNlIjoi7ZiE7J6sIOydtOyKiCDsl7Trnowg6raM7ZWc7J2EIOyalOq1rO2VmOqzoCwg66qo65OgIOydtOuypO2KuOyZgCDtlYTrk5zsl5Ag7ZiE7J6sIOqzteqwnCDrspTsnIQg6rec7LmZ7J2EIOyggeyaqSIsImlkIjoiT1EtMDMyIiwicXVlc3Rpb24iOiLslrTrlqQg6raM7ZWcIOuqqOuNuOuhnCDrgrTrs7TrgrTquLAg7KCR6re87J2EIO2GteygnO2VtOyVvCDtlanri4jquYw/In1dfSx7ImtlZXBfaWQiOiJPUS0wMDkiLCJyZW1vdmVkX2RlY2lzaW9ucyI6W3siY2hvaWNlIjoi7JWI7KCV7KCB7J24IOuCtOu2gCBJROyZgCDqs7XqsJwg6rCA64ql7ZWcIO2RnOyLnCDqsJLsnYQg64K067O064K06rOgLCDsoJztlZzrkJwg7ZWE65Oc64qUIOu5iCDqsJLsnLzroZwg7Jyg7KeAIiwiaWQiOiJPUS0wMTgiLCJxdWVzdGlvbiI6IuyeoOyerOyggeycvOuhnCDruYTqs7XqsJzsnbgg7ZaJ7JyE7J6QIOuwjyDrjJPquIAg642w7J207YSw66W8IOyWtOuWu+qyjCDtkZztmITtlbTslbwg7ZWp64uI6rmMPyJ9LHsiY2hvaWNlIjoi7JWI7KCV7KCB7J24IOuCtOu2gCBJROyZgCDqs7XqsJwg6rCA64ql7ZWcIO2RnOyLnCDqsJLsnYQg64K067O064K06rOgLCDsoJztlZzrkJwg7ZWE65Oc64qUIOu5iCDqsJLsnLzroZwg7Jyg7KeAIiwiaWQiOiJPUS0wMjQiLCJxdWVzdGlvbiI6IuyeoOyerOyggeycvOuhnCDruYTqs7XqsJzsnbgg7ZaJ7JyE7J6QIOuwjyDrjJPquIAg642w7J207YSw66W8IOyWtOuWu+qyjCDtkZztmITtlbTslbwg7ZWp64uI6rmMPyJ9LHsiY2hvaWNlIjoi7JWI7KCV7KCB7J24IOuCtOu2gCBJROyZgCDqs7XqsJwg6rCA64ql7ZWcIO2RnOyLnCDqsJLsnYQg64K067O064K06rOgLCDsoJztlZzrkJwg7ZWE65Oc64qUIOu5iCDqsJLsnLzroZwg7Jyg7KeAIiwiaWQiOiJPUS0wMzMiLCJxdWVzdGlvbiI6IuyeoOyerOyggeycvOuhnCDruYTqs7XqsJzsnbgg7ZaJ7JyE7J6QIOuwjyDrjJPquIAg642w7J207YSw66W8IOyWtOuWu+qyjCDtkZztmITtlbTslbwg7ZWp64uI6rmMPyJ9XX0seyJrZWVwX2lkIjoiT1EtMDEwIiwicmVtb3ZlZF9kZWNpc2lvbnMiOlt7ImNob2ljZSI6IuyZhOyghO2VnCBDU1brpbwg7Iqk7Yq466as67CN7ZWY6rOgLCDrrLjshJztmZTrkJwg7ISc67KEIOygnO2VnOydhCDstIjqs7ztlZjrqbQg66qF7Iuc7KCB7Jy866GcIOyLpO2MqCIsImlkIjoiT1EtMDE5IiwicXVlc3Rpb24iOiLtmZzrj5kg6riw66Gd7J20IOunjuydgCDsnbTsiojsl5DripQg7Ja065akIOuPmeyekeydhCDsoIHsmqntlbTslbwg7ZWp64uI6rmMPyJ9LHsiY2hvaWNlIjoi7JmE7KCE7ZWcIENTVuulvCDsiqTtirjrpqzrsI3tlZjqs6AsIOusuOyEnO2ZlOuQnCDshJzrsoQg7KCc7ZWc7J2EIOy0iOqzvO2VmOuptCDrqoXsi5zsoIHsnLzroZwg7Iuk7YyoIiwiaWQiOiJPUS0wMjUiLCJxdWVzdGlvbiI6Iu2ZnOuPmSDquLDroZ3snbQg66eO7J2AIOydtOyKiOyXkOuKlCDslrTrlqQg64+Z7J6R7J2EIOyggeyaqe2VtOyVvCDtlanri4jquYw/In0seyJjaG9pY2UiOiLsmYTsoITtlZwgQ1NW66W8IOyKpO2KuOumrOuwje2VmOqzoCwg66y47ISc7ZmU65CcIOyEnOuyhCDsoJztlZzsnYQg7LSI6rO87ZWY66m0IOuqheyLnOyggeycvOuhnCDsi6TtjKgiLCJpZCI6Ik9RLTAzNCIsInF1ZXN0aW9uIjoi7Zmc64+ZIOq4sOuhneydtCDrp47snYAg7J207IqI7JeQ64qUIOyWtOuWpCDrj5nsnpHsnYQg7KCB7Jqp7ZW07JW8IO2VqeuLiOq5jD8ifV19LHsia2VlcF9pZCI6Ik9RLTAxMSIsInJlbW92ZWRfZGVjaXNpb25zIjpbeyJjaG9pY2UiOiJVVEYtOCwgUkZDIDQxODAg7Zi47ZmYIOyduOyaqSwgQ1JMRiDroIjsvZTrk5wsIO2XpOuNlCDtlokg67CPIOqwkuydtCDsl4bripQg6rK97JqwIOu5iCDtlYTrk5wg7IKs7JqpIiwiaWQiOiJPUS0wMjAiLCJxdWVzdGlvbiI6IkNTViDsnbjsvZTrlKksIOydtOyKpOy8gOydtO2UhCDrsI8g6rCS7J20IOyXhuuKlCDqsr3smrDsnZgg7ZGc7ZiE7J2EIOyWtOuWu+qyjCDsoJXsnZjtlbTslbwg7ZWp64uI6rmMPyJ9LHsiY2hvaWNlIjoiVVRGLTgsIFJGQyA0MTgwIO2YuO2ZmCDsnbjsmqksIENSTEYg66CI7L2U65OcLCDtl6TrjZQg7ZaJIOuwjyDqsJLsnbQg7JeG64qUIOqyveyasCDruYgg7ZWE65OcIOyCrOyaqSIsImlkIjoiT1EtMDI2IiwicXVlc3Rpb24iOiJDU1Yg7J247L2U65SpLCDsnbTsiqTsvIDsnbTtlIQg67CPIOqwkuydtCDsl4bripQg6rK97Jqw7J2YIO2RnO2YhOydhCDslrTrlrvqsowg7KCV7J2Y7ZW07JW8IO2VqeuLiOq5jD8ifSx7ImNob2ljZSI6IlVURi04LCBSRkMgNDE4MCDtmLjtmZgg7J247JqpLCBDUkxGIOugiOy9lOuTnCwg7Zek642UIO2WiSDrsI8g6rCS7J20IOyXhuuKlCDqsr3smrAg67mIIO2VhOuTnCDsgqzsmqkiLCJpZCI6Ik9RLTAzNSIsInF1ZXN0aW9uIjoiQ1NWIOyduOy9lOuUqSwg7J207Iqk7LyA7J207ZSEIOuwjyDqsJLsnbQg7JeG64qUIOqyveyasOydmCDtkZztmITsnYQg7Ja065a76rKMIOygleydmO2VtOyVvCDtlanri4jquYw/In1dfSx7ImtlZXBfaWQiOiJPUS0wMTIiLCJyZW1vdmVkX2RlY2lzaW9ucyI6W3siY2hvaWNlIjoi7IiY7Iud7Jy866GcIO2VtOyEneuQoCDsiJgg7J6I64qUIOusuOyekOuhnCDsi5zsnpHtlZjripQg6rCS7JeQIOygkeuRkOyCrOulvCDrtpnsnbTqs6Ag67OA7ZmYIOuwqeyLneydhCDrrLjshJztmZQiLCJpZCI6Ik9RLTAyMSIsInF1ZXN0aW9uIjoi7YWN7Iqk7Yq4IO2VhOuTnOydmCDsiqTtlITroIjrk5zsi5ztirgg7IiY7IudIOyCveyehSDsnITtl5jsnYQg7Ja065a76rKMIOyymOumrO2VtOyVvCDtlanri4jquYw/In0seyJjaG9pY2UiOiLsiJjsi53snLzroZwg7ZW07ISd65CgIOyImCDsnojripQg66y47J6Q66GcIOyLnOyeke2VmOuKlCDqsJLsl5Ag7KCR65GQ7IKs66W8IOu2meydtOqzoCDrs4DtmZgg67Cp7Iud7J2EIOusuOyEnO2ZlCIsImlkIjoiT1EtMDI3IiwicXVlc3Rpb24iOiLthY3siqTtirgg7ZWE65Oc7J2YIOyKpO2UhOugiOuTnOyLnO2KuCDsiJjsi50g7IK97J6FIOychO2XmOydhCDslrTrlrvqsowg7LKY66as7ZW07JW8IO2VqeuLiOq5jD8ifSx7ImNob2ljZSI6IuyImOyLneycvOuhnCDtlbTshJ3rkKAg7IiYIOyeiOuKlCDrrLjsnpDroZwg7Iuc7J6R7ZWY64qUIOqwkuyXkCDsoJHrkZDsgqzrpbwg67aZ7J206rOgIOuzgO2ZmCDrsKnsi53snYQg66y47ISc7ZmUIiwiaWQiOiJPUS0wMzYiLCJxdWVzdGlvbiI6Iu2FjeyKpO2KuCDtlYTrk5zsnZgg7Iqk7ZSE66CI65Oc7Iuc7Yq4IOyImOyLnSDsgr3snoUg7JyE7ZeY7J2EIOyWtOuWu+qyjCDsspjrpqztlbTslbwg7ZWp64uI6rmMPyJ9XX1dLCJyZXN1bHRfYm9keV9zaGEyNTYiOiI1NGM2YjUzYzdhMjk1YWM0MjE1MjE3N2ZlNmZiNmEyY2JlMGQxN2E0OTdkZjFkOTY0MzU0ZTRhMWI4NTlmNmI4IiwicmVzdWx0X3N0YXRlX3ZlcnNpb24iOm51bGwsInJldmlzaW9uX2pzb24iOm51bGwsInNvdXJjZV9hdXRob3JfaWQiOm51bGwsInNvdXJjZV9hdXRob3JfbG9naW4iOm51bGwsInN0YXR1cyI6ImFwcGx5In0seyJhZGRlZF9vcGVuX3F1ZXN0aW9uX2lkcyI6W10sImFwcHJvdmFsX2Fzc2lnbmVlcyI6WyJzcGVjLWFnZW50Il0sImFwcHJvdmVkX2Rpc2NvdmVyeV9zaGEyNTYiOiI4Y2M3YjFlMjA1OGVhYjNmZjRkMzUxNWNiNDllNWY2Zjc0MWYwYTgxZDQ3MGYxNDliNDY3OGU0NDYyNDk5MGM3IiwiYmFzZV9ib2R5X3NoYTI1NiI6IjhjYzdiMWUyMDU4ZWFiM2ZmNGQzNTE1Y2I0OWU1ZjZmNzQxZjBhODFkNDcwZjE0OWI0Njc4ZTQ0NjI0OTkwYzciLCJiYXNlX3N0YXRlX3ZlcnNpb24iOiJkaXNjb3Zlcnktc3RhdGUvdjQiLCJjb21tZW50X2lkIjo3NTYsImNvbW1lbnRfc2hhMjU2IjoiYmQ4ODQ0MjQ5YjE1ZTBlNDI3ZjQ3NGQ1NjY5NDNjMWJiYzU2ZjAzY2E1NGMwYTM0Mzk2OTVjOWVhODE3YzM4YSIsImNvcnJlbGF0aW9uX2lkIjoiMTA0NDVhNGZkMDE3M2VjNjMzNDM5ZjRkZjY3MDgxMzMiLCJoYW5kb2ZmX21vZGUiOiJtYW51YWwiLCJvcGVyYXRpb24iOiJkaXNjb3ZlcnktYXBwcm92YWwvdjIiLCJyZXBhaXJfZ3JvdXBzIjpbXSwicmVzdWx0X2JvZHlfc2hhMjU2IjoiOGNjN2IxZTIwNThlYWIzZmY0ZDM1MTVjYjQ5ZTVmNmY3NDFmMGE4MWQ0NzBmMTQ5YjQ2NzhlNDQ2MjQ5OTBjNyIsInJlc3VsdF9zdGF0ZV92ZXJzaW9uIjoiZGlzY292ZXJ5LXN0YXRlL3Y3IiwicmV2aXNpb25fanNvbiI6bnVsbCwic291cmNlX2F1dGhvcl9pZCI6Miwic291cmNlX2F1dGhvcl9sb2dpbiI6ImdlbmljaGluIiwic3RhdHVzIjoiYXBwcm92ZSJ9XSwicmVwb3NpdG9yeV9ldmlkZW5jZSI6W10sInN1bW1hcnkiOiLqtoztlZzsnbQg7J6I64qUIOyCrOyaqeyekOqwgCDsnbTsiogg7Zmc64+Z7J2EIOyYpO2UhOudvOyduOyXkOyEnCDqsoDthqDtlZjqs6Ag6rCQ7IKs7ZWgIOyImCDsnojrj4TroZ0g64yT6riALCDroIjsnbTruJQg67OA6rK9LCDri7Tri7nsnpAg67OA6rK9IOuwjyDsg4Htg5wg7KCE7ZmY7J2EIO2VmOuCmOydmCDqs6DsoJXrkJwg7JmA7J2065OcIENTViDsiqTtgqTrp4jroZwg64K067O064K064qUIOuPmeyekSDrqoXshLjrpbwg7KCV7J2Y7ZWp64uI64ukLiDsnbTrsogg67KU7JyE64qUIO2UhOuhnOuNleyFmCDqtaztmITsnbQg7JWE64uMIOuqheyEuCDsnpHshLHsnoXri4jri6QuIn0= --> # 디스커버리 초안 ## 원본 사용자 요청 > ## 배경 > > 저장소 유지관리자는 오프라인 검토 및 감사를 위해 이슈의 활동 기록을 간단하게 내보낼 수 있는 방법이 필요합니다. > > ## 디스커버리 목표 > > 구현 전에 다음을 포함한 예상 동작을 정의합니다. > > - 포함할 이벤트(댓글, 레이블 변경, 담당자 변경, 상태 전환) > - CSV 열과 순서 > - 타임스탬프 및 시간대 표현 > - 삭제되거나 수정된 댓글의 처리 > - 권한 및 비공개 데이터 제약 사항 > - 활동량이 많은 이슈의 처리 방식 > > ## 게이트 카나리 > > 이 이슈는 의도적으로 **열림** 상태에서 **`spec-agent`**에게 할당되고 **레이블이 없는** 상태로 시작합니다. 결정론적 읽기 전용 게이트는 이를 초기 디스커버리 접수 후보로 인식하고, Gitea 상태를 변경하지 않은 채 `wakeAgent=true`를 반환해야 합니다. > > 이 테스트 이슈에서는 프로덕션 구현을 요청하지 않습니다. ## 요약 권한이 있는 사용자가 이슈 활동을 오프라인에서 검토하고 감사할 수 있도록 댓글, 레이블 변경, 담당자 변경 및 상태 전환을 하나의 고정된 와이드 CSV 스키마로 내보내는 동작 명세를 정의합니다. 이번 범위는 프로덕션 구현이 아닌 명세 작성입니다. ## 문제 이슈 활동을 오프라인 검토와 감사에 사용할 수 있도록 내보내기 범위와 CSV 표현 방식을 정의해야 합니다. 댓글, 레이블 변경, 담당자 변경 및 상태 전환만 포함하고, 공통 열 뒤에 이벤트별 열이 이어지는 하나의 고정된 와이드 스키마를 사용합니다. 열 순서는 \`event\_id\`, \`event\_type\`, \`occurred\_at\`, \`actor\_id\`, \`actor\_login\`, \`subject\_type\`, \`old\_value\`, \`new\_value\`, \`comment\_id\`, \`comment\_body\`로 고정합니다. 이벤트 정렬, 타임스탬프, 수정 및 삭제된 댓글, 권한, 비공개 데이터, 대규모 활동 기록 및 CSV 직렬화에 대한 일관된 계약도 정의해야 합니다. ## 포함 범위 - 댓글, 레이블 변경, 담당자 변경 및 상태 전환 이벤트만 포함하는 내보내기 동작 정의 - 공통 열 뒤에 이벤트별 열이 이어지는 하나의 고정된 와이드 CSV 스키마 정의 - CSV 열 순서를 \`event\_id\`, \`event\_type\`, \`occurred\_at\`, \`actor\_id\`, \`actor\_login\`, \`subject\_type\`, \`old\_value\`, \`new\_value\`, \`comment\_id\`, \`comment\_body\`로 고정 - 오래된 이벤트부터 정렬하고 타임스탬프가 같으면 안정적인 이벤트 식별자로 순서를 결정하는 방식 정의 - UTC로 정규화하고 \`Z\` 접미사를 붙인 RFC 3339 타임스탬프 형식 정의 - 수정된 댓글의 현재 본문과 \`created\_at\`, \`updated\_at\` 메타데이터 처리 방식 정의 - 삭제된 댓글의 메타데이터와 본문 제외를 나타내는 툼스톤 행 처리 방식 정의 - 현재 이슈 열람 권한과 현재 공개 범위 규칙을 적용하는 권한 모델 정의 - 안정적인 내부 ID와 공개 가능한 표시 값을 사용하고 제한된 필드는 빈 값으로 유지하는 방식 정의 - 활동 기록이 많은 이슈에서 완전한 CSV를 스트리밍하고 서버 제한 초과 시 명시적으로 실패하는 방식 정의 - UTF-8, RFC 4180 호환 인용, CRLF 레코드, 헤더 행 및 빈 필드 표현 정의 - 수식으로 해석될 수 있는 값에 접두사를 붙이고 변환 방식을 문서화하는 방식 정의 ## 제외 범위 - 내보내기 기능의 프로덕션 구현 - 이슈 상태, 담당자, 레이블, 댓글 또는 기타 저장소 데이터의 변경 - 저장소 전체, 조직 전체 또는 여러 저장소에 걸친 활동 내보내기 - CSV로 필수 데이터를 표현할 수 없는 이유를 명확히 하는 데 필요한 경우를 제외한 비 CSV 내보내기 형식 - 보존 정책 또는 감사 정책의 변경 - 댓글, 레이블 변경, 담당자 변경 및 상태 전환 이외의 활동 이벤트 내보내기 ## 제약 조건 - 결과물은 프로덕션 코드가 아닌 동작 명세입니다. - 내보내기 형식은 CSV입니다. - 내보내기 생성 과정은 이슈와 저장소 상태에 대해 읽기 전용이어야 합니다. - 포함 이벤트는 댓글, 레이블 변경, 담당자 변경 및 상태 전환으로 제한합니다. - CSV는 공통 열 뒤에 이벤트별 열이 이어지는 하나의 고정된 와이드 스키마를 사용합니다. - CSV 열 순서는 \`event\_id\`, \`event\_type\`, \`occurred\_at\`, \`actor\_id\`, \`actor\_login\`, \`subject\_type\`, \`old\_value\`, \`new\_value\`, \`comment\_id\`, \`comment\_body\`로 고정합니다. - 이벤트는 오래된 순서로 정렬하고 타임스탬프가 같으면 안정적인 이벤트 식별자로 순서를 결정합니다. - 타임스탬프는 UTC로 정규화하고 \`Z\` 접미사를 붙인 RFC 3339 형식으로 표현합니다. - 수정된 댓글은 현재 본문과 \`created\_at\`, \`updated\_at\` 메타데이터를 포함합니다. - 삭제된 댓글은 메타데이터를 포함하되 삭제된 본문은 제외한 툼스톤 행으로 표현합니다. - 내보내기 접근에는 현재 이슈 열람 권한을 요구하고 모든 이벤트와 필드에 현재 공개 범위 규칙을 적용합니다. - 행위자 및 댓글 데이터는 안정적인 내부 ID와 공개 가능한 표시 값을 사용하며 제한된 필드는 빈 값으로 유지합니다. - 활동 기록이 많은 이슈에서는 완전한 CSV를 스트리밍하고 문서화된 서버 제한을 초과하면 명시적으로 실패합니다. - CSV는 UTF-8, RFC 4180 호환 인용, CRLF 레코드 및 헤더 행을 사용하며 값이 없으면 빈 필드로 표현합니다. - 수식으로 해석될 수 있는 문자로 시작하는 값에는 접두사를 붙이고 변환 방식을 문서화합니다. - 제공된 저장소 소스와 요구사항 인덱스에서는 저장소별 요구 사항이나 구현 규칙을 확인할 수 없습니다. ## 확정된 결정 - **OQ-001**: CSV에 어떤 활동 이벤트를 포함해야 합니까? → 댓글, 레이블 변경, 담당자 변경 및 상태 전환만 포함 - **OQ-002**: CSV 스키마에서 서로 다른 이벤트 유형을 어떻게 표현해야 합니까? → 공통 열 뒤에 이벤트별 열이 이어지는 하나의 고정된 와이드 스키마 사용 - **OQ-003**: 내보내기에 사용할 공통 열과 순서는 무엇입니까? → 열 순서: \`event\_id\`, \`event\_type\`, \`occurred\_at\`, \`actor\_id\`, \`actor\_login\`, \`subject\_type\`, \`old\_value\`, \`new\_value\`, \`comment\_id\`, \`comment\_body\` - **OQ-004**: 내보낸 이벤트의 순서를 어떻게 정해야 합니까? → 오래된 이벤트부터 정렬하고, 타임스탬프가 같으면 안정적인 이벤트 식별자로 순서를 결정 - **OQ-005**: 타임스탬프와 시간대를 어떻게 표현해야 합니까? → UTC로 정규화하고 \`Z\` 접미사를 붙인 RFC 3339 타임스탬프 사용 - **OQ-006**: 수정된 댓글을 내보내기에 어떻게 표시해야 합니까? → 현재 본문만 내보내고 \`created\_at\` 및 \`updated\_at\` 메타데이터 포함 - **OQ-007**: 삭제된 댓글을 내보내기에 어떻게 표시해야 합니까? → 메타데이터는 포함하되 삭제된 본문은 제외한 툼스톤 행 포함 - **OQ-008**: 어떤 권한 모델로 내보내기 접근을 통제해야 합니까? → 현재 이슈 열람 권한을 요구하고, 모든 이벤트와 필드에 현재 공개 범위 규칙을 적용 - **OQ-009**: 잠재적으로 비공개인 행위자 및 댓글 데이터를 어떻게 표현해야 합니까? → 안정적인 내부 ID와 공개 가능한 표시 값을 내보내고, 제한된 필드는 빈 값으로 유지 - **OQ-010**: 활동 기록이 많은 이슈에는 어떤 동작을 적용해야 합니까? → 완전한 CSV를 스트리밍하고, 문서화된 서버 제한을 초과하면 명시적으로 실패 - **OQ-011**: CSV 인코딩, 이스케이프 및 값이 없는 경우의 표현을 어떻게 정의해야 합니까? → UTF-8, RFC 4180 호환 인용, CRLF 레코드, 헤더 행 및 값이 없는 경우 빈 필드 사용 - **OQ-012**: 텍스트 필드의 스프레드시트 수식 삽입 위험을 어떻게 처리해야 합니까? → 수식으로 해석될 수 있는 문자로 시작하는 값에 접두사를 붙이고 변환 방식을 문서화 ## 저장소 근거 _없음._ ## 문서 영향 및 산출물 ### `user-guide` / `none` - 대상 유형: `logical-area` - 대상: `사용자 안내` - 관련 미해결 질문: 없음 - 독자: 기능 사용자 - 핵심 내용: 없음 - 검증: 프로덕션 기능이나 사용자용 사용 절차를 추가하지 않으므로 사용자 안내 문서 변경이 없는지 확인합니다. - 근거: 이번 이슈는 확정된 CSV 동작 명세 작성만을 범위로 하며 프로덕션 구현이나 사용자 기능 변경을 포함하지 않습니다. ### `operations-runbook` / `none` - 대상 유형: `logical-area` - 대상: `운영 절차` - 관련 미해결 질문: 없음 - 독자: 저장소 운영자 - 핵심 내용: 없음 - 검증: 실행 가능한 운영 절차나 서버 설정 변경이 추가되지 않았는지 확인합니다. - 근거: 내보내기 기능의 운영 배포나 실행 절차를 정의하는 구현 작업은 범위 밖입니다. ### `cli-api-contract` / `none` - 대상 유형: `logical-area` - 대상: `명령줄 및 API 계약` - 관련 미해결 질문: 없음 - 독자: 통합 개발자 - 핵심 내용: 없음 - 검증: 명령줄 또는 API의 구현 계약을 새로 만들거나 변경하지 않는지 확인합니다. - 근거: CSV 동작 규칙은 정의하지만 명령줄 또는 API 구현과 공개 인터페이스 변경은 범위에 포함하지 않습니다. ### `schema-configuration` / `none` - 대상 유형: `logical-area` - 대상: `스키마 및 설정` - 관련 미해결 질문: 없음 - 독자: 구현 개발자 - 핵심 내용: 없음 - 검증: 확정된 CSV 열 순서와 직렬화 규칙이 구현 문서가 아닌 본 명세에만 반영되는지 확인합니다. - 근거: 고정된 CSV 스키마와 직렬화 제약은 동작 명세로 확정하지만 저장 형식이나 설정 파일 구현은 범위 밖입니다. ### `migration-compatibility` / `none` - 대상 유형: `logical-area` - 대상: `마이그레이션 및 호환성` - 관련 미해결 질문: 없음 - 독자: 유지관리자 - 핵심 내용: 없음 - 검증: 기존 데이터, 저장소 구조 또는 공개 인터페이스의 마이그레이션이 요구되지 않는지 확인합니다. - 근거: 기존 데이터나 공개 인터페이스를 변경하는 구현이 없으므로 마이그레이션 및 호환성 문서 변경은 필요하지 않습니다. ### `release-notes` / `none` - 대상 유형: `logical-area` - 대상: `릴리스 노트` - 관련 미해결 질문: 없음 - 독자: 프로젝트 사용자 - 핵심 내용: 없음 - 검증: 배포 가능한 기능 변경이나 릴리스 대상이 생성되지 않았는지 확인합니다. - 근거: 이번 결과물은 프로덕션 구현이 아닌 동작 명세이므로 릴리스 노트 변경 대상이 없습니다. ## 미해결 질문 _없음._
gitea-spec-agent self-assigned this 2026-09-12 03:26:53 +00:00
admin was assigned by gitea-spec-agent 2026-09-12 05:28:07 +00:00
admin was unassigned by gitea-spec-agent 2026-09-12 05:28:09 +00:00
gitea-spec-agent added the step:discoverystatus:draftspec-agent:busy labels 2026-09-12 14:05:41 +00:00
gitea-spec-agent removed the spec-agent:busy label 2026-09-12 14:07:11 +00:00
gitea-spec-agent removed their assignment 2026-09-12 14:07:12 +00:00
gitea-spec-agent was assigned by genichin 2026-09-13 01:53:19 +00:00
gitea-spec-agent removed their assignment 2026-09-13 05:28:23 +00:00
gitea-spec-agent was assigned by genichin 2026-09-14 13:08:05 +00:00
gitea-spec-agent removed their assignment 2026-09-14 13:10:58 +00:00
gitea-spec-agent was assigned by genichin 2026-09-14 13:30:00 +00:00
gitea-spec-agent added the spec-agent:busy label 2026-09-14 13:30:29 +00:00
gitea-spec-agent removed the spec-agent:busy label 2026-09-14 13:31:43 +00:00
gitea-spec-agent removed their assignment 2026-09-14 13:31:44 +00:00
gitea-spec-agent was assigned by genichin 2026-09-14 23:50:57 +00:00
gitea-spec-agent removed their assignment 2026-09-14 23:52:05 +00:00
gitea-spec-agent was assigned by genichin 2026-09-14 23:53:42 +00:00
gitea-spec-agent added the spec-agent:busy label 2026-09-14 23:54:17 +00:00
gitea-spec-agent removed the spec-agent:busy label 2026-09-14 23:55:50 +00:00
gitea-spec-agent removed their assignment 2026-09-14 23:55:51 +00:00
gitea-spec-agent was assigned by genichin 2026-09-15 02:05:10 +00:00
gitea-spec-agent added the spec-agent:busy label 2026-09-15 02:05:55 +00:00
gitea-spec-agent added status:review and removed status:draftspec-agent:busy labels 2026-09-15 02:07:11 +00:00
gitea-spec-agent removed their assignment 2026-09-15 02:07:12 +00:00
Owner

@spec-agent 확정 결정 중 의미가 중복되는 항목을 정리해줘.
OQ-007을 대표로 유지하고 OQ-016, OQ-022, OQ-031은 중복으로 제거해줘.
나머지 중복 그룹도 최초 ID를 대표로 유지해줘.

@spec-agent 확정 결정 중 의미가 중복되는 항목을 정리해줘. OQ-007을 대표로 유지하고 OQ-016, OQ-022, OQ-031은 중복으로 제거해줘. 나머지 중복 그룹도 최초 ID를 대표로 유지해줘.
gitea-spec-agent was assigned by genichin 2026-09-15 04:00:41 +00:00
gitea-spec-agent added status:draft and removed status:review labels 2026-09-15 05:33:52 +00:00
gitea-spec-agent added the spec-agent:busy label 2026-09-15 05:40:18 +00:00
Author
Collaborator

@genichin 확정 결정 목록의 중복 정리는 지원되는 본문 필드 변경 대상이 아니므로 적용할 수 없습니다.

원본 댓글: #1 (comment)

@genichin 확정 결정 목록의 중복 정리는 지원되는 본문 필드 변경 대상이 아니므로 적용할 수 없습니다. 원본 댓글: https://gitea.jsfamily.quest/genichin/gitea-agent-testbed/issues/1#issuecomment-732 <!-- gitea-agent:discovery-comment-result/v1 source-comment-id=732 source-comment-sha256=87f810f5a99c46b4b15c8974bd0423e9fdb30791a73b98d702a1ae99b096b7fd status=clarify correlation-id=5663e3aeac4f44c2b65714e65dd119c1 final-body-sha256=6644573379de78115d734082519a470bf1237e1c8d94fda2e0f3fc0b62ef539d -->
gitea-spec-agent removed the spec-agent:busy label 2026-09-15 05:40:44 +00:00
gitea-spec-agent removed their assignment 2026-09-15 05:40:45 +00:00
Owner

@spec-agent 확정 결정 중 의미가 중복되는 항목을 정리해줘.
OQ-007을 대표로 유지하고 OQ-016, OQ-022, OQ-031은 중복으로 제거해줘.
나머지 중복 그룹도 최초 ID를 대표로 유지해줘.

@spec-agent 확정 결정 중 의미가 중복되는 항목을 정리해줘. OQ-007을 대표로 유지하고 OQ-016, OQ-022, OQ-031은 중복으로 제거해줘. 나머지 중복 그룹도 최초 ID를 대표로 유지해줘.
gitea-spec-agent was assigned by genichin 2026-09-15 13:30:18 +00:00
gitea-spec-agent removed their assignment 2026-09-15 13:34:21 +00:00
gitea-spec-agent was assigned by genichin 2026-09-15 13:38:30 +00:00
gitea-spec-agent added the spec-agent:busy label 2026-09-15 13:39:33 +00:00
gitea-spec-agent added status:review and removed status:draftspec-agent:busy labels 2026-09-15 13:40:52 +00:00
Author
Collaborator

@genichin 확정 결정 중복 9개 그룹에서 24개 항목을 제거하고 0개 미해결 질문을 추가했습니다. 정리 내역: OQ-004 유지, OQ-013, OQ-028 제거; OQ-005 유지, OQ-014, OQ-029 제거; OQ-006 유지, OQ-015, OQ-030 제거; OQ-007 유지, OQ-016, OQ-022, OQ-031 제거; OQ-008 유지, OQ-017, OQ-023, OQ-032 제거; OQ-009 유지, OQ-018, OQ-024, OQ-033 제거; OQ-010 유지, OQ-019, OQ-025, OQ-034 제거; OQ-011 유지, OQ-020, OQ-026, OQ-035 제거; OQ-012 유지, OQ-021, OQ-027, OQ-036 제거. 새 미해결 질문: 없음.

원본 댓글: #1 (comment)

@genichin 확정 결정 중복 9개 그룹에서 24개 항목을 제거하고 0개 미해결 질문을 추가했습니다. 정리 내역: OQ-004 유지, OQ-013, OQ-028 제거; OQ-005 유지, OQ-014, OQ-029 제거; OQ-006 유지, OQ-015, OQ-030 제거; OQ-007 유지, OQ-016, OQ-022, OQ-031 제거; OQ-008 유지, OQ-017, OQ-023, OQ-032 제거; OQ-009 유지, OQ-018, OQ-024, OQ-033 제거; OQ-010 유지, OQ-019, OQ-025, OQ-034 제거; OQ-011 유지, OQ-020, OQ-026, OQ-035 제거; OQ-012 유지, OQ-021, OQ-027, OQ-036 제거. 새 미해결 질문: 없음. 원본 댓글: https://gitea.jsfamily.quest/genichin/gitea-agent-testbed/issues/1#issuecomment-744 <!-- gitea-agent:discovery-comment-result/v1 source-comment-id=744 source-comment-sha256=0a13bf10f2592b8d7760077c1dbea91683bbc0bbb3f826fe089ac1102e4a9786 status=apply correlation-id=fc8ca95ec4c84d92915b1bc6b2acbfeb final-body-sha256=de0e5e4a068a922193c174b0d6589f26cfd094d30807bfb45121d5d2c99bf672 -->
gitea-spec-agent removed their assignment 2026-09-15 13:40:58 +00:00
Owner

@spec-agent 승인

@spec-agent 승인
gitea-spec-agent was assigned by genichin 2026-09-16 03:52:04 +00:00
gitea-spec-agent added status:draftstep:implementation and removed step:discoverystatus:review labels 2026-09-16 04:07:56 +00:00
Author
Collaborator

@genichin 디스커버리를 승인하고 구현 단계로 인계했으며 code-agent 할당 전까지 구현 시작을 보류합니다.

원본 댓글: #1 (comment)

@genichin 디스커버리를 승인하고 구현 단계로 인계했으며 code-agent 할당 전까지 구현 시작을 보류합니다. 원본 댓글: https://gitea.jsfamily.quest/genichin/gitea-agent-testbed/issues/1#issuecomment-756 <!-- gitea-agent:discovery-comment-result/v1 source-comment-id=756 source-comment-sha256=bd8844249b15e0e427f474d566943c1bbc56f03ca54c0a3439695c9ea817c38a status=approve correlation-id=10445a4fd0173ec633439f4df6708133 final-body-sha256=37119292c2b964acefc37efdef48a86b45755f3b92315fb85709da163ba7794c -->
gitea-spec-agent removed their assignment 2026-09-16 04:08:02 +00:00
Sign in to join this conversation.