본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 09. 07:16

Scarab 필드 테스트 #018 — facebook/react의 탐지 결과 133건을 0건으로 줄이기

요약

Scarab을 사용하여 facebook/react 저장소의 133개 진단 탐지 결과를 0건으로 줄이는 필드 테스트를 진행했습니다. 진단 스위트를 변경하지 않고 28개의 수정 커밋만으로 대규모 저장소의 노이즈를 제거하는 데 성공했습니다.

핵심 포인트

  • facebook/react 저장소의 133개 탐지 결과를 0건으로 감소시킴
  • 진단 메커니즘 변경 없이 28개의 커밋으로 문제 해결
  • 런타임, 컴파일러, DevTools 등 다양한 영역의 클러스터 제거
  • 대규모 실제 저장소에 대한 Scarab의 유효성 검증

이번 테스트는 React의 메인 저장소인 facebook/react를 대상으로 진행된 첫 번째 광범위한 Scarab 침묵(quieting) 실행이었습니다.

이전의 필드 테스트들은 범위가 좁았습니다: 하나의 이슈, 하나의 경계(boundary), 하나의 수정 경로(repair lane), 하나의 패치 후보(patch candidate)를 다루었습니다.

이번 테스트는 달랐습니다.

목표는 대규모의 실제 컴파일러/런타임(compiler/runtime) 저장소가 노이즈가 많은 진단 스코어카드(diagnostic scorecard)로부터 시작하여, 일련의 제한된 수정 패스(bounded repair passes)를 통해 0건으로 줄어들 수 있는지 테스트하는 것이었습니다.

결과

대상:

text facebook/react

초기 진단 스코어카드:

text 133 findings

최종 단계별 스코어카드:

text 0 findings quiet

최종 전체 감사(audit):

text clear 0 findings

수정 커밋(Repair commits):

text 28 bounded commits

실행 중 진단 스위트(diagnostic suite) 메커니즘 변경 여부:

text no

대상 저장소는 수정되었습니다. 결과가 통과되도록 진단 스위트를 변경하지는 않았습니다.

실제로 무엇이 수정되었는가

이번 실행은 단 하나의 이슈를 없애려고 시도한 것이 아닙니다.

패스(passes)를 통해 저장소를 순회하며 React의 여러 주요 영역에 걸친 탐지 클러스터(finding clusters)를 제거했습니다:

  • DevTools 확장 프로그램 거버넌스 (DevTools extension governance)
  • DevTools 폴백 동작 (DevTools fallback behavior)
  • DevTools 스토리지 폴백 동작 (DevTools storage fallback behavior)
  • React 런타임 패리티 (React runtime parity)
  • React DOM 폴백 동작 (React DOM fallback behavior)
  • Fizz 런타임/소스 생성 경계 (Fizz runtime/source-generated boundaries)
  • React 직렬화 에러 경계 (React serialization error boundaries)
  • React 컴파일러 의미론적 경계 (React Compiler semantic boundaries)
  • HIR 의미론적 경계 (HIR semantic boundaries)
  • HIR 의존성 의미론 (HIR dependency semantics)
  • 컴파일러 최적화 의미론 (Compiler optimization semantics)
  • Reactive 스코프 의미론 (Reactive scope semantics)
  • 컴파일러 검증 의미론 (Compiler validation semantics)
  • 컴파일러 픽스처 등가성 (Compiler fixture equivalence)
  • 컴파일러 런타임 등가성 (Compiler runtime equivalence)
  • 컴파일러 스냅 등가성 (Compiler snap equivalence)
  • 소스 맵 출처 (Source-map provenance)
  • 테스트 증명 경계 (Test proof boundaries)
  • 운영 제어 경계 (Operational control boundaries)
  • DevTools 캐시/제어 경계 (DevTools cache/control boundaries)
  • DOM 및 Fizz 제어 경계 (DOM and Fizz control boundaries)
  • 테스트 렌더러 제어 경계 (Test renderer control boundaries)
  • Reconciler 제어 경계 (Reconciler control boundaries)
  • Reconciler 테스트 제어 경계 (Reconciler test control boundaries)
  • Flight 테스트 제어 경계 (Flight test control boundaries)
  • 서버 제어 경계 (Server control boundaries)
  • CI 워크플로 권한 (CI workflow authority)

