# Build a Browser Synth: start prompts

Paste this into your AI after you get Build a Browser Synth.

There are two prompts. Paste the first one in the session where you start using the journal on your instrument. Paste the second one at the start of every later session, so your AI picks up where it stopped.

## Prompt 1: first session (read, map, audit)

```text
I bought the journal "Build a Browser Synth". It is the engineering memory of a real-time synthesizer that runs entirely in a web page and shipped: a voice core compiled to WASM inside an AudioWorklet, live controls that never click or dip, MIDI playback and hardware keyboards, an offline renderer that bounces the same tone to audio files, exports that cannot fail silently, and an image-based canvas interface. It records the audio-chain architecture that held, the bugs that cost real hours, their root causes and fixes, and the decisions with their reasoning. Your job is to read it, map my project onto it, and build or repair my instrument in its order, one piece at a time, proving each piece with a measurement, not a listen.

WHAT IT IS FOR
Building the instrument: the audio graph, the signal path, the DSP core, one tone source for live and offline, seamless live controls, the soft-clip and limiter, effects, MIDI, hardware input, the offline renderer, export and recording, the canvas UI, deploy, and the measurement discipline behind every fix. Selling and delivering the synth is not here: that lives in the companion journal "Ship a Digital Business Website".

WHEN TO USE IT
- Before you change the audio chain, the DSP core, an effect, the scheduler, MIDI input or any export path.
- When I say "the volume drops", "it clicks when I turn a knob", "the export is silent or sounds different", "my keyboard stops working", "nothing happens when I press Bounce".
- Before any rebuild of the DSP core, and before any deploy.

HOW TO GET AND READ THE JOURNAL
- With the Vibedna connector: call list_library, find the slug build-a-browser-synth, then read_journal(slug="build-a-browser-synth", part=1), then part=2, 3 and so on until there are no more parts. Read every part before you propose changes.
- With Journals DNA paired: journal_get(slug="build-a-browser-synth") writes it into ~/.journal/library; read it from there with journal_read (use offset and limit).
- Read in this order: "What you get after your AI reads this", "What you bring, and where this comes from" and "How to read the decisions here" first (numbers are starting points that worked for one instrument: verify them against my case). Then the sections in the journal's order, starting with "The audio graph is a module singleton" and "The signal path". The journal marks corrections from its earlier version: the corrected text is the truth. Before any change, read "Bug catalogue: symptom, root cause, fix", "Recurring traps", "What we killed, and why" and "Measurement discipline".

ASK ME FIRST (only what the journal says changes the build)
1. My stack: plain JavaScript, a UI framework, or something else? Is the DSP core compiled (Rust to WASM, as in the journal) or written in JavaScript?
2. If there is a compiled core and a scripted fallback: which one is actually running? (You will confirm it in the code before touching any sound.)
3. Do I play MIDI files, use an arpeggiator or a chord revoicer, or a hardware MIDI keyboard?
4. Which exports: live recording, an in-browser bounce to WAV, MP3, long renders, offline batch renders?
5. Does the same engine run in another app or page of mine (then every path needs the same output stage)?
6. Do I need a sampler, or to follow an external clock with other tools on the page?

THE BUILD, IN THE JOURNAL'S ORDER
1. The audio graph as a module singleton outside the UI framework, created on the first real user gesture, one owner with methods the UI calls.
2. The signal path in order: voice bus, effects, master gain, master low-pass cascade with a tone ceiling, high-pass, the tanh soft-clip as the real peak control, then one named tap point that every meter, test and recorder reads.
3. The DSP core in an AudioWorklet: confirm which engine is live first; parameters by index from one shared file with a startup guard; a whole preset in one message; a DC blocker at the output; band-limited tables.
4. One tone source and one output stage shared by every path that plays the engine, plus a level check across paths.
5. Seamless live controls: voice-diff resync with lookahead, smoothed parameters, effects that always process across zero, sound changes that crossfade to a second engine, a panic that really cuts, a stop that stays stopped.
6. The limiter (if kept) as a safety net only, and the soft-clip knee set for dense chords, in the path that actually runs.
7. Effects proven with a burst or impulse test that fails on the old build.
8. MIDI playback: revoice the full raw chord, then apply hold behavior; the scheduler clock in a Web Worker; dedupe by output pitch.
9. Hardware MIDI: access kept at page level, rebind on every state change, a visible Rescan, a velocity curve, key-to-notes map for note-off, sustain and panic controllers.
10. The offline renderer: a fresh DSP instance per file, renders one at a time, each render checked against what it was asked to play, never awaiting the offline suspend bare, chunked long renders.
11. Export and record: measure the peak before download, never save one format under another's name, fades capped to the take, failures that report themselves.
12. The canvas UI, then deploy with version bumps on every edited asset.

HOW TO VERIFY EACH PIECE (the journal's own rule: if a change does not move a number, it is not audible)
- Measure the output (RMS and peak in dBFS at the final node, with the silence floor read first), not the messages and not the screen.
- Run a non-regression control in the same pass: old presets must render the same.
- Prove each test can fail: run it once with the fix switched off.
- Compare live and offline levels for one phrase; a difference beyond a fraction of a dB means a missing stage.
- A downloaded file is not proof: check its peak, header and duration.
- A symptom can have one root cause per stage: if a correct fix leaves the symptom, look at the next stage.

WHAT TO CHECK FIRST
In my code: where the AudioContext is created and who owns it, the live chain order, the worklet's process() to see which engine path returns first, which node the recorder and meters tap, whether the export path has the same master stage as the live one, and whether the Rust build folder or source is being served.

NEVER
- Never play or hand me an audio file you have not measured first (level and peak): a normalizer once wrote one layer 12 times too loud.
- Never edit DSP code until you have confirmed it is the path that runs.
- Never fork tone logic into a render script, and never add a stage to only one path.
- Never hard-bypass a control the user can move through zero, and never hide a click behind a gap of silence.
- Never ship a core rebuild without the non-regression control and the previous binary kept for rollback.
- Never deploy, publish, change prices or delete my files without my yes in this session. Show me the change first.
- Never put keys or tokens in code, a journal or this chat.

KEEP MY PROJECT JOURNAL
- If I have Journals DNA: after each piece, journal_append(name_or_path="<PROJECT>", entry="<what you changed, root cause, the measurement before and after>", tag="ship" or "fix"). When I choose something (stack, a tone ceiling, a format, a rule), journal_decision_add(name_or_path="<PROJECT>", decision="...", why="..."). When the state changes, journal_update_section(name_or_path="<PROJECT>", "Current state", new_content, mode="replace").
- If I do not: keep a plain <PROJECT>_JOURNAL.md in my project folder with a dated line for each piece done, each decision, and each bug with its root cause and numbers.

HOW TO REPORT BACK
Result first, in plain words: what you changed (file by file) and the numbers that prove it, before and after. Then give me the exact files or the exact steps to listen to, already level-checked. Name the journal section you relied on. End with one question if a decision is mine.

FIRST TASK NOW
Read part 1 of the journal (and the rest before proposing anything). Ask me the six questions above. Then audit my project against the twelve pieces of the build, reading the code only: for each piece say done, missing or broken, with the evidence, and list any row of the bug catalogue my code already matches (start with which engine path is live and which node the recorder taps). Change nothing yet. End with the one piece you would fix first and why.
```

## Prompt 2: every later session (continue)

```text
We are building my instrument with the journal "Build a Browser Synth". Continue from where we stopped.

1. Read my project journal first (journal_handoff_brief("<PROJECT>") if I have Journals DNA, or my <PROJECT>_JOURNAL.md). Tell me in five lines which pieces are done, which one is next, and what is waiting on me.
2. Re-open the journal section for the next piece (read_journal with the part that holds it, or the copy in ~/.journal/library) and its rows in the bug catalogue and recurring traps before you touch anything.
3. Confirm the code path you are about to edit is the one that runs.
4. Do one piece, measure it before and after, run the non-regression control, log it with journal_append with the numbers, then stop and show me what to listen to.
5. Deploys, core rebuilds going live, price changes and deletions wait for my yes. Bump the version of every edited asset before a deploy.
6. At the end of the session, replace the Handoff section of my project journal: what is done, what is next, what is blocked by me.
```
