Repository navigation
feat(licensing): add default-deny engine and model licensing audit - #57
Open
Pushkraj-Space wants to merge 1 commit into
Open
Pushkraj-Space wants to merge 1 commit into
Pushkraj-Space wants to merge 1 commit into
Conversation
Murmur is about to integrate FluidAudio (october-dev#42) and sherpa-onnx (october-dev#26), and their SDK licenses do not cover the model weights, tokenizers, phonemizers, voices, and prebuilt binaries they fetch or link. october-dev#33 needs a machine-readable, fail-closed audit record before any engine lands. Add licensing/manifest.json, a single default-deny inventory of 71 entries: - the FluidAudio v0.17.4 and sherpa-onnx v1.13.8 engines, each with one named build configuration - their native closures: NemoTextProcessing plus the 37 Rust crates, std, and compiler-builtins it links statically, verified against the release binary; fastcluster; VBx; Japanese G2P code; kaldi-native-fbank, kaldi-decoder, kaldifst, OpenFst, Eigen, simple-sentencepiece, nlohmann/json; and the ONNX Runtime rebuild - the model, tokenizer, phonemizer, and voice components october-dev#42 needs - the two synthetic conformance-fixture sets. Every non-fixture entry is pinned by a 40-hex revision and/or byte-hashed downloads, cites license evidence in its own repository at its own commit, records upstream hops, terms, and download-presentation obligations, and is classified bundle, user-download, or blocked. Nothing is legally approved. Add tool/check_licensing.py, a stdlib-only checker, with 100 unittest cases, wired into `make check` and the CI protocol job. It enforces: - exact field shapes and an acyclic `requires` graph - ambiguity forcing `blocked`, and custom licenses needing exact names - Hugging Face downloads bound to the entry's repository and revision - evidence that is a file in the reviewed repository at the reviewed commit - approvals bound to a SHA-256 fingerprint of the reviewed fields - notices for approved bundles, and byte hashes for approved downloads and content bundles - synthetic-fixture provenance, and a case-insensitive scan that fails on any unregistered tracked model, native binary, or audio file. Document the contract, policy, download rule, runtime boundary, findings, update procedure, and questions for counsel in licensing/README.md. Point THIRD_PARTY_NOTICES.md, docs/voice-runtime.md, and CONTRIBUTING.md at it. Key findings, all recorded as blocked: - FluidAudio bundles an espeak-ng-harvested LuxTTS lexicon with no license. - The Kokoro English G2P and lexicon sources are undocumented. - The Parakeet EOU terms and the legacy diarization models are unresolved. - sherpa-onnx compiles an unlicensed table and a StackOverflow snippet. - The ONNX Runtime rebuild declares no license. Refs october-dev#33 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
harshsaver
requested changes
Sep 30, 2026
harshsaver
left a comment
Member
There was a problem hiding this comment.
Thanks. The inventory work is careful, and default-deny is the right policy while Murmur ships nothing. check-protocol, check-conformance and check-licensing (100/100) pass locally, and I spot-checked FluidAudio, text-processing-rs, Silero VAD Core ML, Kokoro ANE, Parakeet EOU and the diarization legacy models against their sources — all correct. A few things need to change before this can merge.
Blocking
- Adding fixtures breaks CI.
check_licensing.py:568requires every tracked file underconformance/fixtures/to be listed in a fixture entry'spaths(manifest.json:3746). Merging #56 into this branch makescheck_licensing.pyfail with "fixture file has no provenance entry" for all of #56's new fixtures, and #51 adds more. Hand-written synthetic JSONL carries no licensed content. Please scope the fixture rule to the scanned binary and audio suffixes (or register a directory prefix), so protocol PRs don't have to edit the licensing manifest. - The description's own audit is FAIL, with four open findings (kind compatibility for tracked models, prebuilt code without byte hashes, non-SPDX license strings,
vcscommit consistency). Please don't merge a gate that is known to be weak. Preferred: cut the approval path down to what's needed today. Nothing can be approved until legal review, socheck_approval, the 17-fieldfingerprint(check_licensing.py:150,:467) and the approval rules can land with the first real approval (#42 or #16), designed against a real case. Today's checker then only needs to verify the schema, pins,blocked/pendingeverywhere, ambiguity forcingblocked, and no unregistered model or binary files in the tree. (Alternatively, fix all four findings with tests.) - Data accuracy:
manifest.json:517(parakeet-tdt-0.6b-v3-coreml): the evidence README at 7dd20fe sayslicense: cc-by-4.0in its front-matter but "License: Apache 2.0" in the body. Under this PR's own "ambiguous means blocked" rule, record the contradiction inreview.notes, or block the entry until upstream fixes it.licensing/README.md:311callspiper-phonemizeGPL-3.0, but its LICENSE.md at f3ff95a is MIT (the manifest correctly says MIT). It's effectively GPL only through linking espeak-ng. Please reword.
Non-blocking
- Size: about 3.8k of the 5.5k lines are manifest data, including 37 pinned Rust crates for a FluidAudio configuration marked "provisional until #42 confirms". Consider inventorying the transitive crate closure in #42, when the configuration is real, and keeping this PR to the direct engine, model, tokenizer, voice and phonemizer entries plus the known blockers.
- Once item 1 is fixed, please state explicitly in CONTRIBUTING.md that JSON conformance fixtures don't need a manifest change.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Refs #33. This PR does not close the issue: qualified legal review (criterion 10) is an external gate, and the final
code audit still has four open findings (see "Audit result").
Murmur is about to integrate FluidAudio (#42) and sherpa-onnx (#26). An SDK's license is not the license of the
weights, tokenizers, phonemizers, voices, and prebuilt binaries it fetches or links. This PR adds a machine-readable,
default-deny licensing record and a CI gate, so that no engine or model artifact can be packaged or downloaded without
an exact, pinned, reviewed entry.
blocking) are met fail-closed for the current distribution. A PR that adds a downloader ([Offline] Add an atomic on-device voice model-pack manager #16) or packaging path
([SDK] Add generated bindings and package release automation #21, [FluidAudio] Build the Apple Silicon Murmur engine #42, [Offline] Add a cross-platform sherpa-onnx engine #26) re-opens both criteria and must add its cross-check in the same PR.
legal.status: pending, and none is approved.Changed files: 4 new and 5 modified.
licensing/manifest.jsonlicensing/README.mdtool/check_licensing.pytool/test_check_licensing.pyunittestcasesMakefilecheck-licensingtarget, added tocheck.github/workflows/ci.ymlprotocoljob runscheck-licensingTHIRD_PARTY_NOTICES.mddocs/voice-runtime.mdCONTRIBUTING.mdImplementation
Inventory (
licensing/manifest.json)The manifest has 71 entries: 52 bundle candidates, 5 user-download candidates, 12 blocked, and 2 fixture sets.
requiresis complete for exactly thatconfiguration. Both configurations are provisional until [FluidAudio] Build the Apple Silicon Murmur engine #42 and [Offline] Add a cross-platform sherpa-onnx engine #26 confirm them.
21493f8) is the SwiftPM default-traits build on macOS 14+ arm64.11afbd0) is a recognition-only static build.SHERPA_ONNX_USE_PRE_INSTALLED_ONNXRUNTIME_IF_AVAILABLE=OFF, so no unhashed ONNX Runtime from the build machineis linked.
SHERPA_ONNX_LINK_LIBSTDCPP_STATICALLY=OFFandSHERPA_ONNX_USE_STATIC_CRT=OFF, so C/C++ runtimes come from theOS and are not packaged.
5fa8c10d…) statically links 37 Rust crates, the Rust 1.98.1 std,and compiler-builtins. The closure comes from
cargo tree --locked -e normal,no-proc-macroover the seven Appletargets of its build script. It was cross-checked against panic locations and the
rustcversion string in everyrelease-binary slice. Each crate is pinned by its crates.io archive hash (equal to its
Cargo.lockchecksum) and itsVCS commit.
library ports: FunASR, NeMo, misaki, ZipVoice, Chatterbox, StyleTTS2 and mobius.
nlohmann/json. Every CMake source archive was downloaded and hash-verified against sherpa-onnx's pins.
vocabulary, Silero VAD, Kokoro ANE English with its vocabulary, the
af_heartvoice, the lexicon and the G2P, and thetwo legacy diarization models. Each is pinned to a Hugging Face commit and split per component wherever provenance
differs.
configuration.
conformance-audio-fixturesandconformance-json-fixturescover every tracked file underconformance/fixtures/, each with a syntheticmethod.Blocked, each with a recorded reason:
luxtts-en-us-g2p-lexicon: a lexicon harvested from espeak-ng, bundled into every FluidAudio build, with no statedlicense. This gates
fluidaudio.kokoro-english-lexiconandkokoro-english-g2p: undocumented source data and weights. These gatekokoro-82m-coreml-ane.parakeet-realtime-eou-120m-coremland its vocabulary: the NVIDIA Open Model License text has not been captured.pyannote-segmentation-legacy-coremlandwespeaker-v2-legacy-coreml: explicitly outside their repository'sCC-BY-4.0 scope, with no recorded source.
kokoro-spanish-french-g2p: espeak-generated pronunciations with no data license.sherpa-onnx: it compiles a Buckwalter table from an unlicensed repository and a StackOverflow snippet, alongsideApache-2.0 Kaldi/k2/icefall/CATT code and zlib-style cpp-base64 code.
onnxruntime: a third-party rebuild with no declared license or reproducible provenance.espeak-ngandpiper-phonemize: GPL-3.0, TTS only.Operational finding. FluidAudio's model downloader fetches Hugging Face
mainfor every repository except thediarizer, so #42 must fetch from the manifest's pinned files.
Checker (
tool/check_licensing.py)The checker is stdlib-only, in the style of
check_conformance.py. It exposes a purevalidate(manifest, notices, tracked_files), and--fingerprint <id>prints the value to record on approval.https://.requiresmust resolve, be acyclic, and never point to an engine or fixture.revision, byte-hasheddownloads, or both./<source repo>/resolve/<entry revision>/.sourcemust equalrevision.blob/raw, orresolveon Hugging Face) on github.com, gitlab.com orhuggingface.co.
vcs-or-sourcerepository at itsrevision; for a hop, in the hop's repository atits
revision.blocked:commercialUse: allowedand a recorded attributionpaths..onnx,.mlmodelc/,.so,.wavor similar file must be registered. The match ignores case.Tests
make check-licensing: pass, with 100 of 100unittestcases. The checker reports "71 entries: 52 bundle,5 user-download, 12 blocked, 2 fixture; 0 legally approved".
make check-conformance check-python: pass.git diff --checkandpython3 -m py_compileon both tool files: pass.directory/pathless evidence
so those crate versions were checked through the crates.io API instead.
make check-protocolwas not run locally, becauseprotocis not installed. Its inputs are unchanged, and CIruns it.
Audit result
Three audit-and-fix rounds resolved 14 findings:
The final audit verdict is FAIL, with four findings still open in this branch:
.onnxor.mlmodelccan be registered under a code entry(for example an approved
engine), so it never gets alicense.contentreview. The fix is scan-category and kindcompatibility checks, with negative tests.
native-librarypinned only byrevisionvalidates evenwhen it stands for a fetched release binary. The fix is to represent source-built versus prebuilt code explicitly
and require
downloadsfor approved prebuilt code."TBD"count as identified. The fix is tovalidate SPDX identifiers and expressions, and require the custom-license form for anything else.
vcscommit consistency. A commit embedded invcsis not compared withrevision. The fix is toreject a mismatch, with a test.
None of these affects what can ship today, because nothing is approved and the gate still blocks every artifact. Each
one weakens the gate for a future approval, so they should be fixed before merge or tracked as immediate follow-ups.
Known open issues and follow-ups
fingerprint per entry. The questions for counsel are in
licensing/README.md.Package.resolved, CMake options and model-URL checks against the manifest. The sherpa-onnx checkmust assert the ONNX Runtime and runtime-linkage options.
terms.download.presentation.Expo and Omarchy MIT notices. This needs a separate issue.
🤖 Generated with Claude Code