Crux
API Reference@use-crux/core

Connected Knowledge Communities

communities(), KnowledgeCommunitiesSurface, community reports, lifecycle, and report records.

import { communities } from "@use-crux/core/knowledge";
import type {
  CommunitiesConfig,
  CommunitiesFactoryConfig,
  CommunityBuildDescriptor,
  CommunityReadinessStatus,
  CommunityRefreshHost,
  CommunityReport,
  CommunityReportCounts,
  CommunityReportFinding,
  CommunityReportLineage,
  CommunityReportsOptions,
  CommunityReportsPage,
  KnowledgeCommunitiesSurface,
} from "@use-crux/core/knowledge";

Overview

Community configuration enables persisted community reports for a knowledge base or view. The public lifecycle surface reports readiness, prepares missing or stale materializations, and reads paginated reports.

communities(config)

Creates a frozen community strategy config for knowledgeBase({ communities }).

function communities(config: CommunitiesFactoryConfig): CommunitiesConfig;

Parameters

interface CommunitiesFactoryConfig {
  readonly model: KnowledgeModel;
  readonly id?: string;
}
OptionTypeDefaultConstraints
modelKnowledgeModelRequiredMust have non-empty name and fingerprint, plus generateText and generateObject.
idstring"communities"Must be non-empty after trimming.

Returns

interface CommunitiesConfig {
  readonly id: string;
  readonly model: KnowledgeModel;
  readonly strategyFingerprint: string;
}

strategyFingerprint covers community strategy version 1, model name, model fingerprint, leaf input budget 24000, parent input budget 96000, and parent budget multiple 4.

Failures

ConditionError
Missing or invalid model objectError("Communities require a knowledge model.")
Empty model nameError("Communities model name must be non-empty.")
Empty model fingerprintError("Communities model fingerprint must be non-empty.")
Missing model methodsError("Communities model must provide retrieval methods.")
Empty idError("Communities id must be non-empty.")

Example

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

const reportModel = knowledgeModel({
  name: "community-reporter",
  version: "1",
  generateText,
  generateObject,
});

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

KnowledgeCommunitiesSurface

type CommunityReadinessStatus =
  | "missing"
  | "building"
  | "ready"
  | "stale";

interface KnowledgeCommunitiesSurface {
  status(): Promise<CommunityReadinessStatus>;
  prepare(options?: { readonly force?: boolean }): Promise<void>;
  reports(options?: CommunityReportsOptions): Promise<CommunityReportsPage>;
}

The surface is available as knowledgeBase().communities and KnowledgeView.communities only when communities are configured.

status()

Returns:

StatusMeaning
"missing"No current community generation pointer exists.
"building"An equivalent build is in process, or a non-stale lease blocks the probe lease.
"ready"Current pointer matches view revision, graph generation, strategy fingerprint, and has no dirty sources.
"stale"Lease is stale, pointer metadata changed, or dirty sources exist.

After index(), reindex(), or remove() marks communities dirty, Crux schedules a retained refresh when the mutation runs inside a defer-capable execution boundary. While that retained refresh is pending in the same process, status() returns "building".

If no defer-capable boundary is active, scheduling is skipped and the stale state remains visible. Indexed retrieval remains correct; community reports refresh when a caller awaits prepare() or reports().

status() throws Error("knowledgeBase().communities requires record storage.") without record storage.

prepare(options?)

OptionTypeDefaultConstraints
forcebooleanfalseWhen false, a "ready" status short-circuits.

Without a refresh host, prepare() builds communities in process. With a refresh host, it calls refreshHost.ensure(descriptor).

The built-in retained refresh host joins a scheduled background refresh when one exists. Otherwise, prepare() performs the in-process refresh, preserving the existing readiness contract.

interface CommunityBuildDescriptor {
  readonly indexerId: string;
  readonly namespace: string;
  readonly scopeKey: string;
  readonly viewId?: string;
}

interface CommunityRefreshHost {
  ensure(descriptor: CommunityBuildDescriptor, options?: { readonly force?: boolean }): Promise<void>;
  hasPending?(descriptor: CommunityBuildDescriptor): boolean;
}

ensure() is the required member: run a build for the descriptor to completion, or satisfy the call by joining an equivalent build already in flight.

hasPending() is optional. A host that can report whether a refresh is scheduled or running lets status() return "building" while that refresh is in flight. A host that omits it reports "stale" until the refresh publishes; readiness and joining are unaffected either way.

reports(options?)

interface CommunityReportsOptions {
  readonly level?: number;
  readonly parentId?: string;
  readonly cursor?: string;
  readonly limit?: number;
}

interface CommunityReportsPage {
  readonly reports: readonly CommunityReport[];
  readonly cursor?: string;
}
OptionTypeDefaultConstraints
levelnumberundefinedReads the generation level index when supplied.
parentIdstringundefinedReads children of a parent community when supplied. Takes precedence over level.
cursorstringundefinedFor parentId, the cursor is the previous communityId. Otherwise passed to record-store listing.
limitnumberAll in-memory children for parentId; store default otherwiseFor parentId, used as slice length without clamping.

reports() calls prepare() first. It throws the same record-storage error as status() and prepare().

Example

await docs.communities?.prepare();

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

for (const report of page?.reports ?? []) {
  console.log(report.title, report.counts.chunks);
}

Community Reports

interface CommunityReport {
  readonly communityId: string;
  readonly generationId: string;
  readonly level: number;
  readonly parentCommunityId?: string;
  readonly title: string;
  readonly summary: string;
  readonly findings: readonly CommunityReportFinding[];
  readonly lineage: CommunityReportLineage;
  readonly counts: CommunityReportCounts;
}

interface CommunityReportFinding {
  readonly id: string;
  readonly statement: string;
  readonly evidence: readonly KnowledgeRef[];
  readonly assertionRefs?: readonly { readonly assertionId: string }[];
}

Validation bounds for persisted reports:

FieldConstraint
titleString, maximum 120 characters
summaryString, maximum 2000 characters
finding.statementString, maximum 500 characters
finding.evidenceNon-empty array of valid KnowledgeRef values
levelNon-negative integer
interface CommunityReportLineage {
  readonly viewRevision: string | null;
  readonly graphGeneration: string;
  readonly strategyFingerprint: string;
  readonly memberHash: string;
}

interface CommunityReportCounts {
  readonly entities: number;
  readonly chunks: number;
  readonly assertions: number;
}

On this page