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

# Recommendations

> Review AI-generated fix recommendations, push them to your issue tracker, mark them implemented, and prove the fix held with the 90-day attestation window.

A **recommendation** is a concrete fix for a recurring pattern, either drafted by AI (`POST /v1/ai/recommend/{pattern_id}`) or created by hand. Every recommendation requires a `fix_class` (`structural`, `compensating`, or `patch`) and a `pattern_id`. Recommendations close the loop: Causeloop not only tells you what is broken and why, it tells you what to do — and then tracks whether the fix held.

Recommendations are generated automatically when a pattern reaches sufficient confidence, and are ranked (`rank = f(roi_pct, urgency(T̂_R), effort)`, a deterministic formula from the hazard config). The `business_case` behind the ranking — `ale_avoided`, `roi_pct`, and the counterfactual it's coupled to — is always computed by Causeloop from the pattern's fitted hazard and financials; it is never accepted as free-form client input.

## The Recommendations list

Navigate to **Recommendations** in the left sidebar to open the ranked list.

### Summary header

Three KPI tiles appear at the top:

| Tile                   | Description                                                                                                                                                 |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Open**               | Recommendations in `pending` or `in_progress` status                                                                                                        |
| **Loops preventable**  | Sum of `expected_loops_prevented` across open recommendations                                                                                               |
| **Exposure addressed** | Sum of `ale_avoided` across open recommendations — computed per-pattern from the fishbone rate-card and hazard counterfactual, not a flat per-loop constant |

### Ranked rows

Each row shows:

* **Rank** — deterministic ranking (`rank = f(roi_pct, urgency(T̂_R), effort)`; rank 1 = highest priority)
* **Title** — the recommended action
* **Type chip** — `code_fix`, `config`, `process`, or `monitoring`
* **Fix class chip** — `structural`, `compensating`, or `patch`
* **Impact pill** — `high`, `medium`, or `quick_win`
* **Effort chip** — `EFFORT LOW`, `EFFORT MED`, or `EFFORT HIGH`
* **Status pill** — `pending`, `in progress`, `implemented`, or `dismissed`
* **Expected loops prevented** — computed from `ale_avoided` and the counterfactual, not a free-text AI estimate

### Filtering and sorting

Use the filter bar to narrow by:

| Parameter   | Options                                                                              |
| ----------- | ------------------------------------------------------------------------------------ |
| `type`      | `code_fix`, `config_change`, `process`, `monitoring`                                 |
| `fix_class` | `structural`, `compensating`, `patch`                                                |
| `status`    | `pending`, `in_progress`, `implemented`, `dismissed` (comma-separate for OR)         |
| `impact`    | `high`, `medium`, `quick_win`                                                        |
| `sort`      | `rank` (default), `-rank`, `-created_at`, `-expected_loops_prevented`, `-updated_at` |

## Recommendation detail

Click any row to open the recommendation detail page at `/recommendations/{id}`.

### Header

The header shows:

* **Eyebrow** — `RANK #{n} · {type} · CREATED {date}`
* **Title** — the full recommendation title
* **Impact pill** and **status pill**
* **Pattern chip** — the source pattern this recommendation addresses

Top-bar actions: **Push to tracker**, **Mark implemented**.

### Overview (left column)

The **Overview** card contains a plain-language summary of what the fix does and why it prevents the loop from recurring.

### Implementation plan (left column)

Below the overview, the **Implementation plan** card lists the AI-generated steps needed to apply the fix. Each step has a title, a description, and a completion checkbox. As you complete steps, check them off — the progress is saved per step.

### Source pattern (right rail)

The **Source pattern** rail card shows the pattern this recommendation was generated from: name, pattern ID, issue count, and risk score. Click **Open pattern →** to navigate to the [pattern detail page](/product-guide/patterns).

### Addresses N issues (right rail)

This card lists the specific issues that this recommendation, once applied, will address. Each row shows the external ID and a risk score.

### On implementation (right rail)

A note card explains what happens after you mark this recommendation implemented:

