Skip to content

EverRoom

A local-first Electron workspace where files, meetings, repositories and connected accounts are filed into a Context Room: every ingested source keeps an identity, a version and a provenance record, wiki pages and memory are derived from that ledger under a policy snapshot that is itself recorded, and an agent works only inside the Room it was handed.

Screenshot of EverRoom
Editor screenshot, 1 Oct 2026EverRoom ↗

What it is

EverRoom is a local-first desktop workspace built on one sentence: context should be assembled from evidence, scoped to a place of work, and visible enough for a person to govern. Files, repositories, meeting recordings, a browser extension and connected accounts all arrive through one intake path, and every source keeps an identity, a hash, a version and a provenance record while a policy snapshot decides whether it becomes a wiki page, an entity candidate, a memory document or only a link. The unit of work is the Context Room — a project, topic, person or responsibility — and an agent session receives that Room’s tools and documents rather than a global corpus. Documents are versioned, and an agent edit is committed through an operation kernel before any knowledge or memory fan-out runs, so a failing external service cannot corrupt it. Underneath sit SQLite with Drizzle and FTS5, content-addressed objects, a Fastify 5 gateway supervised by Electron, a MemoryCore service forked from TencentDB-Agent-Memory, and thirteen file-driven subagents.

Who built itA company account rather than a person: the repository is NxcoreAI/EverRoom, its metadata carries no owner profile, and its 735 commits are credited to seven listed contributors — the accounts 21335464876 (173), SkylistqAq (159), lzp-plus (128) and Ewan-yuan (112) write most of the history, with Rlacat on 72, ultralan on 9 and xgx1124982311-sys on 2, while eighty commits are linked to no account at all. The commit emails point at a team rather than a stranger: five addresses on vyitec.com, one of them xieguoxin@vyitec.com with 25 commits, and twenty-four commits from nexcore@nexcoredeMacBook-Pro.local. Eighty-eight commits carry a co-author trailer and every one of those names a Claude model. The connector callback domain named in one pull request is connect.everroom.vyitec.com, and the homepage is r.nxcore.ai.

How it is put together

The parts · 6

Four layers with a rule about which of them may change: the desktop owns the lifecycle and the trust boundary, the gateway owns durable orchestration, the engines under it — the Pi agent runtime, the memory core, the knowledge service, the connector bridge — are meant to be replaceable, and the data stays in SQLite and content-addressed objects on the device. The consequence that shapes almost everything else is that a source is normalised once and then referenced rather than copied: an original file and its parsed Markdown have a single storage owner, and everything downstream keeps a hash and a provenance record instead of a second copy. That is why ingest is one of the largest modules and why the policy snapshot exists at all — it is the record of which downstream systems were allowed to see the material. Three more consequences follow. Documents are committed through an operation kernel and an outbox before any knowledge or memory fan-out runs, so an external failure cannot corrupt the authoritative version. Agents are scoped: a session resolves its Room first, and the subagent directory is file-driven with immutable revisions, so a definition that changes cannot alter a run already in flight. And every optional engine has a degraded state written for it, because the desktop has to remain usable when the memory service, the knowledge service or a model credential is missing.

