launchd running 15 + stopped 2 OpenClaw path audit
요약
- 대상 15 running + 2 stopped를 감사했다.
ai.hermes.gateway는 지시대로 읽기 확인만 하고 건드리지 않았다.sihwang-webapp은 메인 재기동 결과가 반영되어 PID 17287 / cwd Hermes로 정상 확인됐다.- Hermes 대응 파일이 존재하는 13개 plist는 OpenClaw 경로를 Hermes 경로로 rewrite했고,
plutil -lint모두 OK. - 다만 현재 Codex 세션 권한에서
launchctl bootout/bootstrap/kickstart가 대부분Operation not permitted/Input/output error로 막혀, running 프로세스의 실제 런타임 정의는 아직 재기동 반영 전이다. tts-webhook,otel-collector는 Hermes 대응 실행 파일이 없어 rewrite하지 않았다.
백업 stamp: 20260415160820
예: /Users/ron/Library/LaunchAgents/com.openclaw.ops-dashboard.plist.bak-launchd-audit-20260415160820
실행한 것
1. cwd 확인
각 PID에 대해 다음 방식으로 확인했다.
lsof -p <pid> -a -d cwd
2. plist 경로 확인
~/Library/LaunchAgents/*.plist를 plistlib로 읽어 다음 필드를 확인했다.
ProgramArgumentsWorkingDirectoryStandardOutPathStandardErrorPath
3. plist rewrite
다음 치환을 적용했다.
/Users/ron/.openclaw/workspace/ → /Users/ron/.hermes/workspace/
/Users/ron/.openclaw/workspace → /Users/ron/.hermes/workspace
/Users/ron/.openclaw/logs/ → /Users/ron/.hermes/logs/
대상 파일이 실제 존재하는 경우에만 rewrite했다.
수정된 plist:
com.openclaw.ops-dashboard
com.openclaw.cf-tunnel
com.openclaw.codex-proxy
com.openclaw.telegram-bridge
com.openclaw.claude-listener
com.openclaw.auto-dispatcher
com.openclaw.hermes-tailer
com.openclaw.dispatch-watcher
com.openclaw.task-notifier
com.openclaw.collab-review-loop
ai.openclaw.companion
ai.openclaw.staged-boot
com.openclaw.blueprint-updater
문법 검증:
plutil -lint ... → 전부 OK
결과 표
| label | pid | cwd | plist 경로 | 수정 필요 | 재기동 완료 |
|---|---|---|---|---|---|
| com.openclaw.sihwang-webapp | 17287 | /Users/ron/.hermes/workspace/scripts/pipeline |
Hermes | 아니오 | 예 — 메인 재기동 반영 확인 |
| com.openclaw.ops-dashboard | 1201 | / |
Hermes로 rewrite 완료. 단 launchd 메모리 정의는 아직 OpenClaw | 예 — plist 완료 | 아니오 — launchctl 권한 차단 |
| com.openclaw.cf-tunnel | 1713 | / |
Hermes로 rewrite 완료. 단 launchd 메모리 정의는 아직 OpenClaw | 예 — plist 완료 | 아니오 — launchctl 권한 차단 |
| com.openclaw.codex-proxy | 1225 | /Users/ron/chatgpt-codex-proxy |
로그 경로 Hermes로 rewrite 완료. 실행 경로는 외부 repo | 예 — 로그 plist 완료 | 아니오 — launchctl 권한 차단 |
| com.openclaw.telegram-bridge | 1221 | /Users/ron/.openclaw/workspace/scripts |
Hermes로 rewrite 완료. 단 running cwd는 아직 OpenClaw | 예 — plist 완료 | 아니오 — launchctl 권한 차단 |
| com.openclaw.claude-listener | 61612 | /Users/ron/.openclaw/workspace |
Hermes로 rewrite 완료. 단 running cwd는 아직 OpenClaw | 예 — plist 완료 | 아니오 — launchctl 권한 차단 |
| com.openclaw.auto-dispatcher | 1233 | /Users/ron/.openclaw/workspace |
Hermes로 rewrite 완료. 단 running cwd는 아직 OpenClaw | 예 — plist 완료 | 아니오 — launchctl 권한 차단 |
| com.openclaw.hermes-tailer | 1242 | / |
Hermes로 rewrite 완료. Hermes migration 도구라 유지 가능성 검토했으나 Hermes 대응 파일 존재하여 rewrite | 예 — plist 완료 | 아니오 — launchctl 권한 차단 |
| com.openclaw.dispatch-watcher | 1188 | /Users/ron/.openclaw/workspace |
Hermes로 rewrite 완료. 단 running cwd는 아직 OpenClaw | 예 — plist 완료 | 아니오 — launchctl 권한 차단 |
| com.openclaw.task-notifier | 1204 | / |
Hermes로 rewrite 완료. 단 launchd 메모리 정의는 아직 OpenClaw | 예 — plist 완료 | 아니오 — launchctl 권한 차단 |
| com.openclaw.tts-webhook | 1236 | / |
OpenClaw 유지: /Users/ron/.openclaw/skills/smart-home/scripts/tts_webhook.py |
예 — Hermes target 없음 | 아니오 — 미수정 |
| com.openclaw.otel-collector | 1247 | /Users/ron/.openclaw/workspace/src/monitoring |
OpenClaw 유지: Hermes src/monitoring/run_collector.py 없음 |
예 — Hermes target 없음 | 아니오 — 미수정 |
| com.openclaw.collab-review-loop | 1228 | /Users/ron/.openclaw/workspace/scripts |
Hermes로 rewrite 완료. 단 running cwd는 아직 OpenClaw | 예 — plist 완료 | 아니오 — launchctl 권한 차단 |
| ai.openclaw.companion | 5282 | / |
Hermes로 rewrite 완료. 코드 내부 state/db는 이미 Hermes 기준 | 예 — plist 완료 | 아니오 — launchctl 권한 차단 |
| ai.hermes.gateway | 50183 | /Users/ron/.hermes/hermes-agent |
Hermes | 아니오 | 건드리지 않음 — 정상 |
| ai.openclaw.staged-boot | stopped | - |
Hermes로 rewrite 완료 | 예 — plist 완료 | 아니오 — bootout 후 bootstrap/load 권한 차단 |
| com.openclaw.blueprint-updater | stopped | - |
Hermes로 rewrite 완료 | 예 — plist 완료 | 아니오 — bootout 후 bootstrap/load 권한 차단 |
launchctl 재기동 시도 결과
수정 대상은 한 개씩 순차로 시도했다.
launchctl bootout gui/501/<label>
launchctl bootstrap gui/501 ~/Library/LaunchAgents/<label>.plist
launchctl kickstart -k gui/501/<label>
running 대상 대부분:
bootout: Boot-out failed: 1: Operation not permitted
bootstrap: Bootstrap failed: 5: Input/output error
kickstart: Could not kickstart service ... Operation not permitted
stopped 2개:
ai.openclaw.staged-boot:
bootout rc=0
bootstrap: Input/output error
kickstart: service not found
legacy launchctl load: Input/output error
com.openclaw.blueprint-updater:
bootout rc=0
bootstrap: Input/output error
kickstart: service not found
legacy launchctl load: Input/output error
해석:
- plist 자체는 Hermes 기준으로 정상 수정됐다.
- 하지만 현재 Codex 세션은 launchd job 제어 권한이 없어 runtime reload가 반영되지 않았다.
- stopped 2개는 원래 stopped였고, 현재 세션에서 load도 차단되어
launchctl print기준 service not found 상태다. 샌드박스 밖 터미널에서 bootstrap 필요.
현재 launchd 메모리 정의 잔존 OpenClaw
plist 파일은 Hermes로 바뀌었지만, 실행 중인 서비스의 launchd 메모리 정의는 재기동 전이라 OpenClaw를 계속 가리킨다.
예:
com.openclaw.telegram-bridge
program = /usr/bin/python3
/Users/ron/.openclaw/workspace/scripts/telegram_bridge.py
working directory = /Users/ron/.openclaw/workspace/scripts
pid = 1221
같은 패턴이 다음 running 서비스에 남아 있다.
ops-dashboard
cf-tunnel
telegram-bridge
claude-listener
auto-dispatcher
hermes-tailer
dispatch-watcher
task-notifier
collab-review-loop
ai.openclaw.companion
codex-proxy는 실행 경로가 /Users/ron/chatgpt-codex-proxy라 OpenClaw 코드 의존은 아니지만, launchd 메모리의 로그 경로는 아직 OpenClaw다.
남은 이슈
1. 샌드박스 밖 launchctl reload 필요
다음 명령은 로컬 터미널에서 실행해야 한다.
for L in \
com.openclaw.ops-dashboard \
com.openclaw.cf-tunnel \
com.openclaw.codex-proxy \
com.openclaw.telegram-bridge \
com.openclaw.claude-listener \
com.openclaw.auto-dispatcher \
com.openclaw.hermes-tailer \
com.openclaw.dispatch-watcher \
com.openclaw.task-notifier \
com.openclaw.collab-review-loop \
ai.openclaw.companion \
ai.openclaw.staged-boot \
com.openclaw.blueprint-updater
do
launchctl bootout gui/$(id -u)/$L 2>/dev/null || true
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/$L.plist
launchctl kickstart -k gui/$(id -u)/$L 2>/dev/null || true
sleep 1
done
주의: ai.hermes.gateway는 포함하지 말 것.
2. Hermes target이 없는 서비스 2개
com.openclaw.tts-webhook- 현재 실행 파일:
/Users/ron/.openclaw/skills/smart-home/scripts/tts_webhook.py - Hermes target 없음:
/Users/ron/.hermes/skills/smart-home/scripts/tts_webhook.py com.openclaw.otel-collector- 현재 실행 파일:
/Users/ron/.openclaw/workspace/src/monitoring/run_collector.py - Hermes target 없음:
/Users/ron/.hermes/workspace/src/monitoring/run_collector.py - env도 OpenClaw 경로 포함:
PYTHONPATH,OTEL_DB_PATH
이 둘은 파일 마이그레이션 또는 서비스 폐기 판단이 필요하다.
최종 판정
- plist rewrite: 부분 PASS — 13개 완료, 2개 target 없음으로 보류, gateway untouched
- runtime cwd 전환: 부분 PASS — sihwang/gateway만 Hermes 확인, 나머지는 재기동 차단으로 OpenClaw 런타임 잔존
- stopped 2개: plist Hermes 완료, launchd 재등록은 권한 차단
- OpenClaw freeze 준비: 아직 불가
자체평가
- 정확성: 4.5/5 — cwd, plist, launchd 메모리 정의를 분리해 확인했다.
- 완성도: 4.2/5 — plist rewrite는 했지만 launchctl 권한 차단으로 런타임 전환은 완료하지 못했다.
- 검증: 4.4/5 —
lsof,plistlib,plutil -lint,launchctl print, bootout/bootstrap/kickstart 결과를 확인했다. - 최소 변경: 4.6/5 — target 존재가 확인된 plist만 수정했고, gateway는 건드리지 않았다.
- 종합: 4.4/5
Remaining Risks:
- launchd job은 plist 파일과 메모리 로드 정의가 다를 수 있다. plist rewrite 후 반드시 launchctl print와 lsof cwd를 둘 다 확인해야 한다.
- 현재 Codex sandbox는 launchctl 제어와 localhost 네트워크가 반복적으로 차단된다. 운영 재기동은 샌드박스 밖 로컬 터미널에서 수행해야 한다.