Skip to main content
Garnet records the supported Linux runner of each job where you configured the action. What that job executes there is recorded at the kernel: the execution chains from the runner’s root process to the action each performed, and the destination each outbound connection reached. Recording starts when the sensor starts, so steps above the Garnet step are not in it. The comment only knows jobs that registered a sensor. A registered job that failed to record gets a fold saying so. A job without the step, or on an unsupported runner, never registers and has no fold. That absence is not coverage of the job, and it does not mean “empty”.

Runners

GitHub-hosted Linux is ubuntu-latest, ubuntu-24.04 and ubuntu-22.04. This is the tested path. Self-hosted Linux x86_64 works on the same terms, including managed providers such as Blacksmith and the Intel labels on Depot. Remote executors run your work on their own machines: Nx Cloud agents, Turborepo or Vercel remote execution, Bazel RBE. Garnet records what the runner did, including the chains and the destinations that reach the executor. macOS, Windows and arm64 runners: the step logs a warning and skips; nothing is recorded there. Linux runners without systemd or sudo: the step warns and the job continues unrecorded.

Requirements

Linux x86_64, systemd, and sudo. The sensor is an eBPF binary built for amd64, installed as a systemd unit, so the step needs sudo to install it and start it. Where a requirement is missing the step skips and your workflow continues. Errors the action catches are logged as warnings rather than failing the job.

Coverage is per job

One Garnet step records one job. Jobs without the step produce no Execution Profile, and the PR comment carries a fold only for the jobs that have one. Add the step first in every job you want recorded. Anything that ran before the sensor started is not in the record. A matrix job is one job per cell, and each cell needs the step to be recorded. A step guarded with if: on the matrix records only the cells that pass the guard: a matrix that spans Node 20, 22 and 24 on Ubuntu, macOS and Windows, with the step guarded to Node 24 on Linux, records that one cell and none of the others. The pull request comment carries one fold for it and says nothing about the rest.

Step names

Step attribution is best effort. Each execution chain carries the workflow step that was running when its first process started, correlated from process start times and the runner’s step boundaries, so some chains land under the wrong step or under (step: "<unknown>"). One known cause: Jibril numbers run: steps in file order, while GitHub numbers only the run: steps without an id:. In a job where a run: step declares an id:, that step records as <unknown>. Every later run: step without an id: is labelled one step early. Chains, destinations and job totals are unaffected. Read step labels inside a chain as approximate: a missing or <unknown> step is an attribution gap, not evidence that the step ran nothing and not background activity.

Limits of the record

Read an Execution Profile for what it is: what Garnet recorded, not a statement that nothing else happened.
  • No completeness claim. The record states what was captured; it does not declare that every connection was captured. Activity that starts and finishes before the sensor is up, or between the sensor’s reporting intervals, can be missing from it.
  • Merge commit, not PR head. On pull_request runs GitHub checks out the synthetic merge commit. The action reports your PR head SHA to Garnet, but the comment headline and the public run report currently label the run by the commit the workflow ran on — the merge commit. Aligning them to the PR head is tracked in the control plane.
  • Matrix jobs. Jobs that share a name across a matrix can be aggregated under one fold and undercount destinations.
  • Step labels are approximate. See Step names above.
  • The post step adds time. Stopping the sensor waits for it to flush its Execution Profile, bounded by stop_timeout_seconds. On busy jobs this has been observed at 1–3 minutes (about 150 s on pnpm’s test job); lower the bound if post-step latency matters more than a complete flush.
  • Comparison needs a recorded pair. The diff view appears only when the previous recorded commit on the pull request has a profile for the same job; otherwise the fold shows the current record alone.

Fork pull requests

GitHub does not expose repository secrets or id-token: write to a workflow triggered from a fork, so the action has no credential there. It warns, names the missing credential in the job summary, skips recording, and the job continues. This is fail-open: an unrecorded job is not a failed job, and the pull request comment carries no fold for it. Read the absence as setup incomplete for that run, never as a job that reached nothing. Installing the GitHub App does not change this; the credentials the runner lacks are the workflow’s, not the App’s. Next: Quick start · The Execution Profile