2026 OPENCLAW
FALLBACK_
CONFIG_
DRIFT.

게이트웨이 설정 로그 검토

Primary + fallback 은 가용성을 지키지만, 성공한 fallback 이 openclaw.json 에 런타임 모델을 박아 넣으면 선언된 primary 가 영영 돌아오지 않습니다. 이 글은 디스크 드리프트·세션 드리프트·provider 파싱 분기를 나누고 Gateway 중지→3종 백업→의도 JSON 복구→오래된 매핑 삭제→단계 재시작을 제시합니다. 교차: 429 로그, 세션 복구, LaunchAgent 토큰.

1. 문제 분해

런타임 선택이 agents 설정에 무분별하게 기록되면 의도가 깨집니다. provider-qualified ID 와 별칭이 어긋나 경로가 틀어질 수 있고 sessions.json 이 오래된 라우팅을 쥐면 채널은 정상처럼 보여도 응답 대상이 다릅니다. SSH 편집과 launchd 환경이 다르면 재시작 시 재발합니다.

특히 불편한 점은 가용성 지표는 초록인 채 진행된다는 것입니다. Webhook 은 200 을 돌려주고 채널도 배달하지만, 규제용 모델 라벨이나 비용 배분만 조용히 어긋납니다. 대시보드에 agents.list[].model 해시를 안 올리면 원인을 «프로바이더 불안정»으로 오해하기 쉽고, 근본 조치가 미뤄집니다. 여러 타임존에서는 야간에 jq 로 고친 값이 조간 launchd 에 의해 다른 버전으로 되돌아가는 이중 진실 도 자주 납니다.

그래서 본 Runbook 은 단발 명령이 아니라 백업 3종·구조화 diff·매핑 정리·단계 재시작을 묶습니다. 폴백을 일상 기능으로 쓸수록 «쓰기 허용 여부»를 코드 리뷰와 피처 플래그 양쪽에서 묶어야 합니다.

2. 증상 매트릭스

신호원인피하기
primary 이름이 백업으로fallback 기록세션 정리 없는 revert
단일 채널만 오경로세션이 runtime provider 보유무분별 재설치
doctor 허용과 충돌JSON·세션 분기npm 연속 업그레이드
원격만 재현plist 환경 stale반쪽 plist

3. 다섯 단계 복구

순서를 바꾸면 재발합니다. Gateway 가 살아 있는 상태에서 sessions 만 지우면 런타임이 다시 JSON 을 덮어쓸 수 있고, doctor 없이 재시작하면 plist 의 HOME 과 실제 작업 디렉터리 불일치가 남습니다. 각 단계마다 «중지 확인 → 백업 존재 확인 → 다음 단계» 체크리스트를 두고, 장애 공유 채널에는 변경 전후의 jq 출력 스니펫(민감값 마스킹)을 남기면 교대 근무자가 같은 길을 걷습니다.

Step 1 Gateway 중지

systemd/launchctl, WebSocket 종료.

Step 2 백업 3종

openclaw.json, sessions.json, jsonl 지문.

Step 3 의도 필드 복원

agents.list[].model, defaults.primary, fallbacks 정렬; provider 없는 모델 변경 금지.

Step 4 매핑 정리

미승인 runtime 키 삭제와 로그.

Step 5 단계 재시작

openclaw doctor→Gateway→채널별 3회 프로브.

jq '.agents.defaults.model' ~/.openclaw/openclaw.json > /tmp/model.before.json jq '.agents.defaults.model' ~/.openclaw/openclaw.json > /tmp/model.after.json diff -u /tmp/model.before.json /tmp/model.after.json || true

위 diff 는 «선언된 기본 모델» 스냅샷 예시입니다. 실제 장애에서는 agents.list[] 전체와 fallbacks 배열, 그리고 세션 쪽 runtime 키를 같은 방식으로 before/after 를 남기세요. 롤백이 필요하면 Trio 백업 중 타임스탬프가 가장 가까운 세트만 복원하고, 나머지는 포렌식용으로 보관합니다.

4. 의사결정

