Skip to main content

What a task is

A task is one piece of work in a workspace. Every task lives in exactly one workspace. It carries a title, an optional markdown body (the brief), two free tags (type and step), a producer-defined payload of ids, and its links: the files and pages the work uses and what came of it. It names who it is for, who reviews it, who created it and who completed it. A task is the record of the work. The ask, its files, every review round, every comment, the action and the result stay on one task, and its timeline tells the story in order.

Tags: type and step

Two tags let a workspace’s agents run their own workflow on top of tasks. Tokenrip stores them, filters on them and never interprets them. Both use the same grammar: lowercase letters, digits, - and _, starting with a letter or a digit, at most 64 characters. Set them when you create a task and change or clear them (null) with an update. type can also be given on a new proposal or report, or on a proposal for a task that has none. Tokenrip changes step only when an approval applies a then (below). List and start filter on both. The old field kind is refused as an unknown field (INVALID_FIELD), with type among the accepted fields. The step reads right in every status: To do at step draft, Doing at step draft, Done at step post.

Three ways in

  • Ask. A person or an agent files a task, for a person or for one agent, optionally with a reviewer, tags, links and a parent task. The assignee is advisory: any editor who can see the task may start it.
  • Propose. Before an agent acts outside the workspace (a post, an email, a booking), it proposes the action: the exact draft, the approve verb (“Post”, “Send”), optionally the files the draft is made of and the step an approval should move it to. The task waits In review for its reviewer. A proposal can also go on an existing task, to send a draft for review.
  • Report. Work worth knowing that needed no approval is reported: a task born Done, with its result and result links. Later results go on the same task.

The lifecycle

Every write takes why and is recorded in the workspace’s change feed.

Rounds

Each proposal opens a round. A round is written when it opens and once more when it closes, and never otherwise. It records:
  • The proposal: its number (1, 2, … per task), the task’s step at the time, the proposer (a person or one agent), the approve verb, then, and the draft: text of at most 64,000 characters and up to 10 artifact versions (draftArtifacts), either, both or neither.
  • The decision: the outcome, when, by whom (or by which instructions version), the then it applied, any edits, and the comment posted with it.
Responses carry the task’s latestRound (whole on a read of one task, { number, outcome } in lists) and its approvedRound: the round being carried out, with its final material, final.text and final.artifacts (per part, the approver’s edit, else the draft). Carry out exactly approvedRound.final. Get Task adds any earlier round whole with round=<n>.

Deciding a round

Every decision names the revision the decider read (expectedRevision). A proposal replaced meanwhile bumped the revision, so the old decision is refused CONFLICT; a round already decided is refused TASK_NOT_IN_REVIEW, which carries the latest round’s number and outcome. decline and the old skip are refused, naming cancel: to say no, cancel the task (task_cancel, rip task cancel). The round closes cancelled, decided by whoever cancelled, and the reason is the task’s cancel reason.

The versions a round uses

A draft names artifact versions, so the reviewer sees exactly what was proposed even after the file changes. Each draft artifact is linked to the task as context, and the versions a round names (its draft’s, and an approver’s edits) are kept for as long as the task exists, whatever the file’s history setting:
  • A whole-file update, an edit or an append that replaces a version in use keeps it.
  • Keeping the last n versions and pruning skip versions in use; prune reports how many it kept as keptInUse.
  • Deleting a version in use is refused 409 VERSION_IN_USE, naming the task and round.
  • Purging the artifact for good releases them; the round then reads the file as gone.
Each draft artifact in a round names its base: the same file in the latest earlier round at the same step. Diff with baseVersionId shows what changed since the last draft (rip artifact diff --version-id <v> --base <base>; rip task show <id> --round <n> prints the command).

Limits

A task holds at most 50 rounds (409 TOO_MANY_ROUNDS), so two agents cannot send a task back and forth forever. A proposer holds at most 200 open proposals per workspace (409 TOO_MANY_PROPOSALS).

Who it is for, and who reviews it

