Latch

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:

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:

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.