Skip to content
Sengi

Switching a repository to Sengi

DRAFT — not a published guide

This guide is a working draft. It is written from the screens that exist in the release running here, and it marks every step it cannot yet deliver as not yet available — runner activation and paid execution are among them. No customer has walked it end to end against live GitHub.

It describes the product, not the agreement. What we charge for and what we promise are in the Sengi service terms, linked at the foot of this page, which are a draft as well.

This is the whole customer path, one section per step, written from the screens that exist in the application as of commit a1e3ce4. Where a step is not implemented yet, this guide says not yet available and names the work that owns it, rather than describing it as if you could do it today.

Two things to know before you read on:

  • Runner activation and paid execution are not available yet. No execution host has completed qualification, no payment provider account is configured, and no customer job has run on Sengi. Creating an account works today. The rest of this guide describes screens that exist and behave as described in local testing, not a service you can switch a repository to right now.
  • The commercial terms are in Sengi service terms. This guide does not restate them; where a number or a rule matters, it links there.

Screenshots are out of scope for this document. It never asks you to run a command, copy a token or edit a workflow file by hand — none of those are part of the supported path.

Based on: beta-terms.md §1.3, §1.4; runner-runtime-qualification.md; github-invoice-export.md; app/views/help.erb ("Runner activation is coming soon. You can create an account now").


Before you start

You need a GitHub account, and a Sengi project — the project is what owns the GitHub App installation, the approved repositories, the job history and the billing. You need permission to manage GitHub connections in that project; if you do not have it, someone who does has to run the setup, or invite you first through the project's existing member invitation flow.

Sengi accounts are created by signing in with GitHub (Continue with GitHub). Signing in is a separate authorization from installing the App: logging in does not give Sengi any access to your repositories.

Starting at /?setup=github_actions takes you to Choose your project, which lists only the projects you may set up GitHub for. Even when you have exactly one project, you choose it explicitly.

Based on: app/views/auth/social_buttons.erb; app/clover.rb (setup=github_actions/github/setup); app/routes/github.rb (Project:github filter); app/views/github/setup.erb ("Choose the Sengi project for this GitHub connection."); beta-terms.md §2.1–§2.2; github-sign-in.md.


Step 1 — Install the Sengi GitHub App and connect it

From the project's Connect GitHub page you start a connection setup:

Connect your personal account or an organization to this project. On GitHub, choose Only select repositories to limit access. Connecting won't enable runners or change workflows.

Set up GitHub connection sends you to GitHub to install the App. If your project already has a connection, the same page offers Verify existing connection for it instead of creating a second one. When you come back, the setup page shows either Continue to GitHub (install) or Verify GitHub connection (recheck an existing install).

The App asks for the permissions listed in the terms §2.4. Choosing "all repositories" on GitHub does not enable anything in Sengi — you still choose one repository here, explicitly.

Three things can happen next:

What you seeWhat it means
<account> is connectedThe connection is verified. The page names the GitHub account, whether GitHub granted "selected repositories" or "all repositories", and how many of them your GitHub account can currently reach.
Waiting for a GitHub account ownerSomeone with owner rights has to approve the App on GitHub. The page says: "Ask the personal account owner or an organization owner to approve the App on GitHub, then open this setup link. They also need permission to manage GitHub connections in <project>. The owner can continue below using their own account."
Connection needs attention"We couldn't confirm current GitHub access. Check the App's installation and permissions on GitHub, then verify again. Your project and previous connection details are preserved."

Every setup has a Resume or share this setup link. You can save it, or send it to the owner who has to approve the install: "The link grants no project or GitHub permissions." Opening it still requires your own sign-in and your own project permission.

Sengi rechecks your GitHub verification periodically during setup. If it lapses you will see Reconnect to GitHub to continue where you left off or Your GitHub access changed. Verify your connection to continue — rechecking access returns you to the same place with your progress intact.

Based on: app/views/github/connections.erb; app/views/github/activation.erb; app/routes/project/github/activation.rb (POST .../connect, .../repositories); app/helpers/github.rb (github_setup_message: verification_expired, authority_changed, github_authorization_revoked); github-activation-connection.md; permission-scoping.md; beta-terms.md §2.3, §2.4.


Step 2 — Choose a repository and a runner size

