Crux
GuidesRetrieval & Knowledge

Views

Create typed, live, and pinned read surfaces from knowledge-base metadata.

Views turn indexed metadata into a named read surface. Use them when a subset is part of the product model: published docs, one tenant, one application, one jurisdiction, or one product line.

Use request-time retrieval filters for one-off narrowing. Use views when membership should affect retrieval, tools, relations, assertions, communities, global search, and receipts.

Add A Metadata Schema

Views require an object metadataSchema. The schema also validates indexed metadata and types retriever filters.

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

const metadataSchema = z.object({
  status: z.enum(["draft", "published", "archived"]),
  application: z.enum(["auto", "home", "life"]),
  jurisdiction: z.string(),
  priority: z.enum(["normal", "high"]),
});

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

await docs.index([
  {
    namespace: "docs",
    sourceId: "auto-ca.md",
    content: "California auto policies require proof of coverage.",
    metadata: {
      status: "published",
      application: "auto",
      jurisdiction: "CA",
      priority: "high",
    },
  },
]);

Invalid metadata is rejected at ingestion. Optional schema fields may be absent.

Create A Typed Where Clause

view({ id, where }) accepts exact scalar matches. Arrays mean an IN match.

const autoPublished = docs.view({
  id: "auto-published",
  where: {
    status: "published",
    application: "auto",
    jurisdiction: ["CA", "NY"],
  },
});

Use any for a union of compound clauses:

const urgent = docs.view({
  id: "urgent",
  where: {
    any: [
      { status: "published", priority: "high" },
      { status: "published", jurisdiction: "CA" },
    ],
  },
});

Only scalar schema fields can appear in where: strings, numbers, booleans, enums, and scalar literals.

Use The View Like A Knowledge Base

Views expose the read surfaces you use on a knowledge base:

import { expandRelations, retrieve } from "@use-crux/core/retrieval";

const hits = await autoPublished
  .retriever({ limit: 8 })
  .retrieve("proof of coverage");

const recipe = autoPublished.recipe({
  id: "auto-published-answer",
  steps: [
    retrieve({ limit: 8 }),
    expandRelations({ types: ["references"], direction: "out" }),
  ],
});

const tools = autoPublished.tools({
  prefix: "auto",
  include: ["search", "getSource"],
});

const grounded = autoPublished.grounding({
  query: ({ input }) => input.question as string,
});

Membership is authoritative. Crux may push exact filters to vector storage, but returned hits are still checked against the resolved view members.

Live Revisions And Pinning

A live view resolves to the current member set each time it is used. resolve() returns a content-addressed revision hash and the source ids in that revision.

const revision = await autoPublished.resolve();

console.log(revision.revisionHash);
console.log(revision.members);

Use at(revisionHash) when a workflow must replay the same source set:

const pinned = autoPublished.at(revision.revisionHash);
const replayHits = await pinned.retriever().retrieve("proof of coverage");

Pinned handles check that every member source is still exactly available. If a member changed or disappeared, replay fails instead of silently using a different source set.

Relation And Assertion Visibility

View recipes hydrate only member hits. A graph traversal can pass through a non-member ref, but a non-member chunk is not returned as a hit.

View-bound assertion sets hide assertions with no visible supports:

const limits = autoPublished.assertions(policyFacts, {
  types: ["requirement"],
});

const page = await limits.list({ limit: 25 });

Namespace Scoping

Views are isolated by the structural namespace:

const tenantDocs = docs.scope({ namespace: "tenant-a" });

const tenantView = tenantDocs.view({
  id: "auto-published",
  where: { status: "published", application: "auto" },
});

The same view id in another namespace has separate membership, revisions, communities, graph traversal, and hydrated hits.

Branch Ceiling

The portable view retriever expands any clauses and IN values into exact vector filter branches. The built-in ceiling is 16 branches. Narrow a wide predicate, split the view, or use storage with view-aware pushdown when a view would expand beyond that ceiling.

On this page