# 가상 반도체 생산라인

웹 CLI → **작업실 → 가상 생산라인 → 가상 생산라인 열기** 또는 입력창 위 **가상 생산라인** 버튼으로 엽니다. API 키 없이 동작합니다.

## 첫 실험

1. 접힌 **실험 설정**을 펼쳐 재현 시드(기본 42), 실험 조건, 판정 임계값(기본 0.55)을 설정합니다. 설정을 접어도 적용한 조건은 제목에 남습니다.
2. **조건 적용 · 초기화**로 적용합니다. 입력값만 바꿔도 진행 중인 실험에는 영향을 주지 않습니다.
3. **시작 · 이어가기**로 재생하고 **일시 정지**로 멈춥니다. **1분 진행**은 재생을 멈추고 가상 시간을 정확히 1분 진행합니다. 화면을 드래그하면 3D 시점이 회전합니다.
4. **실험 끝까지 실행**은 가상 시간 180분까지 계산합니다. 종료 후 **시작 · 이어가기**를 누르면 설정된 조건으로 새 실험을 시작합니다.
5. **같은 시드로 조건 비교**는 입력한 시드·임계값으로 네 조건을 독립 실행합니다. 화면에서 재생 중인 실험을 변경하지 않습니다.
6. **합성 데이터 · 실행 보고서 다운로드**는 현재 실행 시점의 LOT·웨이퍼 정답·모의 점수·센서값·설정·집계와 운반 상태·완료 이력을 JSON으로 저장합니다.

## 데이터와 계산 가정

- LOT 20개, LOT당 웨이퍼 25장. 6분마다 LOT 투입.
- 세 공정과 검사 설비가 각각 한 LOT씩 처리하는 직렬 대기열 모델입니다.
- 단일 운반기 OHT-01이 요청 순서(FIFO)대로 한 LOT씩 운반합니다. 최초 투입과 각 설비 사이 이동에 각각 2분, 각 설비의 로딩에 1분을 가정합니다. 운반 중에는 다음 LOT가 운반 대기열에 남으며, 설비에 도착한 LOT는 설비 대기열에서 자기 차례를 기다립니다. 대기 버퍼의 용량 제한은 없습니다.
- 기본 공정 시간은 12/15/10분이며 LOT 편차를 추가합니다. 검사는 4분입니다.
- 합성 정답은 웨이퍼별 약 7.5% 확률로 불량을 생성합니다. 작은 표본에서는 비율이 달라집니다.
- 온도 180°C, 압력 1.2bar 주변의 LOT·공정 편차는 화면 검증용 임의 단위/가정값이며 특정 장비 레시피를 뜻하지 않습니다.
- 공정 B 정지는 45분 이상 80분 미만에 로딩·공정 진행과 신규 로딩을 멈춥니다. 남은 시간을 유지하고 80분부터 이어갑니다. 다른 설비와 운반기는 계속 동작하며 B의 설비 대기열은 쌓일 수 있습니다.
- 드리프트는 40분 이후 시간에 따라 합성 센서값과 새로 시작하는 공정 처리 시간을 늘립니다. 실제 물성 인과관계가 아닙니다.
- 검사 오류 조건은 모의 점수 생성의 라벨 반전 확률을 12%에서 50%로 변경합니다. **모의 실행기는 정답을 읽습니다. 학습 모델 성능 평가에 사용하면 안 됩니다.**
- 임계값 이상이면 불량 예측입니다. 임계값과 차이가 0.1 미만인 점수는 재검 후보로 집계하며 별도의 재검 공정은 실행하지 않습니다.

180분이 되면 미완료 LOT는 운반 대기·운반·설비 대기·로딩·공정 중으로 남습니다. 평균 대기 시간은 **완료된 LOT의 운반 대기와 설비 대기 시간을 합한 값**만 대상으로 하므로 조건별 완료량과 함께 해석해야 합니다. 운반·로딩·가공·설비 정지 시간은 이 대기 시간과 별도로 기록합니다. 미검사 웨이퍼는 오탐·미탐 집계에서 제외합니다. 분모가 없는 비율은 JSON에서 null입니다.