Every role on a task is a principal: a person (an account acting as itself) or one agent (one key on a person’s account). Responses name assignee, reviewer, createdBy, completedBy, a round’s proposedBy and decidedBy, and a comment’s author the same way:
agent is null for the person. agent.id is the agent’s handle in this workspace: name that agent in any task input as agent:<handle>, with a handle from the workspace load’s agents. agent.name is sent only for an agent on your own account; everyone else reads it by its person and harness (“alek’s agent · Codex”). mine means the principal is on your account, isCaller that it is exactly you. Key ids never appear.
  • Assignee. A person: the task is theirs, and their own agents may pick it up. An agent: the task is that agent’s. Empty: anyone’s. Proposing never changes it.
  • Reviewer. A person, an agent, or empty (any person who can edit tasks). It is the task’s reviewer when one is set; otherwise the one the proposer names; otherwise, for an agent’s proposal, the agent’s own person. A person’s proposal with no reviewer is unaddressed: any other person who can edit tasks may decide it. The reviewer may be the assignee, and is never the proposer of the open round (400 INVALID_REVIEWER).
While a task is In review, a new reviewer re-addresses the open review, and a new assignee is whom a send back returns the task to. A decision belongs to whoever the review is addressed to: Nobody decides their own proposal. A person decides only from their own browser session: a browser an agent’s sign-in link signed in is refused LINK_SESSION_FORBIDDEN. Anyone else is refused REVIEW_NOT_YOURS, which names the reviewer. A task has one links array. Each link has a role and points at an artifact in the task’s workspace (optionally at a version) or at a URL: A link input is { artifact, version? } (the artifact by id or page URL; a version page’s URL names that version; version is a number or a version id) or { url } (at most 255 characters). A link reads back as { id, role, artifact: { id, title, type, version } | null, url, addedAt }. An artifact must live in the task’s workspace and, on a shared task, be shared (400 INVALID_LINKS); one in the trash is refused 410 DELETED and left out of reads until it is restored. A version is a pointer, not a use: if that version is deleted later, the link reads the file’s current version. Each target appears once per role (a target already linked is left as it is), at most 50 per call and 100 per role per task.

Comments

A comment is markdown of at most 8,000 characters on a task: a question, a requested change or an answer. Comments are not a status channel: the task’s own state already says where the work stands.
  • Who posts: anyone who can read the task, any role, viewers included. An external member comments only on shared tasks.
  • Who changes one: only its author: the same agent key, or the person (who also changes their own agents’ comments). Anyone else is refused 403 COMMENT_NOT_YOURS. An edit replaces the text and marks it edited; a delete removes the text for good and leaves a deleted marker.
  • With a move: propose and decide take an optional comment, posted in the same write, so nobody can take the task between a decision and its notes. A send back requires one.
  • No email. Comments land in the task’s timeline and the workspace change feed (comment.created, comment.updated, comment.deleted); the event never carries the text.
See Comments for the routes. CLI: rip comment add --task <id>, rip comment update <id>, rip comment delete <id>. MCP: comment_create, comment_update, comment_delete.

The timeline

A task’s timeline is its story, newest first. Get Task returns the newest 30 entries as timeline: { entries, nextCursor }; pass nextCursor back as timelineCursor for the next 30. Each entry carries exactly one of:
  • round: a review round, its draft, edited text and comment cut to 512 bytes (cut: true says one was; read the round whole with round=<n>), with the why and harness its proposal and decision were recorded with;
  • comment: a comment, with edited and deleted markers;
  • event: any other step from the change feed (created, started, stopped, lease lapsed, completed, cancelled, reopened, result added, links changed, tags or roles changed), with who took it, from which harness, and why.
Rounds and comments never drop out. Events follow the workspace’s activity retention. rip task timeline <id> pages to the start.

Starting by tags

An agent that runs a step of the workflow claims its next task in one call:
POST /v0/tasks/start (MCP task_start with workspaceId, type, step) takes the oldest To do task in the workspace that matches the tags, in the caller’s audiences, and starts it under the caller’s lease. The answer is { task }, with its latest round whole and its approved round, or { task: null } when nothing matches; nothing is recorded then. Two agents starting at once never get the same task. A start by tags never takes a task for another agent or another person, nor one In review, Doing, Done or Cancelled. Starting by tags is for agents; a person starts a task by its id. Use a start with no tag for your own queue, and the tags with the step for routine work. Give the step (or no tags), never a type alone: --type article alone also matches an approved article waiting at the next step, which is another agent’s work.

The claim loop

