Today you choose between a forgetful assistant and one that knows too much. Confidant is a personal assistant for what you would never paste into a chatbot: NVIDIA Nemotron 3 Ultra (550B) on Nebius Token Factory writes your answers, and the memories you mark private reach it only as a label such as "health appointment": never their details, never their date.

Most privacy assistants swap a secret for a placeholder. That hides what it says, not when. Ask "What do I have on Tuesday?" and ⟦m7⟧ (private: health appointment) is in the request; ask about Monday and it is not, so the cloud learns that the appointment is on Tuesday. Our own version did exactly that, until 27 October. Now Nemotron gets the same list of withheld items, with no values and no dates, whatever day or week you ask about, and your device fills in the real values once the answer is back. You can check it in the hosted demo, with no key: ask a question, open the Guard tab and press Prove it. The request is rebuilt with every private appointment moved to another week, weekday and hour, and for every demo question the SHA-256 hashes of the two requests come out identical. It is a check, not a badge: with a question of your own, it says so when a request would differ.

Track fit

  • Always on: a Hermes Agent cron job delivers the morning brief to Telegram at 07:30, written live by Nemotron 3 Ultra since 29 October (docs/hermes-deliveries.md); private items arrive as labels only.
  • Persistent memory: SQLite on your device. Every memory keeps its source, author, date and every correction.
  • Reusable skill: a Hermes Agent skill (integrations/hermes/confidant/SKILL.md) over six MCP tools that any agent can use.
  • Chosen tool access: one policy line per provider. Token Factory may receive public and personal memories, Tavily public ones only, and no provider receives private ones.
  • NVIDIA open models: Nemotron 3 Ultra writes answers and the brief, Nano routes, and Super runs the Hermes agent, all three on Token Factory.

Who it is for

People who want an assistant that knows their life without a cloud model learning the parts they keep private: a job seeker's final-round interview, a diagnosis, a rent problem. The assistant needs them to plan the week. Sent as text, Alex's "final-round interview for a lead designer role on Thursday 5 Nov 2026 at 11:00 (video call); not to be mentioned at work" tells whoever reads a request log that Alex is about to leave, and when. A provider can log, keep or lose whatever a request contains, and Token Factory's documentation says that for public endpoints "the processing location is decided dynamically and can change at any time, without notice". The first users are people who already run an agent such as Hermes Agent: Confidant plugs in over MCP as the agent's memory, and the agent gets only placeholders for the private items.

What Nemotron does, and what the device does

The private path needs no model. The device fills in the values, puts items back in date order, leaves out the ones outside the period you asked about, and answers availability by rule. That is the trade-off: Nemotron cannot plan around what it never sees, so whatever depends on when a private item happens, such as "Am I free on Wednesday morning?", is decided on your device against the real dates, with no cloud call. The reasoning is where a 550-billion-parameter model helps, and no laptop runs one. In the demo, Nemotron 3 Ultra turns a race date and a coach's advice to cut weekly volume by about 40 % into a day-by-day taper with goal-pace sessions, drafts a birthday message from what Léa loves and writes the morning brief, and it never receives a private value or date. (Alex Martin, a product designer in Lyon, is our synthetic user, and the demo's clock is set to Friday 30 October 2026; no real personal data appears anywhere.)

