대상: Android .9.png 납품을 원격 Mac에서 게이트해야 하는 게임·UI 옵스·빌드.
목표: OpenClaw 게이트웨이로 폴더 감시를 디바운스·single-flight 작업으로 접고 외곽 1px 링·명명·바이트·디스크 임계만 승격. 규칙은 9-patch M4 체크리스트, 운영 패턴은 감시·재시도·JSONL·PNG 일괄 QA와 맞춥니다.
왜 수동 확인이 깨지는가
부분 저장
중간 PNG가 큐에 섞여 패딩이 흔들립니다.
링 먼지
회색 알파가 기기별로만 드러납니다.
동기 경로
클라우드 폴더는 stat이 흔들립니다.
감시 방식 비교
| 방식 | 장점 | 한계 |
|---|---|---|
| 크론 | 단순 | 짧은 간격 저장을 합치기 어렵다 |
| 디바운스 감시 | quiet window로 완료 추정 | README에 루트·무시·락 고정 |
| 게이트웨이 | 허용 목록만 호출 | 토큰·ACL을 버전 관리 |
워치독은 상태 머신입니다. 준비는 설치 가이드로 동일 셸에서 재현하세요.
재현 단계와 플레이스홀더 명령
치환 값은 README에만 두고 플래그는 고정합니다.
- 트리 초기화
export NINE_ROOT="${HOME}/nine_jobs/<CAMPAIGN_ID>" mkdir -p "${NINE_ROOT}"/{inbox,work,out,failed,quarantine,logs,archive} - 디바운스 감시
fswatch -l 2.0 -o "${NINE_ROOT}/inbox" | while read -r _; do "${NINE_ROOT}/bin/debounced_enqueue.sh" done - 워커 단발 drain
"${NINE_ROOT}/bin/worker_once.sh" --max-files 32 --trace-id "$(uuidgen)" - 링 픽셀 검증
python3 "${NINE_ROOT}/bin/validate_patch_skirt.py" \ --path "${NINE_ROOT}/work/<ASSET>.9.png" \ --require-srgb-icc true \ --jsonl-out "${NINE_ROOT}/logs/validate.jsonl" - 승격 리네임
mv "${NINE_ROOT}/work/<ASSET>.9.png" \ "${NINE_ROOT}/out/ui__<SLUG>__<DENSITY>.9.png" - 감사 JSONL
printf '%s\n' "{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"event\":\"promote\",\"asset\":\"<SLUG>\",\"bytes\":<N>,\"trace_id\":\"<UUID>\"}" \ >> "${NINE_ROOT}/logs/audit-$(date -u +%Y-%m-%d).jsonl" - 아카이브 tarball
tar -czf "${NINE_ROOT}/archive/$(date -u +%Y-%m-%d)_<BATCH_ID>.tar.gz" -C "${NINE_ROOT}/out" .
명명 필드는 자동 명명·검증, JSONL 스키마는 Lottie 감시독과 공유하세요.
수락 임계 표
열 이름은 YAML 키로 그대로 옮깁니다.
| 게이트 | 측정 | 예시 통과선 | 실패 시 |
|---|---|---|---|
| 링 순도 | 외곽 1px 행·열 RGBA | 마커만 불투명 #000000·나머지 링 알파 0 |
격리·데이터류 재시도 금지 |
| 안티앨리어싱 먼지 | 링 위 0<α<255 픽셀 수 | 0개 | JSONL 기록 |
| 코너 투명 | 링 네 모서리 | 완전 투명 | 데이터류 |
| 파일 바이트 상한 | 파일 크기 | 밀도별 상한 예시 | 격리·알림 |
| 배치 합계 | 현재 dequeue 바이트 합 | 합계 상한 예시 | 큐 정지·resume |
| 여유 디스크 | 작업 볼륨 df |
여유 ≥15% 및 ≥25GiB | 전역 dequeue 정지 |
| ICC 정책 | 임베드 프로필 | sRGB IEC61966-2.1 서명 예외만 | ICC 수정 또는 격리 |
명명 템플릿 계약
| 토큰 | 의미 | 예 |
|---|---|---|
ui__<slug>__<density>.9.png |
모듈·슬러그·mdpi~xxhdpi | ui__hud_frame__xxhdpi.9.png |
<slug>_@<scale>x.9.png |
스튜디오 대체 스타일 | hud_frame_@3x.9.png |
manifest.jsonl |
승격 시 sha256 한 줄 | out/ 옆 사이드카 |
실패 분류·재시도·로그 회전
- 일시: 락·IO → 지터 백오프·
next_eligible_atJSONL. - 데이터: 링·템플릿·ICC → 자동 재시도 없음·
reason_code후 사람 플래그까지 재queue 금지. - 운영: 디스크·401·env → 전역 pause 후
resume.
한 줄에 trace_id·class·exit_code 등을 넣고 오래된 JSONL은 gzip해 archive/logs/로. 상세는 HowTo.
루프백·좁은 FS 허용·Git 고정 검증기·호출마다 동일
trace_id.
운영 체크리스트
- 로컬 NVMe·동기 경로 제외.
- 워처 단일 PID·quiet·이중 stat.
- 검증기 lockfile=CI.
- YAML 임계·웹훅
pause_reason. - JSONL 회전·gzip·분기 복구 리허설.
- 경로 변경 시 허용 목록 리뷰.
FAQ
수출 중 워커가 돌면?
quiet·임시 무시·.done·이중 stat 후 원자 이동.
ImageMagick으로 링 검사?
가능하나 빌드와 동일 디코더·버전 고정이 안전.
401은 비대화형에서만.
launchd·SSH 환경과 토큰 경로를 동일화.
Lottie 큐와 합칠까?
로그만 공유하고 inbox는 분리.
요약: 디바운스·링·임계·분류 재시도·JSONL gzip로 야간 게이트를 고정합니다. 대여·요금·SSH·VNC·기술 인사이트.
Mac 노드와 접속 방식 선택
전용 원격 Mac에서 nine-patch QA 워치독 돌리기
전용 노드에 검증기 버전을 고정하고 큐·JSONL 런북을 공유하세요.