> ## Documentation Index
> Fetch the complete documentation index at: https://docs.promptingcompany.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Model Council v2

> Create narrative questions, assign positions, and retrieve dashboards with noninteractive, agent-facing commands.

# Model Council v2

Use `tpc council-v2` to ask a question, collect model responses, inspect the discovered narratives, assign share directions, and retrieve dashboard data. Every command is noninteractive.

## Prerequisites

* Authenticate with a TPC session token, such as one obtained through `tpc auth login` or `tpc auth claim`. Enterprise API keys are not supported.
* Model Council v2 must be enabled for your organization.
* Pass `--scope <org-slug>/<product-slug>` on every command. You can also pass the product's dashboard URL as the scope.
* Use `--format json` to emit one structured result object. Text mode emits indented JSON; CSV is unsupported.

## Agent workflow

### 1. Discover a question (optional)

```bash theme={null}
tpc --format json council-v2 questions suggest --scope acme/my-product
```

Returns suggested questions with `text`, `topicId`, and `topicText`. Missing suggestions are generated and cached. You can also supply your own question directly.

### 2. Create the question and start analysis

Generate and retain a UUID for this operation before issuing the command. The example UUID below is illustrative; use a new UUID for each new question.

```bash theme={null}
tpc --format json council-v2 questions create \
  --scope acme/my-product \
  --text "Is My Product suitable for enterprise teams?" \
  --idempotency-key 8df3413a-4f6a-4f45-96db-6ecc0e6db8f1
```

Creation starts analysis and exits immediately. The idempotency key becomes the question ID. Retry an interrupted request with the **same key and identical input**. Reusing a key with different question text, topic, or source returns a conflict.

When selecting a suggestion, also pass `--source generated`, its `--topic-text`, and `--topic` when its `topicId` is non-null. Defaults for custom questions are `--source user`, no topic ID, and `--topic-text "Custom question"`.

If the question was saved but analysis could not start, the command prints `status: "saved"`, the question ID, and recovery instructions, then exits with code 1. Recover with:

```bash theme={null}
tpc --format json council-v2 questions start <id> --scope acme/my-product
```

`start` also retries incomplete or failed analysis. An already-running workflow is reused; fully processed questions need no new run.

### 3. Inspect or wait for analysis

```bash theme={null}
tpc --format json council-v2 questions get <id> --scope acme/my-product

tpc --format json council-v2 questions watch <id> \
  --scope acme/my-product --timeout 5m --interval 3s
```

`get` returns the stored question, processing progress, `state`, and `nextAction`.

| State                | Meaning                                           | Next step                                |
| -------------------- | ------------------------------------------------- | ---------------------------------------- |
| `draft`              | Saved; processing has not yet started             | `questions start`                        |
| `processing`         | Generating, collecting, or clustering             | `questions watch`                        |
| `awaiting_positions` | Analysis complete; directions need to be assigned | `narratives list`, then `positions set`  |
| `ready`              | Analysis and position selection complete          | `dashboard`                              |
| `failed`             | Analysis failed or remains incomplete             | Inspect progress, then `questions start` |

`watch` polls without starting or retrying analysis. It stops at `awaiting_positions`, `ready`, or `failed`. The default timeout is five minutes, measured after authentication and scope resolution; the default polling interval is three seconds, with a minimum of one second. Both flags accept Go durations such as `30s` or `5m`.

On timeout, `watch` prints the last observed state with `timedOut: true` and exits with code 1. If no status response arrived, the state is `unknown`. Resume with `get` or another `watch` invocation.

### 4. Inspect narratives and save positions

```bash theme={null}
tpc --format json council-v2 narratives list \
  --scope acme/my-product --question <id>
```

The response includes current major narrative IDs, labels, definitions, shares, sampled evidence, and the separate Others bucket. Evidence is capped per model; the response includes `evidencePerModelLimit`.

Create a positions file using the returned major narrative IDs:

```json theme={null}
{
  "marks": [
    { "clusterId": "<first-narrative-id>", "stance": "mine" },
    { "clusterId": "<second-narrative-id>", "stance": "opposing" },
    { "clusterId": "<third-narrative-id>", "stance": "neutral" }
  ]
}
```

Stances express the desired share direction: `mine` means **increase**, `opposing` means **reduce**, and `neutral` means **maintain**. Choose directions using the product's goals.

```bash theme={null}
tpc --format json council-v2 positions set \
  --scope acme/my-product --question <id> --file positions.json

tpc --format json council-v2 positions set \
  --scope acme/my-product --question <id> --file - < positions.json
```

Submit every current major narrative exactly once, excluding Others. The API saves the set atomically and rejects stale or incomplete sets. If the narrative set changes, fetch it again before retrying. Use `{"marks":[]}` when there are no major narratives. Input is limited to 1 MiB.

### 5. Get the dashboard

```bash theme={null}
tpc --format json council-v2 dashboard \
  --scope acme/my-product --question <id>

tpc --format json council-v2 dashboard \
  --scope acme/my-product --question <id> \
  --from 2026-09-01 --to 2026-09-27
```

The result includes narrative shares and evidence, stance breakdown (`framing`), `modelComparison`, top cited URLs, current suggested actions, processing progress, and a `dashboardUrl`. Date filters are inclusive UTC dates and apply to the dashboard's claim and citation data; suggested actions and processing progress describe the current question. Either date boundary can be omitted. Evidence and citation caps are included in the response.

To get the product question overview, omit `--question`:

```bash theme={null}
tpc --format json council-v2 dashboard --scope acme/my-product
tpc --format json council-v2 questions list --scope acme/my-product
```

Both return up to 100 active questions, newest first, with their status and summary metrics. Date flags require `--question`.

## Agent output and exit codes

Results include `scope` and `dashboardUrl`. When another step is available, `nextAction` names the command and `nextCommand` supplies an argv array including the question ID and scope. A positions command contains a `<positions.json>` placeholder that the agent must replace with its authored file path.

* **0:** The operation succeeded. `watch` reaching `awaiting_positions` is successful because it needs agent input next.
* **1:** Validation, authentication, API, or filesystem error; creation saved but did not start; or `watch` encountered failed analysis, cancellation, or timeout.

For creation failures after saving and watch failures after a status response, read the JSON result even when the process exits nonzero. `get` and `dashboard` are reads: inspect their `state` rather than interpreting exit code 0 as analysis completion.