Once connected, the page says No repositories are enabled for runners. Choose a repository to review its workflow changes. If your repository list has not been fetched yet, Find repositories fetches it and the page shows Finding your repositories — "This page updates as your repositories become available." — until it is ready.

You then pick one repository from the list and one Runner size. The three sizes are 2 vCPU / 8 GB, 4 vCPU / 16 GB and 8 vCPU / 32 GB, all on the same Ubuntu 24.04 x64 image. Each is labelled with its per-minute equivalent and Charged per execution second. A size whose configuration cannot be resolved right now shows Temporarily unavailable and cannot be selected.

Word for word, as the pricing policy records it: "Rates are 50/100/200 integer micro-USD per execution second for the existing 2/8, 4/16 and 8/32 choices, equivalent to $0.003/$0.006/$0.012 per minute." The full billing rules are in the terms §8.

Find workflow jobs moves on to job selection. One repository per setup: to switch a second repository you start another setup for it.

If GitHub shows you no repositories at all, the page explains it rather than substituting one: "No repositories are available in this connection. Update repository access on GitHub, then verify again."

Based on: app/views/github/activation.erb; app/views/github/shapes.erb; app/helpers/github.rb (github_shape_options); app/lib/github_runner_configuration.rb (SHAPES, IMAGE_FAMILY); payg-policy-v1.md (Rates and authority, quoted verbatim); github-setup-preview.md.


Step 3 — Choose the jobs to switch

Sengi reads your workflow files and lists what it found: Choose the jobs to switch — "Select up to 100 jobs. You'll review every change before anything is published."

Supported jobs are pre-checked; unsupported ones cannot be selected, and each carries a plain reason:

Reason shownMeaning
This job chooses a different runner. Keep its current settings.The job's runner is not one of the values Sengi can switch, or it is chosen by an expression, a matrix or a sequence.
This job calls another workflow. Keep its current settings.It is a reusable-workflow call.
This job already uses the selected runner.Nothing to change.
This repository has more jobs than we can preview at once.Too many jobs to preview in one pass.
Choose a supported job to preview a change.Nothing supported is selected, so there is nothing to preview.

If there is nothing to work with, the page says so: No workflow files were found in this repository. There is no Preview changes button when no job is supported, and an empty selection cannot produce an empty pull request. The exact list of supported and unsupported constructs is in the terms §3.2.

Based on: app/views/github/preview.erb (selecting_jobs); app/helpers/github.rb (github_setup_message: unsupported_selection, unsupported_runner, dynamic_runner, runner_sequence, reusable_workflow, already_selected_runner, too_many_jobs, no_selected_changes, selection_invalid); app/routes/project/github/activation.rb (POST .../selection); workflow-support.md; github-workflow-preview.md.


Step 4 — Review the preview

Review your workflow changes shows the exact diff, file by file, with the selected jobs named:

These changes switch your selected jobs to Sengi. Your workflows on GitHub are unchanged.

and, directly above the button:

Enable authorizes Sengi to run workflows in this repository on this runner size and to open a pull request changing only the jobs shown below. Creating the branch or pull request can trigger your existing GitHub workflows. We won't merge it or rerun jobs for you.

Nothing has been sent to GitHub at this point. You can still use Change selected jobs or runner size, Refresh this preview, or Choose another repository or size. Changing the jobs or the size replaces the preview, and your approval applies only to the exact preview you were shown.

If the underlying workflow changed while you were reviewing, the preview says so — "This setup changed. Refresh to review the current choices." — and you review the current version instead. Sengi does not carry an old approval onto new bytes.

Based on: app/views/github/preview.erb (preview stage; github_stored_diff); app/routes/project/github/activation.rb (POST .../jobs, .../retry); app/helpers/github.rb (source_changed, preview_generation_changed); github-migration-consent.md; github-enable-flow.md.


Step 5 — Enable Sengi

Enable Sengi is the consent. It is bound to the exact preview you were shown; a stale page cannot enable a newer or different change, and clicking twice does not start two operations.

After Enable the page becomes Preparing your pull request:

We're checking your selected changes and runner availability. You can leave this page and return to check progress.

and it repeats what Enable does and does not prove:

Your Enable request is saved. A pull request alone does not confirm that your jobs have run successfully.

If something needs your attention first, the same section becomes Your update is paused with a specific reason. The ones you are most likely to see:

Reason shownWhat to do
Billing setup needs to be completed before Sengi can publish these changes. Contact support to continue.Paid publication is held; see step 10 and terms §8.12, §8.13.
Sengi is not yet available for this project. Contact support to continue.The project's billing class is not configured.
Runner availability needs attention. Your progress is saved. Contact support before trying again.Runner capacity or readiness is unavailable.
Runners are paused for this project. Contact your project administrator to continue.New runner work is stopped for the project.
GitHub may have received this change. Check publication progress before preparing another change.Use Check publication progress — "This only checks what GitHub received. It does not publish another change."
Publication is paused because your GitHub verification expired. Your existing permission is unchanged.Use Recheck GitHub access, then Retry this update. Rechecking access does not retry Enable by itself.

Retry this update resumes the same update; it never re-runs your code and never creates a second pull request.

Based on: app/views/github/preview.erb (Enable form); app/views/github/publication.erb; app/views/github/publication_refresh.erb; app/routes/project/github/activation.rb (POST .../enable, .../retry-publication, .../publication-progress, .../refresh-access); app/helpers/github.rb (paid_execution_readiness_unavailable, billing_class_unconfigured, /\Aruntime_/, project_runner_admission_stopped, publication_reconciliation_required, publication_deadline_exceeded); github-enable-flow.md; github-migration-publication.md.


Step 6 — The pull request, and merging it

When the branch and pull request exist, the page becomes Your pull request is ready, with View pull request on GitHub and:

Review and merge the pull request when you're ready. Your jobs will use their normal workflow triggers.

Two things are worth being explicit about:

  • Publishing the branch can trigger your existing workflows before the pull request exists. That is ordinary GitHub behaviour on a push, and the preview says so before you enable.
  • You merge it. Sengi does not merge, dispatch or re-run anything. If the pull request is closed without merging, the page says Pull request closed; closing it does not undo the repository approval or remove the published branch — use step 12 for that.

After a merge the heading becomes Waiting for your first run, with "Pull request merged. Jobs run on their normal workflow triggers."

Based on: app/views/github/migration_outcome.erb; app/views/github/preview.erb (Enable copy); github-migration-outcome.md; activation-journey.md (Enable ordering and result identity); beta-terms.md §3.3.


Step 7 — Your first result

Setup is finished when the jobs you selected have actually run on Sengi after the merge — not when the pull request exists, and not when a check goes green before the merge.

The progress page has one heading for each state it can honestly report:

HeadingWhat it means
Your pull request is readyThe pull request exists and is open.
Pull request closedIt was closed without merging.
Waiting for your first runMerged; no run of the selected workflow has been observed yet.
Your first run is queuedA selected job is queued.
Your first run has startedA selected job is running.
Your selected jobs passedEvery selected job completed successfully in the first attempt of the first qualifying run.
Your first run needs attentionThe first result arrived and it was not a clean pass.

Under each workflow, every selected job has its own status: Passed, Failed, Cancelled, Timed out, Skipped, Running, Queued, Finished without a pass, Action required, No longer current, Could not start, or Waiting for confirmation when the evidence is not conclusive yet. A failure is a real result: it means your job ran on Sengi and your build failed.

Progress is checked when you ask for it. Check progress starts a bounded check, and the page refreshes itself while that check is active; when it ends, the page stops refreshing rather than polling forever. The page always shows Last checked with a UTC timestamp. If checking is not possible right now it says Progress updates are paused. Your previous results are kept.

Two cases the page states rather than guesses:

  • Waiting for this workflow's next normal trigger. Nothing has triggered the workflow yet. Sengi will not dispatch a run to finish your setup.
  • We couldn't confirm these jobs yet. Check the workflow on GitHub. The jobs could not be matched reliably — matrix, reusable-workflow and expression-named jobs cannot be matched, and that state does not resolve itself.

There are links to the pull request and to the first run attempt on GitHub. Your logs stay in GitHub: "Open your repository's Actions tab and select the workflow run."

Not yet available: completing setup from pre-merge checks alone, for a repository whose workflows only run on pull_request. That alternative is a design proposal, not implemented.

