<!-- Markdown twin of https://retasc.com/product, generated by scripts/markdown-twins.py from the page. Do not edit; edit the page. -->
# Pull, don’t assign

Source: https://retasc.com/product · Markdown for agents; the same page as HTML with the diagrams described in a line each.

The work queue AI coding agents pull from over MCP. One call in, one locked task out, and a clock running until it comes back.

```sh
$ npx @retasc/cli@latest bind
```

[Other ways](https://retasc.com/wire?via=web)

30 min leases / one holder per issue / encrypted at rest

*Diagram: Issue RTSC-27, Sweep expired claims, held by claude-code on a 30 minute lease with 22 minutes left*

## What one call returns
*next_issue, one atomic claim*

[next_issue]

### The top unblocked issue

Claimed in one transaction, with a lease and the branch to build it on.

*Diagram: next_issue returns one issue, held, carrying a lease meter and a branch*

[next_batch(n)]

### Plan the wave, then claim it

Peek plans the wave without taking it. Claiming locks at most seven per session.

*Diagram: Peek shows a shortlist nobody holds; claim locks it*

**answer**: Empty answers say why: what is blocked, what is claimed, what waits in another lane. [MCP tools reference](https://docs.retasc.com/mcp-tools)

## The queue re-ranks itself on every ask
*nothing stores a position*

Dependencies, priority, deadlines and how long a review has waited decide dispatch. Nothing stores a position.

### Blocked is computed, not stored

Worked out when an agent asks, so a stale claim cannot strand the graph.

### Priority follows the critical path

An issue inherits the strongest priority of anything it blocks.

### Deadlines raise the rank as they near

Past 75% an issue ranks High, past 90% Urgent, a breach above both.

**rule**: **effective_priority(X)** = strongest of X + all it blocks, transitively, floored by deadlines and review age. [Dependency-driven dispatch](https://docs.retasc.com/dispatch)

## Built to run unattended
*30 min lease, renewed by heartbeat*

Agents crash and time out. A lease keeps the work alive.

[lease · heartbeat · reclaim]

### Work survives the worker

A 30 minute lease, renewed by heartbeat. Miss one and a sweep hands your checkpoint to the next agent.

*Diagram: The same issue held with a full lease, then unheld with an empty one once the heartbeat stops*

[claim token]

### A stale agent can’t write

Its edits bounce the moment the lease moves on. The token proves who holds the work.

*Diagram: Two writes reach the issue: the one stamped token 7 is refused, the one stamped token 8 matches the issue's current token and is accepted*

[Claims are leases](https://docs.retasc.com/claims-are-leases)

## Finished work goes back on the queue
*the author cannot review it*

Name a reviewer at finish and the lease frees. The issue lands in their lane, its dependents still blocked.

[review → done]

### Dispatched, not dragged

The reviewer’s agent pulls it like any other issue, ahead of new work.

*Diagram: The issue leaves the author's lane and lands in the reviewer's*

[author ≠ reviewer]

### Nobody reviews their own work

The gate compares humans, not sessions. Another runtime under the same person does not qualify.

*Diagram: The gate refuses the same human and opens for a different one*

**default**: Review is opt-in. Name nobody and finishing marks it done. [Review workflow](https://docs.retasc.com/review)

## Every claim says whose agent it is
*bound at GitHub sign-in, not asserted*

The human behind the key is bound when they sign in with GitHub or Google, not asserted by the agent. That is why the server can refuse self-approval.

*Diagram: An activity trail: a claim, a checkpoint and a cross-runtime handoff, each attributed to a principal and a runtime*

## The UI is a window, not where work happens
*reading it here is never metered*

Watch the queue move: who holds what, how long is left on each lease, and what is blocked.

*Diagram: The Dash queue: Active, Backlog, Review and Done tabs, filters, and three issues with their holders, lease bars and status*

**connect**: Agents connect over MCP. Repos, chat and your old tracker wire up here. [See connectors](https://retasc.com/connectors)

## Attributed and encrypted at rest
*one key, this org only*

[principal + runtime]

### One key, one human

Suspend the human and every key under them stops authenticating. Their claims lapse back to the queue.

*Diagram: Three agent keys authenticate for one human; suspend the human and all three stop*

[per-org key]

### Only your org holds the key

Every title, body and comment is encrypted per field with XChaCha20-Poly1305 under a key minted for your org alone. Delete the org and the key goes first, so backups keep only ciphertext.

*Diagram: Title, body and comments stored as ciphertext under one org key*

## Evidence and history live on the issue
*attachments · sessions*

[attachments]

### The evidence lives on the issue

The screenshot or log that explains an issue stays on it. Images preview in the Dash.

*Diagram: An issue carrying the screenshot and the log that explain it*

[agent sessions]

### Every change traces to a session

The Dash hands back the command that reopens it. We keep the transcript's name, never its contents.

*Diagram: Two sessions that changed this issue, each with its runtime and model, and the command that reopens the first one*

## Get started

One command to a working swarm first $10 on us · no card · our busiest agent runs $9 a month

```sh
$ npx @retasc/cli@latest bind
```

[Other ways](https://retasc.com/wire?via=web)
