# `Nous.Teams.SharedState`
[🔗](https://github.com/nyo16/nous/blob/v0.17.1/lib/nous/teams/shared_state.ex#L1)

ETS-based shared state for per-team discoveries and file region claims.

Owns an ETS table that stores:
- **Discoveries** — findings shared by agents (topic, content, timestamp)
- **Region claims** — file region locks to prevent editing conflicts

## Architecture

Each team gets its own `SharedState` GenServer. The ETS table is owned by this
process and destroyed when the process terminates. Claims auto-expire after a
configurable timeout (default 5 minutes).

## Quick Start

    {:ok, pid} = SharedState.start_link(team_id: "team_1")

    SharedState.share_discovery(pid, "alice", %{topic: "Bug in parser", content: "Found null check missing"})
    SharedState.get_discoveries(pid)

    :ok = SharedState.claim_region(pid, "alice", "lib/parser.ex", 10, 20)
    {:error, :conflict} = SharedState.claim_region(pid, "bob", "lib/parser.ex", 15, 25)
    :ok = SharedState.release_region(pid, "alice", "lib/parser.ex")

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `claim_region`

```elixir
@spec claim_region(
  pid(),
  String.t(),
  String.t(),
  non_neg_integer(),
  non_neg_integer()
) ::
  :ok | {:error, :conflict}
```

Claim a file region for exclusive editing.

Returns `:ok` if the claim succeeds, or `{:error, :conflict}` if the region
overlaps with an existing claim by a different agent.

## Examples

    :ok = SharedState.claim_region(pid, "alice", "lib/parser.ex", 10, 20)
    {:error, :conflict} = SharedState.claim_region(pid, "bob", "lib/parser.ex", 15, 25)

# `get_claims`

```elixir
@spec get_claims(pid()) :: [map()]
```

Get all current region claims.

Returns a list of maps with `:agent`, `:file`, `:start_line`, `:end_line`,
and `:expires_at` keys.

## Examples

    claims = SharedState.get_claims(pid)
    # [%{agent: "alice", file: "lib/parser.ex", start_line: 10, end_line: 20, expires_at: ~U[...]}]

# `get_discoveries`

```elixir
@spec get_discoveries(pid()) :: [map()]
```

Retrieve all discoveries stored for this team.

Returns a list of maps with `:agent`, `:topic`, `:content`, and `:timestamp` keys.

## Examples

    discoveries = SharedState.get_discoveries(pid)
    # [%{agent: "alice", topic: "Bug", content: "...", timestamp: ~U[...]}]

# `release_region`

```elixir
@spec release_region(pid(), String.t(), String.t()) :: :ok
```

Release all region claims for an agent on a specific file.

## Examples

    :ok = SharedState.release_region(pid, "alice", "lib/parser.ex")

# `share_discovery`

```elixir
@spec share_discovery(pid(), String.t(), map()) :: :ok
```

Store a discovery from an agent.

The discovery map should contain `:topic` and `:content` keys. A timestamp
is automatically added.

## Examples

    SharedState.share_discovery(pid, "alice", %{topic: "Bug", content: "Null check missing"})

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

Start a SharedState process for a team.

## Options

- `:team_id` (required) — unique identifier for the team
- `:claim_ttl` — claim expiration in ms (default: 5 minutes)
- `:discovery_ttl` — discovery expiration in ms, or `:infinity` (default: 1 hour)
- `:name` — optional GenServer name

---

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