> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.pensar.dev/apex/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.pensar.dev/apex/_mcp/server.

# pensar issues

> List, view, update, retest, comment on, and link pull requests to security issues via the Pensar Console API

## Overview

The `pensar issues` command lets you manage security issues discovered by pentests. You can list issues with filters, view detailed information, update issue statuses, queue retests, and link the pull requests that fix them.

All commands operate on the **selected workspace**, which is chosen when you connect with [`pensar login`](/apex/cli-commands/pensar-login). There is no longer a project argument.

## Usage

```bash
pensar issues [filters]                        # List issues in the workspace (alias: pensar issues list)
pensar issues get <issueId>                    # Get issue details
pensar issues update <issueId> [options]       # Update an issue
pensar issues retest <issueId>                 # Queue an issue retest
pensar issues link-pr <issueId> --url <url>    # Link a pull request to an issue
pensar issues prs <issueId>                    # List pull requests linked to an issue
pensar issues comments <issueId>               # List review comments on an issue
pensar issues comment <issueId> --body "..."   # Post a comment on an issue
```

> **Note**
>
> `<issueId>` accepts either the issue UUID or its label — e.g. `VULN-000123`.

## Prerequisites

You must be connected to Pensar Console via [`pensar login`](/apex/cli-commands/pensar-login) before using this command.

## Subcommands

### List Issues

```bash
pensar issues [filters]
```

Lists security issues in the selected workspace. Returns a JSON array. Use filters to narrow the results.

Each entry carries both identifiers plus a direct link:

```json
{
  "id": "11111111-2222-3333-4444-555555555555",
  "issueLabel": "VULN-000123",
  "title": "SQL Injection in login handler",
  "severity": "critical",
  "status": "open",
  "location": "src/auth/login.ts",
  "url": "https://console.pensar.dev/acme/VULN-000123"
}
```

`issueLabel` is the human-facing reference (`null` only for issues predating
labels) and `url` opens the issue directly. Either identifier can be passed
back to any command taking an `<issueId>`.

| Filter              | Description                                                |
| ------------------- | ---------------------------------------------------------- |
| `--status <status>` | Filter by: `open`, `closed`, `false-positive`, `in-review` |
| `--severity <sev>`  | Filter by: `critical`, `high`, `medium`, `low`             |
| `--scan <scanId>`   | Filter by scan (pentest) ID                                |
| `--branch <branch>` | Filter by branch                                           |

### Get Issue Details

```bash
pensar issues get <issueId>
```

Returns detailed information about a specific issue, including vulnerability description, reproduction steps, and severity. The response carries the same `issueLabel` and `url` as the list shape, plus description, line range, CWE, branch, and proof-of-concept.

A reference that is neither a UUID nor a `VULN-…` label is rejected with a 400; a well-formed reference that matches no issue returns a 404.

### Update an Issue

```bash
pensar issues update <issueId> [options]
```

| Option                     | Description                                                                                                       |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `--status <status>`        | New status                                                                                                        |
| `--disposition <value>`    | Why the issue is closed: `resolved`, `duplicate`, `wont-fix`, `out-of-scope`, `risk-accepted`                     |
| `--duplicate-of <issueId>` | The issue this one duplicates, by UUID or label. Required with `--disposition duplicate`, rejected with any other |
| `--closed-reason <reason>` | Reason for closing                                                                                                |
| `--closed-comments <text>` | Additional comments when closing                                                                                  |
| `--false-positive`         | Flag the issue as a false positive                                                                                |
| `--fp-reason <reason>`     | Reason for the false positive flag                                                                                |

`--disposition` records *why* an issue is closed as a structured value, so it can
be filtered and counted. Without it a close reads as a plain resolution whatever
the reason was. The five values above are the full accepted set.

A `duplicate` close links to the original issue, which must be in the same
workspace, must not be the issue itself, and must not itself be closed as a
duplicate. Issue responses carry the link as `duplicateOf`, the original's UUID
(`null` otherwise).

### Retest an Issue

```bash
pensar issues retest <issueId>
```

Queues an asynchronous retest of the issue against its original target. The JSON response includes the agent session ID for the queued run.

### Link a Pull Request

```bash
pensar issues link-pr <issueId> --url <prUrl>
```

Links a pull request to the issue. `--url` is required.

| Option        | Description                                    |
| ------------- | ---------------------------------------------- |
| `--url <url>` | URL of the pull request to link (**required**) |

Returns `{ success, created, pullRequest, issue }`. `created` distinguishes a newly linked PR from one that was already attached, so re-running the command is safe.

### List Linked Pull Requests

```bash
pensar issues prs <issueId>
```

Returns the pull requests linked to the issue as an array of `{ id, url, status, createMethod, createdAt }`. `createMethod` tells you whether the link came from an agent or from a person.

### List Comments

```bash
pensar issues comments <issueId> [--page <n>] [--page-size <n>]
```

Returns the issue's review thread, **oldest first** — the running conversation
between reviewers about a finding, which is where a corrected CVSS score or the
argument for a dismissal usually lives.

```json
{
  "comments": [
    {
      "id": "66666666-7777-8888-9999-000000000000",
      "issueId": "11111111-2222-3333-4444-555555555555",
      "body": "Rescored this to 7.1 — the endpoint needs an authenticated session.",
      "author": {
        "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
        "name": "Ada Lovelace",
        "email": "ada@example.com",
        "type": "user"
      },
      "createdAt": "2026-08-14T10:22:31.000Z",
      "editedAt": null,
      "url": "https://console.pensar.dev/acme/VULN-000123#comment-66666666-7777-8888-9999-000000000000"
    }
  ],
  "pagination": { "page": 1, "pageSize": 50, "totalRows": 1, "totalPages": 1 }
}
```

`author` is `null` when the person who wrote the comment no longer has an
account. `editedAt` is `null` until the comment is edited. Mentions stay inline
in `body` as `@first.last` — there is no separate mentions field.

Default page size is 50; the maximum is 200.

### Post a Comment

```bash
pensar issues comment <issueId> --body "<text>"
```

Adds a comment to the issue's thread and returns the created comment in the
shape above. Mentions written as `@first.last` notify that person, exactly as
they do from the Console.

> **Note**
>
> Posting requires a **user login** (`pensar login`). A workspace API key is
> accepted for reading comments but rejected for posting, because it has no
> author to attribute the comment to.

## Examples

```bash
# List all open critical issues in the workspace
pensar issues --status open --severity critical

# Get details for a specific issue
pensar issues get VULN-000123

# Close an issue with a reason
pensar issues update VULN-000123 --status closed --disposition resolved --closed-reason "Patched in v2.1"

# Close an issue as a duplicate of another
pensar issues update VULN-000124 --status closed --disposition duplicate --duplicate-of VULN-000123

# Flag as false positive
pensar issues update VULN-000123 --false-positive --fp-reason "Test environment only"

# Retest an issue after deploying a fix
pensar issues retest VULN-000123

# Reference an issue by its label instead of its UUID
pensar issues get VULN-000123

# Link the PR that fixes an issue, then confirm the link
pensar issues link-pr VULN-000123 --url https://github.com/acme/api/pull/42
pensar issues prs VULN-000123

# Read the review thread on a finding, then reply to it
pensar issues comments VULN-000123
pensar issues comment VULN-000123 --body "Confirmed exploitable, rescored to 7.1"
```

## Related Commands

#### [pensar fixes](/apex/cli-commands/pensar-fixes)

View suggested fixes for an issue

#### [pensar logs](/apex/cli-commands/pensar-logs)

View agent execution logs for an issue