> The pattern enters its 90-day hold window. If no recurrence, status flips to **Held** and a regulator-ready attestation is generated.

## Acting on a recommendation

### Pushing to your issue tracker

Before starting implementation, queue the recommendation for delivery to your team's issue tracker.

<Steps>
  <Step title="Open the recommendation detail">
    Navigate to the recommendation you want to act on.
  </Step>

  <Step title="Click Push to tracker">
    A dialog appears with fields for the target tracker and project key.
  </Step>

  <Step title="Choose your tracker and project">
    Supported trackers: **Jira**, **Linear**, **GitHub**, **ServiceNow**. Enter the project key (e.g. `ENG`).
  </Step>

  <Step title="Confirm">
    The push is queued against the connected tracker connector.
  </Step>
</Steps>

The push is handled by `POST /v1/recommendations/{id}/push`.

<Warning>
  Causeloop does not yet create a real ticket in the external tracker — there is no tracker connector call wired up to produce a real ticket number or URL. A successful push returns `{"queued": true, "external_ref": null, ...}`, and the recommendation's tracker reference carries `external_id: null` / `external_url: null`. This is intentional: Causeloop never fabricates a ticket ID or URL it did not actually receive from the tracker. If the workspace has **no connected connector of the requested tracker type**, the push fails outright with `409 tracker_not_connected` instead of silently queuing against nothing — connect a tracker connector under Settings → Connectors first.
</Warning>

### Marking implemented

Once you have applied the fix, mark the recommendation as implemented.

<Steps>
  <Step title="Click Mark implemented">
    The button is in the top bar of the recommendation detail page.
  </Step>

  <Step title="Confirm">
    The recommendation status changes to `implemented`. The linked pattern enters the 90-day hold window immediately.
  </Step>
</Steps>

You can also use `PATCH /v1/recommendations/{id}` with `status: "implemented"`. The `analyst` role is required.

### Attesting the fix held

After 90 days without recurrence, the pattern's `attestation_ready` flag is set to `true`. At that point you can formally attest that the fix held.

<Steps>
  <Step title="Navigate to the recommendation detail">
    The detail page shows an attestation prompt when `attestation_ready` is true.
  </Step>

  <Step title="Click Attest">
    Enter attestation notes and optional evidence URLs (links to PRs, run logs, or audit records).
  </Step>

  <Step title="Submit">
    An attestation record is created with `attested_by`, `attested_at`, `notes`, and `evidence_urls`. This record is available for audit and compliance exports.
  </Step>
</Steps>

The attestation is stored via `POST /v1/recommendations/{id}/attest`. Retrieve the attestation record at any time with `GET /v1/recommendations/{id}/attestation`.

Attesting also starts statistical monitoring, not just the 90-day clock. `GET /v1/recommendations/{id}/verification` returns the live state (`monitoring`, `verified`, `failed`, or `not_started`), the CUSUM statistic and its trajectory against the target intensity reduction (taken from the hazard counterfactual), and the expected decision window. An admin can force-close monitoring with `POST /v1/recommendations/{id}/verification/close`. When the fix is verified or fails, the `fix.verified` / `fix.failed` event updates the theme's persistence term (`Sh`) for the next engine run and fires notifications — this is the product's proof-of-value artifact.

<Note>
  Attesting a dismissed recommendation requires you to re-open it first (move status back to `pending` or `in_progress`).
</Note>

### Proof-window verification

The **Remediation view** shows every recommendation currently in — or that has completed — a proof-window verification lifecycle across the workspace, so you don't have to open each recommendation one at a time.

`GET /v1/recommendations/verifications` returns:

```json theme={null}
{
  "data": [
    {
      "rec_id": "rec_01hx...",
      "title": "Add idempotency key to payment webhook handler",
      "pattern_id": "pat_01hx...",
      "pattern_name": "Duplicate payment webhook processing",
      "fix_class": "structural",
      "status": "in_window",
      "window": { "total_days": 90, "elapsed_days": 12.4, "started_at": "2026-06-20T14:03:00Z" },
      "progress_pct": 13.8,
      "live_metric": { "current": -1.2, "decision_boundary": 4.0, "cusum_pos": 0.0, "cusum_neg": 1.2, "trajectory": [] },
      "reopened": false,
      "closed_at": null,
      "outcome": null
    }
  ],
  "summary": { "in_window": 4, "holding": 1, "reopened": 0, "verified": 9 }
}
```

