HANDOFF-RESULT — 엔티티 보고서와 기록 형식
[SKILL.md](../SKILL.md) §6~§8 의 형식이다.
SKILL.md §6~§8 의 형식이다.
| 부분 | 등급 |
|---|---|
항목 필드 7개, status 4종, 모르는 값은 TBD, /workspace 파일 | 실측 — 첫 실제 실행의 보고서 형식 |
다른 앱에서 온 filled 를 완료로 세지 않기 | 실측 — 그 실행의 검증에서 나온 규칙 |
블록 머리·꼬리(
HANDOFF-RESULT
…
END HANDOFF-RESULT
), 머리 세 줄, source 어휘, 읽기 규칙, 판정 열, 기록 틀
|
미검증 — 이 스킬이 정한 형식 |
1. 봇이 돌려주는 블록#
HANDOFF-RESULT
run: 20260101-play-create-app
login: bot-account@example.com
account: Example Corp
language: English
| id | type | store | field | value | source | status |
|----|------|-------|-------|-------|--------|--------|
| APP-REC-001 | record | play | app | <생성된 앱 id> | console | filled |
| APP-LST-001 | listing | play | name | Sample | brief | filled |
| APP-CON-001 | listing | play | contactEmail | TBD | - | pending |
| APP-ACC-001 | account | play | appAccess.password | (보안 입력) | - | pending |
END HANDOFF-RESULT
| 필드 | 뜻 |
|---|---|
| id |
{앱}-{영역}-{번호}
. 영역 예: REC(레코드) · LST(등록정보) · CON(연락처) · POL(방침·URL) · PRIV(개인정보·데이터) · RAT(등급) · ACC(심사·접근) · GFX(그래픽) · BIN(바이너리) · MON(수익화)
|
| type | 항목 종류 — record · listing · declaration · asset · account · setting 등 |
| store | 어느 콘솔인가 — 도메인 스킬이 이름을 정한다 |
| field | 화면의 칸 이름 또는 값 시트 키 |
| value | 넣은 값. 모르면 TBD, 비밀값 칸은 (보안 입력) — 값 자체는 쓰지 않는다. | 를 쓰지 않는다 |
| source |
값을 어디서 가져왔나 —
brief
(브리프 입력값) ·
console
(콘솔이 만든 값: id·URL) ·
human
(사람이 넘겨받아 넣은 값: 약관 체크·보안 입력) ·
existing
(이미 있던 값). 그 밖의 값(다른 앱 등)은 봇이 적은 그대로 둔다
|
| status | filled · pending · blocked · not_submitted |
-
머리 네 줄 —
run(실행 id) ·login(봇이 화면에서 읽은 실제 계정) ·account(개발자 계정·팀 이름) ·language(화면 언어).login은 이슈에 옮길 때 공개될 수 있는 곳이면 역할 별칭으로 바꾼다.
2. 읽기#
봇의 마지막 응답만 파일로 저장해 읽는다. 대화 전체를 저장하면 붙여넣은 브리프의 예시 블록까지 들어와 블록이 둘이 된다.
REPORT=<봇의 마지막 응답만 저장한 파일>
BLOCK=$(mktemp)
sed -n '/^HANDOFF-RESULT$/,/^END HANDOFF-RESULT$/p' "$REPORT" > "$BLOCK"
# ① 블록이 정확히 하나인가 — 0 이면 결과 없음, 2 이상이면 브리프나 이전 응답이 섞였다
N=$(command grep -c '^HANDOFF-RESULT$' "$REPORT")
[ "$N" = 1 ] || echo "UNKNOWN 블록 ${N}개"
# ② 머리 네 줄 — login·account·language 를 브리프의 시작 확인 값과 대조한다
command grep -E '^(run|login|account|language): ' "$BLOCK"
# ③ 행 가르기 — 머리·빈 줄·표 머리를 뺀 나머지 중 | 로 시작하지 않거나 열이 7개가 아닌 줄은
# UNPARSED 로 따로 보여 주고, 나머지는 status 별로 센다
awk -F'|' '
/^(HANDOFF-RESULT|END HANDOFF-RESULT)$/ || /^(run|login|account|language): / || /^[[:space:]]*$/ { next }
/^\|/ && $2 ~ /^ *(id|:?-+:?) *$/ { next }
!/^\|/ || NF != 9 { print "UNPARSED\t" $0; next }
{ s = $8; gsub(/^ +| +$/, "", s); n[s]++; rows++ }
END { for (k in n) print k "\t" n[k]; print "ROWS\t" rows + 0 }' "$BLOCK"
# ④ filled 인데 출처가 brief·console·human 이 아닌 행 → replace 후보 (existing 도 든다)
awk -F'|' '/^\|/ && NF == 9 && $2 !~ /^ *(id|:?-+:?) *$/ {
id = $2; src = $7; st = $8
gsub(/^ +| +$/, "", id); gsub(/^ +| +$/, "", src); gsub(/^ +| +$/, "", st)
if (st == "filled" && src !~ /^(brief|console|human)$/) print "REPLACE?\t" id "\t" src }' "$BLOCK"
| 결과 | 읽는 법 |
|---|---|
UNKNOWN 블록 N개 | 결과 없음. 봇에게 형식대로 다시 요청한다(채팅 서술에서 추측하지 않는다) |
UNPARSED 행 |
표 모양이 아닌 줄(열이 밀렸거나 | 로 시작·끝나지 않음)이다. 그 행은 결과 없음 — 사람이 원문을 보고 판정한다 |
ROWS 0 (정규 실행) | 결과 없음 |
REPLACE? 행 |
§3 판정에서 replace 인지 먼저 본다. existing 은 가드 없이 채워진 콘솔이라면 다른 앱에서 복사된 값일 수 있다 |
드라이런 판정 — ① 출력이 없고(블록 하나), ② 에 머리 네 줄이 모두 있고, login 이 값 시트의 봇 계정(별칭이면 사람이 아는 실제 주소),
account 가 값 시트의 개발자 계정·팀 이름, language 가 런북의 칸 이름 언어와 같고, ③ 이 ROWS 0
이고 UNPARSED 가 없으면 통과다. 드라이런은 행이 없는 것이 정상이다.
3. Claude 가 붙이는 판정#
봇의 행은 그대로 두고 두 열을 덧붙인다 — verdict(판정), checked-by(확인한 경로). 판정의 뜻과 완료 집계는 SKILL.md
§7 표가 정본이다.
| checked-by 예 | 언제 |
|---|---|
api:<조회 이름> | API 로 다시 읽어 대조했다 |
human:<누가 무엇을 봤나> | 사람이 콘솔 화면을 보고 대조했다 |
public-page | 공개된 스토어 페이지로 대조했다 |
sheet |
값 시트의 확정 값과 대조했다(replace · mismatch 판정) |
4. 이슈 기록 틀#
실행 한 건에 코멘트 하나를 남긴다. 갱신하지 않고 실행마다 쌓는다 — 누가 언제 무엇을 했는지가 다음 실행의 판단 재료다.
<!-- cc-dev:grok-handoff -->
## 🤖 콘솔 작업 인계 기록 — {런북} · run {run-id}
- 날짜: {YYYY-MM-DD} · 브리프 승인: {승인자} {시각}
- 봇 로그인 계정: {역할 별칭} · 개발자 계정·팀: {이름}
- 봇 권한: 부여 {시각} → 회수 {시각 · 안 함 — 이유}
- 봇 보고: 엔티티 {N}건 — filled {a} · pending {b} · blocked {c} · not_submitted {d} · unparsed {e}
- 검증: verified {x} · replace {y} · mismatch {z} · unverified {w}
- 만든 레코드: {콘솔} {식별자}
- 남은 일: {id 목록} → {다음 행동}
- 세션: 로그아웃 {함 · 안 함 — 이유}
- 원본 보고서: {위치} (내용은 싣지 않음)
- 싣지 않는 것: 비밀번호·인증 코드·키, 보안 입력에 들어간 값, 심사 계정 자격 증명.
- 공개 저장소의 이슈면 계정 주소·콘솔 식별자를 자리표시자로 바꾼다.
-
가장 최근 기록 읽기:
gh issue view {n} --json comments -q '[.comments[] | select(.body | contains(""))] | last | .body'