tts-voice-creator-clone-and.../architecture/voice-provenance.md
mARTin-B78 781bf6e7f2 feat(voices): consent and provenance field per voice
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 16:39:32 +02:00

14 lines
1.2 KiB
Markdown

# Voice provenance and consent
Data: `provenance` object in `<voice>.meta.json`: `basis` (own_voice | consented | licensed | public_domain | unknown), `source`, `licence`, `note`, `recorded_consent` (original filename of the consent clip, set only by the upload route), `set_at` (UTC ISO). Absent means `unknown`.
Validation: `core/provenance.py` (`validate_provenance`) at the API boundary and again in `_validate_voice_meta` on every meta save: enum, length caps (source 500, licence 300, note 1000), control characters stripped, URL-looking sources must be http(s) without credentials.
API: `PUT /api/voices/{id}/provenance`; `POST|GET /api/voices/{id}/consent-recording` (audio ext + audio MIME, 10 MB cap, atomic write to `<voice>.consent`, served with `nosniff`/no-store). The clip is part of the voice package (`_voice_package_paths`), so rename/move/trash carry it.
Imports: `quick-import-voice` sets `provenance` via `import_provenance(page_url or audio_url)`; basis stays `unknown`.
UI: `static/js/voice-inspector.js` ("Source & consent" panel, `provenanceBadge`), list badge in `voice-library.js`.
Not done: gating generation/agentic use on basis (see TODO.md); consent clip is not cryptographically bound to the voice.