Dataface Tasks

Plans CLI Reference

The plans command manages tasks and initiatives from the command line.

Quick start

# Install (one-time) — the plans entrypoint is registered via pyproject.toml
uv sync --extra dev

# All commands below use `plans` (or `uv run plans` outside an activated venv)

Task commands

Create a task

plans task create \
  --workstream infra-tooling \
  --title "My new task" \
  --description "What this task delivers" \
  --status ready \
  --dependencies sibling-task,another-task

Update a task

plans task update --path tasks/workstreams/infra-tooling/tasks/my-task.md \
  --status in_progress --priority p2 --pr-url https://github.com/org/repo/pull/123 --pr-number 123

Task frontmatter now supports:

  • ready as a first-class queueable status
  • dependencies as a YAML list of task slugs
  • started_at when work begins
  • pr_created_at, pr_number, and pr_url when the task reaches PR handoff

Start a task (shortcut for --status in_progress)

plans task start --path tasks/workstreams/infra-tooling/tasks/my-task.md

For manager-driven dispatch, prefer setting status: ready and then running heartbeat with --dispatch-ready. Reserve task start for already-claimed/manual execution.

Complete a task (shortcut for --status completed)

plans task complete --path tasks/workstreams/infra-tooling/tasks/my-task.md

plans task complete also stamps completed_at and completed_by in task frontmatter. If a completed task is moved back to another status, that completion metadata is cleared.

List tasks

# All tasks across all workstreams
plans task list

# Filter by workstream
plans task list --workstream infra-tooling

# Filter by status (comma-separated)
plans task list --workstream infra-tooling --status not_started,in_progress

Show task details

plans task show --path tasks/workstreams/infra-tooling/tasks/my-task.md

Find task by GitHub issue

# By issue number
plans task find --github-issue 301

# By URL fragment
plans task find --github-issue "github.com/fivetran/dataface/issues/301"

Initiative commands

Create an initiative

plans initiative create \
  --workstream cloud-suite \
  --title "My initiative" \
  --description "Objective of this initiative" \
  --tasks task-slug-1 task-slug-2

Update an initiative

plans initiative update \
  --path tasks/workstreams/cloud-suite/initiatives/my-init/index.md \
  --status in_progress --add-task new-task-slug

Justfile aliases

For convenience, the Justfile provides pass-through wrappers:

just mp-task create --workstream ...    # same as: plans task create --workstream ...
just mp-initiative create --workstream ...  # same as: plans initiative create --workstream ...

Server commands

Run the tasks server (primary local surface)

# Default owner comes from TASK_MANAGER_OWNER (fallback: current system user).
# Heartbeat loop + tasks server (reloads on tasks/ and scripts/ changes):
just tasks serve owner=dave port=8005

# Direct server only (no heartbeat):
uv run python tasks/tools/run_tasks_server.py --port 8005 --owner dave

# Hosted/container mode:
PORT=8080 TASK_MANAGER_OWNER=dave TASKS_SERVER_LIVE_SNAPSHOT=1 \
  uv run python tasks/tools/run_tasks_server.py --host 0.0.0.0 --port "${PORT}" --owner "${TASK_MANAGER_OWNER}" --no-reload

The tasks server is the primary local workflow for browsing tasks and monitoring task status. It provides: - / — tasks-root README.md (Master Plans hub). Legacy /tasks/index, /tasks/README, /tasks, and /tasks/ 308 here. - /tasks/<path> — task plans with a left nav built from tasks/mkdocs.yml (nav config only; MkDocs is not required to read plans), plus Manager (links to /status) at the top of the sidebar. URLs omit .md and directory indexes omit index.md; non-canonical paths 308-redirect to the pretty form. - /workstreams/... and /milestones/... — same markdown as under tasks/workstreams/ and tasks/milestones/, with shorter canonical URLs (e.g. workstreams/foo/index.md/workstreams/foo). Requests under /tasks/workstreams/... 308-redirect here. - /docs and /docs/<path>legacy bookmark URLs; 308-redirect to the matching canonical path (/tasks/..., /workstreams/..., or /milestones/...). - /status — same snapshot UI, wrapped in the docs shell and sidebar - /status.json — raw JSON from the local task-manager heartbeat (same owner as just tasks serve owner=…): in-flight tasks, ready queue, CI hints, etc. Doc pages link to it as Heartbeat snapshot (JSON) in the top-right toolbar. - /evals/ — eval landing page inside the tasks server, with links to rendered eval dashboards and recent run artifacts. - /evals/faces/... — rendered pages from the existing apps/evals Dataface project (for example /evals/faces/overview/ and /evals/faces/sql-leaderboard/). - /evals/artifacts/... — raw eval outputs served directly from apps/evals/runs/. - /browse/ — plain directory + markdown browser under repo root (escape hatch) - /actions/dispatchPOST (form): Build on incomplete workstream task pages for loopback clients only (127.0.0.1 / ::1). Runs uv run python tasks/tools/task_cli.py task start --path … then scripts/dispatch in the background. Non-local clients get no Build button and POST returns 404.

For hosted deployments, set TASKS_SERVER_LIVE_SNAPSHOT=1 so /status and /status.json compute a fresh read-only snapshot without requiring the separate local heartbeat loop that just tasks serve starts.

Optional POST hardening:

Variable Purpose
TASKS_SERVER_DISPATCH_TOKEN When set, require header X-Tasks-Dispatch-Token on POST /actions/dispatch (browser forms cannot send it — for scripted calls).

POST also requires a Referer that matches the server’s own origin.

Evals placement and URLs

The tasks server now treats apps/evals/ as the in-repo eval project.

  • Put generated runs under apps/evals/runs/<family>/<run_id>/.
  • Put summary.json, results.jsonl, and any optional static outputs in that run directory.
  • Browse them from the tasks server at /evals/ and /evals/artifacts/.
  • Rendered eval pages live under /evals/faces/....

This keeps eval browsing on the existing tasks/plans server and avoids separate hosting.

On task-plan pages (/tasks/..., /workstreams/..., /milestones/...), {{ ... }} calls are expanded with Jinja using tasks/macros.py (same functions as the old MkDocs macros plugin). extra.current_milestone is read from tasks/mkdocs.yml.

Task-system script namespace

Use scripts/task-system/* as the canonical local orchestration surface (portable boundary for reuse in other repos):

scripts/task-system/dispatch "<task-slug>" "<prompt>"
scripts/task-system/dispatch-watch "<task-slug>"
scripts/task-system/run --owner dave --interval 60
scripts/task-system/check-status <task-slug-or-path>

Legacy top-level script paths under scripts/ are transitional for compatibility only. Target: retire direct top-level task-system entrypoints by 2026-04-30 after callers are migrated.