apps/gateway/
Four hundred and forty-six files and about ten megabytes: thirty modules under src/modules/, led by a knowledge service of 148 KB, create-server.ts at 85 KB, a files service at 46 KB, a documents service at 46 KB, ingest at 57 KB, memory at 58 KB, writing style at 61 KB and a subagent tool surface of 47 KB, with the smaller modules for perception, reality, ASR, connectors, local agents, scheduler, notifications and runtime configuration. Under drizzle/ sit sixty-three SQL migrations and their snapshots — with duplicate numbers and gaps in the sequence — and the tests are as heavy as the code, agent-room-selection.test.ts alone being 41 KB.
apps/desktop/
Six hundred and ninety-three files: an Electron main process whose largest pieces are a 72 KB local data service, a 64 KB saas-client.ts, a 50 KB preload index, a 26 KB private transcription sync and a 7 KB updater, over a renderer with a 56 KB Reality page, a 55 KB settings page, a 40 KB sources page and a hundred-odd agent and context-room components, including an entire context-room/ported/ component set that carries its own editor, panels and hooks.
agents/
Thirteen file-driven subagents, each an agent.yaml with a system prompt and optional skills and JSON schemas: main, context-room, doc-writer, knowledge, room-corrector, multimodal-document-parser, connector-mapper, transcription-summary, content-analyst, cursor-completion, diary, ingest-filter and web-search. Every SKILL.md needs name and description frontmatter, an agent can read only its own skill snapshot through a restricted tool, and the gateway turns a changed definition into an immutable revision.
packages/ and submodules/
Six workspace packages and one submodule: an agent contract of 46 KB, a Pi runtime of 47 KB whose runtime test is 41 KB and which holds the memory and knowledge tool clients, a document model, a reality contract, a fake and an unconfigured runtime adapter, and the connector submodule — a gateway module of some thirty files with per-provider sync code for Feishu, Feishu wiki, Gmail, Notion, Google Docs, Google Calendar, Outlook and webcal subscriptions.
docs/
Thirty-five files and 656 KB of planning documents, most of them in Chinese: a 42 KB Room wiki plan, a 40 KB unified ingest plan, a 43 KB doc-writer subagent plan, a 38 KB connector refactor plan, a 37 KB writing-style plan, a 36 KB office integration plan and a 29 KB subagent framework design, beside an English perception-to-wiki ingest design and a 62 KB HTML prototype for the sources page.
Tooling and delivery
.github/ holds eight workflows totalling 62 KB, dominated by a 29 KB desktop release pipeline and an 11 KB scheduled one, with a Codex review workflow, a Feishu card action and issue and pull-request notification hooks. Four patches sit in patches/ for electron osx-sign, the memory core, the MCP adapter and sqlite-vec; the packaging scripts prepare five bundled runtimes, including a Rust spreadsheet sidecar, and a 7 KB verifier checks the Windows package before it is published.

Choices, and what they beat

  • Scope context to a Room instead of passing one global corpus over letting an agent read everything the workspace has ingested

    The README states it as the product thesis — knowledge tools resolve the current Room or session before reading a wiki page, a source or a material, and agents "do not receive a global unbounded corpus by default" — and the same document lists a bounded context window, rather than a prompt dump, as the thing a Room protects.

  • Normalise a source once and reference it from there over giving the wiki, the memory layer and the document index their own copies

    Written as "one asset, many references": originals and their parsed Markdown have a single storage owner, and downstream services keep stable references, hashes and provenance rather than copying the same source into several databases. The ingest design applies the same rule to recordings, where the idempotency key is the source identifier plus a content hash.

  • Commit the document before any side effect over pushing a document version to knowledge and memory as part of the same write

    Stated as an ordering rule: document edits go through a transactional commit core and an outbox, and the fan-out to knowledge and memory happens only once the authoritative version is committed, so an external service failure cannot corrupt the document. The same module keeps an operation state machine, so an edit is something that can be inspected rather than a side effect.

  • Make confirmation mandatory on the agent’s delete tool over trusting the model to delete only when it was asked to

    Pull request 257 adds context_room_document_delete and refuses every call whose confirm argument is not exactly true, returning a retryable error whose next action is to ask the user; the prompt guidelines restrict the tool to explicit requests and forbid habitual or batch deletion, and the deletion is a recoverable trash move that deliberately does not emit the permanent-deletion event, because the renderer would otherwise clear the trash list too.

  • A nightly release by machine and a stable release by hand over promoting a stable version whenever a feature commit appears

    Pull request 261 deletes the scheduled promotion, records that 0.1.9 had reached stable through it by accident, and stamps the channel into the package from the tag so that a nightly build cannot offer itself a stable update. The three version bumps and the rollback in pull requests 249, 250 and 253 are the same decision being paid for.

  • Ship a degraded state for every optional engine over treating the memory, knowledge and connector services as required

    The README makes it a written rule — the fake agent runtime, a disabled memory core, unavailable connectors and model failures each have an explicit fallback state — on the argument that a missing optional service must not make local documents inaccessible, and the fault-injection work in pull request 263 tests the visible half of the same idea with an inline error bar and a retry.

