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

# Comments & questions

> Reference for the 29 MCP tools that capture structured Q&A and free-form comments across cards, ideations, refinements, specs, and sprints — including the choice-question pattern that powers Pulse's ambiguity-killer protocol.

# Comments & questions

Pulse exposes **29 of its 216 MCP tools** for back-and-forth communication on pipeline entities:

* **Q\&A on every entity type** — open and choice questions, with answer-or-select responses. **22 tools** spanning ideation, refinement, spec, card, and sprint.
* **Free-form comments on cards** — text comments and choice "polls". **7 tools**.

Source-of-truth citations: `okto-pulse-feature-inventory.md:272–289` (card Q\&A + comments + attachments), `:290–314` (ideation), `:315–332` (refinement), `:353–370` (spec Q\&A), `:457–475` (sprint Q\&A), `:476–484` (delete-Q\&A across stages).

***

## Two patterns, one shape

|                    | Q\&A                                                                             | Comments                                               |
| ------------------ | -------------------------------------------------------------------------------- | ------------------------------------------------------ |
| **Lives on**       | `entity.qa_items` (JSONB on parent)                                              | Dedicated `comments` table linked by `card_id`         |
| **Attached to**    | Ideation, refinement, spec, card, sprint                                         | Card only                                              |
| **Question types** | Open (free-text answer) and choice (single- or multi-select, optional free-text) | Text comments and choice "polls" (single/multi-select) |
| **Lifecycle**      | ask → answer → optional delete                                                   | add → optional update / respond → delete               |
| **Permissions**    | `Permissions.QA_CREATE`, `_ANSWER`, `_DELETE`                                    | `Permissions.COMMENTS_CREATE`, `_UPDATE`, `_DELETE`    |

Use **Q\&A** when you need a structured, reviewable trail of decisions ("did the agent confirm X before advancing?"). Use **comments** for ad-hoc collaboration on a specific card.

The **ambiguity-killer protocol** (an ideation-stage best practice) leans heavily on `okto_pulse_ask_ideation_choice_question`: asking the user to pick between options is faster and less ambiguous than asking an open question.

***

## Q\&A reference (22 tools)

The shape is identical across entity types — only the noun changes. Per parent: `ask_*_question` (open), `ask_*_choice_question` (structured), `answer_*_question`, `list_*_qa`, `delete_*_question`.

### Ideation (`server.py:4282–4538`)

| Tool                                      | Line  | Purpose                                                                        |
| ----------------------------------------- | ----- | ------------------------------------------------------------------------------ |
| `okto_pulse_ask_ideation_question`        | 4282  | Ask an open-ended question.                                                    |
| `okto_pulse_ask_ideation_choice_question` | 4331  | Ask a structured question with options (the **ambiguity-killer** entry point). |
| `okto_pulse_answer_ideation_question`     | 4418  | Answer a Q\&A item — pass `answer` for open, `selected` for choice.            |
| `okto_pulse_list_ideation_qa`             | 4485  | List Q\&A items on an ideation.                                                |
| `okto_pulse_delete_ideation_question`     | 12011 | Delete a Q\&A item.                                                            |

### Refinement (`server.py:5204–5460`)

| Tool                                        | Line  | Purpose                           |
| ------------------------------------------- | ----- | --------------------------------- |
| `okto_pulse_ask_refinement_question`        | 5204  | Ask an open question.             |
| `okto_pulse_ask_refinement_choice_question` | 5253  | Ask a structured choice question. |
| `okto_pulse_answer_refinement_question`     | 5340  | Answer.                           |
| `okto_pulse_list_refinement_qa`             | 5407  | List Q\&A.                        |
| `okto_pulse_delete_refinement_question`     | 12050 | Delete.                           |

### Spec (`server.py:10413–10974`)

| Tool                                  | Line  | Purpose                           |
| ------------------------------------- | ----- | --------------------------------- |
| `okto_pulse_ask_spec_question`        | 10413 | Ask an open question.             |
| `okto_pulse_ask_spec_choice_question` | 10464 | Ask a structured choice question. |
| `okto_pulse_answer_spec_question`     | 10552 | Answer.                           |
| `okto_pulse_list_spec_qa`             | 10619 | List Q\&A.                        |
| `okto_pulse_delete_spec_question`     | 11973 | Delete.                           |

### Card (`server.py:2638–2777`)

| Tool                         | Line | Purpose                         |
| ---------------------------- | ---- | ------------------------------- |
| `okto_pulse_ask_question`    | 2639 | Ask an open question on a card. |
| `okto_pulse_answer_question` | 2689 | Answer a card Q\&A.             |
| `okto_pulse_delete_question` | 2742 | Delete a card Q\&A.             |

<Note>
  Cards do **not** have a `ask_choice_question` tool — choice flows on cards use the comment system below (`okto_pulse_add_choice_comment`), which lives in the same file area and is richer (multi-responder support, response history).
</Note>

### Sprint (`server.py:11903–11972`)

