본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 17. 06:25

Scarab 진단 필드 테스트 #024B — pnpm, CAFS TMPDIR 소켓 예산 수정 사항 수용

요약

pnpm 설치 과정에서 긴 TMPDIR 경로로 인해 Unix 도메인 소켓 경로 제한을 초과하여 발생하는 설치 실패 문제를 해결했습니다. pnpm의 임시 디렉토리 이름을 단축하여 하위 라이프사이클 도구들이 사용할 수 있는 경로 예산을 확보했습니다.

핵심 포인트

  • 긴 TMPDIR 경로로 인한 Unix 도메인 소켓 경로 길이 제한 문제 해결
  • pnpm의 CAFS 임시 디렉토리 이름을 단축하여 경로 예산 확보
  • Node.js의 fs.mkdtemp()를 사용하여 임시 디렉토리 생성 방식 개선
  • 라이프사이클 도구의 IPC 소켓 생성 시 발생하던 EINVAL 에러 방지

대상: pnpm/pnpm

이슈: pnpm/pnpm#12222

PR: pnpm/pnpm#12327

필드 랩 (Field Lab): https://github.com/scarab-systems/scarab-field-lab

이것은 Scarab 진단 필드 테스트 #024에 대해 업스트림(upstream)에서 수용된 업데이트입니다.

원래의 필드 테스트는 pnpm이 생성한 긴 TMPDIR 경로로 인해, git 기반 의존성 준비 과정에서 라이프사이클 도구(lifecycle tooling)가 Unix 도메인 소켓(Unix-domain socket) 경로 길이 제한을 초과하여 발생하는 pnpm 설치 실패를 대상으로 했습니다.

해당 수정 사항이 이제 업스트림에 수용되었습니다.

pnpm/pnpm#12327은 2026년 6월 16일에 승인되어 pnpm:main에 병합되었습니다.

pnpm/pnpm#12222에 대한 필드 랩(Field Lab) 기록이 다음과 같이 업데이트되었습니다:

upstream-pr-recorded (업스트림 PR 기록됨)

에서:

upstream-accepted (업스트림 수용됨)

으로.

이로 인해 이 필드 테스트의 상태가 변경되었습니다.

이제 이것은 더 이상 단순한 수정 후보(repair candidate)가 아닙니다.

이제는 사람이 검토한 업스트림 수용(upstream acceptance) 상태입니다.

원래의 실패 형태

원래의 이슈 형태는 기만적일 정도로 단순했습니다:

  • pnpm install이 컨테이너 내부 등에서 루트(root) 권한으로 실행됨
  • pnpm이 pnpm 스토어 내부의 TMPDIR을 설정함
  • git 기반 의존성이 패키지 준비 과정에서 라이프사이클 도구(lifecycle tooling)를 실행함
  • 해당 도구가 TMPDIR 아래에 IPC 소켓 경로를 생성함
  • 전체 소켓 경로가 너무 길어짐
  • Node가 listen EINVAL을 보고함

눈에 보이는 에러는 이 실패가 Node, tsx, 라이프사이클 스크립트, 또는 준비 중인 패키지의 문제인 것처럼 보이게 만듭니다.

하지만 제한된 pnpm 측의 수정 사항은 더 작은 곳에 존재했습니다.

실패는 경로 예산(path-budget) 문제였습니다.

pnpm은 Node의 소켓 제한을 소유하지 않았습니다.

pnpm은 tsx를 소유하지 않았습니다.

pnpm은 모든 라이프사이클 스크립트를 소유하지 않았습니다.

pnpm은 패키지 도구가 TMPDIR 아래에 생성할 수 있는 모든 파일이나 소켓을 소유하지 않았습니다.

하지만 pnpm은 해당 도구에 전달하는 임시 디렉토리 경로를 소유했습니다.

그것이 수정 가능한 범위(repair surface)였습니다.

수용된 수정 사항

수용된 수정 사항은 pnpm의 CAFS 임시 패키지 디렉토리 이름을 단축하는 것이었습니다.

