frontmatter 필드
사람이 쓰는 필드는 디스패처와 엔진이 쓰는 필드와 구분됩니다(티켓이 지나는 상태가
이미 그 경계를 설명했습니다). 사람이 쓰는 필드에 엔진 쪽 값을 미리 채워 넣으면 안 됩니다.
session_id:를 채워두면 이미 할당된 티켓으로 보이고, 그러면 어떤 워커도 그 티켓을
가져가지 않습니다.
사람이 쓰는 필드
| 필드 | 필수 | 뜻 |
|---|---|---|
ticket | ✓ | 해시. 파일명과 같게 둡니다(없으면 파일명에서 땁니다) |
title | ✓ | 사람이 읽는 제목 |
kind | work=지시 / request=부탁 / feedback=결과보고 / answer=답변 파일. 표시용이고 값을 강제하지 않습니다 | |
persona | 수행할 페르소나 이름. 없으면 페르소나 없는 평범한 에이전트가 처리합니다. 알파벳·숫자·-·_만 통과합니다 | |
squad | 수행할 스쿼드 이름 하나. deps와 달리 목록([...])이 아닙니다. 엔진이 이 값을 해석해 그 묶음의 리더를 띄우고 persona를 그 이름으로 덮어쓰기 때문에 persona와 함께 적지 않습니다(스쿼드) | |
deps | [<hash>...] 반드시 지켜야 하는 선후 관계. 전부 완료여야 큐에 뜹니다 | |
priority | 1~5. 없거나 못 읽거나 범위 밖이면 3으로 읽습니다. 높은 쪽이 먼저 뽑히고, 높은 티켓이 기다리는 선행은 그 값을 물려받습니다 | |
duedate | ISO 8601 시각(2026-08-14T18:00:00+09:00. 오프셋을 생략하면 로컬 시각). 남은 시간이 5시간 이하면(이미 지난 것 포함) 5로, 자기 duedate가 있고 7일 이상 남았으면 1로 읽습니다. 그 사이는 적힌 priority가 그대로 적용됩니다 | |
req | 요구에서 쪼개져 나온 티켓이 적는 원본 요구의 해시. 순서가 아니라 출처라서 deps와 다릅니다 | |
epic | 이 티켓이 속한 묶음의 번호 하나(P273). deps와 달리 목록([...])이 아니고 값을 파싱하지도 않습니다. 엔진은 이 값을 읽지 않으며, 화면 표시만 달라집니다(에픽) | |
archives | 아카이브 티켓이 적는 대상 티켓 해시 하나. deps와 달리 목록([...])이 아닙니다. 이 값이 있으면 보드에 독립된 카드로 표시되지 않고 대상 티켓에 겹쳐 붙습니다 | |
continued | 다 못 끝낸 세션이 남은 범위를 넘긴 후속 티켓의 해시 하나. archives와 같이 목록([...])이 아닙니다. 이 값이 있으면 완료 배지가 완료(이어짐)으로 바뀌고 그 후속으로 가는 링크가 됩니다(티켓이 지나는 상태) | |
handoffs | 이어받기 티켓이 자기가 몇 번째인지 적는 숫자. 앞 티켓 값에 1을 더해 씁니다. 키가 없으면 0으로 읽으니 첫 이어받기가 1입니다. 이 값이 3을 넘으면, 그러니까 네 번째 이어받기부터는 엔진이 티켓을 가져가자마자 다시 놓고 답변 대기로 잠급니다(티켓이 지나는 상태) | |
polling | 이 티켓이 기다리는 폴링 스크립트의 파일명 하나. 경로를 적는 칸이 아니라서 /가 섞이면 엔진이 거절합니다. 스크립트는 큐 루트 밑 polls/에 둡니다. 이 값이 비어 있지 않은 동안 그 티켓은 열려 있어도 후보에서 빠집니다(티켓이 지나는 상태) | |
polling_until | 그 대기의 상한. ISO 8601 시각(duedate와 같은 형식)이고, 이 시각을 넘기면 엔진이 폴링을 그만두고 티켓을 답변 대기로 잠급니다 |
디스패처와 엔진이 쓰는 필드
| 필드 | 쓰는 시점 | 뜻 |
|---|---|---|
session_id | assign — 엔진을 띄우기 전 | 있으면 할당된 것으로 보고 큐에서 제외합니다. 큐에서 제외할지는 이 값 하나로만 판정합니다 |
assigned_at | assign과 동시 | 할당 시각(reap의 유예 판정에 쓰입니다) |
owner | assign(자동 디스패치) 또는 handclaim(손 클레임) | 자동이면 <페르소나 또는 agent> / <워커>-<sid 앞8자리>, 손 클레임이면 호출자가 준 식별자 |
pid | setpid — 엔진을 백그라운드로 띄운 뒤, 또는 handclaim이 조상 claude pid를 기록 | 생존 확인용. 큐 제외 판정과는 상관이 없습니다 |
inbox | setinbox — 최초 프롬프트 주입이 끝난 뒤 | 참견 FIFO 경로. FIFO 파일은 세션이 끝나면 사라지지만 이 값 자체는 정상 완료나 자동 스테일 회수로는 안 지워집니다. unassign이나 디스패치 실패로만 비워집니다 |
claimed_at | handclaim | 손으로 가져간 시각(유휴 판정 유예에 쓰입니다) |
transcript | handclaim | 그 순간 가장 최근 트랜스크립트 경로(유휴 판정용) |
attempts | reap, 그리고 세션이 실패로 끝나는 자리 | 자동 회수 횟수입니다. 계정 한도나 과부하로 죽은 회차, 그리고 더 급한 티켓에 밀려 외부에서 종료된 회차는 세지 않습니다. 상한은 사유에 따라 두 가지입니다. reap이 회수해 온 회차와 요청 자체가 잘못되어 실패한 회차는 2회까지 세고 3회째에 답변 요청으로 올라가면서 이 값이 0으로 리셋됩니다. 그 밖의 실패는 10회까지 세고 11회째부터는 사람을 부르지 않고 그 티켓을 일정 시간 대기시켰다가 다시 디스패치합니다. 이 경우에는 리셋하지 않으므로 값이 10보다 커집니다. 사유마다 칸을 따로 두지는 않습니다. 횟수는 한 칸에 쌓이고, 사유에 따라 달라지는 것은 상한뿐입니다. 티켓 상세 오른쪽 맨 위의 다시 할당 줄과는 세는 사건이 다릅니다 |
awaiting | 엔진이 답변 요청으로 올릴 때(위 attempts가 상한 2를 넘긴 회차, 또는 본문 마지막 절이 ## 블록이면 횟수와 무관하게 즉시), 그리고 사람이 unassign --force로 세션을 끊을 때 | 존재하지 않는 해시. 같은 값이 deps에도 같이 들어가고, 큐를 잠그는 것은 그 deps 쪽입니다. 같은 이름의 답변 파일(<awaiting>.done.md)이 생기면 저절로 풀립니다 |
polled_at | 워커가 폴링 스크립트를 한 번 돌릴 때마다 | 마지막으로 돌린 시각. 스크립트 상단에 적힌 주기를 지키는 근거입니다. 이 값이 없으면 아직 한 번도 안 돌린 것입니다 |
polling_fails | 폴링 스크립트가 오류로 끝났을 때 | 연속으로 오류가 난 횟수입니다. 한 번 성공하면 엔진이 이 값을 지웁니다. 3에 이르면 그 티켓도 답변 대기로 잠깁니다 |
awaiting은 세션도 씁니다. 요구를 쪼개던 세션이 추측하지 않고는 더 진행할 수 없을 때 이
값을 직접 적습니다. 답이 도착한 뒤에도 지우지 않습니다. 기록으로 남기기 위해서이고, 아직
기다리는 중인지는 답변 파일이 있는지로 판단합니다.
표 밖의 규칙 넷
priority에 5를 쓰는 것은 사람의 판단입니다. 그 값은 이미 수행 중인 티켓을 선점하기
때문에 세션은 1~4까지만 씁니다.
duedate는 priority를 고쳐 쓰지 않습니다. 티켓을 뽑을 때 현재 시각을 한 번 확인하고 그
순간에만 우선순위를 높이거나 낮춥니다. 파일에 적힌 숫자는 그대로 남습니다.
kind: answer는 만들어질 때부터 완료 상태입니다(<awaiting>.done.md). 사람이나 앱이
만듭니다. 세션은 이 파일을 만들지 않습니다. 열린 상태로 만들면 페르소나 없는 티켓으로 아무
워커에게나 디스패치될 텐데, 이 파일에는 애초에 수행할 내용이 없기 때문입니다.
무엇을 왜 기다리는지를 적는 칸은 이 표에 없습니다. 대기 사유는 본문에 적습니다.
대기를 걸고 작업을 마치는 세션이 ## 결과 절의 첫 줄에 한 문장으로 씁니다. 보드 카드의 배지
아래 한 줄과 티켓 상세 폴링 대기 절의 사유 행이 그 문장을 그대로 옮긴 것입니다(티켓이
지나는 상태). 이 표에서 그 키를 찾으실 필요는 없습니다.
polling과 polling_until은 사람이 쓰는 칸에 있지만 파일을 열어 손으로 채우는 값은 아닙니다.
기다리기로 한 세션이 워커 스크립트를 통해 적습니다(workers/<워커>.sh poll <해시> <스크립트 파일명> <상한>). 그러면 엔진이 값을 넣기 전에 다섯 가지를 검사합니다. 그 파일이
polls/ 밑에 실제로 있는지부터 확인하고, 마지막에는 스크립트를 그 자리에서 한 번 실행해
보기까지 합니다. 하나라도 어긋나면 파일을 한 글자도 안 고치고 거절합니다. 손으로 적으면 이
검사를 통째로 건너뛰기 때문에, 없는 파일을 가리키는 티켓이 상한 시각이 될 때까지 아무 알림
없이 대기 상태로 남습니다.
화면에서 고치는 자리 - 티켓 상세의 frontmatter 절
이 표의 키를 파일을 열지 않고 고치는 자리가 하나 있습니다. 티켓 상세 왼쪽 위 frontmatter
절입니다. 온톨로지 카드와 같은 행 편집기라 줄마다 키 칸과 값 칸이 있고, 조작법은
아카이빙과 온톨로지에 적힌 그대로입니다. 고친 뒤 절 오른쪽 아래 저장을
누르세요.
열린 티켓만 고쳐집니다. 진행중(.wip)과 완료(.done)는 행 대신 읽기 전용 표가 뜹니다.
본문 편집 폼이 잠기는 것과 같은 이유입니다 - 세션이 점유하고 있는 파일을 화면에서 고치면
그 세션이 방금 읽은 값과 어긋나기 때문입니다.
행으로 뜨는 것은 deps - req - epic - awaiting - continued - archives -
handoffs, 그리고 이 표에 없는 키를 직접 더한 것입니다. 나머지 키는 두 갈래로 나뉩니다.
- 편집 폼에 이미 든 여섯 -
title-kind-persona-squad-priority-duedate. 오른쪽 편집 폼이 정본이라 프론트매터 칸에는 안 뜹니다. 같은 키를 두 자리에서 고치면 나중에 저장한 값이 아무 경고 없이 앞선 값을 덮어씁니다. - 엔진이 기록하는 실행 키 - 아래 표에 보이되 못 고칩니다.
보이되 못 고치는 키
행 목록 밑에 작은 표가 하나 더 붙습니다. 엔진이 기록한 사실을 담고 있어서 읽기 전용입니다. 손으로 고치면 지금 수행 중인 세션의 claim이 화면에서 깨집니다.
여기에 해당하는 키는 ticket - session_id - assigned_at - pid - owner - inbox -
attempts - claimed_at - transcript - polled_at - default_answer, 그리고 polling으로
시작하는 셋(polling - polling_until - polling_fails)입니다.
polling과 polling_until이 여기에 포함된 이유는 위 '표 밖의 규칙 넷'에 적은
그대로입니다. 그 값은 다섯 가지 검사를 모두 통과한 뒤에만 기록됩니다.
폴링 키 셋을 앱이 고치는 자리는 따로 있습니다. 티켓 상세 폴링 대기 절에 있는 버튼
둘입니다(화면 소개). 지금 디스패치는 polling과 polling_fails를
비우고, 상한 늘리기는 polling_until을 새 시각으로 다시 적습니다. polled_at은 어느 쪽에서도
안 지워집니다. 언제까지 기다렸던 티켓인지가 기록으로 남아야 하기 때문입니다.
표는 assigned_at까지 보여주고 나머지는 펼치기로 엽니다. 파일에 없는 키는 줄이 아예
없습니다. 아무 워커도 가져간 적 없는 티켓이면 이 표가 통째로 안 뜹니다.
검사는 여기서도 안 합니다
deps:와 req:의 값 칸에는 이 큐의 티켓 해시가 후보로 뜹니다. 후보는 고르기 편하도록
제공될 뿐이라, 없는 해시를 직접 입력해도 그대로 저장됩니다. 화면은 이 표의 규칙을 검사하지
않습니다 - squad와 persona를 같이 적어도, epic에 목록을 적어도 막지 않습니다. 잘못 쓴
값이 어떻게 읽히는지는 위 두 표에 적힌 그대로입니다.
티켓 화면에는 원문을 통째로 보는 평문으로 버튼이 없습니다. 프론트매터 원문 그대로를 봐야
하면 파일을 직접 여세요.
여기까지가 매뉴얼입니다. 이 표를 손으로 쓸 일이 생기는 자리는 티켓 직접 발행하기입니다.