대부분의 수정 사항은 소스 레벨의 경계 문서화 (boundary documentation)였습니다. 즉, 코드가 이미 의존하고 있던 지점에서 기존의 동작, 소유권 (ownership), 동등성 (parity), 증명 (proof), 폴백 (fallback) 또는 제어 가정 (control assumptions)을 명시적으로 나타내는 주석을 추가하는 작업이었습니다.

실질적인 워크플로 권한 (workflow authority) 변경이 한 건 있었습니다. contents: write 권한이 필요하지 않은 CI 워크플로에서 해당 권한을 제거한 반면, 아티팩트 게시 (artifact-publishing) 워크플로는 실제로 필요한 쓰기 권한 (write authority)을 유지하도록 했습니다.

점수 변동 (Score movement)

실행은 133건의 탐지 결과 (findings)로 시작되었습니다.

자율 실행 (autonomous section) 후반부 동안 점수는 다음과 같이 변동되었습니다:

text 48 -> 43 -> 38 -> 33 -> 28 -> 23 -> 18 -> 13 -> 9 -> 3 -> 1 -> 0

중요한 점은 실행의 형태입니다. 각 패스 (pass)가 제한된 클러스터 (cluster)를 해결하면, 저장소 (repo)를 다시 점검하는 방식이었습니다.

이는 한 번에 이루어진 광범위한 재작성 (rewrite)이 아니었습니다.

소스 측면의 수정 슬라이스 (repair slices)가 연속적으로 이루어진 결과였습니다.

패스 순서 (Pass sequence)

패스 (Pass)탐지 결과 수 (Finding count)수정 슬라이스 (Repair slice)
0133DevTools 확장 기능 거버넌스 경계 명확화
...

영역별 노트 (Area notes)

DevTools

초기 패스들은 주로 DevTools 관련 영역을 해결했습니다.

이 영역들은 확장 기능 주입 (extension injection), 폴백 동작 (fallback behavior), 공유 DevTools 저장소 (shared DevTools storage), 렌더러/백엔드 동작 (renderer/backend behavior), 프로파일러/캐시/스토어 제어 (profiler/cache/store control), 검사된 요소 캐시 소유권 (inspected element cache ownership), 훅 이름 캐시 소유권 (hook-name cache ownership), 타임라인 캐시 소유권 (timeline cache ownership), 그리고 동적 임포트 캐시 동작 (dynamic import cache behavior)을 포함했습니다.

이는 초기에 탐지 결과가 많이 발생했던 주요 원인이었습니다.

해당 경계들이 문서화되자, 점수는 133에서 119로 내려갔습니다.

DOM, Fizz, 그리고 폴백 동작 (fallback behavior)

다음 단계는 React DOM 및 Fizz 영역을 다루었습니다.

수정 사항들은 DOM 컴포넌트 처리, 입력 선택 (input selection), Fizz 런타임 소스/생성 관계 (Fizz runtime source/generated relationships), Fizz 서버 테스트, 직렬화 오류 처리 (serialization error handling), 그리고 인라인 런타임 생성 (inline runtime generation)에 관한 폴백 및 동등성 경계 (fallback and parity boundaries)를 문서화했습니다.

이는 런타임의 동작 방식을 변경하는 것이 아니라, 주로 기존의 폴백 동작을 명시적으로 만드는 작업이었습니다.

컴파일러 (Compiler) 및 HIR

컴파일러 섹션은 이번 실행의 중간 단계 중 가장 큰 비중을 차지했습니다.

HIR 빌드 의미론 (semantics), 옵셔널 체이닝 (optional-chain) 의존성 수집, 의존성 유도 (derivation), 환경 의미론 (environment semantics), 스코프 의존성 전파 (scope dependency propagation), HIR 출력 (printing), 타입 스키마/방문자 (type schema/visitor) 동작, 최적화 (optimization), JSX 아웃라이닝 (outlining), 리액티브 스코프 빌드/코드 생성 (reactive-scope build/codegen), 리액티브 스코프 추론 (reactive-scope inference), 무효화 병합 (invalidation merging), 그리고 가지치기 의미론 (pruning semantics) 과정을 거쳤습니다.

이 섹션은 탐지 결과가 100건 미만으로 떨어진 구간이었습니다.

