Crux
GuidesRetrieval & Knowledge

Communities

Build and read report hierarchies over a knowledge base or view.

Communities materialize a topic map over the visible connected graph. Use them when users ask broad questions such as "what risks affect this application" or "which themes recur across these policies".

Do not use communities for one direct evidence lookup. Use a retriever or a recipe with expandRelations() first.

Configure Communities

communities({ model }) requires a named KnowledgeModel. Reports are generated from visible chunks and graph input, then stored under a community generation.

import {
  communities,
  knowledgeBase,
  knowledgeModel,
} from "@use-crux/core/knowledge";
import { z } from "zod";

const metadataSchema = z.object({
  status: z.enum(["draft", "published"]),
});

const reporter = knowledgeModel({
  name: "policy-community-reporter",
  version: "2026-07",
  generateText: retrievalModel.generateText,
  generateObject: retrievalModel.generateObject,
});

const docs = knowledgeBase({
  id: "docs",
  storage,
  embeddings: dense,
  metadataSchema,
  communities: communities({ model: reporter }),
});

If you have already configured an entity relation stage with mentions and related relations, communities use that graph. Otherwise, configuring communities adds a generic entity mapping pass through the same derive pipeline.

Readiness Lifecycle

The communities surface exists only when configured:

await docs.communities?.status();
await docs.communities?.prepare();

const page = await docs.communities?.reports({ level: 0, limit: 20 });

status() returns:

StatusMeaning
missingNo community generation exists for the current scope.
buildingThis process or another process holds the build lease.
readyThe current reports match the visible graph, view revision, and strategy fingerprint.
staleA current generation exists, but it no longer matches the live inputs.

Without a runtime host, stale is a supported state. Crux does not start detached background work. Call prepare() to refresh in-process, or reports() to prepare before reading.

Use prepare({ force: true }) to rebuild even when the current generation is ready.

Background Refresh

After index(), reindex(), or remove() changes connected knowledge inputs, Crux marks the affected community scope dirty. When the call runs inside a defer-capable Crux execution boundary, Crux also schedules the community refresh as retained background work. The mutation can return before reports finish building, and status() reports building while the retained refresh is scheduled or running.

Without a defer-capable boundary, scheduling is skipped. The mutation still succeeds, retrieval over indexed sources stays correct, and communities remain stale until a caller awaits prepare() or reports(). This stale state is supported: Crux does not start detached serverless work that the host cannot retain.

Views

Views expose the same community surface, scoped to a resolved view revision.

const published = docs.view({
  id: "published",
  where: { status: "published" },
});

await published.communities?.prepare();

const rootReports = await published.communities?.reports({
  level: 1,
  limit: 10,
});

A pinned view has its own community scope:

const revision = await published.resolve();
const pinned = published.at(revision.revisionHash);

await pinned.communities?.prepare();

If the pinned source set is no longer exactly replayable, the pinned community read fails instead of reading a different source set.

Report Structure

Each report includes:

FieldMeaning
communityIdStable id derived from the sorted member identities.
generationIdCommunity generation that owns the report.
levelHierarchy level. Leaves are level 0; parent levels are higher.
parentCommunityIdParent report id when present.
title and summaryBounded report text generated from visible evidence or child findings.
findingsBounded statements with evidence refs and optional assertion refs.
lineageView revision, graph generation, strategy fingerprint, and member hash.
countsCounts for entities, chunks, and assertions represented by the report.

Reports are not indexed source documents. They do not enter vector retrieval, view membership, or later community construction.

Cost Model

Community clustering is deterministic. Model calls happen for:

  • generic entity mapping when no authored entity mapping stage exists
  • report generation for communities whose member hash changed
  • one repair retry when a report does not validate

Unchanged communities reuse prior report content when the communityId, memberHash, and strategy fingerprint match. A failed refresh is atomic: the prior published generation remains current.

What Builds

Community input is assembled from the visible namespace or view:

  • visible chunks
  • entity mentions and entity-to-entity relations
  • evidence-backed graph edges with visible supports
  • fallback leaves for chunks without entity evidence

Every visible chunk belongs to exactly one leaf community. Large inputs are split deterministically to stay within internal report input budgets. A chunk larger than the leaf budget fails the build because it cannot be split safely at the community layer.

On this page