> ## 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.

# Consume the Runtime Review

> The exact contract for the Garnet PR comment — every line it emits — and how agentic reviewers like Devin and Greptile parse it as review input.

The comment is the interface. This page is its contract — every line it can emit, and how a reviewer or a merge gate reads them. Humans read the same comment [here](/run-profile).

<CardGroup cols={2}>
  <Card title="The comment contract" icon="code" href="#the-comment-contract">
    Every line the comment can emit, verbatim. Parse against this.
  </Card>

  <Card title="Agentic reviewers" icon="robot" href="#agentic-reviewers">
    Devin, Greptile, Claude Code, Cursor. Paste one prompt. No code.
  </Card>
</CardGroup>

## The comment contract

One sticky comment per pull request, updated in place, pinned to the head commit it records. These are the exact bytes of a recorded comparison comment — the second recorded commit on [demo pull request #18](https://github.com/garnet-labs/garnet-runtime-review-demo/pull/18), where a `postinstall` hook reached a host the diff never names. The same comment [rendered](/run-profile#what-changed-since-the-last-recorded-commit):

````md theme={null}
<!-- garnet-runtime-review -->
<!-- garnet-control-plane-pr-comment:v1:app.garnet.ai -->
<!-- garnet:commit 44ab6ffa8e17f3386d25ecdfcbeae2e05c35b312 -->
**Execution Profiles recorded for 1 job, triggered by [`44ab6ff`](https://github.com/garnet-labs/garnet-runtime-review-demo/commit/44ab6ffa8e17f3386d25ecdfcbeae2e05c35b312)**

> *10&nbsp;execution chains · 6&nbsp;destinations · changed since [`551aa3f`](https://github.com/garnet-labs/garnet-runtime-review-demo/commit/551aa3f0d55b074f96bbd5143c3aff0611191dde) · recorded at the kernel by Garnet · 2026-08-01 00:16:24 UTC*

<details open><summary><b>+1&nbsp;−0</b> · <code>Garnet Record (install under sensor)</code> / <a href="https://github.com/garnet-labs/garnet-runtime-review-demo/actions/runs/30675075813"><code>record</code>&nbsp;↗</a> · Install dependencies (the workload) reached 2 destinations</summary>

```diff
@@ 44ab6ff vs 551aa3f @@
  Runner.Worker
  ├─ bash
  │  └─ node
  │     ├─ dash
  │     │  └─ node
+ │     │     └─ → httpbin[.]org
  │     └─ → registry.npmjs[.]org
  └─ node
     ├─ → github[.]com
     ├─ → api.github[.]com
     └─ → release-assets.githubusercontent[.]com
```

<details><summary><sub>dns + runner substrate · 5&nbsp;chains</sub></summary>

<pre>
<em>systemd</em>
└─ <strong>hosted-compute-agent</strong>
   ├─ <em>sudo</em>
   │  └─ <strong>provjobd</strong>
   │     └─ → localhost (dns resolver)
   └─ → localhost (dns resolver)
<em>Runner.Worker</em>
├─ <strong>bash</strong>
│  └─ <strong>node</strong>
│     ├─ <strong>dash</strong>
│     │  └─ <strong>node</strong>
│     │     └─ → localhost (dns resolver)
│     └─ → localhost (dns resolver)
└─ <strong>node</strong>
   └─ → localhost (dns resolver)
</pre>

</details>

<p align="right"><sub><a href="https://app.garnet.ai/public/runs/30675075813?profile=019fbaad-dda5-71c3-a8e5-3a4cd96fea21&amp;utm_source=github&amp;utm_medium=pr_comment">View this job's Execution Profile in Garnet →</a></sub></p>

</details>

---

<details open><summary><sub>💡 How to read this</sub></summary>

<pre>
<em>Runner.Worker</em>                ← runner (italic)
└─ <strong>npm install</strong>               ← your workflow step (bold)
   └─ → registry.npmjs[.]org  ← outbound connection, defanged
</pre>

<sub><i><code>+</code> new · <code>−</code> no longer recorded, vs the previous profiled commit. A destination shows as both when its process chain changed.</i></sub>

</details>
````

### Every line the comment emits

**Markers.** Match the comment author `garnet-runtime-review[bot]` and the first marker. The second is namespaced by the posting frontend and carries the record's state. The third carries the full SHA the record covers:

```md theme={null}
<!-- garnet-runtime-review -->
<!-- garnet-control-plane-pr-comment:v1:app.garnet.ai -->
<!-- garnet:commit <full sha> -->
```

While jobs are still recording, the second marker reads `garnet-control-plane-pending-pr-comment:v1:app.garnet.ai`.

**Headline.** Bold body text, never a heading:

```md theme={null}
**Execution Profiles recorded for <N> job(s), triggered by [`<sha7>`](<commit url>)**
```

**Pending headline.** Until every job's profile has landed. The SHA is a bare code span here — the App has no commit URL yet — and gains its link when the record completes:

```md theme={null}
**Execution Profiles recording for jobs triggered by `<sha7>`**

⏳ Execution Profiles for this commit are still being recorded — this comment updates in place as jobs finish.
```

**Metadata line.** An italic blockquote, one fact per `·` segment, each count noun pluralized against its own number. The change segment renders on comparison comments only; the timestamp is omitted when the record carries none:

```md theme={null}
> *<N>&nbsp;execution chain(s) · <M>&nbsp;destination(s) · [changed|no change] since [`<prev7>`](<url>) · recorded at the kernel by Garnet · <YYYY-MM-DD HH:MM:SS> UTC*
```

**Job fold row.** The delta leads, so the left edge is the scan column. Sentence, `no change`, and counts each render only when they apply:

```html theme={null}
<b>+<A>&nbsp;−<R></b> · <code><workflow></code> / <a href="<Actions run url>"><code><job></code>&nbsp;↗</a> · <sentence> · no change <sub>· <N>&nbsp;chain(s) · <M>&nbsp;destination(s)</sub>
```

**Fold sentence.** Built only from recorded step attribution, grouped by displayed step name, at most two groups named. A job with no attributed steps carries counts instead:

```md theme={null}
<step name> reached <N> destination(s), <step name> reached <M> destination(s), and <K> more
```

**Changed job.** The tree renders as a diff fence instead of a `<pre>` block — `+` new, `−` no longer recorded, unmarked in both:

```md theme={null}
@@ <head sha7> vs <previous sha7> @@
```

**Substrate fold.** Nested inside the job fold, holding resolver chatter and unattributed runner chains. Every recorded chain renders somewhere, and each count equals what sits directly beneath it:

```html theme={null}
<details><summary><sub>dns + runner substrate · <N>&nbsp;chain(s)</sub></summary>
```

**Destination leaf.** The first recorded name, defanged at the final dot; a bare IP only when no name was recorded. Two structural tags exist — `(dns resolver)`, a loopback address on port 53, and `(instance metadata)`, one of `169.254.169.254`, `169.254.170.2`, `fd00:ec2::254`. Ports, protocol, and PIDs stay in the [Garnet Execution Summary](/quickstart#action-reference) and the JSON:

```md theme={null}
└─ → registry.npmjs[.]org
└─ → 169.254.169.254 (instance metadata)
```

**Attribution.** Carried by typography: `<strong>` is lineage attributed to a workflow step below `Runner.Worker` — the PR's own workload — and `<em>` is runner scaffolding. Attribution context, not trust.

**No egress, and truncation.** Both are stated, never silent:

```md theme={null}
<sub><workflow> / <job> — no outbound destinations recorded.</sub>
<sub>rendered <X> of <Y> destination associations</sub>
```

**Per-job permalink.** The last line of every fold. Read the `profile` parameter; ignore the campaign parameters after it:

```html theme={null}
<a href="https://app.garnet.ai/public/runs/<run-id>?profile=<profile-id>&amp;utm_source=github&amp;utm_medium=pr_comment">View this job's Execution Profile in Garnet →</a>
```

<Accordion title="Display rules that change what a name looks like">
  Three transforms apply to display only — the Execution Profile, the [Garnet Execution Summary](/quickstart#action-reference), and the JSON keep the recorded value:

  * Hostnames are defanged at the final dot: `registry.npmjs.org` renders as `registry.npmjs[.]org`.
  * Step names lose the runner's ordinal prefix and any unexpanded workflow expression: `4. Run workload ${{ matrix.name }}` renders as `Run workload`. The comment never shows an ordinal.
  * Process names lose a trailing run of four or more digits: `provjobd1326539233` renders as `provjobd`.
</Accordion>

<Warning>
  Fail closed on three states: **no marked comment** (recording never ran), **pending headline** (wait, don't fail), **`garnet:commit` ≠ head SHA** (stale record). In all three there is no runtime evidence for the current head — fall back to your normal policy. The comment carries recorded facts and no verdict; the decision is yours.
</Warning>

## Agentic reviewers

Paste one prompt — the reviewer finds the comment, checks the pin, and correlates the diff with what actually ran.

<Tabs>
  <Tab title="Per-review prompt">
    Paste into the reviewer's instructions, alongside the PR URL:

    ````md theme={null}
    # Review this pull request against its kernel-recorded execution record

    ## Locate the record

    1. On the PR, find the comment containing the marker `<!-- garnet-runtime-review -->`.
       It is a kernel-recorded record of what this PR's CI executed: every recorded
       execution chain and every outbound destination, per job.
    2. Confirm it covers the current head: the marker `<!-- garnet:commit <sha> -->`
       must equal the PR's head SHA. If the comment is missing, still recording
       (headline reads "Execution Profiles recording for jobs"), or pinned to an
       older commit, report "no execution record for the current head" and stop
       treating the run as verified. Absence of evidence is not a clean run.

    ## Read the record

    3. The metadata blockquote carries the run-scope facts: execution chains,
       destinations, whether anything changed since the previous profiled commit,
       and when it was recorded.
    4. Each job fold carries its own facts: a leading `+A −R` delta when the job
       changed, a sentence naming which steps reached how many destinations, and
       the tree itself. Inside a changed job, the diff fence marks `+` new and
       `−` no longer recorded against the previous profiled commit.
    5. In the tree, bold lineage is the PR's own workload (attributed to a workflow
       step), italic lineage is runner scaffolding, and `→ name` leaves are outbound
       destinations with the final dot defanged. The nested "dns + runner substrate"
       fold holds resolver chatter and unattributed runner chains.

    ## Correlate and report

    6. For every workload destination and spawned process, state whether the diff
       explains it (a dependency change explains registry traffic and an install
       chain). Name what the diff does not explain: unexpected hosts, install-script
       activity, interpreters that have no reason to be in the chain.
    7. On a comparison comment, review the delta first: what this commit added or
       stopped doing at runtime, and whether the diff accounts for it.
    8. The record covers the current head only. Say so if the PR has earlier pushes.

    Emit exactly this shape:

    ```md
    <!-- runtime-execution-review:v1 -->
    **Execution review of `<workflow> / <job>`, recorded at [`<sha7>`](<commit url>)**

    > *<N> execution chains · <M> destinations · <changed | no change> since `<prev7>`*

    <2–4 sentences: which steps ran, which destinations they reached, and what
    the delta was. Recorded facts only.>

    | Destination | Chain | Explained by |
    | :--- | :--- | :--- |
    | <destination, as rendered> | <chain, as rendered> | <diff hunk, manifest, or workflow line — or "nothing in the diff"> |

    **Unexplained:** <one line per unexplained destination or process, each citing
    its chain — or "none".>

    **Recommendation:** <merge | hold>, the evidence it rests on, and what a
    re-run should record.

    <sub>Grounding: [Execution Profile](<permalink>), recorded at the kernel,
    pinned to `<sha7>` · correlation sources: <PR diff, workflow yml, manifests></sub>
    ```

    Rules that keep the shape deterministic:
    - Every row and every claim cites the record or the code. No citation, no finding.
    - Chains and destinations are copied from the comment. Never invent a process or
      a destination, and never repair a defanged name into a live link.
    - Counts you quote must equal the counts the comment renders.
    - If the record is missing, pending, or stale, keep the shape, state that reason
      in place of the facts, and recommend against treating the run as verified.
    - The record carries no verdict. The judgment is yours, and it traces to the
      record or the diff.
    ````
  </Tab>

  <Tab title="Repo rules (AGENTS.md)">
    The same contract as standing repo rules — for reviewers that read `AGENTS.md`, `CLAUDE.md`, `.cursorrules`, or a custom-instructions field. Add once; every review follows it:

    ```md theme={null}
    # Execution record (Garnet) — reviewer instructions

    Before finalizing any review of a pull request in this repository:

    1. Find the PR comment containing the marker `<!-- garnet-runtime-review -->`.
       It is the kernel-recorded record of what this PR's CI executed: every
       recorded execution chain and every outbound destination, per job.
    2. Verify it covers the head: `<!-- garnet:commit <sha> -->` must equal the PR's
       head SHA. If it doesn't, or the comment is missing or still recording, treat
       the PR as having **no execution record** and say so. That is not a clean run.
    3. Read the metadata blockquote for run-scope facts, then each job fold: the
       `+A −R` delta, the sentence naming steps and destination counts, and the tree.
       Bold lineage is the workload, italic is runner scaffolding, `→ name` leaves
       are destinations.
    4. Cross-check the diff. Name every destination and process the diff does not
       explain, citing its chain, or state that the record is fully explained.
    5. Report: what ran, the delta since the previous profiled commit, a
       Destination | Chain | Explained by table, the unexplained set, and a merge or
       hold recommendation. The record carries no verdict — you supply the judgment,
       and never invent a chain or destination.
    ```
  </Tab>
</Tabs>

Two demo pull requests carry the same manifest-only diff and different recorded egress — useful for checking that a reviewer reads the record rather than the diff: [registry-only egress](https://github.com/garnet-labs/garnet-runtime-review-demo/pull/1) and [an install script reaching named hosts](https://github.com/garnet-labs/garnet-runtime-review-demo/pull/8).

## Custom harnesses and gates

For a reproducible decision instead of a judgment, parse the comment directly. **StampHog** — [PostHog's merge-gate agent](https://github.com/PostHog/posthog/blob/master/.github/workflows/pr-approval-agent.yml) — does exactly that in the demo repository: every static gate green, held solely on recorded egress the diff never mentions.

<CardGroup cols={2}>
  <Card title="The working consumer" icon="github" href="https://github.com/garnet-labs/garnet-runtime-review-demo/blob/main/tools/pr-approval-agent/garnet_runtime.py">
    `garnet_runtime.py` — locates the comment, checks the pin, extracts destinations, splits by attribution. Start here, not from scratch.
  </Card>

  <Card title="The harness on a pull request" icon="shield-check" href="https://github.com/garnet-labs/garnet-runtime-review-demo/pull/8">
    The harness consuming the record end to end, posting its own decision next to Garnet's. The same harness on a [replayed upstream change](https://github.com/garnet-labs/posthog/pull/44).
  </Card>
</CardGroup>

<Note>
  Harness already locks its own output shape and gates? Keep it — carry the primitive into it instead: (1) fail closed on the three evidence states above, (2) gate on the comment's own `+A −R` delta against the previous profiled commit, (3) make every finding cite its recorded chain and destination.
</Note>

<Accordion title="Structured data — the JSON twin">
  Every fold's permalink has a JSON twin at the same exact selector:

  ```text theme={null}
  https://app.garnet.ai/api/public/runs/<run-id>?profile=<profile-id>
  ```

  The selector is required. Wrong or missing `?profile=`, or a bare `/public/runs/<run-id>` URL, returns a 404 by design — never a silent fallback. See [The public run report](/run-profile#the-public-run-report).
</Accordion>