트리거1순위2순위
살아 있으나 모델 오류allowlist 축소+JSON 복구세션 전체 삭제
공유 게이트웨이 다중 personapersona 단위 동결단일 모델 강제
launchd 가 오래된 envWorkingDirectory 검증임시 export

5. 현장 메모와 감사 관점

“밤은 구했지만 이주 뒤 감사에서 디스크 primary 가 소형 모델로 고정.”

멀티 프로바이더 페일오버는 가용성을 지켰지만, 폴백 후 세션 런타임이 agents.list[0].model 을 소형 모델로 덮어써 주 회로가 복구돼도 «마지막 성공 모델»을 우선하는 해석기에 고정됐습니다. 백업→JSON 복구→sessions 매핑 정리→Gateway 순 재시작 후, MR 템플릿에 폴백 유래 영구 기록 금지 를 넣었고 동종 티켓은 0 이 됐습니다.

감사에서는 심각도를 설정 무결성 으로 분류했습니다(채널 중단이 아니라 라벨·계약 리스크). 이후 내부 리포트에 models 블록 일일 해시를 넣고, CR 번호 없는 diff 는 자동 2차 리뷰로 보냅니다.

6. 거버넌스와 관측성

JSON diff 는 Terraform 변경과 같은 승인 흐름에 태우는 편이 안전합니다. 각 성공 턴마다 qualified model(네임스페이스 포함)을 구조화 로그에 남기고, SIEM 에서는 agents.list 해시 변화를 CR 필수 조건으로 알립니다. 자유 텍스트만 있으면 삼 주 뒤 재발 분석이 멈춥니다.

원격 Mac launchd 상주는 전원·열이 안정되지만, SSH 일시 export 가 진실이라 착각하기 쉽습니다. 당직 절차에 «launchctl 출력 환경 → openclaw doctor 경로 → 최소 메시지로 모델 지문 확인»을 고정으로 넣으세요. Windows/Linux 에서도 Gateway 는 동작하지만, macOS 스크립트를 재사용하려면 MACGPU Apple Silicon 원격 노드에 템플릿을 올리면 책임 경계가 분명해집니다.

7. 프로바이더·제한 경로 게이트

agents.list[].model 이 벌거벗은 별칭이면 기본 프로바이더에 묵시 결합됩니다. 세션이 한 번이라도 vendor/model 형식으로 성공하면 다음 턴에 같은 이름·다른 경로 유령 라우팅이 납니다. 템플릿에서 provider+model 을 필수로 두고 CI 에 jq 검증을 걸면 좋습니다.

Telegram·Web UI·Cron 을 같이 쓰면 채널별 페르소나 덮어쓰기가 오래된 세션 포인터를 보지 않는지 행렬로 봅니다. «일부 채널만 정상»은 거의 세션 분열입니다. plist 를 바꿨는데 프로세스 환경이 낡았으면 SSH 로만 끝내지 말고 launchctl bootstrap 이나 LaunchAgent 재로드까지 Runbook 에 적습니다.

8. 수치 기준(변경 티켓에 붙이기)

① 복구 전후 최소 각 3 라운드 프로브 메시지와 로그 지문. ② 프로바이더 전환 시 시각·HTTP 상태를 티켓에. ③ 주당 2건 초과 «디스크 vs 의도» 불일치면 코드 감사 전까지 폴백 토폴로지 변경 동결. ④ sessions 디렉터리 조작은 sha256 백업 필수.

FinOps 연계로 복구 전후 시간대별 토큰 비용을 스프레드시트에 두고 라벨 오류율(구조화 로그)과 나란히 두면 폴백 영속화 부작용을 경영에도 설명하기 쉽습니다.

9. FAQ

세션만 삭제? JSON 이 휘면 재발.Docker? volume 과 컨테이너 HOME 일치.먼저 버전업? 복구·매핑 정리 먼저.여러 명이 JSON? 잠금 또는 변경 창, 충돌 시 Git 의도 블록 우선.폴백 끄기? 삭제보다 허용 모델 집합 축소.카나리? 페르소나 분리·agents.list 블록 복제·CR 분리.