| Tool                                | Line  | Purpose                           |
| ----------------------------------- | ----- | --------------------------------- |
| `okto_pulse_ask_sprint_question`    | 11903 | Ask an open question on a sprint. |
| `okto_pulse_answer_sprint_question` | 11937 | Answer a sprint Q\&A.             |
| `okto_pulse_delete_sprint_question` | 12089 | Delete a sprint Q\&A.             |

### Cross-stage carry-over

| Tool                         | Line | Purpose                                                                                                              |
| ---------------------------- | ---- | -------------------------------------------------------------------------------------------------------------------- |
| `okto_pulse_copy_qa_to_card` | 7838 | Copy **answered** Q\&A items from a spec into a card as a single consolidated comment. Unanswered Q\&As are skipped. |

This is the bridge that makes spec-level decisions visible to an implementer working a card without forcing them to chase pointers back to the spec.

```text theme={null}
Input to okto_pulse_copy_qa_to_card:
  board_id: "brd_abc123"
  spec_id:  "spec_XYZ"
  card_id:  "card_001"

Output:
{
  "success": true,
  "copied":  4
}
```

The card receives a new comment whose body is a Markdown summary:

```markdown theme={null}
## Spec Q&A Context

**Q:** Should retries be exponential or fixed?
**A:** Exponential with jitter — 3, 6, 12 seconds.

**Q:** Cap retries per webhook event?
**A:** Yes, 5 attempts then dead-letter.
...
```

***

## Open vs. choice questions

### Open

Open questions are free-text in, free-text out. They're the right pick when the answer space isn't enumerable.

```text theme={null}
Input to okto_pulse_ask_spec_question:
  board_id: "brd_abc123"
  spec_id:  "spec_XYZ"
  question: "What's the maximum acceptable end-to-end latency for the checkout submission?"

Output:
{
  "success": true,
  "qa": {
    "id":       "qa_a1b2c3",
    "question": "What's the maximum acceptable end-to-end latency for the checkout submission?",
    "asked_by": "agent_pm"
  }
}
```

### Choice — the ambiguity-killer

Choice questions force a pick from a set. They are the **preferred shape** when the answer is closed-form (yes/no, A/B/C, library X vs Y) — the agent gets a structured response instead of paraphrased prose.

```text theme={null}
Input to okto_pulse_ask_ideation_choice_question:
  board_id:        "brd_abc123"
  ideation_id:     "id_M1"
  question:        "Which diagram tool should we standardize on?"
  options:         ["Mermaid (text-based, lightweight)", "Excalidraw (rich, manual)", "draw.io (export-only)"]
  question_type:   "choice"
  allow_free_text: "false"

Output:
{
  "success": true,
  "qa": {
    "id":              "qa_d4e5f6",
    "question":        "Which diagram tool should we standardize on?",
    "question_type":   "choice",
    "choices": [
      { "id": "opt_0", "label": "Mermaid (text-based, lightweight)" },
      { "id": "opt_1", "label": "Excalidraw (rich, manual)" },
      { "id": "opt_2", "label": "draw.io (export-only)" }
    ],
    "allow_free_text": false,
    "asked_by":        "agent_lead"
  }
}
```

### Multi-value `options` parsing

Both `ask_*_choice_question` and `add_choice_comment` accept `options` in three formats. The same `selected` rules apply when answering / responding.

| Format                       | Example                                     | When                                                      |
| ---------------------------- | ------------------------------------------- | --------------------------------------------------------- |
| **JSON array** *(preferred)* | `'["Option A (with, commas)", "Option B"]'` | Always safe — labels can contain commas, pipes, anything. |
| **Pipe-separated**           | `"Option A\|Option B\|Option C"`            | Labels contain commas but no pipes.                       |
| **Comma-separated**          | `"Option A,Option B,Option C"`              | Legacy — fragile if any label contains a comma.           |

See `okto_pulse.core.mcp.helpers.parse_multi_value` for the canonical parser. The same rules govern `selected` when answering choice questions.

### Answering

`answer_*_question` takes either `answer` (open) **or** `selected` (choice) — provide the one that matches the question's `question_type`.

```text theme={null}
Input to okto_pulse_answer_ideation_question:
  board_id:    "brd_abc123"
  ideation_id: "id_M1"
  qa_id:       "qa_d4e5f6"
  selected:    "opt_0"

Output:
{
  "success": true,
  "qa": {
    "id":            "qa_d4e5f6",
    "question_type": "choice",
    "selected":      ["opt_0"],
    "answered_by":   "agent_user_proxy"
  }
}
```

For multi-select (`question_type="multi_choice"`), pass the same multi-value format used for `options`: `["opt_0", "opt_2"]`, `"opt_0|opt_2"`, or legacy comma-separated.

***

## Card comments (7 tools)

Comments are card-scoped, free-form, and mutable. Two flavors: text and choice (the latter is a richer "poll" that can collect responses from multiple agents).

### Tool reference (`server.py:2778–3164`)

