Skip to content

Glossary

Shared vocabulary for Rose. Terms here mean the same thing across code, schema, backoffice, and docs. Extend it as concepts stabilise rather than redefining them per page.

Workspaces, sites, knowledge, and routing

See the Client-Scoped Sites ADR for the physical model and its original terminology.

A workspace is the client-facing container that owns configuration, knowledge, agents, and website roots. It is the identity the backoffice selects. The physical schema introduced this container as a row in public.sites; database, migration, and routing code may therefore still use site for that row. Frontend selection code and client-facing copy use workspace. In ordinary product copy, site means the client's website, not the selectable container.

Ownership is a composition tree (filled diamond = "owns"); attributes such as enabled or corpus_status are fields on a box, not boxes of their own. Multiplicities read how many of the target a source has.

classDiagram direction LR class Client { +bool explicit_routing_enabled } class Workspace { +uuid site_id +string config_key +enum status +enum corpus_status } class Config { +json client_base +json site_overrides } class Corpus { +string storage_key +tenant vectors_and_graph +set documents +set faqs } class Root { +string host +string path_prefix +bool is_canonical +bool enabled } class Agent { +string kind } Client "1" *-- "0..*" Workspace : owns Workspace "1" *-- "1" Config : configured by Workspace "1" *-- "1" Corpus : owns Workspace "1" *-- "0..*" Root : placed at Workspace "1" o-- "0..*" Agent : hosts Agent "0..*" --> "1" Corpus : reads note for Root "Exactly one root has is_canonical=true when a workspace has roots.\nenabled means this root routes live visitor traffic;\nallowed only when status=live and corpus_status=ready\n(and, for a path_prefix root, explicit_routing_enabled=true).\nCrawl seeds are derived from the roots — the canonical root\nsets the default scope, enabled aliases widen it — and build the Corpus."
  • Workspace — the client-scoped identity: one configuration, one corpus, one or more roots, and its agents. Everything else is scoped by it. It replaces the domain that used to be configuration target, bot identity, and tenant key all at once. A client may have several workspaces (e.g. one per market locale).
  • Site (public.sites) — the physical storage and routing name for a workspace. Keep this term in SQL, migrations, generated types, APIs that expose site_id, and the staff route editor. Do not use it as the frontend selector abstraction or as the client-facing name of a workspace.
  • Root (root URL) — a placement: an exact hostname plus an optional, normalized path prefix (e.g. example.com/fr/) that resolves to one workspace. A workspace with roots has exactly one canonical root — its user-visible label and the default ingest scope — plus any number of alias roots that resolve to the same workspace and widen what gets crawled. A workspace may also be rootless.
  • config_key — a workspace's stable configuration handle: unique, assigned once, and never derived from a root, so a root can move without re-keying configuration, knowledge, or history. For a workspace at a bare host it equals the registered domain; a path-rooted workspace gets an opaque slug.
  • Corpus — a workspace's knowledge boundary: its documents, FAQs, vectors, and graph. Each workspace owns exactly one. A turn retrieves from the corpus of its resolved workspace and nothing else, so a sibling market's knowledge is never named.
  • Storage key (corpus address) — the opaque key that addresses a corpus in the storage layer (LightRAG working set, Mongo tenant_id, Neo4j tenantId). Retrieval resolves an ordered list of storage keys with exactly one entry.
  • Tenant — the isolation scope in the storage layer, keyed by the storage key. "One corpus per workspace" is "one tenant per workspace."
  • corpus_status — the lifecycle of a workspace's corpus: absent → indexing → ready | failed. A root can be enabled only once its corpus is ready; if a corpus leaves ready, its roots are disabled in the same transaction.
  • Legacy workspace — an existing client migrated to a single public.sites row that owns its existing corpus, backfilled at corpus_status='ready'. Its storage key is its domain and its existing tenant data is reused, never relabelled or re-indexed.
  • Crawl seeds — the start URLs a crawl reads, derived from a workspace's roots: the canonical root sets the default scope and enabled aliases widen it.
  • Agent — a surface that works in a workspace (Website Agent, Content Agent, …). Agents live in a workspace and read its corpus; they are not an internal LangGraph node or a response-agent prompt, and they own nothing.
  • Market locale vs response language — the market locale (e.g. fr-FR) selects regional behaviour and facts; the response language may still follow the visitor or channel and can differ from it.

Knowledge ingestion control plane

