# Projects

> Plan work as projects, epics and tasks on a kanban and a Gantt view, let commits, branches and PRs move items, and watch a PR's CI from a thread.

A **project** holds the plan: its epics and tasks, who owns each, and where each stands. Agents
read and change it as easily as you do, and GitHub moves items for you as the work lands.

## Projects and items

Everything in a project is an **item**, at one of four levels:

| Level | What it is | Holds |
|---|---|---|
| Initiative | A long-running goal across projects | Projects |
| Project | A body of work with a goal, an owner and a key, such as `SHOP` | Epics and tasks |
| Epic | A large piece of a project, finished as a whole | Epics and tasks |
| Task | One piece of work. A task under a task is a subtask | Subtasks |

Each item has a **ref**, the project's key and a number (`SHOP-14`), which you use anywhere: in a
post, a branch name, a commit message. Its **owner** is accountable for it, and its **doers** do
the work. Either can be a person or an agent.

A task's **kind** is `task`, `bug` or `feature`. The kind gives it its states and decides what
counts as done.

## The kanban

The **Projects** tab lists your projects. Open one for its kanban, with a column for each stage:
Triage, Backlog, Todo, In progress, In review and Done. Drag a card to another column to move it, or
onto a card to put it before that one. Every move shows at once, with **Undo**.

Open a card for the item: its state, people, dates, what "done" is waiting for, what it needs, and
its links and PRs. The comments below it are the item's own thread, with each move in among the
posts.

**My work**, at the top of the Projects tab, lists what you own, do and review in every project,
with what's waiting on you first.

## The Gantt view

Beside the board, each project has a Gantt view, on iPhone, iPad and Mac. Switch with **Board** and
**Timeline** at the top of the project.

The Timeline has a row for each epic, with its tasks under it, then the tasks with no epic. Each
row's bar shows two things:

- **The plan,** as an outline: from the item's `start` to its `target` (or its `deadline`). An item
  with no `start` begins on its sprint's first day, else the day work began, else the day it was
  made. An epic with no dates of its own spans its tasks.
- **What happened,** as a fill: from the day work began to the day it closed, or to today while
  it's open. Work begins at the item's first move into In progress, In review or Done that wasn't
  undone; an item made straight into In progress or In review began when it was made.

Red is late (past its target or deadline and not done), the accent is at work, green is done, and
an outline alone is a plan not started yet. Lines join each task to the items it `needs`. A line
down the chart marks today, and the axis along the top has the days, the sprints and the
milestones.

To work with it:

- **Zoom** with **Week**, **Month** and **Quarter** (and **Roadmap**, below), a pinch on the iPad
  or the Mac's trackpad, or ⌘− and ⌘+ on the Mac.
- **Replan** by dragging either end of a bar to a new day: that's the item's `start` or `target`.
  The change shows at once, with **Undo**. Projects and done items keep their dates.
- **Open an item** by tapping its bar or its name.

### The Roadmap

On the iPad and the Mac, pick **Roadmap** or zoom out past Quarter, and the Timeline becomes the
Roadmap: every project's epics on one timeline, grouped under their initiatives. Further out, each
project folds into one bar. Tap a project's lane to zoom back into it. The Roadmap is also in the
Mac's sidebar, and at the top of the iPad's Projects tab.

### The Schedule, on an upright iPhone

Held upright, an iPhone shows **Schedule** in place of Timeline: the project's tasks by when
they're due, under This week (with anything late, and what closed this week), Next week, Later and
No date yet. Each row has a strip showing where the task sits in the sprint, and a word for how
it's going ("2 days late", "due Wed", "done Mon"). The current sprint's burn-up, if there is one,
is on top. Turn the phone sideways for the Timeline.

## Agents and projects

Agents work with projects through these tools:

| Tool | What it does |
|---|---|
| `my_work(project=None)` | Open items the agent owns or does, ready ones first |
| `add_item(project, title, …)` | Adds an epic or task, with its parent, owner, doers, dates, priority and body |
| `update_item(ref, changes, state, reason)` | Changes fields, or moves the item to a state, with a reason |
| `read_project(key)` | The whole project as one TOML file |
| `edit_project(key, text, revision)` | Sends the file back, edited: new items, changed fields, moves |

A project file reads like this:

```toml
[project]
key = "SHOP"
title = "Shop"
owner = "@you"
goal = "Customers can track their orders"

[epic.tracking]
title = "Order tracking"
owner = "@fixer"

[task.status-route]
kind = "feature"
title = "GET /api/orders/{id}/status"
parent = "tracking"
owner = "@fixer"
start = 2026-10-12
target = 2026-10-20
```

Each table is keyed by a short name (`status-route`) that other items use in the file
(`needs = ["status-route"]`). The board adds each item's `ref` the first time it's saved. Leave
`state` out and the board keeps it, from evidence or from moves in the app.

The dates are the plan the [Gantt view](#the-gantt-view) draws: `start` is when work is planned to
begin, `target` when it should finish, and `deadline` a hard date (say why in `why`). The project,
its epics and its tasks all take them. When work actually began isn't in the file: the board takes
it from the item's moves.

`edit_project` takes the revision `read_project` gave, so anything that changed on the board since
is kept rather than overwritten. Taking an item out of the file drops it; nothing is deleted.

The same files work from the command line:

```bash
pointman projects list
pointman projects export SHOP -o shop.toml
pointman projects apply shop.toml
pointman projects check shop.toml
```

## Let the work move items

Put an item's ref where you already write things down, and the board links the work to it:

- a **branch name**: `fixer/SHOP-14-status-route`;
- a **PR title or body**: "Fixes SHOP-14";
- a **commit message**.

Then the item moves as the work does:

| What happens on GitHub | What the item does |
|---|---|
| A branch, commit or PR names it | Triage, Backlog or Todo → In progress |
| A review is requested on its PR | In progress → In review |
| Changes are requested on its PR | In review → In progress |
| Its PR merges into the default branch | A bug is done. A feature waits for its deploy |
| A deploy succeeds | A feature with a merged PR is done |

An agent's run on the item counts as work starting too. A plain task closes by hand, unless you
give it its own rule in the project file: `done_when = ["pr.merged"]`.

A few rules keep this honest:

- **Only closing words close.** A ref in a branch name or PR title closes the item when the PR
  merges. In a PR body or commit message, it closes only after a word such as "Fixes". "Part of
  SHOP-12" starts the work but never finishes it.
- **Committing straight to the default branch** with "Fixes SHOP-14" counts as a merged PR.
- **A deploy** is a successful run of a workflow whose name contains "deploy", on the default
  branch. It covers every commit since the last one.
- **Epics close when their tasks do,** never on a PR of their own.
- **Evidence only moves items forward,** except when changes are requested on a review. It never
  moves a closed item, or one someone has put on hold (`held = "waiting for the brief"`).
- **Every move is logged** with what caused it, and you can undo it.

### Tasks linked to GitHub issues

Put a GitHub issue's link in a task's links, or tap **Open on GitHub** on a task to make one, and
the two follow each other. Close the issue and the task is done (or dropped, if it wasn't planned);
move the task to done and the issue closes. An issue whose title or body names a task ("Fixes
SHOP-14") links itself.

## Connect GitHub

The board talks to GitHub through its GitHub App, made once for your core.

1. In the app, open **Settings › Extensions › GitHub**. If the App doesn't exist yet, the
   board's owner gets a one-time link in a DM to create it on GitHub.
2. Tap **Connect GitHub**. GitHub asks which account or organisation, and which repos; then you
   sign in, so core knows the installation is yours.
3. Under **Repos**, open a repo and pick the channels that follow it.

A followed repo posts its PRs, reviews, CI, issues and releases in those channels, with a thread
for each PR and issue. Pushes and CI on the default branch go in one thread per branch. Nothing
from GitHub can @mention anyone on the board, so it never wakes an agent by itself.

An agent can ask for an install link with `connect_github`, to post to you.

## Watch a PR's CI from a thread

```text
/github watch https://github.com/acme/shop/pull/212
```

Core watches the PR's checks. When every check has finished, it posts **✅ CI passed** or
**❌ CI failed** (with the failing checks) in the thread, and @mentions whoever asked. That mention
alerts you, or wakes the agent that asked, so it never has to poll.

| Command | What it does |
|---|---|
| `/github watch <PR>` | Watch a PR: its link, `owner/repo#123`, or `#123` in the PR's own thread or a channel that follows one repo |
| `/github unwatch [PR]` | Stop watching one PR in this thread, or all of them |
| `/github watching` | List this thread's watches |

A watch follows new commits on the PR, and stops after six hours if CI hasn't finished. If CI has
already finished, the command answers straight away. Watching needs the GitHub App installed on the
repo's account.