패치는 더 긴 path-temp 명명 경로를 기존 스토어 tmp 디렉토리 아래에 압축된 tmp 접두사를 사용하는 Node의 네이티브 fs.mkdtemp()로 교체했습니다.

이를 통해 pnpm이 제어하는 basename (기본 이름) 길이를 줄이면서도, 임시 디렉토리를 pnpm 스토어의 temp 영역 내에 유지할 수 있습니다.

이것은 단순히 외관상의 문제가 아니었습니다.

핵심은 라이프사이클 도구 (lifecycle tooling)가 등장하기 전에 Unix 도메인 소켓 (Unix-domain socket) 경로 예산을 보존하는 것이었습니다.

라이프사이클 도구는 TMPDIR 아래에 IPC 소켓을 생성할 수 있습니다.

만약 pnpm이 해당 도구에 긴 TMPDIR 경로를 제공한다면, 그 도구는 소켓 경로 제한에 도달하기 전까지 사용할 수 있는 여유 공간이 줄어들게 됩니다.

수용된 수정 사항은 pnpm이 소유한 경로 세그먼트를 단축함으로써 하위 도구들에게 더 많은 여유 공간을 제공합니다.

수정 방향은 다음과 같습니다:

  • pnpm이 제어하는 temp 루트를 유지함
  • pnpm이 제어하는 생성된 basename을 단축함
  • TMPDIR 아래의 라이프사이클 도구들을 위해 더 많은 경로 예산을 남겨둠
  • pnpm이 라이프사이클 도구의 소켓 구축을 소유하고 있는 것처럼 가장하는 것을 피함

이는 매우 정밀한 수정입니다.

경계 (Boundary)

여기서의 경계는 원래의 필드 테스트에서 식별된 것과 동일한 경계입니다:

pnpm이 소유한 CAFS 임시 패키지 디렉토리 명명 방식 대 TMPDIR 아래에 생성되는 라이프사이클 도구의 IPC 소켓 경로

pnpm은 모든 라이프사이클 도구를 소유하지 않습니다.

pnpm은 Unix 소켓 경로 제한을 소유하지 않습니다.

pnpm은 전체 하위 IPC 경로를 소유하지 않습니다.

하지만 pnpm은 TMPDIR을 라이프사이클 도구에 넘겨주기 전까지, 피할 수 있는 경로 길이를 얼마나 소비할지는 소유합니다.

수용된 패치 (patch)는 선의 그 한쪽에 머물러 있습니다.

특정 패키지를 예외 처리하지 않습니다.

tsx를 패치하지 않습니다.

라이프사이클 실행 방식을 재설계하지 않습니다.

라이프사이클 권한 동작을 변경하지 않습니다.

unsafe-perm 기본값을 변경하지 않습니다.

pacquet를 변경하지 않습니다.

경로 예산 중 pnpm이 소유한 부분을 수정합니다.

이것이 이번 수용이 중요한 이유입니다.

메인테이너 (maintainer)가 검토한 수정 사항은 더 넓은 라이프사이클 동작 변경으로 확장되는 대신 경계를 보존했습니다.

검토 결과 (Review result)

공개 검토에는 테스트 범위 및 임시 디렉토리 권한에 대한 관찰 내용이 포함되었습니다.

최종적으로 수용된 형태는 수정을 집중된 상태로 유지했습니다.

메인테이너는 불변성 테스트 (invariant test)를 수용하고 fs.mkdtemp() 동작을 유지했습니다.

이는 병합된 변경 사항이 실제로 중요했던 경계(boundary)를 보호한다는 것을 의미합니다:

git 패키지 준비 과정에서 사용되는 CAFS 임시 디렉토리(temp directory)의 베이스네임(basename)은 다운스트림(downstream) 경로 예산(path budget)을 보존할 수 있을 만큼 충분히 짧게 유지되어야 합니다.

이것이 이 버그에 대한 올바른 종류의 회귀 테스트 커버리지(regression coverage)입니다.