Start (by id or by tags), work, then propose (it needs review), complete (it is done) or stop (put it down). Two rules go with it:
  • Renew during long work. Start the task again before its lease runs out. Once it lapses another agent may take the task, and your propose is then refused TASK_TAKEN.
  • Only the holder writes the task’s draft artifacts. The hold covers the task, not its files. This is a convention, not enforced: an agent whose lease lapsed may already have overwritten a draft file.

Example: an article pipeline

Simon wants a launch article with an X post and a LinkedIn post. A writer agent drafts, Simon reviews, and a publisher agent posts.
1

Simon asks for the article

Simon’s agent files it:
The task is To do at step draft, for no one.
2

The writer claims it by tags

3

The writer proposes text and two files

The writer publishes the two posts as workspace files, then proposes the article with them and then: post:
Round 1 opens at step draft. The review waits on Simon, the writer’s own person.
4

Simon sends it back

Simon reads round 1 and sends it back with a comment: { "decision": "send_back", "comment": "The X post is too long. Lead with the date.", "expectedRevision": 4 }. Round 1 closes sent_back; the task is To do at step draft, for no one, as it was.
5

The writer revises and proposes again

The writer’s next start by tags returns the task once it is the oldest matching To do task the writer may take (an older matching task comes first). The answer’s latestRound.comment says what to change. The writer updates the X post (round 1 keeps its version) and proposes again:
Round 2 opens. Each draft file’s base is its round 1 version, so Simon sees what changed.
6

Simon approves

Round 2 closes approved and applies then: post: the task is To do at step post, unassigned. approvedRound points at round 2.
7

The publisher posts exactly what was approved

The task is Done at step post, with its result links. Its timeline holds both rounds, the comments and every step.
Over MCP the same pipeline is task_create, task_start { workspaceId, type, step }, task_propose { id, draft, draftArtifacts, approveVerb, then }, task_decide, and task_complete { id, result, links }.

Instructions

Each agent has instructions in each workspace: markdown its person writes (its job here, how to do it, what to watch for) and an on its own list, the types of work it may carry out without asking. Only the agent’s own person writes them, from their own browser, under the workspace’s Members & settings. No agent writes instructions. Every save is a new version; the change feed records which types were added or removed, never the text. The agent reads its current instructions, whole, first in every workspace load. The server applies the on-its-own list: a proposal approves itself at once, decided by that instructions version, when all three hold:
  1. the proposal goes to the agent’s own person (the default reviewer, or that person named or already set as reviewer);
  2. its type is on the agent’s current on-its-own list;
  3. the agent’s own account gave the task that type: the agent’s own new proposal, a task its person (or another of that person’s agents) filed or tagged with that type, or a type this agent set on a task that had none.
Then the reply comes back approved (latestRound.byInstructions names the version and the agent). With a then, the task is To do at that step, unassigned; without, it is doing, held by the agent under the default 2-hour lease. Anything else waits In review. Tasks approved earlier stay approved when the list changes. The text holds at most 8,000 characters and at most 18,000 bytes as load’s JSON carries it, so it always loads whole: plain text fits 8,000 characters, text in CJK scripts about 6,000, emoji about 4,500. The list holds at most 50 types, in the tag grammar. Longer reference belongs in a pin or a skill, which the instructions can name.

Holds and leases

A doing task has exactly one holder: an agent key, or the person in the browser. An agent’s hold carries a lease that expires, because a harness can vanish mid-run; the person’s hold has none and lasts until they move the task. The hold belongs to the agent’s key, so two agents of the same person never hold one task at once. A task is free when it is todo, or doing under an agent hold whose lease has lapsed. Starting a lapsed hold takes it over. Leases run from 15 minutes to 72 hours, defaulting to 2. A sweep runs every minute and returns a lapsed agent hold to todo. Races resolve at the database, not in your code. If two harnesses start the same task at the same moment, exactly one gets it and the other gets 409 TASK_TAKEN, whose holder says who has it and until when. Two simultaneous decisions resolve the same way.

Results and parents

A task keeps what came of it: result, at most 280 characters (“4 likes”, “Sent to 3 people”), given at completion or in a report, and its result links. A later result on a Done task replaces the text and adds links. Reopening keeps both. A task can have a parent, set only when it is created: a task in the same workspace, with at most 100 children. A parent’s children In review show as one card in the dashboard, which a person can decide one by one or all at once (approve all, or cancel all).

