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

# Git and Immutable Experiment Refs

> How Onyx uses git commits and refs as the durable research record.

Onyx treats git as the canonical code record.

## Campaigns Are Logical

Campaigns do not map to a shared mutable git branch. They are logical research
tracks in Onyx. Each measured attempt writes its own immutable result ref:

```text theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
refs/onyx/experiments/<campaignId>/<runRef>
```

When you start with `/onyx ...`, the orchestrator chooses a slug from the goal
and creates or resumes the matching campaign. You can also use
`onyx campaign setup` manually when debugging or scripting.

## Result Refs

Local workers push result commits with:

```bash theme={"theme":{"light":"github-dark-dimmed","dark":"github-dark-dimmed"}}
git push origin HEAD:refs/onyx/experiments/<campaignId>/<runRef>
```

Hosted workers can push directly or use GitHub's Git Database APIs. Optional
promotion refs such as `refs/heads/onyx/<campaign>/best` may move, but those
are curated outputs, not the research history.

## Immutable Rule

Each experiment should be a new commit with its own result ref.

Avoid:

* force-pushing experiment refs;
* deleting experiment commits;
* using `git reset --hard` to rewrite measured history;
* reusing one commit for unrelated attempts.

This keeps every reported experiment reachable and reviewable.

## Deleting Campaigns and Experiments

Mistakes are fixed by deleting records, never by rewriting git history. Delete
an experiment from the campaign view in the web app. The campaign's best
result is recomputed from what remains.

Deletions are tombstoned server-side by each experiment's `runRef`. Immutable
git refs are left untouched automatically, and deleted app records are not
resurrected by later duplicate report attempts.

## Git Status

Campaign state does not track a mutable branch head. Each experiment tracks
its own git state:

* **pending** - the result ref has not been validated yet.
* **verified** - the result ref points at the reported result commit.
* **missing** - the result ref is gone.
* **mismatch** - the ref points at a different commit.
* **unreachable** - the commit cannot be read from GitHub.

Metrics are preserved even when code reads fail. Re-pushing or validating the
correct ref can heal the marker.

## Comparisons

The app stores each experiment's explicit base commit and result commit. Diff
views compare those commits, or compare one campaign experiment against another
when a base experiment is supplied.

## GitHub Code Reads

Onyx reads exact trees, blobs, and diffs from GitHub at the requested commit using the linked GitHub App installation. Repository sync records metadata and the default branch head, but the app does not clone repositories in the web/API runtime.
