Inspiration
Lights on. It hides. Lights off. It comes back. Classic. Most demos hunt the insect: wingbeat, a count, a dot on the wall. In a bedroom a fan is louder than wings, and a product that listens for mosquitoes is the wrong object. We flipped it. The insect is a hidden variable. The human is the sensor. The lamp is a judgment, not a reading light. The person moves, then code (gates, filter, or the model) picks a lamp, then we watch what they do in the next 15 minutes. The mosquito is never measured.
What it does
NightGuard is a bedside agent. It never looks for the insect. It watches the person, spends one cheap model call only when the motion is fuzzy, then compiles a personal rule so the next night can skip that call.
- Hard gates first: cold room, already up, leave-bed, nightly budget.
- A 15-minute watch window. Later sit / leave / scratch is evidence, not a new first judgment. At most one lamp upgrade.
- Morning labels stamp last night's cards. Update tomorrow's rules writes one
ignore/downweightline. Code keeps it or bins it. - The public page is one shared room: first click operates, everyone else watches.
How we built it
Python stdlib HTTP plus a three-pane page. No extra web framework.
Code owns time and safety: gates, the window, clock clustering, card weights, a two-opcode filter grammar, and aim lookup onto five static room faces. NVIDIA Nemotron 3 Nano 30B-A3B on Nebius Token Factory is called only for Pass A, Pass B, or the morning compile. After every parse, code overwrites awake, aim, off-lamp fields, and a downweight cap. The insect never enters the prompt.
The hosted demo runs --llm fake on a free Render web service so judges can click without spending credits. Local --llm nemotron is the Token Factory path the video shows.
Challenges we ran into
The hard part was saying no. The model must not invent extra grammar, must not aim the lamp at a body, must not spend a call on a motion code already understands. Splitting “clickable” from “proof” was the other fight. A public page that calls Nano on every scratch would burn the grant. Hugging Face now charges to create Docker and Gradio Spaces, so the click-demo is Render Free: it sleeps after about 15 idle minutes, and the first open can take a minute. The shared room needed one operator lease. Same browser (including two Chrome incognito windows) is the same person; a second browser watches.
Accomplishments that we're proud of
A closed loop in 2:31: night one is messy, a habit forms, one morning compile, night four skips the sigh and still asks about a new scratch. Code and model have different jobs, and the page makes that visible. The public URL is free, has no login, and stays the same after the host sleeps. The repo is MIT, English, and has the run steps plus which Nemotron and where Token Factory is used.
What we learned
A 2 a.m. bathroom trip and a 2 a.m. itch can look the same. A script cannot tell them apart. A model can, but only after code already owns the clock and the safety gates. The useful product sentence is short: observe, learn, compile, ask less. First night can be wrong. That is allowed.
What's next for NightGuard
After the 10/30 submit freeze: the public host should call Nano only on Update tomorrow's rules, with a daily cap, and fall back to Fake LLM on timeout or a bad JSON — same URL. Then, if we ever leave the browser, the lamp policy is already a structured action. We still will not hunt the insect.
Built With
- cursor
- glm
- gpt
- grok
- javascript
- nebius-token-factory
- nvidia-nemotron
- python
- render
- ttsmaker
Log in or sign up for Devpost to join the conversation.