Nexara Connect docs0.1.0

Concepts

The words in the app are Space, Folder and Page. The code and the API say space, cluster and node. They are the same things.

Workspaces, Spaces, Folders and Pages

---
id: 01J9X...
title: DLP overview
type: project          # note|project|person|company|decision|log|index|skill|thread|capture
sensitivity: internal  # public | internal | confidential | secret (default internal)
tags: [client, dlp]
summary: One line used by bundles and index.md
status: active         # free text; "closed" makes it an archive candidate
pinned: false          # pinned pages are never auto-archived
---
# DLP

Text anyone with internal access can read. See [[Pricing]].

[[Wiki links]] and relative .md links become graph edges, which context_related and bundles follow.

Sensitivity

Four levels, lowest to highest: public < internal < confidential < secret. A level applies to a whole Page through frontmatter, or to a block inside it:

<!-- confidential -->
Contract value and terms.
<!-- /confidential -->

<!-- secret -->
Stored sealed in git; readable only by an owner after step-up.
<!-- /secret -->

Principals: humans and agents

A principal is anyone who acts: a human member or an agent. Every read and write is attributed to one.

Grants

A grant is {space, cluster_glob, actions[], max_sensitivity}, shown in the app as space/glob : actions : level.

ActionLets the agent
readGet pages, bundles, tree, related
searchSearch
proposeQueue changes for review, append to logs
writeCommit directly, archive and restore
collabPost on threads and mention others
watchReserved for subscriptions (planned)
adminCreate Spaces, delete pages, push over git (owners grant it)
assign, captureReserved for tasks and quick capture (planned)

The default grant for a new agent is * / ** : read, search, propose, collab, watch : internal. Standing agent grants stop at confidential whatever you ask for; secret is only reachable through a time-boxed elevation approved by an owner with step-up. Viewers can only grant read, search, propose, collab, watch, and nobody can grant above their own ceiling.

Proposals

Agents propose, humans decide. A proposal is a full new version of a Page plus a reason, waiting for an editor or owner on the Proposals screen (word diff, accept, edit and accept, reject).

Proposals are created when:

Writes and conflicts

Every write goes through a single writer queue per workspace. Send the hash you read as If-Match (REST) or base_sha (MCP). If someone changed the Page since, a clean three-way merge lands (merged: true); a real conflict returns 409 with a proposal_id. Nothing is silently overwritten when a base is given. The web editor always sends it.

Threads and the inbox

Any Page can carry a thread. Messages are stored in core.db and also appended to <page>.threads.md beside the Page, so the discussion is in git. Mentions (@name or a principal id) reach only principals who can read the Page, and land in their inbox together with replies, proposals and conflicts.

Agent traffic is guarded: 20 messages per minute and 300 per day per principal, at most 5 mentions per message, no @all or @here except from owners, duplicate bodies within 10 minutes are refused. After 4 agent-to-agent hops the thread is flagged for a human, and 20 agent messages in 10 minutes lock it until an editor unlocks it.

Bundles

context_bundle(intent) is the tool agents should call first. It runs hybrid keyword and semantic search, filters by your grants before ranking, adds the relevant Folder index.md, deduplicates, packs the best sections into a token budget (default 4000) and cites the source path and commit for every section. Each section is fenced with a per-response nonce so stored text cannot pose as instructions. Only Pages actually emitted in a bundle count as reads.

Lifecycle and archive

Every Page has last_touched_at, the later of its last read and last edit. A nightly job at 03:00 UTC finds archive candidates:

  1. untouched for longer than the Folder's auto_archive_days (120 by default);
  2. status: closed in frontmatter;
  3. superseded_by set.

Closing a whole Folder is a separate, manual action (see below).

Pinned pages and type: index or type: skill are exempt. With LIFECYCLE_MODE=dry (the default) the job only lists candidates on the Archive screen. With apply it archives them.

Archiving sets state: archived in frontmatter and commits; files never move. Archived Pages drop out of bundles, search and tree unless include_archived is set, while context_get by id still works. Archive a whole Folder to close a matter; restore brings it back.

Audit

Every read, write, denial, token and grant change is recorded in an append-only, hash-chained audit log (ids only, never content). Owners see it on the Audit screen, and npm run verify-audit checks the chain.

Generated from concepts.md by docs/site/build.mjs. Edit the Markdown, then rebuild.