collection command family drives the operational substrate: a collection is a configured table, a record is a typed row, and an entity is a cross-collection identity. Add --json to any command for machine output.
Reads are active-only, bounded and brief by default. collection list returns active collections in a bounded, cursor-paged response; --status all opts in to archived. Intent search is collection search <intent>, active-only unless --include-archived. collection get is brief unless you pass --view full. Lifecycle is explicit: archive, restore and purge are separate commands — collection update rejects a --status that touches lifecycle.
Collections
Configuration flags on
add and update: --schema (the record_schema), --views, --distill (the distill_policy config), and --criterion a,b (the criterion_rel_slugs). Each of --schema, --views, --distill accepts inline JSON or @file.
Records
A record’s
--status is validated against the collection’s own stages: a record can only sit in a stage its collection declares. --entity <id> links the record to an entity — it’s a top-level record property, never a field inside --fields. Moving a record to a terminal stage triggers the distill_policy, returning a context_outcome (created · already_exists · skipped · failed) — best-effort, never blocks the write.
Entities
Entities are managed undercollection entity. There is no top-level entity command in the CLI; the MCP tool driftless_entity and the REST /entities routes cover the same object.
--kind and --name are required on add. Entities upsert idempotently on (kind, dedup_key), so re-adding the same pair updates rather than duplicates.
Lifecycle: archive and purge
collection archive, collection restore and collection purge are the only ways to retire a collection:
purge preserves the distilled Notes the collection spawned (they survive the delete); they’re counted in impact.distilled_notes_preserved. A repeat purge after the collection is gone returns already_absent, never errors. The safe record delete follows the same shape — collection record rm --dry-run previews the Entity link removed and the distilled Notes preserved (the delete is workspace-membership gated, not owner/admin).
Retrieve and criterion
collection retrieve <id> returns relevant records and the collection’s criterion Knowledge together, so an agent reads the team’s “how we do this” before acting. Filters: --query, --status, --view, --entity, --updated-after, --drift/--no-drift, --fields, --limit, --cursor. For just the criterion (no records), use collection context <id>.
Flags, files, and JSON
@fileis accepted by--schema,--views,--distill,--fields, and--attrs.--jsonworks on every command.--cursorpages a bounded list/retrieve; the value is opaque, from the prior page’snextCursor.distill_policyset with--distillis a configuration field; it declares how a terminal record should distill back into a Note, returning an observablecontext_outcome.
Permissions
Collection, record, and entity writes are workspace-member actions; purge is owner/admin only. Over MCP they require thework:write scope. collection doctor, reads and record rm are member-level.
Related
- Collections - the concept, archetypes, and field types.
- Integrations and Connections - where imported records come from.
- MCP: Work - the MCP parity surface (
driftless_collection,driftless_collection_record,*_purge,*_delete,driftless_entity). - API: Collections, Records, and Entities - the REST surface.
- Guide: Operate a Collection with governed context - the workflow end to end.
