launchd 일정성 리포트 4개 복구
시작 시각: 2026-04-15 16:08:07 KST
1. 현재 plist 원본 스냅샷
com.openclaw.morning-routine.plist
{
"EnvironmentVariables" => {
"HOME" => "/Users/ron"
"PATH" => "/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin"
}
"Label" => "com.openclaw.morning-routine"
"ProgramArguments" => [
0 => "/bin/bash"
1 => "/Users/ron/.openclaw/skills/smart-home/scripts/tts_morning.sh"
]
"StandardErrorPath" => "/Users/ron/.openclaw/logs/morning-routine.err.log"
"StandardOutPath" => "/Users/ron/.openclaw/logs/morning-routine.log"
"StartCalendarInterval" => {
"Hour" => 6
"Minute" => 30
}
}
com.openclaw.weekly-report.plist
{
"EnvironmentVariables" => {
"HOME" => "/Users/ron"
"PATH" => "/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin"
}
"Label" => "com.openclaw.weekly-report"
"ProgramArguments" => [
0 => "/bin/bash"
1 => "/Users/ron/.openclaw/skills/smart-home/scripts/tts_weekly.sh"
]
"StandardErrorPath" => "/Users/ron/.openclaw/logs/weekly-report.err.log"
"StandardOutPath" => "/Users/ron/.openclaw/logs/weekly-report.log"
"StartCalendarInterval" => {
"Hour" => 20
"Minute" => 0
"Weekday" => 0
}
}
com.openclaw.kpi-daily.plist
{
"Label" => "com.openclaw.kpi-daily"
"ProgramArguments" => [
0 => "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/Resources/Python.app/Contents/MacOS/Python"
1 => "/Users/ron/.openclaw/workspace/scripts/ron_kpi_tracker.py"
]
"StandardErrorPath" => "/Users/ron/.openclaw/logs/kpi_error.log"
"StandardOutPath" => "/Users/ron/.openclaw/logs/kpi_daily.log"
"StartCalendarInterval" => {
"Hour" => 0
"Minute" => 0
}
}
com.openclaw.kpi-weekly.plist
{
"Label" => "com.openclaw.kpi-weekly"
"ProgramArguments" => [
0 => "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/Resources/Python.app/Contents/MacOS/Python"
1 => "/Users/ron/.openclaw/workspace/scripts/ron_kpi_tracker.py"
2 => "--weekly"
]
"StandardErrorPath" => "/Users/ron/.openclaw/logs/kpi_weekly_error.log"
"StandardOutPath" => "/Users/ron/.openclaw/logs/kpi_weekly.log"
"StartCalendarInterval" => {
"Hour" => 9
"Minute" => 0
"Weekday" => 1
}
}
2. 복사/Rewrite 내역
- smart-home skill 복사: /Users/ron/.openclaw/skills/smart-home → /Users/ron/.hermes/skills/smart-home
- 복사본 내부 OpenClaw 루트 문자열을 Hermes 루트로 보정(민감값 미출력).
- plist 백업: /Users/ron/.hermes/backups/launchagents_20260415T160807
Rewrite 후 plist
com.openclaw.morning-routine.plist
{
"EnvironmentVariables" => {
"HOME" => "/Users/ron"
"PATH" => "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
"PYTHONPATH" => "/Users/ron/.hermes/workspace/scripts:/Users/ron/.hermes/workspace/scripts/shared:/Users/ron/.hermes/workspace/scripts/pipeline"
}
"Label" => "com.openclaw.morning-routine"
"ProgramArguments" => [
0 => "/bin/bash"
1 => "/Users/ron/.hermes/skills/smart-home/scripts/tts_morning.sh"
]
"StandardErrorPath" => "/Users/ron/.hermes/logs/morning-routine.err.log"
"StandardOutPath" => "/Users/ron/.hermes/logs/morning-routine.log"
"StartCalendarInterval" => {
"Hour" => 6
"Minute" => 30
}
"WorkingDirectory" => "/Users/ron/.hermes/workspace"
}
com.openclaw.weekly-report.plist
{
"EnvironmentVariables" => {
"HOME" => "/Users/ron"
"PATH" => "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
"PYTHONPATH" => "/Users/ron/.hermes/workspace/scripts:/Users/ron/.hermes/workspace/scripts/shared:/Users/ron/.hermes/workspace/scripts/pipeline"
}
"Label" => "com.openclaw.weekly-report"
"ProgramArguments" => [
0 => "/bin/bash"
1 => "/Users/ron/.hermes/skills/smart-home/scripts/tts_weekly.sh"
]
"StandardErrorPath" => "/Users/ron/.hermes/logs/weekly-report.err.log"
"StandardOutPath" => "/Users/ron/.hermes/logs/weekly-report.log"
"StartCalendarInterval" => {
"Hour" => 20
"Minute" => 0
"Weekday" => 0
}
"WorkingDirectory" => "/Users/ron/.hermes/workspace"
}
com.openclaw.kpi-daily.plist
{
"EnvironmentVariables" => {
"HOME" => "/Users/ron"
"PATH" => "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
"PYTHONPATH" => "/Users/ron/.hermes/workspace/scripts:/Users/ron/.hermes/workspace/scripts/shared:/Users/ron/.hermes/workspace/scripts/pipeline"
}
"Label" => "com.openclaw.kpi-daily"
"ProgramArguments" => [
0 => "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/Resources/Python.app/Contents/MacOS/Python"
1 => "/Users/ron/.hermes/workspace/scripts/ron_kpi_tracker.py"
]
"StandardErrorPath" => "/Users/ron/.hermes/logs/kpi_error.log"
"StandardOutPath" => "/Users/ron/.hermes/logs/kpi_daily.log"
"StartCalendarInterval" => {
"Hour" => 0
"Minute" => 0
}
"WorkingDirectory" => "/Users/ron/.hermes/workspace"
}
com.openclaw.kpi-weekly.plist
{
"EnvironmentVariables" => {
"HOME" => "/Users/ron"
"PATH" => "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
"PYTHONPATH" => "/Users/ron/.hermes/workspace/scripts:/Users/ron/.hermes/workspace/scripts/shared:/Users/ron/.hermes/workspace/scripts/pipeline"
}
"Label" => "com.openclaw.kpi-weekly"
"ProgramArguments" => [
0 => "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/Resources/Python.app/Contents/MacOS/Python"
1 => "/Users/ron/.hermes/workspace/scripts/ron_kpi_tracker.py"
2 => "--weekly"
]
"StandardErrorPath" => "/Users/ron/.hermes/logs/kpi_weekly_error.log"
"StandardOutPath" => "/Users/ron/.hermes/logs/kpi_weekly.log"
"StartCalendarInterval" => {
"Hour" => 9
"Minute" => 0
"Weekday" => 1
}
"WorkingDirectory" => "/Users/ron/.hermes/workspace"
}
3. launchctl bootout/bootstrap
===== com.openclaw.morning-routine =====
$ launchctl bootout gui/501/com.openclaw.morning-routine
bootout_exit=0
$ launchctl bootstrap gui/501 /Users/ron/Library/LaunchAgents/com.openclaw.morning-routine.plist
Bootstrap failed: 5: Input/output error
Try re-running the command as root for richer errors.
bootstrap_exit=5
$ launchctl print gui/501/com.openclaw.morning-routine | head -40
Bad request.
Could not find service "com.openclaw.morning-routine" in domain for user gui: 501
## 4. 직접 1회 실행 검증(launchctl bootstrap 실패 보완)
launchctl bootstrap이 이 세션에서 error 5로 실패해 kickstart 대상 서비스가 등록되지 않았다. 따라서 rewrite된 ProgramArguments를 같은 stdout/stderr 경로로 직접 실행했다.
### com.openclaw.morning-routine direct run
```text
$ /bin/bash /Users/ron/.hermes/skills/smart-home/scripts/tts_morning.sh
exit_code=0
stdout_before=missing stdout_after=1776237061 1000
stderr_before=missing stderr_after=1776237058 270
--- stdout tail ---
/Users/ron/Library/Python/3.9/lib/python/site-packages/urllib3/__init__.py:35: NotOpenSSLWarning: urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 2.8.3'. See: https://github.com/urllib3/urllib3/issues/3020
warnings.warn(
Traceback (most recent call last):
File "<string>", line 5, in <module>
File "/Users/ron/Library/Python/3.9/lib/python/site-packages/zeroconf/_core.py", line 182, in __init__
listen_socket, respond_sockets = create_sockets(interfaces, unicast, ip_version, apple_p2p=apple_p2p)
File "/Users/ron/Library/Python/3.9/lib/python/site-packages/zeroconf/_utils/net.py", line 451, in create_sockets
listen_socket = new_socket(bind_addr=("",), ip_version=ip_version, apple_p2p=apple_p2p)
File "/Users/ron/Library/Python/3.9/lib/python/site-packages/zeroconf/_utils/net.py", line 291, in new_socket
s.bind(bind_tup)
PermissionError: [Errno 1] Operation not permitted
[ERR] TTS 캐스팅 실패
[OK] 아침 루틴 완료
--- stderr tail ---
/Users/ron/Library/Python/3.9/lib/python/site-packages/urllib3/__init__.py:35: NotOpenSSLWarning: urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 2.8.3'. See: https://github.com/urllib3/urllib3/issues/3020
warnings.warn(
com.openclaw.weekly-report direct run
$ /bin/bash /Users/ron/.hermes/skills/smart-home/scripts/tts_weekly.sh
exit_code=1
stdout_before=missing stdout_after=1776237062 974
stderr_before=missing stderr_after=1776237061 270
--- stdout tail ---
/Users/ron/Library/Python/3.9/lib/python/site-packages/urllib3/__init__.py:35: NotOpenSSLWarning: urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 2.8.3'. See: https://github.com/urllib3/urllib3/issues/3020
warnings.warn(
Traceback (most recent call last):
File "<string>", line 5, in <module>
File "/Users/ron/Library/Python/3.9/lib/python/site-packages/zeroconf/_core.py", line 182, in __init__
listen_socket, respond_sockets = create_sockets(interfaces, unicast, ip_version, apple_p2p=apple_p2p)
File "/Users/ron/Library/Python/3.9/lib/python/site-packages/zeroconf/_utils/net.py", line 451, in create_sockets
listen_socket = new_socket(bind_addr=("",), ip_version=ip_version, apple_p2p=apple_p2p)
File "/Users/ron/Library/Python/3.9/lib/python/site-packages/zeroconf/_utils/net.py", line 291, in new_socket
s.bind(bind_tup)
PermissionError: [Errno 1] Operation not permitted
[ERR] TTS 캐스팅 실패
--- stderr tail ---
/Users/ron/Library/Python/3.9/lib/python/site-packages/urllib3/__init__.py:35: NotOpenSSLWarning: urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 2.8.3'. See: https://github.com/urllib3/urllib3/issues/3020
warnings.warn(
com.openclaw.kpi-daily direct run
$ /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/Resources/Python.app/Contents/MacOS/Python /Users/ron/.hermes/workspace/scripts/ron_kpi_tracker.py
exit_code=0
stdout_before=missing stdout_after=1776237062 504
stderr_before=missing stderr_after=1776237062 0
--- stdout tail ---
==================================================
📊 KPI 수집 실행 - 2026-04-15 16:11:02
==================================================
✅ 일일 KPI 저장 완료
날짜: 2026-04-15
ron: 0 done, 0 failed, 100% success
codex: 0 done, 0 failed, 100% success
cowork: 1 done, 0 failed, 100.0% success
analyst-fundamental: 0 done, 0 failed, 100% success
analyst-macro: 0 done, 0 failed, 100% success
analyst-technical: 0 done, 0 failed, 100% success
크론: 8/8 활성
--- stderr tail ---
com.openclaw.kpi-weekly direct run
$ /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/Resources/Python.app/Contents/MacOS/Python /Users/ron/.hermes/workspace/scripts/ron_kpi_tracker.py --weekly
exit_code=0
stdout_before=missing stdout_after=1776237062 316
stderr_before=missing stderr_after=1776237062 0
--- stdout tail ---
==================================================
📊 주간 KPI 리포트 - 2026-04-15
==================================================
데이터 부족 (1일)
==================================================
📋 개선안
==================================================
✅ 개선 필요 영역 없음
--- stderr tail ---
5. 최종 plist 상태 / launchd 등록 상태
최종 plist 요약
| label | 스케줄 | 호출 스크립트 | stdout/stderr | OpenClaw 경로 잔존 |
|---|---|---|---|---|
com.openclaw.morning-routine |
매일 06:30 | /Users/ron/.hermes/skills/smart-home/scripts/tts_morning.sh |
/Users/ron/.hermes/logs/morning-routine*.log |
0 |
com.openclaw.weekly-report |
Weekday=0, 20:00 |
/Users/ron/.hermes/skills/smart-home/scripts/tts_weekly.sh |
/Users/ron/.hermes/logs/weekly-report*.log |
0 |
com.openclaw.kpi-daily |
매일 00:00 | /Users/ron/.hermes/workspace/scripts/ron_kpi_tracker.py |
/Users/ron/.hermes/logs/kpi_daily.log, kpi_error.log |
0 |
com.openclaw.kpi-weekly |
Weekday=1, 09:00 |
/Users/ron/.hermes/workspace/scripts/ron_kpi_tracker.py --weekly |
/Users/ron/.hermes/logs/kpi_weekly*.log |
0 |
최종 4개 plist와 대상 실행 스크립트에서 /Users/ron/.openclaw, ~/.openclaw 경로 grep 결과는 0건이다.
launchctl 결과
bootout: 기존 로드 제거는 성공했다.bootstrap: 이 Codex 세션에서는 모든 대상이Bootstrap failed: 5: Input/output error로 실패했다./tmp의 최소 테스트 plist(/bin/echo)도 동일하게 bootstrap error 5였으므로, plist 내용 문제라기보다 현재 실행 환경의 launchctl bootstrap 제한으로 판단한다.kickstart: 서비스가 등록되지 않아Could not find service, rc=113.launchctl enable gui/501/<label>은 4개 모두 성공했고print-disabled기준 enabled 상태다.
재등록을 로컬 GUI 터미널에서 직접 실행할 수 있도록 보조 스크립트를 만들었다:
/Users/ron/.hermes/scripts/revive_launchd_reports.sh
6. 라이브 직접 실행 결과
launchd 등록이 막혀 kickstart는 못 했지만, rewrite된 ProgramArguments를 같은 로그 경로로 직접 1회 실행했다.
| label | 직접 실행 | 로그 증거 | 발송/도달 결과 |
|---|---|---|---|
com.openclaw.morning-routine |
exit 0 | /Users/ron/.hermes/logs/morning-routine.log, .err.log 생성 |
TTS 캐스팅 단계에서 zeroconf socket PermissionError: [Errno 1] Operation not permitted, [ERR] TTS 캐스팅 실패; 스크립트는 [OK] 아침 루틴 완료 출력 |
com.openclaw.weekly-report |
exit 1 | /Users/ron/.hermes/logs/weekly-report.log, .err.log 생성 |
TTS 캐스팅 단계에서 동일한 zeroconf socket PermissionError. 실제 스피커 도달은 실패 |
com.openclaw.kpi-daily |
exit 0 | /Users/ron/.hermes/logs/kpi_daily.log, kpi_error.log 생성 |
/Users/ron/.hermes/logs/kpi_daily.json 생성. 2026-04-15 KPI 1건 저장, cron 8/8 활성으로 집계 |
com.openclaw.kpi-weekly |
exit 0 | /Users/ron/.hermes/logs/kpi_weekly.log, kpi_weekly_error.log 생성 |
주간 KPI는 데이터 1일뿐이라 데이터 부족 (1일). 전송 로직 없음 |
7. 발송 경로 grep 결과
tts_morning.sh: Telegram이 아니라 Home Assistant/Google Home TTS 경로다.google_home_tts.sh, Home Assistantcurl,docker exec homeassistant, pychromecast/zeroconf를 사용한다.tts_weekly.sh: 동일하게 Home Assistant/Google Home TTS 경로다.ron_kpi_tracker.py:send_dm,send_sector, Telegram 호출 없음. stdout/log와~/.hermes/logs/kpi_daily.json저장만 수행한다.
특히 morning-routine은 현재 plist 기준으로 pipeline/morning_briefing.py --send가 아니라 smart-home TTS 루틴이다. 따라서 fed_liquidity oneliner + briefing 모음 Telegram 발송 여부는 이 plist로는 충족되지 않는다. fed-liquidity oneliner는 별도 pipeline/morning_briefing.py에 구현되어 있다.
8. 결과 표
| label | 스케줄 | 호출 스크립트 | 재기동 | 라이브 실행 | 발송경로 |
|---|---|---|---|---|---|
com.openclaw.morning-routine |
매일 06:30 | ~/.hermes/skills/smart-home/scripts/tts_morning.sh |
bootout OK, bootstrap 실패(error 5), enable OK | 직접 실행 exit 0 | Home Assistant/Google Home TTS. 현재 sandbox socket 제한으로 실제 캐스팅 실패 |
com.openclaw.weekly-report |
일요일 20:00 (Weekday=0) |
~/.hermes/skills/smart-home/scripts/tts_weekly.sh |
bootout OK, bootstrap 실패(error 5), enable OK | 직접 실행 exit 1 | Home Assistant/Google Home TTS. 현재 sandbox socket 제한으로 실제 캐스팅 실패 |
com.openclaw.kpi-daily |
매일 00:00 | ~/.hermes/workspace/scripts/ron_kpi_tracker.py |
bootout OK, bootstrap 실패(error 5), enable OK | 직접 실행 exit 0 | Telegram 없음. ~/.hermes/logs/kpi_daily.json + stdout log |
com.openclaw.kpi-weekly |
월요일 09:00 (Weekday=1) |
~/.hermes/workspace/scripts/ron_kpi_tracker.py --weekly |
bootout OK, bootstrap 실패(error 5), enable OK | 직접 실행 exit 0 | Telegram 없음. stdout log. 데이터 7일 미만이라 주간 리포트는 부족 상태 |
9. 변경 파일 목록
/Users/ron/Library/LaunchAgents/com.openclaw.morning-routine.plist/Users/ron/Library/LaunchAgents/com.openclaw.weekly-report.plist/Users/ron/Library/LaunchAgents/com.openclaw.kpi-daily.plist/Users/ron/Library/LaunchAgents/com.openclaw.kpi-weekly.plist/Users/ron/.hermes/skills/smart-home/신규 복사본/Users/ron/.hermes/scripts/revive_launchd_reports.sh/Users/ron/.hermes/logs/kpi_daily.json/Users/ron/knowledge-agent/400-reports/260415_launchd_schedules_revival.md
백업:
/Users/ron/.hermes/backups/launchagents_20260415T160807/
10. 남은 리스크 / 다음 조치
- 현재 세션에서는
launchctl bootstrap자체가 막혀 4개 서비스가 launchd에 등록되지 않았다. 로컬 GUI 터미널에서 아래를 실행해야 실제 일정성이 살아난다.
/Users/ron/.hermes/scripts/revive_launchd_reports.sh
morning-routine,weekly-report는 Telegram 리포트가 아니라 Google Home TTS 루틴이다. 해리가 원한 “아침 브리핑 Telegram 발송”이라면 plist를pipeline/morning_briefing.py --send또는 별도 wrapper로 바꾸는 후속 작업이 필요하다.kpi-daily,kpi-weekly도 Telegram 발송이 없다. “해리에게 도달”을 알림센터 기준으로 보려면ron_kpi_tracker.py에send_sector('ops' 또는 'report')연동 또는 wrapper가 필요하다.- 직접 실행에서 TTS 캐스팅은 zeroconf socket 권한 문제로 실패했다. 일반 GUI launchd 환경에서는 달라질 수 있지만, 이 세션에서는 실제 스피커 도달을 확인하지 못했다.
자체평가
- 정확성: 4.2/5 — plist rewrite, 스케줄/스크립트/로그/발송 경로 확인은 완료. 다만 launchctl bootstrap이 환경 제한으로 실패했다.
- 완성도: 4.0/5 — Hermes 경로 파일은 준비됐지만 실제 launchd 등록은 미완료. 대신 보조 bootstrap 스크립트와 직접 실행 증거를 남겼다.
- 검증: 4.4/5 — plutil, grep, 직접 실행, 로그, KPI JSON 생성까지 확인. 실제 launchd kickstart/스피커 도달은 실패.
- 최소 변경: 4.6/5 — 대상 4개 plist와 필요한 smart-home 복사본만 변경.
종합: 4.3/5