Experimental

Experimental

OMNESIS_EXPERIMENTAL=1 enables unstable features: browser-extension page notes and Find, realtime voice conversations in the Omnesis Demo iOS app, Omnesis Brain, which reads your data in the background and keeps cited notes and loops and writes a morning brief, and Omnesis Watch, which tells you or an agent when a condition becomes true. This page explains how to run, observe and stop them.

These features are experimental as they are unstable and research/exploration projects within the Omnesis code base.

Nothing here is visible unless the process was started with OMNESIS_EXPERIMENTAL=1. Set it on the gateway to reveal browser notes, Find, Brain, Watch and their controls. With it unset, their experimental routes and autonomous work are unavailable. Source indexing, grounded memory reads, evidence invalidation and privacy cleanup remain active. For a gateway you run in the foreground:

❯ OMNESIS_EXPERIMENTAL=1 omnesis gateway serve

For services, add the variable to each unit. Re-running service install rewrites the unit from the flags you pass, so include the ones the service was installed with (such as its keyring flags), then restart it:

❯ omnesis service install gateway --env OMNESIS_EXPERIMENTAL=1

❯ omnesis service install collector --env OMNESIS_EXPERIMENTAL=1

❯ omnesis service restart

GET /status reports whether the gateway is in experimental mode, and the portal, the mobile apps and the CLI use it to show or hide these controls. The flag on the collector matters only for sources: a source marked experimental is offered in the source picker only by a collector that runs with the flag itself. Experimental sources are listed, labelled, in the sources catalogue.

Realtime voice in Omnesis Demo

This iOS prototype is built only into the Omnesis Demo app; the Omnesis app does not include it. With OMNESIS_EXPERIMENTAL=1, assign the Speech-to-speech capability in Models to an OpenAI backend and gpt-live-1 to enable it. The backend needs an API key and inference.allowRemoteInference=true. The capability is off when unassigned; adding an OpenAI backend alone does not enable it. Open an agent conversation and tap the voice-call button to the right of the microphone. Allow microphone access, then speak naturally and hear the reply. The call screen shows the agent's tool activity while it works. The activity disk stays fixed above the scrolling transcript, with different halos for your speech and the agent's playback. Scrolling back pauses automatic following; use Latest speech to resume it. Reduce Motion keeps the halos static. Use mute to pause your microphone and hang up to end the call.

Omnesis Demo sends call audio directly to OpenAI's GPT-Live over WebRTC. The gateway creates and controls the call; the OpenAI API key stays on the gateway. GPT-Live handles listening and speaking. The configured Omnesis agent handles reasoning and tools, with the same instructions, model, permissions and conversation history as typed messages. Tool calls and citations appear in the same conversation, and you can switch between typing and speaking without starting another thread. Text queued during a call waits until the call ends. Audio and relevant conversation context are sent to OpenAI during the call. Voice-session duration is billed separately from the configured agent's model usage; muting the microphone does not end the voice session.

The configured agent keeps its ordinary backend retry behavior. Provider credit or quota failures show a recovery action instead of repeatedly restarting work. Restore the affected provider's API access before trying again.

The call screen reports provider, connection and audio failures with a recovery action. A failed reply can leave the call connected so you can continue speaking; an error that ends the call remains visible until you dismiss it or start another call. Gateway and provider diagnostics are reduced to safe error categories rather than exposing raw provider messages.

Browser extension notes and Find

These features are unstable and require OMNESIS_EXPERIMENTAL=1 on the gateway. With the flag unset or 0, the extension hides both features and the gateway refuses their endpoints, including activation and requests using previously issued credentials. Older gateways without the feature capabilities also hide them. Automatic page capture remains available without experimental mode. Notes in the portal and mobile apps remain available as usual.

Find and reopen indexed content

On compatible gateways, an already paired browser enables Find automatically; no separate portal approval is required. Its separate credential grants ordinary read access across the index. Find displays only results with an HTTP or HTTPS source link, including captured pages, Gmail messages and Notion pages. Native-only links are omitted. This display filter does not restrict the credential's access.

Open Find through om followed by Space or Tab in Chrome's address bar. Each query requests up to 30 results. Search results show titles, matching snippets, site icons and source links. Select a result with the keyboard and press Enter, or click it, to navigate that same Find tab. Ctrl or Command + Enter opens another tab. Query and result state remain available. Going Back to Find, or reloading it, shows that search's results again without searching again; the browser keeps the current search and the five before it. The configured decision model chooses direct index search or a read-only agent search. A blue indicator marks automatic agentic mode. Search views show streamed agent text and tool activity, followed by structured search results. Without an enabled decision model, Find uses direct search. Each query starts a fresh task, with no timeline or follow-up conversation. Results can also link directly to a source record when its provider supplies a browser URL; a separately captured web page is not required. A search ends after three minutes. When an OpenAI-compatible agent backend answers HTTP 429 (rate limited), each model request of the research retries up to three times with up to 90 seconds of waiting, enough for a per-minute quota to reset, within that three-minute limit.

Use om /search your query for direct index search, or om /agent your query for agent research. Both bypass the decision model's routing judgement; plain om your query keeps automatic routing. The command sets the mode separately and is omitted from the query displayed in Find. Agent research requires an enabled decision model. In Find, click the stars beside the search arrow or press Shift + Enter to search the current query with agent mode. This action is unavailable while that query is running or after it has already run in agent mode. Gateways without explicit-mode support report that limitation instead of silently choosing another mode. Suggestions always use the index.

If Codex reports that the search history exceeds its turn input limit, retry with a narrower query. This limit applies to the submitted research history and can be reached before the model's context window is full.

Chrome requests tab and favicon access at installation or upgrade. Find indicates source links already open in other tabs and displays available site icons automatically. Tab URLs are compared locally; the tab list is not uploaded. Icons use Chrome's local favicon service, with a fallback when an icon is unavailable. Neither feature requests browser-history access.

In Chrome's address bar, type om followed by Space or Tab, then your query. On compatible experimental gateways, Omnesis supplies search-index suggestions while you type. Select a suggestion to navigate the current tab to its source link. Submit the query itself to open full-page Find in a new active tab with keyboard focus and run the configured decision-gated search, including streamed agent work when needed. Suggestion typing does not invoke the decision model or agent. Text entered outside Omnesis keyword mode is not sent to the gateway. Older gateways without suggestion support can still open supported full-page Find on submission.

Chrome may preserve existing shortcut assignments after an upgrade or reload. Set the shortcuts at chrome://extensions/shortcuts; popup icon tooltips show the active bindings.

Tell Omnesis from a page

With experimental mode enabled on a compatible gateway, an already paired browser automatically enables Tell Omnesis. Separate device-bound credentials grant notes:create for new notes, read for searching and listing page-associated notes, and notes:update for editing them. The page-capture credential remains write:web; editing requires no additional Chrome permission.

Press Alt + Shift + N (Control + Command + T on macOS), choose Tell Omnesis in the extension popup, or right-click the page. If text is selected, the note includes that quotation; you can remove it before sending. Each opens a side panel with the page context and a focused note field. The icon need not be pinned to use the shortcut or right-click menu. Change the shortcut at chrome://extensions/shortcuts if another extension uses it.

Ctrl + Enter (Command + Enter on macOS) sends the note; Enter adds a line break. Written drafts retain their original page even when you change tabs; an untouched empty draft follows the page where you next invoke Tell Omnesis. Submitted notes wait locally while the gateway is unavailable; reopening Tell Omnesis shows whether they are waiting to sync or saved. They appear alongside other notes in the portal's Tell Omnesis page and in the day's searchable Notes document, with the page URL and optional quotation. The note agent never acts on a note taken in the browser: it is saved and searchable, and changes no task or memory. Its page reference can resolve when the page is indexed later; taking a note does not automatically capture an excluded page. Automatic capture pauses and exclusions do not prevent you from explicitly submitting a note.

Tell Omnesis lists saved notes associated with the page through the gateway graph. Select one to edit its text, or choose New note for a separate draft. Concurrent edits are detected before overwriting. Browser note edits retain the original page context and quotation. The popup provides separate icons with shortcut tooltips. Escape closes either panel; durably accepting a new note (including offline queuing), updating a saved note, or successfully opening a result closes it automatically. Failed saves retain your text. Agent searches reuse the portal's conversation and ephemeral tool components.

Omnesis Brain

Brain is a background agent. It reads your records as they arrive, and on a schedule, without anyone asking a question, and writes down what it learns in a form the rest of Omnesis can use: dated facts, unresolved commitments, cited context on documents and people, maintained project and topic wikis, and observations for a once-a-day morning brief. It is the one part of Omnesis that spends model tokens with nobody asking, so most of this section is about what it does with them and how to bound it.

The Brain never checks or rewrites what the agent says to you. Conversations in the portal and apps, and answers given to external agents, are exactly what the agent wrote; its instructions tell it to read the relevant wiki page and use the engine's answer policy. Individually verified claims whose supporting evidence is still current can answer the question without reopening that evidence. Other claims require source checks. Answers to external agents still pass your privacy review.

  1. TriggersA new or changed record, a daily or scheduled pass, a historical catch-up
  2. Run queueVersioned maintenance batches, inside the daily budget
  3. Agent runbackground-agent model with read tools over your corpus
  4. GatesCited evidence, entailment verifier, record check
  5. StoresTime index, loops, annotations, wikis, observations