Based on: app/views/github/migration_outcome.erb (headings, per-job status map, refresh partial); app/routes/project/github/activation.rb (POST .../progress); app/helpers/github.rb (github_check_outcome, outcome_mapping_unavailable, outcome_progress_changed, outcome_check_finishing, outcome_check_recently_requested); app/views/help.erb; github-migration-outcome.md (Proof and supported mapping; "Next product decision: PR-only completion").


Step 8 — Job history, after the machine is gone

Job history at .../github/jobs lists your jobs across the project's GitHub connections, including completed ones. Each row links to a detail page showing:

GitHub job, Run / attempt, Runner size, Runner image, Runner label, Job start delay, and Execution time (or Time running at last update while the job is still going), plus Last updated and links to the run and job on GitHub.

The history survives the machine. Deleting a runner, the virtual machine, the repository or the whole App installation does not erase it — it stays with the project that owned it, which is how a charge can be explained later. Reading history needs no GitHub access.

The page also shows Project reservations: how much vCPU is held across how many runners, and the project's limit. It is labelled honestly — "Preparing, running and cleanup runners keep their reservations until cleanup is confirmed. Reserved capacity is separate from available host capacity." It is not host utilisation and not free capacity.

Refreshing reads what has already been received; it does not run, retry or reconcile a job on GitHub. Automatic refresh is off by default (Automatic refresh is paused) and you opt into it per page; Refresh now always works, including with JavaScript disabled.

One retention rule applies, quoted from the page itself: "Job and workflow titles may be removed after 90 days without updates. You can still view the job number and result. Logs are available in GitHub." The execution, billing and unresolved-incident records are kept — see terms §5.3 and §5.4.

Based on: app/views/github/jobs.erb; app/views/github/job.erb; app/views/github/history_refresh.erb; app/routes/project/github/jobs.rb; github-job-history.md; github-job-retention.md (Suggested customer wording); runner-visibility-readiness.md.


Step 9 — Usage, and exactly what the figure means

The project's billing page shows a Usage estimate for one UTC month:

Estimated usage for <project>, before tax. This is not an amount due. No monthly minimum. Credits are shown in the month the affected job ran, even when recorded later.

Three totals — Usage, Credits, Net usage — sit above a per-runner-size table of rate, seconds, usage, credits and net. Anything not yet settled is deliberately kept out of that total and listed separately:

  • Jobs still being processed — "N jobs across all months need review and are not included yet."
  • Not charged — jobs that will not be charged, whose details still need review.
  • Internal usage — Sengi's own nonbillable work, shown with its usage value and marked Not charged.

What is billed, what is excluded, how whole seconds are counted, how cancellation and your own timeout-minutes are treated, and the six-hour allocation window are all in the terms §8.3–§8.6. Nothing on this page is an invoice.

Not yet available on this page: your project's spending allowance, the amount reserved and the amount available for new jobs. The allowance is a real admission control that can hold a job — it is described in terms §8.9 — but there is no customer or operator screen that shows or sets it yet, so a billable project's paid admission holds rather than running. That is the intended fail-closed behaviour, and it is GAP 4 in the terms review.

Based on: app/views/project/usage_preview.erb; app/routes/project/billing.rb (runner_only_product GET branch); github-usage-preview.md; payg-policy-v1.md (Project exposure and reservation lifecycle; Execution interval and bounded duration); github-runner-exposure.md; beta-terms-review.md (GAP 4).


Step 10 — Payment method and invoices

Payment methods, on the same billing page:

Save a payment method securely with Stripe. No charge is made during setup.

Add payment method sends you to the payment provider's own hosted page. That page saves the card; it does not charge it, and card details never reach Sengi. Once saved, the method shows as Saved; otherwise it shows Expired — add a new payment method, Needs attention, or Removed, and Remove takes it off the project.

There is no automatic debit. Invoices are issued through the provider, and paying one is an explicit action you take on the provider's hosted page. A saved card means a usable card is on file — nothing more. Invoices appear under Invoice history and Recent invoices, and a period that has not become an invoice yet appears under Statements awaiting an invoice with the reason it is waiting. "Issued invoices are listed separately. Later credits may appear on a different invoice."

Not yet available: production issuer, tax registration and merchant configuration; hosted collection; automatic preparation of invoices. No live invoice has been issued and no payment has been taken. Until these are configured, paid activation is held. See terms §8.10–§8.13.