| Tool                              | Line | Purpose                                                                                       |
| --------------------------------- | ---- | --------------------------------------------------------------------------------------------- |
| `okto_pulse_add_comment`          | 2778 | Add a text comment to a card.                                                                 |
| `okto_pulse_add_choice_comment`   | 2829 | Add a choice "poll" — `comment_type` ∈ `choice` / `multi_choice`, optional `allow_free_text`. |
| `okto_pulse_respond_to_choice`    | 2914 | Respond to a poll. `selected` accepts the same multi-value formats as `options`.              |
| `okto_pulse_get_choice_responses` | 2975 | Get all responses (per-responder, with optional free-text).                                   |
| `okto_pulse_list_comments`        | 3013 | List all comments on a card (text + choice, in order).                                        |
| `okto_pulse_update_comment`       | 3059 | Edit an existing comment's body.                                                              |
| `okto_pulse_delete_comment`       | 3119 | Delete a comment.                                                                             |

### Choice comment lifecycle

A choice comment is the right tool when several agents need to weigh in on the same card-level decision (sprint review polls, technique selection, prioritization). Compared to a card Q\&A, it captures **multiple distinct responses** with attribution.

```text theme={null}
Input to okto_pulse_add_choice_comment:
  board_id:        "brd_abc123"
  card_id:         "card_001"
  question:        "Pin the Stripe webhook signature library to which version?"
  options:         ["stripe-py 9.x (LTS)", "stripe-py 10.x (current)", "Custom HMAC"]
  comment_type:    "choice"
  allow_free_text: "false"

Output:
{
  "success": true,
  "comment": {
    "id":           "cmt_p1q2r3",
    "comment_type": "choice",
    "content":      "Pin the Stripe webhook signature library to which version?",
    "choices": [
      { "id": "opt_0", "label": "stripe-py 9.x (LTS)" },
      { "id": "opt_1", "label": "stripe-py 10.x (current)" },
      { "id": "opt_2", "label": "Custom HMAC" }
    ],
    "allow_free_text": false,
    "responses":       []
  }
}
```

```text theme={null}
Input to okto_pulse_respond_to_choice:
  board_id:   "brd_abc123"
  comment_id: "cmt_p1q2r3"
  selected:   "opt_0"

Output:
{
  "success": true,
  "comment": {
    "id": "cmt_p1q2r3",
    "responses": [
      { "responder_id": "agent_security", "selected": ["opt_0"], "free_text": null }
    ]
  }
}
```

```text theme={null}
Input to okto_pulse_get_choice_responses:
  board_id:   "brd_abc123"
  comment_id: "cmt_p1q2r3"

Output:
{
  "id":              "cmt_p1q2r3",
  "comment_type":    "choice",
  "question":        "Pin the Stripe webhook signature library to which version?",
  "choices":         [...],
  "allow_free_text": false,
  "responses":       [...],
  "response_count":  3
}
```

***

## Permissions

| Action                        | Permission flag                                         |
| ----------------------------- | ------------------------------------------------------- |
| Ask any Q\&A (open or choice) | `Permissions.QA_CREATE`                                 |
| Answer any Q\&A               | `Permissions.QA_ANSWER`                                 |
| Delete Q\&A on any entity     | `Permissions.QA_DELETE`                                 |
| Add comment / choice comment  | `Permissions.COMMENTS_CREATE`                           |
| Update comment                | `Permissions.COMMENTS_UPDATE`                           |
| Delete comment                | `Permissions.COMMENTS_DELETE`                           |
| List Q\&A or comments         | `Permissions.BOARD_READ`                                |
| Respond to a choice comment   | `Permissions.COMMENTS_RESPOND` (any agent in the board) |

A blocked call returns `FORBIDDEN`. Adjust the agent's preset in **Board → Agents → Edit**.

***

## Errors

```json theme={null}
{
  "error": "VALIDATION_ERROR",
  "message": "At least one option is required",
  "detail": {}
}
```

Codes that hit this domain:

| Code               | Most common cause                                                                                                                         |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `VALIDATION_ERROR` | Empty `options` on a choice question, no `selected` provided when answering, comma-only `options` string with embedded commas in a label. |
| `NOT_FOUND`        | Q\&A item / comment ID belongs to a different board, or the parent entity does not exist.                                                 |
| `FORBIDDEN`        | Agent's preset does not include the required permission flag above.                                                                       |
| `CONFLICT`         | Answering a choice question with `answer` (open text) instead of `selected`, or vice versa.                                               |

***

## Next steps

<CardGroup cols={2}>
  <Card title="Knowledge & attachments" href="/reference/mcp/knowledge-attachments">
    Reference docs and binary files attached to entities.
  </Card>

  <Card title="Architecture & mockups" href="/reference/mcp/architecture-mockups">
    Visual design artifacts across the pipeline.
  </Card>

  <Card title="MCP reference index" href="/reference/mcp">
    All 216 tools across 8 domains.
  </Card>

  <Card title="ADLC pipeline" href="/concepts/sdlc-flow">
    Where Q\&A and comments fit in the ideation → done flow.
  </Card>
</CardGroup>
