songs

One folder per song, grouped by theme: songs/<theme>/<song>/.

Each song folder holds:

  • SPEC.md — the spec the song is generated from. Its frontmatter carries:
    • status — planned (spec only) or made (song.js exists).
    • ideas — where the idea came from, if it started as a pitch: date, model, harness, the user's prompt verbatim, and the pitch verbatim.
    • pitch — if a listener's pitch on the site (the jev panel's pitches) gave the song its idea, that pitch's id (22 characters): the pitch then shows "became" and this song. The song's maker says so, never the pitch's author (website/src/jev/pitches.mjs); a malformed id fails the build.
    • critic — Jev's verdict on the song as it stands: the date, the model, the method (the rubric's version), each criterion's score out of 5, and art, their mean out of 5. Each is the mean of several runs (three by default), and artRuns lists each run's own art: one run moves by up to 0.06 on unchanged code. The rubric (website/src/jev/critic.mjs) scores hook, development, structure, concept, originality and craft like a harsh critic: 0 is not a song, 3 is good, 5 the best ever made in its genre. So 60% means good, 90% takes peak work, and 100% is out of reach. The state is the title, the spec body, the code and facts measured from it. Three notes scored 2% and a one-bar loop 11%; the songs 57-66% (2026-09-24). The card shows "N% art", and hovering its cover shows the criteria. tools/critic/ records it. (Until 2026-09-24 it was one yes/no question, "is this art?", which every song passed at 93-96%.)
    • revisions — every prompt that changed the music: date, model, harness, the prompt, the file it produced, and art, Jev's score for that revision's code, a mean over the runs listed in artRuns (null, with a comment, where the code could not be recovered). A song made from a pitch has the pitch as its first prompt; later prompts are the user's requests, written up as instructions about the music. The spec view shows the scores and how they changed.
  • song.js — the track, once made. Alternate takes sit beside it under their own names.
  • cover.webp — the song's card image in the song browser, 512×512.
  • README.md — its first paragraph is the card's description.

A song lets Jev arrange it live by declaring it at the top in TypeSafe's own shape, jev({ state, questions }) with the SDK's choice, score and noul (website/src/jev/jevCore.mjs), and composing the answers in Strudel. Songs use two: formJev picks the next section, and walk(section, …) holds the form's rules in code; djJev, asked after it (after: { section }), sets a level per part (out, back or full; a score, or a choice narrowed per section with allow) for that section, how the song moves into it, and its energy; each part plays at its level. The site's Worker relays the calls with the site's own TypeSafe key (worker/), so visitors need none.

Levels: each song sets its own master with .mul(postgain(x)) so its peaks sit under -1 dBFS. superdough's master limiter (packages/superdough/superdoughoutput.mjs) holds everything that reaches the speakers to -1 dBTP, so a hot mix cannot clip, but it is a safety net, not the mix: a song whose measured peak is -1.0 is being limited, and should be turned down until it is not.

The card's duration is read from song.js itself: the tempo from setcps(bpm/60/4) and the bar count from the play-once mask (.mask("<1!bars 0!…>")).

Themes:

  • jev/ — songs about Jev, TypeSafe AI's typed-decision model.