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

# GitHub integration

> Install the Olyros GitHub App on your organisation and choose, repository by repository, whether agents may read it, change it, or not see it at all.

A company installs the Olyros GitHub App on its organisation once. From then on agents
can read or change the repositories the company allows, a labelled or front-matter issue
becomes an agent task whose progress is reported back on the issue, and pull request,
push and issue events can start [workflows](https://user-docs.olyrosstudios.com/workflows.md). The connection lives under
**Settings -> Integrations** (`/integrations`), then the GitHub connection
(`/integrations/github/:connectionId` with **Status** (`status`), **Repos** (`repos`),
**Triggers** (`triggers`), **Webhooks** (`webhooks`) and **Settings** (`settings`) tabs);
issues that became tasks show under **Tasks -> Incoming Issues** (`/incoming-issues`).

## What it does

* **One installation per organisation, one company per installation.**
  `GET /api/github/install` stages a single-use setup state (10 minutes) and sends the
  user to the App's install page; `GET /api/github/setup` redeems it, re-checks that the
  initiator is still a member, and stores a `GitHubConnection` with the installation id,
  organisation slug and the permissions GitHub granted. An installation id belongs to one
  connection row across all companies: the first company to claim it keeps it. A setup
  without a valid state (an expired link, an install started on github.com, or an
  installation another company already holds) lands on the app root and creates nothing.
  Status follows GitHub: `active`, `suspended`, `error`, `uninstalled` (the
  `installation` and `installation_repositories` webhooks keep it current).
* **Repository access levels.** The installation's repositories are cached
  (`GitHubRepoCache`: name, private flag, default branch). `updateRepoAccess` sets each
  to `none` (default), `read` or `read_write`. When a task or sandbox mounts a repository,
  Olyros mints a short-lived installation token with `contents: read` or
  `contents: write` according to that level and clones with it; `is_cwd` marks the
  task's working repository.
* **Repositories GitHub stops granting.** A refresh (`POST /api/github/{connection_id}/repos`),
  the setup callback and the installation webhooks share one reconcile path
  that reports added, reactivated, removed and
  marked-inaccessible repositories. A repository the installation no longer grants is
  deleted when nothing references it; otherwise it is kept with `removed_at` set
  (`removedAt` in GraphQL) and shown as removed. A removed repository cannot be picked for
  new tasks, agent defaults, content sync or schedules, issue-triggered tasks skip it, and
  a task or sandbox that still lists it fails with "... is no longer granted to the GitHub
  App installation". Granting it again on GitHub reactivates the row with its access level.
* **Issues become agent tasks.** On `issues` `opened` and `labeled` events the
  connection's agent trigger decides which agent:
  * `label_pattern`: a label `agent:<slug>` (prefix `AGENT_LABEL_PREFIX`); on `labeled`
    only the newly added label counts.
  * `yaml_front_matter` (default): a `---` block at the top of the issue body with an
    `agent` key, plus optional `repos`, `priority` and `schedule_id`; labels are the
    fallback when no front matter parses.
    A match creates a cloud task, dispatches it, posts an acknowledgement comment (or a
    "no OHO available" comment), and records an `ExternalIssueLink` (`active`,
    `comment_posted`, `cancelled`, `error`) with the comment ids. The link is keyed by
    `owner/repo#number`, so the same issue number in two repositories gets two links. When the task ends, a
    result or failure comment is posted. Closing the issue cancels any linked task that is
    still running. Events whose
    sender is the Olyros bot are ignored unless the issue carries a schedule id, which is
    how [scheduled](https://user-docs.olyrosstudios.com/schedules.md) GitHub issues still become tasks.
* **Workflow triggers and actions.** `github_event` nodes receive `pr_opened`,
  `pr_merged`, `push`, `issue_created` and `issue_labeled` for a connection, filtered by
  branch glob and repository; `github_action` nodes can `create_issue`, `add_label`,
  `remove_label` and `add_comment`.
* **Operations.** The webhook (`POST /api/github/webhooks`) verifies the App's HMAC
  signature on the raw body before parsing it and resolves the company from the installation's single
  connection row. `POST /api/github/connections/{connection_id}/verify` checks the
  installation; `GET .../webhook-events` lists recent deliveries; `disconnectGithub`
  removes the connection; `POST /api/github/{connection_id}/repos` refreshes the
  repository cache.
* **Platform side.** The GitHub App itself is created and configured once in the admin
  app (`/integrations/github`, manifest callback, webhook URL patch) and is shared by
  all companies.

## Who can use it

* Install (`GET /api/github/install`), verify, repository refresh
  (`POST /api/github/{connection_id}/repos`), repository access (`updateRepoAccess`),
  trigger configuration (`updateGithubTriggerConfig`) and disconnect
  (`disconnectGithub`): **editor or admin** (ability `integration.manage`, listed under
  **Settings -> Roles**, `/settings/roles`). A viewer gets 403 `EDITOR_REQUIRED` from
  REST or "Editor or admin role required." from GraphQL; the page shows "Only editors
  and admins can change this integration." next to the action.
* List and read connections, webhook events: **any company member**.
* Incoming issues (`externalIssueLinks`): any company member.
* Creating or changing the GitHub App: **platform admin** (admin app).
* No plan or tier gate.

## How to configure it

1. Settings -> Integrations (`/integrations`) -> GitHub -> Install (`/api/github/install`);
   choose the organisation and repositories on GitHub within ten minutes; return lands on
   the connection's Status tab. Start from Olyros: an install begun on github.com does not
   attach to a company.
2. **Repos** tab: set `read` or `read_write` per repository (`updateRepoAccess`). Agents
   can only mount repositories with a level above `none`. After changing the repository
   selection on GitHub, refresh the list (`POST /api/github/{connection_id}/repos`); the
   page reports what was added, reactivated and removed.
3. **Triggers** tab: pick `label_pattern` or `yaml_front_matter` and its config
   (`updateGithubTriggerConfig`). Make sure the agents you name by slug exist.
4. **Webhooks** tab: confirm deliveries arrive after creating a test issue.
5. For automations, add a `github_event` trigger node to a workflow and select this
   connection.

## Limits and defaults

| Setting | Default | Where enforced |
| - | - | - |
| Repository access level | `none` | `GitHubRepoCache.access_level`; token minting per level |
| Installation token permission | `contents: read` or `write` only | token minting at dispatch |
| Agent trigger type | `yaml_front_matter` | connection setting |
| Agent label prefix | `agent:` | `AGENT_LABEL_PREFIX` |
| Handled issue actions | `opened`, `labeled`, `closed` | issue webhook handler |
| Connections per installation | one, across all companies (first claim wins) | unique index `uq_github_conn_installation` |
| Install link lifetime | 10 minutes, single use | install-link state |
| Removed repository | kept with `removed_at` while referenced, never mounted | repository cache |

## What it emits

* Cloud tasks and `ExternalIssueLink` rows; acknowledgement, result and failure
  comments on the issue.
* Workflow runs from `github_event` triggers.
* Webhook delivery log per connection; connection status and `last_error`.

## Known gaps

* No pull request creation: tokens carry `contents` only, the adapter has issue,
  label, comment and `merge_pull_request` calls but no create-PR call. An agent can
  push a branch; opening the PR is manual.
* The `pull_request opened` webhook is received but has no handler, so PRs are not
  linked to the tasks that produced them.
* Only the `issues` and `pull_request` families are consumed for tasks; `push` and PR
  events only reach workflows.
* An organisation's installation cannot be shared by two companies; the second company
  to install it gets no connection and no error message.
* Content synchronisation from repositories (`createGithubSyncSchedule`, Content ->
  GitHub Sync) uses this connection but is a content feature, not covered here.

## Customer-safe summary

Install the Olyros GitHub App on your organisation and choose, repository by
repository, whether agents may read it, change it, or not see it at all. Create an issue
with a short header naming an agent, or add a label such as `agent:<name>`, and the
agent picks it up as a task, confirms on the issue, and posts its result or any failure
back there. Pull request, push and issue events can also start your automations, and
automations can open issues, add labels and comment.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.