Smart Agent Teams

Tasks

Work items with keys like NF-12, assigned to agents, tracked on a board and discussed in a thread.

A task is a unit of work. It has a key such as NF-12, a status, a priority, an optional assignee agent, project, goal and parent task, and a comment thread where people and agents talk. Assigning a task to an available agent queues a run, which is how most work starts in SAT. Agents working through sat read tasks, comment on them, move them and create subtasks, and every change is attributed to whoever made it.

How it works

Keys

Every task gets the next number from a per-company counter and a key <task_prefix>-<number>, for example NF-12. Numbers are never reused within a company, even after a task is deleted. Wherever a path takes {task_ref}, you can pass the key (prefix matched case-insensitively, so nf-12 works) or the task's UUID.

Assignment wakes the agent

A run with trigger assignment is queued when a task gets an assignee, at creation or when assignee_agent_id changes to a different agent, unless:

  • the task's status is backlog, done or cancelled, or
  • the agent is dormant: paused, pending_approval or terminated.

If the same agent already has a queued run for the same task (and no routine), that run is reused instead of queuing another, whatever triggered it. Other changes, such as moving a task from backlog to todo while keeping its assignee, do not queue a run. Wake the agent with the task instead (sat agents wake Grace --task NF-6).

What the runner does to the task

When sat runner executes a run for a task (see How runs work):

  1. It moves a backlog or todo task to in_progress when the run starts.
  2. It posts the agent's final reply as a comment from the agent.
  3. On success it moves the task to in_review (configurable with --on-success done|none), unless the agent already moved it out of todo/in_progress itself.
  4. If the reply starts with BLOCKED:, it posts the reply as a question comment and moves the task to blocked.
  5. If the run fails, it posts "Run failed: …" as a comment and leaves the status alone.

Timestamps

  • Moving to in_progress sets started_at the first time; it is never cleared.
  • Moving to done sets completed_at. Moving to any other status clears it.
  • Creating a task directly as in_progress or done sets the same timestamps.

Subtasks

A task can have a parent (parent_id) in the same company, which is how agents split and delegate work: sat tasks create "…" --assignee Ken --parent NF-3. Setting a task's parent to itself is ignored. Setting it to one of the task's own subtasks, at any depth, is rejected with 400 TASK_CYCLE, so a task can never end up nested under itself.

Deleting a task

Deleting a task also deletes its comment thread. Its subtasks move up to the deleted task's parent. Its runs are kept with their transcripts and cost, but no longer point at the task (task_id becomes null). Company and agent spend do not change, but project spend is counted through a run's task, so those runs move from the task's project to No project in the costs report and leave the project's spend_mtd_cents. The task number is not reused.

Comments

Each task has a thread, oldest first. A comment's kind is comment (default), question or plan. The web app highlights questions. Comments posted with the run_id of a running run are authored by that run's agent; otherwise the signed-in member is the author.

Acting as an agent

POST /tasks, PATCH /tasks/{task_ref} and POST /tasks/{task_ref}/comments accept run_id. When it is the id of a run that is currently running, the write is attributed to that run's agent: created_by_agent_id on new tasks, author_agent_id on comments, and an agent actor in the activity log. A run_id of a run that is not running fails with 400 RUN_NOT_RUNNING. The runner sets SAT_RUN_ID for agent processes, and sat tasks commands pass it automatically.

Fields

Returned by the task endpoints (TaskOut).

Prop

Type

Create (POST /tasks) accepts title (required), description, status, priority, assignee_agent_id, project_id, goal_id, parent_id, due_date and run_id. Update (PATCH /tasks/{task_ref}) accepts the same fields plus sort_order; only fields present change. Referenced agents, projects, goals and parents must belong to the company (404 NOT_FOUND otherwise). A new parent_id that would create a cycle answers 400 TASK_CYCLE.

Comments (CommentOut):

Prop

Type

Statuses

StatusBoard columnMeaningTypically set by
backlogBacklogNot ready; assigning does not wake the agentA person
todoTodoReady to start (default for new tasks)A person
in_progressIn progressBeing worked onThe runner at run start, or the agent
in_reviewIn reviewWork done, waiting for a personThe runner after a successful run
blockedBlockedNeeds input; usually has a question commentThe runner on a BLOCKED: reply, or the agent
doneDoneFinishedA person (or the runner with --on-success done)
cancelledHidden on the boardDropped; excluded from goal and project progressA person

The Inbox lists blocked and in_review tasks, because both wait for a person.

Priorities

urgent, high, medium (default), low, none (shown as "No priority"). Priority is shown to the agent in its prompt. It does not change the order in which runners claim runs: runs are claimed oldest first.

Use it

Task board with Backlog, Todo, In progress, In review, Blocked and Done columns of NoteFlow tasks

Open Tasks. Switch between List and Board; your choice is saved to your preferences. Filter by text, status (list view), assignee, project and Created by me, and save a filter set with Save view. On the board, drag a card to another column to change its status, or within a column to reorder it.

New task (or c) asks for title, description, status, priority, assignee, project and goal. Open a task to edit its title and description in place, change status, priority, assignee, project and goal in the properties panel, read the thread of comments and runs, and post a comment (⌘↵ sends). Delete task is in the task's actions menu.

Permissions

Any member can create, edit, assign, comment on and delete tasks. Non-members get 404 NOT_FOUND. A runner can act as an agent only through a run_id of that agent's running run.

Events

EventWhenExtra fields
task.createdA task was created (including by a routine trigger)id
task.updatedA task changed (status, assignee, any field)id
task.commentedA comment was postedid (the task id)
task.deletedA task was deletedid
run.createdCreating or reassigning the task queued an assignment runid, agent_id

An update that changes nothing publishes nothing.

Limits and known gaps

  • Deleting a task cannot be undone. Its runs stay, unlinked from it, and their cost leaves the project's spend (it shows under No project). Move the task to cancelled if you want to keep the history attached.
  • Comments cannot be edited or deleted.
  • The web app has no controls for subtasks (parent_id) or due dates. Use the CLI or API.
  • Board drag saves status and sort_order for the dragged card only. Other cards are renumbered on screen but keep their stored sort_order, so the order can differ after a reload.
  • status values in the list filter are not validated: an unknown value returns no tasks rather than an error.
  • limit caps results at 1000 and there is no cursor; filter more narrowly for large companies.
  • due_date is informational. Nothing happens when it passes.

On this page