Based on: app/views/project/payment_methods.erb; app/views/project/usage_preview.erb (invoice sections); app/routes/project/billing.rb (POST /billing, /billing/setup/:id, /billing/issued-invoice/:id); github-payment-setup.md; github-billing-presentation.md; github-invoice-initiation.md (Held states; What remains open); github-invoice-export.md.


Step 11 — Credits

If a verified Sengi host, image, bootstrap or runtime fault aborts one of your jobs — including a job stopped because our own execution window ran out — the real duration and the real amount stay on record and the whole of that job's invoiceable usage is credited. Net, you pay nothing for that job.

A GitHub conclusion of failure is not evidence of a Sengi fault: a failing test is your result.

Credits appear as Credits in the usage totals and per line, in the month the affected job ran, even when they are recorded later. They do not expire, there is no claim cutoff, and unused credit stays with the project that earned it. The full rules, including what happens when the affected invoice was already finalized, are in terms §9.

Not offered: general promotional or goodwill credits, and automatic refunds.

Based on: app/views/project/usage_preview.erb (Credits column and total); payg-policy-v1.md (Outcomes and infrastructure credits); github-usage-preview.md; beta-terms.md §9.


Step 12 — Stopping: disable, uninstall, revert

These are three different things, and doing one does not do the others.

Disable this repository. On the setup page, under Stop new jobs:

Disable Sengi for this repository. Running jobs can finish. Your workflow files stay as they are.

Confirming it says New Sengi jobs are stopped for this repository, and the setup page becomes This Sengi setup is disabled — "Running jobs can finish, and your job history remains available." and "Your workflow files have not changed. Jobs that request a Sengi runner need an enabled Sengi setup." Disable is entirely local: it does not call GitHub, does not uninstall the App and does not touch your workflow files. Work already running is allowed to finish; a registration already handed to GitHub cannot be recalled cleanly, so a job may still start. All of it is billed by the ordinary rules.

Uninstall the App. That is your action, in GitHub. When Sengi sees it, your runners and repositories are drained before anything is cleaned up. Uninstalling does not erase job history and does not cancel an amount already owed.

Revert the change. From the disabled setup, Prepare revert preview builds a revert from your current workflow files, and Restore previous runner labels shows the diff:

Review the changes below. Creating this pull request restores the selected jobs' previous runner labels and keeps other workflow changes. You decide when to merge it. Creating the branch or pull request can trigger your repository's configured workflows.

Create revert pull request opens it; you merge it. Only the selected jobs' runner values are restored, and only where they are still exactly what Sengi set — anything that changed since holds the whole revert, and you review a fresh one. If the labels are already back to their originals the page says The selected jobs already use their previous runner labels. No revert is needed.

Ordering matters: the original pull request has to be resolved first. If it is still open the page says "Close the original pull request on GitHub before preparing a revert, then check its status here."; if its state is unknown, "Check the original pull request status before preparing a revert." Check original pull request status and Recheck GitHub access are the two read-only actions that get you unstuck.

Not yet available: none of disable, uninstall, revocation or revert has been qualified against live GitHub behaviour. Treat this section as the implemented design, verified locally, rather than as tested-against-GitHub behaviour. Live disable, revocation, drain and cleanup qualification is runner-7gn.8; the reviewed inverse/revert revisions are runner-7gn.7, whose implementation is recorded but whose live qualification is the same open gate. See terms §13.7.

Based on: app/views/github/repository_controls.erb; app/views/github/repository_disabled.erb; app/views/github/revert.erb; app/routes/project/github/activation.rb (POST .../disable, .../prepare-revert, .../publication-progress, .../recovery-access, revert/:id/create, /withdraw, /progress); app/helpers/github.rb (inverse_original_open, inverse_original_unresolved, inverse_not_published, inverse_source_changed, repository_disable_required, inverse_consent_required); github-repository-disable.md; github-migration-inverse.md; acceptance-followups.md (runner-7gn.7, runner-7gn.8).


If the execution host is unavailable

Sengi runs on a single execution host with a separate control-plane machine. There is no second host, no failover and no clustering, and there is no uptime commitment or service-level agreement. If the host is unavailable, your jobs queue or fail until it comes back, and your workflows are affected for that time.

Jobs above your project's runner CPU quota, or above what the host can currently place, queue and start when capacity frees up. Sengi does not silently give you a bigger runner instead, and it does not send your jobs to another provider.