Workspace and audience

A task belongs to one workspace and one audience inside it: internal (the workspace’s internal members) or shared (external members too). Creating or listing without a workspace answers 400 WORKSPACE_REQUIRED. When someone loses access (removed from the workspace or its owning team, downgraded, or narrowed out of the task’s audience), their holds go back to todo, they stop being the assignee or reviewer of tasks they can no longer work on, and their open proposals are withdrawn. While a workspace is in the trash, its tasks answer 410 WORKSPACE_DELETED.

How agents use it

  1. Load the workspace first; it opens with your instructions. Then what waits on you: approved tasks to carry out, reviews addressed to you, and To do tasks naming you (a sent-back one among them). The load lists them under waiting.
  2. Claim work by id, or by tags with the step.
  3. Before acting outside the workspace (post, send, publish, book), propose it: the draft, the files it is made of, the verb, and a then when another step takes it from there.
  4. The reply says In review (stop; it comes back to you) or approved (your instructions allow it).
  5. Carry out only approvedRound.final, the reviewer’s edits included, then complete with the result and result links. If it fails, propose again with what went wrong, or cancel with the reason. Check that you have not already done it before acting.
  6. Sent back? latestRound.comment says what to change: revise and propose again.
  7. Report work worth knowing that needed no approval; later results go on the same task.
Every write states why: one sentence on what the person is trying to accomplish. See List Tasks for the filters, Update and Transition Tasks and Propose, Report and Decide for the bodies and refusals.

In the change feed

Every step is recorded in the workspace’s change feed: task.created, task.updated, task.audience_changed, task.started, task.stopped, task.lease_expired, task.proposed, task.approved, task.sent_back, task.withdrawn, task.completed, task.reported, task.result_added, task.links_changed, task.cancelled, task.reopened, and comment.created, comment.updated, comment.deleted. Older rows may read task.skipped. Events carry ids, round numbers and tags, never a draft, a comment or a result’s text. Read the feed with rip workspace changes <workspace>, MCP workspace_changes, or GET /v0/workspaces/{id}/changes. The account and team activity feed carries no task events.

How people see it

A workspace’s Home in the dashboard lists, under Action items, everything waiting on the person: reviews addressed to them (or unaddressed, when they may decide), never their own proposal, and To do tasks for them with no agent named, approved ones included. A review card shows the draft with the approve verb, Send back and Cancel task; a To do card has Start and Complete. A review addressed to one of the person’s agents waits on that agent, not on them. Beside it, Done lists what finished in the last 24 hours with what came of it. Every task has its own page: who asked or proposed it, who it is for and who reviews it, the draft and its files, the decision and its comment, files and links, the result, the tasks under it and the timeline with every round, comment and step. The Tasks place lists tasks grouped Doing, In review, To do and Done. A person can add, start, stop, complete, cancel, reopen and decide from the browser; a task they start is held by them, with no lease, until they move it. Sending back with a comment, commenting and proposing on an existing task (Send for review) are on the operator API (POST /v0/operator/tasks/{id}/decide, /v0/operator/comments, POST /v0/operator/tasks/{id}/propose), in the person’s own browser; the dashboard has no control for them.

Limits and gotchas

  • In review means wait. Starting or completing an In review task answers 409 TASK_IN_REVIEW. If it is your proposal, leave it: once decided it comes back through waiting, or stop withdraws it. If it is someone else’s, leave it to its reviewer.
  • Carry out approvedRound.final, not your draft. The reviewer may have edited the text or a file.
  • A lease expiring is not a failure. It returns the task to todo for whoever is next. For long work, start it again to renew the lease.
  • Completing a task someone else holds answers 409 TASK_TAKEN and persists nothing.
  • Leave the person’s holds alone. A task the person started in the browser never lapses.
  • since=0 and negative values are 400, not an empty list. since is a positive number of days back or an ISO-8601 timestamp.
  • A cursor is opaque. A malformed one answers 400 INVALID_CURSOR; re-run the query rather than editing it.
  • due_at is informational. Nothing sorts or filters on it.
  • Doing it twice is your responsibility. Tokenrip does not carry out actions for you; before acting on an approval, check that you have not already done it.

Propose, Report and Decide

Rounds, decisions, bodies and refusals

Workspaces

Where every task lives, and what load returns