콘텐츠로 이동

OpenClaw 프로세스 감독: 안정적인 생명주기 관리 구현

오랫동안 실행되는 커맨드를 관리하다 보면 프로세스가 제대로 종료되지 않거나, PTY 설정이 꼬여서 고생한 적 있으시죠? 특히 백그라운드 실행과 포그라운드 실행이 섞여 있을 때 프로세스 수명 주기를 일관되게 관리하는 건 정말 까다로운 일이에요.

이번 작업에서는 이러한 프로세스 관리의 복잡함을 해결하고, 더 안전하고 예측 가능한 실행 환경을 만들기 위한 PTY 및 프로세스 관리(Process Supervision) 계획을 정리했습니다.

우리는 다음과 같은 다양한 상황에서 오랫동안 실행되는 커맨드에 대해 신뢰할 수 있는 단일 수명 주기가 필요해요.

  • exec 포그라운드 실행
  • exec 백그라운드 실행
  • process 후속 작업 (poll, log, send-keys, paste, submit, kill, remove)
  • CLI agent runner 서브프로세스

단순히 PTY를 지원하는 것이 목표가 아니에요. 불안정한 프로세스 매칭 휴리스틱 없이, 예측 가능한 소유권 확인, 취소, 타임아웃, 그리고 깔끔한 정리를 구현하는 것이 핵심입니다.

  • 구현체는 src/process/supervisor 내부에 유지해요.
  • 이를 위한 새로운 패키지를 만들지는 않습니다.
  • 실용적인 선에서 현재 동작과의 호환성을 유지해요.
  • 터미널 리플레이나 tmux 스타일의 세션 유지까지 범위를 넓히지는 않기로 했습니다.

3. 이번 브랜치에서 구현된 내용

