Crown Debrief
Crown Debrief
One dev panel, two features: an end-of-day debrief that reads a day of your brain data and tells you how it went, and a guide that answers questions about the project and adapts to how much you can absorb right now.
Build spec · as agreed
Note: this is the spec as it was agreed at the start, kept as written so the reasoning stays visible. What shipped differs from it in three ways. The product is three screens, Today, Session and Detail, not the five-tab developer panel described below. The shipped guide is keyword search with no model in the loop; the model-backed variants sketched here stayed local experiments and were deliberately never wired into the public build. And nothing in the shipped build calls an external service. Read the rest as the plan rather than a description of the finished thing.
One dev panel, two features: an end-of-day debrief that reads a day of your brain data and tells you how it went, and a guide that answers questions about the project and adapts to how much you can absorb right now.
Projects 2 + 4 4-hour first build Static site for the lab Keyword search, no model anywhere Agreed, building
01 What we’re building
Two features, one shell around them. Both read the same CSV files your existing logger already writes.
Project 2 · main build
End-of-Day Debrief›
You wear the Crown through a work block. At the end, the app reads the CSV and tells you what happened, when you peaked, when you crashed, how long your best stretch lasted, and one thing to try tomorrow. Half of this already exists: your logger writes the data. This finishes it.
Project 4 · golden build
Adaptive Guide›
A chat panel that answers questions about the project, what alpha is, how to run the logger, what a number means, by looking them up in the project’s own documentation rather than improvising. It reads your current state and gives a dense answer when you’re sharp, a scaffolded one when you’re not.
Where you’re starting from
The crown-focus-logger repository already existed when this spec was written. It records focus, calm, and five bands to CSV every two seconds, with a mock mode and a real Crown mode. It is the collection half of Project 2 and it stays exactly as it is; nothing in this spec rewrites it.
02 Three constraints that shape everything
These aren’t preferences. Each one rules out an otherwise obvious design.
The lab’s copy can’t depend on one laptop›
If the handoff is “run this server on a particular machine,” it dies the day that machine stops being maintained. So the version GFT gets has to be a set of files on a web host: open the link and it works, with nobody running anything. That means every calculation the lab version performs has to happen in the visitor’s browser.
The debrief can’t need an AI model›
Two reasons, and the second is the important one. First, a public site cannot ship an API key, anyone with the page can read it straight out of the source. Second, a tool that stops working when an external service is down is fragile in a lab.
So the debrief is computed, then written: a plain analysis engine works out the facts, and a set of sentence templates turns those facts into readable English. No model involved. If you later add a key, an optional button rewrites that same paragraph more naturally, but it’s polish on top of something already complete.
A side effect worth having
Because every sentence traces back to a number, the debrief is auditable. A GFT engineer can check any claim against the CSV. That’s a stronger position than “the model said so”, the constraint made the product better, not worse.
The first version has to exist in four hours
Which means today’s target is working, not finished. Real data flowing, both features usable, nothing faked in the interface. The public site and anything involving machine learning are separate days.
03 Language, revised again: and why
An earlier draft of this plan said Python. The no-server requirement overturns that, and it is worth saying plainly rather than quietly changing.
The reasoning is short. The lab’s copy must run in a browser. Browsers run JavaScript. So the analysis engine and the guide’s search have to be JavaScript, not because JavaScript is better, but because it’s the only language that runs in the place the code has to end up.
The machine learning argument for Python still holds, and it’s untouched by this. ML doesn’t share any code with the app, it reads the same CSV files independently, in its own folder, whenever you get to it. There’s no rewrite, because there’s no overlap.
| Job | Language | Why |
|---|---|---|
| Talking to the Crown | JavaScript | Neurosity’s official toolkit is JavaScript-first, and your logger.js already works. Not touching it. |
| Analysis + guide search | JavaScript | Must run in the browser for the lab’s serverless copy. This is the constraint that decides it. |
| Dev panel server | Node | Only needed locally, only to stream live Crown data. The public site drops it entirely. |
| Machine learning, later | Python | Every serious EEG and ML library lives here. Separate folder, reads the same CSVs, zero shared code. |
The one rule that makes this work
All the real logic goes in plain JavaScript modules that run both in Node and in a browser, no framework, no build step. The dev panel and the public site are then two thin entry points around the same core. Turning one into the other is a config change, not a port.
04 How data moves
Source Crown or mock logger.js, unchanged. Mock invents plausible data so nothing waits on hardware.
no model in the loop"] AN --> D["The written debrief"] AN --> G["The adaptive guide"] NOTE["Session notes
the why behind the numbers"] --> D
→
Store CSV on disk One row every 2s. Gains a person column so multi-person work is possible later.
→
Core Analysis modules Quality filter, personal baseline, peaks, slumps, time-in-state. Pure JavaScript, no network.
→
Surface Debrief + Guide Dev panel today; the same modules on a static site for the lab.
The AI model, if a key is ever present, hangs off the far right as an optional rewrite step. Nothing upstream depends on it, and raw brain data never reaches it, only the computed summary.
05 Project 2: End-of-Day Debrief
Today · must work›
-
Data Load a session Drag a CSV in, or pick one from the data folder. Reads the format your logger already writes.
-
Data Quality filter Drop rows where the electrodes weren’t making contact, and report what percentage of the session survived. A loose sensor produces confident-looking nonsense; this is the guard.
-
Stats Personal baseline Learn your normal range and judge everything against it. Neurosity’s own docs say focus above 0.3 is already significant, which is exactly why a fixed threshold like “0.7 is focused” would mislead every beginner who used it.
-
Stats Peak windows Your three longest sustained stretches above baseline, with clock times.
-
Stats Slumps Dips below baseline lasting more than a few minutes, with clock times.
-
Stats Time in state How much of the session was focused, calm, drifting, or unreadable.
-
Chart Session timeline Focus and calm across the session, with your baseline band shaded behind it. Hand-drawn on a canvas, no chart library, so it works offline.
-
Chart Band summary Average alpha, beta, theta and gamma, plus how they moved across the session.
-
Output Written debrief A plain-English paragraph assembled from the numbers above. No model, no key, no network.
-
Output One suggestion A single rule-chosen tip, kept behavioural and modest, protect the window you’re actually sharp in, that sort of thing.
-
Output Copy summary One button puts a compact, labelled version of the whole session on your clipboard, ready to paste into Claude or anything else. The app owns the numbers; any model you like can own the words.
-
Output Export Download the whole debrief as a Markdown file.
Session notes: the why behind the numbers›
EEG tells you when something changed and is permanently silent on why. A one-line note against a peak or a slump, “back-to-back meetings”, “after lunch”, “the deploy broke”, is the only thing that can supply it. A few weeks of those and the debrief stops describing and starts noticing: slumps cluster after meetings, peaks are all before eleven.
It’s also the same primitive any future model would train on, a timestamp plus what was true at that moment. Arrived at from the useful end rather than the theoretical one.
-
Today The file format Notes live in their own file keyed by timestamp, never mixed into the CSV, so the raw record stays raw. The debrief displays them if they exist.
-
Next Retrospective capture On the debrief screen: “you dipped at 15:10, what was going on?” You get the label with zero interruption.
-
Later Live prompting Only after a dip has clearly persisted, never during a good stretch, always dismissible.
Why live prompting comes last
Interrupting someone to ask whether they’re distracted is itself distracting, a notification fired during a dip can cause the dip it’s asking about. Retrospective capture gets the same label for free. And these notes are more sensitive than the brain data in places, so: local only, never on the public site, never sent to a model without an explicit yes.
Later›
-
Unbuilt Local rewrite experiment Would rewrite the same computed facts more naturally. Local only, and never wired into the public build.
-
Next Multi-day view Compare sessions; find which hours of the day are reliably yours.
-
Next Eyes-closed self-test 30 seconds open, 30 closed, check alpha rose. Turns “is this real data?” into a button, and since Neurosity computes calm from alpha, it validates calm too.
06 Project 4: Adaptive Guide
A specialist that knows this project and your data, for someone who has never heard of EEG. Not a rival to a general assistant, the layer that makes one useful here.
What it’s for, and what it isn’t›
For a one-off, “here’s my CSV, what do you make of it?”, pasting into a general assistant is better than anything built in a week, and the spec doesn’t pretend otherwise. Four things are different here:
-
It computes rather than estimates. The same peak window, the same way, every run, checkable against the CSV.
-
It says things you didn’t know to ask. The debrief is unprompted; a chat only answers the question you thought of.
-
It has the live stream. “What am I doing right now and what would help?” cannot be pasted into a chat window. This is the strongest reason to build it.
-
It works without prompting skill. A lab visitor gets a link and a working thing.
The framing
The app owns the numbers, the model owns the words. Build the layer that makes any model good at this rather than competing with one, which is exactly what the copy summary button in Project 2 is for.
Two versions, because they have different jobs
Local · the dev panel
Adaptive, local experiment›
Live brain state is available on the machine running the headset, so answers could adapt in real time. This variant was explored locally against a key held in .env and was never wired into the public build.
Public · the lab’s copy
Search and explain, no model›
No headset means no live state, so there is nothing to adapt to, which retires the problem rather than solving it. The guide retrieves the right passage and explains it. No key, and nothing that can go down.
This is why the two-depth writing idea is gone: it only existed to fake adaptation without a model, and on the site where there’s no model there’s also no state to adapt to. Every explanation gets written once, properly.
Today · must work›
-
Core Local search A small keyword-ranking search over the project’s own notes. About sixty lines, no dependencies, no network.
-
Core Sources on every answer Which note, which section. Nothing unattributed, this is what stops it inventing things.
-
Core Answers that reach your data “What’s my focus doing?” answered from the loaded session, not from generic text.
-
UI State badge A small label showing what state it thinks you’re in and what it’s doing about it. Without it the adaptation is invisible and faintly creepy; with it you can see it, debug it, and disagree with it, which matters, because the metric is noisy.
-
UI Adaptive on/off toggle Ask the same question twice with it on and off. This is the demo that sells the idea to the lab.
-
UI Starter questions Six suggested questions, so a first-time visitor isn’t staring at an empty box.
Later›
-
Unbuilt Model-written answers Retrieved passages plus the computed summary handed to a model, which answers in its own words. A local experiment only, and not part of the shipped guide.
-
Next Notes in the loop Once session notes exist, “why do I keep crashing at three?” becomes answerable.
Two rules this feature must never break
Adaptation changes the shape of an answer, how long, how scaffolded, how much at once. Never the substance. If you read as scattered it may slow down; it must never soften, hedge, or withhold something true because it decided you couldn’t handle it.
And it stays behavioural. “Your longest good stretch was 10:20-11:05, protect that window” is just your own data read back to you. “Your theta suggests you need more magnesium” is pseudo-neuroscience and would embarrass the project in front of a lab. When something is unknown, it says so.
07 The dev panel
The local developer panel that preceded the shipped three-screen product had five tabs. Four were the product surface; the fifth is what made it a dev tool rather than a demo.
localhost:5173, Crown Debrief
Live Sessions Debrief Guide Diagnostics
Now · mock source
Focus 0.62
Calm 0.48
vs your baseline +0.9σ
Band power
δ θ α β γ
Electrode contact
CP3 C3 F5 PO3 PO4 F6 C4 CP4
One electrode is not making contact. Rows from this window will be excluded.
Guide · adaptive on · state: focused
What does the alpha number actually mean?
Alpha is the 8-12 Hz rhythm. It rises when you’re relaxed and idling, most reliably when you close your eyes, and drops when you engage with something demanding. In your session it’s averaging 0.41, a little above your usual 0.36.Sources: eeg-primer.md § Bands · this session
| Tab | What’s on it |
|---|---|
| Live | Mock/live toggle, focus and calm meters against your baseline, band power bars, per-electrode contact, start and stop recording, session name and person. |
| Sessions | Every CSV you’ve recorded, date, length, row count, how much survived the quality filter. Click one to open it. |
| Debrief | Project 2 in full: timeline chart, the stats, the written paragraph, the suggestion, the export button. |
| Guide | Project 4 in full: chat, state badge, adaptive toggle, sources under every answer. |
| Diagnostics | Raw incoming data as it arrives; which document chunks matched a question and how strongly; the exact instructions sent to the model when one is used; sliders for the thresholds so you can tune them against a real session and watch the effect immediately. |
08 Handing it to the lab
Three tiers, and only the middle one is the actual handoff.
Tier 1 · you, locally
The dev panel›
Node server on the machine running the headset. Live Crown data, recording, tuning, diagnostics, and the guide. The guide is keyword search over the project notes and cites the note each answer came from; there is no model in the loop here or anywhere else. This is the only tier that touches hardware.
Today
Tier 2 · the handoff
Static site›
The same modules, no server, no model, no keys. Published on GitHub Pages from the repo. A visitor drops in a CSV and gets the full debrief; the guide answers from a search index built at publish time. Nothing to keep running.
Day 2
Tier 3 · only if asked
Lab-hosted service
If GFT eventually wants model-written answers on the open web, they run a small service holding their key, rate-limited and operated by them. Documented in the handoff, deliberately not built.
Out of scope
Why there’s no bring-your-own-key›
It was on the list and it’s off it. A key pasted into a web page is readable by anyone with the device, by any browser extension, by any script on the page, and it sits in plain view in the network panel. There is no way to guarantee otherwise.
The worse problem isn’t technical. Asking lab staff to paste a credential into a website trains them to paste credentials into websites, which is the exact habit phishing depends on. Not shipping it, however carefully it’s built.
The one real answer to “a model they can just talk to” is a small model running inside the visitor’s own browser, no key exists at all and nothing leaves their machine. It costs a large first-visit download and a recent browser, and the model is noticeably weaker. Worth a prototype another week; not this one.
The knowledge base is thin on purpose›
Neurosity already documents their own API, so none of that gets rebuilt here. What their docs don’t do is interpret: they’ll tell you focus is a probability derived from gamma between 30 and 44 Hz, and that above 0.3 is significant, but not what to make of your 0.35 on a Tuesday afternoon. That interpretation layer is the only thing worth writing, and it links out for everything canonical rather than copying it.
Privacy, since this becomes public
A CSV dropped into the static site is read in the visitor’s own browser and never uploaded, worth stating on the page itself, because people are right to be careful with brain data. Session notes never go near it at all. And if multi-person collection ever happens, contributing is an explicit opt-in, not a side effect of using the tool.
09 The four hours
| Time | What gets built | Done when |
|---|---|---|
| 0:00-0:30 | Repo skeleton, shared modules, and a generated sample day so there’s real data to work against immediately | A CSV of a plausible working day exists |
| 0:30-1:15 | The analysis engine, quality filter, baseline, peaks, slumps, time-in-state, with tests | Tests pass against the sample day |
| 1:15-2:00 | Dev panel shell and the Live tab on the mock source | Meters move in a browser |
| 2:00-2:45 | Debrief tab: chart, stats, written paragraph, export | Project 2 works end to end |
| 2:45-3:30 | Guide tab: knowledge base, search, sources on every answer | Project 4 answers a real question |
| 3:30-4:00 | Diagnostics tab, README and HANDOFF drafts, full run-through | You can open it and use both features |
If something runs long, the Diagnostics tab is what gets cut, it’s the one thing only you need.
10 Deliberately not doing today
-
Skip Live Crown data The headset last checked in over a month ago. Battery reads 48%, so it’s not flat, it’s just off or off the network. Worth ten minutes to boot it and rejoin wi-fi, but it isn’t a blocker: everything runs on mock and recorded data.
-
Skip Any AI model call Both features work without one. The hook is built, left switched off.
-
Skip Machine learning Today only guarantees the data is shaped so ML is possible later, consistent format, a person column, per-person baselines.
-
Skip The static site Day 2. Today’s job is making sure it’s a config change and not a rewrite.
-
Skip Any git commit or push Files get written, the Markdown gets drafted, nothing gets committed. Your timestamps stay clean.
11 Settled
-
Name Crown Debrief. The guide reads as asking questions about your debrief rather than a second product.
-
Location A new folder,
neurosity-projects/crown-debrief, with a copy oflogger.jsinside so the lab clones one thing. Your original repo is untouched. -
Git Everything built uncommitted, with a
.gitignoreand a suggested commit message ready. Nothing is committed or pushed until you’ve looked at it and said so. -
Sample data Yes, a synthetic week, generated and labelled as synthetic everywhere it appears, so the debrief has something real to chew on from minute one.
-
Model A local experiment only; no model anywhere on the public site. Two-depth writing dropped.
-
Feature scope Nothing dropped from Project 2 yet. If the four hours bite, Diagnostics is the first thing cut.
One correction to the record
Earlier in this planning I described beta as the “focused thinking” band. Neurosity computes focus from gamma (30-44 Hz) and calm from alpha (7.5-12.5 Hz). The mock generator in your existing logger.js already ties gamma to focus and alpha to calm, so the code was right where the explanation wasn’t.
Sources. The Crown Debrief build specification, README.md and HANDOFF.md in the crown-debrief repository, and the Neurosity focus and calm API documentation. Device state was read live from the Neurosity connector.
Phase 1 spec, agreed and now in build. Nothing committed or pushed. Device state read live from the Neurosity connector: Crown-2B1, Crown 3, 8 channels, 48% battery, offline for over a month.
Explore more
This site covers what the documentation doesn't: the things I wish someone had handed me first.