# OpenClaw 작업 레지스트리 각 작업의 **단일 진입점 명령**과 **트리거**를 한 줄로 매핑한다. > 사용자 또는 에이전트가 "지금 X 한 번 실행해줘"라고 했을 때 — **이 표의 명령만 실행하면 된다.** > cron/launchd 트리거를 만지지 마라. 트리거는 "언제"이고 명령은 "무엇"이다. 두 개는 별개다. --- ## 1. 단순 스크립트 작업 (LLM 불필요 — launchd 단독 운영) | 작업 | 진입점 명령 | 트리거 | |---|---|---| | **OpenClaw Gateway** | `openclaw gateway --port 18789` | launchd `ai.openclaw.gateway` (상시) | | **비하이브 웹뷰** | `python3 ~/.openclaw/agents/stock/workspace/scripts/behive_web.py serve` | launchd `ai.openclaw.stock.behive-web` (상시) | | **웹 채팅 (클로·레이·골디)** | `python3 ~/.openclaw/workspace/scripts/chat_web.py serve` | launchd `ai.openclaw.chat-web` (상시, 포트 18793). `chat.hyowons.net` → NAS 리버스 프록시. 로그인 = iMessage OTP 단독(비밀번호 없음, 코드 발송 1분 1회·1시간 5회 제한) | | **후잉 동기화** | `python3 ~/.openclaw/agents/budget/workspace/skills/whooing-sync/scripts/whooing_sync.py` | launchd `ai.openclaw.budget.whooing-sync` (매 15분). 매 사이클 끝에 **가희 잔액 리마인더·자동분개** 모듈(`gahee_reminder.run`)도 함께 호출 — 매월 25일 10:00 KST 이후 첫 사이클에서 가희님께 iMessage 1회 발신, 이후 답신 폴링 → 텍스트면 후잉 가희주머니 차액 자동 분개, 이미지면 텔레그램 알림만 | | **주식 포트폴리오 스냅샷** | `python3 ~/.openclaw/agents/stock/workspace/scripts/stock_portfolio_report.py send --no-mail` | launchd `ai.openclaw.stock.briefing` (평일 20:10) + 폴백 `-fallback-2030`(20:30, 스냅샷 없을 때만) · `-fallback-2100`(21:00, **무조건 fresh 재조회**). **메일 발송 중지**(2026-08-12 관리자님 결정 — 메일 통수 축소). `--no-mail`은 휴장일 self-skip·실패 텔레그램 알림은 유지하고 메일만 건너뜀. 목적은 자산웹 '당일 평가손익' 기준값이 되는 스냅샷 확보. 리포트 본문을 눈으로 보려면 `run`(메일 없이 평문+`/tmp/stock_report_preview.html`) | | **증권잔액 → 골디 inbox** | `python3 ~/.openclaw/agents/stock/workspace/scripts/send_balance_to_budget.py` | launchd `ai.openclaw.stock.send-balance` (매월 1일 04:30) | | **골디 inbox 처리** (단독) | `python3 ~/.openclaw/agents/budget/workspace/skills/monthly-settlement/scripts/inbox_handler.py [--dry-run]` | 트리거 없음 — 월간결산 cron 진입부에서 자동 호출. 수동 점검·재처리용 | | **워치리스트 모니터링** | `python3 ~/.openclaw/agents/stock/workspace/scripts/watchlist_monitor.py check` | launchd `ai.openclaw.stock.watchlist-monitor` (평일 **10/12/14시 3회** — 2026-05-12 15분 간격에서 축소) | | **트레일링 스톱 감시** | `python3 ~/.openclaw/agents/stock/workspace/scripts/trailing_monitor.py {check [--repeat N --gap S] [--force] [--dry-run]\|list}` | launchd `ai.openclaw.stock.trailing-monitor` (평일 **08:00–19:59 매 1분**, 720엔트리 — 2026-08-25 plist 실측 정정. 스크립트가 장외·휴장 self-skip). 하는 일 둘: ①자산웹에서 PIN 승인된 트레일링 예약의 조건단가를 고점 갱신 시 kt10002로 **상향만** 정정 ②**예약 트레일링(TRAILING_ARM) 발동·만료** — 발동가 도달 시 스톱주문 신규 발주 + 예약 승격, 미발동으로 등록일이 지난 대기 예약은 자동 취소(둘 다 2026-08-25 추가, 관리자님 승인). ⚠️ "신규 발주 없음"은 더 이상 사실이 아니다. 예약 0건이면 즉시 종료(API 콜 0). 상태 `state/trailing_stops.json`. ⚠️ cadence 변경 이력 2분→30초→**1분**(2026-07-30 관리자님) — 30초는 launchd로 불가해 `--repeat 2 --gap 30`(프로세스 내부 2회)으로 구현했었고, 옵션은 살아있으니 다시 쓸 땐 plist 인자만 추가 | | **급등락 알림** | `python3 ~/.openclaw/agents/stock/workspace/scripts/surge_monitor.py {check [--force]\|dry-run\|list}` | launchd `ai.openclaw.stock.surge-monitor` (09:00–19:59 매 1분, 660엔트리 — 스크립트가 휴장·장외 self-skip. 2026-09-22 KRX 애프터마켓 대응으로 15:35 → 20:00 확대). 토글 켠 종목만 감시(상·하한가 / VI 발동 / 자기이력 분위수) → 레이 텔레그램. 토글 0건이면 API 콜 0 | | **codex 폴백 감시** | `python3 ~/.openclaw/workspace/scripts/codex_fallback_monitor.py [--dry-run]` | launchd `ai.openclaw.codex-fallback-monitor` (매 5분). 주 모델이 죽어 유료 OpenRouter 로 폴백하면 클로 텔레그램. 무비용(on-disk sqlite 스캔) | | **git 자동 백업** | `sh ~/.openclaw/scripts/git_autopush.sh` | launchd `ai.openclaw.git-autopush` (매일 02:00). 변경 있을 때만 커밋·푸시 | | **헬스체크** | `python3 ~/.openclaw/scripts/health_check.py [--dry-run] [--verbose]` | launchd `ai.openclaw.health-check` (**매일 09:00**). §4 표를 파싱해 stale·데몬 사망 검사, 이상 있을 때만 텔레그램(같은 이상은 7일간 재발송 안 함). 매월 1일엔 `MAINTENANCE.md` 월간 점검 리마인더 | | **로그 로테이션** | `python3 ~/.openclaw/scripts/log_rotate.py [--dry-run]` | launchd `ai.openclaw.log-rotate` (매주 일요일 04:00). 30일 초과 로그 trash + 20MB 초과 활성 로그 in-place 축소 | | **공모주 캘린더 동기화** | `python3 ~/.openclaw/agents/stock/workspace/scripts/ipo_calendar_sync.py` | launchd `ai.openclaw.stock.ipo-calendar-sync` (**월·수·금 17:00**) | | **FOMC 캘린더 동기화** | `python3 ~/.openclaw/agents/stock/workspace/scripts/fomc_calendar_sync.py [--list\|--dry-run]` | launchd `ai.openclaw.stock.fomc-calendar-sync` (매월 1일 09:10). 연준 공식 일정표 → `[FOMC] YYYY-MM 회의` 종일 일정(회의 시작일 ET ~ 발표일 KST). `--list`는 파싱 결과만(캘린더 미접근) | | **휴장일 동기화** | `python3 ~/.openclaw/agents/stock/workspace/scripts/holiday_sync.py [--show]` | launchd `ai.openclaw.stock.holiday-sync` (매주 일요일 03:00) | | **Gmail 라벨 분류** | `python3 ~/.openclaw/workspace/scripts/gmail_label_classify.py [--dry-run]` | launchd `ai.openclaw.gmail-label-classify` (매일 01:00). self-sent 브리핑·종목분석·주식 리포트 메일 라벨링 + 24h 테스트메일 휴지통. LLM 미경유(`gog` CLI). 2026-06-26 cron→launchd 이관 | | **매매 기록 적재** | `python3 ~/.openclaw/agents/stock/workspace/scripts/trade_journal.py {collect\|seed\|show\|query} ...` | launchd `ai.openclaw.stock.trade-journal` (평일 21:00 — NXT 야간 마감 후 ka10170 4계좌 적재). `seed`는 적재 시작일 이전 보유분을 현재 평단가로 1회 시드 (idempotent) | | **자동매매 시뮬 스캔** | `cd ~/.openclaw/agents/stock/workspace && python3 -m sim {scan [--force]\|status\|report\|reset --yes}` | launchd `ai.openclaw.stock.sim-scan` (09–15:30 **매 2분**, 196엔트리 — 엔진이 장외·휴장 self-skip). 가상자본 **1억** 페이퍼 트레이딩, 규칙 엔진(LLM 미경유). 결과 `state/sim/`. 실주문 아님 | | **자동매매 시뮬 대시보드** | `cd ~/.openclaw/agents/stock/workspace && python3 -m sim.sim_web {serve\|render}` | launchd `ai.openclaw.stock.sim-web` (상시). 포트 18792 → `sim.hyowons.net`(reverse proxy 수동 등록 대기). **3탭**(전략·관심종목·시장 — 계좌·튜닝 탭은 2026-06-10 삭제), 읽기전용+`/save_params`만 쓰기 | | **시뮬 파라미터 스윕(튜닝 비교)** | `cd ~/.openclaw/agents/stock/workspace && python3 -m sim {sweep [frac]\|backtest}` | 트리거 없음(on-demand). **1536조합** 백테스트 학습/검증 비교 → `state/sim/backtest_results.json`(웹 백테스트 탭 표시). 튜닝값은 `state/sim/params.json`(웹 튜닝 탭) | | **Claude Code 원격 세션** (on-demand, 다중) | `python3 ~/.openclaw/workspace/skills/claude-code-session/scripts/session_tool.py {profile\|session} ...` (legacy 단일: `ensure_session.sh {open\|close\|status}`) | 세션 plist는 `~/Library/LaunchAgents/ai.claude-session.-.plist`로 ephemeral, 레거시 단일은 `ai.openclaw.claude-remote-control`. 모두 RunAtLoad=false, KeepAlive=false. 클로 `claude-code-session` 스킬이 자연어 라우팅. | | **테일스케일 켜기·끄기** (on-demand) | `python3 ~/.openclaw/workspace/scripts/tailscale_ctl.py {on|off|status}` | 트리거 없음 — 관리자님이 "테일스케일 꺼줘/켜줘/상태" 라고 할 때 클로가 호출. sudo 불필요(localapi + sameuserproof 토큰). ⚠️ `off` 하면 타넷 경유 접근이 전부 끊긴다(stock.hyowons.net·sim.hyowons.net·폰에서 맥 직접 접근). 텔레그램은 아웃바운드라 영향 없어 되돌릴 길은 항상 남는다. behive_web 은 `BIND_HOST=''` 라 프로세스가 죽지 않고 루프백·LAN 접근은 유지. `up` 후 설정·로그인 상태는 보존되고 재인증 불필요(실측 왕복 복구 1초). ⚠️ **자동 트리거(cron/launchd)에 걸지 말 것** | 수동 실행: 진입점 명령만 그대로 터미널에서 실행하면 된다. launchctl 만지지 마라. --- ## 2. LLM 자연어 작업 (OpenClaw cron — `state/openclaw.sqlite` 의 `cron_jobs` 테이블) LLM이 자막 요약·뉴스 평문 생성·결산 보고서 등 본문을 만들어야 하는 작업만 여기 남는다. | 작업 | 진입점 (사람이 시키는 한 마디) | 트리거 | |---|---|---| | **오전 브리핑** (main/클로) | "오전 브리핑 메일 보내줘" → cron payload의 step 그대로 실행 (미국증시 요약 포함) | OpenClaw cron `56d66b54` (**월~토** 07:30) + 1차폴백 `c4f2d3e5...0755` (07:55) + 2차폴백·최종 `b3f1c2d4...0830` (08:30, US 미게시여도 발송). **일요일 없음**. **토요일은 해외 전용**(스크립트가 `overseas_only` 판정 → 해외 뉴스만·일정·IPO 생략) | | **오후 브리핑** (main/클로) | "오후 브리핑 메일 보내줘" → cron payload의 step 그대로 실행 | OpenClaw cron `9d2c105f` (**평일** 19:00). 주말 없음 | | **비하이브 종목분석 요약** (stock/레이) | "비하이브 신규 영상 점검해줘" → cron payload의 step 그대로 실행 | OpenClaw cron `80052b62` (평일 07/12/18시). 등록명은 "비하이브 추천영상 요약" | | **월간 결산** (budget/골디) | "월간 결산 돌려줘" → cron payload의 step 그대로 실행 | OpenClaw cron `08e9a978` (매월 1일 05:00) | 수동 실행: 사용자가 해당 에이전트에게 작업 이름만 말하면, 에이전트는 `openclaw cron show ` 의 동일 ID 페이로드 step을 그대로 따라 실행한다. **cron 활성화 여부·스케줄 시간을 만지는 작업은 트리거 변경 요청이 명시적으로 있을 때만.** --- ## 3. 운영 원칙 — 트리거 vs 작업 분리 1. **트리거(언제)와 작업(무엇)은 별개다.** "지금 X 실행"은 항상 §1·§2의 진입점 명령만 실행. cron/launchd 등록·해제·재실행은 별도 요청. 2. **payload에 "매일 X시 자동 실행" 같은 자가묘사 메타 문구를 넣지 마라.** 페이로드는 "무엇을 어떻게"만 담는다. "언제"는 schedule 필드가 단일 진실 공급원. 3. **새 트리거를 만들 땐 단순 스크립트면 launchd, LLM이 본문을 생성해야 하면 OpenClaw cron.** 이중 등록 금지. 이관 시 한쪽 완전 제거. 4. **Disabled 좀비 잡 즉시 제거.** `enabled:false`로 두지 말고 `openclaw cron delete ` 로 빼라. 검색에 잡혀서 혼선 유발. 5. **트리거 추가/이관/제거는 담당 에이전트의 MEMORY.md에 반드시 기록.** --- ## 4. 헬스체크 (자동 감시 대상) `scripts/health_check.py` 가 **이 표를 파싱해서** 돈다. 행을 고치면 감시가 바뀐다 — 표가 곧 설정이라, 트리거를 바꾸고 표를 안 고치면 알림이 떠서 드리프트가 스스로 드러난다. **증거 고르는 법:** "그 잡이 돌면 **반드시** 갱신되는" 파일이어야 한다. `surge_alerts.json`·`trailing_stops.json`·`whooing_synced.json` 처럼 **일이 있을 때만** 쓰이는 파일은 조용한 날 stale 로 보여 오탐이 된다 — 그런 잡은 로그 파일을 증거로 쓴다. 반대로 `holiday_sync` 처럼 "돌긴 도는데 결과가 옛것"인 실패(2026-07~09 2개월 stale)를 잡으려면 로그가 아니라 **결과 파일**이어야 한다. **기대 주기:** 평일 전용 잡은 금→월 72h 에 여유를 더해 `100h`. ⚠️ 설·추석 등 3일 초과 연휴엔 오탐이 날 수 있다(휴장일 보정은 넣지 않았다 — 연 2회 오탐을 감수하는 대신 로직을 단순하게 뒀다). `daemon:` 접두는 주기 대신 **프로세스 생존**(PID)을 본다. | 작업 | 증거 (mtime 기준) | 기대 주기 | |---|---|---| | OpenClaw Gateway | `daemon:ai.openclaw.gateway` | - | | 비하이브 웹뷰 | `daemon:ai.openclaw.stock.behive-web` | - | | 시뮬 대시보드 | `daemon:ai.openclaw.stock.sim-web` | - | | 웹 채팅 | `daemon:ai.openclaw.chat-web` | - | | 후잉 동기화 | `logs/whooing-sync.log` | 2h | | codex 폴백 감시 | `logs/codex-fallback-monitor.log` | 2h | | 급등락 알림 | `logs/stock-surge-monitor.log` | 100h | | 트레일링 스톱 감시 | `agents/stock/workspace/state/trailing_monitor_heartbeat` | 100h | | 워치리스트 모니터링 | `logs/watchlist-monitor.log` | 100h | | 자동매매 시뮬 스캔 | `agents/stock/workspace/state/sim/last_scan.json` | 100h | | 주식 포트폴리오 스냅샷 | `agents/stock/workspace/state/portfolio_daily_snapshot.json` | 100h | | 매매 기록 적재 | `agents/stock/workspace/state/trade_journal.jsonl` | 100h | | 시장지표 적재 | `agents/stock/workspace/state/market_indicators_history.jsonl` | 100h | | Gmail 라벨 분류 | `workspace/state/gmail_label_classify.log` | 30h | | git 자동 백업 | `logs/git-autopush.log` | 30h | | 휴장일 동기화 | `agents/stock/workspace/state/market_holidays.json` | 8d | | 공모주 캘린더 동기화 | `agents/stock/workspace/state/ipo_calendar_sync.json` | 5d | | FOMC 캘린더 동기화 | `agents/stock/workspace/state/fomc_calendar_sync.json` | 35d | | 증권잔액 → 골디 inbox | `logs/send-balance.log` | 35d | | 로그 로테이션 | `logs/log-rotate.log` | 8d | 감시하지 **않는** 것과 이유: - **OpenClaw cron 4종**(브리핑·비하이브·월간결산) — 실패하면 메일·텔레그램이 안 와서 관리자님이 바로 아신다. 게다가 `openclaw cron list` 의 `Last`/`Status` 가 이미 이력을 들고 있다 - **시뮬 스윕·골디 inbox 처리** — on-demand 라 기대 주기가 없다 - **`sim.backfill_flow`·`sim universe`** — `stock.trade-journal` plist 가 묶어 도는 5개 명령 중 3·4번째다(5번째는 `kiwoom_client refresh-codes --if-stale 7` — 종목코드 캐시 주 1회 갱신, 2026-09-10 추가. 이 캐시의 `nxt_enable` 이 자산웹 NXT 판정 근거라 낡으면 🔥배지·거래가능 초록점이 틀어진다. 금액엔 영향 없음). 앞 2개(매매기록·시장지표)는 위에서 감시하지만 이 둘은 뺐다 — 결과물(`flow_history.sqlite`·`auto_seen.json`)이 stale 해도 백테스트 수급게이트가 중립으로 비활성되고 sim 관찰목록 자동편입이 멈출 뿐, **실매매·실주문에는 영향이 없다**. ⚠️ 다만 plist 는 `하나 실패해도 나머지 시도` 구조라 이 둘만 조용히 죽을 수 있다 — sim 백테스트 결과가 이상하면 여기부터 본다 - **Claude Code 원격 세션** — ephemeral --- ## 5. 알려진 이슈 / 진단 절차 - **bonjour 광고 stuck → gateway crash 루프** (2026-04-28 한 차례 발생, 현재는 정상) - 증상: `~/.openclaw/logs/stability/` 에 `*unhandled_rejection.json` 누적, gateway PID 계속 변경, `openclaw cron list`가 `gateway closed (1006)` 응답 - 원인: LAN의 mDNS 이름 충돌(`openclaw.local` 또는 `... (OpenClaw)` 서비스명) + OpenClaw bonjour 모듈의 catch 누락 코드 path - 1차 조치: `sudo killall -HUP mDNSResponder` + `launchctl kickstart -k gui/$UID/ai.openclaw.gateway`. 이걸로 보통 풀린다 (mDNS 리셋 후 OpenClaw가 graceful handler로 들어가 이름에 `(2)` suffix 붙여 재광고) - 2차 조치 (재발 시): `openclaw config set plugins.entries.bonjour.enabled false` + gateway 재시작. 비활성 시 잃는 것은 `openclaw.local` 로컬 디스커버리만, 텔레그램·gateway·Tailscale serve·cron 모두 정상