섹션 제목: “3. 이번 브랜치에서 구현된 내용”
  • Supervisor 모듈이 src/process/supervisor/* 경로에 배치되었습니다.
  • Exec 런타임과 CLI runner가 이미 supervisor의 spawn 및 wait를 통해 라우팅되고 있어요.
  • Registry 종료 처리는 멱등성(idempotent)을 유지합니다.
  1. 명시적인 PTY 커맨드 계약(Contract)
  • SpawnInput이 src/process/supervisor/types.ts에서 discriminated union으로 변경되었습니다.
  • PTY 실행 시 일반적인 argv를 재사용하는 대신 ptyCommand가 필수적으로 요구됩니다.
  • Supervisor는 더 이상 src/process/supervisor/supervisor.ts에서 argv를 join하여 PTY 커맨드 문자열을 다시 만들지 않아요.
  • Exec 런타임은 이제 src/agents/bash-tools.exec-runtime.ts에서 ptyCommand를 직접 전달합니다.
  1. 프로세스 레이어 타입 디커플링
  • Supervisor 타입은 더 이상 agent에서 SessionStdin을 가져오지 않아요.
  • 프로세스 로컬 stdin 계약은 src/process/supervisor/types.ts(ManagedRunStdin)에 위치합니다.
  • 어댑터는 이제 프로세스 레벨 타입에만 의존해요:
    • src/process/supervisor/adapters/child.ts
    • src/process/supervisor/adapters/pty.ts
  1. 프로세스 도구 수명 주기 소유권 개선
  • src/agents/bash-tools.process.ts는 이제 supervisor를 통해 먼저 취소를 요청합니다.
  • process kill/remove 실행 시 supervisor에서 조회가 실패하면 process-tree 폴백 종료 방식을 사용해요.
  • remove는 종료 요청 직후에 실행 중인 세션 항목을 즉시 제거하여 결정론적인 삭제 동작을 유지합니다.
  1. 단일 소스 기반의 Watchdog 기본값
  • src/agents/cli-watchdog-defaults.ts에 공유 기본값을 추가했습니다.
  • src/agents/cli-backends.ts에서 이 공유 기본값을 사용해요.
  • src/agents/cli-runner/reliability.ts에서도 동일한 공유 기본값을 사용합니다.
  1. 미사용 헬퍼 정리
  • src/agents/bash-tools.shared.ts에서 사용하지 않는 killSession 헬퍼 경로를 제거했습니다.
  1. 직접적인 Supervisor 경로 테스트 추가
  • supervisor 취소를 통한 kill 및 remove 라우팅을 확인하기 위해 src/agents/bash-tools.process.supervisor.test.ts를 추가했습니다.
  1. 안정성 공백 해결 완료
  • src/agents/bash-tools.process.ts는 이제 supervisor 조회가 실패할 경우 실제 OS 레벨의 프로세스 종료 방식을 사용합니다.
  • src/process/supervisor/adapters/child.ts는 기본 취소/타임아웃 kill 경로에 process-tree 종료 의미론(semantics)을 사용해요.
  • src/process/kill-tree.ts에 공유 process-tree 유틸리티를 추가했습니다.
  1. PTY 계약 엣지 케이스 커버리지 추가
  • PTY 커맨드의 그대로의 전달(verbatim forwarding) 및 빈 커맨드 거절을 테스트하기 위해 src/process/supervisor/supervisor.pty-command.test.ts를 추가했습니다.
  • child 어댑터 취소 시의 process-tree kill 동작을 위해 src/process/supervisor/adapters/child.test.ts를 추가했습니다.

이번 패스에서 필요했던 두 가지 안정성 공백이 해결되었습니다:

  • process kill/remove 실행 시 supervisor 조회가 실패하면 실제 OS 종료 폴백이 작동합니다.
  • child 취소/타임아웃 시 기본 kill 경로로 process-tree kill 방식을 사용합니다.
  • 두 동작 모두에 대해 회귀 테스트가 추가되었습니다.

지속성 및 시작 시 조정(Reconciliation)

섹션 제목: “지속성 및 시작 시 조정(Reconciliation)”

재시작 동작은 이제 명시적으로 메모리 내 수명 주기로만 정의됩니다.

  • src/process/supervisor/supervisor.ts의 reconcileOrphans()는 의도적으로 아무 작업도 수행하지 않는 no-op 상태를 유지해요.
  • 프로세스 재시작 후에는 활성 실행 상태가 복구되지 않습니다.
  • 이는 부분적인 지속성(persistence)으로 인한 리스크를 피하기 위해 이번 구현 패스에서 의도적으로 설정한 경계입니다.
  1. src/agents/bash-tools.exec-runtime.ts의 runExecProcess는 여전히 여러 책임을 가지고 있어서, 나중에 집중화된 헬퍼들로 분리할 수 있습니다.

필수적인 안정성 및 계약 항목에 대한 구현 패스가 완료되었습니다.

완료된 항목:

  • process kill/remove 폴백 실제 종료 구현
  • child 어댑터 기본 kill 경로에 process-tree 취소 적용
  • 폴백 kill 및 child 어댑터 kill 경로에 대한 회귀 테스트
  • 명시적 ptyCommand 하에서의 PTY 커맨드 엣지 케이스 테스트
  • reconcileOrphans() no-op 설계를 통한 명시적인 메모리 내 재시작 경계 설정

선택적 후속 작업:

  • 동작 변경 없이 runExecProcess를 집중화된 헬퍼들로 분리
  • src/process/supervisor/types.ts: discriminated spawn input 및 프로세스 로컬 stdin 계약으로 업데이트되었습니다.
  • src/process/supervisor/supervisor.ts: 명시적인 ptyCommand를 사용하도록 업데이트되었습니다.
  • src/process/supervisor/adapters/child.ts 및 src/process/supervisor/adapters/pty.ts: agent 타입으로부터 분리되었습니다.
  • src/process/supervisor/registry.ts: 멱등성을 가진 finalize 로직은 변경 없이 유지되었습니다.
  • src/agents/bash-tools.exec-runtime.ts: PTY 커맨드를 명시적으로 전달하고 폴백 경로를 유지하도록 업데이트되었습니다.
  • src/agents/bash-tools.process.ts: 실제 process-tree 폴백 종료와 함께 supervisor를 통해 취소하도록 업데이트되었습니다.
  • src/agents/bash-tools.shared.ts: 직접적인 kill 헬퍼 경로가 제거되었습니다.
  • src/agents/cli-watchdog-defaults.ts: 공유 베이스라인으로 추가되었습니다.
  • src/agents/cli-backends.ts 및 src/agents/cli-runner/reliability.ts: 이제 동일한 기본값을 사용합니다.

Unit 테스트:

Terminal window
pnpm vitest src/process/supervisor/registry.test.ts
pnpm vitest src/process/supervisor/supervisor.test.ts
pnpm vitest src/process/supervisor/supervisor.pty-command.test.ts
pnpm vitest src/process/supervisor/adapters/child.test.ts
pnpm vitest src/agents/cli-backends.test.ts
pnpm vitest src/agents/bash-tools.exec.pty-cleanup.test.ts
pnpm vitest src/agents/bash-tools.process.poll-timeout.test.ts
pnpm vitest src/agents/bash-tools.process.supervisor.test.ts
pnpm vitest src/process/exec.test.ts

E2E 대상:

Terminal window
pnpm vitest src/agents/cli-runner.test.ts
pnpm vitest run src/agents/bash-tools.exec.pty-fallback.test.ts src/agents/bash-tools.exec.background-abort.test.ts src/agents/bash-tools.process.send-keys.test.ts

타입 체크 참고:

  • 이 레포지토리에서는 pnpm build(전체 lint/docs 검사는 pnpm check)를 사용하세요. pnpm tsgo를 언급하는 이전 노트들은 이제 유효하지 않습니다.
  • Exec 환경 강화(hardening) 동작은 변경되지 않았습니다.
  • 승인 및 허용 목록(allowlist) 흐름은 변경되지 않았습니다.
  • 출력 정리(sanitization) 및 출력 제한(caps)은 변경되지 않았습니다.
  • PTY 어댑터는 강제 종료 및 리스너 폐기 시 여전히 대기 정착(wait settlement)을 보장합니다.
  1. Supervisor가 관리되는 실행 건에 대한 수명 주기 소유권을 가집니다.
  2. PTY spawn은 argv 재구성 없이 명시적인 커맨드 계약을 사용합니다.
  3. 프로세스 레이어는 supervisor stdin 계약을 위해 agent 레이어에 대한 타입 의존성을 가지지 않습니다.
  4. Watchdog 기본값이 단일 소스에서 관리됩니다.
  5. 타겟팅된 유닛 및 e2e 테스트가 통과(green) 상태를 유지합니다.
  6. 재시작 지속성 경계가 명시적으로 문서화되었거나 완전히 구현되었습니다.

이제 이 브랜치는 더 일관성 있고 안전한 관리 구조를 갖추게 되었습니다.

  • 명시적인 PTY 계약
  • 더 깔끔해진 프로세스 레이어링
  • 프로세스 작업을 위한 supervisor 기반 취소 경로
  • supervisor 조회가 실패할 경우의 실제 폴백 종료 처리
  • child 실행 기본 kill 경로에 대한 process-tree 취소 적용
  • 통합된 watchdog 기본값
  • 명시적인 메모리 내 재시작 경계 (이번 패스에서는 재시작 시 고립된 프로세스 조정을 하지 않음)

AI Setup Assistant

OpenClaw

OpenClaw Expert

아직 막혀 있나요?

이 문서에서 답을 못 찾았다면 OpenClaw Expert에게 바로 물어보세요.