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;
}| Option | Type | Default | Constraints |
|---|---|---|---|
model | KnowledgeModel | Required | Must have non-empty name and fingerprint, plus generateText and generateObject. |
id | string | "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
| Condition | Error |
|---|---|
| Missing or invalid model object | Error("Communities require a knowledge model.") |
| Empty model name | Error("Communities model name must be non-empty.") |
| Empty model fingerprint | Error("Communities model fingerprint must be non-empty.") |
| Missing model methods | Error("Communities model must provide retrieval methods.") |
Empty id | Error("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:
| Status | Meaning |
|---|---|
"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?)
| Option | Type | Default | Constraints |
|---|---|---|---|
force | boolean | false | When 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;
}| Option | Type | Default | Constraints |
|---|---|---|---|
level | number | undefined | Reads the generation level index when supplied. |
parentId | string | undefined | Reads children of a parent community when supplied. Takes precedence over level. |
cursor | string | undefined | For parentId, the cursor is the previous communityId. Otherwise passed to record-store listing. |
limit | number | All in-memory children for parentId; store default otherwise | For 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:
| Field | Constraint |
|---|---|
title | String, maximum 120 characters |
summary | String, maximum 2000 characters |
finding.statement | String, maximum 500 characters |
finding.evidence | Non-empty array of valid KnowledgeRef values |
level | Non-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;
}Related
- Reference: Connected Knowledge recipe steps
- Reference: Connected Knowledge model and refs
- Guide: Retrieval & RAG