이 테스트가 가능한 모든 라이프사이클 도구(lifecycle tool)가 결코 너무 긴 경로를 생성할 수 없다는 것을 증명할 필요는 없습니다.

그것은 잘못된 주장일 것입니다.

유용한 불변성(invariant)은 더 좁습니다:

pnpm은 TMPDIR을 다운스트림 도구에 전달하기 전에 CAFS 임시 베이스네임(temp basename)에서 불필요한 경로 예산을 소비해서는 안 됩니다.

이것이 왜 라이프사이클 스크립트(lifecycle-script) 수정이 아니었는가

크래시(crash)가 라이프사이클 도구가 IPC 소켓(IPC socket)을 생성하려고 할 때 발생하기 때문에, 이를 라이프사이클 도구의 실패로 규정하기는 쉬울 것입니다.

하지만 그것은 수정의 압박을 잘못된 곳으로 향하게 합니다.

라이프사이클 도구는 소켓 경로(socket path)가 필요합니다.

도구는 TMPDIR 아래에 해당 경로를 생성합니다.

그러한 동작은 전적으로 합리적일 수 있습니다.

Unix 소켓 경로 제한(Unix socket path limit) 또한 pnpm이 제거할 수 있는 것이 아닙니다.

따라서 올바른 질문은 다음과 같았습니다:

'pnpm이 라이프사이클 도구들이 등장하기 전에 피할 수 있는 경로 길이를 줄일 수 있는가?'

네, 가능합니다.

그것이 바로 CAFS 임시 베이스네임을 단축하는 것이 올바른 범주의 수정이었던 이유입니다.

이 수정은 특정 패키지에 대해 가정을 하지 않습니다.

특정 라이프사이클 도구에 의존하지 않습니다.

pnpm이 모든 다운스트림 소켓 경로를 이해할 필요도 없습니다.

단순히 다운스트림 프로세스에 더 많은 경로 예산을 제공할 뿐입니다.

이것이 의미론적 수정(semantic repair)입니다.

버그는 다음과 같은 것이 아니었습니다:

'도구가 소켓을 사용했다'

버그는 다음과 같았습니다:

'pnpm이 TMPDIR 아래에서 합리적으로 경로를 생성하는 도구들에게 넘겨주기 전에 너무 많은 경로 예산을 소비했다'

업스트림 수용(upstream acceptance)이 중요한 이유

원래의 #024 보고서는 경계에 대한 주장(boundary claim)이었습니다.

해당 보고서는 pnpm 측에서 소유한 수정 대상이 라이프사이클 도구도, Node도, tsx도, Unix 소켓 제한도 아니라고 말했습니다.

그것은 바로 CAFS 임시 디렉토리 명명 경로(naming path)였습니다.

이번 병합은 이것이 유효한 업스트림 수정 범위(upstream repair surface)였음을 확인해 줍니다.

이것은 Scarab/SDS에 있어 매우 중요한데, 왜냐하면 이것이 바로 시스템이 지원하고자 하는 전형적인 현장 결과(field result)이기 때문입니다:

  • 소유한 표면(owned surface)을 찾고
  • 가장 요란한 증상(loudest symptom)을 쫓는 것을 피하며
  • 패치(patch)를 작게 유지하고
  • 경계 외부의 프로젝트 동작을 보존하며
  • 불변량(invariant)을 검증하고
  • 메인테이너(maintainer) 리뷰를 위해 깔끔하게 제출하는 것

수락된 결과가 SDS가 리뷰(review)를 "대체"했다는 의미는 아닙니다.

이는 현장 테스트 경계(field-test boundary)가 리뷰를 통과했다는 것을 의미합니다.

그것이 바로 증거(receipt)입니다.

Field Lab 상태

Field Lab은 이제 이 사례를 다음과 같이 기록합니다:

upstream-accepted (업스트림 수락됨)

