SPEC.mdpreviewSPEC.mdsource274 lines · 19.0 KB · raw
1---
2title: TYPESAFE JUNGLE
3theme: jev
4status: made
5song: song.js
6measured: {"date":"2026-09-26","song":"3607af93754b","total":{"loudnessDbfs":-21.5,"peakDbfs":-2.5},"parts":{"bass":{"loudnessDbfs":-29,"peakDbfs":-14.2},"drums":{"loudnessDbfs":-22.7,"peakDbfs":-3.7},"lead":{"loudnessDbfs":-42,"peakDbfs":-28},"other":{"loudnessDbfs":-42.8,"peakDbfs":-4},"stabs":{"loudnessDbfs":-39.6,"peakDbfs":-21.6},"vocals":{"loudnessDbfs":-36.2,"peakDbfs":-7.9}},"sections":{"1-4":{"total":{"loudnessDbfs":-40.2,"peakDbfs":-28},"parts":{"lead":{"loudnessDbfs":-40.2,"peakDbfs":-28}}},"5-8":{"total":{"loudnessDbfs":-35.1,"peakDbfs":-16.5},"parts":{"drums":{"loudnessDbfs":-36.8,"peakDbfs":-17.2},"lead":{"loudnessDbfs":-39.9,"peakDbfs":-28}}},"9-12":{"total":{"loudnessDbfs":-24,"peakDbfs":-6.7},"parts":{"bass":{"loudnessDbfs":-25.7,"peakDbfs":-19.6},"drums":{"loudnessDbfs":-36.9,"peakDbfs":-16.8},"lead":{"loudnessDbfs":-39.9,"peakDbfs":-28},"vocals":{"loudnessDbfs":-30.1,"peakDbfs":-8.4}}},"13-16":{"total":{"loudnessDbfs":-23.3,"peakDbfs":-6.8},"parts":{"bass":{"loudnessDbfs":-25.5,"peakDbfs":-19.6},"drums":{"loudnessDbfs":-32.2,"peakDbfs":-11.6},"lead":{"loudnessDbfs":-40.2,"peakDbfs":-28},"vocals":{"loudnessDbfs":-29.3,"peakDbfs":-8.3}}},"17-20":{"total":{"loudnessDbfs":-19.1,"peakDbfs":-3},"parts":{"bass":{"loudnessDbfs":-29,"peakDbfs":-15.1},"drums":{"loudnessDbfs":-19.7,"peakDbfs":-3.7},"lead":{"loudnessDbfs":-43.5,"peakDbfs":-31},"vocals":{"loudnessDbfs":-41.1,"peakDbfs":-8.8}}},"21-24":{"total":{"loudnessDbfs":-19.1,"peakDbfs":-2.7},"parts":{"bass":{"loudnessDbfs":-29.1,"peakDbfs":-16.3},"drums":{"loudnessDbfs":-19.7,"peakDbfs":-3.7},"lead":{"loudnessDbfs":-43.4,"peakDbfs":-31.5},"vocals":{"loudnessDbfs":-200.5,"peakDbfs":-168.3}}},"25-28":{"total":{"loudnessDbfs":-19,"peakDbfs":-3.1},"parts":{"bass":{"loudnessDbfs":-28.7,"peakDbfs":-15.6},"drums":{"loudnessDbfs":-19.7,"peakDbfs":-3.8},"lead":{"loudnessDbfs":-43.5,"peakDbfs":-31.5},"stabs":{"loudnessDbfs":-35.3,"peakDbfs":-21.7},"vocals":{"loudnessDbfs":-354.6,"peakDbfs":-324.6}}},"29-32":{"total":{"loudnessDbfs":-19.1,"peakDbfs":-2.5},"parts":{"bass":{"loudnessDbfs":-29.3,"peakDbfs":-15.8},"drums":{"loudnessDbfs":-19.7,"peakDbfs":-3.8},"lead":{"loudnessDbfs":-43.4,"peakDbfs":-31.5},"stabs":{"loudnessDbfs":-35.2,"peakDbfs":-21.8},"vocals":{"loudnessDbfs":-513.4,"peakDbfs":-482.2}}},"33-36":{"total":{"loudnessDbfs":-25.2,"peakDbfs":-10.8},"parts":{"bass":{"loudnessDbfs":-25.7,"peakDbfs":-19.6},"drums":{"loudnessDbfs":-36,"peakDbfs":-11.7},"lead":{"loudnessDbfs":-40,"peakDbfs":-28},"stabs":{"loudnessDbfs":-66.1,"peakDbfs":-39.5},"vocals":{"loudnessDbfs":-667.6,"peakDbfs":-639.1}}},"37-40":{"total":{"loudnessDbfs":-23.2,"peakDbfs":-6.6},"parts":{"bass":{"loudnessDbfs":-25.5,"peakDbfs":-19.6},"drums":{"loudnessDbfs":-36.4,"peakDbfs":-15.4},"lead":{"loudnessDbfs":-39.9,"peakDbfs":-28},"stabs":{"loudnessDbfs":-220.9,"peakDbfs":-183.2},"vocals":{"loudnessDbfs":-27.7,"peakDbfs":-7.9}}},"41-44":{"total":{"loudnessDbfs":-19.1,"peakDbfs":-2.5},"parts":{"bass":{"loudnessDbfs":-29,"peakDbfs":-14.2},"drums":{"loudnessDbfs":-19.6,"peakDbfs":-3.7},"lead":{"loudnessDbfs":-43.4,"peakDbfs":-31},"stabs":{"loudnessDbfs":-35.3,"peakDbfs":-21.6},"vocals":{"loudnessDbfs":-42.2,"peakDbfs":-10.1}}},"45-48":{"total":{"loudnessDbfs":-19,"peakDbfs":-2.5},"parts":{"bass":{"loudnessDbfs":-29.2,"peakDbfs":-16.9},"drums":{"loudnessDbfs":-19.7,"peakDbfs":-3.7},"lead":{"loudnessDbfs":-43.5,"peakDbfs":-31.5},"stabs":{"loudnessDbfs":-35.3,"peakDbfs":-21.7},"vocals":{"loudnessDbfs":-200.6,"peakDbfs":-168.3}}},"49-52":{"total":{"loudnessDbfs":-19.2,"peakDbfs":-2.5},"parts":{"bass":{"loudnessDbfs":-29.7,"peakDbfs":-16.7},"drums":{"loudnessDbfs":-19.7,"peakDbfs":-3.7},"lead":{"loudnessDbfs":-43.4,"peakDbfs":-31.5},"stabs":{"loudnessDbfs":-35.2,"peakDbfs":-21.6},"vocals":{"loudnessDbfs":-358.8,"peakDbfs":-325.8}}},"53-56":{"total":{"loudnessDbfs":-19.1,"peakDbfs":-2.5},"parts":{"bass":{"loudnessDbfs":-29,"peakDbfs":-16.4},"drums":{"loudnessDbfs":-19.7,"peakDbfs":-3.8},"lead":{"loudnessDbfs":-43.4,"peakDbfs":-31.5},"stabs":{"loudnessDbfs":-35.2,"peakDbfs":-21.7},"vocals":{"loudnessDbfs":-515.2,"peakDbfs":-483}}},"57-60":{"total":{"loudnessDbfs":-32.4,"peakDbfs":-11.7},"parts":{"bass":{"loudnessDbfs":-46.6,"peakDbfs":-21.1},"drums":{"loudnessDbfs":-33.5,"peakDbfs":-11.8},"lead":{"loudnessDbfs":-40.5,"peakDbfs":-28.6},"stabs":{"loudnessDbfs":-67.9,"peakDbfs":-42},"vocals":{"loudnessDbfs":-670,"peakDbfs":-639.3}}},"61-64":{"total":{"loudnessDbfs":-30.5,"peakDbfs":-4.3},"parts":{"drums":{"loudnessDbfs":-47.2,"peakDbfs":-19.8},"lead":{"loudnessDbfs":-47.2,"peakDbfs":-31.2},"other":{"loudnessDbfs":-30.6,"peakDbfs":-4},"vocals":{"loudnessDbfs":null,"peakDbfs":null}}}}}
7brief: "Make a song about TypeSafe's Jev in the style of Aphex Twin, built on real meme samples like \"My name is Jeff\"."
8critic:
9  date: 2026-09-26
10  model: jev-1.13.0
11  method: rubric-1
12  art: 0.6
13  artRuns: [0.6, 0.59, 0.6]
14  criteria:
15    hook: 2.8
16    development: 3.1
17    structure: 3.2
18    concept: 3.2
19    originality: 3
20    craft: 2.6
21revisions:
22  - rev: 1
23    date: 2026-09-24
24    model: claude-opus-5-5
25    harness: claude-code
26    prompt: "Make a song about TypeSafe's Jev in the style of Aphex Twin, built on real meme samples like \"My name is Jeff\"."
27    output: glitch.js
28    art: 0.33
29    artRuns: [0.33, 0.33, 0.33]
30  - rev: 2
31    date: 2026-09-24
32    model: claude-opus-5-5
33    harness: claude-code
34    prompt: "It reads as random noise. Make it more mainstream, driven by jungle kicks."
35    output: null  # overwritten by rev 3; predates this repo
36    art: null  # not scored: predates this repo: no song.js before the next revision was recorded
37  - rev: 3
38    date: 2026-09-24
39    model: claude-opus-5-5
40    harness: claude-code
41    prompt: "Improve it."
42    output: null  # overwritten by rev 4; predates this repo
43    art: null  # not scored: predates this repo: no song.js before the next revision was recorded
44  - rev: 4
45    date: 2026-09-24
46    model: claude-opus-5-5
47    harness: claude-code
48    prompt: "Remove the background pad. Give the song a real start and ending instead of a loop, keep the vocals out of the instrumental sections except the hook and after the drop, and arrange it like a real song."
49    output: null  # overwritten by rev 5
50    art: 0.5
51    artRuns: [0.5, 0.5, 0.49]
52  - rev: 5
53    date: 2026-09-24
54    model: claude-opus-5-5
55    harness: claude-code
56    prompt: "Let Jev arrange the song as it plays. Split it into named parts and cut it into 4-bar sections, each listing the sections allowed to follow it; at every section Jev picks the next section, the move to play it with (as written, no drums, amen and bass, or the lead over the amen), and how intense it is, and ends the song by choosing the last hit, with a cap of 28 sections. Tell Jev the tempo, key, chords, lyrics and everything played so far, and how the listener reacted. Without Jev it plays as written."
57    output: null  # overwritten by rev 6
58    art: 0.6
59    artRuns: [0.6, 0.6, 0.59]
60  - rev: 6
61    date: 2026-09-25
62    model: claude-opus-5-5
63    harness: claude-code
64    prompt: "Fix what a listener hears first. Bring the mix out of clipping with a master level. Make every Jev heard as Jev: spell it out in the swap line (\"My name is Jev. J, E, V.\"), give build 2 the swap too, and leave a gap between \"type safe\" and \"Jev\" in the pickup. Tune the rave stabs to the chords, move the bass up an octave so small speakers carry it, make the crash a crash, keep the lead on its chords, open the amen filter in one sweep and choke its slices. Let the snare roll duck under the words, keep the vocals through a dropout, and let Jev set each part only where it plays, as out, back or full."
65    output: null  # overwritten by rev 7
66    art: 0.6
67    artRuns: [0.6, 0.6, 0.59]
68  - rev: 7
69    date: 2026-09-26
70    model: claude-opus-5-5
71    harness: claude-code
72    prompt: "Keep Jev from looping a drop: each drop's loop may go round once more at most (drop1c and drop2 play at most twice), so no run of drop sections passes 32 bars. Every detour still plays."
73    output: song.js
74    art: 0.6
75    artRuns: [0.6, 0.59, 0.6]
76---
77
78# TYPESAFE JUNGLE — spec
79
80`song.js` is generated from this spec. Change the spec first, then the song.
81
82## Intent
83
84A jungle track about Jev (TypeSafe AI's typed-decision model), built on the
85"My name is Jeff" meme: the hook swaps Jeff for Jev.
86
87The pitch asks for real meme samples "like 'My name is Jeff'", and names no
88other, so the one real meme is the 22 Jump Street clip; everything else the
89hook says is the Jev voice answering it, because the joke is that one swap.
90
91## Style
92
93- Jungle / drum & bass, 170 bpm, C minor (Cm – A♭ – Fm – G, one chord per bar).
94- Structured and repeatable: patterns may vary by section, not by chance.
95- Rolling amen break played in order, with a fill every 4th bar. Each amen
96  slice cuts the one before, so slices never smear into each other.
97- Classic two-step kick (beat 1 and the "and" of 3) with an 808 underneath;
98  snare on 2 and 4.
99- The music-box lead outlines each bar's chord; the dominant (G) bar uses
100  B natural, as the bass does.
101- The rave stabs follow the roots C, A♭, F, G. The sample (`stab:3`) is
102  pitched at C♯, so its speed is set to land on each root.
103- The bass sits in F1–C2 (44–65 Hz): low enough to be a sub, high enough
104  for small speakers to carry. The low sub under the builds and the
105  breakdown gets a little saturation, so its second harmonic carries too.
106- The crash is a crash (`hh27:1`, Dirt-Samples' crash); Dirt-Samples' `cr`
107  is a ride.
108- The amen's filter opens in one continuous sweep from the tease into the
109  first drop, and in its own 4-bar sweep over build 2.
110- No sustained background pad.
111
112## Mix
113
114- Peaks at or under −1 dBFS as measured (superdough has no limiter), with
115  the kick layer trimmed and a master level on the whole song. At a master
116  level of 0.36, two runs measured −2.6 and −1.8 dBFS peak (−21.5 and
117  −22.1 dBFS loudness; the second is `measured:` above). Two runs at 0.6
118  read +2.7 and +1.6, so the margin covers the meter's run-to-run spread.
119
120## Structure
121
122Plays once from bar 1 and ends; it must not loop.
123
124| Bars | Section | Contents |
125|---|---|---|
126| 1–8 | Intro | Music-box lead alone; high-passed amen from bar 5, its filter opening until the drop |
127| 9–16 | Build | Hook vocals; amen filter keeps opening; low sub; snare roll + noise riser in 15–16, the roll ducking under the words |
128| 17–32 | Drop 1 | Full drums, reese + sine bassline, 8th hats; rave stabs from bar 25; crash on 17 |
129| 33–36 | Breakdown | Drums out; lead + low sub |
130| 37–40 | Build | Hook vocals return, the whole swap in 4 bars; amen filter opens again; riser into the drop |
131| 41–56 | Drop 2 | Everything, 16th hats, stabs; crash on 41 |
132| 57–64 | Outro | Kick and bass out, the amen alone thins over 57–60 and is gone for the final hit; lead fades; final kick + crash on 61, left to ring |
133
134## Vocals
135
136- Only in the two builds, as the hook leading into each drop — never in the
137  intro, drops, breakdown or outro.
138- Each build states the swap. Build 1, one line every other bar: "my name
139  is Jeff" → "my name is Jev. J, E, V." → "my name is Jeff" → "type safe
140  Jev", then "type safe… Jev" as the pickup into the drop. Build 2 packs the
141  same lines into its 4 bars: "my name is Jeff", "my name is Jev. J, E, V."
142  (which runs into bar 39, so "type safe Jev" comes in on its beat 3), then
143  the pickup.
144- The swap line spells the name, because a listener (and a speech
145  recogniser) hears a bare "Jev" as "Jeff": the spelling is the correction.
146- The pickup has an audible gap between "type safe" and "Jev": "type safe"
147  on beat 2, "Jev" on beat 4.
148- The build's snare roll ducks out under every spoken word, so the
149  punchline is never under it. In build 2 the words fill bars 39–40, so the
150  noise riser carries that build alone.
151- Every Jev line is heard as Jev by unprimed whisper `small.en` and
152  `medium.en`. Every vocal sample ends in natural decay, at or below −40 dB
153  over its last 20 ms, with at least 150 ms of tail and a fade of at least
154  20 ms, and peaks under −1 dBTP.
155  **Not yet met for two samples** (2026-09-25): `mnjev` passes both models,
156  but for `tsjev` and the pickup's `jev` no SAPI render tried is read as
157  Jev by both. `medium.en` hears a bare "Jev" as "Jeb" or "Jeff" in every
158  spelling tried; the transcripts are in `samples/README.md`.
159- Real samples: the 22 Jump Street clip (`jeff`); Windows speech-synth for the
160  Jev lines (`mnjev`, `tsjev`, `ts`, `jev`). Their sources and transcripts
161  are in `samples/README.md`.
162
163## Jev in the booth
164
165Jev arranges the song as it plays, as two jevs declared at the top in
166TypeSafe's own shape (`jev({ state, questions })`, `website/src/jev/`), both
167given the song as state (subject, tempo, key, chords, lyrics):
168
169- **`formJev`** asks one choice: which **section** plays next, among the
170  song's sixteen 4-bar sections.
171- **`djJev`** asks, once that is decided, a level per part (the music-box lead, the jungle drums, the rave stabs, the bass, the hook vocals:
172  out, back or full), a choice of how the song moves **into** the section,
173  and a score for the section's **energy**.
174  Questions in one request cannot see each other's answers, so it is a
175  second request, told the section just chosen (`after: { section }`).
176
177djJev is asked every section; formJev only where the form branches (where
178one section can follow, `walk` plays it without asking). Both run on a
1794-bar cadence (`.every(4, …)`), and the answers are composed in ordinary
180Strudel at the bottom: `walk` holds the form's rules, each part plays at
181its level, the transition plays over the last bar before the section, and
182`energy.score` scales the velocity.
183The sections are 4 bars: the breakdown and second build are 4 bars, so 8
184would not divide them.
185
186**The form.** A section may be followed only by these:
187
188| Section | Bars as written | May be followed by | Plays at most |
189|---|---|---|---|
190| `intro` | 1–4 | tease |  |
191| `tease` | 5–8 | build1 |  |
192| `build1` | 9–12 | build1b |  |
193| `build1b` | 13–16 | drop1 |  |
194| `drop1` | 17–20 | drop1b |  |
195| `drop1b` | 21–24 | drop1c |  |
196| `drop1c` | 25–28 | drop1d | twice |
197| `drop1d` | 29–32 | breakdown, drop1c |  |
198| `breakdown` | 33–36 | build2 |  |
199| `build2` | 37–40 | drop2 |  |
200| `drop2` | 41–44 | drop2b | twice |
201| `drop2b` | 45–48 | drop2c |  |
202| `drop2c` | 49–52 | drop2d, drop2 |  |
203| `drop2d` | 53–56 | outro, breakdown, drop2 |  |
204| `outro` | 57–60 | final |  |
205| `final` | 61–64 | (the end) |  |
206
207**Loops end.** Uncapped, the ways back let Jev repeat a drop until the cap: up to 64 bars of it in a row. So drop1c and drop2, where the drops' loops return, each play at most twice (`times` in `walk`, which counts every play: a loop is a cycle of different sections, and none of them repeats back to back), and each loop goes round once more at most. The longest run of a drop any path can now take is 32 bars. Every detour can still play, the written order is never capped, and a section that has played its most is not offered, nor is one that could only reach the ending through one.
208
209These rules are code (`walk`), not Jev: each request offers Jev only the
210sections allowed next. The written order is always allowed, and it is what
211plays when Jev can't be reached. Jev ends the song by choosing the outro,
212which always leads into `final`, whose last kick and crash always ring out;
213at 28 sections (about 2½ minutes) the ending is forced. Builds lead only into their drop, and a section plays
214its own bars, so a repeated drop is that drop, with its own hats and stabs.
215
216**The parts.** Each part's level is a choice of three: out (silent for the
217section), back (half velocity, under the rest of the mix) or full (as
218written), and each part plays at Jev's most likely level. Each question
219says what the part is and where it plays as written, so Jev can drop parts
220to build tension or make space, pull them back to let others speak, and
221bring them in full for the payoff. Jev is asked only about the parts that
222play in the section: the lead everywhere; the drums from the tease to the
223outro, except the breakdown and the final hit; the stabs in drop1c, drop1d
224and drop 2; the bass everywhere but the intro, tease, outro and final hit;
225the vocals in the three build sections. A part that cannot sound in a
226section is not asked about (it stays full, and adds nothing to the history).
227In the outro the drums are the amen alone, so there they may be only back
228or full. A part keeps its own masks, so vocals still appear only where the
229structure table puts them. Each part plays on its own
230orbit, named for its question (`lead`, `drums`, `stabs`, `bass`, `vocals`; the lead and the hook each get their own delay line there, where before they shared one), so the browser's meter hears
231each one alone. The last hit always plays, so the song still ends on it. When Jev can't be reached, every part
232plays in full.
233
234**Into the next section.** Over the last bar of each section, the song
235plays how Jev chose to move into the next one: a straight cut, a fill
236(the song's snare roll, rising in pitch), a riser (white noise sweeping up), or a dropout (everything except the vocals stops
237for the last beat). The last bar reads the next section's answer, so the transition
238fits where the song is going. Out of build1b and build2 the move is a cut
239or a dropout only: those bars already play the written roll and riser, so
240a fill or riser would double them, and a dropout lands the pickup's "Jev"
241alone into the drop. No transition doubles a written roll. The `final` section has no next section, so
242nothing plays over its last bar and its last beat is never cut. When Jev
243can't be reached, it is a cut.
244
245**A little chance.** The section is sampled from Jev's
246probabilities at temperature 0.7 (`sample`), so two plays of the song can
247take different paths; the strip shows Jev's top pick beside the one
248sampled. A close call between
249sections is where sampling matters most, so there is no confidence
250threshold: an unsure Jev still picks, and the written order plays only
251when Jev can't be reached.
252
253**Energy** is a four-step ladder, and stays a score, since a continuous
254intensity is what the question means: held back is about −5 dB, steady
255about −3 dB, driving about −1.5 dB, all out as written. It scales every
256part's velocity together (0.56 to 1), except the last hit, so the mix keeps
257its balance. No filter is added: the amen, the reese and the risers already
258set theirs.
259
260- Bars 1–4 always play as written.
261- Each request tells Jev the song's state (subject, tempo, key, chords,
262  lyrics), every answer so far, where the song is in its form (the sections
263  allowed next, and those left before the cap), how loud each finished
264  section measured in the browser, and the 🔥/😴 reactions from the
265  listener's tab.
266- This relaxes the constraints below that the song plays once in a fixed
267  order and is repeatable: the arrangement varies with Jev's choices,
268  which are judgments, with a little sampled chance in the form.
269
270## Constraints
271
272- Samples from `samples/` via `samples('jev-samples/strudel.json')`; drums, stabs
273  and noise from `github:tidalcycles/dirt-samples` and built-in synths.
274- Sections are absolute-cycle masks, so playback must start from stopped.