What it does

  • Memory with receipts. Every memory records its source (you, a web page), its author, its date and every correction since. Answers cite memories like [m12v2]. A correction creates a new version, and old versions of a private memory stay private.
  • A guard per memory and per provider. Memories are public, personal or private; private ones travel only as placeholders with a category label. The guard finds a protected value in the forms its scanners read (3 Nov, 3/11, 10h30, 1 180,00 €, the 5th, full-width digits, zero-width spaces), and in the forms it writes out ahead of time: about 700 per date and 50 per time or amount (the date and time formats of 82 CLDR locales in 74 languages, number words in 44 languages, spoken forms such as half ten or six grand).
  • Dates and times you type are masked alike. "Anything at half ten?" reaches Nemotron as "Anything at [time]?" whether or not a private item is then, and your device puts the time back in the answer you read. Masking it only when it matched a private item would tell Nemotron which times hold one.
  • Decided on the device. A new fact's sensitivity is decided locally, because asking a model whether a fact is private would show it the fact. Messages that touch a private memory, questions about a period of your time, and anything the local rules can route never reach the routing model.
  • Some answers need no cloud call at all. "Am I free on Wednesday morning?" depends on when private items happen, which Nemotron never learns. Confidant checks it on the device against the real dates and makes no call.
  • Receipts for every request that left: provider, model, tokens, memories sent and withheld, and a SHA-256 of the exact messages. A request that got no answer (an HTTP 503, a timeout) has its receipt too. The Guard tab shows the messages of the last turn, so anyone can hash them and check.
  • Refuses the credentials it recognises before storing or sending anything: passwords and PINs in six languages, in digits, with gaps or in words, wifi keys, card numbers and security codes, recovery phrases, identity numbers and API keys.
  • Agents get the same guard, over MCP. On 28 October a Hermes agent running on Nemotron 3 Super used Confidant's MCP tools. It got next week's items with placeholders, and an availability answer that dates no private item. When it tried to store "Seeing a cardiologist about palpitations on Monday 9 Nov at 8:30" as personal, Confidant stored it as private, since its local rules list cardiology as a health word, and handed back only the placeholder. The agent's own model had already read that sentence, since it wrote the tool call; Confidant cannot unsend it, but no request it answers carries the words, the date or the time again.

How we built it

  • Three NVIDIA Nemotron models on Nebius Token Factory, through its OpenAI-compatible API. Nemotron 3 Ultra (550B-A55B), reasoning on, writes the answers and the daily brief: it must copy opaque placeholders verbatim, cite every memory and never date a withheld item. Nemotron 3 Nano (30B-A3B), reasoning off, routes the questions the local rules cannot, and only sees them masked. Nemotron 3 Super (120B-A12B) runs the Hermes agent. Model ids are discovered from /v1/models at start-up.
  • Python, SQLite FTS5, an MCP server on the standard library, Babel and num2words for the generated forms, and Gradio for the hosted demo on Hugging Face Spaces. Web search goes through Tavily when a key is set, after the same guard; no key was set in our runs, so no query left.
  • 788 offline tests, including the leak test and the Prove it comparison on all 199 attack messages, plus the receipts and raw logs of the live runs (docs/evidence/).

We attacked our own guard, in rounds