Source changes invalidate evidence immediately. Model work runs in queued maintenance batches, and synthesis writes pass reference and evidence checks.

What it writes

Brain stores maintained understanding in the gateway database. Claim references and revision history connect generated context to the evidence used to produce it.

Record What it holds Where you see it
Wikis and root overview Reusable context for projects and topics, with claim-level provenance. A compact root wiki provides current orientation and must fit its configured size limit. Debug → Cognition → Library
Time index Temporal annotations: Brain's reading of what a date means and when it applies (“the kitchen fitting starts the week after the deposit clears”), each with the documents it came from. The agent's time query returns them beside source dates and date mentions. Debug → Cognition → Timeline
Open loops Unresolved actions, decisions, promises and obligations, with who owes what, the documents involved, a deadline where there is one, and a ledger of every run that changed the loop. States: open, snoozed, done, dismissed. A loop Brain finds is a suggested task until you accept it. Tasks → Suggested, then your Tasks once accepted; Debug → Cognition → Library
Annotations Durable notes about documents and people, each backed by a quote from a cited document and a confidence. The agent's memory reads the same notes. The document or person page; Debug → Cognition → Library
Observations Things a run noticed that you may want to hear about in the next morning brief, each citing and quoting its sources, with the window in which it matters and the loops it relates to. None reaches you directly. Debug → Cognition → Observations; Debug → Cognition → Library
Morning brief One message a day in a standing conversation, built from the observations that survive the morning recheck, the day's calendar and what is due (see Observations and the morning brief). The Morning brief conversation, in the portal and the apps

With OMNESIS_EXPERIMENTAL=1, the portal's Tell Omnesis page also shows Agent interpretation entries and open loops under each day's collapsible Related to this day section. These are live temporal annotations and loops that cite that day's notes document. These links cover the whole day rather than individual notes; stored records remain visible when the Brain is stopped.

