Reactor Player V3: Protecting Data You Have to Show in the Clear
Every test has to put your stimuli on a respondent's screen and read their keystrokes in real time. Our new player is engineered so that the moment of use is the only thing exposed — and even that is honestly bounded.The problem nobody likes to say out loud
Online research has a security problem that is uncomfortable precisely because it cannot be wished away. To run a test, you have to show your client’s stimuli on a screen you do not own, and you have to read the respondent’s reactions — keystrokes, clicks, reaction times — as they happen. Both of those things have to be in the clear at the instant they are used. A stimulus that is encrypted cannot be seen; a keystroke that is encrypted cannot be measured. There is a moment, every time, where the data is plaintext.
Now add the realities of how modern panels actually work. Many respondents are public testers on the open internet, on devices you have never seen and cannot manage. The data you collect — timelines and responses — routinely contains personally identifiable information and free-text. The stimuli themselves are often confidential client IP, sometimes brand material under embargo. You are being asked to display valuable, sensitive material on hostile hardware and then collect sensitive data back from it, and to leave nothing behind.
That is the honest shape of the threat. Anyone who tells you it is simple, or that one clever trick makes it disappear, is selling you something. We would rather show you the work.
Transparent by construction — and why that matters
It helps to know what most of the market actually ships. A great many online research tools — Gorilla is a widely used example — run entirely in JavaScript that executes, readable, inside the respondent’s browser. That transparency is convenient for the people building studies, but it is also literal: the test logic and the data handling are open to inspection on the very devices you least control. This is not an accusation, it is just how client-side JavaScript works — anyone can open the tools built into their own browser and read it.
Look across the implicit and reaction-time field and a pattern emerges in how it positions itself. quantilope automates implicit testing — its association scores are weighted by reaction time — and ships a mobile app. Sentient Decision Science’s patented Sentient Prime embeds implicit, response-latency experiments inside standard and custom survey platforms. These are serious, valid methods, and we respect the science. But notice what the positioning leads with: automation, scientific validity, and ease of embedding. Protecting the stimuli and the respondent data on a device you do not control is simply not the headline — and an implicit test embedded as client code inside someone else’s survey platform is, again, transparent by construction.
So reaction-time systems are genuinely not all created equal. An all-JavaScript player is, by construction, far more exposed than a compiled one: its logic is its source, and its data sits in browsable objects. The new Reactor player takes the opposite stance — the engine, the timing, and the data vault are moved into a compiled core that is not shipped as readable source and does not leave your data lying around in inspectable form. We compete on the same science, and then we add the layer the rest of the field treats as someone else’s problem.
Where we draw the line — and why we say so
Start with the limit, because a security story that hides its limit is not a security story. Anything a person can see on their screen, they can photograph or screen-record. No web application can reliably block operating-system screen capture across every platform, and we are not going to pretend otherwise. A determined person who controls their own machine can, with effort, film the live frame.
So we define that as the accepted floor: a recording of whatever is on screen at a given instant is the most anyone should ever be able to walk away with. The promise we actually make is precise and defensible. The accumulated dataset, the assets, the keys, and the test logic are encrypted, ephemeral, and key-gated. Only the single in-flight event and the one frame currently on screen are ever plaintext — and the rest cannot be extracted as files, as a dataset, or as a browsable copy of anything.
We treat that honesty as a feature. It is what lets your security team evaluate the protections on their merits instead of taking a marketing claim on faith.
Encrypted, ephemeral, and gated by a key you need even in a debugger
The client requirement we set out to meet is blunt: session data should be designed so that it is not readable without the corresponding key, even from developer tools. The new player is built around that.⁴ Every event and response is sealed the instant it is recorded, so the buffer that accumulates over a session holds ciphertext and pseudonymous tokens — never browsable plaintext. The clear-text lifetime of any single value is one in-flight event, not the whole session.
The key that would unlock that store is held outside the view itself — in the host’s secure storage, or derived per session — and is never retained by the page. Collected data is readable only through an explicit, keyed call, not by reading a variable in a console. For public testers, keys are brokered per session and discarded at completion, so the tester’s machine never holds a reusable key, and the player zeroes its memory when the test ends.
Assets get the same treatment. They are fetched with no-store semantics and never written to disk — no HTTP cache, no service worker, no local storage. Encrypted bytes are decrypted only at the moment a stimulus is about to be shown, drawn straight to the canvas, and the buffer is zeroed immediately afterward. At any instant, only the current stimulus is in the clear; everything before and after it is ciphertext or not yet fetched. When the session ends, there is nothing left on the machine to find.
Not just secret — unaltered
Keeping a stimulus private is only half the job, and for many clients it is not the more important half. The bigger risk is that a stimulus is quietly changed on the way to a respondent — swapped, altered, or spoofed. That does not leak your data; it corrupts your study, and the real danger is that nobody notices the results are wrong.
The new player treats authenticity as a design priority, not an afterthought. The same authenticated encryption that keeps an asset secret also makes it tamper-evident: altering even a single byte is designed to fail its integrity check, and the player is built to refuse to show it. Every asset carries a server-signed fingerprint that the player verifies before the asset ever reaches the screen, and the test definition itself is signed, so the stimuli, their order, and the branching logic cannot be swapped out without detection. Because that verification runs inside the compiled core rather than in readable script, it is far harder to switch off than a check an attacker can simply read and delete — and any tampering that is attempted is recorded, so it surfaces in your data-quality checks instead of silently skewing your numbers.¹
Zero stall, without leaving anything on disk
There is a tension here that timing-critical research makes real. Reaction-time and implicit tests measure milliseconds; a stimulus that paints late or audio that buffers mid-trial does not produce a cosmetic glitch, it corrupts the measurement. Those tests cannot tolerate a network or decode stall — which normally means pre-loading assets. But pre-loading and never leaving anything on disk sound like a contradiction.
The new player resolves it by pre-loading into memory, never to disk. All the encrypted bytes are pre-fetched up front into the player core’s private in-memory heap, so there is no network wait once the timed portion begins. A look-ahead pipeline keeps a small rolling window — the current stimulus plus the next few — decrypted and decoded and ready for instant paint, doing that work ahead of the timing path. The timed paint never waits, yet only that small window is ever in the clear at once.
The same timeline that makes this fast also makes the data trustworthy. Because it records precise timing plus explicit anomaly events — media interrupted, playback stalled, answers too fast or too slow — it does more than feed replay. It detects when a respondent did not get an equivalent experience, so a session degraded by buffering or a device problem can be excluded rather than silently polluting your results.
Built for mobile first
Most respondents take tests on a phone, so mobile is the primary target here, not an afterthought. That is exactly why we are moving to a compiled core and GPU-accelerated rendering: tight WebAssembly code and WebGL drawing are how you make a sophisticated, secure player feel light on a mid-range handset. The goal is straightforward — smoother animation and tighter timing on mobile than the current player delivers, not worse.⁵
The one risk we respect on mobile is the initial load: a powerful engine is no use if it is slow to start. So the core is engineered to load once and stay loaded. The compiled module is cached on the device after first use — and crucially, a returning respondent does not pay that cost again — while the first load is streamed and split so the experience can begin promptly rather than waiting on the whole engine. Caching the program is not the same as leaving your data behind: the engine binary can be reused safely, while your stimuli and the collected data remain encrypted, in-memory, and gone at the end.
A compiled core, for opacity and for speed
The architecture builds the engine and the secure data vault as a compiled WebAssembly core driving a WebGL canvas, wrapped in a thin interface layer — mirroring a pattern already proven elsewhere in Reactor. The security payoff is twofold. The logic and data layout are not shipped as readable source, and the core’s memory is an opaque block of bytes rather than the browsable objects a scripting runtime exposes. That makes the test design and proprietary algorithms genuinely hard to reverse, and the encrypted vault hard to pick apart.
It is also simply faster. Just-in-time decrypt, render, and zero; a key-gated encrypted store; an in-memory look-ahead cache; precise stimulus timing — these are all clean to implement in a compiled core and awkward to do convincingly in inspectable script. WebGL rendering means smoother animation and tighter control over exactly when a frame appears, which is the whole game in timing-sensitive work.
We will keep being precise about what this does not do. WebAssembly does not encrypt memory, and it cannot hide the frame on screen. Survey and message screens stay ordinary interface elements, because the respondent has to type into them. Opacity applies to the logic and the stored data — not to the stimulus a respondent is looking at right now. That is the floor again, stated where it belongs.
From real people — not bots, agents, or synthetic data
There is a newer threat that has moved to the centre of every serious buyer’s mind: is this data even from a person? Bots have always tried to farm survey incentives, but automated and agentic systems — and the temptation to pad a sample with synthetic responses — now make “are these real humans, engaging genuinely?” the question that decides whether a dataset is worth anything at all.
This is why a Panel Guard step is built into every Reactor test, not offered as an add-on. Panel Guard applies behavioural-science data-quality checks designed to identify and screen out bots, fraud, and disengaged or automated behaviour — a screening control, not identity verification.² Combined with the timeline — which records precise timing and flags non-equivalent or anomalous sessions — it is how we support confidence that responses come from genuine, engaged respondents rather than from scripts, agents, or fabricated data, subject to the limits of any automated detection.
The third generation — and every one still runs
This is Reactor Player V3, and it helps to see the line it sits on. V1 was the original player: all JavaScript, no timeline — it showed the test and collected answers, but it could not tell you how the session actually unfolded. V2 introduced the timeline, the record of precisely what happened moment to moment, and began the move into TypeScript with the F1 player. V3 keeps the timeline and adds the part that was missing: a Rust-based, security-first core with the encryption, integrity, and anti-spoofing model described above.
Here is the quiet discipline underneath all three. Every test is run with a specific version of the player, and we keep every version. A study fielded on V1 can be re-run on V1 — same player, same behaviour, even the same bugs — so historical results remain reproducible rather than silently shifting under a new engine. Or you can choose to run it on V3 and gain the new security and performance. That is only possible because backwards compatibility has been maintained the whole way through: each generation reads the same test definitions and produces the same shape of timeline and response data. V3 continues that promise — it is a stronger, faster engine under an unchanged contract, not a break with what came before.
Better and more secure, with nothing downstream to change
Here is the part that matters most for anyone already running on Reactor: this is not a migration. The new player is the real player. It consumes the exact same test definitions you author today and produces the exact same timeline and response data as before. Nothing downstream changes — your analysis, your exports, your data pipelines, your reporting all keep working against identical output. It is engineered to be byte-compatible by design, because a player that drifts from production behaviour would quietly change your data, and that is unacceptable.
What you gain on top of that compatibility is a faster, smoother experience for respondents — especially on mobile — tighter timing for the tests where timing is the measurement, a stronger data-protection posture for your clients’ IP and your respondents’ PII, and a timeline that actively flags non-equivalent sessions so your analysts can trust the sample. Dynamic test flow — visibility and skip logic, filter lists, screenouts, sequencing and randomization, and a Panel Guard step that validates respondents and screens out failures — is implemented faithfully and surfaced for pre-field review, so what each respondent actually experiences is exactly what you designed.
So the proposition is straightforward, which is the only kind worth making about security. A better experience, a stronger data-protection story told honestly down to its accepted floor, and minimal migration cost.³ That is the Science of Choice applied to the thing you have to trust most — the moment your stimulus meets a respondent on a screen you do not own.
| What you’re protecting | Typical all-JavaScript reaction-time tools | Reactor (new player) |
|---|---|---|
| Confidentiality of stimuli / IP | Logic and assets are readable in the browser | Compiled core; assets encrypted, ephemeral, key-gated |
| Integrity / anti-spoofing | Client checks are editable; assets can be swapped | Authenticated encryption + signed manifest; tampering rejected and recorded |
| Real respondents (anti-bot / anti-synthetic) | Often a separate add-on | Panel Guard in every test — designed to validate real humans and screen out bots and fabricated data |
| Respondent privacy (PII) | PII can sit in browsable client state | Pseudonymised at capture; key-gated even with a debugger |
| Performance & mobile | JS re-parsed each load; can stall on first paint | WebAssembly + WebGL, cached and pre-loaded; mobile-first, built for zero-stall timing |
| Flexibility | Largely monolithic | Per-device builds, replayable sessions |
| Backwards compatibility | — | Same test definitions; designed for identical data out and minimal migration |
