SPEC.mdpreviewSPEC.mdsource273 lines · 17.2 KB · raw
1---
2title: SELECT * FROM JEV
3theme: jev
4status: made
5song: song.js
6measured: {"date":"2026-09-26","song":"0b447e15f815","total":{"loudnessDbfs":-22.5,"peakDbfs":-2.2},"parts":{"arp":{"loudnessDbfs":-35.3,"peakDbfs":-18},"bass":{"loudnessDbfs":-28.7,"peakDbfs":-20.1},"drums":{"loudnessDbfs":-26.3,"peakDbfs":-2.8},"lead":{"loudnessDbfs":-31.1,"peakDbfs":-10.5},"other":{"loudnessDbfs":-47.6,"peakDbfs":-4},"vocals":{"loudnessDbfs":-31.6,"peakDbfs":-6.8}},"sections":{"1-8":{"total":{"loudnessDbfs":-27.1,"peakDbfs":-5.3},"parts":{"arp":{"loudnessDbfs":-33.1,"peakDbfs":-18.8},"drums":{"loudnessDbfs":-28.4,"peakDbfs":-6}}},"9-16":{"total":{"loudnessDbfs":-22.6,"peakDbfs":-3.5},"parts":{"arp":{"loudnessDbfs":-37.4,"peakDbfs":-22.4},"bass":{"loudnessDbfs":-28.1,"peakDbfs":-21.3},"drums":{"loudnessDbfs":-25.8,"peakDbfs":-4.8},"vocals":{"loudnessDbfs":-29.7,"peakDbfs":-6.8}}},"17-24":{"total":{"loudnessDbfs":-21.3,"peakDbfs":-2.2},"parts":{"arp":{"loudnessDbfs":-36.4,"peakDbfs":-21.6},"bass":{"loudnessDbfs":-28.1,"peakDbfs":-20.1},"drums":{"loudnessDbfs":-25.6,"peakDbfs":-3.9},"lead":{"loudnessDbfs":-28.7,"peakDbfs":-11.5},"vocals":{"loudnessDbfs":-28.4,"peakDbfs":-6.8}}},"25-32":{"total":{"loudnessDbfs":-22.7,"peakDbfs":-3.5},"parts":{"arp":{"loudnessDbfs":-35,"peakDbfs":-20},"bass":{"loudnessDbfs":-28.3,"peakDbfs":-20.1},"drums":{"loudnessDbfs":-26.5,"peakDbfs":-6},"lead":{"loudnessDbfs":-29,"peakDbfs":-11.3},"vocals":{"loudnessDbfs":-182.2,"peakDbfs":-141.4}}},"33-40":{"total":{"loudnessDbfs":-22.4,"peakDbfs":-3.4},"parts":{"arp":{"loudnessDbfs":-37.3,"peakDbfs":-22.8},"bass":{"loudnessDbfs":-28.2,"peakDbfs":-20.1},"drums":{"loudnessDbfs":-26,"peakDbfs":-4.8},"lead":{"loudnessDbfs":-66.3,"peakDbfs":-36.7},"vocals":{"loudnessDbfs":-28.6,"peakDbfs":-6.8}}},"41-48":{"total":{"loudnessDbfs":-21.2,"peakDbfs":-2.3},"parts":{"arp":{"loudnessDbfs":-36.4,"peakDbfs":-21.6},"bass":{"loudnessDbfs":-28,"peakDbfs":-20.1},"drums":{"loudnessDbfs":-25.4,"peakDbfs":-2.8},"lead":{"loudnessDbfs":-28.7,"peakDbfs":-11.7},"vocals":{"loudnessDbfs":-28.5,"peakDbfs":-6.8}}},"49-56":{"total":{"loudnessDbfs":-22.3,"peakDbfs":-2.9},"parts":{"arp":{"loudnessDbfs":-34.4,"peakDbfs":-19.5},"bass":{"loudnessDbfs":-28.1,"peakDbfs":-21.6},"drums":{"loudnessDbfs":-25.9,"peakDbfs":-6},"lead":{"loudnessDbfs":-28.7,"peakDbfs":-11.1}}},"57-64":{"total":{"loudnessDbfs":-23.8,"peakDbfs":-3.6},"parts":{"arp":{"loudnessDbfs":-33.7,"peakDbfs":-18},"bass":{"loudnessDbfs":-29.2,"peakDbfs":-21.6},"drums":{"loudnessDbfs":-27.9,"peakDbfs":-6},"lead":{"loudnessDbfs":-31.8,"peakDbfs":-10.5},"other":{"loudnessDbfs":-38.6,"peakDbfs":-4}}}}}
7critic:
8  date: 2026-09-26
9  model: jev-1.13.0
10  method: rubric-1
11  art: 0.65
12  artRuns: [0.64, 0.65, 0.66]
13  criteria:
14    hook: 2.9
15    development: 3.4
16    structure: 3.2
17    concept: 3.7
18    originality: 3.5
19    craft: 2.8
20ideas:
21  - date: 2026-09-24
22    model: claude-opus-5-5
23    harness: claude-code
24    prompt: "Give me some song ideas as prompts, in the same Jev theme: perhaps with actual memes in the vocals, or a vocoder sound."
25    brief: "Slow synthwave at 90 bpm for postjevsql. A vocoder sings SQL: \"select star from jev\", \"where vibes are true\". The hook is Obi-Wan's \"Hello there\", answered by \"General Kenobi\". Gated reverb snare, arpeggios, a big 80s chorus. Vocals only in the verse and chorus."
26revisions:
27  - rev: 1
28    date: 2026-09-24
29    model: claude-opus-5-5
30    harness: claude-code
31    prompt: "Slow synthwave at 90 bpm for postjevsql. A vocoder sings SQL: \"select star from jev\", \"where vibes are true\". The hook is Obi-Wan's \"Hello there\", answered by \"General Kenobi\". Gated reverb snare, arpeggios, a big 80s chorus. Vocals only in the verse and chorus."
32    output: null  # overwritten by rev 2
33    art: 0.55
34    artRuns: [0.55, 0.54, 0.55]
35  - rev: 2
36    date: 2026-09-24
37    model: claude-opus-5-5
38    harness: claude-code
39    prompt: "Let Jev arrange the song as it plays. Split it into named parts and name each 8-bar section with the sections allowed to follow it; at each section Jev picks the next section, the move to play it with (as written, no drums, stripped to arps, drums and vocals, no arpeggio), and how intense it is, and ends the song by choosing the outro, with a hard cap of 16 sections. Keep the key change vocal-free. Tell Jev the tempo, key, chords, lyrics and everything played so far. Without Jev it plays as written."
40    output: null  # overwritten by rev 3
41    art: 0.63
42    artRuns: [0.63, 0.64, 0.63]
43  - rev: 3
44    date: 2026-09-25
45    model: claude-opus-5-5
46    harness: claude-code
47    prompt: "Fix the mix and make the song do what it says. Stop the clipping: peaks at or under -1 dBFS, the kick under the vocals, the saw lead about 6 dB under the drums in the instrumentals and the arpeggio about 10 dB under. Make the chorus a big 80s chorus: a clap on 2 and 4, sixteenth hats, the arpeggio's filter opened, a real crash and the lead at full. Gate the snare for real: a flat reverb tail cut dead at about 250 ms. Make \"Jev\" heard as Jev, not \"GIF\". Keep the vocals to the verses and choruses, as the brief says, and make the \"Hello there\" / \"General Kenobi\" hook always play in a chorus. Filter the intro's arpeggio open over four bars. Keep a pulse through the outro and end on G# minor, not F# major. Roll the toms into the choruses and the key change wherever the path goes, never twice and never under a plain cut, and judge each transition on the section it enters. Tell Jev only what the music does: the energy steps, where the vocals are sung, which bars are up a tone, and a riser that swells."
48    output: null  # overwritten by rev 4
49    art: 0.63
50    artRuns: [0.64, 0.63, 0.63]
51  - rev: 4
52    date: 2026-09-26
53    model: claude-opus-5-5
54    harness: claude-code
55    prompt: "Keep Jev from looping the key change: keyUp plays at most twice, so it lasts 16 bars at most before the outro, where it could run for 80."
56    output: song.js
57    art: 0.65
58    artRuns: [0.64, 0.65, 0.66]
59---
60
61# SELECT * FROM JEV — spec
62
63`song.js` is generated from this spec. Change the spec first, then the song.
64
65## Intent
66
67Jev inside SQL — the user's own `~/postjevsql` design and its neighbours.
68Facts:
69- postjevsql (`~/brains/personal/technology/artificial-intelligence/jev/postjevsql.md`): a pgrx extension putting Jev
70  behind a CustomScan node with a warm connection pool and a durable answer
71  cache; Choice questions over more than 255 options use a label tree (255 is
72  Jev's per-question option cap).
73- jevql (`ecosystem/jevql.md`): `WHERE jev(alias, 'condition')` in vanilla
74  PostgreSQL queries.
75- sqlite-jev (`ecosystem/sqlite-jev.md`): `jev_rows()` batches up to 40 rows
76  per call.
77- jev-orderby-bench: ORDER BY over a Jev probability passes on topic
78  membership, fails four of six on graded product relevance, and 40-row
79  batching fails the ranking gate that one row per request passes.
80
81## Style
82
83- Synthwave, 90 bpm, F# minor: F#m – D – A – E, two bars per chord, so
84  each vocoded line sits on one chord (the harmony cycles every 8 bars).
85- Gated-reverb snare on 2 and 4. The gate is a flat tail cut dead at about
86  250 ms, not a room dying away: the snare (`sn:3`) goes through a custom
87  impulse response (`samples/ssgate/`, 250 ms of flat noise with a 5 ms
88  fade at its end, `.ir('ssgate')`), and a high-passed noise burst holds
89  for the same 250 ms and then cuts. Dirt-samples has no LinnDrum kit, so
90  `linnhats` are the hats and 808 toms the fills. The toms and the final
91  snare use the same gate.
92- The crash is a real one, `hh27:1`: dirt-samples' `cr` is a ride.
93- Sixteenth-note arpeggios, a pulsing eighth-note bass, a bright saw lead in
94  the choruses and instrumentals; no pad — the chords are arpeggiated.
95
96## Structure
97
9864 bars (~2:51).
99
100| Bars | Section | Contents |
101|---|---|---|
102| 1–8 | Intro | Arp alone for 4 bars, its low-pass opening a step a bar (700 → 1000 → 1400 → 1800 Hz, then 2.2 kHz); drums from bar 5 |
103| 9–16 | Verse 1 | Vocoder lines 1–4 |
104| 17–24 | Chorus | Vocoder "Select star from Jev" (17), "Where vibes are true" (19); the hook, "Hello there" (21) answered by "General Kenobi" (22); "Where vibes are true" again on E (23); the saw lead and the chorus lift (below) under it |
105| 25–32 | Instrumental | Saw lead up front |
106| 33–40 | Verse 2 | Vocoder lines 5–8 |
107| 41–48 | Chorus | As before |
108| 49–60 | Instrumental | Key change up a tone (G#m – E – B – F#); no vocals, so no line is stranded on a shifted chord |
109| 61–64 | Outro | Arp in the new key, fading; the kick and bass pulse on through bar 63 under a low-pass closing bar by bar; bars 63–64 are G#m, so the song resolves on its tonic instead of stopping on F# (bVII); final gated snare and crash on 64 |
110
111**The chorus lift.** What makes the chorus bigger than the verse, all of it
112masked to the choruses: a clap (`cp`) on 2 and 4 doubling the gated snare,
113sixteenth hats instead of eighths, the arp's low-pass opened from 2.2 to
1143.6 kHz, a crash on its first bar, and the saw lead at its instrumental
115level.
116
117## Mix
118
119Measured as written with `tools/measure` (`measured:` above); set by
120measurement, not by the numbers in the code.
121
122- The master peaks at or under −1 dBFS; nothing clips. The whole song is
123  scaled by one `postgain` at the end to get there.
124- The kick sits under the vocals.
125- In the instrumentals the saw lead is level with the chorus vocals and a
126  few dB under the drums; in the choruses it plays at that level too. (The
127  brief for this mix asked for about 6 dB under the drums as well as at or
128  above the chorus vocals; with the kick brought down under the vocals the
129  two cannot both hold, and level with the vocals is the one a listener
130  hears as the lead being up front. As measured on 2026-09-25: the lead −28.5 and
131  the drums −25.9 dBFS in the instrumental, the vocals −28.5 in the chorus.)
132- The arp is about 8–10 dB under the drums, louder in the intro and outro,
133  where it carries the song.
134- The final hit (snare, crash, noise tail) is left out of the energy scaling,
135  and sits under the loudest chorus.
136
137## Vocals
138
139- Vocoder, one line per 2 bars:
140  1. "Select star from Jev" — F#m
141  2. "Where vibes are true" — D
142  3. "Custom scan" — A
143  4. "Warm pool, cached answers" — E
144  5. "Order by probability" — F#m
145  6. "Forty rows a batch" — D
146  7. "Two hundred fifty-five options" — A
147  8. "Then a label tree" — E
148- Vocoder chorus: "Select star from Jev" (F#m), "Where vibes are true" (D),
149  then "Where vibes are true" again on E — a separate render, since each line
150  is sung on the chord it lands on.
151- "Select star from Jev" must transcribe as Jev (or Jeff) with whisper
152  `small.en` and `medium.en`: the first render read "GIF" on both. It is
153  spoken as "Jehv" with some of the dry voice mixed under the vocoder.
154- The hook, in each chorus: Obi-Wan's "Hello there", answered by General
155  Grievous's "General Kenobi".
156
157## Jev in the booth
158
159Jev arranges the song as it plays, as two jevs declared at the top in
160TypeSafe's own shape (`jev({ state, questions })`, `website/src/jev/`),
161both given the song as state (subject, tempo, key, chords, lyrics):
162
163- **`formJev`** asks one choice: which **section** plays next.
164- **`djJev`** asks, once that is decided, how much of each part plays
165  this section (the arpeggio, the saw lead, the bass, the drums, vocals: each **out**, **back** or **full**, a
166  score), how the song moves **into** it (a choice), and a score for the
167  section's **energy**. Questions in one request cannot see each other's
168  answers, so it is a second request, told the section just chosen
169  (`after: { section }`).
170
171Both are asked every 8 bars (`.every(8, …)`), and the answers are
172composed in ordinary Strudel at the bottom: `walk` holds the form's rules,
173each part plays at its level (`part(name, pat)`), the transition plays
174over the last bar before each section, and `energy.score` scales the
175velocity.
176
177**The form.** Sections are 8-bar windows of the song as written, so
178`outro` holds the last 4 bars of the key-change instrumental and the 4-bar
179outro. A section may be followed only by these:
180
181| Section | Bars as written | May be followed by | Plays at most |
182|---|---|---|---|
183| `intro` | 1–8 | verse1 |  |
184| `verse1` | 9–16 | chorus1 |  |
185| `chorus1` | 17–24 | instrumental, verse2 |  |
186| `instrumental` | 25–32 | verse2, chorus1 |  |
187| `verse2` | 33–40 | chorus2 |  |
188| `chorus2` | 41–48 | keyUp, instrumental |  |
189| `keyUp` | 49–56 | outro, keyUp | twice |
190| `outro` | 57–64 | (the end) |  |
191
192**Loops end.** Uncapped, the ways back let Jev repeat the key change until the cap: up to 80 bars of it in a row. So keyUp, which may follow itself, plays 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 the key change any path can now take is 16 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.
193
194The key change is one way: once the song is up a tone it can only repeat
195the key-change instrumental or end, so no vocoder line (rendered in F#
196minor) ever sings against the shifted band. These rules are code (`walk`),
197not Jev: each request offers Jev only the sections allowed next. The
198written order is always allowed, and it is what plays when Jev can't be
199reached. The song ends when Jev picks the outro, whose final gated snare
200always lands; at 16 sections the outro is forced.
201
202**The parts.** Each question says what the part is and where it plays as
203written, so Jev can drop parts to build tension or make space, pull them
204back to let others speak, and bring them in full for the payoff. A part
205that is out is silent for the whole section; otherwise its velocity is
206scaled by its level (back is about half, full is as written), and it
207keeps its own masks, so vocals still appear only in the verses and
208choruses. Each part plays on its own orbit, named for its
209question (`.orbit('drums')`, …), so the browser's meter hears each part
210alone. The last gated snare, crash and noise tail always land. When Jev can't be reached, every part plays in full.
211
212The "Hello there" / "General Kenobi" exchange is the hook and always
213plays in a chorus: it is not part of the vocals Jev levels (it plays on
214the vocals' orbit, but at its own level), so a chorus with the vocals out
215still has it. The SQL lines are Jev's to arrange.
216
217**Into the next section.** Over the last bar of each section, the `into`
218answer for the section being entered plays. Each transition is judged on
219that section alone: the moves before it are no reason to repeat or avoid
220one.
221
222- **as written**: the song's own 808 toms roll down across the second half
223  of the bar when the section being entered is chorus 1, chorus 2 or the
224  key change, wherever the path goes (not at fixed bar numbers); into any
225  other section, nothing.
226- **fill**: the same tom roll, into any section.
227- **riser**: white noise, one sustained note across the whole bar, its
228  level and its high-pass both rising (400 Hz to about 8 kHz), so it
229  swells.
230- **dropout**: every part stops for the last beat.
231
232The toms are written once, only here, so a roll is never doubled or cut
233in half, and nothing plays under a plain cut into a verse. The form's ending
234has no next section, so nothing plays over its last bar and its last beat
235is never cut. When Jev can't be reached, it plays as written.
236
237**A little chance.** The section is sampled from Jev's
238probabilities at temperature 0.7 (`sample`), so two plays of the song can
239take different paths; the strip shows Jev's top pick beside the one
240sampled. A close call between
241sections is where sampling matters most, so there is no confidence
242threshold: an unsure Jev still picks, and the written order plays only
243when Jev can't be reached.
244
245**Energy** is a four-step ladder that scales every part's velocity
246together, on top of each part's level, so the mix keeps its balance:
247held back 0.55, steady 0.70, driving 0.85, all out 1.0 (as written).
248
249- Bars 1–7 always play as written; bar 8 carries the move into verse 1.
250- Each request carries the song's state (subject, tempo, key, chords,
251  lyrics), every answer so far, how loud each finished section measured in
252  the browser, where the song is in the form and the sections left before
253  the cap, and the listener's 🔥/😴 reactions.
254- This relaxes the constraints below that the song plays once in a fixed
255  order and never varies by chance: the arrangement varies with Jev's
256  choices, which are judgments, with a little sampled chance in the form.
257
258## Constraints
259
260- Plays once from bar 1 and ends; never loops. Sections are absolute-cycle
261  masks, so playback starts from stopped.
262- Structured: patterns vary by section, never by chance. (Random chopping
263  read as noise on the first song.)
264- No sustained background pad; harmony comes from rhythmic parts.
265- Vocals only in the verse and chorus; the intro, instrumentals and outro
266  are instrumental.
267- Meme clips are the real audio (myinstants, or YouTube via yt-dlp), cut at
268  word timings measured with whisper.cpp. Vocoder lines are made with
269  `speak` + `vocode` on the chord they land on, and checked by transcribing
270  the result with whisper. Everything lands in `samples/<sound>/` with
271  a provenance row in `samples/README.md`.
272- Samples load from `samples('jev-samples/strudel.json')`; drums from
273  `github:tidalcycles/dirt-samples`.