From d308adfc11b6f7e0c58ad8e42f47d49dc4947086 Mon Sep 17 00:00:00 2001 From: wine-fall <62830944+wine-fall@users.noreply.github.com> Date: Fri, 4 Sep 2026 14:01:29 +0800 Subject: [PATCH 1/2] =?UTF-8?q?docs(license):=20MIT=20=E2=80=94=20the=20mo?= =?UTF-8?q?del's=20terms=20were=20never=20murmur's=20to=20carry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit murmur called itself "open-source, non-commercial" and shipped no LICENSE file at all. The non-commercial half was inherited from the voice model: fish-speech is under the Fish Audio Research License, and DESIGN §3.7's two-phase strategy deferred "what we're allowed to ship" to distribution. But murmur redistributes none of those materials — it speaks HTTP to an endpoint the listener points it at. A model's license binds whoever reaches the model; it does not reach a client that embodies none of it. So the NC label protected nothing (every commercially interesting piece is already gated by its own author's terms) while costing an OSI license's whole distribution surface: awesome-lists, package indexes, and any reader who checks the badge before they clone. The tense was also stale. §3.7 described distribution as future work while murmur has been on npm since 0.2.1. - LICENSE at the root, MIT, so GitHub detects it - package.json: "SEE LICENSE IN README.md" -> the SPDX id "MIT" - README grows a Third-party services section naming what each hop is under: the listener's Claude session, fish-speech's research license, yt-dlp for music. Disclosure replaces the restriction. - DESIGN §3.7 rewritten present-tense as "murmur ships no model", with §§2/3.1/3.5 and the appendix following it - docs/index.html: five stale "non-commercial" strings, both languages The manifest test tightens with it: license was only asserted defined, which "SEE LICENSE IN README.md" satisfied. It now pins the SPDX id and the file npm packs (LICENSE ships regardless of the files array — verified against npm pack). Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01P6pPTjtKyjcz4rbDKBPVNe --- LICENSE | 21 +++++++++++++++++++++ README.md | 12 +++++++++--- docs/index.html | 10 +++++----- package.json | 2 +- specs/DESIGN.md | 18 +++++++++--------- test/package.test.ts | 10 +++++++++- 6 files changed, 54 insertions(+), 19 deletions(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..247cfc9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 wine-fall + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index d9e7ccd..67554cd 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ murmur is always on the air. It finds a topic and chats with you on its own, pla Existing tools are either "voice-control Claude to write code" or message-driven assistants. Nobody occupies the **proactive + emotional companionship + voice radio** combination. That gap is murmur. -> Open-source and non-commercial — but **not self-contained**. Three things come off the network — the brain is a Claude session, the music streams in, and the voice is [fish-speech](https://github.com/fishaudio/fish-speech) by [@fishaudio](https://github.com/fishaudio), reached over a hosted endpoint — and a fourth if you hand it a listening catalogue to find songs in. What runs on your machine is everything murmur itself owns — program logic, keyboard I/O, memory, persona, and audio mixing. A local TTS is a noted want, not current code. +> Open-source (MIT) — but **not self-contained**. Three things come off the network — the brain is a Claude session, the music streams in, and the voice is [fish-speech](https://github.com/fishaudio/fish-speech) by [@fishaudio](https://github.com/fishaudio), reached over a hosted endpoint — and a fourth if you hand it a listening catalogue to find songs in. What runs on your machine is everything murmur itself owns — program logic, keyboard I/O, memory, persona, and audio mixing. A local TTS is a noted want, not current code. ## Core experience @@ -45,7 +45,7 @@ Two processes. A Node.js (TypeScript) **engine** owns the program and the audio; - **TypeScript on the Claude Agent SDK** — the brain harness is the heart of the product, and `@anthropic-ai/claude-agent-sdk` is the first-class surface for it (the Python implementation served as the behavior oracle for the rewrite — GitHub issue #54). The mixer is a Web Audio graph on `node-web-audio-api`; local TTS models are deferred, so no Python/MLX runtime is needed. - **Brain = a harnessed agent (Claude today), subscription auth** — reuses your local Claude Code OAuth credentials; no `ANTHROPIC_API_KEY` needed. Every model sits behind a seam (`Brain`, `VoiceProvider`, `MusicProvider`) so swaps are adapter/config changes; a second brain backend (Codex SDK) is a recorded direction. - **Keyboard in, voice out** — no ASR this round; ASR is solved and not the value-add. The hard part is making the AI *sound human*, and that's the focus. -- **Two-phase model strategy** — experiment now with the best available models (private, personal use); adopt paid/properly-licensed models at distribution. +- **murmur ships no model** — the brain is your own Claude session and the voice is an endpoint you point it at, so each model's terms stay between you and that model's author, never redistributed by murmur. See [License](#license). See [`DESIGN.md`](specs/DESIGN.md) for the full master spec and rationale. @@ -135,4 +135,10 @@ The voice is [fish-speech](https://github.com/fishaudio/fish-speech) by [@fishau ## License -Open-source, non-commercial. Distributed models are chosen/licensed at distribution time (see the two-phase strategy in `specs/DESIGN.md` §3.7). +murmur's own code is **MIT** — see [`LICENSE`](LICENSE). + +**Third-party services.** murmur ships no model weights; it calls services that carry their own terms, and complying with them is yours: + +- **Brain** — your own Claude session, under your own Anthropic subscription. +- **Voice** — the default endpoint serves [fish-speech](https://github.com/fishaudio/fish-speech), whose model is under the Fish Audio Research License: free for research and non-commercial use, commercial use needs a separate license from Fish Audio. +- **Music** — retrieval runs through `yt-dlp` on your machine, against whatever source you point it at. diff --git a/docs/index.html b/docs/index.html index 7d83fac..faafa34 100644 --- a/docs/index.html +++ b/docs/index.html @@ -4,7 +4,7 @@ murmur — a whole radio station, for an audience of one - + @@ -301,7 +301,7 @@