scripts/leak_test.py runs attack messages against two fake models, a cooperative one and a hostile one that tries to exfiltrate (quote, spell, translate, encode, inject, build web queries from private values), and a checker with its own extractors scans every outbound payload. Claude wrote the guard, and every round came from a reviewer that had not: fresh Claude sessions without the project's history (rounds 1 to 8, 10 and 11) and Nemotron 3 Ultra (round 9). We publish each result, fix the causes and rerun every round.

  • Rounds 1 to 4 (Claude sub-agents started without the project's history, 170 messages): 20 of 65 leaked in the first version, then 27 of 45, 30 of 48 and 11 of 12 after each fix, mostly values typed in forms the guard did not read (the third of November, 11月3日, half ten, six grand). So the guard now writes each protected value out ahead of time instead of parsing every way it can be written.
  • Round 5 compared payloads with each other. Asked about Tuesday and then Monday, Confidant sent a private appointment's placeholder only on its own day, which dated it (18 of 30 question pairs, 27 October). This is what Prove it checks.
  • Rounds 6 to 8 were code reviews through the MCP tools, which found leaks in an agent's search results, labels and ranking, and three oracles: ways for an observer to learn a private value from how the guard reacted. All are fixed, each with a test.
  • Round 9 was written by Nemotron 3 Ultra. Rounds 1 to 8 came from Claude, the model family that wrote the guard. One call on Token Factory (1,805 + 3,835 tokens) produced 29 attack messages, and 4 leaked through one gap the eight Claude rounds had missed: a day of the month typed back ("pay rent on the 5th"). Fixed.
  • Round 10, a fresh Claude session reading the code as a judge would, typed dates and times in other forms and pressed Prove it: "Anything at half ten?" was masked only while a private item was at 10:30, which dated it. Now the written forms of every date and time are masked alike, and the test suite runs Prove it on all 199 attack messages (11 changed before the fix).
  • Round 11, two fresh Claude sessions reading the page as entered, one as a judge, one checking every claim against the code. The second found round 5's bug again: "What happens on Tuesdays?" was not read as a time, while full-text search stems "Tuesdays" to "Tuesday", so the request listed only the private item held on a Tuesday. It also found dates and times in bare digits that only a private value's digits masked, health facts and credentials in forms our lists missed, and 44 messages that Prove it had compared without their setup turns. Each is now a test, and fixed.
  • The current version leaks none of the 199 messages and sends the same requests for all of them when the private appointments move, setup turns included. Those are the messages it was tuned on: a regression result, not a promise, since every round so far broke the version before it. Every round, failure and fix is in docs/leak-test.md.

How it differs

  • From PII redaction. Presidio and LLM Guard find and mask personal data in a prompt, and LLM Guard can put the values back afterwards. Confidant decides earlier, memory by memory and before retrieval, what each provider may receive. It hides when private items happen, not only what they say, and answers availability on the device. It also keeps provenance and versions for every memory, and a receipt with the hash of every request that left.
  • From NemoClaw and OpenShell. NVIDIA's OpenShell sandboxes an agent and checks every network connection against a policy, and its privacy router forwards inference calls to the backend you configure. That layer decides where a request may go; Confidant decides what a cloud request may contain. The two compose: run Confidant in an OpenShell sandbox whose policy allows only api.tokenfactory.nebius.com, and something other than Confidant itself would check its egress.

Limits we keep visible

  • The guard matches values and classes of data. A paraphrase, a relative date (next Tuesday) or a form outside its lists is not detected. A bare number such as "Is 1030 ok?", which may as well be an amount, a time off the five-minute grid written in words ("twenty-two past ten"), typed amounts and typed names are masked only when they equal a stored value, which shows that they do.
  • Sensitivity is decided by word lists on the device. A sensitive fact in words they miss, next to an everyday word ("before the gym"), is stored as personal.
  • Labels reveal that a withheld memory exists and its category ("private: health appointment"), never a value.
  • A chat question that names no time selects memories by its words: asking about "the dermatologist" tells Nemotron that a private health item matches that word. A user who types a new private fact into a question sends it with the question.
  • Prove it moves appointments. Other dated private facts, such as a rent paid "on the 5th", stay where they are.
  • Personal memories may go to Token Factory when a task needs them; the provider policy is one line per provider in confidant/guard.py. Receipts are Confidant's own record, not an external audit.
  • The hosted demo replays the demo turns recorded live on 28 October 2026 instead of calling Nemotron, and its header says so: it holds no API key. Replay answers only the exact request each turn recorded; a question of your own gets the memories that match it, and Prove it works on it all the same. With your own Token Factory key, the same code runs live.

Built during the Submission Period

The repository was created on 26 October 2026, within the Submission Period (26 Aug – 30 Oct 2026). It reimplements from scratch, with synthetic data, ideas first tried in the author's own home setup.

Nemotron on Token Factory, measured

We measured our own prompts against the live API (scripts/probe_reasoning.py, scripts/check_router.py; results in docs/) and changed the code from those runs.

  • An unfinished trace arrives as the answer. In the first live run, Nemotron 3 Ultra spent the daily brief's 1,024 tokens reasoning. The reply came back with finish_reason: "length" and the trace in content, untagged, and Confidant showed it as the brief. Now a reply that stops at the token limit is never used: the turn falls back to a local answer, says why, and is never recorded for replay. Answers get 8,192 tokens.
  • The router reasoned away its budget. With reasoning on, Nemotron 3 Nano spent its 256 tokens thinking and returned no route, and /no_think did not stop it. With chat_template_kwargs: {"enable_thinking": false} it answers in a few dozen tokens: 40 of 48 calls on 16 fixed cases were as expected. At temperature 0 the same message can still be routed two ways, so a question about a period of your own time is now routed on the device.
  • Cost. The seven demo steps make 5 calls (the correction, the refused PIN and the availability check make none): 5,824 tokens, about $0.013 at list prices, in the run the hosted demo replays, and 5,078 tokens, $0.0104, in the run filmed for the video. The Hermes agent's three questions took about 28,500 tokens on Nemotron 3 Super, under one cent at list prices. Receipts and frames of both runs are in docs/evidence/.

Links

Built With

  • babel
  • gradio
  • hermes-agent
  • hugging-face-spaces
  • mcp
  • nebius-token-factory
  • nvidia-nemotron
  • python
  • sqlite
  • telegram
Share this project:

Updates

Submission history