Record resumed development evidence and approved voice correction

This commit is contained in:
NINI
2026-10-05 14:25:51 +09:00
parent 9d8e939704
commit a383bc9d13
+232
View File
@@ -0,0 +1,232 @@
# MagnetismHeroes 개발 인수인계
작성일: 2026-10-05, 한국 시간. 사용자가 CLI를 잠시 중지하기 위해 인수인계를 요청했다. **개발과 독립 검토를 중단했으며, 이 문서 작성 이후 작업을 자동으로 계속하지 않는다.** 다음 세션에서는 아래 중단 지점부터 재개한다.
재개 기록: 같은 날 사용자가 이 문서를 읽고 개발을 이어가라고 요청했다. **T5 저장 수정과 T6의 30개 스테이지·도움·시범이 재검증·독립 검토를 통과했고 루트에 통합됐다. 다음은 T7 최종 외형·자산 통합이다.** 아래 중단 당시 내용과 최신 상태를 구분하며, `.dryforge/temp/go-runtime.json` 및 실제 소스·검증 기록을 함께 확인한다.
### 재개 후 최신 상태
- T5 검증 소스: `babaee3608d8e8fdc3c172bd6055aa2f480c3811`. EditMode 87/87, PlayMode 34/34, 건너뜀 0. Android 일반·오프라인 각각 56/56 통과. 주 파일 누락 복구·손상 백업 원문 보존·안내 화면도 Android 가상 기기에서 확인했다.
- T5 통합 후 루트 `dev`: `60f8a55bb9b3f690ce9c9e5eaffe09930d321da6`. 검사한 브랜치와 통합 소스의 제품 파일 차이가 없음을 확인했다.
- 최신 T5 APK: `artifacts/android/Persistence/MagnetismHeroes.apk`, SHA-256 `974BA14310F020BB42DFFDF4BBE76CBB7249A9FE797853B8158B9BD700AB9D35`. 이전 APK는 같은 폴더의 `503c56a-before-missing-primary-fix.apk`에 남겼다.
- 새 증거 570개는 `artifacts/verification/T5/ResumeImplementation/`에 해시를 대조해 보존했다. 독립 검토는 `artifacts/verification/T5/IndependentReview-Resume/`, 소스 대응은 `artifacts/verification/T5/source-relationship.json`에 있다. 이전 회차는 별도 유지한다.
- T6: 작업 디렉터리 `C:/git/MagnetismHeroes/.dryforge/worktrees/T6`, 브랜치 `dryforge/T6`, 기반 커밋은 위 루트와 같다. 30개 스테이지·세 테마·현재 상태 도움·첫 합체/분리 시범·관련 음성 제작을 진행한다. 다음 재개 시 실제 변경/검사 상태를 확인하고 이 작업부터 이어간다.
- T6 고정 소스 `1f26fbc421754cbc6dc75b18b3f8187305fab7eb`: EditMode 97/97, PlayMode 40/40. 실행 경계·허용 개행 정규화·정규화 후 clean 상태를 별도로 보존한다. AndroidBuild는 종료 0이며 APK SHA-256은 `2F9F31D796AB568FE7814A8930B3C64153CECD7AEDF1F42DB916FD55FBDE02DE`다. AndroidSmoke는 첫 PCM 상관 검사 실패를 보존하고 재생·녹음 원인을 분석 중이며 아직 완료가 아니다. Blender 배경 방향과 숫자 표시 가림을 수정했고, 수 세기 자석 55개의 회전·집기·직접 끌기 검사를 포함한다.
- 음성 후보 44개(기존 승인 3개·청취 대기 41개)의 실제 게임 WAV 복사본과 SHA-256은 `artifacts/audio-preview/Content/candidate-record.json`, 듣기 페이지는 같은 폴더의 `index.html`에 있다. 사용자가 `count_08`이 이상하다며 쉼표 없이 붙여 읽도록 요청했다. 기존 3개만 승인, `count_08`은 거절된 후보이며 나머지 40개도 아직 승인되지 않았다. 동일 GPU·1.7B·Sohee·seed42 프로필과 `여덟.` 대본의 새 후보 입력은 `artifacts/audio-production/count08-correction/Voice`에 준비했다. AVD 녹음을 잠시 중단한 구간에서 실제 GPU 추론·검증·편집을 마쳤다. 새 후보는 0.56초이며 SHA-256 `fa8034948f6ac3e289e8e7e9fb447943760d4ed5ac577c8ab0c961c608fe49c2`, run `20261005T043059823226Z_abdd0294`다. `artifacts/audio-preview/count08-correction-v2/index.html`로 새 청취 질문을 보냈으며 아직 승인 응답은 없다. 현재 검사 중인 소스·APK를 바꾸지 않고 후속 표현 작업에서 채택·재검증한다. 기존 세 파일에 대한 승인을 나머지 파일로 확대하지 않는다.
- 효과음·음악은 사용자가 나중에 추가하기로 했다. 전체 완료·최종 Android 검증·계획 보관은 아직 수행하지 않았다.
- Android 음성 진단: 기존·현재 APK 모두에서 에뮬레이터 gRPC 녹음의 긴 발화 대조 실패를 재현했다. 같은 게임 음성을 Android 내부 AudioRecord로 원시 녹음하면 전체 발화 상관 약 0.99999를 확인했다. 정확한 gRPC 실패 원인은 단정하지 않는다. Content 검사에만 공식 scrcpy 4.1 기반 내부 녹음을 연결하고, 전체 상관 0.95에 더해 동일 시작점의 100ms 창을 50ms 간격으로 검사하는 `RequireFullSpeech`를 추가 중이다. 앞·중간 250ms 누락을 포함한 음성 훼손 대조군이 실제 실패해야 한다. 이 도구 변경 후 새 소스를 고정하여 네 검사를 다시 수행하며, 아직 최종 AndroidSmoke 통과로 처리하지 않는다. 제품 APK에는 녹음 서버·도구·권한을 추가하지 않는다.
- 이후 사용자가 새 `count_08`에 “새 음성 괜찮습니다”라고 답했다. 위 SHA `fa8034948f6ac3e289e8e7e9fb447943760d4ed5ac577c8ab0c961c608fe49c2`만 청취 승인됐으며 원문·파일 해시·시각은 `artifacts/audio-preview/count08-correction-v2/user-approval.json`에 기록했다. 기존 거절 파일이나 다른 40개에 승인을 확대하지 않는다. 검사 중인 T6 APK는 그대로 두고 T7에서 새 승인본을 통합한다.
- T6의 새 도구 고정 커밋은 `ccc8b77cf52e1a591f900ce25cf4c16b1d92b9f8`다. 이 소스로 EditMode97/97·PlayMode40/40·AndroidBuild 종료0을 실제 확인했고 APK는 이전 제품 파일과 같은 SHA `2F9F31D796AB568FE7814A8930B3C64153CECD7AEDF1F42DB916FD55FBDE02DE`다. 이전 최종 원문은 `frozen-1f26-superseded`에 보존했다. 녹음 검사에서 앞/중간250ms 누락을 포함한 대조군6개를 거부하고 정상 발화1개를 통과하는 것을 독립 재계산으로도 확인했다. AndroidSmoke는 네트워크 전환 안정화 실패와 작은 음성의 RMS/단일 창 상관 실패를 그대로 남겼으며 아직 통과하지 않았다. 실제 기기 음량15를 설정해도 내부 녹음의 gain은 그대로인 관찰이 있어 장치별 녹음 경로를 확인 중이다. 낮은 진폭의 원인을 단정하거나 검사 기준을 낮추지 않는다.
- 기존 구현 담당자는 모델 용량 오류로 종료되어 `/root/content_verification_resume`가 같은 T6 폴더의 유일한 쓰기 담당자로 이어받았다. 독립 검토 담당자는 `/root/content_spec_review`다. 최신 AVD PID는 `23984`였으며 다음 실행 전 실제 상태를 재확인한다.
- T6 최종 완료: `ccc8b77`의 Edit97/97·Play40/40·AndroidBuild·AndroidSmoke48/48·추가30번10/10은 모두 실제 종료0이다. 동일 APK의 11발화 전체와 모든 유효 음성 창을 확인했다. 실제 설치 base.apk도 기기/호스트/빌드 SHA가 위 APK와 같다. 녹음 시작 후 활성 `remote_submix` 장치 음량을15로 설정하니 작은 발화도 같은 검사 기준을 통과했고, 검사 후 speaker·remote_submix·default5 및 네트워크0/1/1을 실제 복원했다. 후속 Final에서도 활성 녹음 장치의 실제 음량·복원 증거를 남긴다. 독립 검토 pass이며 루트 통합 커밋 `9d8e93970476170143f78f9c675dbf78f1ec8107`은 검사한 커밋과 전체 Git 트리가 같다. 원본923개는 `artifacts/verification/T6/Implementation/`, 독립 원본44개는 `artifacts/verification/T6/IndependentReview/`, 보존 해시·소스 대응은 같은 상위 폴더의 manifest/source-relationship JSON에 있다. T7 가독성 검수는 `.dryforge/temp/T7-visual-cases.md`를 따르고 새 승인 count_08을 교체한다. 전체 완료나 T8 최종 검증은 아직 아니다.
이하 1~9절은 최초 중단 시점의 기록이다. 현재 T5 수정/검토를 다시 미완료로 취급하거나 이전 APK·검사 소스를 최신으로 사용하지 않는다.
## 1. 재개할 때 가장 먼저 할 일
1. 이 문서와 `.dryforge/handoff.md` → `.dryforge/spec.md` → `.dryforge/plan.md`를 읽는다. 이 문서는 실행 현황이며, 승인된 요구사항의 원본은 `.dryforge`의 세 문서다.
2. 아래 dryforge `go` 지침과 참조 문서를 읽고, 루트와 T5 작업 디렉터리의 Git 상태·커밋·검사 증거를 다시 확인한다. **T5는 아직 루트에 통합하지 않는다.**
3. `LocalProgressStore.TryLoad`의 **주 저장 파일이 없고 백업만 남은 경우**를 수정·검증한다. 독립 검토에서 발견했고 root가 실제 코드로 확인한 미해결 결함이다.
4. T5의 새 소스를 커밋한 뒤 네 검사 명령을 다시 실행하고, 새로운 소스·APK·증거에 대한 독립 명세 검토를 끝낸다.
5. 검토가 통과한 뒤 T5를 통합하고, 계획 순서대로 T6 → T7 → T8을 수행한다. 아직 전체 개발 완료나 계획 보관 처리를 하지 않는다.
사용자가 다시 시작하면 이미 승인한 개발 범위를 이어간다. 기존 선택·권한을 다시 묻지 않는다. 효과음·음악 선택과 새 음성의 청취 승인처럼 실제로 미결인 항목은 별도로 유지한다.
## 2. 저장소와 작업 위치
| 항목 | 중단 시 확인한 값 |
|---|---|
| 프로젝트 루트 | `C:/git/MagnetismHeroes` |
| 루트 브랜치 | `dev` — 처음부터 개발 기반으로 사용한 로컬 브랜치 |
| 루트 HEAD | `a651e5ca7f49239bf9b5027e067c588d1e1a832c` — T4까지 통합 |
| T5 작업 디렉터리 | `C:/git/MagnetismHeroes/.dryforge/worktrees/T5` |
| T5 브랜치 | `dryforge/T5` |
| T5 HEAD | `503c56a19e8705ddf4b2fc0691ef7e80fa44854f` |
| T5 기반 커밋 | `a651e5ca7f49239bf9b5027e067c588d1e1a832c` |
| 내부 실행 기록 | `.dryforge/temp/go-runtime.json` |
| 승인 계획 | `.dryforge/handoff.md`, `.dryforge/spec.md`, `.dryforge/plan.md` |
중단 직후 루트와 T5 모두 기존 추적 파일의 변경이 없었다. 이 인수인계 문서는 이번 중단 요청으로 추가한 파일이다. T5 결함 수정은 요청만 전달했고, 중단 시점에는 코드 변경·새 테스트·새 커밋이 없음을 확인했다.
작업용 디렉터리와 검사 산출물은 Git에서 제외된다. **다음 CLI도 이 컴퓨터의 현재 저장소에서 재개해야 모든 원본 증거를 사용할 수 있다.** 저장소를 복제하거나 이동한다면 `.dryforge`, `artifacts`, 제작 원본·환경 기록도 별도로 보존해야 한다.
확인 명령:
```powershell
git -C C:/git/MagnetismHeroes status --short
git -C C:/git/MagnetismHeroes rev-parse HEAD
git -C C:/git/MagnetismHeroes/.dryforge/worktrees/T5 status --short
git -C C:/git/MagnetismHeroes/.dryforge/worktrees/T5 rev-parse HEAD
```
## 3. 적용 지침과 실행 순서
사용자가 `$dryforge:go`를 실행해 승인한 전체 개발을 진행 중이다. 스킬 원본:
`C:/Users/baram/.codex/plugins/cache/dryforge/dryforge/1.3.7/skills/go/SKILL.md`
함께 읽을 참조는 해당 스킬 폴더의 `references/orchestration.md`, `graph-contract.md`, `implementer-prompt.md`, `spec-review-prompt.md`다. 최종 단계에는 최종 검토·문서 생성·보관 절차의 참조도 읽는다.
- 실행 그래프는 **T1 → T2 → T3 → T4 → T5 → T6 → T7 → T8**, 모두 `RISKY`, `regen_barriers: []`다. 임의로 순서를 바꾸거나 생략하지 않는다.
- 각 위험 작업은 별도 작업 디렉터리의 구현 담당자 한 명에게 맡긴다. 후속 작업으로 결함이 전파될 수 있는 경우 통합 전에 새 독립 명세 검토를 수행한다. 이 위임은 호출된 스킬의 명시적 요구에 따른다.
- 검토자는 명세와 실제 변경·원시 증거로 판단하고 구현 담당자의 자기 평가에 의존하지 않는다.
- 완료는 실제 명령·종료 코드·양수 테스트 수·전부 통과·미실행/건너뜀 없음·검사한 소스·APK 해시로 입증한다.
- 단일 작업의 누적 기반 검사가 통과했다면 별도 중복 통합 검사 단계를 만들지 않는다. 통합 시에는 변경 범위와 공통 연결을 확인한다.
- 아직 첫 개발 주기이며 `.dryforge/status.json`은 없다. 전체 작업과 최종 검토를 끝내기 전에 세 계획 문서를 지우거나 보관 완료로 처리하지 않는다.
- 사용자는 한국어로 소통한다. 설명과 지속 문서도 한국어로 작성한다. 관련 없는 리팩터링이나 범용 프레임워크 추가를 하지 않는다.
- 외부 메시지·원격 게시·PR 병합·스토어 배포는 요청되지 않았다.
## 4. 완료된 개발과 증거
T1~T4는 구현·검증·필요한 독립 검토를 마치고 `dev`에 통합했다. 순수 C# 수학 규칙, 첫 수 세기 퍼즐, 조기 Android 검증, 합체·분리·혼합 퍼즐이 포함된다.
T4 검증 소스는 `08ce71c0a2c7ce9e5504c7a461252bdbfd295c0b`다. EditMode 79개, PlayMode 31개, Android 검사 23개가 통과했고 독립 검토도 통과했다. 루트의 `artifacts/verification/T4/`에 원시 증거와 독립 검토, 소스 대응 기록을 보존했다.
T4 APK: `artifacts/android/Composition/MagnetismHeroes.apk`
SHA-256: `6E3FD34B646B4A4872830BCC246B9E0D00371A01E7B9C8241B42351AA954BF58`
T5는 개별 미완료 저장·최근 자유 놀이·자석 공급/반납·저장 오류 안내를 구현했다. **아래 검사들은 수정 전 소스 503c56a에 대해 실제 통과한 기록이지만, 미해결 검토 사항이 있어 T5 전체 완료 승인은 아니다.**
| 검사 | 실제 결과 |
|---|---|
| EditMode | 84/84, 건너뜀 0, 종료 코드 0 |
| PlayMode | 34/34, 건너뜀 0, 종료 코드 0 |
| AndroidBuild | 종료 코드 0, 소스 시작/끝 clean |
| AndroidSmoke | 49/49, 종료 코드 0 |
Android에서 실제 터치로 두 구 중 하나만 센 상태(1/2), 회전·확대 시점, 서로 다른 두 미완료 퍼즐과 자유 놀이의 교대 복원을 확인했다. 10개 공급 제한, 묶음 전체 반납, 빈 놀이판 재공급, 실제 파일 쓰기 실패 안내·회복, 손상 주 파일의 백업 복구, 주 파일과 백업의 손상 원문 보존도 검사했다.
T5 원본 증거:
`C:/git/MagnetismHeroes/.dryforge/worktrees/T5/artifacts/verification/Persistence/`
루트 보존본:
`artifacts/verification/T5/Implementation/`
보존 목록: `artifacts/verification/T5/preserved-implementation-manifest.json` — 278개 파일의 원본/복사본 SHA-256 일치를 확인했다. 실행 중인 에뮬레이터의 가변 stdout/stderr 두 파일만 명시적으로 제외했다. 다른 실패 로그·RED 테스트·원시 JSON·PNG·명령·PCM은 보존했다.
T5 APK: `artifacts/android/Persistence/MagnetismHeroes.apk`
SHA-256: `44EDA75849E3F1AE86AC14C766059214D8165765E1575261D5715AFA24EE3965`
주요 원시 파일은 `editmode.xml`, `playmode.xml`, 각 `*-evidence.json`, `*-source-boundary.json`, `android-persistence-evidence.json`, `two-partial-before-pause.json`, `two-partial-after-restart.json`, `two-restored-stage.png`다. 새 수정 후 기존 증거를 덮어쓰지 말고 이전 회차를 별도 보존한다. 독립 검토는 아직 완료되지 않았으며 최종 pass 기록이 없다.
## 5. 바로 수정해야 할 저장 결함
파일: T5의 `Assets/MagnetismHeroes/UnityRuntime/Persistence/LocalProgressStore.cs`, `TryLoad`, 중단 시 약 33행.
현재 코드:
```csharp
if (!File.Exists(_path)) { save = new ProgressSave(); return true; }
```
이 때문에 `progress.json`이 없어지고 유효한 `progress.json.bak`만 남으면 백업을 읽지 않고 새 게임으로 시작한다. R12의 손상·불완전 저장에 대한 마지막 유효본 복구 요구에 어긋난다. root가 독립 검토 후보를 실제 코드로 확인했고, **주 파일 누락도 복구 대상임을 명시했다. 사용자 확인이 필요한 기획 변경이 아니다.**
수정 범위와 합격 사례:
1. 주 파일 없음 + 유효 백업: 전체 진행·개별 퍼즐·자유 놀이·카메라를 백업에서 복구하고 기존 복구 안내를 제공한다.
2. 주 파일 없음 + 손상 백업: 읽기 실패를 보고하고, 정상 초기 진입 뒤 후속 두 저장에서도 손상 백업 원문을 보존한다.
3. 주 파일·백업 모두 없음: 정상 새 저장으로 시작한다.
4. 기존 주 파일 손상·둘 다 손상·쓰기 실패·부분 계수 복원 동작을 유지한다.
기존 `Read`와 백업 경로를 재사용해 최소 수정한다. JSON 필드·버전 변경, 과도한 추상화, 검사 기준 완화는 하지 않는다. 먼저 실패 테스트를 실행해 RED를 남기고 수정 후 GREEN을 확인한다. Android에서도 실제 주 파일을 제거하고 유효 백업만 남겨 전체 복구 및 한국어 안내를 검사한다. 손상 백업만 남은 경우도 검사한다.
구현 담당자 `/root/persistence_implementation`에게 이 수정과 재검증을 요청했으나 사용자의 중단 요청 직후 중지했다. 독립 검토자 `/root/persistence_spec_review`도 중지했다. 다음 세션에서는 이 에이전트들이 계속 동작한다고 가정하지 말고 역할과 경로를 다시 지정한다. 미완료 독립 검토는 나머지 결함 여부까지 마쳐야 한다.
T5 작업 디렉터리에서 새 소스를 커밋한 후 실행:
```powershell
pwsh -NoProfile -File tools/verify.ps1 -Phase EditMode -Milestone Persistence
pwsh -NoProfile -File tools/verify.ps1 -Phase PlayMode -Milestone Persistence
pwsh -NoProfile -File tools/verify.ps1 -Phase AndroidBuild -Milestone Persistence
pwsh -NoProfile -File tools/verify.ps1 -Phase AndroidSmoke -Milestone Persistence
```
통합 전에는 작업 브랜치가 루트보다 앞서고, 세 점 비교의 변경이 비어 있지 않으며 선언된 작업 범위를 지키는지 확인한다. 실제 `Main.unity`는 공통 프리팹 참조를 사용하므로 불필요하게 장면 파일을 수정하지 않는다.
## 6. 구현 경계와 주의 사항
- 수학 규칙·진행은 `Assets/MagnetismHeroes/Core/`의 Unity 비의존 C#이다. 입력/화면/파일 저장은 `UnityRuntime/`, 자산 제작 도구는 `Editor/`다. 상태 머신·Presenter·저장 인터페이스·직접 시작 연결을 유지한다.
- `GameData.cs`가 고정 정의/상태 타입을 포함한다. 고정 스테이지는 ScriptableObject, 플레이 상태는 로컬 JSON v1이다.
- 주 저장 필드는 `schemaVersion`, `completedStageIds`, `seenTutorialIds`, `puzzleStates`, `latestFreePlay`다. 자유 놀이에는 수집/계수 목록을 저장하지 않는다.
- 직접 끌어 놓거나 그 조작으로 합쳐진 두 묶음의 구는 수집한 것으로 기록할 수 있다. 이는 R05의 명시적 요구다.
- 퍼즐 정답은 전체 묶음 수량의 다중집합으로 비교한다. 모양·위치·특정 조작 이력을 정답 조건에 추가하지 않는다.
- T5의 `GameSession.SaveFinished`, 시범 본 기록 API, 공급·전체 반납 경로가 후속 기능의 연결점이다.
- 숫자 음성은 FIFO이며 같은 보드에서 자유 놀이로 전환하거나 나누기를 취소해도 마지막 숫자를 끊지 않는다. `CancelGuide`는 숫자 큐를 보존한다. 화면 전환·일시 정지는 이전 큐를 정리한다.
- 현재 임시 자산 제작기를 둘 다 재실행할 때는 `CompositionAssets.Build` 다음 `PersistenceAssets.Build` 순서다. T6에서 전체 콘텐츠 제작기를 정리한다.
- Unity 장면·프리팹·ScriptableObject는 에디터 API로 제작한다. YAML 수동 편집은 하지 않는다.
검사 중 Unity의 설정 직렬화가 변경된 것처럼 나타나는 경우에도 실제 변경을 숨기지 않는다. `tools/verify.ps1`은 지정된 파일의 **전체 blob 동일성**을 비교하는 개행 정규화만 허용한다. `ShaderGraphSettings.asset` 한 항목 추가는 root가 실제 동일 해시를 확인해 허용한 것이다.
별도 확인된 파생 캐시 예외: `Assets/Settings/UniversalRenderPipelineGlobalSettings.asset`에서 `m_Settings.m_RuntimeSettings.m_List`의 14개 rid만 빈 목록으로 바뀌는 경우, 설치된 URP 코드의 `OnAfterDeserialize`가 이를 비우는 동작을 확인했다. 정확한 diff와 패키지 코드 해시 증거를 보존한 경우에만 HEAD로 복원하도록 허용했다. **다른 속성/참조 변화는 이 예외에 포함되지 않는다.** 근거는 `.dryforge/temp/T5-derived-URP-decision.json` 및 T5의 `runtime-derived-*` 증거다. 검사 보호 조건을 넓혀 우회하지 않는다.
## 7. 다음 개발 단계
### T6: 전체 스테이지·배경·도움·시범
- R07의 고정 30개 정의를 모두 실제 ScriptableObject로 만든다. 새 저장 1번부터 순차 해금·재플레이·이어하기 표시를 연결한다. 30번 뒤에는 31번을 제공하지 않는다.
- 1~5번은 1~5 수 세기, 16~20번은 6~10 수 세기다. 구성 퍼즐의 정확한 초기/목표 배열은 원본 표를 따른다.
- 6번 첫 합치기와 10번 첫 나누기 시범은 실제 퍼즐을 바꾸거나 완료시키지 않는 별도 표현으로 만든다. 본 기록은 영속 저장한다.
- 도움은 현재 미수집/미계수 구 또는 현재 묶음에서 목표에 다가가는 첫 행동을 알려준다. 분리된 수집형은 먼저 합칠 두 묶음을 알려준다. 자동 정답 실행은 하지 않는다.
- Blender 원본 `.blend`와 내보낸 FBX 소품으로 서로 다른 테마 세 개를 만든다. 테마는 스테이지의 고정 정의에서 가져오고 성공·퍼즐 복원·자유 놀이 복원에도 유지한다. 번호마다 새 장면을 만들지 않는다.
- 모든 자석에 발견·집기 가능한 시점을 확인한다. 소품에 완전히 갇힌 배치를 만들지 않는다. 새 배경에서도 자유 놀이의 0~10 공급/반납을 회귀 검사한다.
- 실제 도움/시범 대본과 Qwen 생성 이력을 완성한다. 자동 파일 검사를 사람의 발음 승인으로 취급하지 않는다.
- 전체 Core 해답 경로·해금, 자산 검사·PlayMode 및 변경된 흐름의 Android 검사를 실행한다.
### T7: 최종 카툰 표현·소리·화면
- 대표 얼굴·얇은 마스크·연결 빛·묶음별 얇은 리본 망토를 완성한다. 구 개수·크기·아이의 기본 배열을 유지한다.
- 2+3→5, 떨어진 두 구 선택 후 5→2+3, 1~10의 직선/평면/입체 배열을 실제로 돌려 보며 구·숫자·선택·계수의 가독성을 확인한다. 취소/연속 조작/화면 이동/복원 후 중복 표현이 남지 않아야 한다.
- 승인된 계획에 따라 실제 2D 얼굴/UI/텍스처에도 AI 이미지를 사용한다. 관련 imagegen 스킬을 읽고 실제 이미지 도구로 생성·편집한다. 숫자·한국어는 TMP 실제 텍스트로 표시한다.
- 원본·제작 도구·프롬프트/대본·설정·해시·라이선스·채택 기록을 보존하고 필요한 글꼴 사용 고지도 APK에 넣는다.
- 사용자 선택 효과음/음악과 모든 필수 음성의 실제 오프라인 재생을 확인한다. 미선택 음원이나 미청취 음성을 완료로 표시하지 않는다.
- 가로 스마트폰/태블릿 비율·안전 영역을 검사하고 최다 10개/무거운 배경의 비용을 측정한다. 에뮬레이터 성능을 실제 기기 인증으로 표시하지 않는다.
### T8: 최종 Android 검증
- 최종 소스·APK를 고정하고 전체 EditMode/PlayMode/AndroidBuild/AndroidSmoke를 실행한다.
- 새 저장에서 정상 진행으로 30개를 전부 해결·해금하고, 대표 1/6/9/10/13/14/20/30번, 두 미완료+자유 놀이 복원, 오프라인 소리와 입력 경계를 검증한다. QA 저장 주입을 전체 정상 진행 증거로 대체하지 않는다.
- 이후 dryforge 지침의 지속 문서 생성·최종 독립 검토·필요한 사용자 승인·계획 보관 절차를 수행한다. 실제 기기·iOS·스토어 배포는 후속 범위로 남긴다.
## 8. 음성·음악의 승인 상태
사용자는 **효과음과 음악을 나중에 정해서 추가하겠다**고 답했다. `docs/audio-requests.md`에 요청 목록이 있다. 직접 선택·작곡·구매하거나 AI 음악으로 대신하지 않는다. 이 보류가 전체 최종 음향 완료를 의미하지는 않는다.
청취 승인된 실제 파일은 `count_01`, `guide_collect`, `guide_count` 세 개뿐이다. 사용자의 답은 “세 파일 모두 괜찮습니다”였다. 원본 승인 해시는 `docs/qwen-voice-register.md`와 선택 기록에 있다. 파일을 바꾸면 기존 승인도 자동으로 이어지지 않는다.
새 합체 음성 후보 `guide_merge`, `guide_split`, `demo_composition`의 청취 질문은 **답변 대기**다. 후보와 해시는 `artifacts/audio-preview/Composition/`에 있다. `demo_composition`은 둘과 둘을 만드는 14번 내용이므로 다른 스테이지의 첫 합치기/나누기 시범에 그대로 쓰지 않는다. 그 밖의 숫자 음성도 미청취 초안이다.
`count_05`는 9.12초의 비정상 후보여서 게임 연결에서 제외했다. 이전 두 생성 회차를 보존하고 해당 클립만 새 후보로 재생성한다. 승인된 세 파일을 바꾸거나 공유 프로필을 일괄 변경하지 않는다. 실제 청취 수단 없이 파일 길이·PCM 상관도로 발음 합격을 선언하지 않는다.
## 9. 개발 환경과 재시작 시 확인
| 도구 | 확인한 구성 |
|---|---|
| Unity | `6000.6.3f1`, Android Build Support·SDK·NDK·OpenJDK 설치 및 APK 빌드 성공 |
| 렌더링·입력·UI | URP 17.6.0, Input System 1.20.0, uGUI/TMP 2.6.0 |
| Unity 테스트 | Test Framework 1.8.0 |
| Unity CLI | `C:/Users/baram/AppData/Local/Unity/bin/unity.exe` |
| Blender | `C:/Program Files/Blender Foundation/Blender 5.2/blender.exe`, 5.2.2 LTS |
| Qwen Python | `C:/Users/baram/anaconda3/envs/qwen3-tts/python.exe` |
| 음성 추론 | 1.7B CustomVoice, 한국어 Sohee, CUDA GPU, SDPA/bfloat16, seed 42 |
| GPU | RTX 4080 SUPER, 실제 모델 로딩·GPU 추론 확인 |
| 모델 revision | `0c0e3051f131929182e2c023b9537f8b1c68adfe` |
| 제작 프로필 | `SourceAssets/Audio/Voice/qwen-profile.json` |
| 음성 목록 | `SourceAssets/Audio/Voice/voice-catalog.json` |
conda·모델·제작 캐시를 APK에 넣지 않는다. 게임은 완성된 WAV만 재생한다. 기존 모델·GPU 선택을 임의로 CPU/다른 목소리/클라우드로 바꾸지 않는다.
중단 시 Android 가상 기기는 살아 있었다. AVD `Medium_Phone_API_37.0`, serial `emulator-5554`, qemu PID `9928`, launcher PID `13092`, gRPC `127.0.0.1:8554`다. **PID는 재개 시 다시 확인하며 해당 번호만 믿고 종료하지 않는다.** Unity 에디터 PID 41540은 중단 시 존재하지 않았다. 에뮬레이터는 중단 요청에서 종료하지 않았다.
실행 구성은 `-no-window -no-snapshot-save -gpu host -grpc 8554 -grpc-use-token`이다. API37 x86_64 환경의 ARM64 변환으로 APK를 실행했다. 이는 실제 Android 폰에서의 발열·배터리·터치감·성능 검증이 아니다.
- 에뮬레이터/ADB 변경은 동시에 한 담당자만 수행한다. 재개 후 소유권을 새로 지정한다.
- Unity SDK와 사용자 SDK의 ADB 버전이 서버를 바꿔 일시적으로 offline이 된 실패 기록이 있다. 기기/부팅 상태 확인 후 다시 실행하고 원시 실패를 보존한다.
- 가로 스크린샷은 2400×1080이다. gRPC 터치는 세로 논리 좌표여서 `(x,y) → (1080-y,x)` 변환이 필요했던 반면 ADB 입력은 가로 좌표를 사용했다. 기존 검사 도구를 우선 재사용한다.
- gRPC 토큰/인증 헤더를 파일·로그·문서에 노출하지 않는다. 시작 프로세스는 숨김 창을 사용한다.
- 재귀 삭제/이동은 절대 경로가 의도한 작업 영역 안인지 확인하고 PowerShell의 `-LiteralPath`를 사용한다. 보존 전 작업 디렉터리/실패 증거를 삭제하지 않는다.
재개 시 이 문서의 상태를 실제 파일·프로세스·Git과 대조한 뒤 진행한다. 사용자 중단 이후 추가 개발이나 T5 통합을 수행하지 않았다.