3D 화면은 패키지에 포함된 Three.js를 로컬 웹 CLI에서 불러와 WebGL로 렌더링합니다. 외부 CDN 호출은 없습니다. WebGL을 지원하지 않는 환경에서는 경량 Canvas 투영 뷰로 대체합니다. 계산 모듈은 화면 없이도 실행할 수 있습니다. 전체 보고서에는 생성기 버전과 시드가 포함되며 같은 버전·설정에서 입력과 계산이 재현됩니다.

## 현재 범위

이 기능은 운영 가설과 UI 흐름 검증용 합성 환경입니다. 실제 생산 예측, 디지털 트윈, 장비 제어, 물리 시뮬레이터가 아닙니다. 실제 데이터로 모델을 학습하지 않으며, 현재 이 생산라인에는 실제 MLflow 추론이 연결되지 않았습니다. 실제 이미지 기반 MLflow 검사는 기존 [가상 검사 환경](inspection-simulator.md)을 사용하세요. 생산라인 연결에는 모델 입력 계약, 시간 초과·오류 처리, 정답 없는 요청 전송과 실측 검증이 추가로 필요합니다.

## 설비·운반·센서 화면 (생성기 v3)

3D 화면에 챔버, 로딩 포트, 서비스 패널, 상태등, 유틸리티 배관과 운반 레일을 표시합니다. 외형과 공정 명칭은 설명용이며 특정 제조사 장비가 아닙니다. 가정한 2분의 반송 작업과 1분의 로딩이 생산 계산에 포함됩니다. OHT-01 상태에는 현재 운반 LOT·목적지·남은 반송 시간과 운반 대기량을 표시합니다. 실제 공장의 경로 길이, 교통, 배차 규칙이나 물류 처리 시간은 검증하지 않았습니다.

설비별 카드에는 LOT ID, 대기량, 로딩·가동·정지 상태, 공정 진행률, 매 가상 분의 온도·압력 샘플을 표시합니다. 온도 차트 범위는 모든 설비에서 175–195°C로 고정합니다. 센서값은 LOT 편차·공정별 오프셋·시간에 따른 작은 주기 변동과 시나리오의 드리프트를 합성합니다. 보고서에 4개 설비의 전체 시계열이 포함됩니다. 같은 시드와 조건에서 샘플은 재현됩니다. 반송·로딩 단계 추가로 생성기 버전은 `oscode-fab-synthetic/3`이며 이전 버전과 완료량·대기 시간이 달라질 수 있습니다.

화면 재생은 한 번에 가상 1분씩 진행하며, **재생 속도**에서 500ms·200ms·80ms 간격을 선택합니다. 브라우저 부하에 따라 실제 간격은 늘어날 수 있습니다. 이 속도는 화면 재생 간격이며 실제 공장 시간이나 모델 추론 속도를 뜻하지 않습니다. 속도를 바꾸어도 동일한 시드·조건·실행 시점의 계산 결과는 같습니다. 일시 정지는 계산을 멈추고 이어가기는 남은 작업부터 진행합니다. 운영체제의 동작 줄이기 설정에서는 LOT 이동 보간을 생략합니다.

**LOT 운반 이력**을 펼치면 최근 완료한 반송 12건의 LOT ID·출발지·목적지·시작 및 도착 시간을 확인합니다. 전체 완료 이력은 보고서에 포함됩니다. 설정과 이력은 개별적으로 펼치고 접을 수 있습니다.

## LOT·웨이퍼 검사 결과 확인

**웨이퍼 검사 결과**의 **검사 LOT**에서 미투입 LOT를 포함한 전체 20 LOT를 선택합니다. 목록에는 LOT ID와 현재 상태를 함께 표시하며, 선택한 LOT의 진행 상태와 검사 결과는 가상 시간 진행에 맞춰 갱신됩니다.