The agent reuses a complete tracked-outcome inventory within a turn and opens only relevant details. It can request a larger listing after truncation or refresh the inventory when new information warrants checking for changes. The compact root wiki supplies current orientation. The agent can open maintained pages by their node ID or existing wiki link through the same authorized read. Existing agent notes remain available for working lessons (brain.notesMaxBytes bounds that notes file). Brain can also decide pending person-merge proposals that the deterministic matcher left open: merge (a reversible rule that records the model's reason), distinct (the proposal is denied and not proposed again), or unsure (left for you). Proposals that involve you are never decided by Brain.

Observations and the morning brief

Brain does not interrupt you with what it finds. During any run, it can note an observation: a short statement of something you probably do not know and would act on, why it matters, the documents it rests on with an exact quote for each claim, and when it stops mattering. A quote that is not in its cited document is refused. When an observation is noted, the decision model scores three things: what missing it would cost you (consequence, 0 to 4), when acting on it matters (timing, 0 to 3), and how likely you already know it.

Those first scores feed a would have pushed log. An observation is logged there when it has the top consequence, acting on it matters today or tomorrow, and its window closes before the next morning brief, so that it would have earned an immediate notification. No notification is sent for it; the log exists to show whether such a push would ever have been worth having.

Each morning at brain.digest.hour one run rechecks every open observation, in this order:

  1. expire those whose window has ended;
  2. drop those whose evidence was deleted or went stale;
  3. drop those whose related loops are all resolved;
  4. score the rest again with the decision model, now told what happened since they were noted, and ship, hold or drop each one: drop when you probably already know it (brain.observations.alreadyKnownMax, 0.6), ship at consequence 2 or above (minConsequence), or at consequence 1 when timing is 2 or above (minTimelyConsequence, timelyLevel), and otherwise hold it for a later morning;
  5. check the claims of those that ship with the entailment-verifier, dropping any it does not support.

Every judgement fails open: with no decision model, or one that does not answer, an observation ships, and an unavailable verifier ships it unverified. What ships is ranked by consequence, then timing, then age.

The same run then writes one message, the morning brief, into a standing conversation named Morning brief. It is pinned and cannot be deleted, and opens like any other conversation in the portal and the apps. Every item that ships is included, together with the day's calendar and what is due; weekends are no different. When there is nothing (no observations, no calendar, nothing due), no message is written. brain.digest.push sends one notification when the brief is written.

The conversation reads by day: a separator names each day, and each brief shows when it was sent and, under it, Based on N things: its observations, with links to their documents and related tasks, plus other supporting documents used to write the brief. These can be calendar entries, emails, conversations, files or other indexed documents, even when there are no observations. Today's list is open; earlier days fold to one line until you open them.

Each observation carries a thumbs up and a thumbs down; supporting document links have no reaction controls. A thumbs up tells Brain this was worth your morning. A thumbs down asks which of two things is wrong: Not interested teaches Brain that items like this one are not worth your morning and that suggestions like it are not worth making, with whatever you type or dictate as your reason; Factual error says nothing about your interests, marks the item disputed, and sends your correction to Omnesis as a note. Tapping thumbs up again clears it; a thumbs down is removed from its dialog. Nothing is inferred from an item you left alone.

Reply in that conversation to act on the brief. The agent sees that morning's brief and its items, so “the second one” resolves, and acts on what you say with its task tools, stating each change in one line. “Don't tell me about this” suppresses an item for good; a stated preference (“I don't need reminders about newsletters”) is also remembered as a fact about you and recorded as what you care about, so later briefs and task suggestions leave similar things out. Earlier days stay in the transcript but are outside the agent's context.

What you accept, create or ignore in Tasks, the thumbs you give brief items, and what you say in this conversation are the only things Brain learns your interests from. Before it ranks an observation for the brief, judges a new suggestion, or decides how soon to read new evidence, the decision model is shown the few past reactions most like the item in front of it, with your words where you gave any. Debug → Cognition → Interest lists every reaction it has recorded, lets you try a lookup, shows each suggestion verdict, and offers any withheld suggestion again. Set brain.interest.enabled to false to stop recording and showing them.

In experimental mode, Tasks gains a Suggested view in the portal and the apps. By default, loops Brain finds appear only in Suggested and become yours when you accept them. With the suggestion gate set to enforce, the interest-based policy described below can instead adopt or withhold them. Enabling Brain preserves existing tasks and their document links; new supporting sources are added without replacing links on tasks you already own. On the apps a suggestion looks like any task: tapping its circle marks it already done, and a long press offers Accept, Accept with note, Accept for… a planned day, month or someday, Mark as done and Ignore; the portal offers the same actions on the suggestion's line. A note written while accepting is saved as a Tell Omnesis note about that task, and the note agent applies it to the task. You can also ask Tell Omnesis or an interactive conversation to accept or ignore a suggestion. The agent finds the suggested task and records the requested action with an undoable receipt; it does not accept other suggestions on its own. Ignore only takes the suggestion out of Tasks: Brain keeps tracking the loop behind it and does not suggest it again. Each of these can be undone from its receipt. Accepting a suggestion is where you decide whether a task is worth tracking; after that, Brain keeps it current on its own. It retitles a task or rewrites its description when you did not write that text, adds to a description you did write, and marks a task done or sets its deadline when a source states the fact explicitly and the entailment verifier confirms the quoted text establishes it. Striking a task, changing anything else you wrote or edited yourself, and a completion or deadline that cannot be verified are proposed instead: the task shows the proposed change and its reason, with Confirm to apply it or Keep to leave the task as it is. A change Brain applied reads Marked done by Omnesis or Updated by Omnesis in the task's history, with its reason and an Undo; undoing it also keeps Brain from making that change on its own again, and the next morning brief mentions such changes in one line. When a decision model is assigned, a new title applies on its own only after it is checked to still name the same task, and a note that only repeats a task's history is left out of it. Proposals still waiting when Brain starts are checked again: one that no longer changes anything is dropped, and one Brain would now apply on its own is applied. Set brain.tasks.autoApply to false to have every change proposed. Your own tasks never decay. Without experimental mode, neither the Suggested view nor proposed changes appear.

With a decision model assigned and brain.tasks.proposeGate set to enforce, a new suggestion that resembles something you reacted to is judged against what you did then: clearly like suggestions you ignored, it is withheld; clearly like tasks you accepted or created, it is adopted as your task at once; otherwise it is suggested as usual. brain.tasks.proposeGate sets what the verdict does. shadow, the default, only records it, so Debug → Cognition → Interest shows what would have happened. enforce acts on it: a withheld suggestion stays tracked and comes back when you undo it from its history, and an adopted one reads Added by Omnesis with an Undo; undoing an adoption is the strongest sign that suggestions like it are unwanted. off asks nothing. A model outage leaves a suggestion as it is.

Debug → Cognition → Observations lists observations by state, with each one's close reason, its scores when noted and at the recheck, related tasks, the run that noted it and the brief message that carried it. The same tab shows the would-have-pushed log and each day's brief items. Closed observations are kept for 90 days (brain.observations.retentionDays), then reduced to an outcome record of their state, scores and what you did.

Turning it on

Brain runs only when two things are true: the gateway runs with OMNESIS_EXPERIMENTAL=1, and a model is assigned to the background-agent role and can actually be reached. Either alone does nothing. The second step is the one that starts spending: assigning the model starts the enabled producers, from reacting to new records to scheduled sweeps and the morning brief. Read Bounding the spend before you assign it. The one exception is the catch-up over your history, which waits until you start it yourself (see How it runs).

❯ omnesis model assign background-agent <backend>/<model>

❯ omnesis model status

The value is anthropic/<model>, codex/<model>, claude-code/<model> or <backend>/<model> for an OpenAI-compatible backend you configured (see Operating → Models). A local GGUF model cannot serve background-agent, which needs a chat backend; it can serve entailment-verifier. The portal's Settings → Models page lists the Brain's model roles under Cognition. Optional capabilities can add checks and routing decisions:

Model capabilities

These experimental uses require OMNESIS_EXPERIMENTAL=1 and are unstable. The stable roles and their setup are listed under Operating → Models.

Role What it does When unassigned
background-agent Shown as Brain agent in Settings → Models. Runs every Brain agent run and compiles natural-language watches. Tell Omnesis uses the ordinary Agent model, independently of this assignment; its tokens appear as Note agent in the spend breakdown. The two assignments are separate and are never copied automatically. If an existing setup assigned only Brain agent, select Agent explicitly to process Tell Omnesis notes. Optional model-based identity classification also requires the Brain to be active; ordinary deterministic contact matching works without it. Brain does not run. Stored records stay readable.
entailment-verifier Checks that the quoted evidence actually supports a claim before an annotation is stored. A small, fast model is enough. Claims are stored after the citation check alone, with no verification stamp.
decision Routes urgency, discovery, dependency repair and review, checks whether new records belong in durable memory, and scores observations for the morning brief. Served only by TypeSafe Jev (typesafe/jev-1.13.0); see Routing maintenance and Checking what it writes. The role itself is stable; Models covers its setup. Urgency and relevance checks take a conservative fallback; record verification remains separate.
watch-judge Judges semantic conditions for automation Watches. This is separate from the decision role that routes Apple Watch complication captures. Conditions that need a semantic judge cannot be evaluated.
speech-to-speech Handles listening and speaking during live calls. The separately assigned agent handles research and tools. Live calls are disabled.

Decision model uses in experimental mode

The same decision assignment used by stable features also serves these flows. Assigning it does not enable the Brain or browser features by itself. Depending on the flow, TypeSafe receives the query, relevant source content, memory records, task context or past reactions needed for the decision.

Codex can serve background-agent and entailment-verifier through the same ChatGPT login, and Claude Code through the same Claude Code sign-in. The verifier runs as its own model turn even when it uses the same model as the agent waiting on its verdict, and every role shares the account's usage allowance. GET /status reports the gate as brain, with visible, enabled, modelAssigned and active; the portal's Debug → Cognition pages say which of the two conditions is missing.

How it runs

Each Brain agent session is a run, with read-only tools over your corpus and write tools for the stores above. Runs wait in a durable queue and a drainer works through them. Maintenance batches retain their input versions and pending frontier across interruptions; the engine controls admission and repair order.

New and changed sources enter a durable maintenance queue. Immediate rule-based invalidation marks affected claims stale before model repair. Changes to a source's title or dates also invalidate its dependent claims, even when the body is unchanged. The decision model selects an immediate, hourly or six-hour maintenance tier; thresholds and delays are configurable under brain.knowledge. Related changes can share a batch. Disjoint project regions remain separate, while the root overview is refreshed as a shared aggregate.

The synthesis agent receives successive dependency frontiers through tools. The engine checks input versions and decides when work is complete. An unchanged claim stops its propagation path. New evidence also gets a discovery pass to find existing context or propose a useful page; a document does not automatically become a wiki. A late-arriving old message is still considered, with its original time and attribution. Proposed pages receive a bounded curation review; publication still requires useful, grounded content, and explicit deferrals retain their reconsideration date.

Brain runs read documents in pages: unless a run asks for a range, each fetch_many read returns at most brain.documentReadChars characters of a body. A maintenance run's conversation is also bounded. When a request's input reaches brain.knowledge.contextHandoffRatio of the model's reported context window, or brain.knowledge.contextHandoffTokens when no window is reported, the run stops after its current tool calls and a new run continues the batch from a fresh context. A request the provider refuses as too long is handed on the same way, so settled work is kept. After brain.knowledge.maxStalledHandoffs handoffs in a row that settle nothing, the batch fails the ordinary way. omnesis brain run <id> shows the largest request input and why a run handed off.

Bounded organization passes also consider already-interpreted sources together. They can maintain a useful wiki about a settled decision or arrangement without creating a new task. The agent records the grounded page targets, a no-page decision, or a deferral with a bounded reason code; unchanged inputs are not reconsidered on every tick. These passes share the Brain's budget and do not expand historical access. If a joint decision relied on incomplete search, index publication makes that group eligible for one catch-up review without waiting for its ordinary repeat interval. This can enrich an existing page or confirm that no page is needed.

A source excerpt does not count as a complete read. Before recording considered coverage, the agent must receive the full current source content. Discovery settles after both interpretation and organization are considered; conversion is separate. Sources admitted together need not share one topic: organization can investigate useful subsets and related existing pages.

Historical organization is opt-in. Open Debug → Cognition → Discovery and press Start reading history. The pass honors historical enablement, active hours and admission caps, and reports separate interpretation, organization and conversion coverage. Recent-first is the default; historical evidence need not contain a future date to be useful. Upgrading preserves existing loops and annotations without promoting their legacy attachments into verified claims. Initial collector imports expose partial coverage as they arrive. Their recent window (brain.knowledge.recentWindowDays, default 30 days) is admitted recent-first and is eligible immediately at routine priority, so importing history does not give it urgency over already-due reviews. Existing queued work keeps its assigned priority. Older and undated inventory follows the historical-review controls. Later arrivals and edits remain reactive, even when they describe older events.

Historical review reaches back brain.bootstrap.horizon (default 90d), measured from now against each document's own date, not the date it was imported. Older documents are never read proactively, by the catch-up or by an initial import, and the coverage chart shows them as outside the horizon rather than pending. Pending catch-up work that falls outside the horizon is withdrawn; reviewed work is kept. Brain still finds older documents through search when they are relevant. Raise the horizon (for example 1y) to reach further back; the change applies on the next pass.

Wikis use descriptive titles, sections for supported topics, and links to related pages and tracked outcomes. The compact root overview links to relevant detail pages. Structure grows with the available evidence; there is no page quota. Navigation links do not imply evidential support. A root summary that uses a wiki as supporting detail must also link to that page; this does not require linking every page in the library. Publishing a new wiki schedules the root overview at the configured soon tier; ordinary page edits use the routine tier. When wiki navigation is missing, a bounded selection of historical link identities can help the agent find currently readable pages to reconsider. Old links and facts are not restored automatically.

Before publishing a wiki, the agent checks existing pages and candidates and explains why the proposed topic needs its own page. Publication requires claim support from at least two current, readable documents with distinct content; merely listing documents on a candidate does not satisfy this check. A single-document summary belongs in an annotation or an unpublished candidate. Existing pages remain editable after source loss. These safeguards encourage topic synthesis but do not guarantee its quality or a mathematical relationship between document and page counts. Incremental verification does not reset a wiki's whole-page review clock. When a bounded investigation cannot support a useful improvement, the agent can retain the exact existing page after reviewing its claims and defer editorial curation to a later routine review. This does not certify completed curation or bypass evidence checks; new evidence can still trigger maintenance.

Wiki updates preserve existing claims unless the agent explicitly records their removal and its reason. Empty wiki replacements are refused. This protects against accidentally dropping sections; it does not establish that retained or rewritten claims are complete. New internal links to synthesis pages are checked for available targets before saving; unchanged older links are not retroactively validated. Independent page repairs can run without conflicting solely because another wiki changed. Wikis should synthesize durable context, while the time index retains individual events. Newly published pages receive a placement review; adding or removing a parent relationship schedules review of the affected pages. Whole-page reviews record whether placement is connected, standalone, or deferred for follow-up; the outcome appears beside that version in History. Standalone pages remain valid, and organizational links do not count as factual evidence.

Synthesis uses Markdown with addressable claim spans. Normal reading hides the tags, while editing and inspection retain provenance. Wiki and root writes require every nonblank text span, including headings, to sit inside a claim tag. This structural coverage check is separate from evidence verification. The entailment verifier checks tagged assertions against their evidence, including the subject and scope implied by a wiki's title, section headings and enclosing claims. Moving unchanged text to a different scope requires fresh verification; syntax alone cannot guarantee that every assertion is supported. Unavailable verification leaves claims unverified. Contextual checks select exact authorized source segments rather than copying quotations; source qualifications and interpretation limits still apply. A proof-policy upgrade requires bounded re-verification before older proofs can support new assertions. The root wiki is limited by brain.knowledge.rootMaxChars (8000 characters by default).

The answering agent can retrieve maintained pages through its document tools. Page reads separate claim evidence pointers from navigation links and mark truncated lists. Root edits explicitly acknowledge removal of readable wiki navigation; this prevents silent loss during factual repair without requiring every page to appear in the root. Synthesis helps orient an answer. A page or loop read identifies the exact verified claims that can be used without reopening their sources, preserving their attribution, conditions and time scope. The agent cites the page it read; a page's links do not authorize citations of unread original documents. Other prose, unsupported claims and changed evidence require source checks. The page's current status alone is insufficient: it means linked evidence has not changed, rather than certifying every sentence or ruling out newer contradictory records. Questions about the latest state still require checking for newer evidence.

agent.useBrainKnowledgeMode controls how the built-in answering agent and its delegated workers use maintained knowledge. The default, check_stale_claims, permits answers from the exact current verified claims returned by a page or loop read; other claims and current-status questions still need evidence checks. check_all_sources uses maintained knowledge for navigation but always checks supporting sources. off removes wiki/root context and tracked-outcome read tools; document, search and graph tools then exclude those pages and outcomes. The loop-backed Task journal tools, automatic Tasks overlay on today's time queries, and injected task-conversation context are also unavailable in off mode. Original documents, analytics and grounded memory remain available in every mode. The Brain continues maintaining its knowledge, and stored pages and outcomes are retained. Restart the gateway and start fresh conversations after changing the mode. Independent Direct connections are unaffected; old conversations may still contain information read before the change.

Debug groups the library, agent runs, maintenance batches, discovery controls, and confidence and feedback diagnostics under Cognition. Agent runs includes current execution health, full transcripts and tool calls, and token spending. Each transcript shows its own reported attempt usage; missing usage is unknown, and an attempt is not a total across retries. Its Running filter shows the live count and active runs. Gateway diagnostics and database tools remain under System and Data tools. Maintenance supports reason, tier and status filters; each batch shows its tier and all recorded reasons. Filters apply before paging through the history.

Open Debug → Cognition → Library to browse the Brain’s library. Selecting an entry keeps the library’s filters and loaded results in place. On desktop, the list and reading pane scroll independently. More entries load as you approach the end of the list; Refresh includes newly added or updated entries. Person notes identify their subject and link to the current person profile. In Overview, switch between rendered Markdown and Raw to inspect the original claim tags. Hover over or focus the quote indicator at the end of a claim to preview its verification, assessment, supporting references, and which pages use the claim or whole page as support. The claim is underlined while its preview is open; hovering over the text itself does not open a preview. Claim links open the referenced passage in Overview. Connections shows the page’s incoming and outgoing references, including context and organization links. Source documents appear once as an icon and linked title. History shows each saved version’s changes from its predecessor in a collapsed diff; expand a version to inspect its additions and removals. Advanced contains identifiers, metadata, and exact claim mappings. Maintenance status distinguishes pending work from completed work; a current page is not necessarily verified. Maintenance separates inputs waiting to be grouped, inputs assigned to batches, and recent batch history. Historical deferred records are excluded from the waiting count. Select a batch to inspect its checks and open the agent transcript.

Loops live in the same Library. Choose Loops in the type filter to browse active or resolved outcomes, and sort loaded results by deadline, importance, or recent update. Each outcome shows its canonical status and synthesis in one view. Outcome details and activity shows people, evidence, related observations, scheduled checks, and the activity ledger without expanding a section. Advanced fields are also shown without disclosure controls. Outcomes remain readable before synthesis is available. Status filters and pills distinguish active, resolved, and retired outcomes in the same list; outcome details retain recurrence information. Observations also live in the Library, with their state filters, close reasons and full metadata. Older loop links open the corresponding Library entry. Behavioral notes has the brain’s operating lessons; these are distinct from the root wiki’s account of your life.

Run kind What starts it
synthesis — maintenance A tier is due, discovery finds new context, or a synthesis review needs repair.
Historical organization Opt-in source-revision work admitted into maintenance batches.
daily Once a day at brain.dailyRunHour (05:00 gateway local time): a batch per high-volume source whose records are reviewed together rather than one by one, and the morning recheck and brief at brain.digest.hour (07:00).
time_based A follow-up Brain scheduled for itself, or a status check on an open loop that has gone quiet (spaced out further each time, up to 30 days).
synthesis The “Noticing” pass for connections, trends and gaps across the corpus (at most once a day), and collisions between loops that share a person, document or day.
sweep A scheduled sweep came due (see Sweeps).
verification The daily re-check of the stalest annotations against their evidence.
feedback A note that a loop was built on was withdrawn or superseded. An observation built on such a note is dropped without a run.
merge_adjudication A person-merge proposal the matcher could not decide.
notes_compaction The agent-notes file grew past its size limit.
subscription_compile A natural-language watch was compiled (see Watch). Recorded for its transcript; it never waits in the queue.

The queue serves your feedback first, then new records, then scheduled work, and the catch-up and re-checks last. A run that fails is retried up to five times, waiting one minute and then doubling the wait up to an hour.

When a model call fails, Brain looks at what the failure blames. A malformed or oversized request, or one a content filter stopped, is the run's fault, and the run is retired after its retries. Anything else is the environment's fault: no credit, a rejected key, a rate limit, an unreachable backend, a signed-out or missing Claude Code, a model the backend does not offer, or a server whose context length cut the prompt short. Then the run keeps its place and its attempt is refunded until you fix the cause. After three consecutive backend failures the drainer stops claiming work and backs off from one minute to fifteen, and the Discovery tab shows a Model backend — Failing banner with the provider's own error. Nothing is lost while it lasts.

What it will not write

A model's output is not trusted because a model wrote it. Every write passes checks that sit outside the model:

Searchable assistant conversations remain historical context, not independent evidence for their claims. Brain verification uses authenticated, complete attributed utterances; current original sources must be read separately. Long or partially read utterances may remain readable without providing factual support.

A stale maintained page may still expose individually current, qualified claims. Direct reads can handle a freshness-only mirror delay at the same revision. Other prose remains orientation only; privacy restrictions and changed read snapshots still prevent use.

Maintenance can reuse the exact frontier receipt observed by a complete editing read instead of transcribing its fingerprint. Explicit mismatches and stale source, owner or privacy state remain refused.

Synthesis saves report bounded stored claim verification states. A successful save or completed review can still leave claims unverified. Whole synthesis references provide orientation; factual support requires qualified claims or original evidence.

Loop claim verification checks each assertion in its bounded final outcome context. Surrounding prose is interpretation, not additional evidence. Older literal-only proofs are rechecked gradually, including retained completed outcomes without reopening them. Operational loop updates remain separate from claim verification; a stored description is not a guarantee of factual accuracy.

Exact loop reads can reuse current context-verified assertions with their conditions, attribution and time bounds. Surrounding prose and tracked open state do not prove additional facts, present-world obligations or completion.

Evidence-backed timeline entries pass their configured record-value check before paid evidence verification. An enforced value refusal avoids that verification call; cancellation stops the write, and source freshness and privacy checks still apply.

The experimental Brain admits at most two independent remote verification checks at a time; native verification remains serial. Backend pool limits and existing verification deadlines still apply.

Routing maintenance with the decision model

The decision role can select an urgency tier, decide whether new evidence deserves interpretation, assess whether changed inputs could affect a dependent claim, and prioritize proactive review. TypeSafe Jev supplies typed scores rather than prose. A low relevance score can settle a work item without a synthesis turn; uncertainty or an unavailable judgement keeps the conservative repair path. Existing invalidated time-index entries still receive their evidence review.

These checks send the selected evidence context to TypeSafe, so they need inference.allowRemoteInference: true and a TypeSafe API key. Enter the key from Settings → Models → Decision model, or with omnesis backend key set typesafe, then assign the model:

❯ omnesis model assign decision typesafe/jev-1.13.0

Discovery checks complete sources within a 128 KiB application input budget, including the decision rubric. It does not truncate a document to decide it is irrelevant. Larger or empty inputs and missing decision models are admitted for inspection; Decision details identifies these engine bypasses separately from model judgments. This budget does not advertise a provider context limit.

If Jev cannot be reached or returns an invalid answer, the engine records an unavailable judgement and follows its conservative fallback. Inspect decisions beside the maintenance work or agent run they explain by expanding Decision details. Urgency checks show the captured policy, score and applied schedule. Exact requests and model results are loaded on demand; older redacted records and unavailable inputs are labelled explicitly. Advanced history keeps retained decisions accessible after their work or transcript is gone. Input copies follow decision-history retention and deletion of contributing sources. The Brain diagnostics show decision purposes, input fingerprints, normalized scores and model usage. Metadata is retained separately from the bounded input snapshots. Decision tokens count toward the daily token budget, not the daily agent-run budget. The key can also come from OMNESIS_TYPESAFE_API_KEY or TYPESAFE_API_KEY in the gateway's environment. To reach a private TypeSafe deployment instead of the public API, set inference.typesafe.url.

When parallel maintenance discovers a shared target, the Brain coordinates its updates before running write checks. A conflicting run returns its work to the planner and stops its turn; the evidence remains queued for a combined or later pass.

Checking what it writes

Outcome deadlines receive a separate support score in the same decision request: a relevant forecast or event date cannot become an action due date without evidence. Unsupported deadlines can be cleared while retaining the useful outcome; approximate action deadlines keep their source qualifications. The audit shows each score and the limiting requirement.

New wiki publications and changed wiki prose are checked for actual synthesis value: several citations, a document inventory or copied boilerplate are insufficient by themselves. Concise integrated accounts can qualify. Root orientation and unchanged prose proof refreshes skip this value check. It uses the existing default threshold and record-check mode; missing or oversized context is recorded as unavailable and fails open, not as a quality approval.

The same decision model also checks annotations, tracked outcomes, wiki drafts and dated entries written during live, historical, or maintenance runs. For document annotations it reads bounded source context and supporting excerpts: the annotation should add meaningful cross-source context or substantially compress a long substantive document. Restating a short source or shortening boilerplate is insufficient. New document notes pass this value check before entailment verification, so an enforced refusal avoids that verifier call. Caller cancellation still prevents the write. Person annotations need useful context about the person, such as a role, relationship, preference or standing responsibility; one explicit source can suffice. A one-off message or event summary merely involving someone is insufficient. Describing a source that mentions someone is not a person fact unless the assertion itself adds useful context about them. Historical scope and source attribution are allowed. Person and document notes require meaningful value (at least 1.5 on the decision model’s 0–3 scale), rather than marginal usefulness. Profiles are curated as a whole, with defaults of 20 active facts and 4000 characters per person. An independent score in the same request checks that the final profile distills distinct person-level meaning rather than listing supporting documents or repeating retained facts. Necessary historical qualifications stay; additional corroboration belongs in evidence rather than growing the profile prose. Configure these limits through brain.annotations.personProfile; the agent consolidates overlapping facts instead of appending a note for each source. Time-index entries are judged for personal relevance; an automated notice can still contain a meaningful fact. This check happens after the agent’s research and drafting, so it does not avoid the initial synthesis turn. brain.annotations.recordCheck sets what happens: shadow (the default) saves every record at once and scores it afterwards, enforce scores it first, drops a low-scored record and tells the agent not to retry it, and off asks nothing. If Jev does not answer within 15 seconds, the record is saved. Missing or unsafe source context also leaves a document annotation unjudged rather than guessing its added value. Person-profile replacements and revisions are checked against the useful context they would replace. Scheduled person-note reviews also reassess whether to retain each fact in the current compact profile; an enforced refusal requires correction, consolidation or retraction before the review completes. Autonomous person-note withdrawal uses the same profile-utility standard in a separate preservation check: truth alone does not make routine or incidental details useful profile context. A retention refusal never authorizes deletion by itself; useful supported meaning must remain in the profile or be replaced atomically. In enforce, an unavailable withdrawal assessment leaves the old fact pending instead of deleting it. Irrelevant, unsupported and redundant facts may still be removed. Ordinary evidence refreshes do not repeat this editorial check. Tracked outcome creation and substantive changes are checked for supported responsibility, event identity and current status; autonomous outcome assertions require original evidence. Pure scheduling and dismissal, anything you hand to the assistant, and memory you ask for directly are not checked. Each verdict is shown on the run it was made for, with the record and the document it came from, and its tokens appear as Decision model · record check. Verdicts are deleted after the activity-retention window.

Every judgement the decision model makes is recorded and shown in Debug → Cognition with a scale icon: worth admission, record and task checks, the suggestion gate, observation salience, discovery and review timing, and, outside any Brain run, date-mention worth and search routing. Open Maintenance → Advanced → Retained decision history to filter them by kind; each one also appears on the run, page or observation it was made for, and Request and answer shows exactly what the model was asked and what it answered.

Discovery includes a month-by-month coverage chart. Switch between Read evidence and Connect context to inspect the two discovery stages. Reviewed, gated, deferred, failed, and pending sources remain distinct. Counts describe current imported document versions, not history outside your sync range; a connection review does not necessarily produce a wiki page.

During backfill, imported documents can become readable before search catches up. Discovery treats incomplete search as uncertainty and records a bounded catch-up review for after index publication advances. This review does not consume historical admission again. A completed index scan still does not prove that every document is searchable.

Once started, historical bootstrap fills its available batch fairly across sources. Admitted history is ready immediately; the routine maintenance delay applies to live changes. Independent maintenance uses four workers by default. Daily admission, backlog, active-hour and spend limits still bound catch-up work.

Bounding the spend

Everything is measured in tokens and runs, never in money: no model API Brain talks to reports a price, so any currency figure would be an estimate. Convert with your provider's own pricing.

A catch-up run is a full agent session, several model round-trips rather than one completion, so the catch-up lane is where large bills come from. The Discovery tab's Budget section splits the day's tokens into fresh input, input re-read from the provider's cache (billed at a fraction, and a subset of input, not an addition) and output. On the catch-up lane the observed cache share depends on the backend, model and prompt prefix. Compare measured fresh and cached input with your provider's pricing; no fixed output ratio is assumed. Cache totals include only usage reported by the provider. A zero aggregate does not establish that every input token was fresh; missing historical cache details cannot be reconstructed.

All limits are set with omnesis config set <path> <value> (or the portal's Settings → Config) and are read live, so raising one resumes work without a restart.

Key Default What it bounds
brain.budget.dailyTokens no limit All background cognition tokens per local day. Reaching it parks the queue until the next day rather than failing runs.
brain.budget.dailyRuns no limit Completed background runs per local day, parked the same way.
brain.bootstrap.maxRunsPerDay 200 Historical source-revision work admitted per local day. Several seeds may share one synthesis run; this is separate from the agent-run budget.
brain.bootstrap.maxRuns 1,000,000 Lifetime historical work admissions for the install, not reset by removing a source. The lane parks when it is reached.
brain.bootstrap.horizon 90d How far back historical review reaches, by each document's own date. Older documents are not read proactively and do not count as pending.
brain.bootstrap.activeHours unset A local window, {"from": "HH:MM", "to": "HH:MM"}, in which the catch-up lane may enqueue work. A window whose end is not after its start wraps midnight.
brain.reverification.maxPerSweep 12 Re-check runs per daily sweep, the second-largest producer.

Brain maintenance reserves bounded capacity for outdated-proof repairs alongside root and organization work, while retaining capacity for ordinary discovery. This does not bypass budgets or retry delays.

The daily ceilings count interactive agent spend as well, because a budget that chat could exhaust alongside would not bound anything. The catch-up window gates when the lane enqueues work, not when an enqueued run executes; a run already bought is finished. To turn spend down, in order: lower maxRunsPerDay, move the catch-up into off-peak activeHours, lower reverification.maxPerSweep, switch individual producers off (reference), and set budget.dailyTokens as a hard stop under all of it. For example:

❯ omnesis config set /brain/bootstrap/maxRunsPerDay 50

❯ omnesis config set /brain/bootstrap/activeHours '{"from":"01:00","to":"07:00"}'

❯ omnesis config set /brain/budget/dailyTokens 2000000

The Discovery tab reports the catch-up lane as one of five states:

State Meaning
unstarted Nobody has pressed Start reading history yet.
off brain.bootstrap.enabled is false: the lane is paused.
waiting Outside activeHours, or the daily admission allowance is spent. Previously admitted work can still execute.
running Historical admission is enabled within its bounds; an empty queue does not prove corpus completion.
parked Historical admission reached maxRuns or the shared cognition budget. Raise the relevant ceiling or wait for a daily budget reset.

Sweeps

A sweep is a scheduled pass across many records for one kind of pattern that no single arriving record would reveal: people you are waiting on, a trend in your health data, subscriptions worth reviewing. A sweep is a name, a cadence, a local time and a paragraph of prose; the prose is the only per-sweep logic there is, and it is placed inside a fixed set of instructions it cannot override. Sweeps run under the same budget as every other run and stop when brain.sweepsEnabled is false.

Eight sweeps ship with the gateway: Day ahead and Missed calls (daily, at the daily run hour), Weekly finances, Waiting on others, Health trends and Upcoming horizon (weekly), Relationships (every two weeks) and Subscriptions (every 30 days). You can add your own, or retime, silence or rewrite a built-in one, as Markdown files in sweeps/ under the config directory; the file name is the sweep id, and a file named after a built-in sweep overrides only the keys it sets. Edits take effect without a restart, and the portal's Settings → Sweeps tab edits the same files.

sweeps/unsent-promises.md
---
name: Promises I made
cadence: 7d
at: "06:30"
enabled: true
---

Look for promises the user made to someone else and has not yet kept:
sending something, booking something, giving an answer. Surface only the
ones where a reminder would help; skip anything already done or still
comfortably within the promised time. An empty pass is a good outcome.

Every front-matter key is optional; a new sweep needs cadence (at least 24h, counted in whole days) and a body. Without at, a time is derived from the id so sweeps do not all queue at once. An unknown key or a bad value skips that one sweep and is reported on the Sweeps tab and by omnesis doctor. A sweep fires once per boundary: a gateway that was down for a month runs a missed sweep once, not once per missed period. Treat a sweep file from someone else like a script: it is handed to an agent that can read your whole corpus, so read it before enabling it.

Observing it

In the portal, Debug → Cognition holds the Library (pages, loops, annotations and observations) and the Timeline; Agent runs shows the queue, transcripts, decisions and spend; Observations and Interest follow the morning brief and what Brain learns from your reactions; Maintenance follows repair batches; Discovery shows coverage, the budget and historical admission controls; Confidence & feedback compares stated confidence with observed outcomes; Behavioral notes shows the agent-notes file. System → Gateway jobs shows when each scheduled task last ran. The same data is available from the CLI:

Command Shows
omnesis brain loops [--state open] Tracked open loops; omnesis brain loop <id> for one in full, with its ledger and the observations noted about it.
omnesis brain runs [--kind bootstrap] [--status failed] The run queue, newest first; brain run <id> for one run.
omnesis brain transcript <id> One run's prompt, tool calls and final text; --json for the raw transcript.
omnesis brain decisions [--doc <id>] What Brain decided about a record, and why.
omnesis brain spend [--days 30] [--by-mechanism] Tokens by day, or by day, mechanism and model.
omnesis brain calibration How stated confidence compares with what later held up.
omnesis brain notes The agent-notes file.

Transcripts are kept for the activity retention period unless brain.transcriptRetention sets a different one. A transcript contains corpus text the run read, so treat it with the same care as the corpus.

Pausing and turning it off

There are four levels, from narrowest to widest:

Keeping sources out of Brain

brain.excludedSources lists sources Brain never processes. An entry is either a source type, which covers every source of that type, or one source's id, which covers only that source:

❯ omnesis config set brain.excludedSources '["codex","github:jamie-lopez"]'

The list is read live; no restart is needed. A type that is not installed yet is accepted and applies once a source of that type is added. While a source is excluded:

The agent you talk to is not affected: it still searches and reads every source. Knowledge already derived from an excluded source is kept as it is, and Brain still sees it as knowledge: an annotation keeps its quoted evidence, a loop keeps its linked documents, and a page keeps the claims that cite the source, unchanged. Those annotations are not re-verified while the exclusion holds, and no new or changed claim may cite the source. Editing or deleting one of its documents still repairs or removes what cites it. Removing an entry makes the source's documents eligible again: historical review admits the ones inside brain.bootstrap.horizon, and later arrivals and edits are reactive as usual. Documents that arrived while the source was excluded are not replayed as live arrivals.

Privacy and removing its records

Brain reads the same corpus the agent does and sends what a run reads to the backends assigned to its roles, and nowhere else; it has no web access. With a hosted model, the documents a run reads go to that provider. HTTP backends on a non-loopback address are refused unless inference.allowRemoteInference is on. The morning brief's notification travels through your push setup like any other conversation notification.

The agent reads open loops and the time index when it answers a question, so they can inform an answer through Answer, which passes your privacy review as usual. A Direct grant exposes them only when it is unrestricted. Observations are exposed to neither.

Loop lists normally help the agent choose records to read. For counts or recorded rankings, it can request a dated tracking snapshot instead. These answers describe accessible stored records at the stated observation time, not every real-world obligation; discovery and maintenance may still be incomplete. If snapshot support changes while answering, the agent may discard it and rewrite once using independently read evidence. The rewrite cannot rely on the discarded inventory's counts or rankings; privacy and source changes still hold release.

What Brain writes stays in the gateway's database with the rest of your data and is part of backups.

Deleting a document, whether for good (see Search → Beyond search), by a sync or by removing its source, never deletes what Brain built on it. The document itself can no longer be read or cited. The loops and tasks, observations and annotations that rested on it lose their link to it, are marked stale and wait for Brain to review them. A dated fact keeps its link but loses the evidence quoted from it, and is reviewed through any task it belongs to; a wiki page's claims that relied on it turn stale. A review keeps, revises, resolves or removes each one as a deliberate decision. Text they quoted from the document stays with them until then.

To remove what Brain wrote:

Configuration reference

All keys sit under brain in the gateway's configuration and are read live. Durations are written like 30m, 6h or 7d. The budget keys are in Bounding the spend.

Key Default Meaning
excludedSources none Source types and source ids Brain never processes (Keeping sources out of Brain).
recencyWindow 7d How recent a record must be to wake the live lane.
conversationDebounce / conversationMaxDefer 1h / 6h Quiet period before a conversation's run, and the most it can be deferred.
documentUpdateDebounce / documentMaxDefer 30m / 4h The same for an edited document.
derivationBarrier 30m Longest wait for links, people and dates to be derived before a run proceeds.
pendingContentBarrier 1h Longest wait for a voice note's gateway transcript before a run reads the note.
workerConcurrency 4 Concurrent independent maintenance workers (1–32). Root updates and legacy runs execute one at a time. Codex also has a separate background runtime capacity under inference.codex.backgroundPoolSize, defaulting to 4.
dailyRunHour 5 Local hour of the daily runs.
digest.enabled / hour / graceMinutes / push true / 7 / 45 / true The morning brief, the hour it is composed, how long it waits for the overnight queue to drain, and whether writing it sends a notification.
notesMaxBytes 8192 Soft size of the agent-notes file (at most 32768); past it, a compaction run shrinks it.
awarenessAxis true Also ask the daily pass for connections, trends and gaps, not only obligations.
synthesis.enabled / cadenceHours / maxPerDay true / 24 / 1 The “Noticing” pass over the whole corpus.
collision.enabled / maxPerSweep / timeHorizonDays true / 3 / 60 Daily check for loops that share a person, document or day, and for dated notes up to 60 days ahead that conflict. annotationContradictions (on, 2 per sweep) looks for notes that contradict each other.
annotations.enabled true Durable notes on documents and people. basisCeilings and confidenceFloor are described in What it will not write; recordCheck (shadow) in Checking what it writes.
reverification.enabled / intervalDays / maxPerSweep / batchSize true / 14 / 12 / 6 Daily re-check of notes last verified more than 14 days ago: runs per day, notes per run.
provenanceRecheck.enabled true Re-examine loops whose supporting note was withdrawn.
observations.retentionDays / alreadyKnownMax / minConsequence / minTimelyConsequence / timelyLevel 90 / 0.6 / 2 / 1 / 2 How long closed observations are kept, and the policy the morning recheck uses to ship, hold or drop them (see Observations and the morning brief).
mergeAdjudication.enabled true Let Brain decide undecided person-merge proposals.
tasks.autoApply true Let Brain keep your own tasks current on its own instead of proposing every change (see Observations and the morning brief).
tasks.proposeGate shadow What the verdict on a new suggestion does: off, shadow (record only) or enforce (withhold or adopt).
interest.enabled true Record what you accept, ignore, thumb and say, and show the decision model similar past reactions.
interest.lookup.perPolarity / cosineFloor / overlapFloor 4 / 0.55 / 0.2 How many past reactions of each kind the decision model is shown, and how similar one must be to count, by vector or by shared words.
bootstrap.enabled / direction true / recent-first The catch-up lane, and the order it walks history (oldest-first also accepted).
bootstrap.backlogTarget / batchSize 200 / 100 Most catch-up runs queued at once, and documents taken per pass.
sweepsEnabled true Run scheduled sweeps.
transcriptRetention unset How long run transcripts are kept; unset follows activityRetention.maxAge.

Omnesis Watch

Watch tells you, or an agent, when a condition becomes true: “a renewal email has waited five working days for my reply”, “three large card payments in one week”, “every Monday at 8”. A watch is a small program in a JSON language, checked against what your gateway actually holds, that follows the stream of new and changed records from the moment it is added. Most of its work is deterministic filtering and counting; a model is asked only when a condition needs judgement, and only about records that got past the cheaper steps.

  1. JournalNew and changed documents, analytics rows, loops, clock ticks
  2. Filter and recallSource, type, people, fields; similarity or literal terms
  3. JudgeOnly when needed: one bounded call on watch-judge
  4. StateWaits, counts, sequences, cooldowns, kept per key
  5. FiringA recorded row and a trace that explains it
  6. DeliveryOff by default; a notification or an agent wake, within daily caps
A watch reads the journal from where it last stopped; a firing is always recorded, and is delivered only if the watch asks for delivery.

What a watch is

A watch is a graph of nodes. Source nodes listen to the gateway's event journal: a document created or updated, a row landing in an analytics table, an open loop changing state, or a point in time. Other nodes combine what the sources emit: wait for something unless something else cancels it, require two things for the same key, count to a threshold, hold a cooldown. The last node feeds the sink, and each time the sink receives something the watch fires.

A firing is always recorded, with a trace of which node did what and why. Whether it goes anywhere is a separate, per-watch decision: a watch with no delivery is a row and a trace and nothing else. That default is deliberate. It lets you run a watch in the background for a week, see what it would have told you, and only then let it interrupt you.

A new watch starts at the head of the journal: “tell me when” is a question about what happens next, so a watch never fires on the history that existed before it. Records a source replays on its first sync are likewise ignored unless a node asks for them.

Creating a watch

There are four ways in, and they differ in who writes the definition and where it delivers:

Way Written by Delivers to Approval
Ask the built-in agent (portal or app chat) Compiled from your sentence A notification to your devices None; the agent relays how it read your request
An OpenClaw or Hermes agent Compiled from the agent's sentence Wakes that agent with its instruction Required; see below
omnesis watch add <file> You, in the Watch language Nowhere until you run omnesis watch deliver None
POST /admin/watch/compile Compiled from your sentence Nowhere, or an agent wake if you send an instruction None

Compiling a sentence is an agent run on the background-agent role, so it needs that role assigned even when Brain is not otherwise in use. The compiler reads your sources' declared fields and people and may search the corpus to resolve a name; it writes a definition, the validator checks it, and validation errors go back to the compiler to fix. The compiler chooses the stored Watch name. Tell Omnesis receipts use that saved name and the compiler’s interpretation, so a later request can identify the same Watch.

It then replays the candidate over the last 90 days of the journal and, if the watch would never have fired, would judge more than its budget allows or would speak far more often than the request implies, it gets one revision. A compile can take minutes; a single model call within it is abandoned after gateway.watch.compileTimeoutMs (three minutes). Some conditions cannot be watched, such as a verdict on how things are going overall with no event to hang it on; the compiler refuses those with a reason rather than producing a watch that never fires.

Every compile is recorded as a run of kind subscription_compile on Debug → Cognition → Agent runs, with the full transcript: what the compiler looked up, what it wrote and each repair turn. An installed watch links to it from its detail page. The transcript contains corpus text the compiler read.

An agent's request needs approval before it can wake anyone. Until then it is listed at the top of the portal's Watches page as a pending request, and the watch evaluates and wakes nobody. If your privacy policy is set up, its reviewer may approve or deny the request automatically; if the reviewer fails, the request stays pending for you. An operator's own compile or definition approves itself.

To preview a compile without installing anything, send "compileOnly": true; the answer carries the definition, the compiler's reading of it and the replay's numbers, and nothing is stored:

curl -s -X POST "$OMNESIS_GATEWAY_URL/admin/watch/compile" \
  -H "Authorization: Bearer $OMNESIS_TOKEN" -H "Content-Type: application/json" \
  -d '{"request": "Tell me when a supplier invoice arrives that is more than 30 days overdue", "compileOnly": true}'

The Watch language

A watch definition is a JSON document. The example below fires when someone emails you about a contract renewal and you have not replied in the same thread within five working days. Every value in it is fictional; it validates against a Gmail source.

renewal-notice-unanswered.json
{
  "watch": {
    "name": "renewal-notice-unanswered",
    "nl_query": "Tell me when someone emails me about a contract renewal and I have not replied within five working days.",
    "firing_policy": "stays_active",
    "ontology_fingerprint": "<fingerprint from GET /admin/watch/ontology>",
    "nodes": [
      {
        "id": "renewal_notice",
        "type": "source.document_event",
        "filter": {
          "source": "gmail",
          "event": ["created"],
          "documentType": "email",
          "people": [{ "role": "sender", "isSelf": false }]
        },
        "recall": {
          "semantic": {
            "query": "contract or subscription renewal notice",
            "threshold": 0.35
          }
        },
        "judge": {
          "proposition": "The title of this email refers to renewing a contract or plan",
          "output_schema": {}
        },
        "output_map": {
          "doc_id": "$e.docId",
          "thread_id": "$e.metadata.extra.threadId"
        }
      },
      {
        "id": "my_reply",
        "type": "source.document_event",
        "filter": {
          "source": "gmail",
          "event": ["created"],
          "documentType": "email",
          "people": [{ "role": "sender", "isSelf": true }]
        },
        "output_map": { "thread_id": "$e.metadata.extra.threadId" }
      },
      {
        "id": "unanswered",
        "type": "stateful.wait",
        "inputs": {
          "renewal_notice": { "role": "arm", "key": { "thread_id": ".thread_id" } },
          "my_reply": { "role": "cancel", "key": { "thread_id": ".thread_id" } }
        },
        "on_collision": "ignore",
        "duration": "5 business_days",
        "output_map": { "doc_id": "$n.renewal_notice.doc_id" }
      }
    ],
    "sink": {
      "input": "unanswered",
      "output_map": { "evidence": "$n.unanswered.doc_id" }
    }
  }
}

Read it from the top. renewal_notice is a document source: the filter cuts the stream to new inbound email at no cost (there is no direction field on a document, so “inbound” is a sender who is not you). The recall block nominates the emails whose text is close to the query; only those reach the judge, a single model call that must confirm the proposition before the node emits anything. The proposition is written against the email's title, because the title is the evidence the judge is guaranteed to see. my_reply has no recall and no judge: it exists only to cancel, and judging every message you send would cost a model call each. unanswered is a wait keyed on the thread, so an arm and a cancel meet only if they belong to the same conversation; five business days after the arm, with no cancel, it fires. on_collision: "ignore" means a second renewal email in the same thread does not restart the clock.

The ontology_fingerprint identifies the version of your install's sources, fields and tables the watch was checked against; a definition carrying a different one is refused, and the refusal names the current value. Watches written by the compiler get it filled in. The top-level fields are:

Field Meaning
name Lowercase kebab-case; how the CLI and the portal refer to it.
nl_query The request in plain words. Optional, but it is what a reader sees.
firing_policy stays_active, or once_ever to retire the watch after its first firing.
expires_at An ISO instant after which the question has ended; the watch retires on the clock even if nothing arrives.
constants Values read once from a document (a passport expiry date, a budget), each with the provenance_doc it came from. Referenced as $const.<name>.
nodes, sink The graph, and the node whose output is the firing.
delivery Where a firing goes. Not accepted by watch add; set it with omnesis watch deliver (Delivery).

The node types:

Type What it does
source.document_event A document created or updated. Filters on source, documentType, declared metadata fields and people by role. An optional recall block (semantic query and threshold, lexical terms matched against the title, or both) must be paired with a judge.
source.analytics_row A row in an analytics table, inserted (a key the journal has not seen before) or updated, with an optional SQL predicate. backfill is ignore by default; include also takes rows a source replayed on its first sync, for running totals.
source.open_loop A Brain open loop created, updated or resolved, optionally by id, state or person.
source.time one_off (an ISO instant) or recurring (five-field cron in the install's time zone). A boundary missed while the gateway was down fires once when it comes back.
stateless.or Fires when any input fires; $fired_by names which.
stateless.transform A DuckDB expression with no FROM that projects a fires column.
stateful.wait Fires when its duration elapses after an arm, unless a cancel arrives first.
stateful.and Fires when every input has fired for the same key within its deadline.
stateful.threshold Fires when n of its inputs have fired within the deadline.
stateful.sequence Fires when inputs arrive in the declared order within the deadline.
stateful.cooldown Passes a firing on at most once per min_interval.
stateful.persistence Fires when its input fires at least min_events times within duration.
sql A DuckDB query over the analytics tables that projects fires. It can re-run on a timer, require the condition to hold for a persistence period, or fire only on the rising_edge. Time comes from the $now and $today parameters, never from now().
llm A proposition judged over the evidence its inputs carry, on the watch-judge role, firing when its output satisfies fire_when.

Stateful nodes keep one instance per key, which each input extracts from what arrives (".thread_id" above); inputs into one node must produce the same key. A keyless input such as a clock tick feeding a keyed node declares "broadcast": true and reaches every live instance. What a second arm does to a live instance is on_collision: reset restarts it, ignore keeps the first, spawn starts another beside it (with max_live_instances, and never with a cancel input), and accumulate keeps a cell that survives firing so the node can fire again. Durations are written "<amount> <unit>" with units seconds, minutes, hours, days, weeks and business_days (Monday to Friday, no holidays); deadlines may also be "infinite", which draws a warning.

Expressions read $e.<path> from the arriving event (for example $e.people[role=sender].personId), $n.<node>.<field> from an upstream node, $judge.<field> from a judge's output, $key.<component> and $const.<name>. The only functions in a key are date_trunc and coalesce. The validator checks shape, graph, references, keys, collision rules, your install's sources and fields, SQL and semantic match, and reports each problem with a stable code and a JSON path.

Trying one before it runs

Because a watch starts at the head of the journal, a condition that can never match looks exactly like a quiet week. Two commands ask the past instead:

❯ omnesis watch try renewal-notice-unanswered.json --days 90

❯ omnesis watch probe renewal-notice-unanswered --days 180

watch try replays a definition file over recent journal events (500 by default, or --days up to 365) with the same engine the runtime uses, and reports, per node, how many events matched out of how many were evaluated, with the runtime's reason for a sample of its decisions. Nothing is stored. Its judge never says yes, so it reports what would have reached a model rather than what the model would have answered, and lexical terms are matched against titles only. It refuses when a semantic recall arm has no embedder to score it, when the journal is empty, and when the definition does not validate.

watch probe scores an installed watch's recall arm against past documents (90 days and 2,000 documents by default) and reports how many would have been nominated, with the best, 95th-percentile and median scores. When nothing would have been nominated it says by how much the best document missed the threshold. It returns counts and scores, never documents, and applies only the source and document-type filters, so its count is an upper bound.

How watches run

The gateway turns its own events into an ordered, durable journal: every two seconds while events arrive (every fifteen when idle), it writes up to 500 of them, deduplicated, with the fields watches filter on. Analytics rows enter through a transactional outbox, so a restart delays them instead of losing them. Every five seconds (every thirty when idle) each active watch reads up to 200 events from its own cursor. Timers are checked on the same tick, so a wait can fire up to the idle interval late. The journal, the definitions, per-key state and traces live in watch.db in the config directory, encrypted like the other stores and included in backups; a definition exists nowhere else.

The judge runs on the watch-judge role, which must be assigned explicitly: it does not inherit the Brain's model, and until it is assigned, events that need a judgement wait, with no model call and no spend. It can be Codex, Claude Code, a local GGUF model, an Anthropic model or an OpenAI-compatible backend that speaks Chat Completions. It sees the document's id and title, its kind, time and participant roles; a body excerpt is shown only in a second, veto-only check after the title-based decision says yes, so a body-reviewed nomination can cost two calls.

It fails closed: an error, an unparseable reply or a spent budget produces no decision and parks the nomination. A budget-parked nomination retries the next UTC day; a provider failure retries after a one-minute cooldown. Only calls actually sent count against the caps, which are kept on disk, so a restart does not reset the day.

❯ omnesis model assign watch-judge <backend>/<model>

A watch was checked against your sources' declared fields and tables when it was added. When those change (a source starts declaring a new field, a new analytics table gets its first row), every watch is checked again. A watch whose own inputs are byte-for-byte unchanged keeps running; one whose inputs moved is paused with a note, even if it still validates, because the same definition could now select different records. After reviewing, omnesis watch restamp re-validates every watch and resumes the ones that still hold. This happens when the new data arrives, which can be hours or days after an update.

A gateway that is stopping refuses new compiles with a 503 and gives running ones a short grace period. omnesis watch report --json shows compiles.running if you want to restart at a quiet moment.

Delivery

Delivery is off by default for a watch you add or compile yourself, and is set per watch. Turning it off again keeps the watch and its history:

❯ omnesis watch deliver renewal-notice-unanswered

❯ omnesis watch deliver renewal-notice-unanswered --to agent-wake --integration openclaw --instruction "Draft a polite reply asking for the renewal terms." --binding mailbox=drafts

❯ omnesis watch deliver renewal-notice-unanswered --to none

omnesis-notify (the default) has the built-in agent open a conversation about the firing, and sends a notification to your paired devices that quotes its opening message and opens that conversation when tapped. With no agent, or if the conversation cannot be opened, a plain notification composed from the request goes out instead. A watch with no push transport configured keeps firing and recording, and says so in the log and in omnesis watch firings.

agent-wake wakes a paired OpenClaw or Hermes agent. The watch decides when; your instruction (up to 8,000 characters) decides what, and is passed to the agent verbatim. Bindings (key=value, up to 32) name the things the instruction refers to, such as a channel or a mailbox; Omnesis never interprets them. What crosses to the agent is identifiers, the instruction, the bindings and two narrowly scoped credentials, never the firing's content.

When the agent asks what caused the firing, the gateway answers through a read-only turn that starts from what the firing recorded, and the reply passes your Answer privacy review like any other. The agent can then report what it did, for up to 24 hours; omnesis watch firings --all --since 24h shows firings with their outcomes. A watch naming an integration that no paired device holds keeps firing and logs that nobody was woken.

Delivery is capped per day. Over a cap, the firing is recorded as usual and marked suppressed, with the cap named in the trace; nothing is queued for later, because a late notification about a condition is a wrong one. The allowances are kept on disk.

Key (under gateway.watch) Default What it bounds
delivery.dailyCap 20 Notifications from all watches per day
delivery.perWatchDailyCap 5 Notifications from one watch per day
wake.dailyCap 25 Agent wakes from all watches per day
wake.perWatchDailyCap 10 Agent wakes from one watch per day
judge.dailyCap 200 Judge calls from all watches per UTC day (0, or at least 2)
judge.perWatchDailyCap 50 Judge calls from one watch per UTC day (0, or at least 2)

To prove a delivery path without waiting for the condition, omnesis watch fire <name> runs the delivery for a firing made by hand, optionally carrying --doc <documentId> or a JSON --payload. Nothing is evaluated and no judge is asked. The firing is marked by hand everywhere and never counted as a catch, the daily caps still apply, and when nothing arrives the result says why. It refuses a watch that delivers nowhere, and one that is paused or retired.

OpenClaw and Hermes

Experimental mode also covers the Watch half of the OpenClaw and Hermes integrations, which are otherwise generally available (see Agents & MCP → OpenClaw and Hermes). The gateway advertises it as capabilities.subscriptions on GET /health, and omnesis connect reads that to install to match: with the gate off, the agent gets the Answer tool and no Watch tools, its skill describes only what it can do, and the subscription routes themselves are not served. With it on, the agent gets a tool to create, list, inspect, update and revoke its own watches, each a sentence plus the instruction it wants to be woken with.

Turn the gate on and reconnect (or run omnesis connect <harness> --refresh) to add Watch management and Watch-reaction delivery to an installation that already exists. Each omnesis update refreshes the plugin the same way, so an installation gains or loses its Watch tools to match the gateway. An agent's watches are listed in the portal beside your own, and omnesis watches manages them from an integration's device token.

Observing and debugging

Command Answers
omnesis watch list Every watch, its status, how often it has fired, where it started.
omnesis watch show <id> [--diff <file>] The definition a watch is actually running, or its difference from a file.
omnesis watch firings <name> What it said, and what a woken agent did about it. --all --since 7d across watches.
omnesis watch trace <id> Why it fired, or why not: which node armed, on what key, what cancelled it.
omnesis watch judge <id> [--full] What the judge was asked, and what it answered.
omnesis watch report The whole install: running and stopped watches, judge calls against the caps, evaluation timings, parked nominations, delivery tallies and journal health.

Read a trace's transitions with their detail. ignored on a source with the reason naming the arms that declined means no model was asked; held … judge declined means a model was asked and said no; held … judge budget spent; parked means no model was asked and the nomination waits for budget. Traces keep the last 2,000 records per watch (traceRetained), while firings are kept for the life of the watch.

In the portal, Watches lists every watch with pending agent requests at the top; a watch's page shows its definition, its firings and the compile that produced it. Debug → Watch runtime draws one watch as a graph, shows what each stateful node is holding per key and every armed timer, and lights up the path an event took, including the times the watch looked and did not fire. It is read-only; actions stay in the CLI. The iOS and Android apps show watches read-only when experimental mode is on.

omnesis watch report puts every stopped watch in one bucket: drifted (your sources changed under it: rewrite it, or restamp after review), failed (a node threw), held (someone paused it) or retired (it finished, by its horizon or a once_ever firing). A failed watch names the failure class: query (its own SQL), provider (the judge or recall backend), budget (one event needed more off-host rounds than allowed) or internal (a defect). The failing event is retried on every pass, so the watch stays stopped until you act; the message itself is in the trace, not in the status note, because it can quote corpus content.

Pausing, resuming and removing

❯ omnesis watch pause renewal-notice-unanswered

❯ omnesis watch resume renewal-notice-unanswered

❯ omnesis watch resume renewal-notice-unanswered --skip

❯ omnesis watch rm renewal-notice-unanswered

resume re-validates first and refuses, with the validator's diagnostics, a watch that would be paused again on its next pass. --skip moves a failed watch past the one event or parked nomination it could not get through and records the skip in the trace; everything else is untouched. rm (or Remove watch on its portal page) deletes the definition, its state, its traces and its firings, so a new watch with the same name starts fresh. For a watch that woke an agent, the record of what was sent to that agent is kept, marked revoked, because the Answer audit log points at it.

An agent's watch has a second record, the approved request behind it. Revoking it from the portal stops it waking the agent; when the agent itself revokes it, the watch is removed too. omnesis watches purge <id> (or --all-revoked) then deletes a revoked or expired request with its revisions, firings and answers for good.

Configuration reference

Runtime keys sit under gateway.watch; the caps are in Delivery.

Key Default Meaning
drainIntervalMs / idleIntervalMs 2000 / 15000 How often the journal is written while events arrive, and when idle.
batchSize 500 Journal events written per pass (at most queueCapacity).
queueCapacity 50000 Document events that may wait in memory (at least 1000).
evaluateIntervalMs / idleEvaluateIntervalMs 5000 / 30000 How often watches are evaluated; the idle value is also how late a timer can fire.
eventsPerWatch 200 Journal events one watch reads per evaluation.
traceRetained 2000 Trace records kept per watch.
compileTimeoutMs 180000 How long one model call may take while compiling.
compileReasoningTokens unset Bound on a compile turn's reasoning tokens, for reasoning models that run out of time deciding. Not honoured by every backend; the log says when it was not.
promptPeople 200 People named in the compiler's prompt, most-contacted first; everyone stays addressable by id.