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

# The Run Profile

> The record every run produces, and how to read it on your PR.

Every monitored run produces exactly one **Run Profile**: process lineage, network egress, file access, and check results, tied to the commit, actor, and workflow that produced it. It's run-bounded — one run in, one record out — not a firehose.

The Run Profile is what Garnet posts back to your PR. It's the second pass on the change you already reviewed.

<Frame>
  <img src="https://mintcdn.com/garnetlabs/Pn5vIXleTy7UTwfp/images/v1-runs-page.png?fit=max&auto=format&n=Pn5vIXleTy7UTwfp&q=85&s=caabb329aa7440a5bc43c5f3ffe42691" alt="Run Profiles feed in the Garnet dashboard" width="3298" height="1880" data-path="images/v1-runs-page.png" />
</Frame>

## Where it shows up

The same Run Profile surfaces in a few places, driven by one record:

* **PR comment** — automatic on every run, the primary surface. Requires `pull-requests: write` in the workflow. Garnet posts a single comment and updates it in place.
* **Run Profile summary** — automatic in the GitHub Actions run (the Job Summary): check results, egress, and a link to the full profile.
* **Dashboard** — the full interactive profile at [app.garnet.ai](https://app.garnet.ai): process tree, egress, and file access.
* **Slack / webhooks** — optional. Configure under **Settings → Alerting**; see [Outputs & integrations](/reference/github-actions#outputs--integrations).

<Frame>
  <img src="https://mintcdn.com/garnetlabs/PBqV-VIs8oN1XxiL/images/v1-github-summary-fail.png?fit=max&auto=format&n=PBqV-VIs8oN1XxiL&q=85&s=57f60fea8d2f6b88d02042cff7ad6c85" alt="A Run Profile summary in the GitHub Actions run, showing a failed check" style={{maxWidth: "540px"}} width="2384" height="2702" data-path="images/v1-github-summary-fail.png" />
</Frame>

## Reading the comment

The comment presents the Run Profile in the order that matters most.

<Steps>
  <Step title="Summary line — the state" icon="signal">
    A headline [state](#the-state-ladder) — **Clean** or **Needs review** — summarizing the run. A clean PR shows a receipt; states are observed facts, not alarms.
  </Step>

  <Step title="Egress — review-first" icon="globe">
    Outbound connections, the one that needs review (or any first-seen domain) first, each attributed to the process that made it. This is where most of what matters shows up: an unexpected connection the diff never revealed.
  </Step>

  <Step title="Process lineage" icon="diagram-project">
    The tree from init to leaf, with the connection that needs review highlighted. It names the exact step that did the thing.
  </Step>

  <Step title="File activity" icon="file">
    What was read or written, and by which process.
  </Step>
</Steps>

The comment posts as **Pending** the moment a run starts, then fills in as the profile arrives — usually within seconds.

### What the comment looks like

A clean run reads as a short receipt:

```
✅  Garnet · Run Profile — Clean

Checks   3 passed
Egress   api.github.com · registry.npmjs.org · objects.githubusercontent.com
Files    no unexpected writes

View the full Run Profile → app.garnet.ai/runs/…
```

A run that needs review leads with the evidence — the connection to look at, and the exact process that made it:

```
⚠️  Garnet · Run Profile — Needs review

Checks   2 passed · 1 needs review  (no_known_bad_egress)

Egress
  ▸ scan.aquasecurtiy[.]org        on Garnet's known-bad list
      curl · systemd → bash → entrypoint.sh → curl
    api.github.com
    registry.npmjs.org

View the full Run Profile → app.garnet.ai/runs/…
```

The comment updates in place — one comment per PR, not a new one each push.

## The state ladder

Every resolved Run Profile reads as one of three states. The state is an interpretation of the [checks](/reference/checks); a failed check is an objective invariant violation with evidence, not a scary "detection."

| State            | Chip   | When                                                                                      | Reads as                                                                                   |
| :--------------- | :----- | :---------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------- |
| **Clean**        | `pass` | Every check passed                                                                        | The receipt — merge. A clean run may still note an observation worth a glance (see below). |
| **Needs review** | `fail` | A check needs a human look — a known-bad domain, a `/proc` memory read, a drop-and-delete | Evidence to read before you merge: the exact process, domain, and lineage.                 |

While the run is still profiling, the comment shows **Pending** and updates in place when it resolves.

**Clean** — the common case. The comment is a short receipt: checks passed, here's the egress, here's the tree. A clean run may still surface an **observation** — a first-seen outbound domain, say — called out for awareness. Nothing failed; you decide whether it's expected. It stays Clean.

**Needs review** — a check needs a human look. The comment leads with the evidence: the process, the domain, the ancestry chain, and the timestamp. Follow the lineage to the exact step.

<Note>
  The Garnet Action **does not fail your job** by default — a failed check is reported, not enforced. To gate a merge on it yourself, use the `profile_result` output as an [opt-in recipe](/reference/github-actions#gate-a-merge-optional).
</Note>

## Run details in the dashboard

Open any run at [app.garnet.ai](https://app.garnet.ai) for the full profile.

### Clean run

<Frame>
  <img src="https://mintcdn.com/garnetlabs/U7EU-ovjmboKKnJx/images/v1-run-details-ok.png?fit=max&auto=format&n=U7EU-ovjmboKKnJx&q=85&s=cd8878e5b2f90e922d83d405e6fcc707" alt="A clean run with process tree and passing checks" width="3312" height="2068" data-path="images/v1-run-details-ok.png" />
</Frame>

* **Process tree** — full chain with connections inline
* **Overview / JSON** — structured or raw data
* **Checks** — green when every check passed
* **Run context** — workflow, repo, branch, SHA, actor, agent

### Needs-review run

<Frame>
  <img src="https://mintcdn.com/garnetlabs/xu71ouaM8L4tf9sJ/images/v1-run-details-fail.png?fit=max&auto=format&n=xu71ouaM8L4tf9sJ&q=85&s=01ed7ccbee909318794f10074fc6db25" alt="A run that needs review, with the outbound connection to inspect highlighted" width="3308" height="2556" data-path="images/v1-run-details-fail.png" />
</Frame>

* **Highlighted connection** — the outbound destination to inspect, marked in the tree
* **Needs-review check** — the matched domain with full process ancestry
* Same context metadata as a clean run

## Sharing

Every Run Profile has a permanent link on [app.garnet.ai](https://app.garnet.ai). Drop it in a PR thread or an incident channel to point teammates at the exact run, process tree, and evidence.
