FOCUS — a gateway console. Pulsed tones on a timed score, and a point to hold. One HTML file, zero network. https://focus.boyslop.dev
  • HTML 76.5%
  • JavaScript 21.9%
  • Dockerfile 1%
  • Shell 0.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Claude 9e0a84cbda 1.0.0: fix the Docker build, add a publish guard, document releases
- Dockerfile: copy art/ into the build stage (build.mjs inlines it; the
  documented `docker compose up -d` failed without it). .dockerignore keeps
  art/raw and other local material out of the context; server.conf no
  longer ships in the image.
- deploy/nginx.conf.template: drop a host-specific comment.
- test/public.mjs: fail on private addresses, internal hostnames, machine
  paths or key material; self-tests its patterns and refuses an empty scan.
  Runs in `npm test`.
- Page: the source link is a real href (no JS needed) plus a releases link.
- README: size, assertion count, release downloads + checksums. CHANGELOG.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 14:11:12 -05:00
art art: hero, gateway and dawn backdrops from ComfyUI 2026-10-26 23:40:47 -04:00
deploy 1.0.0: fix the Docker build, add a publish guard, document releases 2026-11-02 14:11:12 -05:00
dist 1.0.0: fix the Docker build, add a publish guard, document releases 2026-11-02 14:11:12 -05:00
docs FOCUS 1.0.0 as built 2026-08-01 (from projects/focus-repo.tar.gz) 2026-10-26 23:27:57 -04:00
fonts FOCUS 1.0.0 as built 2026-08-01 (from projects/focus-repo.tar.gz) 2026-10-26 23:27:57 -04:00
scores FOCUS 1.0.0 as built 2026-08-01 (from projects/focus-repo.tar.gz) 2026-10-26 23:27:57 -04:00
src 1.0.0: fix the Docker build, add a publish guard, document releases 2026-11-02 14:11:12 -05:00
static FOCUS 1.0.0 as built 2026-08-01 (from projects/focus-repo.tar.gz) 2026-10-26 23:27:57 -04:00
test 1.0.0: fix the Docker build, add a publish guard, document releases 2026-11-02 14:11:12 -05:00
tools boyslop.dev: art pipeline, save button, footer, forge link 2026-10-26 23:30:59 -04:00
.dockerignore 1.0.0: fix the Docker build, add a publish guard, document releases 2026-11-02 14:11:12 -05:00
.gitignore boyslop.dev: art pipeline, save button, footer, forge link 2026-10-26 23:30:59 -04:00
build.mjs art: embed the hero once (CSS variable); refuse a repeated art reference 2026-10-26 23:45:07 -04:00
CHANGELOG.md 1.0.0: fix the Docker build, add a publish guard, document releases 2026-11-02 14:11:12 -05:00
docker-compose.yml FOCUS 1.0.0 as built 2026-08-01 (from projects/focus-repo.tar.gz) 2026-10-26 23:27:57 -04:00
Dockerfile 1.0.0: fix the Docker build, add a publish guard, document releases 2026-11-02 14:11:12 -05:00
LICENSE FOCUS 1.0.0 as built 2026-08-01 (from projects/focus-repo.tar.gz) 2026-10-26 23:27:57 -04:00
package.json 1.0.0: fix the Docker build, add a publish guard, document releases 2026-11-02 14:11:12 -05:00
README.md 1.0.0: fix the Docker build, add a publish guard, document releases 2026-11-02 14:11:12 -05:00

FOCUS

A gateway console — a self-contained tone console for structured attention practice.

One HTML file. No build step at runtime, no framework, no CDN, no fonts fetched from Google, no analytics, no accounts, no server-side state. Open it from a USB stick on a plane and it works identically to the hosted copy.

That isn't a flex. A tool for sitting quietly with your own attention should not be phoning anyone.


What it does

  • Binaural, monaural, and isochronic beat generation, up to three stacked layers, each with its own carrier, rate, level and method.
  • Session scores — timed programmes with named segments, ramp curves and cues. Eight built in; the format is a small JSON file you can fork.
  • Phase display — a Lissajous of left against right, drawn from the live audio graph. It is not a decoration of the signal, it is the signal.
  • Offline render to WAV through the same code path that plays live, so an exported file is the thing you heard.
  • Practice log — local only, exports as Markdown with YAML frontmatter for a notes vault, or as JSON.
  • Share by link — a whole score deflated into the URL fragment. Fragments are never transmitted, so no server ever sees the session you sent someone.

What it does not do