While new runner work is stopped for a project, the job history page says so and stays readable: "New runners are paused for this project. Your job history is still available."

Not yet available: a status page, a maintenance-window notice channel and a rehearsed outage-communication procedure. Until those exist, you would be contacted at your account email address. This is GAP 7 in the terms review, owned by runner-1aw.

Based on: one-click-beta-direction.md (Initial deployment; Scaling and exclusions); app/views/github/jobs.erb (admission-stopped notice); project-quota-admission.md; beta-terms.md §10.1, §10.3, §10.4; beta-terms-review.md (GAP 7).


Jobs already pointing at Sengi do not fall back to GitHub

This one catches people out, so it is worth stating on its own.

Once a job's runner is Sengi's label, that job runs on Sengi. It does not automatically overflow to a GitHub-hosted runner when Sengi is busy, held or unavailable — it queues. In the research this product is built on: "Jobs already targeting your label do not automatically overflow to GitHub-hosted runners."

If you want a job back on GitHub-hosted runners, that is a change to your workflow, and the supported way to make it is the revert pull request in step 12.

Based on: revised-master-plan-2026-09-08.md (quoted); one-click-beta-direction.md (Initial deployment: "Disable AWS spillover, automatic premium upgrades … initially"); reuse-boundaries.md ("no spillover or warm-pool project at launch"); app/views/marketing.erb FAQ ("Extra jobs wait in the queue."); beta-terms.md §10.4.


Getting support, and what to quote

Support contact addresses are placeholders until they are published — see terms §10.5 and §14. Support hours and a first-response target do not exist yet and are deliberately not promised anywhere (GAP 8).

The reference to quote for one job is the identifier in that job's Sengi page address: open the job from Job history and the last part of the URL (.../github/jobs/<reference>) identifies it exactly. Quoting it needs no secret from you, and it lets support find the same job.

Not yet available: that reference is not yet shown as a labelled field on the job page, only in the address bar. Adding it is a known, recorded gap (Appendix A, row 8 of the operations approval document), owned jointly by the dashboard and customer-documentation work.

For a setup that is stuck, the useful things to say are the state name the page is showing you and the sentence it printed — those are the exact words this guide lists, and they map to a specific cause.

What support can and cannot do is in terms §10.6 and §10.7. Two limits worth repeating: support cannot run, retry or reconcile a GitHub job for you, and cannot complete your activation for you — no operator route exists to bind your installation, approve a repository, consent on your behalf or choose a runner label.

Based on: app/views/github/job.erb and app/routes/project/github/jobs.rb (gj… identifier in the detail path); beta-approval-and-exceptions.md (§2 symptom table; "The boundary this document exists to hold"; Appendix A row 8); github-job-history.md; beta-terms.md §10.5–§10.7; beta-terms-review.md (GAP 8).


Source code for the deployed release

Sengi is built on Ubicloud and is used and distributed under the GNU Affero General Public License. When the published archive matches the exact commit that is deployed, the application shows a "Source code for this release" link. If it is not configured, no link is shown, rather than a link to something else.

Not yet available: nothing has been published yet, and no source URL is configured, so no link appears today. See terms §11.

Based on: corresponding-source-release.md (Config.source_release_url, SourceRelease.url); beta-terms.md §11; beta-terms-review.md (GAP 9).


Everything this guide marks as not yet available

WhereWhat is missing
Whole documentRunner activation and paid execution: no qualified host, no configured payment provider, no customer job has run.
Step 7Completing setup from pre-merge checks only, for pull_request-only repositories. A design proposal, not implemented.
Step 9Spending allowance, reserved and available-for-new-jobs figures, and any way to set an allowance. Paid admission holds.
Step 10Issuer, tax and merchant configuration, hosted collection, automatic invoice preparation. No live invoice, no payment taken.
Step 12Live qualification of disable, uninstall, revocation and revert against real GitHub behaviour.
Outage sectionStatus page, maintenance-notice channel, rehearsed outage communication.
Support sectionPublished support addresses, hours and first-response target; the labelled support reference on the job page.
Source sectionA published corresponding-source archive and a configured source URL.

Every claim in this guide traces to a view, a route, a helper message or an implementation record; the mapping is in guide-review.md. Nothing here describes a capability that does not exist in the application at the commit named at the top.