25장 웨이퍼 중 하나를 누르면 선택 상태가 표시되고 해당 웨이퍼의 판정을 확인할 수 있습니다. 검사가 완료되지 않은 LOT는 모든 웨이퍼가 **판정 대기**로 표시됩니다. 검사 완료 전에는 점수와 합성 정답을 화면에 공개하지 않으며, 아직 없는 점수를 0점으로 표시하지 않습니다.

검사가 완료된 웨이퍼 상세에는 다음을 구분해 표시합니다.

- **모의 불량 점수**와 적용한 **판정 임계값**: 임계값 이상이면 불량 예측입니다. 점수는 합성 정답과 노이즈를 이용해 만든 모의 값이며 실제 모델의 출력이 아닙니다.
- **판정**: 정상 예측 또는 불량 예측입니다.
- **합성 정답**: 생성한 데이터의 정상 또는 불량 라벨입니다. 실제 측정한 품질 판정이 아닙니다.
- **오탐·미탐**: 불량 예측이지만 합성 정답은 정상이면 오탐, 정상 예측이지만 합성 정답은 불량이면 미탐입니다. 검사 완료 후에만 분류합니다.

**3D에서 찾기**는 선택한 LOT가 표시된 위치를 찾아 보여줍니다. 아직 미투입 상태이거나 랙의 최대 표시 개수 등을 넘어 화면에 표시되지 않는 LOT는 안내를 표시합니다. 이때도 목록과 검사 결과에서는 해당 LOT를 선택할 수 있으며, 전체 데이터는 보고서에 남습니다.

3D의 AOI 검사 보드에는 **가장 최근 검사가 완료된 LOT**의 ID와 PASS·FAIL 수를 표시합니다. PASS는 정상 예측 수, FAIL은 불량 예측 수이며 합성 정답과 비교한 오탐·미탐은 검사 결과 패널에서 따로 확인합니다. 이 보드의 수치는 최근 한 LOT에 대한 표시입니다.

## 판정 정책 실험실

생산라인 화면의 **판정 정책 실험실**에서 이미 검사를 완료한 웨이퍼의 모의 점수·합성 정답을 고정한 채 임계값을 비교합니다. 계산은 로컬에서 수행하며 모델을 호출하지 않습니다. 입력 점수 자체를 새로 생성하거나 실제 모델을 학습하는 기능이 아닙니다.

### 실험 실행과 표본 선택

1. **분석 표본**을 선택합니다. 기본값인 **독립 실행 · 180분 표본**은 생산라인에 적용한 시드·조건·기준 임계값으로 별도 실행을 끝까지 계산합니다. 현재 3D의 진행 시점과 선택한 LOT를 바꾸지 않습니다. 180분에 아직 검사가 끝나지 않은 웨이퍼는 이 표본에서도 미검사입니다.
2. **현재 3D 시점의 표본**은 버튼을 누른 시점까지 완료한 검사만 사용합니다. 3D가 계속 진행해도 이미 만든 실험 결과는 자동으로 바뀌지 않습니다. 새 시점의 데이터를 쓰려면 다시 **실험 실행**을 누릅니다.
3. **후보 임계값**(기본 0.6)과 **재검 후보 범위 ±**(기본 0.1)를 지정합니다. 점수가 임계값 이상이면 불량 예측이고, 점수와 임계값의 절대 차이가 재검 후보 범위보다 작으면 재검 후보입니다. 범위를 0으로 설정하면 재검 후보가 없습니다.
4. **비용 가정과 통과 기준**을 펼쳐 가중치와 표본 기준을 검토한 뒤 **실험 실행**을 누릅니다.
5. 결과에 표시된 시드·조건·가상 분과 `검사 수 / 전체 500장`, 미검사 수를 먼저 확인합니다. 기준은 원본 생산라인의 임계값, 후보는 실험실에 지정한 임계값입니다. 두 정책에는 같은 완료 표본·재검 범위·비용 가정이 적용됩니다.