$ cd murmur && make dev # the radio comes on the air

local-first - open-source, non-commercial + open-source, MIT keyboard in, voice out

@@ -388,8 +388,8 @@

Thre

Accepted by ear

-

Open-source and non-commercial, with a hard bar: if it doesn’t sound human, it isn’t done. The remaining work is listening.

+

Open-source under MIT, with a hard bar: if it doesn’t sound human, it isn’t done. The remaining work is listening.

@@ -417,7 +417,7 @@

On the air today

- murmur — open-source, non-commercial + murmur — open-source, MIT github.com/wine-fall/murmur
diff --git a/package.json b/package.json index bd8b28f..b204b54 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "murmur-radio", "version": "0.2.1", "description": "A companion radio, always on the air — Claude for a brain, a fish-speech voice, keyboard-driven replies.", - "license": "SEE LICENSE IN README.md", + "license": "MIT", "repository": { "type": "git", "url": "git+https://github.com/wine-fall/murmur.git" diff --git a/specs/DESIGN.md b/specs/DESIGN.md index afc4157..04e06c9 100644 --- a/specs/DESIGN.md +++ b/specs/DESIGN.md @@ -41,7 +41,7 @@ murmur's design is captured as **one master spec + several sub-specs**. A **fully-local companion radio** — "a radio that broadcasts for an audience of one," with Claude as its brain. -> **Product framing**: murmur is an **open-source, non-commercial product** distributed to users. "Audience of one" is the *experience* — each user runs their own private, fully-local radio — **not** a personal one-off; the earlier "personal use" framing is retired. Model choices follow a **two-phase strategy** (§3.7): experiment with good local/open models now, adopt paid/licensed models at distribution. +> **Product framing**: murmur is an **open-source (MIT) product** distributed to users. "Audience of one" is the *experience* — each user runs their own private radio — **not** a personal one-off; the earlier "personal use" framing is retired. murmur **ships no model** (§3.7): the listener brings their own brain session and voice endpoint, so each model's license is theirs, not something murmur redistributes. It is **always on the air**: it finds a topic and chats with me on its own, plays a song, comes back and keeps going; at the right times it says good morning / good night. It is **broadcasting, never soliciting** — it keeps going whether or not I say anything, and when I type, we chat for a bit before it eases back into the program. (Amended 2026-08-07, §2.2: the earlier "occasionally turns to me and asks" degree is retired — a radio does not solicit interaction.) It has a **persona seeded by a few questions up front** and it **keeps learning me** as it keeps me company, so it fits me better over time. (Amended 2026-07-29, §2.3: the *host's character* stays stable — what grows is what it knows about me and how we get on.) I talk to it with the **keyboard**; it answers with a **voice that sounds human**. @@ -95,9 +95,9 @@ The persona is **not a hard-coded constant — it is an evolving, living asset** Each item records the **why**, to avoid re-litigating later. ### 3.1 Positioning & privacy boundary -- **Fully local, open-source, non-commercial** — distributed to users; every instance runs entirely on the user's own machine (not a hosted service, not a personal one-off). +- **Local-first, open-source (MIT)** — distributed to users; every instance runs on the user's own machine (not a hosted service, not a personal one-off). - **The only two network hops**: ① Claude brain inference; ② the music stream. All other logic, I/O, and memory stay on-device — a core product value, not merely a personal constraint. -- *Rationale*: local-first + open-source is the product's identity. Model **licensing** is handled by the two-phase strategy (§3.7): during local experimentation any good open model is fair game; the distributable stack uses paid/properly-licensed models chosen at distribution time. (This retires the old "personal use unlocks non-commercial models" shortcut.) +- *Rationale*: local-first + open-source is the product's identity. Model **licensing** is not murmur's to carry (§3.7): murmur redistributes no model, so a model's terms bind the listener who reaches it, not murmur's source. (This retires both the old "personal use unlocks non-commercial models" shortcut and the two-phase deferral that replaced it.) ### 3.2 Brain & authentication - Brain = **Claude Opus**, via `claude-agent-sdk`, **reusing the local Claude Code subscription OAuth credentials** — **no API key needed**. @@ -137,7 +137,7 @@ Each item records the **why**, to avoid re-litigating later. - **Candidate pool** (decide the primary after a blind A/B): Qwen3-TTS, CosyVoice2, Chatterbox Multilingual V3, OpenAudio S1-mini. *(spec 02 wires the MLX-runnable experiment shortlist — **Spark** [primary], Qwen3-TTS, Chatterbox, Dia, and VoxCPM2 — as local experiment-phase voices per §3.7.)* - **TTS runs as an always-on warm sidecar process.** *Rationale*: models load slowly (seconds, several GB), so keep them warm rather than loading on every utterance; crash isolation — a TTS crash must not take down the radio brain; cross-process is also the cleanest seam for hot-swapping. - *Selection notes (from mid-2026 research)*: - - **Licensing is deferred to the two-phase strategy (§3.7)**: during local experimentation, non-commercially-licensed models (Spark/CosyVoice2/Fish/IndexTTS2, etc.) are fine to try; the *distributable* voice is a paid/licensed choice made at distribution time. So the experiment pool is unconstrained by license — an experiment pick is not a commitment to ship it. + - **Licensing does not filter the pool (§3.7)**: murmur ships no weights, so a non-commercially-licensed model (Spark/CosyVoice2/Fish/IndexTTS2, etc.) is a legitimate default as well as an experiment — what it obliges is disclosure, so the listener knows whose terms they are under (README's *Third-party services*). - On Mac the real trade-off is just "can it run in real time": MLX/Metal-accelerated models (e.g. Qwen3-TTS) can; CosyVoice2/GPT-SoVITS et al. are mostly CPU-bound and slow on Mac → better for **pre-generation** than millisecond-latency. - Since v1 input is keyboard and proactive broadcasts can be pre-generated in the background, "slow on Mac" matters little for broadcast → the most emotionally rich models remain usable. - **The human-ness / warmth of the voice is the soul of this product.** The primary model is ultimately decided by ear, via blind listening. @@ -151,10 +151,10 @@ Each item records the **why**, to avoid re-litigating later. - **Consequence to reconcile**: a separate always-on engine + an attach/detach TUI **subsumes much of the deferred daemon/detach model** (§10.1, "the radio keeps broadcasting after the terminal closes; a client re-attaches"). spec 10 must reconcile the two rather than treat them as independent. - See the TUI sub-spec (§10, `specs/spec10/10-tui.md`). -### 3.7 Model strategy: local substitutes now, paid/licensed at distribution -- **Two phases.** *Now (local experimentation)*: use the best **local, open** models available to prototype quality — the Claude Code subscription for the brain (§3.2), local open TTS (§3.5) — **regardless of their distribution license**. *At distribution*: re-evaluate and adopt **paid / properly-licensed** models (a paid brain API; a licensed or paid TTS) so the shipped open-source product is legally clean. -- *Why*: it decouples "find what sounds/works good" (cheap, fast, local, license-agnostic for private experimentation) from "what we're allowed to ship" (resolved once, at distribution, by paying for or licensing the chosen models). An experiment-phase pick like a CC-BY-NC TTS (e.g. Spark) is fine to run locally and is **not** a commitment to ship it. -- *Consequence*: model **licensing is not a selection filter during experimentation**; it becomes one only when choosing the distributable stack. Every model sits behind a seam (`Brain`, `VoiceProvider`) so each swap is an adapter/config change, not a rewrite. +### 3.7 Model strategy: murmur ships no model +- **The listener brings the models.** The brain is the listener's own Claude session (§3.2); the voice is an endpoint they point murmur at (§3.5); music is fetched by `yt-dlp` on their machine (§3.6). murmur's tarball carries no weights and no model code — only the client that speaks to them. +- *Consequence for murmur's own license*: the code is **MIT**. A model reached over an endpoint under a research/non-commercial license (fish-speech's Fish Audio Research License, say) binds whoever uses that model; it does not reach murmur's source, which embodies none of those materials. Conflating the two is what produced the earlier "non-commercial" framing, and it bought no protection — every commercially interesting piece is already gated by its own author's terms — while costing the distribution surface an OSI license buys. +- *Consequence for model selection*: licensing is a **disclosure** obligation, not a selection filter. Whatever the default stack reaches is named in README's *Third-party services* with its terms, so the listener knows what they are agreeing to. Every model sits behind a seam (`Brain`, `VoiceProvider`) so each swap is an adapter/config change, not a rewrite. --- @@ -388,7 +388,7 @@ When a test or eval needs an **actual LLM** (not a canned fake) — exercising p ## Appendix: key-decision quick reference (to avoid re-litigating) - **Why TypeScript**: the brain harness is the product's heart and the TS Agent SDK is its first-class surface; deferring local TTS (the one hard Python constraint) freed the choice (issue #54). - **Why a local TTS would be a sidecar**: slow load, keep it warm, crash isolation, clean hot-swap (deferred with local TTS). -- **Why personal use matters**: it unlocks the most emotional, non-commercially-licensed TTS. +- **Why murmur ships no model**: it keeps murmur's own code MIT while leaving the most emotional TTS — non-commercially licensed — a legitimate default, since its terms bind the listener who reaches the endpoint, not murmur's source (§3.7). - **Why yt-dlp for v1 music**: the only "no login, no membership, no app" start that also covers Chinese (Bilibili); Spotify is gated by Premium, NetEase by unofficial-API + login. - **Why single loop + look-ahead**: a radio can't have dead air; this is the minimum-cost prevention. - **Why persona lives in Memory**: it needs a **writable, user-owned home** next to the profile (seeded on first run, then edited by the user) — not because murmur rewrites it. Auto-evolution was considered and rejected (§2.3, amended 2026-07-29): rewrite loops mean-revert, so the *profile* grows and the character stays. diff --git a/test/package.test.ts b/test/package.test.ts index 206cdbc..062683d 100644 --- a/test/package.test.ts +++ b/test/package.test.ts @@ -25,7 +25,15 @@ describe('package manifest (the npm-install contract)', () => { // Bare "murmur" is taken on the registry (a murmur3 hashing lib). expect(pkg.name).toBe('murmur-radio') expect(pkg.private).toBeUndefined() - expect(pkg.license).toBeDefined() + }) + + it('carries a license npm and GitHub both recognise', () => { + // A bare SPDX id (not "SEE LICENSE IN ...") is what keeps npm from warning + // and what GitHub reads to show the license badge; the file at the root is + // what GitHub detects. npm packs LICENSE regardless of the files array. + expect(pkg.license).toBe('MIT') + expect(existsSync(join(root, 'LICENSE'))).toBe(true) + expect(readFileSync(join(root, 'LICENSE'), 'utf8')).toContain('MIT License') }) it('exposes the murmur command as a built entry prepack produces', () => { From 2f752053ec59615193c4b595f79c15a21c5459b8 Mon Sep 17 00:00:00 2001 From: wine-fall <62830944+wine-fall@users.noreply.github.com> Date: Fri, 4 Sep 2026 14:08:38 +0800 Subject: [PATCH 2/2] docs(license): scope the license claim and complete the service list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Peer review (codex gpt-5.6-sol) findings, all three verified against the code and applied: - The §3.7 text pronounced on who a model's license binds at the far end of an endpoint. Redistributing nothing establishes that no model license reaches murmur's source; it does not establish whether the model license or the operator's service terms govern an API caller. murmur is not a party to that agreement and should not characterise it — it now says what it knows and points at the terms. - Third-party services listed three hops and the code makes seven: ensureTuiDeps reaches a package registry on a packaged first boot (a miss degrades the TUI to plain), presetClip reaches raw.githubusercontent.com, HostedListening reaches Last.fm, and latestVersion reaches registry.npmjs.org behind /update. Disclosure replacing a restriction has to be complete or it is worse than what it replaced. - §3.1 still claimed Claude and music were "the only two network hops" on the line after the one this branch edited, the diagram repeated it, and §2 still said "fully-local" — all false once the voice is an endpoint. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01P6pPTjtKyjcz4rbDKBPVNe --- README.md | 11 +++++++++-- specs/DESIGN.md | 10 +++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 67554cd..4f0ffda 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ murmur is always on the air. It finds a topic and chats with you on its own, pla Existing tools are either "voice-control Claude to write code" or message-driven assistants. Nobody occupies the **proactive + emotional companionship + voice radio** combination. That gap is murmur. -> Open-source (MIT) — but **not self-contained**. Three things come off the network — the brain is a Claude session, the music streams in, and the voice is [fish-speech](https://github.com/fishaudio/fish-speech) by [@fishaudio](https://github.com/fishaudio), reached over a hosted endpoint — and a fourth if you hand it a listening catalogue to find songs in. What runs on your machine is everything murmur itself owns — program logic, keyboard I/O, memory, persona, and audio mixing. A local TTS is a noted want, not current code. +> Open-source (MIT) — but **not self-contained**. The main three come off the network — the brain is a Claude session, the music streams in, and the voice is [fish-speech](https://github.com/fishaudio/fish-speech) by [@fishaudio](https://github.com/fishaudio), reached over a hosted endpoint — and a fourth if you hand it a listening catalogue to find songs in. What runs on your machine is everything murmur itself owns — program logic, keyboard I/O, memory, persona, and audio mixing. A local TTS is a noted want, not current code. ## Core experience @@ -140,5 +140,12 @@ murmur's own code is **MIT** — see [`LICENSE`](LICENSE). **Third-party services.** murmur ships no model weights; it calls services that carry their own terms, and complying with them is yours: - **Brain** — your own Claude session, under your own Anthropic subscription. -- **Voice** — the default endpoint serves [fish-speech](https://github.com/fishaudio/fish-speech), whose model is under the Fish Audio Research License: free for research and non-commercial use, commercial use needs a separate license from Fish Audio. +- **Voice** — the default endpoint serves [fish-speech](https://github.com/fishaudio/fish-speech), whose model carries the [Fish Audio Research License](https://github.com/fishaudio/fish-speech/blob/main/LICENSE) (research and non-commercial use free; commercial use by separate license). Whoever operates the endpoint you point at may add service terms of their own — read both; murmur is not a party to either. - **Music** — retrieval runs through `yt-dlp` on your machine, against whatever source you point it at. + +And these, only on the paths that need them: + +- **A package registry** — a packaged first boot runs `bun install` for the TUI; without it murmur falls back to the plain front-end. +- **`raw.githubusercontent.com`** — downloading a built-in voice preset's reference clip (cached and hash-pinned after the first fetch). +- **[Last.fm](https://www.last.fm/api), or the catalogue you point `MURMUR_LISTENING_URL` at** — only with a listening key set. +- **`registry.npmjs.org`** — the version check behind `/update`. diff --git a/specs/DESIGN.md b/specs/DESIGN.md index 04e06c9..e3db75f 100644 --- a/specs/DESIGN.md +++ b/specs/DESIGN.md @@ -39,7 +39,7 @@ murmur's design is captured as **one master spec + several sub-specs**. ## 1. What this is (Vision) -A **fully-local companion radio** — "a radio that broadcasts for an audience of one," with Claude as its brain. +A **local-first companion radio** — "a radio that broadcasts for an audience of one," with Claude as its brain. > **Product framing**: murmur is an **open-source (MIT) product** distributed to users. "Audience of one" is the *experience* — each user runs their own private radio — **not** a personal one-off; the earlier "personal use" framing is retired. murmur **ships no model** (§3.7): the listener brings their own brain session and voice endpoint, so each model's license is theirs, not something murmur redistributes. @@ -96,7 +96,7 @@ Each item records the **why**, to avoid re-litigating later. ### 3.1 Positioning & privacy boundary - **Local-first, open-source (MIT)** — distributed to users; every instance runs on the user's own machine (not a hosted service, not a personal one-off). -- **The only two network hops**: ① Claude brain inference; ② the music stream. All other logic, I/O, and memory stay on-device — a core product value, not merely a personal constraint. +- **The network hops, and only these**: ① Claude brain inference; ② the voice endpoint; ③ the music stream — plus, only where a feature asks for it, a listening catalogue, a package registry on a packaged first boot, a voice preset's clip, and the `/update` version check (README's *Third-party services* is the full list). All other logic, I/O, and memory stay on-device — a core product value, not merely a personal constraint. - *Rationale*: local-first + open-source is the product's identity. Model **licensing** is not murmur's to carry (§3.7): murmur redistributes no model, so a model's terms bind the listener who reaches it, not murmur's source. (This retires both the old "personal use unlocks non-commercial models" shortcut and the two-phase deferral that replaced it.) ### 3.2 Brain & authentication @@ -153,8 +153,8 @@ Each item records the **why**, to avoid re-litigating later. ### 3.7 Model strategy: murmur ships no model - **The listener brings the models.** The brain is the listener's own Claude session (§3.2); the voice is an endpoint they point murmur at (§3.5); music is fetched by `yt-dlp` on their machine (§3.6). murmur's tarball carries no weights and no model code — only the client that speaks to them. -- *Consequence for murmur's own license*: the code is **MIT**. A model reached over an endpoint under a research/non-commercial license (fish-speech's Fish Audio Research License, say) binds whoever uses that model; it does not reach murmur's source, which embodies none of those materials. Conflating the two is what produced the earlier "non-commercial" framing, and it bought no protection — every commercially interesting piece is already gated by its own author's terms — while costing the distribution surface an OSI license buys. -- *Consequence for model selection*: licensing is a **disclosure** obligation, not a selection filter. Whatever the default stack reaches is named in README's *Third-party services* with its terms, so the listener knows what they are agreeing to. Every model sits behind a seam (`Brain`, `VoiceProvider`) so each swap is an adapter/config change, not a rewrite. +- *Consequence for murmur's own license*: the code is **MIT**. What murmur distributes embodies no model materials, so no model's license reaches murmur's source. What that does **not** settle is what binds a listener at the far end of an endpoint — the model's own license, the operator's service terms, or both — and murmur is not the party to that agreement or the one to characterise it. Conflating the two questions is what produced the earlier "non-commercial" framing, and it bought no protection while costing the distribution surface an OSI license buys. +- *Consequence for model selection*: licensing is not a selection filter for murmur. The duty it does create is **disclosure** — every hop the default stack makes is named in README's *Third-party services*, pointing at the terms rather than summarising them, so the listener can read what applies to them. Every model sits behind a seam (`Brain`, `VoiceProvider`) so each swap is an adapter/config change, not a rewrite. --- @@ -179,7 +179,7 @@ Each item records the **why**, to avoid re-litigating later. │ Memory (who you are · what we've discussed · no repeats / │ │ the persona living asset) │ └──────────────────────────────────────────────────────────────────────────────────────┘ - Only network hops: Claude inference (one) + music stream (one) + Network hops: Claude inference + voice endpoint + music stream (see §3.1) ``` | Component | Responsibility | Notes |