feat: improve Korean neural voice quality for v0.1.1
@@ -0,0 +1,21 @@
|
||||
# ACCEPTANCE — Find-Word v0.1.1
|
||||
|
||||
- [ ] package/UI/index/README/manifest 버전 0.1.1
|
||||
- [ ] 정확한 크레딧 유지
|
||||
- [ ] `ko-KR-HyunsuMultilingualNeural`, edge-tts 7.3.1 기반 101개 신규 WAV
|
||||
- [ ] 24kHz mono 16-bit PCM
|
||||
- [ ] 모든 WAV 비무음, full-scale peak 없음, 합리적 duration
|
||||
- [ ] manifest 원문·hash·bytes·duration·provider·voice·prosody·tool version
|
||||
- [ ] 임시 디렉터리 전체 생성 후 원자 교체
|
||||
- [ ] bounded retry와 실패 시 기존 자산 보존
|
||||
- [ ] runtime 외부 TTS/API 요청 없음
|
||||
- [ ] eSpeak 생성 의존 제거
|
||||
- [ ] audio provenance와 생성 도구 라이선스·provider 한계 문서
|
||||
- [ ] 기존 10개 mechanic/100문장/8환경/5SNR/choice+text 보존
|
||||
- [ ] lint PASS
|
||||
- [ ] 전체 tests PASS
|
||||
- [ ] build PASS
|
||||
- [ ] desktop/mobile browser tests PASS
|
||||
- [ ] audit high 0
|
||||
- [ ] `.agent/RESULT-v0.1.1.md`
|
||||
- [ ] Codex는 commit/push/deploy 미실행
|
||||
@@ -0,0 +1,146 @@
|
||||
# Find-Word v0.1.1 — 한국어 neural voice 업그레이드 결과
|
||||
|
||||
작성일: 2026-10-14 UTC. worktree: `/home/hermes/worktrees/find-word-v0.1.1`.
|
||||
브랜치: `fix/v0.1.1-neural-voice`.
|
||||
입력 `.agent/TASK-v0.1.1.md`, `.agent/ACCEPTANCE-v0.1.1.md` 및 기존 맥락을 읽었다.
|
||||
입력 문서는 수정하지 않았다. **Git commit/push, main merge, 서버 배포는 실행하지 않았다.**
|
||||
|
||||
## 구현 결과
|
||||
|
||||
- package·lock·UI·index·README·LICENSE·현재 버전 문서·manifest를 **0.1.1**로 맞췄다.
|
||||
- 정확한 크레딧 `Designed by OZ at Heat-T Medical Inc.`와 canonical repository
|
||||
`https://source.ibit.kr/OZ-Group/Find-Word`를 유지했다.
|
||||
- **Microsoft Edge online TTS**, **ko-KR-HyunsuMultilingualNeural**,
|
||||
**edge-tts 7.3.1**, rate **-6%**, pitch **-4Hz**로 안내 1개·목표 100개를
|
||||
모두 실제로 새로 생성했다. 기존 WAV를 재포장하거나 재사용하지 않았다.
|
||||
- pinned `.venv-audio/bin/python`과 `requirements-audio.txt`로 생성 절차를 고정했다.
|
||||
전역 Python의 다른 버전으로 fallback하지 않는다. FFmpeg 실측 버전은
|
||||
`6.1.1-3ubuntu5`이다.
|
||||
- 임시 MP3를 FFmpeg로 24kHz mono PCM16으로 디코드하고 선형 gain만 적용한다.
|
||||
파일별 RMS 목표 0.10, 증폭 최대 2배, peak ceiling 0.89. 압축·게이트·음절 편집은 없다.
|
||||
- 임시 디렉터리에서 101개 전체 검증 후 Linux `renameat2(RENAME_EXCHANGE)`로
|
||||
단일 원자 교환한다. provider 최대 3회, 1/2초 backoff, 시도당 60초 제한.
|
||||
변환 실패·검증 실패·중단·원자 교체 실패는 기존 자산을 보존한다.
|
||||
- manifest에 원문·SHA-256·bytes·duration·RMS·peak와 provider·voice·prosody·버전·
|
||||
sample rate·생성 시각·실측 도구 버전을 남겼다. 인증 헤더·쿠키·API 키는 저장하지 않는다.
|
||||
- 기존 생성 도구의 캐시/다운로드/문서/manifest 의존을 제거했다. 기존 v0.1 기록은 보존했다.
|
||||
- 10개 mechanic, 100문장, 8환경, 5SNR, 객관식·주관식, IME·재생 취소·재청취·
|
||||
실패 복구 흐름은 기존 소스와 테스트를 보존했다. 앱은 로컬 WAV만 요청한다.
|
||||
|
||||
## 구현 전에 확인한 실제 RED → GREEN
|
||||
|
||||
RED를 모두 실행한 뒤 구현했다. 생성기의 새 함수 계약은 `NotImplementedError`만
|
||||
발생시키는 비동작 stub으로 선언했고, 기존 명령 진입점은 RED 때 그대로 두어 import
|
||||
부작용도 실패로 확인했다. stub에 성공 경로를 미리 구현하지 않았다.
|
||||
RED는 각 명령 종료 코드 **1**, GREEN은 **0**이다. 실패 로그를 덮어쓰지 않았다.
|
||||
|
||||
| 계약 | 실제 RED | 실제 GREEN | 원문 evidence |
|
||||
| --- | --- | --- | --- |
|
||||
| UI/package/lock/index/문서 버전 및 pinned 생성·권리 문서 | `npm test -- tests/neural-release.test.ts tests/App.test.tsx -t '0.1.1\|브랜드\|고정 venv'`: 3 failed, 기존 12개는 필터로 제외 | 동일 명령 3 passed | [RED](evidence-v0.1.1/01-version-docs-red.log), [GREEN](evidence-v0.1.1/08-version-docs-green.log) |
|
||||
| neural provider/voice/prosody/실측 버전, 101개 PCM·원문·hash·bytes·duration | `npm test -- tests/assets.test.ts`: 2 failed. 기존 16kHz·누락 metadata/duration을 실제 검출 | 최종 전체 suite에서 두 계약 모두 통과 | [RED](evidence-v0.1.1/02-assets-red.log), [GREEN](evidence-v0.1.1/11-full-test.log) |
|
||||
| 원자 교체·초기 공개·bounded retry·timeout·기존 자산 보존·secret redaction·실제 MP3 변환·PCM 검증·import 부작용 | Python unittest 16개 모두 RED (subtest 포함 failures=4, errors=20) | 아래 추가 계약을 포함한 18개 통과 | [RED](evidence-v0.1.1/03-generator-red.log), [GREEN](evidence-v0.1.1/05-generator-green.log) |
|
||||
| 앞서 생성한 파일 손상 감지, 다른 edge-tts 버전의 외부 요청 전 거부 | 구현 전 전체 18개 RED (subtest 포함 failures=5, errors=21) | `python3 -m unittest discover -s tests/python -v`: 18 passed | [추가 RED](evidence-v0.1.1/04-generator-additional-red.log), [GREEN](evidence-v0.1.1/05-generator-green.log) |
|
||||
|
||||
Python 계약은 fake provider/작은 PCM fixture로 실패를 강제한다. 원자 디렉터리 교체와
|
||||
FFmpeg MP3 변환은 테스트에서도 실제 실행한다. 이 fixture는 public 음성에 사용하지
|
||||
않았다. 실제 provider의 101개 생성은 다음 별도 로그에 있으며 실패/재시도는 0회였다.
|
||||
전체 `npm test`는 Python 계약 runner도 포함하며 **skip 없이** 통과했다.
|
||||
|
||||
## 실제 음성 생성·전수 독립 검사
|
||||
|
||||
명령: `npm run audio:generate`.
|
||||
생성 완료: **2026-10-14T06:55:41.751382+00:00**.
|
||||
[101개 실제 생성 로그](evidence-v0.1.1/06-audio-generate.log).
|
||||
|
||||
| 항목 | 실제 결과 |
|
||||
| --- | --- |
|
||||
| WAV 개수 | 101개, 101개 해시 모두 고유하고 v0.1의 같은 파일과 모두 다름 |
|
||||
| WAV 합계 | **34,898,524바이트** (약 33.282MiB), 48MiB 예산 이내 |
|
||||
| PCM | 전부 **24,000Hz · mono · signed 16-bit PCM** |
|
||||
| duration | **3.816–11.256초**, 안내 7.056초 |
|
||||
| RMS 범위 | **0.0999998534–0.1000000486** |
|
||||
| peak 범위 | **0.3692016602–0.6843261719**, full-scale 0개 |
|
||||
| 원문·bytes·duration·SHA-256 | 101/101 일치 |
|
||||
| FFprobe 포맷 확인 + FFmpeg 전체 디코드 | 101/101 성공 |
|
||||
| Chrome 실제 WAV 디코드·해시·레벨 검사 | 101/101 성공, 외부 페이지 요청 0·JS 예외 0 |
|
||||
| 남은 임시 MP3/공개 staging 폴더 | 0개 |
|
||||
|
||||
[독립 검사 스크립트](evidence-v0.1.1/verify_audio.py)는 생성기의 검증 함수를
|
||||
import하지 않는다. Python wave·해시·앱 원문과 FFprobe/FFmpeg를 별도로 대조한다.
|
||||
[원문 로그](evidence-v0.1.1/12-independent-audio.log),
|
||||
[파일별 수치 JSON](evidence-v0.1.1/audio-integrity.json).
|
||||
|
||||
[Chrome 전수 검사 스크립트](evidence-v0.1.1/verify_browser.mjs)는 production preview의
|
||||
WAV를 실제 `OfflineAudioContext`로 디코드한다. 응답 bytes/hash, 채널, rate, duration,
|
||||
RMS, peak와 UI/index 버전을 검사한다.
|
||||
[Chrome 로그](evidence-v0.1.1/15-browser-audio.log),
|
||||
[101개 디코드 결과 및 sandbox 상태](evidence-v0.1.1/browser-audio-integrity.json).
|
||||
|
||||
청취용: [intro.wav](../public/audio/intro.wav), [luck-apple.wav](../public/audio/luck-apple.wav).
|
||||
|
||||
## 최종 검증
|
||||
|
||||
환경: Node **26.7.0**, npm **11.19.0**, Python **3.11.16**, Chrome **146.0.7680.80**,
|
||||
Linux 6.8.0, glibc 2.39. [실측 환경과 pip check](evidence-v0.1.1/18-environment.log).
|
||||
|
||||
| 검증 | 결과 | evidence |
|
||||
| --- | --- | --- |
|
||||
| `npm ci` | PASS, 238 packages 설치 | [로그](evidence-v0.1.1/00-npm-ci.log) |
|
||||
| `npm run lint` | PASS, ESLint + TypeScript strict | [최종 로그](evidence-v0.1.1/16-final-lint.log) |
|
||||
| `npm test` | **11 files / 60 passed**, skip 0; Python 18개 계약 포함 | [로그](evidence-v0.1.1/11-full-test.log) |
|
||||
| `npm run audio:generate` | **101개 신규 생성·검증·원자 교체 성공** | [로그](evidence-v0.1.1/06-audio-generate.log) |
|
||||
| `npm run build` | PASS, 101개 해시·런타임 MIT notice 전문 검증 | [로그](evidence-v0.1.1/13-build.log) |
|
||||
| sandboxed system Chrome desktop/mobile suite | **12 passed (2.3m)**, skip 0 | [로그](evidence-v0.1.1/14-browser.log) |
|
||||
| sandboxed Chrome 101개 전수 디코드 | PASS, Namespace/PID/Network/Seccomp sandbox 활성 | [로그](evidence-v0.1.1/15-browser-audio.log) |
|
||||
| `npm audit --audit-level=high` | **0 vulnerabilities**, npm 개발 의존성 포함 | [로그](evidence-v0.1.1/10-audit.log) |
|
||||
| 독립 101개 원문/hash/PCM/FFmpeg 검사 | PASS | [JSON](evidence-v0.1.1/audio-integrity.json) |
|
||||
| 소스·문서·manifest 비밀값 패턴 검사 | 40개 텍스트 파일, 0 matches | [기록](evidence-v0.1.1/17-security-history.json) |
|
||||
| `git diff --check`·문서 링크·sandbox 실행 인자·HEAD·역사 기록 최종 검사 | PASS | [최종 무결성](evidence-v0.1.1/19-final-integrity.json) |
|
||||
| 과거 evidence + RESULT 해시 대조 | **115개 전부 동일** | [baseline](evidence-v0.1.1/baseline.json), [검사](evidence-v0.1.1/17-security-history.json) |
|
||||
|
||||
브라우저 전체 명령:
|
||||
`env -u PLAYWRIGHT_NO_SANDBOX CHROME_PATH=/usr/bin/google-chrome DEBUG=pw:browser npm run test:browser`.
|
||||
두 viewport(1280×1000, 360×800)에서 실제 음성으로 10문제 완주·재청취·404 재시도·
|
||||
키보드·레이아웃·reduced motion·axe·크레딧·MIT HTTP 응답이 모두 통과했다.
|
||||
시작·게임·결과 axe 위반 0, 외부 페이지 요청 0, 페이지 JS 예외 0이다.
|
||||
로컬 preview만 테스트 중 열었으며 서버 배포는 하지 않았다.
|
||||
Chrome 전수 검사에서는 `chrome://sandbox`의 Namespace·Seccomp 상태도 실제 확인했다.
|
||||
headless 브라우저는 실제 파일을 디코드하고 Web Audio를 실행하지만 물리적 스피커
|
||||
청취를 대신하지 않는다. Chrome stderr의 시스템 GPU/GCM 진단과 페이지 JS 예외는 구분한다.
|
||||
|
||||
스크린샷: [desktop 시작](evidence-v0.1.1/desktop-home.png),
|
||||
[게임](evidence-v0.1.1/desktop-game.png), [결과](evidence-v0.1.1/desktop-results.png),
|
||||
[mobile 시작](evidence-v0.1.1/mobile-home.png), [게임](evidence-v0.1.1/mobile-game.png),
|
||||
[결과](evidence-v0.1.1/mobile-results.png).
|
||||
|
||||
## 변경 파일과 기록 보존
|
||||
|
||||
- 앱 표기: `src/App.tsx`, `index.html`, `package.json`, `package-lock.json`.
|
||||
- 생성: `scripts/generate_audio.py`, 신규 `scripts/neural_audio.py`,
|
||||
`requirements-audio.txt`, `.gitignore`, `eslint.config.js`의 venv 제외.
|
||||
- 자산: `public/audio/*.wav` 101개와 `manifest.json`.
|
||||
- 계약 테스트: `tests/assets.test.ts`, `tests/App.test.tsx`, 신규
|
||||
`tests/neural-release.test.ts`, `tests/generator.test.ts`, `tests/python/test_neural_audio.py`.
|
||||
- 기존 browser tests는 새 스크린샷 경로와 v0.1.1 실측 길이 주석만 변경했다.
|
||||
`tests/browser/game.spec.ts`, `tests/browser/ui.spec.ts`. 기존 assertion/timeout은 유지했다.
|
||||
- 문서: `README.md`, `LICENSE`, `docs/AUDIO_PROVENANCE.md`,
|
||||
`docs/ARCHITECTURE.md`, `docs/DEPLOYMENT.md`.
|
||||
- 이번 기록: `.agent/RESULT-v0.1.1.md`, `.agent/evidence-v0.1.1/`.
|
||||
|
||||
이전 `.agent/RESULT.md`, `.agent/evidence/`의 파일은 수정하지 않았다.
|
||||
스크린샷도 새 경로에만 저장한다. 입력 TASK/ACCEPTANCE의 시작 상태는 untracked였으며
|
||||
Codex가 새로 작성한 입력 문서가 아니다. 전체 파일 목록은
|
||||
[changed-files.txt](evidence-v0.1.1/changed-files.txt)에 별도로 남긴다.
|
||||
|
||||
## 남은 청감·provider 한계
|
||||
|
||||
- 자동 검사와 실제 브라우저 재생은 완료했지만 **사람의 청감 평가를 수행한 것은 아니다**.
|
||||
한국어 발음·유사 자모 구분·웃음·소음 혼합 난이도는 대표 샘플과 게임으로 직접 평가해야 한다.
|
||||
- 원격 모델/서비스는 고정할 수 없다. pinned client로 절차를 재현해도 다음 생성의
|
||||
바이트가 같다는 보장은 없다. provider 장애·제한·음성 목록 변경 시 명확히 실패한다.
|
||||
- edge-tts의 LGPLv3(일부 MIT)와 FFmpeg의 빌드별 LGPL/GPL은 provider 서비스 조건 및
|
||||
음성 출력의 권리와 별개다. 생성 음성의 독점 권리나 포괄적 상업 이용 허락을 주장하지 않는다.
|
||||
근거 링크·확인일·조건의 한계는 [AUDIO_PROVENANCE](../docs/AUDIO_PROVENANCE.md)에 기록했다.
|
||||
- 원자 교체는 Linux와 해당 파일시스템의 지원이 필요하다. SIGKILL/전원 손실 때 임시
|
||||
숨김 폴더는 남을 수 있고 전원 손실 내구성까지 보장하지 않는다. 일반 실패·Ctrl-C는 정리한다.
|
||||
- 실제 모바일 Safari/물리적 오디오 장치 청취는 이번 Chrome 검증 범위 밖이다.
|
||||
@@ -0,0 +1,59 @@
|
||||
# TASK — Find-Word v0.1.1 Korean neural voice upgrade
|
||||
|
||||
## 사용자 지시
|
||||
|
||||
현재 v0.1의 한국어 음성이 제대로 만들어지지 않았다. 음성 품질을 높이고 샘플을 다시 생성하며 버전을 0.1.1로 올린다. 모든 소스는 Gitea에 push 및 main merge할 예정이다. Codex는 구현만 하고 commit/push/deploy는 하지 않는다.
|
||||
|
||||
## 고정 계약
|
||||
|
||||
- 정확한 크레딧: `Designed by OZ at Heat-T Medical Inc.`
|
||||
- canonical repository: `https://source.ibit.kr/OZ-Group/Find-Word`
|
||||
- 작업 브랜치: `fix/v0.1.1-neural-voice`
|
||||
- 버전: UI/package/docs/manifest 모두 `0.1.1`
|
||||
- 한국어 상세 소스 주석 유지
|
||||
- 기존 10개 mechanic, 100개 문장 조합, 8개 환경, 5단계 SNR, 객관식·주관식 기능 보존
|
||||
|
||||
## 선택한 생성 방식
|
||||
|
||||
- 직접 생성한 사전 샘플에서 사용 가능한 고품질 음성: `ko-KR-HyunsuMultilingualNeural`
|
||||
- 생성 클라이언트: `edge-tts==7.3.1`
|
||||
- 권장 prosody: rate `-6%`, pitch `-4Hz`
|
||||
- 앱 런타임에는 외부 TTS/API 요청이 없어야 한다.
|
||||
- 생성 시 임시 MP3를 받아 ffmpeg로 24kHz mono PCM s16 WAV로 변환한다.
|
||||
- 음성 간 레벨 편차와 peak를 완화하되 발음을 훼손하는 과도한 DSP를 하지 않는다.
|
||||
- 네트워크·provider 오류에 bounded retry와 명확한 실패를 제공한다.
|
||||
- 부분 실패가 기존 public/audio를 훼손하지 않도록 임시 디렉터리에서 전체 생성·검증 후 원자 교체한다.
|
||||
- API 키·쿠키·인증정보를 저장하지 않는다.
|
||||
|
||||
## 품질·재현성 요구사항
|
||||
|
||||
- intro 1개 + 목표 문장 100개, 총 101개를 모두 새로 생성한다.
|
||||
- manifest에 version, provider, voice, rate, pitch, edge-tts version, ffmpeg version, sample rate, SHA-256, bytes, duration, 원문을 기록한다.
|
||||
- 24kHz mono 16-bit PCM, 비무음, peak full-scale 미도달, 비정상적으로 짧거나 긴 파일 없음.
|
||||
- `audio:generate`는 pinned venv의 Python으로 재현 가능해야 하고 README/AUDIO_PROVENANCE에 설치·생성 절차와 provider 의존성·한계를 기록한다.
|
||||
- `public/audio/intro.wav`와 대표 샘플 `luck-apple.wav`가 청취용 샘플이다.
|
||||
- eSpeak cache/download 경로·문서·manifest 의존성을 제거한다. 과거 evidence는 당시 기록이므로 내용 변조 없이 보존한다.
|
||||
- 생성 도구의 오픈소스 라이선스와 서비스 사용 조건을 과장 없이 문서화한다. 프로젝트가 음성 자체에 독점 권리를 주장한다고 쓰지 않는다.
|
||||
|
||||
## TDD
|
||||
|
||||
1. 버전 0.1.1 계약 테스트 RED
|
||||
2. neural provider/voice/manifest 계약 RED
|
||||
3. 24kHz·비무음·peak·duration·101개 integrity RED
|
||||
4. generator atomicity/retry/unsafe secret absence 테스트 RED
|
||||
5. 기존 full suite와 browser suite GREEN
|
||||
|
||||
## 최종 검증
|
||||
|
||||
- npm ci
|
||||
- npm run lint
|
||||
- npm test
|
||||
- npm run audio:generate 또는 명시적 생성 명령
|
||||
- npm run build
|
||||
- sandboxed system Chrome browser tests
|
||||
- npm audit --audit-level=high
|
||||
- 101개 manifest/hash/PCM 독립 검사
|
||||
|
||||
## 기록
|
||||
|
||||
`.agent/RESULT-v0.1.1.md`에 RED/GREEN, 변경 파일, 생성 provider/voice, 자산 크기, 최종 결과, 남은 청감·provider 위험을 기록한다.
|
||||
@@ -0,0 +1,44 @@
|
||||
Collecting edge-tts==7.3.1
|
||||
Using cached edge_tts-7.3.1-py3-none-any.whl.metadata (6.1 kB)
|
||||
Collecting aiohttp<4.0.0,>=3.8.0 (from edge-tts==7.3.1)
|
||||
Using cached aiohttp-3.14.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (8.3 kB)
|
||||
Collecting certifi>=2023.11.17 (from edge-tts==7.3.1)
|
||||
Using cached certifi-2026.7.22-py3-none-any.whl.metadata (2.5 kB)
|
||||
Collecting tabulate<1.0.0,>=0.4.4 (from edge-tts==7.3.1)
|
||||
Using cached tabulate-0.10.0-py3-none-any.whl.metadata (40 kB)
|
||||
Collecting typing-extensions<5.0.0,>=4.1.0 (from edge-tts==7.3.1)
|
||||
Using cached typing_extensions-4.16.0-py3-none-any.whl.metadata (3.3 kB)
|
||||
Collecting aiohappyeyeballs>=2.5.0 (from aiohttp<4.0.0,>=3.8.0->edge-tts==7.3.1)
|
||||
Using cached aiohappyeyeballs-2.7.1-py3-none-any.whl.metadata (5.9 kB)
|
||||
Collecting aiosignal>=1.4.0 (from aiohttp<4.0.0,>=3.8.0->edge-tts==7.3.1)
|
||||
Using cached aiosignal-1.4.0-py3-none-any.whl.metadata (3.7 kB)
|
||||
Collecting attrs>=17.3.0 (from aiohttp<4.0.0,>=3.8.0->edge-tts==7.3.1)
|
||||
Using cached attrs-26.1.0-py3-none-any.whl.metadata (8.8 kB)
|
||||
Collecting frozenlist>=1.1.1 (from aiohttp<4.0.0,>=3.8.0->edge-tts==7.3.1)
|
||||
Using cached frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.metadata (20 kB)
|
||||
Collecting multidict<8.0,>=4.5 (from aiohttp<4.0.0,>=3.8.0->edge-tts==7.3.1)
|
||||
Using cached multidict-7.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (6.2 kB)
|
||||
Collecting propcache>=0.2.0 (from aiohttp<4.0.0,>=3.8.0->edge-tts==7.3.1)
|
||||
Using cached propcache-0.5.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (25 kB)
|
||||
Collecting yarl<2.0,>=1.25.1 (from aiohttp<4.0.0,>=3.8.0->edge-tts==7.3.1)
|
||||
Using cached yarl-1.25.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (111 kB)
|
||||
Collecting idna>=2.0 (from yarl<2.0,>=1.25.1->aiohttp<4.0.0,>=3.8.0->edge-tts==7.3.1)
|
||||
Using cached idna-3.20-py3-none-any.whl.metadata (7.2 kB)
|
||||
Using cached edge_tts-7.3.1-py3-none-any.whl (38 kB)
|
||||
Using cached aiohttp-3.14.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (1.9 MB)
|
||||
Using cached certifi-2026.7.22-py3-none-any.whl (136 kB)
|
||||
Using cached tabulate-0.10.0-py3-none-any.whl (39 kB)
|
||||
Using cached typing_extensions-4.16.0-py3-none-any.whl (45 kB)
|
||||
Using cached aiohappyeyeballs-2.7.1-py3-none-any.whl (15 kB)
|
||||
Using cached aiosignal-1.4.0-py3-none-any.whl (7.5 kB)
|
||||
Using cached attrs-26.1.0-py3-none-any.whl (67 kB)
|
||||
Using cached frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (231 kB)
|
||||
Using cached multidict-7.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (480 kB)
|
||||
Using cached propcache-0.5.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (235 kB)
|
||||
Using cached yarl-1.25.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (117 kB)
|
||||
Using cached idna-3.20-py3-none-any.whl (69 kB)
|
||||
Installing collected packages: typing-extensions, tabulate, propcache, multidict, idna, frozenlist, certifi, attrs, aiohappyeyeballs, yarl, aiosignal, aiohttp, edge-tts
|
||||
Successfully installed aiohappyeyeballs-2.7.1 aiohttp-3.14.5 aiosignal-1.4.0 attrs-26.1.0 certifi-2026.7.22 edge-tts-7.3.1 frozenlist-1.8.0 idna-3.20 multidict-7.1.0 propcache-0.5.4 tabulate-0.10.0 typing-extensions-4.16.0 yarl-1.25.1
|
||||
|
||||
[notice] A new release of pip is available: 24.0 -> 26.2.1
|
||||
[notice] To update, run: python -m pip install --upgrade pip
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
added 238 packages, and audited 239 packages in 3s
|
||||
|
||||
56 packages are looking for funding
|
||||
run `npm fund` for details
|
||||
|
||||
found 0 vulnerabilities
|
||||
@@ -0,0 +1,305 @@
|
||||
test_all_101_are_validated_before_single_atomic_publication (test_neural_audio.GeneratorContract.test_all_101_are_validated_before_single_atomic_publication) ... ERROR
|
||||
test_atomic_exchange_keeps_old_tree_at_staging_path (test_neural_audio.GeneratorContract.test_atomic_exchange_keeps_old_tree_at_staging_path) ... ERROR
|
||||
test_atomic_first_publication (test_neural_audio.GeneratorContract.test_atomic_first_publication) ... ERROR
|
||||
test_cli_import_has_no_generation_or_filesystem_side_effects (test_neural_audio.GeneratorContract.test_cli_import_has_no_generation_or_filesystem_side_effects) ... FAIL
|
||||
test_edge_adapter_uses_pinned_python_prosody_timeout_and_no_shell (test_neural_audio.GeneratorContract.test_edge_adapter_uses_pinned_python_prosody_timeout_and_no_shell) ... ERROR
|
||||
test_exhausted_provider_failure_preserves_existing_files_and_redacts_secrets (test_neural_audio.GeneratorContract.test_exhausted_provider_failure_preserves_existing_files_and_redacts_secrets) ... FAIL
|
||||
test_ffmpeg_adapter_actually_decodes_mp3_to_normalized_pcm24 (test_neural_audio.GeneratorContract.test_ffmpeg_adapter_actually_decodes_mp3_to_normalized_pcm24) ... ERROR
|
||||
test_ffmpeg_failure_is_not_retried_and_preserves_existing_files (test_neural_audio.GeneratorContract.test_ffmpeg_failure_is_not_retried_and_preserves_existing_files) ... FAIL
|
||||
test_interruption_preserves_existing_files_and_cleans_temporary_data (test_neural_audio.GeneratorContract.test_interruption_preserves_existing_files_and_cleans_temporary_data) ... ERROR
|
||||
test_invalid_pcm_never_reaches_publication (test_neural_audio.GeneratorContract.test_invalid_pcm_never_reaches_publication) ... ERROR
|
||||
test_publication_failure_preserves_existing_files (test_neural_audio.GeneratorContract.test_publication_failure_preserves_existing_files) ... ERROR
|
||||
test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests (test_neural_audio.GeneratorContract.test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests) ...
|
||||
test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests (test_neural_audio.GeneratorContract.test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests) (entries={'file': 'intro.wav', 'text': '안내 문장'}) ... ERROR
|
||||
test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests (test_neural_audio.GeneratorContract.test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests) (entries={'file': 'intro.wav', 'text': '안내 문장'}) ... ERROR
|
||||
test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests (test_neural_audio.GeneratorContract.test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests) (entries={'file': '../escape.wav', 'text': '외부'}) ... ERROR
|
||||
test_timeout_is_bounded_and_preserves_existing_files (test_neural_audio.GeneratorContract.test_timeout_is_bounded_and_preserves_existing_files) ... FAIL
|
||||
test_transient_provider_failures_retry_cleanly_with_bounded_backoff (test_neural_audio.GeneratorContract.test_transient_provider_failures_retry_cleanly_with_bounded_backoff) ... ERROR
|
||||
test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) ...
|
||||
test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'amplitude': 0}) ... ERROR
|
||||
test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'amplitude': 32767}) ... ERROR
|
||||
test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'rate': 16000}) ... ERROR
|
||||
test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'channels': 2}) ... ERROR
|
||||
test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'width': 1}) ... ERROR
|
||||
test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'duration': 0.2}) ... ERROR
|
||||
test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'duration': 21}) ... ERROR
|
||||
test_valid_pcm_returns_measured_hash_bytes_duration_and_levels (test_neural_audio.PCMContract.test_valid_pcm_returns_measured_hash_bytes_duration_and_levels) ... ERROR
|
||||
|
||||
======================================================================
|
||||
ERROR: test_all_101_are_validated_before_single_atomic_publication (test_neural_audio.GeneratorContract.test_all_101_are_validated_before_single_atomic_publication)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 78, in test_all_101_are_validated_before_single_atomic_publication
|
||||
result = self.run_generate()
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 69, in run_generate
|
||||
return audio.generate(ENTRIES, self.output, synthesize=synthesize or self.synthesize,
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 5, in generate
|
||||
raise NotImplementedError("neural 생성·retry·검증·원자 교체 미구현")
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_atomic_exchange_keeps_old_tree_at_staging_path (test_neural_audio.GeneratorContract.test_atomic_exchange_keeps_old_tree_at_staging_path)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 202, in test_atomic_exchange_keeps_old_tree_at_staging_path
|
||||
audio.atomic_publish(staged, self.output)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 13, in atomic_publish
|
||||
raise NotImplementedError("원자 디렉터리 교체 미구현")
|
||||
NotImplementedError: 원자 디렉터리 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_atomic_first_publication (test_neural_audio.GeneratorContract.test_atomic_first_publication)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 211, in test_atomic_first_publication
|
||||
audio.atomic_publish(staged, output)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 13, in atomic_publish
|
||||
raise NotImplementedError("원자 디렉터리 교체 미구현")
|
||||
NotImplementedError: 원자 디렉터리 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_edge_adapter_uses_pinned_python_prosody_timeout_and_no_shell (test_neural_audio.GeneratorContract.test_edge_adapter_uses_pinned_python_prosody_timeout_and_no_shell)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 177, in test_edge_adapter_uses_pinned_python_prosody_timeout_and_no_shell
|
||||
audio.synthesize_edge("한국어 ; $(literal)", path)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 17, in synthesize_edge
|
||||
raise NotImplementedError("pinned edge-tts 실행 미구현")
|
||||
NotImplementedError: pinned edge-tts 실행 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_ffmpeg_adapter_actually_decodes_mp3_to_normalized_pcm24 (test_neural_audio.GeneratorContract.test_ffmpeg_adapter_actually_decodes_mp3_to_normalized_pcm24)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 190, in test_ffmpeg_adapter_actually_decodes_mp3_to_normalized_pcm24
|
||||
audio.convert_mp3(mp3, output)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 21, in convert_mp3
|
||||
raise NotImplementedError("ffmpeg 변환 및 선형 레벨 보정 미구현")
|
||||
NotImplementedError: ffmpeg 변환 및 선형 레벨 보정 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_interruption_preserves_existing_files_and_cleans_temporary_data (test_neural_audio.GeneratorContract.test_interruption_preserves_existing_files_and_cleans_temporary_data)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 149, in test_interruption_preserves_existing_files_and_cleans_temporary_data
|
||||
self.run_generate(synthesize=interrupt)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 69, in run_generate
|
||||
return audio.generate(ENTRIES, self.output, synthesize=synthesize or self.synthesize,
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 5, in generate
|
||||
raise NotImplementedError("neural 생성·retry·검증·원자 교체 미구현")
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_invalid_pcm_never_reaches_publication (test_neural_audio.GeneratorContract.test_invalid_pcm_never_reaches_publication)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 132, in test_invalid_pcm_never_reaches_publication
|
||||
self.run_generate(convert=invalid)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 69, in run_generate
|
||||
return audio.generate(ENTRIES, self.output, synthesize=synthesize or self.synthesize,
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 5, in generate
|
||||
raise NotImplementedError("neural 생성·retry·검증·원자 교체 미구현")
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_publication_failure_preserves_existing_files (test_neural_audio.GeneratorContract.test_publication_failure_preserves_existing_files)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 155, in test_publication_failure_preserves_existing_files
|
||||
self.run_generate()
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 69, in run_generate
|
||||
return audio.generate(ENTRIES, self.output, synthesize=synthesize or self.synthesize,
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 5, in generate
|
||||
raise NotImplementedError("neural 생성·retry·검증·원자 교체 미구현")
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests (test_neural_audio.GeneratorContract.test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests) (entries={'file': 'intro.wav', 'text': '안내 문장'})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 163, in test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests
|
||||
audio.generate(entries, self.output, synthesize=self.synthesize)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 5, in generate
|
||||
raise NotImplementedError("neural 생성·retry·검증·원자 교체 미구현")
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests (test_neural_audio.GeneratorContract.test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests) (entries={'file': 'intro.wav', 'text': '안내 문장'})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 163, in test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests
|
||||
audio.generate(entries, self.output, synthesize=self.synthesize)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 5, in generate
|
||||
raise NotImplementedError("neural 생성·retry·검증·원자 교체 미구현")
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests (test_neural_audio.GeneratorContract.test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests) (entries={'file': '../escape.wav', 'text': '외부'})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 163, in test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests
|
||||
audio.generate(entries, self.output, synthesize=self.synthesize)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 5, in generate
|
||||
raise NotImplementedError("neural 생성·retry·검증·원자 교체 미구현")
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_transient_provider_failures_retry_cleanly_with_bounded_backoff (test_neural_audio.GeneratorContract.test_transient_provider_failures_retry_cleanly_with_bounded_backoff)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 97, in test_transient_provider_failures_retry_cleanly_with_bounded_backoff
|
||||
self.run_generate(synthesize=flaky)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 69, in run_generate
|
||||
return audio.generate(ENTRIES, self.output, synthesize=synthesize or self.synthesize,
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 5, in generate
|
||||
raise NotImplementedError("neural 생성·retry·검증·원자 교체 미구현")
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'amplitude': 0})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 225, in test_rejects_silence_clipping_bad_format_and_abnormal_duration
|
||||
audio.inspect_wav(path)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 9, in inspect_wav
|
||||
raise NotImplementedError("PCM 품질 검사 미구현")
|
||||
NotImplementedError: PCM 품질 검사 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'amplitude': 32767})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 225, in test_rejects_silence_clipping_bad_format_and_abnormal_duration
|
||||
audio.inspect_wav(path)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 9, in inspect_wav
|
||||
raise NotImplementedError("PCM 품질 검사 미구현")
|
||||
NotImplementedError: PCM 품질 검사 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'rate': 16000})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 225, in test_rejects_silence_clipping_bad_format_and_abnormal_duration
|
||||
audio.inspect_wav(path)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 9, in inspect_wav
|
||||
raise NotImplementedError("PCM 품질 검사 미구현")
|
||||
NotImplementedError: PCM 품질 검사 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'channels': 2})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 225, in test_rejects_silence_clipping_bad_format_and_abnormal_duration
|
||||
audio.inspect_wav(path)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 9, in inspect_wav
|
||||
raise NotImplementedError("PCM 품질 검사 미구현")
|
||||
NotImplementedError: PCM 품질 검사 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'width': 1})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 225, in test_rejects_silence_clipping_bad_format_and_abnormal_duration
|
||||
audio.inspect_wav(path)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 9, in inspect_wav
|
||||
raise NotImplementedError("PCM 품질 검사 미구현")
|
||||
NotImplementedError: PCM 품질 검사 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'duration': 0.2})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 225, in test_rejects_silence_clipping_bad_format_and_abnormal_duration
|
||||
audio.inspect_wav(path)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 9, in inspect_wav
|
||||
raise NotImplementedError("PCM 품질 검사 미구현")
|
||||
NotImplementedError: PCM 품질 검사 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'duration': 21})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 225, in test_rejects_silence_clipping_bad_format_and_abnormal_duration
|
||||
audio.inspect_wav(path)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 9, in inspect_wav
|
||||
raise NotImplementedError("PCM 품질 검사 미구현")
|
||||
NotImplementedError: PCM 품질 검사 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_valid_pcm_returns_measured_hash_bytes_duration_and_levels (test_neural_audio.PCMContract.test_valid_pcm_returns_measured_hash_bytes_duration_and_levels)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 231, in test_valid_pcm_returns_measured_hash_bytes_duration_and_levels
|
||||
result = audio.inspect_wav(path)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 9, in inspect_wav
|
||||
raise NotImplementedError("PCM 품질 검사 미구현")
|
||||
NotImplementedError: PCM 품질 검사 미구현
|
||||
|
||||
======================================================================
|
||||
FAIL: test_cli_import_has_no_generation_or_filesystem_side_effects (test_neural_audio.GeneratorContract.test_cli_import_has_no_generation_or_filesystem_side_effects)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 172, in test_cli_import_has_no_generation_or_filesystem_side_effects
|
||||
spec.loader.exec_module(module)
|
||||
File "<frozen importlib._bootstrap_external>", line 940, in exec_module
|
||||
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/generate_audio.py", line 27, in <module>
|
||||
source = subprocess.check_output([
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/.local/share/uv/python/cpython-3.11.16-linux-x86_64-gnu/lib/python3.11/unittest/mock.py", line 1124, in __call__
|
||||
return self._mock_call(*args, **kwargs)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/.local/share/uv/python/cpython-3.11.16-linux-x86_64-gnu/lib/python3.11/unittest/mock.py", line 1128, in _mock_call
|
||||
return self._execute_mock_call(*args, **kwargs)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/.local/share/uv/python/cpython-3.11.16-linux-x86_64-gnu/lib/python3.11/unittest/mock.py", line 1183, in _execute_mock_call
|
||||
raise effect
|
||||
AssertionError: import 실행 금지
|
||||
|
||||
======================================================================
|
||||
FAIL: test_exhausted_provider_failure_preserves_existing_files_and_redacts_secrets (test_neural_audio.GeneratorContract.test_exhausted_provider_failure_preserves_existing_files_and_redacts_secrets)
|
||||
----------------------------------------------------------------------
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
During handling of the above exception, another exception occurred:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 111, in test_exhausted_provider_failure_preserves_existing_files_and_redacts_secrets
|
||||
with self.assertRaisesRegex(RuntimeError, "target-1.wav.*3") as failure:
|
||||
AssertionError: "target-1.wav.*3" does not match "neural 생성·retry·검증·원자 교체 미구현"
|
||||
|
||||
======================================================================
|
||||
FAIL: test_ffmpeg_failure_is_not_retried_and_preserves_existing_files (test_neural_audio.GeneratorContract.test_ffmpeg_failure_is_not_retried_and_preserves_existing_files)
|
||||
----------------------------------------------------------------------
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
During handling of the above exception, another exception occurred:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 138, in test_ffmpeg_failure_is_not_retried_and_preserves_existing_files
|
||||
with self.assertRaisesRegex(RuntimeError, "intro.wav.*변환"):
|
||||
AssertionError: "intro.wav.*변환" does not match "neural 생성·retry·검증·원자 교체 미구현"
|
||||
|
||||
======================================================================
|
||||
FAIL: test_timeout_is_bounded_and_preserves_existing_files (test_neural_audio.GeneratorContract.test_timeout_is_bounded_and_preserves_existing_files)
|
||||
----------------------------------------------------------------------
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
During handling of the above exception, another exception occurred:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 123, in test_timeout_is_bounded_and_preserves_existing_files
|
||||
with self.assertRaisesRegex(RuntimeError, "intro.wav.*3"):
|
||||
AssertionError: "intro.wav.*3" does not match "neural 생성·retry·검증·원자 교체 미구현"
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 16 tests in 0.633s
|
||||
|
||||
FAILED (failures=4, errors=20)
|
||||
@@ -0,0 +1,332 @@
|
||||
test_all_101_are_validated_before_single_atomic_publication (test_neural_audio.GeneratorContract.test_all_101_are_validated_before_single_atomic_publication) ... ERROR
|
||||
test_atomic_exchange_keeps_old_tree_at_staging_path (test_neural_audio.GeneratorContract.test_atomic_exchange_keeps_old_tree_at_staging_path) ... ERROR
|
||||
test_atomic_first_publication (test_neural_audio.GeneratorContract.test_atomic_first_publication) ... ERROR
|
||||
test_cli_import_has_no_generation_or_filesystem_side_effects (test_neural_audio.GeneratorContract.test_cli_import_has_no_generation_or_filesystem_side_effects) ... FAIL
|
||||
test_edge_adapter_uses_pinned_python_prosody_timeout_and_no_shell (test_neural_audio.GeneratorContract.test_edge_adapter_uses_pinned_python_prosody_timeout_and_no_shell) ... ERROR
|
||||
test_exhausted_provider_failure_preserves_existing_files_and_redacts_secrets (test_neural_audio.GeneratorContract.test_exhausted_provider_failure_preserves_existing_files_and_redacts_secrets) ... FAIL
|
||||
test_ffmpeg_adapter_actually_decodes_mp3_to_normalized_pcm24 (test_neural_audio.GeneratorContract.test_ffmpeg_adapter_actually_decodes_mp3_to_normalized_pcm24) ... ERROR
|
||||
test_ffmpeg_failure_is_not_retried_and_preserves_existing_files (test_neural_audio.GeneratorContract.test_ffmpeg_failure_is_not_retried_and_preserves_existing_files) ... FAIL
|
||||
test_full_validation_detects_changed_earlier_file_before_publication (test_neural_audio.GeneratorContract.test_full_validation_detects_changed_earlier_file_before_publication) ... ERROR
|
||||
test_interruption_preserves_existing_files_and_cleans_temporary_data (test_neural_audio.GeneratorContract.test_interruption_preserves_existing_files_and_cleans_temporary_data) ... ERROR
|
||||
test_invalid_pcm_never_reaches_publication (test_neural_audio.GeneratorContract.test_invalid_pcm_never_reaches_publication) ... ERROR
|
||||
test_publication_failure_preserves_existing_files (test_neural_audio.GeneratorContract.test_publication_failure_preserves_existing_files) ... ERROR
|
||||
test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests (test_neural_audio.GeneratorContract.test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests) ...
|
||||
test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests (test_neural_audio.GeneratorContract.test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests) (entries={'file': 'intro.wav', 'text': '안내 문장'}) ... ERROR
|
||||
test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests (test_neural_audio.GeneratorContract.test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests) (entries={'file': 'intro.wav', 'text': '안내 문장'}) ... ERROR
|
||||
test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests (test_neural_audio.GeneratorContract.test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests) (entries={'file': '../escape.wav', 'text': '외부'}) ... ERROR
|
||||
test_timeout_is_bounded_and_preserves_existing_files (test_neural_audio.GeneratorContract.test_timeout_is_bounded_and_preserves_existing_files) ... FAIL
|
||||
test_transient_provider_failures_retry_cleanly_with_bounded_backoff (test_neural_audio.GeneratorContract.test_transient_provider_failures_retry_cleanly_with_bounded_backoff) ... ERROR
|
||||
test_wrong_edge_version_fails_before_network_or_asset_changes (test_neural_audio.GeneratorContract.test_wrong_edge_version_fails_before_network_or_asset_changes) ... FAIL
|
||||
test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) ...
|
||||
test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'amplitude': 0}) ... ERROR
|
||||
test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'amplitude': 32767}) ... ERROR
|
||||
test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'rate': 16000}) ... ERROR
|
||||
test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'channels': 2}) ... ERROR
|
||||
test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'width': 1}) ... ERROR
|
||||
test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'duration': 0.2}) ... ERROR
|
||||
test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'duration': 21}) ... ERROR
|
||||
test_valid_pcm_returns_measured_hash_bytes_duration_and_levels (test_neural_audio.PCMContract.test_valid_pcm_returns_measured_hash_bytes_duration_and_levels) ... ERROR
|
||||
|
||||
======================================================================
|
||||
ERROR: test_all_101_are_validated_before_single_atomic_publication (test_neural_audio.GeneratorContract.test_all_101_are_validated_before_single_atomic_publication)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 78, in test_all_101_are_validated_before_single_atomic_publication
|
||||
result = self.run_generate()
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 69, in run_generate
|
||||
return audio.generate(ENTRIES, self.output, synthesize=synthesize or self.synthesize,
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 5, in generate
|
||||
raise NotImplementedError("neural 생성·retry·검증·원자 교체 미구현")
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_atomic_exchange_keeps_old_tree_at_staging_path (test_neural_audio.GeneratorContract.test_atomic_exchange_keeps_old_tree_at_staging_path)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 218, in test_atomic_exchange_keeps_old_tree_at_staging_path
|
||||
audio.atomic_publish(staged, self.output)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 13, in atomic_publish
|
||||
raise NotImplementedError("원자 디렉터리 교체 미구현")
|
||||
NotImplementedError: 원자 디렉터리 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_atomic_first_publication (test_neural_audio.GeneratorContract.test_atomic_first_publication)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 227, in test_atomic_first_publication
|
||||
audio.atomic_publish(staged, output)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 13, in atomic_publish
|
||||
raise NotImplementedError("원자 디렉터리 교체 미구현")
|
||||
NotImplementedError: 원자 디렉터리 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_edge_adapter_uses_pinned_python_prosody_timeout_and_no_shell (test_neural_audio.GeneratorContract.test_edge_adapter_uses_pinned_python_prosody_timeout_and_no_shell)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 193, in test_edge_adapter_uses_pinned_python_prosody_timeout_and_no_shell
|
||||
audio.synthesize_edge("한국어 ; $(literal)", path)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 17, in synthesize_edge
|
||||
raise NotImplementedError("pinned edge-tts 실행 미구현")
|
||||
NotImplementedError: pinned edge-tts 실행 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_ffmpeg_adapter_actually_decodes_mp3_to_normalized_pcm24 (test_neural_audio.GeneratorContract.test_ffmpeg_adapter_actually_decodes_mp3_to_normalized_pcm24)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 206, in test_ffmpeg_adapter_actually_decodes_mp3_to_normalized_pcm24
|
||||
audio.convert_mp3(mp3, output)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 21, in convert_mp3
|
||||
raise NotImplementedError("ffmpeg 변환 및 선형 레벨 보정 미구현")
|
||||
NotImplementedError: ffmpeg 변환 및 선형 레벨 보정 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_full_validation_detects_changed_earlier_file_before_publication (test_neural_audio.GeneratorContract.test_full_validation_detects_changed_earlier_file_before_publication)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 164, in test_full_validation_detects_changed_earlier_file_before_publication
|
||||
self.run_generate(convert=tamper)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 69, in run_generate
|
||||
return audio.generate(ENTRIES, self.output, synthesize=synthesize or self.synthesize,
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 5, in generate
|
||||
raise NotImplementedError("neural 생성·retry·검증·원자 교체 미구현")
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_interruption_preserves_existing_files_and_cleans_temporary_data (test_neural_audio.GeneratorContract.test_interruption_preserves_existing_files_and_cleans_temporary_data)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 149, in test_interruption_preserves_existing_files_and_cleans_temporary_data
|
||||
self.run_generate(synthesize=interrupt)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 69, in run_generate
|
||||
return audio.generate(ENTRIES, self.output, synthesize=synthesize or self.synthesize,
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 5, in generate
|
||||
raise NotImplementedError("neural 생성·retry·검증·원자 교체 미구현")
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_invalid_pcm_never_reaches_publication (test_neural_audio.GeneratorContract.test_invalid_pcm_never_reaches_publication)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 132, in test_invalid_pcm_never_reaches_publication
|
||||
self.run_generate(convert=invalid)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 69, in run_generate
|
||||
return audio.generate(ENTRIES, self.output, synthesize=synthesize or self.synthesize,
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 5, in generate
|
||||
raise NotImplementedError("neural 생성·retry·검증·원자 교체 미구현")
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_publication_failure_preserves_existing_files (test_neural_audio.GeneratorContract.test_publication_failure_preserves_existing_files)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 155, in test_publication_failure_preserves_existing_files
|
||||
self.run_generate()
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 69, in run_generate
|
||||
return audio.generate(ENTRIES, self.output, synthesize=synthesize or self.synthesize,
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 5, in generate
|
||||
raise NotImplementedError("neural 생성·retry·검증·원자 교체 미구현")
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests (test_neural_audio.GeneratorContract.test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests) (entries={'file': 'intro.wav', 'text': '안내 문장'})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 179, in test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests
|
||||
audio.generate(entries, self.output, synthesize=self.synthesize)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 5, in generate
|
||||
raise NotImplementedError("neural 생성·retry·검증·원자 교체 미구현")
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests (test_neural_audio.GeneratorContract.test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests) (entries={'file': 'intro.wav', 'text': '안내 문장'})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 179, in test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests
|
||||
audio.generate(entries, self.output, synthesize=self.synthesize)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 5, in generate
|
||||
raise NotImplementedError("neural 생성·retry·검증·원자 교체 미구현")
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests (test_neural_audio.GeneratorContract.test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests) (entries={'file': '../escape.wav', 'text': '외부'})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 179, in test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests
|
||||
audio.generate(entries, self.output, synthesize=self.synthesize)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 5, in generate
|
||||
raise NotImplementedError("neural 생성·retry·검증·원자 교체 미구현")
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_transient_provider_failures_retry_cleanly_with_bounded_backoff (test_neural_audio.GeneratorContract.test_transient_provider_failures_retry_cleanly_with_bounded_backoff)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 97, in test_transient_provider_failures_retry_cleanly_with_bounded_backoff
|
||||
self.run_generate(synthesize=flaky)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 69, in run_generate
|
||||
return audio.generate(ENTRIES, self.output, synthesize=synthesize or self.synthesize,
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 5, in generate
|
||||
raise NotImplementedError("neural 생성·retry·검증·원자 교체 미구현")
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'amplitude': 0})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 241, in test_rejects_silence_clipping_bad_format_and_abnormal_duration
|
||||
audio.inspect_wav(path)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 9, in inspect_wav
|
||||
raise NotImplementedError("PCM 품질 검사 미구현")
|
||||
NotImplementedError: PCM 품질 검사 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'amplitude': 32767})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 241, in test_rejects_silence_clipping_bad_format_and_abnormal_duration
|
||||
audio.inspect_wav(path)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 9, in inspect_wav
|
||||
raise NotImplementedError("PCM 품질 검사 미구현")
|
||||
NotImplementedError: PCM 품질 검사 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'rate': 16000})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 241, in test_rejects_silence_clipping_bad_format_and_abnormal_duration
|
||||
audio.inspect_wav(path)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 9, in inspect_wav
|
||||
raise NotImplementedError("PCM 품질 검사 미구현")
|
||||
NotImplementedError: PCM 품질 검사 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'channels': 2})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 241, in test_rejects_silence_clipping_bad_format_and_abnormal_duration
|
||||
audio.inspect_wav(path)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 9, in inspect_wav
|
||||
raise NotImplementedError("PCM 품질 검사 미구현")
|
||||
NotImplementedError: PCM 품질 검사 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'width': 1})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 241, in test_rejects_silence_clipping_bad_format_and_abnormal_duration
|
||||
audio.inspect_wav(path)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 9, in inspect_wav
|
||||
raise NotImplementedError("PCM 품질 검사 미구현")
|
||||
NotImplementedError: PCM 품질 검사 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'duration': 0.2})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 241, in test_rejects_silence_clipping_bad_format_and_abnormal_duration
|
||||
audio.inspect_wav(path)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 9, in inspect_wav
|
||||
raise NotImplementedError("PCM 품질 검사 미구현")
|
||||
NotImplementedError: PCM 품질 검사 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) (options={'duration': 21})
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 241, in test_rejects_silence_clipping_bad_format_and_abnormal_duration
|
||||
audio.inspect_wav(path)
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 9, in inspect_wav
|
||||
raise NotImplementedError("PCM 품질 검사 미구현")
|
||||
NotImplementedError: PCM 품질 검사 미구현
|
||||
|
||||
======================================================================
|
||||
ERROR: test_valid_pcm_returns_measured_hash_bytes_duration_and_levels (test_neural_audio.PCMContract.test_valid_pcm_returns_measured_hash_bytes_duration_and_levels)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 247, in test_valid_pcm_returns_measured_hash_bytes_duration_and_levels
|
||||
result = audio.inspect_wav(path)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/neural_audio.py", line 9, in inspect_wav
|
||||
raise NotImplementedError("PCM 품질 검사 미구현")
|
||||
NotImplementedError: PCM 품질 검사 미구현
|
||||
|
||||
======================================================================
|
||||
FAIL: test_cli_import_has_no_generation_or_filesystem_side_effects (test_neural_audio.GeneratorContract.test_cli_import_has_no_generation_or_filesystem_side_effects)
|
||||
----------------------------------------------------------------------
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 188, in test_cli_import_has_no_generation_or_filesystem_side_effects
|
||||
spec.loader.exec_module(module)
|
||||
File "<frozen importlib._bootstrap_external>", line 940, in exec_module
|
||||
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/scripts/generate_audio.py", line 27, in <module>
|
||||
source = subprocess.check_output([
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/.local/share/uv/python/cpython-3.11.16-linux-x86_64-gnu/lib/python3.11/unittest/mock.py", line 1124, in __call__
|
||||
return self._mock_call(*args, **kwargs)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/.local/share/uv/python/cpython-3.11.16-linux-x86_64-gnu/lib/python3.11/unittest/mock.py", line 1128, in _mock_call
|
||||
return self._execute_mock_call(*args, **kwargs)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
File "/home/hermes/.local/share/uv/python/cpython-3.11.16-linux-x86_64-gnu/lib/python3.11/unittest/mock.py", line 1183, in _execute_mock_call
|
||||
raise effect
|
||||
AssertionError: import 실행 금지
|
||||
|
||||
======================================================================
|
||||
FAIL: test_exhausted_provider_failure_preserves_existing_files_and_redacts_secrets (test_neural_audio.GeneratorContract.test_exhausted_provider_failure_preserves_existing_files_and_redacts_secrets)
|
||||
----------------------------------------------------------------------
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
During handling of the above exception, another exception occurred:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 111, in test_exhausted_provider_failure_preserves_existing_files_and_redacts_secrets
|
||||
with self.assertRaisesRegex(RuntimeError, "target-1.wav.*3") as failure:
|
||||
AssertionError: "target-1.wav.*3" does not match "neural 생성·retry·검증·원자 교체 미구현"
|
||||
|
||||
======================================================================
|
||||
FAIL: test_ffmpeg_failure_is_not_retried_and_preserves_existing_files (test_neural_audio.GeneratorContract.test_ffmpeg_failure_is_not_retried_and_preserves_existing_files)
|
||||
----------------------------------------------------------------------
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
During handling of the above exception, another exception occurred:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 138, in test_ffmpeg_failure_is_not_retried_and_preserves_existing_files
|
||||
with self.assertRaisesRegex(RuntimeError, "intro.wav.*변환"):
|
||||
AssertionError: "intro.wav.*변환" does not match "neural 생성·retry·검증·원자 교체 미구현"
|
||||
|
||||
======================================================================
|
||||
FAIL: test_timeout_is_bounded_and_preserves_existing_files (test_neural_audio.GeneratorContract.test_timeout_is_bounded_and_preserves_existing_files)
|
||||
----------------------------------------------------------------------
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
During handling of the above exception, another exception occurred:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 123, in test_timeout_is_bounded_and_preserves_existing_files
|
||||
with self.assertRaisesRegex(RuntimeError, "intro.wav.*3"):
|
||||
AssertionError: "intro.wav.*3" does not match "neural 생성·retry·검증·원자 교체 미구현"
|
||||
|
||||
======================================================================
|
||||
FAIL: test_wrong_edge_version_fails_before_network_or_asset_changes (test_neural_audio.GeneratorContract.test_wrong_edge_version_fails_before_network_or_asset_changes)
|
||||
----------------------------------------------------------------------
|
||||
NotImplementedError: neural 생성·retry·검증·원자 교체 미구현
|
||||
|
||||
During handling of the above exception, another exception occurred:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "/home/hermes/worktrees/find-word-v0.1.1/tests/python/test_neural_audio.py", line 169, in test_wrong_edge_version_fails_before_network_or_asset_changes
|
||||
with self.assertRaisesRegex(RuntimeError, "7.3.1"):
|
||||
AssertionError: "7.3.1" does not match "neural 생성·retry·검증·원자 교체 미구현"
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 18 tests in 0.488s
|
||||
|
||||
FAILED (failures=5, errors=21)
|
||||
@@ -0,0 +1,432 @@
|
||||
test_all_101_are_validated_before_single_atomic_publication (test_neural_audio.GeneratorContract.test_all_101_are_validated_before_single_atomic_publication) ... [001/101] intro.wav 1.000s
|
||||
[002/101] target-0.wav 1.000s
|
||||
[003/101] target-1.wav 1.000s
|
||||
[004/101] target-2.wav 1.000s
|
||||
[005/101] target-3.wav 1.000s
|
||||
[006/101] target-4.wav 1.000s
|
||||
[007/101] target-5.wav 1.000s
|
||||
[008/101] target-6.wav 1.000s
|
||||
[009/101] target-7.wav 1.000s
|
||||
[010/101] target-8.wav 1.000s
|
||||
[011/101] target-9.wav 1.000s
|
||||
[012/101] target-10.wav 1.000s
|
||||
[013/101] target-11.wav 1.000s
|
||||
[014/101] target-12.wav 1.000s
|
||||
[015/101] target-13.wav 1.000s
|
||||
[016/101] target-14.wav 1.000s
|
||||
[017/101] target-15.wav 1.000s
|
||||
[018/101] target-16.wav 1.000s
|
||||
[019/101] target-17.wav 1.000s
|
||||
[020/101] target-18.wav 1.000s
|
||||
[021/101] target-19.wav 1.000s
|
||||
[022/101] target-20.wav 1.000s
|
||||
[023/101] target-21.wav 1.000s
|
||||
[024/101] target-22.wav 1.000s
|
||||
[025/101] target-23.wav 1.000s
|
||||
[026/101] target-24.wav 1.000s
|
||||
[027/101] target-25.wav 1.000s
|
||||
[028/101] target-26.wav 1.000s
|
||||
[029/101] target-27.wav 1.000s
|
||||
[030/101] target-28.wav 1.000s
|
||||
[031/101] target-29.wav 1.000s
|
||||
[032/101] target-30.wav 1.000s
|
||||
[033/101] target-31.wav 1.000s
|
||||
[034/101] target-32.wav 1.000s
|
||||
[035/101] target-33.wav 1.000s
|
||||
[036/101] target-34.wav 1.000s
|
||||
[037/101] target-35.wav 1.000s
|
||||
[038/101] target-36.wav 1.000s
|
||||
[039/101] target-37.wav 1.000s
|
||||
[040/101] target-38.wav 1.000s
|
||||
[041/101] target-39.wav 1.000s
|
||||
[042/101] target-40.wav 1.000s
|
||||
[043/101] target-41.wav 1.000s
|
||||
[044/101] target-42.wav 1.000s
|
||||
[045/101] target-43.wav 1.000s
|
||||
[046/101] target-44.wav 1.000s
|
||||
[047/101] target-45.wav 1.000s
|
||||
[048/101] target-46.wav 1.000s
|
||||
[049/101] target-47.wav 1.000s
|
||||
[050/101] target-48.wav 1.000s
|
||||
[051/101] target-49.wav 1.000s
|
||||
[052/101] target-50.wav 1.000s
|
||||
[053/101] target-51.wav 1.000s
|
||||
[054/101] target-52.wav 1.000s
|
||||
[055/101] target-53.wav 1.000s
|
||||
[056/101] target-54.wav 1.000s
|
||||
[057/101] target-55.wav 1.000s
|
||||
[058/101] target-56.wav 1.000s
|
||||
[059/101] target-57.wav 1.000s
|
||||
[060/101] target-58.wav 1.000s
|
||||
[061/101] target-59.wav 1.000s
|
||||
[062/101] target-60.wav 1.000s
|
||||
[063/101] target-61.wav 1.000s
|
||||
[064/101] target-62.wav 1.000s
|
||||
[065/101] target-63.wav 1.000s
|
||||
[066/101] target-64.wav 1.000s
|
||||
[067/101] target-65.wav 1.000s
|
||||
[068/101] target-66.wav 1.000s
|
||||
[069/101] target-67.wav 1.000s
|
||||
[070/101] target-68.wav 1.000s
|
||||
[071/101] target-69.wav 1.000s
|
||||
[072/101] target-70.wav 1.000s
|
||||
[073/101] target-71.wav 1.000s
|
||||
[074/101] target-72.wav 1.000s
|
||||
[075/101] target-73.wav 1.000s
|
||||
[076/101] target-74.wav 1.000s
|
||||
[077/101] target-75.wav 1.000s
|
||||
[078/101] target-76.wav 1.000s
|
||||
[079/101] target-77.wav 1.000s
|
||||
[080/101] target-78.wav 1.000s
|
||||
[081/101] target-79.wav 1.000s
|
||||
[082/101] target-80.wav 1.000s
|
||||
[083/101] target-81.wav 1.000s
|
||||
[084/101] target-82.wav 1.000s
|
||||
[085/101] target-83.wav 1.000s
|
||||
[086/101] target-84.wav 1.000s
|
||||
[087/101] target-85.wav 1.000s
|
||||
[088/101] target-86.wav 1.000s
|
||||
[089/101] target-87.wav 1.000s
|
||||
[090/101] target-88.wav 1.000s
|
||||
[091/101] target-89.wav 1.000s
|
||||
[092/101] target-90.wav 1.000s
|
||||
[093/101] target-91.wav 1.000s
|
||||
[094/101] target-92.wav 1.000s
|
||||
[095/101] target-93.wav 1.000s
|
||||
[096/101] target-94.wav 1.000s
|
||||
[097/101] target-95.wav 1.000s
|
||||
[098/101] target-96.wav 1.000s
|
||||
[099/101] target-97.wav 1.000s
|
||||
[100/101] target-98.wav 1.000s
|
||||
[101/101] target-99.wav 1.000s
|
||||
ok
|
||||
test_atomic_exchange_keeps_old_tree_at_staging_path (test_neural_audio.GeneratorContract.test_atomic_exchange_keeps_old_tree_at_staging_path) ... ok
|
||||
test_atomic_first_publication (test_neural_audio.GeneratorContract.test_atomic_first_publication) ... ok
|
||||
test_cli_import_has_no_generation_or_filesystem_side_effects (test_neural_audio.GeneratorContract.test_cli_import_has_no_generation_or_filesystem_side_effects) ... ok
|
||||
test_edge_adapter_uses_pinned_python_prosody_timeout_and_no_shell (test_neural_audio.GeneratorContract.test_edge_adapter_uses_pinned_python_prosody_timeout_and_no_shell) ... ok
|
||||
test_exhausted_provider_failure_preserves_existing_files_and_redacts_secrets (test_neural_audio.GeneratorContract.test_exhausted_provider_failure_preserves_existing_files_and_redacts_secrets) ... ok
|
||||
test_ffmpeg_adapter_actually_decodes_mp3_to_normalized_pcm24 (test_neural_audio.GeneratorContract.test_ffmpeg_adapter_actually_decodes_mp3_to_normalized_pcm24) ... ok
|
||||
test_ffmpeg_failure_is_not_retried_and_preserves_existing_files (test_neural_audio.GeneratorContract.test_ffmpeg_failure_is_not_retried_and_preserves_existing_files) ... ok
|
||||
test_full_validation_detects_changed_earlier_file_before_publication (test_neural_audio.GeneratorContract.test_full_validation_detects_changed_earlier_file_before_publication) ... [001/101] intro.wav 1.000s
|
||||
[002/101] target-0.wav 1.000s
|
||||
[003/101] target-1.wav 1.000s
|
||||
[004/101] target-2.wav 1.000s
|
||||
[005/101] target-3.wav 1.000s
|
||||
[006/101] target-4.wav 1.000s
|
||||
[007/101] target-5.wav 1.000s
|
||||
[008/101] target-6.wav 1.000s
|
||||
[009/101] target-7.wav 1.000s
|
||||
[010/101] target-8.wav 1.000s
|
||||
[011/101] target-9.wav 1.000s
|
||||
[012/101] target-10.wav 1.000s
|
||||
[013/101] target-11.wav 1.000s
|
||||
[014/101] target-12.wav 1.000s
|
||||
[015/101] target-13.wav 1.000s
|
||||
[016/101] target-14.wav 1.000s
|
||||
[017/101] target-15.wav 1.000s
|
||||
[018/101] target-16.wav 1.000s
|
||||
[019/101] target-17.wav 1.000s
|
||||
[020/101] target-18.wav 1.000s
|
||||
[021/101] target-19.wav 1.000s
|
||||
[022/101] target-20.wav 1.000s
|
||||
[023/101] target-21.wav 1.000s
|
||||
[024/101] target-22.wav 1.000s
|
||||
[025/101] target-23.wav 1.000s
|
||||
[026/101] target-24.wav 1.000s
|
||||
[027/101] target-25.wav 1.000s
|
||||
[028/101] target-26.wav 1.000s
|
||||
[029/101] target-27.wav 1.000s
|
||||
[030/101] target-28.wav 1.000s
|
||||
[031/101] target-29.wav 1.000s
|
||||
[032/101] target-30.wav 1.000s
|
||||
[033/101] target-31.wav 1.000s
|
||||
[034/101] target-32.wav 1.000s
|
||||
[035/101] target-33.wav 1.000s
|
||||
[036/101] target-34.wav 1.000s
|
||||
[037/101] target-35.wav 1.000s
|
||||
[038/101] target-36.wav 1.000s
|
||||
[039/101] target-37.wav 1.000s
|
||||
[040/101] target-38.wav 1.000s
|
||||
[041/101] target-39.wav 1.000s
|
||||
[042/101] target-40.wav 1.000s
|
||||
[043/101] target-41.wav 1.000s
|
||||
[044/101] target-42.wav 1.000s
|
||||
[045/101] target-43.wav 1.000s
|
||||
[046/101] target-44.wav 1.000s
|
||||
[047/101] target-45.wav 1.000s
|
||||
[048/101] target-46.wav 1.000s
|
||||
[049/101] target-47.wav 1.000s
|
||||
[050/101] target-48.wav 1.000s
|
||||
[051/101] target-49.wav 1.000s
|
||||
[052/101] target-50.wav 1.000s
|
||||
[053/101] target-51.wav 1.000s
|
||||
[054/101] target-52.wav 1.000s
|
||||
[055/101] target-53.wav 1.000s
|
||||
[056/101] target-54.wav 1.000s
|
||||
[057/101] target-55.wav 1.000s
|
||||
[058/101] target-56.wav 1.000s
|
||||
[059/101] target-57.wav 1.000s
|
||||
[060/101] target-58.wav 1.000s
|
||||
[061/101] target-59.wav 1.000s
|
||||
[062/101] target-60.wav 1.000s
|
||||
[063/101] target-61.wav 1.000s
|
||||
[064/101] target-62.wav 1.000s
|
||||
[065/101] target-63.wav 1.000s
|
||||
[066/101] target-64.wav 1.000s
|
||||
[067/101] target-65.wav 1.000s
|
||||
[068/101] target-66.wav 1.000s
|
||||
[069/101] target-67.wav 1.000s
|
||||
[070/101] target-68.wav 1.000s
|
||||
[071/101] target-69.wav 1.000s
|
||||
[072/101] target-70.wav 1.000s
|
||||
[073/101] target-71.wav 1.000s
|
||||
[074/101] target-72.wav 1.000s
|
||||
[075/101] target-73.wav 1.000s
|
||||
[076/101] target-74.wav 1.000s
|
||||
[077/101] target-75.wav 1.000s
|
||||
[078/101] target-76.wav 1.000s
|
||||
[079/101] target-77.wav 1.000s
|
||||
[080/101] target-78.wav 1.000s
|
||||
[081/101] target-79.wav 1.000s
|
||||
[082/101] target-80.wav 1.000s
|
||||
[083/101] target-81.wav 1.000s
|
||||
[084/101] target-82.wav 1.000s
|
||||
[085/101] target-83.wav 1.000s
|
||||
[086/101] target-84.wav 1.000s
|
||||
[087/101] target-85.wav 1.000s
|
||||
[088/101] target-86.wav 1.000s
|
||||
[089/101] target-87.wav 1.000s
|
||||
[090/101] target-88.wav 1.000s
|
||||
[091/101] target-89.wav 1.000s
|
||||
[092/101] target-90.wav 1.000s
|
||||
[093/101] target-91.wav 1.000s
|
||||
[094/101] target-92.wav 1.000s
|
||||
[095/101] target-93.wav 1.000s
|
||||
[096/101] target-94.wav 1.000s
|
||||
[097/101] target-95.wav 1.000s
|
||||
[098/101] target-96.wav 1.000s
|
||||
[099/101] target-97.wav 1.000s
|
||||
[100/101] target-98.wav 1.000s
|
||||
[101/101] target-99.wav 1.000s
|
||||
ok
|
||||
test_interruption_preserves_existing_files_and_cleans_temporary_data (test_neural_audio.GeneratorContract.test_interruption_preserves_existing_files_and_cleans_temporary_data) ... ok
|
||||
test_invalid_pcm_never_reaches_publication (test_neural_audio.GeneratorContract.test_invalid_pcm_never_reaches_publication) ... ok
|
||||
test_publication_failure_preserves_existing_files (test_neural_audio.GeneratorContract.test_publication_failure_preserves_existing_files) ... [001/101] intro.wav 1.000s
|
||||
[002/101] target-0.wav 1.000s
|
||||
[003/101] target-1.wav 1.000s
|
||||
[004/101] target-2.wav 1.000s
|
||||
[005/101] target-3.wav 1.000s
|
||||
[006/101] target-4.wav 1.000s
|
||||
[007/101] target-5.wav 1.000s
|
||||
[008/101] target-6.wav 1.000s
|
||||
[009/101] target-7.wav 1.000s
|
||||
[010/101] target-8.wav 1.000s
|
||||
[011/101] target-9.wav 1.000s
|
||||
[012/101] target-10.wav 1.000s
|
||||
[013/101] target-11.wav 1.000s
|
||||
[014/101] target-12.wav 1.000s
|
||||
[015/101] target-13.wav 1.000s
|
||||
[016/101] target-14.wav 1.000s
|
||||
[017/101] target-15.wav 1.000s
|
||||
[018/101] target-16.wav 1.000s
|
||||
[019/101] target-17.wav 1.000s
|
||||
[020/101] target-18.wav 1.000s
|
||||
[021/101] target-19.wav 1.000s
|
||||
[022/101] target-20.wav 1.000s
|
||||
[023/101] target-21.wav 1.000s
|
||||
[024/101] target-22.wav 1.000s
|
||||
[025/101] target-23.wav 1.000s
|
||||
[026/101] target-24.wav 1.000s
|
||||
[027/101] target-25.wav 1.000s
|
||||
[028/101] target-26.wav 1.000s
|
||||
[029/101] target-27.wav 1.000s
|
||||
[030/101] target-28.wav 1.000s
|
||||
[031/101] target-29.wav 1.000s
|
||||
[032/101] target-30.wav 1.000s
|
||||
[033/101] target-31.wav 1.000s
|
||||
[034/101] target-32.wav 1.000s
|
||||
[035/101] target-33.wav 1.000s
|
||||
[036/101] target-34.wav 1.000s
|
||||
[037/101] target-35.wav 1.000s
|
||||
[038/101] target-36.wav 1.000s
|
||||
[039/101] target-37.wav 1.000s
|
||||
[040/101] target-38.wav 1.000s
|
||||
[041/101] target-39.wav 1.000s
|
||||
[042/101] target-40.wav 1.000s
|
||||
[043/101] target-41.wav 1.000s
|
||||
[044/101] target-42.wav 1.000s
|
||||
[045/101] target-43.wav 1.000s
|
||||
[046/101] target-44.wav 1.000s
|
||||
[047/101] target-45.wav 1.000s
|
||||
[048/101] target-46.wav 1.000s
|
||||
[049/101] target-47.wav 1.000s
|
||||
[050/101] target-48.wav 1.000s
|
||||
[051/101] target-49.wav 1.000s
|
||||
[052/101] target-50.wav 1.000s
|
||||
[053/101] target-51.wav 1.000s
|
||||
[054/101] target-52.wav 1.000s
|
||||
[055/101] target-53.wav 1.000s
|
||||
[056/101] target-54.wav 1.000s
|
||||
[057/101] target-55.wav 1.000s
|
||||
[058/101] target-56.wav 1.000s
|
||||
[059/101] target-57.wav 1.000s
|
||||
[060/101] target-58.wav 1.000s
|
||||
[061/101] target-59.wav 1.000s
|
||||
[062/101] target-60.wav 1.000s
|
||||
[063/101] target-61.wav 1.000s
|
||||
[064/101] target-62.wav 1.000s
|
||||
[065/101] target-63.wav 1.000s
|
||||
[066/101] target-64.wav 1.000s
|
||||
[067/101] target-65.wav 1.000s
|
||||
[068/101] target-66.wav 1.000s
|
||||
[069/101] target-67.wav 1.000s
|
||||
[070/101] target-68.wav 1.000s
|
||||
[071/101] target-69.wav 1.000s
|
||||
[072/101] target-70.wav 1.000s
|
||||
[073/101] target-71.wav 1.000s
|
||||
[074/101] target-72.wav 1.000s
|
||||
[075/101] target-73.wav 1.000s
|
||||
[076/101] target-74.wav 1.000s
|
||||
[077/101] target-75.wav 1.000s
|
||||
[078/101] target-76.wav 1.000s
|
||||
[079/101] target-77.wav 1.000s
|
||||
[080/101] target-78.wav 1.000s
|
||||
[081/101] target-79.wav 1.000s
|
||||
[082/101] target-80.wav 1.000s
|
||||
[083/101] target-81.wav 1.000s
|
||||
[084/101] target-82.wav 1.000s
|
||||
[085/101] target-83.wav 1.000s
|
||||
[086/101] target-84.wav 1.000s
|
||||
[087/101] target-85.wav 1.000s
|
||||
[088/101] target-86.wav 1.000s
|
||||
[089/101] target-87.wav 1.000s
|
||||
[090/101] target-88.wav 1.000s
|
||||
[091/101] target-89.wav 1.000s
|
||||
[092/101] target-90.wav 1.000s
|
||||
[093/101] target-91.wav 1.000s
|
||||
[094/101] target-92.wav 1.000s
|
||||
[095/101] target-93.wav 1.000s
|
||||
[096/101] target-94.wav 1.000s
|
||||
[097/101] target-95.wav 1.000s
|
||||
[098/101] target-96.wav 1.000s
|
||||
[099/101] target-97.wav 1.000s
|
||||
[100/101] target-98.wav 1.000s
|
||||
[101/101] target-99.wav 1.000s
|
||||
ok
|
||||
test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests (test_neural_audio.GeneratorContract.test_rejects_incomplete_or_duplicate_or_unsafe_inventory_before_requests) ... ok
|
||||
test_timeout_is_bounded_and_preserves_existing_files (test_neural_audio.GeneratorContract.test_timeout_is_bounded_and_preserves_existing_files) ... intro.wav: provider 시도 1/3 실패
|
||||
intro.wav: provider 시도 2/3 실패
|
||||
intro.wav: provider 시도 3/3 실패
|
||||
ok
|
||||
test_transient_provider_failures_retry_cleanly_with_bounded_backoff (test_neural_audio.GeneratorContract.test_transient_provider_failures_retry_cleanly_with_bounded_backoff) ... intro.wav: provider 시도 1/3 실패
|
||||
intro.wav: provider 시도 2/3 실패
|
||||
[001/101] intro.wav 1.000s
|
||||
[002/101] target-0.wav 1.000s
|
||||
[003/101] target-1.wav 1.000s
|
||||
[004/101] target-2.wav 1.000s
|
||||
[005/101] target-3.wav 1.000s
|
||||
[006/101] target-4.wav 1.000s
|
||||
[007/101] target-5.wav 1.000s
|
||||
[008/101] target-6.wav 1.000s
|
||||
[009/101] target-7.wav 1.000s
|
||||
[010/101] target-8.wav 1.000s
|
||||
[011/101] target-9.wav 1.000s
|
||||
[012/101] target-10.wav 1.000s
|
||||
[013/101] target-11.wav 1.000s
|
||||
[014/101] target-12.wav 1.000s
|
||||
[015/101] target-13.wav 1.000s
|
||||
[016/101] target-14.wav 1.000s
|
||||
[017/101] target-15.wav 1.000s
|
||||
[018/101] target-16.wav 1.000s
|
||||
[019/101] target-17.wav 1.000s
|
||||
[020/101] target-18.wav 1.000s
|
||||
[021/101] target-19.wav 1.000s
|
||||
[022/101] target-20.wav 1.000s
|
||||
[023/101] target-21.wav 1.000s
|
||||
[024/101] target-22.wav 1.000s
|
||||
[025/101] target-23.wav 1.000s
|
||||
[026/101] target-24.wav 1.000s
|
||||
[027/101] target-25.wav 1.000s
|
||||
[028/101] target-26.wav 1.000s
|
||||
[029/101] target-27.wav 1.000s
|
||||
[030/101] target-28.wav 1.000s
|
||||
[031/101] target-29.wav 1.000s
|
||||
[032/101] target-30.wav 1.000s
|
||||
[033/101] target-31.wav 1.000s
|
||||
[034/101] target-32.wav 1.000s
|
||||
[035/101] target-33.wav 1.000s
|
||||
[036/101] target-34.wav 1.000s
|
||||
[037/101] target-35.wav 1.000s
|
||||
[038/101] target-36.wav 1.000s
|
||||
[039/101] target-37.wav 1.000s
|
||||
[040/101] target-38.wav 1.000s
|
||||
[041/101] target-39.wav 1.000s
|
||||
[042/101] target-40.wav 1.000s
|
||||
[043/101] target-41.wav 1.000s
|
||||
[044/101] target-42.wav 1.000s
|
||||
[045/101] target-43.wav 1.000s
|
||||
[046/101] target-44.wav 1.000s
|
||||
[047/101] target-45.wav 1.000s
|
||||
[048/101] target-46.wav 1.000s
|
||||
[049/101] target-47.wav 1.000s
|
||||
[050/101] target-48.wav 1.000s
|
||||
[051/101] target-49.wav 1.000s
|
||||
[052/101] target-50.wav 1.000s
|
||||
[053/101] target-51.wav 1.000s
|
||||
[054/101] target-52.wav 1.000s
|
||||
[055/101] target-53.wav 1.000s
|
||||
[056/101] target-54.wav 1.000s
|
||||
[057/101] target-55.wav 1.000s
|
||||
[058/101] target-56.wav 1.000s
|
||||
[059/101] target-57.wav 1.000s
|
||||
[060/101] target-58.wav 1.000s
|
||||
[061/101] target-59.wav 1.000s
|
||||
[062/101] target-60.wav 1.000s
|
||||
[063/101] target-61.wav 1.000s
|
||||
[064/101] target-62.wav 1.000s
|
||||
[065/101] target-63.wav 1.000s
|
||||
[066/101] target-64.wav 1.000s
|
||||
[067/101] target-65.wav 1.000s
|
||||
[068/101] target-66.wav 1.000s
|
||||
[069/101] target-67.wav 1.000s
|
||||
[070/101] target-68.wav 1.000s
|
||||
[071/101] target-69.wav 1.000s
|
||||
[072/101] target-70.wav 1.000s
|
||||
[073/101] target-71.wav 1.000s
|
||||
[074/101] target-72.wav 1.000s
|
||||
[075/101] target-73.wav 1.000s
|
||||
[076/101] target-74.wav 1.000s
|
||||
[077/101] target-75.wav 1.000s
|
||||
[078/101] target-76.wav 1.000s
|
||||
[079/101] target-77.wav 1.000s
|
||||
[080/101] target-78.wav 1.000s
|
||||
[081/101] target-79.wav 1.000s
|
||||
[082/101] target-80.wav 1.000s
|
||||
[083/101] target-81.wav 1.000s
|
||||
[084/101] target-82.wav 1.000s
|
||||
[085/101] target-83.wav 1.000s
|
||||
[086/101] target-84.wav 1.000s
|
||||
[087/101] target-85.wav 1.000s
|
||||
[088/101] target-86.wav 1.000s
|
||||
[089/101] target-87.wav 1.000s
|
||||
[090/101] target-88.wav 1.000s
|
||||
[091/101] target-89.wav 1.000s
|
||||
[092/101] target-90.wav 1.000s
|
||||
[093/101] target-91.wav 1.000s
|
||||
[094/101] target-92.wav 1.000s
|
||||
[095/101] target-93.wav 1.000s
|
||||
[096/101] target-94.wav 1.000s
|
||||
[097/101] target-95.wav 1.000s
|
||||
[098/101] target-96.wav 1.000s
|
||||
[099/101] target-97.wav 1.000s
|
||||
[100/101] target-98.wav 1.000s
|
||||
[101/101] target-99.wav 1.000s
|
||||
ok
|
||||
test_wrong_edge_version_fails_before_network_or_asset_changes (test_neural_audio.GeneratorContract.test_wrong_edge_version_fails_before_network_or_asset_changes) ... ok
|
||||
test_rejects_silence_clipping_bad_format_and_abnormal_duration (test_neural_audio.PCMContract.test_rejects_silence_clipping_bad_format_and_abnormal_duration) ... ok
|
||||
test_valid_pcm_returns_measured_hash_bytes_duration_and_levels (test_neural_audio.PCMContract.test_valid_pcm_returns_measured_hash_bytes_duration_and_levels) ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 18 tests in 2.699s
|
||||
|
||||
OK
|
||||
@@ -0,0 +1,106 @@
|
||||
|
||||
> find-word@0.1.1 audio:generate
|
||||
> .venv-audio/bin/python scripts/generate_audio.py
|
||||
|
||||
[001/101] intro.wav 7.056s
|
||||
[002/101] luck-apple.wav 3.936s
|
||||
[003/101] luck-sea.wav 3.984s
|
||||
[004/101] luck-tree.wav 3.816s
|
||||
[005/101] luck-hat.wav 3.984s
|
||||
[006/101] luck-umbrella.wav 4.008s
|
||||
[007/101] luck-market.wav 4.056s
|
||||
[008/101] luck-oil.wav 3.960s
|
||||
[009/101] luck-sound.wav 3.840s
|
||||
[010/101] luck-meat.wav 3.912s
|
||||
[011/101] luck-furniture.wav 3.888s
|
||||
[012/101] password-apple.wav 4.896s
|
||||
[013/101] password-sea.wav 4.848s
|
||||
[014/101] password-tree.wav 4.872s
|
||||
[015/101] password-hat.wav 4.896s
|
||||
[016/101] password-umbrella.wav 4.992s
|
||||
[017/101] password-market.wav 4.800s
|
||||
[018/101] password-oil.wav 5.016s
|
||||
[019/101] password-sound.wav 4.920s
|
||||
[020/101] password-meat.wav 5.016s
|
||||
[021/101] password-furniture.wav 4.872s
|
||||
[022/101] remember-apple.wav 8.232s
|
||||
[023/101] remember-sea.wav 8.328s
|
||||
[024/101] remember-tree.wav 8.520s
|
||||
[025/101] remember-hat.wav 8.376s
|
||||
[026/101] remember-umbrella.wav 8.400s
|
||||
[027/101] remember-market.wav 8.304s
|
||||
[028/101] remember-oil.wav 8.328s
|
||||
[029/101] remember-sound.wav 8.208s
|
||||
[030/101] remember-meat.wav 8.232s
|
||||
[031/101] remember-furniture.wav 8.400s
|
||||
[032/101] last-apple.wav 7.416s
|
||||
[033/101] last-sea.wav 7.200s
|
||||
[034/101] last-tree.wav 7.968s
|
||||
[035/101] last-hat.wav 7.392s
|
||||
[036/101] last-umbrella.wav 7.728s
|
||||
[037/101] last-market.wav 7.488s
|
||||
[038/101] last-oil.wav 7.032s
|
||||
[039/101] last-sound.wav 7.392s
|
||||
[040/101] last-meat.wav 7.224s
|
||||
[041/101] last-furniture.wav 7.440s
|
||||
[042/101] first-apple.wav 7.488s
|
||||
[043/101] first-sea.wav 7.272s
|
||||
[044/101] first-tree.wav 7.896s
|
||||
[045/101] first-hat.wav 7.440s
|
||||
[046/101] first-umbrella.wav 7.632s
|
||||
[047/101] first-market.wav 7.488s
|
||||
[048/101] first-oil.wav 6.984s
|
||||
[049/101] first-sound.wav 7.368s
|
||||
[050/101] first-meat.wav 7.200s
|
||||
[051/101] first-furniture.wav 7.584s
|
||||
[052/101] repeat-apple.wav 8.280s
|
||||
[053/101] repeat-sea.wav 7.968s
|
||||
[054/101] repeat-tree.wav 8.832s
|
||||
[055/101] repeat-hat.wav 8.256s
|
||||
[056/101] repeat-umbrella.wav 8.544s
|
||||
[057/101] repeat-market.wav 8.376s
|
||||
[058/101] repeat-oil.wav 7.704s
|
||||
[059/101] repeat-sound.wav 8.232s
|
||||
[060/101] repeat-meat.wav 7.920s
|
||||
[061/101] repeat-furniture.wav 8.280s
|
||||
[062/101] correction-apple.wav 8.376s
|
||||
[063/101] correction-sea.wav 8.304s
|
||||
[064/101] correction-tree.wav 8.352s
|
||||
[065/101] correction-hat.wav 8.304s
|
||||
[066/101] correction-umbrella.wav 8.472s
|
||||
[067/101] correction-market.wav 8.448s
|
||||
[068/101] correction-oil.wav 8.472s
|
||||
[069/101] correction-sound.wav 8.280s
|
||||
[070/101] correction-meat.wav 8.400s
|
||||
[071/101] correction-furniture.wav 8.304s
|
||||
[072/101] middle-apple.wav 7.512s
|
||||
[073/101] middle-sea.wav 7.224s
|
||||
[074/101] middle-tree.wav 7.968s
|
||||
[075/101] middle-hat.wav 7.368s
|
||||
[076/101] middle-umbrella.wav 7.680s
|
||||
[077/101] middle-market.wav 7.416s
|
||||
[078/101] middle-oil.wav 6.960s
|
||||
[079/101] middle-sound.wav 7.368s
|
||||
[080/101] middle-meat.wav 7.128s
|
||||
[081/101] middle-furniture.wav 7.392s
|
||||
[082/101] message-apple.wav 10.776s
|
||||
[083/101] message-sea.wav 10.776s
|
||||
[084/101] message-tree.wav 11.256s
|
||||
[085/101] message-hat.wav 10.800s
|
||||
[086/101] message-umbrella.wav 10.896s
|
||||
[087/101] message-market.wav 10.896s
|
||||
[088/101] message-oil.wav 10.608s
|
||||
[089/101] message-sound.wav 10.872s
|
||||
[090/101] message-meat.wav 10.680s
|
||||
[091/101] message-furniture.wav 10.872s
|
||||
[092/101] mission-apple.wav 5.136s
|
||||
[093/101] mission-sea.wav 5.064s
|
||||
[094/101] mission-tree.wav 5.040s
|
||||
[095/101] mission-hat.wav 5.112s
|
||||
[096/101] mission-umbrella.wav 5.160s
|
||||
[097/101] mission-market.wav 5.184s
|
||||
[098/101] mission-oil.wav 5.040s
|
||||
[099/101] mission-sound.wav 5.016s
|
||||
[100/101] mission-meat.wav 5.088s
|
||||
[101/101] mission-furniture.wav 5.040s
|
||||
101개 신규 WAV 원자 교체 완료, 합계 34,898,524 바이트
|
||||
@@ -0,0 +1,7 @@
|
||||
tests/assets.test.ts 130ms
|
||||
tests/neural-release.test.ts 12ms
|
||||
tests/generator.test.ts 5ms
|
||||
tests/App.test.tsx 91ms (unchanged)
|
||||
tests/browser/game.spec.ts 30ms
|
||||
tests/browser/ui.spec.ts 19ms
|
||||
eslint.config.js 21ms (unchanged)
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
> find-word@0.1.1 test
|
||||
> vitest run tests/neural-release.test.ts tests/App.test.tsx -t 0.1.1|브랜드|고정 venv
|
||||
|
||||
|
||||
RUN v5.0.4 /home/hermes/worktrees/find-word-v0.1.1
|
||||
|
||||
|
||||
Test Files 2 passed (2)
|
||||
Tests 3 passed | 12 skipped (15)
|
||||
Start at 06:52:28
|
||||
Duration 1.30s (environment 47%, tests 20%, setup 20%, transform 8%, import 4%, worker 1%)
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
> find-word@0.1.1 lint
|
||||
> eslint . && tsc --noEmit
|
||||
@@ -0,0 +1 @@
|
||||
found 0 vulnerabilities
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
> find-word@0.1.1 test
|
||||
> vitest run
|
||||
|
||||
|
||||
RUN v5.0.4 /home/hermes/worktrees/find-word-v0.1.1
|
||||
|
||||
|
||||
Test Files 11 passed (11)
|
||||
Tests 60 passed (60)
|
||||
Start at 06:56:13
|
||||
Duration 13.30s (tests 64%, environment 24%, setup 9%, transform 1%, import 1%, worker 1%)
|
||||
|
||||
Isolate 11 workers spawned · ~999ms startup each (spawn + environment, per file)
|
||||
at least ~2.66s faster with isolate: false — reuses workers across files instead of one per file
|
||||
@@ -0,0 +1,120 @@
|
||||
PASS intro.wav: 7.056s, RMS=0.100000, peak=0.499847
|
||||
PASS luck-apple.wav: 3.936s, RMS=0.100000, peak=0.401642
|
||||
PASS luck-sea.wav: 3.984s, RMS=0.100000, peak=0.388702
|
||||
PASS luck-tree.wav: 3.816s, RMS=0.100000, peak=0.369202
|
||||
PASS luck-hat.wav: 3.984s, RMS=0.100000, peak=0.417084
|
||||
PASS luck-umbrella.wav: 4.008s, RMS=0.100000, peak=0.385651
|
||||
PASS luck-market.wav: 4.056s, RMS=0.100000, peak=0.402222
|
||||
PASS luck-oil.wav: 3.960s, RMS=0.100000, peak=0.381714
|
||||
PASS luck-sound.wav: 3.840s, RMS=0.100000, peak=0.386322
|
||||
PASS luck-meat.wav: 3.912s, RMS=0.100000, peak=0.371124
|
||||
PASS luck-furniture.wav: 3.888s, RMS=0.100000, peak=0.387054
|
||||
PASS password-apple.wav: 4.896s, RMS=0.100000, peak=0.483429
|
||||
PASS password-sea.wav: 4.848s, RMS=0.100000, peak=0.533905
|
||||
PASS password-tree.wav: 4.872s, RMS=0.100000, peak=0.490387
|
||||
PASS password-hat.wav: 4.896s, RMS=0.100000, peak=0.505890
|
||||
PASS password-umbrella.wav: 4.992s, RMS=0.100000, peak=0.477661
|
||||
PASS password-market.wav: 4.800s, RMS=0.100000, peak=0.481689
|
||||
PASS password-oil.wav: 5.016s, RMS=0.100000, peak=0.494507
|
||||
PASS password-sound.wav: 4.920s, RMS=0.100000, peak=0.462097
|
||||
PASS password-meat.wav: 5.016s, RMS=0.100000, peak=0.497864
|
||||
PASS password-furniture.wav: 4.872s, RMS=0.100000, peak=0.483643
|
||||
PASS remember-apple.wav: 8.232s, RMS=0.100000, peak=0.563568
|
||||
PASS remember-sea.wav: 8.328s, RMS=0.100000, peak=0.546539
|
||||
PASS remember-tree.wav: 8.520s, RMS=0.100000, peak=0.548645
|
||||
PASS remember-hat.wav: 8.376s, RMS=0.100000, peak=0.541779
|
||||
PASS remember-umbrella.wav: 8.400s, RMS=0.100000, peak=0.557831
|
||||
PASS remember-market.wav: 8.304s, RMS=0.100000, peak=0.572815
|
||||
PASS remember-oil.wav: 8.328s, RMS=0.100000, peak=0.524384
|
||||
PASS remember-sound.wav: 8.208s, RMS=0.100000, peak=0.537781
|
||||
PASS remember-meat.wav: 8.232s, RMS=0.100000, peak=0.519287
|
||||
PASS remember-furniture.wav: 8.400s, RMS=0.100000, peak=0.561890
|
||||
PASS last-apple.wav: 7.416s, RMS=0.100000, peak=0.622528
|
||||
PASS last-sea.wav: 7.200s, RMS=0.100000, peak=0.591034
|
||||
PASS last-tree.wav: 7.968s, RMS=0.100000, peak=0.580750
|
||||
PASS last-hat.wav: 7.392s, RMS=0.100000, peak=0.550079
|
||||
PASS last-umbrella.wav: 7.728s, RMS=0.100000, peak=0.597656
|
||||
PASS last-market.wav: 7.488s, RMS=0.100000, peak=0.600555
|
||||
PASS last-oil.wav: 7.032s, RMS=0.100000, peak=0.557068
|
||||
PASS last-sound.wav: 7.392s, RMS=0.100000, peak=0.564087
|
||||
PASS last-meat.wav: 7.224s, RMS=0.100000, peak=0.537201
|
||||
PASS last-furniture.wav: 7.440s, RMS=0.100000, peak=0.583588
|
||||
PASS first-apple.wav: 7.488s, RMS=0.100000, peak=0.579773
|
||||
PASS first-sea.wav: 7.272s, RMS=0.100000, peak=0.571777
|
||||
PASS first-tree.wav: 7.896s, RMS=0.100000, peak=0.583344
|
||||
PASS first-hat.wav: 7.440s, RMS=0.100000, peak=0.531250
|
||||
PASS first-umbrella.wav: 7.632s, RMS=0.100000, peak=0.570007
|
||||
PASS first-market.wav: 7.488s, RMS=0.100000, peak=0.639069
|
||||
PASS first-oil.wav: 6.984s, RMS=0.100000, peak=0.534729
|
||||
PASS first-sound.wav: 7.368s, RMS=0.100000, peak=0.518951
|
||||
PASS first-meat.wav: 7.200s, RMS=0.100000, peak=0.513123
|
||||
PASS first-furniture.wav: 7.584s, RMS=0.100000, peak=0.570038
|
||||
PASS repeat-apple.wav: 8.280s, RMS=0.100000, peak=0.641449
|
||||
PASS repeat-sea.wav: 7.968s, RMS=0.100000, peak=0.684326
|
||||
PASS repeat-tree.wav: 8.832s, RMS=0.100000, peak=0.618744
|
||||
PASS repeat-hat.wav: 8.256s, RMS=0.100000, peak=0.616730
|
||||
PASS repeat-umbrella.wav: 8.544s, RMS=0.100000, peak=0.674835
|
||||
PASS repeat-market.wav: 8.376s, RMS=0.100000, peak=0.682251
|
||||
PASS repeat-oil.wav: 7.704s, RMS=0.100000, peak=0.623962
|
||||
PASS repeat-sound.wav: 8.232s, RMS=0.100000, peak=0.611450
|
||||
PASS repeat-meat.wav: 7.920s, RMS=0.100000, peak=0.592102
|
||||
PASS repeat-furniture.wav: 8.280s, RMS=0.100000, peak=0.667023
|
||||
PASS correction-apple.wav: 8.376s, RMS=0.100000, peak=0.490326
|
||||
PASS correction-sea.wav: 8.304s, RMS=0.100000, peak=0.496155
|
||||
PASS correction-tree.wav: 8.352s, RMS=0.100000, peak=0.470612
|
||||
PASS correction-hat.wav: 8.304s, RMS=0.100000, peak=0.470978
|
||||
PASS correction-umbrella.wav: 8.472s, RMS=0.100000, peak=0.479034
|
||||
PASS correction-market.wav: 8.448s, RMS=0.100000, peak=0.491486
|
||||
PASS correction-oil.wav: 8.472s, RMS=0.100000, peak=0.470795
|
||||
PASS correction-sound.wav: 8.280s, RMS=0.100000, peak=0.469269
|
||||
PASS correction-meat.wav: 8.400s, RMS=0.100000, peak=0.481537
|
||||
PASS correction-furniture.wav: 8.304s, RMS=0.100000, peak=0.487396
|
||||
PASS middle-apple.wav: 7.512s, RMS=0.100000, peak=0.553558
|
||||
PASS middle-sea.wav: 7.224s, RMS=0.100000, peak=0.564941
|
||||
PASS middle-tree.wav: 7.968s, RMS=0.100000, peak=0.600006
|
||||
PASS middle-hat.wav: 7.368s, RMS=0.100000, peak=0.555206
|
||||
PASS middle-umbrella.wav: 7.680s, RMS=0.100000, peak=0.569550
|
||||
PASS middle-market.wav: 7.416s, RMS=0.100000, peak=0.594971
|
||||
PASS middle-oil.wav: 6.960s, RMS=0.100000, peak=0.539917
|
||||
PASS middle-sound.wav: 7.368s, RMS=0.100000, peak=0.534821
|
||||
PASS middle-meat.wav: 7.128s, RMS=0.100000, peak=0.510834
|
||||
PASS middle-furniture.wav: 7.392s, RMS=0.100000, peak=0.557617
|
||||
PASS message-apple.wav: 10.776s, RMS=0.100000, peak=0.525360
|
||||
PASS message-sea.wav: 10.776s, RMS=0.100000, peak=0.535217
|
||||
PASS message-tree.wav: 11.256s, RMS=0.100000, peak=0.526245
|
||||
PASS message-hat.wav: 10.800s, RMS=0.100000, peak=0.587006
|
||||
PASS message-umbrella.wav: 10.896s, RMS=0.100000, peak=0.530365
|
||||
PASS message-market.wav: 10.896s, RMS=0.100000, peak=0.534821
|
||||
PASS message-oil.wav: 10.608s, RMS=0.100000, peak=0.518127
|
||||
PASS message-sound.wav: 10.872s, RMS=0.100000, peak=0.519531
|
||||
PASS message-meat.wav: 10.680s, RMS=0.100000, peak=0.514771
|
||||
PASS message-furniture.wav: 10.872s, RMS=0.100000, peak=0.529327
|
||||
PASS mission-apple.wav: 5.136s, RMS=0.100000, peak=0.470154
|
||||
PASS mission-sea.wav: 5.064s, RMS=0.100000, peak=0.450134
|
||||
PASS mission-tree.wav: 5.040s, RMS=0.100000, peak=0.458527
|
||||
PASS mission-hat.wav: 5.112s, RMS=0.100000, peak=0.449829
|
||||
PASS mission-umbrella.wav: 5.160s, RMS=0.100000, peak=0.465332
|
||||
PASS mission-market.wav: 5.184s, RMS=0.100000, peak=0.485687
|
||||
PASS mission-oil.wav: 5.040s, RMS=0.100000, peak=0.443573
|
||||
PASS mission-sound.wav: 5.016s, RMS=0.100000, peak=0.454803
|
||||
PASS mission-meat.wav: 5.088s, RMS=0.100000, peak=0.441864
|
||||
PASS mission-furniture.wav: 5.040s, RMS=0.100000, peak=0.485229
|
||||
{
|
||||
"count": 101,
|
||||
"newVsV01": 101,
|
||||
"uniqueHashes": 101,
|
||||
"bytes": 34898524,
|
||||
"durationRange": [
|
||||
3.816,
|
||||
11.256
|
||||
],
|
||||
"rmsRange": [
|
||||
0.09999985338851038,
|
||||
0.10000004859108667
|
||||
],
|
||||
"peakRange": [
|
||||
0.36920166015625,
|
||||
0.684326171875
|
||||
],
|
||||
"historicalUnchanged": 115
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
> find-word@0.1.1 build
|
||||
> tsc --noEmit && vite build && node scripts/check-build.mjs
|
||||
|
||||
vite v8.3.4 building client environment for production...
|
||||
transforming...
|
||||
✓ 20 modules transformed.
|
||||
rendering chunks...
|
||||
computing gzip size...
|
||||
dist/index.html 0.89 kB │ gzip: 0.63 kB
|
||||
dist/assets/index-KT6VDfPn.css 15.25 kB │ gzip: 4.39 kB
|
||||
dist/assets/index-CorsjeLi.js 245.34 kB │ gzip: 77.26 kB
|
||||
|
||||
✓ built in 405ms
|
||||
빌드 음성 자산 101개 및 런타임 notice 전문 확인
|
||||
@@ -0,0 +1,77 @@
|
||||
|
||||
> find-word@0.1.1 test:browser
|
||||
> playwright test
|
||||
|
||||
[WebServer] (node:789414) Warning: The 'NO_COLOR' env is ignored due to the 'FORCE_COLOR' env being set.
|
||||
[WebServer] (Use `node --trace-warnings ...` to show where the warning was created)
|
||||
|
||||
Running 12 tests using 2 workers
|
||||
|
||||
(node:789465) Warning: The 'NO_COLOR' env is ignored due to the 'FORCE_COLOR' env being set.
|
||||
(Use `node --trace-warnings ...` to show where the warning was created)
|
||||
(node:789464) Warning: The 'NO_COLOR' env is ignored due to the 'FORCE_COLOR' env being set.
|
||||
(Use `node --trace-warnings ...` to show where the warning was created)
|
||||
pw:browser <launching> /usr/bin/google-chrome --disable-field-trial-config --disable-background-networking --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-edgeupdater --disable-extensions --disable-features=AvoidUnnecessaryBeforeUnloadCheckSync,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,BlockOriginHeaderModificationOnRedirect,Translate,AutoDeElevate,OptimizationHints,NetworkTimeServiceQuerying,AimEnabled,msForceBrowserSignIn,msEdgeUpdateLaunchServicesPreferredVersion --enable-features=CDPScreenshotNewSurface --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-updater-scheduler --force-color-profile=srgb --metrics-recording-only --no-first-run --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --disable-search-engine-choice-screen --unsafely-disable-devtools-self-xss-warnings --edge-skip-compat-layer-relaunch --disable-infobars --disable-search-engine-choice-screen --disable-sync --enable-unsafe-swiftshader --headless --hide-scrollbars --mute-audio --blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4 --user-data-dir=/tmp/playwright_chromiumdev_profile-usRFeJ --remote-debugging-pipe --no-startup-window +0ms
|
||||
pw:browser <launching> /usr/bin/google-chrome --disable-field-trial-config --disable-background-networking --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-edgeupdater --disable-extensions --disable-features=AvoidUnnecessaryBeforeUnloadCheckSync,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,BlockOriginHeaderModificationOnRedirect,Translate,AutoDeElevate,OptimizationHints,NetworkTimeServiceQuerying,AimEnabled,msForceBrowserSignIn,msEdgeUpdateLaunchServicesPreferredVersion --enable-features=CDPScreenshotNewSurface --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-updater-scheduler --force-color-profile=srgb --metrics-recording-only --no-first-run --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --disable-search-engine-choice-screen --unsafely-disable-devtools-self-xss-warnings --edge-skip-compat-layer-relaunch --disable-infobars --disable-search-engine-choice-screen --disable-sync --enable-unsafe-swiftshader --headless --hide-scrollbars --mute-audio --blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4 --user-data-dir=/tmp/playwright_chromiumdev_profile-tgmIGX --remote-debugging-pipe --no-startup-window +0ms
|
||||
pw:browser <launched> pid=789488 +15ms
|
||||
pw:browser <launched> pid=789490 +14ms
|
||||
pw:browser [pid=789488][err] [789574:789574:1014/065656.619803:ERROR:base/memory/shared_memory_switch.cc:289] Failed global descriptor lookup: 7 +253ms
|
||||
pw:browser [pid=789490][err] [789572:789572:1014/065656.641388:ERROR:base/memory/shared_memory_switch.cc:289] Failed global descriptor lookup: 7 +270ms
|
||||
pw:browser [pid=789488][err] [789657:7:1014/065657.003307:ERROR:gpu/ipc/client/command_buffer_proxy_impl.cc:287] ContextResult::kTransientFailure: Failed to send GpuControl.CreateCommandBuffer. +394ms
|
||||
pw:browser [pid=789490][err] [789697:789697:1014/065657.581581:ERROR:base/memory/shared_memory_switch.cc:289] Failed global descriptor lookup: 7 +937ms
|
||||
pw:browser [pid=789488][err] [789721:789721:1014/065659.123843:ERROR:base/memory/shared_memory_switch.cc:289] Failed global descriptor lookup: 7 +2s
|
||||
pw:browser [pid=789490][err] [789490:789531:1014/065701.312194:ERROR:google_apis/gcm/engine/registration_request.cc:291] Registration response error message: DEPRECATED_ENDPOINT +4s
|
||||
pw:browser [pid=789488][err] [789488:789553:1014/065702.399765:ERROR:google_apis/gcm/engine/registration_request.cc:291] Registration response error message: DEPRECATED_ENDPOINT +3s
|
||||
✓ 2 [desktop] › tests/browser/game.spec.ts:114:1 › 오디오 HTTP 실패를 화면에 표시하고 재시도한다 (14.7s)
|
||||
✓ 3 [desktop] › tests/browser/release.spec.ts:6:1 › 릴리스는 사용자 크레딧과 런타임 MIT notice 전문을 제공한다 (309ms)
|
||||
✓ 4 [desktop] › tests/browser/ui.spec.ts:4:1 › 전체 음량은 설정 흐름 안에 들어가며 키보드로 조절된다 (1.6s)
|
||||
✓ 5 [desktop] › tests/browser/ui.spec.ts:52:1 › 난이도 설명은 모바일에서도 보인다 (1.0s)
|
||||
pw:browser [pid=789490][err] [789490:789531:1014/065725.821501:ERROR:google_apis/gcm/engine/registration_request.cc:291] Registration response error message: DEPRECATED_ENDPOINT +25s
|
||||
pw:browser [pid=789488][err] [789488:789553:1014/065728.796251:ERROR:google_apis/gcm/engine/registration_request.cc:291] Registration response error message: QUOTA_EXCEEDED +26s
|
||||
✓ 6 [desktop] › tests/browser/ui.spec.ts:68:1 › 한국어 제목은 단어 중간에서 줄바꿈하지 않는다 (16.7s)
|
||||
pw:browser [pid=789490] <gracefully close start> +5s
|
||||
pw:browser [pid=789490] <process did exit: exitCode=0, signal=null> +53ms
|
||||
pw:browser [pid=789490] starting temporary directories cleanup +0ms
|
||||
pw:browser [pid=789490] finished temporary directories cleanup +9ms
|
||||
pw:browser [pid=789490] <gracefully close end> +0ms
|
||||
(node:789845) Warning: The 'NO_COLOR' env is ignored due to the 'FORCE_COLOR' env being set.
|
||||
(Use `node --trace-warnings ...` to show where the warning was created)
|
||||
pw:browser <launching> /usr/bin/google-chrome --disable-field-trial-config --disable-background-networking --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-edgeupdater --disable-extensions --disable-features=AvoidUnnecessaryBeforeUnloadCheckSync,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,BlockOriginHeaderModificationOnRedirect,Translate,AutoDeElevate,OptimizationHints,NetworkTimeServiceQuerying,AimEnabled,msForceBrowserSignIn,msEdgeUpdateLaunchServicesPreferredVersion --enable-features=CDPScreenshotNewSurface --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-updater-scheduler --force-color-profile=srgb --metrics-recording-only --no-first-run --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --disable-search-engine-choice-screen --unsafely-disable-devtools-self-xss-warnings --edge-skip-compat-layer-relaunch --disable-infobars --disable-search-engine-choice-screen --disable-sync --enable-unsafe-swiftshader --headless --hide-scrollbars --mute-audio --blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4 --user-data-dir=/tmp/playwright_chromiumdev_profile-WzJ5B4 --remote-debugging-pipe --no-startup-window +0ms
|
||||
pw:browser <launched> pid=789857 +13ms
|
||||
pw:browser [pid=789857][err] [789900:789900:1014/065731.887141:ERROR:base/memory/shared_memory_switch.cc:289] Failed global descriptor lookup: 7 +138ms
|
||||
pw:browser [pid=789857][err] [789972:789972:1014/065733.402085:ERROR:base/memory/shared_memory_switch.cc:289] Failed global descriptor lookup: 7 +2s
|
||||
pw:browser [pid=789857][err] [789857:789885:1014/065736.698476:ERROR:google_apis/gcm/engine/registration_request.cc:291] Registration response error message: DEPRECATED_ENDPOINT +3s
|
||||
pw:browser [pid=789857][err] [789857:789885:1014/065757.253598:ERROR:google_apis/gcm/engine/registration_request.cc:291] Registration response error message: DEPRECATED_ENDPOINT +21s
|
||||
✓ 1 [desktop] › tests/browser/game.spec.ts:7:1 › 실제 오디오로 혼합 모드 완주·레이아웃·접근성·외부 요청 없음 (1.6m)
|
||||
pw:browser [pid=789488] <gracefully close start> +1m
|
||||
pw:browser [pid=789488] <process did exit: exitCode=0, signal=null> +49ms
|
||||
pw:browser [pid=789488] starting temporary directories cleanup +1ms
|
||||
pw:browser [pid=789488] finished temporary directories cleanup +10ms
|
||||
pw:browser [pid=789488] <gracefully close end> +0ms
|
||||
(node:790149) Warning: The 'NO_COLOR' env is ignored due to the 'FORCE_COLOR' env being set.
|
||||
(Use `node --trace-warnings ...` to show where the warning was created)
|
||||
pw:browser <launching> /usr/bin/google-chrome --disable-field-trial-config --disable-background-networking --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-edgeupdater --disable-extensions --disable-features=AvoidUnnecessaryBeforeUnloadCheckSync,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,BlockOriginHeaderModificationOnRedirect,Translate,AutoDeElevate,OptimizationHints,NetworkTimeServiceQuerying,AimEnabled,msForceBrowserSignIn,msEdgeUpdateLaunchServicesPreferredVersion --enable-features=CDPScreenshotNewSurface --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-updater-scheduler --force-color-profile=srgb --metrics-recording-only --no-first-run --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --disable-search-engine-choice-screen --unsafely-disable-devtools-self-xss-warnings --edge-skip-compat-layer-relaunch --disable-infobars --disable-search-engine-choice-screen --disable-sync --enable-unsafe-swiftshader --headless --hide-scrollbars --mute-audio --blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4 --user-data-dir=/tmp/playwright_chromiumdev_profile-F4j9tO --remote-debugging-pipe --no-startup-window +0ms
|
||||
pw:browser <launched> pid=790161 +5ms
|
||||
pw:browser [pid=790161][err] [790203:790203:1014/065834.688015:ERROR:base/memory/shared_memory_switch.cc:289] Failed global descriptor lookup: 7 +137ms
|
||||
pw:browser [pid=790161][err] [790242:7:1014/065834.832706:ERROR:gpu/ipc/client/command_buffer_proxy_impl.cc:287] ContextResult::kTransientFailure: Failed to send GpuControl.CreateCommandBuffer. +143ms
|
||||
pw:browser [pid=790161][err] [790262:790262:1014/065835.186112:ERROR:base/memory/shared_memory_switch.cc:289] Failed global descriptor lookup: 7 +352ms
|
||||
pw:browser [pid=789857][err] [789857:789885:1014/065837.765817:ERROR:google_apis/gcm/engine/registration_request.cc:291] Registration response error message: DEPRECATED_ENDPOINT +41s
|
||||
pw:browser [pid=790161][err] [790161:790189:1014/065838.519301:ERROR:google_apis/gcm/engine/registration_request.cc:291] Registration response error message: QUOTA_EXCEEDED +3s
|
||||
✓ 8 [mobile] › tests/browser/game.spec.ts:114:1 › 오디오 HTTP 실패를 화면에 표시하고 재시도한다 (16.9s)
|
||||
✓ 9 [mobile] › tests/browser/release.spec.ts:6:1 › 릴리스는 사용자 크레딧과 런타임 MIT notice 전문을 제공한다 (292ms)
|
||||
✓ 10 [mobile] › tests/browser/ui.spec.ts:4:1 › 전체 음량은 설정 흐름 안에 들어가며 키보드로 조절된다 (938ms)
|
||||
✓ 11 [mobile] › tests/browser/ui.spec.ts:52:1 › 난이도 설명은 모바일에서도 보인다 (921ms)
|
||||
✓ 12 [mobile] › tests/browser/ui.spec.ts:68:1 › 한국어 제목은 단어 중간에서 줄바꿈하지 않는다 (16.7s)
|
||||
pw:browser [pid=790161] <gracefully close start> +32s
|
||||
pw:browser [pid=790161] <process did exit: exitCode=0, signal=null> +51ms
|
||||
pw:browser [pid=790161] starting temporary directories cleanup +0ms
|
||||
pw:browser [pid=790161] finished temporary directories cleanup +9ms
|
||||
pw:browser [pid=790161] <gracefully close end> +0ms
|
||||
✓ 7 [mobile] › tests/browser/game.spec.ts:7:1 › 실제 오디오로 혼합 모드 완주·레이아웃·접근성·외부 요청 없음 (1.7m)
|
||||
pw:browser [pid=789857] <gracefully close start> +34s
|
||||
pw:browser [pid=789857] <process did exit: exitCode=0, signal=null> +107ms
|
||||
pw:browser [pid=789857] starting temporary directories cleanup +1ms
|
||||
pw:browser [pid=789857] finished temporary directories cleanup +18ms
|
||||
pw:browser [pid=789857] <gracefully close end> +1ms
|
||||
|
||||
12 passed (2.3m)
|
||||
@@ -0,0 +1,21 @@
|
||||
2026-10-14T06:56:54.062Z pw:browser <launching> /usr/bin/google-chrome --disable-field-trial-config --disable-background-networking --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-edgeupdater --disable-extensions --disable-features=AvoidUnnecessaryBeforeUnloadCheckSync,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,BlockOriginHeaderModificationOnRedirect,Translate,AutoDeElevate,OptimizationHints,NetworkTimeServiceQuerying,AimEnabled,msForceBrowserSignIn,msEdgeUpdateLaunchServicesPreferredVersion --enable-features=CDPScreenshotNewSurface --allow-pre-commit-input --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-updater-scheduler --force-color-profile=srgb --metrics-recording-only --no-first-run --password-store=basic --use-mock-keychain --no-service-autorun --export-tagged-pdf --disable-search-engine-choice-screen --unsafely-disable-devtools-self-xss-warnings --edge-skip-compat-layer-relaunch --disable-infobars --disable-search-engine-choice-screen --disable-sync --enable-unsafe-swiftshader --headless --hide-scrollbars --mute-audio --blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4 --user-data-dir=/tmp/playwright_chromiumdev_profile-jPkOZ2 --remote-debugging-pipe --no-startup-window
|
||||
2026-10-14T06:56:54.067Z pw:browser <launched> pid=789288
|
||||
2026-10-14T06:56:54.238Z pw:browser [pid=789288][err] [789341:789341:1014/065654.236997:ERROR:base/memory/shared_memory_switch.cc:289] Failed global descriptor lookup: 7
|
||||
2026-10-14T06:56:54.428Z pw:browser [pid=789288][err] [789379:7:1014/065654.427988:ERROR:gpu/ipc/client/command_buffer_proxy_impl.cc:287] ContextResult::kTransientFailure: Failed to send GpuControl.CreateCommandBuffer.
|
||||
SANDBOX STATUS
|
||||
Sandbox Status
|
||||
Layer 1 Sandbox Namespace
|
||||
PID namespaces Yes
|
||||
Network namespaces Yes
|
||||
Seccomp-BPF sandbox Yes
|
||||
Seccomp-BPF sandbox supports TSYNC Yes
|
||||
Ptrace Protection with Yama LSM (Broker) Yes
|
||||
Ptrace Protection with Yama LSM (Non-broker) No
|
||||
|
||||
You are adequately sandboxed.
|
||||
PASS: sandboxed Chrome decoded 101/101 WAVs at 24kHz mono; hashes, bytes, duration, RMS, peak verified; external requests=0, JS errors=0.
|
||||
2026-10-14T06:56:57.008Z pw:browser [pid=789288] <gracefully close start>
|
||||
2026-10-14T06:56:57.243Z pw:browser [pid=789288] <process did exit: exitCode=0, signal=null>
|
||||
2026-10-14T06:56:57.243Z pw:browser [pid=789288] starting temporary directories cleanup
|
||||
2026-10-14T06:56:57.285Z pw:browser [pid=789288] finished temporary directories cleanup
|
||||
2026-10-14T06:56:57.286Z pw:browser [pid=789288] <gracefully close end>
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
> find-word@0.1.1 lint
|
||||
> eslint . && tsc --noEmit
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"historicalFilesUnchanged": 115,
|
||||
"gitHeadUnchanged": "1c0069c367f6e108d3f67a2a0d044399dd0ef2bd",
|
||||
"branch": "fix/v0.1.1-neural-voice",
|
||||
"secretScanTextFiles": 40,
|
||||
"secretMatches": 0,
|
||||
"publicStageDirectories": 0,
|
||||
"pythonVenvVersion": "7.3.1"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
Linux-6.8.0-142-generic-x86_64-with-glibc2.39
|
||||
Generated at: 2026-10-14T06:55:41.751382+00:00
|
||||
$ node --version
|
||||
v26.7.0
|
||||
$ npm --version
|
||||
11.19.0
|
||||
$ .venv-audio/bin/python --version
|
||||
Python 3.11.16
|
||||
$ .venv-audio/bin/python -m pip check
|
||||
No broken requirements found.
|
||||
$ google-chrome --version
|
||||
Google Chrome 146.0.7680.80
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"historicalFilesUnchanged": 115,
|
||||
"gitHeadUnchanged": "1c0069c367f6e108d3f67a2a0d044399dd0ef2bd",
|
||||
"branch": "fix/v0.1.1-neural-voice",
|
||||
"chromeLaunchesWithSandbox": 5,
|
||||
"browserTestsPassed": 12,
|
||||
"browserRuntimeSandbox": [
|
||||
"Namespace",
|
||||
"PID namespaces",
|
||||
"Network namespaces",
|
||||
"Seccomp-BPF"
|
||||
],
|
||||
"documentLinksChecked": 56,
|
||||
"gameMechanicsAndRuntimeAudioUnchanged": true,
|
||||
"distContainsOnlyExpectedArtifacts": true,
|
||||
"diffCheck": "PASS"
|
||||
}
|
||||
@@ -0,0 +1,738 @@
|
||||
{
|
||||
"historical": {
|
||||
".agent/evidence/01-content-green.log": "5585acd257b49225218835acd69a1d240c7737d12dba62949f31a5b7c1c9ed2a",
|
||||
".agent/evidence/01-content-red.log": "0f28fe2ae2c4669a52ba2fc15bfa6285e4922474dc2b2571098b522679948e12",
|
||||
".agent/evidence/02-game-green.log": "5ca5895f8a09f4e9de7a846bf9ab37fb3715623e8e7654dab095505c097fc0c7",
|
||||
".agent/evidence/02-game-red.log": "78468ee5c25c1685f3613926f636b6fb4569227533feda3547afc6b8123d6452",
|
||||
".agent/evidence/03-dsp-green.log": "d3d08683a1426b845a2e987572861b82b3ac978b8c352991950c0f32a473d3de",
|
||||
".agent/evidence/03-dsp-intermediate.log": "084a52294f718718256eb1516048a672d045a5f7dcb5d11c646092d29efbab58",
|
||||
".agent/evidence/03-dsp-red.log": "bacf42e5c808d32702b9bcd30523d1fcf17d5ff75b281233d9e84f33b6e42589",
|
||||
".agent/evidence/04-audio-green.log": "d48c93fa7d32315ed4f719dee19222e7398bc4c4bceb8cf345e0e221a9ac89d8",
|
||||
".agent/evidence/04-audio-red.log": "58bbf8eae572f83e408dd101eac738a5f6963550e21c8265f42a7eeba18be7a7",
|
||||
".agent/evidence/05-assets-red.log": "04388acb098f7dabe9a35783b496075ee7c39757d3fde5361c9ac080188ac371",
|
||||
".agent/evidence/06-ui-05-assets-green.log": "ced2ad738cda673b24308dcb9d99d59e3ae918709eeb32de359d6ab1022133e2",
|
||||
".agent/evidence/06-ui-intermediate.log": "3295b3ae691dadb8feb7f0aaf604a1aa56cbfae27b5dbdd486cb5645f5edabe9",
|
||||
".agent/evidence/06-ui-red.log": "1f1ed6bd440af22f5abf59e4be194f969bee1d115d436a155d879d8cffddb747",
|
||||
".agent/evidence/07-build-green.log": "ec98087d20a68c5b81c6c23406316f1e5f19c6124498e1fc005d04bb78894a57",
|
||||
".agent/evidence/07-build-red.log": "138802de7bc67c1535668efe7a915424a70d5d7994acb7f366a139e89c1da77f",
|
||||
".agent/evidence/08-rule-green.log": "91b7ce3fda181fbe51cbe4e6debb61dd44dd55226dcfa81ed73559ba76811f3f",
|
||||
".agent/evidence/08-rule-red.log": "2cc1854cf6a4b9e8d53a7a36b1dde1fb6c6970b89f841b9e8f404e6e42bb929e",
|
||||
".agent/evidence/09-ime-green.log": "e5d5d1cfa2b6db724ded97d5f3309a517bcf637d9b2b417e9110dc9da0a48d72",
|
||||
".agent/evidence/09-ime-red.log": "10e5f9f99609044c768cd338df0d574a06a7442e0debe0e61ca16a6b5873adf3",
|
||||
".agent/evidence/10-ime-reset-green.log": "e12761b3a2814a79d1448e7452474a086bf371921287718eb72dd9b0f6b8fc82",
|
||||
".agent/evidence/10-ime-reset-red.log": "f6cb7c1724b8f9c410385e9970051577c03527fb7e719f43a77c967ca08ef18f",
|
||||
".agent/evidence/11-provenance-green.log": "54dcc417b97f82422c5c3e0ae11caa1f15a60412853ea1dc0152d15031bcd935",
|
||||
".agent/evidence/11-provenance-red.log": "e69fa7989223e659c16b8030f8668e562ad5b0daa060fbb1c9eff41a37fd56fd",
|
||||
".agent/evidence/12-ime-replay-green.log": "a93d9f16c7d81ed5e9a7c0b70ffee1e393d2943ddf3149a5bb115c5517327c44",
|
||||
".agent/evidence/12-ime-replay-red.log": "8cf5dab06d93cc544c21276ee633829f8b137b4b6d7c5fe47aadcad6fc2afb71",
|
||||
".agent/evidence/13-heading-build-after.log": "19829ac264f97aa023baf7d5e1fd429343272f3bd952e8b6dfb9eec0f594b453",
|
||||
".agent/evidence/13-heading-build-before.log": "646d197d2ef93c19fec4719e20297de1b22eff54f3e6155ba2125fd3dd372c46",
|
||||
".agent/evidence/13-heading-green.log": "d59fa8546083e9d371c7a552287f27bf3acd572bd0cce3da8eba860da5c05880",
|
||||
".agent/evidence/13-heading-red.log": "33acc2838786a87b8ecc170a1ac0a9d7521daf8e5b9aed2195e76e45ea327f76",
|
||||
".agent/evidence/14-snr-browser-green.log": "fcb82296e9af4b96112fae0bbb77c6ba41230c117021243e85916ae1130a462d",
|
||||
".agent/evidence/14-snr-browser-red.log": "36298e5bb1f45a69b0ca75e5cbce85ee1455c4485759670268fbbcf55bacd4d4",
|
||||
".agent/evidence/14-snr-build.log": "1e9ce36a48904a58195f9d1c2d9ca6cf2895fcb8bd0b5ab9b72f76e92c6b2585",
|
||||
".agent/evidence/14-snr-green.log": "ae74e57cea20841299a8c1ee5eaf60efad34bda697339f45527cdec83578e6df",
|
||||
".agent/evidence/14-snr-red.log": "b39bdbd8815d0d9cfcedc41c61124afece2011ea6c6c250b0ee0139eae7e9edd",
|
||||
".agent/evidence/15-volume-browser-green.log": "aeccd5f13eb9db4062cbf2c70eee332d0c39540d580e113d0a79a899b2ef02de",
|
||||
".agent/evidence/15-volume-browser-red.log": "84954280c1729703f9e9c2680c8933c3b0752b19fb9c3562e7dbf2ea1b4a548c",
|
||||
".agent/evidence/15-volume-build.log": "2767b794124804b3447f529eef025e2530975fcc506e1cbe8994acf8243e6ba8",
|
||||
".agent/evidence/15-volume-green.log": "0f9a90923f4fdc477c8f2436653eb2bf0e4b251bcb52e795701309ba14f23c7d",
|
||||
".agent/evidence/15-volume-red.log": "9beae6305080cd0d869bf3fd2093beb6e2e25e5424223aa7e4ad4db96954f37e",
|
||||
".agent/evidence/16-copy-green.log": "dacbdbab5d4af2b6e19eb4e0502a70720aac9fb6cf3b9d6dfdc73a5bf7edabfe",
|
||||
".agent/evidence/16-copy-red.log": "ebe3d7c86938d33d7f1a4818b18c7e94ab8feb18bee099fcb535a93d8083861b",
|
||||
".agent/evidence/17-spacing-green.log": "8ab85362ceadcdfecf4f7b1e95abfb4237e15018692e14f937be90265c351b11",
|
||||
".agent/evidence/17-spacing-red.log": "12db8083cd8627a81a52cd32358780a3c2257cb3bd702350b190b39226f6550f",
|
||||
".agent/evidence/18-literal-green.log": "878a8d788a8cedbf652fe0e819fe482099249a52ae7b5cc3d8826e64b32c6377",
|
||||
".agent/evidence/18-literal-red.log": "ad23ae7be3d9aab83907c12849012a01f9d1b12e5a174c3acede89817a74d2d2",
|
||||
".agent/evidence/19-notices-green.log": "efc51aca0738f3cb5264ec3c3ad0d17bb150d685f5fdb5e200bc1eedc0e3c02b",
|
||||
".agent/evidence/19-notices-red.log": "8f34c583cb8563803828d72fe56622d84bcf59a9541d983d6c0b705225955794",
|
||||
".agent/evidence/20-audio-generate.log": "f864fc266f7ca50c600457399f198a77949e9ee1601b0d2fc19b64942a2030cb",
|
||||
".agent/evidence/20-audio-green.log": "edb9b9f0aa1af11835960eee9bb6e8c013341aa528d2857bac0b89ac38457528",
|
||||
".agent/evidence/20-audio-red.log": "c1cbd5b585e8a70e23b88bfcee0c6479f85fdec0d1e06d13c81c689a140c0ac0",
|
||||
".agent/evidence/20-mechanics-green.log": "9776c68143f668e35df8b2e19884b25d2369e4800b4c264e635d0c260818c5f1",
|
||||
".agent/evidence/20-mechanics-red.log": "d25a1c844366e14fe1db9bb7c243fe0adb6857ee5b4548cf2865de96589af647",
|
||||
".agent/evidence/21-node-green.log": "3c36e9e45b6844ae2c184f943b61195482d9de53ceab06221093c8281d210d73",
|
||||
".agent/evidence/21-node-red.log": "ee25556037bdbd6b099dbb087a522284e8df00bd573dfcf0e42c734e31e09e84",
|
||||
".agent/evidence/22-sandbox-green.log": "e8a1a17e49c22dea81d7f85111c744473427466791ddeda75047cd0082e7faba",
|
||||
".agent/evidence/22-sandbox-red.log": "c8a97270f0f68367d6edb3e5ee10f34bbda1127f8dae2c5639afd482198e7bcd",
|
||||
".agent/evidence/23-delivery-browser-red.log": "180a61bbacf85db9e52f721b50da683103b719bc350454cc99d4c8954b2ae86e",
|
||||
".agent/evidence/24-retry-audio-budget.log": "b9241872b4ecd80265df4c6c2be90b31e9de4d0754772655e50b7fb4f05e2d3b",
|
||||
".agent/evidence/24-retry-final-browser.log": "68029aae89adf86fd60ee56a20a1e2f769cb4f894f27ae23963ca5b5b58c62c4",
|
||||
".agent/evidence/24-retry-final-build.log": "702c20554872e437137097ca59a80d911188477f018bc48c4b49a770b73d5a84",
|
||||
".agent/evidence/24-retry-final-lint.log": "8682ca1f55e3ec58f13321cc339c8647ef72c1934d74ea9b980aee717e528819",
|
||||
".agent/evidence/24-retry-final-test.log": "b71bb1375a039bcc3d7b3c5070da85ece3551f32ae1b8bb3a2abc5ef1edd57b8",
|
||||
".agent/evidence/24-retry-integrity.log": "a188fe54dce05f6caa868b3d9f2c22a852f6a8cdc462355673316578be623a08",
|
||||
".agent/evidence/24-retry-targeted-green.log": "4e53f2de988040540f5075b2e4a483ca53b671486c35e864fbc3c2c9c5361c61",
|
||||
".agent/evidence/audio-reproduce.log": "5f5726f3ed6845882c7a6d6f9a8d898c2b73bf61fa6328e8bbafd25f61ed4268",
|
||||
".agent/evidence/browser-final.log": "9273c91613160e239027452894b3735f9657ccad97a52412eb889290aebd5adf",
|
||||
".agent/evidence/browser-first.log": "f3087028d76aae36d61d7a14da488bd809079a9e121a2d8fb01fa034f99d4f05",
|
||||
".agent/evidence/browser-second.log": "2ff1d16f51b9384cf431d5923ad87d773510fe4b89bdf62f09cbda2efae20e3b",
|
||||
".agent/evidence/browser-third.log": "1b6c264930da8934e7f1c8da6c998543f35e68b1c3159dad722cfe23a8e5244c",
|
||||
".agent/evidence/changed-files.txt": "2b609231e5c7becd581f79413a4f7443312e71f0099ac6a51b2c5f0dfdee576f",
|
||||
".agent/evidence/desktop-game.png": "42702e89264357257db8bf54c2b3743e3212e62cfd3476a8c25bad83fb59ff81",
|
||||
".agent/evidence/desktop-home.png": "bf2f515fcd483cd5ca9a3b408f484d3556b75b1be0bb70360b7fd5f7c3404993",
|
||||
".agent/evidence/desktop-results.png": "003df3aeb08ce66618775377d9b2003809d696629f61cf54b7b86e7a0ed63593",
|
||||
".agent/evidence/final-audit.log": "6d8c5c8f3d7684adb070417bd608d01ae90aa3dc26a65af03ffda4955f38d9a3",
|
||||
".agent/evidence/final-browser.log": "5855691def462b23667a9d658338a0458a53d984b5b5f7e11b45f9a63092abcd",
|
||||
".agent/evidence/final-build.log": "565a95a51a10f78bc08f256755afce5ef183440dcdea5e75b3aefde8d7c5b837",
|
||||
".agent/evidence/final-lint.log": "d2354c241320f11f07890cbf32f99a5d88f1c7f4f236d860e2cd26db739badd8",
|
||||
".agent/evidence/final-security.log": "c585566624a4596e97327fb1864b1ac2a3189c0794b1e25a9d6ff1abb86046cb",
|
||||
".agent/evidence/final-test.log": "af03027cb22a090ecd107c10e3fc7e2f9ceb394122b0b73caa7d362310504170",
|
||||
".agent/evidence/mobile-game.png": "20a3f02f70a28b2faae1b33d0d4d6fea10b77caa426e4bf9faa5ef6d4474a846",
|
||||
".agent/evidence/mobile-home.png": "7f84bd54183fcdd03fe136b41145146ddfb323041c96a8b9e6b670c9a923033a",
|
||||
".agent/evidence/mobile-results.png": "ec2938c03ac03da8e33e25f043522b317b60c16be1c29f9dd325a81ae84513a8",
|
||||
".agent/evidence/neo-before-spacing-browser.log": "e5c214f14bd93ef1bb731f87ecfd3a02d299c9f9e5a788233f6eda5eb8946b4f",
|
||||
".agent/evidence/neo-desktop-game.png": "f5966688ba46f14fab5125452f935e55f6e6dc4355c876416729866129daea70",
|
||||
".agent/evidence/neo-desktop-heading.png": "db609f2f54af0e6b1bb96bce9bf839454403d6e2787e6520a2928fad31beb021",
|
||||
".agent/evidence/neo-desktop-home.png": "826c5da794c4ea3c15bd6c13e81d1c021fbeb8a902fc4908b78f9c457f091c0f",
|
||||
".agent/evidence/neo-desktop-results.png": "98a68ca050a4e66c17dcc3f1bd5f0e86bfc88c2ebe9a75284766d17e10426632",
|
||||
".agent/evidence/neo-final-browser.log": "582e7cbb643201e4b197b566b021322448abaae0b383967ad0e816d0c351e96b",
|
||||
".agent/evidence/neo-final-build.log": "f30138e53b8c12e70e80e2cd5f4bdfcf8d1f6a095216a4f9ade6687bca1f0488",
|
||||
".agent/evidence/neo-final-lint.log": "d2354c241320f11f07890cbf32f99a5d88f1c7f4f236d860e2cd26db739badd8",
|
||||
".agent/evidence/neo-final-test.log": "f718e2acda255fcba67b272c7fa625af450714b384bb67a72f09328bf6964f0b",
|
||||
".agent/evidence/neo-intermediate-build.log": "9d8a1f0586d58196e03e45330b6e8ff5522fdd3c27870aae2fb052199f8cf5cb",
|
||||
".agent/evidence/neo-intermediate-lint.log": "5e94ea847c3a092f4ff8e97ac5b61ebef805b3c859ad38461f4a437045d1b5b9",
|
||||
".agent/evidence/neo-mobile-game.png": "1a6733a3293204e4841ec8722a1ffe37033943097c691bcfadbcd907fde024ef",
|
||||
".agent/evidence/neo-mobile-heading.png": "ae07d0a1cb6f835525c7e0ef31655a543eaa9e10183596c2d409dead6faccf15",
|
||||
".agent/evidence/neo-mobile-home.png": "9b3ba8b0a9f7b321882429e31ac4a0472fcc13a998dfadfc930c273bc37558d4",
|
||||
".agent/evidence/neo-mobile-results.png": "d49fdf6ae9566d7a2003db3f252d84ed88ac4d73a0390ce404b47e7bab9c60df",
|
||||
".agent/evidence/release-desktop-game.png": "7300a06a507f651a587ed3deb36cc5bb728f4a36c30b7b1cf409a3b209ba564c",
|
||||
".agent/evidence/release-desktop-heading.png": "de454d77e29737e23c573646404489d5682004521deabfa01b439d607faa32ca",
|
||||
".agent/evidence/release-desktop-home.png": "f28f744e11b66373ee8db6eda2f7bdc384da4f7e763fbb467a4cda30090e869b",
|
||||
".agent/evidence/release-desktop-results.png": "2ebb4056d0ecdadea8a3469500801065ae158c17cd2db27817e813e53adc71f3",
|
||||
".agent/evidence/release-docs-final.log": "3529acce5befee536ec7d8e9d22cbbf27182297bb07408ab6e31551aaee76ed3",
|
||||
".agent/evidence/release-final-audit.log": "6d8c5c8f3d7684adb070417bd608d01ae90aa3dc26a65af03ffda4955f38d9a3",
|
||||
".agent/evidence/release-final-browser.log": "2a9881cef8c379f41abf5d69dd5ad21881988f78c0579c95e463121dc37f6e09",
|
||||
".agent/evidence/release-final-build.log": "3fba8356382341db9c562d985ca2229fd0b81969532746b0146bc489d54c321e",
|
||||
".agent/evidence/release-final-lint.log": "d2354c241320f11f07890cbf32f99a5d88f1c7f4f236d860e2cd26db739badd8",
|
||||
".agent/evidence/release-final-test.log": "46d5d0fc0180adc00a734b64db4acb4cbaa37d12567d0224836306312213870c",
|
||||
".agent/evidence/release-format.log": "57658c36cb3161b53cdf934017e4b7a733a273509ace184e0a2a6eaa046c742b",
|
||||
".agent/evidence/release-integrity.log": "cc77121b43a6b24a358999cf1a3bbf701d467fcee9730095f318303c2e80602b",
|
||||
".agent/evidence/release-intermediate-lint.log": "ee597e984ebdf11ea247c8cb1551cda446580cbd7a3dc708f85fa78bb72700ad",
|
||||
".agent/evidence/release-mobile-game.png": "83a918e5ff2142e540cd12b85806b3e69a71bc66df5d241f4b2f5abdaf493f82",
|
||||
".agent/evidence/release-mobile-heading.png": "d5c92a3b62f749d5f064af12efa5a1a2ad13b177270ec01dd10a549a8437899d",
|
||||
".agent/evidence/release-mobile-home.png": "c7fc37a247bbadba60de9dff3c8d87930a2e6ebb868f687a4135b3fd035ed1c3",
|
||||
".agent/evidence/release-mobile-results.png": "587956c9ad5eca054e4bb4b44748a2c637655e407427ba5b4c6ad7bf5a74539a",
|
||||
".agent/RESULT.md": "eef6d73a67a8a7e90cd7b4747debc5976cc51571bc268328634413f698d0e311"
|
||||
},
|
||||
"audio": {
|
||||
"generator": "eSpeak NG ko, speed 145, pitch 45, amplitude 100; FFmpeg PCM 16kHz mono s16",
|
||||
"toolVersions": {
|
||||
"espeak": "eSpeak NG text-to-speech: 1.51",
|
||||
"ffmpeg": "ffmpeg version 6.1.1-3ubuntu5 Copyright (c) 2000-2023 the FFmpeg developers"
|
||||
},
|
||||
"source": "https://github.com/espeak-ng/espeak-ng",
|
||||
"method": "자체 작성 문장의 오프라인 포먼트 합성; 외부 녹음·네트워크 TTS 없음",
|
||||
"files": [
|
||||
{
|
||||
"file": "intro.wav",
|
||||
"text": "으하하하~~ 나는 에스다. 널 위한 행운의 단어를 불러주마, 잘 찾아보거라.",
|
||||
"sha256": "4c271551d99cd9dffc01f35c176e98b54b4879549543ff8e2c79c6af8d4dc53a",
|
||||
"bytes": 259900
|
||||
},
|
||||
{
|
||||
"file": "luck-apple.wav",
|
||||
"text": "오늘의 행운을 담은 단어는 ‘사과’입니다.",
|
||||
"sha256": "51e6cf35b219f13c0d72ec9633f0c108c3393bc5ef6ae6aca6aa5d00153b4177",
|
||||
"bytes": 125658
|
||||
},
|
||||
{
|
||||
"file": "luck-sea.wav",
|
||||
"text": "오늘의 행운을 담은 단어는 ‘바다’입니다.",
|
||||
"sha256": "6585cb8d50eea173395417fc5fb357f55901665fe45dd07d942f79e202729111",
|
||||
"bytes": 123366
|
||||
},
|
||||
{
|
||||
"file": "luck-tree.wav",
|
||||
"text": "오늘의 행운을 담은 단어는 ‘나무’입니다.",
|
||||
"sha256": "6d188188d1478d0298536e0e03a58883629459dee56c6ae8ab88b4d7170c1def",
|
||||
"bytes": 121224
|
||||
},
|
||||
{
|
||||
"file": "luck-hat.wav",
|
||||
"text": "오늘의 행운을 담은 단어는 ‘모자’입니다.",
|
||||
"sha256": "be8d4287ebce15e221a8908f6b2d7478e789ecc51ba95d65fdf34f130954e7e5",
|
||||
"bytes": 121644
|
||||
},
|
||||
{
|
||||
"file": "luck-umbrella.wav",
|
||||
"text": "오늘의 행운을 담은 단어는 ‘우산’입니다.",
|
||||
"sha256": "188e24932e5e68fb0de8270e5b48128d486da956ad4069afbbcd0ad9af5913ce",
|
||||
"bytes": 122178
|
||||
},
|
||||
{
|
||||
"file": "luck-market.wav",
|
||||
"text": "오늘의 행운을 담은 단어는 ‘시장’입니다.",
|
||||
"sha256": "e58cdfd5a43074179e65edaf5f223dd15ad1accdd2fd547a6d3311de57b78eca",
|
||||
"bytes": 124352
|
||||
},
|
||||
{
|
||||
"file": "luck-oil.wav",
|
||||
"text": "오늘의 행운을 담은 단어는 ‘기름’입니다.",
|
||||
"sha256": "8b1070414191ff87b9531caf0782b13458b246a1f07b51f7ddcff2cd613930f7",
|
||||
"bytes": 120286
|
||||
},
|
||||
{
|
||||
"file": "luck-sound.wav",
|
||||
"text": "오늘의 행운을 담은 단어는 ‘소리’입니다.",
|
||||
"sha256": "052e2c2724c2fcf9d4c68ba3b746a430af0cfc74b42ed6f8317ae2cc5af1c2ad",
|
||||
"bytes": 122660
|
||||
},
|
||||
{
|
||||
"file": "luck-meat.wav",
|
||||
"text": "오늘의 행운을 담은 단어는 ‘고기’입니다.",
|
||||
"sha256": "dcf3d1c84a9ee00ea8a1ea5552ac69b3dc46b9c4160ee3375a4afe38426c0b8d",
|
||||
"bytes": 121754
|
||||
},
|
||||
{
|
||||
"file": "luck-furniture.wav",
|
||||
"text": "오늘의 행운을 담은 단어는 ‘가구’입니다.",
|
||||
"sha256": "6265e3807ea10eb82e9bb15a7e72dcab5e148277bc49bacfdb2663817d151ddf",
|
||||
"bytes": 122164
|
||||
},
|
||||
{
|
||||
"file": "password-apple.wav",
|
||||
"text": "연습 암호는 ‘다과’, 진짜 암호는 ‘사과’입니다.",
|
||||
"sha256": "14b7c8c0253784f319a04b568da594d8e46077d03931a36a23e8a7689dd4b928",
|
||||
"bytes": 161688
|
||||
},
|
||||
{
|
||||
"file": "password-sea.wav",
|
||||
"text": "연습 암호는 ‘사다’, 진짜 암호는 ‘바다’입니다.",
|
||||
"sha256": "832178b1eee4fe29653ca8dfda5bfb356cab83f4f880a704ee9eab937443f872",
|
||||
"bytes": 160256
|
||||
},
|
||||
{
|
||||
"file": "password-tree.wav",
|
||||
"text": "연습 암호는 ‘나루’, 진짜 암호는 ‘나무’입니다.",
|
||||
"sha256": "ef25aa09f89acadcbb2c43a1f18d0c2da292fae4d87d052868942d08b3825a8d",
|
||||
"bytes": 156642
|
||||
},
|
||||
{
|
||||
"file": "password-hat.wav",
|
||||
"text": "연습 암호는 ‘포자’, 진짜 암호는 ‘모자’입니다.",
|
||||
"sha256": "aef3f595e1b2d36212d4611f9998d841303e96ee5385639094aebcc984ff8a94",
|
||||
"bytes": 158616
|
||||
},
|
||||
{
|
||||
"file": "password-umbrella.wav",
|
||||
"text": "연습 암호는 ‘부산’, 진짜 암호는 ‘우산’입니다.",
|
||||
"sha256": "6bc1bf13c3fd1739bc9e490525ecd5839b9a4032faecb9f101a2c68824d57b82",
|
||||
"bytes": 162668
|
||||
},
|
||||
{
|
||||
"file": "password-market.wav",
|
||||
"text": "연습 암호는 ‘지장’, 진짜 암호는 ‘시장’입니다.",
|
||||
"sha256": "33036e08a06dd33b6aa86e5b78352d2f90e35ac1c7f9f202af2a32e2ceffcfc1",
|
||||
"bytes": 166360
|
||||
},
|
||||
{
|
||||
"file": "password-oil.wav",
|
||||
"text": "연습 암호는 ‘이름’, 진짜 암호는 ‘기름’입니다.",
|
||||
"sha256": "d88914ab7302112beecb6b2edbe114c3c119ee375985eca9716bf239aea94038",
|
||||
"bytes": 157396
|
||||
},
|
||||
{
|
||||
"file": "password-sound.wav",
|
||||
"text": "연습 암호는 ‘오리’, 진짜 암호는 ‘소리’입니다.",
|
||||
"sha256": "d3df570902e1f1fb5b2a7c573d57857bf4da547fb97ebdf27f04fbbf29c1170f",
|
||||
"bytes": 155298
|
||||
},
|
||||
{
|
||||
"file": "password-meat.wav",
|
||||
"text": "연습 암호는 ‘보기’, 진짜 암호는 ‘고기’입니다.",
|
||||
"sha256": "59c422dbf3c2ed7a397e7bf3455a2bf59132f85477765c6ec13673633cdb1e8c",
|
||||
"bytes": 157754
|
||||
},
|
||||
{
|
||||
"file": "password-furniture.wav",
|
||||
"text": "연습 암호는 ‘하구’, 진짜 암호는 ‘가구’입니다.",
|
||||
"sha256": "c349bd57598eec8543ce488dd86a4c4ddd4ec661ac9e8d7f42d914d545f38f61",
|
||||
"bytes": 158998
|
||||
},
|
||||
{
|
||||
"file": "remember-apple.wav",
|
||||
"text": "‘다과’. 이 단어는 잊으세요. 이제 ‘사과’, 이 단어를 기억하세요.",
|
||||
"sha256": "3123d84c546ff4e630a8b93d59bd5e668a5de30ea651e56e134d47690aead28b",
|
||||
"bytes": 205094
|
||||
},
|
||||
{
|
||||
"file": "remember-sea.wav",
|
||||
"text": "‘사다’. 이 단어는 잊으세요. 이제 ‘바다’, 이 단어를 기억하세요.",
|
||||
"sha256": "d802055500865e38b9beffe0213b70314aa59ec181cb1af1897dd010bb5875e3",
|
||||
"bytes": 204654
|
||||
},
|
||||
{
|
||||
"file": "remember-tree.wav",
|
||||
"text": "‘나루’. 이 단어는 잊으세요. 이제 ‘나무’, 이 단어를 기억하세요.",
|
||||
"sha256": "1e3f340609eb9844b7fc727f0c17a7f9f60245d4e00df2330d734efa97d26a33",
|
||||
"bytes": 201206
|
||||
},
|
||||
{
|
||||
"file": "remember-hat.wav",
|
||||
"text": "‘포자’. 이 단어는 잊으세요. 이제 ‘모자’, 이 단어를 기억하세요.",
|
||||
"sha256": "8a3cd1ef975d8a6782c018bbe23d9e69b4876fe8e64dcb9971f5025bb7072a4c",
|
||||
"bytes": 202530
|
||||
},
|
||||
{
|
||||
"file": "remember-umbrella.wav",
|
||||
"text": "‘부산’. 이 단어는 잊으세요. 이제 ‘우산’, 이 단어를 기억하세요.",
|
||||
"sha256": "5c5ab3c30f02d3a3b8188f1d81f4d8f617a9e9783c18da38bf6d4bee9d03709e",
|
||||
"bytes": 209448
|
||||
},
|
||||
{
|
||||
"file": "remember-market.wav",
|
||||
"text": "‘지장’. 이 단어는 잊으세요. 이제 ‘시장’, 이 단어를 기억하세요.",
|
||||
"sha256": "eb582873b55043a61b80e34b25302f8d52ae9c7d641032ce65ddca8fb9bfb181",
|
||||
"bytes": 212988
|
||||
},
|
||||
{
|
||||
"file": "remember-oil.wav",
|
||||
"text": "‘이름’. 이 단어는 잊으세요. 이제 ‘기름’, 이 단어를 기억하세요.",
|
||||
"sha256": "d56d8639bf462b1c341c07252666975ff6f3428de74f0bef886019fe0085be57",
|
||||
"bytes": 204388
|
||||
},
|
||||
{
|
||||
"file": "remember-sound.wav",
|
||||
"text": "‘오리’. 이 단어는 잊으세요. 이제 ‘소리’, 이 단어를 기억하세요.",
|
||||
"sha256": "c3d8e3e75086fd52a38806ea2122542d4fe495e381d4aa4c36e72277449451bf",
|
||||
"bytes": 200100
|
||||
},
|
||||
{
|
||||
"file": "remember-meat.wav",
|
||||
"text": "‘보기’. 이 단어는 잊으세요. 이제 ‘고기’, 이 단어를 기억하세요.",
|
||||
"sha256": "be4cc7dc1af803a23eb4319d076ecf4c5ab37b56913287f49c3b3c96eb4a75ce",
|
||||
"bytes": 201730
|
||||
},
|
||||
{
|
||||
"file": "remember-furniture.wav",
|
||||
"text": "‘하구’. 이 단어는 잊으세요. 이제 ‘가구’, 이 단어를 기억하세요.",
|
||||
"sha256": "acc3efbba9ef6bf53a3992a669946b6c58e90c9821e2fb5ef8e8c4a738f8bdf7",
|
||||
"bytes": 202972
|
||||
},
|
||||
{
|
||||
"file": "last-apple.wav",
|
||||
"text": "세 단어 중 마지막을 고르세요. ‘다과’, ‘사고’, ‘사과’.",
|
||||
"sha256": "5f583e9af9213cd5dc78abb68e5fcba3dbb7c65d7d8131a53210d8326e5cbb87",
|
||||
"bytes": 187732
|
||||
},
|
||||
{
|
||||
"file": "last-sea.wav",
|
||||
"text": "세 단어 중 마지막을 고르세요. ‘사다’, ‘보다’, ‘바다’.",
|
||||
"sha256": "21e589a6f7c262cca5533a8599a9d4fb257028a6e0c42732f6147209ad35ecb6",
|
||||
"bytes": 190468
|
||||
},
|
||||
{
|
||||
"file": "last-tree.wav",
|
||||
"text": "세 단어 중 마지막을 고르세요. ‘나루’, ‘너무’, ‘나무’.",
|
||||
"sha256": "915249a9860aa29c36149fc57b04057b2fa6ab9253fdfa1e0837236f84cb7aab",
|
||||
"bytes": 186820
|
||||
},
|
||||
{
|
||||
"file": "last-hat.wav",
|
||||
"text": "세 단어 중 마지막을 고르세요. ‘포자’, ‘모조’, ‘모자’.",
|
||||
"sha256": "0ce70943449ec5fb18c57d4ba7ea09a6e995f4bc991db07c70c9a846e16679a1",
|
||||
"bytes": 189216
|
||||
},
|
||||
{
|
||||
"file": "last-umbrella.wav",
|
||||
"text": "세 단어 중 마지막을 고르세요. ‘부산’, ‘오산’, ‘우산’.",
|
||||
"sha256": "8e5a3a57fc55a7deae5df5be5425a970b0a4926b74844f0f6fba74d882d8ea73",
|
||||
"bytes": 192394
|
||||
},
|
||||
{
|
||||
"file": "last-market.wav",
|
||||
"text": "세 단어 중 마지막을 고르세요. ‘지장’, ‘사장’, ‘시장’.",
|
||||
"sha256": "2419dbb03e18d3528a615b4977405699ab5285ea4b392e45164b625ebb5ff0db",
|
||||
"bytes": 201286
|
||||
},
|
||||
{
|
||||
"file": "last-oil.wav",
|
||||
"text": "세 단어 중 마지막을 고르세요. ‘이름’, ‘거름’, ‘기름’.",
|
||||
"sha256": "8a7108a6b23dddb5f2ae1c72edf6c488335ccd322acdb6d96a371e7613d47eb2",
|
||||
"bytes": 191000
|
||||
},
|
||||
{
|
||||
"file": "last-sound.wav",
|
||||
"text": "세 단어 중 마지막을 고르세요. ‘오리’, ‘수리’, ‘소리’.",
|
||||
"sha256": "c2b77970b477fd05671c833daaf2fb48aace796e1da54a1f9286fca0a8b7f484",
|
||||
"bytes": 185296
|
||||
},
|
||||
{
|
||||
"file": "last-meat.wav",
|
||||
"text": "세 단어 중 마지막을 고르세요. ‘보기’, ‘고개’, ‘고기’.",
|
||||
"sha256": "f1bbcef87d1b2fda6d36ecc484c62c6f1a4a182c12e2e0ac8bb58f494809ddf8",
|
||||
"bytes": 185540
|
||||
},
|
||||
{
|
||||
"file": "last-furniture.wav",
|
||||
"text": "세 단어 중 마지막을 고르세요. ‘하구’, ‘가교’, ‘가구’.",
|
||||
"sha256": "5e625527e69a3f9a9c508cb9da26252ab621949d7ae9ff41bdd9336627234de0",
|
||||
"bytes": 185132
|
||||
},
|
||||
{
|
||||
"file": "first-apple.wav",
|
||||
"text": "세 단어 중 첫 번째를 고르세요. ‘사과’, ‘다과’, ‘사고’.",
|
||||
"sha256": "d539d03875121570650cac2a2bf800cc67e0a72effaf755e02c870f9569e5028",
|
||||
"bytes": 203904
|
||||
},
|
||||
{
|
||||
"file": "first-sea.wav",
|
||||
"text": "세 단어 중 첫 번째를 고르세요. ‘바다’, ‘사다’, ‘보다’.",
|
||||
"sha256": "2d789349b36dab9bbe784e2fcb8412704f2dd15b22ad63937bad9948720aa5fb",
|
||||
"bytes": 207002
|
||||
},
|
||||
{
|
||||
"file": "first-tree.wav",
|
||||
"text": "세 단어 중 첫 번째를 고르세요. ‘나무’, ‘나루’, ‘너무’.",
|
||||
"sha256": "af4ad056b18af0d376a1df7dda3d7b8419e76cda6ffe57dd71054692aa653fd9",
|
||||
"bytes": 203354
|
||||
},
|
||||
{
|
||||
"file": "first-hat.wav",
|
||||
"text": "세 단어 중 첫 번째를 고르세요. ‘모자’, ‘포자’, ‘모조’.",
|
||||
"sha256": "e34fd5edff5323e45f8621a2adb79ed871d1ce671bd3ac8c4a49a8c703878811",
|
||||
"bytes": 205388
|
||||
},
|
||||
{
|
||||
"file": "first-umbrella.wav",
|
||||
"text": "세 단어 중 첫 번째를 고르세요. ‘우산’, ‘부산’, ‘오산’.",
|
||||
"sha256": "4be32c725583f1579b15be4bbe110b4ab42705221a63621125aa1aa98f7f061c",
|
||||
"bytes": 210768
|
||||
},
|
||||
{
|
||||
"file": "first-market.wav",
|
||||
"text": "세 단어 중 첫 번째를 고르세요. ‘시장’, ‘지장’, ‘사장’.",
|
||||
"sha256": "37925d65ce12429905a1b185824722a34af8d77b15eb7bec3b52665b5c1fbc7c",
|
||||
"bytes": 217794
|
||||
},
|
||||
{
|
||||
"file": "first-oil.wav",
|
||||
"text": "세 단어 중 첫 번째를 고르세요. ‘기름’, ‘이름’, ‘거름’.",
|
||||
"sha256": "0991123aee956c26ca658382102c9b6d0a164fbf2dea45f07a978d2cc1fc6b80",
|
||||
"bytes": 205784
|
||||
},
|
||||
{
|
||||
"file": "first-sound.wav",
|
||||
"text": "세 단어 중 첫 번째를 고르세요. ‘소리’, ‘오리’, ‘수리’.",
|
||||
"sha256": "5b3063285cddd8f46a2c2cbbee1ecc9b64ecdbd287df76df65dec854679ec884",
|
||||
"bytes": 201840
|
||||
},
|
||||
{
|
||||
"file": "first-meat.wav",
|
||||
"text": "세 단어 중 첫 번째를 고르세요. ‘고기’, ‘보기’, ‘고개’.",
|
||||
"sha256": "acf07b6db586616e67e2841a6f122120a5b0b18543047271bd5b8c55e33786e3",
|
||||
"bytes": 201712
|
||||
},
|
||||
{
|
||||
"file": "first-furniture.wav",
|
||||
"text": "세 단어 중 첫 번째를 고르세요. ‘가구’, ‘하구’, ‘가교’.",
|
||||
"sha256": "acba37fc2641c7073210855d294eb7c6e5f3328652c606186b1b0e569e2d0bf6",
|
||||
"bytes": 203872
|
||||
},
|
||||
{
|
||||
"file": "repeat-apple.wav",
|
||||
"text": "두 번 들린 단어를 고르세요. ‘사과’, ‘다과’, ‘사과’, ‘사고’.",
|
||||
"sha256": "5fcef242c63dc7e86c02a1a5813e409e6392511aad5834510696b0d0499a5ef1",
|
||||
"bytes": 215994
|
||||
},
|
||||
{
|
||||
"file": "repeat-sea.wav",
|
||||
"text": "두 번 들린 단어를 고르세요. ‘바다’, ‘사다’, ‘바다’, ‘보다’.",
|
||||
"sha256": "ef675bfa38f4eb4abac04cc64aa2c3ec416d405f9c67646356c9a8f39fe17d21",
|
||||
"bytes": 211180
|
||||
},
|
||||
{
|
||||
"file": "repeat-tree.wav",
|
||||
"text": "두 번 들린 단어를 고르세요. ‘나무’, ‘나루’, ‘나무’, ‘너무’.",
|
||||
"sha256": "b6a1d2923d90f9dd35b324aea419daf3891b76cc8c5c9551fe5ec1140c2ab0bf",
|
||||
"bytes": 206504
|
||||
},
|
||||
{
|
||||
"file": "repeat-hat.wav",
|
||||
"text": "두 번 들린 단어를 고르세요. ‘모자’, ‘포자’, ‘모자’, ‘모조’.",
|
||||
"sha256": "32cbc9823f5af5f897416bec2c377a8559c82fd3fae66273152826dd000cdc4c",
|
||||
"bytes": 208872
|
||||
},
|
||||
{
|
||||
"file": "repeat-umbrella.wav",
|
||||
"text": "두 번 들린 단어를 고르세요. ‘우산’, ‘부산’, ‘우산’, ‘오산’.",
|
||||
"sha256": "4830662f39bc0c62ee9be89de80a44a837c50063fad8fb63129b865673de5525",
|
||||
"bytes": 220408
|
||||
},
|
||||
{
|
||||
"file": "repeat-market.wav",
|
||||
"text": "두 번 들린 단어를 고르세요. ‘시장’, ‘지장’, ‘시장’, ‘사장’.",
|
||||
"sha256": "0e146387377dc38fc10435e06e8eb8cd30a595092887bf8ee4c9d0e7b577650d",
|
||||
"bytes": 232742
|
||||
},
|
||||
{
|
||||
"file": "repeat-oil.wav",
|
||||
"text": "두 번 들린 단어를 고르세요. ‘기름’, ‘이름’, ‘기름’, ‘거름’.",
|
||||
"sha256": "94de2ef7f7d7f9132f3646c3dc09399de23b81909f3edf4bbd1c5b01fad4d8fe",
|
||||
"bytes": 216502
|
||||
},
|
||||
{
|
||||
"file": "repeat-sound.wav",
|
||||
"text": "두 번 들린 단어를 고르세요. ‘소리’, ‘오리’, ‘소리’, ‘수리’.",
|
||||
"sha256": "7f12b6f49a7b4f64af796aa4ad8cfffc85a6b39e2bc6698f74b420b74af6c7c8",
|
||||
"bytes": 205404
|
||||
},
|
||||
{
|
||||
"file": "repeat-meat.wav",
|
||||
"text": "두 번 들린 단어를 고르세요. ‘고기’, ‘보기’, ‘고기’, ‘고개’.",
|
||||
"sha256": "ba8beeb33bcbe4771aaea9b3832a4c25868f6e34e37b3e3d026e891c07b8e71a",
|
||||
"bytes": 203544
|
||||
},
|
||||
{
|
||||
"file": "repeat-furniture.wav",
|
||||
"text": "두 번 들린 단어를 고르세요. ‘가구’, ‘하구’, ‘가구’, ‘가교’.",
|
||||
"sha256": "581a94726b08b6cfd3c688f08838a05787ed902ab6d1d4a038e0ff6b34f63c3a",
|
||||
"bytes": 208274
|
||||
},
|
||||
{
|
||||
"file": "correction-apple.wav",
|
||||
"text": "정답은 ‘다과’입니다. 아니, 잘못 말했어요. 정정한 답은 ‘사과’입니다.",
|
||||
"sha256": "53d1c1b207607e610964e68134a3d35ff521b569e228366ec4eb7c03691724bb",
|
||||
"bytes": 256484
|
||||
},
|
||||
{
|
||||
"file": "correction-sea.wav",
|
||||
"text": "정답은 ‘사다’입니다. 아니, 잘못 말했어요. 정정한 답은 ‘바다’입니다.",
|
||||
"sha256": "df61f91374b9fbb5817249ae3b6cadfae914d3e97ee2c6d07366ef82080a11db",
|
||||
"bytes": 255204
|
||||
},
|
||||
{
|
||||
"file": "correction-tree.wav",
|
||||
"text": "정답은 ‘나루’입니다. 아니, 잘못 말했어요. 정정한 답은 ‘나무’입니다.",
|
||||
"sha256": "837c24b18f63a73e135511b2edd48ba12593317de3be4d225622e6d11b1a57da",
|
||||
"bytes": 251316
|
||||
},
|
||||
{
|
||||
"file": "correction-hat.wav",
|
||||
"text": "정답은 ‘포자’입니다. 아니, 잘못 말했어요. 정정한 답은 ‘모자’입니다.",
|
||||
"sha256": "00d7c21caccbbb6c80ec6218415be1b0a6683a2d509b60821d3556e43353b5dc",
|
||||
"bytes": 253208
|
||||
},
|
||||
{
|
||||
"file": "correction-umbrella.wav",
|
||||
"text": "정답은 ‘부산’입니다. 아니, 잘못 말했어요. 정정한 답은 ‘우산’입니다.",
|
||||
"sha256": "9bb3ce5b00ccc1632c37638550f329cbb6cda01864433e068f85eb7ccab86370",
|
||||
"bytes": 255400
|
||||
},
|
||||
{
|
||||
"file": "correction-market.wav",
|
||||
"text": "정답은 ‘지장’입니다. 아니, 잘못 말했어요. 정정한 답은 ‘시장’입니다.",
|
||||
"sha256": "c8152db42c956701cd5e21c588ef62aedaefa922658d4bc0fecf8243548d7054",
|
||||
"bytes": 257262
|
||||
},
|
||||
{
|
||||
"file": "correction-oil.wav",
|
||||
"text": "정답은 ‘이름’입니다. 아니, 잘못 말했어요. 정정한 답은 ‘기름’입니다.",
|
||||
"sha256": "228759e87b1c80be72ea34ff5b77cb5e4557afca1b73434ca8f6f1c2fedaa836",
|
||||
"bytes": 247864
|
||||
},
|
||||
{
|
||||
"file": "correction-sound.wav",
|
||||
"text": "정답은 ‘오리’입니다. 아니, 잘못 말했어요. 정정한 답은 ‘소리’입니다.",
|
||||
"sha256": "24f2d52bb865c71fc4735a4aebd69ce0e429a9f68646e73e77adababbe34af93",
|
||||
"bytes": 250170
|
||||
},
|
||||
{
|
||||
"file": "correction-meat.wav",
|
||||
"text": "정답은 ‘보기’입니다. 아니, 잘못 말했어요. 정정한 답은 ‘고기’입니다.",
|
||||
"sha256": "821caf897ddab107df8435b00b686bf9223e043c91a311edcaa0c3c5eb8c6511",
|
||||
"bytes": 253432
|
||||
},
|
||||
{
|
||||
"file": "correction-furniture.wav",
|
||||
"text": "정답은 ‘하구’입니다. 아니, 잘못 말했어요. 정정한 답은 ‘가구’입니다.",
|
||||
"sha256": "5d69426f3319fa435ee60b234540dd8d9a07f00900177f03da2770f44511ade8",
|
||||
"bytes": 254342
|
||||
},
|
||||
{
|
||||
"file": "middle-apple.wav",
|
||||
"text": "세 단어 중 가운데를 고르세요. ‘다과’, ‘사과’, ‘사고’.",
|
||||
"sha256": "0ecc7a7d27508f73c9064a35609c922bbdd6fce8ebfc155e74f7b78d4e897dae",
|
||||
"bytes": 191056
|
||||
},
|
||||
{
|
||||
"file": "middle-sea.wav",
|
||||
"text": "세 단어 중 가운데를 고르세요. ‘사다’, ‘바다’, ‘보다’.",
|
||||
"sha256": "c7828af4e64745d89a6f23fda6c86efb76febe379bab0901c2972a4569947604",
|
||||
"bytes": 194176
|
||||
},
|
||||
{
|
||||
"file": "middle-tree.wav",
|
||||
"text": "세 단어 중 가운데를 고르세요. ‘나루’, ‘나무’, ‘너무’.",
|
||||
"sha256": "756d13453c7e13dcfaa65c8cb3497ac8d3a5d12bedb56dcd74e7f1c022392416",
|
||||
"bytes": 190516
|
||||
},
|
||||
{
|
||||
"file": "middle-hat.wav",
|
||||
"text": "세 단어 중 가운데를 고르세요. ‘포자’, ‘모자’, ‘모조’.",
|
||||
"sha256": "6ad5ec1e2c2c0de568c55a0c1f0e8361885725a2515cf396c8fe5d2106ae22d0",
|
||||
"bytes": 192548
|
||||
},
|
||||
{
|
||||
"file": "middle-umbrella.wav",
|
||||
"text": "세 단어 중 가운데를 고르세요. ‘부산’, ‘우산’, ‘오산’.",
|
||||
"sha256": "a507896dd50f98909c6a9fc0a4bfddfde5c975836e494cd9b7f40b69bc8ec33b",
|
||||
"bytes": 196102
|
||||
},
|
||||
{
|
||||
"file": "middle-market.wav",
|
||||
"text": "세 단어 중 가운데를 고르세요. ‘지장’, ‘시장’, ‘사장’.",
|
||||
"sha256": "900024616e512ea6777d08f80e3e2c83815ea1f03b6eeb537d212995474e1048",
|
||||
"bytes": 204956
|
||||
},
|
||||
{
|
||||
"file": "middle-oil.wav",
|
||||
"text": "세 단어 중 가운데를 고르세요. ‘이름’, ‘기름’, ‘거름’.",
|
||||
"sha256": "c42389a5ccd3b39a5877a38e647a6abbec6ff6a7eabf3d4c95c0507fa65d6d2f",
|
||||
"bytes": 194772
|
||||
},
|
||||
{
|
||||
"file": "middle-sound.wav",
|
||||
"text": "세 단어 중 가운데를 고르세요. ‘오리’, ‘소리’, ‘수리’.",
|
||||
"sha256": "b05ae2042bc973c3d1873fe15b5bc7f2af7e803794315023486efa788048342c",
|
||||
"bytes": 188984
|
||||
},
|
||||
{
|
||||
"file": "middle-meat.wav",
|
||||
"text": "세 단어 중 가운데를 고르세요. ‘보기’, ‘고기’, ‘고개’.",
|
||||
"sha256": "d54d6f9b4bd90b840443b9e0b0390a93909eeb81c37af6a9b57ce545bede532d",
|
||||
"bytes": 188870
|
||||
},
|
||||
{
|
||||
"file": "middle-furniture.wav",
|
||||
"text": "세 단어 중 가운데를 고르세요. ‘하구’, ‘가구’, ‘가교’.",
|
||||
"sha256": "d9318ef33ae1c60630ddda5abeefcbe43626d8f8a9abd5d62efd132eeb77c8fc",
|
||||
"bytes": 191024
|
||||
},
|
||||
{
|
||||
"file": "message-apple.wav",
|
||||
"text": "초록 불이면 앞 단어, 빨간 불이면 뒤 단어입니다. ‘다과’, ‘사과’. 지금은 빨간 불입니다.",
|
||||
"sha256": "3867563d5acd2530c72cbe6f98ca2b463ec0c92285069c99c8ba084c45aabfd6",
|
||||
"bytes": 316834
|
||||
},
|
||||
{
|
||||
"file": "message-sea.wav",
|
||||
"text": "초록 불이면 앞 단어, 빨간 불이면 뒤 단어입니다. ‘사다’, ‘바다’. 지금은 빨간 불입니다.",
|
||||
"sha256": "b7d8d89d93247eca9aec124f80bf6328d6d88511d05b513ce6d9fa32b3211848",
|
||||
"bytes": 317816
|
||||
},
|
||||
{
|
||||
"file": "message-tree.wav",
|
||||
"text": "초록 불이면 앞 단어, 빨간 불이면 뒤 단어입니다. ‘나루’, ‘나무’. 지금은 빨간 불입니다.",
|
||||
"sha256": "9539e5ee87068e241598db2e4fbacb240daa011a2238c9864da8ffde6b644918",
|
||||
"bytes": 315930
|
||||
},
|
||||
{
|
||||
"file": "message-hat.wav",
|
||||
"text": "초록 불이면 앞 단어, 빨간 불이면 뒤 단어입니다. ‘포자’, ‘모자’. 지금은 빨간 불입니다.",
|
||||
"sha256": "ccbba6a22c9cbc1231f45fbd7420c6257ac22ac72de8e8c0c97f1cc31bb2b16e",
|
||||
"bytes": 317258
|
||||
},
|
||||
{
|
||||
"file": "message-umbrella.wav",
|
||||
"text": "초록 불이면 앞 단어, 빨간 불이면 뒤 단어입니다. ‘부산’, ‘우산’. 지금은 빨간 불입니다.",
|
||||
"sha256": "e980f4476f7275cc5ae24e7ce0e6d9c1e6db027f7cbd1eb39cc5bc4bc07cbf6e",
|
||||
"bytes": 320532
|
||||
},
|
||||
{
|
||||
"file": "message-market.wav",
|
||||
"text": "초록 불이면 앞 단어, 빨간 불이면 뒤 단어입니다. ‘지장’, ‘시장’. 지금은 빨간 불입니다.",
|
||||
"sha256": "35432a3ed8dd1e15894ace5aad6f5a66cf28509ba92b8ee47bcaae424cb25ba1",
|
||||
"bytes": 325564
|
||||
},
|
||||
{
|
||||
"file": "message-oil.wav",
|
||||
"text": "초록 불이면 앞 단어, 빨간 불이면 뒤 단어입니다. ‘이름’, ‘기름’. 지금은 빨간 불입니다.",
|
||||
"sha256": "814fc749006ed040de58b5236a8d92f0d79683c8eea3b9d095386344f41a47bd",
|
||||
"bytes": 317786
|
||||
},
|
||||
{
|
||||
"file": "message-sound.wav",
|
||||
"text": "초록 불이면 앞 단어, 빨간 불이면 뒤 단어입니다. ‘오리’, ‘소리’. 지금은 빨간 불입니다.",
|
||||
"sha256": "e25c867e6c18d906c010816475253d2b10aa3cc4192b5551ba78055d65c461c8",
|
||||
"bytes": 313270
|
||||
},
|
||||
{
|
||||
"file": "message-meat.wav",
|
||||
"text": "초록 불이면 앞 단어, 빨간 불이면 뒤 단어입니다. ‘보기’, ‘고기’. 지금은 빨간 불입니다.",
|
||||
"sha256": "f1863e1527b7714ae64f5d752b542e8768b8ed89b5885012283f7ca20742ee00",
|
||||
"bytes": 314464
|
||||
},
|
||||
{
|
||||
"file": "message-furniture.wav",
|
||||
"text": "초록 불이면 앞 단어, 빨간 불이면 뒤 단어입니다. ‘하구’, ‘가구’. 지금은 빨간 불입니다.",
|
||||
"sha256": "43f87d0e3d92bd132f9ea46e024b9a940736b7399e899866ed42af367a550f78",
|
||||
"bytes": 316152
|
||||
},
|
||||
{
|
||||
"file": "mission-apple.wav",
|
||||
"text": "오른쪽 표지는 ‘사과’, 왼쪽 표지는 ‘다과’입니다.",
|
||||
"sha256": "36697151a1a57645f5acd9fcca2d13bffa21937e1bbcde08ab2d8d485730145a",
|
||||
"bytes": 166540
|
||||
},
|
||||
{
|
||||
"file": "mission-sea.wav",
|
||||
"text": "오른쪽 표지는 ‘바다’, 왼쪽 표지는 ‘사다’입니다.",
|
||||
"sha256": "2741f404e39ec64af7f73452f82c68b3ae1d377e9f40a586034f9b147fbfb114",
|
||||
"bytes": 165122
|
||||
},
|
||||
{
|
||||
"file": "mission-tree.wav",
|
||||
"text": "오른쪽 표지는 ‘나무’, 왼쪽 표지는 ‘나루’입니다.",
|
||||
"sha256": "8a7bb2c795d8877433be2621b69a48c2b6c5c1e192c094c01257fb93eb5d9449",
|
||||
"bytes": 160834
|
||||
},
|
||||
{
|
||||
"file": "mission-hat.wav",
|
||||
"text": "오른쪽 표지는 ‘모자’, 왼쪽 표지는 ‘포자’입니다.",
|
||||
"sha256": "26dfa26bd8dcb9d63c231dfc37bf25970f4a8dadcaa40347dd15974887e948b1",
|
||||
"bytes": 163102
|
||||
},
|
||||
{
|
||||
"file": "mission-umbrella.wav",
|
||||
"text": "오른쪽 표지는 ‘우산’, 왼쪽 표지는 ‘부산’입니다.",
|
||||
"sha256": "79be98918c3fb4e5e4e2e51b2bfa5e5aad6c600478ae1a34c055b16ce71d5264",
|
||||
"bytes": 167480
|
||||
},
|
||||
{
|
||||
"file": "mission-market.wav",
|
||||
"text": "오른쪽 표지는 ‘시장’, 왼쪽 표지는 ‘지장’입니다.",
|
||||
"sha256": "8f18144a91072be37dc31a161fe6e9bb1980ab36af0edee8d7a359397b8bb8ac",
|
||||
"bytes": 170724
|
||||
},
|
||||
{
|
||||
"file": "mission-oil.wav",
|
||||
"text": "오른쪽 표지는 ‘기름’, 왼쪽 표지는 ‘이름’입니다.",
|
||||
"sha256": "1ceabc58f445f7bd5609b2f9de80b309ad64d11c888c7261cf84315a7637a748",
|
||||
"bytes": 161758
|
||||
},
|
||||
{
|
||||
"file": "mission-sound.wav",
|
||||
"text": "오른쪽 표지는 ‘소리’, 왼쪽 표지는 ‘오리’입니다.",
|
||||
"sha256": "6651b14caf4e54069730f137e5d8c3c1e5a9c66aa72f15623cc442edb967cadb",
|
||||
"bytes": 160162
|
||||
},
|
||||
{
|
||||
"file": "mission-meat.wav",
|
||||
"text": "오른쪽 표지는 ‘고기’, 왼쪽 표지는 ‘보기’입니다.",
|
||||
"sha256": "5d2ab3071fd27e850d99c50ad37905096ef28267b660a35992559bdc126c4931",
|
||||
"bytes": 162626
|
||||
},
|
||||
{
|
||||
"file": "mission-furniture.wav",
|
||||
"text": "오른쪽 표지는 ‘가구’, 왼쪽 표지는 ‘하구’입니다.",
|
||||
"sha256": "080307bb46bb47378c0c03437d9ef44118a5d4ea17b2b6d70e5cbc710c71ba78",
|
||||
"bytes": 163884
|
||||
}
|
||||
]
|
||||
},
|
||||
"head": "1c0069c367f6e108d3f67a2a0d044399dd0ef2bd",
|
||||
"branch": "fix/v0.1.1-neural-voice"
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
ADDED .agent/RESULT-v0.1.1.md
|
||||
ADDED .agent/evidence-v0.1.1/00-audio-venv.log
|
||||
ADDED .agent/evidence-v0.1.1/00-npm-ci.log
|
||||
ADDED .agent/evidence-v0.1.1/01-version-docs-red.log
|
||||
ADDED .agent/evidence-v0.1.1/02-assets-red.log
|
||||
ADDED .agent/evidence-v0.1.1/03-generator-red.log
|
||||
ADDED .agent/evidence-v0.1.1/04-generator-additional-red.log
|
||||
ADDED .agent/evidence-v0.1.1/05-generator-green.log
|
||||
ADDED .agent/evidence-v0.1.1/06-audio-generate.log
|
||||
ADDED .agent/evidence-v0.1.1/07-format.log
|
||||
ADDED .agent/evidence-v0.1.1/08-version-docs-green.log
|
||||
ADDED .agent/evidence-v0.1.1/09-lint.log
|
||||
ADDED .agent/evidence-v0.1.1/10-audit.log
|
||||
ADDED .agent/evidence-v0.1.1/11-full-test.log
|
||||
ADDED .agent/evidence-v0.1.1/12-independent-audio.log
|
||||
ADDED .agent/evidence-v0.1.1/13-build.log
|
||||
ADDED .agent/evidence-v0.1.1/14-browser.log
|
||||
ADDED .agent/evidence-v0.1.1/15-browser-audio.log
|
||||
ADDED .agent/evidence-v0.1.1/16-final-lint.log
|
||||
ADDED .agent/evidence-v0.1.1/17-security-history.json
|
||||
ADDED .agent/evidence-v0.1.1/18-environment.log
|
||||
ADDED .agent/evidence-v0.1.1/19-final-integrity.json
|
||||
ADDED .agent/evidence-v0.1.1/audio-integrity.json
|
||||
ADDED .agent/evidence-v0.1.1/baseline.json
|
||||
ADDED .agent/evidence-v0.1.1/browser-audio-integrity.json
|
||||
ADDED .agent/evidence-v0.1.1/changed-files.txt
|
||||
ADDED .agent/evidence-v0.1.1/desktop-game.png
|
||||
ADDED .agent/evidence-v0.1.1/desktop-heading.png
|
||||
ADDED .agent/evidence-v0.1.1/desktop-home.png
|
||||
ADDED .agent/evidence-v0.1.1/desktop-results.png
|
||||
ADDED .agent/evidence-v0.1.1/mobile-game.png
|
||||
ADDED .agent/evidence-v0.1.1/mobile-heading.png
|
||||
ADDED .agent/evidence-v0.1.1/mobile-home.png
|
||||
ADDED .agent/evidence-v0.1.1/mobile-results.png
|
||||
ADDED .agent/evidence-v0.1.1/verify_audio.py
|
||||
ADDED .agent/evidence-v0.1.1/verify_browser.mjs
|
||||
ADDED requirements-audio.txt
|
||||
ADDED scripts/neural_audio.py
|
||||
ADDED tests/generator.test.ts
|
||||
ADDED tests/neural-release.test.ts
|
||||
ADDED tests/python/test_neural_audio.py
|
||||
MODIFIED .gitignore
|
||||
MODIFIED LICENSE
|
||||
MODIFIED README.md
|
||||
MODIFIED docs/ARCHITECTURE.md
|
||||
MODIFIED docs/AUDIO_PROVENANCE.md
|
||||
MODIFIED docs/DEPLOYMENT.md
|
||||
MODIFIED eslint.config.js
|
||||
MODIFIED index.html
|
||||
MODIFIED package-lock.json
|
||||
MODIFIED package.json
|
||||
MODIFIED public/audio/correction-apple.wav
|
||||
MODIFIED public/audio/correction-furniture.wav
|
||||
MODIFIED public/audio/correction-hat.wav
|
||||
MODIFIED public/audio/correction-market.wav
|
||||
MODIFIED public/audio/correction-meat.wav
|
||||
MODIFIED public/audio/correction-oil.wav
|
||||
MODIFIED public/audio/correction-sea.wav
|
||||
MODIFIED public/audio/correction-sound.wav
|
||||
MODIFIED public/audio/correction-tree.wav
|
||||
MODIFIED public/audio/correction-umbrella.wav
|
||||
MODIFIED public/audio/first-apple.wav
|
||||
MODIFIED public/audio/first-furniture.wav
|
||||
MODIFIED public/audio/first-hat.wav
|
||||
MODIFIED public/audio/first-market.wav
|
||||
MODIFIED public/audio/first-meat.wav
|
||||
MODIFIED public/audio/first-oil.wav
|
||||
MODIFIED public/audio/first-sea.wav
|
||||
MODIFIED public/audio/first-sound.wav
|
||||
MODIFIED public/audio/first-tree.wav
|
||||
MODIFIED public/audio/first-umbrella.wav
|
||||
MODIFIED public/audio/intro.wav
|
||||
MODIFIED public/audio/last-apple.wav
|
||||
MODIFIED public/audio/last-furniture.wav
|
||||
MODIFIED public/audio/last-hat.wav
|
||||
MODIFIED public/audio/last-market.wav
|
||||
MODIFIED public/audio/last-meat.wav
|
||||
MODIFIED public/audio/last-oil.wav
|
||||
MODIFIED public/audio/last-sea.wav
|
||||
MODIFIED public/audio/last-sound.wav
|
||||
MODIFIED public/audio/last-tree.wav
|
||||
MODIFIED public/audio/last-umbrella.wav
|
||||
MODIFIED public/audio/luck-apple.wav
|
||||
MODIFIED public/audio/luck-furniture.wav
|
||||
MODIFIED public/audio/luck-hat.wav
|
||||
MODIFIED public/audio/luck-market.wav
|
||||
MODIFIED public/audio/luck-meat.wav
|
||||
MODIFIED public/audio/luck-oil.wav
|
||||
MODIFIED public/audio/luck-sea.wav
|
||||
MODIFIED public/audio/luck-sound.wav
|
||||
MODIFIED public/audio/luck-tree.wav
|
||||
MODIFIED public/audio/luck-umbrella.wav
|
||||
MODIFIED public/audio/manifest.json
|
||||
MODIFIED public/audio/message-apple.wav
|
||||
MODIFIED public/audio/message-furniture.wav
|
||||
MODIFIED public/audio/message-hat.wav
|
||||
MODIFIED public/audio/message-market.wav
|
||||
MODIFIED public/audio/message-meat.wav
|
||||
MODIFIED public/audio/message-oil.wav
|
||||
MODIFIED public/audio/message-sea.wav
|
||||
MODIFIED public/audio/message-sound.wav
|
||||
MODIFIED public/audio/message-tree.wav
|
||||
MODIFIED public/audio/message-umbrella.wav
|
||||
MODIFIED public/audio/middle-apple.wav
|
||||
MODIFIED public/audio/middle-furniture.wav
|
||||
MODIFIED public/audio/middle-hat.wav
|
||||
MODIFIED public/audio/middle-market.wav
|
||||
MODIFIED public/audio/middle-meat.wav
|
||||
MODIFIED public/audio/middle-oil.wav
|
||||
MODIFIED public/audio/middle-sea.wav
|
||||
MODIFIED public/audio/middle-sound.wav
|
||||
MODIFIED public/audio/middle-tree.wav
|
||||
MODIFIED public/audio/middle-umbrella.wav
|
||||
MODIFIED public/audio/mission-apple.wav
|
||||
MODIFIED public/audio/mission-furniture.wav
|
||||
MODIFIED public/audio/mission-hat.wav
|
||||
MODIFIED public/audio/mission-market.wav
|
||||
MODIFIED public/audio/mission-meat.wav
|
||||
MODIFIED public/audio/mission-oil.wav
|
||||
MODIFIED public/audio/mission-sea.wav
|
||||
MODIFIED public/audio/mission-sound.wav
|
||||
MODIFIED public/audio/mission-tree.wav
|
||||
MODIFIED public/audio/mission-umbrella.wav
|
||||
MODIFIED public/audio/password-apple.wav
|
||||
MODIFIED public/audio/password-furniture.wav
|
||||
MODIFIED public/audio/password-hat.wav
|
||||
MODIFIED public/audio/password-market.wav
|
||||
MODIFIED public/audio/password-meat.wav
|
||||
MODIFIED public/audio/password-oil.wav
|
||||
MODIFIED public/audio/password-sea.wav
|
||||
MODIFIED public/audio/password-sound.wav
|
||||
MODIFIED public/audio/password-tree.wav
|
||||
MODIFIED public/audio/password-umbrella.wav
|
||||
MODIFIED public/audio/remember-apple.wav
|
||||
MODIFIED public/audio/remember-furniture.wav
|
||||
MODIFIED public/audio/remember-hat.wav
|
||||
MODIFIED public/audio/remember-market.wav
|
||||
MODIFIED public/audio/remember-meat.wav
|
||||
MODIFIED public/audio/remember-oil.wav
|
||||
MODIFIED public/audio/remember-sea.wav
|
||||
MODIFIED public/audio/remember-sound.wav
|
||||
MODIFIED public/audio/remember-tree.wav
|
||||
MODIFIED public/audio/remember-umbrella.wav
|
||||
MODIFIED public/audio/repeat-apple.wav
|
||||
MODIFIED public/audio/repeat-furniture.wav
|
||||
MODIFIED public/audio/repeat-hat.wav
|
||||
MODIFIED public/audio/repeat-market.wav
|
||||
MODIFIED public/audio/repeat-meat.wav
|
||||
MODIFIED public/audio/repeat-oil.wav
|
||||
MODIFIED public/audio/repeat-sea.wav
|
||||
MODIFIED public/audio/repeat-sound.wav
|
||||
MODIFIED public/audio/repeat-tree.wav
|
||||
MODIFIED public/audio/repeat-umbrella.wav
|
||||
MODIFIED scripts/generate_audio.py
|
||||
MODIFIED src/App.tsx
|
||||
MODIFIED tests/App.test.tsx
|
||||
MODIFIED tests/assets.test.ts
|
||||
MODIFIED tests/browser/game.spec.ts
|
||||
MODIFIED tests/browser/ui.spec.ts
|
||||
USER INPUT .agent/ACCEPTANCE-v0.1.1.md
|
||||
USER INPUT .agent/TASK-v0.1.1.md
|
||||
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 138 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 59 KiB |
@@ -0,0 +1,71 @@
|
||||
"""생성기 함수를 재사용하지 않는 v0.1.1 인수 검사: 원문·이전 해시·PCM·FFmpeg."""
|
||||
from array import array
|
||||
import hashlib
|
||||
import json
|
||||
import math
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
import wave
|
||||
|
||||
root = Path(__file__).resolve().parents[2]
|
||||
evidence = root / ".agent/evidence-v0.1.1"
|
||||
manifest = json.loads((root / "public/audio/manifest.json").read_text())
|
||||
baseline = json.loads((evidence / "baseline.json").read_text())
|
||||
old = {entry["file"]: entry for entry in baseline["audio"]["files"]}
|
||||
expected = json.loads(subprocess.check_output([
|
||||
"node", "--experimental-strip-types", "--input-type=module", "-e",
|
||||
"import {INTRO,PATTERNS,WORDS,renderSentence} from './src/content.ts'; "
|
||||
"console.log(JSON.stringify([{file:'intro.wav',text:INTRO},"
|
||||
"...PATTERNS.flatMap(p=>WORDS.map(w=>({file:p.id+'-'+w.id+'.wav',text:renderSentence(p,w)})))]));"
|
||||
], cwd=root, text=True))
|
||||
assert manifest["version"] == "0.1.1"
|
||||
assert manifest["provider"] == "Microsoft Edge online TTS"
|
||||
assert manifest["voice"] == "ko-KR-HyunsuMultilingualNeural"
|
||||
assert manifest["rate"] == "-6%" and manifest["pitch"] == "-4Hz"
|
||||
assert manifest["toolVersions"]["edge-tts"] == "7.3.1"
|
||||
assert [{"file": e["file"], "text": e["text"]} for e in manifest["files"]] == expected
|
||||
assert len(expected) == 101
|
||||
assert {p.name for p in (root / "public/audio").iterdir()} == {e["file"] for e in expected} | {"manifest.json"}
|
||||
rows = []
|
||||
for entry in manifest["files"]:
|
||||
path = root / "public/audio" / entry["file"]
|
||||
data = path.read_bytes()
|
||||
digest = hashlib.sha256(data).hexdigest()
|
||||
assert digest == entry["sha256"] and digest != old[entry["file"]]["sha256"]
|
||||
assert len(data) == entry["bytes"]
|
||||
with wave.open(str(path), "rb") as stream:
|
||||
assert (stream.getframerate(), stream.getnchannels(), stream.getsampwidth(), stream.getcomptype()) == (24000, 1, 2, "NONE")
|
||||
duration = stream.getnframes()/24000
|
||||
assert 1 <= duration <= 20 and duration == entry["duration"]
|
||||
samples = array("h", stream.readframes(stream.getnframes()))
|
||||
if sys.byteorder != "little":
|
||||
samples.byteswap()
|
||||
rms = math.sqrt(sum(x*x for x in samples)/len(samples))/32768
|
||||
peak = max(abs(x) for x in samples)/32768
|
||||
assert rms > 100/32768 and peak < 32767/32768
|
||||
assert peak/rms*0.03*2 < 0.8
|
||||
assert abs(entry["rms"]-rms) < 1e-12 and abs(entry["peak"]-peak) < 1e-12
|
||||
probe = json.loads(subprocess.check_output([
|
||||
"ffprobe", "-v", "error", "-show_entries",
|
||||
"stream=codec_name,sample_fmt,sample_rate,channels,bits_per_sample,duration", "-of", "json", str(path)
|
||||
], text=True))["streams"]
|
||||
assert len(probe) == 1
|
||||
stream = probe[0]
|
||||
assert (stream["codec_name"], stream["sample_fmt"], stream["sample_rate"], stream["channels"], stream["bits_per_sample"]) == ("pcm_s16le", "s16", "24000", 1, 16)
|
||||
assert abs(float(stream["duration"])-duration) < 1e-5
|
||||
subprocess.run(["ffmpeg", "-v", "error", "-xerror", "-i", str(path), "-f", "null", "-"], check=True, capture_output=True)
|
||||
rows.append({"file": path.name, "sha256": digest, "bytes": len(data), "duration": duration,
|
||||
"rms": rms, "peak": peak, "ffprobe": stream, "newVsV01": True, "ffmpegDecoded": True})
|
||||
print(f"PASS {path.name}: {duration:.3f}s, RMS={rms:.6f}, peak={peak:.6f}", flush=True)
|
||||
assert len({r["sha256"] for r in rows}) == 101
|
||||
assert sum(r["bytes"] for r in rows) < 48*1024*1024
|
||||
for path, digest in baseline["historical"].items():
|
||||
assert hashlib.sha256((root / path).read_bytes()).hexdigest() == digest, path
|
||||
summary = {"count": len(rows), "newVsV01": 101, "uniqueHashes": 101, "bytes": sum(r["bytes"] for r in rows),
|
||||
"durationRange": [min(r["duration"] for r in rows), max(r["duration"] for r in rows)],
|
||||
"rmsRange": [min(r["rms"] for r in rows), max(r["rms"] for r in rows)],
|
||||
"peakRange": [min(r["peak"] for r in rows), max(r["peak"] for r in rows)],
|
||||
"historicalUnchanged": len(baseline["historical"]), "files": rows}
|
||||
(evidence / "audio-integrity.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2)+"\n")
|
||||
print(json.dumps({k:v for k,v in summary.items() if k != "files"}, indent=2))
|
||||
@@ -0,0 +1,64 @@
|
||||
/* global OfflineAudioContext */
|
||||
// 실제 Chrome의 WAV 디코더로 101개를 검증한다. 재생·UI 흐름은 전체
|
||||
// Playwright suite가 별도 담당하며 이 인수 검사는 모의 AudioContext를 쓰지 않는다.
|
||||
import assert from 'node:assert/strict';
|
||||
import { writeFileSync } from 'node:fs';
|
||||
import { spawn } from 'node:child_process';
|
||||
import { chromium } from '@playwright/test';
|
||||
|
||||
const server = spawn(process.execPath, ['node_modules/vite/bin/vite.js', 'preview', '--host', '127.0.0.1', '--port', '4174', '--strictPort'], { stdio: 'ignore' });
|
||||
const base = 'http://127.0.0.1:4174';
|
||||
let browser;
|
||||
try {
|
||||
for (let i = 0; ; i++) {
|
||||
try { if ((await fetch(base)).ok) break; } catch { /* localhost 준비만 기다린다. */ }
|
||||
assert(i < 100, 'preview startup failed');
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
}
|
||||
browser = await chromium.launch({ executablePath: '/usr/bin/google-chrome', chromiumSandbox: true });
|
||||
const sandbox = await browser.newPage();
|
||||
await sandbox.goto('chrome://sandbox');
|
||||
const sandboxStatus = await sandbox.locator('body').innerText();
|
||||
console.log('SANDBOX STATUS\n' + sandboxStatus);
|
||||
assert.match(sandboxStatus, /Seccomp-BPF sandbox\s+Yes/);
|
||||
await sandbox.close();
|
||||
const page = await browser.newPage();
|
||||
const external = [], errors = [];
|
||||
page.on('request', r => { if (!r.url().startsWith(base + '/')) external.push(r.url()); });
|
||||
page.on('pageerror', e => errors.push(e.message));
|
||||
await page.goto(base);
|
||||
assert.equal(await page.title(), '단어를 맞춰라 · Find-Word v0.1.1');
|
||||
assert.equal(await page.locator('.version').innerText(), 'v0.1.1');
|
||||
const result = await page.evaluate(async () => {
|
||||
const manifest = await (await fetch('/audio/manifest.json')).json();
|
||||
const context = new OfflineAudioContext(1, 1, 24000);
|
||||
const rows = [];
|
||||
for (const entry of manifest.files) {
|
||||
const response = await fetch('/audio/' + entry.file);
|
||||
if (!response.ok) throw Error(entry.file + ': HTTP failure');
|
||||
const bytes = await response.arrayBuffer();
|
||||
const digest = Array.from(new Uint8Array(await crypto.subtle.digest('SHA-256', bytes)), b => b.toString(16).padStart(2, '0')).join('');
|
||||
if (digest !== entry.sha256 || bytes.byteLength !== entry.bytes) throw Error(entry.file + ': integrity failure');
|
||||
const buffer = await context.decodeAudioData(bytes);
|
||||
let power = 0, peak = 0;
|
||||
for (const x of buffer.getChannelData(0)) { power += x*x; peak = Math.max(peak, Math.abs(x)); }
|
||||
if (buffer.sampleRate !== 24000 || buffer.numberOfChannels !== 1 || Math.abs(buffer.duration-entry.duration)>1e-9)
|
||||
throw Error(entry.file + ': decode format/duration mismatch');
|
||||
const rms = Math.sqrt(power/buffer.length);
|
||||
if (rms <= 100/32768 || peak >= 32767/32768) throw Error(entry.file + ': signal failure');
|
||||
rows.push({ file: entry.file, sha256: digest, bytes: entry.bytes, sampleRate: buffer.sampleRate,
|
||||
channels: buffer.numberOfChannels, duration: buffer.duration, rms, peak });
|
||||
}
|
||||
return { version: manifest.version, voice: manifest.voice, files: rows };
|
||||
});
|
||||
assert.equal(result.version, '0.1.1');
|
||||
assert.equal(result.voice, 'ko-KR-HyunsuMultilingualNeural');
|
||||
assert.equal(result.files.length, 101);
|
||||
assert.deepEqual(external, []);
|
||||
assert.deepEqual(errors, []);
|
||||
writeFileSync('.agent/evidence-v0.1.1/browser-audio-integrity.json', JSON.stringify({ chrome: browser.version(), sandboxStatus, external, errors, ...result }, null, 2)+'\n');
|
||||
console.log('PASS: sandboxed Chrome decoded 101/101 WAVs at 24kHz mono; hashes, bytes, duration, RMS, peak verified; external requests=0, JS errors=0.');
|
||||
} finally {
|
||||
await browser?.close();
|
||||
server.kill('SIGTERM');
|
||||
}
|
||||