Saltar al contenido principal
Un Project es donde ocurre el trabajo en un workspace de Driftless. Es un entorno de ejecución compartido para humanos y sus agentes: el project contiene cards (la unidad de trabajo), y el mismo board se opera desde la CLI, la REST API y el dashboard. El producto vive en la superficie headless; el board es visibilidad ocasional para el humano. Esta es la mitad de Driftless que no es documentación. Los Topics capturan lo que el equipo sabe; los projects capturan lo que el equipo está haciendo. Como ambos viven en el mismo workspace, un agente que toma una card tira del Knowledge anclado al código que está por tocar, y los gotchas que aprende regresan al vault.

Projects y cards

  • Un project pertenece a un workspace y tiene un status: active, done o archived. Puede llevar un goal (la definición de terminado para todo el project) y un playbook_slug (un topic de Knowledge que el agente lee para aprender a ejecutarlo), que se setea con --playbook en la CLI o playbook_slug en la REST API. El tool MCP driftless_project todavía no expone playbook_slug; cuando un project tiene uno, el bundle de next de la card lleva un playbook_hint.
  • Una card pertenece a un project y se mueve por un carril de status: todo · in_progress · blocked · review · done. Una card puede llevar:
    • un owner (un member del workspace),
    • un criterio de acceptance: qué significa “done”, verificado antes de cerrar la card,
    • un comando validate: un comando de shell que debe salir con cero,
    • depends_on: otras cards que deben estar en done antes de que esta sea accionable.

El loop del agente

Un project es un board que el agente recorre en un loop, repitiendo cuatro pasos hasta que el project esté done:
1

Pide la próxima card

project card next <project-id> devuelve la próxima card accionable más su context bundle en una sola llamada: { card, context_bundle, project_done }. El bundle une los context refs de la propia card con los del project, sin duplicados: la memoria registrada del equipo para el área de esa card, para que el agente no vuelva a derivar lo que el equipo ya sabe.
2

Trabaja la card

El agente trabaja con el bundle cargado. Esto es lo que lo distingue de una cola de tareas común: la card llega anclada al Knowledge que la rodea, no como un título pelado.
3

Valida contra acceptance

Si la card tiene un comando validate, el agente lo corre. Una salida distinta de cero es stop-and-fix: no marques la card como done, repara y vuelve a validar. acceptance es la definición de terminado legible contra la que el agente verifica.
4

Devuelve lo aprendido y cierra

Persiste todo lo durable que aprendiste, marca la card como done y pide la próxima card. Repite hasta que project_done sea true.
El dep-gating ordena el loop sin microgestión: una card en todo con dependencias sin cumplir nunca aparece en next. Pasa a estar “ready” solo cuando cada card de su lista depends_on está en done. Entre las cards accionables, next elige en orden de prioridad: in_progress primero, luego review, luego blocked, y por último un todo ready. Listar cards con project cards usa un orden distinto, orientado al board (blocked, review, in_progress, todo, done). Cuando ninguna card está lista y ninguna está en vuelo, project_done es true. Blocked, no adivinado: si el agente no puede avanzar sin una decisión humana, pone la card en blocked en vez de marcarla como done.
La verificación es reportar y exponer, no imponer. El agente reporta el resultado de correr validate; Driftless lo guarda y lo expone, pero nunca corre el comando por sí mismo. Una transición a done sin un resultado que pase se permite por defecto (la card se expone como “needs verification”), salvo que el workspace opte por bloquear con require_card_validation, un setting a nivel de workspace (apagado por defecto) que un owner o admin setea con PATCH /workspaces/:slug y { settings: { require_card_validation: true } }. No es un flag por card ni por project.

Devolver lo aprendido a mitad del loop

Un gotcha que descubres mientras trabajas una card no debería esperar al final. Adjúntalo a la card como una nota:
driftless note add \
  --content "Las entregas de webhook llegan desordenadas, se requiere idempotency key" \
  --project prj_abc --card card_xyz
Esa nota viaja en el context bundle de next de la card (el próximo tick del loop la ve), y cuando el project cierra, el compact sintetiza las notas adjuntas de la card en un Topic borrador, enviado al Inbox para que un owner o admin lo integre en Knowledge (ellos mismos, o mediante un agente al que le piden). Los límites del trabajo son donde debería adjuntarse la memoria: next es el momento de inyectar contexto, el cierre de la card es el momento de capturarlo.
--card requiere --project (una card vive dentro de un project). Por MCP, driftless_note_add toma los mismos project_id y card_id.

Desde la CLI

Los projects y las cards son ciudadanos de primera clase en la CLI; un agente corre los mismos comandos que correría un humano.
ComandoDescripción
project add <title>Crea un project
project list [--status active|done|archived]Lista projects
project get <id>Detalle del project + índice de cards
project update <id> [--status …] [--title "…"]Actualiza un project
project cards <project-id> [--status s] [--limit n]Lista cards (orden por prioridad)
project card next <project-id>Próxima card accionable + context bundle (el tick del loop)
project card add <project-id> --title "…" [--description "…"|@file] [--acceptance "…"] [--validate "cmd"] [--dep <card-id>] [--owner <id>]Crea una card
project card add <project-id> --file @cards.jsonCrea cards en lote (depends_on por título o id)
project card update <project-id> <card-id> […]Actualiza una card
project card get <project-id> <card-id>Detalle de la card
project card status <project-id> <card-id> <status>Cambia el status de una card
project card move <project-id> <card-id> <to-project-id>Mueve una card a otro project
project card rm <project-id> <card-id>Elimina una card
# Levanta un project con una card validada y con acceptance
driftless project add "Renovación de refunds"
driftless project card add prj_abc \
  --title "Handler de webhook idempotente" \
  --acceptance "Las entregas duplicadas de webhook son un no-op" \
  --validate "npm test -- webhooks" \
  --owner mem_123

# Luego recórrelo
driftless project card next prj_abc          # card + su context bundle
driftless project card status prj_abc card_xyz done
Las cards se escanean en busca de secrets al escribir, igual que los topics; pasa --allow-secrets solo cuando de verdad quieras guardar uno. Agrega --json a cualquier comando para salida de máquina.

Desde la REST API

Todo lo de arriba mapea a REST bajo el workspace:
MétodoRuta
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
Un PATCH de card acepta add_context para adjuntar una nota o topic a la card a mitad del loop, reflejando el propio add_context del project.

En el dashboard

El board dibuja los mismos projects y cards como un kanban: las columnas son los status de las cards, y arrastrar una card llama al mismo PATCH que la CLI. El encabezado del project expone su goal y su playbook; las cards muestran badges de verified y ready y su acceptance / validate en el detalle. Marcar un project como done abre el compact, donde eliges las cards cuyos aprendizajes se vuelven Topics borrador en tu Inbox; el resto se retira con el project. Es una superficie de visibilidad, no una fuente de verdad aparte: una card creada por un agente desde la CLI aparece de inmediato.
Los projects y las cards viven en el workspace y son visibles para sus members. Se gobiernan por roles del workspace, no por el ciclo de vida Nota → Knowledge; ese ciclo es para topics. Los topics borrador del compact, sin embargo, sí entran a ese ciclo. Ver Gobernanza.