오탐·미탐·재검 후보의 추이와 **임계값 21개 전체 비교 · 선택해서 상세 보기**에서 0부터 1까지 0.05 간격의 결과를 확인합니다. 표의 임계값을 선택하면 해당 후보의 상세 결과를 보여주며 생산라인에는 적용하지 않습니다. 직접 입력한 후보는 이 21개 값 사이의 값이어도 됩니다.

### 비용 가중치와 표본 기준

초기 비용 가중치는 오탐 1, 미탐 10, 재검 후보 0인 **예시 값**입니다. 가정 비용 점수는 다음 합으로 계산합니다.

`오탐 수 × 오탐 가중치 + 미탐 수 × 미탐 가중치 + 재검 후보 수 × 재검 후보 가중치`

예를 들어 오탐 10건·미탐 2건·재검 후보 8건에 가중치 1·10·0.5를 지정하면 34점입니다. 재검 후보는 오탐·미탐과 겹쳐도 추가 가산합니다. 실제 업무에서 비용이 중복되는지 확인하고 가중치를 정하세요. 화면의 점수는 통화가 지정된 실제 원가·절감액·ROI가 아니며, 임계값을 바꾸어도 재검 공정을 실행하거나 생산량·공정 시간을 변경하지 않습니다.

표본 기준의 UI 초기값은 다음과 같습니다. 개수 기준이며 오류율 기준이 아닙니다.

| 설정 | 초기값 | 통과 조건 |
|---|---:|---|
| 최소 검사 수 (`minInspected`) | 100장 | 완료 검사 수가 이 값 이상 |
| 최대 오탐 (`maxFp`) | 25건 | 오탐 수가 이 값 이하 |
| 최대 미탐 (`maxFn`) | 5건 | 미탐 수가 이 값 이하 |
| 최대 재검 후보 (`maxReview`) | 100건 | 재검 후보 수가 이 값 이하 |

검사 완료가 0장이면 **미평가**입니다. 검사 표본이 있지만 최소 검사 수 또는 다른 조건을 충족하지 못하면 **기준 미달**이며, 네 조건을 모두 충족하면 **표본 기준 통과**입니다. 미검사 웨이퍼를 정상·0점으로 넣지 않고 오류와 비용 평가에서 제외합니다. 분모가 없는 정확도·정밀도·재현율이나 검사 1장당 비용은 JSON에서 `null`이며 화면에서는 없는 값으로 표시합니다. 미검사 결과까지 포함한 전체 500장의 성능을 뜻하지 않습니다.

**통과 후보 중 최저 가정 비용**은 비교한 21개 임계값 중 표본 기준을 통과한 값에서 고릅니다. 동일 비용이면 원본 기준 임계값에 가까운 값을 우선하고, 거리도 같으면 더 작은 임계값을 고릅니다. 같은 표본을 비교하고 후보를 고르므로 통계적 최적화나 새로운 데이터에 대한 성능 보증이 아닙니다. 통과 후보가 없으면 추천하지 않습니다.

**후보 임계값 입력하기**는 생산라인 설정에 값을 입력하는 단계입니다. 실제 운영 모델을 변경하거나 자동 승인하지 않습니다. 생산라인에 적용하려면 설정과 초기화 동작을 따로 확인해야 하며, 기존 실행의 모의 점수가 소급 변경되는 기능이 아닙니다.

### 설비별 대기·작업 시간 근거

**설비별 대기·작업 시간 근거**를 펼치면 해당 표본의 원본 실행을 같은 합성 엔진으로 재현해 시간 기록을 집계합니다. 서로 다른 보고 시점을 비교할 때는 누적 관측 시간도 함께 확인하세요.