컴파일러/HIR 패스 (passes)가 중요한 이유는, 의존성 소유권 (dependency ownership), 피스처 동등성 (fixture equivalence), 또는 런타임 패리티 (runtime parity) 뒤에 숨겨진 의도가 향후 수정 작업을 위해 충분히 명시적이지 않더라도, 코드가 구조적으로는 올바르게 유지될 수 있는 소스 영역을 다루기 때문입니다.

컴파일러 피스처 (Compiler fixtures) 및 런타임 동등성 (runtime equivalence)

여러 패스가 컴파일러 피스처 및 런타임 동등성에 집중했습니다.

이 수정 작업들은 테스트와 피스처가 동등성을 증명하고 있는 지점, 옵셔널 체이닝 동작이 의도적으로 보존된 지점, 그리고 스냅/최소화/평가 (snap/minimization/evaluation) 동작이 컴파일러 출력을 재작성하기보다는 선택 또는 비교 역할을 수행하는 지점들을 기록했습니다.

컴파일러 코드에서 이러한 구분은 중요합니다. 왜냐하면 모든 이상해 보이는 피스처나 필터가 버그인 것은 아니기 때문입니다. 어떤 파일들은 특정 변환 (transformation)이 특정 의미론적 경계 (semantic boundary)를 보존한다는 것을 증명하기 위해 존재합니다.

소스 맵 (Source maps)

소스 맵 패스는 생성된 아티팩트/출처 (generated-artifact/provenance) 클러스터를 잠재웠습니다.

여기에는 소스 맵 로딩, 모킹된 (mocked) 소스 맵 업데이트, 파싱 (parsing), 메타데이터, 그리고 소비 (consumption)가 포함되었습니다.

이 패스 이후, 생성된 아티팩트 소유권 (generated-artifact ownership) 레인이 스코어카드에서 사라졌습니다.

테스트 증명 경계 (Test proof boundaries)

증명 (proof) 패스는 증명 경계 역할을 하는 테스트 표면 (test surfaces)들을 기록했습니다.

여기에는 레거시 JSX 런타임 테스트와 DevTools 인라인 e2e 테스트 동작이 포함되었습니다.

이 패스 이후, 증명 소유권 (proof-ownership) 레인이 스코어카드에서 사라졌습니다.

운영 제어 (Operational control)

실행 후반부는 운영 제어 (operational-control) 표면들이 주를 이루었습니다.

이는 hooks 코드 경로 상태 (hooks code-path state), 캐시 동작 (cache behavior), Flight 클라이언트 동작 (Flight client behavior), 디버그 훅 (debug hooks), 독립형 DevTools (standalone DevTools), DevTools 스토어/프로파일러/캐시 제어 (DevTools store/profiler/cache control), 검사된 요소 캐시 제어 (inspected element cache control), DOM/Fizz 제어 (DOM/Fizz control), 렌더러 테스트 제어 (renderer test control), 리콘실러 제어 (reconciler control), 리콘실러 테스트 (reconciler tests), Flight 테스트 (Flight tests), 서버 제어 (server control), 그리고 외부 스토어 공유 테스트 동작 (external-store shared test behavior)을 포함했습니다.

이는 해당 리포지토리가 CI/전체 리포지토리 정리 (CI/full-repo cleanup) 단계로 넘어가기 전 마지막으로 발견된 주요 고위험 (high-severity) 클러스터였습니다.

CI 권한 (CI authority)

마지막 소스 측 정리 작업은 CI 워크플로 권한 (CI workflow authority)에서 이루어졌습니다.

하나의 직접 동기화된 PR 종료 워크플로 (direct-sync PR-closing workflow)가 불필요한 내용인 쓰기 권한 (write authority)을 포함하고 있었습니다. 해당 권한은 제거되었습니다. 아티팩트 게시 워크플로 (Artifact-publishing workflows)는 실제로 필요한 쓰기 권한을 유지했습니다.

마지막으로 하나가 발견된 상태는 CI 수정 사항이 범위 지정된 검사 (scoped checks)는 통과했으나 아직 커밋 (committed)되지 않았기 때문에 발생했습니다. 커밋이 완료되자 스코어카드 (scorecard)는 정적 (quiet) 상태에 도달했습니다.

검증 (Verification)

최종 단계별 결과:

text finding_count: 0 status: quiet selected_subsystem: none

최종 전체 감사 (full audit) 결과:

