Projects and cards
- A project belongs to one workspace and has a status:
active,done, orarchived. It can carry a goal (the definition of done for the whole project) and aplaybook_slug(a Knowledge topic the agent reads to learn how to run it), set with--playbookon the CLI orplaybook_slugon the REST API. The MCPdriftless_projecttool does not exposeplaybook_slugyet; when a project has one, the cardnextbundle carries aplaybook_hint. - A card belongs to one project and moves through a status lane:
todo·in_progress·blocked·review·done. A card can carry:- an owner (a workspace member),
- an
acceptancecriterion: what “done” means, checked before the card is closed, - a
validatecommand: a shell command that must exit zero, depends_on: other cards that must bedonebefore this one becomes actionable.
The agent loop
A project is a board an agent walks in a loop, repeating four steps until the project is done:Ask for the next card
project card next <project-id> returns the next actionable card plus its context bundle in one call: { card, context_bundle, project_done }. The bundle merges the card’s own context refs with the project’s, deduplicated: the team’s recorded memory for that card’s area, so the agent doesn’t re-derive what the team already knows.Work the card
The agent works with the bundle loaded. This is what sets it apart from an ordinary task queue: the card arrives anchored to the Knowledge around it, not as a bare title.
Validate against acceptance
If the card has a
validate command, the agent runs it. A non-zero exit is stop-and-fix: do not mark the card done, repair and re-validate. acceptance is the human-readable definition of done the agent checks against.todo card with unmet dependencies never appears in next. It becomes “ready” only once every card in its depends_on list is done. Among actionable cards, next picks in priority order: in_progress first, then review, then blocked, then a ready todo. Listing cards with project cards uses a different, board-oriented order (blocked, review, in_progress, todo, done). When no cards are ready and none are in flight, project_done is true.
Blocked, not guessed: if the agent cannot proceed without a human decision, it sets the card to blocked rather than marking it done.
Verification is report-and-surface, not enforcement. The agent reports the result of running
validate; Driftless stores and surfaces it, but never runs the command itself. A done transition without a passing result is allowed by default (the card is surfaced as “needs verification”), unless the workspace opts in to blocking via require_card_validation, a workspace-level setting (default off) an owner or admin sets with PATCH /workspaces/:slug and { settings: { require_card_validation: true } }. It is not a per-card or per-project flag.Write-back mid-loop
A gotcha discovered while working a card shouldn’t wait for the end. Attach it to the card as a note:next context bundle (the next loop tick sees it), and when the project closes, the compact synthesizes the card’s attached notes into a draft Topic, sent to the Inbox for an owner or admin to merge into Knowledge (themselves, or via an agent they ask). Work boundaries are where memory should attach: next is the moment to inject context, card-close is the moment to capture it.
--card requires --project (a card lives inside a project). Over MCP, driftless_note_add takes the same project_id and card_id.From the CLI
Projects and cards are first-class CLI citizens; an agent runs the same commands a human would.| Command | Description |
|---|---|
project add <title> | Create a project |
project list [--status active|done|archived] | List projects |
project get <id> | Project detail + card index |
project update <id> [--status …] [--title "…"] | Update a project |
project cards <project-id> [--status s] [--limit n] | List cards (priority order) |
project card next <project-id> | Next actionable card + context bundle (the loop tick) |
project card add <project-id> --title "…" [--description "…"|@file] [--acceptance "…"] [--validate "cmd"] [--dep <card-id>] [--owner <id>] | Create a card |
project card add <project-id> --file @cards.json | Batch-create cards (depends_on by title or id) |
project card update <project-id> <card-id> […] | Update a card |
project card get <project-id> <card-id> | Card detail |
project card status <project-id> <card-id> <status> | Change a card’s status |
project card move <project-id> <card-id> <to-project-id> | Move a card to another project |
project card rm <project-id> <card-id> | Delete a card |
--allow-secrets only when you intend to store one. Add --json to any command for machine output.
From the REST API
Everything above maps to REST under the workspace:| Method | Path |
|---|---|
POST / GET | /workspaces/:slug/projects |
GET / PATCH | /workspaces/:slug/projects/:id |
POST / GET | /workspaces/:slug/projects/:projectId/cards |
GET | /workspaces/:slug/projects/:projectId/cards/next |
GET / PATCH / DELETE | /workspaces/:slug/projects/:projectId/cards/:cardId |
PATCH accepts add_context to attach a note or topic to the card mid-loop, mirroring the project’s own add_context.
On the dashboard
The board renders the same projects and cards as a kanban: columns are the card statuses, and dragging a card calls the samePATCH the CLI does. The project header surfaces its goal and playbook; cards show verified and ready badges and their acceptance / validate in detail. Marking a project done opens the compact, where you pick the cards whose learnings become Topic drafts in your Inbox; the rest retire with the project. It’s a visibility surface, not a separate source of truth: a card created by an agent from the CLI shows up immediately.
Projects and cards live in the workspace and are visible to its members. They’re governed by workspace roles, not by the Note → Knowledge lifecycle; that lifecycle is for topics. The compact’s draft topics, however, do enter that lifecycle. See Governance.