Read fromdocs/reality-wiki-ingest-design.md — the one architecture document the report prints in full, 1,786 characters — the README (23,065 characters, of which the report prints the first 6,000 and the remainder was fetched from raw.githubusercontent.com on 2026-10-01), the README’s own repository layout and technology tables, the thirty issue and pull-request bodies with their comment threads, and the complete 1,386-file tree with sizes together with the two-level directory summary.

Build log

6 stages
  1. 01

    Seven weeks, 735 commits, and bug reports that arrive from a group chat

    The repository was created on 2026-08-14, two days after its oldest commit — "feat: scaffold NexCore CE desktop app", dated 2026-08-12T03:49:30Z — and 735 commits later it stood at 3,069 stars, 322 forks and 219 watchers. The shape is a company sprint rather than a solo run: 561 commits in what was left of August and 174 in September, the newest of them the merge of pull request 239 on 2026-09-20, ten days before the last push recorded on 2026-09-30. Commits with a linked account number 655 of the 735, and the four busiest accounts write 572 of them between themselves. Eighty-eight commits carry a co-author trailer, and all eighty-eight name a Claude model: thirty-one say only "Claude", twenty Fable 5, twelve Opus 5, eleven Opus 4.8, seven Opus 4.8 with a million-token context, five "Claude Code" and two Opus 4.6. The community arrives through a chat client rather than the issue tracker: three of the thirty issues and pull requests were filed by github-actions[bot] carrying a <!-- feishu-request:... --> marker, the repository keeps four notification workflows and a reusable feishu-card action, and one issue consists of nothing but a URL to the repository itself.

  2. 02

    Nightly as the pipeline, stable by hand, and a version number rolled back

    Twenty releases are listed, the oldest of them a nightly published on 2026-09-08 and the newest desktop-v0.1.9-nightly.20261001.81 on 2026-09-30, and eighteen of the twenty are nightlies named desktop-v<version>-nightly.<date>.<serial>, the two exceptions being desktop-v0.1.7 and desktop-v0.1.8. Pull request 261 is the document that fixes the policy and argues it: the automatic stable promotion was deleted — about forty lines that scanned for feat commits and raised a build to the stable channel, which is how 0.1.9 was pushed to stable by accident — the channel is now stamped into the package from the tag through NXCORE_UPDATE_CHANNEL, the nightly channel switches on allowDowngrade because X.Y.Z to X.Y.Z-nightly.N is a downgrade under semver, and stable keeps downgrades blocked because a real one has to be. The same pull request warns that a paired change on the SaaS side must merge in the same batch, or nightly devices will find an empty channel in the window between them. The version line records what the mistake cost: 0.1.8 was bumped to 0.2.0 as the first baseline for the hot-update work and then to 0.2.1 as its update target, and pull request 253 rolled both back to 0.1.9, calling them mistaken jumps and asking to merge before midnight so the scheduled job would not cut a nightly from the wrong series.

  3. 03

    Provenance is a ledger entry, not a summary

    The ingest design states the mechanism in one line: identical content is recognised by sourceId + contentHash, hits the ingest ledger, and returns immediately without being parsed or fanned out a second time. A recorded policy snapshot decides which downstream systems the material may reach — in the worked example the policy is meeting-minutes and by default it opens all three of Room, Wiki and Memory — while the converted Markdown goes into parsed_contents and ingest_events keeps the source version, the content fingerprint, the policy snapshot and the route job. The rules around it are about keeping unfinished things out: a transcription that is still pending_confirmation is not written to the wiki at all, a confirmed recording is delivered asynchronously so the confirmation call is not held open, a metadata update that does not change the wiki body triggers nothing, and a failed automatic delivery is logged without rolling back the fact that the user confirmed the capture. Manual re-delivery has its own endpoint, POST /v1/reality/events/:id/knowledge-ingest, and it accepts completed events only. The boundary is drawn in the same document: the perception module decides when to deliver and holds the source identifier, it never references the knowledge service, and an adapter injected at bootstrap keeps the three modules from forming a dependency cycle.

  4. 04

    What this does differently from three memory projects already in this archive

    This archive already holds three memory layers for agents, and the difference is where the memory comes from. OKF Agent Memory keeps a bundle of Markdown in the repository and searches it with an in-process BM25 index so the memory shows up in git diff; agent-memory makes one file one memory, gives it a validity interval instead of a status field, and lets a sleep-time layer add and update on its own clock; Memmy runs one local service that ten hosts read and write. EverRoom is none of those shapes: it is an application with its own ingress, and memory here is a derivation rather than the artifact, because a source is normalised once and only then does a recorded policy decide whether anything becomes knowledge or memory. The store is SQLite from sixty-three migration files, not Markdown in a repository, and the reasoner is the project’s own Pi runtime rather than the host tool already open. The comparison it makes for itself is against a chat client and a thin retrieval screen, not a memory library, and its README lists what is still missing: conflict display, provenance navigation, manual attach and revert, source-level diagnostics and citation-aware agent workflows are roadmap items, not shipped behaviour. The memory pipeline is borrowed too: MemoryCore is packaged from a fork of TencentDB-Agent-Memory, and one of the four patches in the tree patches it.

  5. 05

    The pull request is the explanation

    The writing here happens in pull-request bodies, and several are worth more than the change they carry. Number 273 is a nightly that died on both platforms because a dependency fetched https://oomol.com/en/apps/catalog.json during the build and that URL had begun returning 404 after the site was rebuilt; the author compares the lockfile SHA against the last successful build to show the dependency was not the variable, notes the upstream project has had no commit since 2026-08-03, and lands a try-catch through the existing patch chain. Number 271 is one line excluding lib/commands/test.js from the bundled npm runtime, after a release audit rejected the package for a forbidden file. Number 268 is two test assertions changed because a new agent tool altered the expected tool list, noting that the branch was already red. Number 262 is the sharpest: a summary that had been filled with the transcript itself, fixed with a detector that strips timestamps and speaker labels and then looks for eight non-overlapping 64-character probes in the original, calling it an echo once half of them hit. Two pull requests chase the same intermittent 500 from opposite ends — 263 makes the gateway return a named 503 with a retry instead of a generic internal error, and 267 adds a silent retry inside the desktop bridge, one second and then three, for the read-only requests that open a Room.

  6. 06

    What the authors decided not to build

    The README names the boundaries before it names the features: no continuous screen recording, no autonomous multi-agent swarm, no enterprise administration and no mandatory cloud synchronisation in the first release, on the argument that the first version is for trustworthy local context. The same restraint shows in the release engineering. macOS is the stated development target and the Windows installer is unsigned, so the README warns about SmartScreen. The updater work in September found that a packaged app had no app-update.yml at all — the file electron-updater reads before it can download anything, missing because the build had no publish configuration — and that a manual check announced a new version whenever versionInfo was present, which it always is, so the test became isUpdateAvailable. A 490 MB update that took more than twenty minutes with no percentage on screen produced a progress broadcast and multi-range downloads, under the argument that the differential download is what keeps the package size survivable. The cost of standing on other people’s code is written into the tree as four patches — electron osx-sign, the memory core, the MCP adapter and sqlite-vec — and into the morning a nightly that built its GitHub release was never distributed or registered, because a CDN had dropped the exact version of the download tool the workflow pinned.

Adjacent records

All records →