# How Flow works

> The records Flow keeps, what it computes from them on every read, and the two writes it refuses.

Flow keeps a small number of records and derives everything else from them each time they are read. Knowing which is which is most of knowing how to use it: what you write is an assertion somebody has to keep true, and what Flow computes cannot go stale.

## What Flow keeps

**A project** (`proj_…`) is where work lives and who can see it: a product, a client, a household. Every task names its project on the call that creates it, and there is no current project to fall back on. Sharing a project shares everything in it and nothing outside it. A project you are not a member of answers as if it did not exist.

**A task** (`task_…`) is one piece of intent. It carries:

- a **status**, the answer to "is this a commitment, and what holds it": `active`, `waiting`, `calendar`, `blocked`, or one of the non-commitments and closed states. The full list, and which moves are allowed, is in the [vocabulary](https://flow.ttoss.dev/docs/vocabulary.md#statuses);
- a **kind**. Most tasks are commitments. An outcome that needs several steps is kind `project` and carries no work of its own. A `decision` records a choice, including a standing rule for agents. The rest are in the [vocabulary](https://flow.ttoss.dev/docs/vocabulary.md#record-kinds);
- an optional **priority**: `very_low`, `low`, `medium`, `high` or `very_high`, listed in the [vocabulary](https://flow.ttoss.dev/docs/vocabulary.md#priorities). Most tasks have none;
- **tags**, which group work and hold nothing up;
- when it was **last confirmed**, and, for work, when it is **due for review**. A record (evidence) has no review date and no readiness, because there is nothing to start or confirm about it.

**A capture** (`cap_…`) is something that arrived and has not been decided: a sentence, an email, a webhook, verbatim, with its source. Captures sit in your inbox, which is personal. A capture is not a task and never becomes one. Triaging it creates a task that points back to it, and the capture stays as it arrived. See [Capture](https://flow.ttoss.dev/docs/method/capture.md).

**An edge** links two tasks with a kind from a closed set. `blocks` is the only kind that holds work up; the others record support, decisions, supersession and plain mentions. Edges are many to many, and there are no sub-tasks: an outcome is reached when the work that `blocks` it is done. See the [link kinds](https://flow.ttoss.dev/docs/vocabulary.md#link-kinds).

**A reference** points outside the graph, at an issue, a pull request, a commit, a file or a URL, with a role: `source`, `spec`, `implements` or `context`. A reference is its URL, and any number of tasks may cite the same one: an issue that specifies four phases is four tasks, each referencing it. One piece of intent across three repositories is one task with three references, not three tasks.

**A wait** says what holds a task that no other task blocks. A `scheduled` wait carries a date and clears itself. An `external` wait names who or what you are waiting on, and may need chasing: its `until` is the date to chase on.

**A change** is kept for every move of a task's status, priority or holder: who made it, from what to what, when, and the cause it named, which is a record's id, a URL or the person's own words ([P4](https://flow.ttoss.dev/docs/method/principles.md#p4-every-change-to-a-commitment-carries-its-cause)). Changes are only ever added. [`get-task`](https://flow.ttoss.dev/docs/reference/get-task.md) lists them, oldest first, so "why did this stop, and who agreed?" is a read.

## What Flow computes

**Readiness** is derived from the edges and waits on every read, and never stored. A task is **ready** when it is `active`, nothing open `blocks` it, and no wait holds it. A task that is not ready says why: `blocked:dependency` (another task holds it, the graph will clear it), `blocked:external` (chase someone) or `waiting:scheduled` (a date will clear it). A blocker in a project you are not a member of still holds your task; it is reported with no id or title, because naming it would reveal a project you cannot see.

**The ready set** is every ready task, ranked by the priority you asserted first and then by leverage: how many open tasks finishing this one would free. [`get-next`](https://flow.ttoss.dev/docs/reference/get-next.md) answers its top task, one at a time, and more when asked. Asked by `slice`, the same call answers the reviews that are due and the drift: anything whose status contradicts what the graph can see.

**The order** is the `blocks` graph in waves. Everything in one wave can run in parallel, so the size of the first wave is how many agents can usefully start now. [`get-order`](https://flow.ttoss.dev/docs/reference/get-order.md) answers it, and reports any cycle it finds.

**What is due for review** comes from each task's review date: open work nobody has written or confirmed for a week, and `incubated` or `reference` tasks nobody has for a month. Priority orders the ready set and sets no review date. [`get-next`](https://flow.ttoss.dev/docs/reference/get-next.md) `slice=review` answers it. [`get-next`](https://flow.ttoss.dev/docs/reference/get-next.md), asked for its recovery slices, answers the question after a gap, and [`validate-project`](https://flow.ttoss.dev/docs/reference/validate-project.md) lists what the graph contradicts about itself.

## What Flow reports, and the two things it refuses

Flow accepts writes and reports what it noticed. A `blocks` cycle is stored and reported. A link to work nobody has captured comes back `unresolved`, and nothing is invented to fill it. A change to a commitment that names no cause is written and flagged `needs_reconciliation` until somebody supplies one with [`reconcile-task`](https://flow.ttoss.dev/docs/reference/reconcile-task.md).

The first refusal is a status move the state table does not allow: reopening a closed task in place, closing an `incubated` idea as `completed` or `cancelled` when it was never a commitment, or moving `reference` anywhere but `archived`. Between the open statuses of work, any move is allowed. It answers `409 invalid_transition` with the moves that are allowed, so the next call can be the right one.

The second is a `calendar` task with no date. `calendar` says a date holds the work, so creating one, moving a task onto it, or taking its date off without a `scheduled` wait carrying `until` answers `400 calendar_requires_date`. The same call with the date lands.

## Who can reach what

- **A client you connect**, such as Claude Code, registers itself and asks for your consent the first time. On the consent screen you can restrict it to some of your projects, and it never sees the others.
- **An API key** is for an agent that runs unattended, such as CI or a scheduled job. Give each agent its own, so the one that leaks can be revoked alone.
- **An ingest endpoint** is a URL an app, a mailbox or a bot posts to. It can write a capture into your inbox and do nothing else. See [an endpoint your app posts to](https://flow.ttoss.dev/docs/examples/an-endpoint-for-an-app.md).

Every task, project and capture has an id like `task_x7kp2mq4vb`, assigned by Flow and never chosen by the caller. It is the only thing any call uses to name a record.
