Skip to main content
Version: 0.5

Core Concepts

Gest manages three primary entity types -- tasks, artifacts, and iterations -- and connects them through links, tags, and metadata. Entity data lives in a local SQLite database (via libsql); for local-mode projects a sync layer mirrors every change to a .gest/ directory as YAML and Markdown files so you can commit the data alongside your code.

Tasks

A task represents a unit of work. Tasks are rows in the tasks table with the following columns (and their YAML mirror in .gest/task/<id>.yaml when local sync is enabled):

FieldDescription
titleShort summary of the work
descriptionLonger explanation (Markdown)
statusCurrent state of the task
priorityUrgency level, 0 (highest) through 4 (lowest)
phaseNumeric execution phase for parallel grouping
assigned_toActor responsible for the task
tagsFreeform labels for filtering and grouping
metadataArbitrary key-value pairs (JSON object)
linksRelationships to other tasks or artifacts

Task Statuses

StatusMeaning
openNot yet started (default)
in-progressActively being worked on
doneCompleted successfully
cancelledAbandoned or no longer needed

done and cancelled are terminal statuses. Resolved tasks are excluded from listings and searches by default; pass --all to include them.

Priority

Priority is a number from 0 to 4, where 0 is the most urgent. Priority is optional; tasks without a priority are treated as unprioritized rather than defaulting to any level.

Phase

Phase is a numeric label used to group tasks for parallel execution inside an iteration. Tasks in the same phase have no ordering dependency on each other and can run concurrently. Lower phase numbers execute first. Phases are the parallelism boundary: if one task blocks another, they must live in different phases.

Artifacts

An artifact is a document -- a spec, ADR, RFC, design note, or any other prose output generated during development. Artifacts are rows in the artifacts table; when local sync is enabled they are also mirrored to .gest/artifact/<id>.md as Markdown with YAML frontmatter.

FieldDescription
titleDocument title (extracted from # heading if not set)
bodyMarkdown content
tagsFreeform labels for filtering
metadataArbitrary key-value pairs (JSON object)
archived_atTimestamp set when the artifact is archived

Categorizing artifacts

Artifact categorization is tag-driven. Tag an artifact with spec, adr, rfc, note, or any other label that fits your workflow, then filter with --tag:

gest artifact create "Auth spec" --tag spec --body "..."
gest artifact list --tag spec

Common conventions used in this project's own artifacts:

TagDescription
specProduct or feature specification
adrArchitecture Decision Record
rfcRequest for Comments
noteGeneral-purpose document

Archiving

Artifacts can be archived with gest artifact archive <id>. Archived artifacts are hidden from listings and searches by default, but remain in the database. Use --all to include them in queries.

Iterations

An iteration groups related tasks into an execution plan. Iterations are rows in the iterations table; the iteration_tasks join table records which tasks belong to which iteration and at which phase.

FieldDescription
titleName of the iteration
descriptionGoal or scope of the iteration (Markdown)
statusCurrent state of the iteration
tasksList of task IDs that belong to this iteration
tagsFreeform labels
metadataArbitrary key-value pairs (JSON object)
linksRelationships to other entities

Iteration Statuses

StatusMeaning
activeCurrently in progress (default)
cancelledIteration was deliberately abandoned
completedAll tasks finished successfully

Dependency Graphs

Use gest iteration graph <id> to visualize the phased execution plan. The graph shows tasks grouped by phase, with dependency edges derived from blocked-by / blocks links between tasks. This makes it clear which tasks can run in parallel and which must wait.

Managing Tasks in an Iteration

gest iteration add <iteration-id> <task-id> # add a task
gest iteration remove <iteration-id> <task-id> # remove a task

Working across workspaces

Gest's zero-config discovery resolves each checkout to its own project row by default, so a secondary jj workspace, git worktree, or fresh clone will not see tasks, artifacts, or iterations from the primary checkout until it is explicitly attached to the same project.

From the primary checkout, print the current project id:

gest project

Then from each secondary checkout, attach to that same id:

gest project attach <project-id>

Before removing a workspace, detach it so the project row is not left pointing at a stale path:

gest project detach

Once multiple checkouts share a project, each workspace can call gest iteration next --claim --agent <name> to pull a different unblocked task from the active phase — this is how phases translate into real parallelism across agents. See Dependency Graphs for how phases and blocking links interact, and Orchestrate multiple agents for the end-to-end loop. For the full gest project reference, see gest project.

Linking

Links create typed relationships between entities. When you link two tasks, gest automatically creates the reciprocal link on the target.

Relationship Types

TypeInverseMeaning
blocksblocked-bySource must complete before target can start
blocked-byblocksSource waits on target
parent-ofchild-ofSource is the parent of target
child-ofparent-ofSource is a child of target
relates-torelates-toGeneral association (symmetric)

Link a task to another task:

gest task link <source-id> blocks <target-id>

Link a task to an artifact (no reciprocal link is created):

gest task link <source-id> relates-to <artifact-id> --artifact

Tagging and Metadata

Tags

Tags are freeform string labels. Add them at creation time with --tag or after the fact:

gest task tag <id> "api,security"
gest task untag <id> "security"

Use tags to filter listings:

gest task list --tag api
gest artifact list --tag design

Metadata

Metadata stores arbitrary key-value pairs on any entity. Set values with the -m flag at creation time or through the meta subcommand:

gest task meta set <id> complexity high
gest task meta get <id> complexity

All metadata is stored as JSON in the database. When local sync is enabled, task and iteration metadata is mirrored as YAML in the entity's .gest/ YAML file, and artifact metadata is mirrored as YAML frontmatter in the entity's .gest/ Markdown file.

Storage modes

Gest supports two storage modes:

  • Global store (default): Entity data lives in a single SQLite database at ~/.local/share/gest/gest.db (Linux) or ~/Library/Application Support/gest/gest.db (macOS). One database, shared across every project on the machine — projects are rows inside it.
  • Local sync: Same database, plus a .gest/ directory inside your project. Every mutation writes to the database first, then the sync layer exports the affected rows to YAML and Markdown files in .gest/, grouped into singular per-entity subdirectories (task/, artifact/, iteration/, etc.). On read commands the sync layer imports any files that are newer than their database rows. This gives you an inspectable, git-commitable mirror without giving up ACID guarantees, relational integrity, or efficient queries.

Initialize with gest init for global-only or gest init --local to also create the .gest/ mirror. Remote sync via libsql is opt-in through the [database] config section — see Configuration for details.

Migrating from v0.4.x

If you are coming from gest v0.4.x where data lived in per-entity-type directories under .gest/, run gest migrate --from v0.4 to import your existing .gest/ tree into the new SQLite database. See the v0.4 → v0.5 migration guide for a step-by-step walkthrough, or gest migrate for the short CLI reference.