🦄 Unicorn.Land ▸ docs/superpowers/specs/2026-06-27-muse-songwriting-assistant-design.md
updated 2026-06-27

Muse — Songwriting Assistant — Design Spec

Date: 2026-06-27 Status: Approved (design) — pending implementation plan Owner: Joshua

1. Purpose

A personal songwriting companion that helps Joshua write deep, moving, catchy, and harmonically unique songs. It is built around his actual process — melody/lyrics-first, piano-literate, strong intuition, still building chord/scale fluency — and its job is to expand the harmonic palette his intuition can reach for, catch fragments before they evaporate, and grow them into full songs.

Working name: Muse.

The core creative loop

Joshua names a feeling (text now; a hummed voice memo later) → Muse replies with a genuinely interesting, non-cliché chord progression that fits that feeling, with every chord spelled out and a one-line “why it feels that way,” plus a piano audio clip he can hear instantly → he writes words/melody on top → he iterates in chat → Muse helps grow it into a full song → everything is saved to a library.

Priorities (from Joshua, in order)

  1. Capture — fragments evaporate; nothing should be lost.
  2. Development — grow a verse/hook into a full song.
  3. Harmonic ceiling — break out of habitual chords/keys into unique territory.

Deferred chapters (explicitly out of scope for now)

2. Experience

Front door: Discord (Joshua’s phone is always in reach; great for voice memos and async, low-friction capture). Grows into a web dashboard later, once the song library is big enough that browsing it becomes the bottleneck.

A Muse reply looks like:

Fmaj7 (F A C E) → A♭maj7 (A♭ C E♭ G) → E♭/G (E♭ G B♭, G in bass) → D♭maj7 (D♭ F A♭ C) Why it floats: A♭maj7 and D♭maj7 are borrowed from F minor — the major-7th color keeps it dreamy while the borrowed chords pull it bittersweet. 🎵 [piano clip attached]

Three layers, every time: 1. The progression, written so Joshua can read and play it. 2. Each chord spelled out (e.g. Fmaj7 = F A C E) — because he’s still building chord fluency, every reply quietly teaches vocabulary in the context of his own song. 3. A one-line “why it feels that way” — the layer that raises his harmonic ceiling over time. 4. A piano audio clip — so he hears the idea instantly, phone in hand, no piano required.

Iteration is conversational: “more tension on chord 3,” “make the bridge lift,” “give me a darker version” → Muse replies with a new card.

3. Architecture

Muse is a single always-on Node.js / TypeScript process running on Joshua’s Mac (which is always on). It listens to Discord, routes each message, and replies with a rendered card.

Discord message (text or voice memo)
        │
        ▼
  ┌─────────────┐
  │  Bot (I/O)  │  discord.js v14 — listens, downloads attachments, sends replies
  └─────┬───────┘
        │
        ▼
  ┌─────────────┐
  │   Router    │  text → Brain;  voice memo → (Phase 2) melody extraction
  └─────┬───────┘
        │
        ▼
  ┌─────────────┐
  │    Brain    │  LLM (Claude) emits a progression as Roman numerals + the
  │ (theory-    │  "why it feels" explanation, conditioned on the feeling/intent
  │  guarded)   │  and (later) Joshua's history/habits
  └─────┬───────┘
        │ Roman numerals + key + intent
        ▼
  ┌─────────────┐
  │   Theory    │  tonal — validates the LLM's chords, realizes them in the key,
  │  (tonal)    │  spells every chord (Fmaj7 → F A C E). Guardrail: no invalid chords.
  └─────┬───────┘
        │ concrete spelled chords + voicing
        ▼
  ┌─────────────┐
  │    MIDI     │  midi-writer-js — build a MIDI file with voicing/rhythm/tempo
  └─────┬───────┘
        │ .mid
        ▼
  ┌─────────────┐
  │   Render    │  FluidSynth (native) + piano soundfont → .wav (→ .mp3 via ffmpeg)
  └─────┬───────┘
        │ audio clip
        ▼
  ┌─────────────┐
  │  Library    │  every fragment, progression, and clip saved (SQLite/local files)
  └─────┬───────┘
        │
        ▼
   Reply card back to Discord (chords + spelled notes + why + audio clip)

Components (each independently understandable and testable)

4. Build vs. assemble

Research confirms ~70% of this is assembly of mature, permissively-licensed parts; ~30% is custom glue. The one genuinely custom, taste-driven component is the emotion → harmony brain — which is a feature, not a gap: it’s where Joshua’s taste and a good LLM live.

Capability Off-the-shelf piece License
Discord I/O (incl. voice memos, audio replies) discord.js v14 Apache-2.0
Theory, chord spelling, Roman→concrete tonal (@tonaljs) MIT
MIDI authoring midi-writer-js MIT
MIDI → piano audio FluidSynth + FluidR3_GM / Salamander soundfont LGPL / MIT / PD
WAV → MP3 (optional) ffmpeg LGPL/GPL
Hum → notes (Phase 2) Spotify Basic Pitch (JS port basic-pitch-ts) Apache-2.0
Emotion → progression + explanation Custom: Claude, guarded by tonal

5. Hosting

Runs as an always-on Node process on Joshua’s Mac (which is always on and online). Free, immediate, no Pi or cloud container needed. A cheap cloud container (Railway ~$5/mo) remains a someday option if Muse ever needs to be fully independent of the Mac.

Why not Cloudflare: the site’s normal host won’t work here, for two structural reasons. (1) A Discord bot must hold a persistent connection and be always listening; Cloudflare Workers/Pages are serverless — they wake per-request and vanish, leaving nothing to catch a message. (2) FluidSynth is a native binary that must be installed into an OS; serverless sandboxes can’t run arbitrary binaries. Neither is FluidSynth-specific — any audio renderer (Timidity, etc.) is also native, and the pure-JS rendering path (Tone.js) still doesn’t solve the always-listening problem. The real requirement is simply a regular, always-on computer — which the Mac is.

6. Memory / “learns you over time” (staged)

Muse is designed as a companion that builds a picture of Joshua, not a stateless vending machine — built up in stages:

7. Phasing (each phase ships independently)

8. Success criteria

9. Open questions (for later phases, not blocking Phase 1)