14 lines
1.2 KiB
Markdown
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.
|