Collections are a separate primitive from Projects. A Project is an execution loop where an agent walks a board; a Collection is operational data a human runs, augmented by AI. They coexist, and neither is built on the other.
The three archetypes
Every use case collapses into one of three shapes:- Pipeline: records flow through a
statuslifecycle on a board: leads, bugs, support tickets, ad campaigns. - Analysis: a record is an artifact anchored to a source that can drift (the source changed) versus decay (no activity): call analysis, competitor tracking, SEO audits.
- Content: a record with a publication lifecycle (draft → published): blog posts, product copy. The published artifact lives in your site/CMS; the collection tracks the work.
What a Collection holds
record_schema: the typed field definitions (the columns). Field types:text,long_text,number,currency,date,datetime,select,multi_select,status,relation,user,url,email,phone,file,anchor_ref,ai_field. Astatusfield carriesstages[], the lifecycle a record flows through.views: saved views over the records:board,table,list,calendar,gallery, each withgroup_by,filter,sort, andvisible_fields.criterion_rel_slugs: the Knowledge Topics the work reads before acting. This is the seam coming down: a lead pipeline readshow-we-sellandicp, so the work happens with the team’s criteria.distill_policy: a configuration field for how a terminal record should distill back into a Note (the seam going up): closing a bug or winning a deal can leave a durable learning in the vault.
A Record
A Record is one row: itsfields are the typed values (keyed by the Collection’s field keys), and its status is validated against the Collection’s own stages. Each Collection defines its own lifecycle, so a record can only sit in a stage its Collection declares.
Entities
A Record is a row inside one Collection. An Entity is an identity that can span Collections: the same customer who appears as a lead in the sales pipeline and a ticket in support. An entity is not a row in a Collection; it is a separate object that Records point at. An entity carries:kind: the identity type (for examplecompany,person).name: its display name.dedup_key: the stable key that makes it unique within itskind.attributes: free-form typed values.
(kind, dedup_key): writing the same pair twice updates the entity instead of creating a duplicate. A Record links to an entity by setting its entity_id, so several Records across different Collections can resolve to one identity.
Entities are available on three surfaces: the CLI (driftless collection entity add|list), MCP (driftless_entity, action: list | get | upsert), and REST (/workspaces/:slug/entities).
Connector
import (via the Broker) maps a provider’s mirrored records into Collection Records. That is different from Broker index, which materializes connector documents for retrieve, not Collection Records. See Broker: reads and materialization.Using collections
From the CLI (the surface also exists in MCP asdriftless_collection and driftless_collection_record):
Retrieve before you act: the seam in one call
Before working a record, an agent reads the collection’s criterion Knowledge: thecriterion_rel_slugs resolved into the actual topics (how-we-sell, icp),
so the work happens with the team’s criteria, not from scratch.
The retrieve action delivers both halves of the seam at once: the relevant
records and the criterion to read first:
criterion is the team’s Knowledge to apply; criterion_missing flags any
criterion slug that doesn’t resolve (a gap to close). Records paginate by keyset
(nextCursor). Read the criterion, then act on a record with
driftless_collection_record action:'update'. For just the criterion (no records),
use driftless_collection action:'context'.
This mirrors topic retrieve: one call returns what to read and
what to work on, instead of hand-chaining a list and a separate criterion lookup.