Overview
Adoora is a sentient door lock you have to emotionally unlock. This week is the application that runs it: the conversation, the trust mechanic, and the interface a visitor actually talks to. The board, the WiFi, and the solenoid it drives are documented under Networking in Week 11 โ; this page is the app on top.
The whole thing is a single
adoora.html โ no build step, no
framework โ using GPT-4o for conversation and
vision, the Web Speech API for the microphone, and a
speech voice for Adoora's replies.
The Interface
The screen is deliberately bare: a circular camera orb showing the visitor, a four-dash code display, a subtitle line for what Adoora is saying, and a Talk button. A numeric keypad is visible the whole time โ but it does nothing until you've earned the digits through conversation.
The interface, live โ the keypad orbits the camera orb, and the subtitle is the vision working in real time: "love the striped shirt, very sharp and a little retro."
Interaction is voice-first: you press Talk, the Web Speech API transcribes you, and after a short silence the turn is sent off. Adoora replies in text on the subtitle line and out loud. The keypad is the only way out โ but it stays inert until trust unlocks it.
The Application Logic โ Earning the Code
The core of the app isn't a passcode check; it's a trust score built across a real conversation. Each message passes through three interlocking systems before Adoora answers.
Phase detection
Every message is read as one of four emotional phases โ BEFORE (surface talk), DURING (something personal surfacing), MOMENT (genuine vulnerability), and AFTER (meta-reflection โ "weird that I just told a door") โ and Adoora's register shifts to match.
Intensity & momentum
Each message gets an intensity score (1โ5) from its emotional vocabulary, punctuation, and hedging; momentum tracks whether you're opening up or pulling back. A run of short, mechanical replies makes Adoora slow down and ask something more direct instead of playing along.
Trust scoring
Each GPT reply ends with a hidden
[TRUST_SCORE: +N] tag โ a
reciprocal moment earns a lot, a one-word reply
almost nothing, rudeness goes negative. The
running total governs the reveal: no digit
surfaces until several real exchanges in, and
then only as trust crosses thresholds.
Digits are never announced โ they're woven into gossip: "I've counted exactly three people who knocked twice today." If the model forgets to embed one, the fallback is a whispered "โฆ3.", as if remembering something small.
The Door Can See You
In the early trust stages, each turn goes to GPT-4o as a multimodal request: a live frame from the webcam is attached with the text, so Adoora notices what you're wearing and speaks to you, not about you โ the opening line in testing was literally "Hello, nice sweater." During testing, several people straightened their posture the moment the camera came on, even knowing it was just their own face in a circle.
Interfacing the App to the Lock
This is where the application meets the device I
made. When the four entered digits match the
session's code, the app fires its unlock state โ the
on-screen "welcome" โ and makes a request to the
board to release the bolt. It's the same call the
control page uses: a plain HTTP
fetch to the board's
/on route over its own access point.
The board catches it, drives the pin high, and the
MOSFET switches the solenoid (the access point,
route, and driver circuit are documented in Week 11
โ).
// app side โ on a correct code, ask the board to open
await fetch("/on"); // board's WiFi AP route
// board side (adoora-control.ino)
void handleOn() {
digitalWrite(CTRL, HIGH); // MOSFET on โ bolt retracts
server.send(200, "text/plain", "open");
}
And here is that request landing โ the board moving the solenoid in response:
The unlock request reaching the board โ the solenoid
retracts and returns. App on one side, bolt on the
other, talking over
/onยท/off.
One genuinely tricky part lives in the app: the code is invented fresh each session by GPT in the browser, so the board has to learn this session's code before it can validate an entry โ the secret is handed over once the story is generated, keeping the talking layer and the switching layer in sync.
What Actually Happened
Three things surprised me in testing. The passive-aggressive idle lines โ "It's okay. I'm used to silence. Mostly." โ landed hard enough that people apologised to the door. The love-confession branch: without saying what it does, people try it. And the code, because it's different every session and tied to memory fragments, doesn't get written down โ people remember it as a feeling, "the third one was about rain", which is strange and exactly right.
A real session โ talking to Adoora, the subtitle replies, and the keypad waiting on trust.
Adoora is about access as a social act. Every door, someone is quietly deciding whether to let you through. Adoora makes that evaluation conversational, emotional, and mutual โ the door wants to be known too.
Problems & How I Fixed Them
The trust tag leaked into the reply
Each GPT response ends with a hidden
[TRUST_SCORE: +N], and early
on it showed up on screen as part of Adoora's
line. Fix: parse the tag out of the raw
response, add the number to the running total,
and render only the text that's left.
Digits sometimes never landed
The reveal depends on the model weaving a digit into the conversation, and sometimes it just wouldn't โ so the code stayed un-gettable. Fix: a fallback that, once trust is high enough, whispers the digit as a half-remembered "โฆ3." instead of relying on the model to embed it.
Flat replies stalled the climb
A run of short, mechanical answers left trust stuck and the conversation going nowhere. Fix: a counter that, after three short turns, makes Adoora drop the act and ask something more direct rather than politely playing along.
Syncing the code to the board
The code is invented in the browser each session, but the board is what has to validate the entry and release the bolt โ so the two have to agree on the secret. The approach: hand the board the code once the story is generated, keeping the talking layer and the switching layer (Week 11 โ) in sync.
Design Files & Source
- adoora.html โ the whole application (HTML / CSS / JS, no build step)
The board and firmware this app talks to live in Week 11 โ.