task store
the task store is the authoritative database for all kasmos task state. it tracks task status, content, subtasks, phase timestamps, pr state, review cycles, and signals. kasmos supports two backends:
- global sqlite (default) — a single machine-wide database shared by all repos.
- remote http store — a kasmos server instance, used for team or ci environments.
pr creation outcome columns
automatic and manual PR creation persist their latest result on the task row:
| column | type | meaning |
|---|---|---|
pr_create_state | text | latest outcome: created, adopted, skipped, failed, or blocked |
pr_create_error | text | human-readable reason for a non-success outcome |
pr_create_attempts | integer | number of creation attempts, used to bound retries |
pr_create_attempted_at | timestamp | time of the latest attempt, used to schedule retry backoff |
pr_url remains the canonical URL. A created or adopted PR writes pr_url and the corresponding outcome; a non-success records enough detail for the TUI, CLI, and retry sweep to explain the result.
global sqlite
default path: ~/.config/kasmos/taskstore.db
the task store is a machine-global, cross-project database — not repo-local. tasks from different repositories are separated by project name (derived from the repo root directory name), so one file serves all your projects. all git worktrees of the same repository share the same project namespace.
the kasmosdb user service typically runs kas serve, which owns the shared sqlite-backed task store, the admin ui, and the shared http mcp endpoint. agents should connect through that shared mcp endpoint by default rather than spawning per-agent kas mcp stdio servers.
# inspect the resolved DB path
kas debug
# check the kasmosdb service
systemctl --user status kasmosdb
sqlite characteristics
- no per-repo configuration required — kasmos creates the global file on first use.
- migrations run automatically when the store opens.
- concurrent access from multiple agents is safe because kasmos uses WAL mode and per-operation transactions.
- worktree-safe — all worktrees of the same repository share one project namespace in the global store.
remote http store
to share task state across machines or use a central server in ci, set database_url in config.toml:
database_url = "http://host:7433"
when database_url is non-empty, kasmos routes all task store operations to the http api instead of the local sqlite file. start the server with:
kas serve --port 7433 --db /path/to/shared/taskstore.db
the http client is initialized lazily — the URL is validated syntactically at startup, but no network connection is made until the first store operation.
rest api
the http store exposes the following endpoints (implemented in config/taskstore/server.go):
health
| method | path | description |
|---|---|---|
GET | /v1/ping | check store availability |
tasks
| method | path | description |
|---|---|---|
GET | /v1/projects/{project}/tasks | list all tasks; filter with ?status= or ?topic= |
POST | /v1/projects/{project}/tasks | create a task |
GET | /v1/projects/{project}/tasks/{filename} | get a single task |
PUT | /v1/projects/{project}/tasks/{filename} | update task metadata |
task content and subtasks
| method | path | description |
|---|---|---|
GET | /v1/projects/{project}/tasks/{filename}/content | get task markdown content |
PUT | /v1/projects/{project}/tasks/{filename}/content | replace task markdown content |
GET | /v1/projects/{project}/tasks/{filename}/subtasks | list subtasks |
PUT | /v1/projects/{project}/tasks/{filename}/subtasks | replace subtask list |
PUT | /v1/projects/{project}/tasks/{filename}/subtasks/{taskNumber}/status | update a single subtask status |
task metadata
| method | path | description |
|---|---|---|
PUT | /v1/projects/{project}/tasks/{filename}/phase-timestamp | record a phase transition timestamp |
PUT | /v1/projects/{project}/tasks/{filename}/goal | set the plan goal text |
PUT | /v1/projects/{project}/tasks/{filename}/clickup-task-id | associate a ClickUp task ID |
PUT | /v1/projects/{project}/tasks/{filename}/linear-link | store canonical Linear issue metadata |
DELETE | /v1/projects/{project}/tasks/{filename}/linear-link | clear canonical Linear issue metadata |
GET | /v1/projects/{project}/tasks/{filename}/linear-link/lookup | find a task by Linear issue id and optional repeated status= filters |
POST | /v1/projects/{project}/tasks/{filename}/rename | rename (reslug) a task |
POST | /v1/projects/{project}/tasks/{filename}/increment-review-cycle | increment the review cycle counter |
architect decisions
| method | path | description |
|---|---|---|
GET | /v1/projects/{project}/tasks/{filename}/architect-decisions | return the architect decision audit rendered by the admin ui |
architect metadata is read from the registered repository's .kasmos/cache/ directory. malformed json or schema-invalid metadata is reported as an unavailable response with reason architect_meta_invalid, allowing the admin ui to remain usable while the cache is repaired or regenerated. filesystem and repository resolution failures remain server errors.
linear linkage columns
linear linkage is stored as five additive task columns:
| column | purpose |
|---|---|
linear_issue_id | canonical Linear issue id used for duplicate detection |
linear_identifier | human-readable issue identifier such as KAS-123 |
linear_url | Linear issue URL |
linear_team_key | Linear team key, when present |
linear_project_id | Linear project id, when present |
these fields are never derived from task markdown content. they are written only by explicit link operations or raw task-store metadata updates, and cleared only by unlink operations. the task-store http server persists the fields but does not call Linear; Linear fetch, duplicate-safe replacement, audit events, and optional backlink comments live in the cli/mcp linker flow.
pr state
| method | path | description |
|---|---|---|
PUT | /v1/projects/{project}/tasks/{filename}/pr-url | store the pr url |
PUT | /v1/projects/{project}/tasks/{filename}/pr-state | update pr review decision and check status |
POST | /v1/projects/{project}/tasks/{filename}/pr-reviews | record a pr review (idempotent by review id) |
GET | /v1/projects/{project}/tasks/{filename}/pr-reviews/pending | list reviews awaiting fixer dispatch |
GET | /v1/projects/{project}/tasks/{filename}/pr-reviews/{reviewID}/processed | check if a review has been processed |
POST | /v1/projects/{project}/tasks/{filename}/pr-reviews/{reviewID}/reacted | mark a reaction as posted |
POST | /v1/projects/{project}/tasks/{filename}/pr-reviews/{reviewID}/fixer-dispatched | mark fixer agent as dispatched |
topics
| method | path | description |
|---|---|---|
GET | /v1/projects/{project}/topics | list all topics |
POST | /v1/projects/{project}/topics | create a topic |
audit events
| method | path | description |
|---|---|---|
GET | /v1/projects/{project}/audit-events | query audit log entries for a project |
Audit filters include repeated kind=, task, instance, after, before, and limit. after and before accept RFC3339 timestamps with optional fractional seconds; limit defaults to 100 and is capped at 500. Responses include stable numeric id values so external pollers can de-duplicate when using overlapping timestamp windows.
project name
the {project} path segment is the project identifier — typically the repository directory name (e.g. kasmos for /home/alice/projects/kasmos). kasmos derives this from the resolved repo root and passes it to all store operations. when using the http store, all projects on the server are namespaced by this identifier.
filename normalization
task filenames in the store are always stored without a .md suffix. the cli (kas task register, kas task update-content) and mcp task tools normalize .md automatically. a sqlite migration runs on startup to strip any .md suffixes from existing rows.
signals
the task store includes a signals table for daemon coordination. signals transition through pending, processing, done, and failed states. agents should use mcp signal_create to create signals; kas signal emit is the operator and cli fallback. CLI, REST, and MCP task transitions that apply the FSM before emitting a signal mark the gateway payload with fsm_applied; the daemon still runs downstream lifecycle actions without replaying the transition. this includes implement_start, whose pre-applied signal launches the architect or first implementation wave after the task enters implementing. if any dispatched action fails, the source signal is recorded as failed with the action error instead of being marked done. see signals for details.
backing up
the local sqlite file can be backed up with any standard file copy while kasmos is not running. to create a safe online backup:
sqlite3 ~/.config/kasmos/taskstore.db ".backup backup.db"