# Site administration

> The superadmin console at dash.git.pkgforge.dev: people, invitations, sign-in links, reports, messages, incidents, the audit log, email, quotas, mirrors and ingest.

Source: https://git.pkgforge.dev/docs/admin/site-administration

The superadmin runs githome. The superadmin decides who gets in, helps people who lost their passkeys, handles private security reports, posts incidents on the status page, and checks the audit log and email delivery. All of it happens in the superadmin console, the dash, at `https://dash.git.pkgforge.dev`. This page names each area of the dash and its path.

The dash is a site of its own, with its own passkey sign-in. It does not sit behind Cloudflare Access, and the core at `https://git.pkgforge.dev` has no **Site administration** group in **Settings**, no **Make admin** action, and `BOOTSTRAP_ADMINS` is empty on git.pkgforge.dev, so no account becomes an administrator at its first sign-in. The REST and CLI admin endpoints under `/api/v3/admin/` and `/api/v3/githome/admin/` answer `403` to each caller, and so does `githome invite` without `--org`: the dash replaces them.

## The superadmin

There is one superadmin. It signs in at `https://dash.git.pkgforge.dev/login` with a passkey. Each page of the dash is behind that session, and a sign-out ends it. The dash makes every instance invitation, invitation of an early access request and sign-in link, with the account `superadmin` of the core as its creator. It shows each link once, and githome sends no email for it: copy the link and send it yourself.

The pages of the dash, in the order of its navigation:

| Page | Path | What it is for |
| --- | --- | --- |
| **People** | `/accounts` | Access requests, the list of people, account status, deletion and sign-in links, and the instance invitations that wait |
| **Server errors** | `/errors` | The newest 5xx errors of the core, found by request ID |
| **Search engines** | `/search-engines` | What githome told search engines through IndexNow |
| **Scheduler** | `/scheduler` | The state of the timer of scheduled workflows |
| **Status** | `/status` | Incidents on the public status page |
| **Security reports** | `/security-reports` | Private vulnerability reports from the report form |
| **Contact messages** | `/contact` | Messages from the contact form |
| **Audit log** | `/audit` | The newest security-relevant events |
| **Quotas** | `/quotas` | The quotas and the usage of a person or an organization |
| **GitHub links** | `/linked-accounts` | Clear a link between a githome account and a GitHub account |
| **Kill switches** | `/kill-switches` | Stop Actions for a repository, for an account, or the hosted compute |
| **Reports** | `/reports` | What people reported as abusive |
| **Email** | `/email` | Email delivery status, the suppression list, template previews and the newest emails |
| **Early access** | `/early-access` | Requests from people without an invitation |
| **Mirrors** | `/mirrors` | The push and pull mirrors, their credentials and providers |
| **Ingest sets** | `/ingest` | The sets of repositories that githome pulls in from a provider |

## People

