feat: release Find-Word v0.2.3

This commit is contained in:
oz
2026-10-14 10:01:46 +00:00
parent c92660b514
commit 812540c743
531 changed files with 103693 additions and 325 deletions
+133 -6
View File
@@ -1,4 +1,4 @@
# Find-Word v0.1.1 오디오 출처와 재현
# Find-Word v0.2.3 오디오 출처와 재현
## 포함 자산과 생성 설정
@@ -6,7 +6,7 @@
| --- | --- | --- | --- |
| `public/audio/intro.wav` | Microsoft Edge online TTS neural 음성 | `src/content.ts`의 INTRO | 24kHz mono PCM16 WAV |
| 목표 음성 100개 | 같은 provider·voice | 10 패턴 × 10 단어, `renderSentence` | 같은 WAV |
| 8개 배경 환경 | 직접 작성한 결정론적 DSP | `ENVIRONMENTS`, 고정 seed | 브라우저 메모리에서 합성 |
| 8개 배경 환경 | 공개 라이선스 실제 현장 녹음 | `public/ambience/manifest.json` | 12초·24kHz mono PCM16 WAV |
| 화면 파형·S 캐릭터 | 직접 작성한 CSS | `App.tsx`, `styles.css` | CSS |
voice는 **`ko-KR-HyunsuMultilingualNeural`**, rate는 **`-6%`**, pitch는
@@ -69,8 +69,8 @@ MP3를 24kHz mono signed 16-bit little-endian PCM으로 디코드한다. 파일
생성기와 독립 자산 테스트는 101개 파일의 원문·집합·SHA-256·bytes·duration,
24kHz mono PCM16, 1–20초 길이, RMS > 100/32768, full-scale 미도달,
총 48MiB 미만을 검사한다. 런타임 RMS 0.03과 최대 +6dB에서도 peak < 0.8을
요구한다. 기존 앱은 Web Audio에서 배경·음성을 RMS 정규화한 뒤 상대 SNR을 적용한다.
총 48MiB 미만을 검사한다. 기존 음성 단독 검사는 RMS 0.03과 +6dB에서 peak < 0.8을
요구한다. 0.2.3의 사용자 최대 +12dB 혼합은 세 경로 공통 감쇠로 별도 검증한다. 앱은 Web Audio에서 배경·음성을 RMS 정규화한 뒤 상대 SNR을 적용한다.
물리적 음압이나 주파수별 청감을 보정한 값은 아니다.
## 도구 라이선스와 서비스 조건
@@ -99,5 +99,132 @@ MP3를 24kHz mono signed 16-bit little-endian PCM으로 디코드한다. 파일
자동 검증은 PCM 신호·무결성·재생 흐름을 확인한다. 한국어 발음, 유사 자모의
구분, 웃음의 자연스러움과 실제 사용자의 난이도는 청취 평가가 필요하다.
대표 샘플과 게임 내 소음 혼합 상태를 직접 들어 인수 판단한다. 배경은 장소를
추상화한 합성 신호다. 이 게임의 수치는 임상 검증·치료·청력 판정용이 아니다.
대표 샘플과 게임 내 소음 혼합 상태를 직접 들어 인수 판단한다. 배경은 실제 현장 녹음의 짧은 구간이다. 이 게임의 수치는 임상 검증·치료·청력 판정용이 아니다.
## v0.2.3 현장 녹음 파생본
원본 선정 계약은 [.agent/AMBIENCE-SOURCES-v0.2.3.json](../.agent/AMBIENCE-SOURCES-v0.2.3.json),
배포 바이트의 출처·직접 URL·저작자·라이선스·변환·SHA-256·bytes·duration·RMS·peak는
[manifest](../public/ambience/manifest.json), 정확한 attribution과 변경 고지는
[AMBIENCE_NOTICES](../public/ambience/AMBIENCE_NOTICES.md)에 있다. 이 고지는 dist에도 포함되고 UI에서 링크한다.
여덟 원본 모두 서로 다른 현장 녹음이며 NC/ND 자산을 사용하지 않는다. 원본은 저장소/빌드에 포함하지 않는다.
| 환경 | 저작자 | 라이선스 | 원본 구간(초) |
| --- | --- | --- | --- |
| 길거리 | cori (Cori Samuel) | PD-author | 35–47 |
| 쇼핑몰 | thore (Thore) | PD-author | 36–48 |
| 극장 | ElevatorFan2020 | CC0 1.0 | 45–57 |
| 백화점 | icmusic | CC0 1.0 | 90–102 |
| 시장 | Marie Flutre | CC BY-SA 4.0 | 24–36 |
| 지하철 | PascalHD | CC BY 4.0 | 65–77 |
| 카페 | Marble Toast | CC0 1.0 | 0–12 |
| 비 오는 거리 | Extemporalist | CC0 1.0 | 180–192 |
Commons primary 페이지/API와 Freesound primary 페이지의 라이선스 근거를 evidence에 보존한다.
Freesound 두 원본은 지정된 preview MP3이다. 프로젝트의 비공개 라이선스를 제3자 녹음에
적용하지 않으며, 시장 파생 WAV는 **CC BY-SA 4.0**으로 계속 공개·수정·재배포할 수 있다.
지하철은 **CC BY 4.0**의 PascalHD credit·변경 고지·라이선스 링크를 유지한다.
재현: 검증한 원본 8개를 `/tmp/findword-ambience-sources`에 놓고
`python3 scripts/ambience_audio.py`를 실행한다. 계획의 파일별 `selectedSegmentStartSeconds`에서 12초를 선택하고,
FFmpeg로 mono 24kHz float PCM 디코드 후 양끝 50ms 선형 fade, RMS 목표 .08,
최대 증폭 4배/peak .85 중 가장 작은 선형 gain을 적용한다. 마지막은 표준 44-byte
WAV 헤더의 PCM16이다. 시간 변형·절차적 합성·원본 음성 대체는 없다.
원본 SHA-256과 실측 FFmpeg 버전을 함께 기록하므로 같은 원본/도구로 재현 가능하다.
런타임은 음성/배경 각각 RMS .03 후 상대 gain `10^(dB/20)`을 적용한다. −12~+12 dB
범위에서도 세 경로의 최악 피크 합을 공통 감쇠하여 최대 .8로 제한한다. 양끝 fade가
있는 배경을 loop하고 목표 끝에서 정리한다. 전체 버퍼 RMS 기준이며 짧은 시간창별
SNR이나 실제 음압을 보증하지 않는다. 원본 녹음의 우연한 사람 말소리는 환경의 일부다.
자동 검사로 음악·개인 대화의 완전한 부재를 인증할 수 없으므로 사람의 최종 청취 검토가 필요하다.
기존 neural WAV 101개의 원문·해시는 v0.1.1 그대로다. 음성 manifest의 version은
배포 버전 0.2.3, `generatedForVersion`은 0.1.1이며 원래 생성 시각·도구 정보는 보존한다.
### 리뷰 후 출처 고정과 원자 발행
승인 계획의 `expectedSourceSha256`와 `sourceBytes`는 불변 입력이다. 생성기는 로컬 경로나
현재 파일에서 이 승인값을 새로 기록하지 않으며, 여덟 원본의 해시·크기를 **첫 변환 전**에 모두 검사한다.
한 원본이라도 다르거나 누락되면 실패한다. `sourceVerification`은 검증 상태·일자·방법·보존된 증거를 가리킨다.
임시 경로를 담던 `verifiedLocalSource` 필드는 제거했다.
`directMediaDurationSeconds`는 **directUrl에서 받은 바로 그 바이트**의 ffprobe `format.duration`이다.
Freesound 항목은 preview MP3의 길이이며 primary 페이지 원본 길이 또는 반올림한 표시 길이가 아니다.
배포 manifest의 `duration`과 `conversion.durationSeconds`는 파생 WAV의 길이(12초),
`selectedSegmentStartSeconds`는 파일별 불변 승인 시작점이며 생성기는 별도 hardcoded map 없이 이 값을 읽는다.
`conversion.startSeconds`는 같은 값이어야 한다. 시작점은 유한한 0 이상 수이고, 시작점+12초가
`directMediaDurationSeconds` 이하여야 한다. 누락·음수·NaN·Infinity·문자열·bool·범위 초과는 첫 변환 전에 거부한다. 원본 전체 디코드와 실제 수치는
[보존된 source-integrity.json](../.agent/evidence-v0.2.3/source-integrity.json)에 있다.
생성기는 출력 폴더와 같은 부모의 `.ambience-stage-*/ready`에서 8 WAV·manifest·`AMBIENCE_NOTICES.md`를
완성한다. 정확한 파일 집합, 고유 해시, 원본 계획, PCM 형식·길이·fade·RMS·peak,
항목별 저작자/primary URL/direct URL/라이선스 링크/outputLicense/변경 설명을 다시 검사한다.
존재하는 symlink 및 dangling symlink 출력을 모두 거부한다. Linux `renameat2(RENAME_EXCHANGE)` 한 번이 교체의
commit 지점이며, 최초 생성은 같은 파일시스템의 rename 한 번이다. 지원하지 않는 환경에서는 실패한다.
파일별 overlay를 하지 않으므로 오래된 파일이 남지 않고 고지도 음원과 같은 디렉터리로 교체된다.
commit 전 변환·쓰기·검증·교환 실패 또는 중단은 이전 디렉터리를 보존한다. syscall 이후에는 완성된 새 디렉터리가
공개된 상태다. SIGKILL 등 강제 종료는 숨은 임시 디렉터리를 남길 수 있지만 부분 배포는 만들지 않는다.
전원 손실에 대한 디스크 내구성이나 여러 HTTP 요청에 걸친 snapshot 격리를 주장하지 않는다.
앞선 독립 리뷰에서는 기존 109 WAV를 재생성하지 않았다. 이후 아래 privacy refinement에서
전체 현장음 bundle을 원자 재생성했으며 mall/market/cafe 3개만 바이트가 바뀌었다.
**사람의 현장음 청취 인수는 미실행**이다.
### 최종 privacy excerpt refinement
현재 선택은 **mall 36–48초, market 24–36초, cafe 0–12초**다. Neo가 동일한
`scripts/ambience_audio.convert` 경로와 아래 ASR 설정으로 해시 고정 원본을 재검사해 제시한
market/cafe 후보를 사용했다. 제공받은 재검사 설명은
[selection-context.json](../.agent/evidence-v0.2.3/privacy-screening/retry-market24-cafe0/selection-context.json)에
별도로 기록했으며, 원본 후보 결과를 최종 WAV 검사 결과로 대신하지 않았다.
승인 원본 8개의 SHA-256·bytes·ffprobe 길이를 먼저 대조하고 하드닝된 생성기로
8 WAV·manifest·notice 전체를 staging/검증/원자 교환했다.
[생성 실측 기록](../.agent/evidence-v0.2.3/privacy-screening/retry-market24-cafe0/regeneration.json)에
현재 해시·RMS·peak·변환이 있다. 이번 재시도는 market/cafe 두 WAV만 변경했다.
**101개 voice, 다섯 unaffected ambience, 기존 mall 36초 WAV는 모두 바이트 동일**하다.
일부 Ogg 구간은 FFmpeg timestamp/seek 때문에 12초보다 몇 프레임 짧게 출력된다.
짧은 결과일 때만 처음부터 디코드한 24kHz PCM의 `round(start × 24000)`부터 정확한 288,000개
sample을 선택하고 출력 PTS를 sample 수로 재설정한다. silent padding이나 time stretching은 없다.
정말 원본이 짧으면 여전히 실패하며 `conversion.seekMethod`가 실제 경로를 기록한다.
[final-asr.json](../.agent/evidence-v0.2.3/privacy-screening/final-asr.json)은 정확한 현재 8 WAV를
로컬 **faster-whisper 1.2.1, tiny multilingual, CPU int8, beam_size=5, best_of=5,
기본 Silero VAD 활성화, condition_on_previous_text=true**로 검사한 원문이다.
모델 revision `d90ca5fe260221311c53c58e660288d3deb8d356`, 모델/VAD 파일 해시,
라이브러리 버전·전체 설정·각 입력 해시·반환 segment/info를 저장했다.
이전 실패 실행과 모든 decoder/VAD 인자가 같은지 스크립트가 대조한다.
**mall/market/cafe 각각 segment 0개, duration_after_vad=0.0, requiredEmptyPassed=true**다.
다른 다섯 WAV도 segment 0개다. threshold 조절이나 반환 segment 삭제는 하지 않았다.
테스트는 지정 시작점·true gate·VAD 설정·실제 WAV/manifest 해시와 아래 false 인수값을 함께 강제한다.
**humanListeningAcceptance=false, legalPrivacyClearance=false**를 유지한다.
Tiny-model ASR은 screening signal일 뿐이며 빈 결과는 말소리·음악·개인 대화가 없음을 증명하지 않는다.
출력 text/language도 환각일 수 있고 충실한 전사나 화자 식별로 주장하지 않는다.
독립적인 사람 청취 인증은 수행하지 않았다. 다만 제품 소유자 Oz는 2026-10-14 제공된
최종 WAV 8개 청취 검수 묶음과 명시된 자동 검사 한계를 기준으로 현재 자산 그대로 릴리스를
진행하도록 승인했다. 이 승인은 제3자의 법적/privacy clearance를 대신하지 않는다.
이전 market 60–72초/cafe 180–192초 실행은 market 3개/cafe 1개 segment를 반환하여
**requiredEmptyPassed=false**였으며 release acceptance 실패였다.
그 실행의 모든 screening 파일은 읽기 전용
[prior-attempt-market60-cafe180](../.agent/evidence-v0.2.3/privacy-screening/prior-attempt-market60-cafe180/)
아래 바이트 그대로 보존했다. [당시 final-asr.json](../.agent/evidence-v0.2.3/privacy-screening/prior-attempt-market60-cafe180/final-asr.json)을
성공으로 덮어쓰지 않았고 회귀 테스트가 이전 실패 상태와 모든 보존 파일 해시를 검사한다.
[기존 no-VAD 증거](../.agent/evidence-v0.2.3/privacy-screening/no-vad-asr.json)도 바이트 그대로 남겼다.
이 결과는 mall 36초/market 60초/cafe 180초에서 환각일 수 있는 candidate text를 냈으며,
새 market/cafe WAV의 검사 결과가 아니다. **no-VAD 결과는 지정된 VAD gate를 대체하거나 뒤집지 않는다.**
두 방법 모두 말소리/음악의 부재를 증명하지 않으며 사람의 청취 인수나 법적/privacy clearance를 제공하지 않는다.
Neo의 [이전 후보 scan](../.agent/evidence-v0.2.3/privacy-screening/candidate-scan-original.json),
[이전 파생본 ASR](../.agent/evidence-v0.2.3/privacy-screening/prior-derivatives-asr-original.json),
[당시 provenance](../.agent/evidence-v0.2.3/privacy-screening/earlier-asr-provenance.json)도 변경하지 않았다.
raw JSON에 없던 설정이나 입력 연결을 사후에 있었던 것으로 주장하지 않는다.
새 RED → GREEN, 전체 검증과 보존 기록은
[retry-market24-cafe0](../.agent/evidence-v0.2.3/privacy-screening/retry-market24-cafe0/),
현재 검증 요약은 [RESULT](../.agent/RESULT-v0.2.3.md)의 마지막 절에 있다.