# `AgentWorkshop.Work`
[🔗](https://github.com/joshrotenberg/agent_workshop/blob/main/lib/agent_workshop/work.ex#L1)

Work board for agent coordination.

A structured task tracker where work items flow through a lifecycle.
Agents poll for work matching their role, claim it, and advance it
through states. Dependencies between items handle ordering.

## Work item lifecycle

    new → ready → claimed → in_progress → done
                                         → failed
                       ↑
                 blocked (unmet dependency)
                 cancelled

## Usage from IEx

    import AgentWorkshop.Workshop

    # Add work
    work(:cache, "Implement LRU cache",
      type: :code, spec: "LRU with 1000 entries and TTL")
    work(:cache_review, "Review cache implementation",
      type: :review, depends_on: [:cache])
    work(:cache_tests, "Write cache tests",
      type: :test, depends_on: [:cache])

    # Browse
    board()                    # full board
    board(status: :ready)      # items ready to pick up
    board(type: :code)         # only code tasks

    # Work on items
    claim(:cache, :impl)      # agent claims the task
    start_work(:cache)        # mark in progress
    complete(:cache)          # mark done, unblocks dependents
    fail(:cache, "tests broke")

## Agent polling

Agents check the board for work matching their type:

    every(:coder, "Check board(type: :code, status: :ready) and work on one item",
      interval: :timer.minutes(2))

# `t`

```elixir
@type t() :: %AgentWorkshop.Work{
  claimed_at: DateTime.t() | nil,
  claimed_by: atom() | nil,
  completed_at: DateTime.t() | nil,
  created_at: DateTime.t(),
  depends_on: [atom()],
  error: String.t() | nil,
  id: atom(),
  metadata: map(),
  priority: non_neg_integer(),
  result: String.t() | nil,
  spec: String.t() | nil,
  started_at: DateTime.t() | nil,
  status: atom(),
  title: String.t(),
  type: atom()
}
```

# `add`

```elixir
@spec add(atom(), String.t(), keyword()) :: :ok
```

Add a work item to the board.

# `cancel`

```elixir
@spec cancel(atom()) :: :ok | {:error, term()}
```

Cancel a work item.

# `claim`

```elixir
@spec claim(atom(), atom()) :: :ok | {:error, term()}
```

Claim a work item for an agent.

Uses atomic ETS take-and-reinsert to prevent race conditions
when multiple board workers poll simultaneously.

# `clear`

```elixir
@spec clear() :: :ok
```

Clear all work items.

# `complete`

```elixir
@spec complete(atom(), String.t() | nil) :: :ok | {:error, term()}
```

Mark a work item as done. Unblocks dependents.

# `fail`

```elixir
@spec fail(atom(), String.t() | nil) :: :ok | {:error, term()}
```

Mark a work item as failed.

# `get`

```elixir
@spec get(atom()) :: t() | nil
```

Get a work item by ID.

# `list`

```elixir
@spec list(keyword()) :: [t()]
```

List work items, optionally filtered.

# `remove`

```elixir
@spec remove(atom()) :: :ok
```

Remove a work item from the board entirely.

# `start_work`

```elixir
@spec start_work(atom()) :: :ok | {:error, term()}
```

Mark a work item as in progress.

# `summary`

```elixir
@spec summary() :: map()
```

Summary counts by status.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
