Inspiration

I'm a mom of two figure skaters, and our week runs on pickups. Plans change all the time: someone travels for a month, a backup changes, a rule I made in September is replaced in October. Assistants keep getting better at remembering more. What I need is one that knows which of the things it remembers is still true. When two notes say different things, they look the same in memory — and the one it finds decides who gets asked to pick up my kid.

The demo plays this through a fictional family (Morgan, her son Theo, Alex and Jordan); the problem is mine.

I wanted an assistant I don't have to double-check: one that never acts on an arrangement I already changed, and when it isn't sure, shows me the exact point and asks.

What it does

  • Tell it what changed, in one sentence. "From tomorrow Alex is the backup for Thursday pickups." NVIDIA Nemotron 3 Super turns the sentence into a decision card; code computes the dates ("tomorrow" = Nov 4, from the moment you spoke) and shows which earlier decision it replaces. Nothing counts until you confirm.
  • It keeps two dates for every decision — when it was decided and when it takes effect — and a link to the decision it replaced. Drag the day slider: today the Thursday backup is still Jordan; on Thursday it's Alex. Decided is not the same as in force.
  • It acts only on what is in force. A flight collides with a pickup → the plan that said "ask Jordan" is refused once the arrangement changes; Plan again → "Alex can cover it", with October's card struck through in the Why panel. Approve → a handoff note is drafted (it never sends; you do), and when Alex says yes, the pickup is marked covered and can go to your own calendar as .ics. Own events can be moved, read back by version, and undone in one click.
  • When it can't tell, it asks. Two undated fridge notes disagree about Saturday → it drafts nothing, quotes both, and asks which one counts.

How we built it

  • Model: every call goes to nvidia/nemotron-3-super-120b-a12b on Nebius Token Factory (OpenAI-compatible API, temperature 0, thinking off via chat_template_kwargs). Three jobs: intake (sentence → card JSON), relate (does the new card replace, refine or repeat the existing one?), explain (a short "how it decided").
  • Code decides what is true. A seat graph (TypeScript, no runtime dependencies) resolves which confirmed decision holds each "seat" on a given day; relative dates are computed in code (Chicago time); a code check overrules relate verdicts the values contradict; explanations are checked word by word against the plan's facts and any sentence claiming it will send something is struck out.
  • A spending wall, because Token Factory has no cap of its own. Before each call the app reserves the worst case (input + max_tokens at console prices) in an append-only ledger and refuses past the login's session ($0.15), the day ($1 on the hosted demo) or the total ($47) budget, with a separate rate limit. The free host loses its disk on restart, so each reservation is first written to a private GitHub repo; if that write fails, no call is made. The whole demo change costs about $0.001.
  • How well the model reads a sentence: 12 hand-written sentences, once per model, raw replies in the repo: Nemotron 3 Super 11/12 right with 0 duplicate keys; Nemotron 3.5 Lightning 8/12, with 6 duplicate-key replies. A small set — it explains the choice of model, not general accuracy.
  • Eval of the core claim: 13 constructed scenarios (a fictional family; no model in the loop), expected answers written from the product's rules before running. unworried, given what a parent confirms on each card, acted on the arrangement in force 13/13 — this shows it follows its own rules, not how often these traps happen in real life. On the same notes, a memory that reads start dates got 8/13 — it fixes the timing traps but still treats a question as a decision and acts when two notes disagree; a memory that trusts the newest note got 6/13; one that was never updated got 5/13. 187 offline tests.
  • The same scenarios given to Nemotron 3 Super without the ledger (notes as plain text, raw replies in the repo): 5/13 both ways. Told "ask me instead of guessing", it asked in 12 of 13, mostly about things the notes already settle; not told, it never asked — asking the wrong person 4 times and acting where it should have asked 4 times. One sentence of prompt flips it between the two; knowing which arrangement holds is what tells unworried when to ask.
  • Hosted on Render's free tier; one sandbox family per judge login.

Challenges we ran into

  • Silent card loss. Our first model, Nemotron 3.5 Lightning, wrote the key "cards" twice in one JSON object in 6 of 12 test replies; in 3 of them the second copy was an empty list, and JSON.parse keeps the last one, so a correct card vanished with no error. We now reject any duplicate key and retry, and switched every call to Super (0 of 12).
  • Thinking ate the budget. With reasoning on by default, Lightning spent the full 512-token budget thinking and returned no JSON. Turning thinking off took output from 106 to 2 tokens on a probe.
  • Two clocks. Decisions were resolved at a fixed demo clock while chat timestamps moved with the server, so a judge's newest sentence counted as a "future" decision and every plan that needed it was refused. Our end-to-end tests had pinned the clock, so they never saw it; a new test now moves the clock on every read.
  • The model guessed dates. "From next week" (said on Tue Nov 3) came back as Tue Nov 10 instead of Mon Nov 9. Dates are now computed by code; the model's date only flags a disagreement.

Accomplishments that we're proud of

  • Measured against the model it runs on: Nemotron 3 Super alone, given the same notes, either asks about almost everything or never asks (5/13 both ways); with the ledger, 13/13 and it asks only in the four cases it should.
  • The one-sentence change works live: a plan refuses itself, re-plans, and shows which decision it replaced — end to end on the hosted site for about a tenth of a cent.
  • It refuses honestly: undated or unlinked decisions are never ordered by guesswork.
  • Every login is capped at $0.15 and all logins together at $1 a day, and nothing can be spent without first being written down outside the server.

What we learned

An assistant's memory problem isn't forgetting; it's not knowing which memory is still true. Language is the model's job; deciding what is in force is code's job — and the two should be visibly separate. Publishing the failure cases (the 11/13 first eval run, the duplicate keys) made the work better, not weaker.

What's next for unworried

Real calendar and messaging connectors (read-only first, then approve-to-act), more household topics beyond pickups, and letting a family share one decision ledger with per-person approval.

Known limits (also in the README)

Sandbox calendar only; drafts are never sent; fixed English value shapes per topic; lexical explanation check; free hosting sleeps after 15 minutes and resets sandboxes on restart. All people and data are fictional.

Links

Built With

Share this project:

Updates

Submission history