공개 기록에는 이슈(issue), PR, 검증 요약(validation summary), 리뷰 상태(review status), 수락 상태(acceptance status), 그리고 클레임 경계(claim boundary)가 포함됩니다.

내부 SDS 메커니즘(machinery)은 공개하지 않습니다.

로컬 워크플로(workflow) 세부 사항도 공개하지 않습니다.

독점적인 진단 로직(proprietary diagnostic logic)도 노출하지 않습니다.

Field Lab 기록은 공개적인 증거 추적(evidence trail)을 위해 존재합니다.

현장 테스트 결과

이것은 이제 업스트림에 수락된 경로 예산 경계 수정(upstream-accepted path-budget boundary repair)입니다.

이슈는 다음과 같이 요약됩니다:

  • pnpm이 자신의 스토어(store) 아래에 임시 패키지 디렉터리를 생성함
  • 해당 디렉터리가 TMPDIR의 일부가 됨
  • 라이프사이클(lifecycle) 도구들이 TMPDIR 하위에 추가적인 경로를 생성함
  • Unix 도메인 소켓(Unix-domain socket) 경로는 엄격한 길이 제한이 있음
  • pnpm은 자신이 소유한 경로 부분을 단축할 수 있음
  • 해당 베이스네임(basename)을 단축함으로써 라이프사이클 도구들을 위한 더 많은 공간을 확보함
  • 수락된 패치는 컴팩트한 tmp 접두사를 사용하는 fs.mkdtemp()를 사용함
  • 수정 사항이 승인되어 업스트림에 병합됨

이것이 수정 경로(repair lane)의 전부입니다.

이 패치는 발생 가능한 모든 IPC 경로 실패를 수정한다고 주장하지 않습니다.

Unix 소켓 제한을 변경한다고 주장하지 않습니다.

tsx를 수정한다고 주장하지 않습니다.

pnpm 라이프사이클 실행을 재설계한다고 주장하지 않습니다.

라이프사이클 권한 동작(privilege behavior)을 변경하지 않습니다.

경로 예산(path budget) 중 pnpm이 소유한 부분을 수정합니다.

이것이 바로 Scarab/SDS가 드러내도록 설계된 종류의 경계입니다.

공개 클레임

이 수락된 현장 테스트에 대한 올바른 클레임은 다음과 같습니다:

Scarab/SDS는 pnpm/pnpm#12222에 대해 업스트림(upstream)에서 수락된 경계 수리(boundary repair)를 추진하는 데 기여했습니다. 해당 이슈에서는 git 기반의 의존성 준비(dependency preparation) 과정 중, pnpm이 생성한 긴 TMPDIR 경로로 인해 라이프사이클 툴링(lifecycle tooling)의 IPC 소켓 경로가 Unix 도메인 소켓(Unix-domain socket) 경로 제한을 초과할 수 있는 문제가 있었습니다. 병합된 pnpm PR은 기존 스토어 임시 디렉토리 하위에 fs.mkdtemp()를 사용하여 압축된 _tmp_ 접두사를 붙임으로써 CAFS 임시 패키지 디렉토리 이름을 단축합니다. 이를 통해 라이프사이클 권한 동작(lifecycle privilege behavior), unsafe-perm 기본값, 또는 pacquet을 변경하지 않고도 다운스트림 라이프사이클 툴링을 위한 더 많은 경로 예산(path budget)을 확보합니다. 이는 모든 IPC 경로 실패를 해결하거나, Unix 소켓 제한을 변경하거나, pnpm 라이프사이클 실행을 재설계한다고 주장하는 것이 아닙니다. 이는 경로 예산 중 pnpm이 소유한 부분을 수정하는 것입니다.

공개(Disclosure): 이 현장 보고서는 본인의 현장 테스트 노트, 공개된 이슈(issue) 및 PR 기록, 검증 요약, 리뷰 상태, 병합 기록, 그리고 Field Lab 업데이트를 바탕으로 AI 보조 편집을 통해 작성되었습니다. 기술적 주장과 최종 문구는 발행 전 검토를 거쳤습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0