`status` is one of four lifecycle buckets, all derived from stored fields — never wall-clock guesses:

| Status      | Meaning                                                                                             |
| ----------- | --------------------------------------------------------------------------------------------------- |
| `in_window` | Monitoring, within its expected decision window                                                     |
| `holding`   | Still monitoring, but past the upper bound of its expected decision window — overdue for a decision |
| `reopened`  | The CUSUM statistic crossed its negative boundary — the fix did not hold                            |
| `verified`  | The CUSUM statistic crossed its positive boundary — the fix held                                    |

`GET /v1/recommendations` also embeds a light `verification` summary (`{status, progress_pct, reopened}` or `null`) on each row, so the list view can show fix-plan state without an extra call per recommendation.

### Dismissing a recommendation

If a recommendation is not applicable to your context, dismiss it with a reason:

```json theme={null}
PATCH /v1/recommendations/{id}
{
  "status": "dismissed",
  "dismissal_reason": "Third-party service handles this — not in scope."
}
```

`dismissal_reason` is required when setting status to `dismissed`.

## Status transitions

| From          | Allowed transitions                   |
| ------------- | ------------------------------------- |
| `pending`     | `in_progress`, `dismissed`            |
| `in_progress` | `implemented`, `pending`, `dismissed` |
| `implemented` | — (terminal; use attestation flow)    |
| `dismissed`   | `pending`                             |

## API reference

| Endpoint                                           | Description                                                                                                                                                |
| -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /v1/recommendations`                          | List recommendations with filters (default `sort=rank`); each row embeds a light `verification` summary                                                    |
| `POST /v1/recommendations`                         | Create a recommendation — requires `fix_class` + `pattern_id`; `business_case` is always computed, never client-supplied                                   |
| `GET /v1/recommendations/{id}`                     | Get recommendation detail                                                                                                                                  |
| `PATCH /v1/recommendations/{id}`                   | Update status, impact, or dismiss                                                                                                                          |
| `POST /v1/recommendations/{id}/push`               | Queue a push to an issue tracker — `409 tracker_not_connected` if none is connected; otherwise `{queued: true, external_ref: null}` (no fabricated ticket) |
| `GET /v1/recommendations/{id}/plan`                | Get the structured implementation plan                                                                                                                     |
| `POST /v1/recommendations/{id}/attest`             | Attest that the fix held (also starts verification monitoring)                                                                                             |
| `GET /v1/recommendations/{id}/attestation`         | Retrieve the attestation record                                                                                                                            |
| `GET /v1/recommendations/{id}/verification`        | Live verification state, CUSUM statistic, and decision window                                                                                              |
| `POST /v1/recommendations/{id}/verification/close` | Admin override to close monitoring                                                                                                                         |
| `GET /v1/recommendations/verifications`            | Remediation view — every verification lifecycle in the workspace, flat list + summary counts                                                               |
| `GET /v1/recommendations/stats`                    | Aggregate stats, derived from business cases (no flat per-loop constant)                                                                                   |

## Related pages

<CardGroup cols={2}>
  <Card title="Patterns" icon="diagram-project" href="/product-guide/patterns">
    See the pattern a recommendation is addressing.
  </Card>

  <Card title="Predictions" icon="chart-line" href="/product-guide/predictions">
    Understand the recurrence risk driving each recommendation.
  </Card>

  <Card title="Issues" icon="circle-exclamation" href="/product-guide/issues">
    See the issues a recommendation addresses.
  </Card>

  <Card title="Reports" icon="file-lines" href="/product-guide/reports">
    Include recommendation coverage in an executive report.
  </Card>
</CardGroup>