See the control-plane overview for the full model; the ADR records the decision and its rationale. The control plane turns a knowledge command into durable, observable background work: Supabase owns workflow state, and the execution systems (Cloud Tasks, the content worker, the document-loader job) only deliver work.

An operation owns its work items, and each work item records its physical attempts. This is the identity trail behind progress, retry, cancellation, and recovery.

classDiagram direction LR class Operation { +uuid operation_id +enum operation_type +enum source_scope +enum status +string idempotency_key } class WorkItem { +enum stage +enum loader_mode +enum status +int max_attempts } class Attempt { +int attempt_number +int dispatch_generation +hash lease_token_digest +enum outcome } class CorpusFreshness { +int shared_revision +int loaded_revision_per_env } Operation "1" *-- "1..*" WorkItem : owns WorkItem "1" *-- "1..*" Attempt : records Operation "0..*" ..> "1" CorpusFreshness : loader coordinates on note for Attempt "Only the claimant holding an unexpired lease can advance state (fenced).\nAn attempt outcome (e.g. duplicate_noop) never becomes the work-item outcome.\ndispatch_generation namespaces GCS artifacts and dispatch identifiers."
  • Control plane vs data plane — the control plane is the orchestration layer that decides and tracks ingestion work and owns its state (the Knowledge API and Supabase). The data plane is what executes the work (the content worker and document-loader job). Execution systems deliver work; they do not own its state.
  • Knowledge API — the private knowledge-api-{environment} service that owns commands, transactional state transitions, dispatch, recovery, document-loader admission, and the sanitized operation status returned to the backoffice. It is the workflow owner; it never calls back into the admin API.
  • Content worker — the private knowledge-content-worker-{environment} service that executes bounded stages (map, triage, discovery finalization, sample, section decision, scrape, clean). It writes artifacts to GCS and reports results; it does not own workflow state or write to RAG.
  • Operation (knowledge.ingestion_operations) — one user or system command (e.g. full refresh, website policy change, retrain). It carries the operation_id that follows the whole flow, its type and scope, aggregate progress, and absolute idempotency identity.
  • Work item (knowledge.ingestion_work_items) — one logical bounded unit of an operation, such as a map, a per-page scrape or clean, or one document-loader run. Its identity survives transient retries.
  • Attempt (knowledge.ingestion_work_item_attempts) — one physical dispatch and execution of a work item. Multiple attempts can back one work item without changing its single logical outcome.
  • Fenced attempt / lease token — a claimed attempt holds a cryptographically unguessable lease. Only the current claimant, presenting the token while its digest matches the unexpired fence, can post progress or terminal state. A stale or duplicate execution cannot advance an item a newer generation already claimed.
  • Dispatch generation — a monotonic counter per work item. It namespaces Cloud Task/Cloud Run dispatch identifiers and GCS artifact paths (generation-<n>/), so a later legitimate attempt is isolated from an earlier one without risking accidental duplicate delivery within a generation.
  • Attempt outcome vs work-item outcome — an attempt outcome describes one physical run; duplicate_noop means that run did no work. It never completes the logical work item or the operation.
  • Guarded snapshot publication — content completion atomically validates the expected current snapshot and policy version before publishing new canonical snapshot metadata, so stale work cannot publish over newer operator intent.
  • Create-only artifacts — worker GCS writes use create-only preconditions. A retry may re-write identical bytes but can never overwrite a different existing body; failed cleaning leaves raw evidence in GCS without publishing a canonical snapshot.
  • Corpus freshness (knowledge.ingestion_corpus_freshness) — a job-level ledger holding one monotonic shared revision per (site, source_scope) and the last revision each environment successfully loaded. Only a completed fenced loader attempt advances an environment's loaded revision; a lagging environment must run the loader even when content hashes are unchanged. It proves an environment still owes a loader run — not that any specific snapshot reached LightRAG.
  • Recovery scheduler — a Cloud Scheduler tick (every minute) that re-dispatches due pending work, resolves ambiguous dispatch, recovers expired leases, and is the automatic producer for dirty source scopes. Retries use bounded max_attempts and exponential backoff, so a deterministic failure cannot become a retry storm.
  • Reviewed re-scan / review — a source-bound website_rescan operation maps the site and publishes an immutable review (added, returning, unchanged, missing URLs against the scanned generation) instead of mutating the catalogue. Applying the review is a second atomic command; dismissal changes nothing. "Missing" means absent from the latest complete map, not a proven HTTP 404.