# v0.1.240 — Vacuum critic CONDITIONAL fix (치명 1 + 중대 2 + 중간 1 + 사소 처리)

- 버전: v0.1.240
- 분류: 48th stable seal (v0.1.366) 일괄 봉인 사이클
- 다운로드: [factory00-windows-x64-v0.1.240.zip](../../downloads/archive/factory00-windows-x64-v0.1.240.zip) (archive 보존)
- 캡처: [qa-screenshots/v0.1.240/](../../qa-screenshots/v0.1.240/)

---

## critic v0.1.239 판정: CONDITIONAL -> v0.1.240 fix
| 등급 | 발견 | 처리 |
|---|---|---|
| 치명 | 1 (VacuumUnit unsubscribe 누락) | 본 사이클 fix |
| 중대 | 3 (_sceneRoot / CaptureDistanceMm / UpdateActuator) | 2 fix + 1 P1.2 예약 |
| 중간 | 3 (CommandBackward 사이드이펙트 / 파일 분리 / pad hit) | 2 fix + 1 예약 |
| 사소 | 2 | 주석 명시 |

## 치명 #1 fix — VacuumUnit EventBus unsubscribe
기존: _bus.OnBlowSignalChanged += OnBlowSignal 구독만, 해제 없음 -> Part 삭제 시 dead handler 누적.**fix**:
- VacuumUnitActuator.Uninitialize() 메서드 신설 — _bus.OnBlowSignalChanged -= OnBlowSignal- ActuatorDriver.UnregisterActuator 안 if (actuator is VacuumUnitActuator vu) vu.Uninitialize() (옵션 B: type cast, IActuator 인터페이스 수정 없이 최소 변경)- ActuatorDriver.UnregisterAll() 헬퍼 + OnDestroy 일괄 cleanup
## 중대 #1 fix — `_sceneRoot` 의도 명시
기존: Transform _sceneRoot 선언만, 할당 없음 -> 항상 null -> SetParent(null) = 씬 루트.**fix**: _sceneRoot = null 명시적 default + 주석 "spec §3 SetParent(SceneRoot), factory00은 별도 SceneRoot GameObject 없음 -> null = Unity scene root (의도)". Ejector + Unit 양쪽.
## 중대 #2 fix — CaptureDistanceMm 단위 주석 강화
기존: 1f default, "1mm 흡착" 짧은 주석만.**fix**: 단위 SSOT 주석 4줄:
- 필드명 suffix "Mm" SSOT (mm 단위)- Unity Transform = mm scaled 환경 (unit-mm-conversion.md 룰)- default 1mm = 산업 진공 패드 실측 (0.5~2mm)- Inspector P1.2 라벨 "(mm)" 명시 예약
## 중대 #3 — UpdateActuator 미등록
P1.2 (v0.1.241+) 예약 합의 (사용자 [완료]). ActuatorDriver registration + Add 헬퍼 + Inspector UI 동반 사이클.

## 중간 #1 fix — CommandBackward 사이드 이펙트
기존: CommandBackward() { _blowSignal = true; /* 진공 유지 */ } -> CommandStop 후 재흡착 위험.**fix**: _vacuumSignal = false; _blowSignal = true; 명시. SetBlow/SetVacuum도 mutex 적용 (SetBlow(on) -> if (on) _vacuumSignal = false).
## 중간 #3 fix — pad 자체 OverlapSphere 포함
기존: IsChildOf(_parentPart.cachedTransform) 가드만 — pad가 Part 자식이 아닐 수 있음.**fix**: if (go.transform == pad || go.transform.IsChildOf(pad)) continue; 추가. Ejector + Unit 양쪽.
## 중간 #2 — 단일 파일 3 클래스
P1.2/P2 사이클에서 각 클래스 분리 예약 (Pneumatic 패턴 미러).

## 사이클 사전 검토 룰 (`spec-vs-codebase-pre-check.md`) 후속 갱신 필요
룰 첫 적용에도 치명 1건 발견. **사전 검토 grep 범위 확대** 필요:
- spec brief의 코드 샘플 인용된 **이벤트 구독 패턴** (+= / -=) -> unsubscribe 경로 검증 의무- spec이 가정하는 **GameObject/Component 생명주기** -> factory00 ActuatorDriver Register/Unregister 매핑 검증다음 사이클(v0.1.241)에서 룰 영구화 갱신 예정.

## 변경 파일
- Assets/Scripts/Actuators/VacuumActuators.cs (+18라인 fix)- VacuumEjectorActuator: _sceneRoot 의도 주석 / CommandBackward 진공 OFF / SetBlow mutex / pad 가드- VacuumUnitActuator: _sceneRoot 의도 / Uninitialize() 신설 / pad 가드- CaptureDistanceMm 단위 주석 강화 (replace_all)- Assets/Scripts/Actuators/ActuatorDriver.cs (+18라인 fix)- UnregisterActuator: VacuumUnit type cast -> Uninitialize() 호출- UnregisterAll() 신설 + OnDestroy 위임
## 판정 (자가)
치명 0 / 중대 0 (P1.2 예약 1건 사용자 합의) -> **PASS** 후보. critic 재호출 가능.

## 다음 단계
- v0.1.241 P1.2 Inspector UI + ActuatorDriver registration (중대 #3 처리 + 풀스택 검증)- 사전 검토 룰 (spec-vs-codebase-pre-check.md) 갱신 — 이벤트 구독 패턴 검토 의무 추가


---

## 봉인 참조

본 사이클은 **48th stable seal (v0.1.366, 2026-05-24)** 일괄 봉인에 포함됨.

- journal: [2026-05-24-v0.1.298-366-48th-stable-seal.md](../../journal/2026-05-24-v0.1.298-366-48th-stable-seal.md)
- alias zip: [factory00-windows-x64-v0.1.366-stable.zip](../../downloads/factory00-windows-x64-v0.1.366-stable.zip) (170 MB)
