foley.licensing#

License policy for foley: the license_id -> flag-set SSOT, flag derivation (with per-source overrides), and the fail-closed candidate keep() gate.

Stdlib-only (imports only foley.base). The dependency direction is one-way: licensing -> base.

The two operational vs copyright flags are DISTINCT and must not be conflated:

  • redistribute_standalone_ok is a COPYRIGHT question (may the raw file be re-exposed standalone?).

  • cache_bytes_ok is a TOS/OPERATIONAL question (may foley persist the bytes at all?).

E.g. Freesound CC0 is legally redistributable yet its API TOS forbids caching, so the Freesound adapter passes overrides={'cache_bytes_ok': False} — the item is redistributable but stored by-reference.

Module Attributes

DEFAULT_INTENDED_USE

The ONE rights intent every verb and surface defaults to (#63, maintainer decision 2026-10-03): commercial publishing, attributable.

UNKNOWN_LICENSE_FLAGS

Fail-closed fallback for unknown / Proprietary-* license ids (all False, cap None).

LICENSE_FLAGS

license_id -> default flag set (report 07 §8.1 seed table).

CC_VERSIONS

The CC versions foley has rows for (Freesound, FSD50K, Clotho and Wikimedia use these).

DEFAULT_CC_VERSION

The version assumed when a source gives a CC family with no version at all (Freesound's search labels: "Attribution").

UNKNOWN_LICENSE_META

Fail-closed display fallback for unknown / Proprietary-* license ids.

LICENSE_META

license_id -> display name + canonical URL (one row per LICENSE_FLAGS key).

AI_TRAINING_SCOPES

The ai_training_scope values (None = no narrowing beyond ai_training_ok).

GEN_AI_PREFERENCE_SCOPES

Freesound gen_ai_preference -> (ai_training_ok override, ai_training_scope).

Functions

ai_scope_from_gen_ai_preference(preference)

Map a Freesound gen_ai_preference to (ai_training_ok override, scope).

ai_use_permitted(record, *, ...)

Whether AI use of the sound (CLAP-embedding it counts) is allowed here.

apply_license_flags(record, *[, overrides])

Populate record's eight derived flags from its license_id (+ overrides), in place, and return it.

derive_license_flags(license_id, *[, overrides])

Look up the flag set for a license_id (fail-closed fallback), then apply per-source overrides.

intended_use_for([intended_use, commercial_ok])

The rights intent a verb runs under — every verb and surface resolves it here (#63).

keep(record, intended_use)

Fail-closed candidate license gate (report 07 §8.2).

keep_sound(sound_record, intended_use)

Convenience: apply keep() to a SoundRecord's nested license.

license_id_from_cc_url(url)

Map a Creative-Commons license URL or label to (license_id, verified).

license_meta(license_id)

Return the display LicenseMeta for license_id (fail-closed fallback).

Classes

LicenseFlags([commercial_ok, ...])

The eight derivable flags for one license_id (the table row type).

LicenseMeta(display_name[, url])

Human-facing display metadata for one license_id (name + canonical URL).

foley.licensing.AI_TRAINING_SCOPES: tuple[str, ...] = ('none', 'open_source_only', 'nc_open_source_only')#

The ai_training_scope values (None = no narrowing beyond ai_training_ok).

foley.licensing.CC_VERSIONS: tuple[str, ...] = ('2.0', '2.5', '3.0', '4.0')#

The CC versions foley has rows for (Freesound, FSD50K, Clotho and Wikimedia use these).

foley.licensing.DEFAULT_CC_VERSION = '4.0'#

The version assumed when a source gives a CC family with no version at all (Freesound’s search labels: "Attribution"). Rights are the same across versions; only the credit’s version is a guess, so the record keeps the label it was given.

foley.licensing.DEFAULT_INTENDED_USE = IntendedUse(commercial=True, publish=True, redistribute_standalone=False, will_train=False, can_attribute=True, revenue_usd=0, allow_voice_or_trademark=False)#

The ONE rights intent every verb and surface defaults to (#63, maintainer decision 2026-10-03): commercial publishing, attributable. NC and SA material is refused unless a caller explicitly passes a different IntendedUse (or commercial_ok=False). Treat it as read-only; copy with dataclasses.replace.

foley.licensing.GEN_AI_PREFERENCE_SCOPES: dict[str, tuple[bool | None, str | None]] = {'no-additional-preferences': (None, None), 'no-gen-ai': (False, 'none'), 'noncommercial-open-source-models': (None, 'nc_open_source_only'), 'open-source-models': (None, 'open_source_only')}#

Freesound gen_ai_preference -> (ai_training_ok override, ai_training_scope). None as the override leaves the CC row’s flag alone. An unlisted value fails closed (see ai_scope_from_gen_ai_preference()).

foley.licensing.LICENSE_FLAGS: dict[str, LicenseFlags] = {'CC-BY-2.0': LicenseFlags(commercial_ok=True, embed_in_derivative_ok=True, redistribute_standalone_ok=True, cache_bytes_ok=True, modification_ok=True, ai_training_ok=True, requires_attribution=True, revenue_cap_usd=None), 'CC-BY-2.5': LicenseFlags(commercial_ok=True, embed_in_derivative_ok=True, redistribute_standalone_ok=True, cache_bytes_ok=True, modification_ok=True, ai_training_ok=True, requires_attribution=True, revenue_cap_usd=None), 'CC-BY-3.0': LicenseFlags(commercial_ok=True, embed_in_derivative_ok=True, redistribute_standalone_ok=True, cache_bytes_ok=True, modification_ok=True, ai_training_ok=True, requires_attribution=True, revenue_cap_usd=None), 'CC-BY-4.0': LicenseFlags(commercial_ok=True, embed_in_derivative_ok=True, redistribute_standalone_ok=True, cache_bytes_ok=True, modification_ok=True, ai_training_ok=True, requires_attribution=True, revenue_cap_usd=None), 'CC-BY-NC-2.0': LicenseFlags(commercial_ok=False, embed_in_derivative_ok=True, redistribute_standalone_ok=True, cache_bytes_ok=True, modification_ok=True, ai_training_ok=False, requires_attribution=True, revenue_cap_usd=None), 'CC-BY-NC-2.5': LicenseFlags(commercial_ok=False, embed_in_derivative_ok=True, redistribute_standalone_ok=True, cache_bytes_ok=True, modification_ok=True, ai_training_ok=False, requires_attribution=True, revenue_cap_usd=None), 'CC-BY-NC-3.0': LicenseFlags(commercial_ok=False, embed_in_derivative_ok=True, redistribute_standalone_ok=True, cache_bytes_ok=True, modification_ok=True, ai_training_ok=False, requires_attribution=True, revenue_cap_usd=None), 'CC-BY-NC-4.0': LicenseFlags(commercial_ok=False, embed_in_derivative_ok=True, redistribute_standalone_ok=True, cache_bytes_ok=True, modification_ok=True, ai_training_ok=False, requires_attribution=True, revenue_cap_usd=None), 'CC-Sampling+-1.0': LicenseFlags(commercial_ok=False, embed_in_derivative_ok=True, redistribute_standalone_ok=False, cache_bytes_ok=True, modification_ok=True, ai_training_ok=False, requires_attribution=True, revenue_cap_usd=None), 'CC0-1.0': LicenseFlags(commercial_ok=True, embed_in_derivative_ok=True, redistribute_standalone_ok=True, cache_bytes_ok=True, modification_ok=True, ai_training_ok=True, requires_attribution=False, revenue_cap_usd=None), 'ElevenLabs-SFX': LicenseFlags(commercial_ok=True, embed_in_derivative_ok=True, redistribute_standalone_ok=False, cache_bytes_ok=True, modification_ok=True, ai_training_ok=False, requires_attribution=False, revenue_cap_usd=None), 'MIT': LicenseFlags(commercial_ok=True, embed_in_derivative_ok=True, redistribute_standalone_ok=True, cache_bytes_ok=True, modification_ok=True, ai_training_ok=True, requires_attribution=True, revenue_cap_usd=None), 'PDM-1.0': LicenseFlags(commercial_ok=True, embed_in_derivative_ok=True, redistribute_standalone_ok=True, cache_bytes_ok=True, modification_ok=True, ai_training_ok=True, requires_attribution=False, revenue_cap_usd=None), 'Pixabay-Content': LicenseFlags(commercial_ok=True, embed_in_derivative_ok=True, redistribute_standalone_ok=False, cache_bytes_ok=True, modification_ok=True, ai_training_ok=False, requires_attribution=False, revenue_cap_usd=None), 'RemArc': LicenseFlags(commercial_ok=False, embed_in_derivative_ok=True, redistribute_standalone_ok=False, cache_bytes_ok=True, modification_ok=True, ai_training_ok=False, requires_attribution=True, revenue_cap_usd=None), 'Sonniss-GDC': LicenseFlags(commercial_ok=True, embed_in_derivative_ok=True, redistribute_standalone_ok=False, cache_bytes_ok=True, modification_ok=True, ai_training_ok=False, requires_attribution=False, revenue_cap_usd=None), 'Stability-Community': LicenseFlags(commercial_ok=True, embed_in_derivative_ok=True, redistribute_standalone_ok=False, cache_bytes_ok=True, modification_ok=True, ai_training_ok=False, requires_attribution=False, revenue_cap_usd=1000000), 'elevenlabs-free-plan': LicenseFlags(commercial_ok=False, embed_in_derivative_ok=True, redistribute_standalone_ok=False, cache_bytes_ok=True, modification_ok=True, ai_training_ok=False, requires_attribution=True, revenue_cap_usd=None), 'elevenlabs-paid-plan': LicenseFlags(commercial_ok=True, embed_in_derivative_ok=True, redistribute_standalone_ok=False, cache_bytes_ok=True, modification_ok=True, ai_training_ok=False, requires_attribution=False, revenue_cap_usd=None), 'unknown': LicenseFlags(commercial_ok=False, embed_in_derivative_ok=False, redistribute_standalone_ok=False, cache_bytes_ok=False, modification_ok=False, ai_training_ok=False, requires_attribution=False, revenue_cap_usd=None), 'user-owned': LicenseFlags(commercial_ok=True, embed_in_derivative_ok=True, redistribute_standalone_ok=True, cache_bytes_ok=True, modification_ok=True, ai_training_ok=True, requires_attribution=False, revenue_cap_usd=None)}#

license_id -> default flag set (report 07 §8.1 seed table).

Order of LicenseFlags positional args:

commercial, embed, redistribute_standalone, cache_bytes, modification,
ai_training, requires_attribution, revenue_cap_usd
Type:

SSOT

foley.licensing.LICENSE_META: dict[str, LicenseMeta] = {'CC-BY-2.0': LicenseMeta(display_name='CC BY 2.0', url='https://creativecommons.org/licenses/by/2.0/'), 'CC-BY-2.5': LicenseMeta(display_name='CC BY 2.5', url='https://creativecommons.org/licenses/by/2.5/'), 'CC-BY-3.0': LicenseMeta(display_name='CC BY 3.0', url='https://creativecommons.org/licenses/by/3.0/'), 'CC-BY-4.0': LicenseMeta(display_name='CC BY 4.0', url='https://creativecommons.org/licenses/by/4.0/'), 'CC-BY-NC-2.0': LicenseMeta(display_name='CC BY-NC 2.0', url='https://creativecommons.org/licenses/by-nc/2.0/'), 'CC-BY-NC-2.5': LicenseMeta(display_name='CC BY-NC 2.5', url='https://creativecommons.org/licenses/by-nc/2.5/'), 'CC-BY-NC-3.0': LicenseMeta(display_name='CC BY-NC 3.0', url='https://creativecommons.org/licenses/by-nc/3.0/'), 'CC-BY-NC-4.0': LicenseMeta(display_name='CC BY-NC 4.0', url='https://creativecommons.org/licenses/by-nc/4.0/'), 'CC-Sampling+-1.0': LicenseMeta(display_name='CC Sampling+ 1.0', url='https://creativecommons.org/licenses/sampling+/1.0/'), 'CC0-1.0': LicenseMeta(display_name='CC0 1.0 Universal (Public Domain Dedication)', url='https://creativecommons.org/publicdomain/zero/1.0/'), 'ElevenLabs-SFX': LicenseMeta(display_name='ElevenLabs Sound Effects Terms (legacy: paid plan assumed)', url='https://elevenlabs.io/terms-of-use'), 'MIT': LicenseMeta(display_name='MIT License', url='https://opensource.org/license/mit'), 'PDM-1.0': LicenseMeta(display_name='Public Domain Mark 1.0 (unverified claim)', url='https://creativecommons.org/publicdomain/mark/1.0/'), 'Pixabay-Content': LicenseMeta(display_name='Pixabay Content License', url='https://pixabay.com/service/license-summary/'), 'RemArc': LicenseMeta(display_name='BBC RemArc Licence', url='https://sound-effects.bbcrewind.co.uk/licensing'), 'Sonniss-GDC': LicenseMeta(display_name='Sonniss GDC Game Audio Bundle License', url='https://sonniss.com/gdc-bundle-license'), 'Stability-Community': LicenseMeta(display_name='Stability AI Community License', url='https://stability.ai/community-license-agreement'), 'elevenlabs-free-plan': LicenseMeta(display_name='ElevenLabs Terms (free plan: non-commercial, attribution required)', url='https://elevenlabs.io/terms-of-use'), 'elevenlabs-paid-plan': LicenseMeta(display_name='ElevenLabs Terms (paid plan)', url='https://elevenlabs.io/terms-of-use'), 'unknown': LicenseMeta(display_name='Unknown / unverified license', url=None), 'user-owned': LicenseMeta(display_name='User-owned / original work', url=None)}#

license_id -> display name + canonical URL (one row per LICENSE_FLAGS key). Used only for human-readable credits; never for permission decisions (those come from LICENSE_FLAGS).

Type:

SSOT

class foley.licensing.LicenseFlags(commercial_ok=False, embed_in_derivative_ok=False, redistribute_standalone_ok=False, cache_bytes_ok=False, modification_ok=False, ai_training_ok=False, requires_attribution=False, revenue_cap_usd=None)[source]#

Bases: object

The eight derivable flags for one license_id (the table row type).

class foley.licensing.LicenseMeta(display_name, url=None)[source]#

Bases: object

Human-facing display metadata for one license_id (name + canonical URL).

The presentation sibling of LicenseFlags: where LicenseFlags holds the permission row consulted by keep(), LicenseMeta holds the display row consulted by the credits/attribution layer (foley.provenance.credits). Kept here so licensing stays the single license authority; a record’s own license_name / license_url (when a source populated them) take precedence over this default.

foley.licensing.UNKNOWN_LICENSE_FLAGS = LicenseFlags(commercial_ok=False, embed_in_derivative_ok=False, redistribute_standalone_ok=False, cache_bytes_ok=False, modification_ok=False, ai_training_ok=False, requires_attribution=False, revenue_cap_usd=None)#

Fail-closed fallback for unknown / Proprietary-* license ids (all False, cap None).

foley.licensing.UNKNOWN_LICENSE_META = LicenseMeta(display_name='Unknown / unverified license', url=None)#

Fail-closed display fallback for unknown / Proprietary-* license ids.

foley.licensing.ai_scope_from_gen_ai_preference(preference)[source]#

Map a Freesound gen_ai_preference to (ai_training_ok override, scope).

All four published values are honoured (only no-gen-ai was before #69). A missing value means no stated preference; an unrecognised one fails closed.

Return type:

tuple[Optional[bool], Optional[str]]

foley.licensing.ai_use_permitted(record, *, open_source_model, commercial)[source]#

Whether AI use of the sound (CLAP-embedding it counts) is allowed here.

ai_training_ok must hold, and the record’s ai_training_scope must admit this use: open_source_only needs an open-source model, nc_open_source_only also needs a non-commercial purpose, none admits nothing.

Parameters:
  • record (LicenseRecord) – The rights record.

  • open_source_model (bool) – Whether the model using the audio is open source (the embedder’s open_source attribute; LAION-CLAP is).

  • commercial (bool) – Whether the purpose is commercial (foley’s default intent).

Return type:

bool

foley.licensing.apply_license_flags(record, *, overrides=None)[source]#

Populate record’s eight derived flags from its license_id (+ overrides), in place, and return it.

Does NOT touch rights_verified — verification is a separate concern.

Parameters:
Return type:

LicenseRecord

Returns:

The same (mutated) record.

foley.licensing.derive_license_flags(license_id, *, overrides=None)[source]#

Look up the flag set for a license_id (fail-closed fallback), then apply per-source overrides.

Parameters:
  • license_id (str) – The normalized license id (SPDX or foley-specific token).

  • overrides (Optional[dict]) – Optional per-source flag overrides — e.g. Freesound forces cache_bytes_ok=False on CC0. Keys must be LicenseFlags fields.

Return type:

LicenseFlags

Returns:

The resolved LicenseFlags (fallback = all-False UNKNOWN_LICENSE_FLAGS for unrecognized ids).

Raises:

ValueError – If overrides contains a key that is not a LicenseFlags field.

foley.licensing.intended_use_for(intended_use=None, *, commercial_ok=None)[source]#

The rights intent a verb runs under — every verb and surface resolves it here (#63).

An explicit intended_use wins; else DEFAULT_INTENDED_USE, with commercial overridden when commercial_ok is given (False is the explicit opt-in to non-commercial material). Always a fresh copy, so callers may mutate it.

Raises:

ValueError – If both are given and disagree on commercial.

Return type:

IntendedUse

foley.licensing.keep(record, intended_use)[source]#

Fail-closed candidate license gate (report 07 §8.2).

Run BEFORE ranking/verification in the agent’s decide(). Unknown or unverified rights => reject. Any single unmet requirement => reject.

Parameters:
  • record (LicenseRecord) – The candidate’s rights record.

  • intended_use (IntendedUse) – The caller’s declared intent.

Return type:

bool

Returns:

True only if every requirement in intended_use is satisfied by record; False otherwise (including unverified rights).

foley.licensing.keep_sound(sound_record, intended_use)[source]#

Convenience: apply keep() to a SoundRecord’s nested license.

Parameters:
  • sound_record – A SoundRecord (its .license is the SSOT consulted).

  • intended_use (IntendedUse) – The caller’s declared intent.

Return type:

bool

Returns:

The result of keep(sound_record.license, intended_use).

foley.licensing.license_id_from_cc_url(url)[source]#

Map a Creative-Commons license URL or label to (license_id, verified).

The single SSOT for turning an external source’s license string into a foley license_id (FSD50K, Clotho, the Freesound API, …). It never widens rights: the string is split into tokens, and

  • any NoDerivatives / ShareAlike sign (nd, sa, no derivatives, share alike, sharealike) → ('unknown', False): foley has no row expressing those restrictions, so the sound is refused everywhere;

  • the Public Domain Mark → ('PDM-1.0', False): a claim about the work, not a licence anyone granted, so never auto-verified (#56);

  • CC0 (publicdomain/zero, cc0, creative commons 0) → CC0-1.0;

  • Sampling+ → CC-Sampling+-1.0;

  • by / attribution with any mention of commercial use (nc, noncommercial, non commercial, no commercial use) → CC-BY-NC-<v>, else CC-BY-<v>. The version is kept (/by/3.0/ → CC-BY-3.0); a versionless label gets DEFAULT_CC_VERSION; a version foley has no row for (a 2.1/jp port) fails closed;

  • anything else — including a string with a token this parser does not know — → ('unknown', False).

Parameters:

url (Optional[str]) – A CC license URL, a CC label string, or None.

Return type:

tuple[str, bool]

Returns:

(license_id, rights_verified).

foley.licensing.license_meta(license_id)[source]#

Return the display LicenseMeta for license_id (fail-closed fallback).

Parameters:

license_id (str) – The normalized license id.

Return type:

LicenseMeta

Returns:

The mapped LicenseMeta, or UNKNOWN_LICENSE_META for an unrecognized / Proprietary-* id.