Get started

QuoxDream

A scheduled pass that turns raw Qortex notes into confidence-scored, deduped memory, the difference between a chunk-search index and a second brain that actually learns.

Maturity: Beta. Statements on this page were checked against QuoxCORE code on 2026-10-30.

Qortex stores raw notes: conversations, transcripts, git history, connector documents, chunked and searchable. That is retrieval, not judgement. QuoxDream is the server-side pass that reads those notes and asks a narrower question of each one: what is actually worth remembering long-term, as a standalone, confidence-scored belief in QuoxMemory?

It was written to close a gap in the second-brain design: without a consolidation pass, the store is a chunk search index with a good name. QuoxDream is what turns that chunk index into consolidation.

What it does

On each scheduled run, QuoxDream:

  1. Reads Qortex notes written since the last run for a given tenant slice, in strict order. Infrastructure failures hold the cursor and are retried; a note whose extraction is malformed or times out is retried (up to 3 attempts), then retired loudly and recorded, not silently skipped.
  2. Sends each note's text to a strict fact-extraction prompt (via the collector's /chat/complete seam), asking for a JSON array of durable beliefs: facts, preferences, decisions, entities, constraints, or observations, each with a confidence score and an importance tag.
  3. For every extracted claim, checks QuoxMemory for a near-duplicate before writing. A duplicate from the same source is skipped (noop); a duplicate from a new source corroborates the existing belief (the source is appended and confidence rises by 0.02); a genuinely new claim is written with its confidence, a stability tier, provenance marked model_inference, and a source pointer back to the originating note. Claims that do not carry a verbatim quote from the note are dropped.
  4. Advances a durable cursor so a service restart never reprocesses old notes.

Extraction is best-effort throughout: a malformed completion, a timed-out request, or a bad note is logged and retried or retired as described above, rather than aborting the run or crashing the service.

The cursor and batch model

Two tables carry the state (migration 005-dream.sql, additive-only):

  • dream_cursor (one row per (org_id, scope, owner_user_id) tenant slice): holds an ingestion-sequence position (with last_occurred_at and last_note_id kept for reference). Notes are read in ingestion order after the cursor, so edited notes and back-dated imports are not skipped, and pagination stays deterministic even when two notes share a timestamp.
  • dream_runs (one row per consolidation run): records notes read, beliefs written, beliefs deduped, and any error, for observability, readable through GET /brain/dream/status (coverage counts, cursor, last run and recent run count).

A single pass works through bounded batches (consolidateSlice), advancing the cursor after each batch rather than only at the end, so a crash mid-run loses at most one batch of progress, not the whole run. consolidateOrg runs this for an organisation's own notes and for private (per-user) slices, into their owner's beliefs (capped at 200 users). Shared-scope consolidation is opt-in and the scheduler never requests it.

Dedup: Jaccard first, semantic second

The default dedup check is word-overlap (Jaccard similarity) between a new claim and the top search results for its content, the same technique the collector's memory-consolidation scheduler already uses, so "near-duplicate" means the same thing across both consolidation paths.

An optional second pass, gated by QUOXDREAM_SEMANTIC_DEDUP, embeds the claim and compares it by cosine similarity against the same candidate set, widened to the 25 most recent beliefs of the same type. It respects the embedding-exclusion setting and fails closed. This only ever adds a second chance to catch a paraphrase Jaccard missed (for example "the org migrated its datastore to Postgres" versus "the team decided to use Postgres"); it never overrides a Jaccard match, and any embedder failure falls back cleanly to the Jaccard-only result. With the flag off, behaviour is byte-identical to the Jaccard-only path.

Env flags

QuoxDream ships dark. The environment variables below are defaults: a per-organisation stored setting overrides them in either direction, and most of these knobs are also available as stored settings. By default nothing runs until both of the first two are set:

FlagPurposeDefault
QUOXDREAM_ENABLEDDefault switch. Scheduler does nothing unless exactly 'true' or the organisation enables it in settings.false
QUOXDREAM_ORGSComma-separated org IDs to consolidate. Empty means no orgs run even if enabled.empty
QUOXDREAM_WARMUP_MSDelay before the first tick after boot, so the service finishes health-checking first.5 minutes
QUOXDREAM_INTERVAL_MSInterval between ticks.6 hours
QUOXDREAM_BATCH_SIZENotes read per batch within a run.40
QUOXDREAM_MAX_BATCHESBatches per run per tenant slice.5
QUOXDREAM_SEMANTIC_DEDUPTurns on the cosine-similarity second pass described above.off
QUOXDREAM_SEMANTIC_DEDUP_THRESHOLDCosine similarity floor for a semantic match.0.90
QUOXDREAM_EXTRACT_TIMEOUT_MSPer-note extraction timeout, so one slow note cannot wedge a whole pass.90 seconds

Settings: whether Dream may send note text to the chat model (QUOXDREAM_ALLOW_LLM_TEXT) is a per-organisation platform setting (settable, audited, re-read every scheduler tick, fails closed), and the Qortex privacy panel shows it. Run history is available from GET /brain/dream/status; a dashboard timeline of runs is not built yet. Enrolling an organisation still uses QUOXDREAM_ORGS.

Maturity

CapabilityStatusNotes
dream_cursor / dream_runs schemaStableAdditive migration.
extractBeliefs (LLM extraction)BetaUnit-tested with a mocked collector; best-effort by design.
writeBelief (Jaccard dedup + write)BetaUnit-tested with a mocked memory service.
Semantic dedup (QUOXDREAM_SEMANTIC_DEDUP)BetaStill additive on top of Jaccard, not a replacement.
Scheduler (startDreamScheduler)BetaDark by default.
Dashboard visibilityPartialWhether Dream may send note text to the chat model is a per-organisation setting shown in the Qortex privacy panel. A dashboard timeline of runs is not built; run history is via GET /brain/dream/status.
Per-user-scoped consolidationBuiltPrivate (per-user) slices consolidate into their owner's beliefs, with their own cursor row per slice.
Supersede-on-updateBuiltA contradicting claim (polarity reversal per clause, or a changed number, date or named value) marks the older belief superseded_by; a correction that adds an exception or condition also replaces the older belief, and a belief the user has reinstated is respected; private notes consolidate into their owner's beliefs.
  • Memory System: the QuoxMemory store QuoxDream writes beliefs into.
  • Qortex: the second-brain plugin QuoxDream consolidates notes from.
  • Schedulers: the other server-side background passes QuoxDream's scheduler shape is mirrored from. </content>

Last verified 2026-10-30 against QuoxCORE origin/main.