It does not claim that playing a tone reliably changes your brain state. The evidence for beat entrainment is real but weak: the auditory steady-state response is solid and replicated, while robust effects on mood, focus or "state" are not. Section 05 of the page says so at length, before you press play. Come for the practice, not the mechanism.

It is not a medical device, and it is not the Gateway Experience. See Provenance.


Run it

Save the page. That's a complete installation. dist/focus.html is ~620 KB — fonts and artwork included — and self-contained.

Download a release. Each release carries the standalone page (focus-<version>.html), a source tarball (focus-<version>-src.tar.gz) and a SHA256SUMS file. The same three files are mirrored under https://boyslop.dev/dl/focus/<version>/ — for 1.0.0, SHA256SUMS. Check a download with shasum -a 256 -c SHA256SUMS --ignore-missing.

Docker:

git clone https://forge.boyslop.dev/lockedtrainee/focus && cd focus
docker compose up -d          # http://localhost:8099

Any static host: copy dist/ behind whatever you already run. The generated dist/Caddyfile carries a Content-Security-Policy pinned to the inline script's own SHA-256 hash — default-src 'none' with no network origins allowed at all. If a future edit ever adds a network call, that header breaks it loudly rather than letting it through quietly.

Build from source:

node build.mjs                # inlines fonts, emits dist/, computes the CSP hash
node test/verify.mjs          # headless Chromium: 34 assertions incl. real audio
node test/csp.mjs             # serves dist/ under the generated CSP and checks it
node test/public.mjs          # refuses private addresses, hostnames, paths, keys

No dependencies for the build. playwright only for the tests.


Scores

A score is the unit of practice here — not a frequency. The shape over time is what makes a guided programme work: a tuning phase, a slow descent, a long hold, a deliberate return.

{ "focus": 1, "title": "Descent — 10",
  "bed": "surf",
  "layers": [{ "carrier": 200, "mode": "binaural" }],
  "segments": [
    { "name": "Tuning",  "duration": 180, "ramp": "hold", "state": [{ "beat": 10,  "gain": 0.5 }] },
    { "name": "Descent", "duration": 300, "ramp": "ease", "state": [{ "beat": 4.2, "gain": 0.6 }] },
    { "name": "Hold",    "duration": 840, "ramp": "hold", "state": [{ "beat": 4.2, "gain": 0.6 }] },
    { "name": "Return",  "duration": 120, "ramp": "ease", "state": [{ "beat": 14,  "gain": 0.3 }] } ] }

Each segment declares the state it arrives at; the player interpolates from the previous one. A plateau is a segment whose values match the one before it. Full reference: docs/SCORE-FORMAT.md. Library: scores/.

Every automation point is scheduled against the Web Audio clock up front, so nothing drifts when the tab is backgrounded and setTimeout gets throttled. Frequency changes are phase-continuous ramps, never assignments, so the beat never clicks or loses lock.

Safety

  • Pulsing visuals are hard-limited to 4 Hz regardless of the audio rate — above that the display divides the beat down rather than flashing at it. Photosensitive-epilepsy risk peaks around 15–25 Hz, which is squarely inside the range this tool generates.
  • Declaring photosensitivity on the entry gate removes the pulsing option entirely, not just its default.
  • A limiter sits on the output and every start and stop is faded, so there is no onset thump into headphones at 3 a.m.
  • Do not use while driving or operating machinery. If you have a seizure history, a pacemaker or a hearing implant, clear it with a clinician first.

These are enforced in code and asserted in the test suite, not just written in a disclaimer.

Privacy

The application makes zero network requests after load — asserted by the test suite, enforced by the CSP. Everything you do stays in your browser: localStorage for the practice log and preferences (with an in-memory fallback if storage is blocked), and nothing else. There is no telemetry, no error reporting, no font CDN, no analytics, and no account.

Provenance

The Monroe Institute's Gateway Experience is the origin of this genre. Its tapes, manuals and the Hemi-Sync trademark are their property. FOCUS ships no Monroe audio, no Monroe text and no Monroe branding; every built-in score and cue is original, written for this project. If the structure works for you, buy the source.

What isn't anybody's property: the structural idea, and the declassified US government assessment of the programme, which is a federal work in the public domain — Analysis and Assessment of Gateway Process (CIA, 1983).

Licence

Code MIT. Built-in scores and cue text CC BY-SA 4.0, so the library stays open as it grows. Fonts under the SIL OFL. See LICENSE.


Built by boyslop.dev. Mirrored from a Forgejo instance that runs on a small computer in a spare room, which is rather the point.