---
phase: implementation
agent: implementation-advisor
agent_version: 1
generated_at: 2026-06-29T13:30:00+09:00
workstream: W3-5 Unity WebGL 업로드 보안 보강
---

# 파일 소유권 맵 — W3-5

설계: `.atp/work-session/20260623-104307/implementation/W3-5-upload-design.md`
파일영향맵 §파일영향맵 U-* 소유권 준수. 1파일 1worker 원칙(강결합 신규 파일군은 동일 worker 로 묶음).

## 의존 그래프 (병렬 wave)

- **Wave 1 (병렬, 독립)**: U-DDL · U-ZIPSEC · U-AUDIT-MAPPER
- **Wave 2 (Wave 1 완료 후)**: U-UPLOAD(ZipSec+Audit+Gate 의존) · U-LIFECYCLE(독립; GameController 단독)
- **Wave 3 (테스트, Wave 2 완료 후)**: TEST-ZIPSEC(U-ZIPSEC만 의존 — Wave 2와 병렬) · TEST-UPLOAD(U-UPLOAD 의존) · TEST-CTX(매퍼/서비스 빈 의존)

## 소유권 테이블

| 파일 | 담당 worker | worker id | 변경 유형 | U-태그 | 의존 |
|---|---|---|---|---|---|
| docs/game-upload-ddl.sql | migration-writer | w-001 | create | U-DDL | - |
| db/schema.sql (append) | migration-writer | w-001 | modify | U-DDL | - |
| security/ZipSecurity.java | code-writer | w-002 | create | U-ZIPSEC | ZipRejectException |
| security/ZipRejectException.java | code-writer | w-002 | create | U-ZIPSEC | - |
| mapper/GameUploadAuditMapper.java | code-writer | w-003 | create | U-AUDIT-MAPPER | GameUploadAudit, GameAssetOwner |
| data/GameUploadAudit.java | code-writer | w-003 | create | U-AUDIT-MAPPER | - |
| data/GameAssetOwner.java | code-writer | w-003 | create | U-AUDIT-MAPPER | - |
| controller/api/GameUploadController.java | code-writer | w-004 | modify | U-UPLOAD | w-002, w-003 |
| service/GameAssetCleanupService.java | code-writer | w-005 | create | U-LIFECYCLE | - |
| controller/api/GameController.java | code-writer | w-005 | modify | U-LIFECYCLE | GameAssetCleanupService |
| test/.../security/ZipSecurityTest.java | code-writer | w-006 | create | (검증) | w-002 |
| test/.../GameUploadControllerSecurityTest.java | code-writer | w-007 | create | (검증) | w-004 |
| test/.../BibimbapApplicationTests.java (append) | advisor 직접 | - | modify | (검증) | w-003, w-005 |

## 불변식 점검
- 동일 파일 단일 worker 할당: 확인 (GameController 는 w-005 단독, GameUploadController 는 w-004 단독).
- 강결합 신규 파일군 동일 worker: ZipSecurity+ZipRejectException(w-002), 매퍼+POJO 2종(w-003), Service+GameController(w-005).
- 의존 있는 건 순차 wave: Wave1 → Wave2 → Wave3.
- BibimbapApplicationTests append 는 단순 @MockBean 2줄 추가 — advisor 직접(병렬화 이득 없음, 다른 워커 산출물 보존하며 append).

## planned_workers: 7 (w-001 ~ w-007)
## actual_workers: 7 (전원 spawn — w-001 migration-writer, w-002~w-007 code-writer)

## 실제 spawn 결과
| worker id | subagent | 산출 | 상태 |
|---|---|---|---|
| w-001 | migration-writer | docs/game-upload-ddl.sql + db/schema.sql append | 완료 (reject_reason 11토큰, schema 1023줄 보존) |
| w-002 | code-writer | ZipSecurity.java + ZipRejectException.java | 완료 (enum 11, getCompressedSize 0, 3중상한, 심링크 전수) |
| w-003 | code-writer | GameUploadAuditMapper + GameUploadAudit + GameAssetOwner | 완료 (#{} only, 컬럼 8 정합, alias 정합) |
| w-004 | code-writer | GameUploadController 보강 | 완료 (게이트 순서, ATOMIC_MOVE, audit, dead code 제거) |
| w-005 | code-writer | GameAssetCleanupService + GameController 훅 | 완료 (UUID 검증+경계, gameRoot 미터치) |
| w-006 | code-writer | ZipSecurityTest (20 @Test) | 완료 (9 거부코드 + 통과 회귀, 심링크 가드) |
| w-007 | code-writer | GameUploadControllerSecurityTest (11 @Test) | 완료 (401/403/413/200/400 + CSRF 3핸들러) |

advisor 직접 처리(병렬화 이득 없는 단일 편집):
- BibimbapApplicationTests.java: @MockBean 2종(GameUploadAuditMapper, GameAssetCleanupService) append.
- ZipRejectException.java: serialVersionUID 1줄 추가([serial] lint 경고 제거).
- 빌드/타입/불변식 게이트(advisor 직접 bash): clean compile + test-compile + javac -Xlint:all(unused 0) + AC-T grep 정합.