The page **People** of the dash (`/accounts`) shows the access requests that wait, the people with their status and a deletion, and the instance invitations that wait. **Invite a person** makes an instance invitation (see [Invites](#invites)), each invitation that waits has **Revoke**, and each person who is not disabled has **Sign-in link** (see [Sign-in links](#sign-in-links)).

### Pending access requests

An account is pending when it exists but has no instance invite. On git.pkgforge.dev none arises: it has no Cloudflare Access sign-in and no open sign-up, so the list of access requests stays empty and the dash has only the buttons below for a deployment where one does. A pending person sees the **Waiting for an invite** page and can click **Request access** with a note. Each request is listed with the person's email address, when they asked and their note.

- **Approve** makes the account active. The person can then use githome, but isn't added to any organization or repository; add them to one, by email address or by username.
- **Deny** disables the account.

See [Invitations](https://git.pkgforge.dev/docs/accounts/invitations#access-requests) for the requester's side.

### Users

The table lists every person (not organizations, agents or deleted accounts) with their username, name, email address, status and when they joined. Each row has one button for the status, **Disable** or, for a disabled person, **Enable**, and **Sign-in link** (see [Sign-in links](#sign-in-links)) and **Delete** (see [Deleting an account](#deleting-an-account)).

| Status | Meaning |
| --- | --- |
| `active` | Can sign in and use everything their roles allow |
| `disabled` | Can't use githome |

A suspended person has status `disabled` until you lift the suspension (see [Suspend an account](#suspend-an-account)).

An invitation of an organization or a repository doesn't make a pending account active, whether it is made or accepted. Only an instance invite of the dash, or **Approve** on the page **People**, makes it active.

### Disable an account

Click **Disable** on the person's row. Immediately:

- every browser session they have ends, so they are signed out everywhere, and passkey sign-in is refused with "Your account is disabled.",
- every access token the person has is revoked,
- agents they own stop working, because an agent can never do more than its owner.

Their repositories, organizations and memberships stay as they are, but they can't be added to organizations or repositories while disabled ("diffy's account is disabled"). Click **Enable** to enable the account again; the person signs in with their passkey again. Their old tokens stay revoked, so they need to create new ones.

Every status change is recorded in the audit log as `user.active` or `user.disabled`.

### Deleting an account

Click **Delete** on the person's row. A page (`/accounts/<id>/delete`) shows what keeps the account, if anything. Type their username and click **Delete the account**. It needs a sign-in of the dash from the last 2 hours.

The page says why, and offers no button, when the person is the only owner of an organization (it names each one) or has a GitHub import running. Make someone else an owner, or delete the organization, first.

Deleting an account is the same as the person deleting it themselves: everything they own goes, what they wrote in other people's repositories is shown as written by **ghost**, and their username can't be used for 90 days. See [Exporting and deleting your account](https://git.pkgforge.dev/docs/accounts/account-data#deleting-your-account). It can't be undone; to keep someone out while you decide, disable the account instead. Each deletion is recorded in the audit log as `account.delete`, with `"via":"admin"`.

### Suspend an account

Suspending is for abuse: like disabling, it stops the person at once, but it also hides what they made, and lifting the suspension puts everything back as it was, tokens included.

Open the report about the person on the page **Reports** (`/reports`), enter a **Reason** (at most 500 characters; it is kept in the audit log) and click **Suspend**. Immediately:

- every browser session they have ends, and passkey sign-in is refused with "Your account is disabled.",
- their access tokens and their agents' tokens are refused (`401`), but not revoked,
- their profile, repositories (on the web, through Git, the API and the container registry) and packages answer `404` to everyone else,
- their issues and pull requests answer `404` and are left out of lists and search, and their comments and reviews are left out of every conversation.

The superadmin still sees all of it. A suspended person shows `suspended_at` and `suspension_reason` in `GET /api/v3/users/{username}` for the superadmin. **Lift the suspension** (on the same report) makes the account active again: tokens and agents work again, and the content is shown again. Their browser sessions stay ended, so they sign in again with their passkey.

Suspensions are audited as `user.suspend` (with the reason and what was stopped) and `user.unsuspend`. The routes `PUT` and `DELETE /api/v3/users/{username}/suspended` answer `403`: the dash replaces them.

## Early access

People without an invitation can ask for one at `/early-access`. The page **Early access** of the dash (`/early-access`) lists the requests. **Invite** makes the usual instance invitation and shows its link once (see [Invites](#invites)), **Decline** sends nobody anything, and **Delete the request** removes everything stored about a request. Each decision is in the audit log. Githome has no early access program: the request is a way to ask the superadmin for an invitation.

## Contact messages

Anyone can write to the superadmin at `/contact` on the core, linked from the footer. People who aren't signed in pass Turnstile first, and until the deployment has its Turnstile keys (neither is set on git.pkgforge.dev yet) the form takes messages only from people who are signed in. The page **Contact messages** of the dash (`/contact`) lists the messages: **New** ones wait for you, a message can be marked handled or spam, a note (**Save the note**) tells what happened, and **Delete the message** removes everything stored about one. Each change is in the audit log. See [Contact form](https://git.pkgforge.dev/docs/admin/contact-form#for-site-administrators) for the form and how it is protected.

## Reports

Anyone signed in can report a person, a repository, an issue, a pull request or a comment as abusive, from the **…** menu on it (or on a profile) and **Report**. They pick a reason (spam, harassment or bullying, hateful content, violence or threats, sexual content, malware or phishing, impersonation, or something else) and can add a note of up to 2,000 characters; "Something else" needs the note. The person reported isn't told. One person files at most 20 reports a day, and one open report per thing.

The page **Reports** of the dash (`/reports`) lists the open reports, newest first, with what was reported, the reason, who reported it and when; **Resolved** and **All** list the rest. Open one to see:

- a link to what was reported, and the account that wrote it,
- the reporter's note,
- what was reported as it was then (an issue's title and text, a comment's text), so editing or deleting it afterwards hides nothing,
- **Resolve** with a note that says what you did (hid the comment, suspended the account, nothing to do). A resolved report can be reopened with **Reopen**.
- **Suspend** the account that wrote it, with a reason.

Filing, resolving and reopening are audited as `report.create`, `report.resolve` and `report.reopen`.

From the API, people file reports with `POST /api/v3/githome/reports`. The routes `GET /api/v3/admin/reports`, `GET /api/v3/admin/reports/{id}` and `PATCH /api/v3/admin/reports/{id}` answer `403` to each caller: the page **Reports** replaces them. See [REST API](https://git.pkgforge.dev/docs/reference/rest-api#moderation).

Other tools for abuse: [blocking](https://git.pkgforge.dev/docs/accounts/blocking-and-reporting) (anyone, for themselves or their organization), [hiding comments](https://git.pkgforge.dev/docs/collaboration/issues#hide-a-comment) (anyone with write access to the repository) and the [kill switches](#kill-switches).

## Invites

Under **Invite a person** on the page **People**, enter an **Email address** and click **Make an invitation link**. The invite isn't tied to an organization or repository. It is the only invite that makes an account. The dash shows the link once, with the time until which it works: 14 days, once. Copy the whole link and send it yourself, because githome sends no email for it. Whoever holds the whole link creates the account, with the address of the invite: nothing proves the inbox. An instance invite of an address whose account waits (pending) makes that account active. **Revoke** on the same page revokes an invitation that waits.

The REST route `POST /api/v3/invitations` answers `403` to each caller, and so does the CLI command `githome invite` without `--org`. Organization owners and admins add people to their organization with **Add people** on its **People** tab. See [Invitations](https://git.pkgforge.dev/docs/accounts/invitations) for all kinds of invites. Open sign-up is off on git.pkgforge.dev: the superadmin invites each account.

## Sign-in links

When someone loses their passkeys, the superadmin can give them a one-time link that adds a new passkey to their existing account. There is no email recovery.

1. On the page **People**, click **Sign-in link** next to the person. The dash asks for a sign-in of the last 2 hours first.
2. The dash shows the link once. githome sends no email for it: send it yourself through a channel you trust.

The person opens the link, creates a passkey and is signed in. See [Passkeys and sign-in](https://git.pkgforge.dev/docs/accounts/passkeys-and-sign-in#sign-in-link-from-an-administrator) for their side.

| Rule | Value |
| --- | --- |
| Lifetime | 24 hours |
| Uses | Once |
| Disabled accounts | Refused with "enable this account first"; enable the account, then create the link |
| Link format | `https://<host>/signin#<token>`. The token is in the URL fragment, which browsers never send to the server, so it stays out of request logs and `Referer` headers. The page removes it from the address bar. |
| Effect | Adds a passkey and signs that browser in; the person's other passkeys stay |
| Audit | `signin_link.create` by the account `superadmin` when you create it, `passkey.add` when it is used |

Anyone with the link can add a passkey to the account, so send it only to that person. The link also works for a first sign-in, for an account that exists but has no passkey yet.

## Kill switches

> The forge CI of git.pkgforge.dev is dormant, so no workflow run, hosted job or agent sandbox starts there now. The kill switches stay in the code and take effect if the CI is turned on.

The page **Kill switches** of the dash (`/kill-switches`) stops Actions and agent sandboxes quickly, for abuse, a runaway workflow or a cost problem. There are three, from the narrowest:

| Switch | What stops | What keeps working |
| --- | --- | --- |
| **Suspend Actions for a repository** | Every workflow run of the repository and its agent sandboxes | Everything else in the repository: Git, issues, pull requests |
| **Suspend Actions for an account** | The same, for every repository a person or an organization owns, including repositories created or transferred in later | The account's other repositories' Git and collaboration |
| **Pause hosted compute** | Hosted Actions jobs and agent sandboxes in every repository on the instance | Self-hosted runners and workflow runs themselves |

Nobody is exempt, not even the superadmin's own account. Every change is in the audit log: `actions.suspend` and `actions.unsuspend` with the repository (`owner/name`) or the account's login as the target, `compute.pause` and `compute.unpause`, each with the reason and what was stopped.

While a repository or its owner is suspended, no workflow run starts, **Run workflow**, `repository_dispatch` and **Re-run** are refused with `403 Actions are suspended for this repository by a site administrator: <reason>`, and a new sandbox is refused with the same `403`. While hosted compute is paused, a job on a hosted runner fails without starting and a new sandbox is refused. The repository's **Actions** page, its run pages and its **Settings** pages show a banner with the reason.

Turning a switch on stops what is running: suspending a repository or an account cancels each of its unfinished runs and closes each of its open sandboxes, and pausing hosted compute fails each running hosted job. The answer says what was stopped: `repositories`, `runs`, `jobs` and `sandboxes`. Turning a switch off only lets new work start again. Nothing that was stopped restarts.

On the page:

- **Hosted compute** shows whether it runs or is paused. Enter a **Reason** and click **Pause hosted compute**, or click **Resume hosted compute**.
- **Accounts with Actions suspended**: the login of a person or an organization and a **Reason**, then **Suspend Actions**. Each listed account has **Lift**.
- **Repositories with Actions suspended**: `owner/name` and a **Reason**, then **Suspend Actions**. Each listed repository has **Lift**.

A reason is required (at most 500 characters): it is shown to the people affected and kept in the audit log. The REST routes under `/api/v3/admin/` for the kill switches answer `403` to each caller.

## GitHub imports and linked accounts

An import attributes a GitHub user's issues, pull requests, comments and reviews to the githome account linked to that GitHub user. Imports from GitLab, Forgejo, Gitea and Codeberg run without a container; the server-side import from GitHub needs the import container, which git.pkgforge.dev does not run. See [imports from GitHub](https://git.pkgforge.dev/docs/migrate-from-github) for how a person starts one.

### Clear a GitHub link

If a link is wrong, for example after a githome account changed hands, the superadmin can remove it. On the page **GitHub links** of the dash (`/linked-accounts`), enter the id of the link and click **Clear the link**. The REST route `DELETE /api/v3/githome/admin/linked-accounts/{id}` answers `403`: the page of the dash replaces it.

The link id comes from `GET /api/v3/githome/user/linked-accounts`, called by the account that owns the link; githome has no endpoint that lists other people's links. The dash answers with a notice, or with `link not found`, and the action is audited as `account.link_cleared`. Imports that already ran keep their attribution; later imports treat that GitHub user as a mannequin until someone links the account again. People unlink their own accounts on **Settings → Linked accounts** (`account.unlink_github`).

## Account quotas

Every person and organization has [quotas](https://git.pkgforge.dev/docs/reference/limits#account-quotas) on hosted minutes per month, hosted jobs running at once, agent sandboxes open at once, repositories and storage. The page **Quotas** of the dash (`/quotas`) shows the quotas and the usage of a login (a person or an organization; an agent uses its owner's quotas) and changes them. Enter a whole number (`storage_bytes` in bytes, up to 1 PiB), `-1` for unlimited, or `default` to go back to the default; the quotas you leave empty stay as they are. Each change is audited as `account.quotas.set`. The REST routes `GET` and `PATCH /api/v3/admin/accounts/{login}/quotas` answer `403`: the page replaces them. People see their own usage with `GET /api/v3/user/usage`, and organization owners and admins see their organization's with `GET /api/v3/orgs/{org}/usage`.

Storage is counted per repository as it changes: each repository's Durable Object keeps a running total of its git objects, Git LFS objects and release assets and reports it to D1 (`repo_storage`), where the owner's repositories and packages are added up.

## Audit log

The page **Audit log** of the dash (`/audit`) shows the 200 most recent security-relevant events: sign-ins, passkeys, tokens, invites, account status changes, repository and access changes, pushes, merges and push protection. Repository and organization settings changed through the REST API or the CLI are recorded too, with `via: api` in their **Detail**, as are imports from GitHub and linked GitHub accounts. Each row has **When**, **Actor** (and who an agent acted for), **Action**, **Target** and **Detail**. See [Audit log](https://git.pkgforge.dev/docs/security/audit-log) for every action and how to use it.

## Email

The page **Email** of the dash (`/email`) shows whether the core can send email, the suppression list and the newest emails, and lets you check every template. Notification email depends on the email sending of the deployment: where none is set up, emails are logged, not sent.

| Item | What it shows |
| --- | --- |
| **Sending** | Whether sending is on, and with which transport (the `EMAIL` binding of Cloudflare, or SMTP) |
| **SMTP** | The server of `SMTP_URL` (never the password), or why it can't be used |
| **Queue** | Whether the `githome-mail` queue is bound |
| **From** | The address emails are sent from |
| **Event intake** | Whether bounces and complaints can reach the list |
| **Last 24 hours** | How many emails were sent, failed and skipped |

Under **Templates**, each template opens a preview with its subject, sender, text and HTML. **Send each sample** sends one sample of every template to an address that you enter. The previews use sample data such as the repository `acme/website`.

**Suppression list** shows every address githome sends nothing to, with why. **Remove** sends email to the address again; **Suppress the address** adds one by hand, with an optional note. Both are recorded in the audit log (`email.suppression.add` and `email.suppression.remove`). **Newest emails** lists the latest emails sent to anyone, with the time, recipient, subject, template kind and status (`sent`, `failed` or `skipped`) with the reason when it wasn't sent. See [Notifications](https://git.pkgforge.dev/docs/accounts/notifications#every-email-githome-sends) for when each email is sent.

The REST routes under `/api/v3/githome/admin/email` answer `403` to each caller, and so does `GET /api/v3/githome/emails?all=1`: the page replaces them.

### Bounces, complaints and the suppression list

Githome sends no email at all to an address on the suppression list. Such an email shows in the list of the newest emails as `skipped` with "address is suppressed: ..." as the reason. An address gets on the list three ways:

| Reason | How |
| --- | --- |
| `hard-bounce` | Email to it bounced permanently, or the sending service or the SMTP server refused the recipient for good. Soft bounces, delays and temporary send errors change nothing. |
| `complaint` | Its owner marked an email from githome as spam. |
| `manual` | The superadmin added it, under **Suppress the address**. |

A newer event replaces an older one for the same address. People can lift a bounce or complaint on their own address themselves: **Settings → Email** shows that the address is suppressed and why, and **Send a verification email** sends one email to it, past the list. A `manual` suppression can only be removed by the superadmin. See [Notifications](https://git.pkgforge.dev/docs/accounts/notifications#when-githome-stops-emailing-you).

#### Where bounces and complaints come from

Where the deployment's email sending publishes delivery events to the `githome-mail-events` queue, the core consumes them and adds the addresses that bounced for good or complained. A signed endpoint, `https://git.pkgforge.dev/-/email/events`, takes the same events from a relay; it answers `404` until the `MAIL_EVENTS_SECRET` secret is set, and refuses (`401`) any request without a good signature (`X-Githome-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<body>">`, at most 5 minutes old). Until events arrive, bounces and complaints reach the list only when a send is refused; the superadmin can still add and remove addresses by hand.

## Security reports

`/.well-known/security.txt` names the instance's private report form, `/security/report`, as its first contact. Anyone signed in can send a report there; someone without an account can too, after Cloudflare Turnstile, but until the deployment has its Turnstile keys (neither is set on git.pkgforge.dev yet) the form takes reports only from people who are signed in. A report has a one-line summary (up to 200 characters), details (plain text, up to 20,000 characters), optionally the affected URL or area, and a reply-to address: required without an account, optional when signed in.

Only the superadmin can see reports. To anyone else the pages and the API answer `404`, as if they didn't exist.

The page **Security reports** of the dash (`/security-reports`) lists reports newest first, with when they arrived, the summary, who sent it (a username, or `anonymous`) and the state: **New**, **Triaged** or **Resolved**. Click a summary to open the report: its state, the reporter, the reply-to address, the affected URL or area and the details as plain text. Below them, pick a state, write a note and click **Save**. Each change is in the audit log (`security_report.triage`, `security_report.resolve`, or `security_report.reopen` when set back to **New**), with the note. Reply to the reporter from your own mailbox: githome doesn't email them. The REST routes under `/api/v3/githome/admin/security-reports` answer `403`.

## Status

Githome has a public [status page](https://git.pkgforge.dev/docs/self-hosting/status-page) at `/status`, with JSON at `GET /api/v3/githome/status`: each component's status, incidents in progress and those resolved in the last 14 days. Anyone can read it without signing in.

The page **Status** of the dash (`/status`) shows what the page says now, a form to open an incident (a title, the impact, the affected components, a state and the first update), each open incident with a form to post an update or resolve it, and the recent incidents. While an incident isn't resolved, its impact sets the status of each component it names. Each change is in the audit log (`status_incident.create`, `status_incident.update` or `status_incident.resolve`). Incidents and their updates are public, so keep internal details out of them. The REST routes under `/api/v3/githome/admin/status/incidents` answer `403`.

The status page runs in the core's own Worker, so it is down whenever the whole Worker is: watch `/healthz` with an external uptime monitor too (see [Monitoring from outside](https://git.pkgforge.dev/docs/self-hosting/status-page#monitoring-from-outside)).

## Search engines

Githome tells search engines about public pages that are added, change or go away through [IndexNow](https://www.indexnow.org), so the engines that share IndexNow submissions recrawl them within minutes. It runs by itself after every deploy, and every hour for public repositories pushed since they were last submitted. It never submits a private repository, a repository whose owner is suspended, or any page behind sign-in.

The page **Search engines** of the dash (`/search-engines`) shows whether IndexNow is on and its key file, how many pages and public repositories it tracks and how many are waiting, and the newest submissions: when, how many URLs, which endpoint answered, its answer and any error. The newest 200 submissions are kept. The REST route `GET /api/v3/githome/admin/indexnow` answers `403`: the page replaces it.

Anyone can see whether it is on and how the last submission went, without the pages, in `GET /api/v3/meta` (`indexnow`). IndexNow is off when `INDEXNOW` is `off`, when `PUBLIC_URL` isn't a public `https` origin, or when `MASTER_KEY` isn't set. See [Configuration](https://git.pkgforge.dev/docs/self-hosting/configuration#worker-variables).

## Workflow scheduler

Scheduled workflows are started by githome's own timer, every 5 minutes (see [Scheduled workflows](https://git.pkgforge.dev/docs/actions/events#schedule)); with the forge CI dormant, no workflow starts. The page **Scheduler** of the dash (`/scheduler`) shows the state of the timer:

| Field | Meaning |
| --- | --- |
| `tick_minutes` | Minutes between checks (`SCHEDULE_TICK_MINUTES`, default 5) |
| `last_tick_at` | When the last check finished, or `null` before the first |
| `covered_until` | The last minute whose schedules have been started |
| `next_tick_at` | When the next check is due, or `null` if the timer isn't set (the cron trigger sets it again within 5 minutes) |

A `last_tick_at` far behind the time means checks are failing; look in the Worker's logs for `schedule tick failed`. The REST route `GET /api/v3/githome/admin/scheduler` answers `403`: the page replaces it.

## Server errors

When githome answers a request with a 5xx status, it keeps a record of the error. The answer's JSON includes a `request_id`, which also appears in the `x-request-id` header, and an error page shows it as **Request ID**. Look the request ID up on the page **Server errors** of the dash (`/errors`). The REST routes `GET /api/v3/githome/admin/errors` and `GET /api/v3/githome/admin/errors/{id}` answer `403`: the page replaces them.

Each record has the request's method, `route` (the matched route pattern), `path`, `status`, `message` and `stack`. Only the newest 500 errors are kept. Records never include request bodies, query strings or headers. Tokens that appear in a message are masked, and a path that carries a secret, such as a sign-in link, is stored as its route pattern instead. On Cloudflare, the request ID is the request's Ray ID, so the same request can also be found in Cloudflare's logs.

## Mirrors and ingest

The page **Mirrors** of the dash (`/mirrors`) lists the push and pull mirrors of repositories, filtered by repository or state, with their provider (GitHub, Cloudflare Artifacts, GitLab, Forgejo or Codeberg), direction, target, state and last success. It makes a mirror, seals the credentials that the mirrors use (a secret goes from the form to the core and is never shown again), rotates a credential, sets the cap on requests of a provider, and promotes a pull-mirrored repository so that it takes pushes again. A mirror's own page (`/mirrors/<id>`) shows its facts and events, pauses and resumes it, changes its credential and interval, and, for a pull mirror, follows the provider on a ref that diverged or deletes a ref that the provider no longer has.

The page **Ingest sets** of the dash (`/ingest`) lists the sets that pull in the repositories of a user or an organization of a provider into an account of githome, each with its credential, interval and filter (include and exclude globs, forks, archived), and makes or changes one.

## Administration from the CLI

There is none. The CLI reaches the core with `githome api METHOD PATH`, and each endpoint under `/api/v3/admin/` and `/api/v3/githome/admin/` answers `403`. The instance invitation, the sign-in links, the email status and the rest are in the dash. `githome invite --org ORG` still invites to an organization; see [Invitations](https://git.pkgforge.dev/docs/accounts/invitations#invite-from-the-cli).

## Troubleshooting

| Message | Cause and fix |
| --- | --- |
| `403 the administration of the site is in the dash of this deployment` | The endpoint moved to the dash. Use its page. |
| `404 link not found` | No GitHub link has that id. Ask the account's owner for the id from `GET /api/v3/githome/user/linked-accounts`. |
| `422 give a reason for the suspension` | Suspending needs a reason. |
| `403 Actions are suspended ... by a site administrator` | A kill switch is on for the repository or its owner. Lift it on the page **Kill switches** of the dash. |
| `422 give a reason` | Kill switches need a reason. |
| "enable this account first" | Sign-in links can't be created for disabled accounts. Click **Enable**, then create the link. |
| "Sign in again to make a sign-in link" | The sign-in of the dash is more than 2 hours old. Sign in again. |
| "enter a valid email address" | The invite form needs an address like `friend@example.com`. |
| `422 friend@example.com has no account of Githome: ask the administrator to invite this address` | An invitation of an organization or a repository needs an account with that address. Make an instance invite of it under **Invite a person** first. |
| **Sending** says off | The Worker has neither an `EMAIL` binding nor `SMTP_URL`, so emails are logged as skipped. |
| Emails show as `skipped` with "address is suppressed" | The address bounced, reported spam or was suppressed by hand. See [Bounces, complaints and the suppression list](#bounces-complaints-and-the-suppression-list). |
| `401 missing or bad signature` from `/-/email/events` | The `X-Githome-Signature` header is missing, signed with another secret, or more than 5 minutes old. |
