티켓 작성
맥락이 없는 사람이 읽고도 일을 시작할 수 있는 티켓을 CLI 로 만드는 법을 다룬다. 티켓을 읽는 사람은 몇 주 뒤의 본인이거나, 이 대화에 없던 동료이거나, 이 프로젝트를 처음 여는 AI 다. 제목만 보고 무엇을 해야 하는지 알 수 있는 티켓은 드물고, 대부분은 본문이 그 일을 한다.
본문 구성하기
세 가지면 충분하고, 셋 중 하나가 빠지면 대개 다시 물어야 한다.
- 배경 — 왜 이것이 필요한가. 어떤 증상·요청·결정에서 나왔는가.
- 작업 — 무엇을 바꾸는가. 대상 파일·화면·엔드포인트처럼 찾아갈 수 있는 이름으로.
- 수용 기준 — 무엇이 참이면 끝났는가. 사람이 확인할 수 있는 문장으로.
## 배경
로그인 후 첫 화면에서 목록이 비어 보이는 신고가 반복된다. 실제로는 데이터가 있고
첫 요청이 캐시를 채우기 전에 렌더된다.
## 작업
- 목록 초기 로딩 상태를 빈 상태와 구분한다
- 빈 상태 문구를 "아직 없음" 과 "불러오는 중" 으로 분리
## 수용 기준
- 느린 네트워크에서 새로고침해도 "아직 없음" 이 먼저 보이지 않는다
- 실제로 비었을 때는 여전히 "아직 없음" 이 보인다
수용 기준을 “잘 동작한다” 로 쓰지 않는다. 그렇게 쓰면 완료 판정을 하는 사람이 기준을 새로 만들어야 하고, 그 기준은 작성자가 생각한 것과 다르다.
본문에서 뺄 것 거르기
- 대화 로그 — “그래서 이렇게 하기로 했다” 까지만 남기고 과정은 버린다.
- 아직 결정되지 않은 선택지 나열 — 결정이 필요하면 그 결정을 티켓의 작업으로 쓴다.
- 추측한 원인 — 확인한 것과 추측한 것을 섞으면 뒤에 읽는 사람이 가른다. 추측이면 추측이라고 적는다.
마크다운으로 쓰기
본문은 마크다운으로 쓴다. 표·코드 블록·목록도 마크다운 문법으로 쓴다.
HTML·JSX 태그는 거부된다(400). 코드 블록과 인라인 코드 안의 태그는 괜찮고, 그 밖에 있으면 태그로 판정된다. 그래서 Array<string> 이나 <tenantId> 같은 표기도 본문에 그냥 쓰면 거부된다 — 백틱으로 감싸거나 {tenantId} 처럼 쓴다.
본문 키 지정하기
본문은 일반 필드가 아니라 values 의 _description 키로 넣는다. 이 키는 가상 키라 describe 의 fieldMap 에 나오지 않는다 — fieldMap 만 보고 키를 고르면 본문을 넣을 자리를 못 찾는다.
dillie project tasks create ACME --data '{"values":{"title":"제목","_description":"## 배경\n…"}}'
본문이 길면 요청 본문 전체를 파일로 넘긴다.
dillie project tasks create ACME --data-file ./ticket.json
values 에 쓸 수 있는 키는 세 종류다 — describe 의 fieldMap.fields 에 있는 필드 id, 아래의 별칭, 그리고 _description. 그 밖의 키를 보내면 거부되고, 메시지가 거부된 키를 알려 준다.
dillie --agent describe ACME --fields fieldMap
본문만 따로 읽고 쓰는 명령이 있다. 이미 있는 아이템의 본문을 바꿀 때는 이쪽을 쓴다. --content 와 --content-file 중 하나만 준다.
dillie --agent project tasks get-description ACME ACME-123
dillie project tasks set-description ACME ACME-123 --content-file ./body.md
값 키에 별칭 쓰기
values 의 키는 fieldMap 의 필드 id 지만, 자주 쓰는 것들은 이름으로도 쓸 수 있다: title·status·issueType·assignee·priority·dueDate. 서버가 그 역할의 필드 id 로 바꾼다. UUID 를 옮겨 적는 것보다 틀릴 여지가 적다.
- 같은 필드를 별칭과 필드 id 로 동시에 주면 거부된다(
400). 하나만 준다. - 그 역할의 필드가 리스트에 없거나 여러 개면 거부된다. 그때는 필드 id 로 준다.
assignee에는 사용자 id 를,dueDate에는"YYYY-MM-DD"또는{ "due": …, "start": … }를 넣는다.
선택지가 정해진 필드(상태·이슈 타입·우선순위)에는 라벨 말고 옵션 id 를 보낸다. 라벨은 별칭 키로 줬을 때, 그리고 라벨이 옵션 하나와 대소문자까지 정확히 일치할 때만 옵션 id 로 바뀐다. 옵션 id 는 describe 의 fieldMap 에서 그 필드의 options 로 조회한다.
이슈 타입은 --issue-type 으로 라벨을 줘도 된다. CLI 가 대소문자를 가리지 않고 옵션 id 로 바꾸고, 라벨이 여러 옵션에 걸리면 고르지 않고 오류를 낸다. create·update·bulk-create 에서 쓸 수 있다.
dillie project tasks create ACME --issue-type Bug --data '{"values":{"title":"빈 목록이 로딩 중과 구분되지 않음"}}'
제목 쓰기
제목은 검색 결과와 목록에서 그 아이템을 알아보는 줄이다.
- 무엇을 하는가로 쓴다. “로그인 버그” 보다 “빈 목록이 로딩 중과 구분되지 않음”.
- 어디를 고치는가를 넣는다. 검색 결과 목록에서 제목만 보고 고를 수 있어야 한다.
- 이슈 타입 필드가 있는 리스트에서는 접두어로 유형을 분류하지 않는다. 그 필드가 유형을 이미 들고 있다.
문제 해결
값 키가 거부된다
메시지에 거부된 키가 나온다. 지난 세션에 본 필드 id 를 그대로 썼을 수 있다 — describe 를 다시 불러 fieldMap.fields 에서 키를 다시 고른다. 별칭과 그 필드 id 를 함께 보냈다면 하나를 뺀다.
본문이 거부된다
본문에 코드 밖의 HTML·JSX 태그나 꺾쇠 표기가 있다. 백틱으로 감싸거나 마크다운 문법으로 바꾼다. 그 밖의 거부를 읽는 법은 dillie CLI 로 일하기 — 문제 해결에 있다.