- **대기 LOT·분**: 매 가상 1분 구간의 설비 대기 LOT 수를 누적한 값입니다. 예를 들어 3 LOT가 2분 대기하면 6 LOT·분입니다. 완료·미완료 LOT를 포함한 누적 설비 대기이며, 완료 LOT만 대상으로 한 평균 대기 시간과 다릅니다.
- **최대 큐**: 가상 분 경계에서 관측한 가장 큰 설비 대기열입니다.
- **가공 분·로딩 분·점유 정지 분·빈 설비 분**: 각 설비의 관측 시간을 구분합니다. 네 항목의 합은 해당 실행의 가상 분과 같습니다. 점유 정지 분은 LOT가 장비 안에 있던 정지 시간입니다. 설비가 정지 상태여도 LOT가 없던 시간은 이 항목에 포함하지 않습니다.
- **운반 대기 LOT·분·운반기 작업 분**: 설비 대기와 별도로 운반기 대기 부담과 실제로 진행한 가정 반송 시간을 표시합니다.

누적 설비 대기가 가장 큰 곳을 검토 후보로 표시합니다. 대기 부담이 쌓인 위치라는 관측이며 지연의 인과관계·장비 결함·증설 효과를 확정하는 진단이 아닙니다. 실제 장비의 OEE를 계산한 결과도 아닙니다.

### 근거 저장과 같은 실험 재현

**JSON 근거 저장**은 `oscode-fab-evidence/1` 자료를, **검토 보고서 저장**은 사람이 읽을 Markdown 요약을 내려받습니다. JSON에는 원본 합성 실행 보고서, 후보 설정·가중치·통과 기준, 기준·후보·21개 비교 결과와 재현 지문이 포함됩니다. Markdown만으로 전체 실험을 복원하지는 못하므로 JSON을 함께 보관하세요.

재현 지문은 입력·설정·결과를 담은 전체 실험 자료를 키 순서에 영향을 받지 않는 JSON으로 정규화한 뒤 계산한 SHA-256 값입니다. 개별 입력·설정·결과에 각각 부여한 별도 서명이 아닙니다. 지문이 같다는 것은 자료와 재계산의 정합성을 확인하는 근거이며, 작성자·데이터 출처·실제 모델 실행을 인증하거나 결과의 정확성을 보증하지 않습니다.

- **같은 실험 재현**: 원본 시드·조건·기준 임계값·가상 시점으로 같은 엔진을 다시 실행하고 정책 결과를 다시 계산합니다. 원본 자료와 재계산 결과의 지문이 일치해야 성공합니다. 3D 화면이나 운영 모델은 변경하지 않습니다.
- **실험 보고서 열기**: 이 실험실에서 저장한 1 MiB 이하의 JSON을 선택합니다. 형식과 지문을 확인한 뒤 재계산이 일치한 자료만 엽니다. 설정도 저장 당시 값으로 복원합니다. 일반 생산라인 실행 보고서나 Markdown 파일은 이 가져오기 형식이 아닙니다.

지원하지 않는 생성기 버전, 자료 변경 또는 재현 불일치는 오류로 표시합니다. 지원 범위는 같은 합성 엔진·설정의 계산 재현이며 3D 렌더링 픽셀이나 실제 공장 결과의 재현이 아닙니다.

### 오류 사례를 검사 화면에 재현

**후보의 오류 사례**에는 후보 임계값에서 오탐·미탐이 된 웨이퍼를 최대 8건 표시합니다. **검사 화면에 재현**을 누르면 실험의 원본 시드·조건·가상 시점으로 3D 생산라인을 복원하고 해당 LOT·웨이퍼를 선택합니다. 독립 180분 표본의 사례라면 3D도 그 표본의 시점으로 이동하므로, 진행 중인 다른 시점의 표본과 구분하세요.

원본 검사 화면은 **생산라인에 적용했던 기준 임계값**을 유지합니다. 후보가 오류로 분류한 웨이퍼라도 원본 화면에서는 다른 판정일 수 있습니다. 복원은 오류의 입력과 원본 상황을 확인하는 동작이며 후보 정책을 적용하는 동작이 아닙니다. 실제 엔드포인트 호출·배포·운영 승인을 실행하지 않습니다.

## 보고서의 상태와 시간