text diagnostic_outcome: clear Findings: 0

추가 소스 검사 통과:

text Governance Intake tests: 60 tests Drift-surface profile tests: 38 tests Diagnostic Suite tests: 247 tests Diagnostic Suite Python compile Diagnostic Suite Node syntax checks

이 결과가 주장하는 바와 주장하지 않는 바

이 결과는 facebook/react에 열려 있는 모든 GitHub 이슈 (GitHub issue)가 해결되었다고 주장하는 것이 아닙니다.

GitHub 이슈 트래커 (issue trackers)에는 살아있는 버그 (live bugs), 오래된 보고 (stale reports), 기능 요청 (feature requests), 중복 (duplicates), 설계 논의 (design discussions), 특정 버전 관련 보고 (version-specific reports), 재현되지 않은 사례 (unreproduced cases), 그리고 로컬 진단 표면 (local diagnostic surface) 외부의 이슈들이 포함되어 있습니다.

여기서의 주장은 더 좁고 측정 가능한 범위입니다:

클론된 facebook/react 타겟은 133개의 Scarab/SDS 진단 결과 (diagnostic findings)로 시작하여, 28회의 제한된 수정 패스 (bounded repair passes)를 통해 0개의 결과에 도달했습니다. 최종 전체 Scarab 감사 (full Scarab audit) 또한 0개의 결과와 함께 깨끗하게 (clear) 완료되었습니다.

요약: 이것이 중요한 이유

이번 실행은 일반적인 단일 이슈 필드 테스트 (single-issue field test)와는 다릅니다.

단일 이슈 테스트 (single-issue test)는 진단 시스템이 하나의 깨진 경계 (boundary)를 찾아내고 하나의 좁은 수정을 안내할 수 있음을 증명합니다.

이번 실행은 대규모 저장소 (repository)가 단계별로 점진적으로 조용해질 수 있는지(quieter pass by pass)를 테스트했습니다.

이것이 중요한 이유는 성숙한 저장소들이 단순히 고립된 버그 (isolated bugs)를 통해서만 실패하지 않기 때문입니다. 저장소들은 다음과 같은 숨겨진 경계 압력 (boundary pressure)을 축적합니다: 작동은 하지만 소스 소유권 (source-owned)이 없는 폴백 동작 (fallback behavior), 출처 (provenance)가 암시적인 생성된 아티팩트 (generated artifacts), 증명 경계 (proof boundary)를 명시하지 않은 채 무언가를 증명하는 테스트, 시스템을 이미 알고 있는 사람들에게만 동등성 (equivalence)이 명확한 컴파일러 픽스처 (compiler fixtures), 운영상 필요하지만 문서화가 미비한 캐시 (caches) 및 제어 경로 (control paths), 그리고 시간이 지남에 따라 권한이 확장될 수 있는 CI 워크플로 (CI workflows).

이번 실행에서 Scarab은 저장소를 하나의 거대한 수정 사항으로 평탄화하지 않았습니다. 대신 일련의 수정 슬라이스 (repair slices)를 통해 저장소를 단계적으로 훑었습니다.

DevTools가 조용해졌습니다.

Compiler/HIR이 조용해졌습니다.

생성된 아티팩트의 출처 (Generated artifact provenance)가 조용해졌습니다.

증명 경계 (Proof boundaries)가 조용해졌습니다.

운영 제어 (Operational control)가 조용해졌습니다.

CI 권한 (CI authority)이 조용해졌습니다.

그 후 전체 스코어카드 (full scorecard)가 조용해졌습니다.

그 결과는 facebook/react가 제한된 커밋 (bounded commits)을 통해 133건의 진단 결과 (diagnostic findings)에서 0건으로 이동하며, 최종적인 전체 감사 (full audit)를 통과했음을 보여주는 소스 수준의 증명 경로 (source-level proof trail)입니다.

이것이 이번 필드 테스트의 핵심입니다: 단 하나의 패치 (patch)가 아니라, 측정 가능한 저장소 정숙화 실행 (measurable repo quieting run)을 보여주는 것입니다.

공개 증거 저장소:
https://github.com/scarab-systems/react-stepwise-quieting-report

공개 React 수정 브랜치:
https://github.com/scarab-systems/react/tree/codex/react-stepwise-source-repair-20260608

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0