Skip to content

Your Twin

Your Twin is the part of Novaterra that belongs entirely to you. It owns your memory, your profile, your indexed files, and whatever you connect — mail, browser history, a phone number on Telegram — and it turns all of that into a small, growing model of who you are, which the rest of the product (Muse, the omnibar, the desktop’s Now widget, Studio agents) reads from constantly and writes to almost never without telling you. Route: /twin.

Concretely, your Twin is five things:

  1. Memory — a searchable, typed store of facts, episodes, preferences, relationships, documents and insights. See The memory model.
  2. Profile — a compact, structured summary: facts, goals, routines, preferences, tone, timezone. See The profile.
  3. The learning loop — the machinery that turns raw text (a conversation, an email, a file, a day of browsing) into memories and profile updates, on a schedule, without you asking. See The learning loop.
  4. Connections — the sources your Twin is allowed to read: files, Chrome/Edge/Brave history, Telegram, Gmail. Each is opt-in, each can be disconnected, and each is documented on its own page: Files, Chrome history, Telegram, Gmail.
  5. Calendar, to-dos, and the Hush — a committed-intention state machine, a unified agenda, and the restraint discipline that gates every proactive nudge on quiet hours, a daily ceiling, cited evidence, and dedup. See Calendar, to-dos, and the Hush.

GET /api/twin/status

The single place that tells you (and the Settings UI) exactly what your Twin can currently see — what’s configured on the server, what’s connected for you personally, and why not if not:

TwinStatus = {
llm: { configured: boolean },
counts: { memories, files, activity, connections },
providers: Array<{
provider: 'files' | 'browser' | 'telegram' | 'gmail',
configured: boolean, // credentials/paths present on this server
connected: boolean, // you personally have connected it
connectionId: string | null,
label: string,
meta: Record<string, unknown>,
lastSyncAt: string | null,
sync: { status: 'idle' | 'running' | 'done' | 'error', startedAt, finishedAt, error, detail },
hint: string | null, // e.g. "Set TELEGRAM_BOT_TOKEN in .env"
}>,
}

Nothing here is guesswork: configured for files checks whether a root folder actually exists on disk; for browser it checks whether a Chrome/Edge/Brave History file is findable; for telegram and gmail it checks whether the relevant .env credentials are present. hint is always a plain-language next step, never a raw error.

The Twin’s own screen

/twin (apps/web/src/twin/index.tsx) is built around the Constellation — a searchable map of every memory, filterable by kind, with a live drawer for reading (and deleting) any single one. Next to it: the Profile panel (facts, goals, routines, preferences, tone), the Sources panel (this page’s four connections, with connect/sync/disconnect), the Activity stream (a running, human-readable log of what the Twin has actually done — “Indexed 12 files”, “Read 3 new email threads”, “Reflected on 6 new memories and raised 1 signal”), and a Teach box where you can just tell it something directly.

POST /api/twin/learn { text, source } → Memory[]

This runs the exact same extraction the learning loop runs on ingested text — see The learning loop — just triggered by you, immediately, instead of on a schedule.

Reflecting on demand

POST /api/twin/reflect → { ran, signals, widgets, thought }

Normally reflection runs automatically every ten minutes and only when at least three new memories have arrived. The Reflect now button on /twin calls the same function with force: true, so you can ask “what have you noticed?” at any moment instead of waiting for the tick.