LOT는 한 시점에 하나의 위치에만 존재합니다. `완료 + 설비 대기 + 운반 대기/운반 + 로딩 + 공정 중 + 미투입 = 20 LOT`를 유지하며, 로딩 중인 LOT를 공정 중 수치에 중복 집계하지 않습니다.

- `metrics.inTransitLots`: 운반 대기와 실제 운반 중 LOT를 합한 수입니다. 실제 운반 중 작업은 `transport.active`, 운반 대기 작업은 `transport.pending`에 나뉩니다.
- `metrics.waitingLots`: 설비에 도착해 처리를 기다리는 LOT 수입니다. 운반 대기는 제외합니다.
- `metrics.loadingLots` / `metrics.inProcessLots`: 로딩 중 / 가공·검사 중 LOT 수입니다.
- LOT의 `carrierWait` / `stationWait`: 운반기 대기 / 설비 대기 분입니다. `wait`는 두 값의 합입니다.
- LOT의 `transportTime` / `loadingTime` / `processTime` / `downTime`: 실제로 진행한 가정 반송 / 로딩 / 가공·검사 시간과 설비 안에서 정지한 시간입니다. 모두 가상 분입니다.
- `transfers`: 완료한 반송 이력입니다. `lotId`, `from`, `to`, `requestedAt`, `startedAt`, `arrivedAt`를 기록합니다. 설비 번호는 0–3, 최초 투입의 출발지는 -1입니다. 진행 중 작업은 `transport.active`에서 확인합니다.

완료 LOT의 총 소요 시간은 `wait + transportTime + loadingTime + processTime + downTime`과 같습니다. 이는 이 합성 모델의 상태·시간 보존 규칙이며 실제 공장의 처리 성능을 보장하지 않습니다.

## WebGL 클린룸 화면

클린룸 서비스 벽·창·조명 패널, 타공 바닥, 금속 재질과 그림자, 공정별로 다른 챔버, 로딩 포트와 LOT 보관 랙을 표시합니다. 검사 완료 LOT는 출고 구역에 표시됩니다. 랙은 설비별 최대 9 LOT만 표시하며 초과분은 BUFFER 표식의 별표와 전체 수량으로 안내합니다. 보고서에는 모든 LOT가 포함됩니다. 드래그는 카메라 회전, 휠은 확대·축소이며 **카메라 초기화**로 기본 시점으로 돌아갑니다. 설비 또는 표시된 LOT를 클릭하면 현재 작업 ID·대기량·센서 또는 LOT 상태를 확인할 수 있습니다. 선택한 LOT의 상태는 계산 진행에 맞춰 갱신됩니다. WebGL 화면에서 **관찰 설비**를 고른 뒤 **설비 관찰**을 누르면 해당 설비를 가까이에서 보여줍니다.

운반기는 실제 운반 중인 LOT 하나의 집기·상승·레일 이동·하강을 표시합니다. 정지 시 저장된 가상 분의 위치에 고정됩니다. 장비 창 안의 웨이퍼와 관절 로봇 팔 움직임은 공정 진행률을 보여주는 설명용 동작이며 개별 웨이퍼의 별도 공정 계산은 아닙니다. 설비의 상태 패널은 현재 LOT·작업 상태·진행 상황을 보여줍니다. 패널 표시, 관절 동작과 AOI 보드는 계산 결과를 시각화하며 공정·운반 시간이나 검사 판정을 변경하지 않습니다. 이러한 화면 개선에서도 생성기 버전은 `oscode-fab-synthetic/3`을 유지합니다.

3D는 시각적 설명이며 실제 장비 CAD 모델이나 공장 배치를 복제하지 않습니다. 애니메이션은 가정한 반송 단계의 계산 결과를 따라가지만, 충돌·로봇 관절·가속도·실제 반송 시간을 물리적으로 계산하지 않습니다. 조명·재질·카메라 변경은 생산·검사 수치를 변경하지 않습니다. 화면 상단의 WebGL 상태 안내로 실제 엔진 사용 여부를 확인할 수 있습니다.
