Modules
Trance
A timed sit with binaural tones, a surf bed and a breath pacer. One wordless score at 30, 45 or 60 minutes, long-press anywhere to stop, and an ending you can hear. No voice, no check-ins, no AI โ yet.
On this page
๐ Trance is the module that does not ask you anything. You pick a length, put headphones on, lie down, and the score plays itself to the end. Nothing to read, nothing to answer, nothing to decide once it starts. The sit lands in the log as one event, like everything else.
This is the first version of it, and it is deliberately small: one score, three lengths, no voice, no check-ins, no AI. Those are coming โ a spoken Handler is the next layer โ but none of it is here yet, and the page below describes what actually plays today, not the thing it is going to become.
What ships today
| The score | Just Beats (plain) โ binaural tones over a surf bed, with a breath pacer. No words. |
| Lengths | 30, 45 or 60 minutes. The ceiling is a setting; the default sit is 45. |
| Stopping | Long-press anywhere for about a second. A tap does nothing. |
| Ending | Audible. The score closes itself; you do not have to watch a timer. |
| Not here yet | Voice, check-ins, any AI, the open-ears (isochronic) alternative. |
The score is a sequence of segments, each with its own beat frequency, walking down across the sit; under them a surf bed hides the seams, and a slow swell rises and falls as a breath pacer to breathe with. Do not chase the pacer. It is a suggestion at a pace you can hold, not a target โ if your breath and the swell drift apart, let them.
The score is code, not a table
Scores are a git-tracked constant (scores.py), not rows in the database, so there is no
score editor on /settings and nothing to back up separately. That is why the exact
frequencies are not printed here: the file is the specification, and a sit stores the
resolved plan it actually played. See How modules work.
You can sit whether or not you are locked. If a lock is running, the sit is filed against that session; if not, it stands on its own.
Headphones, and why
Put headphones on. Not one earbud, not a speaker, not the phone on the pillow.
A binaural beat is not a sound. It is two steady tones at slightly different frequencies, one in each ear, and the beat is what your hearing makes of the difference โ it exists somewhere behind your ears and nowhere in the room. That has two consequences worth saying out loud:
- On one earbud it is inert. One ear gets one plain tone. There is no difference to hear, so there is no beat, and nothing about the sound will tell you that. It will play for forty-five perfectly pleasant minutes and do nothing.
- On a speaker it becomes a different stimulus. Both tones reach both ears and beat against each other in the air โ a real, physical wobble in the volume. That is an amplitude beat, not a binaural one. It is not a weaker version of the same thing; it is another thing.
The app asks once because it genuinely cannot tell
Nothing in a browser reports what you are listening on. Headphones, a speaker, one earbud
with the other on the desk: identical from in here. So before your first sit there is a
three-tap left/right check โ a tone left, a tone right, then both โ and you confirm what
you heard. That answer is stored (trance.channels_ok) and the app stops asking. It is not
a measurement and it does not make the sound safe; it is you telling the app one thing it
has no way to find out. Redo it from /settings if your gear changes.
Where to lie
On your side, or on your back. Not face-down, and specifically not face-down in a hood.
The reason is length, not squeamishness. Forty-five minutes is long enough to hold a position you would never hold awake, in a state where you are deliberately not tracking your body, with the part of you that would normally shift turned down. Pick a position that is still fine if you do not move once. Anything that restricts your airway, loads a joint, or needs a hand holding it in place is not that position โ a sit is not the place to test it.
If you are wearing gear, wear the boring version of it. The sit is the variable; everything else should be the thing you have already done a hundred times.
Volume
Set it in the first minute, at the level you want at minute forty. Then leave it.
Everything about a sit works against you here. The score starts quiet and fills in; your ears adapt; you are lying still in the dark with nothing to compare it to. So the level that feels right at minute two is reliably too loud by minute forty, and by then you are not in a state where reaching for the volume is a small act. Start lower than feels right and let the score come up to it.
There is a limiter after the mix, not before it
๐ด It catches the sum โ the moment two layers peak together โ so a sudden spike cannot happen. That is all it does. It does not know how loud your output is, it does not pull a too-loud setting back down, and it will happily hold a damaging level perfectly steady for an hour. A limiter protects the mix from itself. Your ears are your job.
What is watching you
๐ด Nothing is. This is the most important paragraph on the page.
The whole score โ every tone, every fade, every beat-frequency change, the ending โ is scheduled on the audio clock before the first sound plays. It does not depend on JavaScript still ticking, on the page being visible, on a timer firing on time, or on anything being re-checked as it goes. So a backgrounded tab, a throttled timer, a browser that has stopped running the page's code: none of that alters a single tone or moves it by a millisecond. The sound runs correctly to the end. That is the one thing here that is reliable, and it is reliable because it was decided in advance โ not because something is supervising it.
Nothing is supervising you.
This app is not a safety device
There is no monitoring of any kind. Nothing checks whether you are still breathing, still conscious, still in a sensible position, or still there. The breath pacer continuing is not evidence that anything is watching โ it is a pre-scheduled tone playing out a plan that was fixed before you lay down, and it would play exactly the same way into an empty room. Do not treat its presence as company or as a check.
The ending tone is the only thing you can rely on. Set up the sit so that hearing it is enough: a position you can hold, gear you can get out of, nothing that depends on someone intervening. If a sit needs a person, it needs an actual person in the room โ the app is not one and will never be one.
Two honest edges, because they are the difference between a claim and a promise:
- If the operating system genuinely tears the audio down โ a phone call, low memory, the tab actually killed โ the sound stops. It cannot not stop. What the app does is record that: a sit stores its audio-clock elapsed time, its wall-clock elapsed time, and the gap between them, so a sit that was interrupted is visibly different afterwards from one that played clean. It is a record, not a rescue.
- If both the long-press and the page's own tidy-up die with it, the server closes the sit as
abandonedhalf an hour after it should have finished. That is bookkeeping so a dead sit does not block the next one. It is not a check on you, and nothing is sent anywhere when it happens.
Stopping
Long-press anywhere on the page for about a second. The whole screen is the target โ you do not have to find a button with your eyes shut.
Partway through the press there is an earcon, a short sound that means registered, keep holding. That exists because a silent hold is unfalsifiable: without it you cannot tell a press that is working from a press the page never saw, and you would let go and try again at exactly the moment you least want to be solving an interface. Hear the earcon, keep holding, the score fades.
โ ๏ธ A tap does nothing at all in P0. That is on purpose โ the phone is beside you with the screen on, and a sleeve, a paw, or a roll would end the sit. There is no tap-to-pause and no half-measure: the sit is running or it is over.
The ending is audible either way. You come back on the sound.
Does it actually work?
The honest answer, because you should have it before you spend forty-five minutes on this:
The evidence for binaural beats is weak. Effects reported in the literature are small, replication is inconsistent, and the studies are badly confounded by expectancy โ people who are told a sound will relax them relax, whether or not the sound does anything in particular. Nobody should tell you this is a proven mechanism, and this page is not going to.
What is not in doubt is the rest of the setup: forty-five minutes lying still, in the dark, with headphones on and nothing to attend to, at a time you chose, repeated. That reliably does something, and it does it for reasons that have nothing to do with the tones.
So: the score is the excuse and the container. You showing up is the mechanism. Use it if the container helps โ for a lot of people a sound that has a defined end is the only way the sit happens at all โ but do not credit the tones with what the forty-five minutes did, and do not conclude the practice failed because the tones are unremarkable.
What gets logged
One sit is one event. That is the whole footprint.
| Recorded | What it is |
|---|---|
| Score | which score played, and the exact plan it resolved to |
| Planned length | what you asked for |
| Actual length | audio-clock seconds โ how much sound was really produced |
| Wall length, interrupted | elapsed time, and the gap between the two clocks |
| Outcome | completed, stopped, ended_silent or abandoned |
| Note | optional, after the fact, yours |
XP is one point per minute actually played, capped at 20 โ the same shape as a headspace session in The Handler.
๐ด A sit does not move the clock, and that is a decision
A sit emits its event with a delta of zero. The obvious design โ freeze the lock while you meditate โ is backwards: a freeze stops the clock counting down, so a 45-minute sit would push your release 45 minutes later and the app would be charging you for meditating. Paying time for it is worse: that prices the practice on a hit rate and makes staying shallow the winning strategy. The sit earns XP, which is a record, and nothing else. Contrast Wheel of Fortune, where moving the clock is the point.
Nothing is sent anywhere โ same as the rest of the app, no exceptions for this module. See Privacy. Sits and their checks are both in the export bundle as their own CSVs; see Export and backup.
Reflections are untouched in P0. A sit is not a reflection, does not satisfy the day's required reflection, and does not write to your journal. The Handler's rules are exactly what they were.
โ ๏ธ The database also has a table for per-sit checks โ the responsiveness taps that a guided score will ask for. P0 asks for none, so it stays empty. An empty checks table on a sit is correct, not a fault.
Settings
Settings โ ๐ Trance.
| Key | Meaning | Default |
|---|---|---|
trance.default_score |
Score the page opens on | plain |
trance.default_minutes |
Default length | 45 |
trance.max_minutes |
Hard ceiling on a single sit | 60 |
trance.volume |
Starting volume (0โ100) | 55 |
trance.channels_ok |
Left/right check passed | 0 |
โ ๏ธ trance.channels_ok is written by the left/right check, not by you. Setting it by hand
skips the one question the app cannot answer for itself; if you want it gone, run the check.
What comes next
P1 adds the layer this module was actually built for: a spoken Handler โ the same score with your Handler's voice scheduled into it, reading lines from the prompt library, with responsiveness checks you answer by tapping and a hit rate that means something because the timings were frozen by the server before the sit began. The voice is local; whatever speaks is recorded so the answer to what read this aloud comes from the database and not from a memory of having checked once.
The AI persona behind that voice is the same one described on the Roadmap,
under the same rules: a model on your own hardware, acting through the API as actor=ai, every
action an event, your words never leaving the LAN.
Until then it is one wordless score, and it does not ask you for anything.
This page also ships inside the app, at /guide โ so your own instance always serves the guide for the version you are running, with the internet unplugged. Get Latch ยท Something wrong here? Tell me.